aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic3x.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-11-23 06:45:05 -0500
committerTakashi Iwai <tiwai@suse.de>2010-11-23 06:45:05 -0500
commit2ab46c9390e74368a38ddb5aa525124518df8b69 (patch)
tree631e686fb11709add69f07b4fd1e5aaa10f232de /sound/soc/codecs/tlv320aic3x.c
parent9e18e1869f5ebac69f0d881fe97a198ebc0834db (diff)
parent5b3b0fa8fb0db9645b56361cdc9a9d0ddbc35e4d (diff)
Merge branch 'for-2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into topic/asoc
Conflicts: sound/soc/codecs/tpa6130a2.c
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 df726a5066e8..11a0a3d17055 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -61,6 +61,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
61 "DRVDD", /* ADC Analog and Output Driver Voltage */ 61 "DRVDD", /* ADC Analog and Output Driver Voltage */
62}; 62};
63 63
64static LIST_HEAD(reset_list);
65
64struct aic3x_priv; 66struct aic3x_priv;
65 67
66struct aic3x_disable_nb { 68struct aic3x_disable_nb {
@@ -77,6 +79,7 @@ struct aic3x_priv {
77 struct aic3x_setup_data *setup; 79 struct aic3x_setup_data *setup;
78 void *control_data; 80 void *control_data;
79 unsigned int sysclk; 81 unsigned int sysclk;
82 struct list_head list;
80 int master; 83 int master;
81 int gpio_reset; 84 int gpio_reset;
82 int power; 85 int power;
@@ -1077,7 +1080,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
1077 * Put codec to reset and require cache sync as at least one 1080 * Put codec to reset and require cache sync as at least one
1078 * of the supplies was disabled 1081 * of the supplies was disabled
1079 */ 1082 */
1080 if (aic3x->gpio_reset >= 0) 1083 if (gpio_is_valid(aic3x->gpio_reset))
1081 gpio_set_value(aic3x->gpio_reset, 0); 1084 gpio_set_value(aic3x->gpio_reset, 0);
1082 aic3x->codec->cache_sync = 1; 1085 aic3x->codec->cache_sync = 1;
1083 } 1086 }
@@ -1104,7 +1107,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1104 if (!codec->cache_sync) 1107 if (!codec->cache_sync)
1105 goto out; 1108 goto out;
1106 1109
1107 if (aic3x->gpio_reset >= 0) { 1110 if (gpio_is_valid(aic3x->gpio_reset)) {
1108 udelay(1); 1111 udelay(1);
1109 gpio_set_value(aic3x->gpio_reset, 1); 1112 gpio_set_value(aic3x->gpio_reset, 1);
1110 } 1113 }
@@ -1346,11 +1349,25 @@ static int aic3x_init(struct snd_soc_codec *codec)
1346 return 0; 1349 return 0;
1347} 1350}
1348 1351
1352static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
1353{
1354 struct aic3x_priv *a;
1355
1356 list_for_each_entry(a, &reset_list, list) {
1357 if (gpio_is_valid(aic3x->gpio_reset) &&
1358 aic3x->gpio_reset == a->gpio_reset)
1359 return true;
1360 }
1361
1362 return false;
1363}
1364
1349static int aic3x_probe(struct snd_soc_codec *codec) 1365static int aic3x_probe(struct snd_soc_codec *codec)
1350{ 1366{
1351 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1367 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1352 int ret, i; 1368 int ret, i;
1353 1369
1370 INIT_LIST_HEAD(&aic3x->list);
1354 codec->control_data = aic3x->control_data; 1371 codec->control_data = aic3x->control_data;
1355 aic3x->codec = codec; 1372 aic3x->codec = codec;
1356 codec->dapm.idle_bias_off = 1; 1373 codec->dapm.idle_bias_off = 1;
@@ -1361,7 +1378,8 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1361 return ret; 1378 return ret;
1362 } 1379 }
1363 1380
1364 if (aic3x->gpio_reset >= 0) { 1381 if (gpio_is_valid(aic3x->gpio_reset) &&
1382 !aic3x_is_shared_reset(aic3x)) {
1365 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); 1383 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1366 if (ret != 0) 1384 if (ret != 0)
1367 goto err_gpio; 1385 goto err_gpio;
@@ -1407,6 +1425,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1407 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1425 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1408 1426
1409 aic3x_add_widgets(codec); 1427 aic3x_add_widgets(codec);
1428 list_add(&aic3x->list, &reset_list);
1410 1429
1411 return 0; 1430 return 0;
1412 1431
@@ -1416,7 +1435,8 @@ err_notif:
1416 &aic3x->disable_nb[i].nb); 1435 &aic3x->disable_nb[i].nb);
1417 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1436 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1418err_get: 1437err_get:
1419 if (aic3x->gpio_reset >= 0) 1438 if (gpio_is_valid(aic3x->gpio_reset) &&
1439 !aic3x_is_shared_reset(aic3x))
1420 gpio_free(aic3x->gpio_reset); 1440 gpio_free(aic3x->gpio_reset);
1421err_gpio: 1441err_gpio:
1422 return ret; 1442 return ret;
@@ -1428,7 +1448,9 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1428 int i; 1448 int i;
1429 1449
1430 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1450 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1431 if (aic3x->gpio_reset >= 0) { 1451 list_del(&aic3x->list);
1452 if (gpio_is_valid(aic3x->gpio_reset) &&
1453 !aic3x_is_shared_reset(aic3x)) {
1432 gpio_set_value(aic3x->gpio_reset, 0); 1454 gpio_set_value(aic3x->gpio_reset, 0);
1433 gpio_free(aic3x->gpio_reset); 1455 gpio_free(aic3x->gpio_reset);
1434 } 1456 }