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