aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2017-10-18 05:56:22 -0400
committerChanwoo Choi <cw00.choi@samsung.com>2017-10-23 20:48:54 -0400
commit4a4a87146a07c866ad2ef49cc32296e6583b1cee (patch)
tree4cb7513869c7550a4772db6d622458eea1b80b5a /drivers/extcon
parent7b9651103b64c8a55eb6cec4c2240584e968354c (diff)
extcon: max77843: Add support for SmartDock accessory
SmartDock uses ADC_RESERVED_ACC_3 (0x10) ADC ID type and provides following features: 1. USB host with embedded USB hub (2-4 ports) for mice, keyboard, etc, 2. MHL for video output, 3. charging. Tested with Unitek Y-2165 MHL+OTG Hub Smart Phone Dock. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Chanwoo Choi <cw00.choi@samsung.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/extcon-max77843.c77
1 files changed, 63 insertions, 14 deletions
diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c
index 17d6bd76edb4..c9fcd6cd41cb 100644
--- a/drivers/extcon/extcon-max77843.c
+++ b/drivers/extcon/extcon-max77843.c
@@ -80,7 +80,7 @@ enum max77843_muic_accessory_type {
80 MAX77843_MUIC_ADC_REMOTE_S12_BUTTON, 80 MAX77843_MUIC_ADC_REMOTE_S12_BUTTON,
81 MAX77843_MUIC_ADC_RESERVED_ACC_1, 81 MAX77843_MUIC_ADC_RESERVED_ACC_1,
82 MAX77843_MUIC_ADC_RESERVED_ACC_2, 82 MAX77843_MUIC_ADC_RESERVED_ACC_2,
83 MAX77843_MUIC_ADC_RESERVED_ACC_3, 83 MAX77843_MUIC_ADC_RESERVED_ACC_3, /* SmartDock */
84 MAX77843_MUIC_ADC_RESERVED_ACC_4, 84 MAX77843_MUIC_ADC_RESERVED_ACC_4,
85 MAX77843_MUIC_ADC_RESERVED_ACC_5, 85 MAX77843_MUIC_ADC_RESERVED_ACC_5,
86 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2, 86 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2,
@@ -119,6 +119,7 @@ enum max77843_muic_charger_type {
119 MAX77843_MUIC_CHG_SPECIAL_BIAS, 119 MAX77843_MUIC_CHG_SPECIAL_BIAS,
120 MAX77843_MUIC_CHG_RESERVED, 120 MAX77843_MUIC_CHG_RESERVED,
121 MAX77843_MUIC_CHG_GND, 121 MAX77843_MUIC_CHG_GND,
122 MAX77843_MUIC_CHG_DOCK,
122}; 123};
123 124
124static const unsigned int max77843_extcon_cable[] = { 125static const unsigned int max77843_extcon_cable[] = {
@@ -130,6 +131,7 @@ static const unsigned int max77843_extcon_cable[] = {
130 EXTCON_CHG_USB_FAST, 131 EXTCON_CHG_USB_FAST,
131 EXTCON_CHG_USB_SLOW, 132 EXTCON_CHG_USB_SLOW,
132 EXTCON_DISP_MHL, 133 EXTCON_DISP_MHL,
134 EXTCON_DOCK,
133 EXTCON_JIG, 135 EXTCON_JIG,
134 EXTCON_NONE, 136 EXTCON_NONE,
135}; 137};
@@ -200,7 +202,7 @@ static const struct regmap_irq_chip max77843_muic_irq_chip = {
200}; 202};
201 203
202static int max77843_muic_set_path(struct max77843_muic_info *info, 204static int max77843_muic_set_path(struct max77843_muic_info *info,
203 u8 val, bool attached) 205 u8 val, bool attached, bool nobccomp)
204{ 206{
205 struct max77693_dev *max77843 = info->max77843; 207 struct max77693_dev *max77843 = info->max77843;
206 int ret = 0; 208 int ret = 0;
@@ -210,10 +212,16 @@ static int max77843_muic_set_path(struct max77843_muic_info *info,
210 ctrl1 = val; 212 ctrl1 = val;
211 else 213 else
212 ctrl1 = MAX77843_MUIC_CONTROL1_SW_OPEN; 214 ctrl1 = MAX77843_MUIC_CONTROL1_SW_OPEN;
215 if (nobccomp) {
216 /* Disable BC1.2 protocol and force manual switch control */
217 ctrl1 |= MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK;
218 }
213 219
214 ret = regmap_update_bits(max77843->regmap_muic, 220 ret = regmap_update_bits(max77843->regmap_muic,
215 MAX77843_MUIC_REG_CONTROL1, 221 MAX77843_MUIC_REG_CONTROL1,
216 MAX77843_MUIC_CONTROL1_COM_SW, ctrl1); 222 MAX77843_MUIC_CONTROL1_COM_SW |
223 MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK,
224 ctrl1);
217 if (ret < 0) { 225 if (ret < 0) {
218 dev_err(info->dev, "Cannot switch MUIC port\n"); 226 dev_err(info->dev, "Cannot switch MUIC port\n");
219 return ret; 227 return ret;
@@ -303,6 +311,19 @@ static int max77843_muic_get_cable_type(struct max77843_muic_info *info,
303 break; 311 break;
304 } 312 }
305 313
314 if (adc == MAX77843_MUIC_ADC_RESERVED_ACC_3) { /* SmartDock */
315 if (chg_type == MAX77843_MUIC_CHG_NONE) {
316 *attached = false;
317 cable_type = info->prev_chg_type;
318 info->prev_chg_type = MAX77843_MUIC_CHG_NONE;
319 } else {
320 *attached = true;
321 cable_type = MAX77843_MUIC_CHG_DOCK;
322 info->prev_chg_type = MAX77843_MUIC_CHG_DOCK;
323 }
324 break;
325 }
326
306 if (chg_type == MAX77843_MUIC_CHG_NONE) { 327 if (chg_type == MAX77843_MUIC_CHG_NONE) {
307 *attached = false; 328 *attached = false;
308 cable_type = info->prev_chg_type; 329 cable_type = info->prev_chg_type;
@@ -365,7 +386,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
365 case MAX77843_MUIC_GND_USB_HOST_VB: 386 case MAX77843_MUIC_GND_USB_HOST_VB:
366 ret = max77843_muic_set_path(info, 387 ret = max77843_muic_set_path(info,
367 MAX77843_MUIC_CONTROL1_SW_USB, 388 MAX77843_MUIC_CONTROL1_SW_USB,
368 attached); 389 attached, false);
369 if (ret < 0) 390 if (ret < 0)
370 return ret; 391 return ret;
371 392
@@ -376,7 +397,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
376 case MAX77843_MUIC_GND_MHL: 397 case MAX77843_MUIC_GND_MHL:
377 ret = max77843_muic_set_path(info, 398 ret = max77843_muic_set_path(info,
378 MAX77843_MUIC_CONTROL1_SW_OPEN, 399 MAX77843_MUIC_CONTROL1_SW_OPEN,
379 attached); 400 attached, false);
380 if (ret < 0) 401 if (ret < 0)
381 return ret; 402 return ret;
382 403
@@ -412,7 +433,7 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info,
412 return -EINVAL; 433 return -EINVAL;
413 } 434 }
414 435
415 ret = max77843_muic_set_path(info, path, attached); 436 ret = max77843_muic_set_path(info, path, attached, false);
416 if (ret < 0) 437 if (ret < 0)
417 return ret; 438 return ret;
418 439
@@ -421,6 +442,26 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info,
421 return 0; 442 return 0;
422} 443}
423 444
445static int max77843_muic_dock_handler(struct max77843_muic_info *info,
446 bool attached)
447{
448 int ret;
449
450 dev_dbg(info->dev, "external connector is %s (adc: 0x10)\n",
451 attached ? "attached" : "detached");
452
453 ret = max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_USB,
454 attached, attached);
455 if (ret < 0)
456 return ret;
457
458 extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);
459 extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached);
460 extcon_set_state_sync(info->edev, EXTCON_DOCK, attached);
461
462 return 0;
463}
464
424static int max77843_muic_adc_handler(struct max77843_muic_info *info) 465static int max77843_muic_adc_handler(struct max77843_muic_info *info)
425{ 466{
426 int ret, cable_type; 467 int ret, cable_type;
@@ -435,6 +476,11 @@ static int max77843_muic_adc_handler(struct max77843_muic_info *info)
435 info->prev_cable_type); 476 info->prev_cable_type);
436 477
437 switch (cable_type) { 478 switch (cable_type) {
479 case MAX77843_MUIC_ADC_RESERVED_ACC_3: /* SmartDock */
480 ret = max77843_muic_dock_handler(info, attached);
481 if (ret < 0)
482 return ret;
483 break;
438 case MAX77843_MUIC_ADC_GROUND: 484 case MAX77843_MUIC_ADC_GROUND:
439 ret = max77843_muic_adc_gnd_handler(info); 485 ret = max77843_muic_adc_gnd_handler(info);
440 if (ret < 0) 486 if (ret < 0)
@@ -462,7 +508,6 @@ static int max77843_muic_adc_handler(struct max77843_muic_info *info)
462 case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON: 508 case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON:
463 case MAX77843_MUIC_ADC_RESERVED_ACC_1: 509 case MAX77843_MUIC_ADC_RESERVED_ACC_1:
464 case MAX77843_MUIC_ADC_RESERVED_ACC_2: 510 case MAX77843_MUIC_ADC_RESERVED_ACC_2:
465 case MAX77843_MUIC_ADC_RESERVED_ACC_3:
466 case MAX77843_MUIC_ADC_RESERVED_ACC_4: 511 case MAX77843_MUIC_ADC_RESERVED_ACC_4:
467 case MAX77843_MUIC_ADC_RESERVED_ACC_5: 512 case MAX77843_MUIC_ADC_RESERVED_ACC_5:
468 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2: 513 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2:
@@ -506,7 +551,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
506 case MAX77843_MUIC_CHG_USB: 551 case MAX77843_MUIC_CHG_USB:
507 ret = max77843_muic_set_path(info, 552 ret = max77843_muic_set_path(info,
508 MAX77843_MUIC_CONTROL1_SW_USB, 553 MAX77843_MUIC_CONTROL1_SW_USB,
509 attached); 554 attached, false);
510 if (ret < 0) 555 if (ret < 0)
511 return ret; 556 return ret;
512 557
@@ -517,7 +562,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
517 case MAX77843_MUIC_CHG_DOWNSTREAM: 562 case MAX77843_MUIC_CHG_DOWNSTREAM:
518 ret = max77843_muic_set_path(info, 563 ret = max77843_muic_set_path(info,
519 MAX77843_MUIC_CONTROL1_SW_OPEN, 564 MAX77843_MUIC_CONTROL1_SW_OPEN,
520 attached); 565 attached, false);
521 if (ret < 0) 566 if (ret < 0)
522 return ret; 567 return ret;
523 568
@@ -527,7 +572,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
527 case MAX77843_MUIC_CHG_DEDICATED: 572 case MAX77843_MUIC_CHG_DEDICATED:
528 ret = max77843_muic_set_path(info, 573 ret = max77843_muic_set_path(info,
529 MAX77843_MUIC_CONTROL1_SW_OPEN, 574 MAX77843_MUIC_CONTROL1_SW_OPEN,
530 attached); 575 attached, false);
531 if (ret < 0) 576 if (ret < 0)
532 return ret; 577 return ret;
533 578
@@ -537,7 +582,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
537 case MAX77843_MUIC_CHG_SPECIAL_500MA: 582 case MAX77843_MUIC_CHG_SPECIAL_500MA:
538 ret = max77843_muic_set_path(info, 583 ret = max77843_muic_set_path(info,
539 MAX77843_MUIC_CONTROL1_SW_OPEN, 584 MAX77843_MUIC_CONTROL1_SW_OPEN,
540 attached); 585 attached, false);
541 if (ret < 0) 586 if (ret < 0)
542 return ret; 587 return ret;
543 588
@@ -547,7 +592,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
547 case MAX77843_MUIC_CHG_SPECIAL_1A: 592 case MAX77843_MUIC_CHG_SPECIAL_1A:
548 ret = max77843_muic_set_path(info, 593 ret = max77843_muic_set_path(info,
549 MAX77843_MUIC_CONTROL1_SW_OPEN, 594 MAX77843_MUIC_CONTROL1_SW_OPEN,
550 attached); 595 attached, false);
551 if (ret < 0) 596 if (ret < 0)
552 return ret; 597 return ret;
553 598
@@ -566,6 +611,9 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
566 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, 611 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
567 false); 612 false);
568 break; 613 break;
614 case MAX77843_MUIC_CHG_DOCK:
615 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, attached);
616 break;
569 case MAX77843_MUIC_CHG_NONE: 617 case MAX77843_MUIC_CHG_NONE:
570 break; 618 break;
571 default: 619 default:
@@ -574,7 +622,7 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
574 attached ? "attached" : "detached", chg_type); 622 attached ? "attached" : "detached", chg_type);
575 623
576 max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_OPEN, 624 max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_OPEN,
577 attached); 625 attached, false);
578 return -EINVAL; 626 return -EINVAL;
579 } 627 }
580 628
@@ -814,7 +862,8 @@ static int max77843_muic_probe(struct platform_device *pdev)
814 max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS); 862 max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS);
815 863
816 /* Set initial path for UART */ 864 /* Set initial path for UART */
817 max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART, true); 865 max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART, true,
866 false);
818 867
819 /* Check revision number of MUIC device */ 868 /* Check revision number of MUIC device */
820 ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id); 869 ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id);