diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-11-23 06:45:05 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-11-23 06:45:05 -0500 |
commit | 2ab46c9390e74368a38ddb5aa525124518df8b69 (patch) | |
tree | 631e686fb11709add69f07b4fd1e5aaa10f232de /sound/soc/codecs/tlv320aic3x.c | |
parent | 9e18e1869f5ebac69f0d881fe97a198ebc0834db (diff) | |
parent | 5b3b0fa8fb0db9645b56361cdc9a9d0ddbc35e4d (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.c | 32 |
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 | ||
64 | static LIST_HEAD(reset_list); | ||
65 | |||
64 | struct aic3x_priv; | 66 | struct aic3x_priv; |
65 | 67 | ||
66 | struct aic3x_disable_nb { | 68 | struct 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 | ||
1352 | static 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 | |||
1349 | static int aic3x_probe(struct snd_soc_codec *codec) | 1365 | static 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); |
1418 | err_get: | 1437 | err_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); |
1421 | err_gpio: | 1441 | err_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 | } |