aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic3x.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-24 06:26:39 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-24 06:26:39 -0500
commita1c1f770e3653bfcd5dd664d8471f70d220e19f3 (patch)
treefdf3001d6608d8d8c715da7ea84c0d32fc33a9a7 /sound/soc/codecs/tlv320aic3x.c
parentd50a87402e29e16a63152be810d9723ce4d87e37 (diff)
parent2ab46c9390e74368a38ddb5aa525124518df8b69 (diff)
Merge branch 'topic/asoc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6 into for-2.6.38
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r--sound/soc/codecs/tlv320aic3x.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 49b797ccc8d6..bfd036a2c83c 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -60,6 +60,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
60 "DRVDD", /* ADC Analog and Output Driver Voltage */ 60 "DRVDD", /* ADC Analog and Output Driver Voltage */
61}; 61};
62 62
63static LIST_HEAD(reset_list);
64
63struct aic3x_priv; 65struct aic3x_priv;
64 66
65struct aic3x_disable_nb { 67struct aic3x_disable_nb {
@@ -76,6 +78,7 @@ struct aic3x_priv {
76 struct aic3x_setup_data *setup; 78 struct aic3x_setup_data *setup;
77 void *control_data; 79 void *control_data;
78 unsigned int sysclk; 80 unsigned int sysclk;
81 struct list_head list;
79 int master; 82 int master;
80 int gpio_reset; 83 int gpio_reset;
81 int power; 84 int power;
@@ -1076,7 +1079,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
1076 * Put codec to reset and require cache sync as at least one 1079 * Put codec to reset and require cache sync as at least one
1077 * of the supplies was disabled 1080 * of the supplies was disabled
1078 */ 1081 */
1079 if (aic3x->gpio_reset >= 0) 1082 if (gpio_is_valid(aic3x->gpio_reset))
1080 gpio_set_value(aic3x->gpio_reset, 0); 1083 gpio_set_value(aic3x->gpio_reset, 0);
1081 aic3x->codec->cache_sync = 1; 1084 aic3x->codec->cache_sync = 1;
1082 } 1085 }
@@ -1103,7 +1106,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1103 if (!codec->cache_sync) 1106 if (!codec->cache_sync)
1104 goto out; 1107 goto out;
1105 1108
1106 if (aic3x->gpio_reset >= 0) { 1109 if (gpio_is_valid(aic3x->gpio_reset)) {
1107 udelay(1); 1110 udelay(1);
1108 gpio_set_value(aic3x->gpio_reset, 1); 1111 gpio_set_value(aic3x->gpio_reset, 1);
1109 } 1112 }
@@ -1345,11 +1348,25 @@ static int aic3x_init(struct snd_soc_codec *codec)
1345 return 0; 1348 return 0;
1346} 1349}
1347 1350
1351static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
1352{
1353 struct aic3x_priv *a;
1354
1355 list_for_each_entry(a, &reset_list, list) {
1356 if (gpio_is_valid(aic3x->gpio_reset) &&
1357 aic3x->gpio_reset == a->gpio_reset)
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1348static int aic3x_probe(struct snd_soc_codec *codec) 1364static int aic3x_probe(struct snd_soc_codec *codec)
1349{ 1365{
1350 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1366 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1351 int ret, i; 1367 int ret, i;
1352 1368
1369 INIT_LIST_HEAD(&aic3x->list);
1353 codec->control_data = aic3x->control_data; 1370 codec->control_data = aic3x->control_data;
1354 aic3x->codec = codec; 1371 aic3x->codec = codec;
1355 codec->dapm.idle_bias_off = 1; 1372 codec->dapm.idle_bias_off = 1;
@@ -1360,7 +1377,8 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1360 return ret; 1377 return ret;
1361 } 1378 }
1362 1379
1363 if (aic3x->gpio_reset >= 0) { 1380 if (gpio_is_valid(aic3x->gpio_reset) &&
1381 !aic3x_is_shared_reset(aic3x)) {
1364 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); 1382 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1365 if (ret != 0) 1383 if (ret != 0)
1366 goto err_gpio; 1384 goto err_gpio;
@@ -1406,6 +1424,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1406 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1424 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1407 1425
1408 aic3x_add_widgets(codec); 1426 aic3x_add_widgets(codec);
1427 list_add(&aic3x->list, &reset_list);
1409 1428
1410 return 0; 1429 return 0;
1411 1430
@@ -1415,7 +1434,8 @@ err_notif:
1415 &aic3x->disable_nb[i].nb); 1434 &aic3x->disable_nb[i].nb);
1416 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1435 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1417err_get: 1436err_get:
1418 if (aic3x->gpio_reset >= 0) 1437 if (gpio_is_valid(aic3x->gpio_reset) &&
1438 !aic3x_is_shared_reset(aic3x))
1419 gpio_free(aic3x->gpio_reset); 1439 gpio_free(aic3x->gpio_reset);
1420err_gpio: 1440err_gpio:
1421 return ret; 1441 return ret;
@@ -1427,7 +1447,9 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1427 int i; 1447 int i;
1428 1448
1429 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1449 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1430 if (aic3x->gpio_reset >= 0) { 1450 list_del(&aic3x->list);
1451 if (gpio_is_valid(aic3x->gpio_reset) &&
1452 !aic3x_is_shared_reset(aic3x)) {
1431 gpio_set_value(aic3x->gpio_reset, 0); 1453 gpio_set_value(aic3x->gpio_reset, 0);
1432 gpio_free(aic3x->gpio_reset); 1454 gpio_free(aic3x->gpio_reset);
1433 } 1455 }