29
29
30
30
////////////////////////////////////////////////////////////////////////////////////////////
31
31
32
- #define DRV_NAME "gpio-sqwave "
33
- #define FILE_NAME "sqwave "
32
+ #define DRV_NAME "gpio-pwm-ar9331 "
33
+ #define FILE_NAME "pwm-ar9331 "
34
34
35
35
////////////////////////////////////////////////////////////////////////////////////////////
36
36
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(timer, "system timer number (0-3)");
48
48
#define debug (fmt ,args ...)
49
49
#endif /* DEBUG_OUT */
50
50
51
- static unsigned int _timer_frequency = 100000000 ;
51
+ static unsigned int _timer_frequency = 200000000 ;
52
52
static spinlock_t _lock ;
53
53
static unsigned int _gpio_prev = 0 ;
54
54
@@ -84,6 +84,8 @@ struct _timer_desc_struct
84
84
#define GPIO_OFFS_SET 0x0C
85
85
#define GPIO_OFFS_CLEAR 0x10
86
86
87
+ #define PWM_MAX 65536
88
+
87
89
////////////////////////////////////////////////////////////////////////////////////////////
88
90
89
91
void __iomem * ath79_timer_base = NULL ;
@@ -97,11 +99,16 @@ void __iomem *gpio_cleardataout_addr=NULL;
97
99
98
100
typedef struct
99
101
{
100
- int timer ;
101
- int irq ;
102
- int gpio ;
102
+ int timer ;
103
+ int irq ;
104
+ int gpio ;
103
105
unsigned int frequency ;
104
- int value ;
106
+ unsigned int timeout_total ;
107
+ unsigned int timeout_front ;
108
+ unsigned int timeout_back ;
109
+ unsigned int new_pos ;
110
+ int update ;
111
+ int value ;
105
112
} _timer_handler ;
106
113
107
114
static _timer_handler _handler ;
@@ -110,6 +117,41 @@ static struct dentry* in_file;
110
117
111
118
////////////////////////////////////////////////////////////////////////////////////////////
112
119
120
+ inline void set_timer_reload (int timer , unsigned int freq )
121
+ {
122
+ __raw_writel (freq , ath79_timer_base + _timers [timer ].reload_reg );
123
+ }
124
+
125
+ ////////////////////////////////////////////////////////////////////////////////////////////
126
+
127
+ inline void set_gpio_value (int gpio , int val )
128
+ {
129
+ if (val )
130
+ {
131
+ __raw_writel (1 << gpio , gpio_setdataout_addr );
132
+ }
133
+ else
134
+ {
135
+ __raw_writel (1 << gpio , gpio_cleardataout_addr );
136
+ }
137
+ }
138
+
139
+ ////////////////////////////////////////////////////////////////////////////////////////////
140
+
141
+ void recalculate_timeouts (_timer_handler * handler ){
142
+ unsigned int flags = 0 ;
143
+ spin_lock_irqsave (& _lock ,flags );
144
+ handler -> timeout_total = _timer_frequency /handler -> frequency ;
145
+ debug ("New timeout: %u\n" ,handler -> timeout_total );
146
+ handler -> timeout_front = (unsigned int )(((unsigned long long )handler -> timeout_total * (unsigned long long )handler -> new_pos ) / PWM_MAX );
147
+ debug ("New front timeout: %u\n" ,handler -> timeout_front );
148
+ handler -> timeout_back = handler -> timeout_total - handler -> timeout_front ;
149
+ debug ("New back timeout: %u\n" ,handler -> timeout_back );
150
+ spin_unlock_irqrestore (& _lock ,flags );
151
+ }
152
+
153
+ ////////////////////////////////////////////////////////////////////////////////////////////
154
+
113
155
static int is_space (char symbol )
114
156
{
115
157
return (symbol == ' ' ) || (symbol == '\t' );
@@ -130,15 +172,21 @@ static irqreturn_t timer_interrupt(int irq, void* dev_id)
130
172
131
173
if (handler && (handler -> irq == irq ) && (handler -> gpio >= 0 ))
132
174
{
175
+ if (handler -> update == 1 )
176
+ {
177
+ handler -> update = 0 ;
178
+ recalculate_timeouts (handler );
179
+ }
133
180
if (handler -> value )
134
181
{
135
182
__raw_writel (1 << handler -> gpio , gpio_setdataout_addr );
183
+ set_timer_reload (handler -> timer , handler -> timeout_back );
136
184
}
137
185
else
138
186
{
139
187
__raw_writel (1 << handler -> gpio , gpio_cleardataout_addr );
188
+ set_timer_reload (handler -> timer , handler -> timeout_front );
140
189
}
141
-
142
190
handler -> value = !handler -> value ;
143
191
}
144
192
@@ -186,16 +234,7 @@ static void stop(void)
186
234
187
235
if (_handler .gpio >= 0 )
188
236
{
189
- // restore previous GPIO state
190
- if (_gpio_prev )
191
- {
192
- __raw_writel (1 << _handler .gpio ,gpio_setdataout_addr );
193
- }
194
- else
195
- {
196
- __raw_writel (1 << _handler .gpio ,gpio_cleardataout_addr );
197
- }
198
-
237
+ set_gpio_value (_handler .gpio , _gpio_prev );
199
238
gpio_free (_handler .gpio );
200
239
_handler .gpio = -1 ;
201
240
}
@@ -211,17 +250,16 @@ static void stop(void)
211
250
212
251
////////////////////////////////////////////////////////////////////////////////////////////
213
252
214
- static int start (int gpio ,unsigned int frequency )
253
+ static int start (int gpio ,unsigned int frequency , unsigned int pos )
215
254
{
216
- unsigned int timeout = 0 ;
217
255
int irq = -1 ;
218
256
unsigned long flags = 0 ;
219
257
220
258
stop ();
221
259
222
260
spin_lock_irqsave (& _lock ,flags );
223
261
// need some time (10 ms) before first IRQ - even after "lock"?!
224
- __raw_writel ( _timer_frequency /100 , ath79_timer_base + _timers [ timer ]. reload_reg );
262
+ set_timer_reload ( timer , _timer_frequency /100 );
225
263
226
264
irq = add_irq (& _handler );
227
265
@@ -238,10 +276,11 @@ static int start(int gpio,unsigned int frequency)
238
276
// save current GPIO state
239
277
_gpio_prev = __raw_readl (gpio_readdata_addr + GPIO_OFFS_READ ) & (1 << gpio );
240
278
241
- timeout = _timer_frequency /frequency /2 ;
242
- __raw_writel (timeout , ath79_timer_base + _timers [timer ].reload_reg );
243
279
244
- _handler .frequency = frequency ;
280
+ _handler .frequency = frequency ;
281
+ _handler .new_pos = pos ;
282
+ recalculate_timeouts (& _handler );
283
+ set_timer_reload (timer , _handler .timeout_front );
245
284
246
285
debug ("New frequency: %u.\n" , frequency );
247
286
@@ -270,6 +309,7 @@ static ssize_t run_command(struct file *file, const char __user *buf,
270
309
char * in_pos = NULL ;
271
310
char * end = NULL ;
272
311
char * out_pos = NULL ;
312
+ unsigned int flags = 0 ;
273
313
274
314
if (count > 512 )
275
315
return - EINVAL ; // file is too big
@@ -286,6 +326,7 @@ static ssize_t run_command(struct file *file, const char __user *buf,
286
326
{
287
327
unsigned int gpio = -1 ;
288
328
unsigned int frequency = 0 ;
329
+ unsigned int pos = 0 ;
289
330
290
331
while ((in_pos < end ) && is_space (* in_pos )) ++ in_pos ; // skip whitespace
291
332
if (in_pos >= end ) break ;
@@ -295,7 +336,7 @@ static ssize_t run_command(struct file *file, const char __user *buf,
295
336
stop ();
296
337
return count ;
297
338
}
298
- else if (* in_pos == '?' )
339
+ if (* in_pos == '?' )
299
340
{
300
341
if (_handler .frequency )
301
342
{
@@ -309,46 +350,66 @@ static ssize_t run_command(struct file *file, const char __user *buf,
309
350
310
351
break ;
311
352
}
353
+ if (* in_pos == '+' ){
354
+ ++ in_pos ;
355
+ while ((in_pos < end ) && is_space (* in_pos )) ++ in_pos ; // skip whitespace
356
+ if (in_pos >= end ) break ;
312
357
313
- out_pos = line ;
314
- while ((in_pos < end ) && is_digit (* in_pos )) * out_pos ++ = * in_pos ++ ;
315
- * out_pos = 0 ;
316
-
317
- if (is_digit (line [0 ]))
318
- {
319
- sscanf (line , "%d" , & gpio );
320
- }
321
- else
322
- {
323
- printk (KERN_INFO DRV_NAME " can't read GPIO number.\n" );
324
- break ;
325
- }
326
-
327
- while ((in_pos < end ) && is_space (* in_pos )) ++ in_pos ; // skip whitespace
358
+ out_pos = line ;
359
+ while ((in_pos < end ) && is_digit (* in_pos )) * out_pos ++ = * in_pos ++ ;
360
+ * out_pos = 0 ;
328
361
329
- out_pos = line ;
330
- while ((in_pos < end ) && is_digit (* in_pos )) * out_pos ++ = * in_pos ++ ;
331
- * out_pos = 0 ;
362
+ if (is_digit (line [0 ]))
363
+ {
364
+ sscanf (line , "%d" , & gpio );
365
+ }
366
+ else
367
+ {
368
+ printk (KERN_INFO DRV_NAME " can't read GPIO number.\n" );
369
+ break ;
370
+ }
371
+
372
+ while ((in_pos < end ) && is_space (* in_pos )) ++ in_pos ; // skip whitespace
373
+
374
+ out_pos = line ;
375
+ while ((in_pos < end ) && is_digit (* in_pos )) * out_pos ++ = * in_pos ++ ;
376
+ * out_pos = 0 ;
377
+
378
+ if (is_digit (line [0 ]))
379
+ {
380
+ sscanf (line , "%u" , & frequency );
381
+ }
382
+ else
383
+ {
384
+ printk (KERN_INFO DRV_NAME " can't read frequency.\n" );
385
+ break ;
386
+ }
387
+
388
+ while ((in_pos < end ) && is_space (* in_pos )) ++ in_pos ; // skip whitespace
332
389
333
- if (is_digit (line [0 ]))
334
- {
335
- sscanf (line , "%u" , & frequency );
336
- }
337
- else
338
- {
339
- printk (KERN_INFO DRV_NAME " can't read frequency.\n" );
340
- break ;
341
- }
390
+ out_pos = line ;
391
+ while ((in_pos < end ) && is_digit (* in_pos )) * out_pos ++ = * in_pos ++ ;
392
+ * out_pos = 0 ;
342
393
343
- if ((gpio >= 0 ) && (frequency > 0 ))
344
- {
345
- if (start (gpio ,frequency ) >= 0 )
394
+ if (is_digit (line [0 ]))
395
+ {
396
+ sscanf (line , "%u" , & pos );
397
+ }
398
+ else
346
399
{
347
- debug ( "Started! \n" );
400
+ printk ( KERN_INFO DRV_NAME " can't read pos. \n" );
348
401
break ;
349
402
}
350
- }
351
403
404
+ if ((gpio >= 0 ) && (frequency > 0 ))
405
+ {
406
+ if (start (gpio ,frequency ,pos ) >= 0 )
407
+ {
408
+ debug ("Started!\n" );
409
+ break ;
410
+ }
411
+ }
412
+ }
352
413
printk (KERN_INFO DRV_NAME " can't start.\n" );
353
414
return 0 ;
354
415
}
@@ -380,13 +441,13 @@ static int __init mymodule_init(void)
380
441
_timer_frequency = ahb_clk -> rate ;
381
442
}
382
443
383
- ath79_timer_base = ioremap_nocache (AR71XX_RESET_BASE , AR71XX_RESET_SIZE );
444
+ ath79_timer_base = ioremap_nocache (AR71XX_RESET_BASE , AR71XX_RESET_SIZE );
384
445
385
- gpio_addr = ioremap_nocache (AR71XX_GPIO_BASE , AR71XX_GPIO_SIZE );
446
+ gpio_addr = ioremap_nocache (AR71XX_GPIO_BASE , AR71XX_GPIO_SIZE );
386
447
387
- gpio_readdata_addr = gpio_addr + GPIO_OFFS_READ ;
388
- gpio_setdataout_addr = gpio_addr + GPIO_OFFS_SET ;
389
- gpio_cleardataout_addr = gpio_addr + GPIO_OFFS_CLEAR ;
448
+ gpio_readdata_addr = gpio_addr + GPIO_OFFS_READ ;
449
+ gpio_setdataout_addr = gpio_addr + GPIO_OFFS_SET ;
450
+ gpio_cleardataout_addr = gpio_addr + GPIO_OFFS_CLEAR ;
390
451
391
452
_handler .timer = -1 ;
392
453
_handler .irq = -1 ;
0 commit comments