lkml.org 
[lkml]   [2017]   [May]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v1 1/1] mux: mux-intel-usb: Add Intel USB Multiplexer driver
Date
From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

In some Intel SOCs, a single USB port is shared between USB device and
host controller and an internal mux is used to control the selection of
port by host/device controllers. This driver adds support for the USB
internal mux, and all consumers of this mux can use interfaces provided
by mux subsytem to control the state of the internal mux.

Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
drivers/mux/Kconfig | 13 ++++
drivers/mux/Makefile | 1 +
drivers/mux/mux-intel-usb.c | 132 ++++++++++++++++++++++++++++++++++++++
include/linux/mux/mux-intel-usb.h | 22 +++++++
4 files changed, 168 insertions(+)
create mode 100644 drivers/mux/mux-intel-usb.c
create mode 100644 include/linux/mux/mux-intel-usb.h

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index e8f1df7..0e3af09 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -56,4 +56,17 @@ config MUX_MMIO
To compile the driver as a module, choose M here: the module will
be called mux-mmio.

+config MUX_INTEL_USB
+ tristate "Intel USB Mux"
+ depends on USB
+ help
+ In some Intel SOCs, a single USB port is shared between USB
+ device and host controller and an internal mux is used to
+ control the selection of port by host/device controllers. This
+ driver adds support for the USB internal mux, and all consumers
+ of this mux can use interfaces provided by mux subsytem to control
+ the state of the internal mux.
+
+ To compile the driver as a module, choose M here.
+
endif
diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
index 6bac5b0..9154616 100644
--- a/drivers/mux/Makefile
+++ b/drivers/mux/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_MULTIPLEXER) += mux-core.o
obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o
obj-$(CONFIG_MUX_GPIO) += mux-gpio.o
obj-$(CONFIG_MUX_MMIO) += mux-mmio.o
+obj-$(CONFIG_MUX_INTEL_USB) += mux-intel-usb.o
diff --git a/drivers/mux/mux-intel-usb.c b/drivers/mux/mux-intel-usb.c
new file mode 100644
index 0000000..587e9bb
--- /dev/null
+++ b/drivers/mux/mux-intel-usb.c
@@ -0,0 +1,132 @@
+/*
+ * Intel USB Multiplexer Driver
+ *
+ * Copyright (C) 2017 Intel Corporation
+ *
+ * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@intel.com>
+ *
+ * This driver is written based on extcon-intel-usb driver submitted by
+ * Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/mux/driver.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/mux/mux-intel-usb.h>
+#include <linux/io.h>
+
+#define INTEL_MUX_CFG0 0x00
+#define INTEL_MUX_CFG1 0x04
+
+#define CFG0_SW_DRD_MODE_MASK 0x3
+#define CFG0_SW_DRD_DYN 0
+#define CFG0_SW_DRD_STATIC_HOST 1
+#define CFG0_SW_DRD_STATIC_DEV 2
+#define CFG0_SW_SYNC_SS_AND_HS BIT(2)
+#define CFG0_SW_SWITCH_EN BIT(16)
+#define CFG0_SW_IDPIN BIT(20)
+#define CFG0_SW_IDPIN_EN BIT(21)
+#define CFG0_SW_VBUS_VALID BIT(24)
+
+#define CFG1_MODE BIT(29)
+
+struct mux_intel_usb {
+ struct device *dev;
+ void __iomem *regs;
+};
+
+static int mux_intel_usb_set(struct mux_control *mux_ctrl, int state)
+{
+ struct mux_intel_usb *mux = mux_chip_priv(mux_ctrl->chip);
+ u32 val;
+
+ dev_info(mux->dev, "Intel USB mux set called");
+
+ switch (state) {
+ case INTEL_USB_MUX_STATE_HOST:
+ val = CFG0_SW_IDPIN_EN | CFG0_SW_DRD_STATIC_HOST;
+ break;
+ case INTEL_USB_MUX_STATE_DEVICE:
+ val = CFG0_SW_IDPIN_EN | CFG0_SW_IDPIN | CFG0_SW_VBUS_VALID |
+ CFG0_SW_DRD_STATIC_DEV;
+ break;
+ default:
+ return 0;
+ };
+
+ writel(val, mux->regs);
+
+ return 0;
+}
+
+static const struct mux_control_ops mux_intel_usb_ops = {
+ .set = mux_intel_usb_set,
+};
+
+static int mux_intel_usb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mux_chip *mux_chip;
+ struct mux_intel_usb *mux;
+ struct resource *res;
+ int ret;
+
+ mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux));
+ if (IS_ERR(mux_chip))
+ return PTR_ERR(mux_chip);
+
+ mux = mux_chip_priv(mux_chip);
+ mux->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get mem resource\n");
+ return -ENXIO;
+ }
+
+ mux->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
+ if (!mux->regs) {
+ dev_err(mux->dev, "mux regs io remap failed\n");
+ return -ENOMEM;
+ }
+
+ mux_chip->ops = &mux_intel_usb_ops;
+ mux_chip->mux->states = INTEL_USB_MUX_STATE_MAX;
+ mux_chip->mux->idle_state = MUX_IDLE_AS_IS;
+
+ ret = devm_mux_chip_register(dev, mux_chip);
+ if (ret < 0)
+ return ret;
+
+ dev_info(dev, "%u-way mux-controller registered\n",
+ mux_chip->mux->states);
+
+ return 0;
+}
+
+static const struct platform_device_id mux_intel_usb_id[] = {
+ { .name = "intel-usb-mux", },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, mux_intel_usb_id);
+
+static struct platform_driver mux_intel_usb_driver = {
+ .driver = {
+ .name = "intel-usb-mux",
+ },
+ .probe = mux_intel_usb_probe,
+ .id_table = mux_intel_usb_id,
+};
+module_platform_driver(mux_intel_usb_driver);
+
+MODULE_DESCRIPTION("Intel USB multiplexer driver");
+MODULE_AUTHOR("Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@intel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mux/mux-intel-usb.h b/include/linux/mux/mux-intel-usb.h
new file mode 100644
index 0000000..e77516c
--- /dev/null
+++ b/include/linux/mux/mux-intel-usb.h
@@ -0,0 +1,22 @@
+/*
+ * Intel USB multiplexer header file
+ *
+ * Copyright (C) 2017 Intel Corporation
+ *
+ * Author: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_MUX_MUX_INTEL_USB_H
+#define _LINUX_MUX_MUX_INTEL_USB_H
+
+#include <linux/mux/consumer.h>
+
+#define INTEL_USB_MUX_STATE_HOST 0
+#define INTEL_USB_MUX_STATE_DEVICE 1
+#define INTEL_USB_MUX_STATE_MAX 2
+
+#endif /* _LINUX_MUX_MUX_INTEL_USB_H */
--
2.7.4
\
 
 \ /
  Last update: 2017-05-30 02:52    [W:0.126 / U:0.660 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site