xref: /linux/drivers/pwm/pwm-atmel.c (revision e0bf6c5ca2d3281f231c5f0c9bf145e9513644de)
1 /*
2  * Driver for Atmel Pulse Width Modulation Controller
3  *
4  * Copyright (C) 2013 Atmel Corporation
5  *		 Bo Shen <voice.shen@atmel.com>
6  *
7  * Licensed under GPLv2.
8  */
9 
10 #include <linux/clk.h>
11 #include <linux/err.h>
12 #include <linux/io.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 #include <linux/pwm.h>
18 #include <linux/slab.h>
19 
20 /* The following is global registers for PWM controller */
21 #define PWM_ENA			0x04
22 #define PWM_DIS			0x08
23 #define PWM_SR			0x0C
24 /* Bit field in SR */
25 #define PWM_SR_ALL_CH_ON	0x0F
26 
27 /* The following register is PWM channel related registers */
28 #define PWM_CH_REG_OFFSET	0x200
29 #define PWM_CH_REG_SIZE		0x20
30 
31 #define PWM_CMR			0x0
32 /* Bit field in CMR */
33 #define PWM_CMR_CPOL		(1 << 9)
34 #define PWM_CMR_UPD_CDTY	(1 << 10)
35 #define PWM_CMR_CPRE_MSK	0xF
36 
37 /* The following registers for PWM v1 */
38 #define PWMV1_CDTY		0x04
39 #define PWMV1_CPRD		0x08
40 #define PWMV1_CUPD		0x10
41 
42 /* The following registers for PWM v2 */
43 #define PWMV2_CDTY		0x04
44 #define PWMV2_CDTYUPD		0x08
45 #define PWMV2_CPRD		0x0C
46 #define PWMV2_CPRDUPD		0x10
47 
48 /*
49  * Max value for duty and period
50  *
51  * Although the duty and period register is 32 bit,
52  * however only the LSB 16 bits are significant.
53  */
54 #define PWM_MAX_DTY		0xFFFF
55 #define PWM_MAX_PRD		0xFFFF
56 #define PRD_MAX_PRES		10
57 
58 struct atmel_pwm_chip {
59 	struct pwm_chip chip;
60 	struct clk *clk;
61 	void __iomem *base;
62 
63 	void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
64 		       unsigned long dty, unsigned long prd);
65 };
66 
67 static inline struct atmel_pwm_chip *to_atmel_pwm_chip(struct pwm_chip *chip)
68 {
69 	return container_of(chip, struct atmel_pwm_chip, chip);
70 }
71 
72 static inline u32 atmel_pwm_readl(struct atmel_pwm_chip *chip,
73 				  unsigned long offset)
74 {
75 	return readl_relaxed(chip->base + offset);
76 }
77 
78 static inline void atmel_pwm_writel(struct atmel_pwm_chip *chip,
79 				    unsigned long offset, unsigned long val)
80 {
81 	writel_relaxed(val, chip->base + offset);
82 }
83 
84 static inline u32 atmel_pwm_ch_readl(struct atmel_pwm_chip *chip,
85 				     unsigned int ch, unsigned long offset)
86 {
87 	unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
88 
89 	return readl_relaxed(chip->base + base + offset);
90 }
91 
92 static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
93 				       unsigned int ch, unsigned long offset,
94 				       unsigned long val)
95 {
96 	unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
97 
98 	writel_relaxed(val, chip->base + base + offset);
99 }
100 
101 static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
102 			    int duty_ns, int period_ns)
103 {
104 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
105 	unsigned long prd, dty;
106 	unsigned long long div;
107 	unsigned int pres = 0;
108 	u32 val;
109 	int ret;
110 
111 	if (test_bit(PWMF_ENABLED, &pwm->flags) && (period_ns != pwm->period)) {
112 		dev_err(chip->dev, "cannot change PWM period while enabled\n");
113 		return -EBUSY;
114 	}
115 
116 	/* Calculate the period cycles and prescale value */
117 	div = (unsigned long long)clk_get_rate(atmel_pwm->clk) * period_ns;
118 	do_div(div, NSEC_PER_SEC);
119 
120 	while (div > PWM_MAX_PRD) {
121 		div >>= 1;
122 		pres++;
123 	}
124 
125 	if (pres > PRD_MAX_PRES) {
126 		dev_err(chip->dev, "pres exceeds the maximum value\n");
127 		return -EINVAL;
128 	}
129 
130 	/* Calculate the duty cycles */
131 	prd = div;
132 	div *= duty_ns;
133 	do_div(div, period_ns);
134 	dty = prd - div;
135 
136 	ret = clk_enable(atmel_pwm->clk);
137 	if (ret) {
138 		dev_err(chip->dev, "failed to enable PWM clock\n");
139 		return ret;
140 	}
141 
142 	/* It is necessary to preserve CPOL, inside CMR */
143 	val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
144 	val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);
145 	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
146 	atmel_pwm->config(chip, pwm, dty, prd);
147 
148 	clk_disable(atmel_pwm->clk);
149 	return ret;
150 }
151 
152 static void atmel_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
153 				unsigned long dty, unsigned long prd)
154 {
155 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
156 	unsigned int val;
157 
158 	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
159 		/*
160 		 * If the PWM channel is enabled, using the update register,
161 		 * it needs to set bit 10 of CMR to 0
162 		 */
163 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CUPD, dty);
164 
165 		val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
166 		val &= ~PWM_CMR_UPD_CDTY;
167 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
168 	} else {
169 		/*
170 		 * If the PWM channel is disabled, write value to duty and
171 		 * period registers directly.
172 		 */
173 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CDTY, dty);
174 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CPRD, prd);
175 	}
176 }
177 
178 static void atmel_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm,
179 				unsigned long dty, unsigned long prd)
180 {
181 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
182 
183 	if (test_bit(PWMF_ENABLED, &pwm->flags)) {
184 		/*
185 		 * If the PWM channel is enabled, using the duty update register
186 		 * to update the value.
187 		 */
188 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV2_CDTYUPD, dty);
189 	} else {
190 		/*
191 		 * If the PWM channel is disabled, write value to duty and
192 		 * period registers directly.
193 		 */
194 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV2_CDTY, dty);
195 		atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV2_CPRD, prd);
196 	}
197 }
198 
199 static int atmel_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
200 				  enum pwm_polarity polarity)
201 {
202 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
203 	u32 val;
204 	int ret;
205 
206 	val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
207 
208 	if (polarity == PWM_POLARITY_NORMAL)
209 		val &= ~PWM_CMR_CPOL;
210 	else
211 		val |= PWM_CMR_CPOL;
212 
213 	ret = clk_enable(atmel_pwm->clk);
214 	if (ret) {
215 		dev_err(chip->dev, "failed to enable PWM clock\n");
216 		return ret;
217 	}
218 
219 	atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
220 
221 	clk_disable(atmel_pwm->clk);
222 
223 	return 0;
224 }
225 
226 static int atmel_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
227 {
228 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
229 	int ret;
230 
231 	ret = clk_enable(atmel_pwm->clk);
232 	if (ret) {
233 		dev_err(chip->dev, "failed to enable PWM clock\n");
234 		return ret;
235 	}
236 
237 	atmel_pwm_writel(atmel_pwm, PWM_ENA, 1 << pwm->hwpwm);
238 
239 	return 0;
240 }
241 
242 static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
243 {
244 	struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
245 
246 	atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);
247 
248 	clk_disable(atmel_pwm->clk);
249 }
250 
251 static const struct pwm_ops atmel_pwm_ops = {
252 	.config = atmel_pwm_config,
253 	.set_polarity = atmel_pwm_set_polarity,
254 	.enable = atmel_pwm_enable,
255 	.disable = atmel_pwm_disable,
256 	.owner = THIS_MODULE,
257 };
258 
259 struct atmel_pwm_data {
260 	void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
261 		       unsigned long dty, unsigned long prd);
262 };
263 
264 static const struct atmel_pwm_data atmel_pwm_data_v1 = {
265 	.config = atmel_pwm_config_v1,
266 };
267 
268 static const struct atmel_pwm_data atmel_pwm_data_v2 = {
269 	.config = atmel_pwm_config_v2,
270 };
271 
272 static const struct platform_device_id atmel_pwm_devtypes[] = {
273 	{
274 		.name = "at91sam9rl-pwm",
275 		.driver_data = (kernel_ulong_t)&atmel_pwm_data_v1,
276 	}, {
277 		.name = "sama5d3-pwm",
278 		.driver_data = (kernel_ulong_t)&atmel_pwm_data_v2,
279 	}, {
280 		/* sentinel */
281 	},
282 };
283 MODULE_DEVICE_TABLE(platform, atmel_pwm_devtypes);
284 
285 static const struct of_device_id atmel_pwm_dt_ids[] = {
286 	{
287 		.compatible = "atmel,at91sam9rl-pwm",
288 		.data = &atmel_pwm_data_v1,
289 	}, {
290 		.compatible = "atmel,sama5d3-pwm",
291 		.data = &atmel_pwm_data_v2,
292 	}, {
293 		/* sentinel */
294 	},
295 };
296 MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
297 
298 static inline const struct atmel_pwm_data *
299 atmel_pwm_get_driver_data(struct platform_device *pdev)
300 {
301 	if (pdev->dev.of_node) {
302 		const struct of_device_id *match;
303 
304 		match = of_match_device(atmel_pwm_dt_ids, &pdev->dev);
305 		if (!match)
306 			return NULL;
307 
308 		return match->data;
309 	} else {
310 		const struct platform_device_id *id;
311 
312 		id = platform_get_device_id(pdev);
313 
314 		return (struct atmel_pwm_data *)id->driver_data;
315 	}
316 }
317 
318 static int atmel_pwm_probe(struct platform_device *pdev)
319 {
320 	const struct atmel_pwm_data *data;
321 	struct atmel_pwm_chip *atmel_pwm;
322 	struct resource *res;
323 	int ret;
324 
325 	data = atmel_pwm_get_driver_data(pdev);
326 	if (!data)
327 		return -ENODEV;
328 
329 	atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL);
330 	if (!atmel_pwm)
331 		return -ENOMEM;
332 
333 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
334 	atmel_pwm->base = devm_ioremap_resource(&pdev->dev, res);
335 	if (IS_ERR(atmel_pwm->base))
336 		return PTR_ERR(atmel_pwm->base);
337 
338 	atmel_pwm->clk = devm_clk_get(&pdev->dev, NULL);
339 	if (IS_ERR(atmel_pwm->clk))
340 		return PTR_ERR(atmel_pwm->clk);
341 
342 	ret = clk_prepare(atmel_pwm->clk);
343 	if (ret) {
344 		dev_err(&pdev->dev, "failed to prepare PWM clock\n");
345 		return ret;
346 	}
347 
348 	atmel_pwm->chip.dev = &pdev->dev;
349 	atmel_pwm->chip.ops = &atmel_pwm_ops;
350 
351 	if (pdev->dev.of_node) {
352 		atmel_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
353 		atmel_pwm->chip.of_pwm_n_cells = 3;
354 	}
355 
356 	atmel_pwm->chip.base = -1;
357 	atmel_pwm->chip.npwm = 4;
358 	atmel_pwm->chip.can_sleep = true;
359 	atmel_pwm->config = data->config;
360 
361 	ret = pwmchip_add(&atmel_pwm->chip);
362 	if (ret < 0) {
363 		dev_err(&pdev->dev, "failed to add PWM chip %d\n", ret);
364 		goto unprepare_clk;
365 	}
366 
367 	platform_set_drvdata(pdev, atmel_pwm);
368 
369 	return ret;
370 
371 unprepare_clk:
372 	clk_unprepare(atmel_pwm->clk);
373 	return ret;
374 }
375 
376 static int atmel_pwm_remove(struct platform_device *pdev)
377 {
378 	struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);
379 
380 	clk_unprepare(atmel_pwm->clk);
381 
382 	return pwmchip_remove(&atmel_pwm->chip);
383 }
384 
385 static struct platform_driver atmel_pwm_driver = {
386 	.driver = {
387 		.name = "atmel-pwm",
388 		.of_match_table = of_match_ptr(atmel_pwm_dt_ids),
389 	},
390 	.id_table = atmel_pwm_devtypes,
391 	.probe = atmel_pwm_probe,
392 	.remove = atmel_pwm_remove,
393 };
394 module_platform_driver(atmel_pwm_driver);
395 
396 MODULE_ALIAS("platform:atmel-pwm");
397 MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
398 MODULE_DESCRIPTION("Atmel PWM driver");
399 MODULE_LICENSE("GPL v2");
400