2 * Driver for Atmel Pulse Width Modulation Controller
4 * Copyright (C) 2013 Atmel Corporation
5 * Bo Shen <voice.shen@atmel.com>
7 * Licensed under GPLv2.
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/err.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
17 #include <linux/of_device.h>
18 #include <linux/platform_device.h>
19 #include <linux/pwm.h>
20 #include <linux/slab.h>
22 /* The following is global registers for PWM controller */
28 #define PWM_SR_ALL_CH_ON 0x0F
30 /* The following register is PWM channel related registers */
31 #define PWM_CH_REG_OFFSET 0x200
32 #define PWM_CH_REG_SIZE 0x20
35 /* Bit field in CMR */
36 #define PWM_CMR_CPOL (1 << 9)
37 #define PWM_CMR_UPD_CDTY (1 << 10)
38 #define PWM_CMR_CPRE_MSK 0xF
40 /* The following registers for PWM v1 */
41 #define PWMV1_CDTY 0x04
42 #define PWMV1_CPRD 0x08
43 #define PWMV1_CUPD 0x10
45 /* The following registers for PWM v2 */
46 #define PWMV2_CDTY 0x04
47 #define PWMV2_CDTYUPD 0x08
48 #define PWMV2_CPRD 0x0C
49 #define PWMV2_CPRDUPD 0x10
52 * Max value for duty and period
54 * Although the duty and period register is 32 bit,
55 * however only the LSB 16 bits are significant.
57 #define PWM_MAX_DTY 0xFFFF
58 #define PWM_MAX_PRD 0xFFFF
59 #define PRD_MAX_PRES 10
61 struct atmel_pwm_chip
{
66 unsigned int updated_pwms
;
67 struct mutex isr_lock
; /* ISR is cleared when read, ensure only one thread does that */
69 void (*config
)(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
70 unsigned long dty
, unsigned long prd
);
73 static inline struct atmel_pwm_chip
*to_atmel_pwm_chip(struct pwm_chip
*chip
)
75 return container_of(chip
, struct atmel_pwm_chip
, chip
);
78 static inline u32
atmel_pwm_readl(struct atmel_pwm_chip
*chip
,
81 return readl_relaxed(chip
->base
+ offset
);
84 static inline void atmel_pwm_writel(struct atmel_pwm_chip
*chip
,
85 unsigned long offset
, unsigned long val
)
87 writel_relaxed(val
, chip
->base
+ offset
);
90 static inline u32
atmel_pwm_ch_readl(struct atmel_pwm_chip
*chip
,
91 unsigned int ch
, unsigned long offset
)
93 unsigned long base
= PWM_CH_REG_OFFSET
+ ch
* PWM_CH_REG_SIZE
;
95 return readl_relaxed(chip
->base
+ base
+ offset
);
98 static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip
*chip
,
99 unsigned int ch
, unsigned long offset
,
102 unsigned long base
= PWM_CH_REG_OFFSET
+ ch
* PWM_CH_REG_SIZE
;
104 writel_relaxed(val
, chip
->base
+ base
+ offset
);
107 static int atmel_pwm_config(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
108 int duty_ns
, int period_ns
)
110 struct atmel_pwm_chip
*atmel_pwm
= to_atmel_pwm_chip(chip
);
111 unsigned long prd
, dty
;
112 unsigned long long div
;
113 unsigned int pres
= 0;
117 if (pwm_is_enabled(pwm
) && (period_ns
!= pwm_get_period(pwm
))) {
118 dev_err(chip
->dev
, "cannot change PWM period while enabled\n");
122 /* Calculate the period cycles and prescale value */
123 div
= (unsigned long long)clk_get_rate(atmel_pwm
->clk
) * period_ns
;
124 do_div(div
, NSEC_PER_SEC
);
126 while (div
> PWM_MAX_PRD
) {
131 if (pres
> PRD_MAX_PRES
) {
132 dev_err(chip
->dev
, "pres exceeds the maximum value\n");
136 /* Calculate the duty cycles */
139 do_div(div
, period_ns
);
142 ret
= clk_enable(atmel_pwm
->clk
);
144 dev_err(chip
->dev
, "failed to enable PWM clock\n");
148 /* It is necessary to preserve CPOL, inside CMR */
149 val
= atmel_pwm_ch_readl(atmel_pwm
, pwm
->hwpwm
, PWM_CMR
);
150 val
= (val
& ~PWM_CMR_CPRE_MSK
) | (pres
& PWM_CMR_CPRE_MSK
);
151 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWM_CMR
, val
);
152 atmel_pwm
->config(chip
, pwm
, dty
, prd
);
153 mutex_lock(&atmel_pwm
->isr_lock
);
154 atmel_pwm
->updated_pwms
|= atmel_pwm_readl(atmel_pwm
, PWM_ISR
);
155 atmel_pwm
->updated_pwms
&= ~(1 << pwm
->hwpwm
);
156 mutex_unlock(&atmel_pwm
->isr_lock
);
158 clk_disable(atmel_pwm
->clk
);
162 static void atmel_pwm_config_v1(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
163 unsigned long dty
, unsigned long prd
)
165 struct atmel_pwm_chip
*atmel_pwm
= to_atmel_pwm_chip(chip
);
169 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWMV1_CUPD
, dty
);
171 val
= atmel_pwm_ch_readl(atmel_pwm
, pwm
->hwpwm
, PWM_CMR
);
172 val
&= ~PWM_CMR_UPD_CDTY
;
173 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWM_CMR
, val
);
176 * If the PWM channel is enabled, only update CDTY by using the update
177 * register, it needs to set bit 10 of CMR to 0
179 if (pwm_is_enabled(pwm
))
182 * If the PWM channel is disabled, write value to duty and period
183 * registers directly.
185 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWMV1_CDTY
, dty
);
186 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWMV1_CPRD
, prd
);
189 static void atmel_pwm_config_v2(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
190 unsigned long dty
, unsigned long prd
)
192 struct atmel_pwm_chip
*atmel_pwm
= to_atmel_pwm_chip(chip
);
194 if (pwm_is_enabled(pwm
)) {
196 * If the PWM channel is enabled, using the duty update register
197 * to update the value.
199 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWMV2_CDTYUPD
, dty
);
202 * If the PWM channel is disabled, write value to duty and
203 * period registers directly.
205 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWMV2_CDTY
, dty
);
206 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWMV2_CPRD
, prd
);
210 static int atmel_pwm_set_polarity(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
211 enum pwm_polarity polarity
)
213 struct atmel_pwm_chip
*atmel_pwm
= to_atmel_pwm_chip(chip
);
217 val
= atmel_pwm_ch_readl(atmel_pwm
, pwm
->hwpwm
, PWM_CMR
);
219 if (polarity
== PWM_POLARITY_NORMAL
)
220 val
&= ~PWM_CMR_CPOL
;
224 ret
= clk_enable(atmel_pwm
->clk
);
226 dev_err(chip
->dev
, "failed to enable PWM clock\n");
230 atmel_pwm_ch_writel(atmel_pwm
, pwm
->hwpwm
, PWM_CMR
, val
);
232 clk_disable(atmel_pwm
->clk
);
237 static int atmel_pwm_enable(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
239 struct atmel_pwm_chip
*atmel_pwm
= to_atmel_pwm_chip(chip
);
242 ret
= clk_enable(atmel_pwm
->clk
);
244 dev_err(chip
->dev
, "failed to enable PWM clock\n");
248 atmel_pwm_writel(atmel_pwm
, PWM_ENA
, 1 << pwm
->hwpwm
);
253 static void atmel_pwm_disable(struct pwm_chip
*chip
, struct pwm_device
*pwm
)
255 struct atmel_pwm_chip
*atmel_pwm
= to_atmel_pwm_chip(chip
);
256 unsigned long timeout
= jiffies
+ 2 * HZ
;
259 * Wait for at least a complete period to have passed before disabling a
260 * channel to be sure that CDTY has been updated
262 mutex_lock(&atmel_pwm
->isr_lock
);
263 atmel_pwm
->updated_pwms
|= atmel_pwm_readl(atmel_pwm
, PWM_ISR
);
265 while (!(atmel_pwm
->updated_pwms
& (1 << pwm
->hwpwm
)) &&
266 time_before(jiffies
, timeout
)) {
267 usleep_range(10, 100);
268 atmel_pwm
->updated_pwms
|= atmel_pwm_readl(atmel_pwm
, PWM_ISR
);
271 mutex_unlock(&atmel_pwm
->isr_lock
);
272 atmel_pwm_writel(atmel_pwm
, PWM_DIS
, 1 << pwm
->hwpwm
);
274 clk_disable(atmel_pwm
->clk
);
277 static const struct pwm_ops atmel_pwm_ops
= {
278 .config
= atmel_pwm_config
,
279 .set_polarity
= atmel_pwm_set_polarity
,
280 .enable
= atmel_pwm_enable
,
281 .disable
= atmel_pwm_disable
,
282 .owner
= THIS_MODULE
,
285 struct atmel_pwm_data
{
286 void (*config
)(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
287 unsigned long dty
, unsigned long prd
);
290 static const struct atmel_pwm_data atmel_pwm_data_v1
= {
291 .config
= atmel_pwm_config_v1
,
294 static const struct atmel_pwm_data atmel_pwm_data_v2
= {
295 .config
= atmel_pwm_config_v2
,
298 static const struct platform_device_id atmel_pwm_devtypes
[] = {
300 .name
= "at91sam9rl-pwm",
301 .driver_data
= (kernel_ulong_t
)&atmel_pwm_data_v1
,
303 .name
= "sama5d3-pwm",
304 .driver_data
= (kernel_ulong_t
)&atmel_pwm_data_v2
,
309 MODULE_DEVICE_TABLE(platform
, atmel_pwm_devtypes
);
311 static const struct of_device_id atmel_pwm_dt_ids
[] = {
313 .compatible
= "atmel,at91sam9rl-pwm",
314 .data
= &atmel_pwm_data_v1
,
316 .compatible
= "atmel,sama5d3-pwm",
317 .data
= &atmel_pwm_data_v2
,
322 MODULE_DEVICE_TABLE(of
, atmel_pwm_dt_ids
);
324 static inline const struct atmel_pwm_data
*
325 atmel_pwm_get_driver_data(struct platform_device
*pdev
)
327 if (pdev
->dev
.of_node
) {
328 const struct of_device_id
*match
;
330 match
= of_match_device(atmel_pwm_dt_ids
, &pdev
->dev
);
336 const struct platform_device_id
*id
;
338 id
= platform_get_device_id(pdev
);
340 return (struct atmel_pwm_data
*)id
->driver_data
;
344 static int atmel_pwm_probe(struct platform_device
*pdev
)
346 const struct atmel_pwm_data
*data
;
347 struct atmel_pwm_chip
*atmel_pwm
;
348 struct resource
*res
;
351 data
= atmel_pwm_get_driver_data(pdev
);
355 atmel_pwm
= devm_kzalloc(&pdev
->dev
, sizeof(*atmel_pwm
), GFP_KERNEL
);
359 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
360 atmel_pwm
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
361 if (IS_ERR(atmel_pwm
->base
))
362 return PTR_ERR(atmel_pwm
->base
);
364 atmel_pwm
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
365 if (IS_ERR(atmel_pwm
->clk
))
366 return PTR_ERR(atmel_pwm
->clk
);
368 ret
= clk_prepare(atmel_pwm
->clk
);
370 dev_err(&pdev
->dev
, "failed to prepare PWM clock\n");
374 atmel_pwm
->chip
.dev
= &pdev
->dev
;
375 atmel_pwm
->chip
.ops
= &atmel_pwm_ops
;
377 if (pdev
->dev
.of_node
) {
378 atmel_pwm
->chip
.of_xlate
= of_pwm_xlate_with_flags
;
379 atmel_pwm
->chip
.of_pwm_n_cells
= 3;
382 atmel_pwm
->chip
.base
= -1;
383 atmel_pwm
->chip
.npwm
= 4;
384 atmel_pwm
->chip
.can_sleep
= true;
385 atmel_pwm
->config
= data
->config
;
386 atmel_pwm
->updated_pwms
= 0;
387 mutex_init(&atmel_pwm
->isr_lock
);
389 ret
= pwmchip_add(&atmel_pwm
->chip
);
391 dev_err(&pdev
->dev
, "failed to add PWM chip %d\n", ret
);
395 platform_set_drvdata(pdev
, atmel_pwm
);
400 clk_unprepare(atmel_pwm
->clk
);
404 static int atmel_pwm_remove(struct platform_device
*pdev
)
406 struct atmel_pwm_chip
*atmel_pwm
= platform_get_drvdata(pdev
);
408 clk_unprepare(atmel_pwm
->clk
);
409 mutex_destroy(&atmel_pwm
->isr_lock
);
411 return pwmchip_remove(&atmel_pwm
->chip
);
414 static struct platform_driver atmel_pwm_driver
= {
417 .of_match_table
= of_match_ptr(atmel_pwm_dt_ids
),
419 .id_table
= atmel_pwm_devtypes
,
420 .probe
= atmel_pwm_probe
,
421 .remove
= atmel_pwm_remove
,
423 module_platform_driver(atmel_pwm_driver
);
425 MODULE_ALIAS("platform:atmel-pwm");
426 MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
427 MODULE_DESCRIPTION("Atmel PWM driver");
428 MODULE_LICENSE("GPL v2");