1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (C) 2020 - 2022, Google LLC |
4 | * |
5 | * MAXIM TCPCI based TCPC driver |
6 | */ |
7 | |
8 | #include <linux/interrupt.h> |
9 | #include <linux/i2c.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/module.h> |
12 | #include <linux/regmap.h> |
13 | #include <linux/usb/pd.h> |
14 | #include <linux/usb/tcpci.h> |
15 | #include <linux/usb/tcpm.h> |
16 | #include <linux/usb/typec.h> |
17 | |
18 | #include "tcpci_maxim.h" |
19 | |
20 | #define PD_ACTIVITY_TIMEOUT_MS 10000 |
21 | |
22 | #define TCPC_VENDOR_ALERT 0x80 |
23 | #define TCPC_VENDOR_USBSW_CTRL 0x93 |
24 | #define TCPC_VENDOR_USBSW_CTRL_ENABLE_USB_DATA 0x9 |
25 | #define TCPC_VENDOR_USBSW_CTRL_DISABLE_USB_DATA 0 |
26 | |
27 | #define TCPC_RECEIVE_BUFFER_COUNT_OFFSET 0 |
28 | #define TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET 1 |
29 | #define TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET 2 |
30 | |
31 | /* |
32 | * LongMessage not supported, hence 32 bytes for buf to be read from RECEIVE_BUFFER. |
33 | * DEVICE_CAPABILITIES_2.LongMessage = 0, the value in READABLE_BYTE_COUNT reg shall be |
34 | * less than or equal to 31. Since, RECEIVE_BUFFER len = 31 + 1(READABLE_BYTE_COUNT). |
35 | */ |
36 | #define TCPC_RECEIVE_BUFFER_LEN 32 |
37 | |
38 | #define MAX_BUCK_BOOST_SID 0x69 |
39 | #define MAX_BUCK_BOOST_OP 0xb9 |
40 | #define MAX_BUCK_BOOST_OFF 0 |
41 | #define MAX_BUCK_BOOST_SOURCE 0xa |
42 | #define MAX_BUCK_BOOST_SINK 0x5 |
43 | |
44 | static const struct regmap_range max_tcpci_tcpci_range[] = { |
45 | regmap_reg_range(0x00, 0x95) |
46 | }; |
47 | |
48 | static const struct regmap_access_table max_tcpci_tcpci_write_table = { |
49 | .yes_ranges = max_tcpci_tcpci_range, |
50 | .n_yes_ranges = ARRAY_SIZE(max_tcpci_tcpci_range), |
51 | }; |
52 | |
53 | static const struct regmap_config max_tcpci_regmap_config = { |
54 | .reg_bits = 8, |
55 | .val_bits = 8, |
56 | .max_register = 0x95, |
57 | .wr_table = &max_tcpci_tcpci_write_table, |
58 | }; |
59 | |
60 | static struct max_tcpci_chip *tdata_to_max_tcpci(struct tcpci_data *tdata) |
61 | { |
62 | return container_of(tdata, struct max_tcpci_chip, data); |
63 | } |
64 | |
65 | static void max_tcpci_init_regs(struct max_tcpci_chip *chip) |
66 | { |
67 | u16 alert_mask = 0; |
68 | int ret; |
69 | |
70 | ret = max_tcpci_write16(chip, TCPC_ALERT, val: 0xffff); |
71 | if (ret < 0) { |
72 | dev_err(chip->dev, "Error writing to TCPC_ALERT ret:%d\n" , ret); |
73 | return; |
74 | } |
75 | |
76 | ret = max_tcpci_write16(chip, TCPC_VENDOR_ALERT, val: 0xffff); |
77 | if (ret < 0) { |
78 | dev_err(chip->dev, "Error writing to TCPC_VENDOR_ALERT ret:%d\n" , ret); |
79 | return; |
80 | } |
81 | |
82 | ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, val: 0xff); |
83 | if (ret < 0) { |
84 | dev_err(chip->dev, "Unable to clear TCPC_ALERT_EXTENDED ret:%d\n" , ret); |
85 | return; |
86 | } |
87 | |
88 | /* Enable VSAFE0V detection */ |
89 | ret = max_tcpci_write8(chip, TCPC_EXTENDED_STATUS_MASK, TCPC_EXTENDED_STATUS_VSAFE0V); |
90 | if (ret < 0) { |
91 | dev_err(chip->dev, "Unable to unmask TCPC_EXTENDED_STATUS_VSAFE0V ret:%d\n" , ret); |
92 | return; |
93 | } |
94 | |
95 | /* Vconn Over Current Protection */ |
96 | ret = max_tcpci_write8(chip, TCPC_FAULT_STATUS_MASK, TCPC_FAULT_STATUS_MASK_VCONN_OC); |
97 | if (ret < 0) |
98 | return; |
99 | |
100 | alert_mask = TCPC_ALERT_TX_SUCCESS | TCPC_ALERT_TX_DISCARDED | TCPC_ALERT_TX_FAILED | |
101 | TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_RX_STATUS | TCPC_ALERT_CC_STATUS | |
102 | TCPC_ALERT_VBUS_DISCNCT | TCPC_ALERT_RX_BUF_OVF | TCPC_ALERT_POWER_STATUS | |
103 | /* Enable Extended alert for detecting Fast Role Swap Signal */ |
104 | TCPC_ALERT_EXTND | TCPC_ALERT_EXTENDED_STATUS | TCPC_ALERT_FAULT; |
105 | |
106 | ret = max_tcpci_write16(chip, TCPC_ALERT_MASK, val: alert_mask); |
107 | if (ret < 0) { |
108 | dev_err(chip->dev, |
109 | "Error enabling TCPC_ALERT: TCPC_ALERT_MASK write failed ret:%d\n" , ret); |
110 | return; |
111 | } |
112 | |
113 | /* Enable vbus voltage monitoring and voltage alerts */ |
114 | ret = max_tcpci_write8(chip, TCPC_POWER_CTRL, val: 0); |
115 | if (ret < 0) { |
116 | dev_err(chip->dev, "Error writing to TCPC_POWER_CTRL ret:%d\n" , ret); |
117 | return; |
118 | } |
119 | |
120 | ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED_MASK, TCPC_SINK_FAST_ROLE_SWAP); |
121 | if (ret < 0) |
122 | return; |
123 | } |
124 | |
125 | static void process_rx(struct max_tcpci_chip *chip, u16 status) |
126 | { |
127 | struct pd_message msg; |
128 | u8 count, frame_type, rx_buf[TCPC_RECEIVE_BUFFER_LEN]; |
129 | int ret, payload_index; |
130 | u8 *rx_buf_ptr; |
131 | enum tcpm_transmit_type rx_type; |
132 | |
133 | /* |
134 | * READABLE_BYTE_COUNT: Indicates the number of bytes in the RX_BUF_BYTE_x registers |
135 | * plus one (for the RX_BUF_FRAME_TYPE) Table 4-36. |
136 | * Read the count and frame type. |
137 | */ |
138 | ret = regmap_raw_read(map: chip->data.regmap, TCPC_RX_BYTE_CNT, val: rx_buf, val_len: 2); |
139 | if (ret < 0) { |
140 | dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d\n" , ret); |
141 | return; |
142 | } |
143 | |
144 | count = rx_buf[TCPC_RECEIVE_BUFFER_COUNT_OFFSET]; |
145 | frame_type = rx_buf[TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET]; |
146 | |
147 | switch (frame_type) { |
148 | case TCPC_RX_BUF_FRAME_TYPE_SOP1: |
149 | rx_type = TCPC_TX_SOP_PRIME; |
150 | break; |
151 | case TCPC_RX_BUF_FRAME_TYPE_SOP: |
152 | rx_type = TCPC_TX_SOP; |
153 | break; |
154 | default: |
155 | rx_type = TCPC_TX_SOP; |
156 | break; |
157 | } |
158 | |
159 | if (count == 0 || (frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP && |
160 | frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP1)) { |
161 | max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS); |
162 | dev_err(chip->dev, "%s\n" , count == 0 ? "error: count is 0" : |
163 | "error frame_type is not SOP/SOP'" ); |
164 | return; |
165 | } |
166 | |
167 | if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) { |
168 | dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n" , count); |
169 | return; |
170 | } |
171 | |
172 | /* |
173 | * Read count + 1 as RX_BUF_BYTE_x is hidden and can only be read through |
174 | * TCPC_RX_BYTE_CNT |
175 | */ |
176 | count += 1; |
177 | ret = regmap_raw_read(map: chip->data.regmap, TCPC_RX_BYTE_CNT, val: rx_buf, val_len: count); |
178 | if (ret < 0) { |
179 | dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d\n" , ret); |
180 | return; |
181 | } |
182 | |
183 | rx_buf_ptr = rx_buf + TCPC_RECEIVE_BUFFER_RX_BYTE_BUF_OFFSET; |
184 | msg.header = cpu_to_le16(*(u16 *)rx_buf_ptr); |
185 | rx_buf_ptr = rx_buf_ptr + sizeof(msg.header); |
186 | for (payload_index = 0; payload_index < pd_header_cnt_le(header: msg.header); payload_index++, |
187 | rx_buf_ptr += sizeof(msg.payload[0])) |
188 | msg.payload[payload_index] = cpu_to_le32(*(u32 *)rx_buf_ptr); |
189 | |
190 | /* |
191 | * Read complete, clear RX status alert bit. |
192 | * Clear overflow as well if set. |
193 | */ |
194 | ret = max_tcpci_write16(chip, TCPC_ALERT, val: status & TCPC_ALERT_RX_BUF_OVF ? |
195 | TCPC_ALERT_RX_STATUS | TCPC_ALERT_RX_BUF_OVF : |
196 | TCPC_ALERT_RX_STATUS); |
197 | if (ret < 0) |
198 | return; |
199 | |
200 | tcpm_pd_receive(port: chip->port, msg: &msg, rx_sop_type: rx_type); |
201 | } |
202 | |
203 | static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink) |
204 | { |
205 | struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata); |
206 | u8 buffer_source[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SOURCE}; |
207 | u8 buffer_sink[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SINK}; |
208 | u8 buffer_none[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_OFF}; |
209 | struct i2c_client *i2c = chip->client; |
210 | int ret; |
211 | |
212 | struct i2c_msg msgs[] = { |
213 | { |
214 | .addr = MAX_BUCK_BOOST_SID, |
215 | .flags = i2c->flags & I2C_M_TEN, |
216 | .len = 2, |
217 | .buf = source ? buffer_source : sink ? buffer_sink : buffer_none, |
218 | }, |
219 | }; |
220 | |
221 | if (source && sink) { |
222 | dev_err(chip->dev, "Both source and sink set\n" ); |
223 | return -EINVAL; |
224 | } |
225 | |
226 | ret = i2c_transfer(adap: i2c->adapter, msgs, num: 1); |
227 | |
228 | return ret < 0 ? ret : 1; |
229 | } |
230 | |
231 | static void process_power_status(struct max_tcpci_chip *chip) |
232 | { |
233 | u8 pwr_status; |
234 | int ret; |
235 | |
236 | ret = max_tcpci_read8(chip, TCPC_POWER_STATUS, val: &pwr_status); |
237 | if (ret < 0) |
238 | return; |
239 | |
240 | if (pwr_status == 0xff) |
241 | max_tcpci_init_regs(chip); |
242 | else if (pwr_status & TCPC_POWER_STATUS_SOURCING_VBUS) |
243 | tcpm_sourcing_vbus(port: chip->port); |
244 | else |
245 | tcpm_vbus_change(port: chip->port); |
246 | } |
247 | |
248 | static void max_tcpci_frs_sourcing_vbus(struct tcpci *tcpci, struct tcpci_data *tdata) |
249 | { |
250 | /* |
251 | * For Fast Role Swap case, Boost turns on autonomously without |
252 | * AP intervention, but, needs AP to enable source mode explicitly |
253 | * for AP to regain control. |
254 | */ |
255 | max_tcpci_set_vbus(tcpci, tdata, source: true, sink: false); |
256 | } |
257 | |
258 | static void process_tx(struct max_tcpci_chip *chip, u16 status) |
259 | { |
260 | if (status & TCPC_ALERT_TX_SUCCESS) |
261 | tcpm_pd_transmit_complete(port: chip->port, status: TCPC_TX_SUCCESS); |
262 | else if (status & TCPC_ALERT_TX_DISCARDED) |
263 | tcpm_pd_transmit_complete(port: chip->port, status: TCPC_TX_DISCARDED); |
264 | else if (status & TCPC_ALERT_TX_FAILED) |
265 | tcpm_pd_transmit_complete(port: chip->port, status: TCPC_TX_FAILED); |
266 | |
267 | /* Reinit regs as Hard reset sets them to default value */ |
268 | if ((status & TCPC_ALERT_TX_SUCCESS) && (status & TCPC_ALERT_TX_FAILED)) |
269 | max_tcpci_init_regs(chip); |
270 | } |
271 | |
272 | /* Enable USB switches when partner is USB communications capable */ |
273 | static void max_tcpci_set_partner_usb_comm_capable(struct tcpci *tcpci, struct tcpci_data *data, |
274 | bool capable) |
275 | { |
276 | struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata: data); |
277 | int ret; |
278 | |
279 | ret = max_tcpci_write8(chip, TCPC_VENDOR_USBSW_CTRL, val: capable ? |
280 | TCPC_VENDOR_USBSW_CTRL_ENABLE_USB_DATA : |
281 | TCPC_VENDOR_USBSW_CTRL_DISABLE_USB_DATA); |
282 | |
283 | if (ret < 0) |
284 | dev_err(chip->dev, "Failed to enable USB switches" ); |
285 | } |
286 | |
287 | static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status) |
288 | { |
289 | u16 mask; |
290 | int ret; |
291 | u8 reg_status; |
292 | |
293 | /* |
294 | * Clear alert status for everything except RX_STATUS, which shouldn't |
295 | * be cleared until we have successfully retrieved message. |
296 | */ |
297 | if (status & ~TCPC_ALERT_RX_STATUS) { |
298 | mask = status & TCPC_ALERT_RX_BUF_OVF ? |
299 | status & ~(TCPC_ALERT_RX_STATUS | TCPC_ALERT_RX_BUF_OVF) : |
300 | status & ~TCPC_ALERT_RX_STATUS; |
301 | ret = max_tcpci_write16(chip, TCPC_ALERT, val: mask); |
302 | if (ret < 0) { |
303 | dev_err(chip->dev, "ALERT clear failed\n" ); |
304 | return ret; |
305 | } |
306 | } |
307 | |
308 | if (status & TCPC_ALERT_RX_BUF_OVF && !(status & TCPC_ALERT_RX_STATUS)) { |
309 | ret = max_tcpci_write16(chip, TCPC_ALERT, val: (TCPC_ALERT_RX_STATUS | |
310 | TCPC_ALERT_RX_BUF_OVF)); |
311 | if (ret < 0) { |
312 | dev_err(chip->dev, "ALERT clear failed\n" ); |
313 | return ret; |
314 | } |
315 | } |
316 | |
317 | if (status & TCPC_ALERT_FAULT) { |
318 | ret = max_tcpci_read8(chip, TCPC_FAULT_STATUS, val: ®_status); |
319 | if (ret < 0) |
320 | return ret; |
321 | |
322 | ret = max_tcpci_write8(chip, TCPC_FAULT_STATUS, val: reg_status); |
323 | if (ret < 0) |
324 | return ret; |
325 | |
326 | if (reg_status & TCPC_FAULT_STATUS_VCONN_OC) { |
327 | chip->veto_vconn_swap = true; |
328 | tcpm_port_error_recovery(port: chip->port); |
329 | } |
330 | } |
331 | |
332 | if (status & TCPC_ALERT_EXTND) { |
333 | ret = max_tcpci_read8(chip, TCPC_ALERT_EXTENDED, val: ®_status); |
334 | if (ret < 0) |
335 | return ret; |
336 | |
337 | ret = max_tcpci_write8(chip, TCPC_ALERT_EXTENDED, val: reg_status); |
338 | if (ret < 0) |
339 | return ret; |
340 | |
341 | if (reg_status & TCPC_SINK_FAST_ROLE_SWAP) { |
342 | dev_info(chip->dev, "FRS Signal\n" ); |
343 | tcpm_sink_frs(port: chip->port); |
344 | } |
345 | } |
346 | |
347 | if (status & TCPC_ALERT_EXTENDED_STATUS) { |
348 | ret = max_tcpci_read8(chip, TCPC_EXTENDED_STATUS, val: (u8 *)®_status); |
349 | if (ret >= 0 && (reg_status & TCPC_EXTENDED_STATUS_VSAFE0V)) |
350 | tcpm_vbus_change(port: chip->port); |
351 | } |
352 | |
353 | if (status & TCPC_ALERT_RX_STATUS) |
354 | process_rx(chip, status); |
355 | |
356 | if (status & TCPC_ALERT_VBUS_DISCNCT) |
357 | tcpm_vbus_change(port: chip->port); |
358 | |
359 | if (status & TCPC_ALERT_CC_STATUS) { |
360 | if (chip->contaminant_state == DETECTED || tcpm_port_is_toggling(port: chip->port)) { |
361 | if (!max_contaminant_is_contaminant(chip, disconnect_while_debounce: false)) |
362 | tcpm_port_clean(port: chip->port); |
363 | } else { |
364 | tcpm_cc_change(port: chip->port); |
365 | } |
366 | } |
367 | |
368 | if (status & TCPC_ALERT_POWER_STATUS) |
369 | process_power_status(chip); |
370 | |
371 | if (status & TCPC_ALERT_RX_HARD_RST) { |
372 | tcpm_pd_hard_reset(port: chip->port); |
373 | max_tcpci_init_regs(chip); |
374 | } |
375 | |
376 | if (status & TCPC_ALERT_TX_SUCCESS || status & TCPC_ALERT_TX_DISCARDED || status & |
377 | TCPC_ALERT_TX_FAILED) |
378 | process_tx(chip, status); |
379 | |
380 | return IRQ_HANDLED; |
381 | } |
382 | |
383 | static irqreturn_t max_tcpci_irq(int irq, void *dev_id) |
384 | { |
385 | struct max_tcpci_chip *chip = dev_id; |
386 | u16 status; |
387 | irqreturn_t irq_return = IRQ_HANDLED; |
388 | int ret; |
389 | |
390 | if (!chip->port) |
391 | return IRQ_HANDLED; |
392 | |
393 | ret = max_tcpci_read16(chip, TCPC_ALERT, val: &status); |
394 | if (ret < 0) { |
395 | dev_err(chip->dev, "ALERT read failed\n" ); |
396 | return ret; |
397 | } |
398 | while (status) { |
399 | irq_return = _max_tcpci_irq(chip, status); |
400 | /* Do not return if the ALERT is already set. */ |
401 | ret = max_tcpci_read16(chip, TCPC_ALERT, val: &status); |
402 | if (ret < 0) |
403 | break; |
404 | } |
405 | |
406 | return irq_return; |
407 | } |
408 | |
409 | static irqreturn_t max_tcpci_isr(int irq, void *dev_id) |
410 | { |
411 | struct max_tcpci_chip *chip = dev_id; |
412 | |
413 | pm_wakeup_event(dev: chip->dev, PD_ACTIVITY_TIMEOUT_MS); |
414 | |
415 | if (!chip->port) |
416 | return IRQ_HANDLED; |
417 | |
418 | return IRQ_WAKE_THREAD; |
419 | } |
420 | |
421 | static int max_tcpci_init_alert(struct max_tcpci_chip *chip, struct i2c_client *client) |
422 | { |
423 | int ret; |
424 | |
425 | ret = devm_request_threaded_irq(dev: chip->dev, irq: client->irq, handler: max_tcpci_isr, thread_fn: max_tcpci_irq, |
426 | irqflags: (IRQF_TRIGGER_LOW | IRQF_ONESHOT), devname: dev_name(dev: chip->dev), |
427 | dev_id: chip); |
428 | |
429 | if (ret < 0) |
430 | return ret; |
431 | |
432 | enable_irq_wake(irq: client->irq); |
433 | return 0; |
434 | } |
435 | |
436 | static int max_tcpci_start_toggling(struct tcpci *tcpci, struct tcpci_data *tdata, |
437 | enum typec_cc_status cc) |
438 | { |
439 | struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata); |
440 | |
441 | max_tcpci_init_regs(chip); |
442 | |
443 | return 0; |
444 | } |
445 | |
446 | static int tcpci_init(struct tcpci *tcpci, struct tcpci_data *data) |
447 | { |
448 | /* |
449 | * Generic TCPCI overwrites the regs once this driver initializes |
450 | * them. Prevent this by returning -1. |
451 | */ |
452 | return -1; |
453 | } |
454 | |
455 | static void max_tcpci_check_contaminant(struct tcpci *tcpci, struct tcpci_data *tdata) |
456 | { |
457 | struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata); |
458 | |
459 | if (!max_contaminant_is_contaminant(chip, disconnect_while_debounce: true)) |
460 | tcpm_port_clean(port: chip->port); |
461 | } |
462 | |
463 | static bool max_tcpci_attempt_vconn_swap_discovery(struct tcpci *tcpci, struct tcpci_data *tdata) |
464 | { |
465 | struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata); |
466 | |
467 | if (chip->veto_vconn_swap) { |
468 | chip->veto_vconn_swap = false; |
469 | return false; |
470 | } |
471 | |
472 | return true; |
473 | } |
474 | |
475 | static int max_tcpci_probe(struct i2c_client *client) |
476 | { |
477 | int ret; |
478 | struct max_tcpci_chip *chip; |
479 | u8 power_status; |
480 | |
481 | chip = devm_kzalloc(dev: &client->dev, size: sizeof(*chip), GFP_KERNEL); |
482 | if (!chip) |
483 | return -ENOMEM; |
484 | |
485 | chip->client = client; |
486 | chip->data.regmap = devm_regmap_init_i2c(client, &max_tcpci_regmap_config); |
487 | if (IS_ERR(ptr: chip->data.regmap)) { |
488 | dev_err(&client->dev, "Regmap init failed\n" ); |
489 | return PTR_ERR(ptr: chip->data.regmap); |
490 | } |
491 | |
492 | chip->dev = &client->dev; |
493 | i2c_set_clientdata(client, data: chip); |
494 | |
495 | ret = max_tcpci_read8(chip, TCPC_POWER_STATUS, val: &power_status); |
496 | if (ret < 0) |
497 | return ret; |
498 | |
499 | /* Chip level tcpci callbacks */ |
500 | chip->data.set_vbus = max_tcpci_set_vbus; |
501 | chip->data.start_drp_toggling = max_tcpci_start_toggling; |
502 | chip->data.TX_BUF_BYTE_x_hidden = true; |
503 | chip->data.init = tcpci_init; |
504 | chip->data.frs_sourcing_vbus = max_tcpci_frs_sourcing_vbus; |
505 | chip->data.auto_discharge_disconnect = true; |
506 | chip->data.vbus_vsafe0v = true; |
507 | chip->data.set_partner_usb_comm_capable = max_tcpci_set_partner_usb_comm_capable; |
508 | chip->data.check_contaminant = max_tcpci_check_contaminant; |
509 | chip->data.cable_comm_capable = true; |
510 | chip->data.attempt_vconn_swap_discovery = max_tcpci_attempt_vconn_swap_discovery; |
511 | |
512 | max_tcpci_init_regs(chip); |
513 | chip->tcpci = tcpci_register_port(dev: chip->dev, data: &chip->data); |
514 | if (IS_ERR(ptr: chip->tcpci)) { |
515 | dev_err(&client->dev, "TCPCI port registration failed\n" ); |
516 | return PTR_ERR(ptr: chip->tcpci); |
517 | } |
518 | chip->port = tcpci_get_tcpm_port(tcpci: chip->tcpci); |
519 | ret = max_tcpci_init_alert(chip, client); |
520 | if (ret < 0) |
521 | goto unreg_port; |
522 | |
523 | device_init_wakeup(dev: chip->dev, enable: true); |
524 | return 0; |
525 | |
526 | unreg_port: |
527 | tcpci_unregister_port(tcpci: chip->tcpci); |
528 | |
529 | return ret; |
530 | } |
531 | |
532 | static void max_tcpci_remove(struct i2c_client *client) |
533 | { |
534 | struct max_tcpci_chip *chip = i2c_get_clientdata(client); |
535 | |
536 | if (!IS_ERR_OR_NULL(ptr: chip->tcpci)) |
537 | tcpci_unregister_port(tcpci: chip->tcpci); |
538 | } |
539 | |
540 | static const struct i2c_device_id max_tcpci_id[] = { |
541 | { "maxtcpc" , 0 }, |
542 | { } |
543 | }; |
544 | MODULE_DEVICE_TABLE(i2c, max_tcpci_id); |
545 | |
546 | #ifdef CONFIG_OF |
547 | static const struct of_device_id max_tcpci_of_match[] = { |
548 | { .compatible = "maxim,max33359" , }, |
549 | {}, |
550 | }; |
551 | MODULE_DEVICE_TABLE(of, max_tcpci_of_match); |
552 | #endif |
553 | |
554 | static struct i2c_driver max_tcpci_i2c_driver = { |
555 | .driver = { |
556 | .name = "maxtcpc" , |
557 | .of_match_table = of_match_ptr(max_tcpci_of_match), |
558 | }, |
559 | .probe = max_tcpci_probe, |
560 | .remove = max_tcpci_remove, |
561 | .id_table = max_tcpci_id, |
562 | }; |
563 | module_i2c_driver(max_tcpci_i2c_driver); |
564 | |
565 | MODULE_AUTHOR("Badhri Jagan Sridharan <badhri@google.com>" ); |
566 | MODULE_DESCRIPTION("Maxim TCPCI based USB Type-C Port Controller Interface Driver" ); |
567 | MODULE_LICENSE("GPL v2" ); |
568 | |