Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43ba968b authored by Yoshihiro Shimoda's avatar Yoshihiro Shimoda Committed by Felipe Balbi
Browse files

usb: gadget: udc: renesas_usb3: add debugfs to set the b-device mode



This patch adds debugfs to set the "b-device" mode for using a board
which is not connected to the ID pin (e.g. CN11 on Salvator-X).
If we want to use peripheral mode on such a board, we have to disable
VBUS output first. So, this patch can set such a mode as the following:

 # mount -t debugfs none /sys/kernel/debug
 # modprobe renesas_usb3
 # modprobe g_mass_storage file=/dev/shm/test.bin
 # echo 1 > /sys/kernel/debug/ee020000.usb/b_device

Signed-off-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 7d343a6a
Loading
Loading
Loading
Loading
+76 −2
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * the Free Software Foundation; version 2 of the License.
 */

#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
@@ -20,6 +21,7 @@
#include <linux/pm_runtime.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>

@@ -347,6 +349,7 @@ struct renesas_usb3 {
	bool workaround_for_vbus;
	bool extcon_host;		/* check id and set EXTCON_USB_HOST */
	bool extcon_usb;		/* check vbus and set EXTCON_USB */
	bool forced_b_device;
};

#define gadget_to_renesas_usb3(_gadget)	\
@@ -663,7 +666,9 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev)
	spin_lock_irqsave(&usb3->lock, flags);
	usb3_set_mode(usb3, host);
	usb3_vbus_out(usb3, a_dev);
	if (!host && a_dev)		/* for A-Peripheral */
	/* for A-Peripheral or forced B-device mode */
	if ((!host && a_dev) ||
	    (usb3->workaround_for_vbus && usb3->forced_b_device))
		usb3_connect(usb3);
	spin_unlock_irqrestore(&usb3->lock, flags);
}
@@ -677,7 +682,7 @@ static void usb3_check_id(struct renesas_usb3 *usb3)
{
	usb3->extcon_host = usb3_is_a_device(usb3);

	if (usb3->extcon_host)
	if (usb3->extcon_host && !usb3->forced_b_device)
		usb3_mode_config(usb3, true, true);
	else
		usb3_mode_config(usb3, false, false);
@@ -2272,6 +2277,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
	if (!usb3->driver)
		return -ENODEV;

	if (usb3->forced_b_device)
		return -EBUSY;

	if (!strncmp(buf, "host", strlen("host")))
		new_mode_is_host = true;
	else if (!strncmp(buf, "peripheral", strlen("peripheral")))
@@ -2299,6 +2307,70 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(role);

static int renesas_usb3_b_device_show(struct seq_file *s, void *unused)
{
	struct renesas_usb3 *usb3 = s->private;

	seq_printf(s, "%d\n", usb3->forced_b_device);

	return 0;
}

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

static ssize_t renesas_usb3_b_device_write(struct file *file,
					   const char __user *ubuf,
					   size_t count, loff_t *ppos)
{
	struct seq_file *s = file->private_data;
	struct renesas_usb3 *usb3 = s->private;
	char buf[32];

	if (!usb3->driver)
		return -ENODEV;

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

	if (!strncmp(buf, "1", 1))
		usb3->forced_b_device = true;
	else
		usb3->forced_b_device = false;

	/* Let this driver call usb3_connect() anyway */
	usb3_check_id(usb3);

	return count;
}

static const struct file_operations renesas_usb3_b_device_fops = {
	.open = renesas_usb3_b_device_open,
	.write = renesas_usb3_b_device_write,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

static void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3,
				      struct device *dev)
{
	struct dentry *root, *file;

	root = debugfs_create_dir(dev_name(dev), NULL);
	if (IS_ERR_OR_NULL(root)) {
		dev_info(dev, "%s: Can't create the root\n", __func__);
		return;
	}

	file = debugfs_create_file("b_device", 0644, root, usb3,
				   &renesas_usb3_b_device_fops);
	if (!file)
		dev_info(dev, "%s: Can't create debugfs mode\n", __func__);
}

/*------- platform_driver ------------------------------------------------*/
static int renesas_usb3_remove(struct platform_device *pdev)
{
@@ -2518,6 +2590,8 @@ static int renesas_usb3_probe(struct platform_device *pdev)

	usb3->workaround_for_vbus = priv->workaround_for_vbus;

	renesas_usb3_debugfs_init(usb3, &pdev->dev);

	dev_info(&pdev->dev, "probed\n");

	return 0;