Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: sound/soc/codecs/tlv320aic3x.c

Issue 6577007: CHROMIUM: ASoC: Import entire upstream ASoC tree (Closed)
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sound/soc/codecs/tlv320aic26.c ('k') | sound/soc/codecs/tlv320dac33.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood 7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
(...skipping 28 matching lines...) Expand all
39 #include <linux/pm.h> 39 #include <linux/pm.h>
40 #include <linux/i2c.h> 40 #include <linux/i2c.h>
41 #include <linux/gpio.h> 41 #include <linux/gpio.h>
42 #include <linux/regulator/consumer.h> 42 #include <linux/regulator/consumer.h>
43 #include <linux/platform_device.h> 43 #include <linux/platform_device.h>
44 #include <linux/slab.h> 44 #include <linux/slab.h>
45 #include <sound/core.h> 45 #include <sound/core.h>
46 #include <sound/pcm.h> 46 #include <sound/pcm.h>
47 #include <sound/pcm_params.h> 47 #include <sound/pcm_params.h>
48 #include <sound/soc.h> 48 #include <sound/soc.h>
49 #include <sound/soc-dapm.h>
50 #include <sound/initval.h> 49 #include <sound/initval.h>
51 #include <sound/tlv.h> 50 #include <sound/tlv.h>
52 #include <sound/tlv320aic3x.h> 51 #include <sound/tlv320aic3x.h>
53 52
54 #include "tlv320aic3x.h" 53 #include "tlv320aic3x.h"
55 54
56 #define AIC3X_NUM_SUPPLIES 4 55 #define AIC3X_NUM_SUPPLIES 4
57 static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = { 56 static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
58 "IOVDD", /* I/O Voltage */ 57 "IOVDD", /* I/O Voltage */
59 "DVDD", /* Digital Core Voltage */ 58 "DVDD", /* Digital Core Voltage */
60 "AVDD", /* Analog DAC Voltage */ 59 "AVDD", /* Analog DAC Voltage */
61 "DRVDD", /* ADC Analog and Output Driver Voltage */ 60 "DRVDD", /* ADC Analog and Output Driver Voltage */
62 }; 61 };
63 62
63 static LIST_HEAD(reset_list);
64
64 struct aic3x_priv; 65 struct aic3x_priv;
65 66
66 struct aic3x_disable_nb { 67 struct aic3x_disable_nb {
67 struct notifier_block nb; 68 struct notifier_block nb;
68 struct aic3x_priv *aic3x; 69 struct aic3x_priv *aic3x;
69 }; 70 };
70 71
71 /* codec private data */ 72 /* codec private data */
72 struct aic3x_priv { 73 struct aic3x_priv {
73 struct snd_soc_codec *codec; 74 struct snd_soc_codec *codec;
74 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; 75 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
75 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; 76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
76 enum snd_soc_control_type control_type; 77 enum snd_soc_control_type control_type;
77 struct aic3x_setup_data *setup; 78 struct aic3x_setup_data *setup;
78 void *control_data; 79 void *control_data;
79 unsigned int sysclk; 80 unsigned int sysclk;
81 struct list_head list;
80 int master; 82 int master;
81 int gpio_reset; 83 int gpio_reset;
82 int power; 84 int power;
83 #define AIC3X_MODEL_3X 0 85 #define AIC3X_MODEL_3X 0
84 #define AIC3X_MODEL_33 1 86 #define AIC3X_MODEL_33 1
85 #define AIC3X_MODEL_3007 2 87 #define AIC3X_MODEL_3007 2
86 u16 model; 88 u16 model;
87 }; 89 };
88 90
89 /* 91 /*
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 178
177 if (invert) 179 if (invert)
178 val = mask - val; 180 val = mask - val;
179 val_mask = mask << shift; 181 val_mask = mask << shift;
180 val = val << shift; 182 val = val << shift;
181 183
182 mutex_lock(&widget->codec->mutex); 184 mutex_lock(&widget->codec->mutex);
183 185
184 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 186 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
185 /* find dapm widget path assoc with kcontrol */ 187 /* find dapm widget path assoc with kcontrol */
186 » » list_for_each_entry(path, &widget->codec->dapm_paths, list) { 188 » » list_for_each_entry(path, &widget->dapm->card->paths, list) {
187 if (path->kcontrol != kcontrol) 189 if (path->kcontrol != kcontrol)
188 continue; 190 continue;
189 191
190 /* found, now check type */ 192 /* found, now check type */
191 found = 1; 193 found = 1;
192 if (val) 194 if (val)
193 /* new connection */ 195 /* new connection */
194 path->connect = invert ? 0 : 1; 196 path->connect = invert ? 0 : 1;
195 else 197 else
196 /* old connection must be powered down */ 198 /* old connection must be powered down */
197 path->connect = invert ? 1 : 0; 199 path->connect = invert ? 1 : 0;
198 break; 200 break;
199 } 201 }
200 202
201 if (found) 203 if (found)
202 » » » snd_soc_dapm_sync(widget->codec); 204 » » » snd_soc_dapm_sync(widget->dapm);
203 } 205 }
204 206
205 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 207 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
206 208
207 mutex_unlock(&widget->codec->mutex); 209 mutex_unlock(&widget->codec->mutex);
208 return ret; 210 return ret;
209 } 211 }
210 212
211 static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; 213 static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" };
212 static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; 214 static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" };
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 /* Class-D outputs */ 783 /* Class-D outputs */
782 {"Left Class-D Out", NULL, "Left Line Out"}, 784 {"Left Class-D Out", NULL, "Left Line Out"},
783 {"Right Class-D Out", NULL, "Left Line Out"}, 785 {"Right Class-D Out", NULL, "Left Line Out"},
784 {"SPOP", NULL, "Left Class-D Out"}, 786 {"SPOP", NULL, "Left Class-D Out"},
785 {"SPOM", NULL, "Right Class-D Out"}, 787 {"SPOM", NULL, "Right Class-D Out"},
786 }; 788 };
787 789
788 static int aic3x_add_widgets(struct snd_soc_codec *codec) 790 static int aic3x_add_widgets(struct snd_soc_codec *codec)
789 { 791 {
790 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 792 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
793 struct snd_soc_dapm_context *dapm = &codec->dapm;
791 794
792 » snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 795 » snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
793 ARRAY_SIZE(aic3x_dapm_widgets)); 796 ARRAY_SIZE(aic3x_dapm_widgets));
794 797
795 /* set up audio path interconnects */ 798 /* set up audio path interconnects */
796 » snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 799 » snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
797 800
798 if (aic3x->model == AIC3X_MODEL_3007) { 801 if (aic3x->model == AIC3X_MODEL_3007) {
799 » » snd_soc_dapm_new_controls(codec, aic3007_dapm_widgets, 802 » » snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
800 ARRAY_SIZE(aic3007_dapm_widgets)); 803 ARRAY_SIZE(aic3007_dapm_widgets));
801 » » snd_soc_dapm_add_routes(codec, intercon_3007, ARRAY_SIZE(interco n_3007)); 804 » » snd_soc_dapm_add_routes(dapm, intercon_3007,
805 » » » » » ARRAY_SIZE(intercon_3007));
802 } 806 }
803 807
804 return 0; 808 return 0;
805 } 809 }
806 810
807 static int aic3x_hw_params(struct snd_pcm_substream *substream, 811 static int aic3x_hw_params(struct snd_pcm_substream *substream,
808 struct snd_pcm_hw_params *params, 812 struct snd_pcm_hw_params *params,
809 struct snd_soc_dai *dai) 813 struct snd_soc_dai *dai)
810 { 814 {
811 struct snd_soc_pcm_runtime *rtd = substream->private_data; 815 struct snd_soc_pcm_runtime *rtd = substream->private_data;
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 { 1072 {
1069 struct aic3x_disable_nb *disable_nb = 1073 struct aic3x_disable_nb *disable_nb =
1070 container_of(nb, struct aic3x_disable_nb, nb); 1074 container_of(nb, struct aic3x_disable_nb, nb);
1071 struct aic3x_priv *aic3x = disable_nb->aic3x; 1075 struct aic3x_priv *aic3x = disable_nb->aic3x;
1072 1076
1073 if (event & REGULATOR_EVENT_DISABLE) { 1077 if (event & REGULATOR_EVENT_DISABLE) {
1074 /* 1078 /*
1075 * 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
1076 * of the supplies was disabled 1080 * of the supplies was disabled
1077 */ 1081 */
1078 » » if (aic3x->gpio_reset >= 0) 1082 » » if (gpio_is_valid(aic3x->gpio_reset))
1079 gpio_set_value(aic3x->gpio_reset, 0); 1083 gpio_set_value(aic3x->gpio_reset, 0);
1080 aic3x->codec->cache_sync = 1; 1084 aic3x->codec->cache_sync = 1;
1081 } 1085 }
1082 1086
1083 return 0; 1087 return 0;
1084 } 1088 }
1085 1089
1086 static int aic3x_set_power(struct snd_soc_codec *codec, int power) 1090 static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1087 { 1091 {
1088 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1092 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1089 int i, ret; 1093 int i, ret;
1090 u8 *cache = codec->reg_cache; 1094 u8 *cache = codec->reg_cache;
1091 1095
1092 if (power) { 1096 if (power) {
1093 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies), 1097 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1094 aic3x->supplies); 1098 aic3x->supplies);
1095 if (ret) 1099 if (ret)
1096 goto out; 1100 goto out;
1097 aic3x->power = 1; 1101 aic3x->power = 1;
1098 /* 1102 /*
1099 * Reset release and cache sync is necessary only if some 1103 * Reset release and cache sync is necessary only if some
1100 * supply was off or if there were cached writes 1104 * supply was off or if there were cached writes
1101 */ 1105 */
1102 if (!codec->cache_sync) 1106 if (!codec->cache_sync)
1103 goto out; 1107 goto out;
1104 1108
1105 » » if (aic3x->gpio_reset >= 0) { 1109 » » if (gpio_is_valid(aic3x->gpio_reset)) {
1106 udelay(1); 1110 udelay(1);
1107 gpio_set_value(aic3x->gpio_reset, 1); 1111 gpio_set_value(aic3x->gpio_reset, 1);
1108 } 1112 }
1109 1113
1110 /* Sync reg_cache with the hardware */ 1114 /* Sync reg_cache with the hardware */
1111 codec->cache_only = 0; 1115 codec->cache_only = 0;
1112 for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++) 1116 for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++)
1113 snd_soc_write(codec, i, cache[i]); 1117 snd_soc_write(codec, i, cache[i]);
1114 if (aic3x->model == AIC3X_MODEL_3007) 1118 if (aic3x->model == AIC3X_MODEL_3007)
1115 aic3x_init_3007(codec); 1119 aic3x_init_3007(codec);
(...skipping 12 matching lines...) Expand all
1128 static int aic3x_set_bias_level(struct snd_soc_codec *codec, 1132 static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1129 enum snd_soc_bias_level level) 1133 enum snd_soc_bias_level level)
1130 { 1134 {
1131 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1135 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1132 u8 reg; 1136 u8 reg;
1133 1137
1134 switch (level) { 1138 switch (level) {
1135 case SND_SOC_BIAS_ON: 1139 case SND_SOC_BIAS_ON:
1136 break; 1140 break;
1137 case SND_SOC_BIAS_PREPARE: 1141 case SND_SOC_BIAS_PREPARE:
1138 » » if (codec->bias_level == SND_SOC_BIAS_STANDBY && 1142 » » if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
1139 aic3x->master) { 1143 aic3x->master) {
1140 /* enable pll */ 1144 /* enable pll */
1141 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); 1145 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1142 snd_soc_write(codec, AIC3X_PLL_PROGA_REG, 1146 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1143 reg | PLL_ENABLE); 1147 reg | PLL_ENABLE);
1144 } 1148 }
1145 break; 1149 break;
1146 case SND_SOC_BIAS_STANDBY: 1150 case SND_SOC_BIAS_STANDBY:
1147 if (!aic3x->power) 1151 if (!aic3x->power)
1148 aic3x_set_power(codec, 1); 1152 aic3x_set_power(codec, 1);
1149 » » if (codec->bias_level == SND_SOC_BIAS_PREPARE && 1153 » » if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
1150 aic3x->master) { 1154 aic3x->master) {
1151 /* disable pll */ 1155 /* disable pll */
1152 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); 1156 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1153 snd_soc_write(codec, AIC3X_PLL_PROGA_REG, 1157 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1154 reg & ~PLL_ENABLE); 1158 reg & ~PLL_ENABLE);
1155 } 1159 }
1156 break; 1160 break;
1157 case SND_SOC_BIAS_OFF: 1161 case SND_SOC_BIAS_OFF:
1158 if (aic3x->power) 1162 if (aic3x->power)
1159 aic3x_set_power(codec, 0); 1163 aic3x_set_power(codec, 0);
1160 break; 1164 break;
1161 } 1165 }
1162 » codec->bias_level = level; 1166 » codec->dapm.bias_level = level;
1163 1167
1164 return 0; 1168 return 0;
1165 } 1169 }
1166 1170
1167 void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state) 1171 void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
1168 { 1172 {
1169 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; 1173 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1170 u8 bit = gpio ? 3: 0; 1174 u8 bit = gpio ? 3: 0;
1171 u8 val = snd_soc_read(codec, reg) & ~(1 << bit); 1175 u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
1172 snd_soc_write(codec, reg, val | (!!state << bit)); 1176 snd_soc_write(codec, reg, val | (!!state << bit));
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); 1341 snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
1338 1342
1339 if (aic3x->model == AIC3X_MODEL_3007) { 1343 if (aic3x->model == AIC3X_MODEL_3007) {
1340 aic3x_init_3007(codec); 1344 aic3x_init_3007(codec);
1341 snd_soc_write(codec, CLASSD_CTRL, 0); 1345 snd_soc_write(codec, CLASSD_CTRL, 0);
1342 } 1346 }
1343 1347
1344 return 0; 1348 return 0;
1345 } 1349 }
1346 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
1347 static int aic3x_probe(struct snd_soc_codec *codec) 1364 static int aic3x_probe(struct snd_soc_codec *codec)
1348 { 1365 {
1349 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1366 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1350 int ret, i; 1367 int ret, i;
1351 1368
1369 INIT_LIST_HEAD(&aic3x->list);
1352 codec->control_data = aic3x->control_data; 1370 codec->control_data = aic3x->control_data;
1353 aic3x->codec = codec; 1371 aic3x->codec = codec;
1354 » codec->idle_bias_off = 1; 1372 » codec->dapm.idle_bias_off = 1;
1355 1373
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); 1374 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1357 if (ret != 0) { 1375 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1376 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 return ret; 1377 return ret;
1360 } 1378 }
1361 1379
1362 » if (aic3x->gpio_reset >= 0) { 1380 » if (gpio_is_valid(aic3x->gpio_reset) &&
1381 » !aic3x_is_shared_reset(aic3x)) {
1363 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); 1382 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1364 if (ret != 0) 1383 if (ret != 0)
1365 goto err_gpio; 1384 goto err_gpio;
1366 gpio_direction_output(aic3x->gpio_reset, 0); 1385 gpio_direction_output(aic3x->gpio_reset, 0);
1367 } 1386 }
1368 1387
1369 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) 1388 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1370 aic3x->supplies[i].supply = aic3x_supply_names[i]; 1389 aic3x->supplies[i].supply = aic3x_supply_names[i];
1371 1390
1372 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies), 1391 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
(...skipping 25 matching lines...) Expand all
1398 snd_soc_write(codec, AIC3X_GPIO2_REG, 1417 snd_soc_write(codec, AIC3X_GPIO2_REG,
1399 (aic3x->setup->gpio_func[1] & 0xf) << 4); 1418 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1400 } 1419 }
1401 1420
1402 snd_soc_add_controls(codec, aic3x_snd_controls, 1421 snd_soc_add_controls(codec, aic3x_snd_controls,
1403 ARRAY_SIZE(aic3x_snd_controls)); 1422 ARRAY_SIZE(aic3x_snd_controls));
1404 if (aic3x->model == AIC3X_MODEL_3007) 1423 if (aic3x->model == AIC3X_MODEL_3007)
1405 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1424 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1406 1425
1407 aic3x_add_widgets(codec); 1426 aic3x_add_widgets(codec);
1427 list_add(&aic3x->list, &reset_list);
1408 1428
1409 return 0; 1429 return 0;
1410 1430
1411 err_notif: 1431 err_notif:
1412 while (i--) 1432 while (i--)
1413 regulator_unregister_notifier(aic3x->supplies[i].consumer, 1433 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1414 &aic3x->disable_nb[i].nb); 1434 &aic3x->disable_nb[i].nb);
1415 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1435 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1416 err_get: 1436 err_get:
1417 » if (aic3x->gpio_reset >= 0) 1437 » if (gpio_is_valid(aic3x->gpio_reset) &&
1438 » !aic3x_is_shared_reset(aic3x))
1418 gpio_free(aic3x->gpio_reset); 1439 gpio_free(aic3x->gpio_reset);
1419 err_gpio: 1440 err_gpio:
1420 kfree(aic3x);
1421 return ret; 1441 return ret;
1422 } 1442 }
1423 1443
1424 static int aic3x_remove(struct snd_soc_codec *codec) 1444 static int aic3x_remove(struct snd_soc_codec *codec)
1425 { 1445 {
1426 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1446 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(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 }
1434 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) 1456 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1435 regulator_unregister_notifier(aic3x->supplies[i].consumer, 1457 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1436 &aic3x->disable_nb[i].nb); 1458 &aic3x->disable_nb[i].nb);
1437 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1459 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1438 1460
1439 return 0; 1461 return 0;
1440 } 1462 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 /* machine i2c codec control layer */ 1538 /* machine i2c codec control layer */
1517 static struct i2c_driver aic3x_i2c_driver = { 1539 static struct i2c_driver aic3x_i2c_driver = {
1518 .driver = { 1540 .driver = {
1519 .name = "tlv320aic3x-codec", 1541 .name = "tlv320aic3x-codec",
1520 .owner = THIS_MODULE, 1542 .owner = THIS_MODULE,
1521 }, 1543 },
1522 .probe = aic3x_i2c_probe, 1544 .probe = aic3x_i2c_probe,
1523 .remove = aic3x_i2c_remove, 1545 .remove = aic3x_i2c_remove,
1524 .id_table = aic3x_i2c_id, 1546 .id_table = aic3x_i2c_id,
1525 }; 1547 };
1526
1527 static inline void aic3x_i2c_init(void)
1528 {
1529 int ret;
1530
1531 ret = i2c_add_driver(&aic3x_i2c_driver);
1532 if (ret)
1533 printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
1534 __func__, ret);
1535 }
1536
1537 static inline void aic3x_i2c_exit(void)
1538 {
1539 i2c_del_driver(&aic3x_i2c_driver);
1540 }
1541 #endif 1548 #endif
1542 1549
1543 static int __init aic3x_modinit(void) 1550 static int __init aic3x_modinit(void)
1544 { 1551 {
1545 int ret = 0; 1552 int ret = 0;
1546 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1553 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1547 ret = i2c_add_driver(&aic3x_i2c_driver); 1554 ret = i2c_add_driver(&aic3x_i2c_driver);
1548 if (ret != 0) { 1555 if (ret != 0) {
1549 printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n ", 1556 printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n ",
1550 ret); 1557 ret);
1551 } 1558 }
1552 #endif 1559 #endif
1553 return ret; 1560 return ret;
1554 } 1561 }
1555 module_init(aic3x_modinit); 1562 module_init(aic3x_modinit);
1556 1563
1557 static void __exit aic3x_exit(void) 1564 static void __exit aic3x_exit(void)
1558 { 1565 {
1559 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1566 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1560 i2c_del_driver(&aic3x_i2c_driver); 1567 i2c_del_driver(&aic3x_i2c_driver);
1561 #endif 1568 #endif
1562 } 1569 }
1563 module_exit(aic3x_exit); 1570 module_exit(aic3x_exit);
1564 1571
1565 MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); 1572 MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
1566 MODULE_AUTHOR("Vladimir Barinov"); 1573 MODULE_AUTHOR("Vladimir Barinov");
1567 MODULE_LICENSE("GPL"); 1574 MODULE_LICENSE("GPL");
OLDNEW
« no previous file with comments | « sound/soc/codecs/tlv320aic26.c ('k') | sound/soc/codecs/tlv320dac33.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698