aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-24 06:24:16 -0400
committerMark Brown <broonie@linaro.org>2013-10-24 06:24:16 -0400
commit3caa28274e783875757a36dd4239c3269933255b (patch)
tree9b25957830da77eac2971237d1f3a1c43e0b7d07
parent24a6703abb582a98262f17049bd6fa6c7938b339 (diff)
parentb3b70786ec18ef3088b55b76258bbd48d75aee08 (diff)
Merge remote-tracking branch 'asoc/topic/tlv320aic3x' into asoc-next
-rw-r--r--Documentation/devicetree/bindings/sound/tlv320aic3x.txt26
-rw-r--r--sound/soc/codecs/tlv320aic3x.c234
2 files changed, 139 insertions, 121 deletions
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
index 705a6b156c6c..5e6040c2c2e9 100644
--- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
+++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
@@ -24,10 +24,36 @@ Optional properties:
24 3 - MICBIAS output is connected to AVDD, 24 3 - MICBIAS output is connected to AVDD,
25 If this node is not mentioned or if the value is incorrect, then MicBias 25 If this node is not mentioned or if the value is incorrect, then MicBias
26 is powered down. 26 is powered down.
27- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the
28 device as covered in Documentation/devicetree/bindings/regulator/regulator.txt
29
30CODEC output pins:
31 * LLOUT
32 * RLOUT
33 * MONO_LOUT
34 * HPLOUT
35 * HPROUT
36 * HPLCOM
37 * HPRCOM
38
39CODEC input pins:
40 * MIC3L
41 * MIC3R
42 * LINE1L
43 * LINE2L
44 * LINE1R
45 * LINE2R
46
47The pins can be used in referring sound node's audio-routing property.
27 48
28Example: 49Example:
29 50
30tlv320aic3x: tlv320aic3x@1b { 51tlv320aic3x: tlv320aic3x@1b {
31 compatible = "ti,tlv320aic3x"; 52 compatible = "ti,tlv320aic3x";
32 reg = <0x1b>; 53 reg = <0x1b>;
54
55 AVDD-supply = <&regulator>;
56 IOVDD-supply = <&regulator>;
57 DRVDD-supply = <&regulator>;
58 DVDD-supply = <&regulator>;
33}; 59};
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 64ad84d8a306..546d16b7d38f 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -40,6 +40,7 @@
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/of.h>
43#include <linux/of_gpio.h> 44#include <linux/of_gpio.h>
44#include <linux/slab.h> 45#include <linux/slab.h>
45#include <sound/core.h> 46#include <sound/core.h>
@@ -72,9 +73,9 @@ struct aic3x_disable_nb {
72/* codec private data */ 73/* codec private data */
73struct aic3x_priv { 74struct aic3x_priv {
74 struct snd_soc_codec *codec; 75 struct snd_soc_codec *codec;
76 struct regmap *regmap;
75 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; 77 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; 78 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
77 enum snd_soc_control_type control_type;
78 struct aic3x_setup_data *setup; 79 struct aic3x_setup_data *setup;
79 unsigned int sysclk; 80 unsigned int sysclk;
80 struct list_head list; 81 struct list_head list;
@@ -90,41 +91,45 @@ struct aic3x_priv {
90 enum aic3x_micbias_voltage micbias_vg; 91 enum aic3x_micbias_voltage micbias_vg;
91}; 92};
92 93
93/* 94static const struct reg_default aic3x_reg[] = {
94 * AIC3X register cache 95 { 0, 0x00 }, { 1, 0x00 }, { 2, 0x00 }, { 3, 0x10 },
95 * We can't read the AIC3X register space when we are 96 { 4, 0x04 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 },
96 * using 2 wire for device control, so we cache them instead. 97 { 8, 0x00 }, { 9, 0x00 }, { 10, 0x00 }, { 11, 0x01 },
97 * There is no point in caching the reset register 98 { 12, 0x00 }, { 13, 0x00 }, { 14, 0x00 }, { 15, 0x80 },
98 */ 99 { 16, 0x80 }, { 17, 0xff }, { 18, 0xff }, { 19, 0x78 },
99static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = { 100 { 20, 0x78 }, { 21, 0x78 }, { 22, 0x78 }, { 23, 0x78 },
100 0x00, 0x00, 0x00, 0x10, /* 0 */ 101 { 24, 0x78 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0xfe },
101 0x04, 0x00, 0x00, 0x00, /* 4 */ 102 { 28, 0x00 }, { 29, 0x00 }, { 30, 0xfe }, { 31, 0x00 },
102 0x00, 0x00, 0x00, 0x01, /* 8 */ 103 { 32, 0x18 }, { 33, 0x18 }, { 34, 0x00 }, { 35, 0x00 },
103 0x00, 0x00, 0x00, 0x80, /* 12 */ 104 { 36, 0x00 }, { 37, 0x00 }, { 38, 0x00 }, { 39, 0x00 },
104 0x80, 0xff, 0xff, 0x78, /* 16 */ 105 { 40, 0x00 }, { 41, 0x00 }, { 42, 0x00 }, { 43, 0x80 },
105 0x78, 0x78, 0x78, 0x78, /* 20 */ 106 { 44, 0x80 }, { 45, 0x00 }, { 46, 0x00 }, { 47, 0x00 },
106 0x78, 0x00, 0x00, 0xfe, /* 24 */ 107 { 48, 0x00 }, { 49, 0x00 }, { 50, 0x00 }, { 51, 0x04 },
107 0x00, 0x00, 0xfe, 0x00, /* 28 */ 108 { 52, 0x00 }, { 53, 0x00 }, { 54, 0x00 }, { 55, 0x00 },
108 0x18, 0x18, 0x00, 0x00, /* 32 */ 109 { 56, 0x00 }, { 57, 0x00 }, { 58, 0x04 }, { 59, 0x00 },
109 0x00, 0x00, 0x00, 0x00, /* 36 */ 110 { 60, 0x00 }, { 61, 0x00 }, { 62, 0x00 }, { 63, 0x00 },
110 0x00, 0x00, 0x00, 0x80, /* 40 */ 111 { 64, 0x00 }, { 65, 0x04 }, { 66, 0x00 }, { 67, 0x00 },
111 0x80, 0x00, 0x00, 0x00, /* 44 */ 112 { 68, 0x00 }, { 69, 0x00 }, { 70, 0x00 }, { 71, 0x00 },
112 0x00, 0x00, 0x00, 0x04, /* 48 */ 113 { 72, 0x04 }, { 73, 0x00 }, { 74, 0x00 }, { 75, 0x00 },
113 0x00, 0x00, 0x00, 0x00, /* 52 */ 114 { 76, 0x00 }, { 77, 0x00 }, { 78, 0x00 }, { 79, 0x00 },
114 0x00, 0x00, 0x04, 0x00, /* 56 */ 115 { 80, 0x00 }, { 81, 0x00 }, { 82, 0x00 }, { 83, 0x00 },
115 0x00, 0x00, 0x00, 0x00, /* 60 */ 116 { 84, 0x00 }, { 85, 0x00 }, { 86, 0x00 }, { 87, 0x00 },
116 0x00, 0x04, 0x00, 0x00, /* 64 */ 117 { 88, 0x00 }, { 89, 0x00 }, { 90, 0x00 }, { 91, 0x00 },
117 0x00, 0x00, 0x00, 0x00, /* 68 */ 118 { 92, 0x00 }, { 93, 0x00 }, { 94, 0x00 }, { 95, 0x00 },
118 0x04, 0x00, 0x00, 0x00, /* 72 */ 119 { 96, 0x00 }, { 97, 0x00 }, { 98, 0x00 }, { 99, 0x00 },
119 0x00, 0x00, 0x00, 0x00, /* 76 */ 120 { 100, 0x00 }, { 101, 0x00 }, { 102, 0x02 }, { 103, 0x00 },
120 0x00, 0x00, 0x00, 0x00, /* 80 */ 121 { 104, 0x00 }, { 105, 0x00 }, { 106, 0x00 }, { 107, 0x00 },
121 0x00, 0x00, 0x00, 0x00, /* 84 */ 122 { 108, 0x00 }, { 109, 0x00 },
122 0x00, 0x00, 0x00, 0x00, /* 88 */ 123};
123 0x00, 0x00, 0x00, 0x00, /* 92 */ 124
124 0x00, 0x00, 0x00, 0x00, /* 96 */ 125static const struct regmap_config aic3x_regmap = {
125 0x00, 0x00, 0x02, 0x00, /* 100 */ 126 .reg_bits = 8,
126 0x00, 0x00, 0x00, 0x00, /* 104 */ 127 .val_bits = 8,
127 0x00, 0x00, /* 108 */ 128
129 .max_register = DAC_ICC_ADJ,
130 .reg_defaults = aic3x_reg,
131 .num_reg_defaults = ARRAY_SIZE(aic3x_reg),
132 .cache_type = REGCACHE_RBTREE,
128}; 133};
129 134
130#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 135#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
@@ -828,12 +833,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
828 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 833 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
829 struct snd_soc_dapm_context *dapm = &codec->dapm; 834 struct snd_soc_dapm_context *dapm = &codec->dapm;
830 835
831 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
832 ARRAY_SIZE(aic3x_dapm_widgets));
833
834 /* set up audio path interconnects */
835 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
836
837 if (aic3x->model == AIC3X_MODEL_3007) { 836 if (aic3x->model == AIC3X_MODEL_3007) {
838 snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets, 837 snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
839 ARRAY_SIZE(aic3007_dapm_widgets)); 838 ARRAY_SIZE(aic3007_dapm_widgets));
@@ -1082,29 +1081,6 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
1082 return 0; 1081 return 0;
1083} 1082}
1084 1083
1085static int aic3x_init_3007(struct snd_soc_codec *codec)
1086{
1087 u8 tmp1, tmp2, *cache = codec->reg_cache;
1088
1089 /*
1090 * There is no need to cache writes to undocumented page 0xD but
1091 * respective page 0 register cache entries must be preserved
1092 */
1093 tmp1 = cache[0xD];
1094 tmp2 = cache[0x8];
1095 /* Class-D speaker driver init; datasheet p. 46 */
1096 snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x0D);
1097 snd_soc_write(codec, 0xD, 0x0D);
1098 snd_soc_write(codec, 0x8, 0x5C);
1099 snd_soc_write(codec, 0x8, 0x5D);
1100 snd_soc_write(codec, 0x8, 0x5C);
1101 snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x00);
1102 cache[0xD] = tmp1;
1103 cache[0x8] = tmp2;
1104
1105 return 0;
1106}
1107
1108static int aic3x_regulator_event(struct notifier_block *nb, 1084static int aic3x_regulator_event(struct notifier_block *nb,
1109 unsigned long event, void *data) 1085 unsigned long event, void *data)
1110{ 1086{
@@ -1119,7 +1095,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
1119 */ 1095 */
1120 if (gpio_is_valid(aic3x->gpio_reset)) 1096 if (gpio_is_valid(aic3x->gpio_reset))
1121 gpio_set_value(aic3x->gpio_reset, 0); 1097 gpio_set_value(aic3x->gpio_reset, 0);
1122 aic3x->codec->cache_sync = 1; 1098 regcache_mark_dirty(aic3x->regmap);
1123 } 1099 }
1124 1100
1125 return 0; 1101 return 0;
@@ -1128,8 +1104,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
1128static int aic3x_set_power(struct snd_soc_codec *codec, int power) 1104static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1129{ 1105{
1130 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1106 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1131 int i, ret; 1107 int ret;
1132 u8 *cache = codec->reg_cache;
1133 1108
1134 if (power) { 1109 if (power) {
1135 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies), 1110 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
@@ -1137,12 +1112,6 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1137 if (ret) 1112 if (ret)
1138 goto out; 1113 goto out;
1139 aic3x->power = 1; 1114 aic3x->power = 1;
1140 /*
1141 * Reset release and cache sync is necessary only if some
1142 * supply was off or if there were cached writes
1143 */
1144 if (!codec->cache_sync)
1145 goto out;
1146 1115
1147 if (gpio_is_valid(aic3x->gpio_reset)) { 1116 if (gpio_is_valid(aic3x->gpio_reset)) {
1148 udelay(1); 1117 udelay(1);
@@ -1150,12 +1119,8 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1150 } 1119 }
1151 1120
1152 /* Sync reg_cache with the hardware */ 1121 /* Sync reg_cache with the hardware */
1153 codec->cache_only = 0; 1122 regcache_cache_only(aic3x->regmap, false);
1154 for (i = AIC3X_SAMPLE_RATE_SEL_REG; i < ARRAY_SIZE(aic3x_reg); i++) 1123 regcache_sync(aic3x->regmap);
1155 snd_soc_write(codec, i, cache[i]);
1156 if (aic3x->model == AIC3X_MODEL_3007)
1157 aic3x_init_3007(codec);
1158 codec->cache_sync = 0;
1159 } else { 1124 } else {
1160 /* 1125 /*
1161 * Do soft reset to this codec instance in order to clear 1126 * Do soft reset to this codec instance in order to clear
@@ -1163,10 +1128,10 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1163 * remain on 1128 * remain on
1164 */ 1129 */
1165 snd_soc_write(codec, AIC3X_RESET, SOFT_RESET); 1130 snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
1166 codec->cache_sync = 1; 1131 regcache_mark_dirty(aic3x->regmap);
1167 aic3x->power = 0; 1132 aic3x->power = 0;
1168 /* HW writes are needless when bias is off */ 1133 /* HW writes are needless when bias is off */
1169 codec->cache_only = 1; 1134 regcache_cache_only(aic3x->regmap, true);
1170 ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), 1135 ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies),
1171 aic3x->supplies); 1136 aic3x->supplies);
1172 } 1137 }
@@ -1321,7 +1286,6 @@ static int aic3x_init(struct snd_soc_codec *codec)
1321 snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); 1286 snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
1322 1287
1323 if (aic3x->model == AIC3X_MODEL_3007) { 1288 if (aic3x->model == AIC3X_MODEL_3007) {
1324 aic3x_init_3007(codec);
1325 snd_soc_write(codec, CLASSD_CTRL, 0); 1289 snd_soc_write(codec, CLASSD_CTRL, 0);
1326 } 1290 }
1327 1291
@@ -1349,29 +1313,12 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1349 INIT_LIST_HEAD(&aic3x->list); 1313 INIT_LIST_HEAD(&aic3x->list);
1350 aic3x->codec = codec; 1314 aic3x->codec = codec;
1351 1315
1352 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); 1316 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1353 if (ret != 0) { 1317 if (ret != 0) {
1354 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1318 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1355 return ret; 1319 return ret;
1356 } 1320 }
1357 1321
1358 if (gpio_is_valid(aic3x->gpio_reset) &&
1359 !aic3x_is_shared_reset(aic3x)) {
1360 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1361 if (ret != 0)
1362 goto err_gpio;
1363 gpio_direction_output(aic3x->gpio_reset, 0);
1364 }
1365
1366 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1367 aic3x->supplies[i].supply = aic3x_supply_names[i];
1368
1369 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
1370 aic3x->supplies);
1371 if (ret != 0) {
1372 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1373 goto err_get;
1374 }
1375 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) { 1322 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
1376 aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event; 1323 aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
1377 aic3x->disable_nb[i].aic3x = aic3x; 1324 aic3x->disable_nb[i].aic3x = aic3x;
@@ -1385,7 +1332,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1385 } 1332 }
1386 } 1333 }
1387 1334
1388 codec->cache_only = 1; 1335 regcache_mark_dirty(aic3x->regmap);
1389 aic3x_init(codec); 1336 aic3x_init(codec);
1390 1337
1391 if (aic3x->setup) { 1338 if (aic3x->setup) {
@@ -1396,8 +1343,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1396 (aic3x->setup->gpio_func[1] & 0xf) << 4); 1343 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1397 } 1344 }
1398 1345
1399 snd_soc_add_codec_controls(codec, aic3x_snd_controls,
1400 ARRAY_SIZE(aic3x_snd_controls));
1401 if (aic3x->model == AIC3X_MODEL_3007) 1346 if (aic3x->model == AIC3X_MODEL_3007)
1402 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1347 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1403 1348
@@ -1428,12 +1373,6 @@ err_notif:
1428 while (i--) 1373 while (i--)
1429 regulator_unregister_notifier(aic3x->supplies[i].consumer, 1374 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1430 &aic3x->disable_nb[i].nb); 1375 &aic3x->disable_nb[i].nb);
1431 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1432err_get:
1433 if (gpio_is_valid(aic3x->gpio_reset) &&
1434 !aic3x_is_shared_reset(aic3x))
1435 gpio_free(aic3x->gpio_reset);
1436err_gpio:
1437 return ret; 1376 return ret;
1438} 1377}
1439 1378
@@ -1444,15 +1383,9 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1444 1383
1445 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1384 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1446 list_del(&aic3x->list); 1385 list_del(&aic3x->list);
1447 if (gpio_is_valid(aic3x->gpio_reset) &&
1448 !aic3x_is_shared_reset(aic3x)) {
1449 gpio_set_value(aic3x->gpio_reset, 0);
1450 gpio_free(aic3x->gpio_reset);
1451 }
1452 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) 1386 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1453 regulator_unregister_notifier(aic3x->supplies[i].consumer, 1387 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1454 &aic3x->disable_nb[i].nb); 1388 &aic3x->disable_nb[i].nb);
1455 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1456 1389
1457 return 0; 1390 return 0;
1458} 1391}
@@ -1460,13 +1393,16 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1460static struct snd_soc_codec_driver soc_codec_dev_aic3x = { 1393static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1461 .set_bias_level = aic3x_set_bias_level, 1394 .set_bias_level = aic3x_set_bias_level,
1462 .idle_bias_off = true, 1395 .idle_bias_off = true,
1463 .reg_cache_size = ARRAY_SIZE(aic3x_reg),
1464 .reg_word_size = sizeof(u8),
1465 .reg_cache_default = aic3x_reg,
1466 .probe = aic3x_probe, 1396 .probe = aic3x_probe,
1467 .remove = aic3x_remove, 1397 .remove = aic3x_remove,
1468 .suspend = aic3x_suspend, 1398 .suspend = aic3x_suspend,
1469 .resume = aic3x_resume, 1399 .resume = aic3x_resume,
1400 .controls = aic3x_snd_controls,
1401 .num_controls = ARRAY_SIZE(aic3x_snd_controls),
1402 .dapm_widgets = aic3x_dapm_widgets,
1403 .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
1404 .dapm_routes = intercon,
1405 .num_dapm_routes = ARRAY_SIZE(intercon),
1470}; 1406};
1471 1407
1472/* 1408/*
@@ -1483,6 +1419,16 @@ static const struct i2c_device_id aic3x_i2c_id[] = {
1483}; 1419};
1484MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1420MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1485 1421
1422static const struct reg_default aic3007_class_d[] = {
1423 /* Class-D speaker driver init; datasheet p. 46 */
1424 { AIC3X_PAGE_SELECT, 0x0D },
1425 { 0xD, 0x0D },
1426 { 0x8, 0x5C },
1427 { 0x8, 0x5D },
1428 { 0x8, 0x5C },
1429 { AIC3X_PAGE_SELECT, 0x00 },
1430};
1431
1486/* 1432/*
1487 * If the i2c layer weren't so broken, we could pass this kind of data 1433 * If the i2c layer weren't so broken, we could pass this kind of data
1488 * around 1434 * around
@@ -1494,7 +1440,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1494 struct aic3x_priv *aic3x; 1440 struct aic3x_priv *aic3x;
1495 struct aic3x_setup_data *ai3x_setup; 1441 struct aic3x_setup_data *ai3x_setup;
1496 struct device_node *np = i2c->dev.of_node; 1442 struct device_node *np = i2c->dev.of_node;
1497 int ret; 1443 int ret, i;
1498 u32 value; 1444 u32 value;
1499 1445
1500 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); 1446 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1503,7 +1449,13 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1503 return -ENOMEM; 1449 return -ENOMEM;
1504 } 1450 }
1505 1451
1506 aic3x->control_type = SND_SOC_I2C; 1452 aic3x->regmap = devm_regmap_init_i2c(i2c, &aic3x_regmap);
1453 if (IS_ERR(aic3x->regmap)) {
1454 ret = PTR_ERR(aic3x->regmap);
1455 return ret;
1456 }
1457
1458 regcache_cache_only(aic3x->regmap, true);
1507 1459
1508 i2c_set_clientdata(i2c, aic3x); 1460 i2c_set_clientdata(i2c, aic3x);
1509 if (pdata) { 1461 if (pdata) {
@@ -1555,14 +1507,54 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1555 1507
1556 aic3x->model = id->driver_data; 1508 aic3x->model = id->driver_data;
1557 1509
1510 if (gpio_is_valid(aic3x->gpio_reset) &&
1511 !aic3x_is_shared_reset(aic3x)) {
1512 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1513 if (ret != 0)
1514 goto err;
1515 gpio_direction_output(aic3x->gpio_reset, 0);
1516 }
1517
1518 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1519 aic3x->supplies[i].supply = aic3x_supply_names[i];
1520
1521 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(aic3x->supplies),
1522 aic3x->supplies);
1523 if (ret != 0) {
1524 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
1525 goto err_gpio;
1526 }
1527
1528 if (aic3x->model == AIC3X_MODEL_3007) {
1529 ret = regmap_register_patch(aic3x->regmap, aic3007_class_d,
1530 ARRAY_SIZE(aic3007_class_d));
1531 if (ret != 0)
1532 dev_err(&i2c->dev, "Failed to init class D: %d\n",
1533 ret);
1534 }
1535
1558 ret = snd_soc_register_codec(&i2c->dev, 1536 ret = snd_soc_register_codec(&i2c->dev,
1559 &soc_codec_dev_aic3x, &aic3x_dai, 1); 1537 &soc_codec_dev_aic3x, &aic3x_dai, 1);
1560 return ret; 1538 return ret;
1539
1540err_gpio:
1541 if (gpio_is_valid(aic3x->gpio_reset) &&
1542 !aic3x_is_shared_reset(aic3x))
1543 gpio_free(aic3x->gpio_reset);
1544err:
1545 return ret;
1561} 1546}
1562 1547
1563static int aic3x_i2c_remove(struct i2c_client *client) 1548static int aic3x_i2c_remove(struct i2c_client *client)
1564{ 1549{
1550 struct aic3x_priv *aic3x = i2c_get_clientdata(client);
1551
1565 snd_soc_unregister_codec(&client->dev); 1552 snd_soc_unregister_codec(&client->dev);
1553 if (gpio_is_valid(aic3x->gpio_reset) &&
1554 !aic3x_is_shared_reset(aic3x)) {
1555 gpio_set_value(aic3x->gpio_reset, 0);
1556 gpio_free(aic3x->gpio_reset);
1557 }
1566 return 0; 1558 return 0;
1567} 1559}
1568 1560