1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2018, Richtek Technology Corporation
4 *
5 * Richtek RT1711H Type-C Chip Driver
6 */
7
8 #include <linux/bitfield.h>
9 #include <linux/bits.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/i2c.h>
13 #include <linux/interrupt.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/usb/tcpci.h>
16 #include <linux/usb/tcpm.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19
20 #define RT1711H_PHYCTRL1 0x80
21 #define RT1711H_PHYCTRL2 0x81
22
23 #define RT1711H_RTCTRL4 0x93
24 /* rx threshold of rd/rp: 1b0 for level 0.4V/0.7V, 1b1 for 0.35V/0.75V */
25 #define RT1711H_BMCIO_RXDZSEL BIT(0)
26
27 #define RT1711H_RTCTRL8 0x9B
28 /* Autoidle timeout = (tout * 2 + 1) * 6.4ms */
29 #define RT1711H_RTCTRL8_SET(ck300, ship_off, auto_idle, tout) \
30 (((ck300) << 7) | ((ship_off) << 5) | \
31 ((auto_idle) << 3) | ((tout) & 0x07))
32 #define RT1711H_AUTOIDLEEN BIT(3)
33 #define RT1711H_ENEXTMSG BIT(4)
34
35 #define RT1711H_RTCTRL11 0x9E
36
37 /* I2C timeout = (tout + 1) * 12.5ms */
38 #define RT1711H_RTCTRL11_SET(en, tout) \
39 (((en) << 7) | ((tout) & 0x0F))
40
41 #define RT1711H_RTCTRL13 0xA0
42 #define RT1711H_RTCTRL14 0xA1
43 #define RT1711H_RTCTRL15 0xA2
44 #define RT1711H_RTCTRL16 0xA3
45
46 #define RT1711H_RTCTRL18 0xAF
47 /* 1b0 as fixed rx threshold of rd/rp 0.55V, 1b1 depends on RTCRTL4[0] */
48 #define BMCIO_RXDZEN BIT(0)
49
50 struct rt1711h_chip_info {
51 u32 rxdz_sel;
52 bool enable_pd30_extended_message;
53 };
54
55 struct rt1711h_chip {
56 struct tcpci_data data;
57 struct tcpci *tcpci;
58 struct device *dev;
59 struct regulator *vbus;
60 const struct rt1711h_chip_info *info;
61 bool src_en;
62 };
63
rt1711h_read16(struct rt1711h_chip * chip,unsigned int reg,u16 * val)64 static int rt1711h_read16(struct rt1711h_chip *chip, unsigned int reg, u16 *val)
65 {
66 return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u16));
67 }
68
rt1711h_write16(struct rt1711h_chip * chip,unsigned int reg,u16 val)69 static int rt1711h_write16(struct rt1711h_chip *chip, unsigned int reg, u16 val)
70 {
71 return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u16));
72 }
73
rt1711h_read8(struct rt1711h_chip * chip,unsigned int reg,u8 * val)74 static int rt1711h_read8(struct rt1711h_chip *chip, unsigned int reg, u8 *val)
75 {
76 return regmap_raw_read(chip->data.regmap, reg, val, sizeof(u8));
77 }
78
rt1711h_write8(struct rt1711h_chip * chip,unsigned int reg,u8 val)79 static int rt1711h_write8(struct rt1711h_chip *chip, unsigned int reg, u8 val)
80 {
81 return regmap_raw_write(chip->data.regmap, reg, &val, sizeof(u8));
82 }
83
84 static const struct regmap_config rt1711h_regmap_config = {
85 .reg_bits = 8,
86 .val_bits = 8,
87
88 .max_register = 0xFF, /* 0x80 .. 0xFF are vendor defined */
89 };
90
tdata_to_rt1711h(struct tcpci_data * tdata)91 static struct rt1711h_chip *tdata_to_rt1711h(struct tcpci_data *tdata)
92 {
93 return container_of(tdata, struct rt1711h_chip, data);
94 }
95
rt1711h_init(struct tcpci * tcpci,struct tcpci_data * tdata)96 static int rt1711h_init(struct tcpci *tcpci, struct tcpci_data *tdata)
97 {
98 struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
99 struct regmap *regmap = chip->data.regmap;
100 int ret;
101
102 /* CK 300K from 320K, shipping off, auto_idle enable, tout = 32ms */
103 ret = rt1711h_write8(chip, RT1711H_RTCTRL8,
104 RT1711H_RTCTRL8_SET(0, 1, 1, 2));
105 if (ret < 0)
106 return ret;
107
108 /* Enable PD30 extended message for RT1715 */
109 if (chip->info->enable_pd30_extended_message) {
110 ret = regmap_update_bits(regmap, RT1711H_RTCTRL8,
111 RT1711H_ENEXTMSG, RT1711H_ENEXTMSG);
112 if (ret < 0)
113 return ret;
114 }
115
116 /* I2C reset : (val + 1) * 12.5ms */
117 ret = rt1711h_write8(chip, RT1711H_RTCTRL11,
118 RT1711H_RTCTRL11_SET(1, 0x0F));
119 if (ret < 0)
120 return ret;
121
122 /* tTCPCfilter : (26.7 * val) us */
123 ret = rt1711h_write8(chip, RT1711H_RTCTRL14, 0x0F);
124 if (ret < 0)
125 return ret;
126
127 /* tDRP : (51.2 + 6.4 * val) ms */
128 ret = rt1711h_write8(chip, RT1711H_RTCTRL15, 0x04);
129 if (ret < 0)
130 return ret;
131
132 /* dcSRC.DRP : 33% */
133 ret = rt1711h_write16(chip, RT1711H_RTCTRL16, 330);
134 if (ret < 0)
135 return ret;
136
137 /* Enable phy discard retry, retry count 7, rx filter deglitch 100 us */
138 ret = rt1711h_write8(chip, RT1711H_PHYCTRL1, 0xF1);
139 if (ret < 0)
140 return ret;
141
142 /* Decrease wait time of BMC-encoded 1 bit from 2.67us to 2.55us */
143 /* wait time : (val * .4167) us */
144 return rt1711h_write8(chip, RT1711H_PHYCTRL2, 62);
145 }
146
rt1711h_set_vbus(struct tcpci * tcpci,struct tcpci_data * tdata,bool src,bool snk)147 static int rt1711h_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata,
148 bool src, bool snk)
149 {
150 struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
151 int ret;
152
153 if (chip->src_en == src)
154 return 0;
155
156 if (src)
157 ret = regulator_enable(chip->vbus);
158 else
159 ret = regulator_disable(chip->vbus);
160
161 if (!ret)
162 chip->src_en = src;
163 return ret;
164 }
165
rt1711h_set_vconn(struct tcpci * tcpci,struct tcpci_data * tdata,bool enable)166 static int rt1711h_set_vconn(struct tcpci *tcpci, struct tcpci_data *tdata,
167 bool enable)
168 {
169 struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
170
171 return regmap_update_bits(chip->data.regmap, RT1711H_RTCTRL8,
172 RT1711H_AUTOIDLEEN, enable ? 0 : RT1711H_AUTOIDLEEN);
173 }
174
175 /*
176 * Selects the CC PHY noise filter voltage level according to the remote current
177 * CC voltage level.
178 *
179 * @status: The port's current cc status read from IC
180 * Return 0 if writes succeed; failure code otherwise
181 */
rt1711h_init_cc_params(struct rt1711h_chip * chip,u8 status)182 static inline int rt1711h_init_cc_params(struct rt1711h_chip *chip, u8 status)
183 {
184 int ret, cc1, cc2;
185 u8 role = 0;
186 u32 rxdz_en, rxdz_sel;
187
188 ret = rt1711h_read8(chip, TCPC_ROLE_CTRL, &role);
189 if (ret < 0)
190 return ret;
191
192 cc1 = tcpci_to_typec_cc(FIELD_GET(TCPC_CC_STATUS_CC1, status),
193 status & TCPC_CC_STATUS_TERM ||
194 tcpc_presenting_rd(role, CC1));
195 cc2 = tcpci_to_typec_cc(FIELD_GET(TCPC_CC_STATUS_CC2, status),
196 status & TCPC_CC_STATUS_TERM ||
197 tcpc_presenting_rd(role, CC2));
198
199 if ((cc1 >= TYPEC_CC_RP_1_5 && cc2 < TYPEC_CC_RP_DEF) ||
200 (cc2 >= TYPEC_CC_RP_1_5 && cc1 < TYPEC_CC_RP_DEF)) {
201 rxdz_en = BMCIO_RXDZEN;
202 rxdz_sel = chip->info->rxdz_sel;
203 } else {
204 rxdz_en = 0;
205 rxdz_sel = RT1711H_BMCIO_RXDZSEL;
206 }
207
208 ret = regmap_update_bits(chip->data.regmap, RT1711H_RTCTRL18,
209 BMCIO_RXDZEN, rxdz_en);
210 if (ret < 0)
211 return ret;
212
213 return regmap_update_bits(chip->data.regmap, RT1711H_RTCTRL4,
214 RT1711H_BMCIO_RXDZSEL, rxdz_sel);
215 }
216
rt1711h_start_drp_toggling(struct tcpci * tcpci,struct tcpci_data * tdata,enum typec_cc_status cc)217 static int rt1711h_start_drp_toggling(struct tcpci *tcpci,
218 struct tcpci_data *tdata,
219 enum typec_cc_status cc)
220 {
221 struct rt1711h_chip *chip = tdata_to_rt1711h(tdata);
222 int ret;
223 unsigned int reg = 0;
224
225 switch (cc) {
226 default:
227 case TYPEC_CC_RP_DEF:
228 reg |= FIELD_PREP(TCPC_ROLE_CTRL_RP_VAL,
229 TCPC_ROLE_CTRL_RP_VAL_DEF);
230 break;
231 case TYPEC_CC_RP_1_5:
232 reg |= FIELD_PREP(TCPC_ROLE_CTRL_RP_VAL,
233 TCPC_ROLE_CTRL_RP_VAL_1_5);
234 break;
235 case TYPEC_CC_RP_3_0:
236 reg |= FIELD_PREP(TCPC_ROLE_CTRL_RP_VAL,
237 TCPC_ROLE_CTRL_RP_VAL_3_0);
238 break;
239 }
240
241 if (cc == TYPEC_CC_RD)
242 reg |= (FIELD_PREP(TCPC_ROLE_CTRL_CC1, TCPC_ROLE_CTRL_CC_RD)
243 | FIELD_PREP(TCPC_ROLE_CTRL_CC2, TCPC_ROLE_CTRL_CC_RD));
244 else
245 reg |= (FIELD_PREP(TCPC_ROLE_CTRL_CC1, TCPC_ROLE_CTRL_CC_RP)
246 | FIELD_PREP(TCPC_ROLE_CTRL_CC2, TCPC_ROLE_CTRL_CC_RP));
247
248 ret = rt1711h_write8(chip, TCPC_ROLE_CTRL, reg);
249 if (ret < 0)
250 return ret;
251 usleep_range(500, 1000);
252
253 return 0;
254 }
255
rt1711h_irq(int irq,void * dev_id)256 static irqreturn_t rt1711h_irq(int irq, void *dev_id)
257 {
258 int ret;
259 u16 alert;
260 u8 status;
261 struct rt1711h_chip *chip = dev_id;
262
263 if (!chip->tcpci)
264 return IRQ_HANDLED;
265
266 ret = rt1711h_read16(chip, TCPC_ALERT, &alert);
267 if (ret < 0)
268 goto out;
269
270 if (alert & TCPC_ALERT_CC_STATUS) {
271 ret = rt1711h_read8(chip, TCPC_CC_STATUS, &status);
272 if (ret < 0)
273 goto out;
274 /* Clear cc change event triggered by starting toggling */
275 if (status & TCPC_CC_STATUS_TOGGLING)
276 rt1711h_write8(chip, TCPC_ALERT, TCPC_ALERT_CC_STATUS);
277 else
278 rt1711h_init_cc_params(chip, status);
279 }
280
281 out:
282 return tcpci_irq(chip->tcpci);
283 }
284
rt1711h_sw_reset(struct rt1711h_chip * chip)285 static int rt1711h_sw_reset(struct rt1711h_chip *chip)
286 {
287 int ret;
288
289 ret = rt1711h_write8(chip, RT1711H_RTCTRL13, 0x01);
290 if (ret < 0)
291 return ret;
292
293 usleep_range(1000, 2000);
294 return 0;
295 }
296
297 static void rt1711h_unregister_tcpci_port(void *tcpci);
298
rt1711h_probe(struct i2c_client * client)299 static int rt1711h_probe(struct i2c_client *client)
300 {
301 int ret;
302 struct rt1711h_chip *chip;
303 const u16 alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED |
304 TCPC_ALERT_TX_FAILED | TCPC_ALERT_RX_HARD_RST |
305 TCPC_ALERT_RX_STATUS | TCPC_ALERT_POWER_STATUS |
306 TCPC_ALERT_CC_STATUS | TCPC_ALERT_RX_BUF_OVF |
307 TCPC_ALERT_FAULT;
308
309 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
310 if (!chip)
311 return -ENOMEM;
312
313 chip->info = i2c_get_match_data(client);
314
315 chip->data.regmap = devm_regmap_init_i2c(client,
316 &rt1711h_regmap_config);
317 if (IS_ERR(chip->data.regmap))
318 return PTR_ERR(chip->data.regmap);
319
320 chip->dev = &client->dev;
321 i2c_set_clientdata(client, chip);
322
323 ret = rt1711h_sw_reset(chip);
324 if (ret < 0)
325 return ret;
326
327 /* Disable chip interrupts before requesting irq */
328 ret = rt1711h_write16(chip, TCPC_ALERT_MASK, 0);
329 if (ret < 0)
330 return ret;
331
332 chip->vbus = devm_regulator_get(&client->dev, "vbus");
333 if (IS_ERR(chip->vbus))
334 return PTR_ERR(chip->vbus);
335
336 chip->data.init = rt1711h_init;
337 chip->data.set_vbus = rt1711h_set_vbus;
338 chip->data.set_vconn = rt1711h_set_vconn;
339 chip->data.start_drp_toggling = rt1711h_start_drp_toggling;
340 chip->tcpci = tcpci_register_port(chip->dev, &chip->data);
341 if (IS_ERR_OR_NULL(chip->tcpci))
342 return PTR_ERR(chip->tcpci);
343
344 ret = devm_add_action_or_reset(chip->dev, rt1711h_unregister_tcpci_port, chip->tcpci);
345 if (ret)
346 return ret;
347
348 ret = devm_request_threaded_irq(chip->dev, client->irq, NULL,
349 rt1711h_irq,
350 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
351 dev_name(chip->dev), chip);
352 if (ret < 0)
353 return ret;
354
355 /* Enable alert interrupts */
356 ret = rt1711h_write16(chip, TCPC_ALERT_MASK, alert_mask);
357 if (ret < 0)
358 return ret;
359
360 enable_irq_wake(client->irq);
361
362 return 0;
363 }
364
rt1711h_unregister_tcpci_port(void * tcpci)365 static void rt1711h_unregister_tcpci_port(void *tcpci)
366 {
367 tcpci_unregister_port(tcpci);
368 }
369
370 static const struct rt1711h_chip_info rt1711h = {
371 };
372
373 static const struct rt1711h_chip_info rt1715 = {
374 .rxdz_sel = RT1711H_BMCIO_RXDZSEL,
375 .enable_pd30_extended_message = true,
376 };
377
378 static const struct i2c_device_id rt1711h_id[] = {
379 { .name = "et7304", .driver_data = (kernel_ulong_t)&rt1715 },
380 { .name = "rt1711h", .driver_data = (kernel_ulong_t)&rt1711h },
381 { .name = "rt1715", .driver_data = (kernel_ulong_t)&rt1715 },
382 { }
383 };
384 MODULE_DEVICE_TABLE(i2c, rt1711h_id);
385
386 static const struct of_device_id rt1711h_of_match[] = {
387 { .compatible = "etekmicro,et7304", .data = &rt1715 },
388 { .compatible = "richtek,rt1711h", .data = &rt1711h },
389 { .compatible = "richtek,rt1715", .data = &rt1715 },
390 {}
391 };
392 MODULE_DEVICE_TABLE(of, rt1711h_of_match);
393
394 static struct i2c_driver rt1711h_i2c_driver = {
395 .driver = {
396 .name = "rt1711h",
397 .of_match_table = rt1711h_of_match,
398 },
399 .probe = rt1711h_probe,
400 .id_table = rt1711h_id,
401 };
402 module_i2c_driver(rt1711h_i2c_driver);
403
404 MODULE_AUTHOR("ShuFan Lee <shufan_lee@richtek.com>");
405 MODULE_DESCRIPTION("RT1711H USB Type-C Port Controller Interface Driver");
406 MODULE_LICENSE("GPL");
407