Skip to content

Commit 9492535

Browse files
tmlindkishon
authored andcommitted
phy: cpcap-usb: Improve host vs docked mode detection
When docked to a Motorola lapdock or media dock, we're in USB A-host mode with VBUS provided by the dock. When in regular USB A-host mode, we're providing the VBUS. And in regular USB A-host mode we must also keep kicking the VBUS to keep it active. Let's wait a bit before configuring the USB PHY to allow some time between the ID and VBUS changes. And let's add vbus_provider flag so we can detect docked mode and regularo USB A-host mode better. With better USB A-host mode detection, we can now also just kick the VBUS to keep it enabled and leave out the unnecessary line muxing. We only need to set and clear vbus_provider in the delayed work so no locking is needed for it currently. Cc: Merlijn Wajer <[email protected]> Cc: Pavel Machek <[email protected]> Cc: Sebastian Reichel <[email protected]> Acked-by: Pavel Machek <[email protected]> Signed-off-by: Tony Lindgren <[email protected]> Signed-off-by: Kishon Vijay Abraham I <[email protected]>
1 parent 63078b6 commit 9492535

File tree

1 file changed

+58
-15
lines changed

1 file changed

+58
-15
lines changed

drivers/phy/motorola/phy-cpcap-usb.c

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ struct cpcap_phy_ddata {
134134
struct iio_channel *id;
135135
struct regulator *vusb;
136136
atomic_t active;
137+
unsigned int vbus_provider:1;
138+
unsigned int docked:1;
137139
};
138140

139141
static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
@@ -233,8 +235,60 @@ static void cpcap_usb_detect(struct work_struct *work)
233235
if (error)
234236
return;
235237

236-
if (s.id_ground) {
238+
vbus = cpcap_usb_vbus_valid(ddata);
239+
240+
/* We need to kick the VBUS as USB A-host */
241+
if (s.id_ground && ddata->vbus_provider) {
242+
dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");
243+
244+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
245+
246+
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
247+
CPCAP_BIT_VBUSSTBY_EN |
248+
CPCAP_BIT_VBUSEN_SPI,
249+
CPCAP_BIT_VBUSEN_SPI);
250+
if (error)
251+
goto out_err;
252+
253+
return;
254+
}
255+
256+
if (vbus && s.id_ground && ddata->docked) {
257+
dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");
258+
259+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
260+
261+
return;
262+
}
263+
264+
/* No VBUS needed with docks */
265+
if (vbus && s.id_ground && !ddata->vbus_provider) {
266+
dev_dbg(ddata->dev, "connected to a dock\n");
267+
268+
ddata->docked = true;
269+
270+
error = cpcap_usb_set_usb_mode(ddata);
271+
if (error)
272+
goto out_err;
273+
274+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
275+
276+
/*
277+
* Force check state again after musb has reoriented,
278+
* otherwise devices won't enumerate after loading PHY
279+
* driver.
280+
*/
281+
schedule_delayed_work(&ddata->detect_work,
282+
msecs_to_jiffies(1000));
283+
284+
return;
285+
}
286+
287+
if (s.id_ground && !ddata->docked) {
237288
dev_dbg(ddata->dev, "id ground, USB host mode\n");
289+
290+
ddata->vbus_provider = true;
291+
238292
error = cpcap_usb_set_usb_mode(ddata);
239293
if (error)
240294
goto out_err;
@@ -259,21 +313,8 @@ static void cpcap_usb_detect(struct work_struct *work)
259313

260314
vbus = cpcap_usb_vbus_valid(ddata);
261315

316+
/* Otherwise assume we're connected to a USB host */
262317
if (vbus) {
263-
/* Are we connected to a docking station with vbus? */
264-
if (s.id_ground) {
265-
dev_dbg(ddata->dev, "connected to a dock\n");
266-
267-
/* No VBUS needed with docks */
268-
error = cpcap_usb_set_usb_mode(ddata);
269-
if (error)
270-
goto out_err;
271-
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
272-
273-
return;
274-
}
275-
276-
/* Otherwise assume we're connected to a USB host */
277318
dev_dbg(ddata->dev, "connected to USB host\n");
278319
error = cpcap_usb_set_usb_mode(ddata);
279320
if (error)
@@ -283,6 +324,8 @@ static void cpcap_usb_detect(struct work_struct *work)
283324
return;
284325
}
285326

327+
ddata->vbus_provider = false;
328+
ddata->docked = false;
286329
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
287330

288331
/* Default to debug UART mode */

0 commit comments

Comments
 (0)