forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/drivers/extcon/extcon-arizona.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * extcon-arizona.c - Extcon driver Wolfson Arizona devices
34 *
45 * Copyright (C) 2012-2014 Wolfson Microelectronics plc
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
156 */
167
178 #include <linux/kernel.h>
....@@ -85,8 +76,6 @@
8576
8677 const struct arizona_micd_range *micd_ranges;
8778 int num_micd_ranges;
88
-
89
- int micd_timeout;
9079
9180 bool micd_reva;
9281 bool micd_clamp;
....@@ -319,9 +308,13 @@
319308 }
320309
321310 if (info->micd_reva) {
322
- regmap_write(arizona->regmap, 0x80, 0x3);
323
- regmap_write(arizona->regmap, 0x294, 0);
324
- regmap_write(arizona->regmap, 0x80, 0x0);
311
+ const struct reg_sequence reva[] = {
312
+ { 0x80, 0x3 },
313
+ { 0x294, 0x0 },
314
+ { 0x80, 0x0 },
315
+ };
316
+
317
+ regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva));
325318 }
326319
327320 if (info->detecting && arizona->pdata.micd_software_compare)
....@@ -335,10 +328,12 @@
335328
336329 arizona_extcon_pulse_micbias(info);
337330
338
- regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
339
- ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
340
- &change);
341
- if (!change) {
331
+ ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
332
+ ARIZONA_MICD_ENA, ARIZONA_MICD_ENA,
333
+ &change);
334
+ if (ret < 0) {
335
+ dev_err(arizona->dev, "Failed to enable micd: %d\n", ret);
336
+ } else if (!change) {
342337 regulator_disable(info->micvdd);
343338 pm_runtime_put_autosuspend(info->dev);
344339 }
....@@ -350,12 +345,14 @@
350345 const char *widget = arizona_extcon_get_micbias(info);
351346 struct snd_soc_dapm_context *dapm = arizona->dapm;
352347 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
353
- bool change;
348
+ bool change = false;
354349 int ret;
355350
356
- regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
357
- ARIZONA_MICD_ENA, 0,
358
- &change);
351
+ ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
352
+ ARIZONA_MICD_ENA, 0,
353
+ &change);
354
+ if (ret < 0)
355
+ dev_err(arizona->dev, "Failed to disable micd: %d\n", ret);
359356
360357 ret = snd_soc_component_disable_pin(component, widget);
361358 if (ret != 0)
....@@ -366,9 +363,13 @@
366363 snd_soc_dapm_sync(dapm);
367364
368365 if (info->micd_reva) {
369
- regmap_write(arizona->regmap, 0x80, 0x3);
370
- regmap_write(arizona->regmap, 0x294, 2);
371
- regmap_write(arizona->regmap, 0x80, 0x0);
366
+ const struct reg_sequence reva[] = {
367
+ { 0x80, 0x3 },
368
+ { 0x294, 0x2 },
369
+ { 0x80, 0x0 },
370
+ };
371
+
372
+ regmap_multi_reg_write(arizona->regmap, reva, ARRAY_SIZE(reva));
372373 }
373374
374375 ret = regulator_allow_bypass(info->micvdd, true);
....@@ -532,66 +533,64 @@
532533 struct arizona *arizona = info->arizona;
533534 int id_gpio = arizona->pdata.hpdet_id_gpio;
534535
536
+ if (!arizona->pdata.hpdet_acc_id)
537
+ return 0;
538
+
535539 /*
536540 * If we're using HPDET for accessory identification we need
537541 * to take multiple measurements, step through them in sequence.
538542 */
539
- if (arizona->pdata.hpdet_acc_id) {
540
- info->hpdet_res[info->num_hpdet_res++] = *reading;
543
+ info->hpdet_res[info->num_hpdet_res++] = *reading;
541544
542
- /* Only check the mic directly if we didn't already ID it */
543
- if (id_gpio && info->num_hpdet_res == 1) {
544
- dev_dbg(arizona->dev, "Measuring mic\n");
545
+ /* Only check the mic directly if we didn't already ID it */
546
+ if (id_gpio && info->num_hpdet_res == 1) {
547
+ dev_dbg(arizona->dev, "Measuring mic\n");
545548
546
- regmap_update_bits(arizona->regmap,
547
- ARIZONA_ACCESSORY_DETECT_MODE_1,
548
- ARIZONA_ACCDET_MODE_MASK |
549
- ARIZONA_ACCDET_SRC,
550
- ARIZONA_ACCDET_MODE_HPR |
551
- info->micd_modes[0].src);
552
-
553
- gpio_set_value_cansleep(id_gpio, 1);
554
-
555
- regmap_update_bits(arizona->regmap,
556
- ARIZONA_HEADPHONE_DETECT_1,
557
- ARIZONA_HP_POLL, ARIZONA_HP_POLL);
558
- return -EAGAIN;
559
- }
560
-
561
- /* OK, got both. Now, compare... */
562
- dev_dbg(arizona->dev, "HPDET measured %d %d\n",
563
- info->hpdet_res[0], info->hpdet_res[1]);
564
-
565
- /* Take the headphone impedance for the main report */
566
- *reading = info->hpdet_res[0];
567
-
568
- /* Sometimes we get false readings due to slow insert */
569
- if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
570
- dev_dbg(arizona->dev, "Retrying high impedance\n");
571
- info->num_hpdet_res = 0;
572
- info->hpdet_retried = true;
573
- arizona_start_hpdet_acc_id(info);
574
- pm_runtime_put(info->dev);
575
- return -EAGAIN;
576
- }
577
-
578
- /*
579
- * If we measure the mic as high impedance
580
- */
581
- if (!id_gpio || info->hpdet_res[1] > 50) {
582
- dev_dbg(arizona->dev, "Detected mic\n");
583
- *mic = true;
584
- info->detecting = true;
585
- } else {
586
- dev_dbg(arizona->dev, "Detected headphone\n");
587
- }
588
-
589
- /* Make sure everything is reset back to the real polarity */
590549 regmap_update_bits(arizona->regmap,
591550 ARIZONA_ACCESSORY_DETECT_MODE_1,
551
+ ARIZONA_ACCDET_MODE_MASK |
592552 ARIZONA_ACCDET_SRC,
553
+ ARIZONA_ACCDET_MODE_HPR |
593554 info->micd_modes[0].src);
555
+
556
+ gpio_set_value_cansleep(id_gpio, 1);
557
+
558
+ regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
559
+ ARIZONA_HP_POLL, ARIZONA_HP_POLL);
560
+ return -EAGAIN;
594561 }
562
+
563
+ /* OK, got both. Now, compare... */
564
+ dev_dbg(arizona->dev, "HPDET measured %d %d\n",
565
+ info->hpdet_res[0], info->hpdet_res[1]);
566
+
567
+ /* Take the headphone impedance for the main report */
568
+ *reading = info->hpdet_res[0];
569
+
570
+ /* Sometimes we get false readings due to slow insert */
571
+ if (*reading >= ARIZONA_HPDET_MAX && !info->hpdet_retried) {
572
+ dev_dbg(arizona->dev, "Retrying high impedance\n");
573
+ info->num_hpdet_res = 0;
574
+ info->hpdet_retried = true;
575
+ arizona_start_hpdet_acc_id(info);
576
+ pm_runtime_put(info->dev);
577
+ return -EAGAIN;
578
+ }
579
+
580
+ /*
581
+ * If we measure the mic as high impedance
582
+ */
583
+ if (!id_gpio || info->hpdet_res[1] > 50) {
584
+ dev_dbg(arizona->dev, "Detected mic\n");
585
+ *mic = true;
586
+ info->detecting = true;
587
+ } else {
588
+ dev_dbg(arizona->dev, "Detected headphone\n");
589
+ }
590
+
591
+ /* Make sure everything is reset back to the real polarity */
592
+ regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
593
+ ARIZONA_ACCDET_SRC, info->micd_modes[0].src);
595594
596595 return 0;
597596 }
....@@ -666,11 +665,6 @@
666665 if (id_gpio)
667666 gpio_set_value_cansleep(id_gpio, 0);
668667
669
- /* Revert back to MICDET mode */
670
- regmap_update_bits(arizona->regmap,
671
- ARIZONA_ACCESSORY_DETECT_MODE_1,
672
- ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
673
-
674668 /* If we have a mic then reenable MICDET */
675669 if (state && (mic || info->mic))
676670 arizona_start_mic(info);
....@@ -705,8 +699,7 @@
705699
706700 info->hpdet_active = true;
707701
708
- if (info->mic)
709
- arizona_stop_mic(info);
702
+ arizona_stop_mic(info);
710703
711704 arizona_extcon_hp_clamp(info, true);
712705
....@@ -730,8 +723,8 @@
730723 return;
731724
732725 err:
733
- regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
734
- ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
726
+ arizona_extcon_hp_clamp(info, false);
727
+ pm_runtime_put_autosuspend(info->dev);
735728
736729 /* Just report headphone */
737730 ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
....@@ -787,9 +780,6 @@
787780 return;
788781
789782 err:
790
- regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
791
- ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
792
-
793783 /* Just report headphone */
794784 ret = extcon_set_state_sync(info->edev, EXTCON_JACK_HEADPHONE, true);
795785 if (ret != 0)
....@@ -812,75 +802,58 @@
812802
813803 arizona_identify_headphone(info);
814804
815
- arizona_stop_mic(info);
816
-
817805 mutex_unlock(&info->lock);
818806 }
819807
820
-static void arizona_micd_detect(struct work_struct *work)
808
+static int arizona_micd_adc_read(struct arizona_extcon_info *info)
821809 {
822
- struct arizona_extcon_info *info = container_of(work,
823
- struct arizona_extcon_info,
824
- micd_detect_work.work);
825810 struct arizona *arizona = info->arizona;
826
- unsigned int val = 0, lvl;
827
- int ret, i, key;
811
+ unsigned int val;
812
+ int ret;
828813
829
- cancel_delayed_work_sync(&info->micd_timeout_work);
814
+ /* Must disable MICD before we read the ADCVAL */
815
+ regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
816
+ ARIZONA_MICD_ENA, 0);
830817
831
- mutex_lock(&info->lock);
832
-
833
- /* If the cable was removed while measuring ignore the result */
834
- ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
835
- if (ret < 0) {
836
- dev_err(arizona->dev, "Failed to check cable state: %d\n",
837
- ret);
838
- mutex_unlock(&info->lock);
839
- return;
840
- } else if (!ret) {
841
- dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
842
- mutex_unlock(&info->lock);
843
- return;
818
+ ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
819
+ if (ret != 0) {
820
+ dev_err(arizona->dev,
821
+ "Failed to read MICDET_ADCVAL: %d\n", ret);
822
+ return ret;
844823 }
845824
846
- if (info->detecting && arizona->pdata.micd_software_compare) {
847
- /* Must disable MICD before we read the ADCVAL */
848
- regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
849
- ARIZONA_MICD_ENA, 0);
850
- ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val);
851
- if (ret != 0) {
852
- dev_err(arizona->dev,
853
- "Failed to read MICDET_ADCVAL: %d\n",
854
- ret);
855
- mutex_unlock(&info->lock);
856
- return;
857
- }
825
+ dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
858826
859
- dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val);
827
+ val &= ARIZONA_MICDET_ADCVAL_MASK;
828
+ if (val < ARRAY_SIZE(arizona_micd_levels))
829
+ val = arizona_micd_levels[val];
830
+ else
831
+ val = INT_MAX;
860832
861
- val &= ARIZONA_MICDET_ADCVAL_MASK;
862
- if (val < ARRAY_SIZE(arizona_micd_levels))
863
- val = arizona_micd_levels[val];
864
- else
865
- val = INT_MAX;
833
+ if (val <= QUICK_HEADPHONE_MAX_OHM)
834
+ val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
835
+ else if (val <= MICROPHONE_MIN_OHM)
836
+ val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
837
+ else if (val <= MICROPHONE_MAX_OHM)
838
+ val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
839
+ else
840
+ val = ARIZONA_MICD_LVL_8;
866841
867
- if (val <= QUICK_HEADPHONE_MAX_OHM)
868
- val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0;
869
- else if (val <= MICROPHONE_MIN_OHM)
870
- val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1;
871
- else if (val <= MICROPHONE_MAX_OHM)
872
- val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8;
873
- else
874
- val = ARIZONA_MICD_LVL_8;
875
- }
842
+ return val;
843
+}
844
+
845
+static int arizona_micd_read(struct arizona_extcon_info *info)
846
+{
847
+ struct arizona *arizona = info->arizona;
848
+ unsigned int val = 0;
849
+ int ret, i;
876850
877851 for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) {
878852 ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
879853 if (ret != 0) {
880854 dev_err(arizona->dev,
881855 "Failed to read MICDET: %d\n", ret);
882
- mutex_unlock(&info->lock);
883
- return;
856
+ return ret;
884857 }
885858
886859 dev_dbg(arizona->dev, "MICDET: %x\n", val);
....@@ -888,29 +861,44 @@
888861 if (!(val & ARIZONA_MICD_VALID)) {
889862 dev_warn(arizona->dev,
890863 "Microphone detection state invalid\n");
891
- mutex_unlock(&info->lock);
892
- return;
864
+ return -EINVAL;
893865 }
894866 }
895867
896868 if (i == 10 && !(val & MICD_LVL_0_TO_8)) {
897869 dev_err(arizona->dev, "Failed to get valid MICDET value\n");
898
- mutex_unlock(&info->lock);
899
- return;
870
+ return -EINVAL;
900871 }
872
+
873
+ return val;
874
+}
875
+
876
+static int arizona_micdet_reading(void *priv)
877
+{
878
+ struct arizona_extcon_info *info = priv;
879
+ struct arizona *arizona = info->arizona;
880
+ int ret, val;
881
+
882
+ if (info->detecting && arizona->pdata.micd_software_compare)
883
+ ret = arizona_micd_adc_read(info);
884
+ else
885
+ ret = arizona_micd_read(info);
886
+ if (ret < 0)
887
+ return ret;
888
+
889
+ val = ret;
901890
902891 /* Due to jack detect this should never happen */
903892 if (!(val & ARIZONA_MICD_STS)) {
904893 dev_warn(arizona->dev, "Detected open circuit\n");
905894 info->mic = false;
906
- arizona_stop_mic(info);
907895 info->detecting = false;
908896 arizona_identify_headphone(info);
909
- goto handled;
897
+ return 0;
910898 }
911899
912900 /* If we got a high impedence we should have a headset, report it. */
913
- if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
901
+ if (val & ARIZONA_MICD_LVL_8) {
914902 info->mic = true;
915903 info->detecting = false;
916904
....@@ -929,7 +917,7 @@
929917 ret);
930918 }
931919
932
- goto handled;
920
+ return 0;
933921 }
934922
935923 /* If we detected a lower impedence during initial startup
....@@ -938,15 +926,13 @@
938926 * plain headphones. If both polarities report a low
939927 * impedence then give up and report headphones.
940928 */
941
- if (info->detecting && (val & MICD_LVL_1_TO_7)) {
929
+ if (val & MICD_LVL_1_TO_7) {
942930 if (info->jack_flips >= info->micd_num_modes * 10) {
943931 dev_dbg(arizona->dev, "Detected HP/line\n");
944932
945933 info->detecting = false;
946934
947935 arizona_identify_headphone(info);
948
-
949
- arizona_stop_mic(info);
950936 } else {
951937 info->micd_mode++;
952938 if (info->micd_mode == info->micd_num_modes)
....@@ -954,10 +940,42 @@
954940 arizona_extcon_set_mode(info, info->micd_mode);
955941
956942 info->jack_flips++;
943
+
944
+ if (arizona->pdata.micd_software_compare)
945
+ regmap_update_bits(arizona->regmap,
946
+ ARIZONA_MIC_DETECT_1,
947
+ ARIZONA_MICD_ENA,
948
+ ARIZONA_MICD_ENA);
949
+
950
+ queue_delayed_work(system_power_efficient_wq,
951
+ &info->micd_timeout_work,
952
+ msecs_to_jiffies(arizona->pdata.micd_timeout));
957953 }
958954
959
- goto handled;
955
+ return 0;
960956 }
957
+
958
+ /*
959
+ * If we're still detecting and we detect a short then we've
960
+ * got a headphone.
961
+ */
962
+ dev_dbg(arizona->dev, "Headphone detected\n");
963
+ info->detecting = false;
964
+
965
+ arizona_identify_headphone(info);
966
+
967
+ return 0;
968
+}
969
+
970
+static int arizona_button_reading(void *priv)
971
+{
972
+ struct arizona_extcon_info *info = priv;
973
+ struct arizona *arizona = info->arizona;
974
+ int val, key, lvl, i;
975
+
976
+ val = arizona_micd_read(info);
977
+ if (val < 0)
978
+ return val;
961979
962980 /*
963981 * If we're still detecting and we detect a short then we've
....@@ -974,20 +992,13 @@
974992 input_report_key(info->input,
975993 info->micd_ranges[i].key, 0);
976994
977
- WARN_ON(!lvl);
978
- WARN_ON(ffs(lvl) - 1 >= info->num_micd_ranges);
979995 if (lvl && ffs(lvl) - 1 < info->num_micd_ranges) {
980996 key = info->micd_ranges[ffs(lvl) - 1].key;
981997 input_report_key(info->input, key, 1);
982998 input_sync(info->input);
999
+ } else {
1000
+ dev_err(arizona->dev, "Button out of range\n");
9831001 }
984
-
985
- } else if (info->detecting) {
986
- dev_dbg(arizona->dev, "Headphone detected\n");
987
- info->detecting = false;
988
- arizona_stop_mic(info);
989
-
990
- arizona_identify_headphone(info);
9911002 } else {
9921003 dev_warn(arizona->dev, "Button with no mic: %x\n",
9931004 val);
....@@ -1001,18 +1012,38 @@
10011012 arizona_extcon_pulse_micbias(info);
10021013 }
10031014
1004
-handled:
1005
- if (info->detecting) {
1006
- if (arizona->pdata.micd_software_compare)
1007
- regmap_update_bits(arizona->regmap,
1008
- ARIZONA_MIC_DETECT_1,
1009
- ARIZONA_MICD_ENA,
1010
- ARIZONA_MICD_ENA);
1015
+ return 0;
1016
+}
10111017
1012
- queue_delayed_work(system_power_efficient_wq,
1013
- &info->micd_timeout_work,
1014
- msecs_to_jiffies(info->micd_timeout));
1018
+static void arizona_micd_detect(struct work_struct *work)
1019
+{
1020
+ struct arizona_extcon_info *info = container_of(work,
1021
+ struct arizona_extcon_info,
1022
+ micd_detect_work.work);
1023
+ struct arizona *arizona = info->arizona;
1024
+ int ret;
1025
+
1026
+ cancel_delayed_work_sync(&info->micd_timeout_work);
1027
+
1028
+ mutex_lock(&info->lock);
1029
+
1030
+ /* If the cable was removed while measuring ignore the result */
1031
+ ret = extcon_get_state(info->edev, EXTCON_MECHANICAL);
1032
+ if (ret < 0) {
1033
+ dev_err(arizona->dev, "Failed to check cable state: %d\n",
1034
+ ret);
1035
+ mutex_unlock(&info->lock);
1036
+ return;
1037
+ } else if (!ret) {
1038
+ dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
1039
+ mutex_unlock(&info->lock);
1040
+ return;
10151041 }
1042
+
1043
+ if (info->detecting)
1044
+ arizona_micdet_reading(info);
1045
+ else
1046
+ arizona_button_reading(info);
10161047
10171048 pm_runtime_mark_last_busy(info->dev);
10181049 mutex_unlock(&info->lock);
....@@ -1131,7 +1162,7 @@
11311162 msecs_to_jiffies(HPDET_DEBOUNCE));
11321163
11331164 if (cancelled_mic) {
1134
- int micd_timeout = info->micd_timeout;
1165
+ int micd_timeout = arizona->pdata.micd_timeout;
11351166
11361167 queue_delayed_work(system_power_efficient_wq,
11371168 &info->micd_timeout_work,
....@@ -1151,11 +1182,11 @@
11511182 dev_err(arizona->dev, "Mechanical report failed: %d\n",
11521183 ret);
11531184
1154
- if (!arizona->pdata.hpdet_acc_id) {
1155
- info->detecting = true;
1156
- info->mic = false;
1157
- info->jack_flips = 0;
1185
+ info->detecting = true;
1186
+ info->mic = false;
1187
+ info->jack_flips = 0;
11581188
1189
+ if (!arizona->pdata.hpdet_acc_id) {
11591190 arizona_start_mic(info);
11601191 } else {
11611192 queue_delayed_work(system_power_efficient_wq,
....@@ -1208,11 +1239,6 @@
12081239 ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
12091240 }
12101241
1211
- if (arizona->pdata.micd_timeout)
1212
- info->micd_timeout = arizona->pdata.micd_timeout;
1213
- else
1214
- info->micd_timeout = DEFAULT_MICD_TIMEOUT;
1215
-
12161242 out:
12171243 /* Clear trig_sts to make sure DCVDD is not forced up */
12181244 regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
....@@ -1259,7 +1285,7 @@
12591285 int i, j;
12601286 u32 *vals;
12611287
1262
- nconfs = device_property_read_u32_array(arizona->dev, prop, NULL, 0);
1288
+ nconfs = device_property_count_u32(arizona->dev, prop);
12631289 if (nconfs <= 0)
12641290 return 0;
12651291
....@@ -1435,11 +1461,14 @@
14351461 if (!info->input) {
14361462 dev_err(arizona->dev, "Can't allocate input dev\n");
14371463 ret = -ENOMEM;
1438
- goto err_register;
1464
+ return ret;
14391465 }
14401466
14411467 info->input->name = "Headset";
14421468 info->input->phys = "arizona/extcon";
1469
+
1470
+ if (!pdata->micd_timeout)
1471
+ pdata->micd_timeout = DEFAULT_MICD_TIMEOUT;
14431472
14441473 if (pdata->num_micd_configs) {
14451474 info->micd_modes = pdata->micd_configs;
....@@ -1464,7 +1493,7 @@
14641493 if (ret != 0) {
14651494 dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
14661495 pdata->micd_pol_gpio, ret);
1467
- goto err_register;
1496
+ return ret;
14681497 }
14691498
14701499 info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio);
....@@ -1487,7 +1516,7 @@
14871516 dev_err(arizona->dev,
14881517 "Failed to get microphone polarity GPIO: %d\n",
14891518 ret);
1490
- goto err_register;
1519
+ return ret;
14911520 }
14921521 }
14931522
....@@ -1644,7 +1673,7 @@
16441673 if (ret != 0) {
16451674 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
16461675 ret);
1647
- goto err_gpio;
1676
+ goto err_pm;
16481677 }
16491678
16501679 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
....@@ -1693,13 +1722,13 @@
16931722 dev_warn(arizona->dev, "Failed to set MICVDD to bypass: %d\n",
16941723 ret);
16951724
1696
- pm_runtime_put(&pdev->dev);
1697
-
16981725 ret = input_register_device(info->input);
16991726 if (ret) {
17001727 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
17011728 goto err_hpdet;
17021729 }
1730
+
1731
+ pm_runtime_put(&pdev->dev);
17031732
17041733 return 0;
17051734
....@@ -1715,10 +1744,11 @@
17151744 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
17161745 err_rise:
17171746 arizona_free_irq(arizona, jack_irq_rise, info);
1747
+err_pm:
1748
+ pm_runtime_put(&pdev->dev);
1749
+ pm_runtime_disable(&pdev->dev);
17181750 err_gpio:
17191751 gpiod_put(info->micd_pol_gpio);
1720
-err_register:
1721
- pm_runtime_disable(&pdev->dev);
17221752 return ret;
17231753 }
17241754
....@@ -1728,23 +1758,7 @@
17281758 struct arizona *arizona = info->arizona;
17291759 int jack_irq_rise, jack_irq_fall;
17301760 bool change;
1731
-
1732
- regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
1733
- ARIZONA_MICD_ENA, 0,
1734
- &change);
1735
-
1736
- if (change) {
1737
- regulator_disable(info->micvdd);
1738
- pm_runtime_put(info->dev);
1739
- }
1740
-
1741
- gpiod_put(info->micd_pol_gpio);
1742
-
1743
- pm_runtime_disable(&pdev->dev);
1744
-
1745
- regmap_update_bits(arizona->regmap,
1746
- ARIZONA_MICD_CLAMP_CONTROL,
1747
- ARIZONA_MICD_CLAMP_MODE_MASK, 0);
1761
+ int ret;
17481762
17491763 if (info->micd_clamp) {
17501764 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
....@@ -1761,10 +1775,31 @@
17611775 arizona_free_irq(arizona, jack_irq_rise, info);
17621776 arizona_free_irq(arizona, jack_irq_fall, info);
17631777 cancel_delayed_work_sync(&info->hpdet_work);
1778
+ cancel_delayed_work_sync(&info->micd_detect_work);
1779
+ cancel_delayed_work_sync(&info->micd_timeout_work);
1780
+
1781
+ ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1,
1782
+ ARIZONA_MICD_ENA, 0,
1783
+ &change);
1784
+ if (ret < 0) {
1785
+ dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n",
1786
+ ret);
1787
+ } else if (change) {
1788
+ regulator_disable(info->micvdd);
1789
+ pm_runtime_put(info->dev);
1790
+ }
1791
+
1792
+ regmap_update_bits(arizona->regmap,
1793
+ ARIZONA_MICD_CLAMP_CONTROL,
1794
+ ARIZONA_MICD_CLAMP_MODE_MASK, 0);
17641795 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
17651796 ARIZONA_JD1_ENA, 0);
17661797 arizona_clk32k_disable(arizona);
17671798
1799
+ gpiod_put(info->micd_pol_gpio);
1800
+
1801
+ pm_runtime_disable(&pdev->dev);
1802
+
17681803 return 0;
17691804 }
17701805