pwm: pca9685: Prepare removing pwm_chip from driver data
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Wed, 14 Feb 2024 09:32:08 +0000 (10:32 +0100)
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Mon, 19 Feb 2024 10:04:12 +0000 (11:04 +0100)
This prepares the driver for further changes that will drop struct
pwm_chip chip from struct pca9685. Use the pwm_chip as i2c client data
and gpiochip data instead of the pca9685 to get access to the
pwm_chip in pca9685_pwm_remove(), pca9685_pwm_runtime_suspend(),
pca9685_pwm_runtime_resume(), pca9685_pwm_gpio_request() and the gpio
callbacks without using pca->chip. Also the prototype for various helper
functions is changed to take a pwm_chip instead of a pca9685 for the
same reason.

Link: https://lore.kernel.org/r/e87b378545cee15a52f0d410fcceebf671ab90e0.1707900770.git.u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
drivers/pwm/pwm-pca9685.c

index e79b1de..d754251 100644 (file)
@@ -107,9 +107,10 @@ static bool pca9685_prescaler_can_change(struct pca9685 *pca, int channel)
        return test_bit(channel, pca->pwms_enabled);
 }
 
-static int pca9685_read_reg(struct pca9685 *pca, unsigned int reg, unsigned int *val)
+static int pca9685_read_reg(struct pwm_chip *chip, unsigned int reg, unsigned int *val)
 {
-       struct device *dev = pca->chip.dev;
+       struct pca9685 *pca = to_pca(chip);
+       struct device *dev = chip->dev;
        int err;
 
        err = regmap_read(pca->regmap, reg, val);
@@ -119,9 +120,10 @@ static int pca9685_read_reg(struct pca9685 *pca, unsigned int reg, unsigned int
        return err;
 }
 
-static int pca9685_write_reg(struct pca9685 *pca, unsigned int reg, unsigned int val)
+static int pca9685_write_reg(struct pwm_chip *chip, unsigned int reg, unsigned int val)
 {
-       struct device *dev = pca->chip.dev;
+       struct pca9685 *pca = to_pca(chip);
+       struct device *dev = chip->dev;
        int err;
 
        err = regmap_write(pca->regmap, reg, val);
@@ -132,19 +134,19 @@ static int pca9685_write_reg(struct pca9685 *pca, unsigned int reg, unsigned int
 }
 
 /* Helper function to set the duty cycle ratio to duty/4096 (e.g. duty=2048 -> 50%) */
-static void pca9685_pwm_set_duty(struct pca9685 *pca, int channel, unsigned int duty)
+static void pca9685_pwm_set_duty(struct pwm_chip *chip, int channel, unsigned int duty)
 {
-       struct pwm_device *pwm = &pca->chip.pwms[channel];
+       struct pwm_device *pwm = &chip->pwms[channel];
        unsigned int on, off;
 
        if (duty == 0) {
                /* Set the full OFF bit, which has the highest precedence */
-               pca9685_write_reg(pca, REG_OFF_H(channel), LED_FULL);
+               pca9685_write_reg(chip, REG_OFF_H(channel), LED_FULL);
                return;
        } else if (duty >= PCA9685_COUNTER_RANGE) {
                /* Set the full ON bit and clear the full OFF bit */
-               pca9685_write_reg(pca, REG_ON_H(channel), LED_FULL);
-               pca9685_write_reg(pca, REG_OFF_H(channel), 0);
+               pca9685_write_reg(chip, REG_ON_H(channel), LED_FULL);
+               pca9685_write_reg(chip, REG_OFF_H(channel), 0);
                return;
        }
 
@@ -164,16 +166,16 @@ static void pca9685_pwm_set_duty(struct pca9685 *pca, int channel, unsigned int
        off = (on + duty) % PCA9685_COUNTER_RANGE;
 
        /* Set ON time (clears full ON bit) */
-       pca9685_write_reg(pca, REG_ON_L(channel), on & 0xff);
-       pca9685_write_reg(pca, REG_ON_H(channel), (on >> 8) & 0xf);
+       pca9685_write_reg(chip, REG_ON_L(channel), on & 0xff);
+       pca9685_write_reg(chip, REG_ON_H(channel), (on >> 8) & 0xf);
        /* Set OFF time (clears full OFF bit) */
-       pca9685_write_reg(pca, REG_OFF_L(channel), off & 0xff);
-       pca9685_write_reg(pca, REG_OFF_H(channel), (off >> 8) & 0xf);
+       pca9685_write_reg(chip, REG_OFF_L(channel), off & 0xff);
+       pca9685_write_reg(chip, REG_OFF_H(channel), (off >> 8) & 0xf);
 }
 
-static unsigned int pca9685_pwm_get_duty(struct pca9685 *pca, int channel)
+static unsigned int pca9685_pwm_get_duty(struct pwm_chip *chip, int channel)
 {
-       struct pwm_device *pwm = &pca->chip.pwms[channel];
+       struct pwm_device *pwm = &chip->pwms[channel];
        unsigned int off = 0, on = 0, val = 0;
 
        if (WARN_ON(channel >= PCA9685_MAXCHAN)) {
@@ -181,25 +183,25 @@ static unsigned int pca9685_pwm_get_duty(struct pca9685 *pca, int channel)
                return 0;
        }
 
-       pca9685_read_reg(pca, LED_N_OFF_H(channel), &off);
+       pca9685_read_reg(chip, LED_N_OFF_H(channel), &off);
        if (off & LED_FULL) {
                /* Full OFF bit is set */
                return 0;
        }
 
-       pca9685_read_reg(pca, LED_N_ON_H(channel), &on);
+       pca9685_read_reg(chip, LED_N_ON_H(channel), &on);
        if (on & LED_FULL) {
                /* Full ON bit is set */
                return PCA9685_COUNTER_RANGE;
        }
 
-       pca9685_read_reg(pca, LED_N_OFF_L(channel), &val);
+       pca9685_read_reg(chip, LED_N_OFF_L(channel), &val);
        off = ((off & 0xf) << 8) | (val & 0xff);
        if (!pwm->state.usage_power)
                return off;
 
        /* Read ON register to calculate duty cycle of staggered output */
-       if (pca9685_read_reg(pca, LED_N_ON_L(channel), &val)) {
+       if (pca9685_read_reg(chip, LED_N_ON_L(channel), &val)) {
                /* Reset val to 0 in case reading LED_N_ON_L failed */
                val = 0;
        }
@@ -247,35 +249,37 @@ static void pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx)
 
 static int pca9685_pwm_gpio_request(struct gpio_chip *gpio, unsigned int offset)
 {
-       struct pca9685 *pca = gpiochip_get_data(gpio);
+       struct pwm_chip *chip = gpiochip_get_data(gpio);
+       struct pca9685 *pca = to_pca(chip);
 
        if (pca9685_pwm_test_and_set_inuse(pca, offset))
                return -EBUSY;
-       pm_runtime_get_sync(pca->chip.dev);
+       pm_runtime_get_sync(chip->dev);
        return 0;
 }
 
 static int pca9685_pwm_gpio_get(struct gpio_chip *gpio, unsigned int offset)
 {
-       struct pca9685 *pca = gpiochip_get_data(gpio);
+       struct pwm_chip *chip = gpiochip_get_data(gpio);
 
-       return pca9685_pwm_get_duty(pca, offset) != 0;
+       return pca9685_pwm_get_duty(chip, offset) != 0;
 }
 
 static void pca9685_pwm_gpio_set(struct gpio_chip *gpio, unsigned int offset,
                                 int value)
 {
-       struct pca9685 *pca = gpiochip_get_data(gpio);
+       struct pwm_chip *chip = gpiochip_get_data(gpio);
 
-       pca9685_pwm_set_duty(pca, offset, value ? PCA9685_COUNTER_RANGE : 0);
+       pca9685_pwm_set_duty(chip, offset, value ? PCA9685_COUNTER_RANGE : 0);
 }
 
 static void pca9685_pwm_gpio_free(struct gpio_chip *gpio, unsigned int offset)
 {
-       struct pca9685 *pca = gpiochip_get_data(gpio);
+       struct pwm_chip *chip = gpiochip_get_data(gpio);
+       struct pca9685 *pca = to_pca(chip);
 
-       pca9685_pwm_set_duty(pca, offset, 0);
-       pm_runtime_put(pca->chip.dev);
+       pca9685_pwm_set_duty(chip, offset, 0);
+       pm_runtime_put(chip->dev);
        pca9685_pwm_clear_inuse(pca, offset);
 }
 
@@ -306,9 +310,10 @@ static int pca9685_pwm_gpio_direction_output(struct gpio_chip *gpio,
  * expose a GPIO chip here which can exclusively take over the underlying
  * PWM channel.
  */
-static int pca9685_pwm_gpio_probe(struct pca9685 *pca)
+static int pca9685_pwm_gpio_probe(struct pwm_chip *chip)
 {
-       struct device *dev = pca->chip.dev;
+       struct pca9685 *pca = to_pca(chip);
+       struct device *dev = chip->dev;
 
        pca->gpio.label = dev_name(dev);
        pca->gpio.parent = dev;
@@ -323,7 +328,7 @@ static int pca9685_pwm_gpio_probe(struct pca9685 *pca)
        pca->gpio.ngpio = PCA9685_MAXCHAN;
        pca->gpio.can_sleep = true;
 
-       return devm_gpiochip_add_data(dev, &pca->gpio, pca);
+       return devm_gpiochip_add_data(dev, &pca->gpio, chip);
 }
 #else
 static inline bool pca9685_pwm_test_and_set_inuse(struct pca9685 *pca,
@@ -337,15 +342,16 @@ pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx)
 {
 }
 
-static inline int pca9685_pwm_gpio_probe(struct pca9685 *pca)
+static inline int pca9685_pwm_gpio_probe(struct pwm_chip *chip)
 {
        return 0;
 }
 #endif
 
-static void pca9685_set_sleep_mode(struct pca9685 *pca, bool enable)
+static void pca9685_set_sleep_mode(struct pwm_chip *chip, bool enable)
 {
-       struct device *dev = pca->chip.dev;
+       struct device *dev = chip->dev;
+       struct pca9685 *pca = to_pca(chip);
        int err = regmap_update_bits(pca->regmap, PCA9685_MODE1,
                                     MODE1_SLEEP, enable ? MODE1_SLEEP : 0);
        if (err) {
@@ -378,11 +384,11 @@ static int __pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        }
 
        if (!state->enabled) {
-               pca9685_pwm_set_duty(pca, pwm->hwpwm, 0);
+               pca9685_pwm_set_duty(chip, pwm->hwpwm, 0);
                return 0;
        }
 
-       pca9685_read_reg(pca, PCA9685_PRESCALE, &val);
+       pca9685_read_reg(chip, PCA9685_PRESCALE, &val);
        if (prescale != val) {
                if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) {
                        dev_err(chip->dev,
@@ -397,18 +403,18 @@ static int __pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                 * state is guaranteed active here.
                 */
                /* Put chip into sleep mode */
-               pca9685_set_sleep_mode(pca, true);
+               pca9685_set_sleep_mode(chip, true);
 
                /* Change the chip-wide output frequency */
-               pca9685_write_reg(pca, PCA9685_PRESCALE, prescale);
+               pca9685_write_reg(chip, PCA9685_PRESCALE, prescale);
 
                /* Wake the chip up */
-               pca9685_set_sleep_mode(pca, false);
+               pca9685_set_sleep_mode(chip, false);
        }
 
        duty = PCA9685_COUNTER_RANGE * state->duty_cycle;
        duty = DIV_ROUND_UP_ULL(duty, state->period);
-       pca9685_pwm_set_duty(pca, pwm->hwpwm, duty);
+       pca9685_pwm_set_duty(chip, pwm->hwpwm, duty);
        return 0;
 }
 
@@ -434,12 +440,11 @@ static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
                                 struct pwm_state *state)
 {
-       struct pca9685 *pca = to_pca(chip);
        unsigned long long duty;
        unsigned int val = 0;
 
        /* Calculate (chip-wide) period from prescale value */
-       pca9685_read_reg(pca, PCA9685_PRESCALE, &val);
+       pca9685_read_reg(chip, PCA9685_PRESCALE, &val);
        /*
         * PCA9685_OSC_CLOCK_MHZ is 25, i.e. an integer divider of 1000.
         * The following calculation is therefore only a multiplication
@@ -462,7 +467,7 @@ static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        }
 
        state->enabled = true;
-       duty = pca9685_pwm_get_duty(pca, pwm->hwpwm);
+       duty = pca9685_pwm_get_duty(chip, pwm->hwpwm);
        state->duty_cycle = DIV_ROUND_DOWN_ULL(duty * state->period, PCA9685_COUNTER_RANGE);
 
        return 0;
@@ -492,7 +497,7 @@ static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
        struct pca9685 *pca = to_pca(chip);
 
        mutex_lock(&pca->lock);
-       pca9685_pwm_set_duty(pca, pwm->hwpwm, 0);
+       pca9685_pwm_set_duty(chip, pwm->hwpwm, 0);
        clear_bit(pwm->hwpwm, pca->pwms_enabled);
        mutex_unlock(&pca->lock);
 
@@ -516,6 +521,7 @@ static const struct regmap_config pca9685_regmap_i2c_config = {
 
 static int pca9685_pwm_probe(struct i2c_client *client)
 {
+       struct pwm_chip *chip;
        struct pca9685 *pca;
        unsigned int reg;
        int ret;
@@ -531,12 +537,13 @@ static int pca9685_pwm_probe(struct i2c_client *client)
                        ret);
                return ret;
        }
+       chip = &pca->chip;
 
-       i2c_set_clientdata(client, pca);
+       i2c_set_clientdata(client, chip);
 
        mutex_init(&pca->lock);
 
-       ret = pca9685_read_reg(pca, PCA9685_MODE2, &reg);
+       ret = pca9685_read_reg(chip, PCA9685_MODE2, &reg);
        if (ret)
                return ret;
 
@@ -550,34 +557,34 @@ static int pca9685_pwm_probe(struct i2c_client *client)
        else
                reg |= MODE2_OUTDRV;
 
-       ret = pca9685_write_reg(pca, PCA9685_MODE2, reg);
+       ret = pca9685_write_reg(chip, PCA9685_MODE2, reg);
        if (ret)
                return ret;
 
        /* Disable all LED ALLCALL and SUBx addresses to avoid bus collisions */
-       pca9685_read_reg(pca, PCA9685_MODE1, &reg);
+       pca9685_read_reg(chip, PCA9685_MODE1, &reg);
        reg &= ~(MODE1_ALLCALL | MODE1_SUB1 | MODE1_SUB2 | MODE1_SUB3);
-       pca9685_write_reg(pca, PCA9685_MODE1, reg);
+       pca9685_write_reg(chip, PCA9685_MODE1, reg);
 
        /* Reset OFF/ON registers to POR default */
-       pca9685_write_reg(pca, PCA9685_ALL_LED_OFF_L, 0);
-       pca9685_write_reg(pca, PCA9685_ALL_LED_OFF_H, LED_FULL);
-       pca9685_write_reg(pca, PCA9685_ALL_LED_ON_L, 0);
-       pca9685_write_reg(pca, PCA9685_ALL_LED_ON_H, LED_FULL);
+       pca9685_write_reg(chip, PCA9685_ALL_LED_OFF_L, 0);
+       pca9685_write_reg(chip, PCA9685_ALL_LED_OFF_H, LED_FULL);
+       pca9685_write_reg(chip, PCA9685_ALL_LED_ON_L, 0);
+       pca9685_write_reg(chip, PCA9685_ALL_LED_ON_H, LED_FULL);
 
-       pca->chip.ops = &pca9685_pwm_ops;
+       chip->ops = &pca9685_pwm_ops;
        /* Add an extra channel for ALL_LED */
-       pca->chip.npwm = PCA9685_MAXCHAN + 1;
+       chip->npwm = PCA9685_MAXCHAN + 1;
 
-       pca->chip.dev = &client->dev;
+       chip->dev = &client->dev;
 
-       ret = pwmchip_add(&pca->chip);
+       ret = pwmchip_add(chip);
        if (ret < 0)
                return ret;
 
-       ret = pca9685_pwm_gpio_probe(pca);
+       ret = pca9685_pwm_gpio_probe(chip);
        if (ret < 0) {
-               pwmchip_remove(&pca->chip);
+               pwmchip_remove(chip);
                return ret;
        }
 
@@ -588,11 +595,11 @@ static int pca9685_pwm_probe(struct i2c_client *client)
                 * Although the chip comes out of power-up in the sleep state,
                 * we force it to sleep in case it was woken up before
                 */
-               pca9685_set_sleep_mode(pca, true);
+               pca9685_set_sleep_mode(chip, true);
                pm_runtime_set_suspended(&client->dev);
        } else {
                /* Wake the chip up if runtime PM is disabled */
-               pca9685_set_sleep_mode(pca, false);
+               pca9685_set_sleep_mode(chip, false);
        }
 
        return 0;
@@ -600,13 +607,13 @@ static int pca9685_pwm_probe(struct i2c_client *client)
 
 static void pca9685_pwm_remove(struct i2c_client *client)
 {
-       struct pca9685 *pca = i2c_get_clientdata(client);
+       struct pwm_chip *chip = i2c_get_clientdata(client);
 
-       pwmchip_remove(&pca->chip);
+       pwmchip_remove(chip);
 
        if (!pm_runtime_enabled(&client->dev)) {
                /* Put chip in sleep state if runtime PM is disabled */
-               pca9685_set_sleep_mode(pca, true);
+               pca9685_set_sleep_mode(chip, true);
        }
 
        pm_runtime_disable(&client->dev);
@@ -615,18 +622,18 @@ static void pca9685_pwm_remove(struct i2c_client *client)
 static int __maybe_unused pca9685_pwm_runtime_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
-       struct pca9685 *pca = i2c_get_clientdata(client);
+       struct pwm_chip *chip = i2c_get_clientdata(client);
 
-       pca9685_set_sleep_mode(pca, true);
+       pca9685_set_sleep_mode(chip, true);
        return 0;
 }
 
 static int __maybe_unused pca9685_pwm_runtime_resume(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
-       struct pca9685 *pca = i2c_get_clientdata(client);
+       struct pwm_chip *chip = i2c_get_clientdata(client);
 
-       pca9685_set_sleep_mode(pca, false);
+       pca9685_set_sleep_mode(chip, false);
        return 0;
 }