phy-cpcap-usb.c (17085B)
1/* 2 * Motorola CPCAP PMIC USB PHY driver 3 * Copyright (C) 2017 Tony Lindgren <tony@atomide.com> 4 * 5 * Some parts based on earlier Motorola Linux kernel tree code in 6 * board-mapphone-usb.c and cpcap-usb-det.c: 7 * Copyright (C) 2007 - 2011 Motorola, Inc. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation version 2. 12 * 13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 14 * kind, whether express or implied; without even the implied warranty 15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19#include <linux/atomic.h> 20#include <linux/clk.h> 21#include <linux/delay.h> 22#include <linux/err.h> 23#include <linux/io.h> 24#include <linux/module.h> 25#include <linux/of.h> 26#include <linux/of_platform.h> 27#include <linux/iio/consumer.h> 28#include <linux/pinctrl/consumer.h> 29#include <linux/platform_device.h> 30#include <linux/regmap.h> 31#include <linux/slab.h> 32 33#include <linux/gpio/consumer.h> 34#include <linux/mfd/motorola-cpcap.h> 35#include <linux/phy/omap_usb.h> 36#include <linux/phy/phy.h> 37#include <linux/regulator/consumer.h> 38#include <linux/usb/musb.h> 39 40/* CPCAP_REG_USBC1 register bits */ 41#define CPCAP_BIT_IDPULSE BIT(15) 42#define CPCAP_BIT_ID100KPU BIT(14) 43#define CPCAP_BIT_IDPUCNTRL BIT(13) 44#define CPCAP_BIT_IDPU BIT(12) 45#define CPCAP_BIT_IDPD BIT(11) 46#define CPCAP_BIT_VBUSCHRGTMR3 BIT(10) 47#define CPCAP_BIT_VBUSCHRGTMR2 BIT(9) 48#define CPCAP_BIT_VBUSCHRGTMR1 BIT(8) 49#define CPCAP_BIT_VBUSCHRGTMR0 BIT(7) 50#define CPCAP_BIT_VBUSPU BIT(6) 51#define CPCAP_BIT_VBUSPD BIT(5) 52#define CPCAP_BIT_DMPD BIT(4) 53#define CPCAP_BIT_DPPD BIT(3) 54#define CPCAP_BIT_DM1K5PU BIT(2) 55#define CPCAP_BIT_DP1K5PU BIT(1) 56#define CPCAP_BIT_DP150KPU BIT(0) 57 58/* CPCAP_REG_USBC2 register bits */ 59#define CPCAP_BIT_ZHSDRV1 BIT(15) 60#define CPCAP_BIT_ZHSDRV0 BIT(14) 61#define CPCAP_BIT_DPLLCLKREQ BIT(13) 62#define CPCAP_BIT_SE0CONN BIT(12) 63#define CPCAP_BIT_UARTTXTRI BIT(11) 64#define CPCAP_BIT_UARTSWAP BIT(10) 65#define CPCAP_BIT_UARTMUX1 BIT(9) 66#define CPCAP_BIT_UARTMUX0 BIT(8) 67#define CPCAP_BIT_ULPISTPLOW BIT(7) 68#define CPCAP_BIT_TXENPOL BIT(6) 69#define CPCAP_BIT_USBXCVREN BIT(5) 70#define CPCAP_BIT_USBCNTRL BIT(4) 71#define CPCAP_BIT_USBSUSPEND BIT(3) 72#define CPCAP_BIT_EMUMODE2 BIT(2) 73#define CPCAP_BIT_EMUMODE1 BIT(1) 74#define CPCAP_BIT_EMUMODE0 BIT(0) 75 76/* CPCAP_REG_USBC3 register bits */ 77#define CPCAP_BIT_SPARE_898_15 BIT(15) 78#define CPCAP_BIT_IHSTX03 BIT(14) 79#define CPCAP_BIT_IHSTX02 BIT(13) 80#define CPCAP_BIT_IHSTX01 BIT(12) 81#define CPCAP_BIT_IHSTX0 BIT(11) 82#define CPCAP_BIT_IDPU_SPI BIT(10) 83#define CPCAP_BIT_UNUSED_898_9 BIT(9) 84#define CPCAP_BIT_VBUSSTBY_EN BIT(8) 85#define CPCAP_BIT_VBUSEN_SPI BIT(7) 86#define CPCAP_BIT_VBUSPU_SPI BIT(6) 87#define CPCAP_BIT_VBUSPD_SPI BIT(5) 88#define CPCAP_BIT_DMPD_SPI BIT(4) 89#define CPCAP_BIT_DPPD_SPI BIT(3) 90#define CPCAP_BIT_SUSPEND_SPI BIT(2) 91#define CPCAP_BIT_PU_SPI BIT(1) 92#define CPCAP_BIT_ULPI_SPI_SEL BIT(0) 93 94struct cpcap_usb_ints_state { 95 bool id_ground; 96 bool id_float; 97 bool chrg_det; 98 bool rvrs_chrg; 99 bool vbusov; 100 101 bool chrg_se1b; 102 bool se0conn; 103 bool rvrs_mode; 104 bool chrgcurr1; 105 bool vbusvld; 106 bool sessvld; 107 bool sessend; 108 bool se1; 109 110 bool battdetb; 111 bool dm; 112 bool dp; 113}; 114 115enum cpcap_gpio_mode { 116 CPCAP_DM_DP, 117 CPCAP_MDM_RX_TX, 118 CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */ 119 CPCAP_OTG_DM_DP, 120}; 121 122struct cpcap_phy_ddata { 123 struct regmap *reg; 124 struct device *dev; 125 struct usb_phy phy; 126 struct delayed_work detect_work; 127 struct pinctrl *pins; 128 struct pinctrl_state *pins_ulpi; 129 struct pinctrl_state *pins_utmi; 130 struct pinctrl_state *pins_uart; 131 struct gpio_desc *gpio[2]; 132 struct iio_channel *vbus; 133 struct iio_channel *id; 134 struct regulator *vusb; 135 atomic_t active; 136 unsigned int vbus_provider:1; 137 unsigned int docked:1; 138}; 139 140static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata) 141{ 142 int error, value = 0; 143 144 error = iio_read_channel_processed(ddata->vbus, &value); 145 if (error >= 0) 146 return value > 3900; 147 148 dev_err(ddata->dev, "error reading VBUS: %i\n", error); 149 150 return false; 151} 152 153static int cpcap_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host) 154{ 155 otg->host = host; 156 if (!host) 157 otg->state = OTG_STATE_UNDEFINED; 158 159 return 0; 160} 161 162static int cpcap_usb_phy_set_peripheral(struct usb_otg *otg, 163 struct usb_gadget *gadget) 164{ 165 otg->gadget = gadget; 166 if (!gadget) 167 otg->state = OTG_STATE_UNDEFINED; 168 169 return 0; 170} 171 172static const struct phy_ops ops = { 173 .owner = THIS_MODULE, 174}; 175 176static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata, 177 struct cpcap_usb_ints_state *s) 178{ 179 int val, error; 180 181 error = regmap_read(ddata->reg, CPCAP_REG_INTS1, &val); 182 if (error) 183 return error; 184 185 s->id_ground = val & BIT(15); 186 s->id_float = val & BIT(14); 187 s->vbusov = val & BIT(11); 188 189 error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val); 190 if (error) 191 return error; 192 193 s->vbusvld = val & BIT(3); 194 s->sessvld = val & BIT(2); 195 s->sessend = val & BIT(1); 196 s->se1 = val & BIT(0); 197 198 error = regmap_read(ddata->reg, CPCAP_REG_INTS4, &val); 199 if (error) 200 return error; 201 202 s->dm = val & BIT(1); 203 s->dp = val & BIT(0); 204 205 return 0; 206} 207 208static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata); 209static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata); 210 211static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata, 212 enum musb_vbus_id_status status) 213{ 214 int error; 215 216 error = musb_mailbox(status); 217 if (!error) 218 return; 219 220 dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n", 221 __func__, error); 222} 223 224static void cpcap_usb_detect(struct work_struct *work) 225{ 226 struct cpcap_phy_ddata *ddata; 227 struct cpcap_usb_ints_state s; 228 bool vbus = false; 229 int error; 230 231 ddata = container_of(work, struct cpcap_phy_ddata, detect_work.work); 232 233 error = cpcap_phy_get_ints_state(ddata, &s); 234 if (error) 235 return; 236 237 vbus = cpcap_usb_vbus_valid(ddata); 238 239 /* We need to kick the VBUS as USB A-host */ 240 if (s.id_ground && ddata->vbus_provider) { 241 dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n"); 242 243 cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); 244 245 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 246 CPCAP_BIT_VBUSSTBY_EN | 247 CPCAP_BIT_VBUSEN_SPI, 248 CPCAP_BIT_VBUSEN_SPI); 249 if (error) 250 goto out_err; 251 252 return; 253 } 254 255 if (vbus && s.id_ground && ddata->docked) { 256 dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n"); 257 258 cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); 259 260 return; 261 } 262 263 /* No VBUS needed with docks */ 264 if (vbus && s.id_ground && !ddata->vbus_provider) { 265 dev_dbg(ddata->dev, "connected to a dock\n"); 266 267 ddata->docked = true; 268 269 error = cpcap_usb_set_usb_mode(ddata); 270 if (error) 271 goto out_err; 272 273 cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); 274 275 /* 276 * Force check state again after musb has reoriented, 277 * otherwise devices won't enumerate after loading PHY 278 * driver. 279 */ 280 schedule_delayed_work(&ddata->detect_work, 281 msecs_to_jiffies(1000)); 282 283 return; 284 } 285 286 if (s.id_ground && !ddata->docked) { 287 dev_dbg(ddata->dev, "id ground, USB host mode\n"); 288 289 ddata->vbus_provider = true; 290 291 error = cpcap_usb_set_usb_mode(ddata); 292 if (error) 293 goto out_err; 294 295 cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); 296 297 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 298 CPCAP_BIT_VBUSSTBY_EN | 299 CPCAP_BIT_VBUSEN_SPI, 300 CPCAP_BIT_VBUSEN_SPI); 301 if (error) 302 goto out_err; 303 304 return; 305 } 306 307 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 308 CPCAP_BIT_VBUSSTBY_EN | 309 CPCAP_BIT_VBUSEN_SPI, 0); 310 if (error) 311 goto out_err; 312 313 vbus = cpcap_usb_vbus_valid(ddata); 314 315 /* Otherwise assume we're connected to a USB host */ 316 if (vbus) { 317 dev_dbg(ddata->dev, "connected to USB host\n"); 318 error = cpcap_usb_set_usb_mode(ddata); 319 if (error) 320 goto out_err; 321 cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID); 322 323 return; 324 } 325 326 ddata->vbus_provider = false; 327 ddata->docked = false; 328 cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); 329 330 /* Default to debug UART mode */ 331 error = cpcap_usb_set_uart_mode(ddata); 332 if (error) 333 goto out_err; 334 335 dev_dbg(ddata->dev, "set UART mode\n"); 336 337 return; 338 339out_err: 340 dev_err(ddata->dev, "error setting cable state: %i\n", error); 341} 342 343static irqreturn_t cpcap_phy_irq_thread(int irq, void *data) 344{ 345 struct cpcap_phy_ddata *ddata = data; 346 347 if (!atomic_read(&ddata->active)) 348 return IRQ_NONE; 349 350 schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1)); 351 352 return IRQ_HANDLED; 353} 354 355static int cpcap_usb_init_irq(struct platform_device *pdev, 356 struct cpcap_phy_ddata *ddata, 357 const char *name) 358{ 359 int irq, error; 360 361 irq = platform_get_irq_byname(pdev, name); 362 if (irq < 0) 363 return -ENODEV; 364 365 error = devm_request_threaded_irq(ddata->dev, irq, NULL, 366 cpcap_phy_irq_thread, 367 IRQF_SHARED | 368 IRQF_ONESHOT, 369 name, ddata); 370 if (error) { 371 dev_err(ddata->dev, "could not get irq %s: %i\n", 372 name, error); 373 374 return error; 375 } 376 377 return 0; 378} 379 380static const char * const cpcap_phy_irqs[] = { 381 /* REG_INT_0 */ 382 "id_ground", "id_float", 383 384 /* REG_INT1 */ 385 "se0conn", "vbusvld", "sessvld", "sessend", "se1", 386 387 /* REG_INT_3 */ 388 "dm", "dp", 389}; 390 391static int cpcap_usb_init_interrupts(struct platform_device *pdev, 392 struct cpcap_phy_ddata *ddata) 393{ 394 int i, error; 395 396 for (i = 0; i < ARRAY_SIZE(cpcap_phy_irqs); i++) { 397 error = cpcap_usb_init_irq(pdev, ddata, cpcap_phy_irqs[i]); 398 if (error) 399 return error; 400 } 401 402 return 0; 403} 404 405/* 406 * Optional pins and modes. At least Motorola mapphone devices 407 * are using two GPIOs and dynamic pinctrl to multiplex PHY pins 408 * to UART, ULPI or UTMI mode. 409 */ 410 411static int cpcap_usb_gpio_set_mode(struct cpcap_phy_ddata *ddata, 412 enum cpcap_gpio_mode mode) 413{ 414 if (!ddata->gpio[0] || !ddata->gpio[1]) 415 return 0; 416 417 gpiod_set_value(ddata->gpio[0], mode & 1); 418 gpiod_set_value(ddata->gpio[1], mode >> 1); 419 420 return 0; 421} 422 423static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata) 424{ 425 int error; 426 427 /* Disable lines to prevent glitches from waking up mdm6600 */ 428 error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED); 429 if (error) 430 goto out_err; 431 432 if (ddata->pins_uart) { 433 error = pinctrl_select_state(ddata->pins, ddata->pins_uart); 434 if (error) 435 goto out_err; 436 } 437 438 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1, 439 CPCAP_BIT_VBUSPD, 440 CPCAP_BIT_VBUSPD); 441 if (error) 442 goto out_err; 443 444 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2, 445 0xffff, CPCAP_BIT_UARTMUX0 | 446 CPCAP_BIT_EMUMODE0); 447 if (error) 448 goto out_err; 449 450 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff, 451 CPCAP_BIT_IDPU_SPI); 452 if (error) 453 goto out_err; 454 455 /* Enable UART mode */ 456 error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP); 457 if (error) 458 goto out_err; 459 460 return 0; 461 462out_err: 463 dev_err(ddata->dev, "%s failed with %i\n", __func__, error); 464 465 return error; 466} 467 468static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata) 469{ 470 int error; 471 472 /* Disable lines to prevent glitches from waking up mdm6600 */ 473 error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED); 474 if (error) 475 return error; 476 477 if (ddata->pins_utmi) { 478 error = pinctrl_select_state(ddata->pins, ddata->pins_utmi); 479 if (error) { 480 dev_err(ddata->dev, "could not set usb mode: %i\n", 481 error); 482 483 return error; 484 } 485 } 486 487 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1, 488 CPCAP_BIT_VBUSPD, 0); 489 if (error) 490 goto out_err; 491 492 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 493 CPCAP_BIT_PU_SPI | 494 CPCAP_BIT_DMPD_SPI | 495 CPCAP_BIT_DPPD_SPI | 496 CPCAP_BIT_SUSPEND_SPI | 497 CPCAP_BIT_ULPI_SPI_SEL, 0); 498 if (error) 499 goto out_err; 500 501 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2, 502 CPCAP_BIT_USBXCVREN, 503 CPCAP_BIT_USBXCVREN); 504 if (error) 505 goto out_err; 506 507 /* Enable USB mode */ 508 error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP); 509 if (error) 510 goto out_err; 511 512 return 0; 513 514out_err: 515 dev_err(ddata->dev, "%s failed with %i\n", __func__, error); 516 517 return error; 518} 519 520static int cpcap_usb_init_optional_pins(struct cpcap_phy_ddata *ddata) 521{ 522 ddata->pins = devm_pinctrl_get(ddata->dev); 523 if (IS_ERR(ddata->pins)) { 524 dev_info(ddata->dev, "default pins not configured: %ld\n", 525 PTR_ERR(ddata->pins)); 526 ddata->pins = NULL; 527 528 return 0; 529 } 530 531 ddata->pins_ulpi = pinctrl_lookup_state(ddata->pins, "ulpi"); 532 if (IS_ERR(ddata->pins_ulpi)) { 533 dev_info(ddata->dev, "ulpi pins not configured\n"); 534 ddata->pins_ulpi = NULL; 535 } 536 537 ddata->pins_utmi = pinctrl_lookup_state(ddata->pins, "utmi"); 538 if (IS_ERR(ddata->pins_utmi)) { 539 dev_info(ddata->dev, "utmi pins not configured\n"); 540 ddata->pins_utmi = NULL; 541 } 542 543 ddata->pins_uart = pinctrl_lookup_state(ddata->pins, "uart"); 544 if (IS_ERR(ddata->pins_uart)) { 545 dev_info(ddata->dev, "uart pins not configured\n"); 546 ddata->pins_uart = NULL; 547 } 548 549 if (ddata->pins_uart) 550 return pinctrl_select_state(ddata->pins, ddata->pins_uart); 551 552 return 0; 553} 554 555static void cpcap_usb_init_optional_gpios(struct cpcap_phy_ddata *ddata) 556{ 557 int i; 558 559 for (i = 0; i < 2; i++) { 560 ddata->gpio[i] = devm_gpiod_get_index(ddata->dev, "mode", 561 i, GPIOD_OUT_HIGH); 562 if (IS_ERR(ddata->gpio[i])) { 563 dev_info(ddata->dev, "no mode change GPIO%i: %li\n", 564 i, PTR_ERR(ddata->gpio[i])); 565 ddata->gpio[i] = NULL; 566 } 567 } 568} 569 570static int cpcap_usb_init_iio(struct cpcap_phy_ddata *ddata) 571{ 572 enum iio_chan_type type; 573 int error; 574 575 ddata->vbus = devm_iio_channel_get(ddata->dev, "vbus"); 576 if (IS_ERR(ddata->vbus)) { 577 error = PTR_ERR(ddata->vbus); 578 goto out_err; 579 } 580 581 if (!ddata->vbus->indio_dev) { 582 error = -ENXIO; 583 goto out_err; 584 } 585 586 error = iio_get_channel_type(ddata->vbus, &type); 587 if (error < 0) 588 goto out_err; 589 590 if (type != IIO_VOLTAGE) { 591 error = -EINVAL; 592 goto out_err; 593 } 594 595 return 0; 596 597out_err: 598 dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n", 599 error); 600 601 return error; 602} 603 604#ifdef CONFIG_OF 605static const struct of_device_id cpcap_usb_phy_id_table[] = { 606 { 607 .compatible = "motorola,cpcap-usb-phy", 608 }, 609 { 610 .compatible = "motorola,mapphone-cpcap-usb-phy", 611 }, 612 {}, 613}; 614MODULE_DEVICE_TABLE(of, cpcap_usb_phy_id_table); 615#endif 616 617static int cpcap_usb_phy_probe(struct platform_device *pdev) 618{ 619 struct cpcap_phy_ddata *ddata; 620 struct phy *generic_phy; 621 struct phy_provider *phy_provider; 622 struct usb_otg *otg; 623 const struct of_device_id *of_id; 624 int error; 625 626 of_id = of_match_device(of_match_ptr(cpcap_usb_phy_id_table), 627 &pdev->dev); 628 if (!of_id) 629 return -EINVAL; 630 631 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); 632 if (!ddata) 633 return -ENOMEM; 634 635 ddata->reg = dev_get_regmap(pdev->dev.parent, NULL); 636 if (!ddata->reg) 637 return -ENODEV; 638 639 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 640 if (!otg) 641 return -ENOMEM; 642 643 ddata->dev = &pdev->dev; 644 ddata->phy.dev = ddata->dev; 645 ddata->phy.label = "cpcap_usb_phy"; 646 ddata->phy.otg = otg; 647 ddata->phy.type = USB_PHY_TYPE_USB2; 648 otg->set_host = cpcap_usb_phy_set_host; 649 otg->set_peripheral = cpcap_usb_phy_set_peripheral; 650 otg->usb_phy = &ddata->phy; 651 INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect); 652 platform_set_drvdata(pdev, ddata); 653 654 ddata->vusb = devm_regulator_get(&pdev->dev, "vusb"); 655 if (IS_ERR(ddata->vusb)) 656 return PTR_ERR(ddata->vusb); 657 658 error = regulator_enable(ddata->vusb); 659 if (error) 660 return error; 661 662 generic_phy = devm_phy_create(ddata->dev, NULL, &ops); 663 if (IS_ERR(generic_phy)) { 664 error = PTR_ERR(generic_phy); 665 goto out_reg_disable; 666 } 667 668 phy_set_drvdata(generic_phy, ddata); 669 670 phy_provider = devm_of_phy_provider_register(ddata->dev, 671 of_phy_simple_xlate); 672 if (IS_ERR(phy_provider)) { 673 error = PTR_ERR(phy_provider); 674 goto out_reg_disable; 675 } 676 677 error = cpcap_usb_init_optional_pins(ddata); 678 if (error) 679 goto out_reg_disable; 680 681 cpcap_usb_init_optional_gpios(ddata); 682 683 error = cpcap_usb_init_iio(ddata); 684 if (error) 685 goto out_reg_disable; 686 687 error = cpcap_usb_init_interrupts(pdev, ddata); 688 if (error) 689 goto out_reg_disable; 690 691 usb_add_phy_dev(&ddata->phy); 692 atomic_set(&ddata->active, 1); 693 schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1)); 694 695 return 0; 696 697out_reg_disable: 698 regulator_disable(ddata->vusb); 699 700 return error; 701} 702 703static int cpcap_usb_phy_remove(struct platform_device *pdev) 704{ 705 struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev); 706 int error; 707 708 atomic_set(&ddata->active, 0); 709 error = cpcap_usb_set_uart_mode(ddata); 710 if (error) 711 dev_err(ddata->dev, "could not set UART mode\n"); 712 713 cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); 714 715 usb_remove_phy(&ddata->phy); 716 cancel_delayed_work_sync(&ddata->detect_work); 717 regulator_disable(ddata->vusb); 718 719 return 0; 720} 721 722static struct platform_driver cpcap_usb_phy_driver = { 723 .probe = cpcap_usb_phy_probe, 724 .remove = cpcap_usb_phy_remove, 725 .driver = { 726 .name = "cpcap-usb-phy", 727 .of_match_table = of_match_ptr(cpcap_usb_phy_id_table), 728 }, 729}; 730 731module_platform_driver(cpcap_usb_phy_driver); 732 733MODULE_ALIAS("platform:cpcap_usb"); 734MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); 735MODULE_DESCRIPTION("CPCAP usb phy driver"); 736MODULE_LICENSE("GPL v2");