lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <550ABBE5.6040908@samsung.com>
Date:	Thu, 19 Mar 2015 13:07:01 +0100
From:	Robert Baldyga <r.baldyga@...sung.com>
To:	George Cherian <gcherianv@...il.com>
Cc:	balbi@...com, gregkh@...uxfoundation.org, myungjoo.ham@...sung.com,
	cw00.choi@...sung.com, linux-usb@...r.kernel.org,
	linux-kernel@...r.kernel.org, m.szyprowski@...sung.com,
	Łukasz Stelmach 
	<l.stelmach@...sung.com>
Subject: Re: [RFC 01/19] extcon: add extcon-odroid-usbotg driver

Hi George,

On 03/19/2015 09:50 AM, George Cherian wrote:
> Hi Robert,
> 
> This looks like a extcon driver based on gpio for USB.
> 
> Roger posted a generic one a while back.
> https://lkml.org/lkml/2015/2/2/187
> 
> Doesn't this serve the purpose rather than adding this driver?

Roger's driver doesn't support VBUS state detection so it cannot handle
situation when USB cable is unpluged. In addition some of Odroid boards
has only VBUS detection (without ID pin), so this driver cannot handle
them at all.

Best regards,
Robert

> 
> On Wed, Mar 18, 2015 at 7:34 PM, Robert Baldyga <r.baldyga@...sung.com> wrote:
>> This patch adds extcon driver for Odroid U3, U3+ and X boards.
>> It recognizes type of USB cable connected to Odroid board basing on
>> two signal lines VBUS_DET and OTG_ID (the second one is present only
>> on Odroid U3+ board).
>>
>> Following table of states presents relationship between this signals
>> and detected cable type:
>>
>> state    | VBUS_DET |  OTG_ID
>> -------------------------------
>> USB      |    H     |    H
>> USB_HOST |    H     |    L
>> disconn. |    L     |    H
>> USB-HOST |    L     |    L
>>
>> This driver is based on extcon-gpio driver.
>>
>> Signed-off-by: Łukasz Stelmach <l.stelmach@...sung.com>
>> Signed-off-by: Robert Baldyga <r.baldyga@...sung.com>
>> ---
>>  drivers/extcon/Kconfig                |   4 +
>>  drivers/extcon/Makefile               |   1 +
>>  drivers/extcon/extcon-odroid-usbotg.c | 256 ++++++++++++++++++++++++++++++++++
>>  3 files changed, 261 insertions(+)
>>  create mode 100644 drivers/extcon/extcon-odroid-usbotg.c
>>
>> diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
>> index 6a1f7de..891dca3 100644
>> --- a/drivers/extcon/Kconfig
>> +++ b/drivers/extcon/Kconfig
>> @@ -93,4 +93,8 @@ config EXTCON_SM5502
>>           Silicon Mitus SM5502. The SM5502 is a USB port accessory
>>           detector and switch.
>>
>> +config EXTCON_ODROID_USBOTG
>> +       tristate "Extcon Odroid U3, U3+, X and XU USB OTG port"
>> +       depends on OF_GPIO
>> +
>>  endif # MULTISTATE_SWITCH
>> diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
>> index 0370b42..514384e 100644
>> --- a/drivers/extcon/Makefile
>> +++ b/drivers/extcon/Makefile
>> @@ -12,3 +12,4 @@ obj-$(CONFIG_EXTCON_MAX8997)  += extcon-max8997.o
>>  obj-$(CONFIG_EXTCON_PALMAS)    += extcon-palmas.o
>>  obj-$(CONFIG_EXTCON_RT8973A)   += extcon-rt8973a.o
>>  obj-$(CONFIG_EXTCON_SM5502)    += extcon-sm5502.o
>> +obj-$(CONFIG_EXTCON_ODROID_USBOTG) += extcon-odroid-usbotg.o
>> diff --git a/drivers/extcon/extcon-odroid-usbotg.c b/drivers/extcon/extcon-odroid-usbotg.c
>> new file mode 100644
>> index 0000000..7f71c48
>> --- /dev/null
>> +++ b/drivers/extcon/extcon-odroid-usbotg.c
>> @@ -0,0 +1,256 @@
>> +/*
>> + *  drivers/extcon/extcon-odroid-usbotg.c
>> + *
>> + *  USB cable extcon driver for Odroid U3, Odroid U3+ and Odroid X
>> + *
>> + * Copyright (C) 2014 Samsung Electronics
>> + * Author: Lukasz Stelmach <l.stelmach@...sung.com>
>> + * Author: Robert Baldyga <r.baldyga@...sung.com>
>> + *
>> + * based on drivers/extcon/extcon-gpio.c
>> + * Copyright (C) 2008 Google, Inc.
>> + * Author: Mike Lockwood <lockwood@...roid.com>
>> + *
>> + * This software is licensed under the terms of the GNU General Public
>> + * License version 2, as published by the Free Software Foundation, and
>> + * may be copied, distributed, and modified under those terms.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/gpio.h>
>> +#include <linux/of_gpio.h>
>> +#include <linux/extcon.h>
>> +#include <linux/extcon/extcon-gpio.h>
>> +#include <linux/delay.h>
>> +
>> +enum {
>> +       EXTCON_CABLE_USB = 0,
>> +       EXTCON_CABLE_USB_HOST,
>> +
>> +       _EXTCON_CABLE_NUM,
>> +};
>> +
>> +static const char * const odroid_usbotg_cable[] = {
>> +       [EXTCON_CABLE_USB] = "USB",
>> +       [EXTCON_CABLE_USB_HOST] = "USB-HOST",
>> +
>> +       NULL,
>> +};
>> +
>> +struct odroid_usbotg_data {
>> +       struct extcon_dev *edev;
>> +       struct gpio_desc *otg_id;
>> +       struct gpio_desc *vbus_det;
>> +       int otg_id_irq;
>> +       int vbus_det_irq;
>> +       unsigned long debounce_ms;
>> +};
>> +
>> +/*
>> + * state    | VBUS_DET |  OTG_ID
>> + * -------------------------------
>> + * USB      |    H     |    H
>> + * USB-HOST |    H     |    L
>> + * disconn. |    L     |    H
>> + * USB-HOST |    L     |    L
>> + *
>> + * Only Odroid U3+ has OTG_ID line. U3 and X versions can detect only
>> + * USB slave cable.
>> + */
>> +
>> +static void odroid_usbotg_detect_cable(struct odroid_usbotg_data *extcon_data)
>> +{
>> +       int state;
>> +
>> +       mdelay(extcon_data->debounce_ms);
>> +
>> +       if (extcon_data->otg_id)
>> +               state = (gpiod_get_value(extcon_data->vbus_det) << 1) |
>> +                       gpiod_get_value(extcon_data->otg_id);
>> +       else
>> +               state = (gpiod_get_value(extcon_data->vbus_det) << 1) | 1;
>> +
>> +       dev_dbg(&extcon_data->edev->dev, "cable state changed to %d\n", state);
>> +
>> +       if (state & 0x1)
>> +               extcon_set_cable_state_(extcon_data->edev,
>> +                       EXTCON_CABLE_USB_HOST, false);
>> +       if (state != 0x3)
>> +               extcon_set_cable_state_(extcon_data->edev,
>> +                       EXTCON_CABLE_USB, false);
>> +
>> +       if (!(state & 0x1))
>> +               extcon_set_cable_state_(extcon_data->edev,
>> +                       EXTCON_CABLE_USB_HOST, true);
>> +       else if (state == 0x3)
>> +               extcon_set_cable_state_(extcon_data->edev,
>> +                       EXTCON_CABLE_USB, true);
>> +}
>> +
>> +static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
>> +{
>> +       struct odroid_usbotg_data *extcon_data = dev_id;
>> +
>> +       odroid_usbotg_detect_cable(extcon_data);
>> +
>> +       return IRQ_HANDLED;
>> +}
>> +
>> +static int odroid_usbotg_parse_dt(struct platform_device *pdev,
>> +                                   struct odroid_usbotg_data *extcon_data)
>> +{
>> +       struct device_node *np = pdev->dev.of_node;
>> +       u32 val;
>> +
>> +       if (!np)
>> +               return -ENODEV;
>> +
>> +       extcon_data->edev->name = np->name;
>> +
>> +       if (of_property_read_u32(np, "debounce", &val) != 0)
>> +               val = 50;
>> +       extcon_data->debounce_ms = val;
>> +
>> +       return 0;
>> +}
>> +
>> +static int odroid_usbotg_probe(struct platform_device *pdev)
>> +{
>> +       struct odroid_usbotg_data *extcon_data;
>> +       int ret = 0;
>> +
>> +       extcon_data = devm_kzalloc(&pdev->dev,
>> +               sizeof(struct odroid_usbotg_data), GFP_KERNEL);
>> +       if (!extcon_data)
>> +               return -ENOMEM;
>> +
>> +       extcon_data->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev),
>> +                                        GFP_KERNEL);
>> +       if (IS_ERR(extcon_data->edev)) {
>> +               dev_err(&pdev->dev, "failed to allocate extcon device\n");
>> +               return -ENOMEM;
>> +       }
>> +       extcon_data->edev->supported_cable = odroid_usbotg_cable;
>> +
>> +       ret = odroid_usbotg_parse_dt(pdev, extcon_data);
>> +       if (IS_ERR_VALUE(ret)) {
>> +               dev_err(&pdev->dev, "failed to get data from device tree\n");
>> +               return ret;
>> +       }
>> +
>> +       /* gpios */
>> +       extcon_data->vbus_det = devm_gpiod_get(&pdev->dev, "vbus-det");
>> +       if (IS_ERR(extcon_data->vbus_det)) {
>> +               dev_err(&pdev->dev, "failed to get vbus_det gpio\n");
>> +               return PTR_ERR(extcon_data->vbus_det);
>> +       }
>> +       extcon_data->otg_id = devm_gpiod_get_optional(&pdev->dev, "otg-id");
>> +
>> +       extcon_data->edev->dev.parent = &pdev->dev;
>> +       ret = extcon_dev_register(extcon_data->edev);
>> +       if (ret < 0)
>> +               return ret;
>> +
>> +       /* irq */
>> +       extcon_data->vbus_det_irq = gpiod_to_irq(extcon_data->vbus_det);
>> +       if (extcon_data->vbus_det_irq < 0) {
>> +               dev_err(&pdev->dev, "failed to get irq from vbus_det\n");
>> +               ret = extcon_data->vbus_det_irq;
>> +               goto err;
>> +       }
>> +       ret = request_threaded_irq(extcon_data->vbus_det_irq, NULL,
>> +                                  gpio_irq_handler, IRQF_ONESHOT |
>> +                                  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>> +                                  pdev->name, extcon_data);
>> +       if (ret < 0) {
>> +               dev_err(&pdev->dev, "failed to request vbus_det irq\n");
>> +               goto err;
>> +       }
>> +
>> +       if (extcon_data->otg_id) {
>> +               extcon_data->otg_id_irq = gpiod_to_irq(extcon_data->otg_id);
>> +               if (extcon_data->otg_id_irq < 0) {
>> +                       dev_err(&pdev->dev, "failed to get irq from otg_id\n");
>> +                       ret = extcon_data->otg_id_irq;
>> +                       goto err;
>> +               }
>> +               ret = request_threaded_irq(extcon_data->otg_id_irq, NULL,
>> +                               gpio_irq_handler, IRQF_ONESHOT |
>> +                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>> +                               pdev->name, extcon_data);
>> +               if (ret < 0) {
>> +                       dev_err(&pdev->dev, "failed to request otg_id irq\n");
>> +                       goto err;
>> +               }
>> +       }
>> +
>> +       platform_set_drvdata(pdev, extcon_data);
>> +       /* Perform initial detection */
>> +       odroid_usbotg_detect_cable(extcon_data);
>> +
>> +       dev_dbg(&pdev->dev, "probe: success\n");
>> +
>> +       return 0;
>> +
>> +err:
>> +       extcon_dev_unregister(extcon_data->edev);
>> +
>> +       return ret;
>> +}
>> +
>> +static int odroid_usbotg_remove(struct platform_device *pdev)
>> +{
>> +       struct odroid_usbotg_data *extcon_data = platform_get_drvdata(pdev);
>> +
>> +       free_irq(extcon_data->vbus_det_irq, extcon_data);
>> +       if (extcon_data->otg_id)
>> +               free_irq(extcon_data->otg_id_irq, extcon_data);
>> +       extcon_dev_unregister(extcon_data->edev);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct of_device_id odroid_usbotg_of_match[] = {
>> +       { .compatible = "extcon-odroid-usbotg" },
>> +       { },
>> +};
>> +MODULE_DEVICE_TABLE(of, odroid_usbotg_of_match);
>> +
>> +static struct platform_driver odroid_usbotg_driver = {
>> +       .probe          = odroid_usbotg_probe,
>> +       .remove         = odroid_usbotg_remove,
>> +       .driver         = {
>> +               .name   = "odroid-usbotg",
>> +               .owner  = THIS_MODULE,
>> +               .of_match_table = of_match_ptr(odroid_usbotg_of_match)
>> +       },
>> +};
>> +
>> +static int __init odroid_usbotg_init(void)
>> +{
>> +       return platform_driver_register(&odroid_usbotg_driver);
>> +}
>> +
>> +subsys_initcall(odroid_usbotg_init);
>> +
>> +static void __exit odroid_usbotg_cleanup(void)
>> +{
>> +       platform_driver_unregister(&odroid_usbotg_driver);
>> +}
>> +
>> +module_exit(odroid_usbotg_cleanup);
>> +
>> +MODULE_AUTHOR("Lukasz Stelmach <l.stelmach@...sung.com>, Robert Baldyga <r.baldyga@...sung.com>");
>> +MODULE_DESCRIPTION("USB OTG extcon driver for Odroid U3, U3+ and X");
>> +MODULE_LICENSE("GPL");
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
>> the body of a message to majordomo@...r.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ