Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Marek Szyprowski and committed by
Chanwoo Choi
4a4a8714 7b965110

+65 -14
+63 -14
drivers/extcon/extcon-max77843.c
··· 80 80 MAX77843_MUIC_ADC_REMOTE_S12_BUTTON, 81 81 MAX77843_MUIC_ADC_RESERVED_ACC_1, 82 82 MAX77843_MUIC_ADC_RESERVED_ACC_2, 83 - MAX77843_MUIC_ADC_RESERVED_ACC_3, 83 + MAX77843_MUIC_ADC_RESERVED_ACC_3, /* SmartDock */ 84 84 MAX77843_MUIC_ADC_RESERVED_ACC_4, 85 85 MAX77843_MUIC_ADC_RESERVED_ACC_5, 86 86 MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2, ··· 119 119 MAX77843_MUIC_CHG_SPECIAL_BIAS, 120 120 MAX77843_MUIC_CHG_RESERVED, 121 121 MAX77843_MUIC_CHG_GND, 122 + MAX77843_MUIC_CHG_DOCK, 122 123 }; 123 124 124 125 static const unsigned int max77843_extcon_cable[] = { ··· 131 130 EXTCON_CHG_USB_FAST, 132 131 EXTCON_CHG_USB_SLOW, 133 132 EXTCON_DISP_MHL, 133 + EXTCON_DOCK, 134 134 EXTCON_JIG, 135 135 EXTCON_NONE, 136 136 }; ··· 202 200 }; 203 201 204 202 static int max77843_muic_set_path(struct max77843_muic_info *info, 205 - u8 val, bool attached) 203 + u8 val, bool attached, bool nobccomp) 206 204 { 207 205 struct max77693_dev *max77843 = info->max77843; 208 206 int ret = 0; ··· 212 210 ctrl1 = val; 213 211 else 214 212 ctrl1 = MAX77843_MUIC_CONTROL1_SW_OPEN; 213 + if (nobccomp) { 214 + /* Disable BC1.2 protocol and force manual switch control */ 215 + ctrl1 |= MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK; 216 + } 215 217 216 218 ret = regmap_update_bits(max77843->regmap_muic, 217 219 MAX77843_MUIC_REG_CONTROL1, 218 - MAX77843_MUIC_CONTROL1_COM_SW, ctrl1); 220 + MAX77843_MUIC_CONTROL1_COM_SW | 221 + MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK, 222 + ctrl1); 219 223 if (ret < 0) { 220 224 dev_err(info->dev, "Cannot switch MUIC port\n"); 221 225 return ret; ··· 311 303 break; 312 304 } 313 305 306 + if (adc == MAX77843_MUIC_ADC_RESERVED_ACC_3) { /* SmartDock */ 307 + if (chg_type == MAX77843_MUIC_CHG_NONE) { 308 + *attached = false; 309 + cable_type = info->prev_chg_type; 310 + info->prev_chg_type = MAX77843_MUIC_CHG_NONE; 311 + } else { 312 + *attached = true; 313 + cable_type = MAX77843_MUIC_CHG_DOCK; 314 + info->prev_chg_type = MAX77843_MUIC_CHG_DOCK; 315 + } 316 + break; 317 + } 318 + 314 319 if (chg_type == MAX77843_MUIC_CHG_NONE) { 315 320 *attached = false; 316 321 cable_type = info->prev_chg_type; ··· 386 365 case MAX77843_MUIC_GND_USB_HOST_VB: 387 366 ret = max77843_muic_set_path(info, 388 367 MAX77843_MUIC_CONTROL1_SW_USB, 389 - attached); 368 + attached, false); 390 369 if (ret < 0) 391 370 return ret; 392 371 ··· 397 376 case MAX77843_MUIC_GND_MHL: 398 377 ret = max77843_muic_set_path(info, 399 378 MAX77843_MUIC_CONTROL1_SW_OPEN, 400 - attached); 379 + attached, false); 401 380 if (ret < 0) 402 381 return ret; 403 382 ··· 433 412 return -EINVAL; 434 413 } 435 414 436 - ret = max77843_muic_set_path(info, path, attached); 415 + ret = max77843_muic_set_path(info, path, attached, false); 437 416 if (ret < 0) 438 417 return ret; 439 418 440 419 extcon_set_state_sync(info->edev, EXTCON_JIG, attached); 420 + 421 + return 0; 422 + } 423 + 424 + static int max77843_muic_dock_handler(struct max77843_muic_info *info, 425 + bool attached) 426 + { 427 + int ret; 428 + 429 + dev_dbg(info->dev, "external connector is %s (adc: 0x10)\n", 430 + attached ? "attached" : "detached"); 431 + 432 + ret = max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_USB, 433 + attached, attached); 434 + if (ret < 0) 435 + return ret; 436 + 437 + extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached); 438 + extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached); 439 + extcon_set_state_sync(info->edev, EXTCON_DOCK, attached); 441 440 442 441 return 0; 443 442 } ··· 476 435 info->prev_cable_type); 477 436 478 437 switch (cable_type) { 438 + case MAX77843_MUIC_ADC_RESERVED_ACC_3: /* SmartDock */ 439 + ret = max77843_muic_dock_handler(info, attached); 440 + if (ret < 0) 441 + return ret; 442 + break; 479 443 case MAX77843_MUIC_ADC_GROUND: 480 444 ret = max77843_muic_adc_gnd_handler(info); 481 445 if (ret < 0) ··· 508 462 case MAX77843_MUIC_ADC_REMOTE_S12_BUTTON: 509 463 case MAX77843_MUIC_ADC_RESERVED_ACC_1: 510 464 case MAX77843_MUIC_ADC_RESERVED_ACC_2: 511 - case MAX77843_MUIC_ADC_RESERVED_ACC_3: 512 465 case MAX77843_MUIC_ADC_RESERVED_ACC_4: 513 466 case MAX77843_MUIC_ADC_RESERVED_ACC_5: 514 467 case MAX77843_MUIC_ADC_AUDIO_DEVICE_TYPE2: ··· 551 506 case MAX77843_MUIC_CHG_USB: 552 507 ret = max77843_muic_set_path(info, 553 508 MAX77843_MUIC_CONTROL1_SW_USB, 554 - attached); 509 + attached, false); 555 510 if (ret < 0) 556 511 return ret; 557 512 ··· 562 517 case MAX77843_MUIC_CHG_DOWNSTREAM: 563 518 ret = max77843_muic_set_path(info, 564 519 MAX77843_MUIC_CONTROL1_SW_OPEN, 565 - attached); 520 + attached, false); 566 521 if (ret < 0) 567 522 return ret; 568 523 ··· 572 527 case MAX77843_MUIC_CHG_DEDICATED: 573 528 ret = max77843_muic_set_path(info, 574 529 MAX77843_MUIC_CONTROL1_SW_OPEN, 575 - attached); 530 + attached, false); 576 531 if (ret < 0) 577 532 return ret; 578 533 ··· 582 537 case MAX77843_MUIC_CHG_SPECIAL_500MA: 583 538 ret = max77843_muic_set_path(info, 584 539 MAX77843_MUIC_CONTROL1_SW_OPEN, 585 - attached); 540 + attached, false); 586 541 if (ret < 0) 587 542 return ret; 588 543 ··· 592 547 case MAX77843_MUIC_CHG_SPECIAL_1A: 593 548 ret = max77843_muic_set_path(info, 594 549 MAX77843_MUIC_CONTROL1_SW_OPEN, 595 - attached); 550 + attached, false); 596 551 if (ret < 0) 597 552 return ret; 598 553 ··· 611 566 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, 612 567 false); 613 568 break; 569 + case MAX77843_MUIC_CHG_DOCK: 570 + extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, attached); 571 + break; 614 572 case MAX77843_MUIC_CHG_NONE: 615 573 break; 616 574 default: ··· 622 574 attached ? "attached" : "detached", chg_type); 623 575 624 576 max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_OPEN, 625 - attached); 577 + attached, false); 626 578 return -EINVAL; 627 579 } 628 580 ··· 862 814 max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS); 863 815 864 816 /* Set initial path for UART */ 865 - max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART, true); 817 + max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART, true, 818 + false); 866 819 867 820 /* Check revision number of MUIC device */ 868 821 ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id);
+2
include/linux/mfd/max77843-private.h
··· 350 350 /* MAX77843 CONTROL register */ 351 351 #define MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT 0 352 352 #define MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT 3 353 + #define MAX77843_MUIC_CONTROL1_NOBCCOMP_SHIFT 6 353 354 #define MAX77843_MUIC_CONTROL1_IDBEN_SHIFT 7 354 355 #define MAX77843_MUIC_CONTROL2_LOWPWR_SHIFT 0 355 356 #define MAX77843_MUIC_CONTROL2_ADCEN_SHIFT 1 ··· 367 366 #define MAX77843_MUIC_CONTROL1_COMP1SW_MASK (0x7 << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT) 368 367 #define MAX77843_MUIC_CONTROL1_COMP2SW_MASK (0x7 << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT) 369 368 #define MAX77843_MUIC_CONTROL1_IDBEN_MASK BIT(MAX77843_MUIC_CONTROL1_IDBEN_SHIFT) 369 + #define MAX77843_MUIC_CONTROL1_NOBCCOMP_MASK BIT(MAX77843_MUIC_CONTROL1_NOBCCOMP_SHIFT) 370 370 #define MAX77843_MUIC_CONTROL2_LOWPWR_MASK BIT(MAX77843_MUIC_CONTROL2_LOWPWR_SHIFT) 371 371 #define MAX77843_MUIC_CONTROL2_ADCEN_MASK BIT(MAX77843_MUIC_CONTROL2_ADCEN_SHIFT) 372 372 #define MAX77843_MUIC_CONTROL2_CPEN_MASK BIT(MAX77843_MUIC_CONTROL2_CPEN_SHIFT)