linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add Apple Carplay driver
@ 2018-03-14  6:02 Chunfeng Yun
  2018-03-14  6:02 ` [PATCH] usb: misc: supports " Chunfeng Yun
  2018-03-14  6:53 ` [PATCH] Add " Matthew Dharm
  0 siblings, 2 replies; 6+ messages in thread
From: Chunfeng Yun @ 2018-03-14  6:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Matthias Brugger, Heikki Krogerus, Serge Semin, Chunfeng Yun,
	Guenter Roeck, Kate Stewart, Thomas Gleixner, Alan Stern,
	linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek

>From bf48dcd9cb254576cfea373c9a5d2ab996408895 Mon Sep 17 00:00:00 2001
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
Date: Tue, 13 Mar 2018 11:47:38 +0800
Subject: [PATCH] Add Apple Carplay driver

Some Apple devices which support Carplay can enter USB Host Mode from USB
Device Mode after receiving a specific USB Vendor Request. There is a
requirement apply to accesssories that support the USB dual role switch
feature, and must have a USB-A receptacle that is capable of functioning
in both USB Host and USB Device roles.
It means that the driver should supports manual Dual-Role switch, due to
no IDDIG pin is avaliable.

There is no suitable place to add this spicific USB Vendor Request, so
here I extract a single driver which allow user force to send it by a debug
interface when need it, and keep it independent on USB Dual-Role Controller
Drivers.
But to implement carplay feature, there are some requirments for USB Dual-Role
Driver:
1. supports manual dual-role switch, such as, by a debug interface;
2. keep vbus alive even when switch host into device mode;

More information please refer to "Chapter 46. USB Role Switch" in
MFI Accessroy Interface Specification.pdf

Chunfeng Yun (1):
  usb: misc: supports Apple Carplay driver

 drivers/usb/misc/Kconfig   |    9 +++
 drivers/usb/misc/Makefile  |    1 +
 drivers/usb/misc/carplay.c |  193 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 drivers/usb/misc/carplay.c

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] usb: misc: supports Apple Carplay driver
  2018-03-14  6:02 [PATCH] Add Apple Carplay driver Chunfeng Yun
@ 2018-03-14  6:02 ` Chunfeng Yun
  2018-03-14  6:16   ` Greg Kroah-Hartman
  2018-03-14  6:53 ` [PATCH] Add " Matthew Dharm
  1 sibling, 1 reply; 6+ messages in thread
From: Chunfeng Yun @ 2018-03-14  6:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Matthias Brugger, Heikki Krogerus, Serge Semin, Chunfeng Yun,
	Guenter Roeck, Kate Stewart, Thomas Gleixner, Alan Stern,
	linux-kernel, linux-usb, linux-arm-kernel, linux-mediatek

The driver is used to support Apple carplay feature by a debugfs
interface which can force the driver to send a USB Vendor Request
of "Apple Device to Host Mode Switch" to switch Apple Device
into host mode.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
---
 drivers/usb/misc/Kconfig   |    9 ++
 drivers/usb/misc/Makefile  |    1 +
 drivers/usb/misc/carplay.c |  205 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 215 insertions(+)
 create mode 100644 drivers/usb/misc/carplay.c

diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 68d2f2c..c010c95 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -275,3 +275,12 @@ config USB_CHAOSKEY
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called chaoskey.
+
+config USB_CARPLAY
+	tristate "USB carplay driver support"
+	help
+	  The driver is used to support Apple carplay feature.
+	  It is realized by sending a USB Vendor Request of "Apple Device to
+	  Host Mode Switch" to switch Apple Device into host mode.
+	  When the users want to use carplay, they can force the driver to send
+	  this Vendor Request by a debugfs interface.
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 109f54f..94380e7 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -29,5 +29,6 @@ obj-$(CONFIG_USB_HSIC_USB3503)		+= usb3503.o
 obj-$(CONFIG_USB_HSIC_USB4604)		+= usb4604.o
 obj-$(CONFIG_USB_CHAOSKEY)		+= chaoskey.o
 
+obj-$(CONFIG_USB_CARPLAY)		+= carplay.o
 obj-$(CONFIG_USB_SISUSBVGA)		+= sisusbvga/
 obj-$(CONFIG_USB_LINK_LAYER_TEST)	+= lvstest.o
diff --git a/drivers/usb/misc/carplay.c b/drivers/usb/misc/carplay.c
new file mode 100644
index 0000000..bfd41f3
--- /dev/null
+++ b/drivers/usb/misc/carplay.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * carplay.c - carplay usb driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+
+/*
+ * usage:
+ * The requirement for the platform using Carplay feature is that support
+ * the USB Dual Role Switch feature, and must have a USB-A receptacle
+ * that is capable of functioning in both USB Host and USB Device roles.
+ *
+ * 1. Apple iphone is enumerated as a usb device
+ * 2. switch Apple iphone to host mode, by, e.g.
+ *    echo host > /sys/kernel/debug/usb/carplay.1-1/mode
+ * 3. switch the platform to device mode, but meanwhile should keep vbus alive;
+ * 4. use carplay feature after the platform is enumerated as a usb device;
+ * 5. when unplug usb cable, switch the platform back to host mode.
+ *
+ * step 2 is supported by this driver;
+ * step 1, 3, 4, 5 should be supported by the USB Dual-Role Controller Driver
+ *    on the platform.
+ *
+ * For more detailed information, please refer to "Chapter 46. USB Role Switch"
+ * in MFI Accessroy Interface Specification.pdf
+ */
+
+#define CARPLAY_NAME "carplay"
+#define VENDER_REQ_DEV_TO_HOST 0x51
+
+struct usb_carplay {
+	struct usb_interface *intf;
+	struct usb_device *udev;
+	struct dentry *droot;
+	struct device *idev;
+	bool is_host;
+};
+
+static int carplay_switch_to_host(struct usb_carplay *ucp)
+{
+	struct usb_device *udev = ucp->udev;
+	int retval;
+
+	if (!ucp->udev)
+		return -ENODEV;
+
+	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+			VENDER_REQ_DEV_TO_HOST, USB_TYPE_VENDOR,
+			1, 0, NULL, 0, USB_CTRL_GET_TIMEOUT);
+
+	dev_dbg(ucp->idev, "%s retval = %d\n", __func__, retval);
+
+	if (retval != 0) {
+		dev_err(ucp->idev, "%s fail retval = %d\n", __func__, retval);
+		return retval;
+	}
+	ucp->is_host = true;
+
+	return 0;
+}
+
+static int carplay_mode_show(struct seq_file *sf, void *unused)
+{
+	struct usb_carplay *ucp = sf->private;
+
+	seq_printf(sf, "current mode: %s\n(usage: echo host > mode)\n",
+		ucp->is_host ? "host" : "device");
+
+	return 0;
+}
+
+static int carplay_mode_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, carplay_mode_show, inode->i_private);
+}
+
+static ssize_t carplay_mode_write(struct file *file,
+	const char __user *ubuf, size_t count, loff_t *ppos)
+{
+	struct seq_file *sf = file->private_data;
+	struct usb_carplay *ucp = sf->private;
+	char buf[16];
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	if (!strncmp(buf, "host", 4) && !ucp->is_host) {
+		carplay_switch_to_host(ucp);
+	} else {
+		dev_err(ucp->idev, "wrong setting\n");
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static const struct file_operations carplay_mode_fops = {
+	.open = carplay_mode_open,
+	.write = carplay_mode_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static struct dentry *carplay_debugfs_init(struct usb_carplay *ucp)
+{
+	struct dentry *root;
+	const char *udev_name = dev_name(&ucp->udev->dev);
+	char name[16];
+
+	snprintf(name, sizeof(name), "%s.%s", CARPLAY_NAME, udev_name);
+	root = debugfs_create_dir(name, usb_debug_root);
+	if (!root) {
+		dev_err(ucp->idev, "create debugfs root failed\n");
+		return root;
+	}
+	ucp->droot = root;
+
+	return debugfs_create_file("mode", 0664, root, ucp,
+			&carplay_mode_fops);
+}
+
+static void carplay_debugfs_exit(struct usb_carplay *ucp)
+{
+	debugfs_remove_recursive(ucp->droot);
+}
+
+static int carplay_probe(struct usb_interface *intf,
+	const struct usb_device_id *id)
+{
+	struct usb_device *udev;
+	struct usb_carplay *ucp;
+	struct dentry *de;
+
+	udev = interface_to_usbdev(intf);
+
+	ucp = kzalloc(sizeof(*ucp), GFP_KERNEL);
+	if (!ucp)
+		return -ENOMEM;
+
+	ucp->udev = usb_get_dev(udev);
+	ucp->intf = intf;
+	ucp->idev = &intf->dev;
+	usb_set_intfdata(intf, ucp);
+	ucp->is_host = false;
+
+	de = carplay_debugfs_init(ucp);
+	if (IS_ERR_OR_NULL(de)) {
+		usb_set_intfdata(intf, NULL);
+		usb_put_dev(ucp->udev);
+		kfree(ucp);
+		return -ENOMEM;
+	}
+
+	dev_info(ucp->idev, "carplay attached\n");
+	return 0;
+}
+
+static void carplay_disconnect(struct usb_interface *intf)
+{
+	struct usb_carplay *ucp = usb_get_intfdata(intf);
+
+	usb_set_intfdata(intf, NULL);
+	usb_put_dev(ucp->udev);
+	carplay_debugfs_exit(ucp);
+	kfree(ucp);
+	dev_info(&intf->dev, "carplay disconnected\n");
+}
+
+static const struct usb_device_id carplay_id_table[] = {
+	/* generic EZ-USB FX2 controller (or development board) */
+	{ USB_DEVICE(0x05ac, 0x12a8) },
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, carplay_id_table);
+
+static struct usb_driver carplay_driver = {
+	.name = CARPLAY_NAME,
+	.id_table = carplay_id_table,
+	.probe = carplay_probe,
+	.disconnect = carplay_disconnect,
+};
+
+module_usb_driver(carplay_driver);
+
+MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
+MODULE_DESCRIPTION("USB Carplay Driver");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] usb: misc: supports Apple Carplay driver
  2018-03-14  6:02 ` [PATCH] usb: misc: supports " Chunfeng Yun
@ 2018-03-14  6:16   ` Greg Kroah-Hartman
  2018-03-14  8:20     ` Chunfeng Yun
  0 siblings, 1 reply; 6+ messages in thread
From: Greg Kroah-Hartman @ 2018-03-14  6:16 UTC (permalink / raw)
  To: Chunfeng Yun
  Cc: Matthias Brugger, Heikki Krogerus, Serge Semin, Guenter Roeck,
	Kate Stewart, Thomas Gleixner, Alan Stern, linux-kernel,
	linux-usb, linux-arm-kernel, linux-mediatek

On Wed, Mar 14, 2018 at 02:02:36PM +0800, Chunfeng Yun wrote:
> The driver is used to support Apple carplay feature by a debugfs
> interface which can force the driver to send a USB Vendor Request
> of "Apple Device to Host Mode Switch" to switch Apple Device
> into host mode.

While I am all for crazy debugfs interfaces, I would _strongly_ suggest
not doing that here for the main API to the device.  I know Android is
trying to prevent any new devices from even enabling debugfs, and as the
file system requires root permissions by default, you are forcing any
user of your new api to run as root, which is not a good idea either.

Given that all you are doing here is a single usb control message, why
does this even need to be a kernel driver at all?  Can't you do the same
thing from userspace with a simple libusb/usbfs program?  Or even a
simple script?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add Apple Carplay driver
  2018-03-14  6:02 [PATCH] Add Apple Carplay driver Chunfeng Yun
  2018-03-14  6:02 ` [PATCH] usb: misc: supports " Chunfeng Yun
@ 2018-03-14  6:53 ` Matthew Dharm
  2018-03-14  8:18   ` Chunfeng Yun
  1 sibling, 1 reply; 6+ messages in thread
From: Matthew Dharm @ 2018-03-14  6:53 UTC (permalink / raw)
  To: Chunfeng Yun
  Cc: Greg Kroah-Hartman, Matthias Brugger, Heikki Krogerus,
	Serge Semin, Guenter Roeck, Kate Stewart, Thomas Gleixner,
	Alan Stern, linux-kernel, linux-usb, linux-arm-kernel,
	linux-mediatek

Why is this a kernel-level driver, rather than a userspace application
that uses libusb to send the single vendor-specific command required?
Since this command would be applicable to many CarPlay devices, with
many different VID/PIDs, it would seem to make more sense as a
userspace app that took a reference to a USB device or VID/PID.

Matt

On Tue, Mar 13, 2018 at 11:02 PM, Chunfeng Yun
<chunfeng.yun@mediatek.com> wrote:
> From bf48dcd9cb254576cfea373c9a5d2ab996408895 Mon Sep 17 00:00:00 2001
> From: Chunfeng Yun <chunfeng.yun@mediatek.com>
> Date: Tue, 13 Mar 2018 11:47:38 +0800
> Subject: [PATCH] Add Apple Carplay driver
>
> Some Apple devices which support Carplay can enter USB Host Mode from USB
> Device Mode after receiving a specific USB Vendor Request. There is a
> requirement apply to accesssories that support the USB dual role switch
> feature, and must have a USB-A receptacle that is capable of functioning
> in both USB Host and USB Device roles.
> It means that the driver should supports manual Dual-Role switch, due to
> no IDDIG pin is avaliable.
>
> There is no suitable place to add this spicific USB Vendor Request, so
> here I extract a single driver which allow user force to send it by a debug
> interface when need it, and keep it independent on USB Dual-Role Controller
> Drivers.
> But to implement carplay feature, there are some requirments for USB Dual-Role
> Driver:
> 1. supports manual dual-role switch, such as, by a debug interface;
> 2. keep vbus alive even when switch host into device mode;
>
> More information please refer to "Chapter 46. USB Role Switch" in
> MFI Accessroy Interface Specification.pdf
>
> Chunfeng Yun (1):
>   usb: misc: supports Apple Carplay driver
>
>  drivers/usb/misc/Kconfig   |    9 +++
>  drivers/usb/misc/Makefile  |    1 +
>  drivers/usb/misc/carplay.c |  193 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 203 insertions(+)
>  create mode 100644 drivers/usb/misc/carplay.c
>
> --
> 1.7.9.5
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Matthew Dharm
Former Maintainer, USB Mass Storage driver for Linux

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Add Apple Carplay driver
  2018-03-14  6:53 ` [PATCH] Add " Matthew Dharm
@ 2018-03-14  8:18   ` Chunfeng Yun
  0 siblings, 0 replies; 6+ messages in thread
From: Chunfeng Yun @ 2018-03-14  8:18 UTC (permalink / raw)
  To: Matthew Dharm
  Cc: Greg Kroah-Hartman, Matthias Brugger, Heikki Krogerus,
	Serge Semin, Guenter Roeck, Kate Stewart, Thomas Gleixner,
	Alan Stern, linux-kernel, linux-usb, linux-arm-kernel,
	linux-mediatek

On Tue, 2018-03-13 at 23:53 -0700, Matthew Dharm wrote:
> Why is this a kernel-level driver, rather than a userspace application
> that uses libusb to send the single vendor-specific command required?
> Since this command would be applicable to many CarPlay devices, with
> many different VID/PIDs, it would seem to make more sense as a
> userspace app that took a reference to a USB device or VID/PID.
Sorry, I'm not familiar with libusb.
But after I roughly read a simple example using libusb, it indeed can be
realized by a userspace driver.

Thanks for your useful comments

> 
> Matt
> 
> On Tue, Mar 13, 2018 at 11:02 PM, Chunfeng Yun
> <chunfeng.yun@mediatek.com> wrote:
> > From bf48dcd9cb254576cfea373c9a5d2ab996408895 Mon Sep 17 00:00:00 2001
> > From: Chunfeng Yun <chunfeng.yun@mediatek.com>
> > Date: Tue, 13 Mar 2018 11:47:38 +0800
> > Subject: [PATCH] Add Apple Carplay driver
> >
> > Some Apple devices which support Carplay can enter USB Host Mode from USB
> > Device Mode after receiving a specific USB Vendor Request. There is a
> > requirement apply to accesssories that support the USB dual role switch
> > feature, and must have a USB-A receptacle that is capable of functioning
> > in both USB Host and USB Device roles.
> > It means that the driver should supports manual Dual-Role switch, due to
> > no IDDIG pin is avaliable.
> >
> > There is no suitable place to add this spicific USB Vendor Request, so
> > here I extract a single driver which allow user force to send it by a debug
> > interface when need it, and keep it independent on USB Dual-Role Controller
> > Drivers.
> > But to implement carplay feature, there are some requirments for USB Dual-Role
> > Driver:
> > 1. supports manual dual-role switch, such as, by a debug interface;
> > 2. keep vbus alive even when switch host into device mode;
> >
> > More information please refer to "Chapter 46. USB Role Switch" in
> > MFI Accessroy Interface Specification.pdf
> >
> > Chunfeng Yun (1):
> >   usb: misc: supports Apple Carplay driver
> >
> >  drivers/usb/misc/Kconfig   |    9 +++
> >  drivers/usb/misc/Makefile  |    1 +
> >  drivers/usb/misc/carplay.c |  193 ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 203 insertions(+)
> >  create mode 100644 drivers/usb/misc/carplay.c
> >
> > --
> > 1.7.9.5
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] usb: misc: supports Apple Carplay driver
  2018-03-14  6:16   ` Greg Kroah-Hartman
@ 2018-03-14  8:20     ` Chunfeng Yun
  0 siblings, 0 replies; 6+ messages in thread
From: Chunfeng Yun @ 2018-03-14  8:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Matthias Brugger, Heikki Krogerus, Serge Semin, Guenter Roeck,
	Kate Stewart, Thomas Gleixner, Alan Stern, linux-kernel,
	linux-usb, linux-arm-kernel, linux-mediatek

On Wed, 2018-03-14 at 07:16 +0100, Greg Kroah-Hartman wrote:
> On Wed, Mar 14, 2018 at 02:02:36PM +0800, Chunfeng Yun wrote:
> > The driver is used to support Apple carplay feature by a debugfs
> > interface which can force the driver to send a USB Vendor Request
> > of "Apple Device to Host Mode Switch" to switch Apple Device
> > into host mode.
> 
> While I am all for crazy debugfs interfaces, I would _strongly_ suggest
> not doing that here for the main API to the device.  I know Android is
> trying to prevent any new devices from even enabling debugfs, and as the
> file system requires root permissions by default, you are forcing any
> user of your new api to run as root, which is not a good idea either.
> 
> Given that all you are doing here is a single usb control message, why
> does this even need to be a kernel driver at all?  Can't you do the same
> thing from userspace with a simple libusb/usbfs program?  Or even a
> simple script?
Ok, I'll abandon this patch, and do it by libusb

Thanks a lot

> 
> thanks,
> 
> greg k-h

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-03-14  8:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-14  6:02 [PATCH] Add Apple Carplay driver Chunfeng Yun
2018-03-14  6:02 ` [PATCH] usb: misc: supports " Chunfeng Yun
2018-03-14  6:16   ` Greg Kroah-Hartman
2018-03-14  8:20     ` Chunfeng Yun
2018-03-14  6:53 ` [PATCH] Add " Matthew Dharm
2018-03-14  8:18   ` Chunfeng Yun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).