diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-11-24 06:26:39 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-11-24 06:26:39 -0500 |
commit | a1c1f770e3653bfcd5dd664d8471f70d220e19f3 (patch) | |
tree | fdf3001d6608d8d8c715da7ea84c0d32fc33a9a7 /sound/soc/codecs/tlv320aic3x.c | |
parent | d50a87402e29e16a63152be810d9723ce4d87e37 (diff) | |
parent | 2ab46c9390e74368a38ddb5aa525124518df8b69 (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.c | 32 |
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 | ||
63 | static LIST_HEAD(reset_list); | ||
64 | |||
63 | struct aic3x_priv; | 65 | struct aic3x_priv; |
64 | 66 | ||
65 | struct aic3x_disable_nb { | 67 | struct 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 | ||
1351 | static 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 | |||
1348 | static int aic3x_probe(struct snd_soc_codec *codec) | 1364 | static 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); |
1417 | err_get: | 1436 | err_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); |
1420 | err_gpio: | 1440 | err_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 | } |