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 */
                                        hub->port_off_mask);
                        if (err < 0) {
                                dev_err(dev, "PDS failed (%d)\n", err);
-                               goto err_hubmode;
+                               return err;
                        }
                }
 
                                         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 */
                                          | 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:
                break;
        }
 
-err_hubmode:
        return err;
 }
 
                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");
        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 },
        { }
 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),
        .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@gmail.com>");
 MODULE_DESCRIPTION("USB3503 USB HUB driver");