Merge branch 'next-i2c' of git://aeryn.fluff.org.uk/bjdooks/linux
[linux-2.6] / drivers / char / tlclk.c
1 /*
2  * Telecom Clock driver for Intel NetStructure(tm) MPCBL0010
3  *
4  * Copyright (C) 2005 Kontron Canada
5  *
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16  * NON INFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * Send feedback to <sebastien.bouchard@ca.kontron.com> and the current
24  * Maintainer  <mark.gross@intel.com>
25  *
26  * Description : This is the TELECOM CLOCK module driver for the ATCA
27  * MPCBL0010 ATCA computer.
28  */
29
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/kernel.h>       /* printk() */
33 #include <linux/fs.h>           /* everything... */
34 #include <linux/errno.h>        /* error codes */
35 #include <linux/slab.h>
36 #include <linux/ioport.h>
37 #include <linux/interrupt.h>
38 #include <linux/spinlock.h>
39 #include <linux/smp_lock.h>
40 #include <linux/timer.h>
41 #include <linux/sysfs.h>
42 #include <linux/device.h>
43 #include <linux/miscdevice.h>
44 #include <linux/platform_device.h>
45 #include <asm/io.h>             /* inb/outb */
46 #include <asm/uaccess.h>
47
48 MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
49 MODULE_LICENSE("GPL");
50
51 /*Hardware Reset of the PLL */
52 #define RESET_ON        0x00
53 #define RESET_OFF       0x01
54
55 /* MODE SELECT */
56 #define NORMAL_MODE     0x00
57 #define HOLDOVER_MODE   0x10
58 #define FREERUN_MODE    0x20
59
60 /* FILTER SELECT */
61 #define FILTER_6HZ      0x04
62 #define FILTER_12HZ     0x00
63
64 /* SELECT REFERENCE FREQUENCY */
65 #define REF_CLK1_8kHz           0x00
66 #define REF_CLK2_19_44MHz       0x02
67
68 /* Select primary or secondary redundant clock */
69 #define PRIMARY_CLOCK   0x00
70 #define SECONDARY_CLOCK 0x01
71
72 /* CLOCK TRANSMISSION DEFINE */
73 #define CLK_8kHz        0xff
74 #define CLK_16_384MHz   0xfb
75
76 #define CLK_1_544MHz    0x00
77 #define CLK_2_048MHz    0x01
78 #define CLK_4_096MHz    0x02
79 #define CLK_6_312MHz    0x03
80 #define CLK_8_192MHz    0x04
81 #define CLK_19_440MHz   0x06
82
83 #define CLK_8_592MHz    0x08
84 #define CLK_11_184MHz   0x09
85 #define CLK_34_368MHz   0x0b
86 #define CLK_44_736MHz   0x0a
87
88 /* RECEIVED REFERENCE */
89 #define AMC_B1 0
90 #define AMC_B2 1
91
92 /* HARDWARE SWITCHING DEFINE */
93 #define HW_ENABLE       0x80
94 #define HW_DISABLE      0x00
95
96 /* HARDWARE SWITCHING MODE DEFINE */
97 #define PLL_HOLDOVER    0x40
98 #define LOST_CLOCK      0x00
99
100 /* ALARMS DEFINE */
101 #define UNLOCK_MASK     0x10
102 #define HOLDOVER_MASK   0x20
103 #define SEC_LOST_MASK   0x40
104 #define PRI_LOST_MASK   0x80
105
106 /* INTERRUPT CAUSE DEFINE */
107
108 #define PRI_LOS_01_MASK         0x01
109 #define PRI_LOS_10_MASK         0x02
110
111 #define SEC_LOS_01_MASK         0x04
112 #define SEC_LOS_10_MASK         0x08
113
114 #define HOLDOVER_01_MASK        0x10
115 #define HOLDOVER_10_MASK        0x20
116
117 #define UNLOCK_01_MASK          0x40
118 #define UNLOCK_10_MASK          0x80
119
120 struct tlclk_alarms {
121         __u32 lost_clocks;
122         __u32 lost_primary_clock;
123         __u32 lost_secondary_clock;
124         __u32 primary_clock_back;
125         __u32 secondary_clock_back;
126         __u32 switchover_primary;
127         __u32 switchover_secondary;
128         __u32 pll_holdover;
129         __u32 pll_end_holdover;
130         __u32 pll_lost_sync;
131         __u32 pll_sync;
132 };
133 /* Telecom clock I/O register definition */
134 #define TLCLK_BASE 0xa08
135 #define TLCLK_REG0 TLCLK_BASE
136 #define TLCLK_REG1 (TLCLK_BASE+1)
137 #define TLCLK_REG2 (TLCLK_BASE+2)
138 #define TLCLK_REG3 (TLCLK_BASE+3)
139 #define TLCLK_REG4 (TLCLK_BASE+4)
140 #define TLCLK_REG5 (TLCLK_BASE+5)
141 #define TLCLK_REG6 (TLCLK_BASE+6)
142 #define TLCLK_REG7 (TLCLK_BASE+7)
143
144 #define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
145
146 /* 0 = Dynamic allocation of the major device number */
147 #define TLCLK_MAJOR 0
148
149 /* sysfs interface definition:
150 Upon loading the driver will create a sysfs directory under
151 /sys/devices/platform/telco_clock.
152
153 This directory exports the following interfaces.  There operation is
154 documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
155 alarms                          :
156 current_ref                     :
157 received_ref_clk3a              :
158 received_ref_clk3b              :
159 enable_clk3a_output             :
160 enable_clk3b_output             :
161 enable_clka0_output             :
162 enable_clka1_output             :
163 enable_clkb0_output             :
164 enable_clkb1_output             :
165 filter_select                   :
166 hardware_switching              :
167 hardware_switching_mode         :
168 telclock_version                :
169 mode_select                     :
170 refalign                        :
171 reset                           :
172 select_amcb1_transmit_clock     :
173 select_amcb2_transmit_clock     :
174 select_redundant_clock          :
175 select_ref_frequency            :
176
177 All sysfs interfaces are integers in hex format, i.e echo 99 > refalign
178 has the same effect as echo 0x99 > refalign.
179 */
180
181 static unsigned int telclk_interrupt;
182
183 static int int_events;          /* Event that generate a interrupt */
184 static int got_event;           /* if events processing have been done */
185
186 static void switchover_timeout(unsigned long data);
187 static struct timer_list switchover_timer =
188         TIMER_INITIALIZER(switchover_timeout , 0, 0);
189 static unsigned long tlclk_timer_data;
190
191 static struct tlclk_alarms *alarm_events;
192
193 static DEFINE_SPINLOCK(event_lock);
194
195 static int tlclk_major = TLCLK_MAJOR;
196
197 static irqreturn_t tlclk_interrupt(int irq, void *dev_id);
198
199 static DECLARE_WAIT_QUEUE_HEAD(wq);
200
201 static unsigned long useflags;
202 static DEFINE_MUTEX(tlclk_mutex);
203
204 static int tlclk_open(struct inode *inode, struct file *filp)
205 {
206         int result;
207
208         lock_kernel();
209         if (test_and_set_bit(0, &useflags)) {
210                 result = -EBUSY;
211                 /* this legacy device is always one per system and it doesn't
212                  * know how to handle multiple concurrent clients.
213                  */
214                 goto out;
215         }
216
217         /* Make sure there is no interrupt pending while
218          * initialising interrupt handler */
219         inb(TLCLK_REG6);
220
221         /* This device is wired through the FPGA IO space of the ATCA blade
222          * we can't share this IRQ */
223         result = request_irq(telclk_interrupt, &tlclk_interrupt,
224                              IRQF_DISABLED, "telco_clock", tlclk_interrupt);
225         if (result == -EBUSY)
226                 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
227         else
228                 inb(TLCLK_REG6);        /* Clear interrupt events */
229
230 out:
231         unlock_kernel();
232         return result;
233 }
234
235 static int tlclk_release(struct inode *inode, struct file *filp)
236 {
237         free_irq(telclk_interrupt, tlclk_interrupt);
238         clear_bit(0, &useflags);
239
240         return 0;
241 }
242
243 static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
244                 loff_t *f_pos)
245 {
246         if (count < sizeof(struct tlclk_alarms))
247                 return -EIO;
248         if (mutex_lock_interruptible(&tlclk_mutex))
249                 return -EINTR;
250
251
252         wait_event_interruptible(wq, got_event);
253         if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) {
254                 mutex_unlock(&tlclk_mutex);
255                 return -EFAULT;
256         }
257
258         memset(alarm_events, 0, sizeof(struct tlclk_alarms));
259         got_event = 0;
260
261         mutex_unlock(&tlclk_mutex);
262         return  sizeof(struct tlclk_alarms);
263 }
264
265 static const struct file_operations tlclk_fops = {
266         .read = tlclk_read,
267         .open = tlclk_open,
268         .release = tlclk_release,
269
270 };
271
272 static struct miscdevice tlclk_miscdev = {
273         .minor = MISC_DYNAMIC_MINOR,
274         .name = "telco_clock",
275         .fops = &tlclk_fops,
276 };
277
278 static ssize_t show_current_ref(struct device *d,
279                 struct device_attribute *attr, char *buf)
280 {
281         unsigned long ret_val;
282         unsigned long flags;
283
284         spin_lock_irqsave(&event_lock, flags);
285         ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
286         spin_unlock_irqrestore(&event_lock, flags);
287
288         return sprintf(buf, "0x%lX\n", ret_val);
289 }
290
291 static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
292
293
294 static ssize_t show_telclock_version(struct device *d,
295                 struct device_attribute *attr, char *buf)
296 {
297         unsigned long ret_val;
298         unsigned long flags;
299
300         spin_lock_irqsave(&event_lock, flags);
301         ret_val = inb(TLCLK_REG5);
302         spin_unlock_irqrestore(&event_lock, flags);
303
304         return sprintf(buf, "0x%lX\n", ret_val);
305 }
306
307 static DEVICE_ATTR(telclock_version, S_IRUGO,
308                 show_telclock_version, NULL);
309
310 static ssize_t show_alarms(struct device *d,
311                 struct device_attribute *attr,  char *buf)
312 {
313         unsigned long ret_val;
314         unsigned long flags;
315
316         spin_lock_irqsave(&event_lock, flags);
317         ret_val = (inb(TLCLK_REG2) & 0xf0);
318         spin_unlock_irqrestore(&event_lock, flags);
319
320         return sprintf(buf, "0x%lX\n", ret_val);
321 }
322
323 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
324
325 static ssize_t store_received_ref_clk3a(struct device *d,
326                  struct device_attribute *attr, const char *buf, size_t count)
327 {
328         unsigned long tmp;
329         unsigned char val;
330         unsigned long flags;
331
332         sscanf(buf, "%lX", &tmp);
333         dev_dbg(d, ": tmp = 0x%lX\n", tmp);
334
335         val = (unsigned char)tmp;
336         spin_lock_irqsave(&event_lock, flags);
337         SET_PORT_BITS(TLCLK_REG1, 0xef, val);
338         spin_unlock_irqrestore(&event_lock, flags);
339
340         return strnlen(buf, count);
341 }
342
343 static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL,
344                 store_received_ref_clk3a);
345
346
347 static ssize_t store_received_ref_clk3b(struct device *d,
348                  struct device_attribute *attr, const char *buf, size_t count)
349 {
350         unsigned long tmp;
351         unsigned char val;
352         unsigned long flags;
353
354         sscanf(buf, "%lX", &tmp);
355         dev_dbg(d, ": tmp = 0x%lX\n", tmp);
356
357         val = (unsigned char)tmp;
358         spin_lock_irqsave(&event_lock, flags);
359         SET_PORT_BITS(TLCLK_REG1, 0xdf, val << 1);
360         spin_unlock_irqrestore(&event_lock, flags);
361
362         return strnlen(buf, count);
363 }
364
365 static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL,
366                 store_received_ref_clk3b);
367
368
369 static ssize_t store_enable_clk3b_output(struct device *d,
370                  struct device_attribute *attr, const char *buf, size_t count)
371 {
372         unsigned long tmp;
373         unsigned char val;
374         unsigned long flags;
375
376         sscanf(buf, "%lX", &tmp);
377         dev_dbg(d, ": tmp = 0x%lX\n", tmp);
378
379         val = (unsigned char)tmp;
380         spin_lock_irqsave(&event_lock, flags);
381         SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
382         spin_unlock_irqrestore(&event_lock, flags);
383
384         return strnlen(buf, count);
385 }
386
387 static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL,
388                 store_enable_clk3b_output);
389
390 static ssize_t store_enable_clk3a_output(struct device *d,
391                  struct device_attribute *attr, const char *buf, size_t count)
392 {
393         unsigned long flags;
394         unsigned long tmp;
395         unsigned char val;
396
397         sscanf(buf, "%lX", &tmp);
398         dev_dbg(d, "tmp = 0x%lX\n", tmp);
399
400         val = (unsigned char)tmp;
401         spin_lock_irqsave(&event_lock, flags);
402         SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
403         spin_unlock_irqrestore(&event_lock, flags);
404
405         return strnlen(buf, count);
406 }
407
408 static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL,
409                 store_enable_clk3a_output);
410
411 static ssize_t store_enable_clkb1_output(struct device *d,
412                  struct device_attribute *attr, const char *buf, size_t count)
413 {
414         unsigned long flags;
415         unsigned long tmp;
416         unsigned char val;
417
418         sscanf(buf, "%lX", &tmp);
419         dev_dbg(d, "tmp = 0x%lX\n", tmp);
420
421         val = (unsigned char)tmp;
422         spin_lock_irqsave(&event_lock, flags);
423         SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
424         spin_unlock_irqrestore(&event_lock, flags);
425
426         return strnlen(buf, count);
427 }
428
429 static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL,
430                 store_enable_clkb1_output);
431
432
433 static ssize_t store_enable_clka1_output(struct device *d,
434                  struct device_attribute *attr, const char *buf, size_t count)
435 {
436         unsigned long flags;
437         unsigned long tmp;
438         unsigned char val;
439
440         sscanf(buf, "%lX", &tmp);
441         dev_dbg(d, "tmp = 0x%lX\n", tmp);
442
443         val = (unsigned char)tmp;
444         spin_lock_irqsave(&event_lock, flags);
445         SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
446         spin_unlock_irqrestore(&event_lock, flags);
447
448         return strnlen(buf, count);
449 }
450
451 static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL,
452                 store_enable_clka1_output);
453
454 static ssize_t store_enable_clkb0_output(struct device *d,
455                  struct device_attribute *attr, const char *buf, size_t count)
456 {
457         unsigned long flags;
458         unsigned long tmp;
459         unsigned char val;
460
461         sscanf(buf, "%lX", &tmp);
462         dev_dbg(d, "tmp = 0x%lX\n", tmp);
463
464         val = (unsigned char)tmp;
465         spin_lock_irqsave(&event_lock, flags);
466         SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
467         spin_unlock_irqrestore(&event_lock, flags);
468
469         return strnlen(buf, count);
470 }
471
472 static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL,
473                 store_enable_clkb0_output);
474
475 static ssize_t store_enable_clka0_output(struct device *d,
476                  struct device_attribute *attr, const char *buf, size_t count)
477 {
478         unsigned long flags;
479         unsigned long tmp;
480         unsigned char val;
481
482         sscanf(buf, "%lX", &tmp);
483         dev_dbg(d, "tmp = 0x%lX\n", tmp);
484
485         val = (unsigned char)tmp;
486         spin_lock_irqsave(&event_lock, flags);
487         SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
488         spin_unlock_irqrestore(&event_lock, flags);
489
490         return strnlen(buf, count);
491 }
492
493 static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL,
494                 store_enable_clka0_output);
495
496 static ssize_t store_select_amcb2_transmit_clock(struct device *d,
497                 struct device_attribute *attr, const char *buf, size_t count)
498 {
499         unsigned long flags;
500         unsigned long tmp;
501         unsigned char val;
502
503         sscanf(buf, "%lX", &tmp);
504         dev_dbg(d, "tmp = 0x%lX\n", tmp);
505
506         val = (unsigned char)tmp;
507         spin_lock_irqsave(&event_lock, flags);
508                 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
509                         SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
510                         SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
511                 } else if (val >= CLK_8_592MHz) {
512                         SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
513                         switch (val) {
514                         case CLK_8_592MHz:
515                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
516                                 break;
517                         case CLK_11_184MHz:
518                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
519                                 break;
520                         case CLK_34_368MHz:
521                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
522                                 break;
523                         case CLK_44_736MHz:
524                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
525                                 break;
526                         }
527                 } else
528                         SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
529
530         spin_unlock_irqrestore(&event_lock, flags);
531
532         return strnlen(buf, count);
533 }
534
535 static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
536         store_select_amcb2_transmit_clock);
537
538 static ssize_t store_select_amcb1_transmit_clock(struct device *d,
539                  struct device_attribute *attr, const char *buf, size_t count)
540 {
541         unsigned long tmp;
542         unsigned char val;
543         unsigned long flags;
544
545         sscanf(buf, "%lX", &tmp);
546         dev_dbg(d, "tmp = 0x%lX\n", tmp);
547
548         val = (unsigned char)tmp;
549         spin_lock_irqsave(&event_lock, flags);
550                 if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
551                         SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
552                         SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
553                 } else if (val >= CLK_8_592MHz) {
554                         SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
555                         switch (val) {
556                         case CLK_8_592MHz:
557                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
558                                 break;
559                         case CLK_11_184MHz:
560                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
561                                 break;
562                         case CLK_34_368MHz:
563                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
564                                 break;
565                         case CLK_44_736MHz:
566                                 SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
567                                 break;
568                         }
569                 } else
570                         SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
571         spin_unlock_irqrestore(&event_lock, flags);
572
573         return strnlen(buf, count);
574 }
575
576 static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL,
577                 store_select_amcb1_transmit_clock);
578
579 static ssize_t store_select_redundant_clock(struct device *d,
580                  struct device_attribute *attr, const char *buf, size_t count)
581 {
582         unsigned long tmp;
583         unsigned char val;
584         unsigned long flags;
585
586         sscanf(buf, "%lX", &tmp);
587         dev_dbg(d, "tmp = 0x%lX\n", tmp);
588
589         val = (unsigned char)tmp;
590         spin_lock_irqsave(&event_lock, flags);
591         SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
592         spin_unlock_irqrestore(&event_lock, flags);
593
594         return strnlen(buf, count);
595 }
596
597 static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL,
598                 store_select_redundant_clock);
599
600 static ssize_t store_select_ref_frequency(struct device *d,
601                  struct device_attribute *attr, const char *buf, size_t count)
602 {
603         unsigned long tmp;
604         unsigned char val;
605         unsigned long flags;
606
607         sscanf(buf, "%lX", &tmp);
608         dev_dbg(d, "tmp = 0x%lX\n", tmp);
609
610         val = (unsigned char)tmp;
611         spin_lock_irqsave(&event_lock, flags);
612         SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
613         spin_unlock_irqrestore(&event_lock, flags);
614
615         return strnlen(buf, count);
616 }
617
618 static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL,
619                 store_select_ref_frequency);
620
621 static ssize_t store_filter_select(struct device *d,
622                  struct device_attribute *attr, const char *buf, size_t count)
623 {
624         unsigned long tmp;
625         unsigned char val;
626         unsigned long flags;
627
628         sscanf(buf, "%lX", &tmp);
629         dev_dbg(d, "tmp = 0x%lX\n", tmp);
630
631         val = (unsigned char)tmp;
632         spin_lock_irqsave(&event_lock, flags);
633         SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
634         spin_unlock_irqrestore(&event_lock, flags);
635
636         return strnlen(buf, count);
637 }
638
639 static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select);
640
641 static ssize_t store_hardware_switching_mode(struct device *d,
642                  struct device_attribute *attr, const char *buf, size_t count)
643 {
644         unsigned long tmp;
645         unsigned char val;
646         unsigned long flags;
647
648         sscanf(buf, "%lX", &tmp);
649         dev_dbg(d, "tmp = 0x%lX\n", tmp);
650
651         val = (unsigned char)tmp;
652         spin_lock_irqsave(&event_lock, flags);
653         SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
654         spin_unlock_irqrestore(&event_lock, flags);
655
656         return strnlen(buf, count);
657 }
658
659 static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL,
660                 store_hardware_switching_mode);
661
662 static ssize_t store_hardware_switching(struct device *d,
663                  struct device_attribute *attr, const char *buf, size_t count)
664 {
665         unsigned long tmp;
666         unsigned char val;
667         unsigned long flags;
668
669         sscanf(buf, "%lX", &tmp);
670         dev_dbg(d, "tmp = 0x%lX\n", tmp);
671
672         val = (unsigned char)tmp;
673         spin_lock_irqsave(&event_lock, flags);
674         SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
675         spin_unlock_irqrestore(&event_lock, flags);
676
677         return strnlen(buf, count);
678 }
679
680 static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL,
681                 store_hardware_switching);
682
683 static ssize_t store_refalign (struct device *d,
684                  struct device_attribute *attr, const char *buf, size_t count)
685 {
686         unsigned long tmp;
687         unsigned long flags;
688
689         sscanf(buf, "%lX", &tmp);
690         dev_dbg(d, "tmp = 0x%lX\n", tmp);
691         spin_lock_irqsave(&event_lock, flags);
692         SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
693         SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
694         SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
695         spin_unlock_irqrestore(&event_lock, flags);
696
697         return strnlen(buf, count);
698 }
699
700 static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign);
701
702 static ssize_t store_mode_select (struct device *d,
703                  struct device_attribute *attr, const char *buf, size_t count)
704 {
705         unsigned long tmp;
706         unsigned char val;
707         unsigned long flags;
708
709         sscanf(buf, "%lX", &tmp);
710         dev_dbg(d, "tmp = 0x%lX\n", tmp);
711
712         val = (unsigned char)tmp;
713         spin_lock_irqsave(&event_lock, flags);
714         SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
715         spin_unlock_irqrestore(&event_lock, flags);
716
717         return strnlen(buf, count);
718 }
719
720 static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select);
721
722 static ssize_t store_reset (struct device *d,
723                  struct device_attribute *attr, const char *buf, size_t count)
724 {
725         unsigned long tmp;
726         unsigned char val;
727         unsigned long flags;
728
729         sscanf(buf, "%lX", &tmp);
730         dev_dbg(d, "tmp = 0x%lX\n", tmp);
731
732         val = (unsigned char)tmp;
733         spin_lock_irqsave(&event_lock, flags);
734         SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
735         spin_unlock_irqrestore(&event_lock, flags);
736
737         return strnlen(buf, count);
738 }
739
740 static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset);
741
742 static struct attribute *tlclk_sysfs_entries[] = {
743         &dev_attr_current_ref.attr,
744         &dev_attr_telclock_version.attr,
745         &dev_attr_alarms.attr,
746         &dev_attr_received_ref_clk3a.attr,
747         &dev_attr_received_ref_clk3b.attr,
748         &dev_attr_enable_clk3a_output.attr,
749         &dev_attr_enable_clk3b_output.attr,
750         &dev_attr_enable_clkb1_output.attr,
751         &dev_attr_enable_clka1_output.attr,
752         &dev_attr_enable_clkb0_output.attr,
753         &dev_attr_enable_clka0_output.attr,
754         &dev_attr_select_amcb1_transmit_clock.attr,
755         &dev_attr_select_amcb2_transmit_clock.attr,
756         &dev_attr_select_redundant_clock.attr,
757         &dev_attr_select_ref_frequency.attr,
758         &dev_attr_filter_select.attr,
759         &dev_attr_hardware_switching_mode.attr,
760         &dev_attr_hardware_switching.attr,
761         &dev_attr_refalign.attr,
762         &dev_attr_mode_select.attr,
763         &dev_attr_reset.attr,
764         NULL
765 };
766
767 static struct attribute_group tlclk_attribute_group = {
768         .name = NULL,           /* put in device directory */
769         .attrs = tlclk_sysfs_entries,
770 };
771
772 static struct platform_device *tlclk_device;
773
774 static int __init tlclk_init(void)
775 {
776         int ret;
777
778         ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
779         if (ret < 0) {
780                 printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major);
781                 return ret;
782         }
783         tlclk_major = ret;
784         alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
785         if (!alarm_events)
786                 goto out1;
787
788         /* Read telecom clock IRQ number (Set by BIOS) */
789         if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
790                 printk(KERN_ERR "tlclk: request_region 0x%X failed.\n",
791                         TLCLK_BASE);
792                 ret = -EBUSY;
793                 goto out2;
794         }
795         telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
796
797         if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
798                 printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n",
799                         telclk_interrupt);
800                 ret = -ENXIO;
801                 goto out3;
802         }
803
804         init_timer(&switchover_timer);
805
806         ret = misc_register(&tlclk_miscdev);
807         if (ret < 0) {
808                 printk(KERN_ERR "tlclk: misc_register returns %d.\n", ret);
809                 goto out3;
810         }
811
812         tlclk_device = platform_device_register_simple("telco_clock",
813                                 -1, NULL, 0);
814         if (IS_ERR(tlclk_device)) {
815                 printk(KERN_ERR "tlclk: platform_device_register failed.\n");
816                 ret = PTR_ERR(tlclk_device);
817                 goto out4;
818         }
819
820         ret = sysfs_create_group(&tlclk_device->dev.kobj,
821                         &tlclk_attribute_group);
822         if (ret) {
823                 printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n");
824                 goto out5;
825         }
826
827         return 0;
828 out5:
829         platform_device_unregister(tlclk_device);
830 out4:
831         misc_deregister(&tlclk_miscdev);
832 out3:
833         release_region(TLCLK_BASE, 8);
834 out2:
835         kfree(alarm_events);
836 out1:
837         unregister_chrdev(tlclk_major, "telco_clock");
838         return ret;
839 }
840
841 static void __exit tlclk_cleanup(void)
842 {
843         sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
844         platform_device_unregister(tlclk_device);
845         misc_deregister(&tlclk_miscdev);
846         unregister_chrdev(tlclk_major, "telco_clock");
847
848         release_region(TLCLK_BASE, 8);
849         del_timer_sync(&switchover_timer);
850         kfree(alarm_events);
851
852 }
853
854 static void switchover_timeout(unsigned long data)
855 {
856         unsigned long flags = *(unsigned long *) data;
857
858         if ((flags & 1)) {
859                 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
860                         alarm_events->switchover_primary++;
861         } else {
862                 if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
863                         alarm_events->switchover_secondary++;
864         }
865
866         /* Alarm processing is done, wake up read task */
867         del_timer(&switchover_timer);
868         got_event = 1;
869         wake_up(&wq);
870 }
871
872 static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
873 {
874         unsigned long flags;
875
876         spin_lock_irqsave(&event_lock, flags);
877         /* Read and clear interrupt events */
878         int_events = inb(TLCLK_REG6);
879
880         /* Primary_Los changed from 0 to 1 ? */
881         if (int_events & PRI_LOS_01_MASK) {
882                 if (inb(TLCLK_REG2) & SEC_LOST_MASK)
883                         alarm_events->lost_clocks++;
884                 else
885                         alarm_events->lost_primary_clock++;
886         }
887
888         /* Primary_Los changed from 1 to 0 ? */
889         if (int_events & PRI_LOS_10_MASK) {
890                 alarm_events->primary_clock_back++;
891                 SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
892         }
893         /* Secondary_Los changed from 0 to 1 ? */
894         if (int_events & SEC_LOS_01_MASK) {
895                 if (inb(TLCLK_REG2) & PRI_LOST_MASK)
896                         alarm_events->lost_clocks++;
897                 else
898                         alarm_events->lost_secondary_clock++;
899         }
900         /* Secondary_Los changed from 1 to 0 ? */
901         if (int_events & SEC_LOS_10_MASK) {
902                 alarm_events->secondary_clock_back++;
903                 SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
904         }
905         if (int_events & HOLDOVER_10_MASK)
906                 alarm_events->pll_end_holdover++;
907
908         if (int_events & UNLOCK_01_MASK)
909                 alarm_events->pll_lost_sync++;
910
911         if (int_events & UNLOCK_10_MASK)
912                 alarm_events->pll_sync++;
913
914         /* Holdover changed from 0 to 1 ? */
915         if (int_events & HOLDOVER_01_MASK) {
916                 alarm_events->pll_holdover++;
917
918                 /* TIMEOUT in ~10ms */
919                 switchover_timer.expires = jiffies + msecs_to_jiffies(10);
920                 tlclk_timer_data = inb(TLCLK_REG1);
921                 switchover_timer.data = (unsigned long) &tlclk_timer_data;
922                 mod_timer(&switchover_timer, switchover_timer.expires);
923         } else {
924                 got_event = 1;
925                 wake_up(&wq);
926         }
927         spin_unlock_irqrestore(&event_lock, flags);
928
929         return IRQ_HANDLED;
930 }
931
932 module_init(tlclk_init);
933 module_exit(tlclk_cleanup);