diff options
| -rw-r--r-- | drivers/char/tlclk.c | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index bc56df8a3474..4c272189cd42 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <linux/kernel.h> /* printk() */ | 34 | #include <linux/kernel.h> /* printk() */ |
| 35 | #include <linux/fs.h> /* everything... */ | 35 | #include <linux/fs.h> /* everything... */ |
| 36 | #include <linux/errno.h> /* error codes */ | 36 | #include <linux/errno.h> /* error codes */ |
| 37 | #include <linux/delay.h> /* udelay */ | ||
| 38 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
| 39 | #include <linux/ioport.h> | 38 | #include <linux/ioport.h> |
| 40 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
| @@ -156,6 +155,8 @@ This directory exports the following interfaces. There operation is | |||
| 156 | documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4. | 155 | documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4. |
| 157 | alarms : | 156 | alarms : |
| 158 | current_ref : | 157 | current_ref : |
| 158 | received_ref_clk3a : | ||
| 159 | received_ref_clk3b : | ||
| 159 | enable_clk3a_output : | 160 | enable_clk3a_output : |
| 160 | enable_clk3b_output : | 161 | enable_clk3b_output : |
| 161 | enable_clka0_output : | 162 | enable_clka0_output : |
| @@ -165,7 +166,7 @@ enable_clkb1_output : | |||
| 165 | filter_select : | 166 | filter_select : |
| 166 | hardware_switching : | 167 | hardware_switching : |
| 167 | hardware_switching_mode : | 168 | hardware_switching_mode : |
| 168 | interrupt_switch : | 169 | telclock_version : |
| 169 | mode_select : | 170 | mode_select : |
| 170 | refalign : | 171 | refalign : |
| 171 | reset : | 172 | reset : |
| @@ -173,7 +174,6 @@ select_amcb1_transmit_clock : | |||
| 173 | select_amcb2_transmit_clock : | 174 | select_amcb2_transmit_clock : |
| 174 | select_redundant_clock : | 175 | select_redundant_clock : |
| 175 | select_ref_frequency : | 176 | select_ref_frequency : |
| 176 | test_mode : | ||
| 177 | 177 | ||
| 178 | All sysfs interfaces are integers in hex format, i.e echo 99 > refalign | 178 | All sysfs interfaces are integers in hex format, i.e echo 99 > refalign |
| 179 | has the same effect as echo 0x99 > refalign. | 179 | has the same effect as echo 0x99 > refalign. |
| @@ -226,7 +226,7 @@ static int tlclk_release(struct inode *inode, struct file *filp) | |||
| 226 | return 0; | 226 | return 0; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, | 229 | static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, |
| 230 | loff_t *f_pos) | 230 | loff_t *f_pos) |
| 231 | { | 231 | { |
| 232 | if (count < sizeof(struct tlclk_alarms)) | 232 | if (count < sizeof(struct tlclk_alarms)) |
| @@ -242,7 +242,7 @@ ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, | |||
| 242 | return sizeof(struct tlclk_alarms); | 242 | return sizeof(struct tlclk_alarms); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, | 245 | static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, |
| 246 | loff_t *f_pos) | 246 | loff_t *f_pos) |
| 247 | { | 247 | { |
| 248 | return 0; | 248 | return 0; |
| @@ -278,21 +278,21 @@ static ssize_t show_current_ref(struct device *d, | |||
| 278 | static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL); | 278 | static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL); |
| 279 | 279 | ||
| 280 | 280 | ||
| 281 | static ssize_t show_interrupt_switch(struct device *d, | 281 | static ssize_t show_telclock_version(struct device *d, |
| 282 | struct device_attribute *attr, char *buf) | 282 | struct device_attribute *attr, char *buf) |
| 283 | { | 283 | { |
| 284 | unsigned long ret_val; | 284 | unsigned long ret_val; |
| 285 | unsigned long flags; | 285 | unsigned long flags; |
| 286 | 286 | ||
| 287 | spin_lock_irqsave(&event_lock, flags); | 287 | spin_lock_irqsave(&event_lock, flags); |
| 288 | ret_val = inb(TLCLK_REG6); | 288 | ret_val = inb(TLCLK_REG5); |
| 289 | spin_unlock_irqrestore(&event_lock, flags); | 289 | spin_unlock_irqrestore(&event_lock, flags); |
| 290 | 290 | ||
| 291 | return sprintf(buf, "0x%lX\n", ret_val); | 291 | return sprintf(buf, "0x%lX\n", ret_val); |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static DEVICE_ATTR(interrupt_switch, S_IRUGO, | 294 | static DEVICE_ATTR(telclock_version, S_IRUGO, |
| 295 | show_interrupt_switch, NULL); | 295 | show_telclock_version, NULL); |
| 296 | 296 | ||
| 297 | static ssize_t show_alarms(struct device *d, | 297 | static ssize_t show_alarms(struct device *d, |
| 298 | struct device_attribute *attr, char *buf) | 298 | struct device_attribute *attr, char *buf) |
| @@ -309,6 +309,50 @@ static ssize_t show_alarms(struct device *d, | |||
| 309 | 309 | ||
| 310 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 310 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
| 311 | 311 | ||
| 312 | static ssize_t store_received_ref_clk3a(struct device *d, | ||
| 313 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 314 | { | ||
| 315 | unsigned long tmp; | ||
| 316 | unsigned char val; | ||
| 317 | unsigned long flags; | ||
| 318 | |||
| 319 | sscanf(buf, "%lX", &tmp); | ||
| 320 | dev_dbg(d, ": tmp = 0x%lX\n", tmp); | ||
| 321 | |||
| 322 | val = (unsigned char)tmp; | ||
| 323 | spin_lock_irqsave(&event_lock, flags); | ||
| 324 | SET_PORT_BITS(TLCLK_REG1, 0xef, val); | ||
| 325 | spin_unlock_irqrestore(&event_lock, flags); | ||
| 326 | |||
| 327 | return strnlen(buf, count); | ||
| 328 | } | ||
| 329 | |||
| 330 | static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, | ||
| 331 | store_received_ref_clk3a); | ||
| 332 | |||
| 333 | |||
| 334 | static ssize_t store_received_ref_clk3b(struct device *d, | ||
| 335 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 336 | { | ||
| 337 | unsigned long tmp; | ||
| 338 | unsigned char val; | ||
| 339 | unsigned long flags; | ||
| 340 | |||
| 341 | sscanf(buf, "%lX", &tmp); | ||
| 342 | dev_dbg(d, ": tmp = 0x%lX\n", tmp); | ||
| 343 | |||
| 344 | val = (unsigned char)tmp; | ||
| 345 | spin_lock_irqsave(&event_lock, flags); | ||
| 346 | SET_PORT_BITS(TLCLK_REG1, 0xef, val << 1); | ||
| 347 | spin_unlock_irqrestore(&event_lock, flags); | ||
| 348 | |||
| 349 | return strnlen(buf, count); | ||
| 350 | } | ||
| 351 | |||
| 352 | static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, | ||
| 353 | store_received_ref_clk3b); | ||
| 354 | |||
| 355 | |||
| 312 | static ssize_t store_enable_clk3b_output(struct device *d, | 356 | static ssize_t store_enable_clk3b_output(struct device *d, |
| 313 | struct device_attribute *attr, const char *buf, size_t count) | 357 | struct device_attribute *attr, const char *buf, size_t count) |
| 314 | { | 358 | { |
| @@ -436,26 +480,6 @@ static ssize_t store_enable_clka0_output(struct device *d, | |||
| 436 | static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, | 480 | static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, |
| 437 | store_enable_clka0_output); | 481 | store_enable_clka0_output); |
| 438 | 482 | ||
| 439 | static ssize_t store_test_mode(struct device *d, | ||
| 440 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 441 | { | ||
| 442 | unsigned long flags; | ||
| 443 | unsigned long tmp; | ||
| 444 | unsigned char val; | ||
| 445 | |||
| 446 | sscanf(buf, "%lX", &tmp); | ||
| 447 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | ||
| 448 | |||
| 449 | val = (unsigned char)tmp; | ||
| 450 | spin_lock_irqsave(&event_lock, flags); | ||
| 451 | SET_PORT_BITS(TLCLK_REG4, 0xfd, 2); | ||
| 452 | spin_unlock_irqrestore(&event_lock, flags); | ||
| 453 | |||
| 454 | return strnlen(buf, count); | ||
| 455 | } | ||
| 456 | |||
| 457 | static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode); | ||
| 458 | |||
| 459 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, | 483 | static ssize_t store_select_amcb2_transmit_clock(struct device *d, |
| 460 | struct device_attribute *attr, const char *buf, size_t count) | 484 | struct device_attribute *attr, const char *buf, size_t count) |
| 461 | { | 485 | { |
| @@ -475,7 +499,7 @@ static ssize_t store_select_amcb2_transmit_clock(struct device *d, | |||
| 475 | SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); | 499 | SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); |
| 476 | switch (val) { | 500 | switch (val) { |
| 477 | case CLK_8_592MHz: | 501 | case CLK_8_592MHz: |
| 478 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); | 502 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); |
| 479 | break; | 503 | break; |
| 480 | case CLK_11_184MHz: | 504 | case CLK_11_184MHz: |
| 481 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); | 505 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); |
| @@ -484,7 +508,7 @@ static ssize_t store_select_amcb2_transmit_clock(struct device *d, | |||
| 484 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); | 508 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); |
| 485 | break; | 509 | break; |
| 486 | case CLK_44_736MHz: | 510 | case CLK_44_736MHz: |
| 487 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); | 511 | SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); |
| 488 | break; | 512 | break; |
| 489 | } | 513 | } |
| 490 | } else | 514 | } else |
| @@ -653,9 +677,7 @@ static ssize_t store_refalign (struct device *d, | |||
| 653 | dev_dbg(d, "tmp = 0x%lX\n", tmp); | 677 | dev_dbg(d, "tmp = 0x%lX\n", tmp); |
| 654 | spin_lock_irqsave(&event_lock, flags); | 678 | spin_lock_irqsave(&event_lock, flags); |
| 655 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); | 679 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); |
| 656 | udelay(2); | ||
| 657 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08); | 680 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08); |
| 658 | udelay(2); | ||
| 659 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); | 681 | SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); |
| 660 | spin_unlock_irqrestore(&event_lock, flags); | 682 | spin_unlock_irqrestore(&event_lock, flags); |
| 661 | 683 | ||
| @@ -706,15 +728,16 @@ static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); | |||
| 706 | 728 | ||
| 707 | static struct attribute *tlclk_sysfs_entries[] = { | 729 | static struct attribute *tlclk_sysfs_entries[] = { |
| 708 | &dev_attr_current_ref.attr, | 730 | &dev_attr_current_ref.attr, |
| 709 | &dev_attr_interrupt_switch.attr, | 731 | &dev_attr_telclock_version.attr, |
| 710 | &dev_attr_alarms.attr, | 732 | &dev_attr_alarms.attr, |
| 733 | &dev_attr_received_ref_clk3a.attr, | ||
| 734 | &dev_attr_received_ref_clk3b.attr, | ||
| 711 | &dev_attr_enable_clk3a_output.attr, | 735 | &dev_attr_enable_clk3a_output.attr, |
| 712 | &dev_attr_enable_clk3b_output.attr, | 736 | &dev_attr_enable_clk3b_output.attr, |
| 713 | &dev_attr_enable_clkb1_output.attr, | 737 | &dev_attr_enable_clkb1_output.attr, |
| 714 | &dev_attr_enable_clka1_output.attr, | 738 | &dev_attr_enable_clka1_output.attr, |
| 715 | &dev_attr_enable_clkb0_output.attr, | 739 | &dev_attr_enable_clkb0_output.attr, |
| 716 | &dev_attr_enable_clka0_output.attr, | 740 | &dev_attr_enable_clka0_output.attr, |
| 717 | &dev_attr_test_mode.attr, | ||
| 718 | &dev_attr_select_amcb1_transmit_clock.attr, | 741 | &dev_attr_select_amcb1_transmit_clock.attr, |
| 719 | &dev_attr_select_amcb2_transmit_clock.attr, | 742 | &dev_attr_select_amcb2_transmit_clock.attr, |
| 720 | &dev_attr_select_redundant_clock.attr, | 743 | &dev_attr_select_redundant_clock.attr, |
