1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // extcon-ptn5150.c - PTN5150 CC logic extcon driver to support USB detection 4 // 5 // Based on extcon-sm5502.c driver 6 // Copyright (c) 2018-2019 by Vijai Kumar K 7 // Author: Vijai Kumar K <vijaikumar.kanagarajan@gmail.com> 8 // Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org> 9 10 #include <linux/bitfield.h> 11 #include <linux/err.h> 12 #include <linux/i2c.h> 13 #include <linux/interrupt.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/regmap.h> 17 #include <linux/slab.h> 18 #include <linux/extcon-provider.h> 19 #include <linux/gpio/consumer.h> 20 #include <linux/usb/role.h> 21 #include <linux/usb/typec_mux.h> 22 23 /* PTN5150 registers */ 24 #define PTN5150_REG_DEVICE_ID 0x01 25 #define PTN5150_REG_CONTROL 0x02 26 #define PTN5150_REG_INT_STATUS 0x03 27 #define PTN5150_REG_CC_STATUS 0x04 28 #define PTN5150_REG_CON_DET 0x09 29 #define PTN5150_REG_VCONN_STATUS 0x0a 30 #define PTN5150_REG_RESET 0x0b 31 #define PTN5150_REG_INT_MASK 0x18 32 #define PTN5150_REG_INT_REG_STATUS 0x19 33 #define PTN5150_REG_END PTN5150_REG_INT_REG_STATUS 34 35 #define PTN5150_DFP_ATTACHED 0x1 36 #define PTN5150_UFP_ATTACHED 0x2 37 38 /* Define PTN5150 MASK/SHIFT constant */ 39 #define PTN5150_REG_DEVICE_ID_VERSION GENMASK(7, 3) 40 #define PTN5150_REG_DEVICE_ID_VENDOR GENMASK(2, 0) 41 42 #define PTN5150_POLARITY_CC1 0x1 43 #define PTN5150_POLARITY_CC2 0x2 44 45 #define PTN5150_REG_CC_PORT_ATTACHMENT GENMASK(4, 2) 46 #define PTN5150_REG_CC_POLARITY GENMASK(1, 0) 47 #define PTN5150_REG_CC_VBUS_DETECTION BIT(7) 48 #define PTN5150_REG_INT_CABLE_ATTACH_MASK BIT(0) 49 #define PTN5150_REG_INT_CABLE_DETACH_MASK BIT(1) 50 51 struct ptn5150_info { 52 struct device *dev; 53 struct extcon_dev *edev; 54 struct i2c_client *i2c; 55 struct regmap *regmap; 56 struct gpio_desc *int_gpiod; 57 struct gpio_desc *vbus_gpiod; 58 int irq; 59 struct work_struct irq_work; 60 struct mutex mutex; 61 struct typec_switch *orient_sw; 62 struct usb_role_switch *role_sw; 63 }; 64 65 /* List of detectable cables */ 66 static const unsigned int ptn5150_extcon_cable[] = { 67 EXTCON_USB, 68 EXTCON_USB_HOST, 69 EXTCON_NONE, 70 }; 71 72 static const struct regmap_config ptn5150_regmap_config = { 73 .reg_bits = 8, 74 .val_bits = 8, 75 .max_register = PTN5150_REG_END, 76 }; 77 78 static void ptn5150_check_state(struct ptn5150_info *info) 79 { 80 enum typec_orientation orient = TYPEC_ORIENTATION_NONE; 81 unsigned int port_status, reg_data, vbus; 82 enum usb_role usb_role = USB_ROLE_NONE; 83 int ret; 84 85 ret = regmap_read(info->regmap, PTN5150_REG_CC_STATUS, ®_data); 86 if (ret) { 87 dev_err(info->dev, "failed to read CC STATUS %d\n", ret); 88 return; 89 } 90 91 orient = FIELD_GET(PTN5150_REG_CC_POLARITY, reg_data); 92 switch (orient) { 93 case PTN5150_POLARITY_CC1: 94 orient = TYPEC_ORIENTATION_NORMAL; 95 break; 96 case PTN5150_POLARITY_CC2: 97 orient = TYPEC_ORIENTATION_REVERSE; 98 break; 99 default: 100 orient = TYPEC_ORIENTATION_NONE; 101 break; 102 } 103 104 ret = typec_switch_set(info->orient_sw, orient); 105 if (ret) 106 dev_err(info->dev, "failed to set orientation: %d\n", ret); 107 108 port_status = FIELD_GET(PTN5150_REG_CC_PORT_ATTACHMENT, reg_data); 109 110 switch (port_status) { 111 case PTN5150_DFP_ATTACHED: 112 extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false); 113 gpiod_set_value_cansleep(info->vbus_gpiod, 0); 114 extcon_set_state_sync(info->edev, EXTCON_USB, true); 115 usb_role = USB_ROLE_DEVICE; 116 break; 117 case PTN5150_UFP_ATTACHED: 118 extcon_set_state_sync(info->edev, EXTCON_USB, false); 119 vbus = FIELD_GET(PTN5150_REG_CC_VBUS_DETECTION, reg_data); 120 if (vbus) 121 gpiod_set_value_cansleep(info->vbus_gpiod, 0); 122 else 123 gpiod_set_value_cansleep(info->vbus_gpiod, 1); 124 125 extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true); 126 usb_role = USB_ROLE_HOST; 127 break; 128 default: 129 break; 130 } 131 132 if (usb_role) { 133 ret = usb_role_switch_set_role(info->role_sw, usb_role); 134 if (ret) 135 dev_err(info->dev, "failed to set %s role: %d\n", 136 usb_role_string(usb_role), ret); 137 } 138 } 139 140 static void ptn5150_irq_work(struct work_struct *work) 141 { 142 struct ptn5150_info *info = container_of(work, 143 struct ptn5150_info, irq_work); 144 int ret = 0; 145 unsigned int int_status; 146 147 if (!info->edev) 148 return; 149 150 mutex_lock(&info->mutex); 151 152 /* Clear interrupt. Read would clear the register */ 153 ret = regmap_read(info->regmap, PTN5150_REG_INT_STATUS, &int_status); 154 if (ret) { 155 dev_err(info->dev, "failed to read INT STATUS %d\n", ret); 156 mutex_unlock(&info->mutex); 157 return; 158 } 159 160 if (int_status) { 161 unsigned int cable_attach; 162 163 cable_attach = int_status & PTN5150_REG_INT_CABLE_ATTACH_MASK; 164 if (cable_attach) { 165 ptn5150_check_state(info); 166 } else { 167 extcon_set_state_sync(info->edev, 168 EXTCON_USB_HOST, false); 169 extcon_set_state_sync(info->edev, 170 EXTCON_USB, false); 171 gpiod_set_value_cansleep(info->vbus_gpiod, 0); 172 173 ret = usb_role_switch_set_role(info->role_sw, 174 USB_ROLE_NONE); 175 if (ret) 176 dev_err(info->dev, 177 "failed to set none role: %d\n", 178 ret); 179 180 ret = typec_switch_set(info->orient_sw, 181 TYPEC_ORIENTATION_NONE); 182 if (ret) 183 dev_err(info->dev, 184 "failed to set orientation: %d\n", ret); 185 } 186 } 187 188 /* Clear interrupt. Read would clear the register */ 189 ret = regmap_read(info->regmap, PTN5150_REG_INT_REG_STATUS, 190 &int_status); 191 if (ret) { 192 dev_err(info->dev, 193 "failed to read INT REG STATUS %d\n", ret); 194 mutex_unlock(&info->mutex); 195 return; 196 } 197 198 mutex_unlock(&info->mutex); 199 } 200 201 202 static irqreturn_t ptn5150_irq_handler(int irq, void *data) 203 { 204 struct ptn5150_info *info = data; 205 206 schedule_work(&info->irq_work); 207 208 return IRQ_HANDLED; 209 } 210 211 static int ptn5150_init_dev_type(struct ptn5150_info *info) 212 { 213 unsigned int reg_data, vendor_id, version_id; 214 int ret; 215 216 ret = regmap_read(info->regmap, PTN5150_REG_DEVICE_ID, ®_data); 217 if (ret) { 218 dev_err(info->dev, "failed to read DEVICE_ID %d\n", ret); 219 return -EINVAL; 220 } 221 222 vendor_id = FIELD_GET(PTN5150_REG_DEVICE_ID_VENDOR, reg_data); 223 version_id = FIELD_GET(PTN5150_REG_DEVICE_ID_VERSION, reg_data); 224 dev_dbg(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n", 225 version_id, vendor_id); 226 227 /* Clear any existing interrupts */ 228 ret = regmap_read(info->regmap, PTN5150_REG_INT_STATUS, ®_data); 229 if (ret) { 230 dev_err(info->dev, 231 "failed to read PTN5150_REG_INT_STATUS %d\n", 232 ret); 233 return -EINVAL; 234 } 235 236 ret = regmap_read(info->regmap, PTN5150_REG_INT_REG_STATUS, ®_data); 237 if (ret) { 238 dev_err(info->dev, 239 "failed to read PTN5150_REG_INT_REG_STATUS %d\n", ret); 240 return -EINVAL; 241 } 242 243 return 0; 244 } 245 246 static void ptn5150_work_sync_and_put(void *data) 247 { 248 struct ptn5150_info *info = data; 249 250 cancel_work_sync(&info->irq_work); 251 usb_role_switch_put(info->role_sw); 252 typec_switch_put(info->orient_sw); 253 } 254 255 static int ptn5150_i2c_probe(struct i2c_client *i2c) 256 { 257 struct device *dev = &i2c->dev; 258 struct device_node *np = i2c->dev.of_node; 259 struct fwnode_handle *connector; 260 struct ptn5150_info *info; 261 int ret; 262 263 if (!np) 264 return -EINVAL; 265 266 info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL); 267 if (!info) 268 return -ENOMEM; 269 i2c_set_clientdata(i2c, info); 270 271 info->dev = &i2c->dev; 272 info->i2c = i2c; 273 info->vbus_gpiod = devm_gpiod_get(&i2c->dev, "vbus", GPIOD_OUT_LOW); 274 if (IS_ERR(info->vbus_gpiod)) { 275 ret = PTR_ERR(info->vbus_gpiod); 276 if (ret == -ENOENT) { 277 dev_info(dev, "No VBUS GPIO, ignoring VBUS control\n"); 278 info->vbus_gpiod = NULL; 279 } else { 280 return dev_err_probe(dev, ret, "failed to get VBUS GPIO\n"); 281 } 282 } 283 284 mutex_init(&info->mutex); 285 286 INIT_WORK(&info->irq_work, ptn5150_irq_work); 287 288 info->regmap = devm_regmap_init_i2c(i2c, &ptn5150_regmap_config); 289 if (IS_ERR(info->regmap)) { 290 return dev_err_probe(info->dev, PTR_ERR(info->regmap), 291 "failed to allocate register map\n"); 292 } 293 294 if (i2c->irq > 0) { 295 info->irq = i2c->irq; 296 } else { 297 info->int_gpiod = devm_gpiod_get(&i2c->dev, "int", GPIOD_IN); 298 if (IS_ERR(info->int_gpiod)) { 299 return dev_err_probe(dev, PTR_ERR(info->int_gpiod), 300 "failed to get INT GPIO\n"); 301 } 302 303 info->irq = gpiod_to_irq(info->int_gpiod); 304 if (info->irq < 0) { 305 dev_err(dev, "failed to get INTB IRQ\n"); 306 return info->irq; 307 } 308 } 309 310 ret = devm_request_threaded_irq(dev, info->irq, NULL, 311 ptn5150_irq_handler, 312 IRQF_TRIGGER_FALLING | 313 IRQF_ONESHOT, 314 i2c->name, info); 315 if (ret < 0) { 316 dev_err(dev, "failed to request handler for INTB IRQ\n"); 317 return ret; 318 } 319 320 /* Allocate extcon device */ 321 info->edev = devm_extcon_dev_allocate(info->dev, ptn5150_extcon_cable); 322 if (IS_ERR(info->edev)) { 323 dev_err(info->dev, "failed to allocate memory for extcon\n"); 324 return -ENOMEM; 325 } 326 327 /* Register extcon device */ 328 ret = devm_extcon_dev_register(info->dev, info->edev); 329 if (ret) { 330 dev_err(info->dev, "failed to register extcon device\n"); 331 return ret; 332 } 333 334 extcon_set_property_capability(info->edev, EXTCON_USB, 335 EXTCON_PROP_USB_VBUS); 336 extcon_set_property_capability(info->edev, EXTCON_USB_HOST, 337 EXTCON_PROP_USB_VBUS); 338 extcon_set_property_capability(info->edev, EXTCON_USB_HOST, 339 EXTCON_PROP_USB_TYPEC_POLARITY); 340 341 /* Initialize PTN5150 device and print vendor id and version id */ 342 ret = ptn5150_init_dev_type(info); 343 if (ret) 344 return -EINVAL; 345 346 connector = device_get_named_child_node(dev, "connector"); 347 if (connector) { 348 info->orient_sw = fwnode_typec_switch_get(connector); 349 if (IS_ERR(info->orient_sw)) 350 return dev_err_probe(info->dev, PTR_ERR(info->orient_sw), 351 "failed to get orientation switch\n"); 352 } 353 354 info->role_sw = usb_role_switch_get(info->dev); 355 if (!info->role_sw && connector) 356 info->role_sw = fwnode_usb_role_switch_get(connector); 357 if (IS_ERR(info->role_sw)) 358 return dev_err_probe(info->dev, PTR_ERR(info->role_sw), 359 "failed to get role switch\n"); 360 361 ret = devm_add_action_or_reset(dev, ptn5150_work_sync_and_put, info); 362 if (ret) 363 return ret; 364 365 /* 366 * Update current extcon state if for example OTG connection was there 367 * before the probe 368 */ 369 mutex_lock(&info->mutex); 370 ptn5150_check_state(info); 371 mutex_unlock(&info->mutex); 372 373 return 0; 374 } 375 376 static int ptn5150_resume(struct device *dev) 377 { 378 struct i2c_client *i2c = to_i2c_client(dev); 379 struct ptn5150_info *info = i2c_get_clientdata(i2c); 380 381 /* Need to check possible pending interrupt events */ 382 schedule_work(&info->irq_work); 383 384 return 0; 385 } 386 387 static DEFINE_SIMPLE_DEV_PM_OPS(ptn5150_pm_ops, NULL, ptn5150_resume); 388 389 static const struct of_device_id ptn5150_dt_match[] = { 390 { .compatible = "nxp,ptn5150" }, 391 { }, 392 }; 393 MODULE_DEVICE_TABLE(of, ptn5150_dt_match); 394 395 static const struct i2c_device_id ptn5150_i2c_id[] = { 396 { "ptn5150" }, 397 { } 398 }; 399 MODULE_DEVICE_TABLE(i2c, ptn5150_i2c_id); 400 401 static struct i2c_driver ptn5150_i2c_driver = { 402 .driver = { 403 .name = "ptn5150", 404 .pm = pm_sleep_ptr(&ptn5150_pm_ops), 405 .of_match_table = ptn5150_dt_match, 406 }, 407 .probe = ptn5150_i2c_probe, 408 .id_table = ptn5150_i2c_id, 409 }; 410 module_i2c_driver(ptn5150_i2c_driver); 411 412 MODULE_DESCRIPTION("NXP PTN5150 CC logic Extcon driver"); 413 MODULE_AUTHOR("Vijai Kumar K <vijaikumar.kanagarajan@gmail.com>"); 414 MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); 415 MODULE_LICENSE("GPL v2"); 416