Hi Clemens, On Mon, Apr 12, 2021 at 07:11:58PM +0200, Clemens Gruber wrote: > On Mon, Apr 12, 2021 at 06:30:45PM +0200, Uwe Kleine-König wrote: > > On Mon, Apr 12, 2021 at 03:27:43PM +0200, Clemens Gruber wrote: > > > static unsigned int pca9685_pwm_get_duty(struct pca9685 *pca, int channel) > > > { > > > - unsigned int off_h = 0, val = 0; > > > + struct pwm_device *pwm = &pca->chip.pwms[channel]; > > > + unsigned int off = 0, on = 0, val = 0; > > > > > > if (WARN_ON(channel >= PCA9685_MAXCHAN)) { > > > /* HW does not support reading state of "all LEDs" channel */ > > > return 0; > > > } > > > > > > - regmap_read(pca->regmap, LED_N_OFF_H(channel), &off_h); > > > - if (off_h & LED_FULL) { > > > + regmap_read(pca->regmap, LED_N_OFF_H(channel), &off); > > > + if (off & LED_FULL) { > > > /* Full OFF bit is set */ > > > return 0; > > > } > > > > > > - regmap_read(pca->regmap, LED_N_ON_H(channel), &val); > > > - if (val & LED_FULL) { > > > + regmap_read(pca->regmap, LED_N_ON_H(channel), &on); > > > + if (on & LED_FULL) { > > > /* Full ON bit is set */ > > > return PCA9685_COUNTER_RANGE; > > > } > > > > > > - val = 0; > > > regmap_read(pca->regmap, LED_N_OFF_L(channel), &val); > > > - return ((off_h & 0xf) << 8) | (val & 0xff); > > > + off = ((off & 0xf) << 8) | (val & 0xff); > > > + if (!pwm->args.usage_power) > > > + return off; > > > + > > > + /* Read ON register to calculate duty cycle of staggered output */ > > > + val = 0; > > > + regmap_read(pca->regmap, LED_N_ON_L(channel), &val); > > > + on = ((on & 0xf) << 8) | (val & 0xff); > > > + return (off - on) & (PCA9685_COUNTER_RANGE - 1); > > > > If LED_N_ON is != 0 but usage_power is false, the returned state is > > bogus. > > If usage_power is false, LED_N_ON is guaranteed to be 0. It is reset to > 0 in probe and never changed. Or did I miss something? Ah right, so my concern is only a challenge once the reset in probe goes away. > > > } > > > > > > #if IS_ENABLED(CONFIG_GPIOLIB) > > > @@ -439,9 +469,11 @@ static int pca9685_pwm_probe(struct i2c_client *client, > > > reg &= ~(MODE1_ALLCALL | MODE1_SUB1 | MODE1_SUB2 | MODE1_SUB3); > > > regmap_write(pca->regmap, PCA9685_MODE1, reg); > > > > > > - /* Reset OFF registers to POR default */ > > > + /* Reset OFF/ON registers to POR default */ > > > regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_L, LED_FULL); > > > regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, LED_FULL); > > > + regmap_write(pca->regmap, PCA9685_ALL_LED_ON_L, 0); > > > + regmap_write(pca->regmap, PCA9685_ALL_LED_ON_H, 0); > > > > > > pca->chip.ops = &pca9685_pwm_ops; > > > /* Add an extra channel for ALL_LED */ > > > @@ -450,6 +482,9 @@ static int pca9685_pwm_probe(struct i2c_client *client, > > > pca->chip.dev = &client->dev; > > > pca->chip.base = -1; > > > > > > + pca->chip.of_xlate = of_pwm_xlate_with_flags; > > > + pca->chip.of_pwm_n_cells = 3; > > > + > > > > Huh, you're incompatibly changing the device tree binding here. > > No, I don't think so: > > The third cell is optional with of_pwm_xlate_with_flags. > So previous DTs with pwm-cells = <2> will still work. I thought that .of_pwm_n_cells was enforced, let me check the code ... I had in mind that of_pwm_get() enforced that, but I cannot find it, so I guess you're right and my concern is unjustified. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |
Attachment:
signature.asc
Description: PGP signature