hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/phy/motorola/phy-cpcap-usb.c
....@@ -122,7 +122,6 @@
122122 struct cpcap_phy_ddata {
123123 struct regmap *reg;
124124 struct device *dev;
125
- struct clk *refclk;
126125 struct usb_phy phy;
127126 struct delayed_work detect_work;
128127 struct pinctrl *pins;
....@@ -134,6 +133,8 @@
134133 struct iio_channel *id;
135134 struct regulator *vusb;
136135 atomic_t active;
136
+ unsigned int vbus_provider:1;
137
+ unsigned int docked:1;
137138 };
138139
139140 static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
....@@ -233,8 +234,60 @@
233234 if (error)
234235 return;
235236
236
- if (s.id_ground) {
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) {
237287 dev_dbg(ddata->dev, "id ground, USB host mode\n");
288
+
289
+ ddata->vbus_provider = true;
290
+
238291 error = cpcap_usb_set_usb_mode(ddata);
239292 if (error)
240293 goto out_err;
....@@ -242,8 +295,9 @@
242295 cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
243296
244297 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
245
- CPCAP_BIT_VBUSSTBY_EN,
246
- CPCAP_BIT_VBUSSTBY_EN);
298
+ CPCAP_BIT_VBUSSTBY_EN |
299
+ CPCAP_BIT_VBUSEN_SPI,
300
+ CPCAP_BIT_VBUSEN_SPI);
247301 if (error)
248302 goto out_err;
249303
....@@ -251,27 +305,15 @@
251305 }
252306
253307 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
254
- CPCAP_BIT_VBUSSTBY_EN, 0);
308
+ CPCAP_BIT_VBUSSTBY_EN |
309
+ CPCAP_BIT_VBUSEN_SPI, 0);
255310 if (error)
256311 goto out_err;
257312
258313 vbus = cpcap_usb_vbus_valid(ddata);
259314
315
+ /* Otherwise assume we're connected to a USB host */
260316 if (vbus) {
261
- /* Are we connected to a docking station with vbus? */
262
- if (s.id_ground) {
263
- dev_dbg(ddata->dev, "connected to a dock\n");
264
-
265
- /* No VBUS needed with docks */
266
- error = cpcap_usb_set_usb_mode(ddata);
267
- if (error)
268
- goto out_err;
269
- cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
270
-
271
- return;
272
- }
273
-
274
- /* Otherwise assume we're connected to a USB host */
275317 dev_dbg(ddata->dev, "connected to USB host\n");
276318 error = cpcap_usb_set_usb_mode(ddata);
277319 if (error)
....@@ -281,6 +323,8 @@
281323 return;
282324 }
283325
326
+ ddata->vbus_provider = false;
327
+ ddata->docked = false;
284328 cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
285329
286330 /* Default to debug UART mode */
....@@ -320,7 +364,8 @@
320364
321365 error = devm_request_threaded_irq(ddata->dev, irq, NULL,
322366 cpcap_phy_irq_thread,
323
- IRQF_SHARED,
367
+ IRQF_SHARED |
368
+ IRQF_ONESHOT,
324369 name, ddata);
325370 if (error) {
326371 dev_err(ddata->dev, "could not get irq %s: %i\n",
....@@ -441,12 +486,6 @@
441486
442487 error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
443488 CPCAP_BIT_VBUSPD, 0);
444
- if (error)
445
- goto out_err;
446
-
447
- error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
448
- CPCAP_BIT_USBXCVREN,
449
- CPCAP_BIT_USBXCVREN);
450489 if (error)
451490 goto out_err;
452491
....@@ -675,7 +714,6 @@
675714
676715 usb_remove_phy(&ddata->phy);
677716 cancel_delayed_work_sync(&ddata->detect_work);
678
- clk_unprepare(ddata->refclk);
679717 regulator_disable(ddata->vusb);
680718
681719 return 0;