/* * Because the PCA9685 has only one prescaler per chip, only the first channel * that is enabled is allowed to change the prescale register. * PWM channels requested afterwards must use a period that results in the same * prescale setting as the one set by the first requested channel. * GPIOs do not count as enabled PWMs as they are not using the prescaler.
*/
/* This function is supposed to be called with the lock mutex held */ staticbool pca9685_prescaler_can_change(struct pca9685 *pca, int channel)
{ /* No PWM enabled: Change allowed */ if (bitmap_empty(pca->pwms_enabled, PCA9685_MAXCHAN + 1)) returntrue; /* More than one PWM enabled: Change not allowed */ if (bitmap_weight(pca->pwms_enabled, PCA9685_MAXCHAN + 1) > 1) returnfalse; /* * Only one PWM enabled: Change allowed if the PWM about to * be changed is the one that is already enabled
*/ return test_bit(channel, pca->pwms_enabled);
}
err = regmap_bulk_write(pca->regmap, reg, val, 4); if (err)
dev_err(dev, "regmap_write to register 0x%x failed: %pe\n", reg, ERR_PTR(err));
return err;
}
/* Helper function to set the duty cycle ratio to duty/4096 (e.g. duty=2048 -> 50%) */ staticvoid pca9685_pwm_set_duty(struct pwm_chip *chip, int channel, unsignedint duty)
{ struct pwm_device *pwm = &chip->pwms[channel]; unsignedint on, off;
if (duty == 0) { /* Set the full OFF bit, which has the highest precedence */
pca9685_write_reg(chip, REG_OFF_H(channel), LED_FULL); return;
} elseif (duty >= PCA9685_COUNTER_RANGE) { /* Set the full ON bit and clear the full OFF bit */
pca9685_write_4reg(chip, REG_ON_L(channel), (u8[4]){ 0, LED_FULL, 0, 0 }); return;
}
if (pwm->state.usage_power && channel < PCA9685_MAXCHAN) { /* * If usage_power is set, the pca9685 driver will phase shift * the individual channels relative to their channel number. * This improves EMI because the enabled channels no longer * turn on at the same time, while still maintaining the * configured duty cycle / power output.
*/
on = channel * PCA9685_COUNTER_RANGE / PCA9685_MAXCHAN;
} else
on = 0;
off = (on + duty) % PCA9685_COUNTER_RANGE;
/* implicitly clear full ON and full OFF bit */
pca9685_write_4reg(chip, REG_ON_L(channel),
(u8[4]){ on & 0xff, (on >> 8) & 0xf, off & 0xff, (off >> 8) & 0xf });
}
staticunsignedint pca9685_pwm_get_duty(struct pwm_chip *chip, int channel)
{ struct pwm_device *pwm = &chip->pwms[channel]; unsignedint off = 0, on = 0, val = 0;
if (WARN_ON(channel >= PCA9685_MAXCHAN)) { /* HW does not support reading state of "all LEDs" channel */ return 0;
}
pca9685_read_reg(chip, LED_N_OFF_H(channel), &off); if (off & LED_FULL) { /* Full OFF bit is set */ return 0;
}
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(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(chip, LED_N_ON_L(channel), &val)) { /* Reset val to 0 in case reading LED_N_ON_L failed */
val = 0;
}
on = ((on & 0xf) << 8) | (val & 0xff); return (off - on) & (PCA9685_COUNTER_RANGE - 1);
}
mutex_lock(&pca->lock); if (pwm_idx >= PCA9685_MAXCHAN) { /* * "All LEDs" channel: * pretend already in use if any of the PWMs are requested
*/ if (!bitmap_empty(pca->pwms_inuse, PCA9685_MAXCHAN)) {
is_inuse = true; goto out;
}
} else { /* * Regular channel: * pretend already in use if the "all LEDs" channel is requested
*/ if (test_bit(PCA9685_MAXCHAN, pca->pwms_inuse)) {
is_inuse = true; goto out;
}
}
is_inuse = test_and_set_bit(pwm_idx, pca->pwms_inuse);
out:
mutex_unlock(&pca->lock); return is_inuse;
}
/* * The PCA9685 has a bit for turning the PWM output full off or on. Some * boards like Intel Galileo actually uses these as normal GPIOs so we * expose a GPIO chip here which can exclusively take over the underlying * PWM channel.
*/ staticint pca9685_pwm_gpio_probe(struct pwm_chip *chip)
{ struct pca9685 *pca = to_pca(chip); struct device *dev = pwmchip_parent(chip);
if (state->polarity != PWM_POLARITY_NORMAL) return -EINVAL;
prescale = DIV_ROUND_CLOSEST_ULL(PCA9685_OSC_CLOCK_MHZ * state->period,
PCA9685_COUNTER_RANGE * 1000) - 1; if (prescale < PCA9685_PRESCALE_MIN || prescale > PCA9685_PRESCALE_MAX) {
dev_err(pwmchip_parent(chip), "pwm not changed: period out of bounds!\n"); return -EINVAL;
}
if (!state->enabled) {
pca9685_pwm_set_duty(chip, pwm->hwpwm, 0); return 0;
}
pca9685_read_reg(chip, PCA9685_PRESCALE, &val); if (prescale != val) { if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) {
dev_err(pwmchip_parent(chip), "pwm not changed: periods of enabled pwms must match!\n"); return -EBUSY;
}
/* * Putting the chip briefly into SLEEP mode * at this point won't interfere with the * pm_runtime framework, because the pm_runtime * state is guaranteed active here.
*/ /* Put chip into sleep mode */
pca9685_set_sleep_mode(chip, true);
/* Change the chip-wide output frequency */
pca9685_write_reg(chip, PCA9685_PRESCALE, prescale);
/* Wake the chip up */
pca9685_set_sleep_mode(chip, false);
}
/* Calculate (chip-wide) period from prescale value */
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 * and we are not losing precision.
*/
state->period = (PCA9685_COUNTER_RANGE * 1000 / PCA9685_OSC_CLOCK_MHZ) *
(val + 1);
/* The (per-channel) polarity is fixed */
state->polarity = PWM_POLARITY_NORMAL;
if (pwm->hwpwm >= PCA9685_MAXCHAN) { /* * The "all LEDs" channel does not support HW readout * Return 0 and disabled for backwards compatibility
*/
state->duty_cycle = 0;
state->enabled = false; return 0;
}
/* Add an extra channel for ALL_LED */
chip = devm_pwmchip_alloc(&client->dev, PCA9685_MAXCHAN + 1, sizeof(*pca)); if (IS_ERR(chip)) return PTR_ERR(chip);
pca = to_pca(chip);
pca->regmap = devm_regmap_init_i2c(client, &pca9685_regmap_i2c_config); if (IS_ERR(pca->regmap)) {
ret = PTR_ERR(pca->regmap);
dev_err(&client->dev, "Failed to initialize register map: %d\n",
ret); return ret;
}
i2c_set_clientdata(client, chip);
mutex_init(&pca->lock);
/* clear MODE2_OCH */
reg = 0;
if (device_property_read_bool(&client->dev, "invert"))
reg |= MODE2_INVRT; else
reg &= ~MODE2_INVRT;
if (device_property_read_bool(&client->dev, "open-drain"))
reg &= ~MODE2_OUTDRV; else
reg |= MODE2_OUTDRV;
ret = pca9685_write_reg(chip, PCA9685_MODE2, reg); if (ret) return ret;
/* * Disable all LED ALLCALL and SUBx addresses to avoid bus collisions, * enable Auto-Increment.
*/
pca9685_read_reg(chip, PCA9685_MODE1, ®);
reg &= ~(MODE1_ALLCALL | MODE1_SUB1 | MODE1_SUB2 | MODE1_SUB3);
reg |= MODE1_AI;
pca9685_write_reg(chip, PCA9685_MODE1, reg);
/* Reset OFF/ON registers to POR default */
ret = pca9685_write_4reg(chip, PCA9685_ALL_LED_ON_L, (u8[]){ 0, LED_FULL, 0, LED_FULL }); if (ret < 0) return dev_err_probe(&client->dev, ret, "Failed to reset ON/OFF registers\n");
chip->ops = &pca9685_pwm_ops;
ret = pwmchip_add(chip); if (ret < 0) return ret;
ret = pca9685_pwm_gpio_probe(chip); if (ret < 0) {
pwmchip_remove(chip); return ret;
}
pm_runtime_enable(&client->dev);
if (pm_runtime_enabled(&client->dev)) { /* * 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(chip, true);
pm_runtime_set_suspended(&client->dev);
} else { /* Wake the chip up if runtime PM is disabled */
pca9685_set_sleep_mode(chip, false);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.