forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/usb/typec/tps6598x.c
....@@ -12,8 +12,11 @@
1212 #include <linux/regmap.h>
1313 #include <linux/interrupt.h>
1414 #include <linux/usb/typec.h>
15
+#include <linux/usb/role.h>
1516
1617 /* Register offsets */
18
+#define TPS_REG_VID 0x00
19
+#define TPS_REG_MODE 0x03
1720 #define TPS_REG_CMD1 0x08
1821 #define TPS_REG_DATA1 0x09
1922 #define TPS_REG_INT_EVENT1 0x14
....@@ -59,12 +62,25 @@
5962 struct tps6598x_rx_identity_reg {
6063 u8 status;
6164 struct usb_pd_identity identity;
62
- u32 vdo[3];
6365 } __packed;
6466
6567 /* Standard Task return codes */
6668 #define TPS_TASK_TIMEOUT 1
6769 #define TPS_TASK_REJECTED 3
70
+
71
+enum {
72
+ TPS_MODE_APP,
73
+ TPS_MODE_BOOT,
74
+ TPS_MODE_BIST,
75
+ TPS_MODE_DISC,
76
+};
77
+
78
+static const char *const modes[] = {
79
+ [TPS_MODE_APP] = "APP ",
80
+ [TPS_MODE_BOOT] = "BOOT",
81
+ [TPS_MODE_BIST] = "BIST",
82
+ [TPS_MODE_DISC] = "DISC",
83
+};
6884
6985 /* Unrecognized commands will be replaced with "!CMD" */
7086 #define INVALID_CMD(_cmd_) (_cmd_ == 0x444d4321)
....@@ -78,12 +94,12 @@
7894 struct typec_port *port;
7995 struct typec_partner *partner;
8096 struct usb_pd_identity partner_identity;
81
- struct typec_capability typec_cap;
97
+ struct usb_role_switch *role_sw;
8298 };
8399
84100 /*
85101 * Max data bytes for Data1, Data2, and other registers. See ch 1.3.2:
86
- * http://www.ti.com/lit/ug/slvuan1a/slvuan1a.pdf
102
+ * https://www.ti.com/lit/ug/slvuan1a/slvuan1a.pdf
87103 */
88104 #define TPS_MAX_LEN 64
89105
....@@ -175,6 +191,23 @@
175191 return 0;
176192 }
177193
194
+static void tps6598x_set_data_role(struct tps6598x *tps,
195
+ enum typec_data_role role, bool connected)
196
+{
197
+ enum usb_role role_val;
198
+
199
+ if (role == TYPEC_HOST)
200
+ role_val = USB_ROLE_HOST;
201
+ else
202
+ role_val = USB_ROLE_DEVICE;
203
+
204
+ if (!connected)
205
+ role_val = USB_ROLE_NONE;
206
+
207
+ usb_role_switch_set_role(tps->role_sw, role_val);
208
+ typec_set_data_role(tps->port, role);
209
+}
210
+
178211 static int tps6598x_connect(struct tps6598x *tps, u32 status)
179212 {
180213 struct typec_partner_desc desc;
....@@ -205,7 +238,7 @@
205238 typec_set_pwr_opmode(tps->port, mode);
206239 typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status));
207240 typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status));
208
- typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status));
241
+ tps6598x_set_data_role(tps, TPS_STATUS_DATAROLE(status), true);
209242
210243 tps->partner = typec_register_partner(tps->port, &desc);
211244 if (IS_ERR(tps->partner))
....@@ -225,7 +258,7 @@
225258 typec_set_pwr_opmode(tps->port, TYPEC_PWR_MODE_USB);
226259 typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status));
227260 typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status));
228
- typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status));
261
+ tps6598x_set_data_role(tps, TPS_STATUS_DATAROLE(status), false);
229262 }
230263
231264 static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd,
....@@ -291,11 +324,10 @@
291324 return 0;
292325 }
293326
294
-static int
295
-tps6598x_dr_set(const struct typec_capability *cap, enum typec_data_role role)
327
+static int tps6598x_dr_set(struct typec_port *port, enum typec_data_role role)
296328 {
297
- struct tps6598x *tps = container_of(cap, struct tps6598x, typec_cap);
298329 const char *cmd = (role == TYPEC_DEVICE) ? "SWUF" : "SWDF";
330
+ struct tps6598x *tps = typec_get_drvdata(port);
299331 u32 status;
300332 int ret;
301333
....@@ -314,7 +346,7 @@
314346 goto out_unlock;
315347 }
316348
317
- typec_set_data_role(tps->port, role);
349
+ tps6598x_set_data_role(tps, role, true);
318350
319351 out_unlock:
320352 mutex_unlock(&tps->lock);
....@@ -322,11 +354,10 @@
322354 return ret;
323355 }
324356
325
-static int
326
-tps6598x_pr_set(const struct typec_capability *cap, enum typec_role role)
357
+static int tps6598x_pr_set(struct typec_port *port, enum typec_role role)
327358 {
328
- struct tps6598x *tps = container_of(cap, struct tps6598x, typec_cap);
329359 const char *cmd = (role == TYPEC_SINK) ? "SWSk" : "SWSr";
360
+ struct tps6598x *tps = typec_get_drvdata(port);
330361 u32 status;
331362 int ret;
332363
....@@ -352,6 +383,11 @@
352383
353384 return ret;
354385 }
386
+
387
+static const struct typec_operations tps6598x_ops = {
388
+ .dr_set = tps6598x_dr_set,
389
+ .pr_set = tps6598x_pr_set,
390
+};
355391
356392 static irqreturn_t tps6598x_interrupt(int irq, void *data)
357393 {
....@@ -398,6 +434,32 @@
398434 return IRQ_HANDLED;
399435 }
400436
437
+static int tps6598x_check_mode(struct tps6598x *tps)
438
+{
439
+ char mode[5] = { };
440
+ int ret;
441
+
442
+ ret = tps6598x_read32(tps, TPS_REG_MODE, (void *)mode);
443
+ if (ret)
444
+ return ret;
445
+
446
+ switch (match_string(modes, ARRAY_SIZE(modes), mode)) {
447
+ case TPS_MODE_APP:
448
+ return 0;
449
+ case TPS_MODE_BOOT:
450
+ dev_warn(tps->dev, "dead-battery condition\n");
451
+ return 0;
452
+ case TPS_MODE_BIST:
453
+ case TPS_MODE_DISC:
454
+ default:
455
+ dev_err(tps->dev, "controller in unsupported mode \"%s\"\n",
456
+ mode);
457
+ break;
458
+ }
459
+
460
+ return -ENODEV;
461
+}
462
+
401463 static const struct regmap_config tps6598x_regmap_config = {
402464 .reg_bits = 8,
403465 .val_bits = 8,
....@@ -406,7 +468,9 @@
406468
407469 static int tps6598x_probe(struct i2c_client *client)
408470 {
471
+ struct typec_capability typec_cap = { };
409472 struct tps6598x *tps;
473
+ struct fwnode_handle *fwnode;
410474 u32 status;
411475 u32 conf;
412476 u32 vid;
....@@ -423,10 +487,8 @@
423487 if (IS_ERR(tps->regmap))
424488 return PTR_ERR(tps->regmap);
425489
426
- ret = tps6598x_read32(tps, 0, &vid);
427
- if (ret < 0)
428
- return ret;
429
- if (!vid)
490
+ ret = tps6598x_read32(tps, TPS_REG_VID, &vid);
491
+ if (ret < 0 || !vid)
430492 return -ENODEV;
431493
432494 /*
....@@ -439,6 +501,11 @@
439501 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
440502 tps->i2c_protocol = true;
441503
504
+ /* Make sure the controller has application firmware running */
505
+ ret = tps6598x_check_mode(tps);
506
+ if (ret)
507
+ return ret;
508
+
442509 ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
443510 if (ret < 0)
444511 return ret;
....@@ -447,42 +514,57 @@
447514 if (ret < 0)
448515 return ret;
449516
450
- tps->typec_cap.revision = USB_TYPEC_REV_1_2;
451
- tps->typec_cap.pd_revision = 0x200;
452
- tps->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
453
- tps->typec_cap.pr_set = tps6598x_pr_set;
454
- tps->typec_cap.dr_set = tps6598x_dr_set;
517
+ fwnode = device_get_named_child_node(&client->dev, "connector");
518
+ if (!fwnode)
519
+ return -ENODEV;
520
+
521
+ tps->role_sw = fwnode_usb_role_switch_get(fwnode);
522
+ if (IS_ERR(tps->role_sw)) {
523
+ ret = PTR_ERR(tps->role_sw);
524
+ goto err_fwnode_put;
525
+ }
526
+
527
+ typec_cap.revision = USB_TYPEC_REV_1_2;
528
+ typec_cap.pd_revision = 0x200;
529
+ typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
530
+ typec_cap.driver_data = tps;
531
+ typec_cap.ops = &tps6598x_ops;
532
+ typec_cap.fwnode = fwnode;
455533
456534 switch (TPS_SYSCONF_PORTINFO(conf)) {
457535 case TPS_PORTINFO_SINK_ACCESSORY:
458536 case TPS_PORTINFO_SINK:
459
- tps->typec_cap.type = TYPEC_PORT_SNK;
460
- tps->typec_cap.data = TYPEC_PORT_UFP;
537
+ typec_cap.type = TYPEC_PORT_SNK;
538
+ typec_cap.data = TYPEC_PORT_UFP;
461539 break;
462540 case TPS_PORTINFO_DRP_UFP_DRD:
463541 case TPS_PORTINFO_DRP_DFP_DRD:
464
- tps->typec_cap.type = TYPEC_PORT_DRP;
465
- tps->typec_cap.data = TYPEC_PORT_DRD;
542
+ typec_cap.type = TYPEC_PORT_DRP;
543
+ typec_cap.data = TYPEC_PORT_DRD;
466544 break;
467545 case TPS_PORTINFO_DRP_UFP:
468
- tps->typec_cap.type = TYPEC_PORT_DRP;
469
- tps->typec_cap.data = TYPEC_PORT_UFP;
546
+ typec_cap.type = TYPEC_PORT_DRP;
547
+ typec_cap.data = TYPEC_PORT_UFP;
470548 break;
471549 case TPS_PORTINFO_DRP_DFP:
472
- tps->typec_cap.type = TYPEC_PORT_DRP;
473
- tps->typec_cap.data = TYPEC_PORT_DFP;
550
+ typec_cap.type = TYPEC_PORT_DRP;
551
+ typec_cap.data = TYPEC_PORT_DFP;
474552 break;
475553 case TPS_PORTINFO_SOURCE:
476
- tps->typec_cap.type = TYPEC_PORT_SRC;
477
- tps->typec_cap.data = TYPEC_PORT_DFP;
554
+ typec_cap.type = TYPEC_PORT_SRC;
555
+ typec_cap.data = TYPEC_PORT_DFP;
478556 break;
479557 default:
480
- return -ENODEV;
558
+ ret = -ENODEV;
559
+ goto err_role_put;
481560 }
482561
483
- tps->port = typec_register_port(&client->dev, &tps->typec_cap);
484
- if (IS_ERR(tps->port))
485
- return PTR_ERR(tps->port);
562
+ tps->port = typec_register_port(&client->dev, &typec_cap);
563
+ if (IS_ERR(tps->port)) {
564
+ ret = PTR_ERR(tps->port);
565
+ goto err_role_put;
566
+ }
567
+ fwnode_handle_put(fwnode);
486568
487569 if (status & TPS_STATUS_PLUG_PRESENT) {
488570 ret = tps6598x_connect(tps, status);
....@@ -497,12 +579,19 @@
497579 if (ret) {
498580 tps6598x_disconnect(tps, 0);
499581 typec_unregister_port(tps->port);
500
- return ret;
582
+ goto err_role_put;
501583 }
502584
503585 i2c_set_clientdata(client, tps);
504586
505587 return 0;
588
+
589
+err_role_put:
590
+ usb_role_switch_put(tps->role_sw);
591
+err_fwnode_put:
592
+ fwnode_handle_put(fwnode);
593
+
594
+ return ret;
506595 }
507596
508597 static int tps6598x_remove(struct i2c_client *client)
....@@ -511,23 +600,31 @@
511600
512601 tps6598x_disconnect(tps, 0);
513602 typec_unregister_port(tps->port);
603
+ usb_role_switch_put(tps->role_sw);
514604
515605 return 0;
516606 }
517607
518
-static const struct acpi_device_id tps6598x_acpi_match[] = {
519
- { "INT3515", 0 },
608
+static const struct of_device_id tps6598x_of_match[] = {
609
+ { .compatible = "ti,tps6598x", },
610
+ {}
611
+};
612
+MODULE_DEVICE_TABLE(of, tps6598x_of_match);
613
+
614
+static const struct i2c_device_id tps6598x_id[] = {
615
+ { "tps6598x" },
520616 { }
521617 };
522
-MODULE_DEVICE_TABLE(acpi, tps6598x_acpi_match);
618
+MODULE_DEVICE_TABLE(i2c, tps6598x_id);
523619
524620 static struct i2c_driver tps6598x_i2c_driver = {
525621 .driver = {
526622 .name = "tps6598x",
527
- .acpi_match_table = tps6598x_acpi_match,
623
+ .of_match_table = tps6598x_of_match,
528624 },
529625 .probe_new = tps6598x_probe,
530626 .remove = tps6598x_remove,
627
+ .id_table = tps6598x_id,
531628 };
532629 module_i2c_driver(tps6598x_i2c_driver);
533630