|
49 | 49 | #define PCA9685_PRESCALE_MAX 0xFF /* => min. frequency of 24 Hz */ |
50 | 50 |
|
51 | 51 | #define PCA9685_COUNTER_RANGE 4096 |
52 | | -#define PCA9685_OSC_CLOCK_MHZ 25 /* Internal oscillator with 25 MHz */ |
| 52 | +#define PCA9685_OSC_CLOCK_HZ 25000000 /* Internal oscillator with 25 MHz */ |
| 53 | + |
| 54 | +/* |
| 55 | + * The time value of one counter tick. Note that NSEC_PER_SEC is an integer |
| 56 | + * multiple of PCA9685_OSC_CLOCK_HZ, so there is no rounding involved and we're |
| 57 | + * not loosing precision due to the early division. |
| 58 | + */ |
| 59 | +#define PCA9685_QUANTUM_NS(_prescale) ((NSEC_PER_SEC / PCA9685_OSC_CLOCK_HZ) * (_prescale + 1)) |
53 | 60 |
|
54 | 61 | #define PCA9685_NUMREGS 0xFF |
55 | 62 | #define PCA9685_MAXCHAN 0x10 |
@@ -141,200 +148,213 @@ static int pca9685_write_4reg(struct pwm_chip *chip, unsigned int reg, u8 val[4] |
141 | 148 | return err; |
142 | 149 | } |
143 | 150 |
|
144 | | -/* Helper function to set the duty cycle ratio to duty/4096 (e.g. duty=2048 -> 50%) */ |
145 | | -static void pca9685_pwm_set_duty(struct pwm_chip *chip, int channel, unsigned int duty) |
| 151 | +static int pca9685_set_sleep_mode(struct pwm_chip *chip, bool enable) |
146 | 152 | { |
147 | | - struct pwm_device *pwm = &chip->pwms[channel]; |
148 | | - unsigned int on, off; |
149 | | - |
150 | | - if (duty == 0) { |
151 | | - /* Set the full OFF bit, which has the highest precedence */ |
152 | | - pca9685_write_reg(chip, REG_OFF_H(channel), LED_FULL); |
153 | | - return; |
154 | | - } else if (duty >= PCA9685_COUNTER_RANGE) { |
155 | | - /* Set the full ON bit and clear the full OFF bit */ |
156 | | - pca9685_write_4reg(chip, REG_ON_L(channel), (u8[4]){ 0, LED_FULL, 0, 0 }); |
157 | | - return; |
158 | | - } |
| 153 | + struct pca9685 *pca = to_pca(chip); |
| 154 | + int err; |
159 | 155 |
|
160 | | - if (pwm->state.usage_power && channel < PCA9685_MAXCHAN) { |
161 | | - /* |
162 | | - * If usage_power is set, the pca9685 driver will phase shift |
163 | | - * the individual channels relative to their channel number. |
164 | | - * This improves EMI because the enabled channels no longer |
165 | | - * turn on at the same time, while still maintaining the |
166 | | - * configured duty cycle / power output. |
167 | | - */ |
168 | | - on = channel * PCA9685_COUNTER_RANGE / PCA9685_MAXCHAN; |
169 | | - } else |
170 | | - on = 0; |
| 156 | + err = regmap_update_bits(pca->regmap, PCA9685_MODE1, |
| 157 | + MODE1_SLEEP, enable ? MODE1_SLEEP : 0); |
| 158 | + if (err) |
| 159 | + return err; |
171 | 160 |
|
172 | | - off = (on + duty) % PCA9685_COUNTER_RANGE; |
| 161 | + if (!enable) { |
| 162 | + /* Wait 500us for the oscillator to be back up */ |
| 163 | + udelay(500); |
| 164 | + } |
173 | 165 |
|
174 | | - /* implicitly clear full ON and full OFF bit */ |
175 | | - pca9685_write_4reg(chip, REG_ON_L(channel), |
176 | | - (u8[4]){ on & 0xff, (on >> 8) & 0xf, off & 0xff, (off >> 8) & 0xf }); |
| 166 | + return 0; |
177 | 167 | } |
178 | 168 |
|
179 | | -static unsigned int pca9685_pwm_get_duty(struct pwm_chip *chip, int channel) |
| 169 | +struct pca9685_waveform { |
| 170 | + u8 onoff[4]; |
| 171 | + u8 prescale; |
| 172 | +}; |
| 173 | + |
| 174 | +static int pca9685_round_waveform_tohw(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_waveform *wf, void *_wfhw) |
180 | 175 | { |
181 | | - struct pwm_device *pwm = &chip->pwms[channel]; |
182 | | - unsigned int off = 0, on = 0, val = 0; |
| 176 | + struct pca9685_waveform *wfhw = _wfhw; |
| 177 | + struct pca9685 *pca = to_pca(chip); |
| 178 | + unsigned int best_prescale; |
| 179 | + u8 prescale; |
| 180 | + unsigned int period_ns, duty; |
| 181 | + int ret_tohw = 0; |
183 | 182 |
|
184 | | - if (WARN_ON(channel >= PCA9685_MAXCHAN)) { |
185 | | - /* HW does not support reading state of "all LEDs" channel */ |
186 | | - return 0; |
187 | | - } |
| 183 | + if (!wf->period_length_ns) { |
| 184 | + *wfhw = (typeof(*wfhw)){ |
| 185 | + .onoff = { 0, 0, 0, LED_FULL, }, |
| 186 | + .prescale = 0, |
| 187 | + }; |
| 188 | + |
| 189 | + dev_dbg(&chip->dev, "pwm#%u: %lld/%lld [+%lld] -> [%hhx %hhx %hhx %hhx] PSC:%hhx\n", |
| 190 | + pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns, |
| 191 | + wfhw->onoff[0], wfhw->onoff[1], wfhw->onoff[2], wfhw->onoff[3], wfhw->prescale); |
188 | 192 |
|
189 | | - pca9685_read_reg(chip, LED_N_OFF_H(channel), &off); |
190 | | - if (off & LED_FULL) { |
191 | | - /* Full OFF bit is set */ |
192 | 193 | return 0; |
193 | 194 | } |
194 | 195 |
|
195 | | - pca9685_read_reg(chip, LED_N_ON_H(channel), &on); |
196 | | - if (on & LED_FULL) { |
197 | | - /* Full ON bit is set */ |
198 | | - return PCA9685_COUNTER_RANGE; |
| 196 | + if (wf->period_length_ns >= PCA9685_COUNTER_RANGE * PCA9685_QUANTUM_NS(255)) { |
| 197 | + best_prescale = 255; |
| 198 | + } else if (wf->period_length_ns < PCA9685_COUNTER_RANGE * PCA9685_QUANTUM_NS(3)) { |
| 199 | + best_prescale = 3; |
| 200 | + ret_tohw = 1; |
| 201 | + } else { |
| 202 | + best_prescale = (unsigned int)wf->period_length_ns / (PCA9685_COUNTER_RANGE * (NSEC_PER_SEC / PCA9685_OSC_CLOCK_HZ)) - 1; |
199 | 203 | } |
200 | 204 |
|
201 | | - pca9685_read_reg(chip, LED_N_OFF_L(channel), &val); |
202 | | - off = ((off & 0xf) << 8) | (val & 0xff); |
203 | | - if (!pwm->state.usage_power) |
204 | | - return off; |
| 205 | + guard(mutex)(&pca->lock); |
205 | 206 |
|
206 | | - /* Read ON register to calculate duty cycle of staggered output */ |
207 | | - if (pca9685_read_reg(chip, LED_N_ON_L(channel), &val)) { |
208 | | - /* Reset val to 0 in case reading LED_N_ON_L failed */ |
209 | | - val = 0; |
210 | | - } |
211 | | - on = ((on & 0xf) << 8) | (val & 0xff); |
212 | | - return (off - on) & (PCA9685_COUNTER_RANGE - 1); |
213 | | -} |
| 207 | + if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) { |
| 208 | + unsigned int current_prescale; |
| 209 | + int ret; |
214 | 210 |
|
215 | | -static void pca9685_set_sleep_mode(struct pwm_chip *chip, bool enable) |
216 | | -{ |
217 | | - struct device *dev = pwmchip_parent(chip); |
218 | | - struct pca9685 *pca = to_pca(chip); |
219 | | - int err = regmap_update_bits(pca->regmap, PCA9685_MODE1, |
220 | | - MODE1_SLEEP, enable ? MODE1_SLEEP : 0); |
221 | | - if (err) { |
222 | | - dev_err(dev, "regmap_update_bits of register 0x%x failed: %pe\n", |
223 | | - PCA9685_MODE1, ERR_PTR(err)); |
224 | | - return; |
| 211 | + ret = regmap_read(pca->regmap, PCA9685_PRESCALE, ¤t_prescale); |
| 212 | + if (ret) |
| 213 | + return ret; |
| 214 | + |
| 215 | + if (current_prescale > best_prescale) |
| 216 | + ret_tohw = 1; |
| 217 | + |
| 218 | + prescale = current_prescale; |
| 219 | + } else { |
| 220 | + prescale = best_prescale; |
225 | 221 | } |
226 | 222 |
|
227 | | - if (!enable) { |
228 | | - /* Wait 500us for the oscillator to be back up */ |
229 | | - udelay(500); |
| 223 | + period_ns = PCA9685_COUNTER_RANGE * PCA9685_QUANTUM_NS(prescale); |
| 224 | + |
| 225 | + duty = (unsigned)min_t(u64, wf->duty_length_ns, period_ns) / PCA9685_QUANTUM_NS(prescale); |
| 226 | + |
| 227 | + if (duty < PCA9685_COUNTER_RANGE) { |
| 228 | + unsigned int on, off; |
| 229 | + |
| 230 | + on = (unsigned)min_t(u64, wf->duty_offset_ns, period_ns) / PCA9685_QUANTUM_NS(prescale); |
| 231 | + off = (on + duty) % PCA9685_COUNTER_RANGE; |
| 232 | + |
| 233 | + /* |
| 234 | + * With a zero duty cycle, it doesn't matter if period was |
| 235 | + * rounded up |
| 236 | + */ |
| 237 | + if (!duty) |
| 238 | + ret_tohw = 0; |
| 239 | + |
| 240 | + *wfhw = (typeof(*wfhw)){ |
| 241 | + .onoff = { on & 0xff, (on >> 8) & 0xf, off & 0xff, (off >> 8) & 0xf }, |
| 242 | + .prescale = prescale, |
| 243 | + }; |
| 244 | + } else { |
| 245 | + *wfhw = (typeof(*wfhw)){ |
| 246 | + .onoff = { 0, LED_FULL, 0, 0, }, |
| 247 | + .prescale = prescale, |
| 248 | + }; |
230 | 249 | } |
| 250 | + |
| 251 | + dev_dbg(&chip->dev, "pwm#%u: %lld/%lld [+%lld] -> %s[%hhx %hhx %hhx %hhx] PSC:%hhx\n", |
| 252 | + pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns, |
| 253 | + ret_tohw ? "#" : "", wfhw->onoff[0], wfhw->onoff[1], wfhw->onoff[2], wfhw->onoff[3], wfhw->prescale); |
| 254 | + |
| 255 | + return ret_tohw; |
231 | 256 | } |
232 | 257 |
|
233 | | -static int __pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, |
234 | | - const struct pwm_state *state) |
| 258 | +static int pca9685_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm, |
| 259 | + const void *_wfhw, struct pwm_waveform *wf) |
235 | 260 | { |
| 261 | + const struct pca9685_waveform *wfhw = _wfhw; |
236 | 262 | struct pca9685 *pca = to_pca(chip); |
237 | | - unsigned long long duty, prescale; |
238 | | - unsigned int val = 0; |
239 | | - |
240 | | - if (state->polarity != PWM_POLARITY_NORMAL) |
241 | | - return -EINVAL; |
242 | | - |
243 | | - prescale = DIV_ROUND_CLOSEST_ULL(PCA9685_OSC_CLOCK_MHZ * state->period, |
244 | | - PCA9685_COUNTER_RANGE * 1000) - 1; |
245 | | - if (prescale < PCA9685_PRESCALE_MIN || prescale > PCA9685_PRESCALE_MAX) { |
246 | | - dev_err(pwmchip_parent(chip), "pwm not changed: period out of bounds!\n"); |
247 | | - return -EINVAL; |
248 | | - } |
| 263 | + unsigned int prescale; |
249 | 264 |
|
250 | | - if (!state->enabled) { |
251 | | - pca9685_pwm_set_duty(chip, pwm->hwpwm, 0); |
252 | | - return 0; |
253 | | - } |
| 265 | + if (wfhw->prescale) |
| 266 | + prescale = wfhw->prescale; |
| 267 | + else |
| 268 | + scoped_guard(mutex, &pca->lock) { |
| 269 | + int ret; |
254 | 270 |
|
255 | | - pca9685_read_reg(chip, PCA9685_PRESCALE, &val); |
256 | | - if (prescale != val) { |
257 | | - if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) { |
258 | | - dev_err(pwmchip_parent(chip), |
259 | | - "pwm not changed: periods of enabled pwms must match!\n"); |
260 | | - return -EBUSY; |
| 271 | + ret = regmap_read(pca->regmap, PCA9685_PRESCALE, &prescale); |
| 272 | + if (ret) |
| 273 | + return ret; |
261 | 274 | } |
262 | 275 |
|
263 | | - /* |
264 | | - * Putting the chip briefly into SLEEP mode |
265 | | - * at this point won't interfere with the |
266 | | - * pm_runtime framework, because the pm_runtime |
267 | | - * state is guaranteed active here. |
268 | | - */ |
269 | | - /* Put chip into sleep mode */ |
270 | | - pca9685_set_sleep_mode(chip, true); |
| 276 | + wf->period_length_ns = PCA9685_COUNTER_RANGE * PCA9685_QUANTUM_NS(prescale); |
271 | 277 |
|
272 | | - /* Change the chip-wide output frequency */ |
273 | | - pca9685_write_reg(chip, PCA9685_PRESCALE, prescale); |
| 278 | + if (wfhw->onoff[3] & LED_FULL) { |
| 279 | + wf->duty_length_ns = 0; |
| 280 | + wf->duty_offset_ns = 0; |
| 281 | + } else if (wfhw->onoff[1] & LED_FULL) { |
| 282 | + wf->duty_length_ns = wf->period_length_ns; |
| 283 | + wf->duty_offset_ns = 0; |
| 284 | + } else { |
| 285 | + unsigned int on = wfhw->onoff[0] | (wfhw->onoff[1] & 0xf) << 8; |
| 286 | + unsigned int off = wfhw->onoff[2] | (wfhw->onoff[3] & 0xf) << 8; |
274 | 287 |
|
275 | | - /* Wake the chip up */ |
276 | | - pca9685_set_sleep_mode(chip, false); |
| 288 | + wf->duty_length_ns = (off - on) % PCA9685_COUNTER_RANGE * PCA9685_QUANTUM_NS(prescale); |
| 289 | + wf->duty_offset_ns = on * PCA9685_QUANTUM_NS(prescale); |
277 | 290 | } |
278 | 291 |
|
279 | | - duty = PCA9685_COUNTER_RANGE * state->duty_cycle; |
280 | | - duty = DIV_ROUND_UP_ULL(duty, state->period); |
281 | | - pca9685_pwm_set_duty(chip, pwm->hwpwm, duty); |
| 292 | + dev_dbg(&chip->dev, "pwm#%u: [%hhx %hhx %hhx %hhx] PSC:%hhx -> %lld/%lld [+%lld]\n", |
| 293 | + pwm->hwpwm, |
| 294 | + wfhw->onoff[0], wfhw->onoff[1], wfhw->onoff[2], wfhw->onoff[3], wfhw->prescale, |
| 295 | + wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns); |
| 296 | + |
282 | 297 | return 0; |
283 | 298 | } |
284 | 299 |
|
285 | | -static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, |
286 | | - const struct pwm_state *state) |
| 300 | +static int pca9685_read_waveform(struct pwm_chip *chip, struct pwm_device *pwm, void *_wfhw) |
287 | 301 | { |
| 302 | + struct pca9685_waveform *wfhw = _wfhw; |
288 | 303 | struct pca9685 *pca = to_pca(chip); |
| 304 | + unsigned int prescale; |
289 | 305 | int ret; |
290 | 306 |
|
291 | | - mutex_lock(&pca->lock); |
292 | | - ret = __pca9685_pwm_apply(chip, pwm, state); |
293 | | - if (ret == 0) { |
294 | | - if (state->enabled) |
295 | | - set_bit(pwm->hwpwm, pca->pwms_enabled); |
296 | | - else |
297 | | - clear_bit(pwm->hwpwm, pca->pwms_enabled); |
298 | | - } |
299 | | - mutex_unlock(&pca->lock); |
| 307 | + guard(mutex)(&pca->lock); |
300 | 308 |
|
301 | | - return ret; |
| 309 | + ret = regmap_bulk_read(pca->regmap, REG_ON_L(pwm->hwpwm), &wfhw->onoff, 4); |
| 310 | + if (ret) |
| 311 | + return ret; |
| 312 | + |
| 313 | + ret = regmap_read(pca->regmap, PCA9685_PRESCALE, &prescale); |
| 314 | + if (ret) |
| 315 | + return ret; |
| 316 | + |
| 317 | + wfhw->prescale = prescale; |
| 318 | + |
| 319 | + return 0; |
302 | 320 | } |
303 | 321 |
|
304 | | -static int pca9685_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, |
305 | | - struct pwm_state *state) |
| 322 | +static int pca9685_write_waveform(struct pwm_chip *chip, struct pwm_device *pwm, const void *_wfhw) |
306 | 323 | { |
307 | | - unsigned long long duty; |
308 | | - unsigned int val = 0; |
| 324 | + const struct pca9685_waveform *wfhw = _wfhw; |
| 325 | + struct pca9685 *pca = to_pca(chip); |
| 326 | + unsigned int current_prescale; |
| 327 | + int ret; |
309 | 328 |
|
310 | | - /* Calculate (chip-wide) period from prescale value */ |
311 | | - pca9685_read_reg(chip, PCA9685_PRESCALE, &val); |
312 | | - /* |
313 | | - * PCA9685_OSC_CLOCK_MHZ is 25, i.e. an integer divider of 1000. |
314 | | - * The following calculation is therefore only a multiplication |
315 | | - * and we are not losing precision. |
316 | | - */ |
317 | | - state->period = (PCA9685_COUNTER_RANGE * 1000 / PCA9685_OSC_CLOCK_MHZ) * |
318 | | - (val + 1); |
| 329 | + guard(mutex)(&pca->lock); |
319 | 330 |
|
320 | | - /* The (per-channel) polarity is fixed */ |
321 | | - state->polarity = PWM_POLARITY_NORMAL; |
| 331 | + if (wfhw->prescale) { |
| 332 | + ret = regmap_read(pca->regmap, PCA9685_PRESCALE, ¤t_prescale); |
| 333 | + if (ret) |
| 334 | + return ret; |
322 | 335 |
|
323 | | - if (pwm->hwpwm >= PCA9685_MAXCHAN) { |
324 | | - /* |
325 | | - * The "all LEDs" channel does not support HW readout |
326 | | - * Return 0 and disabled for backwards compatibility |
327 | | - */ |
328 | | - state->duty_cycle = 0; |
329 | | - state->enabled = false; |
330 | | - return 0; |
331 | | - } |
| 336 | + if (current_prescale != wfhw->prescale) { |
| 337 | + if (!pca9685_prescaler_can_change(pca, pwm->hwpwm)) |
| 338 | + return -EBUSY; |
332 | 339 |
|
333 | | - state->enabled = true; |
334 | | - duty = pca9685_pwm_get_duty(chip, pwm->hwpwm); |
335 | | - state->duty_cycle = DIV_ROUND_DOWN_ULL(duty * state->period, PCA9685_COUNTER_RANGE); |
| 340 | + /* Put chip into sleep mode */ |
| 341 | + ret = pca9685_set_sleep_mode(chip, true); |
| 342 | + if (ret) |
| 343 | + return ret; |
336 | 344 |
|
337 | | - return 0; |
| 345 | + /* Change the chip-wide output frequency */ |
| 346 | + ret = regmap_write(pca->regmap, PCA9685_PRESCALE, wfhw->prescale); |
| 347 | + if (ret) |
| 348 | + return ret; |
| 349 | + |
| 350 | + /* Wake the chip up */ |
| 351 | + ret = pca9685_set_sleep_mode(chip, false); |
| 352 | + if (ret) |
| 353 | + return ret; |
| 354 | + } |
| 355 | + } |
| 356 | + |
| 357 | + return regmap_bulk_write(pca->regmap, REG_ON_L(pwm->hwpwm), &wfhw->onoff, 4); |
338 | 358 | } |
339 | 359 |
|
340 | 360 | static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) |
@@ -365,8 +385,11 @@ static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
365 | 385 | } |
366 | 386 |
|
367 | 387 | static const struct pwm_ops pca9685_pwm_ops = { |
368 | | - .apply = pca9685_pwm_apply, |
369 | | - .get_state = pca9685_pwm_get_state, |
| 388 | + .sizeof_wfhw = sizeof(struct pca9685_waveform), |
| 389 | + .round_waveform_tohw = pca9685_round_waveform_tohw, |
| 390 | + .round_waveform_fromhw = pca9685_round_waveform_fromhw, |
| 391 | + .read_waveform = pca9685_read_waveform, |
| 392 | + .write_waveform = pca9685_write_waveform, |
370 | 393 | .request = pca9685_pwm_request, |
371 | 394 | .free = pca9685_pwm_free, |
372 | 395 | }; |
|
0 commit comments