diff options
| author | Marek Szyprowski <m.szyprowski@samsung.com> | 2017-10-18 05:56:22 -0400 |
|---|---|---|
| committer | Chanwoo Choi <cw00.choi@samsung.com> | 2017-10-23 20:48:54 -0400 |
| commit | 4a4a87146a07c866ad2ef49cc32296e6583b1cee (patch) | |
| tree | 4cb7513869c7550a4772db6d622458eea1b80b5a /drivers/extcon | |
| parent | 7b9651103b64c8a55eb6cec4c2240584e968354c (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.c | 77 |
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 | ||
| 124 | static const unsigned int max77843_extcon_cable[] = { | 125 | static 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 | ||
| 202 | static int max77843_muic_set_path(struct max77843_muic_info *info, | 204 | static 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 | ||
| 445 | static 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 | |||
| 424 | static int max77843_muic_adc_handler(struct max77843_muic_info *info) | 465 | static 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); |
