diff options
author | Felipe Balbi <balbi@ti.com> | 2012-01-02 11:38:30 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-02-06 04:48:22 -0500 |
commit | 080d921fe7a8d27c07eba7723fe53a3bea100327 (patch) | |
tree | e0841e4deed5284473d39d3203e846afd14a6353 /drivers/usb/dwc3/debugfs.c | |
parent | 04a9bfcd50dd568a8f1a10194a7f336f6b3ad81c (diff) |
usb: dwc3: gadget: allow testmodes changes via debugfs
This is very useful for low level Link Testing where
we might not have a USB Host stack, only a scope to
verify signal integrity.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3/debugfs.c')
-rw-r--r-- | drivers/usb/dwc3/debugfs.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 433c97c15fc5..c7e85024fda8 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <linux/delay.h> | 46 | #include <linux/delay.h> |
47 | #include <linux/uaccess.h> | 47 | #include <linux/uaccess.h> |
48 | 48 | ||
49 | #include <linux/usb/ch9.h> | ||
50 | |||
49 | #include "core.h" | 51 | #include "core.h" |
50 | #include "gadget.h" | 52 | #include "gadget.h" |
51 | #include "io.h" | 53 | #include "io.h" |
@@ -464,6 +466,89 @@ static const struct file_operations dwc3_mode_fops = { | |||
464 | .release = single_release, | 466 | .release = single_release, |
465 | }; | 467 | }; |
466 | 468 | ||
469 | static int dwc3_testmode_show(struct seq_file *s, void *unused) | ||
470 | { | ||
471 | struct dwc3 *dwc = s->private; | ||
472 | unsigned long flags; | ||
473 | u32 reg; | ||
474 | |||
475 | spin_lock_irqsave(&dwc->lock, flags); | ||
476 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
477 | reg &= DWC3_DCTL_TSTCTRL_MASK; | ||
478 | reg >>= 1; | ||
479 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
480 | |||
481 | switch (reg) { | ||
482 | case 0: | ||
483 | seq_printf(s, "no test\n"); | ||
484 | break; | ||
485 | case TEST_J: | ||
486 | seq_printf(s, "test_j\n"); | ||
487 | break; | ||
488 | case TEST_K: | ||
489 | seq_printf(s, "test_k\n"); | ||
490 | break; | ||
491 | case TEST_SE0_NAK: | ||
492 | seq_printf(s, "test_se0_nak\n"); | ||
493 | break; | ||
494 | case TEST_PACKET: | ||
495 | seq_printf(s, "test_packet\n"); | ||
496 | break; | ||
497 | case TEST_FORCE_EN: | ||
498 | seq_printf(s, "test_force_enable\n"); | ||
499 | break; | ||
500 | default: | ||
501 | seq_printf(s, "UNKNOWN %d\n", reg); | ||
502 | } | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int dwc3_testmode_open(struct inode *inode, struct file *file) | ||
508 | { | ||
509 | return single_open(file, dwc3_testmode_show, inode->i_private); | ||
510 | } | ||
511 | |||
512 | static ssize_t dwc3_testmode_write(struct file *file, | ||
513 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
514 | { | ||
515 | struct seq_file *s = file->private_data; | ||
516 | struct dwc3 *dwc = s->private; | ||
517 | unsigned long flags; | ||
518 | u32 testmode = 0; | ||
519 | char buf[32]; | ||
520 | |||
521 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
522 | return -EFAULT; | ||
523 | |||
524 | if (!strncmp(buf, "test_j", 6)) | ||
525 | testmode = TEST_J; | ||
526 | else if (!strncmp(buf, "test_k", 6)) | ||
527 | testmode = TEST_K; | ||
528 | else if (!strncmp(buf, "test_se0_nak", 13)) | ||
529 | testmode = TEST_SE0_NAK; | ||
530 | else if (!strncmp(buf, "test_packet", 12)) | ||
531 | testmode = TEST_PACKET; | ||
532 | else if (!strncmp(buf, "test_force_enable", 18)) | ||
533 | testmode = TEST_FORCE_EN; | ||
534 | else | ||
535 | testmode = 0; | ||
536 | |||
537 | spin_lock_irqsave(&dwc->lock, flags); | ||
538 | dwc3_gadget_set_test_mode(dwc, testmode); | ||
539 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
540 | |||
541 | return count; | ||
542 | } | ||
543 | |||
544 | static const struct file_operations dwc3_testmode_fops = { | ||
545 | .open = dwc3_testmode_open, | ||
546 | .write = dwc3_testmode_write, | ||
547 | .read = seq_read, | ||
548 | .llseek = seq_lseek, | ||
549 | .release = single_release, | ||
550 | }; | ||
551 | |||
467 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | 552 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) |
468 | { | 553 | { |
469 | struct dentry *root; | 554 | struct dentry *root; |
@@ -492,6 +577,13 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | |||
492 | goto err1; | 577 | goto err1; |
493 | } | 578 | } |
494 | 579 | ||
580 | file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, | ||
581 | dwc, &dwc3_testmode_fops); | ||
582 | if (IS_ERR(file)) { | ||
583 | ret = PTR_ERR(file); | ||
584 | goto err1; | ||
585 | } | ||
586 | |||
495 | return 0; | 587 | return 0; |
496 | 588 | ||
497 | err1: | 589 | err1: |