xref: /linux/drivers/usb/typec/hd3ss3220.c (revision 65538a8f02fe6e4f07228a816529b039b544f051)
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 			  &reg_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