1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * PWM device driver for ST SoCs |
4 | * |
5 | * Copyright (C) 2013-2016 STMicroelectronics (R&D) Limited |
6 | * |
7 | * Author: Ajit Pal Singh <ajitpal.singh@st.com> |
8 | * Lee Jones <lee.jones@linaro.org> |
9 | */ |
10 | |
11 | #include <linux/clk.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/math64.h> |
14 | #include <linux/mfd/syscon.h> |
15 | #include <linux/module.h> |
16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/pwm.h> |
19 | #include <linux/regmap.h> |
20 | #include <linux/sched.h> |
21 | #include <linux/slab.h> |
22 | #include <linux/time.h> |
23 | #include <linux/wait.h> |
24 | |
25 | #define PWM_OUT_VAL(x) (0x00 + (4 * (x))) /* Device's Duty Cycle register */ |
26 | #define PWM_CPT_VAL(x) (0x10 + (4 * (x))) /* Capture value */ |
27 | #define PWM_CPT_EDGE(x) (0x30 + (4 * (x))) /* Edge to capture on */ |
28 | |
29 | #define STI_PWM_CTRL 0x50 /* Control/Config register */ |
30 | #define STI_INT_EN 0x54 /* Interrupt Enable/Disable register */ |
31 | #define STI_INT_STA 0x58 /* Interrupt Status register */ |
32 | #define PWM_INT_ACK 0x5c |
33 | #define PWM_PRESCALE_LOW_MASK 0x0f |
34 | #define PWM_PRESCALE_HIGH_MASK 0xf0 |
35 | #define PWM_CPT_EDGE_MASK 0x03 |
36 | #define PWM_INT_ACK_MASK 0x1ff |
37 | |
38 | #define STI_MAX_CPT_DEVS 4 |
39 | #define CPT_DC_MAX 0xff |
40 | |
41 | /* Regfield IDs */ |
42 | enum { |
43 | /* Bits in PWM_CTRL*/ |
44 | PWMCLK_PRESCALE_LOW, |
45 | PWMCLK_PRESCALE_HIGH, |
46 | CPTCLK_PRESCALE, |
47 | |
48 | PWM_OUT_EN, |
49 | PWM_CPT_EN, |
50 | |
51 | PWM_CPT_INT_EN, |
52 | PWM_CPT_INT_STAT, |
53 | |
54 | /* Keep last */ |
55 | MAX_REGFIELDS |
56 | }; |
57 | |
58 | /* |
59 | * Each capture input can be programmed to detect rising-edge, falling-edge, |
60 | * either edge or neither egde. |
61 | */ |
62 | enum sti_cpt_edge { |
63 | CPT_EDGE_DISABLED, |
64 | CPT_EDGE_RISING, |
65 | CPT_EDGE_FALLING, |
66 | CPT_EDGE_BOTH, |
67 | }; |
68 | |
69 | struct sti_cpt_ddata { |
70 | u32 snapshot[3]; |
71 | unsigned int index; |
72 | struct mutex lock; |
73 | wait_queue_head_t wait; |
74 | }; |
75 | |
76 | struct sti_pwm_compat_data { |
77 | const struct reg_field *reg_fields; |
78 | unsigned int pwm_num_devs; |
79 | unsigned int cpt_num_devs; |
80 | unsigned int max_pwm_cnt; |
81 | unsigned int max_prescale; |
82 | }; |
83 | |
84 | struct sti_pwm_chip { |
85 | struct device *dev; |
86 | struct clk *pwm_clk; |
87 | struct clk *cpt_clk; |
88 | struct regmap *regmap; |
89 | struct sti_pwm_compat_data *cdata; |
90 | struct regmap_field *prescale_low; |
91 | struct regmap_field *prescale_high; |
92 | struct regmap_field *pwm_out_en; |
93 | struct regmap_field *pwm_cpt_en; |
94 | struct regmap_field *pwm_cpt_int_en; |
95 | struct regmap_field *pwm_cpt_int_stat; |
96 | struct pwm_chip chip; |
97 | struct pwm_device *cur; |
98 | unsigned long configured; |
99 | unsigned int en_count; |
100 | struct mutex sti_pwm_lock; /* To sync between enable/disable calls */ |
101 | void __iomem *mmio; |
102 | }; |
103 | |
104 | static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { |
105 | [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWM_CTRL, 0, 3), |
106 | [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWM_CTRL, 11, 14), |
107 | [CPTCLK_PRESCALE] = REG_FIELD(STI_PWM_CTRL, 4, 8), |
108 | [PWM_OUT_EN] = REG_FIELD(STI_PWM_CTRL, 9, 9), |
109 | [PWM_CPT_EN] = REG_FIELD(STI_PWM_CTRL, 10, 10), |
110 | [PWM_CPT_INT_EN] = REG_FIELD(STI_INT_EN, 1, 4), |
111 | [PWM_CPT_INT_STAT] = REG_FIELD(STI_INT_STA, 1, 4), |
112 | }; |
113 | |
114 | static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) |
115 | { |
116 | return container_of(chip, struct sti_pwm_chip, chip); |
117 | } |
118 | |
119 | /* |
120 | * Calculate the prescaler value corresponding to the period. |
121 | */ |
122 | static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period, |
123 | unsigned int *prescale) |
124 | { |
125 | struct sti_pwm_compat_data *cdata = pc->cdata; |
126 | unsigned long clk_rate; |
127 | unsigned long value; |
128 | unsigned int ps; |
129 | |
130 | clk_rate = clk_get_rate(clk: pc->pwm_clk); |
131 | if (!clk_rate) { |
132 | dev_err(pc->dev, "failed to get clock rate\n" ); |
133 | return -EINVAL; |
134 | } |
135 | |
136 | /* |
137 | * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_cnt + 1)) - 1 |
138 | */ |
139 | value = NSEC_PER_SEC / clk_rate; |
140 | value *= cdata->max_pwm_cnt + 1; |
141 | |
142 | if (period % value) |
143 | return -EINVAL; |
144 | |
145 | ps = period / value - 1; |
146 | if (ps > cdata->max_prescale) |
147 | return -EINVAL; |
148 | |
149 | *prescale = ps; |
150 | |
151 | return 0; |
152 | } |
153 | |
154 | /* |
155 | * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. The |
156 | * only way to change the period (apart from changing the PWM input clock) is |
157 | * to change the PWM clock prescaler. |
158 | * |
159 | * The prescaler is of 8 bits, so 256 prescaler values and hence 256 possible |
160 | * period values are supported (for a particular clock rate). The requested |
161 | * period will be applied only if it matches one of these 256 values. |
162 | */ |
163 | static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, |
164 | int duty_ns, int period_ns) |
165 | { |
166 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
167 | struct sti_pwm_compat_data *cdata = pc->cdata; |
168 | unsigned int ncfg, value, prescale = 0; |
169 | struct pwm_device *cur = pc->cur; |
170 | struct device *dev = pc->dev; |
171 | bool period_same = false; |
172 | int ret; |
173 | |
174 | ncfg = hweight_long(w: pc->configured); |
175 | if (ncfg) |
176 | period_same = (period_ns == pwm_get_period(pwm: cur)); |
177 | |
178 | /* |
179 | * Allow configuration changes if one of the following conditions |
180 | * satisfy. |
181 | * 1. No devices have been configured. |
182 | * 2. Only one device has been configured and the new request is for |
183 | * the same device. |
184 | * 3. Only one device has been configured and the new request is for |
185 | * a new device and period of the new device is same as the current |
186 | * configured period. |
187 | * 4. More than one devices are configured and period of the new |
188 | * requestis the same as the current period. |
189 | */ |
190 | if (!ncfg || |
191 | ((ncfg == 1) && (pwm->hwpwm == cur->hwpwm)) || |
192 | ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) || |
193 | ((ncfg > 1) && period_same)) { |
194 | /* Enable clock before writing to PWM registers. */ |
195 | ret = clk_enable(clk: pc->pwm_clk); |
196 | if (ret) |
197 | return ret; |
198 | |
199 | ret = clk_enable(clk: pc->cpt_clk); |
200 | if (ret) |
201 | return ret; |
202 | |
203 | if (!period_same) { |
204 | ret = sti_pwm_get_prescale(pc, period: period_ns, prescale: &prescale); |
205 | if (ret) |
206 | goto clk_dis; |
207 | |
208 | value = prescale & PWM_PRESCALE_LOW_MASK; |
209 | |
210 | ret = regmap_field_write(field: pc->prescale_low, val: value); |
211 | if (ret) |
212 | goto clk_dis; |
213 | |
214 | value = (prescale & PWM_PRESCALE_HIGH_MASK) >> 4; |
215 | |
216 | ret = regmap_field_write(field: pc->prescale_high, val: value); |
217 | if (ret) |
218 | goto clk_dis; |
219 | } |
220 | |
221 | /* |
222 | * When PWMVal == 0, PWM pulse = 1 local clock cycle. |
223 | * When PWMVal == max_pwm_count, |
224 | * PWM pulse = (max_pwm_count + 1) local cycles, |
225 | * that is continuous pulse: signal never goes low. |
226 | */ |
227 | value = cdata->max_pwm_cnt * duty_ns / period_ns; |
228 | |
229 | ret = regmap_write(map: pc->regmap, PWM_OUT_VAL(pwm->hwpwm), val: value); |
230 | if (ret) |
231 | goto clk_dis; |
232 | |
233 | ret = regmap_field_write(field: pc->pwm_cpt_int_en, val: 0); |
234 | |
235 | set_bit(nr: pwm->hwpwm, addr: &pc->configured); |
236 | pc->cur = pwm; |
237 | |
238 | dev_dbg(dev, "prescale:%u, period:%i, duty:%i, value:%u\n" , |
239 | prescale, period_ns, duty_ns, value); |
240 | } else { |
241 | return -EINVAL; |
242 | } |
243 | |
244 | clk_dis: |
245 | clk_disable(clk: pc->pwm_clk); |
246 | clk_disable(clk: pc->cpt_clk); |
247 | return ret; |
248 | } |
249 | |
250 | static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) |
251 | { |
252 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
253 | struct device *dev = pc->dev; |
254 | int ret = 0; |
255 | |
256 | /* |
257 | * Since we have a common enable for all PWM devices, do not enable if |
258 | * already enabled. |
259 | */ |
260 | mutex_lock(&pc->sti_pwm_lock); |
261 | |
262 | if (!pc->en_count) { |
263 | ret = clk_enable(clk: pc->pwm_clk); |
264 | if (ret) |
265 | goto out; |
266 | |
267 | ret = clk_enable(clk: pc->cpt_clk); |
268 | if (ret) |
269 | goto out; |
270 | |
271 | ret = regmap_field_write(field: pc->pwm_out_en, val: 1); |
272 | if (ret) { |
273 | dev_err(dev, "failed to enable PWM device %u: %d\n" , |
274 | pwm->hwpwm, ret); |
275 | goto out; |
276 | } |
277 | } |
278 | |
279 | pc->en_count++; |
280 | |
281 | out: |
282 | mutex_unlock(lock: &pc->sti_pwm_lock); |
283 | return ret; |
284 | } |
285 | |
286 | static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) |
287 | { |
288 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
289 | |
290 | mutex_lock(&pc->sti_pwm_lock); |
291 | |
292 | if (--pc->en_count) { |
293 | mutex_unlock(lock: &pc->sti_pwm_lock); |
294 | return; |
295 | } |
296 | |
297 | regmap_field_write(field: pc->pwm_out_en, val: 0); |
298 | |
299 | clk_disable(clk: pc->pwm_clk); |
300 | clk_disable(clk: pc->cpt_clk); |
301 | |
302 | mutex_unlock(lock: &pc->sti_pwm_lock); |
303 | } |
304 | |
305 | static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
306 | { |
307 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
308 | |
309 | clear_bit(nr: pwm->hwpwm, addr: &pc->configured); |
310 | } |
311 | |
312 | static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, |
313 | struct pwm_capture *result, unsigned long timeout) |
314 | { |
315 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
316 | struct sti_pwm_compat_data *cdata = pc->cdata; |
317 | struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm); |
318 | struct device *dev = pc->dev; |
319 | unsigned int effective_ticks; |
320 | unsigned long long high, low; |
321 | int ret; |
322 | |
323 | if (pwm->hwpwm >= cdata->cpt_num_devs) { |
324 | dev_err(dev, "device %u is not valid\n" , pwm->hwpwm); |
325 | return -EINVAL; |
326 | } |
327 | |
328 | mutex_lock(&ddata->lock); |
329 | ddata->index = 0; |
330 | |
331 | /* Prepare capture measurement */ |
332 | regmap_write(map: pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), val: CPT_EDGE_RISING); |
333 | regmap_field_write(field: pc->pwm_cpt_int_en, BIT(pwm->hwpwm)); |
334 | |
335 | /* Enable capture */ |
336 | ret = regmap_field_write(field: pc->pwm_cpt_en, val: 1); |
337 | if (ret) { |
338 | dev_err(dev, "failed to enable PWM capture %u: %d\n" , |
339 | pwm->hwpwm, ret); |
340 | goto out; |
341 | } |
342 | |
343 | ret = wait_event_interruptible_timeout(ddata->wait, ddata->index > 1, |
344 | msecs_to_jiffies(timeout)); |
345 | |
346 | regmap_write(map: pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), val: CPT_EDGE_DISABLED); |
347 | |
348 | if (ret == -ERESTARTSYS) |
349 | goto out; |
350 | |
351 | switch (ddata->index) { |
352 | case 0: |
353 | case 1: |
354 | /* |
355 | * Getting here could mean: |
356 | * - input signal is constant of less than 1 Hz |
357 | * - there is no input signal at all |
358 | * |
359 | * In such case the frequency is rounded down to 0 |
360 | */ |
361 | result->period = 0; |
362 | result->duty_cycle = 0; |
363 | |
364 | break; |
365 | |
366 | case 2: |
367 | /* We have everying we need */ |
368 | high = ddata->snapshot[1] - ddata->snapshot[0]; |
369 | low = ddata->snapshot[2] - ddata->snapshot[1]; |
370 | |
371 | effective_ticks = clk_get_rate(clk: pc->cpt_clk); |
372 | |
373 | result->period = (high + low) * NSEC_PER_SEC; |
374 | result->period /= effective_ticks; |
375 | |
376 | result->duty_cycle = high * NSEC_PER_SEC; |
377 | result->duty_cycle /= effective_ticks; |
378 | |
379 | break; |
380 | |
381 | default: |
382 | dev_err(dev, "internal error\n" ); |
383 | break; |
384 | } |
385 | |
386 | out: |
387 | /* Disable capture */ |
388 | regmap_field_write(field: pc->pwm_cpt_en, val: 0); |
389 | |
390 | mutex_unlock(lock: &ddata->lock); |
391 | return ret; |
392 | } |
393 | |
394 | static int sti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, |
395 | const struct pwm_state *state) |
396 | { |
397 | int err; |
398 | |
399 | if (state->polarity != PWM_POLARITY_NORMAL) |
400 | return -EINVAL; |
401 | |
402 | if (!state->enabled) { |
403 | if (pwm->state.enabled) |
404 | sti_pwm_disable(chip, pwm); |
405 | |
406 | return 0; |
407 | } |
408 | |
409 | err = sti_pwm_config(chip: pwm->chip, pwm, duty_ns: state->duty_cycle, period_ns: state->period); |
410 | if (err) |
411 | return err; |
412 | |
413 | if (!pwm->state.enabled) |
414 | err = sti_pwm_enable(chip, pwm); |
415 | |
416 | return err; |
417 | } |
418 | |
419 | static const struct pwm_ops sti_pwm_ops = { |
420 | .capture = sti_pwm_capture, |
421 | .apply = sti_pwm_apply, |
422 | .free = sti_pwm_free, |
423 | .owner = THIS_MODULE, |
424 | }; |
425 | |
426 | static irqreturn_t sti_pwm_interrupt(int irq, void *data) |
427 | { |
428 | struct sti_pwm_chip *pc = data; |
429 | struct device *dev = pc->dev; |
430 | struct sti_cpt_ddata *ddata; |
431 | int devicenum; |
432 | unsigned int cpt_int_stat; |
433 | unsigned int reg; |
434 | int ret = IRQ_NONE; |
435 | |
436 | ret = regmap_field_read(field: pc->pwm_cpt_int_stat, val: &cpt_int_stat); |
437 | if (ret) |
438 | return ret; |
439 | |
440 | while (cpt_int_stat) { |
441 | devicenum = ffs(cpt_int_stat) - 1; |
442 | |
443 | ddata = pwm_get_chip_data(pwm: &pc->chip.pwms[devicenum]); |
444 | |
445 | /* |
446 | * Capture input: |
447 | * _______ _______ |
448 | * | | | | |
449 | * __| |_________________| |________ |
450 | * ^0 ^1 ^2 |
451 | * |
452 | * Capture start by the first available rising edge. When a |
453 | * capture event occurs, capture value (CPT_VALx) is stored, |
454 | * index incremented, capture edge changed. |
455 | * |
456 | * After the capture, if the index > 1, we have collected the |
457 | * necessary data so we signal the thread waiting for it and |
458 | * disable the capture by setting capture edge to none |
459 | */ |
460 | |
461 | regmap_read(map: pc->regmap, |
462 | PWM_CPT_VAL(devicenum), |
463 | val: &ddata->snapshot[ddata->index]); |
464 | |
465 | switch (ddata->index) { |
466 | case 0: |
467 | case 1: |
468 | regmap_read(map: pc->regmap, PWM_CPT_EDGE(devicenum), val: ®); |
469 | reg ^= PWM_CPT_EDGE_MASK; |
470 | regmap_write(map: pc->regmap, PWM_CPT_EDGE(devicenum), val: reg); |
471 | |
472 | ddata->index++; |
473 | break; |
474 | |
475 | case 2: |
476 | regmap_write(map: pc->regmap, |
477 | PWM_CPT_EDGE(devicenum), |
478 | val: CPT_EDGE_DISABLED); |
479 | wake_up(&ddata->wait); |
480 | break; |
481 | |
482 | default: |
483 | dev_err(dev, "Internal error\n" ); |
484 | } |
485 | |
486 | cpt_int_stat &= ~BIT_MASK(devicenum); |
487 | |
488 | ret = IRQ_HANDLED; |
489 | } |
490 | |
491 | /* Just ACK everything */ |
492 | regmap_write(map: pc->regmap, PWM_INT_ACK, PWM_INT_ACK_MASK); |
493 | |
494 | return ret; |
495 | } |
496 | |
497 | static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) |
498 | { |
499 | struct device *dev = pc->dev; |
500 | const struct reg_field *reg_fields; |
501 | struct device_node *np = dev->of_node; |
502 | struct sti_pwm_compat_data *cdata = pc->cdata; |
503 | u32 num_devs; |
504 | int ret; |
505 | |
506 | ret = of_property_read_u32(np, propname: "st,pwm-num-chan" , out_value: &num_devs); |
507 | if (!ret) |
508 | cdata->pwm_num_devs = num_devs; |
509 | |
510 | ret = of_property_read_u32(np, propname: "st,capture-num-chan" , out_value: &num_devs); |
511 | if (!ret) |
512 | cdata->cpt_num_devs = num_devs; |
513 | |
514 | if (!cdata->pwm_num_devs && !cdata->cpt_num_devs) { |
515 | dev_err(dev, "No channels configured\n" ); |
516 | return -EINVAL; |
517 | } |
518 | |
519 | reg_fields = cdata->reg_fields; |
520 | |
521 | pc->prescale_low = devm_regmap_field_alloc(dev, regmap: pc->regmap, |
522 | reg_field: reg_fields[PWMCLK_PRESCALE_LOW]); |
523 | if (IS_ERR(ptr: pc->prescale_low)) |
524 | return PTR_ERR(ptr: pc->prescale_low); |
525 | |
526 | pc->prescale_high = devm_regmap_field_alloc(dev, regmap: pc->regmap, |
527 | reg_field: reg_fields[PWMCLK_PRESCALE_HIGH]); |
528 | if (IS_ERR(ptr: pc->prescale_high)) |
529 | return PTR_ERR(ptr: pc->prescale_high); |
530 | |
531 | pc->pwm_out_en = devm_regmap_field_alloc(dev, regmap: pc->regmap, |
532 | reg_field: reg_fields[PWM_OUT_EN]); |
533 | if (IS_ERR(ptr: pc->pwm_out_en)) |
534 | return PTR_ERR(ptr: pc->pwm_out_en); |
535 | |
536 | pc->pwm_cpt_en = devm_regmap_field_alloc(dev, regmap: pc->regmap, |
537 | reg_field: reg_fields[PWM_CPT_EN]); |
538 | if (IS_ERR(ptr: pc->pwm_cpt_en)) |
539 | return PTR_ERR(ptr: pc->pwm_cpt_en); |
540 | |
541 | pc->pwm_cpt_int_en = devm_regmap_field_alloc(dev, regmap: pc->regmap, |
542 | reg_field: reg_fields[PWM_CPT_INT_EN]); |
543 | if (IS_ERR(ptr: pc->pwm_cpt_int_en)) |
544 | return PTR_ERR(ptr: pc->pwm_cpt_int_en); |
545 | |
546 | pc->pwm_cpt_int_stat = devm_regmap_field_alloc(dev, regmap: pc->regmap, |
547 | reg_field: reg_fields[PWM_CPT_INT_STAT]); |
548 | if (PTR_ERR_OR_ZERO(ptr: pc->pwm_cpt_int_stat)) |
549 | return PTR_ERR(ptr: pc->pwm_cpt_int_stat); |
550 | |
551 | return 0; |
552 | } |
553 | |
554 | static const struct regmap_config sti_pwm_regmap_config = { |
555 | .reg_bits = 32, |
556 | .val_bits = 32, |
557 | .reg_stride = 4, |
558 | }; |
559 | |
560 | static int sti_pwm_probe(struct platform_device *pdev) |
561 | { |
562 | struct device *dev = &pdev->dev; |
563 | struct sti_pwm_compat_data *cdata; |
564 | struct sti_pwm_chip *pc; |
565 | unsigned int i; |
566 | int irq, ret; |
567 | |
568 | pc = devm_kzalloc(dev, size: sizeof(*pc), GFP_KERNEL); |
569 | if (!pc) |
570 | return -ENOMEM; |
571 | |
572 | cdata = devm_kzalloc(dev, size: sizeof(*cdata), GFP_KERNEL); |
573 | if (!cdata) |
574 | return -ENOMEM; |
575 | |
576 | pc->mmio = devm_platform_ioremap_resource(pdev, index: 0); |
577 | if (IS_ERR(ptr: pc->mmio)) |
578 | return PTR_ERR(ptr: pc->mmio); |
579 | |
580 | pc->regmap = devm_regmap_init_mmio(dev, pc->mmio, |
581 | &sti_pwm_regmap_config); |
582 | if (IS_ERR(ptr: pc->regmap)) |
583 | return PTR_ERR(ptr: pc->regmap); |
584 | |
585 | irq = platform_get_irq(pdev, 0); |
586 | if (irq < 0) |
587 | return irq; |
588 | |
589 | ret = devm_request_irq(dev: &pdev->dev, irq, handler: sti_pwm_interrupt, irqflags: 0, |
590 | devname: pdev->name, dev_id: pc); |
591 | if (ret < 0) { |
592 | dev_err(&pdev->dev, "Failed to request IRQ\n" ); |
593 | return ret; |
594 | } |
595 | |
596 | /* |
597 | * Setup PWM data with default values: some values could be replaced |
598 | * with specific ones provided from Device Tree. |
599 | */ |
600 | cdata->reg_fields = sti_pwm_regfields; |
601 | cdata->max_prescale = 0xff; |
602 | cdata->max_pwm_cnt = 255; |
603 | cdata->pwm_num_devs = 0; |
604 | cdata->cpt_num_devs = 0; |
605 | |
606 | pc->cdata = cdata; |
607 | pc->dev = dev; |
608 | pc->en_count = 0; |
609 | mutex_init(&pc->sti_pwm_lock); |
610 | |
611 | ret = sti_pwm_probe_dt(pc); |
612 | if (ret) |
613 | return ret; |
614 | |
615 | if (cdata->pwm_num_devs) { |
616 | pc->pwm_clk = of_clk_get_by_name(np: dev->of_node, name: "pwm" ); |
617 | if (IS_ERR(ptr: pc->pwm_clk)) { |
618 | dev_err(dev, "failed to get PWM clock\n" ); |
619 | return PTR_ERR(ptr: pc->pwm_clk); |
620 | } |
621 | |
622 | ret = clk_prepare(clk: pc->pwm_clk); |
623 | if (ret) { |
624 | dev_err(dev, "failed to prepare clock\n" ); |
625 | return ret; |
626 | } |
627 | } |
628 | |
629 | if (cdata->cpt_num_devs) { |
630 | pc->cpt_clk = of_clk_get_by_name(np: dev->of_node, name: "capture" ); |
631 | if (IS_ERR(ptr: pc->cpt_clk)) { |
632 | dev_err(dev, "failed to get PWM capture clock\n" ); |
633 | return PTR_ERR(ptr: pc->cpt_clk); |
634 | } |
635 | |
636 | ret = clk_prepare(clk: pc->cpt_clk); |
637 | if (ret) { |
638 | dev_err(dev, "failed to prepare clock\n" ); |
639 | return ret; |
640 | } |
641 | } |
642 | |
643 | pc->chip.dev = dev; |
644 | pc->chip.ops = &sti_pwm_ops; |
645 | pc->chip.npwm = pc->cdata->pwm_num_devs; |
646 | |
647 | ret = pwmchip_add(chip: &pc->chip); |
648 | if (ret < 0) { |
649 | clk_unprepare(clk: pc->pwm_clk); |
650 | clk_unprepare(clk: pc->cpt_clk); |
651 | return ret; |
652 | } |
653 | |
654 | for (i = 0; i < cdata->cpt_num_devs; i++) { |
655 | struct sti_cpt_ddata *ddata; |
656 | |
657 | ddata = devm_kzalloc(dev, size: sizeof(*ddata), GFP_KERNEL); |
658 | if (!ddata) |
659 | return -ENOMEM; |
660 | |
661 | init_waitqueue_head(&ddata->wait); |
662 | mutex_init(&ddata->lock); |
663 | |
664 | pwm_set_chip_data(pwm: &pc->chip.pwms[i], data: ddata); |
665 | } |
666 | |
667 | platform_set_drvdata(pdev, data: pc); |
668 | |
669 | return 0; |
670 | } |
671 | |
672 | static void sti_pwm_remove(struct platform_device *pdev) |
673 | { |
674 | struct sti_pwm_chip *pc = platform_get_drvdata(pdev); |
675 | |
676 | pwmchip_remove(chip: &pc->chip); |
677 | |
678 | clk_unprepare(clk: pc->pwm_clk); |
679 | clk_unprepare(clk: pc->cpt_clk); |
680 | } |
681 | |
682 | static const struct of_device_id sti_pwm_of_match[] = { |
683 | { .compatible = "st,sti-pwm" , }, |
684 | { /* sentinel */ } |
685 | }; |
686 | MODULE_DEVICE_TABLE(of, sti_pwm_of_match); |
687 | |
688 | static struct platform_driver sti_pwm_driver = { |
689 | .driver = { |
690 | .name = "sti-pwm" , |
691 | .of_match_table = sti_pwm_of_match, |
692 | }, |
693 | .probe = sti_pwm_probe, |
694 | .remove_new = sti_pwm_remove, |
695 | }; |
696 | module_platform_driver(sti_pwm_driver); |
697 | |
698 | MODULE_AUTHOR("Ajit Pal Singh <ajitpal.singh@st.com>" ); |
699 | MODULE_DESCRIPTION("STMicroelectronics ST PWM driver" ); |
700 | MODULE_LICENSE("GPL" ); |
701 | |