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