* [PATCH v2 1/2] extcon: add driver for TI TUSB320 @ 2020-10-12 14:47 ` Michael Auchter 2020-10-12 14:47 ` [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 Michael Auchter ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Michael Auchter @ 2020-10-12 14:47 UTC (permalink / raw) To: MyungJoo Ham, Chanwoo Choi; +Cc: Michael Auchter, linux-kernel This patch adds an extcon driver for the TI TUSB320 USB Type-C device. This can be used to detect whether the port is configured as a downstream or upstream facing port. Signed-off-by: Michael Auchter <michael.auchter@ni.com> --- Changes since v1: - Drop license text that's redundant with SPDX tag - Cleanup, sort list of includes - Add additional register defines - Switch to use regmap API - Fix Kconfig to depend on I2C, not GPIOLIB drivers/extcon/Kconfig | 8 ++ drivers/extcon/Makefile | 1 + drivers/extcon/extcon-usbc-tusb320.c | 191 +++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 drivers/extcon/extcon-usbc-tusb320.c diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index aac507bff135..af58ebca2bf6 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -186,4 +186,12 @@ config EXTCON_USBC_CROS_EC Say Y here to enable USB Type C cable detection extcon support when using Chrome OS EC based USB Type-C ports. +config EXTCON_USBC_TUSB320 + tristate "TI TUSB320 USB-C extcon support" + depends on I2C + select REGMAP_I2C + help + Say Y here to enable support for USB Type C cable detection extcon + support using a TUSB320. + endif diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 52096fd8a216..fe10a1b7d18b 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o +obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c new file mode 100644 index 000000000000..93f1843ca89b --- /dev/null +++ b/drivers/extcon/extcon-usbc-tusb320.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * drivers/extcon/extcon-tusb320.c - TUSB320 extcon driver + * + * Copyright (C) 2020 National Instruments Corporation + * Author: Michael Auchter <michael.auchter@ni.com> + */ + +#include <linux/extcon-provider.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/regmap.h> + +#define TUSB320_REG9 0x9 +#define TUSB320_REG9_ATTACHED_STATE_SHIFT 6 +#define TUSB320_REG9_ATTACHED_STATE_MASK 0x3 +#define TUSB320_REG9_CABLE_DIRECTION BIT(5) +#define TUSB320_REG9_INTERRUPT_STATUS BIT(4) +#define TUSB320_ATTACHED_STATE_NONE 0x0 +#define TUSB320_ATTACHED_STATE_DFP 0x1 +#define TUSB320_ATTACHED_STATE_UFP 0x2 +#define TUSB320_ATTACHED_STATE_ACC 0x3 + +struct tusb320_priv { + struct device *dev; + struct regmap *regmap; + struct extcon_dev *edev; +}; + +static const char * const tusb_attached_states[] = { + [TUSB320_ATTACHED_STATE_NONE] = "not attached", + [TUSB320_ATTACHED_STATE_DFP] = "downstream facing port", + [TUSB320_ATTACHED_STATE_UFP] = "upstream facing port", + [TUSB320_ATTACHED_STATE_ACC] = "accessory", +}; + +static const unsigned int tusb320_extcon_cable[] = { + EXTCON_USB, + EXTCON_USB_HOST, + EXTCON_NONE, +}; + +static int tusb320_check_signature(struct tusb320_priv *priv) +{ + static const char sig[] = { '\0', 'T', 'U', 'S', 'B', '3', '2', '0' }; + unsigned val; + int i, ret; + + for (i = 0; i < sizeof(sig); i++) { + ret = regmap_read(priv->regmap, sizeof(sig) - 1 - i, &val); + if (ret < 0) + return ret; + if (val != sig[i]) { + dev_err(priv->dev, "signature mismatch!\n"); + return -ENODEV; + } + } + + return 0; +} + +static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) +{ + struct tusb320_priv *priv = dev_id; + int state, polarity; + unsigned reg; + + if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { + dev_err(priv->dev, "error during i2c read!\n"); + return IRQ_NONE; + } + + if (!(reg & TUSB320_REG9_INTERRUPT_STATUS)) + return IRQ_NONE; + + state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) & + TUSB320_REG9_ATTACHED_STATE_MASK; + polarity = !!(reg & TUSB320_REG9_CABLE_DIRECTION); + + dev_dbg(priv->dev, "attached state: %s, polarity: %d\n", + tusb_attached_states[state], polarity); + + extcon_set_state(priv->edev, EXTCON_USB, + state == TUSB320_ATTACHED_STATE_UFP); + extcon_set_state(priv->edev, EXTCON_USB_HOST, + state == TUSB320_ATTACHED_STATE_DFP); + extcon_set_property(priv->edev, EXTCON_USB, + EXTCON_PROP_USB_TYPEC_POLARITY, + (union extcon_property_value)polarity); + extcon_set_property(priv->edev, EXTCON_USB_HOST, + EXTCON_PROP_USB_TYPEC_POLARITY, + (union extcon_property_value)polarity); + extcon_sync(priv->edev, EXTCON_USB); + extcon_sync(priv->edev, EXTCON_USB_HOST); + + regmap_write(priv->regmap, TUSB320_REG9, reg); + + return IRQ_HANDLED; +} + +static const struct regmap_config tusb320_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int tusb320_extcon_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tusb320_priv *priv; + int ret; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->dev = &client->dev; + + priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config); + if (IS_ERR(priv->regmap)) + return PTR_ERR(priv->regmap); + + ret = tusb320_check_signature(priv); + if (ret) + return ret; + + priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); + if (IS_ERR(priv->edev)) { + dev_err(priv->dev, "failed to allocate extcon device\n"); + return -ENOMEM; + } + + ret = devm_extcon_dev_register(priv->dev, priv->edev); + if (ret < 0) { + dev_err(priv->dev, "failed to register extcon device\n"); + return ret; + } + + extcon_set_property_capability(priv->edev, EXTCON_USB, + EXTCON_PROP_USB_TYPEC_POLARITY); + extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, + EXTCON_PROP_USB_TYPEC_POLARITY); + + /* update initial state */ + tusb320_irq_handler(client->irq, priv); + + ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, + tusb320_irq_handler, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + dev_name(priv->dev), priv); + + return ret; +} + +static const struct of_device_id tusb320_extcon_dt_match[] = { + { .compatible = "ti,tusb320", }, + { } +}; +MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match); + +static const struct i2c_device_id tusb320_i2c_id[] = { + { "tusb320", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tusb320_i2c_id); + +static struct i2c_driver tusb320_extcon_driver = { + .probe = tusb320_extcon_probe, + .driver = { + .name = "extcon-tusb320", + .of_match_table = tusb320_extcon_dt_match, + }, +}; + +static int __init tusb320_init(void) +{ + return i2c_add_driver(&tusb320_extcon_driver); +} +subsys_initcall(tusb320_init); + +static void __exit tusb320_exit(void) +{ + i2c_del_driver(&tusb320_extcon_driver); +} +module_exit(tusb320_exit); + +MODULE_AUTHOR("Michael Auchter <michael.auchter@ni.com>"); +MODULE_DESCRIPTION("TI TUSB320 extcon driver"); +MODULE_LICENSE("GPL v2"); -- 2.25.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 2020-10-12 14:47 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 Michael Auchter @ 2020-10-12 14:47 ` Michael Auchter 2020-10-13 17:15 ` Rob Herring 2020-10-13 1:44 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 kernel test robot 2020-10-14 3:51 ` Chanwoo Choi 2 siblings, 1 reply; 6+ messages in thread From: Michael Auchter @ 2020-10-12 14:47 UTC (permalink / raw) To: MyungJoo Ham, Chanwoo Choi, Rob Herring, Michael Auchter Cc: linux-kernel, devicetree Add a device tree binding for the TI TUSB320. Signed-off-by: Michael Auchter <michael.auchter@ni.com> --- Changes since v1: - use tusb320 instead of extcon in the unit name .../bindings/extcon/extcon-usbc-tusb320.yaml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/extcon/extcon-usbc-tusb320.yaml diff --git a/Documentation/devicetree/bindings/extcon/extcon-usbc-tusb320.yaml b/Documentation/devicetree/bindings/extcon/extcon-usbc-tusb320.yaml new file mode 100644 index 000000000000..9875b4d5c356 --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/extcon-usbc-tusb320.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/extcon/extcon-usbc-tusb320.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI TUSB320 USB Type-C CC Logic controller + +maintainers: + - Michael Auchter <michael.auchter@ni.com> + +properties: + compatible: + const: ti,tusb320 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + tusb320@61 { + compatible = "ti,tusb320"; + reg = <0x61>; + interrupt-parent = <&gpio>; + interrupts = <27 1>; + }; + }; +... -- 2.25.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 2020-10-12 14:47 ` [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 Michael Auchter @ 2020-10-13 17:15 ` Rob Herring 0 siblings, 0 replies; 6+ messages in thread From: Rob Herring @ 2020-10-13 17:15 UTC (permalink / raw) To: Michael Auchter Cc: Chanwoo Choi, devicetree, MyungJoo Ham, Rob Herring, linux-kernel On Mon, 12 Oct 2020 09:47:53 -0500, Michael Auchter wrote: > Add a device tree binding for the TI TUSB320. > > Signed-off-by: Michael Auchter <michael.auchter@ni.com> > --- > Changes since v1: > - use tusb320 instead of extcon in the unit name > > .../bindings/extcon/extcon-usbc-tusb320.yaml | 41 +++++++++++++++++++ > 1 file changed, 41 insertions(+) > create mode 100644 Documentation/devicetree/bindings/extcon/extcon-usbc-tusb320.yaml > Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] extcon: add driver for TI TUSB320 2020-10-12 14:47 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 Michael Auchter 2020-10-12 14:47 ` [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 Michael Auchter @ 2020-10-13 1:44 ` kernel test robot 2020-10-14 3:51 ` Chanwoo Choi 2 siblings, 0 replies; 6+ messages in thread From: kernel test robot @ 2020-10-13 1:44 UTC (permalink / raw) To: Michael Auchter, MyungJoo Ham, Chanwoo Choi Cc: kbuild-all, clang-built-linux, Michael Auchter, linux-kernel [-- Attachment #1: Type: text/plain, Size: 9158 bytes --] Hi Michael, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on chanwoo-extcon/extcon-next] [also build test WARNING on v5.9 next-20201012] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Michael-Auchter/extcon-add-driver-for-TI-TUSB320/20201012-232733 base: https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git extcon-next config: s390-randconfig-r022-20201013 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project a324d8f964bf421fa7d8b882b0f64ead28c4149c) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install s390 cross compiling tool for clang build # apt-get install binutils-s390x-linux-gnu # https://github.com/0day-ci/linux/commit/5065d684df89cf11f57743f3c1440e6bd09054ea git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Michael-Auchter/extcon-add-driver-for-TI-TUSB320/20201012-232733 git checkout 5065d684df89cf11f57743f3c1440e6bd09054ea # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) ^ include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32' ___constant_swab32(x) : \ ^ include/uapi/linux/swab.h:19:12: note: expanded from macro '___constant_swab32' (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ ^ In file included from drivers/extcon/extcon-usbc-tusb320.c:13: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/s390/include/asm/io.h:72: include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) ^ include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32' ___constant_swab32(x) : \ ^ include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32' (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ ^ In file included from drivers/extcon/extcon-usbc-tusb320.c:13: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/s390/include/asm/io.h:72: include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) ^ include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32' ___constant_swab32(x) : \ ^ include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32' (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ ^ In file included from drivers/extcon/extcon-usbc-tusb320.c:13: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/s390/include/asm/io.h:72: include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) ^ include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32' ___constant_swab32(x) : \ ^ include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32' (((__u32)(x) & (__u32)0xff000000UL) >> 24))) ^ In file included from drivers/extcon/extcon-usbc-tusb320.c:13: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/s390/include/asm/io.h:72: include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); ~~~~~~~~~~ ^ include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) ^ include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32' __fswab32(x)) ^ In file included from drivers/extcon/extcon-usbc-tusb320.c:13: In file included from include/linux/irq.h:20: In file included from include/linux/io.h:13: In file included from arch/s390/include/asm/io.h:72: include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writeb(value, PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); ~~~~~~~~~~ ^ include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] readsb(PCI_IOBASE + addr, buffer, count); ~~~~~~~~~~ ^ include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] readsw(PCI_IOBASE + addr, buffer, count); ~~~~~~~~~~ ^ include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] readsl(PCI_IOBASE + addr, buffer, count); ~~~~~~~~~~ ^ include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] writesb(PCI_IOBASE + addr, buffer, count); ~~~~~~~~~~ ^ include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] writesw(PCI_IOBASE + addr, buffer, count); ~~~~~~~~~~ ^ include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] writesl(PCI_IOBASE + addr, buffer, count); ~~~~~~~~~~ ^ >> drivers/extcon/extcon-usbc-tusb320.c:163:35: warning: unused variable 'tusb320_i2c_id' [-Wunused-const-variable] static const struct i2c_device_id tusb320_i2c_id[] = { ^ 21 warnings generated. vim +/tusb320_i2c_id +163 drivers/extcon/extcon-usbc-tusb320.c 162 > 163 static const struct i2c_device_id tusb320_i2c_id[] = { 164 { "tusb320", 0 }, 165 { } 166 }; 167 MODULE_DEVICE_TABLE(i2c, tusb320_i2c_id); 168 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 19075 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] extcon: add driver for TI TUSB320 2020-10-12 14:47 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 Michael Auchter 2020-10-12 14:47 ` [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 Michael Auchter 2020-10-13 1:44 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 kernel test robot @ 2020-10-14 3:51 ` Chanwoo Choi 2020-10-15 13:40 ` Michael Auchter 2 siblings, 1 reply; 6+ messages in thread From: Chanwoo Choi @ 2020-10-14 3:51 UTC (permalink / raw) To: Michael Auchter, MyungJoo Ham; +Cc: linux-kernel Hi, Looks good to me. I add some comment. Please check them. On 10/12/20 11:47 PM, Michael Auchter wrote: > This patch adds an extcon driver for the TI TUSB320 USB Type-C device. > This can be used to detect whether the port is configured as a > downstream or upstream facing port. > > Signed-off-by: Michael Auchter <michael.auchter@ni.com> > --- > Changes since v1: > - Drop license text that's redundant with SPDX tag > - Cleanup, sort list of includes > - Add additional register defines > - Switch to use regmap API > - Fix Kconfig to depend on I2C, not GPIOLIB > > drivers/extcon/Kconfig | 8 ++ > drivers/extcon/Makefile | 1 + > drivers/extcon/extcon-usbc-tusb320.c | 191 +++++++++++++++++++++++++++ > 3 files changed, 200 insertions(+) > create mode 100644 drivers/extcon/extcon-usbc-tusb320.c > > diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig > index aac507bff135..af58ebca2bf6 100644 > --- a/drivers/extcon/Kconfig > +++ b/drivers/extcon/Kconfig > @@ -186,4 +186,12 @@ config EXTCON_USBC_CROS_EC > Say Y here to enable USB Type C cable detection extcon support when > using Chrome OS EC based USB Type-C ports. > > +config EXTCON_USBC_TUSB320 > + tristate "TI TUSB320 USB-C extcon support" > + depends on I2C > + select REGMAP_I2C > + help > + Say Y here to enable support for USB Type C cable detection extcon > + support using a TUSB320. > + > endif > diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile > index 52096fd8a216..fe10a1b7d18b 100644 > --- a/drivers/extcon/Makefile > +++ b/drivers/extcon/Makefile > @@ -25,3 +25,4 @@ obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o > obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o > obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o > obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o > +obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o > diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c > new file mode 100644 > index 000000000000..93f1843ca89b > --- /dev/null > +++ b/drivers/extcon/extcon-usbc-tusb320.c > @@ -0,0 +1,191 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/** > + * drivers/extcon/extcon-tusb320.c - TUSB320 extcon driver > + * > + * Copyright (C) 2020 National Instruments Corporation > + * Author: Michael Auchter <michael.auchter@ni.com> > + */ > + > +#include <linux/extcon-provider.h> > +#include <linux/i2c.h> > +#include <linux/init.h> > +#include <linux/interrupt.h> > +#include <linux/irq.h> irq.h doesn't be needed. Better to remove irq.h. > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/regmap.h> > + > +#define TUSB320_REG9 0x9 > +#define TUSB320_REG9_ATTACHED_STATE_SHIFT 6 > +#define TUSB320_REG9_ATTACHED_STATE_MASK 0x3 > +#define TUSB320_REG9_CABLE_DIRECTION BIT(5) > +#define TUSB320_REG9_INTERRUPT_STATUS BIT(4) > +#define TUSB320_ATTACHED_STATE_NONE 0x0 > +#define TUSB320_ATTACHED_STATE_DFP 0x1 > +#define TUSB320_ATTACHED_STATE_UFP 0x2 > +#define TUSB320_ATTACHED_STATE_ACC 0x3 Above definition contain the 'space' for indentation. Please edit it as following: -#define TUSB320_ATTACHED_STATE_DFP 0x1 -#define TUSB320_ATTACHED_STATE_UFP 0x2 -#define TUSB320_ATTACHED_STATE_ACC 0x3 +#define TUSB320_ATTACHED_STATE_DFP 0x1 +#define TUSB320_ATTACHED_STATE_UFP 0x2 +#define TUSB320_ATTACHED_STATE_ACC 0x3 > + > +struct tusb320_priv { > + struct device *dev; > + struct regmap *regmap; > + struct extcon_dev *edev; > +}; > + > +static const char * const tusb_attached_states[] = { > + [TUSB320_ATTACHED_STATE_NONE] = "not attached", > + [TUSB320_ATTACHED_STATE_DFP] = "downstream facing port", > + [TUSB320_ATTACHED_STATE_UFP] = "upstream facing port", > + [TUSB320_ATTACHED_STATE_ACC] = "accessory", > +}; > + > +static const unsigned int tusb320_extcon_cable[] = { > + EXTCON_USB, > + EXTCON_USB_HOST, > + EXTCON_NONE, > +}; > + > +static int tusb320_check_signature(struct tusb320_priv *priv) > +{ > + static const char sig[] = { '\0', 'T', 'U', 'S', 'B', '3', '2', '0' }; > + unsigned val; > + int i, ret; > + > + for (i = 0; i < sizeof(sig); i++) { > + ret = regmap_read(priv->regmap, sizeof(sig) - 1 - i, &val); > + if (ret < 0) > + return ret; > + if (val != sig[i]) { > + dev_err(priv->dev, "signature mismatch!\n"); > + return -ENODEV; > + } > + } > + > + return 0; > +} > + > +static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) > +{ > + struct tusb320_priv *priv = dev_id; > + int state, polarity; > + unsigned reg; > + > + if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { > + dev_err(priv->dev, "error during i2c read!\n"); > + return IRQ_NONE; > + } > + > + if (!(reg & TUSB320_REG9_INTERRUPT_STATUS)) > + return IRQ_NONE; > + > + state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) & > + TUSB320_REG9_ATTACHED_STATE_MASK; > + polarity = !!(reg & TUSB320_REG9_CABLE_DIRECTION); > + > + dev_dbg(priv->dev, "attached state: %s, polarity: %d\n", > + tusb_attached_states[state], polarity); > + > + extcon_set_state(priv->edev, EXTCON_USB, > + state == TUSB320_ATTACHED_STATE_UFP); > + extcon_set_state(priv->edev, EXTCON_USB_HOST, > + state == TUSB320_ATTACHED_STATE_DFP); > + extcon_set_property(priv->edev, EXTCON_USB, > + EXTCON_PROP_USB_TYPEC_POLARITY, > + (union extcon_property_value)polarity); > + extcon_set_property(priv->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_TYPEC_POLARITY, > + (union extcon_property_value)polarity); > + extcon_sync(priv->edev, EXTCON_USB); > + extcon_sync(priv->edev, EXTCON_USB_HOST); > + > + regmap_write(priv->regmap, TUSB320_REG9, reg); > + > + return IRQ_HANDLED; > +} > + > +static const struct regmap_config tusb320_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > +}; > + > +static int tusb320_extcon_probe(struct i2c_client *client, > + const struct i2c_device_id *id) > +{ > + struct tusb320_priv *priv; > + int ret; > + > + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + priv->dev = &client->dev; > + > + priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config); > + if (IS_ERR(priv->regmap)) > + return PTR_ERR(priv->regmap); > + > + ret = tusb320_check_signature(priv); > + if (ret) > + return ret; > + > + priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); > + if (IS_ERR(priv->edev)) { > + dev_err(priv->dev, "failed to allocate extcon device\n"); > + return -ENOMEM; Use 'return PTR_ERR(priv->edev)' instead of '-ENOMEM'. > + } > + > + ret = devm_extcon_dev_register(priv->dev, priv->edev); > + if (ret < 0) { > + dev_err(priv->dev, "failed to register extcon device\n"); > + return ret; > + } > + > + extcon_set_property_capability(priv->edev, EXTCON_USB, > + EXTCON_PROP_USB_TYPEC_POLARITY); > + extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_TYPEC_POLARITY); > + > + /* update initial state */ > + tusb320_irq_handler(client->irq, priv); > + > + ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, > + tusb320_irq_handler, > + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, > + dev_name(priv->dev), priv); > + > + return ret; > +} > + > +static const struct of_device_id tusb320_extcon_dt_match[] = { > + { .compatible = "ti,tusb320", }, > + { } > +}; > +MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match); > + > +static const struct i2c_device_id tusb320_i2c_id[] = { > + { "tusb320", 0 }, > + { } > +}; > +MODULE_DEVICE_TABLE(i2c, tusb320_i2c_id); tusb320_i2c_id is not used on this driver. > + > +static struct i2c_driver tusb320_extcon_driver = { > + .probe = tusb320_extcon_probe, > + .driver = { > + .name = "extcon-tusb320", > + .of_match_table = tusb320_extcon_dt_match, > + }, > +}; > + > +static int __init tusb320_init(void) > +{ > + return i2c_add_driver(&tusb320_extcon_driver); > +} > +subsys_initcall(tusb320_init); > + > +static void __exit tusb320_exit(void) > +{ > + i2c_del_driver(&tusb320_extcon_driver); > +} > +module_exit(tusb320_exit); > + > +MODULE_AUTHOR("Michael Auchter <michael.auchter@ni.com>"); > +MODULE_DESCRIPTION("TI TUSB320 extcon driver"); > +MODULE_LICENSE("GPL v2"); > -- Best Regards, Chanwoo Choi Samsung Electronics ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Re: [PATCH v2 1/2] extcon: add driver for TI TUSB320 2020-10-14 3:51 ` Chanwoo Choi @ 2020-10-15 13:40 ` Michael Auchter 0 siblings, 0 replies; 6+ messages in thread From: Michael Auchter @ 2020-10-15 13:40 UTC (permalink / raw) To: Chanwoo Choi; +Cc: MyungJoo Ham, linux-kernel On Wed, Oct 14, 2020 at 12:51:26PM +0900, Chanwoo Choi wrote: > Hi, > > Looks good to me. I add some comment. Please check them. Thanks for the prompt review! I'll address these and send out a v3. Cheers, Michael > On 10/12/20 11:47 PM, Michael Auchter wrote: > > This patch adds an extcon driver for the TI TUSB320 USB Type-C device. > > This can be used to detect whether the port is configured as a > > downstream or upstream facing port. > > > > Signed-off-by: Michael Auchter <michael.auchter@ni.com> > > --- > > Changes since v1: > > - Drop license text that's redundant with SPDX tag > > - Cleanup, sort list of includes > > - Add additional register defines > > - Switch to use regmap API > > - Fix Kconfig to depend on I2C, not GPIOLIB > > > > drivers/extcon/Kconfig | 8 ++ > > drivers/extcon/Makefile | 1 + > > drivers/extcon/extcon-usbc-tusb320.c | 191 +++++++++++++++++++++++++++ > > 3 files changed, 200 insertions(+) > > create mode 100644 drivers/extcon/extcon-usbc-tusb320.c > > > > diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig > > index aac507bff135..af58ebca2bf6 100644 > > --- a/drivers/extcon/Kconfig > > +++ b/drivers/extcon/Kconfig > > @@ -186,4 +186,12 @@ config EXTCON_USBC_CROS_EC > > Say Y here to enable USB Type C cable detection extcon support when > > using Chrome OS EC based USB Type-C ports. > > > > +config EXTCON_USBC_TUSB320 > > + tristate "TI TUSB320 USB-C extcon support" > > + depends on I2C > > + select REGMAP_I2C > > + help > > + Say Y here to enable support for USB Type C cable detection extcon > > + support using a TUSB320. > > + > > endif > > diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile > > index 52096fd8a216..fe10a1b7d18b 100644 > > --- a/drivers/extcon/Makefile > > +++ b/drivers/extcon/Makefile > > @@ -25,3 +25,4 @@ obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o > > obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o > > obj-$(CONFIG_EXTCON_USB_GPIO) += extcon-usb-gpio.o > > obj-$(CONFIG_EXTCON_USBC_CROS_EC) += extcon-usbc-cros-ec.o > > +obj-$(CONFIG_EXTCON_USBC_TUSB320) += extcon-usbc-tusb320.o > > diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c > > new file mode 100644 > > index 000000000000..93f1843ca89b > > --- /dev/null > > +++ b/drivers/extcon/extcon-usbc-tusb320.c > > @@ -0,0 +1,191 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/** > > + * drivers/extcon/extcon-tusb320.c - TUSB320 extcon driver > > + * > > + * Copyright (C) 2020 National Instruments Corporation > > + * Author: Michael Auchter <michael.auchter@ni.com> > > + */ > > + > > +#include <linux/extcon-provider.h> > > +#include <linux/i2c.h> > > +#include <linux/init.h> > > +#include <linux/interrupt.h> > > +#include <linux/irq.h> > > irq.h doesn't be needed. Better to remove irq.h. > > > +#include <linux/kernel.h> > > +#include <linux/module.h> > > +#include <linux/regmap.h> > > + > > +#define TUSB320_REG9 0x9 > > +#define TUSB320_REG9_ATTACHED_STATE_SHIFT 6 > > +#define TUSB320_REG9_ATTACHED_STATE_MASK 0x3 > > +#define TUSB320_REG9_CABLE_DIRECTION BIT(5) > > +#define TUSB320_REG9_INTERRUPT_STATUS BIT(4) > > +#define TUSB320_ATTACHED_STATE_NONE 0x0 > > +#define TUSB320_ATTACHED_STATE_DFP 0x1 > > +#define TUSB320_ATTACHED_STATE_UFP 0x2 > > +#define TUSB320_ATTACHED_STATE_ACC 0x3 > > Above definition contain the 'space' for indentation. > Please edit it as following: > > > -#define TUSB320_ATTACHED_STATE_DFP 0x1 > -#define TUSB320_ATTACHED_STATE_UFP 0x2 > -#define TUSB320_ATTACHED_STATE_ACC 0x3 > +#define TUSB320_ATTACHED_STATE_DFP 0x1 > +#define TUSB320_ATTACHED_STATE_UFP 0x2 > +#define TUSB320_ATTACHED_STATE_ACC 0x3 > > > > + > > +struct tusb320_priv { > > + struct device *dev; > > + struct regmap *regmap; > > + struct extcon_dev *edev; > > +}; > > + > > +static const char * const tusb_attached_states[] = { > > + [TUSB320_ATTACHED_STATE_NONE] = "not attached", > > + [TUSB320_ATTACHED_STATE_DFP] = "downstream facing port", > > + [TUSB320_ATTACHED_STATE_UFP] = "upstream facing port", > > + [TUSB320_ATTACHED_STATE_ACC] = "accessory", > > +}; > > + > > +static const unsigned int tusb320_extcon_cable[] = { > > + EXTCON_USB, > > + EXTCON_USB_HOST, > > + EXTCON_NONE, > > +}; > > + > > +static int tusb320_check_signature(struct tusb320_priv *priv) > > +{ > > + static const char sig[] = { '\0', 'T', 'U', 'S', 'B', '3', '2', '0' }; > > + unsigned val; > > + int i, ret; > > + > > + for (i = 0; i < sizeof(sig); i++) { > > + ret = regmap_read(priv->regmap, sizeof(sig) - 1 - i, &val); > > + if (ret < 0) > > + return ret; > > + if (val != sig[i]) { > > + dev_err(priv->dev, "signature mismatch!\n"); > > + return -ENODEV; > > + } > > + } > > + > > + return 0; > > +} > > + > > +static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) > > +{ > > + struct tusb320_priv *priv = dev_id; > > + int state, polarity; > > + unsigned reg; > > + > > + if (regmap_read(priv->regmap, TUSB320_REG9, ®)) { > > + dev_err(priv->dev, "error during i2c read!\n"); > > + return IRQ_NONE; > > + } > > + > > + if (!(reg & TUSB320_REG9_INTERRUPT_STATUS)) > > + return IRQ_NONE; > > + > > + state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) & > > + TUSB320_REG9_ATTACHED_STATE_MASK; > > + polarity = !!(reg & TUSB320_REG9_CABLE_DIRECTION); > > + > > + dev_dbg(priv->dev, "attached state: %s, polarity: %d\n", > > + tusb_attached_states[state], polarity); > > + > > + extcon_set_state(priv->edev, EXTCON_USB, > > + state == TUSB320_ATTACHED_STATE_UFP); > > + extcon_set_state(priv->edev, EXTCON_USB_HOST, > > + state == TUSB320_ATTACHED_STATE_DFP); > > + extcon_set_property(priv->edev, EXTCON_USB, > > + EXTCON_PROP_USB_TYPEC_POLARITY, > > + (union extcon_property_value)polarity); > > + extcon_set_property(priv->edev, EXTCON_USB_HOST, > > + EXTCON_PROP_USB_TYPEC_POLARITY, > > + (union extcon_property_value)polarity); > > + extcon_sync(priv->edev, EXTCON_USB); > > + extcon_sync(priv->edev, EXTCON_USB_HOST); > > + > > + regmap_write(priv->regmap, TUSB320_REG9, reg); > > + > > + return IRQ_HANDLED; > > +} > > + > > +static const struct regmap_config tusb320_regmap_config = { > > + .reg_bits = 8, > > + .val_bits = 8, > > +}; > > + > > +static int tusb320_extcon_probe(struct i2c_client *client, > > + const struct i2c_device_id *id) > > +{ > > + struct tusb320_priv *priv; > > + int ret; > > + > > + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); > > + if (!priv) > > + return -ENOMEM; > > + priv->dev = &client->dev; > > + > > + priv->regmap = devm_regmap_init_i2c(client, &tusb320_regmap_config); > > + if (IS_ERR(priv->regmap)) > > + return PTR_ERR(priv->regmap); > > + > > + ret = tusb320_check_signature(priv); > > + if (ret) > > + return ret; > > + > > + priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable); > > + if (IS_ERR(priv->edev)) { > > + dev_err(priv->dev, "failed to allocate extcon device\n"); > > + return -ENOMEM; > > Use 'return PTR_ERR(priv->edev)' instead of '-ENOMEM'. > > > + } > > + > > + ret = devm_extcon_dev_register(priv->dev, priv->edev); > > + if (ret < 0) { > > + dev_err(priv->dev, "failed to register extcon device\n"); > > + return ret; > > + } > > + > > + extcon_set_property_capability(priv->edev, EXTCON_USB, > > + EXTCON_PROP_USB_TYPEC_POLARITY); > > + extcon_set_property_capability(priv->edev, EXTCON_USB_HOST, > > + EXTCON_PROP_USB_TYPEC_POLARITY); > > + > > + /* update initial state */ > > + tusb320_irq_handler(client->irq, priv); > > + > > + ret = devm_request_threaded_irq(priv->dev, client->irq, NULL, > > + tusb320_irq_handler, > > + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, > > + dev_name(priv->dev), priv); > > + > > + return ret; > > +} > > + > > +static const struct of_device_id tusb320_extcon_dt_match[] = { > > + { .compatible = "ti,tusb320", }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match); > > + > > +static const struct i2c_device_id tusb320_i2c_id[] = { > > + { "tusb320", 0 }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(i2c, tusb320_i2c_id); > > tusb320_i2c_id is not used on this driver. > > > + > > +static struct i2c_driver tusb320_extcon_driver = { > > + .probe = tusb320_extcon_probe, > > + .driver = { > > + .name = "extcon-tusb320", > > + .of_match_table = tusb320_extcon_dt_match, > > + }, > > +}; > > + > > +static int __init tusb320_init(void) > > +{ > > + return i2c_add_driver(&tusb320_extcon_driver); > > +} > > +subsys_initcall(tusb320_init); > > + > > +static void __exit tusb320_exit(void) > > +{ > > + i2c_del_driver(&tusb320_extcon_driver); > > +} > > +module_exit(tusb320_exit); > > + > > +MODULE_AUTHOR("Michael Auchter <michael.auchter@ni.com>"); > > +MODULE_DESCRIPTION("TI TUSB320 extcon driver"); > > +MODULE_LICENSE("GPL v2"); > > > > -- > Best Regards, > Chanwoo Choi > Samsung Electronics ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-10-15 13:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CGME20201012145748epcas1p13f59fc2f062133e4988bb1d565408ae9@epcas1p1.samsung.com>
2020-10-12 14:47 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 Michael Auchter
2020-10-12 14:47 ` [PATCH v2 2/2] dt-bindings: extcon: add binding for TUSB320 Michael Auchter
2020-10-13 17:15 ` Rob Herring
2020-10-13 1:44 ` [PATCH v2 1/2] extcon: add driver for TI TUSB320 kernel test robot
2020-10-14 3:51 ` Chanwoo Choi
2020-10-15 13:40 ` Michael Auchter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox