linux/drivers/usb/misc/usb3503.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Driver for SMSC USB3503 USB 2.0 hub controller driver
   4 *
   5 * Copyright (c) 2012-2013 Dongjin Kim (tobetter@gmail.com)
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/i2c.h>
  10#include <linux/gpio/consumer.h>
  11#include <linux/delay.h>
  12#include <linux/slab.h>
  13#include <linux/module.h>
  14#include <linux/platform_device.h>
  15#include <linux/platform_data/usb3503.h>
  16#include <linux/regmap.h>
  17
  18#define USB3503_VIDL            0x00
  19#define USB3503_VIDM            0x01
  20#define USB3503_PIDL            0x02
  21#define USB3503_PIDM            0x03
  22#define USB3503_DIDL            0x04
  23#define USB3503_DIDM            0x05
  24
  25#define USB3503_CFG1            0x06
  26#define USB3503_SELF_BUS_PWR    (1 << 7)
  27
  28#define USB3503_CFG2            0x07
  29#define USB3503_CFG3            0x08
  30#define USB3503_NRD             0x09
  31
  32#define USB3503_PDS             0x0a
  33
  34#define USB3503_SP_ILOCK        0xe7
  35#define USB3503_SPILOCK_CONNECT (1 << 1)
  36#define USB3503_SPILOCK_CONFIG  (1 << 0)
  37
  38#define USB3503_CFGP            0xee
  39#define USB3503_CLKSUSP         (1 << 7)
  40
  41#define USB3503_RESET           0xff
  42
  43struct usb3503 {
  44        enum usb3503_mode       mode;
  45        struct regmap           *regmap;
  46        struct device           *dev;
  47        struct clk              *clk;
  48        u8      port_off_mask;
  49        struct gpio_desc        *intn;
  50        struct gpio_desc        *reset;
  51        struct gpio_desc        *connect;
  52        bool    secondary_ref_clk;
  53};
  54
  55static int usb3503_reset(struct usb3503 *hub, int state)
  56{
  57        if (!state && hub->connect)
  58                gpiod_set_value_cansleep(hub->connect, 0);
  59
  60        if (hub->reset)
  61                gpiod_set_value_cansleep(hub->reset, !state);
  62
  63        /* Wait T_HUBINIT == 4ms for hub logic to stabilize */
  64        if (state)
  65                usleep_range(4000, 10000);
  66
  67        return 0;
  68}
  69
  70static int usb3503_connect(struct usb3503 *hub)
  71{
  72        struct device *dev = hub->dev;
  73        int err;
  74
  75        usb3503_reset(hub, 1);
  76
  77        if (hub->regmap) {
  78                /* SP_ILOCK: set connect_n, config_n for config */
  79                err = regmap_write(hub->regmap, USB3503_SP_ILOCK,
  80                           (USB3503_SPILOCK_CONNECT
  81                                 | USB3503_SPILOCK_CONFIG));
  82                if (err < 0) {
  83                        dev_err(dev, "SP_ILOCK failed (%d)\n", err);
  84                        return err;
  85                }
  86
  87                /* PDS : Set the ports which are disabled in self-powered mode. */
  88                if (hub->port_off_mask) {
  89                        err = regmap_update_bits(hub->regmap, USB3503_PDS,
  90                                        hub->port_off_mask,
  91                                        hub->port_off_mask);
  92                        if (err < 0) {
  93                                dev_err(dev, "PDS failed (%d)\n", err);
  94                                return err;
  95                        }
  96                }
  97
  98                /* CFG1 : Set SELF_BUS_PWR, this enables self-powered operation. */
  99                err = regmap_update_bits(hub->regmap, USB3503_CFG1,
 100                                         USB3503_SELF_BUS_PWR,
 101                                         USB3503_SELF_BUS_PWR);
 102                if (err < 0) {
 103                        dev_err(dev, "CFG1 failed (%d)\n", err);
 104                        return err;
 105                }
 106
 107                /* SP_LOCK: clear connect_n, config_n for hub connect */
 108                err = regmap_update_bits(hub->regmap, USB3503_SP_ILOCK,
 109                                         (USB3503_SPILOCK_CONNECT
 110                                          | USB3503_SPILOCK_CONFIG), 0);
 111                if (err < 0) {
 112                        dev_err(dev, "SP_ILOCK failed (%d)\n", err);
 113                        return err;
 114                }
 115        }
 116
 117        if (hub->connect)
 118                gpiod_set_value_cansleep(hub->connect, 1);
 119
 120        hub->mode = USB3503_MODE_HUB;
 121        dev_info(dev, "switched to HUB mode\n");
 122
 123        return 0;
 124}
 125
 126static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode)
 127{
 128        struct device *dev = hub->dev;
 129        int err = 0;
 130
 131        switch (mode) {
 132        case USB3503_MODE_HUB:
 133                err = usb3503_connect(hub);
 134                break;
 135
 136        case USB3503_MODE_STANDBY:
 137                usb3503_reset(hub, 0);
 138                dev_info(dev, "switched to STANDBY mode\n");
 139                break;
 140
 141        default:
 142                dev_err(dev, "unknown mode is requested\n");
 143                err = -EINVAL;
 144                break;
 145        }
 146
 147        return err;
 148}
 149
 150static const struct regmap_config usb3503_regmap_config = {
 151        .reg_bits = 8,
 152        .val_bits = 8,
 153
 154        .max_register = USB3503_RESET,
 155};
 156
 157static int usb3503_probe(struct usb3503 *hub)
 158{
 159        struct device *dev = hub->dev;
 160        struct usb3503_platform_data *pdata = dev_get_platdata(dev);
 161        struct device_node *np = dev->of_node;
 162        int err;
 163        u32 mode = USB3503_MODE_HUB;
 164        const u32 *property;
 165        enum gpiod_flags flags;
 166        int len;
 167
 168        if (pdata) {
 169                hub->port_off_mask      = pdata->port_off_mask;
 170                hub->mode               = pdata->initial_mode;
 171        } else if (np) {
 172                u32 rate = 0;
 173                hub->port_off_mask = 0;
 174
 175                if (!of_property_read_u32(np, "refclk-frequency", &rate)) {
 176                        switch (rate) {
 177                        case 38400000:
 178                        case 26000000:
 179                        case 19200000:
 180                        case 12000000:
 181                                hub->secondary_ref_clk = 0;
 182                                break;
 183                        case 24000000:
 184                        case 27000000:
 185                        case 25000000:
 186                        case 50000000:
 187                                hub->secondary_ref_clk = 1;
 188                                break;
 189                        default:
 190                                dev_err(dev,
 191                                        "unsupported reference clock rate (%d)\n",
 192                                        (int) rate);
 193                                return -EINVAL;
 194                        }
 195                }
 196
 197                hub->clk = devm_clk_get_optional(dev, "refclk");
 198                if (IS_ERR(hub->clk)) {
 199                        dev_err(dev, "unable to request refclk (%ld)\n",
 200                                        PTR_ERR(hub->clk));
 201                        return PTR_ERR(hub->clk);
 202                }
 203
 204                if (rate != 0) {
 205                        err = clk_set_rate(hub->clk, rate);
 206                        if (err) {
 207                                dev_err(dev,
 208                                        "unable to set reference clock rate to %d\n",
 209                                        (int)rate);
 210                                return err;
 211                        }
 212                }
 213
 214                err = clk_prepare_enable(hub->clk);
 215                if (err) {
 216                        dev_err(dev, "unable to enable reference clock\n");
 217                        return err;
 218                }
 219
 220                property = of_get_property(np, "disabled-ports", &len);
 221                if (property && (len / sizeof(u32)) > 0) {
 222                        int i;
 223                        for (i = 0; i < len / sizeof(u32); i++) {
 224                                u32 port = be32_to_cpu(property[i]);
 225                                if ((1 <= port) && (port <= 3))
 226                                        hub->port_off_mask |= (1 << port);
 227                        }
 228                }
 229
 230                of_property_read_u32(np, "initial-mode", &mode);
 231                hub->mode = mode;
 232        }
 233
 234        if (hub->secondary_ref_clk)
 235                flags = GPIOD_OUT_LOW;
 236        else
 237                flags = GPIOD_OUT_HIGH;
 238        hub->intn = devm_gpiod_get_optional(dev, "intn", flags);
 239        if (IS_ERR(hub->intn))
 240                return PTR_ERR(hub->intn);
 241        if (hub->intn)
 242                gpiod_set_consumer_name(hub->intn, "usb3503 intn");
 243
 244        hub->connect = devm_gpiod_get_optional(dev, "connect", GPIOD_OUT_LOW);
 245        if (IS_ERR(hub->connect))
 246                return PTR_ERR(hub->connect);
 247        if (hub->connect)
 248                gpiod_set_consumer_name(hub->connect, "usb3503 connect");
 249
 250        hub->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 251        if (IS_ERR(hub->reset))
 252                return PTR_ERR(hub->reset);
 253        if (hub->reset) {
 254                /* Datasheet defines a hardware reset to be at least 100us */
 255                usleep_range(100, 10000);
 256                gpiod_set_consumer_name(hub->reset, "usb3503 reset");
 257        }
 258
 259        if (hub->port_off_mask && !hub->regmap)
 260                dev_err(dev, "Ports disabled with no control interface\n");
 261
 262        usb3503_switch_mode(hub, hub->mode);
 263
 264        dev_info(dev, "%s: probed in %s mode\n", __func__,
 265                        (hub->mode == USB3503_MODE_HUB) ? "hub" : "standby");
 266
 267        return 0;
 268}
 269
 270static int usb3503_i2c_probe(struct i2c_client *i2c,
 271                             const struct i2c_device_id *id)
 272{
 273        struct usb3503 *hub;
 274        int err;
 275
 276        hub = devm_kzalloc(&i2c->dev, sizeof(struct usb3503), GFP_KERNEL);
 277        if (!hub)
 278                return -ENOMEM;
 279
 280        i2c_set_clientdata(i2c, hub);
 281        hub->regmap = devm_regmap_init_i2c(i2c, &usb3503_regmap_config);
 282        if (IS_ERR(hub->regmap)) {
 283                err = PTR_ERR(hub->regmap);
 284                dev_err(&i2c->dev, "Failed to initialise regmap: %d\n", err);
 285                return err;
 286        }
 287        hub->dev = &i2c->dev;
 288
 289        return usb3503_probe(hub);
 290}
 291
 292static int usb3503_i2c_remove(struct i2c_client *i2c)
 293{
 294        struct usb3503 *hub;
 295
 296        hub = i2c_get_clientdata(i2c);
 297        clk_disable_unprepare(hub->clk);
 298
 299        return 0;
 300}
 301
 302static int usb3503_platform_probe(struct platform_device *pdev)
 303{
 304        struct usb3503 *hub;
 305
 306        hub = devm_kzalloc(&pdev->dev, sizeof(struct usb3503), GFP_KERNEL);
 307        if (!hub)
 308                return -ENOMEM;
 309        hub->dev = &pdev->dev;
 310        platform_set_drvdata(pdev, hub);
 311
 312        return usb3503_probe(hub);
 313}
 314
 315static int usb3503_platform_remove(struct platform_device *pdev)
 316{
 317        struct usb3503 *hub;
 318
 319        hub = platform_get_drvdata(pdev);
 320        clk_disable_unprepare(hub->clk);
 321
 322        return 0;
 323}
 324
 325static int __maybe_unused usb3503_suspend(struct usb3503 *hub)
 326{
 327        usb3503_switch_mode(hub, USB3503_MODE_STANDBY);
 328        clk_disable_unprepare(hub->clk);
 329
 330        return 0;
 331}
 332
 333static int __maybe_unused usb3503_resume(struct usb3503 *hub)
 334{
 335        clk_prepare_enable(hub->clk);
 336        usb3503_switch_mode(hub, hub->mode);
 337
 338        return 0;
 339}
 340
 341static int __maybe_unused usb3503_i2c_suspend(struct device *dev)
 342{
 343        struct i2c_client *client = to_i2c_client(dev);
 344
 345        return usb3503_suspend(i2c_get_clientdata(client));
 346}
 347
 348static int __maybe_unused usb3503_i2c_resume(struct device *dev)
 349{
 350        struct i2c_client *client = to_i2c_client(dev);
 351
 352        return usb3503_resume(i2c_get_clientdata(client));
 353}
 354
 355static int __maybe_unused usb3503_platform_suspend(struct device *dev)
 356{
 357        return usb3503_suspend(dev_get_drvdata(dev));
 358}
 359
 360static int __maybe_unused usb3503_platform_resume(struct device *dev)
 361{
 362        return usb3503_resume(dev_get_drvdata(dev));
 363}
 364
 365static SIMPLE_DEV_PM_OPS(usb3503_i2c_pm_ops, usb3503_i2c_suspend,
 366                usb3503_i2c_resume);
 367
 368static SIMPLE_DEV_PM_OPS(usb3503_platform_pm_ops, usb3503_platform_suspend,
 369                usb3503_platform_resume);
 370
 371static const struct i2c_device_id usb3503_id[] = {
 372        { USB3503_I2C_NAME, 0 },
 373        { }
 374};
 375MODULE_DEVICE_TABLE(i2c, usb3503_id);
 376
 377#ifdef CONFIG_OF
 378static const struct of_device_id usb3503_of_match[] = {
 379        { .compatible = "smsc,usb3503", },
 380        { .compatible = "smsc,usb3503a", },
 381        {},
 382};
 383MODULE_DEVICE_TABLE(of, usb3503_of_match);
 384#endif
 385
 386static struct i2c_driver usb3503_i2c_driver = {
 387        .driver = {
 388                .name = USB3503_I2C_NAME,
 389                .pm = pm_ptr(&usb3503_i2c_pm_ops),
 390                .of_match_table = of_match_ptr(usb3503_of_match),
 391        },
 392        .probe          = usb3503_i2c_probe,
 393        .remove         = usb3503_i2c_remove,
 394        .id_table       = usb3503_id,
 395};
 396
 397static struct platform_driver usb3503_platform_driver = {
 398        .driver = {
 399                .name = USB3503_I2C_NAME,
 400                .of_match_table = of_match_ptr(usb3503_of_match),
 401                .pm = pm_ptr(&usb3503_platform_pm_ops),
 402        },
 403        .probe          = usb3503_platform_probe,
 404        .remove         = usb3503_platform_remove,
 405};
 406
 407static int __init usb3503_init(void)
 408{
 409        int err;
 410
 411        err = i2c_add_driver(&usb3503_i2c_driver);
 412        if (err) {
 413                pr_err("usb3503: Failed to register I2C driver: %d\n", err);
 414                return err;
 415        }
 416
 417        err = platform_driver_register(&usb3503_platform_driver);
 418        if (err) {
 419                pr_err("usb3503: Failed to register platform driver: %d\n",
 420                       err);
 421                i2c_del_driver(&usb3503_i2c_driver);
 422                return err;
 423        }
 424
 425        return 0;
 426}
 427module_init(usb3503_init);
 428
 429static void __exit usb3503_exit(void)
 430{
 431        platform_driver_unregister(&usb3503_platform_driver);
 432        i2c_del_driver(&usb3503_i2c_driver);
 433}
 434module_exit(usb3503_exit);
 435
 436MODULE_AUTHOR("Dongjin Kim <tobetter@gmail.com>");
 437MODULE_DESCRIPTION("USB3503 USB HUB driver");
 438MODULE_LICENSE("GPL");
 439