linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Robert Baldyga <r.baldyga@samsung.com>
To: George Cherian <gcherianv@gmail.com>
Cc: balbi@ti.com, gregkh@linuxfoundation.org,
	myungjoo.ham@samsung.com, cw00.choi@samsung.com,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	m.szyprowski@samsung.com,
	"Łukasz Stelmach" <l.stelmach@samsung.com>
Subject: Re: [RFC 01/19] extcon: add extcon-odroid-usbotg driver
Date: Thu, 19 Mar 2015 13:07:01 +0100	[thread overview]
Message-ID: <550ABBE5.6040908@samsung.com> (raw)
In-Reply-To: <CABYS093nUJ+YPhVgsMame+-N1HvjAFQWBAuXRDixDq3Y7WH-yg@mail.gmail.com>

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@samsung.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@samsung.com>
>> Signed-off-by: Robert Baldyga <r.baldyga@samsung.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@samsung.com>
>> + * Author: Robert Baldyga <r.baldyga@samsung.com>
>> + *
>> + * based on drivers/extcon/extcon-gpio.c
>> + * Copyright (C) 2008 Google, Inc.
>> + * Author: Mike Lockwood <lockwood@android.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@samsung.com>, Robert Baldyga <r.baldyga@samsung.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@vger.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@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


  reply	other threads:[~2015-03-19 12:07 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-18 14:04 [RFC 00/19] dwc3: add USB OTG role switch support Robert Baldyga
2015-03-18 14:04 ` [RFC 01/19] extcon: add extcon-odroid-usbotg driver Robert Baldyga
2015-03-19  8:50   ` George Cherian
2015-03-19 12:07     ` Robert Baldyga [this message]
2015-03-19 12:19       ` George Cherian
2015-03-19 14:45         ` Roger Quadros
2015-03-19 20:50           ` Chanwoo Choi
2015-03-20  7:25             ` Robert Baldyga
2015-03-20  7:45               ` Chanwoo Choi
2015-03-20  8:51                 ` Roger Quadros
2015-03-18 14:04 ` [RFC 02/19] dt-bindings: extcon: Add doc for extcon-odroid-usbotg Robert Baldyga
2015-03-18 14:04 ` [RFC 03/19] ARM: dts: exynos5422-odroidxu3: add odroid-usbotg extcon support Robert Baldyga
2015-03-18 14:04 ` [RFC 04/19] dwc3: gadget: add VBUS session handling Robert Baldyga
2015-03-18 14:04 ` [RFC 05/19] dwc3: gadget: enable/disable ep0 in dwc3_gadget_run_stop() Robert Baldyga
2015-03-18 14:04 ` [RFC 06/19] dwc3: gadget: check returned value in suspend/resume Robert Baldyga
2015-03-18 14:04 ` [RFC 07/19] dwc3: core: cleanup suspend/resume code Robert Baldyga
2015-03-18 15:00   ` Sergei Shtylyov
2015-03-18 14:04 ` [RFC 08/19] dwc3: core: handle event buffers in core_init/exit Robert Baldyga
2015-03-18 14:04 ` [RFC 09/19] dwc3: core: make dwc3_core_init/exit non-static Robert Baldyga
2015-03-18 14:04 ` [RFC 10/19] dwc3: add missing OTG register definitions Robert Baldyga
2015-03-18 14:04 ` [RFC 11/19] dwc3: add OTG handling code Robert Baldyga
2015-03-19  7:38   ` George Cherian
2015-03-18 14:04 ` [RFC 12/19] dwc3: otg: add ext_otg_ops support Robert Baldyga
2015-03-18 14:04 ` [RFC 13/19] dwc3: gadget: register gadget in OTG core Robert Baldyga
2015-03-18 14:04 ` [RFC 14/19] dwc3: host: don't add XHCI device only if in OTG mode Robert Baldyga
2015-03-18 14:04 ` [RFC 15/19] dwc3: core: initialize OTG in DWC3 core Robert Baldyga
2015-03-18 14:04 ` [RFC 16/19] dwc3: exynos: add software role switching code Robert Baldyga
2015-03-18 14:04 ` [RFC 17/19] ARM: dts: exynos5420: set usb3_lpm_capable in dwc3 controllers Robert Baldyga
2015-03-18 14:04 ` [RFC 18/19] ARM: dts: exynos5420: add snps,dis_u3_susphy_quirk to " Robert Baldyga
2015-03-18 14:04 ` [RFC 19/19] ARM: dts: exynos5422-odroidxu3: make usbdrd3 extcon client Robert Baldyga
2015-03-19  2:33 ` [RFC 00/19] dwc3: add USB OTG role switch support Chanwoo Choi
2015-03-19  8:27   ` Robert Baldyga

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=550ABBE5.6040908@samsung.com \
    --to=r.baldyga@samsung.com \
    --cc=balbi@ti.com \
    --cc=cw00.choi@samsung.com \
    --cc=gcherianv@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=l.stelmach@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=myungjoo.ham@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).