aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-atmel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-atmel.c')
-rw-r--r--drivers/pwm/pwm-atmel.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 530d7dc5f1b5..7e86a5266eb6 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -65,11 +65,15 @@ struct atmel_pwm_registers {
65 u8 duty_upd; 65 u8 duty_upd;
66}; 66};
67 67
68struct atmel_pwm_data {
69 struct atmel_pwm_registers regs;
70};
71
68struct atmel_pwm_chip { 72struct atmel_pwm_chip {
69 struct pwm_chip chip; 73 struct pwm_chip chip;
70 struct clk *clk; 74 struct clk *clk;
71 void __iomem *base; 75 void __iomem *base;
72 const struct atmel_pwm_registers *regs; 76 const struct atmel_pwm_data *data;
73 77
74 unsigned int updated_pwms; 78 unsigned int updated_pwms;
75 /* ISR is cleared when read, ensure only one thread does that */ 79 /* ISR is cleared when read, ensure only one thread does that */
@@ -150,15 +154,15 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,
150 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); 154 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
151 u32 val; 155 u32 val;
152 156
153 if (atmel_pwm->regs->duty_upd == 157 if (atmel_pwm->data->regs.duty_upd ==
154 atmel_pwm->regs->period_upd) { 158 atmel_pwm->data->regs.period_upd) {
155 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR); 159 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
156 val &= ~PWM_CMR_UPD_CDTY; 160 val &= ~PWM_CMR_UPD_CDTY;
157 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val); 161 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
158 } 162 }
159 163
160 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, 164 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
161 atmel_pwm->regs->duty_upd, cdty); 165 atmel_pwm->data->regs.duty_upd, cdty);
162} 166}
163 167
164static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip, 168static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
@@ -168,9 +172,9 @@ static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
168 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); 172 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
169 173
170 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, 174 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
171 atmel_pwm->regs->duty, cdty); 175 atmel_pwm->data->regs.duty, cdty);
172 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, 176 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm,
173 atmel_pwm->regs->period, cprd); 177 atmel_pwm->data->regs.period, cprd);
174} 178}
175 179
176static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm, 180static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -225,7 +229,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
225 cstate.polarity == state->polarity && 229 cstate.polarity == state->polarity &&
226 cstate.period == state->period) { 230 cstate.period == state->period) {
227 cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, 231 cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
228 atmel_pwm->regs->period); 232 atmel_pwm->data->regs.period);
229 atmel_pwm_calculate_cdty(state, cprd, &cdty); 233 atmel_pwm_calculate_cdty(state, cprd, &cdty);
230 atmel_pwm_update_cdty(chip, pwm, cdty); 234 atmel_pwm_update_cdty(chip, pwm, cdty);
231 return 0; 235 return 0;
@@ -277,27 +281,31 @@ static const struct pwm_ops atmel_pwm_ops = {
277 .owner = THIS_MODULE, 281 .owner = THIS_MODULE,
278}; 282};
279 283
280static const struct atmel_pwm_registers atmel_pwm_regs_v1 = { 284static const struct atmel_pwm_data atmel_pwm_data_v1 = {
281 .period = PWMV1_CPRD, 285 .regs = {
282 .period_upd = PWMV1_CUPD, 286 .period = PWMV1_CPRD,
283 .duty = PWMV1_CDTY, 287 .period_upd = PWMV1_CUPD,
284 .duty_upd = PWMV1_CUPD, 288 .duty = PWMV1_CDTY,
289 .duty_upd = PWMV1_CUPD,
290 },
285}; 291};
286 292
287static const struct atmel_pwm_registers atmel_pwm_regs_v2 = { 293static const struct atmel_pwm_data atmel_pwm_data_v2 = {
288 .period = PWMV2_CPRD, 294 .regs = {
289 .period_upd = PWMV2_CPRDUPD, 295 .period = PWMV2_CPRD,
290 .duty = PWMV2_CDTY, 296 .period_upd = PWMV2_CPRDUPD,
291 .duty_upd = PWMV2_CDTYUPD, 297 .duty = PWMV2_CDTY,
298 .duty_upd = PWMV2_CDTYUPD,
299 },
292}; 300};
293 301
294static const struct platform_device_id atmel_pwm_devtypes[] = { 302static const struct platform_device_id atmel_pwm_devtypes[] = {
295 { 303 {
296 .name = "at91sam9rl-pwm", 304 .name = "at91sam9rl-pwm",
297 .driver_data = (kernel_ulong_t)&atmel_pwm_regs_v1, 305 .driver_data = (kernel_ulong_t)&atmel_pwm_data_v1,
298 }, { 306 }, {
299 .name = "sama5d3-pwm", 307 .name = "sama5d3-pwm",
300 .driver_data = (kernel_ulong_t)&atmel_pwm_regs_v2, 308 .driver_data = (kernel_ulong_t)&atmel_pwm_data_v2,
301 }, { 309 }, {
302 /* sentinel */ 310 /* sentinel */
303 }, 311 },
@@ -307,20 +315,20 @@ MODULE_DEVICE_TABLE(platform, atmel_pwm_devtypes);
307static const struct of_device_id atmel_pwm_dt_ids[] = { 315static const struct of_device_id atmel_pwm_dt_ids[] = {
308 { 316 {
309 .compatible = "atmel,at91sam9rl-pwm", 317 .compatible = "atmel,at91sam9rl-pwm",
310 .data = &atmel_pwm_regs_v1, 318 .data = &atmel_pwm_data_v1,
311 }, { 319 }, {
312 .compatible = "atmel,sama5d3-pwm", 320 .compatible = "atmel,sama5d3-pwm",
313 .data = &atmel_pwm_regs_v2, 321 .data = &atmel_pwm_data_v2,
314 }, { 322 }, {
315 .compatible = "atmel,sama5d2-pwm", 323 .compatible = "atmel,sama5d2-pwm",
316 .data = &atmel_pwm_regs_v2, 324 .data = &atmel_pwm_data_v2,
317 }, { 325 }, {
318 /* sentinel */ 326 /* sentinel */
319 }, 327 },
320}; 328};
321MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids); 329MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
322 330
323static inline const struct atmel_pwm_registers * 331static inline const struct atmel_pwm_data *
324atmel_pwm_get_driver_data(struct platform_device *pdev) 332atmel_pwm_get_driver_data(struct platform_device *pdev)
325{ 333{
326 const struct platform_device_id *id; 334 const struct platform_device_id *id;
@@ -330,18 +338,18 @@ atmel_pwm_get_driver_data(struct platform_device *pdev)
330 338
331 id = platform_get_device_id(pdev); 339 id = platform_get_device_id(pdev);
332 340
333 return (struct atmel_pwm_registers *)id->driver_data; 341 return (struct atmel_pwm_data *)id->driver_data;
334} 342}
335 343
336static int atmel_pwm_probe(struct platform_device *pdev) 344static int atmel_pwm_probe(struct platform_device *pdev)
337{ 345{
338 const struct atmel_pwm_registers *regs; 346 const struct atmel_pwm_data *data;
339 struct atmel_pwm_chip *atmel_pwm; 347 struct atmel_pwm_chip *atmel_pwm;
340 struct resource *res; 348 struct resource *res;
341 int ret; 349 int ret;
342 350
343 regs = atmel_pwm_get_driver_data(pdev); 351 data = atmel_pwm_get_driver_data(pdev);
344 if (!regs) 352 if (!data)
345 return -ENODEV; 353 return -ENODEV;
346 354
347 atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL); 355 atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL);
@@ -373,7 +381,7 @@ static int atmel_pwm_probe(struct platform_device *pdev)
373 381
374 atmel_pwm->chip.base = -1; 382 atmel_pwm->chip.base = -1;
375 atmel_pwm->chip.npwm = 4; 383 atmel_pwm->chip.npwm = 4;
376 atmel_pwm->regs = regs; 384 atmel_pwm->data = data;
377 atmel_pwm->updated_pwms = 0; 385 atmel_pwm->updated_pwms = 0;
378 mutex_init(&atmel_pwm->isr_lock); 386 mutex_init(&atmel_pwm->isr_lock);
379 387