Commit 45aae62ddd1463cd89a036f9fdf213ff2b7910b0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
Merge remote-tracking branch 'regulator/topic/arizona' into regulator-next
Showing 4 changed files Side-by-side Diff
drivers/regulator/Kconfig
drivers/regulator/arizona-micsupp.c
... | ... | @@ -21,6 +21,8 @@ |
21 | 21 | #include <linux/regulator/machine.h> |
22 | 22 | #include <linux/gpio.h> |
23 | 23 | #include <linux/slab.h> |
24 | +#include <linux/workqueue.h> | |
25 | +#include <sound/soc.h> | |
24 | 26 | |
25 | 27 | #include <linux/mfd/arizona/core.h> |
26 | 28 | #include <linux/mfd/arizona/pdata.h> |
... | ... | @@ -34,6 +36,8 @@ |
34 | 36 | |
35 | 37 | struct regulator_consumer_supply supply; |
36 | 38 | struct regulator_init_data init_data; |
39 | + | |
40 | + struct work_struct check_cp_work; | |
37 | 41 | }; |
38 | 42 | |
39 | 43 | static int arizona_micsupp_list_voltage(struct regulator_dev *rdev, |
40 | 44 | |
... | ... | @@ -72,9 +76,73 @@ |
72 | 76 | return selector; |
73 | 77 | } |
74 | 78 | |
79 | +static void arizona_micsupp_check_cp(struct work_struct *work) | |
80 | +{ | |
81 | + struct arizona_micsupp *micsupp = | |
82 | + container_of(work, struct arizona_micsupp, check_cp_work); | |
83 | + struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm; | |
84 | + struct arizona *arizona = micsupp->arizona; | |
85 | + struct regmap *regmap = arizona->regmap; | |
86 | + unsigned int reg; | |
87 | + int ret; | |
88 | + | |
89 | + ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, ®); | |
90 | + if (ret != 0) { | |
91 | + dev_err(arizona->dev, "Failed to read CP state: %d\n", ret); | |
92 | + return; | |
93 | + } | |
94 | + | |
95 | + if (dapm) { | |
96 | + if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) == | |
97 | + ARIZONA_CPMIC_ENA) | |
98 | + snd_soc_dapm_force_enable_pin(dapm, "MICSUPP"); | |
99 | + else | |
100 | + snd_soc_dapm_disable_pin(dapm, "MICSUPP"); | |
101 | + | |
102 | + snd_soc_dapm_sync(dapm); | |
103 | + } | |
104 | +} | |
105 | + | |
106 | +static int arizona_micsupp_enable(struct regulator_dev *rdev) | |
107 | +{ | |
108 | + struct arizona_micsupp *micsupp = rdev_get_drvdata(rdev); | |
109 | + int ret; | |
110 | + | |
111 | + ret = regulator_enable_regmap(rdev); | |
112 | + | |
113 | + if (ret == 0) | |
114 | + schedule_work(&micsupp->check_cp_work); | |
115 | + | |
116 | + return ret; | |
117 | +} | |
118 | + | |
119 | +static int arizona_micsupp_disable(struct regulator_dev *rdev) | |
120 | +{ | |
121 | + struct arizona_micsupp *micsupp = rdev_get_drvdata(rdev); | |
122 | + int ret; | |
123 | + | |
124 | + ret = regulator_disable_regmap(rdev); | |
125 | + if (ret == 0) | |
126 | + schedule_work(&micsupp->check_cp_work); | |
127 | + | |
128 | + return ret; | |
129 | +} | |
130 | + | |
131 | +static int arizona_micsupp_set_bypass(struct regulator_dev *rdev, bool ena) | |
132 | +{ | |
133 | + struct arizona_micsupp *micsupp = rdev_get_drvdata(rdev); | |
134 | + int ret; | |
135 | + | |
136 | + ret = regulator_set_bypass_regmap(rdev, ena); | |
137 | + if (ret == 0) | |
138 | + schedule_work(&micsupp->check_cp_work); | |
139 | + | |
140 | + return ret; | |
141 | +} | |
142 | + | |
75 | 143 | static struct regulator_ops arizona_micsupp_ops = { |
76 | - .enable = regulator_enable_regmap, | |
77 | - .disable = regulator_disable_regmap, | |
144 | + .enable = arizona_micsupp_enable, | |
145 | + .disable = arizona_micsupp_disable, | |
78 | 146 | .is_enabled = regulator_is_enabled_regmap, |
79 | 147 | |
80 | 148 | .list_voltage = arizona_micsupp_list_voltage, |
... | ... | @@ -84,7 +152,7 @@ |
84 | 152 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
85 | 153 | |
86 | 154 | .get_bypass = regulator_get_bypass_regmap, |
87 | - .set_bypass = regulator_set_bypass_regmap, | |
155 | + .set_bypass = arizona_micsupp_set_bypass, | |
88 | 156 | }; |
89 | 157 | |
90 | 158 | static const struct regulator_desc arizona_micsupp = { |
... | ... | @@ -109,7 +177,8 @@ |
109 | 177 | static const struct regulator_init_data arizona_micsupp_default = { |
110 | 178 | .constraints = { |
111 | 179 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | |
112 | - REGULATOR_CHANGE_VOLTAGE, | |
180 | + REGULATOR_CHANGE_VOLTAGE | | |
181 | + REGULATOR_CHANGE_BYPASS, | |
113 | 182 | .min_uV = 1700000, |
114 | 183 | .max_uV = 3300000, |
115 | 184 | }, |
... | ... | @@ -131,6 +200,7 @@ |
131 | 200 | } |
132 | 201 | |
133 | 202 | micsupp->arizona = arizona; |
203 | + INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); | |
134 | 204 | |
135 | 205 | /* |
136 | 206 | * Since the chip usually supplies itself we provide some |
sound/soc/codecs/wm5102.c
... | ... | @@ -1152,6 +1152,8 @@ |
1152 | 1152 | SND_SOC_DAPM_OUTPUT("SPKOUTRP"), |
1153 | 1153 | SND_SOC_DAPM_OUTPUT("SPKDAT1L"), |
1154 | 1154 | SND_SOC_DAPM_OUTPUT("SPKDAT1R"), |
1155 | + | |
1156 | +SND_SOC_DAPM_OUTPUT("MICSUPP"), | |
1155 | 1157 | }; |
1156 | 1158 | |
1157 | 1159 | #define ARIZONA_MIXER_INPUT_ROUTES(name) \ |
... | ... | @@ -1364,6 +1366,8 @@ |
1364 | 1366 | { "AEC Loopback", "SPKDAT1R", "OUT5R" }, |
1365 | 1367 | { "SPKDAT1L", NULL, "OUT5L" }, |
1366 | 1368 | { "SPKDAT1R", NULL, "OUT5R" }, |
1369 | + | |
1370 | + { "MICSUPP", NULL, "SYSCLK" }, | |
1367 | 1371 | }; |
1368 | 1372 | |
1369 | 1373 | static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, |
sound/soc/codecs/wm5110.c
... | ... | @@ -624,6 +624,8 @@ |
624 | 624 | SND_SOC_DAPM_OUTPUT("SPKDAT1R"), |
625 | 625 | SND_SOC_DAPM_OUTPUT("SPKDAT2L"), |
626 | 626 | SND_SOC_DAPM_OUTPUT("SPKDAT2R"), |
627 | + | |
628 | +SND_SOC_DAPM_OUTPUT("MICSUPP"), | |
627 | 629 | }; |
628 | 630 | |
629 | 631 | #define ARIZONA_MIXER_INPUT_ROUTES(name) \ |
... | ... | @@ -832,6 +834,8 @@ |
832 | 834 | |
833 | 835 | { "SPKDAT2L", NULL, "OUT6L" }, |
834 | 836 | { "SPKDAT2R", NULL, "OUT6R" }, |
837 | + | |
838 | + { "MICSUPP", NULL, "SYSCLK" }, | |
835 | 839 | }; |
836 | 840 | |
837 | 841 | static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, |