diff options
Diffstat (limited to 'sound/soc/codecs/tpa6130a2.c')
-rw-r--r-- | sound/soc/codecs/tpa6130a2.c | 99 |
1 files changed, 21 insertions, 78 deletions
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index d2c243095673..1f1ac8110bef 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <sound/tpa6130a2-plat.h> | 30 | #include <sound/tpa6130a2-plat.h> |
31 | #include <sound/soc.h> | 31 | #include <sound/soc.h> |
32 | #include <sound/soc-dapm.h> | ||
33 | #include <sound/tlv.h> | 32 | #include <sound/tlv.h> |
34 | 33 | ||
35 | #include "tpa6130a2.h" | 34 | #include "tpa6130a2.h" |
@@ -42,7 +41,7 @@ struct tpa6130a2_data { | |||
42 | unsigned char regs[TPA6130A2_CACHEREGNUM]; | 41 | unsigned char regs[TPA6130A2_CACHEREGNUM]; |
43 | struct regulator *supply; | 42 | struct regulator *supply; |
44 | int power_gpio; | 43 | int power_gpio; |
45 | unsigned char power_state; | 44 | u8 power_state:1; |
46 | enum tpa_model id; | 45 | enum tpa_model id; |
47 | }; | 46 | }; |
48 | 47 | ||
@@ -117,7 +116,7 @@ static int tpa6130a2_initialize(void) | |||
117 | return ret; | 116 | return ret; |
118 | } | 117 | } |
119 | 118 | ||
120 | static int tpa6130a2_power(int power) | 119 | static int tpa6130a2_power(u8 power) |
121 | { | 120 | { |
122 | struct tpa6130a2_data *data; | 121 | struct tpa6130a2_data *data; |
123 | u8 val; | 122 | u8 val; |
@@ -127,17 +126,19 @@ static int tpa6130a2_power(int power) | |||
127 | data = i2c_get_clientdata(tpa6130a2_client); | 126 | data = i2c_get_clientdata(tpa6130a2_client); |
128 | 127 | ||
129 | mutex_lock(&data->mutex); | 128 | mutex_lock(&data->mutex); |
130 | if (power && !data->power_state) { | 129 | if (power == data->power_state) |
131 | /* Power on */ | 130 | goto exit; |
132 | if (data->power_gpio >= 0) | ||
133 | gpio_set_value(data->power_gpio, 1); | ||
134 | 131 | ||
132 | if (power) { | ||
135 | ret = regulator_enable(data->supply); | 133 | ret = regulator_enable(data->supply); |
136 | if (ret != 0) { | 134 | if (ret != 0) { |
137 | dev_err(&tpa6130a2_client->dev, | 135 | dev_err(&tpa6130a2_client->dev, |
138 | "Failed to enable supply: %d\n", ret); | 136 | "Failed to enable supply: %d\n", ret); |
139 | goto exit; | 137 | goto exit; |
140 | } | 138 | } |
139 | /* Power on */ | ||
140 | if (data->power_gpio >= 0) | ||
141 | gpio_set_value(data->power_gpio, 1); | ||
141 | 142 | ||
142 | data->power_state = 1; | 143 | data->power_state = 1; |
143 | ret = tpa6130a2_initialize(); | 144 | ret = tpa6130a2_initialize(); |
@@ -150,12 +151,7 @@ static int tpa6130a2_power(int power) | |||
150 | data->power_state = 0; | 151 | data->power_state = 0; |
151 | goto exit; | 152 | goto exit; |
152 | } | 153 | } |
153 | 154 | } else { | |
154 | /* Clear SWS */ | ||
155 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); | ||
156 | val &= ~TPA6130A2_SWS; | ||
157 | tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); | ||
158 | } else if (!power && data->power_state) { | ||
159 | /* set SWS */ | 155 | /* set SWS */ |
160 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); | 156 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); |
161 | val |= TPA6130A2_SWS; | 157 | val |= TPA6130A2_SWS; |
@@ -300,6 +296,7 @@ static void tpa6130a2_channel_enable(u8 channel, int enable) | |||
300 | /* Enable amplifier */ | 296 | /* Enable amplifier */ |
301 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); | 297 | val = tpa6130a2_read(TPA6130A2_REG_CONTROL); |
302 | val |= channel; | 298 | val |= channel; |
299 | val &= ~TPA6130A2_SWS; | ||
303 | tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); | 300 | tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); |
304 | 301 | ||
305 | /* Unmute channel */ | 302 | /* Unmute channel */ |
@@ -320,72 +317,24 @@ static void tpa6130a2_channel_enable(u8 channel, int enable) | |||
320 | } | 317 | } |
321 | } | 318 | } |
322 | 319 | ||
323 | static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w, | 320 | int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable) |
324 | struct snd_kcontrol *kcontrol, int event) | ||
325 | { | ||
326 | switch (event) { | ||
327 | case SND_SOC_DAPM_POST_PMU: | ||
328 | tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1); | ||
329 | break; | ||
330 | case SND_SOC_DAPM_POST_PMD: | ||
331 | tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0); | ||
332 | break; | ||
333 | } | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w, | ||
338 | struct snd_kcontrol *kcontrol, int event) | ||
339 | { | ||
340 | switch (event) { | ||
341 | case SND_SOC_DAPM_POST_PMU: | ||
342 | tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1); | ||
343 | break; | ||
344 | case SND_SOC_DAPM_POST_PMD: | ||
345 | tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0); | ||
346 | break; | ||
347 | } | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w, | ||
352 | struct snd_kcontrol *kcontrol, int event) | ||
353 | { | 321 | { |
354 | int ret = 0; | 322 | int ret = 0; |
355 | 323 | if (enable) { | |
356 | switch (event) { | ||
357 | case SND_SOC_DAPM_POST_PMU: | ||
358 | ret = tpa6130a2_power(1); | 324 | ret = tpa6130a2_power(1); |
359 | break; | 325 | if (ret < 0) |
360 | case SND_SOC_DAPM_POST_PMD: | 326 | return ret; |
327 | tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, | ||
328 | 1); | ||
329 | } else { | ||
330 | tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, | ||
331 | 0); | ||
361 | ret = tpa6130a2_power(0); | 332 | ret = tpa6130a2_power(0); |
362 | break; | ||
363 | } | 333 | } |
334 | |||
364 | return ret; | 335 | return ret; |
365 | } | 336 | } |
366 | 337 | EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable); | |
367 | static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { | ||
368 | SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM, | ||
369 | 0, 0, NULL, 0, tpa6130a2_left_event, | ||
370 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), | ||
371 | SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM, | ||
372 | 0, 0, NULL, 0, tpa6130a2_right_event, | ||
373 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), | ||
374 | SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM, | ||
375 | 0, 0, tpa6130a2_supply_event, | ||
376 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), | ||
377 | /* Outputs */ | ||
378 | SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"), | ||
379 | SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"), | ||
380 | }; | ||
381 | |||
382 | static const struct snd_soc_dapm_route audio_map[] = { | ||
383 | {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"}, | ||
384 | {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"}, | ||
385 | |||
386 | {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"}, | ||
387 | {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"}, | ||
388 | }; | ||
389 | 338 | ||
390 | int tpa6130a2_add_controls(struct snd_soc_codec *codec) | 339 | int tpa6130a2_add_controls(struct snd_soc_codec *codec) |
391 | { | 340 | { |
@@ -396,18 +345,12 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec) | |||
396 | 345 | ||
397 | data = i2c_get_clientdata(tpa6130a2_client); | 346 | data = i2c_get_clientdata(tpa6130a2_client); |
398 | 347 | ||
399 | snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets, | ||
400 | ARRAY_SIZE(tpa6130a2_dapm_widgets)); | ||
401 | |||
402 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | ||
403 | |||
404 | if (data->id == TPA6140A2) | 348 | if (data->id == TPA6140A2) |
405 | return snd_soc_add_controls(codec, tpa6140a2_controls, | 349 | return snd_soc_add_controls(codec, tpa6140a2_controls, |
406 | ARRAY_SIZE(tpa6140a2_controls)); | 350 | ARRAY_SIZE(tpa6140a2_controls)); |
407 | else | 351 | else |
408 | return snd_soc_add_controls(codec, tpa6130a2_controls, | 352 | return snd_soc_add_controls(codec, tpa6130a2_controls, |
409 | ARRAY_SIZE(tpa6130a2_controls)); | 353 | ARRAY_SIZE(tpa6130a2_controls)); |
410 | |||
411 | } | 354 | } |
412 | EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); | 355 | EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); |
413 | 356 | ||