2 * Copyright (C) Overkiz SAS 2012
4 * Author: Boris BREZILLON <b.brezillon@overkiz.com>
5 * License terms: GNU General Public License (GPL) version 2
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/clocksource.h>
11 #include <linux/clockchips.h>
12 #include <linux/interrupt.h>
13 #include <linux/irq.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
17 #include <linux/ioport.h>
19 #include <linux/platform_device.h>
20 #include <linux/atmel_tc.h>
21 #include <linux/pwm.h>
22 #include <linux/of_device.h>
23 #include <linux/slab.h>
27 #define ATMEL_TC_ACMR_MASK (ATMEL_TC_ACPA | ATMEL_TC_ACPC | \
28 ATMEL_TC_AEEVT | ATMEL_TC_ASWTRG)
30 #define ATMEL_TC_BCMR_MASK (ATMEL_TC_BCPB | ATMEL_TC_BCPC | \
31 ATMEL_TC_BEEVT | ATMEL_TC_BSWTRG)
33 struct atmel_tcb_pwm_device
{
34 enum pwm_polarity polarity
; /* PWM polarity */
35 unsigned div
; /* PWM clock divider */
36 unsigned duty
; /* PWM duty expressed in clk cycles */
37 unsigned period
; /* PWM period expressed in clk cycles */
40 struct atmel_tcb_channel
{
48 struct atmel_tcb_pwm_chip
{
52 struct atmel_tcb_pwm_device
*pwms
[NPWM
];
53 struct atmel_tcb_channel bkup
[NPWM
/ 2];
56 static inline struct atmel_tcb_pwm_chip
*to_tcb_chip(struct pwm_chip
*chip
)
58 return container_of(chip
, struct atmel_tcb_pwm_chip
, chip
);
61 static int atmel_tcb_pwm_set_polarity(struct pwm_chip
*chip
,
62 struct pwm_device
*pwm
,
63 enum pwm_polarity polarity
)
65 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
67 tcbpwm
->polarity
= polarity
;
72 static int atmel_tcb_pwm_request(struct pwm_chip
*chip
,
73 struct pwm_device
*pwm
)
75 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
76 struct atmel_tcb_pwm_device
*tcbpwm
;
77 struct atmel_tc
*tc
= tcbpwmc
->tc
;
78 void __iomem
*regs
= tc
->regs
;
79 unsigned group
= pwm
->hwpwm
/ 2;
80 unsigned index
= pwm
->hwpwm
% 2;
84 tcbpwm
= devm_kzalloc(chip
->dev
, sizeof(*tcbpwm
), GFP_KERNEL
);
88 ret
= clk_prepare_enable(tc
->clk
[group
]);
90 devm_kfree(chip
->dev
, tcbpwm
);
94 pwm_set_chip_data(pwm
, tcbpwm
);
95 tcbpwm
->polarity
= PWM_POLARITY_NORMAL
;
100 spin_lock(&tcbpwmc
->lock
);
101 cmr
= __raw_readl(regs
+ ATMEL_TC_REG(group
, CMR
));
103 * Get init config from Timer Counter registers if
104 * Timer Counter is already configured as a PWM generator.
106 if (cmr
& ATMEL_TC_WAVE
) {
109 __raw_readl(regs
+ ATMEL_TC_REG(group
, RA
));
112 __raw_readl(regs
+ ATMEL_TC_REG(group
, RB
));
114 tcbpwm
->div
= cmr
& ATMEL_TC_TCCLKS
;
115 tcbpwm
->period
= __raw_readl(regs
+ ATMEL_TC_REG(group
, RC
));
116 cmr
&= (ATMEL_TC_TCCLKS
| ATMEL_TC_ACMR_MASK
|
121 cmr
|= ATMEL_TC_WAVE
| ATMEL_TC_WAVESEL_UP_AUTO
| ATMEL_TC_EEVT_XC0
;
122 __raw_writel(cmr
, regs
+ ATMEL_TC_REG(group
, CMR
));
123 spin_unlock(&tcbpwmc
->lock
);
125 tcbpwmc
->pwms
[pwm
->hwpwm
] = tcbpwm
;
130 static void atmel_tcb_pwm_free(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
132 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
133 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
134 struct atmel_tc
*tc
= tcbpwmc
->tc
;
136 clk_disable_unprepare(tc
->clk
[pwm
->hwpwm
/ 2]);
137 tcbpwmc
->pwms
[pwm
->hwpwm
] = NULL
;
138 devm_kfree(chip
->dev
, tcbpwm
);
141 static void atmel_tcb_pwm_disable(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
143 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
144 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
145 struct atmel_tc
*tc
= tcbpwmc
->tc
;
146 void __iomem
*regs
= tc
->regs
;
147 unsigned group
= pwm
->hwpwm
/ 2;
148 unsigned index
= pwm
->hwpwm
% 2;
150 enum pwm_polarity polarity
= tcbpwm
->polarity
;
153 * If duty is 0 the timer will be stopped and we have to
154 * configure the output correctly on software trigger:
155 * - set output to high if PWM_POLARITY_INVERSED
156 * - set output to low if PWM_POLARITY_NORMAL
158 * This is why we're reverting polarity in this case.
160 if (tcbpwm
->duty
== 0)
161 polarity
= !polarity
;
163 spin_lock(&tcbpwmc
->lock
);
164 cmr
= __raw_readl(regs
+ ATMEL_TC_REG(group
, CMR
));
166 /* flush old setting and set the new one */
168 cmr
&= ~ATMEL_TC_ACMR_MASK
;
169 if (polarity
== PWM_POLARITY_INVERSED
)
170 cmr
|= ATMEL_TC_ASWTRG_CLEAR
;
172 cmr
|= ATMEL_TC_ASWTRG_SET
;
174 cmr
&= ~ATMEL_TC_BCMR_MASK
;
175 if (polarity
== PWM_POLARITY_INVERSED
)
176 cmr
|= ATMEL_TC_BSWTRG_CLEAR
;
178 cmr
|= ATMEL_TC_BSWTRG_SET
;
181 __raw_writel(cmr
, regs
+ ATMEL_TC_REG(group
, CMR
));
184 * Use software trigger to apply the new setting.
185 * If both PWM devices in this group are disabled we stop the clock.
187 if (!(cmr
& (ATMEL_TC_ACPC
| ATMEL_TC_BCPC
))) {
188 __raw_writel(ATMEL_TC_SWTRG
| ATMEL_TC_CLKDIS
,
189 regs
+ ATMEL_TC_REG(group
, CCR
));
190 tcbpwmc
->bkup
[group
].enabled
= 1;
192 __raw_writel(ATMEL_TC_SWTRG
, regs
+
193 ATMEL_TC_REG(group
, CCR
));
194 tcbpwmc
->bkup
[group
].enabled
= 0;
197 spin_unlock(&tcbpwmc
->lock
);
200 static int atmel_tcb_pwm_enable(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
202 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
203 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
204 struct atmel_tc
*tc
= tcbpwmc
->tc
;
205 void __iomem
*regs
= tc
->regs
;
206 unsigned group
= pwm
->hwpwm
/ 2;
207 unsigned index
= pwm
->hwpwm
% 2;
209 enum pwm_polarity polarity
= tcbpwm
->polarity
;
212 * If duty is 0 the timer will be stopped and we have to
213 * configure the output correctly on software trigger:
214 * - set output to high if PWM_POLARITY_INVERSED
215 * - set output to low if PWM_POLARITY_NORMAL
217 * This is why we're reverting polarity in this case.
219 if (tcbpwm
->duty
== 0)
220 polarity
= !polarity
;
222 spin_lock(&tcbpwmc
->lock
);
223 cmr
= __raw_readl(regs
+ ATMEL_TC_REG(group
, CMR
));
225 /* flush old setting and set the new one */
226 cmr
&= ~ATMEL_TC_TCCLKS
;
229 cmr
&= ~ATMEL_TC_ACMR_MASK
;
231 /* Set CMR flags according to given polarity */
232 if (polarity
== PWM_POLARITY_INVERSED
)
233 cmr
|= ATMEL_TC_ASWTRG_CLEAR
;
235 cmr
|= ATMEL_TC_ASWTRG_SET
;
237 cmr
&= ~ATMEL_TC_BCMR_MASK
;
238 if (polarity
== PWM_POLARITY_INVERSED
)
239 cmr
|= ATMEL_TC_BSWTRG_CLEAR
;
241 cmr
|= ATMEL_TC_BSWTRG_SET
;
245 * If duty is 0 or equal to period there's no need to register
246 * a specific action on RA/RB and RC compare.
247 * The output will be configured on software trigger and keep
248 * this config till next config call.
250 if (tcbpwm
->duty
!= tcbpwm
->period
&& tcbpwm
->duty
> 0) {
252 if (polarity
== PWM_POLARITY_INVERSED
)
253 cmr
|= ATMEL_TC_ACPA_SET
| ATMEL_TC_ACPC_CLEAR
;
255 cmr
|= ATMEL_TC_ACPA_CLEAR
| ATMEL_TC_ACPC_SET
;
257 if (polarity
== PWM_POLARITY_INVERSED
)
258 cmr
|= ATMEL_TC_BCPB_SET
| ATMEL_TC_BCPC_CLEAR
;
260 cmr
|= ATMEL_TC_BCPB_CLEAR
| ATMEL_TC_BCPC_SET
;
264 cmr
|= (tcbpwm
->div
& ATMEL_TC_TCCLKS
);
266 __raw_writel(cmr
, regs
+ ATMEL_TC_REG(group
, CMR
));
269 __raw_writel(tcbpwm
->duty
, regs
+ ATMEL_TC_REG(group
, RA
));
271 __raw_writel(tcbpwm
->duty
, regs
+ ATMEL_TC_REG(group
, RB
));
273 __raw_writel(tcbpwm
->period
, regs
+ ATMEL_TC_REG(group
, RC
));
275 /* Use software trigger to apply the new setting */
276 __raw_writel(ATMEL_TC_CLKEN
| ATMEL_TC_SWTRG
,
277 regs
+ ATMEL_TC_REG(group
, CCR
));
278 tcbpwmc
->bkup
[group
].enabled
= 1;
279 spin_unlock(&tcbpwmc
->lock
);
283 static int atmel_tcb_pwm_config(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
284 int duty_ns
, int period_ns
)
286 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
287 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
288 unsigned group
= pwm
->hwpwm
/ 2;
289 unsigned index
= pwm
->hwpwm
% 2;
290 struct atmel_tcb_pwm_device
*atcbpwm
= NULL
;
291 struct atmel_tc
*tc
= tcbpwmc
->tc
;
296 unsigned rate
= clk_get_rate(tc
->clk
[group
]);
297 unsigned long long min
;
298 unsigned long long max
;
301 * Find best clk divisor:
302 * the smallest divisor which can fulfill the period_ns requirements.
304 for (i
= 0; i
< 5; ++i
) {
305 if (atmel_tc_divisors
[i
] == 0) {
309 min
= div_u64((u64
)NSEC_PER_SEC
* atmel_tc_divisors
[i
], rate
);
310 max
= min
<< tc
->tcb_config
->counter_width
;
311 if (max
>= period_ns
)
316 * If none of the divisor are small enough to represent period_ns
317 * take slow clock (32KHz).
321 rate
= clk_get_rate(tc
->slow_clk
);
322 min
= div_u64(NSEC_PER_SEC
, rate
);
323 max
= min
<< tc
->tcb_config
->counter_width
;
325 /* If period is too big return ERANGE error */
330 duty
= div_u64(duty_ns
, min
);
331 period
= div_u64(period_ns
, min
);
334 atcbpwm
= tcbpwmc
->pwms
[pwm
->hwpwm
+ 1];
336 atcbpwm
= tcbpwmc
->pwms
[pwm
->hwpwm
- 1];
339 * PWM devices provided by TCB driver are grouped by 2:
340 * - group 0: PWM 0 & 1
341 * - group 1: PWM 2 & 3
342 * - group 2: PWM 4 & 5
344 * PWM devices in a given group must be configured with the
347 * We're checking the period value of the second PWM device
348 * in this group before applying the new config.
350 if ((atcbpwm
&& atcbpwm
->duty
> 0 &&
351 atcbpwm
->duty
!= atcbpwm
->period
) &&
352 (atcbpwm
->div
!= i
|| atcbpwm
->period
!= period
)) {
354 "failed to configure period_ns: PWM group already configured with a different value\n");
358 tcbpwm
->period
= period
;
362 /* If the PWM is enabled, call enable to apply the new conf */
363 if (pwm_is_enabled(pwm
))
364 atmel_tcb_pwm_enable(chip
, pwm
);
369 static const struct pwm_ops atmel_tcb_pwm_ops
= {
370 .request
= atmel_tcb_pwm_request
,
371 .free
= atmel_tcb_pwm_free
,
372 .config
= atmel_tcb_pwm_config
,
373 .set_polarity
= atmel_tcb_pwm_set_polarity
,
374 .enable
= atmel_tcb_pwm_enable
,
375 .disable
= atmel_tcb_pwm_disable
,
376 .owner
= THIS_MODULE
,
379 static int atmel_tcb_pwm_probe(struct platform_device
*pdev
)
381 struct atmel_tcb_pwm_chip
*tcbpwm
;
382 struct device_node
*np
= pdev
->dev
.of_node
;
387 err
= of_property_read_u32(np
, "tc-block", &tcblock
);
390 "failed to get Timer Counter Block number from device tree (error: %d)\n",
395 tc
= atmel_tc_alloc(tcblock
);
397 dev_err(&pdev
->dev
, "failed to allocate Timer Counter Block\n");
401 tcbpwm
= devm_kzalloc(&pdev
->dev
, sizeof(*tcbpwm
), GFP_KERNEL
);
402 if (tcbpwm
== NULL
) {
407 tcbpwm
->chip
.dev
= &pdev
->dev
;
408 tcbpwm
->chip
.ops
= &atmel_tcb_pwm_ops
;
409 tcbpwm
->chip
.of_xlate
= of_pwm_xlate_with_flags
;
410 tcbpwm
->chip
.of_pwm_n_cells
= 3;
411 tcbpwm
->chip
.base
= -1;
412 tcbpwm
->chip
.npwm
= NPWM
;
415 err
= clk_prepare_enable(tc
->slow_clk
);
419 spin_lock_init(&tcbpwm
->lock
);
421 err
= pwmchip_add(&tcbpwm
->chip
);
423 goto err_disable_clk
;
425 platform_set_drvdata(pdev
, tcbpwm
);
430 clk_disable_unprepare(tcbpwm
->tc
->slow_clk
);
438 static int atmel_tcb_pwm_remove(struct platform_device
*pdev
)
440 struct atmel_tcb_pwm_chip
*tcbpwm
= platform_get_drvdata(pdev
);
443 clk_disable_unprepare(tcbpwm
->tc
->slow_clk
);
445 err
= pwmchip_remove(&tcbpwm
->chip
);
449 atmel_tc_free(tcbpwm
->tc
);
454 static const struct of_device_id atmel_tcb_pwm_dt_ids
[] = {
455 { .compatible
= "atmel,tcb-pwm", },
458 MODULE_DEVICE_TABLE(of
, atmel_tcb_pwm_dt_ids
);
460 #ifdef CONFIG_PM_SLEEP
461 static int atmel_tcb_pwm_suspend(struct device
*dev
)
463 struct atmel_tcb_pwm_chip
*tcbpwm
= dev_get_drvdata(dev
);
464 void __iomem
*base
= tcbpwm
->tc
->regs
;
467 for (i
= 0; i
< (NPWM
/ 2); i
++) {
468 struct atmel_tcb_channel
*chan
= &tcbpwm
->bkup
[i
];
470 chan
->cmr
= readl(base
+ ATMEL_TC_REG(i
, CMR
));
471 chan
->ra
= readl(base
+ ATMEL_TC_REG(i
, RA
));
472 chan
->rb
= readl(base
+ ATMEL_TC_REG(i
, RB
));
473 chan
->rc
= readl(base
+ ATMEL_TC_REG(i
, RC
));
478 static int atmel_tcb_pwm_resume(struct device
*dev
)
480 struct atmel_tcb_pwm_chip
*tcbpwm
= dev_get_drvdata(dev
);
481 void __iomem
*base
= tcbpwm
->tc
->regs
;
484 for (i
= 0; i
< (NPWM
/ 2); i
++) {
485 struct atmel_tcb_channel
*chan
= &tcbpwm
->bkup
[i
];
487 writel(chan
->cmr
, base
+ ATMEL_TC_REG(i
, CMR
));
488 writel(chan
->ra
, base
+ ATMEL_TC_REG(i
, RA
));
489 writel(chan
->rb
, base
+ ATMEL_TC_REG(i
, RB
));
490 writel(chan
->rc
, base
+ ATMEL_TC_REG(i
, RC
));
492 writel(ATMEL_TC_CLKEN
| ATMEL_TC_SWTRG
,
493 base
+ ATMEL_TC_REG(i
, CCR
));
500 static SIMPLE_DEV_PM_OPS(atmel_tcb_pwm_pm_ops
, atmel_tcb_pwm_suspend
,
501 atmel_tcb_pwm_resume
);
503 static struct platform_driver atmel_tcb_pwm_driver
= {
505 .name
= "atmel-tcb-pwm",
506 .of_match_table
= atmel_tcb_pwm_dt_ids
,
507 .pm
= &atmel_tcb_pwm_pm_ops
,
509 .probe
= atmel_tcb_pwm_probe
,
510 .remove
= atmel_tcb_pwm_remove
,
512 module_platform_driver(atmel_tcb_pwm_driver
);
514 MODULE_AUTHOR("Boris BREZILLON <b.brezillon@overkiz.com>");
515 MODULE_DESCRIPTION("Atmel Timer Counter Pulse Width Modulation Driver");
516 MODULE_LICENSE("GPL v2");