diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2024-02-14 10:32:08 +0100 |
---|---|---|
committer | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2024-02-19 11:04:12 +0100 |
commit | da5a8c555c52e36040c7ccea6a9136349eb16f18 (patch) | |
tree | 21b44782aac9ca975a72f4977c28923d01790130 /drivers/pwm | |
parent | f988b8196322b11c9b49c8df56aa4fada8a6b96a (diff) |
pwm: pca9685: Prepare removing pwm_chip from driver data
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>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-pca9685.c | 143 |
1 files changed, 75 insertions, 68 deletions
diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c index e79b1de8c4d8..d7542517fa49 100644 --- a/drivers/pwm/pwm-pca9685.c +++ b/drivers/pwm/pwm-pca9685.c @@ -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, ®); + ret = pca9685_read_reg(chip, PCA9685_MODE2, ®); 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, ®); + pca9685_read_reg(chip, PCA9685_MODE1, ®); 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; } |