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