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 --- |