Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Motorola CPCAP PMIC USB PHY driver
0004  * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
0005  *
0006  * Some parts based on earlier Motorola Linux kernel tree code in
0007  * board-mapphone-usb.c and cpcap-usb-det.c:
0008  * Copyright (C) 2007 - 2011 Motorola, Inc.
0009  */
0010 
0011 #include <linux/atomic.h>
0012 #include <linux/clk.h>
0013 #include <linux/delay.h>
0014 #include <linux/err.h>
0015 #include <linux/io.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/of_platform.h>
0019 #include <linux/iio/consumer.h>
0020 #include <linux/pinctrl/consumer.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/regmap.h>
0023 #include <linux/slab.h>
0024 
0025 #include <linux/gpio/consumer.h>
0026 #include <linux/mfd/motorola-cpcap.h>
0027 #include <linux/phy/omap_usb.h>
0028 #include <linux/phy/phy.h>
0029 #include <linux/regulator/consumer.h>
0030 #include <linux/usb/musb.h>
0031 
0032 /* CPCAP_REG_USBC1 register bits */
0033 #define CPCAP_BIT_IDPULSE       BIT(15)
0034 #define CPCAP_BIT_ID100KPU      BIT(14)
0035 #define CPCAP_BIT_IDPUCNTRL     BIT(13)
0036 #define CPCAP_BIT_IDPU          BIT(12)
0037 #define CPCAP_BIT_IDPD          BIT(11)
0038 #define CPCAP_BIT_VBUSCHRGTMR3      BIT(10)
0039 #define CPCAP_BIT_VBUSCHRGTMR2      BIT(9)
0040 #define CPCAP_BIT_VBUSCHRGTMR1      BIT(8)
0041 #define CPCAP_BIT_VBUSCHRGTMR0      BIT(7)
0042 #define CPCAP_BIT_VBUSPU        BIT(6)
0043 #define CPCAP_BIT_VBUSPD        BIT(5)
0044 #define CPCAP_BIT_DMPD          BIT(4)
0045 #define CPCAP_BIT_DPPD          BIT(3)
0046 #define CPCAP_BIT_DM1K5PU       BIT(2)
0047 #define CPCAP_BIT_DP1K5PU       BIT(1)
0048 #define CPCAP_BIT_DP150KPU      BIT(0)
0049 
0050 /* CPCAP_REG_USBC2 register bits */
0051 #define CPCAP_BIT_ZHSDRV1       BIT(15)
0052 #define CPCAP_BIT_ZHSDRV0       BIT(14)
0053 #define CPCAP_BIT_DPLLCLKREQ        BIT(13)
0054 #define CPCAP_BIT_SE0CONN       BIT(12)
0055 #define CPCAP_BIT_UARTTXTRI     BIT(11)
0056 #define CPCAP_BIT_UARTSWAP      BIT(10)
0057 #define CPCAP_BIT_UARTMUX1      BIT(9)
0058 #define CPCAP_BIT_UARTMUX0      BIT(8)
0059 #define CPCAP_BIT_ULPISTPLOW        BIT(7)
0060 #define CPCAP_BIT_TXENPOL       BIT(6)
0061 #define CPCAP_BIT_USBXCVREN     BIT(5)
0062 #define CPCAP_BIT_USBCNTRL      BIT(4)
0063 #define CPCAP_BIT_USBSUSPEND        BIT(3)
0064 #define CPCAP_BIT_EMUMODE2      BIT(2)
0065 #define CPCAP_BIT_EMUMODE1      BIT(1)
0066 #define CPCAP_BIT_EMUMODE0      BIT(0)
0067 
0068 /* CPCAP_REG_USBC3 register bits */
0069 #define CPCAP_BIT_SPARE_898_15      BIT(15)
0070 #define CPCAP_BIT_IHSTX03       BIT(14)
0071 #define CPCAP_BIT_IHSTX02       BIT(13)
0072 #define CPCAP_BIT_IHSTX01       BIT(12)
0073 #define CPCAP_BIT_IHSTX0        BIT(11)
0074 #define CPCAP_BIT_IDPU_SPI      BIT(10)
0075 #define CPCAP_BIT_UNUSED_898_9      BIT(9)
0076 #define CPCAP_BIT_VBUSSTBY_EN       BIT(8)
0077 #define CPCAP_BIT_VBUSEN_SPI        BIT(7)
0078 #define CPCAP_BIT_VBUSPU_SPI        BIT(6)
0079 #define CPCAP_BIT_VBUSPD_SPI        BIT(5)
0080 #define CPCAP_BIT_DMPD_SPI      BIT(4)
0081 #define CPCAP_BIT_DPPD_SPI      BIT(3)
0082 #define CPCAP_BIT_SUSPEND_SPI       BIT(2)
0083 #define CPCAP_BIT_PU_SPI        BIT(1)
0084 #define CPCAP_BIT_ULPI_SPI_SEL      BIT(0)
0085 
0086 struct cpcap_usb_ints_state {
0087     bool id_ground;
0088     bool id_float;
0089     bool chrg_det;
0090     bool rvrs_chrg;
0091     bool vbusov;
0092 
0093     bool chrg_se1b;
0094     bool se0conn;
0095     bool rvrs_mode;
0096     bool chrgcurr1;
0097     bool vbusvld;
0098     bool sessvld;
0099     bool sessend;
0100     bool se1;
0101 
0102     bool battdetb;
0103     bool dm;
0104     bool dp;
0105 };
0106 
0107 enum cpcap_gpio_mode {
0108     CPCAP_DM_DP,
0109     CPCAP_MDM_RX_TX,
0110     CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */
0111     CPCAP_OTG_DM_DP,
0112 };
0113 
0114 struct cpcap_phy_ddata {
0115     struct regmap *reg;
0116     struct device *dev;
0117     struct usb_phy phy;
0118     struct delayed_work detect_work;
0119     struct pinctrl *pins;
0120     struct pinctrl_state *pins_ulpi;
0121     struct pinctrl_state *pins_utmi;
0122     struct pinctrl_state *pins_uart;
0123     struct gpio_desc *gpio[2];
0124     struct iio_channel *vbus;
0125     struct iio_channel *id;
0126     struct regulator *vusb;
0127     atomic_t active;
0128     unsigned int vbus_provider:1;
0129     unsigned int docked:1;
0130 };
0131 
0132 static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
0133 {
0134     int error, value = 0;
0135 
0136     error = iio_read_channel_processed(ddata->vbus, &value);
0137     if (error >= 0)
0138         return value > 3900;
0139 
0140     dev_err(ddata->dev, "error reading VBUS: %i\n", error);
0141 
0142     return false;
0143 }
0144 
0145 static int cpcap_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host)
0146 {
0147     otg->host = host;
0148     if (!host)
0149         otg->state = OTG_STATE_UNDEFINED;
0150 
0151     return 0;
0152 }
0153 
0154 static int cpcap_usb_phy_set_peripheral(struct usb_otg *otg,
0155                     struct usb_gadget *gadget)
0156 {
0157     otg->gadget = gadget;
0158     if (!gadget)
0159         otg->state = OTG_STATE_UNDEFINED;
0160 
0161     return 0;
0162 }
0163 
0164 static const struct phy_ops ops = {
0165     .owner      = THIS_MODULE,
0166 };
0167 
0168 static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
0169                     struct cpcap_usb_ints_state *s)
0170 {
0171     int val, error;
0172 
0173     error = regmap_read(ddata->reg, CPCAP_REG_INTS1, &val);
0174     if (error)
0175         return error;
0176 
0177     s->id_ground = val & BIT(15);
0178     s->id_float = val & BIT(14);
0179     s->vbusov = val & BIT(11);
0180 
0181     error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val);
0182     if (error)
0183         return error;
0184 
0185     s->vbusvld = val & BIT(3);
0186     s->sessvld = val & BIT(2);
0187     s->sessend = val & BIT(1);
0188     s->se1 = val & BIT(0);
0189 
0190     error = regmap_read(ddata->reg, CPCAP_REG_INTS4, &val);
0191     if (error)
0192         return error;
0193 
0194     s->dm = val & BIT(1);
0195     s->dp = val & BIT(0);
0196 
0197     return 0;
0198 }
0199 
0200 static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
0201 static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);
0202 
0203 static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
0204                        enum musb_vbus_id_status status)
0205 {
0206     int error;
0207 
0208     error = musb_mailbox(status);
0209     if (!error)
0210         return;
0211 
0212     dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n",
0213         __func__, error);
0214 }
0215 
0216 static void cpcap_usb_detect(struct work_struct *work)
0217 {
0218     struct cpcap_phy_ddata *ddata;
0219     struct cpcap_usb_ints_state s;
0220     bool vbus = false;
0221     int error;
0222 
0223     ddata = container_of(work, struct cpcap_phy_ddata, detect_work.work);
0224 
0225     error = cpcap_phy_get_ints_state(ddata, &s);
0226     if (error)
0227         return;
0228 
0229     vbus = cpcap_usb_vbus_valid(ddata);
0230 
0231     /* We need to kick the VBUS as USB A-host */
0232     if (s.id_ground && ddata->vbus_provider) {
0233         dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");
0234 
0235         cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
0236 
0237         error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
0238                        CPCAP_BIT_VBUSSTBY_EN |
0239                        CPCAP_BIT_VBUSEN_SPI,
0240                        CPCAP_BIT_VBUSEN_SPI);
0241         if (error)
0242             goto out_err;
0243 
0244         return;
0245     }
0246 
0247     if (vbus && s.id_ground && ddata->docked) {
0248         dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");
0249 
0250         cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
0251 
0252         return;
0253     }
0254 
0255     /* No VBUS needed with docks */
0256     if (vbus && s.id_ground && !ddata->vbus_provider) {
0257         dev_dbg(ddata->dev, "connected to a dock\n");
0258 
0259         ddata->docked = true;
0260 
0261         error = cpcap_usb_set_usb_mode(ddata);
0262         if (error)
0263             goto out_err;
0264 
0265         cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
0266 
0267         /*
0268          * Force check state again after musb has reoriented,
0269          * otherwise devices won't enumerate after loading PHY
0270          * driver.
0271          */
0272         schedule_delayed_work(&ddata->detect_work,
0273                       msecs_to_jiffies(1000));
0274 
0275         return;
0276     }
0277 
0278     if (s.id_ground && !ddata->docked) {
0279         dev_dbg(ddata->dev, "id ground, USB host mode\n");
0280 
0281         ddata->vbus_provider = true;
0282 
0283         error = cpcap_usb_set_usb_mode(ddata);
0284         if (error)
0285             goto out_err;
0286 
0287         cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
0288 
0289         error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
0290                        CPCAP_BIT_VBUSSTBY_EN |
0291                        CPCAP_BIT_VBUSEN_SPI,
0292                        CPCAP_BIT_VBUSEN_SPI);
0293         if (error)
0294             goto out_err;
0295 
0296         return;
0297     }
0298 
0299     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
0300                    CPCAP_BIT_VBUSSTBY_EN |
0301                    CPCAP_BIT_VBUSEN_SPI, 0);
0302     if (error)
0303         goto out_err;
0304 
0305     vbus = cpcap_usb_vbus_valid(ddata);
0306 
0307     /* Otherwise assume we're connected to a USB host */
0308     if (vbus) {
0309         dev_dbg(ddata->dev, "connected to USB host\n");
0310         error = cpcap_usb_set_usb_mode(ddata);
0311         if (error)
0312             goto out_err;
0313         cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
0314 
0315         return;
0316     }
0317 
0318     ddata->vbus_provider = false;
0319     ddata->docked = false;
0320     cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
0321 
0322     /* Default to debug UART mode */
0323     error = cpcap_usb_set_uart_mode(ddata);
0324     if (error)
0325         goto out_err;
0326 
0327     dev_dbg(ddata->dev, "set UART mode\n");
0328 
0329     return;
0330 
0331 out_err:
0332     dev_err(ddata->dev, "error setting cable state: %i\n", error);
0333 }
0334 
0335 static irqreturn_t cpcap_phy_irq_thread(int irq, void *data)
0336 {
0337     struct cpcap_phy_ddata *ddata = data;
0338 
0339     if (!atomic_read(&ddata->active))
0340         return IRQ_NONE;
0341 
0342     schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
0343 
0344     return IRQ_HANDLED;
0345 }
0346 
0347 static int cpcap_usb_init_irq(struct platform_device *pdev,
0348                   struct cpcap_phy_ddata *ddata,
0349                   const char *name)
0350 {
0351     int irq, error;
0352 
0353     irq = platform_get_irq_byname(pdev, name);
0354     if (irq < 0)
0355         return -ENODEV;
0356 
0357     error = devm_request_threaded_irq(ddata->dev, irq, NULL,
0358                       cpcap_phy_irq_thread,
0359                       IRQF_SHARED |
0360                       IRQF_ONESHOT,
0361                       name, ddata);
0362     if (error) {
0363         dev_err(ddata->dev, "could not get irq %s: %i\n",
0364             name, error);
0365 
0366         return error;
0367     }
0368 
0369     return 0;
0370 }
0371 
0372 static const char * const cpcap_phy_irqs[] = {
0373     /* REG_INT_0 */
0374     "id_ground", "id_float",
0375 
0376     /* REG_INT1 */
0377     "se0conn", "vbusvld", "sessvld", "sessend", "se1",
0378 
0379     /* REG_INT_3 */
0380     "dm", "dp",
0381 };
0382 
0383 static int cpcap_usb_init_interrupts(struct platform_device *pdev,
0384                      struct cpcap_phy_ddata *ddata)
0385 {
0386     int i, error;
0387 
0388     for (i = 0; i < ARRAY_SIZE(cpcap_phy_irqs); i++) {
0389         error = cpcap_usb_init_irq(pdev, ddata, cpcap_phy_irqs[i]);
0390         if (error)
0391             return error;
0392     }
0393 
0394     return 0;
0395 }
0396 
0397 /*
0398  * Optional pins and modes. At least Motorola mapphone devices
0399  * are using two GPIOs and dynamic pinctrl to multiplex PHY pins
0400  * to UART, ULPI or UTMI mode.
0401  */
0402 
0403 static int cpcap_usb_gpio_set_mode(struct cpcap_phy_ddata *ddata,
0404                    enum cpcap_gpio_mode mode)
0405 {
0406     if (!ddata->gpio[0] || !ddata->gpio[1])
0407         return 0;
0408 
0409     gpiod_set_value(ddata->gpio[0], mode & 1);
0410     gpiod_set_value(ddata->gpio[1], mode >> 1);
0411 
0412     return 0;
0413 }
0414 
0415 static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
0416 {
0417     int error;
0418 
0419     /* Disable lines to prevent glitches from waking up mdm6600 */
0420     error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
0421     if (error)
0422         goto out_err;
0423 
0424     if (ddata->pins_uart) {
0425         error = pinctrl_select_state(ddata->pins, ddata->pins_uart);
0426         if (error)
0427             goto out_err;
0428     }
0429 
0430     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
0431                    CPCAP_BIT_VBUSPD,
0432                    CPCAP_BIT_VBUSPD);
0433     if (error)
0434         goto out_err;
0435 
0436     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
0437                    0xffff, CPCAP_BIT_UARTMUX0 |
0438                    CPCAP_BIT_EMUMODE0);
0439     if (error)
0440         goto out_err;
0441 
0442     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff,
0443                    CPCAP_BIT_IDPU_SPI);
0444     if (error)
0445         goto out_err;
0446 
0447     /* Enable UART mode */
0448     error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
0449     if (error)
0450         goto out_err;
0451 
0452     return 0;
0453 
0454 out_err:
0455     dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
0456 
0457     return error;
0458 }
0459 
0460 static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
0461 {
0462     int error;
0463 
0464     /* Disable lines to prevent glitches from waking up mdm6600 */
0465     error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
0466     if (error)
0467         return error;
0468 
0469     if (ddata->pins_utmi) {
0470         error = pinctrl_select_state(ddata->pins, ddata->pins_utmi);
0471         if (error) {
0472             dev_err(ddata->dev, "could not set usb mode: %i\n",
0473                 error);
0474 
0475             return error;
0476         }
0477     }
0478 
0479     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
0480                    CPCAP_BIT_VBUSPD, 0);
0481     if (error)
0482         goto out_err;
0483 
0484     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
0485                    CPCAP_BIT_PU_SPI |
0486                    CPCAP_BIT_DMPD_SPI |
0487                    CPCAP_BIT_DPPD_SPI |
0488                    CPCAP_BIT_SUSPEND_SPI |
0489                    CPCAP_BIT_ULPI_SPI_SEL, 0);
0490     if (error)
0491         goto out_err;
0492 
0493     error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
0494                    CPCAP_BIT_USBXCVREN,
0495                    CPCAP_BIT_USBXCVREN);
0496     if (error)
0497         goto out_err;
0498 
0499     /* Enable USB mode */
0500     error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
0501     if (error)
0502         goto out_err;
0503 
0504     return 0;
0505 
0506 out_err:
0507     dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
0508 
0509     return error;
0510 }
0511 
0512 static int cpcap_usb_init_optional_pins(struct cpcap_phy_ddata *ddata)
0513 {
0514     ddata->pins = devm_pinctrl_get(ddata->dev);
0515     if (IS_ERR(ddata->pins)) {
0516         dev_info(ddata->dev, "default pins not configured: %ld\n",
0517              PTR_ERR(ddata->pins));
0518         ddata->pins = NULL;
0519 
0520         return 0;
0521     }
0522 
0523     ddata->pins_ulpi = pinctrl_lookup_state(ddata->pins, "ulpi");
0524     if (IS_ERR(ddata->pins_ulpi)) {
0525         dev_info(ddata->dev, "ulpi pins not configured\n");
0526         ddata->pins_ulpi = NULL;
0527     }
0528 
0529     ddata->pins_utmi = pinctrl_lookup_state(ddata->pins, "utmi");
0530     if (IS_ERR(ddata->pins_utmi)) {
0531         dev_info(ddata->dev, "utmi pins not configured\n");
0532         ddata->pins_utmi = NULL;
0533     }
0534 
0535     ddata->pins_uart = pinctrl_lookup_state(ddata->pins, "uart");
0536     if (IS_ERR(ddata->pins_uart)) {
0537         dev_info(ddata->dev, "uart pins not configured\n");
0538         ddata->pins_uart = NULL;
0539     }
0540 
0541     if (ddata->pins_uart)
0542         return pinctrl_select_state(ddata->pins, ddata->pins_uart);
0543 
0544     return 0;
0545 }
0546 
0547 static void cpcap_usb_init_optional_gpios(struct cpcap_phy_ddata *ddata)
0548 {
0549     int i;
0550 
0551     for (i = 0; i < 2; i++) {
0552         ddata->gpio[i] = devm_gpiod_get_index(ddata->dev, "mode",
0553                               i, GPIOD_OUT_HIGH);
0554         if (IS_ERR(ddata->gpio[i])) {
0555             dev_info(ddata->dev, "no mode change GPIO%i: %li\n",
0556                  i, PTR_ERR(ddata->gpio[i]));
0557             ddata->gpio[i] = NULL;
0558         }
0559     }
0560 }
0561 
0562 static int cpcap_usb_init_iio(struct cpcap_phy_ddata *ddata)
0563 {
0564     enum iio_chan_type type;
0565     int error;
0566 
0567     ddata->vbus = devm_iio_channel_get(ddata->dev, "vbus");
0568     if (IS_ERR(ddata->vbus)) {
0569         error = PTR_ERR(ddata->vbus);
0570         goto out_err;
0571     }
0572 
0573     if (!ddata->vbus->indio_dev) {
0574         error = -ENXIO;
0575         goto out_err;
0576     }
0577 
0578     error = iio_get_channel_type(ddata->vbus, &type);
0579     if (error < 0)
0580         goto out_err;
0581 
0582     if (type != IIO_VOLTAGE) {
0583         error = -EINVAL;
0584         goto out_err;
0585     }
0586 
0587     return 0;
0588 
0589 out_err:
0590     dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
0591         error);
0592 
0593     return error;
0594 }
0595 
0596 #ifdef CONFIG_OF
0597 static const struct of_device_id cpcap_usb_phy_id_table[] = {
0598     {
0599         .compatible = "motorola,cpcap-usb-phy",
0600     },
0601     {
0602         .compatible = "motorola,mapphone-cpcap-usb-phy",
0603     },
0604     {},
0605 };
0606 MODULE_DEVICE_TABLE(of, cpcap_usb_phy_id_table);
0607 #endif
0608 
0609 static int cpcap_usb_phy_probe(struct platform_device *pdev)
0610 {
0611     struct cpcap_phy_ddata *ddata;
0612     struct phy *generic_phy;
0613     struct phy_provider *phy_provider;
0614     struct usb_otg *otg;
0615     const struct of_device_id *of_id;
0616     int error;
0617 
0618     of_id = of_match_device(of_match_ptr(cpcap_usb_phy_id_table),
0619                 &pdev->dev);
0620     if (!of_id)
0621         return -EINVAL;
0622 
0623     ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
0624     if (!ddata)
0625         return -ENOMEM;
0626 
0627     ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
0628     if (!ddata->reg)
0629         return -ENODEV;
0630 
0631     otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
0632     if (!otg)
0633         return -ENOMEM;
0634 
0635     ddata->dev = &pdev->dev;
0636     ddata->phy.dev = ddata->dev;
0637     ddata->phy.label = "cpcap_usb_phy";
0638     ddata->phy.otg = otg;
0639     ddata->phy.type = USB_PHY_TYPE_USB2;
0640     otg->set_host = cpcap_usb_phy_set_host;
0641     otg->set_peripheral = cpcap_usb_phy_set_peripheral;
0642     otg->usb_phy = &ddata->phy;
0643     INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect);
0644     platform_set_drvdata(pdev, ddata);
0645 
0646     ddata->vusb = devm_regulator_get(&pdev->dev, "vusb");
0647     if (IS_ERR(ddata->vusb))
0648         return PTR_ERR(ddata->vusb);
0649 
0650     error = regulator_enable(ddata->vusb);
0651     if (error)
0652         return error;
0653 
0654     generic_phy = devm_phy_create(ddata->dev, NULL, &ops);
0655     if (IS_ERR(generic_phy)) {
0656         error = PTR_ERR(generic_phy);
0657         goto out_reg_disable;
0658     }
0659 
0660     phy_set_drvdata(generic_phy, ddata);
0661 
0662     phy_provider = devm_of_phy_provider_register(ddata->dev,
0663                              of_phy_simple_xlate);
0664     if (IS_ERR(phy_provider)) {
0665         error = PTR_ERR(phy_provider);
0666         goto out_reg_disable;
0667     }
0668 
0669     error = cpcap_usb_init_optional_pins(ddata);
0670     if (error)
0671         goto out_reg_disable;
0672 
0673     cpcap_usb_init_optional_gpios(ddata);
0674 
0675     error = cpcap_usb_init_iio(ddata);
0676     if (error)
0677         goto out_reg_disable;
0678 
0679     error = cpcap_usb_init_interrupts(pdev, ddata);
0680     if (error)
0681         goto out_reg_disable;
0682 
0683     usb_add_phy_dev(&ddata->phy);
0684     atomic_set(&ddata->active, 1);
0685     schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
0686 
0687     return 0;
0688 
0689 out_reg_disable:
0690     regulator_disable(ddata->vusb);
0691 
0692     return error;
0693 }
0694 
0695 static int cpcap_usb_phy_remove(struct platform_device *pdev)
0696 {
0697     struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev);
0698     int error;
0699 
0700     atomic_set(&ddata->active, 0);
0701     error = cpcap_usb_set_uart_mode(ddata);
0702     if (error)
0703         dev_err(ddata->dev, "could not set UART mode\n");
0704 
0705     cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
0706 
0707     usb_remove_phy(&ddata->phy);
0708     cancel_delayed_work_sync(&ddata->detect_work);
0709     regulator_disable(ddata->vusb);
0710 
0711     return 0;
0712 }
0713 
0714 static struct platform_driver cpcap_usb_phy_driver = {
0715     .probe      = cpcap_usb_phy_probe,
0716     .remove     = cpcap_usb_phy_remove,
0717     .driver     = {
0718         .name   = "cpcap-usb-phy",
0719         .of_match_table = of_match_ptr(cpcap_usb_phy_id_table),
0720     },
0721 };
0722 
0723 module_platform_driver(cpcap_usb_phy_driver);
0724 
0725 MODULE_ALIAS("platform:cpcap_usb");
0726 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
0727 MODULE_DESCRIPTION("CPCAP usb phy driver");
0728 MODULE_LICENSE("GPL v2");