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

Merge tag 'extcon-arizona-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc into char-misc-next

Mark writes:
extcon: arizona: Updates for v3.9

More updates for v3.9, a mix of fixes for the code that's already there
and a few new features.

+221 -38
+1 -1
drivers/extcon/Kconfig
··· 47 47 48 48 config EXTCON_ARIZONA 49 49 tristate "Wolfson Arizona EXTCON support" 50 - depends on MFD_ARIZONA && INPUT 50 + depends on MFD_ARIZONA && INPUT && SND_SOC 51 51 help 52 52 Say Y here to enable support for external accessory detection 53 53 with Wolfson Arizona devices. These are audio CODECs with
+203 -37
drivers/extcon/extcon-arizona.c
··· 27 27 #include <linux/regulator/consumer.h> 28 28 #include <linux/extcon.h> 29 29 30 + #include <sound/soc.h> 31 + 30 32 #include <linux/mfd/arizona/core.h> 31 33 #include <linux/mfd/arizona/pdata.h> 32 34 #include <linux/mfd/arizona/registers.h> 33 - 34 - #define ARIZONA_DEFAULT_HP 32 35 35 36 36 #define ARIZONA_NUM_BUTTONS 6 37 37 ··· 53 53 bool micd_reva; 54 54 bool micd_clamp; 55 55 56 + struct delayed_work hpdet_work; 57 + 56 58 bool hpdet_active; 59 + bool hpdet_done; 57 60 58 61 int num_hpdet_res; 59 62 unsigned int hpdet_res[3]; ··· 118 115 dev_dbg(arizona->dev, "Set jack polarity to %d\n", mode); 119 116 } 120 117 118 + static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info) 119 + { 120 + switch (info->micd_modes[0].bias >> ARIZONA_MICD_BIAS_SRC_SHIFT) { 121 + case 1: 122 + return "MICBIAS1"; 123 + case 2: 124 + return "MICBIAS2"; 125 + case 3: 126 + return "MICBIAS3"; 127 + default: 128 + return "MICVDD"; 129 + } 130 + } 131 + 132 + static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info) 133 + { 134 + struct arizona *arizona = info->arizona; 135 + const char *widget = arizona_extcon_get_micbias(info); 136 + struct snd_soc_dapm_context *dapm = arizona->dapm; 137 + int ret; 138 + 139 + mutex_lock(&dapm->card->dapm_mutex); 140 + 141 + ret = snd_soc_dapm_force_enable_pin(dapm, widget); 142 + if (ret != 0) 143 + dev_warn(arizona->dev, "Failed to enable %s: %d\n", 144 + widget, ret); 145 + 146 + mutex_unlock(&dapm->card->dapm_mutex); 147 + 148 + snd_soc_dapm_sync(dapm); 149 + 150 + if (!arizona->pdata.micd_force_micbias) { 151 + mutex_lock(&dapm->card->dapm_mutex); 152 + 153 + ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); 154 + if (ret != 0) 155 + dev_warn(arizona->dev, "Failed to disable %s: %d\n", 156 + widget, ret); 157 + 158 + mutex_unlock(&dapm->card->dapm_mutex); 159 + 160 + snd_soc_dapm_sync(dapm); 161 + } 162 + } 163 + 121 164 static void arizona_start_mic(struct arizona_extcon_info *info) 122 165 { 123 166 struct arizona *arizona = info->arizona; ··· 172 123 173 124 /* Microphone detection can't use idle mode */ 174 125 pm_runtime_get(info->dev); 126 + 127 + if (info->detecting) { 128 + ret = regulator_allow_bypass(info->micvdd, false); 129 + if (ret != 0) { 130 + dev_err(arizona->dev, 131 + "Failed to regulate MICVDD: %d\n", 132 + ret); 133 + } 134 + } 175 135 176 136 ret = regulator_enable(info->micvdd); 177 137 if (ret != 0) { ··· 198 140 ARIZONA_ACCESSORY_DETECT_MODE_1, 199 141 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 200 142 143 + arizona_extcon_pulse_micbias(info); 144 + 201 145 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, 202 146 ARIZONA_MICD_ENA, ARIZONA_MICD_ENA, 203 147 &change); ··· 212 152 static void arizona_stop_mic(struct arizona_extcon_info *info) 213 153 { 214 154 struct arizona *arizona = info->arizona; 155 + const char *widget = arizona_extcon_get_micbias(info); 156 + struct snd_soc_dapm_context *dapm = arizona->dapm; 215 157 bool change; 158 + int ret; 216 159 217 160 regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, 218 161 ARIZONA_MICD_ENA, 0, 219 162 &change); 220 163 164 + mutex_lock(&dapm->card->dapm_mutex); 165 + 166 + ret = snd_soc_dapm_disable_pin(dapm, widget); 167 + if (ret != 0) 168 + dev_warn(arizona->dev, 169 + "Failed to disable %s: %d\n", 170 + widget, ret); 171 + 172 + mutex_unlock(&dapm->card->dapm_mutex); 173 + 174 + snd_soc_dapm_sync(dapm); 175 + 221 176 if (info->micd_reva) { 222 177 regmap_write(arizona->regmap, 0x80, 0x3); 223 178 regmap_write(arizona->regmap, 0x294, 2); 224 179 regmap_write(arizona->regmap, 0x80, 0x0); 180 + } 181 + 182 + ret = regulator_allow_bypass(info->micvdd, true); 183 + if (ret != 0) { 184 + dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", 185 + ret); 225 186 } 226 187 227 188 if (change) { ··· 289 208 if (!(val & ARIZONA_HP_DONE)) { 290 209 dev_err(arizona->dev, "HPDET did not complete: %x\n", 291 210 val); 292 - val = ARIZONA_DEFAULT_HP; 211 + return -EAGAIN; 293 212 } 294 213 295 214 val &= ARIZONA_HP_LVL_MASK; ··· 299 218 if (!(val & ARIZONA_HP_DONE_B)) { 300 219 dev_err(arizona->dev, "HPDET did not complete: %x\n", 301 220 val); 302 - return ARIZONA_DEFAULT_HP; 221 + return -EAGAIN; 303 222 } 304 223 305 224 ret = regmap_read(arizona->regmap, ARIZONA_HP_DACVAL, &val); 306 225 if (ret != 0) { 307 226 dev_err(arizona->dev, "Failed to read HP value: %d\n", 308 227 ret); 309 - return ARIZONA_DEFAULT_HP; 228 + return -EAGAIN; 310 229 } 311 230 312 231 regmap_read(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1, ··· 348 267 if (!(val & ARIZONA_HP_DONE_B)) { 349 268 dev_err(arizona->dev, "HPDET did not complete: %x\n", 350 269 val); 351 - return ARIZONA_DEFAULT_HP; 270 + return -EAGAIN; 352 271 } 353 272 354 273 val &= ARIZONA_HP_LVL_B_MASK; ··· 395 314 { 396 315 struct arizona *arizona = info->arizona; 397 316 int id_gpio = arizona->pdata.hpdet_id_gpio; 398 - int ret; 399 317 400 318 /* 401 319 * If we're using HPDET for accessory identification we need ··· 451 371 info->hpdet_res[0], info->hpdet_res[1], 452 372 info->hpdet_res[2]); 453 373 374 + 375 + /* Take the headphone impedance for the main report */ 376 + *reading = info->hpdet_res[0]; 377 + 454 378 /* 455 379 * Either the two grounds measure differently or we 456 380 * measure the mic as high impedance. ··· 463 379 (id_gpio && info->hpdet_res[2] > 10)) { 464 380 dev_dbg(arizona->dev, "Detected mic\n"); 465 381 info->mic = true; 466 - ret = extcon_set_cable_state_(&info->edev, 467 - ARIZONA_CABLE_MICROPHONE, 468 - true); 469 - if (ret != 0) { 470 - dev_err(arizona->dev, 471 - "Failed to report mic: %d\n", ret); 472 - } 473 - 474 - /* Take the headphone impedance for the main report */ 475 - *reading = info->hpdet_res[1]; 382 + info->detecting = true; 476 383 } else { 477 384 dev_dbg(arizona->dev, "Detected headphone\n"); 478 385 } ··· 484 409 struct arizona *arizona = info->arizona; 485 410 int id_gpio = arizona->pdata.hpdet_id_gpio; 486 411 int report = ARIZONA_CABLE_HEADPHONE; 412 + unsigned int val; 487 413 int ret, reading; 488 414 489 415 mutex_lock(&info->lock); ··· 539 463 dev_err(arizona->dev, "Failed to report HP/line: %d\n", 540 464 ret); 541 465 542 - ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); 543 - if (ret != 0) 544 - dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret); 466 + mutex_lock(&arizona->dapm->card->dapm_mutex); 545 467 546 - ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); 547 - if (ret != 0) 548 - dev_warn(arizona->dev, "Failed to undo magic: %d\n", ret); 468 + ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); 469 + if (ret != 0) { 470 + dev_err(arizona->dev, "Failed to read output enables: %d\n", 471 + ret); 472 + val = 0; 473 + } 474 + 475 + if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { 476 + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0); 477 + if (ret != 0) 478 + dev_warn(arizona->dev, "Failed to undo magic: %d\n", 479 + ret); 480 + 481 + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0); 482 + if (ret != 0) 483 + dev_warn(arizona->dev, "Failed to undo magic: %d\n", 484 + ret); 485 + } 486 + 487 + mutex_unlock(&arizona->dapm->card->dapm_mutex); 549 488 550 489 done: 551 490 if (id_gpio) ··· 580 489 info->hpdet_active = false; 581 490 } 582 491 492 + info->hpdet_done = true; 493 + 583 494 out: 584 495 mutex_unlock(&info->lock); 585 496 ··· 592 499 { 593 500 struct arizona *arizona = info->arizona; 594 501 int ret; 502 + 503 + if (info->hpdet_done) 504 + return; 595 505 596 506 dev_dbg(arizona->dev, "Starting HPDET\n"); 597 507 ··· 653 557 static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) 654 558 { 655 559 struct arizona *arizona = info->arizona; 560 + unsigned int val; 656 561 int ret; 657 562 658 563 dev_dbg(arizona->dev, "Starting identification via HPDET\n"); 659 564 660 565 /* Make sure we keep the device enabled during the measurement */ 661 - pm_runtime_get(info->dev); 566 + pm_runtime_get_sync(info->dev); 662 567 663 568 info->hpdet_active = true; 664 569 665 - ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 0x4000); 666 - if (ret != 0) 667 - dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); 570 + arizona_extcon_pulse_micbias(info); 668 571 669 - ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 0x4000); 670 - if (ret != 0) 671 - dev_warn(arizona->dev, "Failed to do magic: %d\n", ret); 572 + mutex_lock(&arizona->dapm->card->dapm_mutex); 573 + 574 + ret = regmap_read(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, &val); 575 + if (ret != 0) { 576 + dev_err(arizona->dev, "Failed to read output enables: %d\n", 577 + ret); 578 + val = 0; 579 + } 580 + 581 + if (!(val & (ARIZONA_OUT1L_ENA | ARIZONA_OUT1R_ENA))) { 582 + ret = regmap_update_bits(arizona->regmap, 0x225, 0x4000, 583 + 0x4000); 584 + if (ret != 0) 585 + dev_warn(arizona->dev, "Failed to do magic: %d\n", 586 + ret); 587 + 588 + ret = regmap_update_bits(arizona->regmap, 0x226, 0x4000, 589 + 0x4000); 590 + if (ret != 0) 591 + dev_warn(arizona->dev, "Failed to do magic: %d\n", 592 + ret); 593 + } 594 + 595 + mutex_unlock(&arizona->dapm->card->dapm_mutex); 672 596 673 597 ret = regmap_update_bits(arizona->regmap, 674 598 ARIZONA_ACCESSORY_DETECT_MODE_1, ··· 767 651 dev_err(arizona->dev, "Headset report failed: %d\n", 768 652 ret); 769 653 654 + /* Don't need to regulate for button detection */ 655 + ret = regulator_allow_bypass(info->micvdd, false); 656 + if (ret != 0) { 657 + dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", 658 + ret); 659 + } 660 + 770 661 info->mic = true; 771 662 info->detecting = false; 772 663 goto handled; ··· 786 663 * impedence then give up and report headphones. 787 664 */ 788 665 if (info->detecting && (val & 0x3f8)) { 789 - info->jack_flips++; 790 - 791 666 if (info->jack_flips >= info->micd_num_modes) { 792 667 dev_dbg(arizona->dev, "Detected HP/line\n"); 793 668 arizona_identify_headphone(info); ··· 839 718 input_report_key(info->input, 840 719 arizona_lvl_to_key[i].report, 0); 841 720 input_sync(info->input); 721 + arizona_extcon_pulse_micbias(info); 842 722 } 843 723 844 724 handled: ··· 847 725 mutex_unlock(&info->lock); 848 726 849 727 return IRQ_HANDLED; 728 + } 729 + 730 + static void arizona_hpdet_work(struct work_struct *work) 731 + { 732 + struct arizona_extcon_info *info = container_of(work, 733 + struct arizona_extcon_info, 734 + hpdet_work.work); 735 + 736 + mutex_lock(&info->lock); 737 + arizona_start_hpdet_acc_id(info); 738 + mutex_unlock(&info->lock); 850 739 } 851 740 852 741 static irqreturn_t arizona_jackdet(int irq, void *data) ··· 868 735 int ret, i; 869 736 870 737 pm_runtime_get_sync(info->dev); 738 + 739 + cancel_delayed_work_sync(&info->hpdet_work); 871 740 872 741 mutex_lock(&info->lock); 873 742 ··· 906 771 907 772 arizona_start_mic(info); 908 773 } else { 909 - arizona_start_hpdet_acc_id(info); 774 + schedule_delayed_work(&info->hpdet_work, 775 + msecs_to_jiffies(250)); 910 776 } 777 + 778 + regmap_update_bits(arizona->regmap, 779 + ARIZONA_JACK_DETECT_DEBOUNCE, 780 + ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0); 911 781 } else { 912 782 dev_dbg(arizona->dev, "Detected jack removal\n"); 913 783 ··· 922 782 for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++) 923 783 info->hpdet_res[i] = 0; 924 784 info->mic = false; 785 + info->hpdet_done = false; 925 786 926 787 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 927 788 input_report_key(info->input, ··· 933 792 if (ret != 0) 934 793 dev_err(arizona->dev, "Removal report failed: %d\n", 935 794 ret); 795 + 796 + regmap_update_bits(arizona->regmap, 797 + ARIZONA_JACK_DETECT_DEBOUNCE, 798 + ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 799 + ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB); 936 800 } 801 + 802 + /* Clear trig_sts to make sure DCVDD is not forced up */ 803 + regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG, 804 + ARIZONA_MICD_CLAMP_FALL_TRIG_STS | 805 + ARIZONA_MICD_CLAMP_RISE_TRIG_STS | 806 + ARIZONA_JD1_FALL_TRIG_STS | 807 + ARIZONA_JD1_RISE_TRIG_STS); 937 808 938 809 mutex_unlock(&info->lock); 939 810 ··· 962 809 struct arizona_extcon_info *info; 963 810 int jack_irq_fall, jack_irq_rise; 964 811 int ret, mode, i; 812 + 813 + if (!arizona->dapm || !arizona->dapm->card) 814 + return -EPROBE_DEFER; 965 815 966 816 pdata = dev_get_platdata(arizona->dev); 967 817 ··· 985 829 mutex_init(&info->lock); 986 830 info->arizona = arizona; 987 831 info->dev = &pdev->dev; 832 + INIT_DELAYED_WORK(&info->hpdet_work, arizona_hpdet_work); 988 833 platform_set_drvdata(pdev, info); 989 834 990 835 switch (arizona->type) { ··· 1056 899 ARIZONA_MICD_BIAS_STARTTIME_MASK, 1057 900 arizona->pdata.micd_bias_start_time 1058 901 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT); 902 + 903 + if (arizona->pdata.micd_rate) 904 + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, 905 + ARIZONA_MICD_RATE_MASK, 906 + arizona->pdata.micd_rate 907 + << ARIZONA_MICD_RATE_SHIFT); 908 + 909 + if (arizona->pdata.micd_dbtime) 910 + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, 911 + ARIZONA_MICD_DBTIME_MASK, 912 + arizona->pdata.micd_dbtime 913 + << ARIZONA_MICD_DBTIME_SHIFT); 1059 914 1060 915 /* 1061 916 * If we have a clamp use it, activating in conjunction with ··· 1165 996 goto err_micdet; 1166 997 } 1167 998 1168 - regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, 1169 - ARIZONA_MICD_RATE_MASK, 1170 - 8 << ARIZONA_MICD_RATE_SHIFT); 1171 - 1172 999 arizona_clk32k_enable(arizona); 1173 1000 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_DEBOUNCE, 1174 1001 ARIZONA_JD1_DB, ARIZONA_JD1_DB); ··· 1232 1067 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info); 1233 1068 arizona_free_irq(arizona, jack_irq_rise, info); 1234 1069 arizona_free_irq(arizona, jack_irq_fall, info); 1070 + cancel_delayed_work_sync(&info->hpdet_work); 1235 1071 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, 1236 1072 ARIZONA_JD1_ENA, 0); 1237 1073 arizona_clk32k_disable(arizona);
+9
include/linux/mfd/arizona/pdata.h
··· 111 111 /** Mic detect ramp rate */ 112 112 int micd_bias_start_time; 113 113 114 + /** Mic detect sample rate */ 115 + int micd_rate; 116 + 117 + /** Mic detect debounce level */ 118 + int micd_dbtime; 119 + 120 + /** Force MICBIAS on for mic detect */ 121 + bool micd_force_micbias; 122 + 114 123 /** Headset polarity configurations */ 115 124 struct arizona_micd_config *micd_configs; 116 125 int num_micd_configs;
+8
include/linux/mfd/arizona/registers.h
··· 5267 5267 /* 5268 5268 * R3408 (0xD50) - AOD wkup and trig 5269 5269 */ 5270 + #define ARIZONA_MICD_CLAMP_FALL_TRIG_STS 0x0080 /* MICD_CLAMP_FALL_TRIG_STS */ 5271 + #define ARIZONA_MICD_CLAMP_FALL_TRIG_STS_MASK 0x0080 /* MICD_CLAMP_FALL_TRIG_STS */ 5272 + #define ARIZONA_MICD_CLAMP_FALL_TRIG_STS_SHIFT 7 /* MICD_CLAMP_FALL_TRIG_STS */ 5273 + #define ARIZONA_MICD_CLAMP_FALL_TRIG_STS_WIDTH 1 /* MICD_CLAMP_FALL_TRIG_STS */ 5274 + #define ARIZONA_MICD_CLAMP_RISE_TRIG_STS 0x0040 /* MICD_CLAMP_RISE_TRIG_STS */ 5275 + #define ARIZONA_MICD_CLAMP_RISE_TRIG_STS_MASK 0x0040 /* MICD_CLAMP_RISE_TRIG_STS */ 5276 + #define ARIZONA_MICD_CLAMP_RISE_TRIG_STS_SHIFT 6 /* MICD_CLAMP_RISE_TRIG_STS */ 5277 + #define ARIZONA_MICD_CLAMP_RISE_TRIG_STS_WIDTH 1 /* MICD_CLAMP_RISE_TRIG_STS */ 5270 5278 #define ARIZONA_GP5_FALL_TRIG_STS 0x0020 /* GP5_FALL_TRIG_STS */ 5271 5279 #define ARIZONA_GP5_FALL_TRIG_STS_MASK 0x0020 /* GP5_FALL_TRIG_STS */ 5272 5280 #define ARIZONA_GP5_FALL_TRIG_STS_SHIFT 5 /* GP5_FALL_TRIG_STS */