static int pwm_regulator_set_voltage(struct udevice *dev, int uvolt) { struct pwm_regulator_info *priv = dev_get_priv(dev); int duty_cycle; int ret = 0; duty_cycle = pwm_voltage_to_duty_cycle_percentage(dev, uvolt); ret = pwm_set_invert(priv->pwm, priv->pwm_id, priv->polarity); if (ret) { dev_err(dev, "Failed to init PWM\n"); return ret; } ret = pwm_set_config(priv->pwm, priv->pwm_id, priv->period_ns, (priv->period_ns / 100) * duty_cycle); if (ret) { dev_err(dev, "Failed to configure PWM\n"); return ret; } priv->volt_uV = uvolt; return ret; }
static int pwm_backlight_enable(struct udevice *dev) { struct pwm_backlight_priv *priv = dev_get_priv(dev); struct dm_regulator_uclass_platdata *plat; uint duty_cycle; int ret; if (priv->reg) { plat = dev_get_uclass_platdata(priv->reg); debug("%s: Enable '%s', regulator '%s'/'%s'\n", __func__, dev->name, priv->reg->name, plat->name); ret = regulator_set_enable(priv->reg, true); if (ret) { debug("%s: Cannot enable regulator for PWM '%s'\n", __func__, dev->name); return ret; } mdelay(120); } duty_cycle = priv->period_ns * (priv->default_level - priv->min_level) / (priv->max_level - priv->min_level + 1); ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, duty_cycle); if (ret) return ret; ret = pwm_set_enable(priv->pwm, priv->channel, true); if (ret) return ret; mdelay(10); dm_gpio_set_value(&priv->enable, 1); return 0; }
/** * Handle the next stage of device init */ static int handle_stage(const void *blob, struct tegra_lcd_priv *priv) { debug("%s: stage %d\n", __func__, priv->stage); /* do the things for this stage */ switch (priv->stage) { case STAGE_START: /* * It is possible that the FDT has requested that the LCD be * disabled. We currently don't support this. It would require * changes to U-Boot LCD subsystem to have LCD support * compiled in but not used. An easier option might be to * still have a frame buffer, but leave the backlight off and * remove all mention of lcd in the stdout environment * variable. */ funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT); break; case STAGE_PANEL_VDD: if (dm_gpio_is_valid(&priv->panel_vdd)) dm_gpio_set_value(&priv->panel_vdd, 1); break; case STAGE_LVDS: if (dm_gpio_is_valid(&priv->lvds_shutdown)) dm_gpio_set_value(&priv->lvds_shutdown, 1); break; case STAGE_BACKLIGHT_VDD: if (dm_gpio_is_valid(&priv->backlight_vdd)) dm_gpio_set_value(&priv->backlight_vdd, 1); break; case STAGE_PWM: /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */ pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_PWM); pinmux_tristate_disable(PMUX_PINGRP_GPU); pwm_set_config(priv->pwm, priv->pwm_channel, 0xdf, 0xff); pwm_set_enable(priv->pwm, priv->pwm_channel, true); break; case STAGE_BACKLIGHT_EN: if (dm_gpio_is_valid(&priv->backlight_en)) dm_gpio_set_value(&priv->backlight_en, 1); break; case STAGE_DONE: break; } /* set up timer for next stage */ priv->timer_next = timer_get_us(); if (priv->stage < FDT_LCD_TIMINGS) priv->timer_next += priv->panel_timings[priv->stage] * 1000; /* move to next stage */ priv->stage++; return 0; }
static int set_pwm(struct pwm_backlight_priv *priv) { uint duty_cycle; int ret; duty_cycle = priv->period_ns * (priv->cur_level - priv->min_level) / (priv->max_level - priv->min_level + 1); ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, duty_cycle); if (ret) return log_ret(ret); ret = pwm_set_invert(priv->pwm, priv->channel, priv->polarity); return log_ret(ret); }
/* Basic test of the pwm uclass */ static int dm_test_pwm_base(struct unit_test_state *uts) { struct udevice *dev; ut_assertok(uclass_get_device(UCLASS_PWM, 0, &dev)); ut_assertnonnull(dev); ut_assertok(pwm_set_config(dev, 0, 100, 50)); ut_assertok(pwm_set_enable(dev, 0, true)); ut_assertok(pwm_set_enable(dev, 1, true)); ut_assertok(pwm_set_enable(dev, 2, true)); ut_asserteq(-ENOSPC, pwm_set_enable(dev, 3, true)); ut_assertok(pwm_set_invert(dev, 0, true)); ut_assertok(uclass_get_device(UCLASS_PWM, 1, &dev)); ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PWM, 2, &dev)); return 0; }