48
48
#define PWMV2_CPRD 0x0C
49
49
#define PWMV2_CPRDUPD 0x10
50
50
51
- /*
52
- * Max value for duty and period
53
- *
54
- * Although the duty and period register is 32 bit,
55
- * however only the LSB 16 bits are significant.
56
- */
57
- #define PWM_MAX_DTY 0xFFFF
58
- #define PWM_MAX_PRD 0xFFFF
59
- #define PRD_MAX_PRES 10
60
-
61
51
struct atmel_pwm_registers {
62
52
u8 period ;
63
53
u8 period_upd ;
64
54
u8 duty ;
65
55
u8 duty_upd ;
66
56
};
67
57
58
+ struct atmel_pwm_config {
59
+ u32 max_period ;
60
+ u32 max_pres ;
61
+ };
62
+
63
+ struct atmel_pwm_data {
64
+ struct atmel_pwm_registers regs ;
65
+ struct atmel_pwm_config cfg ;
66
+ };
67
+
68
68
struct atmel_pwm_chip {
69
69
struct pwm_chip chip ;
70
70
struct clk * clk ;
71
71
void __iomem * base ;
72
- const struct atmel_pwm_registers * regs ;
72
+ const struct atmel_pwm_data * data ;
73
73
74
74
unsigned int updated_pwms ;
75
75
/* ISR is cleared when read, ensure only one thread does that */
@@ -121,10 +121,10 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
121
121
cycles *= clk_get_rate (atmel_pwm -> clk );
122
122
do_div (cycles , NSEC_PER_SEC );
123
123
124
- for (* pres = 0 ; cycles > PWM_MAX_PRD ; cycles >>= 1 )
124
+ for (* pres = 0 ; cycles > atmel_pwm -> data -> cfg . max_period ; cycles >>= 1 )
125
125
(* pres )++ ;
126
126
127
- if (* pres > PRD_MAX_PRES ) {
127
+ if (* pres > atmel_pwm -> data -> cfg . max_pres ) {
128
128
dev_err (chip -> dev , "pres exceeds the maximum value\n" );
129
129
return - EINVAL ;
130
130
}
@@ -150,15 +150,15 @@ static void atmel_pwm_update_cdty(struct pwm_chip *chip, struct pwm_device *pwm,
150
150
struct atmel_pwm_chip * atmel_pwm = to_atmel_pwm_chip (chip );
151
151
u32 val ;
152
152
153
- if (atmel_pwm -> regs -> duty_upd ==
154
- atmel_pwm -> regs -> period_upd ) {
153
+ if (atmel_pwm -> data -> regs . duty_upd ==
154
+ atmel_pwm -> data -> regs . period_upd ) {
155
155
val = atmel_pwm_ch_readl (atmel_pwm , pwm -> hwpwm , PWM_CMR );
156
156
val &= ~PWM_CMR_UPD_CDTY ;
157
157
atmel_pwm_ch_writel (atmel_pwm , pwm -> hwpwm , PWM_CMR , val );
158
158
}
159
159
160
160
atmel_pwm_ch_writel (atmel_pwm , pwm -> hwpwm ,
161
- atmel_pwm -> regs -> duty_upd , cdty );
161
+ atmel_pwm -> data -> regs . duty_upd , cdty );
162
162
}
163
163
164
164
static void atmel_pwm_set_cprd_cdty (struct pwm_chip * chip ,
@@ -168,9 +168,9 @@ static void atmel_pwm_set_cprd_cdty(struct pwm_chip *chip,
168
168
struct atmel_pwm_chip * atmel_pwm = to_atmel_pwm_chip (chip );
169
169
170
170
atmel_pwm_ch_writel (atmel_pwm , pwm -> hwpwm ,
171
- atmel_pwm -> regs -> duty , cdty );
171
+ atmel_pwm -> data -> regs . duty , cdty );
172
172
atmel_pwm_ch_writel (atmel_pwm , pwm -> hwpwm ,
173
- atmel_pwm -> regs -> period , cprd );
173
+ atmel_pwm -> data -> regs . period , cprd );
174
174
}
175
175
176
176
static void atmel_pwm_disable (struct pwm_chip * chip , struct pwm_device * pwm ,
@@ -225,7 +225,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
225
225
cstate .polarity == state -> polarity &&
226
226
cstate .period == state -> period ) {
227
227
cprd = atmel_pwm_ch_readl (atmel_pwm , pwm -> hwpwm ,
228
- atmel_pwm -> regs -> period );
228
+ atmel_pwm -> data -> regs . period );
229
229
atmel_pwm_calculate_cdty (state , cprd , & cdty );
230
230
atmel_pwm_update_cdty (chip , pwm , cdty );
231
231
return 0 ;
@@ -277,27 +277,55 @@ static const struct pwm_ops atmel_pwm_ops = {
277
277
.owner = THIS_MODULE ,
278
278
};
279
279
280
- static const struct atmel_pwm_registers atmel_pwm_regs_v1 = {
281
- .period = PWMV1_CPRD ,
282
- .period_upd = PWMV1_CUPD ,
283
- .duty = PWMV1_CDTY ,
284
- .duty_upd = PWMV1_CUPD ,
280
+ static const struct atmel_pwm_data atmel_sam9rl_pwm_data = {
281
+ .regs = {
282
+ .period = PWMV1_CPRD ,
283
+ .period_upd = PWMV1_CUPD ,
284
+ .duty = PWMV1_CDTY ,
285
+ .duty_upd = PWMV1_CUPD ,
286
+ },
287
+ .cfg = {
288
+ /* 16 bits to keep period and duty. */
289
+ .max_period = 0xffff ,
290
+ .max_pres = 10 ,
291
+ },
292
+ };
293
+
294
+ static const struct atmel_pwm_data atmel_sama5_pwm_data = {
295
+ .regs = {
296
+ .period = PWMV2_CPRD ,
297
+ .period_upd = PWMV2_CPRDUPD ,
298
+ .duty = PWMV2_CDTY ,
299
+ .duty_upd = PWMV2_CDTYUPD ,
300
+ },
301
+ .cfg = {
302
+ /* 16 bits to keep period and duty. */
303
+ .max_period = 0xffff ,
304
+ .max_pres = 10 ,
305
+ },
285
306
};
286
307
287
- static const struct atmel_pwm_registers atmel_pwm_regs_v2 = {
288
- .period = PWMV2_CPRD ,
289
- .period_upd = PWMV2_CPRDUPD ,
290
- .duty = PWMV2_CDTY ,
291
- .duty_upd = PWMV2_CDTYUPD ,
308
+ static const struct atmel_pwm_data mchp_sam9x60_pwm_data = {
309
+ .regs = {
310
+ .period = PWMV1_CPRD ,
311
+ .period_upd = PWMV1_CUPD ,
312
+ .duty = PWMV1_CDTY ,
313
+ .duty_upd = PWMV1_CUPD ,
314
+ },
315
+ .cfg = {
316
+ /* 32 bits to keep period and duty. */
317
+ .max_period = 0xffffffff ,
318
+ .max_pres = 10 ,
319
+ },
292
320
};
293
321
294
322
static const struct platform_device_id atmel_pwm_devtypes [] = {
295
323
{
296
324
.name = "at91sam9rl-pwm" ,
297
- .driver_data = (kernel_ulong_t )& atmel_pwm_regs_v1 ,
325
+ .driver_data = (kernel_ulong_t )& atmel_sam9rl_pwm_data ,
298
326
}, {
299
327
.name = "sama5d3-pwm" ,
300
- .driver_data = (kernel_ulong_t )& atmel_pwm_regs_v2 ,
328
+ .driver_data = (kernel_ulong_t )& atmel_sama5_pwm_data ,
301
329
}, {
302
330
/* sentinel */
303
331
},
@@ -307,20 +335,23 @@ MODULE_DEVICE_TABLE(platform, atmel_pwm_devtypes);
307
335
static const struct of_device_id atmel_pwm_dt_ids [] = {
308
336
{
309
337
.compatible = "atmel,at91sam9rl-pwm" ,
310
- .data = & atmel_pwm_regs_v1 ,
338
+ .data = & atmel_sam9rl_pwm_data ,
311
339
}, {
312
340
.compatible = "atmel,sama5d3-pwm" ,
313
- .data = & atmel_pwm_regs_v2 ,
341
+ .data = & atmel_sama5_pwm_data ,
314
342
}, {
315
343
.compatible = "atmel,sama5d2-pwm" ,
316
- .data = & atmel_pwm_regs_v2 ,
344
+ .data = & atmel_sama5_pwm_data ,
345
+ }, {
346
+ .compatible = "microchip,sam9x60-pwm" ,
347
+ .data = & mchp_sam9x60_pwm_data ,
317
348
}, {
318
349
/* sentinel */
319
350
},
320
351
};
321
352
MODULE_DEVICE_TABLE (of , atmel_pwm_dt_ids );
322
353
323
- static inline const struct atmel_pwm_registers *
354
+ static inline const struct atmel_pwm_data *
324
355
atmel_pwm_get_driver_data (struct platform_device * pdev )
325
356
{
326
357
const struct platform_device_id * id ;
@@ -330,18 +361,18 @@ atmel_pwm_get_driver_data(struct platform_device *pdev)
330
361
331
362
id = platform_get_device_id (pdev );
332
363
333
- return (struct atmel_pwm_registers * )id -> driver_data ;
364
+ return (struct atmel_pwm_data * )id -> driver_data ;
334
365
}
335
366
336
367
static int atmel_pwm_probe (struct platform_device * pdev )
337
368
{
338
- const struct atmel_pwm_registers * regs ;
369
+ const struct atmel_pwm_data * data ;
339
370
struct atmel_pwm_chip * atmel_pwm ;
340
371
struct resource * res ;
341
372
int ret ;
342
373
343
- regs = atmel_pwm_get_driver_data (pdev );
344
- if (!regs )
374
+ data = atmel_pwm_get_driver_data (pdev );
375
+ if (!data )
345
376
return - ENODEV ;
346
377
347
378
atmel_pwm = devm_kzalloc (& pdev -> dev , sizeof (* atmel_pwm ), GFP_KERNEL );
@@ -373,7 +404,7 @@ static int atmel_pwm_probe(struct platform_device *pdev)
373
404
374
405
atmel_pwm -> chip .base = -1 ;
375
406
atmel_pwm -> chip .npwm = 4 ;
376
- atmel_pwm -> regs = regs ;
407
+ atmel_pwm -> data = data ;
377
408
atmel_pwm -> updated_pwms = 0 ;
378
409
mutex_init (& atmel_pwm -> isr_lock );
379
410
0 commit comments