Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc59d81f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents a11dada4 f1b18303
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -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");
+43 −24
Original line number Diff line number Diff line
@@ -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);
	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: