Re: [PATCH 11/11] usb: misc: usb3503: Support operation with no I2C control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Reviewed-by: Dongjin Kim <tobetter@xxxxxxxxx>

I like this patch series, I dropped my changes to support non-i2c
based operation.

On Fri, Aug 9, 2013 at 7:41 PM, Mark Brown <broonie@xxxxxxxxxx> wrote:
> From: Mark Brown <broonie@xxxxxxxxxx>
>
> Refactor so that register writes for configuration are only performed if
> the device has a regmap provided and also register as a platform driver.
> This allows the driver to be used to manage GPIO based control of the
> device.
>
> Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
> Cc: devicetree@xxxxxxxxxxxxxxx
> ---
>  Documentation/devicetree/bindings/usb/usb3503.txt |  3 +-
>  drivers/usb/misc/usb3503.c                        | 93 ++++++++++++++++++-----
>  2 files changed, 78 insertions(+), 18 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
> index 44a03f3..a018da4 100644
> --- a/Documentation/devicetree/bindings/usb/usb3503.txt
> +++ b/Documentation/devicetree/bindings/usb/usb3503.txt
> @@ -2,9 +2,10 @@ SMSC USB3503 High-Speed Hub Controller
>
>  Required properties:
>  - compatible: Should be "smsc,usb3503" or "smsc,usb3503a".
> -- reg: Specifies the i2c slave address, it should be 0x08.
>
>  Optional properties:
> +- reg: Specifies the i2c slave address, it is required and should be 0x08
> +       if I2C is used.
>  - connect-gpios: Should specify GPIO for connect.
>  - disabled-ports: Should specify the ports unused.
>         '1' or '2' or '3' are availe for this property to describe the port
> diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c
> index da45ed9..a31641e 100644
> --- a/drivers/usb/misc/usb3503.c
> +++ b/drivers/usb/misc/usb3503.c
> @@ -78,22 +78,21 @@ static int usb3503_reset(struct usb3503 *hub, int state)
>         return 0;
>  }
>
> -static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
> +static int usb3503_connect(struct usb3503 *hub)
>  {
>         struct device *dev = hub->dev;
> -       int err = 0;
> +       int err;
>
> -       switch (mode) {
> -       case USB3503_MODE_HUB:
> -               usb3503_reset(hub, 1);
> +       usb3503_reset(hub, 1);
>
> +       if (hub->regmap) {
>                 /* SP_ILOCK: set connect_n, config_n for config */
>                 err = regmap_write(hub->regmap, USB3503_SP_ILOCK,
> -                               (USB3503_SPILOCK_CONNECT
> +                          (USB3503_SPILOCK_CONNECT
>                                  | USB3503_SPILOCK_CONFIG));
>                 if (err < 0) {
>                         dev_err(dev, "SP_ILOCK failed (%d)\n", err);
> -                       goto err_hubmode;
> +                       return err;
>                 }
>
>                 /* PDS : Disable For Self Powered Operation */
> @@ -103,7 +102,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
>                                         hub->port_off_mask);
>                         if (err < 0) {
>                                 dev_err(dev, "PDS failed (%d)\n", err);
> -                               goto err_hubmode;
> +                               return err;
>                         }
>                 }
>
> @@ -113,7 +112,7 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
>                                          USB3503_SELF_BUS_PWR);
>                 if (err < 0) {
>                         dev_err(dev, "CFG1 failed (%d)\n", err);
> -                       goto err_hubmode;
> +                       return err;
>                 }
>
>                 /* SP_LOCK: clear connect_n, config_n for hub connect */
> @@ -122,14 +121,27 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
>                                           | USB3503_SPILOCK_CONFIG), 0);
>                 if (err < 0) {
>                         dev_err(dev, "SP_ILOCK failed (%d)\n", err);
> -                       goto err_hubmode;
> +                       return err;
>                 }
> +       }
>
> -               if (gpio_is_valid(hub->gpio_connect))
> -                       gpio_set_value_cansleep(hub->gpio_connect, 1);
> +       if (gpio_is_valid(hub->gpio_connect))
> +               gpio_set_value_cansleep(hub->gpio_connect, 1);
>
> -               hub->mode = mode;
> -               dev_info(dev, "switched to HUB mode\n");
> +       hub->mode = USB3503_MODE_HUB;
> +       dev_info(dev, "switched to HUB mode\n");
> +
> +       return 0;
> +}
> +
> +static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
> +{
> +       struct device *dev = hub->dev;
> +       int err = 0;
> +
> +       switch (mode) {
> +       case USB3503_MODE_HUB:
> +               err = usb3503_connect(hub);
>                 break;
>
>         case USB3503_MODE_STANDBY:
> @@ -145,7 +157,6 @@ static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
>                 break;
>         }
>
> -err_hubmode:
>         return err;
>  }
>
> @@ -198,6 +209,9 @@ static int usb3503_probe(struct usb3503 *hub)
>                 hub->mode = mode;
>         }
>
> +       if (hub->port_off_mask && !hub->regmap)
> +               dev_err(dev, "Ports disabled with no control interface\n");
> +
>         if (gpio_is_valid(hub->gpio_intn)) {
>                 err = devm_gpio_request_one(dev, hub->gpio_intn,
>                                 GPIOF_OUT_INIT_HIGH, "usb3503 intn");
> @@ -263,6 +277,20 @@ static int usb3503_i2c_probe(struct i2c_client *i2c,
>         return usb3503_probe(hub);
>  }
>
> +static int usb3503_platform_probe(struct platform_device *pdev)
> +{
> +       struct usb3503 *hub;
> +
> +       hub = devm_kzalloc(&pdev->dev, sizeof(struct usb3503), GFP_KERNEL);
> +       if (!hub) {
> +               dev_err(&pdev->dev, "private data alloc fail\n");
> +               return -ENOMEM;
> +       }
> +       hub->dev = &pdev->dev;
> +
> +       return usb3503_probe(hub);
> +}
> +
>  static const struct i2c_device_id usb3503_id[] = {
>         { USB3503_I2C_NAME, 0 },
>         { }
> @@ -278,7 +306,7 @@ static const struct of_device_id usb3503_of_match[] = {
>  MODULE_DEVICE_TABLE(of, usb3503_of_match);
>  #endif
>
> -static struct i2c_driver usb3503_driver = {
> +static struct i2c_driver usb3503_i2c_driver = {
>         .driver = {
>                 .name = USB3503_I2C_NAME,
>                 .of_match_table = of_match_ptr(usb3503_of_match),
> @@ -287,7 +315,38 @@ static struct i2c_driver usb3503_driver = {
>         .id_table       = usb3503_id,
>  };
>
> -module_i2c_driver(usb3503_driver);
> +static struct platform_driver usb3503_platform_driver = {
> +       .driver = {
> +               .name = USB3503_I2C_NAME,
> +               .of_match_table = of_match_ptr(usb3503_of_match),
> +               .owner = THIS_MODULE,
> +       },
> +       .probe          = usb3503_platform_probe,
> +};
> +
> +static int __init usb3503_init(void)
> +{
> +       int err;
> +
> +       err = i2c_register_driver(THIS_MODULE, &usb3503_i2c_driver);
> +       if (err != 0)
> +               pr_err("usb3503: Failed to register I2C driver: %d\n", err);
> +
> +       err = platform_driver_register(&usb3503_platform_driver);
> +       if (err != 0)
> +               pr_err("usb3503: Failed to register platform driver: %d\n",
> +                      err);
> +
> +       return 0;
> +}
> +module_init(usb3503_init);
> +
> +static void __exit usb3503_exit(void)
> +{
> +       platform_driver_unregister(&usb3503_platform_driver);
> +       i2c_del_driver(&usb3503_i2c_driver);
> +}
> +module_exit(usb3503_exit);
>
>  MODULE_AUTHOR("Dongjin Kim <tobetter@xxxxxxxxx>");
>  MODULE_DESCRIPTION("USB3503 USB HUB driver");
> --
> 1.8.4.rc1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux