static int usb3503_connect(struct usb3503 *hub) { struct device *dev = hub->dev; int err; 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_CONFIG)); if (err < 0) { dev_err(dev, "SP_ILOCK failed (%d)\n", err); return err; } /* PDS : Set the ports which are disabled in self-powered mode. */ if (hub->port_off_mask) { err = regmap_update_bits(hub->regmap, USB3503_PDS, hub->port_off_mask, hub->port_off_mask); if (err < 0) { dev_err(dev, "PDS failed (%d)\n", err); return err; } } /* CFG1 : Set SELF_BUS_PWR, this enables self-powered operation. */ err = regmap_update_bits(hub->regmap, USB3503_CFG1, USB3503_SELF_BUS_PWR, USB3503_SELF_BUS_PWR); if (err < 0) { dev_err(dev, "CFG1 failed (%d)\n", err); return err; } /* SP_LOCK: clear connect_n, config_n for hub connect */ err = regmap_update_bits(hub->regmap, USB3503_SP_ILOCK, (USB3503_SPILOCK_CONNECT | USB3503_SPILOCK_CONFIG), 0); if (err < 0) { dev_err(dev, "SP_ILOCK failed (%d)\n", err); return err; } } if (gpio_is_valid(hub->gpio_connect)) gpio_set_value_cansleep(hub->gpio_connect, 1); 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: usb3503_reset(hub, 0); dev_info(dev, "switched to STANDBY mode\n"); break; default: dev_err(dev, "unknown mode is requested\n"); err = -EINVAL; break; } return err; }
static int usb3503_switch_mode(struct usb3503 *hub, enum usb3503_mode mode) { struct i2c_client *i2c = hub->client; int err = 0; switch (mode) { case USB3503_MODE_HUB: usb3503_reset(hub->gpio_reset, 1); /* SP_ILOCK: set connect_n, config_n for config */ err = usb3503_write_register(i2c, USB3503_SP_ILOCK, (USB3503_SPILOCK_CONNECT | USB3503_SPILOCK_CONFIG)); if (err < 0) { dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err); goto err_hubmode; } /* PDS : Port2,3 Disable For Self Powered Operation */ /* err = usb3503_set_bits(i2c, USB3503_PDS, (USB3503_PORT2 | USB3503_PORT3)); if (err < 0) { dev_err(&i2c->dev, "PDS failed (%d)\n", err); goto err_hubmode; } */ /* CFG1 : SELF_BUS_PWR -> Self-Powerd operation */ err = usb3503_set_bits(i2c, USB3503_CFG1, USB3503_SELF_BUS_PWR); if (err < 0) { dev_err(&i2c->dev, "CFG1 failed (%d)\n", err); goto err_hubmode; } /* SP_LOCK: clear connect_n, config_n for hub connect */ err = usb3503_clear_bits(i2c, USB3503_SP_ILOCK, (USB3503_SPILOCK_CONNECT | USB3503_SPILOCK_CONFIG)); if (err < 0) { dev_err(&i2c->dev, "SP_ILOCK failed (%d)\n", err); goto err_hubmode; } hub->mode = mode; dev_info(&i2c->dev, "switched to HUB mode\n"); break; case USB3503_MODE_STANDBY: usb3503_reset(hub->gpio_reset, 0); hub->mode = mode; dev_info(&i2c->dev, "switched to STANDBY mode\n"); break; default: dev_err(&i2c->dev, "unknown mode is request\n"); err = -EINVAL; break; } err_hubmode: return err; }