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>
This commit is contained in:
parent
04a9bfcd50
commit
080d921fe7
1 changed files with 92 additions and 0 deletions
|
@ -46,6 +46,8 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
#include <linux/usb/ch9.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "gadget.h"
|
#include "gadget.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
@ -464,6 +466,89 @@ static const struct file_operations dwc3_mode_fops = {
|
||||||
.release = single_release,
|
.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)
|
int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
|
||||||
{
|
{
|
||||||
struct dentry *root;
|
struct dentry *root;
|
||||||
|
@ -492,6 +577,13 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
|
||||||
goto err1;
|
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;
|
return 0;
|
||||||
|
|
||||||
err1:
|
err1:
|
||||||
|
|
Loading…
Reference in a new issue