1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * TI HD3SS3220 Type-C DRP Port Controller Driver
4 *
5 * Copyright (C) 2019 Renesas Electronics Corp.
6 */
7
8 #include <linux/module.h>
9 #include <linux/i2c.h>
10 #include <linux/usb/role.h>
11 #include <linux/irqreturn.h>
12 #include <linux/interrupt.h>
13 #include <linux/regmap.h>
14 #include <linux/slab.h>
15 #include <linux/usb/typec.h>
16 #include <linux/delay.h>
17 #include <linux/workqueue.h>
18 #include <linux/gpio/consumer.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/of_graph.h>
21
22 #define HD3SS3220_REG_CN_STAT 0x08
23 #define HD3SS3220_REG_CN_STAT_CTRL 0x09
24 #define HD3SS3220_REG_GEN_CTRL 0x0A
25 #define HD3SS3220_REG_DEV_REV 0xA0
26
27 /* Register HD3SS3220_REG_CN_STAT */
28 #define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MASK (BIT(7) | BIT(6))
29 #define HD3SS3220_REG_CN_STAT_CURRENT_MODE_DEFAULT 0x00
30 #define HD3SS3220_REG_CN_STAT_CURRENT_MODE_MID BIT(6)
31 #define HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH BIT(7)
32
33 /* Register HD3SS3220_REG_CN_STAT_CTRL*/
34 #define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6))
35 #define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6)
36 #define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7)
37 #define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | BIT(6))
38 #define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4)
39
40 /* Register HD3SS3220_REG_GEN_CTRL*/
41 #define HD3SS3220_REG_GEN_CTRL_DISABLE_TERM BIT(0)
42 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1))
43 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00
44 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1)
45 #define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1))
46 #define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_MASK (BIT(5) | BIT(4))
47 #define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DEFAULT 0x00
48 #define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DFP BIT(5)
49 #define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_UFP BIT(4)
50 #define HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DRP (BIT(5) | BIT(4))
51
52 struct hd3ss3220 {
53 struct device *dev;
54 struct regmap *regmap;
55 struct usb_role_switch *role_sw;
56 struct typec_port *port;
57 struct delayed_work output_poll_work;
58 enum usb_role role_state;
59 bool poll;
60
61 struct gpio_desc *id_gpiod;
62 int id_irq;
63
64 struct regulator *vbus;
65 bool vbus_enabled;
66 };
67
hd3ss3220_set_power_opmode(struct hd3ss3220 * hd3ss3220,int power_opmode)68 static int hd3ss3220_set_power_opmode(struct hd3ss3220 *hd3ss3220, int power_opmode)
69 {
70 int current_mode;
71
72 switch (power_opmode) {
73 case TYPEC_PWR_MODE_USB:
74 current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_DEFAULT;
75 break;
76 case TYPEC_PWR_MODE_1_5A:
77 current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_MID;
78 break;
79 case TYPEC_PWR_MODE_3_0A:
80 current_mode = HD3SS3220_REG_CN_STAT_CURRENT_MODE_HIGH;
81 break;
82 case TYPEC_PWR_MODE_PD: /* Power delivery not supported */
83 default:
84 dev_err(hd3ss3220->dev, "bad power operation mode: %d\n", power_opmode);
85 return -EINVAL;
86 }
87
88 return regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT,
89 HD3SS3220_REG_CN_STAT_CURRENT_MODE_MASK,
90 current_mode);
91 }
92
hd3ss3220_set_port_type(struct hd3ss3220 * hd3ss3220,int type)93 static int hd3ss3220_set_port_type(struct hd3ss3220 *hd3ss3220, int type)
94 {
95 int mode_select, err;
96
97 switch (type) {
98 case TYPEC_PORT_SRC:
99 mode_select = HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DFP;
100 break;
101 case TYPEC_PORT_SNK:
102 mode_select = HD3SS3220_REG_GEN_CTRL_MODE_SELECT_UFP;
103 break;
104 case TYPEC_PORT_DRP:
105 mode_select = HD3SS3220_REG_GEN_CTRL_MODE_SELECT_DRP;
106 break;
107 default:
108 dev_err(hd3ss3220->dev, "bad port type: %d\n", type);
109 return -EINVAL;
110 }
111
112 /* Disable termination before changing MODE_SELECT as required by datasheet */
113 err = regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
114 HD3SS3220_REG_GEN_CTRL_DISABLE_TERM,
115 HD3SS3220_REG_GEN_CTRL_DISABLE_TERM);
116 if (err < 0) {
117 dev_err(hd3ss3220->dev, "Failed to disable port for mode change: %d\n", err);
118 return err;
119 }
120
121 err = regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
122 HD3SS3220_REG_GEN_CTRL_MODE_SELECT_MASK,
123 mode_select);
124 if (err < 0) {
125 dev_err(hd3ss3220->dev, "Failed to change mode: %d\n", err);
126 regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
127 HD3SS3220_REG_GEN_CTRL_DISABLE_TERM, 0);
128 return err;
129 }
130
131 err = regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
132 HD3SS3220_REG_GEN_CTRL_DISABLE_TERM, 0);
133 if (err < 0)
134 dev_err(hd3ss3220->dev, "Failed to re-enable port after mode change: %d\n", err);
135
136 return err;
137 }
138
hd3ss3220_set_source_pref(struct hd3ss3220 * hd3ss3220,int prefer_role)139 static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int prefer_role)
140 {
141 int src_pref;
142
143 switch (prefer_role) {
144 case TYPEC_NO_PREFERRED_ROLE:
145 src_pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT;
146 break;
147 case TYPEC_SINK:
148 src_pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK;
149 break;
150 case TYPEC_SOURCE:
151 src_pref = HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC;
152 break;
153 default:
154 dev_err(hd3ss3220->dev, "bad role preference: %d\n", prefer_role);
155 return -EINVAL;
156 }
157
158 return regmap_update_bits(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL,
159 HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK,
160 src_pref);
161 }
162
hd3ss3220_get_attached_state(struct hd3ss3220 * hd3ss3220)163 static enum usb_role hd3ss3220_get_attached_state(struct hd3ss3220 *hd3ss3220)
164 {
165 unsigned int reg_val;
166 enum usb_role attached_state;
167 int ret;
168
169 ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL,
170 ®_val);
171 if (ret < 0)
172 return ret;
173
174 switch (reg_val & HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK) {
175 case HD3SS3220_REG_CN_STAT_CTRL_AS_DFP:
176 attached_state = USB_ROLE_HOST;
177 break;
178 case HD3SS3220_REG_CN_STAT_CTRL_AS_UFP:
179 attached_state = USB_ROLE_DEVICE;
180 break;
181 default:
182 attached_state = USB_ROLE_NONE;
183 break;
184 }
185
186 return attached_state;
187 }
188
hd3ss3220_try_role(struct typec_port * port,int role)189 static int hd3ss3220_try_role(struct typec_port *port, int role)
190 {
191 struct hd3ss3220 *hd3ss3220 = typec_get_drvdata(port);
192
193 return hd3ss3220_set_source_pref(hd3ss3220, role);
194 }
195
hd3ss3220_port_type_set(struct typec_port * port,enum typec_port_type type)196 static int hd3ss3220_port_type_set(struct typec_port *port, enum typec_port_type type)
197 {
198 struct hd3ss3220 *hd3ss3220 = typec_get_drvdata(port);
199
200 return hd3ss3220_set_port_type(hd3ss3220, type);
201 }
202
203 static const struct typec_operations hd3ss3220_ops = {
204 .try_role = hd3ss3220_try_role,
205 .port_type_set = hd3ss3220_port_type_set,
206 };
207
hd3ss3220_regulator_control(struct hd3ss3220 * hd3ss3220,bool on)208 static void hd3ss3220_regulator_control(struct hd3ss3220 *hd3ss3220, bool on)
209 {
210 int ret;
211
212 if (hd3ss3220->vbus_enabled == on)
213 return;
214
215 if (on)
216 ret = regulator_enable(hd3ss3220->vbus);
217 else
218 ret = regulator_disable(hd3ss3220->vbus);
219
220 if (ret) {
221 dev_err(hd3ss3220->dev,
222 "vbus regulator %s failed: %d\n", on ? "enable" : "disable", ret);
223 return;
224 }
225
226 hd3ss3220->vbus_enabled = on;
227 }
228
hd3ss3220_set_role(struct hd3ss3220 * hd3ss3220)229 static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220)
230 {
231 enum usb_role role_state = hd3ss3220_get_attached_state(hd3ss3220);
232
233 usb_role_switch_set_role(hd3ss3220->role_sw, role_state);
234
235 switch (role_state) {
236 case USB_ROLE_HOST:
237 typec_set_data_role(hd3ss3220->port, TYPEC_HOST);
238 break;
239 case USB_ROLE_DEVICE:
240 typec_set_data_role(hd3ss3220->port, TYPEC_DEVICE);
241 break;
242 default:
243 break;
244 }
245
246 if (hd3ss3220->vbus && !hd3ss3220->id_gpiod)
247 hd3ss3220_regulator_control(hd3ss3220, role_state == USB_ROLE_HOST);
248
249 hd3ss3220->role_state = role_state;
250 }
251
output_poll_execute(struct work_struct * work)252 static void output_poll_execute(struct work_struct *work)
253 {
254 struct delayed_work *delayed_work = to_delayed_work(work);
255 struct hd3ss3220 *hd3ss3220 = container_of(delayed_work,
256 struct hd3ss3220,
257 output_poll_work);
258 enum usb_role role_state = hd3ss3220_get_attached_state(hd3ss3220);
259
260 if (hd3ss3220->role_state != role_state)
261 hd3ss3220_set_role(hd3ss3220);
262
263 schedule_delayed_work(&hd3ss3220->output_poll_work, HZ);
264 }
265
hd3ss3220_irq(struct hd3ss3220 * hd3ss3220)266 static irqreturn_t hd3ss3220_irq(struct hd3ss3220 *hd3ss3220)
267 {
268 int err;
269
270 hd3ss3220_set_role(hd3ss3220);
271 err = regmap_write_bits(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL,
272 HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS,
273 HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
274 if (err < 0)
275 return IRQ_NONE;
276
277 return IRQ_HANDLED;
278 }
279
hd3ss3220_irq_handler(int irq,void * data)280 static irqreturn_t hd3ss3220_irq_handler(int irq, void *data)
281 {
282 struct i2c_client *client = to_i2c_client(data);
283 struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client);
284
285 return hd3ss3220_irq(hd3ss3220);
286 }
287
hd3ss3220_configure_power_opmode(struct hd3ss3220 * hd3ss3220,struct fwnode_handle * connector)288 static int hd3ss3220_configure_power_opmode(struct hd3ss3220 *hd3ss3220,
289 struct fwnode_handle *connector)
290 {
291 /*
292 * Supported power operation mode can be configured through device tree
293 */
294 const char *cap_str;
295 int ret, power_opmode;
296
297 ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
298 if (ret)
299 return 0;
300
301 power_opmode = typec_find_pwr_opmode(cap_str);
302 return hd3ss3220_set_power_opmode(hd3ss3220, power_opmode);
303 }
304
hd3ss3220_configure_port_type(struct hd3ss3220 * hd3ss3220,struct fwnode_handle * connector,struct typec_capability * cap)305 static int hd3ss3220_configure_port_type(struct hd3ss3220 *hd3ss3220,
306 struct fwnode_handle *connector,
307 struct typec_capability *cap)
308 {
309 /*
310 * Port type can be configured through device tree
311 */
312 const char *cap_str;
313 int ret;
314
315 ret = fwnode_property_read_string(connector, "power-role", &cap_str);
316 if (ret)
317 return 0;
318
319 ret = typec_find_port_power_role(cap_str);
320 if (ret < 0)
321 return ret;
322
323 cap->type = ret;
324 return hd3ss3220_set_port_type(hd3ss3220, cap->type);
325 }
326
hd3ss3220_configure_source_pref(struct hd3ss3220 * hd3ss3220,struct fwnode_handle * connector,struct typec_capability * cap)327 static int hd3ss3220_configure_source_pref(struct hd3ss3220 *hd3ss3220,
328 struct fwnode_handle *connector,
329 struct typec_capability *cap)
330 {
331 /*
332 * Preferred role can be configured through device tree
333 */
334 const char *cap_str;
335 int ret;
336
337 ret = fwnode_property_read_string(connector, "try-power-role", &cap_str);
338 if (ret)
339 return 0;
340
341 ret = typec_find_power_role(cap_str);
342 if (ret < 0)
343 return ret;
344
345 cap->prefer_role = ret;
346 return hd3ss3220_set_source_pref(hd3ss3220, cap->prefer_role);
347 }
348
349 static const struct regmap_config config = {
350 .reg_bits = 8,
351 .val_bits = 8,
352 .max_register = 0x0A,
353 };
354
hd3ss3220_id_isr(int irq,void * dev_id)355 static irqreturn_t hd3ss3220_id_isr(int irq, void *dev_id)
356 {
357 struct hd3ss3220 *hd3ss3220 = dev_id;
358 int id;
359
360 id = gpiod_get_value_cansleep(hd3ss3220->id_gpiod);
361 hd3ss3220_regulator_control(hd3ss3220, !id);
362
363 return IRQ_HANDLED;
364 }
365
hd3ss3220_probe(struct i2c_client * client)366 static int hd3ss3220_probe(struct i2c_client *client)
367 {
368 struct typec_capability typec_cap = { };
369 struct fwnode_handle *connector, *ep;
370 struct hd3ss3220 *hd3ss3220;
371 struct regulator *vbus;
372 unsigned int data;
373 int ret;
374
375 hd3ss3220 = devm_kzalloc(&client->dev, sizeof(struct hd3ss3220),
376 GFP_KERNEL);
377 if (!hd3ss3220)
378 return -ENOMEM;
379
380 i2c_set_clientdata(client, hd3ss3220);
381
382 hd3ss3220->dev = &client->dev;
383 hd3ss3220->regmap = devm_regmap_init_i2c(client, &config);
384 if (IS_ERR(hd3ss3220->regmap))
385 return PTR_ERR(hd3ss3220->regmap);
386
387 /* For backward compatibility check the connector child node first */
388 connector = device_get_named_child_node(hd3ss3220->dev, "connector");
389 if (connector) {
390 hd3ss3220->role_sw = fwnode_usb_role_switch_get(connector);
391 } else {
392 ep = fwnode_graph_get_next_endpoint(dev_fwnode(hd3ss3220->dev), NULL);
393 if (!ep)
394 return -ENODEV;
395 connector = fwnode_graph_get_remote_port_parent(ep);
396 fwnode_handle_put(ep);
397 if (!connector)
398 return -ENODEV;
399 hd3ss3220->role_sw = usb_role_switch_get(hd3ss3220->dev);
400 }
401
402 if (IS_ERR(hd3ss3220->role_sw)) {
403 ret = PTR_ERR(hd3ss3220->role_sw);
404 goto err_put_fwnode;
405 }
406
407 vbus = devm_of_regulator_get_optional(hd3ss3220->dev,
408 to_of_node(connector),
409 "vbus");
410 if (IS_ERR(vbus) && vbus != ERR_PTR(-ENODEV)) {
411 ret = PTR_ERR(vbus);
412 dev_err(hd3ss3220->dev, "failed to get vbus: %d", ret);
413 goto err_put_fwnode;
414 }
415
416 hd3ss3220->vbus = (vbus == ERR_PTR(-ENODEV) ? NULL : vbus);
417
418 if (hd3ss3220->vbus) {
419 hd3ss3220->id_gpiod = devm_gpiod_get_optional(hd3ss3220->dev,
420 "id",
421 GPIOD_IN);
422 if (IS_ERR(hd3ss3220->id_gpiod)) {
423 ret = PTR_ERR(hd3ss3220->id_gpiod);
424 goto err_put_fwnode;
425 }
426 }
427
428 if (hd3ss3220->id_gpiod) {
429 hd3ss3220->id_irq = gpiod_to_irq(hd3ss3220->id_gpiod);
430 if (hd3ss3220->id_irq < 0) {
431 ret = hd3ss3220->id_irq;
432 dev_err(hd3ss3220->dev,
433 "failed to get ID gpio: %d\n",
434 hd3ss3220->id_irq);
435 goto err_put_fwnode;
436 }
437
438 ret = devm_request_threaded_irq(hd3ss3220->dev,
439 hd3ss3220->id_irq, NULL,
440 hd3ss3220_id_isr,
441 IRQF_TRIGGER_RISING |
442 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
443 dev_name(hd3ss3220->dev), hd3ss3220);
444 if (ret < 0) {
445 dev_err(hd3ss3220->dev, "failed to get ID irq: %d\n", ret);
446 goto err_put_fwnode;
447 }
448 }
449
450 typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;
451 typec_cap.driver_data = hd3ss3220;
452 typec_cap.type = TYPEC_PORT_DRP;
453 typec_cap.data = TYPEC_PORT_DRD;
454 typec_cap.ops = &hd3ss3220_ops;
455 typec_cap.fwnode = connector;
456
457 ret = hd3ss3220_configure_source_pref(hd3ss3220, connector, &typec_cap);
458 if (ret < 0)
459 goto err_put_role;
460
461 ret = hd3ss3220_configure_port_type(hd3ss3220, connector, &typec_cap);
462 if (ret < 0)
463 goto err_put_role;
464
465 hd3ss3220->port = typec_register_port(&client->dev, &typec_cap);
466 if (IS_ERR(hd3ss3220->port)) {
467 ret = PTR_ERR(hd3ss3220->port);
468 goto err_put_role;
469 }
470
471 ret = hd3ss3220_configure_power_opmode(hd3ss3220, connector);
472 if (ret < 0)
473 goto err_unreg_port;
474
475 hd3ss3220_set_role(hd3ss3220);
476 ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, &data);
477 if (ret < 0)
478 goto err_unreg_port;
479
480 if (data & HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS) {
481 ret = regmap_write(hd3ss3220->regmap,
482 HD3SS3220_REG_CN_STAT_CTRL,
483 data | HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS);
484 if (ret < 0)
485 goto err_unreg_port;
486 }
487
488 if (client->irq > 0) {
489 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
490 hd3ss3220_irq_handler,
491 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
492 "hd3ss3220", &client->dev);
493 if (ret)
494 goto err_unreg_port;
495 } else {
496 INIT_DELAYED_WORK(&hd3ss3220->output_poll_work, output_poll_execute);
497 hd3ss3220->poll = true;
498 }
499
500 ret = i2c_smbus_read_byte_data(client, HD3SS3220_REG_DEV_REV);
501 if (ret < 0)
502 goto err_unreg_port;
503
504 fwnode_handle_put(connector);
505
506 if (hd3ss3220->poll)
507 schedule_delayed_work(&hd3ss3220->output_poll_work, HZ);
508
509 dev_info(&client->dev, "probed revision=0x%x\n", ret);
510
511 return 0;
512 err_unreg_port:
513 typec_unregister_port(hd3ss3220->port);
514 err_put_role:
515 usb_role_switch_put(hd3ss3220->role_sw);
516 err_put_fwnode:
517 fwnode_handle_put(connector);
518
519 return ret;
520 }
521
hd3ss3220_remove(struct i2c_client * client)522 static void hd3ss3220_remove(struct i2c_client *client)
523 {
524 struct hd3ss3220 *hd3ss3220 = i2c_get_clientdata(client);
525
526 if (hd3ss3220->poll)
527 cancel_delayed_work_sync(&hd3ss3220->output_poll_work);
528
529 typec_unregister_port(hd3ss3220->port);
530 usb_role_switch_put(hd3ss3220->role_sw);
531 }
532
533 static const struct of_device_id dev_ids[] = {
534 { .compatible = "ti,hd3ss3220"},
535 {}
536 };
537 MODULE_DEVICE_TABLE(of, dev_ids);
538
539 static struct i2c_driver hd3ss3220_driver = {
540 .driver = {
541 .name = "hd3ss3220",
542 .of_match_table = dev_ids,
543 },
544 .probe = hd3ss3220_probe,
545 .remove = hd3ss3220_remove,
546 };
547
548 module_i2c_driver(hd3ss3220_driver);
549
550 MODULE_AUTHOR("Biju Das <biju.das@bp.renesas.com>");
551 MODULE_DESCRIPTION("TI HD3SS3220 DRP Port Controller Driver");
552 MODULE_LICENSE("GPL");
553