Merge "leds: leds-qpnp: Set PWM channel operational mode explicitly"

This commit is contained in:
Linux Build Service Account 2017-08-21 20:01:10 -07:00 committed by Gerrit - the friendly Code Review server
commit fc59d81f3e
2 changed files with 72 additions and 24 deletions

View file

@ -875,6 +875,14 @@ static int qpnp_mpp_set(struct qpnp_led_data *led)
}
if (led->mpp_cfg->pwm_mode == PWM_MODE) {
/*config pwm for brightness scaling*/
rc = pwm_change_mode(led->mpp_cfg->pwm_cfg->pwm_dev,
PM_PWM_MODE_PWM);
if (rc < 0) {
dev_err(&led->pdev->dev,
"Failed to set PWM mode, rc = %d\n",
rc);
return rc;
}
period_us = led->mpp_cfg->pwm_cfg->pwm_period_us;
if (period_us > INT_MAX / NSEC_PER_USEC) {
duty_us = (period_us * led->cdev.brightness) /
@ -1581,6 +1589,14 @@ static int qpnp_kpdbl_set(struct qpnp_led_data *led)
}
if (led->kpdbl_cfg->pwm_cfg->mode == PWM_MODE) {
rc = pwm_change_mode(led->kpdbl_cfg->pwm_cfg->pwm_dev,
PM_PWM_MODE_PWM);
if (rc < 0) {
dev_err(&led->pdev->dev,
"Failed to set PWM mode, rc = %d\n",
rc);
return rc;
}
period_us = led->kpdbl_cfg->pwm_cfg->pwm_period_us;
if (period_us > INT_MAX / NSEC_PER_USEC) {
duty_us = (period_us * led->cdev.brightness) /
@ -1702,6 +1718,14 @@ static int qpnp_rgb_set(struct qpnp_led_data *led)
led->rgb_cfg->pwm_cfg->mode =
led->rgb_cfg->pwm_cfg->default_mode;
if (led->rgb_cfg->pwm_cfg->mode == PWM_MODE) {
rc = pwm_change_mode(led->rgb_cfg->pwm_cfg->pwm_dev,
PM_PWM_MODE_PWM);
if (rc < 0) {
dev_err(&led->pdev->dev,
"Failed to set PWM mode, rc = %d\n",
rc);
return rc;
}
period_us = led->rgb_cfg->pwm_cfg->pwm_period_us;
if (period_us > INT_MAX / NSEC_PER_USEC) {
duty_us = (period_us * led->cdev.brightness) /
@ -2136,6 +2160,11 @@ static int qpnp_pwm_init(struct pwm_config_data *pwm_cfg,
dev_err(&pdev->dev, "Failed to configure pwm LUT\n");
return rc;
}
rc = pwm_change_mode(pwm_cfg->pwm_dev, PM_PWM_MODE_LPG);
if (rc < 0) {
dev_err(&pdev->dev, "Failed to set LPG mode\n");
return rc;
}
}
} else {
dev_err(&pdev->dev, "Invalid PWM device\n");

View file

@ -328,6 +328,7 @@ struct qpnp_pwm_chip {
bool enabled;
struct _qpnp_pwm_config pwm_config;
struct qpnp_lpg_config lpg_config;
enum pm_pwm_mode pwm_mode;
spinlock_t lpg_lock;
enum qpnp_lpg_revision revision;
u8 sub_type;
@ -1314,12 +1315,10 @@ after_table_write:
return rc;
}
/* lpg_lock should be held while calling _pwm_enable() */
static int _pwm_enable(struct qpnp_pwm_chip *chip)
{
int rc = 0;
unsigned long flags;
spin_lock_irqsave(&chip->lpg_lock, flags);
if (QPNP_IS_PWM_CONFIG_SELECTED(
chip->qpnp_lpg_registers[QPNP_ENABLE_CONTROL]) ||
@ -1332,8 +1331,21 @@ static int _pwm_enable(struct qpnp_pwm_chip *chip)
if (!rc)
chip->enabled = true;
spin_unlock_irqrestore(&chip->lpg_lock, flags);
return rc;
}
/* lpg_lock should be held while calling _pwm_change_mode() */
static int _pwm_change_mode(struct qpnp_pwm_chip *chip, enum pm_pwm_mode mode)
{
int rc;
if (mode == PM_PWM_MODE_LPG)
rc = qpnp_configure_lpg_control(chip);
else
rc = qpnp_configure_pwm_control(chip);
if (rc)
pr_err("Failed to change the mode\n");
return rc;
}
@ -1410,11 +1422,15 @@ static int qpnp_pwm_enable(struct pwm_chip *pwm_chip,
{
int rc;
struct qpnp_pwm_chip *chip = qpnp_pwm_from_pwm_chip(pwm_chip);
unsigned long flags;
spin_lock_irqsave(&chip->lpg_lock, flags);
rc = _pwm_enable(chip);
if (rc)
pr_err("Failed to enable PWM channel: %d\n", chip->channel_id);
spin_unlock_irqrestore(&chip->lpg_lock, flags);
return rc;
}
@ -1452,20 +1468,6 @@ static void qpnp_pwm_disable(struct pwm_chip *pwm_chip,
chip->channel_id);
}
static int _pwm_change_mode(struct qpnp_pwm_chip *chip, enum pm_pwm_mode mode)
{
int rc;
if (mode)
rc = qpnp_configure_lpg_control(chip);
else
rc = qpnp_configure_pwm_control(chip);
if (rc)
pr_err("Failed to change the mode\n");
return rc;
}
/**
* pwm_change_mode - Change the PWM mode configuration
* @pwm: the PWM device
@ -1490,7 +1492,22 @@ int pwm_change_mode(struct pwm_device *pwm, enum pm_pwm_mode mode)
chip = qpnp_pwm_from_pwm_dev(pwm);
spin_lock_irqsave(&chip->lpg_lock, flags);
rc = _pwm_change_mode(chip, mode);
if (chip->pwm_mode != mode) {
rc = _pwm_change_mode(chip, mode);
if (rc) {
pr_err("Failed to change mode: %d, rc=%d\n", mode, rc);
goto unlock;
}
chip->pwm_mode = mode;
if (chip->enabled) {
rc = _pwm_enable(chip);
if (rc) {
pr_err("Failed to enable PWM, rc=%d\n", rc);
goto unlock;
}
}
}
unlock:
spin_unlock_irqrestore(&chip->lpg_lock, flags);
return rc;
@ -1894,7 +1911,7 @@ out:
static int qpnp_parse_dt_config(struct platform_device *pdev,
struct qpnp_pwm_chip *chip)
{
int rc, enable, lut_entry_size, list_size, i;
int rc, mode, lut_entry_size, list_size, i;
const char *label;
const __be32 *prop;
u32 size;
@ -2078,18 +2095,20 @@ static int qpnp_parse_dt_config(struct platform_device *pdev,
}
}
rc = of_property_read_u32(of_node, "qcom,mode-select", &enable);
rc = of_property_read_u32(of_node, "qcom,mode-select", &mode);
if (rc)
goto read_opt_props;
if ((enable == PM_PWM_MODE_PWM && found_pwm_subnode == 0) ||
(enable == PM_PWM_MODE_LPG && found_lpg_subnode == 0)) {
if (mode > PM_PWM_MODE_LPG ||
(mode == PM_PWM_MODE_PWM && found_pwm_subnode == 0) ||
(mode == PM_PWM_MODE_LPG && found_lpg_subnode == 0)) {
dev_err(&pdev->dev, "%s: Invalid mode select\n", __func__);
rc = -EINVAL;
goto out;
}
_pwm_change_mode(chip, enable);
chip->pwm_mode = mode;
_pwm_change_mode(chip, mode);
_pwm_enable(chip);
read_opt_props: