Skip to content

Commit

Permalink
usb: dwc3: gadget: allow testmodes changes via debugfs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Felipe Balbi committed Feb 6, 2012
1 parent 04a9bfc commit 080d921
Showing 1 changed file with 92 additions and 0 deletions.
92 changes: 92 additions & 0 deletions drivers/usb/dwc3/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include <linux/delay.h>
#include <linux/uaccess.h>

#include <linux/usb/ch9.h>

#include "core.h"
#include "gadget.h"
#include "io.h"
Expand Down Expand Up @@ -464,6 +466,89 @@ static const struct file_operations dwc3_mode_fops = {
.release = single_release,
};

static int dwc3_testmode_show(struct seq_file *s, void *unused)
{
struct dwc3 *dwc = s->private;
unsigned long flags;
u32 reg;

spin_lock_irqsave(&dwc->lock, flags);
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
reg &= DWC3_DCTL_TSTCTRL_MASK;
reg >>= 1;
spin_unlock_irqrestore(&dwc->lock, flags);

switch (reg) {
case 0:
seq_printf(s, "no test\n");
break;
case TEST_J:
seq_printf(s, "test_j\n");
break;
case TEST_K:
seq_printf(s, "test_k\n");
break;
case TEST_SE0_NAK:
seq_printf(s, "test_se0_nak\n");
break;
case TEST_PACKET:
seq_printf(s, "test_packet\n");
break;
case TEST_FORCE_EN:
seq_printf(s, "test_force_enable\n");
break;
default:
seq_printf(s, "UNKNOWN %d\n", reg);
}

return 0;
}

static int dwc3_testmode_open(struct inode *inode, struct file *file)
{
return single_open(file, dwc3_testmode_show, inode->i_private);
}

static ssize_t dwc3_testmode_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
struct seq_file *s = file->private_data;
struct dwc3 *dwc = s->private;
unsigned long flags;
u32 testmode = 0;
char buf[32];

if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
return -EFAULT;

if (!strncmp(buf, "test_j", 6))
testmode = TEST_J;
else if (!strncmp(buf, "test_k", 6))
testmode = TEST_K;
else if (!strncmp(buf, "test_se0_nak", 13))
testmode = TEST_SE0_NAK;
else if (!strncmp(buf, "test_packet", 12))
testmode = TEST_PACKET;
else if (!strncmp(buf, "test_force_enable", 18))
testmode = TEST_FORCE_EN;
else
testmode = 0;

spin_lock_irqsave(&dwc->lock, flags);
dwc3_gadget_set_test_mode(dwc, testmode);
spin_unlock_irqrestore(&dwc->lock, flags);

return count;
}

static const struct file_operations dwc3_testmode_fops = {
.open = dwc3_testmode_open,
.write = dwc3_testmode_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
{
struct dentry *root;
Expand Down Expand Up @@ -492,6 +577,13 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
goto err1;
}

file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
dwc, &dwc3_testmode_fops);
if (IS_ERR(file)) {
ret = PTR_ERR(file);
goto err1;
}

return 0;

err1:
Expand Down

0 comments on commit 080d921

Please sign in to comment.