aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8991.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8991.c')
-rw-r--r--sound/soc/codecs/wm8991.c293
1 files changed, 153 insertions, 140 deletions
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 3a39df7a3829..dba0306c42a5 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -31,77 +32,84 @@
31#include "wm8991.h" 32#include "wm8991.h"
32 33
33struct wm8991_priv { 34struct wm8991_priv {
34 enum snd_soc_control_type control_type; 35 struct regmap *regmap;
35 unsigned int pcmclk; 36 unsigned int pcmclk;
36}; 37};
37 38
38static const u16 wm8991_reg_defs[] = { 39static const struct reg_default wm8991_reg_defaults[] = {
39 0x8991, /* R0 - Reset */ 40 { 1, 0x0000 }, /* R1 - Power Management (1) */
40 0x0000, /* R1 - Power Management (1) */ 41 { 2, 0x6000 }, /* R2 - Power Management (2) */
41 0x6000, /* R2 - Power Management (2) */ 42 { 3, 0x0000 }, /* R3 - Power Management (3) */
42 0x0000, /* R3 - Power Management (3) */ 43 { 4, 0x4050 }, /* R4 - Audio Interface (1) */
43 0x4050, /* R4 - Audio Interface (1) */ 44 { 5, 0x4000 }, /* R5 - Audio Interface (2) */
44 0x4000, /* R5 - Audio Interface (2) */ 45 { 6, 0x01C8 }, /* R6 - Clocking (1) */
45 0x01C8, /* R6 - Clocking (1) */ 46 { 7, 0x0000 }, /* R7 - Clocking (2) */
46 0x0000, /* R7 - Clocking (2) */ 47 { 8, 0x0040 }, /* R8 - Audio Interface (3) */
47 0x0040, /* R8 - Audio Interface (3) */ 48 { 9, 0x0040 }, /* R9 - Audio Interface (4) */
48 0x0040, /* R9 - Audio Interface (4) */ 49 { 10, 0x0004 }, /* R10 - DAC CTRL */
49 0x0004, /* R10 - DAC CTRL */ 50 { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */
50 0x00C0, /* R11 - Left DAC Digital Volume */ 51 { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */
51 0x00C0, /* R12 - Right DAC Digital Volume */ 52 { 13, 0x0000 }, /* R13 - Digital Side Tone */
52 0x0000, /* R13 - Digital Side Tone */ 53 { 14, 0x0100 }, /* R14 - ADC CTRL */
53 0x0100, /* R14 - ADC CTRL */ 54 { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */
54 0x00C0, /* R15 - Left ADC Digital Volume */ 55 { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */
55 0x00C0, /* R16 - Right ADC Digital Volume */ 56
56 0x0000, /* R17 */ 57 { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */
57 0x0000, /* R18 - GPIO CTRL 1 */ 58 { 19, 0x1000 }, /* R19 - GPIO1 & GPIO2 */
58 0x1000, /* R19 - GPIO1 & GPIO2 */ 59 { 20, 0x1010 }, /* R20 - GPIO3 & GPIO4 */
59 0x1010, /* R20 - GPIO3 & GPIO4 */ 60 { 21, 0x1010 }, /* R21 - GPIO5 & GPIO6 */
60 0x1010, /* R21 - GPIO5 & GPIO6 */ 61 { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */
61 0x8000, /* R22 - GPIOCTRL 2 */ 62 { 23, 0x0800 }, /* R23 - GPIO_POL */
62 0x0800, /* R23 - GPIO_POL */ 63 { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */
63 0x008B, /* R24 - Left Line Input 1&2 Volume */ 64 { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */
64 0x008B, /* R25 - Left Line Input 3&4 Volume */ 65 { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */
65 0x008B, /* R26 - Right Line Input 1&2 Volume */ 66 { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */
66 0x008B, /* R27 - Right Line Input 3&4 Volume */ 67 { 28, 0x0000 }, /* R28 - Left Output Volume */
67 0x0000, /* R28 - Left Output Volume */ 68 { 29, 0x0000 }, /* R29 - Right Output Volume */
68 0x0000, /* R29 - Right Output Volume */ 69 { 30, 0x0066 }, /* R30 - Line Outputs Volume */
69 0x0066, /* R30 - Line Outputs Volume */ 70 { 31, 0x0022 }, /* R31 - Out3/4 Volume */
70 0x0022, /* R31 - Out3/4 Volume */ 71 { 32, 0x0079 }, /* R32 - Left OPGA Volume */
71 0x0079, /* R32 - Left OPGA Volume */ 72 { 33, 0x0079 }, /* R33 - Right OPGA Volume */
72 0x0079, /* R33 - Right OPGA Volume */ 73 { 34, 0x0003 }, /* R34 - Speaker Volume */
73 0x0003, /* R34 - Speaker Volume */ 74 { 35, 0x0003 }, /* R35 - ClassD1 */
74 0x0003, /* R35 - ClassD1 */ 75
75 0x0000, /* R36 */ 76 { 37, 0x0100 }, /* R37 - ClassD3 */
76 0x0100, /* R37 - ClassD3 */ 77
77 0x0000, /* R38 */ 78 { 39, 0x0000 }, /* R39 - Input Mixer1 */
78 0x0000, /* R39 - Input Mixer1 */ 79 { 40, 0x0000 }, /* R40 - Input Mixer2 */
79 0x0000, /* R40 - Input Mixer2 */ 80 { 41, 0x0000 }, /* R41 - Input Mixer3 */
80 0x0000, /* R41 - Input Mixer3 */ 81 { 42, 0x0000 }, /* R42 - Input Mixer4 */
81 0x0000, /* R42 - Input Mixer4 */ 82 { 43, 0x0000 }, /* R43 - Input Mixer5 */
82 0x0000, /* R43 - Input Mixer5 */ 83 { 44, 0x0000 }, /* R44 - Input Mixer6 */
83 0x0000, /* R44 - Input Mixer6 */ 84 { 45, 0x0000 }, /* R45 - Output Mixer1 */
84 0x0000, /* R45 - Output Mixer1 */ 85 { 46, 0x0000 }, /* R46 - Output Mixer2 */
85 0x0000, /* R46 - Output Mixer2 */ 86 { 47, 0x0000 }, /* R47 - Output Mixer3 */
86 0x0000, /* R47 - Output Mixer3 */ 87 { 48, 0x0000 }, /* R48 - Output Mixer4 */
87 0x0000, /* R48 - Output Mixer4 */ 88 { 49, 0x0000 }, /* R49 - Output Mixer5 */
88 0x0000, /* R49 - Output Mixer5 */ 89 { 50, 0x0000 }, /* R50 - Output Mixer6 */
89 0x0000, /* R50 - Output Mixer6 */ 90 { 51, 0x0180 }, /* R51 - Out3/4 Mixer */
90 0x0180, /* R51 - Out3/4 Mixer */ 91 { 52, 0x0000 }, /* R52 - Line Mixer1 */
91 0x0000, /* R52 - Line Mixer1 */ 92 { 53, 0x0000 }, /* R53 - Line Mixer2 */
92 0x0000, /* R53 - Line Mixer2 */ 93 { 54, 0x0000 }, /* R54 - Speaker Mixer */
93 0x0000, /* R54 - Speaker Mixer */ 94 { 55, 0x0000 }, /* R55 - Additional Control */
94 0x0000, /* R55 - Additional Control */ 95 { 56, 0x0000 }, /* R56 - AntiPOP1 */
95 0x0000, /* R56 - AntiPOP1 */ 96 { 57, 0x0000 }, /* R57 - AntiPOP2 */
96 0x0000, /* R57 - AntiPOP2 */ 97 { 58, 0x0000 }, /* R58 - MICBIAS */
97 0x0000, /* R58 - MICBIAS */ 98
98 0x0000, /* R59 */ 99 { 60, 0x0008 }, /* R60 - PLL1 */
99 0x0008, /* R60 - PLL1 */ 100 { 61, 0x0031 }, /* R61 - PLL2 */
100 0x0031, /* R61 - PLL2 */ 101 { 62, 0x0026 }, /* R62 - PLL3 */
101 0x0026, /* R62 - PLL3 */
102}; 102};
103 103
104#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0) 104static bool wm8991_volatile(struct device *dev, unsigned int reg)
105{
106 switch (reg) {
107 case WM8991_RESET:
108 return true;
109 default:
110 return false;
111 }
112}
105 113
106static const unsigned int rec_mix_tlv[] = { 114static const unsigned int rec_mix_tlv[] = {
107 TLV_DB_RANGE_HEAD(1), 115 TLV_DB_RANGE_HEAD(1),
@@ -374,30 +382,6 @@ static const struct snd_kcontrol_new wm8991_snd_controls[] = {
374/* 382/*
375 * _DAPM_ Controls 383 * _DAPM_ Controls
376 */ 384 */
377static int inmixer_event(struct snd_soc_dapm_widget *w,
378 struct snd_kcontrol *kcontrol, int event)
379{
380 u16 reg, fakepower;
381
382 reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2);
383 fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS);
384
385 if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) |
386 (1 << WM8991_AINLMUX_PWR_BIT)))
387 reg |= WM8991_AINL_ENA;
388 else
389 reg &= ~WM8991_AINL_ENA;
390
391 if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) |
392 (1 << WM8991_AINRMUX_PWR_BIT)))
393 reg |= WM8991_AINR_ENA;
394 else
395 reg &= ~WM8991_AINR_ENA;
396
397 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
398 return 0;
399}
400
401static int outmixer_event(struct snd_soc_dapm_widget *w, 385static int outmixer_event(struct snd_soc_dapm_widget *w,
402 struct snd_kcontrol *kcontrol, int event) 386 struct snd_kcontrol *kcontrol, int event)
403{ 387{
@@ -655,6 +639,11 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
655 SND_SOC_DAPM_INPUT("RIN2"), 639 SND_SOC_DAPM_INPUT("RIN2"),
656 SND_SOC_DAPM_INPUT("Internal ADC Source"), 640 SND_SOC_DAPM_INPUT("Internal ADC Source"),
657 641
642 SND_SOC_DAPM_SUPPLY("INL", WM8991_POWER_MANAGEMENT_2,
643 WM8991_AINL_ENA_BIT, 0, NULL, 0),
644 SND_SOC_DAPM_SUPPLY("INR", WM8991_POWER_MANAGEMENT_2,
645 WM8991_AINR_ENA_BIT, 0, NULL, 0),
646
658 /* DACs */ 647 /* DACs */
659 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2, 648 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2,
660 WM8991_ADCL_ENA_BIT, 0), 649 WM8991_ADCL_ENA_BIT, 0),
@@ -676,26 +665,22 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
676 ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)), 665 ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)),
677 666
678 /* INMIXL */ 667 /* INMIXL */
679 SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0, 668 SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0,
680 &wm8991_dapm_inmixl_controls[0], 669 &wm8991_dapm_inmixl_controls[0],
681 ARRAY_SIZE(wm8991_dapm_inmixl_controls), 670 ARRAY_SIZE(wm8991_dapm_inmixl_controls)),
682 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
683 671
684 /* AINLMUX */ 672 /* AINLMUX */
685 SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0, 673 SND_SOC_DAPM_MUX("AINLMUX", SND_SOC_NOPM, 0, 0,
686 &wm8991_dapm_ainlmux_controls, inmixer_event, 674 &wm8991_dapm_ainlmux_controls),
687 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
688 675
689 /* INMIXR */ 676 /* INMIXR */
690 SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0, 677 SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0,
691 &wm8991_dapm_inmixr_controls[0], 678 &wm8991_dapm_inmixr_controls[0],
692 ARRAY_SIZE(wm8991_dapm_inmixr_controls), 679 ARRAY_SIZE(wm8991_dapm_inmixr_controls)),
693 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
694 680
695 /* AINRMUX */ 681 /* AINRMUX */
696 SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0, 682 SND_SOC_DAPM_MUX("AINRMUX", SND_SOC_NOPM, 0, 0,
697 &wm8991_dapm_ainrmux_controls, inmixer_event, 683 &wm8991_dapm_ainrmux_controls),
698 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
699 684
700 /* Output Side */ 685 /* Output Side */
701 /* DACs */ 686 /* DACs */
@@ -787,7 +772,7 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
787 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"), 772 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
788}; 773};
789 774
790static const struct snd_soc_dapm_route audio_map[] = { 775static const struct snd_soc_dapm_route wm8991_dapm_routes[] = {
791 /* Make DACs turn on when playing even if not mixed into any outputs */ 776 /* Make DACs turn on when playing even if not mixed into any outputs */
792 {"Internal DAC Sink", NULL, "Left DAC"}, 777 {"Internal DAC Sink", NULL, "Left DAC"},
793 {"Internal DAC Sink", NULL, "Right DAC"}, 778 {"Internal DAC Sink", NULL, "Right DAC"},
@@ -797,6 +782,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
797 {"Right ADC", NULL, "Internal ADC Source"}, 782 {"Right ADC", NULL, "Internal ADC Source"},
798 783
799 /* Input Side */ 784 /* Input Side */
785 {"INMIXL", NULL, "INL"},
786 {"AINLMUX", NULL, "INL"},
787 {"INMIXR", NULL, "INR"},
788 {"AINRMUX", NULL, "INR"},
800 /* LIN12 PGA */ 789 /* LIN12 PGA */
801 {"LIN12 PGA", "LIN1 Switch", "LIN1"}, 790 {"LIN12 PGA", "LIN1 Switch", "LIN1"},
802 {"LIN12 PGA", "LIN2 Switch", "LIN2"}, 791 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
@@ -1129,6 +1118,7 @@ static int wm8991_mute(struct snd_soc_dai *dai, int mute)
1129static int wm8991_set_bias_level(struct snd_soc_codec *codec, 1118static int wm8991_set_bias_level(struct snd_soc_codec *codec,
1130 enum snd_soc_bias_level level) 1119 enum snd_soc_bias_level level)
1131{ 1120{
1121 struct wm8991_priv *wm8991 = snd_soc_codec_get_drvdata(codec);
1132 u16 val; 1122 u16 val;
1133 1123
1134 switch (level) { 1124 switch (level) {
@@ -1144,7 +1134,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec,
1144 1134
1145 case SND_SOC_BIAS_STANDBY: 1135 case SND_SOC_BIAS_STANDBY:
1146 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1136 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1147 snd_soc_cache_sync(codec); 1137 regcache_sync(wm8991->regmap);
1148 /* Enable all output discharge bits */ 1138 /* Enable all output discharge bits */
1149 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE | 1139 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1150 WM8991_DIS_RLINE | WM8991_DIS_OUT3 | 1140 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
@@ -1232,7 +1222,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec,
1232 1222
1233 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1223 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1234 snd_soc_write(codec, WM8991_ANTIPOP2, 0x0); 1224 snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
1235 codec->cache_sync = 1; 1225 regcache_mark_dirty(wm8991->regmap);
1236 break; 1226 break;
1237 } 1227 }
1238 1228
@@ -1266,44 +1256,14 @@ static int wm8991_probe(struct snd_soc_codec *codec)
1266 1256
1267 wm8991 = snd_soc_codec_get_drvdata(codec); 1257 wm8991 = snd_soc_codec_get_drvdata(codec);
1268 1258
1269 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type); 1259 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1270 if (ret < 0) { 1260 if (ret < 0) {
1271 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); 1261 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1272 return ret; 1262 return ret;
1273 } 1263 }
1274 1264
1275 ret = wm8991_reset(codec);
1276 if (ret < 0) {
1277 dev_err(codec->dev, "Failed to issue reset\n");
1278 return ret;
1279 }
1280
1281 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1265 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1282 1266
1283 snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4,
1284 WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
1285
1286 snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2,
1287 WM8991_GPIO1_SEL_MASK, 1);
1288
1289 snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1,
1290 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
1291 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
1292
1293 snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2,
1294 WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
1295
1296 snd_soc_write(codec, WM8991_DAC_CTRL, 0);
1297 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1298 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1299
1300 snd_soc_add_codec_controls(codec, wm8991_snd_controls,
1301 ARRAY_SIZE(wm8991_snd_controls));
1302
1303 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
1304 ARRAY_SIZE(wm8991_dapm_widgets));
1305 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1306 ARRAY_SIZE(audio_map));
1307 return 0; 1267 return 0;
1308} 1268}
1309 1269
@@ -1352,24 +1312,77 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
1352 .suspend = wm8991_suspend, 1312 .suspend = wm8991_suspend,
1353 .resume = wm8991_resume, 1313 .resume = wm8991_resume,
1354 .set_bias_level = wm8991_set_bias_level, 1314 .set_bias_level = wm8991_set_bias_level,
1355 .reg_cache_size = WM8991_MAX_REGISTER + 1, 1315 .controls = wm8991_snd_controls,
1356 .reg_word_size = sizeof(u16), 1316 .num_controls = ARRAY_SIZE(wm8991_snd_controls),
1357 .reg_cache_default = wm8991_reg_defs 1317 .dapm_widgets = wm8991_dapm_widgets,
1318 .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets),
1319 .dapm_routes = wm8991_dapm_routes,
1320 .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes),
1321};
1322
1323static const struct regmap_config wm8991_regmap = {
1324 .reg_bits = 8,
1325 .val_bits = 16,
1326
1327 .max_register = WM8991_PLL3,
1328 .volatile_reg = wm8991_volatile,
1329 .reg_defaults = wm8991_reg_defaults,
1330 .num_reg_defaults = ARRAY_SIZE(wm8991_reg_defaults),
1331 .cache_type = REGCACHE_RBTREE,
1358}; 1332};
1359 1333
1360static int wm8991_i2c_probe(struct i2c_client *i2c, 1334static int wm8991_i2c_probe(struct i2c_client *i2c,
1361 const struct i2c_device_id *id) 1335 const struct i2c_device_id *id)
1362{ 1336{
1363 struct wm8991_priv *wm8991; 1337 struct wm8991_priv *wm8991;
1338 unsigned int val;
1364 int ret; 1339 int ret;
1365 1340
1366 wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL); 1341 wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL);
1367 if (!wm8991) 1342 if (!wm8991)
1368 return -ENOMEM; 1343 return -ENOMEM;
1369 1344
1370 wm8991->control_type = SND_SOC_I2C; 1345 wm8991->regmap = devm_regmap_init_i2c(i2c, &wm8991_regmap);
1346 if (IS_ERR(wm8991->regmap))
1347 return PTR_ERR(wm8991->regmap);
1348
1371 i2c_set_clientdata(i2c, wm8991); 1349 i2c_set_clientdata(i2c, wm8991);
1372 1350
1351 ret = regmap_read(wm8991->regmap, WM8991_RESET, &val);
1352 if (ret != 0) {
1353 dev_err(&i2c->dev, "Failed to read device ID: %d\n", ret);
1354 return ret;
1355 }
1356 if (val != 0x8991) {
1357 dev_err(&i2c->dev, "Device with ID %x is not a WM8991\n", val);
1358 return -EINVAL;
1359 }
1360
1361 ret = regmap_write(wm8991->regmap, WM8991_RESET, 0);
1362 if (ret < 0) {
1363 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
1364 return ret;
1365 }
1366
1367 regmap_update_bits(wm8991->regmap, WM8991_AUDIO_INTERFACE_4,
1368 WM8991_ALRCGPIO1, WM8991_ALRCGPIO1);
1369
1370 regmap_update_bits(wm8991->regmap, WM8991_GPIO1_GPIO2,
1371 WM8991_GPIO1_SEL_MASK, 1);
1372
1373 regmap_update_bits(wm8991->regmap, WM8991_POWER_MANAGEMENT_1,
1374 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK,
1375 WM8991_VREF_ENA | WM8991_VMID_MODE_MASK);
1376
1377 regmap_update_bits(wm8991->regmap, WM8991_POWER_MANAGEMENT_2,
1378 WM8991_OPCLK_ENA, WM8991_OPCLK_ENA);
1379
1380 regmap_write(wm8991->regmap, WM8991_DAC_CTRL, 0);
1381 regmap_write(wm8991->regmap, WM8991_LEFT_OUTPUT_VOLUME,
1382 0x50 | (1<<8));
1383 regmap_write(wm8991->regmap, WM8991_RIGHT_OUTPUT_VOLUME,
1384 0x50 | (1<<8));
1385
1373 ret = snd_soc_register_codec(&i2c->dev, 1386 ret = snd_soc_register_codec(&i2c->dev,
1374 &soc_codec_dev_wm8991, &wm8991_dai, 1); 1387 &soc_codec_dev_wm8991, &wm8991_dai, 1);
1375 1388