tlv320aic3x.c (8990c1bc4be46473ad19bf2fa612ca57286f3df4) tlv320aic3x.c (8ddab3f5107c3955e70e87a632d4d179ddba1189)
1/*
2 * ALSA SoC TLV320AIC3X codec driver
3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
8 *

--- 32 unchanged lines hidden (view full) ---

41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h>
43#include <linux/platform_device.h>
44#include <linux/slab.h>
45#include <sound/core.h>
46#include <sound/pcm.h>
47#include <sound/pcm_params.h>
48#include <sound/soc.h>
1/*
2 * ALSA SoC TLV320AIC3X codec driver
3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
8 *

--- 32 unchanged lines hidden (view full) ---

41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h>
43#include <linux/platform_device.h>
44#include <linux/slab.h>
45#include <sound/core.h>
46#include <sound/pcm.h>
47#include <sound/pcm_params.h>
48#include <sound/soc.h>
49#include <sound/soc-dapm.h>
50#include <sound/initval.h>
51#include <sound/tlv.h>
52#include <sound/tlv320aic3x.h>
53
54#include "tlv320aic3x.h"
55
56#define AIC3X_NUM_SUPPLIES 4
57static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
58 "IOVDD", /* I/O Voltage */
59 "DVDD", /* Digital Core Voltage */
60 "AVDD", /* Analog DAC Voltage */
61 "DRVDD", /* ADC Analog and Output Driver Voltage */
62};
63
49#include <sound/initval.h>
50#include <sound/tlv.h>
51#include <sound/tlv320aic3x.h>
52
53#include "tlv320aic3x.h"
54
55#define AIC3X_NUM_SUPPLIES 4
56static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
57 "IOVDD", /* I/O Voltage */
58 "DVDD", /* Digital Core Voltage */
59 "AVDD", /* Analog DAC Voltage */
60 "DRVDD", /* ADC Analog and Output Driver Voltage */
61};
62
63static LIST_HEAD(reset_list);
64
64struct aic3x_priv;
65
66struct aic3x_disable_nb {
67 struct notifier_block nb;
68 struct aic3x_priv *aic3x;
69};
70
71/* codec private data */
72struct aic3x_priv {
73 struct snd_soc_codec *codec;
74 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
75 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
76 enum snd_soc_control_type control_type;
77 struct aic3x_setup_data *setup;
78 void *control_data;
79 unsigned int sysclk;
65struct aic3x_priv;
66
67struct aic3x_disable_nb {
68 struct notifier_block nb;
69 struct aic3x_priv *aic3x;
70};
71
72/* codec private data */
73struct aic3x_priv {
74 struct snd_soc_codec *codec;
75 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
77 enum snd_soc_control_type control_type;
78 struct aic3x_setup_data *setup;
79 void *control_data;
80 unsigned int sysclk;
81 struct list_head list;
80 int master;
81 int gpio_reset;
82 int power;
83#define AIC3X_MODEL_3X 0
84#define AIC3X_MODEL_33 1
85#define AIC3X_MODEL_3007 2
86 u16 model;
87};

--- 90 unchanged lines hidden (view full) ---

178 val = mask - val;
179 val_mask = mask << shift;
180 val = val << shift;
181
182 mutex_lock(&widget->codec->mutex);
183
184 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
185 /* find dapm widget path assoc with kcontrol */
82 int master;
83 int gpio_reset;
84 int power;
85#define AIC3X_MODEL_3X 0
86#define AIC3X_MODEL_33 1
87#define AIC3X_MODEL_3007 2
88 u16 model;
89};

--- 90 unchanged lines hidden (view full) ---

180 val = mask - val;
181 val_mask = mask << shift;
182 val = val << shift;
183
184 mutex_lock(&widget->codec->mutex);
185
186 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
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)
188 continue;
189
190 /* found, now check type */
191 found = 1;
192 if (val)
193 /* new connection */
194 path->connect = invert ? 0 : 1;
195 else
196 /* old connection must be powered down */
197 path->connect = invert ? 1 : 0;
198 break;
199 }
200
201 if (found)
189 if (path->kcontrol != kcontrol)
190 continue;
191
192 /* found, now check type */
193 found = 1;
194 if (val)
195 /* new connection */
196 path->connect = invert ? 0 : 1;
197 else
198 /* old connection must be powered down */
199 path->connect = invert ? 1 : 0;
200 break;
201 }
202
203 if (found)
202 snd_soc_dapm_sync(widget->codec);
204 snd_soc_dapm_sync(widget->dapm);
203 }
204
205 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
206
207 mutex_unlock(&widget->codec->mutex);
208 return ret;
209}
210

--- 572 unchanged lines hidden (view full) ---

783 {"Right Class-D Out", NULL, "Left Line Out"},
784 {"SPOP", NULL, "Left Class-D Out"},
785 {"SPOM", NULL, "Right Class-D Out"},
786};
787
788static int aic3x_add_widgets(struct snd_soc_codec *codec)
789{
790 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
205 }
206
207 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
208
209 mutex_unlock(&widget->codec->mutex);
210 return ret;
211}
212

--- 572 unchanged lines hidden (view full) ---

785 {"Right Class-D Out", NULL, "Left Line Out"},
786 {"SPOP", NULL, "Left Class-D Out"},
787 {"SPOM", NULL, "Right Class-D Out"},
788};
789
790static int aic3x_add_widgets(struct snd_soc_codec *codec)
791{
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));
794
795 /* set up audio path interconnects */
796 ARRAY_SIZE(aic3x_dapm_widgets));
797
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
798 if (aic3x->model == AIC3X_MODEL_3007) {
800
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(intercon_3007));
804 snd_soc_dapm_add_routes(dapm, intercon_3007,
805 ARRAY_SIZE(intercon_3007));
802 }
803
804 return 0;
805}
806
807static int aic3x_hw_params(struct snd_pcm_substream *substream,
808 struct snd_pcm_hw_params *params,
809 struct snd_soc_dai *dai)

--- 260 unchanged lines hidden (view full) ---

1070 container_of(nb, struct aic3x_disable_nb, nb);
1071 struct aic3x_priv *aic3x = disable_nb->aic3x;
1072
1073 if (event & REGULATOR_EVENT_DISABLE) {
1074 /*
1075 * Put codec to reset and require cache sync as at least one
1076 * of the supplies was disabled
1077 */
806 }
807
808 return 0;
809}
810
811static int aic3x_hw_params(struct snd_pcm_substream *substream,
812 struct snd_pcm_hw_params *params,
813 struct snd_soc_dai *dai)

--- 260 unchanged lines hidden (view full) ---

1074 container_of(nb, struct aic3x_disable_nb, nb);
1075 struct aic3x_priv *aic3x = disable_nb->aic3x;
1076
1077 if (event & REGULATOR_EVENT_DISABLE) {
1078 /*
1079 * Put codec to reset and require cache sync as at least one
1080 * of the supplies was disabled
1081 */
1078 if (aic3x->gpio_reset >= 0)
1082 if (gpio_is_valid(aic3x->gpio_reset))
1079 gpio_set_value(aic3x->gpio_reset, 0);
1080 aic3x->codec->cache_sync = 1;
1081 }
1082
1083 return 0;
1084}
1085
1086static int aic3x_set_power(struct snd_soc_codec *codec, int power)

--- 10 unchanged lines hidden (view full) ---

1097 aic3x->power = 1;
1098 /*
1099 * Reset release and cache sync is necessary only if some
1100 * supply was off or if there were cached writes
1101 */
1102 if (!codec->cache_sync)
1103 goto out;
1104
1083 gpio_set_value(aic3x->gpio_reset, 0);
1084 aic3x->codec->cache_sync = 1;
1085 }
1086
1087 return 0;
1088}
1089
1090static int aic3x_set_power(struct snd_soc_codec *codec, int power)

--- 10 unchanged lines hidden (view full) ---

1101 aic3x->power = 1;
1102 /*
1103 * Reset release and cache sync is necessary only if some
1104 * supply was off or if there were cached writes
1105 */
1106 if (!codec->cache_sync)
1107 goto out;
1108
1105 if (aic3x->gpio_reset >= 0) {
1109 if (gpio_is_valid(aic3x->gpio_reset)) {
1106 udelay(1);
1107 gpio_set_value(aic3x->gpio_reset, 1);
1108 }
1109
1110 /* Sync reg_cache with the hardware */
1111 codec->cache_only = 0;
1112 for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++)
1113 snd_soc_write(codec, i, cache[i]);

--- 16 unchanged lines hidden (view full) ---

1130{
1131 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1132 u8 reg;
1133
1134 switch (level) {
1135 case SND_SOC_BIAS_ON:
1136 break;
1137 case SND_SOC_BIAS_PREPARE:
1110 udelay(1);
1111 gpio_set_value(aic3x->gpio_reset, 1);
1112 }
1113
1114 /* Sync reg_cache with the hardware */
1115 codec->cache_only = 0;
1116 for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++)
1117 snd_soc_write(codec, i, cache[i]);

--- 16 unchanged lines hidden (view full) ---

1134{
1135 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1136 u8 reg;
1137
1138 switch (level) {
1139 case SND_SOC_BIAS_ON:
1140 break;
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) {
1140 /* enable pll */
1141 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1142 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1143 reg | PLL_ENABLE);
1144 }
1145 break;
1146 case SND_SOC_BIAS_STANDBY:
1147 if (!aic3x->power)
1148 aic3x_set_power(codec, 1);
1143 aic3x->master) {
1144 /* enable pll */
1145 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1146 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1147 reg | PLL_ENABLE);
1148 }
1149 break;
1150 case SND_SOC_BIAS_STANDBY:
1151 if (!aic3x->power)
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) {
1151 /* disable pll */
1152 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1153 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1154 reg & ~PLL_ENABLE);
1155 }
1156 break;
1157 case SND_SOC_BIAS_OFF:
1158 if (aic3x->power)
1159 aic3x_set_power(codec, 0);
1160 break;
1161 }
1154 aic3x->master) {
1155 /* disable pll */
1156 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1157 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1158 reg & ~PLL_ENABLE);
1159 }
1160 break;
1161 case SND_SOC_BIAS_OFF:
1162 if (aic3x->power)
1163 aic3x_set_power(codec, 0);
1164 break;
1165 }
1162 codec->bias_level = level;
1166 codec->dapm.bias_level = level;
1163
1164 return 0;
1165}
1166
1167void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
1168{
1169 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1170 u8 bit = gpio ? 3: 0;
1171 u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
1172 snd_soc_write(codec, reg, val | (!!state << bit));
1173}
1174EXPORT_SYMBOL_GPL(aic3x_set_gpio);
1175
1176int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
1177{
1178 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1167
1168 return 0;
1169}
1170
1171void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
1172{
1173 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1174 u8 bit = gpio ? 3: 0;
1175 u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
1176 snd_soc_write(codec, reg, val | (!!state << bit));
1177}
1178EXPORT_SYMBOL_GPL(aic3x_set_gpio);
1179
1180int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
1181{
1182 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1179 u8 val, bit = gpio ? 2: 1;
1183 u8 val = 0, bit = gpio ? 2 : 1;
1180
1181 aic3x_read(codec, reg, &val);
1182 return (val >> bit) & 1;
1183}
1184EXPORT_SYMBOL_GPL(aic3x_get_gpio);
1185
1186void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1187 int headset_debounce, int button_debounce)

--- 11 unchanged lines hidden (view full) ---

1199 val |= AIC3X_HEADSET_DETECT_ENABLED;
1200
1201 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1202}
1203EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1204
1205int aic3x_headset_detected(struct snd_soc_codec *codec)
1206{
1184
1185 aic3x_read(codec, reg, &val);
1186 return (val >> bit) & 1;
1187}
1188EXPORT_SYMBOL_GPL(aic3x_get_gpio);
1189
1190void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1191 int headset_debounce, int button_debounce)

--- 11 unchanged lines hidden (view full) ---

1203 val |= AIC3X_HEADSET_DETECT_ENABLED;
1204
1205 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1206}
1207EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1208
1209int aic3x_headset_detected(struct snd_soc_codec *codec)
1210{
1207 u8 val;
1211 u8 val = 0;
1208 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1209 return (val >> 4) & 1;
1210}
1211EXPORT_SYMBOL_GPL(aic3x_headset_detected);
1212
1213int aic3x_button_pressed(struct snd_soc_codec *codec)
1214{
1212 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1213 return (val >> 4) & 1;
1214}
1215EXPORT_SYMBOL_GPL(aic3x_headset_detected);
1216
1217int aic3x_button_pressed(struct snd_soc_codec *codec)
1218{
1215 u8 val;
1219 u8 val = 0;
1216 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1217 return (val >> 5) & 1;
1218}
1219EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1220
1221#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
1222#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1223 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)

--- 115 unchanged lines hidden (view full) ---

1339 if (aic3x->model == AIC3X_MODEL_3007) {
1340 aic3x_init_3007(codec);
1341 snd_soc_write(codec, CLASSD_CTRL, 0);
1342 }
1343
1344 return 0;
1345}
1346
1220 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1221 return (val >> 5) & 1;
1222}
1223EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1224
1225#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
1226#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1227 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)

--- 115 unchanged lines hidden (view full) ---

1343 if (aic3x->model == AIC3X_MODEL_3007) {
1344 aic3x_init_3007(codec);
1345 snd_soc_write(codec, CLASSD_CTRL, 0);
1346 }
1347
1348 return 0;
1349}
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
1347static int aic3x_probe(struct snd_soc_codec *codec)
1348{
1349 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1350 int ret, i;
1351
1364static int aic3x_probe(struct snd_soc_codec *codec)
1365{
1366 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1367 int ret, i;
1368
1369 INIT_LIST_HEAD(&aic3x->list);
1352 codec->control_data = aic3x->control_data;
1353 aic3x->codec = codec;
1370 codec->control_data = aic3x->control_data;
1371 aic3x->codec = codec;
1354 codec->idle_bias_off = 1;
1372 codec->dapm.idle_bias_off = 1;
1355
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1357 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 return ret;
1360 }
1361
1373
1374 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1375 if (ret != 0) {
1376 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1377 return ret;
1378 }
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");
1364 if (ret != 0)
1365 goto err_gpio;
1366 gpio_direction_output(aic3x->gpio_reset, 0);
1367 }
1368
1369 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1370 aic3x->supplies[i].supply = aic3x_supply_names[i];

--- 29 unchanged lines hidden (view full) ---

1400 }
1401
1402 snd_soc_add_controls(codec, aic3x_snd_controls,
1403 ARRAY_SIZE(aic3x_snd_controls));
1404 if (aic3x->model == AIC3X_MODEL_3007)
1405 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1406
1407 aic3x_add_widgets(codec);
1382 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1383 if (ret != 0)
1384 goto err_gpio;
1385 gpio_direction_output(aic3x->gpio_reset, 0);
1386 }
1387
1388 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1389 aic3x->supplies[i].supply = aic3x_supply_names[i];

--- 29 unchanged lines hidden (view full) ---

1419 }
1420
1421 snd_soc_add_controls(codec, aic3x_snd_controls,
1422 ARRAY_SIZE(aic3x_snd_controls));
1423 if (aic3x->model == AIC3X_MODEL_3007)
1424 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1425
1426 aic3x_add_widgets(codec);
1427 list_add(&aic3x->list, &reset_list);
1408
1409 return 0;
1410
1411err_notif:
1412 while (i--)
1413 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1414 &aic3x->disable_nb[i].nb);
1415 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1416err_get:
1428
1429 return 0;
1430
1431err_notif:
1432 while (i--)
1433 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1434 &aic3x->disable_nb[i].nb);
1435 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1436err_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);
1419err_gpio:
1439 gpio_free(aic3x->gpio_reset);
1440err_gpio:
1420 kfree(aic3x);
1421 return ret;
1422}
1423
1424static int aic3x_remove(struct snd_soc_codec *codec)
1425{
1426 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1427 int i;
1428
1429 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1441 return ret;
1442}
1443
1444static int aic3x_remove(struct snd_soc_codec *codec)
1445{
1446 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1447 int i;
1448
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);
1432 gpio_free(aic3x->gpio_reset);
1433 }
1434 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1435 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1436 &aic3x->disable_nb[i].nb);
1437 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1438

--- 129 unchanged lines hidden ---
1453 gpio_set_value(aic3x->gpio_reset, 0);
1454 gpio_free(aic3x->gpio_reset);
1455 }
1456 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1457 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1458 &aic3x->disable_nb[i].nb);
1459 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1460

--- 129 unchanged lines hidden ---