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_pwm_chip
{
44 struct atmel_tcb_pwm_device
*pwms
[NPWM
];
47 static inline struct atmel_tcb_pwm_chip
*to_tcb_chip(struct pwm_chip
*chip
)
49 return container_of(chip
, struct atmel_tcb_pwm_chip
, chip
);
52 static int atmel_tcb_pwm_set_polarity(struct pwm_chip
*chip
,
53 struct pwm_device
*pwm
,
54 enum pwm_polarity polarity
)
56 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
58 tcbpwm
->polarity
= polarity
;
63 static int atmel_tcb_pwm_request(struct pwm_chip
*chip
,
64 struct pwm_device
*pwm
)
66 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
67 struct atmel_tcb_pwm_device
*tcbpwm
;
68 struct atmel_tc
*tc
= tcbpwmc
->tc
;
69 void __iomem
*regs
= tc
->regs
;
70 unsigned group
= pwm
->hwpwm
/ 2;
71 unsigned index
= pwm
->hwpwm
% 2;
75 tcbpwm
= devm_kzalloc(chip
->dev
, sizeof(*tcbpwm
), GFP_KERNEL
);
79 ret
= clk_prepare_enable(tc
->clk
[group
]);
81 devm_kfree(chip
->dev
, tcbpwm
);
85 pwm_set_chip_data(pwm
, tcbpwm
);
86 tcbpwm
->polarity
= PWM_POLARITY_NORMAL
;
91 spin_lock(&tcbpwmc
->lock
);
92 cmr
= __raw_readl(regs
+ ATMEL_TC_REG(group
, CMR
));
94 * Get init config from Timer Counter registers if
95 * Timer Counter is already configured as a PWM generator.
97 if (cmr
& ATMEL_TC_WAVE
) {
100 __raw_readl(regs
+ ATMEL_TC_REG(group
, RA
));
103 __raw_readl(regs
+ ATMEL_TC_REG(group
, RB
));
105 tcbpwm
->div
= cmr
& ATMEL_TC_TCCLKS
;
106 tcbpwm
->period
= __raw_readl(regs
+ ATMEL_TC_REG(group
, RC
));
107 cmr
&= (ATMEL_TC_TCCLKS
| ATMEL_TC_ACMR_MASK
|
112 cmr
|= ATMEL_TC_WAVE
| ATMEL_TC_WAVESEL_UP_AUTO
| ATMEL_TC_EEVT_XC0
;
113 __raw_writel(cmr
, regs
+ ATMEL_TC_REG(group
, CMR
));
114 spin_unlock(&tcbpwmc
->lock
);
116 tcbpwmc
->pwms
[pwm
->hwpwm
] = tcbpwm
;
121 static void atmel_tcb_pwm_free(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
123 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
124 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
125 struct atmel_tc
*tc
= tcbpwmc
->tc
;
127 clk_disable_unprepare(tc
->clk
[pwm
->hwpwm
/ 2]);
128 tcbpwmc
->pwms
[pwm
->hwpwm
] = NULL
;
129 devm_kfree(chip
->dev
, tcbpwm
);
132 static void atmel_tcb_pwm_disable(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
134 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
135 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
136 struct atmel_tc
*tc
= tcbpwmc
->tc
;
137 void __iomem
*regs
= tc
->regs
;
138 unsigned group
= pwm
->hwpwm
/ 2;
139 unsigned index
= pwm
->hwpwm
% 2;
141 enum pwm_polarity polarity
= tcbpwm
->polarity
;
144 * If duty is 0 the timer will be stopped and we have to
145 * configure the output correctly on software trigger:
146 * - set output to high if PWM_POLARITY_INVERSED
147 * - set output to low if PWM_POLARITY_NORMAL
149 * This is why we're reverting polarity in this case.
151 if (tcbpwm
->duty
== 0)
152 polarity
= !polarity
;
154 spin_lock(&tcbpwmc
->lock
);
155 cmr
= __raw_readl(regs
+ ATMEL_TC_REG(group
, CMR
));
157 /* flush old setting and set the new one */
159 cmr
&= ~ATMEL_TC_ACMR_MASK
;
160 if (polarity
== PWM_POLARITY_INVERSED
)
161 cmr
|= ATMEL_TC_ASWTRG_CLEAR
;
163 cmr
|= ATMEL_TC_ASWTRG_SET
;
165 cmr
&= ~ATMEL_TC_BCMR_MASK
;
166 if (polarity
== PWM_POLARITY_INVERSED
)
167 cmr
|= ATMEL_TC_BSWTRG_CLEAR
;
169 cmr
|= ATMEL_TC_BSWTRG_SET
;
172 __raw_writel(cmr
, regs
+ ATMEL_TC_REG(group
, CMR
));
175 * Use software trigger to apply the new setting.
176 * If both PWM devices in this group are disabled we stop the clock.
178 if (!(cmr
& (ATMEL_TC_ACPC
| ATMEL_TC_BCPC
)))
179 __raw_writel(ATMEL_TC_SWTRG
| ATMEL_TC_CLKDIS
,
180 regs
+ ATMEL_TC_REG(group
, CCR
));
182 __raw_writel(ATMEL_TC_SWTRG
, regs
+
183 ATMEL_TC_REG(group
, CCR
));
185 spin_unlock(&tcbpwmc
->lock
);
188 static int atmel_tcb_pwm_enable(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
190 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
191 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
192 struct atmel_tc
*tc
= tcbpwmc
->tc
;
193 void __iomem
*regs
= tc
->regs
;
194 unsigned group
= pwm
->hwpwm
/ 2;
195 unsigned index
= pwm
->hwpwm
% 2;
197 enum pwm_polarity polarity
= tcbpwm
->polarity
;
200 * If duty is 0 the timer will be stopped and we have to
201 * configure the output correctly on software trigger:
202 * - set output to high if PWM_POLARITY_INVERSED
203 * - set output to low if PWM_POLARITY_NORMAL
205 * This is why we're reverting polarity in this case.
207 if (tcbpwm
->duty
== 0)
208 polarity
= !polarity
;
210 spin_lock(&tcbpwmc
->lock
);
211 cmr
= __raw_readl(regs
+ ATMEL_TC_REG(group
, CMR
));
213 /* flush old setting and set the new one */
214 cmr
&= ~ATMEL_TC_TCCLKS
;
217 cmr
&= ~ATMEL_TC_ACMR_MASK
;
219 /* Set CMR flags according to given polarity */
220 if (polarity
== PWM_POLARITY_INVERSED
)
221 cmr
|= ATMEL_TC_ASWTRG_CLEAR
;
223 cmr
|= ATMEL_TC_ASWTRG_SET
;
225 cmr
&= ~ATMEL_TC_BCMR_MASK
;
226 if (polarity
== PWM_POLARITY_INVERSED
)
227 cmr
|= ATMEL_TC_BSWTRG_CLEAR
;
229 cmr
|= ATMEL_TC_BSWTRG_SET
;
233 * If duty is 0 or equal to period there's no need to register
234 * a specific action on RA/RB and RC compare.
235 * The output will be configured on software trigger and keep
236 * this config till next config call.
238 if (tcbpwm
->duty
!= tcbpwm
->period
&& tcbpwm
->duty
> 0) {
240 if (polarity
== PWM_POLARITY_INVERSED
)
241 cmr
|= ATMEL_TC_ACPA_SET
| ATMEL_TC_ACPC_CLEAR
;
243 cmr
|= ATMEL_TC_ACPA_CLEAR
| ATMEL_TC_ACPC_SET
;
245 if (polarity
== PWM_POLARITY_INVERSED
)
246 cmr
|= ATMEL_TC_BCPB_SET
| ATMEL_TC_BCPC_CLEAR
;
248 cmr
|= ATMEL_TC_BCPB_CLEAR
| ATMEL_TC_BCPC_SET
;
252 __raw_writel(cmr
, regs
+ ATMEL_TC_REG(group
, CMR
));
255 __raw_writel(tcbpwm
->duty
, regs
+ ATMEL_TC_REG(group
, RA
));
257 __raw_writel(tcbpwm
->duty
, regs
+ ATMEL_TC_REG(group
, RB
));
259 __raw_writel(tcbpwm
->period
, regs
+ ATMEL_TC_REG(group
, RC
));
261 /* Use software trigger to apply the new setting */
262 __raw_writel(ATMEL_TC_CLKEN
| ATMEL_TC_SWTRG
,
263 regs
+ ATMEL_TC_REG(group
, CCR
));
264 spin_unlock(&tcbpwmc
->lock
);
268 static int atmel_tcb_pwm_config(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
269 int duty_ns
, int period_ns
)
271 struct atmel_tcb_pwm_chip
*tcbpwmc
= to_tcb_chip(chip
);
272 struct atmel_tcb_pwm_device
*tcbpwm
= pwm_get_chip_data(pwm
);
273 unsigned group
= pwm
->hwpwm
/ 2;
274 unsigned index
= pwm
->hwpwm
% 2;
275 struct atmel_tcb_pwm_device
*atcbpwm
= NULL
;
276 struct atmel_tc
*tc
= tcbpwmc
->tc
;
281 unsigned rate
= clk_get_rate(tc
->clk
[group
]);
282 unsigned long long min
;
283 unsigned long long max
;
286 * Find best clk divisor:
287 * the smallest divisor which can fulfill the period_ns requirements.
289 for (i
= 0; i
< 5; ++i
) {
290 if (atmel_tc_divisors
[i
] == 0) {
294 min
= div_u64((u64
)NSEC_PER_SEC
* atmel_tc_divisors
[i
], rate
);
295 max
= min
<< tc
->tcb_config
->counter_width
;
296 if (max
>= period_ns
)
301 * If none of the divisor are small enough to represent period_ns
302 * take slow clock (32KHz).
307 min
= div_u64(NSEC_PER_SEC
, rate
);
310 /* If period is too big return ERANGE error */
315 duty
= div_u64(duty_ns
, min
);
316 period
= div_u64(period_ns
, min
);
319 atcbpwm
= tcbpwmc
->pwms
[pwm
->hwpwm
+ 1];
321 atcbpwm
= tcbpwmc
->pwms
[pwm
->hwpwm
- 1];
324 * PWM devices provided by TCB driver are grouped by 2:
325 * - group 0: PWM 0 & 1
326 * - group 1: PWM 2 & 3
327 * - group 2: PWM 4 & 5
329 * PWM devices in a given group must be configured with the
332 * We're checking the period value of the second PWM device
333 * in this group before applying the new config.
335 if ((atcbpwm
&& atcbpwm
->duty
> 0 &&
336 atcbpwm
->duty
!= atcbpwm
->period
) &&
337 (atcbpwm
->div
!= i
|| atcbpwm
->period
!= period
)) {
339 "failed to configure period_ns: PWM group already configured with a different value\n");
343 tcbpwm
->period
= period
;
347 /* If the PWM is enabled, call enable to apply the new conf */
348 if (test_bit(PWMF_ENABLED
, &pwm
->flags
))
349 atmel_tcb_pwm_enable(chip
, pwm
);
354 static const struct pwm_ops atmel_tcb_pwm_ops
= {
355 .request
= atmel_tcb_pwm_request
,
356 .free
= atmel_tcb_pwm_free
,
357 .config
= atmel_tcb_pwm_config
,
358 .set_polarity
= atmel_tcb_pwm_set_polarity
,
359 .enable
= atmel_tcb_pwm_enable
,
360 .disable
= atmel_tcb_pwm_disable
,
361 .owner
= THIS_MODULE
,
364 static int atmel_tcb_pwm_probe(struct platform_device
*pdev
)
366 struct atmel_tcb_pwm_chip
*tcbpwm
;
367 struct device_node
*np
= pdev
->dev
.of_node
;
372 err
= of_property_read_u32(np
, "tc-block", &tcblock
);
375 "failed to get Timer Counter Block number from device tree (error: %d)\n",
380 tc
= atmel_tc_alloc(tcblock
, "tcb-pwm");
382 dev_err(&pdev
->dev
, "failed to allocate Timer Counter Block\n");
386 tcbpwm
= devm_kzalloc(&pdev
->dev
, sizeof(*tcbpwm
), GFP_KERNEL
);
387 if (tcbpwm
== NULL
) {
389 dev_err(&pdev
->dev
, "failed to allocate memory\n");
393 tcbpwm
->chip
.dev
= &pdev
->dev
;
394 tcbpwm
->chip
.ops
= &atmel_tcb_pwm_ops
;
395 tcbpwm
->chip
.of_xlate
= of_pwm_xlate_with_flags
;
396 tcbpwm
->chip
.of_pwm_n_cells
= 3;
397 tcbpwm
->chip
.base
= -1;
398 tcbpwm
->chip
.npwm
= NPWM
;
401 spin_lock_init(&tcbpwm
->lock
);
403 err
= pwmchip_add(&tcbpwm
->chip
);
409 platform_set_drvdata(pdev
, tcbpwm
);
414 static int atmel_tcb_pwm_remove(struct platform_device
*pdev
)
416 struct atmel_tcb_pwm_chip
*tcbpwm
= platform_get_drvdata(pdev
);
419 err
= pwmchip_remove(&tcbpwm
->chip
);
423 atmel_tc_free(tcbpwm
->tc
);
428 static const struct of_device_id atmel_tcb_pwm_dt_ids
[] = {
429 { .compatible
= "atmel,tcb-pwm", },
432 MODULE_DEVICE_TABLE(of
, atmel_tcb_pwm_dt_ids
);
434 static struct platform_driver atmel_tcb_pwm_driver
= {
436 .name
= "atmel-tcb-pwm",
437 .owner
= THIS_MODULE
,
438 .of_match_table
= atmel_tcb_pwm_dt_ids
,
440 .probe
= atmel_tcb_pwm_probe
,
441 .remove
= atmel_tcb_pwm_remove
,
443 module_platform_driver(atmel_tcb_pwm_driver
);
445 MODULE_AUTHOR("Boris BREZILLON <b.brezillon@overkiz.com>");
446 MODULE_DESCRIPTION("Atmel Timer Counter Pulse Width Modulation Driver");
447 MODULE_LICENSE("GPL v2");