aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/debugfs.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-01-02 11:38:30 -0500
committerFelipe Balbi <balbi@ti.com>2012-02-06 04:48:22 -0500
commit080d921fe7a8d27c07eba7723fe53a3bea100327 (patch)
treee0841e4deed5284473d39d3203e846afd14a6353 /drivers/usb/dwc3/debugfs.c
parent04a9bfcd50dd568a8f1a10194a7f336f6b3ad81c (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.c92
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
469static 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
507static int dwc3_testmode_open(struct inode *inode, struct file *file)
508{
509 return single_open(file, dwc3_testmode_show, inode->i_private);
510}
511
512static 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
544static 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
467int __devinit dwc3_debugfs_init(struct dwc3 *dwc) 552int __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
497err1: 589err1: