1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * USB GPIO Based Connection Detection Driver 4 * 5 * Copyright (C) 2019 MediaTek Inc. 6 * 7 * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> 8 * 9 * Some code borrowed from drivers/extcon/extcon-usb-gpio.c 10 */ 11 12 #include <linux/device.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/interrupt.h> 15 #include <linux/irq.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/pinctrl/consumer.h> 19 #include <linux/platform_device.h> 20 #include <linux/power_supply.h> 21 #include <linux/regulator/consumer.h> 22 #include <linux/string_choices.h> 23 #include <linux/usb/role.h> 24 #include <linux/idr.h> 25 26 static DEFINE_IDA(usb_conn_ida); 27 28 #define USB_GPIO_DEB_MS 20 /* ms */ 29 #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ 30 31 #define USB_CONN_IRQF \ 32 (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT) 33 34 struct usb_conn_info { 35 struct device *dev; 36 int conn_id; /* store the IDA-allocated ID */ 37 struct usb_role_switch *role_sw; 38 enum usb_role last_role; 39 struct regulator *vbus; 40 struct delayed_work dw_det; 41 unsigned long debounce_jiffies; 42 43 struct gpio_desc *id_gpiod; 44 struct gpio_desc *vbus_gpiod; 45 int id_irq; 46 int vbus_irq; 47 48 struct power_supply_desc desc; 49 struct power_supply *charger; 50 bool initial_detection; 51 }; 52 53 /* 54 * "DEVICE" = VBUS and "HOST" = !ID, so we have: 55 * Both "DEVICE" and "HOST" can't be set as active at the same time 56 * so if "HOST" is active (i.e. ID is 0) we keep "DEVICE" inactive 57 * even if VBUS is on. 58 * 59 * Role | ID | VBUS 60 * ------------------------------------ 61 * [1] DEVICE | H | H 62 * [2] NONE | H | L 63 * [3] HOST | L | H 64 * [4] HOST | L | L 65 * 66 * In case we have only one of these signals: 67 * - VBUS only - we want to distinguish between [1] and [2], so ID is always 1 68 * - ID only - we want to distinguish between [1] and [4], so VBUS = ID 69 */ 70 static void usb_conn_detect_cable(struct work_struct *work) 71 { 72 struct usb_conn_info *info; 73 enum usb_role role; 74 int id, vbus, ret; 75 76 info = container_of(to_delayed_work(work), 77 struct usb_conn_info, dw_det); 78 79 /* check ID and VBUS */ 80 id = info->id_gpiod ? 81 gpiod_get_value_cansleep(info->id_gpiod) : 1; 82 vbus = info->vbus_gpiod ? 83 gpiod_get_value_cansleep(info->vbus_gpiod) : id; 84 85 if (!id) 86 role = USB_ROLE_HOST; 87 else if (vbus) 88 role = USB_ROLE_DEVICE; 89 else 90 role = USB_ROLE_NONE; 91 92 dev_dbg(info->dev, "role %s -> %s, gpios: id %d, vbus %d\n", 93 usb_role_string(info->last_role), usb_role_string(role), id, vbus); 94 95 if (!info->initial_detection && info->last_role == role) { 96 dev_warn(info->dev, "repeated role: %s\n", usb_role_string(role)); 97 return; 98 } 99 100 info->initial_detection = false; 101 102 if (info->last_role == USB_ROLE_HOST && info->vbus) 103 regulator_disable(info->vbus); 104 105 ret = usb_role_switch_set_role(info->role_sw, role); 106 if (ret) 107 dev_err(info->dev, "failed to set role: %d\n", ret); 108 109 if (role == USB_ROLE_HOST && info->vbus) { 110 ret = regulator_enable(info->vbus); 111 if (ret) 112 dev_err(info->dev, "enable vbus regulator failed\n"); 113 } 114 115 info->last_role = role; 116 117 if (info->vbus) 118 dev_dbg(info->dev, "vbus regulator is %s\n", 119 str_enabled_disabled(regulator_is_enabled(info->vbus))); 120 121 power_supply_changed(info->charger); 122 } 123 124 static void usb_conn_queue_dwork(struct usb_conn_info *info, 125 unsigned long delay) 126 { 127 queue_delayed_work(system_power_efficient_wq, &info->dw_det, delay); 128 } 129 130 static irqreturn_t usb_conn_isr(int irq, void *dev_id) 131 { 132 struct usb_conn_info *info = dev_id; 133 134 usb_conn_queue_dwork(info, info->debounce_jiffies); 135 136 return IRQ_HANDLED; 137 } 138 139 static enum power_supply_property usb_charger_properties[] = { 140 POWER_SUPPLY_PROP_ONLINE, 141 }; 142 143 static int usb_charger_get_property(struct power_supply *psy, 144 enum power_supply_property psp, 145 union power_supply_propval *val) 146 { 147 struct usb_conn_info *info = power_supply_get_drvdata(psy); 148 149 switch (psp) { 150 case POWER_SUPPLY_PROP_ONLINE: 151 val->intval = info->last_role == USB_ROLE_DEVICE; 152 break; 153 default: 154 return -EINVAL; 155 } 156 157 return 0; 158 } 159 160 static int usb_conn_psy_register(struct usb_conn_info *info) 161 { 162 struct device *dev = info->dev; 163 struct power_supply_desc *desc = &info->desc; 164 struct power_supply_config cfg = { 165 .fwnode = dev_fwnode(dev), 166 }; 167 168 info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); 169 if (info->conn_id < 0) 170 return info->conn_id; 171 172 desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", 173 info->conn_id); 174 if (!desc->name) { 175 ida_free(&usb_conn_ida, info->conn_id); 176 return -ENOMEM; 177 } 178 179 desc->properties = usb_charger_properties; 180 desc->num_properties = ARRAY_SIZE(usb_charger_properties); 181 desc->get_property = usb_charger_get_property; 182 desc->type = POWER_SUPPLY_TYPE_USB; 183 cfg.drv_data = info; 184 185 info->charger = devm_power_supply_register(dev, desc, &cfg); 186 if (IS_ERR(info->charger)) { 187 dev_err(dev, "Unable to register charger %d\n", info->conn_id); 188 ida_free(&usb_conn_ida, info->conn_id); 189 } 190 191 return PTR_ERR_OR_ZERO(info->charger); 192 } 193 194 static int usb_conn_probe(struct platform_device *pdev) 195 { 196 struct device *dev = &pdev->dev; 197 struct usb_conn_info *info; 198 int ret = 0; 199 200 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 201 if (!info) 202 return -ENOMEM; 203 204 info->dev = dev; 205 info->id_gpiod = devm_gpiod_get_optional(dev, "id", GPIOD_IN); 206 if (IS_ERR(info->id_gpiod)) 207 return PTR_ERR(info->id_gpiod); 208 209 info->vbus_gpiod = devm_gpiod_get_optional(dev, "vbus", GPIOD_IN); 210 if (IS_ERR(info->vbus_gpiod)) 211 return PTR_ERR(info->vbus_gpiod); 212 213 if (!info->id_gpiod && !info->vbus_gpiod) { 214 dev_err(dev, "failed to get gpios\n"); 215 return -ENODEV; 216 } 217 218 if (info->id_gpiod) 219 ret = gpiod_set_debounce(info->id_gpiod, USB_GPIO_DEB_US); 220 if (!ret && info->vbus_gpiod) 221 ret = gpiod_set_debounce(info->vbus_gpiod, USB_GPIO_DEB_US); 222 if (ret < 0) 223 info->debounce_jiffies = msecs_to_jiffies(USB_GPIO_DEB_MS); 224 225 INIT_DELAYED_WORK(&info->dw_det, usb_conn_detect_cable); 226 227 info->vbus = devm_regulator_get_optional(dev, "vbus"); 228 if (PTR_ERR(info->vbus) == -ENODEV) 229 info->vbus = NULL; 230 231 if (IS_ERR(info->vbus)) 232 return dev_err_probe(dev, PTR_ERR(info->vbus), "failed to get vbus\n"); 233 234 info->role_sw = usb_role_switch_get(dev); 235 if (IS_ERR(info->role_sw)) 236 return dev_err_probe(dev, PTR_ERR(info->role_sw), 237 "failed to get role switch\n"); 238 239 ret = usb_conn_psy_register(info); 240 if (ret) 241 goto put_role_sw; 242 243 if (info->id_gpiod) { 244 info->id_irq = gpiod_to_irq(info->id_gpiod); 245 if (info->id_irq < 0) { 246 dev_err(dev, "failed to get ID IRQ\n"); 247 ret = info->id_irq; 248 goto put_role_sw; 249 } 250 251 ret = devm_request_threaded_irq(dev, info->id_irq, NULL, 252 usb_conn_isr, USB_CONN_IRQF, 253 pdev->name, info); 254 if (ret < 0) { 255 dev_err(dev, "failed to request ID IRQ\n"); 256 goto put_role_sw; 257 } 258 } 259 260 if (info->vbus_gpiod) { 261 info->vbus_irq = gpiod_to_irq(info->vbus_gpiod); 262 if (info->vbus_irq < 0) { 263 dev_err(dev, "failed to get VBUS IRQ\n"); 264 ret = info->vbus_irq; 265 goto put_role_sw; 266 } 267 268 ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL, 269 usb_conn_isr, USB_CONN_IRQF, 270 pdev->name, info); 271 if (ret < 0) { 272 dev_err(dev, "failed to request VBUS IRQ\n"); 273 goto put_role_sw; 274 } 275 } 276 277 platform_set_drvdata(pdev, info); 278 device_set_wakeup_capable(&pdev->dev, true); 279 280 /* Perform initial detection */ 281 info->initial_detection = true; 282 usb_conn_queue_dwork(info, 0); 283 284 return 0; 285 286 put_role_sw: 287 usb_role_switch_put(info->role_sw); 288 return ret; 289 } 290 291 static void usb_conn_remove(struct platform_device *pdev) 292 { 293 struct usb_conn_info *info = platform_get_drvdata(pdev); 294 295 cancel_delayed_work_sync(&info->dw_det); 296 297 if (info->charger) 298 ida_free(&usb_conn_ida, info->conn_id); 299 300 if (info->last_role == USB_ROLE_HOST && info->vbus) 301 regulator_disable(info->vbus); 302 303 usb_role_switch_put(info->role_sw); 304 } 305 306 static int __maybe_unused usb_conn_suspend(struct device *dev) 307 { 308 struct usb_conn_info *info = dev_get_drvdata(dev); 309 310 if (device_may_wakeup(dev)) { 311 if (info->id_gpiod) 312 enable_irq_wake(info->id_irq); 313 if (info->vbus_gpiod) 314 enable_irq_wake(info->vbus_irq); 315 return 0; 316 } 317 318 if (info->id_gpiod) 319 disable_irq(info->id_irq); 320 if (info->vbus_gpiod) 321 disable_irq(info->vbus_irq); 322 323 pinctrl_pm_select_sleep_state(dev); 324 325 return 0; 326 } 327 328 static int __maybe_unused usb_conn_resume(struct device *dev) 329 { 330 struct usb_conn_info *info = dev_get_drvdata(dev); 331 332 if (device_may_wakeup(dev)) { 333 if (info->id_gpiod) 334 disable_irq_wake(info->id_irq); 335 if (info->vbus_gpiod) 336 disable_irq_wake(info->vbus_irq); 337 return 0; 338 } 339 340 pinctrl_pm_select_default_state(dev); 341 342 if (info->id_gpiod) 343 enable_irq(info->id_irq); 344 if (info->vbus_gpiod) 345 enable_irq(info->vbus_irq); 346 347 usb_conn_queue_dwork(info, 0); 348 349 return 0; 350 } 351 352 static SIMPLE_DEV_PM_OPS(usb_conn_pm_ops, 353 usb_conn_suspend, usb_conn_resume); 354 355 static const struct of_device_id usb_conn_dt_match[] = { 356 { .compatible = "gpio-usb-b-connector", }, 357 { } 358 }; 359 MODULE_DEVICE_TABLE(of, usb_conn_dt_match); 360 361 static struct platform_driver usb_conn_driver = { 362 .probe = usb_conn_probe, 363 .remove = usb_conn_remove, 364 .driver = { 365 .name = "usb-conn-gpio", 366 .pm = &usb_conn_pm_ops, 367 .of_match_table = usb_conn_dt_match, 368 }, 369 }; 370 371 module_platform_driver(usb_conn_driver); 372 373 MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>"); 374 MODULE_DESCRIPTION("USB GPIO based connection detection driver"); 375 MODULE_LICENSE("GPL v2"); 376