]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/usb/typec/tps6598x.c
1c0033ad87382d6c28742719bc17f341dc56ea85
[linux.git] / drivers / usb / typec / tps6598x.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for TI TPS6598x USB Power Delivery controller family
4  *
5  * Copyright (C) 2017, Intel Corporation
6  * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
7  */
8
9 #include <linux/i2c.h>
10 #include <linux/acpi.h>
11 #include <linux/module.h>
12 #include <linux/regmap.h>
13 #include <linux/interrupt.h>
14 #include <linux/usb/typec.h>
15
16 /* Register offsets */
17 #define TPS_REG_CMD1                    0x08
18 #define TPS_REG_DATA1                   0x09
19 #define TPS_REG_INT_EVENT1              0x14
20 #define TPS_REG_INT_EVENT2              0x15
21 #define TPS_REG_INT_MASK1               0x16
22 #define TPS_REG_INT_MASK2               0x17
23 #define TPS_REG_INT_CLEAR1              0x18
24 #define TPS_REG_INT_CLEAR2              0x19
25 #define TPS_REG_STATUS                  0x1a
26 #define TPS_REG_SYSTEM_CONF             0x28
27 #define TPS_REG_CTRL_CONF               0x29
28 #define TPS_REG_POWER_STATUS            0x3f
29 #define TPS_REG_RX_IDENTITY_SOP         0x48
30
31 /* TPS_REG_INT_* bits */
32 #define TPS_REG_INT_PLUG_EVENT          BIT(3)
33
34 /* TPS_REG_STATUS bits */
35 #define TPS_STATUS_PLUG_PRESENT         BIT(0)
36 #define TPS_STATUS_ORIENTATION          BIT(4)
37 #define TPS_STATUS_PORTROLE(s)          (!!((s) & BIT(5)))
38 #define TPS_STATUS_DATAROLE(s)          (!!((s) & BIT(6)))
39 #define TPS_STATUS_VCONN(s)             (!!((s) & BIT(7)))
40
41 /* TPS_REG_SYSTEM_CONF bits */
42 #define TPS_SYSCONF_PORTINFO(c)         ((c) & 3)
43
44 enum {
45         TPS_PORTINFO_SINK,
46         TPS_PORTINFO_SINK_ACCESSORY,
47         TPS_PORTINFO_DRP_UFP,
48         TPS_PORTINFO_DRP_UFP_DRD,
49         TPS_PORTINFO_DRP_DFP,
50         TPS_PORTINFO_DRP_DFP_DRD,
51         TPS_PORTINFO_SOURCE,
52 };
53
54 /* TPS_REG_POWER_STATUS bits */
55 #define TPS_POWER_STATUS_SOURCESINK     BIT(1)
56 #define TPS_POWER_STATUS_PWROPMODE(p)   (((p) & GENMASK(3, 2)) >> 2)
57
58 /* TPS_REG_RX_IDENTITY_SOP */
59 struct tps6598x_rx_identity_reg {
60         u8 status;
61         struct usb_pd_identity identity;
62         u32 vdo[3];
63 } __packed;
64
65 /* Standard Task return codes */
66 #define TPS_TASK_TIMEOUT                1
67 #define TPS_TASK_REJECTED               3
68
69 /* Unrecognized commands will be replaced with "!CMD" */
70 #define INVALID_CMD(_cmd_)              (_cmd_ == 0x444d4321)
71
72 struct tps6598x {
73         struct device *dev;
74         struct regmap *regmap;
75         struct mutex lock; /* device lock */
76         u8 i2c_protocol:1;
77
78         struct typec_port *port;
79         struct typec_partner *partner;
80         struct usb_pd_identity partner_identity;
81         struct typec_capability typec_cap;
82 };
83
84 /*
85  * Max data bytes for Data1, Data2, and other registers. See ch 1.3.2:
86  * http://www.ti.com/lit/ug/slvuan1a/slvuan1a.pdf
87  */
88 #define TPS_MAX_LEN     64
89
90 static int
91 tps6598x_block_read(struct tps6598x *tps, u8 reg, void *val, size_t len)
92 {
93         u8 data[TPS_MAX_LEN + 1];
94         int ret;
95
96         if (WARN_ON(len + 1 > sizeof(data)))
97                 return -EINVAL;
98
99         if (!tps->i2c_protocol)
100                 return regmap_raw_read(tps->regmap, reg, val, len);
101
102         ret = regmap_raw_read(tps->regmap, reg, data, sizeof(data));
103         if (ret)
104                 return ret;
105
106         if (data[0] < len)
107                 return -EIO;
108
109         memcpy(val, &data[1], len);
110         return 0;
111 }
112
113 static inline int tps6598x_read16(struct tps6598x *tps, u8 reg, u16 *val)
114 {
115         return tps6598x_block_read(tps, reg, val, sizeof(u16));
116 }
117
118 static inline int tps6598x_read32(struct tps6598x *tps, u8 reg, u32 *val)
119 {
120         return tps6598x_block_read(tps, reg, val, sizeof(u32));
121 }
122
123 static inline int tps6598x_read64(struct tps6598x *tps, u8 reg, u64 *val)
124 {
125         return tps6598x_block_read(tps, reg, val, sizeof(u64));
126 }
127
128 static inline int tps6598x_write16(struct tps6598x *tps, u8 reg, u16 val)
129 {
130         return regmap_raw_write(tps->regmap, reg, &val, sizeof(u16));
131 }
132
133 static inline int tps6598x_write32(struct tps6598x *tps, u8 reg, u32 val)
134 {
135         return regmap_raw_write(tps->regmap, reg, &val, sizeof(u32));
136 }
137
138 static inline int tps6598x_write64(struct tps6598x *tps, u8 reg, u64 val)
139 {
140         return regmap_raw_write(tps->regmap, reg, &val, sizeof(u64));
141 }
142
143 static inline int
144 tps6598x_write_4cc(struct tps6598x *tps, u8 reg, const char *val)
145 {
146         return regmap_raw_write(tps->regmap, reg, &val, sizeof(u32));
147 }
148
149 static int tps6598x_read_partner_identity(struct tps6598x *tps)
150 {
151         struct tps6598x_rx_identity_reg id;
152         int ret;
153
154         ret = tps6598x_block_read(tps, TPS_REG_RX_IDENTITY_SOP,
155                                   &id, sizeof(id));
156         if (ret)
157                 return ret;
158
159         tps->partner_identity = id.identity;
160
161         return 0;
162 }
163
164 static int tps6598x_connect(struct tps6598x *tps, u32 status)
165 {
166         struct typec_partner_desc desc;
167         enum typec_pwr_opmode mode;
168         u16 pwr_status;
169         int ret;
170
171         if (tps->partner)
172                 return 0;
173
174         ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &pwr_status);
175         if (ret < 0)
176                 return ret;
177
178         mode = TPS_POWER_STATUS_PWROPMODE(pwr_status);
179
180         desc.usb_pd = mode == TYPEC_PWR_MODE_PD;
181         desc.accessory = TYPEC_ACCESSORY_NONE; /* XXX: handle accessories */
182         desc.identity = NULL;
183
184         if (desc.usb_pd) {
185                 ret = tps6598x_read_partner_identity(tps);
186                 if (ret)
187                         return ret;
188                 desc.identity = &tps->partner_identity;
189         }
190
191         typec_set_pwr_opmode(tps->port, mode);
192         typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status));
193         typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status));
194         typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status));
195
196         tps->partner = typec_register_partner(tps->port, &desc);
197         if (IS_ERR(tps->partner))
198                 return PTR_ERR(tps->partner);
199
200         if (desc.identity)
201                 typec_partner_set_identity(tps->partner);
202
203         return 0;
204 }
205
206 static void tps6598x_disconnect(struct tps6598x *tps, u32 status)
207 {
208         if (!IS_ERR(tps->partner))
209                 typec_unregister_partner(tps->partner);
210         tps->partner = NULL;
211         typec_set_pwr_opmode(tps->port, TYPEC_PWR_MODE_USB);
212         typec_set_pwr_role(tps->port, TPS_STATUS_PORTROLE(status));
213         typec_set_vconn_role(tps->port, TPS_STATUS_VCONN(status));
214         typec_set_data_role(tps->port, TPS_STATUS_DATAROLE(status));
215 }
216
217 static int tps6598x_exec_cmd(struct tps6598x *tps, const char *cmd,
218                              size_t in_len, u8 *in_data,
219                              size_t out_len, u8 *out_data)
220 {
221         unsigned long timeout;
222         u32 val;
223         int ret;
224
225         ret = tps6598x_read32(tps, TPS_REG_CMD1, &val);
226         if (ret)
227                 return ret;
228         if (val && !INVALID_CMD(val))
229                 return -EBUSY;
230
231         if (in_len) {
232                 ret = regmap_raw_write(tps->regmap, TPS_REG_DATA1,
233                                        in_data, in_len);
234                 if (ret)
235                         return ret;
236         }
237
238         ret = tps6598x_write_4cc(tps, TPS_REG_CMD1, cmd);
239         if (ret < 0)
240                 return ret;
241
242         /* XXX: Using 1s for now, but it may not be enough for every command. */
243         timeout = jiffies + msecs_to_jiffies(1000);
244
245         do {
246                 ret = tps6598x_read32(tps, TPS_REG_CMD1, &val);
247                 if (ret)
248                         return ret;
249                 if (INVALID_CMD(val))
250                         return -EINVAL;
251
252                 if (time_is_before_jiffies(timeout))
253                         return -ETIMEDOUT;
254         } while (val);
255
256         if (out_len) {
257                 ret = tps6598x_block_read(tps, TPS_REG_DATA1,
258                                           out_data, out_len);
259                 if (ret)
260                         return ret;
261                 val = out_data[0];
262         } else {
263                 ret = tps6598x_block_read(tps, TPS_REG_DATA1, &val, sizeof(u8));
264                 if (ret)
265                         return ret;
266         }
267
268         switch (val) {
269         case TPS_TASK_TIMEOUT:
270                 return -ETIMEDOUT;
271         case TPS_TASK_REJECTED:
272                 return -EPERM;
273         default:
274                 break;
275         }
276
277         return 0;
278 }
279
280 static int
281 tps6598x_dr_set(const struct typec_capability *cap, enum typec_data_role role)
282 {
283         struct tps6598x *tps = container_of(cap, struct tps6598x, typec_cap);
284         const char *cmd = (role == TYPEC_DEVICE) ? "SWUF" : "SWDF";
285         u32 status;
286         int ret;
287
288         mutex_lock(&tps->lock);
289
290         ret = tps6598x_exec_cmd(tps, cmd, 0, NULL, 0, NULL);
291         if (ret)
292                 goto out_unlock;
293
294         ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
295         if (ret)
296                 goto out_unlock;
297
298         if (role != TPS_STATUS_DATAROLE(status)) {
299                 ret = -EPROTO;
300                 goto out_unlock;
301         }
302
303         typec_set_data_role(tps->port, role);
304
305 out_unlock:
306         mutex_unlock(&tps->lock);
307
308         return ret;
309 }
310
311 static int
312 tps6598x_pr_set(const struct typec_capability *cap, enum typec_role role)
313 {
314         struct tps6598x *tps = container_of(cap, struct tps6598x, typec_cap);
315         const char *cmd = (role == TYPEC_SINK) ? "SWSk" : "SWSr";
316         u32 status;
317         int ret;
318
319         mutex_lock(&tps->lock);
320
321         ret = tps6598x_exec_cmd(tps, cmd, 0, NULL, 0, NULL);
322         if (ret)
323                 goto out_unlock;
324
325         ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
326         if (ret)
327                 goto out_unlock;
328
329         if (role != TPS_STATUS_PORTROLE(status)) {
330                 ret = -EPROTO;
331                 goto out_unlock;
332         }
333
334         typec_set_pwr_role(tps->port, role);
335
336 out_unlock:
337         mutex_unlock(&tps->lock);
338
339         return ret;
340 }
341
342 static irqreturn_t tps6598x_interrupt(int irq, void *data)
343 {
344         struct tps6598x *tps = data;
345         u64 event1;
346         u64 event2;
347         u32 status;
348         int ret;
349
350         mutex_lock(&tps->lock);
351
352         ret = tps6598x_read64(tps, TPS_REG_INT_EVENT1, &event1);
353         ret |= tps6598x_read64(tps, TPS_REG_INT_EVENT2, &event2);
354         if (ret) {
355                 dev_err(tps->dev, "%s: failed to read events\n", __func__);
356                 goto err_unlock;
357         }
358
359         ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
360         if (ret) {
361                 dev_err(tps->dev, "%s: failed to read status\n", __func__);
362                 goto err_clear_ints;
363         }
364
365         /* Handle plug insert or removal */
366         if ((event1 | event2) & TPS_REG_INT_PLUG_EVENT) {
367                 if (status & TPS_STATUS_PLUG_PRESENT) {
368                         ret = tps6598x_connect(tps, status);
369                         if (ret)
370                                 dev_err(tps->dev,
371                                         "failed to register partner\n");
372                 } else {
373                         tps6598x_disconnect(tps, status);
374                 }
375         }
376
377 err_clear_ints:
378         tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event1);
379         tps6598x_write64(tps, TPS_REG_INT_CLEAR2, event2);
380
381 err_unlock:
382         mutex_unlock(&tps->lock);
383
384         return IRQ_HANDLED;
385 }
386
387 static const struct regmap_config tps6598x_regmap_config = {
388         .reg_bits = 8,
389         .val_bits = 8,
390         .max_register = 0x7F,
391 };
392
393 static int tps6598x_probe(struct i2c_client *client)
394 {
395         struct tps6598x *tps;
396         u32 status;
397         u32 conf;
398         u32 vid;
399         int ret;
400
401         tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
402         if (!tps)
403                 return -ENOMEM;
404
405         mutex_init(&tps->lock);
406         tps->dev = &client->dev;
407
408         tps->regmap = devm_regmap_init_i2c(client, &tps6598x_regmap_config);
409         if (IS_ERR(tps->regmap))
410                 return PTR_ERR(tps->regmap);
411
412         ret = tps6598x_read32(tps, 0, &vid);
413         if (ret < 0)
414                 return ret;
415         if (!vid)
416                 return -ENODEV;
417
418         /*
419          * Checking can the adapter handle SMBus protocol. If it can not, the
420          * driver needs to take care of block reads separately.
421          *
422          * FIXME: Testing with I2C_FUNC_I2C. regmap-i2c uses I2C protocol
423          * unconditionally if the adapter has I2C_FUNC_I2C set.
424          */
425         if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
426                 tps->i2c_protocol = true;
427
428         ret = tps6598x_read32(tps, TPS_REG_STATUS, &status);
429         if (ret < 0)
430                 return ret;
431
432         ret = tps6598x_read32(tps, TPS_REG_SYSTEM_CONF, &conf);
433         if (ret < 0)
434                 return ret;
435
436         tps->typec_cap.revision = USB_TYPEC_REV_1_2;
437         tps->typec_cap.pd_revision = 0x200;
438         tps->typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
439         tps->typec_cap.pr_set = tps6598x_pr_set;
440         tps->typec_cap.dr_set = tps6598x_dr_set;
441
442         switch (TPS_SYSCONF_PORTINFO(conf)) {
443         case TPS_PORTINFO_SINK_ACCESSORY:
444         case TPS_PORTINFO_SINK:
445                 tps->typec_cap.type = TYPEC_PORT_SNK;
446                 tps->typec_cap.data = TYPEC_PORT_UFP;
447                 break;
448         case TPS_PORTINFO_DRP_UFP_DRD:
449         case TPS_PORTINFO_DRP_DFP_DRD:
450                 tps->typec_cap.type = TYPEC_PORT_DRP;
451                 tps->typec_cap.data = TYPEC_PORT_DRD;
452                 break;
453         case TPS_PORTINFO_DRP_UFP:
454                 tps->typec_cap.type = TYPEC_PORT_DRP;
455                 tps->typec_cap.data = TYPEC_PORT_UFP;
456                 break;
457         case TPS_PORTINFO_DRP_DFP:
458                 tps->typec_cap.type = TYPEC_PORT_DRP;
459                 tps->typec_cap.data = TYPEC_PORT_DFP;
460                 break;
461         case TPS_PORTINFO_SOURCE:
462                 tps->typec_cap.type = TYPEC_PORT_SRC;
463                 tps->typec_cap.data = TYPEC_PORT_DFP;
464                 break;
465         default:
466                 return -ENODEV;
467         }
468
469         tps->port = typec_register_port(&client->dev, &tps->typec_cap);
470         if (IS_ERR(tps->port))
471                 return PTR_ERR(tps->port);
472
473         if (status & TPS_STATUS_PLUG_PRESENT) {
474                 ret = tps6598x_connect(tps, status);
475                 if (ret)
476                         dev_err(&client->dev, "failed to register partner\n");
477         }
478
479         ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
480                                         tps6598x_interrupt,
481                                         IRQF_SHARED | IRQF_ONESHOT,
482                                         dev_name(&client->dev), tps);
483         if (ret) {
484                 tps6598x_disconnect(tps, 0);
485                 typec_unregister_port(tps->port);
486                 return ret;
487         }
488
489         i2c_set_clientdata(client, tps);
490
491         return 0;
492 }
493
494 static int tps6598x_remove(struct i2c_client *client)
495 {
496         struct tps6598x *tps = i2c_get_clientdata(client);
497
498         tps6598x_disconnect(tps, 0);
499         typec_unregister_port(tps->port);
500
501         return 0;
502 }
503
504 static const struct i2c_device_id tps6598x_id[] = {
505         { "tps6598x" },
506         { }
507 };
508 MODULE_DEVICE_TABLE(i2c, tps6598x_id);
509
510 static struct i2c_driver tps6598x_i2c_driver = {
511         .driver = {
512                 .name = "tps6598x",
513         },
514         .probe_new = tps6598x_probe,
515         .remove = tps6598x_remove,
516         .id_table = tps6598x_id,
517 };
518 module_i2c_driver(tps6598x_i2c_driver);
519
520 MODULE_AUTHOR("Heikki Krogerus <heikki.krogerus@linux.intel.com>");
521 MODULE_LICENSE("GPL v2");
522 MODULE_DESCRIPTION("TI TPS6598x USB Power Delivery Controller Driver");