1 /* 2 * extcon-max77843.c - Maxim MAX77843 extcon driver to support 3 * MUIC(Micro USB Interface Controller) 4 * 5 * Copyright (C) 2015 Samsung Electronics 6 * Author: Jaewon Kim <jaewon02.kim@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14 #include <linux/extcon.h> 15 #include <linux/i2c.h> 16 #include <linux/interrupt.h> 17 #include <linux/kernel.h> 18 #include <linux/mfd/max77843-private.h> 19 #include <linux/module.h> 20 #include <linux/platform_device.h> 21 #include <linux/workqueue.h> 22 23 #define DELAY_MS_DEFAULT 15000 /* unit: millisecond */ 24 25 enum max77843_muic_status { 26 MAX77843_MUIC_STATUS1 = 0, 27 MAX77843_MUIC_STATUS2, 28 MAX77843_MUIC_STATUS3, 29 30 MAX77843_MUIC_STATUS_NUM, 31 }; 32 33 struct max77843_muic_info { 34 struct device *dev; 35 struct max77843 *max77843; 36 struct extcon_dev *edev; 37 38 struct mutex mutex; 39 struct work_struct irq_work; 40 struct delayed_work wq_detcable; 41 42 u8 status[MAX77843_MUIC_STATUS_NUM]; 43 int prev_cable_type; 44 int prev_chg_type; 45 int prev_gnd_type; 46 47 bool irq_adc; 48 bool irq_chg; 49 }; 50 51 enum max77843_muic_cable_group { 52 MAX77843_CABLE_GROUP_ADC = 0, 53 MAX77843_CABLE_GROUP_ADC_GND, 54 MAX77843_CABLE_GROUP_CHG, 55 }; 56 57 enum max77843_muic_adc_debounce_time { 58 MAX77843_DEBOUNCE_TIME_5MS = 0, 59 MAX77843_DEBOUNCE_TIME_10MS, 60 MAX77843_DEBOUNCE_TIME_25MS, 61 MAX77843_DEBOUNCE_TIME_38_62MS, 62 }; 63 64 /* Define accessory cable type */ 65 enum max77843_muic_accessory_type { 66 MAX77843_MUIC_ADC_GROUND = 0, 67 MAX77843_MUIC_ADC_SEND_END_BUTTON, 68 MAX77843_MUIC_ADC_REMOTE_S1_BUTTON, 69 MAX77843_MUIC_ADC_REMOTE_S2_BUTTON, 70 MAX77843_MUIC_ADC_REMOTE_S3_BUTTON, 71 MAX77843_MUIC_ADC_REMOTE_S4_BUTTON, 72 MAX77843_MUIC_ADC_REMOTE_S5_BUTTON, 73 MAX77843_MUIC_ADC_REMOTE_S6_BUTTON, 74 MAX77843_MUIC_ADC_REMOTE_S7_BUTTON, 75 MAX77843_MUIC_ADC_REMOTE_S8_BUTTON, 76 MAX77843_MUIC_ADC_REMOTE_S9_BUTTON, 77 MAX77843_MUIC_ADC_REMOTE_S10_BUTTON, 78 MAX77843_MUIC_ADC_REMOTE_S11_BUTTON, 79 MAX77843_MUIC_ADC_REMOTE_S12_BUTTON, 80 MAX77843_MUIC_ADC_RESERVED_ACC_1, 81 MAX77843_MUIC_ADC_RESERVED_ACC_2, 82 MAX77843_MUIC_ADC_RESERVED_ACC_3, 83 MAX77843_MUIC_ADC_RESERVED_ACC_4, 84 MAX77843_MUIC_ADC_RESERVED_ACC_5, 85 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2, 86 MAX77843_MUIC_ADC_PHONE_POWERED_DEV, 87 MAX77843_MUIC_ADC_TTY_CONVERTER, 88 MAX77843_MUIC_ADC_UART_CABLE, 89 MAX77843_MUIC_ADC_CEA936A_TYPE1_CHG, 90 MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF, 91 MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON, 92 MAX77843_MUIC_ADC_AV_CABLE_NOLOAD, 93 MAX77843_MUIC_ADC_CEA936A_TYPE2_CHG, 94 MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF, 95 MAX77843_MUIC_ADC_FACTORY_MODE_UART_ON, 96 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE1, 97 MAX77843_MUIC_ADC_OPEN, 98 99 /* The blow accessories should check 100 not only ADC value but also ADC1K and VBVolt value. */ 101 /* Offset|ADC1K|VBVolt| */ 102 MAX77843_MUIC_GND_USB_HOST = 0x100, /* 0x1| 0| 0| */ 103 MAX77843_MUIC_GND_USB_HOST_VB = 0x101, /* 0x1| 0| 1| */ 104 MAX77843_MUIC_GND_MHL = 0x102, /* 0x1| 1| 0| */ 105 MAX77843_MUIC_GND_MHL_VB = 0x103, /* 0x1| 1| 1| */ 106 }; 107 108 /* Define charger cable type */ 109 enum max77843_muic_charger_type { 110 MAX77843_MUIC_CHG_NONE = 0, 111 MAX77843_MUIC_CHG_USB, 112 MAX77843_MUIC_CHG_DOWNSTREAM, 113 MAX77843_MUIC_CHG_DEDICATED, 114 MAX77843_MUIC_CHG_SPECIAL_500MA, 115 MAX77843_MUIC_CHG_SPECIAL_1A, 116 MAX77843_MUIC_CHG_SPECIAL_BIAS, 117 MAX77843_MUIC_CHG_RESERVED, 118 MAX77843_MUIC_CHG_GND, 119 }; 120 121 enum { 122 MAX77843_CABLE_USB = 0, 123 MAX77843_CABLE_USB_HOST, 124 MAX77843_CABLE_TA, 125 MAX77843_CABLE_CHARGE_DOWNSTREAM, 126 MAX77843_CABLE_FAST_CHARGER, 127 MAX77843_CABLE_SLOW_CHARGER, 128 MAX77843_CABLE_MHL, 129 MAX77843_CABLE_MHL_TA, 130 MAX77843_CABLE_JIG_USB_ON, 131 MAX77843_CABLE_JIG_USB_OFF, 132 MAX77843_CABLE_JIG_UART_ON, 133 MAX77843_CABLE_JIG_UART_OFF, 134 135 MAX77843_CABLE_NUM, 136 }; 137 138 static const char *max77843_extcon_cable[] = { 139 [MAX77843_CABLE_USB] = "USB", 140 [MAX77843_CABLE_USB_HOST] = "USB-HOST", 141 [MAX77843_CABLE_TA] = "TA", 142 [MAX77843_CABLE_CHARGE_DOWNSTREAM] = "CHARGER-DOWNSTREAM", 143 [MAX77843_CABLE_FAST_CHARGER] = "FAST-CHARGER", 144 [MAX77843_CABLE_SLOW_CHARGER] = "SLOW-CHARGER", 145 [MAX77843_CABLE_MHL] = "MHL", 146 [MAX77843_CABLE_MHL_TA] = "MHL-TA", 147 [MAX77843_CABLE_JIG_USB_ON] = "JIG-USB-ON", 148 [MAX77843_CABLE_JIG_USB_OFF] = "JIG-USB-OFF", 149 [MAX77843_CABLE_JIG_UART_ON] = "JIG-UART-ON", 150 [MAX77843_CABLE_JIG_UART_OFF] = "JIG-UART-OFF", 151 }; 152 153 struct max77843_muic_irq { 154 unsigned int irq; 155 const char *name; 156 unsigned int virq; 157 }; 158 159 static struct max77843_muic_irq max77843_muic_irqs[] = { 160 { MAX77843_MUIC_IRQ_INT1_ADC, "MUIC-ADC" }, 161 { MAX77843_MUIC_IRQ_INT1_ADCERROR, "MUIC-ADC_ERROR" }, 162 { MAX77843_MUIC_IRQ_INT1_ADC1K, "MUIC-ADC1K" }, 163 { MAX77843_MUIC_IRQ_INT2_CHGTYP, "MUIC-CHGTYP" }, 164 { MAX77843_MUIC_IRQ_INT2_CHGDETRUN, "MUIC-CHGDETRUN" }, 165 { MAX77843_MUIC_IRQ_INT2_DCDTMR, "MUIC-DCDTMR" }, 166 { MAX77843_MUIC_IRQ_INT2_DXOVP, "MUIC-DXOVP" }, 167 { MAX77843_MUIC_IRQ_INT2_VBVOLT, "MUIC-VBVOLT" }, 168 { MAX77843_MUIC_IRQ_INT3_VBADC, "MUIC-VBADC" }, 169 { MAX77843_MUIC_IRQ_INT3_VDNMON, "MUIC-VDNMON" }, 170 { MAX77843_MUIC_IRQ_INT3_DNRES, "MUIC-DNRES" }, 171 { MAX77843_MUIC_IRQ_INT3_MPNACK, "MUIC-MPNACK"}, 172 { MAX77843_MUIC_IRQ_INT3_MRXBUFOW, "MUIC-MRXBUFOW"}, 173 { MAX77843_MUIC_IRQ_INT3_MRXTRF, "MUIC-MRXTRF"}, 174 { MAX77843_MUIC_IRQ_INT3_MRXPERR, "MUIC-MRXPERR"}, 175 { MAX77843_MUIC_IRQ_INT3_MRXRDY, "MUIC-MRXRDY"}, 176 }; 177 178 static const struct regmap_config max77843_muic_regmap_config = { 179 .reg_bits = 8, 180 .val_bits = 8, 181 .max_register = MAX77843_MUIC_REG_END, 182 }; 183 184 static const struct regmap_irq max77843_muic_irq[] = { 185 /* INT1 interrupt */ 186 { .reg_offset = 0, .mask = MAX77843_MUIC_ADC, }, 187 { .reg_offset = 0, .mask = MAX77843_MUIC_ADCERROR, }, 188 { .reg_offset = 0, .mask = MAX77843_MUIC_ADC1K, }, 189 190 /* INT2 interrupt */ 191 { .reg_offset = 1, .mask = MAX77843_MUIC_CHGTYP, }, 192 { .reg_offset = 1, .mask = MAX77843_MUIC_CHGDETRUN, }, 193 { .reg_offset = 1, .mask = MAX77843_MUIC_DCDTMR, }, 194 { .reg_offset = 1, .mask = MAX77843_MUIC_DXOVP, }, 195 { .reg_offset = 1, .mask = MAX77843_MUIC_VBVOLT, }, 196 197 /* INT3 interrupt */ 198 { .reg_offset = 2, .mask = MAX77843_MUIC_VBADC, }, 199 { .reg_offset = 2, .mask = MAX77843_MUIC_VDNMON, }, 200 { .reg_offset = 2, .mask = MAX77843_MUIC_DNRES, }, 201 { .reg_offset = 2, .mask = MAX77843_MUIC_MPNACK, }, 202 { .reg_offset = 2, .mask = MAX77843_MUIC_MRXBUFOW, }, 203 { .reg_offset = 2, .mask = MAX77843_MUIC_MRXTRF, }, 204 { .reg_offset = 2, .mask = MAX77843_MUIC_MRXPERR, }, 205 { .reg_offset = 2, .mask = MAX77843_MUIC_MRXRDY, }, 206 }; 207 208 static const struct regmap_irq_chip max77843_muic_irq_chip = { 209 .name = "max77843-muic", 210 .status_base = MAX77843_MUIC_REG_INT1, 211 .mask_base = MAX77843_MUIC_REG_INTMASK1, 212 .mask_invert = true, 213 .num_regs = 3, 214 .irqs = max77843_muic_irq, 215 .num_irqs = ARRAY_SIZE(max77843_muic_irq), 216 }; 217 218 static int max77843_muic_set_path(struct max77843_muic_info *info, 219 u8 val, bool attached) 220 { 221 struct max77843 *max77843 = info->max77843; 222 int ret = 0; 223 unsigned int ctrl1, ctrl2; 224 225 if (attached) 226 ctrl1 = val; 227 else 228 ctrl1 = CONTROL1_SW_OPEN; 229 230 ret = regmap_update_bits(max77843->regmap_muic, 231 MAX77843_MUIC_REG_CONTROL1, 232 CONTROL1_COM_SW, ctrl1); 233 if (ret < 0) { 234 dev_err(info->dev, "Cannot switch MUIC port\n"); 235 return ret; 236 } 237 238 if (attached) 239 ctrl2 = MAX77843_MUIC_CONTROL2_CPEN_MASK; 240 else 241 ctrl2 = MAX77843_MUIC_CONTROL2_LOWPWR_MASK; 242 243 ret = regmap_update_bits(max77843->regmap_muic, 244 MAX77843_MUIC_REG_CONTROL2, 245 MAX77843_MUIC_CONTROL2_LOWPWR_MASK | 246 MAX77843_MUIC_CONTROL2_CPEN_MASK, ctrl2); 247 if (ret < 0) { 248 dev_err(info->dev, "Cannot update lowpower mode\n"); 249 return ret; 250 } 251 252 dev_dbg(info->dev, 253 "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n", 254 ctrl1, ctrl2, attached ? "attached" : "detached"); 255 256 return 0; 257 } 258 259 static int max77843_muic_get_cable_type(struct max77843_muic_info *info, 260 enum max77843_muic_cable_group group, bool *attached) 261 { 262 int adc, chg_type, cable_type, gnd_type; 263 264 adc = info->status[MAX77843_MUIC_STATUS1] & 265 MAX77843_MUIC_STATUS1_ADC_MASK; 266 adc >>= STATUS1_ADC_SHIFT; 267 268 switch (group) { 269 case MAX77843_CABLE_GROUP_ADC: 270 if (adc == MAX77843_MUIC_ADC_OPEN) { 271 *attached = false; 272 cable_type = info->prev_cable_type; 273 info->prev_cable_type = MAX77843_MUIC_ADC_OPEN; 274 } else { 275 *attached = true; 276 cable_type = info->prev_cable_type = adc; 277 } 278 break; 279 case MAX77843_CABLE_GROUP_CHG: 280 chg_type = info->status[MAX77843_MUIC_STATUS2] & 281 MAX77843_MUIC_STATUS2_CHGTYP_MASK; 282 283 /* Check GROUND accessory with charger cable */ 284 if (adc == MAX77843_MUIC_ADC_GROUND) { 285 if (chg_type == MAX77843_MUIC_CHG_NONE) { 286 /* The following state when charger cable is 287 * disconnected but the GROUND accessory still 288 * connected */ 289 *attached = false; 290 cable_type = info->prev_chg_type; 291 info->prev_chg_type = MAX77843_MUIC_CHG_NONE; 292 } else { 293 294 /* The following state when charger cable is 295 * connected on the GROUND accessory */ 296 *attached = true; 297 cable_type = MAX77843_MUIC_CHG_GND; 298 info->prev_chg_type = MAX77843_MUIC_CHG_GND; 299 } 300 break; 301 } 302 303 if (chg_type == MAX77843_MUIC_CHG_NONE) { 304 *attached = false; 305 cable_type = info->prev_chg_type; 306 info->prev_chg_type = MAX77843_MUIC_CHG_NONE; 307 } else { 308 *attached = true; 309 cable_type = info->prev_chg_type = chg_type; 310 } 311 break; 312 case MAX77843_CABLE_GROUP_ADC_GND: 313 if (adc == MAX77843_MUIC_ADC_OPEN) { 314 *attached = false; 315 cable_type = info->prev_gnd_type; 316 info->prev_gnd_type = MAX77843_MUIC_ADC_OPEN; 317 } else { 318 *attached = true; 319 320 /* Offset|ADC1K|VBVolt| 321 * 0x1| 0| 0| USB-HOST 322 * 0x1| 0| 1| USB-HOST with VB 323 * 0x1| 1| 0| MHL 324 * 0x1| 1| 1| MHL with VB */ 325 /* Get ADC1K register bit */ 326 gnd_type = (info->status[MAX77843_MUIC_STATUS1] & 327 MAX77843_MUIC_STATUS1_ADC1K_MASK); 328 329 /* Get VBVolt register bit */ 330 gnd_type |= (info->status[MAX77843_MUIC_STATUS2] & 331 MAX77843_MUIC_STATUS2_VBVOLT_MASK); 332 gnd_type >>= STATUS2_VBVOLT_SHIFT; 333 334 /* Offset of GND cable */ 335 gnd_type |= MAX77843_MUIC_GND_USB_HOST; 336 cable_type = info->prev_gnd_type = gnd_type; 337 } 338 break; 339 default: 340 dev_err(info->dev, "Unknown cable group (%d)\n", group); 341 cable_type = -EINVAL; 342 break; 343 } 344 345 return cable_type; 346 } 347 348 static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) 349 { 350 int ret, gnd_cable_type; 351 bool attached; 352 353 gnd_cable_type = max77843_muic_get_cable_type(info, 354 MAX77843_CABLE_GROUP_ADC_GND, &attached); 355 dev_dbg(info->dev, "external connector is %s (gnd:0x%02x)\n", 356 attached ? "attached" : "detached", gnd_cable_type); 357 358 switch (gnd_cable_type) { 359 case MAX77843_MUIC_GND_USB_HOST: 360 case MAX77843_MUIC_GND_USB_HOST_VB: 361 ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); 362 if (ret < 0) 363 return ret; 364 365 extcon_set_cable_state(info->edev, "USB-HOST", attached); 366 break; 367 case MAX77843_MUIC_GND_MHL_VB: 368 case MAX77843_MUIC_GND_MHL: 369 ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 370 if (ret < 0) 371 return ret; 372 373 extcon_set_cable_state(info->edev, "MHL", attached); 374 break; 375 default: 376 dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n", 377 attached ? "attached" : "detached", gnd_cable_type); 378 return -EINVAL; 379 } 380 381 return 0; 382 } 383 384 static int max77843_muic_jig_handler(struct max77843_muic_info *info, 385 int cable_type, bool attached) 386 { 387 int ret; 388 389 dev_dbg(info->dev, "external connector is %s (adc:0x%02x)\n", 390 attached ? "attached" : "detached", cable_type); 391 392 switch (cable_type) { 393 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF: 394 ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); 395 if (ret < 0) 396 return ret; 397 extcon_set_cable_state(info->edev, "JIG-USB-OFF", attached); 398 break; 399 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON: 400 ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); 401 if (ret < 0) 402 return ret; 403 extcon_set_cable_state(info->edev, "JIG-USB-ON", attached); 404 break; 405 case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF: 406 ret = max77843_muic_set_path(info, CONTROL1_SW_UART, attached); 407 if (ret < 0) 408 return ret; 409 extcon_set_cable_state(info->edev, "JIG-UART-OFF", attached); 410 break; 411 default: 412 ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 413 if (ret < 0) 414 return ret; 415 break; 416 } 417 418 return 0; 419 } 420 421 static int max77843_muic_adc_handler(struct max77843_muic_info *info) 422 { 423 int ret, cable_type; 424 bool attached; 425 426 cable_type = max77843_muic_get_cable_type(info, 427 MAX77843_CABLE_GROUP_ADC, &attached); 428 429 dev_dbg(info->dev, 430 "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n", 431 attached ? "attached" : "detached", cable_type, 432 info->prev_cable_type); 433 434 switch (cable_type) { 435 case MAX77843_MUIC_ADC_GROUND: 436 ret = max77843_muic_adc_gnd_handler(info); 437 if (ret < 0) 438 return ret; 439 break; 440 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF: 441 case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON: 442 case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF: 443 ret = max77843_muic_jig_handler(info, cable_type, attached); 444 if (ret < 0) 445 return ret; 446 break; 447 case MAX77843_MUIC_ADC_SEND_END_BUTTON: 448 case MAX77843_MUIC_ADC_REMOTE_S1_BUTTON: 449 case MAX77843_MUIC_ADC_REMOTE_S2_BUTTON: 450 case MAX77843_MUIC_ADC_REMOTE_S3_BUTTON: 451 case MAX77843_MUIC_ADC_REMOTE_S4_BUTTON: 452 case MAX77843_MUIC_ADC_REMOTE_S5_BUTTON: 453 case MAX77843_MUIC_ADC_REMOTE_S6_BUTTON: 454 case MAX77843_MUIC_ADC_REMOTE_S7_BUTTON: 455 case MAX77843_MUIC_ADC_REMOTE_S8_BUTTON: 456 case MAX77843_MUIC_ADC_REMOTE_S9_BUTTON: 457 case MAX77843_MUIC_ADC_REMOTE_S10_BUTTON: 458 case MAX77843_MUIC_ADC_REMOTE_S11_BUTTON: 459 case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON: 460 case MAX77843_MUIC_ADC_RESERVED_ACC_1: 461 case MAX77843_MUIC_ADC_RESERVED_ACC_2: 462 case MAX77843_MUIC_ADC_RESERVED_ACC_3: 463 case MAX77843_MUIC_ADC_RESERVED_ACC_4: 464 case MAX77843_MUIC_ADC_RESERVED_ACC_5: 465 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2: 466 case MAX77843_MUIC_ADC_PHONE_POWERED_DEV: 467 case MAX77843_MUIC_ADC_TTY_CONVERTER: 468 case MAX77843_MUIC_ADC_UART_CABLE: 469 case MAX77843_MUIC_ADC_CEA936A_TYPE1_CHG: 470 case MAX77843_MUIC_ADC_AV_CABLE_NOLOAD: 471 case MAX77843_MUIC_ADC_CEA936A_TYPE2_CHG: 472 case MAX77843_MUIC_ADC_FACTORY_MODE_UART_ON: 473 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE1: 474 case MAX77843_MUIC_ADC_OPEN: 475 dev_err(info->dev, 476 "accessory is %s but it isn't used (adc:0x%x)\n", 477 attached ? "attached" : "detached", cable_type); 478 return -EAGAIN; 479 default: 480 dev_err(info->dev, 481 "failed to detect %s accessory (adc:0x%x)\n", 482 attached ? "attached" : "detached", cable_type); 483 return -EINVAL; 484 } 485 486 return 0; 487 } 488 489 static int max77843_muic_chg_handler(struct max77843_muic_info *info) 490 { 491 int ret, chg_type, gnd_type; 492 bool attached; 493 494 chg_type = max77843_muic_get_cable_type(info, 495 MAX77843_CABLE_GROUP_CHG, &attached); 496 497 dev_dbg(info->dev, 498 "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n", 499 attached ? "attached" : "detached", 500 chg_type, info->prev_chg_type); 501 502 switch (chg_type) { 503 case MAX77843_MUIC_CHG_USB: 504 ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); 505 if (ret < 0) 506 return ret; 507 508 extcon_set_cable_state(info->edev, "USB", attached); 509 break; 510 case MAX77843_MUIC_CHG_DOWNSTREAM: 511 ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 512 if (ret < 0) 513 return ret; 514 515 extcon_set_cable_state(info->edev, 516 "CHARGER-DOWNSTREAM", attached); 517 break; 518 case MAX77843_MUIC_CHG_DEDICATED: 519 ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 520 if (ret < 0) 521 return ret; 522 523 extcon_set_cable_state(info->edev, "TA", attached); 524 break; 525 case MAX77843_MUIC_CHG_SPECIAL_500MA: 526 ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 527 if (ret < 0) 528 return ret; 529 530 extcon_set_cable_state(info->edev, "SLOW-CHAREGER", attached); 531 break; 532 case MAX77843_MUIC_CHG_SPECIAL_1A: 533 ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 534 if (ret < 0) 535 return ret; 536 537 extcon_set_cable_state(info->edev, "FAST-CHARGER", attached); 538 break; 539 case MAX77843_MUIC_CHG_GND: 540 gnd_type = max77843_muic_get_cable_type(info, 541 MAX77843_CABLE_GROUP_ADC_GND, &attached); 542 543 /* Charger cable on MHL accessory is attach or detach */ 544 if (gnd_type == MAX77843_MUIC_GND_MHL_VB) 545 extcon_set_cable_state(info->edev, "MHL-TA", true); 546 else if (gnd_type == MAX77843_MUIC_GND_MHL) 547 extcon_set_cable_state(info->edev, "MHL-TA", false); 548 break; 549 case MAX77843_MUIC_CHG_NONE: 550 break; 551 default: 552 dev_err(info->dev, 553 "failed to detect %s accessory (chg_type:0x%x)\n", 554 attached ? "attached" : "detached", chg_type); 555 556 max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); 557 return -EINVAL; 558 } 559 560 return 0; 561 } 562 563 static void max77843_muic_irq_work(struct work_struct *work) 564 { 565 struct max77843_muic_info *info = container_of(work, 566 struct max77843_muic_info, irq_work); 567 struct max77843 *max77843 = info->max77843; 568 int ret = 0; 569 570 mutex_lock(&info->mutex); 571 572 ret = regmap_bulk_read(max77843->regmap_muic, 573 MAX77843_MUIC_REG_STATUS1, info->status, 574 MAX77843_MUIC_STATUS_NUM); 575 if (ret) { 576 dev_err(info->dev, "Cannot read STATUS registers\n"); 577 mutex_unlock(&info->mutex); 578 return; 579 } 580 581 if (info->irq_adc) { 582 ret = max77843_muic_adc_handler(info); 583 if (ret) 584 dev_err(info->dev, "Unknown cable type\n"); 585 info->irq_adc = false; 586 } 587 588 if (info->irq_chg) { 589 ret = max77843_muic_chg_handler(info); 590 if (ret) 591 dev_err(info->dev, "Unknown charger type\n"); 592 info->irq_chg = false; 593 } 594 595 mutex_unlock(&info->mutex); 596 } 597 598 static irqreturn_t max77843_muic_irq_handler(int irq, void *data) 599 { 600 struct max77843_muic_info *info = data; 601 int i, irq_type = -1; 602 603 for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++) 604 if (irq == max77843_muic_irqs[i].virq) 605 irq_type = max77843_muic_irqs[i].irq; 606 607 switch (irq_type) { 608 case MAX77843_MUIC_IRQ_INT1_ADC: 609 case MAX77843_MUIC_IRQ_INT1_ADCERROR: 610 case MAX77843_MUIC_IRQ_INT1_ADC1K: 611 info->irq_adc = true; 612 break; 613 case MAX77843_MUIC_IRQ_INT2_CHGTYP: 614 case MAX77843_MUIC_IRQ_INT2_CHGDETRUN: 615 case MAX77843_MUIC_IRQ_INT2_DCDTMR: 616 case MAX77843_MUIC_IRQ_INT2_DXOVP: 617 case MAX77843_MUIC_IRQ_INT2_VBVOLT: 618 info->irq_chg = true; 619 break; 620 case MAX77843_MUIC_IRQ_INT3_VBADC: 621 case MAX77843_MUIC_IRQ_INT3_VDNMON: 622 case MAX77843_MUIC_IRQ_INT3_DNRES: 623 case MAX77843_MUIC_IRQ_INT3_MPNACK: 624 case MAX77843_MUIC_IRQ_INT3_MRXBUFOW: 625 case MAX77843_MUIC_IRQ_INT3_MRXTRF: 626 case MAX77843_MUIC_IRQ_INT3_MRXPERR: 627 case MAX77843_MUIC_IRQ_INT3_MRXRDY: 628 break; 629 default: 630 dev_err(info->dev, "Cannot recognize IRQ(%d)\n", irq_type); 631 break; 632 } 633 634 schedule_work(&info->irq_work); 635 636 return IRQ_HANDLED; 637 } 638 639 static void max77843_muic_detect_cable_wq(struct work_struct *work) 640 { 641 struct max77843_muic_info *info = container_of(to_delayed_work(work), 642 struct max77843_muic_info, wq_detcable); 643 struct max77843 *max77843 = info->max77843; 644 int chg_type, adc, ret; 645 bool attached; 646 647 mutex_lock(&info->mutex); 648 649 ret = regmap_bulk_read(max77843->regmap_muic, 650 MAX77843_MUIC_REG_STATUS1, info->status, 651 MAX77843_MUIC_STATUS_NUM); 652 if (ret) { 653 dev_err(info->dev, "Cannot read STATUS registers\n"); 654 goto err_cable_wq; 655 } 656 657 adc = max77843_muic_get_cable_type(info, 658 MAX77843_CABLE_GROUP_ADC, &attached); 659 if (attached && adc != MAX77843_MUIC_ADC_OPEN) { 660 ret = max77843_muic_adc_handler(info); 661 if (ret < 0) { 662 dev_err(info->dev, "Cannot detect accessory\n"); 663 goto err_cable_wq; 664 } 665 } 666 667 chg_type = max77843_muic_get_cable_type(info, 668 MAX77843_CABLE_GROUP_CHG, &attached); 669 if (attached && chg_type != MAX77843_MUIC_CHG_NONE) { 670 ret = max77843_muic_chg_handler(info); 671 if (ret < 0) { 672 dev_err(info->dev, "Cannot detect charger accessory\n"); 673 goto err_cable_wq; 674 } 675 } 676 677 err_cable_wq: 678 mutex_unlock(&info->mutex); 679 } 680 681 static int max77843_muic_set_debounce_time(struct max77843_muic_info *info, 682 enum max77843_muic_adc_debounce_time time) 683 { 684 struct max77843 *max77843 = info->max77843; 685 int ret; 686 687 switch (time) { 688 case MAX77843_DEBOUNCE_TIME_5MS: 689 case MAX77843_DEBOUNCE_TIME_10MS: 690 case MAX77843_DEBOUNCE_TIME_25MS: 691 case MAX77843_DEBOUNCE_TIME_38_62MS: 692 ret = regmap_update_bits(max77843->regmap_muic, 693 MAX77843_MUIC_REG_CONTROL4, 694 MAX77843_MUIC_CONTROL4_ADCDBSET_MASK, 695 time << CONTROL4_ADCDBSET_SHIFT); 696 if (ret < 0) { 697 dev_err(info->dev, "Cannot write MUIC regmap\n"); 698 return ret; 699 } 700 break; 701 default: 702 dev_err(info->dev, "Invalid ADC debounce time\n"); 703 return -EINVAL; 704 } 705 706 return 0; 707 } 708 709 static int max77843_init_muic_regmap(struct max77843 *max77843) 710 { 711 int ret; 712 713 max77843->i2c_muic = i2c_new_dummy(max77843->i2c->adapter, 714 I2C_ADDR_MUIC); 715 if (!max77843->i2c_muic) { 716 dev_err(&max77843->i2c->dev, 717 "Cannot allocate I2C device for MUIC\n"); 718 return -ENOMEM; 719 } 720 721 i2c_set_clientdata(max77843->i2c_muic, max77843); 722 723 max77843->regmap_muic = devm_regmap_init_i2c(max77843->i2c_muic, 724 &max77843_muic_regmap_config); 725 if (IS_ERR(max77843->regmap_muic)) { 726 ret = PTR_ERR(max77843->regmap_muic); 727 goto err_muic_i2c; 728 } 729 730 ret = regmap_add_irq_chip(max77843->regmap_muic, max77843->irq, 731 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 732 0, &max77843_muic_irq_chip, &max77843->irq_data_muic); 733 if (ret < 0) { 734 dev_err(&max77843->i2c->dev, "Cannot add MUIC IRQ chip\n"); 735 goto err_muic_i2c; 736 } 737 738 return 0; 739 740 err_muic_i2c: 741 i2c_unregister_device(max77843->i2c_muic); 742 743 return ret; 744 } 745 746 static int max77843_muic_probe(struct platform_device *pdev) 747 { 748 struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent); 749 struct max77843_muic_info *info; 750 unsigned int id; 751 int i, ret; 752 753 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 754 if (!info) 755 return -ENOMEM; 756 757 info->dev = &pdev->dev; 758 info->max77843 = max77843; 759 760 platform_set_drvdata(pdev, info); 761 mutex_init(&info->mutex); 762 763 /* Initialize i2c and regmap */ 764 ret = max77843_init_muic_regmap(max77843); 765 if (ret) { 766 dev_err(&pdev->dev, "Failed to init MUIC regmap\n"); 767 return ret; 768 } 769 770 /* Turn off auto detection configuration */ 771 ret = regmap_update_bits(max77843->regmap_muic, 772 MAX77843_MUIC_REG_CONTROL4, 773 MAX77843_MUIC_CONTROL4_USBAUTO_MASK | 774 MAX77843_MUIC_CONTROL4_FCTAUTO_MASK, 775 CONTROL4_AUTO_DISABLE); 776 777 /* Initialize extcon device */ 778 info->edev = devm_extcon_dev_allocate(&pdev->dev, 779 max77843_extcon_cable); 780 if (IS_ERR(info->edev)) { 781 dev_err(&pdev->dev, "Failed to allocate memory for extcon\n"); 782 ret = -ENODEV; 783 goto err_muic_irq; 784 } 785 786 ret = devm_extcon_dev_register(&pdev->dev, info->edev); 787 if (ret) { 788 dev_err(&pdev->dev, "Failed to register extcon device\n"); 789 goto err_muic_irq; 790 } 791 792 /* Set ADC debounce time */ 793 max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS); 794 795 /* Set initial path for UART */ 796 max77843_muic_set_path(info, CONTROL1_SW_UART, true); 797 798 /* Check revision number of MUIC device */ 799 ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id); 800 if (ret < 0) { 801 dev_err(&pdev->dev, "Failed to read revision number\n"); 802 goto err_muic_irq; 803 } 804 dev_info(info->dev, "MUIC device ID : 0x%x\n", id); 805 806 /* Support virtual irq domain for max77843 MUIC device */ 807 INIT_WORK(&info->irq_work, max77843_muic_irq_work); 808 809 for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++) { 810 struct max77843_muic_irq *muic_irq = &max77843_muic_irqs[i]; 811 unsigned int virq = 0; 812 813 virq = regmap_irq_get_virq(max77843->irq_data_muic, 814 muic_irq->irq); 815 if (virq <= 0) { 816 ret = -EINVAL; 817 goto err_muic_irq; 818 } 819 muic_irq->virq = virq; 820 821 ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, 822 max77843_muic_irq_handler, IRQF_NO_SUSPEND, 823 muic_irq->name, info); 824 if (ret) { 825 dev_err(&pdev->dev, 826 "Failed to request irq (IRQ: %d, error: %d)\n", 827 muic_irq->irq, ret); 828 goto err_muic_irq; 829 } 830 } 831 832 /* Detect accessory after completing the initialization of platform */ 833 INIT_DELAYED_WORK(&info->wq_detcable, max77843_muic_detect_cable_wq); 834 queue_delayed_work(system_power_efficient_wq, 835 &info->wq_detcable, msecs_to_jiffies(DELAY_MS_DEFAULT)); 836 837 return 0; 838 839 err_muic_irq: 840 regmap_del_irq_chip(max77843->irq, max77843->irq_data_muic); 841 i2c_unregister_device(max77843->i2c_muic); 842 843 return ret; 844 } 845 846 static int max77843_muic_remove(struct platform_device *pdev) 847 { 848 struct max77843_muic_info *info = platform_get_drvdata(pdev); 849 struct max77843 *max77843 = info->max77843; 850 851 cancel_work_sync(&info->irq_work); 852 regmap_del_irq_chip(max77843->irq, max77843->irq_data_muic); 853 i2c_unregister_device(max77843->i2c_muic); 854 855 return 0; 856 } 857 858 static const struct platform_device_id max77843_muic_id[] = { 859 { "max77843-muic", }, 860 { /* sentinel */ }, 861 }; 862 MODULE_DEVICE_TABLE(platform, max77843_muic_id); 863 864 static struct platform_driver max77843_muic_driver = { 865 .driver = { 866 .name = "max77843-muic", 867 }, 868 .probe = max77843_muic_probe, 869 .remove = max77843_muic_remove, 870 .id_table = max77843_muic_id, 871 }; 872 873 static int __init max77843_muic_init(void) 874 { 875 return platform_driver_register(&max77843_muic_driver); 876 } 877 subsys_initcall(max77843_muic_init); 878 879 MODULE_DESCRIPTION("Maxim MAX77843 Extcon driver"); 880 MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>"); 881 MODULE_LICENSE("GPL"); 882