aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /sound/soc/codecs
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/88pm860x-codec.c1490
-rw-r--r--sound/soc/codecs/88pm860x-codec.h97
-rw-r--r--sound/soc/codecs/Kconfig99
-rw-r--r--sound/soc/codecs/Makefile48
-rw-r--r--sound/soc/codecs/ac97.c125
-rw-r--r--sound/soc/codecs/ac97.h19
-rw-r--r--sound/soc/codecs/ad1836.c210
-rw-r--r--sound/soc/codecs/ad1836.h8
-rw-r--r--sound/soc/codecs/ad193x.c214
-rw-r--r--sound/soc/codecs/ad193x.h3
-rw-r--r--sound/soc/codecs/ad1980.c114
-rw-r--r--sound/soc/codecs/ad1980.h3
-rw-r--r--sound/soc/codecs/ad73311.c66
-rw-r--r--sound/soc/codecs/ad73311.h2
-rw-r--r--sound/soc/codecs/ads117x.c72
-rw-r--r--sound/soc/codecs/ads117x.h4
-rw-r--r--sound/soc/codecs/ak4104.c150
-rw-r--r--sound/soc/codecs/ak4104.h7
-rw-r--r--sound/soc/codecs/ak4535.c261
-rw-r--r--sound/soc/codecs/ak4535.h8
-rw-r--r--sound/soc/codecs/ak4641.c664
-rw-r--r--sound/soc/codecs/ak4641.h47
-rw-r--r--sound/soc/codecs/ak4642.c263
-rw-r--r--sound/soc/codecs/ak4642.h20
-rw-r--r--sound/soc/codecs/ak4671.c161
-rw-r--r--sound/soc/codecs/ak4671.h3
-rw-r--r--sound/soc/codecs/alc5623.c1117
-rw-r--r--sound/soc/codecs/alc5623.h161
-rw-r--r--sound/soc/codecs/cq93vc.c136
-rw-r--r--sound/soc/codecs/cq93vc.h29
-rw-r--r--sound/soc/codecs/cs4270.c516
-rw-r--r--sound/soc/codecs/cs4270.h28
-rw-r--r--sound/soc/codecs/cs4271.c667
-rw-r--r--sound/soc/codecs/cs42l51.c302
-rw-r--r--sound/soc/codecs/cs42l51.h2
-rw-r--r--sound/soc/codecs/cx20442.c198
-rw-r--r--sound/soc/codecs/cx20442.h2
-rw-r--r--sound/soc/codecs/da7210.c165
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/dfbmcs320.c72
-rw-r--r--sound/soc/codecs/dmic.c105
-rw-r--r--sound/soc/codecs/jz4740.c137
-rw-r--r--sound/soc/codecs/jz4740.h20
-rw-r--r--sound/soc/codecs/lm4857.c276
-rw-r--r--sound/soc/codecs/max98088.c2125
-rw-r--r--sound/soc/codecs/max98088.h206
-rw-r--r--sound/soc/codecs/max98095.c2396
-rw-r--r--sound/soc/codecs/max98095.h299
-rw-r--r--sound/soc/codecs/max9850.c389
-rw-r--r--sound/soc/codecs/max9850.h38
-rw-r--r--sound/soc/codecs/pcm3008.c92
-rw-r--r--sound/soc/codecs/pcm3008.h3
-rw-r--r--sound/soc/codecs/sgtl5000.c1527
-rw-r--r--sound/soc/codecs/sgtl5000.h400
-rw-r--r--sound/soc/codecs/sn95031.c944
-rw-r--r--sound/soc/codecs/sn95031.h132
-rw-r--r--sound/soc/codecs/spdif_transciever.c110
-rw-r--r--sound/soc/codecs/spdif_transciever.h18
-rw-r--r--sound/soc/codecs/ssm2602.c652
-rw-r--r--sound/soc/codecs/ssm2602.h9
-rw-r--r--sound/soc/codecs/stac9766.c121
-rw-r--r--sound/soc/codecs/stac9766.h4
-rw-r--r--sound/soc/codecs/tlv320aic23.c203
-rw-r--r--sound/soc/codecs/tlv320aic23.h3
-rw-r--r--sound/soc/codecs/tlv320aic26.c195
-rw-r--r--sound/soc/codecs/tlv320aic26.h7
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c794
-rw-r--r--sound/soc/codecs/tlv320aic32x4.h143
-rw-r--r--sound/soc/codecs/tlv320aic3x.c1297
-rw-r--r--sound/soc/codecs/tlv320aic3x.h100
-rw-r--r--sound/soc/codecs/tlv320dac33.c672
-rw-r--r--sound/soc/codecs/tlv320dac33.h5
-rw-r--r--sound/soc/codecs/tpa6130a2.c135
-rw-r--r--sound/soc/codecs/tpa6130a2.h3
-rw-r--r--sound/soc/codecs/twl4030.c284
-rw-r--r--sound/soc/codecs/twl4030.h55
-rw-r--r--sound/soc/codecs/twl6040.c1025
-rw-r--r--sound/soc/codecs/twl6040.h9
-rw-r--r--sound/soc/codecs/uda134x.c157
-rw-r--r--sound/soc/codecs/uda134x.h3
-rw-r--r--sound/soc/codecs/uda1380.c342
-rw-r--r--sound/soc/codecs/uda1380.h3
-rw-r--r--sound/soc/codecs/wl1273.c527
-rw-r--r--sound/soc/codecs/wl1273.h30
-rw-r--r--sound/soc/codecs/wm1250-ev1.c108
-rw-r--r--sound/soc/codecs/wm2000.c20
-rw-r--r--sound/soc/codecs/wm2000.h3
-rw-r--r--sound/soc/codecs/wm8350.c343
-rw-r--r--sound/soc/codecs/wm8350.h3
-rw-r--r--sound/soc/codecs/wm8400.c194
-rw-r--r--sound/soc/codecs/wm8400.h3
-rw-r--r--sound/soc/codecs/wm8510.c300
-rw-r--r--sound/soc/codecs/wm8510.h3
-rw-r--r--sound/soc/codecs/wm8523.c201
-rw-r--r--sound/soc/codecs/wm8523.h3
-rw-r--r--sound/soc/codecs/wm8580.c340
-rw-r--r--sound/soc/codecs/wm8580.h17
-rw-r--r--sound/soc/codecs/wm8711.c222
-rw-r--r--sound/soc/codecs/wm8711.h3
-rw-r--r--sound/soc/codecs/wm8727.c106
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c311
-rw-r--r--sound/soc/codecs/wm8728.h9
-rw-r--r--sound/soc/codecs/wm8731.c376
-rw-r--r--sound/soc/codecs/wm8731.h7
-rw-r--r--sound/soc/codecs/wm8737.c754
-rw-r--r--sound/soc/codecs/wm8737.h322
-rw-r--r--sound/soc/codecs/wm8741.c391
-rw-r--r--sound/soc/codecs/wm8741.h3
-rw-r--r--sound/soc/codecs/wm8750.c277
-rw-r--r--sound/soc/codecs/wm8750.h9
-rw-r--r--sound/soc/codecs/wm8753.c875
-rw-r--r--sound/soc/codecs/wm8753.h3
-rw-r--r--sound/soc/codecs/wm8770.c749
-rw-r--r--sound/soc/codecs/wm8770.h51
-rw-r--r--sound/soc/codecs/wm8776.c259
-rw-r--r--sound/soc/codecs/wm8776.h3
-rw-r--r--sound/soc/codecs/wm8804.c837
-rw-r--r--sound/soc/codecs/wm8804.h61
-rw-r--r--sound/soc/codecs/wm8900.c265
-rw-r--r--sound/soc/codecs/wm8900.h3
-rw-r--r--sound/soc/codecs/wm8903.c1148
-rw-r--r--sound/soc/codecs/wm8903.h38
-rw-r--r--sound/soc/codecs/wm8904.c307
-rw-r--r--sound/soc/codecs/wm8904.h3
-rw-r--r--sound/soc/codecs/wm8915.c2931
-rw-r--r--sound/soc/codecs/wm8915.h3717
-rw-r--r--sound/soc/codecs/wm8940.c206
-rw-r--r--sound/soc/codecs/wm8940.h2
-rw-r--r--sound/soc/codecs/wm8955.c238
-rw-r--r--sound/soc/codecs/wm8955.h3
-rw-r--r--sound/soc/codecs/wm8958-dsp2.c1051
-rw-r--r--sound/soc/codecs/wm8960.c242
-rw-r--r--sound/soc/codecs/wm8960.h3
-rw-r--r--sound/soc/codecs/wm8961.c252
-rw-r--r--sound/soc/codecs/wm8961.h3
-rw-r--r--sound/soc/codecs/wm8962.c4045
-rw-r--r--sound/soc/codecs/wm8962.h3780
-rw-r--r--sound/soc/codecs/wm8971.c276
-rw-r--r--sound/soc/codecs/wm8971.h8
-rw-r--r--sound/soc/codecs/wm8974.c180
-rw-r--r--sound/soc/codecs/wm8974.h3
-rw-r--r--sound/soc/codecs/wm8978.c222
-rw-r--r--sound/soc/codecs/wm8978.h3
-rw-r--r--sound/soc/codecs/wm8985.c1192
-rw-r--r--sound/soc/codecs/wm8985.h1045
-rw-r--r--sound/soc/codecs/wm8988.c268
-rw-r--r--sound/soc/codecs/wm8988.h3
-rw-r--r--sound/soc/codecs/wm8990.c245
-rw-r--r--sound/soc/codecs/wm8990.h8
-rw-r--r--sound/soc/codecs/wm8991.c1426
-rw-r--r--sound/soc/codecs/wm8991.h833
-rw-r--r--sound/soc/codecs/wm8993.c332
-rw-r--r--sound/soc/codecs/wm8993.h3
-rw-r--r--sound/soc/codecs/wm8994-tables.c3147
-rw-r--r--sound/soc/codecs/wm8994.c2916
-rw-r--r--sound/soc/codecs/wm8994.h112
-rw-r--r--sound/soc/codecs/wm8995.c1911
-rw-r--r--sound/soc/codecs/wm8995.h4269
-rw-r--r--sound/soc/codecs/wm9081.c297
-rw-r--r--sound/soc/codecs/wm9081.h3
-rw-r--r--sound/soc/codecs/wm9090.c216
-rw-r--r--sound/soc/codecs/wm9090.h2
-rw-r--r--sound/soc/codecs/wm9705.c133
-rw-r--r--sound/soc/codecs/wm9705.h3
-rw-r--r--sound/soc/codecs/wm9712.c144
-rw-r--r--sound/soc/codecs/wm9712.h3
-rw-r--r--sound/soc/codecs/wm9713.c151
-rw-r--r--sound/soc/codecs/wm9713.h3
-rw-r--r--sound/soc/codecs/wm_hubs.c171
-rw-r--r--sound/soc/codecs/wm_hubs.h3
171 files changed, 55551 insertions, 12976 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
new file mode 100644
index 000000000000..19241576b6b5
--- /dev/null
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -0,0 +1,1490 @@
1/*
2 * 88pm860x-codec.c -- 88PM860x ALSA SoC Audio Driver
3 *
4 * Copyright 2010 Marvell International Ltd.
5 * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/i2c.h>
15#include <linux/platform_device.h>
16#include <linux/mfd/88pm860x.h>
17#include <linux/slab.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/tlv.h>
23#include <sound/initval.h>
24#include <sound/jack.h>
25#include <trace/events/asoc.h>
26
27#include "88pm860x-codec.h"
28
29#define MAX_NAME_LEN 20
30#define REG_CACHE_SIZE 0x40
31#define REG_CACHE_BASE 0xb0
32
33/* Status Register 1 (0x01) */
34#define REG_STATUS_1 0x01
35#define MIC_STATUS (1 << 7)
36#define HOOK_STATUS (1 << 6)
37#define HEADSET_STATUS (1 << 5)
38
39/* Mic Detection Register (0x37) */
40#define REG_MIC_DET 0x37
41#define CONTINUOUS_POLLING (3 << 1)
42#define EN_MIC_DET (1 << 0)
43#define MICDET_MASK 0x07
44
45/* Headset Detection Register (0x38) */
46#define REG_HS_DET 0x38
47#define EN_HS_DET (1 << 0)
48
49/* Misc2 Register (0x42) */
50#define REG_MISC2 0x42
51#define AUDIO_PLL (1 << 5)
52#define AUDIO_SECTION_RESET (1 << 4)
53#define AUDIO_SECTION_ON (1 << 3)
54
55/* PCM Interface Register 2 (0xb1) */
56#define PCM_INF2_BCLK (1 << 6) /* Bit clock polarity */
57#define PCM_INF2_FS (1 << 5) /* Frame Sync polarity */
58#define PCM_INF2_MASTER (1 << 4) /* Master / Slave */
59#define PCM_INF2_18WL (1 << 3) /* 18 / 16 bits */
60#define PCM_GENERAL_I2S 0
61#define PCM_EXACT_I2S 1
62#define PCM_LEFT_I2S 2
63#define PCM_RIGHT_I2S 3
64#define PCM_SHORT_FS 4
65#define PCM_LONG_FS 5
66#define PCM_MODE_MASK 7
67
68/* I2S Interface Register 4 (0xbe) */
69#define I2S_EQU_BYP (1 << 6)
70
71/* DAC Offset Register (0xcb) */
72#define DAC_MUTE (1 << 7)
73#define MUTE_LEFT (1 << 6)
74#define MUTE_RIGHT (1 << 2)
75
76/* ADC Analog Register 1 (0xd0) */
77#define REG_ADC_ANA_1 0xd0
78#define MIC1BIAS_MASK 0x60
79
80/* Earpiece/Speaker Control Register 2 (0xda) */
81#define REG_EAR2 0xda
82#define RSYNC_CHANGE (1 << 2)
83
84/* Audio Supplies Register 2 (0xdc) */
85#define REG_SUPPLIES2 0xdc
86#define LDO15_READY (1 << 4)
87#define LDO15_EN (1 << 3)
88#define CPUMP_READY (1 << 2)
89#define CPUMP_EN (1 << 1)
90#define AUDIO_EN (1 << 0)
91#define SUPPLY_MASK (LDO15_EN | CPUMP_EN | AUDIO_EN)
92
93/* Audio Enable Register 1 (0xdd) */
94#define ADC_MOD_RIGHT (1 << 1)
95#define ADC_MOD_LEFT (1 << 0)
96
97/* Audio Enable Register 2 (0xde) */
98#define ADC_LEFT (1 << 5)
99#define ADC_RIGHT (1 << 4)
100
101/* DAC Enable Register 2 (0xe1) */
102#define DAC_LEFT (1 << 5)
103#define DAC_RIGHT (1 << 4)
104#define MODULATOR (1 << 3)
105
106/* Shorts Register (0xeb) */
107#define REG_SHORTS 0xeb
108#define CLR_SHORT_LO2 (1 << 7)
109#define SHORT_LO2 (1 << 6)
110#define CLR_SHORT_LO1 (1 << 5)
111#define SHORT_LO1 (1 << 4)
112#define CLR_SHORT_HS2 (1 << 3)
113#define SHORT_HS2 (1 << 2)
114#define CLR_SHORT_HS1 (1 << 1)
115#define SHORT_HS1 (1 << 0)
116
117/*
118 * This widget should be just after DAC & PGA in DAPM power-on sequence and
119 * before DAC & PGA in DAPM power-off sequence.
120 */
121#define PM860X_DAPM_OUTPUT(wname, wevent) \
122{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \
123 .shift = 0, .invert = 0, .kcontrol_news = NULL, \
124 .num_kcontrols = 0, .event = wevent, \
125 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD, }
126
127struct pm860x_det {
128 struct snd_soc_jack *hp_jack;
129 struct snd_soc_jack *mic_jack;
130 int hp_det;
131 int mic_det;
132 int hook_det;
133 int hs_shrt;
134 int lo_shrt;
135};
136
137struct pm860x_priv {
138 unsigned int sysclk;
139 unsigned int pcmclk;
140 unsigned int dir;
141 unsigned int filter;
142 struct snd_soc_codec *codec;
143 struct i2c_client *i2c;
144 struct pm860x_chip *chip;
145 struct pm860x_det det;
146
147 int irq[4];
148 unsigned char name[4][MAX_NAME_LEN];
149};
150
151/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */
152static const DECLARE_TLV_DB_SCALE(dpga_tlv, -9450, 150, 1);
153
154/* -9dB to 0db in 3dB steps */
155static const DECLARE_TLV_DB_SCALE(adc_tlv, -900, 300, 0);
156
157/* {-23, -17, -13.5, -11, -9, -6, -3, 0}dB */
158static const unsigned int mic_tlv[] = {
159 TLV_DB_RANGE_HEAD(5),
160 0, 0, TLV_DB_SCALE_ITEM(-2300, 0, 0),
161 1, 1, TLV_DB_SCALE_ITEM(-1700, 0, 0),
162 2, 2, TLV_DB_SCALE_ITEM(-1350, 0, 0),
163 3, 3, TLV_DB_SCALE_ITEM(-1100, 0, 0),
164 4, 7, TLV_DB_SCALE_ITEM(-900, 300, 0),
165};
166
167/* {0, 0, 0, -6, 0, 6, 12, 18}dB */
168static const unsigned int aux_tlv[] = {
169 TLV_DB_RANGE_HEAD(2),
170 0, 2, TLV_DB_SCALE_ITEM(0, 0, 0),
171 3, 7, TLV_DB_SCALE_ITEM(-600, 600, 0),
172};
173
174/* {-16, -13, -10, -7, -5.2, -3,3, -2.2, 0}dB, mute instead of -16dB */
175static const unsigned int out_tlv[] = {
176 TLV_DB_RANGE_HEAD(4),
177 0, 3, TLV_DB_SCALE_ITEM(-1600, 300, 1),
178 4, 4, TLV_DB_SCALE_ITEM(-520, 0, 0),
179 5, 5, TLV_DB_SCALE_ITEM(-330, 0, 0),
180 6, 7, TLV_DB_SCALE_ITEM(-220, 220, 0),
181};
182
183static const unsigned int st_tlv[] = {
184 TLV_DB_RANGE_HEAD(8),
185 0, 1, TLV_DB_SCALE_ITEM(-12041, 602, 0),
186 2, 3, TLV_DB_SCALE_ITEM(-11087, 250, 0),
187 4, 5, TLV_DB_SCALE_ITEM(-10643, 158, 0),
188 6, 7, TLV_DB_SCALE_ITEM(-10351, 116, 0),
189 8, 9, TLV_DB_SCALE_ITEM(-10133, 92, 0),
190 10, 13, TLV_DB_SCALE_ITEM(-9958, 70, 0),
191 14, 17, TLV_DB_SCALE_ITEM(-9689, 53, 0),
192 18, 271, TLV_DB_SCALE_ITEM(-9484, 37, 0),
193};
194
195/* Sidetone Gain = M * 2^(-5-N) */
196struct st_gain {
197 unsigned int db;
198 unsigned int m;
199 unsigned int n;
200};
201
202static struct st_gain st_table[] = {
203 {-12041, 1, 15}, {-11439, 1, 14}, {-11087, 3, 15}, {-10837, 1, 13},
204 {-10643, 5, 15}, {-10485, 3, 14}, {-10351, 7, 15}, {-10235, 1, 12},
205 {-10133, 9, 15}, {-10041, 5, 14}, { -9958, 11, 15}, { -9883, 3, 13},
206 { -9813, 13, 15}, { -9749, 7, 14}, { -9689, 15, 15}, { -9633, 1, 11},
207 { -9580, 17, 15}, { -9531, 9, 14}, { -9484, 19, 15}, { -9439, 5, 13},
208 { -9397, 21, 15}, { -9356, 11, 14}, { -9318, 23, 15}, { -9281, 3, 12},
209 { -9245, 25, 15}, { -9211, 13, 14}, { -9178, 27, 15}, { -9147, 7, 13},
210 { -9116, 29, 15}, { -9087, 15, 14}, { -9058, 31, 15}, { -9031, 1, 10},
211 { -8978, 17, 14}, { -8929, 9, 13}, { -8882, 19, 14}, { -8837, 5, 12},
212 { -8795, 21, 14}, { -8754, 11, 13}, { -8716, 23, 14}, { -8679, 3, 11},
213 { -8643, 25, 14}, { -8609, 13, 13}, { -8576, 27, 14}, { -8545, 7, 12},
214 { -8514, 29, 14}, { -8485, 15, 13}, { -8456, 31, 14}, { -8429, 1, 9},
215 { -8376, 17, 13}, { -8327, 9, 12}, { -8280, 19, 13}, { -8235, 5, 11},
216 { -8193, 21, 13}, { -8152, 11, 12}, { -8114, 23, 13}, { -8077, 3, 10},
217 { -8041, 25, 13}, { -8007, 13, 12}, { -7974, 27, 13}, { -7943, 7, 11},
218 { -7912, 29, 13}, { -7883, 15, 12}, { -7854, 31, 13}, { -7827, 1, 8},
219 { -7774, 17, 12}, { -7724, 9, 11}, { -7678, 19, 12}, { -7633, 5, 10},
220 { -7591, 21, 12}, { -7550, 11, 11}, { -7512, 23, 12}, { -7475, 3, 9},
221 { -7439, 25, 12}, { -7405, 13, 11}, { -7372, 27, 12}, { -7341, 7, 10},
222 { -7310, 29, 12}, { -7281, 15, 11}, { -7252, 31, 12}, { -7225, 1, 7},
223 { -7172, 17, 11}, { -7122, 9, 10}, { -7075, 19, 11}, { -7031, 5, 9},
224 { -6989, 21, 11}, { -6948, 11, 10}, { -6910, 23, 11}, { -6873, 3, 8},
225 { -6837, 25, 11}, { -6803, 13, 10}, { -6770, 27, 11}, { -6739, 7, 9},
226 { -6708, 29, 11}, { -6679, 15, 10}, { -6650, 31, 11}, { -6623, 1, 6},
227 { -6570, 17, 10}, { -6520, 9, 9}, { -6473, 19, 10}, { -6429, 5, 8},
228 { -6386, 21, 10}, { -6346, 11, 9}, { -6307, 23, 10}, { -6270, 3, 7},
229 { -6235, 25, 10}, { -6201, 13, 9}, { -6168, 27, 10}, { -6137, 7, 8},
230 { -6106, 29, 10}, { -6077, 15, 9}, { -6048, 31, 10}, { -6021, 1, 5},
231 { -5968, 17, 9}, { -5918, 9, 8}, { -5871, 19, 9}, { -5827, 5, 7},
232 { -5784, 21, 9}, { -5744, 11, 8}, { -5705, 23, 9}, { -5668, 3, 6},
233 { -5633, 25, 9}, { -5599, 13, 8}, { -5566, 27, 9}, { -5535, 7, 7},
234 { -5504, 29, 9}, { -5475, 15, 8}, { -5446, 31, 9}, { -5419, 1, 4},
235 { -5366, 17, 8}, { -5316, 9, 7}, { -5269, 19, 8}, { -5225, 5, 6},
236 { -5182, 21, 8}, { -5142, 11, 7}, { -5103, 23, 8}, { -5066, 3, 5},
237 { -5031, 25, 8}, { -4997, 13, 7}, { -4964, 27, 8}, { -4932, 7, 6},
238 { -4902, 29, 8}, { -4873, 15, 7}, { -4844, 31, 8}, { -4816, 1, 3},
239 { -4764, 17, 7}, { -4714, 9, 6}, { -4667, 19, 7}, { -4623, 5, 5},
240 { -4580, 21, 7}, { -4540, 11, 6}, { -4501, 23, 7}, { -4464, 3, 4},
241 { -4429, 25, 7}, { -4395, 13, 6}, { -4362, 27, 7}, { -4330, 7, 5},
242 { -4300, 29, 7}, { -4270, 15, 6}, { -4242, 31, 7}, { -4214, 1, 2},
243 { -4162, 17, 6}, { -4112, 9, 5}, { -4065, 19, 6}, { -4021, 5, 4},
244 { -3978, 21, 6}, { -3938, 11, 5}, { -3899, 23, 6}, { -3862, 3, 3},
245 { -3827, 25, 6}, { -3793, 13, 5}, { -3760, 27, 6}, { -3728, 7, 4},
246 { -3698, 29, 6}, { -3668, 15, 5}, { -3640, 31, 6}, { -3612, 1, 1},
247 { -3560, 17, 5}, { -3510, 9, 4}, { -3463, 19, 5}, { -3419, 5, 3},
248 { -3376, 21, 5}, { -3336, 11, 4}, { -3297, 23, 5}, { -3260, 3, 2},
249 { -3225, 25, 5}, { -3191, 13, 4}, { -3158, 27, 5}, { -3126, 7, 3},
250 { -3096, 29, 5}, { -3066, 15, 4}, { -3038, 31, 5}, { -3010, 1, 0},
251 { -2958, 17, 4}, { -2908, 9, 3}, { -2861, 19, 4}, { -2816, 5, 2},
252 { -2774, 21, 4}, { -2734, 11, 3}, { -2695, 23, 4}, { -2658, 3, 1},
253 { -2623, 25, 4}, { -2589, 13, 3}, { -2556, 27, 4}, { -2524, 7, 2},
254 { -2494, 29, 4}, { -2464, 15, 3}, { -2436, 31, 4}, { -2408, 2, 0},
255 { -2356, 17, 3}, { -2306, 9, 2}, { -2259, 19, 3}, { -2214, 5, 1},
256 { -2172, 21, 3}, { -2132, 11, 2}, { -2093, 23, 3}, { -2056, 3, 0},
257 { -2021, 25, 3}, { -1987, 13, 2}, { -1954, 27, 3}, { -1922, 7, 1},
258 { -1892, 29, 3}, { -1862, 15, 2}, { -1834, 31, 3}, { -1806, 4, 0},
259 { -1754, 17, 2}, { -1704, 9, 1}, { -1657, 19, 2}, { -1612, 5, 0},
260 { -1570, 21, 2}, { -1530, 11, 1}, { -1491, 23, 2}, { -1454, 6, 0},
261 { -1419, 25, 2}, { -1384, 13, 1}, { -1352, 27, 2}, { -1320, 7, 0},
262 { -1290, 29, 2}, { -1260, 15, 1}, { -1232, 31, 2}, { -1204, 8, 0},
263 { -1151, 17, 1}, { -1102, 9, 0}, { -1055, 19, 1}, { -1010, 10, 0},
264 { -968, 21, 1}, { -928, 11, 0}, { -889, 23, 1}, { -852, 12, 0},
265 { -816, 25, 1}, { -782, 13, 0}, { -750, 27, 1}, { -718, 14, 0},
266 { -688, 29, 1}, { -658, 15, 0}, { -630, 31, 1}, { -602, 16, 0},
267 { -549, 17, 0}, { -500, 18, 0}, { -453, 19, 0}, { -408, 20, 0},
268 { -366, 21, 0}, { -325, 22, 0}, { -287, 23, 0}, { -250, 24, 0},
269 { -214, 25, 0}, { -180, 26, 0}, { -148, 27, 0}, { -116, 28, 0},
270 { -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0},
271};
272
273static int pm860x_volatile(unsigned int reg)
274{
275 BUG_ON(reg >= REG_CACHE_SIZE);
276
277 switch (reg) {
278 case PM860X_AUDIO_SUPPLIES_2:
279 return 1;
280 }
281
282 return 0;
283}
284
285static unsigned int pm860x_read_reg_cache(struct snd_soc_codec *codec,
286 unsigned int reg)
287{
288 unsigned char *cache = codec->reg_cache;
289
290 BUG_ON(reg >= REG_CACHE_SIZE);
291
292 if (pm860x_volatile(reg))
293 return cache[reg];
294
295 reg += REG_CACHE_BASE;
296
297 return pm860x_reg_read(codec->control_data, reg);
298}
299
300static int pm860x_write_reg_cache(struct snd_soc_codec *codec,
301 unsigned int reg, unsigned int value)
302{
303 unsigned char *cache = codec->reg_cache;
304
305 BUG_ON(reg >= REG_CACHE_SIZE);
306
307 if (!pm860x_volatile(reg))
308 cache[reg] = (unsigned char)value;
309
310 reg += REG_CACHE_BASE;
311
312 return pm860x_reg_write(codec->control_data, reg, value);
313}
314
315static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol,
316 struct snd_ctl_elem_value *ucontrol)
317{
318 struct soc_mixer_control *mc =
319 (struct soc_mixer_control *)kcontrol->private_value;
320 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
321 unsigned int reg = mc->reg;
322 unsigned int reg2 = mc->rreg;
323 int val[2], val2[2], i;
324
325 val[0] = snd_soc_read(codec, reg) & 0x3f;
326 val[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT) >> 4) & 0xf;
327 val2[0] = snd_soc_read(codec, reg2) & 0x3f;
328 val2[1] = (snd_soc_read(codec, PM860X_SIDETONE_SHIFT)) & 0xf;
329
330 for (i = 0; i < ARRAY_SIZE(st_table); i++) {
331 if ((st_table[i].m == val[0]) && (st_table[i].n == val[1]))
332 ucontrol->value.integer.value[0] = i;
333 if ((st_table[i].m == val2[0]) && (st_table[i].n == val2[1]))
334 ucontrol->value.integer.value[1] = i;
335 }
336 return 0;
337}
338
339static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol,
340 struct snd_ctl_elem_value *ucontrol)
341{
342 struct soc_mixer_control *mc =
343 (struct soc_mixer_control *)kcontrol->private_value;
344 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
345 unsigned int reg = mc->reg;
346 unsigned int reg2 = mc->rreg;
347 int err;
348 unsigned int val, val2;
349
350 val = ucontrol->value.integer.value[0];
351 val2 = ucontrol->value.integer.value[1];
352
353 err = snd_soc_update_bits(codec, reg, 0x3f, st_table[val].m);
354 if (err < 0)
355 return err;
356 err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0xf0,
357 st_table[val].n << 4);
358 if (err < 0)
359 return err;
360
361 err = snd_soc_update_bits(codec, reg2, 0x3f, st_table[val2].m);
362 if (err < 0)
363 return err;
364 err = snd_soc_update_bits(codec, PM860X_SIDETONE_SHIFT, 0x0f,
365 st_table[val2].n);
366 return err;
367}
368
369static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol,
370 struct snd_ctl_elem_value *ucontrol)
371{
372 struct soc_mixer_control *mc =
373 (struct soc_mixer_control *)kcontrol->private_value;
374 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
375 unsigned int reg = mc->reg;
376 unsigned int reg2 = mc->rreg;
377 unsigned int shift = mc->shift;
378 int max = mc->max, val, val2;
379 unsigned int mask = (1 << fls(max)) - 1;
380
381 val = snd_soc_read(codec, reg) >> shift;
382 val2 = snd_soc_read(codec, reg2) >> shift;
383 ucontrol->value.integer.value[0] = (max - val) & mask;
384 ucontrol->value.integer.value[1] = (max - val2) & mask;
385
386 return 0;
387}
388
389static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_value *ucontrol)
391{
392 struct soc_mixer_control *mc =
393 (struct soc_mixer_control *)kcontrol->private_value;
394 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
395 unsigned int reg = mc->reg;
396 unsigned int reg2 = mc->rreg;
397 unsigned int shift = mc->shift;
398 int max = mc->max;
399 unsigned int mask = (1 << fls(max)) - 1;
400 int err;
401 unsigned int val, val2, val_mask;
402
403 val_mask = mask << shift;
404 val = ((max - ucontrol->value.integer.value[0]) & mask);
405 val2 = ((max - ucontrol->value.integer.value[1]) & mask);
406
407 val = val << shift;
408 val2 = val2 << shift;
409
410 err = snd_soc_update_bits(codec, reg, val_mask, val);
411 if (err < 0)
412 return err;
413
414 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
415 return err;
416}
417
418/* DAPM Widget Events */
419/*
420 * A lot registers are belong to RSYNC domain. It requires enabling RSYNC bit
421 * after updating these registers. Otherwise, these updated registers won't
422 * be effective.
423 */
424static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
425 struct snd_kcontrol *kcontrol, int event)
426{
427 struct snd_soc_codec *codec = w->codec;
428
429 /*
430 * In order to avoid current on the load, mute power-on and power-off
431 * should be transients.
432 * Unmute by DAC_MUTE. It should be unmuted when DAPM sequence is
433 * finished.
434 */
435 snd_soc_update_bits(codec, PM860X_DAC_OFFSET, DAC_MUTE, 0);
436 snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
437 RSYNC_CHANGE, RSYNC_CHANGE);
438 return 0;
439}
440
441static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
442 struct snd_kcontrol *kcontrol, int event)
443{
444 struct snd_soc_codec *codec = w->codec;
445 unsigned int dac = 0;
446 int data;
447
448 if (!strcmp(w->name, "Left DAC"))
449 dac = DAC_LEFT;
450 if (!strcmp(w->name, "Right DAC"))
451 dac = DAC_RIGHT;
452 switch (event) {
453 case SND_SOC_DAPM_PRE_PMU:
454 if (dac) {
455 /* Auto mute in power-on sequence. */
456 dac |= MODULATOR;
457 snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
458 DAC_MUTE, DAC_MUTE);
459 snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
460 RSYNC_CHANGE, RSYNC_CHANGE);
461 /* update dac */
462 snd_soc_update_bits(codec, PM860X_DAC_EN_2,
463 dac, dac);
464 }
465 break;
466 case SND_SOC_DAPM_PRE_PMD:
467 if (dac) {
468 /* Auto mute in power-off sequence. */
469 snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
470 DAC_MUTE, DAC_MUTE);
471 snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
472 RSYNC_CHANGE, RSYNC_CHANGE);
473 /* update dac */
474 data = snd_soc_read(codec, PM860X_DAC_EN_2);
475 data &= ~dac;
476 if (!(data & (DAC_LEFT | DAC_RIGHT)))
477 data &= ~MODULATOR;
478 snd_soc_write(codec, PM860X_DAC_EN_2, data);
479 }
480 break;
481 }
482 return 0;
483}
484
485static const char *pm860x_opamp_texts[] = {"-50%", "-25%", "0%", "75%"};
486
487static const char *pm860x_pa_texts[] = {"-33%", "0%", "33%", "66%"};
488
489static const struct soc_enum pm860x_hs1_opamp_enum =
490 SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 5, 4, pm860x_opamp_texts);
491
492static const struct soc_enum pm860x_hs2_opamp_enum =
493 SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 5, 4, pm860x_opamp_texts);
494
495static const struct soc_enum pm860x_hs1_pa_enum =
496 SOC_ENUM_SINGLE(PM860X_HS1_CTRL, 3, 4, pm860x_pa_texts);
497
498static const struct soc_enum pm860x_hs2_pa_enum =
499 SOC_ENUM_SINGLE(PM860X_HS2_CTRL, 3, 4, pm860x_pa_texts);
500
501static const struct soc_enum pm860x_lo1_opamp_enum =
502 SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 5, 4, pm860x_opamp_texts);
503
504static const struct soc_enum pm860x_lo2_opamp_enum =
505 SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 5, 4, pm860x_opamp_texts);
506
507static const struct soc_enum pm860x_lo1_pa_enum =
508 SOC_ENUM_SINGLE(PM860X_LO1_CTRL, 3, 4, pm860x_pa_texts);
509
510static const struct soc_enum pm860x_lo2_pa_enum =
511 SOC_ENUM_SINGLE(PM860X_LO2_CTRL, 3, 4, pm860x_pa_texts);
512
513static const struct soc_enum pm860x_spk_pa_enum =
514 SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 5, 4, pm860x_pa_texts);
515
516static const struct soc_enum pm860x_ear_pa_enum =
517 SOC_ENUM_SINGLE(PM860X_EAR_CTRL_2, 0, 4, pm860x_pa_texts);
518
519static const struct soc_enum pm860x_spk_ear_opamp_enum =
520 SOC_ENUM_SINGLE(PM860X_EAR_CTRL_1, 3, 4, pm860x_opamp_texts);
521
522static const struct snd_kcontrol_new pm860x_snd_controls[] = {
523 SOC_DOUBLE_R_TLV("ADC Capture Volume", PM860X_ADC_ANA_2,
524 PM860X_ADC_ANA_3, 6, 3, 0, adc_tlv),
525 SOC_DOUBLE_TLV("AUX Capture Volume", PM860X_ADC_ANA_3, 0, 3, 7, 0,
526 aux_tlv),
527 SOC_SINGLE_TLV("MIC1 Capture Volume", PM860X_ADC_ANA_2, 0, 7, 0,
528 mic_tlv),
529 SOC_SINGLE_TLV("MIC3 Capture Volume", PM860X_ADC_ANA_2, 3, 7, 0,
530 mic_tlv),
531 SOC_DOUBLE_R_EXT_TLV("Sidetone Volume", PM860X_SIDETONE_L_GAIN,
532 PM860X_SIDETONE_R_GAIN, 0, ARRAY_SIZE(st_table)-1,
533 0, snd_soc_get_volsw_2r_st,
534 snd_soc_put_volsw_2r_st, st_tlv),
535 SOC_SINGLE_TLV("Speaker Playback Volume", PM860X_EAR_CTRL_1,
536 0, 7, 0, out_tlv),
537 SOC_DOUBLE_R_TLV("Line Playback Volume", PM860X_LO1_CTRL,
538 PM860X_LO2_CTRL, 0, 7, 0, out_tlv),
539 SOC_DOUBLE_R_TLV("Headset Playback Volume", PM860X_HS1_CTRL,
540 PM860X_HS2_CTRL, 0, 7, 0, out_tlv),
541 SOC_DOUBLE_R_EXT_TLV("Hifi Left Playback Volume",
542 PM860X_HIFIL_GAIN_LEFT,
543 PM860X_HIFIL_GAIN_RIGHT, 0, 63, 0,
544 snd_soc_get_volsw_2r_out,
545 snd_soc_put_volsw_2r_out, dpga_tlv),
546 SOC_DOUBLE_R_EXT_TLV("Hifi Right Playback Volume",
547 PM860X_HIFIR_GAIN_LEFT,
548 PM860X_HIFIR_GAIN_RIGHT, 0, 63, 0,
549 snd_soc_get_volsw_2r_out,
550 snd_soc_put_volsw_2r_out, dpga_tlv),
551 SOC_DOUBLE_R_EXT_TLV("Lofi Playback Volume", PM860X_LOFI_GAIN_LEFT,
552 PM860X_LOFI_GAIN_RIGHT, 0, 63, 0,
553 snd_soc_get_volsw_2r_out,
554 snd_soc_put_volsw_2r_out, dpga_tlv),
555 SOC_ENUM("Headset1 Operational Amplifier Current",
556 pm860x_hs1_opamp_enum),
557 SOC_ENUM("Headset2 Operational Amplifier Current",
558 pm860x_hs2_opamp_enum),
559 SOC_ENUM("Headset1 Amplifier Current", pm860x_hs1_pa_enum),
560 SOC_ENUM("Headset2 Amplifier Current", pm860x_hs2_pa_enum),
561 SOC_ENUM("Lineout1 Operational Amplifier Current",
562 pm860x_lo1_opamp_enum),
563 SOC_ENUM("Lineout2 Operational Amplifier Current",
564 pm860x_lo2_opamp_enum),
565 SOC_ENUM("Lineout1 Amplifier Current", pm860x_lo1_pa_enum),
566 SOC_ENUM("Lineout2 Amplifier Current", pm860x_lo2_pa_enum),
567 SOC_ENUM("Speaker Operational Amplifier Current",
568 pm860x_spk_ear_opamp_enum),
569 SOC_ENUM("Speaker Amplifier Current", pm860x_spk_pa_enum),
570 SOC_ENUM("Earpiece Amplifier Current", pm860x_ear_pa_enum),
571};
572
573/*
574 * DAPM Controls
575 */
576
577/* PCM Switch / PCM Interface */
578static const struct snd_kcontrol_new pcm_switch_controls =
579 SOC_DAPM_SINGLE("Switch", PM860X_ADC_EN_2, 0, 1, 0);
580
581/* AUX1 Switch */
582static const struct snd_kcontrol_new aux1_switch_controls =
583 SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0);
584
585/* AUX2 Switch */
586static const struct snd_kcontrol_new aux2_switch_controls =
587 SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 5, 1, 0);
588
589/* Left Ex. PA Switch */
590static const struct snd_kcontrol_new lepa_switch_controls =
591 SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 2, 1, 0);
592
593/* Right Ex. PA Switch */
594static const struct snd_kcontrol_new repa_switch_controls =
595 SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0);
596
597/* PCM Mux / Mux7 */
598static const char *aif1_text[] = {
599 "PCM L", "PCM R",
600};
601
602static const struct soc_enum aif1_enum =
603 SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 6, 2, aif1_text);
604
605static const struct snd_kcontrol_new aif1_mux =
606 SOC_DAPM_ENUM("PCM Mux", aif1_enum);
607
608/* I2S Mux / Mux9 */
609static const char *i2s_din_text[] = {
610 "DIN", "DIN1",
611};
612
613static const struct soc_enum i2s_din_enum =
614 SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 1, 2, i2s_din_text);
615
616static const struct snd_kcontrol_new i2s_din_mux =
617 SOC_DAPM_ENUM("I2S DIN Mux", i2s_din_enum);
618
619/* I2S Mic Mux / Mux8 */
620static const char *i2s_mic_text[] = {
621 "Ex PA", "ADC",
622};
623
624static const struct soc_enum i2s_mic_enum =
625 SOC_ENUM_SINGLE(PM860X_I2S_IFACE_3, 4, 2, i2s_mic_text);
626
627static const struct snd_kcontrol_new i2s_mic_mux =
628 SOC_DAPM_ENUM("I2S Mic Mux", i2s_mic_enum);
629
630/* ADCL Mux / Mux2 */
631static const char *adcl_text[] = {
632 "ADCR", "ADCL",
633};
634
635static const struct soc_enum adcl_enum =
636 SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 4, 2, adcl_text);
637
638static const struct snd_kcontrol_new adcl_mux =
639 SOC_DAPM_ENUM("ADC Left Mux", adcl_enum);
640
641/* ADCR Mux / Mux3 */
642static const char *adcr_text[] = {
643 "ADCL", "ADCR",
644};
645
646static const struct soc_enum adcr_enum =
647 SOC_ENUM_SINGLE(PM860X_PCM_IFACE_3, 2, 2, adcr_text);
648
649static const struct snd_kcontrol_new adcr_mux =
650 SOC_DAPM_ENUM("ADC Right Mux", adcr_enum);
651
652/* ADCR EC Mux / Mux6 */
653static const char *adcr_ec_text[] = {
654 "ADCR", "EC",
655};
656
657static const struct soc_enum adcr_ec_enum =
658 SOC_ENUM_SINGLE(PM860X_ADC_EN_2, 3, 2, adcr_ec_text);
659
660static const struct snd_kcontrol_new adcr_ec_mux =
661 SOC_DAPM_ENUM("ADCR EC Mux", adcr_ec_enum);
662
663/* EC Mux / Mux4 */
664static const char *ec_text[] = {
665 "Left", "Right", "Left + Right",
666};
667
668static const struct soc_enum ec_enum =
669 SOC_ENUM_SINGLE(PM860X_EC_PATH, 1, 3, ec_text);
670
671static const struct snd_kcontrol_new ec_mux =
672 SOC_DAPM_ENUM("EC Mux", ec_enum);
673
674static const char *dac_text[] = {
675 "No input", "Right", "Left", "No input",
676};
677
678/* DAC Headset 1 Mux / Mux10 */
679static const struct soc_enum dac_hs1_enum =
680 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 0, 4, dac_text);
681
682static const struct snd_kcontrol_new dac_hs1_mux =
683 SOC_DAPM_ENUM("DAC HS1 Mux", dac_hs1_enum);
684
685/* DAC Headset 2 Mux / Mux11 */
686static const struct soc_enum dac_hs2_enum =
687 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 2, 4, dac_text);
688
689static const struct snd_kcontrol_new dac_hs2_mux =
690 SOC_DAPM_ENUM("DAC HS2 Mux", dac_hs2_enum);
691
692/* DAC Lineout 1 Mux / Mux12 */
693static const struct soc_enum dac_lo1_enum =
694 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 4, 4, dac_text);
695
696static const struct snd_kcontrol_new dac_lo1_mux =
697 SOC_DAPM_ENUM("DAC LO1 Mux", dac_lo1_enum);
698
699/* DAC Lineout 2 Mux / Mux13 */
700static const struct soc_enum dac_lo2_enum =
701 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_1, 6, 4, dac_text);
702
703static const struct snd_kcontrol_new dac_lo2_mux =
704 SOC_DAPM_ENUM("DAC LO2 Mux", dac_lo2_enum);
705
706/* DAC Spearker Earphone Mux / Mux14 */
707static const struct soc_enum dac_spk_ear_enum =
708 SOC_ENUM_SINGLE(PM860X_ANA_INPUT_SEL_2, 0, 4, dac_text);
709
710static const struct snd_kcontrol_new dac_spk_ear_mux =
711 SOC_DAPM_ENUM("DAC SP Mux", dac_spk_ear_enum);
712
713/* Headset 1 Mux / Mux15 */
714static const char *in_text[] = {
715 "Digital", "Analog",
716};
717
718static const struct soc_enum hs1_enum =
719 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 0, 2, in_text);
720
721static const struct snd_kcontrol_new hs1_mux =
722 SOC_DAPM_ENUM("Headset1 Mux", hs1_enum);
723
724/* Headset 2 Mux / Mux16 */
725static const struct soc_enum hs2_enum =
726 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 1, 2, in_text);
727
728static const struct snd_kcontrol_new hs2_mux =
729 SOC_DAPM_ENUM("Headset2 Mux", hs2_enum);
730
731/* Lineout 1 Mux / Mux17 */
732static const struct soc_enum lo1_enum =
733 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 2, 2, in_text);
734
735static const struct snd_kcontrol_new lo1_mux =
736 SOC_DAPM_ENUM("Lineout1 Mux", lo1_enum);
737
738/* Lineout 2 Mux / Mux18 */
739static const struct soc_enum lo2_enum =
740 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 3, 2, in_text);
741
742static const struct snd_kcontrol_new lo2_mux =
743 SOC_DAPM_ENUM("Lineout2 Mux", lo2_enum);
744
745/* Speaker Earpiece Demux */
746static const char *spk_text[] = {
747 "Earpiece", "Speaker",
748};
749
750static const struct soc_enum spk_enum =
751 SOC_ENUM_SINGLE(PM860X_ANA_TO_ANA, 6, 2, spk_text);
752
753static const struct snd_kcontrol_new spk_demux =
754 SOC_DAPM_ENUM("Speaker Earpiece Demux", spk_enum);
755
756/* MIC Mux / Mux1 */
757static const char *mic_text[] = {
758 "Mic 1", "Mic 2",
759};
760
761static const struct soc_enum mic_enum =
762 SOC_ENUM_SINGLE(PM860X_ADC_ANA_4, 4, 2, mic_text);
763
764static const struct snd_kcontrol_new mic_mux =
765 SOC_DAPM_ENUM("MIC Mux", mic_enum);
766
767static const struct snd_soc_dapm_widget pm860x_dapm_widgets[] = {
768 SND_SOC_DAPM_AIF_IN("PCM SDI", "PCM Playback", 0,
769 PM860X_ADC_EN_2, 0, 0),
770 SND_SOC_DAPM_AIF_OUT("PCM SDO", "PCM Capture", 0,
771 PM860X_PCM_IFACE_3, 1, 1),
772
773
774 SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0,
775 PM860X_DAC_EN_2, 0, 0),
776 SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0,
777 PM860X_DAC_EN_2, 0, 0),
778 SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0,
779 PM860X_I2S_IFACE_3, 5, 1),
780 SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux),
781 SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux),
782 SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux),
783 SND_SOC_DAPM_MUX("EC Mux", SND_SOC_NOPM, 0, 0, &ec_mux),
784 SND_SOC_DAPM_MUX("ADCR EC Mux", SND_SOC_NOPM, 0, 0, &adcr_ec_mux),
785 SND_SOC_DAPM_SWITCH("Left EPA", SND_SOC_NOPM, 0, 0,
786 &lepa_switch_controls),
787 SND_SOC_DAPM_SWITCH("Right EPA", SND_SOC_NOPM, 0, 0,
788 &repa_switch_controls),
789
790 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "Left ADC MOD", PM860X_ADC_EN_1,
791 0, 1, 1, 0),
792 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "Right ADC MOD", PM860X_ADC_EN_1,
793 1, 1, 1, 0),
794 SND_SOC_DAPM_ADC("Left ADC", NULL, PM860X_ADC_EN_2, 5, 0),
795 SND_SOC_DAPM_ADC("Right ADC", NULL, PM860X_ADC_EN_2, 4, 0),
796
797 SND_SOC_DAPM_SWITCH("AUX1 Switch", SND_SOC_NOPM, 0, 0,
798 &aux1_switch_controls),
799 SND_SOC_DAPM_SWITCH("AUX2 Switch", SND_SOC_NOPM, 0, 0,
800 &aux2_switch_controls),
801
802 SND_SOC_DAPM_MUX("MIC Mux", SND_SOC_NOPM, 0, 0, &mic_mux),
803 SND_SOC_DAPM_MICBIAS("Mic1 Bias", PM860X_ADC_ANA_1, 2, 0),
804 SND_SOC_DAPM_MICBIAS("Mic3 Bias", PM860X_ADC_ANA_1, 7, 0),
805 SND_SOC_DAPM_PGA("MIC1 Volume", PM860X_ADC_EN_1, 2, 0, NULL, 0),
806 SND_SOC_DAPM_PGA("MIC3 Volume", PM860X_ADC_EN_1, 3, 0, NULL, 0),
807 SND_SOC_DAPM_PGA("AUX1 Volume", PM860X_ADC_EN_1, 4, 0, NULL, 0),
808 SND_SOC_DAPM_PGA("AUX2 Volume", PM860X_ADC_EN_1, 5, 0, NULL, 0),
809 SND_SOC_DAPM_PGA("Sidetone PGA", PM860X_ADC_EN_2, 1, 0, NULL, 0),
810 SND_SOC_DAPM_PGA("Lofi PGA", PM860X_ADC_EN_2, 2, 0, NULL, 0),
811
812 SND_SOC_DAPM_INPUT("AUX1"),
813 SND_SOC_DAPM_INPUT("AUX2"),
814 SND_SOC_DAPM_INPUT("MIC1P"),
815 SND_SOC_DAPM_INPUT("MIC1N"),
816 SND_SOC_DAPM_INPUT("MIC2P"),
817 SND_SOC_DAPM_INPUT("MIC2N"),
818 SND_SOC_DAPM_INPUT("MIC3P"),
819 SND_SOC_DAPM_INPUT("MIC3N"),
820
821 SND_SOC_DAPM_DAC_E("Left DAC", NULL, SND_SOC_NOPM, 0, 0,
822 pm860x_dac_event,
823 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
824 SND_SOC_DAPM_DAC_E("Right DAC", NULL, SND_SOC_NOPM, 0, 0,
825 pm860x_dac_event,
826 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
827
828 SND_SOC_DAPM_MUX("I2S DIN Mux", SND_SOC_NOPM, 0, 0, &i2s_din_mux),
829 SND_SOC_DAPM_MUX("DAC HS1 Mux", SND_SOC_NOPM, 0, 0, &dac_hs1_mux),
830 SND_SOC_DAPM_MUX("DAC HS2 Mux", SND_SOC_NOPM, 0, 0, &dac_hs2_mux),
831 SND_SOC_DAPM_MUX("DAC LO1 Mux", SND_SOC_NOPM, 0, 0, &dac_lo1_mux),
832 SND_SOC_DAPM_MUX("DAC LO2 Mux", SND_SOC_NOPM, 0, 0, &dac_lo2_mux),
833 SND_SOC_DAPM_MUX("DAC SP Mux", SND_SOC_NOPM, 0, 0, &dac_spk_ear_mux),
834 SND_SOC_DAPM_MUX("Headset1 Mux", SND_SOC_NOPM, 0, 0, &hs1_mux),
835 SND_SOC_DAPM_MUX("Headset2 Mux", SND_SOC_NOPM, 0, 0, &hs2_mux),
836 SND_SOC_DAPM_MUX("Lineout1 Mux", SND_SOC_NOPM, 0, 0, &lo1_mux),
837 SND_SOC_DAPM_MUX("Lineout2 Mux", SND_SOC_NOPM, 0, 0, &lo2_mux),
838 SND_SOC_DAPM_MUX("Speaker Earpiece Demux", SND_SOC_NOPM, 0, 0,
839 &spk_demux),
840
841
842 SND_SOC_DAPM_PGA("Headset1 PGA", PM860X_DAC_EN_1, 0, 0, NULL, 0),
843 SND_SOC_DAPM_PGA("Headset2 PGA", PM860X_DAC_EN_1, 1, 0, NULL, 0),
844 SND_SOC_DAPM_OUTPUT("HS1"),
845 SND_SOC_DAPM_OUTPUT("HS2"),
846 SND_SOC_DAPM_PGA("Lineout1 PGA", PM860X_DAC_EN_1, 2, 0, NULL, 0),
847 SND_SOC_DAPM_PGA("Lineout2 PGA", PM860X_DAC_EN_1, 3, 0, NULL, 0),
848 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
849 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
850 SND_SOC_DAPM_PGA("Earpiece PGA", PM860X_DAC_EN_1, 4, 0, NULL, 0),
851 SND_SOC_DAPM_OUTPUT("EARP"),
852 SND_SOC_DAPM_OUTPUT("EARN"),
853 SND_SOC_DAPM_PGA("Speaker PGA", PM860X_DAC_EN_1, 5, 0, NULL, 0),
854 SND_SOC_DAPM_OUTPUT("LSP"),
855 SND_SOC_DAPM_OUTPUT("LSN"),
856 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "VCODEC", PM860X_AUDIO_SUPPLIES_2,
857 0, SUPPLY_MASK, SUPPLY_MASK, 0),
858
859 PM860X_DAPM_OUTPUT("RSYNC", pm860x_rsync_event),
860};
861
862static const struct snd_soc_dapm_route audio_map[] = {
863 /* supply */
864 {"Left DAC", NULL, "VCODEC"},
865 {"Right DAC", NULL, "VCODEC"},
866 {"Left ADC", NULL, "VCODEC"},
867 {"Right ADC", NULL, "VCODEC"},
868 {"Left ADC", NULL, "Left ADC MOD"},
869 {"Right ADC", NULL, "Right ADC MOD"},
870
871 /* PCM/AIF1 Inputs */
872 {"PCM SDO", NULL, "ADC Left Mux"},
873 {"PCM SDO", NULL, "ADCR EC Mux"},
874
875 /* PCM/AFI2 Outputs */
876 {"Lofi PGA", NULL, "PCM SDI"},
877 {"Lofi PGA", NULL, "Sidetone PGA"},
878 {"Left DAC", NULL, "Lofi PGA"},
879 {"Right DAC", NULL, "Lofi PGA"},
880
881 /* I2S/AIF2 Inputs */
882 {"MIC Mux", "Mic 1", "MIC1P"},
883 {"MIC Mux", "Mic 1", "MIC1N"},
884 {"MIC Mux", "Mic 2", "MIC2P"},
885 {"MIC Mux", "Mic 2", "MIC2N"},
886 {"MIC1 Volume", NULL, "MIC Mux"},
887 {"MIC3 Volume", NULL, "MIC3P"},
888 {"MIC3 Volume", NULL, "MIC3N"},
889 {"Left ADC", NULL, "MIC1 Volume"},
890 {"Right ADC", NULL, "MIC3 Volume"},
891 {"ADC Left Mux", "ADCR", "Right ADC"},
892 {"ADC Left Mux", "ADCL", "Left ADC"},
893 {"ADC Right Mux", "ADCL", "Left ADC"},
894 {"ADC Right Mux", "ADCR", "Right ADC"},
895 {"Left EPA", "Switch", "Left DAC"},
896 {"Right EPA", "Switch", "Right DAC"},
897 {"EC Mux", "Left", "Left DAC"},
898 {"EC Mux", "Right", "Right DAC"},
899 {"EC Mux", "Left + Right", "Left DAC"},
900 {"EC Mux", "Left + Right", "Right DAC"},
901 {"ADCR EC Mux", "ADCR", "ADC Right Mux"},
902 {"ADCR EC Mux", "EC", "EC Mux"},
903 {"I2S Mic Mux", "Ex PA", "Left EPA"},
904 {"I2S Mic Mux", "Ex PA", "Right EPA"},
905 {"I2S Mic Mux", "ADC", "ADC Left Mux"},
906 {"I2S Mic Mux", "ADC", "ADCR EC Mux"},
907 {"I2S DOUT", NULL, "I2S Mic Mux"},
908
909 /* I2S/AIF2 Outputs */
910 {"I2S DIN Mux", "DIN", "I2S DIN"},
911 {"I2S DIN Mux", "DIN1", "I2S DIN1"},
912 {"Left DAC", NULL, "I2S DIN Mux"},
913 {"Right DAC", NULL, "I2S DIN Mux"},
914 {"DAC HS1 Mux", "Left", "Left DAC"},
915 {"DAC HS1 Mux", "Right", "Right DAC"},
916 {"DAC HS2 Mux", "Left", "Left DAC"},
917 {"DAC HS2 Mux", "Right", "Right DAC"},
918 {"DAC LO1 Mux", "Left", "Left DAC"},
919 {"DAC LO1 Mux", "Right", "Right DAC"},
920 {"DAC LO2 Mux", "Left", "Left DAC"},
921 {"DAC LO2 Mux", "Right", "Right DAC"},
922 {"Headset1 Mux", "Digital", "DAC HS1 Mux"},
923 {"Headset2 Mux", "Digital", "DAC HS2 Mux"},
924 {"Lineout1 Mux", "Digital", "DAC LO1 Mux"},
925 {"Lineout2 Mux", "Digital", "DAC LO2 Mux"},
926 {"Headset1 PGA", NULL, "Headset1 Mux"},
927 {"Headset2 PGA", NULL, "Headset2 Mux"},
928 {"Lineout1 PGA", NULL, "Lineout1 Mux"},
929 {"Lineout2 PGA", NULL, "Lineout2 Mux"},
930 {"DAC SP Mux", "Left", "Left DAC"},
931 {"DAC SP Mux", "Right", "Right DAC"},
932 {"Speaker Earpiece Demux", "Speaker", "DAC SP Mux"},
933 {"Speaker PGA", NULL, "Speaker Earpiece Demux"},
934 {"Earpiece PGA", NULL, "Speaker Earpiece Demux"},
935
936 {"RSYNC", NULL, "Headset1 PGA"},
937 {"RSYNC", NULL, "Headset2 PGA"},
938 {"RSYNC", NULL, "Lineout1 PGA"},
939 {"RSYNC", NULL, "Lineout2 PGA"},
940 {"RSYNC", NULL, "Speaker PGA"},
941 {"RSYNC", NULL, "Speaker PGA"},
942 {"RSYNC", NULL, "Earpiece PGA"},
943 {"RSYNC", NULL, "Earpiece PGA"},
944
945 {"HS1", NULL, "RSYNC"},
946 {"HS2", NULL, "RSYNC"},
947 {"LINEOUT1", NULL, "RSYNC"},
948 {"LINEOUT2", NULL, "RSYNC"},
949 {"LSP", NULL, "RSYNC"},
950 {"LSN", NULL, "RSYNC"},
951 {"EARP", NULL, "RSYNC"},
952 {"EARN", NULL, "RSYNC"},
953};
954
955/*
956 * Use MUTE_LEFT & MUTE_RIGHT to implement digital mute.
957 * These bits can also be used to mute.
958 */
959static int pm860x_digital_mute(struct snd_soc_dai *codec_dai, int mute)
960{
961 struct snd_soc_codec *codec = codec_dai->codec;
962 int data = 0, mask = MUTE_LEFT | MUTE_RIGHT;
963
964 if (mute)
965 data = mask;
966 snd_soc_update_bits(codec, PM860X_DAC_OFFSET, mask, data);
967 snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
968 RSYNC_CHANGE, RSYNC_CHANGE);
969 return 0;
970}
971
972static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
973 struct snd_pcm_hw_params *params,
974 struct snd_soc_dai *dai)
975{
976 struct snd_soc_codec *codec = dai->codec;
977 unsigned char inf = 0, mask = 0;
978
979 /* bit size */
980 switch (params_format(params)) {
981 case SNDRV_PCM_FORMAT_S16_LE:
982 inf &= ~PCM_INF2_18WL;
983 break;
984 case SNDRV_PCM_FORMAT_S18_3LE:
985 inf |= PCM_INF2_18WL;
986 break;
987 default:
988 return -EINVAL;
989 }
990 mask |= PCM_INF2_18WL;
991 snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
992
993 /* sample rate */
994 switch (params_rate(params)) {
995 case 8000:
996 inf = 0;
997 break;
998 case 16000:
999 inf = 3;
1000 break;
1001 case 32000:
1002 inf = 6;
1003 break;
1004 case 48000:
1005 inf = 8;
1006 break;
1007 default:
1008 return -EINVAL;
1009 }
1010 snd_soc_update_bits(codec, PM860X_PCM_RATE, 0x0f, inf);
1011
1012 return 0;
1013}
1014
1015static int pm860x_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
1016 unsigned int fmt)
1017{
1018 struct snd_soc_codec *codec = codec_dai->codec;
1019 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1020 unsigned char inf = 0, mask = 0;
1021 int ret = -EINVAL;
1022
1023 mask |= PCM_INF2_BCLK | PCM_INF2_FS | PCM_INF2_MASTER;
1024
1025 /* set master/slave audio interface */
1026 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1027 case SND_SOC_DAIFMT_CBM_CFM:
1028 case SND_SOC_DAIFMT_CBM_CFS:
1029 if (pm860x->dir == PM860X_CLK_DIR_OUT) {
1030 inf |= PCM_INF2_MASTER;
1031 ret = 0;
1032 }
1033 break;
1034 case SND_SOC_DAIFMT_CBS_CFS:
1035 if (pm860x->dir == PM860X_CLK_DIR_IN) {
1036 inf &= ~PCM_INF2_MASTER;
1037 ret = 0;
1038 }
1039 break;
1040 }
1041
1042 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1043 case SND_SOC_DAIFMT_I2S:
1044 inf |= PCM_EXACT_I2S;
1045 ret = 0;
1046 break;
1047 }
1048 mask |= PCM_MODE_MASK;
1049 if (ret)
1050 return ret;
1051 snd_soc_update_bits(codec, PM860X_PCM_IFACE_2, mask, inf);
1052 return 0;
1053}
1054
1055static int pm860x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1056 int clk_id, unsigned int freq, int dir)
1057{
1058 struct snd_soc_codec *codec = codec_dai->codec;
1059 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1060
1061 if (dir == PM860X_CLK_DIR_OUT)
1062 pm860x->dir = PM860X_CLK_DIR_OUT;
1063 else {
1064 pm860x->dir = PM860X_CLK_DIR_IN;
1065 return -EINVAL;
1066 }
1067
1068 return 0;
1069}
1070
1071static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
1072 struct snd_pcm_hw_params *params,
1073 struct snd_soc_dai *dai)
1074{
1075 struct snd_soc_codec *codec = dai->codec;
1076 unsigned char inf;
1077
1078 /* bit size */
1079 switch (params_format(params)) {
1080 case SNDRV_PCM_FORMAT_S16_LE:
1081 inf = 0;
1082 break;
1083 case SNDRV_PCM_FORMAT_S18_3LE:
1084 inf = PCM_INF2_18WL;
1085 break;
1086 default:
1087 return -EINVAL;
1088 }
1089 snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, PCM_INF2_18WL, inf);
1090
1091 /* sample rate */
1092 switch (params_rate(params)) {
1093 case 8000:
1094 inf = 0;
1095 break;
1096 case 11025:
1097 inf = 1;
1098 break;
1099 case 16000:
1100 inf = 3;
1101 break;
1102 case 22050:
1103 inf = 4;
1104 break;
1105 case 32000:
1106 inf = 6;
1107 break;
1108 case 44100:
1109 inf = 7;
1110 break;
1111 case 48000:
1112 inf = 8;
1113 break;
1114 default:
1115 return -EINVAL;
1116 }
1117 snd_soc_update_bits(codec, PM860X_I2S_IFACE_4, 0xf, inf);
1118
1119 return 0;
1120}
1121
1122static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1123 unsigned int fmt)
1124{
1125 struct snd_soc_codec *codec = codec_dai->codec;
1126 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1127 unsigned char inf = 0, mask = 0;
1128
1129 mask |= PCM_INF2_BCLK | PCM_INF2_FS | PCM_INF2_MASTER;
1130
1131 /* set master/slave audio interface */
1132 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1133 case SND_SOC_DAIFMT_CBM_CFM:
1134 if (pm860x->dir == PM860X_CLK_DIR_OUT)
1135 inf |= PCM_INF2_MASTER;
1136 else
1137 return -EINVAL;
1138 break;
1139 case SND_SOC_DAIFMT_CBS_CFS:
1140 if (pm860x->dir == PM860X_CLK_DIR_IN)
1141 inf &= ~PCM_INF2_MASTER;
1142 else
1143 return -EINVAL;
1144 break;
1145 default:
1146 return -EINVAL;
1147 }
1148
1149 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1150 case SND_SOC_DAIFMT_I2S:
1151 inf |= PCM_EXACT_I2S;
1152 break;
1153 default:
1154 return -EINVAL;
1155 }
1156 mask |= PCM_MODE_MASK;
1157 snd_soc_update_bits(codec, PM860X_I2S_IFACE_2, mask, inf);
1158 return 0;
1159}
1160
1161static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1162 enum snd_soc_bias_level level)
1163{
1164 int data;
1165
1166 switch (level) {
1167 case SND_SOC_BIAS_ON:
1168 break;
1169
1170 case SND_SOC_BIAS_PREPARE:
1171 break;
1172
1173 case SND_SOC_BIAS_STANDBY:
1174 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1175 /* Enable Audio PLL & Audio section */
1176 data = AUDIO_PLL | AUDIO_SECTION_RESET
1177 | AUDIO_SECTION_ON;
1178 pm860x_reg_write(codec->control_data, REG_MISC2, data);
1179 }
1180 break;
1181
1182 case SND_SOC_BIAS_OFF:
1183 data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON;
1184 pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
1185 break;
1186 }
1187 codec->dapm.bias_level = level;
1188 return 0;
1189}
1190
1191static struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
1192 .digital_mute = pm860x_digital_mute,
1193 .hw_params = pm860x_pcm_hw_params,
1194 .set_fmt = pm860x_pcm_set_dai_fmt,
1195 .set_sysclk = pm860x_set_dai_sysclk,
1196};
1197
1198static struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
1199 .digital_mute = pm860x_digital_mute,
1200 .hw_params = pm860x_i2s_hw_params,
1201 .set_fmt = pm860x_i2s_set_dai_fmt,
1202 .set_sysclk = pm860x_set_dai_sysclk,
1203};
1204
1205#define PM860X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
1206 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
1207
1208static struct snd_soc_dai_driver pm860x_dai[] = {
1209 {
1210 /* DAI PCM */
1211 .name = "88pm860x-pcm",
1212 .id = 1,
1213 .playback = {
1214 .stream_name = "PCM Playback",
1215 .channels_min = 2,
1216 .channels_max = 2,
1217 .rates = PM860X_RATES,
1218 .formats = SNDRV_PCM_FORMAT_S16_LE | \
1219 SNDRV_PCM_FORMAT_S18_3LE,
1220 },
1221 .capture = {
1222 .stream_name = "PCM Capture",
1223 .channels_min = 2,
1224 .channels_max = 2,
1225 .rates = PM860X_RATES,
1226 .formats = SNDRV_PCM_FORMAT_S16_LE | \
1227 SNDRV_PCM_FORMAT_S18_3LE,
1228 },
1229 .ops = &pm860x_pcm_dai_ops,
1230 }, {
1231 /* DAI I2S */
1232 .name = "88pm860x-i2s",
1233 .id = 2,
1234 .playback = {
1235 .stream_name = "I2S Playback",
1236 .channels_min = 2,
1237 .channels_max = 2,
1238 .rates = SNDRV_PCM_RATE_8000_48000,
1239 .formats = SNDRV_PCM_FORMAT_S16_LE | \
1240 SNDRV_PCM_FORMAT_S18_3LE,
1241 },
1242 .capture = {
1243 .stream_name = "I2S Capture",
1244 .channels_min = 2,
1245 .channels_max = 2,
1246 .rates = SNDRV_PCM_RATE_8000_48000,
1247 .formats = SNDRV_PCM_FORMAT_S16_LE | \
1248 SNDRV_PCM_FORMAT_S18_3LE,
1249 },
1250 .ops = &pm860x_i2s_dai_ops,
1251 },
1252};
1253
1254static irqreturn_t pm860x_codec_handler(int irq, void *data)
1255{
1256 struct pm860x_priv *pm860x = data;
1257 int status, shrt, report = 0, mic_report = 0;
1258 int mask;
1259
1260 status = pm860x_reg_read(pm860x->i2c, REG_STATUS_1);
1261 shrt = pm860x_reg_read(pm860x->i2c, REG_SHORTS);
1262 mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt
1263 | pm860x->det.hp_det;
1264
1265#ifndef CONFIG_SND_SOC_88PM860X_MODULE
1266 if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
1267 SHORT_LO1 | SHORT_LO2))
1268 trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
1269#endif
1270
1271 if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
1272 && (status & HEADSET_STATUS))
1273 report |= SND_JACK_HEADPHONE;
1274
1275 if ((pm860x->det.mic_det & SND_JACK_MICROPHONE)
1276 && (status & MIC_STATUS))
1277 mic_report |= SND_JACK_MICROPHONE;
1278
1279 if (pm860x->det.hs_shrt && (shrt & (SHORT_HS1 | SHORT_HS2)))
1280 report |= pm860x->det.hs_shrt;
1281
1282 if (pm860x->det.hook_det && (status & HOOK_STATUS))
1283 report |= pm860x->det.hook_det;
1284
1285 if (pm860x->det.lo_shrt && (shrt & (SHORT_LO1 | SHORT_LO2)))
1286 report |= pm860x->det.lo_shrt;
1287
1288 if (report)
1289 snd_soc_jack_report(pm860x->det.hp_jack, report, mask);
1290 if (mic_report)
1291 snd_soc_jack_report(pm860x->det.mic_jack, SND_JACK_MICROPHONE,
1292 SND_JACK_MICROPHONE);
1293
1294 dev_dbg(pm860x->codec->dev, "headphone report:0x%x, mask:%x\n",
1295 report, mask);
1296 dev_dbg(pm860x->codec->dev, "microphone report:0x%x\n", mic_report);
1297 return IRQ_HANDLED;
1298}
1299
1300int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
1301 struct snd_soc_jack *jack,
1302 int det, int hook, int hs_shrt, int lo_shrt)
1303{
1304 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1305 int data;
1306
1307 pm860x->det.hp_jack = jack;
1308 pm860x->det.hp_det = det;
1309 pm860x->det.hook_det = hook;
1310 pm860x->det.hs_shrt = hs_shrt;
1311 pm860x->det.lo_shrt = lo_shrt;
1312
1313 if (det & SND_JACK_HEADPHONE)
1314 pm860x_set_bits(codec->control_data, REG_HS_DET,
1315 EN_HS_DET, EN_HS_DET);
1316 /* headset short detect */
1317 if (hs_shrt) {
1318 data = CLR_SHORT_HS2 | CLR_SHORT_HS1;
1319 pm860x_set_bits(codec->control_data, REG_SHORTS, data, data);
1320 }
1321 /* Lineout short detect */
1322 if (lo_shrt) {
1323 data = CLR_SHORT_LO2 | CLR_SHORT_LO1;
1324 pm860x_set_bits(codec->control_data, REG_SHORTS, data, data);
1325 }
1326
1327 /* sync status */
1328 pm860x_codec_handler(0, pm860x);
1329 return 0;
1330}
1331EXPORT_SYMBOL_GPL(pm860x_hs_jack_detect);
1332
1333int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
1334 struct snd_soc_jack *jack, int det)
1335{
1336 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1337
1338 pm860x->det.mic_jack = jack;
1339 pm860x->det.mic_det = det;
1340
1341 if (det & SND_JACK_MICROPHONE)
1342 pm860x_set_bits(codec->control_data, REG_MIC_DET,
1343 MICDET_MASK, MICDET_MASK);
1344
1345 /* sync status */
1346 pm860x_codec_handler(0, pm860x);
1347 return 0;
1348}
1349EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
1350
1351static int pm860x_probe(struct snd_soc_codec *codec)
1352{
1353 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1354 struct snd_soc_dapm_context *dapm = &codec->dapm;
1355 int i, ret;
1356
1357 pm860x->codec = codec;
1358
1359 codec->control_data = pm860x->i2c;
1360
1361 for (i = 0; i < 4; i++) {
1362 ret = request_threaded_irq(pm860x->irq[i], NULL,
1363 pm860x_codec_handler, IRQF_ONESHOT,
1364 pm860x->name[i], pm860x);
1365 if (ret < 0) {
1366 dev_err(codec->dev, "Failed to request IRQ!\n");
1367 goto out;
1368 }
1369 }
1370
1371 pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1372
1373 ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE,
1374 REG_CACHE_SIZE, codec->reg_cache);
1375 if (ret < 0) {
1376 dev_err(codec->dev, "Failed to fill register cache: %d\n",
1377 ret);
1378 goto out;
1379 }
1380
1381 snd_soc_add_controls(codec, pm860x_snd_controls,
1382 ARRAY_SIZE(pm860x_snd_controls));
1383 snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
1384 ARRAY_SIZE(pm860x_dapm_widgets));
1385 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1386 return 0;
1387
1388out:
1389 while (--i >= 0)
1390 free_irq(pm860x->irq[i], pm860x);
1391 return ret;
1392}
1393
1394static int pm860x_remove(struct snd_soc_codec *codec)
1395{
1396 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1397 int i;
1398
1399 for (i = 3; i >= 0; i--)
1400 free_irq(pm860x->irq[i], pm860x);
1401 pm860x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1402 return 0;
1403}
1404
1405static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
1406 .probe = pm860x_probe,
1407 .remove = pm860x_remove,
1408 .read = pm860x_read_reg_cache,
1409 .write = pm860x_write_reg_cache,
1410 .reg_cache_size = REG_CACHE_SIZE,
1411 .reg_word_size = sizeof(u8),
1412 .set_bias_level = pm860x_set_bias_level,
1413};
1414
1415static int __devinit pm860x_codec_probe(struct platform_device *pdev)
1416{
1417 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
1418 struct pm860x_priv *pm860x;
1419 struct resource *res;
1420 int i, ret;
1421
1422 pm860x = kzalloc(sizeof(struct pm860x_priv), GFP_KERNEL);
1423 if (pm860x == NULL)
1424 return -ENOMEM;
1425
1426 pm860x->chip = chip;
1427 pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client
1428 : chip->companion;
1429 platform_set_drvdata(pdev, pm860x);
1430
1431 for (i = 0; i < 4; i++) {
1432 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
1433 if (!res) {
1434 dev_err(&pdev->dev, "Failed to get IRQ resources\n");
1435 goto out;
1436 }
1437 pm860x->irq[i] = res->start + chip->irq_base;
1438 strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);
1439 }
1440
1441 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pm860x,
1442 pm860x_dai, ARRAY_SIZE(pm860x_dai));
1443 if (ret) {
1444 dev_err(&pdev->dev, "Failed to register codec\n");
1445 goto out;
1446 }
1447 return ret;
1448
1449out:
1450 platform_set_drvdata(pdev, NULL);
1451 kfree(pm860x);
1452 return -EINVAL;
1453}
1454
1455static int __devexit pm860x_codec_remove(struct platform_device *pdev)
1456{
1457 struct pm860x_priv *pm860x = platform_get_drvdata(pdev);
1458
1459 snd_soc_unregister_codec(&pdev->dev);
1460 platform_set_drvdata(pdev, NULL);
1461 kfree(pm860x);
1462 return 0;
1463}
1464
1465static struct platform_driver pm860x_codec_driver = {
1466 .driver = {
1467 .name = "88pm860x-codec",
1468 .owner = THIS_MODULE,
1469 },
1470 .probe = pm860x_codec_probe,
1471 .remove = __devexit_p(pm860x_codec_remove),
1472};
1473
1474static __init int pm860x_init(void)
1475{
1476 return platform_driver_register(&pm860x_codec_driver);
1477}
1478module_init(pm860x_init);
1479
1480static __exit void pm860x_exit(void)
1481{
1482 platform_driver_unregister(&pm860x_codec_driver);
1483}
1484module_exit(pm860x_exit);
1485
1486MODULE_DESCRIPTION("ASoC 88PM860x driver");
1487MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
1488MODULE_LICENSE("GPL");
1489MODULE_ALIAS("platform:88pm860x-codec");
1490
diff --git a/sound/soc/codecs/88pm860x-codec.h b/sound/soc/codecs/88pm860x-codec.h
new file mode 100644
index 000000000000..3364ba4a3607
--- /dev/null
+++ b/sound/soc/codecs/88pm860x-codec.h
@@ -0,0 +1,97 @@
1/*
2 * 88pm860x-codec.h -- 88PM860x ALSA SoC Audio Driver
3 *
4 * Copyright 2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __88PM860X_H
13#define __88PM860X_H
14
15/* The offset of these registers are 0xb0 */
16#define PM860X_PCM_IFACE_1 0x00
17#define PM860X_PCM_IFACE_2 0x01
18#define PM860X_PCM_IFACE_3 0x02
19#define PM860X_PCM_RATE 0x03
20#define PM860X_EC_PATH 0x04
21#define PM860X_SIDETONE_L_GAIN 0x05
22#define PM860X_SIDETONE_R_GAIN 0x06
23#define PM860X_SIDETONE_SHIFT 0x07
24#define PM860X_ADC_OFFSET_1 0x08
25#define PM860X_ADC_OFFSET_2 0x09
26#define PM860X_DMIC_DELAY 0x0a
27
28#define PM860X_I2S_IFACE_1 0x0b
29#define PM860X_I2S_IFACE_2 0x0c
30#define PM860X_I2S_IFACE_3 0x0d
31#define PM860X_I2S_IFACE_4 0x0e
32#define PM860X_EQUALIZER_N0_1 0x0f
33#define PM860X_EQUALIZER_N0_2 0x10
34#define PM860X_EQUALIZER_N1_1 0x11
35#define PM860X_EQUALIZER_N1_2 0x12
36#define PM860X_EQUALIZER_D1_1 0x13
37#define PM860X_EQUALIZER_D1_2 0x14
38#define PM860X_LOFI_GAIN_LEFT 0x15
39#define PM860X_LOFI_GAIN_RIGHT 0x16
40#define PM860X_HIFIL_GAIN_LEFT 0x17
41#define PM860X_HIFIL_GAIN_RIGHT 0x18
42#define PM860X_HIFIR_GAIN_LEFT 0x19
43#define PM860X_HIFIR_GAIN_RIGHT 0x1a
44#define PM860X_DAC_OFFSET 0x1b
45#define PM860X_OFFSET_LEFT_1 0x1c
46#define PM860X_OFFSET_LEFT_2 0x1d
47#define PM860X_OFFSET_RIGHT_1 0x1e
48#define PM860X_OFFSET_RIGHT_2 0x1f
49#define PM860X_ADC_ANA_1 0x20
50#define PM860X_ADC_ANA_2 0x21
51#define PM860X_ADC_ANA_3 0x22
52#define PM860X_ADC_ANA_4 0x23
53#define PM860X_ANA_TO_ANA 0x24
54#define PM860X_HS1_CTRL 0x25
55#define PM860X_HS2_CTRL 0x26
56#define PM860X_LO1_CTRL 0x27
57#define PM860X_LO2_CTRL 0x28
58#define PM860X_EAR_CTRL_1 0x29
59#define PM860X_EAR_CTRL_2 0x2a
60#define PM860X_AUDIO_SUPPLIES_1 0x2b
61#define PM860X_AUDIO_SUPPLIES_2 0x2c
62#define PM860X_ADC_EN_1 0x2d
63#define PM860X_ADC_EN_2 0x2e
64#define PM860X_DAC_EN_1 0x2f
65#define PM860X_DAC_EN_2 0x31
66#define PM860X_AUDIO_CAL_1 0x32
67#define PM860X_AUDIO_CAL_2 0x33
68#define PM860X_AUDIO_CAL_3 0x34
69#define PM860X_AUDIO_CAL_4 0x35
70#define PM860X_AUDIO_CAL_5 0x36
71#define PM860X_ANA_INPUT_SEL_1 0x37
72#define PM860X_ANA_INPUT_SEL_2 0x38
73
74#define PM860X_PCM_IFACE_4 0x39
75#define PM860X_I2S_IFACE_5 0x3a
76
77#define PM860X_SHORTS 0x3b
78#define PM860X_PLL_ADJ_1 0x3c
79#define PM860X_PLL_ADJ_2 0x3d
80
81/* bits definition */
82#define PM860X_CLK_DIR_IN 0
83#define PM860X_CLK_DIR_OUT 1
84
85#define PM860X_DET_HEADSET (1 << 0)
86#define PM860X_DET_MIC (1 << 1)
87#define PM860X_DET_HOOK (1 << 2)
88#define PM860X_SHORT_HEADSET (1 << 3)
89#define PM860X_SHORT_LINEOUT (1 << 4)
90#define PM860X_DET_MASK 0x1F
91
92extern int pm860x_hs_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
93 int, int, int, int);
94extern int pm860x_mic_jack_detect(struct snd_soc_codec *, struct snd_soc_jack *,
95 int);
96
97#endif /* __88PM860X_H */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 83f5c67d3c41..98175a096df2 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -10,29 +10,42 @@ config SND_SOC_I2C_AND_SPI
10 10
11config SND_SOC_ALL_CODECS 11config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 select SND_SOC_88PM860X if MFD_88PM860X
13 select SND_SOC_L3 14 select SND_SOC_L3
14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 15 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
15 select SND_SOC_AD1836 if SPI_MASTER 16 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
19 select SND_SOC_AD73311
18 select SND_SOC_ADS117X 20 select SND_SOC_ADS117X
19 select SND_SOC_AD73311 if I2C
20 select SND_SOC_AK4104 if SPI_MASTER 21 select SND_SOC_AK4104 if SPI_MASTER
21 select SND_SOC_AK4535 if I2C 22 select SND_SOC_AK4535 if I2C
23 select SND_SOC_AK4641 if I2C
22 select SND_SOC_AK4642 if I2C 24 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C 25 select SND_SOC_AK4671 if I2C
26 select SND_SOC_ALC5623 if I2C
24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 27 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
25 select SND_SOC_CS42L51 if I2C 28 select SND_SOC_CS42L51 if I2C
26 select SND_SOC_CS4270 if I2C 29 select SND_SOC_CS4270 if I2C
30 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
31 select SND_SOC_CX20442
27 select SND_SOC_DA7210 if I2C 32 select SND_SOC_DA7210 if I2C
28 select SND_SOC_JZ4740 if SOC_JZ4740 33 select SND_SOC_DFBMCS320
34 select SND_SOC_JZ4740_CODEC if SOC_JZ4740
35 select SND_SOC_LM4857 if I2C
36 select SND_SOC_MAX98088 if I2C
37 select SND_SOC_MAX98095 if I2C
38 select SND_SOC_MAX9850 if I2C
29 select SND_SOC_MAX9877 if I2C 39 select SND_SOC_MAX9877 if I2C
30 select SND_SOC_PCM3008 40 select SND_SOC_PCM3008
41 select SND_SOC_SGTL5000 if I2C
42 select SND_SOC_SN95031 if INTEL_SCU_IPC
31 select SND_SOC_SPDIF 43 select SND_SOC_SPDIF
32 select SND_SOC_SSM2602 if I2C 44 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
33 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 45 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
34 select SND_SOC_TLV320AIC23 if I2C 46 select SND_SOC_TLV320AIC23 if I2C
35 select SND_SOC_TLV320AIC26 if SPI_MASTER 47 select SND_SOC_TLV320AIC26 if SPI_MASTER
48 select SND_SOC_TVL320AIC32X4 if I2C
36 select SND_SOC_TLV320AIC3X if I2C 49 select SND_SOC_TLV320AIC3X if I2C
37 select SND_SOC_TPA6130A2 if I2C 50 select SND_SOC_TPA6130A2 if I2C
38 select SND_SOC_TLV320DAC33 if I2C 51 select SND_SOC_TLV320DAC33 if I2C
@@ -40,6 +53,8 @@ config SND_SOC_ALL_CODECS
40 select SND_SOC_TWL6040 if TWL4030_CORE 53 select SND_SOC_TWL6040 if TWL4030_CORE
41 select SND_SOC_UDA134X 54 select SND_SOC_UDA134X
42 select SND_SOC_UDA1380 if I2C 55 select SND_SOC_UDA1380 if I2C
56 select SND_SOC_WL1273 if MFD_WL1273_CORE
57 select SND_SOC_WM1250_EV1 if I2C
43 select SND_SOC_WM2000 if I2C 58 select SND_SOC_WM2000 if I2C
44 select SND_SOC_WM8350 if MFD_WM8350 59 select SND_SOC_WM8350 if MFD_WM8350
45 select SND_SOC_WM8400 if MFD_WM8400 60 select SND_SOC_WM8400 if MFD_WM8400
@@ -50,24 +65,32 @@ config SND_SOC_ALL_CODECS
50 select SND_SOC_WM8727 65 select SND_SOC_WM8727
51 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 66 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
52 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 67 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
68 select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI
53 select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI 69 select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
54 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 70 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
55 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 71 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
72 select SND_SOC_WM8770 if SPI_MASTER
56 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 73 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
74 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
57 select SND_SOC_WM8900 if I2C 75 select SND_SOC_WM8900 if I2C
58 select SND_SOC_WM8903 if I2C 76 select SND_SOC_WM8903 if I2C
59 select SND_SOC_WM8904 if I2C 77 select SND_SOC_WM8904 if I2C
78 select SND_SOC_WM8915 if I2C
60 select SND_SOC_WM8940 if I2C 79 select SND_SOC_WM8940 if I2C
61 select SND_SOC_WM8955 if I2C 80 select SND_SOC_WM8955 if I2C
62 select SND_SOC_WM8960 if I2C 81 select SND_SOC_WM8960 if I2C
63 select SND_SOC_WM8961 if I2C 82 select SND_SOC_WM8961 if I2C
83 select SND_SOC_WM8962 if I2C
64 select SND_SOC_WM8971 if I2C 84 select SND_SOC_WM8971 if I2C
65 select SND_SOC_WM8974 if I2C 85 select SND_SOC_WM8974 if I2C
66 select SND_SOC_WM8978 if I2C 86 select SND_SOC_WM8978 if I2C
87 select SND_SOC_WM8985 if SND_SOC_I2C_AND_SPI
67 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 88 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
68 select SND_SOC_WM8990 if I2C 89 select SND_SOC_WM8990 if I2C
90 select SND_SOC_WM8991 if I2C
69 select SND_SOC_WM8993 if I2C 91 select SND_SOC_WM8993 if I2C
70 select SND_SOC_WM8994 if MFD_WM8994 92 select SND_SOC_WM8994 if MFD_WM8994
93 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
71 select SND_SOC_WM9081 if I2C 94 select SND_SOC_WM9081 if I2C
72 select SND_SOC_WM9090 if I2C 95 select SND_SOC_WM9090 if I2C
73 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 96 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -84,6 +107,9 @@ config SND_SOC_ALL_CODECS
84 107
85 If unsure select "N". 108 If unsure select "N".
86 109
110config SND_SOC_88PM860X
111 tristate
112
87config SND_SOC_WM_HUBS 113config SND_SOC_WM_HUBS
88 tristate 114 tristate
89 default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y 115 default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
@@ -114,12 +140,18 @@ config SND_SOC_AK4104
114config SND_SOC_AK4535 140config SND_SOC_AK4535
115 tristate 141 tristate
116 142
143config SND_SOC_AK4641
144 tristate
145
117config SND_SOC_AK4642 146config SND_SOC_AK4642
118 tristate 147 tristate
119 148
120config SND_SOC_AK4671 149config SND_SOC_AK4671
121 tristate 150 tristate
122 151
152config SND_SOC_ALC5623
153 tristate
154
123config SND_SOC_CQ0093VC 155config SND_SOC_CQ0093VC
124 tristate 156 tristate
125 157
@@ -138,6 +170,9 @@ config SND_SOC_CS4270_VD33_ERRATA
138 bool 170 bool
139 depends on SND_SOC_CS4270 171 depends on SND_SOC_CS4270
140 172
173config SND_SOC_CS4271
174 tristate
175
141config SND_SOC_CX20442 176config SND_SOC_CX20442
142 tristate 177 tristate
143 178
@@ -150,9 +185,31 @@ config SND_SOC_L3
150config SND_SOC_DA7210 185config SND_SOC_DA7210
151 tristate 186 tristate
152 187
188config SND_SOC_DFBMCS320
189 tristate
190
191config SND_SOC_DMIC
192 tristate
193
194config SND_SOC_MAX98088
195 tristate
196
197config SND_SOC_MAX98095
198 tristate
199
200config SND_SOC_MAX9850
201 tristate
202
153config SND_SOC_PCM3008 203config SND_SOC_PCM3008
154 tristate 204 tristate
155 205
206#Freescale sgtl5000 codec
207config SND_SOC_SGTL5000
208 tristate
209
210config SND_SOC_SN95031
211 tristate
212
156config SND_SOC_SPDIF 213config SND_SOC_SPDIF
157 tristate 214 tristate
158 215
@@ -169,6 +226,9 @@ config SND_SOC_TLV320AIC26
169 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE 226 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
170 depends on SPI 227 depends on SPI
171 228
229config SND_SOC_TVL320AIC32X4
230 tristate
231
172config SND_SOC_TLV320AIC3X 232config SND_SOC_TLV320AIC3X
173 tristate 233 tristate
174 234
@@ -188,6 +248,12 @@ config SND_SOC_UDA134X
188config SND_SOC_UDA1380 248config SND_SOC_UDA1380
189 tristate 249 tristate
190 250
251config SND_SOC_WL1273
252 tristate
253
254config SND_SOC_WM1250_EV1
255 tristate
256
191config SND_SOC_WM8350 257config SND_SOC_WM8350
192 tristate 258 tristate
193 259
@@ -215,6 +281,9 @@ config SND_SOC_WM8728
215config SND_SOC_WM8731 281config SND_SOC_WM8731
216 tristate 282 tristate
217 283
284config SND_SOC_WM8737
285 tristate
286
218config SND_SOC_WM8741 287config SND_SOC_WM8741
219 tristate 288 tristate
220 289
@@ -224,9 +293,15 @@ config SND_SOC_WM8750
224config SND_SOC_WM8753 293config SND_SOC_WM8753
225 tristate 294 tristate
226 295
296config SND_SOC_WM8770
297 tristate
298
227config SND_SOC_WM8776 299config SND_SOC_WM8776
228 tristate 300 tristate
229 301
302config SND_SOC_WM8804
303 tristate
304
230config SND_SOC_WM8900 305config SND_SOC_WM8900
231 tristate 306 tristate
232 307
@@ -236,6 +311,9 @@ config SND_SOC_WM8903
236config SND_SOC_WM8904 311config SND_SOC_WM8904
237 tristate 312 tristate
238 313
314config SND_SOC_WM8915
315 tristate
316
239config SND_SOC_WM8940 317config SND_SOC_WM8940
240 tristate 318 tristate
241 319
@@ -248,6 +326,9 @@ config SND_SOC_WM8960
248config SND_SOC_WM8961 326config SND_SOC_WM8961
249 tristate 327 tristate
250 328
329config SND_SOC_WM8962
330 tristate
331
251config SND_SOC_WM8971 332config SND_SOC_WM8971
252 tristate 333 tristate
253 334
@@ -257,18 +338,27 @@ config SND_SOC_WM8974
257config SND_SOC_WM8978 338config SND_SOC_WM8978
258 tristate 339 tristate
259 340
341config SND_SOC_WM8985
342 tristate
343
260config SND_SOC_WM8988 344config SND_SOC_WM8988
261 tristate 345 tristate
262 346
263config SND_SOC_WM8990 347config SND_SOC_WM8990
264 tristate 348 tristate
265 349
350config SND_SOC_WM8991
351 tristate
352
266config SND_SOC_WM8993 353config SND_SOC_WM8993
267 tristate 354 tristate
268 355
269config SND_SOC_WM8994 356config SND_SOC_WM8994
270 tristate 357 tristate
271 358
359config SND_SOC_WM8995
360 tristate
361
272config SND_SOC_WM9081 362config SND_SOC_WM9081
273 tristate 363 tristate
274 364
@@ -282,6 +372,9 @@ config SND_SOC_WM9713
282 tristate 372 tristate
283 373
284# Amp 374# Amp
375config SND_SOC_LM4857
376 tristate
377
285config SND_SOC_MAX9877 378config SND_SOC_MAX9877
286 tristate 379 tristate
287 380
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 53524095759c..fd8558406ef0 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,3 +1,4 @@
1snd-soc-88pm860x-objs := 88pm860x-codec.o
1snd-soc-ac97-objs := ac97.o 2snd-soc-ac97-objs := ac97.o
2snd-soc-ad1836-objs := ad1836.o 3snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad193x-objs := ad193x.o 4snd-soc-ad193x-objs := ad193x.o
@@ -6,26 +7,39 @@ snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o 7snd-soc-ads117x-objs := ads117x.o
7snd-soc-ak4104-objs := ak4104.o 8snd-soc-ak4104-objs := ak4104.o
8snd-soc-ak4535-objs := ak4535.o 9snd-soc-ak4535-objs := ak4535.o
10snd-soc-ak4641-objs := ak4641.o
9snd-soc-ak4642-objs := ak4642.o 11snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 12snd-soc-ak4671-objs := ak4671.o
11snd-soc-cq93vc-objs := cq93vc.o 13snd-soc-cq93vc-objs := cq93vc.o
12snd-soc-cs42l51-objs := cs42l51.o 14snd-soc-cs42l51-objs := cs42l51.o
13snd-soc-cs4270-objs := cs4270.o 15snd-soc-cs4270-objs := cs4270.o
16snd-soc-cs4271-objs := cs4271.o
14snd-soc-cx20442-objs := cx20442.o 17snd-soc-cx20442-objs := cx20442.o
15snd-soc-da7210-objs := da7210.o 18snd-soc-da7210-objs := da7210.o
19snd-soc-dfbmcs320-objs := dfbmcs320.o
20snd-soc-dmic-objs := dmic.o
16snd-soc-l3-objs := l3.o 21snd-soc-l3-objs := l3.o
22snd-soc-max98088-objs := max98088.o
23snd-soc-max98095-objs := max98095.o
24snd-soc-max9850-objs := max9850.o
17snd-soc-pcm3008-objs := pcm3008.o 25snd-soc-pcm3008-objs := pcm3008.o
26snd-soc-sgtl5000-objs := sgtl5000.o
27snd-soc-alc5623-objs := alc5623.o
28snd-soc-sn95031-objs := sn95031.o
18snd-soc-spdif-objs := spdif_transciever.o 29snd-soc-spdif-objs := spdif_transciever.o
19snd-soc-ssm2602-objs := ssm2602.o 30snd-soc-ssm2602-objs := ssm2602.o
20snd-soc-stac9766-objs := stac9766.o 31snd-soc-stac9766-objs := stac9766.o
21snd-soc-tlv320aic23-objs := tlv320aic23.o 32snd-soc-tlv320aic23-objs := tlv320aic23.o
22snd-soc-tlv320aic26-objs := tlv320aic26.o 33snd-soc-tlv320aic26-objs := tlv320aic26.o
23snd-soc-tlv320aic3x-objs := tlv320aic3x.o 34snd-soc-tlv320aic3x-objs := tlv320aic3x.o
35snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
24snd-soc-tlv320dac33-objs := tlv320dac33.o 36snd-soc-tlv320dac33-objs := tlv320dac33.o
25snd-soc-twl4030-objs := twl4030.o 37snd-soc-twl4030-objs := twl4030.o
26snd-soc-twl6040-objs := twl6040.o 38snd-soc-twl6040-objs := twl6040.o
27snd-soc-uda134x-objs := uda134x.o 39snd-soc-uda134x-objs := uda134x.o
28snd-soc-uda1380-objs := uda1380.o 40snd-soc-uda1380-objs := uda1380.o
41snd-soc-wl1273-objs := wl1273.o
42snd-soc-wm1250-ev1-objs := wm1250-ev1.o
29snd-soc-wm8350-objs := wm8350.o 43snd-soc-wm8350-objs := wm8350.o
30snd-soc-wm8400-objs := wm8400.o 44snd-soc-wm8400-objs := wm8400.o
31snd-soc-wm8510-objs := wm8510.o 45snd-soc-wm8510-objs := wm8510.o
@@ -35,24 +49,32 @@ snd-soc-wm8711-objs := wm8711.o
35snd-soc-wm8727-objs := wm8727.o 49snd-soc-wm8727-objs := wm8727.o
36snd-soc-wm8728-objs := wm8728.o 50snd-soc-wm8728-objs := wm8728.o
37snd-soc-wm8731-objs := wm8731.o 51snd-soc-wm8731-objs := wm8731.o
52snd-soc-wm8737-objs := wm8737.o
38snd-soc-wm8741-objs := wm8741.o 53snd-soc-wm8741-objs := wm8741.o
39snd-soc-wm8750-objs := wm8750.o 54snd-soc-wm8750-objs := wm8750.o
40snd-soc-wm8753-objs := wm8753.o 55snd-soc-wm8753-objs := wm8753.o
56snd-soc-wm8770-objs := wm8770.o
41snd-soc-wm8776-objs := wm8776.o 57snd-soc-wm8776-objs := wm8776.o
58snd-soc-wm8804-objs := wm8804.o
42snd-soc-wm8900-objs := wm8900.o 59snd-soc-wm8900-objs := wm8900.o
43snd-soc-wm8903-objs := wm8903.o 60snd-soc-wm8903-objs := wm8903.o
44snd-soc-wm8904-objs := wm8904.o 61snd-soc-wm8904-objs := wm8904.o
62snd-soc-wm8915-objs := wm8915.o
45snd-soc-wm8940-objs := wm8940.o 63snd-soc-wm8940-objs := wm8940.o
46snd-soc-wm8955-objs := wm8955.o 64snd-soc-wm8955-objs := wm8955.o
47snd-soc-wm8960-objs := wm8960.o 65snd-soc-wm8960-objs := wm8960.o
48snd-soc-wm8961-objs := wm8961.o 66snd-soc-wm8961-objs := wm8961.o
67snd-soc-wm8962-objs := wm8962.o
49snd-soc-wm8971-objs := wm8971.o 68snd-soc-wm8971-objs := wm8971.o
50snd-soc-wm8974-objs := wm8974.o 69snd-soc-wm8974-objs := wm8974.o
51snd-soc-wm8978-objs := wm8978.o 70snd-soc-wm8978-objs := wm8978.o
71snd-soc-wm8985-objs := wm8985.o
52snd-soc-wm8988-objs := wm8988.o 72snd-soc-wm8988-objs := wm8988.o
53snd-soc-wm8990-objs := wm8990.o 73snd-soc-wm8990-objs := wm8990.o
74snd-soc-wm8991-objs := wm8991.o
54snd-soc-wm8993-objs := wm8993.o 75snd-soc-wm8993-objs := wm8993.o
55snd-soc-wm8994-objs := wm8994.o 76snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o
77snd-soc-wm8995-objs := wm8995.o
56snd-soc-wm9081-objs := wm9081.o 78snd-soc-wm9081-objs := wm9081.o
57snd-soc-wm9705-objs := wm9705.o 79snd-soc-wm9705-objs := wm9705.o
58snd-soc-wm9712-objs := wm9712.o 80snd-soc-wm9712-objs := wm9712.o
@@ -61,11 +83,13 @@ snd-soc-wm-hubs-objs := wm_hubs.o
61snd-soc-jz4740-codec-objs := jz4740.o 83snd-soc-jz4740-codec-objs := jz4740.o
62 84
63# Amp 85# Amp
86snd-soc-lm4857-objs := lm4857.o
64snd-soc-max9877-objs := max9877.o 87snd-soc-max9877-objs := max9877.o
65snd-soc-tpa6130a2-objs := tpa6130a2.o 88snd-soc-tpa6130a2-objs := tpa6130a2.o
66snd-soc-wm2000-objs := wm2000.o 89snd-soc-wm2000-objs := wm2000.o
67snd-soc-wm9090-objs := wm9090.o 90snd-soc-wm9090-objs := wm9090.o
68 91
92obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
69obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 93obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
70obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 94obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
71obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 95obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
@@ -74,27 +98,40 @@ obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
74obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 98obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
75obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 99obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
76obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 100obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
101obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
77obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 102obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
78obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 103obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
104obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
79obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 105obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
80obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 106obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
81obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 107obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
108obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
82obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 109obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
83obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 110obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
111obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
112obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
84obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 113obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
85obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 114obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
115obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
116obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
117obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
86obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 118obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
119obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
120obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
87obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 121obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
88obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 122obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
89obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 123obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
90obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 124obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
91obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 125obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
92obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 126obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
127obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o
93obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 128obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
94obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 129obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
95obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o 130obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
96obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 131obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
97obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 132obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
133obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
134obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
98obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 135obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
99obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 136obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
100obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 137obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
@@ -104,24 +141,32 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
104obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o 141obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
105obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 142obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
106obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 143obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
144obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o
107obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o 145obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
108obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 146obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
109obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 147obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
148obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
110obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 149obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
150obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
111obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 151obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
112obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 152obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
113obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o 153obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
154obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o
114obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 155obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
115obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o 156obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
116obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 157obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
117obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o 158obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
159obj-$(CONFIG_SND_SOC_WM8962) += snd-soc-wm8962.o
118obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 160obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
119obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o 161obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
120obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o 162obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
163obj-$(CONFIG_SND_SOC_WM8985) += snd-soc-wm8985.o
121obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 164obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
122obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 165obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
166obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
123obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 167obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
124obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 168obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
169obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
125obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 170obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
126obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 171obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
127obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 172obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
@@ -129,6 +174,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
129obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o 174obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
130 175
131# Amp 176# Amp
177obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
132obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 178obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
133obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 179obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
134obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 180obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 1f5e57a4bb7a..3c087936aa57 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -21,17 +21,13 @@
21#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include "ac97.h"
25
26#define AC97_VERSION "0.6"
27 24
28static int ac97_prepare(struct snd_pcm_substream *substream, 25static int ac97_prepare(struct snd_pcm_substream *substream,
29 struct snd_soc_dai *dai) 26 struct snd_soc_dai *dai)
30{ 27{
31 struct snd_pcm_runtime *runtime = substream->runtime; 28 struct snd_pcm_runtime *runtime = substream->runtime;
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 29 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_soc_device *socdev = rtd->socdev; 30 struct snd_soc_codec *codec = rtd->codec;
34 struct snd_soc_codec *codec = socdev->card->codec;
35 31
36 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 32 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
37 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; 33 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
@@ -46,8 +42,8 @@ static struct snd_soc_dai_ops ac97_dai_ops = {
46 .prepare = ac97_prepare, 42 .prepare = ac97_prepare,
47}; 43};
48 44
49struct snd_soc_dai ac97_dai = { 45static struct snd_soc_dai_driver ac97_dai = {
50 .name = "AC97 HiFi", 46 .name = "ac97-hifi",
51 .ac97_control = 1, 47 .ac97_control = 1,
52 .playback = { 48 .playback = {
53 .stream_name = "AC97 Playback", 49 .stream_name = "AC97 Playback",
@@ -63,7 +59,6 @@ struct snd_soc_dai ac97_dai = {
63 .formats = SND_SOC_STD_AC97_FMTS,}, 59 .formats = SND_SOC_STD_AC97_FMTS,},
64 .ops = &ac97_dai_ops, 60 .ops = &ac97_dai_ops,
65}; 61};
66EXPORT_SYMBOL_GPL(ac97_dai);
67 62
68static unsigned int ac97_read(struct snd_soc_codec *codec, 63static unsigned int ac97_read(struct snd_soc_codec *codec,
69 unsigned int reg) 64 unsigned int reg)
@@ -78,95 +73,41 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
78 return 0; 73 return 0;
79} 74}
80 75
81static int ac97_soc_probe(struct platform_device *pdev) 76static int ac97_soc_probe(struct snd_soc_codec *codec)
82{ 77{
83 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
84 struct snd_soc_card *card = socdev->card;
85 struct snd_soc_codec *codec;
86 struct snd_ac97_bus *ac97_bus; 78 struct snd_ac97_bus *ac97_bus;
87 struct snd_ac97_template ac97_template; 79 struct snd_ac97_template ac97_template;
88 int i; 80 int ret;
89 int ret = 0;
90
91 printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
92
93 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
94 if (!socdev->card->codec)
95 return -ENOMEM;
96 codec = socdev->card->codec;
97 mutex_init(&codec->mutex);
98
99 codec->name = "AC97";
100 codec->owner = THIS_MODULE;
101 codec->dai = &ac97_dai;
102 codec->num_dai = 1;
103 codec->write = ac97_write;
104 codec->read = ac97_read;
105 INIT_LIST_HEAD(&codec->dapm_widgets);
106 INIT_LIST_HEAD(&codec->dapm_paths);
107
108 /* register pcms */
109 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
110 if (ret < 0)
111 goto err;
112 81
113 /* add codec as bus device for standard ac97 */ 82 /* add codec as bus device for standard ac97 */
114 ret = snd_ac97_bus(codec->card, 0, &soc_ac97_ops, NULL, &ac97_bus); 83 ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus);
115 if (ret < 0) 84 if (ret < 0)
116 goto bus_err; 85 return ret;
117 86
118 memset(&ac97_template, 0, sizeof(struct snd_ac97_template)); 87 memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
119 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97); 88 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97);
120 if (ret < 0) 89 if (ret < 0)
121 goto bus_err; 90 return ret;
122
123 for (i = 0; i < card->num_links; i++) {
124 if (card->dai_link[i].codec_dai->ac97_control) {
125 snd_ac97_dev_add_pdata(codec->ac97,
126 card->dai_link[i].cpu_dai->ac97_pdata);
127 }
128 }
129 91
130 return 0; 92 return 0;
131
132bus_err:
133 snd_soc_free_pcms(socdev);
134
135err:
136 kfree(socdev->card->codec);
137 socdev->card->codec = NULL;
138 return ret;
139} 93}
140 94
141static int ac97_soc_remove(struct platform_device *pdev) 95static int ac97_soc_remove(struct snd_soc_codec *codec)
142{ 96{
143 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
144 struct snd_soc_codec *codec = socdev->card->codec;
145
146 if (!codec)
147 return 0;
148
149 snd_soc_free_pcms(socdev);
150 kfree(socdev->card->codec);
151
152 return 0; 97 return 0;
153} 98}
154 99
155#ifdef CONFIG_PM 100#ifdef CONFIG_PM
156static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg) 101static int ac97_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
157{ 102{
158 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 103 snd_ac97_suspend(codec->ac97);
159
160 snd_ac97_suspend(socdev->card->codec->ac97);
161 104
162 return 0; 105 return 0;
163} 106}
164 107
165static int ac97_soc_resume(struct platform_device *pdev) 108static int ac97_soc_resume(struct snd_soc_codec *codec)
166{ 109{
167 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 110 snd_ac97_resume(codec->ac97);
168
169 snd_ac97_resume(socdev->card->codec->ac97);
170 111
171 return 0; 112 return 0;
172} 113}
@@ -175,14 +116,50 @@ static int ac97_soc_resume(struct platform_device *pdev)
175#define ac97_soc_resume NULL 116#define ac97_soc_resume NULL
176#endif 117#endif
177 118
178struct snd_soc_codec_device soc_codec_dev_ac97 = { 119static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
120 .write = ac97_write,
121 .read = ac97_read,
179 .probe = ac97_soc_probe, 122 .probe = ac97_soc_probe,
180 .remove = ac97_soc_remove, 123 .remove = ac97_soc_remove,
181 .suspend = ac97_soc_suspend, 124 .suspend = ac97_soc_suspend,
182 .resume = ac97_soc_resume, 125 .resume = ac97_soc_resume,
183}; 126};
184EXPORT_SYMBOL_GPL(soc_codec_dev_ac97); 127
128static __devinit int ac97_probe(struct platform_device *pdev)
129{
130 return snd_soc_register_codec(&pdev->dev,
131 &soc_codec_dev_ac97, &ac97_dai, 1);
132}
133
134static int __devexit ac97_remove(struct platform_device *pdev)
135{
136 snd_soc_unregister_codec(&pdev->dev);
137 return 0;
138}
139
140static struct platform_driver ac97_codec_driver = {
141 .driver = {
142 .name = "ac97-codec",
143 .owner = THIS_MODULE,
144 },
145
146 .probe = ac97_probe,
147 .remove = __devexit_p(ac97_remove),
148};
149
150static int __init ac97_init(void)
151{
152 return platform_driver_register(&ac97_codec_driver);
153}
154module_init(ac97_init);
155
156static void __exit ac97_exit(void)
157{
158 platform_driver_unregister(&ac97_codec_driver);
159}
160module_exit(ac97_exit);
185 161
186MODULE_DESCRIPTION("Soc Generic AC97 driver"); 162MODULE_DESCRIPTION("Soc Generic AC97 driver");
187MODULE_AUTHOR("Liam Girdwood"); 163MODULE_AUTHOR("Liam Girdwood");
188MODULE_LICENSE("GPL"); 164MODULE_LICENSE("GPL");
165MODULE_ALIAS("platform:ac97-codec");
diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h
deleted file mode 100644
index 281aa42e2bbb..000000000000
--- a/sound/soc/codecs/ac97.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * linux/sound/codecs/ac97.h -- ALSA SoC Layer
3 *
4 * Author: Liam Girdwood
5 * Created: Dec 1st 2005
6 * Copyright: Wolfson Microelectronics. PLC.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __LINUX_SND_SOC_AC97_H
14#define __LINUX_SND_SOC_AC97_H
15
16extern struct snd_soc_codec_device soc_codec_dev_ac97;
17extern struct snd_soc_dai ac97_dai;
18
19#endif
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index a01006c8c606..754c496412bd 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -27,21 +27,15 @@
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/tlv.h> 29#include <sound/tlv.h>
30#include <sound/soc-dapm.h>
31#include <linux/spi/spi.h> 30#include <linux/spi/spi.h>
32#include "ad1836.h" 31#include "ad1836.h"
33 32
34/* codec private data */ 33/* codec private data */
35struct ad1836_priv { 34struct ad1836_priv {
36 struct snd_soc_codec codec; 35 enum snd_soc_control_type control_type;
37 u16 reg_cache[AD1836_NUM_REGS]; 36 void *control_data;
38}; 37};
39 38
40static struct snd_soc_codec *ad1836_codec;
41struct snd_soc_codec_device soc_codec_dev_ad1836;
42static int ad1836_register(struct ad1836_priv *ad1836);
43static void ad1836_unregister(struct ad1836_priv *ad1836);
44
45/* 39/*
46 * AD1836 volume/mute/de-emphasis etc. controls 40 * AD1836 volume/mute/de-emphasis etc. controls
47 */ 41 */
@@ -146,39 +140,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
146 int word_len = 0; 140 int word_len = 0;
147 141
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_device *socdev = rtd->socdev; 143 struct snd_soc_codec *codec = rtd->codec;
150 struct snd_soc_codec *codec = socdev->card->codec;
151 144
152 /* bit size */ 145 /* bit size */
153 switch (params_format(params)) { 146 switch (params_format(params)) {
154 case SNDRV_PCM_FORMAT_S16_LE: 147 case SNDRV_PCM_FORMAT_S16_LE:
155 word_len = 3; 148 word_len = AD1836_WORD_LEN_16;
156 break; 149 break;
157 case SNDRV_PCM_FORMAT_S20_3LE: 150 case SNDRV_PCM_FORMAT_S20_3LE:
158 word_len = 1; 151 word_len = AD1836_WORD_LEN_20;
159 break; 152 break;
160 case SNDRV_PCM_FORMAT_S24_LE: 153 case SNDRV_PCM_FORMAT_S24_LE:
161 case SNDRV_PCM_FORMAT_S32_LE: 154 case SNDRV_PCM_FORMAT_S32_LE:
162 word_len = 0; 155 word_len = AD1836_WORD_LEN_24;
163 break; 156 break;
164 } 157 }
165 158
166 snd_soc_update_bits(codec, AD1836_DAC_CTRL1, 159 snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK,
167 AD1836_DAC_WORD_LEN_MASK, word_len); 160 word_len << AD1836_DAC_WORD_LEN_OFFSET);
168 161
169 snd_soc_update_bits(codec, AD1836_ADC_CTRL2, 162 snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK,
170 AD1836_ADC_WORD_LEN_MASK, word_len); 163 word_len << AD1836_ADC_WORD_OFFSET);
171 164
172 return 0; 165 return 0;
173} 166}
174 167
175#ifdef CONFIG_PM 168#ifdef CONFIG_PM
176static int ad1836_soc_suspend(struct platform_device *pdev, 169static int ad1836_soc_suspend(struct snd_soc_codec *codec,
177 pm_message_t state) 170 pm_message_t state)
178{ 171{
179 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
180 struct snd_soc_codec *codec = socdev->card->codec;
181
182 /* reset clock control mode */ 172 /* reset clock control mode */
183 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 173 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
184 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; 174 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
@@ -186,11 +176,8 @@ static int ad1836_soc_suspend(struct platform_device *pdev,
186 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); 176 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
187} 177}
188 178
189static int ad1836_soc_resume(struct platform_device *pdev) 179static int ad1836_soc_resume(struct snd_soc_codec *codec)
190{ 180{
191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
192 struct snd_soc_codec *codec = socdev->card->codec;
193
194 /* restore clock control mode */ 181 /* restore clock control mode */
195 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); 182 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
196 adc_ctrl2 |= AD1836_ADC_AUX; 183 adc_ctrl2 |= AD1836_ADC_AUX;
@@ -202,49 +189,14 @@ static int ad1836_soc_resume(struct platform_device *pdev)
202#define ad1836_soc_resume NULL 189#define ad1836_soc_resume NULL
203#endif 190#endif
204 191
205static int __devinit ad1836_spi_probe(struct spi_device *spi)
206{
207 struct snd_soc_codec *codec;
208 struct ad1836_priv *ad1836;
209
210 ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
211 if (ad1836 == NULL)
212 return -ENOMEM;
213
214 codec = &ad1836->codec;
215 codec->control_data = spi;
216 codec->dev = &spi->dev;
217
218 dev_set_drvdata(&spi->dev, ad1836);
219
220 return ad1836_register(ad1836);
221}
222
223static int __devexit ad1836_spi_remove(struct spi_device *spi)
224{
225 struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
226
227 ad1836_unregister(ad1836);
228 return 0;
229}
230
231static struct spi_driver ad1836_spi_driver = {
232 .driver = {
233 .name = "ad1836",
234 .owner = THIS_MODULE,
235 },
236 .probe = ad1836_spi_probe,
237 .remove = __devexit_p(ad1836_spi_remove),
238};
239
240static struct snd_soc_dai_ops ad1836_dai_ops = { 192static struct snd_soc_dai_ops ad1836_dai_ops = {
241 .hw_params = ad1836_hw_params, 193 .hw_params = ad1836_hw_params,
242 .set_fmt = ad1836_set_dai_fmt, 194 .set_fmt = ad1836_set_dai_fmt,
243}; 195};
244 196
245/* codec DAI instance */ 197/* codec DAI instance */
246struct snd_soc_dai ad1836_dai = { 198static struct snd_soc_dai_driver ad1836_dai = {
247 .name = "AD1836", 199 .name = "ad1836-hifi",
248 .playback = { 200 .playback = {
249 .stream_name = "Playback", 201 .stream_name = "Playback",
250 .channels_min = 2, 202 .channels_min = 2,
@@ -263,40 +215,18 @@ struct snd_soc_dai ad1836_dai = {
263 }, 215 },
264 .ops = &ad1836_dai_ops, 216 .ops = &ad1836_dai_ops,
265}; 217};
266EXPORT_SYMBOL_GPL(ad1836_dai);
267 218
268static int ad1836_register(struct ad1836_priv *ad1836) 219static int ad1836_probe(struct snd_soc_codec *codec)
269{ 220{
270 int ret; 221 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
271 struct snd_soc_codec *codec = &ad1836->codec; 222 struct snd_soc_dapm_context *dapm = &codec->dapm;
272 223 int ret = 0;
273 if (ad1836_codec) {
274 dev_err(codec->dev, "Another ad1836 is registered\n");
275 kfree(ad1836);
276 return -EINVAL;
277 }
278
279 mutex_init(&codec->mutex);
280 INIT_LIST_HEAD(&codec->dapm_widgets);
281 INIT_LIST_HEAD(&codec->dapm_paths);
282 snd_soc_codec_set_drvdata(codec, ad1836);
283 codec->reg_cache = ad1836->reg_cache;
284 codec->reg_cache_size = AD1836_NUM_REGS;
285 codec->name = "AD1836";
286 codec->owner = THIS_MODULE;
287 codec->dai = &ad1836_dai;
288 codec->num_dai = 1;
289 INIT_LIST_HEAD(&codec->dapm_widgets);
290 INIT_LIST_HEAD(&codec->dapm_paths);
291
292 ad1836_dai.dev = codec->dev;
293 ad1836_codec = codec;
294 224
225 codec->control_data = ad1836->control_data;
295 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); 226 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
296 if (ret < 0) { 227 if (ret < 0) {
297 dev_err(codec->dev, "failed to set cache I/O: %d\n", 228 dev_err(codec->dev, "failed to set cache I/O: %d\n",
298 ret); 229 ret);
299 kfree(ad1836);
300 return ret; 230 return ret;
301 } 231 }
302 232
@@ -319,81 +249,69 @@ static int ad1836_register(struct ad1836_priv *ad1836)
319 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF); 249 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
320 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF); 250 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
321 251
322 ret = snd_soc_register_codec(codec); 252 snd_soc_add_controls(codec, ad1836_snd_controls,
323 if (ret != 0) { 253 ARRAY_SIZE(ad1836_snd_controls));
324 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 254 snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets,
325 kfree(ad1836); 255 ARRAY_SIZE(ad1836_dapm_widgets));
326 return ret; 256 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
327 }
328
329 ret = snd_soc_register_dai(&ad1836_dai);
330 if (ret != 0) {
331 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
332 snd_soc_unregister_codec(codec);
333 kfree(ad1836);
334 return ret;
335 }
336 257
337 return 0; 258 return ret;
338} 259}
339 260
340static void ad1836_unregister(struct ad1836_priv *ad1836) 261/* power down chip */
262static int ad1836_remove(struct snd_soc_codec *codec)
341{ 263{
342 snd_soc_unregister_dai(&ad1836_dai); 264 /* reset clock control mode */
343 snd_soc_unregister_codec(&ad1836->codec); 265 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
344 kfree(ad1836); 266 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
345 ad1836_codec = NULL;
346}
347 267
348static int ad1836_probe(struct platform_device *pdev) 268 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
349{ 269}
350 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
351 struct snd_soc_codec *codec;
352 int ret = 0;
353 270
354 if (ad1836_codec == NULL) { 271static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
355 dev_err(&pdev->dev, "Codec device not registered\n"); 272 .probe = ad1836_probe,
356 return -ENODEV; 273 .remove = ad1836_remove,
357 } 274 .suspend = ad1836_soc_suspend,
275 .resume = ad1836_soc_resume,
276 .reg_cache_size = AD1836_NUM_REGS,
277 .reg_word_size = sizeof(u16),
278};
358 279
359 socdev->card->codec = ad1836_codec; 280static int __devinit ad1836_spi_probe(struct spi_device *spi)
360 codec = ad1836_codec; 281{
282 struct ad1836_priv *ad1836;
283 int ret;
361 284
362 /* register pcms */ 285 ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
363 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 286 if (ad1836 == NULL)
364 if (ret < 0) { 287 return -ENOMEM;
365 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
366 goto pcm_err;
367 }
368 288
369 snd_soc_add_controls(codec, ad1836_snd_controls, 289 spi_set_drvdata(spi, ad1836);
370 ARRAY_SIZE(ad1836_snd_controls)); 290 ad1836->control_data = spi;
371 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 291 ad1836->control_type = SND_SOC_SPI;
372 ARRAY_SIZE(ad1836_dapm_widgets));
373 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
374 292
375pcm_err: 293 ret = snd_soc_register_codec(&spi->dev,
294 &soc_codec_dev_ad1836, &ad1836_dai, 1);
295 if (ret < 0)
296 kfree(ad1836);
376 return ret; 297 return ret;
377} 298}
378 299
379/* power down chip */ 300static int __devexit ad1836_spi_remove(struct spi_device *spi)
380static int ad1836_remove(struct platform_device *pdev)
381{ 301{
382 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 302 snd_soc_unregister_codec(&spi->dev);
383 303 kfree(spi_get_drvdata(spi));
384 snd_soc_free_pcms(socdev);
385 snd_soc_dapm_free(socdev);
386
387 return 0; 304 return 0;
388} 305}
389 306
390struct snd_soc_codec_device soc_codec_dev_ad1836 = { 307static struct spi_driver ad1836_spi_driver = {
391 .probe = ad1836_probe, 308 .driver = {
392 .remove = ad1836_remove, 309 .name = "ad1836-codec",
393 .suspend = ad1836_soc_suspend, 310 .owner = THIS_MODULE,
394 .resume = ad1836_soc_resume, 311 },
312 .probe = ad1836_spi_probe,
313 .remove = __devexit_p(ad1836_spi_remove),
395}; 314};
396EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
397 315
398static int __init ad1836_init(void) 316static int __init ad1836_init(void)
399{ 317{
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index e9d90d3951c5..9d6a3f8f8aaf 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -25,6 +25,7 @@
25#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5) 25#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5)
26#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5) 26#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5)
27#define AD1836_DAC_WORD_LEN_MASK 0x18 27#define AD1836_DAC_WORD_LEN_MASK 0x18
28#define AD1836_DAC_WORD_LEN_OFFSET 3
28 29
29#define AD1836_DAC_CTRL2 1 30#define AD1836_DAC_CTRL2 1
30#define AD1836_DACL1_MUTE 0 31#define AD1836_DACL1_MUTE 0
@@ -51,6 +52,7 @@
51#define AD1836_ADCL2_MUTE 2 52#define AD1836_ADCL2_MUTE 2
52#define AD1836_ADCR2_MUTE 3 53#define AD1836_ADCR2_MUTE 3
53#define AD1836_ADC_WORD_LEN_MASK 0x30 54#define AD1836_ADC_WORD_LEN_MASK 0x30
55#define AD1836_ADC_WORD_OFFSET 5
54#define AD1836_ADC_SERFMT_MASK (7 << 6) 56#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) 57#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) 58#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
@@ -60,6 +62,8 @@
60 62
61#define AD1836_NUM_REGS 16 63#define AD1836_NUM_REGS 16
62 64
63extern struct snd_soc_dai ad1836_dai; 65#define AD1836_WORD_LEN_24 0x0
64extern struct snd_soc_codec_device soc_codec_dev_ad1836; 66#define AD1836_WORD_LEN_20 0x1
67#define AD1836_WORD_LEN_16 0x2
68
65#endif 69#endif
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 1def75e4862f..2374ca5ffe68 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -19,14 +19,12 @@
19#include <sound/initval.h> 19#include <sound/initval.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/tlv.h> 21#include <sound/tlv.h>
22#include <sound/soc-dapm.h>
23#include "ad193x.h" 22#include "ad193x.h"
24 23
25/* codec private data */ 24/* codec private data */
26struct ad193x_priv { 25struct ad193x_priv {
27 unsigned int sysclk; 26 enum snd_soc_control_type control_type;
28 struct snd_soc_codec codec; 27 int sysclk;
29 u8 reg_cache[AD193X_NUM_REGS];
30}; 28};
31 29
32/* ad193x register cache & default register settings */ 30/* ad193x register cache & default register settings */
@@ -34,9 +32,6 @@ static const u8 ad193x_reg[AD193X_NUM_REGS] = {
34 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 32 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
35}; 33};
36 34
37static struct snd_soc_codec *ad193x_codec;
38struct snd_soc_codec_device soc_codec_dev_ad193x;
39
40/* 35/*
41 * AD193X volume/mute/de-emphasis etc. controls 36 * AD193X volume/mute/de-emphasis etc. controls
42 */ 37 */
@@ -275,8 +270,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
275 int word_len = 0, reg = 0, master_rate = 0; 270 int word_len = 0, reg = 0, master_rate = 0;
276 271
277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 272 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_device *socdev = rtd->socdev; 273 struct snd_soc_codec *codec = rtd->codec;
279 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 274 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
281 275
282 /* bit size */ 276 /* bit size */
@@ -323,100 +317,6 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
323 return 0; 317 return 0;
324} 318}
325 319
326static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
327{
328 struct snd_soc_codec *codec;
329 struct ad193x_priv *ad193x;
330 int ret;
331
332 if (ad193x_codec) {
333 dev_err(dev, "Another ad193x is registered\n");
334 return -EINVAL;
335 }
336
337 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
338 if (ad193x == NULL)
339 return -ENOMEM;
340
341 dev_set_drvdata(dev, ad193x);
342
343 codec = &ad193x->codec;
344 mutex_init(&codec->mutex);
345 codec->control_data = ctrl_data;
346 codec->dev = dev;
347 snd_soc_codec_set_drvdata(codec, ad193x);
348 codec->reg_cache = ad193x->reg_cache;
349 codec->reg_cache_size = AD193X_NUM_REGS;
350 codec->name = "AD193X";
351 codec->owner = THIS_MODULE;
352 codec->dai = &ad193x_dai;
353 codec->num_dai = 1;
354 INIT_LIST_HEAD(&codec->dapm_widgets);
355 INIT_LIST_HEAD(&codec->dapm_paths);
356
357 ad193x_dai.dev = codec->dev;
358 ad193x_codec = codec;
359
360 memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
361
362 if (bus_type == SND_SOC_I2C)
363 ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
364 else
365 ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
366 if (ret < 0) {
367 dev_err(codec->dev, "failed to set cache I/O: %d\n",
368 ret);
369 kfree(ad193x);
370 return ret;
371 }
372
373 /* default setting for ad193x */
374
375 /* unmute dac channels */
376 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
377 /* de-emphasis: 48kHz, powedown dac */
378 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
379 /* powerdown dac, dac in tdm mode */
380 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
381 /* high-pass filter enable */
382 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
383 /* sata delay=1, adc aux mode */
384 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
385 /* pll input: mclki/xi */
386 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
387 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
388 ad193x->sysclk = 12288000;
389
390 ret = snd_soc_register_codec(codec);
391 if (ret != 0) {
392 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
393 kfree(ad193x);
394 return ret;
395 }
396
397 ret = snd_soc_register_dai(&ad193x_dai);
398 if (ret != 0) {
399 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
400 snd_soc_unregister_codec(codec);
401 kfree(ad193x);
402 return ret;
403 }
404
405 return 0;
406}
407
408static int ad193x_bus_remove(struct device *dev)
409{
410 struct ad193x_priv *ad193x = dev_get_drvdata(dev);
411
412 snd_soc_unregister_dai(&ad193x_dai);
413 snd_soc_unregister_codec(&ad193x->codec);
414 kfree(ad193x);
415 ad193x_codec = NULL;
416
417 return 0;
418}
419
420static struct snd_soc_dai_ops ad193x_dai_ops = { 320static struct snd_soc_dai_ops ad193x_dai_ops = {
421 .hw_params = ad193x_hw_params, 321 .hw_params = ad193x_hw_params,
422 .digital_mute = ad193x_mute, 322 .digital_mute = ad193x_mute,
@@ -426,8 +326,8 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
426}; 326};
427 327
428/* codec DAI instance */ 328/* codec DAI instance */
429struct snd_soc_dai ad193x_dai = { 329static struct snd_soc_dai_driver ad193x_dai = {
430 .name = "AD193X", 330 .name = "ad193x-hifi",
431 .playback = { 331 .playback = {
432 .stream_name = "Playback", 332 .stream_name = "Playback",
433 .channels_min = 2, 333 .channels_min = 2,
@@ -446,65 +346,79 @@ struct snd_soc_dai ad193x_dai = {
446 }, 346 },
447 .ops = &ad193x_dai_ops, 347 .ops = &ad193x_dai_ops,
448}; 348};
449EXPORT_SYMBOL_GPL(ad193x_dai);
450 349
451static int ad193x_probe(struct platform_device *pdev) 350static int ad193x_probe(struct snd_soc_codec *codec)
452{ 351{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 352 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
454 struct snd_soc_codec *codec; 353 struct snd_soc_dapm_context *dapm = &codec->dapm;
455 int ret = 0; 354 int ret;
456 355
457 if (ad193x_codec == NULL) { 356 if (ad193x->control_type == SND_SOC_I2C)
458 dev_err(&pdev->dev, "Codec device not registered\n"); 357 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type);
459 return -ENODEV; 358 else
359 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type);
360 if (ret < 0) {
361 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
362 return ret;
460 } 363 }
461 364
462 socdev->card->codec = ad193x_codec; 365 /* default setting for ad193x */
463 codec = ad193x_codec;
464 366
465 /* register pcms */ 367 /* unmute dac channels */
466 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 368 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
467 if (ret < 0) { 369 /* de-emphasis: 48kHz, powedown dac */
468 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 370 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
469 goto pcm_err; 371 /* powerdown dac, dac in tdm mode */
470 } 372 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
373 /* high-pass filter enable */
374 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
375 /* sata delay=1, adc aux mode */
376 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
377 /* pll input: mclki/xi */
378 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
379 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
471 380
472 snd_soc_add_controls(codec, ad193x_snd_controls, 381 snd_soc_add_controls(codec, ad193x_snd_controls,
473 ARRAY_SIZE(ad193x_snd_controls)); 382 ARRAY_SIZE(ad193x_snd_controls));
474 snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets, 383 snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
475 ARRAY_SIZE(ad193x_dapm_widgets)); 384 ARRAY_SIZE(ad193x_dapm_widgets));
476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 385 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
477 386
478pcm_err:
479 return ret; 387 return ret;
480} 388}
481 389
482/* power down chip */ 390static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
483static int ad193x_remove(struct platform_device *pdev)
484{
485 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
486
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489
490 return 0;
491}
492
493struct snd_soc_codec_device soc_codec_dev_ad193x = {
494 .probe = ad193x_probe, 391 .probe = ad193x_probe,
495 .remove = ad193x_remove, 392 .reg_cache_default = ad193x_reg,
393 .reg_cache_size = AD193X_NUM_REGS,
394 .reg_word_size = sizeof(u16),
496}; 395};
497EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
498 396
499#if defined(CONFIG_SPI_MASTER) 397#if defined(CONFIG_SPI_MASTER)
500static int __devinit ad193x_spi_probe(struct spi_device *spi) 398static int __devinit ad193x_spi_probe(struct spi_device *spi)
501{ 399{
502 return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI); 400 struct ad193x_priv *ad193x;
401 int ret;
402
403 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
404 if (ad193x == NULL)
405 return -ENOMEM;
406
407 spi_set_drvdata(spi, ad193x);
408 ad193x->control_type = SND_SOC_SPI;
409
410 ret = snd_soc_register_codec(&spi->dev,
411 &soc_codec_dev_ad193x, &ad193x_dai, 1);
412 if (ret < 0)
413 kfree(ad193x);
414 return ret;
503} 415}
504 416
505static int __devexit ad193x_spi_remove(struct spi_device *spi) 417static int __devexit ad193x_spi_remove(struct spi_device *spi)
506{ 418{
507 return ad193x_bus_remove(&spi->dev); 419 snd_soc_unregister_codec(&spi->dev);
420 kfree(spi_get_drvdata(spi));
421 return 0;
508} 422}
509 423
510static struct spi_driver ad193x_spi_driver = { 424static struct spi_driver ad193x_spi_driver = {
@@ -528,12 +442,28 @@ MODULE_DEVICE_TABLE(i2c, ad193x_id);
528static int __devinit ad193x_i2c_probe(struct i2c_client *client, 442static int __devinit ad193x_i2c_probe(struct i2c_client *client,
529 const struct i2c_device_id *id) 443 const struct i2c_device_id *id)
530{ 444{
531 return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C); 445 struct ad193x_priv *ad193x;
446 int ret;
447
448 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
449 if (ad193x == NULL)
450 return -ENOMEM;
451
452 i2c_set_clientdata(client, ad193x);
453 ad193x->control_type = SND_SOC_I2C;
454
455 ret = snd_soc_register_codec(&client->dev,
456 &soc_codec_dev_ad193x, &ad193x_dai, 1);
457 if (ret < 0)
458 kfree(ad193x);
459 return ret;
532} 460}
533 461
534static int __devexit ad193x_i2c_remove(struct i2c_client *client) 462static int __devexit ad193x_i2c_remove(struct i2c_client *client)
535{ 463{
536 return ad193x_bus_remove(&client->dev); 464 snd_soc_unregister_codec(&client->dev);
465 kfree(i2c_get_clientdata(client));
466 return 0;
537} 467}
538 468
539static struct i2c_driver ad193x_i2c_driver = { 469static struct i2c_driver ad193x_i2c_driver = {
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 654ba64ae04c..9747b5497877 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -80,7 +80,4 @@
80 80
81#define AD193X_NUM_REGS 17 81#define AD193X_NUM_REGS 17
82 82
83extern struct snd_soc_dai ad193x_dai;
84extern struct snd_soc_codec_device soc_codec_dev_ad193x;
85
86#endif 83#endif
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 70cfaec3be2c..923b364a3e41 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -29,15 +29,9 @@
29#include <sound/ac97_codec.h> 29#include <sound/ac97_codec.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33 32
34#include "ad1980.h" 33#include "ad1980.h"
35 34
36static unsigned int ac97_read(struct snd_soc_codec *codec,
37 unsigned int reg);
38static int ac97_write(struct snd_soc_codec *codec,
39 unsigned int reg, unsigned int val);
40
41/* 35/*
42 * AD1980 register cache 36 * AD1980 register cache
43 */ 37 */
@@ -138,8 +132,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
138 return 0; 132 return 0;
139} 133}
140 134
141struct snd_soc_dai ad1980_dai = { 135static struct snd_soc_dai_driver ad1980_dai = {
142 .name = "AC97", 136 .name = "ad1980-hifi",
143 .ac97_control = 1, 137 .ac97_control = 1,
144 .playback = { 138 .playback = {
145 .stream_name = "Playback", 139 .stream_name = "Playback",
@@ -185,53 +179,20 @@ err:
185 return -EIO; 179 return -EIO;
186} 180}
187 181
188static int ad1980_soc_probe(struct platform_device *pdev) 182static int ad1980_soc_probe(struct snd_soc_codec *codec)
189{ 183{
190 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 184 int ret;
191 struct snd_soc_codec *codec;
192 int ret = 0;
193 u16 vendor_id2; 185 u16 vendor_id2;
194 u16 ext_status; 186 u16 ext_status;
195 187
196 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 188 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
197 189
198 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
199 if (socdev->card->codec == NULL)
200 return -ENOMEM;
201 codec = socdev->card->codec;
202 mutex_init(&codec->mutex);
203
204 codec->reg_cache =
205 kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
206 if (codec->reg_cache == NULL) {
207 ret = -ENOMEM;
208 goto cache_err;
209 }
210 memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
211 ARRAY_SIZE(ad1980_reg));
212 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
213 codec->reg_cache_step = 2;
214 codec->name = "AD1980";
215 codec->owner = THIS_MODULE;
216 codec->dai = &ad1980_dai;
217 codec->num_dai = 1;
218 codec->write = ac97_write;
219 codec->read = ac97_read;
220 INIT_LIST_HEAD(&codec->dapm_widgets);
221 INIT_LIST_HEAD(&codec->dapm_paths);
222
223 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 190 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
224 if (ret < 0) { 191 if (ret < 0) {
225 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 192 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
226 goto codec_err; 193 return ret;
227 } 194 }
228 195
229 /* register pcms */
230 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
231 if (ret < 0)
232 goto pcm_err;
233
234
235 ret = ad1980_reset(codec, 0); 196 ret = ad1980_reset(codec, 0);
236 if (ret < 0) { 197 if (ret < 0) {
237 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n"); 198 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
@@ -270,41 +231,60 @@ static int ad1980_soc_probe(struct platform_device *pdev)
270 return 0; 231 return 0;
271 232
272reset_err: 233reset_err:
273 snd_soc_free_pcms(socdev);
274
275pcm_err:
276 snd_soc_free_ac97_codec(codec); 234 snd_soc_free_ac97_codec(codec);
277
278codec_err:
279 kfree(codec->reg_cache);
280
281cache_err:
282 kfree(socdev->card->codec);
283 socdev->card->codec = NULL;
284 return ret; 235 return ret;
285} 236}
286 237
287static int ad1980_soc_remove(struct platform_device *pdev) 238static int ad1980_soc_remove(struct snd_soc_codec *codec)
288{ 239{
289 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
290 struct snd_soc_codec *codec = socdev->card->codec;
291
292 if (codec == NULL)
293 return 0;
294
295 snd_soc_dapm_free(socdev);
296 snd_soc_free_pcms(socdev);
297 snd_soc_free_ac97_codec(codec); 240 snd_soc_free_ac97_codec(codec);
298 kfree(codec->reg_cache);
299 kfree(codec);
300 return 0; 241 return 0;
301} 242}
302 243
303struct snd_soc_codec_device soc_codec_dev_ad1980 = { 244static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
304 .probe = ad1980_soc_probe, 245 .probe = ad1980_soc_probe,
305 .remove = ad1980_soc_remove, 246 .remove = ad1980_soc_remove,
247 .reg_cache_size = ARRAY_SIZE(ad1980_reg),
248 .reg_word_size = sizeof(u16),
249 .reg_cache_default = ad1980_reg,
250 .reg_cache_step = 2,
251 .write = ac97_write,
252 .read = ac97_read,
306}; 253};
307EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980); 254
255static __devinit int ad1980_probe(struct platform_device *pdev)
256{
257 return snd_soc_register_codec(&pdev->dev,
258 &soc_codec_dev_ad1980, &ad1980_dai, 1);
259}
260
261static int __devexit ad1980_remove(struct platform_device *pdev)
262{
263 snd_soc_unregister_codec(&pdev->dev);
264 return 0;
265}
266
267static struct platform_driver ad1980_codec_driver = {
268 .driver = {
269 .name = "ad1980",
270 .owner = THIS_MODULE,
271 },
272
273 .probe = ad1980_probe,
274 .remove = __devexit_p(ad1980_remove),
275};
276
277static int __init ad1980_init(void)
278{
279 return platform_driver_register(&ad1980_codec_driver);
280}
281module_init(ad1980_init);
282
283static void __exit ad1980_exit(void)
284{
285 platform_driver_unregister(&ad1980_codec_driver);
286}
287module_exit(ad1980_exit);
308 288
309MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)"); 289MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)");
310MODULE_AUTHOR("Roy Huang, Cliff Cai"); 290MODULE_AUTHOR("Roy Huang, Cliff Cai");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
index 538f37c90806..eb0af44ad3df 100644
--- a/sound/soc/codecs/ad1980.h
+++ b/sound/soc/codecs/ad1980.h
@@ -23,7 +23,4 @@
23#define PR5 0x2000 23#define PR5 0x2000
24#define PR6 0x4000 24#define PR6 0x4000
25 25
26extern struct snd_soc_dai ad1980_dai;
27extern struct snd_soc_codec_device soc_codec_dev_ad1980;
28
29#endif 26#endif
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 475807bea2c2..8d793e993e9a 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -23,8 +23,8 @@
23 23
24#include "ad73311.h" 24#include "ad73311.h"
25 25
26struct snd_soc_dai ad73311_dai = { 26static struct snd_soc_dai_driver ad73311_dai = {
27 .name = "AD73311", 27 .name = "ad73311-hifi",
28 .playback = { 28 .playback = {
29 .stream_name = "Playback", 29 .stream_name = "Playback",
30 .channels_min = 1, 30 .channels_min = 1,
@@ -38,68 +38,40 @@ struct snd_soc_dai ad73311_dai = {
38 .rates = SNDRV_PCM_RATE_8000, 38 .rates = SNDRV_PCM_RATE_8000,
39 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 39 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
40}; 40};
41EXPORT_SYMBOL_GPL(ad73311_dai);
42 41
43static int ad73311_soc_probe(struct platform_device *pdev) 42static struct snd_soc_codec_driver soc_codec_dev_ad73311;
44{
45 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
46 struct snd_soc_codec *codec;
47 int ret = 0;
48
49 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
50 if (codec == NULL)
51 return -ENOMEM;
52 mutex_init(&codec->mutex);
53 codec->name = "AD73311";
54 codec->owner = THIS_MODULE;
55 codec->dai = &ad73311_dai;
56 codec->num_dai = 1;
57 socdev->card->codec = codec;
58 INIT_LIST_HEAD(&codec->dapm_widgets);
59 INIT_LIST_HEAD(&codec->dapm_paths);
60
61 /* register pcms */
62 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
63 if (ret < 0) {
64 printk(KERN_ERR "ad73311: failed to create pcms\n");
65 goto pcm_err;
66 }
67
68 return ret;
69 43
70pcm_err: 44static int ad73311_probe(struct platform_device *pdev)
71 kfree(socdev->card->codec); 45{
72 socdev->card->codec = NULL; 46 return snd_soc_register_codec(&pdev->dev,
73 return ret; 47 &soc_codec_dev_ad73311, &ad73311_dai, 1);
74} 48}
75 49
76static int ad73311_soc_remove(struct platform_device *pdev) 50static int __devexit ad73311_remove(struct platform_device *pdev)
77{ 51{
78 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 52 snd_soc_unregister_codec(&pdev->dev);
79 struct snd_soc_codec *codec = socdev->card->codec;
80
81 if (codec == NULL)
82 return 0;
83 snd_soc_free_pcms(socdev);
84 kfree(codec);
85 return 0; 53 return 0;
86} 54}
87 55
88struct snd_soc_codec_device soc_codec_dev_ad73311 = { 56static struct platform_driver ad73311_codec_driver = {
89 .probe = ad73311_soc_probe, 57 .driver = {
90 .remove = ad73311_soc_remove, 58 .name = "ad73311",
59 .owner = THIS_MODULE,
60 },
61
62 .probe = ad73311_probe,
63 .remove = __devexit_p(ad73311_remove),
91}; 64};
92EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
93 65
94static int __init ad73311_init(void) 66static int __init ad73311_init(void)
95{ 67{
96 return snd_soc_register_dai(&ad73311_dai); 68 return platform_driver_register(&ad73311_codec_driver);
97} 69}
98module_init(ad73311_init); 70module_init(ad73311_init);
99 71
100static void __exit ad73311_exit(void) 72static void __exit ad73311_exit(void)
101{ 73{
102 snd_soc_unregister_dai(&ad73311_dai); 74 platform_driver_unregister(&ad73311_codec_driver);
103} 75}
104module_exit(ad73311_exit); 76module_exit(ad73311_exit);
105 77
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
index 569573d2d4d7..4b353eefc0bf 100644
--- a/sound/soc/codecs/ad73311.h
+++ b/sound/soc/codecs/ad73311.h
@@ -85,6 +85,4 @@
85#define REGF_INV (1 << 6) 85#define REGF_INV (1 << 6)
86#define REGF_ALB (1 << 7) 86#define REGF_ALB (1 << 7)
87 87
88extern struct snd_soc_dai ad73311_dai;
89extern struct snd_soc_codec_device soc_codec_dev_ad73311;
90#endif 88#endif
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index f8e75edb27b7..8402854ec15e 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -19,16 +19,12 @@
19#include <sound/initval.h> 19#include <sound/initval.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21 21
22#include "ads117x.h"
23
24#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000) 22#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
25
26#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) 23#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
27 24
28struct snd_soc_dai ads117x_dai = { 25static struct snd_soc_dai_driver ads117x_dai = {
29/* ADC */ 26/* ADC */
30 .name = "ADS117X ADC", 27 .name = "ads117x-hifi",
31 .id = 1,
32 .capture = { 28 .capture = {
33 .stream_name = "Capture", 29 .stream_name = "Capture",
34 .channels_min = 1, 30 .channels_min = 1,
@@ -36,75 +32,29 @@ struct snd_soc_dai ads117x_dai = {
36 .rates = ADS117X_RATES, 32 .rates = ADS117X_RATES,
37 .formats = ADS117X_FORMATS,}, 33 .formats = ADS117X_FORMATS,},
38}; 34};
39EXPORT_SYMBOL_GPL(ads117x_dai);
40
41static int ads117x_probe(struct platform_device *pdev)
42{
43 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
44 struct snd_soc_codec *codec;
45 int ret;
46
47 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
48 if (codec == NULL)
49 return -ENOMEM;
50 35
51 socdev->card->codec = codec; 36static struct snd_soc_codec_driver soc_codec_dev_ads117x;
52 mutex_init(&codec->mutex);
53 INIT_LIST_HEAD(&codec->dapm_widgets);
54 INIT_LIST_HEAD(&codec->dapm_paths);
55 codec->name = "ADS117X";
56 codec->owner = THIS_MODULE;
57 codec->dai = &ads117x_dai;
58 codec->num_dai = 1;
59
60 /* register pcms */
61 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
62 if (ret < 0) {
63 printk(KERN_ERR "ads117x: failed to create pcms\n");
64 kfree(codec);
65 return ret;
66 }
67
68 return 0;
69}
70
71static int ads117x_remove(struct platform_device *pdev)
72{
73 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
74 struct snd_soc_codec *codec = socdev->card->codec;
75
76 snd_soc_free_pcms(socdev);
77 kfree(codec);
78
79 return 0;
80}
81
82struct snd_soc_codec_device soc_codec_dev_ads117x = {
83 .probe = ads117x_probe,
84 .remove = ads117x_remove,
85};
86EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
87 37
88static __devinit int ads117x_platform_probe(struct platform_device *pdev) 38static __devinit int ads117x_probe(struct platform_device *pdev)
89{ 39{
90 ads117x_dai.dev = &pdev->dev; 40 return snd_soc_register_codec(&pdev->dev,
91 return snd_soc_register_dai(&ads117x_dai); 41 &soc_codec_dev_ads117x, &ads117x_dai, 1);
92} 42}
93 43
94static int __devexit ads117x_platform_remove(struct platform_device *pdev) 44static int __devexit ads117x_remove(struct platform_device *pdev)
95{ 45{
96 snd_soc_unregister_dai(&ads117x_dai); 46 snd_soc_unregister_codec(&pdev->dev);
97 return 0; 47 return 0;
98} 48}
99 49
100static struct platform_driver ads117x_codec_driver = { 50static struct platform_driver ads117x_codec_driver = {
101 .driver = { 51 .driver = {
102 .name = "ads117x", 52 .name = "ads117x-codec",
103 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
104 }, 54 },
105 55
106 .probe = ads117x_platform_probe, 56 .probe = ads117x_probe,
107 .remove = __devexit_p(ads117x_platform_remove), 57 .remove = __devexit_p(ads117x_remove),
108}; 58};
109 59
110static int __init ads117x_init(void) 60static int __init ads117x_init(void)
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
index dbcf50ec9bd1..3ce028614002 100644
--- a/sound/soc/codecs/ads117x.h
+++ b/sound/soc/codecs/ads117x.h
@@ -9,5 +9,5 @@
9 * Free Software Foundation; either version 2 of the License, or (at your 9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. 10 * option) any later version.
11 */ 11 */
12extern struct snd_soc_dai ads117x_dai; 12extern struct snd_soc_dai_driver ads117x_dai;
13extern struct snd_soc_codec_device soc_codec_dev_ads117x; 13extern struct snd_soc_codec_driver soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 192aebda3029..cbf0b6d400b8 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -17,8 +17,6 @@
17#include <linux/spi/spi.h> 17#include <linux/spi/spi.h>
18#include <sound/asoundef.h> 18#include <sound/asoundef.h>
19 19
20#include "ak4104.h"
21
22/* AK4104 registers addresses */ 20/* AK4104 registers addresses */
23#define AK4104_REG_CONTROL1 0x00 21#define AK4104_REG_CONTROL1 0x00
24#define AK4104_REG_RESERVED 0x01 22#define AK4104_REG_RESERVED 0x01
@@ -45,11 +43,11 @@
45#define AK4104_TX_TXE (1 << 0) 43#define AK4104_TX_TXE (1 << 0)
46#define AK4104_TX_V (1 << 1) 44#define AK4104_TX_V (1 << 1)
47 45
48#define DRV_NAME "ak4104" 46#define DRV_NAME "ak4104-codec"
49 47
50struct ak4104_private { 48struct ak4104_private {
51 struct snd_soc_codec codec; 49 enum snd_soc_control_type control_type;
52 u8 reg_cache[AK4104_NUM_REGS]; 50 void *control_data;
53}; 51};
54 52
55static int ak4104_fill_cache(struct snd_soc_codec *codec) 53static int ak4104_fill_cache(struct snd_soc_codec *codec)
@@ -58,7 +56,7 @@ static int ak4104_fill_cache(struct snd_soc_codec *codec)
58 u8 *reg_cache = codec->reg_cache; 56 u8 *reg_cache = codec->reg_cache;
59 struct spi_device *spi = codec->control_data; 57 struct spi_device *spi = codec->control_data;
60 58
61 for (i = 0; i < codec->reg_cache_size; i++) { 59 for (i = 0; i < codec->driver->reg_cache_size; i++) {
62 int ret = spi_w8r8(spi, i | AK4104_READ); 60 int ret = spi_w8r8(spi, i | AK4104_READ);
63 if (ret < 0) { 61 if (ret < 0) {
64 dev_err(&spi->dev, "SPI write failure\n"); 62 dev_err(&spi->dev, "SPI write failure\n");
@@ -76,7 +74,7 @@ static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
76{ 74{
77 u8 *reg_cache = codec->reg_cache; 75 u8 *reg_cache = codec->reg_cache;
78 76
79 if (reg >= codec->reg_cache_size) 77 if (reg >= codec->driver->reg_cache_size)
80 return -EINVAL; 78 return -EINVAL;
81 79
82 return reg_cache[reg]; 80 return reg_cache[reg];
@@ -88,7 +86,7 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
88 u8 *cache = codec->reg_cache; 86 u8 *cache = codec->reg_cache;
89 struct spi_device *spi = codec->control_data; 87 struct spi_device *spi = codec->control_data;
90 88
91 if (reg >= codec->reg_cache_size) 89 if (reg >= codec->driver->reg_cache_size)
92 return -EINVAL; 90 return -EINVAL;
93 91
94 /* only write to the hardware if value has changed */ 92 /* only write to the hardware if value has changed */
@@ -145,8 +143,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai) 143 struct snd_soc_dai *dai)
146{ 144{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev; 146 struct snd_soc_codec *codec = rtd->codec;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 int val = 0; 147 int val = 0;
151 148
152 /* set the IEC958 bits: consumer mode, no copyright bit */ 149 /* set the IEC958 bits: consumer mode, no copyright bit */
@@ -178,8 +175,8 @@ static struct snd_soc_dai_ops ak4101_dai_ops = {
178 .set_fmt = ak4104_set_dai_fmt, 175 .set_fmt = ak4104_set_dai_fmt,
179}; 176};
180 177
181struct snd_soc_dai ak4104_dai = { 178static struct snd_soc_dai_driver ak4104_dai = {
182 .name = DRV_NAME, 179 .name = "ak4104-hifi",
183 .playback = { 180 .playback = {
184 .stream_name = "Playback", 181 .stream_name = "Playback",
185 .channels_min = 2, 182 .channels_min = 2,
@@ -192,45 +189,17 @@ struct snd_soc_dai ak4104_dai = {
192 .ops = &ak4101_dai_ops, 189 .ops = &ak4101_dai_ops,
193}; 190};
194 191
195static struct snd_soc_codec *ak4104_codec; 192static int ak4104_probe(struct snd_soc_codec *codec)
196
197static int ak4104_spi_probe(struct spi_device *spi)
198{ 193{
199 struct snd_soc_codec *codec; 194 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
200 struct ak4104_private *ak4104;
201 int ret, val; 195 int ret, val;
202 196
203 spi->bits_per_word = 8; 197 codec->control_data = ak4104->control_data;
204 spi->mode = SPI_MODE_0;
205 ret = spi_setup(spi);
206 if (ret < 0)
207 return ret;
208
209 ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
210 if (!ak4104) {
211 dev_err(&spi->dev, "could not allocate codec\n");
212 return -ENOMEM;
213 }
214
215 codec = &ak4104->codec;
216 mutex_init(&codec->mutex);
217 INIT_LIST_HEAD(&codec->dapm_widgets);
218 INIT_LIST_HEAD(&codec->dapm_paths);
219
220 codec->dev = &spi->dev;
221 codec->name = DRV_NAME;
222 codec->owner = THIS_MODULE;
223 codec->dai = &ak4104_dai;
224 codec->num_dai = 1;
225 snd_soc_codec_set_drvdata(codec, ak4104);
226 codec->control_data = spi;
227 codec->reg_cache = ak4104->reg_cache;
228 codec->reg_cache_size = AK4104_NUM_REGS;
229 198
230 /* read all regs and fill the cache */ 199 /* read all regs and fill the cache */
231 ret = ak4104_fill_cache(codec); 200 ret = ak4104_fill_cache(codec);
232 if (ret < 0) { 201 if (ret < 0) {
233 dev_err(&spi->dev, "failed to fill register cache\n"); 202 dev_err(codec->dev, "failed to fill register cache\n");
234 return ret; 203 return ret;
235 } 204 }
236 205
@@ -238,93 +207,81 @@ static int ak4104_spi_probe(struct spi_device *spi)
238 * should contain 0x5b. Not a good way to verify the presence of 207 * should contain 0x5b. Not a good way to verify the presence of
239 * the device, but there is no hardware ID register. */ 208 * the device, but there is no hardware ID register. */
240 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) != 209 if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
241 AK4104_RESERVED_VAL) { 210 AK4104_RESERVED_VAL)
242 ret = -ENODEV; 211 return -ENODEV;
243 goto error_free_codec;
244 }
245 212
246 /* set power-up and non-reset bits */ 213 /* set power-up and non-reset bits */
247 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); 214 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
248 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; 215 val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
249 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); 216 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
250 if (ret < 0) 217 if (ret < 0)
251 goto error_free_codec; 218 return ret;
252 219
253 /* enable transmitter */ 220 /* enable transmitter */
254 val = ak4104_read_reg_cache(codec, AK4104_REG_TX); 221 val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
255 val |= AK4104_TX_TXE; 222 val |= AK4104_TX_TXE;
256 ret = ak4104_spi_write(codec, AK4104_REG_TX, val); 223 ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
257 if (ret < 0) 224 if (ret < 0)
258 goto error_free_codec; 225 return ret;
259
260 ak4104_codec = codec;
261 ret = snd_soc_register_dai(&ak4104_dai);
262 if (ret < 0) {
263 dev_err(&spi->dev, "failed to register DAI\n");
264 goto error_free_codec;
265 }
266 226
267 spi_set_drvdata(spi, ak4104); 227 dev_info(codec->dev, "SPI device initialized\n");
268 dev_info(&spi->dev, "SPI device initialized\n");
269 return 0; 228 return 0;
270
271error_free_codec:
272 kfree(ak4104);
273 ak4104_dai.dev = NULL;
274 return ret;
275} 229}
276 230
277static int __devexit ak4104_spi_remove(struct spi_device *spi) 231static int ak4104_remove(struct snd_soc_codec *codec)
278{ 232{
279 int ret, val; 233 int val, ret;
280 struct ak4104_private *ak4104 = spi_get_drvdata(spi);
281 234
282 val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1); 235 val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
283 if (val < 0) 236 if (val < 0)
284 return val; 237 return val;
285 238
286 /* clear power-up and non-reset bits */ 239 /* clear power-up and non-reset bits */
287 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); 240 val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
288 ret = ak4104_spi_write(&ak4104->codec, AK4104_REG_CONTROL1, val); 241 ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
289 if (ret < 0)
290 return ret;
291 242
292 ak4104_codec = NULL; 243 return ret;
293 kfree(ak4104);
294 return 0;
295} 244}
296 245
297static int ak4104_probe(struct platform_device *pdev) 246static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
247 .probe = ak4104_probe,
248 .remove = ak4104_remove,
249 .reg_cache_size = AK4104_NUM_REGS,
250 .reg_word_size = sizeof(u16),
251};
252
253static int ak4104_spi_probe(struct spi_device *spi)
298{ 254{
299 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 255 struct ak4104_private *ak4104;
300 struct snd_soc_codec *codec = ak4104_codec;
301 int ret; 256 int ret;
302 257
303 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 258 spi->bits_per_word = 8;
304 socdev->card->codec = codec; 259 spi->mode = SPI_MODE_0;
305 260 ret = spi_setup(spi);
306 /* Register PCMs */ 261 if (ret < 0)
307 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
308 if (ret < 0) {
309 dev_err(codec->dev, "failed to create pcms\n");
310 return ret; 262 return ret;
311 }
312 263
313 return 0; 264 ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
265 if (ak4104 == NULL)
266 return -ENOMEM;
267
268 ak4104->control_data = spi;
269 ak4104->control_type = SND_SOC_SPI;
270 spi_set_drvdata(spi, ak4104);
271
272 ret = snd_soc_register_codec(&spi->dev,
273 &soc_codec_device_ak4104, &ak4104_dai, 1);
274 if (ret < 0)
275 kfree(ak4104);
276 return ret;
314} 277}
315 278
316static int ak4104_remove(struct platform_device *pdev) 279static int __devexit ak4104_spi_remove(struct spi_device *spi)
317{ 280{
318 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 281 snd_soc_unregister_codec(&spi->dev);
319 snd_soc_free_pcms(socdev); 282 kfree(spi_get_drvdata(spi));
320 return 0; 283 return 0;
321}; 284}
322
323struct snd_soc_codec_device soc_codec_device_ak4104 = {
324 .probe = ak4104_probe,
325 .remove = ak4104_remove
326};
327EXPORT_SYMBOL_GPL(soc_codec_device_ak4104);
328 285
329static struct spi_driver ak4104_spi_driver = { 286static struct spi_driver ak4104_spi_driver = {
330 .driver = { 287 .driver = {
@@ -337,7 +294,6 @@ static struct spi_driver ak4104_spi_driver = {
337 294
338static int __init ak4104_init(void) 295static int __init ak4104_init(void)
339{ 296{
340 pr_info("Asahi Kasei AK4104 ALSA SoC Codec Driver\n");
341 return spi_register_driver(&ak4104_spi_driver); 297 return spi_register_driver(&ak4104_spi_driver);
342} 298}
343module_init(ak4104_init); 299module_init(ak4104_init);
diff --git a/sound/soc/codecs/ak4104.h b/sound/soc/codecs/ak4104.h
deleted file mode 100644
index eb88fe7e4def..000000000000
--- a/sound/soc/codecs/ak4104.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef _AK4104_H
2#define _AK4104_H
3
4extern struct snd_soc_dai ak4104_dai;
5extern struct snd_soc_codec_device soc_codec_device_ak4104;
6
7#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index d4253675b2d3..e1a214ee757f 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -24,18 +24,17 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29 28
30#include "ak4535.h" 29#include "ak4535.h"
31 30
32#define AK4535_VERSION "0.3" 31#define AK4535_VERSION "0.3"
33 32
34struct snd_soc_codec_device soc_codec_dev_ak4535;
35
36/* codec private data */ 33/* codec private data */
37struct ak4535_priv { 34struct ak4535_priv {
38 unsigned int sysclk; 35 unsigned int sysclk;
36 enum snd_soc_control_type control_type;
37 void *control_data;
39}; 38};
40 39
41/* 40/*
@@ -231,7 +230,7 @@ static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
231 SND_SOC_DAPM_INPUT("AIN"), 230 SND_SOC_DAPM_INPUT("AIN"),
232}; 231};
233 232
234static const struct snd_soc_dapm_route audio_map[] = { 233static const struct snd_soc_dapm_route ak4535_audio_map[] = {
235 /*stereo mixer */ 234 /*stereo mixer */
236 {"Stereo Mixer", "Playback Switch", "DAC"}, 235 {"Stereo Mixer", "Playback Switch", "DAC"},
237 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, 236 {"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
@@ -288,16 +287,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
288 {"Input Mixer", "Aux Capture Switch", "Aux In"}, 287 {"Input Mixer", "Aux Capture Switch", "Aux In"},
289}; 288};
290 289
291static int ak4535_add_widgets(struct snd_soc_codec *codec)
292{
293 snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets,
294 ARRAY_SIZE(ak4535_dapm_widgets));
295
296 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
297
298 return 0;
299}
300
301static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, 290static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
302 int clk_id, unsigned int freq, int dir) 291 int clk_id, unsigned int freq, int dir)
303{ 292{
@@ -313,8 +302,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
313 struct snd_soc_dai *dai) 302 struct snd_soc_dai *dai)
314{ 303{
315 struct snd_soc_pcm_runtime *rtd = substream->private_data; 304 struct snd_soc_pcm_runtime *rtd = substream->private_data;
316 struct snd_soc_device *socdev = rtd->socdev; 305 struct snd_soc_codec *codec = rtd->codec;
317 struct snd_soc_codec *codec = socdev->card->codec;
318 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 306 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
319 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 307 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
320 int rate = params_rate(params), fs = 256; 308 int rate = params_rate(params), fs = 256;
@@ -367,9 +355,9 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
367static int ak4535_mute(struct snd_soc_dai *dai, int mute) 355static int ak4535_mute(struct snd_soc_dai *dai, int mute)
368{ 356{
369 struct snd_soc_codec *codec = dai->codec; 357 struct snd_soc_codec *codec = dai->codec;
370 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; 358 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
371 if (!mute) 359 if (!mute)
372 ak4535_write(codec, AK4535_DAC, mute_reg); 360 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
373 else 361 else
374 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); 362 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
375 return 0; 363 return 0;
@@ -378,14 +366,16 @@ static int ak4535_mute(struct snd_soc_dai *dai, int mute)
378static int ak4535_set_bias_level(struct snd_soc_codec *codec, 366static int ak4535_set_bias_level(struct snd_soc_codec *codec,
379 enum snd_soc_bias_level level) 367 enum snd_soc_bias_level level)
380{ 368{
381 u16 i; 369 u16 i, mute_reg;
382 370
383 switch (level) { 371 switch (level) {
384 case SND_SOC_BIAS_ON: 372 case SND_SOC_BIAS_ON:
385 ak4535_mute(codec->dai, 0); 373 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
374 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
386 break; 375 break;
387 case SND_SOC_BIAS_PREPARE: 376 case SND_SOC_BIAS_PREPARE:
388 ak4535_mute(codec->dai, 1); 377 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
378 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
389 break; 379 break;
390 case SND_SOC_BIAS_STANDBY: 380 case SND_SOC_BIAS_STANDBY:
391 i = ak4535_read_reg_cache(codec, AK4535_PM1); 381 i = ak4535_read_reg_cache(codec, AK4535_PM1);
@@ -398,7 +388,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
398 ak4535_write(codec, AK4535_PM1, i & (~0x80)); 388 ak4535_write(codec, AK4535_PM1, i & (~0x80));
399 break; 389 break;
400 } 390 }
401 codec->bias_level = level; 391 codec->dapm.bias_level = level;
402 return 0; 392 return 0;
403} 393}
404 394
@@ -413,8 +403,8 @@ static struct snd_soc_dai_ops ak4535_dai_ops = {
413 .set_sysclk = ak4535_set_dai_sysclk, 403 .set_sysclk = ak4535_set_dai_sysclk,
414}; 404};
415 405
416struct snd_soc_dai ak4535_dai = { 406static struct snd_soc_dai_driver ak4535_dai = {
417 .name = "AK4535", 407 .name = "ak4535-hifi",
418 .playback = { 408 .playback = {
419 .stream_name = "Playback", 409 .stream_name = "Playback",
420 .channels_min = 1, 410 .channels_min = 1,
@@ -429,95 +419,86 @@ struct snd_soc_dai ak4535_dai = {
429 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 419 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
430 .ops = &ak4535_dai_ops, 420 .ops = &ak4535_dai_ops,
431}; 421};
432EXPORT_SYMBOL_GPL(ak4535_dai);
433 422
434static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) 423static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state)
435{ 424{
436 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
437 struct snd_soc_codec *codec = socdev->card->codec;
438
439 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); 425 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
440 return 0; 426 return 0;
441} 427}
442 428
443static int ak4535_resume(struct platform_device *pdev) 429static int ak4535_resume(struct snd_soc_codec *codec)
444{ 430{
445 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
446 struct snd_soc_codec *codec = socdev->card->codec;
447 ak4535_sync(codec); 431 ak4535_sync(codec);
448 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 432 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
449 return 0; 433 return 0;
450} 434}
451 435
452/* 436static int ak4535_probe(struct snd_soc_codec *codec)
453 * initialise the AK4535 driver
454 * register the mixer and dsp interfaces with the kernel
455 */
456static int ak4535_init(struct snd_soc_device *socdev)
457{ 437{
458 struct snd_soc_codec *codec = socdev->card->codec; 438 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
459 int ret = 0;
460 439
461 codec->name = "AK4535"; 440 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
462 codec->owner = THIS_MODULE;
463 codec->read = ak4535_read_reg_cache;
464 codec->write = ak4535_write;
465 codec->set_bias_level = ak4535_set_bias_level;
466 codec->dai = &ak4535_dai;
467 codec->num_dai = 1;
468 codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
469 codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL);
470
471 if (codec->reg_cache == NULL)
472 return -ENOMEM;
473 441
474 /* register pcms */ 442 codec->control_data = ak4535->control_data;
475 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
476 if (ret < 0) {
477 printk(KERN_ERR "ak4535: failed to create pcms\n");
478 goto pcm_err;
479 }
480 443
481 /* power on device */ 444 /* power on device */
482 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 445 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
483 446
484 snd_soc_add_controls(codec, ak4535_snd_controls, 447 snd_soc_add_controls(codec, ak4535_snd_controls,
485 ARRAY_SIZE(ak4535_snd_controls)); 448 ARRAY_SIZE(ak4535_snd_controls));
486 ak4535_add_widgets(codec); 449 return 0;
487 450}
488 return ret;
489
490pcm_err:
491 kfree(codec->reg_cache);
492 451
493 return ret; 452/* power down chip */
453static int ak4535_remove(struct snd_soc_codec *codec)
454{
455 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
456 return 0;
494} 457}
495 458
496static struct snd_soc_device *ak4535_socdev; 459static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
460 .probe = ak4535_probe,
461 .remove = ak4535_remove,
462 .suspend = ak4535_suspend,
463 .resume = ak4535_resume,
464 .read = ak4535_read_reg_cache,
465 .write = ak4535_write,
466 .set_bias_level = ak4535_set_bias_level,
467 .reg_cache_size = ARRAY_SIZE(ak4535_reg),
468 .reg_word_size = sizeof(u8),
469 .reg_cache_default = ak4535_reg,
470 .dapm_widgets = ak4535_dapm_widgets,
471 .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
472 .dapm_routes = ak4535_audio_map,
473 .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
474};
497 475
498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 476#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
499 477static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
500static int ak4535_i2c_probe(struct i2c_client *i2c, 478 const struct i2c_device_id *id)
501 const struct i2c_device_id *id)
502{ 479{
503 struct snd_soc_device *socdev = ak4535_socdev; 480 struct ak4535_priv *ak4535;
504 struct snd_soc_codec *codec = socdev->card->codec;
505 int ret; 481 int ret;
506 482
507 i2c_set_clientdata(i2c, codec); 483 ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
508 codec->control_data = i2c; 484 if (ak4535 == NULL)
485 return -ENOMEM;
509 486
510 ret = ak4535_init(socdev); 487 i2c_set_clientdata(i2c, ak4535);
511 if (ret < 0) 488 ak4535->control_data = i2c;
512 printk(KERN_ERR "failed to initialise AK4535\n"); 489 ak4535->control_type = SND_SOC_I2C;
513 490
491 ret = snd_soc_register_codec(&i2c->dev,
492 &soc_codec_dev_ak4535, &ak4535_dai, 1);
493 if (ret < 0)
494 kfree(ak4535);
514 return ret; 495 return ret;
515} 496}
516 497
517static int ak4535_i2c_remove(struct i2c_client *client) 498static __devexit int ak4535_i2c_remove(struct i2c_client *client)
518{ 499{
519 struct snd_soc_codec *codec = i2c_get_clientdata(client); 500 snd_soc_unregister_codec(&client->dev);
520 kfree(codec->reg_cache); 501 kfree(i2c_get_clientdata(client));
521 return 0; 502 return 0;
522} 503}
523 504
@@ -529,138 +510,34 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
529 510
530static struct i2c_driver ak4535_i2c_driver = { 511static struct i2c_driver ak4535_i2c_driver = {
531 .driver = { 512 .driver = {
532 .name = "AK4535 I2C Codec", 513 .name = "ak4535-codec",
533 .owner = THIS_MODULE, 514 .owner = THIS_MODULE,
534 }, 515 },
535 .probe = ak4535_i2c_probe, 516 .probe = ak4535_i2c_probe,
536 .remove = ak4535_i2c_remove, 517 .remove = __devexit_p(ak4535_i2c_remove),
537 .id_table = ak4535_i2c_id, 518 .id_table = ak4535_i2c_id,
538}; 519};
539
540static int ak4535_add_i2c_device(struct platform_device *pdev,
541 const struct ak4535_setup_data *setup)
542{
543 struct i2c_board_info info;
544 struct i2c_adapter *adapter;
545 struct i2c_client *client;
546 int ret;
547
548 ret = i2c_add_driver(&ak4535_i2c_driver);
549 if (ret != 0) {
550 dev_err(&pdev->dev, "can't add i2c driver\n");
551 return ret;
552 }
553
554 memset(&info, 0, sizeof(struct i2c_board_info));
555 info.addr = setup->i2c_address;
556 strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
557
558 adapter = i2c_get_adapter(setup->i2c_bus);
559 if (!adapter) {
560 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
561 setup->i2c_bus);
562 goto err_driver;
563 }
564
565 client = i2c_new_device(adapter, &info);
566 i2c_put_adapter(adapter);
567 if (!client) {
568 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
569 (unsigned int)info.addr);
570 goto err_driver;
571 }
572
573 return 0;
574
575err_driver:
576 i2c_del_driver(&ak4535_i2c_driver);
577 return -ENODEV;
578}
579#endif 520#endif
580 521
581static int ak4535_probe(struct platform_device *pdev) 522static int __init ak4535_modinit(void)
582{ 523{
583 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 524 int ret = 0;
584 struct ak4535_setup_data *setup;
585 struct snd_soc_codec *codec;
586 struct ak4535_priv *ak4535;
587 int ret;
588
589 printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
590
591 setup = socdev->codec_data;
592 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
593 if (codec == NULL)
594 return -ENOMEM;
595
596 ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
597 if (ak4535 == NULL) {
598 kfree(codec);
599 return -ENOMEM;
600 }
601
602 snd_soc_codec_set_drvdata(codec, ak4535);
603 socdev->card->codec = codec;
604 mutex_init(&codec->mutex);
605 INIT_LIST_HEAD(&codec->dapm_widgets);
606 INIT_LIST_HEAD(&codec->dapm_paths);
607
608 ak4535_socdev = socdev;
609 ret = -ENODEV;
610
611#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 525#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
612 if (setup->i2c_address) { 526 ret = i2c_add_driver(&ak4535_i2c_driver);
613 codec->hw_write = (hw_write_t)i2c_master_send;
614 ret = ak4535_add_i2c_device(pdev, setup);
615 }
616#endif
617
618 if (ret != 0) { 527 if (ret != 0) {
619 kfree(snd_soc_codec_get_drvdata(codec)); 528 printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
620 kfree(codec); 529 ret);
621 } 530 }
531#endif
622 return ret; 532 return ret;
623} 533}
534module_init(ak4535_modinit);
624 535
625/* power down chip */ 536static void __exit ak4535_exit(void)
626static int ak4535_remove(struct platform_device *pdev)
627{ 537{
628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
629 struct snd_soc_codec *codec = socdev->card->codec;
630
631 if (codec->control_data)
632 ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
633
634 snd_soc_free_pcms(socdev);
635 snd_soc_dapm_free(socdev);
636#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 538#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
637 if (codec->control_data)
638 i2c_unregister_device(codec->control_data);
639 i2c_del_driver(&ak4535_i2c_driver); 539 i2c_del_driver(&ak4535_i2c_driver);
640#endif 540#endif
641 kfree(snd_soc_codec_get_drvdata(codec));
642 kfree(codec);
643
644 return 0;
645}
646
647struct snd_soc_codec_device soc_codec_dev_ak4535 = {
648 .probe = ak4535_probe,
649 .remove = ak4535_remove,
650 .suspend = ak4535_suspend,
651 .resume = ak4535_resume,
652};
653EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
654
655static int __init ak4535_modinit(void)
656{
657 return snd_soc_register_dai(&ak4535_dai);
658}
659module_init(ak4535_modinit);
660
661static void __exit ak4535_exit(void)
662{
663 snd_soc_unregister_dai(&ak4535_dai);
664} 541}
665module_exit(ak4535_exit); 542module_exit(ak4535_exit);
666 543
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index c7a58703ea39..0431e5f634a2 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -36,12 +36,4 @@
36 36
37#define AK4535_CACHEREGNUM 0x10 37#define AK4535_CACHEREGNUM 0x10
38 38
39struct ak4535_setup_data {
40 int i2c_bus;
41 unsigned short i2c_address;
42};
43
44extern struct snd_soc_dai ak4535_dai;
45extern struct snd_soc_codec_device soc_codec_dev_ak4535;
46
47#endif 39#endif
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
new file mode 100644
index 000000000000..ed96f247c2da
--- /dev/null
+++ b/sound/soc/codecs/ak4641.c
@@ -0,0 +1,664 @@
1/*
2 * ak4641.c -- AK4641 ALSA Soc Audio driver
3 *
4 * Copyright (C) 2008 Harald Welte <laforge@gnufiish.org>
5 * Copyright (C) 2011 Dmitry Artamonow <mad_soft@inbox.ru>
6 *
7 * Based on ak4535.c by Richard Purdie
8 *
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
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28#include <sound/ak4641.h>
29
30#include "ak4641.h"
31
32/* codec private data */
33struct ak4641_priv {
34 struct snd_soc_codec *codec;
35 unsigned int sysclk;
36 int deemph;
37 int playback_fs;
38};
39
40/*
41 * ak4641 register cache
42 */
43static const u8 ak4641_reg[AK4641_CACHEREGNUM] = {
44 0x00, 0x80, 0x00, 0x80,
45 0x02, 0x00, 0x11, 0x05,
46 0x00, 0x00, 0x36, 0x10,
47 0x00, 0x00, 0x57, 0x00,
48 0x88, 0x88, 0x08, 0x08
49};
50
51static const int deemph_settings[] = {44100, 0, 48000, 32000};
52
53static int ak4641_set_deemph(struct snd_soc_codec *codec)
54{
55 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
56 int i, best = 0;
57
58 for (i = 0 ; i < ARRAY_SIZE(deemph_settings); i++) {
59 /* if deemphasis is on, select the nearest available rate */
60 if (ak4641->deemph && deemph_settings[i] != 0 &&
61 abs(deemph_settings[i] - ak4641->playback_fs) <
62 abs(deemph_settings[best] - ak4641->playback_fs))
63 best = i;
64
65 if (!ak4641->deemph && deemph_settings[i] == 0)
66 best = i;
67 }
68
69 dev_dbg(codec->dev, "Set deemphasis %d\n", best);
70
71 return snd_soc_update_bits(codec, AK4641_DAC, 0x3, best);
72}
73
74static int ak4641_put_deemph(struct snd_kcontrol *kcontrol,
75 struct snd_ctl_elem_value *ucontrol)
76{
77 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
78 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
79 int deemph = ucontrol->value.enumerated.item[0];
80
81 if (deemph > 1)
82 return -EINVAL;
83
84 ak4641->deemph = deemph;
85
86 return ak4641_set_deemph(codec);
87}
88
89static int ak4641_get_deemph(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
94
95 ucontrol->value.enumerated.item[0] = ak4641->deemph;
96 return 0;
97};
98
99static const char *ak4641_mono_out[] = {"(L + R)/2", "Hi-Z"};
100static const char *ak4641_hp_out[] = {"Stereo", "Mono"};
101static const char *ak4641_mic_select[] = {"Internal", "External"};
102static const char *ak4641_mic_or_dac[] = {"Microphone", "Voice DAC"};
103
104
105static const DECLARE_TLV_DB_SCALE(mono_gain_tlv, -1700, 2300, 0);
106static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 2000, 0);
107static const DECLARE_TLV_DB_SCALE(eq_tlv, -1050, 150, 0);
108static const DECLARE_TLV_DB_SCALE(master_tlv, -12750, 50, 0);
109static const DECLARE_TLV_DB_SCALE(mic_stereo_sidetone_tlv, -2700, 300, 0);
110static const DECLARE_TLV_DB_SCALE(mic_mono_sidetone_tlv, -400, 400, 0);
111static const DECLARE_TLV_DB_SCALE(capture_tlv, -800, 50, 0);
112static const DECLARE_TLV_DB_SCALE(alc_tlv, -800, 50, 0);
113static const DECLARE_TLV_DB_SCALE(aux_in_tlv, -2100, 300, 0);
114
115
116static const struct soc_enum ak4641_mono_out_enum =
117 SOC_ENUM_SINGLE(AK4641_SIG1, 6, 2, ak4641_mono_out);
118static const struct soc_enum ak4641_hp_out_enum =
119 SOC_ENUM_SINGLE(AK4641_MODE2, 2, 2, ak4641_hp_out);
120static const struct soc_enum ak4641_mic_select_enum =
121 SOC_ENUM_SINGLE(AK4641_MIC, 1, 2, ak4641_mic_select);
122static const struct soc_enum ak4641_mic_or_dac_enum =
123 SOC_ENUM_SINGLE(AK4641_BTIF, 4, 2, ak4641_mic_or_dac);
124
125static const struct snd_kcontrol_new ak4641_snd_controls[] = {
126 SOC_ENUM("Mono 1 Output", ak4641_mono_out_enum),
127 SOC_SINGLE_TLV("Mono 1 Gain Volume", AK4641_SIG1, 7, 1, 1,
128 mono_gain_tlv),
129 SOC_ENUM("Headphone Output", ak4641_hp_out_enum),
130 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
131 ak4641_get_deemph, ak4641_put_deemph),
132
133 SOC_SINGLE_TLV("Mic Boost Volume", AK4641_MIC, 0, 1, 0, mic_boost_tlv),
134
135 SOC_SINGLE("ALC Operation Time", AK4641_TIMER, 0, 3, 0),
136 SOC_SINGLE("ALC Recovery Time", AK4641_TIMER, 2, 3, 0),
137 SOC_SINGLE("ALC ZC Time", AK4641_TIMER, 4, 3, 0),
138
139 SOC_SINGLE("ALC 1 Switch", AK4641_ALC1, 5, 1, 0),
140
141 SOC_SINGLE_TLV("ALC Volume", AK4641_ALC2, 0, 71, 0, alc_tlv),
142 SOC_SINGLE("Left Out Enable Switch", AK4641_SIG2, 1, 1, 0),
143 SOC_SINGLE("Right Out Enable Switch", AK4641_SIG2, 0, 1, 0),
144
145 SOC_SINGLE_TLV("Capture Volume", AK4641_PGA, 0, 71, 0, capture_tlv),
146
147 SOC_DOUBLE_R_TLV("Master Playback Volume", AK4641_LATT,
148 AK4641_RATT, 0, 255, 1, master_tlv),
149
150 SOC_SINGLE_TLV("AUX In Volume", AK4641_VOL, 0, 15, 0, aux_in_tlv),
151
152 SOC_SINGLE("Equalizer Switch", AK4641_DAC, 2, 1, 0),
153 SOC_SINGLE_TLV("EQ1 100 Hz Volume", AK4641_EQLO, 0, 15, 1, eq_tlv),
154 SOC_SINGLE_TLV("EQ2 250 Hz Volume", AK4641_EQLO, 4, 15, 1, eq_tlv),
155 SOC_SINGLE_TLV("EQ3 1 kHz Volume", AK4641_EQMID, 0, 15, 1, eq_tlv),
156 SOC_SINGLE_TLV("EQ4 3.5 kHz Volume", AK4641_EQMID, 4, 15, 1, eq_tlv),
157 SOC_SINGLE_TLV("EQ5 10 kHz Volume", AK4641_EQHI, 0, 15, 1, eq_tlv),
158};
159
160/* Mono 1 Mixer */
161static const struct snd_kcontrol_new ak4641_mono1_mixer_controls[] = {
162 SOC_DAPM_SINGLE_TLV("Mic Mono Sidetone Volume", AK4641_VOL, 7, 1, 0,
163 mic_mono_sidetone_tlv),
164 SOC_DAPM_SINGLE("Mic Mono Sidetone Switch", AK4641_SIG1, 4, 1, 0),
165 SOC_DAPM_SINGLE("Mono Playback Switch", AK4641_SIG1, 5, 1, 0),
166};
167
168/* Stereo Mixer */
169static const struct snd_kcontrol_new ak4641_stereo_mixer_controls[] = {
170 SOC_DAPM_SINGLE_TLV("Mic Sidetone Volume", AK4641_VOL, 4, 7, 0,
171 mic_stereo_sidetone_tlv),
172 SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4641_SIG2, 4, 1, 0),
173 SOC_DAPM_SINGLE("Playback Switch", AK4641_SIG2, 7, 1, 0),
174 SOC_DAPM_SINGLE("Aux Bypass Switch", AK4641_SIG2, 5, 1, 0),
175};
176
177/* Input Mixer */
178static const struct snd_kcontrol_new ak4641_input_mixer_controls[] = {
179 SOC_DAPM_SINGLE("Mic Capture Switch", AK4641_MIC, 2, 1, 0),
180 SOC_DAPM_SINGLE("Aux Capture Switch", AK4641_MIC, 5, 1, 0),
181};
182
183/* Mic mux */
184static const struct snd_kcontrol_new ak4641_mic_mux_control =
185 SOC_DAPM_ENUM("Mic Select", ak4641_mic_select_enum);
186
187/* Input mux */
188static const struct snd_kcontrol_new ak4641_input_mux_control =
189 SOC_DAPM_ENUM("Input Select", ak4641_mic_or_dac_enum);
190
191/* mono 2 switch */
192static const struct snd_kcontrol_new ak4641_mono2_control =
193 SOC_DAPM_SINGLE("Switch", AK4641_SIG1, 0, 1, 0);
194
195/* ak4641 dapm widgets */
196static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = {
197 SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
198 &ak4641_stereo_mixer_controls[0],
199 ARRAY_SIZE(ak4641_stereo_mixer_controls)),
200 SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
201 &ak4641_mono1_mixer_controls[0],
202 ARRAY_SIZE(ak4641_mono1_mixer_controls)),
203 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
204 &ak4641_input_mixer_controls[0],
205 ARRAY_SIZE(ak4641_input_mixer_controls)),
206 SND_SOC_DAPM_MUX("Mic Mux", SND_SOC_NOPM, 0, 0,
207 &ak4641_mic_mux_control),
208 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
209 &ak4641_input_mux_control),
210 SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
211 &ak4641_mono2_control),
212
213 SND_SOC_DAPM_OUTPUT("LOUT"),
214 SND_SOC_DAPM_OUTPUT("ROUT"),
215 SND_SOC_DAPM_OUTPUT("MOUT1"),
216 SND_SOC_DAPM_OUTPUT("MOUT2"),
217 SND_SOC_DAPM_OUTPUT("MICOUT"),
218
219 SND_SOC_DAPM_ADC("ADC", "HiFi Capture", AK4641_PM1, 0, 0),
220 SND_SOC_DAPM_PGA("Mic", AK4641_PM1, 1, 0, NULL, 0),
221 SND_SOC_DAPM_PGA("AUX In", AK4641_PM1, 2, 0, NULL, 0),
222 SND_SOC_DAPM_PGA("Mono Out", AK4641_PM1, 3, 0, NULL, 0),
223 SND_SOC_DAPM_PGA("Line Out", AK4641_PM1, 4, 0, NULL, 0),
224
225 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", AK4641_PM2, 0, 0),
226 SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0),
227
228 SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0),
229 SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0),
230
231 SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0),
232 SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0),
233
234 SND_SOC_DAPM_INPUT("MICIN"),
235 SND_SOC_DAPM_INPUT("MICEXT"),
236 SND_SOC_DAPM_INPUT("AUX"),
237 SND_SOC_DAPM_INPUT("AIN"),
238};
239
240static const struct snd_soc_dapm_route ak4641_audio_map[] = {
241 /* Stereo Mixer */
242 {"Stereo Mixer", "Playback Switch", "DAC"},
243 {"Stereo Mixer", "Mic Sidetone Switch", "Input Mux"},
244 {"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
245
246 /* Mono 1 Mixer */
247 {"Mono1 Mixer", "Mic Mono Sidetone Switch", "Input Mux"},
248 {"Mono1 Mixer", "Mono Playback Switch", "DAC"},
249
250 /* Mic */
251 {"Mic", NULL, "AIN"},
252 {"Mic Mux", "Internal", "Mic Int Bias"},
253 {"Mic Mux", "External", "Mic Ext Bias"},
254 {"Mic Int Bias", NULL, "MICIN"},
255 {"Mic Ext Bias", NULL, "MICEXT"},
256 {"MICOUT", NULL, "Mic Mux"},
257
258 /* Input Mux */
259 {"Input Mux", "Microphone", "Mic"},
260 {"Input Mux", "Voice DAC", "Voice DAC"},
261
262 /* Line Out */
263 {"LOUT", NULL, "Line Out"},
264 {"ROUT", NULL, "Line Out"},
265 {"Line Out", NULL, "Stereo Mixer"},
266
267 /* Mono 1 Out */
268 {"MOUT1", NULL, "Mono Out"},
269 {"Mono Out", NULL, "Mono1 Mixer"},
270
271 /* Mono 2 Out */
272 {"MOUT2", NULL, "Mono 2 Enable"},
273 {"Mono 2 Enable", "Switch", "Mono Out 2"},
274 {"Mono Out 2", NULL, "Stereo Mixer"},
275
276 {"Voice ADC", NULL, "Mono 2 Enable"},
277
278 /* Aux In */
279 {"AUX In", NULL, "AUX"},
280
281 /* ADC */
282 {"ADC", NULL, "Input Mixer"},
283 {"Input Mixer", "Mic Capture Switch", "Mic"},
284 {"Input Mixer", "Aux Capture Switch", "AUX In"},
285};
286
287static int ak4641_set_dai_sysclk(struct snd_soc_dai *codec_dai,
288 int clk_id, unsigned int freq, int dir)
289{
290 struct snd_soc_codec *codec = codec_dai->codec;
291 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
292
293 ak4641->sysclk = freq;
294 return 0;
295}
296
297static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
298 struct snd_pcm_hw_params *params,
299 struct snd_soc_dai *dai)
300{
301 struct snd_soc_pcm_runtime *rtd = substream->private_data;
302 struct snd_soc_codec *codec = rtd->codec;
303 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
304 int rate = params_rate(params), fs = 256;
305 u8 mode2;
306
307 if (rate)
308 fs = ak4641->sysclk / rate;
309 else
310 return -EINVAL;
311
312 /* set fs */
313 switch (fs) {
314 case 1024:
315 mode2 = (0x2 << 5);
316 break;
317 case 512:
318 mode2 = (0x1 << 5);
319 break;
320 case 256:
321 mode2 = (0x0 << 5);
322 break;
323 default:
324 dev_err(codec->dev, "Error: unsupported fs=%d\n", fs);
325 return -EINVAL;
326 }
327
328 snd_soc_update_bits(codec, AK4641_MODE2, (0x3 << 5), mode2);
329
330 /* Update de-emphasis filter for the new rate */
331 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
332 ak4641->playback_fs = rate;
333 ak4641_set_deemph(codec);
334 };
335
336 return 0;
337}
338
339static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
340 unsigned int fmt)
341{
342 struct snd_soc_codec *codec = codec_dai->codec;
343 u8 btif;
344
345 /* interface format */
346 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
347 case SND_SOC_DAIFMT_I2S:
348 btif = (0x3 << 5);
349 break;
350 case SND_SOC_DAIFMT_LEFT_J:
351 btif = (0x2 << 5);
352 break;
353 case SND_SOC_DAIFMT_DSP_A: /* MSB after FRM */
354 btif = (0x0 << 5);
355 break;
356 case SND_SOC_DAIFMT_DSP_B: /* MSB during FRM */
357 btif = (0x1 << 5);
358 break;
359 default:
360 return -EINVAL;
361 }
362
363 return snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif);
364}
365
366static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
367 unsigned int fmt)
368{
369 struct snd_soc_codec *codec = codec_dai->codec;
370 u8 mode1 = 0;
371
372 /* interface format */
373 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
374 case SND_SOC_DAIFMT_I2S:
375 mode1 = 0x02;
376 break;
377 case SND_SOC_DAIFMT_LEFT_J:
378 mode1 = 0x01;
379 break;
380 default:
381 return -EINVAL;
382 }
383
384 return snd_soc_write(codec, AK4641_MODE1, mode1);
385}
386
387static int ak4641_mute(struct snd_soc_dai *dai, int mute)
388{
389 struct snd_soc_codec *codec = dai->codec;
390
391 return snd_soc_update_bits(codec, AK4641_DAC, 0x20, mute ? 0x20 : 0);
392}
393
394static int ak4641_set_bias_level(struct snd_soc_codec *codec,
395 enum snd_soc_bias_level level)
396{
397 struct ak4641_platform_data *pdata = codec->dev->platform_data;
398 int ret;
399
400 switch (level) {
401 case SND_SOC_BIAS_ON:
402 /* unmute */
403 snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0);
404 break;
405 case SND_SOC_BIAS_PREPARE:
406 /* mute */
407 snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
408 break;
409 case SND_SOC_BIAS_STANDBY:
410 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
411 if (pdata && gpio_is_valid(pdata->gpio_power))
412 gpio_set_value(pdata->gpio_power, 1);
413 mdelay(1);
414 if (pdata && gpio_is_valid(pdata->gpio_npdn))
415 gpio_set_value(pdata->gpio_npdn, 1);
416 mdelay(1);
417
418 ret = snd_soc_cache_sync(codec);
419 if (ret) {
420 dev_err(codec->dev,
421 "Failed to sync cache: %d\n", ret);
422 return ret;
423 }
424 }
425 snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0x80);
426 snd_soc_update_bits(codec, AK4641_PM2, 0x80, 0);
427 break;
428 case SND_SOC_BIAS_OFF:
429 snd_soc_update_bits(codec, AK4641_PM1, 0x80, 0);
430 if (pdata && gpio_is_valid(pdata->gpio_npdn))
431 gpio_set_value(pdata->gpio_npdn, 0);
432 if (pdata && gpio_is_valid(pdata->gpio_power))
433 gpio_set_value(pdata->gpio_power, 0);
434 codec->cache_sync = 1;
435 break;
436 }
437 codec->dapm.bias_level = level;
438 return 0;
439}
440
441#define AK4641_RATES (SNDRV_PCM_RATE_8000_48000)
442#define AK4641_RATES_BT (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
443 SNDRV_PCM_RATE_16000)
444#define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
445
446static struct snd_soc_dai_ops ak4641_i2s_dai_ops = {
447 .hw_params = ak4641_i2s_hw_params,
448 .set_fmt = ak4641_i2s_set_dai_fmt,
449 .digital_mute = ak4641_mute,
450 .set_sysclk = ak4641_set_dai_sysclk,
451};
452
453static struct snd_soc_dai_ops ak4641_pcm_dai_ops = {
454 .hw_params = NULL, /* rates are controlled by BT chip */
455 .set_fmt = ak4641_pcm_set_dai_fmt,
456 .digital_mute = ak4641_mute,
457 .set_sysclk = ak4641_set_dai_sysclk,
458};
459
460struct snd_soc_dai_driver ak4641_dai[] = {
461{
462 .name = "ak4641-hifi",
463 .id = 1,
464 .playback = {
465 .stream_name = "HiFi Playback",
466 .channels_min = 1,
467 .channels_max = 2,
468 .rates = AK4641_RATES,
469 .formats = AK4641_FORMATS,
470 },
471 .capture = {
472 .stream_name = "HiFi Capture",
473 .channels_min = 1,
474 .channels_max = 2,
475 .rates = AK4641_RATES,
476 .formats = AK4641_FORMATS,
477 },
478 .ops = &ak4641_i2s_dai_ops,
479 .symmetric_rates = 1,
480},
481{
482 .name = "ak4641-voice",
483 .id = 1,
484 .playback = {
485 .stream_name = "Voice Playback",
486 .channels_min = 1,
487 .channels_max = 1,
488 .rates = AK4641_RATES_BT,
489 .formats = AK4641_FORMATS,
490 },
491 .capture = {
492 .stream_name = "Voice Capture",
493 .channels_min = 1,
494 .channels_max = 1,
495 .rates = AK4641_RATES_BT,
496 .formats = AK4641_FORMATS,
497 },
498 .ops = &ak4641_pcm_dai_ops,
499 .symmetric_rates = 1,
500},
501};
502
503static int ak4641_suspend(struct snd_soc_codec *codec, pm_message_t state)
504{
505 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
506 return 0;
507}
508
509static int ak4641_resume(struct snd_soc_codec *codec)
510{
511 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
512 return 0;
513}
514
515static int ak4641_probe(struct snd_soc_codec *codec)
516{
517 struct ak4641_platform_data *pdata = codec->dev->platform_data;
518 int ret;
519
520
521 if (pdata) {
522 if (gpio_is_valid(pdata->gpio_power)) {
523 ret = gpio_request_one(pdata->gpio_power,
524 GPIOF_OUT_INIT_LOW, "ak4641 power");
525 if (ret)
526 goto err_out;
527 }
528 if (gpio_is_valid(pdata->gpio_npdn)) {
529 ret = gpio_request_one(pdata->gpio_npdn,
530 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
531 if (ret)
532 goto err_gpio;
533
534 udelay(1); /* > 150 ns */
535 gpio_set_value(pdata->gpio_npdn, 1);
536 }
537 }
538
539 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
540 if (ret != 0) {
541 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
542 goto err_register;
543 }
544
545 /* power on device */
546 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
547
548 return 0;
549
550err_register:
551 if (pdata) {
552 if (gpio_is_valid(pdata->gpio_power))
553 gpio_set_value(pdata->gpio_power, 0);
554 if (gpio_is_valid(pdata->gpio_npdn))
555 gpio_free(pdata->gpio_npdn);
556 }
557err_gpio:
558 if (pdata && gpio_is_valid(pdata->gpio_power))
559 gpio_free(pdata->gpio_power);
560err_out:
561 return ret;
562}
563
564static int ak4641_remove(struct snd_soc_codec *codec)
565{
566 struct ak4641_platform_data *pdata = codec->dev->platform_data;
567
568 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
569
570 if (pdata) {
571 if (gpio_is_valid(pdata->gpio_power)) {
572 gpio_set_value(pdata->gpio_power, 0);
573 gpio_free(pdata->gpio_power);
574 }
575 if (gpio_is_valid(pdata->gpio_npdn))
576 gpio_free(pdata->gpio_npdn);
577 }
578 return 0;
579}
580
581
582static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
583 .probe = ak4641_probe,
584 .remove = ak4641_remove,
585 .suspend = ak4641_suspend,
586 .resume = ak4641_resume,
587 .controls = ak4641_snd_controls,
588 .num_controls = ARRAY_SIZE(ak4641_snd_controls),
589 .dapm_widgets = ak4641_dapm_widgets,
590 .num_dapm_widgets = ARRAY_SIZE(ak4641_dapm_widgets),
591 .dapm_routes = ak4641_audio_map,
592 .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map),
593 .set_bias_level = ak4641_set_bias_level,
594 .reg_cache_size = ARRAY_SIZE(ak4641_reg),
595 .reg_word_size = sizeof(u8),
596 .reg_cache_default = ak4641_reg,
597 .reg_cache_step = 1,
598};
599
600
601static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
602 const struct i2c_device_id *id)
603{
604 struct ak4641_priv *ak4641;
605 int ret;
606
607 ak4641 = kzalloc(sizeof(struct ak4641_priv), GFP_KERNEL);
608 if (!ak4641)
609 return -ENOMEM;
610
611 i2c_set_clientdata(i2c, ak4641);
612
613 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
614 ak4641_dai, ARRAY_SIZE(ak4641_dai));
615 if (ret < 0)
616 kfree(ak4641);
617
618 return ret;
619}
620
621static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
622{
623 snd_soc_unregister_codec(&i2c->dev);
624 kfree(i2c_get_clientdata(i2c));
625 return 0;
626}
627
628static const struct i2c_device_id ak4641_i2c_id[] = {
629 { "ak4641", 0 },
630 { }
631};
632MODULE_DEVICE_TABLE(i2c, ak4641_i2c_id);
633
634static struct i2c_driver ak4641_i2c_driver = {
635 .driver = {
636 .name = "ak4641",
637 .owner = THIS_MODULE,
638 },
639 .probe = ak4641_i2c_probe,
640 .remove = __devexit_p(ak4641_i2c_remove),
641 .id_table = ak4641_i2c_id,
642};
643
644static int __init ak4641_modinit(void)
645{
646 int ret;
647
648 ret = i2c_add_driver(&ak4641_i2c_driver);
649 if (ret != 0)
650 pr_err("Failed to register AK4641 I2C driver: %d\n", ret);
651
652 return ret;
653}
654module_init(ak4641_modinit);
655
656static void __exit ak4641_exit(void)
657{
658 i2c_del_driver(&ak4641_i2c_driver);
659}
660module_exit(ak4641_exit);
661
662MODULE_DESCRIPTION("SoC AK4641 driver");
663MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>");
664MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4641.h b/sound/soc/codecs/ak4641.h
new file mode 100644
index 000000000000..4a263248efea
--- /dev/null
+++ b/sound/soc/codecs/ak4641.h
@@ -0,0 +1,47 @@
1/*
2 * ak4641.h -- AK4641 SoC Audio driver
3 *
4 * Copyright 2008 Harald Welte <laforge@gnufiish.org>
5 *
6 * Based on ak4535.h
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _AK4641_H
14#define _AK4641_H
15
16/* AK4641 register space */
17
18#define AK4641_PM1 0x00
19#define AK4641_PM2 0x01
20#define AK4641_SIG1 0x02
21#define AK4641_SIG2 0x03
22#define AK4641_MODE1 0x04
23#define AK4641_MODE2 0x05
24#define AK4641_DAC 0x06
25#define AK4641_MIC 0x07
26#define AK4641_TIMER 0x08
27#define AK4641_ALC1 0x09
28#define AK4641_ALC2 0x0a
29#define AK4641_PGA 0x0b
30#define AK4641_LATT 0x0c
31#define AK4641_RATT 0x0d
32#define AK4641_VOL 0x0e
33#define AK4641_STATUS 0x0f
34#define AK4641_EQLO 0x10
35#define AK4641_EQMID 0x11
36#define AK4641_EQHI 0x12
37#define AK4641_BTIF 0x13
38
39#define AK4641_CACHEREGNUM 0x14
40
41
42
43#define AK4641_DAI_HIFI 0
44#define AK4641_DAI_VOICE 1
45
46
47#endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 3d7dc55305ec..65f46047b1cb 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -26,12 +26,10 @@
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <sound/soc-dapm.h> 29#include <sound/soc.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/tlv.h> 31#include <sound/tlv.h>
32 32
33#include "ak4642.h"
34
35#define AK4642_VERSION "0.0.1" 33#define AK4642_VERSION "0.0.1"
36 34
37#define PW_MGMT1 0x00 35#define PW_MGMT1 0x00
@@ -74,6 +72,12 @@
74 72
75#define AK4642_CACHEREGNUM 0x25 73#define AK4642_CACHEREGNUM 0x25
76 74
75/* PW_MGMT1*/
76#define PMVCM (1 << 6) /* VCOM Power Management */
77#define PMMIN (1 << 5) /* MIN Input Power Management */
78#define PMDAC (1 << 2) /* DAC Power Management */
79#define PMADL (1 << 0) /* MIC Amp Lch and ADC Lch Power Management */
80
77/* PW_MGMT2 */ 81/* PW_MGMT2 */
78#define HPMTN (1 << 6) 82#define HPMTN (1 << 6)
79#define PMHPL (1 << 5) 83#define PMHPL (1 << 5)
@@ -85,6 +89,23 @@
85#define PMHP_MASK (PMHPL | PMHPR) 89#define PMHP_MASK (PMHPL | PMHPR)
86#define PMHP PMHP_MASK 90#define PMHP PMHP_MASK
87 91
92/* PW_MGMT3 */
93#define PMADR (1 << 0) /* MIC L / ADC R Power Management */
94
95/* SG_SL1 */
96#define MINS (1 << 6) /* Switch from MIN to Speaker */
97#define DACL (1 << 4) /* Switch from DAC to Stereo or Receiver */
98#define PMMP (1 << 2) /* MPWR pin Power Management */
99#define MGAIN0 (1 << 0) /* MIC amp gain*/
100
101/* TIMER */
102#define ZTM(param) ((param & 0x3) << 4) /* ALC Zoro Crossing TimeOut */
103#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2))
104
105/* ALC_CTL1 */
106#define ALC (1 << 5) /* ALC Enable */
107#define LMTH0 (1 << 0) /* ALC Limiter / Recovery Level */
108
88/* MD_CTL1 */ 109/* MD_CTL1 */
89#define PLL3 (1 << 7) 110#define PLL3 (1 << 7)
90#define PLL2 (1 << 6) 111#define PLL2 (1 << 6)
@@ -95,6 +116,12 @@
95#define BCKO_MASK (1 << 3) 116#define BCKO_MASK (1 << 3)
96#define BCKO_64 BCKO_MASK 117#define BCKO_64 BCKO_MASK
97 118
119#define DIF_MASK (3 << 0)
120#define DSP (0 << 0)
121#define RIGHT_J (1 << 0)
122#define LEFT_J (2 << 0)
123#define I2S (3 << 0)
124
98/* MD_CTL2 */ 125/* MD_CTL2 */
99#define FS0 (1 << 0) 126#define FS0 (1 << 0)
100#define FS1 (1 << 1) 127#define FS1 (1 << 1)
@@ -102,7 +129,11 @@
102#define FS3 (1 << 5) 129#define FS3 (1 << 5)
103#define FS_MASK (FS0 | FS1 | FS2 | FS3) 130#define FS_MASK (FS0 | FS1 | FS2 | FS3)
104 131
105struct snd_soc_codec_device soc_codec_dev_ak4642; 132/* MD_CTL3 */
133#define BST1 (1 << 3)
134
135/* MD_CTL4 */
136#define DACH (1 << 0)
106 137
107/* 138/*
108 * Playback Volume (table 39) 139 * Playback Volume (table 39)
@@ -123,11 +154,11 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
123 154
124/* codec private data */ 155/* codec private data */
125struct ak4642_priv { 156struct ak4642_priv {
126 struct snd_soc_codec codec; 157 unsigned int sysclk;
158 enum snd_soc_control_type control_type;
159 void *control_data;
127}; 160};
128 161
129static struct snd_soc_codec *ak4642_codec;
130
131/* 162/*
132 * ak4642 register cache 163 * ak4642 register cache
133 */ 164 */
@@ -219,11 +250,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
219 * This operation came from example code of 250 * This operation came from example code of
220 * "ASAHI KASEI AK4642" (japanese) manual p97. 251 * "ASAHI KASEI AK4642" (japanese) manual p97.
221 */ 252 */
222 ak4642_write(codec, 0x0f, 0x09); 253 snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
223 ak4642_write(codec, 0x0e, 0x19); 254 snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
224 ak4642_write(codec, 0x09, 0x91); 255 ak4642_write(codec, L_IVC, 0x91); /* volume */
225 ak4642_write(codec, 0x0c, 0x91); 256 ak4642_write(codec, R_IVC, 0x91); /* volume */
226 ak4642_write(codec, 0x00, 0x64); 257 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
258 PMVCM | PMMIN | PMDAC);
227 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); 259 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
228 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN); 260 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
229 } else { 261 } else {
@@ -240,13 +272,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
240 * This operation came from example code of 272 * This operation came from example code of
241 * "ASAHI KASEI AK4642" (japanese) manual p94. 273 * "ASAHI KASEI AK4642" (japanese) manual p94.
242 */ 274 */
243 ak4642_write(codec, 0x02, 0x05); 275 ak4642_write(codec, SG_SL1, PMMP | MGAIN0);
244 ak4642_write(codec, 0x06, 0x3c); 276 ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
245 ak4642_write(codec, 0x08, 0xe1); 277 ak4642_write(codec, ALC_CTL1, ALC | LMTH0);
246 ak4642_write(codec, 0x0b, 0x00); 278 snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
247 ak4642_write(codec, 0x07, 0x21); 279 PMVCM | PMADL);
248 ak4642_write(codec, 0x00, 0x41); 280 snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
249 ak4642_write(codec, 0x10, 0x01);
250 } 281 }
251 282
252 return 0; 283 return 0;
@@ -262,14 +293,14 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
262 /* stop headphone output */ 293 /* stop headphone output */
263 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0); 294 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
264 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0); 295 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
265 ak4642_write(codec, 0x00, 0x40); 296 snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0);
266 ak4642_write(codec, 0x0e, 0x11); 297 snd_soc_update_bits(codec, MD_CTL3, BST1, 0);
267 ak4642_write(codec, 0x0f, 0x08); 298 snd_soc_update_bits(codec, MD_CTL4, DACH, 0);
268 } else { 299 } else {
269 /* stop stereo input */ 300 /* stop stereo input */
270 ak4642_write(codec, 0x00, 0x40); 301 snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
271 ak4642_write(codec, 0x10, 0x00); 302 snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0);
272 ak4642_write(codec, 0x07, 0x01); 303 snd_soc_update_bits(codec, ALC_CTL1, ALC, 0);
273 } 304 }
274} 305}
275 306
@@ -326,9 +357,27 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
326 default: 357 default:
327 return -EINVAL; 358 return -EINVAL;
328 } 359 }
329 snd_soc_update_bits(codec, PW_MGMT2, MS, data); 360 snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
330 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); 361 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
331 362
363 /* format type */
364 data = 0;
365 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
366 case SND_SOC_DAIFMT_LEFT_J:
367 data = LEFT_J;
368 break;
369 case SND_SOC_DAIFMT_I2S:
370 data = I2S;
371 break;
372 /* FIXME
373 * Please add RIGHT_J / DSP support here
374 */
375 default:
376 return -EINVAL;
377 break;
378 }
379 snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
380
332 return 0; 381 return 0;
333} 382}
334 383
@@ -393,8 +442,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
393 .hw_params = ak4642_dai_hw_params, 442 .hw_params = ak4642_dai_hw_params,
394}; 443};
395 444
396struct snd_soc_dai ak4642_dai = { 445static struct snd_soc_dai_driver ak4642_dai = {
397 .name = "AK4642", 446 .name = "ak4642-hifi",
398 .playback = { 447 .playback = {
399 .stream_name = "Playback", 448 .stream_name = "Playback",
400 .channels_min = 1, 449 .channels_min = 1,
@@ -410,112 +459,65 @@ struct snd_soc_dai ak4642_dai = {
410 .ops = &ak4642_dai_ops, 459 .ops = &ak4642_dai_ops,
411 .symmetric_rates = 1, 460 .symmetric_rates = 1,
412}; 461};
413EXPORT_SYMBOL_GPL(ak4642_dai);
414 462
415static int ak4642_resume(struct platform_device *pdev) 463static int ak4642_resume(struct snd_soc_codec *codec)
416{ 464{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418 struct snd_soc_codec *codec = socdev->card->codec;
419
420 ak4642_sync(codec); 465 ak4642_sync(codec);
421 return 0; 466 return 0;
422} 467}
423 468
424/* 469
425 * initialise the AK4642 driver 470static int ak4642_probe(struct snd_soc_codec *codec)
426 * register the mixer and dsp interfaces with the kernel
427 */
428static int ak4642_init(struct ak4642_priv *ak4642)
429{ 471{
430 struct snd_soc_codec *codec = &ak4642->codec; 472 struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
431 int ret = 0;
432 473
433 if (ak4642_codec) { 474 dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
434 dev_err(codec->dev, "Another ak4642 is registered\n");
435 return -EINVAL;
436 }
437 475
438 mutex_init(&codec->mutex);
439 INIT_LIST_HEAD(&codec->dapm_widgets);
440 INIT_LIST_HEAD(&codec->dapm_paths);
441
442 snd_soc_codec_set_drvdata(codec, ak4642);
443 codec->name = "AK4642";
444 codec->owner = THIS_MODULE;
445 codec->read = ak4642_read_reg_cache;
446 codec->write = ak4642_write;
447 codec->dai = &ak4642_dai;
448 codec->num_dai = 1;
449 codec->hw_write = (hw_write_t)i2c_master_send; 476 codec->hw_write = (hw_write_t)i2c_master_send;
450 codec->reg_cache_size = ARRAY_SIZE(ak4642_reg); 477 codec->control_data = ak4642->control_data;
451 codec->reg_cache = kmemdup(ak4642_reg,
452 sizeof(ak4642_reg), GFP_KERNEL);
453
454 if (!codec->reg_cache)
455 return -ENOMEM;
456 478
457 ak4642_dai.dev = codec->dev; 479 snd_soc_add_controls(codec, ak4642_snd_controls,
458 ak4642_codec = codec; 480 ARRAY_SIZE(ak4642_snd_controls));
459
460 ret = snd_soc_register_codec(codec);
461 if (ret) {
462 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
463 goto reg_cache_err;
464 }
465
466 ret = snd_soc_register_dai(&ak4642_dai);
467 if (ret) {
468 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
469 snd_soc_unregister_codec(codec);
470 goto reg_cache_err;
471 }
472
473 return ret;
474
475reg_cache_err:
476 kfree(codec->reg_cache);
477 codec->reg_cache = NULL;
478 481
479 return ret; 482 return 0;
480} 483}
481 484
485static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
486 .probe = ak4642_probe,
487 .resume = ak4642_resume,
488 .read = ak4642_read_reg_cache,
489 .write = ak4642_write,
490 .reg_cache_size = ARRAY_SIZE(ak4642_reg),
491 .reg_word_size = sizeof(u8),
492 .reg_cache_default = ak4642_reg,
493};
494
482#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 495#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
483static int ak4642_i2c_probe(struct i2c_client *i2c, 496static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
484 const struct i2c_device_id *id) 497 const struct i2c_device_id *id)
485{ 498{
486 struct ak4642_priv *ak4642; 499 struct ak4642_priv *ak4642;
487 struct snd_soc_codec *codec;
488 int ret; 500 int ret;
489 501
490 ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL); 502 ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
491 if (!ak4642) 503 if (!ak4642)
492 return -ENOMEM; 504 return -ENOMEM;
493 505
494 codec = &ak4642->codec;
495 codec->dev = &i2c->dev;
496
497 i2c_set_clientdata(i2c, ak4642); 506 i2c_set_clientdata(i2c, ak4642);
498 codec->control_data = i2c; 507 ak4642->control_data = i2c;
508 ak4642->control_type = SND_SOC_I2C;
499 509
500 ret = ak4642_init(ak4642); 510 ret = snd_soc_register_codec(&i2c->dev,
501 if (ret < 0) { 511 &soc_codec_dev_ak4642, &ak4642_dai, 1);
502 printk(KERN_ERR "failed to initialise AK4642\n"); 512 if (ret < 0)
503 kfree(ak4642); 513 kfree(ak4642);
504 }
505
506 return ret; 514 return ret;
507} 515}
508 516
509static int ak4642_i2c_remove(struct i2c_client *client) 517static __devexit int ak4642_i2c_remove(struct i2c_client *client)
510{ 518{
511 struct ak4642_priv *ak4642 = i2c_get_clientdata(client); 519 snd_soc_unregister_codec(&client->dev);
512 520 kfree(i2c_get_clientdata(client));
513 snd_soc_unregister_dai(&ak4642_dai);
514 snd_soc_unregister_codec(&ak4642->codec);
515 kfree(ak4642->codec.reg_cache);
516 kfree(ak4642);
517 ak4642_codec = NULL;
518
519 return 0; 521 return 0;
520} 522}
521 523
@@ -528,64 +530,15 @@ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
528 530
529static struct i2c_driver ak4642_i2c_driver = { 531static struct i2c_driver ak4642_i2c_driver = {
530 .driver = { 532 .driver = {
531 .name = "AK4642 I2C Codec", 533 .name = "ak4642-codec",
532 .owner = THIS_MODULE, 534 .owner = THIS_MODULE,
533 }, 535 },
534 .probe = ak4642_i2c_probe, 536 .probe = ak4642_i2c_probe,
535 .remove = ak4642_i2c_remove, 537 .remove = __devexit_p(ak4642_i2c_remove),
536 .id_table = ak4642_i2c_id, 538 .id_table = ak4642_i2c_id,
537}; 539};
538
539#endif 540#endif
540 541
541static int ak4642_probe(struct platform_device *pdev)
542{
543 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
544 int ret;
545
546 if (!ak4642_codec) {
547 dev_err(&pdev->dev, "Codec device not registered\n");
548 return -ENODEV;
549 }
550
551 socdev->card->codec = ak4642_codec;
552
553 /* register pcms */
554 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
555 if (ret < 0) {
556 printk(KERN_ERR "ak4642: failed to create pcms\n");
557 goto pcm_err;
558 }
559
560 snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
561 ARRAY_SIZE(ak4642_snd_controls));
562
563 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
564 return ret;
565
566pcm_err:
567 return ret;
568
569}
570
571/* power down chip */
572static int ak4642_remove(struct platform_device *pdev)
573{
574 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
575
576 snd_soc_free_pcms(socdev);
577 snd_soc_dapm_free(socdev);
578
579 return 0;
580}
581
582struct snd_soc_codec_device soc_codec_dev_ak4642 = {
583 .probe = ak4642_probe,
584 .remove = ak4642_remove,
585 .resume = ak4642_resume,
586};
587EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
588
589static int __init ak4642_modinit(void) 542static int __init ak4642_modinit(void)
590{ 543{
591 int ret = 0; 544 int ret = 0;
diff --git a/sound/soc/codecs/ak4642.h b/sound/soc/codecs/ak4642.h
deleted file mode 100644
index e476833d314e..000000000000
--- a/sound/soc/codecs/ak4642.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * ak4642.h -- AK4642 Soc Audio driver
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ak4535.c
8 *
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
11 * published by the Free Software Foundation.
12 */
13
14#ifndef _AK4642_H
15#define _AK4642_H
16
17extern struct snd_soc_dai ak4642_dai;
18extern struct snd_soc_codec_device soc_codec_dev_ak4642;
19
20#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 87566932a3b1..88b29f8c748b 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -17,18 +17,16 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/initval.h> 20#include <sound/initval.h>
22#include <sound/tlv.h> 21#include <sound/tlv.h>
23 22
24#include "ak4671.h" 23#include "ak4671.h"
25 24
26static struct snd_soc_codec *ak4671_codec;
27 25
28/* codec private data */ 26/* codec private data */
29struct ak4671_priv { 27struct ak4671_priv {
30 struct snd_soc_codec codec; 28 enum snd_soc_control_type control_type;
31 u8 reg_cache[AK4671_CACHEREGNUM]; 29 void *control_data;
32}; 30};
33 31
34/* ak4671 register cache & default register settings */ 32/* ak4671 register cache & default register settings */
@@ -354,7 +352,7 @@ static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
354 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0), 352 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
355}; 353};
356 354
357static const struct snd_soc_dapm_route intercon[] = { 355static const struct snd_soc_dapm_route ak4671_intercon[] = {
358 {"DAC Left", "NULL", "PMPLL"}, 356 {"DAC Left", "NULL", "PMPLL"},
359 {"DAC Right", "NULL", "PMPLL"}, 357 {"DAC Right", "NULL", "PMPLL"},
360 {"ADC Left", "NULL", "PMPLL"}, 358 {"ADC Left", "NULL", "PMPLL"},
@@ -435,16 +433,6 @@ static const struct snd_soc_dapm_route intercon[] = {
435 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"}, 433 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
436}; 434};
437 435
438static int ak4671_add_widgets(struct snd_soc_codec *codec)
439{
440 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442
443 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
444
445 return 0;
446}
447
448static int ak4671_hw_params(struct snd_pcm_substream *substream, 436static int ak4671_hw_params(struct snd_pcm_substream *substream,
449 struct snd_pcm_hw_params *params, 437 struct snd_pcm_hw_params *params,
450 struct snd_soc_dai *dai) 438 struct snd_soc_dai *dai)
@@ -602,7 +590,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
602 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); 590 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
603 break; 591 break;
604 } 592 }
605 codec->bias_level = level; 593 codec->dapm.bias_level = level;
606 return 0; 594 return 0;
607} 595}
608 596
@@ -619,8 +607,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = {
619 .set_fmt = ak4671_set_dai_fmt, 607 .set_fmt = ak4671_set_dai_fmt,
620}; 608};
621 609
622struct snd_soc_dai ak4671_dai = { 610static struct snd_soc_dai_driver ak4671_dai = {
623 .name = "AK4671", 611 .name = "ak4671-hifi",
624 .playback = { 612 .playback = {
625 .stream_name = "Playback", 613 .stream_name = "Playback",
626 .channels_min = 1, 614 .channels_min = 1,
@@ -635,151 +623,72 @@ struct snd_soc_dai ak4671_dai = {
635 .formats = AK4671_FORMATS,}, 623 .formats = AK4671_FORMATS,},
636 .ops = &ak4671_dai_ops, 624 .ops = &ak4671_dai_ops,
637}; 625};
638EXPORT_SYMBOL_GPL(ak4671_dai);
639 626
640static int ak4671_probe(struct platform_device *pdev) 627static int ak4671_probe(struct snd_soc_codec *codec)
641{ 628{
642 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 629 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
643 struct snd_soc_codec *codec; 630 int ret;
644 int ret = 0;
645
646 if (ak4671_codec == NULL) {
647 dev_err(&pdev->dev, "Codec device not registered\n");
648 return -ENODEV;
649 }
650 631
651 socdev->card->codec = ak4671_codec; 632 codec->hw_write = (hw_write_t)i2c_master_send;
652 codec = ak4671_codec;
653 633
654 /* register pcms */ 634 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
655 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
656 if (ret < 0) { 635 if (ret < 0) {
657 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 636 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
658 goto pcm_err; 637 return ret;
659 } 638 }
660 639
661 snd_soc_add_controls(codec, ak4671_snd_controls, 640 snd_soc_add_controls(codec, ak4671_snd_controls,
662 ARRAY_SIZE(ak4671_snd_controls)); 641 ARRAY_SIZE(ak4671_snd_controls));
663 ak4671_add_widgets(codec);
664 642
665 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 643 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
666 644
667 return ret; 645 return ret;
668
669pcm_err:
670 return ret;
671} 646}
672 647
673static int ak4671_remove(struct platform_device *pdev) 648static int ak4671_remove(struct snd_soc_codec *codec)
674{ 649{
675 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 650 ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
676
677 snd_soc_free_pcms(socdev);
678 snd_soc_dapm_free(socdev);
679
680 return 0; 651 return 0;
681} 652}
682 653
683struct snd_soc_codec_device soc_codec_dev_ak4671 = { 654static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
684 .probe = ak4671_probe, 655 .probe = ak4671_probe,
685 .remove = ak4671_remove, 656 .remove = ak4671_remove,
657 .set_bias_level = ak4671_set_bias_level,
658 .reg_cache_size = AK4671_CACHEREGNUM,
659 .reg_word_size = sizeof(u8),
660 .reg_cache_default = ak4671_reg,
661 .dapm_widgets = ak4671_dapm_widgets,
662 .num_dapm_widgets = ARRAY_SIZE(ak4671_dapm_widgets),
663 .dapm_routes = ak4671_intercon,
664 .num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
686}; 665};
687EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
688
689static int ak4671_register(struct ak4671_priv *ak4671,
690 enum snd_soc_control_type control)
691{
692 int ret;
693 struct snd_soc_codec *codec = &ak4671->codec;
694
695 if (ak4671_codec) {
696 dev_err(codec->dev, "Another AK4671 is registered\n");
697 ret = -EINVAL;
698 goto err;
699 }
700
701 mutex_init(&codec->mutex);
702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths);
704
705 snd_soc_codec_set_drvdata(codec, ak4671);
706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF;
709 codec->set_bias_level = ak4671_set_bias_level;
710 codec->dai = &ak4671_dai;
711 codec->num_dai = 1;
712 codec->reg_cache_size = AK4671_CACHEREGNUM;
713 codec->reg_cache = &ak4671->reg_cache;
714
715 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
716
717 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
718 if (ret < 0) {
719 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
720 goto err;
721 }
722
723 ak4671_dai.dev = codec->dev;
724 ak4671_codec = codec;
725
726 ret = snd_soc_register_codec(codec);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
729 goto err;
730 }
731
732 ret = snd_soc_register_dai(&ak4671_dai);
733 if (ret != 0) {
734 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
735 goto err_codec;
736 }
737
738 return 0;
739
740err_codec:
741 snd_soc_unregister_codec(codec);
742err:
743 kfree(ak4671);
744 return ret;
745}
746
747static void ak4671_unregister(struct ak4671_priv *ak4671)
748{
749 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
750 snd_soc_unregister_dai(&ak4671_dai);
751 snd_soc_unregister_codec(&ak4671->codec);
752 kfree(ak4671);
753 ak4671_codec = NULL;
754}
755 666
756static int __devinit ak4671_i2c_probe(struct i2c_client *client, 667static int __devinit ak4671_i2c_probe(struct i2c_client *client,
757 const struct i2c_device_id *id) 668 const struct i2c_device_id *id)
758{ 669{
759 struct ak4671_priv *ak4671; 670 struct ak4671_priv *ak4671;
760 struct snd_soc_codec *codec; 671 int ret;
761 672
762 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL); 673 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
763 if (ak4671 == NULL) 674 if (ak4671 == NULL)
764 return -ENOMEM; 675 return -ENOMEM;
765 676
766 codec = &ak4671->codec;
767 codec->hw_write = (hw_write_t)i2c_master_send;
768
769 i2c_set_clientdata(client, ak4671); 677 i2c_set_clientdata(client, ak4671);
770 codec->control_data = client; 678 ak4671->control_data = client;
771 679 ak4671->control_type = SND_SOC_I2C;
772 codec->dev = &client->dev;
773 680
774 return ak4671_register(ak4671, SND_SOC_I2C); 681 ret = snd_soc_register_codec(&client->dev,
682 &soc_codec_dev_ak4671, &ak4671_dai, 1);
683 if (ret < 0)
684 kfree(ak4671);
685 return ret;
775} 686}
776 687
777static __devexit int ak4671_i2c_remove(struct i2c_client *client) 688static __devexit int ak4671_i2c_remove(struct i2c_client *client)
778{ 689{
779 struct ak4671_priv *ak4671 = i2c_get_clientdata(client); 690 snd_soc_unregister_codec(&client->dev);
780 691 kfree(i2c_get_clientdata(client));
781 ak4671_unregister(ak4671);
782
783 return 0; 692 return 0;
784} 693}
785 694
@@ -791,7 +700,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
791 700
792static struct i2c_driver ak4671_i2c_driver = { 701static struct i2c_driver ak4671_i2c_driver = {
793 .driver = { 702 .driver = {
794 .name = "ak4671", 703 .name = "ak4671-codec",
795 .owner = THIS_MODULE, 704 .owner = THIS_MODULE,
796 }, 705 },
797 .probe = ak4671_i2c_probe, 706 .probe = ak4671_i2c_probe,
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
index e2fad964e88b..61cb7ab7552c 100644
--- a/sound/soc/codecs/ak4671.h
+++ b/sound/soc/codecs/ak4671.h
@@ -150,7 +150,4 @@
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */ 150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04 151#define AK4671_MUTEN 0x04
152 152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif 153#endif
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
new file mode 100644
index 000000000000..eecffb548947
--- /dev/null
+++ b/sound/soc/codecs/alc5623.c
@@ -0,0 +1,1117 @@
1/*
2 * alc5623.c -- alc562[123] ALSA Soc Audio driver
3 *
4 * Copyright 2008 Realtek Microelectronics
5 * Author: flove <flove@realtek.com> Ethan <eku@marvell.com>
6 *
7 * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
8 *
9 *
10 * Based on WM8753.c
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/tlv.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32#include <sound/alc5623.h>
33
34#include "alc5623.h"
35
36static int caps_charge = 2000;
37module_param(caps_charge, int, 0);
38MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
39
40/* codec private data */
41struct alc5623_priv {
42 enum snd_soc_control_type control_type;
43 void *control_data;
44 struct mutex mutex;
45 u8 id;
46 unsigned int sysclk;
47 u16 reg_cache[ALC5623_VENDOR_ID2+2];
48 unsigned int add_ctrl;
49 unsigned int jack_det_ctrl;
50};
51
52static void alc5623_fill_cache(struct snd_soc_codec *codec)
53{
54 int i, step = codec->driver->reg_cache_step;
55 u16 *cache = codec->reg_cache;
56
57 /* not really efficient ... */
58 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
59 cache[i] = codec->hw_read(codec, i);
60}
61
62static inline int alc5623_reset(struct snd_soc_codec *codec)
63{
64 return snd_soc_write(codec, ALC5623_RESET, 0);
65}
66
67static int amp_mixer_event(struct snd_soc_dapm_widget *w,
68 struct snd_kcontrol *kcontrol, int event)
69{
70 /* to power-on/off class-d amp generators/speaker */
71 /* need to write to 'index-46h' register : */
72 /* so write index num (here 0x46) to reg 0x6a */
73 /* and then 0xffff/0 to reg 0x6c */
74 snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46);
75
76 switch (event) {
77 case SND_SOC_DAPM_PRE_PMU:
78 snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
79 break;
80 case SND_SOC_DAPM_POST_PMD:
81 snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0);
82 break;
83 }
84
85 return 0;
86}
87
88/*
89 * ALC5623 Controls
90 */
91
92static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
93static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
94static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
95static const unsigned int boost_tlv[] = {
96 TLV_DB_RANGE_HEAD(3),
97 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
98 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
99 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
100};
101static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
102
103static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = {
104 SOC_DOUBLE_TLV("Speaker Playback Volume",
105 ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
106 SOC_DOUBLE("Speaker Playback Switch",
107 ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
108 SOC_DOUBLE_TLV("Headphone Playback Volume",
109 ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
110 SOC_DOUBLE("Headphone Playback Switch",
111 ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
112};
113
114static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = {
115 SOC_DOUBLE_TLV("Speaker Playback Volume",
116 ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
117 SOC_DOUBLE("Speaker Playback Switch",
118 ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
119 SOC_DOUBLE_TLV("Line Playback Volume",
120 ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
121 SOC_DOUBLE("Line Playback Switch",
122 ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
123};
124
125static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = {
126 SOC_DOUBLE_TLV("Line Playback Volume",
127 ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
128 SOC_DOUBLE("Line Playback Switch",
129 ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
130 SOC_DOUBLE_TLV("Headphone Playback Volume",
131 ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
132 SOC_DOUBLE("Headphone Playback Switch",
133 ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
134};
135
136static const struct snd_kcontrol_new alc5623_snd_controls[] = {
137 SOC_DOUBLE_TLV("Auxout Playback Volume",
138 ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
139 SOC_DOUBLE("Auxout Playback Switch",
140 ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1),
141 SOC_DOUBLE_TLV("PCM Playback Volume",
142 ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv),
143 SOC_DOUBLE_TLV("AuxI Capture Volume",
144 ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv),
145 SOC_DOUBLE_TLV("LineIn Capture Volume",
146 ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
147 SOC_SINGLE_TLV("Mic1 Capture Volume",
148 ALC5623_MIC_VOL, 8, 31, 1, vol_tlv),
149 SOC_SINGLE_TLV("Mic2 Capture Volume",
150 ALC5623_MIC_VOL, 0, 31, 1, vol_tlv),
151 SOC_DOUBLE_TLV("Rec Capture Volume",
152 ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv),
153 SOC_SINGLE_TLV("Mic 1 Boost Volume",
154 ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv),
155 SOC_SINGLE_TLV("Mic 2 Boost Volume",
156 ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv),
157 SOC_SINGLE_TLV("Digital Boost Volume",
158 ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv),
159};
160
161/*
162 * DAPM Controls
163 */
164static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = {
165SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1),
166SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1),
167SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1),
168SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1),
169SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1),
170};
171
172static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = {
173SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1),
174};
175
176static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = {
177SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1),
178};
179
180static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = {
181SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1),
182SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1),
183SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1),
184SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1),
185SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1),
186SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1),
187SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1),
188};
189
190static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = {
191SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1),
192SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1),
193SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1),
194SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1),
195SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1),
196};
197
198/* Left Record Mixer */
199static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = {
200SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1),
201SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1),
202SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1),
203SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1),
204SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1),
205SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1),
206SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1),
207};
208
209/* Right Record Mixer */
210static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = {
211SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1),
212SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1),
213SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1),
214SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1),
215SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1),
216SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1),
217SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1),
218};
219
220static const char *alc5623_spk_n_sour_sel[] = {
221 "RN/-R", "RP/+R", "LN/-R", "Vmid" };
222static const char *alc5623_hpl_out_input_sel[] = {
223 "Vmid", "HP Left Mix"};
224static const char *alc5623_hpr_out_input_sel[] = {
225 "Vmid", "HP Right Mix"};
226static const char *alc5623_spkout_input_sel[] = {
227 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
228static const char *alc5623_aux_out_input_sel[] = {
229 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
230
231/* auxout output mux */
232static const struct soc_enum alc5623_aux_out_input_enum =
233SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel);
234static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
235SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
236
237/* speaker output mux */
238static const struct soc_enum alc5623_spkout_input_enum =
239SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel);
240static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
241SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
242
243/* headphone left output mux */
244static const struct soc_enum alc5623_hpl_out_input_enum =
245SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel);
246static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
247SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
248
249/* headphone right output mux */
250static const struct soc_enum alc5623_hpr_out_input_enum =
251SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel);
252static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
253SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
254
255/* speaker output N select */
256static const struct soc_enum alc5623_spk_n_sour_enum =
257SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel);
258static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
259SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
260
261static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = {
262/* Muxes */
263SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
264 &alc5623_auxout_mux_controls),
265SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
266 &alc5623_spkout_mux_controls),
267SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
268 &alc5623_hpl_out_mux_controls),
269SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
270 &alc5623_hpr_out_mux_controls),
271SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
272 &alc5623_spkoutn_mux_controls),
273
274/* output mixers */
275SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
276 &alc5623_hp_mixer_controls[0],
277 ARRAY_SIZE(alc5623_hp_mixer_controls)),
278SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0,
279 &alc5623_hpr_mixer_controls[0],
280 ARRAY_SIZE(alc5623_hpr_mixer_controls)),
281SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0,
282 &alc5623_hpl_mixer_controls[0],
283 ARRAY_SIZE(alc5623_hpl_mixer_controls)),
284SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
285SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0,
286 &alc5623_mono_mixer_controls[0],
287 ARRAY_SIZE(alc5623_mono_mixer_controls)),
288SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0,
289 &alc5623_speaker_mixer_controls[0],
290 ARRAY_SIZE(alc5623_speaker_mixer_controls)),
291
292/* input mixers */
293SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0,
294 &alc5623_captureL_mixer_controls[0],
295 ARRAY_SIZE(alc5623_captureL_mixer_controls)),
296SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0,
297 &alc5623_captureR_mixer_controls[0],
298 ARRAY_SIZE(alc5623_captureR_mixer_controls)),
299
300SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
301 ALC5623_PWR_MANAG_ADD2, 9, 0),
302SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
303 ALC5623_PWR_MANAG_ADD2, 8, 0),
304SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0),
305SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
306SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
307SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
308 ALC5623_PWR_MANAG_ADD2, 7, 0),
309SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
310 ALC5623_PWR_MANAG_ADD2, 6, 0),
311SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0),
312SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0),
313SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0),
314SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0),
315SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0),
316SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0),
317SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0),
318SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0),
319SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0),
320SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0),
321SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0),
322SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0),
323SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0),
324SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0),
325
326SND_SOC_DAPM_OUTPUT("AUXOUTL"),
327SND_SOC_DAPM_OUTPUT("AUXOUTR"),
328SND_SOC_DAPM_OUTPUT("HPL"),
329SND_SOC_DAPM_OUTPUT("HPR"),
330SND_SOC_DAPM_OUTPUT("SPKOUT"),
331SND_SOC_DAPM_OUTPUT("SPKOUTN"),
332SND_SOC_DAPM_INPUT("LINEINL"),
333SND_SOC_DAPM_INPUT("LINEINR"),
334SND_SOC_DAPM_INPUT("AUXINL"),
335SND_SOC_DAPM_INPUT("AUXINR"),
336SND_SOC_DAPM_INPUT("MIC1"),
337SND_SOC_DAPM_INPUT("MIC2"),
338SND_SOC_DAPM_VMID("Vmid"),
339};
340
341static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
342static const struct soc_enum alc5623_amp_enum =
343 SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names);
344static const struct snd_kcontrol_new alc5623_amp_mux_controls =
345 SOC_DAPM_ENUM("Route", alc5623_amp_enum);
346
347static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = {
348SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0,
349 amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
350SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0),
351SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0,
352 &alc5623_amp_mux_controls),
353};
354
355static const struct snd_soc_dapm_route intercon[] = {
356 /* virtual mixer - mixes left & right channels */
357 {"I2S Mix", NULL, "Left DAC"},
358 {"I2S Mix", NULL, "Right DAC"},
359 {"Line Mix", NULL, "Right LineIn"},
360 {"Line Mix", NULL, "Left LineIn"},
361 {"AuxI Mix", NULL, "Left AuxI"},
362 {"AuxI Mix", NULL, "Right AuxI"},
363 {"AUXOUTL", NULL, "Left AuxOut"},
364 {"AUXOUTR", NULL, "Right AuxOut"},
365
366 /* HP mixer */
367 {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
368 {"HPL Mix", NULL, "HP Mix"},
369 {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
370 {"HPR Mix", NULL, "HP Mix"},
371 {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
372 {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"},
373 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
374 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
375 {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"},
376
377 /* speaker mixer */
378 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
379 {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"},
380 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
381 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
382 {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"},
383
384 /* mono mixer */
385 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
386 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
387 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
388 {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"},
389 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
390 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
391 {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"},
392
393 /* Left record mixer */
394 {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
395 {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"},
396 {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
397 {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
398 {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
399 {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
400 {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
401
402 /*Right record mixer */
403 {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
404 {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"},
405 {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
406 {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
407 {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
408 {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
409 {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
410
411 /* headphone left mux */
412 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
413 {"Left Headphone Mux", "Vmid", "Vmid"},
414
415 /* headphone right mux */
416 {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
417 {"Right Headphone Mux", "Vmid", "Vmid"},
418
419 /* speaker out mux */
420 {"SpeakerOut Mux", "Vmid", "Vmid"},
421 {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
422 {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
423 {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
424
425 /* Mono/Aux Out mux */
426 {"AuxOut Mux", "Vmid", "Vmid"},
427 {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
428 {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
429 {"AuxOut Mux", "Mono Mix", "Mono Mix"},
430
431 /* output pga */
432 {"HPL", NULL, "Left Headphone"},
433 {"Left Headphone", NULL, "Left Headphone Mux"},
434 {"HPR", NULL, "Right Headphone"},
435 {"Right Headphone", NULL, "Right Headphone Mux"},
436 {"Left AuxOut", NULL, "AuxOut Mux"},
437 {"Right AuxOut", NULL, "AuxOut Mux"},
438
439 /* input pga */
440 {"Left LineIn", NULL, "LINEINL"},
441 {"Right LineIn", NULL, "LINEINR"},
442 {"Left AuxI", NULL, "AUXINL"},
443 {"Right AuxI", NULL, "AUXINR"},
444 {"MIC1 Pre Amp", NULL, "MIC1"},
445 {"MIC2 Pre Amp", NULL, "MIC2"},
446 {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
447 {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
448
449 /* left ADC */
450 {"Left ADC", NULL, "Left Capture Mix"},
451
452 /* right ADC */
453 {"Right ADC", NULL, "Right Capture Mix"},
454
455 {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"},
456 {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"},
457 {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"},
458 {"SpeakerOut N Mux", "Vmid", "Vmid"},
459
460 {"SPKOUT", NULL, "SpeakerOut"},
461 {"SPKOUTN", NULL, "SpeakerOut N Mux"},
462};
463
464static const struct snd_soc_dapm_route intercon_spk[] = {
465 {"SpeakerOut", NULL, "SpeakerOut Mux"},
466};
467
468static const struct snd_soc_dapm_route intercon_amp_spk[] = {
469 {"AB Amp", NULL, "SpeakerOut Mux"},
470 {"D Amp", NULL, "SpeakerOut Mux"},
471 {"AB-D Amp Mux", "AB Amp", "AB Amp"},
472 {"AB-D Amp Mux", "D Amp", "D Amp"},
473 {"SpeakerOut", NULL, "AB-D Amp Mux"},
474};
475
476/* PLL divisors */
477struct _pll_div {
478 u32 pll_in;
479 u32 pll_out;
480 u16 regvalue;
481};
482
483/* Note : pll code from original alc5623 driver. Not sure of how good it is */
484/* useful only for master mode */
485static const struct _pll_div codec_master_pll_div[] = {
486
487 { 2048000, 8192000, 0x0ea0},
488 { 3686400, 8192000, 0x4e27},
489 { 12000000, 8192000, 0x456b},
490 { 13000000, 8192000, 0x495f},
491 { 13100000, 8192000, 0x0320},
492 { 2048000, 11289600, 0xf637},
493 { 3686400, 11289600, 0x2f22},
494 { 12000000, 11289600, 0x3e2f},
495 { 13000000, 11289600, 0x4d5b},
496 { 13100000, 11289600, 0x363b},
497 { 2048000, 16384000, 0x1ea0},
498 { 3686400, 16384000, 0x9e27},
499 { 12000000, 16384000, 0x452b},
500 { 13000000, 16384000, 0x542f},
501 { 13100000, 16384000, 0x03a0},
502 { 2048000, 16934400, 0xe625},
503 { 3686400, 16934400, 0x9126},
504 { 12000000, 16934400, 0x4d2c},
505 { 13000000, 16934400, 0x742f},
506 { 13100000, 16934400, 0x3c27},
507 { 2048000, 22579200, 0x2aa0},
508 { 3686400, 22579200, 0x2f20},
509 { 12000000, 22579200, 0x7e2f},
510 { 13000000, 22579200, 0x742f},
511 { 13100000, 22579200, 0x3c27},
512 { 2048000, 24576000, 0x2ea0},
513 { 3686400, 24576000, 0xee27},
514 { 12000000, 24576000, 0x2915},
515 { 13000000, 24576000, 0x772e},
516 { 13100000, 24576000, 0x0d20},
517};
518
519static const struct _pll_div codec_slave_pll_div[] = {
520
521 { 1024000, 16384000, 0x3ea0},
522 { 1411200, 22579200, 0x3ea0},
523 { 1536000, 24576000, 0x3ea0},
524 { 2048000, 16384000, 0x1ea0},
525 { 2822400, 22579200, 0x1ea0},
526 { 3072000, 24576000, 0x1ea0},
527
528};
529
530static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
531 int source, unsigned int freq_in, unsigned int freq_out)
532{
533 int i;
534 struct snd_soc_codec *codec = codec_dai->codec;
535 int gbl_clk = 0, pll_div = 0;
536 u16 reg;
537
538 if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK)
539 return -ENODEV;
540
541 /* Disable PLL power */
542 snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
543 ALC5623_PWR_ADD2_PLL,
544 0);
545
546 /* pll is not used in slave mode */
547 reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
548 if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
549 return 0;
550
551 if (!freq_in || !freq_out)
552 return 0;
553
554 switch (pll_id) {
555 case ALC5623_PLL_FR_MCLK:
556 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
557 if (codec_master_pll_div[i].pll_in == freq_in
558 && codec_master_pll_div[i].pll_out == freq_out) {
559 /* PLL source from MCLK */
560 pll_div = codec_master_pll_div[i].regvalue;
561 break;
562 }
563 }
564 break;
565 case ALC5623_PLL_FR_BCK:
566 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
567 if (codec_slave_pll_div[i].pll_in == freq_in
568 && codec_slave_pll_div[i].pll_out == freq_out) {
569 /* PLL source from Bitclk */
570 gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK;
571 pll_div = codec_slave_pll_div[i].regvalue;
572 break;
573 }
574 }
575 break;
576 default:
577 return -EINVAL;
578 }
579
580 if (!pll_div)
581 return -EINVAL;
582
583 snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
584 snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
585 snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
586 ALC5623_PWR_ADD2_PLL,
587 ALC5623_PWR_ADD2_PLL);
588 gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
589 snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
590
591 return 0;
592}
593
594struct _coeff_div {
595 u16 fs;
596 u16 regvalue;
597};
598
599/* codec hifi mclk (after PLL) clock divider coefficients */
600/* values inspired from column BCLK=32Fs of Appendix A table */
601static const struct _coeff_div coeff_div[] = {
602 {256*8, 0x3a69},
603 {384*8, 0x3c6b},
604 {256*4, 0x2a69},
605 {384*4, 0x2c6b},
606 {256*2, 0x1a69},
607 {384*2, 0x1c6b},
608 {256*1, 0x0a69},
609 {384*1, 0x0c6b},
610};
611
612static int get_coeff(struct snd_soc_codec *codec, int rate)
613{
614 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
615 int i;
616
617 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
618 if (coeff_div[i].fs * rate == alc5623->sysclk)
619 return i;
620 }
621 return -EINVAL;
622}
623
624/*
625 * Clock after PLL and dividers
626 */
627static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
628 int clk_id, unsigned int freq, int dir)
629{
630 struct snd_soc_codec *codec = codec_dai->codec;
631 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
632
633 switch (freq) {
634 case 8192000:
635 case 11289600:
636 case 12288000:
637 case 16384000:
638 case 16934400:
639 case 18432000:
640 case 22579200:
641 case 24576000:
642 alc5623->sysclk = freq;
643 return 0;
644 }
645 return -EINVAL;
646}
647
648static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
649 unsigned int fmt)
650{
651 struct snd_soc_codec *codec = codec_dai->codec;
652 u16 iface = 0;
653
654 /* set master/slave audio interface */
655 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
656 case SND_SOC_DAIFMT_CBM_CFM:
657 iface = ALC5623_DAI_SDP_MASTER_MODE;
658 break;
659 case SND_SOC_DAIFMT_CBS_CFS:
660 iface = ALC5623_DAI_SDP_SLAVE_MODE;
661 break;
662 default:
663 return -EINVAL;
664 }
665
666 /* interface format */
667 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
668 case SND_SOC_DAIFMT_I2S:
669 iface |= ALC5623_DAI_I2S_DF_I2S;
670 break;
671 case SND_SOC_DAIFMT_RIGHT_J:
672 iface |= ALC5623_DAI_I2S_DF_RIGHT;
673 break;
674 case SND_SOC_DAIFMT_LEFT_J:
675 iface |= ALC5623_DAI_I2S_DF_LEFT;
676 break;
677 case SND_SOC_DAIFMT_DSP_A:
678 iface |= ALC5623_DAI_I2S_DF_PCM;
679 break;
680 case SND_SOC_DAIFMT_DSP_B:
681 iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE;
682 break;
683 default:
684 return -EINVAL;
685 }
686
687 /* clock inversion */
688 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
689 case SND_SOC_DAIFMT_NB_NF:
690 break;
691 case SND_SOC_DAIFMT_IB_IF:
692 iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
693 break;
694 case SND_SOC_DAIFMT_IB_NF:
695 iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
696 break;
697 case SND_SOC_DAIFMT_NB_IF:
698 break;
699 default:
700 return -EINVAL;
701 }
702
703 return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
704}
705
706static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
707 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
708{
709 struct snd_soc_pcm_runtime *rtd = substream->private_data;
710 struct snd_soc_codec *codec = rtd->codec;
711 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
712 int coeff, rate;
713 u16 iface;
714
715 iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
716 iface &= ~ALC5623_DAI_I2S_DL_MASK;
717
718 /* bit size */
719 switch (params_format(params)) {
720 case SNDRV_PCM_FORMAT_S16_LE:
721 iface |= ALC5623_DAI_I2S_DL_16;
722 break;
723 case SNDRV_PCM_FORMAT_S20_3LE:
724 iface |= ALC5623_DAI_I2S_DL_20;
725 break;
726 case SNDRV_PCM_FORMAT_S24_LE:
727 iface |= ALC5623_DAI_I2S_DL_24;
728 break;
729 case SNDRV_PCM_FORMAT_S32_LE:
730 iface |= ALC5623_DAI_I2S_DL_32;
731 break;
732 default:
733 return -EINVAL;
734 }
735
736 /* set iface & srate */
737 snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
738 rate = params_rate(params);
739 coeff = get_coeff(codec, rate);
740 if (coeff < 0)
741 return -EINVAL;
742
743 coeff = coeff_div[coeff].regvalue;
744 dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
745 __func__, alc5623->sysclk, rate, coeff);
746 snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
747
748 return 0;
749}
750
751static int alc5623_mute(struct snd_soc_dai *dai, int mute)
752{
753 struct snd_soc_codec *codec = dai->codec;
754 u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
755 u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
756
757 if (mute)
758 mute_reg |= hp_mute;
759
760 return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
761}
762
763#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
764 | ALC5623_PWR_ADD2_DAC_REF_CIR)
765
766#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \
767 | ALC5623_PWR_ADD3_MIC1_BOOST_AD)
768
769#define ALC5623_ADD1_POWER_EN \
770 (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \
771 | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \
772 | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP)
773
774#define ALC5623_ADD1_POWER_EN_5622 \
775 (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
776 | ALC5623_PWR_ADD1_HP_OUT_AMP)
777
778static void enable_power_depop(struct snd_soc_codec *codec)
779{
780 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
781
782 snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
783 ALC5623_PWR_ADD1_SOFTGEN_EN,
784 ALC5623_PWR_ADD1_SOFTGEN_EN);
785
786 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
787
788 snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
789 ALC5623_MISC_HP_DEPOP_MODE2_EN,
790 ALC5623_MISC_HP_DEPOP_MODE2_EN);
791
792 msleep(500);
793
794 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
795
796 /* avoid writing '1' into 5622 reserved bits */
797 if (alc5623->id == 0x22)
798 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
799 ALC5623_ADD1_POWER_EN_5622);
800 else
801 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
802 ALC5623_ADD1_POWER_EN);
803
804 /* disable HP Depop2 */
805 snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
806 ALC5623_MISC_HP_DEPOP_MODE2_EN,
807 0);
808
809}
810
811static int alc5623_set_bias_level(struct snd_soc_codec *codec,
812 enum snd_soc_bias_level level)
813{
814 switch (level) {
815 case SND_SOC_BIAS_ON:
816 enable_power_depop(codec);
817 break;
818 case SND_SOC_BIAS_PREPARE:
819 break;
820 case SND_SOC_BIAS_STANDBY:
821 /* everything off except vref/vmid, */
822 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
823 ALC5623_PWR_ADD2_VREF);
824 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
825 ALC5623_PWR_ADD3_MAIN_BIAS);
826 break;
827 case SND_SOC_BIAS_OFF:
828 /* everything off, dac mute, inactive */
829 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
830 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
831 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
832 break;
833 }
834 codec->dapm.bias_level = level;
835 return 0;
836}
837
838#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
839 | SNDRV_PCM_FMTBIT_S24_LE \
840 | SNDRV_PCM_FMTBIT_S32_LE)
841
842static struct snd_soc_dai_ops alc5623_dai_ops = {
843 .hw_params = alc5623_pcm_hw_params,
844 .digital_mute = alc5623_mute,
845 .set_fmt = alc5623_set_dai_fmt,
846 .set_sysclk = alc5623_set_dai_sysclk,
847 .set_pll = alc5623_set_dai_pll,
848};
849
850static struct snd_soc_dai_driver alc5623_dai = {
851 .name = "alc5623-hifi",
852 .playback = {
853 .stream_name = "Playback",
854 .channels_min = 1,
855 .channels_max = 2,
856 .rate_min = 8000,
857 .rate_max = 48000,
858 .rates = SNDRV_PCM_RATE_8000_48000,
859 .formats = ALC5623_FORMATS,},
860 .capture = {
861 .stream_name = "Capture",
862 .channels_min = 1,
863 .channels_max = 2,
864 .rate_min = 8000,
865 .rate_max = 48000,
866 .rates = SNDRV_PCM_RATE_8000_48000,
867 .formats = ALC5623_FORMATS,},
868
869 .ops = &alc5623_dai_ops,
870};
871
872static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
873{
874 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
875 return 0;
876}
877
878static int alc5623_resume(struct snd_soc_codec *codec)
879{
880 int i, step = codec->driver->reg_cache_step;
881 u16 *cache = codec->reg_cache;
882
883 /* Sync reg_cache with the hardware */
884 for (i = 2 ; i < codec->driver->reg_cache_size ; i += step)
885 snd_soc_write(codec, i, cache[i]);
886
887 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
888
889 /* charge alc5623 caps */
890 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
891 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
892 codec->dapm.bias_level = SND_SOC_BIAS_ON;
893 alc5623_set_bias_level(codec, codec->dapm.bias_level);
894 }
895
896 return 0;
897}
898
899static int alc5623_probe(struct snd_soc_codec *codec)
900{
901 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
902 struct snd_soc_dapm_context *dapm = &codec->dapm;
903 int ret;
904
905 ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type);
906 if (ret < 0) {
907 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
908 return ret;
909 }
910
911 alc5623_reset(codec);
912 alc5623_fill_cache(codec);
913
914 /* power on device */
915 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
916
917 if (alc5623->add_ctrl) {
918 snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
919 alc5623->add_ctrl);
920 }
921
922 if (alc5623->jack_det_ctrl) {
923 snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
924 alc5623->jack_det_ctrl);
925 }
926
927 switch (alc5623->id) {
928 case 0x21:
929 snd_soc_add_controls(codec, rt5621_vol_snd_controls,
930 ARRAY_SIZE(rt5621_vol_snd_controls));
931 break;
932 case 0x22:
933 snd_soc_add_controls(codec, rt5622_vol_snd_controls,
934 ARRAY_SIZE(rt5622_vol_snd_controls));
935 break;
936 case 0x23:
937 snd_soc_add_controls(codec, alc5623_vol_snd_controls,
938 ARRAY_SIZE(alc5623_vol_snd_controls));
939 break;
940 default:
941 return -EINVAL;
942 }
943
944 snd_soc_add_controls(codec, alc5623_snd_controls,
945 ARRAY_SIZE(alc5623_snd_controls));
946
947 snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
948 ARRAY_SIZE(alc5623_dapm_widgets));
949
950 /* set up audio path interconnects */
951 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
952
953 switch (alc5623->id) {
954 case 0x21:
955 case 0x22:
956 snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets,
957 ARRAY_SIZE(alc5623_dapm_amp_widgets));
958 snd_soc_dapm_add_routes(dapm, intercon_amp_spk,
959 ARRAY_SIZE(intercon_amp_spk));
960 break;
961 case 0x23:
962 snd_soc_dapm_add_routes(dapm, intercon_spk,
963 ARRAY_SIZE(intercon_spk));
964 break;
965 default:
966 return -EINVAL;
967 }
968
969 return ret;
970}
971
972/* power down chip */
973static int alc5623_remove(struct snd_soc_codec *codec)
974{
975 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
976 return 0;
977}
978
979static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
980 .probe = alc5623_probe,
981 .remove = alc5623_remove,
982 .suspend = alc5623_suspend,
983 .resume = alc5623_resume,
984 .set_bias_level = alc5623_set_bias_level,
985 .reg_cache_size = ALC5623_VENDOR_ID2+2,
986 .reg_word_size = sizeof(u16),
987 .reg_cache_step = 2,
988};
989
990/*
991 * ALC5623 2 wire address is determined by A1 pin
992 * state during powerup.
993 * low = 0x1a
994 * high = 0x1b
995 */
996static int alc5623_i2c_probe(struct i2c_client *client,
997 const struct i2c_device_id *id)
998{
999 struct alc5623_platform_data *pdata;
1000 struct alc5623_priv *alc5623;
1001 int ret, vid1, vid2;
1002
1003 vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1);
1004 if (vid1 < 0) {
1005 dev_err(&client->dev, "failed to read I2C\n");
1006 return -EIO;
1007 }
1008 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
1009
1010 vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2);
1011 if (vid2 < 0) {
1012 dev_err(&client->dev, "failed to read I2C\n");
1013 return -EIO;
1014 }
1015
1016 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
1017 dev_err(&client->dev, "unknown or wrong codec\n");
1018 dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
1019 0x10ec, id->driver_data,
1020 vid1, vid2);
1021 return -ENODEV;
1022 }
1023
1024 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
1025
1026 alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL);
1027 if (alc5623 == NULL)
1028 return -ENOMEM;
1029
1030 pdata = client->dev.platform_data;
1031 if (pdata) {
1032 alc5623->add_ctrl = pdata->add_ctrl;
1033 alc5623->jack_det_ctrl = pdata->jack_det_ctrl;
1034 }
1035
1036 alc5623->id = vid2;
1037 switch (alc5623->id) {
1038 case 0x21:
1039 alc5623_dai.name = "alc5621-hifi";
1040 break;
1041 case 0x22:
1042 alc5623_dai.name = "alc5622-hifi";
1043 break;
1044 case 0x23:
1045 alc5623_dai.name = "alc5623-hifi";
1046 break;
1047 default:
1048 kfree(alc5623);
1049 return -EINVAL;
1050 }
1051
1052 i2c_set_clientdata(client, alc5623);
1053 alc5623->control_data = client;
1054 alc5623->control_type = SND_SOC_I2C;
1055 mutex_init(&alc5623->mutex);
1056
1057 ret = snd_soc_register_codec(&client->dev,
1058 &soc_codec_device_alc5623, &alc5623_dai, 1);
1059 if (ret != 0) {
1060 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1061 kfree(alc5623);
1062 }
1063
1064 return ret;
1065}
1066
1067static int alc5623_i2c_remove(struct i2c_client *client)
1068{
1069 struct alc5623_priv *alc5623 = i2c_get_clientdata(client);
1070
1071 snd_soc_unregister_codec(&client->dev);
1072 kfree(alc5623);
1073 return 0;
1074}
1075
1076static const struct i2c_device_id alc5623_i2c_table[] = {
1077 {"alc5621", 0x21},
1078 {"alc5622", 0x22},
1079 {"alc5623", 0x23},
1080 {}
1081};
1082MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
1083
1084/* i2c codec control layer */
1085static struct i2c_driver alc5623_i2c_driver = {
1086 .driver = {
1087 .name = "alc562x-codec",
1088 .owner = THIS_MODULE,
1089 },
1090 .probe = alc5623_i2c_probe,
1091 .remove = __devexit_p(alc5623_i2c_remove),
1092 .id_table = alc5623_i2c_table,
1093};
1094
1095static int __init alc5623_modinit(void)
1096{
1097 int ret;
1098
1099 ret = i2c_add_driver(&alc5623_i2c_driver);
1100 if (ret != 0) {
1101 printk(KERN_ERR "%s: can't add i2c driver", __func__);
1102 return ret;
1103 }
1104
1105 return ret;
1106}
1107module_init(alc5623_modinit);
1108
1109static void __exit alc5623_modexit(void)
1110{
1111 i2c_del_driver(&alc5623_i2c_driver);
1112}
1113module_exit(alc5623_modexit);
1114
1115MODULE_DESCRIPTION("ASoC alc5621/2/3 driver");
1116MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
1117MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5623.h b/sound/soc/codecs/alc5623.h
new file mode 100644
index 000000000000..f3d68260d425
--- /dev/null
+++ b/sound/soc/codecs/alc5623.h
@@ -0,0 +1,161 @@
1/*
2 * alc5623.h -- alc562[123] ALSA Soc Audio driver
3 *
4 * Copyright 2008 Realtek Microelectronics
5 * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
6 *
7 * Author: flove <flove@realtek.com>
8 * Arnaud Patard <arnaud.patard@rtp-net.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#ifndef _ALC5623_H
17#define _ALC5623_H
18
19#define ALC5623_RESET 0x00
20/* 5621 5622 5623 */
21/* speaker output vol 2 2 */
22/* line output vol 4 2 */
23/* HP output vol 4 0 4 */
24#define ALC5623_SPK_OUT_VOL 0x02
25#define ALC5623_HP_OUT_VOL 0x04
26#define ALC5623_MONO_AUX_OUT_VOL 0x06
27#define ALC5623_AUXIN_VOL 0x08
28#define ALC5623_LINE_IN_VOL 0x0A
29#define ALC5623_STEREO_DAC_VOL 0x0C
30#define ALC5623_MIC_VOL 0x0E
31#define ALC5623_MIC_ROUTING_CTRL 0x10
32#define ALC5623_ADC_REC_GAIN 0x12
33#define ALC5623_ADC_REC_MIXER 0x14
34#define ALC5623_SOFT_VOL_CTRL_TIME 0x16
35/* ALC5623_OUTPUT_MIXER_CTRL : */
36/* same remark as for reg 2 line vs speaker */
37#define ALC5623_OUTPUT_MIXER_CTRL 0x1C
38#define ALC5623_MIC_CTRL 0x22
39
40#define ALC5623_DAI_CONTROL 0x34
41#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15)
42#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15)
43#define ALC5623_DAI_I2S_PCM_MODE (1 << 14)
44#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
45#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5)
46#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4)
47#define ALC5623_DAI_I2S_DL_MASK (3 << 2)
48#define ALC5623_DAI_I2S_DL_32 (3 << 2)
49#define ALC5623_DAI_I2S_DL_24 (2 << 2)
50#define ALC5623_DAI_I2S_DL_20 (1 << 2)
51#define ALC5623_DAI_I2S_DL_16 (0 << 2)
52#define ALC5623_DAI_I2S_DF_PCM (3 << 0)
53#define ALC5623_DAI_I2S_DF_LEFT (2 << 0)
54#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0)
55#define ALC5623_DAI_I2S_DF_I2S (0 << 0)
56
57#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36
58#define ALC5623_COMPANDING_CTRL 0x38
59
60#define ALC5623_PWR_MANAG_ADD1 0x3A
61#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15)
62#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14)
63#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11)
64#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10)
65#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */
66#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */
67#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5)
68#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */
69#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2)
70#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1)
71#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */
72
73#define ALC5623_PWR_MANAG_ADD2 0x3C
74#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */
75#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */
76#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */
77#define ALC5623_PWR_ADD2_VREF (1 << 13)
78#define ALC5623_PWR_ADD2_PLL (1 << 12)
79#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10)
80#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9)
81#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8)
82#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
83#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
84#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5)
85#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4)
86#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3)
87#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2)
88#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
89#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
90
91#define ALC5623_PWR_MANAG_ADD3 0x3E
92#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15)
93#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14)
94#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13)
95#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12)
96#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10)
97#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9)
98#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7)
99#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6)
100#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5)
101#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4)
102#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3)
103#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2)
104#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
105#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
106
107#define ALC5623_ADD_CTRL_REG 0x40
108
109#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42
110#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15)
111#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15)
112#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14)
113#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14)
114#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1)
115#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1)
116#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1)
117#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1)
118#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0)
119#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0)
120
121#define ALC5623_PLL_CTRL 0x44
122#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
123#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
124#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf)
125
126#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A
127#define ALC5623_GPIO_PIN_CONFIG 0x4C
128#define ALC5623_GPIO_PIN_POLARITY 0x4E
129#define ALC5623_GPIO_PIN_STICKY 0x50
130#define ALC5623_GPIO_PIN_WAKEUP 0x52
131#define ALC5623_GPIO_PIN_STATUS 0x54
132#define ALC5623_GPIO_PIN_SHARING 0x56
133#define ALC5623_OVER_CURR_STATUS 0x58
134#define ALC5623_JACK_DET_CTRL 0x5A
135
136#define ALC5623_MISC_CTRL 0x5E
137#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15)
138#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */
139#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */
140#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10)
141#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9)
142#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8)
143#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6)
144#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5)
145#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4)
146#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3)
147#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2)
148#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0)
149
150#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60
151#define ALC5623_EQ_CTRL 0x62
152#define ALC5623_EQ_MODE_ENABLE 0x66
153#define ALC5623_AVC_CTRL 0x68
154#define ALC5623_HID_CTRL_INDEX 0x6A
155#define ALC5623_HID_CTRL_DATA 0x6C
156#define ALC5623_VENDOR_ID1 0x7C
157#define ALC5623_VENDOR_ID2 0x7E
158
159#define ALC5623_PLL_FR_MCLK 0
160#define ALC5623_PLL_FR_BCK 1
161#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index a320fb5a0e26..46dbfd067f79 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -30,19 +30,16 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/mfd/davinci_voicecodec.h> 32#include <linux/mfd/davinci_voicecodec.h>
33#include <linux/spi/spi.h>
33 34
34#include <sound/core.h> 35#include <sound/core.h>
35#include <sound/pcm.h> 36#include <sound/pcm.h>
36#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
37#include <sound/soc.h> 38#include <sound/soc.h>
38#include <sound/soc-dai.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h> 39#include <sound/initval.h>
41 40
42#include <mach/dm365.h> 41#include <mach/dm365.h>
43 42
44#include "cq93vc.h"
45
46static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, 43static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
47 unsigned int reg) 44 unsigned int reg)
48{ 45{
@@ -117,7 +114,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
117 DAVINCI_VC_REG12_POWER_ALL_OFF); 114 DAVINCI_VC_REG12_POWER_ALL_OFF);
118 break; 115 break;
119 } 116 }
120 codec->bias_level = level; 117 codec->dapm.bias_level = level;
121 118
122 return 0; 119 return 0;
123} 120}
@@ -130,8 +127,8 @@ static struct snd_soc_dai_ops cq93vc_dai_ops = {
130 .set_sysclk = cq93vc_set_dai_sysclk, 127 .set_sysclk = cq93vc_set_dai_sysclk,
131}; 128};
132 129
133struct snd_soc_dai cq93vc_dai = { 130static struct snd_soc_dai_driver cq93vc_dai = {
134 .name = "CQ93VC", 131 .name = "cq93vc-hifi",
135 .playback = { 132 .playback = {
136 .stream_name = "Playback", 133 .stream_name = "Playback",
137 .channels_min = 1, 134 .channels_min = 1,
@@ -146,36 +143,20 @@ struct snd_soc_dai cq93vc_dai = {
146 .formats = CQ93VC_FORMATS,}, 143 .formats = CQ93VC_FORMATS,},
147 .ops = &cq93vc_dai_ops, 144 .ops = &cq93vc_dai_ops,
148}; 145};
149EXPORT_SYMBOL_GPL(cq93vc_dai);
150 146
151static int cq93vc_resume(struct platform_device *pdev) 147static int cq93vc_resume(struct snd_soc_codec *codec)
152{ 148{
153 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
154 struct snd_soc_codec *codec = socdev->card->codec;
155
156 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 149 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
157 150
158 return 0; 151 return 0;
159} 152}
160 153
161static struct snd_soc_codec *cq93vc_codec; 154static int cq93vc_probe(struct snd_soc_codec *codec)
162
163static int cq93vc_probe(struct platform_device *pdev)
164{ 155{
165 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 156 struct davinci_vc *davinci_vc = codec->dev->platform_data;
166 struct device *dev = &pdev->dev; 157
167 struct snd_soc_codec *codec; 158 davinci_vc->cq93vc.codec = codec;
168 int ret; 159 codec->control_data = davinci_vc;
169
170 socdev->card->codec = cq93vc_codec;
171 codec = socdev->card->codec;
172
173 /* Register pcms */
174 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
175 if (ret < 0) {
176 dev_err(dev, "%s: failed to create pcms\n", pdev->name);
177 return ret;
178 }
179 160
180 /* Set controls */ 161 /* Set controls */
181 snd_soc_add_controls(codec, cq93vc_snd_controls, 162 snd_soc_add_controls(codec, cq93vc_snd_controls,
@@ -187,108 +168,51 @@ static int cq93vc_probe(struct platform_device *pdev)
187 return 0; 168 return 0;
188} 169}
189 170
190static int cq93vc_remove(struct platform_device *pdev) 171static int cq93vc_remove(struct snd_soc_codec *codec)
191{ 172{
192 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 173 cq93vc_set_bias_level(codec, SND_SOC_BIAS_OFF);
193
194 snd_soc_free_pcms(socdev);
195 snd_soc_dapm_free(socdev);
196 174
197 return 0; 175 return 0;
198} 176}
199 177
200struct snd_soc_codec_device soc_codec_dev_cq93vc = { 178static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
179 .read = cq93vc_read,
180 .write = cq93vc_write,
181 .set_bias_level = cq93vc_set_bias_level,
201 .probe = cq93vc_probe, 182 .probe = cq93vc_probe,
202 .remove = cq93vc_remove, 183 .remove = cq93vc_remove,
203 .resume = cq93vc_resume, 184 .resume = cq93vc_resume,
204}; 185};
205EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
206 186
207static __init int cq93vc_codec_probe(struct platform_device *pdev) 187static int cq93vc_platform_probe(struct platform_device *pdev)
208{ 188{
209 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 189 return snd_soc_register_codec(&pdev->dev,
210 struct snd_soc_codec *codec; 190 &soc_codec_dev_cq93vc, &cq93vc_dai, 1);
211 int ret;
212
213 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
214 if (codec == NULL) {
215 dev_dbg(davinci_vc->dev,
216 "could not allocate memory for codec data\n");
217 return -ENOMEM;
218 }
219
220 davinci_vc->cq93vc.codec = codec;
221
222 cq93vc_dai.dev = &pdev->dev;
223
224 mutex_init(&codec->mutex);
225 INIT_LIST_HEAD(&codec->dapm_widgets);
226 INIT_LIST_HEAD(&codec->dapm_paths);
227 codec->dev = &pdev->dev;
228 codec->name = "CQ93VC";
229 codec->owner = THIS_MODULE;
230 codec->read = cq93vc_read;
231 codec->write = cq93vc_write;
232 codec->set_bias_level = cq93vc_set_bias_level;
233 codec->dai = &cq93vc_dai;
234 codec->num_dai = 1;
235 codec->control_data = davinci_vc;
236
237 cq93vc_codec = codec;
238
239 ret = snd_soc_register_codec(codec);
240 if (ret) {
241 dev_err(davinci_vc->dev, "failed to register codec\n");
242 goto fail1;
243 }
244
245 ret = snd_soc_register_dai(&cq93vc_dai);
246 if (ret) {
247 dev_err(davinci_vc->dev, "could register dai\n");
248 goto fail2;
249 }
250 return 0;
251
252fail2:
253 snd_soc_unregister_codec(codec);
254
255fail1:
256 kfree(codec);
257 cq93vc_codec = NULL;
258
259 return ret;
260} 191}
261 192
262static int __devexit cq93vc_codec_remove(struct platform_device *pdev) 193static int cq93vc_platform_remove(struct platform_device *pdev)
263{ 194{
264 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 195 snd_soc_unregister_codec(&pdev->dev);
265 struct snd_soc_codec *codec = socdev->card->codec;
266
267 snd_soc_unregister_dai(&cq93vc_dai);
268 snd_soc_unregister_codec(&codec);
269
270 kfree(codec);
271 cq93vc_codec = NULL;
272
273 return 0; 196 return 0;
274} 197}
275 198
276static struct platform_driver cq93vc_codec_driver = { 199static struct platform_driver cq93vc_codec_driver = {
277 .driver = { 200 .driver = {
278 .name = "cq93vc", 201 .name = "cq93vc-codec",
279 .owner = THIS_MODULE, 202 .owner = THIS_MODULE,
280 }, 203 },
281 .probe = cq93vc_codec_probe, 204
282 .remove = __devexit_p(cq93vc_codec_remove), 205 .probe = cq93vc_platform_probe,
206 .remove = __devexit_p(cq93vc_platform_remove),
283}; 207};
284 208
285static __init int cq93vc_init(void) 209static int __init cq93vc_init(void)
286{ 210{
287 return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe); 211 return platform_driver_register(&cq93vc_codec_driver);
288} 212}
289module_init(cq93vc_init); 213module_init(cq93vc_init);
290 214
291static __exit void cq93vc_exit(void) 215static void __exit cq93vc_exit(void)
292{ 216{
293 platform_driver_unregister(&cq93vc_codec_driver); 217 platform_driver_unregister(&cq93vc_codec_driver);
294} 218}
diff --git a/sound/soc/codecs/cq93vc.h b/sound/soc/codecs/cq93vc.h
deleted file mode 100644
index 845b1968ef9c..000000000000
--- a/sound/soc/codecs/cq93vc.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _CQ93VC_H
24#define _CQ93VC_H
25
26extern struct snd_soc_dai cq93vc_dai;
27extern struct snd_soc_codec_device soc_codec_dev_cq93vc;
28
29#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 30d949239def..0206a17d7283 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -31,8 +31,6 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/regulator/consumer.h> 32#include <linux/regulator/consumer.h>
33 33
34#include "cs4270.h"
35
36/* 34/*
37 * The codec isn't really big-endian or little-endian, since the I2S 35 * The codec isn't really big-endian or little-endian, since the I2S
38 * interface requires data to be sent serially with the MSbit first. 36 * interface requires data to be sent serially with the MSbit first.
@@ -108,14 +106,29 @@
108#define CS4270_MUTE_DAC_A 0x01 106#define CS4270_MUTE_DAC_A 0x01
109#define CS4270_MUTE_DAC_B 0x02 107#define CS4270_MUTE_DAC_B 0x02
110 108
109/* Power-on default values for the registers
110 *
111 * This array contains the power-on default values of the registers, with the
112 * exception of the "CHIPID" register (01h). The lower four bits of that
113 * register contain the hardware revision, so it is treated as volatile.
114 *
115 * Also note that on the CS4270, the first readable register is 1, but ASoC
116 * assumes the first register is 0. Therfore, the array must have an entry for
117 * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't
118 * be read.
119 */
120static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = {
121 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00
122};
123
111static const char *supply_names[] = { 124static const char *supply_names[] = {
112 "va", "vd", "vlc" 125 "va", "vd", "vlc"
113}; 126};
114 127
115/* Private data for the CS4270 */ 128/* Private data for the CS4270 */
116struct cs4270_private { 129struct cs4270_private {
117 struct snd_soc_codec codec; 130 enum snd_soc_control_type control_type;
118 u8 reg_cache[CS4270_NUMREGS]; 131 void *control_data;
119 unsigned int mclk; /* Input frequency of the MCLK pin */ 132 unsigned int mclk; /* Input frequency of the MCLK pin */
120 unsigned int mode; /* The mode (I2S or left-justified) */ 133 unsigned int mode; /* The mode (I2S or left-justified) */
121 unsigned int slave_mode; 134 unsigned int slave_mode;
@@ -180,6 +193,20 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
180/* The number of MCLK/LRCK ratios supported by the CS4270 */ 193/* The number of MCLK/LRCK ratios supported by the CS4270 */
181#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) 194#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
182 195
196static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
197{
198 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
199}
200
201static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
202{
203 /* Unreadable registers are considered volatile */
204 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
205 return 1;
206
207 return reg == CS4270_CHIPID;
208}
209
183/** 210/**
184 * cs4270_set_dai_sysclk - determine the CS4270 samples rates. 211 * cs4270_set_dai_sysclk - determine the CS4270 samples rates.
185 * @codec_dai: the codec DAI 212 * @codec_dai: the codec DAI
@@ -212,44 +239,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
212{ 239{
213 struct snd_soc_codec *codec = codec_dai->codec; 240 struct snd_soc_codec *codec = codec_dai->codec;
214 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 241 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
215 unsigned int rates = 0;
216 unsigned int rate_min = -1;
217 unsigned int rate_max = 0;
218 unsigned int i;
219 242
220 cs4270->mclk = freq; 243 cs4270->mclk = freq;
221
222 if (cs4270->mclk) {
223 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
224 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
225 rates |= snd_pcm_rate_to_rate_bit(rate);
226 if (rate < rate_min)
227 rate_min = rate;
228 if (rate > rate_max)
229 rate_max = rate;
230 }
231 /* FIXME: soc should support a rate list */
232 rates &= ~SNDRV_PCM_RATE_KNOT;
233
234 if (!rates) {
235 dev_err(codec->dev, "could not find a valid sample rate\n");
236 return -EINVAL;
237 }
238 } else {
239 /* enable all possible rates */
240 rates = SNDRV_PCM_RATE_8000_192000;
241 rate_min = 8000;
242 rate_max = 192000;
243 }
244
245 codec_dai->playback.rates = rates;
246 codec_dai->playback.rate_min = rate_min;
247 codec_dai->playback.rate_max = rate_max;
248
249 codec_dai->capture.rates = rates;
250 codec_dai->capture.rate_min = rate_min;
251 codec_dai->capture.rate_max = rate_max;
252
253 return 0; 244 return 0;
254} 245}
255 246
@@ -301,97 +292,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
301} 292}
302 293
303/** 294/**
304 * cs4270_fill_cache - pre-fill the CS4270 register cache.
305 * @codec: the codec for this CS4270
306 *
307 * This function fills in the CS4270 register cache by reading the register
308 * values from the hardware.
309 *
310 * This CS4270 registers are cached to avoid excessive I2C I/O operations.
311 * After the initial read to pre-fill the cache, the CS4270 never updates
312 * the register values, so we won't have a cache coherency problem.
313 *
314 * We use the auto-increment feature of the CS4270 to read all registers in
315 * one shot.
316 */
317static int cs4270_fill_cache(struct snd_soc_codec *codec)
318{
319 u8 *cache = codec->reg_cache;
320 struct i2c_client *i2c_client = codec->control_data;
321 s32 length;
322
323 length = i2c_smbus_read_i2c_block_data(i2c_client,
324 CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
325
326 if (length != CS4270_NUMREGS) {
327 dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
328 i2c_client->addr);
329 return -EIO;
330 }
331
332 return 0;
333}
334
335/**
336 * cs4270_read_reg_cache - read from the CS4270 register cache.
337 * @codec: the codec for this CS4270
338 * @reg: the register to read
339 *
340 * This function returns the value for a given register. It reads only from
341 * the register cache, not the hardware itself.
342 *
343 * This CS4270 registers are cached to avoid excessive I2C I/O operations.
344 * After the initial read to pre-fill the cache, the CS4270 never updates
345 * the register values, so we won't have a cache coherency problem.
346 */
347static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
348 unsigned int reg)
349{
350 u8 *cache = codec->reg_cache;
351
352 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
353 return -EIO;
354
355 return cache[reg - CS4270_FIRSTREG];
356}
357
358/**
359 * cs4270_i2c_write - write to a CS4270 register via the I2C bus.
360 * @codec: the codec for this CS4270
361 * @reg: the register to write
362 * @value: the value to write to the register
363 *
364 * This function writes the given value to the given CS4270 register, and
365 * also updates the register cache.
366 *
367 * Note that we don't use the hw_write function pointer of snd_soc_codec.
368 * That's because it's too clunky: the hw_write_t prototype does not match
369 * i2c_smbus_write_byte_data(), and it's just another layer of overhead.
370 */
371static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
372 unsigned int value)
373{
374 u8 *cache = codec->reg_cache;
375
376 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
377 return -EIO;
378
379 /* Only perform an I2C operation if the new value is different */
380 if (cache[reg - CS4270_FIRSTREG] != value) {
381 struct i2c_client *client = codec->control_data;
382 if (i2c_smbus_write_byte_data(client, reg, value)) {
383 dev_err(codec->dev, "i2c write failed\n");
384 return -EIO;
385 }
386
387 /* We've written to the hardware, so update the cache */
388 cache[reg - CS4270_FIRSTREG] = value;
389 }
390
391 return 0;
392}
393
394/**
395 * cs4270_hw_params - program the CS4270 with the given hardware parameters. 295 * cs4270_hw_params - program the CS4270 with the given hardware parameters.
396 * @substream: the audio stream 296 * @substream: the audio stream
397 * @params: the hardware parameters to set 297 * @params: the hardware parameters to set
@@ -410,8 +310,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
410 struct snd_soc_dai *dai) 310 struct snd_soc_dai *dai)
411{ 311{
412 struct snd_soc_pcm_runtime *rtd = substream->private_data; 312 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 struct snd_soc_device *socdev = rtd->socdev; 313 struct snd_soc_codec *codec = rtd->codec;
414 struct snd_soc_codec *codec = socdev->card->codec;
415 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 314 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
416 int ret; 315 int ret;
417 unsigned int i; 316 unsigned int i;
@@ -549,19 +448,6 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
549 snd_soc_get_volsw, cs4270_soc_put_mute), 448 snd_soc_get_volsw, cs4270_soc_put_mute),
550}; 449};
551 450
552/*
553 * cs4270_codec - global variable to store codec for the ASoC probe function
554 *
555 * If struct i2c_driver had a private_data field, we wouldn't need to use
556 * cs4270_codec. This is the only way to pass the codec structure from
557 * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
558 * way to synchronize these two functions. cs4270_i2c_probe() can be called
559 * multiple times before cs4270_probe() is called even once. So for now, we
560 * also only allow cs4270_i2c_probe() to be run once. That means that we do
561 * not support more than one cs4270 device in the system, at least for now.
562 */
563static struct snd_soc_codec *cs4270_codec;
564
565static struct snd_soc_dai_ops cs4270_dai_ops = { 451static struct snd_soc_dai_ops cs4270_dai_ops = {
566 .hw_params = cs4270_hw_params, 452 .hw_params = cs4270_hw_params,
567 .set_sysclk = cs4270_set_dai_sysclk, 453 .set_sysclk = cs4270_set_dai_sysclk,
@@ -569,25 +455,28 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
569 .digital_mute = cs4270_dai_mute, 455 .digital_mute = cs4270_dai_mute,
570}; 456};
571 457
572struct snd_soc_dai cs4270_dai = { 458static struct snd_soc_dai_driver cs4270_dai = {
573 .name = "cs4270", 459 .name = "cs4270-hifi",
574 .playback = { 460 .playback = {
575 .stream_name = "Playback", 461 .stream_name = "Playback",
576 .channels_min = 1, 462 .channels_min = 1,
577 .channels_max = 2, 463 .channels_max = 2,
578 .rates = 0, 464 .rates = SNDRV_PCM_RATE_CONTINUOUS,
465 .rate_min = 4000,
466 .rate_max = 216000,
579 .formats = CS4270_FORMATS, 467 .formats = CS4270_FORMATS,
580 }, 468 },
581 .capture = { 469 .capture = {
582 .stream_name = "Capture", 470 .stream_name = "Capture",
583 .channels_min = 1, 471 .channels_min = 1,
584 .channels_max = 2, 472 .channels_max = 2,
585 .rates = 0, 473 .rates = SNDRV_PCM_RATE_CONTINUOUS,
474 .rate_min = 4000,
475 .rate_max = 216000,
586 .formats = CS4270_FORMATS, 476 .formats = CS4270_FORMATS,
587 }, 477 },
588 .ops = &cs4270_dai_ops, 478 .ops = &cs4270_dai_ops,
589}; 479};
590EXPORT_SYMBOL_GPL(cs4270_dai);
591 480
592/** 481/**
593 * cs4270_probe - ASoC probe function 482 * cs4270_probe - ASoC probe function
@@ -596,20 +485,42 @@ EXPORT_SYMBOL_GPL(cs4270_dai);
596 * This function is called when ASoC has all the pieces it needs to 485 * This function is called when ASoC has all the pieces it needs to
597 * instantiate a sound driver. 486 * instantiate a sound driver.
598 */ 487 */
599static int cs4270_probe(struct platform_device *pdev) 488static int cs4270_probe(struct snd_soc_codec *codec)
600{ 489{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = cs4270_codec;
603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 490 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
604 int i, ret; 491 int i, ret;
605 492
606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 493 codec->control_data = cs4270->control_data;
607 socdev->card->codec = codec;
608 494
609 /* Register PCMs */ 495 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
610 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 496 * then do the I2C transactions itself.
497 */
498 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type);
499 if (ret < 0) {
500 dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
501 return ret;
502 }
503
504 /* Disable auto-mute. This feature appears to be buggy. In some
505 * situations, auto-mute will not deactivate when it should, so we want
506 * this feature disabled by default. An application (e.g. alsactl) can
507 * re-enabled it by using the controls.
508 */
509 ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
510 if (ret < 0) {
511 dev_err(codec->dev, "i2c write failed\n");
512 return ret;
513 }
514
515 /* Disable automatic volume control. The hardware enables, and it
516 * causes volume change commands to be delayed, sometimes until after
517 * playback has started. An application (e.g. alsactl) can
518 * re-enabled it by using the controls.
519 */
520 ret = snd_soc_update_bits(codec, CS4270_TRANS,
521 CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
611 if (ret < 0) { 522 if (ret < 0) {
612 dev_err(codec->dev, "failed to create pcms\n"); 523 dev_err(codec->dev, "i2c write failed\n");
613 return ret; 524 return ret;
614 } 525 }
615 526
@@ -618,7 +529,7 @@ static int cs4270_probe(struct platform_device *pdev)
618 ARRAY_SIZE(cs4270_snd_controls)); 529 ARRAY_SIZE(cs4270_snd_controls));
619 if (ret < 0) { 530 if (ret < 0) {
620 dev_err(codec->dev, "failed to add controls\n"); 531 dev_err(codec->dev, "failed to add controls\n");
621 goto error_free_pcms; 532 return ret;
622 } 533 }
623 534
624 /* get the power supply regulators */ 535 /* get the power supply regulators */
@@ -628,7 +539,7 @@ static int cs4270_probe(struct platform_device *pdev)
628 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies), 539 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
629 cs4270->supplies); 540 cs4270->supplies);
630 if (ret < 0) 541 if (ret < 0)
631 goto error_free_pcms; 542 return ret;
632 543
633 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), 544 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
634 cs4270->supplies); 545 cs4270->supplies);
@@ -641,9 +552,6 @@ error_free_regulators:
641 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), 552 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
642 cs4270->supplies); 553 cs4270->supplies);
643 554
644error_free_pcms:
645 snd_soc_free_pcms(socdev);
646
647 return ret; 555 return ret;
648} 556}
649 557
@@ -653,19 +561,98 @@ error_free_pcms:
653 * 561 *
654 * This function is the counterpart to cs4270_probe(). 562 * This function is the counterpart to cs4270_probe().
655 */ 563 */
656static int cs4270_remove(struct platform_device *pdev) 564static int cs4270_remove(struct snd_soc_codec *codec)
657{ 565{
658 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
659 struct snd_soc_codec *codec = cs4270_codec;
660 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 566 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
661 567
662 snd_soc_free_pcms(socdev);
663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); 568 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
664 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); 569 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
665 570
666 return 0; 571 return 0;
667}; 572};
668 573
574#ifdef CONFIG_PM
575
576/* This suspend/resume implementation can handle both - a simple standby
577 * where the codec remains powered, and a full suspend, where the voltage
578 * domain the codec is connected to is teared down and/or any other hardware
579 * reset condition is asserted.
580 *
581 * The codec's own power saving features are enabled in the suspend callback,
582 * and all registers are written back to the hardware when resuming.
583 */
584
585static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
586{
587 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
588 int reg, ret;
589
590 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
591 if (reg < 0)
592 return reg;
593
594 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
595 if (ret < 0)
596 return ret;
597
598 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
599 cs4270->supplies);
600
601 return 0;
602}
603
604static int cs4270_soc_resume(struct snd_soc_codec *codec)
605{
606 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
607 struct i2c_client *i2c_client = codec->control_data;
608 int reg;
609
610 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
611 cs4270->supplies);
612
613 /* In case the device was put to hard reset during sleep, we need to
614 * wait 500ns here before any I2C communication. */
615 ndelay(500);
616
617 /* first restore the entire register cache ... */
618 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
619 u8 val = snd_soc_read(codec, reg);
620
621 if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
622 dev_err(codec->dev, "i2c write failed\n");
623 return -EIO;
624 }
625 }
626
627 /* ... then disable the power-down bits */
628 reg = snd_soc_read(codec, CS4270_PWRCTL);
629 reg &= ~CS4270_PWRCTL_PDN_ALL;
630
631 return snd_soc_write(codec, CS4270_PWRCTL, reg);
632}
633#else
634#define cs4270_soc_suspend NULL
635#define cs4270_soc_resume NULL
636#endif /* CONFIG_PM */
637
638/*
639 * ASoC codec device structure
640 *
641 * Assign this variable to the codec_dev field of the machine driver's
642 * snd_soc_device structure.
643 */
644static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
645 .probe = cs4270_probe,
646 .remove = cs4270_remove,
647 .suspend = cs4270_soc_suspend,
648 .resume = cs4270_soc_resume,
649 .volatile_register = cs4270_reg_is_volatile,
650 .readable_register = cs4270_reg_is_readable,
651 .reg_cache_size = CS4270_LASTREG + 1,
652 .reg_word_size = sizeof(u8),
653 .reg_cache_default = cs4270_default_reg_cache,
654};
655
669/** 656/**
670 * cs4270_i2c_probe - initialize the I2C interface of the CS4270 657 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
671 * @i2c_client: the I2C client object 658 * @i2c_client: the I2C client object
@@ -677,22 +664,9 @@ static int cs4270_remove(struct platform_device *pdev)
677static int cs4270_i2c_probe(struct i2c_client *i2c_client, 664static int cs4270_i2c_probe(struct i2c_client *i2c_client,
678 const struct i2c_device_id *id) 665 const struct i2c_device_id *id)
679{ 666{
680 struct snd_soc_codec *codec;
681 struct cs4270_private *cs4270; 667 struct cs4270_private *cs4270;
682 unsigned int reg;
683 int ret; 668 int ret;
684 669
685 /* For now, we only support one cs4270 device in the system. See the
686 * comment for cs4270_codec.
687 */
688 if (cs4270_codec) {
689 dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
690 i2c_client->addr);
691 dev_err(&i2c_client->dev, "only one per board allowed\n");
692 /* Should we return something other than ENODEV here? */
693 return -ENODEV;
694 }
695
696 /* Verify that we have a CS4270 */ 670 /* Verify that we have a CS4270 */
697 671
698 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 672 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -712,94 +686,20 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
712 i2c_client->addr); 686 i2c_client->addr);
713 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); 687 dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
714 688
715 /* Allocate enough space for the snd_soc_codec structure
716 and our private data together. */
717 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL); 689 cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
718 if (!cs4270) { 690 if (!cs4270) {
719 dev_err(&i2c_client->dev, "could not allocate codec\n"); 691 dev_err(&i2c_client->dev, "could not allocate codec\n");
720 return -ENOMEM; 692 return -ENOMEM;
721 } 693 }
722 codec = &cs4270->codec;
723
724 mutex_init(&codec->mutex);
725 INIT_LIST_HEAD(&codec->dapm_widgets);
726 INIT_LIST_HEAD(&codec->dapm_paths);
727
728 codec->dev = &i2c_client->dev;
729 codec->name = "CS4270";
730 codec->owner = THIS_MODULE;
731 codec->dai = &cs4270_dai;
732 codec->num_dai = 1;
733 snd_soc_codec_set_drvdata(codec, cs4270);
734 codec->control_data = i2c_client;
735 codec->read = cs4270_read_reg_cache;
736 codec->write = cs4270_i2c_write;
737 codec->reg_cache = cs4270->reg_cache;
738 codec->reg_cache_size = CS4270_NUMREGS;
739
740 /* The I2C interface is set up, so pre-fill our register cache */
741
742 ret = cs4270_fill_cache(codec);
743 if (ret < 0) {
744 dev_err(&i2c_client->dev, "failed to fill register cache\n");
745 goto error_free_codec;
746 }
747
748 /* Disable auto-mute. This feature appears to be buggy. In some
749 * situations, auto-mute will not deactivate when it should, so we want
750 * this feature disabled by default. An application (e.g. alsactl) can
751 * re-enabled it by using the controls.
752 */
753
754 reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
755 reg &= ~CS4270_MUTE_AUTO;
756 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
757 if (ret < 0) {
758 dev_err(&i2c_client->dev, "i2c write failed\n");
759 return ret;
760 }
761
762 /* Disable automatic volume control. The hardware enables, and it
763 * causes volume change commands to be delayed, sometimes until after
764 * playback has started. An application (e.g. alsactl) can
765 * re-enabled it by using the controls.
766 */
767
768 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
769 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
770 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
771 if (ret < 0) {
772 dev_err(&i2c_client->dev, "i2c write failed\n");
773 return ret;
774 }
775
776 /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
777 * structure for each CS4270 device, but the machine driver needs to
778 * have a pointer to the DAI structure, so for now it must be a global
779 * variable.
780 */
781 cs4270_dai.dev = &i2c_client->dev;
782
783 /* Register the DAI. If all the other ASoC driver have already
784 * registered, then this will call our probe function, so
785 * cs4270_codec needs to be ready.
786 */
787 cs4270_codec = codec;
788 ret = snd_soc_register_dai(&cs4270_dai);
789 if (ret < 0) {
790 dev_err(&i2c_client->dev, "failed to register DAIe\n");
791 goto error_free_codec;
792 }
793 694
794 i2c_set_clientdata(i2c_client, cs4270); 695 i2c_set_clientdata(i2c_client, cs4270);
696 cs4270->control_data = i2c_client;
697 cs4270->control_type = SND_SOC_I2C;
795 698
796 return 0; 699 ret = snd_soc_register_codec(&i2c_client->dev,
797 700 &soc_codec_device_cs4270, &cs4270_dai, 1);
798error_free_codec: 701 if (ret < 0)
799 kfree(cs4270); 702 kfree(cs4270);
800 cs4270_codec = NULL;
801 cs4270_dai.dev = NULL;
802
803 return ret; 703 return ret;
804} 704}
805 705
@@ -811,90 +711,20 @@ error_free_codec:
811 */ 711 */
812static int cs4270_i2c_remove(struct i2c_client *i2c_client) 712static int cs4270_i2c_remove(struct i2c_client *i2c_client)
813{ 713{
814 struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client); 714 snd_soc_unregister_codec(&i2c_client->dev);
815 715 kfree(i2c_get_clientdata(i2c_client));
816 kfree(cs4270);
817 cs4270_codec = NULL;
818 cs4270_dai.dev = NULL;
819
820 return 0; 716 return 0;
821} 717}
822 718
823/* 719/*
824 * cs4270_id - I2C device IDs supported by this driver 720 * cs4270_id - I2C device IDs supported by this driver
825 */ 721 */
826static struct i2c_device_id cs4270_id[] = { 722static const struct i2c_device_id cs4270_id[] = {
827 {"cs4270", 0}, 723 {"cs4270", 0},
828 {} 724 {}
829}; 725};
830MODULE_DEVICE_TABLE(i2c, cs4270_id); 726MODULE_DEVICE_TABLE(i2c, cs4270_id);
831 727
832#ifdef CONFIG_PM
833
834/* This suspend/resume implementation can handle both - a simple standby
835 * where the codec remains powered, and a full suspend, where the voltage
836 * domain the codec is connected to is teared down and/or any other hardware
837 * reset condition is asserted.
838 *
839 * The codec's own power saving features are enabled in the suspend callback,
840 * and all registers are written back to the hardware when resuming.
841 */
842
843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
844{
845 struct snd_soc_codec *codec = cs4270_codec;
846 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
847 int reg, ret;
848
849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
850 if (reg < 0)
851 return reg;
852
853 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
854 if (ret < 0)
855 return ret;
856
857 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
858 cs4270->supplies);
859
860 return 0;
861}
862
863static int cs4270_soc_resume(struct platform_device *pdev)
864{
865 struct snd_soc_codec *codec = cs4270_codec;
866 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
867 struct i2c_client *i2c_client = codec->control_data;
868 int reg;
869
870 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
871 cs4270->supplies);
872
873 /* In case the device was put to hard reset during sleep, we need to
874 * wait 500ns here before any I2C communication. */
875 ndelay(500);
876
877 /* first restore the entire register cache ... */
878 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
879 u8 val = snd_soc_read(codec, reg);
880
881 if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
882 dev_err(codec->dev, "i2c write failed\n");
883 return -EIO;
884 }
885 }
886
887 /* ... then disable the power-down bits */
888 reg = snd_soc_read(codec, CS4270_PWRCTL);
889 reg &= ~CS4270_PWRCTL_PDN_ALL;
890
891 return snd_soc_write(codec, CS4270_PWRCTL, reg);
892}
893#else
894#define cs4270_soc_suspend NULL
895#define cs4270_soc_resume NULL
896#endif /* CONFIG_PM */
897
898/* 728/*
899 * cs4270_i2c_driver - I2C device identification 729 * cs4270_i2c_driver - I2C device identification
900 * 730 *
@@ -903,7 +733,7 @@ static int cs4270_soc_resume(struct platform_device *pdev)
903 */ 733 */
904static struct i2c_driver cs4270_i2c_driver = { 734static struct i2c_driver cs4270_i2c_driver = {
905 .driver = { 735 .driver = {
906 .name = "cs4270", 736 .name = "cs4270-codec",
907 .owner = THIS_MODULE, 737 .owner = THIS_MODULE,
908 }, 738 },
909 .id_table = cs4270_id, 739 .id_table = cs4270_id,
@@ -911,24 +741,8 @@ static struct i2c_driver cs4270_i2c_driver = {
911 .remove = cs4270_i2c_remove, 741 .remove = cs4270_i2c_remove,
912}; 742};
913 743
914/*
915 * ASoC codec device structure
916 *
917 * Assign this variable to the codec_dev field of the machine driver's
918 * snd_soc_device structure.
919 */
920struct snd_soc_codec_device soc_codec_device_cs4270 = {
921 .probe = cs4270_probe,
922 .remove = cs4270_remove,
923 .suspend = cs4270_soc_suspend,
924 .resume = cs4270_soc_resume,
925};
926EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
927
928static int __init cs4270_init(void) 744static int __init cs4270_init(void)
929{ 745{
930 pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
931
932 return i2c_add_driver(&cs4270_i2c_driver); 746 return i2c_add_driver(&cs4270_i2c_driver);
933} 747}
934module_init(cs4270_init); 748module_init(cs4270_init);
diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h
deleted file mode 100644
index adc6cd9667d4..000000000000
--- a/sound/soc/codecs/cs4270.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Cirrus Logic CS4270 ALSA SoC Codec Driver
3 *
4 * Author: Timur Tabi <timur@freescale.com>
5 *
6 * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#ifndef _CS4270_H
13#define _CS4270_H
14
15/*
16 * The ASoC codec DAI structure for the CS4270. Assign this structure to
17 * the .codec_dai field of your machine driver's snd_soc_dai_link structure.
18 */
19extern struct snd_soc_dai cs4270_dai;
20
21/*
22 * The ASoC codec device structure for the CS4270. Assign this structure
23 * to the .codec_dev field of your machine driver's snd_soc_device
24 * structure.
25 */
26extern struct snd_soc_codec_device soc_codec_device_cs4270;
27
28#endif
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
new file mode 100644
index 000000000000..083aab96ca80
--- /dev/null
+++ b/sound/soc/codecs/cs4271.c
@@ -0,0 +1,667 @@
1/*
2 * CS4271 ASoC codec driver
3 *
4 * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * This driver support CS4271 codec being master or slave, working
17 * in control port mode, connected either via SPI or I2C.
18 * The data format accepted is I2S or left-justified.
19 * DAPM support not implemented.
20 */
21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/delay.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/tlv.h>
28#include <linux/gpio.h>
29#include <linux/i2c.h>
30#include <linux/spi/spi.h>
31#include <sound/cs4271.h>
32
33#define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S24_LE | \
35 SNDRV_PCM_FMTBIT_S32_LE)
36#define CS4271_PCM_RATES SNDRV_PCM_RATE_8000_192000
37
38/*
39 * CS4271 registers
40 * High byte represents SPI chip address (0x10) + write command (0)
41 * Low byte - codec register address
42 */
43#define CS4271_MODE1 0x2001 /* Mode Control 1 */
44#define CS4271_DACCTL 0x2002 /* DAC Control */
45#define CS4271_DACVOL 0x2003 /* DAC Volume & Mixing Control */
46#define CS4271_VOLA 0x2004 /* DAC Channel A Volume Control */
47#define CS4271_VOLB 0x2005 /* DAC Channel B Volume Control */
48#define CS4271_ADCCTL 0x2006 /* ADC Control */
49#define CS4271_MODE2 0x2007 /* Mode Control 2 */
50#define CS4271_CHIPID 0x2008 /* Chip ID */
51
52#define CS4271_FIRSTREG CS4271_MODE1
53#define CS4271_LASTREG CS4271_MODE2
54#define CS4271_NR_REGS ((CS4271_LASTREG & 0xFF) + 1)
55
56/* Bit masks for the CS4271 registers */
57#define CS4271_MODE1_MODE_MASK 0xC0
58#define CS4271_MODE1_MODE_1X 0x00
59#define CS4271_MODE1_MODE_2X 0x80
60#define CS4271_MODE1_MODE_4X 0xC0
61
62#define CS4271_MODE1_DIV_MASK 0x30
63#define CS4271_MODE1_DIV_1 0x00
64#define CS4271_MODE1_DIV_15 0x10
65#define CS4271_MODE1_DIV_2 0x20
66#define CS4271_MODE1_DIV_3 0x30
67
68#define CS4271_MODE1_MASTER 0x08
69
70#define CS4271_MODE1_DAC_DIF_MASK 0x07
71#define CS4271_MODE1_DAC_DIF_LJ 0x00
72#define CS4271_MODE1_DAC_DIF_I2S 0x01
73#define CS4271_MODE1_DAC_DIF_RJ16 0x02
74#define CS4271_MODE1_DAC_DIF_RJ24 0x03
75#define CS4271_MODE1_DAC_DIF_RJ20 0x04
76#define CS4271_MODE1_DAC_DIF_RJ18 0x05
77
78#define CS4271_DACCTL_AMUTE 0x80
79#define CS4271_DACCTL_IF_SLOW 0x40
80
81#define CS4271_DACCTL_DEM_MASK 0x30
82#define CS4271_DACCTL_DEM_DIS 0x00
83#define CS4271_DACCTL_DEM_441 0x10
84#define CS4271_DACCTL_DEM_48 0x20
85#define CS4271_DACCTL_DEM_32 0x30
86
87#define CS4271_DACCTL_SVRU 0x08
88#define CS4271_DACCTL_SRD 0x04
89#define CS4271_DACCTL_INVA 0x02
90#define CS4271_DACCTL_INVB 0x01
91
92#define CS4271_DACVOL_BEQUA 0x40
93#define CS4271_DACVOL_SOFT 0x20
94#define CS4271_DACVOL_ZEROC 0x10
95
96#define CS4271_DACVOL_ATAPI_MASK 0x0F
97#define CS4271_DACVOL_ATAPI_M_M 0x00
98#define CS4271_DACVOL_ATAPI_M_BR 0x01
99#define CS4271_DACVOL_ATAPI_M_BL 0x02
100#define CS4271_DACVOL_ATAPI_M_BLR2 0x03
101#define CS4271_DACVOL_ATAPI_AR_M 0x04
102#define CS4271_DACVOL_ATAPI_AR_BR 0x05
103#define CS4271_DACVOL_ATAPI_AR_BL 0x06
104#define CS4271_DACVOL_ATAPI_AR_BLR2 0x07
105#define CS4271_DACVOL_ATAPI_AL_M 0x08
106#define CS4271_DACVOL_ATAPI_AL_BR 0x09
107#define CS4271_DACVOL_ATAPI_AL_BL 0x0A
108#define CS4271_DACVOL_ATAPI_AL_BLR2 0x0B
109#define CS4271_DACVOL_ATAPI_ALR2_M 0x0C
110#define CS4271_DACVOL_ATAPI_ALR2_BR 0x0D
111#define CS4271_DACVOL_ATAPI_ALR2_BL 0x0E
112#define CS4271_DACVOL_ATAPI_ALR2_BLR2 0x0F
113
114#define CS4271_VOLA_MUTE 0x80
115#define CS4271_VOLA_VOL_MASK 0x7F
116#define CS4271_VOLB_MUTE 0x80
117#define CS4271_VOLB_VOL_MASK 0x7F
118
119#define CS4271_ADCCTL_DITHER16 0x20
120
121#define CS4271_ADCCTL_ADC_DIF_MASK 0x10
122#define CS4271_ADCCTL_ADC_DIF_LJ 0x00
123#define CS4271_ADCCTL_ADC_DIF_I2S 0x10
124
125#define CS4271_ADCCTL_MUTEA 0x08
126#define CS4271_ADCCTL_MUTEB 0x04
127#define CS4271_ADCCTL_HPFDA 0x02
128#define CS4271_ADCCTL_HPFDB 0x01
129
130#define CS4271_MODE2_LOOP 0x10
131#define CS4271_MODE2_MUTECAEQUB 0x08
132#define CS4271_MODE2_FREEZE 0x04
133#define CS4271_MODE2_CPEN 0x02
134#define CS4271_MODE2_PDN 0x01
135
136#define CS4271_CHIPID_PART_MASK 0xF0
137#define CS4271_CHIPID_REV_MASK 0x0F
138
139/*
140 * Default CS4271 power-up configuration
141 * Array contains non-existing in hw register at address 0
142 * Array do not include Chip ID, as codec driver does not use
143 * registers read operations at all
144 */
145static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = {
146 0,
147 0,
148 CS4271_DACCTL_AMUTE,
149 CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR,
150 0,
151 0,
152 0,
153 0,
154};
155
156struct cs4271_private {
157 /* SND_SOC_I2C or SND_SOC_SPI */
158 enum snd_soc_control_type bus_type;
159 void *control_data;
160 unsigned int mclk;
161 bool master;
162 bool deemph;
163 /* Current sample rate for de-emphasis control */
164 int rate;
165 /* GPIO driving Reset pin, if any */
166 int gpio_nreset;
167 /* GPIO that disable serial bus, if any */
168 int gpio_disable;
169};
170
171/*
172 * @freq is the desired MCLK rate
173 * MCLK rate should (c) be the sample rate, multiplied by one of the
174 * ratios listed in cs4271_mclk_fs_ratios table
175 */
176static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
177 int clk_id, unsigned int freq, int dir)
178{
179 struct snd_soc_codec *codec = codec_dai->codec;
180 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
181
182 cs4271->mclk = freq;
183 return 0;
184}
185
186static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 unsigned int format)
188{
189 struct snd_soc_codec *codec = codec_dai->codec;
190 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
191 unsigned int val = 0;
192 int ret;
193
194 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
195 case SND_SOC_DAIFMT_CBS_CFS:
196 cs4271->master = 0;
197 break;
198 case SND_SOC_DAIFMT_CBM_CFM:
199 cs4271->master = 1;
200 val |= CS4271_MODE1_MASTER;
201 break;
202 default:
203 dev_err(codec->dev, "Invalid DAI format\n");
204 return -EINVAL;
205 }
206
207 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
208 case SND_SOC_DAIFMT_LEFT_J:
209 val |= CS4271_MODE1_DAC_DIF_LJ;
210 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
211 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
212 if (ret < 0)
213 return ret;
214 break;
215 case SND_SOC_DAIFMT_I2S:
216 val |= CS4271_MODE1_DAC_DIF_I2S;
217 ret = snd_soc_update_bits(codec, CS4271_ADCCTL,
218 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
219 if (ret < 0)
220 return ret;
221 break;
222 default:
223 dev_err(codec->dev, "Invalid DAI format\n");
224 return -EINVAL;
225 }
226
227 ret = snd_soc_update_bits(codec, CS4271_MODE1,
228 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
229 if (ret < 0)
230 return ret;
231 return 0;
232}
233
234static int cs4271_deemph[] = {0, 44100, 48000, 32000};
235
236static int cs4271_set_deemph(struct snd_soc_codec *codec)
237{
238 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
239 int i, ret;
240 int val = CS4271_DACCTL_DEM_DIS;
241
242 if (cs4271->deemph) {
243 /* Find closest de-emphasis freq */
244 val = 1;
245 for (i = 2; i < ARRAY_SIZE(cs4271_deemph); i++)
246 if (abs(cs4271_deemph[i] - cs4271->rate) <
247 abs(cs4271_deemph[val] - cs4271->rate))
248 val = i;
249 val <<= 4;
250 }
251
252 ret = snd_soc_update_bits(codec, CS4271_DACCTL,
253 CS4271_DACCTL_DEM_MASK, val);
254 if (ret < 0)
255 return ret;
256 return 0;
257}
258
259static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
260 struct snd_ctl_elem_value *ucontrol)
261{
262 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
263 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
264
265 ucontrol->value.enumerated.item[0] = cs4271->deemph;
266 return 0;
267}
268
269static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
270 struct snd_ctl_elem_value *ucontrol)
271{
272 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
273 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
274
275 cs4271->deemph = ucontrol->value.enumerated.item[0];
276 return cs4271_set_deemph(codec);
277}
278
279struct cs4271_clk_cfg {
280 bool master; /* codec mode */
281 u8 speed_mode; /* codec speed mode: 1x, 2x, 4x */
282 unsigned short ratio; /* MCLK / sample rate */
283 u8 ratio_mask; /* ratio bit mask for Master mode */
284};
285
286static struct cs4271_clk_cfg cs4271_clk_tab[] = {
287 {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
288 {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15},
289 {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2},
290 {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3},
291 {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
292 {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15},
293 {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2},
294 {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3},
295 {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
296 {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15},
297 {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2},
298 {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3},
299 {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
300 {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1},
301 {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1},
302 {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2},
303 {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2},
304 {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
305 {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1},
306 {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1},
307 {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2},
308 {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2},
309 {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
310 {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1},
311 {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1},
312 {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2},
313 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
314};
315
316#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
317
318static int cs4271_hw_params(struct snd_pcm_substream *substream,
319 struct snd_pcm_hw_params *params,
320 struct snd_soc_dai *dai)
321{
322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_codec *codec = rtd->codec;
324 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
325 int i, ret;
326 unsigned int ratio, val;
327
328 cs4271->rate = params_rate(params);
329
330 /* Configure DAC */
331 if (cs4271->rate < 50000)
332 val = CS4271_MODE1_MODE_1X;
333 else if (cs4271->rate < 100000)
334 val = CS4271_MODE1_MODE_2X;
335 else
336 val = CS4271_MODE1_MODE_4X;
337
338 ratio = cs4271->mclk / cs4271->rate;
339 for (i = 0; i < CS4171_NR_RATIOS; i++)
340 if ((cs4271_clk_tab[i].master == cs4271->master) &&
341 (cs4271_clk_tab[i].speed_mode == val) &&
342 (cs4271_clk_tab[i].ratio == ratio))
343 break;
344
345 if (i == CS4171_NR_RATIOS) {
346 dev_err(codec->dev, "Invalid sample rate\n");
347 return -EINVAL;
348 }
349
350 val |= cs4271_clk_tab[i].ratio_mask;
351
352 ret = snd_soc_update_bits(codec, CS4271_MODE1,
353 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
354 if (ret < 0)
355 return ret;
356
357 return cs4271_set_deemph(codec);
358}
359
360static int cs4271_digital_mute(struct snd_soc_dai *dai, int mute)
361{
362 struct snd_soc_codec *codec = dai->codec;
363 int ret;
364 int val_a = 0;
365 int val_b = 0;
366
367 if (mute) {
368 val_a = CS4271_VOLA_MUTE;
369 val_b = CS4271_VOLB_MUTE;
370 }
371
372 ret = snd_soc_update_bits(codec, CS4271_VOLA, CS4271_VOLA_MUTE, val_a);
373 if (ret < 0)
374 return ret;
375 ret = snd_soc_update_bits(codec, CS4271_VOLB, CS4271_VOLB_MUTE, val_b);
376 if (ret < 0)
377 return ret;
378
379 return 0;
380}
381
382/* CS4271 controls */
383static DECLARE_TLV_DB_SCALE(cs4271_dac_tlv, -12700, 100, 0);
384
385static const struct snd_kcontrol_new cs4271_snd_controls[] = {
386 SOC_DOUBLE_R_TLV("Master Playback Volume", CS4271_VOLA, CS4271_VOLB,
387 0, 0x7F, 1, cs4271_dac_tlv),
388 SOC_SINGLE("Digital Loopback Switch", CS4271_MODE2, 4, 1, 0),
389 SOC_SINGLE("Soft Ramp Switch", CS4271_DACVOL, 5, 1, 0),
390 SOC_SINGLE("Zero Cross Switch", CS4271_DACVOL, 4, 1, 0),
391 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
392 cs4271_get_deemph, cs4271_put_deemph),
393 SOC_SINGLE("Auto-Mute Switch", CS4271_DACCTL, 7, 1, 0),
394 SOC_SINGLE("Slow Roll Off Filter Switch", CS4271_DACCTL, 6, 1, 0),
395 SOC_SINGLE("Soft Volume Ramp-Up Switch", CS4271_DACCTL, 3, 1, 0),
396 SOC_SINGLE("Soft Ramp-Down Switch", CS4271_DACCTL, 2, 1, 0),
397 SOC_SINGLE("Left Channel Inversion Switch", CS4271_DACCTL, 1, 1, 0),
398 SOC_SINGLE("Right Channel Inversion Switch", CS4271_DACCTL, 0, 1, 0),
399 SOC_DOUBLE("Master Capture Switch", CS4271_ADCCTL, 3, 2, 1, 1),
400 SOC_SINGLE("Dither 16-Bit Data Switch", CS4271_ADCCTL, 5, 1, 0),
401 SOC_DOUBLE("High Pass Filter Switch", CS4271_ADCCTL, 1, 0, 1, 1),
402 SOC_DOUBLE_R("Master Playback Switch", CS4271_VOLA, CS4271_VOLB,
403 7, 1, 1),
404};
405
406static struct snd_soc_dai_ops cs4271_dai_ops = {
407 .hw_params = cs4271_hw_params,
408 .set_sysclk = cs4271_set_dai_sysclk,
409 .set_fmt = cs4271_set_dai_fmt,
410 .digital_mute = cs4271_digital_mute,
411};
412
413static struct snd_soc_dai_driver cs4271_dai = {
414 .name = "cs4271-hifi",
415 .playback = {
416 .stream_name = "Playback",
417 .channels_min = 2,
418 .channels_max = 2,
419 .rates = CS4271_PCM_RATES,
420 .formats = CS4271_PCM_FORMATS,
421 },
422 .capture = {
423 .stream_name = "Capture",
424 .channels_min = 2,
425 .channels_max = 2,
426 .rates = CS4271_PCM_RATES,
427 .formats = CS4271_PCM_FORMATS,
428 },
429 .ops = &cs4271_dai_ops,
430 .symmetric_rates = 1,
431};
432
433#ifdef CONFIG_PM
434static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
435{
436 int ret;
437 /* Set power-down bit */
438 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN);
439 if (ret < 0)
440 return ret;
441 return 0;
442}
443
444static int cs4271_soc_resume(struct snd_soc_codec *codec)
445{
446 int ret;
447 /* Restore codec state */
448 ret = snd_soc_cache_sync(codec);
449 if (ret < 0)
450 return ret;
451 /* then disable the power-down bit */
452 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
453 if (ret < 0)
454 return ret;
455 return 0;
456}
457#else
458#define cs4271_soc_suspend NULL
459#define cs4271_soc_resume NULL
460#endif /* CONFIG_PM */
461
462static int cs4271_probe(struct snd_soc_codec *codec)
463{
464 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
465 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
466 int ret;
467 int gpio_nreset = -EINVAL;
468
469 codec->control_data = cs4271->control_data;
470
471 if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
472 gpio_nreset = cs4271plat->gpio_nreset;
473
474 if (gpio_nreset >= 0)
475 if (gpio_request(gpio_nreset, "CS4271 Reset"))
476 gpio_nreset = -EINVAL;
477 if (gpio_nreset >= 0) {
478 /* Reset codec */
479 gpio_direction_output(gpio_nreset, 0);
480 udelay(1);
481 gpio_set_value(gpio_nreset, 1);
482 /* Give the codec time to wake up */
483 udelay(1);
484 }
485
486 cs4271->gpio_nreset = gpio_nreset;
487
488 /*
489 * In case of I2C, chip address specified in board data.
490 * So cache IO operations use 8 bit codec register address.
491 * In case of SPI, chip address and register address
492 * passed together as 16 bit value.
493 * Anyway, register address is masked with 0xFF inside
494 * soc-cache code.
495 */
496 if (cs4271->bus_type == SND_SOC_SPI)
497 ret = snd_soc_codec_set_cache_io(codec, 16, 8,
498 cs4271->bus_type);
499 else
500 ret = snd_soc_codec_set_cache_io(codec, 8, 8,
501 cs4271->bus_type);
502 if (ret) {
503 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
504 return ret;
505 }
506
507 ret = snd_soc_update_bits(codec, CS4271_MODE2, 0,
508 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
509 if (ret < 0)
510 return ret;
511 ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0);
512 if (ret < 0)
513 return ret;
514 /* Power-up sequence requires 85 uS */
515 udelay(85);
516
517 return snd_soc_add_controls(codec, cs4271_snd_controls,
518 ARRAY_SIZE(cs4271_snd_controls));
519}
520
521static int cs4271_remove(struct snd_soc_codec *codec)
522{
523 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
524 int gpio_nreset;
525
526 gpio_nreset = cs4271->gpio_nreset;
527
528 if (gpio_is_valid(gpio_nreset)) {
529 /* Set codec to the reset state */
530 gpio_set_value(gpio_nreset, 0);
531 gpio_free(gpio_nreset);
532 }
533
534 return 0;
535};
536
537static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
538 .probe = cs4271_probe,
539 .remove = cs4271_remove,
540 .suspend = cs4271_soc_suspend,
541 .resume = cs4271_soc_resume,
542 .reg_cache_default = cs4271_dflt_reg,
543 .reg_cache_size = ARRAY_SIZE(cs4271_dflt_reg),
544 .reg_word_size = sizeof(cs4271_dflt_reg[0]),
545 .compress_type = SND_SOC_FLAT_COMPRESSION,
546};
547
548#if defined(CONFIG_SPI_MASTER)
549static int __devinit cs4271_spi_probe(struct spi_device *spi)
550{
551 struct cs4271_private *cs4271;
552
553 cs4271 = devm_kzalloc(&spi->dev, sizeof(*cs4271), GFP_KERNEL);
554 if (!cs4271)
555 return -ENOMEM;
556
557 spi_set_drvdata(spi, cs4271);
558 cs4271->control_data = spi;
559 cs4271->bus_type = SND_SOC_SPI;
560
561 return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271,
562 &cs4271_dai, 1);
563}
564
565static int __devexit cs4271_spi_remove(struct spi_device *spi)
566{
567 snd_soc_unregister_codec(&spi->dev);
568 return 0;
569}
570
571static struct spi_driver cs4271_spi_driver = {
572 .driver = {
573 .name = "cs4271",
574 .owner = THIS_MODULE,
575 },
576 .probe = cs4271_spi_probe,
577 .remove = __devexit_p(cs4271_spi_remove),
578};
579#endif /* defined(CONFIG_SPI_MASTER) */
580
581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
582static const struct i2c_device_id cs4271_i2c_id[] = {
583 {"cs4271", 0},
584 {}
585};
586MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
587
588static int __devinit cs4271_i2c_probe(struct i2c_client *client,
589 const struct i2c_device_id *id)
590{
591 struct cs4271_private *cs4271;
592
593 cs4271 = devm_kzalloc(&client->dev, sizeof(*cs4271), GFP_KERNEL);
594 if (!cs4271)
595 return -ENOMEM;
596
597 i2c_set_clientdata(client, cs4271);
598 cs4271->control_data = client;
599 cs4271->bus_type = SND_SOC_I2C;
600
601 return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271,
602 &cs4271_dai, 1);
603}
604
605static int __devexit cs4271_i2c_remove(struct i2c_client *client)
606{
607 snd_soc_unregister_codec(&client->dev);
608 return 0;
609}
610
611static struct i2c_driver cs4271_i2c_driver = {
612 .driver = {
613 .name = "cs4271",
614 .owner = THIS_MODULE,
615 },
616 .id_table = cs4271_i2c_id,
617 .probe = cs4271_i2c_probe,
618 .remove = __devexit_p(cs4271_i2c_remove),
619};
620#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
621
622/*
623 * We only register our serial bus driver here without
624 * assignment to particular chip. So if any of the below
625 * fails, there is some problem with I2C or SPI subsystem.
626 * In most cases this module will be compiled with support
627 * of only one serial bus.
628 */
629static int __init cs4271_modinit(void)
630{
631 int ret;
632
633#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
634 ret = i2c_add_driver(&cs4271_i2c_driver);
635 if (ret) {
636 pr_err("Failed to register CS4271 I2C driver: %d\n", ret);
637 return ret;
638 }
639#endif
640
641#if defined(CONFIG_SPI_MASTER)
642 ret = spi_register_driver(&cs4271_spi_driver);
643 if (ret) {
644 pr_err("Failed to register CS4271 SPI driver: %d\n", ret);
645 return ret;
646 }
647#endif
648
649 return 0;
650}
651module_init(cs4271_modinit);
652
653static void __exit cs4271_modexit(void)
654{
655#if defined(CONFIG_SPI_MASTER)
656 spi_unregister_driver(&cs4271_spi_driver);
657#endif
658
659#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
660 i2c_del_driver(&cs4271_i2c_driver);
661#endif
662}
663module_exit(cs4271_modexit);
664
665MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
666MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
667MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index dd9b8550c402..8fb7070108dd 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <sound/core.h> 27#include <sound/core.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h> 29#include <sound/tlv.h>
31#include <sound/initval.h> 30#include <sound/initval.h>
32#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -42,15 +41,13 @@ enum master_slave_mode {
42}; 41};
43 42
44struct cs42l51_private { 43struct cs42l51_private {
44 enum snd_soc_control_type control_type;
45 void *control_data;
45 unsigned int mclk; 46 unsigned int mclk;
46 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 47 unsigned int audio_mode; /* The mode (I2S or left-justified) */
47 enum master_slave_mode func; 48 enum master_slave_mode func;
48 struct snd_soc_codec codec;
49 u8 reg_cache[CS42L51_NUMREGS];
50}; 49};
51 50
52static struct snd_soc_codec *cs42l51_codec;
53
54#define CS42L51_FORMATS ( \ 51#define CS42L51_FORMATS ( \
55 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ 52 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
56 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ 53 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
@@ -75,134 +72,6 @@ static int cs42l51_fill_cache(struct snd_soc_codec *codec)
75 return 0; 72 return 0;
76} 73}
77 74
78static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
79 const struct i2c_device_id *id)
80{
81 struct snd_soc_codec *codec;
82 struct cs42l51_private *cs42l51;
83 int ret = 0;
84 int reg;
85
86 if (cs42l51_codec)
87 return -EBUSY;
88
89 /* Verify that we have a CS42L51 */
90 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
91 if (ret < 0) {
92 dev_err(&i2c_client->dev, "failed to read I2C\n");
93 goto error;
94 }
95
96 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
97 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
98 dev_err(&i2c_client->dev, "Invalid chip id\n");
99 ret = -ENODEV;
100 goto error;
101 }
102
103 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
104 ret & 7);
105
106 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
107 if (!cs42l51) {
108 dev_err(&i2c_client->dev, "could not allocate codec\n");
109 return -ENOMEM;
110 }
111 codec = &cs42l51->codec;
112
113 mutex_init(&codec->mutex);
114 INIT_LIST_HEAD(&codec->dapm_widgets);
115 INIT_LIST_HEAD(&codec->dapm_paths);
116
117 codec->dev = &i2c_client->dev;
118 codec->name = "CS42L51";
119 codec->owner = THIS_MODULE;
120 codec->dai = &cs42l51_dai;
121 codec->num_dai = 1;
122 snd_soc_codec_set_drvdata(codec, cs42l51);
123
124 codec->control_data = i2c_client;
125 codec->reg_cache = cs42l51->reg_cache;
126 codec->reg_cache_size = CS42L51_NUMREGS;
127 i2c_set_clientdata(i2c_client, codec);
128
129 ret = cs42l51_fill_cache(codec);
130 if (ret < 0) {
131 dev_err(&i2c_client->dev, "failed to fill register cache\n");
132 goto error_alloc;
133 }
134
135 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
136 if (ret < 0) {
137 dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
138 goto error_alloc;
139 }
140
141 /*
142 * DAC configuration
143 * - Use signal processor
144 * - auto mute
145 * - vol changes immediate
146 * - no de-emphasize
147 */
148 reg = CS42L51_DAC_CTL_DATA_SEL(1)
149 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
150 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
151 if (ret < 0)
152 goto error_alloc;
153
154 cs42l51_dai.dev = codec->dev;
155 cs42l51_codec = codec;
156
157 ret = snd_soc_register_codec(codec);
158 if (ret != 0) {
159 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
160 goto error_alloc;
161 }
162
163 ret = snd_soc_register_dai(&cs42l51_dai);
164 if (ret < 0) {
165 dev_err(&i2c_client->dev, "failed to register DAIe\n");
166 goto error_reg;
167 }
168
169 return 0;
170
171error_reg:
172 snd_soc_unregister_codec(codec);
173error_alloc:
174 kfree(cs42l51);
175error:
176 return ret;
177}
178
179static int cs42l51_i2c_remove(struct i2c_client *client)
180{
181 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
182 snd_soc_unregister_dai(&cs42l51_dai);
183 snd_soc_unregister_codec(cs42l51_codec);
184 cs42l51_codec = NULL;
185 kfree(cs42l51);
186 return 0;
187}
188
189
190static const struct i2c_device_id cs42l51_id[] = {
191 {"cs42l51", 0},
192 {}
193};
194MODULE_DEVICE_TABLE(i2c, cs42l51_id);
195
196static struct i2c_driver cs42l51_i2c_driver = {
197 .driver = {
198 .name = "CS42L51 I2C",
199 .owner = THIS_MODULE,
200 },
201 .id_table = cs42l51_id,
202 .probe = cs42l51_i2c_probe,
203 .remove = cs42l51_i2c_remove,
204};
205
206static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 75static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 76 struct snd_ctl_elem_value *ucontrol)
208{ 77{
@@ -484,51 +353,8 @@ static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
484{ 353{
485 struct snd_soc_codec *codec = codec_dai->codec; 354 struct snd_soc_codec *codec = codec_dai->codec;
486 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 355 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
487 struct cs42l51_ratios *ratios = NULL;
488 int nr_ratios = 0;
489 unsigned int rates = 0;
490 unsigned int rate_min = -1;
491 unsigned int rate_max = 0;
492 int i;
493 356
494 cs42l51->mclk = freq; 357 cs42l51->mclk = freq;
495
496 switch (cs42l51->func) {
497 case MODE_MASTER:
498 return -EINVAL;
499 case MODE_SLAVE:
500 ratios = slave_ratios;
501 nr_ratios = ARRAY_SIZE(slave_ratios);
502 break;
503 case MODE_SLAVE_AUTO:
504 ratios = slave_auto_ratios;
505 nr_ratios = ARRAY_SIZE(slave_auto_ratios);
506 break;
507 }
508
509 for (i = 0; i < nr_ratios; i++) {
510 unsigned int rate = freq / ratios[i].ratio;
511 rates |= snd_pcm_rate_to_rate_bit(rate);
512 if (rate < rate_min)
513 rate_min = rate;
514 if (rate > rate_max)
515 rate_max = rate;
516 }
517 rates &= ~SNDRV_PCM_RATE_KNOT;
518
519 if (!rates) {
520 dev_err(codec->dev, "could not find a valid sample rate\n");
521 return -EINVAL;
522 }
523
524 codec_dai->playback.rates = rates;
525 codec_dai->playback.rate_min = rate_min;
526 codec_dai->playback.rate_max = rate_max;
527
528 codec_dai->capture.rates = rates;
529 codec_dai->capture.rate_min = rate_min;
530 codec_dai->capture.rate_max = rate_max;
531
532 return 0; 358 return 0;
533} 359}
534 360
@@ -537,8 +363,7 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
537 struct snd_soc_dai *dai) 363 struct snd_soc_dai *dai)
538{ 364{
539 struct snd_soc_pcm_runtime *rtd = substream->private_data; 365 struct snd_soc_pcm_runtime *rtd = substream->private_data;
540 struct snd_soc_device *socdev = rtd->socdev; 366 struct snd_soc_codec *codec = rtd->codec;
541 struct snd_soc_codec *codec = socdev->card->codec;
542 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 367 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
543 int ret; 368 int ret;
544 unsigned int i; 369 unsigned int i;
@@ -670,8 +495,8 @@ static struct snd_soc_dai_ops cs42l51_dai_ops = {
670 .digital_mute = cs42l51_dai_mute, 495 .digital_mute = cs42l51_dai_mute,
671}; 496};
672 497
673struct snd_soc_dai cs42l51_dai = { 498static struct snd_soc_dai_driver cs42l51_dai = {
674 .name = "CS42L51 HiFi", 499 .name = "cs42l51-hifi",
675 .playback = { 500 .playback = {
676 .stream_name = "Playback", 501 .stream_name = "Playback",
677 .channels_min = 1, 502 .channels_min = 1,
@@ -688,56 +513,121 @@ struct snd_soc_dai cs42l51_dai = {
688 }, 513 },
689 .ops = &cs42l51_dai_ops, 514 .ops = &cs42l51_dai_ops,
690}; 515};
691EXPORT_SYMBOL_GPL(cs42l51_dai);
692
693 516
694static int cs42l51_probe(struct platform_device *pdev) 517static int cs42l51_probe(struct snd_soc_codec *codec)
695{ 518{
696 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 519 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
697 struct snd_soc_codec *codec; 520 struct snd_soc_dapm_context *dapm = &codec->dapm;
698 int ret = 0; 521 int ret, reg;
699 522
700 if (!cs42l51_codec) { 523 codec->control_data = cs42l51->control_data;
701 dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
702 return -EINVAL;
703 }
704 524
705 socdev->card->codec = cs42l51_codec; 525 ret = cs42l51_fill_cache(codec);
706 codec = socdev->card->codec; 526 if (ret < 0) {
527 dev_err(codec->dev, "failed to fill register cache\n");
528 return ret;
529 }
707 530
708 /* Register PCMs */ 531 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
709 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
710 if (ret < 0) { 532 if (ret < 0) {
711 dev_err(&pdev->dev, "failed to create PCMs\n"); 533 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
712 return ret; 534 return ret;
713 } 535 }
714 536
537 /*
538 * DAC configuration
539 * - Use signal processor
540 * - auto mute
541 * - vol changes immediate
542 * - no de-emphasize
543 */
544 reg = CS42L51_DAC_CTL_DATA_SEL(1)
545 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
546 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
547 if (ret < 0)
548 return ret;
549
715 snd_soc_add_controls(codec, cs42l51_snd_controls, 550 snd_soc_add_controls(codec, cs42l51_snd_controls,
716 ARRAY_SIZE(cs42l51_snd_controls)); 551 ARRAY_SIZE(cs42l51_snd_controls));
717 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets, 552 snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets,
718 ARRAY_SIZE(cs42l51_dapm_widgets)); 553 ARRAY_SIZE(cs42l51_dapm_widgets));
719 snd_soc_dapm_add_routes(codec, cs42l51_routes, 554 snd_soc_dapm_add_routes(dapm, cs42l51_routes,
720 ARRAY_SIZE(cs42l51_routes)); 555 ARRAY_SIZE(cs42l51_routes));
721 556
722 return 0; 557 return 0;
723} 558}
724 559
560static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
561 .probe = cs42l51_probe,
562 .reg_cache_size = CS42L51_NUMREGS,
563 .reg_word_size = sizeof(u8),
564};
725 565
726static int cs42l51_remove(struct platform_device *pdev) 566static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
567 const struct i2c_device_id *id)
727{ 568{
728 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 569 struct cs42l51_private *cs42l51;
570 int ret;
729 571
730 snd_soc_free_pcms(socdev); 572 /* Verify that we have a CS42L51 */
731 snd_soc_dapm_free(socdev); 573 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
574 if (ret < 0) {
575 dev_err(&i2c_client->dev, "failed to read I2C\n");
576 goto error;
577 }
578
579 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
580 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
581 dev_err(&i2c_client->dev, "Invalid chip id\n");
582 ret = -ENODEV;
583 goto error;
584 }
585
586 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
587 ret & 7);
588
589 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
590 if (!cs42l51) {
591 dev_err(&i2c_client->dev, "could not allocate codec\n");
592 return -ENOMEM;
593 }
594
595 i2c_set_clientdata(i2c_client, cs42l51);
596 cs42l51->control_data = i2c_client;
597 cs42l51->control_type = SND_SOC_I2C;
732 598
599 ret = snd_soc_register_codec(&i2c_client->dev,
600 &soc_codec_device_cs42l51, &cs42l51_dai, 1);
601 if (ret < 0)
602 kfree(cs42l51);
603error:
604 return ret;
605}
606
607static int cs42l51_i2c_remove(struct i2c_client *client)
608{
609 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
610
611 snd_soc_unregister_codec(&client->dev);
612 kfree(cs42l51);
733 return 0; 613 return 0;
734} 614}
735 615
736struct snd_soc_codec_device soc_codec_device_cs42l51 = { 616static const struct i2c_device_id cs42l51_id[] = {
737 .probe = cs42l51_probe, 617 {"cs42l51", 0},
738 .remove = cs42l51_remove 618 {}
619};
620MODULE_DEVICE_TABLE(i2c, cs42l51_id);
621
622static struct i2c_driver cs42l51_i2c_driver = {
623 .driver = {
624 .name = "cs42l51-codec",
625 .owner = THIS_MODULE,
626 },
627 .id_table = cs42l51_id,
628 .probe = cs42l51_i2c_probe,
629 .remove = cs42l51_i2c_remove,
739}; 630};
740EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
741 631
742static int __init cs42l51_init(void) 632static int __init cs42l51_init(void)
743{ 633{
@@ -758,6 +648,6 @@ static void __exit cs42l51_exit(void)
758} 648}
759module_exit(cs42l51_exit); 649module_exit(cs42l51_exit);
760 650
761MODULE_AUTHOR("Arnaud Patard <apatard@mandriva.com>"); 651MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
762MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); 652MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
763MODULE_LICENSE("GPL"); 653MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h
index 8f0bd9786ad2..2beeb171db4b 100644
--- a/sound/soc/codecs/cs42l51.h
+++ b/sound/soc/codecs/cs42l51.h
@@ -158,6 +158,4 @@
158#define CS42L51_LASTREG 0x20 158#define CS42L51_LASTREG 0x20
159#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1) 159#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
160 160
161extern struct snd_soc_dai cs42l51_dai;
162extern struct snd_soc_codec_device soc_codec_device_cs42l51;
163#endif 161#endif
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index f07a415c753f..d68ea532cc7f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -18,14 +18,14 @@
18 18
19#include <sound/core.h> 19#include <sound/core.h>
20#include <sound/initval.h> 20#include <sound/initval.h>
21#include <sound/soc-dapm.h> 21#include <sound/soc.h>
22 22
23#include "cx20442.h" 23#include "cx20442.h"
24 24
25 25
26struct cx20442_priv { 26struct cx20442_priv {
27 struct snd_soc_codec codec; 27 enum snd_soc_control_type control_type;
28 u8 reg_cache[1]; 28 void *control_data;
29}; 29};
30 30
31#define CX20442_PM 0x0 31#define CX20442_PM 0x0
@@ -86,23 +86,12 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
86 {"ADC", NULL, "Input Mixer"}, 86 {"ADC", NULL, "Input Mixer"},
87}; 87};
88 88
89static int cx20442_add_widgets(struct snd_soc_codec *codec)
90{
91 snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets,
92 ARRAY_SIZE(cx20442_dapm_widgets));
93
94 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
95 ARRAY_SIZE(cx20442_audio_map));
96
97 return 0;
98}
99
100static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, 89static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
101 unsigned int reg) 90 unsigned int reg)
102{ 91{
103 u8 *reg_cache = codec->reg_cache; 92 u8 *reg_cache = codec->reg_cache;
104 93
105 if (reg >= codec->reg_cache_size) 94 if (reg >= codec->driver->reg_cache_size)
106 return -EINVAL; 95 return -EINVAL;
107 96
108 return reg_cache[reg]; 97 return reg_cache[reg];
@@ -164,16 +153,17 @@ static int cx20442_pm_to_v253_vsp(u8 value)
164static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, 153static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
165 unsigned int value) 154 unsigned int value)
166{ 155{
156 struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
167 u8 *reg_cache = codec->reg_cache; 157 u8 *reg_cache = codec->reg_cache;
168 int vls, vsp, old, len; 158 int vls, vsp, old, len;
169 char buf[18]; 159 char buf[18];
170 160
171 if (reg >= codec->reg_cache_size) 161 if (reg >= codec->driver->reg_cache_size)
172 return -EINVAL; 162 return -EINVAL;
173 163
174 /* hw_write and control_data pointers required for talking to the modem 164 /* hw_write and control_data pointers required for talking to the modem
175 * are expected to be set by the line discipline initialization code */ 165 * are expected to be set by the line discipline initialization code */
176 if (!codec->hw_write || !codec->control_data) 166 if (!codec->hw_write || !cx20442->control_data)
177 return -EIO; 167 return -EIO;
178 168
179 old = reg_cache[reg]; 169 old = reg_cache[reg];
@@ -202,17 +192,13 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
202 return -ENOMEM; 192 return -ENOMEM;
203 193
204 dev_dbg(codec->dev, "%s: %s\n", __func__, buf); 194 dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
205 if (codec->hw_write(codec->control_data, buf, len) != len) 195 if (codec->hw_write(cx20442->control_data, buf, len) != len)
206 return -EIO; 196 return -EIO;
207 197
208 return 0; 198 return 0;
209} 199}
210 200
211 201
212/* Moved up here as line discipline referres it during initialization */
213static struct snd_soc_codec *cx20442_codec;
214
215
216/* 202/*
217 * Line discpline related code 203 * Line discpline related code
218 * 204 *
@@ -228,15 +214,15 @@ static const char *v253_init = "ate0m0q0+fclass=8\r";
228/* Line discipline .open() */ 214/* Line discipline .open() */
229static int v253_open(struct tty_struct *tty) 215static int v253_open(struct tty_struct *tty)
230{ 216{
231 struct snd_soc_codec *codec = cx20442_codec;
232 int ret, len = strlen(v253_init); 217 int ret, len = strlen(v253_init);
233 218
234 /* Doesn't make sense without write callback */ 219 /* Doesn't make sense without write callback */
235 if (!tty->ops->write) 220 if (!tty->ops->write)
236 return -EINVAL; 221 return -EINVAL;
237 222
238 /* Pass the codec structure address for use by other ldisc callbacks */ 223 /* Won't work if no codec pointer has been passed by a card driver */
239 tty->disc_data = codec; 224 if (!tty->disc_data)
225 return -ENODEV;
240 226
241 if (tty->ops->write(tty, v253_init, len) != len) { 227 if (tty->ops->write(tty, v253_init, len) != len) {
242 ret = -EIO; 228 ret = -EIO;
@@ -253,16 +239,19 @@ err:
253static void v253_close(struct tty_struct *tty) 239static void v253_close(struct tty_struct *tty)
254{ 240{
255 struct snd_soc_codec *codec = tty->disc_data; 241 struct snd_soc_codec *codec = tty->disc_data;
242 struct cx20442_priv *cx20442;
256 243
257 tty->disc_data = NULL; 244 tty->disc_data = NULL;
258 245
259 if (!codec) 246 if (!codec)
260 return; 247 return;
261 248
249 cx20442 = snd_soc_codec_get_drvdata(codec);
250
262 /* Prevent the codec driver from further accessing the modem */ 251 /* Prevent the codec driver from further accessing the modem */
263 codec->hw_write = NULL; 252 codec->hw_write = NULL;
264 codec->control_data = NULL; 253 cx20442->control_data = NULL;
265 codec->pop_time = 0; 254 codec->card->pop_time = 0;
266} 255}
267 256
268/* Line discipline .hangup() */ 257/* Line discipline .hangup() */
@@ -277,17 +266,20 @@ static void v253_receive(struct tty_struct *tty,
277 const unsigned char *cp, char *fp, int count) 266 const unsigned char *cp, char *fp, int count)
278{ 267{
279 struct snd_soc_codec *codec = tty->disc_data; 268 struct snd_soc_codec *codec = tty->disc_data;
269 struct cx20442_priv *cx20442;
280 270
281 if (!codec) 271 if (!codec)
282 return; 272 return;
283 273
284 if (!codec->control_data) { 274 cx20442 = snd_soc_codec_get_drvdata(codec);
275
276 if (!cx20442->control_data) {
285 /* First modem response, complete setup procedure */ 277 /* First modem response, complete setup procedure */
286 278
287 /* Set up codec driver access to modem controls */ 279 /* Set up codec driver access to modem controls */
288 codec->control_data = tty; 280 cx20442->control_data = tty;
289 codec->hw_write = (hw_write_t)tty->ops->write; 281 codec->hw_write = (hw_write_t)tty->ops->write;
290 codec->pop_time = 1; 282 codec->card->pop_time = 1;
291 } 283 }
292} 284}
293 285
@@ -313,8 +305,8 @@ EXPORT_SYMBOL_GPL(v253_ops);
313 * Codec DAI 305 * Codec DAI
314 */ 306 */
315 307
316struct snd_soc_dai cx20442_dai = { 308static struct snd_soc_dai_driver cx20442_dai = {
317 .name = "CX20442", 309 .name = "cx20442-voice",
318 .playback = { 310 .playback = {
319 .stream_name = "Playback", 311 .stream_name = "Playback",
320 .channels_min = 1, 312 .channels_min = 1,
@@ -330,142 +322,68 @@ struct snd_soc_dai cx20442_dai = {
330 .formats = SNDRV_PCM_FMTBIT_S16_LE, 322 .formats = SNDRV_PCM_FMTBIT_S16_LE,
331 }, 323 },
332}; 324};
333EXPORT_SYMBOL_GPL(cx20442_dai);
334 325
335static int cx20442_codec_probe(struct platform_device *pdev) 326static int cx20442_codec_probe(struct snd_soc_codec *codec)
336{ 327{
337 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 328 struct cx20442_priv *cx20442;
338 struct snd_soc_codec *codec;
339 int ret;
340
341 if (!cx20442_codec) {
342 dev_err(&pdev->dev, "cx20442 not yet discovered\n");
343 return -ENODEV;
344 }
345 codec = cx20442_codec;
346
347 socdev->card->codec = codec;
348 329
349 /* register pcms */ 330 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
350 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 331 if (cx20442 == NULL)
351 if (ret < 0) { 332 return -ENOMEM;
352 dev_err(&pdev->dev, "failed to create pcms\n"); 333 snd_soc_codec_set_drvdata(codec, cx20442);
353 goto pcm_err;
354 }
355 334
356 cx20442_add_widgets(codec); 335 cx20442->control_data = NULL;
336 codec->hw_write = NULL;
337 codec->card->pop_time = 0;
357 338
358pcm_err: 339 return 0;
359 return ret;
360} 340}
361 341
362/* power down chip */ 342/* power down chip */
363static int cx20442_codec_remove(struct platform_device *pdev) 343static int cx20442_codec_remove(struct snd_soc_codec *codec)
364{ 344{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 345 struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
366 346
367 snd_soc_free_pcms(socdev); 347 if (cx20442->control_data) {
368 snd_soc_dapm_free(socdev); 348 struct tty_struct *tty = cx20442->control_data;
349 tty_hangup(tty);
350 }
369 351
352 kfree(cx20442);
370 return 0; 353 return 0;
371} 354}
372 355
373struct snd_soc_codec_device cx20442_codec_dev = { 356static const u8 cx20442_reg;
357
358static struct snd_soc_codec_driver cx20442_codec_dev = {
374 .probe = cx20442_codec_probe, 359 .probe = cx20442_codec_probe,
375 .remove = cx20442_codec_remove, 360 .remove = cx20442_codec_remove,
361 .reg_cache_default = &cx20442_reg,
362 .reg_cache_size = 1,
363 .reg_word_size = sizeof(u8),
364 .read = cx20442_read_reg_cache,
365 .write = cx20442_write,
366 .dapm_widgets = cx20442_dapm_widgets,
367 .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
368 .dapm_routes = cx20442_audio_map,
369 .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
376}; 370};
377EXPORT_SYMBOL_GPL(cx20442_codec_dev);
378
379static int cx20442_register(struct cx20442_priv *cx20442)
380{
381 struct snd_soc_codec *codec = &cx20442->codec;
382 int ret;
383
384 mutex_init(&codec->mutex);
385 INIT_LIST_HEAD(&codec->dapm_widgets);
386 INIT_LIST_HEAD(&codec->dapm_paths);
387
388 codec->name = "CX20442";
389 codec->owner = THIS_MODULE;
390 snd_soc_codec_set_drvdata(codec, cx20442);
391
392 codec->dai = &cx20442_dai;
393 codec->num_dai = 1;
394
395 codec->reg_cache = &cx20442->reg_cache;
396 codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
397 codec->read = cx20442_read_reg_cache;
398 codec->write = cx20442_write;
399
400 codec->bias_level = SND_SOC_BIAS_OFF;
401
402 cx20442_dai.dev = codec->dev;
403
404 cx20442_codec = codec;
405
406 ret = snd_soc_register_codec(codec);
407 if (ret != 0) {
408 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
409 goto err;
410 }
411
412 ret = snd_soc_register_dai(&cx20442_dai);
413 if (ret != 0) {
414 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
415 goto err_codec;
416 }
417
418 return 0;
419
420err_codec:
421 snd_soc_unregister_codec(codec);
422err:
423 cx20442_codec = NULL;
424 kfree(cx20442);
425 return ret;
426}
427
428static void cx20442_unregister(struct cx20442_priv *cx20442)
429{
430 snd_soc_unregister_dai(&cx20442_dai);
431 snd_soc_unregister_codec(&cx20442->codec);
432
433 cx20442_codec = NULL;
434 kfree(cx20442);
435}
436 371
437static int cx20442_platform_probe(struct platform_device *pdev) 372static int cx20442_platform_probe(struct platform_device *pdev)
438{ 373{
439 struct cx20442_priv *cx20442; 374 return snd_soc_register_codec(&pdev->dev,
440 struct snd_soc_codec *codec; 375 &cx20442_codec_dev, &cx20442_dai, 1);
441
442 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
443 if (cx20442 == NULL)
444 return -ENOMEM;
445
446 codec = &cx20442->codec;
447
448 codec->control_data = NULL;
449 codec->hw_write = NULL;
450 codec->pop_time = 0;
451
452 codec->dev = &pdev->dev;
453 platform_set_drvdata(pdev, cx20442);
454
455 return cx20442_register(cx20442);
456} 376}
457 377
458static int __exit cx20442_platform_remove(struct platform_device *pdev) 378static int __exit cx20442_platform_remove(struct platform_device *pdev)
459{ 379{
460 struct cx20442_priv *cx20442 = platform_get_drvdata(pdev); 380 snd_soc_unregister_codec(&pdev->dev);
461
462 cx20442_unregister(cx20442);
463 return 0; 381 return 0;
464} 382}
465 383
466static struct platform_driver cx20442_platform_driver = { 384static struct platform_driver cx20442_platform_driver = {
467 .driver = { 385 .driver = {
468 .name = "cx20442", 386 .name = "cx20442-codec",
469 .owner = THIS_MODULE, 387 .owner = THIS_MODULE,
470 }, 388 },
471 .probe = cx20442_platform_probe, 389 .probe = cx20442_platform_probe,
@@ -487,4 +405,4 @@ module_exit(cx20442_exit);
487MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver"); 405MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
488MODULE_AUTHOR("Janusz Krzysztofik"); 406MODULE_AUTHOR("Janusz Krzysztofik");
489MODULE_LICENSE("GPL"); 407MODULE_LICENSE("GPL");
490MODULE_ALIAS("platform:cx20442"); 408MODULE_ALIAS("platform:cx20442-codec");
diff --git a/sound/soc/codecs/cx20442.h b/sound/soc/codecs/cx20442.h
index 688a5eb62e17..c7a7c79ef0cd 100644
--- a/sound/soc/codecs/cx20442.h
+++ b/sound/soc/codecs/cx20442.h
@@ -13,8 +13,6 @@
13#ifndef _CX20442_CODEC_H 13#ifndef _CX20442_CODEC_H
14#define _CX20442_CODEC_H 14#define _CX20442_CODEC_H
15 15
16extern struct snd_soc_dai cx20442_dai;
17extern struct snd_soc_codec_device cx20442_codec_dev;
18extern struct tty_ldisc_ops v253_ops; 16extern struct tty_ldisc_ops v253_ops;
19 17
20#endif 18#endif
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 3c51d6a57523..92fd9d7a9221 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -21,12 +21,10 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc-dapm.h> 24#include <sound/soc.h>
25#include <sound/initval.h> 25#include <sound/initval.h>
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27 27
28#include "da7210.h"
29
30/* DA7210 register space */ 28/* DA7210 register space */
31#define DA7210_STATUS 0x02 29#define DA7210_STATUS 0x02
32#define DA7210_STARTUP1 0x03 30#define DA7210_STARTUP1 0x03
@@ -162,11 +160,10 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
162 160
163/* Codec private data */ 161/* Codec private data */
164struct da7210_priv { 162struct da7210_priv {
165 struct snd_soc_codec codec; 163 enum snd_soc_control_type control_type;
164 void *control_data;
166}; 165};
167 166
168static struct snd_soc_codec *da7210_codec;
169
170/* 167/*
171 * Register cache 168 * Register cache
172 */ 169 */
@@ -209,12 +206,12 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
209 u8 *cache = codec->reg_cache; 206 u8 *cache = codec->reg_cache;
210 u8 data[2]; 207 u8 data[2];
211 208
212 BUG_ON(codec->volatile_register); 209 BUG_ON(codec->driver->volatile_register);
213 210
214 data[0] = reg & 0xff; 211 data[0] = reg & 0xff;
215 data[1] = value & 0xff; 212 data[1] = value & 0xff;
216 213
217 if (reg >= codec->reg_cache_size) 214 if (reg >= codec->driver->reg_cache_size)
218 return -EIO; 215 return -EIO;
219 216
220 if (2 != codec->hw_write(codec->control_data, data, 2)) 217 if (2 != codec->hw_write(codec->control_data, data, 2))
@@ -267,8 +264,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
267 struct snd_soc_dai *dai) 264 struct snd_soc_dai *dai)
268{ 265{
269 struct snd_soc_pcm_runtime *rtd = substream->private_data; 266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
270 struct snd_soc_device *socdev = rtd->socdev; 267 struct snd_soc_codec *codec = rtd->codec;
271 struct snd_soc_codec *codec = socdev->card->codec;
272 u32 dai_cfg1; 268 u32 dai_cfg1;
273 u32 hpf_reg, hpf_mask, hpf_value; 269 u32 hpf_reg, hpf_mask, hpf_value;
274 u32 fs, bypass; 270 u32 fs, bypass;
@@ -430,9 +426,8 @@ static struct snd_soc_dai_ops da7210_dai_ops = {
430 .set_fmt = da7210_set_dai_fmt, 426 .set_fmt = da7210_set_dai_fmt,
431}; 427};
432 428
433struct snd_soc_dai da7210_dai = { 429static struct snd_soc_dai_driver da7210_dai = {
434 .name = "DA7210 IIS", 430 .name = "da7210-hifi",
435 .id = 0,
436 /* playback capabilities */ 431 /* playback capabilities */
437 .playback = { 432 .playback = {
438 .stream_name = "Playback", 433 .stream_name = "Playback",
@@ -452,55 +447,15 @@ struct snd_soc_dai da7210_dai = {
452 .ops = &da7210_dai_ops, 447 .ops = &da7210_dai_ops,
453 .symmetric_rates = 1, 448 .symmetric_rates = 1,
454}; 449};
455EXPORT_SYMBOL_GPL(da7210_dai);
456 450
457/* 451static int da7210_probe(struct snd_soc_codec *codec)
458 * Initialize the DA7210 driver
459 * register the mixer and dsp interfaces with the kernel
460 */
461static int da7210_init(struct da7210_priv *da7210)
462{ 452{
463 struct snd_soc_codec *codec = &da7210->codec; 453 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
464 int ret = 0;
465 454
466 if (da7210_codec) { 455 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
467 dev_err(codec->dev, "Another da7210 is registered\n");
468 return -EINVAL;
469 }
470 456
471 mutex_init(&codec->mutex); 457 codec->control_data = da7210->control_data;
472 INIT_LIST_HEAD(&codec->dapm_widgets);
473 INIT_LIST_HEAD(&codec->dapm_paths);
474
475 snd_soc_codec_set_drvdata(codec, da7210);
476 codec->name = "DA7210";
477 codec->owner = THIS_MODULE;
478 codec->read = da7210_read;
479 codec->write = da7210_write;
480 codec->dai = &da7210_dai;
481 codec->num_dai = 1;
482 codec->hw_write = (hw_write_t)i2c_master_send; 458 codec->hw_write = (hw_write_t)i2c_master_send;
483 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
484 codec->reg_cache = kmemdup(da7210_reg,
485 sizeof(da7210_reg), GFP_KERNEL);
486
487 if (!codec->reg_cache)
488 return -ENOMEM;
489
490 da7210_dai.dev = codec->dev;
491 da7210_codec = codec;
492
493 ret = snd_soc_register_codec(codec);
494 if (ret) {
495 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
496 goto init_err;
497 }
498
499 ret = snd_soc_register_dai(&da7210_dai);
500 if (ret) {
501 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
502 goto codec_err;
503 }
504 459
505 /* FIXME 460 /* FIXME
506 * 461 *
@@ -583,54 +538,50 @@ static int da7210_init(struct da7210_priv *da7210)
583 /* Activate all enabled subsystem */ 538 /* Activate all enabled subsystem */
584 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 539 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
585 540
586 return ret; 541 snd_soc_add_controls(codec, da7210_snd_controls,
587 542 ARRAY_SIZE(da7210_snd_controls));
588codec_err:
589 snd_soc_unregister_codec(codec);
590init_err:
591 kfree(codec->reg_cache);
592 codec->reg_cache = NULL;
593 543
594 return ret; 544 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
595 545
546 return 0;
596} 547}
597 548
549static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
550 .probe = da7210_probe,
551 .read = da7210_read,
552 .write = da7210_write,
553 .reg_cache_size = ARRAY_SIZE(da7210_reg),
554 .reg_word_size = sizeof(u8),
555 .reg_cache_default = da7210_reg,
556};
557
598#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
599static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 559static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
600 const struct i2c_device_id *id) 560 const struct i2c_device_id *id)
601{ 561{
602 struct da7210_priv *da7210; 562 struct da7210_priv *da7210;
603 struct snd_soc_codec *codec;
604 int ret; 563 int ret;
605 564
606 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL); 565 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
607 if (!da7210) 566 if (!da7210)
608 return -ENOMEM; 567 return -ENOMEM;
609 568
610 codec = &da7210->codec;
611 codec->dev = &i2c->dev;
612
613 i2c_set_clientdata(i2c, da7210); 569 i2c_set_clientdata(i2c, da7210);
614 codec->control_data = i2c; 570 da7210->control_data = i2c;
571 da7210->control_type = SND_SOC_I2C;
615 572
616 ret = da7210_init(da7210); 573 ret = snd_soc_register_codec(&i2c->dev,
617 if (ret < 0) { 574 &soc_codec_dev_da7210, &da7210_dai, 1);
618 pr_err("Failed to initialise da7210 audio codec\n"); 575 if (ret < 0)
619 kfree(da7210); 576 kfree(da7210);
620 }
621 577
622 return ret; 578 return ret;
623} 579}
624 580
625static int __devexit da7210_i2c_remove(struct i2c_client *client) 581static int __devexit da7210_i2c_remove(struct i2c_client *client)
626{ 582{
627 struct da7210_priv *da7210 = i2c_get_clientdata(client); 583 snd_soc_unregister_codec(&client->dev);
628 584 kfree(i2c_get_clientdata(client));
629 snd_soc_unregister_dai(&da7210_dai);
630 kfree(da7210->codec.reg_cache);
631 kfree(da7210);
632 da7210_codec = NULL;
633
634 return 0; 585 return 0;
635} 586}
636 587
@@ -643,59 +594,15 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
643/* I2C codec control layer */ 594/* I2C codec control layer */
644static struct i2c_driver da7210_i2c_driver = { 595static struct i2c_driver da7210_i2c_driver = {
645 .driver = { 596 .driver = {
646 .name = "DA7210 I2C Codec", 597 .name = "da7210-codec",
647 .owner = THIS_MODULE, 598 .owner = THIS_MODULE,
648 }, 599 },
649 .probe = da7210_i2c_probe, 600 .probe = da7210_i2c_probe,
650 .remove = __devexit_p(da7210_i2c_remove), 601 .remove = __devexit_p(da7210_i2c_remove),
651 .id_table = da7210_i2c_id, 602 .id_table = da7210_i2c_id,
652}; 603};
653#endif 604#endif
654 605
655static int da7210_probe(struct platform_device *pdev)
656{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
658 struct snd_soc_codec *codec;
659 int ret;
660
661 if (!da7210_codec) {
662 dev_err(&pdev->dev, "Codec device not registered\n");
663 return -ENODEV;
664 }
665
666 socdev->card->codec = da7210_codec;
667 codec = da7210_codec;
668
669 /* Register pcms */
670 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
671 if (ret < 0)
672 goto pcm_err;
673
674 snd_soc_add_controls(da7210_codec, da7210_snd_controls,
675 ARRAY_SIZE(da7210_snd_controls));
676
677 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
678
679pcm_err:
680 return ret;
681}
682
683static int da7210_remove(struct platform_device *pdev)
684{
685 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
686
687 snd_soc_free_pcms(socdev);
688 snd_soc_dapm_free(socdev);
689
690 return 0;
691}
692
693struct snd_soc_codec_device soc_codec_dev_da7210 = {
694 .probe = da7210_probe,
695 .remove = da7210_remove,
696};
697EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
698
699static int __init da7210_modinit(void) 606static int __init da7210_modinit(void)
700{ 607{
701 int ret = 0; 608 int ret = 0;
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
deleted file mode 100644
index 390d621eb742..000000000000
--- a/sound/soc/codecs/da7210.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * da7210.h -- audio driver for da7210
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef _DA7210_H
18#define _DA7210_H
19
20extern struct snd_soc_dai da7210_dai;
21extern struct snd_soc_codec_device soc_codec_dev_da7210;
22
23#endif
24
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c
new file mode 100644
index 000000000000..704bbde65737
--- /dev/null
+++ b/sound/soc/codecs/dfbmcs320.c
@@ -0,0 +1,72 @@
1/*
2 * Driver for the DFBM-CS320 bluetooth module
3 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/platform_device.h>
15
16#include <sound/soc.h>
17
18static struct snd_soc_dai_driver dfbmcs320_dai = {
19 .name = "dfbmcs320-pcm",
20 .playback = {
21 .channels_min = 1,
22 .channels_max = 1,
23 .rates = SNDRV_PCM_RATE_8000,
24 .formats = SNDRV_PCM_FMTBIT_S16_LE,
25 },
26 .capture = {
27 .channels_min = 1,
28 .channels_max = 1,
29 .rates = SNDRV_PCM_RATE_8000,
30 .formats = SNDRV_PCM_FMTBIT_S16_LE,
31 },
32};
33
34static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
35
36static int __devinit dfbmcs320_probe(struct platform_device *pdev)
37{
38 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
39 &dfbmcs320_dai, 1);
40}
41
42static int __devexit dfbmcs320_remove(struct platform_device *pdev)
43{
44 snd_soc_unregister_codec(&pdev->dev);
45
46 return 0;
47}
48
49static struct platform_driver dfmcs320_driver = {
50 .driver = {
51 .name = "dfbmcs320",
52 .owner = THIS_MODULE,
53 },
54 .probe = dfbmcs320_probe,
55 .remove = __devexit_p(dfbmcs320_remove),
56};
57
58static int __init dfbmcs320_init(void)
59{
60 return platform_driver_register(&dfmcs320_driver);
61}
62module_init(dfbmcs320_init);
63
64static void __exit dfbmcs320_exit(void)
65{
66 platform_driver_unregister(&dfmcs320_driver);
67}
68module_exit(dfbmcs320_exit);
69
70MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
71MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver");
72MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
new file mode 100644
index 000000000000..f9a87737ec16
--- /dev/null
+++ b/sound/soc/codecs/dmic.c
@@ -0,0 +1,105 @@
1/*
2 * dmic.c -- SoC audio for Generic Digital MICs
3 *
4 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/platform_device.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29static struct snd_soc_dai_driver dmic_dai = {
30 .name = "dmic-hifi",
31 .capture = {
32 .stream_name = "Capture",
33 .channels_min = 1,
34 .channels_max = 8,
35 .rates = SNDRV_PCM_RATE_CONTINUOUS,
36 .formats = SNDRV_PCM_FMTBIT_S32_LE
37 | SNDRV_PCM_FMTBIT_S24_LE
38 | SNDRV_PCM_FMTBIT_S16_LE,
39 },
40};
41
42static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
43 SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
44 SND_SOC_NOPM, 0, 0),
45 SND_SOC_DAPM_INPUT("DMic"),
46};
47
48static const struct snd_soc_dapm_route intercon[] = {
49 {"DMIC AIF", NULL, "DMic"},
50};
51
52static int dmic_probe(struct snd_soc_codec *codec)
53{
54 struct snd_soc_dapm_context *dapm = &codec->dapm;
55
56 snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
57 ARRAY_SIZE(dmic_dapm_widgets));
58 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
59 snd_soc_dapm_new_widgets(dapm);
60
61 return 0;
62}
63
64static struct snd_soc_codec_driver soc_dmic = {
65 .probe = dmic_probe,
66};
67
68static int __devinit dmic_dev_probe(struct platform_device *pdev)
69{
70 return snd_soc_register_codec(&pdev->dev,
71 &soc_dmic, &dmic_dai, 1);
72}
73
74static int __devexit dmic_dev_remove(struct platform_device *pdev)
75{
76 snd_soc_unregister_codec(&pdev->dev);
77 return 0;
78}
79
80MODULE_ALIAS("platform:dmic-codec");
81
82static struct platform_driver dmic_driver = {
83 .driver = {
84 .name = "dmic-codec",
85 .owner = THIS_MODULE,
86 },
87 .probe = dmic_dev_probe,
88 .remove = __devexit_p(dmic_dev_remove),
89};
90
91static int __init dmic_init(void)
92{
93 return platform_driver_register(&dmic_driver);
94}
95module_init(dmic_init);
96
97static void __exit dmic_exit(void)
98{
99 platform_driver_unregister(&dmic_driver);
100}
101module_exit(dmic_exit);
102
103MODULE_DESCRIPTION("Generic DMIC driver");
104MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
105MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 66557de1e4fe..e373f8f06907 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -22,7 +22,6 @@
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/soc-dapm.h>
26#include <sound/soc.h> 25#include <sound/soc.h>
27 26
28#define JZ4740_REG_CODEC_1 0x0 27#define JZ4740_REG_CODEC_1 0x0
@@ -74,29 +73,22 @@ static const uint32_t jz4740_codec_regs[] = {
74struct jz4740_codec { 73struct jz4740_codec {
75 void __iomem *base; 74 void __iomem *base;
76 struct resource *mem; 75 struct resource *mem;
77
78 uint32_t reg_cache[2];
79 struct snd_soc_codec codec;
80}; 76};
81 77
82static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
83{
84 return container_of(codec, struct jz4740_codec, codec);
85}
86
87static unsigned int jz4740_codec_read(struct snd_soc_codec *codec, 78static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
88 unsigned int reg) 79 unsigned int reg)
89{ 80{
90 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec); 81 struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
91 return readl(jz4740_codec->base + (reg << 2)); 82 return readl(jz4740_codec->base + (reg << 2));
92} 83}
93 84
94static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg, 85static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
95 unsigned int val) 86 unsigned int val)
96{ 87{
97 struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec); 88 struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
89 u32 *cache = codec->reg_cache;
98 90
99 jz4740_codec->reg_cache[reg] = val; 91 cache[reg] = val;
100 writel(val, jz4740_codec->base + (reg << 2)); 92 writel(val, jz4740_codec->base + (reg << 2));
101 93
102 return 0; 94 return 0;
@@ -172,8 +164,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
172{ 164{
173 uint32_t val; 165 uint32_t val;
174 struct snd_soc_pcm_runtime *rtd = substream->private_data; 166 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev; 167 struct snd_soc_codec *codec =rtd->codec;
176 struct snd_soc_codec *codec = socdev->card->codec;
177 168
178 switch (params_rate(params)) { 169 switch (params_rate(params)) {
179 case 8000: 170 case 8000:
@@ -219,8 +210,8 @@ static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
219 .hw_params = jz4740_codec_hw_params, 210 .hw_params = jz4740_codec_hw_params,
220}; 211};
221 212
222struct snd_soc_dai jz4740_codec_dai = { 213static struct snd_soc_dai_driver jz4740_codec_dai = {
223 .name = "jz4740", 214 .name = "jz4740-hifi",
224 .playback = { 215 .playback = {
225 .stream_name = "Playback", 216 .stream_name = "Playback",
226 .channels_min = 2, 217 .channels_min = 2,
@@ -238,7 +229,6 @@ struct snd_soc_dai jz4740_codec_dai = {
238 .ops = &jz4740_codec_dai_ops, 229 .ops = &jz4740_codec_dai_ops,
239 .symmetric_rates = 1, 230 .symmetric_rates = 1,
240}; 231};
241EXPORT_SYMBOL_GPL(jz4740_codec_dai);
242 232
243static void jz4740_codec_wakeup(struct snd_soc_codec *codec) 233static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
244{ 234{
@@ -275,7 +265,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
275 break; 265 break;
276 case SND_SOC_BIAS_STANDBY: 266 case SND_SOC_BIAS_STANDBY:
277 /* The only way to clear the suspend flag is to reset the codec */ 267 /* The only way to clear the suspend flag is to reset the codec */
278 if (codec->bias_level == SND_SOC_BIAS_OFF) 268 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
279 jz4740_codec_wakeup(codec); 269 jz4740_codec_wakeup(codec);
280 270
281 mask = JZ4740_CODEC_1_VREF_DISABLE | 271 mask = JZ4740_CODEC_1_VREF_DISABLE |
@@ -297,68 +287,37 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
297 break; 287 break;
298 } 288 }
299 289
300 codec->bias_level = level; 290 codec->dapm.bias_level = level;
301 291
302 return 0; 292 return 0;
303} 293}
304 294
305static struct snd_soc_codec *jz4740_codec_codec; 295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
306
307static int jz4740_codec_dev_probe(struct platform_device *pdev)
308{ 296{
309 int ret; 297 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
310 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 298 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
311 struct snd_soc_codec *codec = jz4740_codec_codec;
312
313 BUG_ON(!codec);
314
315 socdev->card->codec = codec;
316
317 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
318 if (ret) {
319 dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
320 return ret;
321 }
322
323 snd_soc_add_controls(codec, jz4740_codec_controls,
324 ARRAY_SIZE(jz4740_codec_controls));
325
326 snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets,
327 ARRAY_SIZE(jz4740_codec_dapm_widgets));
328
329 snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes,
330 ARRAY_SIZE(jz4740_codec_dapm_routes));
331 299
332 snd_soc_dapm_new_widgets(codec); 300 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
333 301
334 return 0; 302 return 0;
335} 303}
336 304
337static int jz4740_codec_dev_remove(struct platform_device *pdev) 305static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
338{ 306{
339 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 307 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
340
341 snd_soc_free_pcms(socdev);
342 snd_soc_dapm_free(socdev);
343 308
344 return 0; 309 return 0;
345} 310}
346 311
347#ifdef CONFIG_PM_SLEEP 312#ifdef CONFIG_PM_SLEEP
348 313
349static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state) 314static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
350{ 315{
351 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
352 struct snd_soc_codec *codec = socdev->card->codec;
353
354 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); 316 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
355} 317}
356 318
357static int jz4740_codec_resume(struct platform_device *pdev) 319static int jz4740_codec_resume(struct snd_soc_codec *codec)
358{ 320{
359 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
360 struct snd_soc_codec *codec = socdev->card->codec;
361
362 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 321 return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
363} 322}
364 323
@@ -367,19 +326,30 @@ static int jz4740_codec_resume(struct platform_device *pdev)
367#define jz4740_codec_resume NULL 326#define jz4740_codec_resume NULL
368#endif 327#endif
369 328
370struct snd_soc_codec_device soc_codec_dev_jz4740_codec = { 329static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
371 .probe = jz4740_codec_dev_probe, 330 .probe = jz4740_codec_dev_probe,
372 .remove = jz4740_codec_dev_remove, 331 .remove = jz4740_codec_dev_remove,
373 .suspend = jz4740_codec_suspend, 332 .suspend = jz4740_codec_suspend,
374 .resume = jz4740_codec_resume, 333 .resume = jz4740_codec_resume,
334 .read = jz4740_codec_read,
335 .write = jz4740_codec_write,
336 .set_bias_level = jz4740_codec_set_bias_level,
337 .reg_cache_default = jz4740_codec_regs,
338 .reg_word_size = sizeof(u32),
339 .reg_cache_size = 2,
340
341 .controls = jz4740_codec_controls,
342 .num_controls = ARRAY_SIZE(jz4740_codec_controls),
343 .dapm_widgets = jz4740_codec_dapm_widgets,
344 .num_dapm_widgets = ARRAY_SIZE(jz4740_codec_dapm_widgets),
345 .dapm_routes = jz4740_codec_dapm_routes,
346 .num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
375}; 347};
376EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
377 348
378static int __devinit jz4740_codec_probe(struct platform_device *pdev) 349static int __devinit jz4740_codec_probe(struct platform_device *pdev)
379{ 350{
380 int ret; 351 int ret;
381 struct jz4740_codec *jz4740_codec; 352 struct jz4740_codec *jz4740_codec;
382 struct snd_soc_codec *codec;
383 struct resource *mem; 353 struct resource *mem;
384 354
385 jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL); 355 jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
@@ -408,55 +378,17 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev)
408 } 378 }
409 jz4740_codec->mem = mem; 379 jz4740_codec->mem = mem;
410 380
411 jz4740_codec_dai.dev = &pdev->dev;
412
413 codec = &jz4740_codec->codec;
414
415 codec->dev = &pdev->dev;
416 codec->name = "jz4740";
417 codec->owner = THIS_MODULE;
418
419 codec->read = jz4740_codec_read;
420 codec->write = jz4740_codec_write;
421 codec->set_bias_level = jz4740_codec_set_bias_level;
422 codec->bias_level = SND_SOC_BIAS_OFF;
423
424 codec->dai = &jz4740_codec_dai;
425 codec->num_dai = 1;
426
427 codec->reg_cache = jz4740_codec->reg_cache;
428 codec->reg_cache_size = 2;
429 memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
430
431 mutex_init(&codec->mutex);
432 INIT_LIST_HEAD(&codec->dapm_widgets);
433 INIT_LIST_HEAD(&codec->dapm_paths);
434
435 jz4740_codec_codec = codec;
436
437 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
438 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
439
440 platform_set_drvdata(pdev, jz4740_codec); 381 platform_set_drvdata(pdev, jz4740_codec);
441 382
442 ret = snd_soc_register_codec(codec); 383 ret = snd_soc_register_codec(&pdev->dev,
384 &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
443 if (ret) { 385 if (ret) {
444 dev_err(&pdev->dev, "Failed to register codec\n"); 386 dev_err(&pdev->dev, "Failed to register codec\n");
445 goto err_iounmap; 387 goto err_iounmap;
446 } 388 }
447 389
448 ret = snd_soc_register_dai(&jz4740_codec_dai);
449 if (ret) {
450 dev_err(&pdev->dev, "Failed to register codec dai\n");
451 goto err_unregister_codec;
452 }
453
454 jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
455
456 return 0; 390 return 0;
457 391
458err_unregister_codec:
459 snd_soc_unregister_codec(codec);
460err_iounmap: 392err_iounmap:
461 iounmap(jz4740_codec->base); 393 iounmap(jz4740_codec->base);
462err_release_mem_region: 394err_release_mem_region:
@@ -472,8 +404,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev)
472 struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev); 404 struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
473 struct resource *mem = jz4740_codec->mem; 405 struct resource *mem = jz4740_codec->mem;
474 406
475 snd_soc_unregister_dai(&jz4740_codec_dai); 407 snd_soc_unregister_codec(&pdev->dev);
476 snd_soc_unregister_codec(&jz4740_codec->codec);
477 408
478 iounmap(jz4740_codec->base); 409 iounmap(jz4740_codec->base);
479 release_mem_region(mem->start, resource_size(mem)); 410 release_mem_region(mem->start, resource_size(mem));
diff --git a/sound/soc/codecs/jz4740.h b/sound/soc/codecs/jz4740.h
deleted file mode 100644
index b5a0691be763..000000000000
--- a/sound/soc/codecs/jz4740.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * You should have received a copy of the GNU General Public License along
9 * with this program; if not, write to the Free Software Foundation, Inc.,
10 * 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 */
13
14#ifndef __SND_SOC_CODECS_JZ4740_CODEC_H__
15#define __SND_SOC_CODECS_JZ4740_CODEC_H__
16
17extern struct snd_soc_dai jz4740_codec_dai;
18extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
19
20#endif
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
new file mode 100644
index 000000000000..2c2a681da0d7
--- /dev/null
+++ b/sound/soc/codecs/lm4857.c
@@ -0,0 +1,276 @@
1/*
2 * LM4857 AMP driver
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20
21#include <sound/core.h>
22#include <sound/soc.h>
23#include <sound/tlv.h>
24
25struct lm4857 {
26 struct i2c_client *i2c;
27 uint8_t mode;
28};
29
30static const uint8_t lm4857_default_regs[] = {
31 0x00, 0x00, 0x00, 0x00,
32};
33
34/* The register offsets in the cache array */
35#define LM4857_MVOL 0
36#define LM4857_LVOL 1
37#define LM4857_RVOL 2
38#define LM4857_CTRL 3
39
40/* the shifts required to set these bits */
41#define LM4857_3D 5
42#define LM4857_WAKEUP 5
43#define LM4857_EPGAIN 4
44
45static int lm4857_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value)
47{
48 uint8_t data;
49 int ret;
50
51 ret = snd_soc_cache_write(codec, reg, value);
52 if (ret < 0)
53 return ret;
54
55 data = (reg << 6) | value;
56 ret = i2c_master_send(codec->control_data, &data, 1);
57 if (ret != 1) {
58 dev_err(codec->dev, "Failed to write register: %d\n", ret);
59 return ret;
60 }
61
62 return 0;
63}
64
65static unsigned int lm4857_read(struct snd_soc_codec *codec,
66 unsigned int reg)
67{
68 unsigned int val;
69 int ret;
70
71 ret = snd_soc_cache_read(codec, reg, &val);
72 if (ret)
73 return -1;
74
75 return val;
76}
77
78static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
79 struct snd_ctl_elem_value *ucontrol)
80{
81 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
82 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
83
84 ucontrol->value.integer.value[0] = lm4857->mode;
85
86 return 0;
87}
88
89static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
90 struct snd_ctl_elem_value *ucontrol)
91{
92 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
93 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
94 uint8_t value = ucontrol->value.integer.value[0];
95
96 lm4857->mode = value;
97
98 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
99 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, value + 6);
100
101 return 1;
102}
103
104static int lm4857_set_bias_level(struct snd_soc_codec *codec,
105 enum snd_soc_bias_level level)
106{
107 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
108
109 switch (level) {
110 case SND_SOC_BIAS_ON:
111 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, lm4857->mode + 6);
112 break;
113 case SND_SOC_BIAS_STANDBY:
114 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, 0);
115 break;
116 default:
117 break;
118 }
119
120 codec->dapm.bias_level = level;
121
122 return 0;
123}
124
125static const char *lm4857_mode[] = {
126 "Earpiece",
127 "Loudspeaker",
128 "Loudspeaker + Headphone",
129 "Headphone",
130};
131
132static const struct soc_enum lm4857_mode_enum =
133 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode);
134
135static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
136 SND_SOC_DAPM_INPUT("IN"),
137
138 SND_SOC_DAPM_OUTPUT("LS"),
139 SND_SOC_DAPM_OUTPUT("HP"),
140 SND_SOC_DAPM_OUTPUT("EP"),
141};
142
143static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
144static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
145
146static const struct snd_kcontrol_new lm4857_controls[] = {
147 SOC_SINGLE_TLV("Left Playback Volume", LM4857_LVOL, 0, 31, 0,
148 stereo_tlv),
149 SOC_SINGLE_TLV("Right Playback Volume", LM4857_RVOL, 0, 31, 0,
150 stereo_tlv),
151 SOC_SINGLE_TLV("Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
152 mono_tlv),
153 SOC_SINGLE("Spk 3D Playback Switch", LM4857_LVOL, LM4857_3D, 1, 0),
154 SOC_SINGLE("HP 3D Playback Switch", LM4857_RVOL, LM4857_3D, 1, 0),
155 SOC_SINGLE("Fast Wakeup Playback Switch", LM4857_CTRL,
156 LM4857_WAKEUP, 1, 0),
157 SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
158 LM4857_EPGAIN, 1, 0),
159
160 SOC_ENUM_EXT("Mode", lm4857_mode_enum,
161 lm4857_get_mode, lm4857_set_mode),
162};
163
164/* There is a demux between the input signal and the output signals.
165 * Currently there is no easy way to model it in ASoC and since it does not make
166 * much of a difference in practice simply connect the input direclty to the
167 * outputs. */
168static const struct snd_soc_dapm_route lm4857_routes[] = {
169 {"LS", NULL, "IN"},
170 {"HP", NULL, "IN"},
171 {"EP", NULL, "IN"},
172};
173
174static int lm4857_probe(struct snd_soc_codec *codec)
175{
176 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
177 struct snd_soc_dapm_context *dapm = &codec->dapm;
178 int ret;
179
180 codec->control_data = lm4857->i2c;
181
182 ret = snd_soc_add_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls));
184 if (ret)
185 return ret;
186
187 ret = snd_soc_dapm_new_controls(dapm, lm4857_dapm_widgets,
188 ARRAY_SIZE(lm4857_dapm_widgets));
189 if (ret)
190 return ret;
191
192 ret = snd_soc_dapm_add_routes(dapm, lm4857_routes,
193 ARRAY_SIZE(lm4857_routes));
194 if (ret)
195 return ret;
196
197 snd_soc_dapm_new_widgets(dapm);
198
199 return 0;
200}
201
202static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
203 .write = lm4857_write,
204 .read = lm4857_read,
205 .probe = lm4857_probe,
206 .reg_cache_size = ARRAY_SIZE(lm4857_default_regs),
207 .reg_word_size = sizeof(uint8_t),
208 .reg_cache_default = lm4857_default_regs,
209 .set_bias_level = lm4857_set_bias_level,
210};
211
212static int __devinit lm4857_i2c_probe(struct i2c_client *i2c,
213 const struct i2c_device_id *id)
214{
215 struct lm4857 *lm4857;
216 int ret;
217
218 lm4857 = kzalloc(sizeof(*lm4857), GFP_KERNEL);
219 if (!lm4857)
220 return -ENOMEM;
221
222 i2c_set_clientdata(i2c, lm4857);
223
224 lm4857->i2c = i2c;
225
226 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
227
228 if (ret) {
229 kfree(lm4857);
230 return ret;
231 }
232
233 return 0;
234}
235
236static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
237{
238 struct lm4857 *lm4857 = i2c_get_clientdata(i2c);
239
240 snd_soc_unregister_codec(&i2c->dev);
241 kfree(lm4857);
242
243 return 0;
244}
245
246static const struct i2c_device_id lm4857_i2c_id[] = {
247 { "lm4857", 0 },
248 { }
249};
250MODULE_DEVICE_TABLE(i2c, lm4857_i2c_id);
251
252static struct i2c_driver lm4857_i2c_driver = {
253 .driver = {
254 .name = "lm4857",
255 .owner = THIS_MODULE,
256 },
257 .probe = lm4857_i2c_probe,
258 .remove = __devexit_p(lm4857_i2c_remove),
259 .id_table = lm4857_i2c_id,
260};
261
262static int __init lm4857_init(void)
263{
264 return i2c_add_driver(&lm4857_i2c_driver);
265}
266module_init(lm4857_init);
267
268static void __exit lm4857_exit(void)
269{
270 i2c_del_driver(&lm4857_i2c_driver);
271}
272module_exit(lm4857_exit);
273
274MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
275MODULE_DESCRIPTION("LM4857 amplifier driver");
276MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
new file mode 100644
index 000000000000..4173b67c94d1
--- /dev/null
+++ b/sound/soc/codecs/max98088.c
@@ -0,0 +1,2125 @@
1/*
2 * max98088.c -- MAX98088 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <linux/slab.h>
26#include <asm/div64.h>
27#include <sound/max98088.h>
28#include "max98088.h"
29
30enum max98088_type {
31 MAX98088,
32 MAX98089,
33};
34
35struct max98088_cdata {
36 unsigned int rate;
37 unsigned int fmt;
38 int eq_sel;
39};
40
41struct max98088_priv {
42 enum max98088_type devtype;
43 void *control_data;
44 struct max98088_pdata *pdata;
45 unsigned int sysclk;
46 struct max98088_cdata dai[2];
47 int eq_textcnt;
48 const char **eq_texts;
49 struct soc_enum eq_enum;
50 u8 ina_state;
51 u8 inb_state;
52 unsigned int ex_mode;
53 unsigned int digmic;
54 unsigned int mic1pre;
55 unsigned int mic2pre;
56 unsigned int extmic_mode;
57};
58
59static const u8 max98088_reg[M98088_REG_CNT] = {
60 0x00, /* 00 IRQ status */
61 0x00, /* 01 MIC status */
62 0x00, /* 02 jack status */
63 0x00, /* 03 battery voltage */
64 0x00, /* 04 */
65 0x00, /* 05 */
66 0x00, /* 06 */
67 0x00, /* 07 */
68 0x00, /* 08 */
69 0x00, /* 09 */
70 0x00, /* 0A */
71 0x00, /* 0B */
72 0x00, /* 0C */
73 0x00, /* 0D */
74 0x00, /* 0E */
75 0x00, /* 0F interrupt enable */
76
77 0x00, /* 10 master clock */
78 0x00, /* 11 DAI1 clock mode */
79 0x00, /* 12 DAI1 clock control */
80 0x00, /* 13 DAI1 clock control */
81 0x00, /* 14 DAI1 format */
82 0x00, /* 15 DAI1 clock */
83 0x00, /* 16 DAI1 config */
84 0x00, /* 17 DAI1 TDM */
85 0x00, /* 18 DAI1 filters */
86 0x00, /* 19 DAI2 clock mode */
87 0x00, /* 1A DAI2 clock control */
88 0x00, /* 1B DAI2 clock control */
89 0x00, /* 1C DAI2 format */
90 0x00, /* 1D DAI2 clock */
91 0x00, /* 1E DAI2 config */
92 0x00, /* 1F DAI2 TDM */
93
94 0x00, /* 20 DAI2 filters */
95 0x00, /* 21 data config */
96 0x00, /* 22 DAC mixer */
97 0x00, /* 23 left ADC mixer */
98 0x00, /* 24 right ADC mixer */
99 0x00, /* 25 left HP mixer */
100 0x00, /* 26 right HP mixer */
101 0x00, /* 27 HP control */
102 0x00, /* 28 left REC mixer */
103 0x00, /* 29 right REC mixer */
104 0x00, /* 2A REC control */
105 0x00, /* 2B left SPK mixer */
106 0x00, /* 2C right SPK mixer */
107 0x00, /* 2D SPK control */
108 0x00, /* 2E sidetone */
109 0x00, /* 2F DAI1 playback level */
110
111 0x00, /* 30 DAI1 playback level */
112 0x00, /* 31 DAI2 playback level */
113 0x00, /* 32 DAI2 playbakc level */
114 0x00, /* 33 left ADC level */
115 0x00, /* 34 right ADC level */
116 0x00, /* 35 MIC1 level */
117 0x00, /* 36 MIC2 level */
118 0x00, /* 37 INA level */
119 0x00, /* 38 INB level */
120 0x00, /* 39 left HP volume */
121 0x00, /* 3A right HP volume */
122 0x00, /* 3B left REC volume */
123 0x00, /* 3C right REC volume */
124 0x00, /* 3D left SPK volume */
125 0x00, /* 3E right SPK volume */
126 0x00, /* 3F MIC config */
127
128 0x00, /* 40 MIC threshold */
129 0x00, /* 41 excursion limiter filter */
130 0x00, /* 42 excursion limiter threshold */
131 0x00, /* 43 ALC */
132 0x00, /* 44 power limiter threshold */
133 0x00, /* 45 power limiter config */
134 0x00, /* 46 distortion limiter config */
135 0x00, /* 47 audio input */
136 0x00, /* 48 microphone */
137 0x00, /* 49 level control */
138 0x00, /* 4A bypass switches */
139 0x00, /* 4B jack detect */
140 0x00, /* 4C input enable */
141 0x00, /* 4D output enable */
142 0xF0, /* 4E bias control */
143 0x00, /* 4F DAC power */
144
145 0x0F, /* 50 DAC power */
146 0x00, /* 51 system */
147 0x00, /* 52 DAI1 EQ1 */
148 0x00, /* 53 DAI1 EQ1 */
149 0x00, /* 54 DAI1 EQ1 */
150 0x00, /* 55 DAI1 EQ1 */
151 0x00, /* 56 DAI1 EQ1 */
152 0x00, /* 57 DAI1 EQ1 */
153 0x00, /* 58 DAI1 EQ1 */
154 0x00, /* 59 DAI1 EQ1 */
155 0x00, /* 5A DAI1 EQ1 */
156 0x00, /* 5B DAI1 EQ1 */
157 0x00, /* 5C DAI1 EQ2 */
158 0x00, /* 5D DAI1 EQ2 */
159 0x00, /* 5E DAI1 EQ2 */
160 0x00, /* 5F DAI1 EQ2 */
161
162 0x00, /* 60 DAI1 EQ2 */
163 0x00, /* 61 DAI1 EQ2 */
164 0x00, /* 62 DAI1 EQ2 */
165 0x00, /* 63 DAI1 EQ2 */
166 0x00, /* 64 DAI1 EQ2 */
167 0x00, /* 65 DAI1 EQ2 */
168 0x00, /* 66 DAI1 EQ3 */
169 0x00, /* 67 DAI1 EQ3 */
170 0x00, /* 68 DAI1 EQ3 */
171 0x00, /* 69 DAI1 EQ3 */
172 0x00, /* 6A DAI1 EQ3 */
173 0x00, /* 6B DAI1 EQ3 */
174 0x00, /* 6C DAI1 EQ3 */
175 0x00, /* 6D DAI1 EQ3 */
176 0x00, /* 6E DAI1 EQ3 */
177 0x00, /* 6F DAI1 EQ3 */
178
179 0x00, /* 70 DAI1 EQ4 */
180 0x00, /* 71 DAI1 EQ4 */
181 0x00, /* 72 DAI1 EQ4 */
182 0x00, /* 73 DAI1 EQ4 */
183 0x00, /* 74 DAI1 EQ4 */
184 0x00, /* 75 DAI1 EQ4 */
185 0x00, /* 76 DAI1 EQ4 */
186 0x00, /* 77 DAI1 EQ4 */
187 0x00, /* 78 DAI1 EQ4 */
188 0x00, /* 79 DAI1 EQ4 */
189 0x00, /* 7A DAI1 EQ5 */
190 0x00, /* 7B DAI1 EQ5 */
191 0x00, /* 7C DAI1 EQ5 */
192 0x00, /* 7D DAI1 EQ5 */
193 0x00, /* 7E DAI1 EQ5 */
194 0x00, /* 7F DAI1 EQ5 */
195
196 0x00, /* 80 DAI1 EQ5 */
197 0x00, /* 81 DAI1 EQ5 */
198 0x00, /* 82 DAI1 EQ5 */
199 0x00, /* 83 DAI1 EQ5 */
200 0x00, /* 84 DAI2 EQ1 */
201 0x00, /* 85 DAI2 EQ1 */
202 0x00, /* 86 DAI2 EQ1 */
203 0x00, /* 87 DAI2 EQ1 */
204 0x00, /* 88 DAI2 EQ1 */
205 0x00, /* 89 DAI2 EQ1 */
206 0x00, /* 8A DAI2 EQ1 */
207 0x00, /* 8B DAI2 EQ1 */
208 0x00, /* 8C DAI2 EQ1 */
209 0x00, /* 8D DAI2 EQ1 */
210 0x00, /* 8E DAI2 EQ2 */
211 0x00, /* 8F DAI2 EQ2 */
212
213 0x00, /* 90 DAI2 EQ2 */
214 0x00, /* 91 DAI2 EQ2 */
215 0x00, /* 92 DAI2 EQ2 */
216 0x00, /* 93 DAI2 EQ2 */
217 0x00, /* 94 DAI2 EQ2 */
218 0x00, /* 95 DAI2 EQ2 */
219 0x00, /* 96 DAI2 EQ2 */
220 0x00, /* 97 DAI2 EQ2 */
221 0x00, /* 98 DAI2 EQ3 */
222 0x00, /* 99 DAI2 EQ3 */
223 0x00, /* 9A DAI2 EQ3 */
224 0x00, /* 9B DAI2 EQ3 */
225 0x00, /* 9C DAI2 EQ3 */
226 0x00, /* 9D DAI2 EQ3 */
227 0x00, /* 9E DAI2 EQ3 */
228 0x00, /* 9F DAI2 EQ3 */
229
230 0x00, /* A0 DAI2 EQ3 */
231 0x00, /* A1 DAI2 EQ3 */
232 0x00, /* A2 DAI2 EQ4 */
233 0x00, /* A3 DAI2 EQ4 */
234 0x00, /* A4 DAI2 EQ4 */
235 0x00, /* A5 DAI2 EQ4 */
236 0x00, /* A6 DAI2 EQ4 */
237 0x00, /* A7 DAI2 EQ4 */
238 0x00, /* A8 DAI2 EQ4 */
239 0x00, /* A9 DAI2 EQ4 */
240 0x00, /* AA DAI2 EQ4 */
241 0x00, /* AB DAI2 EQ4 */
242 0x00, /* AC DAI2 EQ5 */
243 0x00, /* AD DAI2 EQ5 */
244 0x00, /* AE DAI2 EQ5 */
245 0x00, /* AF DAI2 EQ5 */
246
247 0x00, /* B0 DAI2 EQ5 */
248 0x00, /* B1 DAI2 EQ5 */
249 0x00, /* B2 DAI2 EQ5 */
250 0x00, /* B3 DAI2 EQ5 */
251 0x00, /* B4 DAI2 EQ5 */
252 0x00, /* B5 DAI2 EQ5 */
253 0x00, /* B6 DAI1 biquad */
254 0x00, /* B7 DAI1 biquad */
255 0x00, /* B8 DAI1 biquad */
256 0x00, /* B9 DAI1 biquad */
257 0x00, /* BA DAI1 biquad */
258 0x00, /* BB DAI1 biquad */
259 0x00, /* BC DAI1 biquad */
260 0x00, /* BD DAI1 biquad */
261 0x00, /* BE DAI1 biquad */
262 0x00, /* BF DAI1 biquad */
263
264 0x00, /* C0 DAI2 biquad */
265 0x00, /* C1 DAI2 biquad */
266 0x00, /* C2 DAI2 biquad */
267 0x00, /* C3 DAI2 biquad */
268 0x00, /* C4 DAI2 biquad */
269 0x00, /* C5 DAI2 biquad */
270 0x00, /* C6 DAI2 biquad */
271 0x00, /* C7 DAI2 biquad */
272 0x00, /* C8 DAI2 biquad */
273 0x00, /* C9 DAI2 biquad */
274 0x00, /* CA */
275 0x00, /* CB */
276 0x00, /* CC */
277 0x00, /* CD */
278 0x00, /* CE */
279 0x00, /* CF */
280
281 0x00, /* D0 */
282 0x00, /* D1 */
283 0x00, /* D2 */
284 0x00, /* D3 */
285 0x00, /* D4 */
286 0x00, /* D5 */
287 0x00, /* D6 */
288 0x00, /* D7 */
289 0x00, /* D8 */
290 0x00, /* D9 */
291 0x00, /* DA */
292 0x70, /* DB */
293 0x00, /* DC */
294 0x00, /* DD */
295 0x00, /* DE */
296 0x00, /* DF */
297
298 0x00, /* E0 */
299 0x00, /* E1 */
300 0x00, /* E2 */
301 0x00, /* E3 */
302 0x00, /* E4 */
303 0x00, /* E5 */
304 0x00, /* E6 */
305 0x00, /* E7 */
306 0x00, /* E8 */
307 0x00, /* E9 */
308 0x00, /* EA */
309 0x00, /* EB */
310 0x00, /* EC */
311 0x00, /* ED */
312 0x00, /* EE */
313 0x00, /* EF */
314
315 0x00, /* F0 */
316 0x00, /* F1 */
317 0x00, /* F2 */
318 0x00, /* F3 */
319 0x00, /* F4 */
320 0x00, /* F5 */
321 0x00, /* F6 */
322 0x00, /* F7 */
323 0x00, /* F8 */
324 0x00, /* F9 */
325 0x00, /* FA */
326 0x00, /* FB */
327 0x00, /* FC */
328 0x00, /* FD */
329 0x00, /* FE */
330 0x00, /* FF */
331};
332
333static struct {
334 int readable;
335 int writable;
336 int vol;
337} max98088_access[M98088_REG_CNT] = {
338 { 0xFF, 0xFF, 1 }, /* 00 IRQ status */
339 { 0xFF, 0x00, 1 }, /* 01 MIC status */
340 { 0xFF, 0x00, 1 }, /* 02 jack status */
341 { 0x1F, 0x1F, 1 }, /* 03 battery voltage */
342 { 0xFF, 0xFF, 0 }, /* 04 */
343 { 0xFF, 0xFF, 0 }, /* 05 */
344 { 0xFF, 0xFF, 0 }, /* 06 */
345 { 0xFF, 0xFF, 0 }, /* 07 */
346 { 0xFF, 0xFF, 0 }, /* 08 */
347 { 0xFF, 0xFF, 0 }, /* 09 */
348 { 0xFF, 0xFF, 0 }, /* 0A */
349 { 0xFF, 0xFF, 0 }, /* 0B */
350 { 0xFF, 0xFF, 0 }, /* 0C */
351 { 0xFF, 0xFF, 0 }, /* 0D */
352 { 0xFF, 0xFF, 0 }, /* 0E */
353 { 0xFF, 0xFF, 0 }, /* 0F interrupt enable */
354
355 { 0xFF, 0xFF, 0 }, /* 10 master clock */
356 { 0xFF, 0xFF, 0 }, /* 11 DAI1 clock mode */
357 { 0xFF, 0xFF, 0 }, /* 12 DAI1 clock control */
358 { 0xFF, 0xFF, 0 }, /* 13 DAI1 clock control */
359 { 0xFF, 0xFF, 0 }, /* 14 DAI1 format */
360 { 0xFF, 0xFF, 0 }, /* 15 DAI1 clock */
361 { 0xFF, 0xFF, 0 }, /* 16 DAI1 config */
362 { 0xFF, 0xFF, 0 }, /* 17 DAI1 TDM */
363 { 0xFF, 0xFF, 0 }, /* 18 DAI1 filters */
364 { 0xFF, 0xFF, 0 }, /* 19 DAI2 clock mode */
365 { 0xFF, 0xFF, 0 }, /* 1A DAI2 clock control */
366 { 0xFF, 0xFF, 0 }, /* 1B DAI2 clock control */
367 { 0xFF, 0xFF, 0 }, /* 1C DAI2 format */
368 { 0xFF, 0xFF, 0 }, /* 1D DAI2 clock */
369 { 0xFF, 0xFF, 0 }, /* 1E DAI2 config */
370 { 0xFF, 0xFF, 0 }, /* 1F DAI2 TDM */
371
372 { 0xFF, 0xFF, 0 }, /* 20 DAI2 filters */
373 { 0xFF, 0xFF, 0 }, /* 21 data config */
374 { 0xFF, 0xFF, 0 }, /* 22 DAC mixer */
375 { 0xFF, 0xFF, 0 }, /* 23 left ADC mixer */
376 { 0xFF, 0xFF, 0 }, /* 24 right ADC mixer */
377 { 0xFF, 0xFF, 0 }, /* 25 left HP mixer */
378 { 0xFF, 0xFF, 0 }, /* 26 right HP mixer */
379 { 0xFF, 0xFF, 0 }, /* 27 HP control */
380 { 0xFF, 0xFF, 0 }, /* 28 left REC mixer */
381 { 0xFF, 0xFF, 0 }, /* 29 right REC mixer */
382 { 0xFF, 0xFF, 0 }, /* 2A REC control */
383 { 0xFF, 0xFF, 0 }, /* 2B left SPK mixer */
384 { 0xFF, 0xFF, 0 }, /* 2C right SPK mixer */
385 { 0xFF, 0xFF, 0 }, /* 2D SPK control */
386 { 0xFF, 0xFF, 0 }, /* 2E sidetone */
387 { 0xFF, 0xFF, 0 }, /* 2F DAI1 playback level */
388
389 { 0xFF, 0xFF, 0 }, /* 30 DAI1 playback level */
390 { 0xFF, 0xFF, 0 }, /* 31 DAI2 playback level */
391 { 0xFF, 0xFF, 0 }, /* 32 DAI2 playbakc level */
392 { 0xFF, 0xFF, 0 }, /* 33 left ADC level */
393 { 0xFF, 0xFF, 0 }, /* 34 right ADC level */
394 { 0xFF, 0xFF, 0 }, /* 35 MIC1 level */
395 { 0xFF, 0xFF, 0 }, /* 36 MIC2 level */
396 { 0xFF, 0xFF, 0 }, /* 37 INA level */
397 { 0xFF, 0xFF, 0 }, /* 38 INB level */
398 { 0xFF, 0xFF, 0 }, /* 39 left HP volume */
399 { 0xFF, 0xFF, 0 }, /* 3A right HP volume */
400 { 0xFF, 0xFF, 0 }, /* 3B left REC volume */
401 { 0xFF, 0xFF, 0 }, /* 3C right REC volume */
402 { 0xFF, 0xFF, 0 }, /* 3D left SPK volume */
403 { 0xFF, 0xFF, 0 }, /* 3E right SPK volume */
404 { 0xFF, 0xFF, 0 }, /* 3F MIC config */
405
406 { 0xFF, 0xFF, 0 }, /* 40 MIC threshold */
407 { 0xFF, 0xFF, 0 }, /* 41 excursion limiter filter */
408 { 0xFF, 0xFF, 0 }, /* 42 excursion limiter threshold */
409 { 0xFF, 0xFF, 0 }, /* 43 ALC */
410 { 0xFF, 0xFF, 0 }, /* 44 power limiter threshold */
411 { 0xFF, 0xFF, 0 }, /* 45 power limiter config */
412 { 0xFF, 0xFF, 0 }, /* 46 distortion limiter config */
413 { 0xFF, 0xFF, 0 }, /* 47 audio input */
414 { 0xFF, 0xFF, 0 }, /* 48 microphone */
415 { 0xFF, 0xFF, 0 }, /* 49 level control */
416 { 0xFF, 0xFF, 0 }, /* 4A bypass switches */
417 { 0xFF, 0xFF, 0 }, /* 4B jack detect */
418 { 0xFF, 0xFF, 0 }, /* 4C input enable */
419 { 0xFF, 0xFF, 0 }, /* 4D output enable */
420 { 0xFF, 0xFF, 0 }, /* 4E bias control */
421 { 0xFF, 0xFF, 0 }, /* 4F DAC power */
422
423 { 0xFF, 0xFF, 0 }, /* 50 DAC power */
424 { 0xFF, 0xFF, 0 }, /* 51 system */
425 { 0xFF, 0xFF, 0 }, /* 52 DAI1 EQ1 */
426 { 0xFF, 0xFF, 0 }, /* 53 DAI1 EQ1 */
427 { 0xFF, 0xFF, 0 }, /* 54 DAI1 EQ1 */
428 { 0xFF, 0xFF, 0 }, /* 55 DAI1 EQ1 */
429 { 0xFF, 0xFF, 0 }, /* 56 DAI1 EQ1 */
430 { 0xFF, 0xFF, 0 }, /* 57 DAI1 EQ1 */
431 { 0xFF, 0xFF, 0 }, /* 58 DAI1 EQ1 */
432 { 0xFF, 0xFF, 0 }, /* 59 DAI1 EQ1 */
433 { 0xFF, 0xFF, 0 }, /* 5A DAI1 EQ1 */
434 { 0xFF, 0xFF, 0 }, /* 5B DAI1 EQ1 */
435 { 0xFF, 0xFF, 0 }, /* 5C DAI1 EQ2 */
436 { 0xFF, 0xFF, 0 }, /* 5D DAI1 EQ2 */
437 { 0xFF, 0xFF, 0 }, /* 5E DAI1 EQ2 */
438 { 0xFF, 0xFF, 0 }, /* 5F DAI1 EQ2 */
439
440 { 0xFF, 0xFF, 0 }, /* 60 DAI1 EQ2 */
441 { 0xFF, 0xFF, 0 }, /* 61 DAI1 EQ2 */
442 { 0xFF, 0xFF, 0 }, /* 62 DAI1 EQ2 */
443 { 0xFF, 0xFF, 0 }, /* 63 DAI1 EQ2 */
444 { 0xFF, 0xFF, 0 }, /* 64 DAI1 EQ2 */
445 { 0xFF, 0xFF, 0 }, /* 65 DAI1 EQ2 */
446 { 0xFF, 0xFF, 0 }, /* 66 DAI1 EQ3 */
447 { 0xFF, 0xFF, 0 }, /* 67 DAI1 EQ3 */
448 { 0xFF, 0xFF, 0 }, /* 68 DAI1 EQ3 */
449 { 0xFF, 0xFF, 0 }, /* 69 DAI1 EQ3 */
450 { 0xFF, 0xFF, 0 }, /* 6A DAI1 EQ3 */
451 { 0xFF, 0xFF, 0 }, /* 6B DAI1 EQ3 */
452 { 0xFF, 0xFF, 0 }, /* 6C DAI1 EQ3 */
453 { 0xFF, 0xFF, 0 }, /* 6D DAI1 EQ3 */
454 { 0xFF, 0xFF, 0 }, /* 6E DAI1 EQ3 */
455 { 0xFF, 0xFF, 0 }, /* 6F DAI1 EQ3 */
456
457 { 0xFF, 0xFF, 0 }, /* 70 DAI1 EQ4 */
458 { 0xFF, 0xFF, 0 }, /* 71 DAI1 EQ4 */
459 { 0xFF, 0xFF, 0 }, /* 72 DAI1 EQ4 */
460 { 0xFF, 0xFF, 0 }, /* 73 DAI1 EQ4 */
461 { 0xFF, 0xFF, 0 }, /* 74 DAI1 EQ4 */
462 { 0xFF, 0xFF, 0 }, /* 75 DAI1 EQ4 */
463 { 0xFF, 0xFF, 0 }, /* 76 DAI1 EQ4 */
464 { 0xFF, 0xFF, 0 }, /* 77 DAI1 EQ4 */
465 { 0xFF, 0xFF, 0 }, /* 78 DAI1 EQ4 */
466 { 0xFF, 0xFF, 0 }, /* 79 DAI1 EQ4 */
467 { 0xFF, 0xFF, 0 }, /* 7A DAI1 EQ5 */
468 { 0xFF, 0xFF, 0 }, /* 7B DAI1 EQ5 */
469 { 0xFF, 0xFF, 0 }, /* 7C DAI1 EQ5 */
470 { 0xFF, 0xFF, 0 }, /* 7D DAI1 EQ5 */
471 { 0xFF, 0xFF, 0 }, /* 7E DAI1 EQ5 */
472 { 0xFF, 0xFF, 0 }, /* 7F DAI1 EQ5 */
473
474 { 0xFF, 0xFF, 0 }, /* 80 DAI1 EQ5 */
475 { 0xFF, 0xFF, 0 }, /* 81 DAI1 EQ5 */
476 { 0xFF, 0xFF, 0 }, /* 82 DAI1 EQ5 */
477 { 0xFF, 0xFF, 0 }, /* 83 DAI1 EQ5 */
478 { 0xFF, 0xFF, 0 }, /* 84 DAI2 EQ1 */
479 { 0xFF, 0xFF, 0 }, /* 85 DAI2 EQ1 */
480 { 0xFF, 0xFF, 0 }, /* 86 DAI2 EQ1 */
481 { 0xFF, 0xFF, 0 }, /* 87 DAI2 EQ1 */
482 { 0xFF, 0xFF, 0 }, /* 88 DAI2 EQ1 */
483 { 0xFF, 0xFF, 0 }, /* 89 DAI2 EQ1 */
484 { 0xFF, 0xFF, 0 }, /* 8A DAI2 EQ1 */
485 { 0xFF, 0xFF, 0 }, /* 8B DAI2 EQ1 */
486 { 0xFF, 0xFF, 0 }, /* 8C DAI2 EQ1 */
487 { 0xFF, 0xFF, 0 }, /* 8D DAI2 EQ1 */
488 { 0xFF, 0xFF, 0 }, /* 8E DAI2 EQ2 */
489 { 0xFF, 0xFF, 0 }, /* 8F DAI2 EQ2 */
490
491 { 0xFF, 0xFF, 0 }, /* 90 DAI2 EQ2 */
492 { 0xFF, 0xFF, 0 }, /* 91 DAI2 EQ2 */
493 { 0xFF, 0xFF, 0 }, /* 92 DAI2 EQ2 */
494 { 0xFF, 0xFF, 0 }, /* 93 DAI2 EQ2 */
495 { 0xFF, 0xFF, 0 }, /* 94 DAI2 EQ2 */
496 { 0xFF, 0xFF, 0 }, /* 95 DAI2 EQ2 */
497 { 0xFF, 0xFF, 0 }, /* 96 DAI2 EQ2 */
498 { 0xFF, 0xFF, 0 }, /* 97 DAI2 EQ2 */
499 { 0xFF, 0xFF, 0 }, /* 98 DAI2 EQ3 */
500 { 0xFF, 0xFF, 0 }, /* 99 DAI2 EQ3 */
501 { 0xFF, 0xFF, 0 }, /* 9A DAI2 EQ3 */
502 { 0xFF, 0xFF, 0 }, /* 9B DAI2 EQ3 */
503 { 0xFF, 0xFF, 0 }, /* 9C DAI2 EQ3 */
504 { 0xFF, 0xFF, 0 }, /* 9D DAI2 EQ3 */
505 { 0xFF, 0xFF, 0 }, /* 9E DAI2 EQ3 */
506 { 0xFF, 0xFF, 0 }, /* 9F DAI2 EQ3 */
507
508 { 0xFF, 0xFF, 0 }, /* A0 DAI2 EQ3 */
509 { 0xFF, 0xFF, 0 }, /* A1 DAI2 EQ3 */
510 { 0xFF, 0xFF, 0 }, /* A2 DAI2 EQ4 */
511 { 0xFF, 0xFF, 0 }, /* A3 DAI2 EQ4 */
512 { 0xFF, 0xFF, 0 }, /* A4 DAI2 EQ4 */
513 { 0xFF, 0xFF, 0 }, /* A5 DAI2 EQ4 */
514 { 0xFF, 0xFF, 0 }, /* A6 DAI2 EQ4 */
515 { 0xFF, 0xFF, 0 }, /* A7 DAI2 EQ4 */
516 { 0xFF, 0xFF, 0 }, /* A8 DAI2 EQ4 */
517 { 0xFF, 0xFF, 0 }, /* A9 DAI2 EQ4 */
518 { 0xFF, 0xFF, 0 }, /* AA DAI2 EQ4 */
519 { 0xFF, 0xFF, 0 }, /* AB DAI2 EQ4 */
520 { 0xFF, 0xFF, 0 }, /* AC DAI2 EQ5 */
521 { 0xFF, 0xFF, 0 }, /* AD DAI2 EQ5 */
522 { 0xFF, 0xFF, 0 }, /* AE DAI2 EQ5 */
523 { 0xFF, 0xFF, 0 }, /* AF DAI2 EQ5 */
524
525 { 0xFF, 0xFF, 0 }, /* B0 DAI2 EQ5 */
526 { 0xFF, 0xFF, 0 }, /* B1 DAI2 EQ5 */
527 { 0xFF, 0xFF, 0 }, /* B2 DAI2 EQ5 */
528 { 0xFF, 0xFF, 0 }, /* B3 DAI2 EQ5 */
529 { 0xFF, 0xFF, 0 }, /* B4 DAI2 EQ5 */
530 { 0xFF, 0xFF, 0 }, /* B5 DAI2 EQ5 */
531 { 0xFF, 0xFF, 0 }, /* B6 DAI1 biquad */
532 { 0xFF, 0xFF, 0 }, /* B7 DAI1 biquad */
533 { 0xFF, 0xFF, 0 }, /* B8 DAI1 biquad */
534 { 0xFF, 0xFF, 0 }, /* B9 DAI1 biquad */
535 { 0xFF, 0xFF, 0 }, /* BA DAI1 biquad */
536 { 0xFF, 0xFF, 0 }, /* BB DAI1 biquad */
537 { 0xFF, 0xFF, 0 }, /* BC DAI1 biquad */
538 { 0xFF, 0xFF, 0 }, /* BD DAI1 biquad */
539 { 0xFF, 0xFF, 0 }, /* BE DAI1 biquad */
540 { 0xFF, 0xFF, 0 }, /* BF DAI1 biquad */
541
542 { 0xFF, 0xFF, 0 }, /* C0 DAI2 biquad */
543 { 0xFF, 0xFF, 0 }, /* C1 DAI2 biquad */
544 { 0xFF, 0xFF, 0 }, /* C2 DAI2 biquad */
545 { 0xFF, 0xFF, 0 }, /* C3 DAI2 biquad */
546 { 0xFF, 0xFF, 0 }, /* C4 DAI2 biquad */
547 { 0xFF, 0xFF, 0 }, /* C5 DAI2 biquad */
548 { 0xFF, 0xFF, 0 }, /* C6 DAI2 biquad */
549 { 0xFF, 0xFF, 0 }, /* C7 DAI2 biquad */
550 { 0xFF, 0xFF, 0 }, /* C8 DAI2 biquad */
551 { 0xFF, 0xFF, 0 }, /* C9 DAI2 biquad */
552 { 0x00, 0x00, 0 }, /* CA */
553 { 0x00, 0x00, 0 }, /* CB */
554 { 0x00, 0x00, 0 }, /* CC */
555 { 0x00, 0x00, 0 }, /* CD */
556 { 0x00, 0x00, 0 }, /* CE */
557 { 0x00, 0x00, 0 }, /* CF */
558
559 { 0x00, 0x00, 0 }, /* D0 */
560 { 0x00, 0x00, 0 }, /* D1 */
561 { 0x00, 0x00, 0 }, /* D2 */
562 { 0x00, 0x00, 0 }, /* D3 */
563 { 0x00, 0x00, 0 }, /* D4 */
564 { 0x00, 0x00, 0 }, /* D5 */
565 { 0x00, 0x00, 0 }, /* D6 */
566 { 0x00, 0x00, 0 }, /* D7 */
567 { 0x00, 0x00, 0 }, /* D8 */
568 { 0x00, 0x00, 0 }, /* D9 */
569 { 0x00, 0x00, 0 }, /* DA */
570 { 0x00, 0x00, 0 }, /* DB */
571 { 0x00, 0x00, 0 }, /* DC */
572 { 0x00, 0x00, 0 }, /* DD */
573 { 0x00, 0x00, 0 }, /* DE */
574 { 0x00, 0x00, 0 }, /* DF */
575
576 { 0x00, 0x00, 0 }, /* E0 */
577 { 0x00, 0x00, 0 }, /* E1 */
578 { 0x00, 0x00, 0 }, /* E2 */
579 { 0x00, 0x00, 0 }, /* E3 */
580 { 0x00, 0x00, 0 }, /* E4 */
581 { 0x00, 0x00, 0 }, /* E5 */
582 { 0x00, 0x00, 0 }, /* E6 */
583 { 0x00, 0x00, 0 }, /* E7 */
584 { 0x00, 0x00, 0 }, /* E8 */
585 { 0x00, 0x00, 0 }, /* E9 */
586 { 0x00, 0x00, 0 }, /* EA */
587 { 0x00, 0x00, 0 }, /* EB */
588 { 0x00, 0x00, 0 }, /* EC */
589 { 0x00, 0x00, 0 }, /* ED */
590 { 0x00, 0x00, 0 }, /* EE */
591 { 0x00, 0x00, 0 }, /* EF */
592
593 { 0x00, 0x00, 0 }, /* F0 */
594 { 0x00, 0x00, 0 }, /* F1 */
595 { 0x00, 0x00, 0 }, /* F2 */
596 { 0x00, 0x00, 0 }, /* F3 */
597 { 0x00, 0x00, 0 }, /* F4 */
598 { 0x00, 0x00, 0 }, /* F5 */
599 { 0x00, 0x00, 0 }, /* F6 */
600 { 0x00, 0x00, 0 }, /* F7 */
601 { 0x00, 0x00, 0 }, /* F8 */
602 { 0x00, 0x00, 0 }, /* F9 */
603 { 0x00, 0x00, 0 }, /* FA */
604 { 0x00, 0x00, 0 }, /* FB */
605 { 0x00, 0x00, 0 }, /* FC */
606 { 0x00, 0x00, 0 }, /* FD */
607 { 0x00, 0x00, 0 }, /* FE */
608 { 0xFF, 0x00, 1 }, /* FF */
609};
610
611static int max98088_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
612{
613 return max98088_access[reg].vol;
614}
615
616
617/*
618 * Load equalizer DSP coefficient configurations registers
619 */
620static void m98088_eq_band(struct snd_soc_codec *codec, unsigned int dai,
621 unsigned int band, u16 *coefs)
622{
623 unsigned int eq_reg;
624 unsigned int i;
625
626 BUG_ON(band > 4);
627 BUG_ON(dai > 1);
628
629 /* Load the base register address */
630 eq_reg = dai ? M98088_REG_84_DAI2_EQ_BASE : M98088_REG_52_DAI1_EQ_BASE;
631
632 /* Add the band address offset, note adjustment for word address */
633 eq_reg += band * (M98088_COEFS_PER_BAND << 1);
634
635 /* Step through the registers and coefs */
636 for (i = 0; i < M98088_COEFS_PER_BAND; i++) {
637 snd_soc_write(codec, eq_reg++, M98088_BYTE1(coefs[i]));
638 snd_soc_write(codec, eq_reg++, M98088_BYTE0(coefs[i]));
639 }
640}
641
642/*
643 * Excursion limiter modes
644 */
645static const char *max98088_exmode_texts[] = {
646 "Off", "100Hz", "400Hz", "600Hz", "800Hz", "1000Hz", "200-400Hz",
647 "400-600Hz", "400-800Hz",
648};
649
650static const unsigned int max98088_exmode_values[] = {
651 0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32
652};
653
654static const struct soc_enum max98088_exmode_enum =
655 SOC_VALUE_ENUM_SINGLE(M98088_REG_41_SPKDHP, 0, 127,
656 ARRAY_SIZE(max98088_exmode_texts),
657 max98088_exmode_texts,
658 max98088_exmode_values);
659
660static const char *max98088_ex_thresh[] = { /* volts PP */
661 "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};
662static const struct soc_enum max98088_ex_thresh_enum[] = {
663 SOC_ENUM_SINGLE(M98088_REG_42_SPKDHP_THRESH, 0, 8,
664 max98088_ex_thresh),
665};
666
667static const char *max98088_fltr_mode[] = {"Voice", "Music" };
668static const struct soc_enum max98088_filter_mode_enum[] = {
669 SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 7, 2, max98088_fltr_mode),
670};
671
672static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" };
673
674static const struct soc_enum max98088_extmic_enum =
675 SOC_ENUM_SINGLE(M98088_REG_48_CFG_MIC, 0, 3, max98088_extmic_text);
676
677static const struct snd_kcontrol_new max98088_extmic_mux =
678 SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum);
679
680static const char *max98088_dai1_fltr[] = {
681 "Off", "fc=258/fs=16k", "fc=500/fs=16k",
682 "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"};
683static const struct soc_enum max98088_dai1_dac_filter_enum[] = {
684 SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 0, 6, max98088_dai1_fltr),
685};
686static const struct soc_enum max98088_dai1_adc_filter_enum[] = {
687 SOC_ENUM_SINGLE(M98088_REG_18_DAI1_FILTERS, 4, 6, max98088_dai1_fltr),
688};
689
690static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,
691 struct snd_ctl_elem_value *ucontrol)
692{
693 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
694 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
695 unsigned int sel = ucontrol->value.integer.value[0];
696
697 max98088->mic1pre = sel;
698 snd_soc_update_bits(codec, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,
699 (1+sel)<<M98088_MICPRE_SHIFT);
700
701 return 0;
702}
703
704static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,
705 struct snd_ctl_elem_value *ucontrol)
706{
707 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
708 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
709
710 ucontrol->value.integer.value[0] = max98088->mic1pre;
711 return 0;
712}
713
714static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_value *ucontrol)
716{
717 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
718 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
719 unsigned int sel = ucontrol->value.integer.value[0];
720
721 max98088->mic2pre = sel;
722 snd_soc_update_bits(codec, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,
723 (1+sel)<<M98088_MICPRE_SHIFT);
724
725 return 0;
726}
727
728static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol,
729 struct snd_ctl_elem_value *ucontrol)
730{
731 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
732 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
733
734 ucontrol->value.integer.value[0] = max98088->mic2pre;
735 return 0;
736}
737
738static const unsigned int max98088_micboost_tlv[] = {
739 TLV_DB_RANGE_HEAD(2),
740 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
741 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
742};
743
744static const struct snd_kcontrol_new max98088_snd_controls[] = {
745
746 SOC_DOUBLE_R("Headphone Volume", M98088_REG_39_LVL_HP_L,
747 M98088_REG_3A_LVL_HP_R, 0, 31, 0),
748 SOC_DOUBLE_R("Speaker Volume", M98088_REG_3D_LVL_SPK_L,
749 M98088_REG_3E_LVL_SPK_R, 0, 31, 0),
750 SOC_DOUBLE_R("Receiver Volume", M98088_REG_3B_LVL_REC_L,
751 M98088_REG_3C_LVL_REC_R, 0, 31, 0),
752
753 SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L,
754 M98088_REG_3A_LVL_HP_R, 7, 1, 1),
755 SOC_DOUBLE_R("Speaker Switch", M98088_REG_3D_LVL_SPK_L,
756 M98088_REG_3E_LVL_SPK_R, 7, 1, 1),
757 SOC_DOUBLE_R("Receiver Switch", M98088_REG_3B_LVL_REC_L,
758 M98088_REG_3C_LVL_REC_R, 7, 1, 1),
759
760 SOC_SINGLE("MIC1 Volume", M98088_REG_35_LVL_MIC1, 0, 31, 1),
761 SOC_SINGLE("MIC2 Volume", M98088_REG_36_LVL_MIC2, 0, 31, 1),
762
763 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
764 M98088_REG_35_LVL_MIC1, 5, 2, 0,
765 max98088_mic1pre_get, max98088_mic1pre_set,
766 max98088_micboost_tlv),
767 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
768 M98088_REG_36_LVL_MIC2, 5, 2, 0,
769 max98088_mic2pre_get, max98088_mic2pre_set,
770 max98088_micboost_tlv),
771
772 SOC_SINGLE("INA Volume", M98088_REG_37_LVL_INA, 0, 7, 1),
773 SOC_SINGLE("INB Volume", M98088_REG_38_LVL_INB, 0, 7, 1),
774
775 SOC_SINGLE("ADCL Volume", M98088_REG_33_LVL_ADC_L, 0, 15, 0),
776 SOC_SINGLE("ADCR Volume", M98088_REG_34_LVL_ADC_R, 0, 15, 0),
777
778 SOC_SINGLE("ADCL Boost Volume", M98088_REG_33_LVL_ADC_L, 4, 3, 0),
779 SOC_SINGLE("ADCR Boost Volume", M98088_REG_34_LVL_ADC_R, 4, 3, 0),
780
781 SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0),
782 SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0),
783
784 SOC_ENUM("EX Limiter Mode", max98088_exmode_enum),
785 SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum),
786
787 SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum),
788 SOC_ENUM("DAI1 DAC Filter", max98088_dai1_dac_filter_enum),
789 SOC_ENUM("DAI1 ADC Filter", max98088_dai1_adc_filter_enum),
790 SOC_SINGLE("DAI2 DC Block Switch", M98088_REG_20_DAI2_FILTERS,
791 0, 1, 0),
792
793 SOC_SINGLE("ALC Switch", M98088_REG_43_SPKALC_COMP, 7, 1, 0),
794 SOC_SINGLE("ALC Threshold", M98088_REG_43_SPKALC_COMP, 0, 7, 0),
795 SOC_SINGLE("ALC Multiband", M98088_REG_43_SPKALC_COMP, 3, 1, 0),
796 SOC_SINGLE("ALC Release Time", M98088_REG_43_SPKALC_COMP, 4, 7, 0),
797
798 SOC_SINGLE("PWR Limiter Threshold", M98088_REG_44_PWRLMT_CFG,
799 4, 15, 0),
800 SOC_SINGLE("PWR Limiter Weight", M98088_REG_44_PWRLMT_CFG, 0, 7, 0),
801 SOC_SINGLE("PWR Limiter Time1", M98088_REG_45_PWRLMT_TIME, 0, 15, 0),
802 SOC_SINGLE("PWR Limiter Time2", M98088_REG_45_PWRLMT_TIME, 4, 15, 0),
803
804 SOC_SINGLE("THD Limiter Threshold", M98088_REG_46_THDLMT_CFG, 4, 15, 0),
805 SOC_SINGLE("THD Limiter Time", M98088_REG_46_THDLMT_CFG, 0, 7, 0),
806};
807
808/* Left speaker mixer switch */
809static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = {
810 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
811 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
812 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),
813 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),
814 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0),
815 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0),
816 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0),
817 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 2, 1, 0),
818 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 3, 1, 0),
819 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 4, 1, 0),
820};
821
822/* Right speaker mixer switch */
823static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = {
824 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0),
825 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0),
826 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0),
827 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0),
828 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 5, 1, 0),
829 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 6, 1, 0),
830 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 1, 1, 0),
831 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 2, 1, 0),
832 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 3, 1, 0),
833 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 4, 1, 0),
834};
835
836/* Left headphone mixer switch */
837static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = {
838 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
839 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
840 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),
841 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),
842 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0),
843 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0),
844 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0),
845 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_25_MIX_HP_LEFT, 2, 1, 0),
846 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_25_MIX_HP_LEFT, 3, 1, 0),
847 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_25_MIX_HP_LEFT, 4, 1, 0),
848};
849
850/* Right headphone mixer switch */
851static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = {
852 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0),
853 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0),
854 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0),
855 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0),
856 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 5, 1, 0),
857 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 6, 1, 0),
858 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_26_MIX_HP_RIGHT, 1, 1, 0),
859 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_26_MIX_HP_RIGHT, 2, 1, 0),
860 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_26_MIX_HP_RIGHT, 3, 1, 0),
861 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_26_MIX_HP_RIGHT, 4, 1, 0),
862};
863
864/* Left earpiece/receiver mixer switch */
865static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = {
866 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
867 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
868 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),
869 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),
870 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0),
871 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0),
872 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0),
873 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_28_MIX_REC_LEFT, 2, 1, 0),
874 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_28_MIX_REC_LEFT, 3, 1, 0),
875 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_28_MIX_REC_LEFT, 4, 1, 0),
876};
877
878/* Right earpiece/receiver mixer switch */
879static const struct snd_kcontrol_new max98088_right_rec_mixer_controls[] = {
880 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0),
881 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0),
882 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0),
883 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0),
884 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 5, 1, 0),
885 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 6, 1, 0),
886 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_29_MIX_REC_RIGHT, 1, 1, 0),
887 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_29_MIX_REC_RIGHT, 2, 1, 0),
888 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_29_MIX_REC_RIGHT, 3, 1, 0),
889 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_29_MIX_REC_RIGHT, 4, 1, 0),
890};
891
892/* Left ADC mixer switch */
893static const struct snd_kcontrol_new max98088_left_ADC_mixer_controls[] = {
894 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_23_MIX_ADC_LEFT, 7, 1, 0),
895 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_23_MIX_ADC_LEFT, 6, 1, 0),
896 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_23_MIX_ADC_LEFT, 3, 1, 0),
897 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_23_MIX_ADC_LEFT, 2, 1, 0),
898 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_23_MIX_ADC_LEFT, 1, 1, 0),
899 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_23_MIX_ADC_LEFT, 0, 1, 0),
900};
901
902/* Right ADC mixer switch */
903static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = {
904 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 7, 1, 0),
905 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 6, 1, 0),
906 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 3, 1, 0),
907 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 2, 1, 0),
908 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 1, 1, 0),
909 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 0, 1, 0),
910};
911
912static int max98088_mic_event(struct snd_soc_dapm_widget *w,
913 struct snd_kcontrol *kcontrol, int event)
914{
915 struct snd_soc_codec *codec = w->codec;
916 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
917
918 switch (event) {
919 case SND_SOC_DAPM_POST_PMU:
920 if (w->reg == M98088_REG_35_LVL_MIC1) {
921 snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
922 (1+max98088->mic1pre)<<M98088_MICPRE_SHIFT);
923 } else {
924 snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK,
925 (1+max98088->mic2pre)<<M98088_MICPRE_SHIFT);
926 }
927 break;
928 case SND_SOC_DAPM_POST_PMD:
929 snd_soc_update_bits(codec, w->reg, M98088_MICPRE_MASK, 0);
930 break;
931 default:
932 return -EINVAL;
933 }
934
935 return 0;
936}
937
938/*
939 * The line inputs are 2-channel stereo inputs with the left
940 * and right channels sharing a common PGA power control signal.
941 */
942static int max98088_line_pga(struct snd_soc_dapm_widget *w,
943 int event, int line, u8 channel)
944{
945 struct snd_soc_codec *codec = w->codec;
946 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
947 u8 *state;
948
949 BUG_ON(!((channel == 1) || (channel == 2)));
950
951 switch (line) {
952 case LINE_INA:
953 state = &max98088->ina_state;
954 break;
955 case LINE_INB:
956 state = &max98088->inb_state;
957 break;
958 default:
959 return -EINVAL;
960 }
961
962 switch (event) {
963 case SND_SOC_DAPM_POST_PMU:
964 *state |= channel;
965 snd_soc_update_bits(codec, w->reg,
966 (1 << w->shift), (1 << w->shift));
967 break;
968 case SND_SOC_DAPM_POST_PMD:
969 *state &= ~channel;
970 if (*state == 0) {
971 snd_soc_update_bits(codec, w->reg,
972 (1 << w->shift), 0);
973 }
974 break;
975 default:
976 return -EINVAL;
977 }
978
979 return 0;
980}
981
982static int max98088_pga_ina1_event(struct snd_soc_dapm_widget *w,
983 struct snd_kcontrol *k, int event)
984{
985 return max98088_line_pga(w, event, LINE_INA, 1);
986}
987
988static int max98088_pga_ina2_event(struct snd_soc_dapm_widget *w,
989 struct snd_kcontrol *k, int event)
990{
991 return max98088_line_pga(w, event, LINE_INA, 2);
992}
993
994static int max98088_pga_inb1_event(struct snd_soc_dapm_widget *w,
995 struct snd_kcontrol *k, int event)
996{
997 return max98088_line_pga(w, event, LINE_INB, 1);
998}
999
1000static int max98088_pga_inb2_event(struct snd_soc_dapm_widget *w,
1001 struct snd_kcontrol *k, int event)
1002{
1003 return max98088_line_pga(w, event, LINE_INB, 2);
1004}
1005
1006static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {
1007
1008 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 1, 0),
1009 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 0, 0),
1010
1011 SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
1012 M98088_REG_4D_PWR_EN_OUT, 1, 0),
1013 SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
1014 M98088_REG_4D_PWR_EN_OUT, 0, 0),
1015 SND_SOC_DAPM_DAC("DACL2", "Aux Playback",
1016 M98088_REG_4D_PWR_EN_OUT, 1, 0),
1017 SND_SOC_DAPM_DAC("DACR2", "Aux Playback",
1018 M98088_REG_4D_PWR_EN_OUT, 0, 0),
1019
1020 SND_SOC_DAPM_PGA("HP Left Out", M98088_REG_4D_PWR_EN_OUT,
1021 7, 0, NULL, 0),
1022 SND_SOC_DAPM_PGA("HP Right Out", M98088_REG_4D_PWR_EN_OUT,
1023 6, 0, NULL, 0),
1024
1025 SND_SOC_DAPM_PGA("SPK Left Out", M98088_REG_4D_PWR_EN_OUT,
1026 5, 0, NULL, 0),
1027 SND_SOC_DAPM_PGA("SPK Right Out", M98088_REG_4D_PWR_EN_OUT,
1028 4, 0, NULL, 0),
1029
1030 SND_SOC_DAPM_PGA("REC Left Out", M98088_REG_4D_PWR_EN_OUT,
1031 3, 0, NULL, 0),
1032 SND_SOC_DAPM_PGA("REC Right Out", M98088_REG_4D_PWR_EN_OUT,
1033 2, 0, NULL, 0),
1034
1035 SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
1036 &max98088_extmic_mux),
1037
1038 SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
1039 &max98088_left_hp_mixer_controls[0],
1040 ARRAY_SIZE(max98088_left_hp_mixer_controls)),
1041
1042 SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
1043 &max98088_right_hp_mixer_controls[0],
1044 ARRAY_SIZE(max98088_right_hp_mixer_controls)),
1045
1046 SND_SOC_DAPM_MIXER("Left SPK Mixer", SND_SOC_NOPM, 0, 0,
1047 &max98088_left_speaker_mixer_controls[0],
1048 ARRAY_SIZE(max98088_left_speaker_mixer_controls)),
1049
1050 SND_SOC_DAPM_MIXER("Right SPK Mixer", SND_SOC_NOPM, 0, 0,
1051 &max98088_right_speaker_mixer_controls[0],
1052 ARRAY_SIZE(max98088_right_speaker_mixer_controls)),
1053
1054 SND_SOC_DAPM_MIXER("Left REC Mixer", SND_SOC_NOPM, 0, 0,
1055 &max98088_left_rec_mixer_controls[0],
1056 ARRAY_SIZE(max98088_left_rec_mixer_controls)),
1057
1058 SND_SOC_DAPM_MIXER("Right REC Mixer", SND_SOC_NOPM, 0, 0,
1059 &max98088_right_rec_mixer_controls[0],
1060 ARRAY_SIZE(max98088_right_rec_mixer_controls)),
1061
1062 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1063 &max98088_left_ADC_mixer_controls[0],
1064 ARRAY_SIZE(max98088_left_ADC_mixer_controls)),
1065
1066 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1067 &max98088_right_ADC_mixer_controls[0],
1068 ARRAY_SIZE(max98088_right_ADC_mixer_controls)),
1069
1070 SND_SOC_DAPM_PGA_E("MIC1 Input", M98088_REG_35_LVL_MIC1,
1071 5, 0, NULL, 0, max98088_mic_event,
1072 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1073
1074 SND_SOC_DAPM_PGA_E("MIC2 Input", M98088_REG_36_LVL_MIC2,
1075 5, 0, NULL, 0, max98088_mic_event,
1076 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1077
1078 SND_SOC_DAPM_PGA_E("INA1 Input", M98088_REG_4C_PWR_EN_IN,
1079 7, 0, NULL, 0, max98088_pga_ina1_event,
1080 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1081
1082 SND_SOC_DAPM_PGA_E("INA2 Input", M98088_REG_4C_PWR_EN_IN,
1083 7, 0, NULL, 0, max98088_pga_ina2_event,
1084 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1085
1086 SND_SOC_DAPM_PGA_E("INB1 Input", M98088_REG_4C_PWR_EN_IN,
1087 6, 0, NULL, 0, max98088_pga_inb1_event,
1088 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1089
1090 SND_SOC_DAPM_PGA_E("INB2 Input", M98088_REG_4C_PWR_EN_IN,
1091 6, 0, NULL, 0, max98088_pga_inb2_event,
1092 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1093
1094 SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0),
1095
1096 SND_SOC_DAPM_OUTPUT("HPL"),
1097 SND_SOC_DAPM_OUTPUT("HPR"),
1098 SND_SOC_DAPM_OUTPUT("SPKL"),
1099 SND_SOC_DAPM_OUTPUT("SPKR"),
1100 SND_SOC_DAPM_OUTPUT("RECL"),
1101 SND_SOC_DAPM_OUTPUT("RECR"),
1102
1103 SND_SOC_DAPM_INPUT("MIC1"),
1104 SND_SOC_DAPM_INPUT("MIC2"),
1105 SND_SOC_DAPM_INPUT("INA1"),
1106 SND_SOC_DAPM_INPUT("INA2"),
1107 SND_SOC_DAPM_INPUT("INB1"),
1108 SND_SOC_DAPM_INPUT("INB2"),
1109};
1110
1111static const struct snd_soc_dapm_route max98088_audio_map[] = {
1112 /* Left headphone output mixer */
1113 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"},
1114 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"},
1115 {"Left HP Mixer", "Right DAC1 Switch", "DACR1"},
1116 {"Left HP Mixer", "Right DAC2 Switch", "DACR2"},
1117 {"Left HP Mixer", "MIC1 Switch", "MIC1 Input"},
1118 {"Left HP Mixer", "MIC2 Switch", "MIC2 Input"},
1119 {"Left HP Mixer", "INA1 Switch", "INA1 Input"},
1120 {"Left HP Mixer", "INA2 Switch", "INA2 Input"},
1121 {"Left HP Mixer", "INB1 Switch", "INB1 Input"},
1122 {"Left HP Mixer", "INB2 Switch", "INB2 Input"},
1123
1124 /* Right headphone output mixer */
1125 {"Right HP Mixer", "Left DAC1 Switch", "DACL1"},
1126 {"Right HP Mixer", "Left DAC2 Switch", "DACL2" },
1127 {"Right HP Mixer", "Right DAC1 Switch", "DACR1"},
1128 {"Right HP Mixer", "Right DAC2 Switch", "DACR2"},
1129 {"Right HP Mixer", "MIC1 Switch", "MIC1 Input"},
1130 {"Right HP Mixer", "MIC2 Switch", "MIC2 Input"},
1131 {"Right HP Mixer", "INA1 Switch", "INA1 Input"},
1132 {"Right HP Mixer", "INA2 Switch", "INA2 Input"},
1133 {"Right HP Mixer", "INB1 Switch", "INB1 Input"},
1134 {"Right HP Mixer", "INB2 Switch", "INB2 Input"},
1135
1136 /* Left speaker output mixer */
1137 {"Left SPK Mixer", "Left DAC1 Switch", "DACL1"},
1138 {"Left SPK Mixer", "Left DAC2 Switch", "DACL2"},
1139 {"Left SPK Mixer", "Right DAC1 Switch", "DACR1"},
1140 {"Left SPK Mixer", "Right DAC2 Switch", "DACR2"},
1141 {"Left SPK Mixer", "MIC1 Switch", "MIC1 Input"},
1142 {"Left SPK Mixer", "MIC2 Switch", "MIC2 Input"},
1143 {"Left SPK Mixer", "INA1 Switch", "INA1 Input"},
1144 {"Left SPK Mixer", "INA2 Switch", "INA2 Input"},
1145 {"Left SPK Mixer", "INB1 Switch", "INB1 Input"},
1146 {"Left SPK Mixer", "INB2 Switch", "INB2 Input"},
1147
1148 /* Right speaker output mixer */
1149 {"Right SPK Mixer", "Left DAC1 Switch", "DACL1"},
1150 {"Right SPK Mixer", "Left DAC2 Switch", "DACL2"},
1151 {"Right SPK Mixer", "Right DAC1 Switch", "DACR1"},
1152 {"Right SPK Mixer", "Right DAC2 Switch", "DACR2"},
1153 {"Right SPK Mixer", "MIC1 Switch", "MIC1 Input"},
1154 {"Right SPK Mixer", "MIC2 Switch", "MIC2 Input"},
1155 {"Right SPK Mixer", "INA1 Switch", "INA1 Input"},
1156 {"Right SPK Mixer", "INA2 Switch", "INA2 Input"},
1157 {"Right SPK Mixer", "INB1 Switch", "INB1 Input"},
1158 {"Right SPK Mixer", "INB2 Switch", "INB2 Input"},
1159
1160 /* Earpiece/Receiver output mixer */
1161 {"Left REC Mixer", "Left DAC1 Switch", "DACL1"},
1162 {"Left REC Mixer", "Left DAC2 Switch", "DACL2"},
1163 {"Left REC Mixer", "Right DAC1 Switch", "DACR1"},
1164 {"Left REC Mixer", "Right DAC2 Switch", "DACR2"},
1165 {"Left REC Mixer", "MIC1 Switch", "MIC1 Input"},
1166 {"Left REC Mixer", "MIC2 Switch", "MIC2 Input"},
1167 {"Left REC Mixer", "INA1 Switch", "INA1 Input"},
1168 {"Left REC Mixer", "INA2 Switch", "INA2 Input"},
1169 {"Left REC Mixer", "INB1 Switch", "INB1 Input"},
1170 {"Left REC Mixer", "INB2 Switch", "INB2 Input"},
1171
1172 /* Earpiece/Receiver output mixer */
1173 {"Right REC Mixer", "Left DAC1 Switch", "DACL1"},
1174 {"Right REC Mixer", "Left DAC2 Switch", "DACL2"},
1175 {"Right REC Mixer", "Right DAC1 Switch", "DACR1"},
1176 {"Right REC Mixer", "Right DAC2 Switch", "DACR2"},
1177 {"Right REC Mixer", "MIC1 Switch", "MIC1 Input"},
1178 {"Right REC Mixer", "MIC2 Switch", "MIC2 Input"},
1179 {"Right REC Mixer", "INA1 Switch", "INA1 Input"},
1180 {"Right REC Mixer", "INA2 Switch", "INA2 Input"},
1181 {"Right REC Mixer", "INB1 Switch", "INB1 Input"},
1182 {"Right REC Mixer", "INB2 Switch", "INB2 Input"},
1183
1184 {"HP Left Out", NULL, "Left HP Mixer"},
1185 {"HP Right Out", NULL, "Right HP Mixer"},
1186 {"SPK Left Out", NULL, "Left SPK Mixer"},
1187 {"SPK Right Out", NULL, "Right SPK Mixer"},
1188 {"REC Left Out", NULL, "Left REC Mixer"},
1189 {"REC Right Out", NULL, "Right REC Mixer"},
1190
1191 {"HPL", NULL, "HP Left Out"},
1192 {"HPR", NULL, "HP Right Out"},
1193 {"SPKL", NULL, "SPK Left Out"},
1194 {"SPKR", NULL, "SPK Right Out"},
1195 {"RECL", NULL, "REC Left Out"},
1196 {"RECR", NULL, "REC Right Out"},
1197
1198 /* Left ADC input mixer */
1199 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1200 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1201 {"Left ADC Mixer", "INA1 Switch", "INA1 Input"},
1202 {"Left ADC Mixer", "INA2 Switch", "INA2 Input"},
1203 {"Left ADC Mixer", "INB1 Switch", "INB1 Input"},
1204 {"Left ADC Mixer", "INB2 Switch", "INB2 Input"},
1205
1206 /* Right ADC input mixer */
1207 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1208 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1209 {"Right ADC Mixer", "INA1 Switch", "INA1 Input"},
1210 {"Right ADC Mixer", "INA2 Switch", "INA2 Input"},
1211 {"Right ADC Mixer", "INB1 Switch", "INB1 Input"},
1212 {"Right ADC Mixer", "INB2 Switch", "INB2 Input"},
1213
1214 /* Inputs */
1215 {"ADCL", NULL, "Left ADC Mixer"},
1216 {"ADCR", NULL, "Right ADC Mixer"},
1217 {"INA1 Input", NULL, "INA1"},
1218 {"INA2 Input", NULL, "INA2"},
1219 {"INB1 Input", NULL, "INB1"},
1220 {"INB2 Input", NULL, "INB2"},
1221 {"MIC1 Input", NULL, "MIC1"},
1222 {"MIC2 Input", NULL, "MIC2"},
1223};
1224
1225/* codec mclk clock divider coefficients */
1226static const struct {
1227 u32 rate;
1228 u8 sr;
1229} rate_table[] = {
1230 {8000, 0x10},
1231 {11025, 0x20},
1232 {16000, 0x30},
1233 {22050, 0x40},
1234 {24000, 0x50},
1235 {32000, 0x60},
1236 {44100, 0x70},
1237 {48000, 0x80},
1238 {88200, 0x90},
1239 {96000, 0xA0},
1240};
1241
1242static inline int rate_value(int rate, u8 *value)
1243{
1244 int i;
1245
1246 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
1247 if (rate_table[i].rate >= rate) {
1248 *value = rate_table[i].sr;
1249 return 0;
1250 }
1251 }
1252 *value = rate_table[0].sr;
1253 return -EINVAL;
1254}
1255
1256static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
1257 struct snd_pcm_hw_params *params,
1258 struct snd_soc_dai *dai)
1259{
1260 struct snd_soc_codec *codec = dai->codec;
1261 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1262 struct max98088_cdata *cdata;
1263 unsigned long long ni;
1264 unsigned int rate;
1265 u8 regval;
1266
1267 cdata = &max98088->dai[0];
1268
1269 rate = params_rate(params);
1270
1271 switch (params_format(params)) {
1272 case SNDRV_PCM_FORMAT_S16_LE:
1273 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
1274 M98088_DAI_WS, 0);
1275 break;
1276 case SNDRV_PCM_FORMAT_S24_LE:
1277 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
1278 M98088_DAI_WS, M98088_DAI_WS);
1279 break;
1280 default:
1281 return -EINVAL;
1282 }
1283
1284 snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
1285
1286 if (rate_value(rate, &regval))
1287 return -EINVAL;
1288
1289 snd_soc_update_bits(codec, M98088_REG_11_DAI1_CLKMODE,
1290 M98088_CLKMODE_MASK, regval);
1291 cdata->rate = rate;
1292
1293 /* Configure NI when operating as master */
1294 if (snd_soc_read(codec, M98088_REG_14_DAI1_FORMAT)
1295 & M98088_DAI_MAS) {
1296 if (max98088->sysclk == 0) {
1297 dev_err(codec->dev, "Invalid system clock frequency\n");
1298 return -EINVAL;
1299 }
1300 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1301 * (unsigned long long int)rate;
1302 do_div(ni, (unsigned long long int)max98088->sysclk);
1303 snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
1304 (ni >> 8) & 0x7F);
1305 snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
1306 ni & 0xFF);
1307 }
1308
1309 /* Update sample rate mode */
1310 if (rate < 50000)
1311 snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
1312 M98088_DAI_DHF, 0);
1313 else
1314 snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
1315 M98088_DAI_DHF, M98088_DAI_DHF);
1316
1317 snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
1318 M98088_SHDNRUN);
1319
1320 return 0;
1321}
1322
1323static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
1324 struct snd_pcm_hw_params *params,
1325 struct snd_soc_dai *dai)
1326{
1327 struct snd_soc_codec *codec = dai->codec;
1328 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1329 struct max98088_cdata *cdata;
1330 unsigned long long ni;
1331 unsigned int rate;
1332 u8 regval;
1333
1334 cdata = &max98088->dai[1];
1335
1336 rate = params_rate(params);
1337
1338 switch (params_format(params)) {
1339 case SNDRV_PCM_FORMAT_S16_LE:
1340 snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
1341 M98088_DAI_WS, 0);
1342 break;
1343 case SNDRV_PCM_FORMAT_S24_LE:
1344 snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
1345 M98088_DAI_WS, M98088_DAI_WS);
1346 break;
1347 default:
1348 return -EINVAL;
1349 }
1350
1351 snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);
1352
1353 if (rate_value(rate, &regval))
1354 return -EINVAL;
1355
1356 snd_soc_update_bits(codec, M98088_REG_19_DAI2_CLKMODE,
1357 M98088_CLKMODE_MASK, regval);
1358 cdata->rate = rate;
1359
1360 /* Configure NI when operating as master */
1361 if (snd_soc_read(codec, M98088_REG_1C_DAI2_FORMAT)
1362 & M98088_DAI_MAS) {
1363 if (max98088->sysclk == 0) {
1364 dev_err(codec->dev, "Invalid system clock frequency\n");
1365 return -EINVAL;
1366 }
1367 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1368 * (unsigned long long int)rate;
1369 do_div(ni, (unsigned long long int)max98088->sysclk);
1370 snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
1371 (ni >> 8) & 0x7F);
1372 snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
1373 ni & 0xFF);
1374 }
1375
1376 /* Update sample rate mode */
1377 if (rate < 50000)
1378 snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
1379 M98088_DAI_DHF, 0);
1380 else
1381 snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
1382 M98088_DAI_DHF, M98088_DAI_DHF);
1383
1384 snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
1385 M98088_SHDNRUN);
1386
1387 return 0;
1388}
1389
1390static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,
1391 int clk_id, unsigned int freq, int dir)
1392{
1393 struct snd_soc_codec *codec = dai->codec;
1394 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1395
1396 /* Requested clock frequency is already setup */
1397 if (freq == max98088->sysclk)
1398 return 0;
1399
1400 max98088->sysclk = freq; /* remember current sysclk */
1401
1402 /* Setup clocks for slave mode, and using the PLL
1403 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1404 * 0x02 (when master clk is 20MHz to 30MHz)..
1405 */
1406 if ((freq >= 10000000) && (freq < 20000000)) {
1407 snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x10);
1408 } else if ((freq >= 20000000) && (freq < 30000000)) {
1409 snd_soc_write(codec, M98088_REG_10_SYS_CLK, 0x20);
1410 } else {
1411 dev_err(codec->dev, "Invalid master clock frequency\n");
1412 return -EINVAL;
1413 }
1414
1415 if (snd_soc_read(codec, M98088_REG_51_PWR_SYS) & M98088_SHDNRUN) {
1416 snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
1417 M98088_SHDNRUN, 0);
1418 snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
1419 M98088_SHDNRUN, M98088_SHDNRUN);
1420 }
1421
1422 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1423
1424 max98088->sysclk = freq;
1425 return 0;
1426}
1427
1428static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
1429 unsigned int fmt)
1430{
1431 struct snd_soc_codec *codec = codec_dai->codec;
1432 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1433 struct max98088_cdata *cdata;
1434 u8 reg15val;
1435 u8 reg14val = 0;
1436
1437 cdata = &max98088->dai[0];
1438
1439 if (fmt != cdata->fmt) {
1440 cdata->fmt = fmt;
1441
1442 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1443 case SND_SOC_DAIFMT_CBS_CFS:
1444 /* Slave mode PLL */
1445 snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
1446 0x80);
1447 snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
1448 0x00);
1449 break;
1450 case SND_SOC_DAIFMT_CBM_CFM:
1451 /* Set to master mode */
1452 reg14val |= M98088_DAI_MAS;
1453 break;
1454 case SND_SOC_DAIFMT_CBS_CFM:
1455 case SND_SOC_DAIFMT_CBM_CFS:
1456 default:
1457 dev_err(codec->dev, "Clock mode unsupported");
1458 return -EINVAL;
1459 }
1460
1461 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1462 case SND_SOC_DAIFMT_I2S:
1463 reg14val |= M98088_DAI_DLY;
1464 break;
1465 case SND_SOC_DAIFMT_LEFT_J:
1466 break;
1467 default:
1468 return -EINVAL;
1469 }
1470
1471 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1472 case SND_SOC_DAIFMT_NB_NF:
1473 break;
1474 case SND_SOC_DAIFMT_NB_IF:
1475 reg14val |= M98088_DAI_WCI;
1476 break;
1477 case SND_SOC_DAIFMT_IB_NF:
1478 reg14val |= M98088_DAI_BCI;
1479 break;
1480 case SND_SOC_DAIFMT_IB_IF:
1481 reg14val |= M98088_DAI_BCI|M98088_DAI_WCI;
1482 break;
1483 default:
1484 return -EINVAL;
1485 }
1486
1487 snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
1488 M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
1489 M98088_DAI_WCI, reg14val);
1490
1491 reg15val = M98088_DAI_BSEL64;
1492 if (max98088->digmic)
1493 reg15val |= M98088_DAI_OSR64;
1494 snd_soc_write(codec, M98088_REG_15_DAI1_CLOCK, reg15val);
1495 }
1496
1497 return 0;
1498}
1499
1500static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1501 unsigned int fmt)
1502{
1503 struct snd_soc_codec *codec = codec_dai->codec;
1504 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1505 struct max98088_cdata *cdata;
1506 u8 reg1Cval = 0;
1507
1508 cdata = &max98088->dai[1];
1509
1510 if (fmt != cdata->fmt) {
1511 cdata->fmt = fmt;
1512
1513 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1514 case SND_SOC_DAIFMT_CBS_CFS:
1515 /* Slave mode PLL */
1516 snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
1517 0x80);
1518 snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
1519 0x00);
1520 break;
1521 case SND_SOC_DAIFMT_CBM_CFM:
1522 /* Set to master mode */
1523 reg1Cval |= M98088_DAI_MAS;
1524 break;
1525 case SND_SOC_DAIFMT_CBS_CFM:
1526 case SND_SOC_DAIFMT_CBM_CFS:
1527 default:
1528 dev_err(codec->dev, "Clock mode unsupported");
1529 return -EINVAL;
1530 }
1531
1532 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1533 case SND_SOC_DAIFMT_I2S:
1534 reg1Cval |= M98088_DAI_DLY;
1535 break;
1536 case SND_SOC_DAIFMT_LEFT_J:
1537 break;
1538 default:
1539 return -EINVAL;
1540 }
1541
1542 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1543 case SND_SOC_DAIFMT_NB_NF:
1544 break;
1545 case SND_SOC_DAIFMT_NB_IF:
1546 reg1Cval |= M98088_DAI_WCI;
1547 break;
1548 case SND_SOC_DAIFMT_IB_NF:
1549 reg1Cval |= M98088_DAI_BCI;
1550 break;
1551 case SND_SOC_DAIFMT_IB_IF:
1552 reg1Cval |= M98088_DAI_BCI|M98088_DAI_WCI;
1553 break;
1554 default:
1555 return -EINVAL;
1556 }
1557
1558 snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
1559 M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
1560 M98088_DAI_WCI, reg1Cval);
1561
1562 snd_soc_write(codec, M98088_REG_1D_DAI2_CLOCK,
1563 M98088_DAI_BSEL64);
1564 }
1565
1566 return 0;
1567}
1568
1569static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1570{
1571 struct snd_soc_codec *codec = codec_dai->codec;
1572 int reg;
1573
1574 if (mute)
1575 reg = M98088_DAI_MUTE;
1576 else
1577 reg = 0;
1578
1579 snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
1580 M98088_DAI_MUTE_MASK, reg);
1581 return 0;
1582}
1583
1584static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1585{
1586 struct snd_soc_codec *codec = codec_dai->codec;
1587 int reg;
1588
1589 if (mute)
1590 reg = M98088_DAI_MUTE;
1591 else
1592 reg = 0;
1593
1594 snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
1595 M98088_DAI_MUTE_MASK, reg);
1596 return 0;
1597}
1598
1599static void max98088_sync_cache(struct snd_soc_codec *codec)
1600{
1601 u16 *reg_cache = codec->reg_cache;
1602 int i;
1603
1604 if (!codec->cache_sync)
1605 return;
1606
1607 codec->cache_only = 0;
1608
1609 /* write back cached values if they're writeable and
1610 * different from the hardware default.
1611 */
1612 for (i = 1; i < codec->driver->reg_cache_size; i++) {
1613 if (!max98088_access[i].writable)
1614 continue;
1615
1616 if (reg_cache[i] == max98088_reg[i])
1617 continue;
1618
1619 snd_soc_write(codec, i, reg_cache[i]);
1620 }
1621
1622 codec->cache_sync = 0;
1623}
1624
1625static int max98088_set_bias_level(struct snd_soc_codec *codec,
1626 enum snd_soc_bias_level level)
1627{
1628 switch (level) {
1629 case SND_SOC_BIAS_ON:
1630 break;
1631
1632 case SND_SOC_BIAS_PREPARE:
1633 break;
1634
1635 case SND_SOC_BIAS_STANDBY:
1636 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1637 max98088_sync_cache(codec);
1638
1639 snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
1640 M98088_MBEN, M98088_MBEN);
1641 break;
1642
1643 case SND_SOC_BIAS_OFF:
1644 snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
1645 M98088_MBEN, 0);
1646 codec->cache_sync = 1;
1647 break;
1648 }
1649 codec->dapm.bias_level = level;
1650 return 0;
1651}
1652
1653#define MAX98088_RATES SNDRV_PCM_RATE_8000_96000
1654#define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
1655
1656static struct snd_soc_dai_ops max98088_dai1_ops = {
1657 .set_sysclk = max98088_dai_set_sysclk,
1658 .set_fmt = max98088_dai1_set_fmt,
1659 .hw_params = max98088_dai1_hw_params,
1660 .digital_mute = max98088_dai1_digital_mute,
1661};
1662
1663static struct snd_soc_dai_ops max98088_dai2_ops = {
1664 .set_sysclk = max98088_dai_set_sysclk,
1665 .set_fmt = max98088_dai2_set_fmt,
1666 .hw_params = max98088_dai2_hw_params,
1667 .digital_mute = max98088_dai2_digital_mute,
1668};
1669
1670static struct snd_soc_dai_driver max98088_dai[] = {
1671{
1672 .name = "HiFi",
1673 .playback = {
1674 .stream_name = "HiFi Playback",
1675 .channels_min = 1,
1676 .channels_max = 2,
1677 .rates = MAX98088_RATES,
1678 .formats = MAX98088_FORMATS,
1679 },
1680 .capture = {
1681 .stream_name = "HiFi Capture",
1682 .channels_min = 1,
1683 .channels_max = 2,
1684 .rates = MAX98088_RATES,
1685 .formats = MAX98088_FORMATS,
1686 },
1687 .ops = &max98088_dai1_ops,
1688},
1689{
1690 .name = "Aux",
1691 .playback = {
1692 .stream_name = "Aux Playback",
1693 .channels_min = 1,
1694 .channels_max = 2,
1695 .rates = MAX98088_RATES,
1696 .formats = MAX98088_FORMATS,
1697 },
1698 .ops = &max98088_dai2_ops,
1699}
1700};
1701
1702static int max98088_get_channel(const char *name)
1703{
1704 if (strcmp(name, "EQ1 Mode") == 0)
1705 return 0;
1706 if (strcmp(name, "EQ2 Mode") == 0)
1707 return 1;
1708 return -EINVAL;
1709}
1710
1711static void max98088_setup_eq1(struct snd_soc_codec *codec)
1712{
1713 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1714 struct max98088_pdata *pdata = max98088->pdata;
1715 struct max98088_eq_cfg *coef_set;
1716 int best, best_val, save, i, sel, fs;
1717 struct max98088_cdata *cdata;
1718
1719 cdata = &max98088->dai[0];
1720
1721 if (!pdata || !max98088->eq_textcnt)
1722 return;
1723
1724 /* Find the selected configuration with nearest sample rate */
1725 fs = cdata->rate;
1726 sel = cdata->eq_sel;
1727
1728 best = 0;
1729 best_val = INT_MAX;
1730 for (i = 0; i < pdata->eq_cfgcnt; i++) {
1731 if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 &&
1732 abs(pdata->eq_cfg[i].rate - fs) < best_val) {
1733 best = i;
1734 best_val = abs(pdata->eq_cfg[i].rate - fs);
1735 }
1736 }
1737
1738 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
1739 pdata->eq_cfg[best].name,
1740 pdata->eq_cfg[best].rate, fs);
1741
1742 /* Disable EQ while configuring, and save current on/off state */
1743 save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
1744 snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);
1745
1746 coef_set = &pdata->eq_cfg[sel];
1747
1748 m98088_eq_band(codec, 0, 0, coef_set->band1);
1749 m98088_eq_band(codec, 0, 1, coef_set->band2);
1750 m98088_eq_band(codec, 0, 2, coef_set->band3);
1751 m98088_eq_band(codec, 0, 3, coef_set->band4);
1752 m98088_eq_band(codec, 0, 4, coef_set->band5);
1753
1754 /* Restore the original on/off state */
1755 snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);
1756}
1757
1758static void max98088_setup_eq2(struct snd_soc_codec *codec)
1759{
1760 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1761 struct max98088_pdata *pdata = max98088->pdata;
1762 struct max98088_eq_cfg *coef_set;
1763 int best, best_val, save, i, sel, fs;
1764 struct max98088_cdata *cdata;
1765
1766 cdata = &max98088->dai[1];
1767
1768 if (!pdata || !max98088->eq_textcnt)
1769 return;
1770
1771 /* Find the selected configuration with nearest sample rate */
1772 fs = cdata->rate;
1773
1774 sel = cdata->eq_sel;
1775 best = 0;
1776 best_val = INT_MAX;
1777 for (i = 0; i < pdata->eq_cfgcnt; i++) {
1778 if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 &&
1779 abs(pdata->eq_cfg[i].rate - fs) < best_val) {
1780 best = i;
1781 best_val = abs(pdata->eq_cfg[i].rate - fs);
1782 }
1783 }
1784
1785 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
1786 pdata->eq_cfg[best].name,
1787 pdata->eq_cfg[best].rate, fs);
1788
1789 /* Disable EQ while configuring, and save current on/off state */
1790 save = snd_soc_read(codec, M98088_REG_49_CFG_LEVEL);
1791 snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);
1792
1793 coef_set = &pdata->eq_cfg[sel];
1794
1795 m98088_eq_band(codec, 1, 0, coef_set->band1);
1796 m98088_eq_band(codec, 1, 1, coef_set->band2);
1797 m98088_eq_band(codec, 1, 2, coef_set->band3);
1798 m98088_eq_band(codec, 1, 3, coef_set->band4);
1799 m98088_eq_band(codec, 1, 4, coef_set->band5);
1800
1801 /* Restore the original on/off state */
1802 snd_soc_update_bits(codec, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,
1803 save);
1804}
1805
1806static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,
1807 struct snd_ctl_elem_value *ucontrol)
1808{
1809 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1810 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1811 struct max98088_pdata *pdata = max98088->pdata;
1812 int channel = max98088_get_channel(kcontrol->id.name);
1813 struct max98088_cdata *cdata;
1814 int sel = ucontrol->value.integer.value[0];
1815
1816 cdata = &max98088->dai[channel];
1817
1818 if (sel >= pdata->eq_cfgcnt)
1819 return -EINVAL;
1820
1821 cdata->eq_sel = sel;
1822
1823 switch (channel) {
1824 case 0:
1825 max98088_setup_eq1(codec);
1826 break;
1827 case 1:
1828 max98088_setup_eq2(codec);
1829 break;
1830 }
1831
1832 return 0;
1833}
1834
1835static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,
1836 struct snd_ctl_elem_value *ucontrol)
1837{
1838 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1839 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1840 int channel = max98088_get_channel(kcontrol->id.name);
1841 struct max98088_cdata *cdata;
1842
1843 cdata = &max98088->dai[channel];
1844 ucontrol->value.enumerated.item[0] = cdata->eq_sel;
1845 return 0;
1846}
1847
1848static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
1849{
1850 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1851 struct max98088_pdata *pdata = max98088->pdata;
1852 struct max98088_eq_cfg *cfg;
1853 unsigned int cfgcnt;
1854 int i, j;
1855 const char **t;
1856 int ret;
1857
1858 struct snd_kcontrol_new controls[] = {
1859 SOC_ENUM_EXT("EQ1 Mode",
1860 max98088->eq_enum,
1861 max98088_get_eq_enum,
1862 max98088_put_eq_enum),
1863 SOC_ENUM_EXT("EQ2 Mode",
1864 max98088->eq_enum,
1865 max98088_get_eq_enum,
1866 max98088_put_eq_enum),
1867 };
1868
1869 cfg = pdata->eq_cfg;
1870 cfgcnt = pdata->eq_cfgcnt;
1871
1872 /* Setup an array of texts for the equalizer enum.
1873 * This is based on Mark Brown's equalizer driver code.
1874 */
1875 max98088->eq_textcnt = 0;
1876 max98088->eq_texts = NULL;
1877 for (i = 0; i < cfgcnt; i++) {
1878 for (j = 0; j < max98088->eq_textcnt; j++) {
1879 if (strcmp(cfg[i].name, max98088->eq_texts[j]) == 0)
1880 break;
1881 }
1882
1883 if (j != max98088->eq_textcnt)
1884 continue;
1885
1886 /* Expand the array */
1887 t = krealloc(max98088->eq_texts,
1888 sizeof(char *) * (max98088->eq_textcnt + 1),
1889 GFP_KERNEL);
1890 if (t == NULL)
1891 continue;
1892
1893 /* Store the new entry */
1894 t[max98088->eq_textcnt] = cfg[i].name;
1895 max98088->eq_textcnt++;
1896 max98088->eq_texts = t;
1897 }
1898
1899 /* Now point the soc_enum to .texts array items */
1900 max98088->eq_enum.texts = max98088->eq_texts;
1901 max98088->eq_enum.max = max98088->eq_textcnt;
1902
1903 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
1904 if (ret != 0)
1905 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1906}
1907
1908static void max98088_handle_pdata(struct snd_soc_codec *codec)
1909{
1910 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1911 struct max98088_pdata *pdata = max98088->pdata;
1912 u8 regval = 0;
1913
1914 if (!pdata) {
1915 dev_dbg(codec->dev, "No platform data\n");
1916 return;
1917 }
1918
1919 /* Configure mic for analog/digital mic mode */
1920 if (pdata->digmic_left_mode)
1921 regval |= M98088_DIGMIC_L;
1922
1923 if (pdata->digmic_right_mode)
1924 regval |= M98088_DIGMIC_R;
1925
1926 max98088->digmic = (regval ? 1 : 0);
1927
1928 snd_soc_write(codec, M98088_REG_48_CFG_MIC, regval);
1929
1930 /* Configure receiver output */
1931 regval = ((pdata->receiver_mode) ? M98088_REC_LINEMODE : 0);
1932 snd_soc_update_bits(codec, M98088_REG_2A_MIC_REC_CNTL,
1933 M98088_REC_LINEMODE_MASK, regval);
1934
1935 /* Configure equalizers */
1936 if (pdata->eq_cfgcnt)
1937 max98088_handle_eq_pdata(codec);
1938}
1939
1940#ifdef CONFIG_PM
1941static int max98088_suspend(struct snd_soc_codec *codec, pm_message_t state)
1942{
1943 max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
1944
1945 return 0;
1946}
1947
1948static int max98088_resume(struct snd_soc_codec *codec)
1949{
1950 max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1951
1952 return 0;
1953}
1954#else
1955#define max98088_suspend NULL
1956#define max98088_resume NULL
1957#endif
1958
1959static int max98088_probe(struct snd_soc_codec *codec)
1960{
1961 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
1962 struct max98088_cdata *cdata;
1963 int ret = 0;
1964
1965 codec->cache_sync = 1;
1966
1967 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
1968 if (ret != 0) {
1969 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1970 return ret;
1971 }
1972
1973 /* initialize private data */
1974
1975 max98088->sysclk = (unsigned)-1;
1976 max98088->eq_textcnt = 0;
1977
1978 cdata = &max98088->dai[0];
1979 cdata->rate = (unsigned)-1;
1980 cdata->fmt = (unsigned)-1;
1981 cdata->eq_sel = 0;
1982
1983 cdata = &max98088->dai[1];
1984 cdata->rate = (unsigned)-1;
1985 cdata->fmt = (unsigned)-1;
1986 cdata->eq_sel = 0;
1987
1988 max98088->ina_state = 0;
1989 max98088->inb_state = 0;
1990 max98088->ex_mode = 0;
1991 max98088->digmic = 0;
1992 max98088->mic1pre = 0;
1993 max98088->mic2pre = 0;
1994
1995 ret = snd_soc_read(codec, M98088_REG_FF_REV_ID);
1996 if (ret < 0) {
1997 dev_err(codec->dev, "Failed to read device revision: %d\n",
1998 ret);
1999 goto err_access;
2000 }
2001 dev_info(codec->dev, "revision %c\n", ret + 'A');
2002
2003 snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV);
2004
2005 /* initialize registers cache to hardware default */
2006 max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2007
2008 snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00);
2009
2010 snd_soc_write(codec, M98088_REG_22_MIX_DAC,
2011 M98088_DAI1L_TO_DACL|M98088_DAI2L_TO_DACL|
2012 M98088_DAI1R_TO_DACR|M98088_DAI2R_TO_DACR);
2013
2014 snd_soc_write(codec, M98088_REG_4E_BIAS_CNTL, 0xF0);
2015 snd_soc_write(codec, M98088_REG_50_DAC_BIAS2, 0x0F);
2016
2017 snd_soc_write(codec, M98088_REG_16_DAI1_IOCFG,
2018 M98088_S1NORMAL|M98088_SDATA);
2019
2020 snd_soc_write(codec, M98088_REG_1E_DAI2_IOCFG,
2021 M98088_S2NORMAL|M98088_SDATA);
2022
2023 max98088_handle_pdata(codec);
2024
2025 snd_soc_add_controls(codec, max98088_snd_controls,
2026 ARRAY_SIZE(max98088_snd_controls));
2027
2028err_access:
2029 return ret;
2030}
2031
2032static int max98088_remove(struct snd_soc_codec *codec)
2033{
2034 struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
2035
2036 max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
2037 kfree(max98088->eq_texts);
2038
2039 return 0;
2040}
2041
2042static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
2043 .probe = max98088_probe,
2044 .remove = max98088_remove,
2045 .suspend = max98088_suspend,
2046 .resume = max98088_resume,
2047 .set_bias_level = max98088_set_bias_level,
2048 .reg_cache_size = ARRAY_SIZE(max98088_reg),
2049 .reg_word_size = sizeof(u8),
2050 .reg_cache_default = max98088_reg,
2051 .volatile_register = max98088_volatile_register,
2052 .dapm_widgets = max98088_dapm_widgets,
2053 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),
2054 .dapm_routes = max98088_audio_map,
2055 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),
2056};
2057
2058static int max98088_i2c_probe(struct i2c_client *i2c,
2059 const struct i2c_device_id *id)
2060{
2061 struct max98088_priv *max98088;
2062 int ret;
2063
2064 max98088 = kzalloc(sizeof(struct max98088_priv), GFP_KERNEL);
2065 if (max98088 == NULL)
2066 return -ENOMEM;
2067
2068 max98088->devtype = id->driver_data;
2069
2070 i2c_set_clientdata(i2c, max98088);
2071 max98088->control_data = i2c;
2072 max98088->pdata = i2c->dev.platform_data;
2073
2074 ret = snd_soc_register_codec(&i2c->dev,
2075 &soc_codec_dev_max98088, &max98088_dai[0], 2);
2076 if (ret < 0)
2077 kfree(max98088);
2078 return ret;
2079}
2080
2081static int __devexit max98088_i2c_remove(struct i2c_client *client)
2082{
2083 snd_soc_unregister_codec(&client->dev);
2084 kfree(i2c_get_clientdata(client));
2085 return 0;
2086}
2087
2088static const struct i2c_device_id max98088_i2c_id[] = {
2089 { "max98088", MAX98088 },
2090 { "max98089", MAX98089 },
2091 { }
2092};
2093MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
2094
2095static struct i2c_driver max98088_i2c_driver = {
2096 .driver = {
2097 .name = "max98088",
2098 .owner = THIS_MODULE,
2099 },
2100 .probe = max98088_i2c_probe,
2101 .remove = __devexit_p(max98088_i2c_remove),
2102 .id_table = max98088_i2c_id,
2103};
2104
2105static int __init max98088_init(void)
2106{
2107 int ret;
2108
2109 ret = i2c_add_driver(&max98088_i2c_driver);
2110 if (ret)
2111 pr_err("Failed to register max98088 I2C driver: %d\n", ret);
2112
2113 return ret;
2114}
2115module_init(max98088_init);
2116
2117static void __exit max98088_exit(void)
2118{
2119 i2c_del_driver(&max98088_i2c_driver);
2120}
2121module_exit(max98088_exit);
2122
2123MODULE_DESCRIPTION("ALSA SoC MAX98088 driver");
2124MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin");
2125MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98088.h b/sound/soc/codecs/max98088.h
new file mode 100644
index 000000000000..be89a4f4aab8
--- /dev/null
+++ b/sound/soc/codecs/max98088.h
@@ -0,0 +1,206 @@
1/*
2 * max98088.h -- MAX98088 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98088_H
12#define _MAX98088_H
13
14/*
15 * MAX98088 Registers Definition
16 */
17#define M98088_REG_00_IRQ_STATUS 0x00
18#define M98088_REG_01_MIC_STATUS 0x01
19#define M98088_REG_02_JACK_STAUS 0x02
20#define M98088_REG_03_BATTERY_VOLTAGE 0x03
21#define M98088_REG_0F_IRQ_ENABLE 0x0F
22#define M98088_REG_10_SYS_CLK 0x10
23#define M98088_REG_11_DAI1_CLKMODE 0x11
24#define M98088_REG_12_DAI1_CLKCFG_HI 0x12
25#define M98088_REG_13_DAI1_CLKCFG_LO 0x13
26#define M98088_REG_14_DAI1_FORMAT 0x14
27#define M98088_REG_15_DAI1_CLOCK 0x15
28#define M98088_REG_16_DAI1_IOCFG 0x16
29#define M98088_REG_17_DAI1_TDM 0x17
30#define M98088_REG_18_DAI1_FILTERS 0x18
31#define M98088_REG_19_DAI2_CLKMODE 0x19
32#define M98088_REG_1A_DAI2_CLKCFG_HI 0x1A
33#define M98088_REG_1B_DAI2_CLKCFG_LO 0x1B
34#define M98088_REG_1C_DAI2_FORMAT 0x1C
35#define M98088_REG_1D_DAI2_CLOCK 0x1D
36#define M98088_REG_1E_DAI2_IOCFG 0x1E
37#define M98088_REG_1F_DAI2_TDM 0x1F
38#define M98088_REG_20_DAI2_FILTERS 0x20
39#define M98088_REG_21_SRC 0x21
40#define M98088_REG_22_MIX_DAC 0x22
41#define M98088_REG_23_MIX_ADC_LEFT 0x23
42#define M98088_REG_24_MIX_ADC_RIGHT 0x24
43#define M98088_REG_25_MIX_HP_LEFT 0x25
44#define M98088_REG_26_MIX_HP_RIGHT 0x26
45#define M98088_REG_27_MIX_HP_CNTL 0x27
46#define M98088_REG_28_MIX_REC_LEFT 0x28
47#define M98088_REG_29_MIX_REC_RIGHT 0x29
48#define M98088_REG_2A_MIC_REC_CNTL 0x2A
49#define M98088_REG_2B_MIX_SPK_LEFT 0x2B
50#define M98088_REG_2C_MIX_SPK_RIGHT 0x2C
51#define M98088_REG_2D_MIX_SPK_CNTL 0x2D
52#define M98088_REG_2E_LVL_SIDETONE 0x2E
53#define M98088_REG_2F_LVL_DAI1_PLAY 0x2F
54#define M98088_REG_30_LVL_DAI1_PLAY_EQ 0x30
55#define M98088_REG_31_LVL_DAI2_PLAY 0x31
56#define M98088_REG_32_LVL_DAI2_PLAY_EQ 0x32
57#define M98088_REG_33_LVL_ADC_L 0x33
58#define M98088_REG_34_LVL_ADC_R 0x34
59#define M98088_REG_35_LVL_MIC1 0x35
60#define M98088_REG_36_LVL_MIC2 0x36
61#define M98088_REG_37_LVL_INA 0x37
62#define M98088_REG_38_LVL_INB 0x38
63#define M98088_REG_39_LVL_HP_L 0x39
64#define M98088_REG_3A_LVL_HP_R 0x3A
65#define M98088_REG_3B_LVL_REC_L 0x3B
66#define M98088_REG_3C_LVL_REC_R 0x3C
67#define M98088_REG_3D_LVL_SPK_L 0x3D
68#define M98088_REG_3E_LVL_SPK_R 0x3E
69#define M98088_REG_3F_MICAGC_CFG 0x3F
70#define M98088_REG_40_MICAGC_THRESH 0x40
71#define M98088_REG_41_SPKDHP 0x41
72#define M98088_REG_42_SPKDHP_THRESH 0x42
73#define M98088_REG_43_SPKALC_COMP 0x43
74#define M98088_REG_44_PWRLMT_CFG 0x44
75#define M98088_REG_45_PWRLMT_TIME 0x45
76#define M98088_REG_46_THDLMT_CFG 0x46
77#define M98088_REG_47_CFG_AUDIO_IN 0x47
78#define M98088_REG_48_CFG_MIC 0x48
79#define M98088_REG_49_CFG_LEVEL 0x49
80#define M98088_REG_4A_CFG_BYPASS 0x4A
81#define M98088_REG_4B_CFG_JACKDET 0x4B
82#define M98088_REG_4C_PWR_EN_IN 0x4C
83#define M98088_REG_4D_PWR_EN_OUT 0x4D
84#define M98088_REG_4E_BIAS_CNTL 0x4E
85#define M98088_REG_4F_DAC_BIAS1 0x4F
86#define M98088_REG_50_DAC_BIAS2 0x50
87#define M98088_REG_51_PWR_SYS 0x51
88#define M98088_REG_52_DAI1_EQ_BASE 0x52
89#define M98088_REG_84_DAI2_EQ_BASE 0x84
90#define M98088_REG_B6_DAI1_BIQUAD_BASE 0xB6
91#define M98088_REG_C0_DAI2_BIQUAD_BASE 0xC0
92#define M98088_REG_FF_REV_ID 0xFF
93
94#define M98088_REG_CNT (0xFF+1)
95
96/* MAX98088 Registers Bit Fields */
97
98/* M98088_REG_11_DAI1_CLKMODE, M98088_REG_19_DAI2_CLKMODE */
99 #define M98088_CLKMODE_MASK 0xFF
100
101/* M98088_REG_14_DAI1_FORMAT, M98088_REG_1C_DAI2_FORMAT */
102 #define M98088_DAI_MAS (1<<7)
103 #define M98088_DAI_WCI (1<<6)
104 #define M98088_DAI_BCI (1<<5)
105 #define M98088_DAI_DLY (1<<4)
106 #define M98088_DAI_TDM (1<<2)
107 #define M98088_DAI_FSW (1<<1)
108 #define M98088_DAI_WS (1<<0)
109
110/* M98088_REG_15_DAI1_CLOCK, M98088_REG_1D_DAI2_CLOCK */
111 #define M98088_DAI_BSEL64 (1<<0)
112 #define M98088_DAI_OSR64 (1<<6)
113
114/* M98088_REG_16_DAI1_IOCFG, M98088_REG_1E_DAI2_IOCFG */
115 #define M98088_S1NORMAL (1<<6)
116 #define M98088_S2NORMAL (2<<6)
117 #define M98088_SDATA (3<<0)
118
119/* M98088_REG_18_DAI1_FILTERS, M98088_REG_20_DAI2_FILTERS */
120 #define M98088_DAI_DHF (1<<3)
121
122/* M98088_REG_22_MIX_DAC */
123 #define M98088_DAI1L_TO_DACL (1<<7)
124 #define M98088_DAI1R_TO_DACL (1<<6)
125 #define M98088_DAI2L_TO_DACL (1<<5)
126 #define M98088_DAI2R_TO_DACL (1<<4)
127 #define M98088_DAI1L_TO_DACR (1<<3)
128 #define M98088_DAI1R_TO_DACR (1<<2)
129 #define M98088_DAI2L_TO_DACR (1<<1)
130 #define M98088_DAI2R_TO_DACR (1<<0)
131
132/* M98088_REG_2A_MIC_REC_CNTL */
133 #define M98088_REC_LINEMODE (1<<7)
134 #define M98088_REC_LINEMODE_MASK (1<<7)
135
136/* M98088_REG_2D_MIX_SPK_CNTL */
137 #define M98088_MIX_SPKR_GAIN_MASK (3<<2)
138 #define M98088_MIX_SPKR_GAIN_SHIFT 2
139 #define M98088_MIX_SPKL_GAIN_MASK (3<<0)
140 #define M98088_MIX_SPKL_GAIN_SHIFT 0
141
142/* M98088_REG_2F_LVL_DAI1_PLAY, M98088_REG_31_LVL_DAI2_PLAY */
143 #define M98088_DAI_MUTE (1<<7)
144 #define M98088_DAI_MUTE_MASK (1<<7)
145 #define M98088_DAI_VOICE_GAIN_MASK (3<<4)
146 #define M98088_DAI_ATTENUATION_MASK (0xF<<0)
147 #define M98088_DAI_ATTENUATION_SHIFT 0
148
149/* M98088_REG_35_LVL_MIC1, M98088_REG_36_LVL_MIC2 */
150 #define M98088_MICPRE_MASK (3<<5)
151 #define M98088_MICPRE_SHIFT 5
152
153/* M98088_REG_3A_LVL_HP_R */
154 #define M98088_HP_MUTE (1<<7)
155
156/* M98088_REG_3C_LVL_REC_R */
157 #define M98088_REC_MUTE (1<<7)
158
159/* M98088_REG_3E_LVL_SPK_R */
160 #define M98088_SP_MUTE (1<<7)
161
162/* M98088_REG_48_CFG_MIC */
163 #define M98088_EXTMIC_MASK (3<<0)
164 #define M98088_DIGMIC_L (1<<5)
165 #define M98088_DIGMIC_R (1<<4)
166
167/* M98088_REG_49_CFG_LEVEL */
168 #define M98088_VSEN (1<<6)
169 #define M98088_ZDEN (1<<5)
170 #define M98088_EQ2EN (1<<1)
171 #define M98088_EQ1EN (1<<0)
172
173/* M98088_REG_4C_PWR_EN_IN */
174 #define M98088_INAEN (1<<7)
175 #define M98088_INBEN (1<<6)
176 #define M98088_MBEN (1<<3)
177 #define M98088_ADLEN (1<<1)
178 #define M98088_ADREN (1<<0)
179
180/* M98088_REG_4D_PWR_EN_OUT */
181 #define M98088_HPLEN (1<<7)
182 #define M98088_HPREN (1<<6)
183 #define M98088_HPEN ((1<<7)|(1<<6))
184 #define M98088_SPLEN (1<<5)
185 #define M98088_SPREN (1<<4)
186 #define M98088_RECEN (1<<3)
187 #define M98088_DALEN (1<<1)
188 #define M98088_DAREN (1<<0)
189
190/* M98088_REG_51_PWR_SYS */
191 #define M98088_SHDNRUN (1<<7)
192 #define M98088_PERFMODE (1<<3)
193 #define M98088_HPPLYBACK (1<<2)
194 #define M98088_PWRSV8K (1<<1)
195 #define M98088_PWRSV (1<<0)
196
197/* Line inputs */
198#define LINE_INA 0
199#define LINE_INB 1
200
201#define M98088_COEFS_PER_BAND 5
202
203#define M98088_BYTE1(w) ((w >> 8) & 0xff)
204#define M98088_BYTE0(w) (w & 0xff)
205
206#endif
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
new file mode 100644
index 000000000000..e1d282d477da
--- /dev/null
+++ b/sound/soc/codecs/max98095.c
@@ -0,0 +1,2396 @@
1/*
2 * max98095.c -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/initval.h>
24#include <sound/tlv.h>
25#include <linux/slab.h>
26#include <asm/div64.h>
27#include <sound/max98095.h>
28#include "max98095.h"
29
30enum max98095_type {
31 MAX98095,
32};
33
34struct max98095_cdata {
35 unsigned int rate;
36 unsigned int fmt;
37 int eq_sel;
38 int bq_sel;
39};
40
41struct max98095_priv {
42 enum max98095_type devtype;
43 void *control_data;
44 struct max98095_pdata *pdata;
45 unsigned int sysclk;
46 struct max98095_cdata dai[3];
47 const char **eq_texts;
48 const char **bq_texts;
49 struct soc_enum eq_enum;
50 struct soc_enum bq_enum;
51 int eq_textcnt;
52 int bq_textcnt;
53 u8 lin_state;
54 unsigned int mic1pre;
55 unsigned int mic2pre;
56};
57
58static const u8 max98095_reg_def[M98095_REG_CNT] = {
59 0x00, /* 00 */
60 0x00, /* 01 */
61 0x00, /* 02 */
62 0x00, /* 03 */
63 0x00, /* 04 */
64 0x00, /* 05 */
65 0x00, /* 06 */
66 0x00, /* 07 */
67 0x00, /* 08 */
68 0x00, /* 09 */
69 0x00, /* 0A */
70 0x00, /* 0B */
71 0x00, /* 0C */
72 0x00, /* 0D */
73 0x00, /* 0E */
74 0x00, /* 0F */
75 0x00, /* 10 */
76 0x00, /* 11 */
77 0x00, /* 12 */
78 0x00, /* 13 */
79 0x00, /* 14 */
80 0x00, /* 15 */
81 0x00, /* 16 */
82 0x00, /* 17 */
83 0x00, /* 18 */
84 0x00, /* 19 */
85 0x00, /* 1A */
86 0x00, /* 1B */
87 0x00, /* 1C */
88 0x00, /* 1D */
89 0x00, /* 1E */
90 0x00, /* 1F */
91 0x00, /* 20 */
92 0x00, /* 21 */
93 0x00, /* 22 */
94 0x00, /* 23 */
95 0x00, /* 24 */
96 0x00, /* 25 */
97 0x00, /* 26 */
98 0x00, /* 27 */
99 0x00, /* 28 */
100 0x00, /* 29 */
101 0x00, /* 2A */
102 0x00, /* 2B */
103 0x00, /* 2C */
104 0x00, /* 2D */
105 0x00, /* 2E */
106 0x00, /* 2F */
107 0x00, /* 30 */
108 0x00, /* 31 */
109 0x00, /* 32 */
110 0x00, /* 33 */
111 0x00, /* 34 */
112 0x00, /* 35 */
113 0x00, /* 36 */
114 0x00, /* 37 */
115 0x00, /* 38 */
116 0x00, /* 39 */
117 0x00, /* 3A */
118 0x00, /* 3B */
119 0x00, /* 3C */
120 0x00, /* 3D */
121 0x00, /* 3E */
122 0x00, /* 3F */
123 0x00, /* 40 */
124 0x00, /* 41 */
125 0x00, /* 42 */
126 0x00, /* 43 */
127 0x00, /* 44 */
128 0x00, /* 45 */
129 0x00, /* 46 */
130 0x00, /* 47 */
131 0x00, /* 48 */
132 0x00, /* 49 */
133 0x00, /* 4A */
134 0x00, /* 4B */
135 0x00, /* 4C */
136 0x00, /* 4D */
137 0x00, /* 4E */
138 0x00, /* 4F */
139 0x00, /* 50 */
140 0x00, /* 51 */
141 0x00, /* 52 */
142 0x00, /* 53 */
143 0x00, /* 54 */
144 0x00, /* 55 */
145 0x00, /* 56 */
146 0x00, /* 57 */
147 0x00, /* 58 */
148 0x00, /* 59 */
149 0x00, /* 5A */
150 0x00, /* 5B */
151 0x00, /* 5C */
152 0x00, /* 5D */
153 0x00, /* 5E */
154 0x00, /* 5F */
155 0x00, /* 60 */
156 0x00, /* 61 */
157 0x00, /* 62 */
158 0x00, /* 63 */
159 0x00, /* 64 */
160 0x00, /* 65 */
161 0x00, /* 66 */
162 0x00, /* 67 */
163 0x00, /* 68 */
164 0x00, /* 69 */
165 0x00, /* 6A */
166 0x00, /* 6B */
167 0x00, /* 6C */
168 0x00, /* 6D */
169 0x00, /* 6E */
170 0x00, /* 6F */
171 0x00, /* 70 */
172 0x00, /* 71 */
173 0x00, /* 72 */
174 0x00, /* 73 */
175 0x00, /* 74 */
176 0x00, /* 75 */
177 0x00, /* 76 */
178 0x00, /* 77 */
179 0x00, /* 78 */
180 0x00, /* 79 */
181 0x00, /* 7A */
182 0x00, /* 7B */
183 0x00, /* 7C */
184 0x00, /* 7D */
185 0x00, /* 7E */
186 0x00, /* 7F */
187 0x00, /* 80 */
188 0x00, /* 81 */
189 0x00, /* 82 */
190 0x00, /* 83 */
191 0x00, /* 84 */
192 0x00, /* 85 */
193 0x00, /* 86 */
194 0x00, /* 87 */
195 0x00, /* 88 */
196 0x00, /* 89 */
197 0x00, /* 8A */
198 0x00, /* 8B */
199 0x00, /* 8C */
200 0x00, /* 8D */
201 0x00, /* 8E */
202 0x00, /* 8F */
203 0x00, /* 90 */
204 0x00, /* 91 */
205 0x30, /* 92 */
206 0xF0, /* 93 */
207 0x00, /* 94 */
208 0x00, /* 95 */
209 0x3F, /* 96 */
210 0x00, /* 97 */
211 0x00, /* 98 */
212 0x00, /* 99 */
213 0x00, /* 9A */
214 0x00, /* 9B */
215 0x00, /* 9C */
216 0x00, /* 9D */
217 0x00, /* 9E */
218 0x00, /* 9F */
219 0x00, /* A0 */
220 0x00, /* A1 */
221 0x00, /* A2 */
222 0x00, /* A3 */
223 0x00, /* A4 */
224 0x00, /* A5 */
225 0x00, /* A6 */
226 0x00, /* A7 */
227 0x00, /* A8 */
228 0x00, /* A9 */
229 0x00, /* AA */
230 0x00, /* AB */
231 0x00, /* AC */
232 0x00, /* AD */
233 0x00, /* AE */
234 0x00, /* AF */
235 0x00, /* B0 */
236 0x00, /* B1 */
237 0x00, /* B2 */
238 0x00, /* B3 */
239 0x00, /* B4 */
240 0x00, /* B5 */
241 0x00, /* B6 */
242 0x00, /* B7 */
243 0x00, /* B8 */
244 0x00, /* B9 */
245 0x00, /* BA */
246 0x00, /* BB */
247 0x00, /* BC */
248 0x00, /* BD */
249 0x00, /* BE */
250 0x00, /* BF */
251 0x00, /* C0 */
252 0x00, /* C1 */
253 0x00, /* C2 */
254 0x00, /* C3 */
255 0x00, /* C4 */
256 0x00, /* C5 */
257 0x00, /* C6 */
258 0x00, /* C7 */
259 0x00, /* C8 */
260 0x00, /* C9 */
261 0x00, /* CA */
262 0x00, /* CB */
263 0x00, /* CC */
264 0x00, /* CD */
265 0x00, /* CE */
266 0x00, /* CF */
267 0x00, /* D0 */
268 0x00, /* D1 */
269 0x00, /* D2 */
270 0x00, /* D3 */
271 0x00, /* D4 */
272 0x00, /* D5 */
273 0x00, /* D6 */
274 0x00, /* D7 */
275 0x00, /* D8 */
276 0x00, /* D9 */
277 0x00, /* DA */
278 0x00, /* DB */
279 0x00, /* DC */
280 0x00, /* DD */
281 0x00, /* DE */
282 0x00, /* DF */
283 0x00, /* E0 */
284 0x00, /* E1 */
285 0x00, /* E2 */
286 0x00, /* E3 */
287 0x00, /* E4 */
288 0x00, /* E5 */
289 0x00, /* E6 */
290 0x00, /* E7 */
291 0x00, /* E8 */
292 0x00, /* E9 */
293 0x00, /* EA */
294 0x00, /* EB */
295 0x00, /* EC */
296 0x00, /* ED */
297 0x00, /* EE */
298 0x00, /* EF */
299 0x00, /* F0 */
300 0x00, /* F1 */
301 0x00, /* F2 */
302 0x00, /* F3 */
303 0x00, /* F4 */
304 0x00, /* F5 */
305 0x00, /* F6 */
306 0x00, /* F7 */
307 0x00, /* F8 */
308 0x00, /* F9 */
309 0x00, /* FA */
310 0x00, /* FB */
311 0x00, /* FC */
312 0x00, /* FD */
313 0x00, /* FE */
314 0x00, /* FF */
315};
316
317static struct {
318 int readable;
319 int writable;
320} max98095_access[M98095_REG_CNT] = {
321 { 0x00, 0x00 }, /* 00 */
322 { 0xFF, 0x00 }, /* 01 */
323 { 0xFF, 0x00 }, /* 02 */
324 { 0xFF, 0x00 }, /* 03 */
325 { 0xFF, 0x00 }, /* 04 */
326 { 0xFF, 0x00 }, /* 05 */
327 { 0xFF, 0x00 }, /* 06 */
328 { 0xFF, 0x00 }, /* 07 */
329 { 0xFF, 0x00 }, /* 08 */
330 { 0xFF, 0x00 }, /* 09 */
331 { 0xFF, 0x00 }, /* 0A */
332 { 0xFF, 0x00 }, /* 0B */
333 { 0xFF, 0x00 }, /* 0C */
334 { 0xFF, 0x00 }, /* 0D */
335 { 0xFF, 0x00 }, /* 0E */
336 { 0xFF, 0x9F }, /* 0F */
337 { 0xFF, 0xFF }, /* 10 */
338 { 0xFF, 0xFF }, /* 11 */
339 { 0xFF, 0xFF }, /* 12 */
340 { 0xFF, 0xFF }, /* 13 */
341 { 0xFF, 0xFF }, /* 14 */
342 { 0xFF, 0xFF }, /* 15 */
343 { 0xFF, 0xFF }, /* 16 */
344 { 0xFF, 0xFF }, /* 17 */
345 { 0xFF, 0xFF }, /* 18 */
346 { 0xFF, 0xFF }, /* 19 */
347 { 0xFF, 0xFF }, /* 1A */
348 { 0xFF, 0xFF }, /* 1B */
349 { 0xFF, 0xFF }, /* 1C */
350 { 0xFF, 0xFF }, /* 1D */
351 { 0xFF, 0x77 }, /* 1E */
352 { 0xFF, 0x77 }, /* 1F */
353 { 0xFF, 0x77 }, /* 20 */
354 { 0xFF, 0x77 }, /* 21 */
355 { 0xFF, 0x77 }, /* 22 */
356 { 0xFF, 0x77 }, /* 23 */
357 { 0xFF, 0xFF }, /* 24 */
358 { 0xFF, 0x7F }, /* 25 */
359 { 0xFF, 0x31 }, /* 26 */
360 { 0xFF, 0xFF }, /* 27 */
361 { 0xFF, 0xFF }, /* 28 */
362 { 0xFF, 0xFF }, /* 29 */
363 { 0xFF, 0xF7 }, /* 2A */
364 { 0xFF, 0x2F }, /* 2B */
365 { 0xFF, 0xEF }, /* 2C */
366 { 0xFF, 0xFF }, /* 2D */
367 { 0xFF, 0xFF }, /* 2E */
368 { 0xFF, 0xFF }, /* 2F */
369 { 0xFF, 0xFF }, /* 30 */
370 { 0xFF, 0xFF }, /* 31 */
371 { 0xFF, 0xFF }, /* 32 */
372 { 0xFF, 0xFF }, /* 33 */
373 { 0xFF, 0xF7 }, /* 34 */
374 { 0xFF, 0x2F }, /* 35 */
375 { 0xFF, 0xCF }, /* 36 */
376 { 0xFF, 0xFF }, /* 37 */
377 { 0xFF, 0xFF }, /* 38 */
378 { 0xFF, 0xFF }, /* 39 */
379 { 0xFF, 0xFF }, /* 3A */
380 { 0xFF, 0xFF }, /* 3B */
381 { 0xFF, 0xFF }, /* 3C */
382 { 0xFF, 0xFF }, /* 3D */
383 { 0xFF, 0xF7 }, /* 3E */
384 { 0xFF, 0x2F }, /* 3F */
385 { 0xFF, 0xCF }, /* 40 */
386 { 0xFF, 0xFF }, /* 41 */
387 { 0xFF, 0x77 }, /* 42 */
388 { 0xFF, 0xFF }, /* 43 */
389 { 0xFF, 0xFF }, /* 44 */
390 { 0xFF, 0xFF }, /* 45 */
391 { 0xFF, 0xFF }, /* 46 */
392 { 0xFF, 0xFF }, /* 47 */
393 { 0xFF, 0xFF }, /* 48 */
394 { 0xFF, 0x0F }, /* 49 */
395 { 0xFF, 0xFF }, /* 4A */
396 { 0xFF, 0xFF }, /* 4B */
397 { 0xFF, 0x3F }, /* 4C */
398 { 0xFF, 0x3F }, /* 4D */
399 { 0xFF, 0x3F }, /* 4E */
400 { 0xFF, 0xFF }, /* 4F */
401 { 0xFF, 0x7F }, /* 50 */
402 { 0xFF, 0x7F }, /* 51 */
403 { 0xFF, 0x0F }, /* 52 */
404 { 0xFF, 0x3F }, /* 53 */
405 { 0xFF, 0x3F }, /* 54 */
406 { 0xFF, 0x3F }, /* 55 */
407 { 0xFF, 0xFF }, /* 56 */
408 { 0xFF, 0xFF }, /* 57 */
409 { 0xFF, 0xBF }, /* 58 */
410 { 0xFF, 0x1F }, /* 59 */
411 { 0xFF, 0xBF }, /* 5A */
412 { 0xFF, 0x1F }, /* 5B */
413 { 0xFF, 0xBF }, /* 5C */
414 { 0xFF, 0x3F }, /* 5D */
415 { 0xFF, 0x3F }, /* 5E */
416 { 0xFF, 0x7F }, /* 5F */
417 { 0xFF, 0x7F }, /* 60 */
418 { 0xFF, 0x47 }, /* 61 */
419 { 0xFF, 0x9F }, /* 62 */
420 { 0xFF, 0x9F }, /* 63 */
421 { 0xFF, 0x9F }, /* 64 */
422 { 0xFF, 0x9F }, /* 65 */
423 { 0xFF, 0x9F }, /* 66 */
424 { 0xFF, 0xBF }, /* 67 */
425 { 0xFF, 0xBF }, /* 68 */
426 { 0xFF, 0xFF }, /* 69 */
427 { 0xFF, 0xFF }, /* 6A */
428 { 0xFF, 0x7F }, /* 6B */
429 { 0xFF, 0xF7 }, /* 6C */
430 { 0xFF, 0xFF }, /* 6D */
431 { 0xFF, 0xFF }, /* 6E */
432 { 0xFF, 0x1F }, /* 6F */
433 { 0xFF, 0xF7 }, /* 70 */
434 { 0xFF, 0xFF }, /* 71 */
435 { 0xFF, 0xFF }, /* 72 */
436 { 0xFF, 0x1F }, /* 73 */
437 { 0xFF, 0xF7 }, /* 74 */
438 { 0xFF, 0xFF }, /* 75 */
439 { 0xFF, 0xFF }, /* 76 */
440 { 0xFF, 0x1F }, /* 77 */
441 { 0xFF, 0xF7 }, /* 78 */
442 { 0xFF, 0xFF }, /* 79 */
443 { 0xFF, 0xFF }, /* 7A */
444 { 0xFF, 0x1F }, /* 7B */
445 { 0xFF, 0xF7 }, /* 7C */
446 { 0xFF, 0xFF }, /* 7D */
447 { 0xFF, 0xFF }, /* 7E */
448 { 0xFF, 0x1F }, /* 7F */
449 { 0xFF, 0xF7 }, /* 80 */
450 { 0xFF, 0xFF }, /* 81 */
451 { 0xFF, 0xFF }, /* 82 */
452 { 0xFF, 0x1F }, /* 83 */
453 { 0xFF, 0x7F }, /* 84 */
454 { 0xFF, 0x0F }, /* 85 */
455 { 0xFF, 0xD8 }, /* 86 */
456 { 0xFF, 0xFF }, /* 87 */
457 { 0xFF, 0xEF }, /* 88 */
458 { 0xFF, 0xFE }, /* 89 */
459 { 0xFF, 0xFE }, /* 8A */
460 { 0xFF, 0xFF }, /* 8B */
461 { 0xFF, 0xFF }, /* 8C */
462 { 0xFF, 0x3F }, /* 8D */
463 { 0xFF, 0xFF }, /* 8E */
464 { 0xFF, 0x3F }, /* 8F */
465 { 0xFF, 0x8F }, /* 90 */
466 { 0xFF, 0xFF }, /* 91 */
467 { 0xFF, 0x3F }, /* 92 */
468 { 0xFF, 0xFF }, /* 93 */
469 { 0xFF, 0xFF }, /* 94 */
470 { 0xFF, 0x0F }, /* 95 */
471 { 0xFF, 0x3F }, /* 96 */
472 { 0xFF, 0x8C }, /* 97 */
473 { 0x00, 0x00 }, /* 98 */
474 { 0x00, 0x00 }, /* 99 */
475 { 0x00, 0x00 }, /* 9A */
476 { 0x00, 0x00 }, /* 9B */
477 { 0x00, 0x00 }, /* 9C */
478 { 0x00, 0x00 }, /* 9D */
479 { 0x00, 0x00 }, /* 9E */
480 { 0x00, 0x00 }, /* 9F */
481 { 0x00, 0x00 }, /* A0 */
482 { 0x00, 0x00 }, /* A1 */
483 { 0x00, 0x00 }, /* A2 */
484 { 0x00, 0x00 }, /* A3 */
485 { 0x00, 0x00 }, /* A4 */
486 { 0x00, 0x00 }, /* A5 */
487 { 0x00, 0x00 }, /* A6 */
488 { 0x00, 0x00 }, /* A7 */
489 { 0x00, 0x00 }, /* A8 */
490 { 0x00, 0x00 }, /* A9 */
491 { 0x00, 0x00 }, /* AA */
492 { 0x00, 0x00 }, /* AB */
493 { 0x00, 0x00 }, /* AC */
494 { 0x00, 0x00 }, /* AD */
495 { 0x00, 0x00 }, /* AE */
496 { 0x00, 0x00 }, /* AF */
497 { 0x00, 0x00 }, /* B0 */
498 { 0x00, 0x00 }, /* B1 */
499 { 0x00, 0x00 }, /* B2 */
500 { 0x00, 0x00 }, /* B3 */
501 { 0x00, 0x00 }, /* B4 */
502 { 0x00, 0x00 }, /* B5 */
503 { 0x00, 0x00 }, /* B6 */
504 { 0x00, 0x00 }, /* B7 */
505 { 0x00, 0x00 }, /* B8 */
506 { 0x00, 0x00 }, /* B9 */
507 { 0x00, 0x00 }, /* BA */
508 { 0x00, 0x00 }, /* BB */
509 { 0x00, 0x00 }, /* BC */
510 { 0x00, 0x00 }, /* BD */
511 { 0x00, 0x00 }, /* BE */
512 { 0x00, 0x00 }, /* BF */
513 { 0x00, 0x00 }, /* C0 */
514 { 0x00, 0x00 }, /* C1 */
515 { 0x00, 0x00 }, /* C2 */
516 { 0x00, 0x00 }, /* C3 */
517 { 0x00, 0x00 }, /* C4 */
518 { 0x00, 0x00 }, /* C5 */
519 { 0x00, 0x00 }, /* C6 */
520 { 0x00, 0x00 }, /* C7 */
521 { 0x00, 0x00 }, /* C8 */
522 { 0x00, 0x00 }, /* C9 */
523 { 0x00, 0x00 }, /* CA */
524 { 0x00, 0x00 }, /* CB */
525 { 0x00, 0x00 }, /* CC */
526 { 0x00, 0x00 }, /* CD */
527 { 0x00, 0x00 }, /* CE */
528 { 0x00, 0x00 }, /* CF */
529 { 0x00, 0x00 }, /* D0 */
530 { 0x00, 0x00 }, /* D1 */
531 { 0x00, 0x00 }, /* D2 */
532 { 0x00, 0x00 }, /* D3 */
533 { 0x00, 0x00 }, /* D4 */
534 { 0x00, 0x00 }, /* D5 */
535 { 0x00, 0x00 }, /* D6 */
536 { 0x00, 0x00 }, /* D7 */
537 { 0x00, 0x00 }, /* D8 */
538 { 0x00, 0x00 }, /* D9 */
539 { 0x00, 0x00 }, /* DA */
540 { 0x00, 0x00 }, /* DB */
541 { 0x00, 0x00 }, /* DC */
542 { 0x00, 0x00 }, /* DD */
543 { 0x00, 0x00 }, /* DE */
544 { 0x00, 0x00 }, /* DF */
545 { 0x00, 0x00 }, /* E0 */
546 { 0x00, 0x00 }, /* E1 */
547 { 0x00, 0x00 }, /* E2 */
548 { 0x00, 0x00 }, /* E3 */
549 { 0x00, 0x00 }, /* E4 */
550 { 0x00, 0x00 }, /* E5 */
551 { 0x00, 0x00 }, /* E6 */
552 { 0x00, 0x00 }, /* E7 */
553 { 0x00, 0x00 }, /* E8 */
554 { 0x00, 0x00 }, /* E9 */
555 { 0x00, 0x00 }, /* EA */
556 { 0x00, 0x00 }, /* EB */
557 { 0x00, 0x00 }, /* EC */
558 { 0x00, 0x00 }, /* ED */
559 { 0x00, 0x00 }, /* EE */
560 { 0x00, 0x00 }, /* EF */
561 { 0x00, 0x00 }, /* F0 */
562 { 0x00, 0x00 }, /* F1 */
563 { 0x00, 0x00 }, /* F2 */
564 { 0x00, 0x00 }, /* F3 */
565 { 0x00, 0x00 }, /* F4 */
566 { 0x00, 0x00 }, /* F5 */
567 { 0x00, 0x00 }, /* F6 */
568 { 0x00, 0x00 }, /* F7 */
569 { 0x00, 0x00 }, /* F8 */
570 { 0x00, 0x00 }, /* F9 */
571 { 0x00, 0x00 }, /* FA */
572 { 0x00, 0x00 }, /* FB */
573 { 0x00, 0x00 }, /* FC */
574 { 0x00, 0x00 }, /* FD */
575 { 0x00, 0x00 }, /* FE */
576 { 0xFF, 0x00 }, /* FF */
577};
578
579static int max98095_readable(struct snd_soc_codec *codec, unsigned int reg)
580{
581 if (reg >= M98095_REG_CNT)
582 return 0;
583 return max98095_access[reg].readable != 0;
584}
585
586static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg)
587{
588 if (reg > M98095_REG_MAX_CACHED)
589 return 1;
590
591 switch (reg) {
592 case M98095_000_HOST_DATA:
593 case M98095_001_HOST_INT_STS:
594 case M98095_002_HOST_RSP_STS:
595 case M98095_003_HOST_CMD_STS:
596 case M98095_004_CODEC_STS:
597 case M98095_005_DAI1_ALC_STS:
598 case M98095_006_DAI2_ALC_STS:
599 case M98095_007_JACK_AUTO_STS:
600 case M98095_008_JACK_MANUAL_STS:
601 case M98095_009_JACK_VBAT_STS:
602 case M98095_00A_ACC_ADC_STS:
603 case M98095_00B_MIC_NG_AGC_STS:
604 case M98095_00C_SPK_L_VOLT_STS:
605 case M98095_00D_SPK_R_VOLT_STS:
606 case M98095_00E_TEMP_SENSOR_STS:
607 return 1;
608 }
609
610 return 0;
611}
612
613/*
614 * Filter coefficients are in a separate register segment
615 * and they share the address space of the normal registers.
616 * The coefficient registers do not need or share the cache.
617 */
618static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg,
619 unsigned int value)
620{
621 u8 data[2];
622
623 data[0] = reg;
624 data[1] = value;
625 if (codec->hw_write(codec->control_data, data, 2) == 2)
626 return 0;
627 else
628 return -EIO;
629}
630
631/*
632 * Load equalizer DSP coefficient configurations registers
633 */
634static void m98095_eq_band(struct snd_soc_codec *codec, unsigned int dai,
635 unsigned int band, u16 *coefs)
636{
637 unsigned int eq_reg;
638 unsigned int i;
639
640 BUG_ON(band > 4);
641 BUG_ON(dai > 1);
642
643 /* Load the base register address */
644 eq_reg = dai ? M98095_142_DAI2_EQ_BASE : M98095_110_DAI1_EQ_BASE;
645
646 /* Add the band address offset, note adjustment for word address */
647 eq_reg += band * (M98095_COEFS_PER_BAND << 1);
648
649 /* Step through the registers and coefs */
650 for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
651 max98095_hw_write(codec, eq_reg++, M98095_BYTE1(coefs[i]));
652 max98095_hw_write(codec, eq_reg++, M98095_BYTE0(coefs[i]));
653 }
654}
655
656/*
657 * Load biquad filter coefficient configurations registers
658 */
659static void m98095_biquad_band(struct snd_soc_codec *codec, unsigned int dai,
660 unsigned int band, u16 *coefs)
661{
662 unsigned int bq_reg;
663 unsigned int i;
664
665 BUG_ON(band > 1);
666 BUG_ON(dai > 1);
667
668 /* Load the base register address */
669 bq_reg = dai ? M98095_17E_DAI2_BQ_BASE : M98095_174_DAI1_BQ_BASE;
670
671 /* Add the band address offset, note adjustment for word address */
672 bq_reg += band * (M98095_COEFS_PER_BAND << 1);
673
674 /* Step through the registers and coefs */
675 for (i = 0; i < M98095_COEFS_PER_BAND; i++) {
676 max98095_hw_write(codec, bq_reg++, M98095_BYTE1(coefs[i]));
677 max98095_hw_write(codec, bq_reg++, M98095_BYTE0(coefs[i]));
678 }
679}
680
681static const char * const max98095_fltr_mode[] = { "Voice", "Music" };
682static const struct soc_enum max98095_dai1_filter_mode_enum[] = {
683 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 7, 2, max98095_fltr_mode),
684};
685static const struct soc_enum max98095_dai2_filter_mode_enum[] = {
686 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 7, 2, max98095_fltr_mode),
687};
688
689static const char * const max98095_extmic_text[] = { "None", "MIC1", "MIC2" };
690
691static const struct soc_enum max98095_extmic_enum =
692 SOC_ENUM_SINGLE(M98095_087_CFG_MIC, 0, 3, max98095_extmic_text);
693
694static const struct snd_kcontrol_new max98095_extmic_mux =
695 SOC_DAPM_ENUM("External MIC Mux", max98095_extmic_enum);
696
697static const char * const max98095_linein_text[] = { "INA", "INB" };
698
699static const struct soc_enum max98095_linein_enum =
700 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 6, 2, max98095_linein_text);
701
702static const struct snd_kcontrol_new max98095_linein_mux =
703 SOC_DAPM_ENUM("Linein Input Mux", max98095_linein_enum);
704
705static const char * const max98095_line_mode_text[] = {
706 "Stereo", "Differential"};
707
708static const struct soc_enum max98095_linein_mode_enum =
709 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 7, 2, max98095_line_mode_text);
710
711static const struct soc_enum max98095_lineout_mode_enum =
712 SOC_ENUM_SINGLE(M98095_086_CFG_LINE, 4, 2, max98095_line_mode_text);
713
714static const char * const max98095_dai_fltr[] = {
715 "Off", "Elliptical-HPF-16k", "Butterworth-HPF-16k",
716 "Elliptical-HPF-8k", "Butterworth-HPF-8k", "Butterworth-HPF-Fs/240"};
717static const struct soc_enum max98095_dai1_dac_filter_enum[] = {
718 SOC_ENUM_SINGLE(M98095_02E_DAI1_FILTERS, 0, 6, max98095_dai_fltr),
719};
720static const struct soc_enum max98095_dai2_dac_filter_enum[] = {
721 SOC_ENUM_SINGLE(M98095_038_DAI2_FILTERS, 0, 6, max98095_dai_fltr),
722};
723static const struct soc_enum max98095_dai3_dac_filter_enum[] = {
724 SOC_ENUM_SINGLE(M98095_042_DAI3_FILTERS, 0, 6, max98095_dai_fltr),
725};
726
727static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_value *ucontrol)
729{
730 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
731 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
732 unsigned int sel = ucontrol->value.integer.value[0];
733
734 max98095->mic1pre = sel;
735 snd_soc_update_bits(codec, M98095_05F_LVL_MIC1, M98095_MICPRE_MASK,
736 (1+sel)<<M98095_MICPRE_SHIFT);
737
738 return 0;
739}
740
741static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
743{
744 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
745 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
746
747 ucontrol->value.integer.value[0] = max98095->mic1pre;
748 return 0;
749}
750
751static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
753{
754 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
755 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
756 unsigned int sel = ucontrol->value.integer.value[0];
757
758 max98095->mic2pre = sel;
759 snd_soc_update_bits(codec, M98095_060_LVL_MIC2, M98095_MICPRE_MASK,
760 (1+sel)<<M98095_MICPRE_SHIFT);
761
762 return 0;
763}
764
765static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
769 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
770
771 ucontrol->value.integer.value[0] = max98095->mic2pre;
772 return 0;
773}
774
775static const unsigned int max98095_micboost_tlv[] = {
776 TLV_DB_RANGE_HEAD(2),
777 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
778 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
779};
780
781static const DECLARE_TLV_DB_SCALE(max98095_mic_tlv, 0, 100, 0);
782static const DECLARE_TLV_DB_SCALE(max98095_adc_tlv, -1200, 100, 0);
783static const DECLARE_TLV_DB_SCALE(max98095_adcboost_tlv, 0, 600, 0);
784
785static const unsigned int max98095_hp_tlv[] = {
786 TLV_DB_RANGE_HEAD(5),
787 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),
788 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),
789 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),
790 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),
791 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0),
792};
793
794static const unsigned int max98095_spk_tlv[] = {
795 TLV_DB_RANGE_HEAD(4),
796 0, 10, TLV_DB_SCALE_ITEM(-5900, 400, 0),
797 11, 18, TLV_DB_SCALE_ITEM(-1700, 200, 0),
798 19, 27, TLV_DB_SCALE_ITEM(-200, 100, 0),
799 28, 39, TLV_DB_SCALE_ITEM(650, 50, 0),
800};
801
802static const unsigned int max98095_rcv_lout_tlv[] = {
803 TLV_DB_RANGE_HEAD(5),
804 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),
805 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),
806 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),
807 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),
808 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0),
809};
810
811static const unsigned int max98095_lin_tlv[] = {
812 TLV_DB_RANGE_HEAD(3),
813 0, 2, TLV_DB_SCALE_ITEM(-600, 300, 0),
814 3, 3, TLV_DB_SCALE_ITEM(300, 1100, 0),
815 4, 5, TLV_DB_SCALE_ITEM(1400, 600, 0),
816};
817
818static const struct snd_kcontrol_new max98095_snd_controls[] = {
819
820 SOC_DOUBLE_R_TLV("Headphone Volume", M98095_064_LVL_HP_L,
821 M98095_065_LVL_HP_R, 0, 31, 0, max98095_hp_tlv),
822
823 SOC_DOUBLE_R_TLV("Speaker Volume", M98095_067_LVL_SPK_L,
824 M98095_068_LVL_SPK_R, 0, 39, 0, max98095_spk_tlv),
825
826 SOC_SINGLE_TLV("Receiver Volume", M98095_066_LVL_RCV,
827 0, 31, 0, max98095_rcv_lout_tlv),
828
829 SOC_DOUBLE_R_TLV("Lineout Volume", M98095_062_LVL_LINEOUT1,
830 M98095_063_LVL_LINEOUT2, 0, 31, 0, max98095_rcv_lout_tlv),
831
832 SOC_DOUBLE_R("Headphone Switch", M98095_064_LVL_HP_L,
833 M98095_065_LVL_HP_R, 7, 1, 1),
834
835 SOC_DOUBLE_R("Speaker Switch", M98095_067_LVL_SPK_L,
836 M98095_068_LVL_SPK_R, 7, 1, 1),
837
838 SOC_SINGLE("Receiver Switch", M98095_066_LVL_RCV, 7, 1, 1),
839
840 SOC_DOUBLE_R("Lineout Switch", M98095_062_LVL_LINEOUT1,
841 M98095_063_LVL_LINEOUT2, 7, 1, 1),
842
843 SOC_SINGLE_TLV("MIC1 Volume", M98095_05F_LVL_MIC1, 0, 20, 1,
844 max98095_mic_tlv),
845
846 SOC_SINGLE_TLV("MIC2 Volume", M98095_060_LVL_MIC2, 0, 20, 1,
847 max98095_mic_tlv),
848
849 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
850 M98095_05F_LVL_MIC1, 5, 2, 0,
851 max98095_mic1pre_get, max98095_mic1pre_set,
852 max98095_micboost_tlv),
853 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",
854 M98095_060_LVL_MIC2, 5, 2, 0,
855 max98095_mic2pre_get, max98095_mic2pre_set,
856 max98095_micboost_tlv),
857
858 SOC_SINGLE_TLV("Linein Volume", M98095_061_LVL_LINEIN, 0, 5, 1,
859 max98095_lin_tlv),
860
861 SOC_SINGLE_TLV("ADCL Volume", M98095_05D_LVL_ADC_L, 0, 15, 1,
862 max98095_adc_tlv),
863 SOC_SINGLE_TLV("ADCR Volume", M98095_05E_LVL_ADC_R, 0, 15, 1,
864 max98095_adc_tlv),
865
866 SOC_SINGLE_TLV("ADCL Boost Volume", M98095_05D_LVL_ADC_L, 4, 3, 0,
867 max98095_adcboost_tlv),
868 SOC_SINGLE_TLV("ADCR Boost Volume", M98095_05E_LVL_ADC_R, 4, 3, 0,
869 max98095_adcboost_tlv),
870
871 SOC_SINGLE("EQ1 Switch", M98095_088_CFG_LEVEL, 0, 1, 0),
872 SOC_SINGLE("EQ2 Switch", M98095_088_CFG_LEVEL, 1, 1, 0),
873
874 SOC_SINGLE("Biquad1 Switch", M98095_088_CFG_LEVEL, 2, 1, 0),
875 SOC_SINGLE("Biquad2 Switch", M98095_088_CFG_LEVEL, 3, 1, 0),
876
877 SOC_ENUM("DAI1 Filter Mode", max98095_dai1_filter_mode_enum),
878 SOC_ENUM("DAI2 Filter Mode", max98095_dai2_filter_mode_enum),
879 SOC_ENUM("DAI1 DAC Filter", max98095_dai1_dac_filter_enum),
880 SOC_ENUM("DAI2 DAC Filter", max98095_dai2_dac_filter_enum),
881 SOC_ENUM("DAI3 DAC Filter", max98095_dai3_dac_filter_enum),
882
883 SOC_ENUM("Linein Mode", max98095_linein_mode_enum),
884 SOC_ENUM("Lineout Mode", max98095_lineout_mode_enum),
885};
886
887/* Left speaker mixer switch */
888static const struct snd_kcontrol_new max98095_left_speaker_mixer_controls[] = {
889 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_050_MIX_SPK_LEFT, 0, 1, 0),
890 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_050_MIX_SPK_LEFT, 6, 1, 0),
891 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
892 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_050_MIX_SPK_LEFT, 3, 1, 0),
893 SOC_DAPM_SINGLE("MIC1 Switch", M98095_050_MIX_SPK_LEFT, 4, 1, 0),
894 SOC_DAPM_SINGLE("MIC2 Switch", M98095_050_MIX_SPK_LEFT, 5, 1, 0),
895 SOC_DAPM_SINGLE("IN1 Switch", M98095_050_MIX_SPK_LEFT, 1, 1, 0),
896 SOC_DAPM_SINGLE("IN2 Switch", M98095_050_MIX_SPK_LEFT, 2, 1, 0),
897};
898
899/* Right speaker mixer switch */
900static const struct snd_kcontrol_new max98095_right_speaker_mixer_controls[] = {
901 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 6, 1, 0),
902 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_051_MIX_SPK_RIGHT, 0, 1, 0),
903 SOC_DAPM_SINGLE("Mono DAC2 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
904 SOC_DAPM_SINGLE("Mono DAC3 Switch", M98095_051_MIX_SPK_RIGHT, 3, 1, 0),
905 SOC_DAPM_SINGLE("MIC1 Switch", M98095_051_MIX_SPK_RIGHT, 5, 1, 0),
906 SOC_DAPM_SINGLE("MIC2 Switch", M98095_051_MIX_SPK_RIGHT, 4, 1, 0),
907 SOC_DAPM_SINGLE("IN1 Switch", M98095_051_MIX_SPK_RIGHT, 1, 1, 0),
908 SOC_DAPM_SINGLE("IN2 Switch", M98095_051_MIX_SPK_RIGHT, 2, 1, 0),
909};
910
911/* Left headphone mixer switch */
912static const struct snd_kcontrol_new max98095_left_hp_mixer_controls[] = {
913 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04C_MIX_HP_LEFT, 0, 1, 0),
914 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04C_MIX_HP_LEFT, 5, 1, 0),
915 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04C_MIX_HP_LEFT, 3, 1, 0),
916 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04C_MIX_HP_LEFT, 4, 1, 0),
917 SOC_DAPM_SINGLE("IN1 Switch", M98095_04C_MIX_HP_LEFT, 1, 1, 0),
918 SOC_DAPM_SINGLE("IN2 Switch", M98095_04C_MIX_HP_LEFT, 2, 1, 0),
919};
920
921/* Right headphone mixer switch */
922static const struct snd_kcontrol_new max98095_right_hp_mixer_controls[] = {
923 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 5, 1, 0),
924 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04D_MIX_HP_RIGHT, 0, 1, 0),
925 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04D_MIX_HP_RIGHT, 3, 1, 0),
926 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04D_MIX_HP_RIGHT, 4, 1, 0),
927 SOC_DAPM_SINGLE("IN1 Switch", M98095_04D_MIX_HP_RIGHT, 1, 1, 0),
928 SOC_DAPM_SINGLE("IN2 Switch", M98095_04D_MIX_HP_RIGHT, 2, 1, 0),
929};
930
931/* Receiver earpiece mixer switch */
932static const struct snd_kcontrol_new max98095_mono_rcv_mixer_controls[] = {
933 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_04F_MIX_RCV, 0, 1, 0),
934 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_04F_MIX_RCV, 5, 1, 0),
935 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04F_MIX_RCV, 3, 1, 0),
936 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04F_MIX_RCV, 4, 1, 0),
937 SOC_DAPM_SINGLE("IN1 Switch", M98095_04F_MIX_RCV, 1, 1, 0),
938 SOC_DAPM_SINGLE("IN2 Switch", M98095_04F_MIX_RCV, 2, 1, 0),
939};
940
941/* Left lineout mixer switch */
942static const struct snd_kcontrol_new max98095_left_lineout_mixer_controls[] = {
943 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_053_MIX_LINEOUT1, 5, 1, 0),
944 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_053_MIX_LINEOUT1, 0, 1, 0),
945 SOC_DAPM_SINGLE("MIC1 Switch", M98095_053_MIX_LINEOUT1, 3, 1, 0),
946 SOC_DAPM_SINGLE("MIC2 Switch", M98095_053_MIX_LINEOUT1, 4, 1, 0),
947 SOC_DAPM_SINGLE("IN1 Switch", M98095_053_MIX_LINEOUT1, 1, 1, 0),
948 SOC_DAPM_SINGLE("IN2 Switch", M98095_053_MIX_LINEOUT1, 2, 1, 0),
949};
950
951/* Right lineout mixer switch */
952static const struct snd_kcontrol_new max98095_right_lineout_mixer_controls[] = {
953 SOC_DAPM_SINGLE("Left DAC1 Switch", M98095_054_MIX_LINEOUT2, 0, 1, 0),
954 SOC_DAPM_SINGLE("Right DAC1 Switch", M98095_054_MIX_LINEOUT2, 5, 1, 0),
955 SOC_DAPM_SINGLE("MIC1 Switch", M98095_054_MIX_LINEOUT2, 3, 1, 0),
956 SOC_DAPM_SINGLE("MIC2 Switch", M98095_054_MIX_LINEOUT2, 4, 1, 0),
957 SOC_DAPM_SINGLE("IN1 Switch", M98095_054_MIX_LINEOUT2, 1, 1, 0),
958 SOC_DAPM_SINGLE("IN2 Switch", M98095_054_MIX_LINEOUT2, 2, 1, 0),
959};
960
961/* Left ADC mixer switch */
962static const struct snd_kcontrol_new max98095_left_ADC_mixer_controls[] = {
963 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04A_MIX_ADC_LEFT, 7, 1, 0),
964 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04A_MIX_ADC_LEFT, 6, 1, 0),
965 SOC_DAPM_SINGLE("IN1 Switch", M98095_04A_MIX_ADC_LEFT, 3, 1, 0),
966 SOC_DAPM_SINGLE("IN2 Switch", M98095_04A_MIX_ADC_LEFT, 2, 1, 0),
967};
968
969/* Right ADC mixer switch */
970static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
971 SOC_DAPM_SINGLE("MIC1 Switch", M98095_04B_MIX_ADC_RIGHT, 7, 1, 0),
972 SOC_DAPM_SINGLE("MIC2 Switch", M98095_04B_MIX_ADC_RIGHT, 6, 1, 0),
973 SOC_DAPM_SINGLE("IN1 Switch", M98095_04B_MIX_ADC_RIGHT, 3, 1, 0),
974 SOC_DAPM_SINGLE("IN2 Switch", M98095_04B_MIX_ADC_RIGHT, 2, 1, 0),
975};
976
977static int max98095_mic_event(struct snd_soc_dapm_widget *w,
978 struct snd_kcontrol *kcontrol, int event)
979{
980 struct snd_soc_codec *codec = w->codec;
981 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
982
983 switch (event) {
984 case SND_SOC_DAPM_POST_PMU:
985 if (w->reg == M98095_05F_LVL_MIC1) {
986 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
987 (1+max98095->mic1pre)<<M98095_MICPRE_SHIFT);
988 } else {
989 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK,
990 (1+max98095->mic2pre)<<M98095_MICPRE_SHIFT);
991 }
992 break;
993 case SND_SOC_DAPM_POST_PMD:
994 snd_soc_update_bits(codec, w->reg, M98095_MICPRE_MASK, 0);
995 break;
996 default:
997 return -EINVAL;
998 }
999
1000 return 0;
1001}
1002
1003/*
1004 * The line inputs are stereo inputs with the left and right
1005 * channels sharing a common PGA power control signal.
1006 */
1007static int max98095_line_pga(struct snd_soc_dapm_widget *w,
1008 int event, u8 channel)
1009{
1010 struct snd_soc_codec *codec = w->codec;
1011 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1012 u8 *state;
1013
1014 BUG_ON(!((channel == 1) || (channel == 2)));
1015
1016 state = &max98095->lin_state;
1017
1018 switch (event) {
1019 case SND_SOC_DAPM_POST_PMU:
1020 *state |= channel;
1021 snd_soc_update_bits(codec, w->reg,
1022 (1 << w->shift), (1 << w->shift));
1023 break;
1024 case SND_SOC_DAPM_POST_PMD:
1025 *state &= ~channel;
1026 if (*state == 0) {
1027 snd_soc_update_bits(codec, w->reg,
1028 (1 << w->shift), 0);
1029 }
1030 break;
1031 default:
1032 return -EINVAL;
1033 }
1034
1035 return 0;
1036}
1037
1038static int max98095_pga_in1_event(struct snd_soc_dapm_widget *w,
1039 struct snd_kcontrol *k, int event)
1040{
1041 return max98095_line_pga(w, event, 1);
1042}
1043
1044static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
1045 struct snd_kcontrol *k, int event)
1046{
1047 return max98095_line_pga(w, event, 2);
1048}
1049
1050/*
1051 * The stereo line out mixer outputs to two stereo line outs.
1052 * The 2nd pair has a separate set of enables.
1053 */
1054static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
1055 struct snd_kcontrol *kcontrol, int event)
1056{
1057 struct snd_soc_codec *codec = w->codec;
1058
1059 switch (event) {
1060 case SND_SOC_DAPM_POST_PMU:
1061 snd_soc_update_bits(codec, w->reg,
1062 (1 << (w->shift+2)), (1 << (w->shift+2)));
1063 break;
1064 case SND_SOC_DAPM_POST_PMD:
1065 snd_soc_update_bits(codec, w->reg,
1066 (1 << (w->shift+2)), 0);
1067 break;
1068 default:
1069 return -EINVAL;
1070 }
1071
1072 return 0;
1073}
1074
1075static const struct snd_soc_dapm_widget max98095_dapm_widgets[] = {
1076
1077 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98095_090_PWR_EN_IN, 0, 0),
1078 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98095_090_PWR_EN_IN, 1, 0),
1079
1080 SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",
1081 M98095_091_PWR_EN_OUT, 0, 0),
1082 SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",
1083 M98095_091_PWR_EN_OUT, 1, 0),
1084 SND_SOC_DAPM_DAC("DACM2", "Aux Playback",
1085 M98095_091_PWR_EN_OUT, 2, 0),
1086 SND_SOC_DAPM_DAC("DACM3", "Voice Playback",
1087 M98095_091_PWR_EN_OUT, 2, 0),
1088
1089 SND_SOC_DAPM_PGA("HP Left Out", M98095_091_PWR_EN_OUT,
1090 6, 0, NULL, 0),
1091 SND_SOC_DAPM_PGA("HP Right Out", M98095_091_PWR_EN_OUT,
1092 7, 0, NULL, 0),
1093
1094 SND_SOC_DAPM_PGA("SPK Left Out", M98095_091_PWR_EN_OUT,
1095 4, 0, NULL, 0),
1096 SND_SOC_DAPM_PGA("SPK Right Out", M98095_091_PWR_EN_OUT,
1097 5, 0, NULL, 0),
1098
1099 SND_SOC_DAPM_PGA("RCV Mono Out", M98095_091_PWR_EN_OUT,
1100 3, 0, NULL, 0),
1101
1102 SND_SOC_DAPM_PGA_E("LINE Left Out", M98095_092_PWR_EN_OUT,
1103 0, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1104 SND_SOC_DAPM_PGA_E("LINE Right Out", M98095_092_PWR_EN_OUT,
1105 1, 0, NULL, 0, max98095_lineout_event, SND_SOC_DAPM_PRE_PMD),
1106
1107 SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,
1108 &max98095_extmic_mux),
1109
1110 SND_SOC_DAPM_MUX("Linein Mux", SND_SOC_NOPM, 0, 0,
1111 &max98095_linein_mux),
1112
1113 SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
1114 &max98095_left_hp_mixer_controls[0],
1115 ARRAY_SIZE(max98095_left_hp_mixer_controls)),
1116
1117 SND_SOC_DAPM_MIXER("Right Headphone Mixer", SND_SOC_NOPM, 0, 0,
1118 &max98095_right_hp_mixer_controls[0],
1119 ARRAY_SIZE(max98095_right_hp_mixer_controls)),
1120
1121 SND_SOC_DAPM_MIXER("Left Speaker Mixer", SND_SOC_NOPM, 0, 0,
1122 &max98095_left_speaker_mixer_controls[0],
1123 ARRAY_SIZE(max98095_left_speaker_mixer_controls)),
1124
1125 SND_SOC_DAPM_MIXER("Right Speaker Mixer", SND_SOC_NOPM, 0, 0,
1126 &max98095_right_speaker_mixer_controls[0],
1127 ARRAY_SIZE(max98095_right_speaker_mixer_controls)),
1128
1129 SND_SOC_DAPM_MIXER("Receiver Mixer", SND_SOC_NOPM, 0, 0,
1130 &max98095_mono_rcv_mixer_controls[0],
1131 ARRAY_SIZE(max98095_mono_rcv_mixer_controls)),
1132
1133 SND_SOC_DAPM_MIXER("Left Lineout Mixer", SND_SOC_NOPM, 0, 0,
1134 &max98095_left_lineout_mixer_controls[0],
1135 ARRAY_SIZE(max98095_left_lineout_mixer_controls)),
1136
1137 SND_SOC_DAPM_MIXER("Right Lineout Mixer", SND_SOC_NOPM, 0, 0,
1138 &max98095_right_lineout_mixer_controls[0],
1139 ARRAY_SIZE(max98095_right_lineout_mixer_controls)),
1140
1141 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1142 &max98095_left_ADC_mixer_controls[0],
1143 ARRAY_SIZE(max98095_left_ADC_mixer_controls)),
1144
1145 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1146 &max98095_right_ADC_mixer_controls[0],
1147 ARRAY_SIZE(max98095_right_ADC_mixer_controls)),
1148
1149 SND_SOC_DAPM_PGA_E("MIC1 Input", M98095_05F_LVL_MIC1,
1150 5, 0, NULL, 0, max98095_mic_event,
1151 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1152
1153 SND_SOC_DAPM_PGA_E("MIC2 Input", M98095_060_LVL_MIC2,
1154 5, 0, NULL, 0, max98095_mic_event,
1155 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1156
1157 SND_SOC_DAPM_PGA_E("IN1 Input", M98095_090_PWR_EN_IN,
1158 7, 0, NULL, 0, max98095_pga_in1_event,
1159 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1160
1161 SND_SOC_DAPM_PGA_E("IN2 Input", M98095_090_PWR_EN_IN,
1162 7, 0, NULL, 0, max98095_pga_in2_event,
1163 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1164
1165 SND_SOC_DAPM_MICBIAS("MICBIAS1", M98095_090_PWR_EN_IN, 2, 0),
1166 SND_SOC_DAPM_MICBIAS("MICBIAS2", M98095_090_PWR_EN_IN, 3, 0),
1167
1168 SND_SOC_DAPM_OUTPUT("HPL"),
1169 SND_SOC_DAPM_OUTPUT("HPR"),
1170 SND_SOC_DAPM_OUTPUT("SPKL"),
1171 SND_SOC_DAPM_OUTPUT("SPKR"),
1172 SND_SOC_DAPM_OUTPUT("RCV"),
1173 SND_SOC_DAPM_OUTPUT("OUT1"),
1174 SND_SOC_DAPM_OUTPUT("OUT2"),
1175 SND_SOC_DAPM_OUTPUT("OUT3"),
1176 SND_SOC_DAPM_OUTPUT("OUT4"),
1177
1178 SND_SOC_DAPM_INPUT("MIC1"),
1179 SND_SOC_DAPM_INPUT("MIC2"),
1180 SND_SOC_DAPM_INPUT("INA1"),
1181 SND_SOC_DAPM_INPUT("INA2"),
1182 SND_SOC_DAPM_INPUT("INB1"),
1183 SND_SOC_DAPM_INPUT("INB2"),
1184};
1185
1186static const struct snd_soc_dapm_route max98095_audio_map[] = {
1187 /* Left headphone output mixer */
1188 {"Left Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1189 {"Left Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1190 {"Left Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1191 {"Left Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1192 {"Left Headphone Mixer", "IN1 Switch", "IN1 Input"},
1193 {"Left Headphone Mixer", "IN2 Switch", "IN2 Input"},
1194
1195 /* Right headphone output mixer */
1196 {"Right Headphone Mixer", "Left DAC1 Switch", "DACL1"},
1197 {"Right Headphone Mixer", "Right DAC1 Switch", "DACR1"},
1198 {"Right Headphone Mixer", "MIC1 Switch", "MIC1 Input"},
1199 {"Right Headphone Mixer", "MIC2 Switch", "MIC2 Input"},
1200 {"Right Headphone Mixer", "IN1 Switch", "IN1 Input"},
1201 {"Right Headphone Mixer", "IN2 Switch", "IN2 Input"},
1202
1203 /* Left speaker output mixer */
1204 {"Left Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1205 {"Left Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1206 {"Left Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1207 {"Left Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1208 {"Left Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1209 {"Left Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1210 {"Left Speaker Mixer", "IN1 Switch", "IN1 Input"},
1211 {"Left Speaker Mixer", "IN2 Switch", "IN2 Input"},
1212
1213 /* Right speaker output mixer */
1214 {"Right Speaker Mixer", "Left DAC1 Switch", "DACL1"},
1215 {"Right Speaker Mixer", "Right DAC1 Switch", "DACR1"},
1216 {"Right Speaker Mixer", "Mono DAC2 Switch", "DACM2"},
1217 {"Right Speaker Mixer", "Mono DAC3 Switch", "DACM3"},
1218 {"Right Speaker Mixer", "MIC1 Switch", "MIC1 Input"},
1219 {"Right Speaker Mixer", "MIC2 Switch", "MIC2 Input"},
1220 {"Right Speaker Mixer", "IN1 Switch", "IN1 Input"},
1221 {"Right Speaker Mixer", "IN2 Switch", "IN2 Input"},
1222
1223 /* Earpiece/Receiver output mixer */
1224 {"Receiver Mixer", "Left DAC1 Switch", "DACL1"},
1225 {"Receiver Mixer", "Right DAC1 Switch", "DACR1"},
1226 {"Receiver Mixer", "MIC1 Switch", "MIC1 Input"},
1227 {"Receiver Mixer", "MIC2 Switch", "MIC2 Input"},
1228 {"Receiver Mixer", "IN1 Switch", "IN1 Input"},
1229 {"Receiver Mixer", "IN2 Switch", "IN2 Input"},
1230
1231 /* Left Lineout output mixer */
1232 {"Left Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1233 {"Left Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1234 {"Left Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1235 {"Left Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1236 {"Left Lineout Mixer", "IN1 Switch", "IN1 Input"},
1237 {"Left Lineout Mixer", "IN2 Switch", "IN2 Input"},
1238
1239 /* Right lineout output mixer */
1240 {"Right Lineout Mixer", "Left DAC1 Switch", "DACL1"},
1241 {"Right Lineout Mixer", "Right DAC1 Switch", "DACR1"},
1242 {"Right Lineout Mixer", "MIC1 Switch", "MIC1 Input"},
1243 {"Right Lineout Mixer", "MIC2 Switch", "MIC2 Input"},
1244 {"Right Lineout Mixer", "IN1 Switch", "IN1 Input"},
1245 {"Right Lineout Mixer", "IN2 Switch", "IN2 Input"},
1246
1247 {"HP Left Out", NULL, "Left Headphone Mixer"},
1248 {"HP Right Out", NULL, "Right Headphone Mixer"},
1249 {"SPK Left Out", NULL, "Left Speaker Mixer"},
1250 {"SPK Right Out", NULL, "Right Speaker Mixer"},
1251 {"RCV Mono Out", NULL, "Receiver Mixer"},
1252 {"LINE Left Out", NULL, "Left Lineout Mixer"},
1253 {"LINE Right Out", NULL, "Right Lineout Mixer"},
1254
1255 {"HPL", NULL, "HP Left Out"},
1256 {"HPR", NULL, "HP Right Out"},
1257 {"SPKL", NULL, "SPK Left Out"},
1258 {"SPKR", NULL, "SPK Right Out"},
1259 {"RCV", NULL, "RCV Mono Out"},
1260 {"OUT1", NULL, "LINE Left Out"},
1261 {"OUT2", NULL, "LINE Right Out"},
1262 {"OUT3", NULL, "LINE Left Out"},
1263 {"OUT4", NULL, "LINE Right Out"},
1264
1265 /* Left ADC input mixer */
1266 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1267 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1268 {"Left ADC Mixer", "IN1 Switch", "IN1 Input"},
1269 {"Left ADC Mixer", "IN2 Switch", "IN2 Input"},
1270
1271 /* Right ADC input mixer */
1272 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},
1273 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},
1274 {"Right ADC Mixer", "IN1 Switch", "IN1 Input"},
1275 {"Right ADC Mixer", "IN2 Switch", "IN2 Input"},
1276
1277 /* Inputs */
1278 {"ADCL", NULL, "Left ADC Mixer"},
1279 {"ADCR", NULL, "Right ADC Mixer"},
1280
1281 {"IN1 Input", NULL, "INA1"},
1282 {"IN2 Input", NULL, "INA2"},
1283
1284 {"MIC1 Input", NULL, "MIC1"},
1285 {"MIC2 Input", NULL, "MIC2"},
1286};
1287
1288static int max98095_add_widgets(struct snd_soc_codec *codec)
1289{
1290 snd_soc_add_controls(codec, max98095_snd_controls,
1291 ARRAY_SIZE(max98095_snd_controls));
1292
1293 return 0;
1294}
1295
1296/* codec mclk clock divider coefficients */
1297static const struct {
1298 u32 rate;
1299 u8 sr;
1300} rate_table[] = {
1301 {8000, 0x01},
1302 {11025, 0x02},
1303 {16000, 0x03},
1304 {22050, 0x04},
1305 {24000, 0x05},
1306 {32000, 0x06},
1307 {44100, 0x07},
1308 {48000, 0x08},
1309 {88200, 0x09},
1310 {96000, 0x0A},
1311};
1312
1313static int rate_value(int rate, u8 *value)
1314{
1315 int i;
1316
1317 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
1318 if (rate_table[i].rate >= rate) {
1319 *value = rate_table[i].sr;
1320 return 0;
1321 }
1322 }
1323 *value = rate_table[0].sr;
1324 return -EINVAL;
1325}
1326
1327static int max98095_dai1_hw_params(struct snd_pcm_substream *substream,
1328 struct snd_pcm_hw_params *params,
1329 struct snd_soc_dai *dai)
1330{
1331 struct snd_soc_codec *codec = dai->codec;
1332 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1333 struct max98095_cdata *cdata;
1334 unsigned long long ni;
1335 unsigned int rate;
1336 u8 regval;
1337
1338 cdata = &max98095->dai[0];
1339
1340 rate = params_rate(params);
1341
1342 switch (params_format(params)) {
1343 case SNDRV_PCM_FORMAT_S16_LE:
1344 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1345 M98095_DAI_WS, 0);
1346 break;
1347 case SNDRV_PCM_FORMAT_S24_LE:
1348 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1349 M98095_DAI_WS, M98095_DAI_WS);
1350 break;
1351 default:
1352 return -EINVAL;
1353 }
1354
1355 if (rate_value(rate, &regval))
1356 return -EINVAL;
1357
1358 snd_soc_update_bits(codec, M98095_027_DAI1_CLKMODE,
1359 M98095_CLKMODE_MASK, regval);
1360 cdata->rate = rate;
1361
1362 /* Configure NI when operating as master */
1363 if (snd_soc_read(codec, M98095_02A_DAI1_FORMAT) & M98095_DAI_MAS) {
1364 if (max98095->sysclk == 0) {
1365 dev_err(codec->dev, "Invalid system clock frequency\n");
1366 return -EINVAL;
1367 }
1368 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1369 * (unsigned long long int)rate;
1370 do_div(ni, (unsigned long long int)max98095->sysclk);
1371 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1372 (ni >> 8) & 0x7F);
1373 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1374 ni & 0xFF);
1375 }
1376
1377 /* Update sample rate mode */
1378 if (rate < 50000)
1379 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1380 M98095_DAI_DHF, 0);
1381 else
1382 snd_soc_update_bits(codec, M98095_02E_DAI1_FILTERS,
1383 M98095_DAI_DHF, M98095_DAI_DHF);
1384
1385 return 0;
1386}
1387
1388static int max98095_dai2_hw_params(struct snd_pcm_substream *substream,
1389 struct snd_pcm_hw_params *params,
1390 struct snd_soc_dai *dai)
1391{
1392 struct snd_soc_codec *codec = dai->codec;
1393 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1394 struct max98095_cdata *cdata;
1395 unsigned long long ni;
1396 unsigned int rate;
1397 u8 regval;
1398
1399 cdata = &max98095->dai[1];
1400
1401 rate = params_rate(params);
1402
1403 switch (params_format(params)) {
1404 case SNDRV_PCM_FORMAT_S16_LE:
1405 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1406 M98095_DAI_WS, 0);
1407 break;
1408 case SNDRV_PCM_FORMAT_S24_LE:
1409 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1410 M98095_DAI_WS, M98095_DAI_WS);
1411 break;
1412 default:
1413 return -EINVAL;
1414 }
1415
1416 if (rate_value(rate, &regval))
1417 return -EINVAL;
1418
1419 snd_soc_update_bits(codec, M98095_031_DAI2_CLKMODE,
1420 M98095_CLKMODE_MASK, regval);
1421 cdata->rate = rate;
1422
1423 /* Configure NI when operating as master */
1424 if (snd_soc_read(codec, M98095_034_DAI2_FORMAT) & M98095_DAI_MAS) {
1425 if (max98095->sysclk == 0) {
1426 dev_err(codec->dev, "Invalid system clock frequency\n");
1427 return -EINVAL;
1428 }
1429 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1430 * (unsigned long long int)rate;
1431 do_div(ni, (unsigned long long int)max98095->sysclk);
1432 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1433 (ni >> 8) & 0x7F);
1434 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1435 ni & 0xFF);
1436 }
1437
1438 /* Update sample rate mode */
1439 if (rate < 50000)
1440 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1441 M98095_DAI_DHF, 0);
1442 else
1443 snd_soc_update_bits(codec, M98095_038_DAI2_FILTERS,
1444 M98095_DAI_DHF, M98095_DAI_DHF);
1445
1446 return 0;
1447}
1448
1449static int max98095_dai3_hw_params(struct snd_pcm_substream *substream,
1450 struct snd_pcm_hw_params *params,
1451 struct snd_soc_dai *dai)
1452{
1453 struct snd_soc_codec *codec = dai->codec;
1454 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1455 struct max98095_cdata *cdata;
1456 unsigned long long ni;
1457 unsigned int rate;
1458 u8 regval;
1459
1460 cdata = &max98095->dai[2];
1461
1462 rate = params_rate(params);
1463
1464 switch (params_format(params)) {
1465 case SNDRV_PCM_FORMAT_S16_LE:
1466 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1467 M98095_DAI_WS, 0);
1468 break;
1469 case SNDRV_PCM_FORMAT_S24_LE:
1470 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1471 M98095_DAI_WS, M98095_DAI_WS);
1472 break;
1473 default:
1474 return -EINVAL;
1475 }
1476
1477 if (rate_value(rate, &regval))
1478 return -EINVAL;
1479
1480 snd_soc_update_bits(codec, M98095_03B_DAI3_CLKMODE,
1481 M98095_CLKMODE_MASK, regval);
1482 cdata->rate = rate;
1483
1484 /* Configure NI when operating as master */
1485 if (snd_soc_read(codec, M98095_03E_DAI3_FORMAT) & M98095_DAI_MAS) {
1486 if (max98095->sysclk == 0) {
1487 dev_err(codec->dev, "Invalid system clock frequency\n");
1488 return -EINVAL;
1489 }
1490 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
1491 * (unsigned long long int)rate;
1492 do_div(ni, (unsigned long long int)max98095->sysclk);
1493 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1494 (ni >> 8) & 0x7F);
1495 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1496 ni & 0xFF);
1497 }
1498
1499 /* Update sample rate mode */
1500 if (rate < 50000)
1501 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1502 M98095_DAI_DHF, 0);
1503 else
1504 snd_soc_update_bits(codec, M98095_042_DAI3_FILTERS,
1505 M98095_DAI_DHF, M98095_DAI_DHF);
1506
1507 return 0;
1508}
1509
1510static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
1511 int clk_id, unsigned int freq, int dir)
1512{
1513 struct snd_soc_codec *codec = dai->codec;
1514 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1515
1516 /* Requested clock frequency is already setup */
1517 if (freq == max98095->sysclk)
1518 return 0;
1519
1520 max98095->sysclk = freq; /* remember current sysclk */
1521
1522 /* Setup clocks for slave mode, and using the PLL
1523 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
1524 * 0x02 (when master clk is 20MHz to 40MHz)..
1525 * 0x03 (when master clk is 40MHz to 60MHz)..
1526 */
1527 if ((freq >= 10000000) && (freq < 20000000)) {
1528 snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
1529 } else if ((freq >= 20000000) && (freq < 40000000)) {
1530 snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
1531 } else if ((freq >= 40000000) && (freq < 60000000)) {
1532 snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
1533 } else {
1534 dev_err(codec->dev, "Invalid master clock frequency\n");
1535 return -EINVAL;
1536 }
1537
1538 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1539
1540 max98095->sysclk = freq;
1541 return 0;
1542}
1543
1544static int max98095_dai1_set_fmt(struct snd_soc_dai *codec_dai,
1545 unsigned int fmt)
1546{
1547 struct snd_soc_codec *codec = codec_dai->codec;
1548 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1549 struct max98095_cdata *cdata;
1550 u8 regval = 0;
1551
1552 cdata = &max98095->dai[0];
1553
1554 if (fmt != cdata->fmt) {
1555 cdata->fmt = fmt;
1556
1557 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1558 case SND_SOC_DAIFMT_CBS_CFS:
1559 /* Slave mode PLL */
1560 snd_soc_write(codec, M98095_028_DAI1_CLKCFG_HI,
1561 0x80);
1562 snd_soc_write(codec, M98095_029_DAI1_CLKCFG_LO,
1563 0x00);
1564 break;
1565 case SND_SOC_DAIFMT_CBM_CFM:
1566 /* Set to master mode */
1567 regval |= M98095_DAI_MAS;
1568 break;
1569 case SND_SOC_DAIFMT_CBS_CFM:
1570 case SND_SOC_DAIFMT_CBM_CFS:
1571 default:
1572 dev_err(codec->dev, "Clock mode unsupported");
1573 return -EINVAL;
1574 }
1575
1576 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1577 case SND_SOC_DAIFMT_I2S:
1578 regval |= M98095_DAI_DLY;
1579 break;
1580 case SND_SOC_DAIFMT_LEFT_J:
1581 break;
1582 default:
1583 return -EINVAL;
1584 }
1585
1586 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1587 case SND_SOC_DAIFMT_NB_NF:
1588 break;
1589 case SND_SOC_DAIFMT_NB_IF:
1590 regval |= M98095_DAI_WCI;
1591 break;
1592 case SND_SOC_DAIFMT_IB_NF:
1593 regval |= M98095_DAI_BCI;
1594 break;
1595 case SND_SOC_DAIFMT_IB_IF:
1596 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1597 break;
1598 default:
1599 return -EINVAL;
1600 }
1601
1602 snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT,
1603 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1604 M98095_DAI_WCI, regval);
1605
1606 snd_soc_write(codec, M98095_02B_DAI1_CLOCK, M98095_DAI_BSEL64);
1607 }
1608
1609 return 0;
1610}
1611
1612static int max98095_dai2_set_fmt(struct snd_soc_dai *codec_dai,
1613 unsigned int fmt)
1614{
1615 struct snd_soc_codec *codec = codec_dai->codec;
1616 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1617 struct max98095_cdata *cdata;
1618 u8 regval = 0;
1619
1620 cdata = &max98095->dai[1];
1621
1622 if (fmt != cdata->fmt) {
1623 cdata->fmt = fmt;
1624
1625 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1626 case SND_SOC_DAIFMT_CBS_CFS:
1627 /* Slave mode PLL */
1628 snd_soc_write(codec, M98095_032_DAI2_CLKCFG_HI,
1629 0x80);
1630 snd_soc_write(codec, M98095_033_DAI2_CLKCFG_LO,
1631 0x00);
1632 break;
1633 case SND_SOC_DAIFMT_CBM_CFM:
1634 /* Set to master mode */
1635 regval |= M98095_DAI_MAS;
1636 break;
1637 case SND_SOC_DAIFMT_CBS_CFM:
1638 case SND_SOC_DAIFMT_CBM_CFS:
1639 default:
1640 dev_err(codec->dev, "Clock mode unsupported");
1641 return -EINVAL;
1642 }
1643
1644 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1645 case SND_SOC_DAIFMT_I2S:
1646 regval |= M98095_DAI_DLY;
1647 break;
1648 case SND_SOC_DAIFMT_LEFT_J:
1649 break;
1650 default:
1651 return -EINVAL;
1652 }
1653
1654 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1655 case SND_SOC_DAIFMT_NB_NF:
1656 break;
1657 case SND_SOC_DAIFMT_NB_IF:
1658 regval |= M98095_DAI_WCI;
1659 break;
1660 case SND_SOC_DAIFMT_IB_NF:
1661 regval |= M98095_DAI_BCI;
1662 break;
1663 case SND_SOC_DAIFMT_IB_IF:
1664 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1665 break;
1666 default:
1667 return -EINVAL;
1668 }
1669
1670 snd_soc_update_bits(codec, M98095_034_DAI2_FORMAT,
1671 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1672 M98095_DAI_WCI, regval);
1673
1674 snd_soc_write(codec, M98095_035_DAI2_CLOCK,
1675 M98095_DAI_BSEL64);
1676 }
1677
1678 return 0;
1679}
1680
1681static int max98095_dai3_set_fmt(struct snd_soc_dai *codec_dai,
1682 unsigned int fmt)
1683{
1684 struct snd_soc_codec *codec = codec_dai->codec;
1685 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1686 struct max98095_cdata *cdata;
1687 u8 regval = 0;
1688
1689 cdata = &max98095->dai[2];
1690
1691 if (fmt != cdata->fmt) {
1692 cdata->fmt = fmt;
1693
1694 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1695 case SND_SOC_DAIFMT_CBS_CFS:
1696 /* Slave mode PLL */
1697 snd_soc_write(codec, M98095_03C_DAI3_CLKCFG_HI,
1698 0x80);
1699 snd_soc_write(codec, M98095_03D_DAI3_CLKCFG_LO,
1700 0x00);
1701 break;
1702 case SND_SOC_DAIFMT_CBM_CFM:
1703 /* Set to master mode */
1704 regval |= M98095_DAI_MAS;
1705 break;
1706 case SND_SOC_DAIFMT_CBS_CFM:
1707 case SND_SOC_DAIFMT_CBM_CFS:
1708 default:
1709 dev_err(codec->dev, "Clock mode unsupported");
1710 return -EINVAL;
1711 }
1712
1713 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1714 case SND_SOC_DAIFMT_I2S:
1715 regval |= M98095_DAI_DLY;
1716 break;
1717 case SND_SOC_DAIFMT_LEFT_J:
1718 break;
1719 default:
1720 return -EINVAL;
1721 }
1722
1723 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1724 case SND_SOC_DAIFMT_NB_NF:
1725 break;
1726 case SND_SOC_DAIFMT_NB_IF:
1727 regval |= M98095_DAI_WCI;
1728 break;
1729 case SND_SOC_DAIFMT_IB_NF:
1730 regval |= M98095_DAI_BCI;
1731 break;
1732 case SND_SOC_DAIFMT_IB_IF:
1733 regval |= M98095_DAI_BCI|M98095_DAI_WCI;
1734 break;
1735 default:
1736 return -EINVAL;
1737 }
1738
1739 snd_soc_update_bits(codec, M98095_03E_DAI3_FORMAT,
1740 M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI |
1741 M98095_DAI_WCI, regval);
1742
1743 snd_soc_write(codec, M98095_03F_DAI3_CLOCK,
1744 M98095_DAI_BSEL64);
1745 }
1746
1747 return 0;
1748}
1749
1750static int max98095_set_bias_level(struct snd_soc_codec *codec,
1751 enum snd_soc_bias_level level)
1752{
1753 int ret;
1754
1755 switch (level) {
1756 case SND_SOC_BIAS_ON:
1757 break;
1758
1759 case SND_SOC_BIAS_PREPARE:
1760 break;
1761
1762 case SND_SOC_BIAS_STANDBY:
1763 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1764 ret = snd_soc_cache_sync(codec);
1765
1766 if (ret != 0) {
1767 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
1768 return ret;
1769 }
1770 }
1771
1772 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1773 M98095_MBEN, M98095_MBEN);
1774 break;
1775
1776 case SND_SOC_BIAS_OFF:
1777 snd_soc_update_bits(codec, M98095_090_PWR_EN_IN,
1778 M98095_MBEN, 0);
1779 codec->cache_sync = 1;
1780 break;
1781 }
1782 codec->dapm.bias_level = level;
1783 return 0;
1784}
1785
1786#define MAX98095_RATES SNDRV_PCM_RATE_8000_96000
1787#define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
1788
1789static struct snd_soc_dai_ops max98095_dai1_ops = {
1790 .set_sysclk = max98095_dai_set_sysclk,
1791 .set_fmt = max98095_dai1_set_fmt,
1792 .hw_params = max98095_dai1_hw_params,
1793};
1794
1795static struct snd_soc_dai_ops max98095_dai2_ops = {
1796 .set_sysclk = max98095_dai_set_sysclk,
1797 .set_fmt = max98095_dai2_set_fmt,
1798 .hw_params = max98095_dai2_hw_params,
1799};
1800
1801static struct snd_soc_dai_ops max98095_dai3_ops = {
1802 .set_sysclk = max98095_dai_set_sysclk,
1803 .set_fmt = max98095_dai3_set_fmt,
1804 .hw_params = max98095_dai3_hw_params,
1805};
1806
1807static struct snd_soc_dai_driver max98095_dai[] = {
1808{
1809 .name = "HiFi",
1810 .playback = {
1811 .stream_name = "HiFi Playback",
1812 .channels_min = 1,
1813 .channels_max = 2,
1814 .rates = MAX98095_RATES,
1815 .formats = MAX98095_FORMATS,
1816 },
1817 .capture = {
1818 .stream_name = "HiFi Capture",
1819 .channels_min = 1,
1820 .channels_max = 2,
1821 .rates = MAX98095_RATES,
1822 .formats = MAX98095_FORMATS,
1823 },
1824 .ops = &max98095_dai1_ops,
1825},
1826{
1827 .name = "Aux",
1828 .playback = {
1829 .stream_name = "Aux Playback",
1830 .channels_min = 1,
1831 .channels_max = 1,
1832 .rates = MAX98095_RATES,
1833 .formats = MAX98095_FORMATS,
1834 },
1835 .ops = &max98095_dai2_ops,
1836},
1837{
1838 .name = "Voice",
1839 .playback = {
1840 .stream_name = "Voice Playback",
1841 .channels_min = 1,
1842 .channels_max = 1,
1843 .rates = MAX98095_RATES,
1844 .formats = MAX98095_FORMATS,
1845 },
1846 .ops = &max98095_dai3_ops,
1847}
1848
1849};
1850
1851static int max98095_get_eq_channel(const char *name)
1852{
1853 if (strcmp(name, "EQ1 Mode") == 0)
1854 return 0;
1855 if (strcmp(name, "EQ2 Mode") == 0)
1856 return 1;
1857 return -EINVAL;
1858}
1859
1860static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol,
1861 struct snd_ctl_elem_value *ucontrol)
1862{
1863 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1864 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1865 struct max98095_pdata *pdata = max98095->pdata;
1866 int channel = max98095_get_eq_channel(kcontrol->id.name);
1867 struct max98095_cdata *cdata;
1868 int sel = ucontrol->value.integer.value[0];
1869 struct max98095_eq_cfg *coef_set;
1870 int fs, best, best_val, i;
1871 int regmask, regsave;
1872
1873 BUG_ON(channel > 1);
1874
1875 if (!pdata || !max98095->eq_textcnt)
1876 return 0;
1877
1878 if (sel >= pdata->eq_cfgcnt)
1879 return -EINVAL;
1880
1881 cdata = &max98095->dai[channel];
1882 cdata->eq_sel = sel;
1883 fs = cdata->rate;
1884
1885 /* Find the selected configuration with nearest sample rate */
1886 best = 0;
1887 best_val = INT_MAX;
1888 for (i = 0; i < pdata->eq_cfgcnt; i++) {
1889 if (strcmp(pdata->eq_cfg[i].name, max98095->eq_texts[sel]) == 0 &&
1890 abs(pdata->eq_cfg[i].rate - fs) < best_val) {
1891 best = i;
1892 best_val = abs(pdata->eq_cfg[i].rate - fs);
1893 }
1894 }
1895
1896 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
1897 pdata->eq_cfg[best].name,
1898 pdata->eq_cfg[best].rate, fs);
1899
1900 coef_set = &pdata->eq_cfg[best];
1901
1902 regmask = (channel == 0) ? M98095_EQ1EN : M98095_EQ2EN;
1903
1904 /* Disable filter while configuring, and save current on/off state */
1905 regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
1906 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
1907
1908 mutex_lock(&codec->mutex);
1909 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
1910 m98095_eq_band(codec, channel, 0, coef_set->band1);
1911 m98095_eq_band(codec, channel, 1, coef_set->band2);
1912 m98095_eq_band(codec, channel, 2, coef_set->band3);
1913 m98095_eq_band(codec, channel, 3, coef_set->band4);
1914 m98095_eq_band(codec, channel, 4, coef_set->band5);
1915 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
1916 mutex_unlock(&codec->mutex);
1917
1918 /* Restore the original on/off state */
1919 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
1920 return 0;
1921}
1922
1923static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol,
1924 struct snd_ctl_elem_value *ucontrol)
1925{
1926 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1927 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1928 int channel = max98095_get_eq_channel(kcontrol->id.name);
1929 struct max98095_cdata *cdata;
1930
1931 cdata = &max98095->dai[channel];
1932 ucontrol->value.enumerated.item[0] = cdata->eq_sel;
1933
1934 return 0;
1935}
1936
1937static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
1938{
1939 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
1940 struct max98095_pdata *pdata = max98095->pdata;
1941 struct max98095_eq_cfg *cfg;
1942 unsigned int cfgcnt;
1943 int i, j;
1944 const char **t;
1945 int ret;
1946
1947 struct snd_kcontrol_new controls[] = {
1948 SOC_ENUM_EXT("EQ1 Mode",
1949 max98095->eq_enum,
1950 max98095_get_eq_enum,
1951 max98095_put_eq_enum),
1952 SOC_ENUM_EXT("EQ2 Mode",
1953 max98095->eq_enum,
1954 max98095_get_eq_enum,
1955 max98095_put_eq_enum),
1956 };
1957
1958 cfg = pdata->eq_cfg;
1959 cfgcnt = pdata->eq_cfgcnt;
1960
1961 /* Setup an array of texts for the equalizer enum.
1962 * This is based on Mark Brown's equalizer driver code.
1963 */
1964 max98095->eq_textcnt = 0;
1965 max98095->eq_texts = NULL;
1966 for (i = 0; i < cfgcnt; i++) {
1967 for (j = 0; j < max98095->eq_textcnt; j++) {
1968 if (strcmp(cfg[i].name, max98095->eq_texts[j]) == 0)
1969 break;
1970 }
1971
1972 if (j != max98095->eq_textcnt)
1973 continue;
1974
1975 /* Expand the array */
1976 t = krealloc(max98095->eq_texts,
1977 sizeof(char *) * (max98095->eq_textcnt + 1),
1978 GFP_KERNEL);
1979 if (t == NULL)
1980 continue;
1981
1982 /* Store the new entry */
1983 t[max98095->eq_textcnt] = cfg[i].name;
1984 max98095->eq_textcnt++;
1985 max98095->eq_texts = t;
1986 }
1987
1988 /* Now point the soc_enum to .texts array items */
1989 max98095->eq_enum.texts = max98095->eq_texts;
1990 max98095->eq_enum.max = max98095->eq_textcnt;
1991
1992 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
1993 if (ret != 0)
1994 dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
1995}
1996
1997static int max98095_get_bq_channel(const char *name)
1998{
1999 if (strcmp(name, "Biquad1 Mode") == 0)
2000 return 0;
2001 if (strcmp(name, "Biquad2 Mode") == 0)
2002 return 1;
2003 return -EINVAL;
2004}
2005
2006static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol,
2007 struct snd_ctl_elem_value *ucontrol)
2008{
2009 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2010 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2011 struct max98095_pdata *pdata = max98095->pdata;
2012 int channel = max98095_get_bq_channel(kcontrol->id.name);
2013 struct max98095_cdata *cdata;
2014 int sel = ucontrol->value.integer.value[0];
2015 struct max98095_biquad_cfg *coef_set;
2016 int fs, best, best_val, i;
2017 int regmask, regsave;
2018
2019 BUG_ON(channel > 1);
2020
2021 if (!pdata || !max98095->bq_textcnt)
2022 return 0;
2023
2024 if (sel >= pdata->bq_cfgcnt)
2025 return -EINVAL;
2026
2027 cdata = &max98095->dai[channel];
2028 cdata->bq_sel = sel;
2029 fs = cdata->rate;
2030
2031 /* Find the selected configuration with nearest sample rate */
2032 best = 0;
2033 best_val = INT_MAX;
2034 for (i = 0; i < pdata->bq_cfgcnt; i++) {
2035 if (strcmp(pdata->bq_cfg[i].name, max98095->bq_texts[sel]) == 0 &&
2036 abs(pdata->bq_cfg[i].rate - fs) < best_val) {
2037 best = i;
2038 best_val = abs(pdata->bq_cfg[i].rate - fs);
2039 }
2040 }
2041
2042 dev_dbg(codec->dev, "Selected %s/%dHz for %dHz sample rate\n",
2043 pdata->bq_cfg[best].name,
2044 pdata->bq_cfg[best].rate, fs);
2045
2046 coef_set = &pdata->bq_cfg[best];
2047
2048 regmask = (channel == 0) ? M98095_BQ1EN : M98095_BQ2EN;
2049
2050 /* Disable filter while configuring, and save current on/off state */
2051 regsave = snd_soc_read(codec, M98095_088_CFG_LEVEL);
2052 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, 0);
2053
2054 mutex_lock(&codec->mutex);
2055 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, M98095_SEG);
2056 m98095_biquad_band(codec, channel, 0, coef_set->band1);
2057 m98095_biquad_band(codec, channel, 1, coef_set->band2);
2058 snd_soc_update_bits(codec, M98095_00F_HOST_CFG, M98095_SEG, 0);
2059 mutex_unlock(&codec->mutex);
2060
2061 /* Restore the original on/off state */
2062 snd_soc_update_bits(codec, M98095_088_CFG_LEVEL, regmask, regsave);
2063 return 0;
2064}
2065
2066static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol,
2067 struct snd_ctl_elem_value *ucontrol)
2068{
2069 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2070 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2071 int channel = max98095_get_bq_channel(kcontrol->id.name);
2072 struct max98095_cdata *cdata;
2073
2074 cdata = &max98095->dai[channel];
2075 ucontrol->value.enumerated.item[0] = cdata->bq_sel;
2076
2077 return 0;
2078}
2079
2080static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
2081{
2082 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2083 struct max98095_pdata *pdata = max98095->pdata;
2084 struct max98095_biquad_cfg *cfg;
2085 unsigned int cfgcnt;
2086 int i, j;
2087 const char **t;
2088 int ret;
2089
2090 struct snd_kcontrol_new controls[] = {
2091 SOC_ENUM_EXT("Biquad1 Mode",
2092 max98095->bq_enum,
2093 max98095_get_bq_enum,
2094 max98095_put_bq_enum),
2095 SOC_ENUM_EXT("Biquad2 Mode",
2096 max98095->bq_enum,
2097 max98095_get_bq_enum,
2098 max98095_put_bq_enum),
2099 };
2100
2101 cfg = pdata->bq_cfg;
2102 cfgcnt = pdata->bq_cfgcnt;
2103
2104 /* Setup an array of texts for the biquad enum.
2105 * This is based on Mark Brown's equalizer driver code.
2106 */
2107 max98095->bq_textcnt = 0;
2108 max98095->bq_texts = NULL;
2109 for (i = 0; i < cfgcnt; i++) {
2110 for (j = 0; j < max98095->bq_textcnt; j++) {
2111 if (strcmp(cfg[i].name, max98095->bq_texts[j]) == 0)
2112 break;
2113 }
2114
2115 if (j != max98095->bq_textcnt)
2116 continue;
2117
2118 /* Expand the array */
2119 t = krealloc(max98095->bq_texts,
2120 sizeof(char *) * (max98095->bq_textcnt + 1),
2121 GFP_KERNEL);
2122 if (t == NULL)
2123 continue;
2124
2125 /* Store the new entry */
2126 t[max98095->bq_textcnt] = cfg[i].name;
2127 max98095->bq_textcnt++;
2128 max98095->bq_texts = t;
2129 }
2130
2131 /* Now point the soc_enum to .texts array items */
2132 max98095->bq_enum.texts = max98095->bq_texts;
2133 max98095->bq_enum.max = max98095->bq_textcnt;
2134
2135 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2136 if (ret != 0)
2137 dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
2138}
2139
2140static void max98095_handle_pdata(struct snd_soc_codec *codec)
2141{
2142 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2143 struct max98095_pdata *pdata = max98095->pdata;
2144 u8 regval = 0;
2145
2146 if (!pdata) {
2147 dev_dbg(codec->dev, "No platform data\n");
2148 return;
2149 }
2150
2151 /* Configure mic for analog/digital mic mode */
2152 if (pdata->digmic_left_mode)
2153 regval |= M98095_DIGMIC_L;
2154
2155 if (pdata->digmic_right_mode)
2156 regval |= M98095_DIGMIC_R;
2157
2158 snd_soc_write(codec, M98095_087_CFG_MIC, regval);
2159
2160 /* Configure equalizers */
2161 if (pdata->eq_cfgcnt)
2162 max98095_handle_eq_pdata(codec);
2163
2164 /* Configure bi-quad filters */
2165 if (pdata->bq_cfgcnt)
2166 max98095_handle_bq_pdata(codec);
2167}
2168
2169#ifdef CONFIG_PM
2170static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state)
2171{
2172 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2173
2174 return 0;
2175}
2176
2177static int max98095_resume(struct snd_soc_codec *codec)
2178{
2179 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2180
2181 return 0;
2182}
2183#else
2184#define max98095_suspend NULL
2185#define max98095_resume NULL
2186#endif
2187
2188static int max98095_reset(struct snd_soc_codec *codec)
2189{
2190 int i, ret;
2191
2192 /* Gracefully reset the DSP core and the codec hardware
2193 * in a proper sequence */
2194 ret = snd_soc_write(codec, M98095_00F_HOST_CFG, 0);
2195 if (ret < 0) {
2196 dev_err(codec->dev, "Failed to reset DSP: %d\n", ret);
2197 return ret;
2198 }
2199
2200 ret = snd_soc_write(codec, M98095_097_PWR_SYS, 0);
2201 if (ret < 0) {
2202 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
2203 return ret;
2204 }
2205
2206 /* Reset to hardware default for registers, as there is not
2207 * a soft reset hardware control register */
2208 for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
2209 ret = snd_soc_write(codec, i, max98095_reg_def[i]);
2210 if (ret < 0) {
2211 dev_err(codec->dev, "Failed to reset: %d\n", ret);
2212 return ret;
2213 }
2214 }
2215
2216 return ret;
2217}
2218
2219static int max98095_probe(struct snd_soc_codec *codec)
2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 struct max98095_cdata *cdata;
2223 int ret = 0;
2224
2225 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
2226 if (ret != 0) {
2227 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2228 return ret;
2229 }
2230
2231 /* reset the codec, the DSP core, and disable all interrupts */
2232 max98095_reset(codec);
2233
2234 /* initialize private data */
2235
2236 max98095->sysclk = (unsigned)-1;
2237 max98095->eq_textcnt = 0;
2238 max98095->bq_textcnt = 0;
2239
2240 cdata = &max98095->dai[0];
2241 cdata->rate = (unsigned)-1;
2242 cdata->fmt = (unsigned)-1;
2243 cdata->eq_sel = 0;
2244 cdata->bq_sel = 0;
2245
2246 cdata = &max98095->dai[1];
2247 cdata->rate = (unsigned)-1;
2248 cdata->fmt = (unsigned)-1;
2249 cdata->eq_sel = 0;
2250 cdata->bq_sel = 0;
2251
2252 cdata = &max98095->dai[2];
2253 cdata->rate = (unsigned)-1;
2254 cdata->fmt = (unsigned)-1;
2255 cdata->eq_sel = 0;
2256 cdata->bq_sel = 0;
2257
2258 max98095->lin_state = 0;
2259 max98095->mic1pre = 0;
2260 max98095->mic2pre = 0;
2261
2262 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2263 if (ret < 0) {
2264 dev_err(codec->dev, "Failed to read device revision: %d\n",
2265 ret);
2266 goto err_access;
2267 }
2268 dev_info(codec->dev, "revision %c\n", ret + 'A');
2269
2270 snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
2271
2272 /* initialize registers cache to hardware default */
2273 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2274
2275 snd_soc_write(codec, M98095_048_MIX_DAC_LR,
2276 M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
2277
2278 snd_soc_write(codec, M98095_049_MIX_DAC_M,
2279 M98095_DAI2M_TO_DACM|M98095_DAI3M_TO_DACM);
2280
2281 snd_soc_write(codec, M98095_092_PWR_EN_OUT, M98095_SPK_SPREADSPECTRUM);
2282 snd_soc_write(codec, M98095_045_CFG_DSP, M98095_DSPNORMAL);
2283 snd_soc_write(codec, M98095_04E_CFG_HP, M98095_HPNORMAL);
2284
2285 snd_soc_write(codec, M98095_02C_DAI1_IOCFG,
2286 M98095_S1NORMAL|M98095_SDATA);
2287
2288 snd_soc_write(codec, M98095_036_DAI2_IOCFG,
2289 M98095_S2NORMAL|M98095_SDATA);
2290
2291 snd_soc_write(codec, M98095_040_DAI3_IOCFG,
2292 M98095_S3NORMAL|M98095_SDATA);
2293
2294 max98095_handle_pdata(codec);
2295
2296 /* take the codec out of the shut down */
2297 snd_soc_update_bits(codec, M98095_097_PWR_SYS, M98095_SHDNRUN,
2298 M98095_SHDNRUN);
2299
2300 max98095_add_widgets(codec);
2301
2302err_access:
2303 return ret;
2304}
2305
2306static int max98095_remove(struct snd_soc_codec *codec)
2307{
2308 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2309
2310 return 0;
2311}
2312
2313static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
2314 .probe = max98095_probe,
2315 .remove = max98095_remove,
2316 .suspend = max98095_suspend,
2317 .resume = max98095_resume,
2318 .set_bias_level = max98095_set_bias_level,
2319 .reg_cache_size = ARRAY_SIZE(max98095_reg_def),
2320 .reg_word_size = sizeof(u8),
2321 .reg_cache_default = max98095_reg_def,
2322 .readable_register = max98095_readable,
2323 .volatile_register = max98095_volatile,
2324 .dapm_widgets = max98095_dapm_widgets,
2325 .num_dapm_widgets = ARRAY_SIZE(max98095_dapm_widgets),
2326 .dapm_routes = max98095_audio_map,
2327 .num_dapm_routes = ARRAY_SIZE(max98095_audio_map),
2328};
2329
2330static int max98095_i2c_probe(struct i2c_client *i2c,
2331 const struct i2c_device_id *id)
2332{
2333 struct max98095_priv *max98095;
2334 int ret;
2335
2336 max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL);
2337 if (max98095 == NULL)
2338 return -ENOMEM;
2339
2340 max98095->devtype = id->driver_data;
2341 i2c_set_clientdata(i2c, max98095);
2342 max98095->control_data = i2c;
2343 max98095->pdata = i2c->dev.platform_data;
2344
2345 ret = snd_soc_register_codec(&i2c->dev,
2346 &soc_codec_dev_max98095, &max98095_dai[0], 3);
2347 if (ret < 0)
2348 kfree(max98095);
2349 return ret;
2350}
2351
2352static int __devexit max98095_i2c_remove(struct i2c_client *client)
2353{
2354 snd_soc_unregister_codec(&client->dev);
2355 kfree(i2c_get_clientdata(client));
2356
2357 return 0;
2358}
2359
2360static const struct i2c_device_id max98095_i2c_id[] = {
2361 { "max98095", MAX98095 },
2362 { }
2363};
2364MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
2365
2366static struct i2c_driver max98095_i2c_driver = {
2367 .driver = {
2368 .name = "max98095",
2369 .owner = THIS_MODULE,
2370 },
2371 .probe = max98095_i2c_probe,
2372 .remove = __devexit_p(max98095_i2c_remove),
2373 .id_table = max98095_i2c_id,
2374};
2375
2376static int __init max98095_init(void)
2377{
2378 int ret;
2379
2380 ret = i2c_add_driver(&max98095_i2c_driver);
2381 if (ret)
2382 pr_err("Failed to register max98095 I2C driver: %d\n", ret);
2383
2384 return ret;
2385}
2386module_init(max98095_init);
2387
2388static void __exit max98095_exit(void)
2389{
2390 i2c_del_driver(&max98095_i2c_driver);
2391}
2392module_exit(max98095_exit);
2393
2394MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
2395MODULE_AUTHOR("Peter Hsiang");
2396MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
new file mode 100644
index 000000000000..891584a0eb03
--- /dev/null
+++ b/sound/soc/codecs/max98095.h
@@ -0,0 +1,299 @@
1/*
2 * max98095.h -- MAX98095 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98095_H
12#define _MAX98095_H
13
14/*
15 * MAX98095 Registers Definition
16 */
17
18#define M98095_000_HOST_DATA 0x00
19#define M98095_001_HOST_INT_STS 0x01
20#define M98095_002_HOST_RSP_STS 0x02
21#define M98095_003_HOST_CMD_STS 0x03
22#define M98095_004_CODEC_STS 0x04
23#define M98095_005_DAI1_ALC_STS 0x05
24#define M98095_006_DAI2_ALC_STS 0x06
25#define M98095_007_JACK_AUTO_STS 0x07
26#define M98095_008_JACK_MANUAL_STS 0x08
27#define M98095_009_JACK_VBAT_STS 0x09
28#define M98095_00A_ACC_ADC_STS 0x0A
29#define M98095_00B_MIC_NG_AGC_STS 0x0B
30#define M98095_00C_SPK_L_VOLT_STS 0x0C
31#define M98095_00D_SPK_R_VOLT_STS 0x0D
32#define M98095_00E_TEMP_SENSOR_STS 0x0E
33#define M98095_00F_HOST_CFG 0x0F
34#define M98095_010_HOST_INT_CFG 0x10
35#define M98095_011_HOST_INT_EN 0x11
36#define M98095_012_CODEC_INT_EN 0x12
37#define M98095_013_JACK_INT_EN 0x13
38#define M98095_014_JACK_INT_EN 0x14
39#define M98095_015_DEC 0x15
40#define M98095_016_RESERVED 0x16
41#define M98095_017_RESERVED 0x17
42#define M98095_018_KEYCODE3 0x18
43#define M98095_019_KEYCODE2 0x19
44#define M98095_01A_KEYCODE1 0x1A
45#define M98095_01B_KEYCODE0 0x1B
46#define M98095_01C_OEMCODE1 0x1C
47#define M98095_01D_OEMCODE0 0x1D
48#define M98095_01E_XCFG1 0x1E
49#define M98095_01F_XCFG2 0x1F
50#define M98095_020_XCFG3 0x20
51#define M98095_021_XCFG4 0x21
52#define M98095_022_XCFG5 0x22
53#define M98095_023_XCFG6 0x23
54#define M98095_024_XGPIO 0x24
55#define M98095_025_XCLKCFG 0x25
56#define M98095_026_SYS_CLK 0x26
57#define M98095_027_DAI1_CLKMODE 0x27
58#define M98095_028_DAI1_CLKCFG_HI 0x28
59#define M98095_029_DAI1_CLKCFG_LO 0x29
60#define M98095_02A_DAI1_FORMAT 0x2A
61#define M98095_02B_DAI1_CLOCK 0x2B
62#define M98095_02C_DAI1_IOCFG 0x2C
63#define M98095_02D_DAI1_TDM 0x2D
64#define M98095_02E_DAI1_FILTERS 0x2E
65#define M98095_02F_DAI1_LVL1 0x2F
66#define M98095_030_DAI1_LVL2 0x30
67#define M98095_031_DAI2_CLKMODE 0x31
68#define M98095_032_DAI2_CLKCFG_HI 0x32
69#define M98095_033_DAI2_CLKCFG_LO 0x33
70#define M98095_034_DAI2_FORMAT 0x34
71#define M98095_035_DAI2_CLOCK 0x35
72#define M98095_036_DAI2_IOCFG 0x36
73#define M98095_037_DAI2_TDM 0x37
74#define M98095_038_DAI2_FILTERS 0x38
75#define M98095_039_DAI2_LVL1 0x39
76#define M98095_03A_DAI2_LVL2 0x3A
77#define M98095_03B_DAI3_CLKMODE 0x3B
78#define M98095_03C_DAI3_CLKCFG_HI 0x3C
79#define M98095_03D_DAI3_CLKCFG_LO 0x3D
80#define M98095_03E_DAI3_FORMAT 0x3E
81#define M98095_03F_DAI3_CLOCK 0x3F
82#define M98095_040_DAI3_IOCFG 0x40
83#define M98095_041_DAI3_TDM 0x41
84#define M98095_042_DAI3_FILTERS 0x42
85#define M98095_043_DAI3_LVL1 0x43
86#define M98095_044_DAI3_LVL2 0x44
87#define M98095_045_CFG_DSP 0x45
88#define M98095_046_DAC_CTRL1 0x46
89#define M98095_047_DAC_CTRL2 0x47
90#define M98095_048_MIX_DAC_LR 0x48
91#define M98095_049_MIX_DAC_M 0x49
92#define M98095_04A_MIX_ADC_LEFT 0x4A
93#define M98095_04B_MIX_ADC_RIGHT 0x4B
94#define M98095_04C_MIX_HP_LEFT 0x4C
95#define M98095_04D_MIX_HP_RIGHT 0x4D
96#define M98095_04E_CFG_HP 0x4E
97#define M98095_04F_MIX_RCV 0x4F
98#define M98095_050_MIX_SPK_LEFT 0x50
99#define M98095_051_MIX_SPK_RIGHT 0x51
100#define M98095_052_MIX_SPK_CFG 0x52
101#define M98095_053_MIX_LINEOUT1 0x53
102#define M98095_054_MIX_LINEOUT2 0x54
103#define M98095_055_MIX_LINEOUT_CFG 0x55
104#define M98095_056_LVL_SIDETONE_DAI12 0x56
105#define M98095_057_LVL_SIDETONE_DAI3 0x57
106#define M98095_058_LVL_DAI1_PLAY 0x58
107#define M98095_059_LVL_DAI1_EQ 0x59
108#define M98095_05A_LVL_DAI2_PLAY 0x5A
109#define M98095_05B_LVL_DAI2_EQ 0x5B
110#define M98095_05C_LVL_DAI3_PLAY 0x5C
111#define M98095_05D_LVL_ADC_L 0x5D
112#define M98095_05E_LVL_ADC_R 0x5E
113#define M98095_05F_LVL_MIC1 0x5F
114#define M98095_060_LVL_MIC2 0x60
115#define M98095_061_LVL_LINEIN 0x61
116#define M98095_062_LVL_LINEOUT1 0x62
117#define M98095_063_LVL_LINEOUT2 0x63
118#define M98095_064_LVL_HP_L 0x64
119#define M98095_065_LVL_HP_R 0x65
120#define M98095_066_LVL_RCV 0x66
121#define M98095_067_LVL_SPK_L 0x67
122#define M98095_068_LVL_SPK_R 0x68
123#define M98095_069_MICAGC_CFG 0x69
124#define M98095_06A_MICAGC_THRESH 0x6A
125#define M98095_06B_SPK_NOISEGATE 0x6B
126#define M98095_06C_DAI1_ALC1_TIME 0x6C
127#define M98095_06D_DAI1_ALC1_COMP 0x6D
128#define M98095_06E_DAI1_ALC1_EXPN 0x6E
129#define M98095_06F_DAI1_ALC1_GAIN 0x6F
130#define M98095_070_DAI1_ALC2_TIME 0x70
131#define M98095_071_DAI1_ALC2_COMP 0x71
132#define M98095_072_DAI1_ALC2_EXPN 0x72
133#define M98095_073_DAI1_ALC2_GAIN 0x73
134#define M98095_074_DAI1_ALC3_TIME 0x74
135#define M98095_075_DAI1_ALC3_COMP 0x75
136#define M98095_076_DAI1_ALC3_EXPN 0x76
137#define M98095_077_DAI1_ALC3_GAIN 0x77
138#define M98095_078_DAI2_ALC1_TIME 0x78
139#define M98095_079_DAI2_ALC1_COMP 0x79
140#define M98095_07A_DAI2_ALC1_EXPN 0x7A
141#define M98095_07B_DAI2_ALC1_GAIN 0x7B
142#define M98095_07C_DAI2_ALC2_TIME 0x7C
143#define M98095_07D_DAI2_ALC2_COMP 0x7D
144#define M98095_07E_DAI2_ALC2_EXPN 0x7E
145#define M98095_07F_DAI2_ALC2_GAIN 0x7F
146#define M98095_080_DAI2_ALC3_TIME 0x80
147#define M98095_081_DAI2_ALC3_COMP 0x81
148#define M98095_082_DAI2_ALC3_EXPN 0x82
149#define M98095_083_DAI2_ALC3_GAIN 0x83
150#define M98095_084_HP_NOISE_GATE 0x84
151#define M98095_085_AUX_ADC 0x85
152#define M98095_086_CFG_LINE 0x86
153#define M98095_087_CFG_MIC 0x87
154#define M98095_088_CFG_LEVEL 0x88
155#define M98095_089_JACK_DET_AUTO 0x89
156#define M98095_08A_JACK_DET_MANUAL 0x8A
157#define M98095_08B_JACK_KEYSCAN_DBC 0x8B
158#define M98095_08C_JACK_KEYSCAN_DLY 0x8C
159#define M98095_08D_JACK_KEY_THRESH 0x8D
160#define M98095_08E_JACK_DC_SLEW 0x8E
161#define M98095_08F_JACK_TEST_CFG 0x8F
162#define M98095_090_PWR_EN_IN 0x90
163#define M98095_091_PWR_EN_OUT 0x91
164#define M98095_092_PWR_EN_OUT 0x92
165#define M98095_093_BIAS_CTRL 0x93
166#define M98095_094_PWR_DAC_21 0x94
167#define M98095_095_PWR_DAC_03 0x95
168#define M98095_096_PWR_DAC_CK 0x96
169#define M98095_097_PWR_SYS 0x97
170
171#define M98095_0FF_REV_ID 0xFF
172
173#define M98095_REG_CNT (0xFF+1)
174#define M98095_REG_MAX_CACHED 0X97
175
176/* MAX98095 Registers Bit Fields */
177
178/* M98095_00F_HOST_CFG */
179 #define M98095_SEG (1<<0)
180 #define M98095_XTEN (1<<1)
181 #define M98095_MDLLEN (1<<2)
182
183/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 #define M98095_CLKMODE_MASK 0xFF
185
186/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */
187 #define M98095_DAI_MAS (1<<7)
188 #define M98095_DAI_WCI (1<<6)
189 #define M98095_DAI_BCI (1<<5)
190 #define M98095_DAI_DLY (1<<4)
191 #define M98095_DAI_TDM (1<<2)
192 #define M98095_DAI_FSW (1<<1)
193 #define M98095_DAI_WS (1<<0)
194
195/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */
196 #define M98095_DAI_BSEL64 (1<<0)
197 #define M98095_DAI_DOSR_DIV2 (0<<5)
198 #define M98095_DAI_DOSR_DIV4 (1<<5)
199
200/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */
201 #define M98095_S1NORMAL (1<<6)
202 #define M98095_S2NORMAL (2<<6)
203 #define M98095_S3NORMAL (3<<6)
204 #define M98095_SDATA (3<<0)
205
206/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */
207 #define M98095_DAI_DHF (1<<3)
208
209/* M98095_045_DSP_CFG */
210 #define M98095_DSPNORMAL (5<<4)
211
212/* M98095_048_MIX_DAC_LR */
213 #define M98095_DAI1L_TO_DACR (1<<7)
214 #define M98095_DAI1R_TO_DACR (1<<6)
215 #define M98095_DAI2M_TO_DACR (1<<5)
216 #define M98095_DAI1L_TO_DACL (1<<3)
217 #define M98095_DAI1R_TO_DACL (1<<2)
218 #define M98095_DAI2M_TO_DACL (1<<1)
219 #define M98095_DAI3M_TO_DACL (1<<0)
220
221/* M98095_049_MIX_DAC_M */
222 #define M98095_DAI1L_TO_DACM (1<<3)
223 #define M98095_DAI1R_TO_DACM (1<<2)
224 #define M98095_DAI2M_TO_DACM (1<<1)
225 #define M98095_DAI3M_TO_DACM (1<<0)
226
227/* M98095_04E_MIX_HP_CFG */
228 #define M98095_HPNORMAL (3<<4)
229
230/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */
231 #define M98095_MICPRE_MASK (3<<5)
232 #define M98095_MICPRE_SHIFT 5
233
234/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */
235 #define M98095_HP_MUTE (1<<7)
236
237/* M98095_066_LVL_RCV */
238 #define M98095_REC_MUTE (1<<7)
239
240/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */
241 #define M98095_SP_MUTE (1<<7)
242
243/* M98095_087_CFG_MIC */
244 #define M98095_MICSEL_MASK (3<<0)
245 #define M98095_DIGMIC_L (1<<2)
246 #define M98095_DIGMIC_R (1<<3)
247 #define M98095_DIGMIC2L (1<<4)
248 #define M98095_DIGMIC2R (1<<5)
249
250/* M98095_088_CFG_LEVEL */
251 #define M98095_VSEN (1<<6)
252 #define M98095_ZDEN (1<<5)
253 #define M98095_BQ2EN (1<<3)
254 #define M98095_BQ1EN (1<<2)
255 #define M98095_EQ2EN (1<<1)
256 #define M98095_EQ1EN (1<<0)
257
258/* M98095_090_PWR_EN_IN */
259 #define M98095_INEN (1<<7)
260 #define M98095_MB2EN (1<<3)
261 #define M98095_MB1EN (1<<2)
262 #define M98095_MBEN (3<<2)
263 #define M98095_ADREN (1<<1)
264 #define M98095_ADLEN (1<<0)
265
266/* M98095_091_PWR_EN_OUT */
267 #define M98095_HPLEN (1<<7)
268 #define M98095_HPREN (1<<6)
269 #define M98095_SPLEN (1<<5)
270 #define M98095_SPREN (1<<4)
271 #define M98095_RECEN (1<<3)
272 #define M98095_DALEN (1<<1)
273 #define M98095_DAREN (1<<0)
274
275/* M98095_092_PWR_EN_OUT */
276 #define M98095_SPK_FIXEDSPECTRUM (0<<4)
277 #define M98095_SPK_SPREADSPECTRUM (1<<4)
278
279/* M98095_097_PWR_SYS */
280 #define M98095_SHDNRUN (1<<7)
281 #define M98095_PERFMODE (1<<3)
282 #define M98095_HPPLYBACK (1<<2)
283 #define M98095_PWRSV8K (1<<1)
284 #define M98095_PWRSV (1<<0)
285
286#define M98095_COEFS_PER_BAND 5
287
288#define M98095_BYTE1(w) ((w >> 8) & 0xff)
289#define M98095_BYTE0(w) (w & 0xff)
290
291/* Equalizer filter coefficients */
292#define M98095_110_DAI1_EQ_BASE 0x10
293#define M98095_142_DAI2_EQ_BASE 0x42
294
295/* Biquad filter coefficients */
296#define M98095_174_DAI1_BQ_BASE 0x74
297#define M98095_17E_DAI2_BQ_BASE 0x7E
298
299#endif
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
new file mode 100644
index 000000000000..208d2ee61855
--- /dev/null
+++ b/sound/soc/codecs/max9850.c
@@ -0,0 +1,389 @@
1/*
2 * max9850.c -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 *
6 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
7 *
8 * Initial development of this code was funded by
9 * MICRONIC Computer Systeme GmbH, http://www.mcsberlin.de/
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/tlv.h>
26
27#include "max9850.h"
28
29struct max9850_priv {
30 unsigned int sysclk;
31};
32
33/* max9850 register cache */
34static const u8 max9850_reg[MAX9850_CACHEREGNUM] = {
35 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
36};
37
38/* these registers are not used at the moment but provided for the sake of
39 * completeness */
40static int max9850_volatile_register(struct snd_soc_codec *codec,
41 unsigned int reg)
42{
43 switch (reg) {
44 case MAX9850_STATUSA:
45 case MAX9850_STATUSB:
46 return 1;
47 default:
48 return 0;
49 }
50}
51
52static const unsigned int max9850_tlv[] = {
53 TLV_DB_RANGE_HEAD(4),
54 0x18, 0x1f, TLV_DB_SCALE_ITEM(-7450, 400, 0),
55 0x20, 0x33, TLV_DB_SCALE_ITEM(-4150, 200, 0),
56 0x34, 0x37, TLV_DB_SCALE_ITEM(-150, 100, 0),
57 0x38, 0x3f, TLV_DB_SCALE_ITEM(250, 50, 0),
58};
59
60static const struct snd_kcontrol_new max9850_controls[] = {
61SOC_SINGLE_TLV("Headphone Volume", MAX9850_VOLUME, 0, 0x3f, 1, max9850_tlv),
62SOC_SINGLE("Headphone Switch", MAX9850_VOLUME, 7, 1, 1),
63SOC_SINGLE("Mono Switch", MAX9850_GENERAL_PURPOSE, 2, 1, 0),
64};
65
66static const struct snd_kcontrol_new max9850_mixer_controls[] = {
67 SOC_DAPM_SINGLE("Line In Switch", MAX9850_ENABLE, 1, 1, 0),
68};
69
70static const struct snd_soc_dapm_widget max9850_dapm_widgets[] = {
71SND_SOC_DAPM_SUPPLY("Charge Pump 1", MAX9850_ENABLE, 4, 0, NULL, 0),
72SND_SOC_DAPM_SUPPLY("Charge Pump 2", MAX9850_ENABLE, 5, 0, NULL, 0),
73SND_SOC_DAPM_SUPPLY("MCLK", MAX9850_ENABLE, 6, 0, NULL, 0),
74SND_SOC_DAPM_SUPPLY("SHDN", MAX9850_ENABLE, 7, 0, NULL, 0),
75SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", MAX9850_ENABLE, 2, 0,
76 &max9850_mixer_controls[0],
77 ARRAY_SIZE(max9850_mixer_controls)),
78SND_SOC_DAPM_PGA("Headphone Output", MAX9850_ENABLE, 3, 0, NULL, 0),
79SND_SOC_DAPM_DAC("DAC", "HiFi Playback", MAX9850_ENABLE, 0, 0),
80SND_SOC_DAPM_OUTPUT("OUTL"),
81SND_SOC_DAPM_OUTPUT("HPL"),
82SND_SOC_DAPM_OUTPUT("OUTR"),
83SND_SOC_DAPM_OUTPUT("HPR"),
84SND_SOC_DAPM_MIXER("Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
85SND_SOC_DAPM_INPUT("INL"),
86SND_SOC_DAPM_INPUT("INR"),
87};
88
89static const struct snd_soc_dapm_route intercon[] = {
90 /* output mixer */
91 {"Output Mixer", NULL, "DAC"},
92 {"Output Mixer", "Line In Switch", "Line Input"},
93
94 /* outputs */
95 {"Headphone Output", NULL, "Output Mixer"},
96 {"HPL", NULL, "Headphone Output"},
97 {"HPR", NULL, "Headphone Output"},
98 {"OUTL", NULL, "Output Mixer"},
99 {"OUTR", NULL, "Output Mixer"},
100
101 /* inputs */
102 {"Line Input", NULL, "INL"},
103 {"Line Input", NULL, "INR"},
104
105 /* supplies */
106 {"Output Mixer", NULL, "Charge Pump 1"},
107 {"Output Mixer", NULL, "Charge Pump 2"},
108 {"Output Mixer", NULL, "SHDN"},
109 {"DAC", NULL, "MCLK"},
110};
111
112static int max9850_hw_params(struct snd_pcm_substream *substream,
113 struct snd_pcm_hw_params *params,
114 struct snd_soc_dai *dai)
115{
116 struct snd_soc_codec *codec = dai->codec;
117 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
118 u64 lrclk_div;
119 u8 sf, da;
120
121 if (!max9850->sysclk)
122 return -EINVAL;
123
124 /* lrclk_div = 2^22 * rate / iclk with iclk = mclk / sf */
125 sf = (snd_soc_read(codec, MAX9850_CLOCK) >> 2) + 1;
126 lrclk_div = (1 << 22);
127 lrclk_div *= params_rate(params);
128 lrclk_div *= sf;
129 do_div(lrclk_div, max9850->sysclk);
130
131 snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f);
132 snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff);
133
134 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S16_LE:
136 da = 0;
137 break;
138 case SNDRV_PCM_FORMAT_S20_3LE:
139 da = 0x2;
140 break;
141 case SNDRV_PCM_FORMAT_S24_LE:
142 da = 0x3;
143 break;
144 default:
145 return -EINVAL;
146 }
147 snd_soc_update_bits(codec, MAX9850_DIGITAL_AUDIO, 0x3, da);
148
149 return 0;
150}
151
152static int max9850_set_dai_sysclk(struct snd_soc_dai *codec_dai,
153 int clk_id, unsigned int freq, int dir)
154{
155 struct snd_soc_codec *codec = codec_dai->codec;
156 struct max9850_priv *max9850 = snd_soc_codec_get_drvdata(codec);
157
158 /* calculate mclk -> iclk divider */
159 if (freq <= 13000000)
160 snd_soc_write(codec, MAX9850_CLOCK, 0x0);
161 else if (freq <= 26000000)
162 snd_soc_write(codec, MAX9850_CLOCK, 0x4);
163 else if (freq <= 40000000)
164 snd_soc_write(codec, MAX9850_CLOCK, 0x8);
165 else
166 return -EINVAL;
167
168 max9850->sysclk = freq;
169 return 0;
170}
171
172static int max9850_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
173{
174 struct snd_soc_codec *codec = codec_dai->codec;
175 u8 da = 0;
176
177 /* set master/slave audio interface */
178 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
179 case SND_SOC_DAIFMT_CBM_CFM:
180 da |= MAX9850_MASTER;
181 break;
182 case SND_SOC_DAIFMT_CBS_CFS:
183 break;
184 default:
185 return -EINVAL;
186 }
187
188 /* interface format */
189 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
190 case SND_SOC_DAIFMT_I2S:
191 da |= MAX9850_DLY;
192 break;
193 case SND_SOC_DAIFMT_RIGHT_J:
194 da |= MAX9850_RTJ;
195 break;
196 case SND_SOC_DAIFMT_LEFT_J:
197 break;
198 default:
199 return -EINVAL;
200 }
201
202 /* clock inversion */
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 break;
206 case SND_SOC_DAIFMT_IB_IF:
207 da |= MAX9850_BCINV | MAX9850_INV;
208 break;
209 case SND_SOC_DAIFMT_IB_NF:
210 da |= MAX9850_BCINV;
211 break;
212 case SND_SOC_DAIFMT_NB_IF:
213 da |= MAX9850_INV;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 /* set da */
220 snd_soc_write(codec, MAX9850_DIGITAL_AUDIO, da);
221
222 return 0;
223}
224
225static int max9850_set_bias_level(struct snd_soc_codec *codec,
226 enum snd_soc_bias_level level)
227{
228 int ret;
229
230 switch (level) {
231 case SND_SOC_BIAS_ON:
232 break;
233 case SND_SOC_BIAS_PREPARE:
234 break;
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
237 ret = snd_soc_cache_sync(codec);
238 if (ret) {
239 dev_err(codec->dev,
240 "Failed to sync cache: %d\n", ret);
241 return ret;
242 }
243 }
244 break;
245 case SND_SOC_BIAS_OFF:
246 break;
247 }
248 codec->dapm.bias_level = level;
249 return 0;
250}
251
252#define MAX9850_RATES SNDRV_PCM_RATE_8000_48000
253
254#define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
255 SNDRV_PCM_FMTBIT_S24_LE)
256
257static struct snd_soc_dai_ops max9850_dai_ops = {
258 .hw_params = max9850_hw_params,
259 .set_sysclk = max9850_set_dai_sysclk,
260 .set_fmt = max9850_set_dai_fmt,
261};
262
263static struct snd_soc_dai_driver max9850_dai = {
264 .name = "max9850-hifi",
265 .playback = {
266 .stream_name = "Playback",
267 .channels_min = 1,
268 .channels_max = 2,
269 .rates = MAX9850_RATES,
270 .formats = MAX9850_FORMATS
271 },
272 .ops = &max9850_dai_ops,
273};
274
275#ifdef CONFIG_PM
276static int max9850_suspend(struct snd_soc_codec *codec, pm_message_t state)
277{
278 max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
279
280 return 0;
281}
282
283static int max9850_resume(struct snd_soc_codec *codec)
284{
285 max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
286
287 return 0;
288}
289#else
290#define max9850_suspend NULL
291#define max9850_resume NULL
292#endif
293
294static int max9850_probe(struct snd_soc_codec *codec)
295{
296 struct snd_soc_dapm_context *dapm = &codec->dapm;
297 int ret;
298
299 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
300 if (ret < 0) {
301 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
302 return ret;
303 }
304
305 /* enable zero-detect */
306 snd_soc_update_bits(codec, MAX9850_GENERAL_PURPOSE, 1, 1);
307 /* enable slew-rate control */
308 snd_soc_update_bits(codec, MAX9850_VOLUME, 0x40, 0x40);
309 /* set slew-rate 125ms */
310 snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0);
311
312 snd_soc_dapm_new_controls(dapm, max9850_dapm_widgets,
313 ARRAY_SIZE(max9850_dapm_widgets));
314 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
315
316 snd_soc_add_controls(codec, max9850_controls,
317 ARRAY_SIZE(max9850_controls));
318
319 return 0;
320}
321
322static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
323 .probe = max9850_probe,
324 .suspend = max9850_suspend,
325 .resume = max9850_resume,
326 .set_bias_level = max9850_set_bias_level,
327 .reg_cache_size = ARRAY_SIZE(max9850_reg),
328 .reg_word_size = sizeof(u8),
329 .reg_cache_default = max9850_reg,
330 .volatile_register = max9850_volatile_register,
331};
332
333static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
334 const struct i2c_device_id *id)
335{
336 struct max9850_priv *max9850;
337 int ret;
338
339 max9850 = kzalloc(sizeof(struct max9850_priv), GFP_KERNEL);
340 if (max9850 == NULL)
341 return -ENOMEM;
342
343 i2c_set_clientdata(i2c, max9850);
344
345 ret = snd_soc_register_codec(&i2c->dev,
346 &soc_codec_dev_max9850, &max9850_dai, 1);
347 if (ret < 0)
348 kfree(max9850);
349 return ret;
350}
351
352static __devexit int max9850_i2c_remove(struct i2c_client *client)
353{
354 snd_soc_unregister_codec(&client->dev);
355 kfree(i2c_get_clientdata(client));
356 return 0;
357}
358
359static const struct i2c_device_id max9850_i2c_id[] = {
360 { "max9850", 0 },
361 { }
362};
363MODULE_DEVICE_TABLE(i2c, max9850_i2c_id);
364
365static struct i2c_driver max9850_i2c_driver = {
366 .driver = {
367 .name = "max9850",
368 .owner = THIS_MODULE,
369 },
370 .probe = max9850_i2c_probe,
371 .remove = __devexit_p(max9850_i2c_remove),
372 .id_table = max9850_i2c_id,
373};
374
375static int __init max9850_init(void)
376{
377 return i2c_add_driver(&max9850_i2c_driver);
378}
379module_init(max9850_init);
380
381static void __exit max9850_exit(void)
382{
383 i2c_del_driver(&max9850_i2c_driver);
384}
385module_exit(max9850_exit);
386
387MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
388MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
389MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9850.h b/sound/soc/codecs/max9850.h
new file mode 100644
index 000000000000..72b1ddb04b0d
--- /dev/null
+++ b/sound/soc/codecs/max9850.h
@@ -0,0 +1,38 @@
1/*
2 * max9850.h -- codec driver for max9850
3 *
4 * Copyright (C) 2011 taskit GmbH
5 * Author: Christian Glindkamp <christian.glindkamp@taskit.de>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef _MAX9850_H
15#define _MAX9850_H
16
17#define MAX9850_STATUSA 0x00
18#define MAX9850_STATUSB 0x01
19#define MAX9850_VOLUME 0x02
20#define MAX9850_GENERAL_PURPOSE 0x03
21#define MAX9850_INTERRUPT 0x04
22#define MAX9850_ENABLE 0x05
23#define MAX9850_CLOCK 0x06
24#define MAX9850_CHARGE_PUMP 0x07
25#define MAX9850_LRCLK_MSB 0x08
26#define MAX9850_LRCLK_LSB 0x09
27#define MAX9850_DIGITAL_AUDIO 0x0a
28
29#define MAX9850_CACHEREGNUM 11
30
31/* MAX9850_DIGITAL_AUDIO */
32#define MAX9850_MASTER (1<<7)
33#define MAX9850_INV (1<<6)
34#define MAX9850_BCINV (1<<5)
35#define MAX9850_DLY (1<<3)
36#define MAX9850_RTJ (1<<2)
37
38#endif
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5a5f187a2657..bd8f26e41602 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -32,8 +32,8 @@
32#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 32#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
33 SNDRV_PCM_RATE_48000) 33 SNDRV_PCM_RATE_48000)
34 34
35struct snd_soc_dai pcm3008_dai = { 35static struct snd_soc_dai_driver pcm3008_dai = {
36 .name = "PCM3008 HiFi", 36 .name = "pcm3008-hifi",
37 .playback = { 37 .playback = {
38 .stream_name = "PCM3008 Playback", 38 .stream_name = "PCM3008 Playback",
39 .channels_min = 1, 39 .channels_min = 1,
@@ -49,7 +49,6 @@ struct snd_soc_dai pcm3008_dai = {
49 .formats = SNDRV_PCM_FMTBIT_S16_LE, 49 .formats = SNDRV_PCM_FMTBIT_S16_LE,
50 }, 50 },
51}; 51};
52EXPORT_SYMBOL_GPL(pcm3008_dai);
53 52
54static void pcm3008_gpio_free(struct pcm3008_setup_data *setup) 53static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
55{ 54{
@@ -59,38 +58,13 @@ static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
59 gpio_free(setup->pdda_pin); 58 gpio_free(setup->pdda_pin);
60} 59}
61 60
62static int pcm3008_soc_probe(struct platform_device *pdev) 61static int pcm3008_soc_probe(struct snd_soc_codec *codec)
63{ 62{
64 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 63 struct pcm3008_setup_data *setup = codec->dev->platform_data;
65 struct snd_soc_codec *codec;
66 struct pcm3008_setup_data *setup = socdev->codec_data;
67 int ret = 0; 64 int ret = 0;
68 65
69 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); 66 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
70 67
71 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
72 if (!socdev->card->codec)
73 return -ENOMEM;
74
75 codec = socdev->card->codec;
76 mutex_init(&codec->mutex);
77
78 codec->name = "PCM3008";
79 codec->owner = THIS_MODULE;
80 codec->dai = &pcm3008_dai;
81 codec->num_dai = 1;
82 codec->write = NULL;
83 codec->read = NULL;
84 INIT_LIST_HEAD(&codec->dapm_widgets);
85 INIT_LIST_HEAD(&codec->dapm_paths);
86
87 /* Register PCMs. */
88 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
89 if (ret < 0) {
90 printk(KERN_ERR "pcm3008: failed to create pcms\n");
91 goto pcm_err;
92 }
93
94 /* DEM1 DEM0 DE-EMPHASIS_MODE 68 /* DEM1 DEM0 DE-EMPHASIS_MODE
95 * Low Low De-emphasis 44.1 kHz ON 69 * Low Low De-emphasis 44.1 kHz ON
96 * Low High De-emphasis OFF 70 * Low High De-emphasis OFF
@@ -130,33 +104,22 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
130 104
131gpio_err: 105gpio_err:
132 pcm3008_gpio_free(setup); 106 pcm3008_gpio_free(setup);
133pcm_err:
134 kfree(socdev->card->codec);
135 107
136 return ret; 108 return ret;
137} 109}
138 110
139static int pcm3008_soc_remove(struct platform_device *pdev) 111static int pcm3008_soc_remove(struct snd_soc_codec *codec)
140{ 112{
141 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 113 struct pcm3008_setup_data *setup = codec->dev->platform_data;
142 struct snd_soc_codec *codec = socdev->card->codec;
143 struct pcm3008_setup_data *setup = socdev->codec_data;
144
145 if (!codec)
146 return 0;
147 114
148 pcm3008_gpio_free(setup); 115 pcm3008_gpio_free(setup);
149 snd_soc_free_pcms(socdev);
150 kfree(socdev->card->codec);
151
152 return 0; 116 return 0;
153} 117}
154 118
155#ifdef CONFIG_PM 119#ifdef CONFIG_PM
156static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg) 120static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
157{ 121{
158 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 122 struct pcm3008_setup_data *setup = codec->dev->platform_data;
159 struct pcm3008_setup_data *setup = socdev->codec_data;
160 123
161 gpio_set_value(setup->pdad_pin, 0); 124 gpio_set_value(setup->pdad_pin, 0);
162 gpio_set_value(setup->pdda_pin, 0); 125 gpio_set_value(setup->pdda_pin, 0);
@@ -164,10 +127,9 @@ static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
164 return 0; 127 return 0;
165} 128}
166 129
167static int pcm3008_soc_resume(struct platform_device *pdev) 130static int pcm3008_soc_resume(struct snd_soc_codec *codec)
168{ 131{
169 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 132 struct pcm3008_setup_data *setup = codec->dev->platform_data;
170 struct pcm3008_setup_data *setup = socdev->codec_data;
171 133
172 gpio_set_value(setup->pdad_pin, 1); 134 gpio_set_value(setup->pdad_pin, 1);
173 gpio_set_value(setup->pdda_pin, 1); 135 gpio_set_value(setup->pdda_pin, 1);
@@ -179,23 +141,45 @@ static int pcm3008_soc_resume(struct platform_device *pdev)
179#define pcm3008_soc_resume NULL 141#define pcm3008_soc_resume NULL
180#endif 142#endif
181 143
182struct snd_soc_codec_device soc_codec_dev_pcm3008 = { 144static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
183 .probe = pcm3008_soc_probe, 145 .probe = pcm3008_soc_probe,
184 .remove = pcm3008_soc_remove, 146 .remove = pcm3008_soc_remove,
185 .suspend = pcm3008_soc_suspend, 147 .suspend = pcm3008_soc_suspend,
186 .resume = pcm3008_soc_resume, 148 .resume = pcm3008_soc_resume,
187}; 149};
188EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
189 150
190static int __init pcm3008_init(void) 151static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
152{
153 return snd_soc_register_codec(&pdev->dev,
154 &soc_codec_dev_pcm3008, &pcm3008_dai, 1);
155}
156
157static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
158{
159 snd_soc_unregister_codec(&pdev->dev);
160 return 0;
161}
162
163MODULE_ALIAS("platform:pcm3008-codec");
164
165static struct platform_driver pcm3008_codec_driver = {
166 .probe = pcm3008_codec_probe,
167 .remove = __devexit_p(pcm3008_codec_remove),
168 .driver = {
169 .name = "pcm3008-codec",
170 .owner = THIS_MODULE,
171 },
172};
173
174static int __init pcm3008_modinit(void)
191{ 175{
192 return snd_soc_register_dai(&pcm3008_dai); 176 return platform_driver_register(&pcm3008_codec_driver);
193} 177}
194module_init(pcm3008_init); 178module_init(pcm3008_modinit);
195 179
196static void __exit pcm3008_exit(void) 180static void __exit pcm3008_exit(void)
197{ 181{
198 snd_soc_unregister_dai(&pcm3008_dai); 182 platform_driver_unregister(&pcm3008_codec_driver);
199} 183}
200module_exit(pcm3008_exit); 184module_exit(pcm3008_exit);
201 185
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
index d04e87d3c060..7e5489ab4812 100644
--- a/sound/soc/codecs/pcm3008.h
+++ b/sound/soc/codecs/pcm3008.h
@@ -19,7 +19,4 @@ struct pcm3008_setup_data {
19 unsigned pdda_pin; 19 unsigned pdda_pin;
20}; 20};
21 21
22extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
23extern struct snd_soc_dai pcm3008_dai;
24
25#endif 22#endif
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
new file mode 100644
index 000000000000..ff29380c9ed3
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.c
@@ -0,0 +1,1527 @@
1/*
2 * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/slab.h>
16#include <linux/pm.h>
17#include <linux/i2c.h>
18#include <linux/clk.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22#include <linux/regulator/consumer.h>
23#include <sound/core.h>
24#include <sound/tlv.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30
31#include "sgtl5000.h"
32
33#define SGTL5000_DAP_REG_OFFSET 0x0100
34#define SGTL5000_MAX_REG_OFFSET 0x013A
35
36/* default value of sgtl5000 registers except DAP */
37static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = {
38 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */
39 0x0000, /* 0x0002, CHIP_DIG_POWER. */
40 0x0008, /* 0x0004, CHIP_CKL_CTRL */
41 0x0010, /* 0x0006, CHIP_I2S_CTRL */
42 0x0000, /* 0x0008, reserved */
43 0x0008, /* 0x000A, CHIP_SSS_CTRL */
44 0x0000, /* 0x000C, reserved */
45 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */
46 0x3c3c, /* 0x0010, CHIP_DAC_VOL */
47 0x0000, /* 0x0012, reserved */
48 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */
49 0x0000, /* 0x0016, reserved */
50 0x0000, /* 0x0018, reserved */
51 0x0000, /* 0x001A, reserved */
52 0x0000, /* 0x001E, reserved */
53 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */
54 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */
55 0x0111, /* 0x0024, CHIP_ANN_CTRL */
56 0x0000, /* 0x0026, CHIP_LINREG_CTRL */
57 0x0000, /* 0x0028, CHIP_REF_CTRL */
58 0x0000, /* 0x002A, CHIP_MIC_CTRL */
59 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */
60 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */
61 0x7060, /* 0x0030, CHIP_ANA_POWER */
62 0x5000, /* 0x0032, CHIP_PLL_CTRL */
63 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */
64 0x0000, /* 0x0036, CHIP_ANA_STATUS */
65 0x0000, /* 0x0038, reserved */
66 0x0000, /* 0x003A, CHIP_ANA_TEST2 */
67 0x0000, /* 0x003C, CHIP_SHORT_CTRL */
68 0x0000, /* reserved */
69};
70
71/* default value of dap registers */
72static const u16 sgtl5000_dap_regs[] = {
73 0x0000, /* 0x0100, DAP_CONTROL */
74 0x0000, /* 0x0102, DAP_PEQ */
75 0x0040, /* 0x0104, DAP_BASS_ENHANCE */
76 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */
77 0x0000, /* 0x0108, DAP_AUDIO_EQ */
78 0x0040, /* 0x010A, DAP_SGTL_SURROUND */
79 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */
80 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */
81 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */
82 0x0000, /* 0x0112, reserved */
83 0x0000, /* 0x0114, reserved */
84 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */
85 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */
86 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */
87 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */
88 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */
89 0x8000, /* 0x0120, DAP_MAIN_CHAN */
90 0x0000, /* 0x0122, DAP_MIX_CHAN */
91 0x0510, /* 0x0124, DAP_AVC_CTRL */
92 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */
93 0x0028, /* 0x0128, DAP_AVC_ATTACK */
94 0x0050, /* 0x012A, DAP_AVC_DECAY */
95 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */
96 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */
97 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */
98 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */
99 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */
100 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */
101 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */
102 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */
103};
104
105/* regulator supplies for sgtl5000, VDDD is an optional external supply */
106enum sgtl5000_regulator_supplies {
107 VDDA,
108 VDDIO,
109 VDDD,
110 SGTL5000_SUPPLY_NUM
111};
112
113/* vddd is optional supply */
114static const char *supply_names[SGTL5000_SUPPLY_NUM] = {
115 "VDDA",
116 "VDDIO",
117 "VDDD"
118};
119
120#define LDO_CONSUMER_NAME "VDDD_LDO"
121#define LDO_VOLTAGE 1200000
122
123static struct regulator_consumer_supply ldo_consumer[] = {
124 REGULATOR_SUPPLY(LDO_CONSUMER_NAME, NULL),
125};
126
127static struct regulator_init_data ldo_init_data = {
128 .constraints = {
129 .min_uV = 850000,
130 .max_uV = 1600000,
131 .valid_modes_mask = REGULATOR_MODE_NORMAL,
132 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
133 },
134 .num_consumer_supplies = 1,
135 .consumer_supplies = &ldo_consumer[0],
136};
137
138/*
139 * sgtl5000 internal ldo regulator,
140 * enabled when VDDD not provided
141 */
142struct ldo_regulator {
143 struct regulator_desc desc;
144 struct regulator_dev *dev;
145 int voltage;
146 void *codec_data;
147 bool enabled;
148};
149
150/* sgtl5000 private structure in codec */
151struct sgtl5000_priv {
152 int sysclk; /* sysclk rate */
153 int master; /* i2s master or not */
154 int fmt; /* i2s data format */
155 struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM];
156 struct ldo_regulator *ldo;
157};
158
159/*
160 * mic_bias power on/off share the same register bits with
161 * output impedance of mic bias, when power on mic bias, we
162 * need reclaim it to impedance value.
163 * 0x0 = Powered off
164 * 0x1 = 2Kohm
165 * 0x2 = 4Kohm
166 * 0x3 = 8Kohm
167 */
168static int mic_bias_event(struct snd_soc_dapm_widget *w,
169 struct snd_kcontrol *kcontrol, int event)
170{
171 switch (event) {
172 case SND_SOC_DAPM_POST_PMU:
173 /* change mic bias resistor to 4Kohm */
174 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
175 SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k);
176 break;
177
178 case SND_SOC_DAPM_PRE_PMD:
179 /*
180 * SGTL5000_BIAS_R_8k as mask to clean the two bits
181 * of mic bias and output impedance
182 */
183 snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
184 SGTL5000_BIAS_R_8k, 0);
185 break;
186 }
187 return 0;
188}
189
190/*
191 * using codec assist to small pop, hp_powerup or lineout_powerup
192 * should stay setting until vag_powerup is fully ramped down,
193 * vag fully ramped down require 400ms.
194 */
195static int small_pop_event(struct snd_soc_dapm_widget *w,
196 struct snd_kcontrol *kcontrol, int event)
197{
198 switch (event) {
199 case SND_SOC_DAPM_PRE_PMU:
200 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
201 SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
202 break;
203
204 case SND_SOC_DAPM_PRE_PMD:
205 snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
206 SGTL5000_VAG_POWERUP, 0);
207 msleep(400);
208 break;
209 default:
210 break;
211 }
212
213 return 0;
214}
215
216/* input sources for ADC */
217static const char *adc_mux_text[] = {
218 "MIC_IN", "LINE_IN"
219};
220
221static const struct soc_enum adc_enum =
222SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text);
223
224static const struct snd_kcontrol_new adc_mux =
225SOC_DAPM_ENUM("Capture Mux", adc_enum);
226
227/* input sources for DAC */
228static const char *dac_mux_text[] = {
229 "DAC", "LINE_IN"
230};
231
232static const struct soc_enum dac_enum =
233SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text);
234
235static const struct snd_kcontrol_new dac_mux =
236SOC_DAPM_ENUM("Headphone Mux", dac_enum);
237
238static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
239 SND_SOC_DAPM_INPUT("LINE_IN"),
240 SND_SOC_DAPM_INPUT("MIC_IN"),
241
242 SND_SOC_DAPM_OUTPUT("HP_OUT"),
243 SND_SOC_DAPM_OUTPUT("LINE_OUT"),
244
245 SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
246 mic_bias_event,
247 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
248
249 SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
250 small_pop_event,
251 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
252 SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0,
253 small_pop_event,
254 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
255
256 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
257 SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux),
258
259 /* aif for i2s input */
260 SND_SOC_DAPM_AIF_IN("AIFIN", "Playback",
261 0, SGTL5000_CHIP_DIG_POWER,
262 0, 0),
263
264 /* aif for i2s output */
265 SND_SOC_DAPM_AIF_OUT("AIFOUT", "Capture",
266 0, SGTL5000_CHIP_DIG_POWER,
267 1, 0),
268
269 SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
270
271 SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
272};
273
274/* routes for sgtl5000 */
275static const struct snd_soc_dapm_route audio_map[] = {
276 {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */
277 {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */
278
279 {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */
280 {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */
281
282 {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */
283 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
284 {"LO", NULL, "DAC"}, /* dac --> line_out */
285
286 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
287 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
288
289 {"LINE_OUT", NULL, "LO"},
290 {"HP_OUT", NULL, "HP"},
291};
292
293/* custom function to fetch info of PCM playback volume */
294static int dac_info_volsw(struct snd_kcontrol *kcontrol,
295 struct snd_ctl_elem_info *uinfo)
296{
297 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
298 uinfo->count = 2;
299 uinfo->value.integer.min = 0;
300 uinfo->value.integer.max = 0xfc - 0x3c;
301 return 0;
302}
303
304/*
305 * custom function to get of PCM playback volume
306 *
307 * dac volume register
308 * 15-------------8-7--------------0
309 * | R channel vol | L channel vol |
310 * -------------------------------
311 *
312 * PCM volume with 0.5017 dB steps from 0 to -90 dB
313 *
314 * register values map to dB
315 * 0x3B and less = Reserved
316 * 0x3C = 0 dB
317 * 0x3D = -0.5 dB
318 * 0xF0 = -90 dB
319 * 0xFC and greater = Muted
320 *
321 * register value map to userspace value
322 *
323 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
324 * ------------------------------
325 * userspace value 0xc0 0
326 */
327static int dac_get_volsw(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol)
329{
330 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
331 int reg;
332 int l;
333 int r;
334
335 reg = snd_soc_read(codec, SGTL5000_CHIP_DAC_VOL);
336
337 /* get left channel volume */
338 l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
339
340 /* get right channel volume */
341 r = (reg & SGTL5000_DAC_VOL_RIGHT_MASK) >> SGTL5000_DAC_VOL_RIGHT_SHIFT;
342
343 /* make sure value fall in (0x3c,0xfc) */
344 l = clamp(l, 0x3c, 0xfc);
345 r = clamp(r, 0x3c, 0xfc);
346
347 /* invert it and map to userspace value */
348 l = 0xfc - l;
349 r = 0xfc - r;
350
351 ucontrol->value.integer.value[0] = l;
352 ucontrol->value.integer.value[1] = r;
353
354 return 0;
355}
356
357/*
358 * custom function to put of PCM playback volume
359 *
360 * dac volume register
361 * 15-------------8-7--------------0
362 * | R channel vol | L channel vol |
363 * -------------------------------
364 *
365 * PCM volume with 0.5017 dB steps from 0 to -90 dB
366 *
367 * register values map to dB
368 * 0x3B and less = Reserved
369 * 0x3C = 0 dB
370 * 0x3D = -0.5 dB
371 * 0xF0 = -90 dB
372 * 0xFC and greater = Muted
373 *
374 * userspace value map to register value
375 *
376 * userspace value 0xc0 0
377 * ------------------------------
378 * register value 0x3c(0dB) 0xf0(-90dB)0xfc
379 */
380static int dac_put_volsw(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 int reg;
385 int l;
386 int r;
387
388 l = ucontrol->value.integer.value[0];
389 r = ucontrol->value.integer.value[1];
390
391 /* make sure userspace volume fall in (0, 0xfc-0x3c) */
392 l = clamp(l, 0, 0xfc - 0x3c);
393 r = clamp(r, 0, 0xfc - 0x3c);
394
395 /* invert it, get the value can be set to register */
396 l = 0xfc - l;
397 r = 0xfc - r;
398
399 /* shift to get the register value */
400 reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
401 r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
402
403 snd_soc_write(codec, SGTL5000_CHIP_DAC_VOL, reg);
404
405 return 0;
406}
407
408static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0);
409
410/* tlv for mic gain, 0db 20db 30db 40db */
411static const unsigned int mic_gain_tlv[] = {
412 TLV_DB_RANGE_HEAD(4),
413 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
414 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
415};
416
417/* tlv for hp volume, -51.5db to 12.0db, step .5db */
418static const DECLARE_TLV_DB_SCALE(headphone_volume, -5150, 50, 0);
419
420static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
421 /* SOC_DOUBLE_S8_TLV with invert */
422 {
423 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
424 .name = "PCM Playback Volume",
425 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
426 SNDRV_CTL_ELEM_ACCESS_READWRITE,
427 .info = dac_info_volsw,
428 .get = dac_get_volsw,
429 .put = dac_put_volsw,
430 },
431
432 SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0),
433 SOC_SINGLE_TLV("Capture Attenuate Switch (-6dB)",
434 SGTL5000_CHIP_ANA_ADC_CTRL,
435 8, 2, 0, capture_6db_attenuate),
436 SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
437
438 SOC_DOUBLE_TLV("Headphone Playback Volume",
439 SGTL5000_CHIP_ANA_HP_CTRL,
440 0, 8,
441 0x7f, 1,
442 headphone_volume),
443 SOC_SINGLE("Headphone Playback ZC Switch", SGTL5000_CHIP_ANA_CTRL,
444 5, 1, 0),
445
446 SOC_SINGLE_TLV("Mic Volume", SGTL5000_CHIP_MIC_CTRL,
447 0, 4, 0, mic_gain_tlv),
448};
449
450/* mute the codec used by alsa core */
451static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute)
452{
453 struct snd_soc_codec *codec = codec_dai->codec;
454 u16 adcdac_ctrl = SGTL5000_DAC_MUTE_LEFT | SGTL5000_DAC_MUTE_RIGHT;
455
456 snd_soc_update_bits(codec, SGTL5000_CHIP_ADCDAC_CTRL,
457 adcdac_ctrl, mute ? adcdac_ctrl : 0);
458
459 return 0;
460}
461
462/* set codec format */
463static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
464{
465 struct snd_soc_codec *codec = codec_dai->codec;
466 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
467 u16 i2sctl = 0;
468
469 sgtl5000->master = 0;
470 /*
471 * i2s clock and frame master setting.
472 * ONLY support:
473 * - clock and frame slave,
474 * - clock and frame master
475 */
476 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
477 case SND_SOC_DAIFMT_CBS_CFS:
478 break;
479 case SND_SOC_DAIFMT_CBM_CFM:
480 i2sctl |= SGTL5000_I2S_MASTER;
481 sgtl5000->master = 1;
482 break;
483 default:
484 return -EINVAL;
485 }
486
487 /* setting i2s data format */
488 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
489 case SND_SOC_DAIFMT_DSP_A:
490 i2sctl |= SGTL5000_I2S_MODE_PCM;
491 break;
492 case SND_SOC_DAIFMT_DSP_B:
493 i2sctl |= SGTL5000_I2S_MODE_PCM;
494 i2sctl |= SGTL5000_I2S_LRALIGN;
495 break;
496 case SND_SOC_DAIFMT_I2S:
497 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
498 break;
499 case SND_SOC_DAIFMT_RIGHT_J:
500 i2sctl |= SGTL5000_I2S_MODE_RJ;
501 i2sctl |= SGTL5000_I2S_LRPOL;
502 break;
503 case SND_SOC_DAIFMT_LEFT_J:
504 i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
505 i2sctl |= SGTL5000_I2S_LRALIGN;
506 break;
507 default:
508 return -EINVAL;
509 }
510
511 sgtl5000->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
512
513 /* Clock inversion */
514 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
515 case SND_SOC_DAIFMT_NB_NF:
516 break;
517 case SND_SOC_DAIFMT_IB_NF:
518 i2sctl |= SGTL5000_I2S_SCLK_INV;
519 break;
520 default:
521 return -EINVAL;
522 }
523
524 snd_soc_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl);
525
526 return 0;
527}
528
529/* set codec sysclk */
530static int sgtl5000_set_dai_sysclk(struct snd_soc_dai *codec_dai,
531 int clk_id, unsigned int freq, int dir)
532{
533 struct snd_soc_codec *codec = codec_dai->codec;
534 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
535
536 switch (clk_id) {
537 case SGTL5000_SYSCLK:
538 sgtl5000->sysclk = freq;
539 break;
540 default:
541 return -EINVAL;
542 }
543
544 return 0;
545}
546
547/*
548 * set clock according to i2s frame clock,
549 * sgtl5000 provide 2 clock sources.
550 * 1. sys_mclk. sample freq can only configure to
551 * 1/256, 1/384, 1/512 of sys_mclk.
552 * 2. pll. can derive any audio clocks.
553 *
554 * clock setting rules:
555 * 1. in slave mode, only sys_mclk can use.
556 * 2. as constraint by sys_mclk, sample freq should
557 * set to 32k, 44.1k and above.
558 * 3. using sys_mclk prefer to pll to save power.
559 */
560static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
561{
562 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
563 int clk_ctl = 0;
564 int sys_fs; /* sample freq */
565
566 /*
567 * sample freq should be divided by frame clock,
568 * if frame clock lower than 44.1khz, sample feq should set to
569 * 32khz or 44.1khz.
570 */
571 switch (frame_rate) {
572 case 8000:
573 case 16000:
574 sys_fs = 32000;
575 break;
576 case 11025:
577 case 22050:
578 sys_fs = 44100;
579 break;
580 default:
581 sys_fs = frame_rate;
582 break;
583 }
584
585 /* set divided factor of frame clock */
586 switch (sys_fs / frame_rate) {
587 case 4:
588 clk_ctl |= SGTL5000_RATE_MODE_DIV_4 << SGTL5000_RATE_MODE_SHIFT;
589 break;
590 case 2:
591 clk_ctl |= SGTL5000_RATE_MODE_DIV_2 << SGTL5000_RATE_MODE_SHIFT;
592 break;
593 case 1:
594 clk_ctl |= SGTL5000_RATE_MODE_DIV_1 << SGTL5000_RATE_MODE_SHIFT;
595 break;
596 default:
597 return -EINVAL;
598 }
599
600 /* set the sys_fs according to frame rate */
601 switch (sys_fs) {
602 case 32000:
603 clk_ctl |= SGTL5000_SYS_FS_32k << SGTL5000_SYS_FS_SHIFT;
604 break;
605 case 44100:
606 clk_ctl |= SGTL5000_SYS_FS_44_1k << SGTL5000_SYS_FS_SHIFT;
607 break;
608 case 48000:
609 clk_ctl |= SGTL5000_SYS_FS_48k << SGTL5000_SYS_FS_SHIFT;
610 break;
611 case 96000:
612 clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT;
613 break;
614 default:
615 dev_err(codec->dev, "frame rate %d not supported\n",
616 frame_rate);
617 return -EINVAL;
618 }
619
620 /*
621 * calculate the divider of mclk/sample_freq,
622 * factor of freq =96k can only be 256, since mclk in range (12m,27m)
623 */
624 switch (sgtl5000->sysclk / sys_fs) {
625 case 256:
626 clk_ctl |= SGTL5000_MCLK_FREQ_256FS <<
627 SGTL5000_MCLK_FREQ_SHIFT;
628 break;
629 case 384:
630 clk_ctl |= SGTL5000_MCLK_FREQ_384FS <<
631 SGTL5000_MCLK_FREQ_SHIFT;
632 break;
633 case 512:
634 clk_ctl |= SGTL5000_MCLK_FREQ_512FS <<
635 SGTL5000_MCLK_FREQ_SHIFT;
636 break;
637 default:
638 /* if mclk not satisify the divider, use pll */
639 if (sgtl5000->master) {
640 clk_ctl |= SGTL5000_MCLK_FREQ_PLL <<
641 SGTL5000_MCLK_FREQ_SHIFT;
642 } else {
643 dev_err(codec->dev,
644 "PLL not supported in slave mode\n");
645 return -EINVAL;
646 }
647 }
648
649 /* if using pll, please check manual 6.4.2 for detail */
650 if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) {
651 u64 out, t;
652 int div2;
653 int pll_ctl;
654 unsigned int in, int_div, frac_div;
655
656 if (sgtl5000->sysclk > 17000000) {
657 div2 = 1;
658 in = sgtl5000->sysclk / 2;
659 } else {
660 div2 = 0;
661 in = sgtl5000->sysclk;
662 }
663 if (sys_fs == 44100)
664 out = 180633600;
665 else
666 out = 196608000;
667 t = do_div(out, in);
668 int_div = out;
669 t *= 2048;
670 do_div(t, in);
671 frac_div = t;
672 pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT |
673 frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT;
674
675 snd_soc_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl);
676 if (div2)
677 snd_soc_update_bits(codec,
678 SGTL5000_CHIP_CLK_TOP_CTRL,
679 SGTL5000_INPUT_FREQ_DIV2,
680 SGTL5000_INPUT_FREQ_DIV2);
681 else
682 snd_soc_update_bits(codec,
683 SGTL5000_CHIP_CLK_TOP_CTRL,
684 SGTL5000_INPUT_FREQ_DIV2,
685 0);
686
687 /* power up pll */
688 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
689 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
690 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
691 } else {
692 /* power down pll */
693 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
694 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
695 0);
696 }
697
698 /* if using pll, clk_ctrl must be set after pll power up */
699 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
700
701 return 0;
702}
703
704/*
705 * Set PCM DAI bit size and sample rate.
706 * input: params_rate, params_fmt
707 */
708static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
709 struct snd_pcm_hw_params *params,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_codec *codec = rtd->codec;
714 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
715 int channels = params_channels(params);
716 int i2s_ctl = 0;
717 int stereo;
718 int ret;
719
720 /* sysclk should already set */
721 if (!sgtl5000->sysclk) {
722 dev_err(codec->dev, "%s: set sysclk first!\n", __func__);
723 return -EFAULT;
724 }
725
726 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
727 stereo = SGTL5000_DAC_STEREO;
728 else
729 stereo = SGTL5000_ADC_STEREO;
730
731 /* set mono to save power */
732 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, stereo,
733 channels == 1 ? 0 : stereo);
734
735 /* set codec clock base on lrclk */
736 ret = sgtl5000_set_clock(codec, params_rate(params));
737 if (ret)
738 return ret;
739
740 /* set i2s data format */
741 switch (params_format(params)) {
742 case SNDRV_PCM_FORMAT_S16_LE:
743 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
744 return -EINVAL;
745 i2s_ctl |= SGTL5000_I2S_DLEN_16 << SGTL5000_I2S_DLEN_SHIFT;
746 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_32FS <<
747 SGTL5000_I2S_SCLKFREQ_SHIFT;
748 break;
749 case SNDRV_PCM_FORMAT_S20_3LE:
750 i2s_ctl |= SGTL5000_I2S_DLEN_20 << SGTL5000_I2S_DLEN_SHIFT;
751 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
752 SGTL5000_I2S_SCLKFREQ_SHIFT;
753 break;
754 case SNDRV_PCM_FORMAT_S24_LE:
755 i2s_ctl |= SGTL5000_I2S_DLEN_24 << SGTL5000_I2S_DLEN_SHIFT;
756 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
757 SGTL5000_I2S_SCLKFREQ_SHIFT;
758 break;
759 case SNDRV_PCM_FORMAT_S32_LE:
760 if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J)
761 return -EINVAL;
762 i2s_ctl |= SGTL5000_I2S_DLEN_32 << SGTL5000_I2S_DLEN_SHIFT;
763 i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS <<
764 SGTL5000_I2S_SCLKFREQ_SHIFT;
765 break;
766 default:
767 return -EINVAL;
768 }
769
770 snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl);
771
772 return 0;
773}
774
775#ifdef CONFIG_REGULATOR
776static int ldo_regulator_is_enabled(struct regulator_dev *dev)
777{
778 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
779
780 return ldo->enabled;
781}
782
783static int ldo_regulator_enable(struct regulator_dev *dev)
784{
785 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
786 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
787 int reg;
788
789 if (ldo_regulator_is_enabled(dev))
790 return 0;
791
792 /* set regulator value firstly */
793 reg = (1600 - ldo->voltage / 1000) / 50;
794 reg = clamp(reg, 0x0, 0xf);
795
796 /* amend the voltage value, unit: uV */
797 ldo->voltage = (1600 - reg * 50) * 1000;
798
799 /* set voltage to register */
800 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
801 (0x1 << 4) - 1, reg);
802
803 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
804 SGTL5000_LINEREG_D_POWERUP,
805 SGTL5000_LINEREG_D_POWERUP);
806
807 /* when internal ldo enabled, simple digital power can be disabled */
808 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
809 SGTL5000_LINREG_SIMPLE_POWERUP,
810 0);
811
812 ldo->enabled = 1;
813 return 0;
814}
815
816static int ldo_regulator_disable(struct regulator_dev *dev)
817{
818 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
819 struct snd_soc_codec *codec = (struct snd_soc_codec *)ldo->codec_data;
820
821 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
822 SGTL5000_LINEREG_D_POWERUP,
823 0);
824
825 /* clear voltage info */
826 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
827 (0x1 << 4) - 1, 0);
828
829 ldo->enabled = 0;
830
831 return 0;
832}
833
834static int ldo_regulator_get_voltage(struct regulator_dev *dev)
835{
836 struct ldo_regulator *ldo = rdev_get_drvdata(dev);
837
838 return ldo->voltage;
839}
840
841static struct regulator_ops ldo_regulator_ops = {
842 .is_enabled = ldo_regulator_is_enabled,
843 .enable = ldo_regulator_enable,
844 .disable = ldo_regulator_disable,
845 .get_voltage = ldo_regulator_get_voltage,
846};
847
848static int ldo_regulator_register(struct snd_soc_codec *codec,
849 struct regulator_init_data *init_data,
850 int voltage)
851{
852 struct ldo_regulator *ldo;
853
854 ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
855
856 if (!ldo) {
857 dev_err(codec->dev, "failed to allocate ldo_regulator\n");
858 return -ENOMEM;
859 }
860
861 ldo->desc.name = kstrdup(dev_name(codec->dev), GFP_KERNEL);
862 if (!ldo->desc.name) {
863 kfree(ldo);
864 dev_err(codec->dev, "failed to allocate decs name memory\n");
865 return -ENOMEM;
866 }
867
868 ldo->desc.type = REGULATOR_VOLTAGE;
869 ldo->desc.owner = THIS_MODULE;
870 ldo->desc.ops = &ldo_regulator_ops;
871 ldo->desc.n_voltages = 1;
872
873 ldo->codec_data = codec;
874 ldo->voltage = voltage;
875
876 ldo->dev = regulator_register(&ldo->desc, codec->dev,
877 init_data, ldo);
878 if (IS_ERR(ldo->dev)) {
879 int ret = PTR_ERR(ldo->dev);
880
881 dev_err(codec->dev, "failed to register regulator\n");
882 kfree(ldo->desc.name);
883 kfree(ldo);
884
885 return ret;
886 }
887
888 return 0;
889}
890
891static int ldo_regulator_remove(struct snd_soc_codec *codec)
892{
893 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
894 struct ldo_regulator *ldo = sgtl5000->ldo;
895
896 if (!ldo)
897 return 0;
898
899 regulator_unregister(ldo->dev);
900 kfree(ldo->desc.name);
901 kfree(ldo);
902
903 return 0;
904}
905#else
906static int ldo_regulator_register(struct snd_soc_codec *codec,
907 struct regulator_init_data *init_data,
908 int voltage)
909{
910 return -EINVAL;
911}
912
913static int ldo_regulator_remove(struct snd_soc_codec *codec)
914{
915 return 0;
916}
917#endif
918
919/*
920 * set dac bias
921 * common state changes:
922 * startup:
923 * off --> standby --> prepare --> on
924 * standby --> prepare --> on
925 *
926 * stop:
927 * on --> prepare --> standby
928 */
929static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
930 enum snd_soc_bias_level level)
931{
932 int ret;
933 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
934
935 switch (level) {
936 case SND_SOC_BIAS_ON:
937 case SND_SOC_BIAS_PREPARE:
938 break;
939 case SND_SOC_BIAS_STANDBY:
940 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
941 ret = regulator_bulk_enable(
942 ARRAY_SIZE(sgtl5000->supplies),
943 sgtl5000->supplies);
944 if (ret)
945 return ret;
946 udelay(10);
947 }
948
949 break;
950 case SND_SOC_BIAS_OFF:
951 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
952 sgtl5000->supplies);
953 break;
954 }
955
956 codec->dapm.bias_level = level;
957 return 0;
958}
959
960#define SGTL5000_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
961 SNDRV_PCM_FMTBIT_S20_3LE |\
962 SNDRV_PCM_FMTBIT_S24_LE |\
963 SNDRV_PCM_FMTBIT_S32_LE)
964
965static struct snd_soc_dai_ops sgtl5000_ops = {
966 .hw_params = sgtl5000_pcm_hw_params,
967 .digital_mute = sgtl5000_digital_mute,
968 .set_fmt = sgtl5000_set_dai_fmt,
969 .set_sysclk = sgtl5000_set_dai_sysclk,
970};
971
972static struct snd_soc_dai_driver sgtl5000_dai = {
973 .name = "sgtl5000",
974 .playback = {
975 .stream_name = "Playback",
976 .channels_min = 1,
977 .channels_max = 2,
978 /*
979 * only support 8~48K + 96K,
980 * TODO modify hw_param to support more
981 */
982 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
983 .formats = SGTL5000_FORMATS,
984 },
985 .capture = {
986 .stream_name = "Capture",
987 .channels_min = 1,
988 .channels_max = 2,
989 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000,
990 .formats = SGTL5000_FORMATS,
991 },
992 .ops = &sgtl5000_ops,
993 .symmetric_rates = 1,
994};
995
996static int sgtl5000_volatile_register(struct snd_soc_codec *codec,
997 unsigned int reg)
998{
999 switch (reg) {
1000 case SGTL5000_CHIP_ID:
1001 case SGTL5000_CHIP_ADCDAC_CTRL:
1002 case SGTL5000_CHIP_ANA_STATUS:
1003 return 1;
1004 }
1005
1006 return 0;
1007}
1008
1009#ifdef CONFIG_SUSPEND
1010static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state)
1011{
1012 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
1013
1014 return 0;
1015}
1016
1017/*
1018 * restore all sgtl5000 registers,
1019 * since a big hole between dap and regular registers,
1020 * we will restore them respectively.
1021 */
1022static int sgtl5000_restore_regs(struct snd_soc_codec *codec)
1023{
1024 u16 *cache = codec->reg_cache;
1025 int i;
1026 int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1;
1027
1028 /* restore regular registers */
1029 for (i = 0; i < regular_regs; i++) {
1030 int reg = i << 1;
1031
1032 /* this regs depends on the others */
1033 if (reg == SGTL5000_CHIP_ANA_POWER ||
1034 reg == SGTL5000_CHIP_CLK_CTRL ||
1035 reg == SGTL5000_CHIP_LINREG_CTRL ||
1036 reg == SGTL5000_CHIP_LINE_OUT_CTRL ||
1037 reg == SGTL5000_CHIP_CLK_CTRL)
1038 continue;
1039
1040 snd_soc_write(codec, reg, cache[i]);
1041 }
1042
1043 /* restore dap registers */
1044 for (i = SGTL5000_DAP_REG_OFFSET >> 1;
1045 i < SGTL5000_MAX_REG_OFFSET >> 1; i++) {
1046 int reg = i << 1;
1047
1048 snd_soc_write(codec, reg, cache[i]);
1049 }
1050
1051 /*
1052 * restore power and other regs according
1053 * to set_power() and set_clock()
1054 */
1055 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL,
1056 cache[SGTL5000_CHIP_LINREG_CTRL >> 1]);
1057
1058 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER,
1059 cache[SGTL5000_CHIP_ANA_POWER >> 1]);
1060
1061 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL,
1062 cache[SGTL5000_CHIP_CLK_CTRL >> 1]);
1063
1064 snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL,
1065 cache[SGTL5000_CHIP_REF_CTRL >> 1]);
1066
1067 snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1068 cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]);
1069 return 0;
1070}
1071
1072static int sgtl5000_resume(struct snd_soc_codec *codec)
1073{
1074 /* Bring the codec back up to standby to enable regulators */
1075 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1076
1077 /* Restore registers by cached in memory */
1078 sgtl5000_restore_regs(codec);
1079 return 0;
1080}
1081#else
1082#define sgtl5000_suspend NULL
1083#define sgtl5000_resume NULL
1084#endif /* CONFIG_SUSPEND */
1085
1086/*
1087 * sgtl5000 has 3 internal power supplies:
1088 * 1. VAG, normally set to vdda/2
1089 * 2. chargepump, set to different value
1090 * according to voltage of vdda and vddio
1091 * 3. line out VAG, normally set to vddio/2
1092 *
1093 * and should be set according to:
1094 * 1. vddd provided by external or not
1095 * 2. vdda and vddio voltage value. > 3.1v or not
1096 * 3. chip revision >=0x11 or not. If >=0x11, not use external vddd.
1097 */
1098static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
1099{
1100 int vddd;
1101 int vdda;
1102 int vddio;
1103 u16 ana_pwr;
1104 u16 lreg_ctrl;
1105 int vag;
1106 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1107
1108 vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
1109 vddio = regulator_get_voltage(sgtl5000->supplies[VDDIO].consumer);
1110 vddd = regulator_get_voltage(sgtl5000->supplies[VDDD].consumer);
1111
1112 vdda = vdda / 1000;
1113 vddio = vddio / 1000;
1114 vddd = vddd / 1000;
1115
1116 if (vdda <= 0 || vddio <= 0 || vddd < 0) {
1117 dev_err(codec->dev, "regulator voltage not set correctly\n");
1118
1119 return -EINVAL;
1120 }
1121
1122 /* according to datasheet, maximum voltage of supplies */
1123 if (vdda > 3600 || vddio > 3600 || vddd > 1980) {
1124 dev_err(codec->dev,
1125 "exceed max voltage vdda %dmv vddio %dma vddd %dma\n",
1126 vdda, vddio, vddd);
1127
1128 return -EINVAL;
1129 }
1130
1131 /* reset value */
1132 ana_pwr = snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER);
1133 ana_pwr |= SGTL5000_DAC_STEREO |
1134 SGTL5000_ADC_STEREO |
1135 SGTL5000_REFTOP_POWERUP;
1136 lreg_ctrl = snd_soc_read(codec, SGTL5000_CHIP_LINREG_CTRL);
1137
1138 if (vddio < 3100 && vdda < 3100) {
1139 /* enable internal oscillator used for charge pump */
1140 snd_soc_update_bits(codec, SGTL5000_CHIP_CLK_TOP_CTRL,
1141 SGTL5000_INT_OSC_EN,
1142 SGTL5000_INT_OSC_EN);
1143 /* Enable VDDC charge pump */
1144 ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
1145 } else if (vddio >= 3100 && vdda >= 3100) {
1146 /*
1147 * if vddio and vddd > 3.1v,
1148 * charge pump should be clean before set ana_pwr
1149 */
1150 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1151 SGTL5000_VDDC_CHRGPMP_POWERUP, 0);
1152
1153 /* VDDC use VDDIO rail */
1154 lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
1155 lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
1156 SGTL5000_VDDC_MAN_ASSN_SHIFT;
1157 }
1158
1159 snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
1160
1161 snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr);
1162
1163 /* set voltage to register */
1164 snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL,
1165 (0x1 << 4) - 1, 0x8);
1166
1167 /*
1168 * if vddd linear reg has been enabled,
1169 * simple digital supply should be clear to get
1170 * proper VDDD voltage.
1171 */
1172 if (ana_pwr & SGTL5000_LINEREG_D_POWERUP)
1173 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1174 SGTL5000_LINREG_SIMPLE_POWERUP,
1175 0);
1176 else
1177 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
1178 SGTL5000_LINREG_SIMPLE_POWERUP |
1179 SGTL5000_STARTUP_POWERUP,
1180 0);
1181
1182 /*
1183 * set ADC/DAC VAG to vdda / 2,
1184 * should stay in range (0.8v, 1.575v)
1185 */
1186 vag = vdda / 2;
1187 if (vag <= SGTL5000_ANA_GND_BASE)
1188 vag = 0;
1189 else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP *
1190 (SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT))
1191 vag = SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT;
1192 else
1193 vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP;
1194
1195 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1196 vag << SGTL5000_ANA_GND_SHIFT,
1197 vag << SGTL5000_ANA_GND_SHIFT);
1198
1199 /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
1200 vag = vddio / 2;
1201 if (vag <= SGTL5000_LINE_OUT_GND_BASE)
1202 vag = 0;
1203 else if (vag >= SGTL5000_LINE_OUT_GND_BASE +
1204 SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
1205 vag = SGTL5000_LINE_OUT_GND_MAX;
1206 else
1207 vag = (vag - SGTL5000_LINE_OUT_GND_BASE) /
1208 SGTL5000_LINE_OUT_GND_STP;
1209
1210 snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
1211 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1212 SGTL5000_LINE_OUT_CURRENT_360u <<
1213 SGTL5000_LINE_OUT_CURRENT_SHIFT,
1214 vag << SGTL5000_LINE_OUT_GND_SHIFT |
1215 SGTL5000_LINE_OUT_CURRENT_360u <<
1216 SGTL5000_LINE_OUT_CURRENT_SHIFT);
1217
1218 return 0;
1219}
1220
1221static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
1222{
1223 u16 reg;
1224 int ret;
1225 int rev;
1226 int i;
1227 int external_vddd = 0;
1228 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1229
1230 for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++)
1231 sgtl5000->supplies[i].supply = supply_names[i];
1232
1233 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
1234 sgtl5000->supplies);
1235 if (!ret)
1236 external_vddd = 1;
1237 else {
1238 /* set internal ldo to 1.2v */
1239 int voltage = LDO_VOLTAGE;
1240
1241 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1242 if (ret) {
1243 dev_err(codec->dev,
1244 "Failed to register vddd internal supplies: %d\n",
1245 ret);
1246 return ret;
1247 }
1248
1249 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1250
1251 ret = regulator_bulk_get(codec->dev,
1252 ARRAY_SIZE(sgtl5000->supplies),
1253 sgtl5000->supplies);
1254
1255 if (ret) {
1256 ldo_regulator_remove(codec);
1257 dev_err(codec->dev,
1258 "Failed to request supplies: %d\n", ret);
1259
1260 return ret;
1261 }
1262 }
1263
1264 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1265 sgtl5000->supplies);
1266 if (ret)
1267 goto err_regulator_free;
1268
1269 /* wait for all power rails bring up */
1270 udelay(10);
1271
1272 /* read chip information */
1273 reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
1274 if (((reg & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) !=
1275 SGTL5000_PARTID_PART_ID) {
1276 dev_err(codec->dev,
1277 "Device with ID register %x is not a sgtl5000\n", reg);
1278 ret = -ENODEV;
1279 goto err_regulator_disable;
1280 }
1281
1282 rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
1283 dev_info(codec->dev, "sgtl5000 revision %d\n", rev);
1284
1285 /*
1286 * workaround for revision 0x11 and later,
1287 * roll back to use internal LDO
1288 */
1289 if (external_vddd && rev >= 0x11) {
1290 int voltage = LDO_VOLTAGE;
1291 /* disable all regulator first */
1292 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1293 sgtl5000->supplies);
1294 /* free VDDD regulator */
1295 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1296 sgtl5000->supplies);
1297
1298 ret = ldo_regulator_register(codec, &ldo_init_data, voltage);
1299 if (ret)
1300 return ret;
1301
1302 sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME;
1303
1304 ret = regulator_bulk_get(codec->dev,
1305 ARRAY_SIZE(sgtl5000->supplies),
1306 sgtl5000->supplies);
1307 if (ret) {
1308 ldo_regulator_remove(codec);
1309 dev_err(codec->dev,
1310 "Failed to request supplies: %d\n", ret);
1311
1312 return ret;
1313 }
1314
1315 ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
1316 sgtl5000->supplies);
1317 if (ret)
1318 goto err_regulator_free;
1319
1320 /* wait for all power rails bring up */
1321 udelay(10);
1322 }
1323
1324 return 0;
1325
1326err_regulator_disable:
1327 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1328 sgtl5000->supplies);
1329err_regulator_free:
1330 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1331 sgtl5000->supplies);
1332 if (external_vddd)
1333 ldo_regulator_remove(codec);
1334 return ret;
1335
1336}
1337
1338static int sgtl5000_probe(struct snd_soc_codec *codec)
1339{
1340 int ret;
1341 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1342
1343 /* setup i2c data ops */
1344 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
1345 if (ret < 0) {
1346 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1347 return ret;
1348 }
1349
1350 ret = sgtl5000_enable_regulators(codec);
1351 if (ret)
1352 return ret;
1353
1354 /* power up sgtl5000 */
1355 ret = sgtl5000_set_power_regs(codec);
1356 if (ret)
1357 goto err;
1358
1359 /* enable small pop, introduce 400ms delay in turning off */
1360 snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL,
1361 SGTL5000_SMALL_POP,
1362 SGTL5000_SMALL_POP);
1363
1364 /* disable short cut detector */
1365 snd_soc_write(codec, SGTL5000_CHIP_SHORT_CTRL, 0);
1366
1367 /*
1368 * set i2s as default input of sound switch
1369 * TODO: add sound switch to control and dapm widge.
1370 */
1371 snd_soc_write(codec, SGTL5000_CHIP_SSS_CTRL,
1372 SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT);
1373 snd_soc_write(codec, SGTL5000_CHIP_DIG_POWER,
1374 SGTL5000_ADC_EN | SGTL5000_DAC_EN);
1375
1376 /* enable dac volume ramp by default */
1377 snd_soc_write(codec, SGTL5000_CHIP_ADCDAC_CTRL,
1378 SGTL5000_DAC_VOL_RAMP_EN |
1379 SGTL5000_DAC_MUTE_RIGHT |
1380 SGTL5000_DAC_MUTE_LEFT);
1381
1382 snd_soc_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f);
1383
1384 snd_soc_write(codec, SGTL5000_CHIP_ANA_CTRL,
1385 SGTL5000_HP_ZCD_EN |
1386 SGTL5000_ADC_ZCD_EN);
1387
1388 snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, 0);
1389
1390 /*
1391 * disable DAP
1392 * TODO:
1393 * Enable DAP in kcontrol and dapm.
1394 */
1395 snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
1396
1397 /* leading to standby state */
1398 ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1399 if (ret)
1400 goto err;
1401
1402 snd_soc_add_controls(codec, sgtl5000_snd_controls,
1403 ARRAY_SIZE(sgtl5000_snd_controls));
1404
1405 snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
1406 ARRAY_SIZE(sgtl5000_dapm_widgets));
1407
1408 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1409 ARRAY_SIZE(audio_map));
1410
1411 snd_soc_dapm_new_widgets(&codec->dapm);
1412
1413 return 0;
1414
1415err:
1416 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1417 sgtl5000->supplies);
1418 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1419 sgtl5000->supplies);
1420 ldo_regulator_remove(codec);
1421
1422 return ret;
1423}
1424
1425static int sgtl5000_remove(struct snd_soc_codec *codec)
1426{
1427 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
1428
1429 sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
1430
1431 regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
1432 sgtl5000->supplies);
1433 regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
1434 sgtl5000->supplies);
1435 ldo_regulator_remove(codec);
1436
1437 return 0;
1438}
1439
1440static struct snd_soc_codec_driver sgtl5000_driver = {
1441 .probe = sgtl5000_probe,
1442 .remove = sgtl5000_remove,
1443 .suspend = sgtl5000_suspend,
1444 .resume = sgtl5000_resume,
1445 .set_bias_level = sgtl5000_set_bias_level,
1446 .reg_cache_size = ARRAY_SIZE(sgtl5000_regs),
1447 .reg_word_size = sizeof(u16),
1448 .reg_cache_step = 2,
1449 .reg_cache_default = sgtl5000_regs,
1450 .volatile_register = sgtl5000_volatile_register,
1451};
1452
1453static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
1454 const struct i2c_device_id *id)
1455{
1456 struct sgtl5000_priv *sgtl5000;
1457 int ret;
1458
1459 sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL);
1460 if (!sgtl5000)
1461 return -ENOMEM;
1462
1463 /*
1464 * copy DAP default values to default value array.
1465 * sgtl5000 register space has a big hole, merge it
1466 * at init phase makes life easy.
1467 * FIXME: should we drop 'const' of sgtl5000_regs?
1468 */
1469 memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)),
1470 sgtl5000_dap_regs,
1471 SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET);
1472
1473 i2c_set_clientdata(client, sgtl5000);
1474
1475 ret = snd_soc_register_codec(&client->dev,
1476 &sgtl5000_driver, &sgtl5000_dai, 1);
1477 if (ret) {
1478 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1479 kfree(sgtl5000);
1480 return ret;
1481 }
1482
1483 return 0;
1484}
1485
1486static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
1487{
1488 struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
1489
1490 snd_soc_unregister_codec(&client->dev);
1491
1492 kfree(sgtl5000);
1493 return 0;
1494}
1495
1496static const struct i2c_device_id sgtl5000_id[] = {
1497 {"sgtl5000", 0},
1498 {},
1499};
1500
1501MODULE_DEVICE_TABLE(i2c, sgtl5000_id);
1502
1503static struct i2c_driver sgtl5000_i2c_driver = {
1504 .driver = {
1505 .name = "sgtl5000",
1506 .owner = THIS_MODULE,
1507 },
1508 .probe = sgtl5000_i2c_probe,
1509 .remove = __devexit_p(sgtl5000_i2c_remove),
1510 .id_table = sgtl5000_id,
1511};
1512
1513static int __init sgtl5000_modinit(void)
1514{
1515 return i2c_add_driver(&sgtl5000_i2c_driver);
1516}
1517module_init(sgtl5000_modinit);
1518
1519static void __exit sgtl5000_exit(void)
1520{
1521 i2c_del_driver(&sgtl5000_i2c_driver);
1522}
1523module_exit(sgtl5000_exit);
1524
1525MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
1526MODULE_AUTHOR("Zeng Zhaoming <zhaoming.zeng@freescale.com>");
1527MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h
new file mode 100644
index 000000000000..eec3ab368f39
--- /dev/null
+++ b/sound/soc/codecs/sgtl5000.h
@@ -0,0 +1,400 @@
1/*
2 * sgtl5000.h - SGTL5000 audio codec interface
3 *
4 * Copyright 2010-2011 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _SGTL5000_H
12#define _SGTL5000_H
13
14/*
15 * Register values.
16 */
17#define SGTL5000_CHIP_ID 0x0000
18#define SGTL5000_CHIP_DIG_POWER 0x0002
19#define SGTL5000_CHIP_CLK_CTRL 0x0004
20#define SGTL5000_CHIP_I2S_CTRL 0x0006
21#define SGTL5000_CHIP_SSS_CTRL 0x000a
22#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e
23#define SGTL5000_CHIP_DAC_VOL 0x0010
24#define SGTL5000_CHIP_PAD_STRENGTH 0x0014
25#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020
26#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022
27#define SGTL5000_CHIP_ANA_CTRL 0x0024
28#define SGTL5000_CHIP_LINREG_CTRL 0x0026
29#define SGTL5000_CHIP_REF_CTRL 0x0028
30#define SGTL5000_CHIP_MIC_CTRL 0x002a
31#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c
32#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e
33#define SGTL5000_CHIP_ANA_POWER 0x0030
34#define SGTL5000_CHIP_PLL_CTRL 0x0032
35#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034
36#define SGTL5000_CHIP_ANA_STATUS 0x0036
37#define SGTL5000_CHIP_SHORT_CTRL 0x003c
38#define SGTL5000_CHIP_ANA_TEST2 0x003a
39#define SGTL5000_DAP_CTRL 0x0100
40#define SGTL5000_DAP_PEQ 0x0102
41#define SGTL5000_DAP_BASS_ENHANCE 0x0104
42#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106
43#define SGTL5000_DAP_AUDIO_EQ 0x0108
44#define SGTL5000_DAP_SURROUND 0x010a
45#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c
46#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e
47#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110
48#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116
49#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118
50#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a
51#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c
52#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e
53#define SGTL5000_DAP_MAIN_CHAN 0x0120
54#define SGTL5000_DAP_MIX_CHAN 0x0122
55#define SGTL5000_DAP_AVC_CTRL 0x0124
56#define SGTL5000_DAP_AVC_THRESHOLD 0x0126
57#define SGTL5000_DAP_AVC_ATTACK 0x0128
58#define SGTL5000_DAP_AVC_DECAY 0x012a
59#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c
60#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e
61#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130
62#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132
63#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134
64#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136
65#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138
66#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a
67
68/*
69 * Field Definitions.
70 */
71
72/*
73 * SGTL5000_CHIP_ID
74 */
75#define SGTL5000_PARTID_MASK 0xff00
76#define SGTL5000_PARTID_SHIFT 8
77#define SGTL5000_PARTID_WIDTH 8
78#define SGTL5000_PARTID_PART_ID 0xa0
79#define SGTL5000_REVID_MASK 0x00ff
80#define SGTL5000_REVID_SHIFT 0
81#define SGTL5000_REVID_WIDTH 8
82
83/*
84 * SGTL5000_CHIP_DIG_POWER
85 */
86#define SGTL5000_ADC_EN 0x0040
87#define SGTL5000_DAC_EN 0x0020
88#define SGTL5000_DAP_POWERUP 0x0010
89#define SGTL5000_I2S_OUT_POWERUP 0x0002
90#define SGTL5000_I2S_IN_POWERUP 0x0001
91
92/*
93 * SGTL5000_CHIP_CLK_CTRL
94 */
95#define SGTL5000_RATE_MODE_MASK 0x0030
96#define SGTL5000_RATE_MODE_SHIFT 4
97#define SGTL5000_RATE_MODE_WIDTH 2
98#define SGTL5000_RATE_MODE_DIV_1 0
99#define SGTL5000_RATE_MODE_DIV_2 1
100#define SGTL5000_RATE_MODE_DIV_4 2
101#define SGTL5000_RATE_MODE_DIV_6 3
102#define SGTL5000_SYS_FS_MASK 0x000c
103#define SGTL5000_SYS_FS_SHIFT 2
104#define SGTL5000_SYS_FS_WIDTH 2
105#define SGTL5000_SYS_FS_32k 0x0
106#define SGTL5000_SYS_FS_44_1k 0x1
107#define SGTL5000_SYS_FS_48k 0x2
108#define SGTL5000_SYS_FS_96k 0x3
109#define SGTL5000_MCLK_FREQ_MASK 0x0003
110#define SGTL5000_MCLK_FREQ_SHIFT 0
111#define SGTL5000_MCLK_FREQ_WIDTH 2
112#define SGTL5000_MCLK_FREQ_256FS 0x0
113#define SGTL5000_MCLK_FREQ_384FS 0x1
114#define SGTL5000_MCLK_FREQ_512FS 0x2
115#define SGTL5000_MCLK_FREQ_PLL 0x3
116
117/*
118 * SGTL5000_CHIP_I2S_CTRL
119 */
120#define SGTL5000_I2S_SCLKFREQ_MASK 0x0100
121#define SGTL5000_I2S_SCLKFREQ_SHIFT 8
122#define SGTL5000_I2S_SCLKFREQ_WIDTH 1
123#define SGTL5000_I2S_SCLKFREQ_64FS 0x0
124#define SGTL5000_I2S_SCLKFREQ_32FS 0x1 /* Not for RJ mode */
125#define SGTL5000_I2S_MASTER 0x0080
126#define SGTL5000_I2S_SCLK_INV 0x0040
127#define SGTL5000_I2S_DLEN_MASK 0x0030
128#define SGTL5000_I2S_DLEN_SHIFT 4
129#define SGTL5000_I2S_DLEN_WIDTH 2
130#define SGTL5000_I2S_DLEN_32 0x0
131#define SGTL5000_I2S_DLEN_24 0x1
132#define SGTL5000_I2S_DLEN_20 0x2
133#define SGTL5000_I2S_DLEN_16 0x3
134#define SGTL5000_I2S_MODE_MASK 0x000c
135#define SGTL5000_I2S_MODE_SHIFT 2
136#define SGTL5000_I2S_MODE_WIDTH 2
137#define SGTL5000_I2S_MODE_I2S_LJ 0x0
138#define SGTL5000_I2S_MODE_RJ 0x1
139#define SGTL5000_I2S_MODE_PCM 0x2
140#define SGTL5000_I2S_LRALIGN 0x0002
141#define SGTL5000_I2S_LRPOL 0x0001 /* set for which mode */
142
143/*
144 * SGTL5000_CHIP_SSS_CTRL
145 */
146#define SGTL5000_DAP_MIX_LRSWAP 0x4000
147#define SGTL5000_DAP_LRSWAP 0x2000
148#define SGTL5000_DAC_LRSWAP 0x1000
149#define SGTL5000_I2S_OUT_LRSWAP 0x0400
150#define SGTL5000_DAP_MIX_SEL_MASK 0x0300
151#define SGTL5000_DAP_MIX_SEL_SHIFT 8
152#define SGTL5000_DAP_MIX_SEL_WIDTH 2
153#define SGTL5000_DAP_MIX_SEL_ADC 0x0
154#define SGTL5000_DAP_MIX_SEL_I2S_IN 0x1
155#define SGTL5000_DAP_SEL_MASK 0x00c0
156#define SGTL5000_DAP_SEL_SHIFT 6
157#define SGTL5000_DAP_SEL_WIDTH 2
158#define SGTL5000_DAP_SEL_ADC 0x0
159#define SGTL5000_DAP_SEL_I2S_IN 0x1
160#define SGTL5000_DAC_SEL_MASK 0x0030
161#define SGTL5000_DAC_SEL_SHIFT 4
162#define SGTL5000_DAC_SEL_WIDTH 2
163#define SGTL5000_DAC_SEL_ADC 0x0
164#define SGTL5000_DAC_SEL_I2S_IN 0x1
165#define SGTL5000_DAC_SEL_DAP 0x3
166#define SGTL5000_I2S_OUT_SEL_MASK 0x0003
167#define SGTL5000_I2S_OUT_SEL_SHIFT 0
168#define SGTL5000_I2S_OUT_SEL_WIDTH 2
169#define SGTL5000_I2S_OUT_SEL_ADC 0x0
170#define SGTL5000_I2S_OUT_SEL_I2S_IN 0x1
171#define SGTL5000_I2S_OUT_SEL_DAP 0x3
172
173/*
174 * SGTL5000_CHIP_ADCDAC_CTRL
175 */
176#define SGTL5000_VOL_BUSY_DAC_RIGHT 0x2000
177#define SGTL5000_VOL_BUSY_DAC_LEFT 0x1000
178#define SGTL5000_DAC_VOL_RAMP_EN 0x0200
179#define SGTL5000_DAC_VOL_RAMP_EXPO 0x0100
180#define SGTL5000_DAC_MUTE_RIGHT 0x0008
181#define SGTL5000_DAC_MUTE_LEFT 0x0004
182#define SGTL5000_ADC_HPF_FREEZE 0x0002
183#define SGTL5000_ADC_HPF_BYPASS 0x0001
184
185/*
186 * SGTL5000_CHIP_DAC_VOL
187 */
188#define SGTL5000_DAC_VOL_RIGHT_MASK 0xff00
189#define SGTL5000_DAC_VOL_RIGHT_SHIFT 8
190#define SGTL5000_DAC_VOL_RIGHT_WIDTH 8
191#define SGTL5000_DAC_VOL_LEFT_MASK 0x00ff
192#define SGTL5000_DAC_VOL_LEFT_SHIFT 0
193#define SGTL5000_DAC_VOL_LEFT_WIDTH 8
194
195/*
196 * SGTL5000_CHIP_PAD_STRENGTH
197 */
198#define SGTL5000_PAD_I2S_LRCLK_MASK 0x0300
199#define SGTL5000_PAD_I2S_LRCLK_SHIFT 8
200#define SGTL5000_PAD_I2S_LRCLK_WIDTH 2
201#define SGTL5000_PAD_I2S_SCLK_MASK 0x00c0
202#define SGTL5000_PAD_I2S_SCLK_SHIFT 6
203#define SGTL5000_PAD_I2S_SCLK_WIDTH 2
204#define SGTL5000_PAD_I2S_DOUT_MASK 0x0030
205#define SGTL5000_PAD_I2S_DOUT_SHIFT 4
206#define SGTL5000_PAD_I2S_DOUT_WIDTH 2
207#define SGTL5000_PAD_I2C_SDA_MASK 0x000c
208#define SGTL5000_PAD_I2C_SDA_SHIFT 2
209#define SGTL5000_PAD_I2C_SDA_WIDTH 2
210#define SGTL5000_PAD_I2C_SCL_MASK 0x0003
211#define SGTL5000_PAD_I2C_SCL_SHIFT 0
212#define SGTL5000_PAD_I2C_SCL_WIDTH 2
213
214/*
215 * SGTL5000_CHIP_ANA_ADC_CTRL
216 */
217#define SGTL5000_ADC_VOL_M6DB 0x0100
218#define SGTL5000_ADC_VOL_RIGHT_MASK 0x00f0
219#define SGTL5000_ADC_VOL_RIGHT_SHIFT 4
220#define SGTL5000_ADC_VOL_RIGHT_WIDTH 4
221#define SGTL5000_ADC_VOL_LEFT_MASK 0x000f
222#define SGTL5000_ADC_VOL_LEFT_SHIFT 0
223#define SGTL5000_ADC_VOL_LEFT_WIDTH 4
224
225/*
226 * SGTL5000_CHIP_ANA_HP_CTRL
227 */
228#define SGTL5000_HP_VOL_RIGHT_MASK 0x7f00
229#define SGTL5000_HP_VOL_RIGHT_SHIFT 8
230#define SGTL5000_HP_VOL_RIGHT_WIDTH 7
231#define SGTL5000_HP_VOL_LEFT_MASK 0x007f
232#define SGTL5000_HP_VOL_LEFT_SHIFT 0
233#define SGTL5000_HP_VOL_LEFT_WIDTH 7
234
235/*
236 * SGTL5000_CHIP_ANA_CTRL
237 */
238#define SGTL5000_LINE_OUT_MUTE 0x0100
239#define SGTL5000_HP_SEL_MASK 0x0040
240#define SGTL5000_HP_SEL_SHIFT 6
241#define SGTL5000_HP_SEL_WIDTH 1
242#define SGTL5000_HP_SEL_DAC 0x0
243#define SGTL5000_HP_SEL_LINE_IN 0x1
244#define SGTL5000_HP_ZCD_EN 0x0020
245#define SGTL5000_HP_MUTE 0x0010
246#define SGTL5000_ADC_SEL_MASK 0x0004
247#define SGTL5000_ADC_SEL_SHIFT 2
248#define SGTL5000_ADC_SEL_WIDTH 1
249#define SGTL5000_ADC_SEL_MIC 0x0
250#define SGTL5000_ADC_SEL_LINE_IN 0x1
251#define SGTL5000_ADC_ZCD_EN 0x0002
252#define SGTL5000_ADC_MUTE 0x0001
253
254/*
255 * SGTL5000_CHIP_LINREG_CTRL
256 */
257#define SGTL5000_VDDC_MAN_ASSN_MASK 0x0040
258#define SGTL5000_VDDC_MAN_ASSN_SHIFT 6
259#define SGTL5000_VDDC_MAN_ASSN_WIDTH 1
260#define SGTL5000_VDDC_MAN_ASSN_VDDA 0x0
261#define SGTL5000_VDDC_MAN_ASSN_VDDIO 0x1
262#define SGTL5000_VDDC_ASSN_OVRD 0x0020
263#define SGTL5000_LINREG_VDDD_MASK 0x000f
264#define SGTL5000_LINREG_VDDD_SHIFT 0
265#define SGTL5000_LINREG_VDDD_WIDTH 4
266
267/*
268 * SGTL5000_CHIP_REF_CTRL
269 */
270#define SGTL5000_ANA_GND_MASK 0x01f0
271#define SGTL5000_ANA_GND_SHIFT 4
272#define SGTL5000_ANA_GND_WIDTH 5
273#define SGTL5000_ANA_GND_BASE 800 /* mv */
274#define SGTL5000_ANA_GND_STP 25 /*mv */
275#define SGTL5000_BIAS_CTRL_MASK 0x000e
276#define SGTL5000_BIAS_CTRL_SHIFT 1
277#define SGTL5000_BIAS_CTRL_WIDTH 3
278#define SGTL5000_SMALL_POP 0x0001
279
280/*
281 * SGTL5000_CHIP_MIC_CTRL
282 */
283#define SGTL5000_BIAS_R_MASK 0x0200
284#define SGTL5000_BIAS_R_SHIFT 8
285#define SGTL5000_BIAS_R_WIDTH 2
286#define SGTL5000_BIAS_R_off 0x0
287#define SGTL5000_BIAS_R_2K 0x1
288#define SGTL5000_BIAS_R_4k 0x2
289#define SGTL5000_BIAS_R_8k 0x3
290#define SGTL5000_BIAS_VOLT_MASK 0x0070
291#define SGTL5000_BIAS_VOLT_SHIFT 4
292#define SGTL5000_BIAS_VOLT_WIDTH 3
293#define SGTL5000_MIC_GAIN_MASK 0x0003
294#define SGTL5000_MIC_GAIN_SHIFT 0
295#define SGTL5000_MIC_GAIN_WIDTH 2
296
297/*
298 * SGTL5000_CHIP_LINE_OUT_CTRL
299 */
300#define SGTL5000_LINE_OUT_CURRENT_MASK 0x0f00
301#define SGTL5000_LINE_OUT_CURRENT_SHIFT 8
302#define SGTL5000_LINE_OUT_CURRENT_WIDTH 4
303#define SGTL5000_LINE_OUT_CURRENT_180u 0x0
304#define SGTL5000_LINE_OUT_CURRENT_270u 0x1
305#define SGTL5000_LINE_OUT_CURRENT_360u 0x3
306#define SGTL5000_LINE_OUT_CURRENT_450u 0x7
307#define SGTL5000_LINE_OUT_CURRENT_540u 0xf
308#define SGTL5000_LINE_OUT_GND_MASK 0x003f
309#define SGTL5000_LINE_OUT_GND_SHIFT 0
310#define SGTL5000_LINE_OUT_GND_WIDTH 6
311#define SGTL5000_LINE_OUT_GND_BASE 800 /* mv */
312#define SGTL5000_LINE_OUT_GND_STP 25
313#define SGTL5000_LINE_OUT_GND_MAX 0x23
314
315/*
316 * SGTL5000_CHIP_LINE_OUT_VOL
317 */
318#define SGTL5000_LINE_OUT_VOL_RIGHT_MASK 0x1f00
319#define SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT 8
320#define SGTL5000_LINE_OUT_VOL_RIGHT_WIDTH 5
321#define SGTL5000_LINE_OUT_VOL_LEFT_MASK 0x001f
322#define SGTL5000_LINE_OUT_VOL_LEFT_SHIFT 0
323#define SGTL5000_LINE_OUT_VOL_LEFT_WIDTH 5
324
325/*
326 * SGTL5000_CHIP_ANA_POWER
327 */
328#define SGTL5000_DAC_STEREO 0x4000
329#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000
330#define SGTL5000_STARTUP_POWERUP 0x1000
331#define SGTL5000_VDDC_CHRGPMP_POWERUP 0x0800
332#define SGTL5000_PLL_POWERUP 0x0400
333#define SGTL5000_LINEREG_D_POWERUP 0x0200
334#define SGTL5000_VCOAMP_POWERUP 0x0100
335#define SGTL5000_VAG_POWERUP 0x0080
336#define SGTL5000_ADC_STEREO 0x0040
337#define SGTL5000_REFTOP_POWERUP 0x0020
338#define SGTL5000_HP_POWERUP 0x0010
339#define SGTL5000_DAC_POWERUP 0x0008
340#define SGTL5000_CAPLESS_HP_POWERUP 0x0004
341#define SGTL5000_ADC_POWERUP 0x0002
342#define SGTL5000_LINE_OUT_POWERUP 0x0001
343
344/*
345 * SGTL5000_CHIP_PLL_CTRL
346 */
347#define SGTL5000_PLL_INT_DIV_MASK 0xf800
348#define SGTL5000_PLL_INT_DIV_SHIFT 11
349#define SGTL5000_PLL_INT_DIV_WIDTH 5
350#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700
351#define SGTL5000_PLL_FRAC_DIV_SHIFT 0
352#define SGTL5000_PLL_FRAC_DIV_WIDTH 11
353
354/*
355 * SGTL5000_CHIP_CLK_TOP_CTRL
356 */
357#define SGTL5000_INT_OSC_EN 0x0800
358#define SGTL5000_INPUT_FREQ_DIV2 0x0008
359
360/*
361 * SGTL5000_CHIP_ANA_STATUS
362 */
363#define SGTL5000_HP_LRSHORT 0x0200
364#define SGTL5000_CAPLESS_SHORT 0x0100
365#define SGTL5000_PLL_LOCKED 0x0010
366
367/*
368 * SGTL5000_CHIP_SHORT_CTRL
369 */
370#define SGTL5000_LVLADJR_MASK 0x7000
371#define SGTL5000_LVLADJR_SHIFT 12
372#define SGTL5000_LVLADJR_WIDTH 3
373#define SGTL5000_LVLADJL_MASK 0x0700
374#define SGTL5000_LVLADJL_SHIFT 8
375#define SGTL5000_LVLADJL_WIDTH 3
376#define SGTL5000_LVLADJC_MASK 0x0070
377#define SGTL5000_LVLADJC_SHIFT 4
378#define SGTL5000_LVLADJC_WIDTH 3
379#define SGTL5000_LR_SHORT_MOD_MASK 0x000c
380#define SGTL5000_LR_SHORT_MOD_SHIFT 2
381#define SGTL5000_LR_SHORT_MOD_WIDTH 2
382#define SGTL5000_CM_SHORT_MOD_MASK 0x0003
383#define SGTL5000_CM_SHORT_MOD_SHIFT 0
384#define SGTL5000_CM_SHORT_MOD_WIDTH 2
385
386/*
387 *SGTL5000_CHIP_ANA_TEST2
388 */
389#define SGTL5000_MONO_DAC 0x1000
390
391/*
392 * SGTL5000_DAP_CTRL
393 */
394#define SGTL5000_DAP_MIX_EN 0x0010
395#define SGTL5000_DAP_EN 0x0001
396
397#define SGTL5000_SYSCLK 0x00
398#define SGTL5000_LRCLK 0x01
399
400#endif
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
new file mode 100644
index 000000000000..84ffdebb8a8b
--- /dev/null
+++ b/sound/soc/codecs/sn95031.c
@@ -0,0 +1,944 @@
1/*
2 * sn95031.c - TI sn95031 Codec driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
27
28#include <linux/platform_device.h>
29#include <linux/delay.h>
30#include <linux/slab.h>
31
32#include <asm/intel_scu_ipc.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/initval.h>
38#include <sound/tlv.h>
39#include <sound/jack.h>
40#include "sn95031.h"
41
42#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
43#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
44
45/* adc helper functions */
46
47/* enables mic bias voltage */
48static void sn95031_enable_mic_bias(struct snd_soc_codec *codec)
49{
50 snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0));
51 snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2));
52}
53
54/* Enable/Disable the ADC depending on the argument */
55static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
56{
57 int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
58
59 if (val) {
60 /* Enable and start the ADC */
61 value |= (SN95031_ADC_ENBL | SN95031_ADC_START);
62 value &= (~SN95031_ADC_NO_LOOP);
63 } else {
64 /* Just stop the ADC */
65 value &= (~SN95031_ADC_START);
66 }
67 snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value);
68}
69
70/*
71 * finds an empty channel for conversion
72 * If the ADC is not enabled then start using 0th channel
73 * itself. Otherwise find an empty channel by looking for a
74 * channel in which the stopbit is set to 1. returns the index
75 * of the first free channel if succeeds or an error code.
76 *
77 * Context: can sleep
78 *
79 */
80static int find_free_channel(struct snd_soc_codec *sn95031_codec)
81{
82 int ret = 0, i, value;
83
84 /* check whether ADC is enabled */
85 value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
86
87 if ((value & SN95031_ADC_ENBL) == 0)
88 return 0;
89
90 /* ADC is already enabled; Looking for an empty channel */
91 for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
92 value = snd_soc_read(sn95031_codec,
93 SN95031_ADC_CHNL_START_ADDR + i);
94 if (value & SN95031_STOPBIT_MASK) {
95 ret = i;
96 break;
97 }
98 }
99 return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret;
100}
101
102/* Initialize the ADC for reading micbias values. Can sleep. */
103static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
104{
105 int base_addr, chnl_addr;
106 int value;
107 static int channel_index;
108
109 /* Index of the first channel in which the stop bit is set */
110 channel_index = find_free_channel(sn95031_codec);
111 if (channel_index < 0) {
112 pr_err("No free ADC channels");
113 return channel_index;
114 }
115
116 base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index;
117
118 if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) {
119 /* Reset stop bit for channels other than 0 and 12 */
120 value = snd_soc_read(sn95031_codec, base_addr);
121 /* Set the stop bit to zero */
122 snd_soc_write(sn95031_codec, base_addr, value & 0xEF);
123 /* Index of the first free channel */
124 base_addr++;
125 channel_index++;
126 }
127
128 /* Since this is the last channel, set the stop bit
129 to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
130 snd_soc_write(sn95031_codec, base_addr,
131 SN95031_AUDIO_DETECT_CODE | 0x10);
132
133 chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index;
134 pr_debug("mid_initialize : %x", chnl_addr);
135 configure_adc(sn95031_codec, 1);
136 return chnl_addr;
137}
138
139
140/* reads the ADC registers and gets the mic bias value in mV. */
141static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
142{
143 u16 adc_adr = sn95031_initialize_adc(codec);
144 u16 adc_val1, adc_val2;
145 unsigned int mic_bias;
146
147 sn95031_enable_mic_bias(codec);
148
149 /* Enable the sound card for conversion before reading */
150 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05);
151 /* Re-toggle the RRDATARD bit */
152 snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04);
153
154 /* Read the higher bits of data */
155 msleep(1000);
156 adc_val1 = snd_soc_read(codec, adc_adr);
157 adc_adr++;
158 adc_val2 = snd_soc_read(codec, adc_adr);
159
160 /* Adding lower two bits to the higher bits */
161 mic_bias = (adc_val1 << 2) + (adc_val2 & 3);
162 mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000;
163 pr_debug("mic bias = %dmV\n", mic_bias);
164 return mic_bias;
165}
166EXPORT_SYMBOL_GPL(sn95031_get_mic_bias);
167/*end - adc helper functions */
168
169static inline unsigned int sn95031_read(struct snd_soc_codec *codec,
170 unsigned int reg)
171{
172 u8 value = 0;
173 int ret;
174
175 ret = intel_scu_ipc_ioread8(reg, &value);
176 if (ret)
177 pr_err("read of %x failed, err %d\n", reg, ret);
178 return value;
179
180}
181
182static inline int sn95031_write(struct snd_soc_codec *codec,
183 unsigned int reg, unsigned int value)
184{
185 int ret;
186
187 ret = intel_scu_ipc_iowrite8(reg, value);
188 if (ret)
189 pr_err("write of %x failed, err %d\n", reg, ret);
190 return ret;
191}
192
193static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
194 enum snd_soc_bias_level level)
195{
196 switch (level) {
197 case SND_SOC_BIAS_ON:
198 break;
199
200 case SND_SOC_BIAS_PREPARE:
201 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
202 pr_debug("vaud_bias powering up pll\n");
203 /* power up the pll */
204 snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
205 /* enable pcm 2 */
206 snd_soc_update_bits(codec, SN95031_PCM2C2,
207 BIT(0), BIT(0));
208 }
209 break;
210
211 case SND_SOC_BIAS_STANDBY:
212 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
213 pr_debug("vaud_bias power up rail\n");
214 /* power up the rail */
215 snd_soc_write(codec, SN95031_VAUD,
216 BIT(2)|BIT(1)|BIT(0));
217 msleep(1);
218 } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
219 /* turn off pcm */
220 pr_debug("vaud_bias power dn pcm\n");
221 snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
222 snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
223 }
224 break;
225
226
227 case SND_SOC_BIAS_OFF:
228 pr_debug("vaud_bias _OFF doing rail shutdown\n");
229 snd_soc_write(codec, SN95031_VAUD, BIT(3));
230 break;
231 }
232
233 codec->dapm.bias_level = level;
234 return 0;
235}
236
237static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
238 struct snd_kcontrol *kcontrol, int event)
239{
240 if (SND_SOC_DAPM_EVENT_ON(event)) {
241 pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
242 /* power up the rail */
243 snd_soc_write(w->codec, SN95031_VHSP, 0x3D);
244 snd_soc_write(w->codec, SN95031_VHSN, 0x3F);
245 msleep(1);
246 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
247 pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
248 snd_soc_write(w->codec, SN95031_VHSP, 0xC4);
249 snd_soc_write(w->codec, SN95031_VHSN, 0x04);
250 }
251 return 0;
252}
253
254static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event)
256{
257 if (SND_SOC_DAPM_EVENT_ON(event)) {
258 pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
259 /* power up the rail */
260 snd_soc_write(w->codec, SN95031_VIHF, 0x27);
261 msleep(1);
262 } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
263 pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
264 snd_soc_write(w->codec, SN95031_VIHF, 0x24);
265 }
266 return 0;
267}
268
269static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
270 struct snd_kcontrol *k, int event)
271{
272 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
273
274 if (SND_SOC_DAPM_EVENT_ON(event)) {
275 ldo = BIT(5)|BIT(4);
276 clk_dir = BIT(0);
277 data_dir = BIT(7);
278 }
279 /* program DMIC LDO, clock and set clock */
280 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
281 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
282 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir);
283 return 0;
284}
285
286static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
287 struct snd_kcontrol *k, int event)
288{
289 unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
290
291 if (SND_SOC_DAPM_EVENT_ON(event)) {
292 ldo = BIT(5)|BIT(4);
293 clk_dir = BIT(2);
294 data_dir = BIT(1);
295 }
296 /* program DMIC LDO, clock and set clock */
297 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
298 snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
299 snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir);
300 return 0;
301}
302
303static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
304 struct snd_kcontrol *k, int event)
305{
306 unsigned int ldo = 0;
307
308 if (SND_SOC_DAPM_EVENT_ON(event))
309 ldo = BIT(7)|BIT(6);
310
311 /* program DMIC LDO */
312 snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
313 return 0;
314}
315
316/* mux controls */
317static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" };
318
319static const struct soc_enum sn95031_micl_enum =
320 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 1, 2, sn95031_mic_texts);
321
322static const struct snd_kcontrol_new sn95031_micl_mux_control =
323 SOC_DAPM_ENUM("Route", sn95031_micl_enum);
324
325static const struct soc_enum sn95031_micr_enum =
326 SOC_ENUM_SINGLE(SN95031_ADCCONFIG, 3, 2, sn95031_mic_texts);
327
328static const struct snd_kcontrol_new sn95031_micr_mux_control =
329 SOC_DAPM_ENUM("Route", sn95031_micr_enum);
330
331static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3",
332 "DMIC4", "DMIC5", "DMIC6",
333 "ADC Left", "ADC Right" };
334
335static const struct soc_enum sn95031_input1_enum =
336 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 0, 8, sn95031_input_texts);
337
338static const struct snd_kcontrol_new sn95031_input1_mux_control =
339 SOC_DAPM_ENUM("Route", sn95031_input1_enum);
340
341static const struct soc_enum sn95031_input2_enum =
342 SOC_ENUM_SINGLE(SN95031_AUDIOMUX12, 4, 8, sn95031_input_texts);
343
344static const struct snd_kcontrol_new sn95031_input2_mux_control =
345 SOC_DAPM_ENUM("Route", sn95031_input2_enum);
346
347static const struct soc_enum sn95031_input3_enum =
348 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 0, 8, sn95031_input_texts);
349
350static const struct snd_kcontrol_new sn95031_input3_mux_control =
351 SOC_DAPM_ENUM("Route", sn95031_input3_enum);
352
353static const struct soc_enum sn95031_input4_enum =
354 SOC_ENUM_SINGLE(SN95031_AUDIOMUX34, 4, 8, sn95031_input_texts);
355
356static const struct snd_kcontrol_new sn95031_input4_mux_control =
357 SOC_DAPM_ENUM("Route", sn95031_input4_enum);
358
359/* capture path controls */
360
361static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
362
363/* 0dB to 30dB in 10dB steps */
364static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0);
365
366static const struct soc_enum sn95031_micmode1_enum =
367 SOC_ENUM_SINGLE(SN95031_MICAMP1, 1, 2, sn95031_micmode_text);
368static const struct soc_enum sn95031_micmode2_enum =
369 SOC_ENUM_SINGLE(SN95031_MICAMP2, 1, 2, sn95031_micmode_text);
370
371static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"};
372
373static const struct soc_enum sn95031_dmic12_cfg_enum =
374 SOC_ENUM_SINGLE(SN95031_DMICMUX, 0, 2, sn95031_dmic_cfg_text);
375static const struct soc_enum sn95031_dmic34_cfg_enum =
376 SOC_ENUM_SINGLE(SN95031_DMICMUX, 1, 2, sn95031_dmic_cfg_text);
377static const struct soc_enum sn95031_dmic56_cfg_enum =
378 SOC_ENUM_SINGLE(SN95031_DMICMUX, 2, 2, sn95031_dmic_cfg_text);
379
380static const struct snd_kcontrol_new sn95031_snd_controls[] = {
381 SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
382 SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum),
383 SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum),
384 SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum),
385 SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum),
386 SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1,
387 2, 4, 0, mic_tlv),
388 SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2,
389 2, 4, 0, mic_tlv),
390};
391
392/* DAPM widgets */
393static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
394
395 /* all end points mic, hs etc */
396 SND_SOC_DAPM_OUTPUT("HPOUTL"),
397 SND_SOC_DAPM_OUTPUT("HPOUTR"),
398 SND_SOC_DAPM_OUTPUT("EPOUT"),
399 SND_SOC_DAPM_OUTPUT("IHFOUTL"),
400 SND_SOC_DAPM_OUTPUT("IHFOUTR"),
401 SND_SOC_DAPM_OUTPUT("LINEOUTL"),
402 SND_SOC_DAPM_OUTPUT("LINEOUTR"),
403 SND_SOC_DAPM_OUTPUT("VIB1OUT"),
404 SND_SOC_DAPM_OUTPUT("VIB2OUT"),
405
406 SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */
407 SND_SOC_DAPM_INPUT("AMIC2"),
408 SND_SOC_DAPM_INPUT("DMIC1"),
409 SND_SOC_DAPM_INPUT("DMIC2"),
410 SND_SOC_DAPM_INPUT("DMIC3"),
411 SND_SOC_DAPM_INPUT("DMIC4"),
412 SND_SOC_DAPM_INPUT("DMIC5"),
413 SND_SOC_DAPM_INPUT("DMIC6"),
414 SND_SOC_DAPM_INPUT("LINEINL"),
415 SND_SOC_DAPM_INPUT("LINEINR"),
416
417 SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0),
418 SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0),
419 SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0),
420 SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0),
421 SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0),
422
423 SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0,
424 sn95031_dmic12_event,
425 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
426 SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0,
427 sn95031_dmic34_event,
428 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
429 SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0,
430 sn95031_dmic56_event,
431 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
432
433 SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0,
434 SND_SOC_NOPM, 0, 0),
435
436 SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
437 sn95031_vhs_event,
438 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
439 SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0,
440 sn95031_vihf_event,
441 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
442
443 /* playback path driver enables */
444 SND_SOC_DAPM_PGA("Headset Left Playback",
445 SN95031_DRIVEREN, 0, 0, NULL, 0),
446 SND_SOC_DAPM_PGA("Headset Right Playback",
447 SN95031_DRIVEREN, 1, 0, NULL, 0),
448 SND_SOC_DAPM_PGA("Speaker Left Playback",
449 SN95031_DRIVEREN, 2, 0, NULL, 0),
450 SND_SOC_DAPM_PGA("Speaker Right Playback",
451 SN95031_DRIVEREN, 3, 0, NULL, 0),
452 SND_SOC_DAPM_PGA("Vibra1 Playback",
453 SN95031_DRIVEREN, 4, 0, NULL, 0),
454 SND_SOC_DAPM_PGA("Vibra2 Playback",
455 SN95031_DRIVEREN, 5, 0, NULL, 0),
456 SND_SOC_DAPM_PGA("Earpiece Playback",
457 SN95031_DRIVEREN, 6, 0, NULL, 0),
458 SND_SOC_DAPM_PGA("Lineout Left Playback",
459 SN95031_LOCTL, 0, 0, NULL, 0),
460 SND_SOC_DAPM_PGA("Lineout Right Playback",
461 SN95031_LOCTL, 4, 0, NULL, 0),
462
463 /* playback path filter enable */
464 SND_SOC_DAPM_PGA("Headset Left Filter",
465 SN95031_HSEPRXCTRL, 4, 0, NULL, 0),
466 SND_SOC_DAPM_PGA("Headset Right Filter",
467 SN95031_HSEPRXCTRL, 5, 0, NULL, 0),
468 SND_SOC_DAPM_PGA("Speaker Left Filter",
469 SN95031_IHFRXCTRL, 0, 0, NULL, 0),
470 SND_SOC_DAPM_PGA("Speaker Right Filter",
471 SN95031_IHFRXCTRL, 1, 0, NULL, 0),
472
473 /* DACs */
474 SND_SOC_DAPM_DAC("HSDAC Left", "Headset",
475 SN95031_DACCONFIG, 0, 0),
476 SND_SOC_DAPM_DAC("HSDAC Right", "Headset",
477 SN95031_DACCONFIG, 1, 0),
478 SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker",
479 SN95031_DACCONFIG, 2, 0),
480 SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker",
481 SN95031_DACCONFIG, 3, 0),
482 SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1",
483 SN95031_VIB1C5, 1, 0),
484 SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
485 SN95031_VIB2C5, 1, 0),
486
487 /* capture widgets */
488 SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1,
489 7, 0, NULL, 0),
490 SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2,
491 7, 0, NULL, 0),
492
493 SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0),
494 SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0),
495 SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0),
496 SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0),
497 SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0),
498 SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0),
499
500 /* ADC have null stream as they will be turned ON by TX path */
501 SND_SOC_DAPM_ADC("ADC Left", NULL,
502 SN95031_ADCCONFIG, 0, 0),
503 SND_SOC_DAPM_ADC("ADC Right", NULL,
504 SN95031_ADCCONFIG, 2, 0),
505
506 SND_SOC_DAPM_MUX("Mic_InputL Capture Route",
507 SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control),
508 SND_SOC_DAPM_MUX("Mic_InputR Capture Route",
509 SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control),
510
511 SND_SOC_DAPM_MUX("Txpath1 Capture Route",
512 SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control),
513 SND_SOC_DAPM_MUX("Txpath2 Capture Route",
514 SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control),
515 SND_SOC_DAPM_MUX("Txpath3 Capture Route",
516 SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control),
517 SND_SOC_DAPM_MUX("Txpath4 Capture Route",
518 SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control),
519
520};
521
522static const struct snd_soc_dapm_route sn95031_audio_map[] = {
523 /* headset and earpiece map */
524 { "HPOUTL", NULL, "Headset Rail"},
525 { "HPOUTR", NULL, "Headset Rail"},
526 { "HPOUTL", NULL, "Headset Left Playback" },
527 { "HPOUTR", NULL, "Headset Right Playback" },
528 { "EPOUT", NULL, "Earpiece Playback" },
529 { "Headset Left Playback", NULL, "Headset Left Filter"},
530 { "Headset Right Playback", NULL, "Headset Right Filter"},
531 { "Earpiece Playback", NULL, "Headset Left Filter"},
532 { "Headset Left Filter", NULL, "HSDAC Left"},
533 { "Headset Right Filter", NULL, "HSDAC Right"},
534
535 /* speaker map */
536 { "IHFOUTL", NULL, "Speaker Rail"},
537 { "IHFOUTR", NULL, "Speaker Rail"},
538 { "IHFOUTL", "NULL", "Speaker Left Playback"},
539 { "IHFOUTR", "NULL", "Speaker Right Playback"},
540 { "Speaker Left Playback", NULL, "Speaker Left Filter"},
541 { "Speaker Right Playback", NULL, "Speaker Right Filter"},
542 { "Speaker Left Filter", NULL, "IHFDAC Left"},
543 { "Speaker Right Filter", NULL, "IHFDAC Right"},
544
545 /* vibra map */
546 { "VIB1OUT", NULL, "Vibra1 Playback"},
547 { "Vibra1 Playback", NULL, "Vibra1 DAC"},
548
549 { "VIB2OUT", NULL, "Vibra2 Playback"},
550 { "Vibra2 Playback", NULL, "Vibra2 DAC"},
551
552 /* lineout */
553 { "LINEOUTL", NULL, "Lineout Left Playback"},
554 { "LINEOUTR", NULL, "Lineout Right Playback"},
555 { "Lineout Left Playback", NULL, "Headset Left Filter"},
556 { "Lineout Left Playback", NULL, "Speaker Left Filter"},
557 { "Lineout Left Playback", NULL, "Vibra1 DAC"},
558 { "Lineout Right Playback", NULL, "Headset Right Filter"},
559 { "Lineout Right Playback", NULL, "Speaker Right Filter"},
560 { "Lineout Right Playback", NULL, "Vibra2 DAC"},
561
562 /* Headset (AMIC1) mic */
563 { "AMIC1Bias", NULL, "AMIC1"},
564 { "MIC1 Enable", NULL, "AMIC1Bias"},
565 { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"},
566
567 /* AMIC2 */
568 { "AMIC2Bias", NULL, "AMIC2"},
569 { "MIC2 Enable", NULL, "AMIC2Bias"},
570 { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"},
571
572
573 /* Linein */
574 { "LineIn Enable Left", NULL, "LINEINL"},
575 { "LineIn Enable Right", NULL, "LINEINR"},
576 { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"},
577 { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"},
578
579 /* ADC connection */
580 { "ADC Left", NULL, "Mic_InputL Capture Route"},
581 { "ADC Right", NULL, "Mic_InputR Capture Route"},
582
583 /*DMIC connections */
584 { "DMIC1", NULL, "DMIC12supply"},
585 { "DMIC2", NULL, "DMIC12supply"},
586 { "DMIC3", NULL, "DMIC34supply"},
587 { "DMIC4", NULL, "DMIC34supply"},
588 { "DMIC5", NULL, "DMIC56supply"},
589 { "DMIC6", NULL, "DMIC56supply"},
590
591 { "DMIC12Bias", NULL, "DMIC1"},
592 { "DMIC12Bias", NULL, "DMIC2"},
593 { "DMIC34Bias", NULL, "DMIC3"},
594 { "DMIC34Bias", NULL, "DMIC4"},
595 { "DMIC56Bias", NULL, "DMIC5"},
596 { "DMIC56Bias", NULL, "DMIC6"},
597
598 /*TX path inputs*/
599 { "Txpath1 Capture Route", "ADC Left", "ADC Left"},
600 { "Txpath2 Capture Route", "ADC Left", "ADC Left"},
601 { "Txpath3 Capture Route", "ADC Left", "ADC Left"},
602 { "Txpath4 Capture Route", "ADC Left", "ADC Left"},
603 { "Txpath1 Capture Route", "ADC Right", "ADC Right"},
604 { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
605 { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
606 { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
607 { "Txpath1 Capture Route", "DMIC1", "DMIC1"},
608 { "Txpath2 Capture Route", "DMIC1", "DMIC1"},
609 { "Txpath3 Capture Route", "DMIC1", "DMIC1"},
610 { "Txpath4 Capture Route", "DMIC1", "DMIC1"},
611 { "Txpath1 Capture Route", "DMIC2", "DMIC2"},
612 { "Txpath2 Capture Route", "DMIC2", "DMIC2"},
613 { "Txpath3 Capture Route", "DMIC2", "DMIC2"},
614 { "Txpath4 Capture Route", "DMIC2", "DMIC2"},
615 { "Txpath1 Capture Route", "DMIC3", "DMIC3"},
616 { "Txpath2 Capture Route", "DMIC3", "DMIC3"},
617 { "Txpath3 Capture Route", "DMIC3", "DMIC3"},
618 { "Txpath4 Capture Route", "DMIC3", "DMIC3"},
619 { "Txpath1 Capture Route", "DMIC4", "DMIC4"},
620 { "Txpath2 Capture Route", "DMIC4", "DMIC4"},
621 { "Txpath3 Capture Route", "DMIC4", "DMIC4"},
622 { "Txpath4 Capture Route", "DMIC4", "DMIC4"},
623 { "Txpath1 Capture Route", "DMIC5", "DMIC5"},
624 { "Txpath2 Capture Route", "DMIC5", "DMIC5"},
625 { "Txpath3 Capture Route", "DMIC5", "DMIC5"},
626 { "Txpath4 Capture Route", "DMIC5", "DMIC5"},
627 { "Txpath1 Capture Route", "DMIC6", "DMIC6"},
628 { "Txpath2 Capture Route", "DMIC6", "DMIC6"},
629 { "Txpath3 Capture Route", "DMIC6", "DMIC6"},
630 { "Txpath4 Capture Route", "DMIC6", "DMIC6"},
631
632 /* tx path */
633 { "TX1 Enable", NULL, "Txpath1 Capture Route"},
634 { "TX2 Enable", NULL, "Txpath2 Capture Route"},
635 { "TX3 Enable", NULL, "Txpath3 Capture Route"},
636 { "TX4 Enable", NULL, "Txpath4 Capture Route"},
637 { "PCM_Out", NULL, "TX1 Enable"},
638 { "PCM_Out", NULL, "TX2 Enable"},
639 { "PCM_Out", NULL, "TX3 Enable"},
640 { "PCM_Out", NULL, "TX4 Enable"},
641
642};
643
644/* speaker and headset mutes, for audio pops and clicks */
645static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute)
646{
647 snd_soc_update_bits(dai->codec,
648 SN95031_HSLVOLCTRL, BIT(7), (!mute << 7));
649 snd_soc_update_bits(dai->codec,
650 SN95031_HSRVOLCTRL, BIT(7), (!mute << 7));
651 return 0;
652}
653
654static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
655{
656 snd_soc_update_bits(dai->codec,
657 SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7));
658 snd_soc_update_bits(dai->codec,
659 SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7));
660 return 0;
661}
662
663int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
664 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
665{
666 unsigned int format, rate;
667
668 switch (params_format(params)) {
669 case SNDRV_PCM_FORMAT_S16_LE:
670 format = BIT(4)|BIT(5);
671 break;
672
673 case SNDRV_PCM_FORMAT_S24_LE:
674 format = 0;
675 break;
676 default:
677 return -EINVAL;
678 }
679 snd_soc_update_bits(dai->codec, SN95031_PCM2C2,
680 BIT(4)|BIT(5), format);
681
682 switch (params_rate(params)) {
683 case 48000:
684 pr_debug("RATE_48000\n");
685 rate = 0;
686 break;
687
688 case 44100:
689 pr_debug("RATE_44100\n");
690 rate = BIT(7);
691 break;
692
693 default:
694 pr_err("ERR rate %d\n", params_rate(params));
695 return -EINVAL;
696 }
697 snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate);
698
699 return 0;
700}
701
702/* Codec DAI section */
703static struct snd_soc_dai_ops sn95031_headset_dai_ops = {
704 .digital_mute = sn95031_pcm_hs_mute,
705 .hw_params = sn95031_pcm_hw_params,
706};
707
708static struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
709 .digital_mute = sn95031_pcm_spkr_mute,
710 .hw_params = sn95031_pcm_hw_params,
711};
712
713static struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
714 .hw_params = sn95031_pcm_hw_params,
715};
716
717static struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
718 .hw_params = sn95031_pcm_hw_params,
719};
720
721struct snd_soc_dai_driver sn95031_dais[] = {
722{
723 .name = "SN95031 Headset",
724 .playback = {
725 .stream_name = "Headset",
726 .channels_min = 2,
727 .channels_max = 2,
728 .rates = SN95031_RATES,
729 .formats = SN95031_FORMATS,
730 },
731 .capture = {
732 .stream_name = "Capture",
733 .channels_min = 1,
734 .channels_max = 5,
735 .rates = SN95031_RATES,
736 .formats = SN95031_FORMATS,
737 },
738 .ops = &sn95031_headset_dai_ops,
739},
740{ .name = "SN95031 Speaker",
741 .playback = {
742 .stream_name = "Speaker",
743 .channels_min = 2,
744 .channels_max = 2,
745 .rates = SN95031_RATES,
746 .formats = SN95031_FORMATS,
747 },
748 .ops = &sn95031_speaker_dai_ops,
749},
750{ .name = "SN95031 Vibra1",
751 .playback = {
752 .stream_name = "Vibra1",
753 .channels_min = 1,
754 .channels_max = 1,
755 .rates = SN95031_RATES,
756 .formats = SN95031_FORMATS,
757 },
758 .ops = &sn95031_vib1_dai_ops,
759},
760{ .name = "SN95031 Vibra2",
761 .playback = {
762 .stream_name = "Vibra2",
763 .channels_min = 1,
764 .channels_max = 1,
765 .rates = SN95031_RATES,
766 .formats = SN95031_FORMATS,
767 },
768 .ops = &sn95031_vib2_dai_ops,
769},
770};
771
772static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
773{
774 snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
775}
776
777static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
778{
779 snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
780 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
781}
782
783static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack)
784{
785 int micbias = sn95031_get_mic_bias(mfld_jack->codec);
786
787 int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
788
789 pr_debug("jack type detected = %d\n", jack_type);
790 if (jack_type == SND_JACK_HEADSET)
791 sn95031_enable_jack_btn(mfld_jack->codec);
792 return jack_type;
793}
794
795void sn95031_jack_detection(struct mfld_jack_data *jack_data)
796{
797 unsigned int status;
798 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
799
800 pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
801 if (jack_data->intr_id & 0x1) {
802 pr_debug("short_push detected\n");
803 status = SND_JACK_HEADSET | SND_JACK_BTN_0;
804 } else if (jack_data->intr_id & 0x2) {
805 pr_debug("long_push detected\n");
806 status = SND_JACK_HEADSET | SND_JACK_BTN_1;
807 } else if (jack_data->intr_id & 0x4) {
808 pr_debug("headset or headphones inserted\n");
809 status = sn95031_get_headset_state(jack_data->mfld_jack);
810 } else if (jack_data->intr_id & 0x8) {
811 pr_debug("headset or headphones removed\n");
812 status = 0;
813 sn95031_disable_jack_btn(jack_data->mfld_jack->codec);
814 } else {
815 pr_err("unidentified interrupt\n");
816 return;
817 }
818
819 snd_soc_jack_report(jack_data->mfld_jack, status, mask);
820 /*button pressed and released so we send explicit button release */
821 if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
822 snd_soc_jack_report(jack_data->mfld_jack,
823 SND_JACK_HEADSET, mask);
824}
825EXPORT_SYMBOL_GPL(sn95031_jack_detection);
826
827/* codec registration */
828static int sn95031_codec_probe(struct snd_soc_codec *codec)
829{
830 pr_debug("codec_probe called\n");
831
832 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
833 codec->dapm.idle_bias_off = 1;
834
835 /* PCM interface config
836 * This sets the pcm rx slot conguration to max 6 slots
837 * for max 4 dais (2 stereo and 2 mono)
838 */
839 snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10);
840 snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32);
841 snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54);
842 snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10);
843 snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32);
844 /* pcm port setting
845 * This sets the pcm port to slave and clock at 19.2Mhz which
846 * can support 6slots, sampling rate set per stream in hw-params
847 */
848 snd_soc_write(codec, SN95031_PCM1C1, 0x00);
849 snd_soc_write(codec, SN95031_PCM2C1, 0x01);
850 snd_soc_write(codec, SN95031_PCM2C2, 0x0A);
851 snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4));
852 /* vendor vibra workround, the vibras are muted by
853 * custom register so unmute them
854 */
855 snd_soc_write(codec, SN95031_SSR5, 0x80);
856 snd_soc_write(codec, SN95031_SSR6, 0x80);
857 snd_soc_write(codec, SN95031_VIB1C5, 0x00);
858 snd_soc_write(codec, SN95031_VIB2C5, 0x00);
859 /* configure vibras for pcm port */
860 snd_soc_write(codec, SN95031_VIB1C3, 0x00);
861 snd_soc_write(codec, SN95031_VIB2C3, 0x00);
862
863 /* soft mute ramp time */
864 snd_soc_write(codec, SN95031_SOFTMUTE, 0x3);
865 /* fix the initial volume at 1dB,
866 * default in +9dB,
867 * 1dB give optimal swing on DAC, amps
868 */
869 snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08);
870 snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08);
871 snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08);
872 snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08);
873 /* dac mode and lineout workaround */
874 snd_soc_write(codec, SN95031_SSR2, 0x10);
875 snd_soc_write(codec, SN95031_SSR3, 0x40);
876
877 snd_soc_add_controls(codec, sn95031_snd_controls,
878 ARRAY_SIZE(sn95031_snd_controls));
879
880 return 0;
881}
882
883static int sn95031_codec_remove(struct snd_soc_codec *codec)
884{
885 pr_debug("codec_remove called\n");
886 sn95031_set_vaud_bias(codec, SND_SOC_BIAS_OFF);
887
888 return 0;
889}
890
891struct snd_soc_codec_driver sn95031_codec = {
892 .probe = sn95031_codec_probe,
893 .remove = sn95031_codec_remove,
894 .read = sn95031_read,
895 .write = sn95031_write,
896 .set_bias_level = sn95031_set_vaud_bias,
897 .dapm_widgets = sn95031_dapm_widgets,
898 .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
899 .dapm_routes = sn95031_audio_map,
900 .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
901};
902
903static int __devinit sn95031_device_probe(struct platform_device *pdev)
904{
905 pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev));
906 return snd_soc_register_codec(&pdev->dev, &sn95031_codec,
907 sn95031_dais, ARRAY_SIZE(sn95031_dais));
908}
909
910static int __devexit sn95031_device_remove(struct platform_device *pdev)
911{
912 pr_debug("codec device remove called\n");
913 snd_soc_unregister_codec(&pdev->dev);
914 return 0;
915}
916
917static struct platform_driver sn95031_codec_driver = {
918 .driver = {
919 .name = "sn95031",
920 .owner = THIS_MODULE,
921 },
922 .probe = sn95031_device_probe,
923 .remove = __devexit_p(sn95031_device_remove),
924};
925
926static int __init sn95031_init(void)
927{
928 pr_debug("driver init called\n");
929 return platform_driver_register(&sn95031_codec_driver);
930}
931module_init(sn95031_init);
932
933static void __exit sn95031_exit(void)
934{
935 pr_debug("driver exit called\n");
936 platform_driver_unregister(&sn95031_codec_driver);
937}
938module_exit(sn95031_exit);
939
940MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
941MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
942MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
943MODULE_LICENSE("GPL v2");
944MODULE_ALIAS("platform:sn95031");
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
new file mode 100644
index 000000000000..20376d234fb8
--- /dev/null
+++ b/sound/soc/codecs/sn95031.h
@@ -0,0 +1,132 @@
1/*
2 * sn95031.h - TI sn95031 Codec driver
3 *
4 * Copyright (C) 2010 Intel Corp
5 * Author: Vinod Koul <vinod.koul@intel.com>
6 * Author: Harsha Priya <priya.harsha@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 *
24 *
25 */
26#ifndef _SN95031_H
27#define _SN95031_H
28
29/*register map*/
30#define SN95031_VAUD 0xDB
31#define SN95031_VHSP 0xDC
32#define SN95031_VHSN 0xDD
33#define SN95031_VIHF 0xC9
34
35#define SN95031_AUDPLLCTRL 0x240
36#define SN95031_DMICBUF0123 0x241
37#define SN95031_DMICBUF45 0x242
38#define SN95031_DMICGPO 0x244
39#define SN95031_DMICMUX 0x245
40#define SN95031_DMICLK 0x246
41#define SN95031_MICBIAS 0x247
42#define SN95031_ADCCONFIG 0x248
43#define SN95031_MICAMP1 0x249
44#define SN95031_MICAMP2 0x24A
45#define SN95031_NOISEMUX 0x24B
46#define SN95031_AUDIOMUX12 0x24C
47#define SN95031_AUDIOMUX34 0x24D
48#define SN95031_AUDIOSINC 0x24E
49#define SN95031_AUDIOTXEN 0x24F
50#define SN95031_HSEPRXCTRL 0x250
51#define SN95031_IHFRXCTRL 0x251
52#define SN95031_HSMIXER 0x256
53#define SN95031_DACCONFIG 0x257
54#define SN95031_SOFTMUTE 0x258
55#define SN95031_HSLVOLCTRL 0x259
56#define SN95031_HSRVOLCTRL 0x25A
57#define SN95031_IHFLVOLCTRL 0x25B
58#define SN95031_IHFRVOLCTRL 0x25C
59#define SN95031_DRIVEREN 0x25D
60#define SN95031_LOCTL 0x25E
61#define SN95031_VIB1C1 0x25F
62#define SN95031_VIB1C2 0x260
63#define SN95031_VIB1C3 0x261
64#define SN95031_VIB1SPIPCM1 0x262
65#define SN95031_VIB1SPIPCM2 0x263
66#define SN95031_VIB1C5 0x264
67#define SN95031_VIB2C1 0x265
68#define SN95031_VIB2C2 0x266
69#define SN95031_VIB2C3 0x267
70#define SN95031_VIB2SPIPCM1 0x268
71#define SN95031_VIB2SPIPCM2 0x269
72#define SN95031_VIB2C5 0x26A
73#define SN95031_BTNCTRL1 0x26B
74#define SN95031_BTNCTRL2 0x26C
75#define SN95031_PCM1TXSLOT01 0x26D
76#define SN95031_PCM1TXSLOT23 0x26E
77#define SN95031_PCM1TXSLOT45 0x26F
78#define SN95031_PCM1RXSLOT0_3 0x270
79#define SN95031_PCM1RXSLOT45 0x271
80#define SN95031_PCM2TXSLOT01 0x272
81#define SN95031_PCM2TXSLOT23 0x273
82#define SN95031_PCM2TXSLOT45 0x274
83#define SN95031_PCM2RXSLOT01 0x275
84#define SN95031_PCM2RXSLOT23 0x276
85#define SN95031_PCM2RXSLOT45 0x277
86#define SN95031_PCM1C1 0x278
87#define SN95031_PCM1C2 0x279
88#define SN95031_PCM1C3 0x27A
89#define SN95031_PCM2C1 0x27B
90#define SN95031_PCM2C2 0x27C
91/*end codec register defn*/
92
93/*vendor defn these are not part of avp*/
94#define SN95031_SSR2 0x381
95#define SN95031_SSR3 0x382
96#define SN95031_SSR5 0x384
97#define SN95031_SSR6 0x385
98
99/* ADC registers */
100
101#define SN95031_ADC1CNTL1 0x1C0
102#define SN95031_ADC_ENBL 0x10
103#define SN95031_ADC_START 0x08
104#define SN95031_ADC1CNTL3 0x1C2
105#define SN95031_ADCTHERM_ENBL 0x04
106#define SN95031_ADCRRDATA_ENBL 0x05
107#define SN95031_STOPBIT_MASK 16
108#define SN95031_ADCTHERM_MASK 4
109#define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */
110#define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1)
111#define SN95031_ADC_NO_LOOP 0x07
112#define SN95031_AUDIO_GPIO_CTRL 0x070
113
114/* ADC channel code values */
115#define SN95031_AUDIO_DETECT_CODE 0x06
116
117/* ADC base addresses */
118#define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
119#define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
120/* multipier to convert to mV */
121#define SN95031_ADC_ONE_LSB_MULTIPLIER 2346
122
123
124struct mfld_jack_data {
125 int intr_id;
126 int micbias_vol;
127 struct snd_soc_jack *mfld_jack;
128};
129
130extern void sn95031_jack_detection(struct mfld_jack_data *jack_data);
131
132#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 9119836051a4..6a1a7e705cd7 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -21,57 +21,16 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23 23
24#include "spdif_transciever.h" 24#define DRV_NAME "spdif-dit"
25
26MODULE_LICENSE("GPL");
27 25
28#define STUB_RATES SNDRV_PCM_RATE_8000_96000 26#define STUB_RATES SNDRV_PCM_RATE_8000_96000
29#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
30 28
31static struct snd_soc_codec *spdif_dit_codec;
32
33static int spdif_dit_codec_probe(struct platform_device *pdev)
34{
35 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
36 struct snd_soc_codec *codec;
37 int ret;
38
39 if (spdif_dit_codec == NULL) {
40 dev_err(&pdev->dev, "Codec device not registered\n");
41 return -ENODEV;
42 }
43
44 socdev->card->codec = spdif_dit_codec;
45 codec = spdif_dit_codec;
46
47 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
48 if (ret < 0) {
49 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
50 goto err_create_pcms;
51 }
52
53 return 0;
54
55err_create_pcms:
56 return ret;
57}
58
59static int spdif_dit_codec_remove(struct platform_device *pdev)
60{
61 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
62
63 snd_soc_free_pcms(socdev);
64
65 return 0;
66}
67 29
68struct snd_soc_codec_device soc_codec_dev_spdif_dit = { 30static struct snd_soc_codec_driver soc_codec_spdif_dit;
69 .probe = spdif_dit_codec_probe,
70 .remove = spdif_dit_codec_remove,
71}; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit);
72 31
73struct snd_soc_dai dit_stub_dai = { 32static struct snd_soc_dai_driver dit_stub_dai = {
74 .name = "DIT", 33 .name = "dit-hifi",
75 .playback = { 34 .playback = {
76 .stream_name = "Playback", 35 .stream_name = "Playback",
77 .channels_min = 1, 36 .channels_min = 1,
@@ -80,65 +39,16 @@ struct snd_soc_dai dit_stub_dai = {
80 .formats = STUB_FORMATS, 39 .formats = STUB_FORMATS,
81 }, 40 },
82}; 41};
83EXPORT_SYMBOL_GPL(dit_stub_dai);
84 42
85static int spdif_dit_probe(struct platform_device *pdev) 43static int spdif_dit_probe(struct platform_device *pdev)
86{ 44{
87 struct snd_soc_codec *codec; 45 return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
88 int ret; 46 &dit_stub_dai, 1);
89
90 if (spdif_dit_codec) {
91 dev_err(&pdev->dev, "Another Codec is registered\n");
92 ret = -EINVAL;
93 goto err_reg_codec;
94 }
95
96 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
97 if (codec == NULL)
98 return -ENOMEM;
99
100 codec->dev = &pdev->dev;
101
102 mutex_init(&codec->mutex);
103
104 INIT_LIST_HEAD(&codec->dapm_widgets);
105 INIT_LIST_HEAD(&codec->dapm_paths);
106
107 codec->name = "spdif-dit";
108 codec->owner = THIS_MODULE;
109 codec->dai = &dit_stub_dai;
110 codec->num_dai = 1;
111
112 spdif_dit_codec = codec;
113
114 ret = snd_soc_register_codec(codec);
115 if (ret < 0) {
116 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
117 goto err_reg_codec;
118 }
119
120 dit_stub_dai.dev = &pdev->dev;
121 ret = snd_soc_register_dai(&dit_stub_dai);
122 if (ret < 0) {
123 dev_err(codec->dev, "Failed to register dai: %d\n", ret);
124 goto err_reg_dai;
125 }
126
127 return 0;
128
129err_reg_dai:
130 snd_soc_unregister_codec(codec);
131err_reg_codec:
132 kfree(spdif_dit_codec);
133 return ret;
134} 47}
135 48
136static int spdif_dit_remove(struct platform_device *pdev) 49static int spdif_dit_remove(struct platform_device *pdev)
137{ 50{
138 snd_soc_unregister_dai(&dit_stub_dai); 51 snd_soc_unregister_codec(&pdev->dev);
139 snd_soc_unregister_codec(spdif_dit_codec);
140 kfree(spdif_dit_codec);
141 spdif_dit_codec = NULL;
142 return 0; 52 return 0;
143} 53}
144 54
@@ -146,7 +56,7 @@ static struct platform_driver spdif_dit_driver = {
146 .probe = spdif_dit_probe, 56 .probe = spdif_dit_probe,
147 .remove = spdif_dit_remove, 57 .remove = spdif_dit_remove,
148 .driver = { 58 .driver = {
149 .name = "spdif-dit", 59 .name = DRV_NAME,
150 .owner = THIS_MODULE, 60 .owner = THIS_MODULE,
151 }, 61 },
152}; 62};
@@ -164,3 +74,7 @@ static void __exit dit_exit(void)
164module_init(dit_modinit); 74module_init(dit_modinit);
165module_exit(dit_exit); 75module_exit(dit_exit);
166 76
77MODULE_AUTHOR("Steve Chen <schen@mvista.com>");
78MODULE_DESCRIPTION("SPDIF dummy codec driver");
79MODULE_LICENSE("GPL");
80MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/spdif_transciever.h b/sound/soc/codecs/spdif_transciever.h
deleted file mode 100644
index 1e102124f546..000000000000
--- a/sound/soc/codecs/spdif_transciever.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * ALSA SoC DIT/DIR driver header
3 *
4 * Author: Steve Chen, <schen@mvista.com>
5 * Copyright: (C) 2008 MontaVista Software, Inc., <source@mvista.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CODEC_STUBS_H
13#define CODEC_STUBS_H
14
15extern struct snd_soc_codec_device soc_codec_dev_spdif_dit;
16extern struct snd_soc_dai dit_stub_dai;
17
18#endif /* CODEC_STUBS_H */
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index b47ed4f6ab20..84f4ad568556 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -32,26 +32,33 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/spi/spi.h>
35#include <linux/platform_device.h> 36#include <linux/platform_device.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <sound/core.h> 38#include <sound/core.h>
38#include <sound/pcm.h> 39#include <sound/pcm.h>
39#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
40#include <sound/soc.h> 41#include <sound/soc.h>
41#include <sound/soc-dapm.h>
42#include <sound/initval.h> 42#include <sound/initval.h>
43#include <sound/tlv.h>
43 44
44#include "ssm2602.h" 45#include "ssm2602.h"
45 46
46#define SSM2602_VERSION "0.1" 47#define SSM2602_VERSION "0.1"
47 48
48struct snd_soc_codec_device soc_codec_dev_ssm2602; 49enum ssm2602_type {
50 SSM2602,
51 SSM2604,
52};
49 53
50/* codec private data */ 54/* codec private data */
51struct ssm2602_priv { 55struct ssm2602_priv {
52 unsigned int sysclk; 56 unsigned int sysclk;
57 enum snd_soc_control_type control_type;
53 struct snd_pcm_substream *master_substream; 58 struct snd_pcm_substream *master_substream;
54 struct snd_pcm_substream *slave_substream; 59 struct snd_pcm_substream *slave_substream;
60
61 enum ssm2602_type type;
55}; 62};
56 63
57/* 64/*
@@ -61,60 +68,12 @@ struct ssm2602_priv {
61 * There is no point in caching the reset register 68 * There is no point in caching the reset register
62 */ 69 */
63static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { 70static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
64 0x0017, 0x0017, 0x0079, 0x0079, 71 0x0097, 0x0097, 0x0079, 0x0079,
65 0x0000, 0x0000, 0x0000, 0x000a, 72 0x000a, 0x0008, 0x009f, 0x000a,
66 0x0000, 0x0000 73 0x0000, 0x0000
67}; 74};
68 75
69/* 76#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0)
70 * read ssm2602 register cache
71 */
72static inline unsigned int ssm2602_read_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg)
74{
75 u16 *cache = codec->reg_cache;
76 if (reg == SSM2602_RESET)
77 return 0;
78 if (reg >= SSM2602_CACHEREGNUM)
79 return -1;
80 return cache[reg];
81}
82
83/*
84 * write ssm2602 register cache
85 */
86static inline void ssm2602_write_reg_cache(struct snd_soc_codec *codec,
87 u16 reg, unsigned int value)
88{
89 u16 *cache = codec->reg_cache;
90 if (reg >= SSM2602_CACHEREGNUM)
91 return;
92 cache[reg] = value;
93}
94
95/*
96 * write to the ssm2602 register space
97 */
98static int ssm2602_write(struct snd_soc_codec *codec, unsigned int reg,
99 unsigned int value)
100{
101 u8 data[2];
102
103 /* data is
104 * D15..D9 ssm2602 register offset
105 * D8...D0 register data
106 */
107 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
108 data[1] = value & 0x00ff;
109
110 ssm2602_write_reg_cache(codec, reg, value);
111 if (codec->hw_write(codec->control_data, data, 2) == 2)
112 return 0;
113 else
114 return -EIO;
115}
116
117#define ssm2602_reset(c) ssm2602_write(c, SSM2602_RESET, 0)
118 77
119/*Appending several "None"s just for OSS mixer use*/ 78/*Appending several "None"s just for OSS mixer use*/
120static const char *ssm2602_input_select[] = { 79static const char *ssm2602_input_select[] = {
@@ -129,174 +88,187 @@ static const struct soc_enum ssm2602_enum[] = {
129 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph), 88 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph),
130}; 89};
131 90
132static const struct snd_kcontrol_new ssm2602_snd_controls[] = { 91static const unsigned int ssm260x_outmix_tlv[] = {
92 TLV_DB_RANGE_HEAD(2),
93 0, 47, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
94 48, 127, TLV_DB_SCALE_ITEM(-7400, 100, 0),
95};
133 96
134SOC_DOUBLE_R("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V, 97static const DECLARE_TLV_DB_SCALE(ssm260x_inpga_tlv, -3450, 150, 0);
135 0, 127, 0), 98static const DECLARE_TLV_DB_SCALE(ssm260x_sidetone_tlv, -1500, 300, 0);
136SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
137 7, 1, 0),
138 99
139SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0), 100static const struct snd_kcontrol_new ssm260x_snd_controls[] = {
101SOC_DOUBLE_R_TLV("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 45, 0,
102 ssm260x_inpga_tlv),
140SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), 103SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
141 104
142SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
143SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 7, 1, 0),
144SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
145
146SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
147
148SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1), 105SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1),
149SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0), 106SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0),
150 107
151SOC_ENUM("Capture Source", ssm2602_enum[0]),
152
153SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), 108SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]),
154}; 109};
155 110
111static const struct snd_kcontrol_new ssm2602_snd_controls[] = {
112SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V,
113 0, 127, 0, ssm260x_outmix_tlv),
114SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V,
115 7, 1, 0),
116SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1,
117 ssm260x_sidetone_tlv),
118
119SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
120SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0),
121SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
122};
123
156/* Output Mixer */ 124/* Output Mixer */
157static const struct snd_kcontrol_new ssm2602_output_mixer_controls[] = { 125static const struct snd_kcontrol_new ssm260x_output_mixer_controls[] = {
158SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), 126SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0),
159SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
160SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0), 127SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0),
128SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0),
161}; 129};
162 130
163/* Input mux */ 131/* Input mux */
164static const struct snd_kcontrol_new ssm2602_input_mux_controls = 132static const struct snd_kcontrol_new ssm2602_input_mux_controls =
165SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]); 133SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]);
166 134
167static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = { 135static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = {
168SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
169 &ssm2602_output_mixer_controls[0],
170 ARRAY_SIZE(ssm2602_output_mixer_controls)),
171SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1), 136SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1),
137SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1),
138SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
139
140SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, NULL, 0),
141
172SND_SOC_DAPM_OUTPUT("LOUT"), 142SND_SOC_DAPM_OUTPUT("LOUT"),
173SND_SOC_DAPM_OUTPUT("LHPOUT"),
174SND_SOC_DAPM_OUTPUT("ROUT"), 143SND_SOC_DAPM_OUTPUT("ROUT"),
175SND_SOC_DAPM_OUTPUT("RHPOUT"), 144SND_SOC_DAPM_INPUT("RLINEIN"),
176SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), 145SND_SOC_DAPM_INPUT("LLINEIN"),
146};
147
148static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = {
149SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1,
150 ssm260x_output_mixer_controls,
151 ARRAY_SIZE(ssm260x_output_mixer_controls)),
152
177SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls), 153SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls),
178SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0),
179SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1), 154SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1),
155
156SND_SOC_DAPM_OUTPUT("LHPOUT"),
157SND_SOC_DAPM_OUTPUT("RHPOUT"),
180SND_SOC_DAPM_INPUT("MICIN"), 158SND_SOC_DAPM_INPUT("MICIN"),
181SND_SOC_DAPM_INPUT("RLINEIN"),
182SND_SOC_DAPM_INPUT("LLINEIN"),
183}; 159};
184 160
185static const struct snd_soc_dapm_route audio_conn[] = { 161static const struct snd_soc_dapm_widget ssm2604_dapm_widgets[] = {
186 /* output mixer */ 162SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
163 ssm260x_output_mixer_controls,
164 ARRAY_SIZE(ssm260x_output_mixer_controls) - 1), /* Last element is the mic */
165};
166
167static const struct snd_soc_dapm_route ssm260x_routes[] = {
168 {"DAC", NULL, "Digital Core Power"},
169 {"ADC", NULL, "Digital Core Power"},
170
187 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 171 {"Output Mixer", "Line Bypass Switch", "Line Input"},
188 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 172 {"Output Mixer", "HiFi Playback Switch", "DAC"},
173
174 {"ROUT", NULL, "Output Mixer"},
175 {"LOUT", NULL, "Output Mixer"},
176
177 {"Line Input", NULL, "LLINEIN"},
178 {"Line Input", NULL, "RLINEIN"},
179};
180
181static const struct snd_soc_dapm_route ssm2602_routes[] = {
189 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, 182 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
190 183
191 /* outputs */
192 {"RHPOUT", NULL, "Output Mixer"}, 184 {"RHPOUT", NULL, "Output Mixer"},
193 {"ROUT", NULL, "Output Mixer"},
194 {"LHPOUT", NULL, "Output Mixer"}, 185 {"LHPOUT", NULL, "Output Mixer"},
195 {"LOUT", NULL, "Output Mixer"},
196 186
197 /* input mux */
198 {"Input Mux", "Line", "Line Input"}, 187 {"Input Mux", "Line", "Line Input"},
199 {"Input Mux", "Mic", "Mic Bias"}, 188 {"Input Mux", "Mic", "Mic Bias"},
200 {"ADC", NULL, "Input Mux"}, 189 {"ADC", NULL, "Input Mux"},
201 190
202 /* inputs */
203 {"Line Input", NULL, "LLINEIN"},
204 {"Line Input", NULL, "RLINEIN"},
205 {"Mic Bias", NULL, "MICIN"}, 191 {"Mic Bias", NULL, "MICIN"},
206}; 192};
207 193
208static int ssm2602_add_widgets(struct snd_soc_codec *codec) 194static const struct snd_soc_dapm_route ssm2604_routes[] = {
209{ 195 {"ADC", NULL, "Line Input"},
210 snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets, 196};
211 ARRAY_SIZE(ssm2602_dapm_widgets));
212
213 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
214
215 return 0;
216}
217 197
218struct _coeff_div { 198struct ssm2602_coeff {
219 u32 mclk; 199 u32 mclk;
220 u32 rate; 200 u32 rate;
221 u16 fs; 201 u8 srate;
222 u8 sr:4;
223 u8 bosr:1;
224 u8 usb:1;
225}; 202};
226 203
227/* codec mclk clock divider coefficients */ 204#define SSM2602_COEFF_SRATE(sr, bosr, usb) (((sr) << 2) | ((bosr) << 1) | (usb))
228static const struct _coeff_div coeff_div[] = { 205
206/* codec mclk clock coefficients */
207static const struct ssm2602_coeff ssm2602_coeff_table[] = {
229 /* 48k */ 208 /* 48k */
230 {12288000, 48000, 256, 0x0, 0x0, 0x0}, 209 {12288000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x0)},
231 {18432000, 48000, 384, 0x0, 0x1, 0x0}, 210 {18432000, 48000, SSM2602_COEFF_SRATE(0x0, 0x1, 0x0)},
232 {12000000, 48000, 250, 0x0, 0x0, 0x1}, 211 {12000000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x1)},
233 212
234 /* 32k */ 213 /* 32k */
235 {12288000, 32000, 384, 0x6, 0x0, 0x0}, 214 {12288000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x0)},
236 {18432000, 32000, 576, 0x6, 0x1, 0x0}, 215 {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)},
237 {12000000, 32000, 375, 0x6, 0x0, 0x1}, 216 {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)},
238 217
239 /* 8k */ 218 /* 8k */
240 {12288000, 8000, 1536, 0x3, 0x0, 0x0}, 219 {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)},
241 {18432000, 8000, 2304, 0x3, 0x1, 0x0}, 220 {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)},
242 {11289600, 8000, 1408, 0xb, 0x0, 0x0}, 221 {11289600, 8000, SSM2602_COEFF_SRATE(0xb, 0x0, 0x0)},
243 {16934400, 8000, 2112, 0xb, 0x1, 0x0}, 222 {16934400, 8000, SSM2602_COEFF_SRATE(0xb, 0x1, 0x0)},
244 {12000000, 8000, 1500, 0x3, 0x0, 0x1}, 223 {12000000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x1)},
245 224
246 /* 96k */ 225 /* 96k */
247 {12288000, 96000, 128, 0x7, 0x0, 0x0}, 226 {12288000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x0)},
248 {18432000, 96000, 192, 0x7, 0x1, 0x0}, 227 {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)},
249 {12000000, 96000, 125, 0x7, 0x0, 0x1}, 228 {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)},
250 229
251 /* 44.1k */ 230 /* 44.1k */
252 {11289600, 44100, 256, 0x8, 0x0, 0x0}, 231 {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)},
253 {16934400, 44100, 384, 0x8, 0x1, 0x0}, 232 {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)},
254 {12000000, 44100, 272, 0x8, 0x1, 0x1}, 233 {12000000, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x1)},
255 234
256 /* 88.2k */ 235 /* 88.2k */
257 {11289600, 88200, 128, 0xf, 0x0, 0x0}, 236 {11289600, 88200, SSM2602_COEFF_SRATE(0xf, 0x0, 0x0)},
258 {16934400, 88200, 192, 0xf, 0x1, 0x0}, 237 {16934400, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x0)},
259 {12000000, 88200, 136, 0xf, 0x1, 0x1}, 238 {12000000, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x1)},
260}; 239};
261 240
262static inline int get_coeff(int mclk, int rate) 241static inline int ssm2602_get_coeff(int mclk, int rate)
263{ 242{
264 int i; 243 int i;
265 244
266 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 245 for (i = 0; i < ARRAY_SIZE(ssm2602_coeff_table); i++) {
267 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) 246 if (ssm2602_coeff_table[i].rate == rate &&
268 return i; 247 ssm2602_coeff_table[i].mclk == mclk)
248 return ssm2602_coeff_table[i].srate;
269 } 249 }
270 return i; 250 return -EINVAL;
271} 251}
272 252
273static int ssm2602_hw_params(struct snd_pcm_substream *substream, 253static int ssm2602_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params, 254 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai) 255 struct snd_soc_dai *dai)
276{ 256{
277 u16 srate;
278 struct snd_soc_pcm_runtime *rtd = substream->private_data; 257 struct snd_soc_pcm_runtime *rtd = substream->private_data;
279 struct snd_soc_device *socdev = rtd->socdev; 258 struct snd_soc_codec *codec = rtd->codec;
280 struct snd_soc_codec *codec = socdev->card->codec;
281 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 259 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
282 struct i2c_client *i2c = codec->control_data; 260 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
283 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 261 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
284 int i = get_coeff(ssm2602->sysclk, params_rate(params));
285 262
286 if (substream == ssm2602->slave_substream) { 263 if (substream == ssm2602->slave_substream) {
287 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 264 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
288 return 0; 265 return 0;
289 } 266 }
290 267
291 /*no match is found*/ 268 if (srate < 0)
292 if (i == ARRAY_SIZE(coeff_div)) 269 return srate;
293 return -EINVAL;
294
295 srate = (coeff_div[i].sr << 2) |
296 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
297 270
298 ssm2602_write(codec, SSM2602_ACTIVE, 0); 271 snd_soc_write(codec, SSM2602_SRATE, srate);
299 ssm2602_write(codec, SSM2602_SRATE, srate);
300 272
301 /* bit size */ 273 /* bit size */
302 switch (params_format(params)) { 274 switch (params_format(params)) {
@@ -312,8 +284,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
312 iface |= 0x000c; 284 iface |= 0x000c;
313 break; 285 break;
314 } 286 }
315 ssm2602_write(codec, SSM2602_IFACE, iface); 287 snd_soc_write(codec, SSM2602_IFACE, iface);
316 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
317 return 0; 288 return 0;
318} 289}
319 290
@@ -321,8 +292,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
321 struct snd_soc_dai *dai) 292 struct snd_soc_dai *dai)
322{ 293{
323 struct snd_soc_pcm_runtime *rtd = substream->private_data; 294 struct snd_soc_pcm_runtime *rtd = substream->private_data;
324 struct snd_soc_device *socdev = rtd->socdev; 295 struct snd_soc_codec *codec = rtd->codec;
325 struct snd_soc_codec *codec = socdev->card->codec;
326 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
327 struct i2c_client *i2c = codec->control_data; 297 struct i2c_client *i2c = codec->control_data;
328 struct snd_pcm_runtime *master_runtime; 298 struct snd_pcm_runtime *master_runtime;
@@ -356,45 +326,29 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
356 return 0; 326 return 0;
357} 327}
358 328
359static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
360 struct snd_soc_dai *dai)
361{
362 struct snd_soc_pcm_runtime *rtd = substream->private_data;
363 struct snd_soc_device *socdev = rtd->socdev;
364 struct snd_soc_codec *codec = socdev->card->codec;
365 /* set active */
366 ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
367
368 return 0;
369}
370
371static void ssm2602_shutdown(struct snd_pcm_substream *substream, 329static void ssm2602_shutdown(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai) 330 struct snd_soc_dai *dai)
373{ 331{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 332 struct snd_soc_pcm_runtime *rtd = substream->private_data;
375 struct snd_soc_device *socdev = rtd->socdev; 333 struct snd_soc_codec *codec = rtd->codec;
376 struct snd_soc_codec *codec = socdev->card->codec;
377 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 334 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
378 335
379 /* deactivate */
380 if (!codec->active)
381 ssm2602_write(codec, SSM2602_ACTIVE, 0);
382
383 if (ssm2602->master_substream == substream) 336 if (ssm2602->master_substream == substream)
384 ssm2602->master_substream = ssm2602->slave_substream; 337 ssm2602->master_substream = ssm2602->slave_substream;
385 338
386 ssm2602->slave_substream = NULL; 339 ssm2602->slave_substream = NULL;
387} 340}
388 341
342
389static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 343static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
390{ 344{
391 struct snd_soc_codec *codec = dai->codec; 345 struct snd_soc_codec *codec = dai->codec;
392 u16 mute_reg = ssm2602_read_reg_cache(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; 346 u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE;
393 if (mute) 347 if (mute)
394 ssm2602_write(codec, SSM2602_APDIGI, 348 snd_soc_write(codec, SSM2602_APDIGI,
395 mute_reg | APDIGI_ENABLE_DAC_MUTE); 349 mute_reg | APDIGI_ENABLE_DAC_MUTE);
396 else 350 else
397 ssm2602_write(codec, SSM2602_APDIGI, mute_reg); 351 snd_soc_write(codec, SSM2602_APDIGI, mute_reg);
398 return 0; 352 return 0;
399} 353}
400 354
@@ -470,34 +424,33 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
470 } 424 }
471 425
472 /* set iface */ 426 /* set iface */
473 ssm2602_write(codec, SSM2602_IFACE, iface); 427 snd_soc_write(codec, SSM2602_IFACE, iface);
474 return 0; 428 return 0;
475} 429}
476 430
477static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 431static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
478 enum snd_soc_bias_level level) 432 enum snd_soc_bias_level level)
479{ 433{
480 u16 reg = ssm2602_read_reg_cache(codec, SSM2602_PWR) & 0xff7f; 434 u16 reg = snd_soc_read(codec, SSM2602_PWR) & 0xff7f;
481 435
482 switch (level) { 436 switch (level) {
483 case SND_SOC_BIAS_ON: 437 case SND_SOC_BIAS_ON:
484 /* vref/mid, osc on, dac unmute */ 438 /* vref/mid, osc on, dac unmute */
485 ssm2602_write(codec, SSM2602_PWR, reg); 439 snd_soc_write(codec, SSM2602_PWR, reg);
486 break; 440 break;
487 case SND_SOC_BIAS_PREPARE: 441 case SND_SOC_BIAS_PREPARE:
488 break; 442 break;
489 case SND_SOC_BIAS_STANDBY: 443 case SND_SOC_BIAS_STANDBY:
490 /* everything off except vref/vmid, */ 444 /* everything off except vref/vmid, */
491 ssm2602_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); 445 snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN);
492 break; 446 break;
493 case SND_SOC_BIAS_OFF: 447 case SND_SOC_BIAS_OFF:
494 /* everything off, dac mute, inactive */ 448 /* everything off, dac mute, inactive */
495 ssm2602_write(codec, SSM2602_ACTIVE, 0); 449 snd_soc_write(codec, SSM2602_PWR, 0xffff);
496 ssm2602_write(codec, SSM2602_PWR, 0xffff);
497 break; 450 break;
498 451
499 } 452 }
500 codec->bias_level = level; 453 codec->dapm.bias_level = level;
501 return 0; 454 return 0;
502} 455}
503 456
@@ -510,7 +463,6 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
510 463
511static struct snd_soc_dai_ops ssm2602_dai_ops = { 464static struct snd_soc_dai_ops ssm2602_dai_ops = {
512 .startup = ssm2602_startup, 465 .startup = ssm2602_startup,
513 .prepare = ssm2602_pcm_prepare,
514 .hw_params = ssm2602_hw_params, 466 .hw_params = ssm2602_hw_params,
515 .shutdown = ssm2602_shutdown, 467 .shutdown = ssm2602_shutdown,
516 .digital_mute = ssm2602_mute, 468 .digital_mute = ssm2602_mute,
@@ -518,8 +470,8 @@ static struct snd_soc_dai_ops ssm2602_dai_ops = {
518 .set_fmt = ssm2602_set_dai_fmt, 470 .set_fmt = ssm2602_set_dai_fmt,
519}; 471};
520 472
521struct snd_soc_dai ssm2602_dai = { 473static struct snd_soc_dai_driver ssm2602_dai = {
522 .name = "SSM2602", 474 .name = "ssm2602-hifi",
523 .playback = { 475 .playback = {
524 .stream_name = "Playback", 476 .stream_name = "Playback",
525 .channels_min = 2, 477 .channels_min = 2,
@@ -534,93 +486,162 @@ struct snd_soc_dai ssm2602_dai = {
534 .formats = SSM2602_FORMATS,}, 486 .formats = SSM2602_FORMATS,},
535 .ops = &ssm2602_dai_ops, 487 .ops = &ssm2602_dai_ops,
536}; 488};
537EXPORT_SYMBOL_GPL(ssm2602_dai);
538 489
539static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state) 490static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state)
540{ 491{
541 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
542 struct snd_soc_codec *codec = socdev->card->codec;
543
544 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); 492 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
545 return 0; 493 return 0;
546} 494}
547 495
548static int ssm2602_resume(struct platform_device *pdev) 496static int ssm2602_resume(struct snd_soc_codec *codec)
549{ 497{
550 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 498 snd_soc_cache_sync(codec);
551 struct snd_soc_codec *codec = socdev->card->codec; 499
552 int i;
553 u8 data[2];
554 u16 *cache = codec->reg_cache;
555
556 /* Sync reg_cache with the hardware */
557 for (i = 0; i < ARRAY_SIZE(ssm2602_reg); i++) {
558 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
559 data[1] = cache[i] & 0x00ff;
560 codec->hw_write(codec->control_data, data, 2);
561 }
562 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 500 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
501
563 return 0; 502 return 0;
564} 503}
565 504
566/* 505static int ssm2602_probe(struct snd_soc_codec *codec)
567 * initialise the ssm2602 driver
568 * register the mixer and dsp interfaces with the kernel
569 */
570static int ssm2602_init(struct snd_soc_device *socdev)
571{ 506{
572 struct snd_soc_codec *codec = socdev->card->codec; 507 struct snd_soc_dapm_context *dapm = &codec->dapm;
573 int reg, ret = 0; 508 int ret, reg;
574 509
575 codec->name = "SSM2602"; 510 reg = snd_soc_read(codec, SSM2602_LOUT1V);
576 codec->owner = THIS_MODULE; 511 snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
577 codec->read = ssm2602_read_reg_cache; 512 reg = snd_soc_read(codec, SSM2602_ROUT1V);
578 codec->write = ssm2602_write; 513 snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
579 codec->set_bias_level = ssm2602_set_bias_level;
580 codec->dai = &ssm2602_dai;
581 codec->num_dai = 1;
582 codec->reg_cache_size = sizeof(ssm2602_reg);
583 codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
584 GFP_KERNEL);
585 if (codec->reg_cache == NULL)
586 return -ENOMEM;
587 514
588 ssm2602_reset(codec); 515 ret = snd_soc_add_controls(codec, ssm2602_snd_controls,
516 ARRAY_SIZE(ssm2602_snd_controls));
517 if (ret)
518 return ret;
519
520 ret = snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
521 ARRAY_SIZE(ssm2602_dapm_widgets));
522 if (ret)
523 return ret;
524
525 return snd_soc_dapm_add_routes(dapm, ssm2602_routes,
526 ARRAY_SIZE(ssm2602_routes));
527}
528
529static int ssm2604_probe(struct snd_soc_codec *codec)
530{
531 struct snd_soc_dapm_context *dapm = &codec->dapm;
532 int ret;
533
534 ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
535 ARRAY_SIZE(ssm2604_dapm_widgets));
536 if (ret)
537 return ret;
589 538
590 /* register pcms */ 539 return snd_soc_dapm_add_routes(dapm, ssm2604_routes,
591 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 540 ARRAY_SIZE(ssm2604_routes));
541}
542
543static int ssm260x_probe(struct snd_soc_codec *codec)
544{
545 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
546 int ret, reg;
547
548 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
549
550 ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type);
592 if (ret < 0) { 551 if (ret < 0) {
593 pr_err("ssm2602: failed to create pcms\n"); 552 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
594 goto pcm_err; 553 return ret;
595 } 554 }
596 /*power on device*/ 555
597 ssm2602_write(codec, SSM2602_ACTIVE, 0); 556 ret = ssm2602_reset(codec);
557 if (ret < 0) {
558 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
559 return ret;
560 }
561
598 /* set the update bits */ 562 /* set the update bits */
599 reg = ssm2602_read_reg_cache(codec, SSM2602_LINVOL); 563 reg = snd_soc_read(codec, SSM2602_LINVOL);
600 ssm2602_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); 564 snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH);
601 reg = ssm2602_read_reg_cache(codec, SSM2602_RINVOL); 565 reg = snd_soc_read(codec, SSM2602_RINVOL);
602 ssm2602_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); 566 snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH);
603 reg = ssm2602_read_reg_cache(codec, SSM2602_LOUT1V);
604 ssm2602_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH);
605 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
606 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
607 /*select Line in as default input*/ 567 /*select Line in as default input*/
608 ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 568 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
609 APANA_ENABLE_MIC_BOOST); 569 APANA_ENABLE_MIC_BOOST);
610 ssm2602_write(codec, SSM2602_PWR, 0);
611 570
612 snd_soc_add_controls(codec, ssm2602_snd_controls, 571 switch (ssm2602->type) {
613 ARRAY_SIZE(ssm2602_snd_controls)); 572 case SSM2602:
614 ssm2602_add_widgets(codec); 573 ret = ssm2602_probe(codec);
574 break;
575 case SSM2604:
576 ret = ssm2604_probe(codec);
577 break;
578 }
615 579
616 return ret; 580 return ret;
581}
617 582
618pcm_err: 583/* remove everything here */
619 kfree(codec->reg_cache); 584static int ssm2602_remove(struct snd_soc_codec *codec)
585{
586 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
587 return 0;
588}
589
590static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
591 .probe = ssm260x_probe,
592 .remove = ssm2602_remove,
593 .suspend = ssm2602_suspend,
594 .resume = ssm2602_resume,
595 .set_bias_level = ssm2602_set_bias_level,
596 .reg_cache_size = ARRAY_SIZE(ssm2602_reg),
597 .reg_word_size = sizeof(u16),
598 .reg_cache_default = ssm2602_reg,
599
600 .controls = ssm260x_snd_controls,
601 .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
602 .dapm_widgets = ssm260x_dapm_widgets,
603 .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets),
604 .dapm_routes = ssm260x_routes,
605 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
606};
607
608#if defined(CONFIG_SPI_MASTER)
609static int __devinit ssm2602_spi_probe(struct spi_device *spi)
610{
611 struct ssm2602_priv *ssm2602;
612 int ret;
613
614 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
615 if (ssm2602 == NULL)
616 return -ENOMEM;
617
618 spi_set_drvdata(spi, ssm2602);
619 ssm2602->control_type = SND_SOC_SPI;
620 ssm2602->type = SSM2602;
621
622 ret = snd_soc_register_codec(&spi->dev,
623 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
624 if (ret < 0)
625 kfree(ssm2602);
620 return ret; 626 return ret;
621} 627}
622 628
623static struct snd_soc_device *ssm2602_socdev; 629static int __devexit ssm2602_spi_remove(struct spi_device *spi)
630{
631 snd_soc_unregister_codec(&spi->dev);
632 kfree(spi_get_drvdata(spi));
633 return 0;
634}
635
636static struct spi_driver ssm2602_spi_driver = {
637 .driver = {
638 .name = "ssm2602",
639 .owner = THIS_MODULE,
640 },
641 .probe = ssm2602_spi_probe,
642 .remove = __devexit_p(ssm2602_spi_remove),
643};
644#endif
624 645
625#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 646#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
626/* 647/*
@@ -629,162 +650,87 @@ static struct snd_soc_device *ssm2602_socdev;
629 * low = 0x1a 650 * low = 0x1a
630 * high = 0x1b 651 * high = 0x1b
631 */ 652 */
632static int ssm2602_i2c_probe(struct i2c_client *i2c, 653static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c,
633 const struct i2c_device_id *id) 654 const struct i2c_device_id *id)
634{ 655{
635 struct snd_soc_device *socdev = ssm2602_socdev; 656 struct ssm2602_priv *ssm2602;
636 struct snd_soc_codec *codec = socdev->card->codec;
637 int ret; 657 int ret;
638 658
639 i2c_set_clientdata(i2c, codec); 659 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
640 codec->control_data = i2c; 660 if (ssm2602 == NULL)
661 return -ENOMEM;
641 662
642 ret = ssm2602_init(socdev); 663 i2c_set_clientdata(i2c, ssm2602);
643 if (ret < 0) 664 ssm2602->control_type = SND_SOC_I2C;
644 pr_err("failed to initialise SSM2602\n"); 665 ssm2602->type = id->driver_data;
645 666
667 ret = snd_soc_register_codec(&i2c->dev,
668 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
669 if (ret < 0)
670 kfree(ssm2602);
646 return ret; 671 return ret;
647} 672}
648 673
649static int ssm2602_i2c_remove(struct i2c_client *client) 674static int __devexit ssm2602_i2c_remove(struct i2c_client *client)
650{ 675{
651 struct snd_soc_codec *codec = i2c_get_clientdata(client); 676 snd_soc_unregister_codec(&client->dev);
652 kfree(codec->reg_cache); 677 kfree(i2c_get_clientdata(client));
653 return 0; 678 return 0;
654} 679}
655 680
656static const struct i2c_device_id ssm2602_i2c_id[] = { 681static const struct i2c_device_id ssm2602_i2c_id[] = {
657 { "ssm2602", 0 }, 682 { "ssm2602", SSM2602 },
683 { "ssm2603", SSM2602 },
684 { "ssm2604", SSM2604 },
658 { } 685 { }
659}; 686};
660MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 687MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
688
661/* corgi i2c codec control layer */ 689/* corgi i2c codec control layer */
662static struct i2c_driver ssm2602_i2c_driver = { 690static struct i2c_driver ssm2602_i2c_driver = {
663 .driver = { 691 .driver = {
664 .name = "SSM2602 I2C Codec", 692 .name = "ssm2602",
665 .owner = THIS_MODULE, 693 .owner = THIS_MODULE,
666 }, 694 },
667 .probe = ssm2602_i2c_probe, 695 .probe = ssm2602_i2c_probe,
668 .remove = ssm2602_i2c_remove, 696 .remove = __devexit_p(ssm2602_i2c_remove),
669 .id_table = ssm2602_i2c_id, 697 .id_table = ssm2602_i2c_id,
670}; 698};
671
672static int ssm2602_add_i2c_device(struct platform_device *pdev,
673 const struct ssm2602_setup_data *setup)
674{
675 struct i2c_board_info info;
676 struct i2c_adapter *adapter;
677 struct i2c_client *client;
678 int ret;
679
680 ret = i2c_add_driver(&ssm2602_i2c_driver);
681 if (ret != 0) {
682 dev_err(&pdev->dev, "can't add i2c driver\n");
683 return ret;
684 }
685 memset(&info, 0, sizeof(struct i2c_board_info));
686 info.addr = setup->i2c_address;
687 strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
688 adapter = i2c_get_adapter(setup->i2c_bus);
689 if (!adapter) {
690 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
691 setup->i2c_bus);
692 goto err_driver;
693 }
694 client = i2c_new_device(adapter, &info);
695 i2c_put_adapter(adapter);
696 if (!client) {
697 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
698 (unsigned int)info.addr);
699 goto err_driver;
700 }
701 return 0;
702err_driver:
703 i2c_del_driver(&ssm2602_i2c_driver);
704 return -ENODEV;
705}
706#endif 699#endif
707 700
708static int ssm2602_probe(struct platform_device *pdev) 701
702static int __init ssm2602_modinit(void)
709{ 703{
710 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
711 struct ssm2602_setup_data *setup;
712 struct snd_soc_codec *codec;
713 struct ssm2602_priv *ssm2602;
714 int ret = 0; 704 int ret = 0;
715 705
716 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 706#if defined(CONFIG_SPI_MASTER)
717 707 ret = spi_register_driver(&ssm2602_spi_driver);
718 setup = socdev->codec_data; 708 if (ret)
719 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 709 return ret;
720 if (codec == NULL) 710#endif
721 return -ENOMEM;
722
723 ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
724 if (ssm2602 == NULL) {
725 kfree(codec);
726 return -ENOMEM;
727 }
728
729 snd_soc_codec_set_drvdata(codec, ssm2602);
730 socdev->card->codec = codec;
731 mutex_init(&codec->mutex);
732 INIT_LIST_HEAD(&codec->dapm_widgets);
733 INIT_LIST_HEAD(&codec->dapm_paths);
734 711
735 ssm2602_socdev = socdev;
736#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 712#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
737 if (setup->i2c_address) { 713 ret = i2c_add_driver(&ssm2602_i2c_driver);
738 codec->hw_write = (hw_write_t)i2c_master_send; 714 if (ret)
739 ret = ssm2602_add_i2c_device(pdev, setup); 715 return ret;
740 }
741#else
742 /* other interfaces */
743#endif 716#endif
717
744 return ret; 718 return ret;
745} 719}
720module_init(ssm2602_modinit);
746 721
747/* remove everything here */ 722static void __exit ssm2602_exit(void)
748static int ssm2602_remove(struct platform_device *pdev)
749{ 723{
750 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 724#if defined(CONFIG_SPI_MASTER)
751 struct snd_soc_codec *codec = socdev->card->codec; 725 spi_unregister_driver(&ssm2602_spi_driver);
752 726#endif
753 if (codec->control_data)
754 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
755 727
756 snd_soc_free_pcms(socdev);
757 snd_soc_dapm_free(socdev);
758#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 728#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
759 i2c_unregister_device(codec->control_data);
760 i2c_del_driver(&ssm2602_i2c_driver); 729 i2c_del_driver(&ssm2602_i2c_driver);
761#endif 730#endif
762 kfree(snd_soc_codec_get_drvdata(codec));
763 kfree(codec);
764
765 return 0;
766}
767
768struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
769 .probe = ssm2602_probe,
770 .remove = ssm2602_remove,
771 .suspend = ssm2602_suspend,
772 .resume = ssm2602_resume,
773};
774EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
775
776static int __init ssm2602_modinit(void)
777{
778 return snd_soc_register_dai(&ssm2602_dai);
779}
780module_init(ssm2602_modinit);
781
782static void __exit ssm2602_exit(void)
783{
784 snd_soc_unregister_dai(&ssm2602_dai);
785} 731}
786module_exit(ssm2602_exit); 732module_exit(ssm2602_exit);
787 733
788MODULE_DESCRIPTION("ASoC ssm2602 driver"); 734MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver");
789MODULE_AUTHOR("Cliff Cai"); 735MODULE_AUTHOR("Cliff Cai");
790MODULE_LICENSE("GPL"); 736MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index f344e6d76e31..b98c69168036 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -117,14 +117,5 @@
117#define SSM2602_CACHEREGNUM 10 117#define SSM2602_CACHEREGNUM 10
118 118
119#define SSM2602_SYSCLK 0 119#define SSM2602_SYSCLK 0
120#define SSM2602_DAI 0
121
122struct ssm2602_setup_data {
123 int i2c_bus;
124 unsigned short i2c_address;
125};
126
127extern struct snd_soc_dai ssm2602_dai;
128extern struct snd_soc_codec_device soc_codec_dev_ssm2602;
129 120
130#endif 121#endif
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index ee86568545c2..78b2b50271e2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -25,7 +25,6 @@
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/tlv.h> 27#include <sound/tlv.h>
28#include <sound/soc-of-simple.h>
29 28
30#include "stac9766.h" 29#include "stac9766.h"
31 30
@@ -237,7 +236,7 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
237 stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff); 236 stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
238 break; 237 break;
239 } 238 }
240 codec->bias_level = level; 239 codec->dapm.bias_level = level;
241 return 0; 240 return 0;
242} 241}
243 242
@@ -257,20 +256,15 @@ static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
257 return 0; 256 return 0;
258} 257}
259 258
260static int stac9766_codec_suspend(struct platform_device *pdev, 259static int stac9766_codec_suspend(struct snd_soc_codec *codec,
261 pm_message_t state) 260 pm_message_t state)
262{ 261{
263 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
264 struct snd_soc_codec *codec = socdev->card->codec;
265
266 stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF); 262 stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
267 return 0; 263 return 0;
268} 264}
269 265
270static int stac9766_codec_resume(struct platform_device *pdev) 266static int stac9766_codec_resume(struct snd_soc_codec *codec)
271{ 267{
272 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
273 struct snd_soc_codec *codec = socdev->card->codec;
274 u16 id, reset; 268 u16 id, reset;
275 269
276 reset = 0; 270 reset = 0;
@@ -300,10 +294,9 @@ static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
300 .prepare = ac97_digital_prepare, 294 .prepare = ac97_digital_prepare,
301}; 295};
302 296
303struct snd_soc_dai stac9766_dai[] = { 297static struct snd_soc_dai_driver stac9766_dai[] = {
304{ 298{
305 .name = "stac9766 analog", 299 .name = "stac9766-hifi-analog",
306 .id = 0,
307 .ac97_control = 1, 300 .ac97_control = 1,
308 301
309 /* stream cababilities */ 302 /* stream cababilities */
@@ -325,8 +318,7 @@ struct snd_soc_dai stac9766_dai[] = {
325 .ops = &stac9766_dai_ops_analog, 318 .ops = &stac9766_dai_ops_analog,
326}, 319},
327{ 320{
328 .name = "stac9766 IEC958", 321 .name = "stac9766-hifi-IEC958",
329 .id = 1,
330 .ac97_control = 1, 322 .ac97_control = 1,
331 323
332 /* stream cababilities */ 324 /* stream cababilities */
@@ -342,57 +334,24 @@ struct snd_soc_dai stac9766_dai[] = {
342 .ops = &stac9766_dai_ops_digital, 334 .ops = &stac9766_dai_ops_digital,
343} 335}
344}; 336};
345EXPORT_SYMBOL_GPL(stac9766_dai);
346 337
347static int stac9766_codec_probe(struct platform_device *pdev) 338static int stac9766_codec_probe(struct snd_soc_codec *codec)
348{ 339{
349 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
350 struct snd_soc_codec *codec;
351 int ret = 0; 340 int ret = 0;
352 341
353 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); 342 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
354 343
355 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
356 if (socdev->card->codec == NULL)
357 return -ENOMEM;
358 codec = socdev->card->codec;
359 mutex_init(&codec->mutex);
360
361 codec->reg_cache = kmemdup(stac9766_reg, sizeof(stac9766_reg),
362 GFP_KERNEL);
363 if (codec->reg_cache == NULL) {
364 ret = -ENOMEM;
365 goto cache_err;
366 }
367 codec->reg_cache_size = sizeof(stac9766_reg);
368 codec->reg_cache_step = 2;
369
370 codec->name = "STAC9766";
371 codec->owner = THIS_MODULE;
372 codec->dai = stac9766_dai;
373 codec->num_dai = ARRAY_SIZE(stac9766_dai);
374 codec->write = stac9766_ac97_write;
375 codec->read = stac9766_ac97_read;
376 codec->set_bias_level = stac9766_set_bias_level;
377 INIT_LIST_HEAD(&codec->dapm_widgets);
378 INIT_LIST_HEAD(&codec->dapm_paths);
379
380 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 344 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
381 if (ret < 0) 345 if (ret < 0)
382 goto codec_err; 346 goto codec_err;
383 347
384 /* register pcms */
385 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
386 if (ret < 0)
387 goto pcm_err;
388
389 /* do a cold reset for the controller and then try 348 /* do a cold reset for the controller and then try
390 * a warm reset followed by an optional cold reset for codec */ 349 * a warm reset followed by an optional cold reset for codec */
391 stac9766_reset(codec, 0); 350 stac9766_reset(codec, 0);
392 ret = stac9766_reset(codec, 1); 351 ret = stac9766_reset(codec, 1);
393 if (ret < 0) { 352 if (ret < 0) {
394 printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n"); 353 printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
395 goto reset_err; 354 goto codec_err;
396 } 355 }
397 356
398 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 357 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -402,40 +361,64 @@ static int stac9766_codec_probe(struct platform_device *pdev)
402 361
403 return 0; 362 return 0;
404 363
405reset_err:
406 snd_soc_free_pcms(socdev);
407pcm_err:
408 snd_soc_free_ac97_codec(codec);
409codec_err: 364codec_err:
410 kfree(snd_soc_codec_get_drvdata(codec)); 365 snd_soc_free_ac97_codec(codec);
411cache_err:
412 kfree(socdev->card->codec);
413 socdev->card->codec = NULL;
414 return ret; 366 return ret;
415} 367}
416 368
417static int stac9766_codec_remove(struct platform_device *pdev) 369static int stac9766_codec_remove(struct snd_soc_codec *codec)
418{ 370{
419 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
420 struct snd_soc_codec *codec = socdev->card->codec;
421
422 if (codec == NULL)
423 return 0;
424
425 snd_soc_free_pcms(socdev);
426 snd_soc_free_ac97_codec(codec); 371 snd_soc_free_ac97_codec(codec);
427 kfree(codec->reg_cache);
428 kfree(codec);
429 return 0; 372 return 0;
430} 373}
431 374
432struct snd_soc_codec_device soc_codec_dev_stac9766 = { 375static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
376 .write = stac9766_ac97_write,
377 .read = stac9766_ac97_read,
378 .set_bias_level = stac9766_set_bias_level,
433 .probe = stac9766_codec_probe, 379 .probe = stac9766_codec_probe,
434 .remove = stac9766_codec_remove, 380 .remove = stac9766_codec_remove,
435 .suspend = stac9766_codec_suspend, 381 .suspend = stac9766_codec_suspend,
436 .resume = stac9766_codec_resume, 382 .resume = stac9766_codec_resume,
383 .reg_cache_size = sizeof(stac9766_reg),
384 .reg_word_size = sizeof(u16),
385 .reg_cache_step = 2,
386 .reg_cache_default = stac9766_reg,
387};
388
389static __devinit int stac9766_probe(struct platform_device *pdev)
390{
391 return snd_soc_register_codec(&pdev->dev,
392 &soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
393}
394
395static int __devexit stac9766_remove(struct platform_device *pdev)
396{
397 snd_soc_unregister_codec(&pdev->dev);
398 return 0;
399}
400
401static struct platform_driver stac9766_codec_driver = {
402 .driver = {
403 .name = "stac9766-codec",
404 .owner = THIS_MODULE,
405 },
406
407 .probe = stac9766_probe,
408 .remove = __devexit_p(stac9766_remove),
437}; 409};
438EXPORT_SYMBOL_GPL(soc_codec_dev_stac9766); 410
411static int __init stac9766_init(void)
412{
413 return platform_driver_register(&stac9766_codec_driver);
414}
415module_init(stac9766_init);
416
417static void __exit stac9766_exit(void)
418{
419 platform_driver_unregister(&stac9766_codec_driver);
420}
421module_exit(stac9766_exit);
439 422
440MODULE_DESCRIPTION("ASoC stac9766 driver"); 423MODULE_DESCRIPTION("ASoC stac9766 driver");
441MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); 424MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
diff --git a/sound/soc/codecs/stac9766.h b/sound/soc/codecs/stac9766.h
index 65642eb8393e..c726f907e2c0 100644
--- a/sound/soc/codecs/stac9766.h
+++ b/sound/soc/codecs/stac9766.h
@@ -14,8 +14,4 @@
14#define STAC9766_DAI_AC97_ANALOG 0 14#define STAC9766_DAI_AC97_ANALOG 0
15#define STAC9766_DAI_AC97_DIGITAL 1 15#define STAC9766_DAI_AC97_DIGITAL 1
16 16
17extern struct snd_soc_dai stac9766_dai[];
18extern struct snd_soc_codec_device soc_codec_dev_stac9766;
19
20
21#endif 17#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 0a4b0fef3355..33bb52f3f683 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -30,7 +30,6 @@
30#include <sound/pcm.h> 30#include <sound/pcm.h>
31#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <sound/tlv.h> 33#include <sound/tlv.h>
35#include <sound/initval.h> 34#include <sound/initval.h>
36 35
@@ -213,7 +212,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
213 SND_SOC_DAPM_INPUT("MICIN"), 212 SND_SOC_DAPM_INPUT("MICIN"),
214}; 213};
215 214
216static const struct snd_soc_dapm_route intercon[] = { 215static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
217 /* Output Mixer */ 216 /* Output Mixer */
218 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 217 {"Output Mixer", "Line Bypass Switch", "Line Input"},
219 {"Output Mixer", "Playback Switch", "DAC"}, 218 {"Output Mixer", "Playback Switch", "DAC"},
@@ -240,7 +239,8 @@ static const struct snd_soc_dapm_route intercon[] = {
240 239
241/* AIC23 driver data */ 240/* AIC23 driver data */
242struct aic23 { 241struct aic23 {
243 struct snd_soc_codec codec; 242 enum snd_soc_control_type control_type;
243 void *control_data;
244 int mclk; 244 int mclk;
245 int requested_adc; 245 int requested_adc;
246 int requested_dac; 246 int requested_dac;
@@ -388,27 +388,15 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
388 return 0; 388 return 0;
389} 389}
390 390
391static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
392{
393 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
394 ARRAY_SIZE(tlv320aic23_dapm_widgets));
395
396 /* set up audio path interconnects */
397 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
398
399 return 0;
400}
401
402static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 391static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
403 struct snd_pcm_hw_params *params, 392 struct snd_pcm_hw_params *params,
404 struct snd_soc_dai *dai) 393 struct snd_soc_dai *dai)
405{ 394{
406 struct snd_soc_pcm_runtime *rtd = substream->private_data; 395 struct snd_soc_pcm_runtime *rtd = substream->private_data;
407 struct snd_soc_device *socdev = rtd->socdev; 396 struct snd_soc_codec *codec = rtd->codec;
408 struct snd_soc_codec *codec = socdev->card->codec;
409 u16 iface_reg; 397 u16 iface_reg;
410 int ret; 398 int ret;
411 struct aic23 *aic23 = container_of(codec, struct aic23, codec); 399 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
412 u32 sample_rate_adc = aic23->requested_adc; 400 u32 sample_rate_adc = aic23->requested_adc;
413 u32 sample_rate_dac = aic23->requested_dac; 401 u32 sample_rate_dac = aic23->requested_dac;
414 u32 sample_rate = params_rate(params); 402 u32 sample_rate = params_rate(params);
@@ -452,8 +440,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
452 struct snd_soc_dai *dai) 440 struct snd_soc_dai *dai)
453{ 441{
454 struct snd_soc_pcm_runtime *rtd = substream->private_data; 442 struct snd_soc_pcm_runtime *rtd = substream->private_data;
455 struct snd_soc_device *socdev = rtd->socdev; 443 struct snd_soc_codec *codec = rtd->codec;
456 struct snd_soc_codec *codec = socdev->card->codec;
457 444
458 /* set active */ 445 /* set active */
459 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 446 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
@@ -465,9 +452,8 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
465 struct snd_soc_dai *dai) 452 struct snd_soc_dai *dai)
466{ 453{
467 struct snd_soc_pcm_runtime *rtd = substream->private_data; 454 struct snd_soc_pcm_runtime *rtd = substream->private_data;
468 struct snd_soc_device *socdev = rtd->socdev; 455 struct snd_soc_codec *codec = rtd->codec;
469 struct snd_soc_codec *codec = socdev->card->codec; 456 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
470 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
471 457
472 /* deactivate */ 458 /* deactivate */
473 if (!codec->active) { 459 if (!codec->active) {
@@ -546,8 +532,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
546static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, 532static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
547 int clk_id, unsigned int freq, int dir) 533 int clk_id, unsigned int freq, int dir)
548{ 534{
549 struct snd_soc_codec *codec = codec_dai->codec; 535 struct aic23 *aic23 = snd_soc_dai_get_drvdata(codec_dai);
550 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
551 aic23->mclk = freq; 536 aic23->mclk = freq;
552 return 0; 537 return 0;
553} 538}
@@ -577,7 +562,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
577 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); 562 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
578 break; 563 break;
579 } 564 }
580 codec->bias_level = level; 565 codec->dapm.bias_level = level;
581 return 0; 566 return 0;
582} 567}
583 568
@@ -594,8 +579,8 @@ static struct snd_soc_dai_ops tlv320aic23_dai_ops = {
594 .set_sysclk = tlv320aic23_set_dai_sysclk, 579 .set_sysclk = tlv320aic23_set_dai_sysclk,
595}; 580};
596 581
597struct snd_soc_dai tlv320aic23_dai = { 582static struct snd_soc_dai_driver tlv320aic23_dai = {
598 .name = "tlv320aic23", 583 .name = "tlv320aic23-hifi",
599 .playback = { 584 .playback = {
600 .stream_name = "Playback", 585 .stream_name = "Playback",
601 .channels_min = 2, 586 .channels_min = 2,
@@ -610,23 +595,17 @@ struct snd_soc_dai tlv320aic23_dai = {
610 .formats = AIC23_FORMATS,}, 595 .formats = AIC23_FORMATS,},
611 .ops = &tlv320aic23_dai_ops, 596 .ops = &tlv320aic23_dai_ops,
612}; 597};
613EXPORT_SYMBOL_GPL(tlv320aic23_dai);
614 598
615static int tlv320aic23_suspend(struct platform_device *pdev, 599static int tlv320aic23_suspend(struct snd_soc_codec *codec,
616 pm_message_t state) 600 pm_message_t state)
617{ 601{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619 struct snd_soc_codec *codec = socdev->card->codec;
620
621 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 602 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
622 603
623 return 0; 604 return 0;
624} 605}
625 606
626static int tlv320aic23_resume(struct platform_device *pdev) 607static int tlv320aic23_resume(struct snd_soc_codec *codec)
627{ 608{
628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
629 struct snd_soc_codec *codec = socdev->card->codec;
630 u16 reg; 609 u16 reg;
631 610
632 /* Sync reg_cache with the hardware */ 611 /* Sync reg_cache with the hardware */
@@ -639,39 +618,19 @@ static int tlv320aic23_resume(struct platform_device *pdev)
639 return 0; 618 return 0;
640} 619}
641 620
642/* 621static int tlv320aic23_probe(struct snd_soc_codec *codec)
643 * initialise the AIC23 driver
644 * register the mixer and dsp interfaces with the kernel
645 */
646static int tlv320aic23_init(struct snd_soc_device *socdev)
647{ 622{
648 struct snd_soc_codec *codec = socdev->card->codec; 623 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
649 int ret = 0; 624 int reg;
650 u16 reg;
651 625
652 codec->name = "tlv320aic23"; 626 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
653 codec->owner = THIS_MODULE; 627 codec->control_data = aic23->control_data;
654 codec->read = tlv320aic23_read_reg_cache; 628 codec->hw_write = (hw_write_t)i2c_master_send;
655 codec->write = tlv320aic23_write; 629 codec->hw_read = NULL;
656 codec->set_bias_level = tlv320aic23_set_bias_level;
657 codec->dai = &tlv320aic23_dai;
658 codec->num_dai = 1;
659 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
660 codec->reg_cache =
661 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
662 if (codec->reg_cache == NULL)
663 return -ENOMEM;
664 630
665 /* Reset codec */ 631 /* Reset codec */
666 tlv320aic23_write(codec, TLV320AIC23_RESET, 0); 632 tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
667 633
668 /* register pcms */
669 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
670 if (ret < 0) {
671 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
672 goto pcm_err;
673 }
674
675 /* power on device */ 634 /* power on device */
676 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 635 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
677 636
@@ -705,15 +664,32 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
705 664
706 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 665 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
707 ARRAY_SIZE(tlv320aic23_snd_controls)); 666 ARRAY_SIZE(tlv320aic23_snd_controls));
708 tlv320aic23_add_widgets(codec);
709 667
710 return ret; 668 return 0;
669}
711 670
712pcm_err: 671static int tlv320aic23_remove(struct snd_soc_codec *codec)
713 kfree(codec->reg_cache); 672{
714 return ret; 673 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
674 return 0;
715} 675}
716static struct snd_soc_device *tlv320aic23_socdev; 676
677static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
678 .reg_cache_size = ARRAY_SIZE(tlv320aic23_reg),
679 .reg_word_size = sizeof(u16),
680 .reg_cache_default = tlv320aic23_reg,
681 .probe = tlv320aic23_probe,
682 .remove = tlv320aic23_remove,
683 .suspend = tlv320aic23_suspend,
684 .resume = tlv320aic23_resume,
685 .read = tlv320aic23_read_reg_cache,
686 .write = tlv320aic23_write,
687 .set_bias_level = tlv320aic23_set_bias_level,
688 .dapm_widgets = tlv320aic23_dapm_widgets,
689 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
690 .dapm_routes = tlv320aic23_intercon,
691 .num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
692};
717 693
718#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
719/* 695/*
@@ -723,31 +699,30 @@ static struct snd_soc_device *tlv320aic23_socdev;
723static int tlv320aic23_codec_probe(struct i2c_client *i2c, 699static int tlv320aic23_codec_probe(struct i2c_client *i2c,
724 const struct i2c_device_id *i2c_id) 700 const struct i2c_device_id *i2c_id)
725{ 701{
726 struct snd_soc_device *socdev = tlv320aic23_socdev; 702 struct aic23 *aic23;
727 struct snd_soc_codec *codec = socdev->card->codec;
728 int ret; 703 int ret;
729 704
730 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 705 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
731 return -EINVAL; 706 return -EINVAL;
732 707
733 i2c_set_clientdata(i2c, codec); 708 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
734 codec->control_data = i2c; 709 if (aic23 == NULL)
710 return -ENOMEM;
735 711
736 ret = tlv320aic23_init(socdev); 712 i2c_set_clientdata(i2c, aic23);
737 if (ret < 0) { 713 aic23->control_data = i2c;
738 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n"); 714 aic23->control_type = SND_SOC_I2C;
739 goto err;
740 }
741 return ret;
742 715
743err: 716 ret = snd_soc_register_codec(&i2c->dev,
744 kfree(codec); 717 &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
745 kfree(i2c); 718 if (ret < 0)
719 kfree(aic23);
746 return ret; 720 return ret;
747} 721}
748static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) 722static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
749{ 723{
750 put_device(&i2c->dev); 724 snd_soc_unregister_codec(&i2c->dev);
725 kfree(i2c_get_clientdata(i2c));
751 return 0; 726 return 0;
752} 727}
753 728
@@ -760,7 +735,7 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
760 735
761static struct i2c_driver tlv320aic23_i2c_driver = { 736static struct i2c_driver tlv320aic23_i2c_driver = {
762 .driver = { 737 .driver = {
763 .name = "tlv320aic23", 738 .name = "tlv320aic23-codec",
764 }, 739 },
765 .probe = tlv320aic23_codec_probe, 740 .probe = tlv320aic23_codec_probe,
766 .remove = __exit_p(tlv320aic23_i2c_remove), 741 .remove = __exit_p(tlv320aic23_i2c_remove),
@@ -769,71 +744,25 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
769 744
770#endif 745#endif
771 746
772static int tlv320aic23_probe(struct platform_device *pdev) 747static int __init tlv320aic23_modinit(void)
773{ 748{
774 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 749 int ret;
775 struct snd_soc_codec *codec;
776 struct aic23 *aic23;
777 int ret = 0;
778
779 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
780
781 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
782 if (aic23 == NULL)
783 return -ENOMEM;
784 codec = &aic23->codec;
785 socdev->card->codec = codec;
786 mutex_init(&codec->mutex);
787 INIT_LIST_HEAD(&codec->dapm_widgets);
788 INIT_LIST_HEAD(&codec->dapm_paths);
789
790 tlv320aic23_socdev = socdev;
791#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 750#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
792 codec->hw_write = (hw_write_t) i2c_master_send;
793 codec->hw_read = NULL;
794 ret = i2c_add_driver(&tlv320aic23_i2c_driver); 751 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
795 if (ret != 0) 752 if (ret != 0) {
796 printk(KERN_ERR "can't add i2c driver"); 753 printk(KERN_ERR "Failed to register TLV320AIC23 I2C driver: %d\n",
754 ret);
755 }
797#endif 756#endif
798 return ret; 757 return ret;
799} 758}
759module_init(tlv320aic23_modinit);
800 760
801static int tlv320aic23_remove(struct platform_device *pdev) 761static void __exit tlv320aic23_exit(void)
802{ 762{
803 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
804 struct snd_soc_codec *codec = socdev->card->codec;
805 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
806
807 if (codec->control_data)
808 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
809
810 snd_soc_free_pcms(socdev);
811 snd_soc_dapm_free(socdev);
812#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 763#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
813 i2c_del_driver(&tlv320aic23_i2c_driver); 764 i2c_del_driver(&tlv320aic23_i2c_driver);
814#endif 765#endif
815 kfree(codec->reg_cache);
816 kfree(aic23);
817
818 return 0;
819}
820struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
821 .probe = tlv320aic23_probe,
822 .remove = tlv320aic23_remove,
823 .suspend = tlv320aic23_suspend,
824 .resume = tlv320aic23_resume,
825};
826EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
827
828static int __init tlv320aic23_modinit(void)
829{
830 return snd_soc_register_dai(&tlv320aic23_dai);
831}
832module_init(tlv320aic23_modinit);
833
834static void __exit tlv320aic23_exit(void)
835{
836 snd_soc_unregister_dai(&tlv320aic23_dai);
837} 766}
838module_exit(tlv320aic23_exit); 767module_exit(tlv320aic23_exit);
839 768
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
index 79d1faf8e570..e804120bd3da 100644
--- a/sound/soc/codecs/tlv320aic23.h
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -116,7 +116,4 @@
116#define TLV320AIC23_SIDETONE_12 0x080 116#define TLV320AIC23_SIDETONE_12 0x080
117#define TLV320AIC23_SIDETONE_18 0x0c0 117#define TLV320AIC23_SIDETONE_18 0x0c0
118 118
119extern struct snd_soc_dai tlv320aic23_dai;
120extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
121
122#endif /* _TLV320AIC23_H */ 119#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index f0e00fd4b435..7859bdcc93db 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -18,8 +18,6 @@
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/soc-of-simple.h>
23#include <sound/initval.h> 21#include <sound/initval.h>
24 22
25#include "tlv320aic26.h" 23#include "tlv320aic26.h"
@@ -32,7 +30,6 @@ MODULE_LICENSE("GPL");
32struct aic26 { 30struct aic26 {
33 struct spi_device *spi; 31 struct spi_device *spi;
34 struct snd_soc_codec codec; 32 struct snd_soc_codec codec;
35 u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
36 int master; 33 int master;
37 int datfm; 34 int datfm;
38 int mclk; 35 int mclk;
@@ -130,8 +127,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
130 struct snd_soc_dai *dai) 127 struct snd_soc_dai *dai)
131{ 128{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_device *socdev = rtd->socdev; 130 struct snd_soc_codec *codec = rtd->codec;
134 struct snd_soc_codec *codec = socdev->card->codec;
135 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec); 131 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
136 int fsref, divisor, wlen, pval, jval, dval, qval; 132 int fsref, divisor, wlen, pval, jval, dval, qval;
137 u16 reg; 133 u16 reg;
@@ -165,10 +161,18 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
165 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL; 161 dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL;
166 } 162 }
167 163
168 /* Configure PLL */ 164 /**
165 * Configure PLL
166 * fsref = (mclk * PLLM) / 2048
167 * where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal)
168 */
169 pval = 1; 169 pval = 1;
170 jval = (fsref == 44100) ? 7 : 8; 170 /* compute J portion of multiplier */
171 dval = (fsref == 44100) ? 5264 : 1920; 171 jval = fsref / (aic26->mclk / 2048);
172 /* compute fractional DDDD component of multiplier */
173 dval = fsref - (jval * (aic26->mclk / 2048));
174 dval = (10000 * dval) / (aic26->mclk / 2048);
175 dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
172 qval = 0; 176 qval = 0;
173 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2; 177 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
174 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg); 178 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg);
@@ -278,8 +282,8 @@ static struct snd_soc_dai_ops aic26_dai_ops = {
278 .set_fmt = aic26_set_fmt, 282 .set_fmt = aic26_set_fmt,
279}; 283};
280 284
281struct snd_soc_dai aic26_dai = { 285static struct snd_soc_dai_driver aic26_dai = {
282 .name = "tlv320aic26", 286 .name = "tlv320aic26-hifi",
283 .playback = { 287 .playback = {
284 .stream_name = "Playback", 288 .stream_name = "Playback",
285 .channels_min = 2, 289 .channels_min = 2,
@@ -296,7 +300,6 @@ struct snd_soc_dai aic26_dai = {
296 }, 300 },
297 .ops = &aic26_dai_ops, 301 .ops = &aic26_dai_ops,
298}; 302};
299EXPORT_SYMBOL_GPL(aic26_dai);
300 303
301/* --------------------------------------------------------------------- 304/* ---------------------------------------------------------------------
302 * ALSA controls 305 * ALSA controls
@@ -319,61 +322,6 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = {
319}; 322};
320 323
321/* --------------------------------------------------------------------- 324/* ---------------------------------------------------------------------
322 * SoC CODEC portion of driver: probe and release routines
323 */
324static int aic26_probe(struct platform_device *pdev)
325{
326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
327 struct snd_soc_codec *codec;
328 struct aic26 *aic26;
329 int ret, err;
330
331 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
332 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
333 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
334
335 /* Fetch the relevant aic26 private data here (it's already been
336 * stored in the .codec pointer) */
337 aic26 = socdev->codec_data;
338 if (aic26 == NULL) {
339 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
340 return -ENODEV;
341 }
342 codec = &aic26->codec;
343 socdev->card->codec = codec;
344
345 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
346 &pdev->dev, socdev->dev);
347 /* register pcms */
348 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
349 if (ret < 0) {
350 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
351 return -ENODEV;
352 }
353
354 /* register controls */
355 dev_dbg(&pdev->dev, "Registering controls\n");
356 err = snd_soc_add_controls(codec, aic26_snd_controls,
357 ARRAY_SIZE(aic26_snd_controls));
358 WARN_ON(err < 0);
359
360 return 0;
361}
362
363static int aic26_remove(struct platform_device *pdev)
364{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
366 snd_soc_free_pcms(socdev);
367 return 0;
368}
369
370struct snd_soc_codec_device aic26_soc_codec_dev = {
371 .probe = aic26_probe,
372 .remove = aic26_remove,
373};
374EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
375
376/* ---------------------------------------------------------------------
377 * SPI device portion of driver: sysfs files for debugging 325 * SPI device portion of driver: sysfs files for debugging
378 */ 326 */
379 327
@@ -409,13 +357,61 @@ static ssize_t aic26_keyclick_set(struct device *dev,
409static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set); 357static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
410 358
411/* --------------------------------------------------------------------- 359/* ---------------------------------------------------------------------
360 * SoC CODEC portion of driver: probe and release routines
361 */
362static int aic26_probe(struct snd_soc_codec *codec)
363{
364 int ret, err, i, reg;
365
366 dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
367
368 /* Reset the codec to power on defaults */
369 aic26_reg_write(codec, AIC26_REG_RESET, 0xBB00);
370
371 /* Power up CODEC */
372 aic26_reg_write(codec, AIC26_REG_POWER_CTRL, 0);
373
374 /* Audio Control 3 (master mode, fsref rate) */
375 reg = aic26_reg_read(codec, AIC26_REG_AUDIO_CTRL3);
376 reg &= ~0xf800;
377 reg |= 0x0800; /* set master mode */
378 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
379
380 /* Fill register cache */
381 for (i = 0; i < codec->driver->reg_cache_size; i++)
382 aic26_reg_read(codec, i);
383
384 /* Register the sysfs files for debugging */
385 /* Create SysFS files */
386 ret = device_create_file(codec->dev, &dev_attr_keyclick);
387 if (ret)
388 dev_info(codec->dev, "error creating sysfs files\n");
389
390 /* register controls */
391 dev_dbg(codec->dev, "Registering controls\n");
392 err = snd_soc_add_controls(codec, aic26_snd_controls,
393 ARRAY_SIZE(aic26_snd_controls));
394 WARN_ON(err < 0);
395
396 return 0;
397}
398
399static struct snd_soc_codec_driver aic26_soc_codec_dev = {
400 .probe = aic26_probe,
401 .read = aic26_reg_read,
402 .write = aic26_reg_write,
403 .reg_cache_size = AIC26_NUM_REGS,
404 .reg_word_size = sizeof(u16),
405};
406
407/* ---------------------------------------------------------------------
412 * SPI device portion of driver: probe and release routines and SPI 408 * SPI device portion of driver: probe and release routines and SPI
413 * driver registration. 409 * driver registration.
414 */ 410 */
415static int aic26_spi_probe(struct spi_device *spi) 411static int aic26_spi_probe(struct spi_device *spi)
416{ 412{
417 struct aic26 *aic26; 413 struct aic26 *aic26;
418 int ret, i, reg; 414 int ret;
419 415
420 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n"); 416 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
421 417
@@ -427,59 +423,13 @@ static int aic26_spi_probe(struct spi_device *spi)
427 /* Initialize the driver data */ 423 /* Initialize the driver data */
428 aic26->spi = spi; 424 aic26->spi = spi;
429 dev_set_drvdata(&spi->dev, aic26); 425 dev_set_drvdata(&spi->dev, aic26);
430
431 /* Setup what we can in the codec structure so that the register
432 * access functions will work as expected. More will be filled
433 * out when it is probed by the SoC CODEC part of this driver */
434 snd_soc_codec_set_drvdata(&aic26->codec, aic26);
435 aic26->codec.name = "aic26";
436 aic26->codec.owner = THIS_MODULE;
437 aic26->codec.dai = &aic26_dai;
438 aic26->codec.num_dai = 1;
439 aic26->codec.read = aic26_reg_read;
440 aic26->codec.write = aic26_reg_write;
441 aic26->master = 1; 426 aic26->master = 1;
442 mutex_init(&aic26->codec.mutex);
443 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
444 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
445 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
446 aic26->codec.reg_cache = aic26->reg_cache;
447
448 aic26_dai.dev = &spi->dev;
449 ret = snd_soc_register_dai(&aic26_dai);
450 if (ret != 0) {
451 dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
452 kfree(aic26);
453 return ret;
454 }
455
456 /* Reset the codec to power on defaults */
457 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
458
459 /* Power up CODEC */
460 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0);
461
462 /* Audio Control 3 (master mode, fsref rate) */
463 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3);
464 reg &= ~0xf800;
465 reg |= 0x0800; /* set master mode */
466 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg);
467 427
468 /* Fill register cache */ 428 ret = snd_soc_register_codec(&spi->dev,
469 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++) 429 &aic26_soc_codec_dev, &aic26_dai, 1);
470 aic26_reg_read(&aic26->codec, i); 430 if (ret < 0)
471 431 kfree(aic26);
472 /* Register the sysfs files for debugging */ 432 return ret;
473 /* Create SysFS files */
474 ret = device_create_file(&spi->dev, &dev_attr_keyclick);
475 if (ret)
476 dev_info(&spi->dev, "error creating sysfs files\n");
477
478#if defined(CONFIG_SND_SOC_OF_SIMPLE)
479 /* Tell the of_soc helper about this codec */
480 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai,
481 spi->dev.archdata.of_node);
482#endif
483 433
484 dev_dbg(&spi->dev, "SPI device initialized\n"); 434 dev_dbg(&spi->dev, "SPI device initialized\n");
485 return 0; 435 return 0;
@@ -487,17 +437,14 @@ static int aic26_spi_probe(struct spi_device *spi)
487 437
488static int aic26_spi_remove(struct spi_device *spi) 438static int aic26_spi_remove(struct spi_device *spi)
489{ 439{
490 struct aic26 *aic26 = dev_get_drvdata(&spi->dev); 440 snd_soc_unregister_codec(&spi->dev);
491 441 kfree(spi_get_drvdata(spi));
492 snd_soc_unregister_dai(&aic26_dai);
493 kfree(aic26);
494
495 return 0; 442 return 0;
496} 443}
497 444
498static struct spi_driver aic26_spi = { 445static struct spi_driver aic26_spi = {
499 .driver = { 446 .driver = {
500 .name = "tlv320aic26", 447 .name = "tlv320aic26-codec",
501 .owner = THIS_MODULE, 448 .owner = THIS_MODULE,
502 }, 449 },
503 .probe = aic26_spi_probe, 450 .probe = aic26_spi_probe,
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
index 786ba16c945f..67f19c3bebe6 100644
--- a/sound/soc/codecs/tlv320aic26.h
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -14,14 +14,14 @@
14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset) 14#define AIC26_PAGE_ADDR(page, offset) ((page << 6) | offset)
15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0) 15#define AIC26_NUM_REGS AIC26_PAGE_ADDR(3, 0)
16 16
17/* Page 0: Auxillary data registers */ 17/* Page 0: Auxiliary data registers */
18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05) 18#define AIC26_REG_BAT1 AIC26_PAGE_ADDR(0, 0x05)
19#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06) 19#define AIC26_REG_BAT2 AIC26_PAGE_ADDR(0, 0x06)
20#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07) 20#define AIC26_REG_AUX AIC26_PAGE_ADDR(0, 0x07)
21#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09) 21#define AIC26_REG_TEMP1 AIC26_PAGE_ADDR(0, 0x09)
22#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A) 22#define AIC26_REG_TEMP2 AIC26_PAGE_ADDR(0, 0x0A)
23 23
24/* Page 1: Auxillary control registers */ 24/* Page 1: Auxiliary control registers */
25#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00) 25#define AIC26_REG_AUX_ADC AIC26_PAGE_ADDR(1, 0x00)
26#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01) 26#define AIC26_REG_STATUS AIC26_PAGE_ADDR(1, 0x01)
27#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03) 27#define AIC26_REG_REFERENCE AIC26_PAGE_ADDR(1, 0x03)
@@ -90,7 +90,4 @@ enum aic26_wlen {
90 AIC26_WLEN_32 = 3 << 10, 90 AIC26_WLEN_32 = 3 << 10,
91}; 91};
92 92
93extern struct snd_soc_dai aic26_dai;
94extern struct snd_soc_codec_device aic26_soc_codec_dev;
95
96#endif /* _TLV320AIC16_H_ */ 93#endif /* _TLV320AIC16_H_ */
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
new file mode 100644
index 000000000000..e93b9d1ae1dd
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -0,0 +1,794 @@
1/*
2 * linux/sound/soc/codecs/tlv320aic32x4.c
3 *
4 * Copyright 2011 Vista Silicon S.L.
5 *
6 * Author: Javier Martin <javier.martin@vista-silicon.com>
7 *
8 * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02110-1301, USA.
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/pm.h>
31#include <linux/i2c.h>
32#include <linux/platform_device.h>
33#include <linux/cdev.h>
34#include <linux/slab.h>
35
36#include <sound/tlv320aic32x4.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/soc.h>
41#include <sound/soc-dapm.h>
42#include <sound/initval.h>
43#include <sound/tlv.h>
44
45#include "tlv320aic32x4.h"
46
47struct aic32x4_rate_divs {
48 u32 mclk;
49 u32 rate;
50 u8 p_val;
51 u8 pll_j;
52 u16 pll_d;
53 u16 dosr;
54 u8 ndac;
55 u8 mdac;
56 u8 aosr;
57 u8 nadc;
58 u8 madc;
59 u8 blck_N;
60};
61
62struct aic32x4_priv {
63 u32 sysclk;
64 s32 master;
65 u8 page_no;
66 void *control_data;
67 u32 power_cfg;
68 u32 micpga_routing;
69 bool swapdacs;
70};
71
72/* 0dB min, 1dB steps */
73static DECLARE_TLV_DB_SCALE(tlv_step_1, 0, 100, 0);
74/* 0dB min, 0.5dB steps */
75static DECLARE_TLV_DB_SCALE(tlv_step_0_5, 0, 50, 0);
76
77static const struct snd_kcontrol_new aic32x4_snd_controls[] = {
78 SOC_DOUBLE_R_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
79 AIC32X4_RDACVOL, 0, 0x30, 0, tlv_step_0_5),
80 SOC_DOUBLE_R_TLV("HP Driver Gain Volume", AIC32X4_HPLGAIN,
81 AIC32X4_HPRGAIN, 0, 0x1D, 0, tlv_step_1),
82 SOC_DOUBLE_R_TLV("LO Driver Gain Volume", AIC32X4_LOLGAIN,
83 AIC32X4_LORGAIN, 0, 0x1D, 0, tlv_step_1),
84 SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
85 AIC32X4_HPRGAIN, 6, 0x01, 1),
86 SOC_DOUBLE_R("LO DAC Playback Switch", AIC32X4_LOLGAIN,
87 AIC32X4_LORGAIN, 6, 0x01, 1),
88 SOC_DOUBLE_R("Mic PGA Switch", AIC32X4_LMICPGAVOL,
89 AIC32X4_RMICPGAVOL, 7, 0x01, 1),
90
91 SOC_SINGLE("ADCFGA Left Mute Switch", AIC32X4_ADCFGA, 7, 1, 0),
92 SOC_SINGLE("ADCFGA Right Mute Switch", AIC32X4_ADCFGA, 3, 1, 0),
93
94 SOC_DOUBLE_R_TLV("ADC Level Volume", AIC32X4_LADCVOL,
95 AIC32X4_RADCVOL, 0, 0x28, 0, tlv_step_0_5),
96 SOC_DOUBLE_R_TLV("PGA Level Volume", AIC32X4_LMICPGAVOL,
97 AIC32X4_RMICPGAVOL, 0, 0x5f, 0, tlv_step_0_5),
98
99 SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),
100
101 SOC_SINGLE("AGC Left Switch", AIC32X4_LAGC1, 7, 1, 0),
102 SOC_SINGLE("AGC Right Switch", AIC32X4_RAGC1, 7, 1, 0),
103 SOC_DOUBLE_R("AGC Target Level", AIC32X4_LAGC1, AIC32X4_RAGC1,
104 4, 0x07, 0),
105 SOC_DOUBLE_R("AGC Gain Hysteresis", AIC32X4_LAGC1, AIC32X4_RAGC1,
106 0, 0x03, 0),
107 SOC_DOUBLE_R("AGC Hysteresis", AIC32X4_LAGC2, AIC32X4_RAGC2,
108 6, 0x03, 0),
109 SOC_DOUBLE_R("AGC Noise Threshold", AIC32X4_LAGC2, AIC32X4_RAGC2,
110 1, 0x1F, 0),
111 SOC_DOUBLE_R("AGC Max PGA", AIC32X4_LAGC3, AIC32X4_RAGC3,
112 0, 0x7F, 0),
113 SOC_DOUBLE_R("AGC Attack Time", AIC32X4_LAGC4, AIC32X4_RAGC4,
114 3, 0x1F, 0),
115 SOC_DOUBLE_R("AGC Decay Time", AIC32X4_LAGC5, AIC32X4_RAGC5,
116 3, 0x1F, 0),
117 SOC_DOUBLE_R("AGC Noise Debounce", AIC32X4_LAGC6, AIC32X4_RAGC6,
118 0, 0x1F, 0),
119 SOC_DOUBLE_R("AGC Signal Debounce", AIC32X4_LAGC7, AIC32X4_RAGC7,
120 0, 0x0F, 0),
121};
122
123static const struct aic32x4_rate_divs aic32x4_divs[] = {
124 /* 8k rate */
125 {AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24},
126 {AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24},
127 {AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24},
128 /* 11.025k rate */
129 {AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16},
130 {AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16},
131 /* 16k rate */
132 {AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12},
133 {AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12},
134 {AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12},
135 /* 22.05k rate */
136 {AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8},
137 {AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8},
138 {AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8},
139 /* 32k rate */
140 {AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6},
141 {AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6},
142 /* 44.1k rate */
143 {AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4},
144 {AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4},
145 {AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4},
146 /* 48k rate */
147 {AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4},
148 {AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4},
149 {AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}
150};
151
152static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
153 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
154 SOC_DAPM_SINGLE("IN1_L Switch", AIC32X4_HPLROUTE, 2, 1, 0),
155};
156
157static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
158 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_HPRROUTE, 3, 1, 0),
159 SOC_DAPM_SINGLE("IN1_R Switch", AIC32X4_HPRROUTE, 2, 1, 0),
160};
161
162static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
163 SOC_DAPM_SINGLE("L_DAC Switch", AIC32X4_LOLROUTE, 3, 1, 0),
164};
165
166static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
167 SOC_DAPM_SINGLE("R_DAC Switch", AIC32X4_LORROUTE, 3, 1, 0),
168};
169
170static const struct snd_kcontrol_new left_input_mixer_controls[] = {
171 SOC_DAPM_SINGLE("IN1_L P Switch", AIC32X4_LMICPGAPIN, 6, 1, 0),
172 SOC_DAPM_SINGLE("IN2_L P Switch", AIC32X4_LMICPGAPIN, 4, 1, 0),
173 SOC_DAPM_SINGLE("IN3_L P Switch", AIC32X4_LMICPGAPIN, 2, 1, 0),
174};
175
176static const struct snd_kcontrol_new right_input_mixer_controls[] = {
177 SOC_DAPM_SINGLE("IN1_R P Switch", AIC32X4_RMICPGAPIN, 6, 1, 0),
178 SOC_DAPM_SINGLE("IN2_R P Switch", AIC32X4_RMICPGAPIN, 4, 1, 0),
179 SOC_DAPM_SINGLE("IN3_R P Switch", AIC32X4_RMICPGAPIN, 2, 1, 0),
180};
181
182static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
183 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
184 SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
185 &hpl_output_mixer_controls[0],
186 ARRAY_SIZE(hpl_output_mixer_controls)),
187 SND_SOC_DAPM_PGA("HPL Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
188
189 SND_SOC_DAPM_MIXER("LOL Output Mixer", SND_SOC_NOPM, 0, 0,
190 &lol_output_mixer_controls[0],
191 ARRAY_SIZE(lol_output_mixer_controls)),
192 SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),
193
194 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
195 SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
196 &hpr_output_mixer_controls[0],
197 ARRAY_SIZE(hpr_output_mixer_controls)),
198 SND_SOC_DAPM_PGA("HPR Power", AIC32X4_OUTPWRCTL, 4, 0, NULL, 0),
199 SND_SOC_DAPM_MIXER("LOR Output Mixer", SND_SOC_NOPM, 0, 0,
200 &lor_output_mixer_controls[0],
201 ARRAY_SIZE(lor_output_mixer_controls)),
202 SND_SOC_DAPM_PGA("LOR Power", AIC32X4_OUTPWRCTL, 2, 0, NULL, 0),
203 SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
204 &left_input_mixer_controls[0],
205 ARRAY_SIZE(left_input_mixer_controls)),
206 SND_SOC_DAPM_MIXER("Right Input Mixer", SND_SOC_NOPM, 0, 0,
207 &right_input_mixer_controls[0],
208 ARRAY_SIZE(right_input_mixer_controls)),
209 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", AIC32X4_ADCSETUP, 7, 0),
210 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", AIC32X4_ADCSETUP, 6, 0),
211 SND_SOC_DAPM_MICBIAS("Mic Bias", AIC32X4_MICBIAS, 6, 0),
212
213 SND_SOC_DAPM_OUTPUT("HPL"),
214 SND_SOC_DAPM_OUTPUT("HPR"),
215 SND_SOC_DAPM_OUTPUT("LOL"),
216 SND_SOC_DAPM_OUTPUT("LOR"),
217 SND_SOC_DAPM_INPUT("IN1_L"),
218 SND_SOC_DAPM_INPUT("IN1_R"),
219 SND_SOC_DAPM_INPUT("IN2_L"),
220 SND_SOC_DAPM_INPUT("IN2_R"),
221 SND_SOC_DAPM_INPUT("IN3_L"),
222 SND_SOC_DAPM_INPUT("IN3_R"),
223};
224
225static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
226 /* Left Output */
227 {"HPL Output Mixer", "L_DAC Switch", "Left DAC"},
228 {"HPL Output Mixer", "IN1_L Switch", "IN1_L"},
229
230 {"HPL Power", NULL, "HPL Output Mixer"},
231 {"HPL", NULL, "HPL Power"},
232
233 {"LOL Output Mixer", "L_DAC Switch", "Left DAC"},
234
235 {"LOL Power", NULL, "LOL Output Mixer"},
236 {"LOL", NULL, "LOL Power"},
237
238 /* Right Output */
239 {"HPR Output Mixer", "R_DAC Switch", "Right DAC"},
240 {"HPR Output Mixer", "IN1_R Switch", "IN1_R"},
241
242 {"HPR Power", NULL, "HPR Output Mixer"},
243 {"HPR", NULL, "HPR Power"},
244
245 {"LOR Output Mixer", "R_DAC Switch", "Right DAC"},
246
247 {"LOR Power", NULL, "LOR Output Mixer"},
248 {"LOR", NULL, "LOR Power"},
249
250 /* Left input */
251 {"Left Input Mixer", "IN1_L P Switch", "IN1_L"},
252 {"Left Input Mixer", "IN2_L P Switch", "IN2_L"},
253 {"Left Input Mixer", "IN3_L P Switch", "IN3_L"},
254
255 {"Left ADC", NULL, "Left Input Mixer"},
256
257 /* Right Input */
258 {"Right Input Mixer", "IN1_R P Switch", "IN1_R"},
259 {"Right Input Mixer", "IN2_R P Switch", "IN2_R"},
260 {"Right Input Mixer", "IN3_R P Switch", "IN3_R"},
261
262 {"Right ADC", NULL, "Right Input Mixer"},
263};
264
265static inline int aic32x4_change_page(struct snd_soc_codec *codec,
266 unsigned int new_page)
267{
268 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
269 u8 data[2];
270 int ret;
271
272 data[0] = 0x00;
273 data[1] = new_page & 0xff;
274
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret == 2) {
277 aic32x4->page_no = new_page;
278 return 0;
279 } else {
280 return ret;
281 }
282}
283
284static int aic32x4_write(struct snd_soc_codec *codec, unsigned int reg,
285 unsigned int val)
286{
287 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
288 unsigned int page = reg / 128;
289 unsigned int fixed_reg = reg % 128;
290 u8 data[2];
291 int ret;
292
293 /* A write to AIC32X4_PSEL is really a non-explicit page change */
294 if (reg == AIC32X4_PSEL)
295 return aic32x4_change_page(codec, val);
296
297 if (aic32x4->page_no != page) {
298 ret = aic32x4_change_page(codec, page);
299 if (ret != 0)
300 return ret;
301 }
302
303 data[0] = fixed_reg & 0xff;
304 data[1] = val & 0xff;
305
306 if (codec->hw_write(codec->control_data, data, 2) == 2)
307 return 0;
308 else
309 return -EIO;
310}
311
312static unsigned int aic32x4_read(struct snd_soc_codec *codec, unsigned int reg)
313{
314 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
315 unsigned int page = reg / 128;
316 unsigned int fixed_reg = reg % 128;
317 int ret;
318
319 if (aic32x4->page_no != page) {
320 ret = aic32x4_change_page(codec, page);
321 if (ret != 0)
322 return ret;
323 }
324 return i2c_smbus_read_byte_data(codec->control_data, fixed_reg & 0xff);
325}
326
327static inline int aic32x4_get_divs(int mclk, int rate)
328{
329 int i;
330
331 for (i = 0; i < ARRAY_SIZE(aic32x4_divs); i++) {
332 if ((aic32x4_divs[i].rate == rate)
333 && (aic32x4_divs[i].mclk == mclk)) {
334 return i;
335 }
336 }
337 printk(KERN_ERR "aic32x4: master clock and sample rate is not supported\n");
338 return -EINVAL;
339}
340
341static int aic32x4_add_widgets(struct snd_soc_codec *codec)
342{
343 snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
344 ARRAY_SIZE(aic32x4_dapm_widgets));
345
346 snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
347 ARRAY_SIZE(aic32x4_dapm_routes));
348
349 snd_soc_dapm_new_widgets(&codec->dapm);
350 return 0;
351}
352
353static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir)
355{
356 struct snd_soc_codec *codec = codec_dai->codec;
357 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
358
359 switch (freq) {
360 case AIC32X4_FREQ_12000000:
361 case AIC32X4_FREQ_24000000:
362 case AIC32X4_FREQ_25000000:
363 aic32x4->sysclk = freq;
364 return 0;
365 }
366 printk(KERN_ERR "aic32x4: invalid frequency to set DAI system clock\n");
367 return -EINVAL;
368}
369
370static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
371{
372 struct snd_soc_codec *codec = codec_dai->codec;
373 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
374 u8 iface_reg_1;
375 u8 iface_reg_2;
376 u8 iface_reg_3;
377
378 iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1);
379 iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2);
380 iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2);
381 iface_reg_2 = 0;
382 iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3);
383 iface_reg_3 = iface_reg_3 & ~(1 << 3);
384
385 /* set master/slave audio interface */
386 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
387 case SND_SOC_DAIFMT_CBM_CFM:
388 aic32x4->master = 1;
389 iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER;
390 break;
391 case SND_SOC_DAIFMT_CBS_CFS:
392 aic32x4->master = 0;
393 break;
394 default:
395 printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n");
396 return -EINVAL;
397 }
398
399 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
400 case SND_SOC_DAIFMT_I2S:
401 break;
402 case SND_SOC_DAIFMT_DSP_A:
403 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
404 iface_reg_3 |= (1 << 3); /* invert bit clock */
405 iface_reg_2 = 0x01; /* add offset 1 */
406 break;
407 case SND_SOC_DAIFMT_DSP_B:
408 iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT);
409 iface_reg_3 |= (1 << 3); /* invert bit clock */
410 break;
411 case SND_SOC_DAIFMT_RIGHT_J:
412 iface_reg_1 |=
413 (AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
414 break;
415 case SND_SOC_DAIFMT_LEFT_J:
416 iface_reg_1 |=
417 (AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT);
418 break;
419 default:
420 printk(KERN_ERR "aic32x4: invalid DAI interface format\n");
421 return -EINVAL;
422 }
423
424 snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1);
425 snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2);
426 snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3);
427 return 0;
428}
429
430static int aic32x4_hw_params(struct snd_pcm_substream *substream,
431 struct snd_pcm_hw_params *params,
432 struct snd_soc_dai *dai)
433{
434 struct snd_soc_codec *codec = dai->codec;
435 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
436 u8 data;
437 int i;
438
439 i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params));
440 if (i < 0) {
441 printk(KERN_ERR "aic32x4: sampling rate not supported\n");
442 return i;
443 }
444
445 /* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */
446 snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN);
447 snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK);
448
449 /* We will fix R value to 1 and will make P & J=K.D as varialble */
450 data = snd_soc_read(codec, AIC32X4_PLLPR);
451 data &= ~(7 << 4);
452 snd_soc_write(codec, AIC32X4_PLLPR,
453 (data | (aic32x4_divs[i].p_val << 4) | 0x01));
454
455 snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j);
456
457 snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8));
458 snd_soc_write(codec, AIC32X4_PLLDLSB,
459 (aic32x4_divs[i].pll_d & 0xff));
460
461 /* NDAC divider value */
462 data = snd_soc_read(codec, AIC32X4_NDAC);
463 data &= ~(0x7f);
464 snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac);
465
466 /* MDAC divider value */
467 data = snd_soc_read(codec, AIC32X4_MDAC);
468 data &= ~(0x7f);
469 snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac);
470
471 /* DOSR MSB & LSB values */
472 snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8);
473 snd_soc_write(codec, AIC32X4_DOSRLSB,
474 (aic32x4_divs[i].dosr & 0xff));
475
476 /* NADC divider value */
477 data = snd_soc_read(codec, AIC32X4_NADC);
478 data &= ~(0x7f);
479 snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc);
480
481 /* MADC divider value */
482 data = snd_soc_read(codec, AIC32X4_MADC);
483 data &= ~(0x7f);
484 snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc);
485
486 /* AOSR value */
487 snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr);
488
489 /* BCLK N divider */
490 data = snd_soc_read(codec, AIC32X4_BCLKN);
491 data &= ~(0x7f);
492 snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N);
493
494 data = snd_soc_read(codec, AIC32X4_IFACE1);
495 data = data & ~(3 << 4);
496 switch (params_format(params)) {
497 case SNDRV_PCM_FORMAT_S16_LE:
498 break;
499 case SNDRV_PCM_FORMAT_S20_3LE:
500 data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT);
501 break;
502 case SNDRV_PCM_FORMAT_S24_LE:
503 data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT);
504 break;
505 case SNDRV_PCM_FORMAT_S32_LE:
506 data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT);
507 break;
508 }
509 snd_soc_write(codec, AIC32X4_IFACE1, data);
510
511 return 0;
512}
513
514static int aic32x4_mute(struct snd_soc_dai *dai, int mute)
515{
516 struct snd_soc_codec *codec = dai->codec;
517 u8 dac_reg;
518
519 dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON;
520 if (mute)
521 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON);
522 else
523 snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg);
524 return 0;
525}
526
527static int aic32x4_set_bias_level(struct snd_soc_codec *codec,
528 enum snd_soc_bias_level level)
529{
530 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
531 u8 value;
532
533 switch (level) {
534 case SND_SOC_BIAS_ON:
535 if (aic32x4->master) {
536 /* Switch on PLL */
537 value = snd_soc_read(codec, AIC32X4_PLLPR);
538 snd_soc_write(codec, AIC32X4_PLLPR,
539 (value | AIC32X4_PLLEN));
540
541 /* Switch on NDAC Divider */
542 value = snd_soc_read(codec, AIC32X4_NDAC);
543 snd_soc_write(codec, AIC32X4_NDAC,
544 value | AIC32X4_NDACEN);
545
546 /* Switch on MDAC Divider */
547 value = snd_soc_read(codec, AIC32X4_MDAC);
548 snd_soc_write(codec, AIC32X4_MDAC,
549 value | AIC32X4_MDACEN);
550
551 /* Switch on NADC Divider */
552 value = snd_soc_read(codec, AIC32X4_NADC);
553 snd_soc_write(codec, AIC32X4_NADC,
554 value | AIC32X4_MDACEN);
555
556 /* Switch on MADC Divider */
557 value = snd_soc_read(codec, AIC32X4_MADC);
558 snd_soc_write(codec, AIC32X4_MADC,
559 value | AIC32X4_MDACEN);
560
561 /* Switch on BCLK_N Divider */
562 value = snd_soc_read(codec, AIC32X4_BCLKN);
563 snd_soc_write(codec, AIC32X4_BCLKN,
564 value | AIC32X4_BCLKEN);
565 }
566 break;
567 case SND_SOC_BIAS_PREPARE:
568 break;
569 case SND_SOC_BIAS_STANDBY:
570 if (aic32x4->master) {
571 /* Switch off PLL */
572 value = snd_soc_read(codec, AIC32X4_PLLPR);
573 snd_soc_write(codec, AIC32X4_PLLPR,
574 (value & ~AIC32X4_PLLEN));
575
576 /* Switch off NDAC Divider */
577 value = snd_soc_read(codec, AIC32X4_NDAC);
578 snd_soc_write(codec, AIC32X4_NDAC,
579 value & ~AIC32X4_NDACEN);
580
581 /* Switch off MDAC Divider */
582 value = snd_soc_read(codec, AIC32X4_MDAC);
583 snd_soc_write(codec, AIC32X4_MDAC,
584 value & ~AIC32X4_MDACEN);
585
586 /* Switch off NADC Divider */
587 value = snd_soc_read(codec, AIC32X4_NADC);
588 snd_soc_write(codec, AIC32X4_NADC,
589 value & ~AIC32X4_NDACEN);
590
591 /* Switch off MADC Divider */
592 value = snd_soc_read(codec, AIC32X4_MADC);
593 snd_soc_write(codec, AIC32X4_MADC,
594 value & ~AIC32X4_MDACEN);
595 value = snd_soc_read(codec, AIC32X4_BCLKN);
596
597 /* Switch off BCLK_N Divider */
598 snd_soc_write(codec, AIC32X4_BCLKN,
599 value & ~AIC32X4_BCLKEN);
600 }
601 break;
602 case SND_SOC_BIAS_OFF:
603 break;
604 }
605 codec->dapm.bias_level = level;
606 return 0;
607}
608
609#define AIC32X4_RATES SNDRV_PCM_RATE_8000_48000
610#define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
611 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
612
613static struct snd_soc_dai_ops aic32x4_ops = {
614 .hw_params = aic32x4_hw_params,
615 .digital_mute = aic32x4_mute,
616 .set_fmt = aic32x4_set_dai_fmt,
617 .set_sysclk = aic32x4_set_dai_sysclk,
618};
619
620static struct snd_soc_dai_driver aic32x4_dai = {
621 .name = "tlv320aic32x4-hifi",
622 .playback = {
623 .stream_name = "Playback",
624 .channels_min = 1,
625 .channels_max = 2,
626 .rates = AIC32X4_RATES,
627 .formats = AIC32X4_FORMATS,},
628 .capture = {
629 .stream_name = "Capture",
630 .channels_min = 1,
631 .channels_max = 2,
632 .rates = AIC32X4_RATES,
633 .formats = AIC32X4_FORMATS,},
634 .ops = &aic32x4_ops,
635 .symmetric_rates = 1,
636};
637
638static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state)
639{
640 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
641 return 0;
642}
643
644static int aic32x4_resume(struct snd_soc_codec *codec)
645{
646 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
647 return 0;
648}
649
650static int aic32x4_probe(struct snd_soc_codec *codec)
651{
652 struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
653 u32 tmp_reg;
654
655 codec->hw_write = (hw_write_t) i2c_master_send;
656 codec->control_data = aic32x4->control_data;
657
658 snd_soc_write(codec, AIC32X4_RESET, 0x01);
659
660 /* Power platform configuration */
661 if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
662 snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
663 AIC32X4_MICBIAS_2075V);
664 }
665 if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) {
666 snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
667 }
668 if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) {
669 snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN);
670 }
671 tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
672 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) {
673 tmp_reg |= AIC32X4_LDOIN_18_36;
674 }
675 if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED) {
676 tmp_reg |= AIC32X4_LDOIN2HP;
677 }
678 snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);
679
680 /* Do DACs need to be swapped? */
681 if (aic32x4->swapdacs) {
682 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2RCHN | AIC32X4_RDAC2LCHN);
683 } else {
684 snd_soc_write(codec, AIC32X4_DACSETUP, AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN);
685 }
686
687 /* Mic PGA routing */
688 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) {
689 snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K);
690 }
691 if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) {
692 snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K);
693 }
694
695 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
696 snd_soc_add_controls(codec, aic32x4_snd_controls,
697 ARRAY_SIZE(aic32x4_snd_controls));
698 aic32x4_add_widgets(codec);
699
700 return 0;
701}
702
703static int aic32x4_remove(struct snd_soc_codec *codec)
704{
705 aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF);
706 return 0;
707}
708
709static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
710 .read = aic32x4_read,
711 .write = aic32x4_write,
712 .probe = aic32x4_probe,
713 .remove = aic32x4_remove,
714 .suspend = aic32x4_suspend,
715 .resume = aic32x4_resume,
716 .set_bias_level = aic32x4_set_bias_level,
717};
718
719static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
720 const struct i2c_device_id *id)
721{
722 struct aic32x4_pdata *pdata = i2c->dev.platform_data;
723 struct aic32x4_priv *aic32x4;
724 int ret;
725
726 aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL);
727 if (aic32x4 == NULL)
728 return -ENOMEM;
729
730 aic32x4->control_data = i2c;
731 i2c_set_clientdata(i2c, aic32x4);
732
733 if (pdata) {
734 aic32x4->power_cfg = pdata->power_cfg;
735 aic32x4->swapdacs = pdata->swapdacs;
736 aic32x4->micpga_routing = pdata->micpga_routing;
737 } else {
738 aic32x4->power_cfg = 0;
739 aic32x4->swapdacs = false;
740 aic32x4->micpga_routing = 0;
741 }
742
743 ret = snd_soc_register_codec(&i2c->dev,
744 &soc_codec_dev_aic32x4, &aic32x4_dai, 1);
745 if (ret < 0)
746 kfree(aic32x4);
747 return ret;
748}
749
750static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
751{
752 snd_soc_unregister_codec(&client->dev);
753 kfree(i2c_get_clientdata(client));
754 return 0;
755}
756
757static const struct i2c_device_id aic32x4_i2c_id[] = {
758 { "tlv320aic32x4", 0 },
759 { }
760};
761MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
762
763static struct i2c_driver aic32x4_i2c_driver = {
764 .driver = {
765 .name = "tlv320aic32x4",
766 .owner = THIS_MODULE,
767 },
768 .probe = aic32x4_i2c_probe,
769 .remove = __devexit_p(aic32x4_i2c_remove),
770 .id_table = aic32x4_i2c_id,
771};
772
773static int __init aic32x4_modinit(void)
774{
775 int ret = 0;
776
777 ret = i2c_add_driver(&aic32x4_i2c_driver);
778 if (ret != 0) {
779 printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
780 ret);
781 }
782 return ret;
783}
784module_init(aic32x4_modinit);
785
786static void __exit aic32x4_exit(void)
787{
788 i2c_del_driver(&aic32x4_i2c_driver);
789}
790module_exit(aic32x4_exit);
791
792MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
793MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
794MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h
new file mode 100644
index 000000000000..aae2b2440398
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic32x4.h
@@ -0,0 +1,143 @@
1/*
2 * tlv320aic32x4.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9
10#ifndef _TLV320AIC32X4_H
11#define _TLV320AIC32X4_H
12
13/* tlv320aic32x4 register space (in decimal to match datasheet) */
14
15#define AIC32X4_PAGE1 128
16
17#define AIC32X4_PSEL 0
18#define AIC32X4_RESET 1
19#define AIC32X4_CLKMUX 4
20#define AIC32X4_PLLPR 5
21#define AIC32X4_PLLJ 6
22#define AIC32X4_PLLDMSB 7
23#define AIC32X4_PLLDLSB 8
24#define AIC32X4_NDAC 11
25#define AIC32X4_MDAC 12
26#define AIC32X4_DOSRMSB 13
27#define AIC32X4_DOSRLSB 14
28#define AIC32X4_NADC 18
29#define AIC32X4_MADC 19
30#define AIC32X4_AOSR 20
31#define AIC32X4_CLKMUX2 25
32#define AIC32X4_CLKOUTM 26
33#define AIC32X4_IFACE1 27
34#define AIC32X4_IFACE2 28
35#define AIC32X4_IFACE3 29
36#define AIC32X4_BCLKN 30
37#define AIC32X4_IFACE4 31
38#define AIC32X4_IFACE5 32
39#define AIC32X4_IFACE6 33
40#define AIC32X4_DOUTCTL 53
41#define AIC32X4_DINCTL 54
42#define AIC32X4_DACSPB 60
43#define AIC32X4_ADCSPB 61
44#define AIC32X4_DACSETUP 63
45#define AIC32X4_DACMUTE 64
46#define AIC32X4_LDACVOL 65
47#define AIC32X4_RDACVOL 66
48#define AIC32X4_ADCSETUP 81
49#define AIC32X4_ADCFGA 82
50#define AIC32X4_LADCVOL 83
51#define AIC32X4_RADCVOL 84
52#define AIC32X4_LAGC1 86
53#define AIC32X4_LAGC2 87
54#define AIC32X4_LAGC3 88
55#define AIC32X4_LAGC4 89
56#define AIC32X4_LAGC5 90
57#define AIC32X4_LAGC6 91
58#define AIC32X4_LAGC7 92
59#define AIC32X4_RAGC1 94
60#define AIC32X4_RAGC2 95
61#define AIC32X4_RAGC3 96
62#define AIC32X4_RAGC4 97
63#define AIC32X4_RAGC5 98
64#define AIC32X4_RAGC6 99
65#define AIC32X4_RAGC7 100
66#define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1)
67#define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2)
68#define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9)
69#define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10)
70#define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12)
71#define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13)
72#define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14)
73#define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15)
74#define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16)
75#define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17)
76#define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18)
77#define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19)
78#define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20)
79#define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51)
80#define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52)
81#define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54)
82#define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55)
83#define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57)
84#define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58)
85#define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59)
86#define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60)
87
88#define AIC32X4_FREQ_12000000 12000000
89#define AIC32X4_FREQ_24000000 24000000
90#define AIC32X4_FREQ_25000000 25000000
91
92#define AIC32X4_WORD_LEN_16BITS 0x00
93#define AIC32X4_WORD_LEN_20BITS 0x01
94#define AIC32X4_WORD_LEN_24BITS 0x02
95#define AIC32X4_WORD_LEN_32BITS 0x03
96
97#define AIC32X4_I2S_MODE 0x00
98#define AIC32X4_DSP_MODE 0x01
99#define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02
100#define AIC32X4_LEFT_JUSTIFIED_MODE 0x03
101
102#define AIC32X4_AVDDWEAKDISABLE 0x08
103#define AIC32X4_LDOCTLEN 0x01
104
105#define AIC32X4_LDOIN_18_36 0x01
106#define AIC32X4_LDOIN2HP 0x02
107
108#define AIC32X4_DACSPBLOCK_MASK 0x1f
109#define AIC32X4_ADCSPBLOCK_MASK 0x1f
110
111#define AIC32X4_PLLJ_SHIFT 6
112#define AIC32X4_DOSRMSB_SHIFT 4
113
114#define AIC32X4_PLLCLKIN 0x03
115
116#define AIC32X4_MICBIAS_LDOIN 0x08
117#define AIC32X4_MICBIAS_2075V 0x60
118
119#define AIC32X4_LMICPGANIN_IN2R_10K 0x10
120#define AIC32X4_RMICPGANIN_IN1L_10K 0x10
121
122#define AIC32X4_LMICPGAVOL_NOGAIN 0x80
123#define AIC32X4_RMICPGAVOL_NOGAIN 0x80
124
125#define AIC32X4_BCLKMASTER 0x08
126#define AIC32X4_WCLKMASTER 0x04
127#define AIC32X4_PLLEN (0x01 << 7)
128#define AIC32X4_NDACEN (0x01 << 7)
129#define AIC32X4_MDACEN (0x01 << 7)
130#define AIC32X4_NADCEN (0x01 << 7)
131#define AIC32X4_MADCEN (0x01 << 7)
132#define AIC32X4_BCLKEN (0x01 << 7)
133#define AIC32X4_DACEN (0x03 << 6)
134#define AIC32X4_RDAC2LCHN (0x02 << 2)
135#define AIC32X4_LDAC2RCHN (0x02 << 4)
136#define AIC32X4_LDAC2LCHN (0x01 << 4)
137#define AIC32X4_RDAC2RCHN (0x01 << 2)
138
139#define AIC32X4_SSTEP2WCLK 0x01
140#define AIC32X4_MUTEON 0x0C
141#define AIC32X4_DACMOD2BCLK 0x01
142
143#endif /* _TLV320AIC32X4_H */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 71a69908ccf6..789453d44ec5 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -12,11 +12,11 @@
12 * 12 *
13 * Notes: 13 * Notes:
14 * The AIC3X is a driver for a low power stereo audio 14 * The AIC3X is a driver for a low power stereo audio
15 * codecs aic31, aic32, aic33. 15 * codecs aic31, aic32, aic33, aic3007.
16 * 16 *
17 * It supports full aic33 codec functionality. 17 * It supports full aic33 codec functionality.
18 * The compatibility with aic32, aic31 is as follows: 18 * The compatibility with aic32, aic31 and aic3007 is as follows:
19 * aic32 | aic31 19 * aic32/aic3007 | aic31
20 * --------------------------------------- 20 * ---------------------------------------
21 * MONO_LOUT -> N/A | MONO_LOUT -> N/A 21 * MONO_LOUT -> N/A | MONO_LOUT -> N/A
22 * | IN1L -> LINE1L 22 * | IN1L -> LINE1L
@@ -46,7 +46,6 @@
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>
@@ -61,13 +60,32 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
61 "DRVDD", /* ADC Analog and Output Driver Voltage */ 60 "DRVDD", /* ADC Analog and Output Driver Voltage */
62}; 61};
63 62
63static LIST_HEAD(reset_list);
64
65struct aic3x_priv;
66
67struct aic3x_disable_nb {
68 struct notifier_block nb;
69 struct aic3x_priv *aic3x;
70};
71
64/* codec private data */ 72/* codec private data */
65struct aic3x_priv { 73struct aic3x_priv {
66 struct snd_soc_codec codec; 74 struct snd_soc_codec *codec;
67 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; 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;
68 unsigned int sysclk; 80 unsigned int sysclk;
81 struct list_head list;
69 int master; 82 int master;
70 int gpio_reset; 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;
71}; 89};
72 90
73/* 91/*
@@ -106,62 +124,23 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
106}; 124};
107 125
108/* 126/*
109 * read aic3x register cache 127 * read from the aic3x register space. Only use for this function is if
128 * wanting to read volatile bits from those registers that has both read-only
129 * and read/write bits. All other cases should use snd_soc_read.
110 */ 130 */
111static inline unsigned int aic3x_read_reg_cache(struct snd_soc_codec *codec, 131static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
112 unsigned int reg) 132 u8 *value)
113{ 133{
114 u8 *cache = codec->reg_cache; 134 u8 *cache = codec->reg_cache;
115 if (reg >= AIC3X_CACHEREGNUM)
116 return -1;
117 return cache[reg];
118}
119 135
120/* 136 if (codec->cache_only)
121 * write aic3x register cache 137 return -EINVAL;
122 */
123static inline void aic3x_write_reg_cache(struct snd_soc_codec *codec,
124 u8 reg, u8 value)
125{
126 u8 *cache = codec->reg_cache;
127 if (reg >= AIC3X_CACHEREGNUM) 138 if (reg >= AIC3X_CACHEREGNUM)
128 return; 139 return -1;
129 cache[reg] = value;
130}
131
132/*
133 * write to the aic3x register space
134 */
135static int aic3x_write(struct snd_soc_codec *codec, unsigned int reg,
136 unsigned int value)
137{
138 u8 data[2];
139
140 /* data is
141 * D15..D8 aic3x register offset
142 * D7...D0 register data
143 */
144 data[0] = reg & 0xff;
145 data[1] = value & 0xff;
146
147 aic3x_write_reg_cache(codec, data[0], data[1]);
148 if (codec->hw_write(codec->control_data, data, 2) == 2)
149 return 0;
150 else
151 return -EIO;
152}
153
154/*
155 * read from the aic3x register space
156 */
157static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
158 u8 *value)
159{
160 *value = reg & 0xff;
161 140
162 value[0] = i2c_smbus_read_byte_data(codec->control_data, value[0]); 141 *value = codec->hw_read(codec, reg);
142 cache[reg] = *value;
163 143
164 aic3x_write_reg_cache(codec, reg, *value);
165 return 0; 144 return 0;
166} 145}
167 146
@@ -178,7 +157,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
178static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, 157static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
179 struct snd_ctl_elem_value *ucontrol) 158 struct snd_ctl_elem_value *ucontrol)
180{ 159{
181 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 160 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
161 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
182 struct soc_mixer_control *mc = 162 struct soc_mixer_control *mc =
183 (struct soc_mixer_control *)kcontrol->private_value; 163 (struct soc_mixer_control *)kcontrol->private_value;
184 unsigned int reg = mc->reg; 164 unsigned int reg = mc->reg;
@@ -206,7 +186,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
206 186
207 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 187 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
208 /* find dapm widget path assoc with kcontrol */ 188 /* find dapm widget path assoc with kcontrol */
209 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 189 list_for_each_entry(path, &widget->dapm->card->paths, list) {
210 if (path->kcontrol != kcontrol) 190 if (path->kcontrol != kcontrol)
211 continue; 191 continue;
212 192
@@ -222,7 +202,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
222 } 202 }
223 203
224 if (found) 204 if (found)
225 snd_soc_dapm_sync(widget->codec); 205 snd_soc_dapm_sync(widget->dapm);
226 } 206 }
227 207
228 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 208 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
@@ -286,64 +266,102 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
286 SOC_DOUBLE_R_TLV("PCM Playback Volume", 266 SOC_DOUBLE_R_TLV("PCM Playback Volume",
287 LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv), 267 LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv),
288 268
269 /*
270 * Output controls that map to output mixer switches. Note these are
271 * only for swapped L-to-R and R-to-L routes. See below stereo controls
272 * for direct L-to-L and R-to-R routes.
273 */
274 SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume",
275 LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
276 SOC_SINGLE_TLV("Left Line Mixer PGAR Bypass Volume",
277 PGAR_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
278 SOC_SINGLE_TLV("Left Line Mixer DACR1 Playback Volume",
279 DACR1_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
280
281 SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume",
282 LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
283 SOC_SINGLE_TLV("Right Line Mixer PGAL Bypass Volume",
284 PGAL_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
285 SOC_SINGLE_TLV("Right Line Mixer DACL1 Playback Volume",
286 DACL1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
287
288 SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume",
289 LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
290 SOC_SINGLE_TLV("Left HP Mixer PGAR Bypass Volume",
291 PGAR_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
292 SOC_SINGLE_TLV("Left HP Mixer DACR1 Playback Volume",
293 DACR1_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
294
295 SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume",
296 LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
297 SOC_SINGLE_TLV("Right HP Mixer PGAL Bypass Volume",
298 PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
299 SOC_SINGLE_TLV("Right HP Mixer DACL1 Playback Volume",
300 DACL1_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
301
302 SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume",
303 LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
304 SOC_SINGLE_TLV("Left HPCOM Mixer PGAR Bypass Volume",
305 PGAR_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
306 SOC_SINGLE_TLV("Left HPCOM Mixer DACR1 Playback Volume",
307 DACR1_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
308
309 SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume",
310 LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
311 SOC_SINGLE_TLV("Right HPCOM Mixer PGAL Bypass Volume",
312 PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
313 SOC_SINGLE_TLV("Right HPCOM Mixer DACL1 Playback Volume",
314 DACL1_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
315
316 /* Stereo output controls for direct L-to-L and R-to-R routes */
317 SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume",
318 LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL,
319 0, 118, 1, output_stage_tlv),
320 SOC_DOUBLE_R_TLV("Line PGA Bypass Volume",
321 PGAL_2_LLOPM_VOL, PGAR_2_RLOPM_VOL,
322 0, 118, 1, output_stage_tlv),
289 SOC_DOUBLE_R_TLV("Line DAC Playback Volume", 323 SOC_DOUBLE_R_TLV("Line DAC Playback Volume",
290 DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL, 324 DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL,
291 0, 118, 1, output_stage_tlv), 325 0, 118, 1, output_stage_tlv),
292 SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0), 326
293 SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0), 327 SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume",
294 SOC_DOUBLE_R_TLV("LineL DAC Playback Volume", 328 LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL,
295 DACL1_2_LLOPM_VOL, DACR1_2_LLOPM_VOL,
296 0, 118, 1, output_stage_tlv),
297 SOC_SINGLE_TLV("LineL Left PGA Bypass Playback Volume",
298 PGAL_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
299 SOC_SINGLE_TLV("LineR Right PGA Bypass Playback Volume",
300 PGAR_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
301 SOC_DOUBLE_R_TLV("LineL Line2 Bypass Playback Volume",
302 LINE2L_2_LLOPM_VOL, LINE2R_2_LLOPM_VOL,
303 0, 118, 1, output_stage_tlv), 329 0, 118, 1, output_stage_tlv),
304 SOC_DOUBLE_R_TLV("LineR Line2 Bypass Playback Volume", 330 SOC_DOUBLE_R_TLV("Mono PGA Bypass Volume",
305 LINE2L_2_RLOPM_VOL, LINE2R_2_RLOPM_VOL, 331 PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL,
306 0, 118, 1, output_stage_tlv), 332 0, 118, 1, output_stage_tlv),
307
308 SOC_DOUBLE_R_TLV("Mono DAC Playback Volume", 333 SOC_DOUBLE_R_TLV("Mono DAC Playback Volume",
309 DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL, 334 DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL,
310 0, 118, 1, output_stage_tlv), 335 0, 118, 1, output_stage_tlv),
311 SOC_SINGLE("Mono DAC Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), 336
312 SOC_DOUBLE_R_TLV("Mono PGA Bypass Playback Volume", 337 SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume",
313 PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL, 338 LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
314 0, 118, 1, output_stage_tlv), 339 0, 118, 1, output_stage_tlv),
315 SOC_DOUBLE_R_TLV("Mono Line2 Bypass Playback Volume", 340 SOC_DOUBLE_R_TLV("HP PGA Bypass Volume",
316 LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, 341 PGAL_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL,
317 0, 118, 1, output_stage_tlv), 342 0, 118, 1, output_stage_tlv),
318
319 SOC_DOUBLE_R_TLV("HP DAC Playback Volume", 343 SOC_DOUBLE_R_TLV("HP DAC Playback Volume",
320 DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL, 344 DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL,
321 0, 118, 1, output_stage_tlv), 345 0, 118, 1, output_stage_tlv),
322 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 346
323 0x01, 0), 347 SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume",
324 SOC_DOUBLE_R_TLV("HP Right PGA Bypass Playback Volume", 348 LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
325 PGAR_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL,
326 0, 118, 1, output_stage_tlv), 349 0, 118, 1, output_stage_tlv),
327 SOC_SINGLE_TLV("HPL PGA Bypass Playback Volume", 350 SOC_DOUBLE_R_TLV("HPCOM PGA Bypass Volume",
328 PGAL_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv), 351 PGAL_2_HPLCOM_VOL, PGAR_2_HPRCOM_VOL,
329 SOC_SINGLE_TLV("HPR PGA Bypass Playback Volume",
330 PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
331 SOC_DOUBLE_R_TLV("HP Line2 Bypass Playback Volume",
332 LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
333 0, 118, 1, output_stage_tlv), 352 0, 118, 1, output_stage_tlv),
334
335 SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume", 353 SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume",
336 DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL, 354 DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
337 0, 118, 1, output_stage_tlv), 355 0, 118, 1, output_stage_tlv),
338 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, 356
357 /* Output pin mute controls */
358 SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
359 0x01, 0),
360 SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
361 SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
362 0x01, 0),
363 SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
339 0x01, 0), 364 0x01, 0),
340 SOC_SINGLE_TLV("HPLCOM PGA Bypass Playback Volume",
341 PGAL_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
342 SOC_SINGLE_TLV("HPRCOM PGA Bypass Playback Volume",
343 PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
344 SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Playback Volume",
345 LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
346 0, 118, 1, output_stage_tlv),
347 365
348 /* 366 /*
349 * Note: enable Automatic input Gain Controller with care. It can 367 * Note: enable Automatic input Gain Controller with care. It can
@@ -359,6 +377,14 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
359 SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), 377 SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]),
360}; 378};
361 379
380/*
381 * Class-D amplifier gain. From 0 to 18 dB in 6 dB steps
382 */
383static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0);
384
385static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl =
386 SOC_DOUBLE_TLV("Class-D Amplifier Gain", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv);
387
362/* Left DAC Mux */ 388/* Left DAC Mux */
363static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = 389static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =
364SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]); 390SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]);
@@ -375,22 +401,74 @@ SOC_DAPM_ENUM("Route", aic3x_enum[LHPCOM_ENUM]);
375static const struct snd_kcontrol_new aic3x_right_hpcom_mux_controls = 401static const struct snd_kcontrol_new aic3x_right_hpcom_mux_controls =
376SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]); 402SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
377 403
378/* Left DAC_L1 Mixer */ 404/* Left Line Mixer */
379static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = { 405static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = {
380 SOC_DAPM_SINGLE("LineL Switch", DACL1_2_LLOPM_VOL, 7, 1, 0), 406 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
381 SOC_DAPM_SINGLE("LineR Switch", DACL1_2_RLOPM_VOL, 7, 1, 0), 407 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
382 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0), 408 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
383 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0), 409 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
384 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0), 410 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
411 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
385}; 412};
386 413
387/* Right DAC_R1 Mixer */ 414/* Right Line Mixer */
388static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = { 415static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] = {
389 SOC_DAPM_SINGLE("LineL Switch", DACR1_2_LLOPM_VOL, 7, 1, 0), 416 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
390 SOC_DAPM_SINGLE("LineR Switch", DACR1_2_RLOPM_VOL, 7, 1, 0), 417 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
391 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0), 418 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
392 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0), 419 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
393 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0), 420 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
421 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
422};
423
424/* Mono Mixer */
425static const struct snd_kcontrol_new aic3x_mono_mixer_controls[] = {
426 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
427 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
428 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
429 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
430 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
431 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
432};
433
434/* Left HP Mixer */
435static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] = {
436 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
437 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
438 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
439 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0),
440 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
441 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLOUT_VOL, 7, 1, 0),
442};
443
444/* Right HP Mixer */
445static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] = {
446 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0),
447 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
448 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPROUT_VOL, 7, 1, 0),
449 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
450 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
451 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
452};
453
454/* Left HPCOM Mixer */
455static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] = {
456 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
457 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
458 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
459 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0),
460 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
461 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLCOM_VOL, 7, 1, 0),
462};
463
464/* Right HPCOM Mixer */
465static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] = {
466 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0),
467 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
468 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPRCOM_VOL, 7, 1, 0),
469 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
470 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
471 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
394}; 472};
395 473
396/* Left PGA Mixer */ 474/* Left PGA Mixer */
@@ -427,54 +505,11 @@ SOC_DAPM_ENUM("Route", aic3x_enum[LINE2L_ENUM]);
427static const struct snd_kcontrol_new aic3x_right_line2_mux_controls = 505static const struct snd_kcontrol_new aic3x_right_line2_mux_controls =
428SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]); 506SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
429 507
430/* Left PGA Bypass Mixer */
431static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = {
432 SOC_DAPM_SINGLE("LineL Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
433 SOC_DAPM_SINGLE("LineR Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
434 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
435 SOC_DAPM_SINGLE("HPL Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
436 SOC_DAPM_SINGLE("HPR Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
437 SOC_DAPM_SINGLE("HPLCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
438 SOC_DAPM_SINGLE("HPRCOM Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
439};
440
441/* Right PGA Bypass Mixer */
442static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = {
443 SOC_DAPM_SINGLE("LineL Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
444 SOC_DAPM_SINGLE("LineR Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
445 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
446 SOC_DAPM_SINGLE("HPL Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
447 SOC_DAPM_SINGLE("HPR Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
448 SOC_DAPM_SINGLE("HPLCOM Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
449 SOC_DAPM_SINGLE("HPRCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
450};
451
452/* Left Line2 Bypass Mixer */
453static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = {
454 SOC_DAPM_SINGLE("LineL Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
455 SOC_DAPM_SINGLE("LineR Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
456 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
457 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
458 SOC_DAPM_SINGLE("HPLCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
459};
460
461/* Right Line2 Bypass Mixer */
462static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = {
463 SOC_DAPM_SINGLE("LineL Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
464 SOC_DAPM_SINGLE("LineR Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
465 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
466 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
467 SOC_DAPM_SINGLE("HPRCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
468};
469
470static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { 508static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
471 /* Left DAC to Left Outputs */ 509 /* Left DAC to Left Outputs */
472 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0), 510 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0),
473 SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0, 511 SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0,
474 &aic3x_left_dac_mux_controls), 512 &aic3x_left_dac_mux_controls),
475 SND_SOC_DAPM_MIXER("Left DAC_L1 Mixer", SND_SOC_NOPM, 0, 0,
476 &aic3x_left_dac_mixer_controls[0],
477 ARRAY_SIZE(aic3x_left_dac_mixer_controls)),
478 SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0, 513 SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0,
479 &aic3x_left_hpcom_mux_controls), 514 &aic3x_left_hpcom_mux_controls),
480 SND_SOC_DAPM_PGA("Left Line Out", LLOPM_CTRL, 0, 0, NULL, 0), 515 SND_SOC_DAPM_PGA("Left Line Out", LLOPM_CTRL, 0, 0, NULL, 0),
@@ -485,9 +520,6 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
485 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0), 520 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0),
486 SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0, 521 SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0,
487 &aic3x_right_dac_mux_controls), 522 &aic3x_right_dac_mux_controls),
488 SND_SOC_DAPM_MIXER("Right DAC_R1 Mixer", SND_SOC_NOPM, 0, 0,
489 &aic3x_right_dac_mixer_controls[0],
490 ARRAY_SIZE(aic3x_right_dac_mixer_controls)),
491 SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0, 523 SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0,
492 &aic3x_right_hpcom_mux_controls), 524 &aic3x_right_hpcom_mux_controls),
493 SND_SOC_DAPM_PGA("Right Line Out", RLOPM_CTRL, 0, 0, NULL, 0), 525 SND_SOC_DAPM_PGA("Right Line Out", RLOPM_CTRL, 0, 0, NULL, 0),
@@ -551,25 +583,28 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
551 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD", 583 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD",
552 MICBIAS_CTRL, 6, 3, 3, 0), 584 MICBIAS_CTRL, 6, 3, 3, 0),
553 585
554 /* Left PGA to Left Output bypass */ 586 /* Output mixers */
555 SND_SOC_DAPM_MIXER("Left PGA Bypass Mixer", SND_SOC_NOPM, 0, 0, 587 SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
556 &aic3x_left_pga_bp_mixer_controls[0], 588 &aic3x_left_line_mixer_controls[0],
557 ARRAY_SIZE(aic3x_left_pga_bp_mixer_controls)), 589 ARRAY_SIZE(aic3x_left_line_mixer_controls)),
558 590 SND_SOC_DAPM_MIXER("Right Line Mixer", SND_SOC_NOPM, 0, 0,
559 /* Right PGA to Right Output bypass */ 591 &aic3x_right_line_mixer_controls[0],
560 SND_SOC_DAPM_MIXER("Right PGA Bypass Mixer", SND_SOC_NOPM, 0, 0, 592 ARRAY_SIZE(aic3x_right_line_mixer_controls)),
561 &aic3x_right_pga_bp_mixer_controls[0], 593 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0,
562 ARRAY_SIZE(aic3x_right_pga_bp_mixer_controls)), 594 &aic3x_mono_mixer_controls[0],
563 595 ARRAY_SIZE(aic3x_mono_mixer_controls)),
564 /* Left Line2 to Left Output bypass */ 596 SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
565 SND_SOC_DAPM_MIXER("Left Line2 Bypass Mixer", SND_SOC_NOPM, 0, 0, 597 &aic3x_left_hp_mixer_controls[0],
566 &aic3x_left_line2_bp_mixer_controls[0], 598 ARRAY_SIZE(aic3x_left_hp_mixer_controls)),
567 ARRAY_SIZE(aic3x_left_line2_bp_mixer_controls)), 599 SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
568 600 &aic3x_right_hp_mixer_controls[0],
569 /* Right Line2 to Right Output bypass */ 601 ARRAY_SIZE(aic3x_right_hp_mixer_controls)),
570 SND_SOC_DAPM_MIXER("Right Line2 Bypass Mixer", SND_SOC_NOPM, 0, 0, 602 SND_SOC_DAPM_MIXER("Left HPCOM Mixer", SND_SOC_NOPM, 0, 0,
571 &aic3x_right_line2_bp_mixer_controls[0], 603 &aic3x_left_hpcom_mixer_controls[0],
572 ARRAY_SIZE(aic3x_right_line2_bp_mixer_controls)), 604 ARRAY_SIZE(aic3x_left_hpcom_mixer_controls)),
605 SND_SOC_DAPM_MIXER("Right HPCOM Mixer", SND_SOC_NOPM, 0, 0,
606 &aic3x_right_hpcom_mixer_controls[0],
607 ARRAY_SIZE(aic3x_right_hpcom_mixer_controls)),
573 608
574 SND_SOC_DAPM_OUTPUT("LLOUT"), 609 SND_SOC_DAPM_OUTPUT("LLOUT"),
575 SND_SOC_DAPM_OUTPUT("RLOUT"), 610 SND_SOC_DAPM_OUTPUT("RLOUT"),
@@ -585,69 +620,26 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
585 SND_SOC_DAPM_INPUT("LINE1R"), 620 SND_SOC_DAPM_INPUT("LINE1R"),
586 SND_SOC_DAPM_INPUT("LINE2L"), 621 SND_SOC_DAPM_INPUT("LINE2L"),
587 SND_SOC_DAPM_INPUT("LINE2R"), 622 SND_SOC_DAPM_INPUT("LINE2R"),
588};
589 623
590static const struct snd_soc_dapm_route intercon[] = { 624 /*
591 /* Left Output */ 625 * Virtual output pin to detection block inside codec. This can be
592 {"Left DAC Mux", "DAC_L1", "Left DAC"}, 626 * used to keep codec bias on if gpio or detection features are needed.
593 {"Left DAC Mux", "DAC_L2", "Left DAC"}, 627 * Force pin on or construct a path with an input jack and mic bias
594 {"Left DAC Mux", "DAC_L3", "Left DAC"}, 628 * widgets.
595 629 */
596 {"Left DAC_L1 Mixer", "LineL Switch", "Left DAC Mux"}, 630 SND_SOC_DAPM_OUTPUT("Detection"),
597 {"Left DAC_L1 Mixer", "LineR Switch", "Left DAC Mux"}, 631};
598 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"},
599 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"},
600 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"},
601 {"Left Line Out", NULL, "Left DAC Mux"},
602 {"Left HP Out", NULL, "Left DAC Mux"},
603
604 {"Left HPCOM Mux", "differential of HPLOUT", "Left DAC_L1 Mixer"},
605 {"Left HPCOM Mux", "constant VCM", "Left DAC_L1 Mixer"},
606 {"Left HPCOM Mux", "single-ended", "Left DAC_L1 Mixer"},
607
608 {"Left Line Out", NULL, "Left DAC_L1 Mixer"},
609 {"Mono Out", NULL, "Left DAC_L1 Mixer"},
610 {"Left HP Out", NULL, "Left DAC_L1 Mixer"},
611 {"Left HP Com", NULL, "Left HPCOM Mux"},
612
613 {"LLOUT", NULL, "Left Line Out"},
614 {"LLOUT", NULL, "Left Line Out"},
615 {"HPLOUT", NULL, "Left HP Out"},
616 {"HPLCOM", NULL, "Left HP Com"},
617
618 /* Right Output */
619 {"Right DAC Mux", "DAC_R1", "Right DAC"},
620 {"Right DAC Mux", "DAC_R2", "Right DAC"},
621 {"Right DAC Mux", "DAC_R3", "Right DAC"},
622
623 {"Right DAC_R1 Mixer", "LineL Switch", "Right DAC Mux"},
624 {"Right DAC_R1 Mixer", "LineR Switch", "Right DAC Mux"},
625 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"},
626 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"},
627 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"},
628 {"Right Line Out", NULL, "Right DAC Mux"},
629 {"Right HP Out", NULL, "Right DAC Mux"},
630
631 {"Right HPCOM Mux", "differential of HPROUT", "Right DAC_R1 Mixer"},
632 {"Right HPCOM Mux", "constant VCM", "Right DAC_R1 Mixer"},
633 {"Right HPCOM Mux", "single-ended", "Right DAC_R1 Mixer"},
634 {"Right HPCOM Mux", "differential of HPLCOM", "Right DAC_R1 Mixer"},
635 {"Right HPCOM Mux", "external feedback", "Right DAC_R1 Mixer"},
636 632
637 {"Right Line Out", NULL, "Right DAC_R1 Mixer"}, 633static const struct snd_soc_dapm_widget aic3007_dapm_widgets[] = {
638 {"Mono Out", NULL, "Right DAC_R1 Mixer"}, 634 /* Class-D outputs */
639 {"Right HP Out", NULL, "Right DAC_R1 Mixer"}, 635 SND_SOC_DAPM_PGA("Left Class-D Out", CLASSD_CTRL, 3, 0, NULL, 0),
640 {"Right HP Com", NULL, "Right HPCOM Mux"}, 636 SND_SOC_DAPM_PGA("Right Class-D Out", CLASSD_CTRL, 2, 0, NULL, 0),
641 637
642 {"RLOUT", NULL, "Right Line Out"}, 638 SND_SOC_DAPM_OUTPUT("SPOP"),
643 {"RLOUT", NULL, "Right Line Out"}, 639 SND_SOC_DAPM_OUTPUT("SPOM"),
644 {"HPROUT", NULL, "Right HP Out"}, 640};
645 {"HPRCOM", NULL, "Right HP Com"},
646
647 /* Mono Output */
648 {"MONO_LOUT", NULL, "Mono Out"},
649 {"MONO_LOUT", NULL, "Mono Out"},
650 641
642static const struct snd_soc_dapm_route intercon[] = {
651 /* Left Input */ 643 /* Left Input */
652 {"Left Line1L Mux", "single-ended", "LINE1L"}, 644 {"Left Line1L Mux", "single-ended", "LINE1L"},
653 {"Left Line1L Mux", "differential", "LINE1L"}, 645 {"Left Line1L Mux", "differential", "LINE1L"},
@@ -680,74 +672,6 @@ static const struct snd_soc_dapm_route intercon[] = {
680 {"Right ADC", NULL, "Right PGA Mixer"}, 672 {"Right ADC", NULL, "Right PGA Mixer"},
681 {"Right ADC", NULL, "GPIO1 dmic modclk"}, 673 {"Right ADC", NULL, "GPIO1 dmic modclk"},
682 674
683 /* Left PGA Bypass */
684 {"Left PGA Bypass Mixer", "LineL Switch", "Left PGA Mixer"},
685 {"Left PGA Bypass Mixer", "LineR Switch", "Left PGA Mixer"},
686 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"},
687 {"Left PGA Bypass Mixer", "HPL Switch", "Left PGA Mixer"},
688 {"Left PGA Bypass Mixer", "HPR Switch", "Left PGA Mixer"},
689 {"Left PGA Bypass Mixer", "HPLCOM Switch", "Left PGA Mixer"},
690 {"Left PGA Bypass Mixer", "HPRCOM Switch", "Left PGA Mixer"},
691
692 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"},
693 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"},
694 {"Left HPCOM Mux", "single-ended", "Left PGA Bypass Mixer"},
695
696 {"Left Line Out", NULL, "Left PGA Bypass Mixer"},
697 {"Mono Out", NULL, "Left PGA Bypass Mixer"},
698 {"Left HP Out", NULL, "Left PGA Bypass Mixer"},
699
700 /* Right PGA Bypass */
701 {"Right PGA Bypass Mixer", "LineL Switch", "Right PGA Mixer"},
702 {"Right PGA Bypass Mixer", "LineR Switch", "Right PGA Mixer"},
703 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"},
704 {"Right PGA Bypass Mixer", "HPL Switch", "Right PGA Mixer"},
705 {"Right PGA Bypass Mixer", "HPR Switch", "Right PGA Mixer"},
706 {"Right PGA Bypass Mixer", "HPLCOM Switch", "Right PGA Mixer"},
707 {"Right PGA Bypass Mixer", "HPRCOM Switch", "Right PGA Mixer"},
708
709 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"},
710 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"},
711 {"Right HPCOM Mux", "single-ended", "Right PGA Bypass Mixer"},
712 {"Right HPCOM Mux", "differential of HPLCOM", "Right PGA Bypass Mixer"},
713 {"Right HPCOM Mux", "external feedback", "Right PGA Bypass Mixer"},
714
715 {"Right Line Out", NULL, "Right PGA Bypass Mixer"},
716 {"Mono Out", NULL, "Right PGA Bypass Mixer"},
717 {"Right HP Out", NULL, "Right PGA Bypass Mixer"},
718
719 /* Left Line2 Bypass */
720 {"Left Line2 Bypass Mixer", "LineL Switch", "Left Line2L Mux"},
721 {"Left Line2 Bypass Mixer", "LineR Switch", "Left Line2L Mux"},
722 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"},
723 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"},
724 {"Left Line2 Bypass Mixer", "HPLCOM Switch", "Left Line2L Mux"},
725
726 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"},
727 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"},
728 {"Left HPCOM Mux", "single-ended", "Left Line2 Bypass Mixer"},
729
730 {"Left Line Out", NULL, "Left Line2 Bypass Mixer"},
731 {"Mono Out", NULL, "Left Line2 Bypass Mixer"},
732 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"},
733
734 /* Right Line2 Bypass */
735 {"Right Line2 Bypass Mixer", "LineL Switch", "Right Line2R Mux"},
736 {"Right Line2 Bypass Mixer", "LineR Switch", "Right Line2R Mux"},
737 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"},
738 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"},
739 {"Right Line2 Bypass Mixer", "HPRCOM Switch", "Right Line2R Mux"},
740
741 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"},
742 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"},
743 {"Right HPCOM Mux", "single-ended", "Right Line2 Bypass Mixer"},
744 {"Right HPCOM Mux", "differential of HPLCOM", "Right Line2 Bypass Mixer"},
745 {"Right HPCOM Mux", "external feedback", "Right Line2 Bypass Mixer"},
746
747 {"Right Line Out", NULL, "Right Line2 Bypass Mixer"},
748 {"Mono Out", NULL, "Right Line2 Bypass Mixer"},
749 {"Right HP Out", NULL, "Right Line2 Bypass Mixer"},
750
751 /* 675 /*
752 * Logical path between digital mic enable and GPIO1 modulator clock 676 * Logical path between digital mic enable and GPIO1 modulator clock
753 * output function 677 * output function
@@ -755,15 +679,132 @@ static const struct snd_soc_dapm_route intercon[] = {
755 {"GPIO1 dmic modclk", NULL, "DMic Rate 128"}, 679 {"GPIO1 dmic modclk", NULL, "DMic Rate 128"},
756 {"GPIO1 dmic modclk", NULL, "DMic Rate 64"}, 680 {"GPIO1 dmic modclk", NULL, "DMic Rate 64"},
757 {"GPIO1 dmic modclk", NULL, "DMic Rate 32"}, 681 {"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
682
683 /* Left DAC Output */
684 {"Left DAC Mux", "DAC_L1", "Left DAC"},
685 {"Left DAC Mux", "DAC_L2", "Left DAC"},
686 {"Left DAC Mux", "DAC_L3", "Left DAC"},
687
688 /* Right DAC Output */
689 {"Right DAC Mux", "DAC_R1", "Right DAC"},
690 {"Right DAC Mux", "DAC_R2", "Right DAC"},
691 {"Right DAC Mux", "DAC_R3", "Right DAC"},
692
693 /* Left Line Output */
694 {"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
695 {"Left Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
696 {"Left Line Mixer", "DACL1 Switch", "Left DAC Mux"},
697 {"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
698 {"Left Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
699 {"Left Line Mixer", "DACR1 Switch", "Right DAC Mux"},
700
701 {"Left Line Out", NULL, "Left Line Mixer"},
702 {"Left Line Out", NULL, "Left DAC Mux"},
703 {"LLOUT", NULL, "Left Line Out"},
704
705 /* Right Line Output */
706 {"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
707 {"Right Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
708 {"Right Line Mixer", "DACL1 Switch", "Left DAC Mux"},
709 {"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
710 {"Right Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
711 {"Right Line Mixer", "DACR1 Switch", "Right DAC Mux"},
712
713 {"Right Line Out", NULL, "Right Line Mixer"},
714 {"Right Line Out", NULL, "Right DAC Mux"},
715 {"RLOUT", NULL, "Right Line Out"},
716
717 /* Mono Output */
718 {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
719 {"Mono Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
720 {"Mono Mixer", "DACL1 Switch", "Left DAC Mux"},
721 {"Mono Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
722 {"Mono Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
723 {"Mono Mixer", "DACR1 Switch", "Right DAC Mux"},
724
725 {"Mono Out", NULL, "Mono Mixer"},
726 {"MONO_LOUT", NULL, "Mono Out"},
727
728 /* Left HP Output */
729 {"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
730 {"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
731 {"Left HP Mixer", "DACL1 Switch", "Left DAC Mux"},
732 {"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
733 {"Left HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
734 {"Left HP Mixer", "DACR1 Switch", "Right DAC Mux"},
735
736 {"Left HP Out", NULL, "Left HP Mixer"},
737 {"Left HP Out", NULL, "Left DAC Mux"},
738 {"HPLOUT", NULL, "Left HP Out"},
739
740 /* Right HP Output */
741 {"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
742 {"Right HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
743 {"Right HP Mixer", "DACL1 Switch", "Left DAC Mux"},
744 {"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
745 {"Right HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
746 {"Right HP Mixer", "DACR1 Switch", "Right DAC Mux"},
747
748 {"Right HP Out", NULL, "Right HP Mixer"},
749 {"Right HP Out", NULL, "Right DAC Mux"},
750 {"HPROUT", NULL, "Right HP Out"},
751
752 /* Left HPCOM Output */
753 {"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
754 {"Left HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
755 {"Left HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
756 {"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
757 {"Left HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
758 {"Left HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
759
760 {"Left HPCOM Mux", "differential of HPLOUT", "Left HP Mixer"},
761 {"Left HPCOM Mux", "constant VCM", "Left HPCOM Mixer"},
762 {"Left HPCOM Mux", "single-ended", "Left HPCOM Mixer"},
763 {"Left HP Com", NULL, "Left HPCOM Mux"},
764 {"HPLCOM", NULL, "Left HP Com"},
765
766 /* Right HPCOM Output */
767 {"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
768 {"Right HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
769 {"Right HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
770 {"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
771 {"Right HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
772 {"Right HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
773
774 {"Right HPCOM Mux", "differential of HPROUT", "Right HP Mixer"},
775 {"Right HPCOM Mux", "constant VCM", "Right HPCOM Mixer"},
776 {"Right HPCOM Mux", "single-ended", "Right HPCOM Mixer"},
777 {"Right HPCOM Mux", "differential of HPLCOM", "Left HPCOM Mixer"},
778 {"Right HPCOM Mux", "external feedback", "Right HPCOM Mixer"},
779 {"Right HP Com", NULL, "Right HPCOM Mux"},
780 {"HPRCOM", NULL, "Right HP Com"},
781};
782
783static const struct snd_soc_dapm_route intercon_3007[] = {
784 /* Class-D outputs */
785 {"Left Class-D Out", NULL, "Left Line Out"},
786 {"Right Class-D Out", NULL, "Left Line Out"},
787 {"SPOP", NULL, "Left Class-D Out"},
788 {"SPOM", NULL, "Right Class-D Out"},
758}; 789};
759 790
760static int aic3x_add_widgets(struct snd_soc_codec *codec) 791static int aic3x_add_widgets(struct snd_soc_codec *codec)
761{ 792{
762 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 793 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
794 struct snd_soc_dapm_context *dapm = &codec->dapm;
795
796 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
763 ARRAY_SIZE(aic3x_dapm_widgets)); 797 ARRAY_SIZE(aic3x_dapm_widgets));
764 798
765 /* set up audio path interconnects */ 799 /* set up audio path interconnects */
766 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 800 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
801
802 if (aic3x->model == AIC3X_MODEL_3007) {
803 snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
804 ARRAY_SIZE(aic3007_dapm_widgets));
805 snd_soc_dapm_add_routes(dapm, intercon_3007,
806 ARRAY_SIZE(intercon_3007));
807 }
767 808
768 return 0; 809 return 0;
769} 810}
@@ -773,8 +814,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
773 struct snd_soc_dai *dai) 814 struct snd_soc_dai *dai)
774{ 815{
775 struct snd_soc_pcm_runtime *rtd = substream->private_data; 816 struct snd_soc_pcm_runtime *rtd = substream->private_data;
776 struct snd_soc_device *socdev = rtd->socdev; 817 struct snd_soc_codec *codec =rtd->codec;
777 struct snd_soc_codec *codec = socdev->card->codec;
778 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 818 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
779 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 819 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
780 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 820 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
@@ -783,8 +823,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
783 int clk; 823 int clk;
784 824
785 /* select data word length */ 825 /* select data word length */
786 data = 826 data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
787 aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
788 switch (params_format(params)) { 827 switch (params_format(params)) {
789 case SNDRV_PCM_FORMAT_S16_LE: 828 case SNDRV_PCM_FORMAT_S16_LE:
790 break; 829 break;
@@ -798,7 +837,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
798 data |= (0x03 << 4); 837 data |= (0x03 << 4);
799 break; 838 break;
800 } 839 }
801 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data); 840 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
802 841
803 /* Fsref can be 44100 or 48000 */ 842 /* Fsref can be 44100 or 48000 */
804 fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000; 843 fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
@@ -813,17 +852,17 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
813 852
814 if (bypass_pll) { 853 if (bypass_pll) {
815 pll_q &= 0xf; 854 pll_q &= 0xf;
816 aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT); 855 snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
817 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV); 856 snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
818 /* disable PLL if it is bypassed */ 857 /* disable PLL if it is bypassed */
819 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 858 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
820 aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE); 859 snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE);
821 860
822 } else { 861 } else {
823 aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV); 862 snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
824 /* enable PLL when it is used */ 863 /* enable PLL when it is used */
825 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 864 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
826 aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE); 865 snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
827 } 866 }
828 867
829 /* Route Left DAC to left channel input and 868 /* Route Left DAC to left channel input and
@@ -832,7 +871,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
832 data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000; 871 data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
833 if (params_rate(params) >= 64000) 872 if (params_rate(params) >= 64000)
834 data |= DUAL_RATE_MODE; 873 data |= DUAL_RATE_MODE;
835 aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data); 874 snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
836 875
837 /* codec sample rate select */ 876 /* codec sample rate select */
838 data = (fsref * 20) / params_rate(params); 877 data = (fsref * 20) / params_rate(params);
@@ -841,12 +880,12 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
841 data /= 5; 880 data /= 5;
842 data -= 2; 881 data -= 2;
843 data |= (data << 4); 882 data |= (data << 4);
844 aic3x_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data); 883 snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
845 884
846 if (bypass_pll) 885 if (bypass_pll)
847 return 0; 886 return 0;
848 887
849 /* Use PLL, compute apropriate setup for j, d, r and p, the closest 888 /* Use PLL, compute appropriate setup for j, d, r and p, the closest
850 * one wins the game. Try with d==0 first, next with d!=0. 889 * one wins the game. Try with d==0 first, next with d!=0.
851 * Constraints for j are according to the datasheet. 890 * Constraints for j are according to the datasheet.
852 * The sysclk is divided by 1000 to prevent integer overflows. 891 * The sysclk is divided by 1000 to prevent integer overflows.
@@ -910,13 +949,16 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
910 } 949 }
911 950
912found: 951found:
913 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 952 data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
914 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 953 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
915 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); 954 data | (pll_p << PLLP_SHIFT));
916 aic3x_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT); 955 snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
917 aic3x_write(codec, AIC3X_PLL_PROGC_REG, (pll_d >> 6) << PLLD_MSB_SHIFT); 956 pll_r << PLLR_SHIFT);
918 aic3x_write(codec, AIC3X_PLL_PROGD_REG, 957 snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
919 (pll_d & 0x3F) << PLLD_LSB_SHIFT); 958 snd_soc_write(codec, AIC3X_PLL_PROGC_REG,
959 (pll_d >> 6) << PLLD_MSB_SHIFT);
960 snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
961 (pll_d & 0x3F) << PLLD_LSB_SHIFT);
920 962
921 return 0; 963 return 0;
922} 964}
@@ -924,15 +966,15 @@ found:
924static int aic3x_mute(struct snd_soc_dai *dai, int mute) 966static int aic3x_mute(struct snd_soc_dai *dai, int mute)
925{ 967{
926 struct snd_soc_codec *codec = dai->codec; 968 struct snd_soc_codec *codec = dai->codec;
927 u8 ldac_reg = aic3x_read_reg_cache(codec, LDAC_VOL) & ~MUTE_ON; 969 u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
928 u8 rdac_reg = aic3x_read_reg_cache(codec, RDAC_VOL) & ~MUTE_ON; 970 u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
929 971
930 if (mute) { 972 if (mute) {
931 aic3x_write(codec, LDAC_VOL, ldac_reg | MUTE_ON); 973 snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
932 aic3x_write(codec, RDAC_VOL, rdac_reg | MUTE_ON); 974 snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
933 } else { 975 } else {
934 aic3x_write(codec, LDAC_VOL, ldac_reg); 976 snd_soc_write(codec, LDAC_VOL, ldac_reg);
935 aic3x_write(codec, RDAC_VOL, rdac_reg); 977 snd_soc_write(codec, RDAC_VOL, rdac_reg);
936 } 978 }
937 979
938 return 0; 980 return 0;
@@ -956,8 +998,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
956 u8 iface_areg, iface_breg; 998 u8 iface_areg, iface_breg;
957 int delay = 0; 999 int delay = 0;
958 1000
959 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f; 1001 iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
960 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f; 1002 iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
961 1003
962 /* set master/slave audio interface */ 1004 /* set master/slave audio interface */
963 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1005 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -996,13 +1038,105 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
996 } 1038 }
997 1039
998 /* set iface */ 1040 /* set iface */
999 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg); 1041 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
1000 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg); 1042 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
1001 aic3x_write(codec, AIC3X_ASD_INTF_CTRLC, delay); 1043 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
1044
1045 return 0;
1046}
1047
1048static int aic3x_init_3007(struct snd_soc_codec *codec)
1049{
1050 u8 tmp1, tmp2, *cache = codec->reg_cache;
1051
1052 /*
1053 * There is no need to cache writes to undocumented page 0xD but
1054 * respective page 0 register cache entries must be preserved
1055 */
1056 tmp1 = cache[0xD];
1057 tmp2 = cache[0x8];
1058 /* Class-D speaker driver init; datasheet p. 46 */
1059 snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x0D);
1060 snd_soc_write(codec, 0xD, 0x0D);
1061 snd_soc_write(codec, 0x8, 0x5C);
1062 snd_soc_write(codec, 0x8, 0x5D);
1063 snd_soc_write(codec, 0x8, 0x5C);
1064 snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x00);
1065 cache[0xD] = tmp1;
1066 cache[0x8] = tmp2;
1067
1068 return 0;
1069}
1070
1071static int aic3x_regulator_event(struct notifier_block *nb,
1072 unsigned long event, void *data)
1073{
1074 struct aic3x_disable_nb *disable_nb =
1075 container_of(nb, struct aic3x_disable_nb, nb);
1076 struct aic3x_priv *aic3x = disable_nb->aic3x;
1077
1078 if (event & REGULATOR_EVENT_DISABLE) {
1079 /*
1080 * Put codec to reset and require cache sync as at least one
1081 * of the supplies was disabled
1082 */
1083 if (gpio_is_valid(aic3x->gpio_reset))
1084 gpio_set_value(aic3x->gpio_reset, 0);
1085 aic3x->codec->cache_sync = 1;
1086 }
1002 1087
1003 return 0; 1088 return 0;
1004} 1089}
1005 1090
1091static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1092{
1093 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1094 int i, ret;
1095 u8 *cache = codec->reg_cache;
1096
1097 if (power) {
1098 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1099 aic3x->supplies);
1100 if (ret)
1101 goto out;
1102 aic3x->power = 1;
1103 /*
1104 * Reset release and cache sync is necessary only if some
1105 * supply was off or if there were cached writes
1106 */
1107 if (!codec->cache_sync)
1108 goto out;
1109
1110 if (gpio_is_valid(aic3x->gpio_reset)) {
1111 udelay(1);
1112 gpio_set_value(aic3x->gpio_reset, 1);
1113 }
1114
1115 /* Sync reg_cache with the hardware */
1116 codec->cache_only = 0;
1117 for (i = AIC3X_SAMPLE_RATE_SEL_REG; i < ARRAY_SIZE(aic3x_reg); i++)
1118 snd_soc_write(codec, i, cache[i]);
1119 if (aic3x->model == AIC3X_MODEL_3007)
1120 aic3x_init_3007(codec);
1121 codec->cache_sync = 0;
1122 } else {
1123 /*
1124 * Do soft reset to this codec instance in order to clear
1125 * possible VDD leakage currents in case the supply regulators
1126 * remain on
1127 */
1128 snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
1129 codec->cache_sync = 1;
1130 aic3x->power = 0;
1131 /* HW writes are needless when bias is off */
1132 codec->cache_only = 1;
1133 ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies),
1134 aic3x->supplies);
1135 }
1136out:
1137 return ret;
1138}
1139
1006static int aic3x_set_bias_level(struct snd_soc_codec *codec, 1140static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1007 enum snd_soc_bias_level level) 1141 enum snd_soc_bias_level level)
1008{ 1142{
@@ -1013,25 +1147,31 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1013 case SND_SOC_BIAS_ON: 1147 case SND_SOC_BIAS_ON:
1014 break; 1148 break;
1015 case SND_SOC_BIAS_PREPARE: 1149 case SND_SOC_BIAS_PREPARE:
1016 if (aic3x->master) { 1150 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
1151 aic3x->master) {
1017 /* enable pll */ 1152 /* enable pll */
1018 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 1153 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1019 aic3x_write(codec, AIC3X_PLL_PROGA_REG, 1154 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1020 reg | PLL_ENABLE); 1155 reg | PLL_ENABLE);
1021 } 1156 }
1022 break; 1157 break;
1023 case SND_SOC_BIAS_STANDBY: 1158 case SND_SOC_BIAS_STANDBY:
1024 /* fall through and disable pll */ 1159 if (!aic3x->power)
1025 case SND_SOC_BIAS_OFF: 1160 aic3x_set_power(codec, 1);
1026 if (aic3x->master) { 1161 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
1162 aic3x->master) {
1027 /* disable pll */ 1163 /* disable pll */
1028 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 1164 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
1029 aic3x_write(codec, AIC3X_PLL_PROGA_REG, 1165 snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
1030 reg & ~PLL_ENABLE); 1166 reg & ~PLL_ENABLE);
1031 } 1167 }
1032 break; 1168 break;
1169 case SND_SOC_BIAS_OFF:
1170 if (aic3x->power)
1171 aic3x_set_power(codec, 0);
1172 break;
1033 } 1173 }
1034 codec->bias_level = level; 1174 codec->dapm.bias_level = level;
1035 1175
1036 return 0; 1176 return 0;
1037} 1177}
@@ -1040,15 +1180,15 @@ void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
1040{ 1180{
1041 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; 1181 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1042 u8 bit = gpio ? 3: 0; 1182 u8 bit = gpio ? 3: 0;
1043 u8 val = aic3x_read_reg_cache(codec, reg) & ~(1 << bit); 1183 u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
1044 aic3x_write(codec, reg, val | (!!state << bit)); 1184 snd_soc_write(codec, reg, val | (!!state << bit));
1045} 1185}
1046EXPORT_SYMBOL_GPL(aic3x_set_gpio); 1186EXPORT_SYMBOL_GPL(aic3x_set_gpio);
1047 1187
1048int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio) 1188int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
1049{ 1189{
1050 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; 1190 u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
1051 u8 val, bit = gpio ? 2: 1; 1191 u8 val = 0, bit = gpio ? 2 : 1;
1052 1192
1053 aic3x_read(codec, reg, &val); 1193 aic3x_read(codec, reg, &val);
1054 return (val >> bit) & 1; 1194 return (val >> bit) & 1;
@@ -1070,13 +1210,13 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1070 if (detect & AIC3X_HEADSET_DETECT_MASK) 1210 if (detect & AIC3X_HEADSET_DETECT_MASK)
1071 val |= AIC3X_HEADSET_DETECT_ENABLED; 1211 val |= AIC3X_HEADSET_DETECT_ENABLED;
1072 1212
1073 aic3x_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); 1213 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1074} 1214}
1075EXPORT_SYMBOL_GPL(aic3x_set_headset_detection); 1215EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1076 1216
1077int aic3x_headset_detected(struct snd_soc_codec *codec) 1217int aic3x_headset_detected(struct snd_soc_codec *codec)
1078{ 1218{
1079 u8 val; 1219 u8 val = 0;
1080 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); 1220 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1081 return (val >> 4) & 1; 1221 return (val >> 4) & 1;
1082} 1222}
@@ -1084,7 +1224,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
1084 1224
1085int aic3x_button_pressed(struct snd_soc_codec *codec) 1225int aic3x_button_pressed(struct snd_soc_codec *codec)
1086{ 1226{
1087 u8 val; 1227 u8 val = 0;
1088 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); 1228 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1089 return (val >> 5) & 1; 1229 return (val >> 5) & 1;
1090} 1230}
@@ -1101,8 +1241,8 @@ static struct snd_soc_dai_ops aic3x_dai_ops = {
1101 .set_fmt = aic3x_set_dai_fmt, 1241 .set_fmt = aic3x_set_dai_fmt,
1102}; 1242};
1103 1243
1104struct snd_soc_dai aic3x_dai = { 1244static struct snd_soc_dai_driver aic3x_dai = {
1105 .name = "tlv320aic3x", 1245 .name = "tlv320aic3x-hifi",
1106 .playback = { 1246 .playback = {
1107 .stream_name = "Playback", 1247 .stream_name = "Playback",
1108 .channels_min = 1, 1248 .channels_min = 1,
@@ -1116,34 +1256,18 @@ struct snd_soc_dai aic3x_dai = {
1116 .rates = AIC3X_RATES, 1256 .rates = AIC3X_RATES,
1117 .formats = AIC3X_FORMATS,}, 1257 .formats = AIC3X_FORMATS,},
1118 .ops = &aic3x_dai_ops, 1258 .ops = &aic3x_dai_ops,
1259 .symmetric_rates = 1,
1119}; 1260};
1120EXPORT_SYMBOL_GPL(aic3x_dai);
1121 1261
1122static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) 1262static int aic3x_suspend(struct snd_soc_codec *codec, pm_message_t state)
1123{ 1263{
1124 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1125 struct snd_soc_codec *codec = socdev->card->codec;
1126
1127 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1264 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1128 1265
1129 return 0; 1266 return 0;
1130} 1267}
1131 1268
1132static int aic3x_resume(struct platform_device *pdev) 1269static int aic3x_resume(struct snd_soc_codec *codec)
1133{ 1270{
1134 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1135 struct snd_soc_codec *codec = socdev->card->codec;
1136 int i;
1137 u8 data[2];
1138 u8 *cache = codec->reg_cache;
1139
1140 /* Sync reg_cache with the hardware */
1141 for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++) {
1142 data[0] = i;
1143 data[1] = cache[i];
1144 codec->hw_write(codec->control_data, data, 2);
1145 }
1146
1147 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1271 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1148 1272
1149 return 0; 1273 return 0;
@@ -1155,152 +1279,221 @@ static int aic3x_resume(struct platform_device *pdev)
1155 */ 1279 */
1156static int aic3x_init(struct snd_soc_codec *codec) 1280static int aic3x_init(struct snd_soc_codec *codec)
1157{ 1281{
1282 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1158 int reg; 1283 int reg;
1159 1284
1160 mutex_init(&codec->mutex); 1285 snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
1161 INIT_LIST_HEAD(&codec->dapm_widgets); 1286 snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
1162 INIT_LIST_HEAD(&codec->dapm_paths);
1163
1164 codec->name = "tlv320aic3x";
1165 codec->owner = THIS_MODULE;
1166 codec->read = aic3x_read_reg_cache;
1167 codec->write = aic3x_write;
1168 codec->set_bias_level = aic3x_set_bias_level;
1169 codec->dai = &aic3x_dai;
1170 codec->num_dai = 1;
1171 codec->reg_cache_size = ARRAY_SIZE(aic3x_reg);
1172 codec->reg_cache = kmemdup(aic3x_reg, sizeof(aic3x_reg), GFP_KERNEL);
1173 if (codec->reg_cache == NULL)
1174 return -ENOMEM;
1175
1176 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
1177 aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
1178 1287
1179 /* DAC default volume and mute */ 1288 /* DAC default volume and mute */
1180 aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON); 1289 snd_soc_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
1181 aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON); 1290 snd_soc_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
1182 1291
1183 /* DAC to HP default volume and route to Output mixer */ 1292 /* DAC to HP default volume and route to Output mixer */
1184 aic3x_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON); 1293 snd_soc_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
1185 aic3x_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON); 1294 snd_soc_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
1186 aic3x_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON); 1295 snd_soc_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
1187 aic3x_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON); 1296 snd_soc_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
1188 /* DAC to Line Out default volume and route to Output mixer */ 1297 /* DAC to Line Out default volume and route to Output mixer */
1189 aic3x_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON); 1298 snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1190 aic3x_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON); 1299 snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1191 /* DAC to Mono Line Out default volume and route to Output mixer */ 1300 /* DAC to Mono Line Out default volume and route to Output mixer */
1192 aic3x_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); 1301 snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1193 aic3x_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); 1302 snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1194 1303
1195 /* unmute all outputs */ 1304 /* unmute all outputs */
1196 reg = aic3x_read_reg_cache(codec, LLOPM_CTRL); 1305 reg = snd_soc_read(codec, LLOPM_CTRL);
1197 aic3x_write(codec, LLOPM_CTRL, reg | UNMUTE); 1306 snd_soc_write(codec, LLOPM_CTRL, reg | UNMUTE);
1198 reg = aic3x_read_reg_cache(codec, RLOPM_CTRL); 1307 reg = snd_soc_read(codec, RLOPM_CTRL);
1199 aic3x_write(codec, RLOPM_CTRL, reg | UNMUTE); 1308 snd_soc_write(codec, RLOPM_CTRL, reg | UNMUTE);
1200 reg = aic3x_read_reg_cache(codec, MONOLOPM_CTRL); 1309 reg = snd_soc_read(codec, MONOLOPM_CTRL);
1201 aic3x_write(codec, MONOLOPM_CTRL, reg | UNMUTE); 1310 snd_soc_write(codec, MONOLOPM_CTRL, reg | UNMUTE);
1202 reg = aic3x_read_reg_cache(codec, HPLOUT_CTRL); 1311 reg = snd_soc_read(codec, HPLOUT_CTRL);
1203 aic3x_write(codec, HPLOUT_CTRL, reg | UNMUTE); 1312 snd_soc_write(codec, HPLOUT_CTRL, reg | UNMUTE);
1204 reg = aic3x_read_reg_cache(codec, HPROUT_CTRL); 1313 reg = snd_soc_read(codec, HPROUT_CTRL);
1205 aic3x_write(codec, HPROUT_CTRL, reg | UNMUTE); 1314 snd_soc_write(codec, HPROUT_CTRL, reg | UNMUTE);
1206 reg = aic3x_read_reg_cache(codec, HPLCOM_CTRL); 1315 reg = snd_soc_read(codec, HPLCOM_CTRL);
1207 aic3x_write(codec, HPLCOM_CTRL, reg | UNMUTE); 1316 snd_soc_write(codec, HPLCOM_CTRL, reg | UNMUTE);
1208 reg = aic3x_read_reg_cache(codec, HPRCOM_CTRL); 1317 reg = snd_soc_read(codec, HPRCOM_CTRL);
1209 aic3x_write(codec, HPRCOM_CTRL, reg | UNMUTE); 1318 snd_soc_write(codec, HPRCOM_CTRL, reg | UNMUTE);
1210 1319
1211 /* ADC default volume and unmute */ 1320 /* ADC default volume and unmute */
1212 aic3x_write(codec, LADC_VOL, DEFAULT_GAIN); 1321 snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
1213 aic3x_write(codec, RADC_VOL, DEFAULT_GAIN); 1322 snd_soc_write(codec, RADC_VOL, DEFAULT_GAIN);
1214 /* By default route Line1 to ADC PGA mixer */ 1323 /* By default route Line1 to ADC PGA mixer */
1215 aic3x_write(codec, LINE1L_2_LADC_CTRL, 0x0); 1324 snd_soc_write(codec, LINE1L_2_LADC_CTRL, 0x0);
1216 aic3x_write(codec, LINE1R_2_RADC_CTRL, 0x0); 1325 snd_soc_write(codec, LINE1R_2_RADC_CTRL, 0x0);
1217 1326
1218 /* PGA to HP Bypass default volume, disconnect from Output Mixer */ 1327 /* PGA to HP Bypass default volume, disconnect from Output Mixer */
1219 aic3x_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL); 1328 snd_soc_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
1220 aic3x_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL); 1329 snd_soc_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
1221 aic3x_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL); 1330 snd_soc_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
1222 aic3x_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL); 1331 snd_soc_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
1223 /* PGA to Line Out default volume, disconnect from Output Mixer */ 1332 /* PGA to Line Out default volume, disconnect from Output Mixer */
1224 aic3x_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL); 1333 snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
1225 aic3x_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL); 1334 snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
1226 /* PGA to Mono Line Out default volume, disconnect from Output Mixer */ 1335 /* PGA to Mono Line Out default volume, disconnect from Output Mixer */
1227 aic3x_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL); 1336 snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
1228 aic3x_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL); 1337 snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
1229 1338
1230 /* Line2 to HP Bypass default volume, disconnect from Output Mixer */ 1339 /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
1231 aic3x_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL); 1340 snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
1232 aic3x_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL); 1341 snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
1233 aic3x_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL); 1342 snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
1234 aic3x_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL); 1343 snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
1235 /* Line2 Line Out default volume, disconnect from Output Mixer */ 1344 /* Line2 Line Out default volume, disconnect from Output Mixer */
1236 aic3x_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL); 1345 snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
1237 aic3x_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL); 1346 snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
1238 /* Line2 to Mono Out default volume, disconnect from Output Mixer */ 1347 /* Line2 to Mono Out default volume, disconnect from Output Mixer */
1239 aic3x_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL); 1348 snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
1240 aic3x_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); 1349 snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
1241 1350
1242 /* off, with power on */ 1351 if (aic3x->model == AIC3X_MODEL_3007) {
1243 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1352 aic3x_init_3007(codec);
1353 snd_soc_write(codec, CLASSD_CTRL, 0);
1354 }
1244 1355
1245 return 0; 1356 return 0;
1246} 1357}
1247 1358
1248static struct snd_soc_codec *aic3x_codec; 1359static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
1360{
1361 struct aic3x_priv *a;
1362
1363 list_for_each_entry(a, &reset_list, list) {
1364 if (gpio_is_valid(aic3x->gpio_reset) &&
1365 aic3x->gpio_reset == a->gpio_reset)
1366 return true;
1367 }
1368
1369 return false;
1370}
1249 1371
1250static int aic3x_register(struct snd_soc_codec *codec) 1372static int aic3x_probe(struct snd_soc_codec *codec)
1251{ 1373{
1252 int ret; 1374 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1375 int ret, i;
1376
1377 INIT_LIST_HEAD(&aic3x->list);
1378 codec->control_data = aic3x->control_data;
1379 aic3x->codec = codec;
1380 codec->dapm.idle_bias_off = 1;
1253 1381
1254 ret = aic3x_init(codec); 1382 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1255 if (ret < 0) { 1383 if (ret != 0) {
1256 dev_err(codec->dev, "Failed to initialise device\n"); 1384 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1257 return ret; 1385 return ret;
1258 } 1386 }
1259 1387
1260 aic3x_codec = codec; 1388 if (gpio_is_valid(aic3x->gpio_reset) &&
1389 !aic3x_is_shared_reset(aic3x)) {
1390 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1391 if (ret != 0)
1392 goto err_gpio;
1393 gpio_direction_output(aic3x->gpio_reset, 0);
1394 }
1261 1395
1262 ret = snd_soc_register_codec(codec); 1396 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1263 if (ret) { 1397 aic3x->supplies[i].supply = aic3x_supply_names[i];
1264 dev_err(codec->dev, "Failed to register codec\n"); 1398
1265 return ret; 1399 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
1400 aic3x->supplies);
1401 if (ret != 0) {
1402 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1403 goto err_get;
1404 }
1405 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
1406 aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
1407 aic3x->disable_nb[i].aic3x = aic3x;
1408 ret = regulator_register_notifier(aic3x->supplies[i].consumer,
1409 &aic3x->disable_nb[i].nb);
1410 if (ret) {
1411 dev_err(codec->dev,
1412 "Failed to request regulator notifier: %d\n",
1413 ret);
1414 goto err_notif;
1415 }
1266 } 1416 }
1267 1417
1268 ret = snd_soc_register_dai(&aic3x_dai); 1418 codec->cache_only = 1;
1269 if (ret) { 1419 aic3x_init(codec);
1270 dev_err(codec->dev, "Failed to register dai\n"); 1420
1271 snd_soc_unregister_codec(codec); 1421 if (aic3x->setup) {
1272 return ret; 1422 /* setup GPIO functions */
1423 snd_soc_write(codec, AIC3X_GPIO1_REG,
1424 (aic3x->setup->gpio_func[0] & 0xf) << 4);
1425 snd_soc_write(codec, AIC3X_GPIO2_REG,
1426 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1273 } 1427 }
1274 1428
1429 snd_soc_add_controls(codec, aic3x_snd_controls,
1430 ARRAY_SIZE(aic3x_snd_controls));
1431 if (aic3x->model == AIC3X_MODEL_3007)
1432 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1433
1434 aic3x_add_widgets(codec);
1435 list_add(&aic3x->list, &reset_list);
1436
1275 return 0; 1437 return 0;
1438
1439err_notif:
1440 while (i--)
1441 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1442 &aic3x->disable_nb[i].nb);
1443 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1444err_get:
1445 if (gpio_is_valid(aic3x->gpio_reset) &&
1446 !aic3x_is_shared_reset(aic3x))
1447 gpio_free(aic3x->gpio_reset);
1448err_gpio:
1449 return ret;
1276} 1450}
1277 1451
1278static int aic3x_unregister(struct aic3x_priv *aic3x) 1452static int aic3x_remove(struct snd_soc_codec *codec)
1279{ 1453{
1280 aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF); 1454 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1281 1455 int i;
1282 snd_soc_unregister_dai(&aic3x_dai);
1283 snd_soc_unregister_codec(&aic3x->codec);
1284 1456
1285 if (aic3x->gpio_reset >= 0) { 1457 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1458 list_del(&aic3x->list);
1459 if (gpio_is_valid(aic3x->gpio_reset) &&
1460 !aic3x_is_shared_reset(aic3x)) {
1286 gpio_set_value(aic3x->gpio_reset, 0); 1461 gpio_set_value(aic3x->gpio_reset, 0);
1287 gpio_free(aic3x->gpio_reset); 1462 gpio_free(aic3x->gpio_reset);
1288 } 1463 }
1289 regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1464 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1465 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1466 &aic3x->disable_nb[i].nb);
1290 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1467 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1291 1468
1292 kfree(aic3x);
1293 aic3x_codec = NULL;
1294
1295 return 0; 1469 return 0;
1296} 1470}
1297 1471
1472static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1473 .set_bias_level = aic3x_set_bias_level,
1474 .reg_cache_size = ARRAY_SIZE(aic3x_reg),
1475 .reg_word_size = sizeof(u8),
1476 .reg_cache_default = aic3x_reg,
1477 .probe = aic3x_probe,
1478 .remove = aic3x_remove,
1479 .suspend = aic3x_suspend,
1480 .resume = aic3x_resume,
1481};
1482
1298#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1483#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1299/* 1484/*
1300 * AIC3X 2 wire address can be up to 4 devices with device addresses 1485 * AIC3X 2 wire address can be up to 4 devices with device addresses
1301 * 0x18, 0x19, 0x1A, 0x1B 1486 * 0x18, 0x19, 0x1A, 0x1B
1302 */ 1487 */
1303 1488
1489static const struct i2c_device_id aic3x_i2c_id[] = {
1490 [AIC3X_MODEL_3X] = { "tlv320aic3x", 0 },
1491 [AIC3X_MODEL_33] = { "tlv320aic33", 0 },
1492 [AIC3X_MODEL_3007] = { "tlv320aic3007", 0 },
1493 { }
1494};
1495MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1496
1304/* 1497/*
1305 * If the i2c layer weren't so broken, we could pass this kind of data 1498 * If the i2c layer weren't so broken, we could pass this kind of data
1306 * around 1499 * around
@@ -1308,10 +1501,10 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
1308static int aic3x_i2c_probe(struct i2c_client *i2c, 1501static int aic3x_i2c_probe(struct i2c_client *i2c,
1309 const struct i2c_device_id *id) 1502 const struct i2c_device_id *id)
1310{ 1503{
1311 struct snd_soc_codec *codec;
1312 struct aic3x_priv *aic3x;
1313 struct aic3x_pdata *pdata = i2c->dev.platform_data; 1504 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1314 int ret, i; 1505 struct aic3x_priv *aic3x;
1506 int ret;
1507 const struct i2c_device_id *tbl;
1315 1508
1316 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1509 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1317 if (aic3x == NULL) { 1510 if (aic3x == NULL) {
@@ -1319,180 +1512,68 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1319 return -ENOMEM; 1512 return -ENOMEM;
1320 } 1513 }
1321 1514
1322 codec = &aic3x->codec; 1515 aic3x->control_data = i2c;
1323 codec->dev = &i2c->dev; 1516 aic3x->control_type = SND_SOC_I2C;
1324 snd_soc_codec_set_drvdata(codec, aic3x);
1325 codec->control_data = i2c;
1326 codec->hw_write = (hw_write_t) i2c_master_send;
1327 1517
1328 i2c_set_clientdata(i2c, aic3x); 1518 i2c_set_clientdata(i2c, aic3x);
1329 1519 if (pdata) {
1330 aic3x->gpio_reset = -1;
1331 if (pdata && pdata->gpio_reset >= 0) {
1332 ret = gpio_request(pdata->gpio_reset, "tlv320aic3x reset");
1333 if (ret != 0)
1334 goto err_gpio;
1335 aic3x->gpio_reset = pdata->gpio_reset; 1520 aic3x->gpio_reset = pdata->gpio_reset;
1336 gpio_direction_output(aic3x->gpio_reset, 0); 1521 aic3x->setup = pdata->setup;
1337 } 1522 } else {
1338 1523 aic3x->gpio_reset = -1;
1339 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1340 aic3x->supplies[i].supply = aic3x_supply_names[i];
1341
1342 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
1343 aic3x->supplies);
1344 if (ret != 0) {
1345 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1346 goto err_get;
1347 }
1348
1349 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1350 aic3x->supplies);
1351 if (ret != 0) {
1352 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1353 goto err_enable;
1354 } 1524 }
1355 1525
1356 if (aic3x->gpio_reset >= 0) { 1526 for (tbl = aic3x_i2c_id; tbl->name[0]; tbl++) {
1357 udelay(1); 1527 if (!strcmp(tbl->name, id->name))
1358 gpio_set_value(aic3x->gpio_reset, 1); 1528 break;
1359 } 1529 }
1530 aic3x->model = tbl - aic3x_i2c_id;
1360 1531
1361 return aic3x_register(codec); 1532 ret = snd_soc_register_codec(&i2c->dev,
1362 1533 &soc_codec_dev_aic3x, &aic3x_dai, 1);
1363err_enable: 1534 if (ret < 0)
1364 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1535 kfree(aic3x);
1365err_get:
1366 if (aic3x->gpio_reset >= 0)
1367 gpio_free(aic3x->gpio_reset);
1368err_gpio:
1369 kfree(aic3x);
1370 return ret; 1536 return ret;
1371} 1537}
1372 1538
1373static int aic3x_i2c_remove(struct i2c_client *client) 1539static int aic3x_i2c_remove(struct i2c_client *client)
1374{ 1540{
1375 struct aic3x_priv *aic3x = i2c_get_clientdata(client); 1541 snd_soc_unregister_codec(&client->dev);
1376 1542 kfree(i2c_get_clientdata(client));
1377 return aic3x_unregister(aic3x); 1543 return 0;
1378} 1544}
1379 1545
1380static const struct i2c_device_id aic3x_i2c_id[] = {
1381 { "tlv320aic3x", 0 },
1382 { "tlv320aic33", 0 },
1383 { }
1384};
1385MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1386
1387/* machine i2c codec control layer */ 1546/* machine i2c codec control layer */
1388static struct i2c_driver aic3x_i2c_driver = { 1547static struct i2c_driver aic3x_i2c_driver = {
1389 .driver = { 1548 .driver = {
1390 .name = "aic3x I2C Codec", 1549 .name = "tlv320aic3x-codec",
1391 .owner = THIS_MODULE, 1550 .owner = THIS_MODULE,
1392 }, 1551 },
1393 .probe = aic3x_i2c_probe, 1552 .probe = aic3x_i2c_probe,
1394 .remove = aic3x_i2c_remove, 1553 .remove = aic3x_i2c_remove,
1395 .id_table = aic3x_i2c_id, 1554 .id_table = aic3x_i2c_id,
1396}; 1555};
1397
1398static inline void aic3x_i2c_init(void)
1399{
1400 int ret;
1401
1402 ret = i2c_add_driver(&aic3x_i2c_driver);
1403 if (ret)
1404 printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
1405 __func__, ret);
1406}
1407
1408static inline void aic3x_i2c_exit(void)
1409{
1410 i2c_del_driver(&aic3x_i2c_driver);
1411}
1412#else
1413static inline void aic3x_i2c_init(void) { }
1414static inline void aic3x_i2c_exit(void) { }
1415#endif 1556#endif
1416 1557
1417static int aic3x_probe(struct platform_device *pdev) 1558static int __init aic3x_modinit(void)
1418{ 1559{
1419 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1420 struct aic3x_setup_data *setup;
1421 struct snd_soc_codec *codec;
1422 int ret = 0; 1560 int ret = 0;
1423 1561#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1424 codec = aic3x_codec; 1562 ret = i2c_add_driver(&aic3x_i2c_driver);
1425 if (!codec) { 1563 if (ret != 0) {
1426 dev_err(&pdev->dev, "Codec not registered\n"); 1564 printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
1427 return -ENODEV; 1565 ret);
1428 }
1429
1430 socdev->card->codec = codec;
1431 setup = socdev->codec_data;
1432
1433 if (setup) {
1434 /* setup GPIO functions */
1435 aic3x_write(codec, AIC3X_GPIO1_REG,
1436 (setup->gpio_func[0] & 0xf) << 4);
1437 aic3x_write(codec, AIC3X_GPIO2_REG,
1438 (setup->gpio_func[1] & 0xf) << 4);
1439 }
1440
1441 /* register pcms */
1442 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1443 if (ret < 0) {
1444 printk(KERN_ERR "aic3x: failed to create pcms\n");
1445 goto pcm_err;
1446 } 1566 }
1447 1567#endif
1448 snd_soc_add_controls(codec, aic3x_snd_controls,
1449 ARRAY_SIZE(aic3x_snd_controls));
1450
1451 aic3x_add_widgets(codec);
1452
1453 return ret;
1454
1455pcm_err:
1456 kfree(codec->reg_cache);
1457 return ret; 1568 return ret;
1458} 1569}
1459
1460static int aic3x_remove(struct platform_device *pdev)
1461{
1462 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1463 struct snd_soc_codec *codec = socdev->card->codec;
1464
1465 /* power down chip */
1466 if (codec->control_data)
1467 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1468
1469 snd_soc_free_pcms(socdev);
1470 snd_soc_dapm_free(socdev);
1471
1472 kfree(codec->reg_cache);
1473
1474 return 0;
1475}
1476
1477struct snd_soc_codec_device soc_codec_dev_aic3x = {
1478 .probe = aic3x_probe,
1479 .remove = aic3x_remove,
1480 .suspend = aic3x_suspend,
1481 .resume = aic3x_resume,
1482};
1483EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1484
1485static int __init aic3x_modinit(void)
1486{
1487 aic3x_i2c_init();
1488
1489 return 0;
1490}
1491module_init(aic3x_modinit); 1570module_init(aic3x_modinit);
1492 1571
1493static void __exit aic3x_exit(void) 1572static void __exit aic3x_exit(void)
1494{ 1573{
1495 aic3x_i2c_exit(); 1574#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1575 i2c_del_driver(&aic3x_i2c_driver);
1576#endif
1496} 1577}
1497module_exit(aic3x_exit); 1578module_exit(aic3x_exit);
1498 1579
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 9af1c886213c..06a19784b162 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -81,50 +81,63 @@
81/* DAC Digital control registers */ 81/* DAC Digital control registers */
82#define LDAC_VOL 43 82#define LDAC_VOL 43
83#define RDAC_VOL 44 83#define RDAC_VOL 44
84/* High Power Output control registers */ 84/* Left High Power Output control registers */
85#define LINE2L_2_HPLOUT_VOL 45 85#define LINE2L_2_HPLOUT_VOL 45
86#define LINE2R_2_HPROUT_VOL 62
87#define PGAL_2_HPLOUT_VOL 46 86#define PGAL_2_HPLOUT_VOL 46
88#define PGAL_2_HPROUT_VOL 60
89#define PGAR_2_HPLOUT_VOL 49
90#define PGAR_2_HPROUT_VOL 63
91#define DACL1_2_HPLOUT_VOL 47 87#define DACL1_2_HPLOUT_VOL 47
92#define DACR1_2_HPROUT_VOL 64 88#define LINE2R_2_HPLOUT_VOL 48
89#define PGAR_2_HPLOUT_VOL 49
90#define DACR1_2_HPLOUT_VOL 50
93#define HPLOUT_CTRL 51 91#define HPLOUT_CTRL 51
94#define HPROUT_CTRL 65 92/* Left High Power COM control registers */
95/* High Power COM control registers */
96#define LINE2L_2_HPLCOM_VOL 52 93#define LINE2L_2_HPLCOM_VOL 52
97#define LINE2R_2_HPRCOM_VOL 69
98#define PGAL_2_HPLCOM_VOL 53 94#define PGAL_2_HPLCOM_VOL 53
95#define DACL1_2_HPLCOM_VOL 54
96#define LINE2R_2_HPLCOM_VOL 55
99#define PGAR_2_HPLCOM_VOL 56 97#define PGAR_2_HPLCOM_VOL 56
98#define DACR1_2_HPLCOM_VOL 57
99#define HPLCOM_CTRL 58
100/* Right High Power Output control registers */
101#define LINE2L_2_HPROUT_VOL 59
102#define PGAL_2_HPROUT_VOL 60
103#define DACL1_2_HPROUT_VOL 61
104#define LINE2R_2_HPROUT_VOL 62
105#define PGAR_2_HPROUT_VOL 63
106#define DACR1_2_HPROUT_VOL 64
107#define HPROUT_CTRL 65
108/* Right High Power COM control registers */
109#define LINE2L_2_HPRCOM_VOL 66
100#define PGAL_2_HPRCOM_VOL 67 110#define PGAL_2_HPRCOM_VOL 67
111#define DACL1_2_HPRCOM_VOL 68
112#define LINE2R_2_HPRCOM_VOL 69
101#define PGAR_2_HPRCOM_VOL 70 113#define PGAR_2_HPRCOM_VOL 70
102#define DACL1_2_HPLCOM_VOL 54
103#define DACR1_2_HPRCOM_VOL 71 114#define DACR1_2_HPRCOM_VOL 71
104#define HPLCOM_CTRL 58
105#define HPRCOM_CTRL 72 115#define HPRCOM_CTRL 72
106/* Mono Line Output Plus/Minus control registers */ 116/* Mono Line Output Plus/Minus control registers */
107#define LINE2L_2_MONOLOPM_VOL 73 117#define LINE2L_2_MONOLOPM_VOL 73
108#define LINE2R_2_MONOLOPM_VOL 76
109#define PGAL_2_MONOLOPM_VOL 74 118#define PGAL_2_MONOLOPM_VOL 74
110#define PGAR_2_MONOLOPM_VOL 77
111#define DACL1_2_MONOLOPM_VOL 75 119#define DACL1_2_MONOLOPM_VOL 75
120#define LINE2R_2_MONOLOPM_VOL 76
121#define PGAR_2_MONOLOPM_VOL 77
112#define DACR1_2_MONOLOPM_VOL 78 122#define DACR1_2_MONOLOPM_VOL 78
113#define MONOLOPM_CTRL 79 123#define MONOLOPM_CTRL 79
114/* Line Output Plus/Minus control registers */ 124/* Class-D speaker driver on tlv320aic3007 */
125#define CLASSD_CTRL 73
126/* Left Line Output Plus/Minus control registers */
115#define LINE2L_2_LLOPM_VOL 80 127#define LINE2L_2_LLOPM_VOL 80
116#define LINE2L_2_RLOPM_VOL 87
117#define LINE2R_2_LLOPM_VOL 83
118#define LINE2R_2_RLOPM_VOL 90
119#define PGAL_2_LLOPM_VOL 81 128#define PGAL_2_LLOPM_VOL 81
120#define PGAL_2_RLOPM_VOL 88
121#define PGAR_2_LLOPM_VOL 84
122#define PGAR_2_RLOPM_VOL 91
123#define DACL1_2_LLOPM_VOL 82 129#define DACL1_2_LLOPM_VOL 82
124#define DACL1_2_RLOPM_VOL 89 130#define LINE2R_2_LLOPM_VOL 83
125#define DACR1_2_RLOPM_VOL 92 131#define PGAR_2_LLOPM_VOL 84
126#define DACR1_2_LLOPM_VOL 85 132#define DACR1_2_LLOPM_VOL 85
127#define LLOPM_CTRL 86 133#define LLOPM_CTRL 86
134/* Right Line Output Plus/Minus control registers */
135#define LINE2L_2_RLOPM_VOL 87
136#define PGAL_2_RLOPM_VOL 88
137#define DACL1_2_RLOPM_VOL 89
138#define LINE2R_2_RLOPM_VOL 90
139#define PGAR_2_RLOPM_VOL 91
140#define DACR1_2_RLOPM_VOL 92
128#define RLOPM_CTRL 93 141#define RLOPM_CTRL 93
129/* GPIO/IRQ registers */ 142/* GPIO/IRQ registers */
130#define AIC3X_STICKY_IRQ_FLAGS_REG 96 143#define AIC3X_STICKY_IRQ_FLAGS_REG 96
@@ -199,42 +212,6 @@
199/* Default input volume */ 212/* Default input volume */
200#define DEFAULT_GAIN 0x20 213#define DEFAULT_GAIN 0x20
201 214
202/* GPIO API */
203enum {
204 AIC3X_GPIO1_FUNC_DISABLED = 0,
205 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
206 AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
207 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
208 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
209 AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
210 AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
211 AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
212 AIC3X_GPIO1_FUNC_INPUT = 8,
213 AIC3X_GPIO1_FUNC_OUTPUT = 9,
214 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
215 AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
216 AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
217 AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
218 AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
219 AIC3X_GPIO1_FUNC_ALL_IRQ = 16
220};
221
222enum {
223 AIC3X_GPIO2_FUNC_DISABLED = 0,
224 AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
225 AIC3X_GPIO2_FUNC_INPUT = 3,
226 AIC3X_GPIO2_FUNC_OUTPUT = 4,
227 AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
228 AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
229 AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
230 AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
231 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
232 AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
233 AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
234 AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
235 AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
236};
237
238void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); 215void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
239int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); 216int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
240 217
@@ -281,11 +258,4 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
281int aic3x_headset_detected(struct snd_soc_codec *codec); 258int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec); 259int aic3x_button_pressed(struct snd_soc_codec *codec);
283 260
284struct aic3x_setup_data {
285 unsigned int gpio_func[2];
286};
287
288extern struct snd_soc_dai aic3x_dai;
289extern struct snd_soc_codec_device soc_codec_dev_aic3x;
290
291#endif /* _AIC3X_H */ 261#endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 8651b01ed223..faa5e9fb1471 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver 2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
@@ -36,21 +36,21 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h> 39#include <sound/initval.h>
41#include <sound/tlv.h> 40#include <sound/tlv.h>
42 41
43#include <sound/tlv320dac33-plat.h> 42#include <sound/tlv320dac33-plat.h>
44#include "tlv320dac33.h" 43#include "tlv320dac33.h"
45 44
46#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words, 45/*
47 * 6144 stereo */ 46 * The internal FIFO is 24576 bytes long
48#define DAC33_BUFFER_SIZE_SAMPLES 6144 47 * It can be configured to hold 16bit or 24bit samples
49 48 * In 16bit configuration the FIFO can hold 6144 stereo samples
50#define NSAMPLE_MAX 5700 49 * In 24bit configuration the FIFO can hold 4096 stereo samples
51 50 */
52#define MODE7_LTHR 10 51#define DAC33_FIFO_SIZE_16BIT 6144
53#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) 52#define DAC33_FIFO_SIZE_24BIT 4096
53#define DAC33_MODE7_MARGIN 10 /* Safety margin for FIFO in Mode7 */
54 54
55#define BURST_BASEFREQ_HZ 49152000 55#define BURST_BASEFREQ_HZ 49152000
56 56
@@ -58,7 +58,7 @@
58 (1000000000 / ((rate * 1000) / samples)) 58 (1000000000 / ((rate * 1000) / samples))
59 59
60#define US_TO_SAMPLES(rate, us) \ 60#define US_TO_SAMPLES(rate, us) \
61 (rate / (1000000 / us)) 61 (rate / (1000000 / (us < 1000000 ? us : 1000000)))
62 62
63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ 63#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) 64 ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate)))
@@ -66,8 +66,6 @@
66static void dac33_calculate_times(struct snd_pcm_substream *substream); 66static void dac33_calculate_times(struct snd_pcm_substream *substream);
67static int dac33_prepare_chip(struct snd_pcm_substream *substream); 67static int dac33_prepare_chip(struct snd_pcm_substream *substream);
68 68
69static struct snd_soc_codec *tlv320dac33_codec;
70
71enum dac33_state { 69enum dac33_state {
72 DAC33_IDLE = 0, 70 DAC33_IDLE = 0,
73 DAC33_PREFILL, 71 DAC33_PREFILL,
@@ -93,7 +91,7 @@ struct tlv320dac33_priv {
93 struct mutex mutex; 91 struct mutex mutex;
94 struct workqueue_struct *dac33_wq; 92 struct workqueue_struct *dac33_wq;
95 struct work_struct work; 93 struct work_struct work;
96 struct snd_soc_codec codec; 94 struct snd_soc_codec *codec;
97 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; 95 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
98 struct snd_pcm_substream *substream; 96 struct snd_pcm_substream *substream;
99 int power_gpio; 97 int power_gpio;
@@ -102,16 +100,11 @@ struct tlv320dac33_priv {
102 unsigned int refclk; 100 unsigned int refclk;
103 101
104 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */ 102 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
105 unsigned int nsample_min; /* nsample should not be lower than
106 * this */
107 unsigned int nsample_max; /* nsample should not be higher than
108 * this */
109 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 103 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
104 unsigned int fifo_size; /* Size of the FIFO in samples */
110 unsigned int nsample; /* burst read amount from host */ 105 unsigned int nsample; /* burst read amount from host */
111 int mode1_latency; /* latency caused by the i2c writes in 106 int mode1_latency; /* latency caused by the i2c writes in
112 * us */ 107 * us */
113 int auto_fifo_config; /* Configure the FIFO based on the
114 * period size */
115 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 108 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
116 unsigned int burst_rate; /* Interface speed in Burst modes */ 109 unsigned int burst_rate; /* Interface speed in Burst modes */
117 110
@@ -128,6 +121,8 @@ struct tlv320dac33_priv {
128 unsigned int uthr; 121 unsigned int uthr;
129 122
130 enum dac33_state state; 123 enum dac33_state state;
124 enum snd_soc_control_type control_type;
125 void *control_data;
131}; 126};
132 127
133static const u8 dac33_reg[DAC33_CACHEREGNUM] = { 128static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
@@ -200,7 +195,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
200 u8 *value) 195 u8 *value)
201{ 196{
202 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 197 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
203 int val; 198 int val, ret = 0;
204 199
205 *value = reg & 0xff; 200 *value = reg & 0xff;
206 201
@@ -210,6 +205,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
210 if (val < 0) { 205 if (val < 0) {
211 dev_err(codec->dev, "Read failed (%d)\n", val); 206 dev_err(codec->dev, "Read failed (%d)\n", val);
212 value[0] = dac33_read_reg_cache(codec, reg); 207 value[0] = dac33_read_reg_cache(codec, reg);
208 ret = val;
213 } else { 209 } else {
214 value[0] = val; 210 value[0] = val;
215 dac33_write_reg_cache(codec, reg, val); 211 dac33_write_reg_cache(codec, reg, val);
@@ -218,7 +214,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
218 value[0] = dac33_read_reg_cache(codec, reg); 214 value[0] = dac33_read_reg_cache(codec, reg);
219 } 215 }
220 216
221 return 0; 217 return ret;
222} 218}
223 219
224static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, 220static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
@@ -302,7 +298,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
302 if (unlikely(!dac33->chip_power)) 298 if (unlikely(!dac33->chip_power))
303 return; 299 return;
304 300
305 /* 44-46: DAC Control Registers */
306 /* A : DAC sample rate Fsref/1.5 */ 301 /* A : DAC sample rate Fsref/1.5 */
307 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0)); 302 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
308 /* B : DAC src=normal, not muted */ 303 /* B : DAC src=normal, not muted */
@@ -315,8 +310,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
315 clock source = internal osc (?) */ 310 clock source = internal osc (?) */
316 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN); 311 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
317 312
318 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
319
320 /* Restore only selected registers (gains mostly) */ 313 /* Restore only selected registers (gains mostly) */
321 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL, 314 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
322 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL)); 315 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
@@ -327,15 +320,28 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
327 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL)); 320 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
328 dac33_write(codec, DAC33_LINER_TO_RLO_VOL, 321 dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
329 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); 322 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
323
324 dac33_write(codec, DAC33_OUT_AMP_CTRL,
325 dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL));
326
327 dac33_write(codec, DAC33_LDAC_PWR_CTRL,
328 dac33_read_reg_cache(codec, DAC33_LDAC_PWR_CTRL));
329 dac33_write(codec, DAC33_RDAC_PWR_CTRL,
330 dac33_read_reg_cache(codec, DAC33_RDAC_PWR_CTRL));
330} 331}
331 332
332static inline void dac33_read_id(struct snd_soc_codec *codec) 333static inline int dac33_read_id(struct snd_soc_codec *codec)
333{ 334{
335 int i, ret = 0;
334 u8 reg; 336 u8 reg;
335 337
336 dac33_read(codec, DAC33_DEVICE_ID_MSB, &reg); 338 for (i = 0; i < 3; i++) {
337 dac33_read(codec, DAC33_DEVICE_ID_LSB, &reg); 339 ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, &reg);
338 dac33_read(codec, DAC33_DEVICE_REV_ID, &reg); 340 if (ret < 0)
341 break;
342 }
343
344 return ret;
339} 345}
340 346
341static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) 347static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
@@ -351,6 +357,21 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
351 dac33_write(codec, DAC33_PWR_CTRL, reg); 357 dac33_write(codec, DAC33_PWR_CTRL, reg);
352} 358}
353 359
360static inline void dac33_disable_digital(struct snd_soc_codec *codec)
361{
362 u8 reg;
363
364 /* Stop the DAI clock */
365 reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
366 reg &= ~DAC33_BCLKON;
367 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
368
369 /* Power down the Oscillator, and DACs */
370 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
371 reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
372 dac33_write(codec, DAC33_PWR_CTRL, reg);
373}
374
354static int dac33_hard_power(struct snd_soc_codec *codec, int power) 375static int dac33_hard_power(struct snd_soc_codec *codec, int power)
355{ 376{
356 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 377 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
@@ -399,7 +420,7 @@ exit:
399 return ret; 420 return ret;
400} 421}
401 422
402static int playback_event(struct snd_soc_dapm_widget *w, 423static int dac33_playback_event(struct snd_soc_dapm_widget *w,
403 struct snd_kcontrol *kcontrol, int event) 424 struct snd_kcontrol *kcontrol, int event)
404{ 425{
405 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec); 426 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
@@ -411,77 +432,13 @@ static int playback_event(struct snd_soc_dapm_widget *w,
411 dac33_prepare_chip(dac33->substream); 432 dac33_prepare_chip(dac33->substream);
412 } 433 }
413 break; 434 break;
435 case SND_SOC_DAPM_POST_PMD:
436 dac33_disable_digital(w->codec);
437 break;
414 } 438 }
415 return 0; 439 return 0;
416} 440}
417 441
418static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
419 struct snd_ctl_elem_value *ucontrol)
420{
421 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
422 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
423
424 ucontrol->value.integer.value[0] = dac33->nsample;
425
426 return 0;
427}
428
429static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_value *ucontrol)
431{
432 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
433 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
434 int ret = 0;
435
436 if (dac33->nsample == ucontrol->value.integer.value[0])
437 return 0;
438
439 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
440 ucontrol->value.integer.value[0] > dac33->nsample_max) {
441 ret = -EINVAL;
442 } else {
443 dac33->nsample = ucontrol->value.integer.value[0];
444 /* Re calculate the burst time */
445 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
446 dac33->nsample);
447 }
448
449 return ret;
450}
451
452static int dac33_get_uthr(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
454{
455 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
456 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
457
458 ucontrol->value.integer.value[0] = dac33->uthr;
459
460 return 0;
461}
462
463static int dac33_set_uthr(struct snd_kcontrol *kcontrol,
464 struct snd_ctl_elem_value *ucontrol)
465{
466 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
467 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
468 int ret = 0;
469
470 if (dac33->substream)
471 return -EBUSY;
472
473 if (dac33->uthr == ucontrol->value.integer.value[0])
474 return 0;
475
476 if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) ||
477 ucontrol->value.integer.value[0] > MODE7_UTHR)
478 ret = -EINVAL;
479 else
480 dac33->uthr = ucontrol->value.integer.value[0];
481
482 return ret;
483}
484
485static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, 442static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol) 443 struct snd_ctl_elem_value *ucontrol)
487{ 444{
@@ -524,6 +481,22 @@ static const struct soc_enum dac33_fifo_mode_enum =
524 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts), 481 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
525 dac33_fifo_mode_texts); 482 dac33_fifo_mode_texts);
526 483
484/* L/R Line Output Gain */
485static const char *lr_lineout_gain_texts[] = {
486 "Line -12dB DAC 0dB", "Line -6dB DAC 6dB",
487 "Line 0dB DAC 12dB", "Line 6dB DAC 18dB",
488};
489
490static const struct soc_enum l_lineout_gain_enum =
491 SOC_ENUM_SINGLE(DAC33_LDAC_PWR_CTRL, 0,
492 ARRAY_SIZE(lr_lineout_gain_texts),
493 lr_lineout_gain_texts);
494
495static const struct soc_enum r_lineout_gain_enum =
496 SOC_ENUM_SINGLE(DAC33_RDAC_PWR_CTRL, 0,
497 ARRAY_SIZE(lr_lineout_gain_texts),
498 lr_lineout_gain_texts);
499
527/* 500/*
528 * DACL/R digital volume control: 501 * DACL/R digital volume control:
529 * from 0 dB to -63.5 in 0.5 dB steps 502 * from 0 dB to -63.5 in 0.5 dB steps
@@ -541,6 +514,8 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
541 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1), 514 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
542 SOC_DOUBLE_R("Line to Line Out Volume", 515 SOC_DOUBLE_R("Line to Line Out Volume",
543 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1), 516 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
517 SOC_ENUM("Left Line Output Gain", l_lineout_gain_enum),
518 SOC_ENUM("Right Line Output Gain", r_lineout_gain_enum),
544}; 519};
545 520
546static const struct snd_kcontrol_new dac33_mode_snd_controls[] = { 521static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
@@ -548,13 +523,6 @@ static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
548 dac33_get_fifo_mode, dac33_set_fifo_mode), 523 dac33_get_fifo_mode, dac33_set_fifo_mode),
549}; 524};
550 525
551static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = {
552 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
553 dac33_get_nsample, dac33_set_nsample),
554 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
555 dac33_get_uthr, dac33_set_uthr),
556};
557
558/* Analog bypass */ 526/* Analog bypass */
559static const struct snd_kcontrol_new dac33_dapm_abypassl_control = 527static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
560 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); 528 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
@@ -562,6 +530,25 @@ static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
562static const struct snd_kcontrol_new dac33_dapm_abypassr_control = 530static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
563 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1); 531 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
564 532
533/* LOP L/R invert selection */
534static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"};
535
536static const struct soc_enum dac33_left_lom_enum =
537 SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 3,
538 ARRAY_SIZE(dac33_lr_lom_texts),
539 dac33_lr_lom_texts);
540
541static const struct snd_kcontrol_new dac33_dapm_left_lom_control =
542SOC_DAPM_ENUM("Route", dac33_left_lom_enum);
543
544static const struct soc_enum dac33_right_lom_enum =
545 SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 2,
546 ARRAY_SIZE(dac33_lr_lom_texts),
547 dac33_lr_lom_texts);
548
549static const struct snd_kcontrol_new dac33_dapm_right_lom_control =
550SOC_DAPM_ENUM("Route", dac33_right_lom_enum);
551
565static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { 552static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
566 SND_SOC_DAPM_OUTPUT("LEFT_LO"), 553 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
567 SND_SOC_DAPM_OUTPUT("RIGHT_LO"), 554 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
@@ -569,8 +556,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
569 SND_SOC_DAPM_INPUT("LINEL"), 556 SND_SOC_DAPM_INPUT("LINEL"),
570 SND_SOC_DAPM_INPUT("LINER"), 557 SND_SOC_DAPM_INPUT("LINER"),
571 558
572 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0), 559 SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
573 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0), 560 SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
574 561
575 /* Analog bypass */ 562 /* Analog bypass */
576 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0, 563 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
@@ -578,12 +565,33 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
578 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0, 565 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
579 &dac33_dapm_abypassr_control), 566 &dac33_dapm_abypassr_control),
580 567
581 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power", 568 SND_SOC_DAPM_MUX("Left LOM Inverted From", SND_SOC_NOPM, 0, 0,
569 &dac33_dapm_left_lom_control),
570 SND_SOC_DAPM_MUX("Right LOM Inverted From", SND_SOC_NOPM, 0, 0,
571 &dac33_dapm_right_lom_control),
572 /*
573 * For DAPM path, when only the anlog bypass path is enabled, and the
574 * LOP inverted from the corresponding DAC side.
575 * This is needed, so we can attach the DAC power supply in this case.
576 */
577 SND_SOC_DAPM_PGA("Left Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
578 SND_SOC_DAPM_PGA("Right Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
579
580 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
582 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 581 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
583 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 582 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
584 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 583 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
585 584
586 SND_SOC_DAPM_PRE("Prepare Playback", playback_event), 585 SND_SOC_DAPM_SUPPLY("Left DAC Power",
586 DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
587 SND_SOC_DAPM_SUPPLY("Right DAC Power",
588 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
589
590 SND_SOC_DAPM_SUPPLY("Codec Power",
591 DAC33_PWR_CTRL, 4, 0, NULL, 0),
592
593 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
594 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
587}; 595};
588 596
589static const struct snd_soc_dapm_route audio_map[] = { 597static const struct snd_soc_dapm_route audio_map[] = {
@@ -591,24 +599,42 @@ static const struct snd_soc_dapm_route audio_map[] = {
591 {"Analog Left Bypass", "Switch", "LINEL"}, 599 {"Analog Left Bypass", "Switch", "LINEL"},
592 {"Analog Right Bypass", "Switch", "LINER"}, 600 {"Analog Right Bypass", "Switch", "LINER"},
593 601
594 {"Output Left Amp Power", NULL, "DACL"}, 602 {"Output Left Amplifier", NULL, "DACL"},
595 {"Output Right Amp Power", NULL, "DACR"}, 603 {"Output Right Amplifier", NULL, "DACR"},
604
605 {"Left Bypass PGA", NULL, "Analog Left Bypass"},
606 {"Right Bypass PGA", NULL, "Analog Right Bypass"},
607
608 {"Left LOM Inverted From", "DAC", "Left Bypass PGA"},
609 {"Right LOM Inverted From", "DAC", "Right Bypass PGA"},
610 {"Left LOM Inverted From", "LOP", "Analog Left Bypass"},
611 {"Right LOM Inverted From", "LOP", "Analog Right Bypass"},
596 612
597 {"Output Left Amp Power", NULL, "Analog Left Bypass"}, 613 {"Output Left Amplifier", NULL, "Left LOM Inverted From"},
598 {"Output Right Amp Power", NULL, "Analog Right Bypass"}, 614 {"Output Right Amplifier", NULL, "Right LOM Inverted From"},
615
616 {"DACL", NULL, "Left DAC Power"},
617 {"DACR", NULL, "Right DAC Power"},
618
619 {"Left Bypass PGA", NULL, "Left DAC Power"},
620 {"Right Bypass PGA", NULL, "Right DAC Power"},
599 621
600 /* output */ 622 /* output */
601 {"LEFT_LO", NULL, "Output Left Amp Power"}, 623 {"LEFT_LO", NULL, "Output Left Amplifier"},
602 {"RIGHT_LO", NULL, "Output Right Amp Power"}, 624 {"RIGHT_LO", NULL, "Output Right Amplifier"},
625
626 {"LEFT_LO", NULL, "Codec Power"},
627 {"RIGHT_LO", NULL, "Codec Power"},
603}; 628};
604 629
605static int dac33_add_widgets(struct snd_soc_codec *codec) 630static int dac33_add_widgets(struct snd_soc_codec *codec)
606{ 631{
607 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets, 632 struct snd_soc_dapm_context *dapm = &codec->dapm;
608 ARRAY_SIZE(dac33_dapm_widgets));
609 633
634 snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets,
635 ARRAY_SIZE(dac33_dapm_widgets));
610 /* set up audio path interconnects */ 636 /* set up audio path interconnects */
611 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 637 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
612 638
613 return 0; 639 return 0;
614} 640}
@@ -620,12 +646,11 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
620 646
621 switch (level) { 647 switch (level) {
622 case SND_SOC_BIAS_ON: 648 case SND_SOC_BIAS_ON:
623 dac33_soft_power(codec, 1);
624 break; 649 break;
625 case SND_SOC_BIAS_PREPARE: 650 case SND_SOC_BIAS_PREPARE:
626 break; 651 break;
627 case SND_SOC_BIAS_STANDBY: 652 case SND_SOC_BIAS_STANDBY:
628 if (codec->bias_level == SND_SOC_BIAS_OFF) { 653 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
629 /* Coming from OFF, switch on the codec */ 654 /* Coming from OFF, switch on the codec */
630 ret = dac33_hard_power(codec, 1); 655 ret = dac33_hard_power(codec, 1);
631 if (ret != 0) 656 if (ret != 0)
@@ -636,23 +661,23 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
636 break; 661 break;
637 case SND_SOC_BIAS_OFF: 662 case SND_SOC_BIAS_OFF:
638 /* Do not power off, when the codec is already off */ 663 /* Do not power off, when the codec is already off */
639 if (codec->bias_level == SND_SOC_BIAS_OFF) 664 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
640 return 0; 665 return 0;
641 ret = dac33_hard_power(codec, 0); 666 ret = dac33_hard_power(codec, 0);
642 if (ret != 0) 667 if (ret != 0)
643 return ret; 668 return ret;
644 break; 669 break;
645 } 670 }
646 codec->bias_level = level; 671 codec->dapm.bias_level = level;
647 672
648 return 0; 673 return 0;
649} 674}
650 675
651static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) 676static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
652{ 677{
653 struct snd_soc_codec *codec; 678 struct snd_soc_codec *codec = dac33->codec;
654 679 unsigned int delay;
655 codec = &dac33->codec; 680 unsigned long flags;
656 681
657 switch (dac33->fifo_mode) { 682 switch (dac33->fifo_mode) {
658 case DAC33_FIFO_MODE1: 683 case DAC33_FIFO_MODE1:
@@ -660,28 +685,29 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
660 DAC33_THRREG(dac33->nsample)); 685 DAC33_THRREG(dac33->nsample));
661 686
662 /* Take the timestamps */ 687 /* Take the timestamps */
663 spin_lock_irq(&dac33->lock); 688 spin_lock_irqsave(&dac33->lock, flags);
664 dac33->t_stamp2 = ktime_to_us(ktime_get()); 689 dac33->t_stamp2 = ktime_to_us(ktime_get());
665 dac33->t_stamp1 = dac33->t_stamp2; 690 dac33->t_stamp1 = dac33->t_stamp2;
666 spin_unlock_irq(&dac33->lock); 691 spin_unlock_irqrestore(&dac33->lock, flags);
667 692
668 dac33_write16(codec, DAC33_PREFILL_MSB, 693 dac33_write16(codec, DAC33_PREFILL_MSB,
669 DAC33_THRREG(dac33->alarm_threshold)); 694 DAC33_THRREG(dac33->alarm_threshold));
670 /* Enable Alarm Threshold IRQ with a delay */ 695 /* Enable Alarm Threshold IRQ with a delay */
671 udelay(SAMPLES_TO_US(dac33->burst_rate, 696 delay = SAMPLES_TO_US(dac33->burst_rate,
672 dac33->alarm_threshold)); 697 dac33->alarm_threshold) + 1000;
698 usleep_range(delay, delay + 500);
673 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT); 699 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
674 break; 700 break;
675 case DAC33_FIFO_MODE7: 701 case DAC33_FIFO_MODE7:
676 /* Take the timestamp */ 702 /* Take the timestamp */
677 spin_lock_irq(&dac33->lock); 703 spin_lock_irqsave(&dac33->lock, flags);
678 dac33->t_stamp1 = ktime_to_us(ktime_get()); 704 dac33->t_stamp1 = ktime_to_us(ktime_get());
679 /* Move back the timestamp with drain time */ 705 /* Move back the timestamp with drain time */
680 dac33->t_stamp1 -= dac33->mode7_us_to_lthr; 706 dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
681 spin_unlock_irq(&dac33->lock); 707 spin_unlock_irqrestore(&dac33->lock, flags);
682 708
683 dac33_write16(codec, DAC33_PREFILL_MSB, 709 dac33_write16(codec, DAC33_PREFILL_MSB,
684 DAC33_THRREG(MODE7_LTHR)); 710 DAC33_THRREG(DAC33_MODE7_MARGIN));
685 711
686 /* Enable Upper Threshold IRQ */ 712 /* Enable Upper Threshold IRQ */
687 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT); 713 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
@@ -695,16 +721,15 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
695 721
696static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33) 722static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
697{ 723{
698 struct snd_soc_codec *codec; 724 struct snd_soc_codec *codec = dac33->codec;
699 725 unsigned long flags;
700 codec = &dac33->codec;
701 726
702 switch (dac33->fifo_mode) { 727 switch (dac33->fifo_mode) {
703 case DAC33_FIFO_MODE1: 728 case DAC33_FIFO_MODE1:
704 /* Take the timestamp */ 729 /* Take the timestamp */
705 spin_lock_irq(&dac33->lock); 730 spin_lock_irqsave(&dac33->lock, flags);
706 dac33->t_stamp2 = ktime_to_us(ktime_get()); 731 dac33->t_stamp2 = ktime_to_us(ktime_get());
707 spin_unlock_irq(&dac33->lock); 732 spin_unlock_irqrestore(&dac33->lock, flags);
708 733
709 dac33_write16(codec, DAC33_NSAMPLE_MSB, 734 dac33_write16(codec, DAC33_NSAMPLE_MSB,
710 DAC33_THRREG(dac33->nsample)); 735 DAC33_THRREG(dac33->nsample));
@@ -726,7 +751,7 @@ static void dac33_work(struct work_struct *work)
726 u8 reg; 751 u8 reg;
727 752
728 dac33 = container_of(work, struct tlv320dac33_priv, work); 753 dac33 = container_of(work, struct tlv320dac33_priv, work);
729 codec = &dac33->codec; 754 codec = dac33->codec;
730 755
731 mutex_lock(&dac33->mutex); 756 mutex_lock(&dac33->mutex);
732 switch (dac33->state) { 757 switch (dac33->state) {
@@ -757,10 +782,11 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
757{ 782{
758 struct snd_soc_codec *codec = dev; 783 struct snd_soc_codec *codec = dev;
759 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 784 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
785 unsigned long flags;
760 786
761 spin_lock(&dac33->lock); 787 spin_lock_irqsave(&dac33->lock, flags);
762 dac33->t_stamp1 = ktime_to_us(ktime_get()); 788 dac33->t_stamp1 = ktime_to_us(ktime_get());
763 spin_unlock(&dac33->lock); 789 spin_unlock_irqrestore(&dac33->lock, flags);
764 790
765 /* Do not schedule the workqueue in Mode7 */ 791 /* Do not schedule the workqueue in Mode7 */
766 if (dac33->fifo_mode != DAC33_FIFO_MODE7) 792 if (dac33->fifo_mode != DAC33_FIFO_MODE7)
@@ -771,11 +797,11 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
771 797
772static void dac33_oscwait(struct snd_soc_codec *codec) 798static void dac33_oscwait(struct snd_soc_codec *codec)
773{ 799{
774 int timeout = 20; 800 int timeout = 60;
775 u8 reg; 801 u8 reg;
776 802
777 do { 803 do {
778 msleep(1); 804 usleep_range(1000, 2000);
779 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg); 805 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
780 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--); 806 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
781 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) 807 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
@@ -787,13 +813,14 @@ static int dac33_startup(struct snd_pcm_substream *substream,
787 struct snd_soc_dai *dai) 813 struct snd_soc_dai *dai)
788{ 814{
789 struct snd_soc_pcm_runtime *rtd = substream->private_data; 815 struct snd_soc_pcm_runtime *rtd = substream->private_data;
790 struct snd_soc_device *socdev = rtd->socdev; 816 struct snd_soc_codec *codec = rtd->codec;
791 struct snd_soc_codec *codec = socdev->card->codec;
792 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 817 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
793 818
794 /* Stream started, save the substream pointer */ 819 /* Stream started, save the substream pointer */
795 dac33->substream = substream; 820 dac33->substream = substream;
796 821
822 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
823
797 return 0; 824 return 0;
798} 825}
799 826
@@ -801,24 +828,21 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
801 struct snd_soc_dai *dai) 828 struct snd_soc_dai *dai)
802{ 829{
803 struct snd_soc_pcm_runtime *rtd = substream->private_data; 830 struct snd_soc_pcm_runtime *rtd = substream->private_data;
804 struct snd_soc_device *socdev = rtd->socdev; 831 struct snd_soc_codec *codec = rtd->codec;
805 struct snd_soc_codec *codec = socdev->card->codec;
806 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 832 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
807 833
808 dac33->substream = NULL; 834 dac33->substream = NULL;
809
810 /* Reset the nSample restrictions */
811 dac33->nsample_min = 0;
812 dac33->nsample_max = NSAMPLE_MAX;
813} 835}
814 836
837#define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \
838 (BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample)
815static int dac33_hw_params(struct snd_pcm_substream *substream, 839static int dac33_hw_params(struct snd_pcm_substream *substream,
816 struct snd_pcm_hw_params *params, 840 struct snd_pcm_hw_params *params,
817 struct snd_soc_dai *dai) 841 struct snd_soc_dai *dai)
818{ 842{
819 struct snd_soc_pcm_runtime *rtd = substream->private_data; 843 struct snd_soc_pcm_runtime *rtd = substream->private_data;
820 struct snd_soc_device *socdev = rtd->socdev; 844 struct snd_soc_codec *codec = rtd->codec;
821 struct snd_soc_codec *codec = socdev->card->codec; 845 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
822 846
823 /* Check parameters for validity */ 847 /* Check parameters for validity */
824 switch (params_rate(params)) { 848 switch (params_rate(params)) {
@@ -833,6 +857,12 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
833 857
834 switch (params_format(params)) { 858 switch (params_format(params)) {
835 case SNDRV_PCM_FORMAT_S16_LE: 859 case SNDRV_PCM_FORMAT_S16_LE:
860 dac33->fifo_size = DAC33_FIFO_SIZE_16BIT;
861 dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32);
862 break;
863 case SNDRV_PCM_FORMAT_S32_LE:
864 dac33->fifo_size = DAC33_FIFO_SIZE_24BIT;
865 dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64);
836 break; 866 break;
837 default: 867 default:
838 dev_err(codec->dev, "unsupported format %d\n", 868 dev_err(codec->dev, "unsupported format %d\n",
@@ -856,8 +886,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
856static int dac33_prepare_chip(struct snd_pcm_substream *substream) 886static int dac33_prepare_chip(struct snd_pcm_substream *substream)
857{ 887{
858 struct snd_soc_pcm_runtime *rtd = substream->private_data; 888 struct snd_soc_pcm_runtime *rtd = substream->private_data;
859 struct snd_soc_device *socdev = rtd->socdev; 889 struct snd_soc_codec *codec = rtd->codec;
860 struct snd_soc_codec *codec = socdev->card->codec;
861 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 890 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
862 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 891 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
863 u8 aictrl_a, aictrl_b, fifoctrl_a; 892 u8 aictrl_a, aictrl_b, fifoctrl_a;
@@ -888,6 +917,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
888 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16); 917 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
889 fifoctrl_a |= DAC33_WIDTH; 918 fifoctrl_a |= DAC33_WIDTH;
890 break; 919 break;
920 case SNDRV_PCM_FORMAT_S32_LE:
921 aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24);
922 break;
891 default: 923 default:
892 dev_err(codec->dev, "unsupported format %d\n", 924 dev_err(codec->dev, "unsupported format %d\n",
893 substream->runtime->format); 925 substream->runtime->format);
@@ -914,8 +946,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
914 /* Write registers 0x08 and 0x09 (MSB, LSB) */ 946 /* Write registers 0x08 and 0x09 (MSB, LSB) */
915 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset); 947 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
916 948
917 /* calib time: 128 is a nice number ;) */ 949 /* OSC calibration time */
918 dac33_write(codec, DAC33_CALIB_TIME, 128); 950 dac33_write(codec, DAC33_CALIB_TIME, 96);
919 951
920 /* adjustment treshold & step */ 952 /* adjustment treshold & step */
921 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) | 953 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
@@ -998,7 +1030,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
998 /* 1030 /*
999 * For FIFO bypass mode: 1031 * For FIFO bypass mode:
1000 * Enable the FIFO bypass (Disable the FIFO use) 1032 * Enable the FIFO bypass (Disable the FIFO use)
1001 * Set the BCLK as continous 1033 * Set the BCLK as continuous
1002 */ 1034 */
1003 fifoctrl_a |= DAC33_FBYPAS; 1035 fifoctrl_a |= DAC33_FBYPAS;
1004 aictrl_b |= DAC33_BCLKON; 1036 aictrl_b |= DAC33_BCLKON;
@@ -1022,7 +1054,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1022 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 1054 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
1023 dac33->burst_bclkdiv); 1055 dac33->burst_bclkdiv);
1024 else 1056 else
1025 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); 1057 if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE)
1058 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
1059 else
1060 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16);
1026 1061
1027 switch (dac33->fifo_mode) { 1062 switch (dac33->fifo_mode) {
1028 case DAC33_FIFO_MODE1: 1063 case DAC33_FIFO_MODE1:
@@ -1035,7 +1070,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1035 * at the bottom, and also at the top of the FIFO 1070 * at the bottom, and also at the top of the FIFO
1036 */ 1071 */
1037 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr)); 1072 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
1038 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); 1073 dac33_write16(codec, DAC33_LTHR_MSB,
1074 DAC33_THRREG(DAC33_MODE7_MARGIN));
1039 break; 1075 break;
1040 default: 1076 default:
1041 break; 1077 break;
@@ -1049,8 +1085,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1049static void dac33_calculate_times(struct snd_pcm_substream *substream) 1085static void dac33_calculate_times(struct snd_pcm_substream *substream)
1050{ 1086{
1051 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1087 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1052 struct snd_soc_device *socdev = rtd->socdev; 1088 struct snd_soc_codec *codec = rtd->codec;
1053 struct snd_soc_codec *codec = socdev->card->codec;
1054 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1089 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int period_size = substream->runtime->period_size; 1090 unsigned int period_size = substream->runtime->period_size;
1056 unsigned int rate = substream->runtime->rate; 1091 unsigned int rate = substream->runtime->rate;
@@ -1065,38 +1100,21 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1065 /* Number of samples under i2c latency */ 1100 /* Number of samples under i2c latency */
1066 dac33->alarm_threshold = US_TO_SAMPLES(rate, 1101 dac33->alarm_threshold = US_TO_SAMPLES(rate,
1067 dac33->mode1_latency); 1102 dac33->mode1_latency);
1068 if (dac33->auto_fifo_config) { 1103 nsample_limit = dac33->fifo_size - dac33->alarm_threshold;
1069 if (period_size <= dac33->alarm_threshold) 1104
1070 /* 1105 if (period_size <= dac33->alarm_threshold)
1071 * Configure nSamaple to number of periods,
1072 * which covers the latency requironment.
1073 */
1074 dac33->nsample = period_size *
1075 ((dac33->alarm_threshold / period_size) +
1076 (dac33->alarm_threshold % period_size ?
1077 1 : 0));
1078 else
1079 dac33->nsample = period_size;
1080 } else {
1081 /* nSample time shall not be shorter than i2c latency */
1082 dac33->nsample_min = dac33->alarm_threshold;
1083 /* 1106 /*
1084 * nSample should not be bigger than alsa buffer minus 1107 * Configure nSamaple to number of periods,
1085 * size of one period to avoid overruns 1108 * which covers the latency requironment.
1086 */ 1109 */
1087 dac33->nsample_max = substream->runtime->buffer_size - 1110 dac33->nsample = period_size *
1088 period_size; 1111 ((dac33->alarm_threshold / period_size) +
1089 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - 1112 (dac33->alarm_threshold % period_size ?
1090 dac33->alarm_threshold; 1113 1 : 0));
1091 if (dac33->nsample_max > nsample_limit) 1114 else if (period_size > nsample_limit)
1092 dac33->nsample_max = nsample_limit; 1115 dac33->nsample = nsample_limit;
1093 1116 else
1094 /* Correct the nSample if it is outside of the ranges */ 1117 dac33->nsample = period_size;
1095 if (dac33->nsample < dac33->nsample_min)
1096 dac33->nsample = dac33->nsample_min;
1097 if (dac33->nsample > dac33->nsample_max)
1098 dac33->nsample = dac33->nsample_max;
1099 }
1100 1118
1101 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, 1119 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1102 dac33->nsample); 1120 dac33->nsample);
@@ -1104,19 +1122,16 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1104 dac33->t_stamp2 = 0; 1122 dac33->t_stamp2 = 0;
1105 break; 1123 break;
1106 case DAC33_FIFO_MODE7: 1124 case DAC33_FIFO_MODE7:
1107 if (dac33->auto_fifo_config) { 1125 dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate,
1108 dac33->uthr = UTHR_FROM_PERIOD_SIZE( 1126 dac33->burst_rate) + 9;
1109 period_size, 1127 if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN))
1110 rate, 1128 dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN;
1111 dac33->burst_rate) + 9; 1129 if (dac33->uthr < (DAC33_MODE7_MARGIN + 10))
1112 if (dac33->uthr > MODE7_UTHR) 1130 dac33->uthr = (DAC33_MODE7_MARGIN + 10);
1113 dac33->uthr = MODE7_UTHR; 1131
1114 if (dac33->uthr < (MODE7_LTHR + 10))
1115 dac33->uthr = (MODE7_LTHR + 10);
1116 }
1117 dac33->mode7_us_to_lthr = 1132 dac33->mode7_us_to_lthr =
1118 SAMPLES_TO_US(substream->runtime->rate, 1133 SAMPLES_TO_US(substream->runtime->rate,
1119 dac33->uthr - MODE7_LTHR + 1); 1134 dac33->uthr - DAC33_MODE7_MARGIN + 1);
1120 dac33->t_stamp1 = 0; 1135 dac33->t_stamp1 = 0;
1121 break; 1136 break;
1122 default: 1137 default:
@@ -1129,8 +1144,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1129 struct snd_soc_dai *dai) 1144 struct snd_soc_dai *dai)
1130{ 1145{
1131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1132 struct snd_soc_device *socdev = rtd->socdev; 1147 struct snd_soc_codec *codec = rtd->codec;
1133 struct snd_soc_codec *codec = socdev->card->codec;
1134 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1148 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1135 int ret = 0; 1149 int ret = 0;
1136 1150
@@ -1163,22 +1177,22 @@ static snd_pcm_sframes_t dac33_dai_delay(
1163 struct snd_soc_dai *dai) 1177 struct snd_soc_dai *dai)
1164{ 1178{
1165 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1179 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1166 struct snd_soc_device *socdev = rtd->socdev; 1180 struct snd_soc_codec *codec = rtd->codec;
1167 struct snd_soc_codec *codec = socdev->card->codec;
1168 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1181 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1169 unsigned long long t0, t1, t_now; 1182 unsigned long long t0, t1, t_now;
1170 unsigned int time_delta, uthr; 1183 unsigned int time_delta, uthr;
1171 int samples_out, samples_in, samples; 1184 int samples_out, samples_in, samples;
1172 snd_pcm_sframes_t delay = 0; 1185 snd_pcm_sframes_t delay = 0;
1186 unsigned long flags;
1173 1187
1174 switch (dac33->fifo_mode) { 1188 switch (dac33->fifo_mode) {
1175 case DAC33_FIFO_BYPASS: 1189 case DAC33_FIFO_BYPASS:
1176 break; 1190 break;
1177 case DAC33_FIFO_MODE1: 1191 case DAC33_FIFO_MODE1:
1178 spin_lock(&dac33->lock); 1192 spin_lock_irqsave(&dac33->lock, flags);
1179 t0 = dac33->t_stamp1; 1193 t0 = dac33->t_stamp1;
1180 t1 = dac33->t_stamp2; 1194 t1 = dac33->t_stamp2;
1181 spin_unlock(&dac33->lock); 1195 spin_unlock_irqrestore(&dac33->lock, flags);
1182 t_now = ktime_to_us(ktime_get()); 1196 t_now = ktime_to_us(ktime_get());
1183 1197
1184 /* We have not started to fill the FIFO yet, delay is 0 */ 1198 /* We have not started to fill the FIFO yet, delay is 0 */
@@ -1236,17 +1250,17 @@ static snd_pcm_sframes_t dac33_dai_delay(
1236 samples += (samples_in - samples_out); 1250 samples += (samples_in - samples_out);
1237 1251
1238 if (likely(samples > 0)) 1252 if (likely(samples > 0))
1239 delay = samples > DAC33_BUFFER_SIZE_SAMPLES ? 1253 delay = samples > dac33->fifo_size ?
1240 DAC33_BUFFER_SIZE_SAMPLES : samples; 1254 dac33->fifo_size : samples;
1241 else 1255 else
1242 delay = 0; 1256 delay = 0;
1243 } 1257 }
1244 break; 1258 break;
1245 case DAC33_FIFO_MODE7: 1259 case DAC33_FIFO_MODE7:
1246 spin_lock(&dac33->lock); 1260 spin_lock_irqsave(&dac33->lock, flags);
1247 t0 = dac33->t_stamp1; 1261 t0 = dac33->t_stamp1;
1248 uthr = dac33->uthr; 1262 uthr = dac33->uthr;
1249 spin_unlock(&dac33->lock); 1263 spin_unlock_irqrestore(&dac33->lock, flags);
1250 t_now = ktime_to_us(ktime_get()); 1264 t_now = ktime_to_us(ktime_get());
1251 1265
1252 /* We have not started to fill the FIFO yet, delay is 0 */ 1266 /* We have not started to fill the FIFO yet, delay is 0 */
@@ -1289,7 +1303,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1289 samples_in = US_TO_SAMPLES( 1303 samples_in = US_TO_SAMPLES(
1290 dac33->burst_rate, 1304 dac33->burst_rate,
1291 time_delta); 1305 time_delta);
1292 delay = MODE7_LTHR + samples_in - samples_out; 1306 delay = DAC33_MODE7_MARGIN + samples_in - samples_out;
1293 1307
1294 if (unlikely(delay > uthr)) 1308 if (unlikely(delay > uthr))
1295 delay = uthr; 1309 delay = uthr;
@@ -1389,91 +1403,110 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1389 return 0; 1403 return 0;
1390} 1404}
1391 1405
1392static int dac33_soc_probe(struct platform_device *pdev) 1406static int dac33_soc_probe(struct snd_soc_codec *codec)
1393{ 1407{
1394 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1408 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1395 struct snd_soc_codec *codec;
1396 struct tlv320dac33_priv *dac33;
1397 int ret = 0; 1409 int ret = 0;
1398 1410
1399 BUG_ON(!tlv320dac33_codec); 1411 codec->control_data = dac33->control_data;
1412 codec->hw_write = (hw_write_t) i2c_master_send;
1413 codec->dapm.idle_bias_off = 1;
1414 dac33->codec = codec;
1400 1415
1401 codec = tlv320dac33_codec; 1416 /* Read the tlv320dac33 ID registers */
1402 socdev->card->codec = codec; 1417 ret = dac33_hard_power(codec, 1);
1403 dac33 = snd_soc_codec_get_drvdata(codec); 1418 if (ret != 0) {
1419 dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
1420 goto err_power;
1421 }
1422 ret = dac33_read_id(codec);
1423 dac33_hard_power(codec, 0);
1404 1424
1405 /* register pcms */
1406 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1407 if (ret < 0) { 1425 if (ret < 0) {
1408 dev_err(codec->dev, "failed to create pcms\n"); 1426 dev_err(codec->dev, "Failed to read chip ID: %d\n", ret);
1409 goto pcm_err; 1427 ret = -ENODEV;
1428 goto err_power;
1429 }
1430
1431 /* Check if the IRQ number is valid and request it */
1432 if (dac33->irq >= 0) {
1433 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1434 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1435 codec->name, codec);
1436 if (ret < 0) {
1437 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1438 dac33->irq, ret);
1439 dac33->irq = -1;
1440 }
1441 if (dac33->irq != -1) {
1442 /* Setup work queue */
1443 dac33->dac33_wq =
1444 create_singlethread_workqueue("tlv320dac33");
1445 if (dac33->dac33_wq == NULL) {
1446 free_irq(dac33->irq, codec);
1447 return -ENOMEM;
1448 }
1449
1450 INIT_WORK(&dac33->work, dac33_work);
1451 }
1410 } 1452 }
1411 1453
1412 snd_soc_add_controls(codec, dac33_snd_controls, 1454 snd_soc_add_controls(codec, dac33_snd_controls,
1413 ARRAY_SIZE(dac33_snd_controls)); 1455 ARRAY_SIZE(dac33_snd_controls));
1414 /* Only add the FIFO controls, if we have valid IRQ number */ 1456 /* Only add the FIFO controls, if we have valid IRQ number */
1415 if (dac33->irq >= 0) { 1457 if (dac33->irq >= 0)
1416 snd_soc_add_controls(codec, dac33_mode_snd_controls, 1458 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1417 ARRAY_SIZE(dac33_mode_snd_controls)); 1459 ARRAY_SIZE(dac33_mode_snd_controls));
1418 /* FIFO usage controls only, if autoio config is not selected */
1419 if (!dac33->auto_fifo_config)
1420 snd_soc_add_controls(codec, dac33_fifo_snd_controls,
1421 ARRAY_SIZE(dac33_fifo_snd_controls));
1422 }
1423 1460
1424 dac33_add_widgets(codec); 1461 dac33_add_widgets(codec);
1425 1462
1426 return 0; 1463err_power:
1427
1428pcm_err:
1429 dac33_hard_power(codec, 0);
1430 return ret; 1464 return ret;
1431} 1465}
1432 1466
1433static int dac33_soc_remove(struct platform_device *pdev) 1467static int dac33_soc_remove(struct snd_soc_codec *codec)
1434{ 1468{
1435 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1469 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1436 struct snd_soc_codec *codec = socdev->card->codec;
1437 1470
1438 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF); 1471 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1439 1472
1440 snd_soc_free_pcms(socdev); 1473 if (dac33->irq >= 0) {
1441 snd_soc_dapm_free(socdev); 1474 free_irq(dac33->irq, dac33->codec);
1442 1475 destroy_workqueue(dac33->dac33_wq);
1476 }
1443 return 0; 1477 return 0;
1444} 1478}
1445 1479
1446static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state) 1480static int dac33_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
1447{ 1481{
1448 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1449 struct snd_soc_codec *codec = socdev->card->codec;
1450
1451 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF); 1482 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
1452 1483
1453 return 0; 1484 return 0;
1454} 1485}
1455 1486
1456static int dac33_soc_resume(struct platform_device *pdev) 1487static int dac33_soc_resume(struct snd_soc_codec *codec)
1457{ 1488{
1458 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1459 struct snd_soc_codec *codec = socdev->card->codec;
1460
1461 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1489 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1462 1490
1463 return 0; 1491 return 0;
1464} 1492}
1465 1493
1466struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = { 1494static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1495 .read = dac33_read_reg_cache,
1496 .write = dac33_write_locked,
1497 .set_bias_level = dac33_set_bias_level,
1498 .reg_cache_size = ARRAY_SIZE(dac33_reg),
1499 .reg_word_size = sizeof(u8),
1500 .reg_cache_default = dac33_reg,
1467 .probe = dac33_soc_probe, 1501 .probe = dac33_soc_probe,
1468 .remove = dac33_soc_remove, 1502 .remove = dac33_soc_remove,
1469 .suspend = dac33_soc_suspend, 1503 .suspend = dac33_soc_suspend,
1470 .resume = dac33_soc_resume, 1504 .resume = dac33_soc_resume,
1471}; 1505};
1472EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1473 1506
1474#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ 1507#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1475 SNDRV_PCM_RATE_48000) 1508 SNDRV_PCM_RATE_48000)
1476#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE 1509#define DAC33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1477 1510
1478static struct snd_soc_dai_ops dac33_dai_ops = { 1511static struct snd_soc_dai_ops dac33_dai_ops = {
1479 .startup = dac33_startup, 1512 .startup = dac33_startup,
@@ -1485,8 +1518,8 @@ static struct snd_soc_dai_ops dac33_dai_ops = {
1485 .set_fmt = dac33_set_dai_fmt, 1518 .set_fmt = dac33_set_dai_fmt,
1486}; 1519};
1487 1520
1488struct snd_soc_dai dac33_dai = { 1521static struct snd_soc_dai_driver dac33_dai = {
1489 .name = "tlv320dac33", 1522 .name = "tlv320dac33-hifi",
1490 .playback = { 1523 .playback = {
1491 .stream_name = "Playback", 1524 .stream_name = "Playback",
1492 .channels_min = 2, 1525 .channels_min = 2,
@@ -1495,14 +1528,12 @@ struct snd_soc_dai dac33_dai = {
1495 .formats = DAC33_FORMATS,}, 1528 .formats = DAC33_FORMATS,},
1496 .ops = &dac33_dai_ops, 1529 .ops = &dac33_dai_ops,
1497}; 1530};
1498EXPORT_SYMBOL_GPL(dac33_dai);
1499 1531
1500static int __devinit dac33_i2c_probe(struct i2c_client *client, 1532static int __devinit dac33_i2c_probe(struct i2c_client *client,
1501 const struct i2c_device_id *id) 1533 const struct i2c_device_id *id)
1502{ 1534{
1503 struct tlv320dac33_platform_data *pdata; 1535 struct tlv320dac33_platform_data *pdata;
1504 struct tlv320dac33_priv *dac33; 1536 struct tlv320dac33_priv *dac33;
1505 struct snd_soc_codec *codec;
1506 int ret, i; 1537 int ret, i;
1507 1538
1508 if (client->dev.platform_data == NULL) { 1539 if (client->dev.platform_data == NULL) {
@@ -1515,171 +1546,75 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1515 if (dac33 == NULL) 1546 if (dac33 == NULL)
1516 return -ENOMEM; 1547 return -ENOMEM;
1517 1548
1518 codec = &dac33->codec; 1549 dac33->control_data = client;
1519 snd_soc_codec_set_drvdata(codec, dac33);
1520 codec->control_data = client;
1521
1522 mutex_init(&codec->mutex);
1523 mutex_init(&dac33->mutex); 1550 mutex_init(&dac33->mutex);
1524 spin_lock_init(&dac33->lock); 1551 spin_lock_init(&dac33->lock);
1525 INIT_LIST_HEAD(&codec->dapm_widgets);
1526 INIT_LIST_HEAD(&codec->dapm_paths);
1527
1528 codec->name = "tlv320dac33";
1529 codec->owner = THIS_MODULE;
1530 codec->read = dac33_read_reg_cache;
1531 codec->write = dac33_write_locked;
1532 codec->hw_write = (hw_write_t) i2c_master_send;
1533 codec->bias_level = SND_SOC_BIAS_OFF;
1534 codec->set_bias_level = dac33_set_bias_level;
1535 codec->idle_bias_off = 1;
1536 codec->dai = &dac33_dai;
1537 codec->num_dai = 1;
1538 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1539 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1540 GFP_KERNEL);
1541 if (codec->reg_cache == NULL) {
1542 ret = -ENOMEM;
1543 goto error_reg;
1544 }
1545 1552
1546 i2c_set_clientdata(client, dac33); 1553 i2c_set_clientdata(client, dac33);
1547 1554
1548 dac33->power_gpio = pdata->power_gpio; 1555 dac33->power_gpio = pdata->power_gpio;
1549 dac33->burst_bclkdiv = pdata->burst_bclkdiv; 1556 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1550 /* Pre calculate the burst rate */
1551 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1552 dac33->keep_bclk = pdata->keep_bclk; 1557 dac33->keep_bclk = pdata->keep_bclk;
1553 dac33->auto_fifo_config = pdata->auto_fifo_config;
1554 dac33->mode1_latency = pdata->mode1_latency; 1558 dac33->mode1_latency = pdata->mode1_latency;
1555 if (!dac33->mode1_latency) 1559 if (!dac33->mode1_latency)
1556 dac33->mode1_latency = 10000; /* 10ms */ 1560 dac33->mode1_latency = 10000; /* 10ms */
1557 dac33->irq = client->irq; 1561 dac33->irq = client->irq;
1558 dac33->nsample = NSAMPLE_MAX;
1559 dac33->nsample_max = NSAMPLE_MAX;
1560 dac33->uthr = MODE7_UTHR;
1561 /* Disable FIFO use by default */ 1562 /* Disable FIFO use by default */
1562 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1563 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1563 1564
1564 tlv320dac33_codec = codec;
1565
1566 codec->dev = &client->dev;
1567 dac33_dai.dev = codec->dev;
1568
1569 /* Check if the reset GPIO number is valid and request it */ 1565 /* Check if the reset GPIO number is valid and request it */
1570 if (dac33->power_gpio >= 0) { 1566 if (dac33->power_gpio >= 0) {
1571 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset"); 1567 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1572 if (ret < 0) { 1568 if (ret < 0) {
1573 dev_err(codec->dev, 1569 dev_err(&client->dev,
1574 "Failed to request reset GPIO (%d)\n", 1570 "Failed to request reset GPIO (%d)\n",
1575 dac33->power_gpio); 1571 dac33->power_gpio);
1576 snd_soc_unregister_dai(&dac33_dai); 1572 goto err_gpio;
1577 snd_soc_unregister_codec(codec);
1578 goto error_gpio;
1579 } 1573 }
1580 gpio_direction_output(dac33->power_gpio, 0); 1574 gpio_direction_output(dac33->power_gpio, 0);
1581 } 1575 }
1582 1576
1583 /* Check if the IRQ number is valid and request it */
1584 if (dac33->irq >= 0) {
1585 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1586 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1587 codec->name, codec);
1588 if (ret < 0) {
1589 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1590 dac33->irq, ret);
1591 dac33->irq = -1;
1592 }
1593 if (dac33->irq != -1) {
1594 /* Setup work queue */
1595 dac33->dac33_wq =
1596 create_singlethread_workqueue("tlv320dac33");
1597 if (dac33->dac33_wq == NULL) {
1598 free_irq(dac33->irq, &dac33->codec);
1599 ret = -ENOMEM;
1600 goto error_wq;
1601 }
1602
1603 INIT_WORK(&dac33->work, dac33_work);
1604 }
1605 }
1606
1607 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++) 1577 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1608 dac33->supplies[i].supply = dac33_supply_names[i]; 1578 dac33->supplies[i].supply = dac33_supply_names[i];
1609 1579
1610 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies), 1580 ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies),
1611 dac33->supplies); 1581 dac33->supplies);
1612 1582
1613 if (ret != 0) { 1583 if (ret != 0) {
1614 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 1584 dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
1615 goto err_get; 1585 goto err_get;
1616 } 1586 }
1617 1587
1618 /* Read the tlv320dac33 ID registers */ 1588 ret = snd_soc_register_codec(&client->dev,
1619 ret = dac33_hard_power(codec, 1); 1589 &soc_codec_dev_tlv320dac33, &dac33_dai, 1);
1620 if (ret != 0) { 1590 if (ret < 0)
1621 dev_err(codec->dev, "Failed to power up codec: %d\n", ret); 1591 goto err_register;
1622 goto error_codec;
1623 }
1624 dac33_read_id(codec);
1625 dac33_hard_power(codec, 0);
1626
1627 ret = snd_soc_register_codec(codec);
1628 if (ret != 0) {
1629 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1630 goto error_codec;
1631 }
1632
1633 ret = snd_soc_register_dai(&dac33_dai);
1634 if (ret != 0) {
1635 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1636 snd_soc_unregister_codec(codec);
1637 goto error_codec;
1638 }
1639 1592
1640 return ret; 1593 return ret;
1641 1594err_register:
1642error_codec:
1643 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1595 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1644err_get: 1596err_get:
1645 if (dac33->irq >= 0) {
1646 free_irq(dac33->irq, &dac33->codec);
1647 destroy_workqueue(dac33->dac33_wq);
1648 }
1649error_wq:
1650 if (dac33->power_gpio >= 0) 1597 if (dac33->power_gpio >= 0)
1651 gpio_free(dac33->power_gpio); 1598 gpio_free(dac33->power_gpio);
1652error_gpio: 1599err_gpio:
1653 kfree(codec->reg_cache);
1654error_reg:
1655 tlv320dac33_codec = NULL;
1656 kfree(dac33); 1600 kfree(dac33);
1657
1658 return ret; 1601 return ret;
1659} 1602}
1660 1603
1661static int __devexit dac33_i2c_remove(struct i2c_client *client) 1604static int __devexit dac33_i2c_remove(struct i2c_client *client)
1662{ 1605{
1663 struct tlv320dac33_priv *dac33; 1606 struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
1664
1665 dac33 = i2c_get_clientdata(client);
1666 1607
1667 if (unlikely(dac33->chip_power)) 1608 if (unlikely(dac33->chip_power))
1668 dac33_hard_power(&dac33->codec, 0); 1609 dac33_hard_power(dac33->codec, 0);
1669 1610
1670 if (dac33->power_gpio >= 0) 1611 if (dac33->power_gpio >= 0)
1671 gpio_free(dac33->power_gpio); 1612 gpio_free(dac33->power_gpio);
1672 if (dac33->irq >= 0)
1673 free_irq(dac33->irq, &dac33->codec);
1674 1613
1675 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1614 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1676 1615
1677 destroy_workqueue(dac33->dac33_wq); 1616 snd_soc_unregister_codec(&client->dev);
1678 snd_soc_unregister_dai(&dac33_dai);
1679 snd_soc_unregister_codec(&dac33->codec);
1680 kfree(dac33->codec.reg_cache);
1681 kfree(dac33); 1617 kfree(dac33);
1682 tlv320dac33_codec = NULL;
1683 1618
1684 return 0; 1619 return 0;
1685} 1620}
@@ -1691,10 +1626,11 @@ static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1691 }, 1626 },
1692 { }, 1627 { },
1693}; 1628};
1629MODULE_DEVICE_TABLE(i2c, tlv320dac33_i2c_id);
1694 1630
1695static struct i2c_driver tlv320dac33_i2c_driver = { 1631static struct i2c_driver tlv320dac33_i2c_driver = {
1696 .driver = { 1632 .driver = {
1697 .name = "tlv320dac33", 1633 .name = "tlv320dac33-codec",
1698 .owner = THIS_MODULE, 1634 .owner = THIS_MODULE,
1699 }, 1635 },
1700 .probe = dac33_i2c_probe, 1636 .probe = dac33_i2c_probe,
@@ -1722,5 +1658,5 @@ module_exit(dac33_module_exit);
1722 1658
1723 1659
1724MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver"); 1660MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1725MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>"); 1661MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
1726MODULE_LICENSE("GPL"); 1662MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
index eb8ae07f0bd2..ed69670747bf 100644
--- a/sound/soc/codecs/tlv320dac33.h
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver 2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 * 3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 4 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5 * 5 *
6 * Copyright: (C) 2009 Nokia Corporation 6 * Copyright: (C) 2009 Nokia Corporation
7 * 7 *
@@ -261,7 +261,4 @@
261#define TLV320DAC33_MCLK 0 261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1 262#define TLV320DAC33_SLEEPCLK 1
263 263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */ 264#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 99b70e5978a2..239e0c461068 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -29,7 +29,6 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <sound/tpa6130a2-plat.h> 30#include <sound/tpa6130a2-plat.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h> 32#include <sound/tlv.h>
34 33
35#include "tpa6130a2.h" 34#include "tpa6130a2.h"
@@ -42,7 +41,7 @@ struct tpa6130a2_data {
42 unsigned char regs[TPA6130A2_CACHEREGNUM]; 41 unsigned char regs[TPA6130A2_CACHEREGNUM];
43 struct regulator *supply; 42 struct regulator *supply;
44 int power_gpio; 43 int power_gpio;
45 unsigned char power_state; 44 u8 power_state:1;
46 enum tpa_model id; 45 enum tpa_model id;
47}; 46};
48 47
@@ -78,8 +77,10 @@ static int tpa6130a2_i2c_write(int reg, u8 value)
78 77
79 if (data->power_state) { 78 if (data->power_state) {
80 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value); 79 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
81 if (val < 0) 80 if (val < 0) {
82 dev_err(&tpa6130a2_client->dev, "Write failed\n"); 81 dev_err(&tpa6130a2_client->dev, "Write failed\n");
82 return val;
83 }
83 } 84 }
84 85
85 /* Either powered on or off, we save the context */ 86 /* Either powered on or off, we save the context */
@@ -98,47 +99,58 @@ static u8 tpa6130a2_read(int reg)
98 return data->regs[reg]; 99 return data->regs[reg];
99} 100}
100 101
101static void tpa6130a2_initialize(void) 102static int tpa6130a2_initialize(void)
102{ 103{
103 struct tpa6130a2_data *data; 104 struct tpa6130a2_data *data;
104 int i; 105 int i, ret = 0;
105 106
106 BUG_ON(tpa6130a2_client == NULL); 107 BUG_ON(tpa6130a2_client == NULL);
107 data = i2c_get_clientdata(tpa6130a2_client); 108 data = i2c_get_clientdata(tpa6130a2_client);
108 109
109 for (i = 1; i < TPA6130A2_REG_VERSION; i++) 110 for (i = 1; i < TPA6130A2_REG_VERSION; i++) {
110 tpa6130a2_i2c_write(i, data->regs[i]); 111 ret = tpa6130a2_i2c_write(i, data->regs[i]);
112 if (ret < 0)
113 break;
114 }
115
116 return ret;
111} 117}
112 118
113static int tpa6130a2_power(int power) 119static int tpa6130a2_power(u8 power)
114{ 120{
115 struct tpa6130a2_data *data; 121 struct tpa6130a2_data *data;
116 u8 val; 122 u8 val;
117 int ret; 123 int ret = 0;
118 124
119 BUG_ON(tpa6130a2_client == NULL); 125 BUG_ON(tpa6130a2_client == NULL);
120 data = i2c_get_clientdata(tpa6130a2_client); 126 data = i2c_get_clientdata(tpa6130a2_client);
121 127
122 mutex_lock(&data->mutex); 128 mutex_lock(&data->mutex);
123 if (power) { 129 if (power == data->power_state)
124 /* Power on */ 130 goto exit;
125 if (data->power_gpio >= 0)
126 gpio_set_value(data->power_gpio, 1);
127 131
132 if (power) {
128 ret = regulator_enable(data->supply); 133 ret = regulator_enable(data->supply);
129 if (ret != 0) { 134 if (ret != 0) {
130 dev_err(&tpa6130a2_client->dev, 135 dev_err(&tpa6130a2_client->dev,
131 "Failed to enable supply: %d\n", ret); 136 "Failed to enable supply: %d\n", ret);
132 goto exit; 137 goto exit;
133 } 138 }
139 /* Power on */
140 if (data->power_gpio >= 0)
141 gpio_set_value(data->power_gpio, 1);
134 142
135 data->power_state = 1; 143 data->power_state = 1;
136 tpa6130a2_initialize(); 144 ret = tpa6130a2_initialize();
137 145 if (ret < 0) {
138 /* Clear SWS */ 146 dev_err(&tpa6130a2_client->dev,
139 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 147 "Failed to initialize chip\n");
140 val &= ~TPA6130A2_SWS; 148 if (data->power_gpio >= 0)
141 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); 149 gpio_set_value(data->power_gpio, 0);
150 regulator_disable(data->supply);
151 data->power_state = 0;
152 goto exit;
153 }
142 } else { 154 } else {
143 /* set SWS */ 155 /* set SWS */
144 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 156 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
@@ -284,6 +296,7 @@ static void tpa6130a2_channel_enable(u8 channel, int enable)
284 /* Enable amplifier */ 296 /* Enable amplifier */
285 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 297 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
286 val |= channel; 298 val |= channel;
299 val &= ~TPA6130A2_SWS;
287 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); 300 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
288 301
289 /* Unmute channel */ 302 /* Unmute channel */
@@ -304,84 +317,33 @@ static void tpa6130a2_channel_enable(u8 channel, int enable)
304 } 317 }
305} 318}
306 319
307static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w, 320int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
308 struct snd_kcontrol *kcontrol, int event)
309{
310 switch (event) {
311 case SND_SOC_DAPM_POST_PMU:
312 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
313 break;
314 case SND_SOC_DAPM_POST_PMD:
315 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
316 break;
317 }
318 return 0;
319}
320
321static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
322 struct snd_kcontrol *kcontrol, int event)
323{
324 switch (event) {
325 case SND_SOC_DAPM_POST_PMU:
326 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
327 break;
328 case SND_SOC_DAPM_POST_PMD:
329 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
330 break;
331 }
332 return 0;
333}
334
335static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
336 struct snd_kcontrol *kcontrol, int event)
337{ 321{
338 int ret = 0; 322 int ret = 0;
339 323 if (enable) {
340 switch (event) {
341 case SND_SOC_DAPM_POST_PMU:
342 ret = tpa6130a2_power(1); 324 ret = tpa6130a2_power(1);
343 break; 325 if (ret < 0)
344 case SND_SOC_DAPM_POST_PMD: 326 return ret;
327 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
328 1);
329 } else {
330 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
331 0);
345 ret = tpa6130a2_power(0); 332 ret = tpa6130a2_power(0);
346 break;
347 } 333 }
334
348 return ret; 335 return ret;
349} 336}
350 337EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
351static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
352 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
353 0, 0, NULL, 0, tpa6130a2_left_event,
354 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
355 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
356 0, 0, NULL, 0, tpa6130a2_right_event,
357 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
358 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
359 0, 0, tpa6130a2_supply_event,
360 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
361 /* Outputs */
362 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"),
363 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"),
364};
365
366static const struct snd_soc_dapm_route audio_map[] = {
367 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
368 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
369
370 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
371 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
372};
373 338
374int tpa6130a2_add_controls(struct snd_soc_codec *codec) 339int tpa6130a2_add_controls(struct snd_soc_codec *codec)
375{ 340{
376 struct tpa6130a2_data *data; 341 struct tpa6130a2_data *data;
377 342
378 BUG_ON(tpa6130a2_client == NULL); 343 if (tpa6130a2_client == NULL)
379 data = i2c_get_clientdata(tpa6130a2_client); 344 return -ENODEV;
380
381 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
382 ARRAY_SIZE(tpa6130a2_dapm_widgets));
383 345
384 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 346 data = i2c_get_clientdata(tpa6130a2_client);
385 347
386 if (data->id == TPA6140A2) 348 if (data->id == TPA6140A2)
387 return snd_soc_add_controls(codec, tpa6140a2_controls, 349 return snd_soc_add_controls(codec, tpa6140a2_controls,
@@ -389,7 +351,6 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
389 else 351 else
390 return snd_soc_add_controls(codec, tpa6130a2_controls, 352 return snd_soc_add_controls(codec, tpa6130a2_controls,
391 ARRAY_SIZE(tpa6130a2_controls)); 353 ARRAY_SIZE(tpa6130a2_controls));
392
393} 354}
394EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 355EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
395 356
@@ -534,7 +495,7 @@ static void __exit tpa6130a2_exit(void)
534 i2c_del_driver(&tpa6130a2_i2c_driver); 495 i2c_del_driver(&tpa6130a2_i2c_driver);
535} 496}
536 497
537MODULE_AUTHOR("Peter Ujfalusi"); 498MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
538MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver"); 499MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
539MODULE_LICENSE("GPL"); 500MODULE_LICENSE("GPL");
540 501
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 57e867fd86d1..417444020ba6 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) Nokia Corporation 4 * Copyright (C) Nokia Corporation
5 * 5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com> 6 * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -57,5 +57,6 @@
57#define TPA6130A2_VERSION_MASK (0x0f) 57#define TPA6130A2_VERSION_MASK (0x0f)
58 58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec); 59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
60 61
61#endif /* __TPA6130A2_H__ */ 62#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 7b618bbff884..bec788b12613 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -32,11 +32,19 @@
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <sound/soc-dapm.h>
36#include <sound/initval.h> 35#include <sound/initval.h>
37#include <sound/tlv.h> 36#include <sound/tlv.h>
38 37
39#include "twl4030.h" 38/* Register descriptions are here */
39#include <linux/mfd/twl4030-codec.h>
40
41/* Shadow register used by the audio driver */
42#define TWL4030_REG_SW_SHADOW 0x4A
43#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
44
45/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
46#define TWL4030_HFL_EN 0x01
47#define TWL4030_HFR_EN 0x02
40 48
41/* 49/*
42 * twl4030 register cache & default register settings 50 * twl4030 register cache & default register settings
@@ -224,6 +232,16 @@ static int twl4030_write(struct snd_soc_codec *codec,
224 return 0; 232 return 0;
225} 233}
226 234
235static inline void twl4030_wait_ms(int time)
236{
237 if (time < 60) {
238 time *= 1000;
239 usleep_range(time, time + 500);
240 } else {
241 msleep(time);
242 }
243}
244
227static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 245static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
228{ 246{
229 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 247 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -262,7 +280,7 @@ static inline void twl4030_check_defaults(struct snd_soc_codec *codec)
262 i, val, twl4030_reg[i]); 280 i, val, twl4030_reg[i]);
263 } 281 }
264 } 282 }
265 dev_dbg(codec->dev, "Found %d non maching registers. %s\n", 283 dev_dbg(codec->dev, "Found %d non-matching registers. %s\n",
266 difference, difference ? "Not OK" : "OK"); 284 difference, difference ? "Not OK" : "OK");
267} 285}
268 286
@@ -277,21 +295,19 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
277 295
278} 296}
279 297
280static void twl4030_init_chip(struct platform_device *pdev) 298static void twl4030_init_chip(struct snd_soc_codec *codec)
281{ 299{
282 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 300 struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev);
283 struct twl4030_setup_data *setup = socdev->codec_data;
284 struct snd_soc_codec *codec = socdev->card->codec;
285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 301 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
286 u8 reg, byte; 302 u8 reg, byte;
287 int i = 0; 303 int i = 0;
288 304
289 /* Check defaults, if instructed before anything else */ 305 /* Check defaults, if instructed before anything else */
290 if (setup && setup->check_defaults) 306 if (pdata && pdata->check_defaults)
291 twl4030_check_defaults(codec); 307 twl4030_check_defaults(codec);
292 308
293 /* Reset registers, if no setup data or if instructed to do so */ 309 /* Reset registers, if no setup data or if instructed to do so */
294 if (!setup || (setup && setup->reset_registers)) 310 if (!pdata || (pdata && pdata->reset_registers))
295 twl4030_reset_registers(codec); 311 twl4030_reset_registers(codec);
296 312
297 /* Refresh APLL_CTL register from HW */ 313 /* Refresh APLL_CTL register from HW */
@@ -312,20 +328,14 @@ static void twl4030_init_chip(struct platform_device *pdev)
312 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32); 328 twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
313 329
314 /* Machine dependent setup */ 330 /* Machine dependent setup */
315 if (!setup) 331 if (!pdata)
316 return; 332 return;
317 333
318 twl4030->digimic_delay = setup->digimic_delay; 334 twl4030->digimic_delay = pdata->digimic_delay;
319
320 /* Configuration for headset ramp delay from setup data */
321 if (setup->sysclk != twl4030->sysclk)
322 dev_warn(codec->dev,
323 "Mismatch in APLL mclk: %u (configured: %u)\n",
324 setup->sysclk, twl4030->sysclk);
325 335
326 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 336 reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
327 reg &= ~TWL4030_RAMP_DELAY; 337 reg &= ~TWL4030_RAMP_DELAY;
328 reg |= (setup->ramp_delay_value << 2); 338 reg |= (pdata->ramp_delay_value << 2);
329 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg); 339 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
330 340
331 /* initiate offset cancellation */ 341 /* initiate offset cancellation */
@@ -333,14 +343,18 @@ static void twl4030_init_chip(struct platform_device *pdev)
333 343
334 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); 344 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
335 reg &= ~TWL4030_OFFSET_CNCL_SEL; 345 reg &= ~TWL4030_OFFSET_CNCL_SEL;
336 reg |= setup->offset_cncl_path; 346 reg |= pdata->offset_cncl_path;
337 twl4030_write(codec, TWL4030_REG_ANAMICL, 347 twl4030_write(codec, TWL4030_REG_ANAMICL,
338 reg | TWL4030_CNCL_OFFSET_START); 348 reg | TWL4030_CNCL_OFFSET_START);
339 349
340 /* wait for offset cancellation to complete */ 350 /*
351 * Wait for offset cancellation to complete.
352 * Since this takes a while, do not slam the i2c.
353 * Start polling the status after ~20ms.
354 */
355 msleep(20);
341 do { 356 do {
342 /* this takes a little while, so don't slam i2c */ 357 usleep_range(1000, 2000);
343 udelay(2000);
344 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, 358 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
345 TWL4030_REG_ANAMICL); 359 TWL4030_REG_ANAMICL);
346 } while ((i++ < 100) && 360 } while ((i++ < 100) &&
@@ -718,23 +732,24 @@ static int aif_event(struct snd_soc_dapm_widget *w,
718 732
719static void headset_ramp(struct snd_soc_codec *codec, int ramp) 733static void headset_ramp(struct snd_soc_codec *codec, int ramp)
720{ 734{
721 struct snd_soc_device *socdev = codec->socdev; 735 struct twl4030_codec_audio_data *pdata = codec->dev->platform_data;
722 struct twl4030_setup_data *setup = socdev->codec_data;
723
724 unsigned char hs_gain, hs_pop; 736 unsigned char hs_gain, hs_pop;
725 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
726 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 738 /* Base values for ramp delay calculation: 2^19 - 2^26 */
727 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 739 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
728 8388608, 16777216, 33554432, 67108864}; 740 8388608, 16777216, 33554432, 67108864};
741 unsigned int delay;
729 742
730 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 743 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
731 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 744 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
745 delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
746 twl4030->sysclk) + 1;
732 747
733 /* Enable external mute control, this dramatically reduces 748 /* Enable external mute control, this dramatically reduces
734 * the pop-noise */ 749 * the pop-noise */
735 if (setup && setup->hs_extmute) { 750 if (pdata && pdata->hs_extmute) {
736 if (setup->set_hs_extmute) { 751 if (pdata->set_hs_extmute) {
737 setup->set_hs_extmute(1); 752 pdata->set_hs_extmute(1);
738 } else { 753 } else {
739 hs_pop |= TWL4030_EXTMUTE; 754 hs_pop |= TWL4030_EXTMUTE;
740 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 755 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -752,16 +767,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
752 hs_pop |= TWL4030_RAMP_EN; 767 hs_pop |= TWL4030_RAMP_EN;
753 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 768 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
754 /* Wait ramp delay time + 1, so the VMID can settle */ 769 /* Wait ramp delay time + 1, so the VMID can settle */
755 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 770 twl4030_wait_ms(delay);
756 twl4030->sysclk) + 1);
757 } else { 771 } else {
758 /* Headset ramp-down _not_ according to 772 /* Headset ramp-down _not_ according to
759 * the TRM, but in a way that it is working */ 773 * the TRM, but in a way that it is working */
760 hs_pop &= ~TWL4030_RAMP_EN; 774 hs_pop &= ~TWL4030_RAMP_EN;
761 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 775 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
762 /* Wait ramp delay time + 1, so the VMID can settle */ 776 /* Wait ramp delay time + 1, so the VMID can settle */
763 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 777 twl4030_wait_ms(delay);
764 twl4030->sysclk) + 1);
765 /* Bypass the reg_cache to mute the headset */ 778 /* Bypass the reg_cache to mute the headset */
766 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 779 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
767 hs_gain & (~0x0f), 780 hs_gain & (~0x0f),
@@ -772,9 +785,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
772 } 785 }
773 786
774 /* Disable external mute */ 787 /* Disable external mute */
775 if (setup && setup->hs_extmute) { 788 if (pdata && pdata->hs_extmute) {
776 if (setup->set_hs_extmute) { 789 if (pdata->set_hs_extmute) {
777 setup->set_hs_extmute(0); 790 pdata->set_hs_extmute(0);
778 } else { 791 } else {
779 hs_pop &= ~TWL4030_EXTMUTE; 792 hs_pop &= ~TWL4030_EXTMUTE;
780 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 793 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -836,7 +849,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
836 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 849 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
837 850
838 if (twl4030->digimic_delay) 851 if (twl4030->digimic_delay)
839 mdelay(twl4030->digimic_delay); 852 twl4030_wait_ms(twl4030->digimic_delay);
840 return 0; 853 return 0;
841} 854}
842 855
@@ -1622,10 +1635,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1622 1635
1623static int twl4030_add_widgets(struct snd_soc_codec *codec) 1636static int twl4030_add_widgets(struct snd_soc_codec *codec)
1624{ 1637{
1625 snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets, 1638 struct snd_soc_dapm_context *dapm = &codec->dapm;
1626 ARRAY_SIZE(twl4030_dapm_widgets));
1627 1639
1628 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1640 snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
1641 ARRAY_SIZE(twl4030_dapm_widgets));
1642 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1629 1643
1630 return 0; 1644 return 0;
1631} 1645}
@@ -1639,14 +1653,14 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1639 case SND_SOC_BIAS_PREPARE: 1653 case SND_SOC_BIAS_PREPARE:
1640 break; 1654 break;
1641 case SND_SOC_BIAS_STANDBY: 1655 case SND_SOC_BIAS_STANDBY:
1642 if (codec->bias_level == SND_SOC_BIAS_OFF) 1656 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1643 twl4030_codec_enable(codec, 1); 1657 twl4030_codec_enable(codec, 1);
1644 break; 1658 break;
1645 case SND_SOC_BIAS_OFF: 1659 case SND_SOC_BIAS_OFF:
1646 twl4030_codec_enable(codec, 0); 1660 twl4030_codec_enable(codec, 0);
1647 break; 1661 break;
1648 } 1662 }
1649 codec->bias_level = level; 1663 codec->dapm.bias_level = level;
1650 1664
1651 return 0; 1665 return 0;
1652} 1666}
@@ -1707,10 +1721,10 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1707 struct snd_soc_dai *dai) 1721 struct snd_soc_dai *dai)
1708{ 1722{
1709 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1723 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1710 struct snd_soc_device *socdev = rtd->socdev; 1724 struct snd_soc_codec *codec = rtd->codec;
1711 struct snd_soc_codec *codec = socdev->card->codec;
1712 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1725 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1713 1726
1727 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
1714 if (twl4030->master_substream) { 1728 if (twl4030->master_substream) {
1715 twl4030->slave_substream = substream; 1729 twl4030->slave_substream = substream;
1716 /* The DAI has one configuration for playback and capture, so 1730 /* The DAI has one configuration for playback and capture, so
@@ -1738,8 +1752,7 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
1738 struct snd_soc_dai *dai) 1752 struct snd_soc_dai *dai)
1739{ 1753{
1740 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1754 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1741 struct snd_soc_device *socdev = rtd->socdev; 1755 struct snd_soc_codec *codec = rtd->codec;
1742 struct snd_soc_codec *codec = socdev->card->codec;
1743 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1756 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1744 1757
1745 if (twl4030->master_substream == substream) 1758 if (twl4030->master_substream == substream)
@@ -1764,8 +1777,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1764 struct snd_soc_dai *dai) 1777 struct snd_soc_dai *dai)
1765{ 1778{
1766 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1779 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1767 struct snd_soc_device *socdev = rtd->socdev; 1780 struct snd_soc_codec *codec = rtd->codec;
1768 struct snd_soc_codec *codec = socdev->card->codec;
1769 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1781 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1770 u8 mode, old_mode, format, old_format; 1782 u8 mode, old_mode, format, old_format;
1771 1783
@@ -1837,7 +1849,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1837 case SNDRV_PCM_FORMAT_S16_LE: 1849 case SNDRV_PCM_FORMAT_S16_LE:
1838 format |= TWL4030_DATA_WIDTH_16S_16W; 1850 format |= TWL4030_DATA_WIDTH_16S_16W;
1839 break; 1851 break;
1840 case SNDRV_PCM_FORMAT_S24_LE: 1852 case SNDRV_PCM_FORMAT_S32_LE:
1841 format |= TWL4030_DATA_WIDTH_32S_24W; 1853 format |= TWL4030_DATA_WIDTH_32S_24W;
1842 break; 1854 break;
1843 default: 1855 default:
@@ -1999,13 +2011,12 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1999 struct snd_soc_dai *dai) 2011 struct snd_soc_dai *dai)
2000{ 2012{
2001 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2013 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2002 struct snd_soc_device *socdev = rtd->socdev; 2014 struct snd_soc_codec *codec = rtd->codec;
2003 struct snd_soc_codec *codec = socdev->card->codec;
2004 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2015 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2005 u8 mode; 2016 u8 mode;
2006 2017
2007 /* If the system master clock is not 26MHz, the voice PCM interface is 2018 /* If the system master clock is not 26MHz, the voice PCM interface is
2008 * not avilable. 2019 * not available.
2009 */ 2020 */
2010 if (twl4030->sysclk != 26000) { 2021 if (twl4030->sysclk != 26000) {
2011 dev_err(codec->dev, "The board is configured for %u Hz, while" 2022 dev_err(codec->dev, "The board is configured for %u Hz, while"
@@ -2015,7 +2026,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2015 } 2026 }
2016 2027
2017 /* If the codec mode is not option2, the voice PCM interface is not 2028 /* If the codec mode is not option2, the voice PCM interface is not
2018 * avilable. 2029 * available.
2019 */ 2030 */
2020 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) 2031 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE)
2021 & TWL4030_OPT_MODE; 2032 & TWL4030_OPT_MODE;
@@ -2033,8 +2044,7 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2033 struct snd_soc_dai *dai) 2044 struct snd_soc_dai *dai)
2034{ 2045{
2035 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2046 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2036 struct snd_soc_device *socdev = rtd->socdev; 2047 struct snd_soc_codec *codec = rtd->codec;
2037 struct snd_soc_codec *codec = socdev->card->codec;
2038 2048
2039 /* Enable voice digital filters */ 2049 /* Enable voice digital filters */
2040 twl4030_voice_enable(codec, substream->stream, 0); 2050 twl4030_voice_enable(codec, substream->stream, 0);
@@ -2044,8 +2054,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2044 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 2054 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2045{ 2055{
2046 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2056 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2047 struct snd_soc_device *socdev = rtd->socdev; 2057 struct snd_soc_codec *codec = rtd->codec;
2048 struct snd_soc_codec *codec = socdev->card->codec;
2049 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2058 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2050 u8 old_mode, mode; 2059 u8 old_mode, mode;
2051 2060
@@ -2173,9 +2182,9 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2173} 2182}
2174 2183
2175#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 2184#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
2176#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 2185#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
2177 2186
2178static struct snd_soc_dai_ops twl4030_dai_ops = { 2187static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
2179 .startup = twl4030_startup, 2188 .startup = twl4030_startup,
2180 .shutdown = twl4030_shutdown, 2189 .shutdown = twl4030_shutdown,
2181 .hw_params = twl4030_hw_params, 2190 .hw_params = twl4030_hw_params,
@@ -2193,9 +2202,9 @@ static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
2193 .set_tristate = twl4030_voice_set_tristate, 2202 .set_tristate = twl4030_voice_set_tristate,
2194}; 2203};
2195 2204
2196struct snd_soc_dai twl4030_dai[] = { 2205static struct snd_soc_dai_driver twl4030_dai[] = {
2197{ 2206{
2198 .name = "twl4030", 2207 .name = "twl4030-hifi",
2199 .playback = { 2208 .playback = {
2200 .stream_name = "HiFi Playback", 2209 .stream_name = "HiFi Playback",
2201 .channels_min = 2, 2210 .channels_min = 2,
@@ -2208,10 +2217,10 @@ struct snd_soc_dai twl4030_dai[] = {
2208 .channels_max = 4, 2217 .channels_max = 4,
2209 .rates = TWL4030_RATES, 2218 .rates = TWL4030_RATES,
2210 .formats = TWL4030_FORMATS,}, 2219 .formats = TWL4030_FORMATS,},
2211 .ops = &twl4030_dai_ops, 2220 .ops = &twl4030_dai_hifi_ops,
2212}, 2221},
2213{ 2222{
2214 .name = "twl4030 Voice", 2223 .name = "twl4030-voice",
2215 .playback = { 2224 .playback = {
2216 .stream_name = "Voice Playback", 2225 .stream_name = "Voice Playback",
2217 .channels_min = 1, 2226 .channels_min = 1,
@@ -2227,164 +2236,91 @@ struct snd_soc_dai twl4030_dai[] = {
2227 .ops = &twl4030_dai_voice_ops, 2236 .ops = &twl4030_dai_voice_ops,
2228}, 2237},
2229}; 2238};
2230EXPORT_SYMBOL_GPL(twl4030_dai);
2231 2239
2232static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state) 2240static int twl4030_soc_suspend(struct snd_soc_codec *codec, pm_message_t state)
2233{ 2241{
2234 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2235 struct snd_soc_codec *codec = socdev->card->codec;
2236
2237 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2242 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2238
2239 return 0; 2243 return 0;
2240} 2244}
2241 2245
2242static int twl4030_soc_resume(struct platform_device *pdev) 2246static int twl4030_soc_resume(struct snd_soc_codec *codec)
2243{ 2247{
2244 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2245 struct snd_soc_codec *codec = socdev->card->codec;
2246
2247 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2248 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2248 return 0; 2249 return 0;
2249} 2250}
2250 2251
2251static struct snd_soc_codec *twl4030_codec; 2252static int twl4030_soc_probe(struct snd_soc_codec *codec)
2252
2253static int twl4030_soc_probe(struct platform_device *pdev)
2254{ 2253{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2254 struct twl4030_priv *twl4030;
2256 struct snd_soc_codec *codec;
2257 int ret;
2258
2259 BUG_ON(!twl4030_codec);
2260
2261 codec = twl4030_codec;
2262 socdev->card->codec = codec;
2263
2264 twl4030_init_chip(pdev);
2265 2255
2266 /* register pcms */ 2256 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2267 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2257 if (twl4030 == NULL) {
2268 if (ret < 0) { 2258 printk("Can not allocate memroy\n");
2269 dev_err(&pdev->dev, "failed to create pcms\n"); 2259 return -ENOMEM;
2270 return ret;
2271 } 2260 }
2261 snd_soc_codec_set_drvdata(codec, twl4030);
2262 /* Set the defaults, and power up the codec */
2263 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2264 codec->dapm.idle_bias_off = 1;
2265
2266 twl4030_init_chip(codec);
2272 2267
2273 snd_soc_add_controls(codec, twl4030_snd_controls, 2268 snd_soc_add_controls(codec, twl4030_snd_controls,
2274 ARRAY_SIZE(twl4030_snd_controls)); 2269 ARRAY_SIZE(twl4030_snd_controls));
2275 twl4030_add_widgets(codec); 2270 twl4030_add_widgets(codec);
2276
2277 return 0; 2271 return 0;
2278} 2272}
2279 2273
2280static int twl4030_soc_remove(struct platform_device *pdev) 2274static int twl4030_soc_remove(struct snd_soc_codec *codec)
2281{ 2275{
2282 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2276 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2283 struct snd_soc_codec *codec = socdev->card->codec;
2284 2277
2285 /* Reset registers to their chip default before leaving */ 2278 /* Reset registers to their chip default before leaving */
2286 twl4030_reset_registers(codec); 2279 twl4030_reset_registers(codec);
2287 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2280 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2288 snd_soc_free_pcms(socdev); 2281 kfree(twl4030);
2289 snd_soc_dapm_free(socdev);
2290
2291 return 0; 2282 return 0;
2292} 2283}
2293 2284
2285static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2286 .probe = twl4030_soc_probe,
2287 .remove = twl4030_soc_remove,
2288 .suspend = twl4030_soc_suspend,
2289 .resume = twl4030_soc_resume,
2290 .read = twl4030_read_reg_cache,
2291 .write = twl4030_write,
2292 .set_bias_level = twl4030_set_bias_level,
2293 .reg_cache_size = sizeof(twl4030_reg),
2294 .reg_word_size = sizeof(u8),
2295 .reg_cache_default = twl4030_reg,
2296};
2297
2294static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2298static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2295{ 2299{
2296 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; 2300 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2297 struct snd_soc_codec *codec;
2298 struct twl4030_priv *twl4030;
2299 int ret;
2300 2301
2301 if (!pdata) { 2302 if (!pdata) {
2302 dev_err(&pdev->dev, "platform_data is missing\n"); 2303 dev_err(&pdev->dev, "platform_data is missing\n");
2303 return -EINVAL; 2304 return -EINVAL;
2304 } 2305 }
2305 2306
2306 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2307 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
2307 if (twl4030 == NULL) { 2308 twl4030_dai, ARRAY_SIZE(twl4030_dai));
2308 dev_err(&pdev->dev, "Can not allocate memroy\n");
2309 return -ENOMEM;
2310 }
2311
2312 codec = &twl4030->codec;
2313 snd_soc_codec_set_drvdata(codec, twl4030);
2314 codec->dev = &pdev->dev;
2315 twl4030_dai[0].dev = &pdev->dev;
2316 twl4030_dai[1].dev = &pdev->dev;
2317
2318 mutex_init(&codec->mutex);
2319 INIT_LIST_HEAD(&codec->dapm_widgets);
2320 INIT_LIST_HEAD(&codec->dapm_paths);
2321
2322 codec->name = "twl4030";
2323 codec->owner = THIS_MODULE;
2324 codec->read = twl4030_read_reg_cache;
2325 codec->write = twl4030_write;
2326 codec->set_bias_level = twl4030_set_bias_level;
2327 codec->idle_bias_off = 1;
2328 codec->dai = twl4030_dai;
2329 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2330 codec->reg_cache_size = sizeof(twl4030_reg);
2331 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2332 GFP_KERNEL);
2333 if (codec->reg_cache == NULL) {
2334 ret = -ENOMEM;
2335 goto error_cache;
2336 }
2337
2338 platform_set_drvdata(pdev, twl4030);
2339 twl4030_codec = codec;
2340
2341 /* Set the defaults, and power up the codec */
2342 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2343 codec->bias_level = SND_SOC_BIAS_OFF;
2344
2345 ret = snd_soc_register_codec(codec);
2346 if (ret != 0) {
2347 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2348 goto error_codec;
2349 }
2350
2351 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2352 if (ret != 0) {
2353 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2354 snd_soc_unregister_codec(codec);
2355 goto error_codec;
2356 }
2357
2358 return 0;
2359
2360error_codec:
2361 twl4030_codec_enable(codec, 0);
2362 kfree(codec->reg_cache);
2363error_cache:
2364 kfree(twl4030);
2365 return ret;
2366} 2309}
2367 2310
2368static int __devexit twl4030_codec_remove(struct platform_device *pdev) 2311static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2369{ 2312{
2370 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev); 2313 snd_soc_unregister_codec(&pdev->dev);
2371
2372 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2373 snd_soc_unregister_codec(&twl4030->codec);
2374 kfree(twl4030->codec.reg_cache);
2375 kfree(twl4030);
2376
2377 twl4030_codec = NULL;
2378 return 0; 2314 return 0;
2379} 2315}
2380 2316
2381MODULE_ALIAS("platform:twl4030_codec_audio"); 2317MODULE_ALIAS("platform:twl4030-codec");
2382 2318
2383static struct platform_driver twl4030_codec_driver = { 2319static struct platform_driver twl4030_codec_driver = {
2384 .probe = twl4030_codec_probe, 2320 .probe = twl4030_codec_probe,
2385 .remove = __devexit_p(twl4030_codec_remove), 2321 .remove = __devexit_p(twl4030_codec_remove),
2386 .driver = { 2322 .driver = {
2387 .name = "twl4030_codec_audio", 2323 .name = "twl4030-codec",
2388 .owner = THIS_MODULE, 2324 .owner = THIS_MODULE,
2389 }, 2325 },
2390}; 2326};
@@ -2401,14 +2337,6 @@ static void __exit twl4030_exit(void)
2401} 2337}
2402module_exit(twl4030_exit); 2338module_exit(twl4030_exit);
2403 2339
2404struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2405 .probe = twl4030_soc_probe,
2406 .remove = twl4030_soc_remove,
2407 .suspend = twl4030_soc_suspend,
2408 .resume = twl4030_soc_resume,
2409};
2410EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2411
2412MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2340MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2413MODULE_AUTHOR("Steve Sakoman"); 2341MODULE_AUTHOR("Steve Sakoman");
2414MODULE_LICENSE("GPL"); 2342MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
deleted file mode 100644
index 6c57430f6e24..000000000000
--- a/sound/soc/codecs/twl4030.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__
24
25/* Register descriptions are here */
26#include <linux/mfd/twl4030-codec.h>
27
28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
31
32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
33#define TWL4030_HFL_EN 0x01
34#define TWL4030_HFR_EN 0x02
35
36#define TWL4030_DAI_HIFI 0
37#define TWL4030_DAI_VOICE 1
38
39extern struct snd_soc_dai twl4030_dai[2];
40extern struct snd_soc_codec_device soc_codec_dev_twl4030;
41
42struct twl4030_setup_data {
43 unsigned int ramp_delay_value;
44 unsigned int digimic_delay; /* in ms */
45 unsigned int sysclk;
46 unsigned int offset_cncl_path;
47 unsigned int check_defaults:1;
48 unsigned int reset_registers:1;
49 unsigned int hs_extmute:1;
50 void (*set_hs_extmute)(int mute);
51};
52
53#endif /* End of __TWL4030_AUDIO_H__ */
54
55
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 64a807f1a8a1..4c336636d4f5 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -34,18 +34,49 @@
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
36#include <sound/soc.h> 36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38#include <sound/initval.h> 37#include <sound/initval.h>
39#include <sound/tlv.h> 38#include <sound/tlv.h>
40 39
41#include "twl6040.h" 40#include "twl6040.h"
42 41
43#define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 42#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
44#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 43#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
44
45#define TWL6040_OUTHS_0dB 0x00
46#define TWL6040_OUTHS_M30dB 0x0F
47#define TWL6040_OUTHF_0dB 0x03
48#define TWL6040_OUTHF_M52dB 0x1D
49
50#define TWL6040_RAMP_NONE 0
51#define TWL6040_RAMP_UP 1
52#define TWL6040_RAMP_DOWN 2
53
54#define TWL6040_HSL_VOL_MASK 0x0F
55#define TWL6040_HSL_VOL_SHIFT 0
56#define TWL6040_HSR_VOL_MASK 0xF0
57#define TWL6040_HSR_VOL_SHIFT 4
58#define TWL6040_HF_VOL_MASK 0x1F
59#define TWL6040_HF_VOL_SHIFT 0
60
61struct twl6040_output {
62 u16 active;
63 u16 left_vol;
64 u16 right_vol;
65 u16 left_step;
66 u16 right_step;
67 unsigned int step_delay;
68 u16 ramp;
69 u16 mute;
70 struct completion ramp_done;
71};
72
73struct twl6040_jack_data {
74 struct snd_soc_jack *jack;
75 int report;
76};
45 77
46/* codec private data */ 78/* codec private data */
47struct twl6040_data { 79struct twl6040_data {
48 struct snd_soc_codec codec;
49 int audpwron; 80 int audpwron;
50 int naudint; 81 int naudint;
51 int codec_powered; 82 int codec_powered;
@@ -54,6 +85,17 @@ struct twl6040_data {
54 unsigned int sysclk; 85 unsigned int sysclk;
55 struct snd_pcm_hw_constraint_list *sysclk_constraints; 86 struct snd_pcm_hw_constraint_list *sysclk_constraints;
56 struct completion ready; 87 struct completion ready;
88 struct twl6040_jack_data hs_jack;
89 struct snd_soc_codec *codec;
90 struct workqueue_struct *workqueue;
91 struct delayed_work delayed_work;
92 struct mutex mutex;
93 struct twl6040_output headset;
94 struct twl6040_output handsfree;
95 struct workqueue_struct *hf_workqueue;
96 struct workqueue_struct *hs_workqueue;
97 struct delayed_work hs_delayed_work;
98 struct delayed_work hf_delayed_work;
57}; 99};
58 100
59/* 101/*
@@ -202,7 +244,7 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
202 if (reg >= TWL6040_CACHEREGNUM) 244 if (reg >= TWL6040_CACHEREGNUM)
203 return -EIO; 245 return -EIO;
204 246
205 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg); 247 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg);
206 twl6040_write_reg_cache(codec, reg, value); 248 twl6040_write_reg_cache(codec, reg, value);
207 249
208 return value; 250 return value;
@@ -218,7 +260,7 @@ static int twl6040_write(struct snd_soc_codec *codec,
218 return -EIO; 260 return -EIO;
219 261
220 twl6040_write_reg_cache(codec, reg, value); 262 twl6040_write_reg_cache(codec, reg, value);
221 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); 263 return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg);
222} 264}
223 265
224static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 266static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
@@ -255,6 +297,305 @@ static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
255 } 297 }
256} 298}
257 299
300/*
301 * Ramp HS PGA volume to minimise pops at stream startup and shutdown.
302 */
303static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
304 unsigned int left_step, unsigned int right_step)
305{
306
307 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
308 struct twl6040_output *headset = &priv->headset;
309 int left_complete = 0, right_complete = 0;
310 u8 reg, val;
311
312 /* left channel */
313 left_step = (left_step > 0xF) ? 0xF : left_step;
314 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
315 val = (~reg & TWL6040_HSL_VOL_MASK);
316
317 if (headset->ramp == TWL6040_RAMP_UP) {
318 /* ramp step up */
319 if (val < headset->left_vol) {
320 val += left_step;
321 reg &= ~TWL6040_HSL_VOL_MASK;
322 twl6040_write(codec, TWL6040_REG_HSGAIN,
323 (reg | (~val & TWL6040_HSL_VOL_MASK)));
324 } else {
325 left_complete = 1;
326 }
327 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
328 /* ramp step down */
329 if (val > 0x0) {
330 val -= left_step;
331 reg &= ~TWL6040_HSL_VOL_MASK;
332 twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
333 (~val & TWL6040_HSL_VOL_MASK));
334 } else {
335 left_complete = 1;
336 }
337 }
338
339 /* right channel */
340 right_step = (right_step > 0xF) ? 0xF : right_step;
341 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
342 val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT;
343
344 if (headset->ramp == TWL6040_RAMP_UP) {
345 /* ramp step up */
346 if (val < headset->right_vol) {
347 val += right_step;
348 reg &= ~TWL6040_HSR_VOL_MASK;
349 twl6040_write(codec, TWL6040_REG_HSGAIN,
350 (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
351 } else {
352 right_complete = 1;
353 }
354 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
355 /* ramp step down */
356 if (val > 0x0) {
357 val -= right_step;
358 reg &= ~TWL6040_HSR_VOL_MASK;
359 twl6040_write(codec, TWL6040_REG_HSGAIN,
360 reg | (~val << TWL6040_HSR_VOL_SHIFT));
361 } else {
362 right_complete = 1;
363 }
364 }
365
366 return left_complete & right_complete;
367}
368
369/*
370 * Ramp HF PGA volume to minimise pops at stream startup and shutdown.
371 */
372static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
373 unsigned int left_step, unsigned int right_step)
374{
375 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
376 struct twl6040_output *handsfree = &priv->handsfree;
377 int left_complete = 0, right_complete = 0;
378 u16 reg, val;
379
380 /* left channel */
381 left_step = (left_step > 0x1D) ? 0x1D : left_step;
382 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN);
383 reg = 0x1D - reg;
384 val = (reg & TWL6040_HF_VOL_MASK);
385 if (handsfree->ramp == TWL6040_RAMP_UP) {
386 /* ramp step up */
387 if (val < handsfree->left_vol) {
388 val += left_step;
389 reg &= ~TWL6040_HF_VOL_MASK;
390 twl6040_write(codec, TWL6040_REG_HFLGAIN,
391 reg | (0x1D - val));
392 } else {
393 left_complete = 1;
394 }
395 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
396 /* ramp step down */
397 if (val > 0) {
398 val -= left_step;
399 reg &= ~TWL6040_HF_VOL_MASK;
400 twl6040_write(codec, TWL6040_REG_HFLGAIN,
401 reg | (0x1D - val));
402 } else {
403 left_complete = 1;
404 }
405 }
406
407 /* right channel */
408 right_step = (right_step > 0x1D) ? 0x1D : right_step;
409 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN);
410 reg = 0x1D - reg;
411 val = (reg & TWL6040_HF_VOL_MASK);
412 if (handsfree->ramp == TWL6040_RAMP_UP) {
413 /* ramp step up */
414 if (val < handsfree->right_vol) {
415 val += right_step;
416 reg &= ~TWL6040_HF_VOL_MASK;
417 twl6040_write(codec, TWL6040_REG_HFRGAIN,
418 reg | (0x1D - val));
419 } else {
420 right_complete = 1;
421 }
422 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
423 /* ramp step down */
424 if (val > 0) {
425 val -= right_step;
426 reg &= ~TWL6040_HF_VOL_MASK;
427 twl6040_write(codec, TWL6040_REG_HFRGAIN,
428 reg | (0x1D - val));
429 }
430 }
431
432 return left_complete & right_complete;
433}
434
435/*
436 * This work ramps both output PGAs at stream start/stop time to
437 * minimise pop associated with DAPM power switching.
438 */
439static void twl6040_pga_hs_work(struct work_struct *work)
440{
441 struct twl6040_data *priv =
442 container_of(work, struct twl6040_data, hs_delayed_work.work);
443 struct snd_soc_codec *codec = priv->codec;
444 struct twl6040_output *headset = &priv->headset;
445 unsigned int delay = headset->step_delay;
446 int i, headset_complete;
447
448 /* do we need to ramp at all ? */
449 if (headset->ramp == TWL6040_RAMP_NONE)
450 return;
451
452 /* HS PGA volumes have 4 bits of resolution to ramp */
453 for (i = 0; i <= 16; i++) {
454 headset_complete = 1;
455 if (headset->ramp != TWL6040_RAMP_NONE)
456 headset_complete = twl6040_hs_ramp_step(codec,
457 headset->left_step,
458 headset->right_step);
459
460 /* ramp finished ? */
461 if (headset_complete)
462 break;
463
464 /*
465 * TODO: tune: delay is longer over 0dB
466 * as increases are larger.
467 */
468 if (i >= 8)
469 schedule_timeout_interruptible(msecs_to_jiffies(delay +
470 (delay >> 1)));
471 else
472 schedule_timeout_interruptible(msecs_to_jiffies(delay));
473 }
474
475 if (headset->ramp == TWL6040_RAMP_DOWN) {
476 headset->active = 0;
477 complete(&headset->ramp_done);
478 } else {
479 headset->active = 1;
480 }
481 headset->ramp = TWL6040_RAMP_NONE;
482}
483
484static void twl6040_pga_hf_work(struct work_struct *work)
485{
486 struct twl6040_data *priv =
487 container_of(work, struct twl6040_data, hf_delayed_work.work);
488 struct snd_soc_codec *codec = priv->codec;
489 struct twl6040_output *handsfree = &priv->handsfree;
490 unsigned int delay = handsfree->step_delay;
491 int i, handsfree_complete;
492
493 /* do we need to ramp at all ? */
494 if (handsfree->ramp == TWL6040_RAMP_NONE)
495 return;
496
497 /* HF PGA volumes have 5 bits of resolution to ramp */
498 for (i = 0; i <= 32; i++) {
499 handsfree_complete = 1;
500 if (handsfree->ramp != TWL6040_RAMP_NONE)
501 handsfree_complete = twl6040_hf_ramp_step(codec,
502 handsfree->left_step,
503 handsfree->right_step);
504
505 /* ramp finished ? */
506 if (handsfree_complete)
507 break;
508
509 /*
510 * TODO: tune: delay is longer over 0dB
511 * as increases are larger.
512 */
513 if (i >= 16)
514 schedule_timeout_interruptible(msecs_to_jiffies(delay +
515 (delay >> 1)));
516 else
517 schedule_timeout_interruptible(msecs_to_jiffies(delay));
518 }
519
520
521 if (handsfree->ramp == TWL6040_RAMP_DOWN) {
522 handsfree->active = 0;
523 complete(&handsfree->ramp_done);
524 } else
525 handsfree->active = 1;
526 handsfree->ramp = TWL6040_RAMP_NONE;
527}
528
529static int pga_event(struct snd_soc_dapm_widget *w,
530 struct snd_kcontrol *kcontrol, int event)
531{
532 struct snd_soc_codec *codec = w->codec;
533 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
534 struct twl6040_output *out;
535 struct delayed_work *work;
536 struct workqueue_struct *queue;
537
538 switch (w->shift) {
539 case 2:
540 case 3:
541 out = &priv->headset;
542 work = &priv->hs_delayed_work;
543 queue = priv->hs_workqueue;
544 out->step_delay = 5; /* 5 ms between volume ramp steps */
545 break;
546 case 4:
547 out = &priv->handsfree;
548 work = &priv->hf_delayed_work;
549 queue = priv->hf_workqueue;
550 out->step_delay = 5; /* 5 ms between volume ramp steps */
551 if (SND_SOC_DAPM_EVENT_ON(event))
552 priv->non_lp++;
553 else
554 priv->non_lp--;
555 break;
556 default:
557 return -1;
558 }
559
560 switch (event) {
561 case SND_SOC_DAPM_POST_PMU:
562 if (out->active)
563 break;
564
565 /* don't use volume ramp for power-up */
566 out->left_step = out->left_vol;
567 out->right_step = out->right_vol;
568
569 if (!delayed_work_pending(work)) {
570 out->ramp = TWL6040_RAMP_UP;
571 queue_delayed_work(queue, work,
572 msecs_to_jiffies(1));
573 }
574 break;
575
576 case SND_SOC_DAPM_PRE_PMD:
577 if (!out->active)
578 break;
579
580 if (!delayed_work_pending(work)) {
581 /* use volume ramp for power-down */
582 out->left_step = 1;
583 out->right_step = 1;
584 out->ramp = TWL6040_RAMP_DOWN;
585 INIT_COMPLETION(out->ramp_done);
586
587 queue_delayed_work(queue, work,
588 msecs_to_jiffies(1));
589
590 wait_for_completion_timeout(&out->ramp_done,
591 msecs_to_jiffies(2000));
592 }
593 break;
594 }
595
596 return 0;
597}
598
258/* twl6040 codec manual power-up sequence */ 599/* twl6040 codec manual power-up sequence */
259static void twl6040_power_up(struct snd_soc_codec *codec) 600static void twl6040_power_up(struct snd_soc_codec *codec)
260{ 601{
@@ -383,6 +724,47 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
383 return 0; 724 return 0;
384} 725}
385 726
727static void twl6040_hs_jack_report(struct snd_soc_codec *codec,
728 struct snd_soc_jack *jack, int report)
729{
730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
731 int status;
732
733 mutex_lock(&priv->mutex);
734
735 /* Sync status */
736 status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS);
737 if (status & TWL6040_PLUGCOMP)
738 snd_soc_jack_report(jack, report, report);
739 else
740 snd_soc_jack_report(jack, 0, report);
741
742 mutex_unlock(&priv->mutex);
743}
744
745void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
746 struct snd_soc_jack *jack, int report)
747{
748 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
749 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
750
751 hs_jack->jack = jack;
752 hs_jack->report = report;
753
754 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
755}
756EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
757
758static void twl6040_accessory_work(struct work_struct *work)
759{
760 struct twl6040_data *priv = container_of(work,
761 struct twl6040_data, delayed_work.work);
762 struct snd_soc_codec *codec = priv->codec;
763 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
764
765 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
766}
767
386/* audio interrupt handler */ 768/* audio interrupt handler */
387static irqreturn_t twl6040_naudint_handler(int irq, void *data) 769static irqreturn_t twl6040_naudint_handler(int irq, void *data)
388{ 770{
@@ -390,33 +772,180 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data)
390 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 772 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
391 u8 intid; 773 u8 intid;
392 774
393 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); 775 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
394 776
395 switch (intid) { 777 if (intid & TWL6040_THINT)
396 case TWL6040_THINT:
397 dev_alert(codec->dev, "die temp over-limit detection\n"); 778 dev_alert(codec->dev, "die temp over-limit detection\n");
779
780 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT))
781 queue_delayed_work(priv->workqueue, &priv->delayed_work,
782 msecs_to_jiffies(200));
783
784 if (intid & TWL6040_HOOKINT)
785 dev_info(codec->dev, "hook detection\n");
786
787 if (intid & TWL6040_HFINT)
788 dev_alert(codec->dev, "hf drivers over current detection\n");
789
790 if (intid & TWL6040_VIBINT)
791 dev_alert(codec->dev, "vib drivers over current detection\n");
792
793 if (intid & TWL6040_READYINT)
794 complete(&priv->ready);
795
796 return IRQ_HANDLED;
797}
798
799static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
800 struct snd_ctl_elem_value *ucontrol)
801{
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
804 struct twl6040_output *out = NULL;
805 struct soc_mixer_control *mc =
806 (struct soc_mixer_control *)kcontrol->private_value;
807 int ret;
808 unsigned int reg = mc->reg;
809
810 /* For HS and HF we shadow the values and only actually write
811 * them out when active in order to ensure the amplifier comes on
812 * as quietly as possible. */
813 switch (reg) {
814 case TWL6040_REG_HSGAIN:
815 out = &twl6040_priv->headset;
398 break; 816 break;
399 case TWL6040_PLUGINT: 817 default:
400 case TWL6040_UNPLUGINT:
401 case TWL6040_HOOKINT:
402 break; 818 break;
403 case TWL6040_HFINT: 819 }
404 dev_alert(codec->dev, "hf drivers over current detection\n"); 820
821 if (out) {
822 out->left_vol = ucontrol->value.integer.value[0];
823 out->right_vol = ucontrol->value.integer.value[1];
824 if (!out->active)
825 return 1;
826 }
827
828 ret = snd_soc_put_volsw(kcontrol, ucontrol);
829 if (ret < 0)
830 return ret;
831
832 return 1;
833}
834
835static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
836 struct snd_ctl_elem_value *ucontrol)
837{
838 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
839 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
840 struct twl6040_output *out = &twl6040_priv->headset;
841 struct soc_mixer_control *mc =
842 (struct soc_mixer_control *)kcontrol->private_value;
843 unsigned int reg = mc->reg;
844
845 switch (reg) {
846 case TWL6040_REG_HSGAIN:
847 out = &twl6040_priv->headset;
848 ucontrol->value.integer.value[0] = out->left_vol;
849 ucontrol->value.integer.value[1] = out->right_vol;
850 return 0;
851
852 default:
405 break; 853 break;
406 case TWL6040_VIBINT: 854 }
407 dev_alert(codec->dev, "vib drivers over current detection\n"); 855
856 return snd_soc_get_volsw(kcontrol, ucontrol);
857}
858
859static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
860 struct snd_ctl_elem_value *ucontrol)
861{
862 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
863 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
864 struct twl6040_output *out = NULL;
865 struct soc_mixer_control *mc =
866 (struct soc_mixer_control *)kcontrol->private_value;
867 int ret;
868 unsigned int reg = mc->reg;
869
870 /* For HS and HF we shadow the values and only actually write
871 * them out when active in order to ensure the amplifier comes on
872 * as quietly as possible. */
873 switch (reg) {
874 case TWL6040_REG_HFLGAIN:
875 case TWL6040_REG_HFRGAIN:
876 out = &twl6040_priv->handsfree;
408 break; 877 break;
409 case TWL6040_READYINT: 878 default:
410 complete(&priv->ready);
411 break; 879 break;
880 }
881
882 if (out) {
883 out->left_vol = ucontrol->value.integer.value[0];
884 out->right_vol = ucontrol->value.integer.value[1];
885 if (!out->active)
886 return 1;
887 }
888
889 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
890 if (ret < 0)
891 return ret;
892
893 return 1;
894}
895
896static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol,
897 struct snd_ctl_elem_value *ucontrol)
898{
899 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
900 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
901 struct twl6040_output *out = &twl6040_priv->handsfree;
902 struct soc_mixer_control *mc =
903 (struct soc_mixer_control *)kcontrol->private_value;
904 unsigned int reg = mc->reg;
905
906 /* If these are cached registers use the cache */
907 switch (reg) {
908 case TWL6040_REG_HFLGAIN:
909 case TWL6040_REG_HFRGAIN:
910 out = &twl6040_priv->handsfree;
911 ucontrol->value.integer.value[0] = out->left_vol;
912 ucontrol->value.integer.value[1] = out->right_vol;
913 return 0;
914
412 default: 915 default:
413 dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
414 break; 916 break;
415 } 917 }
416 918
417 return IRQ_HANDLED; 919 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
418} 920}
419 921
922/* double control with volume update */
923#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\
924 xinvert, tlv_array)\
925{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
926 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
927 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
928 .tlv.p = (tlv_array), \
929 .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \
930 .put = twl6040_put_volsw, \
931 .private_value = (unsigned long)&(struct soc_mixer_control) \
932 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
933 .max = xmax, .platform_max = xmax, .invert = xinvert} }
934
935/* double control with volume update */
936#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\
937 xinvert, tlv_array)\
938{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
939 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
940 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
941 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
942 .tlv.p = (tlv_array), \
943 .info = snd_soc_info_volsw_2r, \
944 .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \
945 .private_value = (unsigned long)&(struct soc_mixer_control) \
946 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
947 .rshift = xshift, .max = xmax, .invert = xinvert}, }
948
420/* 949/*
421 * MICATT volume control: 950 * MICATT volume control:
422 * from -6 to 0 dB in 6 dB steps 951 * from -6 to 0 dB in 6 dB steps
@@ -425,9 +954,15 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
425 954
426/* 955/*
427 * MICGAIN volume control: 956 * MICGAIN volume control:
428 * from 6 to 30 dB in 6 dB steps 957 * from -6 to 30 dB in 6 dB steps
958 */
959static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
960
961/*
962 * AFMGAIN volume control:
963 * from -18 to 24 dB in 6 dB steps
429 */ 964 */
430static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0); 965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, -1800, 600, 0);
431 966
432/* 967/*
433 * HSGAIN volume control: 968 * HSGAIN volume control:
@@ -456,8 +991,30 @@ static const char *twl6040_amicr_texts[] =
456 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; 991 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
457 992
458static const struct soc_enum twl6040_enum[] = { 993static const struct soc_enum twl6040_enum[] = {
459 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts), 994 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts),
460 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts), 995 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts),
996};
997
998static const char *twl6040_hs_texts[] = {
999 "Off", "HS DAC", "Line-In amp"
1000};
1001
1002static const struct soc_enum twl6040_hs_enum[] = {
1003 SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
1004 twl6040_hs_texts),
1005 SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
1006 twl6040_hs_texts),
1007};
1008
1009static const char *twl6040_hf_texts[] = {
1010 "Off", "HF DAC", "Line-In amp"
1011};
1012
1013static const struct soc_enum twl6040_hf_enum[] = {
1014 SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
1015 twl6040_hf_texts),
1016 SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
1017 twl6040_hf_texts),
461}; 1018};
462 1019
463static const struct snd_kcontrol_new amicl_control = 1020static const struct snd_kcontrol_new amicl_control =
@@ -467,18 +1024,18 @@ static const struct snd_kcontrol_new amicr_control =
467 SOC_DAPM_ENUM("Route", twl6040_enum[1]); 1024 SOC_DAPM_ENUM("Route", twl6040_enum[1]);
468 1025
469/* Headset DAC playback switches */ 1026/* Headset DAC playback switches */
470static const struct snd_kcontrol_new hsdacl_switch_controls = 1027static const struct snd_kcontrol_new hsl_mux_controls =
471 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0); 1028 SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
472 1029
473static const struct snd_kcontrol_new hsdacr_switch_controls = 1030static const struct snd_kcontrol_new hsr_mux_controls =
474 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0); 1031 SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
475 1032
476/* Handsfree DAC playback switches */ 1033/* Handsfree DAC playback switches */
477static const struct snd_kcontrol_new hfdacl_switch_controls = 1034static const struct snd_kcontrol_new hfl_mux_controls =
478 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0); 1035 SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
479 1036
480static const struct snd_kcontrol_new hfdacr_switch_controls = 1037static const struct snd_kcontrol_new hfr_mux_controls =
481 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0); 1038 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
482 1039
483static const struct snd_kcontrol_new ep_driver_switch_controls = 1040static const struct snd_kcontrol_new ep_driver_switch_controls =
484 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 1041 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
@@ -490,10 +1047,14 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
490 SOC_DOUBLE_TLV("Capture Volume", 1047 SOC_DOUBLE_TLV("Capture Volume",
491 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv), 1048 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
492 1049
1050 /* AFM gains */
1051 SOC_DOUBLE_TLV("Aux FM Volume",
1052 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1053
493 /* Playback gains */ 1054 /* Playback gains */
494 SOC_DOUBLE_TLV("Headset Playback Volume", 1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume",
495 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), 1056 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
496 SOC_DOUBLE_R_TLV("Handsfree Playback Volume", 1057 SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume",
497 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 1058 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
498 SOC_SINGLE_TLV("Earphone Playback Volume", 1059 SOC_SINGLE_TLV("Earphone Playback Volume",
499 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 1060 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
@@ -526,6 +1087,12 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
526 SND_SOC_DAPM_PGA("MicAmpR", 1087 SND_SOC_DAPM_PGA("MicAmpR",
527 TWL6040_REG_MICRCTL, 0, 0, NULL, 0), 1088 TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
528 1089
1090 /* Auxiliary FM PGAs */
1091 SND_SOC_DAPM_PGA("AFMAmpL",
1092 TWL6040_REG_MICLCTL, 1, 0, NULL, 0),
1093 SND_SOC_DAPM_PGA("AFMAmpR",
1094 TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
1095
529 /* ADCs */ 1096 /* ADCs */
530 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture", 1097 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
531 TWL6040_REG_MICLCTL, 2, 0), 1098 TWL6040_REG_MICLCTL, 2, 0),
@@ -560,29 +1127,33 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
560 twl6040_power_mode_event, 1127 twl6040_power_mode_event,
561 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1128 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
562 1129
563 /* Analog playback switches */ 1130 SND_SOC_DAPM_MUX("HF Left Playback",
564 SND_SOC_DAPM_SWITCH("HSDAC Left Playback", 1131 SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
565 SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls), 1132 SND_SOC_DAPM_MUX("HF Right Playback",
566 SND_SOC_DAPM_SWITCH("HSDAC Right Playback", 1133 SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
567 SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls), 1134 /* Analog playback Muxes */
568 SND_SOC_DAPM_SWITCH("HFDAC Left Playback", 1135 SND_SOC_DAPM_MUX("HS Left Playback",
569 SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls), 1136 SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
570 SND_SOC_DAPM_SWITCH("HFDAC Right Playback", 1137 SND_SOC_DAPM_MUX("HS Right Playback",
571 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls), 1138 SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
572 1139
573 /* Analog playback drivers */ 1140 /* Analog playback drivers */
574 SND_SOC_DAPM_PGA_E("Handsfree Left Driver", 1141 SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver",
575 TWL6040_REG_HFLCTL, 4, 0, NULL, 0, 1142 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
576 twl6040_power_mode_event, 1143 pga_event,
577 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1144 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
578 SND_SOC_DAPM_PGA_E("Handsfree Right Driver", 1145 SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver",
579 TWL6040_REG_HFRCTL, 4, 0, NULL, 0, 1146 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
580 twl6040_power_mode_event, 1147 pga_event,
581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1148 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
582 SND_SOC_DAPM_PGA("Headset Left Driver", 1149 SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver",
583 TWL6040_REG_HSLCTL, 2, 0, NULL, 0), 1150 TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
584 SND_SOC_DAPM_PGA("Headset Right Driver", 1151 pga_event,
585 TWL6040_REG_HSRCTL, 2, 0, NULL, 0), 1152 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1153 SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver",
1154 TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
1155 pga_event,
1156 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
586 SND_SOC_DAPM_SWITCH_E("Earphone Driver", 1157 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, 1158 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
588 twl6040_power_mode_event, 1159 twl6040_power_mode_event,
@@ -612,12 +1183,18 @@ static const struct snd_soc_dapm_route intercon[] = {
612 {"ADC Left", NULL, "MicAmpL"}, 1183 {"ADC Left", NULL, "MicAmpL"},
613 {"ADC Right", NULL, "MicAmpR"}, 1184 {"ADC Right", NULL, "MicAmpR"},
614 1185
615 /* Headset playback path */ 1186 /* AFM path */
616 {"HSDAC Left Playback", "Switch", "HSDAC Left"}, 1187 {"AFMAmpL", "NULL", "AFML"},
617 {"HSDAC Right Playback", "Switch", "HSDAC Right"}, 1188 {"AFMAmpR", "NULL", "AFMR"},
1189
1190 {"HS Left Playback", "HS DAC", "HSDAC Left"},
1191 {"HS Left Playback", "Line-In amp", "AFMAmpL"},
1192
1193 {"HS Right Playback", "HS DAC", "HSDAC Right"},
1194 {"HS Right Playback", "Line-In amp", "AFMAmpR"},
618 1195
619 {"Headset Left Driver", NULL, "HSDAC Left Playback"}, 1196 {"Headset Left Driver", "NULL", "HS Left Playback"},
620 {"Headset Right Driver", NULL, "HSDAC Right Playback"}, 1197 {"Headset Right Driver", "NULL", "HS Right Playback"},
621 1198
622 {"HSOL", NULL, "Headset Left Driver"}, 1199 {"HSOL", NULL, "Headset Left Driver"},
623 {"HSOR", NULL, "Headset Right Driver"}, 1200 {"HSOR", NULL, "Headset Right Driver"},
@@ -626,12 +1203,14 @@ static const struct snd_soc_dapm_route intercon[] = {
626 {"Earphone Driver", "Switch", "HSDAC Left"}, 1203 {"Earphone Driver", "Switch", "HSDAC Left"},
627 {"EP", NULL, "Earphone Driver"}, 1204 {"EP", NULL, "Earphone Driver"},
628 1205
629 /* Handsfree playback path */ 1206 {"HF Left Playback", "HF DAC", "HFDAC Left"},
630 {"HFDAC Left Playback", "Switch", "HFDAC Left"}, 1207 {"HF Left Playback", "Line-In amp", "AFMAmpL"},
631 {"HFDAC Right Playback", "Switch", "HFDAC Right"},
632 1208
633 {"HFDAC Left PGA", NULL, "HFDAC Left Playback"}, 1209 {"HF Right Playback", "HF DAC", "HFDAC Right"},
634 {"HFDAC Right PGA", NULL, "HFDAC Right Playback"}, 1210 {"HF Right Playback", "Line-In amp", "AFMAmpR"},
1211
1212 {"HFDAC Left PGA", NULL, "HF Left Playback"},
1213 {"HFDAC Right PGA", NULL, "HF Right Playback"},
635 1214
636 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, 1215 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
637 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, 1216 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
@@ -642,12 +1221,12 @@ static const struct snd_soc_dapm_route intercon[] = {
642 1221
643static int twl6040_add_widgets(struct snd_soc_codec *codec) 1222static int twl6040_add_widgets(struct snd_soc_codec *codec)
644{ 1223{
645 snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets, 1224 struct snd_soc_dapm_context *dapm = &codec->dapm;
646 ARRAY_SIZE(twl6040_dapm_widgets));
647
648 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
649 1225
650 snd_soc_dapm_new_widgets(codec); 1226 snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets,
1227 ARRAY_SIZE(twl6040_dapm_widgets));
1228 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1229 snd_soc_dapm_new_widgets(dapm);
651 1230
652 return 0; 1231 return 0;
653} 1232}
@@ -660,10 +1239,10 @@ static int twl6040_power_up_completion(struct snd_soc_codec *codec,
660 u8 intid; 1239 u8 intid;
661 1240
662 time_left = wait_for_completion_timeout(&priv->ready, 1241 time_left = wait_for_completion_timeout(&priv->ready,
663 msecs_to_jiffies(48)); 1242 msecs_to_jiffies(144));
664 1243
665 if (!time_left) { 1244 if (!time_left) {
666 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, 1245 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid,
667 TWL6040_REG_INTID); 1246 TWL6040_REG_INTID);
668 if (!(intid & TWL6040_READYINT)) { 1247 if (!(intid & TWL6040_READYINT)) {
669 dev_err(codec->dev, "timeout waiting for READYINT\n"); 1248 dev_err(codec->dev, "timeout waiting for READYINT\n");
@@ -714,6 +1293,15 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
714 1293
715 /* initialize vdd/vss registers with reg_cache */ 1294 /* initialize vdd/vss registers with reg_cache */
716 twl6040_init_vdd_regs(codec); 1295 twl6040_init_vdd_regs(codec);
1296
1297 /* Set external boost GPO */
1298 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
1299
1300 /* Set initial minimal gain values */
1301 twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF);
1302 twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E);
1303 twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D);
1304 twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D);
717 break; 1305 break;
718 case SND_SOC_BIAS_OFF: 1306 case SND_SOC_BIAS_OFF:
719 if (!priv->codec_powered) 1307 if (!priv->codec_powered)
@@ -740,7 +1328,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
740 break; 1328 break;
741 } 1329 }
742 1330
743 codec->bias_level = level; 1331 codec->dapm.bias_level = level;
744 1332
745 return 0; 1333 return 0;
746} 1334}
@@ -770,27 +1358,9 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
770 struct snd_soc_dai *dai) 1358 struct snd_soc_dai *dai)
771{ 1359{
772 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1360 struct snd_soc_pcm_runtime *rtd = substream->private_data;
773 struct snd_soc_device *socdev = rtd->socdev; 1361 struct snd_soc_codec *codec = rtd->codec;
774 struct snd_soc_codec *codec = socdev->card->codec;
775 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1362 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
776 1363
777 if (!priv->sysclk) {
778 dev_err(codec->dev,
779 "no mclk configured, call set_sysclk() on init\n");
780 return -EINVAL;
781 }
782
783 /*
784 * capture is not supported at 17.64 MHz,
785 * it's reserved for headset low-power playback scenario
786 */
787 if ((priv->sysclk == 17640000) && substream->stream) {
788 dev_err(codec->dev,
789 "capture mode is not supported at %dHz\n",
790 priv->sysclk);
791 return -EINVAL;
792 }
793
794 snd_pcm_hw_constraint_list(substream->runtime, 0, 1364 snd_pcm_hw_constraint_list(substream->runtime, 0,
795 SNDRV_PCM_HW_PARAM_RATE, 1365 SNDRV_PCM_HW_PARAM_RATE,
796 priv->sysclk_constraints); 1366 priv->sysclk_constraints);
@@ -803,8 +1373,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
803 struct snd_soc_dai *dai) 1373 struct snd_soc_dai *dai)
804{ 1374{
805 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1375 struct snd_soc_pcm_runtime *rtd = substream->private_data;
806 struct snd_soc_device *socdev = rtd->socdev; 1376 struct snd_soc_codec *codec = rtd->codec;
807 struct snd_soc_codec *codec = socdev->card->codec;
808 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1377 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
809 u8 lppllctl; 1378 u8 lppllctl;
810 int rate; 1379 int rate;
@@ -817,10 +1386,17 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
817 1386
818 rate = params_rate(params); 1387 rate = params_rate(params);
819 switch (rate) { 1388 switch (rate) {
1389 case 11250:
1390 case 22500:
1391 case 44100:
820 case 88200: 1392 case 88200:
821 lppllctl |= TWL6040_LPLLFIN; 1393 lppllctl |= TWL6040_LPLLFIN;
822 priv->sysclk = 17640000; 1394 priv->sysclk = 17640000;
823 break; 1395 break;
1396 case 8000:
1397 case 16000:
1398 case 32000:
1399 case 48000:
824 case 96000: 1400 case 96000:
825 lppllctl &= ~TWL6040_LPLLFIN; 1401 lppllctl &= ~TWL6040_LPLLFIN;
826 priv->sysclk = 19200000; 1402 priv->sysclk = 19200000;
@@ -835,32 +1411,37 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
835 return 0; 1411 return 0;
836} 1412}
837 1413
838static int twl6040_trigger(struct snd_pcm_substream *substream, 1414static int twl6040_prepare(struct snd_pcm_substream *substream,
839 int cmd, struct snd_soc_dai *dai) 1415 struct snd_soc_dai *dai)
840{ 1416{
841 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1417 struct snd_soc_pcm_runtime *rtd = substream->private_data;
842 struct snd_soc_device *socdev = rtd->socdev; 1418 struct snd_soc_codec *codec = rtd->codec;
843 struct snd_soc_codec *codec = socdev->card->codec;
844 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1419 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
845 1420
846 switch (cmd) { 1421 if (!priv->sysclk) {
847 case SNDRV_PCM_TRIGGER_START: 1422 dev_err(codec->dev,
848 case SNDRV_PCM_TRIGGER_RESUME: 1423 "no mclk configured, call set_sysclk() on init\n");
849 /* 1424 return -EINVAL;
850 * low-power playback mode is restricted 1425 }
851 * for headset path only 1426
852 */ 1427 /*
853 if ((priv->sysclk == 17640000) && priv->non_lp) { 1428 * capture is not supported at 17.64 MHz,
1429 * it's reserved for headset low-power playback scenario
1430 */
1431 if ((priv->sysclk == 17640000) &&
1432 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1433 dev_err(codec->dev,
1434 "capture mode is not supported at %dHz\n",
1435 priv->sysclk);
1436 return -EINVAL;
1437 }
1438
1439 if ((priv->sysclk == 17640000) && priv->non_lp) {
854 dev_err(codec->dev, 1440 dev_err(codec->dev,
855 "some enabled paths aren't supported at %dHz\n", 1441 "some enabled paths aren't supported at %dHz\n",
856 priv->sysclk); 1442 priv->sysclk);
857 return -EPERM; 1443 return -EPERM;
858 }
859 break;
860 default:
861 break;
862 } 1444 }
863
864 return 0; 1445 return 0;
865} 1446}
866 1447
@@ -974,12 +1555,12 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
974static struct snd_soc_dai_ops twl6040_dai_ops = { 1555static struct snd_soc_dai_ops twl6040_dai_ops = {
975 .startup = twl6040_startup, 1556 .startup = twl6040_startup,
976 .hw_params = twl6040_hw_params, 1557 .hw_params = twl6040_hw_params,
977 .trigger = twl6040_trigger, 1558 .prepare = twl6040_prepare,
978 .set_sysclk = twl6040_set_dai_sysclk, 1559 .set_sysclk = twl6040_set_dai_sysclk,
979}; 1560};
980 1561
981struct snd_soc_dai twl6040_dai = { 1562static struct snd_soc_dai_driver twl6040_dai = {
982 .name = "twl6040", 1563 .name = "twl6040-hifi",
983 .playback = { 1564 .playback = {
984 .stream_name = "Playback", 1565 .stream_name = "Playback",
985 .channels_min = 1, 1566 .channels_min = 1,
@@ -996,25 +1577,19 @@ struct snd_soc_dai twl6040_dai = {
996 }, 1577 },
997 .ops = &twl6040_dai_ops, 1578 .ops = &twl6040_dai_ops,
998}; 1579};
999EXPORT_SYMBOL_GPL(twl6040_dai);
1000 1580
1001#ifdef CONFIG_PM 1581#ifdef CONFIG_PM
1002static int twl6040_suspend(struct platform_device *pdev, pm_message_t state) 1582static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
1003{ 1583{
1004 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1005 struct snd_soc_codec *codec = socdev->card->codec;
1006
1007 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); 1584 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1008 1585
1009 return 0; 1586 return 0;
1010} 1587}
1011 1588
1012static int twl6040_resume(struct platform_device *pdev) 1589static int twl6040_resume(struct snd_soc_codec *codec)
1013{ 1590{
1014 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1015 struct snd_soc_codec *codec = socdev->card->codec;
1016
1017 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1591 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1592 twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);
1018 1593
1019 return 0; 1594 return 0;
1020} 1595}
@@ -1023,111 +1598,49 @@ static int twl6040_resume(struct platform_device *pdev)
1023#define twl6040_resume NULL 1598#define twl6040_resume NULL
1024#endif 1599#endif
1025 1600
1026static struct snd_soc_codec *twl6040_codec; 1601static int twl6040_probe(struct snd_soc_codec *codec)
1027
1028static int twl6040_probe(struct platform_device *pdev)
1029{ 1602{
1030 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1603 struct twl4030_codec_data *twl_codec = codec->dev->platform_data;
1031 struct snd_soc_codec *codec;
1032 int ret = 0;
1033
1034 BUG_ON(!twl6040_codec);
1035
1036 codec = twl6040_codec;
1037 socdev->card->codec = codec;
1038
1039 /* register pcms */
1040 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1041 if (ret < 0) {
1042 dev_err(&pdev->dev, "failed to create pcms\n");
1043 return ret;
1044 }
1045
1046 snd_soc_add_controls(codec, twl6040_snd_controls,
1047 ARRAY_SIZE(twl6040_snd_controls));
1048 twl6040_add_widgets(codec);
1049
1050 if (ret < 0) {
1051 dev_err(&pdev->dev, "failed to register card\n");
1052 goto card_err;
1053 }
1054
1055 return ret;
1056
1057card_err:
1058 snd_soc_free_pcms(socdev);
1059 snd_soc_dapm_free(socdev);
1060 return ret;
1061}
1062
1063static int twl6040_remove(struct platform_device *pdev)
1064{
1065 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1066 struct snd_soc_codec *codec = socdev->card->codec;
1067
1068 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1069 snd_soc_free_pcms(socdev);
1070 snd_soc_dapm_free(socdev);
1071 kfree(codec);
1072
1073 return 0;
1074}
1075
1076struct snd_soc_codec_device soc_codec_dev_twl6040 = {
1077 .probe = twl6040_probe,
1078 .remove = twl6040_remove,
1079 .suspend = twl6040_suspend,
1080 .resume = twl6040_resume,
1081};
1082EXPORT_SYMBOL_GPL(soc_codec_dev_twl6040);
1083
1084static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1085{
1086 struct twl4030_codec_data *twl_codec = pdev->dev.platform_data;
1087 struct snd_soc_codec *codec;
1088 struct twl6040_data *priv; 1604 struct twl6040_data *priv;
1089 int audpwron, naudint; 1605 int audpwron, naudint;
1090 int ret = 0; 1606 int ret = 0;
1607 u8 icrev, intmr = TWL6040_ALLINT_MSK;
1091 1608
1092 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); 1609 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1093 if (priv == NULL) 1610 if (priv == NULL)
1094 return -ENOMEM; 1611 return -ENOMEM;
1612 snd_soc_codec_set_drvdata(codec, priv);
1095 1613
1096 if (twl_codec) { 1614 priv->codec = codec;
1615
1616 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV);
1617
1618 if (twl_codec && (icrev > 0))
1097 audpwron = twl_codec->audpwron_gpio; 1619 audpwron = twl_codec->audpwron_gpio;
1098 naudint = twl_codec->naudint_irq; 1620 else
1099 } else {
1100 audpwron = -EINVAL; 1621 audpwron = -EINVAL;
1622
1623 if (twl_codec)
1624 naudint = twl_codec->naudint_irq;
1625 else
1101 naudint = 0; 1626 naudint = 0;
1102 }
1103 1627
1104 priv->audpwron = audpwron; 1628 priv->audpwron = audpwron;
1105 priv->naudint = naudint; 1629 priv->naudint = naudint;
1630 priv->workqueue = create_singlethread_workqueue("twl6040-codec");
1106 1631
1107 codec = &priv->codec; 1632 if (!priv->workqueue) {
1108 codec->dev = &pdev->dev;
1109 twl6040_dai.dev = &pdev->dev;
1110
1111 codec->name = "twl6040";
1112 codec->owner = THIS_MODULE;
1113 codec->read = twl6040_read_reg_cache;
1114 codec->write = twl6040_write;
1115 codec->set_bias_level = twl6040_set_bias_level;
1116 snd_soc_codec_set_drvdata(codec, priv);
1117 codec->dai = &twl6040_dai;
1118 codec->num_dai = 1;
1119 codec->reg_cache_size = ARRAY_SIZE(twl6040_reg);
1120 codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg),
1121 GFP_KERNEL);
1122 if (codec->reg_cache == NULL) {
1123 ret = -ENOMEM; 1633 ret = -ENOMEM;
1124 goto cache_err; 1634 goto work_err;
1125 } 1635 }
1126 1636
1127 mutex_init(&codec->mutex); 1637 INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work);
1128 INIT_LIST_HEAD(&codec->dapm_widgets); 1638
1129 INIT_LIST_HEAD(&codec->dapm_paths); 1639 mutex_init(&priv->mutex);
1640
1130 init_completion(&priv->ready); 1641 init_completion(&priv->ready);
1642 init_completion(&priv->headset.ramp_done);
1643 init_completion(&priv->handsfree.ramp_done);
1131 1644
1132 if (gpio_is_valid(audpwron)) { 1645 if (gpio_is_valid(audpwron)) {
1133 ret = gpio_request(audpwron, "audpwron"); 1646 ret = gpio_request(audpwron, "audpwron");
@@ -1139,7 +1652,14 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1139 goto gpio2_err; 1652 goto gpio2_err;
1140 1653
1141 priv->codec_powered = 0; 1654 priv->codec_powered = 0;
1655
1656 /* enable only codec ready interrupt */
1657 intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK);
1658
1659 /* reset interrupt status to allow correct power up sequence */
1660 twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
1142 } 1661 }
1662 twl6040_write(codec, TWL6040_REG_INTMR, intmr);
1143 1663
1144 if (naudint) { 1664 if (naudint) {
1145 /* audio interrupt */ 1665 /* audio interrupt */
@@ -1149,43 +1669,40 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1149 "twl6040_codec", codec); 1669 "twl6040_codec", codec);
1150 if (ret) 1670 if (ret)
1151 goto gpio2_err; 1671 goto gpio2_err;
1152 } else {
1153 if (gpio_is_valid(audpwron)) {
1154 /* enable only codec ready interrupt */
1155 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1156 ~TWL6040_READYMSK & TWL6040_ALLINT_MSK);
1157 } else {
1158 /* no interrupts at all */
1159 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1160 TWL6040_ALLINT_MSK);
1161 }
1162 } 1672 }
1163 1673
1164 /* init vio registers */ 1674 /* init vio registers */
1165 twl6040_init_vio_regs(codec); 1675 twl6040_init_vio_regs(codec);
1166 1676
1167 /* power on device */ 1677 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
1168 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1678 if (priv->hf_workqueue == NULL) {
1169 if (ret) 1679 ret = -ENOMEM;
1170 goto irq_err; 1680 goto irq_err;
1681 }
1682 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
1683 if (priv->hs_workqueue == NULL) {
1684 ret = -ENOMEM;
1685 goto wq_err;
1686 }
1171 1687
1172 ret = snd_soc_register_codec(codec); 1688 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
1173 if (ret) 1689 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
1174 goto reg_err;
1175
1176 twl6040_codec = codec;
1177 1690
1178 ret = snd_soc_register_dai(&twl6040_dai); 1691 /* power on device */
1692 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1179 if (ret) 1693 if (ret)
1180 goto dai_err; 1694 goto bias_err;
1695
1696 snd_soc_add_controls(codec, twl6040_snd_controls,
1697 ARRAY_SIZE(twl6040_snd_controls));
1698 twl6040_add_widgets(codec);
1181 1699
1182 return 0; 1700 return 0;
1183 1701
1184dai_err: 1702bias_err:
1185 snd_soc_unregister_codec(codec); 1703 destroy_workqueue(priv->hs_workqueue);
1186 twl6040_codec = NULL; 1704wq_err:
1187reg_err: 1705 destroy_workqueue(priv->hf_workqueue);
1188 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1189irq_err: 1706irq_err:
1190 if (naudint) 1707 if (naudint)
1191 free_irq(naudint, codec); 1708 free_irq(naudint, codec);
@@ -1193,36 +1710,62 @@ gpio2_err:
1193 if (gpio_is_valid(audpwron)) 1710 if (gpio_is_valid(audpwron))
1194 gpio_free(audpwron); 1711 gpio_free(audpwron);
1195gpio1_err: 1712gpio1_err:
1196 kfree(codec->reg_cache); 1713 destroy_workqueue(priv->workqueue);
1197cache_err: 1714work_err:
1198 kfree(priv); 1715 kfree(priv);
1199 return ret; 1716 return ret;
1200} 1717}
1201 1718
1202static int __devexit twl6040_codec_remove(struct platform_device *pdev) 1719static int twl6040_remove(struct snd_soc_codec *codec)
1203{ 1720{
1204 struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec); 1721 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1205 int audpwron = priv->audpwron; 1722 int audpwron = priv->audpwron;
1206 int naudint = priv->naudint; 1723 int naudint = priv->naudint;
1207 1724
1725 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1726
1208 if (gpio_is_valid(audpwron)) 1727 if (gpio_is_valid(audpwron))
1209 gpio_free(audpwron); 1728 gpio_free(audpwron);
1210 1729
1211 if (naudint) 1730 if (naudint)
1212 free_irq(naudint, twl6040_codec); 1731 free_irq(naudint, codec);
1732
1733 destroy_workqueue(priv->workqueue);
1734 destroy_workqueue(priv->hf_workqueue);
1735 destroy_workqueue(priv->hs_workqueue);
1736 kfree(priv);
1737
1738 return 0;
1739}
1213 1740
1214 snd_soc_unregister_dai(&twl6040_dai); 1741static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
1215 snd_soc_unregister_codec(twl6040_codec); 1742 .probe = twl6040_probe,
1743 .remove = twl6040_remove,
1744 .suspend = twl6040_suspend,
1745 .resume = twl6040_resume,
1746 .read = twl6040_read_reg_cache,
1747 .write = twl6040_write,
1748 .set_bias_level = twl6040_set_bias_level,
1749 .reg_cache_size = ARRAY_SIZE(twl6040_reg),
1750 .reg_word_size = sizeof(u8),
1751 .reg_cache_default = twl6040_reg,
1752};
1216 1753
1217 kfree(twl6040_codec); 1754static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1218 twl6040_codec = NULL; 1755{
1756 return snd_soc_register_codec(&pdev->dev,
1757 &soc_codec_dev_twl6040, &twl6040_dai, 1);
1758}
1219 1759
1760static int __devexit twl6040_codec_remove(struct platform_device *pdev)
1761{
1762 snd_soc_unregister_codec(&pdev->dev);
1220 return 0; 1763 return 0;
1221} 1764}
1222 1765
1223static struct platform_driver twl6040_codec_driver = { 1766static struct platform_driver twl6040_codec_driver = {
1224 .driver = { 1767 .driver = {
1225 .name = "twl6040_codec", 1768 .name = "twl6040-codec",
1226 .owner = THIS_MODULE, 1769 .owner = THIS_MODULE,
1227 }, 1770 },
1228 .probe = twl6040_codec_probe, 1771 .probe = twl6040_codec_probe,
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index c472070a1da2..23aeed0963e6 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -79,6 +79,7 @@
79 79
80/* INTMR (0x04) fields */ 80/* INTMR (0x04) fields */
81 81
82#define TWL6040_PLUGMSK 0x02
82#define TWL6040_READYMSK 0x40 83#define TWL6040_READYMSK 0x40
83#define TWL6040_ALLINT_MSK 0x7B 84#define TWL6040_ALLINT_MSK 0x7B
84 85
@@ -135,7 +136,11 @@
135#define TWL6040_HPPLL_ID 1 136#define TWL6040_HPPLL_ID 1
136#define TWL6040_LPPLL_ID 2 137#define TWL6040_LPPLL_ID 2
137 138
138extern struct snd_soc_dai twl6040_dai; 139/* STATUS (0x2E) fields */
139extern struct snd_soc_codec_device soc_codec_dev_twl6040; 140
141#define TWL6040_PLUGCOMP 0x02
142
143void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
144 struct snd_soc_jack *jack, int report);
140 145
141#endif /* End of __TWL6040_H__ */ 146#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index f3b4c1d6a82d..a7b8f301bad3 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -19,7 +19,6 @@
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <sound/initval.h> 22#include <sound/initval.h>
24 23
25#include <sound/uda134x.h> 24#include <sound/uda134x.h>
@@ -161,8 +160,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
161 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
162{ 161{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data; 162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct snd_soc_device *socdev = rtd->socdev; 163 struct snd_soc_codec *codec =rtd->codec;
165 struct snd_soc_codec *codec = socdev->card->codec;
166 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 164 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
167 struct snd_pcm_runtime *master_runtime; 165 struct snd_pcm_runtime *master_runtime;
168 166
@@ -194,8 +192,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream,
194 struct snd_soc_dai *dai) 192 struct snd_soc_dai *dai)
195{ 193{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
197 struct snd_soc_device *socdev = rtd->socdev; 195 struct snd_soc_codec *codec = rtd->codec;
198 struct snd_soc_codec *codec = socdev->card->codec;
199 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 196 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
200 197
201 if (uda134x->master_substream == substream) 198 if (uda134x->master_substream == substream)
@@ -209,8 +206,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
209 struct snd_soc_dai *dai) 206 struct snd_soc_dai *dai)
210{ 207{
211 struct snd_soc_pcm_runtime *rtd = substream->private_data; 208 struct snd_soc_pcm_runtime *rtd = substream->private_data;
212 struct snd_soc_device *socdev = rtd->socdev; 209 struct snd_soc_codec *codec = rtd->codec;
213 struct snd_soc_codec *codec = socdev->card->codec;
214 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 210 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
215 u8 hw_params; 211 u8 hw_params;
216 212
@@ -364,7 +360,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
364 pd->power(1); 360 pd->power(1);
365 /* Sync reg_cache with the hardware */ 361 /* Sync reg_cache with the hardware */
366 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++) 362 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
367 codec->write(codec, i, *cache++); 363 codec->driver->write(codec, i, *cache++);
368 } 364 }
369 break; 365 break;
370 case SND_SOC_BIAS_STANDBY: 366 case SND_SOC_BIAS_STANDBY:
@@ -392,7 +388,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
392 pd->power(0); 388 pd->power(0);
393 break; 389 break;
394 } 390 }
395 codec->bias_level = level; 391 codec->dapm.bias_level = level;
396 return 0; 392 return 0;
397} 393}
398 394
@@ -465,8 +461,8 @@ static struct snd_soc_dai_ops uda134x_dai_ops = {
465 .set_fmt = uda134x_set_dai_fmt, 461 .set_fmt = uda134x_set_dai_fmt,
466}; 462};
467 463
468struct snd_soc_dai uda134x_dai = { 464static struct snd_soc_dai_driver uda134x_dai = {
469 .name = "UDA134X", 465 .name = "uda134x-hifi",
470 /* playback capabilities */ 466 /* playback capabilities */
471 .playback = { 467 .playback = {
472 .stream_name = "Playback", 468 .stream_name = "Playback",
@@ -486,27 +482,22 @@ struct snd_soc_dai uda134x_dai = {
486 /* pcm operations */ 482 /* pcm operations */
487 .ops = &uda134x_dai_ops, 483 .ops = &uda134x_dai_ops,
488}; 484};
489EXPORT_SYMBOL(uda134x_dai);
490 485
491 486static int uda134x_soc_probe(struct snd_soc_codec *codec)
492static int uda134x_soc_probe(struct platform_device *pdev)
493{ 487{
494 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
495 struct snd_soc_codec *codec;
496 struct uda134x_priv *uda134x; 488 struct uda134x_priv *uda134x;
497 void *codec_setup_data = socdev->codec_data; 489 struct uda134x_platform_data *pd = codec->card->dev->platform_data;
498 int ret = -ENOMEM; 490
499 struct uda134x_platform_data *pd; 491 int ret;
500 492
501 printk(KERN_INFO "UDA134X SoC Audio Codec\n"); 493 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
502 494
503 if (!codec_setup_data) { 495 if (!pd) {
504 printk(KERN_ERR "UDA134X SoC codec: " 496 printk(KERN_ERR "UDA134X SoC codec: "
505 "missing L3 bitbang function\n"); 497 "missing L3 bitbang function\n");
506 return -ENODEV; 498 return -ENODEV;
507 } 499 }
508 500
509 pd = codec_setup_data;
510 switch (pd->model) { 501 switch (pd->model) {
511 case UDA134X_UDA1340: 502 case UDA134X_UDA1340:
512 case UDA134X_UDA1341: 503 case UDA134X_UDA1341:
@@ -520,58 +511,22 @@ static int uda134x_soc_probe(struct platform_device *pdev)
520 return -EINVAL; 511 return -EINVAL;
521 } 512 }
522 513
523 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
524 if (socdev->card->codec == NULL)
525 return ret;
526
527 codec = socdev->card->codec;
528
529 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); 514 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
530 if (uda134x == NULL) 515 if (uda134x == NULL)
531 goto priv_err; 516 return -ENOMEM;
532 snd_soc_codec_set_drvdata(codec, uda134x); 517 snd_soc_codec_set_drvdata(codec, uda134x);
533 518
534 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg), 519 codec->control_data = pd;
535 GFP_KERNEL);
536 if (codec->reg_cache == NULL)
537 goto reg_err;
538
539 mutex_init(&codec->mutex);
540
541 codec->reg_cache_size = sizeof(uda134x_reg);
542 codec->reg_cache_step = 1;
543
544 codec->name = "UDA134X";
545 codec->owner = THIS_MODULE;
546 codec->dai = &uda134x_dai;
547 codec->num_dai = 1;
548 codec->read = uda134x_read_reg_cache;
549 codec->write = uda134x_write;
550
551 INIT_LIST_HEAD(&codec->dapm_widgets);
552 INIT_LIST_HEAD(&codec->dapm_paths);
553
554 codec->control_data = codec_setup_data;
555 520
556 if (pd->power) 521 if (pd->power)
557 pd->power(1); 522 pd->power(1);
558 523
559 uda134x_reset(codec); 524 uda134x_reset(codec);
560 525
561 if (pd->is_powered_on_standby) { 526 if (pd->is_powered_on_standby)
562 codec->set_bias_level = NULL;
563 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); 527 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
564 } else { 528 else
565 codec->set_bias_level = uda134x_set_bias_level;
566 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 529 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 }
568
569 /* register pcms */
570 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
571 if (ret < 0) {
572 printk(KERN_ERR "UDA134X: failed to register pcms\n");
573 goto pcm_err;
574 }
575 530
576 switch (pd->model) { 531 switch (pd->model) {
577 case UDA134X_UDA1340: 532 case UDA134X_UDA1340:
@@ -590,61 +545,42 @@ static int uda134x_soc_probe(struct platform_device *pdev)
590 default: 545 default:
591 printk(KERN_ERR "%s unknown codec type: %d", 546 printk(KERN_ERR "%s unknown codec type: %d",
592 __func__, pd->model); 547 __func__, pd->model);
593 return -EINVAL; 548 kfree(uda134x);
549 return -EINVAL;
594 } 550 }
595 551
596 if (ret < 0) { 552 if (ret < 0) {
597 printk(KERN_ERR "UDA134X: failed to register controls\n"); 553 printk(KERN_ERR "UDA134X: failed to register controls\n");
598 goto pcm_err; 554 kfree(uda134x);
555 return ret;
599 } 556 }
600 557
601 return 0; 558 return 0;
602
603pcm_err:
604 kfree(codec->reg_cache);
605reg_err:
606 kfree(snd_soc_codec_get_drvdata(codec));
607priv_err:
608 kfree(codec);
609 return ret;
610} 559}
611 560
612/* power down chip */ 561/* power down chip */
613static int uda134x_soc_remove(struct platform_device *pdev) 562static int uda134x_soc_remove(struct snd_soc_codec *codec)
614{ 563{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 564 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
616 struct snd_soc_codec *codec = socdev->card->codec;
617 565
618 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 566 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
619 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); 567 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
620 568
621 snd_soc_free_pcms(socdev); 569 kfree(uda134x);
622 snd_soc_dapm_free(socdev);
623
624 kfree(snd_soc_codec_get_drvdata(codec));
625 kfree(codec->reg_cache);
626 kfree(codec);
627
628 return 0; 570 return 0;
629} 571}
630 572
631#if defined(CONFIG_PM) 573#if defined(CONFIG_PM)
632static int uda134x_soc_suspend(struct platform_device *pdev, 574static int uda134x_soc_suspend(struct snd_soc_codec *codec,
633 pm_message_t state) 575 pm_message_t state)
634{ 576{
635 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
636 struct snd_soc_codec *codec = socdev->card->codec;
637
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 577 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
639 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); 578 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
640 return 0; 579 return 0;
641} 580}
642 581
643static int uda134x_soc_resume(struct platform_device *pdev) 582static int uda134x_soc_resume(struct snd_soc_codec *codec)
644{ 583{
645 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
646 struct snd_soc_codec *codec = socdev->card->codec;
647
648 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 584 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
649 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); 585 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
650 return 0; 586 return 0;
@@ -654,25 +590,52 @@ static int uda134x_soc_resume(struct platform_device *pdev)
654#define uda134x_soc_resume NULL 590#define uda134x_soc_resume NULL
655#endif /* CONFIG_PM */ 591#endif /* CONFIG_PM */
656 592
657struct snd_soc_codec_device soc_codec_dev_uda134x = { 593static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
658 .probe = uda134x_soc_probe, 594 .probe = uda134x_soc_probe,
659 .remove = uda134x_soc_remove, 595 .remove = uda134x_soc_remove,
660 .suspend = uda134x_soc_suspend, 596 .suspend = uda134x_soc_suspend,
661 .resume = uda134x_soc_resume, 597 .resume = uda134x_soc_resume,
598 .reg_cache_size = sizeof(uda134x_reg),
599 .reg_word_size = sizeof(u8),
600 .reg_cache_default = uda134x_reg,
601 .reg_cache_step = 1,
602 .read = uda134x_read_reg_cache,
603 .write = uda134x_write,
604 .set_bias_level = uda134x_set_bias_level,
605};
606
607static int __devinit uda134x_codec_probe(struct platform_device *pdev)
608{
609 return snd_soc_register_codec(&pdev->dev,
610 &soc_codec_dev_uda134x, &uda134x_dai, 1);
611}
612
613static int __devexit uda134x_codec_remove(struct platform_device *pdev)
614{
615 snd_soc_unregister_codec(&pdev->dev);
616 return 0;
617}
618
619static struct platform_driver uda134x_codec_driver = {
620 .driver = {
621 .name = "uda134x-codec",
622 .owner = THIS_MODULE,
623 },
624 .probe = uda134x_codec_probe,
625 .remove = __devexit_p(uda134x_codec_remove),
662}; 626};
663EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
664 627
665static int __init uda134x_init(void) 628static int __init uda134x_codec_init(void)
666{ 629{
667 return snd_soc_register_dai(&uda134x_dai); 630 return platform_driver_register(&uda134x_codec_driver);
668} 631}
669module_init(uda134x_init); 632module_init(uda134x_codec_init);
670 633
671static void __exit uda134x_exit(void) 634static void __exit uda134x_codec_exit(void)
672{ 635{
673 snd_soc_unregister_dai(&uda134x_dai); 636 platform_driver_unregister(&uda134x_codec_driver);
674} 637}
675module_exit(uda134x_exit); 638module_exit(uda134x_codec_exit);
676 639
677MODULE_DESCRIPTION("UDA134X ALSA soc codec driver"); 640MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
678MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); 641MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
index 205f03b3eaf8..9faae06972b3 100644
--- a/sound/soc/codecs/uda134x.h
+++ b/sound/soc/codecs/uda134x.h
@@ -31,7 +31,4 @@
31#define STATUS0_DAIFMT_MASK (~(7<<1)) 31#define STATUS0_DAIFMT_MASK (~(7<<1))
32#define STATUS0_SYSCLK_MASK (~(3<<4)) 32#define STATUS0_SYSCLK_MASK (~(3<<4))
33 33
34extern struct snd_soc_dai uda134x_dai;
35extern struct snd_soc_codec_device soc_codec_dev_uda134x;
36
37#endif 34#endif
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2f925a27dcde..c5ca8cfea60f 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -27,20 +27,17 @@
27#include <sound/control.h> 27#include <sound/control.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h> 30#include <sound/tlv.h>
32#include <sound/uda1380.h> 31#include <sound/uda1380.h>
33 32
34#include "uda1380.h" 33#include "uda1380.h"
35 34
36static struct snd_soc_codec *uda1380_codec;
37
38/* codec private data */ 35/* codec private data */
39struct uda1380_priv { 36struct uda1380_priv {
40 struct snd_soc_codec codec; 37 struct snd_soc_codec *codec;
41 u16 reg_cache[UDA1380_CACHEREGNUM];
42 unsigned int dac_clk; 38 unsigned int dac_clk;
43 struct work_struct work; 39 struct work_struct work;
40 void *control_data;
44}; 41};
45 42
46/* 43/*
@@ -131,10 +128,51 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
131 return -EIO; 128 return -EIO;
132} 129}
133 130
134#define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0) 131static void uda1380_sync_cache(struct snd_soc_codec *codec)
132{
133 int reg;
134 u8 data[3];
135 u16 *cache = codec->reg_cache;
136
137 /* Sync reg_cache with the hardware */
138 for (reg = 0; reg < UDA1380_MVOL; reg++) {
139 data[0] = reg;
140 data[1] = (cache[reg] & 0xff00) >> 8;
141 data[2] = cache[reg] & 0x00ff;
142 if (codec->hw_write(codec->control_data, data, 3) != 3)
143 dev_err(codec->dev, "%s: write to reg 0x%x failed\n",
144 __func__, reg);
145 }
146}
147
148static int uda1380_reset(struct snd_soc_codec *codec)
149{
150 struct uda1380_platform_data *pdata = codec->dev->platform_data;
151
152 if (gpio_is_valid(pdata->gpio_reset)) {
153 gpio_set_value(pdata->gpio_reset, 1);
154 mdelay(1);
155 gpio_set_value(pdata->gpio_reset, 0);
156 } else {
157 u8 data[3];
158
159 data[0] = UDA1380_RESET;
160 data[1] = 0;
161 data[2] = 0;
162
163 if (codec->hw_write(codec->control_data, data, 3) != 3) {
164 dev_err(codec->dev, "%s: failed\n", __func__);
165 return -EIO;
166 }
167 }
168
169 return 0;
170}
135 171
136static void uda1380_flush_work(struct work_struct *work) 172static void uda1380_flush_work(struct work_struct *work)
137{ 173{
174 struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
175 struct snd_soc_codec *uda1380_codec = uda1380->codec;
138 int bit, reg; 176 int bit, reg;
139 177
140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 178 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
@@ -145,6 +183,7 @@ static void uda1380_flush_work(struct work_struct *work)
145 uda1380_read_reg_cache(uda1380_codec, reg)); 183 uda1380_read_reg_cache(uda1380_codec, reg));
146 clear_bit(bit, &uda1380_cache_dirty); 184 clear_bit(bit, &uda1380_cache_dirty);
147 } 185 }
186
148} 187}
149 188
150/* declarations of ALSA reg_elem_REAL controls */ 189/* declarations of ALSA reg_elem_REAL controls */
@@ -373,10 +412,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
373 412
374static int uda1380_add_widgets(struct snd_soc_codec *codec) 413static int uda1380_add_widgets(struct snd_soc_codec *codec)
375{ 414{
376 snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, 415 struct snd_soc_dapm_context *dapm = &codec->dapm;
377 ARRAY_SIZE(uda1380_dapm_widgets));
378 416
379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 417 snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
418 ARRAY_SIZE(uda1380_dapm_widgets));
419 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
380 420
381 return 0; 421 return 0;
382} 422}
@@ -474,8 +514,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
474 struct snd_soc_dai *dai) 514 struct snd_soc_dai *dai)
475{ 515{
476 struct snd_soc_pcm_runtime *rtd = substream->private_data; 516 struct snd_soc_pcm_runtime *rtd = substream->private_data;
477 struct snd_soc_device *socdev = rtd->socdev; 517 struct snd_soc_codec *codec = rtd->codec;
478 struct snd_soc_codec *codec = socdev->card->codec;
479 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); 518 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 519 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
481 520
@@ -501,8 +540,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
501 struct snd_soc_dai *dai) 540 struct snd_soc_dai *dai)
502{ 541{
503 struct snd_soc_pcm_runtime *rtd = substream->private_data; 542 struct snd_soc_pcm_runtime *rtd = substream->private_data;
504 struct snd_soc_device *socdev = rtd->socdev; 543 struct snd_soc_codec *codec = rtd->codec;
505 struct snd_soc_codec *codec = socdev->card->codec;
506 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 544 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
507 545
508 /* set WSPLL power and divider if running from this clock */ 546 /* set WSPLL power and divider if running from this clock */
@@ -540,8 +578,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
540 struct snd_soc_dai *dai) 578 struct snd_soc_dai *dai)
541{ 579{
542 struct snd_soc_pcm_runtime *rtd = substream->private_data; 580 struct snd_soc_pcm_runtime *rtd = substream->private_data;
543 struct snd_soc_device *socdev = rtd->socdev; 581 struct snd_soc_codec *codec = rtd->codec;
544 struct snd_soc_codec *codec = socdev->card->codec;
545 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 582 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
546 583
547 /* shut down WSPLL power if running from this clock */ 584 /* shut down WSPLL power if running from this clock */
@@ -562,20 +599,43 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
562 enum snd_soc_bias_level level) 599 enum snd_soc_bias_level level)
563{ 600{
564 int pm = uda1380_read_reg_cache(codec, UDA1380_PM); 601 int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
602 int reg;
603 struct uda1380_platform_data *pdata = codec->dev->platform_data;
604
605 if (codec->dapm.bias_level == level)
606 return 0;
565 607
566 switch (level) { 608 switch (level) {
567 case SND_SOC_BIAS_ON: 609 case SND_SOC_BIAS_ON:
568 case SND_SOC_BIAS_PREPARE: 610 case SND_SOC_BIAS_PREPARE:
611 /* ADC, DAC on */
569 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); 612 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
570 break; 613 break;
571 case SND_SOC_BIAS_STANDBY: 614 case SND_SOC_BIAS_STANDBY:
572 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS); 615 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
573 break; 616 if (gpio_is_valid(pdata->gpio_power)) {
574 case SND_SOC_BIAS_OFF: 617 gpio_set_value(pdata->gpio_power, 1);
618 mdelay(1);
619 uda1380_reset(codec);
620 }
621
622 uda1380_sync_cache(codec);
623 }
575 uda1380_write(codec, UDA1380_PM, 0x0); 624 uda1380_write(codec, UDA1380_PM, 0x0);
576 break; 625 break;
626 case SND_SOC_BIAS_OFF:
627 if (!gpio_is_valid(pdata->gpio_power))
628 break;
629
630 gpio_set_value(pdata->gpio_power, 0);
631
632 /* Mark mixer regs cache dirty to sync them with
633 * codec regs on power on.
634 */
635 for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
636 set_bit(reg - 0x10, &uda1380_cache_dirty);
577 } 637 }
578 codec->bias_level = level; 638 codec->dapm.bias_level = level;
579 return 0; 639 return 0;
580} 640}
581 641
@@ -604,9 +664,9 @@ static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
604 .set_fmt = uda1380_set_dai_fmt_capture, 664 .set_fmt = uda1380_set_dai_fmt_capture,
605}; 665};
606 666
607struct snd_soc_dai uda1380_dai[] = { 667static struct snd_soc_dai_driver uda1380_dai[] = {
608{ 668{
609 .name = "UDA1380", 669 .name = "uda1380-hifi",
610 .playback = { 670 .playback = {
611 .stream_name = "Playback", 671 .stream_name = "Playback",
612 .channels_min = 1, 672 .channels_min = 1,
@@ -622,7 +682,7 @@ struct snd_soc_dai uda1380_dai[] = {
622 .ops = &uda1380_dai_ops, 682 .ops = &uda1380_dai_ops,
623}, 683},
624{ /* playback only - dual interface */ 684{ /* playback only - dual interface */
625 .name = "UDA1380", 685 .name = "uda1380-hifi-playback",
626 .playback = { 686 .playback = {
627 .stream_name = "Playback", 687 .stream_name = "Playback",
628 .channels_min = 1, 688 .channels_min = 1,
@@ -633,7 +693,7 @@ struct snd_soc_dai uda1380_dai[] = {
633 .ops = &uda1380_dai_ops_playback, 693 .ops = &uda1380_dai_ops_playback,
634}, 694},
635{ /* capture only - dual interface*/ 695{ /* capture only - dual interface*/
636 .name = "UDA1380", 696 .name = "uda1380-hifi-capture",
637 .capture = { 697 .capture = {
638 .stream_name = "Capture", 698 .stream_name = "Capture",
639 .channels_min = 1, 699 .channels_min = 1,
@@ -644,67 +704,69 @@ struct snd_soc_dai uda1380_dai[] = {
644 .ops = &uda1380_dai_ops_capture, 704 .ops = &uda1380_dai_ops_capture,
645}, 705},
646}; 706};
647EXPORT_SYMBOL_GPL(uda1380_dai);
648 707
649static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) 708static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state)
650{ 709{
651 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
652 struct snd_soc_codec *codec = socdev->card->codec;
653
654 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 710 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
655 return 0; 711 return 0;
656} 712}
657 713
658static int uda1380_resume(struct platform_device *pdev) 714static int uda1380_resume(struct snd_soc_codec *codec)
659{ 715{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec = socdev->card->codec;
662 int i;
663 u8 data[2];
664 u16 *cache = codec->reg_cache;
665
666 /* Sync reg_cache with the hardware */
667 for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) {
668 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
669 data[1] = cache[i] & 0x00ff;
670 codec->hw_write(codec->control_data, data, 2);
671 }
672 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 716 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
673 return 0; 717 return 0;
674} 718}
675 719
676static int uda1380_probe(struct platform_device *pdev) 720static int uda1380_probe(struct snd_soc_codec *codec)
677{ 721{
678 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 722 struct uda1380_platform_data *pdata =codec->dev->platform_data;
679 struct snd_soc_codec *codec; 723 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
680 struct uda1380_platform_data *pdata; 724 int ret;
681 int ret = 0;
682 725
683 if (uda1380_codec == NULL) { 726 uda1380->codec = codec;
684 dev_err(&pdev->dev, "Codec device not registered\n"); 727
685 return -ENODEV; 728 codec->hw_write = (hw_write_t)i2c_master_send;
686 } 729 codec->control_data = uda1380->control_data;
687 730
688 socdev->card->codec = uda1380_codec; 731 if (!pdata)
689 codec = uda1380_codec; 732 return -EINVAL;
690 pdata = codec->dev->platform_data; 733
734 if (gpio_is_valid(pdata->gpio_reset)) {
735 ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
736 if (ret)
737 goto err_out;
738 ret = gpio_direction_output(pdata->gpio_reset, 0);
739 if (ret)
740 goto err_gpio_reset_conf;
741 }
691 742
692 /* register pcms */ 743 if (gpio_is_valid(pdata->gpio_power)) {
693 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 744 ret = gpio_request(pdata->gpio_power, "uda1380 power");
694 if (ret < 0) { 745 if (ret)
695 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 746 goto err_gpio;
696 goto pcm_err; 747 ret = gpio_direction_output(pdata->gpio_power, 0);
748 if (ret)
749 goto err_gpio_power_conf;
750 } else {
751 ret = uda1380_reset(codec);
752 if (ret) {
753 dev_err(codec->dev, "Failed to issue reset\n");
754 goto err_reset;
755 }
697 } 756 }
698 757
758 INIT_WORK(&uda1380->work, uda1380_flush_work);
759
699 /* power on device */ 760 /* power on device */
700 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 761 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
701 /* set clock input */ 762 /* set clock input */
702 switch (pdata->dac_clk) { 763 switch (pdata->dac_clk) {
703 case UDA1380_DAC_CLK_SYSCLK: 764 case UDA1380_DAC_CLK_SYSCLK:
704 uda1380_write(codec, UDA1380_CLK, 0); 765 uda1380_write_reg_cache(codec, UDA1380_CLK, 0);
705 break; 766 break;
706 case UDA1380_DAC_CLK_WSPLL: 767 case UDA1380_DAC_CLK_WSPLL:
707 uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK); 768 uda1380_write_reg_cache(codec, UDA1380_CLK,
769 R00_DAC_CLK);
708 break; 770 break;
709 } 771 }
710 772
@@ -712,167 +774,73 @@ static int uda1380_probe(struct platform_device *pdev)
712 ARRAY_SIZE(uda1380_snd_controls)); 774 ARRAY_SIZE(uda1380_snd_controls));
713 uda1380_add_widgets(codec); 775 uda1380_add_widgets(codec);
714 776
715 return ret;
716
717pcm_err:
718 return ret;
719}
720
721/* power down chip */
722static int uda1380_remove(struct platform_device *pdev)
723{
724 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
725 struct snd_soc_codec *codec = socdev->card->codec;
726
727 if (codec->control_data)
728 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
729
730 snd_soc_free_pcms(socdev);
731 snd_soc_dapm_free(socdev);
732
733 return 0;
734}
735
736struct snd_soc_codec_device soc_codec_dev_uda1380 = {
737 .probe = uda1380_probe,
738 .remove = uda1380_remove,
739 .suspend = uda1380_suspend,
740 .resume = uda1380_resume,
741};
742EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
743
744static int uda1380_register(struct uda1380_priv *uda1380)
745{
746 int ret, i;
747 struct snd_soc_codec *codec = &uda1380->codec;
748 struct uda1380_platform_data *pdata = codec->dev->platform_data;
749
750 if (uda1380_codec) {
751 dev_err(codec->dev, "Another UDA1380 is registered\n");
752 return -EINVAL;
753 }
754
755 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
756 return -EINVAL;
757
758 ret = gpio_request(pdata->gpio_power, "uda1380 power");
759 if (ret)
760 goto err_out;
761 ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
762 if (ret)
763 goto err_gpio;
764
765 gpio_direction_output(pdata->gpio_power, 1);
766
767 /* we may need to have the clock running here - pH5 */
768 gpio_direction_output(pdata->gpio_reset, 1);
769 udelay(5);
770 gpio_set_value(pdata->gpio_reset, 0);
771
772 mutex_init(&codec->mutex);
773 INIT_LIST_HEAD(&codec->dapm_widgets);
774 INIT_LIST_HEAD(&codec->dapm_paths);
775
776 snd_soc_codec_set_drvdata(codec, uda1380);
777 codec->name = "UDA1380";
778 codec->owner = THIS_MODULE;
779 codec->read = uda1380_read_reg_cache;
780 codec->write = uda1380_write;
781 codec->bias_level = SND_SOC_BIAS_OFF;
782 codec->set_bias_level = uda1380_set_bias_level;
783 codec->dai = uda1380_dai;
784 codec->num_dai = ARRAY_SIZE(uda1380_dai);
785 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
786 codec->reg_cache = &uda1380->reg_cache;
787 codec->reg_cache_step = 1;
788
789 memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
790
791 ret = uda1380_reset(codec);
792 if (ret < 0) {
793 dev_err(codec->dev, "Failed to issue reset\n");
794 goto err_reset;
795 }
796
797 INIT_WORK(&uda1380->work, uda1380_flush_work);
798
799 for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++)
800 uda1380_dai[i].dev = codec->dev;
801
802 uda1380_codec = codec;
803
804 ret = snd_soc_register_codec(codec);
805 if (ret != 0) {
806 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
807 goto err_reset;
808 }
809
810 ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
811 if (ret != 0) {
812 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
813 goto err_dai;
814 }
815
816 return 0; 777 return 0;
817 778
818err_dai:
819 snd_soc_unregister_codec(codec);
820err_reset: 779err_reset:
821 gpio_set_value(pdata->gpio_power, 0); 780err_gpio_power_conf:
822 gpio_free(pdata->gpio_reset); 781 if (gpio_is_valid(pdata->gpio_power))
782 gpio_free(pdata->gpio_power);
783
784err_gpio_reset_conf:
823err_gpio: 785err_gpio:
824 gpio_free(pdata->gpio_power); 786 if (gpio_is_valid(pdata->gpio_reset))
787 gpio_free(pdata->gpio_reset);
825err_out: 788err_out:
826 return ret; 789 return ret;
827} 790}
828 791
829static void uda1380_unregister(struct uda1380_priv *uda1380) 792/* power down chip */
793static int uda1380_remove(struct snd_soc_codec *codec)
830{ 794{
831 struct snd_soc_codec *codec = &uda1380->codec; 795 struct uda1380_platform_data *pdata =codec->dev->platform_data;
832 struct uda1380_platform_data *pdata = codec->dev->platform_data;
833 796
834 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 797 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
835 snd_soc_unregister_codec(&uda1380->codec);
836 798
837 gpio_set_value(pdata->gpio_power, 0);
838 gpio_free(pdata->gpio_reset); 799 gpio_free(pdata->gpio_reset);
839 gpio_free(pdata->gpio_power); 800 gpio_free(pdata->gpio_power);
840 801
841 kfree(uda1380); 802 return 0;
842 uda1380_codec = NULL;
843} 803}
844 804
805static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
806 .probe = uda1380_probe,
807 .remove = uda1380_remove,
808 .suspend = uda1380_suspend,
809 .resume = uda1380_resume,
810 .read = uda1380_read_reg_cache,
811 .write = uda1380_write,
812 .set_bias_level = uda1380_set_bias_level,
813 .reg_cache_size = ARRAY_SIZE(uda1380_reg),
814 .reg_word_size = sizeof(u16),
815 .reg_cache_default = uda1380_reg,
816 .reg_cache_step = 1,
817};
818
845#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 819#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
846static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, 820static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
847 const struct i2c_device_id *id) 821 const struct i2c_device_id *id)
848{ 822{
849 struct uda1380_priv *uda1380; 823 struct uda1380_priv *uda1380;
850 struct snd_soc_codec *codec;
851 int ret; 824 int ret;
852 825
853 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); 826 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
854 if (uda1380 == NULL) 827 if (uda1380 == NULL)
855 return -ENOMEM; 828 return -ENOMEM;
856 829
857 codec = &uda1380->codec;
858 codec->hw_write = (hw_write_t)i2c_master_send;
859
860 i2c_set_clientdata(i2c, uda1380); 830 i2c_set_clientdata(i2c, uda1380);
861 codec->control_data = i2c; 831 uda1380->control_data = i2c;
862 832
863 codec->dev = &i2c->dev; 833 ret = snd_soc_register_codec(&i2c->dev,
864 834 &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
865 ret = uda1380_register(uda1380); 835 if (ret < 0)
866 if (ret != 0)
867 kfree(uda1380); 836 kfree(uda1380);
868
869 return ret; 837 return ret;
870} 838}
871 839
872static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) 840static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
873{ 841{
874 struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c); 842 snd_soc_unregister_codec(&i2c->dev);
875 uda1380_unregister(uda1380); 843 kfree(i2c_get_clientdata(i2c));
876 return 0; 844 return 0;
877} 845}
878 846
@@ -884,7 +852,7 @@ MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
884 852
885static struct i2c_driver uda1380_i2c_driver = { 853static struct i2c_driver uda1380_i2c_driver = {
886 .driver = { 854 .driver = {
887 .name = "UDA1380 I2C Codec", 855 .name = "uda1380-codec",
888 .owner = THIS_MODULE, 856 .owner = THIS_MODULE,
889 }, 857 },
890 .probe = uda1380_i2c_probe, 858 .probe = uda1380_i2c_probe,
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index 9cefa8a54770..942e3927c72b 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -76,7 +76,4 @@
76#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ 76#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
77#define UDA1380_DAI_CAPTURE 2 /* capture DAI */ 77#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
78 78
79extern struct snd_soc_dai uda1380_dai[3];
80extern struct snd_soc_codec_device soc_codec_dev_uda1380;
81
82#endif /* _UDA1380_H */ 79#endif /* _UDA1380_H */
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
new file mode 100644
index 000000000000..5836201834d9
--- /dev/null
+++ b/sound/soc/codecs/wl1273.c
@@ -0,0 +1,527 @@
1/*
2 * ALSA SoC WL1273 codec driver
3 *
4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com>
5 *
6 * Copyright: (C) 2010, 2011 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/mfd/wl1273-core.h>
25#include <linux/slab.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/initval.h>
30
31#include "wl1273.h"
32
33enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };
34
35/* codec private data */
36struct wl1273_priv {
37 enum wl1273_mode mode;
38 struct wl1273_core *core;
39 unsigned int channels;
40};
41
42static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,
43 int rate, int width)
44{
45 struct device *dev = &core->client->dev;
46 int r = 0;
47 u16 mode;
48
49 dev_dbg(dev, "rate: %d\n", rate);
50 dev_dbg(dev, "width: %d\n", width);
51
52 mutex_lock(&core->lock);
53
54 mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;
55
56 switch (rate) {
57 case 48000:
58 mode |= WL1273_IS2_RATE_48K;
59 break;
60 case 44100:
61 mode |= WL1273_IS2_RATE_44_1K;
62 break;
63 case 32000:
64 mode |= WL1273_IS2_RATE_32K;
65 break;
66 case 22050:
67 mode |= WL1273_IS2_RATE_22_05K;
68 break;
69 case 16000:
70 mode |= WL1273_IS2_RATE_16K;
71 break;
72 case 12000:
73 mode |= WL1273_IS2_RATE_12K;
74 break;
75 case 11025:
76 mode |= WL1273_IS2_RATE_11_025;
77 break;
78 case 8000:
79 mode |= WL1273_IS2_RATE_8K;
80 break;
81 default:
82 dev_err(dev, "Sampling rate: %d not supported\n", rate);
83 r = -EINVAL;
84 goto out;
85 }
86
87 switch (width) {
88 case 16:
89 mode |= WL1273_IS2_WIDTH_32;
90 break;
91 case 20:
92 mode |= WL1273_IS2_WIDTH_40;
93 break;
94 case 24:
95 mode |= WL1273_IS2_WIDTH_48;
96 break;
97 case 25:
98 mode |= WL1273_IS2_WIDTH_50;
99 break;
100 case 30:
101 mode |= WL1273_IS2_WIDTH_60;
102 break;
103 case 32:
104 mode |= WL1273_IS2_WIDTH_64;
105 break;
106 case 40:
107 mode |= WL1273_IS2_WIDTH_80;
108 break;
109 case 48:
110 mode |= WL1273_IS2_WIDTH_96;
111 break;
112 case 64:
113 mode |= WL1273_IS2_WIDTH_128;
114 break;
115 default:
116 dev_err(dev, "Data width: %d not supported\n", width);
117 r = -EINVAL;
118 goto out;
119 }
120
121 dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE);
122 dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);
123 dev_dbg(dev, "mode: 0x%04x\n", mode);
124
125 if (core->i2s_mode != mode) {
126 r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);
127 if (r)
128 goto out;
129
130 core->i2s_mode = mode;
131 r = core->write(core, WL1273_AUDIO_ENABLE,
132 WL1273_AUDIO_ENABLE_I2S);
133 if (r)
134 goto out;
135 }
136out:
137 mutex_unlock(&core->lock);
138
139 return r;
140}
141
142static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
143 int channel_number)
144{
145 struct device *dev = &core->client->dev;
146 int r = 0;
147
148 dev_dbg(dev, "%s\n", __func__);
149
150 mutex_lock(&core->lock);
151
152 if (core->channel_number == channel_number)
153 goto out;
154
155 if (channel_number == 1 && core->mode == WL1273_MODE_RX)
156 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
157 else if (channel_number == 1 && core->mode == WL1273_MODE_TX)
158 r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
159 else if (channel_number == 2 && core->mode == WL1273_MODE_RX)
160 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
161 else if (channel_number == 2 && core->mode == WL1273_MODE_TX)
162 r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);
163 else
164 r = -EINVAL;
165out:
166 mutex_unlock(&core->lock);
167
168 return r;
169}
170
171static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
172 struct snd_ctl_elem_value *ucontrol)
173{
174 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
175 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
176
177 ucontrol->value.integer.value[0] = wl1273->mode;
178
179 return 0;
180}
181
182/*
183 * TODO: Implement the audio routing in the driver. Now this control
184 * only indicates the setting that has been done elsewhere (in the user
185 * space).
186 */
187static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
188
189static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
190 struct snd_ctl_elem_value *ucontrol)
191{
192 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
193 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
194
195 if (wl1273->mode == ucontrol->value.integer.value[0])
196 return 0;
197
198 /* Do not allow changes while stream is running */
199 if (codec->active)
200 return -EPERM;
201
202 if (ucontrol->value.integer.value[0] < 0 ||
203 ucontrol->value.integer.value[0] >= ARRAY_SIZE(wl1273_audio_route))
204 return -EINVAL;
205
206 wl1273->mode = ucontrol->value.integer.value[0];
207
208 return 1;
209}
210
211static const struct soc_enum wl1273_enum =
212 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_route), wl1273_audio_route);
213
214static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
215 struct snd_ctl_elem_value *ucontrol)
216{
217 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
218 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
219
220 dev_dbg(codec->dev, "%s: enter.\n", __func__);
221
222 ucontrol->value.integer.value[0] = wl1273->core->audio_mode;
223
224 return 0;
225}
226
227static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
228 struct snd_ctl_elem_value *ucontrol)
229{
230 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
231 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
232 int val, r = 0;
233
234 dev_dbg(codec->dev, "%s: enter.\n", __func__);
235
236 val = ucontrol->value.integer.value[0];
237 if (wl1273->core->audio_mode == val)
238 return 0;
239
240 r = wl1273->core->set_audio(wl1273->core, val);
241 if (r < 0)
242 return r;
243
244 return 1;
245}
246
247static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
248
249static const struct soc_enum wl1273_audio_enum =
250 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings),
251 wl1273_audio_strings);
252
253static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
254 struct snd_ctl_elem_value *ucontrol)
255{
256 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
257 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
258
259 dev_dbg(codec->dev, "%s: enter.\n", __func__);
260
261 ucontrol->value.integer.value[0] = wl1273->core->volume;
262
263 return 0;
264}
265
266static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
267 struct snd_ctl_elem_value *ucontrol)
268{
269 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
270 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
271 int r;
272
273 dev_dbg(codec->dev, "%s: enter.\n", __func__);
274
275 r = wl1273->core->set_volume(wl1273->core,
276 ucontrol->value.integer.value[0]);
277 if (r)
278 return r;
279
280 return 1;
281}
282
283static const struct snd_kcontrol_new wl1273_controls[] = {
284 SOC_ENUM_EXT("Codec Mode", wl1273_enum,
285 snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),
286 SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,
287 snd_wl1273_fm_audio_get, snd_wl1273_fm_audio_put),
288 SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,
289 snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
290};
291
292static int wl1273_startup(struct snd_pcm_substream *substream,
293 struct snd_soc_dai *dai)
294{
295 struct snd_soc_pcm_runtime *rtd = substream->private_data;
296 struct snd_soc_codec *codec = rtd->codec;
297 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
298
299 switch (wl1273->mode) {
300 case WL1273_MODE_BT:
301 snd_pcm_hw_constraint_minmax(substream->runtime,
302 SNDRV_PCM_HW_PARAM_RATE,
303 8000, 8000);
304 snd_pcm_hw_constraint_minmax(substream->runtime,
305 SNDRV_PCM_HW_PARAM_CHANNELS, 1, 1);
306 break;
307 case WL1273_MODE_FM_RX:
308 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
309 pr_err("Cannot play in RX mode.\n");
310 return -EINVAL;
311 }
312 break;
313 case WL1273_MODE_FM_TX:
314 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
315 pr_err("Cannot capture in TX mode.\n");
316 return -EINVAL;
317 }
318 break;
319 default:
320 return -EINVAL;
321 break;
322 }
323
324 return 0;
325}
326
327static int wl1273_hw_params(struct snd_pcm_substream *substream,
328 struct snd_pcm_hw_params *params,
329 struct snd_soc_dai *dai)
330{
331 struct snd_soc_pcm_runtime *rtd = substream->private_data;
332 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(rtd->codec);
333 struct wl1273_core *core = wl1273->core;
334 unsigned int rate, width, r;
335
336 if (params_format(params) != SNDRV_PCM_FORMAT_S16_LE) {
337 pr_err("Only SNDRV_PCM_FORMAT_S16_LE supported.\n");
338 return -EINVAL;
339 }
340
341 rate = params_rate(params);
342 width = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
343
344 if (wl1273->mode == WL1273_MODE_BT) {
345 if (rate != 8000) {
346 pr_err("Rate %d not supported.\n", params_rate(params));
347 return -EINVAL;
348 }
349
350 if (params_channels(params) != 1) {
351 pr_err("Only mono supported.\n");
352 return -EINVAL;
353 }
354
355 return 0;
356 }
357
358 if (wl1273->mode == WL1273_MODE_FM_TX &&
359 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
360 pr_err("Only playback supported with TX.\n");
361 return -EINVAL;
362 }
363
364 if (wl1273->mode == WL1273_MODE_FM_RX &&
365 substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
366 pr_err("Only capture supported with RX.\n");
367 return -EINVAL;
368 }
369
370 if (wl1273->mode != WL1273_MODE_FM_RX &&
371 wl1273->mode != WL1273_MODE_FM_TX) {
372 pr_err("Unexpected mode: %d.\n", wl1273->mode);
373 return -EINVAL;
374 }
375
376 r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
377 if (r)
378 return r;
379
380 wl1273->channels = params_channels(params);
381 r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
382 if (r)
383 return r;
384
385 return 0;
386}
387
388static struct snd_soc_dai_ops wl1273_dai_ops = {
389 .startup = wl1273_startup,
390 .hw_params = wl1273_hw_params,
391};
392
393static struct snd_soc_dai_driver wl1273_dai = {
394 .name = "wl1273-fm",
395 .playback = {
396 .stream_name = "Playback",
397 .channels_min = 1,
398 .channels_max = 2,
399 .rates = SNDRV_PCM_RATE_8000_48000,
400 .formats = SNDRV_PCM_FMTBIT_S16_LE},
401 .capture = {
402 .stream_name = "Capture",
403 .channels_min = 1,
404 .channels_max = 2,
405 .rates = SNDRV_PCM_RATE_8000_48000,
406 .formats = SNDRV_PCM_FMTBIT_S16_LE},
407 .ops = &wl1273_dai_ops,
408};
409
410/* Audio interface format for the soc_card driver */
411int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
412{
413 struct wl1273_priv *wl1273;
414
415 if (codec == NULL || fmt == NULL)
416 return -EINVAL;
417
418 wl1273 = snd_soc_codec_get_drvdata(codec);
419
420 switch (wl1273->mode) {
421 case WL1273_MODE_FM_RX:
422 case WL1273_MODE_FM_TX:
423 *fmt = SND_SOC_DAIFMT_I2S |
424 SND_SOC_DAIFMT_NB_NF |
425 SND_SOC_DAIFMT_CBM_CFM;
426
427 break;
428 case WL1273_MODE_BT:
429 *fmt = SND_SOC_DAIFMT_DSP_A |
430 SND_SOC_DAIFMT_IB_NF |
431 SND_SOC_DAIFMT_CBM_CFM;
432
433 break;
434 default:
435 return -EINVAL;
436 }
437
438 return 0;
439}
440EXPORT_SYMBOL_GPL(wl1273_get_format);
441
442static int wl1273_probe(struct snd_soc_codec *codec)
443{
444 struct wl1273_core **core = codec->dev->platform_data;
445 struct wl1273_priv *wl1273;
446 int r;
447
448 dev_dbg(codec->dev, "%s.\n", __func__);
449
450 if (!core) {
451 dev_err(codec->dev, "Platform data is missing.\n");
452 return -EINVAL;
453 }
454
455 wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
456 if (wl1273 == NULL) {
457 dev_err(codec->dev, "Cannot allocate memory.\n");
458 return -ENOMEM;
459 }
460
461 wl1273->mode = WL1273_MODE_BT;
462 wl1273->core = *core;
463
464 snd_soc_codec_set_drvdata(codec, wl1273);
465 mutex_init(&codec->mutex);
466
467 r = snd_soc_add_controls(codec, wl1273_controls,
468 ARRAY_SIZE(wl1273_controls));
469 if (r)
470 kfree(wl1273);
471
472 return r;
473}
474
475static int wl1273_remove(struct snd_soc_codec *codec)
476{
477 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
478
479 dev_dbg(codec->dev, "%s\n", __func__);
480 kfree(wl1273);
481
482 return 0;
483}
484
485static struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
486 .probe = wl1273_probe,
487 .remove = wl1273_remove,
488};
489
490static int __devinit wl1273_platform_probe(struct platform_device *pdev)
491{
492 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
493 &wl1273_dai, 1);
494}
495
496static int __devexit wl1273_platform_remove(struct platform_device *pdev)
497{
498 snd_soc_unregister_codec(&pdev->dev);
499 return 0;
500}
501
502MODULE_ALIAS("platform:wl1273-codec");
503
504static struct platform_driver wl1273_platform_driver = {
505 .driver = {
506 .name = "wl1273-codec",
507 .owner = THIS_MODULE,
508 },
509 .probe = wl1273_platform_probe,
510 .remove = __devexit_p(wl1273_platform_remove),
511};
512
513static int __init wl1273_init(void)
514{
515 return platform_driver_register(&wl1273_platform_driver);
516}
517module_init(wl1273_init);
518
519static void __exit wl1273_exit(void)
520{
521 platform_driver_unregister(&wl1273_platform_driver);
522}
523module_exit(wl1273_exit);
524
525MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
526MODULE_DESCRIPTION("ASoC WL1273 codec driver");
527MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wl1273.h b/sound/soc/codecs/wl1273.h
new file mode 100644
index 000000000000..43ec7e668c51
--- /dev/null
+++ b/sound/soc/codecs/wl1273.h
@@ -0,0 +1,30 @@
1/*
2 * sound/soc/codec/wl1273.h
3 *
4 * ALSA SoC WL1273 codec driver
5 *
6 * Copyright (C) Nokia Corporation
7 * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __WL1273_CODEC_H__
26#define __WL1273_CODEC_H__
27
28int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt);
29
30#endif /* End of __WL1273_CODEC_H__ */
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
new file mode 100644
index 000000000000..bcc208967917
--- /dev/null
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -0,0 +1,108 @@
1/*
2 * Driver for the 1250-EV1 audio I/O module
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16
17#include <sound/soc.h>
18#include <sound/soc-dapm.h>
19
20static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = {
21SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0),
22SND_SOC_DAPM_DAC("DAC", "wm1250-ev1 Playback", SND_SOC_NOPM, 0, 0),
23
24SND_SOC_DAPM_INPUT("WM1250 Input"),
25SND_SOC_DAPM_OUTPUT("WM1250 Output"),
26};
27
28static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = {
29 { "ADC", NULL, "WM1250 Input" },
30 { "WM1250 Output", NULL, "DAC" },
31};
32
33static struct snd_soc_dai_driver wm1250_ev1_dai = {
34 .name = "wm1250-ev1",
35 .playback = {
36 .stream_name = "Playback",
37 .channels_min = 1,
38 .channels_max = 1,
39 .rates = SNDRV_PCM_RATE_8000,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE,
41 },
42 .capture = {
43 .stream_name = "Capture",
44 .channels_min = 1,
45 .channels_max = 1,
46 .rates = SNDRV_PCM_RATE_8000,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 },
49};
50
51static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
52 .dapm_widgets = wm1250_ev1_dapm_widgets,
53 .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets),
54 .dapm_routes = wm1250_ev1_dapm_routes,
55 .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes),
56};
57
58static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
59 const struct i2c_device_id *id)
60{
61 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1,
62 &wm1250_ev1_dai, 1);
63}
64
65static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
66{
67 snd_soc_unregister_codec(&i2c->dev);
68
69 return 0;
70}
71
72static const struct i2c_device_id wm1250_ev1_i2c_id[] = {
73 { "wm1250-ev1", 0 },
74 { }
75};
76MODULE_DEVICE_TABLE(i2c, wm1250_ev1_i2c_id);
77
78static struct i2c_driver wm1250_ev1_i2c_driver = {
79 .driver = {
80 .name = "wm1250-ev1",
81 .owner = THIS_MODULE,
82 },
83 .probe = wm1250_ev1_probe,
84 .remove = __devexit_p(wm1250_ev1_remove),
85 .id_table = wm1250_ev1_i2c_id,
86};
87
88static int __init wm1250_ev1_modinit(void)
89{
90 int ret = 0;
91
92 ret = i2c_add_driver(&wm1250_ev1_i2c_driver);
93 if (ret != 0)
94 pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret);
95
96 return ret;
97}
98module_init(wm1250_ev1_modinit);
99
100static void __exit wm1250_ev1_exit(void)
101{
102 i2c_del_driver(&wm1250_ev1_i2c_driver);
103}
104module_exit(wm1250_ev1_exit);
105
106MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
107MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver");
108MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 4bcd168794e1..a3b9cbb20ee9 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -36,7 +36,6 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h> 39#include <sound/initval.h>
41#include <sound/tlv.h> 40#include <sound/tlv.h>
42 41
@@ -705,6 +704,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
705/* Called from the machine driver */ 704/* Called from the machine driver */
706int wm2000_add_controls(struct snd_soc_codec *codec) 705int wm2000_add_controls(struct snd_soc_codec *codec)
707{ 706{
707 struct snd_soc_dapm_context *dapm = &codec->dapm;
708 int ret; 708 int ret;
709 709
710 if (!wm2000_i2c) { 710 if (!wm2000_i2c) {
@@ -712,12 +712,12 @@ int wm2000_add_controls(struct snd_soc_codec *codec)
712 return -ENODEV; 712 return -ENODEV;
713 } 713 }
714 714
715 ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets, 715 ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets,
716 ARRAY_SIZE(wm2000_dapm_widgets)); 716 ARRAY_SIZE(wm2000_dapm_widgets));
717 if (ret < 0) 717 if (ret < 0)
718 return ret; 718 return ret;
719 719
720 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 720 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
721 if (ret < 0) 721 if (ret < 0)
722 return ret; 722 return ret;
723 723
@@ -836,24 +836,25 @@ static void wm2000_i2c_shutdown(struct i2c_client *i2c)
836} 836}
837 837
838#ifdef CONFIG_PM 838#ifdef CONFIG_PM
839static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) 839static int wm2000_i2c_suspend(struct device *dev)
840{ 840{
841 struct i2c_client *i2c = to_i2c_client(dev);
841 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 842 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
842 843
843 return wm2000_anc_transition(wm2000, ANC_OFF); 844 return wm2000_anc_transition(wm2000, ANC_OFF);
844} 845}
845 846
846static int wm2000_i2c_resume(struct i2c_client *i2c) 847static int wm2000_i2c_resume(struct device *dev)
847{ 848{
849 struct i2c_client *i2c = to_i2c_client(dev);
848 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); 850 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
849 851
850 return wm2000_anc_set_mode(wm2000); 852 return wm2000_anc_set_mode(wm2000);
851} 853}
852#else
853#define wm2000_i2c_suspend NULL
854#define wm2000_i2c_resume NULL
855#endif 854#endif
856 855
856static SIMPLE_DEV_PM_OPS(wm2000_pm, wm2000_i2c_suspend, wm2000_i2c_resume);
857
857static const struct i2c_device_id wm2000_i2c_id[] = { 858static const struct i2c_device_id wm2000_i2c_id[] = {
858 { "wm2000", 0 }, 859 { "wm2000", 0 },
859 { } 860 { }
@@ -864,11 +865,10 @@ static struct i2c_driver wm2000_i2c_driver = {
864 .driver = { 865 .driver = {
865 .name = "wm2000", 866 .name = "wm2000",
866 .owner = THIS_MODULE, 867 .owner = THIS_MODULE,
868 .pm = &wm2000_pm,
867 }, 869 },
868 .probe = wm2000_i2c_probe, 870 .probe = wm2000_i2c_probe,
869 .remove = __devexit_p(wm2000_i2c_remove), 871 .remove = __devexit_p(wm2000_i2c_remove),
870 .suspend = wm2000_i2c_suspend,
871 .resume = wm2000_i2c_resume,
872 .shutdown = wm2000_i2c_shutdown, 872 .shutdown = wm2000_i2c_shutdown,
873 .id_table = wm2000_i2c_id, 873 .id_table = wm2000_i2c_id,
874}; 874};
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
index c18e261c3c7f..0b6f056f73cc 100644
--- a/sound/soc/codecs/wm2000.h
+++ b/sound/soc/codecs/wm2000.h
@@ -16,9 +16,6 @@ struct wm2000_setup_data {
16 16
17extern int wm2000_add_controls(struct snd_soc_codec *codec); 17extern int wm2000_add_controls(struct snd_soc_codec *codec);
18 18
19extern struct snd_soc_dai wm2000_dai;
20extern struct snd_soc_codec_device soc_codec_dev_wm2000;
21
22#define WM2000_REG_SYS_START 0x8000 19#define WM2000_REG_SYS_START 0x8000
23#define WM2000_REG_SPEECH_CLARITY 0x8fef 20#define WM2000_REG_SPEECH_CLARITY 0x8fef
24#define WM2000_REG_SYS_WATCHDOG 0x8ff6 21#define WM2000_REG_SYS_WATCHDOG 0x8ff6
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 0221ca79b3ae..6d6dc9efe914 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -24,9 +24,9 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <trace/events/asoc.h>
30 30
31#include "wm8350.h" 31#include "wm8350.h"
32 32
@@ -54,6 +54,7 @@ struct wm8350_output {
54 54
55struct wm8350_jack_data { 55struct wm8350_jack_data {
56 struct snd_soc_jack *jack; 56 struct snd_soc_jack *jack;
57 struct delayed_work work;
57 int report; 58 int report;
58 int short_report; 59 int short_report;
59}; 60};
@@ -230,8 +231,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
230 */ 231 */
231static void wm8350_pga_work(struct work_struct *work) 232static void wm8350_pga_work(struct work_struct *work)
232{ 233{
233 struct snd_soc_codec *codec = 234 struct snd_soc_dapm_context *dapm =
234 container_of(work, struct snd_soc_codec, delayed_work.work); 235 container_of(work, struct snd_soc_dapm_context, delayed_work.work);
236 struct snd_soc_codec *codec = dapm->codec;
235 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); 237 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
236 struct wm8350_output *out1 = &wm8350_data->out1, 238 struct wm8350_output *out1 = &wm8350_data->out1,
237 *out2 = &wm8350_data->out2; 239 *out2 = &wm8350_data->out2;
@@ -302,8 +304,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
302 out->ramp = WM8350_RAMP_UP; 304 out->ramp = WM8350_RAMP_UP;
303 out->active = 1; 305 out->active = 1;
304 306
305 if (!delayed_work_pending(&codec->delayed_work)) 307 if (!delayed_work_pending(&codec->dapm.delayed_work))
306 schedule_delayed_work(&codec->delayed_work, 308 schedule_delayed_work(&codec->dapm.delayed_work,
307 msecs_to_jiffies(1)); 309 msecs_to_jiffies(1));
308 break; 310 break;
309 311
@@ -311,8 +313,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
311 out->ramp = WM8350_RAMP_DOWN; 313 out->ramp = WM8350_RAMP_DOWN;
312 out->active = 0; 314 out->active = 0;
313 315
314 if (!delayed_work_pending(&codec->delayed_work)) 316 if (!delayed_work_pending(&codec->dapm.delayed_work))
315 schedule_delayed_work(&codec->delayed_work, 317 schedule_delayed_work(&codec->dapm.delayed_work,
316 msecs_to_jiffies(1)); 318 msecs_to_jiffies(1));
317 break; 319 break;
318 } 320 }
@@ -786,9 +788,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
786 788
787static int wm8350_add_widgets(struct snd_soc_codec *codec) 789static int wm8350_add_widgets(struct snd_soc_codec *codec)
788{ 790{
791 struct snd_soc_dapm_context *dapm = &codec->dapm;
789 int ret; 792 int ret;
790 793
791 ret = snd_soc_dapm_new_controls(codec, 794 ret = snd_soc_dapm_new_controls(dapm,
792 wm8350_dapm_widgets, 795 wm8350_dapm_widgets,
793 ARRAY_SIZE(wm8350_dapm_widgets)); 796 ARRAY_SIZE(wm8350_dapm_widgets));
794 if (ret != 0) { 797 if (ret != 0) {
@@ -797,7 +800,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
797 } 800 }
798 801
799 /* set up audio paths */ 802 /* set up audio paths */
800 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 803 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
801 if (ret != 0) { 804 if (ret != 0) {
802 dev_err(codec->dev, "DAPM route register failed\n"); 805 dev_err(codec->dev, "DAPM route register failed\n");
803 return ret; 806 return ret;
@@ -831,7 +834,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
831 } 834 }
832 835
833 /* MCLK direction */ 836 /* MCLK direction */
834 if (dir == WM8350_MCLK_DIR_OUT) 837 if (dir == SND_SOC_CLOCK_OUT)
835 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2, 838 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
836 WM8350_MCLK_DIR); 839 WM8350_MCLK_DIR);
837 else 840 else
@@ -1184,7 +1187,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1184 break; 1187 break;
1185 1188
1186 case SND_SOC_BIAS_STANDBY: 1189 case SND_SOC_BIAS_STANDBY:
1187 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1190 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1188 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), 1191 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
1189 priv->supplies); 1192 priv->supplies);
1190 if (ret != 0) 1193 if (ret != 0)
@@ -1317,68 +1320,86 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1317 priv->supplies); 1320 priv->supplies);
1318 break; 1321 break;
1319 } 1322 }
1320 codec->bias_level = level; 1323 codec->dapm.bias_level = level;
1321 return 0; 1324 return 0;
1322} 1325}
1323 1326
1324static int wm8350_suspend(struct platform_device *pdev, pm_message_t state) 1327static int wm8350_suspend(struct snd_soc_codec *codec, pm_message_t state)
1325{ 1328{
1326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1327 struct snd_soc_codec *codec = socdev->card->codec;
1328
1329 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1329 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1330 return 0; 1330 return 0;
1331} 1331}
1332 1332
1333static int wm8350_resume(struct platform_device *pdev) 1333static int wm8350_resume(struct snd_soc_codec *codec)
1334{ 1334{
1335 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1336 struct snd_soc_codec *codec = socdev->card->codec;
1337
1338 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1335 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339 1336
1340 return 0; 1337 return 0;
1341} 1338}
1342 1339
1343static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) 1340static void wm8350_hp_work(struct wm8350_data *priv,
1341 struct wm8350_jack_data *jack,
1342 u16 mask)
1344{ 1343{
1345 struct wm8350_data *priv = data;
1346 struct wm8350 *wm8350 = priv->codec.control_data; 1344 struct wm8350 *wm8350 = priv->codec.control_data;
1347 u16 reg; 1345 u16 reg;
1348 int report; 1346 int report;
1349 int mask; 1347
1348 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1349 if (reg & mask)
1350 report = jack->report;
1351 else
1352 report = 0;
1353
1354 snd_soc_jack_report(jack->jack, report, jack->report);
1355
1356}
1357
1358static void wm8350_hpl_work(struct work_struct *work)
1359{
1360 struct wm8350_data *priv =
1361 container_of(work, struct wm8350_data, hpl.work.work);
1362
1363 wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL);
1364}
1365
1366static void wm8350_hpr_work(struct work_struct *work)
1367{
1368 struct wm8350_data *priv =
1369 container_of(work, struct wm8350_data, hpr.work.work);
1370
1371 wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
1372}
1373
1374static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1375{
1376 struct wm8350_data *priv = data;
1377 struct wm8350 *wm8350 = priv->codec.control_data;
1350 struct wm8350_jack_data *jack = NULL; 1378 struct wm8350_jack_data *jack = NULL;
1351 1379
1352 switch (irq - wm8350->irq_base) { 1380 switch (irq - wm8350->irq_base) {
1353 case WM8350_IRQ_CODEC_JCK_DET_L: 1381 case WM8350_IRQ_CODEC_JCK_DET_L:
1382#ifndef CONFIG_SND_SOC_WM8350_MODULE
1383 trace_snd_soc_jack_irq("WM8350 HPL");
1384#endif
1354 jack = &priv->hpl; 1385 jack = &priv->hpl;
1355 mask = WM8350_JACK_L_LVL;
1356 break; 1386 break;
1357 1387
1358 case WM8350_IRQ_CODEC_JCK_DET_R: 1388 case WM8350_IRQ_CODEC_JCK_DET_R:
1389#ifndef CONFIG_SND_SOC_WM8350_MODULE
1390 trace_snd_soc_jack_irq("WM8350 HPR");
1391#endif
1359 jack = &priv->hpr; 1392 jack = &priv->hpr;
1360 mask = WM8350_JACK_R_LVL;
1361 break; 1393 break;
1362 1394
1363 default: 1395 default:
1364 BUG(); 1396 BUG();
1365 } 1397 }
1366 1398
1367 if (!jack->jack) { 1399 if (device_may_wakeup(wm8350->dev))
1368 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); 1400 pm_wakeup_event(wm8350->dev, 250);
1369 return IRQ_NONE;
1370 }
1371
1372 /* Debounce */
1373 msleep(200);
1374
1375 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1376 if (reg & mask)
1377 report = jack->report;
1378 else
1379 report = 0;
1380 1401
1381 snd_soc_jack_report(jack->jack, report, jack->report); 1402 schedule_delayed_work(&jack->work, 200);
1382 1403
1383 return IRQ_HANDLED; 1404 return IRQ_HANDLED;
1384} 1405}
@@ -1442,6 +1463,10 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
1442 u16 reg; 1463 u16 reg;
1443 int report = 0; 1464 int report = 0;
1444 1465
1466#ifndef CONFIG_SND_SOC_WM8350_MODULE
1467 trace_snd_soc_jack_irq("WM8350 mic");
1468#endif
1469
1445 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); 1470 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1446 if (reg & WM8350_JACK_MICSCD_LVL) 1471 if (reg & WM8350_JACK_MICSCD_LVL)
1447 report |= priv->mic.short_report; 1472 report |= priv->mic.short_report;
@@ -1489,24 +1514,76 @@ int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1489} 1514}
1490EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); 1515EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1491 1516
1492static struct snd_soc_codec *wm8350_codec; 1517#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1518
1519#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1520 SNDRV_PCM_FMTBIT_S20_3LE |\
1521 SNDRV_PCM_FMTBIT_S24_LE)
1522
1523static struct snd_soc_dai_ops wm8350_dai_ops = {
1524 .hw_params = wm8350_pcm_hw_params,
1525 .digital_mute = wm8350_mute,
1526 .trigger = wm8350_pcm_trigger,
1527 .set_fmt = wm8350_set_dai_fmt,
1528 .set_sysclk = wm8350_set_dai_sysclk,
1529 .set_pll = wm8350_set_fll,
1530 .set_clkdiv = wm8350_set_clkdiv,
1531};
1532
1533static struct snd_soc_dai_driver wm8350_dai = {
1534 .name = "wm8350-hifi",
1535 .playback = {
1536 .stream_name = "Playback",
1537 .channels_min = 1,
1538 .channels_max = 2,
1539 .rates = WM8350_RATES,
1540 .formats = WM8350_FORMATS,
1541 },
1542 .capture = {
1543 .stream_name = "Capture",
1544 .channels_min = 1,
1545 .channels_max = 2,
1546 .rates = WM8350_RATES,
1547 .formats = WM8350_FORMATS,
1548 },
1549 .ops = &wm8350_dai_ops,
1550};
1493 1551
1494static int wm8350_probe(struct platform_device *pdev) 1552static int wm8350_codec_probe(struct snd_soc_codec *codec)
1495{ 1553{
1496 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1554 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1497 struct snd_soc_codec *codec;
1498 struct wm8350 *wm8350;
1499 struct wm8350_data *priv; 1555 struct wm8350_data *priv;
1500 int ret;
1501 struct wm8350_output *out1; 1556 struct wm8350_output *out1;
1502 struct wm8350_output *out2; 1557 struct wm8350_output *out2;
1558 int ret, i;
1559
1560 if (wm8350->codec.platform_data == NULL) {
1561 dev_err(codec->dev, "No audio platform data supplied\n");
1562 return -EINVAL;
1563 }
1564
1565 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1566 if (priv == NULL)
1567 return -ENOMEM;
1568 snd_soc_codec_set_drvdata(codec, priv);
1503 1569
1504 BUG_ON(!wm8350_codec); 1570 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1571 priv->supplies[i].supply = supply_names[i];
1505 1572
1506 socdev->card->codec = wm8350_codec; 1573 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1507 codec = socdev->card->codec; 1574 priv->supplies);
1508 wm8350 = codec->control_data; 1575 if (ret != 0)
1509 priv = snd_soc_codec_get_drvdata(codec); 1576 goto err_priv;
1577
1578 wm8350->codec.codec = codec;
1579 codec->control_data = wm8350;
1580
1581 /* Put the codec into reset if it wasn't already */
1582 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1583
1584 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work);
1585 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
1586 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
1510 1587
1511 /* Enable the codec */ 1588 /* Enable the codec */
1512 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1589 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1542,6 +1619,13 @@ static int wm8350_probe(struct platform_device *pdev)
1542 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, 1619 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1543 WM8350_OUT2_VU | WM8350_OUT2R_MUTE); 1620 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1544 1621
1622 /* Make sure AIF tristating is disabled by default */
1623 wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
1624
1625 /* Make sure we've got a sane companding setup too */
1626 wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
1627 WM8350_DAC_COMP | WM8350_LOOPBACK);
1628
1545 /* Make sure jack detect is disabled to start off with */ 1629 /* Make sure jack detect is disabled to start off with */
1546 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1630 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1547 WM8350_JDL_ENA | WM8350_JDR_ENA); 1631 WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1557,11 +1641,6 @@ static int wm8350_probe(struct platform_device *pdev)
1557 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, 1641 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
1558 wm8350_mic_handler, 0, "Microphone detect", priv); 1642 wm8350_mic_handler, 0, "Microphone detect", priv);
1559 1643
1560 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1561 if (ret < 0) {
1562 dev_err(&pdev->dev, "failed to create pcms\n");
1563 return ret;
1564 }
1565 1644
1566 snd_soc_add_controls(codec, wm8350_snd_controls, 1645 snd_soc_add_controls(codec, wm8350_snd_controls,
1567 ARRAY_SIZE(wm8350_snd_controls)); 1646 ARRAY_SIZE(wm8350_snd_controls));
@@ -1570,15 +1649,16 @@ static int wm8350_probe(struct platform_device *pdev)
1570 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1649 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1571 1650
1572 return 0; 1651 return 0;
1652
1653err_priv:
1654 kfree(priv);
1655 return ret;
1573} 1656}
1574 1657
1575static int wm8350_remove(struct platform_device *pdev) 1658static int wm8350_codec_remove(struct snd_soc_codec *codec)
1576{ 1659{
1577 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1578 struct snd_soc_codec *codec = socdev->card->codec;
1579 struct wm8350 *wm8350 = codec->control_data;
1580 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1660 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1581 int ret; 1661 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1582 1662
1583 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1663 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1584 WM8350_JDL_ENA | WM8350_JDR_ENA); 1664 WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1593,148 +1673,41 @@ static int wm8350_remove(struct platform_device *pdev)
1593 priv->hpr.jack = NULL; 1673 priv->hpr.jack = NULL;
1594 priv->mic.jack = NULL; 1674 priv->mic.jack = NULL;
1595 1675
1596 /* cancel any work waiting to be queued. */ 1676 cancel_delayed_work_sync(&priv->hpl.work);
1597 ret = cancel_delayed_work(&codec->delayed_work); 1677 cancel_delayed_work_sync(&priv->hpr.work);
1598 1678
1599 /* if there was any work waiting then we run it now and 1679 /* if there was any work waiting then we run it now and
1600 * wait for its completion */ 1680 * wait for its completion */
1601 if (ret) { 1681 flush_delayed_work_sync(&codec->dapm.delayed_work);
1602 schedule_delayed_work(&codec->delayed_work, 0);
1603 flush_scheduled_work();
1604 }
1605 1682
1606 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1683 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1607 1684
1608 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1685 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1609 1686
1687 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1688 kfree(priv);
1610 return 0; 1689 return 0;
1611} 1690}
1612 1691
1613#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000) 1692static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
1614 1693 .probe = wm8350_codec_probe,
1615#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 1694 .remove = wm8350_codec_remove,
1616 SNDRV_PCM_FMTBIT_S20_3LE |\
1617 SNDRV_PCM_FMTBIT_S24_LE)
1618
1619static struct snd_soc_dai_ops wm8350_dai_ops = {
1620 .hw_params = wm8350_pcm_hw_params,
1621 .digital_mute = wm8350_mute,
1622 .trigger = wm8350_pcm_trigger,
1623 .set_fmt = wm8350_set_dai_fmt,
1624 .set_sysclk = wm8350_set_dai_sysclk,
1625 .set_pll = wm8350_set_fll,
1626 .set_clkdiv = wm8350_set_clkdiv,
1627};
1628
1629struct snd_soc_dai wm8350_dai = {
1630 .name = "WM8350",
1631 .playback = {
1632 .stream_name = "Playback",
1633 .channels_min = 1,
1634 .channels_max = 2,
1635 .rates = WM8350_RATES,
1636 .formats = WM8350_FORMATS,
1637 },
1638 .capture = {
1639 .stream_name = "Capture",
1640 .channels_min = 1,
1641 .channels_max = 2,
1642 .rates = WM8350_RATES,
1643 .formats = WM8350_FORMATS,
1644 },
1645 .ops = &wm8350_dai_ops,
1646};
1647EXPORT_SYMBOL_GPL(wm8350_dai);
1648
1649struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1650 .probe = wm8350_probe,
1651 .remove = wm8350_remove,
1652 .suspend = wm8350_suspend, 1695 .suspend = wm8350_suspend,
1653 .resume = wm8350_resume, 1696 .resume = wm8350_resume,
1697 .read = wm8350_codec_read,
1698 .write = wm8350_codec_write,
1699 .set_bias_level = wm8350_set_bias_level,
1654}; 1700};
1655EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1656 1701
1657static __devinit int wm8350_codec_probe(struct platform_device *pdev) 1702static int __devinit wm8350_probe(struct platform_device *pdev)
1658{ 1703{
1659 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1704 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
1660 struct wm8350_data *priv; 1705 &wm8350_dai, 1);
1661 struct snd_soc_codec *codec;
1662 int ret, i;
1663
1664 if (wm8350->codec.platform_data == NULL) {
1665 dev_err(&pdev->dev, "No audio platform data supplied\n");
1666 return -EINVAL;
1667 }
1668
1669 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1670 if (priv == NULL)
1671 return -ENOMEM;
1672
1673 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1674 priv->supplies[i].supply = supply_names[i];
1675
1676 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1677 priv->supplies);
1678 if (ret != 0)
1679 goto err_priv;
1680
1681 codec = &priv->codec;
1682 wm8350->codec.codec = codec;
1683
1684 wm8350_dai.dev = &pdev->dev;
1685
1686 mutex_init(&codec->mutex);
1687 INIT_LIST_HEAD(&codec->dapm_widgets);
1688 INIT_LIST_HEAD(&codec->dapm_paths);
1689 codec->dev = &pdev->dev;
1690 codec->name = "WM8350";
1691 codec->owner = THIS_MODULE;
1692 codec->read = wm8350_codec_read;
1693 codec->write = wm8350_codec_write;
1694 codec->bias_level = SND_SOC_BIAS_OFF;
1695 codec->set_bias_level = wm8350_set_bias_level;
1696 codec->dai = &wm8350_dai;
1697 codec->num_dai = 1;
1698 codec->reg_cache_size = WM8350_MAX_REGISTER;
1699 snd_soc_codec_set_drvdata(codec, priv);
1700 codec->control_data = wm8350;
1701
1702 /* Put the codec into reset if it wasn't already */
1703 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1704
1705 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1706 ret = snd_soc_register_codec(codec);
1707 if (ret != 0)
1708 goto err_supply;
1709
1710 wm8350_codec = codec;
1711
1712 ret = snd_soc_register_dai(&wm8350_dai);
1713 if (ret != 0)
1714 goto err_codec;
1715 return 0;
1716
1717err_codec:
1718 snd_soc_unregister_codec(codec);
1719err_supply:
1720 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1721err_priv:
1722 kfree(priv);
1723 wm8350_codec = NULL;
1724 return ret;
1725} 1706}
1726 1707
1727static int __devexit wm8350_codec_remove(struct platform_device *pdev) 1708static int __devexit wm8350_remove(struct platform_device *pdev)
1728{ 1709{
1729 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1710 snd_soc_unregister_codec(&pdev->dev);
1730 struct snd_soc_codec *codec = wm8350->codec.codec;
1731 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1732
1733 snd_soc_unregister_dai(&wm8350_dai);
1734 snd_soc_unregister_codec(codec);
1735 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1736 kfree(priv);
1737 wm8350_codec = NULL;
1738 return 0; 1711 return 0;
1739} 1712}
1740 1713
@@ -1743,8 +1716,8 @@ static struct platform_driver wm8350_codec_driver = {
1743 .name = "wm8350-codec", 1716 .name = "wm8350-codec",
1744 .owner = THIS_MODULE, 1717 .owner = THIS_MODULE,
1745 }, 1718 },
1746 .probe = wm8350_codec_probe, 1719 .probe = wm8350_probe,
1747 .remove = __devexit_p(wm8350_codec_remove), 1720 .remove = __devexit_p(wm8350_remove),
1748}; 1721};
1749 1722
1750static __init int wm8350_init(void) 1723static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index 9ed0467c71db..74108eb82938 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -15,9 +15,6 @@
15#include <sound/soc.h> 15#include <sound/soc.h>
16#include <linux/mfd/wm8350/audio.h> 16#include <linux/mfd/wm8350/audio.h>
17 17
18extern struct snd_soc_dai wm8350_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8350;
20
21enum wm8350_jack { 18enum wm8350_jack {
22 WM8350_JDL = 1, 19 WM8350_JDL = 1,
23 WM8350_JDR = 2, 20 WM8350_JDR = 2,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 8f294066b0ed..fbee556cbf35 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -22,11 +22,11 @@
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/mfd/wm8400-audio.h> 23#include <linux/mfd/wm8400-audio.h>
24#include <linux/mfd/wm8400-private.h> 24#include <linux/mfd/wm8400-private.h>
25#include <linux/mfd/core.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
28#include <sound/soc.h> 29#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/tlv.h> 31#include <sound/tlv.h>
32 32
@@ -65,7 +65,7 @@ static struct regulator_bulk_data power[] = {
65 65
66/* codec private data */ 66/* codec private data */
67struct wm8400_priv { 67struct wm8400_priv {
68 struct snd_soc_codec codec; 68 struct snd_soc_codec *codec;
69 struct wm8400 *wm8400; 69 struct wm8400 *wm8400;
70 u16 fake_register; 70 u16 fake_register;
71 unsigned int sysclk; 71 unsigned int sysclk;
@@ -911,10 +911,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
911 911
912static int wm8400_add_widgets(struct snd_soc_codec *codec) 912static int wm8400_add_widgets(struct snd_soc_codec *codec)
913{ 913{
914 snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets, 914 struct snd_soc_dapm_context *dapm = &codec->dapm;
915 ARRAY_SIZE(wm8400_dapm_widgets));
916 915
917 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 916 snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets,
917 ARRAY_SIZE(wm8400_dapm_widgets));
918 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
918 919
919 return 0; 920 return 0;
920} 921}
@@ -1163,8 +1164,7 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
1163 struct snd_soc_dai *dai) 1164 struct snd_soc_dai *dai)
1164{ 1165{
1165 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1166 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1166 struct snd_soc_device *socdev = rtd->socdev; 1167 struct snd_soc_codec *codec = rtd->codec;
1167 struct snd_soc_codec *codec = socdev->card->codec;
1168 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); 1168 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
1169 1169
1170 audio1 &= ~WM8400_AIF_WL_MASK; 1170 audio1 &= ~WM8400_AIF_WL_MASK;
@@ -1220,7 +1220,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1220 break; 1220 break;
1221 1221
1222 case SND_SOC_BIAS_STANDBY: 1222 case SND_SOC_BIAS_STANDBY:
1223 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1223 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1224 ret = regulator_bulk_enable(ARRAY_SIZE(power), 1224 ret = regulator_bulk_enable(ARRAY_SIZE(power),
1225 &power[0]); 1225 &power[0]);
1226 if (ret != 0) { 1226 if (ret != 0) {
@@ -1307,7 +1307,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1307 break; 1307 break;
1308 } 1308 }
1309 1309
1310 codec->bias_level = level; 1310 codec->dapm.bias_level = level;
1311 return 0; 1311 return 0;
1312} 1312}
1313 1313
@@ -1332,10 +1332,9 @@ static struct snd_soc_dai_ops wm8400_dai_ops = {
1332 * 1. ADC/DAC on Primary Interface 1332 * 1. ADC/DAC on Primary Interface
1333 * 2. ADC on Primary Interface/DAC on secondary 1333 * 2. ADC on Primary Interface/DAC on secondary
1334 */ 1334 */
1335struct snd_soc_dai wm8400_dai = { 1335static struct snd_soc_dai_driver wm8400_dai = {
1336/* ADC/DAC on primary */ 1336/* ADC/DAC on primary */
1337 .name = "WM8400 ADC/DAC Primary", 1337 .name = "wm8400-hifi",
1338 .id = 1,
1339 .playback = { 1338 .playback = {
1340 .stream_name = "Playback", 1339 .stream_name = "Playback",
1341 .channels_min = 1, 1340 .channels_min = 1,
@@ -1352,147 +1351,53 @@ struct snd_soc_dai wm8400_dai = {
1352 }, 1351 },
1353 .ops = &wm8400_dai_ops, 1352 .ops = &wm8400_dai_ops,
1354}; 1353};
1355EXPORT_SYMBOL_GPL(wm8400_dai);
1356 1354
1357static int wm8400_suspend(struct platform_device *pdev, pm_message_t state) 1355static int wm8400_suspend(struct snd_soc_codec *codec, pm_message_t state)
1358{ 1356{
1359 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1360 struct snd_soc_codec *codec = socdev->card->codec;
1361
1362 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); 1357 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
1363 1358
1364 return 0; 1359 return 0;
1365} 1360}
1366 1361
1367static int wm8400_resume(struct platform_device *pdev) 1362static int wm8400_resume(struct snd_soc_codec *codec)
1368{ 1363{
1369 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1370 struct snd_soc_codec *codec = socdev->card->codec;
1371
1372 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1364 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1373 1365
1374 return 0; 1366 return 0;
1375} 1367}
1376 1368
1377static struct snd_soc_codec *wm8400_codec;
1378
1379static int wm8400_probe(struct platform_device *pdev)
1380{
1381 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1382 struct snd_soc_codec *codec;
1383 int ret;
1384
1385 if (!wm8400_codec) {
1386 dev_err(&pdev->dev, "wm8400 not yet discovered\n");
1387 return -ENODEV;
1388 }
1389 codec = wm8400_codec;
1390
1391 socdev->card->codec = codec;
1392
1393 /* register pcms */
1394 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1395 if (ret < 0) {
1396 dev_err(&pdev->dev, "failed to create pcms\n");
1397 goto pcm_err;
1398 }
1399
1400 wm8400_add_controls(codec);
1401 wm8400_add_widgets(codec);
1402
1403pcm_err:
1404 return ret;
1405}
1406
1407/* power down chip */
1408static int wm8400_remove(struct platform_device *pdev)
1409{
1410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1411
1412 snd_soc_free_pcms(socdev);
1413 snd_soc_dapm_free(socdev);
1414
1415 return 0;
1416}
1417
1418struct snd_soc_codec_device soc_codec_dev_wm8400 = {
1419 .probe = wm8400_probe,
1420 .remove = wm8400_remove,
1421 .suspend = wm8400_suspend,
1422 .resume = wm8400_resume,
1423};
1424
1425static void wm8400_probe_deferred(struct work_struct *work) 1369static void wm8400_probe_deferred(struct work_struct *work)
1426{ 1370{
1427 struct wm8400_priv *priv = container_of(work, struct wm8400_priv, 1371 struct wm8400_priv *priv = container_of(work, struct wm8400_priv,
1428 work); 1372 work);
1429 struct snd_soc_codec *codec = &priv->codec; 1373 struct snd_soc_codec *codec = priv->codec;
1430 int ret;
1431 1374
1432 /* charge output caps */ 1375 /* charge output caps */
1433 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1376 wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1434
1435 /* We're done, tell the subsystem. */
1436 ret = snd_soc_register_codec(codec);
1437 if (ret != 0) {
1438 dev_err(priv->wm8400->dev,
1439 "Failed to register codec: %d\n", ret);
1440 goto err;
1441 }
1442
1443 ret = snd_soc_register_dai(&wm8400_dai);
1444 if (ret != 0) {
1445 dev_err(priv->wm8400->dev,
1446 "Failed to register DAI: %d\n", ret);
1447 goto err_codec;
1448 }
1449
1450 return;
1451
1452err_codec:
1453 snd_soc_unregister_codec(codec);
1454err:
1455 wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
1456} 1377}
1457 1378
1458static int wm8400_codec_probe(struct platform_device *dev) 1379static int wm8400_codec_probe(struct snd_soc_codec *codec)
1459{ 1380{
1381 struct wm8400 *wm8400 = dev_get_platdata(codec->dev);
1460 struct wm8400_priv *priv; 1382 struct wm8400_priv *priv;
1461 int ret; 1383 int ret;
1462 u16 reg; 1384 u16 reg;
1463 struct snd_soc_codec *codec;
1464 1385
1465 priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL); 1386 priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL);
1466 if (priv == NULL) 1387 if (priv == NULL)
1467 return -ENOMEM; 1388 return -ENOMEM;
1468 1389
1469 codec = &priv->codec;
1470 snd_soc_codec_set_drvdata(codec, priv); 1390 snd_soc_codec_set_drvdata(codec, priv);
1471 codec->control_data = dev_get_drvdata(&dev->dev); 1391 codec->control_data = priv->wm8400 = wm8400;
1472 priv->wm8400 = dev_get_drvdata(&dev->dev); 1392 priv->codec = codec;
1473 1393
1474 ret = regulator_bulk_get(priv->wm8400->dev, 1394 ret = regulator_bulk_get(wm8400->dev,
1475 ARRAY_SIZE(power), &power[0]); 1395 ARRAY_SIZE(power), &power[0]);
1476 if (ret != 0) { 1396 if (ret != 0) {
1477 dev_err(&dev->dev, "Failed to get regulators: %d\n", ret); 1397 dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
1478 goto err; 1398 goto err;
1479 } 1399 }
1480 1400
1481 codec->dev = &dev->dev;
1482 wm8400_dai.dev = &dev->dev;
1483
1484 codec->name = "WM8400";
1485 codec->owner = THIS_MODULE;
1486 codec->read = wm8400_read;
1487 codec->write = wm8400_write;
1488 codec->bias_level = SND_SOC_BIAS_OFF;
1489 codec->set_bias_level = wm8400_set_bias_level;
1490 codec->dai = &wm8400_dai;
1491 codec->num_dai = 1;
1492 codec->reg_cache_size = WM8400_REGISTER_COUNT;
1493 mutex_init(&codec->mutex);
1494 INIT_LIST_HEAD(&codec->dapm_widgets);
1495 INIT_LIST_HEAD(&codec->dapm_paths);
1496 INIT_WORK(&priv->work, wm8400_probe_deferred); 1401 INIT_WORK(&priv->work, wm8400_probe_deferred);
1497 1402
1498 wm8400_codec_reset(codec); 1403 wm8400_codec_reset(codec);
@@ -1511,65 +1416,78 @@ static int wm8400_codec_probe(struct platform_device *dev)
1511 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1416 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1512 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1417 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1513 1418
1514 wm8400_codec = codec;
1515
1516 if (!schedule_work(&priv->work)) { 1419 if (!schedule_work(&priv->work)) {
1517 ret = -EINVAL; 1420 ret = -EINVAL;
1518 goto err_regulator; 1421 goto err_regulator;
1519 } 1422 }
1520 1423 wm8400_add_controls(codec);
1424 wm8400_add_widgets(codec);
1521 return 0; 1425 return 0;
1522 1426
1523err_regulator: 1427err_regulator:
1524 wm8400_codec = NULL;
1525 regulator_bulk_free(ARRAY_SIZE(power), power); 1428 regulator_bulk_free(ARRAY_SIZE(power), power);
1526err: 1429err:
1527 kfree(priv); 1430 kfree(priv);
1528 return ret; 1431 return ret;
1529} 1432}
1530 1433
1531static int __exit wm8400_codec_remove(struct platform_device *dev) 1434static int wm8400_codec_remove(struct snd_soc_codec *codec)
1532{ 1435{
1533 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(wm8400_codec); 1436 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(codec);
1534 u16 reg; 1437 u16 reg;
1535 1438
1536 snd_soc_unregister_dai(&wm8400_dai); 1439 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
1537 snd_soc_unregister_codec(wm8400_codec); 1440 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1,
1538
1539 reg = wm8400_read(wm8400_codec, WM8400_POWER_MANAGEMENT_1);
1540 wm8400_write(wm8400_codec, WM8400_POWER_MANAGEMENT_1,
1541 reg & (~WM8400_CODEC_ENA)); 1441 reg & (~WM8400_CODEC_ENA));
1542 1442
1543 regulator_bulk_free(ARRAY_SIZE(power), power); 1443 regulator_bulk_free(ARRAY_SIZE(power), power);
1544 kfree(priv); 1444 kfree(priv);
1545 1445
1546 wm8400_codec = NULL; 1446 return 0;
1447}
1547 1448
1449static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
1450 .probe = wm8400_codec_probe,
1451 .remove = wm8400_codec_remove,
1452 .suspend = wm8400_suspend,
1453 .resume = wm8400_resume,
1454 .read = wm8400_read,
1455 .write = wm8400_write,
1456 .set_bias_level = wm8400_set_bias_level,
1457};
1458
1459static int __devinit wm8400_probe(struct platform_device *pdev)
1460{
1461 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
1462 &wm8400_dai, 1);
1463}
1464
1465static int __devexit wm8400_remove(struct platform_device *pdev)
1466{
1467 snd_soc_unregister_codec(&pdev->dev);
1548 return 0; 1468 return 0;
1549} 1469}
1550 1470
1551static struct platform_driver wm8400_codec_driver = { 1471static struct platform_driver wm8400_codec_driver = {
1552 .driver = { 1472 .driver = {
1553 .name = "wm8400-codec", 1473 .name = "wm8400-codec",
1554 .owner = THIS_MODULE, 1474 .owner = THIS_MODULE,
1555 }, 1475 },
1556 .probe = wm8400_codec_probe, 1476 .probe = wm8400_probe,
1557 .remove = __exit_p(wm8400_codec_remove), 1477 .remove = __devexit_p(wm8400_remove),
1558}; 1478};
1559 1479
1560static int __init wm8400_codec_init(void) 1480static __init int wm8400_init(void)
1561{ 1481{
1562 return platform_driver_register(&wm8400_codec_driver); 1482 return platform_driver_register(&wm8400_codec_driver);
1563} 1483}
1564module_init(wm8400_codec_init); 1484module_init(wm8400_init);
1565 1485
1566static void __exit wm8400_codec_exit(void) 1486static __exit void wm8400_exit(void)
1567{ 1487{
1568 platform_driver_unregister(&wm8400_codec_driver); 1488 platform_driver_unregister(&wm8400_codec_driver);
1569} 1489}
1570module_exit(wm8400_codec_exit); 1490module_exit(wm8400_exit);
1571
1572EXPORT_SYMBOL_GPL(soc_codec_dev_wm8400);
1573 1491
1574MODULE_DESCRIPTION("ASoC WM8400 driver"); 1492MODULE_DESCRIPTION("ASoC WM8400 driver");
1575MODULE_AUTHOR("Mark Brown"); 1493MODULE_AUTHOR("Mark Brown");
diff --git a/sound/soc/codecs/wm8400.h b/sound/soc/codecs/wm8400.h
index 79c5934d4776..521adb193870 100644
--- a/sound/soc/codecs/wm8400.h
+++ b/sound/soc/codecs/wm8400.h
@@ -56,7 +56,4 @@
56#define WM8400_BCLK_DIV_44 (0xE << 1) 56#define WM8400_BCLK_DIV_44 (0xE << 1)
57#define WM8400_BCLK_DIV_48 (0xF << 1) 57#define WM8400_BCLK_DIV_48 (0xF << 1)
58 58
59extern struct snd_soc_dai wm8400_dai;
60extern struct snd_soc_codec_device soc_codec_dev_wm8400;
61
62#endif 59#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 0f7bcb61071a..db0dced74843 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -24,15 +24,10 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29 28
30#include "wm8510.h" 29#include "wm8510.h"
31 30
32#define WM8510_VERSION "0.6"
33
34struct snd_soc_codec_device soc_codec_dev_wm8510;
35
36/* 31/*
37 * wm8510 register cache 32 * wm8510 register cache
38 * We can't read the WM8510 register space when we are 33 * We can't read the WM8510 register space when we are
@@ -61,6 +56,11 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
61 56
62#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0) 57#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
63 58
59/* codec private data */
60struct wm8510_priv {
61 enum snd_soc_control_type control_type;
62};
63
64static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; 64static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
65static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; 65static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
66static const char *wm8510_alc[] = { "ALC", "Limiter" }; 66static const char *wm8510_alc[] = { "ALC", "Limiter" };
@@ -215,10 +215,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
215 215
216static int wm8510_add_widgets(struct snd_soc_codec *codec) 216static int wm8510_add_widgets(struct snd_soc_codec *codec)
217{ 217{
218 snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets, 218 struct snd_soc_dapm_context *dapm = &codec->dapm;
219 ARRAY_SIZE(wm8510_dapm_widgets));
220 219
221 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 220 snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets,
221 ARRAY_SIZE(wm8510_dapm_widgets));
222 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
222 223
223 return 0; 224 return 0;
224} 225}
@@ -403,8 +404,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
403 struct snd_soc_dai *dai) 404 struct snd_soc_dai *dai)
404{ 405{
405 struct snd_soc_pcm_runtime *rtd = substream->private_data; 406 struct snd_soc_pcm_runtime *rtd = substream->private_data;
406 struct snd_soc_device *socdev = rtd->socdev; 407 struct snd_soc_codec *codec = rtd->codec;
407 struct snd_soc_codec *codec = socdev->card->codec;
408 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f; 408 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
409 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1; 409 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
410 410
@@ -478,7 +478,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
478 case SND_SOC_BIAS_STANDBY: 478 case SND_SOC_BIAS_STANDBY:
479 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; 479 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
480 480
481 if (codec->bias_level == SND_SOC_BIAS_OFF) { 481 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
482 /* Initial cap charge at VMID 5k */ 482 /* Initial cap charge at VMID 5k */
483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); 483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
484 mdelay(100); 484 mdelay(100);
@@ -495,7 +495,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
495 break; 495 break;
496 } 496 }
497 497
498 codec->bias_level = level; 498 codec->dapm.bias_level = level;
499 return 0; 499 return 0;
500} 500}
501 501
@@ -514,8 +514,8 @@ static struct snd_soc_dai_ops wm8510_dai_ops = {
514 .set_pll = wm8510_set_dai_pll, 514 .set_pll = wm8510_set_dai_pll,
515}; 515};
516 516
517struct snd_soc_dai wm8510_dai = { 517static struct snd_soc_dai_driver wm8510_dai = {
518 .name = "WM8510 HiFi", 518 .name = "wm8510-hifi",
519 .playback = { 519 .playback = {
520 .stream_name = "Playback", 520 .stream_name = "Playback",
521 .channels_min = 2, 521 .channels_min = 2,
@@ -531,21 +531,15 @@ struct snd_soc_dai wm8510_dai = {
531 .ops = &wm8510_dai_ops, 531 .ops = &wm8510_dai_ops,
532 .symmetric_rates = 1, 532 .symmetric_rates = 1,
533}; 533};
534EXPORT_SYMBOL_GPL(wm8510_dai);
535 534
536static int wm8510_suspend(struct platform_device *pdev, pm_message_t state) 535static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state)
537{ 536{
538 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
539 struct snd_soc_codec *codec = socdev->card->codec;
540
541 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); 537 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
542 return 0; 538 return 0;
543} 539}
544 540
545static int wm8510_resume(struct platform_device *pdev) 541static int wm8510_resume(struct snd_soc_codec *codec)
546{ 542{
547 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
548 struct snd_soc_codec *codec = socdev->card->codec;
549 int i; 543 int i;
550 u8 data[2]; 544 u8 data[2];
551 u16 *cache = codec->reg_cache; 545 u16 *cache = codec->reg_cache;
@@ -561,256 +555,158 @@ static int wm8510_resume(struct platform_device *pdev)
561 return 0; 555 return 0;
562} 556}
563 557
564/* 558static int wm8510_probe(struct snd_soc_codec *codec)
565 * initialise the WM8510 driver
566 * register the mixer and dsp interfaces with the kernel
567 */
568static int wm8510_init(struct snd_soc_device *socdev,
569 enum snd_soc_control_type control)
570{ 559{
571 struct snd_soc_codec *codec = socdev->card->codec; 560 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
572 int ret = 0; 561 int ret;
573
574 codec->name = "WM8510";
575 codec->owner = THIS_MODULE;
576 codec->set_bias_level = wm8510_set_bias_level;
577 codec->dai = &wm8510_dai;
578 codec->num_dai = 1;
579 codec->reg_cache_size = ARRAY_SIZE(wm8510_reg);
580 codec->reg_cache = kmemdup(wm8510_reg, sizeof(wm8510_reg), GFP_KERNEL);
581
582 if (codec->reg_cache == NULL)
583 return -ENOMEM;
584 562
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 563 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type);
586 if (ret < 0) { 564 if (ret < 0) {
587 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", 565 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
588 ret); 566 return ret;
589 goto err;
590 } 567 }
591 568
592 wm8510_reset(codec); 569 wm8510_reset(codec);
593 570
594 /* register pcms */
595 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
596 if (ret < 0) {
597 printk(KERN_ERR "wm8510: failed to create pcms\n");
598 goto err;
599 }
600
601 /* power on device */ 571 /* power on device */
602 codec->bias_level = SND_SOC_BIAS_OFF;
603 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 572 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
604 snd_soc_add_controls(codec, wm8510_snd_controls, 573 snd_soc_add_controls(codec, wm8510_snd_controls,
605 ARRAY_SIZE(wm8510_snd_controls)); 574 ARRAY_SIZE(wm8510_snd_controls));
606 wm8510_add_widgets(codec); 575 wm8510_add_widgets(codec);
607 576
608 return ret; 577 return ret;
609
610err:
611 kfree(codec->reg_cache);
612 return ret;
613} 578}
614 579
615static struct snd_soc_device *wm8510_socdev; 580/* power down chip */
581static int wm8510_remove(struct snd_soc_codec *codec)
582{
583 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
616 584
617#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 585 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
586 kfree(wm8510);
587 return 0;
588}
618 589
619/* 590static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
620 * WM8510 2 wire address is 0x1a 591 .probe = wm8510_probe,
621 */ 592 .remove = wm8510_remove,
593 .suspend = wm8510_suspend,
594 .resume = wm8510_resume,
595 .set_bias_level = wm8510_set_bias_level,
596 .reg_cache_size = ARRAY_SIZE(wm8510_reg),
597 .reg_word_size = sizeof(u16),
598 .reg_cache_default =wm8510_reg,
599};
622 600
623static int wm8510_i2c_probe(struct i2c_client *i2c, 601#if defined(CONFIG_SPI_MASTER)
624 const struct i2c_device_id *id) 602static int __devinit wm8510_spi_probe(struct spi_device *spi)
625{ 603{
626 struct snd_soc_device *socdev = wm8510_socdev; 604 struct wm8510_priv *wm8510;
627 struct snd_soc_codec *codec = socdev->card->codec;
628 int ret; 605 int ret;
629 606
630 i2c_set_clientdata(i2c, codec); 607 wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
631 codec->control_data = i2c; 608 if (wm8510 == NULL)
609 return -ENOMEM;
610
611 wm8510->control_type = SND_SOC_SPI;
612 spi_set_drvdata(spi, wm8510);
632 613
633 ret = wm8510_init(socdev, SND_SOC_I2C); 614 ret = snd_soc_register_codec(&spi->dev,
615 &soc_codec_dev_wm8510, &wm8510_dai, 1);
634 if (ret < 0) 616 if (ret < 0)
635 pr_err("failed to initialise WM8510\n"); 617 kfree(wm8510);
636
637 return ret; 618 return ret;
638} 619}
639 620
640static int wm8510_i2c_remove(struct i2c_client *client) 621static int __devexit wm8510_spi_remove(struct spi_device *spi)
641{ 622{
642 struct snd_soc_codec *codec = i2c_get_clientdata(client); 623 snd_soc_unregister_codec(&spi->dev);
643 kfree(codec->reg_cache);
644 return 0; 624 return 0;
645} 625}
646 626
647static const struct i2c_device_id wm8510_i2c_id[] = { 627static struct spi_driver wm8510_spi_driver = {
648 { "wm8510", 0 },
649 { }
650};
651MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
652
653static struct i2c_driver wm8510_i2c_driver = {
654 .driver = { 628 .driver = {
655 .name = "WM8510 I2C Codec", 629 .name = "wm8510",
656 .owner = THIS_MODULE, 630 .owner = THIS_MODULE,
657 }, 631 },
658 .probe = wm8510_i2c_probe, 632 .probe = wm8510_spi_probe,
659 .remove = wm8510_i2c_remove, 633 .remove = __devexit_p(wm8510_spi_remove),
660 .id_table = wm8510_i2c_id,
661}; 634};
635#endif /* CONFIG_SPI_MASTER */
662 636
663static int wm8510_add_i2c_device(struct platform_device *pdev, 637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
664 const struct wm8510_setup_data *setup) 638static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
639 const struct i2c_device_id *id)
665{ 640{
666 struct i2c_board_info info; 641 struct wm8510_priv *wm8510;
667 struct i2c_adapter *adapter;
668 struct i2c_client *client;
669 int ret; 642 int ret;
670 643
671 ret = i2c_add_driver(&wm8510_i2c_driver); 644 wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
672 if (ret != 0) { 645 if (wm8510 == NULL)
673 dev_err(&pdev->dev, "can't add i2c driver\n"); 646 return -ENOMEM;
674 return ret;
675 }
676
677 memset(&info, 0, sizeof(struct i2c_board_info));
678 info.addr = setup->i2c_address;
679 strlcpy(info.type, "wm8510", I2C_NAME_SIZE);
680
681 adapter = i2c_get_adapter(setup->i2c_bus);
682 if (!adapter) {
683 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
684 setup->i2c_bus);
685 goto err_driver;
686 }
687
688 client = i2c_new_device(adapter, &info);
689 i2c_put_adapter(adapter);
690 if (!client) {
691 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
692 (unsigned int)info.addr);
693 goto err_driver;
694 }
695
696 return 0;
697
698err_driver:
699 i2c_del_driver(&wm8510_i2c_driver);
700 return -ENODEV;
701}
702#endif
703
704#if defined(CONFIG_SPI_MASTER)
705static int __devinit wm8510_spi_probe(struct spi_device *spi)
706{
707 struct snd_soc_device *socdev = wm8510_socdev;
708 struct snd_soc_codec *codec = socdev->card->codec;
709 int ret;
710 647
711 codec->control_data = spi; 648 i2c_set_clientdata(i2c, wm8510);
649 wm8510->control_type = SND_SOC_I2C;
712 650
713 ret = wm8510_init(socdev, SND_SOC_SPI); 651 ret = snd_soc_register_codec(&i2c->dev,
652 &soc_codec_dev_wm8510, &wm8510_dai, 1);
714 if (ret < 0) 653 if (ret < 0)
715 dev_err(&spi->dev, "failed to initialise WM8510\n"); 654 kfree(wm8510);
716
717 return ret; 655 return ret;
718} 656}
719 657
720static int __devexit wm8510_spi_remove(struct spi_device *spi) 658static __devexit int wm8510_i2c_remove(struct i2c_client *client)
721{ 659{
660 snd_soc_unregister_codec(&client->dev);
722 return 0; 661 return 0;
723} 662}
724 663
725static struct spi_driver wm8510_spi_driver = { 664static const struct i2c_device_id wm8510_i2c_id[] = {
665 { "wm8510", 0 },
666 { }
667};
668MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
669
670static struct i2c_driver wm8510_i2c_driver = {
726 .driver = { 671 .driver = {
727 .name = "wm8510", 672 .name = "wm8510-codec",
728 .bus = &spi_bus_type, 673 .owner = THIS_MODULE,
729 .owner = THIS_MODULE,
730 }, 674 },
731 .probe = wm8510_spi_probe, 675 .probe = wm8510_i2c_probe,
732 .remove = __devexit_p(wm8510_spi_remove), 676 .remove = __devexit_p(wm8510_i2c_remove),
677 .id_table = wm8510_i2c_id,
733}; 678};
734#endif /* CONFIG_SPI_MASTER */ 679#endif
735 680
736static int wm8510_probe(struct platform_device *pdev) 681static int __init wm8510_modinit(void)
737{ 682{
738 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
739 struct wm8510_setup_data *setup;
740 struct snd_soc_codec *codec;
741 int ret = 0; 683 int ret = 0;
742
743 pr_info("WM8510 Audio Codec %s", WM8510_VERSION);
744
745 setup = socdev->codec_data;
746 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
747 if (codec == NULL)
748 return -ENOMEM;
749
750 socdev->card->codec = codec;
751 mutex_init(&codec->mutex);
752 INIT_LIST_HEAD(&codec->dapm_widgets);
753 INIT_LIST_HEAD(&codec->dapm_paths);
754
755 wm8510_socdev = socdev;
756#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 684#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
757 if (setup->i2c_address) { 685 ret = i2c_add_driver(&wm8510_i2c_driver);
758 ret = wm8510_add_i2c_device(pdev, setup); 686 if (ret != 0) {
687 printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n",
688 ret);
759 } 689 }
760#endif 690#endif
761#if defined(CONFIG_SPI_MASTER) 691#if defined(CONFIG_SPI_MASTER)
762 if (setup->spi) { 692 ret = spi_register_driver(&wm8510_spi_driver);
763 ret = spi_register_driver(&wm8510_spi_driver); 693 if (ret != 0) {
764 if (ret != 0) 694 printk(KERN_ERR "Failed to register WM8510 SPI driver: %d\n",
765 printk(KERN_ERR "can't add spi driver"); 695 ret);
766 } 696 }
767#endif 697#endif
768
769 if (ret != 0)
770 kfree(codec);
771 return ret; 698 return ret;
772} 699}
700module_init(wm8510_modinit);
773 701
774/* power down chip */ 702static void __exit wm8510_exit(void)
775static int wm8510_remove(struct platform_device *pdev)
776{ 703{
777 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
778 struct snd_soc_codec *codec = socdev->card->codec;
779
780 if (codec->control_data)
781 wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
782
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 704#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
786 i2c_unregister_device(codec->control_data);
787 i2c_del_driver(&wm8510_i2c_driver); 705 i2c_del_driver(&wm8510_i2c_driver);
788#endif 706#endif
789#if defined(CONFIG_SPI_MASTER) 707#if defined(CONFIG_SPI_MASTER)
790 spi_unregister_driver(&wm8510_spi_driver); 708 spi_unregister_driver(&wm8510_spi_driver);
791#endif 709#endif
792 kfree(codec);
793
794 return 0;
795}
796
797struct snd_soc_codec_device soc_codec_dev_wm8510 = {
798 .probe = wm8510_probe,
799 .remove = wm8510_remove,
800 .suspend = wm8510_suspend,
801 .resume = wm8510_resume,
802};
803EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
804
805static int __init wm8510_modinit(void)
806{
807 return snd_soc_register_dai(&wm8510_dai);
808}
809module_init(wm8510_modinit);
810
811static void __exit wm8510_exit(void)
812{
813 snd_soc_unregister_dai(&wm8510_dai);
814} 710}
815module_exit(wm8510_exit); 711module_exit(wm8510_exit);
816 712
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index bdefcf5c69ff..b3e26ed9f2d0 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -99,7 +99,4 @@ struct wm8510_setup_data {
99 unsigned short i2c_address; 99 unsigned short i2c_address;
100}; 100};
101 101
102extern struct snd_soc_dai wm8510_dai;
103extern struct snd_soc_codec_device soc_codec_dev_wm8510;
104
105#endif 102#endif
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 0ad039b4adf5..4fd4d8dca0fc 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -24,15 +24,11 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30 29
31#include "wm8523.h" 30#include "wm8523.h"
32 31
33static struct snd_soc_codec *wm8523_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8523;
35
36#define WM8523_NUM_SUPPLIES 2 32#define WM8523_NUM_SUPPLIES 2
37static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { 33static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
38 "AVDD", 34 "AVDD",
@@ -43,8 +39,7 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
43 39
44/* codec private data */ 40/* codec private data */
45struct wm8523_priv { 41struct wm8523_priv {
46 struct snd_soc_codec codec; 42 enum snd_soc_control_type control_type;
47 u16 reg_cache[WM8523_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; 43 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
49 unsigned int sysclk; 44 unsigned int sysclk;
50 unsigned int rate_constraint_list[WM8523_NUM_RATES]; 45 unsigned int rate_constraint_list[WM8523_NUM_RATES];
@@ -63,7 +58,7 @@ static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
63 0x0000, /* R8 - ZERO_DETECT */ 58 0x0000, /* R8 - ZERO_DETECT */
64}; 59};
65 60
66static int wm8523_volatile_register(unsigned int reg) 61static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
67{ 62{
68 switch (reg) { 63 switch (reg) {
69 case WM8523_DEVICE_ID: 64 case WM8523_DEVICE_ID:
@@ -113,10 +108,11 @@ static const struct snd_soc_dapm_route intercon[] = {
113 108
114static int wm8523_add_widgets(struct snd_soc_codec *codec) 109static int wm8523_add_widgets(struct snd_soc_codec *codec)
115{ 110{
116 snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets, 111 struct snd_soc_dapm_context *dapm = &codec->dapm;
117 ARRAY_SIZE(wm8523_dapm_widgets));
118 112
119 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 113 snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
114 ARRAY_SIZE(wm8523_dapm_widgets));
115 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
120 116
121 return 0; 117 return 0;
122} 118}
@@ -149,7 +145,6 @@ static int wm8523_startup(struct snd_pcm_substream *substream,
149 return -EINVAL; 145 return -EINVAL;
150 } 146 }
151 147
152 return 0;
153 snd_pcm_hw_constraint_list(substream->runtime, 0, 148 snd_pcm_hw_constraint_list(substream->runtime, 0,
154 SNDRV_PCM_HW_PARAM_RATE, 149 SNDRV_PCM_HW_PARAM_RATE,
155 &wm8523->rate_constraint); 150 &wm8523->rate_constraint);
@@ -162,8 +157,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
162 struct snd_soc_dai *dai) 157 struct snd_soc_dai *dai)
163{ 158{
164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 159 struct snd_soc_pcm_runtime *rtd = substream->private_data;
165 struct snd_soc_device *socdev = rtd->socdev; 160 struct snd_soc_codec *codec = rtd->codec;
166 struct snd_soc_codec *codec = socdev->card->codec;
167 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 161 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
168 int i; 162 int i;
169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); 163 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
@@ -319,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
319 enum snd_soc_bias_level level) 313 enum snd_soc_bias_level level)
320{ 314{
321 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 315 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
316 u16 *reg_cache = codec->reg_cache;
322 int ret, i; 317 int ret, i;
323 318
324 switch (level) { 319 switch (level) {
@@ -332,7 +327,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
332 break; 327 break;
333 328
334 case SND_SOC_BIAS_STANDBY: 329 case SND_SOC_BIAS_STANDBY:
335 if (codec->bias_level == SND_SOC_BIAS_OFF) { 330 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
336 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 331 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
337 wm8523->supplies); 332 wm8523->supplies);
338 if (ret != 0) { 333 if (ret != 0) {
@@ -349,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
349 /* Sync back default/cached values */ 344 /* Sync back default/cached values */
350 for (i = WM8523_AIF_CTRL1; 345 for (i = WM8523_AIF_CTRL1;
351 i < WM8523_MAX_REGISTER; i++) 346 i < WM8523_MAX_REGISTER; i++)
352 snd_soc_write(codec, i, wm8523->reg_cache[i]); 347 snd_soc_write(codec, i, reg_cache[i]);
353 348
354 349
355 msleep(100); 350 msleep(100);
@@ -371,7 +366,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
371 wm8523->supplies); 366 wm8523->supplies);
372 break; 367 break;
373 } 368 }
374 codec->bias_level = level; 369 codec->dapm.bias_level = level;
375 return 0; 370 return 0;
376} 371}
377 372
@@ -387,8 +382,8 @@ static struct snd_soc_dai_ops wm8523_dai_ops = {
387 .set_fmt = wm8523_set_dai_fmt, 382 .set_fmt = wm8523_set_dai_fmt,
388}; 383};
389 384
390struct snd_soc_dai wm8523_dai = { 385static struct snd_soc_dai_driver wm8523_dai = {
391 .name = "WM8523", 386 .name = "wm8523-hifi",
392 .playback = { 387 .playback = {
393 .stream_name = "Playback", 388 .stream_name = "Playback",
394 .channels_min = 2, /* Mono modes not yet supported */ 389 .channels_min = 2, /* Mono modes not yet supported */
@@ -398,25 +393,17 @@ struct snd_soc_dai wm8523_dai = {
398 }, 393 },
399 .ops = &wm8523_dai_ops, 394 .ops = &wm8523_dai_ops,
400}; 395};
401EXPORT_SYMBOL_GPL(wm8523_dai);
402 396
403#ifdef CONFIG_PM 397#ifdef CONFIG_PM
404static int wm8523_suspend(struct platform_device *pdev, pm_message_t state) 398static int wm8523_suspend(struct snd_soc_codec *codec, pm_message_t state)
405{ 399{
406 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
407 struct snd_soc_codec *codec = socdev->card->codec;
408
409 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); 400 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
410 return 0; 401 return 0;
411} 402}
412 403
413static int wm8523_resume(struct platform_device *pdev) 404static int wm8523_resume(struct snd_soc_codec *codec)
414{ 405{
415 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
416 struct snd_soc_codec *codec = socdev->card->codec;
417
418 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 406 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
419
420 return 0; 407 return 0;
421} 408}
422#else 409#else
@@ -424,93 +411,20 @@ static int wm8523_resume(struct platform_device *pdev)
424#define wm8523_resume NULL 411#define wm8523_resume NULL
425#endif 412#endif
426 413
427static int wm8523_probe(struct platform_device *pdev) 414static int wm8523_probe(struct snd_soc_codec *codec)
428{
429 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
430 struct snd_soc_codec *codec;
431 int ret = 0;
432
433 if (wm8523_codec == NULL) {
434 dev_err(&pdev->dev, "Codec device not registered\n");
435 return -ENODEV;
436 }
437
438 socdev->card->codec = wm8523_codec;
439 codec = wm8523_codec;
440
441 /* register pcms */
442 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
443 if (ret < 0) {
444 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
445 goto pcm_err;
446 }
447
448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec);
451
452 return ret;
453
454pcm_err:
455 return ret;
456}
457
458static int wm8523_remove(struct platform_device *pdev)
459{
460 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
461
462 snd_soc_free_pcms(socdev);
463 snd_soc_dapm_free(socdev);
464
465 return 0;
466}
467
468struct snd_soc_codec_device soc_codec_dev_wm8523 = {
469 .probe = wm8523_probe,
470 .remove = wm8523_remove,
471 .suspend = wm8523_suspend,
472 .resume = wm8523_resume,
473};
474EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
475
476static int wm8523_register(struct wm8523_priv *wm8523,
477 enum snd_soc_control_type control)
478{ 415{
479 int ret; 416 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
480 struct snd_soc_codec *codec = &wm8523->codec; 417 int ret, i;
481 int i;
482
483 if (wm8523_codec) {
484 dev_err(codec->dev, "Another WM8523 is registered\n");
485 ret = -EINVAL;
486 goto err;
487 }
488
489 mutex_init(&codec->mutex);
490 INIT_LIST_HEAD(&codec->dapm_widgets);
491 INIT_LIST_HEAD(&codec->dapm_paths);
492
493 snd_soc_codec_set_drvdata(codec, wm8523);
494 codec->name = "WM8523";
495 codec->owner = THIS_MODULE;
496 codec->bias_level = SND_SOC_BIAS_OFF;
497 codec->set_bias_level = wm8523_set_bias_level;
498 codec->dai = &wm8523_dai;
499 codec->num_dai = 1;
500 codec->reg_cache_size = WM8523_REGISTER_COUNT;
501 codec->reg_cache = &wm8523->reg_cache;
502 codec->volatile_register = wm8523_volatile_register;
503 418
419 codec->hw_write = (hw_write_t)i2c_master_send;
504 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; 420 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
505 wm8523->rate_constraint.count = 421 wm8523->rate_constraint.count =
506 ARRAY_SIZE(wm8523->rate_constraint_list); 422 ARRAY_SIZE(wm8523->rate_constraint_list);
507 423
508 memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg)); 424 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
509
510 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
511 if (ret != 0) { 425 if (ret != 0) {
512 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 426 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
513 goto err; 427 return ret;
514 } 428 }
515 429
516 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++) 430 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
@@ -520,7 +434,7 @@ static int wm8523_register(struct wm8523_priv *wm8523,
520 wm8523->supplies); 434 wm8523->supplies);
521 if (ret != 0) { 435 if (ret != 0) {
522 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 436 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
523 goto err; 437 return ret;
524 } 438 }
525 439
526 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 440 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
@@ -555,80 +469,77 @@ static int wm8523_register(struct wm8523_priv *wm8523,
555 goto err_enable; 469 goto err_enable;
556 } 470 }
557 471
558 wm8523_dai.dev = codec->dev;
559
560 /* Change some default settings - latch VU and enable ZC */ 472 /* Change some default settings - latch VU and enable ZC */
561 wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; 473 snd_soc_update_bits(codec, WM8523_DAC_GAINR,
562 wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; 474 WM8523_DACR_VU, WM8523_DACR_VU);
475 snd_soc_update_bits(codec, WM8523_DAC_CTRL3, WM8523_ZC, WM8523_ZC);
563 476
564 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 477 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
565 478
566 /* Bias level configuration will have done an extra enable */ 479 /* Bias level configuration will have done an extra enable */
567 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 480 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
568 481
569 wm8523_codec = codec; 482 snd_soc_add_controls(codec, wm8523_snd_controls,
570 483 ARRAY_SIZE(wm8523_snd_controls));
571 ret = snd_soc_register_codec(codec); 484 wm8523_add_widgets(codec);
572 if (ret != 0) {
573 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
574 goto err_enable;
575 }
576
577 ret = snd_soc_register_dai(&wm8523_dai);
578 if (ret != 0) {
579 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
580 goto err_codec;
581 }
582 485
583 return 0; 486 return 0;
584 487
585err_codec:
586 snd_soc_unregister_codec(codec);
587err_enable: 488err_enable:
588 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 489 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
589err_get: 490err_get:
590 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 491 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
591err: 492
592 kfree(wm8523);
593 return ret; 493 return ret;
594} 494}
595 495
596static void wm8523_unregister(struct wm8523_priv *wm8523) 496static int wm8523_remove(struct snd_soc_codec *codec)
597{ 497{
598 wm8523_set_bias_level(&wm8523->codec, SND_SOC_BIAS_OFF); 498 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
499
500 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
599 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); 501 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
600 snd_soc_unregister_dai(&wm8523_dai); 502 return 0;
601 snd_soc_unregister_codec(&wm8523->codec);
602 kfree(wm8523);
603 wm8523_codec = NULL;
604} 503}
605 504
505static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
506 .probe = wm8523_probe,
507 .remove = wm8523_remove,
508 .suspend = wm8523_suspend,
509 .resume = wm8523_resume,
510 .set_bias_level = wm8523_set_bias_level,
511 .reg_cache_size = WM8523_REGISTER_COUNT,
512 .reg_word_size = sizeof(u16),
513 .reg_cache_default = wm8523_reg,
514 .volatile_register = wm8523_volatile_register,
515};
516
606#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 517#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
607static __devinit int wm8523_i2c_probe(struct i2c_client *i2c, 518static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
608 const struct i2c_device_id *id) 519 const struct i2c_device_id *id)
609{ 520{
610 struct wm8523_priv *wm8523; 521 struct wm8523_priv *wm8523;
611 struct snd_soc_codec *codec; 522 int ret;
612 523
613 wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL); 524 wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
614 if (wm8523 == NULL) 525 if (wm8523 == NULL)
615 return -ENOMEM; 526 return -ENOMEM;
616 527
617 codec = &wm8523->codec;
618 codec->hw_write = (hw_write_t)i2c_master_send;
619
620 i2c_set_clientdata(i2c, wm8523); 528 i2c_set_clientdata(i2c, wm8523);
621 codec->control_data = i2c; 529 wm8523->control_type = SND_SOC_I2C;
622 530
623 codec->dev = &i2c->dev; 531 ret = snd_soc_register_codec(&i2c->dev,
532 &soc_codec_dev_wm8523, &wm8523_dai, 1);
533 if (ret < 0)
534 kfree(wm8523);
535 return ret;
624 536
625 return wm8523_register(wm8523, SND_SOC_I2C);
626} 537}
627 538
628static __devexit int wm8523_i2c_remove(struct i2c_client *client) 539static __devexit int wm8523_i2c_remove(struct i2c_client *client)
629{ 540{
630 struct wm8523_priv *wm8523 = i2c_get_clientdata(client); 541 snd_soc_unregister_codec(&client->dev);
631 wm8523_unregister(wm8523); 542 kfree(i2c_get_clientdata(client));
632 return 0; 543 return 0;
633} 544}
634 545
@@ -640,7 +551,7 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
640 551
641static struct i2c_driver wm8523_i2c_driver = { 552static struct i2c_driver wm8523_i2c_driver = {
642 .driver = { 553 .driver = {
643 .name = "WM8523", 554 .name = "wm8523-codec",
644 .owner = THIS_MODULE, 555 .owner = THIS_MODULE,
645 }, 556 },
646 .probe = wm8523_i2c_probe, 557 .probe = wm8523_i2c_probe,
diff --git a/sound/soc/codecs/wm8523.h b/sound/soc/codecs/wm8523.h
index 1aa9ce3e1357..4d5b1eb8f2fc 100644
--- a/sound/soc/codecs/wm8523.h
+++ b/sound/soc/codecs/wm8523.h
@@ -154,7 +154,4 @@
154#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */ 154#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */
155#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */ 155#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */
156 156
157extern struct snd_soc_dai wm8523_dai;
158extern struct snd_soc_codec_device soc_codec_dev_wm8523;
159
160#endif 157#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 72deeabef4fe..4bbc0a79f01e 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -31,7 +31,6 @@
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/tlv.h> 34#include <sound/tlv.h>
36#include <sound/initval.h> 35#include <sound/initval.h>
37#include <asm/div64.h> 36#include <asm/div64.h>
@@ -94,6 +93,8 @@
94 93
95#define WM8580_MAX_REGISTER 0x35 94#define WM8580_MAX_REGISTER 0x35
96 95
96#define WM8580_DACOSR 0x40
97
97/* PLLB4 (register 7h) */ 98/* PLLB4 (register 7h) */
98#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60 99#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
99#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20 100#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
@@ -112,19 +113,7 @@
112 113
113/* AIF control 1 (registers 9h-bh) */ 114/* AIF control 1 (registers 9h-bh) */
114#define WM8580_AIF_RATE_MASK 0x7 115#define WM8580_AIF_RATE_MASK 0x7
115#define WM8580_AIF_RATE_128 0x0
116#define WM8580_AIF_RATE_192 0x1
117#define WM8580_AIF_RATE_256 0x2
118#define WM8580_AIF_RATE_384 0x3
119#define WM8580_AIF_RATE_512 0x4
120#define WM8580_AIF_RATE_768 0x5
121#define WM8580_AIF_RATE_1152 0x6
122
123#define WM8580_AIF_BCLKSEL_MASK 0x18 116#define WM8580_AIF_BCLKSEL_MASK 0x18
124#define WM8580_AIF_BCLKSEL_64 0x00
125#define WM8580_AIF_BCLKSEL_128 0x08
126#define WM8580_AIF_BCLKSEL_256 0x10
127#define WM8580_AIF_BCLKSEL_SYSCLK 0x18
128 117
129#define WM8580_AIF_MS 0x20 118#define WM8580_AIF_MS 0x20
130 119
@@ -171,7 +160,7 @@
171static const u16 wm8580_reg[] = { 160static const u16 wm8580_reg[] = {
172 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ 161 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
173 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ 162 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
174 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/ 163 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
175 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ 164 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
176 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ 165 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
177 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ 166 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
@@ -199,11 +188,11 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
199 188
200/* codec private data */ 189/* codec private data */
201struct wm8580_priv { 190struct wm8580_priv {
202 struct snd_soc_codec codec; 191 enum snd_soc_control_type control_type;
203 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; 192 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
204 u16 reg_cache[WM8580_MAX_REGISTER + 1];
205 struct pll_state a; 193 struct pll_state a;
206 struct pll_state b; 194 struct pll_state b;
195 int sysclk[2];
207}; 196};
208 197
209static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); 198static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
@@ -273,8 +262,8 @@ SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 1),
273SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1), 262SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1),
274SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1), 263SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1),
275 264
276SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0), 265SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1),
277SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), 266SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
278}; 267};
279 268
280static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { 269static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
@@ -311,10 +300,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
311 300
312static int wm8580_add_widgets(struct snd_soc_codec *codec) 301static int wm8580_add_widgets(struct snd_soc_codec *codec)
313{ 302{
314 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets, 303 struct snd_soc_dapm_context *dapm = &codec->dapm;
315 ARRAY_SIZE(wm8580_dapm_widgets));
316 304
317 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 305 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets,
306 ARRAY_SIZE(wm8580_dapm_widgets));
307 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
318 308
319 return 0; 309 return 0;
320} 310}
@@ -476,6 +466,10 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
476 return 0; 466 return 0;
477} 467}
478 468
469static const int wm8580_sysclk_ratios[] = {
470 128, 192, 256, 384, 512, 768, 1152,
471};
472
479/* 473/*
480 * Set PCM DAI bit size and sample rate. 474 * Set PCM DAI bit size and sample rate.
481 */ 475 */
@@ -484,29 +478,68 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
484 struct snd_soc_dai *dai) 478 struct snd_soc_dai *dai)
485{ 479{
486 struct snd_soc_pcm_runtime *rtd = substream->private_data; 480 struct snd_soc_pcm_runtime *rtd = substream->private_data;
487 struct snd_soc_device *socdev = rtd->socdev; 481 struct snd_soc_codec *codec = rtd->codec;
488 struct snd_soc_codec *codec = socdev->card->codec; 482 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id); 483 u16 paifa = 0;
484 u16 paifb = 0;
485 int i, ratio, osr;
490 486
491 paifb &= ~WM8580_AIF_LENGTH_MASK;
492 /* bit size */ 487 /* bit size */
493 switch (params_format(params)) { 488 switch (params_format(params)) {
494 case SNDRV_PCM_FORMAT_S16_LE: 489 case SNDRV_PCM_FORMAT_S16_LE:
490 paifa |= 0x8;
495 break; 491 break;
496 case SNDRV_PCM_FORMAT_S20_3LE: 492 case SNDRV_PCM_FORMAT_S20_3LE:
493 paifa |= 0x0;
497 paifb |= WM8580_AIF_LENGTH_20; 494 paifb |= WM8580_AIF_LENGTH_20;
498 break; 495 break;
499 case SNDRV_PCM_FORMAT_S24_LE: 496 case SNDRV_PCM_FORMAT_S24_LE:
497 paifa |= 0x0;
500 paifb |= WM8580_AIF_LENGTH_24; 498 paifb |= WM8580_AIF_LENGTH_24;
501 break; 499 break;
502 case SNDRV_PCM_FORMAT_S32_LE: 500 case SNDRV_PCM_FORMAT_S32_LE:
503 paifb |= WM8580_AIF_LENGTH_24; 501 paifa |= 0x0;
502 paifb |= WM8580_AIF_LENGTH_32;
504 break; 503 break;
505 default: 504 default:
506 return -EINVAL; 505 return -EINVAL;
507 } 506 }
508 507
509 snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb); 508 /* Look up the SYSCLK ratio; accept only exact matches */
509 ratio = wm8580->sysclk[dai->driver->id] / params_rate(params);
510 for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)
511 if (ratio == wm8580_sysclk_ratios[i])
512 break;
513 if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
514 dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
515 wm8580->sysclk[dai->driver->id], params_rate(params));
516 return -EINVAL;
517 }
518 paifa |= i;
519 dev_dbg(codec->dev, "Running at %dfs with %dHz clock\n",
520 wm8580_sysclk_ratios[i], wm8580->sysclk[dai->driver->id]);
521
522 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
523 switch (ratio) {
524 case 128:
525 case 192:
526 osr = WM8580_DACOSR;
527 dev_dbg(codec->dev, "Selecting 64x OSR\n");
528 break;
529 default:
530 osr = 0;
531 dev_dbg(codec->dev, "Selecting 128x OSR\n");
532 break;
533 }
534
535 snd_soc_update_bits(codec, WM8580_PAIF3, WM8580_DACOSR, osr);
536 }
537
538 snd_soc_update_bits(codec, WM8580_PAIF1 + dai->driver->id,
539 WM8580_AIF_RATE_MASK | WM8580_AIF_BCLKSEL_MASK,
540 paifa);
541 snd_soc_update_bits(codec, WM8580_PAIF3 + dai->driver->id,
542 WM8580_AIF_LENGTH_MASK, paifb);
510 return 0; 543 return 0;
511} 544}
512 545
@@ -518,8 +551,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
518 unsigned int aifb; 551 unsigned int aifb;
519 int can_invert_lrclk; 552 int can_invert_lrclk;
520 553
521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id); 554 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id); 555 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
523 556
524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); 557 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
525 558
@@ -585,8 +618,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
585 return -EINVAL; 618 return -EINVAL;
586 } 619 }
587 620
588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); 621 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); 622 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
590 623
591 return 0; 624 return 0;
592} 625}
@@ -624,28 +657,6 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
624 snd_soc_write(codec, WM8580_PLLB4, reg); 657 snd_soc_write(codec, WM8580_PLLB4, reg);
625 break; 658 break;
626 659
627 case WM8580_DAC_CLKSEL:
628 reg = snd_soc_read(codec, WM8580_CLKSEL);
629 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
630
631 switch (div) {
632 case WM8580_CLKSRC_MCLK:
633 break;
634
635 case WM8580_CLKSRC_PLLA:
636 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLA;
637 break;
638
639 case WM8580_CLKSRC_PLLB:
640 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLB;
641 break;
642
643 default:
644 return -EINVAL;
645 }
646 snd_soc_write(codec, WM8580_CLKSEL, reg);
647 break;
648
649 case WM8580_CLKOUTSRC: 660 case WM8580_CLKOUTSRC:
650 reg = snd_soc_read(codec, WM8580_PLLB4); 661 reg = snd_soc_read(codec, WM8580_PLLB4);
651 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK; 662 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
@@ -679,6 +690,55 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
679 return 0; 690 return 0;
680} 691}
681 692
693static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
694 unsigned int freq, int dir)
695{
696 struct snd_soc_codec *codec = dai->codec;
697 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
698 int sel, sel_mask, sel_shift;
699
700 switch (dai->driver->id) {
701 case WM8580_DAI_PAIFRX:
702 sel_mask = 0x3;
703 sel_shift = 0;
704 break;
705
706 case WM8580_DAI_PAIFTX:
707 sel_mask = 0xc;
708 sel_shift = 2;
709 break;
710
711 default:
712 BUG_ON("Unknown DAI driver ID\n");
713 return -EINVAL;
714 }
715
716 switch (clk_id) {
717 case WM8580_CLKSRC_ADCMCLK:
718 if (dai->driver->id != WM8580_DAI_PAIFTX)
719 return -EINVAL;
720 sel = 0 << sel_shift;
721 break;
722 case WM8580_CLKSRC_PLLA:
723 sel = 1 << sel_shift;
724 break;
725 case WM8580_CLKSRC_PLLB:
726 sel = 2 << sel_shift;
727 break;
728 case WM8580_CLKSRC_MCLK:
729 sel = 3 << sel_shift;
730 break;
731 default:
732 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
733 return -EINVAL;
734 }
735
736 /* We really should validate PLL settings but not yet */
737 wm8580->sysclk[dai->driver->id] = freq;
738
739 return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
740}
741
682static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute) 742static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
683{ 743{
684 struct snd_soc_codec *codec = codec_dai->codec; 744 struct snd_soc_codec *codec = codec_dai->codec;
@@ -706,13 +766,13 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
706 break; 766 break;
707 767
708 case SND_SOC_BIAS_STANDBY: 768 case SND_SOC_BIAS_STANDBY:
709 if (codec->bias_level == SND_SOC_BIAS_OFF) { 769 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
710 /* Power up and get individual control of the DACs */ 770 /* Power up and get individual control of the DACs */
711 reg = snd_soc_read(codec, WM8580_PWRDN1); 771 reg = snd_soc_read(codec, WM8580_PWRDN1);
712 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 772 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
713 snd_soc_write(codec, WM8580_PWRDN1, reg); 773 snd_soc_write(codec, WM8580_PWRDN1, reg);
714 774
715 /* Make VMID high impedence */ 775 /* Make VMID high impedance */
716 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); 776 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1);
717 reg &= ~0x100; 777 reg &= ~0x100;
718 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg); 778 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
@@ -724,7 +784,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
724 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 784 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
725 break; 785 break;
726 } 786 }
727 codec->bias_level = level; 787 codec->dapm.bias_level = level;
728 return 0; 788 return 0;
729} 789}
730 790
@@ -732,6 +792,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
732 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 792 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
733 793
734static struct snd_soc_dai_ops wm8580_dai_ops_playback = { 794static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
795 .set_sysclk = wm8580_set_sysclk,
735 .hw_params = wm8580_paif_hw_params, 796 .hw_params = wm8580_paif_hw_params,
736 .set_fmt = wm8580_set_paif_dai_fmt, 797 .set_fmt = wm8580_set_paif_dai_fmt,
737 .set_clkdiv = wm8580_set_dai_clkdiv, 798 .set_clkdiv = wm8580_set_dai_clkdiv,
@@ -740,16 +801,17 @@ static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
740}; 801};
741 802
742static struct snd_soc_dai_ops wm8580_dai_ops_capture = { 803static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
804 .set_sysclk = wm8580_set_sysclk,
743 .hw_params = wm8580_paif_hw_params, 805 .hw_params = wm8580_paif_hw_params,
744 .set_fmt = wm8580_set_paif_dai_fmt, 806 .set_fmt = wm8580_set_paif_dai_fmt,
745 .set_clkdiv = wm8580_set_dai_clkdiv, 807 .set_clkdiv = wm8580_set_dai_clkdiv,
746 .set_pll = wm8580_set_dai_pll, 808 .set_pll = wm8580_set_dai_pll,
747}; 809};
748 810
749struct snd_soc_dai wm8580_dai[] = { 811static struct snd_soc_dai_driver wm8580_dai[] = {
750 { 812 {
751 .name = "WM8580 PAIFRX", 813 .name = "wm8580-hifi-playback",
752 .id = 0, 814 .id = WM8580_DAI_PAIFRX,
753 .playback = { 815 .playback = {
754 .stream_name = "Playback", 816 .stream_name = "Playback",
755 .channels_min = 1, 817 .channels_min = 1,
@@ -760,8 +822,8 @@ struct snd_soc_dai wm8580_dai[] = {
760 .ops = &wm8580_dai_ops_playback, 822 .ops = &wm8580_dai_ops_playback,
761 }, 823 },
762 { 824 {
763 .name = "WM8580 PAIFTX", 825 .name = "wm8580-hifi-capture",
764 .id = 1, 826 .id = WM8580_DAI_PAIFTX,
765 .capture = { 827 .capture = {
766 .stream_name = "Capture", 828 .stream_name = "Capture",
767 .channels_min = 2, 829 .channels_min = 2,
@@ -772,90 +834,16 @@ struct snd_soc_dai wm8580_dai[] = {
772 .ops = &wm8580_dai_ops_capture, 834 .ops = &wm8580_dai_ops_capture,
773 }, 835 },
774}; 836};
775EXPORT_SYMBOL_GPL(wm8580_dai);
776
777static struct snd_soc_codec *wm8580_codec;
778
779static int wm8580_probe(struct platform_device *pdev)
780{
781 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
782 struct snd_soc_codec *codec;
783 int ret = 0;
784
785 if (wm8580_codec == NULL) {
786 dev_err(&pdev->dev, "Codec device not registered\n");
787 return -ENODEV;
788 }
789
790 socdev->card->codec = wm8580_codec;
791 codec = wm8580_codec;
792
793 /* register pcms */
794 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
795 if (ret < 0) {
796 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
797 goto pcm_err;
798 }
799
800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec);
803
804 return ret;
805
806pcm_err:
807 return ret;
808}
809
810/* power down chip */
811static int wm8580_remove(struct platform_device *pdev)
812{
813 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
814
815 snd_soc_free_pcms(socdev);
816 snd_soc_dapm_free(socdev);
817
818 return 0;
819}
820
821struct snd_soc_codec_device soc_codec_dev_wm8580 = {
822 .probe = wm8580_probe,
823 .remove = wm8580_remove,
824};
825EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
826 837
827static int wm8580_register(struct wm8580_priv *wm8580, 838static int wm8580_probe(struct snd_soc_codec *codec)
828 enum snd_soc_control_type control)
829{ 839{
830 int ret, i; 840 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
831 struct snd_soc_codec *codec = &wm8580->codec; 841 int ret = 0,i;
832
833 if (wm8580_codec) {
834 dev_err(codec->dev, "Another WM8580 is registered\n");
835 ret = -EINVAL;
836 goto err;
837 }
838
839 mutex_init(&codec->mutex);
840 INIT_LIST_HEAD(&codec->dapm_widgets);
841 INIT_LIST_HEAD(&codec->dapm_paths);
842
843 snd_soc_codec_set_drvdata(codec, wm8580);
844 codec->name = "WM8580";
845 codec->owner = THIS_MODULE;
846 codec->bias_level = SND_SOC_BIAS_OFF;
847 codec->set_bias_level = wm8580_set_bias_level;
848 codec->dai = wm8580_dai;
849 codec->num_dai = ARRAY_SIZE(wm8580_dai);
850 codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
851 codec->reg_cache = &wm8580->reg_cache;
852
853 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
854 842
855 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 843 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
856 if (ret < 0) { 844 if (ret < 0) {
857 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 845 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
858 goto err; 846 return ret;
859 } 847 }
860 848
861 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) 849 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
@@ -865,7 +853,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
865 wm8580->supplies); 853 wm8580->supplies);
866 if (ret != 0) { 854 if (ret != 0) {
867 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 855 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
868 goto err; 856 return ret;
869 } 857 }
870 858
871 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), 859 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
@@ -882,74 +870,68 @@ static int wm8580_register(struct wm8580_priv *wm8580,
882 goto err_regulator_enable; 870 goto err_regulator_enable;
883 } 871 }
884 872
885 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
886 wm8580_dai[i].dev = codec->dev;
887
888 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 873 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
889 874
890 wm8580_codec = codec; 875 snd_soc_add_controls(codec, wm8580_snd_controls,
891 876 ARRAY_SIZE(wm8580_snd_controls));
892 ret = snd_soc_register_codec(codec); 877 wm8580_add_widgets(codec);
893 if (ret != 0) {
894 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
895 goto err_regulator_enable;
896 }
897
898 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
899 if (ret != 0) {
900 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
901 goto err_codec;
902 }
903 878
904 return 0; 879 return 0;
905 880
906err_codec:
907 snd_soc_unregister_codec(codec);
908err_regulator_enable: 881err_regulator_enable:
909 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 882 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
910err_regulator_get: 883err_regulator_get:
911 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 884 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
912err:
913 kfree(wm8580);
914 return ret; 885 return ret;
915} 886}
916 887
917static void wm8580_unregister(struct wm8580_priv *wm8580) 888/* power down chip */
889static int wm8580_remove(struct snd_soc_codec *codec)
918{ 890{
919 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); 891 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
920 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 892
921 snd_soc_unregister_codec(&wm8580->codec); 893 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
894
922 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 895 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
923 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 896 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
924 kfree(wm8580); 897
925 wm8580_codec = NULL; 898 return 0;
926} 899}
927 900
901static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
902 .probe = wm8580_probe,
903 .remove = wm8580_remove,
904 .set_bias_level = wm8580_set_bias_level,
905 .reg_cache_size = ARRAY_SIZE(wm8580_reg),
906 .reg_word_size = sizeof(u16),
907 .reg_cache_default = wm8580_reg,
908};
909
928#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 910#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
929static int wm8580_i2c_probe(struct i2c_client *i2c, 911static int wm8580_i2c_probe(struct i2c_client *i2c,
930 const struct i2c_device_id *id) 912 const struct i2c_device_id *id)
931{ 913{
932 struct wm8580_priv *wm8580; 914 struct wm8580_priv *wm8580;
933 struct snd_soc_codec *codec; 915 int ret;
934 916
935 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); 917 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
936 if (wm8580 == NULL) 918 if (wm8580 == NULL)
937 return -ENOMEM; 919 return -ENOMEM;
938 920
939 codec = &wm8580->codec;
940
941 i2c_set_clientdata(i2c, wm8580); 921 i2c_set_clientdata(i2c, wm8580);
942 codec->control_data = i2c; 922 wm8580->control_type = SND_SOC_I2C;
943 923
944 codec->dev = &i2c->dev; 924 ret = snd_soc_register_codec(&i2c->dev,
945 925 &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
946 return wm8580_register(wm8580, SND_SOC_I2C); 926 if (ret < 0)
927 kfree(wm8580);
928 return ret;
947} 929}
948 930
949static int wm8580_i2c_remove(struct i2c_client *client) 931static int wm8580_i2c_remove(struct i2c_client *client)
950{ 932{
951 struct wm8580_priv *wm8580 = i2c_get_clientdata(client); 933 snd_soc_unregister_codec(&client->dev);
952 wm8580_unregister(wm8580); 934 kfree(i2c_get_clientdata(client));
953 return 0; 935 return 0;
954} 936}
955 937
@@ -961,7 +943,7 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
961 943
962static struct i2c_driver wm8580_i2c_driver = { 944static struct i2c_driver wm8580_i2c_driver = {
963 .driver = { 945 .driver = {
964 .name = "wm8580", 946 .name = "wm8580-codec",
965 .owner = THIS_MODULE, 947 .owner = THIS_MODULE,
966 }, 948 },
967 .probe = wm8580_i2c_probe, 949 .probe = wm8580_i2c_probe,
@@ -972,7 +954,7 @@ static struct i2c_driver wm8580_i2c_driver = {
972 954
973static int __init wm8580_modinit(void) 955static int __init wm8580_modinit(void)
974{ 956{
975 int ret; 957 int ret = 0;
976 958
977#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 959#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
978 ret = i2c_add_driver(&wm8580_i2c_driver); 960 ret = i2c_add_driver(&wm8580_i2c_driver);
@@ -981,7 +963,7 @@ static int __init wm8580_modinit(void)
981 } 963 }
982#endif 964#endif
983 965
984 return 0; 966 return ret;
985} 967}
986module_init(wm8580_modinit); 968module_init(wm8580_modinit);
987 969
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 0dfb5ddde6a2..1d34656d0dcb 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -19,20 +19,17 @@
19#define WM8580_PLLB 2 19#define WM8580_PLLB 2
20 20
21#define WM8580_MCLK 1 21#define WM8580_MCLK 1
22#define WM8580_DAC_CLKSEL 2 22#define WM8580_CLKOUTSRC 2
23#define WM8580_CLKOUTSRC 3
24 23
25#define WM8580_CLKSRC_MCLK 1 24#define WM8580_CLKSRC_MCLK 1
26#define WM8580_CLKSRC_PLLA 2 25#define WM8580_CLKSRC_PLLA 2
27#define WM8580_CLKSRC_PLLB 3 26#define WM8580_CLKSRC_PLLB 3
28#define WM8580_CLKSRC_OSC 4 27#define WM8580_CLKSRC_OSC 4
29#define WM8580_CLKSRC_NONE 5 28#define WM8580_CLKSRC_NONE 5
29#define WM8580_CLKSRC_ADCMCLK 6
30 30
31#define WM8580_DAI_PAIFRX 0 31#define WM8580_DAI_PAIFRX 0
32#define WM8580_DAI_PAIFTX 1 32#define WM8580_DAI_PAIFTX 1
33 33
34extern struct snd_soc_dai wm8580_dai[];
35extern struct snd_soc_codec_device soc_codec_dev_wm8580;
36
37#endif 34#endif
38 35
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index e2dba07f0260..a537e4af6ae7 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -25,18 +25,14 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31 30
32#include "wm8711.h" 31#include "wm8711.h"
33 32
34static struct snd_soc_codec *wm8711_codec;
35
36/* codec private data */ 33/* codec private data */
37struct wm8711_priv { 34struct wm8711_priv {
38 struct snd_soc_codec codec; 35 enum snd_soc_control_type bus_type;
39 u16 reg_cache[WM8711_CACHEREGNUM];
40 unsigned int sysclk; 36 unsigned int sysclk;
41}; 37};
42 38
@@ -81,7 +77,7 @@ SND_SOC_DAPM_OUTPUT("ROUT"),
81SND_SOC_DAPM_OUTPUT("RHPOUT"), 77SND_SOC_DAPM_OUTPUT("RHPOUT"),
82}; 78};
83 79
84static const struct snd_soc_dapm_route intercon[] = { 80static const struct snd_soc_dapm_route wm8711_intercon[] = {
85 /* output mixer */ 81 /* output mixer */
86 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 82 {"Output Mixer", "Line Bypass Switch", "Line Input"},
87 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 83 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -93,16 +89,6 @@ static const struct snd_soc_dapm_route intercon[] = {
93 {"LOUT", NULL, "Output Mixer"}, 89 {"LOUT", NULL, "Output Mixer"},
94}; 90};
95 91
96static int wm8711_add_widgets(struct snd_soc_codec *codec)
97{
98 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
99 ARRAY_SIZE(wm8711_dapm_widgets));
100
101 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
102
103 return 0;
104}
105
106struct _coeff_div { 92struct _coeff_div {
107 u32 mclk; 93 u32 mclk;
108 u32 rate; 94 u32 rate;
@@ -163,7 +149,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai) 149 struct snd_soc_dai *dai)
164{ 150{
165 struct snd_soc_codec *codec = dai->codec; 151 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 152 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; 153 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params)); 154 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) | 155 u16 srate = (coeff_div[i].sr << 2) |
@@ -227,7 +213,7 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir) 213 int clk_id, unsigned int freq, int dir)
228{ 214{
229 struct snd_soc_codec *codec = codec_dai->codec; 215 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); 216 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
231 217
232 switch (freq) { 218 switch (freq) {
233 case 11289600: 219 case 11289600:
@@ -320,7 +306,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
320 snd_soc_write(codec, WM8711_PWR, 0xffff); 306 snd_soc_write(codec, WM8711_PWR, 0xffff);
321 break; 307 break;
322 } 308 }
323 codec->bias_level = level; 309 codec->dapm.bias_level = level;
324 return 0; 310 return 0;
325} 311}
326 312
@@ -338,8 +324,8 @@ static struct snd_soc_dai_ops wm8711_ops = {
338 .set_fmt = wm8711_set_dai_fmt, 324 .set_fmt = wm8711_set_dai_fmt,
339}; 325};
340 326
341struct snd_soc_dai wm8711_dai = { 327static struct snd_soc_dai_driver wm8711_dai = {
342 .name = "WM8711", 328 .name = "wm8711-hifi",
343 .playback = { 329 .playback = {
344 .stream_name = "Playback", 330 .stream_name = "Playback",
345 .channels_min = 1, 331 .channels_min = 1,
@@ -349,22 +335,16 @@ struct snd_soc_dai wm8711_dai = {
349 }, 335 },
350 .ops = &wm8711_ops, 336 .ops = &wm8711_ops,
351}; 337};
352EXPORT_SYMBOL_GPL(wm8711_dai);
353 338
354static int wm8711_suspend(struct platform_device *pdev, pm_message_t state) 339static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state)
355{ 340{
356 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
357 struct snd_soc_codec *codec = socdev->card->codec;
358
359 snd_soc_write(codec, WM8711_ACTIVE, 0x0); 341 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
360 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF); 342 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
361 return 0; 343 return 0;
362} 344}
363 345
364static int wm8711_resume(struct platform_device *pdev) 346static int wm8711_resume(struct snd_soc_codec *codec)
365{ 347{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec = socdev->card->codec;
368 int i; 348 int i;
369 u8 data[2]; 349 u8 data[2];
370 u16 *cache = codec->reg_cache; 350 u16 *cache = codec->reg_cache;
@@ -380,99 +360,23 @@ static int wm8711_resume(struct platform_device *pdev)
380 return 0; 360 return 0;
381} 361}
382 362
383static int wm8711_probe(struct platform_device *pdev) 363static int wm8711_probe(struct snd_soc_codec *codec)
384{
385 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
386 struct snd_soc_codec *codec;
387 int ret = 0;
388
389 if (wm8711_codec == NULL) {
390 dev_err(&pdev->dev, "Codec device not registered\n");
391 return -ENODEV;
392 }
393
394 socdev->card->codec = wm8711_codec;
395 codec = wm8711_codec;
396
397 /* register pcms */
398 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
399 if (ret < 0) {
400 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
401 goto pcm_err;
402 }
403
404 snd_soc_add_controls(codec, wm8711_snd_controls,
405 ARRAY_SIZE(wm8711_snd_controls));
406 wm8711_add_widgets(codec);
407
408 return ret;
409
410pcm_err:
411 return ret;
412}
413
414/* power down chip */
415static int wm8711_remove(struct platform_device *pdev)
416{
417 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
418
419 snd_soc_free_pcms(socdev);
420 snd_soc_dapm_free(socdev);
421
422 return 0;
423}
424
425struct snd_soc_codec_device soc_codec_dev_wm8711 = {
426 .probe = wm8711_probe,
427 .remove = wm8711_remove,
428 .suspend = wm8711_suspend,
429 .resume = wm8711_resume,
430};
431EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
432
433static int wm8711_register(struct wm8711_priv *wm8711,
434 enum snd_soc_control_type control)
435{ 364{
436 int ret; 365 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
437 struct snd_soc_codec *codec = &wm8711->codec; 366 int ret, reg;
438 u16 reg;
439
440 if (wm8711_codec) {
441 dev_err(codec->dev, "Another WM8711 is registered\n");
442 ret = -EINVAL;
443 goto err;
444 }
445
446 mutex_init(&codec->mutex);
447 INIT_LIST_HEAD(&codec->dapm_widgets);
448 INIT_LIST_HEAD(&codec->dapm_paths);
449
450 snd_soc_codec_set_drvdata(codec, wm8711);
451 codec->name = "WM8711";
452 codec->owner = THIS_MODULE;
453 codec->bias_level = SND_SOC_BIAS_OFF;
454 codec->set_bias_level = wm8711_set_bias_level;
455 codec->dai = &wm8711_dai;
456 codec->num_dai = 1;
457 codec->reg_cache_size = WM8711_CACHEREGNUM;
458 codec->reg_cache = &wm8711->reg_cache;
459
460 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
461 367
462 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 368 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
463 if (ret < 0) { 369 if (ret < 0) {
464 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 370 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
465 goto err; 371 return ret;
466 } 372 }
467 373
468 ret = wm8711_reset(codec); 374 ret = wm8711_reset(codec);
469 if (ret < 0) { 375 if (ret < 0) {
470 dev_err(codec->dev, "Failed to issue reset\n"); 376 dev_err(codec->dev, "Failed to issue reset\n");
471 goto err; 377 return ret;
472 } 378 }
473 379
474 wm8711_dai.dev = codec->dev;
475
476 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 380 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
477 381
478 /* Latch the update bits */ 382 /* Latch the update bits */
@@ -481,70 +385,65 @@ static int wm8711_register(struct wm8711_priv *wm8711,
481 reg = snd_soc_read(codec, WM8711_ROUT1V); 385 reg = snd_soc_read(codec, WM8711_ROUT1V);
482 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100); 386 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
483 387
484 wm8711_codec = codec; 388 snd_soc_add_controls(codec, wm8711_snd_controls,
485 389 ARRAY_SIZE(wm8711_snd_controls));
486 ret = snd_soc_register_codec(codec);
487 if (ret != 0) {
488 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
489 goto err;
490 }
491
492 ret = snd_soc_register_dai(&wm8711_dai);
493 if (ret != 0) {
494 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
495 goto err_codec;
496 }
497
498 return 0;
499 390
500err_codec:
501 snd_soc_unregister_codec(codec);
502err:
503 kfree(wm8711);
504 return ret; 391 return ret;
392
505} 393}
506 394
507static void wm8711_unregister(struct wm8711_priv *wm8711) 395/* power down chip */
396static int wm8711_remove(struct snd_soc_codec *codec)
508{ 397{
509 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF); 398 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
510 snd_soc_unregister_dai(&wm8711_dai); 399 return 0;
511 snd_soc_unregister_codec(&wm8711->codec);
512 kfree(wm8711);
513 wm8711_codec = NULL;
514} 400}
515 401
402static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
403 .probe = wm8711_probe,
404 .remove = wm8711_remove,
405 .suspend = wm8711_suspend,
406 .resume = wm8711_resume,
407 .set_bias_level = wm8711_set_bias_level,
408 .reg_cache_size = ARRAY_SIZE(wm8711_reg),
409 .reg_word_size = sizeof(u16),
410 .reg_cache_default = wm8711_reg,
411 .dapm_widgets = wm8711_dapm_widgets,
412 .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets),
413 .dapm_routes = wm8711_intercon,
414 .num_dapm_routes = ARRAY_SIZE(wm8711_intercon),
415};
416
516#if defined(CONFIG_SPI_MASTER) 417#if defined(CONFIG_SPI_MASTER)
517static int __devinit wm8711_spi_probe(struct spi_device *spi) 418static int __devinit wm8711_spi_probe(struct spi_device *spi)
518{ 419{
519 struct snd_soc_codec *codec;
520 struct wm8711_priv *wm8711; 420 struct wm8711_priv *wm8711;
421 int ret;
521 422
522 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL); 423 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
523 if (wm8711 == NULL) 424 if (wm8711 == NULL)
524 return -ENOMEM; 425 return -ENOMEM;
525 426
526 codec = &wm8711->codec; 427 spi_set_drvdata(spi, wm8711);
527 codec->control_data = spi; 428 wm8711->bus_type = SND_SOC_SPI;
528 codec->dev = &spi->dev;
529 429
530 dev_set_drvdata(&spi->dev, wm8711); 430 ret = snd_soc_register_codec(&spi->dev,
531 431 &soc_codec_dev_wm8711, &wm8711_dai, 1);
532 return wm8711_register(wm8711, SND_SOC_SPI); 432 if (ret < 0)
433 kfree(wm8711);
434 return ret;
533} 435}
534 436
535static int __devexit wm8711_spi_remove(struct spi_device *spi) 437static int __devexit wm8711_spi_remove(struct spi_device *spi)
536{ 438{
537 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev); 439 snd_soc_unregister_codec(&spi->dev);
538 440 kfree(spi_get_drvdata(spi));
539 wm8711_unregister(wm8711);
540
541 return 0; 441 return 0;
542} 442}
543 443
544static struct spi_driver wm8711_spi_driver = { 444static struct spi_driver wm8711_spi_driver = {
545 .driver = { 445 .driver = {
546 .name = "wm8711", 446 .name = "wm8711-codec",
547 .bus = &spi_bus_type,
548 .owner = THIS_MODULE, 447 .owner = THIS_MODULE,
549 }, 448 },
550 .probe = wm8711_spi_probe, 449 .probe = wm8711_spi_probe,
@@ -553,31 +452,30 @@ static struct spi_driver wm8711_spi_driver = {
553#endif /* CONFIG_SPI_MASTER */ 452#endif /* CONFIG_SPI_MASTER */
554 453
555#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 454#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
556static __devinit int wm8711_i2c_probe(struct i2c_client *i2c, 455static __devinit int wm8711_i2c_probe(struct i2c_client *client,
557 const struct i2c_device_id *id) 456 const struct i2c_device_id *id)
558{ 457{
559 struct wm8711_priv *wm8711; 458 struct wm8711_priv *wm8711;
560 struct snd_soc_codec *codec; 459 int ret;
561 460
562 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL); 461 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
563 if (wm8711 == NULL) 462 if (wm8711 == NULL)
564 return -ENOMEM; 463 return -ENOMEM;
565 464
566 codec = &wm8711->codec; 465 i2c_set_clientdata(client, wm8711);
567 codec->hw_write = (hw_write_t)i2c_master_send; 466 wm8711->bus_type = SND_SOC_I2C;
568
569 i2c_set_clientdata(i2c, wm8711);
570 codec->control_data = i2c;
571 467
572 codec->dev = &i2c->dev; 468 ret = snd_soc_register_codec(&client->dev,
573 469 &soc_codec_dev_wm8711, &wm8711_dai, 1);
574 return wm8711_register(wm8711, SND_SOC_I2C); 470 if (ret < 0)
471 kfree(wm8711);
472 return ret;
575} 473}
576 474
577static __devexit int wm8711_i2c_remove(struct i2c_client *client) 475static __devexit int wm8711_i2c_remove(struct i2c_client *client)
578{ 476{
579 struct wm8711_priv *wm8711 = i2c_get_clientdata(client); 477 snd_soc_unregister_codec(&client->dev);
580 wm8711_unregister(wm8711); 478 kfree(i2c_get_clientdata(client));
581 return 0; 479 return 0;
582} 480}
583 481
@@ -589,7 +487,7 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
589 487
590static struct i2c_driver wm8711_i2c_driver = { 488static struct i2c_driver wm8711_i2c_driver = {
591 .driver = { 489 .driver = {
592 .name = "WM8711 I2C Codec", 490 .name = "wm8711-codec",
593 .owner = THIS_MODULE, 491 .owner = THIS_MODULE,
594 }, 492 },
595 .probe = wm8711_i2c_probe, 493 .probe = wm8711_i2c_probe,
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
index 381e84a43816..a61db985499f 100644
--- a/sound/soc/codecs/wm8711.h
+++ b/sound/soc/codecs/wm8711.h
@@ -36,7 +36,4 @@ struct wm8711_setup_data {
36 unsigned short i2c_address; 36 unsigned short i2c_address;
37}; 37};
38 38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif 39#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 9d1df2628136..748808285119 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -23,7 +23,6 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25 25
26#include "wm8727.h"
27/* 26/*
28 * Note this is a simple chip with no configuration interface, sample rate is 27 * Note this is a simple chip with no configuration interface, sample rate is
29 * determined automatically by examining the Master clock and Bit clock ratios 28 * determined automatically by examining the Master clock and Bit clock ratios
@@ -33,8 +32,8 @@
33 SNDRV_PCM_RATE_192000) 32 SNDRV_PCM_RATE_192000)
34 33
35 34
36struct snd_soc_dai wm8727_dai = { 35static struct snd_soc_dai_driver wm8727_dai = {
37 .name = "WM8727", 36 .name = "wm8727-hifi",
38 .playback = { 37 .playback = {
39 .stream_name = "Playback", 38 .stream_name = "Playback",
40 .channels_min = 2, 39 .channels_min = 2,
@@ -43,103 +42,18 @@ struct snd_soc_dai wm8727_dai = {
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, 42 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
44 }, 43 },
45}; 44};
46EXPORT_SYMBOL_GPL(wm8727_dai);
47 45
48static struct snd_soc_codec *wm8727_codec; 46static struct snd_soc_codec_driver soc_codec_dev_wm8727;
49 47
50static int wm8727_soc_probe(struct platform_device *pdev) 48static __devinit int wm8727_probe(struct platform_device *pdev)
51{ 49{
52 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 50 return snd_soc_register_codec(&pdev->dev,
53 int ret = 0; 51 &soc_codec_dev_wm8727, &wm8727_dai, 1);
54
55 BUG_ON(!wm8727_codec);
56
57 socdev->card->codec = wm8727_codec;
58
59 /* register pcms */
60 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
61 if (ret < 0) {
62 printk(KERN_ERR "wm8727: failed to create pcms\n");
63 goto pcm_err;
64 }
65
66 return ret;
67
68pcm_err:
69 kfree(socdev->card->codec);
70 socdev->card->codec = NULL;
71 return ret;
72}
73
74static int wm8727_soc_remove(struct platform_device *pdev)
75{
76 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
77
78 snd_soc_free_pcms(socdev);
79
80 return 0;
81}
82
83struct snd_soc_codec_device soc_codec_dev_wm8727 = {
84 .probe = wm8727_soc_probe,
85 .remove = wm8727_soc_remove,
86};
87EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
88
89
90static __devinit int wm8727_platform_probe(struct platform_device *pdev)
91{
92 struct snd_soc_codec *codec;
93 int ret;
94
95 if (wm8727_codec) {
96 dev_err(&pdev->dev, "Another WM8727 is registered\n");
97 return -EBUSY;
98 }
99
100 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
101 if (codec == NULL)
102 return -ENOMEM;
103 wm8727_codec = codec;
104
105 platform_set_drvdata(pdev, codec);
106
107 mutex_init(&codec->mutex);
108 codec->dev = &pdev->dev;
109 codec->name = "WM8727";
110 codec->owner = THIS_MODULE;
111 codec->dai = &wm8727_dai;
112 codec->num_dai = 1;
113 INIT_LIST_HEAD(&codec->dapm_widgets);
114 INIT_LIST_HEAD(&codec->dapm_paths);
115
116 wm8727_dai.dev = &pdev->dev;
117
118 ret = snd_soc_register_codec(codec);
119 if (ret != 0) {
120 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
121 goto err;
122 }
123
124 ret = snd_soc_register_dai(&wm8727_dai);
125 if (ret != 0) {
126 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
127 goto err_codec;
128 }
129
130 return 0;
131
132err_codec:
133 snd_soc_unregister_codec(codec);
134err:
135 kfree(codec);
136 return ret;
137} 52}
138 53
139static int __devexit wm8727_platform_remove(struct platform_device *pdev) 54static int __devexit wm8727_remove(struct platform_device *pdev)
140{ 55{
141 snd_soc_unregister_dai(&wm8727_dai); 56 snd_soc_unregister_codec(&pdev->dev);
142 snd_soc_unregister_codec(platform_get_drvdata(pdev));
143 return 0; 57 return 0;
144} 58}
145 59
@@ -149,8 +63,8 @@ static struct platform_driver wm8727_codec_driver = {
149 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
150 }, 64 },
151 65
152 .probe = wm8727_platform_probe, 66 .probe = wm8727_probe,
153 .remove = __devexit_p(wm8727_platform_remove), 67 .remove = __devexit_p(wm8727_remove),
154}; 68};
155 69
156static int __init wm8727_init(void) 70static int __init wm8727_init(void)
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
deleted file mode 100644
index ee19aa71bcdc..000000000000
--- a/sound/soc/codecs/wm8727.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 34be2d2b69ef..86d4718d3a76 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -23,14 +23,11 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
30#include "wm8728.h" 29#include "wm8728.h"
31 30
32struct snd_soc_codec_device soc_codec_dev_wm8728;
33
34/* 31/*
35 * We can't read the WM8728 register space so we cache them instead. 32 * We can't read the WM8728 register space so we cache them instead.
36 * Note that the defaults here aren't the physical defaults, we latch 33 * Note that the defaults here aren't the physical defaults, we latch
@@ -44,6 +41,11 @@ static const u16 wm8728_reg_defaults[] = {
44 0x100, 41 0x100,
45}; 42};
46 43
44/* codec private data */
45struct wm8728_priv {
46 enum snd_soc_control_type control_type;
47};
48
47static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1); 49static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
48 50
49static const struct snd_kcontrol_new wm8728_snd_controls[] = { 51static const struct snd_kcontrol_new wm8728_snd_controls[] = {
@@ -63,21 +65,11 @@ SND_SOC_DAPM_OUTPUT("VOUTL"),
63SND_SOC_DAPM_OUTPUT("VOUTR"), 65SND_SOC_DAPM_OUTPUT("VOUTR"),
64}; 66};
65 67
66static const struct snd_soc_dapm_route intercon[] = { 68static const struct snd_soc_dapm_route wm8728_intercon[] = {
67 {"VOUTL", NULL, "DAC"}, 69 {"VOUTL", NULL, "DAC"},
68 {"VOUTR", NULL, "DAC"}, 70 {"VOUTR", NULL, "DAC"},
69}; 71};
70 72
71static int wm8728_add_widgets(struct snd_soc_codec *codec)
72{
73 snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
74 ARRAY_SIZE(wm8728_dapm_widgets));
75
76 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
77
78 return 0;
79}
80
81static int wm8728_mute(struct snd_soc_dai *dai, int mute) 73static int wm8728_mute(struct snd_soc_dai *dai, int mute)
82{ 74{
83 struct snd_soc_codec *codec = dai->codec; 75 struct snd_soc_codec *codec = dai->codec;
@@ -96,8 +88,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *dai) 88 struct snd_soc_dai *dai)
97{ 89{
98 struct snd_soc_pcm_runtime *rtd = substream->private_data; 90 struct snd_soc_pcm_runtime *rtd = substream->private_data;
99 struct snd_soc_device *socdev = rtd->socdev; 91 struct snd_soc_codec *codec = rtd->codec;
100 struct snd_soc_codec *codec = socdev->card->codec;
101 u16 dac = snd_soc_read(codec, WM8728_DACCTL); 92 u16 dac = snd_soc_read(codec, WM8728_DACCTL);
102 93
103 dac &= ~0x18; 94 dac &= ~0x18;
@@ -178,7 +169,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
178 case SND_SOC_BIAS_ON: 169 case SND_SOC_BIAS_ON:
179 case SND_SOC_BIAS_PREPARE: 170 case SND_SOC_BIAS_PREPARE:
180 case SND_SOC_BIAS_STANDBY: 171 case SND_SOC_BIAS_STANDBY:
181 if (codec->bias_level == SND_SOC_BIAS_OFF) { 172 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
182 /* Power everything up... */ 173 /* Power everything up... */
183 reg = snd_soc_read(codec, WM8728_DACCTL); 174 reg = snd_soc_read(codec, WM8728_DACCTL);
184 snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); 175 snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
@@ -195,7 +186,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
195 snd_soc_write(codec, WM8728_DACCTL, reg | 0x4); 186 snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
196 break; 187 break;
197 } 188 }
198 codec->bias_level = level; 189 codec->dapm.bias_level = level;
199 return 0; 190 return 0;
200} 191}
201 192
@@ -210,8 +201,8 @@ static struct snd_soc_dai_ops wm8728_dai_ops = {
210 .set_fmt = wm8728_set_dai_fmt, 201 .set_fmt = wm8728_set_dai_fmt,
211}; 202};
212 203
213struct snd_soc_dai wm8728_dai = { 204static struct snd_soc_dai_driver wm8728_dai = {
214 .name = "WM8728", 205 .name = "wm8728-hifi",
215 .playback = { 206 .playback = {
216 .stream_name = "Playback", 207 .stream_name = "Playback",
217 .channels_min = 2, 208 .channels_min = 2,
@@ -221,63 +212,31 @@ struct snd_soc_dai wm8728_dai = {
221 }, 212 },
222 .ops = &wm8728_dai_ops, 213 .ops = &wm8728_dai_ops,
223}; 214};
224EXPORT_SYMBOL_GPL(wm8728_dai);
225 215
226static int wm8728_suspend(struct platform_device *pdev, pm_message_t state) 216static int wm8728_suspend(struct snd_soc_codec *codec, pm_message_t state)
227{ 217{
228 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
229 struct snd_soc_codec *codec = socdev->card->codec;
230
231 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); 218 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
232 219
233 return 0; 220 return 0;
234} 221}
235 222
236static int wm8728_resume(struct platform_device *pdev) 223static int wm8728_resume(struct snd_soc_codec *codec)
237{ 224{
238 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
239 struct snd_soc_codec *codec = socdev->card->codec;
240
241 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 225 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
242 226
243 return 0; 227 return 0;
244} 228}
245 229
246/* 230static int wm8728_probe(struct snd_soc_codec *codec)
247 * initialise the WM8728 driver
248 * register the mixer and dsp interfaces with the kernel
249 */
250static int wm8728_init(struct snd_soc_device *socdev,
251 enum snd_soc_control_type control)
252{ 231{
253 struct snd_soc_codec *codec = socdev->card->codec; 232 struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
254 int ret = 0; 233 int ret;
255
256 codec->name = "WM8728";
257 codec->owner = THIS_MODULE;
258 codec->set_bias_level = wm8728_set_bias_level;
259 codec->dai = &wm8728_dai;
260 codec->num_dai = 1;
261 codec->bias_level = SND_SOC_BIAS_OFF;
262 codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
263 codec->reg_cache = kmemdup(wm8728_reg_defaults,
264 sizeof(wm8728_reg_defaults),
265 GFP_KERNEL);
266 if (codec->reg_cache == NULL)
267 return -ENOMEM;
268 234
269 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 235 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type);
270 if (ret < 0) { 236 if (ret < 0) {
271 printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n", 237 printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
272 ret); 238 ret);
273 goto err; 239 return ret;
274 }
275
276 /* register pcms */
277 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
278 if (ret < 0) {
279 printk(KERN_ERR "wm8728: failed to create pcms\n");
280 goto err;
281 } 240 }
282 241
283 /* power on device */ 242 /* power on device */
@@ -285,218 +244,142 @@ static int wm8728_init(struct snd_soc_device *socdev,
285 244
286 snd_soc_add_controls(codec, wm8728_snd_controls, 245 snd_soc_add_controls(codec, wm8728_snd_controls,
287 ARRAY_SIZE(wm8728_snd_controls)); 246 ARRAY_SIZE(wm8728_snd_controls));
288 wm8728_add_widgets(codec);
289
290 return ret;
291 247
292err:
293 kfree(codec->reg_cache);
294 return ret; 248 return ret;
295} 249}
296 250
297static struct snd_soc_device *wm8728_socdev; 251static int wm8728_remove(struct snd_soc_codec *codec)
298 252{
299#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 253 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
254 return 0;
255}
300 256
301/* 257static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
302 * WM8728 2 wire address is determined by GPIO5 258 .probe = wm8728_probe,
303 * state during powerup. 259 .remove = wm8728_remove,
304 * low = 0x1a 260 .suspend = wm8728_suspend,
305 * high = 0x1b 261 .resume = wm8728_resume,
306 */ 262 .set_bias_level = wm8728_set_bias_level,
263 .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
264 .reg_word_size = sizeof(u16),
265 .reg_cache_default = wm8728_reg_defaults,
266 .dapm_widgets = wm8728_dapm_widgets,
267 .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets),
268 .dapm_routes = wm8728_intercon,
269 .num_dapm_routes = ARRAY_SIZE(wm8728_intercon),
270};
307 271
308static int wm8728_i2c_probe(struct i2c_client *i2c, 272#if defined(CONFIG_SPI_MASTER)
309 const struct i2c_device_id *id) 273static int __devinit wm8728_spi_probe(struct spi_device *spi)
310{ 274{
311 struct snd_soc_device *socdev = wm8728_socdev; 275 struct wm8728_priv *wm8728;
312 struct snd_soc_codec *codec = socdev->card->codec;
313 int ret; 276 int ret;
314 277
315 i2c_set_clientdata(i2c, codec); 278 wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
316 codec->control_data = i2c; 279 if (wm8728 == NULL)
280 return -ENOMEM;
281
282 wm8728->control_type = SND_SOC_SPI;
283 spi_set_drvdata(spi, wm8728);
317 284
318 ret = wm8728_init(socdev, SND_SOC_I2C); 285 ret = snd_soc_register_codec(&spi->dev,
286 &soc_codec_dev_wm8728, &wm8728_dai, 1);
319 if (ret < 0) 287 if (ret < 0)
320 pr_err("failed to initialise WM8728\n"); 288 kfree(wm8728);
321
322 return ret; 289 return ret;
323} 290}
324 291
325static int wm8728_i2c_remove(struct i2c_client *client) 292static int __devexit wm8728_spi_remove(struct spi_device *spi)
326{ 293{
327 struct snd_soc_codec *codec = i2c_get_clientdata(client); 294 snd_soc_unregister_codec(&spi->dev);
328 kfree(codec->reg_cache); 295 kfree(spi_get_drvdata(spi));
329 return 0; 296 return 0;
330} 297}
331 298
332static const struct i2c_device_id wm8728_i2c_id[] = { 299static struct spi_driver wm8728_spi_driver = {
333 { "wm8728", 0 },
334 { }
335};
336MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
337
338static struct i2c_driver wm8728_i2c_driver = {
339 .driver = { 300 .driver = {
340 .name = "WM8728 I2C Codec", 301 .name = "wm8728-codec",
341 .owner = THIS_MODULE, 302 .owner = THIS_MODULE,
342 }, 303 },
343 .probe = wm8728_i2c_probe, 304 .probe = wm8728_spi_probe,
344 .remove = wm8728_i2c_remove, 305 .remove = __devexit_p(wm8728_spi_remove),
345 .id_table = wm8728_i2c_id,
346}; 306};
307#endif /* CONFIG_SPI_MASTER */
347 308
348static int wm8728_add_i2c_device(struct platform_device *pdev, 309#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
349 const struct wm8728_setup_data *setup) 310static __devinit int wm8728_i2c_probe(struct i2c_client *i2c,
311 const struct i2c_device_id *id)
350{ 312{
351 struct i2c_board_info info; 313 struct wm8728_priv *wm8728;
352 struct i2c_adapter *adapter;
353 struct i2c_client *client;
354 int ret; 314 int ret;
355 315
356 ret = i2c_add_driver(&wm8728_i2c_driver); 316 wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
357 if (ret != 0) { 317 if (wm8728 == NULL)
358 dev_err(&pdev->dev, "can't add i2c driver\n"); 318 return -ENOMEM;
359 return ret;
360 }
361
362 memset(&info, 0, sizeof(struct i2c_board_info));
363 info.addr = setup->i2c_address;
364 strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
365
366 adapter = i2c_get_adapter(setup->i2c_bus);
367 if (!adapter) {
368 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
369 setup->i2c_bus);
370 goto err_driver;
371 }
372
373 client = i2c_new_device(adapter, &info);
374 i2c_put_adapter(adapter);
375 if (!client) {
376 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
377 (unsigned int)info.addr);
378 goto err_driver;
379 }
380
381 return 0;
382
383err_driver:
384 i2c_del_driver(&wm8728_i2c_driver);
385 return -ENODEV;
386}
387#endif
388
389#if defined(CONFIG_SPI_MASTER)
390static int __devinit wm8728_spi_probe(struct spi_device *spi)
391{
392 struct snd_soc_device *socdev = wm8728_socdev;
393 struct snd_soc_codec *codec = socdev->card->codec;
394 int ret;
395 319
396 codec->control_data = spi; 320 i2c_set_clientdata(i2c, wm8728);
321 wm8728->control_type = SND_SOC_I2C;
397 322
398 ret = wm8728_init(socdev, SND_SOC_SPI); 323 ret = snd_soc_register_codec(&i2c->dev,
324 &soc_codec_dev_wm8728, &wm8728_dai, 1);
399 if (ret < 0) 325 if (ret < 0)
400 dev_err(&spi->dev, "failed to initialise WM8728\n"); 326 kfree(wm8728);
401
402 return ret; 327 return ret;
403} 328}
404 329
405static int __devexit wm8728_spi_remove(struct spi_device *spi) 330static __devexit int wm8728_i2c_remove(struct i2c_client *client)
406{ 331{
332 snd_soc_unregister_codec(&client->dev);
333 kfree(i2c_get_clientdata(client));
407 return 0; 334 return 0;
408} 335}
409 336
410static struct spi_driver wm8728_spi_driver = { 337static const struct i2c_device_id wm8728_i2c_id[] = {
338 { "wm8728", 0 },
339 { }
340};
341MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
342
343static struct i2c_driver wm8728_i2c_driver = {
411 .driver = { 344 .driver = {
412 .name = "wm8728", 345 .name = "wm8728-codec",
413 .bus = &spi_bus_type, 346 .owner = THIS_MODULE,
414 .owner = THIS_MODULE,
415 }, 347 },
416 .probe = wm8728_spi_probe, 348 .probe = wm8728_i2c_probe,
417 .remove = __devexit_p(wm8728_spi_remove), 349 .remove = __devexit_p(wm8728_i2c_remove),
350 .id_table = wm8728_i2c_id,
418}; 351};
419#endif /* CONFIG_SPI_MASTER */ 352#endif
420 353
421static int wm8728_probe(struct platform_device *pdev) 354static int __init wm8728_modinit(void)
422{ 355{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
424 struct wm8728_setup_data *setup;
425 struct snd_soc_codec *codec;
426 int ret = 0; 356 int ret = 0;
427
428 setup = socdev->codec_data;
429 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
430 if (codec == NULL)
431 return -ENOMEM;
432
433 socdev->card->codec = codec;
434 mutex_init(&codec->mutex);
435 INIT_LIST_HEAD(&codec->dapm_widgets);
436 INIT_LIST_HEAD(&codec->dapm_paths);
437
438 wm8728_socdev = socdev;
439 ret = -ENODEV;
440
441#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 357#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
442 if (setup->i2c_address) { 358 ret = i2c_add_driver(&wm8728_i2c_driver);
443 ret = wm8728_add_i2c_device(pdev, setup); 359 if (ret != 0) {
360 printk(KERN_ERR "Failed to register wm8728 I2C driver: %d\n",
361 ret);
444 } 362 }
445#endif 363#endif
446#if defined(CONFIG_SPI_MASTER) 364#if defined(CONFIG_SPI_MASTER)
447 if (setup->spi) { 365 ret = spi_register_driver(&wm8728_spi_driver);
448 ret = spi_register_driver(&wm8728_spi_driver); 366 if (ret != 0) {
449 if (ret != 0) 367 printk(KERN_ERR "Failed to register wm8728 SPI driver: %d\n",
450 printk(KERN_ERR "can't add spi driver"); 368 ret);
451 } 369 }
452#endif 370#endif
453
454 if (ret != 0)
455 kfree(codec);
456
457 return ret; 371 return ret;
458} 372}
373module_init(wm8728_modinit);
459 374
460/* power down chip */ 375static void __exit wm8728_exit(void)
461static int wm8728_remove(struct platform_device *pdev)
462{ 376{
463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
464 struct snd_soc_codec *codec = socdev->card->codec;
465
466 if (codec->control_data)
467 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
468
469 snd_soc_free_pcms(socdev);
470 snd_soc_dapm_free(socdev);
471#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 377#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
472 i2c_unregister_device(codec->control_data);
473 i2c_del_driver(&wm8728_i2c_driver); 378 i2c_del_driver(&wm8728_i2c_driver);
474#endif 379#endif
475#if defined(CONFIG_SPI_MASTER) 380#if defined(CONFIG_SPI_MASTER)
476 spi_unregister_driver(&wm8728_spi_driver); 381 spi_unregister_driver(&wm8728_spi_driver);
477#endif 382#endif
478 kfree(codec);
479
480 return 0;
481}
482
483struct snd_soc_codec_device soc_codec_dev_wm8728 = {
484 .probe = wm8728_probe,
485 .remove = wm8728_remove,
486 .suspend = wm8728_suspend,
487 .resume = wm8728_resume,
488};
489EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
490
491static int __init wm8728_modinit(void)
492{
493 return snd_soc_register_dai(&wm8728_dai);
494}
495module_init(wm8728_modinit);
496
497static void __exit wm8728_exit(void)
498{
499 snd_soc_unregister_dai(&wm8728_dai);
500} 383}
501module_exit(wm8728_exit); 384module_exit(wm8728_exit);
502 385
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
index d269c132474b..8aea362ffd47 100644
--- a/sound/soc/codecs/wm8728.h
+++ b/sound/soc/codecs/wm8728.h
@@ -18,13 +18,4 @@
18#define WM8728_DACCTL 0x02 18#define WM8728_DACCTL 0x02
19#define WM8728_IFCTL 0x03 19#define WM8728_IFCTL 0x03
20 20
21struct wm8728_setup_data {
22 int spi;
23 int i2c_bus;
24 unsigned short i2c_address;
25};
26
27extern struct snd_soc_dai wm8728_dai;
28extern struct snd_soc_codec_device soc_codec_dev_wm8728;
29
30#endif 21#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0ab9b6355297..76b4361e9b80 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -26,15 +26,11 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31#include <sound/tlv.h> 30#include <sound/tlv.h>
32 31
33#include "wm8731.h" 32#include "wm8731.h"
34 33
35static struct snd_soc_codec *wm8731_codec;
36struct snd_soc_codec_device soc_codec_dev_wm8731;
37
38#define WM8731_NUM_SUPPLIES 4 34#define WM8731_NUM_SUPPLIES 4
39static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { 35static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
40 "AVDD", 36 "AVDD",
@@ -45,10 +41,12 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45 41
46/* codec private data */ 42/* codec private data */
47struct wm8731_priv { 43struct wm8731_priv {
48 struct snd_soc_codec codec; 44 enum snd_soc_control_type control_type;
49 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 45 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
50 u16 reg_cache[WM8731_CACHEREGNUM];
51 unsigned int sysclk; 46 unsigned int sysclk;
47 int sysclk_type;
48 int playback_fs;
49 bool deemph;
52}; 50};
53 51
54 52
@@ -67,16 +65,79 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
67#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) 65#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
68 66
69static const char *wm8731_input_select[] = {"Line In", "Mic"}; 67static const char *wm8731_input_select[] = {"Line In", "Mic"};
70static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
71 68
72static const struct soc_enum wm8731_enum[] = { 69static const struct soc_enum wm8731_insel_enum =
73 SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select), 70 SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select);
74 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), 71
75}; 72static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
73
74static int wm8731_set_deemph(struct snd_soc_codec *codec)
75{
76 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
77 int val, i, best;
78
79 /* If we're using deemphasis select the nearest available sample
80 * rate.
81 */
82 if (wm8731->deemph) {
83 best = 1;
84 for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) {
85 if (abs(wm8731_deemph[i] - wm8731->playback_fs) <
86 abs(wm8731_deemph[best] - wm8731->playback_fs))
87 best = i;
88 }
89
90 val = best << 1;
91 } else {
92 best = 0;
93 val = 0;
94 }
95
96 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
97 best, wm8731_deemph[best]);
98
99 return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
100}
101
102static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
103 struct snd_ctl_elem_value *ucontrol)
104{
105 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
106 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
107
108 ucontrol->value.enumerated.item[0] = wm8731->deemph;
109
110 return 0;
111}
112
113static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
114 struct snd_ctl_elem_value *ucontrol)
115{
116 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
117 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
118 int deemph = ucontrol->value.enumerated.item[0];
119 int ret = 0;
120
121 if (deemph > 1)
122 return -EINVAL;
123
124 mutex_lock(&codec->mutex);
125 if (wm8731->deemph != deemph) {
126 wm8731->deemph = deemph;
127
128 wm8731_set_deemph(codec);
129
130 ret = 1;
131 }
132 mutex_unlock(&codec->mutex);
133
134 return ret;
135}
76 136
77static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); 137static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
78static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); 138static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
79static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 139static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
140static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0);
80 141
81static const struct snd_kcontrol_new wm8731_snd_controls[] = { 142static const struct snd_kcontrol_new wm8731_snd_controls[] = {
82 143
@@ -89,7 +150,7 @@ SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
89 in_tlv), 150 in_tlv),
90SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), 151SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
91 152
92SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), 153SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv),
93SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), 154SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
94 155
95SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, 156SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
@@ -98,7 +159,8 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
98SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 159SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
99SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 160SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
100 161
101SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), 162SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
163 wm8731_get_deemph, wm8731_put_deemph),
102}; 164};
103 165
104/* Output Mixer */ 166/* Output Mixer */
@@ -110,9 +172,11 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
110 172
111/* Input mux */ 173/* Input mux */
112static const struct snd_kcontrol_new wm8731_input_mux_controls = 174static const struct snd_kcontrol_new wm8731_input_mux_controls =
113SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); 175SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
114 176
115static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { 177static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
178SND_SOC_DAPM_SUPPLY("ACTIVE",WM8731_ACTIVE, 0, 0, NULL, 0),
179SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
116SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, 180SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1,
117 &wm8731_output_mixer_controls[0], 181 &wm8731_output_mixer_controls[0],
118 ARRAY_SIZE(wm8731_output_mixer_controls)), 182 ARRAY_SIZE(wm8731_output_mixer_controls)),
@@ -130,7 +194,20 @@ SND_SOC_DAPM_INPUT("RLINEIN"),
130SND_SOC_DAPM_INPUT("LLINEIN"), 194SND_SOC_DAPM_INPUT("LLINEIN"),
131}; 195};
132 196
133static const struct snd_soc_dapm_route intercon[] = { 197static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
198 struct snd_soc_dapm_widget *sink)
199{
200 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec);
201
202 return wm8731->sysclk_type == WM8731_SYSCLK_XTAL;
203}
204
205static const struct snd_soc_dapm_route wm8731_intercon[] = {
206 {"DAC", NULL, "OSC", wm8731_check_osc},
207 {"ADC", NULL, "OSC", wm8731_check_osc},
208 {"DAC", NULL, "ACTIVE"},
209 {"ADC", NULL, "ACTIVE"},
210
134 /* output mixer */ 211 /* output mixer */
135 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 212 {"Output Mixer", "Line Bypass Switch", "Line Input"},
136 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 213 {"Output Mixer", "HiFi Playback Switch", "DAC"},
@@ -153,16 +230,6 @@ static const struct snd_soc_dapm_route intercon[] = {
153 {"Mic Bias", NULL, "MICIN"}, 230 {"Mic Bias", NULL, "MICIN"},
154}; 231};
155 232
156static int wm8731_add_widgets(struct snd_soc_codec *codec)
157{
158 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
159 ARRAY_SIZE(wm8731_dapm_widgets));
160
161 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
162
163 return 0;
164}
165
166struct _coeff_div { 233struct _coeff_div {
167 u32 mclk; 234 u32 mclk;
168 u32 rate; 235 u32 rate;
@@ -222,15 +289,15 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params, 289 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai) 290 struct snd_soc_dai *dai)
224{ 291{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 292 struct snd_soc_codec *codec = dai->codec;
226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 293 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 294 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 295 int i = get_coeff(wm8731->sysclk, params_rate(params));
231 u16 srate = (coeff_div[i].sr << 2) | 296 u16 srate = (coeff_div[i].sr << 2) |
232 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 297 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
233 298
299 wm8731->playback_fs = params_rate(params);
300
234 snd_soc_write(codec, WM8731_SRATE, srate); 301 snd_soc_write(codec, WM8731_SRATE, srate);
235 302
236 /* bit size */ 303 /* bit size */
@@ -245,37 +312,12 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
245 break; 312 break;
246 } 313 }
247 314
248 snd_soc_write(codec, WM8731_IFACE, iface); 315 wm8731_set_deemph(codec);
249 return 0;
250}
251
252static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_dai *dai)
254{
255 struct snd_soc_pcm_runtime *rtd = substream->private_data;
256 struct snd_soc_device *socdev = rtd->socdev;
257 struct snd_soc_codec *codec = socdev->card->codec;
258
259 /* set active */
260 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
261 316
317 snd_soc_write(codec, WM8731_IFACE, iface);
262 return 0; 318 return 0;
263} 319}
264 320
265static void wm8731_shutdown(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *dai)
267{
268 struct snd_soc_pcm_runtime *rtd = substream->private_data;
269 struct snd_soc_device *socdev = rtd->socdev;
270 struct snd_soc_codec *codec = socdev->card->codec;
271
272 /* deactivate */
273 if (!codec->active) {
274 udelay(50);
275 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
276 }
277}
278
279static int wm8731_mute(struct snd_soc_dai *dai, int mute) 321static int wm8731_mute(struct snd_soc_dai *dai, int mute)
280{ 322{
281 struct snd_soc_codec *codec = dai->codec; 323 struct snd_soc_codec *codec = dai->codec;
@@ -294,6 +336,15 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
294 struct snd_soc_codec *codec = codec_dai->codec; 336 struct snd_soc_codec *codec = codec_dai->codec;
295 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 337 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
296 338
339 switch (clk_id) {
340 case WM8731_SYSCLK_XTAL:
341 case WM8731_SYSCLK_MCLK:
342 wm8731->sysclk_type = clk_id;
343 break;
344 default:
345 return -EINVAL;
346 }
347
297 switch (freq) { 348 switch (freq) {
298 case 11289600: 349 case 11289600:
299 case 12000000: 350 case 12000000:
@@ -301,9 +352,14 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
301 case 16934400: 352 case 16934400:
302 case 18432000: 353 case 18432000:
303 wm8731->sysclk = freq; 354 wm8731->sysclk = freq;
304 return 0; 355 break;
356 default:
357 return -EINVAL;
305 } 358 }
306 return -EINVAL; 359
360 snd_soc_dapm_sync(&codec->dapm);
361
362 return 0;
307} 363}
308 364
309 365
@@ -381,7 +437,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
381 case SND_SOC_BIAS_PREPARE: 437 case SND_SOC_BIAS_PREPARE:
382 break; 438 break;
383 case SND_SOC_BIAS_STANDBY: 439 case SND_SOC_BIAS_STANDBY:
384 if (codec->bias_level == SND_SOC_BIAS_OFF) { 440 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
385 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 441 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
386 wm8731->supplies); 442 wm8731->supplies);
387 if (ret != 0) 443 if (ret != 0)
@@ -404,13 +460,12 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
404 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); 460 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
405 break; 461 break;
406 case SND_SOC_BIAS_OFF: 462 case SND_SOC_BIAS_OFF:
407 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
408 snd_soc_write(codec, WM8731_PWR, 0xffff); 463 snd_soc_write(codec, WM8731_PWR, 0xffff);
409 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 464 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
410 wm8731->supplies); 465 wm8731->supplies);
411 break; 466 break;
412 } 467 }
413 codec->bias_level = level; 468 codec->dapm.bias_level = level;
414 return 0; 469 return 0;
415} 470}
416 471
@@ -420,16 +475,14 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
420 SNDRV_PCM_FMTBIT_S24_LE) 475 SNDRV_PCM_FMTBIT_S24_LE)
421 476
422static struct snd_soc_dai_ops wm8731_dai_ops = { 477static struct snd_soc_dai_ops wm8731_dai_ops = {
423 .prepare = wm8731_pcm_prepare,
424 .hw_params = wm8731_hw_params, 478 .hw_params = wm8731_hw_params,
425 .shutdown = wm8731_shutdown,
426 .digital_mute = wm8731_mute, 479 .digital_mute = wm8731_mute,
427 .set_sysclk = wm8731_set_dai_sysclk, 480 .set_sysclk = wm8731_set_dai_sysclk,
428 .set_fmt = wm8731_set_dai_fmt, 481 .set_fmt = wm8731_set_dai_fmt,
429}; 482};
430 483
431struct snd_soc_dai wm8731_dai = { 484static struct snd_soc_dai_driver wm8731_dai = {
432 .name = "WM8731", 485 .name = "wm8731-hifi",
433 .playback = { 486 .playback = {
434 .stream_name = "Playback", 487 .stream_name = "Playback",
435 .channels_min = 1, 488 .channels_min = 1,
@@ -445,24 +498,17 @@ struct snd_soc_dai wm8731_dai = {
445 .ops = &wm8731_dai_ops, 498 .ops = &wm8731_dai_ops,
446 .symmetric_rates = 1, 499 .symmetric_rates = 1,
447}; 500};
448EXPORT_SYMBOL_GPL(wm8731_dai);
449 501
450#ifdef CONFIG_PM 502#ifdef CONFIG_PM
451static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 503static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state)
452{ 504{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
454 struct snd_soc_codec *codec = socdev->card->codec;
455
456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 505 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
457 506
458 return 0; 507 return 0;
459} 508}
460 509
461static int wm8731_resume(struct platform_device *pdev) 510static int wm8731_resume(struct snd_soc_codec *codec)
462{ 511{
463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
464 struct snd_soc_codec *codec = socdev->card->codec;
465
466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 512 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
467 513
468 return 0; 514 return 0;
@@ -472,88 +518,15 @@ static int wm8731_resume(struct platform_device *pdev)
472#define wm8731_resume NULL 518#define wm8731_resume NULL
473#endif 519#endif
474 520
475static int wm8731_probe(struct platform_device *pdev) 521static int wm8731_probe(struct snd_soc_codec *codec)
476{ 522{
477 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 523 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
478 struct snd_soc_codec *codec; 524 int ret = 0, i;
479 int ret = 0;
480
481 if (wm8731_codec == NULL) {
482 dev_err(&pdev->dev, "Codec device not registered\n");
483 return -ENODEV;
484 }
485
486 socdev->card->codec = wm8731_codec;
487 codec = wm8731_codec;
488
489 /* register pcms */
490 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
491 if (ret < 0) {
492 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
493 goto pcm_err;
494 }
495
496 snd_soc_add_controls(codec, wm8731_snd_controls,
497 ARRAY_SIZE(wm8731_snd_controls));
498 wm8731_add_widgets(codec);
499
500 return ret;
501
502pcm_err:
503 return ret;
504}
505
506/* power down chip */
507static int wm8731_remove(struct platform_device *pdev)
508{
509 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
510
511 snd_soc_free_pcms(socdev);
512 snd_soc_dapm_free(socdev);
513
514 return 0;
515}
516
517struct snd_soc_codec_device soc_codec_dev_wm8731 = {
518 .probe = wm8731_probe,
519 .remove = wm8731_remove,
520 .suspend = wm8731_suspend,
521 .resume = wm8731_resume,
522};
523EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
524
525static int wm8731_register(struct wm8731_priv *wm8731,
526 enum snd_soc_control_type control)
527{
528 int ret, i;
529 struct snd_soc_codec *codec = &wm8731->codec;
530
531 if (wm8731_codec) {
532 dev_err(codec->dev, "Another WM8731 is registered\n");
533 ret = -EINVAL;
534 goto err;
535 }
536
537 mutex_init(&codec->mutex);
538 INIT_LIST_HEAD(&codec->dapm_widgets);
539 INIT_LIST_HEAD(&codec->dapm_paths);
540
541 snd_soc_codec_set_drvdata(codec, wm8731);
542 codec->name = "WM8731";
543 codec->owner = THIS_MODULE;
544 codec->bias_level = SND_SOC_BIAS_OFF;
545 codec->set_bias_level = wm8731_set_bias_level;
546 codec->dai = &wm8731_dai;
547 codec->num_dai = 1;
548 codec->reg_cache_size = WM8731_CACHEREGNUM;
549 codec->reg_cache = &wm8731->reg_cache;
550
551 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
552 525
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 526 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
554 if (ret < 0) { 527 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 528 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
556 goto err; 529 return ret;
557 } 530 }
558 531
559 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) 532 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
@@ -563,7 +536,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
563 wm8731->supplies); 536 wm8731->supplies);
564 if (ret != 0) { 537 if (ret != 0) {
565 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 538 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
566 goto err; 539 return ret;
567 } 540 }
568 541
569 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 542 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
@@ -579,8 +552,6 @@ static int wm8731_register(struct wm8731_priv *wm8731,
579 goto err_regulator_enable; 552 goto err_regulator_enable;
580 } 553 }
581 554
582 wm8731_dai.dev = codec->dev;
583
584 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 555 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
585 556
586 /* Latch the update bits */ 557 /* Latch the update bits */
@@ -590,81 +561,82 @@ static int wm8731_register(struct wm8731_priv *wm8731,
590 snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0); 561 snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
591 562
592 /* Disable bypass path by default */ 563 /* Disable bypass path by default */
593 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); 564 snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0);
594 565
595 wm8731_codec = codec; 566 snd_soc_add_controls(codec, wm8731_snd_controls,
596 567 ARRAY_SIZE(wm8731_snd_controls));
597 ret = snd_soc_register_codec(codec);
598 if (ret != 0) {
599 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
600 goto err_regulator_enable;
601 }
602
603 ret = snd_soc_register_dai(&wm8731_dai);
604 if (ret != 0) {
605 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
606 snd_soc_unregister_codec(codec);
607 goto err_codec;
608 }
609 568
610 /* Regulators will have been enabled by bias management */ 569 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 570 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612 571
613 return 0; 572 return 0;
614 573
615err_codec:
616 snd_soc_unregister_codec(codec);
617err_regulator_enable: 574err_regulator_enable:
618 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 575 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
619err_regulator_get: 576err_regulator_get:
620 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 577 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
621err: 578
622 kfree(wm8731);
623 return ret; 579 return ret;
624} 580}
625 581
626static void wm8731_unregister(struct wm8731_priv *wm8731) 582/* power down chip */
583static int wm8731_remove(struct snd_soc_codec *codec)
627{ 584{
628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 585 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
629 snd_soc_unregister_dai(&wm8731_dai); 586
630 snd_soc_unregister_codec(&wm8731->codec); 587 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
588
589 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 590 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 591
633 wm8731_codec = NULL; 592 return 0;
634} 593}
635 594
595static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
596 .probe = wm8731_probe,
597 .remove = wm8731_remove,
598 .suspend = wm8731_suspend,
599 .resume = wm8731_resume,
600 .set_bias_level = wm8731_set_bias_level,
601 .reg_cache_size = ARRAY_SIZE(wm8731_reg),
602 .reg_word_size = sizeof(u16),
603 .reg_cache_default = wm8731_reg,
604 .dapm_widgets = wm8731_dapm_widgets,
605 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
606 .dapm_routes = wm8731_intercon,
607 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon),
608};
609
636#if defined(CONFIG_SPI_MASTER) 610#if defined(CONFIG_SPI_MASTER)
637static int __devinit wm8731_spi_probe(struct spi_device *spi) 611static int __devinit wm8731_spi_probe(struct spi_device *spi)
638{ 612{
639 struct snd_soc_codec *codec;
640 struct wm8731_priv *wm8731; 613 struct wm8731_priv *wm8731;
614 int ret;
641 615
642 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 616 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
643 if (wm8731 == NULL) 617 if (wm8731 == NULL)
644 return -ENOMEM; 618 return -ENOMEM;
645 619
646 codec = &wm8731->codec; 620 wm8731->control_type = SND_SOC_SPI;
647 codec->control_data = spi; 621 spi_set_drvdata(spi, wm8731);
648 codec->dev = &spi->dev;
649 622
650 dev_set_drvdata(&spi->dev, wm8731); 623 ret = snd_soc_register_codec(&spi->dev,
651 624 &soc_codec_dev_wm8731, &wm8731_dai, 1);
652 return wm8731_register(wm8731, SND_SOC_SPI); 625 if (ret < 0)
626 kfree(wm8731);
627 return ret;
653} 628}
654 629
655static int __devexit wm8731_spi_remove(struct spi_device *spi) 630static int __devexit wm8731_spi_remove(struct spi_device *spi)
656{ 631{
657 struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); 632 snd_soc_unregister_codec(&spi->dev);
658 633 kfree(spi_get_drvdata(spi));
659 wm8731_unregister(wm8731);
660
661 return 0; 634 return 0;
662} 635}
663 636
664static struct spi_driver wm8731_spi_driver = { 637static struct spi_driver wm8731_spi_driver = {
665 .driver = { 638 .driver = {
666 .name = "wm8731", 639 .name = "wm8731",
667 .bus = &spi_bus_type,
668 .owner = THIS_MODULE, 640 .owner = THIS_MODULE,
669 }, 641 },
670 .probe = wm8731_spi_probe, 642 .probe = wm8731_spi_probe,
@@ -677,26 +649,26 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
677 const struct i2c_device_id *id) 649 const struct i2c_device_id *id)
678{ 650{
679 struct wm8731_priv *wm8731; 651 struct wm8731_priv *wm8731;
680 struct snd_soc_codec *codec; 652 int ret;
681 653
682 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 654 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
683 if (wm8731 == NULL) 655 if (wm8731 == NULL)
684 return -ENOMEM; 656 return -ENOMEM;
685 657
686 codec = &wm8731->codec;
687
688 i2c_set_clientdata(i2c, wm8731); 658 i2c_set_clientdata(i2c, wm8731);
689 codec->control_data = i2c; 659 wm8731->control_type = SND_SOC_I2C;
690 660
691 codec->dev = &i2c->dev; 661 ret = snd_soc_register_codec(&i2c->dev,
692 662 &soc_codec_dev_wm8731, &wm8731_dai, 1);
693 return wm8731_register(wm8731, SND_SOC_I2C); 663 if (ret < 0)
664 kfree(wm8731);
665 return ret;
694} 666}
695 667
696static __devexit int wm8731_i2c_remove(struct i2c_client *client) 668static __devexit int wm8731_i2c_remove(struct i2c_client *client)
697{ 669{
698 struct wm8731_priv *wm8731 = i2c_get_clientdata(client); 670 snd_soc_unregister_codec(&client->dev);
699 wm8731_unregister(wm8731); 671 kfree(i2c_get_clientdata(client));
700 return 0; 672 return 0;
701} 673}
702 674
@@ -719,7 +691,7 @@ static struct i2c_driver wm8731_i2c_driver = {
719 691
720static int __init wm8731_modinit(void) 692static int __init wm8731_modinit(void)
721{ 693{
722 int ret; 694 int ret = 0;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 695#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8731_i2c_driver); 696 ret = i2c_add_driver(&wm8731_i2c_driver);
725 if (ret != 0) { 697 if (ret != 0) {
@@ -734,7 +706,7 @@ static int __init wm8731_modinit(void)
734 ret); 706 ret);
735 } 707 }
736#endif 708#endif
737 return 0; 709 return ret;
738} 710}
739module_init(wm8731_modinit); 711module_init(wm8731_modinit);
740 712
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index cd7b806e8ad0..e9c0c76ab73b 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -31,10 +31,9 @@
31 31
32#define WM8731_CACHEREGNUM 10 32#define WM8731_CACHEREGNUM 10
33 33
34#define WM8731_SYSCLK 0 34#define WM8731_SYSCLK_XTAL 1
35#define WM8731_DAI 0 35#define WM8731_SYSCLK_MCLK 2
36 36
37extern struct snd_soc_dai wm8731_dai; 37#define WM8731_DAI 0
38extern struct snd_soc_codec_device soc_codec_dev_wm8731;
39 38
40#endif 39#endif
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
new file mode 100644
index 000000000000..30c67d06a904
--- /dev/null
+++ b/sound/soc/codecs/wm8737.c
@@ -0,0 +1,754 @@
1/*
2 * wm8737.c -- WM8737 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/consumer.h>
21#include <linux/spi/spi.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "wm8737.h"
32
33#define WM8737_NUM_SUPPLIES 4
34static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
35 "DCVDD",
36 "DBVDD",
37 "AVDD",
38 "MVDD",
39};
40
41/* codec private data */
42struct wm8737_priv {
43 enum snd_soc_control_type control_type;
44 struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
45 unsigned int mclk;
46};
47
48static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
49 0x00C3, /* R0 - Left PGA volume */
50 0x00C3, /* R1 - Right PGA volume */
51 0x0007, /* R2 - AUDIO path L */
52 0x0007, /* R3 - AUDIO path R */
53 0x0000, /* R4 - 3D Enhance */
54 0x0000, /* R5 - ADC Control */
55 0x0000, /* R6 - Power Management */
56 0x000A, /* R7 - Audio Format */
57 0x0000, /* R8 - Clocking */
58 0x000F, /* R9 - MIC Preamp Control */
59 0x0003, /* R10 - Misc Bias Control */
60 0x0000, /* R11 - Noise Gate */
61 0x007C, /* R12 - ALC1 */
62 0x0000, /* R13 - ALC2 */
63 0x0032, /* R14 - ALC3 */
64};
65
66static int wm8737_reset(struct snd_soc_codec *codec)
67{
68 return snd_soc_write(codec, WM8737_RESET, 0);
69}
70
71static const unsigned int micboost_tlv[] = {
72 TLV_DB_RANGE_HEAD(4),
73 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
74 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
75 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
76 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
77};
78static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
79static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
80static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
81static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
82static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
83
84static const char *micbias_enum_text[] = {
85 "25%",
86 "50%",
87 "75%",
88 "100%",
89};
90
91static const struct soc_enum micbias_enum =
92 SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
93
94static const char *low_cutoff_text[] = {
95 "Low", "High"
96};
97
98static const struct soc_enum low_3d =
99 SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
100
101static const char *high_cutoff_text[] = {
102 "High", "Low"
103};
104
105static const struct soc_enum high_3d =
106 SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
107
108static const char *alc_fn_text[] = {
109 "Disabled", "Right", "Left", "Stereo"
110};
111
112static const struct soc_enum alc_fn =
113 SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text);
114
115static const char *alc_hold_text[] = {
116 "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
117 "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
118 "10.916s", "21.832s", "43.691s"
119};
120
121static const struct soc_enum alc_hold =
122 SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text);
123
124static const char *alc_atk_text[] = {
125 "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
126 "1.075s", "2.15s", "4.3s", "8.6s"
127};
128
129static const struct soc_enum alc_atk =
130 SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text);
131
132static const char *alc_dcy_text[] = {
133 "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
134 "4.3s", "8.6s", "17.2s", "34.41s"
135};
136
137static const struct soc_enum alc_dcy =
138 SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
139
140static const struct snd_kcontrol_new wm8737_snd_controls[] = {
141SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
142 6, 3, 0, micboost_tlv),
143SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
144 4, 1, 0),
145SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
146 3, 1, 0),
147
148SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
149 WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
150SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
151 2, 1, 0),
152
153SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
154
155SOC_ENUM("Mic PGA Bias", micbias_enum),
156SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
157SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
158SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
159
160SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
161SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
162SOC_ENUM("3D Low Cut-off", low_3d),
163SOC_ENUM("3D High Cut-off", low_3d),
164SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
165
166SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
167SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
168 ng_tlv),
169
170SOC_ENUM("ALC", alc_fn),
171SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
172SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
173SOC_ENUM("ALC Hold Time", alc_hold),
174SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
175SOC_ENUM("ALC Attack Time", alc_atk),
176SOC_ENUM("ALC Decay Time", alc_dcy),
177};
178
179static const char *linsel_text[] = {
180 "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
181};
182
183static const struct soc_enum linsel_enum =
184 SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text);
185
186static const struct snd_kcontrol_new linsel_mux =
187 SOC_DAPM_ENUM("LINSEL", linsel_enum);
188
189
190static const char *rinsel_text[] = {
191 "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
192};
193
194static const struct soc_enum rinsel_enum =
195 SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text);
196
197static const struct snd_kcontrol_new rinsel_mux =
198 SOC_DAPM_ENUM("RINSEL", rinsel_enum);
199
200static const char *bypass_text[] = {
201 "Direct", "Preamp"
202};
203
204static const struct soc_enum lbypass_enum =
205 SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text);
206
207static const struct snd_kcontrol_new lbypass_mux =
208 SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
209
210
211static const struct soc_enum rbypass_enum =
212 SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text);
213
214static const struct snd_kcontrol_new rbypass_mux =
215 SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
216
217static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
218SND_SOC_DAPM_INPUT("LINPUT1"),
219SND_SOC_DAPM_INPUT("LINPUT2"),
220SND_SOC_DAPM_INPUT("LINPUT3"),
221SND_SOC_DAPM_INPUT("RINPUT1"),
222SND_SOC_DAPM_INPUT("RINPUT2"),
223SND_SOC_DAPM_INPUT("RINPUT3"),
224SND_SOC_DAPM_INPUT("LACIN"),
225SND_SOC_DAPM_INPUT("RACIN"),
226
227SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
228SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
229
230SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
231SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
232
233SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
234SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
235
236SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
237SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
238
239SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
240};
241
242static const struct snd_soc_dapm_route intercon[] = {
243 { "LINSEL", "LINPUT1", "LINPUT1" },
244 { "LINSEL", "LINPUT2", "LINPUT2" },
245 { "LINSEL", "LINPUT3", "LINPUT3" },
246 { "LINSEL", "LINPUT1 DC", "LINPUT1" },
247
248 { "RINSEL", "RINPUT1", "RINPUT1" },
249 { "RINSEL", "RINPUT2", "RINPUT2" },
250 { "RINSEL", "RINPUT3", "RINPUT3" },
251 { "RINSEL", "RINPUT1 DC", "RINPUT1" },
252
253 { "Left Preamp Mux", "Preamp", "LINSEL" },
254 { "Left Preamp Mux", "Direct", "LACIN" },
255
256 { "Right Preamp Mux", "Preamp", "RINSEL" },
257 { "Right Preamp Mux", "Direct", "RACIN" },
258
259 { "PGAL", NULL, "Left Preamp Mux" },
260 { "PGAR", NULL, "Right Preamp Mux" },
261
262 { "ADCL", NULL, "PGAL" },
263 { "ADCR", NULL, "PGAR" },
264
265 { "AIF", NULL, "ADCL" },
266 { "AIF", NULL, "ADCR" },
267};
268
269static int wm8737_add_widgets(struct snd_soc_codec *codec)
270{
271 struct snd_soc_dapm_context *dapm = &codec->dapm;
272
273 snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
274 ARRAY_SIZE(wm8737_dapm_widgets));
275 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
276
277 return 0;
278}
279
280/* codec mclk clock divider coefficients */
281static const struct {
282 u32 mclk;
283 u32 rate;
284 u8 usb;
285 u8 sr;
286} coeff_div[] = {
287 { 12288000, 8000, 0, 0x4 },
288 { 12288000, 12000, 0, 0x8 },
289 { 12288000, 16000, 0, 0xa },
290 { 12288000, 24000, 0, 0x1c },
291 { 12288000, 32000, 0, 0xc },
292 { 12288000, 48000, 0, 0 },
293 { 12288000, 96000, 0, 0xe },
294
295 { 11289600, 8000, 0, 0x14 },
296 { 11289600, 11025, 0, 0x18 },
297 { 11289600, 22050, 0, 0x1a },
298 { 11289600, 44100, 0, 0x10 },
299 { 11289600, 88200, 0, 0x1e },
300
301 { 18432000, 8000, 0, 0x5 },
302 { 18432000, 12000, 0, 0x9 },
303 { 18432000, 16000, 0, 0xb },
304 { 18432000, 24000, 0, 0x1b },
305 { 18432000, 32000, 0, 0xd },
306 { 18432000, 48000, 0, 0x1 },
307 { 18432000, 96000, 0, 0x1f },
308
309 { 16934400, 8000, 0, 0x15 },
310 { 16934400, 11025, 0, 0x19 },
311 { 16934400, 22050, 0, 0x1b },
312 { 16934400, 44100, 0, 0x11 },
313 { 16934400, 88200, 0, 0x1f },
314
315 { 12000000, 8000, 1, 0x4 },
316 { 12000000, 11025, 1, 0x19 },
317 { 12000000, 12000, 1, 0x8 },
318 { 12000000, 16000, 1, 0xa },
319 { 12000000, 22050, 1, 0x1b },
320 { 12000000, 24000, 1, 0x1c },
321 { 12000000, 32000, 1, 0xc },
322 { 12000000, 44100, 1, 0x11 },
323 { 12000000, 48000, 1, 0x0 },
324 { 12000000, 88200, 1, 0x1f },
325 { 12000000, 96000, 1, 0xe },
326};
327
328static int wm8737_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai)
331{
332 struct snd_soc_pcm_runtime *rtd = substream->private_data;
333 struct snd_soc_codec *codec = rtd->codec;
334 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
335 int i;
336 u16 clocking = 0;
337 u16 af = 0;
338
339 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
340 if (coeff_div[i].rate != params_rate(params))
341 continue;
342
343 if (coeff_div[i].mclk == wm8737->mclk)
344 break;
345
346 if (coeff_div[i].mclk == wm8737->mclk * 2) {
347 clocking |= WM8737_CLKDIV2;
348 break;
349 }
350 }
351
352 if (i == ARRAY_SIZE(coeff_div)) {
353 dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
354 wm8737->mclk, params_rate(params));
355 return -EINVAL;
356 }
357
358 clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
359
360 switch (params_format(params)) {
361 case SNDRV_PCM_FORMAT_S16_LE:
362 break;
363 case SNDRV_PCM_FORMAT_S20_3LE:
364 af |= 0x8;
365 break;
366 case SNDRV_PCM_FORMAT_S24_LE:
367 af |= 0x10;
368 break;
369 case SNDRV_PCM_FORMAT_S32_LE:
370 af |= 0x18;
371 break;
372 default:
373 return -EINVAL;
374 }
375
376 snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
377 snd_soc_update_bits(codec, WM8737_CLOCKING,
378 WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
379 clocking);
380
381 return 0;
382}
383
384static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
385 int clk_id, unsigned int freq, int dir)
386{
387 struct snd_soc_codec *codec = codec_dai->codec;
388 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
389 int i;
390
391 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
392 if (freq == coeff_div[i].mclk ||
393 freq == coeff_div[i].mclk * 2) {
394 wm8737->mclk = freq;
395 return 0;
396 }
397 }
398
399 dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
400
401 return -EINVAL;
402}
403
404
405static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
406 unsigned int fmt)
407{
408 struct snd_soc_codec *codec = codec_dai->codec;
409 u16 af = 0;
410
411 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
412 case SND_SOC_DAIFMT_CBM_CFM:
413 af |= WM8737_MS;
414 break;
415 case SND_SOC_DAIFMT_CBS_CFS:
416 break;
417 default:
418 return -EINVAL;
419 }
420
421 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
422 case SND_SOC_DAIFMT_I2S:
423 af |= 0x2;
424 break;
425 case SND_SOC_DAIFMT_RIGHT_J:
426 break;
427 case SND_SOC_DAIFMT_LEFT_J:
428 af |= 0x1;
429 break;
430 case SND_SOC_DAIFMT_DSP_A:
431 af |= 0x3;
432 break;
433 case SND_SOC_DAIFMT_DSP_B:
434 af |= 0x13;
435 break;
436 default:
437 return -EINVAL;
438 }
439
440 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
441 case SND_SOC_DAIFMT_NB_NF:
442 break;
443 case SND_SOC_DAIFMT_NB_IF:
444 af |= WM8737_LRP;
445 break;
446 default:
447 return -EINVAL;
448 }
449
450 snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
451 WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
452
453 return 0;
454}
455
456static int wm8737_set_bias_level(struct snd_soc_codec *codec,
457 enum snd_soc_bias_level level)
458{
459 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
460 int ret;
461
462 switch (level) {
463 case SND_SOC_BIAS_ON:
464 break;
465
466 case SND_SOC_BIAS_PREPARE:
467 /* VMID at 2*75k */
468 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
469 WM8737_VMIDSEL_MASK, 0);
470 break;
471
472 case SND_SOC_BIAS_STANDBY:
473 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
474 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
475 wm8737->supplies);
476 if (ret != 0) {
477 dev_err(codec->dev,
478 "Failed to enable supplies: %d\n",
479 ret);
480 return ret;
481 }
482
483 snd_soc_cache_sync(codec);
484
485 /* Fast VMID ramp at 2*2.5k */
486 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
487 WM8737_VMIDSEL_MASK, 0x4);
488
489 /* Bring VMID up */
490 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
491 WM8737_VMID_MASK |
492 WM8737_VREF_MASK,
493 WM8737_VMID_MASK |
494 WM8737_VREF_MASK);
495
496 msleep(500);
497 }
498
499 /* VMID at 2*300k */
500 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
501 WM8737_VMIDSEL_MASK, 2);
502
503 break;
504
505 case SND_SOC_BIAS_OFF:
506 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
507 WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
508
509 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
510 wm8737->supplies);
511 break;
512 }
513
514 codec->dapm.bias_level = level;
515 return 0;
516}
517
518#define WM8737_RATES SNDRV_PCM_RATE_8000_96000
519
520#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
521 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
522
523static struct snd_soc_dai_ops wm8737_dai_ops = {
524 .hw_params = wm8737_hw_params,
525 .set_sysclk = wm8737_set_dai_sysclk,
526 .set_fmt = wm8737_set_dai_fmt,
527};
528
529static struct snd_soc_dai_driver wm8737_dai = {
530 .name = "wm8737",
531 .capture = {
532 .stream_name = "Capture",
533 .channels_min = 2, /* Mono modes not yet supported */
534 .channels_max = 2,
535 .rates = WM8737_RATES,
536 .formats = WM8737_FORMATS,
537 },
538 .ops = &wm8737_dai_ops,
539};
540
541#ifdef CONFIG_PM
542static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state)
543{
544 wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
545 return 0;
546}
547
548static int wm8737_resume(struct snd_soc_codec *codec)
549{
550 wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
551 return 0;
552}
553#else
554#define wm8737_suspend NULL
555#define wm8737_resume NULL
556#endif
557
558static int wm8737_probe(struct snd_soc_codec *codec)
559{
560 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
561 int ret, i;
562
563 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
564 if (ret != 0) {
565 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
566 return ret;
567 }
568
569 for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
570 wm8737->supplies[i].supply = wm8737_supply_names[i];
571
572 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
573 wm8737->supplies);
574 if (ret != 0) {
575 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
576 return ret;
577 }
578
579 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
580 wm8737->supplies);
581 if (ret != 0) {
582 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
583 goto err_get;
584 }
585
586 ret = wm8737_reset(codec);
587 if (ret < 0) {
588 dev_err(codec->dev, "Failed to issue reset\n");
589 goto err_enable;
590 }
591
592 snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
593 WM8737_LVU);
594 snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
595 WM8737_RVU);
596
597 wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598
599 /* Bias level configuration will have done an extra enable */
600 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
601
602 snd_soc_add_controls(codec, wm8737_snd_controls,
603 ARRAY_SIZE(wm8737_snd_controls));
604 wm8737_add_widgets(codec);
605
606 return 0;
607
608err_enable:
609 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
610err_get:
611 regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
612
613 return ret;
614}
615
616static int wm8737_remove(struct snd_soc_codec *codec)
617{
618 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
619
620 wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
621 regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
622 return 0;
623}
624
625static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
626 .probe = wm8737_probe,
627 .remove = wm8737_remove,
628 .suspend = wm8737_suspend,
629 .resume = wm8737_resume,
630 .set_bias_level = wm8737_set_bias_level,
631
632 .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
633 .reg_word_size = sizeof(u16),
634 .reg_cache_default = wm8737_reg,
635};
636
637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
638static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
639 const struct i2c_device_id *id)
640{
641 struct wm8737_priv *wm8737;
642 int ret;
643
644 wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
645 if (wm8737 == NULL)
646 return -ENOMEM;
647
648 i2c_set_clientdata(i2c, wm8737);
649 wm8737->control_type = SND_SOC_I2C;
650
651 ret = snd_soc_register_codec(&i2c->dev,
652 &soc_codec_dev_wm8737, &wm8737_dai, 1);
653 if (ret < 0)
654 kfree(wm8737);
655 return ret;
656
657}
658
659static __devexit int wm8737_i2c_remove(struct i2c_client *client)
660{
661 snd_soc_unregister_codec(&client->dev);
662 kfree(i2c_get_clientdata(client));
663 return 0;
664}
665
666static const struct i2c_device_id wm8737_i2c_id[] = {
667 { "wm8737", 0 },
668 { }
669};
670MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
671
672static struct i2c_driver wm8737_i2c_driver = {
673 .driver = {
674 .name = "wm8737",
675 .owner = THIS_MODULE,
676 },
677 .probe = wm8737_i2c_probe,
678 .remove = __devexit_p(wm8737_i2c_remove),
679 .id_table = wm8737_i2c_id,
680};
681#endif
682
683#if defined(CONFIG_SPI_MASTER)
684static int __devinit wm8737_spi_probe(struct spi_device *spi)
685{
686 struct wm8737_priv *wm8737;
687 int ret;
688
689 wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
690 if (wm8737 == NULL)
691 return -ENOMEM;
692
693 wm8737->control_type = SND_SOC_SPI;
694 spi_set_drvdata(spi, wm8737);
695
696 ret = snd_soc_register_codec(&spi->dev,
697 &soc_codec_dev_wm8737, &wm8737_dai, 1);
698 if (ret < 0)
699 kfree(wm8737);
700 return ret;
701}
702
703static int __devexit wm8737_spi_remove(struct spi_device *spi)
704{
705 snd_soc_unregister_codec(&spi->dev);
706 kfree(spi_get_drvdata(spi));
707 return 0;
708}
709
710static struct spi_driver wm8737_spi_driver = {
711 .driver = {
712 .name = "wm8737",
713 .owner = THIS_MODULE,
714 },
715 .probe = wm8737_spi_probe,
716 .remove = __devexit_p(wm8737_spi_remove),
717};
718#endif /* CONFIG_SPI_MASTER */
719
720static int __init wm8737_modinit(void)
721{
722 int ret;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8737_i2c_driver);
725 if (ret != 0) {
726 printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
727 ret);
728 }
729#endif
730#if defined(CONFIG_SPI_MASTER)
731 ret = spi_register_driver(&wm8737_spi_driver);
732 if (ret != 0) {
733 printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
734 ret);
735 }
736#endif
737 return 0;
738}
739module_init(wm8737_modinit);
740
741static void __exit wm8737_exit(void)
742{
743#if defined(CONFIG_SPI_MASTER)
744 spi_unregister_driver(&wm8737_spi_driver);
745#endif
746#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
747 i2c_del_driver(&wm8737_i2c_driver);
748#endif
749}
750module_exit(wm8737_exit);
751
752MODULE_DESCRIPTION("ASoC WM8737 driver");
753MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
754MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8737.h b/sound/soc/codecs/wm8737.h
new file mode 100644
index 000000000000..23d14c8ff6e7
--- /dev/null
+++ b/sound/soc/codecs/wm8737.h
@@ -0,0 +1,322 @@
1#ifndef _WM8737_H
2#define _WM8737_H
3
4/*
5 * wm8737.c -- WM8523 ALSA SoC Audio driver
6 *
7 * Copyright 2010 Wolfson Microelectronics plc
8 *
9 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16/*
17 * Register values.
18 */
19#define WM8737_LEFT_PGA_VOLUME 0x00
20#define WM8737_RIGHT_PGA_VOLUME 0x01
21#define WM8737_AUDIO_PATH_L 0x02
22#define WM8737_AUDIO_PATH_R 0x03
23#define WM8737_3D_ENHANCE 0x04
24#define WM8737_ADC_CONTROL 0x05
25#define WM8737_POWER_MANAGEMENT 0x06
26#define WM8737_AUDIO_FORMAT 0x07
27#define WM8737_CLOCKING 0x08
28#define WM8737_MIC_PREAMP_CONTROL 0x09
29#define WM8737_MISC_BIAS_CONTROL 0x0A
30#define WM8737_NOISE_GATE 0x0B
31#define WM8737_ALC1 0x0C
32#define WM8737_ALC2 0x0D
33#define WM8737_ALC3 0x0E
34#define WM8737_RESET 0x0F
35
36#define WM8737_REGISTER_COUNT 16
37#define WM8737_MAX_REGISTER 0x0F
38
39/*
40 * Field Definitions.
41 */
42
43/*
44 * R0 (0x00) - Left PGA volume
45 */
46#define WM8737_LVU 0x0100 /* LVU */
47#define WM8737_LVU_MASK 0x0100 /* LVU */
48#define WM8737_LVU_SHIFT 8 /* LVU */
49#define WM8737_LVU_WIDTH 1 /* LVU */
50#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */
51#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */
52#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */
53
54/*
55 * R1 (0x01) - Right PGA volume
56 */
57#define WM8737_RVU 0x0100 /* RVU */
58#define WM8737_RVU_MASK 0x0100 /* RVU */
59#define WM8737_RVU_SHIFT 8 /* RVU */
60#define WM8737_RVU_WIDTH 1 /* RVU */
61#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */
62#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */
63#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */
64
65/*
66 * R2 (0x02) - AUDIO path L
67 */
68#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */
69#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */
70#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */
71#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */
72#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */
73#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */
74#define WM8737_LMBE 0x0010 /* LMBE */
75#define WM8737_LMBE_MASK 0x0010 /* LMBE */
76#define WM8737_LMBE_SHIFT 4 /* LMBE */
77#define WM8737_LMBE_WIDTH 1 /* LMBE */
78#define WM8737_LMZC 0x0008 /* LMZC */
79#define WM8737_LMZC_MASK 0x0008 /* LMZC */
80#define WM8737_LMZC_SHIFT 3 /* LMZC */
81#define WM8737_LMZC_WIDTH 1 /* LMZC */
82#define WM8737_LPZC 0x0004 /* LPZC */
83#define WM8737_LPZC_MASK 0x0004 /* LPZC */
84#define WM8737_LPZC_SHIFT 2 /* LPZC */
85#define WM8737_LPZC_WIDTH 1 /* LPZC */
86#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */
87#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */
88#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */
89
90/*
91 * R3 (0x03) - AUDIO path R
92 */
93#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */
94#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */
95#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */
96#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */
97#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */
98#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */
99#define WM8737_RMBE 0x0010 /* RMBE */
100#define WM8737_RMBE_MASK 0x0010 /* RMBE */
101#define WM8737_RMBE_SHIFT 4 /* RMBE */
102#define WM8737_RMBE_WIDTH 1 /* RMBE */
103#define WM8737_RMZC 0x0008 /* RMZC */
104#define WM8737_RMZC_MASK 0x0008 /* RMZC */
105#define WM8737_RMZC_SHIFT 3 /* RMZC */
106#define WM8737_RMZC_WIDTH 1 /* RMZC */
107#define WM8737_RPZC 0x0004 /* RPZC */
108#define WM8737_RPZC_MASK 0x0004 /* RPZC */
109#define WM8737_RPZC_SHIFT 2 /* RPZC */
110#define WM8737_RPZC_WIDTH 1 /* RPZC */
111#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */
112#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */
113#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */
114
115/*
116 * R4 (0x04) - 3D Enhance
117 */
118#define WM8737_DIV2 0x0080 /* DIV2 */
119#define WM8737_DIV2_MASK 0x0080 /* DIV2 */
120#define WM8737_DIV2_SHIFT 7 /* DIV2 */
121#define WM8737_DIV2_WIDTH 1 /* DIV2 */
122#define WM8737_3DLC 0x0040 /* 3DLC */
123#define WM8737_3DLC_MASK 0x0040 /* 3DLC */
124#define WM8737_3DLC_SHIFT 6 /* 3DLC */
125#define WM8737_3DLC_WIDTH 1 /* 3DLC */
126#define WM8737_3DUC 0x0020 /* 3DUC */
127#define WM8737_3DUC_MASK 0x0020 /* 3DUC */
128#define WM8737_3DUC_SHIFT 5 /* 3DUC */
129#define WM8737_3DUC_WIDTH 1 /* 3DUC */
130#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */
131#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */
132#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */
133#define WM8737_3DE 0x0001 /* 3DE */
134#define WM8737_3DE_MASK 0x0001 /* 3DE */
135#define WM8737_3DE_SHIFT 0 /* 3DE */
136#define WM8737_3DE_WIDTH 1 /* 3DE */
137
138/*
139 * R5 (0x05) - ADC Control
140 */
141#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */
142#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */
143#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */
144#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */
145#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */
146#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */
147#define WM8737_HPOR 0x0010 /* HPOR */
148#define WM8737_HPOR_MASK 0x0010 /* HPOR */
149#define WM8737_HPOR_SHIFT 4 /* HPOR */
150#define WM8737_HPOR_WIDTH 1 /* HPOR */
151#define WM8737_LP 0x0004 /* LP */
152#define WM8737_LP_MASK 0x0004 /* LP */
153#define WM8737_LP_SHIFT 2 /* LP */
154#define WM8737_LP_WIDTH 1 /* LP */
155#define WM8737_MONOUT 0x0002 /* MONOUT */
156#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */
157#define WM8737_MONOUT_SHIFT 1 /* MONOUT */
158#define WM8737_MONOUT_WIDTH 1 /* MONOUT */
159#define WM8737_ADCHPD 0x0001 /* ADCHPD */
160#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */
161#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */
162#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */
163
164/*
165 * R6 (0x06) - Power Management
166 */
167#define WM8737_VMID 0x0100 /* VMID */
168#define WM8737_VMID_MASK 0x0100 /* VMID */
169#define WM8737_VMID_SHIFT 8 /* VMID */
170#define WM8737_VMID_WIDTH 1 /* VMID */
171#define WM8737_VREF 0x0080 /* VREF */
172#define WM8737_VREF_MASK 0x0080 /* VREF */
173#define WM8737_VREF_SHIFT 7 /* VREF */
174#define WM8737_VREF_WIDTH 1 /* VREF */
175#define WM8737_AI 0x0040 /* AI */
176#define WM8737_AI_MASK 0x0040 /* AI */
177#define WM8737_AI_SHIFT 6 /* AI */
178#define WM8737_AI_WIDTH 1 /* AI */
179#define WM8737_PGL 0x0020 /* PGL */
180#define WM8737_PGL_MASK 0x0020 /* PGL */
181#define WM8737_PGL_SHIFT 5 /* PGL */
182#define WM8737_PGL_WIDTH 1 /* PGL */
183#define WM8737_PGR 0x0010 /* PGR */
184#define WM8737_PGR_MASK 0x0010 /* PGR */
185#define WM8737_PGR_SHIFT 4 /* PGR */
186#define WM8737_PGR_WIDTH 1 /* PGR */
187#define WM8737_ADL 0x0008 /* ADL */
188#define WM8737_ADL_MASK 0x0008 /* ADL */
189#define WM8737_ADL_SHIFT 3 /* ADL */
190#define WM8737_ADL_WIDTH 1 /* ADL */
191#define WM8737_ADR 0x0004 /* ADR */
192#define WM8737_ADR_MASK 0x0004 /* ADR */
193#define WM8737_ADR_SHIFT 2 /* ADR */
194#define WM8737_ADR_WIDTH 1 /* ADR */
195#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */
196#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */
197#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */
198
199/*
200 * R7 (0x07) - Audio Format
201 */
202#define WM8737_SDODIS 0x0080 /* SDODIS */
203#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */
204#define WM8737_SDODIS_SHIFT 7 /* SDODIS */
205#define WM8737_SDODIS_WIDTH 1 /* SDODIS */
206#define WM8737_MS 0x0040 /* MS */
207#define WM8737_MS_MASK 0x0040 /* MS */
208#define WM8737_MS_SHIFT 6 /* MS */
209#define WM8737_MS_WIDTH 1 /* MS */
210#define WM8737_LRP 0x0010 /* LRP */
211#define WM8737_LRP_MASK 0x0010 /* LRP */
212#define WM8737_LRP_SHIFT 4 /* LRP */
213#define WM8737_LRP_WIDTH 1 /* LRP */
214#define WM8737_WL_MASK 0x000C /* WL - [3:2] */
215#define WM8737_WL_SHIFT 2 /* WL - [3:2] */
216#define WM8737_WL_WIDTH 2 /* WL - [3:2] */
217#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
218#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
219#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
220
221/*
222 * R8 (0x08) - Clocking
223 */
224#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */
225#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */
226#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */
227#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */
228#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */
229#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */
230#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */
231#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */
232#define WM8737_SR_MASK 0x003E /* SR - [5:1] */
233#define WM8737_SR_SHIFT 1 /* SR - [5:1] */
234#define WM8737_SR_WIDTH 5 /* SR - [5:1] */
235#define WM8737_USB_MODE 0x0001 /* USB MODE */
236#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */
237#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */
238#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */
239
240/*
241 * R9 (0x09) - MIC Preamp Control
242 */
243#define WM8737_RBYPEN 0x0008 /* RBYPEN */
244#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */
245#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */
246#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */
247#define WM8737_LBYPEN 0x0004 /* LBYPEN */
248#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */
249#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */
250#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */
251#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */
252#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */
253#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */
254
255/*
256 * R10 (0x0A) - Misc Bias Control
257 */
258#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */
259#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */
260#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */
261#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */
262#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */
263#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */
264#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */
265#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */
266#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */
267#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */
268#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */
269
270/*
271 * R11 (0x0B) - Noise Gate
272 */
273#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */
274#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */
275#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */
276#define WM8737_NGAT 0x0001 /* NGAT */
277#define WM8737_NGAT_MASK 0x0001 /* NGAT */
278#define WM8737_NGAT_SHIFT 0 /* NGAT */
279#define WM8737_NGAT_WIDTH 1 /* NGAT */
280
281/*
282 * R12 (0x0C) - ALC1
283 */
284#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
285#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
286#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
287#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */
288#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */
289#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */
290#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */
291#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */
292#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */
293
294/*
295 * R13 (0x0D) - ALC2
296 */
297#define WM8737_ALCZCE 0x0010 /* ALCZCE */
298#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */
299#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */
300#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */
301#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */
302#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */
303#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */
304
305/*
306 * R14 (0x0E) - ALC3
307 */
308#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */
309#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */
310#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */
311#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */
312#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */
313#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */
314
315/*
316 * R15 (0x0F) - Reset
317 */
318#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */
319#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */
320#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */
321
322#endif
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index b9ea8904ad4b..25af901fe813 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -24,31 +24,25 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30 29
31#include "wm8741.h" 30#include "wm8741.h"
32 31
33static struct snd_soc_codec *wm8741_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8741;
35
36#define WM8741_NUM_SUPPLIES 2 32#define WM8741_NUM_SUPPLIES 2
37static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { 33static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
38 "AVDD", 34 "AVDD",
39 "DVDD", 35 "DVDD",
40}; 36};
41 37
42#define WM8741_NUM_RATES 4 38#define WM8741_NUM_RATES 6
43 39
44/* codec private data */ 40/* codec private data */
45struct wm8741_priv { 41struct wm8741_priv {
46 struct snd_soc_codec codec; 42 enum snd_soc_control_type control_type;
47 u16 reg_cache[WM8741_REGISTER_COUNT];
48 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; 43 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
49 unsigned int sysclk; 44 unsigned int sysclk;
50 unsigned int rate_constraint_list[WM8741_NUM_RATES]; 45 struct snd_pcm_hw_constraint_list *sysclk_constraints;
51 struct snd_pcm_hw_constraint_list rate_constraint;
52}; 46};
53 47
54static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = { 48static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
@@ -99,10 +93,11 @@ static const struct snd_soc_dapm_route intercon[] = {
99 93
100static int wm8741_add_widgets(struct snd_soc_codec *codec) 94static int wm8741_add_widgets(struct snd_soc_codec *codec)
101{ 95{
102 snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets, 96 struct snd_soc_dapm_context *dapm = &codec->dapm;
103 ARRAY_SIZE(wm8741_dapm_widgets));
104 97
105 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 98 snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets,
99 ARRAY_SIZE(wm8741_dapm_widgets));
100 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
106 101
107 return 0; 102 return 0;
108} 103}
@@ -111,10 +106,84 @@ static struct {
111 int value; 106 int value;
112 int ratio; 107 int ratio;
113} lrclk_ratios[WM8741_NUM_RATES] = { 108} lrclk_ratios[WM8741_NUM_RATES] = {
114 { 1, 256 }, 109 { 1, 128 },
115 { 2, 384 }, 110 { 2, 192 },
116 { 3, 512 }, 111 { 3, 256 },
117 { 4, 768 }, 112 { 4, 384 },
113 { 5, 512 },
114 { 6, 768 },
115};
116
117static unsigned int rates_11289[] = {
118 44100, 88235,
119};
120
121static struct snd_pcm_hw_constraint_list constraints_11289 = {
122 .count = ARRAY_SIZE(rates_11289),
123 .list = rates_11289,
124};
125
126static unsigned int rates_12288[] = {
127 32000, 48000, 96000,
128};
129
130static struct snd_pcm_hw_constraint_list constraints_12288 = {
131 .count = ARRAY_SIZE(rates_12288),
132 .list = rates_12288,
133};
134
135static unsigned int rates_16384[] = {
136 32000,
137};
138
139static struct snd_pcm_hw_constraint_list constraints_16384 = {
140 .count = ARRAY_SIZE(rates_16384),
141 .list = rates_16384,
142};
143
144static unsigned int rates_16934[] = {
145 44100, 88235,
146};
147
148static struct snd_pcm_hw_constraint_list constraints_16934 = {
149 .count = ARRAY_SIZE(rates_16934),
150 .list = rates_16934,
151};
152
153static unsigned int rates_18432[] = {
154 48000, 96000,
155};
156
157static struct snd_pcm_hw_constraint_list constraints_18432 = {
158 .count = ARRAY_SIZE(rates_18432),
159 .list = rates_18432,
160};
161
162static unsigned int rates_22579[] = {
163 44100, 88235, 1764000
164};
165
166static struct snd_pcm_hw_constraint_list constraints_22579 = {
167 .count = ARRAY_SIZE(rates_22579),
168 .list = rates_22579,
169};
170
171static unsigned int rates_24576[] = {
172 32000, 48000, 96000, 192000
173};
174
175static struct snd_pcm_hw_constraint_list constraints_24576 = {
176 .count = ARRAY_SIZE(rates_24576),
177 .list = rates_24576,
178};
179
180static unsigned int rates_36864[] = {
181 48000, 96000, 19200
182};
183
184static struct snd_pcm_hw_constraint_list constraints_36864 = {
185 .count = ARRAY_SIZE(rates_36864),
186 .list = rates_36864,
118}; 187};
119 188
120 189
@@ -135,7 +204,7 @@ static int wm8741_startup(struct snd_pcm_substream *substream,
135 204
136 snd_pcm_hw_constraint_list(substream->runtime, 0, 205 snd_pcm_hw_constraint_list(substream->runtime, 0,
137 SNDRV_PCM_HW_PARAM_RATE, 206 SNDRV_PCM_HW_PARAM_RATE,
138 &wm8741->rate_constraint); 207 wm8741->sysclk_constraints);
139 208
140 return 0; 209 return 0;
141} 210}
@@ -145,8 +214,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
145 struct snd_soc_dai *dai) 214 struct snd_soc_dai *dai)
146{ 215{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data; 216 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct snd_soc_device *socdev = rtd->socdev; 217 struct snd_soc_codec *codec = rtd->codec;
149 struct snd_soc_codec *codec = socdev->card->codec;
150 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 218 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
151 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 219 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
152 int i; 220 int i;
@@ -196,47 +264,52 @@ static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
196{ 264{
197 struct snd_soc_codec *codec = codec_dai->codec; 265 struct snd_soc_codec *codec = codec_dai->codec;
198 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 266 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
199 unsigned int val;
200 int i;
201 267
202 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq); 268 dev_dbg(codec->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
203 269
204 wm8741->sysclk = freq; 270 switch (freq) {
205 271 case 11289600:
206 wm8741->rate_constraint.count = 0; 272 wm8741->sysclk_constraints = &constraints_11289;
207 273 wm8741->sysclk = freq;
208 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { 274 return 0;
209 dev_dbg(codec->dev, "index = %d, ratio = %d, freq = %d", 275
210 i, lrclk_ratios[i].ratio, freq); 276 case 12288000:
211 277 wm8741->sysclk_constraints = &constraints_12288;
212 val = freq / lrclk_ratios[i].ratio; 278 wm8741->sysclk = freq;
213 /* Check that it's a standard rate since core can't 279 return 0;
214 * cope with others and having the odd rates confuses 280
215 * constraint matching. 281 case 16384000:
216 */ 282 wm8741->sysclk_constraints = &constraints_16384;
217 switch (val) { 283 wm8741->sysclk = freq;
218 case 32000: 284 return 0;
219 case 44100: 285
220 case 48000: 286 case 16934400:
221 case 64000: 287 wm8741->sysclk_constraints = &constraints_16934;
222 case 88200: 288 wm8741->sysclk = freq;
223 case 96000: 289 return 0;
224 dev_dbg(codec->dev, "Supported sample rate: %dHz\n", 290
225 val); 291 case 18432000:
226 wm8741->rate_constraint_list[i] = val; 292 wm8741->sysclk_constraints = &constraints_18432;
227 wm8741->rate_constraint.count++; 293 wm8741->sysclk = freq;
228 break; 294 return 0;
229 default: 295
230 dev_dbg(codec->dev, "Skipping sample rate: %dHz\n", 296 case 22579200:
231 val); 297 case 33868800:
232 } 298 wm8741->sysclk_constraints = &constraints_22579;
299 wm8741->sysclk = freq;
300 return 0;
301
302 case 24576000:
303 wm8741->sysclk_constraints = &constraints_24576;
304 wm8741->sysclk = freq;
305 return 0;
306
307 case 36864000:
308 wm8741->sysclk_constraints = &constraints_36864;
309 wm8741->sysclk = freq;
310 return 0;
233 } 311 }
234 312 return -EINVAL;
235 /* Need at least one supported rate... */
236 if (wm8741->rate_constraint.count == 0)
237 return -EINVAL;
238
239 return 0;
240} 313}
241 314
242static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, 315static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
@@ -314,8 +387,8 @@ static struct snd_soc_dai_ops wm8741_dai_ops = {
314 .set_fmt = wm8741_set_dai_fmt, 387 .set_fmt = wm8741_set_dai_fmt,
315}; 388};
316 389
317struct snd_soc_dai wm8741_dai = { 390static struct snd_soc_dai_driver wm8741_dai = {
318 .name = "WM8741", 391 .name = "wm8741",
319 .playback = { 392 .playback = {
320 .stream_name = "Playback", 393 .stream_name = "Playback",
321 .channels_min = 2, /* Mono modes not yet supported */ 394 .channels_min = 2, /* Mono modes not yet supported */
@@ -325,13 +398,10 @@ struct snd_soc_dai wm8741_dai = {
325 }, 398 },
326 .ops = &wm8741_dai_ops, 399 .ops = &wm8741_dai_ops,
327}; 400};
328EXPORT_SYMBOL_GPL(wm8741_dai);
329 401
330#ifdef CONFIG_PM 402#ifdef CONFIG_PM
331static int wm8741_resume(struct platform_device *pdev) 403static int wm8741_resume(struct snd_soc_codec *codec)
332{ 404{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 u16 *cache = codec->reg_cache; 405 u16 *cache = codec->reg_cache;
336 int i; 406 int i;
337 407
@@ -348,189 +418,103 @@ static int wm8741_resume(struct platform_device *pdev)
348#define wm8741_resume NULL 418#define wm8741_resume NULL
349#endif 419#endif
350 420
351static int wm8741_probe(struct platform_device *pdev) 421static int wm8741_probe(struct snd_soc_codec *codec)
352{ 422{
353 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 423 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
354 struct snd_soc_codec *codec;
355 int ret = 0; 424 int ret = 0;
356 425
357 if (wm8741_codec == NULL) { 426 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
358 dev_err(&pdev->dev, "Codec device not registered\n"); 427 if (ret != 0) {
359 return -ENODEV; 428 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
429 return ret;
360 } 430 }
361 431
362 socdev->card->codec = wm8741_codec; 432 ret = wm8741_reset(codec);
363 codec = wm8741_codec;
364
365 /* register pcms */
366 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
367 if (ret < 0) { 433 if (ret < 0) {
368 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 434 dev_err(codec->dev, "Failed to issue reset\n");
369 goto pcm_err; 435 return ret;
370 } 436 }
371 437
438 /* Change some default settings - latch VU */
439 snd_soc_update_bits(codec, WM8741_DACLLSB_ATTENUATION,
440 WM8741_UPDATELL, WM8741_UPDATELL);
441 snd_soc_update_bits(codec, WM8741_DACLMSB_ATTENUATION,
442 WM8741_UPDATELM, WM8741_UPDATELM);
443 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
444 WM8741_UPDATERL, WM8741_UPDATERL);
445 snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION,
446 WM8741_UPDATERM, WM8741_UPDATERM);
447
372 snd_soc_add_controls(codec, wm8741_snd_controls, 448 snd_soc_add_controls(codec, wm8741_snd_controls,
373 ARRAY_SIZE(wm8741_snd_controls)); 449 ARRAY_SIZE(wm8741_snd_controls));
374 wm8741_add_widgets(codec); 450 wm8741_add_widgets(codec);
375 451
452 dev_dbg(codec->dev, "Successful registration\n");
376 return ret; 453 return ret;
377
378pcm_err:
379 return ret;
380}
381
382static int wm8741_remove(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385
386 snd_soc_free_pcms(socdev);
387 snd_soc_dapm_free(socdev);
388
389 return 0;
390} 454}
391 455
392struct snd_soc_codec_device soc_codec_dev_wm8741 = { 456static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
393 .probe = wm8741_probe, 457 .probe = wm8741_probe,
394 .remove = wm8741_remove,
395 .resume = wm8741_resume, 458 .resume = wm8741_resume,
459 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
460 .reg_word_size = sizeof(u16),
461 .reg_cache_default = wm8741_reg_defaults,
396}; 462};
397EXPORT_SYMBOL_GPL(soc_codec_dev_wm8741);
398 463
399static int wm8741_register(struct wm8741_priv *wm8741, 464#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
400 enum snd_soc_control_type control) 465static int wm8741_i2c_probe(struct i2c_client *i2c,
466 const struct i2c_device_id *id)
401{ 467{
402 int ret; 468 struct wm8741_priv *wm8741;
403 struct snd_soc_codec *codec = &wm8741->codec; 469 int ret, i;
404 int i;
405
406 if (wm8741_codec) {
407 dev_err(codec->dev, "Another WM8741 is registered\n");
408 return -EINVAL;
409 }
410
411 mutex_init(&codec->mutex);
412 INIT_LIST_HEAD(&codec->dapm_widgets);
413 INIT_LIST_HEAD(&codec->dapm_paths);
414
415 snd_soc_codec_set_drvdata(codec, wm8741);
416 codec->name = "WM8741";
417 codec->owner = THIS_MODULE;
418 codec->bias_level = SND_SOC_BIAS_OFF;
419 codec->set_bias_level = NULL;
420 codec->dai = &wm8741_dai;
421 codec->num_dai = 1;
422 codec->reg_cache_size = WM8741_REGISTER_COUNT;
423 codec->reg_cache = &wm8741->reg_cache;
424
425 wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
426 wm8741->rate_constraint.count =
427 ARRAY_SIZE(wm8741->rate_constraint_list);
428
429 memcpy(codec->reg_cache, wm8741_reg_defaults,
430 sizeof(wm8741->reg_cache));
431 470
432 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 471 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
433 if (ret != 0) { 472 if (wm8741 == NULL)
434 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 473 return -ENOMEM;
435 goto err;
436 }
437 474
438 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) 475 for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
439 wm8741->supplies[i].supply = wm8741_supply_names[i]; 476 wm8741->supplies[i].supply = wm8741_supply_names[i];
440 477
441 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies), 478 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
442 wm8741->supplies); 479 wm8741->supplies);
443 if (ret != 0) { 480 if (ret != 0) {
444 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 481 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
445 goto err; 482 goto err;
446 } 483 }
447 484
448 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), 485 ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
449 wm8741->supplies); 486 wm8741->supplies);
450 if (ret != 0) { 487 if (ret != 0) {
451 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 488 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
452 goto err_get; 489 goto err_get;
453 } 490 }
454 491
455 ret = wm8741_reset(codec); 492 i2c_set_clientdata(i2c, wm8741);
456 if (ret < 0) { 493 wm8741->control_type = SND_SOC_I2C;
457 dev_err(codec->dev, "Failed to issue reset\n");
458 goto err_enable;
459 }
460
461 wm8741_dai.dev = codec->dev;
462
463 /* Change some default settings - latch VU */
464 wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
465 wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
466 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
467 wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
468
469 wm8741_codec = codec;
470
471 ret = snd_soc_register_codec(codec);
472 if (ret != 0) {
473 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
474 return ret;
475 }
476
477 ret = snd_soc_register_dai(&wm8741_dai);
478 if (ret != 0) {
479 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
480 snd_soc_unregister_codec(codec);
481 return ret;
482 }
483 494
484 dev_dbg(codec->dev, "Successful registration\n"); 495 ret = snd_soc_register_codec(&i2c->dev,
485 return 0; 496 &soc_codec_dev_wm8741, &wm8741_dai, 1);
497 if (ret < 0)
498 goto err_enable;
499 return ret;
486 500
487err_enable: 501err_enable:
488 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); 502 regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
489 503
490err_get: 504err_get:
491 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); 505 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
492
493err: 506err:
494 kfree(wm8741); 507 kfree(wm8741);
495 return ret; 508 return ret;
496} 509}
497 510
498static void wm8741_unregister(struct wm8741_priv *wm8741) 511static int wm8741_i2c_remove(struct i2c_client *client)
499{
500 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
501
502 snd_soc_unregister_dai(&wm8741_dai);
503 snd_soc_unregister_codec(&wm8741->codec);
504 kfree(wm8741);
505 wm8741_codec = NULL;
506}
507
508#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
509static __devinit int wm8741_i2c_probe(struct i2c_client *i2c,
510 const struct i2c_device_id *id)
511{
512 struct wm8741_priv *wm8741;
513 struct snd_soc_codec *codec;
514
515 wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
516 if (wm8741 == NULL)
517 return -ENOMEM;
518
519 codec = &wm8741->codec;
520 codec->hw_write = (hw_write_t)i2c_master_send;
521
522 i2c_set_clientdata(i2c, wm8741);
523 codec->control_data = i2c;
524
525 codec->dev = &i2c->dev;
526
527 return wm8741_register(wm8741, SND_SOC_I2C);
528}
529
530static __devexit int wm8741_i2c_remove(struct i2c_client *client)
531{ 512{
532 struct wm8741_priv *wm8741 = i2c_get_clientdata(client); 513 struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
533 wm8741_unregister(wm8741); 514
515 snd_soc_unregister_codec(&client->dev);
516 regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
517 kfree(i2c_get_clientdata(client));
534 return 0; 518 return 0;
535} 519}
536 520
@@ -540,29 +524,28 @@ static const struct i2c_device_id wm8741_i2c_id[] = {
540}; 524};
541MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id); 525MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
542 526
543
544static struct i2c_driver wm8741_i2c_driver = { 527static struct i2c_driver wm8741_i2c_driver = {
545 .driver = { 528 .driver = {
546 .name = "WM8741", 529 .name = "wm8741-codec",
547 .owner = THIS_MODULE, 530 .owner = THIS_MODULE,
548 }, 531 },
549 .probe = wm8741_i2c_probe, 532 .probe = wm8741_i2c_probe,
550 .remove = __devexit_p(wm8741_i2c_remove), 533 .remove = wm8741_i2c_remove,
551 .id_table = wm8741_i2c_id, 534 .id_table = wm8741_i2c_id,
552}; 535};
553#endif 536#endif
554 537
555static int __init wm8741_modinit(void) 538static int __init wm8741_modinit(void)
556{ 539{
557 int ret; 540 int ret = 0;
541
558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 542#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
559 ret = i2c_add_driver(&wm8741_i2c_driver); 543 ret = i2c_add_driver(&wm8741_i2c_driver);
560 if (ret != 0) { 544 if (ret != 0)
561 printk(KERN_ERR "Failed to register WM8741 I2C driver: %d\n", 545 pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
562 ret);
563 }
564#endif 546#endif
565 return 0; 547
548 return ret;
566} 549}
567module_init(wm8741_modinit); 550module_init(wm8741_modinit);
568 551
diff --git a/sound/soc/codecs/wm8741.h b/sound/soc/codecs/wm8741.h
index fdef6ecd1f6f..56c1b1d4a681 100644
--- a/sound/soc/codecs/wm8741.h
+++ b/sound/soc/codecs/wm8741.h
@@ -208,7 +208,4 @@
208 208
209#define WM8741_SYSCLK 0 209#define WM8741_SYSCLK 0
210 210
211extern struct snd_soc_dai wm8741_dai;
212extern struct snd_soc_codec_device soc_codec_dev_wm8741;
213
214#endif 211#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index e2c05e3e323a..38f38fddd190 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -25,7 +25,6 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31#include "wm8750.h" 30#include "wm8750.h"
@@ -52,8 +51,7 @@ static const u16 wm8750_reg[] = {
52/* codec private data */ 51/* codec private data */
53struct wm8750_priv { 52struct wm8750_priv {
54 unsigned int sysclk; 53 unsigned int sysclk;
55 struct snd_soc_codec codec; 54 enum snd_soc_control_type control_type;
56 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
57}; 55};
58 56
59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 57#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
@@ -399,10 +397,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
399 397
400static int wm8750_add_widgets(struct snd_soc_codec *codec) 398static int wm8750_add_widgets(struct snd_soc_codec *codec)
401{ 399{
402 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 400 struct snd_soc_dapm_context *dapm = &codec->dapm;
403 ARRAY_SIZE(wm8750_dapm_widgets));
404 401
405 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 402 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
403 ARRAY_SIZE(wm8750_dapm_widgets));
404 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
406 405
407 return 0; 406 return 0;
408} 407}
@@ -560,8 +559,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
560 struct snd_soc_dai *dai) 559 struct snd_soc_dai *dai)
561{ 560{
562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 561 struct snd_soc_pcm_runtime *rtd = substream->private_data;
563 struct snd_soc_device *socdev = rtd->socdev; 562 struct snd_soc_codec *codec = rtd->codec;
564 struct snd_soc_codec *codec = socdev->card->codec;
565 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); 563 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 564 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 565 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
@@ -616,7 +614,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
616 case SND_SOC_BIAS_PREPARE: 614 case SND_SOC_BIAS_PREPARE:
617 break; 615 break;
618 case SND_SOC_BIAS_STANDBY: 616 case SND_SOC_BIAS_STANDBY:
619 if (codec->bias_level == SND_SOC_BIAS_OFF) { 617 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
620 /* Set VMID to 5k */ 618 /* Set VMID to 5k */
621 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 619 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
622 620
@@ -631,7 +629,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
631 snd_soc_write(codec, WM8750_PWR1, 0x0001); 629 snd_soc_write(codec, WM8750_PWR1, 0x0001);
632 break; 630 break;
633 } 631 }
634 codec->bias_level = level; 632 codec->dapm.bias_level = level;
635 return 0; 633 return 0;
636} 634}
637 635
@@ -649,8 +647,8 @@ static struct snd_soc_dai_ops wm8750_dai_ops = {
649 .set_sysclk = wm8750_set_dai_sysclk, 647 .set_sysclk = wm8750_set_dai_sysclk,
650}; 648};
651 649
652struct snd_soc_dai wm8750_dai = { 650static struct snd_soc_dai_driver wm8750_dai = {
653 .name = "WM8750", 651 .name = "wm8750-hifi",
654 .playback = { 652 .playback = {
655 .stream_name = "Playback", 653 .stream_name = "Playback",
656 .channels_min = 1, 654 .channels_min = 1,
@@ -665,21 +663,15 @@ struct snd_soc_dai wm8750_dai = {
665 .formats = WM8750_FORMATS,}, 663 .formats = WM8750_FORMATS,},
666 .ops = &wm8750_dai_ops, 664 .ops = &wm8750_dai_ops,
667}; 665};
668EXPORT_SYMBOL_GPL(wm8750_dai);
669 666
670static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 667static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
671{ 668{
672 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
673 struct snd_soc_codec *codec = socdev->card->codec;
674
675 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); 669 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
676 return 0; 670 return 0;
677} 671}
678 672
679static int wm8750_resume(struct platform_device *pdev) 673static int wm8750_resume(struct snd_soc_codec *codec)
680{ 674{
681 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
682 struct snd_soc_codec *codec = socdev->card->codec;
683 int i; 675 int i;
684 u8 data[2]; 676 u8 data[2];
685 u16 *cache = codec->reg_cache; 677 u16 *cache = codec->reg_cache;
@@ -698,100 +690,21 @@ static int wm8750_resume(struct platform_device *pdev)
698 return 0; 690 return 0;
699} 691}
700 692
701static struct snd_soc_codec *wm8750_codec; 693static int wm8750_probe(struct snd_soc_codec *codec)
702
703static int wm8750_probe(struct platform_device *pdev)
704{ 694{
705 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 695 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
706 struct snd_soc_codec *codec; 696 int reg, ret;
707 int ret = 0;
708
709 if (!wm8750_codec) {
710 dev_err(&pdev->dev, "WM8750 codec not yet registered\n");
711 return -EINVAL;
712 }
713
714 socdev->card->codec = wm8750_codec;
715 codec = wm8750_codec;
716
717 /* register pcms */
718 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
719 if (ret < 0) {
720 printk(KERN_ERR "wm8750: failed to create pcms\n");
721 goto err;
722 }
723
724 snd_soc_add_controls(codec, wm8750_snd_controls,
725 ARRAY_SIZE(wm8750_snd_controls));
726 wm8750_add_widgets(codec);
727
728 return 0;
729
730err:
731 return ret;
732}
733
734/* power down chip */
735static int wm8750_remove(struct platform_device *pdev)
736{
737 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
738
739 snd_soc_free_pcms(socdev);
740 snd_soc_dapm_free(socdev);
741
742 return 0;
743}
744
745struct snd_soc_codec_device soc_codec_dev_wm8750 = {
746 .probe = wm8750_probe,
747 .remove = wm8750_remove,
748 .suspend = wm8750_suspend,
749 .resume = wm8750_resume,
750};
751EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
752
753/*
754 * initialise the WM8750 driver
755 * register the mixer and dsp interfaces with the kernel
756 */
757static int wm8750_register(struct wm8750_priv *wm8750,
758 enum snd_soc_control_type control)
759{
760 struct snd_soc_codec *codec = &wm8750->codec;
761 int reg, ret = 0;
762
763 if (wm8750_codec) {
764 dev_err(codec->dev, "Multiple WM8750 devices not supported\n");
765 ret = -EINVAL;
766 goto err;
767 }
768
769 mutex_init(&codec->mutex);
770 INIT_LIST_HEAD(&codec->dapm_widgets);
771 INIT_LIST_HEAD(&codec->dapm_paths);
772
773 codec->name = "WM8750";
774 codec->owner = THIS_MODULE;
775 codec->bias_level = SND_SOC_BIAS_STANDBY;
776 codec->set_bias_level = wm8750_set_bias_level;
777 codec->dai = &wm8750_dai;
778 codec->num_dai = 1;
779 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
780 codec->reg_cache = &wm8750->reg_cache;
781 snd_soc_codec_set_drvdata(codec, wm8750);
782
783 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
784 697
785 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 698 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
786 if (ret < 0) { 699 if (ret < 0) {
787 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret); 700 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
788 goto err; 701 return ret;
789 } 702 }
790 703
791 ret = wm8750_reset(codec); 704 ret = wm8750_reset(codec);
792 if (ret < 0) { 705 if (ret < 0) {
793 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret); 706 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
794 goto err; 707 return ret;
795 } 708 }
796 709
797 /* charge output caps */ 710 /* charge output caps */
@@ -815,150 +728,130 @@ static int wm8750_register(struct wm8750_priv *wm8750,
815 reg = snd_soc_read(codec, WM8750_RINVOL); 728 reg = snd_soc_read(codec, WM8750_RINVOL);
816 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 729 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
817 730
818 wm8750_codec = codec; 731 snd_soc_add_controls(codec, wm8750_snd_controls,
819 732 ARRAY_SIZE(wm8750_snd_controls));
820 ret = snd_soc_register_codec(codec); 733 wm8750_add_widgets(codec);
821 if (ret != 0) {
822 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
823 goto err;
824 }
825
826 ret = snd_soc_register_dais(&wm8750_dai, 1);
827 if (ret != 0) {
828 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
829 goto err_codec;
830 }
831
832 return 0;
833
834err_codec:
835 snd_soc_unregister_codec(codec);
836err:
837 kfree(wm8750);
838 return ret; 734 return ret;
839} 735}
840 736
841static void wm8750_unregister(struct wm8750_priv *wm8750) 737static int wm8750_remove(struct snd_soc_codec *codec)
842{ 738{
843 wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF); 739 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
844 snd_soc_unregister_dais(&wm8750_dai, 1); 740 return 0;
845 snd_soc_unregister_codec(&wm8750->codec);
846 kfree(wm8750);
847 wm8750_codec = NULL;
848} 741}
849 742
850#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 743static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
851 744 .probe = wm8750_probe,
852/* 745 .remove = wm8750_remove,
853 * WM8750 2 wire address is determined by GPIO5 746 .suspend = wm8750_suspend,
854 * state during powerup. 747 .resume = wm8750_resume,
855 * low = 0x1a 748 .set_bias_level = wm8750_set_bias_level,
856 * high = 0x1b 749 .reg_cache_size = ARRAY_SIZE(wm8750_reg),
857 */ 750 .reg_word_size = sizeof(u16),
751 .reg_cache_default = wm8750_reg,
752};
858 753
859static int wm8750_i2c_probe(struct i2c_client *i2c, 754#if defined(CONFIG_SPI_MASTER)
860 const struct i2c_device_id *id) 755static int __devinit wm8750_spi_probe(struct spi_device *spi)
861{ 756{
862 struct snd_soc_codec *codec;
863 struct wm8750_priv *wm8750; 757 struct wm8750_priv *wm8750;
758 int ret;
864 759
865 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 760 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
866 if (wm8750 == NULL) 761 if (wm8750 == NULL)
867 return -ENOMEM; 762 return -ENOMEM;
868 763
869 codec = &wm8750->codec; 764 wm8750->control_type = SND_SOC_SPI;
870 codec->control_data = i2c; 765 spi_set_drvdata(spi, wm8750);
871 i2c_set_clientdata(i2c, wm8750);
872
873 codec->dev = &i2c->dev;
874 766
875 return wm8750_register(wm8750, SND_SOC_I2C); 767 ret = snd_soc_register_codec(&spi->dev,
768 &soc_codec_dev_wm8750, &wm8750_dai, 1);
769 if (ret < 0)
770 kfree(wm8750);
771 return ret;
876} 772}
877 773
878static int wm8750_i2c_remove(struct i2c_client *client) 774static int __devexit wm8750_spi_remove(struct spi_device *spi)
879{ 775{
880 struct wm8750_priv *wm8750 = i2c_get_clientdata(client); 776 snd_soc_unregister_codec(&spi->dev);
881 wm8750_unregister(wm8750); 777 kfree(spi_get_drvdata(spi));
882 return 0; 778 return 0;
883} 779}
884 780
885static const struct i2c_device_id wm8750_i2c_id[] = { 781static struct spi_driver wm8750_spi_driver = {
886 { "wm8750", 0 },
887 { "wm8987", 0 }, /* WM8987 is register compatible with WM8750 */
888 { }
889};
890MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
891
892static struct i2c_driver wm8750_i2c_driver = {
893 .driver = { 782 .driver = {
894 .name = "WM8750 I2C Codec", 783 .name = "wm8750-codec",
895 .owner = THIS_MODULE, 784 .owner = THIS_MODULE,
896 }, 785 },
897 .probe = wm8750_i2c_probe, 786 .probe = wm8750_spi_probe,
898 .remove = wm8750_i2c_remove, 787 .remove = __devexit_p(wm8750_spi_remove),
899 .id_table = wm8750_i2c_id,
900}; 788};
901#endif 789#endif /* CONFIG_SPI_MASTER */
902 790
903#if defined(CONFIG_SPI_MASTER) 791#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
904static int __devinit wm8750_spi_probe(struct spi_device *spi) 792static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
793 const struct i2c_device_id *id)
905{ 794{
906 struct snd_soc_codec *codec;
907 struct wm8750_priv *wm8750; 795 struct wm8750_priv *wm8750;
796 int ret;
908 797
909 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); 798 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
910 if (wm8750 == NULL) 799 if (wm8750 == NULL)
911 return -ENOMEM; 800 return -ENOMEM;
912 801
913 codec = &wm8750->codec; 802 i2c_set_clientdata(i2c, wm8750);
914 codec->control_data = spi; 803 wm8750->control_type = SND_SOC_I2C;
915 codec->dev = &spi->dev;
916
917 dev_set_drvdata(&spi->dev, wm8750);
918 804
919 return wm8750_register(wm8750, SND_SOC_SPI); 805 ret = snd_soc_register_codec(&i2c->dev,
806 &soc_codec_dev_wm8750, &wm8750_dai, 1);
807 if (ret < 0)
808 kfree(wm8750);
809 return ret;
920} 810}
921 811
922static int __devexit wm8750_spi_remove(struct spi_device *spi) 812static __devexit int wm8750_i2c_remove(struct i2c_client *client)
923{ 813{
924 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev); 814 snd_soc_unregister_codec(&client->dev);
925 wm8750_unregister(wm8750); 815 kfree(i2c_get_clientdata(client));
926 return 0; 816 return 0;
927} 817}
928 818
929static const struct spi_device_id wm8750_spi_id[] = { 819static const struct i2c_device_id wm8750_i2c_id[] = {
930 { "wm8750", 0 }, 820 { "wm8750", 0 },
931 { "wm8987", 0 }, 821 { "wm8987", 0 },
932 { } 822 { }
933}; 823};
934MODULE_DEVICE_TABLE(spi, wm8750_spi_id); 824MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
935 825
936static struct spi_driver wm8750_spi_driver = { 826static struct i2c_driver wm8750_i2c_driver = {
937 .driver = { 827 .driver = {
938 .name = "WM8750 SPI Codec", 828 .name = "wm8750-codec",
939 .bus = &spi_bus_type, 829 .owner = THIS_MODULE,
940 .owner = THIS_MODULE,
941 }, 830 },
942 .probe = wm8750_spi_probe, 831 .probe = wm8750_i2c_probe,
943 .remove = __devexit_p(wm8750_spi_remove), 832 .remove = __devexit_p(wm8750_i2c_remove),
944 .id_table = wm8750_spi_id, 833 .id_table = wm8750_i2c_id,
945}; 834};
946#endif 835#endif
947 836
948static int __init wm8750_modinit(void) 837static int __init wm8750_modinit(void)
949{ 838{
950 int ret; 839 int ret = 0;
951#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 840#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
952 ret = i2c_add_driver(&wm8750_i2c_driver); 841 ret = i2c_add_driver(&wm8750_i2c_driver);
953 if (ret != 0) 842 if (ret != 0) {
954 pr_err("Failed to register WM8750 I2C driver: %d\n", ret); 843 printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
844 ret);
845 }
955#endif 846#endif
956#if defined(CONFIG_SPI_MASTER) 847#if defined(CONFIG_SPI_MASTER)
957 ret = spi_register_driver(&wm8750_spi_driver); 848 ret = spi_register_driver(&wm8750_spi_driver);
958 if (ret != 0) 849 if (ret != 0) {
959 pr_err("Failed to register WM8750 SPI driver: %d\n", ret); 850 printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
851 ret);
852 }
960#endif 853#endif
961 return 0; 854 return ret;
962} 855}
963module_init(wm8750_modinit); 856module_init(wm8750_modinit);
964 857
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index 1dc100e19cfe..121427c047fb 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -57,13 +57,4 @@
57 57
58#define WM8750_SYSCLK 0 58#define WM8750_SYSCLK 0
59 59
60struct wm8750_setup_data {
61 int spi;
62 int i2c_bus;
63 unsigned short i2c_address;
64};
65
66extern struct snd_soc_dai wm8750_dai;
67extern struct snd_soc_codec_device soc_codec_dev_wm8750;
68
69#endif 60#endif
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b59f349c5218..ffa2ffe5ec11 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -45,7 +45,6 @@
45#include <sound/pcm.h> 45#include <sound/pcm.h>
46#include <sound/pcm_params.h> 46#include <sound/pcm_params.h>
47#include <sound/soc.h> 47#include <sound/soc.h>
48#include <sound/soc-dapm.h>
49#include <sound/initval.h> 48#include <sound/initval.h>
50#include <sound/tlv.h> 49#include <sound/tlv.h>
51#include <asm/div64.h> 50#include <asm/div64.h>
@@ -56,8 +55,10 @@ static int caps_charge = 2000;
56module_param(caps_charge, int, 0); 55module_param(caps_charge, int, 0);
57MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); 56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
58 57
59static void wm8753_set_dai_mode(struct snd_soc_codec *codec, 58static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
60 unsigned int mode); 59 unsigned int fmt);
60static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
61 unsigned int fmt);
61 62
62/* 63/*
63 * wm8753 register cache 64 * wm8753 register cache
@@ -65,79 +66,37 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
65 * are using 2 wire for device control, so we cache them instead. 66 * are using 2 wire for device control, so we cache them instead.
66 */ 67 */
67static const u16 wm8753_reg[] = { 68static const u16 wm8753_reg[] = {
68 0x0008, 0x0000, 0x000a, 0x000a, 69 0x0000, 0x0008, 0x0000, 0x000a,
69 0x0033, 0x0000, 0x0007, 0x00ff, 70 0x000a, 0x0033, 0x0000, 0x0007,
70 0x00ff, 0x000f, 0x000f, 0x007b, 71 0x00ff, 0x00ff, 0x000f, 0x000f,
71 0x0000, 0x0032, 0x0000, 0x00c3, 72 0x007b, 0x0000, 0x0032, 0x0000,
72 0x00c3, 0x00c0, 0x0000, 0x0000, 73 0x00c3, 0x00c3, 0x00c0, 0x0000,
73 0x0000, 0x0000, 0x0000, 0x0000, 74 0x0000, 0x0000, 0x0000, 0x0000,
74 0x0000, 0x0000, 0x0000, 0x0000, 75 0x0000, 0x0000, 0x0000, 0x0000,
75 0x0000, 0x0000, 0x0000, 0x0055,
76 0x0005, 0x0050, 0x0055, 0x0050,
77 0x0055, 0x0050, 0x0055, 0x0079,
78 0x0079, 0x0079, 0x0079, 0x0079,
79 0x0000, 0x0000, 0x0000, 0x0000, 76 0x0000, 0x0000, 0x0000, 0x0000,
80 0x0097, 0x0097, 0x0000, 0x0004, 77 0x0055, 0x0005, 0x0050, 0x0055,
81 0x0000, 0x0083, 0x0024, 0x01ba, 78 0x0050, 0x0055, 0x0050, 0x0055,
82 0x0000, 0x0083, 0x0024, 0x01ba, 79 0x0079, 0x0079, 0x0079, 0x0079,
83 0x0000, 0x0000, 0x0000 80 0x0079, 0x0000, 0x0000, 0x0000,
81 0x0000, 0x0097, 0x0097, 0x0000,
82 0x0004, 0x0000, 0x0083, 0x0024,
83 0x01ba, 0x0000, 0x0083, 0x0024,
84 0x01ba, 0x0000, 0x0000, 0x0000
84}; 85};
85 86
86/* codec private data */ 87/* codec private data */
87struct wm8753_priv { 88struct wm8753_priv {
89 enum snd_soc_control_type control_type;
88 unsigned int sysclk; 90 unsigned int sysclk;
89 unsigned int pcmclk; 91 unsigned int pcmclk;
90 struct snd_soc_codec codec;
91 u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
92};
93
94/*
95 * read wm8753 register cache
96 */
97static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
98 unsigned int reg)
99{
100 u16 *cache = codec->reg_cache;
101 if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
102 return -1;
103 return cache[reg - 1];
104}
105
106/*
107 * write wm8753 register cache
108 */
109static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
110 unsigned int reg, unsigned int value)
111{
112 u16 *cache = codec->reg_cache;
113 if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
114 return;
115 cache[reg - 1] = value;
116}
117
118/*
119 * write to the WM8753 register space
120 */
121static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
122 unsigned int value)
123{
124 u8 data[2];
125 92
126 /* data is 93 unsigned int voice_fmt;
127 * D15..D9 WM8753 register offset 94 unsigned int hifi_fmt;
128 * D8...D0 register data
129 */
130 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
131 data[1] = value & 0x00ff;
132 95
133 wm8753_write_reg_cache(codec, reg, value); 96 int dai_func;
134 if (codec->hw_write(codec->control_data, data, 2) == 2) 97};
135 return 0;
136 else
137 return -EIO;
138}
139 98
140#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0) 99#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
141 100
142/* 101/*
143 * WM8753 Controls 102 * WM8753 Controls
@@ -217,9 +176,9 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
217 struct snd_ctl_elem_value *ucontrol) 176 struct snd_ctl_elem_value *ucontrol)
218{ 177{
219 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 178 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
220 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); 179 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
221 180
222 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; 181 ucontrol->value.integer.value[0] = wm8753->dai_func;
223 return 0; 182 return 0;
224} 183}
225 184
@@ -227,16 +186,26 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
227 struct snd_ctl_elem_value *ucontrol) 186 struct snd_ctl_elem_value *ucontrol)
228{ 187{
229 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 188 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
230 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); 189 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
190 u16 ioctl;
231 191
232 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) 192 if (codec->active)
233 return 0; 193 return -EBUSY;
194
195 ioctl = snd_soc_read(codec, WM8753_IOCTL);
196
197 wm8753->dai_func = ucontrol->value.integer.value[0];
198
199 if (((ioctl >> 2) & 0x3) == wm8753->dai_func)
200 return 1;
234 201
235 mode &= 0xfff3; 202 ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
236 mode |= (ucontrol->value.integer.value[0] << 2); 203 snd_soc_write(codec, WM8753_IOCTL, ioctl);
204
205
206 wm8753_hifi_write_dai_fmt(codec, wm8753->hifi_fmt);
207 wm8753_voice_write_dai_fmt(codec, wm8753->voice_fmt);
237 208
238 wm8753_write(codec, WM8753_IOCTL, mode);
239 wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]);
240 return 1; 209 return 1;
241} 210}
242 211
@@ -669,10 +638,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
669 638
670static int wm8753_add_widgets(struct snd_soc_codec *codec) 639static int wm8753_add_widgets(struct snd_soc_codec *codec)
671{ 640{
672 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 641 struct snd_soc_dapm_context *dapm = &codec->dapm;
673 ARRAY_SIZE(wm8753_dapm_widgets));
674 642
675 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 643 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
644 ARRAY_SIZE(wm8753_dapm_widgets));
645 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
676 646
677 return 0; 647 return 0;
678} 648}
@@ -737,17 +707,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
737 if (pll_id == WM8753_PLL1) { 707 if (pll_id == WM8753_PLL1) {
738 offset = 0; 708 offset = 0;
739 enable = 0x10; 709 enable = 0x10;
740 reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; 710 reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
741 } else { 711 } else {
742 offset = 4; 712 offset = 4;
743 enable = 0x8; 713 enable = 0x8;
744 reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; 714 reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
745 } 715 }
746 716
747 if (!freq_in || !freq_out) { 717 if (!freq_in || !freq_out) {
748 /* disable PLL */ 718 /* disable PLL */
749 wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); 719 snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
750 wm8753_write(codec, WM8753_CLOCK, reg); 720 snd_soc_write(codec, WM8753_CLOCK, reg);
751 return 0; 721 return 0;
752 } else { 722 } else {
753 u16 value = 0; 723 u16 value = 0;
@@ -758,20 +728,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
758 /* set up N and K PLL divisor ratios */ 728 /* set up N and K PLL divisor ratios */
759 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ 729 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
760 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); 730 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
761 wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); 731 snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
762 732
763 /* bits 8:0 = PLL_K[17:9] */ 733 /* bits 8:0 = PLL_K[17:9] */
764 value = (pll_div.k & 0x03fe00) >> 9; 734 value = (pll_div.k & 0x03fe00) >> 9;
765 wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); 735 snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
766 736
767 /* bits 8:0 = PLL_K[8:0] */ 737 /* bits 8:0 = PLL_K[8:0] */
768 value = pll_div.k & 0x0001ff; 738 value = pll_div.k & 0x0001ff;
769 wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); 739 snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
770 740
771 /* set PLL as input and enable */ 741 /* set PLL as input and enable */
772 wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | 742 snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
773 (pll_div.div2 << 3)); 743 (pll_div.div2 << 3));
774 wm8753_write(codec, WM8753_CLOCK, reg | enable); 744 snd_soc_write(codec, WM8753_CLOCK, reg | enable);
775 } 745 }
776 return 0; 746 return 0;
777} 747}
@@ -874,11 +844,10 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
874/* 844/*
875 * Set's ADC and Voice DAC format. 845 * Set's ADC and Voice DAC format.
876 */ 846 */
877static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, 847static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec *codec,
878 unsigned int fmt) 848 unsigned int fmt)
879{ 849{
880 struct snd_soc_codec *codec = codec_dai->codec; 850 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
881 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
882 851
883 /* interface format */ 852 /* interface format */
884 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 853 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -900,7 +869,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
900 return -EINVAL; 869 return -EINVAL;
901 } 870 }
902 871
903 wm8753_write(codec, WM8753_PCM, voice); 872 snd_soc_write(codec, WM8753_PCM, voice);
904 return 0; 873 return 0;
905} 874}
906 875
@@ -912,11 +881,10 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
912 struct snd_soc_dai *dai) 881 struct snd_soc_dai *dai)
913{ 882{
914 struct snd_soc_pcm_runtime *rtd = substream->private_data; 883 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_device *socdev = rtd->socdev; 884 struct snd_soc_codec *codec = rtd->codec;
916 struct snd_soc_codec *codec = socdev->card->codec;
917 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 885 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 886 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 887 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
920 888
921 /* bit size */ 889 /* bit size */
922 switch (params_format(params)) { 890 switch (params_format(params)) {
@@ -936,23 +904,22 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
936 /* sample rate */ 904 /* sample rate */
937 if (params_rate(params) * 384 == wm8753->pcmclk) 905 if (params_rate(params) * 384 == wm8753->pcmclk)
938 srate |= 0x80; 906 srate |= 0x80;
939 wm8753_write(codec, WM8753_SRATE1, srate); 907 snd_soc_write(codec, WM8753_SRATE1, srate);
940 908
941 wm8753_write(codec, WM8753_PCM, voice); 909 snd_soc_write(codec, WM8753_PCM, voice);
942 return 0; 910 return 0;
943} 911}
944 912
945/* 913/*
946 * Set's PCM dai fmt and BCLK. 914 * Set's PCM dai fmt and BCLK.
947 */ 915 */
948static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, 916static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec *codec,
949 unsigned int fmt) 917 unsigned int fmt)
950{ 918{
951 struct snd_soc_codec *codec = codec_dai->codec;
952 u16 voice, ioctl; 919 u16 voice, ioctl;
953 920
954 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; 921 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
955 ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; 922 ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
956 923
957 /* set master/slave audio interface */ 924 /* set master/slave audio interface */
958 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 925 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1006,8 +973,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
1006 return -EINVAL; 973 return -EINVAL;
1007 } 974 }
1008 975
1009 wm8753_write(codec, WM8753_PCM, voice); 976 snd_soc_write(codec, WM8753_PCM, voice);
1010 wm8753_write(codec, WM8753_IOCTL, ioctl); 977 snd_soc_write(codec, WM8753_IOCTL, ioctl);
1011 return 0; 978 return 0;
1012} 979}
1013 980
@@ -1019,16 +986,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1019 986
1020 switch (div_id) { 987 switch (div_id) {
1021 case WM8753_PCMDIV: 988 case WM8753_PCMDIV:
1022 reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; 989 reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
1023 wm8753_write(codec, WM8753_CLOCK, reg | div); 990 snd_soc_write(codec, WM8753_CLOCK, reg | div);
1024 break; 991 break;
1025 case WM8753_BCLKDIV: 992 case WM8753_BCLKDIV:
1026 reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; 993 reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
1027 wm8753_write(codec, WM8753_SRATE2, reg | div); 994 snd_soc_write(codec, WM8753_SRATE2, reg | div);
1028 break; 995 break;
1029 case WM8753_VXCLKDIV: 996 case WM8753_VXCLKDIV:
1030 reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; 997 reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
1031 wm8753_write(codec, WM8753_SRATE2, reg | div); 998 snd_soc_write(codec, WM8753_SRATE2, reg | div);
1032 break; 999 break;
1033 default: 1000 default:
1034 return -EINVAL; 1001 return -EINVAL;
@@ -1039,11 +1006,10 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1039/* 1006/*
1040 * Set's HiFi DAC format. 1007 * Set's HiFi DAC format.
1041 */ 1008 */
1042static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, 1009static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec *codec,
1043 unsigned int fmt) 1010 unsigned int fmt)
1044{ 1011{
1045 struct snd_soc_codec *codec = codec_dai->codec; 1012 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
1046 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
1047 1013
1048 /* interface format */ 1014 /* interface format */
1049 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1015 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1065,21 +1031,20 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1065 return -EINVAL; 1031 return -EINVAL;
1066 } 1032 }
1067 1033
1068 wm8753_write(codec, WM8753_HIFI, hifi); 1034 snd_soc_write(codec, WM8753_HIFI, hifi);
1069 return 0; 1035 return 0;
1070} 1036}
1071 1037
1072/* 1038/*
1073 * Set's I2S DAI format. 1039 * Set's I2S DAI format.
1074 */ 1040 */
1075static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, 1041static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
1076 unsigned int fmt) 1042 unsigned int fmt)
1077{ 1043{
1078 struct snd_soc_codec *codec = codec_dai->codec;
1079 u16 ioctl, hifi; 1044 u16 ioctl, hifi;
1080 1045
1081 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; 1046 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
1082 ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; 1047 ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
1083 1048
1084 /* set master/slave audio interface */ 1049 /* set master/slave audio interface */
1085 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1050 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1133,8 +1098,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1133 return -EINVAL; 1098 return -EINVAL;
1134 } 1099 }
1135 1100
1136 wm8753_write(codec, WM8753_HIFI, hifi); 1101 snd_soc_write(codec, WM8753_HIFI, hifi);
1137 wm8753_write(codec, WM8753_IOCTL, ioctl); 1102 snd_soc_write(codec, WM8753_IOCTL, ioctl);
1138 return 0; 1103 return 0;
1139} 1104}
1140 1105
@@ -1146,11 +1111,10 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1146 struct snd_soc_dai *dai) 1111 struct snd_soc_dai *dai)
1147{ 1112{
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1113 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1149 struct snd_soc_device *socdev = rtd->socdev; 1114 struct snd_soc_codec *codec = rtd->codec;
1150 struct snd_soc_codec *codec = socdev->card->codec;
1151 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1115 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1116 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1117 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
1154 int coeff; 1118 int coeff;
1155 1119
1156 /* is digital filter coefficient valid ? */ 1120 /* is digital filter coefficient valid ? */
@@ -1159,7 +1123,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1159 printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); 1123 printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
1160 return coeff; 1124 return coeff;
1161 } 1125 }
1162 wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | 1126 snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
1163 coeff_div[coeff].usb); 1127 coeff_div[coeff].usb);
1164 1128
1165 /* bit size */ 1129 /* bit size */
@@ -1177,81 +1141,137 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1177 break; 1141 break;
1178 } 1142 }
1179 1143
1180 wm8753_write(codec, WM8753_HIFI, hifi); 1144 snd_soc_write(codec, WM8753_HIFI, hifi);
1181 return 0; 1145 return 0;
1182} 1146}
1183 1147
1184static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, 1148static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec *codec,
1185 unsigned int fmt) 1149 unsigned int fmt)
1186{ 1150{
1187 struct snd_soc_codec *codec = codec_dai->codec;
1188 u16 clock; 1151 u16 clock;
1189 1152
1190 /* set clk source as pcmclk */ 1153 /* set clk source as pcmclk */
1191 clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; 1154 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1192 wm8753_write(codec, WM8753_CLOCK, clock); 1155 snd_soc_write(codec, WM8753_CLOCK, clock);
1193 1156
1194 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1157 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1195 return -EINVAL;
1196 return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
1197} 1158}
1198 1159
1199static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai, 1160static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec *codec,
1200 unsigned int fmt) 1161 unsigned int fmt)
1201{ 1162{
1202 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1163 return wm8753_hdac_set_dai_fmt(codec, fmt);
1203 return -EINVAL;
1204 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1205} 1164}
1206 1165
1207static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, 1166static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec *codec,
1208 unsigned int fmt) 1167 unsigned int fmt)
1209{ 1168{
1210 struct snd_soc_codec *codec = codec_dai->codec;
1211 u16 clock; 1169 u16 clock;
1212 1170
1213 /* set clk source as pcmclk */ 1171 /* set clk source as pcmclk */
1214 clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; 1172 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1215 wm8753_write(codec, WM8753_CLOCK, clock); 1173 snd_soc_write(codec, WM8753_CLOCK, clock);
1216 1174
1217 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1175 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1218 return -EINVAL;
1219 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1220} 1176}
1221 1177
1222static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, 1178static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec *codec,
1223 unsigned int fmt) 1179 unsigned int fmt)
1224{ 1180{
1225 struct snd_soc_codec *codec = codec_dai->codec;
1226 u16 clock; 1181 u16 clock;
1227 1182
1228 /* set clk source as mclk */ 1183 /* set clk source as mclk */
1229 clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; 1184 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1230 wm8753_write(codec, WM8753_CLOCK, clock | 0x4); 1185 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
1231 1186
1232 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1187 if (wm8753_hdac_set_dai_fmt(codec, fmt) < 0)
1233 return -EINVAL;
1234 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
1235 return -EINVAL; 1188 return -EINVAL;
1236 return wm8753_i2s_set_dai_fmt(codec_dai, fmt); 1189 return wm8753_vdac_adc_set_dai_fmt(codec, fmt);
1190}
1191
1192static int wm8753_hifi_write_dai_fmt(struct snd_soc_codec *codec,
1193 unsigned int fmt)
1194{
1195 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1196 int ret = 0;
1197
1198 switch (wm8753->dai_func) {
1199 case 0:
1200 ret = wm8753_mode1h_set_dai_fmt(codec, fmt);
1201 break;
1202 case 1:
1203 ret = wm8753_mode2_set_dai_fmt(codec, fmt);
1204 break;
1205 case 2:
1206 case 3:
1207 ret = wm8753_mode3_4_set_dai_fmt(codec, fmt);
1208 break;
1209 default:
1210 break;
1211 }
1212 if (ret)
1213 return ret;
1214
1215 return wm8753_i2s_set_dai_fmt(codec, fmt);
1237} 1216}
1238 1217
1218static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
1219 unsigned int fmt)
1220{
1221 struct snd_soc_codec *codec = codec_dai->codec;
1222 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1223
1224 wm8753->hifi_fmt = fmt;
1225
1226 return wm8753_hifi_write_dai_fmt(codec, fmt);
1227};
1228
1229static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
1230 unsigned int fmt)
1231{
1232 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1233 int ret = 0;
1234
1235 if (wm8753->dai_func != 0)
1236 return 0;
1237
1238 ret = wm8753_mode1v_set_dai_fmt(codec, fmt);
1239 if (ret)
1240 return ret;
1241 ret = wm8753_pcm_set_dai_fmt(codec, fmt);
1242 if (ret)
1243 return ret;
1244
1245 return 0;
1246};
1247
1248static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1249 unsigned int fmt)
1250{
1251 struct snd_soc_codec *codec = codec_dai->codec;
1252 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1253
1254 wm8753->voice_fmt = fmt;
1255
1256 return wm8753_voice_write_dai_fmt(codec, fmt);
1257};
1258
1239static int wm8753_mute(struct snd_soc_dai *dai, int mute) 1259static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1240{ 1260{
1241 struct snd_soc_codec *codec = dai->codec; 1261 struct snd_soc_codec *codec = dai->codec;
1242 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; 1262 u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
1263 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1243 1264
1244 /* the digital mute covers the HiFi and Voice DAC's on the WM8753. 1265 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1245 * make sure we check if they are not both active when we mute */ 1266 * make sure we check if they are not both active when we mute */
1246 if (mute && dai->id == 1) { 1267 if (mute && wm8753->dai_func == 1) {
1247 if (!wm8753_dai[WM8753_DAI_VOICE].playback.active || 1268 if (!codec->active)
1248 !wm8753_dai[WM8753_DAI_HIFI].playback.active) 1269 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1249 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
1250 } else { 1270 } else {
1251 if (mute) 1271 if (mute)
1252 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); 1272 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1253 else 1273 else
1254 wm8753_write(codec, WM8753_DAC, mute_reg); 1274 snd_soc_write(codec, WM8753_DAC, mute_reg);
1255 } 1275 }
1256 1276
1257 return 0; 1277 return 0;
@@ -1260,26 +1280,26 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1260static int wm8753_set_bias_level(struct snd_soc_codec *codec, 1280static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1261 enum snd_soc_bias_level level) 1281 enum snd_soc_bias_level level)
1262{ 1282{
1263 u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; 1283 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
1264 1284
1265 switch (level) { 1285 switch (level) {
1266 case SND_SOC_BIAS_ON: 1286 case SND_SOC_BIAS_ON:
1267 /* set vmid to 50k and unmute dac */ 1287 /* set vmid to 50k and unmute dac */
1268 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); 1288 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1269 break; 1289 break;
1270 case SND_SOC_BIAS_PREPARE: 1290 case SND_SOC_BIAS_PREPARE:
1271 /* set vmid to 5k for quick power up */ 1291 /* set vmid to 5k for quick power up */
1272 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); 1292 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1273 break; 1293 break;
1274 case SND_SOC_BIAS_STANDBY: 1294 case SND_SOC_BIAS_STANDBY:
1275 /* mute dac and set vmid to 500k, enable VREF */ 1295 /* mute dac and set vmid to 500k, enable VREF */
1276 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); 1296 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1277 break; 1297 break;
1278 case SND_SOC_BIAS_OFF: 1298 case SND_SOC_BIAS_OFF:
1279 wm8753_write(codec, WM8753_PWR1, 0x0001); 1299 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1280 break; 1300 break;
1281 } 1301 }
1282 codec->bias_level = level; 1302 codec->dapm.bias_level = level;
1283 return 0; 1303 return 0;
1284} 1304}
1285 1305
@@ -1292,7 +1312,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1292 SNDRV_PCM_FMTBIT_S24_LE) 1312 SNDRV_PCM_FMTBIT_S24_LE)
1293 1313
1294/* 1314/*
1295 * The WM8753 supports upto 4 different and mutually exclusive DAI 1315 * The WM8753 supports up to 4 different and mutually exclusive DAI
1296 * configurations. This gives 2 PCM's available for use, hifi and voice. 1316 * configurations. This gives 2 PCM's available for use, hifi and voice.
1297 * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI 1317 * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI
1298 * is connected between the wm8753 and a BT codec or GSM modem. 1318 * is connected between the wm8753 and a BT codec or GSM modem.
@@ -1302,452 +1322,237 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1302 * 3. Voice disabled - HIFI over HIFI 1322 * 3. Voice disabled - HIFI over HIFI
1303 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture 1323 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1304 */ 1324 */
1305static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = { 1325static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
1306 .hw_params = wm8753_i2s_hw_params, 1326 .hw_params = wm8753_i2s_hw_params,
1307 .digital_mute = wm8753_mute, 1327 .digital_mute = wm8753_mute,
1308 .set_fmt = wm8753_mode1h_set_dai_fmt, 1328 .set_fmt = wm8753_hifi_set_dai_fmt,
1309 .set_clkdiv = wm8753_set_dai_clkdiv,
1310 .set_pll = wm8753_set_dai_pll,
1311 .set_sysclk = wm8753_set_dai_sysclk,
1312};
1313
1314static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
1315 .hw_params = wm8753_pcm_hw_params,
1316 .digital_mute = wm8753_mute,
1317 .set_fmt = wm8753_mode1v_set_dai_fmt,
1318 .set_clkdiv = wm8753_set_dai_clkdiv, 1329 .set_clkdiv = wm8753_set_dai_clkdiv,
1319 .set_pll = wm8753_set_dai_pll, 1330 .set_pll = wm8753_set_dai_pll,
1320 .set_sysclk = wm8753_set_dai_sysclk, 1331 .set_sysclk = wm8753_set_dai_sysclk,
1321}; 1332};
1322 1333
1323static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = { 1334static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
1324 .hw_params = wm8753_pcm_hw_params, 1335 .hw_params = wm8753_pcm_hw_params,
1325 .digital_mute = wm8753_mute, 1336 .digital_mute = wm8753_mute,
1326 .set_fmt = wm8753_mode2_set_dai_fmt, 1337 .set_fmt = wm8753_voice_set_dai_fmt,
1327 .set_clkdiv = wm8753_set_dai_clkdiv, 1338 .set_clkdiv = wm8753_set_dai_clkdiv,
1328 .set_pll = wm8753_set_dai_pll, 1339 .set_pll = wm8753_set_dai_pll,
1329 .set_sysclk = wm8753_set_dai_sysclk, 1340 .set_sysclk = wm8753_set_dai_sysclk,
1330}; 1341};
1331 1342
1332static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = { 1343static struct snd_soc_dai_driver wm8753_dai[] = {
1333 .hw_params = wm8753_i2s_hw_params,
1334 .digital_mute = wm8753_mute,
1335 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1336 .set_clkdiv = wm8753_set_dai_clkdiv,
1337 .set_pll = wm8753_set_dai_pll,
1338 .set_sysclk = wm8753_set_dai_sysclk,
1339};
1340
1341static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
1342 .hw_params = wm8753_i2s_hw_params,
1343 .digital_mute = wm8753_mute,
1344 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1345 .set_clkdiv = wm8753_set_dai_clkdiv,
1346 .set_pll = wm8753_set_dai_pll,
1347 .set_sysclk = wm8753_set_dai_sysclk,
1348};
1349
1350static const struct snd_soc_dai wm8753_all_dai[] = {
1351/* DAI HiFi mode 1 */ 1344/* DAI HiFi mode 1 */
1352{ .name = "WM8753 HiFi", 1345{ .name = "wm8753-hifi",
1353 .id = 1,
1354 .playback = { 1346 .playback = {
1355 .stream_name = "HiFi Playback", 1347 .stream_name = "HiFi Playback",
1356 .channels_min = 1, 1348 .channels_min = 1,
1357 .channels_max = 2, 1349 .channels_max = 2,
1358 .rates = WM8753_RATES, 1350 .rates = WM8753_RATES,
1359 .formats = WM8753_FORMATS}, 1351 .formats = WM8753_FORMATS
1352 },
1360 .capture = { /* dummy for fast DAI switching */ 1353 .capture = { /* dummy for fast DAI switching */
1361 .stream_name = "Capture", 1354 .stream_name = "Capture",
1362 .channels_min = 1, 1355 .channels_min = 1,
1363 .channels_max = 2, 1356 .channels_max = 2,
1364 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1365 .formats = WM8753_FORMATS}, 1358 .formats = WM8753_FORMATS
1366 .ops = &wm8753_dai_ops_hifi_mode1, 1359 },
1360 .ops = &wm8753_dai_ops_hifi_mode,
1367}, 1361},
1368/* DAI Voice mode 1 */ 1362/* DAI Voice mode 1 */
1369{ .name = "WM8753 Voice", 1363{ .name = "wm8753-voice",
1370 .id = 1,
1371 .playback = { 1364 .playback = {
1372 .stream_name = "Voice Playback", 1365 .stream_name = "Voice Playback",
1373 .channels_min = 1, 1366 .channels_min = 1,
1374 .channels_max = 1, 1367 .channels_max = 1,
1375 .rates = WM8753_RATES, 1368 .rates = WM8753_RATES,
1376 .formats = WM8753_FORMATS,}, 1369 .formats = WM8753_FORMATS,
1377 .capture = { 1370 },
1378 .stream_name = "Capture",
1379 .channels_min = 1,
1380 .channels_max = 2,
1381 .rates = WM8753_RATES,
1382 .formats = WM8753_FORMATS,},
1383 .ops = &wm8753_dai_ops_voice_mode1,
1384},
1385/* DAI HiFi mode 2 - dummy */
1386{ .name = "WM8753 HiFi",
1387 .id = 2,
1388},
1389/* DAI Voice mode 2 */
1390{ .name = "WM8753 Voice",
1391 .id = 2,
1392 .playback = {
1393 .stream_name = "Voice Playback",
1394 .channels_min = 1,
1395 .channels_max = 1,
1396 .rates = WM8753_RATES,
1397 .formats = WM8753_FORMATS,},
1398 .capture = {
1399 .stream_name = "Capture",
1400 .channels_min = 1,
1401 .channels_max = 2,
1402 .rates = WM8753_RATES,
1403 .formats = WM8753_FORMATS,},
1404 .ops = &wm8753_dai_ops_voice_mode2,
1405},
1406/* DAI HiFi mode 3 */
1407{ .name = "WM8753 HiFi",
1408 .id = 3,
1409 .playback = {
1410 .stream_name = "HiFi Playback",
1411 .channels_min = 1,
1412 .channels_max = 2,
1413 .rates = WM8753_RATES,
1414 .formats = WM8753_FORMATS,},
1415 .capture = {
1416 .stream_name = "Capture",
1417 .channels_min = 1,
1418 .channels_max = 2,
1419 .rates = WM8753_RATES,
1420 .formats = WM8753_FORMATS,},
1421 .ops = &wm8753_dai_ops_hifi_mode3,
1422},
1423/* DAI Voice mode 3 - dummy */
1424{ .name = "WM8753 Voice",
1425 .id = 3,
1426},
1427/* DAI HiFi mode 4 */
1428{ .name = "WM8753 HiFi",
1429 .id = 4,
1430 .playback = {
1431 .stream_name = "HiFi Playback",
1432 .channels_min = 1,
1433 .channels_max = 2,
1434 .rates = WM8753_RATES,
1435 .formats = WM8753_FORMATS,},
1436 .capture = { 1371 .capture = {
1437 .stream_name = "Capture", 1372 .stream_name = "Capture",
1438 .channels_min = 1, 1373 .channels_min = 1,
1439 .channels_max = 2, 1374 .channels_max = 2,
1440 .rates = WM8753_RATES, 1375 .rates = WM8753_RATES,
1441 .formats = WM8753_FORMATS,}, 1376 .formats = WM8753_FORMATS,
1442 .ops = &wm8753_dai_ops_hifi_mode4,
1443},
1444/* DAI Voice mode 4 - dummy */
1445{ .name = "WM8753 Voice",
1446 .id = 4,
1447},
1448};
1449
1450struct snd_soc_dai wm8753_dai[] = {
1451 {
1452 .name = "WM8753 DAI 0",
1453 },
1454 {
1455 .name = "WM8753 DAI 1",
1456 }, 1377 },
1378 .ops = &wm8753_dai_ops_voice_mode,
1379},
1457}; 1380};
1458EXPORT_SYMBOL_GPL(wm8753_dai);
1459
1460static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode)
1461{
1462 if (mode < 4) {
1463 int playback_active, capture_active, codec_active, pop_wait;
1464 void *private_data;
1465 struct list_head list;
1466
1467 playback_active = wm8753_dai[0].playback.active;
1468 capture_active = wm8753_dai[0].capture.active;
1469 codec_active = wm8753_dai[0].active;
1470 private_data = wm8753_dai[0].private_data;
1471 pop_wait = wm8753_dai[0].pop_wait;
1472 list = wm8753_dai[0].list;
1473 wm8753_dai[0] = wm8753_all_dai[mode << 1];
1474 wm8753_dai[0].playback.active = playback_active;
1475 wm8753_dai[0].capture.active = capture_active;
1476 wm8753_dai[0].active = codec_active;
1477 wm8753_dai[0].private_data = private_data;
1478 wm8753_dai[0].pop_wait = pop_wait;
1479 wm8753_dai[0].list = list;
1480
1481 playback_active = wm8753_dai[1].playback.active;
1482 capture_active = wm8753_dai[1].capture.active;
1483 codec_active = wm8753_dai[1].active;
1484 private_data = wm8753_dai[1].private_data;
1485 pop_wait = wm8753_dai[1].pop_wait;
1486 list = wm8753_dai[1].list;
1487 wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
1488 wm8753_dai[1].playback.active = playback_active;
1489 wm8753_dai[1].capture.active = capture_active;
1490 wm8753_dai[1].active = codec_active;
1491 wm8753_dai[1].private_data = private_data;
1492 wm8753_dai[1].pop_wait = pop_wait;
1493 wm8753_dai[1].list = list;
1494 }
1495 wm8753_dai[0].codec = codec;
1496 wm8753_dai[1].codec = codec;
1497}
1498 1381
1499static void wm8753_work(struct work_struct *work) 1382static void wm8753_work(struct work_struct *work)
1500{ 1383{
1501 struct snd_soc_codec *codec = 1384 struct snd_soc_dapm_context *dapm =
1502 container_of(work, struct snd_soc_codec, delayed_work.work); 1385 container_of(work, struct snd_soc_dapm_context,
1503 wm8753_set_bias_level(codec, codec->bias_level); 1386 delayed_work.work);
1387 struct snd_soc_codec *codec = dapm->codec;
1388 wm8753_set_bias_level(codec, dapm->bias_level);
1504} 1389}
1505 1390
1506static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) 1391static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
1507{ 1392{
1508 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1509 struct snd_soc_codec *codec = socdev->card->codec;
1510
1511 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1393 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1512 return 0; 1394 return 0;
1513} 1395}
1514 1396
1515static int wm8753_resume(struct platform_device *pdev) 1397static int wm8753_resume(struct snd_soc_codec *codec)
1516{ 1398{
1517 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1399 u16 *reg_cache = codec->reg_cache;
1518 struct snd_soc_codec *codec = socdev->card->codec;
1519 int i; 1400 int i;
1520 u8 data[2];
1521 u16 *cache = codec->reg_cache;
1522 1401
1523 /* Sync reg_cache with the hardware */ 1402 /* Sync reg_cache with the hardware */
1524 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1403 for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
1525 if (i + 1 == WM8753_RESET) 1404 if (i == WM8753_RESET)
1526 continue; 1405 continue;
1527 1406
1528 /* No point in writing hardware default values back */ 1407 /* No point in writing hardware default values back */
1529 if (cache[i] == wm8753_reg[i]) 1408 if (reg_cache[i] == wm8753_reg[i])
1530 continue; 1409 continue;
1531 1410
1532 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); 1411 snd_soc_write(codec, i, reg_cache[i]);
1533 data[1] = cache[i] & 0x00ff;
1534 codec->hw_write(codec->control_data, data, 2);
1535 } 1412 }
1536 1413
1537 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1414 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1538 1415
1539 /* charge wm8753 caps */ 1416 /* charge wm8753 caps */
1540 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 1417 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
1541 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1418 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1542 codec->bias_level = SND_SOC_BIAS_ON; 1419 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1543 schedule_delayed_work(&codec->delayed_work, 1420 schedule_delayed_work(&codec->dapm.delayed_work,
1544 msecs_to_jiffies(caps_charge)); 1421 msecs_to_jiffies(caps_charge));
1545 } 1422 }
1546 1423
1547 return 0; 1424 return 0;
1548} 1425}
1549 1426
1550static struct snd_soc_codec *wm8753_codec; 1427static int wm8753_probe(struct snd_soc_codec *codec)
1551
1552static int wm8753_probe(struct platform_device *pdev)
1553{ 1428{
1554 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1429 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1555 struct snd_soc_codec *codec; 1430 int ret;
1556 int ret = 0;
1557
1558 if (!wm8753_codec) {
1559 dev_err(&pdev->dev, "WM8753 codec not yet registered\n");
1560 return -EINVAL;
1561 }
1562 1431
1563 socdev->card->codec = wm8753_codec; 1432 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
1564 codec = wm8753_codec;
1565 1433
1566 wm8753_set_dai_mode(codec, 0); 1434 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
1435 if (ret < 0) {
1436 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1437 return ret;
1438 }
1567 1439
1568 /* register pcms */ 1440 ret = wm8753_reset(codec);
1569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1570 if (ret < 0) { 1441 if (ret < 0) {
1571 printk(KERN_ERR "wm8753: failed to create pcms\n"); 1442 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1572 goto pcm_err; 1443 return ret;
1573 } 1444 }
1574 1445
1446 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1447 wm8753->dai_func = 0;
1448
1449 /* charge output caps */
1450 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1451 schedule_delayed_work(&codec->dapm.delayed_work,
1452 msecs_to_jiffies(caps_charge));
1453
1454 /* set the update bits */
1455 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1456 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1457 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1458 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1459 snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
1460 snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
1461 snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
1462 snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
1463 snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
1464 snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
1465
1575 snd_soc_add_controls(codec, wm8753_snd_controls, 1466 snd_soc_add_controls(codec, wm8753_snd_controls,
1576 ARRAY_SIZE(wm8753_snd_controls)); 1467 ARRAY_SIZE(wm8753_snd_controls));
1577 wm8753_add_widgets(codec); 1468 wm8753_add_widgets(codec);
1578 1469
1579 return 0; 1470 return 0;
1580
1581pcm_err:
1582 return ret;
1583}
1584
1585/*
1586 * This function forces any delayed work to be queued and run.
1587 */
1588static int run_delayed_work(struct delayed_work *dwork)
1589{
1590 int ret;
1591
1592 /* cancel any work waiting to be queued. */
1593 ret = cancel_delayed_work(dwork);
1594
1595 /* if there was any work waiting then we run it now and
1596 * wait for it's completion */
1597 if (ret) {
1598 schedule_delayed_work(dwork, 0);
1599 flush_scheduled_work();
1600 }
1601 return ret;
1602} 1471}
1603 1472
1604/* power down chip */ 1473/* power down chip */
1605static int wm8753_remove(struct platform_device *pdev) 1474static int wm8753_remove(struct snd_soc_codec *codec)
1606{ 1475{
1607 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1476 flush_delayed_work_sync(&codec->dapm.delayed_work);
1608 1477 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1609 snd_soc_free_pcms(socdev);
1610 snd_soc_dapm_free(socdev);
1611 1478
1612 return 0; 1479 return 0;
1613} 1480}
1614 1481
1615struct snd_soc_codec_device soc_codec_dev_wm8753 = { 1482static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1616 .probe = wm8753_probe, 1483 .probe = wm8753_probe,
1617 .remove = wm8753_remove, 1484 .remove = wm8753_remove,
1618 .suspend = wm8753_suspend, 1485 .suspend = wm8753_suspend,
1619 .resume = wm8753_resume, 1486 .resume = wm8753_resume,
1487 .set_bias_level = wm8753_set_bias_level,
1488 .reg_cache_size = ARRAY_SIZE(wm8753_reg),
1489 .reg_word_size = sizeof(u16),
1490 .reg_cache_default = wm8753_reg,
1620}; 1491};
1621EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1622 1492
1623static int wm8753_register(struct wm8753_priv *wm8753) 1493#if defined(CONFIG_SPI_MASTER)
1494static int __devinit wm8753_spi_probe(struct spi_device *spi)
1624{ 1495{
1625 int ret, i; 1496 struct wm8753_priv *wm8753;
1626 struct snd_soc_codec *codec = &wm8753->codec; 1497 int ret;
1627 u16 reg;
1628
1629 if (wm8753_codec) {
1630 dev_err(codec->dev, "Multiple WM8753 devices not supported\n");
1631 ret = -EINVAL;
1632 goto err;
1633 }
1634
1635 mutex_init(&codec->mutex);
1636 INIT_LIST_HEAD(&codec->dapm_widgets);
1637 INIT_LIST_HEAD(&codec->dapm_paths);
1638
1639 codec->name = "WM8753";
1640 codec->owner = THIS_MODULE;
1641 codec->read = wm8753_read_reg_cache;
1642 codec->write = wm8753_write;
1643 codec->bias_level = SND_SOC_BIAS_STANDBY;
1644 codec->set_bias_level = wm8753_set_bias_level;
1645 codec->dai = wm8753_dai;
1646 codec->num_dai = 2;
1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
1648 codec->reg_cache = &wm8753->reg_cache;
1649 snd_soc_codec_set_drvdata(codec, wm8753);
1650
1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1653
1654 ret = wm8753_reset(codec);
1655 if (ret < 0) {
1656 dev_err(codec->dev, "Failed to issue reset\n");
1657 goto err;
1658 }
1659
1660 /* charge output caps */
1661 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1662 schedule_delayed_work(&codec->delayed_work,
1663 msecs_to_jiffies(caps_charge));
1664
1665 /* set the update bits */
1666 reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
1667 wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
1668 reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
1669 wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
1670 reg = wm8753_read_reg_cache(codec, WM8753_LADC);
1671 wm8753_write(codec, WM8753_LADC, reg | 0x0100);
1672 reg = wm8753_read_reg_cache(codec, WM8753_RADC);
1673 wm8753_write(codec, WM8753_RADC, reg | 0x0100);
1674 reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
1675 wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
1676 reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
1677 wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
1678 reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
1679 wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
1680 reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
1681 wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
1682 reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
1683 wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
1684 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
1685 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
1686
1687 wm8753_codec = codec;
1688
1689 for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++)
1690 wm8753_dai[i].dev = codec->dev;
1691
1692 ret = snd_soc_register_codec(codec);
1693 if (ret != 0) {
1694 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1695 goto err;
1696 }
1697 1498
1698 ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); 1499 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1699 if (ret != 0) { 1500 if (wm8753 == NULL)
1700 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); 1501 return -ENOMEM;
1701 goto err_codec;
1702 }
1703 1502
1704 return 0; 1503 wm8753->control_type = SND_SOC_SPI;
1504 spi_set_drvdata(spi, wm8753);
1705 1505
1706err_codec: 1506 ret = snd_soc_register_codec(&spi->dev,
1707 run_delayed_work(&codec->delayed_work); 1507 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1708 snd_soc_unregister_codec(codec); 1508 if (ret < 0)
1709err: 1509 kfree(wm8753);
1710 kfree(wm8753);
1711 return ret; 1510 return ret;
1712} 1511}
1713 1512
1714static void wm8753_unregister(struct wm8753_priv *wm8753) 1513static int __devexit wm8753_spi_remove(struct spi_device *spi)
1715{ 1514{
1716 wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF); 1515 snd_soc_unregister_codec(&spi->dev);
1717 run_delayed_work(&wm8753->codec.delayed_work); 1516 kfree(spi_get_drvdata(spi));
1718 snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai)); 1517 return 0;
1719 snd_soc_unregister_codec(&wm8753->codec);
1720 kfree(wm8753);
1721 wm8753_codec = NULL;
1722} 1518}
1723 1519
1724#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1520static struct spi_driver wm8753_spi_driver = {
1521 .driver = {
1522 .name = "wm8753-codec",
1523 .owner = THIS_MODULE,
1524 },
1525 .probe = wm8753_spi_probe,
1526 .remove = __devexit_p(wm8753_spi_remove),
1527};
1528#endif /* CONFIG_SPI_MASTER */
1725 1529
1726static int wm8753_i2c_probe(struct i2c_client *i2c, 1530#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1727 const struct i2c_device_id *id) 1531static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1532 const struct i2c_device_id *id)
1728{ 1533{
1729 struct snd_soc_codec *codec;
1730 struct wm8753_priv *wm8753; 1534 struct wm8753_priv *wm8753;
1535 int ret;
1731 1536
1732 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); 1537 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1733 if (wm8753 == NULL) 1538 if (wm8753 == NULL)
1734 return -ENOMEM; 1539 return -ENOMEM;
1735 1540
1736 codec = &wm8753->codec; 1541 i2c_set_clientdata(i2c, wm8753);
1737 codec->hw_write = (hw_write_t)i2c_master_send; 1542 wm8753->control_type = SND_SOC_I2C;
1738 codec->control_data = i2c;
1739 i2c_set_clientdata(i2c, wm8753);
1740
1741 codec->dev = &i2c->dev;
1742 1543
1743 return wm8753_register(wm8753); 1544 ret = snd_soc_register_codec(&i2c->dev,
1545 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1546 if (ret < 0)
1547 kfree(wm8753);
1548 return ret;
1744} 1549}
1745 1550
1746static int wm8753_i2c_remove(struct i2c_client *client) 1551static __devexit int wm8753_i2c_remove(struct i2c_client *client)
1747{ 1552{
1748 struct wm8753_priv *wm8753 = i2c_get_clientdata(client); 1553 snd_soc_unregister_codec(&client->dev);
1749 wm8753_unregister(wm8753); 1554 kfree(i2c_get_clientdata(client));
1750 return 0; 1555 return 0;
1751} 1556}
1752 1557
1753static const struct i2c_device_id wm8753_i2c_id[] = { 1558static const struct i2c_device_id wm8753_i2c_id[] = {
@@ -1758,91 +1563,33 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1758 1563
1759static struct i2c_driver wm8753_i2c_driver = { 1564static struct i2c_driver wm8753_i2c_driver = {
1760 .driver = { 1565 .driver = {
1761 .name = "wm8753", 1566 .name = "wm8753-codec",
1762 .owner = THIS_MODULE, 1567 .owner = THIS_MODULE,
1763 }, 1568 },
1764 .probe = wm8753_i2c_probe, 1569 .probe = wm8753_i2c_probe,
1765 .remove = wm8753_i2c_remove, 1570 .remove = __devexit_p(wm8753_i2c_remove),
1766 .id_table = wm8753_i2c_id, 1571 .id_table = wm8753_i2c_id,
1767}; 1572};
1768#endif 1573#endif
1769 1574
1770#if defined(CONFIG_SPI_MASTER)
1771static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1772{
1773 struct spi_transfer t;
1774 struct spi_message m;
1775 u8 msg[2];
1776
1777 if (len <= 0)
1778 return 0;
1779
1780 msg[0] = data[0];
1781 msg[1] = data[1];
1782
1783 spi_message_init(&m);
1784 memset(&t, 0, (sizeof t));
1785
1786 t.tx_buf = &msg[0];
1787 t.len = len;
1788
1789 spi_message_add_tail(&t, &m);
1790 spi_sync(spi, &m);
1791
1792 return len;
1793}
1794
1795static int __devinit wm8753_spi_probe(struct spi_device *spi)
1796{
1797 struct snd_soc_codec *codec;
1798 struct wm8753_priv *wm8753;
1799
1800 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1801 if (wm8753 == NULL)
1802 return -ENOMEM;
1803
1804 codec = &wm8753->codec;
1805 codec->control_data = spi;
1806 codec->hw_write = (hw_write_t)wm8753_spi_write;
1807 codec->dev = &spi->dev;
1808
1809 dev_set_drvdata(&spi->dev, wm8753);
1810
1811 return wm8753_register(wm8753);
1812}
1813
1814static int __devexit wm8753_spi_remove(struct spi_device *spi)
1815{
1816 struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev);
1817 wm8753_unregister(wm8753);
1818 return 0;
1819}
1820
1821static struct spi_driver wm8753_spi_driver = {
1822 .driver = {
1823 .name = "wm8753",
1824 .bus = &spi_bus_type,
1825 .owner = THIS_MODULE,
1826 },
1827 .probe = wm8753_spi_probe,
1828 .remove = __devexit_p(wm8753_spi_remove),
1829};
1830#endif
1831
1832static int __init wm8753_modinit(void) 1575static int __init wm8753_modinit(void)
1833{ 1576{
1834 int ret; 1577 int ret = 0;
1835#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1578#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1836 ret = i2c_add_driver(&wm8753_i2c_driver); 1579 ret = i2c_add_driver(&wm8753_i2c_driver);
1837 if (ret != 0) 1580 if (ret != 0) {
1838 pr_err("Failed to register WM8753 I2C driver: %d\n", ret); 1581 printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
1582 ret);
1583 }
1839#endif 1584#endif
1840#if defined(CONFIG_SPI_MASTER) 1585#if defined(CONFIG_SPI_MASTER)
1841 ret = spi_register_driver(&wm8753_spi_driver); 1586 ret = spi_register_driver(&wm8753_spi_driver);
1842 if (ret != 0) 1587 if (ret != 0) {
1843 pr_err("Failed to register WM8753 SPI driver: %d\n", ret); 1588 printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
1589 ret);
1590 }
1844#endif 1591#endif
1845 return 0; 1592 return ret;
1846} 1593}
1847module_init(wm8753_modinit); 1594module_init(wm8753_modinit);
1848 1595
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 57b2ba244040..94edac144bcb 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -115,7 +115,4 @@
115#define WM8753_DAI_HIFI 0 115#define WM8753_DAI_HIFI 0
116#define WM8753_DAI_VOICE 1 116#define WM8753_DAI_VOICE 1
117 117
118extern struct snd_soc_dai wm8753_dai[2];
119extern struct snd_soc_codec_device soc_codec_dev_wm8753;
120
121#endif 118#endif
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
new file mode 100644
index 000000000000..19b92baa9e8c
--- /dev/null
+++ b/sound/soc/codecs/wm8770.c
@@ -0,0 +1,749 @@
1/*
2 * wm8770.c -- WM8770 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/platform_device.h>
19#include <linux/spi/spi.h>
20#include <linux/regulator/consumer.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8770.h"
30
31#define WM8770_NUM_SUPPLIES 3
32static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = {
33 "AVDD1",
34 "AVDD2",
35 "DVDD"
36};
37
38static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = {
39 0x7f, 0x7f, 0x7f, 0x7f,
40 0x7f, 0x7f, 0x7f, 0x7f,
41 0x7f, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0, 0x90, 0,
44 0, 0x22, 0x22, 0x3e,
45 0xc, 0xc, 0x100, 0x189,
46 0x189, 0x8770
47};
48
49struct wm8770_priv {
50 enum snd_soc_control_type control_type;
51 struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
52 struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
53 struct snd_soc_codec *codec;
54 int sysclk;
55};
56
57static int vout12supply_event(struct snd_soc_dapm_widget *w,
58 struct snd_kcontrol *kcontrol, int event);
59static int vout34supply_event(struct snd_soc_dapm_widget *w,
60 struct snd_kcontrol *kcontrol, int event);
61
62/*
63 * We can't use the same notifier block for more than one supply and
64 * there's no way I can see to get from a callback to the caller
65 * except container_of().
66 */
67#define WM8770_REGULATOR_EVENT(n) \
68static int wm8770_regulator_event_##n(struct notifier_block *nb, \
69 unsigned long event, void *data) \
70{ \
71 struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
72 disable_nb[n]); \
73 if (event & REGULATOR_EVENT_DISABLE) { \
74 wm8770->codec->cache_sync = 1; \
75 } \
76 return 0; \
77}
78
79WM8770_REGULATOR_EVENT(0)
80WM8770_REGULATOR_EVENT(1)
81WM8770_REGULATOR_EVENT(2)
82
83static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
84static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1);
85static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1);
86
87static const char *dac_phase_text[][2] = {
88 { "DAC1 Normal", "DAC1 Inverted" },
89 { "DAC2 Normal", "DAC2 Inverted" },
90 { "DAC3 Normal", "DAC3 Inverted" },
91 { "DAC4 Normal", "DAC4 Inverted" },
92};
93
94static const struct soc_enum dac_phase[] = {
95 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]),
96 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]),
97 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]),
98 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]),
99};
100
101static const struct snd_kcontrol_new wm8770_snd_controls[] = {
102 /* global DAC playback controls */
103 SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0,
104 dac_dig_tlv),
105 SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1),
106 SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0),
107
108 /* global VOUT playback controls */
109 SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0,
110 dac_alg_tlv),
111 SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0),
112
113 /* VOUT1/2/3/4 specific controls */
114 SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL,
115 WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv),
116 SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL,
117 WM8770_VOUT1RVOL, 7, 1, 0),
118 SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL,
119 WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv),
120 SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL,
121 WM8770_VOUT2RVOL, 7, 1, 0),
122 SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL,
123 WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv),
124 SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL,
125 WM8770_VOUT3RVOL, 7, 1, 0),
126 SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL,
127 WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv),
128 SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL,
129 WM8770_VOUT4RVOL, 7, 1, 0),
130
131 /* DAC1/2/3/4 specific controls */
132 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL,
133 WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv),
134 SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0),
135 SOC_ENUM("DAC1 Phase", dac_phase[0]),
136 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL,
137 WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv),
138 SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0),
139 SOC_ENUM("DAC2 Phase", dac_phase[1]),
140 SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL,
141 WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv),
142 SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0),
143 SOC_ENUM("DAC3 Phase", dac_phase[2]),
144 SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL,
145 WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv),
146 SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0),
147 SOC_ENUM("DAC4 Phase", dac_phase[3]),
148
149 /* ADC specific controls */
150 SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
151 0, 31, 0, adc_tlv),
152 SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
153 5, 1, 1),
154
155 /* other controls */
156 SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0),
157 SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1)
158};
159
160static const char *ain_text[] = {
161 "AIN1", "AIN2", "AIN3", "AIN4",
162 "AIN5", "AIN6", "AIN7", "AIN8"
163};
164
165static const struct soc_enum ain_enum =
166 SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text);
167
168static const struct snd_kcontrol_new ain_mux =
169 SOC_DAPM_ENUM("Capture Mux", ain_enum);
170
171static const struct snd_kcontrol_new vout1_mix_controls[] = {
172 SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0),
173 SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0),
174 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0)
175};
176
177static const struct snd_kcontrol_new vout2_mix_controls[] = {
178 SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0),
179 SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0),
180 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0)
181};
182
183static const struct snd_kcontrol_new vout3_mix_controls[] = {
184 SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0),
185 SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0),
186 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0)
187};
188
189static const struct snd_kcontrol_new vout4_mix_controls[] = {
190 SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0),
191 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0)
192};
193
194static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = {
195 SND_SOC_DAPM_INPUT("AUX1"),
196 SND_SOC_DAPM_INPUT("AUX2"),
197 SND_SOC_DAPM_INPUT("AUX3"),
198
199 SND_SOC_DAPM_INPUT("AIN1"),
200 SND_SOC_DAPM_INPUT("AIN2"),
201 SND_SOC_DAPM_INPUT("AIN3"),
202 SND_SOC_DAPM_INPUT("AIN4"),
203 SND_SOC_DAPM_INPUT("AIN5"),
204 SND_SOC_DAPM_INPUT("AIN6"),
205 SND_SOC_DAPM_INPUT("AIN7"),
206 SND_SOC_DAPM_INPUT("AIN8"),
207
208 SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux),
209
210 SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1),
211
212 SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1),
213 SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1),
214 SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1),
215 SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1),
216
217 SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0,
218 vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
219 SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0,
220 vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
221
222 SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0,
223 vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)),
224 SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0,
225 vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)),
226 SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0,
227 vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)),
228 SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0,
229 vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)),
230
231 SND_SOC_DAPM_OUTPUT("VOUT1"),
232 SND_SOC_DAPM_OUTPUT("VOUT2"),
233 SND_SOC_DAPM_OUTPUT("VOUT3"),
234 SND_SOC_DAPM_OUTPUT("VOUT4")
235};
236
237static const struct snd_soc_dapm_route wm8770_intercon[] = {
238 { "Capture Mux", "AIN1", "AIN1" },
239 { "Capture Mux", "AIN2", "AIN2" },
240 { "Capture Mux", "AIN3", "AIN3" },
241 { "Capture Mux", "AIN4", "AIN4" },
242 { "Capture Mux", "AIN5", "AIN5" },
243 { "Capture Mux", "AIN6", "AIN6" },
244 { "Capture Mux", "AIN7", "AIN7" },
245 { "Capture Mux", "AIN8", "AIN8" },
246
247 { "ADC", NULL, "Capture Mux" },
248
249 { "VOUT1 Mixer", NULL, "VOUT12 Supply" },
250 { "VOUT1 Mixer", "DAC1 Switch", "DAC1" },
251 { "VOUT1 Mixer", "AUX1 Switch", "AUX1" },
252 { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" },
253
254 { "VOUT2 Mixer", NULL, "VOUT12 Supply" },
255 { "VOUT2 Mixer", "DAC2 Switch", "DAC2" },
256 { "VOUT2 Mixer", "AUX2 Switch", "AUX2" },
257 { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" },
258
259 { "VOUT3 Mixer", NULL, "VOUT34 Supply" },
260 { "VOUT3 Mixer", "DAC3 Switch", "DAC3" },
261 { "VOUT3 Mixer", "AUX3 Switch", "AUX3" },
262 { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" },
263
264 { "VOUT4 Mixer", NULL, "VOUT34 Supply" },
265 { "VOUT4 Mixer", "DAC4 Switch", "DAC4" },
266 { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" },
267
268 { "VOUT1", NULL, "VOUT1 Mixer" },
269 { "VOUT2", NULL, "VOUT2 Mixer" },
270 { "VOUT3", NULL, "VOUT3 Mixer" },
271 { "VOUT4", NULL, "VOUT4 Mixer" }
272};
273
274static int vout12supply_event(struct snd_soc_dapm_widget *w,
275 struct snd_kcontrol *kcontrol, int event)
276{
277 struct snd_soc_codec *codec;
278
279 codec = w->codec;
280
281 switch (event) {
282 case SND_SOC_DAPM_PRE_PMU:
283 snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
284 break;
285 case SND_SOC_DAPM_POST_PMD:
286 snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
287 break;
288 }
289
290 return 0;
291}
292
293static int vout34supply_event(struct snd_soc_dapm_widget *w,
294 struct snd_kcontrol *kcontrol, int event)
295{
296 struct snd_soc_codec *codec;
297
298 codec = w->codec;
299
300 switch (event) {
301 case SND_SOC_DAPM_PRE_PMU:
302 snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
303 break;
304 case SND_SOC_DAPM_POST_PMD:
305 snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
306 break;
307 }
308
309 return 0;
310}
311
312static int wm8770_reset(struct snd_soc_codec *codec)
313{
314 return snd_soc_write(codec, WM8770_RESET, 0);
315}
316
317static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
318{
319 struct snd_soc_codec *codec;
320 int iface, master;
321
322 codec = dai->codec;
323
324 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
325 case SND_SOC_DAIFMT_CBM_CFM:
326 master = 0x100;
327 break;
328 case SND_SOC_DAIFMT_CBS_CFS:
329 master = 0;
330 break;
331 default:
332 return -EINVAL;
333 }
334
335 iface = 0;
336 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
337 case SND_SOC_DAIFMT_I2S:
338 iface |= 0x2;
339 break;
340 case SND_SOC_DAIFMT_RIGHT_J:
341 break;
342 case SND_SOC_DAIFMT_LEFT_J:
343 iface |= 0x1;
344 break;
345 default:
346 return -EINVAL;
347 }
348
349 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
350 case SND_SOC_DAIFMT_NB_NF:
351 break;
352 case SND_SOC_DAIFMT_IB_IF:
353 iface |= 0xc;
354 break;
355 case SND_SOC_DAIFMT_IB_NF:
356 iface |= 0x8;
357 break;
358 case SND_SOC_DAIFMT_NB_IF:
359 iface |= 0x4;
360 break;
361 default:
362 return -EINVAL;
363 }
364
365 snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
366 snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
367
368 return 0;
369}
370
371static const int mclk_ratios[] = {
372 128,
373 192,
374 256,
375 384,
376 512,
377 768
378};
379
380static int wm8770_hw_params(struct snd_pcm_substream *substream,
381 struct snd_pcm_hw_params *params,
382 struct snd_soc_dai *dai)
383{
384 struct snd_soc_codec *codec;
385 struct wm8770_priv *wm8770;
386 int i;
387 int iface;
388 int shift;
389 int ratio;
390
391 codec = dai->codec;
392 wm8770 = snd_soc_codec_get_drvdata(codec);
393
394 iface = 0;
395 switch (params_format(params)) {
396 case SNDRV_PCM_FORMAT_S16_LE:
397 break;
398 case SNDRV_PCM_FORMAT_S20_3LE:
399 iface |= 0x10;
400 break;
401 case SNDRV_PCM_FORMAT_S24_LE:
402 iface |= 0x20;
403 break;
404 case SNDRV_PCM_FORMAT_S32_LE:
405 iface |= 0x30;
406 break;
407 }
408
409 switch (substream->stream) {
410 case SNDRV_PCM_STREAM_PLAYBACK:
411 i = 0;
412 shift = 4;
413 break;
414 case SNDRV_PCM_STREAM_CAPTURE:
415 i = 2;
416 shift = 0;
417 break;
418 default:
419 return -EINVAL;
420 }
421
422 /* Only need to set MCLK/LRCLK ratio if we're master */
423 if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
424 for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
425 ratio = wm8770->sysclk / params_rate(params);
426 if (ratio == mclk_ratios[i])
427 break;
428 }
429
430 if (i == ARRAY_SIZE(mclk_ratios)) {
431 dev_err(codec->dev,
432 "Unable to configure MCLK ratio %d/%d\n",
433 wm8770->sysclk, params_rate(params));
434 return -EINVAL;
435 }
436
437 dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
438
439 snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
440 i << shift);
441 }
442
443 snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
444
445 return 0;
446}
447
448static int wm8770_mute(struct snd_soc_dai *dai, int mute)
449{
450 struct snd_soc_codec *codec;
451
452 codec = dai->codec;
453 return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
454 !!mute << 4);
455}
456
457static int wm8770_set_sysclk(struct snd_soc_dai *dai,
458 int clk_id, unsigned int freq, int dir)
459{
460 struct snd_soc_codec *codec;
461 struct wm8770_priv *wm8770;
462
463 codec = dai->codec;
464 wm8770 = snd_soc_codec_get_drvdata(codec);
465 wm8770->sysclk = freq;
466 return 0;
467}
468
469static void wm8770_sync_cache(struct snd_soc_codec *codec)
470{
471 int i;
472 u16 *cache;
473
474 if (!codec->cache_sync)
475 return;
476
477 codec->cache_only = 0;
478 cache = codec->reg_cache;
479 for (i = 0; i < codec->driver->reg_cache_size; i++) {
480 if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i])
481 continue;
482 snd_soc_write(codec, i, cache[i]);
483 }
484 codec->cache_sync = 0;
485}
486
487static int wm8770_set_bias_level(struct snd_soc_codec *codec,
488 enum snd_soc_bias_level level)
489{
490 int ret;
491 struct wm8770_priv *wm8770;
492
493 wm8770 = snd_soc_codec_get_drvdata(codec);
494
495 switch (level) {
496 case SND_SOC_BIAS_ON:
497 break;
498 case SND_SOC_BIAS_PREPARE:
499 break;
500 case SND_SOC_BIAS_STANDBY:
501 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
502 ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
503 wm8770->supplies);
504 if (ret) {
505 dev_err(codec->dev,
506 "Failed to enable supplies: %d\n",
507 ret);
508 return ret;
509 }
510 wm8770_sync_cache(codec);
511 /* global powerup */
512 snd_soc_write(codec, WM8770_PWDNCTRL, 0);
513 }
514 break;
515 case SND_SOC_BIAS_OFF:
516 /* global powerdown */
517 snd_soc_write(codec, WM8770_PWDNCTRL, 1);
518 regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
519 wm8770->supplies);
520 break;
521 }
522
523 codec->dapm.bias_level = level;
524 return 0;
525}
526
527#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
528 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
529
530static struct snd_soc_dai_ops wm8770_dai_ops = {
531 .digital_mute = wm8770_mute,
532 .hw_params = wm8770_hw_params,
533 .set_fmt = wm8770_set_fmt,
534 .set_sysclk = wm8770_set_sysclk,
535};
536
537static struct snd_soc_dai_driver wm8770_dai = {
538 .name = "wm8770-hifi",
539 .playback = {
540 .stream_name = "Playback",
541 .channels_min = 2,
542 .channels_max = 2,
543 .rates = SNDRV_PCM_RATE_8000_192000,
544 .formats = WM8770_FORMATS
545 },
546 .capture = {
547 .stream_name = "Capture",
548 .channels_min = 2,
549 .channels_max = 2,
550 .rates = SNDRV_PCM_RATE_8000_96000,
551 .formats = WM8770_FORMATS
552 },
553 .ops = &wm8770_dai_ops,
554 .symmetric_rates = 1
555};
556
557#ifdef CONFIG_PM
558static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state)
559{
560 wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
561 return 0;
562}
563
564static int wm8770_resume(struct snd_soc_codec *codec)
565{
566 wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 return 0;
568}
569#else
570#define wm8770_suspend NULL
571#define wm8770_resume NULL
572#endif
573
574static int wm8770_probe(struct snd_soc_codec *codec)
575{
576 struct wm8770_priv *wm8770;
577 int ret;
578 int i;
579
580 wm8770 = snd_soc_codec_get_drvdata(codec);
581 wm8770->codec = codec;
582
583 codec->dapm.idle_bias_off = 1;
584
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
586 if (ret < 0) {
587 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
588 return ret;
589 }
590
591 for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
592 wm8770->supplies[i].supply = wm8770_supply_names[i];
593
594 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies),
595 wm8770->supplies);
596 if (ret) {
597 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
598 return ret;
599 }
600
601 wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
602 wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
603 wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
604
605 /* This should really be moved into the regulator core */
606 for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
607 ret = regulator_register_notifier(wm8770->supplies[i].consumer,
608 &wm8770->disable_nb[i]);
609 if (ret) {
610 dev_err(codec->dev,
611 "Failed to register regulator notifier: %d\n",
612 ret);
613 }
614 }
615
616 ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
617 wm8770->supplies);
618 if (ret) {
619 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
620 goto err_reg_get;
621 }
622
623 ret = wm8770_reset(codec);
624 if (ret < 0) {
625 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
626 goto err_reg_enable;
627 }
628
629 wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
630
631 /* latch the volume update bits */
632 snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
633 snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
634 snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
635 snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
636 snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
637 snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
638 snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
639 snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
640 snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
641 snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
642
643 /* mute all DACs */
644 snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
645
646 snd_soc_add_controls(codec, wm8770_snd_controls,
647 ARRAY_SIZE(wm8770_snd_controls));
648 snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
649 ARRAY_SIZE(wm8770_dapm_widgets));
650 snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon,
651 ARRAY_SIZE(wm8770_intercon));
652 return 0;
653
654err_reg_enable:
655 regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
656err_reg_get:
657 regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
658 return ret;
659}
660
661static int wm8770_remove(struct snd_soc_codec *codec)
662{
663 struct wm8770_priv *wm8770;
664 int i;
665
666 wm8770 = snd_soc_codec_get_drvdata(codec);
667 wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
668
669 for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
670 regulator_unregister_notifier(wm8770->supplies[i].consumer,
671 &wm8770->disable_nb[i]);
672 regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
673 return 0;
674}
675
676static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
677 .probe = wm8770_probe,
678 .remove = wm8770_remove,
679 .suspend = wm8770_suspend,
680 .resume = wm8770_resume,
681 .set_bias_level = wm8770_set_bias_level,
682 .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
683 .reg_word_size = sizeof (u16),
684 .reg_cache_default = wm8770_reg_defs
685};
686
687#if defined(CONFIG_SPI_MASTER)
688static int __devinit wm8770_spi_probe(struct spi_device *spi)
689{
690 struct wm8770_priv *wm8770;
691 int ret;
692
693 wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL);
694 if (!wm8770)
695 return -ENOMEM;
696
697 wm8770->control_type = SND_SOC_SPI;
698 spi_set_drvdata(spi, wm8770);
699
700 ret = snd_soc_register_codec(&spi->dev,
701 &soc_codec_dev_wm8770, &wm8770_dai, 1);
702 if (ret < 0)
703 kfree(wm8770);
704 return ret;
705}
706
707static int __devexit wm8770_spi_remove(struct spi_device *spi)
708{
709 snd_soc_unregister_codec(&spi->dev);
710 kfree(spi_get_drvdata(spi));
711 return 0;
712}
713
714static struct spi_driver wm8770_spi_driver = {
715 .driver = {
716 .name = "wm8770",
717 .owner = THIS_MODULE,
718 },
719 .probe = wm8770_spi_probe,
720 .remove = __devexit_p(wm8770_spi_remove)
721};
722#endif
723
724static int __init wm8770_modinit(void)
725{
726 int ret = 0;
727
728#if defined(CONFIG_SPI_MASTER)
729 ret = spi_register_driver(&wm8770_spi_driver);
730 if (ret) {
731 printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
732 ret);
733 }
734#endif
735 return ret;
736}
737module_init(wm8770_modinit);
738
739static void __exit wm8770_exit(void)
740{
741#if defined(CONFIG_SPI_MASTER)
742 spi_unregister_driver(&wm8770_spi_driver);
743#endif
744}
745module_exit(wm8770_exit);
746
747MODULE_DESCRIPTION("ASoC WM8770 driver");
748MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
749MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8770.h b/sound/soc/codecs/wm8770.h
new file mode 100644
index 000000000000..5f1b3bda6cc8
--- /dev/null
+++ b/sound/soc/codecs/wm8770.h
@@ -0,0 +1,51 @@
1/*
2 * wm8770.h -- WM8770 ASoC driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8770_H
14#define _WM8770_H
15
16/* Registers */
17#define WM8770_VOUT1LVOL 0
18#define WM8770_VOUT1RVOL 0x1
19#define WM8770_VOUT2LVOL 0x2
20#define WM8770_VOUT2RVOL 0x3
21#define WM8770_VOUT3LVOL 0x4
22#define WM8770_VOUT3RVOL 0x5
23#define WM8770_VOUT4LVOL 0x6
24#define WM8770_VOUT4RVOL 0x7
25#define WM8770_MSALGVOL 0x8
26#define WM8770_DAC1LVOL 0x9
27#define WM8770_DAC1RVOL 0xa
28#define WM8770_DAC2LVOL 0xb
29#define WM8770_DAC2RVOL 0xc
30#define WM8770_DAC3LVOL 0xd
31#define WM8770_DAC3RVOL 0xe
32#define WM8770_DAC4LVOL 0xf
33#define WM8770_DAC4RVOL 0x10
34#define WM8770_MSDIGVOL 0x11
35#define WM8770_DACPHASE 0x12
36#define WM8770_DACCTRL1 0x13
37#define WM8770_DACMUTE 0x14
38#define WM8770_DACCTRL2 0x15
39#define WM8770_IFACECTRL 0x16
40#define WM8770_MSTRCTRL 0x17
41#define WM8770_PWDNCTRL 0x18
42#define WM8770_ADCLCTRL 0x19
43#define WM8770_ADCRCTRL 0x1a
44#define WM8770_ADCMUX 0x1b
45#define WM8770_OUTMUX1 0x1c
46#define WM8770_OUTMUX2 0x1d
47#define WM8770_RESET 0x31
48
49#define WM8770_CACHEREGNUM 0x20
50
51#endif
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index f8154e661524..8e7953b1b790 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -25,26 +25,17 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30#include <sound/tlv.h> 29#include <sound/tlv.h>
31 30
32#include "wm8776.h" 31#include "wm8776.h"
33 32
34static struct snd_soc_codec *wm8776_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8776;
36
37/* codec private data */ 33/* codec private data */
38struct wm8776_priv { 34struct wm8776_priv {
39 struct snd_soc_codec codec; 35 enum snd_soc_control_type control_type;
40 u16 reg_cache[WM8776_CACHEREGNUM];
41 int sysclk[2]; 36 int sysclk[2];
42}; 37};
43 38
44#ifdef CONFIG_SPI_MASTER
45static int wm8776_spi_write(struct spi_device *spi, const char *data, int len);
46#endif
47
48static const u16 wm8776_reg[WM8776_CACHEREGNUM] = { 39static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
49 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */ 40 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
50 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */ 41 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
@@ -144,7 +135,7 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
144 struct snd_soc_codec *codec = dai->codec; 135 struct snd_soc_codec *codec = dai->codec;
145 int reg, iface, master; 136 int reg, iface, master;
146 137
147 switch (dai->id) { 138 switch (dai->driver->id) {
148 case WM8776_DAI_DAC: 139 case WM8776_DAI_DAC:
149 reg = WM8776_DACIFCTRL; 140 reg = WM8776_DACIFCTRL;
150 master = 0x80; 141 master = 0x80;
@@ -226,7 +217,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
226 217
227 iface = 0; 218 iface = 0;
228 219
229 switch (dai->id) { 220 switch (dai->driver->id) {
230 case WM8776_DAI_DAC: 221 case WM8776_DAI_DAC:
231 iface_reg = WM8776_DACIFCTRL; 222 iface_reg = WM8776_DACIFCTRL;
232 master = 0x80; 223 master = 0x80;
@@ -260,7 +251,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
260 /* Only need to set MCLK/LRCLK ratio if we're master */ 251 /* Only need to set MCLK/LRCLK ratio if we're master */
261 if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) { 252 if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
262 for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) { 253 for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
263 if (wm8776->sysclk[dai->id] / params_rate(params) 254 if (wm8776->sysclk[dai->driver->id] / params_rate(params)
264 == mclk_ratios[i]) 255 == mclk_ratios[i])
265 break; 256 break;
266 } 257 }
@@ -268,7 +259,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
268 if (i == ARRAY_SIZE(mclk_ratios)) { 259 if (i == ARRAY_SIZE(mclk_ratios)) {
269 dev_err(codec->dev, 260 dev_err(codec->dev,
270 "Unable to configure MCLK ratio %d/%d\n", 261 "Unable to configure MCLK ratio %d/%d\n",
271 wm8776->sysclk[dai->id], params_rate(params)); 262 wm8776->sysclk[dai->driver->id], params_rate(params));
272 return -EINVAL; 263 return -EINVAL;
273 } 264 }
274 265
@@ -298,9 +289,9 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
298 struct snd_soc_codec *codec = dai->codec; 289 struct snd_soc_codec *codec = dai->codec;
299 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); 290 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
300 291
301 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk)); 292 BUG_ON(dai->driver->id >= ARRAY_SIZE(wm8776->sysclk));
302 293
303 wm8776->sysclk[dai->id] = freq; 294 wm8776->sysclk[dai->driver->id] = freq;
304 295
305 return 0; 296 return 0;
306} 297}
@@ -314,7 +305,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
314 case SND_SOC_BIAS_PREPARE: 305 case SND_SOC_BIAS_PREPARE:
315 break; 306 break;
316 case SND_SOC_BIAS_STANDBY: 307 case SND_SOC_BIAS_STANDBY:
317 if (codec->bias_level == SND_SOC_BIAS_OFF) { 308 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
318 /* Disable the global powerdown; DAPM does the rest */ 309 /* Disable the global powerdown; DAPM does the rest */
319 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); 310 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
320 } 311 }
@@ -325,7 +316,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
325 break; 316 break;
326 } 317 }
327 318
328 codec->bias_level = level; 319 codec->dapm.bias_level = level;
329 return 0; 320 return 0;
330} 321}
331 322
@@ -350,10 +341,10 @@ static struct snd_soc_dai_ops wm8776_adc_ops = {
350 .set_sysclk = wm8776_set_sysclk, 341 .set_sysclk = wm8776_set_sysclk,
351}; 342};
352 343
353struct snd_soc_dai wm8776_dai[] = { 344static struct snd_soc_dai_driver wm8776_dai[] = {
354 { 345 {
355 .name = "WM8776 Playback", 346 .name = "wm8776-hifi-playback",
356 .id = WM8776_DAI_DAC, 347 .id = WM8776_DAI_DAC,
357 .playback = { 348 .playback = {
358 .stream_name = "Playback", 349 .stream_name = "Playback",
359 .channels_min = 2, 350 .channels_min = 2,
@@ -364,8 +355,8 @@ struct snd_soc_dai wm8776_dai[] = {
364 .ops = &wm8776_dac_ops, 355 .ops = &wm8776_dac_ops,
365 }, 356 },
366 { 357 {
367 .name = "WM8776 Capture", 358 .name = "wm8776-hifi-capture",
368 .id = WM8776_DAI_ADC, 359 .id = WM8776_DAI_ADC,
369 .capture = { 360 .capture = {
370 .stream_name = "Capture", 361 .stream_name = "Capture",
371 .channels_min = 2, 362 .channels_min = 2,
@@ -376,23 +367,17 @@ struct snd_soc_dai wm8776_dai[] = {
376 .ops = &wm8776_adc_ops, 367 .ops = &wm8776_adc_ops,
377 }, 368 },
378}; 369};
379EXPORT_SYMBOL_GPL(wm8776_dai);
380 370
381#ifdef CONFIG_PM 371#ifdef CONFIG_PM
382static int wm8776_suspend(struct platform_device *pdev, pm_message_t state) 372static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state)
383{ 373{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385 struct snd_soc_codec *codec = socdev->card->codec;
386
387 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF); 374 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
388 375
389 return 0; 376 return 0;
390} 377}
391 378
392static int wm8776_resume(struct platform_device *pdev) 379static int wm8776_resume(struct snd_soc_codec *codec)
393{ 380{
394 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
395 struct snd_soc_codec *codec = socdev->card->codec;
396 int i; 381 int i;
397 u8 data[2]; 382 u8 data[2];
398 u16 *cache = codec->reg_cache; 383 u16 *cache = codec->reg_cache;
@@ -415,99 +400,22 @@ static int wm8776_resume(struct platform_device *pdev)
415#define wm8776_resume NULL 400#define wm8776_resume NULL
416#endif 401#endif
417 402
418static int wm8776_probe(struct platform_device *pdev) 403static int wm8776_probe(struct snd_soc_codec *codec)
419{ 404{
420 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 405 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
421 struct snd_soc_codec *codec; 406 struct snd_soc_dapm_context *dapm = &codec->dapm;
422 int ret = 0; 407 int ret = 0;
423 408
424 if (wm8776_codec == NULL) { 409 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
425 dev_err(&pdev->dev, "Codec device not registered\n");
426 return -ENODEV;
427 }
428
429 socdev->card->codec = wm8776_codec;
430 codec = wm8776_codec;
431
432 /* register pcms */
433 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
434 if (ret < 0) {
435 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
436 goto pcm_err;
437 }
438
439 snd_soc_add_controls(codec, wm8776_snd_controls,
440 ARRAY_SIZE(wm8776_snd_controls));
441 snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
442 ARRAY_SIZE(wm8776_dapm_widgets));
443 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
444
445 return ret;
446
447pcm_err:
448 return ret;
449}
450
451/* power down chip */
452static int wm8776_remove(struct platform_device *pdev)
453{
454 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
455
456 snd_soc_free_pcms(socdev);
457 snd_soc_dapm_free(socdev);
458
459 return 0;
460}
461
462struct snd_soc_codec_device soc_codec_dev_wm8776 = {
463 .probe = wm8776_probe,
464 .remove = wm8776_remove,
465 .suspend = wm8776_suspend,
466 .resume = wm8776_resume,
467};
468EXPORT_SYMBOL_GPL(soc_codec_dev_wm8776);
469
470static int wm8776_register(struct wm8776_priv *wm8776,
471 enum snd_soc_control_type control)
472{
473 int ret, i;
474 struct snd_soc_codec *codec = &wm8776->codec;
475
476 if (wm8776_codec) {
477 dev_err(codec->dev, "Another WM8776 is registered\n");
478 ret = -EINVAL;
479 goto err;
480 }
481
482 mutex_init(&codec->mutex);
483 INIT_LIST_HEAD(&codec->dapm_widgets);
484 INIT_LIST_HEAD(&codec->dapm_paths);
485
486 snd_soc_codec_set_drvdata(codec, wm8776);
487 codec->name = "WM8776";
488 codec->owner = THIS_MODULE;
489 codec->bias_level = SND_SOC_BIAS_OFF;
490 codec->set_bias_level = wm8776_set_bias_level;
491 codec->dai = wm8776_dai;
492 codec->num_dai = ARRAY_SIZE(wm8776_dai);
493 codec->reg_cache_size = WM8776_CACHEREGNUM;
494 codec->reg_cache = &wm8776->reg_cache;
495
496 memcpy(codec->reg_cache, wm8776_reg, sizeof(wm8776_reg));
497
498 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
499 if (ret < 0) { 410 if (ret < 0) {
500 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 411 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
501 goto err; 412 return ret;
502 } 413 }
503 414
504 for (i = 0; i < ARRAY_SIZE(wm8776_dai); i++)
505 wm8776_dai[i].dev = codec->dev;
506
507 ret = wm8776_reset(codec); 415 ret = wm8776_reset(codec);
508 if (ret < 0) { 416 if (ret < 0) {
509 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 417 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
510 goto err; 418 return ret;
511 } 419 }
512 420
513 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 421 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -517,95 +425,63 @@ static int wm8776_register(struct wm8776_priv *wm8776,
517 snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100); 425 snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
518 snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100); 426 snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
519 427
520 wm8776_codec = codec; 428 snd_soc_add_controls(codec, wm8776_snd_controls,
521 429 ARRAY_SIZE(wm8776_snd_controls));
522 ret = snd_soc_register_codec(codec); 430 snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets,
523 if (ret != 0) { 431 ARRAY_SIZE(wm8776_dapm_widgets));
524 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 432 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
525 goto err;
526 }
527
528 ret = snd_soc_register_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
529 if (ret != 0) {
530 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
531 goto err_codec;
532 }
533
534 return 0;
535 433
536err_codec:
537 snd_soc_unregister_codec(codec);
538err:
539 kfree(wm8776);
540 return ret; 434 return ret;
541} 435}
542 436
543static void wm8776_unregister(struct wm8776_priv *wm8776) 437/* power down chip */
438static int wm8776_remove(struct snd_soc_codec *codec)
544{ 439{
545 wm8776_set_bias_level(&wm8776->codec, SND_SOC_BIAS_OFF); 440 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
546 snd_soc_unregister_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai)); 441 return 0;
547 snd_soc_unregister_codec(&wm8776->codec);
548 kfree(wm8776);
549 wm8776_codec = NULL;
550} 442}
551 443
552#if defined(CONFIG_SPI_MASTER) 444static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
553static int wm8776_spi_write(struct spi_device *spi, const char *data, int len) 445 .probe = wm8776_probe,
554{ 446 .remove = wm8776_remove,
555 struct spi_transfer t; 447 .suspend = wm8776_suspend,
556 struct spi_message m; 448 .resume = wm8776_resume,
557 u8 msg[2]; 449 .set_bias_level = wm8776_set_bias_level,
558 450 .reg_cache_size = ARRAY_SIZE(wm8776_reg),
559 if (len <= 0) 451 .reg_word_size = sizeof(u16),
560 return 0; 452 .reg_cache_default = wm8776_reg,
561 453};
562 msg[0] = data[0];
563 msg[1] = data[1];
564
565 spi_message_init(&m);
566 memset(&t, 0, (sizeof t));
567
568 t.tx_buf = &msg[0];
569 t.len = len;
570
571 spi_message_add_tail(&t, &m);
572 spi_sync(spi, &m);
573
574 return len;
575}
576 454
455#if defined(CONFIG_SPI_MASTER)
577static int __devinit wm8776_spi_probe(struct spi_device *spi) 456static int __devinit wm8776_spi_probe(struct spi_device *spi)
578{ 457{
579 struct snd_soc_codec *codec;
580 struct wm8776_priv *wm8776; 458 struct wm8776_priv *wm8776;
459 int ret;
581 460
582 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL); 461 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
583 if (wm8776 == NULL) 462 if (wm8776 == NULL)
584 return -ENOMEM; 463 return -ENOMEM;
585 464
586 codec = &wm8776->codec; 465 wm8776->control_type = SND_SOC_SPI;
587 codec->control_data = spi; 466 spi_set_drvdata(spi, wm8776);
588 codec->hw_write = (hw_write_t)wm8776_spi_write;
589 codec->dev = &spi->dev;
590 467
591 dev_set_drvdata(&spi->dev, wm8776); 468 ret = snd_soc_register_codec(&spi->dev,
592 469 &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
593 return wm8776_register(wm8776, SND_SOC_SPI); 470 if (ret < 0)
471 kfree(wm8776);
472 return ret;
594} 473}
595 474
596static int __devexit wm8776_spi_remove(struct spi_device *spi) 475static int __devexit wm8776_spi_remove(struct spi_device *spi)
597{ 476{
598 struct wm8776_priv *wm8776 = dev_get_drvdata(&spi->dev); 477 snd_soc_unregister_codec(&spi->dev);
599 478 kfree(spi_get_drvdata(spi));
600 wm8776_unregister(wm8776);
601
602 return 0; 479 return 0;
603} 480}
604 481
605static struct spi_driver wm8776_spi_driver = { 482static struct spi_driver wm8776_spi_driver = {
606 .driver = { 483 .driver = {
607 .name = "wm8776", 484 .name = "wm8776-codec",
608 .bus = &spi_bus_type,
609 .owner = THIS_MODULE, 485 .owner = THIS_MODULE,
610 }, 486 },
611 .probe = wm8776_spi_probe, 487 .probe = wm8776_spi_probe,
@@ -618,27 +494,26 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
618 const struct i2c_device_id *id) 494 const struct i2c_device_id *id)
619{ 495{
620 struct wm8776_priv *wm8776; 496 struct wm8776_priv *wm8776;
621 struct snd_soc_codec *codec; 497 int ret;
622 498
623 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL); 499 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
624 if (wm8776 == NULL) 500 if (wm8776 == NULL)
625 return -ENOMEM; 501 return -ENOMEM;
626 502
627 codec = &wm8776->codec;
628 codec->hw_write = (hw_write_t)i2c_master_send;
629
630 i2c_set_clientdata(i2c, wm8776); 503 i2c_set_clientdata(i2c, wm8776);
631 codec->control_data = i2c; 504 wm8776->control_type = SND_SOC_I2C;
632
633 codec->dev = &i2c->dev;
634 505
635 return wm8776_register(wm8776, SND_SOC_I2C); 506 ret = snd_soc_register_codec(&i2c->dev,
507 &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
508 if (ret < 0)
509 kfree(wm8776);
510 return ret;
636} 511}
637 512
638static __devexit int wm8776_i2c_remove(struct i2c_client *client) 513static __devexit int wm8776_i2c_remove(struct i2c_client *client)
639{ 514{
640 struct wm8776_priv *wm8776 = i2c_get_clientdata(client); 515 snd_soc_unregister_codec(&client->dev);
641 wm8776_unregister(wm8776); 516 kfree(i2c_get_clientdata(client));
642 return 0; 517 return 0;
643} 518}
644 519
@@ -650,7 +525,7 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
650 525
651static struct i2c_driver wm8776_i2c_driver = { 526static struct i2c_driver wm8776_i2c_driver = {
652 .driver = { 527 .driver = {
653 .name = "wm8776", 528 .name = "wm8776-codec",
654 .owner = THIS_MODULE, 529 .owner = THIS_MODULE,
655 }, 530 },
656 .probe = wm8776_i2c_probe, 531 .probe = wm8776_i2c_probe,
@@ -661,22 +536,22 @@ static struct i2c_driver wm8776_i2c_driver = {
661 536
662static int __init wm8776_modinit(void) 537static int __init wm8776_modinit(void)
663{ 538{
664 int ret; 539 int ret = 0;
665#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 540#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
666 ret = i2c_add_driver(&wm8776_i2c_driver); 541 ret = i2c_add_driver(&wm8776_i2c_driver);
667 if (ret != 0) { 542 if (ret != 0) {
668 printk(KERN_ERR "Failed to register WM8776 I2C driver: %d\n", 543 printk(KERN_ERR "Failed to register wm8776 I2C driver: %d\n",
669 ret); 544 ret);
670 } 545 }
671#endif 546#endif
672#if defined(CONFIG_SPI_MASTER) 547#if defined(CONFIG_SPI_MASTER)
673 ret = spi_register_driver(&wm8776_spi_driver); 548 ret = spi_register_driver(&wm8776_spi_driver);
674 if (ret != 0) { 549 if (ret != 0) {
675 printk(KERN_ERR "Failed to register WM8776 SPI driver: %d\n", 550 printk(KERN_ERR "Failed to register wm8776 SPI driver: %d\n",
676 ret); 551 ret);
677 } 552 }
678#endif 553#endif
679 return 0; 554 return ret;
680} 555}
681module_init(wm8776_modinit); 556module_init(wm8776_modinit);
682 557
diff --git a/sound/soc/codecs/wm8776.h b/sound/soc/codecs/wm8776.h
index 6606d25d2d83..4cf1c8e0bfc9 100644
--- a/sound/soc/codecs/wm8776.h
+++ b/sound/soc/codecs/wm8776.h
@@ -45,7 +45,4 @@
45#define WM8776_DAI_DAC 0 45#define WM8776_DAI_DAC 0
46#define WM8776_DAI_ADC 1 46#define WM8776_DAI_ADC 1
47 47
48extern struct snd_soc_dai wm8776_dai[];
49extern struct snd_soc_codec_device soc_codec_dev_wm8776;
50
51#endif 48#endif
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
new file mode 100644
index 000000000000..9a5e67c5a6bd
--- /dev/null
+++ b/sound/soc/codecs/wm8804.c
@@ -0,0 +1,837 @@
1/*
2 * wm8804.c -- WM8804 S/PDIF transceiver driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/spi/spi.h>
20#include <linux/regulator/consumer.h>
21#include <linux/slab.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8804.h"
30
31#define WM8804_NUM_SUPPLIES 2
32static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = {
33 "PVDD",
34 "DVDD"
35};
36
37static const u8 wm8804_reg_defs[] = {
38 0x05, /* R0 - RST/DEVID1 */
39 0x88, /* R1 - DEVID2 */
40 0x04, /* R2 - DEVREV */
41 0x21, /* R3 - PLL1 */
42 0xFD, /* R4 - PLL2 */
43 0x36, /* R5 - PLL3 */
44 0x07, /* R6 - PLL4 */
45 0x16, /* R7 - PLL5 */
46 0x18, /* R8 - PLL6 */
47 0xFF, /* R9 - SPDMODE */
48 0x00, /* R10 - INTMASK */
49 0x00, /* R11 - INTSTAT */
50 0x00, /* R12 - SPDSTAT */
51 0x00, /* R13 - RXCHAN1 */
52 0x00, /* R14 - RXCHAN2 */
53 0x00, /* R15 - RXCHAN3 */
54 0x00, /* R16 - RXCHAN4 */
55 0x00, /* R17 - RXCHAN5 */
56 0x00, /* R18 - SPDTX1 */
57 0x00, /* R19 - SPDTX2 */
58 0x00, /* R20 - SPDTX3 */
59 0x71, /* R21 - SPDTX4 */
60 0x0B, /* R22 - SPDTX5 */
61 0x70, /* R23 - GPO0 */
62 0x57, /* R24 - GPO1 */
63 0x00, /* R25 */
64 0x42, /* R26 - GPO2 */
65 0x06, /* R27 - AIFTX */
66 0x06, /* R28 - AIFRX */
67 0x80, /* R29 - SPDRX1 */
68 0x07, /* R30 - PWRDN */
69};
70
71struct wm8804_priv {
72 enum snd_soc_control_type control_type;
73 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
74 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
75 struct snd_soc_codec *codec;
76};
77
78static int txsrc_get(struct snd_kcontrol *kcontrol,
79 struct snd_ctl_elem_value *ucontrol);
80
81static int txsrc_put(struct snd_kcontrol *kcontrol,
82 struct snd_ctl_elem_value *ucontrol);
83
84/*
85 * We can't use the same notifier block for more than one supply and
86 * there's no way I can see to get from a callback to the caller
87 * except container_of().
88 */
89#define WM8804_REGULATOR_EVENT(n) \
90static int wm8804_regulator_event_##n(struct notifier_block *nb, \
91 unsigned long event, void *data) \
92{ \
93 struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
94 disable_nb[n]); \
95 if (event & REGULATOR_EVENT_DISABLE) { \
96 wm8804->codec->cache_sync = 1; \
97 } \
98 return 0; \
99}
100
101WM8804_REGULATOR_EVENT(0)
102WM8804_REGULATOR_EVENT(1)
103
104static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
105static const SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text);
106
107static const struct snd_kcontrol_new wm8804_snd_controls[] = {
108 SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put),
109 SOC_SINGLE("TX Playback Switch", WM8804_PWRDN, 2, 1, 1),
110 SOC_SINGLE("AIF Playback Switch", WM8804_PWRDN, 4, 1, 1)
111};
112
113static int txsrc_get(struct snd_kcontrol *kcontrol,
114 struct snd_ctl_elem_value *ucontrol)
115{
116 struct snd_soc_codec *codec;
117 unsigned int src;
118
119 codec = snd_kcontrol_chip(kcontrol);
120 src = snd_soc_read(codec, WM8804_SPDTX4);
121 if (src & 0x40)
122 ucontrol->value.integer.value[0] = 1;
123 else
124 ucontrol->value.integer.value[0] = 0;
125
126 return 0;
127}
128
129static int txsrc_put(struct snd_kcontrol *kcontrol,
130 struct snd_ctl_elem_value *ucontrol)
131{
132 struct snd_soc_codec *codec;
133 unsigned int src, txpwr;
134
135 codec = snd_kcontrol_chip(kcontrol);
136
137 if (ucontrol->value.integer.value[0] != 0
138 && ucontrol->value.integer.value[0] != 1)
139 return -EINVAL;
140
141 src = snd_soc_read(codec, WM8804_SPDTX4);
142 switch ((src & 0x40) >> 6) {
143 case 0:
144 if (!ucontrol->value.integer.value[0])
145 return 0;
146 break;
147 case 1:
148 if (ucontrol->value.integer.value[1])
149 return 0;
150 break;
151 }
152
153 /* save the current power state of the transmitter */
154 txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;
155 /* power down the transmitter */
156 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);
157 /* set the tx source */
158 snd_soc_update_bits(codec, WM8804_SPDTX4, 0x40,
159 ucontrol->value.integer.value[0] << 6);
160
161 if (ucontrol->value.integer.value[0]) {
162 /* power down the receiver */
163 snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0x2);
164 /* power up the AIF */
165 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0);
166 } else {
167 /* don't power down the AIF -- may be used as an output */
168 /* power up the receiver */
169 snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0);
170 }
171
172 /* restore the transmitter's configuration */
173 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
174
175 return 0;
176}
177
178static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
179{
180 switch (reg) {
181 case WM8804_RST_DEVID1:
182 case WM8804_DEVID2:
183 case WM8804_DEVREV:
184 case WM8804_INTSTAT:
185 case WM8804_SPDSTAT:
186 case WM8804_RXCHAN1:
187 case WM8804_RXCHAN2:
188 case WM8804_RXCHAN3:
189 case WM8804_RXCHAN4:
190 case WM8804_RXCHAN5:
191 return 1;
192 default:
193 break;
194 }
195
196 return 0;
197}
198
199static int wm8804_reset(struct snd_soc_codec *codec)
200{
201 return snd_soc_write(codec, WM8804_RST_DEVID1, 0x0);
202}
203
204static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
205{
206 struct snd_soc_codec *codec;
207 u16 format, master, bcp, lrp;
208
209 codec = dai->codec;
210
211 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
212 case SND_SOC_DAIFMT_I2S:
213 format = 0x2;
214 break;
215 case SND_SOC_DAIFMT_RIGHT_J:
216 format = 0x0;
217 break;
218 case SND_SOC_DAIFMT_LEFT_J:
219 format = 0x1;
220 break;
221 case SND_SOC_DAIFMT_DSP_A:
222 case SND_SOC_DAIFMT_DSP_B:
223 format = 0x3;
224 break;
225 default:
226 dev_err(dai->dev, "Unknown dai format\n");
227 return -EINVAL;
228 }
229
230 /* set data format */
231 snd_soc_update_bits(codec, WM8804_AIFTX, 0x3, format);
232 snd_soc_update_bits(codec, WM8804_AIFRX, 0x3, format);
233
234 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
235 case SND_SOC_DAIFMT_CBM_CFM:
236 master = 1;
237 break;
238 case SND_SOC_DAIFMT_CBS_CFS:
239 master = 0;
240 break;
241 default:
242 dev_err(dai->dev, "Unknown master/slave configuration\n");
243 return -EINVAL;
244 }
245
246 /* set master/slave mode */
247 snd_soc_update_bits(codec, WM8804_AIFRX, 0x40, master << 6);
248
249 bcp = lrp = 0;
250 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
251 case SND_SOC_DAIFMT_NB_NF:
252 break;
253 case SND_SOC_DAIFMT_IB_IF:
254 bcp = lrp = 1;
255 break;
256 case SND_SOC_DAIFMT_IB_NF:
257 bcp = 1;
258 break;
259 case SND_SOC_DAIFMT_NB_IF:
260 lrp = 1;
261 break;
262 default:
263 dev_err(dai->dev, "Unknown polarity configuration\n");
264 return -EINVAL;
265 }
266
267 /* set frame inversion */
268 snd_soc_update_bits(codec, WM8804_AIFTX, 0x10 | 0x20,
269 (bcp << 4) | (lrp << 5));
270 snd_soc_update_bits(codec, WM8804_AIFRX, 0x10 | 0x20,
271 (bcp << 4) | (lrp << 5));
272 return 0;
273}
274
275static int wm8804_hw_params(struct snd_pcm_substream *substream,
276 struct snd_pcm_hw_params *params,
277 struct snd_soc_dai *dai)
278{
279 struct snd_soc_codec *codec;
280 u16 blen;
281
282 codec = dai->codec;
283
284 switch (params_format(params)) {
285 case SNDRV_PCM_FORMAT_S16_LE:
286 blen = 0x0;
287 break;
288 case SNDRV_PCM_FORMAT_S20_3LE:
289 blen = 0x1;
290 break;
291 case SNDRV_PCM_FORMAT_S24_LE:
292 blen = 0x2;
293 break;
294 default:
295 dev_err(dai->dev, "Unsupported word length: %u\n",
296 params_format(params));
297 return -EINVAL;
298 }
299
300 /* set word length */
301 snd_soc_update_bits(codec, WM8804_AIFTX, 0xc, blen << 2);
302 snd_soc_update_bits(codec, WM8804_AIFRX, 0xc, blen << 2);
303
304 return 0;
305}
306
307struct pll_div {
308 u32 prescale:1;
309 u32 mclkdiv:1;
310 u32 freqmode:2;
311 u32 n:4;
312 u32 k:22;
313};
314
315/* PLL rate to output rate divisions */
316static struct {
317 unsigned int div;
318 unsigned int freqmode;
319 unsigned int mclkdiv;
320} post_table[] = {
321 { 2, 0, 0 },
322 { 4, 0, 1 },
323 { 4, 1, 0 },
324 { 8, 1, 1 },
325 { 8, 2, 0 },
326 { 16, 2, 1 },
327 { 12, 3, 0 },
328 { 24, 3, 1 }
329};
330
331#define FIXED_PLL_SIZE ((1ULL << 22) * 10)
332static int pll_factors(struct pll_div *pll_div, unsigned int target,
333 unsigned int source)
334{
335 u64 Kpart;
336 unsigned long int K, Ndiv, Nmod, tmp;
337 int i;
338
339 /*
340 * Scale the output frequency up; the PLL should run in the
341 * region of 90-100MHz.
342 */
343 for (i = 0; i < ARRAY_SIZE(post_table); i++) {
344 tmp = target * post_table[i].div;
345 if (tmp >= 90000000 && tmp <= 100000000) {
346 pll_div->freqmode = post_table[i].freqmode;
347 pll_div->mclkdiv = post_table[i].mclkdiv;
348 target *= post_table[i].div;
349 break;
350 }
351 }
352
353 if (i == ARRAY_SIZE(post_table)) {
354 pr_err("%s: Unable to scale output frequency: %uHz\n",
355 __func__, target);
356 return -EINVAL;
357 }
358
359 pll_div->prescale = 0;
360 Ndiv = target / source;
361 if (Ndiv < 5) {
362 source >>= 1;
363 pll_div->prescale = 1;
364 Ndiv = target / source;
365 }
366
367 if (Ndiv < 5 || Ndiv > 13) {
368 pr_err("%s: WM8804 N value is not within the recommended range: %lu\n",
369 __func__, Ndiv);
370 return -EINVAL;
371 }
372 pll_div->n = Ndiv;
373
374 Nmod = target % source;
375 Kpart = FIXED_PLL_SIZE * (u64)Nmod;
376
377 do_div(Kpart, source);
378
379 K = Kpart & 0xffffffff;
380 if ((K % 10) >= 5)
381 K += 5;
382 K /= 10;
383 pll_div->k = K;
384
385 return 0;
386}
387
388static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
389 int source, unsigned int freq_in,
390 unsigned int freq_out)
391{
392 struct snd_soc_codec *codec;
393
394 codec = dai->codec;
395 if (!freq_in || !freq_out) {
396 /* disable the PLL */
397 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1);
398 return 0;
399 } else {
400 int ret;
401 struct pll_div pll_div;
402
403 ret = pll_factors(&pll_div, freq_out, freq_in);
404 if (ret)
405 return ret;
406
407 /* power down the PLL before reprogramming it */
408 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1);
409
410 if (!freq_in || !freq_out)
411 return 0;
412
413 /* set PLLN and PRESCALE */
414 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
415 pll_div.n | (pll_div.prescale << 4));
416 /* set mclkdiv and freqmode */
417 snd_soc_update_bits(codec, WM8804_PLL5, 0x3 | 0x8,
418 pll_div.freqmode | (pll_div.mclkdiv << 3));
419 /* set PLLK */
420 snd_soc_write(codec, WM8804_PLL1, pll_div.k & 0xff);
421 snd_soc_write(codec, WM8804_PLL2, (pll_div.k >> 8) & 0xff);
422 snd_soc_write(codec, WM8804_PLL3, pll_div.k >> 16);
423
424 /* power up the PLL */
425 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0);
426 }
427
428 return 0;
429}
430
431static int wm8804_set_sysclk(struct snd_soc_dai *dai,
432 int clk_id, unsigned int freq, int dir)
433{
434 struct snd_soc_codec *codec;
435
436 codec = dai->codec;
437
438 switch (clk_id) {
439 case WM8804_TX_CLKSRC_MCLK:
440 if ((freq >= 10000000 && freq <= 14400000)
441 || (freq >= 16280000 && freq <= 27000000))
442 snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0x80);
443 else {
444 dev_err(dai->dev, "OSCCLOCK is not within the "
445 "recommended range: %uHz\n", freq);
446 return -EINVAL;
447 }
448 break;
449 case WM8804_TX_CLKSRC_PLL:
450 snd_soc_update_bits(codec, WM8804_PLL6, 0x80, 0);
451 break;
452 case WM8804_CLKOUT_SRC_CLK1:
453 snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0);
454 break;
455 case WM8804_CLKOUT_SRC_OSCCLK:
456 snd_soc_update_bits(codec, WM8804_PLL6, 0x8, 0x8);
457 break;
458 default:
459 dev_err(dai->dev, "Unknown clock source: %d\n", clk_id);
460 return -EINVAL;
461 }
462
463 return 0;
464}
465
466static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
467 int div_id, int div)
468{
469 struct snd_soc_codec *codec;
470
471 codec = dai->codec;
472 switch (div_id) {
473 case WM8804_CLKOUT_DIV:
474 snd_soc_update_bits(codec, WM8804_PLL5, 0x30,
475 (div & 0x3) << 4);
476 break;
477 default:
478 dev_err(dai->dev, "Unknown clock divider: %d\n", div_id);
479 return -EINVAL;
480 }
481 return 0;
482}
483
484static void wm8804_sync_cache(struct snd_soc_codec *codec)
485{
486 short i;
487 u8 *cache;
488
489 if (!codec->cache_sync)
490 return;
491
492 codec->cache_only = 0;
493 cache = codec->reg_cache;
494 for (i = 0; i < codec->driver->reg_cache_size; i++) {
495 if (i == WM8804_RST_DEVID1 || cache[i] == wm8804_reg_defs[i])
496 continue;
497 snd_soc_write(codec, i, cache[i]);
498 }
499 codec->cache_sync = 0;
500}
501
502static int wm8804_set_bias_level(struct snd_soc_codec *codec,
503 enum snd_soc_bias_level level)
504{
505 int ret;
506 struct wm8804_priv *wm8804;
507
508 wm8804 = snd_soc_codec_get_drvdata(codec);
509 switch (level) {
510 case SND_SOC_BIAS_ON:
511 break;
512 case SND_SOC_BIAS_PREPARE:
513 /* power up the OSC and the PLL */
514 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
515 break;
516 case SND_SOC_BIAS_STANDBY:
517 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
518 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
519 wm8804->supplies);
520 if (ret) {
521 dev_err(codec->dev,
522 "Failed to enable supplies: %d\n",
523 ret);
524 return ret;
525 }
526 wm8804_sync_cache(codec);
527 }
528 /* power down the OSC and the PLL */
529 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
530 break;
531 case SND_SOC_BIAS_OFF:
532 /* power down the OSC and the PLL */
533 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
534 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
535 wm8804->supplies);
536 break;
537 }
538
539 codec->dapm.bias_level = level;
540 return 0;
541}
542
543#ifdef CONFIG_PM
544static int wm8804_suspend(struct snd_soc_codec *codec, pm_message_t state)
545{
546 wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
547 return 0;
548}
549
550static int wm8804_resume(struct snd_soc_codec *codec)
551{
552 wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
553 return 0;
554}
555#else
556#define wm8804_suspend NULL
557#define wm8804_resume NULL
558#endif
559
560static int wm8804_remove(struct snd_soc_codec *codec)
561{
562 struct wm8804_priv *wm8804;
563 int i;
564
565 wm8804 = snd_soc_codec_get_drvdata(codec);
566 wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
567
568 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i)
569 regulator_unregister_notifier(wm8804->supplies[i].consumer,
570 &wm8804->disable_nb[i]);
571 regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
572 return 0;
573}
574
575static int wm8804_probe(struct snd_soc_codec *codec)
576{
577 struct wm8804_priv *wm8804;
578 int i, id1, id2, ret;
579
580 wm8804 = snd_soc_codec_get_drvdata(codec);
581 wm8804->codec = codec;
582
583 codec->dapm.idle_bias_off = 1;
584
585 ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type);
586 if (ret < 0) {
587 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
588 return ret;
589 }
590
591 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
592 wm8804->supplies[i].supply = wm8804_supply_names[i];
593
594 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies),
595 wm8804->supplies);
596 if (ret) {
597 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
598 return ret;
599 }
600
601 wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0;
602 wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1;
603
604 /* This should really be moved into the regulator core */
605 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) {
606 ret = regulator_register_notifier(wm8804->supplies[i].consumer,
607 &wm8804->disable_nb[i]);
608 if (ret != 0) {
609 dev_err(codec->dev,
610 "Failed to register regulator notifier: %d\n",
611 ret);
612 }
613 }
614
615 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
616 wm8804->supplies);
617 if (ret) {
618 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
619 goto err_reg_get;
620 }
621
622 id1 = snd_soc_read(codec, WM8804_RST_DEVID1);
623 if (id1 < 0) {
624 dev_err(codec->dev, "Failed to read device ID: %d\n", id1);
625 ret = id1;
626 goto err_reg_enable;
627 }
628
629 id2 = snd_soc_read(codec, WM8804_DEVID2);
630 if (id2 < 0) {
631 dev_err(codec->dev, "Failed to read device ID: %d\n", id2);
632 ret = id2;
633 goto err_reg_enable;
634 }
635
636 id2 = (id2 << 8) | id1;
637
638 if (id2 != ((wm8804_reg_defs[WM8804_DEVID2] << 8)
639 | wm8804_reg_defs[WM8804_RST_DEVID1])) {
640 dev_err(codec->dev, "Invalid device ID: %#x\n", id2);
641 ret = -EINVAL;
642 goto err_reg_enable;
643 }
644
645 ret = snd_soc_read(codec, WM8804_DEVREV);
646 if (ret < 0) {
647 dev_err(codec->dev, "Failed to read device revision: %d\n",
648 ret);
649 goto err_reg_enable;
650 }
651 dev_info(codec->dev, "revision %c\n", ret + 'A');
652
653 ret = wm8804_reset(codec);
654 if (ret < 0) {
655 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
656 goto err_reg_enable;
657 }
658
659 wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
660
661 snd_soc_add_controls(codec, wm8804_snd_controls,
662 ARRAY_SIZE(wm8804_snd_controls));
663 return 0;
664
665err_reg_enable:
666 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
667err_reg_get:
668 regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
669 return ret;
670}
671
672static struct snd_soc_dai_ops wm8804_dai_ops = {
673 .hw_params = wm8804_hw_params,
674 .set_fmt = wm8804_set_fmt,
675 .set_sysclk = wm8804_set_sysclk,
676 .set_clkdiv = wm8804_set_clkdiv,
677 .set_pll = wm8804_set_pll
678};
679
680#define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
681 SNDRV_PCM_FMTBIT_S24_LE)
682
683#define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
684 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
685 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
686 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
687
688static struct snd_soc_dai_driver wm8804_dai = {
689 .name = "wm8804-spdif",
690 .playback = {
691 .stream_name = "Playback",
692 .channels_min = 2,
693 .channels_max = 2,
694 .rates = WM8804_RATES,
695 .formats = WM8804_FORMATS,
696 },
697 .capture = {
698 .stream_name = "Capture",
699 .channels_min = 2,
700 .channels_max = 2,
701 .rates = WM8804_RATES,
702 .formats = WM8804_FORMATS,
703 },
704 .ops = &wm8804_dai_ops,
705 .symmetric_rates = 1
706};
707
708static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
709 .probe = wm8804_probe,
710 .remove = wm8804_remove,
711 .suspend = wm8804_suspend,
712 .resume = wm8804_resume,
713 .set_bias_level = wm8804_set_bias_level,
714 .reg_cache_size = ARRAY_SIZE(wm8804_reg_defs),
715 .reg_word_size = sizeof(u8),
716 .reg_cache_default = wm8804_reg_defs,
717 .volatile_register = wm8804_volatile
718};
719
720#if defined(CONFIG_SPI_MASTER)
721static int __devinit wm8804_spi_probe(struct spi_device *spi)
722{
723 struct wm8804_priv *wm8804;
724 int ret;
725
726 wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL);
727 if (!wm8804)
728 return -ENOMEM;
729
730 wm8804->control_type = SND_SOC_SPI;
731 spi_set_drvdata(spi, wm8804);
732
733 ret = snd_soc_register_codec(&spi->dev,
734 &soc_codec_dev_wm8804, &wm8804_dai, 1);
735 if (ret < 0)
736 kfree(wm8804);
737 return ret;
738}
739
740static int __devexit wm8804_spi_remove(struct spi_device *spi)
741{
742 snd_soc_unregister_codec(&spi->dev);
743 kfree(spi_get_drvdata(spi));
744 return 0;
745}
746
747static struct spi_driver wm8804_spi_driver = {
748 .driver = {
749 .name = "wm8804",
750 .owner = THIS_MODULE,
751 },
752 .probe = wm8804_spi_probe,
753 .remove = __devexit_p(wm8804_spi_remove)
754};
755#endif
756
757#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
758static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
759 const struct i2c_device_id *id)
760{
761 struct wm8804_priv *wm8804;
762 int ret;
763
764 wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL);
765 if (!wm8804)
766 return -ENOMEM;
767
768 wm8804->control_type = SND_SOC_I2C;
769 i2c_set_clientdata(i2c, wm8804);
770
771 ret = snd_soc_register_codec(&i2c->dev,
772 &soc_codec_dev_wm8804, &wm8804_dai, 1);
773 if (ret < 0)
774 kfree(wm8804);
775 return ret;
776}
777
778static __devexit int wm8804_i2c_remove(struct i2c_client *client)
779{
780 snd_soc_unregister_codec(&client->dev);
781 kfree(i2c_get_clientdata(client));
782 return 0;
783}
784
785static const struct i2c_device_id wm8804_i2c_id[] = {
786 { "wm8804", 0 },
787 { }
788};
789MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id);
790
791static struct i2c_driver wm8804_i2c_driver = {
792 .driver = {
793 .name = "wm8804",
794 .owner = THIS_MODULE,
795 },
796 .probe = wm8804_i2c_probe,
797 .remove = __devexit_p(wm8804_i2c_remove),
798 .id_table = wm8804_i2c_id
799};
800#endif
801
802static int __init wm8804_modinit(void)
803{
804 int ret = 0;
805
806#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
807 ret = i2c_add_driver(&wm8804_i2c_driver);
808 if (ret) {
809 printk(KERN_ERR "Failed to register wm8804 I2C driver: %d\n",
810 ret);
811 }
812#endif
813#if defined(CONFIG_SPI_MASTER)
814 ret = spi_register_driver(&wm8804_spi_driver);
815 if (ret != 0) {
816 printk(KERN_ERR "Failed to register wm8804 SPI driver: %d\n",
817 ret);
818 }
819#endif
820 return ret;
821}
822module_init(wm8804_modinit);
823
824static void __exit wm8804_exit(void)
825{
826#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
827 i2c_del_driver(&wm8804_i2c_driver);
828#endif
829#if defined(CONFIG_SPI_MASTER)
830 spi_unregister_driver(&wm8804_spi_driver);
831#endif
832}
833module_exit(wm8804_exit);
834
835MODULE_DESCRIPTION("ASoC WM8804 driver");
836MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
837MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8804.h b/sound/soc/codecs/wm8804.h
new file mode 100644
index 000000000000..8ec14f5573cb
--- /dev/null
+++ b/sound/soc/codecs/wm8804.h
@@ -0,0 +1,61 @@
1/*
2 * wm8804.h -- WM8804 S/PDIF transceiver driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8804_H
14#define _WM8804_H
15
16/*
17 * Register values.
18 */
19#define WM8804_RST_DEVID1 0x00
20#define WM8804_DEVID2 0x01
21#define WM8804_DEVREV 0x02
22#define WM8804_PLL1 0x03
23#define WM8804_PLL2 0x04
24#define WM8804_PLL3 0x05
25#define WM8804_PLL4 0x06
26#define WM8804_PLL5 0x07
27#define WM8804_PLL6 0x08
28#define WM8804_SPDMODE 0x09
29#define WM8804_INTMASK 0x0A
30#define WM8804_INTSTAT 0x0B
31#define WM8804_SPDSTAT 0x0C
32#define WM8804_RXCHAN1 0x0D
33#define WM8804_RXCHAN2 0x0E
34#define WM8804_RXCHAN3 0x0F
35#define WM8804_RXCHAN4 0x10
36#define WM8804_RXCHAN5 0x11
37#define WM8804_SPDTX1 0x12
38#define WM8804_SPDTX2 0x13
39#define WM8804_SPDTX3 0x14
40#define WM8804_SPDTX4 0x15
41#define WM8804_SPDTX5 0x16
42#define WM8804_GPO0 0x17
43#define WM8804_GPO1 0x18
44#define WM8804_GPO2 0x1A
45#define WM8804_AIFTX 0x1B
46#define WM8804_AIFRX 0x1C
47#define WM8804_SPDRX1 0x1D
48#define WM8804_PWRDN 0x1E
49
50#define WM8804_REGISTER_COUNT 30
51#define WM8804_MAX_REGISTER 0x1E
52
53#define WM8804_TX_CLKSRC_MCLK 1
54#define WM8804_TX_CLKSRC_PLL 2
55
56#define WM8804_CLKOUT_SRC_CLK1 3
57#define WM8804_CLKOUT_SRC_OSCCLK 4
58
59#define WM8804_CLKOUT_DIV 1
60
61#endif /* _WM8804_H */
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5da17a704e5a..449ea09a193d 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -23,13 +23,13 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/spi/spi.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
31#include <sound/soc.h> 32#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 33#include <sound/initval.h>
34#include <sound/tlv.h> 34#include <sound/tlv.h>
35 35
@@ -137,12 +137,8 @@
137 137
138#define WM8900_LRC_MASK 0xfc00 138#define WM8900_LRC_MASK 0xfc00
139 139
140struct snd_soc_codec_device soc_codec_dev_wm8900;
141
142struct wm8900_priv { 140struct wm8900_priv {
143 struct snd_soc_codec codec; 141 enum snd_soc_control_type control_type;
144
145 u16 reg_cache[WM8900_MAXREG];
146 142
147 u32 fll_in; /* FLL input frequency */ 143 u32 fll_in; /* FLL input frequency */
148 u32 fll_out; /* FLL output frequency */ 144 u32 fll_out; /* FLL output frequency */
@@ -184,11 +180,10 @@ static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
184 /* Remaining registers all zero */ 180 /* Remaining registers all zero */
185}; 181};
186 182
187static int wm8900_volatile_register(unsigned int reg) 183static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
188{ 184{
189 switch (reg) { 185 switch (reg) {
190 case WM8900_REG_ID: 186 case WM8900_REG_ID:
191 case WM8900_REG_POWER1:
192 return 1; 187 return 1;
193 default: 188 default:
194 return 0; 189 return 0;
@@ -614,10 +609,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
614 609
615static int wm8900_add_widgets(struct snd_soc_codec *codec) 610static int wm8900_add_widgets(struct snd_soc_codec *codec)
616{ 611{
617 snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, 612 struct snd_soc_dapm_context *dapm = &codec->dapm;
618 ARRAY_SIZE(wm8900_dapm_widgets));
619 613
620 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 614 snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets,
615 ARRAY_SIZE(wm8900_dapm_widgets));
616 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
621 617
622 return 0; 618 return 0;
623} 619}
@@ -627,8 +623,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
627 struct snd_soc_dai *dai) 623 struct snd_soc_dai *dai)
628{ 624{
629 struct snd_soc_pcm_runtime *rtd = substream->private_data; 625 struct snd_soc_pcm_runtime *rtd = substream->private_data;
630 struct snd_soc_device *socdev = rtd->socdev; 626 struct snd_soc_codec *codec = rtd->codec;
631 struct snd_soc_codec *codec = socdev->card->codec;
632 u16 reg; 627 u16 reg;
633 628
634 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; 629 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
@@ -1015,8 +1010,8 @@ static struct snd_soc_dai_ops wm8900_dai_ops = {
1015 .digital_mute = wm8900_digital_mute, 1010 .digital_mute = wm8900_digital_mute,
1016}; 1011};
1017 1012
1018struct snd_soc_dai wm8900_dai = { 1013static struct snd_soc_dai_driver wm8900_dai = {
1019 .name = "WM8900 HiFi", 1014 .name = "wm8900-hifi",
1020 .playback = { 1015 .playback = {
1021 .stream_name = "HiFi Playback", 1016 .stream_name = "HiFi Playback",
1022 .channels_min = 1, 1017 .channels_min = 1,
@@ -1033,7 +1028,6 @@ struct snd_soc_dai wm8900_dai = {
1033 }, 1028 },
1034 .ops = &wm8900_dai_ops, 1029 .ops = &wm8900_dai_ops,
1035}; 1030};
1036EXPORT_SYMBOL_GPL(wm8900_dai);
1037 1031
1038static int wm8900_set_bias_level(struct snd_soc_codec *codec, 1032static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1039 enum snd_soc_bias_level level) 1033 enum snd_soc_bias_level level)
@@ -1056,7 +1050,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1056 1050
1057 case SND_SOC_BIAS_STANDBY: 1051 case SND_SOC_BIAS_STANDBY:
1058 /* Charge capacitors if initial power up */ 1052 /* Charge capacitors if initial power up */
1059 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1053 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1060 /* STARTUP_BIAS_ENA on */ 1054 /* STARTUP_BIAS_ENA on */
1061 snd_soc_write(codec, WM8900_REG_POWER1, 1055 snd_soc_write(codec, WM8900_REG_POWER1,
1062 WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1056 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
@@ -1124,14 +1118,12 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1124 WM8900_REG_POWER2_SYSCLK_ENA); 1118 WM8900_REG_POWER2_SYSCLK_ENA);
1125 break; 1119 break;
1126 } 1120 }
1127 codec->bias_level = level; 1121 codec->dapm.bias_level = level;
1128 return 0; 1122 return 0;
1129} 1123}
1130 1124
1131static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) 1125static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state)
1132{ 1126{
1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1134 struct snd_soc_codec *codec = socdev->card->codec;
1135 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 1127 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1136 int fll_out = wm8900->fll_out; 1128 int fll_out = wm8900->fll_out;
1137 int fll_in = wm8900->fll_in; 1129 int fll_in = wm8900->fll_in;
@@ -1140,7 +1132,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1140 /* Stop the FLL in an orderly fashion */ 1132 /* Stop the FLL in an orderly fashion */
1141 ret = wm8900_set_fll(codec, 0, 0, 0); 1133 ret = wm8900_set_fll(codec, 0, 0, 0);
1142 if (ret != 0) { 1134 if (ret != 0) {
1143 dev_err(&pdev->dev, "Failed to stop FLL\n"); 1135 dev_err(codec->dev, "Failed to stop FLL\n");
1144 return ret; 1136 return ret;
1145 } 1137 }
1146 1138
@@ -1152,10 +1144,8 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1152 return 0; 1144 return 0;
1153} 1145}
1154 1146
1155static int wm8900_resume(struct platform_device *pdev) 1147static int wm8900_resume(struct snd_soc_codec *codec)
1156{ 1148{
1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1158 struct snd_soc_codec *codec = socdev->card->codec;
1159 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 1149 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1160 u16 *cache; 1150 u16 *cache;
1161 int i, ret; 1151 int i, ret;
@@ -1176,7 +1166,7 @@ static int wm8900_resume(struct platform_device *pdev)
1176 1166
1177 ret = wm8900_set_fll(codec, 0, fll_in, fll_out); 1167 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1178 if (ret != 0) { 1168 if (ret != 0) {
1179 dev_err(&pdev->dev, "Failed to restart FLL\n"); 1169 dev_err(codec->dev, "Failed to restart FLL\n");
1180 return ret; 1170 return ret;
1181 } 1171 }
1182 } 1172 }
@@ -1186,61 +1176,28 @@ static int wm8900_resume(struct platform_device *pdev)
1186 snd_soc_write(codec, i, cache[i]); 1176 snd_soc_write(codec, i, cache[i]);
1187 kfree(cache); 1177 kfree(cache);
1188 } else 1178 } else
1189 dev_err(&pdev->dev, "Unable to allocate register cache\n"); 1179 dev_err(codec->dev, "Unable to allocate register cache\n");
1190 1180
1191 return 0; 1181 return 0;
1192} 1182}
1193 1183
1194static struct snd_soc_codec *wm8900_codec; 1184static int wm8900_probe(struct snd_soc_codec *codec)
1195
1196static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1197 const struct i2c_device_id *id)
1198{ 1185{
1199 struct wm8900_priv *wm8900; 1186 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1200 struct snd_soc_codec *codec; 1187 int ret = 0, reg;
1201 unsigned int reg;
1202 int ret;
1203
1204 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1205 if (wm8900 == NULL)
1206 return -ENOMEM;
1207 1188
1208 codec = &wm8900->codec; 1189 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
1209 snd_soc_codec_set_drvdata(codec, wm8900);
1210 codec->reg_cache = &wm8900->reg_cache[0];
1211 codec->reg_cache_size = WM8900_MAXREG;
1212
1213 mutex_init(&codec->mutex);
1214 INIT_LIST_HEAD(&codec->dapm_widgets);
1215 INIT_LIST_HEAD(&codec->dapm_paths);
1216
1217 codec->name = "WM8900";
1218 codec->owner = THIS_MODULE;
1219 codec->dai = &wm8900_dai;
1220 codec->num_dai = 1;
1221 codec->control_data = i2c;
1222 codec->set_bias_level = wm8900_set_bias_level;
1223 codec->volatile_register = wm8900_volatile_register;
1224 codec->dev = &i2c->dev;
1225
1226 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1227 if (ret != 0) { 1190 if (ret != 0) {
1228 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); 1191 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1229 goto err; 1192 return ret;
1230 } 1193 }
1231 1194
1232 reg = snd_soc_read(codec, WM8900_REG_ID); 1195 reg = snd_soc_read(codec, WM8900_REG_ID);
1233 if (reg != 0x8900) { 1196 if (reg != 0x8900) {
1234 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg); 1197 dev_err(codec->dev, "Device is not a WM8900 - ID %x\n", reg);
1235 ret = -ENODEV; 1198 return -ENODEV;
1236 goto err;
1237 } 1199 }
1238 1200
1239 /* Read back from the chip */
1240 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1241 reg = (reg >> 12) & 0xf;
1242 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1243
1244 wm8900_reset(codec); 1201 wm8900_reset(codec);
1245 1202
1246 /* Turn the chip on */ 1203 /* Turn the chip on */
@@ -1271,43 +1228,94 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1271 /* Set the DAC and mixer output bias */ 1228 /* Set the DAC and mixer output bias */
1272 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1229 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1273 1230
1274 wm8900_dai.dev = &i2c->dev; 1231 snd_soc_add_controls(codec, wm8900_snd_controls,
1232 ARRAY_SIZE(wm8900_snd_controls));
1233 wm8900_add_widgets(codec);
1234
1235 return 0;
1236}
1275 1237
1276 wm8900_codec = codec; 1238/* power down chip */
1239static int wm8900_remove(struct snd_soc_codec *codec)
1240{
1241 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1242 return 0;
1243}
1277 1244
1278 ret = snd_soc_register_codec(codec); 1245static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
1279 if (ret != 0) { 1246 .probe = wm8900_probe,
1280 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); 1247 .remove = wm8900_remove,
1281 goto err; 1248 .suspend = wm8900_suspend,
1282 } 1249 .resume = wm8900_resume,
1250 .set_bias_level = wm8900_set_bias_level,
1251 .volatile_register = wm8900_volatile_register,
1252 .reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults),
1253 .reg_word_size = sizeof(u16),
1254 .reg_cache_default = wm8900_reg_defaults,
1255};
1283 1256
1284 ret = snd_soc_register_dai(&wm8900_dai); 1257#if defined(CONFIG_SPI_MASTER)
1285 if (ret != 0) { 1258static int __devinit wm8900_spi_probe(struct spi_device *spi)
1286 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret); 1259{
1287 goto err_codec; 1260 struct wm8900_priv *wm8900;
1288 } 1261 int ret;
1289 1262
1290 return ret; 1263 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1264 if (wm8900 == NULL)
1265 return -ENOMEM;
1266
1267 wm8900->control_type = SND_SOC_SPI;
1268 spi_set_drvdata(spi, wm8900);
1291 1269
1292err_codec: 1270 ret = snd_soc_register_codec(&spi->dev,
1293 snd_soc_unregister_codec(codec); 1271 &soc_codec_dev_wm8900, &wm8900_dai, 1);
1294err: 1272 if (ret < 0)
1295 kfree(wm8900); 1273 kfree(wm8900);
1296 wm8900_codec = NULL;
1297 return ret; 1274 return ret;
1298} 1275}
1299 1276
1300static __devexit int wm8900_i2c_remove(struct i2c_client *client) 1277static int __devexit wm8900_spi_remove(struct spi_device *spi)
1301{ 1278{
1302 snd_soc_unregister_dai(&wm8900_dai); 1279 snd_soc_unregister_codec(&spi->dev);
1303 snd_soc_unregister_codec(wm8900_codec); 1280 kfree(spi_get_drvdata(spi));
1281 return 0;
1282}
1304 1283
1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF); 1284static struct spi_driver wm8900_spi_driver = {
1285 .driver = {
1286 .name = "wm8900-codec",
1287 .owner = THIS_MODULE,
1288 },
1289 .probe = wm8900_spi_probe,
1290 .remove = __devexit_p(wm8900_spi_remove),
1291};
1292#endif /* CONFIG_SPI_MASTER */
1306 1293
1307 wm8900_dai.dev = NULL; 1294#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1308 kfree(snd_soc_codec_get_drvdata(wm8900_codec)); 1295static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1309 wm8900_codec = NULL; 1296 const struct i2c_device_id *id)
1297{
1298 struct wm8900_priv *wm8900;
1299 int ret;
1310 1300
1301 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1302 if (wm8900 == NULL)
1303 return -ENOMEM;
1304
1305 i2c_set_clientdata(i2c, wm8900);
1306 wm8900->control_type = SND_SOC_I2C;
1307
1308 ret = snd_soc_register_codec(&i2c->dev,
1309 &soc_codec_dev_wm8900, &wm8900_dai, 1);
1310 if (ret < 0)
1311 kfree(wm8900);
1312 return ret;
1313}
1314
1315static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1316{
1317 snd_soc_unregister_codec(&client->dev);
1318 kfree(i2c_get_clientdata(client));
1311 return 0; 1319 return 0;
1312} 1320}
1313 1321
@@ -1319,71 +1327,44 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1319 1327
1320static struct i2c_driver wm8900_i2c_driver = { 1328static struct i2c_driver wm8900_i2c_driver = {
1321 .driver = { 1329 .driver = {
1322 .name = "WM8900", 1330 .name = "wm8900-codec",
1323 .owner = THIS_MODULE, 1331 .owner = THIS_MODULE,
1324 }, 1332 },
1325 .probe = wm8900_i2c_probe, 1333 .probe = wm8900_i2c_probe,
1326 .remove = __devexit_p(wm8900_i2c_remove), 1334 .remove = __devexit_p(wm8900_i2c_remove),
1327 .id_table = wm8900_i2c_id, 1335 .id_table = wm8900_i2c_id,
1328}; 1336};
1337#endif
1329 1338
1330static int wm8900_probe(struct platform_device *pdev) 1339static int __init wm8900_modinit(void)
1331{ 1340{
1332 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1333 struct snd_soc_codec *codec;
1334 int ret = 0; 1341 int ret = 0;
1335 1342#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1336 if (!wm8900_codec) { 1343 ret = i2c_add_driver(&wm8900_i2c_driver);
1337 dev_err(&pdev->dev, "I2C client not yet instantiated\n"); 1344 if (ret != 0) {
1338 return -ENODEV; 1345 printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n",
1346 ret);
1339 } 1347 }
1340 1348#endif
1341 codec = wm8900_codec; 1349#if defined(CONFIG_SPI_MASTER)
1342 socdev->card->codec = codec; 1350 ret = spi_register_driver(&wm8900_spi_driver);
1343 1351 if (ret != 0) {
1344 /* Register pcms */ 1352 printk(KERN_ERR "Failed to register wm8900 SPI driver: %d\n",
1345 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1353 ret);
1346 if (ret < 0) {
1347 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1348 goto pcm_err;
1349 } 1354 }
1350 1355#endif
1351 snd_soc_add_controls(codec, wm8900_snd_controls,
1352 ARRAY_SIZE(wm8900_snd_controls));
1353 wm8900_add_widgets(codec);
1354
1355pcm_err:
1356 return ret; 1356 return ret;
1357} 1357}
1358
1359/* power down chip */
1360static int wm8900_remove(struct platform_device *pdev)
1361{
1362 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1363
1364 snd_soc_free_pcms(socdev);
1365 snd_soc_dapm_free(socdev);
1366
1367 return 0;
1368}
1369
1370struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1371 .probe = wm8900_probe,
1372 .remove = wm8900_remove,
1373 .suspend = wm8900_suspend,
1374 .resume = wm8900_resume,
1375};
1376EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1377
1378static int __init wm8900_modinit(void)
1379{
1380 return i2c_add_driver(&wm8900_i2c_driver);
1381}
1382module_init(wm8900_modinit); 1358module_init(wm8900_modinit);
1383 1359
1384static void __exit wm8900_exit(void) 1360static void __exit wm8900_exit(void)
1385{ 1361{
1362#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1386 i2c_del_driver(&wm8900_i2c_driver); 1363 i2c_del_driver(&wm8900_i2c_driver);
1364#endif
1365#if defined(CONFIG_SPI_MASTER)
1366 spi_unregister_driver(&wm8900_spi_driver);
1367#endif
1387} 1368}
1388module_exit(wm8900_exit); 1369module_exit(wm8900_exit);
1389 1370
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index fd15007d10c7..583f257e799b 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,7 +52,4 @@
52#define WM8900_DAC_CLKDIV_5_5 0x14 52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18 53#define WM8900_DAC_CLKDIV_6 0x18
54 54
55extern struct snd_soc_dai wm8900_dai;
56extern struct snd_soc_codec_device soc_codec_dev_wm8900;
57
58#endif 55#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index bf08282d5ee5..43e3d760766f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2,6 +2,7 @@
2 * wm8903.c -- WM8903 ALSA SoC Audio driver 2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics 4 * Copyright 2008 Wolfson Microelectronics
5 * Copyright 2011 NVIDIA, Inc.
5 * 6 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 8 *
@@ -19,6 +20,7 @@
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/completion.h> 21#include <linux/completion.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/gpio.h>
22#include <linux/pm.h> 24#include <linux/pm.h>
23#include <linux/i2c.h> 25#include <linux/i2c.h>
24#include <linux/platform_device.h> 26#include <linux/platform_device.h>
@@ -29,9 +31,9 @@
29#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
30#include <sound/tlv.h> 32#include <sound/tlv.h>
31#include <sound/soc.h> 33#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 34#include <sound/initval.h>
34#include <sound/wm8903.h> 35#include <sound/wm8903.h>
36#include <trace/events/asoc.h>
35 37
36#include "wm8903.h" 38#include "wm8903.h"
37 39
@@ -213,17 +215,19 @@ static u16 wm8903_reg_defaults[] = {
213}; 215};
214 216
215struct wm8903_priv { 217struct wm8903_priv {
216 struct snd_soc_codec codec; 218 struct snd_soc_codec *codec;
217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
218 219
219 int sysclk; 220 int sysclk;
221 int irq;
220 222
221 /* Reference counts */ 223 int fs;
222 int class_w_users; 224 int deemph;
223 int playback_active;
224 int capture_active;
225 225
226 struct completion wseq; 226 int dcs_pending;
227 int dcs_cache[4];
228
229 /* Reference count */
230 int class_w_users;
227 231
228 struct snd_soc_jack *mic_jack; 232 struct snd_soc_jack *mic_jack;
229 int mic_det; 233 int mic_det;
@@ -231,17 +235,22 @@ struct wm8903_priv {
231 int mic_last_report; 235 int mic_last_report;
232 int mic_delay; 236 int mic_delay;
233 237
234 struct snd_pcm_substream *master_substream; 238#ifdef CONFIG_GPIOLIB
235 struct snd_pcm_substream *slave_substream; 239 struct gpio_chip gpio_chip;
240#endif
236}; 241};
237 242
238static int wm8903_volatile_register(unsigned int reg) 243static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
239{ 244{
240 switch (reg) { 245 switch (reg) {
241 case WM8903_SW_RESET_AND_ID: 246 case WM8903_SW_RESET_AND_ID:
242 case WM8903_REVISION_NUMBER: 247 case WM8903_REVISION_NUMBER:
243 case WM8903_INTERRUPT_STATUS_1: 248 case WM8903_INTERRUPT_STATUS_1:
244 case WM8903_WRITE_SEQUENCER_4: 249 case WM8903_WRITE_SEQUENCER_4:
250 case WM8903_DC_SERVO_READBACK_1:
251 case WM8903_DC_SERVO_READBACK_2:
252 case WM8903_DC_SERVO_READBACK_3:
253 case WM8903_DC_SERVO_READBACK_4:
245 return 1; 254 return 1;
246 255
247 default: 256 default:
@@ -249,51 +258,6 @@ static int wm8903_volatile_register(unsigned int reg)
249 } 258 }
250} 259}
251 260
252static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
253{
254 u16 reg[5];
255 struct i2c_client *i2c = codec->control_data;
256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
257
258 BUG_ON(start > 48);
259
260 /* Enable the sequencer if it's not already on */
261 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
263 reg[0] | WM8903_WSEQ_ENA);
264
265 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
266
267 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
268 start | WM8903_WSEQ_START);
269
270 /* Wait for it to complete. If we have the interrupt wired up then
271 * that will break us out of the poll early.
272 */
273 do {
274 wait_for_completion_timeout(&wm8903->wseq,
275 msecs_to_jiffies(10));
276
277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
278 } while (reg[4] & WM8903_WSEQ_BUSY);
279
280 dev_dbg(&i2c->dev, "Sequence complete\n");
281
282 /* Disable the sequencer again if we enabled it */
283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
284
285 return 0;
286}
287
288static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
289{
290 int i;
291
292 /* There really ought to be something better we can do here :/ */
293 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
294 cache[i] = codec->hw_read(codec, i);
295}
296
297static void wm8903_reset(struct snd_soc_codec *codec) 261static void wm8903_reset(struct snd_soc_codec *codec)
298{ 262{
299 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); 263 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
@@ -301,11 +265,6 @@ static void wm8903_reset(struct snd_soc_codec *codec)
301 sizeof(wm8903_reg_defaults)); 265 sizeof(wm8903_reg_defaults));
302} 266}
303 267
304#define WM8903_OUTPUT_SHORT 0x8
305#define WM8903_OUTPUT_OUT 0x4
306#define WM8903_OUTPUT_INT 0x2
307#define WM8903_OUTPUT_IN 0x1
308
309static int wm8903_cp_event(struct snd_soc_dapm_widget *w, 268static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
310 struct snd_kcontrol *kcontrol, int event) 269 struct snd_kcontrol *kcontrol, int event)
311{ 270{
@@ -315,97 +274,101 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
315 return 0; 274 return 0;
316} 275}
317 276
318/* 277static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
319 * Event for headphone and line out amplifier power changes. Special 278 struct snd_kcontrol *kcontrol, int event)
320 * power up/down sequences are required in order to maximise pop/click
321 * performance.
322 */
323static int wm8903_output_event(struct snd_soc_dapm_widget *w,
324 struct snd_kcontrol *kcontrol, int event)
325{ 279{
326 struct snd_soc_codec *codec = w->codec; 280 struct snd_soc_codec *codec = w->codec;
327 u16 val; 281 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
328 u16 reg;
329 u16 dcs_reg;
330 u16 dcs_bit;
331 int shift;
332
333 switch (w->reg) {
334 case WM8903_POWER_MANAGEMENT_2:
335 reg = WM8903_ANALOGUE_HP_0;
336 dcs_bit = 0 + w->shift;
337 break;
338 case WM8903_POWER_MANAGEMENT_3:
339 reg = WM8903_ANALOGUE_LINEOUT_0;
340 dcs_bit = 2 + w->shift;
341 break;
342 default:
343 BUG();
344 return -EINVAL; /* Spurious warning from some compilers */
345 }
346 282
347 switch (w->shift) { 283 switch (event) {
348 case 0: 284 case SND_SOC_DAPM_POST_PMU:
349 shift = 0; 285 wm8903->dcs_pending |= 1 << w->shift;
350 break; 286 break;
351 case 1: 287 case SND_SOC_DAPM_PRE_PMD:
352 shift = 4; 288 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
289 1 << w->shift, 0);
353 break; 290 break;
354 default:
355 BUG();
356 return -EINVAL; /* Spurious warning from some compilers */
357 } 291 }
358 292
359 if (event & SND_SOC_DAPM_PRE_PMU) { 293 return 0;
360 val = snd_soc_read(codec, reg); 294}
295
296#define WM8903_DCS_MODE_WRITE_STOP 0
297#define WM8903_DCS_MODE_START_STOP 2
361 298
362 /* Short the output */ 299static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
363 val &= ~(WM8903_OUTPUT_SHORT << shift); 300 enum snd_soc_dapm_type event, int subseq)
364 snd_soc_write(codec, reg, val); 301{
365 } 302 struct snd_soc_codec *codec = container_of(dapm,
303 struct snd_soc_codec, dapm);
304 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
305 int dcs_mode = WM8903_DCS_MODE_WRITE_STOP;
306 int i, val;
366 307
367 if (event & SND_SOC_DAPM_POST_PMU) { 308 /* Complete any pending DC servo starts */
368 val = snd_soc_read(codec, reg); 309 if (wm8903->dcs_pending) {
310 dev_dbg(codec->dev, "Starting DC servo for %x\n",
311 wm8903->dcs_pending);
369 312
370 val |= (WM8903_OUTPUT_IN << shift); 313 /* If we've no cached values then we need to do startup */
371 snd_soc_write(codec, reg, val); 314 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
315 if (!(wm8903->dcs_pending & (1 << i)))
316 continue;
372 317
373 val |= (WM8903_OUTPUT_INT << shift); 318 if (wm8903->dcs_cache[i]) {
374 snd_soc_write(codec, reg, val); 319 dev_dbg(codec->dev,
320 "Restore DC servo %d value %x\n",
321 3 - i, wm8903->dcs_cache[i]);
322
323 snd_soc_write(codec, WM8903_DC_SERVO_4 + i,
324 wm8903->dcs_cache[i] & 0xff);
325 } else {
326 dev_dbg(codec->dev,
327 "Calibrate DC servo %d\n", 3 - i);
328 dcs_mode = WM8903_DCS_MODE_START_STOP;
329 }
330 }
375 331
376 /* Turn on the output ENA_OUTP */ 332 /* Don't trust the cache for analogue */
377 val |= (WM8903_OUTPUT_OUT << shift); 333 if (wm8903->class_w_users)
378 snd_soc_write(codec, reg, val); 334 dcs_mode = WM8903_DCS_MODE_START_STOP;
379 335
380 /* Enable the DC servo */ 336 snd_soc_update_bits(codec, WM8903_DC_SERVO_2,
381 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 337 WM8903_DCS_MODE_MASK, dcs_mode);
382 dcs_reg |= dcs_bit;
383 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
384 338
385 /* Remove the short */ 339 snd_soc_update_bits(codec, WM8903_DC_SERVO_0,
386 val |= (WM8903_OUTPUT_SHORT << shift); 340 WM8903_DCS_ENA_MASK, wm8903->dcs_pending);
387 snd_soc_write(codec, reg, val);
388 }
389 341
390 if (event & SND_SOC_DAPM_PRE_PMD) { 342 switch (dcs_mode) {
391 val = snd_soc_read(codec, reg); 343 case WM8903_DCS_MODE_WRITE_STOP:
344 break;
392 345
393 /* Short the output */ 346 case WM8903_DCS_MODE_START_STOP:
394 val &= ~(WM8903_OUTPUT_SHORT << shift); 347 msleep(270);
395 snd_soc_write(codec, reg, val);
396 348
397 /* Disable the DC servo */ 349 /* Cache the measured offsets for digital */
398 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); 350 if (wm8903->class_w_users)
399 dcs_reg &= ~dcs_bit; 351 break;
400 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
401 352
402 /* Then disable the intermediate and output stages */ 353 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) {
403 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 354 if (!(wm8903->dcs_pending & (1 << i)))
404 WM8903_OUTPUT_IN) << shift); 355 continue;
405 snd_soc_write(codec, reg, val);
406 }
407 356
408 return 0; 357 val = snd_soc_read(codec,
358 WM8903_DC_SERVO_READBACK_1 + i);
359 dev_dbg(codec->dev, "DC servo %d: %x\n",
360 3 - i, val);
361 wm8903->dcs_cache[i] = val;
362 }
363 break;
364
365 default:
366 pr_warn("DCS mode %d delay not set\n", dcs_mode);
367 break;
368 }
369
370 wm8903->dcs_pending = 0;
371 }
409} 372}
410 373
411/* 374/*
@@ -419,10 +382,10 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
419static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, 382static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
420 struct snd_ctl_elem_value *ucontrol) 383 struct snd_ctl_elem_value *ucontrol)
421{ 384{
422 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 385 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
386 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
423 struct snd_soc_codec *codec = widget->codec; 387 struct snd_soc_codec *codec = widget->codec;
424 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 388 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
425 struct i2c_client *i2c = codec->control_data;
426 u16 reg; 389 u16 reg;
427 int ret; 390 int ret;
428 391
@@ -431,7 +394,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
431 /* Turn it off if we're about to enable bypass */ 394 /* Turn it off if we're about to enable bypass */
432 if (ucontrol->value.integer.value[0]) { 395 if (ucontrol->value.integer.value[0]) {
433 if (wm8903->class_w_users == 0) { 396 if (wm8903->class_w_users == 0) {
434 dev_dbg(&i2c->dev, "Disabling Class W\n"); 397 dev_dbg(codec->dev, "Disabling Class W\n");
435 snd_soc_write(codec, WM8903_CLASS_W_0, reg & 398 snd_soc_write(codec, WM8903_CLASS_W_0, reg &
436 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); 399 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
437 } 400 }
@@ -444,14 +407,14 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
444 /* If we've just disabled the last bypass path turn Class W on */ 407 /* If we've just disabled the last bypass path turn Class W on */
445 if (!ucontrol->value.integer.value[0]) { 408 if (!ucontrol->value.integer.value[0]) {
446 if (wm8903->class_w_users == 1) { 409 if (wm8903->class_w_users == 1) {
447 dev_dbg(&i2c->dev, "Enabling Class W\n"); 410 dev_dbg(codec->dev, "Enabling Class W\n");
448 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 411 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
449 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 412 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
450 } 413 }
451 wm8903->class_w_users--; 414 wm8903->class_w_users--;
452 } 415 }
453 416
454 dev_dbg(&i2c->dev, "Bypass use count now %d\n", 417 dev_dbg(codec->dev, "Bypass use count now %d\n",
455 wm8903->class_w_users); 418 wm8903->class_w_users);
456 419
457 return ret; 420 return ret;
@@ -464,6 +427,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
464 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 427 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
465 428
466 429
430static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
431
432static int wm8903_set_deemph(struct snd_soc_codec *codec)
433{
434 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
435 int val, i, best;
436
437 /* If we're using deemphasis select the nearest available sample
438 * rate.
439 */
440 if (wm8903->deemph) {
441 best = 1;
442 for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
443 if (abs(wm8903_deemph[i] - wm8903->fs) <
444 abs(wm8903_deemph[best] - wm8903->fs))
445 best = i;
446 }
447
448 val = best << WM8903_DEEMPH_SHIFT;
449 } else {
450 best = 0;
451 val = 0;
452 }
453
454 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
455 best, wm8903_deemph[best]);
456
457 return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
458 WM8903_DEEMPH_MASK, val);
459}
460
461static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
462 struct snd_ctl_elem_value *ucontrol)
463{
464 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
465 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
466
467 ucontrol->value.enumerated.item[0] = wm8903->deemph;
468
469 return 0;
470}
471
472static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
477 int deemph = ucontrol->value.enumerated.item[0];
478 int ret = 0;
479
480 if (deemph > 1)
481 return -EINVAL;
482
483 mutex_lock(&codec->mutex);
484 if (wm8903->deemph != deemph) {
485 wm8903->deemph = deemph;
486
487 wm8903_set_deemph(codec);
488
489 ret = 1;
490 }
491 mutex_unlock(&codec->mutex);
492
493 return ret;
494}
495
467/* ALSA can only do steps of .01dB */ 496/* ALSA can only do steps of .01dB */
468static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 497static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
469 498
@@ -476,6 +505,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
476static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); 505static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
477static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); 506static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
478 507
508static const char *hpf_mode_text[] = {
509 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
510};
511
512static const struct soc_enum hpf_mode =
513 SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
514
515static const char *osr_text[] = {
516 "Low power", "High performance"
517};
518
519static const struct soc_enum adc_osr =
520 SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);
521
522static const struct soc_enum dac_osr =
523 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);
524
479static const char *drc_slope_text[] = { 525static const char *drc_slope_text[] = {
480 "1", "1/2", "1/4", "1/8", "1/16", "0" 526 "1", "1/2", "1/4", "1/8", "1/16", "0"
481}; 527};
@@ -538,13 +584,6 @@ static const char *mute_mode_text[] = {
538static const struct soc_enum mute_mode = 584static const struct soc_enum mute_mode =
539 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); 585 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
540 586
541static const char *dac_deemphasis_text[] = {
542 "Disabled", "32kHz", "44.1kHz", "48kHz"
543};
544
545static const struct soc_enum dac_deemphasis =
546 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
547
548static const char *companding_text[] = { 587static const char *companding_text[] = {
549 "ulaw", "alaw" 588 "ulaw", "alaw"
550}; 589};
@@ -596,6 +635,29 @@ static const struct soc_enum lsidetone_enum =
596static const struct soc_enum rsidetone_enum = 635static const struct soc_enum rsidetone_enum =
597 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); 636 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text);
598 637
638static const char *adcinput_text[] = {
639 "ADC", "DMIC"
640};
641
642static const struct soc_enum adcinput_enum =
643 SOC_ENUM_SINGLE(WM8903_CLOCK_RATE_TEST_4, 9, 2, adcinput_text);
644
645static const char *aif_text[] = {
646 "Left", "Right"
647};
648
649static const struct soc_enum lcapture_enum =
650 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text);
651
652static const struct soc_enum rcapture_enum =
653 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text);
654
655static const struct soc_enum lplay_enum =
656 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text);
657
658static const struct soc_enum rplay_enum =
659 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text);
660
599static const struct snd_kcontrol_new wm8903_snd_controls[] = { 661static const struct snd_kcontrol_new wm8903_snd_controls[] = {
600 662
601/* Input PGAs - No TLV since the scale depends on PGA mode */ 663/* Input PGAs - No TLV since the scale depends on PGA mode */
@@ -614,6 +676,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
614 6, 1, 0), 676 6, 1, 0),
615 677
616/* ADCs */ 678/* ADCs */
679SOC_ENUM("ADC OSR", adc_osr),
680SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
681SOC_ENUM("HPF Mode", hpf_mode),
617SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 682SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
618SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 683SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
619SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 684SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
@@ -635,7 +700,7 @@ SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
635SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), 700SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
636 701
637SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, 702SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
638 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), 703 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
639SOC_ENUM("ADC Companding Mode", adc_companding), 704SOC_ENUM("ADC Companding Mode", adc_companding),
640SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), 705SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0),
641 706
@@ -643,14 +708,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
643 12, 0, digital_sidetone_tlv), 708 12, 0, digital_sidetone_tlv),
644 709
645/* DAC */ 710/* DAC */
711SOC_ENUM("DAC OSR", dac_osr),
646SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, 712SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
647 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), 713 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
648SOC_ENUM("DAC Soft Mute Rate", soft_mute), 714SOC_ENUM("DAC Soft Mute Rate", soft_mute),
649SOC_ENUM("DAC Mute Mode", mute_mode), 715SOC_ENUM("DAC Mute Mode", mute_mode),
650SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), 716SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
651SOC_ENUM("DAC De-emphasis", dac_deemphasis),
652SOC_ENUM("DAC Companding Mode", dac_companding), 717SOC_ENUM("DAC Companding Mode", dac_companding),
653SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), 718SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
719SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
720 wm8903_get_deemph, wm8903_put_deemph),
654 721
655/* Headphones */ 722/* Headphones */
656SOC_DOUBLE_R("Headphone Switch", 723SOC_DOUBLE_R("Headphone Switch",
@@ -708,6 +775,21 @@ static const struct snd_kcontrol_new lsidetone_mux =
708static const struct snd_kcontrol_new rsidetone_mux = 775static const struct snd_kcontrol_new rsidetone_mux =
709 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); 776 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
710 777
778static const struct snd_kcontrol_new adcinput_mux =
779 SOC_DAPM_ENUM("ADC Input", adcinput_enum);
780
781static const struct snd_kcontrol_new lcapture_mux =
782 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
783
784static const struct snd_kcontrol_new rcapture_mux =
785 SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum);
786
787static const struct snd_kcontrol_new lplay_mux =
788 SOC_DAPM_ENUM("Left Playback Mux", lplay_enum);
789
790static const struct snd_kcontrol_new rplay_mux =
791 SOC_DAPM_ENUM("Right Playback Mux", rplay_enum);
792
711static const struct snd_kcontrol_new left_output_mixer[] = { 793static const struct snd_kcontrol_new left_output_mixer[] = {
712SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 794SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
713SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), 795SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
@@ -746,6 +828,7 @@ SND_SOC_DAPM_INPUT("IN2L"),
746SND_SOC_DAPM_INPUT("IN2R"), 828SND_SOC_DAPM_INPUT("IN2R"),
747SND_SOC_DAPM_INPUT("IN3L"), 829SND_SOC_DAPM_INPUT("IN3L"),
748SND_SOC_DAPM_INPUT("IN3R"), 830SND_SOC_DAPM_INPUT("IN3R"),
831SND_SOC_DAPM_INPUT("DMICDAT"),
749 832
750SND_SOC_DAPM_OUTPUT("HPOUTL"), 833SND_SOC_DAPM_OUTPUT("HPOUTL"),
751SND_SOC_DAPM_OUTPUT("HPOUTR"), 834SND_SOC_DAPM_OUTPUT("HPOUTR"),
@@ -771,14 +854,29 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
771SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), 854SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0),
772SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), 855SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0),
773 856
774SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), 857SND_SOC_DAPM_MUX("Left ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
775SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), 858SND_SOC_DAPM_MUX("Right ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux),
859
860SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0),
861SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0),
862
863SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux),
864SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux),
865
866SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
867SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
776 868
777SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), 869SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux),
778SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), 870SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux),
779 871
780SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), 872SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0),
781SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), 873SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0),
874
875SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux),
876SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux),
877
878SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0),
879SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0),
782 880
783SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, 881SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0,
784 left_output_mixer, ARRAY_SIZE(left_output_mixer)), 882 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
@@ -790,23 +888,51 @@ SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0,
790SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, 888SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0,
791 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), 889 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
792 890
793SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 891SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_POWER_MANAGEMENT_2,
794 1, 0, NULL, 0, wm8903_output_event, 892 1, 0, NULL, 0),
795 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 893SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_POWER_MANAGEMENT_2,
796 SND_SOC_DAPM_PRE_PMD), 894 0, 0, NULL, 0),
797SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 895
798 0, 0, NULL, 0, wm8903_output_event, 896SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_POWER_MANAGEMENT_3, 1, 0,
799 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 897 NULL, 0),
800 SND_SOC_DAPM_PRE_PMD), 898SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_POWER_MANAGEMENT_3, 0, 0,
801 899 NULL, 0),
802SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, 900
803 NULL, 0, wm8903_output_event, 901SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0),
804 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 902SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0),
805 SND_SOC_DAPM_PRE_PMD), 903SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 2, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0),
806SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, 904SND_SOC_DAPM_PGA_S("HPL_ENA", 1, WM8903_ANALOGUE_HP_0, 4, 0, NULL, 0),
807 NULL, 0, wm8903_output_event, 905SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0),
808 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 906SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0),
809 SND_SOC_DAPM_PRE_PMD), 907SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 2, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0),
908SND_SOC_DAPM_PGA_S("HPR_ENA", 1, WM8903_ANALOGUE_HP_0, 0, 0, NULL, 0),
909
910SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0,
911 NULL, 0),
912SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0,
913 NULL, 0),
914SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 2, WM8903_ANALOGUE_LINEOUT_0, 5, 0,
915 NULL, 0),
916SND_SOC_DAPM_PGA_S("LINEOUTL_ENA", 1, WM8903_ANALOGUE_LINEOUT_0, 4, 0,
917 NULL, 0),
918SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0,
919 NULL, 0),
920SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0,
921 NULL, 0),
922SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 2, WM8903_ANALOGUE_LINEOUT_0, 1, 0,
923 NULL, 0),
924SND_SOC_DAPM_PGA_S("LINEOUTR_ENA", 1, WM8903_ANALOGUE_LINEOUT_0, 0, 0,
925 NULL, 0),
926
927SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0),
928SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event,
929 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
930SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event,
931 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
932SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event,
933 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
934SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event,
935 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
810 936
811SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, 937SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0,
812 NULL, 0), 938 NULL, 0),
@@ -816,9 +942,17 @@ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0,
816SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, 942SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0,
817 wm8903_cp_event, SND_SOC_DAPM_POST_PMU), 943 wm8903_cp_event, SND_SOC_DAPM_POST_PMU),
818SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), 944SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0),
945SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0),
819}; 946};
820 947
821static const struct snd_soc_dapm_route intercon[] = { 948static const struct snd_soc_dapm_route wm8903_intercon[] = {
949
950 { "CLK_DSP", NULL, "CLK_SYS" },
951 { "Mic Bias", NULL, "CLK_SYS" },
952 { "HPL_DCS", NULL, "CLK_SYS" },
953 { "HPR_DCS", NULL, "CLK_SYS" },
954 { "LINEOUTL_DCS", NULL, "CLK_SYS" },
955 { "LINEOUTR_DCS", NULL, "CLK_SYS" },
822 956
823 { "Left Input Mux", "IN1L", "IN1L" }, 957 { "Left Input Mux", "IN1L", "IN1L" },
824 { "Left Input Mux", "IN2L", "IN2L" }, 958 { "Left Input Mux", "IN2L", "IN2L" },
@@ -860,18 +994,41 @@ static const struct snd_soc_dapm_route intercon[] = {
860 { "Left Input PGA", NULL, "Left Input Mode Mux" }, 994 { "Left Input PGA", NULL, "Left Input Mode Mux" },
861 { "Right Input PGA", NULL, "Right Input Mode Mux" }, 995 { "Right Input PGA", NULL, "Right Input Mode Mux" },
862 996
863 { "ADCL", NULL, "Left Input PGA" }, 997 { "Left ADC Input", "ADC", "Left Input PGA" },
998 { "Left ADC Input", "DMIC", "DMICDAT" },
999 { "Right ADC Input", "ADC", "Right Input PGA" },
1000 { "Right ADC Input", "DMIC", "DMICDAT" },
1001
1002 { "Left Capture Mux", "Left", "ADCL" },
1003 { "Left Capture Mux", "Right", "ADCR" },
1004
1005 { "Right Capture Mux", "Left", "ADCL" },
1006 { "Right Capture Mux", "Right", "ADCR" },
1007
1008 { "AIFTXL", NULL, "Left Capture Mux" },
1009 { "AIFTXR", NULL, "Right Capture Mux" },
1010
1011 { "ADCL", NULL, "Left ADC Input" },
864 { "ADCL", NULL, "CLK_DSP" }, 1012 { "ADCL", NULL, "CLK_DSP" },
865 { "ADCR", NULL, "Right Input PGA" }, 1013 { "ADCR", NULL, "Right ADC Input" },
866 { "ADCR", NULL, "CLK_DSP" }, 1014 { "ADCR", NULL, "CLK_DSP" },
867 1015
1016 { "Left Playback Mux", "Left", "AIFRXL" },
1017 { "Left Playback Mux", "Right", "AIFRXR" },
1018
1019 { "Right Playback Mux", "Left", "AIFRXL" },
1020 { "Right Playback Mux", "Right", "AIFRXR" },
1021
868 { "DACL Sidetone", "Left", "ADCL" }, 1022 { "DACL Sidetone", "Left", "ADCL" },
869 { "DACL Sidetone", "Right", "ADCR" }, 1023 { "DACL Sidetone", "Right", "ADCR" },
870 { "DACR Sidetone", "Left", "ADCL" }, 1024 { "DACR Sidetone", "Left", "ADCL" },
871 { "DACR Sidetone", "Right", "ADCR" }, 1025 { "DACR Sidetone", "Right", "ADCR" },
872 1026
1027 { "DACL", NULL, "Left Playback Mux" },
873 { "DACL", NULL, "DACL Sidetone" }, 1028 { "DACL", NULL, "DACL Sidetone" },
874 { "DACL", NULL, "CLK_DSP" }, 1029 { "DACL", NULL, "CLK_DSP" },
1030
1031 { "DACR", NULL, "Right Playback Mux" },
875 { "DACR", NULL, "DACR Sidetone" }, 1032 { "DACR", NULL, "DACR Sidetone" },
876 { "DACR", NULL, "CLK_DSP" }, 1033 { "DACR", NULL, "CLK_DSP" },
877 1034
@@ -904,11 +1061,39 @@ static const struct snd_soc_dapm_route intercon[] = {
904 { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, 1061 { "Left Speaker PGA", NULL, "Left Speaker Mixer" },
905 { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, 1062 { "Right Speaker PGA", NULL, "Right Speaker Mixer" },
906 1063
907 { "HPOUTL", NULL, "Left Headphone Output PGA" }, 1064 { "HPL_ENA", NULL, "Left Headphone Output PGA" },
908 { "HPOUTR", NULL, "Right Headphone Output PGA" }, 1065 { "HPR_ENA", NULL, "Right Headphone Output PGA" },
909 1066 { "HPL_ENA_DLY", NULL, "HPL_ENA" },
910 { "LINEOUTL", NULL, "Left Line Output PGA" }, 1067 { "HPR_ENA_DLY", NULL, "HPR_ENA" },
911 { "LINEOUTR", NULL, "Right Line Output PGA" }, 1068 { "LINEOUTL_ENA", NULL, "Left Line Output PGA" },
1069 { "LINEOUTR_ENA", NULL, "Right Line Output PGA" },
1070 { "LINEOUTL_ENA_DLY", NULL, "LINEOUTL_ENA" },
1071 { "LINEOUTR_ENA_DLY", NULL, "LINEOUTR_ENA" },
1072
1073 { "HPL_DCS", NULL, "DCS Master" },
1074 { "HPR_DCS", NULL, "DCS Master" },
1075 { "LINEOUTL_DCS", NULL, "DCS Master" },
1076 { "LINEOUTR_DCS", NULL, "DCS Master" },
1077
1078 { "HPL_DCS", NULL, "HPL_ENA_DLY" },
1079 { "HPR_DCS", NULL, "HPR_ENA_DLY" },
1080 { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" },
1081 { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" },
1082
1083 { "HPL_ENA_OUTP", NULL, "HPL_DCS" },
1084 { "HPR_ENA_OUTP", NULL, "HPR_DCS" },
1085 { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" },
1086 { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" },
1087
1088 { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" },
1089 { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" },
1090 { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" },
1091 { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" },
1092
1093 { "HPOUTL", NULL, "HPL_RMV_SHORT" },
1094 { "HPOUTR", NULL, "HPR_RMV_SHORT" },
1095 { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" },
1096 { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" },
912 1097
913 { "LOP", NULL, "Left Speaker PGA" }, 1098 { "LOP", NULL, "Left Speaker PGA" },
914 { "LON", NULL, "Left Speaker PGA" }, 1099 { "LON", NULL, "Left Speaker PGA" },
@@ -922,78 +1107,116 @@ static const struct snd_soc_dapm_route intercon[] = {
922 { "Right Line Output PGA", NULL, "Charge Pump" }, 1107 { "Right Line Output PGA", NULL, "Charge Pump" },
923}; 1108};
924 1109
925static int wm8903_add_widgets(struct snd_soc_codec *codec)
926{
927 snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
928 ARRAY_SIZE(wm8903_dapm_widgets));
929
930 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
931
932 return 0;
933}
934
935static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1110static int wm8903_set_bias_level(struct snd_soc_codec *codec,
936 enum snd_soc_bias_level level) 1111 enum snd_soc_bias_level level)
937{ 1112{
938 struct i2c_client *i2c = codec->control_data;
939 u16 reg, reg2;
940
941 switch (level) { 1113 switch (level) {
942 case SND_SOC_BIAS_ON: 1114 case SND_SOC_BIAS_ON:
1115 break;
1116
943 case SND_SOC_BIAS_PREPARE: 1117 case SND_SOC_BIAS_PREPARE:
944 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1118 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
945 reg &= ~(WM8903_VMID_RES_MASK); 1119 WM8903_VMID_RES_MASK,
946 reg |= WM8903_VMID_RES_50K; 1120 WM8903_VMID_RES_50K);
947 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
948 break; 1121 break;
949 1122
950 case SND_SOC_BIAS_STANDBY: 1123 case SND_SOC_BIAS_STANDBY:
951 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1124 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
952 snd_soc_write(codec, WM8903_CLOCK_RATES_2, 1125 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
953 WM8903_CLK_SYS_ENA); 1126 WM8903_POBCTRL | WM8903_ISEL_MASK |
954 1127 WM8903_STARTUP_BIAS_ENA |
955 /* Change DC servo dither level in startup sequence */ 1128 WM8903_BIAS_ENA,
956 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); 1129 WM8903_POBCTRL |
957 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); 1130 (2 << WM8903_ISEL_SHIFT) |
958 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); 1131 WM8903_STARTUP_BIAS_ENA);
959 1132
960 wm8903_run_sequence(codec, 0); 1133 snd_soc_update_bits(codec,
961 wm8903_sync_reg_cache(codec, codec->reg_cache); 1134 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
962 1135 WM8903_SPK_DISCHARGE,
963 /* Enable low impedence charge pump output */ 1136 WM8903_SPK_DISCHARGE);
964 reg = snd_soc_read(codec, 1137
965 WM8903_CONTROL_INTERFACE_TEST_1); 1138 msleep(33);
966 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, 1139
967 reg | WM8903_TEST_KEY); 1140 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
968 reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1); 1141 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
969 snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1, 1142 WM8903_SPKL_ENA | WM8903_SPKR_ENA);
970 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK); 1143
971 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, 1144 snd_soc_update_bits(codec,
972 reg); 1145 WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0,
1146 WM8903_SPK_DISCHARGE, 0);
1147
1148 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1149 WM8903_VMID_TIE_ENA |
1150 WM8903_BUFIO_ENA |
1151 WM8903_VMID_IO_ENA |
1152 WM8903_VMID_SOFT_MASK |
1153 WM8903_VMID_RES_MASK |
1154 WM8903_VMID_BUF_ENA,
1155 WM8903_VMID_TIE_ENA |
1156 WM8903_BUFIO_ENA |
1157 WM8903_VMID_IO_ENA |
1158 (2 << WM8903_VMID_SOFT_SHIFT) |
1159 WM8903_VMID_RES_250K |
1160 WM8903_VMID_BUF_ENA);
1161
1162 msleep(129);
1163
1164 snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5,
1165 WM8903_SPKL_ENA | WM8903_SPKR_ENA,
1166 0);
1167
1168 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1169 WM8903_VMID_SOFT_MASK, 0);
1170
1171 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1172 WM8903_VMID_RES_MASK,
1173 WM8903_VMID_RES_50K);
1174
1175 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1176 WM8903_BIAS_ENA | WM8903_POBCTRL,
1177 WM8903_BIAS_ENA);
973 1178
974 /* By default no bypass paths are enabled so 1179 /* By default no bypass paths are enabled so
975 * enable Class W support. 1180 * enable Class W support.
976 */ 1181 */
977 dev_dbg(&i2c->dev, "Enabling Class W\n"); 1182 dev_dbg(codec->dev, "Enabling Class W\n");
978 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 1183 snd_soc_update_bits(codec, WM8903_CLASS_W_0,
979 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 1184 WM8903_CP_DYN_FREQ |
1185 WM8903_CP_DYN_V,
1186 WM8903_CP_DYN_FREQ |
1187 WM8903_CP_DYN_V);
980 } 1188 }
981 1189
982 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1190 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
983 reg &= ~(WM8903_VMID_RES_MASK); 1191 WM8903_VMID_RES_MASK,
984 reg |= WM8903_VMID_RES_250K; 1192 WM8903_VMID_RES_250K);
985 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
986 break; 1193 break;
987 1194
988 case SND_SOC_BIAS_OFF: 1195 case SND_SOC_BIAS_OFF:
989 wm8903_run_sequence(codec, 32); 1196 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
990 reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2); 1197 WM8903_BIAS_ENA, 0);
991 reg &= ~WM8903_CLK_SYS_ENA; 1198
992 snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg); 1199 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1200 WM8903_VMID_SOFT_MASK,
1201 2 << WM8903_VMID_SOFT_SHIFT);
1202
1203 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1204 WM8903_VMID_BUF_ENA, 0);
1205
1206 msleep(290);
1207
1208 snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0,
1209 WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA |
1210 WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK |
1211 WM8903_VMID_SOFT_MASK |
1212 WM8903_VMID_BUF_ENA, 0);
1213
1214 snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0,
1215 WM8903_STARTUP_BIAS_ENA, 0);
993 break; 1216 break;
994 } 1217 }
995 1218
996 codec->bias_level = level; 1219 codec->dapm.bias_level = level;
997 1220
998 return 0; 1221 return 0;
999} 1222}
@@ -1224,70 +1447,13 @@ static struct {
1224 { 0, 0 }, 1447 { 0, 0 },
1225}; 1448};
1226 1449
1227static int wm8903_startup(struct snd_pcm_substream *substream,
1228 struct snd_soc_dai *dai)
1229{
1230 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1231 struct snd_soc_device *socdev = rtd->socdev;
1232 struct snd_soc_codec *codec = socdev->card->codec;
1233 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1234 struct i2c_client *i2c = codec->control_data;
1235 struct snd_pcm_runtime *master_runtime;
1236
1237 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1238 wm8903->playback_active++;
1239 else
1240 wm8903->capture_active++;
1241
1242 /* The DAI has shared clocks so if we already have a playback or
1243 * capture going then constrain this substream to match it.
1244 */
1245 if (wm8903->master_substream) {
1246 master_runtime = wm8903->master_substream->runtime;
1247
1248 dev_dbg(&i2c->dev, "Constraining to %d bits\n",
1249 master_runtime->sample_bits);
1250
1251 snd_pcm_hw_constraint_minmax(substream->runtime,
1252 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1253 master_runtime->sample_bits,
1254 master_runtime->sample_bits);
1255
1256 wm8903->slave_substream = substream;
1257 } else
1258 wm8903->master_substream = substream;
1259
1260 return 0;
1261}
1262
1263static void wm8903_shutdown(struct snd_pcm_substream *substream,
1264 struct snd_soc_dai *dai)
1265{
1266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1267 struct snd_soc_device *socdev = rtd->socdev;
1268 struct snd_soc_codec *codec = socdev->card->codec;
1269 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1270
1271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1272 wm8903->playback_active--;
1273 else
1274 wm8903->capture_active--;
1275
1276 if (wm8903->master_substream == substream)
1277 wm8903->master_substream = wm8903->slave_substream;
1278
1279 wm8903->slave_substream = NULL;
1280}
1281
1282static int wm8903_hw_params(struct snd_pcm_substream *substream, 1450static int wm8903_hw_params(struct snd_pcm_substream *substream,
1283 struct snd_pcm_hw_params *params, 1451 struct snd_pcm_hw_params *params,
1284 struct snd_soc_dai *dai) 1452 struct snd_soc_dai *dai)
1285{ 1453{
1286 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1454 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1287 struct snd_soc_device *socdev = rtd->socdev; 1455 struct snd_soc_codec *codec =rtd->codec;
1288 struct snd_soc_codec *codec = socdev->card->codec;
1289 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1456 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1290 struct i2c_client *i2c = codec->control_data;
1291 int fs = params_rate(params); 1457 int fs = params_rate(params);
1292 int bclk; 1458 int bclk;
1293 int bclk_div; 1459 int bclk_div;
@@ -1305,11 +1471,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1305 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); 1471 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
1306 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 1472 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1307 1473
1308 if (substream == wm8903->slave_substream) {
1309 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
1310 return 0;
1311 }
1312
1313 /* Enable sloping stopband filter for low sample rates */ 1474 /* Enable sloping stopband filter for low sample rates */
1314 if (fs <= 24000) 1475 if (fs <= 24000)
1315 dac_digital1 |= WM8903_DAC_SB_FILT; 1476 dac_digital1 |= WM8903_DAC_SB_FILT;
@@ -1327,20 +1488,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1327 } 1488 }
1328 } 1489 }
1329 1490
1330 /* Constraints should stop us hitting this but let's make sure */ 1491 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1331 if (wm8903->capture_active)
1332 switch (sample_rates[dsp_config].rate) {
1333 case 88200:
1334 case 96000:
1335 dev_err(&i2c->dev, "%dHz unsupported by ADC\n",
1336 fs);
1337 return -EINVAL;
1338
1339 default:
1340 break;
1341 }
1342
1343 dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1344 clock1 &= ~WM8903_SAMPLE_RATE_MASK; 1492 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1345 clock1 |= sample_rates[dsp_config].value; 1493 clock1 |= sample_rates[dsp_config].value;
1346 1494
@@ -1366,7 +1514,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1366 return -EINVAL; 1514 return -EINVAL;
1367 } 1515 }
1368 1516
1369 dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n", 1517 dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n",
1370 wm8903->sysclk, fs); 1518 wm8903->sysclk, fs);
1371 1519
1372 /* We may not have an MCLK which allows us to generate exactly 1520 /* We may not have an MCLK which allows us to generate exactly
@@ -1401,12 +1549,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1401 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT; 1549 clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
1402 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT; 1550 clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
1403 1551
1404 dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n", 1552 dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
1405 clk_sys_ratios[clk_config].rate, 1553 clk_sys_ratios[clk_config].rate,
1406 clk_sys_ratios[clk_config].mode, 1554 clk_sys_ratios[clk_config].mode,
1407 clk_sys_ratios[clk_config].div); 1555 clk_sys_ratios[clk_config].div);
1408 1556
1409 dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys); 1557 dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
1410 1558
1411 /* We may not get quite the right frequency if using 1559 /* We may not get quite the right frequency if using
1412 * approximate clocks so look for the closest match that is 1560 * approximate clocks so look for the closest match that is
@@ -1428,13 +1576,16 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1428 aif2 &= ~WM8903_BCLK_DIV_MASK; 1576 aif2 &= ~WM8903_BCLK_DIV_MASK;
1429 aif3 &= ~WM8903_LRCLK_RATE_MASK; 1577 aif3 &= ~WM8903_LRCLK_RATE_MASK;
1430 1578
1431 dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", 1579 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
1432 bclk_divs[bclk_div].ratio / 10, bclk, 1580 bclk_divs[bclk_div].ratio / 10, bclk,
1433 (clk_sys * 10) / bclk_divs[bclk_div].ratio); 1581 (clk_sys * 10) / bclk_divs[bclk_div].ratio);
1434 1582
1435 aif2 |= bclk_divs[bclk_div].div; 1583 aif2 |= bclk_divs[bclk_div].div;
1436 aif3 |= bclk / fs; 1584 aif3 |= bclk / fs;
1437 1585
1586 wm8903->fs = params_rate(params);
1587 wm8903_set_deemph(codec);
1588
1438 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); 1589 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
1439 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); 1590 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
1440 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1591 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
@@ -1486,7 +1637,7 @@ int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
1486 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, 1637 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
1487 irq_mask); 1638 irq_mask);
1488 1639
1489 if (det && shrt) { 1640 if (det || shrt) {
1490 /* Enable mic detection, this may not have been set through 1641 /* Enable mic detection, this may not have been set through
1491 * platform data (eg, if the defaults are OK). */ 1642 * platform data (eg, if the defaults are OK). */
1492 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1643 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
@@ -1504,8 +1655,8 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1504 1655
1505static irqreturn_t wm8903_irq(int irq, void *data) 1656static irqreturn_t wm8903_irq(int irq, void *data)
1506{ 1657{
1507 struct wm8903_priv *wm8903 = data; 1658 struct snd_soc_codec *codec = data;
1508 struct snd_soc_codec *codec = &wm8903->codec; 1659 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1509 int mic_report; 1660 int mic_report;
1510 int int_pol; 1661 int int_pol;
1511 int int_val = 0; 1662 int int_val = 0;
@@ -1514,8 +1665,7 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1514 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; 1665 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1515 1666
1516 if (int_val & WM8903_WSEQ_BUSY_EINT) { 1667 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1517 dev_dbg(codec->dev, "Write sequencer done\n"); 1668 dev_warn(codec->dev, "Write sequencer done\n");
1518 complete(&wm8903->wseq);
1519 } 1669 }
1520 1670
1521 /* 1671 /*
@@ -1528,6 +1678,11 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1528 mic_report = wm8903->mic_last_report; 1678 mic_report = wm8903->mic_last_report;
1529 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); 1679 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
1530 1680
1681#ifndef CONFIG_SND_SOC_WM8903_MODULE
1682 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
1683 trace_snd_soc_jack_irq(dev_name(codec->dev));
1684#endif
1685
1531 if (int_val & WM8903_MICSHRT_EINT) { 1686 if (int_val & WM8903_MICSHRT_EINT) {
1532 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); 1687 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
1533 1688
@@ -1578,16 +1733,14 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1578 SNDRV_PCM_FMTBIT_S24_LE) 1733 SNDRV_PCM_FMTBIT_S24_LE)
1579 1734
1580static struct snd_soc_dai_ops wm8903_dai_ops = { 1735static struct snd_soc_dai_ops wm8903_dai_ops = {
1581 .startup = wm8903_startup,
1582 .shutdown = wm8903_shutdown,
1583 .hw_params = wm8903_hw_params, 1736 .hw_params = wm8903_hw_params,
1584 .digital_mute = wm8903_digital_mute, 1737 .digital_mute = wm8903_digital_mute,
1585 .set_fmt = wm8903_set_dai_fmt, 1738 .set_fmt = wm8903_set_dai_fmt,
1586 .set_sysclk = wm8903_set_dai_sysclk, 1739 .set_sysclk = wm8903_set_dai_sysclk,
1587}; 1740};
1588 1741
1589struct snd_soc_dai wm8903_dai = { 1742static struct snd_soc_dai_driver wm8903_dai = {
1590 .name = "WM8903", 1743 .name = "wm8903-hifi",
1591 .playback = { 1744 .playback = {
1592 .stream_name = "Playback", 1745 .stream_name = "Playback",
1593 .channels_min = 2, 1746 .channels_min = 2,
@@ -1605,23 +1758,16 @@ struct snd_soc_dai wm8903_dai = {
1605 .ops = &wm8903_dai_ops, 1758 .ops = &wm8903_dai_ops,
1606 .symmetric_rates = 1, 1759 .symmetric_rates = 1,
1607}; 1760};
1608EXPORT_SYMBOL_GPL(wm8903_dai);
1609 1761
1610static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) 1762static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state)
1611{ 1763{
1612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1613 struct snd_soc_codec *codec = socdev->card->codec;
1614
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1764 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1616 1765
1617 return 0; 1766 return 0;
1618} 1767}
1619 1768
1620static int wm8903_resume(struct platform_device *pdev) 1769static int wm8903_resume(struct snd_soc_codec *codec)
1621{ 1770{
1622 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1623 struct snd_soc_codec *codec = socdev->card->codec;
1624 struct i2c_client *i2c = codec->control_data;
1625 int i; 1771 int i;
1626 u16 *reg_cache = codec->reg_cache; 1772 u16 *reg_cache = codec->reg_cache;
1627 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), 1773 u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
@@ -1637,77 +1783,177 @@ static int wm8903_resume(struct platform_device *pdev)
1637 snd_soc_write(codec, i, tmp_cache[i]); 1783 snd_soc_write(codec, i, tmp_cache[i]);
1638 kfree(tmp_cache); 1784 kfree(tmp_cache);
1639 } else { 1785 } else {
1640 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1786 dev_err(codec->dev, "Failed to allocate temporary cache\n");
1641 } 1787 }
1642 1788
1643 return 0; 1789 return 0;
1644} 1790}
1645 1791
1646static struct snd_soc_codec *wm8903_codec; 1792#ifdef CONFIG_GPIOLIB
1793static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip)
1794{
1795 return container_of(chip, struct wm8903_priv, gpio_chip);
1796}
1647 1797
1648static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, 1798static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
1649 const struct i2c_device_id *id)
1650{ 1799{
1651 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); 1800 if (offset >= WM8903_NUM_GPIO)
1652 struct wm8903_priv *wm8903; 1801 return -EINVAL;
1653 struct snd_soc_codec *codec;
1654 int ret, i;
1655 int trigger, irq_pol;
1656 u16 val;
1657 1802
1658 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1803 return 0;
1659 if (wm8903 == NULL) 1804}
1660 return -ENOMEM;
1661 1805
1662 codec = &wm8903->codec; 1806static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1807{
1808 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1809 struct snd_soc_codec *codec = wm8903->codec;
1810 unsigned int mask, val;
1663 1811
1664 mutex_init(&codec->mutex); 1812 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK;
1665 INIT_LIST_HEAD(&codec->dapm_widgets); 1813 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
1666 INIT_LIST_HEAD(&codec->dapm_paths); 1814 WM8903_GP1_DIR;
1667 1815
1668 codec->dev = &i2c->dev; 1816 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1669 codec->name = "WM8903"; 1817 mask, val);
1670 codec->owner = THIS_MODULE; 1818}
1671 codec->bias_level = SND_SOC_BIAS_OFF; 1819
1672 codec->set_bias_level = wm8903_set_bias_level; 1820static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1673 codec->dai = &wm8903_dai; 1821{
1674 codec->num_dai = 1; 1822 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1675 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); 1823 struct snd_soc_codec *codec = wm8903->codec;
1676 codec->reg_cache = &wm8903->reg_cache[0]; 1824 int reg;
1677 snd_soc_codec_set_drvdata(codec, wm8903);
1678 codec->volatile_register = wm8903_volatile_register;
1679 init_completion(&wm8903->wseq);
1680 1825
1681 i2c_set_clientdata(i2c, codec); 1826 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset);
1682 codec->control_data = i2c; 1827
1828 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
1829}
1830
1831static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1832 unsigned offset, int value)
1833{
1834 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1835 struct snd_soc_codec *codec = wm8903->codec;
1836 unsigned int mask, val;
1837
1838 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK;
1839 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
1840 (value << WM8903_GP2_LVL_SHIFT);
1841
1842 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1843 mask, val);
1844}
1845
1846static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1847{
1848 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1849 struct snd_soc_codec *codec = wm8903->codec;
1850
1851 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset,
1852 WM8903_GP1_LVL_MASK,
1853 !!value << WM8903_GP1_LVL_SHIFT);
1854}
1855
1856static struct gpio_chip wm8903_template_chip = {
1857 .label = "wm8903",
1858 .owner = THIS_MODULE,
1859 .request = wm8903_gpio_request,
1860 .direction_input = wm8903_gpio_direction_in,
1861 .get = wm8903_gpio_get,
1862 .direction_output = wm8903_gpio_direction_out,
1863 .set = wm8903_gpio_set,
1864 .can_sleep = 1,
1865};
1866
1867static void wm8903_init_gpio(struct snd_soc_codec *codec)
1868{
1869 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1870 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1871 int ret;
1872
1873 wm8903->gpio_chip = wm8903_template_chip;
1874 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
1875 wm8903->gpio_chip.dev = codec->dev;
1876
1877 if (pdata && pdata->gpio_base)
1878 wm8903->gpio_chip.base = pdata->gpio_base;
1879 else
1880 wm8903->gpio_chip.base = -1;
1881
1882 ret = gpiochip_add(&wm8903->gpio_chip);
1883 if (ret != 0)
1884 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
1885}
1886
1887static void wm8903_free_gpio(struct snd_soc_codec *codec)
1888{
1889 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1890 int ret;
1891
1892 ret = gpiochip_remove(&wm8903->gpio_chip);
1893 if (ret != 0)
1894 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
1895}
1896#else
1897static void wm8903_init_gpio(struct snd_soc_codec *codec)
1898{
1899}
1900
1901static void wm8903_free_gpio(struct snd_soc_codec *codec)
1902{
1903}
1904#endif
1905
1906static int wm8903_probe(struct snd_soc_codec *codec)
1907{
1908 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
1909 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1910 int ret, i;
1911 int trigger, irq_pol;
1912 u16 val;
1913
1914 wm8903->codec = codec;
1683 1915
1684 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1916 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1685 if (ret != 0) { 1917 if (ret != 0) {
1686 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); 1918 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1687 goto err; 1919 return ret;
1688 } 1920 }
1689 1921
1690 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); 1922 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
1691 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1923 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1692 dev_err(&i2c->dev, 1924 dev_err(codec->dev,
1693 "Device with ID register %x is not a WM8903\n", val); 1925 "Device with ID register %x is not a WM8903\n", val);
1694 return -ENODEV; 1926 return -ENODEV;
1695 } 1927 }
1696 1928
1697 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); 1929 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1698 dev_info(&i2c->dev, "WM8903 revision %d\n", 1930 dev_info(codec->dev, "WM8903 revision %c\n",
1699 val & WM8903_CHIP_REV_MASK); 1931 (val & WM8903_CHIP_REV_MASK) + 'A');
1700 1932
1701 wm8903_reset(codec); 1933 wm8903_reset(codec);
1702 1934
1703 /* Set up GPIOs and microphone detection */ 1935 /* Set up GPIOs and microphone detection */
1704 if (pdata) { 1936 if (pdata) {
1937 bool mic_gpio = false;
1938
1705 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { 1939 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1706 if (!pdata->gpio_cfg[i]) 1940 if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG)
1707 continue; 1941 continue;
1708 1942
1709 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, 1943 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1710 pdata->gpio_cfg[i] & 0xffff); 1944 pdata->gpio_cfg[i] & 0xffff);
1945
1946 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
1947 >> WM8903_GP1_FN_SHIFT;
1948
1949 switch (val) {
1950 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
1951 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
1952 mic_gpio = true;
1953 break;
1954 default:
1955 break;
1956 }
1711 } 1957 }
1712 1958
1713 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, 1959 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
@@ -1718,10 +1964,18 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1718 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, 1964 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1719 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); 1965 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1720 1966
1967 /* If microphone detection is enabled by pdata but
1968 * detected via IRQ then interrupts can be lost before
1969 * the machine driver has set up microphone detection
1970 * IRQs as the IRQs are clear on read. The detection
1971 * will be enabled when the machine driver configures.
1972 */
1973 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
1974
1721 wm8903->mic_delay = pdata->micdet_delay; 1975 wm8903->mic_delay = pdata->micdet_delay;
1722 } 1976 }
1723 1977
1724 if (i2c->irq) { 1978 if (wm8903->irq) {
1725 if (pdata && pdata->irq_active_low) { 1979 if (pdata && pdata->irq_active_low) {
1726 trigger = IRQF_TRIGGER_LOW; 1980 trigger = IRQF_TRIGGER_LOW;
1727 irq_pol = WM8903_IRQ_POL; 1981 irq_pol = WM8903_IRQ_POL;
@@ -1733,13 +1987,13 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1733 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, 1987 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1734 WM8903_IRQ_POL, irq_pol); 1988 WM8903_IRQ_POL, irq_pol);
1735 1989
1736 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq, 1990 ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
1737 trigger | IRQF_ONESHOT, 1991 trigger | IRQF_ONESHOT,
1738 "wm8903", wm8903); 1992 "wm8903", codec);
1739 if (ret != 0) { 1993 if (ret != 0) {
1740 dev_err(&i2c->dev, "Failed to request IRQ: %d\n", 1994 dev_err(codec->dev, "Failed to request IRQ: %d\n",
1741 ret); 1995 ret);
1742 goto err; 1996 return ret;
1743 } 1997 }
1744 1998
1745 /* Enable write sequencer interrupts */ 1999 /* Enable write sequencer interrupts */
@@ -1777,137 +2031,107 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1777 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); 2031 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1778 2032
1779 /* Enable DAC soft mute by default */ 2033 /* Enable DAC soft mute by default */
1780 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 2034 snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
1781 val |= WM8903_DAC_MUTEMODE; 2035 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
1782 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); 2036 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
1783 2037
1784 wm8903_dai.dev = &i2c->dev; 2038 snd_soc_add_controls(codec, wm8903_snd_controls,
1785 wm8903_codec = codec; 2039 ARRAY_SIZE(wm8903_snd_controls));
1786
1787 ret = snd_soc_register_codec(codec);
1788 if (ret != 0) {
1789 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1790 goto err_irq;
1791 }
1792
1793 ret = snd_soc_register_dai(&wm8903_dai);
1794 if (ret != 0) {
1795 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1796 goto err_codec;
1797 }
1798 2040
1799 return ret; 2041 wm8903_init_gpio(codec);
1800 2042
1801err_codec:
1802 snd_soc_unregister_codec(codec);
1803err_irq:
1804 if (i2c->irq)
1805 free_irq(i2c->irq, wm8903);
1806err:
1807 wm8903_codec = NULL;
1808 kfree(wm8903);
1809 return ret; 2043 return ret;
1810} 2044}
1811 2045
1812static __devexit int wm8903_i2c_remove(struct i2c_client *client) 2046/* power down chip */
2047static int wm8903_remove(struct snd_soc_codec *codec)
1813{ 2048{
1814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 2049 wm8903_free_gpio(codec);
1815 struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec); 2050 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
2051 return 0;
2052}
1816 2053
1817 snd_soc_unregister_dai(&wm8903_dai); 2054static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
1818 snd_soc_unregister_codec(codec); 2055 .probe = wm8903_probe,
2056 .remove = wm8903_remove,
2057 .suspend = wm8903_suspend,
2058 .resume = wm8903_resume,
2059 .set_bias_level = wm8903_set_bias_level,
2060 .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults),
2061 .reg_word_size = sizeof(u16),
2062 .reg_cache_default = wm8903_reg_defaults,
2063 .volatile_register = wm8903_volatile_register,
2064 .seq_notifier = wm8903_seq_notifier,
2065 .dapm_widgets = wm8903_dapm_widgets,
2066 .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets),
2067 .dapm_routes = wm8903_intercon,
2068 .num_dapm_routes = ARRAY_SIZE(wm8903_intercon),
2069};
1819 2070
1820 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 2071#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2072static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2073 const struct i2c_device_id *id)
2074{
2075 struct wm8903_priv *wm8903;
2076 int ret;
1821 2077
1822 if (client->irq) 2078 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1823 free_irq(client->irq, priv); 2079 if (wm8903 == NULL)
2080 return -ENOMEM;
1824 2081
1825 kfree(priv); 2082 i2c_set_clientdata(i2c, wm8903);
2083 wm8903->irq = i2c->irq;
1826 2084
1827 wm8903_codec = NULL; 2085 ret = snd_soc_register_codec(&i2c->dev,
1828 wm8903_dai.dev = NULL; 2086 &soc_codec_dev_wm8903, &wm8903_dai, 1);
2087 if (ret < 0)
2088 kfree(wm8903);
2089 return ret;
2090}
1829 2091
2092static __devexit int wm8903_i2c_remove(struct i2c_client *client)
2093{
2094 snd_soc_unregister_codec(&client->dev);
2095 kfree(i2c_get_clientdata(client));
1830 return 0; 2096 return 0;
1831} 2097}
1832 2098
1833/* i2c codec control layer */
1834static const struct i2c_device_id wm8903_i2c_id[] = { 2099static const struct i2c_device_id wm8903_i2c_id[] = {
1835 { "wm8903", 0 }, 2100 { "wm8903", 0 },
1836 { } 2101 { }
1837}; 2102};
1838MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); 2103MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
1839 2104
1840static struct i2c_driver wm8903_i2c_driver = { 2105static struct i2c_driver wm8903_i2c_driver = {
1841 .driver = { 2106 .driver = {
1842 .name = "WM8903", 2107 .name = "wm8903",
1843 .owner = THIS_MODULE, 2108 .owner = THIS_MODULE,
1844 }, 2109 },
1845 .probe = wm8903_i2c_probe, 2110 .probe = wm8903_i2c_probe,
1846 .remove = __devexit_p(wm8903_i2c_remove), 2111 .remove = __devexit_p(wm8903_i2c_remove),
1847 .id_table = wm8903_i2c_id, 2112 .id_table = wm8903_i2c_id,
1848}; 2113};
2114#endif
1849 2115
1850static int wm8903_probe(struct platform_device *pdev) 2116static int __init wm8903_modinit(void)
1851{ 2117{
1852 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1853 int ret = 0; 2118 int ret = 0;
1854 2119#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1855 if (!wm8903_codec) { 2120 ret = i2c_add_driver(&wm8903_i2c_driver);
1856 dev_err(&pdev->dev, "I2C device not yet probed\n"); 2121 if (ret != 0) {
1857 goto err; 2122 printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
1858 } 2123 ret);
1859
1860 socdev->card->codec = wm8903_codec;
1861
1862 /* register pcms */
1863 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1864 if (ret < 0) {
1865 dev_err(&pdev->dev, "failed to create pcms\n");
1866 goto err;
1867 } 2124 }
1868 2125#endif
1869 snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls,
1870 ARRAY_SIZE(wm8903_snd_controls));
1871 wm8903_add_widgets(socdev->card->codec);
1872
1873 return ret;
1874
1875err:
1876 return ret; 2126 return ret;
1877} 2127}
1878
1879/* power down chip */
1880static int wm8903_remove(struct platform_device *pdev)
1881{
1882 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1883 struct snd_soc_codec *codec = socdev->card->codec;
1884
1885 if (codec->control_data)
1886 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1887
1888 snd_soc_free_pcms(socdev);
1889 snd_soc_dapm_free(socdev);
1890
1891 return 0;
1892}
1893
1894struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1895 .probe = wm8903_probe,
1896 .remove = wm8903_remove,
1897 .suspend = wm8903_suspend,
1898 .resume = wm8903_resume,
1899};
1900EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1901
1902static int __init wm8903_modinit(void)
1903{
1904 return i2c_add_driver(&wm8903_i2c_driver);
1905}
1906module_init(wm8903_modinit); 2128module_init(wm8903_modinit);
1907 2129
1908static void __exit wm8903_exit(void) 2130static void __exit wm8903_exit(void)
1909{ 2131{
2132#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1910 i2c_del_driver(&wm8903_i2c_driver); 2133 i2c_del_driver(&wm8903_i2c_driver);
2134#endif
1911} 2135}
1912module_exit(wm8903_exit); 2136module_exit(wm8903_exit);
1913 2137
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index ce384a2ad820..db949311c0f2 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -15,17 +15,10 @@
15 15
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17 17
18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20
21extern int wm8903_mic_detect(struct snd_soc_codec *codec, 18extern int wm8903_mic_detect(struct snd_soc_codec *codec,
22 struct snd_soc_jack *jack, 19 struct snd_soc_jack *jack,
23 int det, int shrt); 20 int det, int shrt);
24 21
25#define WM8903_MCLK_DIV_2 1
26#define WM8903_CLK_SYS 2
27#define WM8903_BCLK 3
28#define WM8903_LRCLK 4
29 22
30/* 23/*
31 * Register values. 24 * Register values.
@@ -82,6 +75,14 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
82#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41 75#define WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0 0x41
83#define WM8903_DC_SERVO_0 0x43 76#define WM8903_DC_SERVO_0 0x43
84#define WM8903_DC_SERVO_2 0x45 77#define WM8903_DC_SERVO_2 0x45
78#define WM8903_DC_SERVO_4 0x47
79#define WM8903_DC_SERVO_5 0x48
80#define WM8903_DC_SERVO_6 0x49
81#define WM8903_DC_SERVO_7 0x4A
82#define WM8903_DC_SERVO_READBACK_1 0x51
83#define WM8903_DC_SERVO_READBACK_2 0x52
84#define WM8903_DC_SERVO_READBACK_3 0x53
85#define WM8903_DC_SERVO_READBACK_4 0x54
85#define WM8903_ANALOGUE_HP_0 0x5A 86#define WM8903_ANALOGUE_HP_0 0x5A
86#define WM8903_ANALOGUE_LINEOUT_0 0x5E 87#define WM8903_ANALOGUE_LINEOUT_0 0x5E
87#define WM8903_CHARGE_PUMP_0 0x62 88#define WM8903_CHARGE_PUMP_0 0x62
@@ -101,8 +102,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
101#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A 102#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
102#define WM8903_INTERRUPT_POLARITY_1 0x7B 103#define WM8903_INTERRUPT_POLARITY_1 0x7B
103#define WM8903_INTERRUPT_CONTROL 0x7E 104#define WM8903_INTERRUPT_CONTROL 0x7E
104#define WM8903_CONTROL_INTERFACE_TEST_1 0x81
105#define WM8903_CHARGE_PUMP_TEST_1 0x95
106#define WM8903_CLOCK_RATE_TEST_4 0xA4 105#define WM8903_CLOCK_RATE_TEST_4 0xA4
107#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC 106#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
108 107
@@ -174,7 +173,7 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
174 173
175#define WM8903_VMID_RES_50K 2 174#define WM8903_VMID_RES_50K 2
176#define WM8903_VMID_RES_250K 3 175#define WM8903_VMID_RES_250K 3
177#define WM8903_VMID_RES_5K 4 176#define WM8903_VMID_RES_5K 6
178 177
179/* 178/*
180 * R8 (0x08) - Analogue DAC 0 179 * R8 (0x08) - Analogue DAC 0
@@ -1209,25 +1208,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
1209#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */ 1208#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
1210 1209
1211/* 1210/*
1212 * R129 (0x81) - Control Interface Test 1
1213 */
1214#define WM8903_USER_KEY 0x0002 /* USER_KEY */
1215#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */
1216#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */
1217#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */
1218#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */
1219#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */
1220#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */
1221#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */
1222
1223/*
1224 * R149 (0x95) - Charge Pump Test 1
1225 */
1226#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */
1227#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */
1228#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */
1229
1230/*
1231 * R164 (0xA4) - Clock Rate Test 4 1211 * R164 (0xA4) - Clock Rate Test 4
1232 */ 1212 */
1233#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */ 1213#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f7dcabf6283c..9b3bba4df5b3 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -24,16 +24,12 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <sound/wm8904.h> 29#include <sound/wm8904.h>
31 30
32#include "wm8904.h" 31#include "wm8904.h"
33 32
34static struct snd_soc_codec *wm8904_codec;
35struct snd_soc_codec_device soc_codec_dev_wm8904;
36
37enum wm8904_type { 33enum wm8904_type {
38 WM8904, 34 WM8904,
39 WM8912, 35 WM8912,
@@ -52,10 +48,9 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
52 48
53/* codec private data */ 49/* codec private data */
54struct wm8904_priv { 50struct wm8904_priv {
55 struct snd_soc_codec codec;
56 u16 reg_cache[WM8904_MAX_REGISTER + 1];
57 51
58 enum wm8904_type devtype; 52 enum wm8904_type devtype;
53 void *control_data;
59 54
60 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; 55 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
61 56
@@ -601,7 +596,7 @@ static struct {
601 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ 596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
602}; 597};
603 598
604static int wm8904_volatile_register(unsigned int reg) 599static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
605{ 600{
606 return wm8904_access[reg].vol; 601 return wm8904_access[reg].vol;
607} 602}
@@ -689,7 +684,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol) 684 struct snd_ctl_elem_value *ucontrol)
690{ 685{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 686 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 687 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
693 struct wm8904_pdata *pdata = wm8904->pdata; 688 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0]; 689 int value = ucontrol->value.integer.value[0];
695 690
@@ -760,7 +755,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol) 755 struct snd_ctl_elem_value *ucontrol)
761{ 756{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 757 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 758 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
764 struct wm8904_pdata *pdata = wm8904->pdata; 759 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0]; 760 int value = ucontrol->value.integer.value[0];
766 761
@@ -820,7 +815,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 815 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
821 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 816 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
822 817
823 return wm8904->deemph; 818 ucontrol->value.enumerated.item[0] = wm8904->deemph;
819 return 0;
824} 820}
825 821
826static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, 822static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -1430,10 +1426,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
1430static int wm8904_add_widgets(struct snd_soc_codec *codec) 1426static int wm8904_add_widgets(struct snd_soc_codec *codec)
1431{ 1427{
1432 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 1428 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1429 struct snd_soc_dapm_context *dapm = &codec->dapm;
1433 1430
1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, 1431 snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
1435 ARRAY_SIZE(wm8904_core_dapm_widgets)); 1432 ARRAY_SIZE(wm8904_core_dapm_widgets));
1436 snd_soc_dapm_add_routes(codec, core_intercon, 1433 snd_soc_dapm_add_routes(dapm, core_intercon,
1437 ARRAY_SIZE(core_intercon)); 1434 ARRAY_SIZE(core_intercon));
1438 1435
1439 switch (wm8904->devtype) { 1436 switch (wm8904->devtype) {
@@ -1445,20 +1442,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1445 snd_soc_add_controls(codec, wm8904_snd_controls, 1442 snd_soc_add_controls(codec, wm8904_snd_controls,
1446 ARRAY_SIZE(wm8904_snd_controls)); 1443 ARRAY_SIZE(wm8904_snd_controls));
1447 1444
1448 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, 1445 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
1449 ARRAY_SIZE(wm8904_adc_dapm_widgets)); 1446 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1450 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, 1447 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
1451 ARRAY_SIZE(wm8904_dac_dapm_widgets)); 1448 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1452 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, 1449 snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
1453 ARRAY_SIZE(wm8904_dapm_widgets)); 1450 ARRAY_SIZE(wm8904_dapm_widgets));
1454 1451
1455 snd_soc_dapm_add_routes(codec, core_intercon, 1452 snd_soc_dapm_add_routes(dapm, core_intercon,
1456 ARRAY_SIZE(core_intercon)); 1453 ARRAY_SIZE(core_intercon));
1457 snd_soc_dapm_add_routes(codec, adc_intercon, 1454 snd_soc_dapm_add_routes(dapm, adc_intercon,
1458 ARRAY_SIZE(adc_intercon)); 1455 ARRAY_SIZE(adc_intercon));
1459 snd_soc_dapm_add_routes(codec, dac_intercon, 1456 snd_soc_dapm_add_routes(dapm, dac_intercon,
1460 ARRAY_SIZE(dac_intercon)); 1457 ARRAY_SIZE(dac_intercon));
1461 snd_soc_dapm_add_routes(codec, wm8904_intercon, 1458 snd_soc_dapm_add_routes(dapm, wm8904_intercon,
1462 ARRAY_SIZE(wm8904_intercon)); 1459 ARRAY_SIZE(wm8904_intercon));
1463 break; 1460 break;
1464 1461
@@ -1466,17 +1463,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1466 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1463 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1467 ARRAY_SIZE(wm8904_dac_snd_controls)); 1464 ARRAY_SIZE(wm8904_dac_snd_controls));
1468 1465
1469 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, 1466 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
1470 ARRAY_SIZE(wm8904_dac_dapm_widgets)); 1467 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1471 1468
1472 snd_soc_dapm_add_routes(codec, dac_intercon, 1469 snd_soc_dapm_add_routes(dapm, dac_intercon,
1473 ARRAY_SIZE(dac_intercon)); 1470 ARRAY_SIZE(dac_intercon));
1474 snd_soc_dapm_add_routes(codec, wm8912_intercon, 1471 snd_soc_dapm_add_routes(dapm, wm8912_intercon,
1475 ARRAY_SIZE(wm8912_intercon)); 1472 ARRAY_SIZE(wm8912_intercon));
1476 break; 1473 break;
1477 } 1474 }
1478 1475
1479 snd_soc_dapm_new_widgets(codec); 1476 snd_soc_dapm_new_widgets(dapm);
1480 return 0; 1477 return 0;
1481} 1478}
1482 1479
@@ -1592,7 +1589,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
1592 - wm8904->fs); 1589 - wm8904->fs);
1593 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { 1590 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1594 cur_val = abs((wm8904->sysclk_rate / 1591 cur_val = abs((wm8904->sysclk_rate /
1595 clk_sys_rates[i].ratio) - wm8904->fs);; 1592 clk_sys_rates[i].ratio) - wm8904->fs);
1596 if (cur_val < best_val) { 1593 if (cur_val < best_val) {
1597 best = i; 1594 best = i;
1598 best_val = cur_val; 1595 best_val = cur_val;
@@ -1898,7 +1895,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1898 1895
1899 pr_debug("Fvco=%dHz\n", target); 1896 pr_debug("Fvco=%dHz\n", target);
1900 1897
1901 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 1898 /* Find an appropriate FLL_FRATIO and factor it out of the target */
1902 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 1899 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1903 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 1900 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1904 fll_div->fll_fratio = fll_fratios[i].fll_fratio; 1901 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
@@ -2095,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2095 2092
2096static void wm8904_sync_cache(struct snd_soc_codec *codec) 2093static void wm8904_sync_cache(struct snd_soc_codec *codec)
2097{ 2094{
2098 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 2095 u16 *reg_cache = codec->reg_cache;
2099 int i; 2096 int i;
2100 2097
2101 if (!codec->cache_sync) 2098 if (!codec->cache_sync)
@@ -2106,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
2106 /* Sync back cached values if they're different from the 2103 /* Sync back cached values if they're different from the
2107 * hardware default. 2104 * hardware default.
2108 */ 2105 */
2109 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) { 2106 for (i = 1; i < codec->driver->reg_cache_size; i++) {
2110 if (!wm8904_access[i].writable) 2107 if (!wm8904_access[i].writable)
2111 continue; 2108 continue;
2112 2109
2113 if (wm8904->reg_cache[i] == wm8904_reg[i]) 2110 if (reg_cache[i] == wm8904_reg[i])
2114 continue; 2111 continue;
2115 2112
2116 snd_soc_write(codec, i, wm8904->reg_cache[i]); 2113 snd_soc_write(codec, i, reg_cache[i]);
2117 } 2114 }
2118 2115
2119 codec->cache_sync = 0; 2116 codec->cache_sync = 0;
@@ -2141,7 +2138,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2141 break; 2138 break;
2142 2139
2143 case SND_SOC_BIAS_STANDBY: 2140 case SND_SOC_BIAS_STANDBY:
2144 if (codec->bias_level == SND_SOC_BIAS_OFF) { 2141 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2145 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), 2142 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2146 wm8904->supplies); 2143 wm8904->supplies);
2147 if (ret != 0) { 2144 if (ret != 0) {
@@ -2200,7 +2197,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2200 wm8904->supplies); 2197 wm8904->supplies);
2201 break; 2198 break;
2202 } 2199 }
2203 codec->bias_level = level; 2200 codec->dapm.bias_level = level;
2204 return 0; 2201 return 0;
2205} 2202}
2206 2203
@@ -2218,8 +2215,8 @@ static struct snd_soc_dai_ops wm8904_dai_ops = {
2218 .digital_mute = wm8904_digital_mute, 2215 .digital_mute = wm8904_digital_mute,
2219}; 2216};
2220 2217
2221struct snd_soc_dai wm8904_dai = { 2218static struct snd_soc_dai_driver wm8904_dai = {
2222 .name = "WM8904", 2219 .name = "wm8904-hifi",
2223 .playback = { 2220 .playback = {
2224 .stream_name = "Playback", 2221 .stream_name = "Playback",
2225 .channels_min = 2, 2222 .channels_min = 2,
@@ -2237,24 +2234,17 @@ struct snd_soc_dai wm8904_dai = {
2237 .ops = &wm8904_dai_ops, 2234 .ops = &wm8904_dai_ops,
2238 .symmetric_rates = 1, 2235 .symmetric_rates = 1,
2239}; 2236};
2240EXPORT_SYMBOL_GPL(wm8904_dai);
2241 2237
2242#ifdef CONFIG_PM 2238#ifdef CONFIG_PM
2243static int wm8904_suspend(struct platform_device *pdev, pm_message_t state) 2239static int wm8904_suspend(struct snd_soc_codec *codec, pm_message_t state)
2244{ 2240{
2245 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2246 struct snd_soc_codec *codec = socdev->card->codec;
2247
2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); 2241 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2249 2242
2250 return 0; 2243 return 0;
2251} 2244}
2252 2245
2253static int wm8904_resume(struct platform_device *pdev) 2246static int wm8904_resume(struct snd_soc_codec *codec)
2254{ 2247{
2255 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2256 struct snd_soc_codec *codec = socdev->card->codec;
2257
2258 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2248 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2259 2249
2260 return 0; 2250 return 0;
@@ -2264,9 +2254,9 @@ static int wm8904_resume(struct platform_device *pdev)
2264#define wm8904_resume NULL 2254#define wm8904_resume NULL
2265#endif 2255#endif
2266 2256
2267static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904) 2257static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
2268{ 2258{
2269 struct snd_soc_codec *codec = &wm8904->codec; 2259 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2270 struct wm8904_pdata *pdata = wm8904->pdata; 2260 struct wm8904_pdata *pdata = wm8904->pdata;
2271 struct snd_kcontrol_new control = 2261 struct snd_kcontrol_new control =
2272 SOC_ENUM_EXT("EQ Mode", 2262 SOC_ENUM_EXT("EQ Mode",
@@ -2315,20 +2305,20 @@ static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2315 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; 2305 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2316 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; 2306 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2317 2307
2318 ret = snd_soc_add_controls(&wm8904->codec, &control, 1); 2308 ret = snd_soc_add_controls(codec, &control, 1);
2319 if (ret != 0) 2309 if (ret != 0)
2320 dev_err(wm8904->codec.dev, 2310 dev_err(codec->dev,
2321 "Failed to add ReTune Mobile control: %d\n", ret); 2311 "Failed to add ReTune Mobile control: %d\n", ret);
2322} 2312}
2323 2313
2324static void wm8904_handle_pdata(struct wm8904_priv *wm8904) 2314static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2325{ 2315{
2326 struct snd_soc_codec *codec = &wm8904->codec; 2316 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2327 struct wm8904_pdata *pdata = wm8904->pdata; 2317 struct wm8904_pdata *pdata = wm8904->pdata;
2328 int ret, i; 2318 int ret, i;
2329 2319
2330 if (!pdata) { 2320 if (!pdata) {
2331 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, 2321 snd_soc_add_controls(codec, wm8904_eq_controls,
2332 ARRAY_SIZE(wm8904_eq_controls)); 2322 ARRAY_SIZE(wm8904_eq_controls));
2333 return; 2323 return;
2334 } 2324 }
@@ -2344,7 +2334,7 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2344 wm8904->drc_texts = kmalloc(sizeof(char *) 2334 wm8904->drc_texts = kmalloc(sizeof(char *)
2345 * pdata->num_drc_cfgs, GFP_KERNEL); 2335 * pdata->num_drc_cfgs, GFP_KERNEL);
2346 if (!wm8904->drc_texts) { 2336 if (!wm8904->drc_texts) {
2347 dev_err(wm8904->codec.dev, 2337 dev_err(codec->dev,
2348 "Failed to allocate %d DRC config texts\n", 2338 "Failed to allocate %d DRC config texts\n",
2349 pdata->num_drc_cfgs); 2339 pdata->num_drc_cfgs);
2350 return; 2340 return;
@@ -2356,9 +2346,9 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2356 wm8904->drc_enum.max = pdata->num_drc_cfgs; 2346 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2357 wm8904->drc_enum.texts = wm8904->drc_texts; 2347 wm8904->drc_enum.texts = wm8904->drc_texts;
2358 2348
2359 ret = snd_soc_add_controls(&wm8904->codec, &control, 1); 2349 ret = snd_soc_add_controls(codec, &control, 1);
2360 if (ret != 0) 2350 if (ret != 0)
2361 dev_err(wm8904->codec.dev, 2351 dev_err(codec->dev,
2362 "Failed to add DRC mode control: %d\n", ret); 2352 "Failed to add DRC mode control: %d\n", ret);
2363 2353
2364 wm8904_set_drc(codec); 2354 wm8904_set_drc(codec);
@@ -2368,91 +2358,22 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2368 pdata->num_retune_mobile_cfgs); 2358 pdata->num_retune_mobile_cfgs);
2369 2359
2370 if (pdata->num_retune_mobile_cfgs) 2360 if (pdata->num_retune_mobile_cfgs)
2371 wm8904_handle_retune_mobile_pdata(wm8904); 2361 wm8904_handle_retune_mobile_pdata(codec);
2372 else 2362 else
2373 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, 2363 snd_soc_add_controls(codec, wm8904_eq_controls,
2374 ARRAY_SIZE(wm8904_eq_controls)); 2364 ARRAY_SIZE(wm8904_eq_controls));
2375} 2365}
2376 2366
2377static int wm8904_probe(struct platform_device *pdev)
2378{
2379 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2380 struct snd_soc_codec *codec;
2381 int ret = 0;
2382
2383 if (wm8904_codec == NULL) {
2384 dev_err(&pdev->dev, "Codec device not registered\n");
2385 return -ENODEV;
2386 }
2387
2388 socdev->card->codec = wm8904_codec;
2389 codec = wm8904_codec;
2390
2391 /* register pcms */
2392 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2393 if (ret < 0) {
2394 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2395 goto pcm_err;
2396 }
2397
2398 wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec));
2399
2400 wm8904_add_widgets(codec);
2401
2402 return ret;
2403
2404pcm_err:
2405 return ret;
2406}
2407
2408static int wm8904_remove(struct platform_device *pdev)
2409{
2410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2411
2412 snd_soc_free_pcms(socdev);
2413 snd_soc_dapm_free(socdev);
2414
2415 return 0;
2416}
2417
2418struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2419 .probe = wm8904_probe,
2420 .remove = wm8904_remove,
2421 .suspend = wm8904_suspend,
2422 .resume = wm8904_resume,
2423};
2424EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2425 2367
2426static int wm8904_register(struct wm8904_priv *wm8904, 2368static int wm8904_probe(struct snd_soc_codec *codec)
2427 enum snd_soc_control_type control)
2428{ 2369{
2370 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2429 struct wm8904_pdata *pdata = wm8904->pdata; 2371 struct wm8904_pdata *pdata = wm8904->pdata;
2430 int ret; 2372 u16 *reg_cache = codec->reg_cache;
2431 struct snd_soc_codec *codec = &wm8904->codec; 2373 int ret, i;
2432 int i;
2433
2434 if (wm8904_codec) {
2435 dev_err(codec->dev, "Another WM8904 is registered\n");
2436 ret = -EINVAL;
2437 goto err;
2438 }
2439 2374
2440 mutex_init(&codec->mutex);
2441 INIT_LIST_HEAD(&codec->dapm_widgets);
2442 INIT_LIST_HEAD(&codec->dapm_paths);
2443
2444 snd_soc_codec_set_drvdata(codec, wm8904);
2445 codec->name = "WM8904";
2446 codec->owner = THIS_MODULE;
2447 codec->bias_level = SND_SOC_BIAS_OFF;
2448 codec->set_bias_level = wm8904_set_bias_level;
2449 codec->dai = &wm8904_dai;
2450 codec->num_dai = 1;
2451 codec->reg_cache_size = WM8904_MAX_REGISTER;
2452 codec->reg_cache = &wm8904->reg_cache;
2453 codec->volatile_register = wm8904_volatile_register;
2454 codec->cache_sync = 1; 2375 codec->cache_sync = 1;
2455 codec->idle_bias_off = 1; 2376 codec->dapm.idle_bias_off = 1;
2456 2377
2457 switch (wm8904->devtype) { 2378 switch (wm8904->devtype) {
2458 case WM8904: 2379 case WM8904:
@@ -2463,16 +2384,13 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2463 default: 2384 default:
2464 dev_err(codec->dev, "Unknown device type %d\n", 2385 dev_err(codec->dev, "Unknown device type %d\n",
2465 wm8904->devtype); 2386 wm8904->devtype);
2466 ret = -EINVAL; 2387 return -EINVAL;
2467 goto err;
2468 } 2388 }
2469 2389
2470 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2390 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
2471
2472 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2473 if (ret != 0) { 2391 if (ret != 0) {
2474 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 2392 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2475 goto err; 2393 return ret;
2476 } 2394 }
2477 2395
2478 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) 2396 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
@@ -2482,7 +2400,7 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2482 wm8904->supplies); 2400 wm8904->supplies);
2483 if (ret != 0) { 2401 if (ret != 0) {
2484 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 2402 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2485 goto err; 2403 return ret;
2486 } 2404 }
2487 2405
2488 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), 2406 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
@@ -2517,22 +2435,29 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2517 goto err_enable; 2435 goto err_enable;
2518 } 2436 }
2519 2437
2520 wm8904_dai.dev = codec->dev;
2521
2522 /* Change some default settings - latch VU and enable ZC */ 2438 /* Change some default settings - latch VU and enable ZC */
2523 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; 2439 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2524 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; 2440 WM8904_ADC_VU, WM8904_ADC_VU);
2525 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; 2441 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2526 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; 2442 WM8904_ADC_VU, WM8904_ADC_VU);
2527 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | 2443 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2528 WM8904_HPOUTLZC; 2444 WM8904_DAC_VU, WM8904_DAC_VU);
2529 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | 2445 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2530 WM8904_HPOUTRZC; 2446 WM8904_DAC_VU, WM8904_DAC_VU);
2531 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | 2447 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
2532 WM8904_LINEOUTLZC; 2448 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2533 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | 2449 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2534 WM8904_LINEOUTRZC; 2450 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
2535 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; 2451 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2452 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2453 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
2454 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2455 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2456 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
2457 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2458 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2459 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
2460 WM8904_SR_MODE, 0);
2536 2461
2537 /* Apply configuration from the platform data. */ 2462 /* Apply configuration from the platform data. */
2538 if (wm8904->pdata) { 2463 if (wm8904->pdata) {
@@ -2540,95 +2465,95 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2540 if (!pdata->gpio_cfg[i]) 2465 if (!pdata->gpio_cfg[i])
2541 continue; 2466 continue;
2542 2467
2543 wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i] 2468 reg_cache[WM8904_GPIO_CONTROL_1 + i]
2544 = pdata->gpio_cfg[i] & 0xffff; 2469 = pdata->gpio_cfg[i] & 0xffff;
2545 } 2470 }
2546 2471
2547 /* Zero is the default value for these anyway */ 2472 /* Zero is the default value for these anyway */
2548 for (i = 0; i < WM8904_MIC_REGS; i++) 2473 for (i = 0; i < WM8904_MIC_REGS; i++)
2549 wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] 2474 reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
2550 = pdata->mic_cfg[i]; 2475 = pdata->mic_cfg[i];
2551 } 2476 }
2552 2477
2553 /* Set Class W by default - this will be managed by the Class 2478 /* Set Class W by default - this will be managed by the Class
2554 * G widget at runtime where bypass paths are available. 2479 * G widget at runtime where bypass paths are available.
2555 */ 2480 */
2556 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; 2481 snd_soc_update_bits(codec, WM8904_CLASS_W_0,
2482 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2557 2483
2558 /* Use normal bias source */ 2484 /* Use normal bias source */
2559 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; 2485 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2486 WM8904_POBCTRL, 0);
2560 2487
2561 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2488 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2562 2489
2563 /* Bias level configuration will have done an extra enable */ 2490 /* Bias level configuration will have done an extra enable */
2564 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2491 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2565 2492
2566 wm8904_codec = codec; 2493 wm8904_handle_pdata(codec);
2567 2494
2568 ret = snd_soc_register_codec(codec); 2495 wm8904_add_widgets(codec);
2569 if (ret != 0) {
2570 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2571 goto err_enable;
2572 }
2573
2574 ret = snd_soc_register_dai(&wm8904_dai);
2575 if (ret != 0) {
2576 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2577 goto err_codec;
2578 }
2579 2496
2580 return 0; 2497 return 0;
2581 2498
2582err_codec:
2583 snd_soc_unregister_codec(codec);
2584err_enable: 2499err_enable:
2585 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2500 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2586err_get: 2501err_get:
2587 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2502 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2588err:
2589 kfree(wm8904);
2590 return ret; 2503 return ret;
2591} 2504}
2592 2505
2593static void wm8904_unregister(struct wm8904_priv *wm8904) 2506static int wm8904_remove(struct snd_soc_codec *codec)
2594{ 2507{
2595 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF); 2508 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2509
2510 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2596 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); 2511 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2597 snd_soc_unregister_dai(&wm8904_dai); 2512 kfree(wm8904->retune_mobile_texts);
2598 snd_soc_unregister_codec(&wm8904->codec); 2513 kfree(wm8904->drc_texts);
2599 kfree(wm8904); 2514
2600 wm8904_codec = NULL; 2515 return 0;
2601} 2516}
2602 2517
2518static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2519 .probe = wm8904_probe,
2520 .remove = wm8904_remove,
2521 .suspend = wm8904_suspend,
2522 .resume = wm8904_resume,
2523 .set_bias_level = wm8904_set_bias_level,
2524 .reg_cache_size = ARRAY_SIZE(wm8904_reg),
2525 .reg_word_size = sizeof(u16),
2526 .reg_cache_default = wm8904_reg,
2527 .volatile_register = wm8904_volatile_register,
2528};
2529
2603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2530#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2604static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, 2531static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2605 const struct i2c_device_id *id) 2532 const struct i2c_device_id *id)
2606{ 2533{
2607 struct wm8904_priv *wm8904; 2534 struct wm8904_priv *wm8904;
2608 struct snd_soc_codec *codec; 2535 int ret;
2609 2536
2610 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); 2537 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2611 if (wm8904 == NULL) 2538 if (wm8904 == NULL)
2612 return -ENOMEM; 2539 return -ENOMEM;
2613 2540
2614 codec = &wm8904->codec;
2615 codec->hw_write = (hw_write_t)i2c_master_send;
2616
2617 wm8904->devtype = id->driver_data; 2541 wm8904->devtype = id->driver_data;
2618
2619 i2c_set_clientdata(i2c, wm8904); 2542 i2c_set_clientdata(i2c, wm8904);
2620 codec->control_data = i2c; 2543 wm8904->control_data = i2c;
2621 wm8904->pdata = i2c->dev.platform_data; 2544 wm8904->pdata = i2c->dev.platform_data;
2622 2545
2623 codec->dev = &i2c->dev; 2546 ret = snd_soc_register_codec(&i2c->dev,
2624 2547 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2625 return wm8904_register(wm8904, SND_SOC_I2C); 2548 if (ret < 0)
2549 kfree(wm8904);
2550 return ret;
2626} 2551}
2627 2552
2628static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2553static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2629{ 2554{
2630 struct wm8904_priv *wm8904 = i2c_get_clientdata(client); 2555 snd_soc_unregister_codec(&client->dev);
2631 wm8904_unregister(wm8904); 2556 kfree(i2c_get_clientdata(client));
2632 return 0; 2557 return 0;
2633} 2558}
2634 2559
@@ -2641,7 +2566,7 @@ MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2641 2566
2642static struct i2c_driver wm8904_i2c_driver = { 2567static struct i2c_driver wm8904_i2c_driver = {
2643 .driver = { 2568 .driver = {
2644 .name = "WM8904", 2569 .name = "wm8904-codec",
2645 .owner = THIS_MODULE, 2570 .owner = THIS_MODULE,
2646 }, 2571 },
2647 .probe = wm8904_i2c_probe, 2572 .probe = wm8904_i2c_probe,
@@ -2652,15 +2577,15 @@ static struct i2c_driver wm8904_i2c_driver = {
2652 2577
2653static int __init wm8904_modinit(void) 2578static int __init wm8904_modinit(void)
2654{ 2579{
2655 int ret; 2580 int ret = 0;
2656#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 2581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2657 ret = i2c_add_driver(&wm8904_i2c_driver); 2582 ret = i2c_add_driver(&wm8904_i2c_driver);
2658 if (ret != 0) { 2583 if (ret != 0) {
2659 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n", 2584 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2660 ret); 2585 ret);
2661 } 2586 }
2662#endif 2587#endif
2663 return 0; 2588 return ret;
2664} 2589}
2665module_init(wm8904_modinit); 2590module_init(wm8904_modinit);
2666 2591
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index abe5059b3004..9e8c84188ba7 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -21,9 +21,6 @@
21#define WM8904_FLL_LRCLK 3 21#define WM8904_FLL_LRCLK 3
22#define WM8904_FLL_FREE_RUNNING 4 22#define WM8904_FLL_FREE_RUNNING 4
23 23
24extern struct snd_soc_dai wm8904_dai;
25extern struct snd_soc_codec_device soc_codec_dev_wm8904;
26
27/* 24/*
28 * Register values. 25 * Register values.
29 */ 26 */
diff --git a/sound/soc/codecs/wm8915.c b/sound/soc/codecs/wm8915.c
new file mode 100644
index 000000000000..e2ab4fac2819
--- /dev/null
+++ b/sound/soc/codecs/wm8915.c
@@ -0,0 +1,2931 @@
1/*
2 * wm8915.c - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/completion.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/gcd.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22#include <linux/regulator/consumer.h>
23#include <linux/slab.h>
24#include <linux/workqueue.h>
25#include <sound/core.h>
26#include <sound/jack.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/initval.h>
31#include <sound/tlv.h>
32#include <trace/events/asoc.h>
33
34#include <sound/wm8915.h>
35#include "wm8915.h"
36
37#define WM8915_AIFS 2
38
39#define HPOUT1L 1
40#define HPOUT1R 2
41#define HPOUT2L 4
42#define HPOUT2R 8
43
44#define WM8915_NUM_SUPPLIES 6
45static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = {
46 "DCVDD",
47 "DBVDD",
48 "AVDD1",
49 "AVDD2",
50 "CPVDD",
51 "MICVDD",
52};
53
54struct wm8915_priv {
55 struct snd_soc_codec *codec;
56
57 int ldo1ena;
58
59 int sysclk;
60
61 int fll_src;
62 int fll_fref;
63 int fll_fout;
64
65 struct completion fll_lock;
66
67 u16 dcs_pending;
68 struct completion dcs_done;
69
70 u16 hpout_ena;
71 u16 hpout_pending;
72
73 struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES];
74 struct notifier_block disable_nb[WM8915_NUM_SUPPLIES];
75
76 struct wm8915_pdata pdata;
77
78 int rx_rate[WM8915_AIFS];
79
80 /* Platform dependant ReTune mobile configuration */
81 int num_retune_mobile_texts;
82 const char **retune_mobile_texts;
83 int retune_mobile_cfg[2];
84 struct soc_enum retune_mobile_enum;
85
86 struct snd_soc_jack *jack;
87 bool detecting;
88 bool jack_mic;
89 wm8915_polarity_fn polarity_cb;
90
91#ifdef CONFIG_GPIOLIB
92 struct gpio_chip gpio_chip;
93#endif
94};
95
96/* We can't use the same notifier block for more than one supply and
97 * there's no way I can see to get from a callback to the caller
98 * except container_of().
99 */
100#define WM8915_REGULATOR_EVENT(n) \
101static int wm8915_regulator_event_##n(struct notifier_block *nb, \
102 unsigned long event, void *data) \
103{ \
104 struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \
105 disable_nb[n]); \
106 if (event & REGULATOR_EVENT_DISABLE) { \
107 wm8915->codec->cache_sync = 1; \
108 } \
109 return 0; \
110}
111
112WM8915_REGULATOR_EVENT(0)
113WM8915_REGULATOR_EVENT(1)
114WM8915_REGULATOR_EVENT(2)
115WM8915_REGULATOR_EVENT(3)
116WM8915_REGULATOR_EVENT(4)
117WM8915_REGULATOR_EVENT(5)
118
119static const u16 wm8915_reg[WM8915_MAX_REGISTER] = {
120 [WM8915_SOFTWARE_RESET] = 0x8915,
121 [WM8915_POWER_MANAGEMENT_7] = 0x10,
122 [WM8915_DAC1_HPOUT1_VOLUME] = 0x88,
123 [WM8915_DAC2_HPOUT2_VOLUME] = 0x88,
124 [WM8915_DAC1_LEFT_VOLUME] = 0x2c0,
125 [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0,
126 [WM8915_DAC2_LEFT_VOLUME] = 0x2c0,
127 [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0,
128 [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80,
129 [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80,
130 [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80,
131 [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80,
132 [WM8915_MICBIAS_1] = 0x39,
133 [WM8915_MICBIAS_2] = 0x39,
134 [WM8915_LDO_1] = 0x3,
135 [WM8915_LDO_2] = 0x13,
136 [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4,
137 [WM8915_HEADPHONE_DETECT_1] = 0x20,
138 [WM8915_MIC_DETECT_1] = 0x7600,
139 [WM8915_MIC_DETECT_2] = 0xbf,
140 [WM8915_CHARGE_PUMP_1] = 0x1f25,
141 [WM8915_CHARGE_PUMP_2] = 0xab19,
142 [WM8915_DC_SERVO_5] = 0x2a2a,
143 [WM8915_CONTROL_INTERFACE_1] = 0x8004,
144 [WM8915_CLOCKING_1] = 0x10,
145 [WM8915_AIF_RATE] = 0x83,
146 [WM8915_FLL_CONTROL_4] = 0x5dc0,
147 [WM8915_FLL_CONTROL_5] = 0xc84,
148 [WM8915_FLL_EFS_2] = 0x2,
149 [WM8915_AIF1_TX_LRCLK_1] = 0x80,
150 [WM8915_AIF1_TX_LRCLK_2] = 0x8,
151 [WM8915_AIF1_RX_LRCLK_1] = 0x80,
152 [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818,
153 [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818,
154 [WM8915_AIF1TX_TEST] = 0x7,
155 [WM8915_AIF2_TX_LRCLK_1] = 0x80,
156 [WM8915_AIF2_TX_LRCLK_2] = 0x8,
157 [WM8915_AIF2_RX_LRCLK_1] = 0x80,
158 [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818,
159 [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818,
160 [WM8915_AIF2TX_TEST] = 0x1,
161 [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0,
162 [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0,
163 [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0,
164 [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0,
165 [WM8915_DSP1_TX_FILTERS] = 0x2000,
166 [WM8915_DSP1_RX_FILTERS_1] = 0x200,
167 [WM8915_DSP1_RX_FILTERS_2] = 0x10,
168 [WM8915_DSP1_DRC_1] = 0x98,
169 [WM8915_DSP1_DRC_2] = 0x845,
170 [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318,
171 [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300,
172 [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca,
173 [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400,
174 [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8,
175 [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5,
176 [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145,
177 [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75,
178 [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5,
179 [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58,
180 [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373,
181 [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54,
182 [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558,
183 [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e,
184 [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829,
185 [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad,
186 [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103,
187 [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564,
188 [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559,
189 [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000,
190 [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0,
191 [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0,
192 [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0,
193 [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0,
194 [WM8915_DSP2_TX_FILTERS] = 0x2000,
195 [WM8915_DSP2_RX_FILTERS_1] = 0x200,
196 [WM8915_DSP2_RX_FILTERS_2] = 0x10,
197 [WM8915_DSP2_DRC_1] = 0x98,
198 [WM8915_DSP2_DRC_2] = 0x845,
199 [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318,
200 [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300,
201 [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca,
202 [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400,
203 [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8,
204 [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5,
205 [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145,
206 [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75,
207 [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5,
208 [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58,
209 [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373,
210 [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54,
211 [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558,
212 [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e,
213 [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829,
214 [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad,
215 [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103,
216 [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564,
217 [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559,
218 [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000,
219 [WM8915_OVERSAMPLING] = 0xd,
220 [WM8915_SIDETONE] = 0x1040,
221 [WM8915_GPIO_1] = 0xa101,
222 [WM8915_GPIO_2] = 0xa101,
223 [WM8915_GPIO_3] = 0xa101,
224 [WM8915_GPIO_4] = 0xa101,
225 [WM8915_GPIO_5] = 0xa101,
226 [WM8915_PULL_CONTROL_2] = 0x140,
227 [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f,
228 [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf,
229 [WM8915_RIGHT_PDM_SPEAKER] = 0x1,
230 [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69,
231 [WM8915_PDM_SPEAKER_VOLUME] = 0x66,
232 [WM8915_WRITE_SEQUENCER_0] = 0x1,
233 [WM8915_WRITE_SEQUENCER_1] = 0x1,
234 [WM8915_WRITE_SEQUENCER_3] = 0x6,
235 [WM8915_WRITE_SEQUENCER_4] = 0x40,
236 [WM8915_WRITE_SEQUENCER_5] = 0x1,
237 [WM8915_WRITE_SEQUENCER_6] = 0xf,
238 [WM8915_WRITE_SEQUENCER_7] = 0x6,
239 [WM8915_WRITE_SEQUENCER_8] = 0x1,
240 [WM8915_WRITE_SEQUENCER_9] = 0x3,
241 [WM8915_WRITE_SEQUENCER_10] = 0x104,
242 [WM8915_WRITE_SEQUENCER_12] = 0x60,
243 [WM8915_WRITE_SEQUENCER_13] = 0x11,
244 [WM8915_WRITE_SEQUENCER_14] = 0x401,
245 [WM8915_WRITE_SEQUENCER_16] = 0x50,
246 [WM8915_WRITE_SEQUENCER_17] = 0x3,
247 [WM8915_WRITE_SEQUENCER_18] = 0x100,
248 [WM8915_WRITE_SEQUENCER_20] = 0x51,
249 [WM8915_WRITE_SEQUENCER_21] = 0x3,
250 [WM8915_WRITE_SEQUENCER_22] = 0x104,
251 [WM8915_WRITE_SEQUENCER_23] = 0xa,
252 [WM8915_WRITE_SEQUENCER_24] = 0x60,
253 [WM8915_WRITE_SEQUENCER_25] = 0x3b,
254 [WM8915_WRITE_SEQUENCER_26] = 0x502,
255 [WM8915_WRITE_SEQUENCER_27] = 0x100,
256 [WM8915_WRITE_SEQUENCER_28] = 0x2fff,
257 [WM8915_WRITE_SEQUENCER_32] = 0x2fff,
258 [WM8915_WRITE_SEQUENCER_36] = 0x2fff,
259 [WM8915_WRITE_SEQUENCER_40] = 0x2fff,
260 [WM8915_WRITE_SEQUENCER_44] = 0x2fff,
261 [WM8915_WRITE_SEQUENCER_48] = 0x2fff,
262 [WM8915_WRITE_SEQUENCER_52] = 0x2fff,
263 [WM8915_WRITE_SEQUENCER_56] = 0x2fff,
264 [WM8915_WRITE_SEQUENCER_60] = 0x2fff,
265 [WM8915_WRITE_SEQUENCER_64] = 0x1,
266 [WM8915_WRITE_SEQUENCER_65] = 0x1,
267 [WM8915_WRITE_SEQUENCER_67] = 0x6,
268 [WM8915_WRITE_SEQUENCER_68] = 0x40,
269 [WM8915_WRITE_SEQUENCER_69] = 0x1,
270 [WM8915_WRITE_SEQUENCER_70] = 0xf,
271 [WM8915_WRITE_SEQUENCER_71] = 0x6,
272 [WM8915_WRITE_SEQUENCER_72] = 0x1,
273 [WM8915_WRITE_SEQUENCER_73] = 0x3,
274 [WM8915_WRITE_SEQUENCER_74] = 0x104,
275 [WM8915_WRITE_SEQUENCER_76] = 0x60,
276 [WM8915_WRITE_SEQUENCER_77] = 0x11,
277 [WM8915_WRITE_SEQUENCER_78] = 0x401,
278 [WM8915_WRITE_SEQUENCER_80] = 0x50,
279 [WM8915_WRITE_SEQUENCER_81] = 0x3,
280 [WM8915_WRITE_SEQUENCER_82] = 0x100,
281 [WM8915_WRITE_SEQUENCER_84] = 0x60,
282 [WM8915_WRITE_SEQUENCER_85] = 0x3b,
283 [WM8915_WRITE_SEQUENCER_86] = 0x502,
284 [WM8915_WRITE_SEQUENCER_87] = 0x100,
285 [WM8915_WRITE_SEQUENCER_88] = 0x2fff,
286 [WM8915_WRITE_SEQUENCER_92] = 0x2fff,
287 [WM8915_WRITE_SEQUENCER_96] = 0x2fff,
288 [WM8915_WRITE_SEQUENCER_100] = 0x2fff,
289 [WM8915_WRITE_SEQUENCER_104] = 0x2fff,
290 [WM8915_WRITE_SEQUENCER_108] = 0x2fff,
291 [WM8915_WRITE_SEQUENCER_112] = 0x2fff,
292 [WM8915_WRITE_SEQUENCER_116] = 0x2fff,
293 [WM8915_WRITE_SEQUENCER_120] = 0x2fff,
294 [WM8915_WRITE_SEQUENCER_124] = 0x2fff,
295 [WM8915_WRITE_SEQUENCER_128] = 0x1,
296 [WM8915_WRITE_SEQUENCER_129] = 0x1,
297 [WM8915_WRITE_SEQUENCER_131] = 0x6,
298 [WM8915_WRITE_SEQUENCER_132] = 0x40,
299 [WM8915_WRITE_SEQUENCER_133] = 0x1,
300 [WM8915_WRITE_SEQUENCER_134] = 0xf,
301 [WM8915_WRITE_SEQUENCER_135] = 0x6,
302 [WM8915_WRITE_SEQUENCER_136] = 0x1,
303 [WM8915_WRITE_SEQUENCER_137] = 0x3,
304 [WM8915_WRITE_SEQUENCER_138] = 0x106,
305 [WM8915_WRITE_SEQUENCER_140] = 0x61,
306 [WM8915_WRITE_SEQUENCER_141] = 0x11,
307 [WM8915_WRITE_SEQUENCER_142] = 0x401,
308 [WM8915_WRITE_SEQUENCER_144] = 0x50,
309 [WM8915_WRITE_SEQUENCER_145] = 0x3,
310 [WM8915_WRITE_SEQUENCER_146] = 0x102,
311 [WM8915_WRITE_SEQUENCER_148] = 0x51,
312 [WM8915_WRITE_SEQUENCER_149] = 0x3,
313 [WM8915_WRITE_SEQUENCER_150] = 0x106,
314 [WM8915_WRITE_SEQUENCER_151] = 0xa,
315 [WM8915_WRITE_SEQUENCER_152] = 0x61,
316 [WM8915_WRITE_SEQUENCER_153] = 0x3b,
317 [WM8915_WRITE_SEQUENCER_154] = 0x502,
318 [WM8915_WRITE_SEQUENCER_155] = 0x100,
319 [WM8915_WRITE_SEQUENCER_156] = 0x2fff,
320 [WM8915_WRITE_SEQUENCER_160] = 0x2fff,
321 [WM8915_WRITE_SEQUENCER_164] = 0x2fff,
322 [WM8915_WRITE_SEQUENCER_168] = 0x2fff,
323 [WM8915_WRITE_SEQUENCER_172] = 0x2fff,
324 [WM8915_WRITE_SEQUENCER_176] = 0x2fff,
325 [WM8915_WRITE_SEQUENCER_180] = 0x2fff,
326 [WM8915_WRITE_SEQUENCER_184] = 0x2fff,
327 [WM8915_WRITE_SEQUENCER_188] = 0x2fff,
328 [WM8915_WRITE_SEQUENCER_192] = 0x1,
329 [WM8915_WRITE_SEQUENCER_193] = 0x1,
330 [WM8915_WRITE_SEQUENCER_195] = 0x6,
331 [WM8915_WRITE_SEQUENCER_196] = 0x40,
332 [WM8915_WRITE_SEQUENCER_197] = 0x1,
333 [WM8915_WRITE_SEQUENCER_198] = 0xf,
334 [WM8915_WRITE_SEQUENCER_199] = 0x6,
335 [WM8915_WRITE_SEQUENCER_200] = 0x1,
336 [WM8915_WRITE_SEQUENCER_201] = 0x3,
337 [WM8915_WRITE_SEQUENCER_202] = 0x106,
338 [WM8915_WRITE_SEQUENCER_204] = 0x61,
339 [WM8915_WRITE_SEQUENCER_205] = 0x11,
340 [WM8915_WRITE_SEQUENCER_206] = 0x401,
341 [WM8915_WRITE_SEQUENCER_208] = 0x50,
342 [WM8915_WRITE_SEQUENCER_209] = 0x3,
343 [WM8915_WRITE_SEQUENCER_210] = 0x102,
344 [WM8915_WRITE_SEQUENCER_212] = 0x61,
345 [WM8915_WRITE_SEQUENCER_213] = 0x3b,
346 [WM8915_WRITE_SEQUENCER_214] = 0x502,
347 [WM8915_WRITE_SEQUENCER_215] = 0x100,
348 [WM8915_WRITE_SEQUENCER_216] = 0x2fff,
349 [WM8915_WRITE_SEQUENCER_220] = 0x2fff,
350 [WM8915_WRITE_SEQUENCER_224] = 0x2fff,
351 [WM8915_WRITE_SEQUENCER_228] = 0x2fff,
352 [WM8915_WRITE_SEQUENCER_232] = 0x2fff,
353 [WM8915_WRITE_SEQUENCER_236] = 0x2fff,
354 [WM8915_WRITE_SEQUENCER_240] = 0x2fff,
355 [WM8915_WRITE_SEQUENCER_244] = 0x2fff,
356 [WM8915_WRITE_SEQUENCER_248] = 0x2fff,
357 [WM8915_WRITE_SEQUENCER_252] = 0x2fff,
358 [WM8915_WRITE_SEQUENCER_256] = 0x60,
359 [WM8915_WRITE_SEQUENCER_258] = 0x601,
360 [WM8915_WRITE_SEQUENCER_260] = 0x50,
361 [WM8915_WRITE_SEQUENCER_262] = 0x100,
362 [WM8915_WRITE_SEQUENCER_264] = 0x1,
363 [WM8915_WRITE_SEQUENCER_266] = 0x104,
364 [WM8915_WRITE_SEQUENCER_267] = 0x100,
365 [WM8915_WRITE_SEQUENCER_268] = 0x2fff,
366 [WM8915_WRITE_SEQUENCER_272] = 0x2fff,
367 [WM8915_WRITE_SEQUENCER_276] = 0x2fff,
368 [WM8915_WRITE_SEQUENCER_280] = 0x2fff,
369 [WM8915_WRITE_SEQUENCER_284] = 0x2fff,
370 [WM8915_WRITE_SEQUENCER_288] = 0x2fff,
371 [WM8915_WRITE_SEQUENCER_292] = 0x2fff,
372 [WM8915_WRITE_SEQUENCER_296] = 0x2fff,
373 [WM8915_WRITE_SEQUENCER_300] = 0x2fff,
374 [WM8915_WRITE_SEQUENCER_304] = 0x2fff,
375 [WM8915_WRITE_SEQUENCER_308] = 0x2fff,
376 [WM8915_WRITE_SEQUENCER_312] = 0x2fff,
377 [WM8915_WRITE_SEQUENCER_316] = 0x2fff,
378 [WM8915_WRITE_SEQUENCER_320] = 0x61,
379 [WM8915_WRITE_SEQUENCER_322] = 0x601,
380 [WM8915_WRITE_SEQUENCER_324] = 0x50,
381 [WM8915_WRITE_SEQUENCER_326] = 0x102,
382 [WM8915_WRITE_SEQUENCER_328] = 0x1,
383 [WM8915_WRITE_SEQUENCER_330] = 0x106,
384 [WM8915_WRITE_SEQUENCER_331] = 0x100,
385 [WM8915_WRITE_SEQUENCER_332] = 0x2fff,
386 [WM8915_WRITE_SEQUENCER_336] = 0x2fff,
387 [WM8915_WRITE_SEQUENCER_340] = 0x2fff,
388 [WM8915_WRITE_SEQUENCER_344] = 0x2fff,
389 [WM8915_WRITE_SEQUENCER_348] = 0x2fff,
390 [WM8915_WRITE_SEQUENCER_352] = 0x2fff,
391 [WM8915_WRITE_SEQUENCER_356] = 0x2fff,
392 [WM8915_WRITE_SEQUENCER_360] = 0x2fff,
393 [WM8915_WRITE_SEQUENCER_364] = 0x2fff,
394 [WM8915_WRITE_SEQUENCER_368] = 0x2fff,
395 [WM8915_WRITE_SEQUENCER_372] = 0x2fff,
396 [WM8915_WRITE_SEQUENCER_376] = 0x2fff,
397 [WM8915_WRITE_SEQUENCER_380] = 0x2fff,
398 [WM8915_WRITE_SEQUENCER_384] = 0x60,
399 [WM8915_WRITE_SEQUENCER_386] = 0x601,
400 [WM8915_WRITE_SEQUENCER_388] = 0x61,
401 [WM8915_WRITE_SEQUENCER_390] = 0x601,
402 [WM8915_WRITE_SEQUENCER_392] = 0x50,
403 [WM8915_WRITE_SEQUENCER_394] = 0x300,
404 [WM8915_WRITE_SEQUENCER_396] = 0x1,
405 [WM8915_WRITE_SEQUENCER_398] = 0x304,
406 [WM8915_WRITE_SEQUENCER_400] = 0x40,
407 [WM8915_WRITE_SEQUENCER_402] = 0xf,
408 [WM8915_WRITE_SEQUENCER_404] = 0x1,
409 [WM8915_WRITE_SEQUENCER_407] = 0x100,
410};
411
412static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
413static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
414static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
415static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);
416static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);
417static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);
418static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
419
420static const char *sidetone_hpf_text[] = {
421 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"
422};
423
424static const struct soc_enum sidetone_hpf =
425 SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text);
426
427static const char *hpf_mode_text[] = {
428 "HiFi", "Custom", "Voice"
429};
430
431static const struct soc_enum dsp1tx_hpf_mode =
432 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text);
433
434static const struct soc_enum dsp2tx_hpf_mode =
435 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text);
436
437static const char *hpf_cutoff_text[] = {
438 "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
439};
440
441static const struct soc_enum dsp1tx_hpf_cutoff =
442 SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text);
443
444static const struct soc_enum dsp2tx_hpf_cutoff =
445 SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text);
446
447static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block)
448{
449 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
450 struct wm8915_pdata *pdata = &wm8915->pdata;
451 int base, best, best_val, save, i, cfg, iface;
452
453 if (!wm8915->num_retune_mobile_texts)
454 return;
455
456 switch (block) {
457 case 0:
458 base = WM8915_DSP1_RX_EQ_GAINS_1;
459 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
460 WM8915_DSP1RX_SRC)
461 iface = 1;
462 else
463 iface = 0;
464 break;
465 case 1:
466 base = WM8915_DSP1_RX_EQ_GAINS_2;
467 if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) &
468 WM8915_DSP2RX_SRC)
469 iface = 1;
470 else
471 iface = 0;
472 break;
473 default:
474 return;
475 }
476
477 /* Find the version of the currently selected configuration
478 * with the nearest sample rate. */
479 cfg = wm8915->retune_mobile_cfg[block];
480 best = 0;
481 best_val = INT_MAX;
482 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
483 if (strcmp(pdata->retune_mobile_cfgs[i].name,
484 wm8915->retune_mobile_texts[cfg]) == 0 &&
485 abs(pdata->retune_mobile_cfgs[i].rate
486 - wm8915->rx_rate[iface]) < best_val) {
487 best = i;
488 best_val = abs(pdata->retune_mobile_cfgs[i].rate
489 - wm8915->rx_rate[iface]);
490 }
491 }
492
493 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
494 block,
495 pdata->retune_mobile_cfgs[best].name,
496 pdata->retune_mobile_cfgs[best].rate,
497 wm8915->rx_rate[iface]);
498
499 /* The EQ will be disabled while reconfiguring it, remember the
500 * current configuration.
501 */
502 save = snd_soc_read(codec, base);
503 save &= WM8915_DSP1RX_EQ_ENA;
504
505 for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)
506 snd_soc_update_bits(codec, base + i, 0xffff,
507 pdata->retune_mobile_cfgs[best].regs[i]);
508
509 snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save);
510}
511
512/* Icky as hell but saves code duplication */
513static int wm8915_get_retune_mobile_block(const char *name)
514{
515 if (strcmp(name, "DSP1 EQ Mode") == 0)
516 return 0;
517 if (strcmp(name, "DSP2 EQ Mode") == 0)
518 return 1;
519 return -EINVAL;
520}
521
522static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
523 struct snd_ctl_elem_value *ucontrol)
524{
525 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
526 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
527 struct wm8915_pdata *pdata = &wm8915->pdata;
528 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
529 int value = ucontrol->value.integer.value[0];
530
531 if (block < 0)
532 return block;
533
534 if (value >= pdata->num_retune_mobile_cfgs)
535 return -EINVAL;
536
537 wm8915->retune_mobile_cfg[block] = value;
538
539 wm8915_set_retune_mobile(codec, block);
540
541 return 0;
542}
543
544static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
546{
547 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
548 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
549 int block = wm8915_get_retune_mobile_block(kcontrol->id.name);
550
551 ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block];
552
553 return 0;
554}
555
556static const struct snd_kcontrol_new wm8915_snd_controls[] = {
557SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME,
558 WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),
559SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME,
560 WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),
561
562SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES,
563 0, 5, 24, 0, sidetone_tlv),
564SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES,
565 0, 5, 24, 0, sidetone_tlv),
566SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0),
567SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),
568SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0),
569
570SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME,
571 WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
572SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME,
573 WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
574
575SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS,
576 13, 1, 0),
577SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0),
578SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),
579SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),
580
581SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS,
582 13, 1, 0),
583SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0),
584SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),
585SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),
586
587SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME,
588 WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
589SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1),
590
591SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME,
592 WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
593SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1),
594
595SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME,
596 WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
597SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME,
598 WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1),
599
600SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME,
601 WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),
602SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME,
603 WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1),
604
605SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0),
606SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0),
607SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0),
608SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0),
609
610SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0),
611SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0),
612
613SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4,
614 8, 0, out_digital_tlv),
615SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4,
616 8, 0, out_digital_tlv),
617
618SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME,
619 WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),
620SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME,
621 WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),
622
623SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME,
624 WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),
625SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME,
626 WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),
627
628SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,
629 spk_tlv),
630SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER,
631 WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1),
632SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER,
633 WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0),
634
635SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0),
636SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
637};
638
639static const struct snd_kcontrol_new wm8915_eq_controls[] = {
640SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0,
641 eq_tlv),
642SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0,
643 eq_tlv),
644SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0,
645 eq_tlv),
646SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0,
647 eq_tlv),
648SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0,
649 eq_tlv),
650
651SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0,
652 eq_tlv),
653SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0,
654 eq_tlv),
655SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0,
656 eq_tlv),
657SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0,
658 eq_tlv),
659SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0,
660 eq_tlv),
661};
662
663static int cp_event(struct snd_soc_dapm_widget *w,
664 struct snd_kcontrol *kcontrol, int event)
665{
666 switch (event) {
667 case SND_SOC_DAPM_POST_PMU:
668 msleep(5);
669 break;
670 default:
671 BUG();
672 return -EINVAL;
673 }
674
675 return 0;
676}
677
678static int rmv_short_event(struct snd_soc_dapm_widget *w,
679 struct snd_kcontrol *kcontrol, int event)
680{
681 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
682
683 /* Record which outputs we enabled */
684 switch (event) {
685 case SND_SOC_DAPM_PRE_PMD:
686 wm8915->hpout_pending &= ~w->shift;
687 break;
688 case SND_SOC_DAPM_PRE_PMU:
689 wm8915->hpout_pending |= w->shift;
690 break;
691 default:
692 BUG();
693 return -EINVAL;
694 }
695
696 return 0;
697}
698
699static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask)
700{
701 struct i2c_client *i2c = to_i2c_client(codec->dev);
702 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
703 int i, ret;
704 unsigned long timeout = 200;
705
706 snd_soc_write(codec, WM8915_DC_SERVO_2, mask);
707
708 /* Use the interrupt if possible */
709 do {
710 if (i2c->irq) {
711 timeout = wait_for_completion_timeout(&wm8915->dcs_done,
712 msecs_to_jiffies(200));
713 if (timeout == 0)
714 dev_err(codec->dev, "DC servo timed out\n");
715
716 } else {
717 msleep(1);
718 if (--i) {
719 timeout = 0;
720 break;
721 }
722 }
723
724 ret = snd_soc_read(codec, WM8915_DC_SERVO_2);
725 dev_dbg(codec->dev, "DC servo state: %x\n", ret);
726 } while (ret & mask);
727
728 if (timeout == 0)
729 dev_err(codec->dev, "DC servo timed out for %x\n", mask);
730 else
731 dev_dbg(codec->dev, "DC servo complete for %x\n", mask);
732}
733
734static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm,
735 enum snd_soc_dapm_type event, int subseq)
736{
737 struct snd_soc_codec *codec = container_of(dapm,
738 struct snd_soc_codec, dapm);
739 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
740 u16 val, mask;
741
742 /* Complete any pending DC servo starts */
743 if (wm8915->dcs_pending) {
744 dev_dbg(codec->dev, "Starting DC servo for %x\n",
745 wm8915->dcs_pending);
746
747 /* Trigger a startup sequence */
748 wait_for_dc_servo(codec, wm8915->dcs_pending
749 << WM8915_DCS_TRIG_STARTUP_0_SHIFT);
750
751 wm8915->dcs_pending = 0;
752 }
753
754 if (wm8915->hpout_pending != wm8915->hpout_ena) {
755 dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n",
756 wm8915->hpout_ena, wm8915->hpout_pending);
757
758 val = 0;
759 mask = 0;
760 if (wm8915->hpout_pending & HPOUT1L) {
761 val |= WM8915_HPOUT1L_RMV_SHORT;
762 mask |= WM8915_HPOUT1L_RMV_SHORT;
763 } else {
764 mask |= WM8915_HPOUT1L_RMV_SHORT |
765 WM8915_HPOUT1L_OUTP |
766 WM8915_HPOUT1L_DLY;
767 }
768
769 if (wm8915->hpout_pending & HPOUT1R) {
770 val |= WM8915_HPOUT1R_RMV_SHORT;
771 mask |= WM8915_HPOUT1R_RMV_SHORT;
772 } else {
773 mask |= WM8915_HPOUT1R_RMV_SHORT |
774 WM8915_HPOUT1R_OUTP |
775 WM8915_HPOUT1R_DLY;
776 }
777
778 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val);
779
780 val = 0;
781 mask = 0;
782 if (wm8915->hpout_pending & HPOUT2L) {
783 val |= WM8915_HPOUT2L_RMV_SHORT;
784 mask |= WM8915_HPOUT2L_RMV_SHORT;
785 } else {
786 mask |= WM8915_HPOUT2L_RMV_SHORT |
787 WM8915_HPOUT2L_OUTP |
788 WM8915_HPOUT2L_DLY;
789 }
790
791 if (wm8915->hpout_pending & HPOUT2R) {
792 val |= WM8915_HPOUT2R_RMV_SHORT;
793 mask |= WM8915_HPOUT2R_RMV_SHORT;
794 } else {
795 mask |= WM8915_HPOUT2R_RMV_SHORT |
796 WM8915_HPOUT2R_OUTP |
797 WM8915_HPOUT2R_DLY;
798 }
799
800 snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val);
801
802 wm8915->hpout_ena = wm8915->hpout_pending;
803 }
804}
805
806static int dcs_start(struct snd_soc_dapm_widget *w,
807 struct snd_kcontrol *kcontrol, int event)
808{
809 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec);
810
811 switch (event) {
812 case SND_SOC_DAPM_POST_PMU:
813 wm8915->dcs_pending |= 1 << w->shift;
814 break;
815 default:
816 BUG();
817 return -EINVAL;
818 }
819
820 return 0;
821}
822
823static const char *sidetone_text[] = {
824 "IN1", "IN2",
825};
826
827static const struct soc_enum left_sidetone_enum =
828 SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text);
829
830static const struct snd_kcontrol_new left_sidetone =
831 SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);
832
833static const struct soc_enum right_sidetone_enum =
834 SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text);
835
836static const struct snd_kcontrol_new right_sidetone =
837 SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);
838
839static const char *spk_text[] = {
840 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
841};
842
843static const struct soc_enum spkl_enum =
844 SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text);
845
846static const struct snd_kcontrol_new spkl_mux =
847 SOC_DAPM_ENUM("SPKL", spkl_enum);
848
849static const struct soc_enum spkr_enum =
850 SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text);
851
852static const struct snd_kcontrol_new spkr_mux =
853 SOC_DAPM_ENUM("SPKR", spkr_enum);
854
855static const char *dsp1rx_text[] = {
856 "AIF1", "AIF2"
857};
858
859static const struct soc_enum dsp1rx_enum =
860 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text);
861
862static const struct snd_kcontrol_new dsp1rx =
863 SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);
864
865static const char *dsp2rx_text[] = {
866 "AIF2", "AIF1"
867};
868
869static const struct soc_enum dsp2rx_enum =
870 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text);
871
872static const struct snd_kcontrol_new dsp2rx =
873 SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);
874
875static const char *aif2tx_text[] = {
876 "DSP2", "DSP1", "AIF1"
877};
878
879static const struct soc_enum aif2tx_enum =
880 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text);
881
882static const struct snd_kcontrol_new aif2tx =
883 SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);
884
885static const char *inmux_text[] = {
886 "ADC", "DMIC1", "DMIC2"
887};
888
889static const struct soc_enum in1_enum =
890 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text);
891
892static const struct snd_kcontrol_new in1_mux =
893 SOC_DAPM_ENUM("IN1 Mux", in1_enum);
894
895static const struct soc_enum in2_enum =
896 SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text);
897
898static const struct snd_kcontrol_new in2_mux =
899 SOC_DAPM_ENUM("IN2 Mux", in2_enum);
900
901static const struct snd_kcontrol_new dac2r_mix[] = {
902SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
903 5, 1, 0),
904SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING,
905 4, 1, 0),
906SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),
907SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),
908};
909
910static const struct snd_kcontrol_new dac2l_mix[] = {
911SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
912 5, 1, 0),
913SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING,
914 4, 1, 0),
915SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),
916SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),
917};
918
919static const struct snd_kcontrol_new dac1r_mix[] = {
920SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
921 5, 1, 0),
922SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING,
923 4, 1, 0),
924SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),
925SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),
926};
927
928static const struct snd_kcontrol_new dac1l_mix[] = {
929SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
930 5, 1, 0),
931SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING,
932 4, 1, 0),
933SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),
934SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),
935};
936
937static const struct snd_kcontrol_new dsp1txl[] = {
938SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
939 1, 1, 0),
940SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING,
941 0, 1, 0),
942};
943
944static const struct snd_kcontrol_new dsp1txr[] = {
945SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
946 1, 1, 0),
947SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING,
948 0, 1, 0),
949};
950
951static const struct snd_kcontrol_new dsp2txl[] = {
952SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
953 1, 1, 0),
954SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING,
955 0, 1, 0),
956};
957
958static const struct snd_kcontrol_new dsp2txr[] = {
959SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
960 1, 1, 0),
961SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING,
962 0, 1, 0),
963};
964
965
966static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = {
967SND_SOC_DAPM_INPUT("IN1LN"),
968SND_SOC_DAPM_INPUT("IN1LP"),
969SND_SOC_DAPM_INPUT("IN1RN"),
970SND_SOC_DAPM_INPUT("IN1RP"),
971
972SND_SOC_DAPM_INPUT("IN2LN"),
973SND_SOC_DAPM_INPUT("IN2LP"),
974SND_SOC_DAPM_INPUT("IN2RN"),
975SND_SOC_DAPM_INPUT("IN2RP"),
976
977SND_SOC_DAPM_INPUT("DMIC1DAT"),
978SND_SOC_DAPM_INPUT("DMIC2DAT"),
979
980SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0),
981SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0),
982SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0),
983SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event,
984 SND_SOC_DAPM_POST_PMU),
985
986SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
987SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0),
988SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0),
989
990SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
991SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
992
993SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
994SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux),
995SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
996SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux),
997
998SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0),
999SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0),
1000SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0),
1001SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0),
1002
1003SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0),
1004SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0),
1005
1006SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0),
1007SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0),
1008SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0),
1009SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0),
1010
1011SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0),
1012SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0),
1013
1014SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),
1015SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),
1016
1017SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0),
1018SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0),
1019SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0),
1020SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0),
1021
1022SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0,
1023 dsp2txl, ARRAY_SIZE(dsp2txl)),
1024SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0,
1025 dsp2txr, ARRAY_SIZE(dsp2txr)),
1026SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0,
1027 dsp1txl, ARRAY_SIZE(dsp1txl)),
1028SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0,
1029 dsp1txr, ARRAY_SIZE(dsp1txr)),
1030
1031SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,
1032 dac2l_mix, ARRAY_SIZE(dac2l_mix)),
1033SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,
1034 dac2r_mix, ARRAY_SIZE(dac2r_mix)),
1035SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
1036 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
1037SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
1038 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
1039
1040SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0),
1041SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0),
1042SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0),
1043SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0),
1044
1045SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1,
1046 WM8915_POWER_MANAGEMENT_4, 9, 0),
1047SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2,
1048 WM8915_POWER_MANAGEMENT_4, 8, 0),
1049
1050SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1,
1051 WM8915_POWER_MANAGEMENT_6, 9, 0),
1052SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2,
1053 WM8915_POWER_MANAGEMENT_6, 8, 0),
1054
1055SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5,
1056 WM8915_POWER_MANAGEMENT_4, 5, 0),
1057SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4,
1058 WM8915_POWER_MANAGEMENT_4, 4, 0),
1059SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3,
1060 WM8915_POWER_MANAGEMENT_4, 3, 0),
1061SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2,
1062 WM8915_POWER_MANAGEMENT_4, 2, 0),
1063SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1,
1064 WM8915_POWER_MANAGEMENT_4, 1, 0),
1065SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0,
1066 WM8915_POWER_MANAGEMENT_4, 0, 0),
1067
1068SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5,
1069 WM8915_POWER_MANAGEMENT_6, 5, 0),
1070SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4,
1071 WM8915_POWER_MANAGEMENT_6, 4, 0),
1072SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3,
1073 WM8915_POWER_MANAGEMENT_6, 3, 0),
1074SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2,
1075 WM8915_POWER_MANAGEMENT_6, 2, 0),
1076SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1,
1077 WM8915_POWER_MANAGEMENT_6, 1, 0),
1078SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0,
1079 WM8915_POWER_MANAGEMENT_6, 0, 0),
1080
1081/* We route as stereo pairs so define some dummy widgets to squash
1082 * things down for now. RXA = 0,1, RXB = 2,3 and so on */
1083SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),
1084SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),
1085SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),
1086SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),
1087SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),
1088
1089SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),
1090SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),
1091SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),
1092
1093SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),
1094SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),
1095SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),
1096SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),
1097
1098SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0),
1099SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0),
1100SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start,
1101 SND_SOC_DAPM_POST_PMU),
1102SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0),
1103SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,
1104 rmv_short_event,
1105 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1106
1107SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0),
1108SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0),
1109SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start,
1110 SND_SOC_DAPM_POST_PMU),
1111SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0),
1112SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,
1113 rmv_short_event,
1114 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1115
1116SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
1117SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0),
1118SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start,
1119 SND_SOC_DAPM_POST_PMU),
1120SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0),
1121SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,
1122 rmv_short_event,
1123 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1124
1125SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
1126SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0),
1127SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start,
1128 SND_SOC_DAPM_POST_PMU),
1129SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0),
1130SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,
1131 rmv_short_event,
1132 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
1133
1134SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1135SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1136SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1137SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1138SND_SOC_DAPM_OUTPUT("SPKDAT"),
1139};
1140
1141static const struct snd_soc_dapm_route wm8915_dapm_routes[] = {
1142 { "AIFCLK", NULL, "SYSCLK" },
1143 { "SYSDSPCLK", NULL, "SYSCLK" },
1144 { "Charge Pump", NULL, "SYSCLK" },
1145
1146 { "MICB1", NULL, "LDO2" },
1147 { "MICB2", NULL, "LDO2" },
1148
1149 { "IN1L PGA", NULL, "IN2LN" },
1150 { "IN1L PGA", NULL, "IN2LP" },
1151 { "IN1L PGA", NULL, "IN1LN" },
1152 { "IN1L PGA", NULL, "IN1LP" },
1153
1154 { "IN1R PGA", NULL, "IN2RN" },
1155 { "IN1R PGA", NULL, "IN2RP" },
1156 { "IN1R PGA", NULL, "IN1RN" },
1157 { "IN1R PGA", NULL, "IN1RP" },
1158
1159 { "ADCL", NULL, "IN1L PGA" },
1160
1161 { "ADCR", NULL, "IN1R PGA" },
1162
1163 { "DMIC1L", NULL, "DMIC1DAT" },
1164 { "DMIC1R", NULL, "DMIC1DAT" },
1165 { "DMIC2L", NULL, "DMIC2DAT" },
1166 { "DMIC2R", NULL, "DMIC2DAT" },
1167
1168 { "DMIC2L", NULL, "DMIC2" },
1169 { "DMIC2R", NULL, "DMIC2" },
1170 { "DMIC1L", NULL, "DMIC1" },
1171 { "DMIC1R", NULL, "DMIC1" },
1172
1173 { "IN1L Mux", "ADC", "ADCL" },
1174 { "IN1L Mux", "DMIC1", "DMIC1L" },
1175 { "IN1L Mux", "DMIC2", "DMIC2L" },
1176
1177 { "IN1R Mux", "ADC", "ADCR" },
1178 { "IN1R Mux", "DMIC1", "DMIC1R" },
1179 { "IN1R Mux", "DMIC2", "DMIC2R" },
1180
1181 { "IN2L Mux", "ADC", "ADCL" },
1182 { "IN2L Mux", "DMIC1", "DMIC1L" },
1183 { "IN2L Mux", "DMIC2", "DMIC2L" },
1184
1185 { "IN2R Mux", "ADC", "ADCR" },
1186 { "IN2R Mux", "DMIC1", "DMIC1R" },
1187 { "IN2R Mux", "DMIC2", "DMIC2R" },
1188
1189 { "Left Sidetone", "IN1", "IN1L Mux" },
1190 { "Left Sidetone", "IN2", "IN2L Mux" },
1191
1192 { "Right Sidetone", "IN1", "IN1R Mux" },
1193 { "Right Sidetone", "IN2", "IN2R Mux" },
1194
1195 { "DSP1TXL", "IN1 Switch", "IN1L Mux" },
1196 { "DSP1TXR", "IN1 Switch", "IN1R Mux" },
1197
1198 { "DSP2TXL", "IN1 Switch", "IN2L Mux" },
1199 { "DSP2TXR", "IN1 Switch", "IN2R Mux" },
1200
1201 { "AIF1TX0", NULL, "DSP1TXL" },
1202 { "AIF1TX1", NULL, "DSP1TXR" },
1203 { "AIF1TX2", NULL, "DSP2TXL" },
1204 { "AIF1TX3", NULL, "DSP2TXR" },
1205 { "AIF1TX4", NULL, "AIF2RX0" },
1206 { "AIF1TX5", NULL, "AIF2RX1" },
1207
1208 { "AIF1RX0", NULL, "AIFCLK" },
1209 { "AIF1RX1", NULL, "AIFCLK" },
1210 { "AIF1RX2", NULL, "AIFCLK" },
1211 { "AIF1RX3", NULL, "AIFCLK" },
1212 { "AIF1RX4", NULL, "AIFCLK" },
1213 { "AIF1RX5", NULL, "AIFCLK" },
1214
1215 { "AIF2RX0", NULL, "AIFCLK" },
1216 { "AIF2RX1", NULL, "AIFCLK" },
1217
1218 { "DSP1RXL", NULL, "SYSDSPCLK" },
1219 { "DSP1RXR", NULL, "SYSDSPCLK" },
1220 { "DSP2RXL", NULL, "SYSDSPCLK" },
1221 { "DSP2RXR", NULL, "SYSDSPCLK" },
1222 { "DSP1TXL", NULL, "SYSDSPCLK" },
1223 { "DSP1TXR", NULL, "SYSDSPCLK" },
1224 { "DSP2TXL", NULL, "SYSDSPCLK" },
1225 { "DSP2TXR", NULL, "SYSDSPCLK" },
1226
1227 { "AIF1RXA", NULL, "AIF1RX0" },
1228 { "AIF1RXA", NULL, "AIF1RX1" },
1229 { "AIF1RXB", NULL, "AIF1RX2" },
1230 { "AIF1RXB", NULL, "AIF1RX3" },
1231 { "AIF1RXC", NULL, "AIF1RX4" },
1232 { "AIF1RXC", NULL, "AIF1RX5" },
1233
1234 { "AIF2RX", NULL, "AIF2RX0" },
1235 { "AIF2RX", NULL, "AIF2RX1" },
1236
1237 { "AIF2TX", "DSP2", "DSP2TX" },
1238 { "AIF2TX", "DSP1", "DSP1RX" },
1239 { "AIF2TX", "AIF1", "AIF1RXC" },
1240
1241 { "DSP1RXL", NULL, "DSP1RX" },
1242 { "DSP1RXR", NULL, "DSP1RX" },
1243 { "DSP2RXL", NULL, "DSP2RX" },
1244 { "DSP2RXR", NULL, "DSP2RX" },
1245
1246 { "DSP2TX", NULL, "DSP2TXL" },
1247 { "DSP2TX", NULL, "DSP2TXR" },
1248
1249 { "DSP1RX", "AIF1", "AIF1RXA" },
1250 { "DSP1RX", "AIF2", "AIF2RX" },
1251
1252 { "DSP2RX", "AIF1", "AIF1RXB" },
1253 { "DSP2RX", "AIF2", "AIF2RX" },
1254
1255 { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },
1256 { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },
1257 { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1258 { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1259
1260 { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },
1261 { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },
1262 { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1263 { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1264
1265 { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },
1266 { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },
1267 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
1268 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
1269
1270 { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },
1271 { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },
1272 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
1273 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
1274
1275 { "DAC1L", NULL, "DAC1L Mixer" },
1276 { "DAC1R", NULL, "DAC1R Mixer" },
1277 { "DAC2L", NULL, "DAC2L Mixer" },
1278 { "DAC2R", NULL, "DAC2R Mixer" },
1279
1280 { "HPOUT2L PGA", NULL, "Charge Pump" },
1281 { "HPOUT2L PGA", NULL, "DAC2L" },
1282 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },
1283 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },
1284 { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" },
1285 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" },
1286
1287 { "HPOUT2R PGA", NULL, "Charge Pump" },
1288 { "HPOUT2R PGA", NULL, "DAC2R" },
1289 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },
1290 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },
1291 { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" },
1292 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" },
1293
1294 { "HPOUT1L PGA", NULL, "Charge Pump" },
1295 { "HPOUT1L PGA", NULL, "DAC1L" },
1296 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },
1297 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },
1298 { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" },
1299 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" },
1300
1301 { "HPOUT1R PGA", NULL, "Charge Pump" },
1302 { "HPOUT1R PGA", NULL, "DAC1R" },
1303 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },
1304 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },
1305 { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" },
1306 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" },
1307
1308 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },
1309 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },
1310 { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },
1311 { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },
1312
1313 { "SPKL", "DAC1L", "DAC1L" },
1314 { "SPKL", "DAC1R", "DAC1R" },
1315 { "SPKL", "DAC2L", "DAC2L" },
1316 { "SPKL", "DAC2R", "DAC2R" },
1317
1318 { "SPKR", "DAC1L", "DAC1L" },
1319 { "SPKR", "DAC1R", "DAC1R" },
1320 { "SPKR", "DAC2L", "DAC2L" },
1321 { "SPKR", "DAC2R", "DAC2R" },
1322
1323 { "SPKL PGA", NULL, "SPKL" },
1324 { "SPKR PGA", NULL, "SPKR" },
1325
1326 { "SPKDAT", NULL, "SPKL PGA" },
1327 { "SPKDAT", NULL, "SPKR PGA" },
1328};
1329
1330static int wm8915_readable_register(struct snd_soc_codec *codec,
1331 unsigned int reg)
1332{
1333 /* Due to the sparseness of the register map the compiler
1334 * output from an explicit switch statement ends up being much
1335 * more efficient than a table.
1336 */
1337 switch (reg) {
1338 case WM8915_SOFTWARE_RESET:
1339 case WM8915_POWER_MANAGEMENT_1:
1340 case WM8915_POWER_MANAGEMENT_2:
1341 case WM8915_POWER_MANAGEMENT_3:
1342 case WM8915_POWER_MANAGEMENT_4:
1343 case WM8915_POWER_MANAGEMENT_5:
1344 case WM8915_POWER_MANAGEMENT_6:
1345 case WM8915_POWER_MANAGEMENT_7:
1346 case WM8915_POWER_MANAGEMENT_8:
1347 case WM8915_LEFT_LINE_INPUT_VOLUME:
1348 case WM8915_RIGHT_LINE_INPUT_VOLUME:
1349 case WM8915_LINE_INPUT_CONTROL:
1350 case WM8915_DAC1_HPOUT1_VOLUME:
1351 case WM8915_DAC2_HPOUT2_VOLUME:
1352 case WM8915_DAC1_LEFT_VOLUME:
1353 case WM8915_DAC1_RIGHT_VOLUME:
1354 case WM8915_DAC2_LEFT_VOLUME:
1355 case WM8915_DAC2_RIGHT_VOLUME:
1356 case WM8915_OUTPUT1_LEFT_VOLUME:
1357 case WM8915_OUTPUT1_RIGHT_VOLUME:
1358 case WM8915_OUTPUT2_LEFT_VOLUME:
1359 case WM8915_OUTPUT2_RIGHT_VOLUME:
1360 case WM8915_MICBIAS_1:
1361 case WM8915_MICBIAS_2:
1362 case WM8915_LDO_1:
1363 case WM8915_LDO_2:
1364 case WM8915_ACCESSORY_DETECT_MODE_1:
1365 case WM8915_ACCESSORY_DETECT_MODE_2:
1366 case WM8915_HEADPHONE_DETECT_1:
1367 case WM8915_HEADPHONE_DETECT_2:
1368 case WM8915_MIC_DETECT_1:
1369 case WM8915_MIC_DETECT_2:
1370 case WM8915_MIC_DETECT_3:
1371 case WM8915_CHARGE_PUMP_1:
1372 case WM8915_CHARGE_PUMP_2:
1373 case WM8915_DC_SERVO_1:
1374 case WM8915_DC_SERVO_2:
1375 case WM8915_DC_SERVO_3:
1376 case WM8915_DC_SERVO_5:
1377 case WM8915_DC_SERVO_6:
1378 case WM8915_DC_SERVO_7:
1379 case WM8915_DC_SERVO_READBACK_0:
1380 case WM8915_ANALOGUE_HP_1:
1381 case WM8915_ANALOGUE_HP_2:
1382 case WM8915_CHIP_REVISION:
1383 case WM8915_CONTROL_INTERFACE_1:
1384 case WM8915_WRITE_SEQUENCER_CTRL_1:
1385 case WM8915_WRITE_SEQUENCER_CTRL_2:
1386 case WM8915_AIF_CLOCKING_1:
1387 case WM8915_AIF_CLOCKING_2:
1388 case WM8915_CLOCKING_1:
1389 case WM8915_CLOCKING_2:
1390 case WM8915_AIF_RATE:
1391 case WM8915_FLL_CONTROL_1:
1392 case WM8915_FLL_CONTROL_2:
1393 case WM8915_FLL_CONTROL_3:
1394 case WM8915_FLL_CONTROL_4:
1395 case WM8915_FLL_CONTROL_5:
1396 case WM8915_FLL_CONTROL_6:
1397 case WM8915_FLL_EFS_1:
1398 case WM8915_FLL_EFS_2:
1399 case WM8915_AIF1_CONTROL:
1400 case WM8915_AIF1_BCLK:
1401 case WM8915_AIF1_TX_LRCLK_1:
1402 case WM8915_AIF1_TX_LRCLK_2:
1403 case WM8915_AIF1_RX_LRCLK_1:
1404 case WM8915_AIF1_RX_LRCLK_2:
1405 case WM8915_AIF1TX_DATA_CONFIGURATION_1:
1406 case WM8915_AIF1TX_DATA_CONFIGURATION_2:
1407 case WM8915_AIF1RX_DATA_CONFIGURATION:
1408 case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION:
1409 case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION:
1410 case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION:
1411 case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION:
1412 case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION:
1413 case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION:
1414 case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION:
1415 case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION:
1416 case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION:
1417 case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION:
1418 case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION:
1419 case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION:
1420 case WM8915_AIF1RX_MONO_CONFIGURATION:
1421 case WM8915_AIF1TX_TEST:
1422 case WM8915_AIF2_CONTROL:
1423 case WM8915_AIF2_BCLK:
1424 case WM8915_AIF2_TX_LRCLK_1:
1425 case WM8915_AIF2_TX_LRCLK_2:
1426 case WM8915_AIF2_RX_LRCLK_1:
1427 case WM8915_AIF2_RX_LRCLK_2:
1428 case WM8915_AIF2TX_DATA_CONFIGURATION_1:
1429 case WM8915_AIF2TX_DATA_CONFIGURATION_2:
1430 case WM8915_AIF2RX_DATA_CONFIGURATION:
1431 case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION:
1432 case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION:
1433 case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION:
1434 case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION:
1435 case WM8915_AIF2RX_MONO_CONFIGURATION:
1436 case WM8915_AIF2TX_TEST:
1437 case WM8915_DSP1_TX_LEFT_VOLUME:
1438 case WM8915_DSP1_TX_RIGHT_VOLUME:
1439 case WM8915_DSP1_RX_LEFT_VOLUME:
1440 case WM8915_DSP1_RX_RIGHT_VOLUME:
1441 case WM8915_DSP1_TX_FILTERS:
1442 case WM8915_DSP1_RX_FILTERS_1:
1443 case WM8915_DSP1_RX_FILTERS_2:
1444 case WM8915_DSP1_DRC_1:
1445 case WM8915_DSP1_DRC_2:
1446 case WM8915_DSP1_DRC_3:
1447 case WM8915_DSP1_DRC_4:
1448 case WM8915_DSP1_DRC_5:
1449 case WM8915_DSP1_RX_EQ_GAINS_1:
1450 case WM8915_DSP1_RX_EQ_GAINS_2:
1451 case WM8915_DSP1_RX_EQ_BAND_1_A:
1452 case WM8915_DSP1_RX_EQ_BAND_1_B:
1453 case WM8915_DSP1_RX_EQ_BAND_1_PG:
1454 case WM8915_DSP1_RX_EQ_BAND_2_A:
1455 case WM8915_DSP1_RX_EQ_BAND_2_B:
1456 case WM8915_DSP1_RX_EQ_BAND_2_C:
1457 case WM8915_DSP1_RX_EQ_BAND_2_PG:
1458 case WM8915_DSP1_RX_EQ_BAND_3_A:
1459 case WM8915_DSP1_RX_EQ_BAND_3_B:
1460 case WM8915_DSP1_RX_EQ_BAND_3_C:
1461 case WM8915_DSP1_RX_EQ_BAND_3_PG:
1462 case WM8915_DSP1_RX_EQ_BAND_4_A:
1463 case WM8915_DSP1_RX_EQ_BAND_4_B:
1464 case WM8915_DSP1_RX_EQ_BAND_4_C:
1465 case WM8915_DSP1_RX_EQ_BAND_4_PG:
1466 case WM8915_DSP1_RX_EQ_BAND_5_A:
1467 case WM8915_DSP1_RX_EQ_BAND_5_B:
1468 case WM8915_DSP1_RX_EQ_BAND_5_PG:
1469 case WM8915_DSP2_TX_LEFT_VOLUME:
1470 case WM8915_DSP2_TX_RIGHT_VOLUME:
1471 case WM8915_DSP2_RX_LEFT_VOLUME:
1472 case WM8915_DSP2_RX_RIGHT_VOLUME:
1473 case WM8915_DSP2_TX_FILTERS:
1474 case WM8915_DSP2_RX_FILTERS_1:
1475 case WM8915_DSP2_RX_FILTERS_2:
1476 case WM8915_DSP2_DRC_1:
1477 case WM8915_DSP2_DRC_2:
1478 case WM8915_DSP2_DRC_3:
1479 case WM8915_DSP2_DRC_4:
1480 case WM8915_DSP2_DRC_5:
1481 case WM8915_DSP2_RX_EQ_GAINS_1:
1482 case WM8915_DSP2_RX_EQ_GAINS_2:
1483 case WM8915_DSP2_RX_EQ_BAND_1_A:
1484 case WM8915_DSP2_RX_EQ_BAND_1_B:
1485 case WM8915_DSP2_RX_EQ_BAND_1_PG:
1486 case WM8915_DSP2_RX_EQ_BAND_2_A:
1487 case WM8915_DSP2_RX_EQ_BAND_2_B:
1488 case WM8915_DSP2_RX_EQ_BAND_2_C:
1489 case WM8915_DSP2_RX_EQ_BAND_2_PG:
1490 case WM8915_DSP2_RX_EQ_BAND_3_A:
1491 case WM8915_DSP2_RX_EQ_BAND_3_B:
1492 case WM8915_DSP2_RX_EQ_BAND_3_C:
1493 case WM8915_DSP2_RX_EQ_BAND_3_PG:
1494 case WM8915_DSP2_RX_EQ_BAND_4_A:
1495 case WM8915_DSP2_RX_EQ_BAND_4_B:
1496 case WM8915_DSP2_RX_EQ_BAND_4_C:
1497 case WM8915_DSP2_RX_EQ_BAND_4_PG:
1498 case WM8915_DSP2_RX_EQ_BAND_5_A:
1499 case WM8915_DSP2_RX_EQ_BAND_5_B:
1500 case WM8915_DSP2_RX_EQ_BAND_5_PG:
1501 case WM8915_DAC1_MIXER_VOLUMES:
1502 case WM8915_DAC1_LEFT_MIXER_ROUTING:
1503 case WM8915_DAC1_RIGHT_MIXER_ROUTING:
1504 case WM8915_DAC2_MIXER_VOLUMES:
1505 case WM8915_DAC2_LEFT_MIXER_ROUTING:
1506 case WM8915_DAC2_RIGHT_MIXER_ROUTING:
1507 case WM8915_DSP1_TX_LEFT_MIXER_ROUTING:
1508 case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING:
1509 case WM8915_DSP2_TX_LEFT_MIXER_ROUTING:
1510 case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING:
1511 case WM8915_DSP_TX_MIXER_SELECT:
1512 case WM8915_DAC_SOFTMUTE:
1513 case WM8915_OVERSAMPLING:
1514 case WM8915_SIDETONE:
1515 case WM8915_GPIO_1:
1516 case WM8915_GPIO_2:
1517 case WM8915_GPIO_3:
1518 case WM8915_GPIO_4:
1519 case WM8915_GPIO_5:
1520 case WM8915_PULL_CONTROL_1:
1521 case WM8915_PULL_CONTROL_2:
1522 case WM8915_INTERRUPT_STATUS_1:
1523 case WM8915_INTERRUPT_STATUS_2:
1524 case WM8915_INTERRUPT_RAW_STATUS_2:
1525 case WM8915_INTERRUPT_STATUS_1_MASK:
1526 case WM8915_INTERRUPT_STATUS_2_MASK:
1527 case WM8915_INTERRUPT_CONTROL:
1528 case WM8915_LEFT_PDM_SPEAKER:
1529 case WM8915_RIGHT_PDM_SPEAKER:
1530 case WM8915_PDM_SPEAKER_MUTE_SEQUENCE:
1531 case WM8915_PDM_SPEAKER_VOLUME:
1532 return 1;
1533 default:
1534 return 0;
1535 }
1536}
1537
1538static int wm8915_volatile_register(struct snd_soc_codec *codec,
1539 unsigned int reg)
1540{
1541 switch (reg) {
1542 case WM8915_SOFTWARE_RESET:
1543 case WM8915_CHIP_REVISION:
1544 case WM8915_LDO_1:
1545 case WM8915_LDO_2:
1546 case WM8915_INTERRUPT_STATUS_1:
1547 case WM8915_INTERRUPT_STATUS_2:
1548 case WM8915_INTERRUPT_RAW_STATUS_2:
1549 case WM8915_DC_SERVO_READBACK_0:
1550 case WM8915_DC_SERVO_2:
1551 case WM8915_DC_SERVO_6:
1552 case WM8915_DC_SERVO_7:
1553 case WM8915_FLL_CONTROL_6:
1554 case WM8915_MIC_DETECT_3:
1555 case WM8915_HEADPHONE_DETECT_1:
1556 case WM8915_HEADPHONE_DETECT_2:
1557 return 1;
1558 default:
1559 return 0;
1560 }
1561}
1562
1563static int wm8915_reset(struct snd_soc_codec *codec)
1564{
1565 return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915);
1566}
1567
1568static int wm8915_set_bias_level(struct snd_soc_codec *codec,
1569 enum snd_soc_bias_level level)
1570{
1571 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1572 int ret;
1573
1574 switch (level) {
1575 case SND_SOC_BIAS_ON:
1576 break;
1577
1578 case SND_SOC_BIAS_PREPARE:
1579 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
1580 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1581 WM8915_BG_ENA, WM8915_BG_ENA);
1582 msleep(2);
1583 }
1584 break;
1585
1586 case SND_SOC_BIAS_STANDBY:
1587 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1588 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
1589 wm8915->supplies);
1590 if (ret != 0) {
1591 dev_err(codec->dev,
1592 "Failed to enable supplies: %d\n",
1593 ret);
1594 return ret;
1595 }
1596
1597 if (wm8915->pdata.ldo_ena >= 0) {
1598 gpio_set_value_cansleep(wm8915->pdata.ldo_ena,
1599 1);
1600 msleep(5);
1601 }
1602
1603 codec->cache_only = false;
1604 snd_soc_cache_sync(codec);
1605 }
1606
1607 snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1,
1608 WM8915_BG_ENA, 0);
1609 break;
1610
1611 case SND_SOC_BIAS_OFF:
1612 codec->cache_only = true;
1613 if (wm8915->pdata.ldo_ena >= 0)
1614 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
1615 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies),
1616 wm8915->supplies);
1617 break;
1618 }
1619
1620 codec->dapm.bias_level = level;
1621
1622 return 0;
1623}
1624
1625static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1626{
1627 struct snd_soc_codec *codec = dai->codec;
1628 int aifctrl = 0;
1629 int bclk = 0;
1630 int lrclk_tx = 0;
1631 int lrclk_rx = 0;
1632 int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;
1633
1634 switch (dai->id) {
1635 case 0:
1636 aifctrl_reg = WM8915_AIF1_CONTROL;
1637 bclk_reg = WM8915_AIF1_BCLK;
1638 lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2;
1639 lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2;
1640 break;
1641 case 1:
1642 aifctrl_reg = WM8915_AIF2_CONTROL;
1643 bclk_reg = WM8915_AIF2_BCLK;
1644 lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2;
1645 lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2;
1646 break;
1647 default:
1648 BUG();
1649 return -EINVAL;
1650 }
1651
1652 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1653 case SND_SOC_DAIFMT_NB_NF:
1654 break;
1655 case SND_SOC_DAIFMT_IB_NF:
1656 bclk |= WM8915_AIF1_BCLK_INV;
1657 break;
1658 case SND_SOC_DAIFMT_NB_IF:
1659 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1660 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1661 break;
1662 case SND_SOC_DAIFMT_IB_IF:
1663 bclk |= WM8915_AIF1_BCLK_INV;
1664 lrclk_tx |= WM8915_AIF1TX_LRCLK_INV;
1665 lrclk_rx |= WM8915_AIF1RX_LRCLK_INV;
1666 break;
1667 }
1668
1669 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1670 case SND_SOC_DAIFMT_CBS_CFS:
1671 break;
1672 case SND_SOC_DAIFMT_CBS_CFM:
1673 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1674 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1675 break;
1676 case SND_SOC_DAIFMT_CBM_CFS:
1677 bclk |= WM8915_AIF1_BCLK_MSTR;
1678 break;
1679 case SND_SOC_DAIFMT_CBM_CFM:
1680 bclk |= WM8915_AIF1_BCLK_MSTR;
1681 lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR;
1682 lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR;
1683 break;
1684 default:
1685 return -EINVAL;
1686 }
1687
1688 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1689 case SND_SOC_DAIFMT_DSP_A:
1690 break;
1691 case SND_SOC_DAIFMT_DSP_B:
1692 aifctrl |= 1;
1693 break;
1694 case SND_SOC_DAIFMT_I2S:
1695 aifctrl |= 2;
1696 break;
1697 case SND_SOC_DAIFMT_LEFT_J:
1698 aifctrl |= 3;
1699 break;
1700 default:
1701 return -EINVAL;
1702 }
1703
1704 snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl);
1705 snd_soc_update_bits(codec, bclk_reg,
1706 WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR,
1707 bclk);
1708 snd_soc_update_bits(codec, lrclk_tx_reg,
1709 WM8915_AIF1TX_LRCLK_INV |
1710 WM8915_AIF1TX_LRCLK_MSTR,
1711 lrclk_tx);
1712 snd_soc_update_bits(codec, lrclk_rx_reg,
1713 WM8915_AIF1RX_LRCLK_INV |
1714 WM8915_AIF1RX_LRCLK_MSTR,
1715 lrclk_rx);
1716
1717 return 0;
1718}
1719
1720static const int bclk_divs[] = {
1721 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1722};
1723
1724static const int dsp_divs[] = {
1725 48000, 32000, 16000, 8000
1726};
1727
1728static int wm8915_hw_params(struct snd_pcm_substream *substream,
1729 struct snd_pcm_hw_params *params,
1730 struct snd_soc_dai *dai)
1731{
1732 struct snd_soc_codec *codec = dai->codec;
1733 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1734 int bits, i, bclk_rate, best, cur_val;
1735 int aifdata = 0;
1736 int bclk = 0;
1737 int lrclk = 0;
1738 int dsp = 0;
1739 int aifdata_reg, bclk_reg, lrclk_reg, dsp_shift;
1740
1741 if (!wm8915->sysclk) {
1742 dev_err(codec->dev, "SYSCLK not configured\n");
1743 return -EINVAL;
1744 }
1745
1746 switch (dai->id) {
1747 case 0:
1748 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1749 (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) {
1750 aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION;
1751 lrclk_reg = WM8915_AIF1_RX_LRCLK_1;
1752 } else {
1753 aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1;
1754 lrclk_reg = WM8915_AIF1_TX_LRCLK_1;
1755 }
1756 bclk_reg = WM8915_AIF1_BCLK;
1757 dsp_shift = 0;
1758 break;
1759 case 1:
1760 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1761 (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) {
1762 aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION;
1763 lrclk_reg = WM8915_AIF2_RX_LRCLK_1;
1764 } else {
1765 aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1;
1766 lrclk_reg = WM8915_AIF2_TX_LRCLK_1;
1767 }
1768 bclk_reg = WM8915_AIF2_BCLK;
1769 dsp_shift = WM8915_DSP2_DIV_SHIFT;
1770 break;
1771 default:
1772 BUG();
1773 return -EINVAL;
1774 }
1775
1776 bclk_rate = snd_soc_params_to_bclk(params);
1777 if (bclk_rate < 0) {
1778 dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate);
1779 return bclk_rate;
1780 }
1781
1782 /* Needs looking at for TDM */
1783 bits = snd_pcm_format_width(params_format(params));
1784 if (bits < 0)
1785 return bits;
1786 aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits;
1787
1788 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {
1789 if (dsp_divs[i] == params_rate(params))
1790 break;
1791 }
1792 if (i == ARRAY_SIZE(dsp_divs)) {
1793 dev_err(codec->dev, "Unsupported sample rate %dHz\n",
1794 params_rate(params));
1795 return -EINVAL;
1796 }
1797 dsp |= i << dsp_shift;
1798
1799 /* Pick a divisor for BCLK as close as we can get to ideal */
1800 best = 0;
1801 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1802 cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate;
1803 if (cur_val < 0) /* BCLK table is sorted */
1804 break;
1805 best = i;
1806 }
1807 bclk_rate = wm8915->sysclk / bclk_divs[best];
1808 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1809 bclk_divs[best], bclk_rate);
1810 bclk |= best;
1811
1812 lrclk = bclk_rate / params_rate(params);
1813 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
1814 lrclk, bclk_rate / lrclk);
1815
1816 snd_soc_update_bits(codec, aifdata_reg,
1817 WM8915_AIF1TX_WL_MASK |
1818 WM8915_AIF1TX_SLOT_LEN_MASK,
1819 aifdata);
1820 snd_soc_update_bits(codec, bclk_reg, WM8915_AIF1_BCLK_DIV_MASK, bclk);
1821 snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK,
1822 lrclk);
1823 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2,
1824 WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp);
1825
1826 wm8915->rx_rate[dai->id] = params_rate(params);
1827
1828 return 0;
1829}
1830
1831static int wm8915_set_sysclk(struct snd_soc_dai *dai,
1832 int clk_id, unsigned int freq, int dir)
1833{
1834 struct snd_soc_codec *codec = dai->codec;
1835 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
1836 int lfclk = 0;
1837 int ratediv = 0;
1838 int src;
1839 int old;
1840
1841 /* Disable SYSCLK while we reconfigure */
1842 old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1) & WM8915_SYSCLK_ENA;
1843 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1844 WM8915_SYSCLK_ENA, 0);
1845
1846 switch (clk_id) {
1847 case WM8915_SYSCLK_MCLK1:
1848 wm8915->sysclk = freq;
1849 src = 0;
1850 break;
1851 case WM8915_SYSCLK_MCLK2:
1852 wm8915->sysclk = freq;
1853 src = 1;
1854 break;
1855 case WM8915_SYSCLK_FLL:
1856 wm8915->sysclk = freq;
1857 src = 2;
1858 break;
1859 default:
1860 dev_err(codec->dev, "Unsupported clock source %d\n", clk_id);
1861 return -EINVAL;
1862 }
1863
1864 switch (wm8915->sysclk) {
1865 case 6144000:
1866 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1867 WM8915_SYSCLK_RATE, 0);
1868 break;
1869 case 24576000:
1870 ratediv = WM8915_SYSCLK_DIV;
1871 case 12288000:
1872 snd_soc_update_bits(codec, WM8915_AIF_RATE,
1873 WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE);
1874 break;
1875 case 32000:
1876 case 32768:
1877 lfclk = WM8915_LFCLK_ENA;
1878 break;
1879 default:
1880 dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
1881 wm8915->sysclk);
1882 return -EINVAL;
1883 }
1884
1885 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1886 WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK,
1887 src << WM8915_SYSCLK_SRC_SHIFT | ratediv);
1888 snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk);
1889 snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1,
1890 WM8915_SYSCLK_ENA, old);
1891
1892 return 0;
1893}
1894
1895struct _fll_div {
1896 u16 fll_fratio;
1897 u16 fll_outdiv;
1898 u16 fll_refclk_div;
1899 u16 fll_loop_gain;
1900 u16 fll_ref_freq;
1901 u16 n;
1902 u16 theta;
1903 u16 lambda;
1904};
1905
1906static struct {
1907 unsigned int min;
1908 unsigned int max;
1909 u16 fll_fratio;
1910 int ratio;
1911} fll_fratios[] = {
1912 { 0, 64000, 4, 16 },
1913 { 64000, 128000, 3, 8 },
1914 { 128000, 256000, 2, 4 },
1915 { 256000, 1000000, 1, 2 },
1916 { 1000000, 13500000, 0, 1 },
1917};
1918
1919static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1920 unsigned int Fout)
1921{
1922 unsigned int target;
1923 unsigned int div;
1924 unsigned int fratio, gcd_fll;
1925 int i;
1926
1927 /* Fref must be <=13.5MHz */
1928 div = 1;
1929 fll_div->fll_refclk_div = 0;
1930 while ((Fref / div) > 13500000) {
1931 div *= 2;
1932 fll_div->fll_refclk_div++;
1933
1934 if (div > 8) {
1935 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1936 Fref);
1937 return -EINVAL;
1938 }
1939 }
1940
1941 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1942
1943 /* Apply the division for our remaining calculations */
1944 Fref /= div;
1945
1946 if (Fref >= 3000000)
1947 fll_div->fll_loop_gain = 5;
1948 else
1949 fll_div->fll_loop_gain = 0;
1950
1951 if (Fref >= 48000)
1952 fll_div->fll_ref_freq = 0;
1953 else
1954 fll_div->fll_ref_freq = 1;
1955
1956 /* Fvco should be 90-100MHz; don't check the upper bound */
1957 div = 2;
1958 while (Fout * div < 90000000) {
1959 div++;
1960 if (div > 64) {
1961 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1962 Fout);
1963 return -EINVAL;
1964 }
1965 }
1966 target = Fout * div;
1967 fll_div->fll_outdiv = div - 1;
1968
1969 pr_debug("FLL Fvco=%dHz\n", target);
1970
1971 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1972 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1973 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1974 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1975 fratio = fll_fratios[i].ratio;
1976 break;
1977 }
1978 }
1979 if (i == ARRAY_SIZE(fll_fratios)) {
1980 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1981 return -EINVAL;
1982 }
1983
1984 fll_div->n = target / (fratio * Fref);
1985
1986 if (target % Fref == 0) {
1987 fll_div->theta = 0;
1988 fll_div->lambda = 0;
1989 } else {
1990 gcd_fll = gcd(target, fratio * Fref);
1991
1992 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1993 / gcd_fll;
1994 fll_div->lambda = (fratio * Fref) / gcd_fll;
1995 }
1996
1997 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1998 fll_div->n, fll_div->theta, fll_div->lambda);
1999 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
2000 fll_div->fll_fratio, fll_div->fll_outdiv,
2001 fll_div->fll_refclk_div);
2002
2003 return 0;
2004}
2005
2006static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2007 unsigned int Fref, unsigned int Fout)
2008{
2009 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2010 struct _fll_div fll_div;
2011 unsigned long timeout;
2012 int ret, reg;
2013
2014 /* Any change? */
2015 if (source == wm8915->fll_src && Fref == wm8915->fll_fref &&
2016 Fout == wm8915->fll_fout)
2017 return 0;
2018
2019 if (Fout == 0) {
2020 dev_dbg(codec->dev, "FLL disabled\n");
2021
2022 wm8915->fll_fref = 0;
2023 wm8915->fll_fout = 0;
2024
2025 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2026 WM8915_FLL_ENA, 0);
2027
2028 return 0;
2029 }
2030
2031 ret = fll_factors(&fll_div, Fref, Fout);
2032 if (ret != 0)
2033 return ret;
2034
2035 switch (source) {
2036 case WM8915_FLL_MCLK1:
2037 reg = 0;
2038 break;
2039 case WM8915_FLL_MCLK2:
2040 reg = 1;
2041 break;
2042 case WM8915_FLL_DACLRCLK1:
2043 reg = 2;
2044 break;
2045 case WM8915_FLL_BCLK1:
2046 reg = 3;
2047 break;
2048 default:
2049 dev_err(codec->dev, "Unknown FLL source %d\n", ret);
2050 return -EINVAL;
2051 }
2052
2053 reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT;
2054 reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT;
2055
2056 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5,
2057 WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ |
2058 WM8915_FLL_REFCLK_SRC_MASK, reg);
2059
2060 reg = 0;
2061 if (fll_div.theta || fll_div.lambda)
2062 reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT);
2063 else
2064 reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT;
2065 snd_soc_write(codec, WM8915_FLL_EFS_2, reg);
2066
2067 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2,
2068 WM8915_FLL_OUTDIV_MASK |
2069 WM8915_FLL_FRATIO_MASK,
2070 (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) |
2071 (fll_div.fll_fratio));
2072
2073 snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta);
2074
2075 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4,
2076 WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK,
2077 (fll_div.n << WM8915_FLL_N_SHIFT) |
2078 fll_div.fll_loop_gain);
2079
2080 snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda);
2081
2082 snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1,
2083 WM8915_FLL_ENA, WM8915_FLL_ENA);
2084
2085 /* The FLL supports live reconfiguration - kick that in case we were
2086 * already enabled.
2087 */
2088 snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK);
2089
2090 /* Wait for the FLL to lock, using the interrupt if possible */
2091 if (Fref > 1000000)
2092 timeout = usecs_to_jiffies(300);
2093 else
2094 timeout = msecs_to_jiffies(2);
2095
2096 wait_for_completion_timeout(&wm8915->fll_lock, timeout);
2097
2098 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2099
2100 wm8915->fll_fref = Fref;
2101 wm8915->fll_fout = Fout;
2102 wm8915->fll_src = source;
2103
2104 return 0;
2105}
2106
2107#ifdef CONFIG_GPIOLIB
2108static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip)
2109{
2110 return container_of(chip, struct wm8915_priv, gpio_chip);
2111}
2112
2113static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2114{
2115 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2116 struct snd_soc_codec *codec = wm8915->codec;
2117
2118 snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2119 WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT);
2120}
2121
2122static int wm8915_gpio_direction_out(struct gpio_chip *chip,
2123 unsigned offset, int value)
2124{
2125 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2126 struct snd_soc_codec *codec = wm8915->codec;
2127 int val;
2128
2129 val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT);
2130
2131 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2132 WM8915_GP1_FN_MASK | WM8915_GP1_DIR |
2133 WM8915_GP1_LVL, val);
2134}
2135
2136static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset)
2137{
2138 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2139 struct snd_soc_codec *codec = wm8915->codec;
2140 int ret;
2141
2142 ret = snd_soc_read(codec, WM8915_GPIO_1 + offset);
2143 if (ret < 0)
2144 return ret;
2145
2146 return (ret & WM8915_GP1_LVL) != 0;
2147}
2148
2149static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2150{
2151 struct wm8915_priv *wm8915 = gpio_to_wm8915(chip);
2152 struct snd_soc_codec *codec = wm8915->codec;
2153
2154 return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset,
2155 WM8915_GP1_FN_MASK | WM8915_GP1_DIR,
2156 (1 << WM8915_GP1_FN_SHIFT) |
2157 (1 << WM8915_GP1_DIR_SHIFT));
2158}
2159
2160static struct gpio_chip wm8915_template_chip = {
2161 .label = "wm8915",
2162 .owner = THIS_MODULE,
2163 .direction_output = wm8915_gpio_direction_out,
2164 .set = wm8915_gpio_set,
2165 .direction_input = wm8915_gpio_direction_in,
2166 .get = wm8915_gpio_get,
2167 .can_sleep = 1,
2168};
2169
2170static void wm8915_init_gpio(struct snd_soc_codec *codec)
2171{
2172 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2173 int ret;
2174
2175 wm8915->gpio_chip = wm8915_template_chip;
2176 wm8915->gpio_chip.ngpio = 5;
2177 wm8915->gpio_chip.dev = codec->dev;
2178
2179 if (wm8915->pdata.gpio_base)
2180 wm8915->gpio_chip.base = wm8915->pdata.gpio_base;
2181 else
2182 wm8915->gpio_chip.base = -1;
2183
2184 ret = gpiochip_add(&wm8915->gpio_chip);
2185 if (ret != 0)
2186 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2187}
2188
2189static void wm8915_free_gpio(struct snd_soc_codec *codec)
2190{
2191 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2192 int ret;
2193
2194 ret = gpiochip_remove(&wm8915->gpio_chip);
2195 if (ret != 0)
2196 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2197}
2198#else
2199static void wm8915_init_gpio(struct snd_soc_codec *codec)
2200{
2201}
2202
2203static void wm8915_free_gpio(struct snd_soc_codec *codec)
2204{
2205}
2206#endif
2207
2208/**
2209 * wm8915_detect - Enable default WM8915 jack detection
2210 *
2211 * The WM8915 has advanced accessory detection support for headsets.
2212 * This function provides a default implementation which integrates
2213 * the majority of this functionality with minimal user configuration.
2214 *
2215 * This will detect headset, headphone and short circuit button and
2216 * will also detect inverted microphone ground connections and update
2217 * the polarity of the connections.
2218 */
2219int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2220 wm8915_polarity_fn polarity_cb)
2221{
2222 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2223
2224 wm8915->jack = jack;
2225 wm8915->detecting = true;
2226 wm8915->polarity_cb = polarity_cb;
2227
2228 if (wm8915->polarity_cb)
2229 wm8915->polarity_cb(codec, 0);
2230
2231 /* Clear discarge to avoid noise during detection */
2232 snd_soc_update_bits(codec, WM8915_MICBIAS_1,
2233 WM8915_MICB1_DISCH, 0);
2234 snd_soc_update_bits(codec, WM8915_MICBIAS_2,
2235 WM8915_MICB2_DISCH, 0);
2236
2237 /* LDO2 powers the microphones, SYSCLK clocks detection */
2238 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2");
2239 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2240
2241 /* We start off just enabling microphone detection - even a
2242 * plain headphone will trigger detection.
2243 */
2244 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2245 WM8915_MICD_ENA, WM8915_MICD_ENA);
2246
2247 /* Slowest detection rate, gives debounce for initial detection */
2248 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2249 WM8915_MICD_RATE_MASK,
2250 WM8915_MICD_RATE_MASK);
2251
2252 /* Enable interrupts and we're off */
2253 snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK,
2254 WM8915_IM_MICD_EINT, 0);
2255
2256 return 0;
2257}
2258EXPORT_SYMBOL_GPL(wm8915_detect);
2259
2260static void wm8915_micd(struct snd_soc_codec *codec)
2261{
2262 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2263 int val, reg;
2264
2265 val = snd_soc_read(codec, WM8915_MIC_DETECT_3);
2266
2267 dev_dbg(codec->dev, "Microphone event: %x\n", val);
2268
2269 if (!(val & WM8915_MICD_VALID)) {
2270 dev_warn(codec->dev, "Microphone detection state invalid\n");
2271 return;
2272 }
2273
2274 /* No accessory, reset everything and report removal */
2275 if (!(val & WM8915_MICD_STS)) {
2276 dev_dbg(codec->dev, "Jack removal detected\n");
2277 wm8915->jack_mic = false;
2278 wm8915->detecting = true;
2279 snd_soc_jack_report(wm8915->jack, 0,
2280 SND_JACK_HEADSET | SND_JACK_BTN_0);
2281 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2282 WM8915_MICD_RATE_MASK,
2283 WM8915_MICD_RATE_MASK);
2284 return;
2285 }
2286
2287 /* If the measurement is very high we've got a microphone but
2288 * do a little debounce to account for mechanical issues.
2289 */
2290 if (val & 0x400) {
2291 dev_dbg(codec->dev, "Microphone detected\n");
2292 snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET,
2293 SND_JACK_HEADSET | SND_JACK_BTN_0);
2294 wm8915->jack_mic = true;
2295 wm8915->detecting = false;
2296 }
2297
2298 /* If we detected a lower impedence during initial startup
2299 * then we probably have the wrong polarity, flip it. Don't
2300 * do this for the lowest impedences to speed up detection of
2301 * plain headphones.
2302 */
2303 if (wm8915->detecting && (val & 0x3f0)) {
2304 reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2);
2305 reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2306 WM8915_MICD_BIAS_SRC;
2307 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2308 WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC |
2309 WM8915_MICD_BIAS_SRC, reg);
2310
2311 if (wm8915->polarity_cb)
2312 wm8915->polarity_cb(codec,
2313 (reg & WM8915_MICD_SRC) != 0);
2314
2315 dev_dbg(codec->dev, "Set microphone polarity to %d\n",
2316 (reg & WM8915_MICD_SRC) != 0);
2317
2318 return;
2319 }
2320
2321 /* Don't distinguish between buttons, just report any low
2322 * impedence as BTN_0.
2323 */
2324 if (val & 0x3fc) {
2325 if (wm8915->jack_mic) {
2326 dev_dbg(codec->dev, "Mic button detected\n");
2327 snd_soc_jack_report(wm8915->jack,
2328 SND_JACK_HEADSET | SND_JACK_BTN_0,
2329 SND_JACK_HEADSET | SND_JACK_BTN_0);
2330 } else {
2331 dev_dbg(codec->dev, "Headphone detected\n");
2332 snd_soc_jack_report(wm8915->jack,
2333 SND_JACK_HEADPHONE,
2334 SND_JACK_HEADSET |
2335 SND_JACK_BTN_0);
2336 wm8915->detecting = false;
2337 }
2338 }
2339
2340 /* Increase poll rate to give better responsiveness for buttons */
2341 if (!wm8915->detecting)
2342 snd_soc_update_bits(codec, WM8915_MIC_DETECT_1,
2343 WM8915_MICD_RATE_MASK,
2344 5 << WM8915_MICD_RATE_SHIFT);
2345}
2346
2347static irqreturn_t wm8915_irq(int irq, void *data)
2348{
2349 struct snd_soc_codec *codec = data;
2350 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2351 int irq_val;
2352
2353 irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2);
2354 if (irq_val < 0) {
2355 dev_err(codec->dev, "Failed to read IRQ status: %d\n",
2356 irq_val);
2357 return IRQ_NONE;
2358 }
2359 irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK);
2360
2361 if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) {
2362 dev_dbg(codec->dev, "DC servo IRQ\n");
2363 complete(&wm8915->dcs_done);
2364 }
2365
2366 if (irq_val & WM8915_FIFOS_ERR_EINT)
2367 dev_err(codec->dev, "Digital core FIFO error\n");
2368
2369 if (irq_val & WM8915_FLL_LOCK_EINT) {
2370 dev_dbg(codec->dev, "FLL locked\n");
2371 complete(&wm8915->fll_lock);
2372 }
2373
2374 if (irq_val & WM8915_MICD_EINT)
2375 wm8915_micd(codec);
2376
2377 if (irq_val) {
2378 snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val);
2379
2380 return IRQ_HANDLED;
2381 } else {
2382 return IRQ_NONE;
2383 }
2384}
2385
2386static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec)
2387{
2388 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2389 struct wm8915_pdata *pdata = &wm8915->pdata;
2390
2391 struct snd_kcontrol_new controls[] = {
2392 SOC_ENUM_EXT("DSP1 EQ Mode",
2393 wm8915->retune_mobile_enum,
2394 wm8915_get_retune_mobile_enum,
2395 wm8915_put_retune_mobile_enum),
2396 SOC_ENUM_EXT("DSP2 EQ Mode",
2397 wm8915->retune_mobile_enum,
2398 wm8915_get_retune_mobile_enum,
2399 wm8915_put_retune_mobile_enum),
2400 };
2401 int ret, i, j;
2402 const char **t;
2403
2404 /* We need an array of texts for the enum API but the number
2405 * of texts is likely to be less than the number of
2406 * configurations due to the sample rate dependency of the
2407 * configurations. */
2408 wm8915->num_retune_mobile_texts = 0;
2409 wm8915->retune_mobile_texts = NULL;
2410 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2411 for (j = 0; j < wm8915->num_retune_mobile_texts; j++) {
2412 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2413 wm8915->retune_mobile_texts[j]) == 0)
2414 break;
2415 }
2416
2417 if (j != wm8915->num_retune_mobile_texts)
2418 continue;
2419
2420 /* Expand the array... */
2421 t = krealloc(wm8915->retune_mobile_texts,
2422 sizeof(char *) *
2423 (wm8915->num_retune_mobile_texts + 1),
2424 GFP_KERNEL);
2425 if (t == NULL)
2426 continue;
2427
2428 /* ...store the new entry... */
2429 t[wm8915->num_retune_mobile_texts] =
2430 pdata->retune_mobile_cfgs[i].name;
2431
2432 /* ...and remember the new version. */
2433 wm8915->num_retune_mobile_texts++;
2434 wm8915->retune_mobile_texts = t;
2435 }
2436
2437 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2438 wm8915->num_retune_mobile_texts);
2439
2440 wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts;
2441 wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts;
2442
2443 ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
2444 if (ret != 0)
2445 dev_err(codec->dev,
2446 "Failed to add ReTune Mobile controls: %d\n", ret);
2447}
2448
2449static int wm8915_probe(struct snd_soc_codec *codec)
2450{
2451 int ret;
2452 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2453 struct i2c_client *i2c = to_i2c_client(codec->dev);
2454 struct snd_soc_dapm_context *dapm = &codec->dapm;
2455 int i, irq_flags;
2456
2457 wm8915->codec = codec;
2458
2459 init_completion(&wm8915->dcs_done);
2460 init_completion(&wm8915->fll_lock);
2461
2462 dapm->idle_bias_off = true;
2463 dapm->bias_level = SND_SOC_BIAS_OFF;
2464
2465 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2466 if (ret != 0) {
2467 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2468 goto err;
2469 }
2470
2471 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2472 wm8915->supplies[i].supply = wm8915_supply_names[i];
2473
2474 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies),
2475 wm8915->supplies);
2476 if (ret != 0) {
2477 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2478 goto err;
2479 }
2480
2481 wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0;
2482 wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1;
2483 wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2;
2484 wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3;
2485 wm8915->disable_nb[4].notifier_call = wm8915_regulator_event_4;
2486 wm8915->disable_nb[5].notifier_call = wm8915_regulator_event_5;
2487
2488 /* This should really be moved into the regulator core */
2489 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) {
2490 ret = regulator_register_notifier(wm8915->supplies[i].consumer,
2491 &wm8915->disable_nb[i]);
2492 if (ret != 0) {
2493 dev_err(codec->dev,
2494 "Failed to register regulator notifier: %d\n",
2495 ret);
2496 }
2497 }
2498
2499 ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies),
2500 wm8915->supplies);
2501 if (ret != 0) {
2502 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2503 goto err_get;
2504 }
2505
2506 if (wm8915->pdata.ldo_ena >= 0) {
2507 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1);
2508 msleep(5);
2509 }
2510
2511 ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET);
2512 if (ret < 0) {
2513 dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
2514 goto err_enable;
2515 }
2516 if (ret != 0x8915) {
2517 dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret);
2518 ret = -EINVAL;
2519 goto err_enable;
2520 }
2521
2522 ret = snd_soc_read(codec, WM8915_CHIP_REVISION);
2523 if (ret < 0) {
2524 dev_err(codec->dev, "Failed to read device revision: %d\n",
2525 ret);
2526 goto err_enable;
2527 }
2528
2529 dev_info(codec->dev, "revision %c\n",
2530 (ret & WM8915_CHIP_REV_MASK) + 'A');
2531
2532 if (wm8915->pdata.ldo_ena >= 0) {
2533 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2534 } else {
2535 ret = wm8915_reset(codec);
2536 if (ret < 0) {
2537 dev_err(codec->dev, "Failed to issue reset\n");
2538 goto err_enable;
2539 }
2540 }
2541
2542 codec->cache_only = true;
2543
2544 /* Apply platform data settings */
2545 snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL,
2546 WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK,
2547 wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT |
2548 wm8915->pdata.inr_mode);
2549
2550 for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) {
2551 if (!wm8915->pdata.gpio_default[i])
2552 continue;
2553
2554 snd_soc_write(codec, WM8915_GPIO_1 + i,
2555 wm8915->pdata.gpio_default[i] & 0xffff);
2556 }
2557
2558 if (wm8915->pdata.spkmute_seq)
2559 snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE,
2560 WM8915_SPK_MUTE_ENDIAN |
2561 WM8915_SPK_MUTE_SEQ1_MASK,
2562 wm8915->pdata.spkmute_seq);
2563
2564 snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2,
2565 WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC |
2566 WM8915_MICD_SRC, wm8915->pdata.micdet_def);
2567
2568 /* Latch volume update bits */
2569 snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME,
2570 WM8915_IN1_VU, WM8915_IN1_VU);
2571 snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME,
2572 WM8915_IN1_VU, WM8915_IN1_VU);
2573
2574 snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME,
2575 WM8915_DAC1_VU, WM8915_DAC1_VU);
2576 snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME,
2577 WM8915_DAC1_VU, WM8915_DAC1_VU);
2578 snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME,
2579 WM8915_DAC2_VU, WM8915_DAC2_VU);
2580 snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME,
2581 WM8915_DAC2_VU, WM8915_DAC2_VU);
2582
2583 snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME,
2584 WM8915_DAC1_VU, WM8915_DAC1_VU);
2585 snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME,
2586 WM8915_DAC1_VU, WM8915_DAC1_VU);
2587 snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME,
2588 WM8915_DAC2_VU, WM8915_DAC2_VU);
2589 snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME,
2590 WM8915_DAC2_VU, WM8915_DAC2_VU);
2591
2592 snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME,
2593 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2594 snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME,
2595 WM8915_DSP1TX_VU, WM8915_DSP1TX_VU);
2596 snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME,
2597 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2598 snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME,
2599 WM8915_DSP2TX_VU, WM8915_DSP2TX_VU);
2600
2601 snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME,
2602 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2603 snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME,
2604 WM8915_DSP1RX_VU, WM8915_DSP1RX_VU);
2605 snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME,
2606 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2607 snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME,
2608 WM8915_DSP2RX_VU, WM8915_DSP2RX_VU);
2609
2610 /* No support currently for the underclocked TDM modes and
2611 * pick a default TDM layout with each channel pair working with
2612 * slots 0 and 1. */
2613 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION,
2614 WM8915_AIF1RX_CHAN0_SLOTS_MASK |
2615 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2616 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2617 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION,
2618 WM8915_AIF1RX_CHAN1_SLOTS_MASK |
2619 WM8915_AIF1RX_CHAN1_START_SLOT_MASK,
2620 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2621 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION,
2622 WM8915_AIF1RX_CHAN2_SLOTS_MASK |
2623 WM8915_AIF1RX_CHAN2_START_SLOT_MASK,
2624 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2625 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION,
2626 WM8915_AIF1RX_CHAN3_SLOTS_MASK |
2627 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2628 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2629 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION,
2630 WM8915_AIF1RX_CHAN4_SLOTS_MASK |
2631 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2632 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2633 snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION,
2634 WM8915_AIF1RX_CHAN5_SLOTS_MASK |
2635 WM8915_AIF1RX_CHAN0_START_SLOT_MASK,
2636 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2637
2638 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION,
2639 WM8915_AIF2RX_CHAN0_SLOTS_MASK |
2640 WM8915_AIF2RX_CHAN0_START_SLOT_MASK,
2641 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2642 snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION,
2643 WM8915_AIF2RX_CHAN1_SLOTS_MASK |
2644 WM8915_AIF2RX_CHAN1_START_SLOT_MASK,
2645 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2646
2647 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION,
2648 WM8915_AIF1TX_CHAN0_SLOTS_MASK |
2649 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2650 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2651 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2652 WM8915_AIF1TX_CHAN1_SLOTS_MASK |
2653 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2654 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2655 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION,
2656 WM8915_AIF1TX_CHAN2_SLOTS_MASK |
2657 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2658 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2659 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION,
2660 WM8915_AIF1TX_CHAN3_SLOTS_MASK |
2661 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2662 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2663 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION,
2664 WM8915_AIF1TX_CHAN4_SLOTS_MASK |
2665 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2666 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2667 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION,
2668 WM8915_AIF1TX_CHAN5_SLOTS_MASK |
2669 WM8915_AIF1TX_CHAN0_START_SLOT_MASK,
2670 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2671
2672 snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION,
2673 WM8915_AIF2TX_CHAN0_SLOTS_MASK |
2674 WM8915_AIF2TX_CHAN0_START_SLOT_MASK,
2675 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2676 snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION,
2677 WM8915_AIF2TX_CHAN1_SLOTS_MASK |
2678 WM8915_AIF2TX_CHAN1_START_SLOT_MASK,
2679 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2680
2681 if (wm8915->pdata.num_retune_mobile_cfgs)
2682 wm8915_retune_mobile_pdata(codec);
2683 else
2684 snd_soc_add_controls(codec, wm8915_eq_controls,
2685 ARRAY_SIZE(wm8915_eq_controls));
2686
2687 /* If the TX LRCLK pins are not in LRCLK mode configure the
2688 * AIFs to source their clocks from the RX LRCLKs.
2689 */
2690 if ((snd_soc_read(codec, WM8915_GPIO_1)))
2691 snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2,
2692 WM8915_AIF1TX_LRCLK_MODE,
2693 WM8915_AIF1TX_LRCLK_MODE);
2694
2695 if ((snd_soc_read(codec, WM8915_GPIO_2)))
2696 snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2,
2697 WM8915_AIF2TX_LRCLK_MODE,
2698 WM8915_AIF2TX_LRCLK_MODE);
2699
2700 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2701
2702 wm8915_init_gpio(codec);
2703
2704 if (i2c->irq) {
2705 if (wm8915->pdata.irq_flags)
2706 irq_flags = wm8915->pdata.irq_flags;
2707 else
2708 irq_flags = IRQF_TRIGGER_LOW;
2709
2710 irq_flags |= IRQF_ONESHOT;
2711
2712 ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq,
2713 irq_flags, "wm8915", codec);
2714 if (ret == 0) {
2715 /* Unmask the interrupt */
2716 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2717 WM8915_IM_IRQ, 0);
2718
2719 /* Enable error reporting and DC servo status */
2720 snd_soc_update_bits(codec,
2721 WM8915_INTERRUPT_STATUS_2_MASK,
2722 WM8915_IM_DCS_DONE_23_EINT |
2723 WM8915_IM_DCS_DONE_01_EINT |
2724 WM8915_IM_FLL_LOCK_EINT |
2725 WM8915_IM_FIFOS_ERR_EINT,
2726 0);
2727 } else {
2728 dev_err(codec->dev, "Failed to request IRQ: %d\n",
2729 ret);
2730 }
2731 }
2732
2733 return 0;
2734
2735err_enable:
2736 if (wm8915->pdata.ldo_ena >= 0)
2737 gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0);
2738
2739 regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2740err_get:
2741 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2742err:
2743 return ret;
2744}
2745
2746static int wm8915_remove(struct snd_soc_codec *codec)
2747{
2748 struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec);
2749 struct i2c_client *i2c = to_i2c_client(codec->dev);
2750 int i;
2751
2752 snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL,
2753 WM8915_IM_IRQ, WM8915_IM_IRQ);
2754
2755 if (i2c->irq)
2756 free_irq(i2c->irq, codec);
2757
2758 wm8915_free_gpio(codec);
2759
2760 for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++)
2761 regulator_unregister_notifier(wm8915->supplies[i].consumer,
2762 &wm8915->disable_nb[i]);
2763 regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies);
2764
2765 return 0;
2766}
2767
2768static struct snd_soc_codec_driver soc_codec_dev_wm8915 = {
2769 .probe = wm8915_probe,
2770 .remove = wm8915_remove,
2771 .set_bias_level = wm8915_set_bias_level,
2772 .seq_notifier = wm8915_seq_notifier,
2773 .reg_cache_size = WM8915_MAX_REGISTER + 1,
2774 .reg_word_size = sizeof(u16),
2775 .reg_cache_default = wm8915_reg,
2776 .volatile_register = wm8915_volatile_register,
2777 .readable_register = wm8915_readable_register,
2778 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2779 .controls = wm8915_snd_controls,
2780 .num_controls = ARRAY_SIZE(wm8915_snd_controls),
2781 .dapm_widgets = wm8915_dapm_widgets,
2782 .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets),
2783 .dapm_routes = wm8915_dapm_routes,
2784 .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes),
2785 .set_pll = wm8915_set_fll,
2786};
2787
2788#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
2789 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
2790#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
2791 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
2792 SNDRV_PCM_FMTBIT_S32_LE)
2793
2794static struct snd_soc_dai_ops wm8915_dai_ops = {
2795 .set_fmt = wm8915_set_fmt,
2796 .hw_params = wm8915_hw_params,
2797 .set_sysclk = wm8915_set_sysclk,
2798};
2799
2800static struct snd_soc_dai_driver wm8915_dai[] = {
2801 {
2802 .name = "wm8915-aif1",
2803 .playback = {
2804 .stream_name = "AIF1 Playback",
2805 .channels_min = 1,
2806 .channels_max = 6,
2807 .rates = WM8915_RATES,
2808 .formats = WM8915_FORMATS,
2809 },
2810 .capture = {
2811 .stream_name = "AIF1 Capture",
2812 .channels_min = 1,
2813 .channels_max = 6,
2814 .rates = WM8915_RATES,
2815 .formats = WM8915_FORMATS,
2816 },
2817 .ops = &wm8915_dai_ops,
2818 },
2819 {
2820 .name = "wm8915-aif2",
2821 .playback = {
2822 .stream_name = "AIF2 Playback",
2823 .channels_min = 1,
2824 .channels_max = 2,
2825 .rates = WM8915_RATES,
2826 .formats = WM8915_FORMATS,
2827 },
2828 .capture = {
2829 .stream_name = "AIF2 Capture",
2830 .channels_min = 1,
2831 .channels_max = 2,
2832 .rates = WM8915_RATES,
2833 .formats = WM8915_FORMATS,
2834 },
2835 .ops = &wm8915_dai_ops,
2836 },
2837};
2838
2839static __devinit int wm8915_i2c_probe(struct i2c_client *i2c,
2840 const struct i2c_device_id *id)
2841{
2842 struct wm8915_priv *wm8915;
2843 int ret;
2844
2845 wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL);
2846 if (wm8915 == NULL)
2847 return -ENOMEM;
2848
2849 i2c_set_clientdata(i2c, wm8915);
2850
2851 if (dev_get_platdata(&i2c->dev))
2852 memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev),
2853 sizeof(wm8915->pdata));
2854
2855 if (wm8915->pdata.ldo_ena > 0) {
2856 ret = gpio_request_one(wm8915->pdata.ldo_ena,
2857 GPIOF_OUT_INIT_LOW, "WM8915 ENA");
2858 if (ret < 0) {
2859 dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n",
2860 wm8915->pdata.ldo_ena, ret);
2861 goto err;
2862 }
2863 }
2864
2865 ret = snd_soc_register_codec(&i2c->dev,
2866 &soc_codec_dev_wm8915, wm8915_dai,
2867 ARRAY_SIZE(wm8915_dai));
2868 if (ret < 0)
2869 goto err_gpio;
2870
2871 return ret;
2872
2873err_gpio:
2874 if (wm8915->pdata.ldo_ena > 0)
2875 gpio_free(wm8915->pdata.ldo_ena);
2876err:
2877 kfree(wm8915);
2878
2879 return ret;
2880}
2881
2882static __devexit int wm8915_i2c_remove(struct i2c_client *client)
2883{
2884 struct wm8915_priv *wm8915 = i2c_get_clientdata(client);
2885
2886 snd_soc_unregister_codec(&client->dev);
2887 if (wm8915->pdata.ldo_ena > 0)
2888 gpio_free(wm8915->pdata.ldo_ena);
2889 kfree(i2c_get_clientdata(client));
2890 return 0;
2891}
2892
2893static const struct i2c_device_id wm8915_i2c_id[] = {
2894 { "wm8915", 0 },
2895 { }
2896};
2897MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id);
2898
2899static struct i2c_driver wm8915_i2c_driver = {
2900 .driver = {
2901 .name = "wm8915",
2902 .owner = THIS_MODULE,
2903 },
2904 .probe = wm8915_i2c_probe,
2905 .remove = __devexit_p(wm8915_i2c_remove),
2906 .id_table = wm8915_i2c_id,
2907};
2908
2909static int __init wm8915_modinit(void)
2910{
2911 int ret;
2912
2913 ret = i2c_add_driver(&wm8915_i2c_driver);
2914 if (ret != 0) {
2915 printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n",
2916 ret);
2917 }
2918
2919 return ret;
2920}
2921module_init(wm8915_modinit);
2922
2923static void __exit wm8915_exit(void)
2924{
2925 i2c_del_driver(&wm8915_i2c_driver);
2926}
2927module_exit(wm8915_exit);
2928
2929MODULE_DESCRIPTION("ASoC WM8915 driver");
2930MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2931MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8915.h b/sound/soc/codecs/wm8915.h
new file mode 100644
index 000000000000..200ffd7bf953
--- /dev/null
+++ b/sound/soc/codecs/wm8915.h
@@ -0,0 +1,3717 @@
1/*
2 * wm8915.h - WM8915 audio codec interface
3 *
4 * Copyright 2011 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _WM8915_H
14#define _WM8915_H
15
16#define WM8915_SYSCLK_MCLK1 1
17#define WM8915_SYSCLK_MCLK2 2
18#define WM8915_SYSCLK_FLL 3
19
20#define WM8915_FLL_MCLK1 1
21#define WM8915_FLL_MCLK2 2
22#define WM8915_FLL_DACLRCLK1 3
23#define WM8915_FLL_BCLK1 4
24
25typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity);
26
27int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
28 wm8915_polarity_fn polarity_cb);
29
30/*
31 * Register values.
32 */
33#define WM8915_SOFTWARE_RESET 0x00
34#define WM8915_POWER_MANAGEMENT_1 0x01
35#define WM8915_POWER_MANAGEMENT_2 0x02
36#define WM8915_POWER_MANAGEMENT_3 0x03
37#define WM8915_POWER_MANAGEMENT_4 0x04
38#define WM8915_POWER_MANAGEMENT_5 0x05
39#define WM8915_POWER_MANAGEMENT_6 0x06
40#define WM8915_POWER_MANAGEMENT_7 0x07
41#define WM8915_POWER_MANAGEMENT_8 0x08
42#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10
43#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11
44#define WM8915_LINE_INPUT_CONTROL 0x12
45#define WM8915_DAC1_HPOUT1_VOLUME 0x15
46#define WM8915_DAC2_HPOUT2_VOLUME 0x16
47#define WM8915_DAC1_LEFT_VOLUME 0x18
48#define WM8915_DAC1_RIGHT_VOLUME 0x19
49#define WM8915_DAC2_LEFT_VOLUME 0x1A
50#define WM8915_DAC2_RIGHT_VOLUME 0x1B
51#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C
52#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D
53#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E
54#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F
55#define WM8915_MICBIAS_1 0x20
56#define WM8915_MICBIAS_2 0x21
57#define WM8915_LDO_1 0x28
58#define WM8915_LDO_2 0x29
59#define WM8915_ACCESSORY_DETECT_MODE_1 0x30
60#define WM8915_ACCESSORY_DETECT_MODE_2 0x31
61#define WM8915_HEADPHONE_DETECT_1 0x34
62#define WM8915_HEADPHONE_DETECT_2 0x35
63#define WM8915_MIC_DETECT_1 0x38
64#define WM8915_MIC_DETECT_2 0x39
65#define WM8915_MIC_DETECT_3 0x3A
66#define WM8915_CHARGE_PUMP_1 0x40
67#define WM8915_CHARGE_PUMP_2 0x41
68#define WM8915_DC_SERVO_1 0x50
69#define WM8915_DC_SERVO_2 0x51
70#define WM8915_DC_SERVO_3 0x52
71#define WM8915_DC_SERVO_5 0x54
72#define WM8915_DC_SERVO_6 0x55
73#define WM8915_DC_SERVO_7 0x56
74#define WM8915_DC_SERVO_READBACK_0 0x57
75#define WM8915_ANALOGUE_HP_1 0x60
76#define WM8915_ANALOGUE_HP_2 0x61
77#define WM8915_CHIP_REVISION 0x100
78#define WM8915_CONTROL_INTERFACE_1 0x101
79#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110
80#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111
81#define WM8915_AIF_CLOCKING_1 0x200
82#define WM8915_AIF_CLOCKING_2 0x201
83#define WM8915_CLOCKING_1 0x208
84#define WM8915_CLOCKING_2 0x209
85#define WM8915_AIF_RATE 0x210
86#define WM8915_FLL_CONTROL_1 0x220
87#define WM8915_FLL_CONTROL_2 0x221
88#define WM8915_FLL_CONTROL_3 0x222
89#define WM8915_FLL_CONTROL_4 0x223
90#define WM8915_FLL_CONTROL_5 0x224
91#define WM8915_FLL_CONTROL_6 0x225
92#define WM8915_FLL_EFS_1 0x226
93#define WM8915_FLL_EFS_2 0x227
94#define WM8915_AIF1_CONTROL 0x300
95#define WM8915_AIF1_BCLK 0x301
96#define WM8915_AIF1_TX_LRCLK_1 0x302
97#define WM8915_AIF1_TX_LRCLK_2 0x303
98#define WM8915_AIF1_RX_LRCLK_1 0x304
99#define WM8915_AIF1_RX_LRCLK_2 0x305
100#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306
101#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307
102#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308
103#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309
104#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A
105#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B
106#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C
107#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D
108#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E
109#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F
110#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310
111#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311
112#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312
113#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313
114#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314
115#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315
116#define WM8915_AIF1TX_TEST 0x31A
117#define WM8915_AIF2_CONTROL 0x320
118#define WM8915_AIF2_BCLK 0x321
119#define WM8915_AIF2_TX_LRCLK_1 0x322
120#define WM8915_AIF2_TX_LRCLK_2 0x323
121#define WM8915_AIF2_RX_LRCLK_1 0x324
122#define WM8915_AIF2_RX_LRCLK_2 0x325
123#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326
124#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327
125#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328
126#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329
127#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A
128#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B
129#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C
130#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D
131#define WM8915_AIF2TX_TEST 0x32F
132#define WM8915_DSP1_TX_LEFT_VOLUME 0x400
133#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401
134#define WM8915_DSP1_RX_LEFT_VOLUME 0x402
135#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403
136#define WM8915_DSP1_TX_FILTERS 0x410
137#define WM8915_DSP1_RX_FILTERS_1 0x420
138#define WM8915_DSP1_RX_FILTERS_2 0x421
139#define WM8915_DSP1_DRC_1 0x440
140#define WM8915_DSP1_DRC_2 0x441
141#define WM8915_DSP1_DRC_3 0x442
142#define WM8915_DSP1_DRC_4 0x443
143#define WM8915_DSP1_DRC_5 0x444
144#define WM8915_DSP1_RX_EQ_GAINS_1 0x480
145#define WM8915_DSP1_RX_EQ_GAINS_2 0x481
146#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482
147#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483
148#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484
149#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485
150#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486
151#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487
152#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488
153#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489
154#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A
155#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B
156#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C
157#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D
158#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E
159#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F
160#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490
161#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491
162#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492
163#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493
164#define WM8915_DSP2_TX_LEFT_VOLUME 0x500
165#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501
166#define WM8915_DSP2_RX_LEFT_VOLUME 0x502
167#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503
168#define WM8915_DSP2_TX_FILTERS 0x510
169#define WM8915_DSP2_RX_FILTERS_1 0x520
170#define WM8915_DSP2_RX_FILTERS_2 0x521
171#define WM8915_DSP2_DRC_1 0x540
172#define WM8915_DSP2_DRC_2 0x541
173#define WM8915_DSP2_DRC_3 0x542
174#define WM8915_DSP2_DRC_4 0x543
175#define WM8915_DSP2_DRC_5 0x544
176#define WM8915_DSP2_RX_EQ_GAINS_1 0x580
177#define WM8915_DSP2_RX_EQ_GAINS_2 0x581
178#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582
179#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583
180#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584
181#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585
182#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586
183#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587
184#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588
185#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589
186#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A
187#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B
188#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C
189#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D
190#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E
191#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F
192#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590
193#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591
194#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592
195#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593
196#define WM8915_DAC1_MIXER_VOLUMES 0x600
197#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601
198#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602
199#define WM8915_DAC2_MIXER_VOLUMES 0x603
200#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604
201#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605
202#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606
203#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607
204#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608
205#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609
206#define WM8915_DSP_TX_MIXER_SELECT 0x60A
207#define WM8915_DAC_SOFTMUTE 0x610
208#define WM8915_OVERSAMPLING 0x620
209#define WM8915_SIDETONE 0x621
210#define WM8915_GPIO_1 0x700
211#define WM8915_GPIO_2 0x701
212#define WM8915_GPIO_3 0x702
213#define WM8915_GPIO_4 0x703
214#define WM8915_GPIO_5 0x704
215#define WM8915_PULL_CONTROL_1 0x720
216#define WM8915_PULL_CONTROL_2 0x721
217#define WM8915_INTERRUPT_STATUS_1 0x730
218#define WM8915_INTERRUPT_STATUS_2 0x731
219#define WM8915_INTERRUPT_RAW_STATUS_2 0x732
220#define WM8915_INTERRUPT_STATUS_1_MASK 0x738
221#define WM8915_INTERRUPT_STATUS_2_MASK 0x739
222#define WM8915_INTERRUPT_CONTROL 0x740
223#define WM8915_LEFT_PDM_SPEAKER 0x800
224#define WM8915_RIGHT_PDM_SPEAKER 0x801
225#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802
226#define WM8915_PDM_SPEAKER_VOLUME 0x803
227#define WM8915_WRITE_SEQUENCER_0 0x3000
228#define WM8915_WRITE_SEQUENCER_1 0x3001
229#define WM8915_WRITE_SEQUENCER_2 0x3002
230#define WM8915_WRITE_SEQUENCER_3 0x3003
231#define WM8915_WRITE_SEQUENCER_4 0x3004
232#define WM8915_WRITE_SEQUENCER_5 0x3005
233#define WM8915_WRITE_SEQUENCER_6 0x3006
234#define WM8915_WRITE_SEQUENCER_7 0x3007
235#define WM8915_WRITE_SEQUENCER_8 0x3008
236#define WM8915_WRITE_SEQUENCER_9 0x3009
237#define WM8915_WRITE_SEQUENCER_10 0x300A
238#define WM8915_WRITE_SEQUENCER_11 0x300B
239#define WM8915_WRITE_SEQUENCER_12 0x300C
240#define WM8915_WRITE_SEQUENCER_13 0x300D
241#define WM8915_WRITE_SEQUENCER_14 0x300E
242#define WM8915_WRITE_SEQUENCER_15 0x300F
243#define WM8915_WRITE_SEQUENCER_16 0x3010
244#define WM8915_WRITE_SEQUENCER_17 0x3011
245#define WM8915_WRITE_SEQUENCER_18 0x3012
246#define WM8915_WRITE_SEQUENCER_19 0x3013
247#define WM8915_WRITE_SEQUENCER_20 0x3014
248#define WM8915_WRITE_SEQUENCER_21 0x3015
249#define WM8915_WRITE_SEQUENCER_22 0x3016
250#define WM8915_WRITE_SEQUENCER_23 0x3017
251#define WM8915_WRITE_SEQUENCER_24 0x3018
252#define WM8915_WRITE_SEQUENCER_25 0x3019
253#define WM8915_WRITE_SEQUENCER_26 0x301A
254#define WM8915_WRITE_SEQUENCER_27 0x301B
255#define WM8915_WRITE_SEQUENCER_28 0x301C
256#define WM8915_WRITE_SEQUENCER_29 0x301D
257#define WM8915_WRITE_SEQUENCER_30 0x301E
258#define WM8915_WRITE_SEQUENCER_31 0x301F
259#define WM8915_WRITE_SEQUENCER_32 0x3020
260#define WM8915_WRITE_SEQUENCER_33 0x3021
261#define WM8915_WRITE_SEQUENCER_34 0x3022
262#define WM8915_WRITE_SEQUENCER_35 0x3023
263#define WM8915_WRITE_SEQUENCER_36 0x3024
264#define WM8915_WRITE_SEQUENCER_37 0x3025
265#define WM8915_WRITE_SEQUENCER_38 0x3026
266#define WM8915_WRITE_SEQUENCER_39 0x3027
267#define WM8915_WRITE_SEQUENCER_40 0x3028
268#define WM8915_WRITE_SEQUENCER_41 0x3029
269#define WM8915_WRITE_SEQUENCER_42 0x302A
270#define WM8915_WRITE_SEQUENCER_43 0x302B
271#define WM8915_WRITE_SEQUENCER_44 0x302C
272#define WM8915_WRITE_SEQUENCER_45 0x302D
273#define WM8915_WRITE_SEQUENCER_46 0x302E
274#define WM8915_WRITE_SEQUENCER_47 0x302F
275#define WM8915_WRITE_SEQUENCER_48 0x3030
276#define WM8915_WRITE_SEQUENCER_49 0x3031
277#define WM8915_WRITE_SEQUENCER_50 0x3032
278#define WM8915_WRITE_SEQUENCER_51 0x3033
279#define WM8915_WRITE_SEQUENCER_52 0x3034
280#define WM8915_WRITE_SEQUENCER_53 0x3035
281#define WM8915_WRITE_SEQUENCER_54 0x3036
282#define WM8915_WRITE_SEQUENCER_55 0x3037
283#define WM8915_WRITE_SEQUENCER_56 0x3038
284#define WM8915_WRITE_SEQUENCER_57 0x3039
285#define WM8915_WRITE_SEQUENCER_58 0x303A
286#define WM8915_WRITE_SEQUENCER_59 0x303B
287#define WM8915_WRITE_SEQUENCER_60 0x303C
288#define WM8915_WRITE_SEQUENCER_61 0x303D
289#define WM8915_WRITE_SEQUENCER_62 0x303E
290#define WM8915_WRITE_SEQUENCER_63 0x303F
291#define WM8915_WRITE_SEQUENCER_64 0x3040
292#define WM8915_WRITE_SEQUENCER_65 0x3041
293#define WM8915_WRITE_SEQUENCER_66 0x3042
294#define WM8915_WRITE_SEQUENCER_67 0x3043
295#define WM8915_WRITE_SEQUENCER_68 0x3044
296#define WM8915_WRITE_SEQUENCER_69 0x3045
297#define WM8915_WRITE_SEQUENCER_70 0x3046
298#define WM8915_WRITE_SEQUENCER_71 0x3047
299#define WM8915_WRITE_SEQUENCER_72 0x3048
300#define WM8915_WRITE_SEQUENCER_73 0x3049
301#define WM8915_WRITE_SEQUENCER_74 0x304A
302#define WM8915_WRITE_SEQUENCER_75 0x304B
303#define WM8915_WRITE_SEQUENCER_76 0x304C
304#define WM8915_WRITE_SEQUENCER_77 0x304D
305#define WM8915_WRITE_SEQUENCER_78 0x304E
306#define WM8915_WRITE_SEQUENCER_79 0x304F
307#define WM8915_WRITE_SEQUENCER_80 0x3050
308#define WM8915_WRITE_SEQUENCER_81 0x3051
309#define WM8915_WRITE_SEQUENCER_82 0x3052
310#define WM8915_WRITE_SEQUENCER_83 0x3053
311#define WM8915_WRITE_SEQUENCER_84 0x3054
312#define WM8915_WRITE_SEQUENCER_85 0x3055
313#define WM8915_WRITE_SEQUENCER_86 0x3056
314#define WM8915_WRITE_SEQUENCER_87 0x3057
315#define WM8915_WRITE_SEQUENCER_88 0x3058
316#define WM8915_WRITE_SEQUENCER_89 0x3059
317#define WM8915_WRITE_SEQUENCER_90 0x305A
318#define WM8915_WRITE_SEQUENCER_91 0x305B
319#define WM8915_WRITE_SEQUENCER_92 0x305C
320#define WM8915_WRITE_SEQUENCER_93 0x305D
321#define WM8915_WRITE_SEQUENCER_94 0x305E
322#define WM8915_WRITE_SEQUENCER_95 0x305F
323#define WM8915_WRITE_SEQUENCER_96 0x3060
324#define WM8915_WRITE_SEQUENCER_97 0x3061
325#define WM8915_WRITE_SEQUENCER_98 0x3062
326#define WM8915_WRITE_SEQUENCER_99 0x3063
327#define WM8915_WRITE_SEQUENCER_100 0x3064
328#define WM8915_WRITE_SEQUENCER_101 0x3065
329#define WM8915_WRITE_SEQUENCER_102 0x3066
330#define WM8915_WRITE_SEQUENCER_103 0x3067
331#define WM8915_WRITE_SEQUENCER_104 0x3068
332#define WM8915_WRITE_SEQUENCER_105 0x3069
333#define WM8915_WRITE_SEQUENCER_106 0x306A
334#define WM8915_WRITE_SEQUENCER_107 0x306B
335#define WM8915_WRITE_SEQUENCER_108 0x306C
336#define WM8915_WRITE_SEQUENCER_109 0x306D
337#define WM8915_WRITE_SEQUENCER_110 0x306E
338#define WM8915_WRITE_SEQUENCER_111 0x306F
339#define WM8915_WRITE_SEQUENCER_112 0x3070
340#define WM8915_WRITE_SEQUENCER_113 0x3071
341#define WM8915_WRITE_SEQUENCER_114 0x3072
342#define WM8915_WRITE_SEQUENCER_115 0x3073
343#define WM8915_WRITE_SEQUENCER_116 0x3074
344#define WM8915_WRITE_SEQUENCER_117 0x3075
345#define WM8915_WRITE_SEQUENCER_118 0x3076
346#define WM8915_WRITE_SEQUENCER_119 0x3077
347#define WM8915_WRITE_SEQUENCER_120 0x3078
348#define WM8915_WRITE_SEQUENCER_121 0x3079
349#define WM8915_WRITE_SEQUENCER_122 0x307A
350#define WM8915_WRITE_SEQUENCER_123 0x307B
351#define WM8915_WRITE_SEQUENCER_124 0x307C
352#define WM8915_WRITE_SEQUENCER_125 0x307D
353#define WM8915_WRITE_SEQUENCER_126 0x307E
354#define WM8915_WRITE_SEQUENCER_127 0x307F
355#define WM8915_WRITE_SEQUENCER_128 0x3080
356#define WM8915_WRITE_SEQUENCER_129 0x3081
357#define WM8915_WRITE_SEQUENCER_130 0x3082
358#define WM8915_WRITE_SEQUENCER_131 0x3083
359#define WM8915_WRITE_SEQUENCER_132 0x3084
360#define WM8915_WRITE_SEQUENCER_133 0x3085
361#define WM8915_WRITE_SEQUENCER_134 0x3086
362#define WM8915_WRITE_SEQUENCER_135 0x3087
363#define WM8915_WRITE_SEQUENCER_136 0x3088
364#define WM8915_WRITE_SEQUENCER_137 0x3089
365#define WM8915_WRITE_SEQUENCER_138 0x308A
366#define WM8915_WRITE_SEQUENCER_139 0x308B
367#define WM8915_WRITE_SEQUENCER_140 0x308C
368#define WM8915_WRITE_SEQUENCER_141 0x308D
369#define WM8915_WRITE_SEQUENCER_142 0x308E
370#define WM8915_WRITE_SEQUENCER_143 0x308F
371#define WM8915_WRITE_SEQUENCER_144 0x3090
372#define WM8915_WRITE_SEQUENCER_145 0x3091
373#define WM8915_WRITE_SEQUENCER_146 0x3092
374#define WM8915_WRITE_SEQUENCER_147 0x3093
375#define WM8915_WRITE_SEQUENCER_148 0x3094
376#define WM8915_WRITE_SEQUENCER_149 0x3095
377#define WM8915_WRITE_SEQUENCER_150 0x3096
378#define WM8915_WRITE_SEQUENCER_151 0x3097
379#define WM8915_WRITE_SEQUENCER_152 0x3098
380#define WM8915_WRITE_SEQUENCER_153 0x3099
381#define WM8915_WRITE_SEQUENCER_154 0x309A
382#define WM8915_WRITE_SEQUENCER_155 0x309B
383#define WM8915_WRITE_SEQUENCER_156 0x309C
384#define WM8915_WRITE_SEQUENCER_157 0x309D
385#define WM8915_WRITE_SEQUENCER_158 0x309E
386#define WM8915_WRITE_SEQUENCER_159 0x309F
387#define WM8915_WRITE_SEQUENCER_160 0x30A0
388#define WM8915_WRITE_SEQUENCER_161 0x30A1
389#define WM8915_WRITE_SEQUENCER_162 0x30A2
390#define WM8915_WRITE_SEQUENCER_163 0x30A3
391#define WM8915_WRITE_SEQUENCER_164 0x30A4
392#define WM8915_WRITE_SEQUENCER_165 0x30A5
393#define WM8915_WRITE_SEQUENCER_166 0x30A6
394#define WM8915_WRITE_SEQUENCER_167 0x30A7
395#define WM8915_WRITE_SEQUENCER_168 0x30A8
396#define WM8915_WRITE_SEQUENCER_169 0x30A9
397#define WM8915_WRITE_SEQUENCER_170 0x30AA
398#define WM8915_WRITE_SEQUENCER_171 0x30AB
399#define WM8915_WRITE_SEQUENCER_172 0x30AC
400#define WM8915_WRITE_SEQUENCER_173 0x30AD
401#define WM8915_WRITE_SEQUENCER_174 0x30AE
402#define WM8915_WRITE_SEQUENCER_175 0x30AF
403#define WM8915_WRITE_SEQUENCER_176 0x30B0
404#define WM8915_WRITE_SEQUENCER_177 0x30B1
405#define WM8915_WRITE_SEQUENCER_178 0x30B2
406#define WM8915_WRITE_SEQUENCER_179 0x30B3
407#define WM8915_WRITE_SEQUENCER_180 0x30B4
408#define WM8915_WRITE_SEQUENCER_181 0x30B5
409#define WM8915_WRITE_SEQUENCER_182 0x30B6
410#define WM8915_WRITE_SEQUENCER_183 0x30B7
411#define WM8915_WRITE_SEQUENCER_184 0x30B8
412#define WM8915_WRITE_SEQUENCER_185 0x30B9
413#define WM8915_WRITE_SEQUENCER_186 0x30BA
414#define WM8915_WRITE_SEQUENCER_187 0x30BB
415#define WM8915_WRITE_SEQUENCER_188 0x30BC
416#define WM8915_WRITE_SEQUENCER_189 0x30BD
417#define WM8915_WRITE_SEQUENCER_190 0x30BE
418#define WM8915_WRITE_SEQUENCER_191 0x30BF
419#define WM8915_WRITE_SEQUENCER_192 0x30C0
420#define WM8915_WRITE_SEQUENCER_193 0x30C1
421#define WM8915_WRITE_SEQUENCER_194 0x30C2
422#define WM8915_WRITE_SEQUENCER_195 0x30C3
423#define WM8915_WRITE_SEQUENCER_196 0x30C4
424#define WM8915_WRITE_SEQUENCER_197 0x30C5
425#define WM8915_WRITE_SEQUENCER_198 0x30C6
426#define WM8915_WRITE_SEQUENCER_199 0x30C7
427#define WM8915_WRITE_SEQUENCER_200 0x30C8
428#define WM8915_WRITE_SEQUENCER_201 0x30C9
429#define WM8915_WRITE_SEQUENCER_202 0x30CA
430#define WM8915_WRITE_SEQUENCER_203 0x30CB
431#define WM8915_WRITE_SEQUENCER_204 0x30CC
432#define WM8915_WRITE_SEQUENCER_205 0x30CD
433#define WM8915_WRITE_SEQUENCER_206 0x30CE
434#define WM8915_WRITE_SEQUENCER_207 0x30CF
435#define WM8915_WRITE_SEQUENCER_208 0x30D0
436#define WM8915_WRITE_SEQUENCER_209 0x30D1
437#define WM8915_WRITE_SEQUENCER_210 0x30D2
438#define WM8915_WRITE_SEQUENCER_211 0x30D3
439#define WM8915_WRITE_SEQUENCER_212 0x30D4
440#define WM8915_WRITE_SEQUENCER_213 0x30D5
441#define WM8915_WRITE_SEQUENCER_214 0x30D6
442#define WM8915_WRITE_SEQUENCER_215 0x30D7
443#define WM8915_WRITE_SEQUENCER_216 0x30D8
444#define WM8915_WRITE_SEQUENCER_217 0x30D9
445#define WM8915_WRITE_SEQUENCER_218 0x30DA
446#define WM8915_WRITE_SEQUENCER_219 0x30DB
447#define WM8915_WRITE_SEQUENCER_220 0x30DC
448#define WM8915_WRITE_SEQUENCER_221 0x30DD
449#define WM8915_WRITE_SEQUENCER_222 0x30DE
450#define WM8915_WRITE_SEQUENCER_223 0x30DF
451#define WM8915_WRITE_SEQUENCER_224 0x30E0
452#define WM8915_WRITE_SEQUENCER_225 0x30E1
453#define WM8915_WRITE_SEQUENCER_226 0x30E2
454#define WM8915_WRITE_SEQUENCER_227 0x30E3
455#define WM8915_WRITE_SEQUENCER_228 0x30E4
456#define WM8915_WRITE_SEQUENCER_229 0x30E5
457#define WM8915_WRITE_SEQUENCER_230 0x30E6
458#define WM8915_WRITE_SEQUENCER_231 0x30E7
459#define WM8915_WRITE_SEQUENCER_232 0x30E8
460#define WM8915_WRITE_SEQUENCER_233 0x30E9
461#define WM8915_WRITE_SEQUENCER_234 0x30EA
462#define WM8915_WRITE_SEQUENCER_235 0x30EB
463#define WM8915_WRITE_SEQUENCER_236 0x30EC
464#define WM8915_WRITE_SEQUENCER_237 0x30ED
465#define WM8915_WRITE_SEQUENCER_238 0x30EE
466#define WM8915_WRITE_SEQUENCER_239 0x30EF
467#define WM8915_WRITE_SEQUENCER_240 0x30F0
468#define WM8915_WRITE_SEQUENCER_241 0x30F1
469#define WM8915_WRITE_SEQUENCER_242 0x30F2
470#define WM8915_WRITE_SEQUENCER_243 0x30F3
471#define WM8915_WRITE_SEQUENCER_244 0x30F4
472#define WM8915_WRITE_SEQUENCER_245 0x30F5
473#define WM8915_WRITE_SEQUENCER_246 0x30F6
474#define WM8915_WRITE_SEQUENCER_247 0x30F7
475#define WM8915_WRITE_SEQUENCER_248 0x30F8
476#define WM8915_WRITE_SEQUENCER_249 0x30F9
477#define WM8915_WRITE_SEQUENCER_250 0x30FA
478#define WM8915_WRITE_SEQUENCER_251 0x30FB
479#define WM8915_WRITE_SEQUENCER_252 0x30FC
480#define WM8915_WRITE_SEQUENCER_253 0x30FD
481#define WM8915_WRITE_SEQUENCER_254 0x30FE
482#define WM8915_WRITE_SEQUENCER_255 0x30FF
483#define WM8915_WRITE_SEQUENCER_256 0x3100
484#define WM8915_WRITE_SEQUENCER_257 0x3101
485#define WM8915_WRITE_SEQUENCER_258 0x3102
486#define WM8915_WRITE_SEQUENCER_259 0x3103
487#define WM8915_WRITE_SEQUENCER_260 0x3104
488#define WM8915_WRITE_SEQUENCER_261 0x3105
489#define WM8915_WRITE_SEQUENCER_262 0x3106
490#define WM8915_WRITE_SEQUENCER_263 0x3107
491#define WM8915_WRITE_SEQUENCER_264 0x3108
492#define WM8915_WRITE_SEQUENCER_265 0x3109
493#define WM8915_WRITE_SEQUENCER_266 0x310A
494#define WM8915_WRITE_SEQUENCER_267 0x310B
495#define WM8915_WRITE_SEQUENCER_268 0x310C
496#define WM8915_WRITE_SEQUENCER_269 0x310D
497#define WM8915_WRITE_SEQUENCER_270 0x310E
498#define WM8915_WRITE_SEQUENCER_271 0x310F
499#define WM8915_WRITE_SEQUENCER_272 0x3110
500#define WM8915_WRITE_SEQUENCER_273 0x3111
501#define WM8915_WRITE_SEQUENCER_274 0x3112
502#define WM8915_WRITE_SEQUENCER_275 0x3113
503#define WM8915_WRITE_SEQUENCER_276 0x3114
504#define WM8915_WRITE_SEQUENCER_277 0x3115
505#define WM8915_WRITE_SEQUENCER_278 0x3116
506#define WM8915_WRITE_SEQUENCER_279 0x3117
507#define WM8915_WRITE_SEQUENCER_280 0x3118
508#define WM8915_WRITE_SEQUENCER_281 0x3119
509#define WM8915_WRITE_SEQUENCER_282 0x311A
510#define WM8915_WRITE_SEQUENCER_283 0x311B
511#define WM8915_WRITE_SEQUENCER_284 0x311C
512#define WM8915_WRITE_SEQUENCER_285 0x311D
513#define WM8915_WRITE_SEQUENCER_286 0x311E
514#define WM8915_WRITE_SEQUENCER_287 0x311F
515#define WM8915_WRITE_SEQUENCER_288 0x3120
516#define WM8915_WRITE_SEQUENCER_289 0x3121
517#define WM8915_WRITE_SEQUENCER_290 0x3122
518#define WM8915_WRITE_SEQUENCER_291 0x3123
519#define WM8915_WRITE_SEQUENCER_292 0x3124
520#define WM8915_WRITE_SEQUENCER_293 0x3125
521#define WM8915_WRITE_SEQUENCER_294 0x3126
522#define WM8915_WRITE_SEQUENCER_295 0x3127
523#define WM8915_WRITE_SEQUENCER_296 0x3128
524#define WM8915_WRITE_SEQUENCER_297 0x3129
525#define WM8915_WRITE_SEQUENCER_298 0x312A
526#define WM8915_WRITE_SEQUENCER_299 0x312B
527#define WM8915_WRITE_SEQUENCER_300 0x312C
528#define WM8915_WRITE_SEQUENCER_301 0x312D
529#define WM8915_WRITE_SEQUENCER_302 0x312E
530#define WM8915_WRITE_SEQUENCER_303 0x312F
531#define WM8915_WRITE_SEQUENCER_304 0x3130
532#define WM8915_WRITE_SEQUENCER_305 0x3131
533#define WM8915_WRITE_SEQUENCER_306 0x3132
534#define WM8915_WRITE_SEQUENCER_307 0x3133
535#define WM8915_WRITE_SEQUENCER_308 0x3134
536#define WM8915_WRITE_SEQUENCER_309 0x3135
537#define WM8915_WRITE_SEQUENCER_310 0x3136
538#define WM8915_WRITE_SEQUENCER_311 0x3137
539#define WM8915_WRITE_SEQUENCER_312 0x3138
540#define WM8915_WRITE_SEQUENCER_313 0x3139
541#define WM8915_WRITE_SEQUENCER_314 0x313A
542#define WM8915_WRITE_SEQUENCER_315 0x313B
543#define WM8915_WRITE_SEQUENCER_316 0x313C
544#define WM8915_WRITE_SEQUENCER_317 0x313D
545#define WM8915_WRITE_SEQUENCER_318 0x313E
546#define WM8915_WRITE_SEQUENCER_319 0x313F
547#define WM8915_WRITE_SEQUENCER_320 0x3140
548#define WM8915_WRITE_SEQUENCER_321 0x3141
549#define WM8915_WRITE_SEQUENCER_322 0x3142
550#define WM8915_WRITE_SEQUENCER_323 0x3143
551#define WM8915_WRITE_SEQUENCER_324 0x3144
552#define WM8915_WRITE_SEQUENCER_325 0x3145
553#define WM8915_WRITE_SEQUENCER_326 0x3146
554#define WM8915_WRITE_SEQUENCER_327 0x3147
555#define WM8915_WRITE_SEQUENCER_328 0x3148
556#define WM8915_WRITE_SEQUENCER_329 0x3149
557#define WM8915_WRITE_SEQUENCER_330 0x314A
558#define WM8915_WRITE_SEQUENCER_331 0x314B
559#define WM8915_WRITE_SEQUENCER_332 0x314C
560#define WM8915_WRITE_SEQUENCER_333 0x314D
561#define WM8915_WRITE_SEQUENCER_334 0x314E
562#define WM8915_WRITE_SEQUENCER_335 0x314F
563#define WM8915_WRITE_SEQUENCER_336 0x3150
564#define WM8915_WRITE_SEQUENCER_337 0x3151
565#define WM8915_WRITE_SEQUENCER_338 0x3152
566#define WM8915_WRITE_SEQUENCER_339 0x3153
567#define WM8915_WRITE_SEQUENCER_340 0x3154
568#define WM8915_WRITE_SEQUENCER_341 0x3155
569#define WM8915_WRITE_SEQUENCER_342 0x3156
570#define WM8915_WRITE_SEQUENCER_343 0x3157
571#define WM8915_WRITE_SEQUENCER_344 0x3158
572#define WM8915_WRITE_SEQUENCER_345 0x3159
573#define WM8915_WRITE_SEQUENCER_346 0x315A
574#define WM8915_WRITE_SEQUENCER_347 0x315B
575#define WM8915_WRITE_SEQUENCER_348 0x315C
576#define WM8915_WRITE_SEQUENCER_349 0x315D
577#define WM8915_WRITE_SEQUENCER_350 0x315E
578#define WM8915_WRITE_SEQUENCER_351 0x315F
579#define WM8915_WRITE_SEQUENCER_352 0x3160
580#define WM8915_WRITE_SEQUENCER_353 0x3161
581#define WM8915_WRITE_SEQUENCER_354 0x3162
582#define WM8915_WRITE_SEQUENCER_355 0x3163
583#define WM8915_WRITE_SEQUENCER_356 0x3164
584#define WM8915_WRITE_SEQUENCER_357 0x3165
585#define WM8915_WRITE_SEQUENCER_358 0x3166
586#define WM8915_WRITE_SEQUENCER_359 0x3167
587#define WM8915_WRITE_SEQUENCER_360 0x3168
588#define WM8915_WRITE_SEQUENCER_361 0x3169
589#define WM8915_WRITE_SEQUENCER_362 0x316A
590#define WM8915_WRITE_SEQUENCER_363 0x316B
591#define WM8915_WRITE_SEQUENCER_364 0x316C
592#define WM8915_WRITE_SEQUENCER_365 0x316D
593#define WM8915_WRITE_SEQUENCER_366 0x316E
594#define WM8915_WRITE_SEQUENCER_367 0x316F
595#define WM8915_WRITE_SEQUENCER_368 0x3170
596#define WM8915_WRITE_SEQUENCER_369 0x3171
597#define WM8915_WRITE_SEQUENCER_370 0x3172
598#define WM8915_WRITE_SEQUENCER_371 0x3173
599#define WM8915_WRITE_SEQUENCER_372 0x3174
600#define WM8915_WRITE_SEQUENCER_373 0x3175
601#define WM8915_WRITE_SEQUENCER_374 0x3176
602#define WM8915_WRITE_SEQUENCER_375 0x3177
603#define WM8915_WRITE_SEQUENCER_376 0x3178
604#define WM8915_WRITE_SEQUENCER_377 0x3179
605#define WM8915_WRITE_SEQUENCER_378 0x317A
606#define WM8915_WRITE_SEQUENCER_379 0x317B
607#define WM8915_WRITE_SEQUENCER_380 0x317C
608#define WM8915_WRITE_SEQUENCER_381 0x317D
609#define WM8915_WRITE_SEQUENCER_382 0x317E
610#define WM8915_WRITE_SEQUENCER_383 0x317F
611#define WM8915_WRITE_SEQUENCER_384 0x3180
612#define WM8915_WRITE_SEQUENCER_385 0x3181
613#define WM8915_WRITE_SEQUENCER_386 0x3182
614#define WM8915_WRITE_SEQUENCER_387 0x3183
615#define WM8915_WRITE_SEQUENCER_388 0x3184
616#define WM8915_WRITE_SEQUENCER_389 0x3185
617#define WM8915_WRITE_SEQUENCER_390 0x3186
618#define WM8915_WRITE_SEQUENCER_391 0x3187
619#define WM8915_WRITE_SEQUENCER_392 0x3188
620#define WM8915_WRITE_SEQUENCER_393 0x3189
621#define WM8915_WRITE_SEQUENCER_394 0x318A
622#define WM8915_WRITE_SEQUENCER_395 0x318B
623#define WM8915_WRITE_SEQUENCER_396 0x318C
624#define WM8915_WRITE_SEQUENCER_397 0x318D
625#define WM8915_WRITE_SEQUENCER_398 0x318E
626#define WM8915_WRITE_SEQUENCER_399 0x318F
627#define WM8915_WRITE_SEQUENCER_400 0x3190
628#define WM8915_WRITE_SEQUENCER_401 0x3191
629#define WM8915_WRITE_SEQUENCER_402 0x3192
630#define WM8915_WRITE_SEQUENCER_403 0x3193
631#define WM8915_WRITE_SEQUENCER_404 0x3194
632#define WM8915_WRITE_SEQUENCER_405 0x3195
633#define WM8915_WRITE_SEQUENCER_406 0x3196
634#define WM8915_WRITE_SEQUENCER_407 0x3197
635#define WM8915_WRITE_SEQUENCER_408 0x3198
636#define WM8915_WRITE_SEQUENCER_409 0x3199
637#define WM8915_WRITE_SEQUENCER_410 0x319A
638#define WM8915_WRITE_SEQUENCER_411 0x319B
639#define WM8915_WRITE_SEQUENCER_412 0x319C
640#define WM8915_WRITE_SEQUENCER_413 0x319D
641#define WM8915_WRITE_SEQUENCER_414 0x319E
642#define WM8915_WRITE_SEQUENCER_415 0x319F
643#define WM8915_WRITE_SEQUENCER_416 0x31A0
644#define WM8915_WRITE_SEQUENCER_417 0x31A1
645#define WM8915_WRITE_SEQUENCER_418 0x31A2
646#define WM8915_WRITE_SEQUENCER_419 0x31A3
647#define WM8915_WRITE_SEQUENCER_420 0x31A4
648#define WM8915_WRITE_SEQUENCER_421 0x31A5
649#define WM8915_WRITE_SEQUENCER_422 0x31A6
650#define WM8915_WRITE_SEQUENCER_423 0x31A7
651#define WM8915_WRITE_SEQUENCER_424 0x31A8
652#define WM8915_WRITE_SEQUENCER_425 0x31A9
653#define WM8915_WRITE_SEQUENCER_426 0x31AA
654#define WM8915_WRITE_SEQUENCER_427 0x31AB
655#define WM8915_WRITE_SEQUENCER_428 0x31AC
656#define WM8915_WRITE_SEQUENCER_429 0x31AD
657#define WM8915_WRITE_SEQUENCER_430 0x31AE
658#define WM8915_WRITE_SEQUENCER_431 0x31AF
659#define WM8915_WRITE_SEQUENCER_432 0x31B0
660#define WM8915_WRITE_SEQUENCER_433 0x31B1
661#define WM8915_WRITE_SEQUENCER_434 0x31B2
662#define WM8915_WRITE_SEQUENCER_435 0x31B3
663#define WM8915_WRITE_SEQUENCER_436 0x31B4
664#define WM8915_WRITE_SEQUENCER_437 0x31B5
665#define WM8915_WRITE_SEQUENCER_438 0x31B6
666#define WM8915_WRITE_SEQUENCER_439 0x31B7
667#define WM8915_WRITE_SEQUENCER_440 0x31B8
668#define WM8915_WRITE_SEQUENCER_441 0x31B9
669#define WM8915_WRITE_SEQUENCER_442 0x31BA
670#define WM8915_WRITE_SEQUENCER_443 0x31BB
671#define WM8915_WRITE_SEQUENCER_444 0x31BC
672#define WM8915_WRITE_SEQUENCER_445 0x31BD
673#define WM8915_WRITE_SEQUENCER_446 0x31BE
674#define WM8915_WRITE_SEQUENCER_447 0x31BF
675#define WM8915_WRITE_SEQUENCER_448 0x31C0
676#define WM8915_WRITE_SEQUENCER_449 0x31C1
677#define WM8915_WRITE_SEQUENCER_450 0x31C2
678#define WM8915_WRITE_SEQUENCER_451 0x31C3
679#define WM8915_WRITE_SEQUENCER_452 0x31C4
680#define WM8915_WRITE_SEQUENCER_453 0x31C5
681#define WM8915_WRITE_SEQUENCER_454 0x31C6
682#define WM8915_WRITE_SEQUENCER_455 0x31C7
683#define WM8915_WRITE_SEQUENCER_456 0x31C8
684#define WM8915_WRITE_SEQUENCER_457 0x31C9
685#define WM8915_WRITE_SEQUENCER_458 0x31CA
686#define WM8915_WRITE_SEQUENCER_459 0x31CB
687#define WM8915_WRITE_SEQUENCER_460 0x31CC
688#define WM8915_WRITE_SEQUENCER_461 0x31CD
689#define WM8915_WRITE_SEQUENCER_462 0x31CE
690#define WM8915_WRITE_SEQUENCER_463 0x31CF
691#define WM8915_WRITE_SEQUENCER_464 0x31D0
692#define WM8915_WRITE_SEQUENCER_465 0x31D1
693#define WM8915_WRITE_SEQUENCER_466 0x31D2
694#define WM8915_WRITE_SEQUENCER_467 0x31D3
695#define WM8915_WRITE_SEQUENCER_468 0x31D4
696#define WM8915_WRITE_SEQUENCER_469 0x31D5
697#define WM8915_WRITE_SEQUENCER_470 0x31D6
698#define WM8915_WRITE_SEQUENCER_471 0x31D7
699#define WM8915_WRITE_SEQUENCER_472 0x31D8
700#define WM8915_WRITE_SEQUENCER_473 0x31D9
701#define WM8915_WRITE_SEQUENCER_474 0x31DA
702#define WM8915_WRITE_SEQUENCER_475 0x31DB
703#define WM8915_WRITE_SEQUENCER_476 0x31DC
704#define WM8915_WRITE_SEQUENCER_477 0x31DD
705#define WM8915_WRITE_SEQUENCER_478 0x31DE
706#define WM8915_WRITE_SEQUENCER_479 0x31DF
707#define WM8915_WRITE_SEQUENCER_480 0x31E0
708#define WM8915_WRITE_SEQUENCER_481 0x31E1
709#define WM8915_WRITE_SEQUENCER_482 0x31E2
710#define WM8915_WRITE_SEQUENCER_483 0x31E3
711#define WM8915_WRITE_SEQUENCER_484 0x31E4
712#define WM8915_WRITE_SEQUENCER_485 0x31E5
713#define WM8915_WRITE_SEQUENCER_486 0x31E6
714#define WM8915_WRITE_SEQUENCER_487 0x31E7
715#define WM8915_WRITE_SEQUENCER_488 0x31E8
716#define WM8915_WRITE_SEQUENCER_489 0x31E9
717#define WM8915_WRITE_SEQUENCER_490 0x31EA
718#define WM8915_WRITE_SEQUENCER_491 0x31EB
719#define WM8915_WRITE_SEQUENCER_492 0x31EC
720#define WM8915_WRITE_SEQUENCER_493 0x31ED
721#define WM8915_WRITE_SEQUENCER_494 0x31EE
722#define WM8915_WRITE_SEQUENCER_495 0x31EF
723#define WM8915_WRITE_SEQUENCER_496 0x31F0
724#define WM8915_WRITE_SEQUENCER_497 0x31F1
725#define WM8915_WRITE_SEQUENCER_498 0x31F2
726#define WM8915_WRITE_SEQUENCER_499 0x31F3
727#define WM8915_WRITE_SEQUENCER_500 0x31F4
728#define WM8915_WRITE_SEQUENCER_501 0x31F5
729#define WM8915_WRITE_SEQUENCER_502 0x31F6
730#define WM8915_WRITE_SEQUENCER_503 0x31F7
731#define WM8915_WRITE_SEQUENCER_504 0x31F8
732#define WM8915_WRITE_SEQUENCER_505 0x31F9
733#define WM8915_WRITE_SEQUENCER_506 0x31FA
734#define WM8915_WRITE_SEQUENCER_507 0x31FB
735#define WM8915_WRITE_SEQUENCER_508 0x31FC
736#define WM8915_WRITE_SEQUENCER_509 0x31FD
737#define WM8915_WRITE_SEQUENCER_510 0x31FE
738#define WM8915_WRITE_SEQUENCER_511 0x31FF
739
740#define WM8915_REGISTER_COUNT 706
741#define WM8915_MAX_REGISTER 0x31FF
742
743/*
744 * Field Definitions.
745 */
746
747/*
748 * R0 (0x00) - Software Reset
749 */
750#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
751#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
752#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
753
754/*
755 * R1 (0x01) - Power Management (1)
756 */
757#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */
758#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
759#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
760#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
761#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */
762#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
763#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
764#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
765#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
766#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
767#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
768#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
769#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
770#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
771#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
772#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
773#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
774#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
775#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
776#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
777#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
778#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
779#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
780#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
781#define WM8915_BG_ENA 0x0001 /* BG_ENA */
782#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */
783#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */
784#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */
785
786/*
787 * R2 (0x02) - Power Management (2)
788 */
789#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */
790#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
791#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
792#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
793#define WM8915_INL_ENA 0x0020 /* INL_ENA */
794#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */
795#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */
796#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */
797#define WM8915_INR_ENA 0x0010 /* INR_ENA */
798#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */
799#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */
800#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */
801#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */
802#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
803#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
804#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
805
806/*
807 * R3 (0x03) - Power Management (3)
808 */
809#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */
810#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */
811#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */
812#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */
813#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */
814#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */
815#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */
816#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */
817#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */
818#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */
819#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */
820#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */
821#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */
822#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */
823#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */
824#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */
825#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
826#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
827#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
828#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
829#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
830#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
831#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
832#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
833#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
834#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
835#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
836#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
837#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
838#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
839#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
840#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
841#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */
842#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
843#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
844#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
845#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */
846#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
847#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
848#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
849
850/*
851 * R4 (0x04) - Power Management (4)
852 */
853#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */
854#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */
855#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */
856#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */
857#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */
858#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */
859#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */
860#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */
861#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */
862#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */
863#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */
864#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */
865#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */
866#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */
867#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */
868#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */
869#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */
870#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */
871#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */
872#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */
873#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */
874#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */
875#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */
876#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */
877#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */
878#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */
879#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */
880#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */
881#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */
882#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */
883#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */
884#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */
885
886/*
887 * R5 (0x05) - Power Management (5)
888 */
889#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */
890#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */
891#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */
892#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */
893#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */
894#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */
895#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */
896#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */
897#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */
898#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */
899#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */
900#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */
901#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */
902#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */
903#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */
904#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */
905#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */
906#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
907#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
908#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
909#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */
910#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
911#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
912#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
913#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */
914#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
915#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
916#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
917#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */
918#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
919#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
920#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
921
922/*
923 * R6 (0x06) - Power Management (6)
924 */
925#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */
926#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */
927#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */
928#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */
929#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */
930#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */
931#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */
932#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */
933#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */
934#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */
935#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */
936#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */
937#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */
938#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */
939#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */
940#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */
941#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */
942#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */
943#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */
944#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */
945#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */
946#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */
947#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */
948#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */
949#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */
950#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */
951#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */
952#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */
953#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */
954#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */
955#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */
956#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */
957
958/*
959 * R7 (0x07) - Power Management (7)
960 */
961#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */
962#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */
963#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */
964#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */
965#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */
966#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */
967#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */
968#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */
969#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */
970#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */
971#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */
972#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */
973#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */
974#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */
975#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */
976#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */
977#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */
978#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */
979#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */
980#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */
981#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */
982#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */
983#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */
984#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */
985#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */
986#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */
987#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */
988#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */
989#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */
990#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */
991
992/*
993 * R8 (0x08) - Power Management (8)
994 */
995#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */
996#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */
997#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */
998#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */
999#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */
1000#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */
1001#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */
1002#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */
1003#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */
1004#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */
1005#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */
1006
1007/*
1008 * R16 (0x10) - Left Line Input Volume
1009 */
1010#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1011#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1012#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1013#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1014#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */
1015#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
1016#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
1017#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
1018#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
1019#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
1020#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
1021
1022/*
1023 * R17 (0x11) - Right Line Input Volume
1024 */
1025#define WM8915_IN1_VU 0x0080 /* IN1_VU */
1026#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */
1027#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */
1028#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */
1029#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */
1030#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
1031#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
1032#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
1033#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
1034#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
1035#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
1036
1037/*
1038 * R18 (0x12) - Line Input Control
1039 */
1040#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */
1041#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */
1042#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */
1043#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */
1044#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */
1045#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */
1046
1047/*
1048 * R21 (0x15) - DAC1 HPOUT1 Volume
1049 */
1050#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */
1051#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1052#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */
1053#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */
1054#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */
1055#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */
1056
1057/*
1058 * R22 (0x16) - DAC2 HPOUT2 Volume
1059 */
1060#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */
1061#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1062#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */
1063#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */
1064#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */
1065#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */
1066
1067/*
1068 * R24 (0x18) - DAC1 Left Volume
1069 */
1070#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
1071#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
1072#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
1073#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
1074#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1075#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1076#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1077#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1078#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
1079#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
1080#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
1081
1082/*
1083 * R25 (0x19) - DAC1 Right Volume
1084 */
1085#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
1086#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
1087#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
1088#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
1089#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1090#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1091#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1092#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1093#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
1094#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
1095#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
1096
1097/*
1098 * R26 (0x1A) - DAC2 Left Volume
1099 */
1100#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
1101#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
1102#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
1103#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
1104#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1105#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1106#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1107#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1108#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
1109#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
1110#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
1111
1112/*
1113 * R27 (0x1B) - DAC2 Right Volume
1114 */
1115#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
1116#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
1117#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
1118#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
1119#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1120#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1121#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1122#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1123#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
1124#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
1125#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
1126
1127/*
1128 * R28 (0x1C) - Output1 Left Volume
1129 */
1130#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1131#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1132#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1133#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1134#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
1135#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
1136#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
1137#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1138#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */
1139#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */
1140#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */
1141
1142/*
1143 * R29 (0x1D) - Output1 Right Volume
1144 */
1145#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */
1146#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1147#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */
1148#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */
1149#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
1150#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
1151#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
1152#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1153#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */
1154#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */
1155#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */
1156
1157/*
1158 * R30 (0x1E) - Output2 Left Volume
1159 */
1160#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1161#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1162#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1163#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1164#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */
1165#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */
1166#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */
1167#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
1168#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */
1169#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */
1170#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */
1171
1172/*
1173 * R31 (0x1F) - Output2 Right Volume
1174 */
1175#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */
1176#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1177#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */
1178#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */
1179#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */
1180#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */
1181#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */
1182#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
1183#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */
1184#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */
1185#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */
1186
1187/*
1188 * R32 (0x20) - MICBIAS (1)
1189 */
1190#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */
1191#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
1192#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
1193#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
1194#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */
1195#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
1196#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
1197#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1198#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
1199#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
1200#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
1201#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1202#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1203#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1204#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1205
1206/*
1207 * R33 (0x21) - MICBIAS (2)
1208 */
1209#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */
1210#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
1211#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
1212#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
1213#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */
1214#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
1215#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
1216#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1217#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
1218#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
1219#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
1220#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1221#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1222#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1223#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1224
1225/*
1226 * R40 (0x28) - LDO 1
1227 */
1228#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */
1229#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
1230#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
1231#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
1232#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
1233#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
1234#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
1235#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1236#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1237#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1238#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1239
1240/*
1241 * R41 (0x29) - LDO 2
1242 */
1243#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */
1244#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
1245#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
1246#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
1247#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
1248#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
1249#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
1250#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1251#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1252#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1253#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1254
1255/*
1256 * R48 (0x30) - Accessory Detect Mode 1
1257 */
1258#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
1259#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
1260#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
1261
1262/*
1263 * R49 (0x31) - Accessory Detect Mode 2
1264 */
1265#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */
1266#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */
1267#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */
1268#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */
1269#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */
1270#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */
1271#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */
1272#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */
1273#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */
1274#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */
1275#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */
1276#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */
1277
1278/*
1279 * R52 (0x34) - Headphone Detect 1
1280 */
1281#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */
1282#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */
1283#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */
1284#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */
1285#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */
1286#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */
1287#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */
1288#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */
1289#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */
1290#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */
1291#define WM8915_HP_POLL 0x0001 /* HP_POLL */
1292#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */
1293#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */
1294#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */
1295
1296/*
1297 * R53 (0x35) - Headphone Detect 2
1298 */
1299#define WM8915_HP_DONE 0x0080 /* HP_DONE */
1300#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */
1301#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */
1302#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */
1303#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1304#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1305#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1306
1307/*
1308 * R56 (0x38) - Mic Detect 1
1309 */
1310#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */
1311#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */
1312#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */
1313#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */
1314#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */
1315#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */
1316#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */
1317#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
1318#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
1319#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
1320#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */
1321#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */
1322#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */
1323#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */
1324
1325/*
1326 * R57 (0x39) - Mic Detect 2
1327 */
1328#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */
1329#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */
1330#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */
1331
1332/*
1333 * R58 (0x3A) - Mic Detect 3
1334 */
1335#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */
1336#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */
1337#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */
1338#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */
1339#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */
1340#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */
1341#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */
1342#define WM8915_MICD_STS 0x0001 /* MICD_STS */
1343#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */
1344#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */
1345#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */
1346
1347/*
1348 * R64 (0x40) - Charge Pump (1)
1349 */
1350#define WM8915_CP_ENA 0x8000 /* CP_ENA */
1351#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */
1352#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */
1353#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */
1354
1355/*
1356 * R65 (0x41) - Charge Pump (2)
1357 */
1358#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */
1359#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */
1360#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */
1361#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */
1362
1363/*
1364 * R80 (0x50) - DC Servo (1)
1365 */
1366#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
1367#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
1368#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
1369#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
1370#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
1371#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
1372#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
1373#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
1374#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1375#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1376#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1377#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1378#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1379#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1380#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1381#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1382
1383/*
1384 * R81 (0x51) - DC Servo (2)
1385 */
1386#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
1387#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
1388#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
1389#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
1390#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
1391#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
1392#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
1393#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
1394#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1395#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1396#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1397#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1398#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1399#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1400#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1401#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1402#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
1403#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
1404#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
1405#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
1406#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
1407#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
1408#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
1409#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
1410#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1411#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1412#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1413#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1414#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1415#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1416#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1417#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1418#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
1419#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
1420#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
1421#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
1422#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
1423#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
1424#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
1425#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
1426#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1427#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1428#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1429#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1430#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1431#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1432#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1433#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1434#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
1435#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
1436#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
1437#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
1438#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
1439#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
1440#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
1441#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
1442#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
1443#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
1444#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
1445#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1446#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
1447#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
1448#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
1449#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1450
1451/*
1452 * R82 (0x52) - DC Servo (3)
1453 */
1454#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
1455#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
1456#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
1457#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1458#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1459#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1460
1461/*
1462 * R84 (0x54) - DC Servo (5)
1463 */
1464#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
1465#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
1466#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
1467#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
1468#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
1469#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
1470
1471/*
1472 * R85 (0x55) - DC Servo (6)
1473 */
1474#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
1475#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1476#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1477#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
1478#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
1479#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
1480
1481/*
1482 * R86 (0x56) - DC Servo (7)
1483 */
1484#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1485#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1486#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1487#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1488#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1489#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1490
1491/*
1492 * R87 (0x57) - DC Servo Readback 0
1493 */
1494#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
1495#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
1496#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
1497#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
1498#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1499#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1500#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
1501#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
1502#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
1503
1504/*
1505 * R96 (0x60) - Analogue HP (1)
1506 */
1507#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1508#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1509#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1510#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1511#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1512#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1513#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1514#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1515#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1516#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1517#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1518#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1519#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1520#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1521#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1522#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1523#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1524#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1525#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1526#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1527#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1528#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1529#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1530#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1531
1532/*
1533 * R97 (0x61) - Analogue HP (2)
1534 */
1535#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
1536#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
1537#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
1538#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
1539#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
1540#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
1541#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
1542#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
1543#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
1544#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
1545#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
1546#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
1547#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
1548#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
1549#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
1550#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
1551#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
1552#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
1553#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
1554#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
1555#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
1556#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
1557#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
1558#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
1559
1560/*
1561 * R256 (0x100) - Chip Revision
1562 */
1563#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1564#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1565#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1566
1567/*
1568 * R257 (0x101) - Control Interface (1)
1569 */
1570#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */
1571#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1572#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */
1573#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */
1574
1575/*
1576 * R272 (0x110) - Write Sequencer Ctrl (1)
1577 */
1578#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1579#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1580#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1581#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1582#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1583#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1584#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1585#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1586#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */
1587#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1588#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */
1589#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */
1590#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1591#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1592#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1593
1594/*
1595 * R273 (0x111) - Write Sequencer Ctrl (2)
1596 */
1597#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
1598#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
1599#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
1600#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1601#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
1602#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
1603#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
1604
1605/*
1606 * R512 (0x200) - AIF Clocking (1)
1607 */
1608#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */
1609#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */
1610#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */
1611#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */
1612#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */
1613#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */
1614#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */
1615#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */
1616#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */
1617#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */
1618#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */
1619#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */
1620#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */
1621#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */
1622#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
1623
1624/*
1625 * R513 (0x201) - AIF Clocking (2)
1626 */
1627#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */
1628#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */
1629#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */
1630#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */
1631#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */
1632#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */
1633
1634/*
1635 * R520 (0x208) - Clocking (1)
1636 */
1637#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */
1638#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
1639#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
1640#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
1641#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */
1642#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
1643#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
1644#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1645#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */
1646#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */
1647#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */
1648#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */
1649#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
1650#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
1651#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
1652#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
1653
1654/*
1655 * R521 (0x209) - Clocking (2)
1656 */
1657#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
1658#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
1659#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
1660#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
1661#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
1662#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
1663#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
1664#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
1665#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
1666
1667/*
1668 * R528 (0x210) - AIF Rate
1669 */
1670#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */
1671#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */
1672#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */
1673#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */
1674
1675/*
1676 * R544 (0x220) - FLL Control (1)
1677 */
1678#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1679#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1680#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1681#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1682#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */
1683#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1684#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */
1685#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */
1686
1687/*
1688 * R545 (0x221) - FLL Control (2)
1689 */
1690#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1691#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1692#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1693#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1694#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1695#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1696
1697/*
1698 * R546 (0x222) - FLL Control (3)
1699 */
1700#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
1701#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
1702#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
1703
1704/*
1705 * R547 (0x223) - FLL Control (4)
1706 */
1707#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1708#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1709#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1710#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */
1711#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */
1712#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */
1713
1714/*
1715 * R548 (0x224) - FLL Control (5)
1716 */
1717#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
1718#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
1719#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
1720#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
1721#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
1722#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
1723#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1724#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */
1725#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */
1726#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */
1727#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */
1728#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */
1729#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */
1730#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */
1731#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */
1732#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */
1733#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */
1734
1735/*
1736 * R549 (0x225) - FLL Control (6)
1737 */
1738#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */
1739#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1740#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */
1741#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */
1742#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */
1743#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */
1744#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */
1745
1746/*
1747 * R550 (0x226) - FLL EFS 1
1748 */
1749#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
1750#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
1751#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
1752
1753/*
1754 * R551 (0x227) - FLL EFS 2
1755 */
1756#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */
1757#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */
1758#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */
1759#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */
1760#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */
1761#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */
1762#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */
1763
1764/*
1765 * R768 (0x300) - AIF1 Control
1766 */
1767#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */
1768#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */
1769#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */
1770#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1771#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */
1772#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */
1773#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */
1774
1775/*
1776 * R769 (0x301) - AIF1 BCLK
1777 */
1778#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */
1779#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */
1780#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */
1781#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1782#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */
1783#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */
1784#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */
1785#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */
1786#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */
1787#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */
1788#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */
1789#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */
1790#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */
1791#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */
1792#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */
1793
1794/*
1795 * R770 (0x302) - AIF1 TX LRCLK(1)
1796 */
1797#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */
1798#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */
1799#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */
1800
1801/*
1802 * R771 (0x303) - AIF1 TX LRCLK(2)
1803 */
1804#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */
1805#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */
1806#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */
1807#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */
1808#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */
1809#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */
1810#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */
1811#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */
1812#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */
1813#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */
1814#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */
1815#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */
1816#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */
1817#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */
1818#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */
1819#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */
1820
1821/*
1822 * R772 (0x304) - AIF1 RX LRCLK(1)
1823 */
1824#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */
1825#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */
1826#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */
1827
1828/*
1829 * R773 (0x305) - AIF1 RX LRCLK(2)
1830 */
1831#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */
1832#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */
1833#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */
1834#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */
1835#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */
1836#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */
1837#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */
1838#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */
1839#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */
1840#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */
1841#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */
1842#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */
1843
1844/*
1845 * R774 (0x306) - AIF1TX Data Configuration (1)
1846 */
1847#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */
1848#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */
1849#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */
1850#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */
1851#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */
1852#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */
1853
1854/*
1855 * R775 (0x307) - AIF1TX Data Configuration (2)
1856 */
1857#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */
1858#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */
1859#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */
1860#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */
1861
1862/*
1863 * R776 (0x308) - AIF1RX Data Configuration
1864 */
1865#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */
1866#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */
1867#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */
1868#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */
1869#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */
1870#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */
1871
1872/*
1873 * R777 (0x309) - AIF1TX Channel 0 Configuration
1874 */
1875#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1876#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */
1877#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */
1878#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */
1879#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */
1880#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */
1881#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */
1882#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1883#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1884#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */
1885#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1886#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1887#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */
1888
1889/*
1890 * R778 (0x30A) - AIF1TX Channel 1 Configuration
1891 */
1892#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1893#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */
1894#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */
1895#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */
1896#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */
1897#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */
1898#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */
1899#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1900#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1901#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */
1902#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1903#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1904#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */
1905
1906/*
1907 * R779 (0x30B) - AIF1TX Channel 2 Configuration
1908 */
1909#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1910#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */
1911#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */
1912#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */
1913#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */
1914#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */
1915#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */
1916#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1917#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1918#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */
1919#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1920#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1921#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */
1922
1923/*
1924 * R780 (0x30C) - AIF1TX Channel 3 Configuration
1925 */
1926#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1927#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */
1928#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */
1929#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */
1930#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */
1931#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */
1932#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */
1933#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1934#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1935#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */
1936#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1937#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1938#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */
1939
1940/*
1941 * R781 (0x30D) - AIF1TX Channel 4 Configuration
1942 */
1943#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1944#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */
1945#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */
1946#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */
1947#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */
1948#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */
1949#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */
1950#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1951#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1952#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */
1953#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1954#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1955#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */
1956
1957/*
1958 * R782 (0x30E) - AIF1TX Channel 5 Configuration
1959 */
1960#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1961#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */
1962#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */
1963#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */
1964#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */
1965#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */
1966#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */
1967#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1968#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1969#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */
1970#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1971#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1972#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */
1973
1974/*
1975 * R783 (0x30F) - AIF1RX Channel 0 Configuration
1976 */
1977#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1978#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */
1979#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */
1980#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */
1981#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */
1982#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */
1983#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */
1984#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1985#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1986#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */
1987#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1988#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1989#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */
1990
1991/*
1992 * R784 (0x310) - AIF1RX Channel 1 Configuration
1993 */
1994#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1995#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */
1996#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */
1997#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */
1998#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */
1999#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */
2000#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */
2001#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2002#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2003#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */
2004#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2005#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2006#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */
2007
2008/*
2009 * R785 (0x311) - AIF1RX Channel 2 Configuration
2010 */
2011#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2012#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */
2013#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */
2014#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */
2015#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */
2016#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */
2017#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */
2018#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2019#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2020#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */
2021#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2022#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2023#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */
2024
2025/*
2026 * R786 (0x312) - AIF1RX Channel 3 Configuration
2027 */
2028#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2029#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */
2030#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */
2031#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */
2032#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */
2033#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */
2034#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */
2035#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2036#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2037#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */
2038#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2039#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2040#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */
2041
2042/*
2043 * R787 (0x313) - AIF1RX Channel 4 Configuration
2044 */
2045#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2046#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */
2047#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */
2048#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */
2049#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */
2050#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */
2051#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */
2052#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2053#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2054#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */
2055#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2056#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2057#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */
2058
2059/*
2060 * R788 (0x314) - AIF1RX Channel 5 Configuration
2061 */
2062#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2063#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */
2064#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */
2065#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */
2066#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */
2067#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */
2068#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */
2069#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2070#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2071#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */
2072#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2073#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2074#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */
2075
2076/*
2077 * R789 (0x315) - AIF1RX Mono Configuration
2078 */
2079#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2080#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */
2081#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */
2082#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */
2083#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2084#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */
2085#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */
2086#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */
2087#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2088#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */
2089#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */
2090#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */
2091
2092/*
2093 * R794 (0x31A) - AIF1TX Test
2094 */
2095#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */
2096#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */
2097#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */
2098#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */
2099#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */
2100#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */
2101#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */
2102#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */
2103#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */
2104#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */
2105#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */
2106#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */
2107
2108/*
2109 * R800 (0x320) - AIF2 Control
2110 */
2111#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */
2112#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */
2113#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */
2114#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2115#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */
2116#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */
2117#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */
2118
2119/*
2120 * R801 (0x321) - AIF2 BCLK
2121 */
2122#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */
2123#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */
2124#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */
2125#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2126#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */
2127#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */
2128#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */
2129#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */
2130#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */
2131#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */
2132#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */
2133#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */
2134#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */
2135#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */
2136#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */
2137
2138/*
2139 * R802 (0x322) - AIF2 TX LRCLK(1)
2140 */
2141#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */
2142#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */
2143#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */
2144
2145/*
2146 * R803 (0x323) - AIF2 TX LRCLK(2)
2147 */
2148#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */
2149#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */
2150#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */
2151#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */
2152#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */
2153#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */
2154#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */
2155#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */
2156#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */
2157#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */
2158#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */
2159#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */
2160#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */
2161#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */
2162#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */
2163#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */
2164
2165/*
2166 * R804 (0x324) - AIF2 RX LRCLK(1)
2167 */
2168#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */
2169#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */
2170#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */
2171
2172/*
2173 * R805 (0x325) - AIF2 RX LRCLK(2)
2174 */
2175#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */
2176#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */
2177#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */
2178#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */
2179#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */
2180#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */
2181#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */
2182#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */
2183#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */
2184#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */
2185#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */
2186#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */
2187
2188/*
2189 * R806 (0x326) - AIF2TX Data Configuration (1)
2190 */
2191#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */
2192#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */
2193#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */
2194#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */
2195#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */
2196#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */
2197
2198/*
2199 * R807 (0x327) - AIF2TX Data Configuration (2)
2200 */
2201#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */
2202#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */
2203#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */
2204#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */
2205
2206/*
2207 * R808 (0x328) - AIF2RX Data Configuration
2208 */
2209#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */
2210#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */
2211#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */
2212#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */
2213#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */
2214#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */
2215
2216/*
2217 * R809 (0x329) - AIF2TX Channel 0 Configuration
2218 */
2219#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2220#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */
2221#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */
2222#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */
2223#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */
2224#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */
2225#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */
2226#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2227#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2228#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */
2229#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2230#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2231#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */
2232
2233/*
2234 * R810 (0x32A) - AIF2TX Channel 1 Configuration
2235 */
2236#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2237#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */
2238#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */
2239#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */
2240#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */
2241#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */
2242#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */
2243#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2244#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2245#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */
2246#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2247#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2248#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */
2249
2250/*
2251 * R811 (0x32B) - AIF2RX Channel 0 Configuration
2252 */
2253#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2254#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */
2255#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */
2256#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */
2257#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */
2258#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */
2259#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */
2260#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2261#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2262#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */
2263#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2264#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2265#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */
2266
2267/*
2268 * R812 (0x32C) - AIF2RX Channel 1 Configuration
2269 */
2270#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2271#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */
2272#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */
2273#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */
2274#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */
2275#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */
2276#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */
2277#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2278#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2279#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */
2280#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2281#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2282#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */
2283
2284/*
2285 * R813 (0x32D) - AIF2RX Mono Configuration
2286 */
2287#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2288#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */
2289#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */
2290#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */
2291
2292/*
2293 * R815 (0x32F) - AIF2TX Test
2294 */
2295#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */
2296#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */
2297#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */
2298#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */
2299
2300/*
2301 * R1024 (0x400) - DSP1 TX Left Volume
2302 */
2303#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2304#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2305#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2306#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2307#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */
2308#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */
2309#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */
2310
2311/*
2312 * R1025 (0x401) - DSP1 TX Right Volume
2313 */
2314#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */
2315#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */
2316#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */
2317#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */
2318#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */
2319#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */
2320#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */
2321
2322/*
2323 * R1026 (0x402) - DSP1 RX Left Volume
2324 */
2325#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2326#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2327#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2328#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2329#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */
2330#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */
2331#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */
2332
2333/*
2334 * R1027 (0x403) - DSP1 RX Right Volume
2335 */
2336#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */
2337#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */
2338#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */
2339#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */
2340#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */
2341#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */
2342#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */
2343
2344/*
2345 * R1040 (0x410) - DSP1 TX Filters
2346 */
2347#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */
2348#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */
2349#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */
2350#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */
2351#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */
2352#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */
2353#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */
2354#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */
2355#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */
2356#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */
2357#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */
2358#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */
2359#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */
2360#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */
2361#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */
2362#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */
2363#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */
2364#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */
2365
2366/*
2367 * R1056 (0x420) - DSP1 RX Filters (1)
2368 */
2369#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */
2370#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */
2371#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */
2372#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */
2373#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */
2374#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */
2375#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */
2376#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */
2377#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */
2378#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */
2379#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */
2380#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */
2381#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */
2382#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */
2383#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */
2384#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */
2385
2386/*
2387 * R1057 (0x421) - DSP1 RX Filters (2)
2388 */
2389#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */
2390#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */
2391#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */
2392#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */
2393#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */
2394#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */
2395#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */
2396
2397/*
2398 * R1088 (0x440) - DSP1 DRC (1)
2399 */
2400#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2401#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2402#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */
2403#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */
2404#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */
2405#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */
2406#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */
2407#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */
2408#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */
2409#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */
2410#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */
2411#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */
2412#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */
2413#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */
2414#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */
2415#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */
2416#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */
2417#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */
2418#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2419#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */
2420#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */
2421#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */
2422#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */
2423#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */
2424#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */
2425#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */
2426#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */
2427#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */
2428#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */
2429#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */
2430#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */
2431#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */
2432#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */
2433#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */
2434#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */
2435#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */
2436#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */
2437#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */
2438#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */
2439#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */
2440#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */
2441#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */
2442
2443/*
2444 * R1089 (0x441) - DSP1 DRC (2)
2445 */
2446#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */
2447#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */
2448#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */
2449#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */
2450#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */
2451#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */
2452#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */
2453#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */
2454#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */
2455#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */
2456#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */
2457#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */
2458
2459/*
2460 * R1090 (0x442) - DSP1 DRC (3)
2461 */
2462#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */
2463#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */
2464#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */
2465#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */
2466#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */
2467#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */
2468#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */
2469#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */
2470#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */
2471#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */
2472#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */
2473#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */
2474#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */
2475#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */
2476#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */
2477#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */
2478#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */
2479#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */
2480
2481/*
2482 * R1091 (0x443) - DSP1 DRC (4)
2483 */
2484#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */
2485#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */
2486#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */
2487#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */
2488#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */
2489#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */
2490
2491/*
2492 * R1092 (0x444) - DSP1 DRC (5)
2493 */
2494#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */
2495#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2496#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */
2497#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */
2498#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */
2499#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */
2500
2501/*
2502 * R1152 (0x480) - DSP1 RX EQ Gains (1)
2503 */
2504#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2505#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2506#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */
2507#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2508#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2509#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */
2510#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */
2511#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2512#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */
2513#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */
2514#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */
2515#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */
2516#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */
2517
2518/*
2519 * R1153 (0x481) - DSP1 RX EQ Gains (2)
2520 */
2521#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2522#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2523#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */
2524#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2525#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2526#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */
2527
2528/*
2529 * R1154 (0x482) - DSP1 RX EQ Band 1 A
2530 */
2531#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */
2532#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */
2533#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */
2534
2535/*
2536 * R1155 (0x483) - DSP1 RX EQ Band 1 B
2537 */
2538#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */
2539#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */
2540#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */
2541
2542/*
2543 * R1156 (0x484) - DSP1 RX EQ Band 1 PG
2544 */
2545#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */
2546#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */
2547#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */
2548
2549/*
2550 * R1157 (0x485) - DSP1 RX EQ Band 2 A
2551 */
2552#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */
2553#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */
2554#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */
2555
2556/*
2557 * R1158 (0x486) - DSP1 RX EQ Band 2 B
2558 */
2559#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */
2560#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */
2561#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */
2562
2563/*
2564 * R1159 (0x487) - DSP1 RX EQ Band 2 C
2565 */
2566#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */
2567#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */
2568#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */
2569
2570/*
2571 * R1160 (0x488) - DSP1 RX EQ Band 2 PG
2572 */
2573#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */
2574#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */
2575#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */
2576
2577/*
2578 * R1161 (0x489) - DSP1 RX EQ Band 3 A
2579 */
2580#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */
2581#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */
2582#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */
2583
2584/*
2585 * R1162 (0x48A) - DSP1 RX EQ Band 3 B
2586 */
2587#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */
2588#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */
2589#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */
2590
2591/*
2592 * R1163 (0x48B) - DSP1 RX EQ Band 3 C
2593 */
2594#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */
2595#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */
2596#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */
2597
2598/*
2599 * R1164 (0x48C) - DSP1 RX EQ Band 3 PG
2600 */
2601#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */
2602#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */
2603#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */
2604
2605/*
2606 * R1165 (0x48D) - DSP1 RX EQ Band 4 A
2607 */
2608#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */
2609#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */
2610#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */
2611
2612/*
2613 * R1166 (0x48E) - DSP1 RX EQ Band 4 B
2614 */
2615#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */
2616#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */
2617#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */
2618
2619/*
2620 * R1167 (0x48F) - DSP1 RX EQ Band 4 C
2621 */
2622#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */
2623#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */
2624#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */
2625
2626/*
2627 * R1168 (0x490) - DSP1 RX EQ Band 4 PG
2628 */
2629#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */
2630#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */
2631#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */
2632
2633/*
2634 * R1169 (0x491) - DSP1 RX EQ Band 5 A
2635 */
2636#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */
2637#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */
2638#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */
2639
2640/*
2641 * R1170 (0x492) - DSP1 RX EQ Band 5 B
2642 */
2643#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */
2644#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */
2645#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */
2646
2647/*
2648 * R1171 (0x493) - DSP1 RX EQ Band 5 PG
2649 */
2650#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */
2651#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */
2652#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */
2653
2654/*
2655 * R1280 (0x500) - DSP2 TX Left Volume
2656 */
2657#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2658#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2659#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2660#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2661#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */
2662#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */
2663#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */
2664
2665/*
2666 * R1281 (0x501) - DSP2 TX Right Volume
2667 */
2668#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */
2669#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */
2670#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */
2671#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */
2672#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */
2673#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */
2674#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */
2675
2676/*
2677 * R1282 (0x502) - DSP2 RX Left Volume
2678 */
2679#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2680#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2681#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2682#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2683#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */
2684#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */
2685#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */
2686
2687/*
2688 * R1283 (0x503) - DSP2 RX Right Volume
2689 */
2690#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */
2691#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */
2692#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */
2693#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */
2694#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */
2695#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */
2696#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */
2697
2698/*
2699 * R1296 (0x510) - DSP2 TX Filters
2700 */
2701#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */
2702#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */
2703#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */
2704#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */
2705#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */
2706#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */
2707#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */
2708#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */
2709#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */
2710#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */
2711#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */
2712#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */
2713#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */
2714#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */
2715#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */
2716#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */
2717#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */
2718#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */
2719
2720/*
2721 * R1312 (0x520) - DSP2 RX Filters (1)
2722 */
2723#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */
2724#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */
2725#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */
2726#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */
2727#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */
2728#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */
2729#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */
2730#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */
2731#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */
2732#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */
2733#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */
2734#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */
2735#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */
2736#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */
2737#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */
2738#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */
2739
2740/*
2741 * R1313 (0x521) - DSP2 RX Filters (2)
2742 */
2743#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */
2744#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */
2745#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */
2746#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */
2747#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */
2748#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */
2749#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */
2750
2751/*
2752 * R1344 (0x540) - DSP2 DRC (1)
2753 */
2754#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2755#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2756#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */
2757#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */
2758#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */
2759#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */
2760#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */
2761#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */
2762#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */
2763#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */
2764#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */
2765#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */
2766#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */
2767#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */
2768#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */
2769#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */
2770#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */
2771#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */
2772#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2773#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */
2774#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */
2775#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */
2776#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */
2777#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */
2778#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */
2779#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */
2780#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */
2781#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */
2782#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */
2783#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */
2784#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */
2785#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */
2786#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */
2787#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */
2788#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */
2789#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */
2790#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */
2791#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */
2792#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */
2793#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */
2794#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */
2795#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */
2796
2797/*
2798 * R1345 (0x541) - DSP2 DRC (2)
2799 */
2800#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */
2801#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */
2802#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */
2803#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */
2804#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */
2805#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */
2806#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */
2807#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */
2808#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */
2809#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */
2810#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */
2811#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */
2812
2813/*
2814 * R1346 (0x542) - DSP2 DRC (3)
2815 */
2816#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */
2817#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */
2818#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */
2819#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */
2820#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */
2821#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */
2822#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */
2823#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */
2824#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */
2825#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */
2826#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */
2827#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */
2828#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */
2829#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */
2830#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */
2831#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */
2832#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */
2833#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */
2834
2835/*
2836 * R1347 (0x543) - DSP2 DRC (4)
2837 */
2838#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */
2839#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */
2840#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */
2841#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */
2842#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */
2843#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */
2844
2845/*
2846 * R1348 (0x544) - DSP2 DRC (5)
2847 */
2848#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */
2849#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2850#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */
2851#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */
2852#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */
2853#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */
2854
2855/*
2856 * R1408 (0x580) - DSP2 RX EQ Gains (1)
2857 */
2858#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2859#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2860#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */
2861#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2862#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2863#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */
2864#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */
2865#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2866#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */
2867#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */
2868#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */
2869#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */
2870#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */
2871
2872/*
2873 * R1409 (0x581) - DSP2 RX EQ Gains (2)
2874 */
2875#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2876#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2877#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */
2878#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2879#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2880#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */
2881
2882/*
2883 * R1410 (0x582) - DSP2 RX EQ Band 1 A
2884 */
2885#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */
2886#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */
2887#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */
2888
2889/*
2890 * R1411 (0x583) - DSP2 RX EQ Band 1 B
2891 */
2892#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */
2893#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */
2894#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */
2895
2896/*
2897 * R1412 (0x584) - DSP2 RX EQ Band 1 PG
2898 */
2899#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */
2900#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */
2901#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */
2902
2903/*
2904 * R1413 (0x585) - DSP2 RX EQ Band 2 A
2905 */
2906#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */
2907#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */
2908#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */
2909
2910/*
2911 * R1414 (0x586) - DSP2 RX EQ Band 2 B
2912 */
2913#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */
2914#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */
2915#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */
2916
2917/*
2918 * R1415 (0x587) - DSP2 RX EQ Band 2 C
2919 */
2920#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */
2921#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */
2922#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */
2923
2924/*
2925 * R1416 (0x588) - DSP2 RX EQ Band 2 PG
2926 */
2927#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */
2928#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */
2929#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */
2930
2931/*
2932 * R1417 (0x589) - DSP2 RX EQ Band 3 A
2933 */
2934#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */
2935#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */
2936#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */
2937
2938/*
2939 * R1418 (0x58A) - DSP2 RX EQ Band 3 B
2940 */
2941#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */
2942#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */
2943#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */
2944
2945/*
2946 * R1419 (0x58B) - DSP2 RX EQ Band 3 C
2947 */
2948#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */
2949#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */
2950#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */
2951
2952/*
2953 * R1420 (0x58C) - DSP2 RX EQ Band 3 PG
2954 */
2955#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */
2956#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */
2957#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */
2958
2959/*
2960 * R1421 (0x58D) - DSP2 RX EQ Band 4 A
2961 */
2962#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */
2963#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */
2964#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */
2965
2966/*
2967 * R1422 (0x58E) - DSP2 RX EQ Band 4 B
2968 */
2969#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */
2970#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */
2971#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */
2972
2973/*
2974 * R1423 (0x58F) - DSP2 RX EQ Band 4 C
2975 */
2976#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */
2977#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */
2978#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */
2979
2980/*
2981 * R1424 (0x590) - DSP2 RX EQ Band 4 PG
2982 */
2983#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */
2984#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */
2985#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */
2986
2987/*
2988 * R1425 (0x591) - DSP2 RX EQ Band 5 A
2989 */
2990#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */
2991#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */
2992#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */
2993
2994/*
2995 * R1426 (0x592) - DSP2 RX EQ Band 5 B
2996 */
2997#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */
2998#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */
2999#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */
3000
3001/*
3002 * R1427 (0x593) - DSP2 RX EQ Band 5 PG
3003 */
3004#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */
3005#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */
3006#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */
3007
3008/*
3009 * R1536 (0x600) - DAC1 Mixer Volumes
3010 */
3011#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
3012#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
3013#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
3014#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
3015#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
3016#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
3017
3018/*
3019 * R1537 (0x601) - DAC1 Left Mixer Routing
3020 */
3021#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3022#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3023#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3024#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3025#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3026#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3027#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3028#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3029#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */
3030#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */
3031#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */
3032#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */
3033#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */
3034#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */
3035#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */
3036#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */
3037
3038/*
3039 * R1538 (0x602) - DAC1 Right Mixer Routing
3040 */
3041#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3042#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3043#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3044#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3045#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3046#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3047#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3048#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3049#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */
3050#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */
3051#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */
3052#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */
3053#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */
3054#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */
3055#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */
3056#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */
3057
3058/*
3059 * R1539 (0x603) - DAC2 Mixer Volumes
3060 */
3061#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
3062#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
3063#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
3064#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
3065#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
3066#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
3067
3068/*
3069 * R1540 (0x604) - DAC2 Left Mixer Routing
3070 */
3071#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3072#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3073#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3074#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3075#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3076#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3077#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3078#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3079#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */
3080#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */
3081#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */
3082#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */
3083#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */
3084#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */
3085#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */
3086#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */
3087
3088/*
3089 * R1541 (0x605) - DAC2 Right Mixer Routing
3090 */
3091#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3092#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3093#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3094#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3095#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3096#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3097#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3098#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3099#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */
3100#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */
3101#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */
3102#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */
3103#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */
3104#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */
3105#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */
3106#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */
3107
3108/*
3109 * R1542 (0x606) - DSP1 TX Left Mixer Routing
3110 */
3111#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */
3112#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */
3113#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */
3114#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */
3115#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */
3116#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */
3117#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */
3118#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */
3119
3120/*
3121 * R1543 (0x607) - DSP1 TX Right Mixer Routing
3122 */
3123#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */
3124#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */
3125#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */
3126#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */
3127#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */
3128#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */
3129#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */
3130#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */
3131
3132/*
3133 * R1544 (0x608) - DSP2 TX Left Mixer Routing
3134 */
3135#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */
3136#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */
3137#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */
3138#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */
3139#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */
3140#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */
3141#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */
3142#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */
3143
3144/*
3145 * R1545 (0x609) - DSP2 TX Right Mixer Routing
3146 */
3147#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */
3148#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */
3149#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */
3150#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */
3151#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */
3152#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */
3153#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */
3154#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */
3155
3156/*
3157 * R1546 (0x60A) - DSP TX Mixer Select
3158 */
3159#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */
3160#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */
3161#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */
3162#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */
3163
3164/*
3165 * R1552 (0x610) - DAC Softmute
3166 */
3167#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3168#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3169#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3170#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3171#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3172#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3173#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3174#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3175
3176/*
3177 * R1568 (0x620) - Oversampling
3178 */
3179#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */
3180#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */
3181#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */
3182#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */
3183#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */
3184#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */
3185#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */
3186#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */
3187#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */
3188#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3189#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3190#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3191#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */
3192#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3193#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3194#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3195
3196/*
3197 * R1569 (0x621) - Sidetone
3198 */
3199#define WM8915_ST_LPF 0x1000 /* ST_LPF */
3200#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */
3201#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */
3202#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */
3203#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3204#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3205#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3206#define WM8915_ST_HPF 0x0040 /* ST_HPF */
3207#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */
3208#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */
3209#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */
3210#define WM8915_STR_SEL 0x0002 /* STR_SEL */
3211#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */
3212#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */
3213#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */
3214#define WM8915_STL_SEL 0x0001 /* STL_SEL */
3215#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */
3216#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */
3217#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */
3218
3219/*
3220 * R1792 (0x700) - GPIO 1
3221 */
3222#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */
3223#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */
3224#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */
3225#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */
3226#define WM8915_GP1_PU 0x4000 /* GP1_PU */
3227#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */
3228#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */
3229#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */
3230#define WM8915_GP1_PD 0x2000 /* GP1_PD */
3231#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */
3232#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */
3233#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */
3234#define WM8915_GP1_POL 0x0400 /* GP1_POL */
3235#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */
3236#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */
3237#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */
3238#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
3239#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
3240#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
3241#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
3242#define WM8915_GP1_DB 0x0100 /* GP1_DB */
3243#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */
3244#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */
3245#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */
3246#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */
3247#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */
3248#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */
3249#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */
3250#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */
3251#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */
3252#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */
3253
3254/*
3255 * R1793 (0x701) - GPIO 2
3256 */
3257#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */
3258#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */
3259#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */
3260#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */
3261#define WM8915_GP2_PU 0x4000 /* GP2_PU */
3262#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */
3263#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */
3264#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */
3265#define WM8915_GP2_PD 0x2000 /* GP2_PD */
3266#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */
3267#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */
3268#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */
3269#define WM8915_GP2_POL 0x0400 /* GP2_POL */
3270#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */
3271#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */
3272#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */
3273#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
3274#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
3275#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
3276#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
3277#define WM8915_GP2_DB 0x0100 /* GP2_DB */
3278#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */
3279#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */
3280#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */
3281#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */
3282#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3283#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */
3284#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */
3285#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */
3286#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */
3287#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */
3288
3289/*
3290 * R1794 (0x702) - GPIO 3
3291 */
3292#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */
3293#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */
3294#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */
3295#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */
3296#define WM8915_GP3_PU 0x4000 /* GP3_PU */
3297#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */
3298#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */
3299#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */
3300#define WM8915_GP3_PD 0x2000 /* GP3_PD */
3301#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */
3302#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */
3303#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */
3304#define WM8915_GP3_POL 0x0400 /* GP3_POL */
3305#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */
3306#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */
3307#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */
3308#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3309#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3310#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3311#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3312#define WM8915_GP3_DB 0x0100 /* GP3_DB */
3313#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */
3314#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */
3315#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */
3316#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */
3317#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3318#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */
3319#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */
3320#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */
3321#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */
3322#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */
3323
3324/*
3325 * R1795 (0x703) - GPIO 4
3326 */
3327#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */
3328#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3329#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */
3330#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */
3331#define WM8915_GP4_PU 0x4000 /* GP4_PU */
3332#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */
3333#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */
3334#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */
3335#define WM8915_GP4_PD 0x2000 /* GP4_PD */
3336#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */
3337#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */
3338#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */
3339#define WM8915_GP4_POL 0x0400 /* GP4_POL */
3340#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */
3341#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */
3342#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */
3343#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3344#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3345#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3346#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3347#define WM8915_GP4_DB 0x0100 /* GP4_DB */
3348#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */
3349#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */
3350#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */
3351#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */
3352#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3353#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */
3354#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */
3355#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */
3356#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */
3357#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */
3358
3359/*
3360 * R1796 (0x704) - GPIO 5
3361 */
3362#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */
3363#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3364#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */
3365#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */
3366#define WM8915_GP5_PU 0x4000 /* GP5_PU */
3367#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */
3368#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */
3369#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */
3370#define WM8915_GP5_PD 0x2000 /* GP5_PD */
3371#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */
3372#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */
3373#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */
3374#define WM8915_GP5_POL 0x0400 /* GP5_POL */
3375#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */
3376#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */
3377#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */
3378#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3379#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3380#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3381#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3382#define WM8915_GP5_DB 0x0100 /* GP5_DB */
3383#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */
3384#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */
3385#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */
3386#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */
3387#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3388#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */
3389#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */
3390#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */
3391#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */
3392#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */
3393
3394/*
3395 * R1824 (0x720) - Pull Control (1)
3396 */
3397#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
3398#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
3399#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
3400#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3401#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
3402#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
3403#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
3404#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3405#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */
3406#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
3407#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
3408#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
3409#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */
3410#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
3411#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
3412#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3413#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */
3414#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3415#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3416#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3417#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */
3418#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3419#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3420#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3421#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3422#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3423#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3424#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3425#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3426#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3427#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3428#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3429#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3430#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3431#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3432#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3433#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3434#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3435#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3436#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3437#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */
3438#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3439#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3440#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3441#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */
3442#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3443#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3444#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3445
3446/*
3447 * R1825 (0x721) - Pull Control (2)
3448 */
3449#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */
3450#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */
3451#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */
3452#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3453#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */
3454#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */
3455#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */
3456#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */
3457#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */
3458#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */
3459#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */
3460#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */
3461#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */
3462#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */
3463#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */
3464#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */
3465#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */
3466#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */
3467#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */
3468#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */
3469#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */
3470#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */
3471#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */
3472#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */
3473#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */
3474#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */
3475#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */
3476#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */
3477#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */
3478#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */
3479#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */
3480#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */
3481
3482/*
3483 * R1840 (0x730) - Interrupt Status 1
3484 */
3485#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */
3486#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3487#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */
3488#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */
3489#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */
3490#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3491#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */
3492#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */
3493#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */
3494#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3495#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */
3496#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */
3497#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */
3498#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3499#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */
3500#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */
3501#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */
3502#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3503#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */
3504#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */
3505
3506/*
3507 * R1841 (0x731) - Interrupt Status 2
3508 */
3509#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
3510#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
3511#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
3512#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
3513#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
3514#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
3515#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
3516#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
3517#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
3518#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
3519#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
3520#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3521#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
3522#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
3523#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
3524#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3525#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */
3526#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */
3527#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */
3528#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */
3529#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */
3530#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */
3531#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */
3532#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */
3533#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */
3534#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */
3535#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */
3536#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */
3537#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
3538#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
3539#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
3540#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
3541#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
3542#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
3543#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
3544#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
3545#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */
3546#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */
3547#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */
3548#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */
3549
3550/*
3551 * R1842 (0x732) - Interrupt Raw Status 2
3552 */
3553#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
3554#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
3555#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
3556#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
3557#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
3558#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
3559#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
3560#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
3561#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
3562#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
3563#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
3564#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
3565#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
3566#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
3567#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
3568#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
3569#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */
3570#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */
3571#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */
3572#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */
3573#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */
3574#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */
3575#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */
3576#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */
3577#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */
3578#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */
3579#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */
3580#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */
3581
3582/*
3583 * R1848 (0x738) - Interrupt Status 1 Mask
3584 */
3585#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3586#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3587#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3588#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3589#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
3590#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
3591#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
3592#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
3593#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
3594#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
3595#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
3596#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
3597#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
3598#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
3599#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
3600#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
3601#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
3602#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
3603#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
3604#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
3605
3606/*
3607 * R1849 (0x739) - Interrupt Status 2 Mask
3608 */
3609#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
3610#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
3611#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
3612#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
3613#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
3614#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
3615#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
3616#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
3617#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
3618#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
3619#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
3620#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
3621#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
3622#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
3623#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
3624#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
3625#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3626#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */
3627#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */
3628#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */
3629#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3630#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */
3631#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */
3632#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */
3633#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3634#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */
3635#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */
3636#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */
3637#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
3638#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
3639#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
3640#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
3641#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
3642#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
3643#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
3644#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
3645#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
3646#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
3647#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
3648#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
3649
3650/*
3651 * R1856 (0x740) - Interrupt Control
3652 */
3653#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */
3654#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */
3655#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */
3656#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */
3657
3658/*
3659 * R2048 (0x800) - Left PDM Speaker
3660 */
3661#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */
3662#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */
3663#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */
3664#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
3665#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */
3666#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */
3667#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */
3668#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */
3669#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */
3670#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */
3671#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */
3672#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */
3673#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */
3674#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */
3675#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */
3676
3677/*
3678 * R2049 (0x801) - Right PDM Speaker
3679 */
3680#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */
3681#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */
3682#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */
3683#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
3684#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */
3685#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */
3686#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */
3687#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */
3688#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */
3689#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */
3690#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */
3691#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */
3692#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */
3693#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */
3694#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */
3695
3696/*
3697 * R2050 (0x802) - PDM Speaker Mute Sequence
3698 */
3699#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */
3700#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */
3701#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */
3702#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */
3703#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */
3704#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */
3705#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */
3706
3707/*
3708 * R2051 (0x803) - PDM Speaker Volume
3709 */
3710#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */
3711#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */
3712#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */
3713#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */
3714#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */
3715#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */
3716
3717#endif
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index f0c11138e610..25580e3ee7c4 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -35,7 +35,6 @@
35#include <sound/pcm.h> 35#include <sound/pcm.h>
36#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/soc-dapm.h>
39#include <sound/initval.h> 38#include <sound/initval.h>
40#include <sound/tlv.h> 39#include <sound/tlv.h>
41 40
@@ -43,8 +42,8 @@
43 42
44struct wm8940_priv { 43struct wm8940_priv {
45 unsigned int sysclk; 44 unsigned int sysclk;
46 u16 reg_cache[WM8940_CACHEREGNUM]; 45 enum snd_soc_control_type control_type;
47 struct snd_soc_codec codec; 46 void *control_data;
48}; 47};
49 48
50static u16 wm8940_reg_defaults[] = { 49static u16 wm8940_reg_defaults[] = {
@@ -290,13 +289,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
290 289
291static int wm8940_add_widgets(struct snd_soc_codec *codec) 290static int wm8940_add_widgets(struct snd_soc_codec *codec)
292{ 291{
292 struct snd_soc_dapm_context *dapm = &codec->dapm;
293 int ret; 293 int ret;
294 294
295 ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets, 295 ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets,
296 ARRAY_SIZE(wm8940_dapm_widgets)); 296 ARRAY_SIZE(wm8940_dapm_widgets));
297 if (ret) 297 if (ret)
298 goto error_ret; 298 goto error_ret;
299 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 299 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
300 if (ret) 300 if (ret)
301 goto error_ret; 301 goto error_ret;
302 302
@@ -365,8 +365,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
365 struct snd_soc_dai *dai) 365 struct snd_soc_dai *dai)
366{ 366{
367 struct snd_soc_pcm_runtime *rtd = substream->private_data; 367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
368 struct snd_soc_device *socdev = rtd->socdev; 368 struct snd_soc_codec *codec = rtd->codec;
369 struct snd_soc_codec *codec = socdev->card->codec;
370 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F; 369 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
371 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1; 370 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
372 u16 companding = snd_soc_read(codec, 371 u16 companding = snd_soc_read(codec,
@@ -636,8 +635,8 @@ static struct snd_soc_dai_ops wm8940_dai_ops = {
636 .set_pll = wm8940_set_dai_pll, 635 .set_pll = wm8940_set_dai_pll,
637}; 636};
638 637
639struct snd_soc_dai wm8940_dai = { 638static struct snd_soc_dai_driver wm8940_dai = {
640 .name = "WM8940", 639 .name = "wm8940-hifi",
641 .playback = { 640 .playback = {
642 .stream_name = "Playback", 641 .stream_name = "Playback",
643 .channels_min = 1, 642 .channels_min = 1,
@@ -655,20 +654,14 @@ struct snd_soc_dai wm8940_dai = {
655 .ops = &wm8940_dai_ops, 654 .ops = &wm8940_dai_ops,
656 .symmetric_rates = 1, 655 .symmetric_rates = 1,
657}; 656};
658EXPORT_SYMBOL_GPL(wm8940_dai);
659 657
660static int wm8940_suspend(struct platform_device *pdev, pm_message_t state) 658static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state)
661{ 659{
662 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
663 struct snd_soc_codec *codec = socdev->card->codec;
664
665 return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); 660 return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
666} 661}
667 662
668static int wm8940_resume(struct platform_device *pdev) 663static int wm8940_resume(struct snd_soc_codec *codec)
669{ 664{
670 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
671 struct snd_soc_codec *codec = socdev->card->codec;
672 int i; 665 int i;
673 int ret; 666 int ret;
674 u8 data[3]; 667 u8 data[3];
@@ -697,108 +690,26 @@ error_ret:
697 return ret; 690 return ret;
698} 691}
699 692
700static struct snd_soc_codec *wm8940_codec; 693static int wm8940_probe(struct snd_soc_codec *codec)
701
702static int wm8940_probe(struct platform_device *pdev)
703{
704 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
705 struct snd_soc_codec *codec;
706
707 int ret = 0;
708
709 if (wm8940_codec == NULL) {
710 dev_err(&pdev->dev, "Codec device not registered\n");
711 return -ENODEV;
712 }
713
714 socdev->card->codec = wm8940_codec;
715 codec = wm8940_codec;
716
717 mutex_init(&codec->mutex);
718 /* register pcms */
719 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
720 if (ret < 0) {
721 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
722 goto pcm_err;
723 }
724
725 ret = snd_soc_add_controls(codec, wm8940_snd_controls,
726 ARRAY_SIZE(wm8940_snd_controls));
727 if (ret)
728 goto error_free_pcms;
729 ret = wm8940_add_widgets(codec);
730 if (ret)
731 goto error_free_pcms;
732
733 return ret;
734
735error_free_pcms:
736 snd_soc_free_pcms(socdev);
737 snd_soc_dapm_free(socdev);
738pcm_err:
739 return ret;
740}
741
742static int wm8940_remove(struct platform_device *pdev)
743{
744 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
745
746 snd_soc_free_pcms(socdev);
747 snd_soc_dapm_free(socdev);
748
749 return 0;
750}
751
752struct snd_soc_codec_device soc_codec_dev_wm8940 = {
753 .probe = wm8940_probe,
754 .remove = wm8940_remove,
755 .suspend = wm8940_suspend,
756 .resume = wm8940_resume,
757};
758EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940);
759
760static int wm8940_register(struct wm8940_priv *wm8940,
761 enum snd_soc_control_type control)
762{ 694{
763 struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data; 695 struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
764 struct snd_soc_codec *codec = &wm8940->codec; 696 struct wm8940_setup_data *pdata = codec->dev->platform_data;
765 int ret; 697 int ret;
766 u16 reg; 698 u16 reg;
767 if (wm8940_codec) {
768 dev_err(codec->dev, "Another WM8940 is registered\n");
769 return -EINVAL;
770 }
771
772 INIT_LIST_HEAD(&codec->dapm_widgets);
773 INIT_LIST_HEAD(&codec->dapm_paths);
774
775 snd_soc_codec_set_drvdata(codec, wm8940);
776 codec->name = "WM8940";
777 codec->owner = THIS_MODULE;
778 codec->bias_level = SND_SOC_BIAS_OFF;
779 codec->set_bias_level = wm8940_set_bias_level;
780 codec->dai = &wm8940_dai;
781 codec->num_dai = 1;
782 codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults);
783 codec->reg_cache = &wm8940->reg_cache;
784 699
785 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); 700 codec->control_data = wm8940->control_data;
701 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
786 if (ret < 0) { 702 if (ret < 0) {
787 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 703 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
788 return ret; 704 return ret;
789 } 705 }
790 706
791 memcpy(codec->reg_cache, wm8940_reg_defaults,
792 sizeof(wm8940_reg_defaults));
793
794 ret = wm8940_reset(codec); 707 ret = wm8940_reset(codec);
795 if (ret < 0) { 708 if (ret < 0) {
796 dev_err(codec->dev, "Failed to issue reset\n"); 709 dev_err(codec->dev, "Failed to issue reset\n");
797 return ret; 710 return ret;
798 } 711 }
799 712
800 wm8940_dai.dev = codec->dev;
801
802 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 713 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
803 714
804 ret = snd_soc_write(codec, WM8940_POWER1, 0x180); 715 ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
@@ -814,64 +725,60 @@ static int wm8940_register(struct wm8940_priv *wm8940,
814 return ret; 725 return ret;
815 } 726 }
816 727
817 728 ret = snd_soc_add_controls(codec, wm8940_snd_controls,
818 wm8940_codec = codec; 729 ARRAY_SIZE(wm8940_snd_controls));
819 730 if (ret)
820 ret = snd_soc_register_codec(codec);
821 if (ret) {
822 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
823 return ret; 731 return ret;
824 } 732 ret = wm8940_add_widgets(codec);
825 733 if (ret)
826 ret = snd_soc_register_dai(&wm8940_dai);
827 if (ret) {
828 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
829 snd_soc_unregister_codec(codec);
830 return ret; 734 return ret;
831 }
832 735
833 return 0; 736 return ret;
834} 737}
835 738
836static void wm8940_unregister(struct wm8940_priv *wm8940) 739static int wm8940_remove(struct snd_soc_codec *codec)
837{ 740{
838 wm8940_set_bias_level(&wm8940->codec, SND_SOC_BIAS_OFF); 741 wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
839 snd_soc_unregister_dai(&wm8940_dai); 742 return 0;
840 snd_soc_unregister_codec(&wm8940->codec);
841 kfree(wm8940);
842 wm8940_codec = NULL;
843} 743}
844 744
845static int wm8940_i2c_probe(struct i2c_client *i2c, 745static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
846 const struct i2c_device_id *id) 746 .probe = wm8940_probe,
747 .remove = wm8940_remove,
748 .suspend = wm8940_suspend,
749 .resume = wm8940_resume,
750 .set_bias_level = wm8940_set_bias_level,
751 .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults),
752 .reg_word_size = sizeof(u16),
753 .reg_cache_default = wm8940_reg_defaults,
754};
755
756#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
757static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
758 const struct i2c_device_id *id)
847{ 759{
848 int ret;
849 struct wm8940_priv *wm8940; 760 struct wm8940_priv *wm8940;
850 struct snd_soc_codec *codec; 761 int ret;
851 762
852 wm8940 = kzalloc(sizeof *wm8940, GFP_KERNEL); 763 wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL);
853 if (wm8940 == NULL) 764 if (wm8940 == NULL)
854 return -ENOMEM; 765 return -ENOMEM;
855 766
856 codec = &wm8940->codec;
857 codec->hw_write = (hw_write_t)i2c_master_send;
858 i2c_set_clientdata(i2c, wm8940); 767 i2c_set_clientdata(i2c, wm8940);
859 codec->control_data = i2c; 768 wm8940->control_data = i2c;
860 codec->dev = &i2c->dev; 769 wm8940->control_type = SND_SOC_I2C;
861 770
862 ret = wm8940_register(wm8940, SND_SOC_I2C); 771 ret = snd_soc_register_codec(&i2c->dev,
772 &soc_codec_dev_wm8940, &wm8940_dai, 1);
863 if (ret < 0) 773 if (ret < 0)
864 kfree(wm8940); 774 kfree(wm8940);
865
866 return ret; 775 return ret;
867} 776}
868 777
869static int __devexit wm8940_i2c_remove(struct i2c_client *client) 778static __devexit int wm8940_i2c_remove(struct i2c_client *client)
870{ 779{
871 struct wm8940_priv *wm8940 = i2c_get_clientdata(client); 780 snd_soc_unregister_codec(&client->dev);
872 781 kfree(i2c_get_clientdata(client));
873 wm8940_unregister(wm8940);
874
875 return 0; 782 return 0;
876} 783}
877 784
@@ -883,29 +790,34 @@ MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
883 790
884static struct i2c_driver wm8940_i2c_driver = { 791static struct i2c_driver wm8940_i2c_driver = {
885 .driver = { 792 .driver = {
886 .name = "WM8940 I2C Codec", 793 .name = "wm8940-codec",
887 .owner = THIS_MODULE, 794 .owner = THIS_MODULE,
888 }, 795 },
889 .probe = wm8940_i2c_probe, 796 .probe = wm8940_i2c_probe,
890 .remove = __devexit_p(wm8940_i2c_remove), 797 .remove = __devexit_p(wm8940_i2c_remove),
891 .id_table = wm8940_i2c_id, 798 .id_table = wm8940_i2c_id,
892}; 799};
800#endif
893 801
894static int __init wm8940_modinit(void) 802static int __init wm8940_modinit(void)
895{ 803{
896 int ret; 804 int ret = 0;
897 805#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
898 ret = i2c_add_driver(&wm8940_i2c_driver); 806 ret = i2c_add_driver(&wm8940_i2c_driver);
899 if (ret) 807 if (ret != 0) {
900 printk(KERN_ERR "Failed to register WM8940 I2C driver: %d\n", 808 printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
901 ret); 809 ret);
810 }
811#endif
902 return ret; 812 return ret;
903} 813}
904module_init(wm8940_modinit); 814module_init(wm8940_modinit);
905 815
906static void __exit wm8940_exit(void) 816static void __exit wm8940_exit(void)
907{ 817{
818#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
908 i2c_del_driver(&wm8940_i2c_driver); 819 i2c_del_driver(&wm8940_i2c_driver);
820#endif
909} 821}
910module_exit(wm8940_exit); 822module_exit(wm8940_exit);
911 823
diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h
index 8410eed3ef84..907fe192e9e0 100644
--- a/sound/soc/codecs/wm8940.h
+++ b/sound/soc/codecs/wm8940.h
@@ -15,8 +15,6 @@ struct wm8940_setup_data {
15#define WM8940_VROI_30K 1 15#define WM8940_VROI_30K 1
16 unsigned int vroi:1; 16 unsigned int vroi:1;
17}; 17};
18extern struct snd_soc_dai wm8940_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8940;
20 18
21/* WM8940 register space */ 19/* WM8940 register space */
22#define WM8940_SOFTRESET 0x00 20#define WM8940_SOFTRESET 0x00
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 5f025593d84d..3c7198779c31 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -23,16 +23,12 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29#include <sound/wm8955.h> 28#include <sound/wm8955.h>
30 29
31#include "wm8955.h" 30#include "wm8955.h"
32 31
33static struct snd_soc_codec *wm8955_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8955;
35
36#define WM8955_NUM_SUPPLIES 4 32#define WM8955_NUM_SUPPLIES 4
37static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { 33static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
38 "DCVDD", 34 "DCVDD",
@@ -43,8 +39,7 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
43 39
44/* codec private data */ 40/* codec private data */
45struct wm8955_priv { 41struct wm8955_priv {
46 struct snd_soc_codec codec; 42 enum snd_soc_control_type control_type;
47 u16 reg_cache[WM8955_MAX_REGISTER + 1];
48 43
49 unsigned int mclk_rate; 44 unsigned int mclk_rate;
50 45
@@ -52,8 +47,6 @@ struct wm8955_priv {
52 int fs; 47 int fs;
53 48
54 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; 49 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
55
56 struct wm8955_pdata *pdata;
57}; 50};
58 51
59static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = { 52static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
@@ -183,7 +176,7 @@ static int wm8995_pll_factors(struct device *dev,
183 return 0; 176 return 0;
184} 177}
185 178
186/* Lookup table specifiying SRATE (table 25 in datasheet); some of the 179/* Lookup table specifying SRATE (table 25 in datasheet); some of the
187 * output frequencies have been rounded to the standard frequencies 180 * output frequencies have been rounded to the standard frequencies
188 * they are intended to match where the error is slight. */ 181 * they are intended to match where the error is slight. */
189static struct { 182static struct {
@@ -384,7 +377,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 378 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
386 379
387 return wm8955->deemph; 380 ucontrol->value.enumerated.item[0] = wm8955->deemph;
381 return 0;
388} 382}
389 383
390static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, 384static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
@@ -581,13 +575,14 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = {
581 575
582static int wm8955_add_widgets(struct snd_soc_codec *codec) 576static int wm8955_add_widgets(struct snd_soc_codec *codec)
583{ 577{
578 struct snd_soc_dapm_context *dapm = &codec->dapm;
579
584 snd_soc_add_controls(codec, wm8955_snd_controls, 580 snd_soc_add_controls(codec, wm8955_snd_controls,
585 ARRAY_SIZE(wm8955_snd_controls)); 581 ARRAY_SIZE(wm8955_snd_controls));
586 582
587 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets, 583 snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets,
588 ARRAY_SIZE(wm8955_dapm_widgets)); 584 ARRAY_SIZE(wm8955_dapm_widgets));
589 585 snd_soc_dapm_add_routes(dapm, wm8955_intercon,
590 snd_soc_dapm_add_routes(codec, wm8955_intercon,
591 ARRAY_SIZE(wm8955_intercon)); 586 ARRAY_SIZE(wm8955_intercon));
592 587
593 return 0; 588 return 0;
@@ -771,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
771 enum snd_soc_bias_level level) 766 enum snd_soc_bias_level level)
772{ 767{
773 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 768 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
769 u16 *reg_cache = codec->reg_cache;
774 int ret, i; 770 int ret, i;
775 771
776 switch (level) { 772 switch (level) {
@@ -790,7 +786,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
790 break; 786 break;
791 787
792 case SND_SOC_BIAS_STANDBY: 788 case SND_SOC_BIAS_STANDBY:
793 if (codec->bias_level == SND_SOC_BIAS_OFF) { 789 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
794 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), 790 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
795 wm8955->supplies); 791 wm8955->supplies);
796 if (ret != 0) { 792 if (ret != 0) {
@@ -803,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
803 /* Sync back cached values if they're 799 /* Sync back cached values if they're
804 * different from the hardware default. 800 * different from the hardware default.
805 */ 801 */
806 for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) { 802 for (i = 0; i < codec->driver->reg_cache_size; i++) {
807 if (i == WM8955_RESET) 803 if (i == WM8955_RESET)
808 continue; 804 continue;
809 805
810 if (wm8955->reg_cache[i] == wm8955_reg[i]) 806 if (reg_cache[i] == wm8955_reg[i])
811 continue; 807 continue;
812 808
813 snd_soc_write(codec, i, wm8955->reg_cache[i]); 809 snd_soc_write(codec, i, reg_cache[i]);
814 } 810 }
815 811
816 /* Enable VREF and VMID */ 812 /* Enable VREF and VMID */
@@ -854,7 +850,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
854 wm8955->supplies); 850 wm8955->supplies);
855 break; 851 break;
856 } 852 }
857 codec->bias_level = level; 853 codec->dapm.bias_level = level;
858 return 0; 854 return 0;
859} 855}
860 856
@@ -870,8 +866,8 @@ static struct snd_soc_dai_ops wm8955_dai_ops = {
870 .digital_mute = wm8955_digital_mute, 866 .digital_mute = wm8955_digital_mute,
871}; 867};
872 868
873struct snd_soc_dai wm8955_dai = { 869static struct snd_soc_dai_driver wm8955_dai = {
874 .name = "WM8955", 870 .name = "wm8955-hifi",
875 .playback = { 871 .playback = {
876 .stream_name = "Playback", 872 .stream_name = "Playback",
877 .channels_min = 2, 873 .channels_min = 2,
@@ -881,24 +877,17 @@ struct snd_soc_dai wm8955_dai = {
881 }, 877 },
882 .ops = &wm8955_dai_ops, 878 .ops = &wm8955_dai_ops,
883}; 879};
884EXPORT_SYMBOL_GPL(wm8955_dai);
885 880
886#ifdef CONFIG_PM 881#ifdef CONFIG_PM
887static int wm8955_suspend(struct platform_device *pdev, pm_message_t state) 882static int wm8955_suspend(struct snd_soc_codec *codec, pm_message_t state)
888{ 883{
889 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
890 struct snd_soc_codec *codec = socdev->card->codec;
891
892 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); 884 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
893 885
894 return 0; 886 return 0;
895} 887}
896 888
897static int wm8955_resume(struct platform_device *pdev) 889static int wm8955_resume(struct snd_soc_codec *codec)
898{ 890{
899 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
900 struct snd_soc_codec *codec = socdev->card->codec;
901
902 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 891 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
903 892
904 return 0; 893 return 0;
@@ -908,86 +897,17 @@ static int wm8955_resume(struct platform_device *pdev)
908#define wm8955_resume NULL 897#define wm8955_resume NULL
909#endif 898#endif
910 899
911static int wm8955_probe(struct platform_device *pdev) 900static int wm8955_probe(struct snd_soc_codec *codec)
912{ 901{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 902 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
914 struct snd_soc_codec *codec; 903 struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
915 int ret = 0; 904 u16 *reg_cache = codec->reg_cache;
916 905 int ret, i;
917 if (wm8955_codec == NULL) {
918 dev_err(&pdev->dev, "Codec device not registered\n");
919 return -ENODEV;
920 }
921
922 socdev->card->codec = wm8955_codec;
923 codec = wm8955_codec;
924
925 /* register pcms */
926 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
927 if (ret < 0) {
928 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
929 goto pcm_err;
930 }
931
932 wm8955_add_widgets(codec);
933
934 return ret;
935
936pcm_err:
937 return ret;
938}
939
940static int wm8955_remove(struct platform_device *pdev)
941{
942 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
943
944 snd_soc_free_pcms(socdev);
945 snd_soc_dapm_free(socdev);
946
947 return 0;
948}
949
950struct snd_soc_codec_device soc_codec_dev_wm8955 = {
951 .probe = wm8955_probe,
952 .remove = wm8955_remove,
953 .suspend = wm8955_suspend,
954 .resume = wm8955_resume,
955};
956EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
957
958static int wm8955_register(struct wm8955_priv *wm8955,
959 enum snd_soc_control_type control)
960{
961 int ret;
962 struct snd_soc_codec *codec = &wm8955->codec;
963 int i;
964
965 if (wm8955_codec) {
966 dev_err(codec->dev, "Another WM8955 is registered\n");
967 ret = -EINVAL;
968 goto err;
969 }
970
971 mutex_init(&codec->mutex);
972 INIT_LIST_HEAD(&codec->dapm_widgets);
973 INIT_LIST_HEAD(&codec->dapm_paths);
974
975 snd_soc_codec_set_drvdata(codec, wm8955);
976 codec->name = "WM8955";
977 codec->owner = THIS_MODULE;
978 codec->bias_level = SND_SOC_BIAS_OFF;
979 codec->set_bias_level = wm8955_set_bias_level;
980 codec->dai = &wm8955_dai;
981 codec->num_dai = 1;
982 codec->reg_cache_size = WM8955_MAX_REGISTER;
983 codec->reg_cache = &wm8955->reg_cache;
984
985 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
986 906
987 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 907 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
988 if (ret != 0) { 908 if (ret != 0) {
989 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 909 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
990 goto err; 910 return ret;
991 } 911 }
992 912
993 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) 913 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
@@ -997,7 +917,7 @@ static int wm8955_register(struct wm8955_priv *wm8955,
997 wm8955->supplies); 917 wm8955->supplies);
998 if (ret != 0) { 918 if (ret != 0) {
999 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 919 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1000 goto err; 920 return ret;
1001 } 921 }
1002 922
1003 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), 923 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
@@ -1013,28 +933,37 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1013 goto err_enable; 933 goto err_enable;
1014 } 934 }
1015 935
1016 wm8955_dai.dev = codec->dev;
1017
1018 /* Change some default settings - latch VU and enable ZC */ 936 /* Change some default settings - latch VU and enable ZC */
1019 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; 937 snd_soc_update_bits(codec, WM8955_LEFT_DAC_VOLUME,
1020 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; 938 WM8955_LDVU, WM8955_LDVU);
1021 wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; 939 snd_soc_update_bits(codec, WM8955_RIGHT_DAC_VOLUME,
1022 wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; 940 WM8955_RDVU, WM8955_RDVU);
1023 wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; 941 snd_soc_update_bits(codec, WM8955_LOUT1_VOLUME,
1024 wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; 942 WM8955_LO1VU | WM8955_LO1ZC,
1025 wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; 943 WM8955_LO1VU | WM8955_LO1ZC);
944 snd_soc_update_bits(codec, WM8955_ROUT1_VOLUME,
945 WM8955_RO1VU | WM8955_RO1ZC,
946 WM8955_RO1VU | WM8955_RO1ZC);
947 snd_soc_update_bits(codec, WM8955_LOUT2_VOLUME,
948 WM8955_LO2VU | WM8955_LO2ZC,
949 WM8955_LO2VU | WM8955_LO2ZC);
950 snd_soc_update_bits(codec, WM8955_ROUT2_VOLUME,
951 WM8955_RO2VU | WM8955_RO2ZC,
952 WM8955_RO2VU | WM8955_RO2ZC);
953 snd_soc_update_bits(codec, WM8955_MONOOUT_VOLUME,
954 WM8955_MOZC, WM8955_MOZC);
1026 955
1027 /* Also enable adaptive bass boost by default */ 956 /* Also enable adaptive bass boost by default */
1028 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; 957 snd_soc_update_bits(codec, WM8955_BASS_CONTROL, WM8955_BB, WM8955_BB);
1029 958
1030 /* Set platform data values */ 959 /* Set platform data values */
1031 if (wm8955->pdata) { 960 if (pdata) {
1032 if (wm8955->pdata->out2_speaker) 961 if (pdata->out2_speaker)
1033 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2] 962 reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1034 |= WM8955_ROUT2INV; 963 |= WM8955_ROUT2INV;
1035 964
1036 if (wm8955->pdata->monoin_diff) 965 if (pdata->monoin_diff)
1037 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1] 966 reg_cache[WM8955_MONO_OUT_MIX_1]
1038 |= WM8955_DMEN; 967 |= WM8955_DMEN;
1039 } 968 }
1040 969
@@ -1043,70 +972,61 @@ static int wm8955_register(struct wm8955_priv *wm8955,
1043 /* Bias level configuration will have done an extra enable */ 972 /* Bias level configuration will have done an extra enable */
1044 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 973 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1045 974
1046 wm8955_codec = codec; 975 wm8955_add_widgets(codec);
1047
1048 ret = snd_soc_register_codec(codec);
1049 if (ret != 0) {
1050 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1051 goto err_enable;
1052 }
1053
1054 ret = snd_soc_register_dai(&wm8955_dai);
1055 if (ret != 0) {
1056 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1057 goto err_codec;
1058 }
1059
1060 return 0; 976 return 0;
1061 977
1062err_codec:
1063 snd_soc_unregister_codec(codec);
1064err_enable: 978err_enable:
1065 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 979 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1066err_get: 980err_get:
1067 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 981 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1068err:
1069 kfree(wm8955);
1070 return ret; 982 return ret;
1071} 983}
1072 984
1073static void wm8955_unregister(struct wm8955_priv *wm8955) 985static int wm8955_remove(struct snd_soc_codec *codec)
1074{ 986{
1075 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF); 987 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
988
989 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
1076 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); 990 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1077 snd_soc_unregister_dai(&wm8955_dai); 991 return 0;
1078 snd_soc_unregister_codec(&wm8955->codec);
1079 kfree(wm8955);
1080 wm8955_codec = NULL;
1081} 992}
1082 993
994static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
995 .probe = wm8955_probe,
996 .remove = wm8955_remove,
997 .suspend = wm8955_suspend,
998 .resume = wm8955_resume,
999 .set_bias_level = wm8955_set_bias_level,
1000 .reg_cache_size = ARRAY_SIZE(wm8955_reg),
1001 .reg_word_size = sizeof(u16),
1002 .reg_cache_default = wm8955_reg,
1003};
1004
1083#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1005#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1084static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, 1006static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1085 const struct i2c_device_id *id) 1007 const struct i2c_device_id *id)
1086{ 1008{
1087 struct wm8955_priv *wm8955; 1009 struct wm8955_priv *wm8955;
1088 struct snd_soc_codec *codec; 1010 int ret;
1089 1011
1090 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL); 1012 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1091 if (wm8955 == NULL) 1013 if (wm8955 == NULL)
1092 return -ENOMEM; 1014 return -ENOMEM;
1093 1015
1094 codec = &wm8955->codec;
1095 codec->hw_write = (hw_write_t)i2c_master_send;
1096
1097 i2c_set_clientdata(i2c, wm8955); 1016 i2c_set_clientdata(i2c, wm8955);
1098 codec->control_data = i2c; 1017 wm8955->control_type = SND_SOC_I2C;
1099 wm8955->pdata = i2c->dev.platform_data;
1100
1101 codec->dev = &i2c->dev;
1102 1018
1103 return wm8955_register(wm8955, SND_SOC_I2C); 1019 ret = snd_soc_register_codec(&i2c->dev,
1020 &soc_codec_dev_wm8955, &wm8955_dai, 1);
1021 if (ret < 0)
1022 kfree(wm8955);
1023 return ret;
1104} 1024}
1105 1025
1106static __devexit int wm8955_i2c_remove(struct i2c_client *client) 1026static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1107{ 1027{
1108 struct wm8955_priv *wm8955 = i2c_get_clientdata(client); 1028 snd_soc_unregister_codec(&client->dev);
1109 wm8955_unregister(wm8955); 1029 kfree(i2c_get_clientdata(client));
1110 return 0; 1030 return 0;
1111} 1031}
1112 1032
@@ -1118,7 +1038,7 @@ MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1118 1038
1119static struct i2c_driver wm8955_i2c_driver = { 1039static struct i2c_driver wm8955_i2c_driver = {
1120 .driver = { 1040 .driver = {
1121 .name = "wm8955", 1041 .name = "wm8955-codec",
1122 .owner = THIS_MODULE, 1042 .owner = THIS_MODULE,
1123 }, 1043 },
1124 .probe = wm8955_i2c_probe, 1044 .probe = wm8955_i2c_probe,
@@ -1129,7 +1049,7 @@ static struct i2c_driver wm8955_i2c_driver = {
1129 1049
1130static int __init wm8955_modinit(void) 1050static int __init wm8955_modinit(void)
1131{ 1051{
1132 int ret; 1052 int ret = 0;
1133#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1053#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1134 ret = i2c_add_driver(&wm8955_i2c_driver); 1054 ret = i2c_add_driver(&wm8955_i2c_driver);
1135 if (ret != 0) { 1055 if (ret != 0) {
@@ -1137,7 +1057,7 @@ static int __init wm8955_modinit(void)
1137 ret); 1057 ret);
1138 } 1058 }
1139#endif 1059#endif
1140 return 0; 1060 return ret;
1141} 1061}
1142module_init(wm8955_modinit); 1062module_init(wm8955_modinit);
1143 1063
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
index ae349c8531f6..d13fd5c5fa63 100644
--- a/sound/soc/codecs/wm8955.h
+++ b/sound/soc/codecs/wm8955.h
@@ -15,9 +15,6 @@
15 15
16#define WM8955_CLK_MCLK 1 16#define WM8955_CLK_MCLK 1
17 17
18extern struct snd_soc_dai wm8955_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8955;
20
21/* 18/*
22 * Register values. 19 * Register values.
23 */ 20 */
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
new file mode 100644
index 000000000000..0293763debe5
--- /dev/null
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -0,0 +1,1051 @@
1/*
2 * wm8958-dsp2.c -- WM8958 DSP2 support
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <sound/soc.h>
22#include <sound/initval.h>
23#include <sound/tlv.h>
24#include <trace/events/asoc.h>
25
26#include <linux/mfd/wm8994/core.h>
27#include <linux/mfd/wm8994/registers.h>
28#include <linux/mfd/wm8994/pdata.h>
29#include <linux/mfd/wm8994/gpio.h>
30
31#include "wm8994.h"
32
33#define WM_FW_BLOCK_INFO 0xff
34#define WM_FW_BLOCK_PM 0x00
35#define WM_FW_BLOCK_X 0x01
36#define WM_FW_BLOCK_Y 0x02
37#define WM_FW_BLOCK_Z 0x03
38#define WM_FW_BLOCK_I 0x06
39#define WM_FW_BLOCK_A 0x08
40#define WM_FW_BLOCK_C 0x0c
41
42static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name,
43 const struct firmware *fw, bool check)
44{
45 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
46 u64 data64;
47 u32 data32;
48 const u8 *data;
49 char *str;
50 size_t block_len, len;
51 int ret = 0;
52
53 /* Suppress unneeded downloads */
54 if (wm8994->cur_fw == fw)
55 return 0;
56
57 if (fw->size < 32) {
58 dev_err(codec->dev, "%s: firmware too short\n", name);
59 goto err;
60 }
61
62 if (memcmp(fw->data, "WMFW", 4) != 0) {
63 dev_err(codec->dev, "%s: firmware has bad file magic %08x\n",
64 name, data32);
65 goto err;
66 }
67
68 memcpy(&data32, fw->data + 4, sizeof(data32));
69 len = be32_to_cpu(data32);
70
71 memcpy(&data32, fw->data + 8, sizeof(data32));
72 data32 = be32_to_cpu(data32);
73 if ((data32 >> 24) & 0xff) {
74 dev_err(codec->dev, "%s: unsupported firmware version %d\n",
75 name, (data32 >> 24) & 0xff);
76 goto err;
77 }
78 if ((data32 & 0xffff) != 8958) {
79 dev_err(codec->dev, "%s: unsupported target device %d\n",
80 name, data32 & 0xffff);
81 goto err;
82 }
83 if (((data32 >> 16) & 0xff) != 0xc) {
84 dev_err(codec->dev, "%s: unsupported target core %d\n",
85 name, (data32 >> 16) & 0xff);
86 goto err;
87 }
88
89 if (check) {
90 memcpy(&data64, fw->data + 24, sizeof(u64));
91 dev_info(codec->dev, "%s timestamp %llx\n",
92 name, be64_to_cpu(data64));
93 } else {
94 snd_soc_write(codec, 0x102, 0x2);
95 snd_soc_write(codec, 0x900, 0x2);
96 }
97
98 data = fw->data + len;
99 len = fw->size - len;
100 while (len) {
101 if (len < 12) {
102 dev_err(codec->dev, "%s short data block of %zd\n",
103 name, len);
104 goto err;
105 }
106
107 memcpy(&data32, data + 4, sizeof(data32));
108 block_len = be32_to_cpu(data32);
109 if (block_len + 8 > len) {
110 dev_err(codec->dev, "%zd byte block longer than file\n",
111 block_len);
112 goto err;
113 }
114 if (block_len == 0) {
115 dev_err(codec->dev, "Zero length block\n");
116 goto err;
117 }
118
119 memcpy(&data32, data, sizeof(data32));
120 data32 = be32_to_cpu(data32);
121
122 switch ((data32 >> 24) & 0xff) {
123 case WM_FW_BLOCK_INFO:
124 /* Informational text */
125 if (!check)
126 break;
127
128 str = kzalloc(block_len + 1, GFP_KERNEL);
129 if (str) {
130 memcpy(str, data + 8, block_len);
131 dev_info(codec->dev, "%s: %s\n", name, str);
132 kfree(str);
133 } else {
134 dev_err(codec->dev, "Out of memory\n");
135 }
136 break;
137 case WM_FW_BLOCK_PM:
138 case WM_FW_BLOCK_X:
139 case WM_FW_BLOCK_Y:
140 case WM_FW_BLOCK_Z:
141 case WM_FW_BLOCK_I:
142 case WM_FW_BLOCK_A:
143 case WM_FW_BLOCK_C:
144 dev_dbg(codec->dev, "%s: %zd bytes of %x@%x\n", name,
145 block_len, (data32 >> 24) & 0xff,
146 data32 & 0xffffff);
147
148 if (check)
149 break;
150
151 data32 &= 0xffffff;
152
153 wm8994_bulk_write(codec->control_data,
154 data32 & 0xffffff,
155 block_len / 2,
156 (void *)(data + 8));
157
158 break;
159 default:
160 dev_warn(codec->dev, "%s: unknown block type %d\n",
161 name, (data32 >> 24) & 0xff);
162 break;
163 }
164
165 /* Round up to the next 32 bit word */
166 block_len += block_len % 4;
167
168 data += block_len + 8;
169 len -= block_len + 8;
170 }
171
172 if (!check) {
173 dev_dbg(codec->dev, "%s: download done\n", name);
174 wm8994->cur_fw = fw;
175 } else {
176 dev_info(codec->dev, "%s: got firmware\n", name);
177 }
178
179 goto ok;
180
181err:
182 ret = -EINVAL;
183ok:
184 if (!check) {
185 snd_soc_write(codec, 0x900, 0x0);
186 snd_soc_write(codec, 0x102, 0x0);
187 }
188
189 return ret;
190}
191
192static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
193{
194 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
195 struct wm8994_pdata *pdata = wm8994->pdata;
196 int i;
197
198 /* If the DSP is already running then noop */
199 if (snd_soc_read(codec, WM8958_DSP2_PROGRAM) & WM8958_DSP2_ENA)
200 return;
201
202 /* If we have MBC firmware download it */
203 if (wm8994->mbc)
204 wm8958_dsp2_fw(codec, "MBC", wm8994->mbc, false);
205
206 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
207 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
208
209 /* If we've got user supplied MBC settings use them */
210 if (pdata && pdata->num_mbc_cfgs) {
211 struct wm8958_mbc_cfg *cfg
212 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
213
214 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
215 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
216 cfg->coeff_regs[i]);
217
218 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
219 snd_soc_write(codec,
220 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
221 cfg->cutoff_regs[i]);
222 }
223
224 /* Run the DSP */
225 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
226 WM8958_DSP2_RUNR);
227
228 /* And we're off! */
229 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
230 WM8958_MBC_ENA |
231 WM8958_MBC_SEL_MASK,
232 path << WM8958_MBC_SEL_SHIFT |
233 WM8958_MBC_ENA);
234}
235
236static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
237{
238 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
239 struct wm8994_pdata *pdata = wm8994->pdata;
240 int i, ena;
241
242 if (wm8994->mbc_vss)
243 wm8958_dsp2_fw(codec, "MBC+VSS", wm8994->mbc_vss, false);
244
245 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
246 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
247
248 /* If we've got user supplied settings use them */
249 if (pdata && pdata->num_mbc_cfgs) {
250 struct wm8958_mbc_cfg *cfg
251 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
252
253 for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
254 snd_soc_write(codec, i + 0x2800,
255 cfg->combined_regs[i]);
256 }
257
258 if (pdata && pdata->num_vss_cfgs) {
259 struct wm8958_vss_cfg *cfg
260 = &pdata->vss_cfgs[wm8994->vss_cfg];
261
262 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
263 snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
264 }
265
266 if (pdata && pdata->num_vss_hpf_cfgs) {
267 struct wm8958_vss_hpf_cfg *cfg
268 = &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
269
270 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
271 snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
272 }
273
274 /* Run the DSP */
275 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
276 WM8958_DSP2_RUNR);
277
278 /* Enable the algorithms we've selected */
279 ena = 0;
280 if (wm8994->mbc_ena[path])
281 ena |= 0x8;
282 if (wm8994->hpf2_ena[path])
283 ena |= 0x4;
284 if (wm8994->hpf1_ena[path])
285 ena |= 0x2;
286 if (wm8994->vss_ena[path])
287 ena |= 0x1;
288
289 snd_soc_write(codec, 0x2201, ena);
290
291 /* Switch the DSP into the data path */
292 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
293 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
294 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
295}
296
297static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
298{
299 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
300 struct wm8994_pdata *pdata = wm8994->pdata;
301 int i;
302
303 wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
304
305 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
306 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
307
308 /* If we've got user supplied settings use them */
309 if (pdata && pdata->num_enh_eq_cfgs) {
310 struct wm8958_enh_eq_cfg *cfg
311 = &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
312
313 for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
314 snd_soc_write(codec, i + 0x2200,
315 cfg->regs[i]);
316 }
317
318 /* Run the DSP */
319 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
320 WM8958_DSP2_RUNR);
321
322 /* Switch the DSP into the data path */
323 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
324 WM8958_MBC_SEL_MASK | WM8958_MBC_ENA,
325 path << WM8958_MBC_SEL_SHIFT | WM8958_MBC_ENA);
326}
327
328static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
329{
330 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
331 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
332 int ena, reg, aif;
333
334 switch (path) {
335 case 0:
336 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
337 aif = 0;
338 break;
339 case 1:
340 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
341 aif = 0;
342 break;
343 case 2:
344 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
345 aif = 1;
346 break;
347 default:
348 BUG();
349 return;
350 }
351
352 /* Do we have both an active AIF and an active algorithm? */
353 ena = wm8994->mbc_ena[path] || wm8994->vss_ena[path] ||
354 wm8994->hpf1_ena[path] || wm8994->hpf2_ena[path] ||
355 wm8994->enh_eq_ena[path];
356 if (!pwr_reg)
357 ena = 0;
358
359 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
360
361 dev_dbg(codec->dev, "DSP path %d %d startup: %d, power: %x, DSP: %x\n",
362 path, wm8994->dsp_active, start, pwr_reg, reg);
363
364 if (start && ena) {
365 /* If the DSP is already running then noop */
366 if (reg & WM8958_DSP2_ENA)
367 return;
368
369 /* If either AIFnCLK is not yet enabled postpone */
370 if (!(snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
371 & WM8994_AIF1CLK_ENA_MASK) &&
372 !(snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
373 & WM8994_AIF2CLK_ENA_MASK))
374 return;
375
376 /* Switch the clock over to the appropriate AIF */
377 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
378 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
379 aif << WM8958_DSP2CLK_SRC_SHIFT |
380 WM8958_DSP2CLK_ENA);
381
382 if (wm8994->enh_eq_ena[path])
383 wm8958_dsp_start_enh_eq(codec, path);
384 else if (wm8994->vss_ena[path] || wm8994->hpf1_ena[path] ||
385 wm8994->hpf2_ena[path])
386 wm8958_dsp_start_vss(codec, path);
387 else if (wm8994->mbc_ena[path])
388 wm8958_dsp_start_mbc(codec, path);
389
390 wm8994->dsp_active = path;
391
392 dev_dbg(codec->dev, "DSP running in path %d\n", path);
393 }
394
395 if (!start && wm8994->dsp_active == path) {
396 /* If the DSP is already stopped then noop */
397 if (!(reg & WM8958_DSP2_ENA))
398 return;
399
400 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
401 WM8958_MBC_ENA, 0);
402 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
403 WM8958_DSP2_STOP);
404 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
405 WM8958_DSP2_ENA, 0);
406 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
407 WM8958_DSP2CLK_ENA, 0);
408
409 wm8994->dsp_active = -1;
410
411 dev_dbg(codec->dev, "DSP stopped\n");
412 }
413}
414
415int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
416 struct snd_kcontrol *kcontrol, int event)
417{
418 struct snd_soc_codec *codec = w->codec;
419 int i;
420
421 switch (event) {
422 case SND_SOC_DAPM_POST_PMU:
423 case SND_SOC_DAPM_PRE_PMU:
424 for (i = 0; i < 3; i++)
425 wm8958_dsp_apply(codec, i, 1);
426 break;
427 case SND_SOC_DAPM_POST_PMD:
428 case SND_SOC_DAPM_PRE_PMD:
429 for (i = 0; i < 3; i++)
430 wm8958_dsp_apply(codec, i, 0);
431 break;
432 }
433
434 return 0;
435}
436
437/* Check if DSP2 is in use on another AIF */
438static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif)
439{
440 int i;
441
442 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
443 if (i == aif)
444 continue;
445 if (wm8994->mbc_ena[i] || wm8994->vss_ena[i] ||
446 wm8994->hpf1_ena[i] || wm8994->hpf2_ena[i])
447 return 1;
448 }
449
450 return 0;
451}
452
453static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
455{
456 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
458 struct wm8994_pdata *pdata = wm8994->pdata;
459 int value = ucontrol->value.integer.value[0];
460 int reg;
461
462 /* Don't allow on the fly reconfiguration */
463 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
464 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
465 return -EBUSY;
466
467 if (value >= pdata->num_mbc_cfgs)
468 return -EINVAL;
469
470 wm8994->mbc_cfg = value;
471
472 return 0;
473}
474
475static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
479 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
480
481 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
482
483 return 0;
484}
485
486static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_info *uinfo)
488{
489 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
490 uinfo->count = 1;
491 uinfo->value.integer.min = 0;
492 uinfo->value.integer.max = 1;
493 return 0;
494}
495
496static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498{
499 int mbc = kcontrol->private_value;
500 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
502
503 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
504
505 return 0;
506}
507
508static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
509 struct snd_ctl_elem_value *ucontrol)
510{
511 int mbc = kcontrol->private_value;
512 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
513 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
514
515 if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0])
516 return 0;
517
518 if (ucontrol->value.integer.value[0] > 1)
519 return -EINVAL;
520
521 if (wm8958_dsp2_busy(wm8994, mbc)) {
522 dev_dbg(codec->dev, "DSP2 active on %d already\n", mbc);
523 return -EBUSY;
524 }
525
526 if (wm8994->enh_eq_ena[mbc])
527 return -EBUSY;
528
529 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
530
531 wm8958_dsp_apply(codec, mbc, wm8994->mbc_ena[mbc]);
532
533 return 0;
534}
535
536#define WM8958_MBC_SWITCH(xname, xval) {\
537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
538 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
539 .info = wm8958_mbc_info, \
540 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
541 .private_value = xval }
542
543static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
545{
546 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
548 struct wm8994_pdata *pdata = wm8994->pdata;
549 int value = ucontrol->value.integer.value[0];
550 int reg;
551
552 /* Don't allow on the fly reconfiguration */
553 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
554 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
555 return -EBUSY;
556
557 if (value >= pdata->num_vss_cfgs)
558 return -EINVAL;
559
560 wm8994->vss_cfg = value;
561
562 return 0;
563}
564
565static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol,
566 struct snd_ctl_elem_value *ucontrol)
567{
568 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
569 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
570
571 ucontrol->value.enumerated.item[0] = wm8994->vss_cfg;
572
573 return 0;
574}
575
576static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *ucontrol)
578{
579 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
580 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
581 struct wm8994_pdata *pdata = wm8994->pdata;
582 int value = ucontrol->value.integer.value[0];
583 int reg;
584
585 /* Don't allow on the fly reconfiguration */
586 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
587 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
588 return -EBUSY;
589
590 if (value >= pdata->num_vss_hpf_cfgs)
591 return -EINVAL;
592
593 wm8994->vss_hpf_cfg = value;
594
595 return 0;
596}
597
598static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol,
599 struct snd_ctl_elem_value *ucontrol)
600{
601 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
602 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
603
604 ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg;
605
606 return 0;
607}
608
609static int wm8958_vss_info(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_info *uinfo)
611{
612 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
613 uinfo->count = 1;
614 uinfo->value.integer.min = 0;
615 uinfo->value.integer.max = 1;
616 return 0;
617}
618
619static int wm8958_vss_get(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_value *ucontrol)
621{
622 int vss = kcontrol->private_value;
623 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
624 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
625
626 ucontrol->value.integer.value[0] = wm8994->vss_ena[vss];
627
628 return 0;
629}
630
631static int wm8958_vss_put(struct snd_kcontrol *kcontrol,
632 struct snd_ctl_elem_value *ucontrol)
633{
634 int vss = kcontrol->private_value;
635 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
637
638 if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0])
639 return 0;
640
641 if (ucontrol->value.integer.value[0] > 1)
642 return -EINVAL;
643
644 if (!wm8994->mbc_vss)
645 return -ENODEV;
646
647 if (wm8958_dsp2_busy(wm8994, vss)) {
648 dev_dbg(codec->dev, "DSP2 active on %d already\n", vss);
649 return -EBUSY;
650 }
651
652 if (wm8994->enh_eq_ena[vss])
653 return -EBUSY;
654
655 wm8994->vss_ena[vss] = ucontrol->value.integer.value[0];
656
657 wm8958_dsp_apply(codec, vss, wm8994->vss_ena[vss]);
658
659 return 0;
660}
661
662
663#define WM8958_VSS_SWITCH(xname, xval) {\
664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
665 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
666 .info = wm8958_vss_info, \
667 .get = wm8958_vss_get, .put = wm8958_vss_put, \
668 .private_value = xval }
669
670static int wm8958_hpf_info(struct snd_kcontrol *kcontrol,
671 struct snd_ctl_elem_info *uinfo)
672{
673 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
674 uinfo->count = 1;
675 uinfo->value.integer.min = 0;
676 uinfo->value.integer.max = 1;
677 return 0;
678}
679
680static int wm8958_hpf_get(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
682{
683 int hpf = kcontrol->private_value;
684 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
685 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
686
687 if (hpf < 3)
688 ucontrol->value.integer.value[0] = wm8994->hpf1_ena[hpf % 3];
689 else
690 ucontrol->value.integer.value[0] = wm8994->hpf2_ena[hpf % 3];
691
692 return 0;
693}
694
695static int wm8958_hpf_put(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_value *ucontrol)
697{
698 int hpf = kcontrol->private_value;
699 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
700 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
701
702 if (hpf < 3) {
703 if (wm8994->hpf1_ena[hpf % 3] ==
704 ucontrol->value.integer.value[0])
705 return 0;
706 } else {
707 if (wm8994->hpf2_ena[hpf % 3] ==
708 ucontrol->value.integer.value[0])
709 return 0;
710 }
711
712 if (ucontrol->value.integer.value[0] > 1)
713 return -EINVAL;
714
715 if (!wm8994->mbc_vss)
716 return -ENODEV;
717
718 if (wm8958_dsp2_busy(wm8994, hpf % 3)) {
719 dev_dbg(codec->dev, "DSP2 active on %d already\n", hpf);
720 return -EBUSY;
721 }
722
723 if (wm8994->enh_eq_ena[hpf % 3])
724 return -EBUSY;
725
726 if (hpf < 3)
727 wm8994->hpf1_ena[hpf % 3] = ucontrol->value.integer.value[0];
728 else
729 wm8994->hpf2_ena[hpf % 3] = ucontrol->value.integer.value[0];
730
731 wm8958_dsp_apply(codec, hpf % 3, ucontrol->value.integer.value[0]);
732
733 return 0;
734}
735
736#define WM8958_HPF_SWITCH(xname, xval) {\
737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
738 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
739 .info = wm8958_hpf_info, \
740 .get = wm8958_hpf_get, .put = wm8958_hpf_put, \
741 .private_value = xval }
742
743static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol,
744 struct snd_ctl_elem_value *ucontrol)
745{
746 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
748 struct wm8994_pdata *pdata = wm8994->pdata;
749 int value = ucontrol->value.integer.value[0];
750 int reg;
751
752 /* Don't allow on the fly reconfiguration */
753 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
754 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
755 return -EBUSY;
756
757 if (value >= pdata->num_enh_eq_cfgs)
758 return -EINVAL;
759
760 wm8994->enh_eq_cfg = value;
761
762 return 0;
763}
764
765static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
767{
768 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
769 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
770
771 ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg;
772
773 return 0;
774}
775
776static int wm8958_enh_eq_info(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_info *uinfo)
778{
779 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
780 uinfo->count = 1;
781 uinfo->value.integer.min = 0;
782 uinfo->value.integer.max = 1;
783 return 0;
784}
785
786static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
788{
789 int eq = kcontrol->private_value;
790 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
791 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
792
793 ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq];
794
795 return 0;
796}
797
798static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol,
799 struct snd_ctl_elem_value *ucontrol)
800{
801 int eq = kcontrol->private_value;
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
804
805 if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0])
806 return 0;
807
808 if (ucontrol->value.integer.value[0] > 1)
809 return -EINVAL;
810
811 if (!wm8994->enh_eq)
812 return -ENODEV;
813
814 if (wm8958_dsp2_busy(wm8994, eq)) {
815 dev_dbg(codec->dev, "DSP2 active on %d already\n", eq);
816 return -EBUSY;
817 }
818
819 if (wm8994->mbc_ena[eq] || wm8994->vss_ena[eq] ||
820 wm8994->hpf1_ena[eq] || wm8994->hpf2_ena[eq])
821 return -EBUSY;
822
823 wm8994->enh_eq_ena[eq] = ucontrol->value.integer.value[0];
824
825 wm8958_dsp_apply(codec, eq, ucontrol->value.integer.value[0]);
826
827 return 0;
828}
829
830#define WM8958_ENH_EQ_SWITCH(xname, xval) {\
831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
832 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
833 .info = wm8958_enh_eq_info, \
834 .get = wm8958_enh_eq_get, .put = wm8958_enh_eq_put, \
835 .private_value = xval }
836
837static const struct snd_kcontrol_new wm8958_mbc_snd_controls[] = {
838WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
839WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
840WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
841};
842
843static const struct snd_kcontrol_new wm8958_vss_snd_controls[] = {
844WM8958_VSS_SWITCH("AIF1DAC1 VSS Switch", 0),
845WM8958_VSS_SWITCH("AIF1DAC2 VSS Switch", 1),
846WM8958_VSS_SWITCH("AIF2DAC VSS Switch", 2),
847WM8958_HPF_SWITCH("AIF1DAC1 HPF1 Switch", 0),
848WM8958_HPF_SWITCH("AIF1DAC2 HPF1 Switch", 1),
849WM8958_HPF_SWITCH("AIF2DAC HPF1 Switch", 2),
850WM8958_HPF_SWITCH("AIF1DAC1 HPF2 Switch", 3),
851WM8958_HPF_SWITCH("AIF1DAC2 HPF2 Switch", 4),
852WM8958_HPF_SWITCH("AIF2DAC HPF2 Switch", 5),
853};
854
855static const struct snd_kcontrol_new wm8958_enh_eq_snd_controls[] = {
856WM8958_ENH_EQ_SWITCH("AIF1DAC1 Enhanced EQ Switch", 0),
857WM8958_ENH_EQ_SWITCH("AIF1DAC2 Enhanced EQ Switch", 1),
858WM8958_ENH_EQ_SWITCH("AIF2DAC Enhanced EQ Switch", 2),
859};
860
861static void wm8958_enh_eq_loaded(const struct firmware *fw, void *context)
862{
863 struct snd_soc_codec *codec = context;
864 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
865
866 if (fw && (wm8958_dsp2_fw(codec, "ENH_EQ", fw, true) == 0)) {
867 mutex_lock(&codec->mutex);
868 wm8994->enh_eq = fw;
869 mutex_unlock(&codec->mutex);
870 }
871}
872
873static void wm8958_mbc_vss_loaded(const struct firmware *fw, void *context)
874{
875 struct snd_soc_codec *codec = context;
876 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
877
878 if (fw && (wm8958_dsp2_fw(codec, "MBC+VSS", fw, true) == 0)) {
879 mutex_lock(&codec->mutex);
880 wm8994->mbc_vss = fw;
881 mutex_unlock(&codec->mutex);
882 }
883
884 /* We can't have more than one request outstanding at once so
885 * we daisy chain.
886 */
887 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
888 "wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
889 codec, wm8958_enh_eq_loaded);
890}
891
892static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
893{
894 struct snd_soc_codec *codec = context;
895 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
896
897 if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
898 return;
899
900 mutex_lock(&codec->mutex);
901 wm8994->mbc = fw;
902 mutex_unlock(&codec->mutex);
903
904 /* We can't have more than one request outstanding at once so
905 * we daisy chain.
906 */
907 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
908 "wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
909 codec, wm8958_mbc_vss_loaded);
910}
911
912void wm8958_dsp2_init(struct snd_soc_codec *codec)
913{
914 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
915 struct wm8994_pdata *pdata = wm8994->pdata;
916 int ret, i;
917
918 wm8994->dsp_active = -1;
919
920 snd_soc_add_controls(codec, wm8958_mbc_snd_controls,
921 ARRAY_SIZE(wm8958_mbc_snd_controls));
922 snd_soc_add_controls(codec, wm8958_vss_snd_controls,
923 ARRAY_SIZE(wm8958_vss_snd_controls));
924 snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls,
925 ARRAY_SIZE(wm8958_enh_eq_snd_controls));
926
927
928 /* We don't *require* firmware and don't want to delay boot */
929 request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
930 "wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
931 codec, wm8958_mbc_loaded);
932
933 if (!pdata)
934 return;
935
936 if (pdata->num_mbc_cfgs) {
937 struct snd_kcontrol_new control[] = {
938 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
939 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
940 };
941
942 /* We need an array of texts for the enum API */
943 wm8994->mbc_texts = kmalloc(sizeof(char *)
944 * pdata->num_mbc_cfgs, GFP_KERNEL);
945 if (!wm8994->mbc_texts) {
946 dev_err(wm8994->codec->dev,
947 "Failed to allocate %d MBC config texts\n",
948 pdata->num_mbc_cfgs);
949 return;
950 }
951
952 for (i = 0; i < pdata->num_mbc_cfgs; i++)
953 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
954
955 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
956 wm8994->mbc_enum.texts = wm8994->mbc_texts;
957
958 ret = snd_soc_add_controls(wm8994->codec, control, 1);
959 if (ret != 0)
960 dev_err(wm8994->codec->dev,
961 "Failed to add MBC mode controls: %d\n", ret);
962 }
963
964 if (pdata->num_vss_cfgs) {
965 struct snd_kcontrol_new control[] = {
966 SOC_ENUM_EXT("VSS Mode", wm8994->vss_enum,
967 wm8958_get_vss_enum, wm8958_put_vss_enum),
968 };
969
970 /* We need an array of texts for the enum API */
971 wm8994->vss_texts = kmalloc(sizeof(char *)
972 * pdata->num_vss_cfgs, GFP_KERNEL);
973 if (!wm8994->vss_texts) {
974 dev_err(wm8994->codec->dev,
975 "Failed to allocate %d VSS config texts\n",
976 pdata->num_vss_cfgs);
977 return;
978 }
979
980 for (i = 0; i < pdata->num_vss_cfgs; i++)
981 wm8994->vss_texts[i] = pdata->vss_cfgs[i].name;
982
983 wm8994->vss_enum.max = pdata->num_vss_cfgs;
984 wm8994->vss_enum.texts = wm8994->vss_texts;
985
986 ret = snd_soc_add_controls(wm8994->codec, control, 1);
987 if (ret != 0)
988 dev_err(wm8994->codec->dev,
989 "Failed to add VSS mode controls: %d\n", ret);
990 }
991
992 if (pdata->num_vss_hpf_cfgs) {
993 struct snd_kcontrol_new control[] = {
994 SOC_ENUM_EXT("VSS HPF Mode", wm8994->vss_hpf_enum,
995 wm8958_get_vss_hpf_enum,
996 wm8958_put_vss_hpf_enum),
997 };
998
999 /* We need an array of texts for the enum API */
1000 wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
1001 * pdata->num_vss_hpf_cfgs, GFP_KERNEL);
1002 if (!wm8994->vss_hpf_texts) {
1003 dev_err(wm8994->codec->dev,
1004 "Failed to allocate %d VSS HPF config texts\n",
1005 pdata->num_vss_hpf_cfgs);
1006 return;
1007 }
1008
1009 for (i = 0; i < pdata->num_vss_hpf_cfgs; i++)
1010 wm8994->vss_hpf_texts[i] = pdata->vss_hpf_cfgs[i].name;
1011
1012 wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
1013 wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
1014
1015 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1016 if (ret != 0)
1017 dev_err(wm8994->codec->dev,
1018 "Failed to add VSS HPFmode controls: %d\n",
1019 ret);
1020 }
1021
1022 if (pdata->num_enh_eq_cfgs) {
1023 struct snd_kcontrol_new control[] = {
1024 SOC_ENUM_EXT("Enhanced EQ Mode", wm8994->enh_eq_enum,
1025 wm8958_get_enh_eq_enum,
1026 wm8958_put_enh_eq_enum),
1027 };
1028
1029 /* We need an array of texts for the enum API */
1030 wm8994->enh_eq_texts = kmalloc(sizeof(char *)
1031 * pdata->num_enh_eq_cfgs, GFP_KERNEL);
1032 if (!wm8994->enh_eq_texts) {
1033 dev_err(wm8994->codec->dev,
1034 "Failed to allocate %d enhanced EQ config texts\n",
1035 pdata->num_enh_eq_cfgs);
1036 return;
1037 }
1038
1039 for (i = 0; i < pdata->num_enh_eq_cfgs; i++)
1040 wm8994->enh_eq_texts[i] = pdata->enh_eq_cfgs[i].name;
1041
1042 wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
1043 wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
1044
1045 ret = snd_soc_add_controls(wm8994->codec, control, 1);
1046 if (ret != 0)
1047 dev_err(wm8994->codec->dev,
1048 "Failed to add enhanced EQ controls: %d\n",
1049 ret);
1050 }
1051}
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 3c6ee61f6c95..4393394b7bc1 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -20,7 +20,6 @@
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/initval.h> 23#include <sound/initval.h>
25#include <sound/tlv.h> 24#include <sound/tlv.h>
26#include <sound/wm8960.h> 25#include <sound/wm8960.h>
@@ -29,8 +28,6 @@
29 28
30#define AUDIO_NAME "wm8960" 29#define AUDIO_NAME "wm8960"
31 30
32struct snd_soc_codec_device soc_codec_dev_wm8960;
33
34/* R25 - Power 1 */ 31/* R25 - Power 1 */
35#define WM8960_VMID_MASK 0x180 32#define WM8960_VMID_MASK 0x180
36#define WM8960_VREF 0x40 33#define WM8960_VREF 0x40
@@ -74,8 +71,10 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
74}; 71};
75 72
76struct wm8960_priv { 73struct wm8960_priv {
77 u16 reg_cache[WM8960_CACHEREGNUM]; 74 enum snd_soc_control_type control_type;
78 struct snd_soc_codec codec; 75 void *control_data;
76 int (*set_bias_level)(struct snd_soc_codec *,
77 enum snd_soc_bias_level level);
79 struct snd_soc_dapm_widget *lout1; 78 struct snd_soc_dapm_widget *lout1;
80 struct snd_soc_dapm_widget *rout1; 79 struct snd_soc_dapm_widget *rout1;
81 struct snd_soc_dapm_widget *out3; 80 struct snd_soc_dapm_widget *out3;
@@ -137,7 +136,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
137 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 136 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
138 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 137 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
139 138
140 return wm8960->deemph; 139 ucontrol->value.enumerated.item[0] = wm8960->deemph;
140 return 0;
141} 141}
142 142
143static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, 143static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
@@ -387,27 +387,28 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
387{ 387{
388 struct wm8960_data *pdata = codec->dev->platform_data; 388 struct wm8960_data *pdata = codec->dev->platform_data;
389 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 389 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
390 struct snd_soc_dapm_context *dapm = &codec->dapm;
390 struct snd_soc_dapm_widget *w; 391 struct snd_soc_dapm_widget *w;
391 392
392 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, 393 snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
393 ARRAY_SIZE(wm8960_dapm_widgets)); 394 ARRAY_SIZE(wm8960_dapm_widgets));
394 395
395 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 396 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
396 397
397 /* In capless mode OUT3 is used to provide VMID for the 398 /* In capless mode OUT3 is used to provide VMID for the
398 * headphone outputs, otherwise it is used as a mono mixer. 399 * headphone outputs, otherwise it is used as a mono mixer.
399 */ 400 */
400 if (pdata && pdata->capless) { 401 if (pdata && pdata->capless) {
401 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless, 402 snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
402 ARRAY_SIZE(wm8960_dapm_widgets_capless)); 403 ARRAY_SIZE(wm8960_dapm_widgets_capless));
403 404
404 snd_soc_dapm_add_routes(codec, audio_paths_capless, 405 snd_soc_dapm_add_routes(dapm, audio_paths_capless,
405 ARRAY_SIZE(audio_paths_capless)); 406 ARRAY_SIZE(audio_paths_capless));
406 } else { 407 } else {
407 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3, 408 snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
408 ARRAY_SIZE(wm8960_dapm_widgets_out3)); 409 ARRAY_SIZE(wm8960_dapm_widgets_out3));
409 410
410 snd_soc_dapm_add_routes(codec, audio_paths_out3, 411 snd_soc_dapm_add_routes(dapm, audio_paths_out3,
411 ARRAY_SIZE(audio_paths_out3)); 412 ARRAY_SIZE(audio_paths_out3));
412 } 413 }
413 414
@@ -416,7 +417,9 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
416 * list each time to find the desired power state do so now 417 * list each time to find the desired power state do so now
417 * and save the result. 418 * and save the result.
418 */ 419 */
419 list_for_each_entry(w, &codec->dapm_widgets, list) { 420 list_for_each_entry(w, &codec->card->widgets, list) {
421 if (w->dapm != &codec->dapm)
422 continue;
420 if (strcmp(w->name, "LOUT1 PGA") == 0) 423 if (strcmp(w->name, "LOUT1 PGA") == 0)
421 wm8960->lout1 = w; 424 wm8960->lout1 = w;
422 if (strcmp(w->name, "ROUT1 PGA") == 0) 425 if (strcmp(w->name, "ROUT1 PGA") == 0)
@@ -507,8 +510,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
507 struct snd_soc_dai *dai) 510 struct snd_soc_dai *dai)
508{ 511{
509 struct snd_soc_pcm_runtime *rtd = substream->private_data; 512 struct snd_soc_pcm_runtime *rtd = substream->private_data;
510 struct snd_soc_device *socdev = rtd->socdev; 513 struct snd_soc_codec *codec = rtd->codec;
511 struct snd_soc_codec *codec = socdev->card->codec;
512 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 514 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
513 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; 515 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
514 int i; 516 int i;
@@ -572,7 +574,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
572 break; 574 break;
573 575
574 case SND_SOC_BIAS_STANDBY: 576 case SND_SOC_BIAS_STANDBY:
575 if (codec->bias_level == SND_SOC_BIAS_OFF) { 577 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
576 /* Enable anti-pop features */ 578 /* Enable anti-pop features */
577 snd_soc_write(codec, WM8960_APOP1, 579 snd_soc_write(codec, WM8960_APOP1,
578 WM8960_POBCTRL | WM8960_SOFT_ST | 580 WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -610,7 +612,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
610 break; 612 break;
611 } 613 }
612 614
613 codec->bias_level = level; 615 codec->dapm.bias_level = level;
614 616
615 return 0; 617 return 0;
616} 618}
@@ -626,7 +628,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
626 break; 628 break;
627 629
628 case SND_SOC_BIAS_PREPARE: 630 case SND_SOC_BIAS_PREPARE:
629 switch (codec->bias_level) { 631 switch (codec->dapm.bias_level) {
630 case SND_SOC_BIAS_STANDBY: 632 case SND_SOC_BIAS_STANDBY:
631 /* Enable anti pop mode */ 633 /* Enable anti pop mode */
632 snd_soc_update_bits(codec, WM8960_APOP1, 634 snd_soc_update_bits(codec, WM8960_APOP1,
@@ -681,7 +683,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
681 break; 683 break;
682 684
683 case SND_SOC_BIAS_STANDBY: 685 case SND_SOC_BIAS_STANDBY:
684 switch (codec->bias_level) { 686 switch (codec->dapm.bias_level) {
685 case SND_SOC_BIAS_PREPARE: 687 case SND_SOC_BIAS_PREPARE:
686 /* Disable HP discharge */ 688 /* Disable HP discharge */
687 snd_soc_update_bits(codec, WM8960_APOP2, 689 snd_soc_update_bits(codec, WM8960_APOP2,
@@ -705,7 +707,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
705 break; 707 break;
706 } 708 }
707 709
708 codec->bias_level = level; 710 codec->dapm.bias_level = level;
709 711
710 return 0; 712 return 0;
711} 713}
@@ -849,6 +851,14 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
849 return 0; 851 return 0;
850} 852}
851 853
854static int wm8960_set_bias_level(struct snd_soc_codec *codec,
855 enum snd_soc_bias_level level)
856{
857 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
858
859 return wm8960->set_bias_level(codec, level);
860}
861
852#define WM8960_RATES SNDRV_PCM_RATE_8000_48000 862#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
853 863
854#define WM8960_FORMATS \ 864#define WM8960_FORMATS \
@@ -863,8 +873,8 @@ static struct snd_soc_dai_ops wm8960_dai_ops = {
863 .set_pll = wm8960_set_dai_pll, 873 .set_pll = wm8960_set_dai_pll,
864}; 874};
865 875
866struct snd_soc_dai wm8960_dai = { 876static struct snd_soc_dai_driver wm8960_dai = {
867 .name = "WM8960", 877 .name = "wm8960-hifi",
868 .playback = { 878 .playback = {
869 .stream_name = "Playback", 879 .stream_name = "Playback",
870 .channels_min = 1, 880 .channels_min = 1,
@@ -880,21 +890,18 @@ struct snd_soc_dai wm8960_dai = {
880 .ops = &wm8960_dai_ops, 890 .ops = &wm8960_dai_ops,
881 .symmetric_rates = 1, 891 .symmetric_rates = 1,
882}; 892};
883EXPORT_SYMBOL_GPL(wm8960_dai);
884 893
885static int wm8960_suspend(struct platform_device *pdev, pm_message_t state) 894static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state)
886{ 895{
887 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 896 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
888 struct snd_soc_codec *codec = socdev->card->codec;
889 897
890 codec->set_bias_level(codec, SND_SOC_BIAS_OFF); 898 wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
891 return 0; 899 return 0;
892} 900}
893 901
894static int wm8960_resume(struct platform_device *pdev) 902static int wm8960_resume(struct snd_soc_codec *codec)
895{ 903{
896 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 904 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
897 struct snd_soc_codec *codec = socdev->card->codec;
898 int i; 905 int i;
899 u8 data[2]; 906 u8 data[2];
900 u16 *cache = codec->reg_cache; 907 u16 *cache = codec->reg_cache;
@@ -906,78 +913,19 @@ static int wm8960_resume(struct platform_device *pdev)
906 codec->hw_write(codec->control_data, data, 2); 913 codec->hw_write(codec->control_data, data, 2);
907 } 914 }
908 915
909 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY); 916 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
910
911 return 0; 917 return 0;
912} 918}
913 919
914static struct snd_soc_codec *wm8960_codec; 920static int wm8960_probe(struct snd_soc_codec *codec)
915
916static int wm8960_probe(struct platform_device *pdev)
917{
918 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
919 struct snd_soc_codec *codec;
920 int ret = 0;
921
922 if (wm8960_codec == NULL) {
923 dev_err(&pdev->dev, "Codec device not registered\n");
924 return -ENODEV;
925 }
926
927 socdev->card->codec = wm8960_codec;
928 codec = wm8960_codec;
929
930 /* register pcms */
931 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
932 if (ret < 0) {
933 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
934 goto pcm_err;
935 }
936
937 snd_soc_add_controls(codec, wm8960_snd_controls,
938 ARRAY_SIZE(wm8960_snd_controls));
939 wm8960_add_widgets(codec);
940
941 return ret;
942
943pcm_err:
944 return ret;
945}
946
947/* power down chip */
948static int wm8960_remove(struct platform_device *pdev)
949{ 921{
950 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 922 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
951 923 struct wm8960_data *pdata = dev_get_platdata(codec->dev);
952 snd_soc_free_pcms(socdev);
953 snd_soc_dapm_free(socdev);
954
955 return 0;
956}
957
958struct snd_soc_codec_device soc_codec_dev_wm8960 = {
959 .probe = wm8960_probe,
960 .remove = wm8960_remove,
961 .suspend = wm8960_suspend,
962 .resume = wm8960_resume,
963};
964EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
965
966static int wm8960_register(struct wm8960_priv *wm8960,
967 enum snd_soc_control_type control)
968{
969 struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
970 struct snd_soc_codec *codec = &wm8960->codec;
971 int ret; 924 int ret;
972 u16 reg; 925 u16 reg;
973 926
974 if (wm8960_codec) { 927 wm8960->set_bias_level = wm8960_set_bias_level_out3;
975 dev_err(codec->dev, "Another WM8960 is registered\n"); 928 codec->control_data = wm8960->control_data;
976 ret = -EINVAL;
977 goto err;
978 }
979
980 codec->set_bias_level = wm8960_set_bias_level_out3;
981 929
982 if (!pdata) { 930 if (!pdata) {
983 dev_warn(codec->dev, "No platform data supplied\n"); 931 dev_warn(codec->dev, "No platform data supplied\n");
@@ -988,39 +936,22 @@ static int wm8960_register(struct wm8960_priv *wm8960,
988 } 936 }
989 937
990 if (pdata->capless) 938 if (pdata->capless)
991 codec->set_bias_level = wm8960_set_bias_level_capless; 939 wm8960->set_bias_level = wm8960_set_bias_level_capless;
992 } 940 }
993 941
994 mutex_init(&codec->mutex); 942 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type);
995 INIT_LIST_HEAD(&codec->dapm_widgets);
996 INIT_LIST_HEAD(&codec->dapm_paths);
997
998 snd_soc_codec_set_drvdata(codec, wm8960);
999 codec->name = "WM8960";
1000 codec->owner = THIS_MODULE;
1001 codec->bias_level = SND_SOC_BIAS_OFF;
1002 codec->dai = &wm8960_dai;
1003 codec->num_dai = 1;
1004 codec->reg_cache_size = WM8960_CACHEREGNUM;
1005 codec->reg_cache = &wm8960->reg_cache;
1006
1007 memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
1008
1009 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
1010 if (ret < 0) { 943 if (ret < 0) {
1011 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 944 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1012 goto err; 945 return ret;
1013 } 946 }
1014 947
1015 ret = wm8960_reset(codec); 948 ret = wm8960_reset(codec);
1016 if (ret < 0) { 949 if (ret < 0) {
1017 dev_err(codec->dev, "Failed to issue reset\n"); 950 dev_err(codec->dev, "Failed to issue reset\n");
1018 goto err; 951 return ret;
1019 } 952 }
1020 953
1021 wm8960_dai.dev = codec->dev; 954 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1022
1023 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1024 955
1025 /* Latch the update bits */ 956 /* Latch the update bits */
1026 reg = snd_soc_read(codec, WM8960_LINVOL); 957 reg = snd_soc_read(codec, WM8960_LINVOL);
@@ -1044,62 +975,59 @@ static int wm8960_register(struct wm8960_priv *wm8960,
1044 reg = snd_soc_read(codec, WM8960_ROUT2); 975 reg = snd_soc_read(codec, WM8960_ROUT2);
1045 snd_soc_write(codec, WM8960_ROUT2, reg | 0x100); 976 snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
1046 977
1047 wm8960_codec = codec; 978 snd_soc_add_controls(codec, wm8960_snd_controls,
1048 979 ARRAY_SIZE(wm8960_snd_controls));
1049 ret = snd_soc_register_codec(codec); 980 wm8960_add_widgets(codec);
1050 if (ret != 0) {
1051 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1052 goto err;
1053 }
1054
1055 ret = snd_soc_register_dai(&wm8960_dai);
1056 if (ret != 0) {
1057 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1058 goto err_codec;
1059 }
1060 981
1061 return 0; 982 return 0;
1062
1063err_codec:
1064 snd_soc_unregister_codec(codec);
1065err:
1066 kfree(wm8960);
1067 return ret;
1068} 983}
1069 984
1070static void wm8960_unregister(struct wm8960_priv *wm8960) 985/* power down chip */
986static int wm8960_remove(struct snd_soc_codec *codec)
1071{ 987{
1072 wm8960->codec.set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF); 988 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
1073 snd_soc_unregister_dai(&wm8960_dai); 989
1074 snd_soc_unregister_codec(&wm8960->codec); 990 wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
1075 kfree(wm8960); 991 return 0;
1076 wm8960_codec = NULL;
1077} 992}
1078 993
994static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
995 .probe = wm8960_probe,
996 .remove = wm8960_remove,
997 .suspend = wm8960_suspend,
998 .resume = wm8960_resume,
999 .set_bias_level = wm8960_set_bias_level,
1000 .reg_cache_size = ARRAY_SIZE(wm8960_reg),
1001 .reg_word_size = sizeof(u16),
1002 .reg_cache_default = wm8960_reg,
1003};
1004
1005#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1079static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, 1006static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
1080 const struct i2c_device_id *id) 1007 const struct i2c_device_id *id)
1081{ 1008{
1082 struct wm8960_priv *wm8960; 1009 struct wm8960_priv *wm8960;
1083 struct snd_soc_codec *codec; 1010 int ret;
1084 1011
1085 wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL); 1012 wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
1086 if (wm8960 == NULL) 1013 if (wm8960 == NULL)
1087 return -ENOMEM; 1014 return -ENOMEM;
1088 1015
1089 codec = &wm8960->codec;
1090
1091 i2c_set_clientdata(i2c, wm8960); 1016 i2c_set_clientdata(i2c, wm8960);
1092 codec->control_data = i2c; 1017 wm8960->control_type = SND_SOC_I2C;
1093 1018 wm8960->control_data = i2c;
1094 codec->dev = &i2c->dev;
1095 1019
1096 return wm8960_register(wm8960, SND_SOC_I2C); 1020 ret = snd_soc_register_codec(&i2c->dev,
1021 &soc_codec_dev_wm8960, &wm8960_dai, 1);
1022 if (ret < 0)
1023 kfree(wm8960);
1024 return ret;
1097} 1025}
1098 1026
1099static __devexit int wm8960_i2c_remove(struct i2c_client *client) 1027static __devexit int wm8960_i2c_remove(struct i2c_client *client)
1100{ 1028{
1101 struct wm8960_priv *wm8960 = i2c_get_clientdata(client); 1029 snd_soc_unregister_codec(&client->dev);
1102 wm8960_unregister(wm8960); 1030 kfree(i2c_get_clientdata(client));
1103 return 0; 1031 return 0;
1104} 1032}
1105 1033
@@ -1111,35 +1039,37 @@ MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
1111 1039
1112static struct i2c_driver wm8960_i2c_driver = { 1040static struct i2c_driver wm8960_i2c_driver = {
1113 .driver = { 1041 .driver = {
1114 .name = "wm8960", 1042 .name = "wm8960-codec",
1115 .owner = THIS_MODULE, 1043 .owner = THIS_MODULE,
1116 }, 1044 },
1117 .probe = wm8960_i2c_probe, 1045 .probe = wm8960_i2c_probe,
1118 .remove = __devexit_p(wm8960_i2c_remove), 1046 .remove = __devexit_p(wm8960_i2c_remove),
1119 .id_table = wm8960_i2c_id, 1047 .id_table = wm8960_i2c_id,
1120}; 1048};
1049#endif
1121 1050
1122static int __init wm8960_modinit(void) 1051static int __init wm8960_modinit(void)
1123{ 1052{
1124 int ret; 1053 int ret = 0;
1125 1054#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1126 ret = i2c_add_driver(&wm8960_i2c_driver); 1055 ret = i2c_add_driver(&wm8960_i2c_driver);
1127 if (ret != 0) { 1056 if (ret != 0) {
1128 printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", 1057 printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
1129 ret); 1058 ret);
1130 } 1059 }
1131 1060#endif
1132 return ret; 1061 return ret;
1133} 1062}
1134module_init(wm8960_modinit); 1063module_init(wm8960_modinit);
1135 1064
1136static void __exit wm8960_exit(void) 1065static void __exit wm8960_exit(void)
1137{ 1066{
1067#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1138 i2c_del_driver(&wm8960_i2c_driver); 1068 i2c_del_driver(&wm8960_i2c_driver);
1069#endif
1139} 1070}
1140module_exit(wm8960_exit); 1071module_exit(wm8960_exit);
1141 1072
1142
1143MODULE_DESCRIPTION("ASoC WM8960 driver"); 1073MODULE_DESCRIPTION("ASoC WM8960 driver");
1144MODULE_AUTHOR("Liam Girdwood"); 1074MODULE_AUTHOR("Liam Girdwood");
1145MODULE_LICENSE("GPL"); 1075MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
index a5ef65481b86..2d8163d7004b 100644
--- a/sound/soc/codecs/wm8960.h
+++ b/sound/soc/codecs/wm8960.h
@@ -110,7 +110,4 @@
110#define WM8960_OPCLK_DIV_5_5 (4 << 0) 110#define WM8960_OPCLK_DIV_5_5 (4 << 0)
111#define WM8960_OPCLK_DIV_6 (5 << 0) 111#define WM8960_OPCLK_DIV_6 (5 << 0)
112 112
113extern struct snd_soc_dai wm8960_dai;
114extern struct snd_soc_codec_device soc_codec_dev_wm8960;
115
116#endif 113#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 2549d3a297ab..cdee8103d09b 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -288,12 +287,11 @@ static u16 wm8961_reg_defaults[] = {
288}; 287};
289 288
290struct wm8961_priv { 289struct wm8961_priv {
291 struct snd_soc_codec codec; 290 enum snd_soc_control_type control_type;
292 int sysclk; 291 int sysclk;
293 u16 reg_cache[WM8961_MAX_REGISTER];
294}; 292};
295 293
296static int wm8961_volatile_register(unsigned int reg) 294static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
297{ 295{
298 switch (reg) { 296 switch (reg) {
299 case WM8961_SOFTWARE_RESET: 297 case WM8961_SOFTWARE_RESET:
@@ -711,7 +709,7 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
711 if (fs <= 24000) 709 if (fs <= 24000)
712 reg |= WM8961_DACSLOPE; 710 reg |= WM8961_DACSLOPE;
713 else 711 else
714 reg &= WM8961_DACSLOPE; 712 reg &= ~WM8961_DACSLOPE;
715 snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg); 713 snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
716 714
717 return 0; 715 return 0;
@@ -736,7 +734,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
736 freq /= 2; 734 freq /= 2;
737 } else { 735 } else {
738 dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq); 736 dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
739 reg &= WM8961_MCLKDIV; 737 reg &= ~WM8961_MCLKDIV;
740 } 738 }
741 739
742 snd_soc_write(codec, WM8961_CLOCKING1, reg); 740 snd_soc_write(codec, WM8961_CLOCKING1, reg);
@@ -882,7 +880,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
882 break; 880 break;
883 881
884 case SND_SOC_BIAS_PREPARE: 882 case SND_SOC_BIAS_PREPARE:
885 if (codec->bias_level == SND_SOC_BIAS_STANDBY) { 883 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
886 /* Enable bias generation */ 884 /* Enable bias generation */
887 reg = snd_soc_read(codec, WM8961_ANTI_POP); 885 reg = snd_soc_read(codec, WM8961_ANTI_POP);
888 reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; 886 reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
@@ -897,7 +895,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
897 break; 895 break;
898 896
899 case SND_SOC_BIAS_STANDBY: 897 case SND_SOC_BIAS_STANDBY:
900 if (codec->bias_level == SND_SOC_BIAS_PREPARE) { 898 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
901 /* VREF off */ 899 /* VREF off */
902 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); 900 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
903 reg &= ~WM8961_VREF; 901 reg &= ~WM8961_VREF;
@@ -919,7 +917,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
919 break; 917 break;
920 } 918 }
921 919
922 codec->bias_level = level; 920 codec->dapm.bias_level = level;
923 921
924 return 0; 922 return 0;
925} 923}
@@ -940,8 +938,8 @@ static struct snd_soc_dai_ops wm8961_dai_ops = {
940 .set_clkdiv = wm8961_set_clkdiv, 938 .set_clkdiv = wm8961_set_clkdiv,
941}; 939};
942 940
943struct snd_soc_dai wm8961_dai = { 941static struct snd_soc_dai_driver wm8961_dai = {
944 .name = "WM8961", 942 .name = "wm8961-hifi",
945 .playback = { 943 .playback = {
946 .stream_name = "HiFi Playback", 944 .stream_name = "HiFi Playback",
947 .channels_min = 1, 945 .channels_min = 1,
@@ -956,140 +954,23 @@ struct snd_soc_dai wm8961_dai = {
956 .formats = WM8961_FORMATS,}, 954 .formats = WM8961_FORMATS,},
957 .ops = &wm8961_dai_ops, 955 .ops = &wm8961_dai_ops,
958}; 956};
959EXPORT_SYMBOL_GPL(wm8961_dai);
960 957
961 958static int wm8961_probe(struct snd_soc_codec *codec)
962static struct snd_soc_codec *wm8961_codec;
963
964static int wm8961_probe(struct platform_device *pdev)
965{ 959{
966 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 960 struct snd_soc_dapm_context *dapm = &codec->dapm;
967 struct snd_soc_codec *codec;
968 int ret = 0; 961 int ret = 0;
969
970 if (wm8961_codec == NULL) {
971 dev_err(&pdev->dev, "Codec device not registered\n");
972 return -ENODEV;
973 }
974
975 socdev->card->codec = wm8961_codec;
976 codec = wm8961_codec;
977
978 /* register pcms */
979 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
980 if (ret < 0) {
981 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
982 goto pcm_err;
983 }
984
985 snd_soc_add_controls(codec, wm8961_snd_controls,
986 ARRAY_SIZE(wm8961_snd_controls));
987 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
988 ARRAY_SIZE(wm8961_dapm_widgets));
989 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
990
991 return ret;
992
993pcm_err:
994 return ret;
995}
996
997static int wm8961_remove(struct platform_device *pdev)
998{
999 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1000
1001 snd_soc_free_pcms(socdev);
1002 snd_soc_dapm_free(socdev);
1003
1004 return 0;
1005}
1006
1007#ifdef CONFIG_PM
1008static int wm8961_suspend(struct platform_device *pdev, pm_message_t state)
1009{
1010 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1011 struct snd_soc_codec *codec = socdev->card->codec;
1012
1013 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1014
1015 return 0;
1016}
1017
1018static int wm8961_resume(struct platform_device *pdev)
1019{
1020 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1021 struct snd_soc_codec *codec = socdev->card->codec;
1022 u16 *reg_cache = codec->reg_cache;
1023 int i;
1024
1025 for (i = 0; i < codec->reg_cache_size; i++) {
1026 if (reg_cache[i] == wm8961_reg_defaults[i])
1027 continue;
1028
1029 if (i == WM8961_SOFTWARE_RESET)
1030 continue;
1031
1032 snd_soc_write(codec, i, reg_cache[i]);
1033 }
1034
1035 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1036
1037 return 0;
1038}
1039#else
1040#define wm8961_suspend NULL
1041#define wm8961_resume NULL
1042#endif
1043
1044struct snd_soc_codec_device soc_codec_dev_wm8961 = {
1045 .probe = wm8961_probe,
1046 .remove = wm8961_remove,
1047 .suspend = wm8961_suspend,
1048 .resume = wm8961_resume,
1049};
1050EXPORT_SYMBOL_GPL(soc_codec_dev_wm8961);
1051
1052static int wm8961_register(struct wm8961_priv *wm8961)
1053{
1054 struct snd_soc_codec *codec = &wm8961->codec;
1055 int ret;
1056 u16 reg; 962 u16 reg;
1057 963
1058 if (wm8961_codec) {
1059 dev_err(codec->dev, "Another WM8961 is registered\n");
1060 ret = -EINVAL;
1061 goto err;
1062 }
1063
1064 mutex_init(&codec->mutex);
1065 INIT_LIST_HEAD(&codec->dapm_widgets);
1066 INIT_LIST_HEAD(&codec->dapm_paths);
1067
1068 snd_soc_codec_set_drvdata(codec, wm8961);
1069 codec->name = "WM8961";
1070 codec->owner = THIS_MODULE;
1071 codec->dai = &wm8961_dai;
1072 codec->num_dai = 1;
1073 codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
1074 codec->reg_cache = &wm8961->reg_cache;
1075 codec->bias_level = SND_SOC_BIAS_OFF;
1076 codec->set_bias_level = wm8961_set_bias_level;
1077 codec->volatile_register = wm8961_volatile_register;
1078
1079 memcpy(codec->reg_cache, wm8961_reg_defaults,
1080 sizeof(wm8961_reg_defaults));
1081
1082 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 964 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1083 if (ret != 0) { 965 if (ret != 0) {
1084 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 966 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1085 goto err; 967 return ret;
1086 } 968 }
1087 969
1088 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET); 970 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
1089 if (reg != 0x1801) { 971 if (reg != 0x1801) {
1090 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg); 972 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
1091 ret = -EINVAL; 973 return -EINVAL;
1092 goto err;
1093 } 974 }
1094 975
1095 /* This isn't volatile - readback doesn't correspond to write */ 976 /* This isn't volatile - readback doesn't correspond to write */
@@ -1102,7 +983,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1102 ret = wm8961_reset(codec); 983 ret = wm8961_reset(codec);
1103 if (ret < 0) { 984 if (ret < 0) {
1104 dev_err(codec->dev, "Failed to issue reset\n"); 985 dev_err(codec->dev, "Failed to issue reset\n");
1105 goto err; 986 return ret;
1106 } 987 }
1107 988
1108 /* Enable class W */ 989 /* Enable class W */
@@ -1140,64 +1021,89 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1140 1021
1141 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1022 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1142 1023
1143 wm8961_dai.dev = codec->dev; 1024 snd_soc_add_controls(codec, wm8961_snd_controls,
1025 ARRAY_SIZE(wm8961_snd_controls));
1026 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
1027 ARRAY_SIZE(wm8961_dapm_widgets));
1028 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1144 1029
1145 wm8961_codec = codec; 1030 return 0;
1031}
1146 1032
1147 ret = snd_soc_register_codec(codec); 1033static int wm8961_remove(struct snd_soc_codec *codec)
1148 if (ret != 0) { 1034{
1149 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1035 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1150 goto err; 1036 return 0;
1151 } 1037}
1152 1038
1153 ret = snd_soc_register_dai(&wm8961_dai); 1039#ifdef CONFIG_PM
1154 if (ret != 0) { 1040static int wm8961_suspend(struct snd_soc_codec *codec, pm_message_t state)
1155 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 1041{
1156 goto err_codec; 1042 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1157 }
1158 1043
1159 return 0; 1044 return 0;
1160
1161err_codec:
1162 snd_soc_unregister_codec(codec);
1163err:
1164 kfree(wm8961);
1165 return ret;
1166} 1045}
1167 1046
1168static void wm8961_unregister(struct wm8961_priv *wm8961) 1047static int wm8961_resume(struct snd_soc_codec *codec)
1169{ 1048{
1170 wm8961_set_bias_level(&wm8961->codec, SND_SOC_BIAS_OFF); 1049 u16 *reg_cache = codec->reg_cache;
1171 snd_soc_unregister_dai(&wm8961_dai); 1050 int i;
1172 snd_soc_unregister_codec(&wm8961->codec); 1051
1173 kfree(wm8961); 1052 for (i = 0; i < codec->driver->reg_cache_size; i++) {
1174 wm8961_codec = NULL; 1053 if (reg_cache[i] == wm8961_reg_defaults[i])
1054 continue;
1055
1056 if (i == WM8961_SOFTWARE_RESET)
1057 continue;
1058
1059 snd_soc_write(codec, i, reg_cache[i]);
1060 }
1061
1062 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1063
1064 return 0;
1175} 1065}
1066#else
1067#define wm8961_suspend NULL
1068#define wm8961_resume NULL
1069#endif
1176 1070
1071static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
1072 .probe = wm8961_probe,
1073 .remove = wm8961_remove,
1074 .suspend = wm8961_suspend,
1075 .resume = wm8961_resume,
1076 .set_bias_level = wm8961_set_bias_level,
1077 .reg_cache_size = ARRAY_SIZE(wm8961_reg_defaults),
1078 .reg_word_size = sizeof(u16),
1079 .reg_cache_default = wm8961_reg_defaults,
1080 .volatile_register = wm8961_volatile_register,
1081};
1082
1083#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1177static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, 1084static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
1178 const struct i2c_device_id *id) 1085 const struct i2c_device_id *id)
1179{ 1086{
1180 struct wm8961_priv *wm8961; 1087 struct wm8961_priv *wm8961;
1181 struct snd_soc_codec *codec; 1088 int ret;
1182 1089
1183 wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL); 1090 wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL);
1184 if (wm8961 == NULL) 1091 if (wm8961 == NULL)
1185 return -ENOMEM; 1092 return -ENOMEM;
1186 1093
1187 codec = &wm8961->codec;
1188
1189 i2c_set_clientdata(i2c, wm8961); 1094 i2c_set_clientdata(i2c, wm8961);
1190 codec->control_data = i2c;
1191 1095
1192 codec->dev = &i2c->dev; 1096 ret = snd_soc_register_codec(&i2c->dev,
1193 1097 &soc_codec_dev_wm8961, &wm8961_dai, 1);
1194 return wm8961_register(wm8961); 1098 if (ret < 0)
1099 kfree(wm8961);
1100 return ret;
1195} 1101}
1196 1102
1197static __devexit int wm8961_i2c_remove(struct i2c_client *client) 1103static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1198{ 1104{
1199 struct wm8961_priv *wm8961 = i2c_get_clientdata(client); 1105 snd_soc_unregister_codec(&client->dev);
1200 wm8961_unregister(wm8961); 1106 kfree(i2c_get_clientdata(client));
1201 return 0; 1107 return 0;
1202} 1108}
1203 1109
@@ -1209,35 +1115,37 @@ MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id);
1209 1115
1210static struct i2c_driver wm8961_i2c_driver = { 1116static struct i2c_driver wm8961_i2c_driver = {
1211 .driver = { 1117 .driver = {
1212 .name = "wm8961", 1118 .name = "wm8961-codec",
1213 .owner = THIS_MODULE, 1119 .owner = THIS_MODULE,
1214 }, 1120 },
1215 .probe = wm8961_i2c_probe, 1121 .probe = wm8961_i2c_probe,
1216 .remove = __devexit_p(wm8961_i2c_remove), 1122 .remove = __devexit_p(wm8961_i2c_remove),
1217 .id_table = wm8961_i2c_id, 1123 .id_table = wm8961_i2c_id,
1218}; 1124};
1125#endif
1219 1126
1220static int __init wm8961_modinit(void) 1127static int __init wm8961_modinit(void)
1221{ 1128{
1222 int ret; 1129 int ret = 0;
1223 1130#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1224 ret = i2c_add_driver(&wm8961_i2c_driver); 1131 ret = i2c_add_driver(&wm8961_i2c_driver);
1225 if (ret != 0) { 1132 if (ret != 0) {
1226 printk(KERN_ERR "Failed to register WM8961 I2C driver: %d\n", 1133 printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
1227 ret); 1134 ret);
1228 } 1135 }
1229 1136#endif
1230 return ret; 1137 return ret;
1231} 1138}
1232module_init(wm8961_modinit); 1139module_init(wm8961_modinit);
1233 1140
1234static void __exit wm8961_exit(void) 1141static void __exit wm8961_exit(void)
1235{ 1142{
1143#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1236 i2c_del_driver(&wm8961_i2c_driver); 1144 i2c_del_driver(&wm8961_i2c_driver);
1145#endif
1237} 1146}
1238module_exit(wm8961_exit); 1147module_exit(wm8961_exit);
1239 1148
1240
1241MODULE_DESCRIPTION("ASoC WM8961 driver"); 1149MODULE_DESCRIPTION("ASoC WM8961 driver");
1242MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1150MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1243MODULE_LICENSE("GPL"); 1151MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8961.h b/sound/soc/codecs/wm8961.h
index 5513bfd720d6..1d736e5701c8 100644
--- a/sound/soc/codecs/wm8961.h
+++ b/sound/soc/codecs/wm8961.h
@@ -11,9 +11,6 @@
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13 13
14extern struct snd_soc_codec_device soc_codec_dev_wm8961;
15extern struct snd_soc_dai wm8961_dai;
16
17#define WM8961_BCLK 1 14#define WM8961_BCLK 1
18#define WM8961_LRCLK 2 15#define WM8961_LRCLK 2
19 16
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
new file mode 100644
index 000000000000..5e05eed96c38
--- /dev/null
+++ b/sound/soc/codecs/wm8962.c
@@ -0,0 +1,4045 @@
1/*
2 * wm8962.c -- WM8962 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
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
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/gcd.h>
20#include <linux/gpio.h>
21#include <linux/i2c.h>
22#include <linux/input.h>
23#include <linux/platform_device.h>
24#include <linux/regulator/consumer.h>
25#include <linux/slab.h>
26#include <linux/workqueue.h>
27#include <sound/core.h>
28#include <sound/jack.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/initval.h>
33#include <sound/tlv.h>
34#include <sound/wm8962.h>
35#include <trace/events/asoc.h>
36
37#include "wm8962.h"
38
39#define WM8962_NUM_SUPPLIES 8
40static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
41 "DCVDD",
42 "DBVDD",
43 "AVDD",
44 "CPVDD",
45 "MICVDD",
46 "PLLVDD",
47 "SPKVDD1",
48 "SPKVDD2",
49};
50
51/* codec private data */
52struct wm8962_priv {
53 struct snd_soc_codec *codec;
54
55 int sysclk;
56 int sysclk_rate;
57
58 int bclk; /* Desired BCLK */
59 int lrclk;
60
61 struct completion fll_lock;
62 int fll_src;
63 int fll_fref;
64 int fll_fout;
65
66 struct delayed_work mic_work;
67 struct snd_soc_jack *jack;
68
69 struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES];
70 struct notifier_block disable_nb[WM8962_NUM_SUPPLIES];
71
72#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
73 struct input_dev *beep;
74 struct work_struct beep_work;
75 int beep_rate;
76#endif
77
78#ifdef CONFIG_GPIOLIB
79 struct gpio_chip gpio_chip;
80#endif
81};
82
83/* We can't use the same notifier block for more than one supply and
84 * there's no way I can see to get from a callback to the caller
85 * except container_of().
86 */
87#define WM8962_REGULATOR_EVENT(n) \
88static int wm8962_regulator_event_##n(struct notifier_block *nb, \
89 unsigned long event, void *data) \
90{ \
91 struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
92 disable_nb[n]); \
93 if (event & REGULATOR_EVENT_DISABLE) { \
94 wm8962->codec->cache_sync = 1; \
95 } \
96 return 0; \
97}
98
99WM8962_REGULATOR_EVENT(0)
100WM8962_REGULATOR_EVENT(1)
101WM8962_REGULATOR_EVENT(2)
102WM8962_REGULATOR_EVENT(3)
103WM8962_REGULATOR_EVENT(4)
104WM8962_REGULATOR_EVENT(5)
105WM8962_REGULATOR_EVENT(6)
106WM8962_REGULATOR_EVENT(7)
107
108static const u16 wm8962_reg[WM8962_MAX_REGISTER + 1] = {
109 [0] = 0x009F, /* R0 - Left Input volume */
110 [1] = 0x049F, /* R1 - Right Input volume */
111 [2] = 0x0000, /* R2 - HPOUTL volume */
112 [3] = 0x0000, /* R3 - HPOUTR volume */
113 [4] = 0x0020, /* R4 - Clocking1 */
114 [5] = 0x0018, /* R5 - ADC & DAC Control 1 */
115 [6] = 0x2008, /* R6 - ADC & DAC Control 2 */
116 [7] = 0x000A, /* R7 - Audio Interface 0 */
117 [8] = 0x01E4, /* R8 - Clocking2 */
118 [9] = 0x0300, /* R9 - Audio Interface 1 */
119 [10] = 0x00C0, /* R10 - Left DAC volume */
120 [11] = 0x00C0, /* R11 - Right DAC volume */
121
122 [14] = 0x0040, /* R14 - Audio Interface 2 */
123 [15] = 0x6243, /* R15 - Software Reset */
124
125 [17] = 0x007B, /* R17 - ALC1 */
126 [18] = 0x0000, /* R18 - ALC2 */
127 [19] = 0x1C32, /* R19 - ALC3 */
128 [20] = 0x3200, /* R20 - Noise Gate */
129 [21] = 0x00C0, /* R21 - Left ADC volume */
130 [22] = 0x00C0, /* R22 - Right ADC volume */
131 [23] = 0x0160, /* R23 - Additional control(1) */
132 [24] = 0x0000, /* R24 - Additional control(2) */
133 [25] = 0x0000, /* R25 - Pwr Mgmt (1) */
134 [26] = 0x0000, /* R26 - Pwr Mgmt (2) */
135 [27] = 0x0010, /* R27 - Additional Control (3) */
136 [28] = 0x0000, /* R28 - Anti-pop */
137
138 [30] = 0x005E, /* R30 - Clocking 3 */
139 [31] = 0x0000, /* R31 - Input mixer control (1) */
140 [32] = 0x0145, /* R32 - Left input mixer volume */
141 [33] = 0x0145, /* R33 - Right input mixer volume */
142 [34] = 0x0009, /* R34 - Input mixer control (2) */
143 [35] = 0x0003, /* R35 - Input bias control */
144 [37] = 0x0008, /* R37 - Left input PGA control */
145 [38] = 0x0008, /* R38 - Right input PGA control */
146
147 [40] = 0x0000, /* R40 - SPKOUTL volume */
148 [41] = 0x0000, /* R41 - SPKOUTR volume */
149
150 [47] = 0x0000, /* R47 - Thermal Shutdown Status */
151 [48] = 0x8027, /* R48 - Additional Control (4) */
152 [49] = 0x0010, /* R49 - Class D Control 1 */
153
154 [51] = 0x0003, /* R51 - Class D Control 2 */
155
156 [56] = 0x0506, /* R56 - Clocking 4 */
157 [57] = 0x0000, /* R57 - DAC DSP Mixing (1) */
158 [58] = 0x0000, /* R58 - DAC DSP Mixing (2) */
159
160 [60] = 0x0300, /* R60 - DC Servo 0 */
161 [61] = 0x0300, /* R61 - DC Servo 1 */
162
163 [64] = 0x0810, /* R64 - DC Servo 4 */
164
165 [66] = 0x0000, /* R66 - DC Servo 6 */
166
167 [68] = 0x001B, /* R68 - Analogue PGA Bias */
168 [69] = 0x0000, /* R69 - Analogue HP 0 */
169
170 [71] = 0x01FB, /* R71 - Analogue HP 2 */
171 [72] = 0x0000, /* R72 - Charge Pump 1 */
172
173 [82] = 0x0004, /* R82 - Charge Pump B */
174
175 [87] = 0x0000, /* R87 - Write Sequencer Control 1 */
176
177 [90] = 0x0000, /* R90 - Write Sequencer Control 2 */
178
179 [93] = 0x0000, /* R93 - Write Sequencer Control 3 */
180 [94] = 0x0000, /* R94 - Control Interface */
181
182 [99] = 0x0000, /* R99 - Mixer Enables */
183 [100] = 0x0000, /* R100 - Headphone Mixer (1) */
184 [101] = 0x0000, /* R101 - Headphone Mixer (2) */
185 [102] = 0x013F, /* R102 - Headphone Mixer (3) */
186 [103] = 0x013F, /* R103 - Headphone Mixer (4) */
187
188 [105] = 0x0000, /* R105 - Speaker Mixer (1) */
189 [106] = 0x0000, /* R106 - Speaker Mixer (2) */
190 [107] = 0x013F, /* R107 - Speaker Mixer (3) */
191 [108] = 0x013F, /* R108 - Speaker Mixer (4) */
192 [109] = 0x0003, /* R109 - Speaker Mixer (5) */
193 [110] = 0x0002, /* R110 - Beep Generator (1) */
194
195 [115] = 0x0006, /* R115 - Oscillator Trim (3) */
196 [116] = 0x0026, /* R116 - Oscillator Trim (4) */
197
198 [119] = 0x0000, /* R119 - Oscillator Trim (7) */
199
200 [124] = 0x0011, /* R124 - Analogue Clocking1 */
201 [125] = 0x004B, /* R125 - Analogue Clocking2 */
202 [126] = 0x000D, /* R126 - Analogue Clocking3 */
203 [127] = 0x0000, /* R127 - PLL Software Reset */
204
205 [129] = 0x0000, /* R129 - PLL2 */
206
207 [131] = 0x0000, /* R131 - PLL 4 */
208
209 [136] = 0x0067, /* R136 - PLL 9 */
210 [137] = 0x001C, /* R137 - PLL 10 */
211 [138] = 0x0071, /* R138 - PLL 11 */
212 [139] = 0x00C7, /* R139 - PLL 12 */
213 [140] = 0x0067, /* R140 - PLL 13 */
214 [141] = 0x0048, /* R141 - PLL 14 */
215 [142] = 0x0022, /* R142 - PLL 15 */
216 [143] = 0x0097, /* R143 - PLL 16 */
217
218 [155] = 0x000C, /* R155 - FLL Control (1) */
219 [156] = 0x0039, /* R156 - FLL Control (2) */
220 [157] = 0x0180, /* R157 - FLL Control (3) */
221
222 [159] = 0x0032, /* R159 - FLL Control (5) */
223 [160] = 0x0018, /* R160 - FLL Control (6) */
224 [161] = 0x007D, /* R161 - FLL Control (7) */
225 [162] = 0x0008, /* R162 - FLL Control (8) */
226
227 [252] = 0x0005, /* R252 - General test 1 */
228
229 [256] = 0x0000, /* R256 - DF1 */
230 [257] = 0x0000, /* R257 - DF2 */
231 [258] = 0x0000, /* R258 - DF3 */
232 [259] = 0x0000, /* R259 - DF4 */
233 [260] = 0x0000, /* R260 - DF5 */
234 [261] = 0x0000, /* R261 - DF6 */
235 [262] = 0x0000, /* R262 - DF7 */
236
237 [264] = 0x0000, /* R264 - LHPF1 */
238 [265] = 0x0000, /* R265 - LHPF2 */
239
240 [268] = 0x0000, /* R268 - THREED1 */
241 [269] = 0x0000, /* R269 - THREED2 */
242 [270] = 0x0000, /* R270 - THREED3 */
243 [271] = 0x0000, /* R271 - THREED4 */
244
245 [276] = 0x000C, /* R276 - DRC 1 */
246 [277] = 0x0925, /* R277 - DRC 2 */
247 [278] = 0x0000, /* R278 - DRC 3 */
248 [279] = 0x0000, /* R279 - DRC 4 */
249 [280] = 0x0000, /* R280 - DRC 5 */
250
251 [285] = 0x0000, /* R285 - Tloopback */
252
253 [335] = 0x0004, /* R335 - EQ1 */
254 [336] = 0x6318, /* R336 - EQ2 */
255 [337] = 0x6300, /* R337 - EQ3 */
256 [338] = 0x0FCA, /* R338 - EQ4 */
257 [339] = 0x0400, /* R339 - EQ5 */
258 [340] = 0x00D8, /* R340 - EQ6 */
259 [341] = 0x1EB5, /* R341 - EQ7 */
260 [342] = 0xF145, /* R342 - EQ8 */
261 [343] = 0x0B75, /* R343 - EQ9 */
262 [344] = 0x01C5, /* R344 - EQ10 */
263 [345] = 0x1C58, /* R345 - EQ11 */
264 [346] = 0xF373, /* R346 - EQ12 */
265 [347] = 0x0A54, /* R347 - EQ13 */
266 [348] = 0x0558, /* R348 - EQ14 */
267 [349] = 0x168E, /* R349 - EQ15 */
268 [350] = 0xF829, /* R350 - EQ16 */
269 [351] = 0x07AD, /* R351 - EQ17 */
270 [352] = 0x1103, /* R352 - EQ18 */
271 [353] = 0x0564, /* R353 - EQ19 */
272 [354] = 0x0559, /* R354 - EQ20 */
273 [355] = 0x4000, /* R355 - EQ21 */
274 [356] = 0x6318, /* R356 - EQ22 */
275 [357] = 0x6300, /* R357 - EQ23 */
276 [358] = 0x0FCA, /* R358 - EQ24 */
277 [359] = 0x0400, /* R359 - EQ25 */
278 [360] = 0x00D8, /* R360 - EQ26 */
279 [361] = 0x1EB5, /* R361 - EQ27 */
280 [362] = 0xF145, /* R362 - EQ28 */
281 [363] = 0x0B75, /* R363 - EQ29 */
282 [364] = 0x01C5, /* R364 - EQ30 */
283 [365] = 0x1C58, /* R365 - EQ31 */
284 [366] = 0xF373, /* R366 - EQ32 */
285 [367] = 0x0A54, /* R367 - EQ33 */
286 [368] = 0x0558, /* R368 - EQ34 */
287 [369] = 0x168E, /* R369 - EQ35 */
288 [370] = 0xF829, /* R370 - EQ36 */
289 [371] = 0x07AD, /* R371 - EQ37 */
290 [372] = 0x1103, /* R372 - EQ38 */
291 [373] = 0x0564, /* R373 - EQ39 */
292 [374] = 0x0559, /* R374 - EQ40 */
293 [375] = 0x4000, /* R375 - EQ41 */
294
295 [513] = 0x0000, /* R513 - GPIO 2 */
296 [514] = 0x0000, /* R514 - GPIO 3 */
297
298 [516] = 0x8100, /* R516 - GPIO 5 */
299 [517] = 0x8100, /* R517 - GPIO 6 */
300
301 [560] = 0x0000, /* R560 - Interrupt Status 1 */
302 [561] = 0x0000, /* R561 - Interrupt Status 2 */
303
304 [568] = 0x0030, /* R568 - Interrupt Status 1 Mask */
305 [569] = 0xFFED, /* R569 - Interrupt Status 2 Mask */
306
307 [576] = 0x0000, /* R576 - Interrupt Control */
308
309 [584] = 0x002D, /* R584 - IRQ Debounce */
310
311 [586] = 0x0000, /* R586 - MICINT Source Pol */
312
313 [768] = 0x1C00, /* R768 - DSP2 Power Management */
314
315 [1037] = 0x0000, /* R1037 - DSP2_ExecControl */
316
317 [8192] = 0x0000, /* R8192 - DSP2 Instruction RAM 0 */
318
319 [9216] = 0x0030, /* R9216 - DSP2 Address RAM 2 */
320 [9217] = 0x0000, /* R9217 - DSP2 Address RAM 1 */
321 [9218] = 0x0000, /* R9218 - DSP2 Address RAM 0 */
322
323 [12288] = 0x0000, /* R12288 - DSP2 Data1 RAM 1 */
324 [12289] = 0x0000, /* R12289 - DSP2 Data1 RAM 0 */
325
326 [13312] = 0x0000, /* R13312 - DSP2 Data2 RAM 1 */
327 [13313] = 0x0000, /* R13313 - DSP2 Data2 RAM 0 */
328
329 [14336] = 0x0000, /* R14336 - DSP2 Data3 RAM 1 */
330 [14337] = 0x0000, /* R14337 - DSP2 Data3 RAM 0 */
331
332 [15360] = 0x000A, /* R15360 - DSP2 Coeff RAM 0 */
333
334 [16384] = 0x0000, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
335 [16385] = 0x0000, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
336 [16386] = 0x0000, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
337 [16387] = 0x0000, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
338 [16388] = 0x0000, /* R16388 - SOUNDSTAGE_ENABLES_1 */
339 [16389] = 0x0000, /* R16389 - SOUNDSTAGE_ENABLES_0 */
340
341 [16896] = 0x0002, /* R16896 - HDBASS_AI_1 */
342 [16897] = 0xBD12, /* R16897 - HDBASS_AI_0 */
343 [16898] = 0x007C, /* R16898 - HDBASS_AR_1 */
344 [16899] = 0x586C, /* R16899 - HDBASS_AR_0 */
345 [16900] = 0x0053, /* R16900 - HDBASS_B_1 */
346 [16901] = 0x8121, /* R16901 - HDBASS_B_0 */
347 [16902] = 0x003F, /* R16902 - HDBASS_K_1 */
348 [16903] = 0x8BD8, /* R16903 - HDBASS_K_0 */
349 [16904] = 0x0032, /* R16904 - HDBASS_N1_1 */
350 [16905] = 0xF52D, /* R16905 - HDBASS_N1_0 */
351 [16906] = 0x0065, /* R16906 - HDBASS_N2_1 */
352 [16907] = 0xAC8C, /* R16907 - HDBASS_N2_0 */
353 [16908] = 0x006B, /* R16908 - HDBASS_N3_1 */
354 [16909] = 0xE087, /* R16909 - HDBASS_N3_0 */
355 [16910] = 0x0072, /* R16910 - HDBASS_N4_1 */
356 [16911] = 0x1483, /* R16911 - HDBASS_N4_0 */
357 [16912] = 0x0072, /* R16912 - HDBASS_N5_1 */
358 [16913] = 0x1483, /* R16913 - HDBASS_N5_0 */
359 [16914] = 0x0043, /* R16914 - HDBASS_X1_1 */
360 [16915] = 0x3525, /* R16915 - HDBASS_X1_0 */
361 [16916] = 0x0006, /* R16916 - HDBASS_X2_1 */
362 [16917] = 0x6A4A, /* R16917 - HDBASS_X2_0 */
363 [16918] = 0x0043, /* R16918 - HDBASS_X3_1 */
364 [16919] = 0x6079, /* R16919 - HDBASS_X3_0 */
365 [16920] = 0x0008, /* R16920 - HDBASS_ATK_1 */
366 [16921] = 0x0000, /* R16921 - HDBASS_ATK_0 */
367 [16922] = 0x0001, /* R16922 - HDBASS_DCY_1 */
368 [16923] = 0x0000, /* R16923 - HDBASS_DCY_0 */
369 [16924] = 0x0059, /* R16924 - HDBASS_PG_1 */
370 [16925] = 0x999A, /* R16925 - HDBASS_PG_0 */
371
372 [17048] = 0x0083, /* R17408 - HPF_C_1 */
373 [17049] = 0x98AD, /* R17409 - HPF_C_0 */
374
375 [17920] = 0x007F, /* R17920 - ADCL_RETUNE_C1_1 */
376 [17921] = 0xFFFF, /* R17921 - ADCL_RETUNE_C1_0 */
377 [17922] = 0x0000, /* R17922 - ADCL_RETUNE_C2_1 */
378 [17923] = 0x0000, /* R17923 - ADCL_RETUNE_C2_0 */
379 [17924] = 0x0000, /* R17924 - ADCL_RETUNE_C3_1 */
380 [17925] = 0x0000, /* R17925 - ADCL_RETUNE_C3_0 */
381 [17926] = 0x0000, /* R17926 - ADCL_RETUNE_C4_1 */
382 [17927] = 0x0000, /* R17927 - ADCL_RETUNE_C4_0 */
383 [17928] = 0x0000, /* R17928 - ADCL_RETUNE_C5_1 */
384 [17929] = 0x0000, /* R17929 - ADCL_RETUNE_C5_0 */
385 [17930] = 0x0000, /* R17930 - ADCL_RETUNE_C6_1 */
386 [17931] = 0x0000, /* R17931 - ADCL_RETUNE_C6_0 */
387 [17932] = 0x0000, /* R17932 - ADCL_RETUNE_C7_1 */
388 [17933] = 0x0000, /* R17933 - ADCL_RETUNE_C7_0 */
389 [17934] = 0x0000, /* R17934 - ADCL_RETUNE_C8_1 */
390 [17935] = 0x0000, /* R17935 - ADCL_RETUNE_C8_0 */
391 [17936] = 0x0000, /* R17936 - ADCL_RETUNE_C9_1 */
392 [17937] = 0x0000, /* R17937 - ADCL_RETUNE_C9_0 */
393 [17938] = 0x0000, /* R17938 - ADCL_RETUNE_C10_1 */
394 [17939] = 0x0000, /* R17939 - ADCL_RETUNE_C10_0 */
395 [17940] = 0x0000, /* R17940 - ADCL_RETUNE_C11_1 */
396 [17941] = 0x0000, /* R17941 - ADCL_RETUNE_C11_0 */
397 [17942] = 0x0000, /* R17942 - ADCL_RETUNE_C12_1 */
398 [17943] = 0x0000, /* R17943 - ADCL_RETUNE_C12_0 */
399 [17944] = 0x0000, /* R17944 - ADCL_RETUNE_C13_1 */
400 [17945] = 0x0000, /* R17945 - ADCL_RETUNE_C13_0 */
401 [17946] = 0x0000, /* R17946 - ADCL_RETUNE_C14_1 */
402 [17947] = 0x0000, /* R17947 - ADCL_RETUNE_C14_0 */
403 [17948] = 0x0000, /* R17948 - ADCL_RETUNE_C15_1 */
404 [17949] = 0x0000, /* R17949 - ADCL_RETUNE_C15_0 */
405 [17950] = 0x0000, /* R17950 - ADCL_RETUNE_C16_1 */
406 [17951] = 0x0000, /* R17951 - ADCL_RETUNE_C16_0 */
407 [17952] = 0x0000, /* R17952 - ADCL_RETUNE_C17_1 */
408 [17953] = 0x0000, /* R17953 - ADCL_RETUNE_C17_0 */
409 [17954] = 0x0000, /* R17954 - ADCL_RETUNE_C18_1 */
410 [17955] = 0x0000, /* R17955 - ADCL_RETUNE_C18_0 */
411 [17956] = 0x0000, /* R17956 - ADCL_RETUNE_C19_1 */
412 [17957] = 0x0000, /* R17957 - ADCL_RETUNE_C19_0 */
413 [17958] = 0x0000, /* R17958 - ADCL_RETUNE_C20_1 */
414 [17959] = 0x0000, /* R17959 - ADCL_RETUNE_C20_0 */
415 [17960] = 0x0000, /* R17960 - ADCL_RETUNE_C21_1 */
416 [17961] = 0x0000, /* R17961 - ADCL_RETUNE_C21_0 */
417 [17962] = 0x0000, /* R17962 - ADCL_RETUNE_C22_1 */
418 [17963] = 0x0000, /* R17963 - ADCL_RETUNE_C22_0 */
419 [17964] = 0x0000, /* R17964 - ADCL_RETUNE_C23_1 */
420 [17965] = 0x0000, /* R17965 - ADCL_RETUNE_C23_0 */
421 [17966] = 0x0000, /* R17966 - ADCL_RETUNE_C24_1 */
422 [17967] = 0x0000, /* R17967 - ADCL_RETUNE_C24_0 */
423 [17968] = 0x0000, /* R17968 - ADCL_RETUNE_C25_1 */
424 [17969] = 0x0000, /* R17969 - ADCL_RETUNE_C25_0 */
425 [17970] = 0x0000, /* R17970 - ADCL_RETUNE_C26_1 */
426 [17971] = 0x0000, /* R17971 - ADCL_RETUNE_C26_0 */
427 [17972] = 0x0000, /* R17972 - ADCL_RETUNE_C27_1 */
428 [17973] = 0x0000, /* R17973 - ADCL_RETUNE_C27_0 */
429 [17974] = 0x0000, /* R17974 - ADCL_RETUNE_C28_1 */
430 [17975] = 0x0000, /* R17975 - ADCL_RETUNE_C28_0 */
431 [17976] = 0x0000, /* R17976 - ADCL_RETUNE_C29_1 */
432 [17977] = 0x0000, /* R17977 - ADCL_RETUNE_C29_0 */
433 [17978] = 0x0000, /* R17978 - ADCL_RETUNE_C30_1 */
434 [17979] = 0x0000, /* R17979 - ADCL_RETUNE_C30_0 */
435 [17980] = 0x0000, /* R17980 - ADCL_RETUNE_C31_1 */
436 [17981] = 0x0000, /* R17981 - ADCL_RETUNE_C31_0 */
437 [17982] = 0x0000, /* R17982 - ADCL_RETUNE_C32_1 */
438 [17983] = 0x0000, /* R17983 - ADCL_RETUNE_C32_0 */
439
440 [18432] = 0x0020, /* R18432 - RETUNEADC_PG2_1 */
441 [18433] = 0x0000, /* R18433 - RETUNEADC_PG2_0 */
442 [18434] = 0x0040, /* R18434 - RETUNEADC_PG_1 */
443 [18435] = 0x0000, /* R18435 - RETUNEADC_PG_0 */
444
445 [18944] = 0x007F, /* R18944 - ADCR_RETUNE_C1_1 */
446 [18945] = 0xFFFF, /* R18945 - ADCR_RETUNE_C1_0 */
447 [18946] = 0x0000, /* R18946 - ADCR_RETUNE_C2_1 */
448 [18947] = 0x0000, /* R18947 - ADCR_RETUNE_C2_0 */
449 [18948] = 0x0000, /* R18948 - ADCR_RETUNE_C3_1 */
450 [18949] = 0x0000, /* R18949 - ADCR_RETUNE_C3_0 */
451 [18950] = 0x0000, /* R18950 - ADCR_RETUNE_C4_1 */
452 [18951] = 0x0000, /* R18951 - ADCR_RETUNE_C4_0 */
453 [18952] = 0x0000, /* R18952 - ADCR_RETUNE_C5_1 */
454 [18953] = 0x0000, /* R18953 - ADCR_RETUNE_C5_0 */
455 [18954] = 0x0000, /* R18954 - ADCR_RETUNE_C6_1 */
456 [18955] = 0x0000, /* R18955 - ADCR_RETUNE_C6_0 */
457 [18956] = 0x0000, /* R18956 - ADCR_RETUNE_C7_1 */
458 [18957] = 0x0000, /* R18957 - ADCR_RETUNE_C7_0 */
459 [18958] = 0x0000, /* R18958 - ADCR_RETUNE_C8_1 */
460 [18959] = 0x0000, /* R18959 - ADCR_RETUNE_C8_0 */
461 [18960] = 0x0000, /* R18960 - ADCR_RETUNE_C9_1 */
462 [18961] = 0x0000, /* R18961 - ADCR_RETUNE_C9_0 */
463 [18962] = 0x0000, /* R18962 - ADCR_RETUNE_C10_1 */
464 [18963] = 0x0000, /* R18963 - ADCR_RETUNE_C10_0 */
465 [18964] = 0x0000, /* R18964 - ADCR_RETUNE_C11_1 */
466 [18965] = 0x0000, /* R18965 - ADCR_RETUNE_C11_0 */
467 [18966] = 0x0000, /* R18966 - ADCR_RETUNE_C12_1 */
468 [18967] = 0x0000, /* R18967 - ADCR_RETUNE_C12_0 */
469 [18968] = 0x0000, /* R18968 - ADCR_RETUNE_C13_1 */
470 [18969] = 0x0000, /* R18969 - ADCR_RETUNE_C13_0 */
471 [18970] = 0x0000, /* R18970 - ADCR_RETUNE_C14_1 */
472 [18971] = 0x0000, /* R18971 - ADCR_RETUNE_C14_0 */
473 [18972] = 0x0000, /* R18972 - ADCR_RETUNE_C15_1 */
474 [18973] = 0x0000, /* R18973 - ADCR_RETUNE_C15_0 */
475 [18974] = 0x0000, /* R18974 - ADCR_RETUNE_C16_1 */
476 [18975] = 0x0000, /* R18975 - ADCR_RETUNE_C16_0 */
477 [18976] = 0x0000, /* R18976 - ADCR_RETUNE_C17_1 */
478 [18977] = 0x0000, /* R18977 - ADCR_RETUNE_C17_0 */
479 [18978] = 0x0000, /* R18978 - ADCR_RETUNE_C18_1 */
480 [18979] = 0x0000, /* R18979 - ADCR_RETUNE_C18_0 */
481 [18980] = 0x0000, /* R18980 - ADCR_RETUNE_C19_1 */
482 [18981] = 0x0000, /* R18981 - ADCR_RETUNE_C19_0 */
483 [18982] = 0x0000, /* R18982 - ADCR_RETUNE_C20_1 */
484 [18983] = 0x0000, /* R18983 - ADCR_RETUNE_C20_0 */
485 [18984] = 0x0000, /* R18984 - ADCR_RETUNE_C21_1 */
486 [18985] = 0x0000, /* R18985 - ADCR_RETUNE_C21_0 */
487 [18986] = 0x0000, /* R18986 - ADCR_RETUNE_C22_1 */
488 [18987] = 0x0000, /* R18987 - ADCR_RETUNE_C22_0 */
489 [18988] = 0x0000, /* R18988 - ADCR_RETUNE_C23_1 */
490 [18989] = 0x0000, /* R18989 - ADCR_RETUNE_C23_0 */
491 [18990] = 0x0000, /* R18990 - ADCR_RETUNE_C24_1 */
492 [18991] = 0x0000, /* R18991 - ADCR_RETUNE_C24_0 */
493 [18992] = 0x0000, /* R18992 - ADCR_RETUNE_C25_1 */
494 [18993] = 0x0000, /* R18993 - ADCR_RETUNE_C25_0 */
495 [18994] = 0x0000, /* R18994 - ADCR_RETUNE_C26_1 */
496 [18995] = 0x0000, /* R18995 - ADCR_RETUNE_C26_0 */
497 [18996] = 0x0000, /* R18996 - ADCR_RETUNE_C27_1 */
498 [18997] = 0x0000, /* R18997 - ADCR_RETUNE_C27_0 */
499 [18998] = 0x0000, /* R18998 - ADCR_RETUNE_C28_1 */
500 [18999] = 0x0000, /* R18999 - ADCR_RETUNE_C28_0 */
501 [19000] = 0x0000, /* R19000 - ADCR_RETUNE_C29_1 */
502 [19001] = 0x0000, /* R19001 - ADCR_RETUNE_C29_0 */
503 [19002] = 0x0000, /* R19002 - ADCR_RETUNE_C30_1 */
504 [19003] = 0x0000, /* R19003 - ADCR_RETUNE_C30_0 */
505 [19004] = 0x0000, /* R19004 - ADCR_RETUNE_C31_1 */
506 [19005] = 0x0000, /* R19005 - ADCR_RETUNE_C31_0 */
507 [19006] = 0x0000, /* R19006 - ADCR_RETUNE_C32_1 */
508 [19007] = 0x0000, /* R19007 - ADCR_RETUNE_C32_0 */
509
510 [19456] = 0x007F, /* R19456 - DACL_RETUNE_C1_1 */
511 [19457] = 0xFFFF, /* R19457 - DACL_RETUNE_C1_0 */
512 [19458] = 0x0000, /* R19458 - DACL_RETUNE_C2_1 */
513 [19459] = 0x0000, /* R19459 - DACL_RETUNE_C2_0 */
514 [19460] = 0x0000, /* R19460 - DACL_RETUNE_C3_1 */
515 [19461] = 0x0000, /* R19461 - DACL_RETUNE_C3_0 */
516 [19462] = 0x0000, /* R19462 - DACL_RETUNE_C4_1 */
517 [19463] = 0x0000, /* R19463 - DACL_RETUNE_C4_0 */
518 [19464] = 0x0000, /* R19464 - DACL_RETUNE_C5_1 */
519 [19465] = 0x0000, /* R19465 - DACL_RETUNE_C5_0 */
520 [19466] = 0x0000, /* R19466 - DACL_RETUNE_C6_1 */
521 [19467] = 0x0000, /* R19467 - DACL_RETUNE_C6_0 */
522 [19468] = 0x0000, /* R19468 - DACL_RETUNE_C7_1 */
523 [19469] = 0x0000, /* R19469 - DACL_RETUNE_C7_0 */
524 [19470] = 0x0000, /* R19470 - DACL_RETUNE_C8_1 */
525 [19471] = 0x0000, /* R19471 - DACL_RETUNE_C8_0 */
526 [19472] = 0x0000, /* R19472 - DACL_RETUNE_C9_1 */
527 [19473] = 0x0000, /* R19473 - DACL_RETUNE_C9_0 */
528 [19474] = 0x0000, /* R19474 - DACL_RETUNE_C10_1 */
529 [19475] = 0x0000, /* R19475 - DACL_RETUNE_C10_0 */
530 [19476] = 0x0000, /* R19476 - DACL_RETUNE_C11_1 */
531 [19477] = 0x0000, /* R19477 - DACL_RETUNE_C11_0 */
532 [19478] = 0x0000, /* R19478 - DACL_RETUNE_C12_1 */
533 [19479] = 0x0000, /* R19479 - DACL_RETUNE_C12_0 */
534 [19480] = 0x0000, /* R19480 - DACL_RETUNE_C13_1 */
535 [19481] = 0x0000, /* R19481 - DACL_RETUNE_C13_0 */
536 [19482] = 0x0000, /* R19482 - DACL_RETUNE_C14_1 */
537 [19483] = 0x0000, /* R19483 - DACL_RETUNE_C14_0 */
538 [19484] = 0x0000, /* R19484 - DACL_RETUNE_C15_1 */
539 [19485] = 0x0000, /* R19485 - DACL_RETUNE_C15_0 */
540 [19486] = 0x0000, /* R19486 - DACL_RETUNE_C16_1 */
541 [19487] = 0x0000, /* R19487 - DACL_RETUNE_C16_0 */
542 [19488] = 0x0000, /* R19488 - DACL_RETUNE_C17_1 */
543 [19489] = 0x0000, /* R19489 - DACL_RETUNE_C17_0 */
544 [19490] = 0x0000, /* R19490 - DACL_RETUNE_C18_1 */
545 [19491] = 0x0000, /* R19491 - DACL_RETUNE_C18_0 */
546 [19492] = 0x0000, /* R19492 - DACL_RETUNE_C19_1 */
547 [19493] = 0x0000, /* R19493 - DACL_RETUNE_C19_0 */
548 [19494] = 0x0000, /* R19494 - DACL_RETUNE_C20_1 */
549 [19495] = 0x0000, /* R19495 - DACL_RETUNE_C20_0 */
550 [19496] = 0x0000, /* R19496 - DACL_RETUNE_C21_1 */
551 [19497] = 0x0000, /* R19497 - DACL_RETUNE_C21_0 */
552 [19498] = 0x0000, /* R19498 - DACL_RETUNE_C22_1 */
553 [19499] = 0x0000, /* R19499 - DACL_RETUNE_C22_0 */
554 [19500] = 0x0000, /* R19500 - DACL_RETUNE_C23_1 */
555 [19501] = 0x0000, /* R19501 - DACL_RETUNE_C23_0 */
556 [19502] = 0x0000, /* R19502 - DACL_RETUNE_C24_1 */
557 [19503] = 0x0000, /* R19503 - DACL_RETUNE_C24_0 */
558 [19504] = 0x0000, /* R19504 - DACL_RETUNE_C25_1 */
559 [19505] = 0x0000, /* R19505 - DACL_RETUNE_C25_0 */
560 [19506] = 0x0000, /* R19506 - DACL_RETUNE_C26_1 */
561 [19507] = 0x0000, /* R19507 - DACL_RETUNE_C26_0 */
562 [19508] = 0x0000, /* R19508 - DACL_RETUNE_C27_1 */
563 [19509] = 0x0000, /* R19509 - DACL_RETUNE_C27_0 */
564 [19510] = 0x0000, /* R19510 - DACL_RETUNE_C28_1 */
565 [19511] = 0x0000, /* R19511 - DACL_RETUNE_C28_0 */
566 [19512] = 0x0000, /* R19512 - DACL_RETUNE_C29_1 */
567 [19513] = 0x0000, /* R19513 - DACL_RETUNE_C29_0 */
568 [19514] = 0x0000, /* R19514 - DACL_RETUNE_C30_1 */
569 [19515] = 0x0000, /* R19515 - DACL_RETUNE_C30_0 */
570 [19516] = 0x0000, /* R19516 - DACL_RETUNE_C31_1 */
571 [19517] = 0x0000, /* R19517 - DACL_RETUNE_C31_0 */
572 [19518] = 0x0000, /* R19518 - DACL_RETUNE_C32_1 */
573 [19519] = 0x0000, /* R19519 - DACL_RETUNE_C32_0 */
574
575 [19968] = 0x0020, /* R19968 - RETUNEDAC_PG2_1 */
576 [19969] = 0x0000, /* R19969 - RETUNEDAC_PG2_0 */
577 [19970] = 0x0040, /* R19970 - RETUNEDAC_PG_1 */
578 [19971] = 0x0000, /* R19971 - RETUNEDAC_PG_0 */
579
580 [20480] = 0x007F, /* R20480 - DACR_RETUNE_C1_1 */
581 [20481] = 0xFFFF, /* R20481 - DACR_RETUNE_C1_0 */
582 [20482] = 0x0000, /* R20482 - DACR_RETUNE_C2_1 */
583 [20483] = 0x0000, /* R20483 - DACR_RETUNE_C2_0 */
584 [20484] = 0x0000, /* R20484 - DACR_RETUNE_C3_1 */
585 [20485] = 0x0000, /* R20485 - DACR_RETUNE_C3_0 */
586 [20486] = 0x0000, /* R20486 - DACR_RETUNE_C4_1 */
587 [20487] = 0x0000, /* R20487 - DACR_RETUNE_C4_0 */
588 [20488] = 0x0000, /* R20488 - DACR_RETUNE_C5_1 */
589 [20489] = 0x0000, /* R20489 - DACR_RETUNE_C5_0 */
590 [20490] = 0x0000, /* R20490 - DACR_RETUNE_C6_1 */
591 [20491] = 0x0000, /* R20491 - DACR_RETUNE_C6_0 */
592 [20492] = 0x0000, /* R20492 - DACR_RETUNE_C7_1 */
593 [20493] = 0x0000, /* R20493 - DACR_RETUNE_C7_0 */
594 [20494] = 0x0000, /* R20494 - DACR_RETUNE_C8_1 */
595 [20495] = 0x0000, /* R20495 - DACR_RETUNE_C8_0 */
596 [20496] = 0x0000, /* R20496 - DACR_RETUNE_C9_1 */
597 [20497] = 0x0000, /* R20497 - DACR_RETUNE_C9_0 */
598 [20498] = 0x0000, /* R20498 - DACR_RETUNE_C10_1 */
599 [20499] = 0x0000, /* R20499 - DACR_RETUNE_C10_0 */
600 [20500] = 0x0000, /* R20500 - DACR_RETUNE_C11_1 */
601 [20501] = 0x0000, /* R20501 - DACR_RETUNE_C11_0 */
602 [20502] = 0x0000, /* R20502 - DACR_RETUNE_C12_1 */
603 [20503] = 0x0000, /* R20503 - DACR_RETUNE_C12_0 */
604 [20504] = 0x0000, /* R20504 - DACR_RETUNE_C13_1 */
605 [20505] = 0x0000, /* R20505 - DACR_RETUNE_C13_0 */
606 [20506] = 0x0000, /* R20506 - DACR_RETUNE_C14_1 */
607 [20507] = 0x0000, /* R20507 - DACR_RETUNE_C14_0 */
608 [20508] = 0x0000, /* R20508 - DACR_RETUNE_C15_1 */
609 [20509] = 0x0000, /* R20509 - DACR_RETUNE_C15_0 */
610 [20510] = 0x0000, /* R20510 - DACR_RETUNE_C16_1 */
611 [20511] = 0x0000, /* R20511 - DACR_RETUNE_C16_0 */
612 [20512] = 0x0000, /* R20512 - DACR_RETUNE_C17_1 */
613 [20513] = 0x0000, /* R20513 - DACR_RETUNE_C17_0 */
614 [20514] = 0x0000, /* R20514 - DACR_RETUNE_C18_1 */
615 [20515] = 0x0000, /* R20515 - DACR_RETUNE_C18_0 */
616 [20516] = 0x0000, /* R20516 - DACR_RETUNE_C19_1 */
617 [20517] = 0x0000, /* R20517 - DACR_RETUNE_C19_0 */
618 [20518] = 0x0000, /* R20518 - DACR_RETUNE_C20_1 */
619 [20519] = 0x0000, /* R20519 - DACR_RETUNE_C20_0 */
620 [20520] = 0x0000, /* R20520 - DACR_RETUNE_C21_1 */
621 [20521] = 0x0000, /* R20521 - DACR_RETUNE_C21_0 */
622 [20522] = 0x0000, /* R20522 - DACR_RETUNE_C22_1 */
623 [20523] = 0x0000, /* R20523 - DACR_RETUNE_C22_0 */
624 [20524] = 0x0000, /* R20524 - DACR_RETUNE_C23_1 */
625 [20525] = 0x0000, /* R20525 - DACR_RETUNE_C23_0 */
626 [20526] = 0x0000, /* R20526 - DACR_RETUNE_C24_1 */
627 [20527] = 0x0000, /* R20527 - DACR_RETUNE_C24_0 */
628 [20528] = 0x0000, /* R20528 - DACR_RETUNE_C25_1 */
629 [20529] = 0x0000, /* R20529 - DACR_RETUNE_C25_0 */
630 [20530] = 0x0000, /* R20530 - DACR_RETUNE_C26_1 */
631 [20531] = 0x0000, /* R20531 - DACR_RETUNE_C26_0 */
632 [20532] = 0x0000, /* R20532 - DACR_RETUNE_C27_1 */
633 [20533] = 0x0000, /* R20533 - DACR_RETUNE_C27_0 */
634 [20534] = 0x0000, /* R20534 - DACR_RETUNE_C28_1 */
635 [20535] = 0x0000, /* R20535 - DACR_RETUNE_C28_0 */
636 [20536] = 0x0000, /* R20536 - DACR_RETUNE_C29_1 */
637 [20537] = 0x0000, /* R20537 - DACR_RETUNE_C29_0 */
638 [20538] = 0x0000, /* R20538 - DACR_RETUNE_C30_1 */
639 [20539] = 0x0000, /* R20539 - DACR_RETUNE_C30_0 */
640 [20540] = 0x0000, /* R20540 - DACR_RETUNE_C31_1 */
641 [20541] = 0x0000, /* R20541 - DACR_RETUNE_C31_0 */
642 [20542] = 0x0000, /* R20542 - DACR_RETUNE_C32_1 */
643 [20543] = 0x0000, /* R20543 - DACR_RETUNE_C32_0 */
644
645 [20992] = 0x008C, /* R20992 - VSS_XHD2_1 */
646 [20993] = 0x0200, /* R20993 - VSS_XHD2_0 */
647 [20994] = 0x0035, /* R20994 - VSS_XHD3_1 */
648 [20995] = 0x0700, /* R20995 - VSS_XHD3_0 */
649 [20996] = 0x003A, /* R20996 - VSS_XHN1_1 */
650 [20997] = 0x4100, /* R20997 - VSS_XHN1_0 */
651 [20998] = 0x008B, /* R20998 - VSS_XHN2_1 */
652 [20999] = 0x7D00, /* R20999 - VSS_XHN2_0 */
653 [21000] = 0x003A, /* R21000 - VSS_XHN3_1 */
654 [21001] = 0x4100, /* R21001 - VSS_XHN3_0 */
655 [21002] = 0x008C, /* R21002 - VSS_XLA_1 */
656 [21003] = 0xFEE8, /* R21003 - VSS_XLA_0 */
657 [21004] = 0x0078, /* R21004 - VSS_XLB_1 */
658 [21005] = 0x0000, /* R21005 - VSS_XLB_0 */
659 [21006] = 0x003F, /* R21006 - VSS_XLG_1 */
660 [21007] = 0xB260, /* R21007 - VSS_XLG_0 */
661 [21008] = 0x002D, /* R21008 - VSS_PG2_1 */
662 [21009] = 0x1818, /* R21009 - VSS_PG2_0 */
663 [21010] = 0x0020, /* R21010 - VSS_PG_1 */
664 [21011] = 0x0000, /* R21011 - VSS_PG_0 */
665 [21012] = 0x00F1, /* R21012 - VSS_XTD1_1 */
666 [21013] = 0x8340, /* R21013 - VSS_XTD1_0 */
667 [21014] = 0x00FB, /* R21014 - VSS_XTD2_1 */
668 [21015] = 0x8300, /* R21015 - VSS_XTD2_0 */
669 [21016] = 0x00EE, /* R21016 - VSS_XTD3_1 */
670 [21017] = 0xAEC0, /* R21017 - VSS_XTD3_0 */
671 [21018] = 0x00FB, /* R21018 - VSS_XTD4_1 */
672 [21019] = 0xAC40, /* R21019 - VSS_XTD4_0 */
673 [21020] = 0x00F1, /* R21020 - VSS_XTD5_1 */
674 [21021] = 0x7F80, /* R21021 - VSS_XTD5_0 */
675 [21022] = 0x00F4, /* R21022 - VSS_XTD6_1 */
676 [21023] = 0x3B40, /* R21023 - VSS_XTD6_0 */
677 [21024] = 0x00F5, /* R21024 - VSS_XTD7_1 */
678 [21025] = 0xFB00, /* R21025 - VSS_XTD7_0 */
679 [21026] = 0x00EA, /* R21026 - VSS_XTD8_1 */
680 [21027] = 0x10C0, /* R21027 - VSS_XTD8_0 */
681 [21028] = 0x00FC, /* R21028 - VSS_XTD9_1 */
682 [21029] = 0xC580, /* R21029 - VSS_XTD9_0 */
683 [21030] = 0x00E2, /* R21030 - VSS_XTD10_1 */
684 [21031] = 0x75C0, /* R21031 - VSS_XTD10_0 */
685 [21032] = 0x0004, /* R21032 - VSS_XTD11_1 */
686 [21033] = 0xB480, /* R21033 - VSS_XTD11_0 */
687 [21034] = 0x00D4, /* R21034 - VSS_XTD12_1 */
688 [21035] = 0xF980, /* R21035 - VSS_XTD12_0 */
689 [21036] = 0x0004, /* R21036 - VSS_XTD13_1 */
690 [21037] = 0x9140, /* R21037 - VSS_XTD13_0 */
691 [21038] = 0x00D8, /* R21038 - VSS_XTD14_1 */
692 [21039] = 0xA480, /* R21039 - VSS_XTD14_0 */
693 [21040] = 0x0002, /* R21040 - VSS_XTD15_1 */
694 [21041] = 0x3DC0, /* R21041 - VSS_XTD15_0 */
695 [21042] = 0x00CF, /* R21042 - VSS_XTD16_1 */
696 [21043] = 0x7A80, /* R21043 - VSS_XTD16_0 */
697 [21044] = 0x00DC, /* R21044 - VSS_XTD17_1 */
698 [21045] = 0x0600, /* R21045 - VSS_XTD17_0 */
699 [21046] = 0x00F2, /* R21046 - VSS_XTD18_1 */
700 [21047] = 0xDAC0, /* R21047 - VSS_XTD18_0 */
701 [21048] = 0x00BA, /* R21048 - VSS_XTD19_1 */
702 [21049] = 0xF340, /* R21049 - VSS_XTD19_0 */
703 [21050] = 0x000A, /* R21050 - VSS_XTD20_1 */
704 [21051] = 0x7940, /* R21051 - VSS_XTD20_0 */
705 [21052] = 0x001C, /* R21052 - VSS_XTD21_1 */
706 [21053] = 0x0680, /* R21053 - VSS_XTD21_0 */
707 [21054] = 0x00FD, /* R21054 - VSS_XTD22_1 */
708 [21055] = 0x2D00, /* R21055 - VSS_XTD22_0 */
709 [21056] = 0x001C, /* R21056 - VSS_XTD23_1 */
710 [21057] = 0xE840, /* R21057 - VSS_XTD23_0 */
711 [21058] = 0x000D, /* R21058 - VSS_XTD24_1 */
712 [21059] = 0xDC40, /* R21059 - VSS_XTD24_0 */
713 [21060] = 0x00FC, /* R21060 - VSS_XTD25_1 */
714 [21061] = 0x9D00, /* R21061 - VSS_XTD25_0 */
715 [21062] = 0x0009, /* R21062 - VSS_XTD26_1 */
716 [21063] = 0x5580, /* R21063 - VSS_XTD26_0 */
717 [21064] = 0x00FE, /* R21064 - VSS_XTD27_1 */
718 [21065] = 0x7E80, /* R21065 - VSS_XTD27_0 */
719 [21066] = 0x000E, /* R21066 - VSS_XTD28_1 */
720 [21067] = 0xAB40, /* R21067 - VSS_XTD28_0 */
721 [21068] = 0x00F9, /* R21068 - VSS_XTD29_1 */
722 [21069] = 0x9880, /* R21069 - VSS_XTD29_0 */
723 [21070] = 0x0009, /* R21070 - VSS_XTD30_1 */
724 [21071] = 0x87C0, /* R21071 - VSS_XTD30_0 */
725 [21072] = 0x00FD, /* R21072 - VSS_XTD31_1 */
726 [21073] = 0x2C40, /* R21073 - VSS_XTD31_0 */
727 [21074] = 0x0009, /* R21074 - VSS_XTD32_1 */
728 [21075] = 0x4800, /* R21075 - VSS_XTD32_0 */
729 [21076] = 0x0003, /* R21076 - VSS_XTS1_1 */
730 [21077] = 0x5F40, /* R21077 - VSS_XTS1_0 */
731 [21078] = 0x0000, /* R21078 - VSS_XTS2_1 */
732 [21079] = 0x8700, /* R21079 - VSS_XTS2_0 */
733 [21080] = 0x00FA, /* R21080 - VSS_XTS3_1 */
734 [21081] = 0xE4C0, /* R21081 - VSS_XTS3_0 */
735 [21082] = 0x0000, /* R21082 - VSS_XTS4_1 */
736 [21083] = 0x0B40, /* R21083 - VSS_XTS4_0 */
737 [21084] = 0x0004, /* R21084 - VSS_XTS5_1 */
738 [21085] = 0xE180, /* R21085 - VSS_XTS5_0 */
739 [21086] = 0x0001, /* R21086 - VSS_XTS6_1 */
740 [21087] = 0x1F40, /* R21087 - VSS_XTS6_0 */
741 [21088] = 0x00F8, /* R21088 - VSS_XTS7_1 */
742 [21089] = 0xB000, /* R21089 - VSS_XTS7_0 */
743 [21090] = 0x00FB, /* R21090 - VSS_XTS8_1 */
744 [21091] = 0xCBC0, /* R21091 - VSS_XTS8_0 */
745 [21092] = 0x0004, /* R21092 - VSS_XTS9_1 */
746 [21093] = 0xF380, /* R21093 - VSS_XTS9_0 */
747 [21094] = 0x0007, /* R21094 - VSS_XTS10_1 */
748 [21095] = 0xDF40, /* R21095 - VSS_XTS10_0 */
749 [21096] = 0x00FF, /* R21096 - VSS_XTS11_1 */
750 [21097] = 0x0700, /* R21097 - VSS_XTS11_0 */
751 [21098] = 0x00EF, /* R21098 - VSS_XTS12_1 */
752 [21099] = 0xD700, /* R21099 - VSS_XTS12_0 */
753 [21100] = 0x00FB, /* R21100 - VSS_XTS13_1 */
754 [21101] = 0xAF40, /* R21101 - VSS_XTS13_0 */
755 [21102] = 0x0010, /* R21102 - VSS_XTS14_1 */
756 [21103] = 0x8A80, /* R21103 - VSS_XTS14_0 */
757 [21104] = 0x0011, /* R21104 - VSS_XTS15_1 */
758 [21105] = 0x07C0, /* R21105 - VSS_XTS15_0 */
759 [21106] = 0x00E0, /* R21106 - VSS_XTS16_1 */
760 [21107] = 0x0800, /* R21107 - VSS_XTS16_0 */
761 [21108] = 0x00D2, /* R21108 - VSS_XTS17_1 */
762 [21109] = 0x7600, /* R21109 - VSS_XTS17_0 */
763 [21110] = 0x0020, /* R21110 - VSS_XTS18_1 */
764 [21111] = 0xCF40, /* R21111 - VSS_XTS18_0 */
765 [21112] = 0x0030, /* R21112 - VSS_XTS19_1 */
766 [21113] = 0x2340, /* R21113 - VSS_XTS19_0 */
767 [21114] = 0x00FD, /* R21114 - VSS_XTS20_1 */
768 [21115] = 0x69C0, /* R21115 - VSS_XTS20_0 */
769 [21116] = 0x0028, /* R21116 - VSS_XTS21_1 */
770 [21117] = 0x3500, /* R21117 - VSS_XTS21_0 */
771 [21118] = 0x0006, /* R21118 - VSS_XTS22_1 */
772 [21119] = 0x3300, /* R21119 - VSS_XTS22_0 */
773 [21120] = 0x00D9, /* R21120 - VSS_XTS23_1 */
774 [21121] = 0xF6C0, /* R21121 - VSS_XTS23_0 */
775 [21122] = 0x00F3, /* R21122 - VSS_XTS24_1 */
776 [21123] = 0x3340, /* R21123 - VSS_XTS24_0 */
777 [21124] = 0x000F, /* R21124 - VSS_XTS25_1 */
778 [21125] = 0x4200, /* R21125 - VSS_XTS25_0 */
779 [21126] = 0x0004, /* R21126 - VSS_XTS26_1 */
780 [21127] = 0x0C80, /* R21127 - VSS_XTS26_0 */
781 [21128] = 0x00FB, /* R21128 - VSS_XTS27_1 */
782 [21129] = 0x3F80, /* R21129 - VSS_XTS27_0 */
783 [21130] = 0x00F7, /* R21130 - VSS_XTS28_1 */
784 [21131] = 0x57C0, /* R21131 - VSS_XTS28_0 */
785 [21132] = 0x0003, /* R21132 - VSS_XTS29_1 */
786 [21133] = 0x5400, /* R21133 - VSS_XTS29_0 */
787 [21134] = 0x0000, /* R21134 - VSS_XTS30_1 */
788 [21135] = 0xC6C0, /* R21135 - VSS_XTS30_0 */
789 [21136] = 0x0003, /* R21136 - VSS_XTS31_1 */
790 [21137] = 0x12C0, /* R21137 - VSS_XTS31_0 */
791 [21138] = 0x00FD, /* R21138 - VSS_XTS32_1 */
792 [21139] = 0x8580, /* R21139 - VSS_XTS32_0 */
793};
794
795static const struct wm8962_reg_access {
796 u16 read;
797 u16 write;
798 u16 vol;
799} wm8962_reg_access[WM8962_MAX_REGISTER + 1] = {
800 [0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0 - Left Input volume */
801 [1] = { 0xFEFF, 0x01FF, 0xFFFF }, /* R1 - Right Input volume */
802 [2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2 - HPOUTL volume */
803 [3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3 - HPOUTR volume */
804 [4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4 - Clocking1 */
805 [5] = { 0x007F, 0x007F, 0x0000 }, /* R5 - ADC & DAC Control 1 */
806 [6] = { 0x37ED, 0x37ED, 0x0000 }, /* R6 - ADC & DAC Control 2 */
807 [7] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R7 - Audio Interface 0 */
808 [8] = { 0x0FEF, 0x0FEF, 0xFFFF }, /* R8 - Clocking2 */
809 [9] = { 0x0B9F, 0x039F, 0x0000 }, /* R9 - Audio Interface 1 */
810 [10] = { 0x00FF, 0x01FF, 0x0000 }, /* R10 - Left DAC volume */
811 [11] = { 0x00FF, 0x01FF, 0x0000 }, /* R11 - Right DAC volume */
812 [14] = { 0x07FF, 0x07FF, 0x0000 }, /* R14 - Audio Interface 2 */
813 [15] = { 0xFFFF, 0xFFFF, 0xFFFF }, /* R15 - Software Reset */
814 [17] = { 0x07FF, 0x07FF, 0x0000 }, /* R17 - ALC1 */
815 [18] = { 0xF8FF, 0x00FF, 0xFFFF }, /* R18 - ALC2 */
816 [19] = { 0x1DFF, 0x1DFF, 0x0000 }, /* R19 - ALC3 */
817 [20] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20 - Noise Gate */
818 [21] = { 0x00FF, 0x01FF, 0x0000 }, /* R21 - Left ADC volume */
819 [22] = { 0x00FF, 0x01FF, 0x0000 }, /* R22 - Right ADC volume */
820 [23] = { 0x0161, 0x0161, 0x0000 }, /* R23 - Additional control(1) */
821 [24] = { 0x0008, 0x0008, 0x0000 }, /* R24 - Additional control(2) */
822 [25] = { 0x07FE, 0x07FE, 0x0000 }, /* R25 - Pwr Mgmt (1) */
823 [26] = { 0x01FB, 0x01FB, 0x0000 }, /* R26 - Pwr Mgmt (2) */
824 [27] = { 0x0017, 0x0017, 0x0000 }, /* R27 - Additional Control (3) */
825 [28] = { 0x001C, 0x001C, 0x0000 }, /* R28 - Anti-pop */
826
827 [30] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R30 - Clocking 3 */
828 [31] = { 0x000F, 0x000F, 0x0000 }, /* R31 - Input mixer control (1) */
829 [32] = { 0x01FF, 0x01FF, 0x0000 }, /* R32 - Left input mixer volume */
830 [33] = { 0x01FF, 0x01FF, 0x0000 }, /* R33 - Right input mixer volume */
831 [34] = { 0x003F, 0x003F, 0x0000 }, /* R34 - Input mixer control (2) */
832 [35] = { 0x003F, 0x003F, 0x0000 }, /* R35 - Input bias control */
833 [37] = { 0x001F, 0x001F, 0x0000 }, /* R37 - Left input PGA control */
834 [38] = { 0x001F, 0x001F, 0x0000 }, /* R38 - Right input PGA control */
835 [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */
836 [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */
837
838 [47] = { 0x000F, 0x0000, 0x0000 }, /* R47 - Thermal Shutdown Status */
839 [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */
840 [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */
841 [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */
842 [56] = { 0x001E, 0x001E, 0x0000 }, /* R56 - Clocking 4 */
843 [57] = { 0x02FC, 0x02FC, 0x0000 }, /* R57 - DAC DSP Mixing (1) */
844 [58] = { 0x00FC, 0x00FC, 0x0000 }, /* R58 - DAC DSP Mixing (2) */
845 [60] = { 0x00CC, 0x00CC, 0x0000 }, /* R60 - DC Servo 0 */
846 [61] = { 0x00DD, 0x00DD, 0x0000 }, /* R61 - DC Servo 1 */
847 [64] = { 0x3F80, 0x3F80, 0x0000 }, /* R64 - DC Servo 4 */
848 [66] = { 0x0780, 0x0000, 0xFFFF }, /* R66 - DC Servo 6 */
849 [68] = { 0x0007, 0x0007, 0x0000 }, /* R68 - Analogue PGA Bias */
850 [69] = { 0x00FF, 0x00FF, 0x0000 }, /* R69 - Analogue HP 0 */
851 [71] = { 0x01FF, 0x01FF, 0x0000 }, /* R71 - Analogue HP 2 */
852 [72] = { 0x0001, 0x0001, 0x0000 }, /* R72 - Charge Pump 1 */
853 [82] = { 0x0001, 0x0001, 0x0000 }, /* R82 - Charge Pump B */
854 [87] = { 0x00A0, 0x00A0, 0x0000 }, /* R87 - Write Sequencer Control 1 */
855 [90] = { 0x007F, 0x01FF, 0x0000 }, /* R90 - Write Sequencer Control 2 */
856 [93] = { 0x03F9, 0x0000, 0x0000 }, /* R93 - Write Sequencer Control 3 */
857 [94] = { 0x0070, 0x0070, 0x0000 }, /* R94 - Control Interface */
858 [99] = { 0x000F, 0x000F, 0x0000 }, /* R99 - Mixer Enables */
859 [100] = { 0x00BF, 0x00BF, 0x0000 }, /* R100 - Headphone Mixer (1) */
860 [101] = { 0x00BF, 0x00BF, 0x0000 }, /* R101 - Headphone Mixer (2) */
861 [102] = { 0x01FF, 0x01FF, 0x0000 }, /* R102 - Headphone Mixer (3) */
862 [103] = { 0x01FF, 0x01FF, 0x0000 }, /* R103 - Headphone Mixer (4) */
863 [105] = { 0x00BF, 0x00BF, 0x0000 }, /* R105 - Speaker Mixer (1) */
864 [106] = { 0x00BF, 0x00BF, 0x0000 }, /* R106 - Speaker Mixer (2) */
865 [107] = { 0x01FF, 0x01FF, 0x0000 }, /* R107 - Speaker Mixer (3) */
866 [108] = { 0x01FF, 0x01FF, 0x0000 }, /* R108 - Speaker Mixer (4) */
867 [109] = { 0x00F0, 0x00F0, 0x0000 }, /* R109 - Speaker Mixer (5) */
868 [110] = { 0x00F7, 0x00F7, 0x0000 }, /* R110 - Beep Generator (1) */
869 [115] = { 0x001F, 0x001F, 0x0000 }, /* R115 - Oscillator Trim (3) */
870 [116] = { 0x001F, 0x001F, 0x0000 }, /* R116 - Oscillator Trim (4) */
871 [119] = { 0x00FF, 0x00FF, 0x0000 }, /* R119 - Oscillator Trim (7) */
872 [124] = { 0x0079, 0x0079, 0x0000 }, /* R124 - Analogue Clocking1 */
873 [125] = { 0x00DF, 0x00DF, 0x0000 }, /* R125 - Analogue Clocking2 */
874 [126] = { 0x000D, 0x000D, 0x0000 }, /* R126 - Analogue Clocking3 */
875 [127] = { 0x0000, 0xFFFF, 0x0000 }, /* R127 - PLL Software Reset */
876 [129] = { 0x00B0, 0x00B0, 0x0000 }, /* R129 - PLL2 */
877 [131] = { 0x0003, 0x0003, 0x0000 }, /* R131 - PLL 4 */
878 [136] = { 0x005F, 0x005F, 0x0000 }, /* R136 - PLL 9 */
879 [137] = { 0x00FF, 0x00FF, 0x0000 }, /* R137 - PLL 10 */
880 [138] = { 0x00FF, 0x00FF, 0x0000 }, /* R138 - PLL 11 */
881 [139] = { 0x00FF, 0x00FF, 0x0000 }, /* R139 - PLL 12 */
882 [140] = { 0x005F, 0x005F, 0x0000 }, /* R140 - PLL 13 */
883 [141] = { 0x00FF, 0x00FF, 0x0000 }, /* R141 - PLL 14 */
884 [142] = { 0x00FF, 0x00FF, 0x0000 }, /* R142 - PLL 15 */
885 [143] = { 0x00FF, 0x00FF, 0x0000 }, /* R143 - PLL 16 */
886 [155] = { 0x0067, 0x0067, 0x0000 }, /* R155 - FLL Control (1) */
887 [156] = { 0x01FB, 0x01FB, 0x0000 }, /* R156 - FLL Control (2) */
888 [157] = { 0x0007, 0x0007, 0x0000 }, /* R157 - FLL Control (3) */
889 [159] = { 0x007F, 0x007F, 0x0000 }, /* R159 - FLL Control (5) */
890 [160] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R160 - FLL Control (6) */
891 [161] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R161 - FLL Control (7) */
892 [162] = { 0x03FF, 0x03FF, 0x0000 }, /* R162 - FLL Control (8) */
893 [252] = { 0x0005, 0x0005, 0x0000 }, /* R252 - General test 1 */
894 [256] = { 0x000F, 0x000F, 0x0000 }, /* R256 - DF1 */
895 [257] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R257 - DF2 */
896 [258] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R258 - DF3 */
897 [259] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R259 - DF4 */
898 [260] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R260 - DF5 */
899 [261] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R261 - DF6 */
900 [262] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R262 - DF7 */
901 [264] = { 0x0003, 0x0003, 0x0000 }, /* R264 - LHPF1 */
902 [265] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R265 - LHPF2 */
903 [268] = { 0x0077, 0x0077, 0x0000 }, /* R268 - THREED1 */
904 [269] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R269 - THREED2 */
905 [270] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R270 - THREED3 */
906 [271] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R271 - THREED4 */
907 [276] = { 0x7FFF, 0x7FFF, 0x0000 }, /* R276 - DRC 1 */
908 [277] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R277 - DRC 2 */
909 [278] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R278 - DRC 3 */
910 [279] = { 0x07FF, 0x07FF, 0x0000 }, /* R279 - DRC 4 */
911 [280] = { 0x03FF, 0x03FF, 0x0000 }, /* R280 - DRC 5 */
912 [285] = { 0x0003, 0x0003, 0x0000 }, /* R285 - Tloopback */
913 [335] = { 0x0007, 0x0007, 0x0000 }, /* R335 - EQ1 */
914 [336] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R336 - EQ2 */
915 [337] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R337 - EQ3 */
916 [338] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R338 - EQ4 */
917 [339] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R339 - EQ5 */
918 [340] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R340 - EQ6 */
919 [341] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R341 - EQ7 */
920 [342] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R342 - EQ8 */
921 [343] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R343 - EQ9 */
922 [344] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R344 - EQ10 */
923 [345] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R345 - EQ11 */
924 [346] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R346 - EQ12 */
925 [347] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R347 - EQ13 */
926 [348] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R348 - EQ14 */
927 [349] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R349 - EQ15 */
928 [350] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R350 - EQ16 */
929 [351] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R351 - EQ17 */
930 [352] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R352 - EQ18 */
931 [353] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R353 - EQ19 */
932 [354] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R354 - EQ20 */
933 [355] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R355 - EQ21 */
934 [356] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R356 - EQ22 */
935 [357] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R357 - EQ23 */
936 [358] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R358 - EQ24 */
937 [359] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R359 - EQ25 */
938 [360] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R360 - EQ26 */
939 [361] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R361 - EQ27 */
940 [362] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R362 - EQ28 */
941 [363] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R363 - EQ29 */
942 [364] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R364 - EQ30 */
943 [365] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R365 - EQ31 */
944 [366] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R366 - EQ32 */
945 [367] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R367 - EQ33 */
946 [368] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R368 - EQ34 */
947 [369] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R369 - EQ35 */
948 [370] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R370 - EQ36 */
949 [371] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R371 - EQ37 */
950 [372] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R372 - EQ38 */
951 [373] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R373 - EQ39 */
952 [374] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R374 - EQ40 */
953 [375] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R375 - EQ41 */
954 [513] = { 0x045F, 0x045F, 0x0000 }, /* R513 - GPIO 2 */
955 [514] = { 0x045F, 0x045F, 0x0000 }, /* R514 - GPIO 3 */
956 [516] = { 0xE75F, 0xE75F, 0x0000 }, /* R516 - GPIO 5 */
957 [517] = { 0xE75F, 0xE75F, 0x0000 }, /* R517 - GPIO 6 */
958 [560] = { 0x0030, 0x0030, 0xFFFF }, /* R560 - Interrupt Status 1 */
959 [561] = { 0xFFED, 0xFFED, 0xFFFF }, /* R561 - Interrupt Status 2 */
960 [568] = { 0x0030, 0x0030, 0x0000 }, /* R568 - Interrupt Status 1 Mask */
961 [569] = { 0xFFED, 0xFFED, 0x0000 }, /* R569 - Interrupt Status 2 Mask */
962 [576] = { 0x0001, 0x0001, 0x0000 }, /* R576 - Interrupt Control */
963 [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */
964 [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */
965 [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */
966 [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037 - DSP2_ExecControl */
967 [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */
968 [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */
969 [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */
970 [4099] = { 0x010F, 0x010F, 0x0000 }, /* R4099 - Write Sequencer 3 */
971 [4100] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4100 - Write Sequencer 4 */
972 [4101] = { 0x00FF, 0x00FF, 0x0000 }, /* R4101 - Write Sequencer 5 */
973 [4102] = { 0x070F, 0x070F, 0x0000 }, /* R4102 - Write Sequencer 6 */
974 [4103] = { 0x010F, 0x010F, 0x0000 }, /* R4103 - Write Sequencer 7 */
975 [4104] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4104 - Write Sequencer 8 */
976 [4105] = { 0x00FF, 0x00FF, 0x0000 }, /* R4105 - Write Sequencer 9 */
977 [4106] = { 0x070F, 0x070F, 0x0000 }, /* R4106 - Write Sequencer 10 */
978 [4107] = { 0x010F, 0x010F, 0x0000 }, /* R4107 - Write Sequencer 11 */
979 [4108] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4108 - Write Sequencer 12 */
980 [4109] = { 0x00FF, 0x00FF, 0x0000 }, /* R4109 - Write Sequencer 13 */
981 [4110] = { 0x070F, 0x070F, 0x0000 }, /* R4110 - Write Sequencer 14 */
982 [4111] = { 0x010F, 0x010F, 0x0000 }, /* R4111 - Write Sequencer 15 */
983 [4112] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4112 - Write Sequencer 16 */
984 [4113] = { 0x00FF, 0x00FF, 0x0000 }, /* R4113 - Write Sequencer 17 */
985 [4114] = { 0x070F, 0x070F, 0x0000 }, /* R4114 - Write Sequencer 18 */
986 [4115] = { 0x010F, 0x010F, 0x0000 }, /* R4115 - Write Sequencer 19 */
987 [4116] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4116 - Write Sequencer 20 */
988 [4117] = { 0x00FF, 0x00FF, 0x0000 }, /* R4117 - Write Sequencer 21 */
989 [4118] = { 0x070F, 0x070F, 0x0000 }, /* R4118 - Write Sequencer 22 */
990 [4119] = { 0x010F, 0x010F, 0x0000 }, /* R4119 - Write Sequencer 23 */
991 [4120] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4120 - Write Sequencer 24 */
992 [4121] = { 0x00FF, 0x00FF, 0x0000 }, /* R4121 - Write Sequencer 25 */
993 [4122] = { 0x070F, 0x070F, 0x0000 }, /* R4122 - Write Sequencer 26 */
994 [4123] = { 0x010F, 0x010F, 0x0000 }, /* R4123 - Write Sequencer 27 */
995 [4124] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4124 - Write Sequencer 28 */
996 [4125] = { 0x00FF, 0x00FF, 0x0000 }, /* R4125 - Write Sequencer 29 */
997 [4126] = { 0x070F, 0x070F, 0x0000 }, /* R4126 - Write Sequencer 30 */
998 [4127] = { 0x010F, 0x010F, 0x0000 }, /* R4127 - Write Sequencer 31 */
999 [4128] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4128 - Write Sequencer 32 */
1000 [4129] = { 0x00FF, 0x00FF, 0x0000 }, /* R4129 - Write Sequencer 33 */
1001 [4130] = { 0x070F, 0x070F, 0x0000 }, /* R4130 - Write Sequencer 34 */
1002 [4131] = { 0x010F, 0x010F, 0x0000 }, /* R4131 - Write Sequencer 35 */
1003 [4132] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4132 - Write Sequencer 36 */
1004 [4133] = { 0x00FF, 0x00FF, 0x0000 }, /* R4133 - Write Sequencer 37 */
1005 [4134] = { 0x070F, 0x070F, 0x0000 }, /* R4134 - Write Sequencer 38 */
1006 [4135] = { 0x010F, 0x010F, 0x0000 }, /* R4135 - Write Sequencer 39 */
1007 [4136] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4136 - Write Sequencer 40 */
1008 [4137] = { 0x00FF, 0x00FF, 0x0000 }, /* R4137 - Write Sequencer 41 */
1009 [4138] = { 0x070F, 0x070F, 0x0000 }, /* R4138 - Write Sequencer 42 */
1010 [4139] = { 0x010F, 0x010F, 0x0000 }, /* R4139 - Write Sequencer 43 */
1011 [4140] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4140 - Write Sequencer 44 */
1012 [4141] = { 0x00FF, 0x00FF, 0x0000 }, /* R4141 - Write Sequencer 45 */
1013 [4142] = { 0x070F, 0x070F, 0x0000 }, /* R4142 - Write Sequencer 46 */
1014 [4143] = { 0x010F, 0x010F, 0x0000 }, /* R4143 - Write Sequencer 47 */
1015 [4144] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4144 - Write Sequencer 48 */
1016 [4145] = { 0x00FF, 0x00FF, 0x0000 }, /* R4145 - Write Sequencer 49 */
1017 [4146] = { 0x070F, 0x070F, 0x0000 }, /* R4146 - Write Sequencer 50 */
1018 [4147] = { 0x010F, 0x010F, 0x0000 }, /* R4147 - Write Sequencer 51 */
1019 [4148] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4148 - Write Sequencer 52 */
1020 [4149] = { 0x00FF, 0x00FF, 0x0000 }, /* R4149 - Write Sequencer 53 */
1021 [4150] = { 0x070F, 0x070F, 0x0000 }, /* R4150 - Write Sequencer 54 */
1022 [4151] = { 0x010F, 0x010F, 0x0000 }, /* R4151 - Write Sequencer 55 */
1023 [4152] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4152 - Write Sequencer 56 */
1024 [4153] = { 0x00FF, 0x00FF, 0x0000 }, /* R4153 - Write Sequencer 57 */
1025 [4154] = { 0x070F, 0x070F, 0x0000 }, /* R4154 - Write Sequencer 58 */
1026 [4155] = { 0x010F, 0x010F, 0x0000 }, /* R4155 - Write Sequencer 59 */
1027 [4156] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4156 - Write Sequencer 60 */
1028 [4157] = { 0x00FF, 0x00FF, 0x0000 }, /* R4157 - Write Sequencer 61 */
1029 [4158] = { 0x070F, 0x070F, 0x0000 }, /* R4158 - Write Sequencer 62 */
1030 [4159] = { 0x010F, 0x010F, 0x0000 }, /* R4159 - Write Sequencer 63 */
1031 [4160] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4160 - Write Sequencer 64 */
1032 [4161] = { 0x00FF, 0x00FF, 0x0000 }, /* R4161 - Write Sequencer 65 */
1033 [4162] = { 0x070F, 0x070F, 0x0000 }, /* R4162 - Write Sequencer 66 */
1034 [4163] = { 0x010F, 0x010F, 0x0000 }, /* R4163 - Write Sequencer 67 */
1035 [4164] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4164 - Write Sequencer 68 */
1036 [4165] = { 0x00FF, 0x00FF, 0x0000 }, /* R4165 - Write Sequencer 69 */
1037 [4166] = { 0x070F, 0x070F, 0x0000 }, /* R4166 - Write Sequencer 70 */
1038 [4167] = { 0x010F, 0x010F, 0x0000 }, /* R4167 - Write Sequencer 71 */
1039 [4168] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4168 - Write Sequencer 72 */
1040 [4169] = { 0x00FF, 0x00FF, 0x0000 }, /* R4169 - Write Sequencer 73 */
1041 [4170] = { 0x070F, 0x070F, 0x0000 }, /* R4170 - Write Sequencer 74 */
1042 [4171] = { 0x010F, 0x010F, 0x0000 }, /* R4171 - Write Sequencer 75 */
1043 [4172] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4172 - Write Sequencer 76 */
1044 [4173] = { 0x00FF, 0x00FF, 0x0000 }, /* R4173 - Write Sequencer 77 */
1045 [4174] = { 0x070F, 0x070F, 0x0000 }, /* R4174 - Write Sequencer 78 */
1046 [4175] = { 0x010F, 0x010F, 0x0000 }, /* R4175 - Write Sequencer 79 */
1047 [4176] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4176 - Write Sequencer 80 */
1048 [4177] = { 0x00FF, 0x00FF, 0x0000 }, /* R4177 - Write Sequencer 81 */
1049 [4178] = { 0x070F, 0x070F, 0x0000 }, /* R4178 - Write Sequencer 82 */
1050 [4179] = { 0x010F, 0x010F, 0x0000 }, /* R4179 - Write Sequencer 83 */
1051 [4180] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4180 - Write Sequencer 84 */
1052 [4181] = { 0x00FF, 0x00FF, 0x0000 }, /* R4181 - Write Sequencer 85 */
1053 [4182] = { 0x070F, 0x070F, 0x0000 }, /* R4182 - Write Sequencer 86 */
1054 [4183] = { 0x010F, 0x010F, 0x0000 }, /* R4183 - Write Sequencer 87 */
1055 [4184] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4184 - Write Sequencer 88 */
1056 [4185] = { 0x00FF, 0x00FF, 0x0000 }, /* R4185 - Write Sequencer 89 */
1057 [4186] = { 0x070F, 0x070F, 0x0000 }, /* R4186 - Write Sequencer 90 */
1058 [4187] = { 0x010F, 0x010F, 0x0000 }, /* R4187 - Write Sequencer 91 */
1059 [4188] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4188 - Write Sequencer 92 */
1060 [4189] = { 0x00FF, 0x00FF, 0x0000 }, /* R4189 - Write Sequencer 93 */
1061 [4190] = { 0x070F, 0x070F, 0x0000 }, /* R4190 - Write Sequencer 94 */
1062 [4191] = { 0x010F, 0x010F, 0x0000 }, /* R4191 - Write Sequencer 95 */
1063 [4192] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4192 - Write Sequencer 96 */
1064 [4193] = { 0x00FF, 0x00FF, 0x0000 }, /* R4193 - Write Sequencer 97 */
1065 [4194] = { 0x070F, 0x070F, 0x0000 }, /* R4194 - Write Sequencer 98 */
1066 [4195] = { 0x010F, 0x010F, 0x0000 }, /* R4195 - Write Sequencer 99 */
1067 [4196] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4196 - Write Sequencer 100 */
1068 [4197] = { 0x00FF, 0x00FF, 0x0000 }, /* R4197 - Write Sequencer 101 */
1069 [4198] = { 0x070F, 0x070F, 0x0000 }, /* R4198 - Write Sequencer 102 */
1070 [4199] = { 0x010F, 0x010F, 0x0000 }, /* R4199 - Write Sequencer 103 */
1071 [4200] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4200 - Write Sequencer 104 */
1072 [4201] = { 0x00FF, 0x00FF, 0x0000 }, /* R4201 - Write Sequencer 105 */
1073 [4202] = { 0x070F, 0x070F, 0x0000 }, /* R4202 - Write Sequencer 106 */
1074 [4203] = { 0x010F, 0x010F, 0x0000 }, /* R4203 - Write Sequencer 107 */
1075 [4204] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4204 - Write Sequencer 108 */
1076 [4205] = { 0x00FF, 0x00FF, 0x0000 }, /* R4205 - Write Sequencer 109 */
1077 [4206] = { 0x070F, 0x070F, 0x0000 }, /* R4206 - Write Sequencer 110 */
1078 [4207] = { 0x010F, 0x010F, 0x0000 }, /* R4207 - Write Sequencer 111 */
1079 [4208] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4208 - Write Sequencer 112 */
1080 [4209] = { 0x00FF, 0x00FF, 0x0000 }, /* R4209 - Write Sequencer 113 */
1081 [4210] = { 0x070F, 0x070F, 0x0000 }, /* R4210 - Write Sequencer 114 */
1082 [4211] = { 0x010F, 0x010F, 0x0000 }, /* R4211 - Write Sequencer 115 */
1083 [4212] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4212 - Write Sequencer 116 */
1084 [4213] = { 0x00FF, 0x00FF, 0x0000 }, /* R4213 - Write Sequencer 117 */
1085 [4214] = { 0x070F, 0x070F, 0x0000 }, /* R4214 - Write Sequencer 118 */
1086 [4215] = { 0x010F, 0x010F, 0x0000 }, /* R4215 - Write Sequencer 119 */
1087 [4216] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4216 - Write Sequencer 120 */
1088 [4217] = { 0x00FF, 0x00FF, 0x0000 }, /* R4217 - Write Sequencer 121 */
1089 [4218] = { 0x070F, 0x070F, 0x0000 }, /* R4218 - Write Sequencer 122 */
1090 [4219] = { 0x010F, 0x010F, 0x0000 }, /* R4219 - Write Sequencer 123 */
1091 [4220] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4220 - Write Sequencer 124 */
1092 [4221] = { 0x00FF, 0x00FF, 0x0000 }, /* R4221 - Write Sequencer 125 */
1093 [4222] = { 0x070F, 0x070F, 0x0000 }, /* R4222 - Write Sequencer 126 */
1094 [4223] = { 0x010F, 0x010F, 0x0000 }, /* R4223 - Write Sequencer 127 */
1095 [4224] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4224 - Write Sequencer 128 */
1096 [4225] = { 0x00FF, 0x00FF, 0x0000 }, /* R4225 - Write Sequencer 129 */
1097 [4226] = { 0x070F, 0x070F, 0x0000 }, /* R4226 - Write Sequencer 130 */
1098 [4227] = { 0x010F, 0x010F, 0x0000 }, /* R4227 - Write Sequencer 131 */
1099 [4228] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4228 - Write Sequencer 132 */
1100 [4229] = { 0x00FF, 0x00FF, 0x0000 }, /* R4229 - Write Sequencer 133 */
1101 [4230] = { 0x070F, 0x070F, 0x0000 }, /* R4230 - Write Sequencer 134 */
1102 [4231] = { 0x010F, 0x010F, 0x0000 }, /* R4231 - Write Sequencer 135 */
1103 [4232] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4232 - Write Sequencer 136 */
1104 [4233] = { 0x00FF, 0x00FF, 0x0000 }, /* R4233 - Write Sequencer 137 */
1105 [4234] = { 0x070F, 0x070F, 0x0000 }, /* R4234 - Write Sequencer 138 */
1106 [4235] = { 0x010F, 0x010F, 0x0000 }, /* R4235 - Write Sequencer 139 */
1107 [4236] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4236 - Write Sequencer 140 */
1108 [4237] = { 0x00FF, 0x00FF, 0x0000 }, /* R4237 - Write Sequencer 141 */
1109 [4238] = { 0x070F, 0x070F, 0x0000 }, /* R4238 - Write Sequencer 142 */
1110 [4239] = { 0x010F, 0x010F, 0x0000 }, /* R4239 - Write Sequencer 143 */
1111 [4240] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4240 - Write Sequencer 144 */
1112 [4241] = { 0x00FF, 0x00FF, 0x0000 }, /* R4241 - Write Sequencer 145 */
1113 [4242] = { 0x070F, 0x070F, 0x0000 }, /* R4242 - Write Sequencer 146 */
1114 [4243] = { 0x010F, 0x010F, 0x0000 }, /* R4243 - Write Sequencer 147 */
1115 [4244] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4244 - Write Sequencer 148 */
1116 [4245] = { 0x00FF, 0x00FF, 0x0000 }, /* R4245 - Write Sequencer 149 */
1117 [4246] = { 0x070F, 0x070F, 0x0000 }, /* R4246 - Write Sequencer 150 */
1118 [4247] = { 0x010F, 0x010F, 0x0000 }, /* R4247 - Write Sequencer 151 */
1119 [4248] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4248 - Write Sequencer 152 */
1120 [4249] = { 0x00FF, 0x00FF, 0x0000 }, /* R4249 - Write Sequencer 153 */
1121 [4250] = { 0x070F, 0x070F, 0x0000 }, /* R4250 - Write Sequencer 154 */
1122 [4251] = { 0x010F, 0x010F, 0x0000 }, /* R4251 - Write Sequencer 155 */
1123 [4252] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4252 - Write Sequencer 156 */
1124 [4253] = { 0x00FF, 0x00FF, 0x0000 }, /* R4253 - Write Sequencer 157 */
1125 [4254] = { 0x070F, 0x070F, 0x0000 }, /* R4254 - Write Sequencer 158 */
1126 [4255] = { 0x010F, 0x010F, 0x0000 }, /* R4255 - Write Sequencer 159 */
1127 [4256] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4256 - Write Sequencer 160 */
1128 [4257] = { 0x00FF, 0x00FF, 0x0000 }, /* R4257 - Write Sequencer 161 */
1129 [4258] = { 0x070F, 0x070F, 0x0000 }, /* R4258 - Write Sequencer 162 */
1130 [4259] = { 0x010F, 0x010F, 0x0000 }, /* R4259 - Write Sequencer 163 */
1131 [4260] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4260 - Write Sequencer 164 */
1132 [4261] = { 0x00FF, 0x00FF, 0x0000 }, /* R4261 - Write Sequencer 165 */
1133 [4262] = { 0x070F, 0x070F, 0x0000 }, /* R4262 - Write Sequencer 166 */
1134 [4263] = { 0x010F, 0x010F, 0x0000 }, /* R4263 - Write Sequencer 167 */
1135 [4264] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4264 - Write Sequencer 168 */
1136 [4265] = { 0x00FF, 0x00FF, 0x0000 }, /* R4265 - Write Sequencer 169 */
1137 [4266] = { 0x070F, 0x070F, 0x0000 }, /* R4266 - Write Sequencer 170 */
1138 [4267] = { 0x010F, 0x010F, 0x0000 }, /* R4267 - Write Sequencer 171 */
1139 [4268] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4268 - Write Sequencer 172 */
1140 [4269] = { 0x00FF, 0x00FF, 0x0000 }, /* R4269 - Write Sequencer 173 */
1141 [4270] = { 0x070F, 0x070F, 0x0000 }, /* R4270 - Write Sequencer 174 */
1142 [4271] = { 0x010F, 0x010F, 0x0000 }, /* R4271 - Write Sequencer 175 */
1143 [4272] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4272 - Write Sequencer 176 */
1144 [4273] = { 0x00FF, 0x00FF, 0x0000 }, /* R4273 - Write Sequencer 177 */
1145 [4274] = { 0x070F, 0x070F, 0x0000 }, /* R4274 - Write Sequencer 178 */
1146 [4275] = { 0x010F, 0x010F, 0x0000 }, /* R4275 - Write Sequencer 179 */
1147 [4276] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4276 - Write Sequencer 180 */
1148 [4277] = { 0x00FF, 0x00FF, 0x0000 }, /* R4277 - Write Sequencer 181 */
1149 [4278] = { 0x070F, 0x070F, 0x0000 }, /* R4278 - Write Sequencer 182 */
1150 [4279] = { 0x010F, 0x010F, 0x0000 }, /* R4279 - Write Sequencer 183 */
1151 [4280] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4280 - Write Sequencer 184 */
1152 [4281] = { 0x00FF, 0x00FF, 0x0000 }, /* R4281 - Write Sequencer 185 */
1153 [4282] = { 0x070F, 0x070F, 0x0000 }, /* R4282 - Write Sequencer 186 */
1154 [4283] = { 0x010F, 0x010F, 0x0000 }, /* R4283 - Write Sequencer 187 */
1155 [4284] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4284 - Write Sequencer 188 */
1156 [4285] = { 0x00FF, 0x00FF, 0x0000 }, /* R4285 - Write Sequencer 189 */
1157 [4286] = { 0x070F, 0x070F, 0x0000 }, /* R4286 - Write Sequencer 190 */
1158 [4287] = { 0x010F, 0x010F, 0x0000 }, /* R4287 - Write Sequencer 191 */
1159 [4288] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4288 - Write Sequencer 192 */
1160 [4289] = { 0x00FF, 0x00FF, 0x0000 }, /* R4289 - Write Sequencer 193 */
1161 [4290] = { 0x070F, 0x070F, 0x0000 }, /* R4290 - Write Sequencer 194 */
1162 [4291] = { 0x010F, 0x010F, 0x0000 }, /* R4291 - Write Sequencer 195 */
1163 [4292] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4292 - Write Sequencer 196 */
1164 [4293] = { 0x00FF, 0x00FF, 0x0000 }, /* R4293 - Write Sequencer 197 */
1165 [4294] = { 0x070F, 0x070F, 0x0000 }, /* R4294 - Write Sequencer 198 */
1166 [4295] = { 0x010F, 0x010F, 0x0000 }, /* R4295 - Write Sequencer 199 */
1167 [4296] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4296 - Write Sequencer 200 */
1168 [4297] = { 0x00FF, 0x00FF, 0x0000 }, /* R4297 - Write Sequencer 201 */
1169 [4298] = { 0x070F, 0x070F, 0x0000 }, /* R4298 - Write Sequencer 202 */
1170 [4299] = { 0x010F, 0x010F, 0x0000 }, /* R4299 - Write Sequencer 203 */
1171 [4300] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4300 - Write Sequencer 204 */
1172 [4301] = { 0x00FF, 0x00FF, 0x0000 }, /* R4301 - Write Sequencer 205 */
1173 [4302] = { 0x070F, 0x070F, 0x0000 }, /* R4302 - Write Sequencer 206 */
1174 [4303] = { 0x010F, 0x010F, 0x0000 }, /* R4303 - Write Sequencer 207 */
1175 [4304] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4304 - Write Sequencer 208 */
1176 [4305] = { 0x00FF, 0x00FF, 0x0000 }, /* R4305 - Write Sequencer 209 */
1177 [4306] = { 0x070F, 0x070F, 0x0000 }, /* R4306 - Write Sequencer 210 */
1178 [4307] = { 0x010F, 0x010F, 0x0000 }, /* R4307 - Write Sequencer 211 */
1179 [4308] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4308 - Write Sequencer 212 */
1180 [4309] = { 0x00FF, 0x00FF, 0x0000 }, /* R4309 - Write Sequencer 213 */
1181 [4310] = { 0x070F, 0x070F, 0x0000 }, /* R4310 - Write Sequencer 214 */
1182 [4311] = { 0x010F, 0x010F, 0x0000 }, /* R4311 - Write Sequencer 215 */
1183 [4312] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4312 - Write Sequencer 216 */
1184 [4313] = { 0x00FF, 0x00FF, 0x0000 }, /* R4313 - Write Sequencer 217 */
1185 [4314] = { 0x070F, 0x070F, 0x0000 }, /* R4314 - Write Sequencer 218 */
1186 [4315] = { 0x010F, 0x010F, 0x0000 }, /* R4315 - Write Sequencer 219 */
1187 [4316] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4316 - Write Sequencer 220 */
1188 [4317] = { 0x00FF, 0x00FF, 0x0000 }, /* R4317 - Write Sequencer 221 */
1189 [4318] = { 0x070F, 0x070F, 0x0000 }, /* R4318 - Write Sequencer 222 */
1190 [4319] = { 0x010F, 0x010F, 0x0000 }, /* R4319 - Write Sequencer 223 */
1191 [4320] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4320 - Write Sequencer 224 */
1192 [4321] = { 0x00FF, 0x00FF, 0x0000 }, /* R4321 - Write Sequencer 225 */
1193 [4322] = { 0x070F, 0x070F, 0x0000 }, /* R4322 - Write Sequencer 226 */
1194 [4323] = { 0x010F, 0x010F, 0x0000 }, /* R4323 - Write Sequencer 227 */
1195 [4324] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4324 - Write Sequencer 228 */
1196 [4325] = { 0x00FF, 0x00FF, 0x0000 }, /* R4325 - Write Sequencer 229 */
1197 [4326] = { 0x070F, 0x070F, 0x0000 }, /* R4326 - Write Sequencer 230 */
1198 [4327] = { 0x010F, 0x010F, 0x0000 }, /* R4327 - Write Sequencer 231 */
1199 [4328] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4328 - Write Sequencer 232 */
1200 [4329] = { 0x00FF, 0x00FF, 0x0000 }, /* R4329 - Write Sequencer 233 */
1201 [4330] = { 0x070F, 0x070F, 0x0000 }, /* R4330 - Write Sequencer 234 */
1202 [4331] = { 0x010F, 0x010F, 0x0000 }, /* R4331 - Write Sequencer 235 */
1203 [4332] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4332 - Write Sequencer 236 */
1204 [4333] = { 0x00FF, 0x00FF, 0x0000 }, /* R4333 - Write Sequencer 237 */
1205 [4334] = { 0x070F, 0x070F, 0x0000 }, /* R4334 - Write Sequencer 238 */
1206 [4335] = { 0x010F, 0x010F, 0x0000 }, /* R4335 - Write Sequencer 239 */
1207 [4336] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4336 - Write Sequencer 240 */
1208 [4337] = { 0x00FF, 0x00FF, 0x0000 }, /* R4337 - Write Sequencer 241 */
1209 [4338] = { 0x070F, 0x070F, 0x0000 }, /* R4338 - Write Sequencer 242 */
1210 [4339] = { 0x010F, 0x010F, 0x0000 }, /* R4339 - Write Sequencer 243 */
1211 [4340] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4340 - Write Sequencer 244 */
1212 [4341] = { 0x00FF, 0x00FF, 0x0000 }, /* R4341 - Write Sequencer 245 */
1213 [4342] = { 0x070F, 0x070F, 0x0000 }, /* R4342 - Write Sequencer 246 */
1214 [4343] = { 0x010F, 0x010F, 0x0000 }, /* R4343 - Write Sequencer 247 */
1215 [4344] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4344 - Write Sequencer 248 */
1216 [4345] = { 0x00FF, 0x00FF, 0x0000 }, /* R4345 - Write Sequencer 249 */
1217 [4346] = { 0x070F, 0x070F, 0x0000 }, /* R4346 - Write Sequencer 250 */
1218 [4347] = { 0x010F, 0x010F, 0x0000 }, /* R4347 - Write Sequencer 251 */
1219 [4348] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4348 - Write Sequencer 252 */
1220 [4349] = { 0x00FF, 0x00FF, 0x0000 }, /* R4349 - Write Sequencer 253 */
1221 [4350] = { 0x070F, 0x070F, 0x0000 }, /* R4350 - Write Sequencer 254 */
1222 [4351] = { 0x010F, 0x010F, 0x0000 }, /* R4351 - Write Sequencer 255 */
1223 [4352] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4352 - Write Sequencer 256 */
1224 [4353] = { 0x00FF, 0x00FF, 0x0000 }, /* R4353 - Write Sequencer 257 */
1225 [4354] = { 0x070F, 0x070F, 0x0000 }, /* R4354 - Write Sequencer 258 */
1226 [4355] = { 0x010F, 0x010F, 0x0000 }, /* R4355 - Write Sequencer 259 */
1227 [4356] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4356 - Write Sequencer 260 */
1228 [4357] = { 0x00FF, 0x00FF, 0x0000 }, /* R4357 - Write Sequencer 261 */
1229 [4358] = { 0x070F, 0x070F, 0x0000 }, /* R4358 - Write Sequencer 262 */
1230 [4359] = { 0x010F, 0x010F, 0x0000 }, /* R4359 - Write Sequencer 263 */
1231 [4360] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4360 - Write Sequencer 264 */
1232 [4361] = { 0x00FF, 0x00FF, 0x0000 }, /* R4361 - Write Sequencer 265 */
1233 [4362] = { 0x070F, 0x070F, 0x0000 }, /* R4362 - Write Sequencer 266 */
1234 [4363] = { 0x010F, 0x010F, 0x0000 }, /* R4363 - Write Sequencer 267 */
1235 [4364] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4364 - Write Sequencer 268 */
1236 [4365] = { 0x00FF, 0x00FF, 0x0000 }, /* R4365 - Write Sequencer 269 */
1237 [4366] = { 0x070F, 0x070F, 0x0000 }, /* R4366 - Write Sequencer 270 */
1238 [4367] = { 0x010F, 0x010F, 0x0000 }, /* R4367 - Write Sequencer 271 */
1239 [4368] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4368 - Write Sequencer 272 */
1240 [4369] = { 0x00FF, 0x00FF, 0x0000 }, /* R4369 - Write Sequencer 273 */
1241 [4370] = { 0x070F, 0x070F, 0x0000 }, /* R4370 - Write Sequencer 274 */
1242 [4371] = { 0x010F, 0x010F, 0x0000 }, /* R4371 - Write Sequencer 275 */
1243 [4372] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4372 - Write Sequencer 276 */
1244 [4373] = { 0x00FF, 0x00FF, 0x0000 }, /* R4373 - Write Sequencer 277 */
1245 [4374] = { 0x070F, 0x070F, 0x0000 }, /* R4374 - Write Sequencer 278 */
1246 [4375] = { 0x010F, 0x010F, 0x0000 }, /* R4375 - Write Sequencer 279 */
1247 [4376] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4376 - Write Sequencer 280 */
1248 [4377] = { 0x00FF, 0x00FF, 0x0000 }, /* R4377 - Write Sequencer 281 */
1249 [4378] = { 0x070F, 0x070F, 0x0000 }, /* R4378 - Write Sequencer 282 */
1250 [4379] = { 0x010F, 0x010F, 0x0000 }, /* R4379 - Write Sequencer 283 */
1251 [4380] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4380 - Write Sequencer 284 */
1252 [4381] = { 0x00FF, 0x00FF, 0x0000 }, /* R4381 - Write Sequencer 285 */
1253 [4382] = { 0x070F, 0x070F, 0x0000 }, /* R4382 - Write Sequencer 286 */
1254 [4383] = { 0x010F, 0x010F, 0x0000 }, /* R4383 - Write Sequencer 287 */
1255 [4384] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4384 - Write Sequencer 288 */
1256 [4385] = { 0x00FF, 0x00FF, 0x0000 }, /* R4385 - Write Sequencer 289 */
1257 [4386] = { 0x070F, 0x070F, 0x0000 }, /* R4386 - Write Sequencer 290 */
1258 [4387] = { 0x010F, 0x010F, 0x0000 }, /* R4387 - Write Sequencer 291 */
1259 [4388] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4388 - Write Sequencer 292 */
1260 [4389] = { 0x00FF, 0x00FF, 0x0000 }, /* R4389 - Write Sequencer 293 */
1261 [4390] = { 0x070F, 0x070F, 0x0000 }, /* R4390 - Write Sequencer 294 */
1262 [4391] = { 0x010F, 0x010F, 0x0000 }, /* R4391 - Write Sequencer 295 */
1263 [4392] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4392 - Write Sequencer 296 */
1264 [4393] = { 0x00FF, 0x00FF, 0x0000 }, /* R4393 - Write Sequencer 297 */
1265 [4394] = { 0x070F, 0x070F, 0x0000 }, /* R4394 - Write Sequencer 298 */
1266 [4395] = { 0x010F, 0x010F, 0x0000 }, /* R4395 - Write Sequencer 299 */
1267 [4396] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4396 - Write Sequencer 300 */
1268 [4397] = { 0x00FF, 0x00FF, 0x0000 }, /* R4397 - Write Sequencer 301 */
1269 [4398] = { 0x070F, 0x070F, 0x0000 }, /* R4398 - Write Sequencer 302 */
1270 [4399] = { 0x010F, 0x010F, 0x0000 }, /* R4399 - Write Sequencer 303 */
1271 [4400] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4400 - Write Sequencer 304 */
1272 [4401] = { 0x00FF, 0x00FF, 0x0000 }, /* R4401 - Write Sequencer 305 */
1273 [4402] = { 0x070F, 0x070F, 0x0000 }, /* R4402 - Write Sequencer 306 */
1274 [4403] = { 0x010F, 0x010F, 0x0000 }, /* R4403 - Write Sequencer 307 */
1275 [4404] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4404 - Write Sequencer 308 */
1276 [4405] = { 0x00FF, 0x00FF, 0x0000 }, /* R4405 - Write Sequencer 309 */
1277 [4406] = { 0x070F, 0x070F, 0x0000 }, /* R4406 - Write Sequencer 310 */
1278 [4407] = { 0x010F, 0x010F, 0x0000 }, /* R4407 - Write Sequencer 311 */
1279 [4408] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4408 - Write Sequencer 312 */
1280 [4409] = { 0x00FF, 0x00FF, 0x0000 }, /* R4409 - Write Sequencer 313 */
1281 [4410] = { 0x070F, 0x070F, 0x0000 }, /* R4410 - Write Sequencer 314 */
1282 [4411] = { 0x010F, 0x010F, 0x0000 }, /* R4411 - Write Sequencer 315 */
1283 [4412] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4412 - Write Sequencer 316 */
1284 [4413] = { 0x00FF, 0x00FF, 0x0000 }, /* R4413 - Write Sequencer 317 */
1285 [4414] = { 0x070F, 0x070F, 0x0000 }, /* R4414 - Write Sequencer 318 */
1286 [4415] = { 0x010F, 0x010F, 0x0000 }, /* R4415 - Write Sequencer 319 */
1287 [4416] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4416 - Write Sequencer 320 */
1288 [4417] = { 0x00FF, 0x00FF, 0x0000 }, /* R4417 - Write Sequencer 321 */
1289 [4418] = { 0x070F, 0x070F, 0x0000 }, /* R4418 - Write Sequencer 322 */
1290 [4419] = { 0x010F, 0x010F, 0x0000 }, /* R4419 - Write Sequencer 323 */
1291 [4420] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4420 - Write Sequencer 324 */
1292 [4421] = { 0x00FF, 0x00FF, 0x0000 }, /* R4421 - Write Sequencer 325 */
1293 [4422] = { 0x070F, 0x070F, 0x0000 }, /* R4422 - Write Sequencer 326 */
1294 [4423] = { 0x010F, 0x010F, 0x0000 }, /* R4423 - Write Sequencer 327 */
1295 [4424] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4424 - Write Sequencer 328 */
1296 [4425] = { 0x00FF, 0x00FF, 0x0000 }, /* R4425 - Write Sequencer 329 */
1297 [4426] = { 0x070F, 0x070F, 0x0000 }, /* R4426 - Write Sequencer 330 */
1298 [4427] = { 0x010F, 0x010F, 0x0000 }, /* R4427 - Write Sequencer 331 */
1299 [4428] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4428 - Write Sequencer 332 */
1300 [4429] = { 0x00FF, 0x00FF, 0x0000 }, /* R4429 - Write Sequencer 333 */
1301 [4430] = { 0x070F, 0x070F, 0x0000 }, /* R4430 - Write Sequencer 334 */
1302 [4431] = { 0x010F, 0x010F, 0x0000 }, /* R4431 - Write Sequencer 335 */
1303 [4432] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4432 - Write Sequencer 336 */
1304 [4433] = { 0x00FF, 0x00FF, 0x0000 }, /* R4433 - Write Sequencer 337 */
1305 [4434] = { 0x070F, 0x070F, 0x0000 }, /* R4434 - Write Sequencer 338 */
1306 [4435] = { 0x010F, 0x010F, 0x0000 }, /* R4435 - Write Sequencer 339 */
1307 [4436] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4436 - Write Sequencer 340 */
1308 [4437] = { 0x00FF, 0x00FF, 0x0000 }, /* R4437 - Write Sequencer 341 */
1309 [4438] = { 0x070F, 0x070F, 0x0000 }, /* R4438 - Write Sequencer 342 */
1310 [4439] = { 0x010F, 0x010F, 0x0000 }, /* R4439 - Write Sequencer 343 */
1311 [4440] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4440 - Write Sequencer 344 */
1312 [4441] = { 0x00FF, 0x00FF, 0x0000 }, /* R4441 - Write Sequencer 345 */
1313 [4442] = { 0x070F, 0x070F, 0x0000 }, /* R4442 - Write Sequencer 346 */
1314 [4443] = { 0x010F, 0x010F, 0x0000 }, /* R4443 - Write Sequencer 347 */
1315 [4444] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4444 - Write Sequencer 348 */
1316 [4445] = { 0x00FF, 0x00FF, 0x0000 }, /* R4445 - Write Sequencer 349 */
1317 [4446] = { 0x070F, 0x070F, 0x0000 }, /* R4446 - Write Sequencer 350 */
1318 [4447] = { 0x010F, 0x010F, 0x0000 }, /* R4447 - Write Sequencer 351 */
1319 [4448] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4448 - Write Sequencer 352 */
1320 [4449] = { 0x00FF, 0x00FF, 0x0000 }, /* R4449 - Write Sequencer 353 */
1321 [4450] = { 0x070F, 0x070F, 0x0000 }, /* R4450 - Write Sequencer 354 */
1322 [4451] = { 0x010F, 0x010F, 0x0000 }, /* R4451 - Write Sequencer 355 */
1323 [4452] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4452 - Write Sequencer 356 */
1324 [4453] = { 0x00FF, 0x00FF, 0x0000 }, /* R4453 - Write Sequencer 357 */
1325 [4454] = { 0x070F, 0x070F, 0x0000 }, /* R4454 - Write Sequencer 358 */
1326 [4455] = { 0x010F, 0x010F, 0x0000 }, /* R4455 - Write Sequencer 359 */
1327 [4456] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4456 - Write Sequencer 360 */
1328 [4457] = { 0x00FF, 0x00FF, 0x0000 }, /* R4457 - Write Sequencer 361 */
1329 [4458] = { 0x070F, 0x070F, 0x0000 }, /* R4458 - Write Sequencer 362 */
1330 [4459] = { 0x010F, 0x010F, 0x0000 }, /* R4459 - Write Sequencer 363 */
1331 [4460] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4460 - Write Sequencer 364 */
1332 [4461] = { 0x00FF, 0x00FF, 0x0000 }, /* R4461 - Write Sequencer 365 */
1333 [4462] = { 0x070F, 0x070F, 0x0000 }, /* R4462 - Write Sequencer 366 */
1334 [4463] = { 0x010F, 0x010F, 0x0000 }, /* R4463 - Write Sequencer 367 */
1335 [4464] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4464 - Write Sequencer 368 */
1336 [4465] = { 0x00FF, 0x00FF, 0x0000 }, /* R4465 - Write Sequencer 369 */
1337 [4466] = { 0x070F, 0x070F, 0x0000 }, /* R4466 - Write Sequencer 370 */
1338 [4467] = { 0x010F, 0x010F, 0x0000 }, /* R4467 - Write Sequencer 371 */
1339 [4468] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4468 - Write Sequencer 372 */
1340 [4469] = { 0x00FF, 0x00FF, 0x0000 }, /* R4469 - Write Sequencer 373 */
1341 [4470] = { 0x070F, 0x070F, 0x0000 }, /* R4470 - Write Sequencer 374 */
1342 [4471] = { 0x010F, 0x010F, 0x0000 }, /* R4471 - Write Sequencer 375 */
1343 [4472] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4472 - Write Sequencer 376 */
1344 [4473] = { 0x00FF, 0x00FF, 0x0000 }, /* R4473 - Write Sequencer 377 */
1345 [4474] = { 0x070F, 0x070F, 0x0000 }, /* R4474 - Write Sequencer 378 */
1346 [4475] = { 0x010F, 0x010F, 0x0000 }, /* R4475 - Write Sequencer 379 */
1347 [4476] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4476 - Write Sequencer 380 */
1348 [4477] = { 0x00FF, 0x00FF, 0x0000 }, /* R4477 - Write Sequencer 381 */
1349 [4478] = { 0x070F, 0x070F, 0x0000 }, /* R4478 - Write Sequencer 382 */
1350 [4479] = { 0x010F, 0x010F, 0x0000 }, /* R4479 - Write Sequencer 383 */
1351 [4480] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4480 - Write Sequencer 384 */
1352 [4481] = { 0x00FF, 0x00FF, 0x0000 }, /* R4481 - Write Sequencer 385 */
1353 [4482] = { 0x070F, 0x070F, 0x0000 }, /* R4482 - Write Sequencer 386 */
1354 [4483] = { 0x010F, 0x010F, 0x0000 }, /* R4483 - Write Sequencer 387 */
1355 [4484] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4484 - Write Sequencer 388 */
1356 [4485] = { 0x00FF, 0x00FF, 0x0000 }, /* R4485 - Write Sequencer 389 */
1357 [4486] = { 0x070F, 0x070F, 0x0000 }, /* R4486 - Write Sequencer 390 */
1358 [4487] = { 0x010F, 0x010F, 0x0000 }, /* R4487 - Write Sequencer 391 */
1359 [4488] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4488 - Write Sequencer 392 */
1360 [4489] = { 0x00FF, 0x00FF, 0x0000 }, /* R4489 - Write Sequencer 393 */
1361 [4490] = { 0x070F, 0x070F, 0x0000 }, /* R4490 - Write Sequencer 394 */
1362 [4491] = { 0x010F, 0x010F, 0x0000 }, /* R4491 - Write Sequencer 395 */
1363 [4492] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4492 - Write Sequencer 396 */
1364 [4493] = { 0x00FF, 0x00FF, 0x0000 }, /* R4493 - Write Sequencer 397 */
1365 [4494] = { 0x070F, 0x070F, 0x0000 }, /* R4494 - Write Sequencer 398 */
1366 [4495] = { 0x010F, 0x010F, 0x0000 }, /* R4495 - Write Sequencer 399 */
1367 [4496] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4496 - Write Sequencer 400 */
1368 [4497] = { 0x00FF, 0x00FF, 0x0000 }, /* R4497 - Write Sequencer 401 */
1369 [4498] = { 0x070F, 0x070F, 0x0000 }, /* R4498 - Write Sequencer 402 */
1370 [4499] = { 0x010F, 0x010F, 0x0000 }, /* R4499 - Write Sequencer 403 */
1371 [4500] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4500 - Write Sequencer 404 */
1372 [4501] = { 0x00FF, 0x00FF, 0x0000 }, /* R4501 - Write Sequencer 405 */
1373 [4502] = { 0x070F, 0x070F, 0x0000 }, /* R4502 - Write Sequencer 406 */
1374 [4503] = { 0x010F, 0x010F, 0x0000 }, /* R4503 - Write Sequencer 407 */
1375 [4504] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4504 - Write Sequencer 408 */
1376 [4505] = { 0x00FF, 0x00FF, 0x0000 }, /* R4505 - Write Sequencer 409 */
1377 [4506] = { 0x070F, 0x070F, 0x0000 }, /* R4506 - Write Sequencer 410 */
1378 [4507] = { 0x010F, 0x010F, 0x0000 }, /* R4507 - Write Sequencer 411 */
1379 [4508] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4508 - Write Sequencer 412 */
1380 [4509] = { 0x00FF, 0x00FF, 0x0000 }, /* R4509 - Write Sequencer 413 */
1381 [4510] = { 0x070F, 0x070F, 0x0000 }, /* R4510 - Write Sequencer 414 */
1382 [4511] = { 0x010F, 0x010F, 0x0000 }, /* R4511 - Write Sequencer 415 */
1383 [4512] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4512 - Write Sequencer 416 */
1384 [4513] = { 0x00FF, 0x00FF, 0x0000 }, /* R4513 - Write Sequencer 417 */
1385 [4514] = { 0x070F, 0x070F, 0x0000 }, /* R4514 - Write Sequencer 418 */
1386 [4515] = { 0x010F, 0x010F, 0x0000 }, /* R4515 - Write Sequencer 419 */
1387 [4516] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4516 - Write Sequencer 420 */
1388 [4517] = { 0x00FF, 0x00FF, 0x0000 }, /* R4517 - Write Sequencer 421 */
1389 [4518] = { 0x070F, 0x070F, 0x0000 }, /* R4518 - Write Sequencer 422 */
1390 [4519] = { 0x010F, 0x010F, 0x0000 }, /* R4519 - Write Sequencer 423 */
1391 [4520] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4520 - Write Sequencer 424 */
1392 [4521] = { 0x00FF, 0x00FF, 0x0000 }, /* R4521 - Write Sequencer 425 */
1393 [4522] = { 0x070F, 0x070F, 0x0000 }, /* R4522 - Write Sequencer 426 */
1394 [4523] = { 0x010F, 0x010F, 0x0000 }, /* R4523 - Write Sequencer 427 */
1395 [4524] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4524 - Write Sequencer 428 */
1396 [4525] = { 0x00FF, 0x00FF, 0x0000 }, /* R4525 - Write Sequencer 429 */
1397 [4526] = { 0x070F, 0x070F, 0x0000 }, /* R4526 - Write Sequencer 430 */
1398 [4527] = { 0x010F, 0x010F, 0x0000 }, /* R4527 - Write Sequencer 431 */
1399 [4528] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4528 - Write Sequencer 432 */
1400 [4529] = { 0x00FF, 0x00FF, 0x0000 }, /* R4529 - Write Sequencer 433 */
1401 [4530] = { 0x070F, 0x070F, 0x0000 }, /* R4530 - Write Sequencer 434 */
1402 [4531] = { 0x010F, 0x010F, 0x0000 }, /* R4531 - Write Sequencer 435 */
1403 [4532] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4532 - Write Sequencer 436 */
1404 [4533] = { 0x00FF, 0x00FF, 0x0000 }, /* R4533 - Write Sequencer 437 */
1405 [4534] = { 0x070F, 0x070F, 0x0000 }, /* R4534 - Write Sequencer 438 */
1406 [4535] = { 0x010F, 0x010F, 0x0000 }, /* R4535 - Write Sequencer 439 */
1407 [4536] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4536 - Write Sequencer 440 */
1408 [4537] = { 0x00FF, 0x00FF, 0x0000 }, /* R4537 - Write Sequencer 441 */
1409 [4538] = { 0x070F, 0x070F, 0x0000 }, /* R4538 - Write Sequencer 442 */
1410 [4539] = { 0x010F, 0x010F, 0x0000 }, /* R4539 - Write Sequencer 443 */
1411 [4540] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4540 - Write Sequencer 444 */
1412 [4541] = { 0x00FF, 0x00FF, 0x0000 }, /* R4541 - Write Sequencer 445 */
1413 [4542] = { 0x070F, 0x070F, 0x0000 }, /* R4542 - Write Sequencer 446 */
1414 [4543] = { 0x010F, 0x010F, 0x0000 }, /* R4543 - Write Sequencer 447 */
1415 [4544] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4544 - Write Sequencer 448 */
1416 [4545] = { 0x00FF, 0x00FF, 0x0000 }, /* R4545 - Write Sequencer 449 */
1417 [4546] = { 0x070F, 0x070F, 0x0000 }, /* R4546 - Write Sequencer 450 */
1418 [4547] = { 0x010F, 0x010F, 0x0000 }, /* R4547 - Write Sequencer 451 */
1419 [4548] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4548 - Write Sequencer 452 */
1420 [4549] = { 0x00FF, 0x00FF, 0x0000 }, /* R4549 - Write Sequencer 453 */
1421 [4550] = { 0x070F, 0x070F, 0x0000 }, /* R4550 - Write Sequencer 454 */
1422 [4551] = { 0x010F, 0x010F, 0x0000 }, /* R4551 - Write Sequencer 455 */
1423 [4552] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4552 - Write Sequencer 456 */
1424 [4553] = { 0x00FF, 0x00FF, 0x0000 }, /* R4553 - Write Sequencer 457 */
1425 [4554] = { 0x070F, 0x070F, 0x0000 }, /* R4554 - Write Sequencer 458 */
1426 [4555] = { 0x010F, 0x010F, 0x0000 }, /* R4555 - Write Sequencer 459 */
1427 [4556] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4556 - Write Sequencer 460 */
1428 [4557] = { 0x00FF, 0x00FF, 0x0000 }, /* R4557 - Write Sequencer 461 */
1429 [4558] = { 0x070F, 0x070F, 0x0000 }, /* R4558 - Write Sequencer 462 */
1430 [4559] = { 0x010F, 0x010F, 0x0000 }, /* R4559 - Write Sequencer 463 */
1431 [4560] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4560 - Write Sequencer 464 */
1432 [4561] = { 0x00FF, 0x00FF, 0x0000 }, /* R4561 - Write Sequencer 465 */
1433 [4562] = { 0x070F, 0x070F, 0x0000 }, /* R4562 - Write Sequencer 466 */
1434 [4563] = { 0x010F, 0x010F, 0x0000 }, /* R4563 - Write Sequencer 467 */
1435 [4564] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4564 - Write Sequencer 468 */
1436 [4565] = { 0x00FF, 0x00FF, 0x0000 }, /* R4565 - Write Sequencer 469 */
1437 [4566] = { 0x070F, 0x070F, 0x0000 }, /* R4566 - Write Sequencer 470 */
1438 [4567] = { 0x010F, 0x010F, 0x0000 }, /* R4567 - Write Sequencer 471 */
1439 [4568] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4568 - Write Sequencer 472 */
1440 [4569] = { 0x00FF, 0x00FF, 0x0000 }, /* R4569 - Write Sequencer 473 */
1441 [4570] = { 0x070F, 0x070F, 0x0000 }, /* R4570 - Write Sequencer 474 */
1442 [4571] = { 0x010F, 0x010F, 0x0000 }, /* R4571 - Write Sequencer 475 */
1443 [4572] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4572 - Write Sequencer 476 */
1444 [4573] = { 0x00FF, 0x00FF, 0x0000 }, /* R4573 - Write Sequencer 477 */
1445 [4574] = { 0x070F, 0x070F, 0x0000 }, /* R4574 - Write Sequencer 478 */
1446 [4575] = { 0x010F, 0x010F, 0x0000 }, /* R4575 - Write Sequencer 479 */
1447 [4576] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4576 - Write Sequencer 480 */
1448 [4577] = { 0x00FF, 0x00FF, 0x0000 }, /* R4577 - Write Sequencer 481 */
1449 [4578] = { 0x070F, 0x070F, 0x0000 }, /* R4578 - Write Sequencer 482 */
1450 [4579] = { 0x010F, 0x010F, 0x0000 }, /* R4579 - Write Sequencer 483 */
1451 [4580] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4580 - Write Sequencer 484 */
1452 [4581] = { 0x00FF, 0x00FF, 0x0000 }, /* R4581 - Write Sequencer 485 */
1453 [4582] = { 0x070F, 0x070F, 0x0000 }, /* R4582 - Write Sequencer 486 */
1454 [4583] = { 0x010F, 0x010F, 0x0000 }, /* R4583 - Write Sequencer 487 */
1455 [4584] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4584 - Write Sequencer 488 */
1456 [4585] = { 0x00FF, 0x00FF, 0x0000 }, /* R4585 - Write Sequencer 489 */
1457 [4586] = { 0x070F, 0x070F, 0x0000 }, /* R4586 - Write Sequencer 490 */
1458 [4587] = { 0x010F, 0x010F, 0x0000 }, /* R4587 - Write Sequencer 491 */
1459 [4588] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4588 - Write Sequencer 492 */
1460 [4589] = { 0x00FF, 0x00FF, 0x0000 }, /* R4589 - Write Sequencer 493 */
1461 [4590] = { 0x070F, 0x070F, 0x0000 }, /* R4590 - Write Sequencer 494 */
1462 [4591] = { 0x010F, 0x010F, 0x0000 }, /* R4591 - Write Sequencer 495 */
1463 [4592] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4592 - Write Sequencer 496 */
1464 [4593] = { 0x00FF, 0x00FF, 0x0000 }, /* R4593 - Write Sequencer 497 */
1465 [4594] = { 0x070F, 0x070F, 0x0000 }, /* R4594 - Write Sequencer 498 */
1466 [4595] = { 0x010F, 0x010F, 0x0000 }, /* R4595 - Write Sequencer 499 */
1467 [4596] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4596 - Write Sequencer 500 */
1468 [4597] = { 0x00FF, 0x00FF, 0x0000 }, /* R4597 - Write Sequencer 501 */
1469 [4598] = { 0x070F, 0x070F, 0x0000 }, /* R4598 - Write Sequencer 502 */
1470 [4599] = { 0x010F, 0x010F, 0x0000 }, /* R4599 - Write Sequencer 503 */
1471 [4600] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4600 - Write Sequencer 504 */
1472 [4601] = { 0x00FF, 0x00FF, 0x0000 }, /* R4601 - Write Sequencer 505 */
1473 [4602] = { 0x070F, 0x070F, 0x0000 }, /* R4602 - Write Sequencer 506 */
1474 [4603] = { 0x010F, 0x010F, 0x0000 }, /* R4603 - Write Sequencer 507 */
1475 [4604] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4604 - Write Sequencer 508 */
1476 [4605] = { 0x00FF, 0x00FF, 0x0000 }, /* R4605 - Write Sequencer 509 */
1477 [4606] = { 0x070F, 0x070F, 0x0000 }, /* R4606 - Write Sequencer 510 */
1478 [4607] = { 0x010F, 0x010F, 0x0000 }, /* R4607 - Write Sequencer 511 */
1479 [8192] = { 0x03FF, 0x03FF, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */
1480 [9216] = { 0x003F, 0x003F, 0x0000 }, /* R9216 - DSP2 Address RAM 2 */
1481 [9217] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */
1482 [9218] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */
1483 [12288] = { 0x00FF, 0x00FF, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */
1484 [12289] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */
1485 [13312] = { 0x00FF, 0x00FF, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */
1486 [13313] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */
1487 [14336] = { 0x00FF, 0x00FF, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */
1488 [14337] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */
1489 [15360] = { 0x07FF, 0x07FF, 0x0000 }, /* R15360 - DSP2 Coeff RAM 0 */
1490 [16384] = { 0x00FF, 0x00FF, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
1491 [16385] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
1492 [16386] = { 0x00FF, 0x00FF, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
1493 [16387] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
1494 [16388] = { 0x00FF, 0x00FF, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */
1495 [16389] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */
1496 [16896] = { 0x00FF, 0x00FF, 0x0000 }, /* R16896 - HDBASS_AI_1 */
1497 [16897] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16897 - HDBASS_AI_0 */
1498 [16898] = { 0x00FF, 0x00FF, 0x0000 }, /* R16898 - HDBASS_AR_1 */
1499 [16899] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16899 - HDBASS_AR_0 */
1500 [16900] = { 0x00FF, 0x00FF, 0x0000 }, /* R16900 - HDBASS_B_1 */
1501 [16901] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16901 - HDBASS_B_0 */
1502 [16902] = { 0x00FF, 0x00FF, 0x0000 }, /* R16902 - HDBASS_K_1 */
1503 [16903] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16903 - HDBASS_K_0 */
1504 [16904] = { 0x00FF, 0x00FF, 0x0000 }, /* R16904 - HDBASS_N1_1 */
1505 [16905] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16905 - HDBASS_N1_0 */
1506 [16906] = { 0x00FF, 0x00FF, 0x0000 }, /* R16906 - HDBASS_N2_1 */
1507 [16907] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16907 - HDBASS_N2_0 */
1508 [16908] = { 0x00FF, 0x00FF, 0x0000 }, /* R16908 - HDBASS_N3_1 */
1509 [16909] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16909 - HDBASS_N3_0 */
1510 [16910] = { 0x00FF, 0x00FF, 0x0000 }, /* R16910 - HDBASS_N4_1 */
1511 [16911] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16911 - HDBASS_N4_0 */
1512 [16912] = { 0x00FF, 0x00FF, 0x0000 }, /* R16912 - HDBASS_N5_1 */
1513 [16913] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16913 - HDBASS_N5_0 */
1514 [16914] = { 0x00FF, 0x00FF, 0x0000 }, /* R16914 - HDBASS_X1_1 */
1515 [16915] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16915 - HDBASS_X1_0 */
1516 [16916] = { 0x00FF, 0x00FF, 0x0000 }, /* R16916 - HDBASS_X2_1 */
1517 [16917] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16917 - HDBASS_X2_0 */
1518 [16918] = { 0x00FF, 0x00FF, 0x0000 }, /* R16918 - HDBASS_X3_1 */
1519 [16919] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16919 - HDBASS_X3_0 */
1520 [16920] = { 0x00FF, 0x00FF, 0x0000 }, /* R16920 - HDBASS_ATK_1 */
1521 [16921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16921 - HDBASS_ATK_0 */
1522 [16922] = { 0x00FF, 0x00FF, 0x0000 }, /* R16922 - HDBASS_DCY_1 */
1523 [16923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16923 - HDBASS_DCY_0 */
1524 [16924] = { 0x00FF, 0x00FF, 0x0000 }, /* R16924 - HDBASS_PG_1 */
1525 [16925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16925 - HDBASS_PG_0 */
1526 [17408] = { 0x00FF, 0x00FF, 0x0000 }, /* R17408 - HPF_C_1 */
1527 [17409] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17409 - HPF_C_0 */
1528 [17920] = { 0x00FF, 0x00FF, 0x0000 }, /* R17920 - ADCL_RETUNE_C1_1 */
1529 [17921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17921 - ADCL_RETUNE_C1_0 */
1530 [17922] = { 0x00FF, 0x00FF, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */
1531 [17923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */
1532 [17924] = { 0x00FF, 0x00FF, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */
1533 [17925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */
1534 [17926] = { 0x00FF, 0x00FF, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */
1535 [17927] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */
1536 [17928] = { 0x00FF, 0x00FF, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */
1537 [17929] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */
1538 [17930] = { 0x00FF, 0x00FF, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */
1539 [17931] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */
1540 [17932] = { 0x00FF, 0x00FF, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */
1541 [17933] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */
1542 [17934] = { 0x00FF, 0x00FF, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */
1543 [17935] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */
1544 [17936] = { 0x00FF, 0x00FF, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */
1545 [17937] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */
1546 [17938] = { 0x00FF, 0x00FF, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */
1547 [17939] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */
1548 [17940] = { 0x00FF, 0x00FF, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */
1549 [17941] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */
1550 [17942] = { 0x00FF, 0x00FF, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */
1551 [17943] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */
1552 [17944] = { 0x00FF, 0x00FF, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */
1553 [17945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */
1554 [17946] = { 0x00FF, 0x00FF, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */
1555 [17947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */
1556 [17948] = { 0x00FF, 0x00FF, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */
1557 [17949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */
1558 [17950] = { 0x00FF, 0x00FF, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */
1559 [17951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */
1560 [17952] = { 0x00FF, 0x00FF, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */
1561 [17953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */
1562 [17954] = { 0x00FF, 0x00FF, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */
1563 [17955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */
1564 [17956] = { 0x00FF, 0x00FF, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */
1565 [17957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */
1566 [17958] = { 0x00FF, 0x00FF, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */
1567 [17959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */
1568 [17960] = { 0x00FF, 0x00FF, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */
1569 [17961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */
1570 [17962] = { 0x00FF, 0x00FF, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */
1571 [17963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */
1572 [17964] = { 0x00FF, 0x00FF, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */
1573 [17965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */
1574 [17966] = { 0x00FF, 0x00FF, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */
1575 [17967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */
1576 [17968] = { 0x00FF, 0x00FF, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */
1577 [17969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */
1578 [17970] = { 0x00FF, 0x00FF, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */
1579 [17971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */
1580 [17972] = { 0x00FF, 0x00FF, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */
1581 [17973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */
1582 [17974] = { 0x00FF, 0x00FF, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */
1583 [17975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */
1584 [17976] = { 0x00FF, 0x00FF, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */
1585 [17977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */
1586 [17978] = { 0x00FF, 0x00FF, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */
1587 [17979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */
1588 [17980] = { 0x00FF, 0x00FF, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */
1589 [17981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */
1590 [17982] = { 0x00FF, 0x00FF, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */
1591 [17983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */
1592 [18432] = { 0x00FF, 0x00FF, 0x0000 }, /* R18432 - RETUNEADC_PG2_1 */
1593 [18433] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */
1594 [18434] = { 0x00FF, 0x00FF, 0x0000 }, /* R18434 - RETUNEADC_PG_1 */
1595 [18435] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */
1596 [18944] = { 0x00FF, 0x00FF, 0x0000 }, /* R18944 - ADCR_RETUNE_C1_1 */
1597 [18945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18945 - ADCR_RETUNE_C1_0 */
1598 [18946] = { 0x00FF, 0x00FF, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */
1599 [18947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */
1600 [18948] = { 0x00FF, 0x00FF, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */
1601 [18949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */
1602 [18950] = { 0x00FF, 0x00FF, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */
1603 [18951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */
1604 [18952] = { 0x00FF, 0x00FF, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */
1605 [18953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */
1606 [18954] = { 0x00FF, 0x00FF, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */
1607 [18955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */
1608 [18956] = { 0x00FF, 0x00FF, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */
1609 [18957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */
1610 [18958] = { 0x00FF, 0x00FF, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */
1611 [18959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */
1612 [18960] = { 0x00FF, 0x00FF, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */
1613 [18961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */
1614 [18962] = { 0x00FF, 0x00FF, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */
1615 [18963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */
1616 [18964] = { 0x00FF, 0x00FF, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */
1617 [18965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */
1618 [18966] = { 0x00FF, 0x00FF, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */
1619 [18967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */
1620 [18968] = { 0x00FF, 0x00FF, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */
1621 [18969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */
1622 [18970] = { 0x00FF, 0x00FF, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */
1623 [18971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */
1624 [18972] = { 0x00FF, 0x00FF, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */
1625 [18973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */
1626 [18974] = { 0x00FF, 0x00FF, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */
1627 [18975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */
1628 [18976] = { 0x00FF, 0x00FF, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */
1629 [18977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */
1630 [18978] = { 0x00FF, 0x00FF, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */
1631 [18979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */
1632 [18980] = { 0x00FF, 0x00FF, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */
1633 [18981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */
1634 [18982] = { 0x00FF, 0x00FF, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */
1635 [18983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */
1636 [18984] = { 0x00FF, 0x00FF, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */
1637 [18985] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */
1638 [18986] = { 0x00FF, 0x00FF, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */
1639 [18987] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */
1640 [18988] = { 0x00FF, 0x00FF, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */
1641 [18989] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */
1642 [18990] = { 0x00FF, 0x00FF, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */
1643 [18991] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */
1644 [18992] = { 0x00FF, 0x00FF, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */
1645 [18993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */
1646 [18994] = { 0x00FF, 0x00FF, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */
1647 [18995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */
1648 [18996] = { 0x00FF, 0x00FF, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */
1649 [18997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */
1650 [18998] = { 0x00FF, 0x00FF, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */
1651 [18999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */
1652 [19000] = { 0x00FF, 0x00FF, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */
1653 [19001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */
1654 [19002] = { 0x00FF, 0x00FF, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */
1655 [19003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */
1656 [19004] = { 0x00FF, 0x00FF, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */
1657 [19005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */
1658 [19006] = { 0x00FF, 0x00FF, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */
1659 [19007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */
1660 [19456] = { 0x00FF, 0x00FF, 0x0000 }, /* R19456 - DACL_RETUNE_C1_1 */
1661 [19457] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19457 - DACL_RETUNE_C1_0 */
1662 [19458] = { 0x00FF, 0x00FF, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */
1663 [19459] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */
1664 [19460] = { 0x00FF, 0x00FF, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */
1665 [19461] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */
1666 [19462] = { 0x00FF, 0x00FF, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */
1667 [19463] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */
1668 [19464] = { 0x00FF, 0x00FF, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */
1669 [19465] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */
1670 [19466] = { 0x00FF, 0x00FF, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */
1671 [19467] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */
1672 [19468] = { 0x00FF, 0x00FF, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */
1673 [19469] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */
1674 [19470] = { 0x00FF, 0x00FF, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */
1675 [19471] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */
1676 [19472] = { 0x00FF, 0x00FF, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */
1677 [19473] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */
1678 [19474] = { 0x00FF, 0x00FF, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */
1679 [19475] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */
1680 [19476] = { 0x00FF, 0x00FF, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */
1681 [19477] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */
1682 [19478] = { 0x00FF, 0x00FF, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */
1683 [19479] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */
1684 [19480] = { 0x00FF, 0x00FF, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */
1685 [19481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */
1686 [19482] = { 0x00FF, 0x00FF, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */
1687 [19483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */
1688 [19484] = { 0x00FF, 0x00FF, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */
1689 [19485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */
1690 [19486] = { 0x00FF, 0x00FF, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */
1691 [19487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */
1692 [19488] = { 0x00FF, 0x00FF, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */
1693 [19489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */
1694 [19490] = { 0x00FF, 0x00FF, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */
1695 [19491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */
1696 [19492] = { 0x00FF, 0x00FF, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */
1697 [19493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */
1698 [19494] = { 0x00FF, 0x00FF, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */
1699 [19495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */
1700 [19496] = { 0x00FF, 0x00FF, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */
1701 [19497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */
1702 [19498] = { 0x00FF, 0x00FF, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */
1703 [19499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */
1704 [19500] = { 0x00FF, 0x00FF, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */
1705 [19501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */
1706 [19502] = { 0x00FF, 0x00FF, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */
1707 [19503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */
1708 [19504] = { 0x00FF, 0x00FF, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */
1709 [19505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */
1710 [19506] = { 0x00FF, 0x00FF, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */
1711 [19507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */
1712 [19508] = { 0x00FF, 0x00FF, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */
1713 [19509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */
1714 [19510] = { 0x00FF, 0x00FF, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */
1715 [19511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */
1716 [19512] = { 0x00FF, 0x00FF, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */
1717 [19513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */
1718 [19514] = { 0x00FF, 0x00FF, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */
1719 [19515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */
1720 [19516] = { 0x00FF, 0x00FF, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */
1721 [19517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */
1722 [19518] = { 0x00FF, 0x00FF, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */
1723 [19519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */
1724 [19968] = { 0x00FF, 0x00FF, 0x0000 }, /* R19968 - RETUNEDAC_PG2_1 */
1725 [19969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */
1726 [19970] = { 0x00FF, 0x00FF, 0x0000 }, /* R19970 - RETUNEDAC_PG_1 */
1727 [19971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */
1728 [20480] = { 0x00FF, 0x00FF, 0x0000 }, /* R20480 - DACR_RETUNE_C1_1 */
1729 [20481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20481 - DACR_RETUNE_C1_0 */
1730 [20482] = { 0x00FF, 0x00FF, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */
1731 [20483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */
1732 [20484] = { 0x00FF, 0x00FF, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */
1733 [20485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */
1734 [20486] = { 0x00FF, 0x00FF, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */
1735 [20487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */
1736 [20488] = { 0x00FF, 0x00FF, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */
1737 [20489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */
1738 [20490] = { 0x00FF, 0x00FF, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */
1739 [20491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */
1740 [20492] = { 0x00FF, 0x00FF, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */
1741 [20493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */
1742 [20494] = { 0x00FF, 0x00FF, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */
1743 [20495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */
1744 [20496] = { 0x00FF, 0x00FF, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */
1745 [20497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */
1746 [20498] = { 0x00FF, 0x00FF, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */
1747 [20499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */
1748 [20500] = { 0x00FF, 0x00FF, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */
1749 [20501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */
1750 [20502] = { 0x00FF, 0x00FF, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */
1751 [20503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */
1752 [20504] = { 0x00FF, 0x00FF, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */
1753 [20505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */
1754 [20506] = { 0x00FF, 0x00FF, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */
1755 [20507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */
1756 [20508] = { 0x00FF, 0x00FF, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */
1757 [20509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */
1758 [20510] = { 0x00FF, 0x00FF, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */
1759 [20511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */
1760 [20512] = { 0x00FF, 0x00FF, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */
1761 [20513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */
1762 [20514] = { 0x00FF, 0x00FF, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */
1763 [20515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */
1764 [20516] = { 0x00FF, 0x00FF, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */
1765 [20517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */
1766 [20518] = { 0x00FF, 0x00FF, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */
1767 [20519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */
1768 [20520] = { 0x00FF, 0x00FF, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */
1769 [20521] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */
1770 [20522] = { 0x00FF, 0x00FF, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */
1771 [20523] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */
1772 [20524] = { 0x00FF, 0x00FF, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */
1773 [20525] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */
1774 [20526] = { 0x00FF, 0x00FF, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */
1775 [20527] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */
1776 [20528] = { 0x00FF, 0x00FF, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */
1777 [20529] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */
1778 [20530] = { 0x00FF, 0x00FF, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */
1779 [20531] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */
1780 [20532] = { 0x00FF, 0x00FF, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */
1781 [20533] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */
1782 [20534] = { 0x00FF, 0x00FF, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */
1783 [20535] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */
1784 [20536] = { 0x00FF, 0x00FF, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */
1785 [20537] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */
1786 [20538] = { 0x00FF, 0x00FF, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */
1787 [20539] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */
1788 [20540] = { 0x00FF, 0x00FF, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */
1789 [20541] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */
1790 [20542] = { 0x00FF, 0x00FF, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */
1791 [20543] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */
1792 [20992] = { 0x00FF, 0x00FF, 0x0000 }, /* R20992 - VSS_XHD2_1 */
1793 [20993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20993 - VSS_XHD2_0 */
1794 [20994] = { 0x00FF, 0x00FF, 0x0000 }, /* R20994 - VSS_XHD3_1 */
1795 [20995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20995 - VSS_XHD3_0 */
1796 [20996] = { 0x00FF, 0x00FF, 0x0000 }, /* R20996 - VSS_XHN1_1 */
1797 [20997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20997 - VSS_XHN1_0 */
1798 [20998] = { 0x00FF, 0x00FF, 0x0000 }, /* R20998 - VSS_XHN2_1 */
1799 [20999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20999 - VSS_XHN2_0 */
1800 [21000] = { 0x00FF, 0x00FF, 0x0000 }, /* R21000 - VSS_XHN3_1 */
1801 [21001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21001 - VSS_XHN3_0 */
1802 [21002] = { 0x00FF, 0x00FF, 0x0000 }, /* R21002 - VSS_XLA_1 */
1803 [21003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21003 - VSS_XLA_0 */
1804 [21004] = { 0x00FF, 0x00FF, 0x0000 }, /* R21004 - VSS_XLB_1 */
1805 [21005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21005 - VSS_XLB_0 */
1806 [21006] = { 0x00FF, 0x00FF, 0x0000 }, /* R21006 - VSS_XLG_1 */
1807 [21007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21007 - VSS_XLG_0 */
1808 [21008] = { 0x00FF, 0x00FF, 0x0000 }, /* R21008 - VSS_PG2_1 */
1809 [21009] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21009 - VSS_PG2_0 */
1810 [21010] = { 0x00FF, 0x00FF, 0x0000 }, /* R21010 - VSS_PG_1 */
1811 [21011] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21011 - VSS_PG_0 */
1812 [21012] = { 0x00FF, 0x00FF, 0x0000 }, /* R21012 - VSS_XTD1_1 */
1813 [21013] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21013 - VSS_XTD1_0 */
1814 [21014] = { 0x00FF, 0x00FF, 0x0000 }, /* R21014 - VSS_XTD2_1 */
1815 [21015] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21015 - VSS_XTD2_0 */
1816 [21016] = { 0x00FF, 0x00FF, 0x0000 }, /* R21016 - VSS_XTD3_1 */
1817 [21017] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21017 - VSS_XTD3_0 */
1818 [21018] = { 0x00FF, 0x00FF, 0x0000 }, /* R21018 - VSS_XTD4_1 */
1819 [21019] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21019 - VSS_XTD4_0 */
1820 [21020] = { 0x00FF, 0x00FF, 0x0000 }, /* R21020 - VSS_XTD5_1 */
1821 [21021] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21021 - VSS_XTD5_0 */
1822 [21022] = { 0x00FF, 0x00FF, 0x0000 }, /* R21022 - VSS_XTD6_1 */
1823 [21023] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21023 - VSS_XTD6_0 */
1824 [21024] = { 0x00FF, 0x00FF, 0x0000 }, /* R21024 - VSS_XTD7_1 */
1825 [21025] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21025 - VSS_XTD7_0 */
1826 [21026] = { 0x00FF, 0x00FF, 0x0000 }, /* R21026 - VSS_XTD8_1 */
1827 [21027] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21027 - VSS_XTD8_0 */
1828 [21028] = { 0x00FF, 0x00FF, 0x0000 }, /* R21028 - VSS_XTD9_1 */
1829 [21029] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21029 - VSS_XTD9_0 */
1830 [21030] = { 0x00FF, 0x00FF, 0x0000 }, /* R21030 - VSS_XTD10_1 */
1831 [21031] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21031 - VSS_XTD10_0 */
1832 [21032] = { 0x00FF, 0x00FF, 0x0000 }, /* R21032 - VSS_XTD11_1 */
1833 [21033] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21033 - VSS_XTD11_0 */
1834 [21034] = { 0x00FF, 0x00FF, 0x0000 }, /* R21034 - VSS_XTD12_1 */
1835 [21035] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21035 - VSS_XTD12_0 */
1836 [21036] = { 0x00FF, 0x00FF, 0x0000 }, /* R21036 - VSS_XTD13_1 */
1837 [21037] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21037 - VSS_XTD13_0 */
1838 [21038] = { 0x00FF, 0x00FF, 0x0000 }, /* R21038 - VSS_XTD14_1 */
1839 [21039] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21039 - VSS_XTD14_0 */
1840 [21040] = { 0x00FF, 0x00FF, 0x0000 }, /* R21040 - VSS_XTD15_1 */
1841 [21041] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21041 - VSS_XTD15_0 */
1842 [21042] = { 0x00FF, 0x00FF, 0x0000 }, /* R21042 - VSS_XTD16_1 */
1843 [21043] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21043 - VSS_XTD16_0 */
1844 [21044] = { 0x00FF, 0x00FF, 0x0000 }, /* R21044 - VSS_XTD17_1 */
1845 [21045] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21045 - VSS_XTD17_0 */
1846 [21046] = { 0x00FF, 0x00FF, 0x0000 }, /* R21046 - VSS_XTD18_1 */
1847 [21047] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21047 - VSS_XTD18_0 */
1848 [21048] = { 0x00FF, 0x00FF, 0x0000 }, /* R21048 - VSS_XTD19_1 */
1849 [21049] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21049 - VSS_XTD19_0 */
1850 [21050] = { 0x00FF, 0x00FF, 0x0000 }, /* R21050 - VSS_XTD20_1 */
1851 [21051] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21051 - VSS_XTD20_0 */
1852 [21052] = { 0x00FF, 0x00FF, 0x0000 }, /* R21052 - VSS_XTD21_1 */
1853 [21053] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21053 - VSS_XTD21_0 */
1854 [21054] = { 0x00FF, 0x00FF, 0x0000 }, /* R21054 - VSS_XTD22_1 */
1855 [21055] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21055 - VSS_XTD22_0 */
1856 [21056] = { 0x00FF, 0x00FF, 0x0000 }, /* R21056 - VSS_XTD23_1 */
1857 [21057] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21057 - VSS_XTD23_0 */
1858 [21058] = { 0x00FF, 0x00FF, 0x0000 }, /* R21058 - VSS_XTD24_1 */
1859 [21059] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21059 - VSS_XTD24_0 */
1860 [21060] = { 0x00FF, 0x00FF, 0x0000 }, /* R21060 - VSS_XTD25_1 */
1861 [21061] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21061 - VSS_XTD25_0 */
1862 [21062] = { 0x00FF, 0x00FF, 0x0000 }, /* R21062 - VSS_XTD26_1 */
1863 [21063] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21063 - VSS_XTD26_0 */
1864 [21064] = { 0x00FF, 0x00FF, 0x0000 }, /* R21064 - VSS_XTD27_1 */
1865 [21065] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21065 - VSS_XTD27_0 */
1866 [21066] = { 0x00FF, 0x00FF, 0x0000 }, /* R21066 - VSS_XTD28_1 */
1867 [21067] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21067 - VSS_XTD28_0 */
1868 [21068] = { 0x00FF, 0x00FF, 0x0000 }, /* R21068 - VSS_XTD29_1 */
1869 [21069] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21069 - VSS_XTD29_0 */
1870 [21070] = { 0x00FF, 0x00FF, 0x0000 }, /* R21070 - VSS_XTD30_1 */
1871 [21071] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21071 - VSS_XTD30_0 */
1872 [21072] = { 0x00FF, 0x00FF, 0x0000 }, /* R21072 - VSS_XTD31_1 */
1873 [21073] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21073 - VSS_XTD31_0 */
1874 [21074] = { 0x00FF, 0x00FF, 0x0000 }, /* R21074 - VSS_XTD32_1 */
1875 [21075] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21075 - VSS_XTD32_0 */
1876 [21076] = { 0x00FF, 0x00FF, 0x0000 }, /* R21076 - VSS_XTS1_1 */
1877 [21077] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21077 - VSS_XTS1_0 */
1878 [21078] = { 0x00FF, 0x00FF, 0x0000 }, /* R21078 - VSS_XTS2_1 */
1879 [21079] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21079 - VSS_XTS2_0 */
1880 [21080] = { 0x00FF, 0x00FF, 0x0000 }, /* R21080 - VSS_XTS3_1 */
1881 [21081] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21081 - VSS_XTS3_0 */
1882 [21082] = { 0x00FF, 0x00FF, 0x0000 }, /* R21082 - VSS_XTS4_1 */
1883 [21083] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21083 - VSS_XTS4_0 */
1884 [21084] = { 0x00FF, 0x00FF, 0x0000 }, /* R21084 - VSS_XTS5_1 */
1885 [21085] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21085 - VSS_XTS5_0 */
1886 [21086] = { 0x00FF, 0x00FF, 0x0000 }, /* R21086 - VSS_XTS6_1 */
1887 [21087] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21087 - VSS_XTS6_0 */
1888 [21088] = { 0x00FF, 0x00FF, 0x0000 }, /* R21088 - VSS_XTS7_1 */
1889 [21089] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21089 - VSS_XTS7_0 */
1890 [21090] = { 0x00FF, 0x00FF, 0x0000 }, /* R21090 - VSS_XTS8_1 */
1891 [21091] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21091 - VSS_XTS8_0 */
1892 [21092] = { 0x00FF, 0x00FF, 0x0000 }, /* R21092 - VSS_XTS9_1 */
1893 [21093] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21093 - VSS_XTS9_0 */
1894 [21094] = { 0x00FF, 0x00FF, 0x0000 }, /* R21094 - VSS_XTS10_1 */
1895 [21095] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21095 - VSS_XTS10_0 */
1896 [21096] = { 0x00FF, 0x00FF, 0x0000 }, /* R21096 - VSS_XTS11_1 */
1897 [21097] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21097 - VSS_XTS11_0 */
1898 [21098] = { 0x00FF, 0x00FF, 0x0000 }, /* R21098 - VSS_XTS12_1 */
1899 [21099] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21099 - VSS_XTS12_0 */
1900 [21100] = { 0x00FF, 0x00FF, 0x0000 }, /* R21100 - VSS_XTS13_1 */
1901 [21101] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21101 - VSS_XTS13_0 */
1902 [21102] = { 0x00FF, 0x00FF, 0x0000 }, /* R21102 - VSS_XTS14_1 */
1903 [21103] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21103 - VSS_XTS14_0 */
1904 [21104] = { 0x00FF, 0x00FF, 0x0000 }, /* R21104 - VSS_XTS15_1 */
1905 [21105] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21105 - VSS_XTS15_0 */
1906 [21106] = { 0x00FF, 0x00FF, 0x0000 }, /* R21106 - VSS_XTS16_1 */
1907 [21107] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21107 - VSS_XTS16_0 */
1908 [21108] = { 0x00FF, 0x00FF, 0x0000 }, /* R21108 - VSS_XTS17_1 */
1909 [21109] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21109 - VSS_XTS17_0 */
1910 [21110] = { 0x00FF, 0x00FF, 0x0000 }, /* R21110 - VSS_XTS18_1 */
1911 [21111] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21111 - VSS_XTS18_0 */
1912 [21112] = { 0x00FF, 0x00FF, 0x0000 }, /* R21112 - VSS_XTS19_1 */
1913 [21113] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21113 - VSS_XTS19_0 */
1914 [21114] = { 0x00FF, 0x00FF, 0x0000 }, /* R21114 - VSS_XTS20_1 */
1915 [21115] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21115 - VSS_XTS20_0 */
1916 [21116] = { 0x00FF, 0x00FF, 0x0000 }, /* R21116 - VSS_XTS21_1 */
1917 [21117] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21117 - VSS_XTS21_0 */
1918 [21118] = { 0x00FF, 0x00FF, 0x0000 }, /* R21118 - VSS_XTS22_1 */
1919 [21119] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21119 - VSS_XTS22_0 */
1920 [21120] = { 0x00FF, 0x00FF, 0x0000 }, /* R21120 - VSS_XTS23_1 */
1921 [21121] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21121 - VSS_XTS23_0 */
1922 [21122] = { 0x00FF, 0x00FF, 0x0000 }, /* R21122 - VSS_XTS24_1 */
1923 [21123] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21123 - VSS_XTS24_0 */
1924 [21124] = { 0x00FF, 0x00FF, 0x0000 }, /* R21124 - VSS_XTS25_1 */
1925 [21125] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21125 - VSS_XTS25_0 */
1926 [21126] = { 0x00FF, 0x00FF, 0x0000 }, /* R21126 - VSS_XTS26_1 */
1927 [21127] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21127 - VSS_XTS26_0 */
1928 [21128] = { 0x00FF, 0x00FF, 0x0000 }, /* R21128 - VSS_XTS27_1 */
1929 [21129] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21129 - VSS_XTS27_0 */
1930 [21130] = { 0x00FF, 0x00FF, 0x0000 }, /* R21130 - VSS_XTS28_1 */
1931 [21131] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21131 - VSS_XTS28_0 */
1932 [21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */
1933 [21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */
1934 [21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */
1935 [21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */
1936 [21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */
1937 [21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */
1938 [21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */
1939 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
1940};
1941
1942static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
1943{
1944 if (wm8962_reg_access[reg].vol)
1945 return 1;
1946 else
1947 return 0;
1948}
1949
1950static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int reg)
1951{
1952 if (wm8962_reg_access[reg].read)
1953 return 1;
1954 else
1955 return 0;
1956}
1957
1958static int wm8962_reset(struct snd_soc_codec *codec)
1959{
1960 return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
1961}
1962
1963static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
1964static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0);
1965static const unsigned int mixinpga_tlv[] = {
1966 TLV_DB_RANGE_HEAD(7),
1967 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0),
1968 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0),
1969 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0),
1970 5, 5, TLV_DB_SCALE_ITEM(2400, 0, 0),
1971 6, 7, TLV_DB_SCALE_ITEM(2700, 300, 0),
1972};
1973static const DECLARE_TLV_DB_SCALE(beep_tlv, -9600, 600, 1);
1974static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1975static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
1976static const DECLARE_TLV_DB_SCALE(inmix_tlv, -600, 600, 0);
1977static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
1978static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
1979static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0);
1980static const unsigned int classd_tlv[] = {
1981 TLV_DB_RANGE_HEAD(7),
1982 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
1983 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
1984};
1985
1986/* The VU bits for the headphones are in a different register to the mute
1987 * bits and only take effect on the PGA if it is actually powered.
1988 */
1989static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
1990 struct snd_ctl_elem_value *ucontrol)
1991{
1992 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1993 u16 *reg_cache = codec->reg_cache;
1994 int ret;
1995
1996 /* Apply the update (if any) */
1997 ret = snd_soc_put_volsw(kcontrol, ucontrol);
1998 if (ret == 0)
1999 return 0;
2000
2001 /* If the left PGA is enabled hit that VU bit... */
2002 if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTL_PGA_ENA)
2003 return snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
2004 reg_cache[WM8962_HPOUTL_VOLUME]);
2005
2006 /* ...otherwise the right. The VU is stereo. */
2007 if (snd_soc_read(codec, WM8962_PWR_MGMT_2) & WM8962_HPOUTR_PGA_ENA)
2008 return snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
2009 reg_cache[WM8962_HPOUTR_VOLUME]);
2010
2011 return 0;
2012}
2013
2014/* The VU bits for the speakers are in a different register to the mute
2015 * bits and only take effect on the PGA if it is actually powered.
2016 */
2017static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2018 struct snd_ctl_elem_value *ucontrol)
2019{
2020 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2021 u16 *reg_cache = codec->reg_cache;
2022 int ret;
2023
2024 /* Apply the update (if any) */
2025 ret = snd_soc_put_volsw(kcontrol, ucontrol);
2026 if (ret == 0)
2027 return 0;
2028
2029 /* If the left PGA is enabled hit that VU bit... */
2030 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTL_PGA_ENA)
2031 return snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
2032 reg_cache[WM8962_SPKOUTL_VOLUME]);
2033
2034 /* ...otherwise the right. The VU is stereo. */
2035 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTR_PGA_ENA)
2036 return snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
2037 reg_cache[WM8962_SPKOUTR_VOLUME]);
2038
2039 return 0;
2040}
2041
2042static const char *cap_hpf_mode_text[] = {
2043 "Hi-fi", "Application"
2044};
2045
2046static const struct soc_enum cap_hpf_mode =
2047 SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text);
2048
2049static const struct snd_kcontrol_new wm8962_snd_controls[] = {
2050SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
2051
2052SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 6, 7, 0,
2053 mixin_tlv),
2054SOC_SINGLE_TLV("MIXINL PGA Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 3, 7, 0,
2055 mixinpga_tlv),
2056SOC_SINGLE_TLV("MIXINL IN3L Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 0, 7, 0,
2057 mixin_tlv),
2058
2059SOC_SINGLE_TLV("MIXINR IN2R Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 6, 7, 0,
2060 mixin_tlv),
2061SOC_SINGLE_TLV("MIXINR PGA Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 3, 7, 0,
2062 mixinpga_tlv),
2063SOC_SINGLE_TLV("MIXINR IN3R Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 0, 7, 0,
2064 mixin_tlv),
2065
2066SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8962_LEFT_ADC_VOLUME,
2067 WM8962_RIGHT_ADC_VOLUME, 1, 127, 0, digital_tlv),
2068SOC_DOUBLE_R_TLV("Capture Volume", WM8962_LEFT_INPUT_VOLUME,
2069 WM8962_RIGHT_INPUT_VOLUME, 0, 63, 0, inpga_tlv),
2070SOC_DOUBLE_R("Capture Switch", WM8962_LEFT_INPUT_VOLUME,
2071 WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1),
2072SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
2073 WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1),
2074SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1),
2075SOC_ENUM("Capture HPF Mode", cap_hpf_mode),
2076SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0),
2077
2078SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
2079 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
2080
2081SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME,
2082 WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv),
2083SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0),
2084
2085SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1,
2086 5, 1, 0),
2087
2088SOC_SINGLE_TLV("Beep Volume", WM8962_BEEP_GENERATOR_1, 4, 15, 0, beep_tlv),
2089
2090SOC_DOUBLE_R_TLV("Headphone Volume", WM8962_HPOUTL_VOLUME,
2091 WM8962_HPOUTR_VOLUME, 0, 127, 0, out_tlv),
2092SOC_DOUBLE_EXT("Headphone Switch", WM8962_PWR_MGMT_2, 1, 0, 1, 1,
2093 snd_soc_get_volsw, wm8962_put_hp_sw),
2094SOC_DOUBLE_R("Headphone ZC Switch", WM8962_HPOUTL_VOLUME, WM8962_HPOUTR_VOLUME,
2095 7, 1, 0),
2096SOC_DOUBLE_TLV("Headphone Aux Volume", WM8962_ANALOGUE_HP_2, 3, 6, 7, 0,
2097 hp_tlv),
2098
2099SOC_DOUBLE_R("Headphone Mixer Switch", WM8962_HEADPHONE_MIXER_3,
2100 WM8962_HEADPHONE_MIXER_4, 8, 1, 1),
2101
2102SOC_SINGLE_TLV("HPMIXL IN4L Volume", WM8962_HEADPHONE_MIXER_3,
2103 3, 7, 0, bypass_tlv),
2104SOC_SINGLE_TLV("HPMIXL IN4R Volume", WM8962_HEADPHONE_MIXER_3,
2105 0, 7, 0, bypass_tlv),
2106SOC_SINGLE_TLV("HPMIXL MIXINL Volume", WM8962_HEADPHONE_MIXER_3,
2107 7, 1, 1, inmix_tlv),
2108SOC_SINGLE_TLV("HPMIXL MIXINR Volume", WM8962_HEADPHONE_MIXER_3,
2109 6, 1, 1, inmix_tlv),
2110
2111SOC_SINGLE_TLV("HPMIXR IN4L Volume", WM8962_HEADPHONE_MIXER_4,
2112 3, 7, 0, bypass_tlv),
2113SOC_SINGLE_TLV("HPMIXR IN4R Volume", WM8962_HEADPHONE_MIXER_4,
2114 0, 7, 0, bypass_tlv),
2115SOC_SINGLE_TLV("HPMIXR MIXINL Volume", WM8962_HEADPHONE_MIXER_4,
2116 7, 1, 1, inmix_tlv),
2117SOC_SINGLE_TLV("HPMIXR MIXINR Volume", WM8962_HEADPHONE_MIXER_4,
2118 6, 1, 1, inmix_tlv),
2119
2120SOC_SINGLE_TLV("Speaker Boost Volume", WM8962_CLASS_D_CONTROL_2, 0, 7, 0,
2121 classd_tlv),
2122};
2123
2124static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
2125SOC_SINGLE_TLV("Speaker Volume", WM8962_SPKOUTL_VOLUME, 0, 127, 0, out_tlv),
2126SOC_SINGLE_EXT("Speaker Switch", WM8962_CLASS_D_CONTROL_1, 1, 1, 1,
2127 snd_soc_get_volsw, wm8962_put_spk_sw),
2128SOC_SINGLE("Speaker ZC Switch", WM8962_SPKOUTL_VOLUME, 7, 1, 0),
2129
2130SOC_SINGLE("Speaker Mixer Switch", WM8962_SPEAKER_MIXER_3, 8, 1, 1),
2131SOC_SINGLE_TLV("Speaker Mixer IN4L Volume", WM8962_SPEAKER_MIXER_3,
2132 3, 7, 0, bypass_tlv),
2133SOC_SINGLE_TLV("Speaker Mixer IN4R Volume", WM8962_SPEAKER_MIXER_3,
2134 0, 7, 0, bypass_tlv),
2135SOC_SINGLE_TLV("Speaker Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_3,
2136 7, 1, 1, inmix_tlv),
2137SOC_SINGLE_TLV("Speaker Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_3,
2138 6, 1, 1, inmix_tlv),
2139SOC_SINGLE_TLV("Speaker Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
2140 7, 1, 0, inmix_tlv),
2141SOC_SINGLE_TLV("Speaker Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
2142 6, 1, 0, inmix_tlv),
2143};
2144
2145static const struct snd_kcontrol_new wm8962_spk_stereo_controls[] = {
2146SOC_DOUBLE_R_TLV("Speaker Volume", WM8962_SPKOUTL_VOLUME,
2147 WM8962_SPKOUTR_VOLUME, 0, 127, 0, out_tlv),
2148SOC_DOUBLE_EXT("Speaker Switch", WM8962_CLASS_D_CONTROL_1, 1, 0, 1, 1,
2149 snd_soc_get_volsw, wm8962_put_spk_sw),
2150SOC_DOUBLE_R("Speaker ZC Switch", WM8962_SPKOUTL_VOLUME, WM8962_SPKOUTR_VOLUME,
2151 7, 1, 0),
2152
2153SOC_DOUBLE_R("Speaker Mixer Switch", WM8962_SPEAKER_MIXER_3,
2154 WM8962_SPEAKER_MIXER_4, 8, 1, 1),
2155
2156SOC_SINGLE_TLV("SPKOUTL Mixer IN4L Volume", WM8962_SPEAKER_MIXER_3,
2157 3, 7, 0, bypass_tlv),
2158SOC_SINGLE_TLV("SPKOUTL Mixer IN4R Volume", WM8962_SPEAKER_MIXER_3,
2159 0, 7, 0, bypass_tlv),
2160SOC_SINGLE_TLV("SPKOUTL Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_3,
2161 7, 1, 1, inmix_tlv),
2162SOC_SINGLE_TLV("SPKOUTL Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_3,
2163 6, 1, 1, inmix_tlv),
2164SOC_SINGLE_TLV("SPKOUTL Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
2165 7, 1, 0, inmix_tlv),
2166SOC_SINGLE_TLV("SPKOUTL Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
2167 6, 1, 0, inmix_tlv),
2168
2169SOC_SINGLE_TLV("SPKOUTR Mixer IN4L Volume", WM8962_SPEAKER_MIXER_4,
2170 3, 7, 0, bypass_tlv),
2171SOC_SINGLE_TLV("SPKOUTR Mixer IN4R Volume", WM8962_SPEAKER_MIXER_4,
2172 0, 7, 0, bypass_tlv),
2173SOC_SINGLE_TLV("SPKOUTR Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_4,
2174 7, 1, 1, inmix_tlv),
2175SOC_SINGLE_TLV("SPKOUTR Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_4,
2176 6, 1, 1, inmix_tlv),
2177SOC_SINGLE_TLV("SPKOUTR Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
2178 5, 1, 0, inmix_tlv),
2179SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
2180 4, 1, 0, inmix_tlv),
2181};
2182
2183static int sysclk_event(struct snd_soc_dapm_widget *w,
2184 struct snd_kcontrol *kcontrol, int event)
2185{
2186 struct snd_soc_codec *codec = w->codec;
2187 int src;
2188 int fll;
2189
2190 src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
2191
2192 switch (src) {
2193 case 0: /* MCLK */
2194 fll = 0;
2195 break;
2196 case 0x200: /* FLL */
2197 fll = 1;
2198 break;
2199 default:
2200 dev_err(codec->dev, "Unknown SYSCLK source %x\n", src);
2201 return -EINVAL;
2202 }
2203
2204 switch (event) {
2205 case SND_SOC_DAPM_PRE_PMU:
2206 if (fll)
2207 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2208 WM8962_FLL_ENA, WM8962_FLL_ENA);
2209 break;
2210
2211 case SND_SOC_DAPM_POST_PMD:
2212 if (fll)
2213 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
2214 WM8962_FLL_ENA, 0);
2215 break;
2216
2217 default:
2218 BUG();
2219 return -EINVAL;
2220 }
2221
2222 return 0;
2223}
2224
2225static int cp_event(struct snd_soc_dapm_widget *w,
2226 struct snd_kcontrol *kcontrol, int event)
2227{
2228 switch (event) {
2229 case SND_SOC_DAPM_POST_PMU:
2230 msleep(5);
2231 break;
2232
2233 default:
2234 BUG();
2235 return -EINVAL;
2236 }
2237
2238 return 0;
2239}
2240
2241static int hp_event(struct snd_soc_dapm_widget *w,
2242 struct snd_kcontrol *kcontrol, int event)
2243{
2244 struct snd_soc_codec *codec = w->codec;
2245 int timeout;
2246 int reg;
2247 int expected = (WM8962_DCS_STARTUP_DONE_HP1L |
2248 WM8962_DCS_STARTUP_DONE_HP1R);
2249
2250 switch (event) {
2251 case SND_SOC_DAPM_POST_PMU:
2252 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
2253 WM8962_HP1L_ENA | WM8962_HP1R_ENA,
2254 WM8962_HP1L_ENA | WM8962_HP1R_ENA);
2255 udelay(20);
2256
2257 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
2258 WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY,
2259 WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY);
2260
2261 /* Start the DC servo */
2262 snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
2263 WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
2264 WM8962_HP1L_DCS_STARTUP |
2265 WM8962_HP1R_DCS_STARTUP,
2266 WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
2267 WM8962_HP1L_DCS_STARTUP |
2268 WM8962_HP1R_DCS_STARTUP);
2269
2270 /* Wait for it to complete, should be well under 100ms */
2271 timeout = 0;
2272 do {
2273 msleep(1);
2274 reg = snd_soc_read(codec, WM8962_DC_SERVO_6);
2275 if (reg < 0) {
2276 dev_err(codec->dev,
2277 "Failed to read DCS status: %d\n",
2278 reg);
2279 continue;
2280 }
2281 dev_dbg(codec->dev, "DCS status: %x\n", reg);
2282 } while (++timeout < 200 && (reg & expected) != expected);
2283
2284 if ((reg & expected) != expected)
2285 dev_err(codec->dev, "DC servo timed out\n");
2286 else
2287 dev_dbg(codec->dev, "DC servo complete after %dms\n",
2288 timeout);
2289
2290 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
2291 WM8962_HP1L_ENA_OUTP |
2292 WM8962_HP1R_ENA_OUTP,
2293 WM8962_HP1L_ENA_OUTP |
2294 WM8962_HP1R_ENA_OUTP);
2295 udelay(20);
2296
2297 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
2298 WM8962_HP1L_RMV_SHORT |
2299 WM8962_HP1R_RMV_SHORT,
2300 WM8962_HP1L_RMV_SHORT |
2301 WM8962_HP1R_RMV_SHORT);
2302 break;
2303
2304 case SND_SOC_DAPM_PRE_PMD:
2305 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
2306 WM8962_HP1L_RMV_SHORT |
2307 WM8962_HP1R_RMV_SHORT, 0);
2308
2309 udelay(20);
2310
2311 snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
2312 WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
2313 WM8962_HP1L_DCS_STARTUP |
2314 WM8962_HP1R_DCS_STARTUP,
2315 0);
2316
2317 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
2318 WM8962_HP1L_ENA | WM8962_HP1R_ENA |
2319 WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY |
2320 WM8962_HP1L_ENA_OUTP |
2321 WM8962_HP1R_ENA_OUTP, 0);
2322
2323 break;
2324
2325 default:
2326 BUG();
2327 return -EINVAL;
2328
2329 }
2330
2331 return 0;
2332}
2333
2334/* VU bits for the output PGAs only take effect while the PGA is powered */
2335static int out_pga_event(struct snd_soc_dapm_widget *w,
2336 struct snd_kcontrol *kcontrol, int event)
2337{
2338 struct snd_soc_codec *codec = w->codec;
2339 u16 *reg_cache = codec->reg_cache;
2340 int reg;
2341
2342 switch (w->shift) {
2343 case WM8962_HPOUTR_PGA_ENA_SHIFT:
2344 reg = WM8962_HPOUTR_VOLUME;
2345 break;
2346 case WM8962_HPOUTL_PGA_ENA_SHIFT:
2347 reg = WM8962_HPOUTL_VOLUME;
2348 break;
2349 case WM8962_SPKOUTR_PGA_ENA_SHIFT:
2350 reg = WM8962_SPKOUTR_VOLUME;
2351 break;
2352 case WM8962_SPKOUTL_PGA_ENA_SHIFT:
2353 reg = WM8962_SPKOUTL_VOLUME;
2354 break;
2355 default:
2356 BUG();
2357 return -EINVAL;
2358 }
2359
2360 switch (event) {
2361 case SND_SOC_DAPM_POST_PMU:
2362 return snd_soc_write(codec, reg, reg_cache[reg]);
2363 default:
2364 BUG();
2365 return -EINVAL;
2366 }
2367}
2368
2369static const char *st_text[] = { "None", "Right", "Left" };
2370
2371static const struct soc_enum str_enum =
2372 SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text);
2373
2374static const struct snd_kcontrol_new str_mux =
2375 SOC_DAPM_ENUM("Right Sidetone", str_enum);
2376
2377static const struct soc_enum stl_enum =
2378 SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_2, 2, 3, st_text);
2379
2380static const struct snd_kcontrol_new stl_mux =
2381 SOC_DAPM_ENUM("Left Sidetone", stl_enum);
2382
2383static const char *outmux_text[] = { "DAC", "Mixer" };
2384
2385static const struct soc_enum spkoutr_enum =
2386 SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_2, 7, 2, outmux_text);
2387
2388static const struct snd_kcontrol_new spkoutr_mux =
2389 SOC_DAPM_ENUM("SPKOUTR Mux", spkoutr_enum);
2390
2391static const struct soc_enum spkoutl_enum =
2392 SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_1, 7, 2, outmux_text);
2393
2394static const struct snd_kcontrol_new spkoutl_mux =
2395 SOC_DAPM_ENUM("SPKOUTL Mux", spkoutl_enum);
2396
2397static const struct soc_enum hpoutr_enum =
2398 SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_2, 7, 2, outmux_text);
2399
2400static const struct snd_kcontrol_new hpoutr_mux =
2401 SOC_DAPM_ENUM("HPOUTR Mux", hpoutr_enum);
2402
2403static const struct soc_enum hpoutl_enum =
2404 SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_1, 7, 2, outmux_text);
2405
2406static const struct snd_kcontrol_new hpoutl_mux =
2407 SOC_DAPM_ENUM("HPOUTL Mux", hpoutl_enum);
2408
2409static const struct snd_kcontrol_new inpgal[] = {
2410SOC_DAPM_SINGLE("IN1L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 3, 1, 0),
2411SOC_DAPM_SINGLE("IN2L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 2, 1, 0),
2412SOC_DAPM_SINGLE("IN3L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 1, 1, 0),
2413SOC_DAPM_SINGLE("IN4L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 0, 1, 0),
2414};
2415
2416static const struct snd_kcontrol_new inpgar[] = {
2417SOC_DAPM_SINGLE("IN1R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 3, 1, 0),
2418SOC_DAPM_SINGLE("IN2R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 2, 1, 0),
2419SOC_DAPM_SINGLE("IN3R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 1, 1, 0),
2420SOC_DAPM_SINGLE("IN4R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 0, 1, 0),
2421};
2422
2423static const struct snd_kcontrol_new mixinl[] = {
2424SOC_DAPM_SINGLE("IN2L Switch", WM8962_INPUT_MIXER_CONTROL_2, 5, 1, 0),
2425SOC_DAPM_SINGLE("IN3L Switch", WM8962_INPUT_MIXER_CONTROL_2, 4, 1, 0),
2426SOC_DAPM_SINGLE("PGA Switch", WM8962_INPUT_MIXER_CONTROL_2, 3, 1, 0),
2427};
2428
2429static const struct snd_kcontrol_new mixinr[] = {
2430SOC_DAPM_SINGLE("IN2R Switch", WM8962_INPUT_MIXER_CONTROL_2, 2, 1, 0),
2431SOC_DAPM_SINGLE("IN3R Switch", WM8962_INPUT_MIXER_CONTROL_2, 1, 1, 0),
2432SOC_DAPM_SINGLE("PGA Switch", WM8962_INPUT_MIXER_CONTROL_2, 0, 1, 0),
2433};
2434
2435static const struct snd_kcontrol_new hpmixl[] = {
2436SOC_DAPM_SINGLE("DACL Switch", WM8962_HEADPHONE_MIXER_1, 5, 1, 0),
2437SOC_DAPM_SINGLE("DACR Switch", WM8962_HEADPHONE_MIXER_1, 4, 1, 0),
2438SOC_DAPM_SINGLE("MIXINL Switch", WM8962_HEADPHONE_MIXER_1, 3, 1, 0),
2439SOC_DAPM_SINGLE("MIXINR Switch", WM8962_HEADPHONE_MIXER_1, 2, 1, 0),
2440SOC_DAPM_SINGLE("IN4L Switch", WM8962_HEADPHONE_MIXER_1, 1, 1, 0),
2441SOC_DAPM_SINGLE("IN4R Switch", WM8962_HEADPHONE_MIXER_1, 0, 1, 0),
2442};
2443
2444static const struct snd_kcontrol_new hpmixr[] = {
2445SOC_DAPM_SINGLE("DACL Switch", WM8962_HEADPHONE_MIXER_2, 5, 1, 0),
2446SOC_DAPM_SINGLE("DACR Switch", WM8962_HEADPHONE_MIXER_2, 4, 1, 0),
2447SOC_DAPM_SINGLE("MIXINL Switch", WM8962_HEADPHONE_MIXER_2, 3, 1, 0),
2448SOC_DAPM_SINGLE("MIXINR Switch", WM8962_HEADPHONE_MIXER_2, 2, 1, 0),
2449SOC_DAPM_SINGLE("IN4L Switch", WM8962_HEADPHONE_MIXER_2, 1, 1, 0),
2450SOC_DAPM_SINGLE("IN4R Switch", WM8962_HEADPHONE_MIXER_2, 0, 1, 0),
2451};
2452
2453static const struct snd_kcontrol_new spkmixl[] = {
2454SOC_DAPM_SINGLE("DACL Switch", WM8962_SPEAKER_MIXER_1, 5, 1, 0),
2455SOC_DAPM_SINGLE("DACR Switch", WM8962_SPEAKER_MIXER_1, 4, 1, 0),
2456SOC_DAPM_SINGLE("MIXINL Switch", WM8962_SPEAKER_MIXER_1, 3, 1, 0),
2457SOC_DAPM_SINGLE("MIXINR Switch", WM8962_SPEAKER_MIXER_1, 2, 1, 0),
2458SOC_DAPM_SINGLE("IN4L Switch", WM8962_SPEAKER_MIXER_1, 1, 1, 0),
2459SOC_DAPM_SINGLE("IN4R Switch", WM8962_SPEAKER_MIXER_1, 0, 1, 0),
2460};
2461
2462static const struct snd_kcontrol_new spkmixr[] = {
2463SOC_DAPM_SINGLE("DACL Switch", WM8962_SPEAKER_MIXER_2, 5, 1, 0),
2464SOC_DAPM_SINGLE("DACR Switch", WM8962_SPEAKER_MIXER_2, 4, 1, 0),
2465SOC_DAPM_SINGLE("MIXINL Switch", WM8962_SPEAKER_MIXER_2, 3, 1, 0),
2466SOC_DAPM_SINGLE("MIXINR Switch", WM8962_SPEAKER_MIXER_2, 2, 1, 0),
2467SOC_DAPM_SINGLE("IN4L Switch", WM8962_SPEAKER_MIXER_2, 1, 1, 0),
2468SOC_DAPM_SINGLE("IN4R Switch", WM8962_SPEAKER_MIXER_2, 0, 1, 0),
2469};
2470
2471static const struct snd_soc_dapm_widget wm8962_dapm_widgets[] = {
2472SND_SOC_DAPM_INPUT("IN1L"),
2473SND_SOC_DAPM_INPUT("IN1R"),
2474SND_SOC_DAPM_INPUT("IN2L"),
2475SND_SOC_DAPM_INPUT("IN2R"),
2476SND_SOC_DAPM_INPUT("IN3L"),
2477SND_SOC_DAPM_INPUT("IN3R"),
2478SND_SOC_DAPM_INPUT("IN4L"),
2479SND_SOC_DAPM_INPUT("IN4R"),
2480SND_SOC_DAPM_INPUT("Beep"),
2481SND_SOC_DAPM_INPUT("DMICDAT"),
2482
2483SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0),
2484
2485SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
2486SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
2487 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2488SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
2489 SND_SOC_DAPM_POST_PMU),
2490SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
2491
2492SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
2493 inpgal, ARRAY_SIZE(inpgal)),
2494SND_SOC_DAPM_MIXER("INPGAR", WM8962_RIGHT_INPUT_PGA_CONTROL, 4, 0,
2495 inpgar, ARRAY_SIZE(inpgar)),
2496SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
2497 mixinl, ARRAY_SIZE(mixinl)),
2498SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
2499 mixinr, ARRAY_SIZE(mixinr)),
2500
2501SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0),
2502
2503SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
2504SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
2505
2506SND_SOC_DAPM_MUX("STL", SND_SOC_NOPM, 0, 0, &stl_mux),
2507SND_SOC_DAPM_MUX("STR", SND_SOC_NOPM, 0, 0, &str_mux),
2508
2509SND_SOC_DAPM_DAC("DACL", "Playback", WM8962_PWR_MGMT_2, 8, 0),
2510SND_SOC_DAPM_DAC("DACR", "Playback", WM8962_PWR_MGMT_2, 7, 0),
2511
2512SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
2513SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
2514
2515SND_SOC_DAPM_MIXER("HPMIXL", WM8962_MIXER_ENABLES, 3, 0,
2516 hpmixl, ARRAY_SIZE(hpmixl)),
2517SND_SOC_DAPM_MIXER("HPMIXR", WM8962_MIXER_ENABLES, 2, 0,
2518 hpmixr, ARRAY_SIZE(hpmixr)),
2519
2520SND_SOC_DAPM_MUX_E("HPOUTL PGA", WM8962_PWR_MGMT_2, 6, 0, &hpoutl_mux,
2521 out_pga_event, SND_SOC_DAPM_POST_PMU),
2522SND_SOC_DAPM_MUX_E("HPOUTR PGA", WM8962_PWR_MGMT_2, 5, 0, &hpoutr_mux,
2523 out_pga_event, SND_SOC_DAPM_POST_PMU),
2524
2525SND_SOC_DAPM_PGA_E("HPOUT", SND_SOC_NOPM, 0, 0, NULL, 0, hp_event,
2526 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2527
2528SND_SOC_DAPM_OUTPUT("HPOUTL"),
2529SND_SOC_DAPM_OUTPUT("HPOUTR"),
2530};
2531
2532static const struct snd_soc_dapm_widget wm8962_dapm_spk_mono_widgets[] = {
2533SND_SOC_DAPM_MIXER("Speaker Mixer", WM8962_MIXER_ENABLES, 1, 0,
2534 spkmixl, ARRAY_SIZE(spkmixl)),
2535SND_SOC_DAPM_MUX_E("Speaker PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux,
2536 out_pga_event, SND_SOC_DAPM_POST_PMU),
2537SND_SOC_DAPM_PGA("Speaker Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0),
2538SND_SOC_DAPM_OUTPUT("SPKOUT"),
2539};
2540
2541static const struct snd_soc_dapm_widget wm8962_dapm_spk_stereo_widgets[] = {
2542SND_SOC_DAPM_MIXER("SPKOUTL Mixer", WM8962_MIXER_ENABLES, 1, 0,
2543 spkmixl, ARRAY_SIZE(spkmixl)),
2544SND_SOC_DAPM_MIXER("SPKOUTR Mixer", WM8962_MIXER_ENABLES, 0, 0,
2545 spkmixr, ARRAY_SIZE(spkmixr)),
2546
2547SND_SOC_DAPM_MUX_E("SPKOUTL PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux,
2548 out_pga_event, SND_SOC_DAPM_POST_PMU),
2549SND_SOC_DAPM_MUX_E("SPKOUTR PGA", WM8962_PWR_MGMT_2, 3, 0, &spkoutr_mux,
2550 out_pga_event, SND_SOC_DAPM_POST_PMU),
2551
2552SND_SOC_DAPM_PGA("SPKOUTR Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0),
2553SND_SOC_DAPM_PGA("SPKOUTL Output", WM8962_CLASS_D_CONTROL_1, 6, 0, NULL, 0),
2554
2555SND_SOC_DAPM_OUTPUT("SPKOUTL"),
2556SND_SOC_DAPM_OUTPUT("SPKOUTR"),
2557};
2558
2559static const struct snd_soc_dapm_route wm8962_intercon[] = {
2560 { "INPGAL", "IN1L Switch", "IN1L" },
2561 { "INPGAL", "IN2L Switch", "IN2L" },
2562 { "INPGAL", "IN3L Switch", "IN3L" },
2563 { "INPGAL", "IN4L Switch", "IN4L" },
2564
2565 { "INPGAR", "IN1R Switch", "IN1R" },
2566 { "INPGAR", "IN2R Switch", "IN2R" },
2567 { "INPGAR", "IN3R Switch", "IN3R" },
2568 { "INPGAR", "IN4R Switch", "IN4R" },
2569
2570 { "MIXINL", "IN2L Switch", "IN2L" },
2571 { "MIXINL", "IN3L Switch", "IN3L" },
2572 { "MIXINL", "PGA Switch", "INPGAL" },
2573
2574 { "MIXINR", "IN2R Switch", "IN2R" },
2575 { "MIXINR", "IN3R Switch", "IN3R" },
2576 { "MIXINR", "PGA Switch", "INPGAR" },
2577
2578 { "MICBIAS", NULL, "SYSCLK" },
2579
2580 { "DMIC", NULL, "DMICDAT" },
2581
2582 { "ADCL", NULL, "SYSCLK" },
2583 { "ADCL", NULL, "TOCLK" },
2584 { "ADCL", NULL, "MIXINL" },
2585 { "ADCL", NULL, "DMIC" },
2586
2587 { "ADCR", NULL, "SYSCLK" },
2588 { "ADCR", NULL, "TOCLK" },
2589 { "ADCR", NULL, "MIXINR" },
2590 { "ADCR", NULL, "DMIC" },
2591
2592 { "STL", "Left", "ADCL" },
2593 { "STL", "Right", "ADCR" },
2594
2595 { "STR", "Left", "ADCL" },
2596 { "STR", "Right", "ADCR" },
2597
2598 { "DACL", NULL, "SYSCLK" },
2599 { "DACL", NULL, "TOCLK" },
2600 { "DACL", NULL, "Beep" },
2601 { "DACL", NULL, "STL" },
2602
2603 { "DACR", NULL, "SYSCLK" },
2604 { "DACR", NULL, "TOCLK" },
2605 { "DACR", NULL, "Beep" },
2606 { "DACR", NULL, "STR" },
2607
2608 { "HPMIXL", "IN4L Switch", "IN4L" },
2609 { "HPMIXL", "IN4R Switch", "IN4R" },
2610 { "HPMIXL", "DACL Switch", "DACL" },
2611 { "HPMIXL", "DACR Switch", "DACR" },
2612 { "HPMIXL", "MIXINL Switch", "MIXINL" },
2613 { "HPMIXL", "MIXINR Switch", "MIXINR" },
2614
2615 { "HPMIXR", "IN4L Switch", "IN4L" },
2616 { "HPMIXR", "IN4R Switch", "IN4R" },
2617 { "HPMIXR", "DACL Switch", "DACL" },
2618 { "HPMIXR", "DACR Switch", "DACR" },
2619 { "HPMIXR", "MIXINL Switch", "MIXINL" },
2620 { "HPMIXR", "MIXINR Switch", "MIXINR" },
2621
2622 { "Left Bypass", NULL, "HPMIXL" },
2623 { "Left Bypass", NULL, "Class G" },
2624
2625 { "Right Bypass", NULL, "HPMIXR" },
2626 { "Right Bypass", NULL, "Class G" },
2627
2628 { "HPOUTL PGA", "Mixer", "Left Bypass" },
2629 { "HPOUTL PGA", "DAC", "DACL" },
2630
2631 { "HPOUTR PGA", "Mixer", "Right Bypass" },
2632 { "HPOUTR PGA", "DAC", "DACR" },
2633
2634 { "HPOUT", NULL, "HPOUTL PGA" },
2635 { "HPOUT", NULL, "HPOUTR PGA" },
2636 { "HPOUT", NULL, "Charge Pump" },
2637 { "HPOUT", NULL, "SYSCLK" },
2638 { "HPOUT", NULL, "TOCLK" },
2639
2640 { "HPOUTL", NULL, "HPOUT" },
2641 { "HPOUTR", NULL, "HPOUT" },
2642};
2643
2644static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = {
2645 { "Speaker Mixer", "IN4L Switch", "IN4L" },
2646 { "Speaker Mixer", "IN4R Switch", "IN4R" },
2647 { "Speaker Mixer", "DACL Switch", "DACL" },
2648 { "Speaker Mixer", "DACR Switch", "DACR" },
2649 { "Speaker Mixer", "MIXINL Switch", "MIXINL" },
2650 { "Speaker Mixer", "MIXINR Switch", "MIXINR" },
2651
2652 { "Speaker PGA", "Mixer", "Speaker Mixer" },
2653 { "Speaker PGA", "DAC", "DACL" },
2654
2655 { "Speaker Output", NULL, "Speaker PGA" },
2656 { "Speaker Output", NULL, "SYSCLK" },
2657 { "Speaker Output", NULL, "TOCLK" },
2658
2659 { "SPKOUT", NULL, "Speaker Output" },
2660};
2661
2662static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
2663 { "SPKOUTL Mixer", "IN4L Switch", "IN4L" },
2664 { "SPKOUTL Mixer", "IN4R Switch", "IN4R" },
2665 { "SPKOUTL Mixer", "DACL Switch", "DACL" },
2666 { "SPKOUTL Mixer", "DACR Switch", "DACR" },
2667 { "SPKOUTL Mixer", "MIXINL Switch", "MIXINL" },
2668 { "SPKOUTL Mixer", "MIXINR Switch", "MIXINR" },
2669
2670 { "SPKOUTR Mixer", "IN4L Switch", "IN4L" },
2671 { "SPKOUTR Mixer", "IN4R Switch", "IN4R" },
2672 { "SPKOUTR Mixer", "DACL Switch", "DACL" },
2673 { "SPKOUTR Mixer", "DACR Switch", "DACR" },
2674 { "SPKOUTR Mixer", "MIXINL Switch", "MIXINL" },
2675 { "SPKOUTR Mixer", "MIXINR Switch", "MIXINR" },
2676
2677 { "SPKOUTL PGA", "Mixer", "SPKOUTL Mixer" },
2678 { "SPKOUTL PGA", "DAC", "DACL" },
2679
2680 { "SPKOUTR PGA", "Mixer", "SPKOUTR Mixer" },
2681 { "SPKOUTR PGA", "DAC", "DACR" },
2682
2683 { "SPKOUTL Output", NULL, "SPKOUTL PGA" },
2684 { "SPKOUTL Output", NULL, "SYSCLK" },
2685 { "SPKOUTL Output", NULL, "TOCLK" },
2686
2687 { "SPKOUTR Output", NULL, "SPKOUTR PGA" },
2688 { "SPKOUTR Output", NULL, "SYSCLK" },
2689 { "SPKOUTR Output", NULL, "TOCLK" },
2690
2691 { "SPKOUTL", NULL, "SPKOUTL Output" },
2692 { "SPKOUTR", NULL, "SPKOUTR Output" },
2693};
2694
2695static int wm8962_add_widgets(struct snd_soc_codec *codec)
2696{
2697 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
2698 struct snd_soc_dapm_context *dapm = &codec->dapm;
2699
2700 snd_soc_add_controls(codec, wm8962_snd_controls,
2701 ARRAY_SIZE(wm8962_snd_controls));
2702 if (pdata && pdata->spk_mono)
2703 snd_soc_add_controls(codec, wm8962_spk_mono_controls,
2704 ARRAY_SIZE(wm8962_spk_mono_controls));
2705 else
2706 snd_soc_add_controls(codec, wm8962_spk_stereo_controls,
2707 ARRAY_SIZE(wm8962_spk_stereo_controls));
2708
2709
2710 snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets,
2711 ARRAY_SIZE(wm8962_dapm_widgets));
2712 if (pdata && pdata->spk_mono)
2713 snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets,
2714 ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
2715 else
2716 snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets,
2717 ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets));
2718
2719 snd_soc_dapm_add_routes(dapm, wm8962_intercon,
2720 ARRAY_SIZE(wm8962_intercon));
2721 if (pdata && pdata->spk_mono)
2722 snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon,
2723 ARRAY_SIZE(wm8962_spk_mono_intercon));
2724 else
2725 snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon,
2726 ARRAY_SIZE(wm8962_spk_stereo_intercon));
2727
2728
2729 snd_soc_dapm_disable_pin(dapm, "Beep");
2730
2731 return 0;
2732}
2733
2734static void wm8962_sync_cache(struct snd_soc_codec *codec)
2735{
2736 u16 *reg_cache = codec->reg_cache;
2737 int i;
2738
2739 if (!codec->cache_sync)
2740 return;
2741
2742 dev_dbg(codec->dev, "Syncing cache\n");
2743
2744 codec->cache_only = 0;
2745
2746 /* Sync back cached values if they're different from the
2747 * hardware default.
2748 */
2749 for (i = 1; i < codec->driver->reg_cache_size; i++) {
2750 if (i == WM8962_SOFTWARE_RESET)
2751 continue;
2752 if (reg_cache[i] == wm8962_reg[i])
2753 continue;
2754
2755 snd_soc_write(codec, i, reg_cache[i]);
2756 }
2757
2758 codec->cache_sync = 0;
2759}
2760
2761/* -1 for reserved values */
2762static const int bclk_divs[] = {
2763 1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
2764};
2765
2766static void wm8962_configure_bclk(struct snd_soc_codec *codec)
2767{
2768 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2769 int dspclk, i;
2770 int clocking2 = 0;
2771 int aif2 = 0;
2772
2773 if (!wm8962->bclk) {
2774 dev_dbg(codec->dev, "No BCLK rate configured\n");
2775 return;
2776 }
2777
2778 dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
2779 if (dspclk < 0) {
2780 dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
2781 return;
2782 }
2783
2784 dspclk = (dspclk & WM8962_DSPCLK_DIV_MASK) >> WM8962_DSPCLK_DIV_SHIFT;
2785 switch (dspclk) {
2786 case 0:
2787 dspclk = wm8962->sysclk_rate;
2788 break;
2789 case 1:
2790 dspclk = wm8962->sysclk_rate / 2;
2791 break;
2792 case 2:
2793 dspclk = wm8962->sysclk_rate / 4;
2794 break;
2795 default:
2796 dev_warn(codec->dev, "Unknown DSPCLK divisor read back\n");
2797 dspclk = wm8962->sysclk;
2798 }
2799
2800 dev_dbg(codec->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk);
2801
2802 /* We're expecting an exact match */
2803 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
2804 if (bclk_divs[i] < 0)
2805 continue;
2806
2807 if (dspclk / bclk_divs[i] == wm8962->bclk) {
2808 dev_dbg(codec->dev, "Selected BCLK_DIV %d for %dHz\n",
2809 bclk_divs[i], wm8962->bclk);
2810 clocking2 |= i;
2811 break;
2812 }
2813 }
2814 if (i == ARRAY_SIZE(bclk_divs)) {
2815 dev_err(codec->dev, "Unsupported BCLK ratio %d\n",
2816 dspclk / wm8962->bclk);
2817 return;
2818 }
2819
2820 aif2 |= wm8962->bclk / wm8962->lrclk;
2821 dev_dbg(codec->dev, "Selected LRCLK divisor %d for %dHz\n",
2822 wm8962->bclk / wm8962->lrclk, wm8962->lrclk);
2823
2824 snd_soc_update_bits(codec, WM8962_CLOCKING2,
2825 WM8962_BCLK_DIV_MASK, clocking2);
2826 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_2,
2827 WM8962_AIF_RATE_MASK, aif2);
2828}
2829
2830static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2831 enum snd_soc_bias_level level)
2832{
2833 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2834 int ret;
2835
2836 if (level == codec->dapm.bias_level)
2837 return 0;
2838
2839 switch (level) {
2840 case SND_SOC_BIAS_ON:
2841 break;
2842
2843 case SND_SOC_BIAS_PREPARE:
2844 /* VMID 2*50k */
2845 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2846 WM8962_VMID_SEL_MASK, 0x80);
2847 break;
2848
2849 case SND_SOC_BIAS_STANDBY:
2850 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2851 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
2852 wm8962->supplies);
2853 if (ret != 0) {
2854 dev_err(codec->dev,
2855 "Failed to enable supplies: %d\n",
2856 ret);
2857 return ret;
2858 }
2859
2860 wm8962_sync_cache(codec);
2861
2862 snd_soc_update_bits(codec, WM8962_ANTI_POP,
2863 WM8962_STARTUP_BIAS_ENA |
2864 WM8962_VMID_BUF_ENA,
2865 WM8962_STARTUP_BIAS_ENA |
2866 WM8962_VMID_BUF_ENA);
2867
2868 /* Bias enable at 2*50k for ramp */
2869 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2870 WM8962_VMID_SEL_MASK |
2871 WM8962_BIAS_ENA,
2872 WM8962_BIAS_ENA | 0x180);
2873
2874 msleep(5);
2875
2876 snd_soc_update_bits(codec, WM8962_CLOCKING2,
2877 WM8962_CLKREG_OVD,
2878 WM8962_CLKREG_OVD);
2879
2880 wm8962_configure_bclk(codec);
2881 }
2882
2883 /* VMID 2*250k */
2884 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2885 WM8962_VMID_SEL_MASK, 0x100);
2886 break;
2887
2888 case SND_SOC_BIAS_OFF:
2889 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2890 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
2891
2892 snd_soc_update_bits(codec, WM8962_ANTI_POP,
2893 WM8962_STARTUP_BIAS_ENA |
2894 WM8962_VMID_BUF_ENA, 0);
2895
2896 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
2897 wm8962->supplies);
2898 break;
2899 }
2900 codec->dapm.bias_level = level;
2901 return 0;
2902}
2903
2904static const struct {
2905 int rate;
2906 int reg;
2907} sr_vals[] = {
2908 { 48000, 0 },
2909 { 44100, 0 },
2910 { 32000, 1 },
2911 { 22050, 2 },
2912 { 24000, 2 },
2913 { 16000, 3 },
2914 { 11025, 4 },
2915 { 12000, 4 },
2916 { 8000, 5 },
2917 { 88200, 6 },
2918 { 96000, 6 },
2919};
2920
2921static const int sysclk_rates[] = {
2922 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
2923};
2924
2925static int wm8962_hw_params(struct snd_pcm_substream *substream,
2926 struct snd_pcm_hw_params *params,
2927 struct snd_soc_dai *dai)
2928{
2929 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2930 struct snd_soc_codec *codec = rtd->codec;
2931 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2932 int rate = params_rate(params);
2933 int i;
2934 int aif0 = 0;
2935 int adctl3 = 0;
2936 int clocking4 = 0;
2937
2938 wm8962->bclk = snd_soc_params_to_bclk(params);
2939 wm8962->lrclk = params_rate(params);
2940
2941 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
2942 if (sr_vals[i].rate == rate) {
2943 adctl3 |= sr_vals[i].reg;
2944 break;
2945 }
2946 }
2947 if (i == ARRAY_SIZE(sr_vals)) {
2948 dev_err(codec->dev, "Unsupported rate %dHz\n", rate);
2949 return -EINVAL;
2950 }
2951
2952 if (rate % 8000 == 0)
2953 adctl3 |= WM8962_SAMPLE_RATE_INT_MODE;
2954
2955 for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
2956 if (sysclk_rates[i] == wm8962->sysclk_rate / rate) {
2957 clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
2958 break;
2959 }
2960 }
2961 if (i == ARRAY_SIZE(sysclk_rates)) {
2962 dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
2963 wm8962->sysclk_rate / rate);
2964 return -EINVAL;
2965 }
2966
2967 switch (params_format(params)) {
2968 case SNDRV_PCM_FORMAT_S16_LE:
2969 break;
2970 case SNDRV_PCM_FORMAT_S20_3LE:
2971 aif0 |= 0x40;
2972 break;
2973 case SNDRV_PCM_FORMAT_S24_LE:
2974 aif0 |= 0x80;
2975 break;
2976 case SNDRV_PCM_FORMAT_S32_LE:
2977 aif0 |= 0xc0;
2978 break;
2979 default:
2980 return -EINVAL;
2981 }
2982
2983 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
2984 WM8962_WL_MASK, aif0);
2985 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3,
2986 WM8962_SAMPLE_RATE_INT_MODE |
2987 WM8962_SAMPLE_RATE_MASK, adctl3);
2988 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
2989 WM8962_SYSCLK_RATE_MASK, clocking4);
2990
2991 wm8962_configure_bclk(codec);
2992
2993 return 0;
2994}
2995
2996static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
2997 unsigned int freq, int dir)
2998{
2999 struct snd_soc_codec *codec = dai->codec;
3000 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3001 int src;
3002
3003 switch (clk_id) {
3004 case WM8962_SYSCLK_MCLK:
3005 wm8962->sysclk = WM8962_SYSCLK_MCLK;
3006 src = 0;
3007 break;
3008 case WM8962_SYSCLK_FLL:
3009 wm8962->sysclk = WM8962_SYSCLK_FLL;
3010 src = 1 << WM8962_SYSCLK_SRC_SHIFT;
3011 break;
3012 default:
3013 return -EINVAL;
3014 }
3015
3016 snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_SRC_MASK,
3017 src);
3018
3019 wm8962->sysclk_rate = freq;
3020
3021 return 0;
3022}
3023
3024static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3025{
3026 struct snd_soc_codec *codec = dai->codec;
3027 int aif0 = 0;
3028
3029 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3030 case SND_SOC_DAIFMT_DSP_A:
3031 aif0 |= WM8962_LRCLK_INV;
3032 case SND_SOC_DAIFMT_DSP_B:
3033 aif0 |= 3;
3034
3035 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3036 case SND_SOC_DAIFMT_NB_NF:
3037 case SND_SOC_DAIFMT_IB_NF:
3038 break;
3039 default:
3040 return -EINVAL;
3041 }
3042 break;
3043
3044 case SND_SOC_DAIFMT_RIGHT_J:
3045 break;
3046 case SND_SOC_DAIFMT_LEFT_J:
3047 aif0 |= 1;
3048 break;
3049 case SND_SOC_DAIFMT_I2S:
3050 aif0 |= 2;
3051 break;
3052 default:
3053 return -EINVAL;
3054 }
3055
3056 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3057 case SND_SOC_DAIFMT_NB_NF:
3058 break;
3059 case SND_SOC_DAIFMT_IB_NF:
3060 aif0 |= WM8962_BCLK_INV;
3061 break;
3062 case SND_SOC_DAIFMT_NB_IF:
3063 aif0 |= WM8962_LRCLK_INV;
3064 break;
3065 case SND_SOC_DAIFMT_IB_IF:
3066 aif0 |= WM8962_BCLK_INV | WM8962_LRCLK_INV;
3067 break;
3068 default:
3069 return -EINVAL;
3070 }
3071
3072 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3073 case SND_SOC_DAIFMT_CBM_CFM:
3074 aif0 |= WM8962_MSTR;
3075 break;
3076 case SND_SOC_DAIFMT_CBS_CFS:
3077 break;
3078 default:
3079 return -EINVAL;
3080 }
3081
3082 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
3083 WM8962_FMT_MASK | WM8962_BCLK_INV | WM8962_MSTR |
3084 WM8962_LRCLK_INV, aif0);
3085
3086 return 0;
3087}
3088
3089struct _fll_div {
3090 u16 fll_fratio;
3091 u16 fll_outdiv;
3092 u16 fll_refclk_div;
3093 u16 n;
3094 u16 theta;
3095 u16 lambda;
3096};
3097
3098/* The size in bits of the FLL divide multiplied by 10
3099 * to allow rounding later */
3100#define FIXED_FLL_SIZE ((1 << 16) * 10)
3101
3102static struct {
3103 unsigned int min;
3104 unsigned int max;
3105 u16 fll_fratio;
3106 int ratio;
3107} fll_fratios[] = {
3108 { 0, 64000, 4, 16 },
3109 { 64000, 128000, 3, 8 },
3110 { 128000, 256000, 2, 4 },
3111 { 256000, 1000000, 1, 2 },
3112 { 1000000, 13500000, 0, 1 },
3113};
3114
3115static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
3116 unsigned int Fout)
3117{
3118 unsigned int target;
3119 unsigned int div;
3120 unsigned int fratio, gcd_fll;
3121 int i;
3122
3123 /* Fref must be <=13.5MHz */
3124 div = 1;
3125 fll_div->fll_refclk_div = 0;
3126 while ((Fref / div) > 13500000) {
3127 div *= 2;
3128 fll_div->fll_refclk_div++;
3129
3130 if (div > 4) {
3131 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
3132 Fref);
3133 return -EINVAL;
3134 }
3135 }
3136
3137 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
3138
3139 /* Apply the division for our remaining calculations */
3140 Fref /= div;
3141
3142 /* Fvco should be 90-100MHz; don't check the upper bound */
3143 div = 2;
3144 while (Fout * div < 90000000) {
3145 div++;
3146 if (div > 64) {
3147 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
3148 Fout);
3149 return -EINVAL;
3150 }
3151 }
3152 target = Fout * div;
3153 fll_div->fll_outdiv = div - 1;
3154
3155 pr_debug("FLL Fvco=%dHz\n", target);
3156
3157 /* Find an appropriate FLL_FRATIO and factor it out of the target */
3158 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
3159 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
3160 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
3161 fratio = fll_fratios[i].ratio;
3162 break;
3163 }
3164 }
3165 if (i == ARRAY_SIZE(fll_fratios)) {
3166 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
3167 return -EINVAL;
3168 }
3169
3170 fll_div->n = target / (fratio * Fref);
3171
3172 if (target % Fref == 0) {
3173 fll_div->theta = 0;
3174 fll_div->lambda = 0;
3175 } else {
3176 gcd_fll = gcd(target, fratio * Fref);
3177
3178 fll_div->theta = (target - (fll_div->n * fratio * Fref))
3179 / gcd_fll;
3180 fll_div->lambda = (fratio * Fref) / gcd_fll;
3181 }
3182
3183 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
3184 fll_div->n, fll_div->theta, fll_div->lambda);
3185 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
3186 fll_div->fll_fratio, fll_div->fll_outdiv,
3187 fll_div->fll_refclk_div);
3188
3189 return 0;
3190}
3191
3192static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
3193 unsigned int Fref, unsigned int Fout)
3194{
3195 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3196 struct _fll_div fll_div;
3197 unsigned long timeout;
3198 int ret;
3199 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA;
3200
3201 /* Any change? */
3202 if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
3203 Fout == wm8962->fll_fout)
3204 return 0;
3205
3206 if (Fout == 0) {
3207 dev_dbg(codec->dev, "FLL disabled\n");
3208
3209 wm8962->fll_fref = 0;
3210 wm8962->fll_fout = 0;
3211
3212 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
3213 WM8962_FLL_ENA, 0);
3214
3215 return 0;
3216 }
3217
3218 ret = fll_factors(&fll_div, Fref, Fout);
3219 if (ret != 0)
3220 return ret;
3221
3222 switch (fll_id) {
3223 case WM8962_FLL_MCLK:
3224 case WM8962_FLL_BCLK:
3225 case WM8962_FLL_OSC:
3226 fll1 |= (fll_id - 1) << WM8962_FLL_REFCLK_SRC_SHIFT;
3227 break;
3228 case WM8962_FLL_INT:
3229 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
3230 WM8962_FLL_OSC_ENA, WM8962_FLL_OSC_ENA);
3231 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_5,
3232 WM8962_FLL_FRC_NCO, WM8962_FLL_FRC_NCO);
3233 break;
3234 default:
3235 dev_err(codec->dev, "Unknown FLL source %d\n", ret);
3236 return -EINVAL;
3237 }
3238
3239 if (fll_div.theta || fll_div.lambda)
3240 fll1 |= WM8962_FLL_FRAC;
3241
3242 /* Stop the FLL while we reconfigure */
3243 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
3244
3245 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_2,
3246 WM8962_FLL_OUTDIV_MASK |
3247 WM8962_FLL_REFCLK_DIV_MASK,
3248 (fll_div.fll_outdiv << WM8962_FLL_OUTDIV_SHIFT) |
3249 (fll_div.fll_refclk_div));
3250
3251 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_3,
3252 WM8962_FLL_FRATIO_MASK, fll_div.fll_fratio);
3253
3254 snd_soc_write(codec, WM8962_FLL_CONTROL_6, fll_div.theta);
3255 snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
3256 snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
3257
3258 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
3259 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
3260 WM8962_FLL_ENA, fll1);
3261
3262 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
3263
3264 /* This should be a massive overestimate */
3265 timeout = msecs_to_jiffies(1);
3266
3267 wait_for_completion_timeout(&wm8962->fll_lock, timeout);
3268
3269 wm8962->fll_fref = Fref;
3270 wm8962->fll_fout = Fout;
3271 wm8962->fll_src = source;
3272
3273 return 0;
3274}
3275
3276static int wm8962_mute(struct snd_soc_dai *dai, int mute)
3277{
3278 struct snd_soc_codec *codec = dai->codec;
3279 int val;
3280
3281 if (mute)
3282 val = WM8962_DAC_MUTE;
3283 else
3284 val = 0;
3285
3286 return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
3287 WM8962_DAC_MUTE, val);
3288}
3289
3290#define WM8962_RATES SNDRV_PCM_RATE_8000_96000
3291
3292#define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3293 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
3294
3295static struct snd_soc_dai_ops wm8962_dai_ops = {
3296 .hw_params = wm8962_hw_params,
3297 .set_sysclk = wm8962_set_dai_sysclk,
3298 .set_fmt = wm8962_set_dai_fmt,
3299 .digital_mute = wm8962_mute,
3300};
3301
3302static struct snd_soc_dai_driver wm8962_dai = {
3303 .name = "wm8962",
3304 .playback = {
3305 .stream_name = "Playback",
3306 .channels_min = 2,
3307 .channels_max = 2,
3308 .rates = WM8962_RATES,
3309 .formats = WM8962_FORMATS,
3310 },
3311 .capture = {
3312 .stream_name = "Capture",
3313 .channels_min = 2,
3314 .channels_max = 2,
3315 .rates = WM8962_RATES,
3316 .formats = WM8962_FORMATS,
3317 },
3318 .ops = &wm8962_dai_ops,
3319 .symmetric_rates = 1,
3320};
3321
3322static void wm8962_mic_work(struct work_struct *work)
3323{
3324 struct wm8962_priv *wm8962 = container_of(work,
3325 struct wm8962_priv,
3326 mic_work.work);
3327 struct snd_soc_codec *codec = wm8962->codec;
3328 int status = 0;
3329 int irq_pol = 0;
3330 int reg;
3331
3332 reg = snd_soc_read(codec, WM8962_ADDITIONAL_CONTROL_4);
3333
3334 if (reg & WM8962_MICDET_STS) {
3335 status |= SND_JACK_MICROPHONE;
3336 irq_pol |= WM8962_MICD_IRQ_POL;
3337 }
3338
3339 if (reg & WM8962_MICSHORT_STS) {
3340 status |= SND_JACK_BTN_0;
3341 irq_pol |= WM8962_MICSCD_IRQ_POL;
3342 }
3343
3344 snd_soc_jack_report(wm8962->jack, status,
3345 SND_JACK_MICROPHONE | SND_JACK_BTN_0);
3346
3347 snd_soc_update_bits(codec, WM8962_MICINT_SOURCE_POL,
3348 WM8962_MICSCD_IRQ_POL |
3349 WM8962_MICD_IRQ_POL, irq_pol);
3350}
3351
3352static irqreturn_t wm8962_irq(int irq, void *data)
3353{
3354 struct snd_soc_codec *codec = data;
3355 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3356 int mask;
3357 int active;
3358
3359 mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
3360
3361 active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
3362 active &= ~mask;
3363
3364 if (active & WM8962_FLL_LOCK_EINT) {
3365 dev_dbg(codec->dev, "FLL locked\n");
3366 complete(&wm8962->fll_lock);
3367 }
3368
3369 if (active & WM8962_FIFOS_ERR_EINT)
3370 dev_err(codec->dev, "FIFO error\n");
3371
3372 if (active & WM8962_TEMP_SHUT_EINT)
3373 dev_crit(codec->dev, "Thermal shutdown\n");
3374
3375 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3376 dev_dbg(codec->dev, "Microphone event detected\n");
3377
3378#ifndef CONFIG_SND_SOC_WM8962_MODULE
3379 trace_snd_soc_jack_irq(dev_name(codec->dev));
3380#endif
3381
3382 pm_wakeup_event(codec->dev, 300);
3383
3384 schedule_delayed_work(&wm8962->mic_work,
3385 msecs_to_jiffies(250));
3386 }
3387
3388 /* Acknowledge the interrupts */
3389 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active);
3390
3391 return IRQ_HANDLED;
3392}
3393
3394/**
3395 * wm8962_mic_detect - Enable microphone detection via the WM8962 IRQ
3396 *
3397 * @codec: WM8962 codec
3398 * @jack: jack to report detection events on
3399 *
3400 * Enable microphone detection via IRQ on the WM8962. If GPIOs are
3401 * being used to bring out signals to the processor then only platform
3402 * data configuration is needed for WM8962 and processor GPIOs should
3403 * be configured using snd_soc_jack_add_gpios() instead.
3404 *
3405 * If no jack is supplied detection will be disabled.
3406 */
3407int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
3408{
3409 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3410 int irq_mask, enable;
3411
3412 wm8962->jack = jack;
3413 if (jack) {
3414 irq_mask = 0;
3415 enable = WM8962_MICDET_ENA;
3416 } else {
3417 irq_mask = WM8962_MICD_EINT | WM8962_MICSCD_EINT;
3418 enable = 0;
3419 }
3420
3421 snd_soc_update_bits(codec, WM8962_INTERRUPT_STATUS_2_MASK,
3422 WM8962_MICD_EINT | WM8962_MICSCD_EINT, irq_mask);
3423 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4,
3424 WM8962_MICDET_ENA, enable);
3425
3426 /* Send an initial empty report */
3427 snd_soc_jack_report(wm8962->jack, 0,
3428 SND_JACK_MICROPHONE | SND_JACK_BTN_0);
3429
3430 return 0;
3431}
3432EXPORT_SYMBOL_GPL(wm8962_mic_detect);
3433
3434#ifdef CONFIG_PM
3435static int wm8962_resume(struct snd_soc_codec *codec)
3436{
3437 u16 *reg_cache = codec->reg_cache;
3438 int i;
3439
3440 /* Restore the registers */
3441 for (i = 1; i < codec->driver->reg_cache_size; i++) {
3442 switch (i) {
3443 case WM8962_SOFTWARE_RESET:
3444 continue;
3445 default:
3446 break;
3447 }
3448
3449 if (reg_cache[i] != wm8962_reg[i])
3450 snd_soc_write(codec, i, reg_cache[i]);
3451 }
3452
3453 return 0;
3454}
3455#else
3456#define wm8962_resume NULL
3457#endif
3458
3459#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3460static int beep_rates[] = {
3461 500, 1000, 2000, 4000,
3462};
3463
3464static void wm8962_beep_work(struct work_struct *work)
3465{
3466 struct wm8962_priv *wm8962 =
3467 container_of(work, struct wm8962_priv, beep_work);
3468 struct snd_soc_codec *codec = wm8962->codec;
3469 struct snd_soc_dapm_context *dapm = &codec->dapm;
3470 int i;
3471 int reg = 0;
3472 int best = 0;
3473
3474 if (wm8962->beep_rate) {
3475 for (i = 0; i < ARRAY_SIZE(beep_rates); i++) {
3476 if (abs(wm8962->beep_rate - beep_rates[i]) <
3477 abs(wm8962->beep_rate - beep_rates[best]))
3478 best = i;
3479 }
3480
3481 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
3482 beep_rates[best], wm8962->beep_rate);
3483
3484 reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
3485
3486 snd_soc_dapm_enable_pin(dapm, "Beep");
3487 } else {
3488 dev_dbg(codec->dev, "Disabling beep\n");
3489 snd_soc_dapm_disable_pin(dapm, "Beep");
3490 }
3491
3492 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
3493 WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
3494
3495 snd_soc_dapm_sync(dapm);
3496}
3497
3498/* For usability define a way of injecting beep events for the device -
3499 * many systems will not have a keyboard.
3500 */
3501static int wm8962_beep_event(struct input_dev *dev, unsigned int type,
3502 unsigned int code, int hz)
3503{
3504 struct snd_soc_codec *codec = input_get_drvdata(dev);
3505 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3506
3507 dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
3508
3509 switch (code) {
3510 case SND_BELL:
3511 if (hz)
3512 hz = 1000;
3513 case SND_TONE:
3514 break;
3515 default:
3516 return -1;
3517 }
3518
3519 /* Kick the beep from a workqueue */
3520 wm8962->beep_rate = hz;
3521 schedule_work(&wm8962->beep_work);
3522 return 0;
3523}
3524
3525static ssize_t wm8962_beep_set(struct device *dev,
3526 struct device_attribute *attr,
3527 const char *buf, size_t count)
3528{
3529 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3530 long int time;
3531 int ret;
3532
3533 ret = strict_strtol(buf, 10, &time);
3534 if (ret != 0)
3535 return ret;
3536
3537 input_event(wm8962->beep, EV_SND, SND_TONE, time);
3538
3539 return count;
3540}
3541
3542static DEVICE_ATTR(beep, 0200, NULL, wm8962_beep_set);
3543
3544static void wm8962_init_beep(struct snd_soc_codec *codec)
3545{
3546 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3547 int ret;
3548
3549 wm8962->beep = input_allocate_device();
3550 if (!wm8962->beep) {
3551 dev_err(codec->dev, "Failed to allocate beep device\n");
3552 return;
3553 }
3554
3555 INIT_WORK(&wm8962->beep_work, wm8962_beep_work);
3556 wm8962->beep_rate = 0;
3557
3558 wm8962->beep->name = "WM8962 Beep Generator";
3559 wm8962->beep->phys = dev_name(codec->dev);
3560 wm8962->beep->id.bustype = BUS_I2C;
3561
3562 wm8962->beep->evbit[0] = BIT_MASK(EV_SND);
3563 wm8962->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
3564 wm8962->beep->event = wm8962_beep_event;
3565 wm8962->beep->dev.parent = codec->dev;
3566 input_set_drvdata(wm8962->beep, codec);
3567
3568 ret = input_register_device(wm8962->beep);
3569 if (ret != 0) {
3570 input_free_device(wm8962->beep);
3571 wm8962->beep = NULL;
3572 dev_err(codec->dev, "Failed to register beep device\n");
3573 }
3574
3575 ret = device_create_file(codec->dev, &dev_attr_beep);
3576 if (ret != 0) {
3577 dev_err(codec->dev, "Failed to create keyclick file: %d\n",
3578 ret);
3579 }
3580}
3581
3582static void wm8962_free_beep(struct snd_soc_codec *codec)
3583{
3584 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3585
3586 device_remove_file(codec->dev, &dev_attr_beep);
3587 input_unregister_device(wm8962->beep);
3588 cancel_work_sync(&wm8962->beep_work);
3589 wm8962->beep = NULL;
3590
3591 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0);
3592}
3593#else
3594static void wm8962_init_beep(struct snd_soc_codec *codec)
3595{
3596}
3597
3598static void wm8962_free_beep(struct snd_soc_codec *codec)
3599{
3600}
3601#endif
3602
3603static void wm8962_set_gpio_mode(struct snd_soc_codec *codec, int gpio)
3604{
3605 int mask = 0;
3606 int val = 0;
3607
3608 /* Some of the GPIOs are behind MFP configuration and need to
3609 * be put into GPIO mode. */
3610 switch (gpio) {
3611 case 2:
3612 mask = WM8962_CLKOUT2_SEL_MASK;
3613 val = 1 << WM8962_CLKOUT2_SEL_SHIFT;
3614 break;
3615 case 3:
3616 mask = WM8962_CLKOUT3_SEL_MASK;
3617 val = 1 << WM8962_CLKOUT3_SEL_SHIFT;
3618 break;
3619 default:
3620 break;
3621 }
3622
3623 if (mask)
3624 snd_soc_update_bits(codec, WM8962_ANALOGUE_CLOCKING1,
3625 mask, val);
3626}
3627
3628#ifdef CONFIG_GPIOLIB
3629static inline struct wm8962_priv *gpio_to_wm8962(struct gpio_chip *chip)
3630{
3631 return container_of(chip, struct wm8962_priv, gpio_chip);
3632}
3633
3634static int wm8962_gpio_request(struct gpio_chip *chip, unsigned offset)
3635{
3636 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
3637 struct snd_soc_codec *codec = wm8962->codec;
3638
3639 /* The WM8962 GPIOs aren't linearly numbered. For simplicity
3640 * we export linear numbers and error out if the unsupported
3641 * ones are requsted.
3642 */
3643 switch (offset + 1) {
3644 case 2:
3645 case 3:
3646 case 5:
3647 case 6:
3648 break;
3649 default:
3650 return -EINVAL;
3651 }
3652
3653 wm8962_set_gpio_mode(codec, offset + 1);
3654
3655 return 0;
3656}
3657
3658static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
3659{
3660 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
3661 struct snd_soc_codec *codec = wm8962->codec;
3662
3663 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
3664 WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT);
3665}
3666
3667static int wm8962_gpio_direction_out(struct gpio_chip *chip,
3668 unsigned offset, int value)
3669{
3670 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip);
3671 struct snd_soc_codec *codec = wm8962->codec;
3672 int val;
3673
3674 /* Force function 1 (logic output) */
3675 val = (1 << WM8962_GP2_FN_SHIFT) | (value << WM8962_GP2_LVL_SHIFT);
3676
3677 return snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset,
3678 WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val);
3679}
3680
3681static struct gpio_chip wm8962_template_chip = {
3682 .label = "wm8962",
3683 .owner = THIS_MODULE,
3684 .request = wm8962_gpio_request,
3685 .direction_output = wm8962_gpio_direction_out,
3686 .set = wm8962_gpio_set,
3687 .can_sleep = 1,
3688};
3689
3690static void wm8962_init_gpio(struct snd_soc_codec *codec)
3691{
3692 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3693 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
3694 int ret;
3695
3696 wm8962->gpio_chip = wm8962_template_chip;
3697 wm8962->gpio_chip.ngpio = WM8962_MAX_GPIO;
3698 wm8962->gpio_chip.dev = codec->dev;
3699
3700 if (pdata && pdata->gpio_base)
3701 wm8962->gpio_chip.base = pdata->gpio_base;
3702 else
3703 wm8962->gpio_chip.base = -1;
3704
3705 ret = gpiochip_add(&wm8962->gpio_chip);
3706 if (ret != 0)
3707 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
3708}
3709
3710static void wm8962_free_gpio(struct snd_soc_codec *codec)
3711{
3712 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3713 int ret;
3714
3715 ret = gpiochip_remove(&wm8962->gpio_chip);
3716 if (ret != 0)
3717 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
3718}
3719#else
3720static void wm8962_init_gpio(struct snd_soc_codec *codec)
3721{
3722}
3723
3724static void wm8962_free_gpio(struct snd_soc_codec *codec)
3725{
3726}
3727#endif
3728
3729static int wm8962_probe(struct snd_soc_codec *codec)
3730{
3731 int ret;
3732 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3733 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
3734 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
3735 dev);
3736 u16 *reg_cache = codec->reg_cache;
3737 int i, trigger, irq_pol;
3738 bool dmicclk, dmicdat;
3739
3740 wm8962->codec = codec;
3741 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
3742 init_completion(&wm8962->fll_lock);
3743
3744 codec->cache_sync = 1;
3745 codec->dapm.idle_bias_off = 1;
3746
3747 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
3748 if (ret != 0) {
3749 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
3750 goto err;
3751 }
3752
3753 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
3754 wm8962->supplies[i].supply = wm8962_supply_names[i];
3755
3756 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8962->supplies),
3757 wm8962->supplies);
3758 if (ret != 0) {
3759 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
3760 goto err;
3761 }
3762
3763 wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
3764 wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1;
3765 wm8962->disable_nb[2].notifier_call = wm8962_regulator_event_2;
3766 wm8962->disable_nb[3].notifier_call = wm8962_regulator_event_3;
3767 wm8962->disable_nb[4].notifier_call = wm8962_regulator_event_4;
3768 wm8962->disable_nb[5].notifier_call = wm8962_regulator_event_5;
3769 wm8962->disable_nb[6].notifier_call = wm8962_regulator_event_6;
3770 wm8962->disable_nb[7].notifier_call = wm8962_regulator_event_7;
3771
3772 /* This should really be moved into the regulator core */
3773 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) {
3774 ret = regulator_register_notifier(wm8962->supplies[i].consumer,
3775 &wm8962->disable_nb[i]);
3776 if (ret != 0) {
3777 dev_err(codec->dev,
3778 "Failed to register regulator notifier: %d\n",
3779 ret);
3780 }
3781 }
3782
3783 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
3784 wm8962->supplies);
3785 if (ret != 0) {
3786 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
3787 goto err_get;
3788 }
3789
3790 ret = snd_soc_read(codec, WM8962_SOFTWARE_RESET);
3791 if (ret < 0) {
3792 dev_err(codec->dev, "Failed to read ID register\n");
3793 goto err_enable;
3794 }
3795 if (ret != wm8962_reg[WM8962_SOFTWARE_RESET]) {
3796 dev_err(codec->dev, "Device is not a WM8962, ID %x != %x\n",
3797 ret, wm8962_reg[WM8962_SOFTWARE_RESET]);
3798 ret = -EINVAL;
3799 goto err_enable;
3800 }
3801
3802 ret = snd_soc_read(codec, WM8962_RIGHT_INPUT_VOLUME);
3803 if (ret < 0) {
3804 dev_err(codec->dev, "Failed to read device revision: %d\n",
3805 ret);
3806 goto err_enable;
3807 }
3808
3809 dev_info(codec->dev, "customer id %x revision %c\n",
3810 (ret & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
3811 ((ret & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
3812 + 'A');
3813
3814 ret = wm8962_reset(codec);
3815 if (ret < 0) {
3816 dev_err(codec->dev, "Failed to issue reset\n");
3817 goto err_enable;
3818 }
3819
3820 /* SYSCLK defaults to on; make sure it is off so we can safely
3821 * write to registers if the device is declocked.
3822 */
3823 snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
3824
3825 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3826
3827 if (pdata) {
3828 /* Apply static configuration for GPIOs */
3829 for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++)
3830 if (pdata->gpio_init[i]) {
3831 wm8962_set_gpio_mode(codec, i + 1);
3832 snd_soc_write(codec, 0x200 + i,
3833 pdata->gpio_init[i] & 0xffff);
3834 }
3835
3836 /* Put the speakers into mono mode? */
3837 if (pdata->spk_mono)
3838 reg_cache[WM8962_CLASS_D_CONTROL_2]
3839 |= WM8962_SPK_MONO;
3840
3841 /* Micbias setup, detection enable and detection
3842 * threasholds. */
3843 if (pdata->mic_cfg)
3844 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4,
3845 WM8962_MICDET_ENA |
3846 WM8962_MICDET_THR_MASK |
3847 WM8962_MICSHORT_THR_MASK |
3848 WM8962_MICBIAS_LVL,
3849 pdata->mic_cfg);
3850 }
3851
3852 /* Latch volume update bits */
3853 snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME,
3854 WM8962_IN_VU, WM8962_IN_VU);
3855 snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME,
3856 WM8962_IN_VU, WM8962_IN_VU);
3857 snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME,
3858 WM8962_ADC_VU, WM8962_ADC_VU);
3859 snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME,
3860 WM8962_ADC_VU, WM8962_ADC_VU);
3861 snd_soc_update_bits(codec, WM8962_LEFT_DAC_VOLUME,
3862 WM8962_DAC_VU, WM8962_DAC_VU);
3863 snd_soc_update_bits(codec, WM8962_RIGHT_DAC_VOLUME,
3864 WM8962_DAC_VU, WM8962_DAC_VU);
3865 snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME,
3866 WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
3867 snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME,
3868 WM8962_SPKOUT_VU, WM8962_SPKOUT_VU);
3869 snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME,
3870 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3871 snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME,
3872 WM8962_HPOUT_VU, WM8962_HPOUT_VU);
3873
3874 wm8962_add_widgets(codec);
3875
3876 /* Save boards having to disable DMIC when not in use */
3877 dmicclk = false;
3878 dmicdat = false;
3879 for (i = 0; i < WM8962_MAX_GPIO; i++) {
3880 switch (snd_soc_read(codec, WM8962_GPIO_BASE + i)
3881 & WM8962_GP2_FN_MASK) {
3882 case WM8962_GPIO_FN_DMICCLK:
3883 dmicclk = true;
3884 break;
3885 case WM8962_GPIO_FN_DMICDAT:
3886 dmicdat = true;
3887 break;
3888 default:
3889 break;
3890 }
3891 }
3892 if (!dmicclk || !dmicdat) {
3893 dev_dbg(codec->dev, "DMIC not in use, disabling\n");
3894 snd_soc_dapm_nc_pin(&codec->dapm, "DMICDAT");
3895 }
3896 if (dmicclk != dmicdat)
3897 dev_warn(codec->dev, "DMIC GPIOs partially configured\n");
3898
3899 wm8962_init_beep(codec);
3900 wm8962_init_gpio(codec);
3901
3902 if (i2c->irq) {
3903 if (pdata && pdata->irq_active_low) {
3904 trigger = IRQF_TRIGGER_LOW;
3905 irq_pol = WM8962_IRQ_POL;
3906 } else {
3907 trigger = IRQF_TRIGGER_HIGH;
3908 irq_pol = 0;
3909 }
3910
3911 snd_soc_update_bits(codec, WM8962_INTERRUPT_CONTROL,
3912 WM8962_IRQ_POL, irq_pol);
3913
3914 ret = request_threaded_irq(i2c->irq, NULL, wm8962_irq,
3915 trigger | IRQF_ONESHOT,
3916 "wm8962", codec);
3917 if (ret != 0) {
3918 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
3919 i2c->irq, ret);
3920 /* Non-fatal */
3921 } else {
3922 /* Enable some IRQs by default */
3923 snd_soc_update_bits(codec,
3924 WM8962_INTERRUPT_STATUS_2_MASK,
3925 WM8962_FLL_LOCK_EINT |
3926 WM8962_TEMP_SHUT_EINT |
3927 WM8962_FIFOS_ERR_EINT, 0);
3928 }
3929 }
3930
3931 return 0;
3932
3933err_enable:
3934 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3935err_get:
3936 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3937err:
3938 return ret;
3939}
3940
3941static int wm8962_remove(struct snd_soc_codec *codec)
3942{
3943 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3944 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
3945 dev);
3946 int i;
3947
3948 if (i2c->irq)
3949 free_irq(i2c->irq, codec);
3950
3951 cancel_delayed_work_sync(&wm8962->mic_work);
3952
3953 wm8962_free_gpio(codec);
3954 wm8962_free_beep(codec);
3955 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
3956 regulator_unregister_notifier(wm8962->supplies[i].consumer,
3957 &wm8962->disable_nb[i]);
3958 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3959
3960 return 0;
3961}
3962
3963static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
3964 .probe = wm8962_probe,
3965 .remove = wm8962_remove,
3966 .resume = wm8962_resume,
3967 .set_bias_level = wm8962_set_bias_level,
3968 .reg_cache_size = WM8962_MAX_REGISTER + 1,
3969 .reg_word_size = sizeof(u16),
3970 .reg_cache_default = wm8962_reg,
3971 .volatile_register = wm8962_volatile_register,
3972 .readable_register = wm8962_readable_register,
3973 .set_pll = wm8962_set_fll,
3974};
3975
3976#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
3977static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
3978 const struct i2c_device_id *id)
3979{
3980 struct wm8962_priv *wm8962;
3981 int ret;
3982
3983 wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL);
3984 if (wm8962 == NULL)
3985 return -ENOMEM;
3986
3987 i2c_set_clientdata(i2c, wm8962);
3988
3989 ret = snd_soc_register_codec(&i2c->dev,
3990 &soc_codec_dev_wm8962, &wm8962_dai, 1);
3991 if (ret < 0)
3992 kfree(wm8962);
3993
3994 return ret;
3995}
3996
3997static __devexit int wm8962_i2c_remove(struct i2c_client *client)
3998{
3999 snd_soc_unregister_codec(&client->dev);
4000 kfree(i2c_get_clientdata(client));
4001 return 0;
4002}
4003
4004static const struct i2c_device_id wm8962_i2c_id[] = {
4005 { "wm8962", 0 },
4006 { }
4007};
4008MODULE_DEVICE_TABLE(i2c, wm8962_i2c_id);
4009
4010static struct i2c_driver wm8962_i2c_driver = {
4011 .driver = {
4012 .name = "wm8962",
4013 .owner = THIS_MODULE,
4014 },
4015 .probe = wm8962_i2c_probe,
4016 .remove = __devexit_p(wm8962_i2c_remove),
4017 .id_table = wm8962_i2c_id,
4018};
4019#endif
4020
4021static int __init wm8962_modinit(void)
4022{
4023 int ret;
4024#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4025 ret = i2c_add_driver(&wm8962_i2c_driver);
4026 if (ret != 0) {
4027 printk(KERN_ERR "Failed to register WM8962 I2C driver: %d\n",
4028 ret);
4029 }
4030#endif
4031 return 0;
4032}
4033module_init(wm8962_modinit);
4034
4035static void __exit wm8962_exit(void)
4036{
4037#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
4038 i2c_del_driver(&wm8962_i2c_driver);
4039#endif
4040}
4041module_exit(wm8962_exit);
4042
4043MODULE_DESCRIPTION("ASoC WM8962 driver");
4044MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
4045MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8962.h b/sound/soc/codecs/wm8962.h
new file mode 100644
index 000000000000..a1a5d5294c19
--- /dev/null
+++ b/sound/soc/codecs/wm8962.h
@@ -0,0 +1,3780 @@
1/*
2 * wm8962.h -- WM8962 ASoC driver
3 *
4 * Copyright 2010 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8962_H
14#define _WM8962_H
15
16#include <asm/types.h>
17#include <sound/soc.h>
18
19#define WM8962_SYSCLK_MCLK 1
20#define WM8962_SYSCLK_FLL 2
21#define WM8962_SYSCLK_PLL3 3
22
23#define WM8962_FLL 1
24
25#define WM8962_FLL_MCLK 1
26#define WM8962_FLL_BCLK 2
27#define WM8962_FLL_OSC 3
28#define WM8962_FLL_INT 4
29
30/*
31 * Register values.
32 */
33#define WM8962_LEFT_INPUT_VOLUME 0x00
34#define WM8962_RIGHT_INPUT_VOLUME 0x01
35#define WM8962_HPOUTL_VOLUME 0x02
36#define WM8962_HPOUTR_VOLUME 0x03
37#define WM8962_CLOCKING1 0x04
38#define WM8962_ADC_DAC_CONTROL_1 0x05
39#define WM8962_ADC_DAC_CONTROL_2 0x06
40#define WM8962_AUDIO_INTERFACE_0 0x07
41#define WM8962_CLOCKING2 0x08
42#define WM8962_AUDIO_INTERFACE_1 0x09
43#define WM8962_LEFT_DAC_VOLUME 0x0A
44#define WM8962_RIGHT_DAC_VOLUME 0x0B
45#define WM8962_AUDIO_INTERFACE_2 0x0E
46#define WM8962_SOFTWARE_RESET 0x0F
47#define WM8962_ALC1 0x11
48#define WM8962_ALC2 0x12
49#define WM8962_ALC3 0x13
50#define WM8962_NOISE_GATE 0x14
51#define WM8962_LEFT_ADC_VOLUME 0x15
52#define WM8962_RIGHT_ADC_VOLUME 0x16
53#define WM8962_ADDITIONAL_CONTROL_1 0x17
54#define WM8962_ADDITIONAL_CONTROL_2 0x18
55#define WM8962_PWR_MGMT_1 0x19
56#define WM8962_PWR_MGMT_2 0x1A
57#define WM8962_ADDITIONAL_CONTROL_3 0x1B
58#define WM8962_ANTI_POP 0x1C
59#define WM8962_CLOCKING_3 0x1E
60#define WM8962_INPUT_MIXER_CONTROL_1 0x1F
61#define WM8962_LEFT_INPUT_MIXER_VOLUME 0x20
62#define WM8962_RIGHT_INPUT_MIXER_VOLUME 0x21
63#define WM8962_INPUT_MIXER_CONTROL_2 0x22
64#define WM8962_INPUT_BIAS_CONTROL 0x23
65#define WM8962_LEFT_INPUT_PGA_CONTROL 0x25
66#define WM8962_RIGHT_INPUT_PGA_CONTROL 0x26
67#define WM8962_SPKOUTL_VOLUME 0x28
68#define WM8962_SPKOUTR_VOLUME 0x29
69#define WM8962_THERMAL_SHUTDOWN_STATUS 0x2F
70#define WM8962_ADDITIONAL_CONTROL_4 0x30
71#define WM8962_CLASS_D_CONTROL_1 0x31
72#define WM8962_CLASS_D_CONTROL_2 0x33
73#define WM8962_CLOCKING_4 0x38
74#define WM8962_DAC_DSP_MIXING_1 0x39
75#define WM8962_DAC_DSP_MIXING_2 0x3A
76#define WM8962_DC_SERVO_0 0x3C
77#define WM8962_DC_SERVO_1 0x3D
78#define WM8962_DC_SERVO_4 0x40
79#define WM8962_DC_SERVO_6 0x42
80#define WM8962_ANALOGUE_PGA_BIAS 0x44
81#define WM8962_ANALOGUE_HP_0 0x45
82#define WM8962_ANALOGUE_HP_2 0x47
83#define WM8962_CHARGE_PUMP_1 0x48
84#define WM8962_CHARGE_PUMP_B 0x52
85#define WM8962_WRITE_SEQUENCER_CONTROL_1 0x57
86#define WM8962_WRITE_SEQUENCER_CONTROL_2 0x5A
87#define WM8962_WRITE_SEQUENCER_CONTROL_3 0x5D
88#define WM8962_CONTROL_INTERFACE 0x5E
89#define WM8962_MIXER_ENABLES 0x63
90#define WM8962_HEADPHONE_MIXER_1 0x64
91#define WM8962_HEADPHONE_MIXER_2 0x65
92#define WM8962_HEADPHONE_MIXER_3 0x66
93#define WM8962_HEADPHONE_MIXER_4 0x67
94#define WM8962_SPEAKER_MIXER_1 0x69
95#define WM8962_SPEAKER_MIXER_2 0x6A
96#define WM8962_SPEAKER_MIXER_3 0x6B
97#define WM8962_SPEAKER_MIXER_4 0x6C
98#define WM8962_SPEAKER_MIXER_5 0x6D
99#define WM8962_BEEP_GENERATOR_1 0x6E
100#define WM8962_OSCILLATOR_TRIM_3 0x73
101#define WM8962_OSCILLATOR_TRIM_4 0x74
102#define WM8962_OSCILLATOR_TRIM_7 0x77
103#define WM8962_ANALOGUE_CLOCKING1 0x7C
104#define WM8962_ANALOGUE_CLOCKING2 0x7D
105#define WM8962_ANALOGUE_CLOCKING3 0x7E
106#define WM8962_PLL_SOFTWARE_RESET 0x7F
107#define WM8962_PLL2 0x81
108#define WM8962_PLL_4 0x83
109#define WM8962_PLL_9 0x88
110#define WM8962_PLL_10 0x89
111#define WM8962_PLL_11 0x8A
112#define WM8962_PLL_12 0x8B
113#define WM8962_PLL_13 0x8C
114#define WM8962_PLL_14 0x8D
115#define WM8962_PLL_15 0x8E
116#define WM8962_PLL_16 0x8F
117#define WM8962_FLL_CONTROL_1 0x9B
118#define WM8962_FLL_CONTROL_2 0x9C
119#define WM8962_FLL_CONTROL_3 0x9D
120#define WM8962_FLL_CONTROL_5 0x9F
121#define WM8962_FLL_CONTROL_6 0xA0
122#define WM8962_FLL_CONTROL_7 0xA1
123#define WM8962_FLL_CONTROL_8 0xA2
124#define WM8962_GENERAL_TEST_1 0xFC
125#define WM8962_DF1 0x100
126#define WM8962_DF2 0x101
127#define WM8962_DF3 0x102
128#define WM8962_DF4 0x103
129#define WM8962_DF5 0x104
130#define WM8962_DF6 0x105
131#define WM8962_DF7 0x106
132#define WM8962_LHPF1 0x108
133#define WM8962_LHPF2 0x109
134#define WM8962_THREED1 0x10C
135#define WM8962_THREED2 0x10D
136#define WM8962_THREED3 0x10E
137#define WM8962_THREED4 0x10F
138#define WM8962_DRC_1 0x114
139#define WM8962_DRC_2 0x115
140#define WM8962_DRC_3 0x116
141#define WM8962_DRC_4 0x117
142#define WM8962_DRC_5 0x118
143#define WM8962_TLOOPBACK 0x11D
144#define WM8962_EQ1 0x14F
145#define WM8962_EQ2 0x150
146#define WM8962_EQ3 0x151
147#define WM8962_EQ4 0x152
148#define WM8962_EQ5 0x153
149#define WM8962_EQ6 0x154
150#define WM8962_EQ7 0x155
151#define WM8962_EQ8 0x156
152#define WM8962_EQ9 0x157
153#define WM8962_EQ10 0x158
154#define WM8962_EQ11 0x159
155#define WM8962_EQ12 0x15A
156#define WM8962_EQ13 0x15B
157#define WM8962_EQ14 0x15C
158#define WM8962_EQ15 0x15D
159#define WM8962_EQ16 0x15E
160#define WM8962_EQ17 0x15F
161#define WM8962_EQ18 0x160
162#define WM8962_EQ19 0x161
163#define WM8962_EQ20 0x162
164#define WM8962_EQ21 0x163
165#define WM8962_EQ22 0x164
166#define WM8962_EQ23 0x165
167#define WM8962_EQ24 0x166
168#define WM8962_EQ25 0x167
169#define WM8962_EQ26 0x168
170#define WM8962_EQ27 0x169
171#define WM8962_EQ28 0x16A
172#define WM8962_EQ29 0x16B
173#define WM8962_EQ30 0x16C
174#define WM8962_EQ31 0x16D
175#define WM8962_EQ32 0x16E
176#define WM8962_EQ33 0x16F
177#define WM8962_EQ34 0x170
178#define WM8962_EQ35 0x171
179#define WM8962_EQ36 0x172
180#define WM8962_EQ37 0x173
181#define WM8962_EQ38 0x174
182#define WM8962_EQ39 0x175
183#define WM8962_EQ40 0x176
184#define WM8962_EQ41 0x177
185#define WM8962_GPIO_BASE 0x200
186#define WM8962_GPIO_2 0x201
187#define WM8962_GPIO_3 0x202
188#define WM8962_GPIO_5 0x204
189#define WM8962_GPIO_6 0x205
190#define WM8962_INTERRUPT_STATUS_1 0x230
191#define WM8962_INTERRUPT_STATUS_2 0x231
192#define WM8962_INTERRUPT_STATUS_1_MASK 0x238
193#define WM8962_INTERRUPT_STATUS_2_MASK 0x239
194#define WM8962_INTERRUPT_CONTROL 0x240
195#define WM8962_IRQ_DEBOUNCE 0x248
196#define WM8962_MICINT_SOURCE_POL 0x24A
197#define WM8962_DSP2_POWER_MANAGEMENT 0x300
198#define WM8962_DSP2_EXECCONTROL 0x40D
199#define WM8962_WRITE_SEQUENCER_0 0x1000
200#define WM8962_WRITE_SEQUENCER_1 0x1001
201#define WM8962_WRITE_SEQUENCER_2 0x1002
202#define WM8962_WRITE_SEQUENCER_3 0x1003
203#define WM8962_WRITE_SEQUENCER_4 0x1004
204#define WM8962_WRITE_SEQUENCER_5 0x1005
205#define WM8962_WRITE_SEQUENCER_6 0x1006
206#define WM8962_WRITE_SEQUENCER_7 0x1007
207#define WM8962_WRITE_SEQUENCER_8 0x1008
208#define WM8962_WRITE_SEQUENCER_9 0x1009
209#define WM8962_WRITE_SEQUENCER_10 0x100A
210#define WM8962_WRITE_SEQUENCER_11 0x100B
211#define WM8962_WRITE_SEQUENCER_12 0x100C
212#define WM8962_WRITE_SEQUENCER_13 0x100D
213#define WM8962_WRITE_SEQUENCER_14 0x100E
214#define WM8962_WRITE_SEQUENCER_15 0x100F
215#define WM8962_WRITE_SEQUENCER_16 0x1010
216#define WM8962_WRITE_SEQUENCER_17 0x1011
217#define WM8962_WRITE_SEQUENCER_18 0x1012
218#define WM8962_WRITE_SEQUENCER_19 0x1013
219#define WM8962_WRITE_SEQUENCER_20 0x1014
220#define WM8962_WRITE_SEQUENCER_21 0x1015
221#define WM8962_WRITE_SEQUENCER_22 0x1016
222#define WM8962_WRITE_SEQUENCER_23 0x1017
223#define WM8962_WRITE_SEQUENCER_24 0x1018
224#define WM8962_WRITE_SEQUENCER_25 0x1019
225#define WM8962_WRITE_SEQUENCER_26 0x101A
226#define WM8962_WRITE_SEQUENCER_27 0x101B
227#define WM8962_WRITE_SEQUENCER_28 0x101C
228#define WM8962_WRITE_SEQUENCER_29 0x101D
229#define WM8962_WRITE_SEQUENCER_30 0x101E
230#define WM8962_WRITE_SEQUENCER_31 0x101F
231#define WM8962_WRITE_SEQUENCER_32 0x1020
232#define WM8962_WRITE_SEQUENCER_33 0x1021
233#define WM8962_WRITE_SEQUENCER_34 0x1022
234#define WM8962_WRITE_SEQUENCER_35 0x1023
235#define WM8962_WRITE_SEQUENCER_36 0x1024
236#define WM8962_WRITE_SEQUENCER_37 0x1025
237#define WM8962_WRITE_SEQUENCER_38 0x1026
238#define WM8962_WRITE_SEQUENCER_39 0x1027
239#define WM8962_WRITE_SEQUENCER_40 0x1028
240#define WM8962_WRITE_SEQUENCER_41 0x1029
241#define WM8962_WRITE_SEQUENCER_42 0x102A
242#define WM8962_WRITE_SEQUENCER_43 0x102B
243#define WM8962_WRITE_SEQUENCER_44 0x102C
244#define WM8962_WRITE_SEQUENCER_45 0x102D
245#define WM8962_WRITE_SEQUENCER_46 0x102E
246#define WM8962_WRITE_SEQUENCER_47 0x102F
247#define WM8962_WRITE_SEQUENCER_48 0x1030
248#define WM8962_WRITE_SEQUENCER_49 0x1031
249#define WM8962_WRITE_SEQUENCER_50 0x1032
250#define WM8962_WRITE_SEQUENCER_51 0x1033
251#define WM8962_WRITE_SEQUENCER_52 0x1034
252#define WM8962_WRITE_SEQUENCER_53 0x1035
253#define WM8962_WRITE_SEQUENCER_54 0x1036
254#define WM8962_WRITE_SEQUENCER_55 0x1037
255#define WM8962_WRITE_SEQUENCER_56 0x1038
256#define WM8962_WRITE_SEQUENCER_57 0x1039
257#define WM8962_WRITE_SEQUENCER_58 0x103A
258#define WM8962_WRITE_SEQUENCER_59 0x103B
259#define WM8962_WRITE_SEQUENCER_60 0x103C
260#define WM8962_WRITE_SEQUENCER_61 0x103D
261#define WM8962_WRITE_SEQUENCER_62 0x103E
262#define WM8962_WRITE_SEQUENCER_63 0x103F
263#define WM8962_WRITE_SEQUENCER_64 0x1040
264#define WM8962_WRITE_SEQUENCER_65 0x1041
265#define WM8962_WRITE_SEQUENCER_66 0x1042
266#define WM8962_WRITE_SEQUENCER_67 0x1043
267#define WM8962_WRITE_SEQUENCER_68 0x1044
268#define WM8962_WRITE_SEQUENCER_69 0x1045
269#define WM8962_WRITE_SEQUENCER_70 0x1046
270#define WM8962_WRITE_SEQUENCER_71 0x1047
271#define WM8962_WRITE_SEQUENCER_72 0x1048
272#define WM8962_WRITE_SEQUENCER_73 0x1049
273#define WM8962_WRITE_SEQUENCER_74 0x104A
274#define WM8962_WRITE_SEQUENCER_75 0x104B
275#define WM8962_WRITE_SEQUENCER_76 0x104C
276#define WM8962_WRITE_SEQUENCER_77 0x104D
277#define WM8962_WRITE_SEQUENCER_78 0x104E
278#define WM8962_WRITE_SEQUENCER_79 0x104F
279#define WM8962_WRITE_SEQUENCER_80 0x1050
280#define WM8962_WRITE_SEQUENCER_81 0x1051
281#define WM8962_WRITE_SEQUENCER_82 0x1052
282#define WM8962_WRITE_SEQUENCER_83 0x1053
283#define WM8962_WRITE_SEQUENCER_84 0x1054
284#define WM8962_WRITE_SEQUENCER_85 0x1055
285#define WM8962_WRITE_SEQUENCER_86 0x1056
286#define WM8962_WRITE_SEQUENCER_87 0x1057
287#define WM8962_WRITE_SEQUENCER_88 0x1058
288#define WM8962_WRITE_SEQUENCER_89 0x1059
289#define WM8962_WRITE_SEQUENCER_90 0x105A
290#define WM8962_WRITE_SEQUENCER_91 0x105B
291#define WM8962_WRITE_SEQUENCER_92 0x105C
292#define WM8962_WRITE_SEQUENCER_93 0x105D
293#define WM8962_WRITE_SEQUENCER_94 0x105E
294#define WM8962_WRITE_SEQUENCER_95 0x105F
295#define WM8962_WRITE_SEQUENCER_96 0x1060
296#define WM8962_WRITE_SEQUENCER_97 0x1061
297#define WM8962_WRITE_SEQUENCER_98 0x1062
298#define WM8962_WRITE_SEQUENCER_99 0x1063
299#define WM8962_WRITE_SEQUENCER_100 0x1064
300#define WM8962_WRITE_SEQUENCER_101 0x1065
301#define WM8962_WRITE_SEQUENCER_102 0x1066
302#define WM8962_WRITE_SEQUENCER_103 0x1067
303#define WM8962_WRITE_SEQUENCER_104 0x1068
304#define WM8962_WRITE_SEQUENCER_105 0x1069
305#define WM8962_WRITE_SEQUENCER_106 0x106A
306#define WM8962_WRITE_SEQUENCER_107 0x106B
307#define WM8962_WRITE_SEQUENCER_108 0x106C
308#define WM8962_WRITE_SEQUENCER_109 0x106D
309#define WM8962_WRITE_SEQUENCER_110 0x106E
310#define WM8962_WRITE_SEQUENCER_111 0x106F
311#define WM8962_WRITE_SEQUENCER_112 0x1070
312#define WM8962_WRITE_SEQUENCER_113 0x1071
313#define WM8962_WRITE_SEQUENCER_114 0x1072
314#define WM8962_WRITE_SEQUENCER_115 0x1073
315#define WM8962_WRITE_SEQUENCER_116 0x1074
316#define WM8962_WRITE_SEQUENCER_117 0x1075
317#define WM8962_WRITE_SEQUENCER_118 0x1076
318#define WM8962_WRITE_SEQUENCER_119 0x1077
319#define WM8962_WRITE_SEQUENCER_120 0x1078
320#define WM8962_WRITE_SEQUENCER_121 0x1079
321#define WM8962_WRITE_SEQUENCER_122 0x107A
322#define WM8962_WRITE_SEQUENCER_123 0x107B
323#define WM8962_WRITE_SEQUENCER_124 0x107C
324#define WM8962_WRITE_SEQUENCER_125 0x107D
325#define WM8962_WRITE_SEQUENCER_126 0x107E
326#define WM8962_WRITE_SEQUENCER_127 0x107F
327#define WM8962_WRITE_SEQUENCER_128 0x1080
328#define WM8962_WRITE_SEQUENCER_129 0x1081
329#define WM8962_WRITE_SEQUENCER_130 0x1082
330#define WM8962_WRITE_SEQUENCER_131 0x1083
331#define WM8962_WRITE_SEQUENCER_132 0x1084
332#define WM8962_WRITE_SEQUENCER_133 0x1085
333#define WM8962_WRITE_SEQUENCER_134 0x1086
334#define WM8962_WRITE_SEQUENCER_135 0x1087
335#define WM8962_WRITE_SEQUENCER_136 0x1088
336#define WM8962_WRITE_SEQUENCER_137 0x1089
337#define WM8962_WRITE_SEQUENCER_138 0x108A
338#define WM8962_WRITE_SEQUENCER_139 0x108B
339#define WM8962_WRITE_SEQUENCER_140 0x108C
340#define WM8962_WRITE_SEQUENCER_141 0x108D
341#define WM8962_WRITE_SEQUENCER_142 0x108E
342#define WM8962_WRITE_SEQUENCER_143 0x108F
343#define WM8962_WRITE_SEQUENCER_144 0x1090
344#define WM8962_WRITE_SEQUENCER_145 0x1091
345#define WM8962_WRITE_SEQUENCER_146 0x1092
346#define WM8962_WRITE_SEQUENCER_147 0x1093
347#define WM8962_WRITE_SEQUENCER_148 0x1094
348#define WM8962_WRITE_SEQUENCER_149 0x1095
349#define WM8962_WRITE_SEQUENCER_150 0x1096
350#define WM8962_WRITE_SEQUENCER_151 0x1097
351#define WM8962_WRITE_SEQUENCER_152 0x1098
352#define WM8962_WRITE_SEQUENCER_153 0x1099
353#define WM8962_WRITE_SEQUENCER_154 0x109A
354#define WM8962_WRITE_SEQUENCER_155 0x109B
355#define WM8962_WRITE_SEQUENCER_156 0x109C
356#define WM8962_WRITE_SEQUENCER_157 0x109D
357#define WM8962_WRITE_SEQUENCER_158 0x109E
358#define WM8962_WRITE_SEQUENCER_159 0x109F
359#define WM8962_WRITE_SEQUENCER_160 0x10A0
360#define WM8962_WRITE_SEQUENCER_161 0x10A1
361#define WM8962_WRITE_SEQUENCER_162 0x10A2
362#define WM8962_WRITE_SEQUENCER_163 0x10A3
363#define WM8962_WRITE_SEQUENCER_164 0x10A4
364#define WM8962_WRITE_SEQUENCER_165 0x10A5
365#define WM8962_WRITE_SEQUENCER_166 0x10A6
366#define WM8962_WRITE_SEQUENCER_167 0x10A7
367#define WM8962_WRITE_SEQUENCER_168 0x10A8
368#define WM8962_WRITE_SEQUENCER_169 0x10A9
369#define WM8962_WRITE_SEQUENCER_170 0x10AA
370#define WM8962_WRITE_SEQUENCER_171 0x10AB
371#define WM8962_WRITE_SEQUENCER_172 0x10AC
372#define WM8962_WRITE_SEQUENCER_173 0x10AD
373#define WM8962_WRITE_SEQUENCER_174 0x10AE
374#define WM8962_WRITE_SEQUENCER_175 0x10AF
375#define WM8962_WRITE_SEQUENCER_176 0x10B0
376#define WM8962_WRITE_SEQUENCER_177 0x10B1
377#define WM8962_WRITE_SEQUENCER_178 0x10B2
378#define WM8962_WRITE_SEQUENCER_179 0x10B3
379#define WM8962_WRITE_SEQUENCER_180 0x10B4
380#define WM8962_WRITE_SEQUENCER_181 0x10B5
381#define WM8962_WRITE_SEQUENCER_182 0x10B6
382#define WM8962_WRITE_SEQUENCER_183 0x10B7
383#define WM8962_WRITE_SEQUENCER_184 0x10B8
384#define WM8962_WRITE_SEQUENCER_185 0x10B9
385#define WM8962_WRITE_SEQUENCER_186 0x10BA
386#define WM8962_WRITE_SEQUENCER_187 0x10BB
387#define WM8962_WRITE_SEQUENCER_188 0x10BC
388#define WM8962_WRITE_SEQUENCER_189 0x10BD
389#define WM8962_WRITE_SEQUENCER_190 0x10BE
390#define WM8962_WRITE_SEQUENCER_191 0x10BF
391#define WM8962_WRITE_SEQUENCER_192 0x10C0
392#define WM8962_WRITE_SEQUENCER_193 0x10C1
393#define WM8962_WRITE_SEQUENCER_194 0x10C2
394#define WM8962_WRITE_SEQUENCER_195 0x10C3
395#define WM8962_WRITE_SEQUENCER_196 0x10C4
396#define WM8962_WRITE_SEQUENCER_197 0x10C5
397#define WM8962_WRITE_SEQUENCER_198 0x10C6
398#define WM8962_WRITE_SEQUENCER_199 0x10C7
399#define WM8962_WRITE_SEQUENCER_200 0x10C8
400#define WM8962_WRITE_SEQUENCER_201 0x10C9
401#define WM8962_WRITE_SEQUENCER_202 0x10CA
402#define WM8962_WRITE_SEQUENCER_203 0x10CB
403#define WM8962_WRITE_SEQUENCER_204 0x10CC
404#define WM8962_WRITE_SEQUENCER_205 0x10CD
405#define WM8962_WRITE_SEQUENCER_206 0x10CE
406#define WM8962_WRITE_SEQUENCER_207 0x10CF
407#define WM8962_WRITE_SEQUENCER_208 0x10D0
408#define WM8962_WRITE_SEQUENCER_209 0x10D1
409#define WM8962_WRITE_SEQUENCER_210 0x10D2
410#define WM8962_WRITE_SEQUENCER_211 0x10D3
411#define WM8962_WRITE_SEQUENCER_212 0x10D4
412#define WM8962_WRITE_SEQUENCER_213 0x10D5
413#define WM8962_WRITE_SEQUENCER_214 0x10D6
414#define WM8962_WRITE_SEQUENCER_215 0x10D7
415#define WM8962_WRITE_SEQUENCER_216 0x10D8
416#define WM8962_WRITE_SEQUENCER_217 0x10D9
417#define WM8962_WRITE_SEQUENCER_218 0x10DA
418#define WM8962_WRITE_SEQUENCER_219 0x10DB
419#define WM8962_WRITE_SEQUENCER_220 0x10DC
420#define WM8962_WRITE_SEQUENCER_221 0x10DD
421#define WM8962_WRITE_SEQUENCER_222 0x10DE
422#define WM8962_WRITE_SEQUENCER_223 0x10DF
423#define WM8962_WRITE_SEQUENCER_224 0x10E0
424#define WM8962_WRITE_SEQUENCER_225 0x10E1
425#define WM8962_WRITE_SEQUENCER_226 0x10E2
426#define WM8962_WRITE_SEQUENCER_227 0x10E3
427#define WM8962_WRITE_SEQUENCER_228 0x10E4
428#define WM8962_WRITE_SEQUENCER_229 0x10E5
429#define WM8962_WRITE_SEQUENCER_230 0x10E6
430#define WM8962_WRITE_SEQUENCER_231 0x10E7
431#define WM8962_WRITE_SEQUENCER_232 0x10E8
432#define WM8962_WRITE_SEQUENCER_233 0x10E9
433#define WM8962_WRITE_SEQUENCER_234 0x10EA
434#define WM8962_WRITE_SEQUENCER_235 0x10EB
435#define WM8962_WRITE_SEQUENCER_236 0x10EC
436#define WM8962_WRITE_SEQUENCER_237 0x10ED
437#define WM8962_WRITE_SEQUENCER_238 0x10EE
438#define WM8962_WRITE_SEQUENCER_239 0x10EF
439#define WM8962_WRITE_SEQUENCER_240 0x10F0
440#define WM8962_WRITE_SEQUENCER_241 0x10F1
441#define WM8962_WRITE_SEQUENCER_242 0x10F2
442#define WM8962_WRITE_SEQUENCER_243 0x10F3
443#define WM8962_WRITE_SEQUENCER_244 0x10F4
444#define WM8962_WRITE_SEQUENCER_245 0x10F5
445#define WM8962_WRITE_SEQUENCER_246 0x10F6
446#define WM8962_WRITE_SEQUENCER_247 0x10F7
447#define WM8962_WRITE_SEQUENCER_248 0x10F8
448#define WM8962_WRITE_SEQUENCER_249 0x10F9
449#define WM8962_WRITE_SEQUENCER_250 0x10FA
450#define WM8962_WRITE_SEQUENCER_251 0x10FB
451#define WM8962_WRITE_SEQUENCER_252 0x10FC
452#define WM8962_WRITE_SEQUENCER_253 0x10FD
453#define WM8962_WRITE_SEQUENCER_254 0x10FE
454#define WM8962_WRITE_SEQUENCER_255 0x10FF
455#define WM8962_WRITE_SEQUENCER_256 0x1100
456#define WM8962_WRITE_SEQUENCER_257 0x1101
457#define WM8962_WRITE_SEQUENCER_258 0x1102
458#define WM8962_WRITE_SEQUENCER_259 0x1103
459#define WM8962_WRITE_SEQUENCER_260 0x1104
460#define WM8962_WRITE_SEQUENCER_261 0x1105
461#define WM8962_WRITE_SEQUENCER_262 0x1106
462#define WM8962_WRITE_SEQUENCER_263 0x1107
463#define WM8962_WRITE_SEQUENCER_264 0x1108
464#define WM8962_WRITE_SEQUENCER_265 0x1109
465#define WM8962_WRITE_SEQUENCER_266 0x110A
466#define WM8962_WRITE_SEQUENCER_267 0x110B
467#define WM8962_WRITE_SEQUENCER_268 0x110C
468#define WM8962_WRITE_SEQUENCER_269 0x110D
469#define WM8962_WRITE_SEQUENCER_270 0x110E
470#define WM8962_WRITE_SEQUENCER_271 0x110F
471#define WM8962_WRITE_SEQUENCER_272 0x1110
472#define WM8962_WRITE_SEQUENCER_273 0x1111
473#define WM8962_WRITE_SEQUENCER_274 0x1112
474#define WM8962_WRITE_SEQUENCER_275 0x1113
475#define WM8962_WRITE_SEQUENCER_276 0x1114
476#define WM8962_WRITE_SEQUENCER_277 0x1115
477#define WM8962_WRITE_SEQUENCER_278 0x1116
478#define WM8962_WRITE_SEQUENCER_279 0x1117
479#define WM8962_WRITE_SEQUENCER_280 0x1118
480#define WM8962_WRITE_SEQUENCER_281 0x1119
481#define WM8962_WRITE_SEQUENCER_282 0x111A
482#define WM8962_WRITE_SEQUENCER_283 0x111B
483#define WM8962_WRITE_SEQUENCER_284 0x111C
484#define WM8962_WRITE_SEQUENCER_285 0x111D
485#define WM8962_WRITE_SEQUENCER_286 0x111E
486#define WM8962_WRITE_SEQUENCER_287 0x111F
487#define WM8962_WRITE_SEQUENCER_288 0x1120
488#define WM8962_WRITE_SEQUENCER_289 0x1121
489#define WM8962_WRITE_SEQUENCER_290 0x1122
490#define WM8962_WRITE_SEQUENCER_291 0x1123
491#define WM8962_WRITE_SEQUENCER_292 0x1124
492#define WM8962_WRITE_SEQUENCER_293 0x1125
493#define WM8962_WRITE_SEQUENCER_294 0x1126
494#define WM8962_WRITE_SEQUENCER_295 0x1127
495#define WM8962_WRITE_SEQUENCER_296 0x1128
496#define WM8962_WRITE_SEQUENCER_297 0x1129
497#define WM8962_WRITE_SEQUENCER_298 0x112A
498#define WM8962_WRITE_SEQUENCER_299 0x112B
499#define WM8962_WRITE_SEQUENCER_300 0x112C
500#define WM8962_WRITE_SEQUENCER_301 0x112D
501#define WM8962_WRITE_SEQUENCER_302 0x112E
502#define WM8962_WRITE_SEQUENCER_303 0x112F
503#define WM8962_WRITE_SEQUENCER_304 0x1130
504#define WM8962_WRITE_SEQUENCER_305 0x1131
505#define WM8962_WRITE_SEQUENCER_306 0x1132
506#define WM8962_WRITE_SEQUENCER_307 0x1133
507#define WM8962_WRITE_SEQUENCER_308 0x1134
508#define WM8962_WRITE_SEQUENCER_309 0x1135
509#define WM8962_WRITE_SEQUENCER_310 0x1136
510#define WM8962_WRITE_SEQUENCER_311 0x1137
511#define WM8962_WRITE_SEQUENCER_312 0x1138
512#define WM8962_WRITE_SEQUENCER_313 0x1139
513#define WM8962_WRITE_SEQUENCER_314 0x113A
514#define WM8962_WRITE_SEQUENCER_315 0x113B
515#define WM8962_WRITE_SEQUENCER_316 0x113C
516#define WM8962_WRITE_SEQUENCER_317 0x113D
517#define WM8962_WRITE_SEQUENCER_318 0x113E
518#define WM8962_WRITE_SEQUENCER_319 0x113F
519#define WM8962_WRITE_SEQUENCER_320 0x1140
520#define WM8962_WRITE_SEQUENCER_321 0x1141
521#define WM8962_WRITE_SEQUENCER_322 0x1142
522#define WM8962_WRITE_SEQUENCER_323 0x1143
523#define WM8962_WRITE_SEQUENCER_324 0x1144
524#define WM8962_WRITE_SEQUENCER_325 0x1145
525#define WM8962_WRITE_SEQUENCER_326 0x1146
526#define WM8962_WRITE_SEQUENCER_327 0x1147
527#define WM8962_WRITE_SEQUENCER_328 0x1148
528#define WM8962_WRITE_SEQUENCER_329 0x1149
529#define WM8962_WRITE_SEQUENCER_330 0x114A
530#define WM8962_WRITE_SEQUENCER_331 0x114B
531#define WM8962_WRITE_SEQUENCER_332 0x114C
532#define WM8962_WRITE_SEQUENCER_333 0x114D
533#define WM8962_WRITE_SEQUENCER_334 0x114E
534#define WM8962_WRITE_SEQUENCER_335 0x114F
535#define WM8962_WRITE_SEQUENCER_336 0x1150
536#define WM8962_WRITE_SEQUENCER_337 0x1151
537#define WM8962_WRITE_SEQUENCER_338 0x1152
538#define WM8962_WRITE_SEQUENCER_339 0x1153
539#define WM8962_WRITE_SEQUENCER_340 0x1154
540#define WM8962_WRITE_SEQUENCER_341 0x1155
541#define WM8962_WRITE_SEQUENCER_342 0x1156
542#define WM8962_WRITE_SEQUENCER_343 0x1157
543#define WM8962_WRITE_SEQUENCER_344 0x1158
544#define WM8962_WRITE_SEQUENCER_345 0x1159
545#define WM8962_WRITE_SEQUENCER_346 0x115A
546#define WM8962_WRITE_SEQUENCER_347 0x115B
547#define WM8962_WRITE_SEQUENCER_348 0x115C
548#define WM8962_WRITE_SEQUENCER_349 0x115D
549#define WM8962_WRITE_SEQUENCER_350 0x115E
550#define WM8962_WRITE_SEQUENCER_351 0x115F
551#define WM8962_WRITE_SEQUENCER_352 0x1160
552#define WM8962_WRITE_SEQUENCER_353 0x1161
553#define WM8962_WRITE_SEQUENCER_354 0x1162
554#define WM8962_WRITE_SEQUENCER_355 0x1163
555#define WM8962_WRITE_SEQUENCER_356 0x1164
556#define WM8962_WRITE_SEQUENCER_357 0x1165
557#define WM8962_WRITE_SEQUENCER_358 0x1166
558#define WM8962_WRITE_SEQUENCER_359 0x1167
559#define WM8962_WRITE_SEQUENCER_360 0x1168
560#define WM8962_WRITE_SEQUENCER_361 0x1169
561#define WM8962_WRITE_SEQUENCER_362 0x116A
562#define WM8962_WRITE_SEQUENCER_363 0x116B
563#define WM8962_WRITE_SEQUENCER_364 0x116C
564#define WM8962_WRITE_SEQUENCER_365 0x116D
565#define WM8962_WRITE_SEQUENCER_366 0x116E
566#define WM8962_WRITE_SEQUENCER_367 0x116F
567#define WM8962_WRITE_SEQUENCER_368 0x1170
568#define WM8962_WRITE_SEQUENCER_369 0x1171
569#define WM8962_WRITE_SEQUENCER_370 0x1172
570#define WM8962_WRITE_SEQUENCER_371 0x1173
571#define WM8962_WRITE_SEQUENCER_372 0x1174
572#define WM8962_WRITE_SEQUENCER_373 0x1175
573#define WM8962_WRITE_SEQUENCER_374 0x1176
574#define WM8962_WRITE_SEQUENCER_375 0x1177
575#define WM8962_WRITE_SEQUENCER_376 0x1178
576#define WM8962_WRITE_SEQUENCER_377 0x1179
577#define WM8962_WRITE_SEQUENCER_378 0x117A
578#define WM8962_WRITE_SEQUENCER_379 0x117B
579#define WM8962_WRITE_SEQUENCER_380 0x117C
580#define WM8962_WRITE_SEQUENCER_381 0x117D
581#define WM8962_WRITE_SEQUENCER_382 0x117E
582#define WM8962_WRITE_SEQUENCER_383 0x117F
583#define WM8962_WRITE_SEQUENCER_384 0x1180
584#define WM8962_WRITE_SEQUENCER_385 0x1181
585#define WM8962_WRITE_SEQUENCER_386 0x1182
586#define WM8962_WRITE_SEQUENCER_387 0x1183
587#define WM8962_WRITE_SEQUENCER_388 0x1184
588#define WM8962_WRITE_SEQUENCER_389 0x1185
589#define WM8962_WRITE_SEQUENCER_390 0x1186
590#define WM8962_WRITE_SEQUENCER_391 0x1187
591#define WM8962_WRITE_SEQUENCER_392 0x1188
592#define WM8962_WRITE_SEQUENCER_393 0x1189
593#define WM8962_WRITE_SEQUENCER_394 0x118A
594#define WM8962_WRITE_SEQUENCER_395 0x118B
595#define WM8962_WRITE_SEQUENCER_396 0x118C
596#define WM8962_WRITE_SEQUENCER_397 0x118D
597#define WM8962_WRITE_SEQUENCER_398 0x118E
598#define WM8962_WRITE_SEQUENCER_399 0x118F
599#define WM8962_WRITE_SEQUENCER_400 0x1190
600#define WM8962_WRITE_SEQUENCER_401 0x1191
601#define WM8962_WRITE_SEQUENCER_402 0x1192
602#define WM8962_WRITE_SEQUENCER_403 0x1193
603#define WM8962_WRITE_SEQUENCER_404 0x1194
604#define WM8962_WRITE_SEQUENCER_405 0x1195
605#define WM8962_WRITE_SEQUENCER_406 0x1196
606#define WM8962_WRITE_SEQUENCER_407 0x1197
607#define WM8962_WRITE_SEQUENCER_408 0x1198
608#define WM8962_WRITE_SEQUENCER_409 0x1199
609#define WM8962_WRITE_SEQUENCER_410 0x119A
610#define WM8962_WRITE_SEQUENCER_411 0x119B
611#define WM8962_WRITE_SEQUENCER_412 0x119C
612#define WM8962_WRITE_SEQUENCER_413 0x119D
613#define WM8962_WRITE_SEQUENCER_414 0x119E
614#define WM8962_WRITE_SEQUENCER_415 0x119F
615#define WM8962_WRITE_SEQUENCER_416 0x11A0
616#define WM8962_WRITE_SEQUENCER_417 0x11A1
617#define WM8962_WRITE_SEQUENCER_418 0x11A2
618#define WM8962_WRITE_SEQUENCER_419 0x11A3
619#define WM8962_WRITE_SEQUENCER_420 0x11A4
620#define WM8962_WRITE_SEQUENCER_421 0x11A5
621#define WM8962_WRITE_SEQUENCER_422 0x11A6
622#define WM8962_WRITE_SEQUENCER_423 0x11A7
623#define WM8962_WRITE_SEQUENCER_424 0x11A8
624#define WM8962_WRITE_SEQUENCER_425 0x11A9
625#define WM8962_WRITE_SEQUENCER_426 0x11AA
626#define WM8962_WRITE_SEQUENCER_427 0x11AB
627#define WM8962_WRITE_SEQUENCER_428 0x11AC
628#define WM8962_WRITE_SEQUENCER_429 0x11AD
629#define WM8962_WRITE_SEQUENCER_430 0x11AE
630#define WM8962_WRITE_SEQUENCER_431 0x11AF
631#define WM8962_WRITE_SEQUENCER_432 0x11B0
632#define WM8962_WRITE_SEQUENCER_433 0x11B1
633#define WM8962_WRITE_SEQUENCER_434 0x11B2
634#define WM8962_WRITE_SEQUENCER_435 0x11B3
635#define WM8962_WRITE_SEQUENCER_436 0x11B4
636#define WM8962_WRITE_SEQUENCER_437 0x11B5
637#define WM8962_WRITE_SEQUENCER_438 0x11B6
638#define WM8962_WRITE_SEQUENCER_439 0x11B7
639#define WM8962_WRITE_SEQUENCER_440 0x11B8
640#define WM8962_WRITE_SEQUENCER_441 0x11B9
641#define WM8962_WRITE_SEQUENCER_442 0x11BA
642#define WM8962_WRITE_SEQUENCER_443 0x11BB
643#define WM8962_WRITE_SEQUENCER_444 0x11BC
644#define WM8962_WRITE_SEQUENCER_445 0x11BD
645#define WM8962_WRITE_SEQUENCER_446 0x11BE
646#define WM8962_WRITE_SEQUENCER_447 0x11BF
647#define WM8962_WRITE_SEQUENCER_448 0x11C0
648#define WM8962_WRITE_SEQUENCER_449 0x11C1
649#define WM8962_WRITE_SEQUENCER_450 0x11C2
650#define WM8962_WRITE_SEQUENCER_451 0x11C3
651#define WM8962_WRITE_SEQUENCER_452 0x11C4
652#define WM8962_WRITE_SEQUENCER_453 0x11C5
653#define WM8962_WRITE_SEQUENCER_454 0x11C6
654#define WM8962_WRITE_SEQUENCER_455 0x11C7
655#define WM8962_WRITE_SEQUENCER_456 0x11C8
656#define WM8962_WRITE_SEQUENCER_457 0x11C9
657#define WM8962_WRITE_SEQUENCER_458 0x11CA
658#define WM8962_WRITE_SEQUENCER_459 0x11CB
659#define WM8962_WRITE_SEQUENCER_460 0x11CC
660#define WM8962_WRITE_SEQUENCER_461 0x11CD
661#define WM8962_WRITE_SEQUENCER_462 0x11CE
662#define WM8962_WRITE_SEQUENCER_463 0x11CF
663#define WM8962_WRITE_SEQUENCER_464 0x11D0
664#define WM8962_WRITE_SEQUENCER_465 0x11D1
665#define WM8962_WRITE_SEQUENCER_466 0x11D2
666#define WM8962_WRITE_SEQUENCER_467 0x11D3
667#define WM8962_WRITE_SEQUENCER_468 0x11D4
668#define WM8962_WRITE_SEQUENCER_469 0x11D5
669#define WM8962_WRITE_SEQUENCER_470 0x11D6
670#define WM8962_WRITE_SEQUENCER_471 0x11D7
671#define WM8962_WRITE_SEQUENCER_472 0x11D8
672#define WM8962_WRITE_SEQUENCER_473 0x11D9
673#define WM8962_WRITE_SEQUENCER_474 0x11DA
674#define WM8962_WRITE_SEQUENCER_475 0x11DB
675#define WM8962_WRITE_SEQUENCER_476 0x11DC
676#define WM8962_WRITE_SEQUENCER_477 0x11DD
677#define WM8962_WRITE_SEQUENCER_478 0x11DE
678#define WM8962_WRITE_SEQUENCER_479 0x11DF
679#define WM8962_WRITE_SEQUENCER_480 0x11E0
680#define WM8962_WRITE_SEQUENCER_481 0x11E1
681#define WM8962_WRITE_SEQUENCER_482 0x11E2
682#define WM8962_WRITE_SEQUENCER_483 0x11E3
683#define WM8962_WRITE_SEQUENCER_484 0x11E4
684#define WM8962_WRITE_SEQUENCER_485 0x11E5
685#define WM8962_WRITE_SEQUENCER_486 0x11E6
686#define WM8962_WRITE_SEQUENCER_487 0x11E7
687#define WM8962_WRITE_SEQUENCER_488 0x11E8
688#define WM8962_WRITE_SEQUENCER_489 0x11E9
689#define WM8962_WRITE_SEQUENCER_490 0x11EA
690#define WM8962_WRITE_SEQUENCER_491 0x11EB
691#define WM8962_WRITE_SEQUENCER_492 0x11EC
692#define WM8962_WRITE_SEQUENCER_493 0x11ED
693#define WM8962_WRITE_SEQUENCER_494 0x11EE
694#define WM8962_WRITE_SEQUENCER_495 0x11EF
695#define WM8962_WRITE_SEQUENCER_496 0x11F0
696#define WM8962_WRITE_SEQUENCER_497 0x11F1
697#define WM8962_WRITE_SEQUENCER_498 0x11F2
698#define WM8962_WRITE_SEQUENCER_499 0x11F3
699#define WM8962_WRITE_SEQUENCER_500 0x11F4
700#define WM8962_WRITE_SEQUENCER_501 0x11F5
701#define WM8962_WRITE_SEQUENCER_502 0x11F6
702#define WM8962_WRITE_SEQUENCER_503 0x11F7
703#define WM8962_WRITE_SEQUENCER_504 0x11F8
704#define WM8962_WRITE_SEQUENCER_505 0x11F9
705#define WM8962_WRITE_SEQUENCER_506 0x11FA
706#define WM8962_WRITE_SEQUENCER_507 0x11FB
707#define WM8962_WRITE_SEQUENCER_508 0x11FC
708#define WM8962_WRITE_SEQUENCER_509 0x11FD
709#define WM8962_WRITE_SEQUENCER_510 0x11FE
710#define WM8962_WRITE_SEQUENCER_511 0x11FF
711#define WM8962_DSP2_INSTRUCTION_RAM_0 0x2000
712#define WM8962_DSP2_ADDRESS_RAM_2 0x2400
713#define WM8962_DSP2_ADDRESS_RAM_1 0x2401
714#define WM8962_DSP2_ADDRESS_RAM_0 0x2402
715#define WM8962_DSP2_DATA1_RAM_1 0x3000
716#define WM8962_DSP2_DATA1_RAM_0 0x3001
717#define WM8962_DSP2_DATA2_RAM_1 0x3400
718#define WM8962_DSP2_DATA2_RAM_0 0x3401
719#define WM8962_DSP2_DATA3_RAM_1 0x3800
720#define WM8962_DSP2_DATA3_RAM_0 0x3801
721#define WM8962_DSP2_COEFF_RAM_0 0x3C00
722#define WM8962_RETUNEADC_SHARED_COEFF_1 0x4000
723#define WM8962_RETUNEADC_SHARED_COEFF_0 0x4001
724#define WM8962_RETUNEDAC_SHARED_COEFF_1 0x4002
725#define WM8962_RETUNEDAC_SHARED_COEFF_0 0x4003
726#define WM8962_SOUNDSTAGE_ENABLES_1 0x4004
727#define WM8962_SOUNDSTAGE_ENABLES_0 0x4005
728#define WM8962_HDBASS_AI_1 0x4200
729#define WM8962_HDBASS_AI_0 0x4201
730#define WM8962_HDBASS_AR_1 0x4202
731#define WM8962_HDBASS_AR_0 0x4203
732#define WM8962_HDBASS_B_1 0x4204
733#define WM8962_HDBASS_B_0 0x4205
734#define WM8962_HDBASS_K_1 0x4206
735#define WM8962_HDBASS_K_0 0x4207
736#define WM8962_HDBASS_N1_1 0x4208
737#define WM8962_HDBASS_N1_0 0x4209
738#define WM8962_HDBASS_N2_1 0x420A
739#define WM8962_HDBASS_N2_0 0x420B
740#define WM8962_HDBASS_N3_1 0x420C
741#define WM8962_HDBASS_N3_0 0x420D
742#define WM8962_HDBASS_N4_1 0x420E
743#define WM8962_HDBASS_N4_0 0x420F
744#define WM8962_HDBASS_N5_1 0x4210
745#define WM8962_HDBASS_N5_0 0x4211
746#define WM8962_HDBASS_X1_1 0x4212
747#define WM8962_HDBASS_X1_0 0x4213
748#define WM8962_HDBASS_X2_1 0x4214
749#define WM8962_HDBASS_X2_0 0x4215
750#define WM8962_HDBASS_X3_1 0x4216
751#define WM8962_HDBASS_X3_0 0x4217
752#define WM8962_HDBASS_ATK_1 0x4218
753#define WM8962_HDBASS_ATK_0 0x4219
754#define WM8962_HDBASS_DCY_1 0x421A
755#define WM8962_HDBASS_DCY_0 0x421B
756#define WM8962_HDBASS_PG_1 0x421C
757#define WM8962_HDBASS_PG_0 0x421D
758#define WM8962_HPF_C_1 0x4400
759#define WM8962_HPF_C_0 0x4401
760#define WM8962_ADCL_RETUNE_C1_1 0x4600
761#define WM8962_ADCL_RETUNE_C1_0 0x4601
762#define WM8962_ADCL_RETUNE_C2_1 0x4602
763#define WM8962_ADCL_RETUNE_C2_0 0x4603
764#define WM8962_ADCL_RETUNE_C3_1 0x4604
765#define WM8962_ADCL_RETUNE_C3_0 0x4605
766#define WM8962_ADCL_RETUNE_C4_1 0x4606
767#define WM8962_ADCL_RETUNE_C4_0 0x4607
768#define WM8962_ADCL_RETUNE_C5_1 0x4608
769#define WM8962_ADCL_RETUNE_C5_0 0x4609
770#define WM8962_ADCL_RETUNE_C6_1 0x460A
771#define WM8962_ADCL_RETUNE_C6_0 0x460B
772#define WM8962_ADCL_RETUNE_C7_1 0x460C
773#define WM8962_ADCL_RETUNE_C7_0 0x460D
774#define WM8962_ADCL_RETUNE_C8_1 0x460E
775#define WM8962_ADCL_RETUNE_C8_0 0x460F
776#define WM8962_ADCL_RETUNE_C9_1 0x4610
777#define WM8962_ADCL_RETUNE_C9_0 0x4611
778#define WM8962_ADCL_RETUNE_C10_1 0x4612
779#define WM8962_ADCL_RETUNE_C10_0 0x4613
780#define WM8962_ADCL_RETUNE_C11_1 0x4614
781#define WM8962_ADCL_RETUNE_C11_0 0x4615
782#define WM8962_ADCL_RETUNE_C12_1 0x4616
783#define WM8962_ADCL_RETUNE_C12_0 0x4617
784#define WM8962_ADCL_RETUNE_C13_1 0x4618
785#define WM8962_ADCL_RETUNE_C13_0 0x4619
786#define WM8962_ADCL_RETUNE_C14_1 0x461A
787#define WM8962_ADCL_RETUNE_C14_0 0x461B
788#define WM8962_ADCL_RETUNE_C15_1 0x461C
789#define WM8962_ADCL_RETUNE_C15_0 0x461D
790#define WM8962_ADCL_RETUNE_C16_1 0x461E
791#define WM8962_ADCL_RETUNE_C16_0 0x461F
792#define WM8962_ADCL_RETUNE_C17_1 0x4620
793#define WM8962_ADCL_RETUNE_C17_0 0x4621
794#define WM8962_ADCL_RETUNE_C18_1 0x4622
795#define WM8962_ADCL_RETUNE_C18_0 0x4623
796#define WM8962_ADCL_RETUNE_C19_1 0x4624
797#define WM8962_ADCL_RETUNE_C19_0 0x4625
798#define WM8962_ADCL_RETUNE_C20_1 0x4626
799#define WM8962_ADCL_RETUNE_C20_0 0x4627
800#define WM8962_ADCL_RETUNE_C21_1 0x4628
801#define WM8962_ADCL_RETUNE_C21_0 0x4629
802#define WM8962_ADCL_RETUNE_C22_1 0x462A
803#define WM8962_ADCL_RETUNE_C22_0 0x462B
804#define WM8962_ADCL_RETUNE_C23_1 0x462C
805#define WM8962_ADCL_RETUNE_C23_0 0x462D
806#define WM8962_ADCL_RETUNE_C24_1 0x462E
807#define WM8962_ADCL_RETUNE_C24_0 0x462F
808#define WM8962_ADCL_RETUNE_C25_1 0x4630
809#define WM8962_ADCL_RETUNE_C25_0 0x4631
810#define WM8962_ADCL_RETUNE_C26_1 0x4632
811#define WM8962_ADCL_RETUNE_C26_0 0x4633
812#define WM8962_ADCL_RETUNE_C27_1 0x4634
813#define WM8962_ADCL_RETUNE_C27_0 0x4635
814#define WM8962_ADCL_RETUNE_C28_1 0x4636
815#define WM8962_ADCL_RETUNE_C28_0 0x4637
816#define WM8962_ADCL_RETUNE_C29_1 0x4638
817#define WM8962_ADCL_RETUNE_C29_0 0x4639
818#define WM8962_ADCL_RETUNE_C30_1 0x463A
819#define WM8962_ADCL_RETUNE_C30_0 0x463B
820#define WM8962_ADCL_RETUNE_C31_1 0x463C
821#define WM8962_ADCL_RETUNE_C31_0 0x463D
822#define WM8962_ADCL_RETUNE_C32_1 0x463E
823#define WM8962_ADCL_RETUNE_C32_0 0x463F
824#define WM8962_RETUNEADC_PG2_1 0x4800
825#define WM8962_RETUNEADC_PG2_0 0x4801
826#define WM8962_RETUNEADC_PG_1 0x4802
827#define WM8962_RETUNEADC_PG_0 0x4803
828#define WM8962_ADCR_RETUNE_C1_1 0x4A00
829#define WM8962_ADCR_RETUNE_C1_0 0x4A01
830#define WM8962_ADCR_RETUNE_C2_1 0x4A02
831#define WM8962_ADCR_RETUNE_C2_0 0x4A03
832#define WM8962_ADCR_RETUNE_C3_1 0x4A04
833#define WM8962_ADCR_RETUNE_C3_0 0x4A05
834#define WM8962_ADCR_RETUNE_C4_1 0x4A06
835#define WM8962_ADCR_RETUNE_C4_0 0x4A07
836#define WM8962_ADCR_RETUNE_C5_1 0x4A08
837#define WM8962_ADCR_RETUNE_C5_0 0x4A09
838#define WM8962_ADCR_RETUNE_C6_1 0x4A0A
839#define WM8962_ADCR_RETUNE_C6_0 0x4A0B
840#define WM8962_ADCR_RETUNE_C7_1 0x4A0C
841#define WM8962_ADCR_RETUNE_C7_0 0x4A0D
842#define WM8962_ADCR_RETUNE_C8_1 0x4A0E
843#define WM8962_ADCR_RETUNE_C8_0 0x4A0F
844#define WM8962_ADCR_RETUNE_C9_1 0x4A10
845#define WM8962_ADCR_RETUNE_C9_0 0x4A11
846#define WM8962_ADCR_RETUNE_C10_1 0x4A12
847#define WM8962_ADCR_RETUNE_C10_0 0x4A13
848#define WM8962_ADCR_RETUNE_C11_1 0x4A14
849#define WM8962_ADCR_RETUNE_C11_0 0x4A15
850#define WM8962_ADCR_RETUNE_C12_1 0x4A16
851#define WM8962_ADCR_RETUNE_C12_0 0x4A17
852#define WM8962_ADCR_RETUNE_C13_1 0x4A18
853#define WM8962_ADCR_RETUNE_C13_0 0x4A19
854#define WM8962_ADCR_RETUNE_C14_1 0x4A1A
855#define WM8962_ADCR_RETUNE_C14_0 0x4A1B
856#define WM8962_ADCR_RETUNE_C15_1 0x4A1C
857#define WM8962_ADCR_RETUNE_C15_0 0x4A1D
858#define WM8962_ADCR_RETUNE_C16_1 0x4A1E
859#define WM8962_ADCR_RETUNE_C16_0 0x4A1F
860#define WM8962_ADCR_RETUNE_C17_1 0x4A20
861#define WM8962_ADCR_RETUNE_C17_0 0x4A21
862#define WM8962_ADCR_RETUNE_C18_1 0x4A22
863#define WM8962_ADCR_RETUNE_C18_0 0x4A23
864#define WM8962_ADCR_RETUNE_C19_1 0x4A24
865#define WM8962_ADCR_RETUNE_C19_0 0x4A25
866#define WM8962_ADCR_RETUNE_C20_1 0x4A26
867#define WM8962_ADCR_RETUNE_C20_0 0x4A27
868#define WM8962_ADCR_RETUNE_C21_1 0x4A28
869#define WM8962_ADCR_RETUNE_C21_0 0x4A29
870#define WM8962_ADCR_RETUNE_C22_1 0x4A2A
871#define WM8962_ADCR_RETUNE_C22_0 0x4A2B
872#define WM8962_ADCR_RETUNE_C23_1 0x4A2C
873#define WM8962_ADCR_RETUNE_C23_0 0x4A2D
874#define WM8962_ADCR_RETUNE_C24_1 0x4A2E
875#define WM8962_ADCR_RETUNE_C24_0 0x4A2F
876#define WM8962_ADCR_RETUNE_C25_1 0x4A30
877#define WM8962_ADCR_RETUNE_C25_0 0x4A31
878#define WM8962_ADCR_RETUNE_C26_1 0x4A32
879#define WM8962_ADCR_RETUNE_C26_0 0x4A33
880#define WM8962_ADCR_RETUNE_C27_1 0x4A34
881#define WM8962_ADCR_RETUNE_C27_0 0x4A35
882#define WM8962_ADCR_RETUNE_C28_1 0x4A36
883#define WM8962_ADCR_RETUNE_C28_0 0x4A37
884#define WM8962_ADCR_RETUNE_C29_1 0x4A38
885#define WM8962_ADCR_RETUNE_C29_0 0x4A39
886#define WM8962_ADCR_RETUNE_C30_1 0x4A3A
887#define WM8962_ADCR_RETUNE_C30_0 0x4A3B
888#define WM8962_ADCR_RETUNE_C31_1 0x4A3C
889#define WM8962_ADCR_RETUNE_C31_0 0x4A3D
890#define WM8962_ADCR_RETUNE_C32_1 0x4A3E
891#define WM8962_ADCR_RETUNE_C32_0 0x4A3F
892#define WM8962_DACL_RETUNE_C1_1 0x4C00
893#define WM8962_DACL_RETUNE_C1_0 0x4C01
894#define WM8962_DACL_RETUNE_C2_1 0x4C02
895#define WM8962_DACL_RETUNE_C2_0 0x4C03
896#define WM8962_DACL_RETUNE_C3_1 0x4C04
897#define WM8962_DACL_RETUNE_C3_0 0x4C05
898#define WM8962_DACL_RETUNE_C4_1 0x4C06
899#define WM8962_DACL_RETUNE_C4_0 0x4C07
900#define WM8962_DACL_RETUNE_C5_1 0x4C08
901#define WM8962_DACL_RETUNE_C5_0 0x4C09
902#define WM8962_DACL_RETUNE_C6_1 0x4C0A
903#define WM8962_DACL_RETUNE_C6_0 0x4C0B
904#define WM8962_DACL_RETUNE_C7_1 0x4C0C
905#define WM8962_DACL_RETUNE_C7_0 0x4C0D
906#define WM8962_DACL_RETUNE_C8_1 0x4C0E
907#define WM8962_DACL_RETUNE_C8_0 0x4C0F
908#define WM8962_DACL_RETUNE_C9_1 0x4C10
909#define WM8962_DACL_RETUNE_C9_0 0x4C11
910#define WM8962_DACL_RETUNE_C10_1 0x4C12
911#define WM8962_DACL_RETUNE_C10_0 0x4C13
912#define WM8962_DACL_RETUNE_C11_1 0x4C14
913#define WM8962_DACL_RETUNE_C11_0 0x4C15
914#define WM8962_DACL_RETUNE_C12_1 0x4C16
915#define WM8962_DACL_RETUNE_C12_0 0x4C17
916#define WM8962_DACL_RETUNE_C13_1 0x4C18
917#define WM8962_DACL_RETUNE_C13_0 0x4C19
918#define WM8962_DACL_RETUNE_C14_1 0x4C1A
919#define WM8962_DACL_RETUNE_C14_0 0x4C1B
920#define WM8962_DACL_RETUNE_C15_1 0x4C1C
921#define WM8962_DACL_RETUNE_C15_0 0x4C1D
922#define WM8962_DACL_RETUNE_C16_1 0x4C1E
923#define WM8962_DACL_RETUNE_C16_0 0x4C1F
924#define WM8962_DACL_RETUNE_C17_1 0x4C20
925#define WM8962_DACL_RETUNE_C17_0 0x4C21
926#define WM8962_DACL_RETUNE_C18_1 0x4C22
927#define WM8962_DACL_RETUNE_C18_0 0x4C23
928#define WM8962_DACL_RETUNE_C19_1 0x4C24
929#define WM8962_DACL_RETUNE_C19_0 0x4C25
930#define WM8962_DACL_RETUNE_C20_1 0x4C26
931#define WM8962_DACL_RETUNE_C20_0 0x4C27
932#define WM8962_DACL_RETUNE_C21_1 0x4C28
933#define WM8962_DACL_RETUNE_C21_0 0x4C29
934#define WM8962_DACL_RETUNE_C22_1 0x4C2A
935#define WM8962_DACL_RETUNE_C22_0 0x4C2B
936#define WM8962_DACL_RETUNE_C23_1 0x4C2C
937#define WM8962_DACL_RETUNE_C23_0 0x4C2D
938#define WM8962_DACL_RETUNE_C24_1 0x4C2E
939#define WM8962_DACL_RETUNE_C24_0 0x4C2F
940#define WM8962_DACL_RETUNE_C25_1 0x4C30
941#define WM8962_DACL_RETUNE_C25_0 0x4C31
942#define WM8962_DACL_RETUNE_C26_1 0x4C32
943#define WM8962_DACL_RETUNE_C26_0 0x4C33
944#define WM8962_DACL_RETUNE_C27_1 0x4C34
945#define WM8962_DACL_RETUNE_C27_0 0x4C35
946#define WM8962_DACL_RETUNE_C28_1 0x4C36
947#define WM8962_DACL_RETUNE_C28_0 0x4C37
948#define WM8962_DACL_RETUNE_C29_1 0x4C38
949#define WM8962_DACL_RETUNE_C29_0 0x4C39
950#define WM8962_DACL_RETUNE_C30_1 0x4C3A
951#define WM8962_DACL_RETUNE_C30_0 0x4C3B
952#define WM8962_DACL_RETUNE_C31_1 0x4C3C
953#define WM8962_DACL_RETUNE_C31_0 0x4C3D
954#define WM8962_DACL_RETUNE_C32_1 0x4C3E
955#define WM8962_DACL_RETUNE_C32_0 0x4C3F
956#define WM8962_RETUNEDAC_PG2_1 0x4E00
957#define WM8962_RETUNEDAC_PG2_0 0x4E01
958#define WM8962_RETUNEDAC_PG_1 0x4E02
959#define WM8962_RETUNEDAC_PG_0 0x4E03
960#define WM8962_DACR_RETUNE_C1_1 0x5000
961#define WM8962_DACR_RETUNE_C1_0 0x5001
962#define WM8962_DACR_RETUNE_C2_1 0x5002
963#define WM8962_DACR_RETUNE_C2_0 0x5003
964#define WM8962_DACR_RETUNE_C3_1 0x5004
965#define WM8962_DACR_RETUNE_C3_0 0x5005
966#define WM8962_DACR_RETUNE_C4_1 0x5006
967#define WM8962_DACR_RETUNE_C4_0 0x5007
968#define WM8962_DACR_RETUNE_C5_1 0x5008
969#define WM8962_DACR_RETUNE_C5_0 0x5009
970#define WM8962_DACR_RETUNE_C6_1 0x500A
971#define WM8962_DACR_RETUNE_C6_0 0x500B
972#define WM8962_DACR_RETUNE_C7_1 0x500C
973#define WM8962_DACR_RETUNE_C7_0 0x500D
974#define WM8962_DACR_RETUNE_C8_1 0x500E
975#define WM8962_DACR_RETUNE_C8_0 0x500F
976#define WM8962_DACR_RETUNE_C9_1 0x5010
977#define WM8962_DACR_RETUNE_C9_0 0x5011
978#define WM8962_DACR_RETUNE_C10_1 0x5012
979#define WM8962_DACR_RETUNE_C10_0 0x5013
980#define WM8962_DACR_RETUNE_C11_1 0x5014
981#define WM8962_DACR_RETUNE_C11_0 0x5015
982#define WM8962_DACR_RETUNE_C12_1 0x5016
983#define WM8962_DACR_RETUNE_C12_0 0x5017
984#define WM8962_DACR_RETUNE_C13_1 0x5018
985#define WM8962_DACR_RETUNE_C13_0 0x5019
986#define WM8962_DACR_RETUNE_C14_1 0x501A
987#define WM8962_DACR_RETUNE_C14_0 0x501B
988#define WM8962_DACR_RETUNE_C15_1 0x501C
989#define WM8962_DACR_RETUNE_C15_0 0x501D
990#define WM8962_DACR_RETUNE_C16_1 0x501E
991#define WM8962_DACR_RETUNE_C16_0 0x501F
992#define WM8962_DACR_RETUNE_C17_1 0x5020
993#define WM8962_DACR_RETUNE_C17_0 0x5021
994#define WM8962_DACR_RETUNE_C18_1 0x5022
995#define WM8962_DACR_RETUNE_C18_0 0x5023
996#define WM8962_DACR_RETUNE_C19_1 0x5024
997#define WM8962_DACR_RETUNE_C19_0 0x5025
998#define WM8962_DACR_RETUNE_C20_1 0x5026
999#define WM8962_DACR_RETUNE_C20_0 0x5027
1000#define WM8962_DACR_RETUNE_C21_1 0x5028
1001#define WM8962_DACR_RETUNE_C21_0 0x5029
1002#define WM8962_DACR_RETUNE_C22_1 0x502A
1003#define WM8962_DACR_RETUNE_C22_0 0x502B
1004#define WM8962_DACR_RETUNE_C23_1 0x502C
1005#define WM8962_DACR_RETUNE_C23_0 0x502D
1006#define WM8962_DACR_RETUNE_C24_1 0x502E
1007#define WM8962_DACR_RETUNE_C24_0 0x502F
1008#define WM8962_DACR_RETUNE_C25_1 0x5030
1009#define WM8962_DACR_RETUNE_C25_0 0x5031
1010#define WM8962_DACR_RETUNE_C26_1 0x5032
1011#define WM8962_DACR_RETUNE_C26_0 0x5033
1012#define WM8962_DACR_RETUNE_C27_1 0x5034
1013#define WM8962_DACR_RETUNE_C27_0 0x5035
1014#define WM8962_DACR_RETUNE_C28_1 0x5036
1015#define WM8962_DACR_RETUNE_C28_0 0x5037
1016#define WM8962_DACR_RETUNE_C29_1 0x5038
1017#define WM8962_DACR_RETUNE_C29_0 0x5039
1018#define WM8962_DACR_RETUNE_C30_1 0x503A
1019#define WM8962_DACR_RETUNE_C30_0 0x503B
1020#define WM8962_DACR_RETUNE_C31_1 0x503C
1021#define WM8962_DACR_RETUNE_C31_0 0x503D
1022#define WM8962_DACR_RETUNE_C32_1 0x503E
1023#define WM8962_DACR_RETUNE_C32_0 0x503F
1024#define WM8962_VSS_XHD2_1 0x5200
1025#define WM8962_VSS_XHD2_0 0x5201
1026#define WM8962_VSS_XHD3_1 0x5202
1027#define WM8962_VSS_XHD3_0 0x5203
1028#define WM8962_VSS_XHN1_1 0x5204
1029#define WM8962_VSS_XHN1_0 0x5205
1030#define WM8962_VSS_XHN2_1 0x5206
1031#define WM8962_VSS_XHN2_0 0x5207
1032#define WM8962_VSS_XHN3_1 0x5208
1033#define WM8962_VSS_XHN3_0 0x5209
1034#define WM8962_VSS_XLA_1 0x520A
1035#define WM8962_VSS_XLA_0 0x520B
1036#define WM8962_VSS_XLB_1 0x520C
1037#define WM8962_VSS_XLB_0 0x520D
1038#define WM8962_VSS_XLG_1 0x520E
1039#define WM8962_VSS_XLG_0 0x520F
1040#define WM8962_VSS_PG2_1 0x5210
1041#define WM8962_VSS_PG2_0 0x5211
1042#define WM8962_VSS_PG_1 0x5212
1043#define WM8962_VSS_PG_0 0x5213
1044#define WM8962_VSS_XTD1_1 0x5214
1045#define WM8962_VSS_XTD1_0 0x5215
1046#define WM8962_VSS_XTD2_1 0x5216
1047#define WM8962_VSS_XTD2_0 0x5217
1048#define WM8962_VSS_XTD3_1 0x5218
1049#define WM8962_VSS_XTD3_0 0x5219
1050#define WM8962_VSS_XTD4_1 0x521A
1051#define WM8962_VSS_XTD4_0 0x521B
1052#define WM8962_VSS_XTD5_1 0x521C
1053#define WM8962_VSS_XTD5_0 0x521D
1054#define WM8962_VSS_XTD6_1 0x521E
1055#define WM8962_VSS_XTD6_0 0x521F
1056#define WM8962_VSS_XTD7_1 0x5220
1057#define WM8962_VSS_XTD7_0 0x5221
1058#define WM8962_VSS_XTD8_1 0x5222
1059#define WM8962_VSS_XTD8_0 0x5223
1060#define WM8962_VSS_XTD9_1 0x5224
1061#define WM8962_VSS_XTD9_0 0x5225
1062#define WM8962_VSS_XTD10_1 0x5226
1063#define WM8962_VSS_XTD10_0 0x5227
1064#define WM8962_VSS_XTD11_1 0x5228
1065#define WM8962_VSS_XTD11_0 0x5229
1066#define WM8962_VSS_XTD12_1 0x522A
1067#define WM8962_VSS_XTD12_0 0x522B
1068#define WM8962_VSS_XTD13_1 0x522C
1069#define WM8962_VSS_XTD13_0 0x522D
1070#define WM8962_VSS_XTD14_1 0x522E
1071#define WM8962_VSS_XTD14_0 0x522F
1072#define WM8962_VSS_XTD15_1 0x5230
1073#define WM8962_VSS_XTD15_0 0x5231
1074#define WM8962_VSS_XTD16_1 0x5232
1075#define WM8962_VSS_XTD16_0 0x5233
1076#define WM8962_VSS_XTD17_1 0x5234
1077#define WM8962_VSS_XTD17_0 0x5235
1078#define WM8962_VSS_XTD18_1 0x5236
1079#define WM8962_VSS_XTD18_0 0x5237
1080#define WM8962_VSS_XTD19_1 0x5238
1081#define WM8962_VSS_XTD19_0 0x5239
1082#define WM8962_VSS_XTD20_1 0x523A
1083#define WM8962_VSS_XTD20_0 0x523B
1084#define WM8962_VSS_XTD21_1 0x523C
1085#define WM8962_VSS_XTD21_0 0x523D
1086#define WM8962_VSS_XTD22_1 0x523E
1087#define WM8962_VSS_XTD22_0 0x523F
1088#define WM8962_VSS_XTD23_1 0x5240
1089#define WM8962_VSS_XTD23_0 0x5241
1090#define WM8962_VSS_XTD24_1 0x5242
1091#define WM8962_VSS_XTD24_0 0x5243
1092#define WM8962_VSS_XTD25_1 0x5244
1093#define WM8962_VSS_XTD25_0 0x5245
1094#define WM8962_VSS_XTD26_1 0x5246
1095#define WM8962_VSS_XTD26_0 0x5247
1096#define WM8962_VSS_XTD27_1 0x5248
1097#define WM8962_VSS_XTD27_0 0x5249
1098#define WM8962_VSS_XTD28_1 0x524A
1099#define WM8962_VSS_XTD28_0 0x524B
1100#define WM8962_VSS_XTD29_1 0x524C
1101#define WM8962_VSS_XTD29_0 0x524D
1102#define WM8962_VSS_XTD30_1 0x524E
1103#define WM8962_VSS_XTD30_0 0x524F
1104#define WM8962_VSS_XTD31_1 0x5250
1105#define WM8962_VSS_XTD31_0 0x5251
1106#define WM8962_VSS_XTD32_1 0x5252
1107#define WM8962_VSS_XTD32_0 0x5253
1108#define WM8962_VSS_XTS1_1 0x5254
1109#define WM8962_VSS_XTS1_0 0x5255
1110#define WM8962_VSS_XTS2_1 0x5256
1111#define WM8962_VSS_XTS2_0 0x5257
1112#define WM8962_VSS_XTS3_1 0x5258
1113#define WM8962_VSS_XTS3_0 0x5259
1114#define WM8962_VSS_XTS4_1 0x525A
1115#define WM8962_VSS_XTS4_0 0x525B
1116#define WM8962_VSS_XTS5_1 0x525C
1117#define WM8962_VSS_XTS5_0 0x525D
1118#define WM8962_VSS_XTS6_1 0x525E
1119#define WM8962_VSS_XTS6_0 0x525F
1120#define WM8962_VSS_XTS7_1 0x5260
1121#define WM8962_VSS_XTS7_0 0x5261
1122#define WM8962_VSS_XTS8_1 0x5262
1123#define WM8962_VSS_XTS8_0 0x5263
1124#define WM8962_VSS_XTS9_1 0x5264
1125#define WM8962_VSS_XTS9_0 0x5265
1126#define WM8962_VSS_XTS10_1 0x5266
1127#define WM8962_VSS_XTS10_0 0x5267
1128#define WM8962_VSS_XTS11_1 0x5268
1129#define WM8962_VSS_XTS11_0 0x5269
1130#define WM8962_VSS_XTS12_1 0x526A
1131#define WM8962_VSS_XTS12_0 0x526B
1132#define WM8962_VSS_XTS13_1 0x526C
1133#define WM8962_VSS_XTS13_0 0x526D
1134#define WM8962_VSS_XTS14_1 0x526E
1135#define WM8962_VSS_XTS14_0 0x526F
1136#define WM8962_VSS_XTS15_1 0x5270
1137#define WM8962_VSS_XTS15_0 0x5271
1138#define WM8962_VSS_XTS16_1 0x5272
1139#define WM8962_VSS_XTS16_0 0x5273
1140#define WM8962_VSS_XTS17_1 0x5274
1141#define WM8962_VSS_XTS17_0 0x5275
1142#define WM8962_VSS_XTS18_1 0x5276
1143#define WM8962_VSS_XTS18_0 0x5277
1144#define WM8962_VSS_XTS19_1 0x5278
1145#define WM8962_VSS_XTS19_0 0x5279
1146#define WM8962_VSS_XTS20_1 0x527A
1147#define WM8962_VSS_XTS20_0 0x527B
1148#define WM8962_VSS_XTS21_1 0x527C
1149#define WM8962_VSS_XTS21_0 0x527D
1150#define WM8962_VSS_XTS22_1 0x527E
1151#define WM8962_VSS_XTS22_0 0x527F
1152#define WM8962_VSS_XTS23_1 0x5280
1153#define WM8962_VSS_XTS23_0 0x5281
1154#define WM8962_VSS_XTS24_1 0x5282
1155#define WM8962_VSS_XTS24_0 0x5283
1156#define WM8962_VSS_XTS25_1 0x5284
1157#define WM8962_VSS_XTS25_0 0x5285
1158#define WM8962_VSS_XTS26_1 0x5286
1159#define WM8962_VSS_XTS26_0 0x5287
1160#define WM8962_VSS_XTS27_1 0x5288
1161#define WM8962_VSS_XTS27_0 0x5289
1162#define WM8962_VSS_XTS28_1 0x528A
1163#define WM8962_VSS_XTS28_0 0x528B
1164#define WM8962_VSS_XTS29_1 0x528C
1165#define WM8962_VSS_XTS29_0 0x528D
1166#define WM8962_VSS_XTS30_1 0x528E
1167#define WM8962_VSS_XTS30_0 0x528F
1168#define WM8962_VSS_XTS31_1 0x5290
1169#define WM8962_VSS_XTS31_0 0x5291
1170#define WM8962_VSS_XTS32_1 0x5292
1171#define WM8962_VSS_XTS32_0 0x5293
1172
1173#define WM8962_REGISTER_COUNT 1138
1174#define WM8962_MAX_REGISTER 0x5293
1175
1176/*
1177 * Field Definitions.
1178 */
1179
1180/*
1181 * R0 (0x00) - Left Input volume
1182 */
1183#define WM8962_IN_VU 0x0100 /* IN_VU */
1184#define WM8962_IN_VU_MASK 0x0100 /* IN_VU */
1185#define WM8962_IN_VU_SHIFT 8 /* IN_VU */
1186#define WM8962_IN_VU_WIDTH 1 /* IN_VU */
1187#define WM8962_INPGAL_MUTE 0x0080 /* INPGAL_MUTE */
1188#define WM8962_INPGAL_MUTE_MASK 0x0080 /* INPGAL_MUTE */
1189#define WM8962_INPGAL_MUTE_SHIFT 7 /* INPGAL_MUTE */
1190#define WM8962_INPGAL_MUTE_WIDTH 1 /* INPGAL_MUTE */
1191#define WM8962_INL_ZC 0x0040 /* INL_ZC */
1192#define WM8962_INL_ZC_MASK 0x0040 /* INL_ZC */
1193#define WM8962_INL_ZC_SHIFT 6 /* INL_ZC */
1194#define WM8962_INL_ZC_WIDTH 1 /* INL_ZC */
1195#define WM8962_INL_VOL_MASK 0x003F /* INL_VOL - [5:0] */
1196#define WM8962_INL_VOL_SHIFT 0 /* INL_VOL - [5:0] */
1197#define WM8962_INL_VOL_WIDTH 6 /* INL_VOL - [5:0] */
1198
1199/*
1200 * R1 (0x01) - Right Input volume
1201 */
1202#define WM8962_CUST_ID_MASK 0xF000 /* CUST_ID - [15:12] */
1203#define WM8962_CUST_ID_SHIFT 12 /* CUST_ID - [15:12] */
1204#define WM8962_CUST_ID_WIDTH 4 /* CUST_ID - [15:12] */
1205#define WM8962_CHIP_REV_MASK 0x0E00 /* CHIP_REV - [11:9] */
1206#define WM8962_CHIP_REV_SHIFT 9 /* CHIP_REV - [11:9] */
1207#define WM8962_CHIP_REV_WIDTH 3 /* CHIP_REV - [11:9] */
1208#define WM8962_IN_VU 0x0100 /* IN_VU */
1209#define WM8962_IN_VU_MASK 0x0100 /* IN_VU */
1210#define WM8962_IN_VU_SHIFT 8 /* IN_VU */
1211#define WM8962_IN_VU_WIDTH 1 /* IN_VU */
1212#define WM8962_INPGAR_MUTE 0x0080 /* INPGAR_MUTE */
1213#define WM8962_INPGAR_MUTE_MASK 0x0080 /* INPGAR_MUTE */
1214#define WM8962_INPGAR_MUTE_SHIFT 7 /* INPGAR_MUTE */
1215#define WM8962_INPGAR_MUTE_WIDTH 1 /* INPGAR_MUTE */
1216#define WM8962_INR_ZC 0x0040 /* INR_ZC */
1217#define WM8962_INR_ZC_MASK 0x0040 /* INR_ZC */
1218#define WM8962_INR_ZC_SHIFT 6 /* INR_ZC */
1219#define WM8962_INR_ZC_WIDTH 1 /* INR_ZC */
1220#define WM8962_INR_VOL_MASK 0x003F /* INR_VOL - [5:0] */
1221#define WM8962_INR_VOL_SHIFT 0 /* INR_VOL - [5:0] */
1222#define WM8962_INR_VOL_WIDTH 6 /* INR_VOL - [5:0] */
1223
1224/*
1225 * R2 (0x02) - HPOUTL volume
1226 */
1227#define WM8962_HPOUT_VU 0x0100 /* HPOUT_VU */
1228#define WM8962_HPOUT_VU_MASK 0x0100 /* HPOUT_VU */
1229#define WM8962_HPOUT_VU_SHIFT 8 /* HPOUT_VU */
1230#define WM8962_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
1231#define WM8962_HPOUTL_ZC 0x0080 /* HPOUTL_ZC */
1232#define WM8962_HPOUTL_ZC_MASK 0x0080 /* HPOUTL_ZC */
1233#define WM8962_HPOUTL_ZC_SHIFT 7 /* HPOUTL_ZC */
1234#define WM8962_HPOUTL_ZC_WIDTH 1 /* HPOUTL_ZC */
1235#define WM8962_HPOUTL_VOL_MASK 0x007F /* HPOUTL_VOL - [6:0] */
1236#define WM8962_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [6:0] */
1237#define WM8962_HPOUTL_VOL_WIDTH 7 /* HPOUTL_VOL - [6:0] */
1238
1239/*
1240 * R3 (0x03) - HPOUTR volume
1241 */
1242#define WM8962_HPOUT_VU 0x0100 /* HPOUT_VU */
1243#define WM8962_HPOUT_VU_MASK 0x0100 /* HPOUT_VU */
1244#define WM8962_HPOUT_VU_SHIFT 8 /* HPOUT_VU */
1245#define WM8962_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
1246#define WM8962_HPOUTR_ZC 0x0080 /* HPOUTR_ZC */
1247#define WM8962_HPOUTR_ZC_MASK 0x0080 /* HPOUTR_ZC */
1248#define WM8962_HPOUTR_ZC_SHIFT 7 /* HPOUTR_ZC */
1249#define WM8962_HPOUTR_ZC_WIDTH 1 /* HPOUTR_ZC */
1250#define WM8962_HPOUTR_VOL_MASK 0x007F /* HPOUTR_VOL - [6:0] */
1251#define WM8962_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [6:0] */
1252#define WM8962_HPOUTR_VOL_WIDTH 7 /* HPOUTR_VOL - [6:0] */
1253
1254/*
1255 * R4 (0x04) - Clocking1
1256 */
1257#define WM8962_DSPCLK_DIV_MASK 0x0600 /* DSPCLK_DIV - [10:9] */
1258#define WM8962_DSPCLK_DIV_SHIFT 9 /* DSPCLK_DIV - [10:9] */
1259#define WM8962_DSPCLK_DIV_WIDTH 2 /* DSPCLK_DIV - [10:9] */
1260#define WM8962_ADCSYS_CLK_DIV_MASK 0x01C0 /* ADCSYS_CLK_DIV - [8:6] */
1261#define WM8962_ADCSYS_CLK_DIV_SHIFT 6 /* ADCSYS_CLK_DIV - [8:6] */
1262#define WM8962_ADCSYS_CLK_DIV_WIDTH 3 /* ADCSYS_CLK_DIV - [8:6] */
1263#define WM8962_DACSYS_CLK_DIV_MASK 0x0038 /* DACSYS_CLK_DIV - [5:3] */
1264#define WM8962_DACSYS_CLK_DIV_SHIFT 3 /* DACSYS_CLK_DIV - [5:3] */
1265#define WM8962_DACSYS_CLK_DIV_WIDTH 3 /* DACSYS_CLK_DIV - [5:3] */
1266#define WM8962_MCLKDIV_MASK 0x0006 /* MCLKDIV - [2:1] */
1267#define WM8962_MCLKDIV_SHIFT 1 /* MCLKDIV - [2:1] */
1268#define WM8962_MCLKDIV_WIDTH 2 /* MCLKDIV - [2:1] */
1269
1270/*
1271 * R5 (0x05) - ADC & DAC Control 1
1272 */
1273#define WM8962_ADCR_DAT_INV 0x0040 /* ADCR_DAT_INV */
1274#define WM8962_ADCR_DAT_INV_MASK 0x0040 /* ADCR_DAT_INV */
1275#define WM8962_ADCR_DAT_INV_SHIFT 6 /* ADCR_DAT_INV */
1276#define WM8962_ADCR_DAT_INV_WIDTH 1 /* ADCR_DAT_INV */
1277#define WM8962_ADCL_DAT_INV 0x0020 /* ADCL_DAT_INV */
1278#define WM8962_ADCL_DAT_INV_MASK 0x0020 /* ADCL_DAT_INV */
1279#define WM8962_ADCL_DAT_INV_SHIFT 5 /* ADCL_DAT_INV */
1280#define WM8962_ADCL_DAT_INV_WIDTH 1 /* ADCL_DAT_INV */
1281#define WM8962_DAC_MUTE_RAMP 0x0010 /* DAC_MUTE_RAMP */
1282#define WM8962_DAC_MUTE_RAMP_MASK 0x0010 /* DAC_MUTE_RAMP */
1283#define WM8962_DAC_MUTE_RAMP_SHIFT 4 /* DAC_MUTE_RAMP */
1284#define WM8962_DAC_MUTE_RAMP_WIDTH 1 /* DAC_MUTE_RAMP */
1285#define WM8962_DAC_MUTE 0x0008 /* DAC_MUTE */
1286#define WM8962_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
1287#define WM8962_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
1288#define WM8962_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
1289#define WM8962_DAC_DEEMP_MASK 0x0006 /* DAC_DEEMP - [2:1] */
1290#define WM8962_DAC_DEEMP_SHIFT 1 /* DAC_DEEMP - [2:1] */
1291#define WM8962_DAC_DEEMP_WIDTH 2 /* DAC_DEEMP - [2:1] */
1292#define WM8962_ADC_HPF_DIS 0x0001 /* ADC_HPF_DIS */
1293#define WM8962_ADC_HPF_DIS_MASK 0x0001 /* ADC_HPF_DIS */
1294#define WM8962_ADC_HPF_DIS_SHIFT 0 /* ADC_HPF_DIS */
1295#define WM8962_ADC_HPF_DIS_WIDTH 1 /* ADC_HPF_DIS */
1296
1297/*
1298 * R6 (0x06) - ADC & DAC Control 2
1299 */
1300#define WM8962_ADC_HPF_SR_MASK 0x3000 /* ADC_HPF_SR - [13:12] */
1301#define WM8962_ADC_HPF_SR_SHIFT 12 /* ADC_HPF_SR - [13:12] */
1302#define WM8962_ADC_HPF_SR_WIDTH 2 /* ADC_HPF_SR - [13:12] */
1303#define WM8962_ADC_HPF_MODE 0x0400 /* ADC_HPF_MODE */
1304#define WM8962_ADC_HPF_MODE_MASK 0x0400 /* ADC_HPF_MODE */
1305#define WM8962_ADC_HPF_MODE_SHIFT 10 /* ADC_HPF_MODE */
1306#define WM8962_ADC_HPF_MODE_WIDTH 1 /* ADC_HPF_MODE */
1307#define WM8962_ADC_HPF_CUT_MASK 0x0380 /* ADC_HPF_CUT - [9:7] */
1308#define WM8962_ADC_HPF_CUT_SHIFT 7 /* ADC_HPF_CUT - [9:7] */
1309#define WM8962_ADC_HPF_CUT_WIDTH 3 /* ADC_HPF_CUT - [9:7] */
1310#define WM8962_DACR_DAT_INV 0x0040 /* DACR_DAT_INV */
1311#define WM8962_DACR_DAT_INV_MASK 0x0040 /* DACR_DAT_INV */
1312#define WM8962_DACR_DAT_INV_SHIFT 6 /* DACR_DAT_INV */
1313#define WM8962_DACR_DAT_INV_WIDTH 1 /* DACR_DAT_INV */
1314#define WM8962_DACL_DAT_INV 0x0020 /* DACL_DAT_INV */
1315#define WM8962_DACL_DAT_INV_MASK 0x0020 /* DACL_DAT_INV */
1316#define WM8962_DACL_DAT_INV_SHIFT 5 /* DACL_DAT_INV */
1317#define WM8962_DACL_DAT_INV_WIDTH 1 /* DACL_DAT_INV */
1318#define WM8962_DAC_UNMUTE_RAMP 0x0008 /* DAC_UNMUTE_RAMP */
1319#define WM8962_DAC_UNMUTE_RAMP_MASK 0x0008 /* DAC_UNMUTE_RAMP */
1320#define WM8962_DAC_UNMUTE_RAMP_SHIFT 3 /* DAC_UNMUTE_RAMP */
1321#define WM8962_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
1322#define WM8962_DAC_MUTERATE 0x0004 /* DAC_MUTERATE */
1323#define WM8962_DAC_MUTERATE_MASK 0x0004 /* DAC_MUTERATE */
1324#define WM8962_DAC_MUTERATE_SHIFT 2 /* DAC_MUTERATE */
1325#define WM8962_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
1326#define WM8962_DAC_HP 0x0001 /* DAC_HP */
1327#define WM8962_DAC_HP_MASK 0x0001 /* DAC_HP */
1328#define WM8962_DAC_HP_SHIFT 0 /* DAC_HP */
1329#define WM8962_DAC_HP_WIDTH 1 /* DAC_HP */
1330
1331/*
1332 * R7 (0x07) - Audio Interface 0
1333 */
1334#define WM8962_AIFDAC_TDM_MODE 0x1000 /* AIFDAC_TDM_MODE */
1335#define WM8962_AIFDAC_TDM_MODE_MASK 0x1000 /* AIFDAC_TDM_MODE */
1336#define WM8962_AIFDAC_TDM_MODE_SHIFT 12 /* AIFDAC_TDM_MODE */
1337#define WM8962_AIFDAC_TDM_MODE_WIDTH 1 /* AIFDAC_TDM_MODE */
1338#define WM8962_AIFDAC_TDM_SLOT 0x0800 /* AIFDAC_TDM_SLOT */
1339#define WM8962_AIFDAC_TDM_SLOT_MASK 0x0800 /* AIFDAC_TDM_SLOT */
1340#define WM8962_AIFDAC_TDM_SLOT_SHIFT 11 /* AIFDAC_TDM_SLOT */
1341#define WM8962_AIFDAC_TDM_SLOT_WIDTH 1 /* AIFDAC_TDM_SLOT */
1342#define WM8962_AIFADC_TDM_MODE 0x0400 /* AIFADC_TDM_MODE */
1343#define WM8962_AIFADC_TDM_MODE_MASK 0x0400 /* AIFADC_TDM_MODE */
1344#define WM8962_AIFADC_TDM_MODE_SHIFT 10 /* AIFADC_TDM_MODE */
1345#define WM8962_AIFADC_TDM_MODE_WIDTH 1 /* AIFADC_TDM_MODE */
1346#define WM8962_AIFADC_TDM_SLOT 0x0200 /* AIFADC_TDM_SLOT */
1347#define WM8962_AIFADC_TDM_SLOT_MASK 0x0200 /* AIFADC_TDM_SLOT */
1348#define WM8962_AIFADC_TDM_SLOT_SHIFT 9 /* AIFADC_TDM_SLOT */
1349#define WM8962_AIFADC_TDM_SLOT_WIDTH 1 /* AIFADC_TDM_SLOT */
1350#define WM8962_ADC_LRSWAP 0x0100 /* ADC_LRSWAP */
1351#define WM8962_ADC_LRSWAP_MASK 0x0100 /* ADC_LRSWAP */
1352#define WM8962_ADC_LRSWAP_SHIFT 8 /* ADC_LRSWAP */
1353#define WM8962_ADC_LRSWAP_WIDTH 1 /* ADC_LRSWAP */
1354#define WM8962_BCLK_INV 0x0080 /* BCLK_INV */
1355#define WM8962_BCLK_INV_MASK 0x0080 /* BCLK_INV */
1356#define WM8962_BCLK_INV_SHIFT 7 /* BCLK_INV */
1357#define WM8962_BCLK_INV_WIDTH 1 /* BCLK_INV */
1358#define WM8962_MSTR 0x0040 /* MSTR */
1359#define WM8962_MSTR_MASK 0x0040 /* MSTR */
1360#define WM8962_MSTR_SHIFT 6 /* MSTR */
1361#define WM8962_MSTR_WIDTH 1 /* MSTR */
1362#define WM8962_DAC_LRSWAP 0x0020 /* DAC_LRSWAP */
1363#define WM8962_DAC_LRSWAP_MASK 0x0020 /* DAC_LRSWAP */
1364#define WM8962_DAC_LRSWAP_SHIFT 5 /* DAC_LRSWAP */
1365#define WM8962_DAC_LRSWAP_WIDTH 1 /* DAC_LRSWAP */
1366#define WM8962_LRCLK_INV 0x0010 /* LRCLK_INV */
1367#define WM8962_LRCLK_INV_MASK 0x0010 /* LRCLK_INV */
1368#define WM8962_LRCLK_INV_SHIFT 4 /* LRCLK_INV */
1369#define WM8962_LRCLK_INV_WIDTH 1 /* LRCLK_INV */
1370#define WM8962_WL_MASK 0x000C /* WL - [3:2] */
1371#define WM8962_WL_SHIFT 2 /* WL - [3:2] */
1372#define WM8962_WL_WIDTH 2 /* WL - [3:2] */
1373#define WM8962_FMT_MASK 0x0003 /* FMT - [1:0] */
1374#define WM8962_FMT_SHIFT 0 /* FMT - [1:0] */
1375#define WM8962_FMT_WIDTH 2 /* FMT - [1:0] */
1376
1377/*
1378 * R8 (0x08) - Clocking2
1379 */
1380#define WM8962_CLKREG_OVD 0x0800 /* CLKREG_OVD */
1381#define WM8962_CLKREG_OVD_MASK 0x0800 /* CLKREG_OVD */
1382#define WM8962_CLKREG_OVD_SHIFT 11 /* CLKREG_OVD */
1383#define WM8962_CLKREG_OVD_WIDTH 1 /* CLKREG_OVD */
1384#define WM8962_SYSCLK_SRC_MASK 0x0600 /* SYSCLK_SRC - [10:9] */
1385#define WM8962_SYSCLK_SRC_SHIFT 9 /* SYSCLK_SRC - [10:9] */
1386#define WM8962_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [10:9] */
1387#define WM8962_CLASSD_CLK_DIV_MASK 0x01C0 /* CLASSD_CLK_DIV - [8:6] */
1388#define WM8962_CLASSD_CLK_DIV_SHIFT 6 /* CLASSD_CLK_DIV - [8:6] */
1389#define WM8962_CLASSD_CLK_DIV_WIDTH 3 /* CLASSD_CLK_DIV - [8:6] */
1390#define WM8962_SYSCLK_ENA 0x0020 /* SYSCLK_ENA */
1391#define WM8962_SYSCLK_ENA_MASK 0x0020 /* SYSCLK_ENA */
1392#define WM8962_SYSCLK_ENA_SHIFT 5 /* SYSCLK_ENA */
1393#define WM8962_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */
1394#define WM8962_BCLK_DIV_MASK 0x000F /* BCLK_DIV - [3:0] */
1395#define WM8962_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [3:0] */
1396#define WM8962_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [3:0] */
1397
1398/*
1399 * R9 (0x09) - Audio Interface 1
1400 */
1401#define WM8962_AUTOMUTE_STS 0x0800 /* AUTOMUTE_STS */
1402#define WM8962_AUTOMUTE_STS_MASK 0x0800 /* AUTOMUTE_STS */
1403#define WM8962_AUTOMUTE_STS_SHIFT 11 /* AUTOMUTE_STS */
1404#define WM8962_AUTOMUTE_STS_WIDTH 1 /* AUTOMUTE_STS */
1405#define WM8962_DAC_AUTOMUTE_SAMPLES_MASK 0x0300 /* DAC_AUTOMUTE_SAMPLES - [9:8] */
1406#define WM8962_DAC_AUTOMUTE_SAMPLES_SHIFT 8 /* DAC_AUTOMUTE_SAMPLES - [9:8] */
1407#define WM8962_DAC_AUTOMUTE_SAMPLES_WIDTH 2 /* DAC_AUTOMUTE_SAMPLES - [9:8] */
1408#define WM8962_DAC_AUTOMUTE 0x0080 /* DAC_AUTOMUTE */
1409#define WM8962_DAC_AUTOMUTE_MASK 0x0080 /* DAC_AUTOMUTE */
1410#define WM8962_DAC_AUTOMUTE_SHIFT 7 /* DAC_AUTOMUTE */
1411#define WM8962_DAC_AUTOMUTE_WIDTH 1 /* DAC_AUTOMUTE */
1412#define WM8962_DAC_COMP 0x0010 /* DAC_COMP */
1413#define WM8962_DAC_COMP_MASK 0x0010 /* DAC_COMP */
1414#define WM8962_DAC_COMP_SHIFT 4 /* DAC_COMP */
1415#define WM8962_DAC_COMP_WIDTH 1 /* DAC_COMP */
1416#define WM8962_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
1417#define WM8962_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */
1418#define WM8962_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */
1419#define WM8962_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
1420#define WM8962_ADC_COMP 0x0004 /* ADC_COMP */
1421#define WM8962_ADC_COMP_MASK 0x0004 /* ADC_COMP */
1422#define WM8962_ADC_COMP_SHIFT 2 /* ADC_COMP */
1423#define WM8962_ADC_COMP_WIDTH 1 /* ADC_COMP */
1424#define WM8962_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
1425#define WM8962_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */
1426#define WM8962_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */
1427#define WM8962_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
1428#define WM8962_LOOPBACK 0x0001 /* LOOPBACK */
1429#define WM8962_LOOPBACK_MASK 0x0001 /* LOOPBACK */
1430#define WM8962_LOOPBACK_SHIFT 0 /* LOOPBACK */
1431#define WM8962_LOOPBACK_WIDTH 1 /* LOOPBACK */
1432
1433/*
1434 * R10 (0x0A) - Left DAC volume
1435 */
1436#define WM8962_DAC_VU 0x0100 /* DAC_VU */
1437#define WM8962_DAC_VU_MASK 0x0100 /* DAC_VU */
1438#define WM8962_DAC_VU_SHIFT 8 /* DAC_VU */
1439#define WM8962_DAC_VU_WIDTH 1 /* DAC_VU */
1440#define WM8962_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
1441#define WM8962_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
1442#define WM8962_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
1443
1444/*
1445 * R11 (0x0B) - Right DAC volume
1446 */
1447#define WM8962_DAC_VU 0x0100 /* DAC_VU */
1448#define WM8962_DAC_VU_MASK 0x0100 /* DAC_VU */
1449#define WM8962_DAC_VU_SHIFT 8 /* DAC_VU */
1450#define WM8962_DAC_VU_WIDTH 1 /* DAC_VU */
1451#define WM8962_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
1452#define WM8962_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
1453#define WM8962_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
1454
1455/*
1456 * R14 (0x0E) - Audio Interface 2
1457 */
1458#define WM8962_AIF_RATE_MASK 0x07FF /* AIF_RATE - [10:0] */
1459#define WM8962_AIF_RATE_SHIFT 0 /* AIF_RATE - [10:0] */
1460#define WM8962_AIF_RATE_WIDTH 11 /* AIF_RATE - [10:0] */
1461
1462/*
1463 * R15 (0x0F) - Software Reset
1464 */
1465#define WM8962_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
1466#define WM8962_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
1467#define WM8962_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
1468
1469/*
1470 * R17 (0x11) - ALC1
1471 */
1472#define WM8962_ALC_INACTIVE_ENA 0x0400 /* ALC_INACTIVE_ENA */
1473#define WM8962_ALC_INACTIVE_ENA_MASK 0x0400 /* ALC_INACTIVE_ENA */
1474#define WM8962_ALC_INACTIVE_ENA_SHIFT 10 /* ALC_INACTIVE_ENA */
1475#define WM8962_ALC_INACTIVE_ENA_WIDTH 1 /* ALC_INACTIVE_ENA */
1476#define WM8962_ALC_LVL_MODE 0x0200 /* ALC_LVL_MODE */
1477#define WM8962_ALC_LVL_MODE_MASK 0x0200 /* ALC_LVL_MODE */
1478#define WM8962_ALC_LVL_MODE_SHIFT 9 /* ALC_LVL_MODE */
1479#define WM8962_ALC_LVL_MODE_WIDTH 1 /* ALC_LVL_MODE */
1480#define WM8962_ALCL_ENA 0x0100 /* ALCL_ENA */
1481#define WM8962_ALCL_ENA_MASK 0x0100 /* ALCL_ENA */
1482#define WM8962_ALCL_ENA_SHIFT 8 /* ALCL_ENA */
1483#define WM8962_ALCL_ENA_WIDTH 1 /* ALCL_ENA */
1484#define WM8962_ALCR_ENA 0x0080 /* ALCR_ENA */
1485#define WM8962_ALCR_ENA_MASK 0x0080 /* ALCR_ENA */
1486#define WM8962_ALCR_ENA_SHIFT 7 /* ALCR_ENA */
1487#define WM8962_ALCR_ENA_WIDTH 1 /* ALCR_ENA */
1488#define WM8962_ALC_MAXGAIN_MASK 0x0070 /* ALC_MAXGAIN - [6:4] */
1489#define WM8962_ALC_MAXGAIN_SHIFT 4 /* ALC_MAXGAIN - [6:4] */
1490#define WM8962_ALC_MAXGAIN_WIDTH 3 /* ALC_MAXGAIN - [6:4] */
1491#define WM8962_ALC_LVL_MASK 0x000F /* ALC_LVL - [3:0] */
1492#define WM8962_ALC_LVL_SHIFT 0 /* ALC_LVL - [3:0] */
1493#define WM8962_ALC_LVL_WIDTH 4 /* ALC_LVL - [3:0] */
1494
1495/*
1496 * R18 (0x12) - ALC2
1497 */
1498#define WM8962_ALC_LOCK_STS 0x8000 /* ALC_LOCK_STS */
1499#define WM8962_ALC_LOCK_STS_MASK 0x8000 /* ALC_LOCK_STS */
1500#define WM8962_ALC_LOCK_STS_SHIFT 15 /* ALC_LOCK_STS */
1501#define WM8962_ALC_LOCK_STS_WIDTH 1 /* ALC_LOCK_STS */
1502#define WM8962_ALC_THRESH_STS 0x4000 /* ALC_THRESH_STS */
1503#define WM8962_ALC_THRESH_STS_MASK 0x4000 /* ALC_THRESH_STS */
1504#define WM8962_ALC_THRESH_STS_SHIFT 14 /* ALC_THRESH_STS */
1505#define WM8962_ALC_THRESH_STS_WIDTH 1 /* ALC_THRESH_STS */
1506#define WM8962_ALC_SAT_STS 0x2000 /* ALC_SAT_STS */
1507#define WM8962_ALC_SAT_STS_MASK 0x2000 /* ALC_SAT_STS */
1508#define WM8962_ALC_SAT_STS_SHIFT 13 /* ALC_SAT_STS */
1509#define WM8962_ALC_SAT_STS_WIDTH 1 /* ALC_SAT_STS */
1510#define WM8962_ALC_PKOVR_STS 0x1000 /* ALC_PKOVR_STS */
1511#define WM8962_ALC_PKOVR_STS_MASK 0x1000 /* ALC_PKOVR_STS */
1512#define WM8962_ALC_PKOVR_STS_SHIFT 12 /* ALC_PKOVR_STS */
1513#define WM8962_ALC_PKOVR_STS_WIDTH 1 /* ALC_PKOVR_STS */
1514#define WM8962_ALC_NGATE_STS 0x0800 /* ALC_NGATE_STS */
1515#define WM8962_ALC_NGATE_STS_MASK 0x0800 /* ALC_NGATE_STS */
1516#define WM8962_ALC_NGATE_STS_SHIFT 11 /* ALC_NGATE_STS */
1517#define WM8962_ALC_NGATE_STS_WIDTH 1 /* ALC_NGATE_STS */
1518#define WM8962_ALC_ZC 0x0080 /* ALC_ZC */
1519#define WM8962_ALC_ZC_MASK 0x0080 /* ALC_ZC */
1520#define WM8962_ALC_ZC_SHIFT 7 /* ALC_ZC */
1521#define WM8962_ALC_ZC_WIDTH 1 /* ALC_ZC */
1522#define WM8962_ALC_MINGAIN_MASK 0x0070 /* ALC_MINGAIN - [6:4] */
1523#define WM8962_ALC_MINGAIN_SHIFT 4 /* ALC_MINGAIN - [6:4] */
1524#define WM8962_ALC_MINGAIN_WIDTH 3 /* ALC_MINGAIN - [6:4] */
1525#define WM8962_ALC_HLD_MASK 0x000F /* ALC_HLD - [3:0] */
1526#define WM8962_ALC_HLD_SHIFT 0 /* ALC_HLD - [3:0] */
1527#define WM8962_ALC_HLD_WIDTH 4 /* ALC_HLD - [3:0] */
1528
1529/*
1530 * R19 (0x13) - ALC3
1531 */
1532#define WM8962_ALC_NGATE_GAIN_MASK 0x1C00 /* ALC_NGATE_GAIN - [12:10] */
1533#define WM8962_ALC_NGATE_GAIN_SHIFT 10 /* ALC_NGATE_GAIN - [12:10] */
1534#define WM8962_ALC_NGATE_GAIN_WIDTH 3 /* ALC_NGATE_GAIN - [12:10] */
1535#define WM8962_ALC_MODE 0x0100 /* ALC_MODE */
1536#define WM8962_ALC_MODE_MASK 0x0100 /* ALC_MODE */
1537#define WM8962_ALC_MODE_SHIFT 8 /* ALC_MODE */
1538#define WM8962_ALC_MODE_WIDTH 1 /* ALC_MODE */
1539#define WM8962_ALC_DCY_MASK 0x00F0 /* ALC_DCY - [7:4] */
1540#define WM8962_ALC_DCY_SHIFT 4 /* ALC_DCY - [7:4] */
1541#define WM8962_ALC_DCY_WIDTH 4 /* ALC_DCY - [7:4] */
1542#define WM8962_ALC_ATK_MASK 0x000F /* ALC_ATK - [3:0] */
1543#define WM8962_ALC_ATK_SHIFT 0 /* ALC_ATK - [3:0] */
1544#define WM8962_ALC_ATK_WIDTH 4 /* ALC_ATK - [3:0] */
1545
1546/*
1547 * R20 (0x14) - Noise Gate
1548 */
1549#define WM8962_ALC_NGATE_DCY_MASK 0xF000 /* ALC_NGATE_DCY - [15:12] */
1550#define WM8962_ALC_NGATE_DCY_SHIFT 12 /* ALC_NGATE_DCY - [15:12] */
1551#define WM8962_ALC_NGATE_DCY_WIDTH 4 /* ALC_NGATE_DCY - [15:12] */
1552#define WM8962_ALC_NGATE_ATK_MASK 0x0F00 /* ALC_NGATE_ATK - [11:8] */
1553#define WM8962_ALC_NGATE_ATK_SHIFT 8 /* ALC_NGATE_ATK - [11:8] */
1554#define WM8962_ALC_NGATE_ATK_WIDTH 4 /* ALC_NGATE_ATK - [11:8] */
1555#define WM8962_ALC_NGATE_THR_MASK 0x00F8 /* ALC_NGATE_THR - [7:3] */
1556#define WM8962_ALC_NGATE_THR_SHIFT 3 /* ALC_NGATE_THR - [7:3] */
1557#define WM8962_ALC_NGATE_THR_WIDTH 5 /* ALC_NGATE_THR - [7:3] */
1558#define WM8962_ALC_NGATE_MODE_MASK 0x0006 /* ALC_NGATE_MODE - [2:1] */
1559#define WM8962_ALC_NGATE_MODE_SHIFT 1 /* ALC_NGATE_MODE - [2:1] */
1560#define WM8962_ALC_NGATE_MODE_WIDTH 2 /* ALC_NGATE_MODE - [2:1] */
1561#define WM8962_ALC_NGATE_ENA 0x0001 /* ALC_NGATE_ENA */
1562#define WM8962_ALC_NGATE_ENA_MASK 0x0001 /* ALC_NGATE_ENA */
1563#define WM8962_ALC_NGATE_ENA_SHIFT 0 /* ALC_NGATE_ENA */
1564#define WM8962_ALC_NGATE_ENA_WIDTH 1 /* ALC_NGATE_ENA */
1565
1566/*
1567 * R21 (0x15) - Left ADC volume
1568 */
1569#define WM8962_ADC_VU 0x0100 /* ADC_VU */
1570#define WM8962_ADC_VU_MASK 0x0100 /* ADC_VU */
1571#define WM8962_ADC_VU_SHIFT 8 /* ADC_VU */
1572#define WM8962_ADC_VU_WIDTH 1 /* ADC_VU */
1573#define WM8962_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
1574#define WM8962_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
1575#define WM8962_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
1576
1577/*
1578 * R22 (0x16) - Right ADC volume
1579 */
1580#define WM8962_ADC_VU 0x0100 /* ADC_VU */
1581#define WM8962_ADC_VU_MASK 0x0100 /* ADC_VU */
1582#define WM8962_ADC_VU_SHIFT 8 /* ADC_VU */
1583#define WM8962_ADC_VU_WIDTH 1 /* ADC_VU */
1584#define WM8962_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
1585#define WM8962_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
1586#define WM8962_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
1587
1588/*
1589 * R23 (0x17) - Additional control(1)
1590 */
1591#define WM8962_THERR_ACT 0x0100 /* THERR_ACT */
1592#define WM8962_THERR_ACT_MASK 0x0100 /* THERR_ACT */
1593#define WM8962_THERR_ACT_SHIFT 8 /* THERR_ACT */
1594#define WM8962_THERR_ACT_WIDTH 1 /* THERR_ACT */
1595#define WM8962_ADC_BIAS 0x0040 /* ADC_BIAS */
1596#define WM8962_ADC_BIAS_MASK 0x0040 /* ADC_BIAS */
1597#define WM8962_ADC_BIAS_SHIFT 6 /* ADC_BIAS */
1598#define WM8962_ADC_BIAS_WIDTH 1 /* ADC_BIAS */
1599#define WM8962_ADC_HP 0x0020 /* ADC_HP */
1600#define WM8962_ADC_HP_MASK 0x0020 /* ADC_HP */
1601#define WM8962_ADC_HP_SHIFT 5 /* ADC_HP */
1602#define WM8962_ADC_HP_WIDTH 1 /* ADC_HP */
1603#define WM8962_TOCLK_ENA 0x0001 /* TOCLK_ENA */
1604#define WM8962_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
1605#define WM8962_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
1606#define WM8962_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1607
1608/*
1609 * R24 (0x18) - Additional control(2)
1610 */
1611#define WM8962_AIF_TRI 0x0008 /* AIF_TRI */
1612#define WM8962_AIF_TRI_MASK 0x0008 /* AIF_TRI */
1613#define WM8962_AIF_TRI_SHIFT 3 /* AIF_TRI */
1614#define WM8962_AIF_TRI_WIDTH 1 /* AIF_TRI */
1615
1616/*
1617 * R25 (0x19) - Pwr Mgmt (1)
1618 */
1619#define WM8962_DMIC_ENA 0x0400 /* DMIC_ENA */
1620#define WM8962_DMIC_ENA_MASK 0x0400 /* DMIC_ENA */
1621#define WM8962_DMIC_ENA_SHIFT 10 /* DMIC_ENA */
1622#define WM8962_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
1623#define WM8962_OPCLK_ENA 0x0200 /* OPCLK_ENA */
1624#define WM8962_OPCLK_ENA_MASK 0x0200 /* OPCLK_ENA */
1625#define WM8962_OPCLK_ENA_SHIFT 9 /* OPCLK_ENA */
1626#define WM8962_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
1627#define WM8962_VMID_SEL_MASK 0x0180 /* VMID_SEL - [8:7] */
1628#define WM8962_VMID_SEL_SHIFT 7 /* VMID_SEL - [8:7] */
1629#define WM8962_VMID_SEL_WIDTH 2 /* VMID_SEL - [8:7] */
1630#define WM8962_BIAS_ENA 0x0040 /* BIAS_ENA */
1631#define WM8962_BIAS_ENA_MASK 0x0040 /* BIAS_ENA */
1632#define WM8962_BIAS_ENA_SHIFT 6 /* BIAS_ENA */
1633#define WM8962_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
1634#define WM8962_INL_ENA 0x0020 /* INL_ENA */
1635#define WM8962_INL_ENA_MASK 0x0020 /* INL_ENA */
1636#define WM8962_INL_ENA_SHIFT 5 /* INL_ENA */
1637#define WM8962_INL_ENA_WIDTH 1 /* INL_ENA */
1638#define WM8962_INR_ENA 0x0010 /* INR_ENA */
1639#define WM8962_INR_ENA_MASK 0x0010 /* INR_ENA */
1640#define WM8962_INR_ENA_SHIFT 4 /* INR_ENA */
1641#define WM8962_INR_ENA_WIDTH 1 /* INR_ENA */
1642#define WM8962_ADCL_ENA 0x0008 /* ADCL_ENA */
1643#define WM8962_ADCL_ENA_MASK 0x0008 /* ADCL_ENA */
1644#define WM8962_ADCL_ENA_SHIFT 3 /* ADCL_ENA */
1645#define WM8962_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
1646#define WM8962_ADCR_ENA 0x0004 /* ADCR_ENA */
1647#define WM8962_ADCR_ENA_MASK 0x0004 /* ADCR_ENA */
1648#define WM8962_ADCR_ENA_SHIFT 2 /* ADCR_ENA */
1649#define WM8962_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
1650#define WM8962_MICBIAS_ENA 0x0002 /* MICBIAS_ENA */
1651#define WM8962_MICBIAS_ENA_MASK 0x0002 /* MICBIAS_ENA */
1652#define WM8962_MICBIAS_ENA_SHIFT 1 /* MICBIAS_ENA */
1653#define WM8962_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
1654
1655/*
1656 * R26 (0x1A) - Pwr Mgmt (2)
1657 */
1658#define WM8962_DACL_ENA 0x0100 /* DACL_ENA */
1659#define WM8962_DACL_ENA_MASK 0x0100 /* DACL_ENA */
1660#define WM8962_DACL_ENA_SHIFT 8 /* DACL_ENA */
1661#define WM8962_DACL_ENA_WIDTH 1 /* DACL_ENA */
1662#define WM8962_DACR_ENA 0x0080 /* DACR_ENA */
1663#define WM8962_DACR_ENA_MASK 0x0080 /* DACR_ENA */
1664#define WM8962_DACR_ENA_SHIFT 7 /* DACR_ENA */
1665#define WM8962_DACR_ENA_WIDTH 1 /* DACR_ENA */
1666#define WM8962_HPOUTL_PGA_ENA 0x0040 /* HPOUTL_PGA_ENA */
1667#define WM8962_HPOUTL_PGA_ENA_MASK 0x0040 /* HPOUTL_PGA_ENA */
1668#define WM8962_HPOUTL_PGA_ENA_SHIFT 6 /* HPOUTL_PGA_ENA */
1669#define WM8962_HPOUTL_PGA_ENA_WIDTH 1 /* HPOUTL_PGA_ENA */
1670#define WM8962_HPOUTR_PGA_ENA 0x0020 /* HPOUTR_PGA_ENA */
1671#define WM8962_HPOUTR_PGA_ENA_MASK 0x0020 /* HPOUTR_PGA_ENA */
1672#define WM8962_HPOUTR_PGA_ENA_SHIFT 5 /* HPOUTR_PGA_ENA */
1673#define WM8962_HPOUTR_PGA_ENA_WIDTH 1 /* HPOUTR_PGA_ENA */
1674#define WM8962_SPKOUTL_PGA_ENA 0x0010 /* SPKOUTL_PGA_ENA */
1675#define WM8962_SPKOUTL_PGA_ENA_MASK 0x0010 /* SPKOUTL_PGA_ENA */
1676#define WM8962_SPKOUTL_PGA_ENA_SHIFT 4 /* SPKOUTL_PGA_ENA */
1677#define WM8962_SPKOUTL_PGA_ENA_WIDTH 1 /* SPKOUTL_PGA_ENA */
1678#define WM8962_SPKOUTR_PGA_ENA 0x0008 /* SPKOUTR_PGA_ENA */
1679#define WM8962_SPKOUTR_PGA_ENA_MASK 0x0008 /* SPKOUTR_PGA_ENA */
1680#define WM8962_SPKOUTR_PGA_ENA_SHIFT 3 /* SPKOUTR_PGA_ENA */
1681#define WM8962_SPKOUTR_PGA_ENA_WIDTH 1 /* SPKOUTR_PGA_ENA */
1682#define WM8962_HPOUTL_PGA_MUTE 0x0002 /* HPOUTL_PGA_MUTE */
1683#define WM8962_HPOUTL_PGA_MUTE_MASK 0x0002 /* HPOUTL_PGA_MUTE */
1684#define WM8962_HPOUTL_PGA_MUTE_SHIFT 1 /* HPOUTL_PGA_MUTE */
1685#define WM8962_HPOUTL_PGA_MUTE_WIDTH 1 /* HPOUTL_PGA_MUTE */
1686#define WM8962_HPOUTR_PGA_MUTE 0x0001 /* HPOUTR_PGA_MUTE */
1687#define WM8962_HPOUTR_PGA_MUTE_MASK 0x0001 /* HPOUTR_PGA_MUTE */
1688#define WM8962_HPOUTR_PGA_MUTE_SHIFT 0 /* HPOUTR_PGA_MUTE */
1689#define WM8962_HPOUTR_PGA_MUTE_WIDTH 1 /* HPOUTR_PGA_MUTE */
1690
1691/*
1692 * R27 (0x1B) - Additional Control (3)
1693 */
1694#define WM8962_SAMPLE_RATE_INT_MODE 0x0010 /* SAMPLE_RATE_INT_MODE */
1695#define WM8962_SAMPLE_RATE_INT_MODE_MASK 0x0010 /* SAMPLE_RATE_INT_MODE */
1696#define WM8962_SAMPLE_RATE_INT_MODE_SHIFT 4 /* SAMPLE_RATE_INT_MODE */
1697#define WM8962_SAMPLE_RATE_INT_MODE_WIDTH 1 /* SAMPLE_RATE_INT_MODE */
1698#define WM8962_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
1699#define WM8962_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
1700#define WM8962_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
1701
1702/*
1703 * R28 (0x1C) - Anti-pop
1704 */
1705#define WM8962_STARTUP_BIAS_ENA 0x0010 /* STARTUP_BIAS_ENA */
1706#define WM8962_STARTUP_BIAS_ENA_MASK 0x0010 /* STARTUP_BIAS_ENA */
1707#define WM8962_STARTUP_BIAS_ENA_SHIFT 4 /* STARTUP_BIAS_ENA */
1708#define WM8962_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
1709#define WM8962_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
1710#define WM8962_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
1711#define WM8962_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
1712#define WM8962_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
1713#define WM8962_VMID_RAMP 0x0004 /* VMID_RAMP */
1714#define WM8962_VMID_RAMP_MASK 0x0004 /* VMID_RAMP */
1715#define WM8962_VMID_RAMP_SHIFT 2 /* VMID_RAMP */
1716#define WM8962_VMID_RAMP_WIDTH 1 /* VMID_RAMP */
1717
1718/*
1719 * R30 (0x1E) - Clocking 3
1720 */
1721#define WM8962_DBCLK_DIV_MASK 0xE000 /* DBCLK_DIV - [15:13] */
1722#define WM8962_DBCLK_DIV_SHIFT 13 /* DBCLK_DIV - [15:13] */
1723#define WM8962_DBCLK_DIV_WIDTH 3 /* DBCLK_DIV - [15:13] */
1724#define WM8962_OPCLK_DIV_MASK 0x1C00 /* OPCLK_DIV - [12:10] */
1725#define WM8962_OPCLK_DIV_SHIFT 10 /* OPCLK_DIV - [12:10] */
1726#define WM8962_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [12:10] */
1727#define WM8962_TOCLK_DIV_MASK 0x0380 /* TOCLK_DIV - [9:7] */
1728#define WM8962_TOCLK_DIV_SHIFT 7 /* TOCLK_DIV - [9:7] */
1729#define WM8962_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [9:7] */
1730#define WM8962_F256KCLK_DIV_MASK 0x007E /* F256KCLK_DIV - [6:1] */
1731#define WM8962_F256KCLK_DIV_SHIFT 1 /* F256KCLK_DIV - [6:1] */
1732#define WM8962_F256KCLK_DIV_WIDTH 6 /* F256KCLK_DIV - [6:1] */
1733
1734/*
1735 * R31 (0x1F) - Input mixer control (1)
1736 */
1737#define WM8962_MIXINL_MUTE 0x0008 /* MIXINL_MUTE */
1738#define WM8962_MIXINL_MUTE_MASK 0x0008 /* MIXINL_MUTE */
1739#define WM8962_MIXINL_MUTE_SHIFT 3 /* MIXINL_MUTE */
1740#define WM8962_MIXINL_MUTE_WIDTH 1 /* MIXINL_MUTE */
1741#define WM8962_MIXINR_MUTE 0x0004 /* MIXINR_MUTE */
1742#define WM8962_MIXINR_MUTE_MASK 0x0004 /* MIXINR_MUTE */
1743#define WM8962_MIXINR_MUTE_SHIFT 2 /* MIXINR_MUTE */
1744#define WM8962_MIXINR_MUTE_WIDTH 1 /* MIXINR_MUTE */
1745#define WM8962_MIXINL_ENA 0x0002 /* MIXINL_ENA */
1746#define WM8962_MIXINL_ENA_MASK 0x0002 /* MIXINL_ENA */
1747#define WM8962_MIXINL_ENA_SHIFT 1 /* MIXINL_ENA */
1748#define WM8962_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
1749#define WM8962_MIXINR_ENA 0x0001 /* MIXINR_ENA */
1750#define WM8962_MIXINR_ENA_MASK 0x0001 /* MIXINR_ENA */
1751#define WM8962_MIXINR_ENA_SHIFT 0 /* MIXINR_ENA */
1752#define WM8962_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
1753
1754/*
1755 * R32 (0x20) - Left input mixer volume
1756 */
1757#define WM8962_IN2L_MIXINL_VOL_MASK 0x01C0 /* IN2L_MIXINL_VOL - [8:6] */
1758#define WM8962_IN2L_MIXINL_VOL_SHIFT 6 /* IN2L_MIXINL_VOL - [8:6] */
1759#define WM8962_IN2L_MIXINL_VOL_WIDTH 3 /* IN2L_MIXINL_VOL - [8:6] */
1760#define WM8962_INPGAL_MIXINL_VOL_MASK 0x0038 /* INPGAL_MIXINL_VOL - [5:3] */
1761#define WM8962_INPGAL_MIXINL_VOL_SHIFT 3 /* INPGAL_MIXINL_VOL - [5:3] */
1762#define WM8962_INPGAL_MIXINL_VOL_WIDTH 3 /* INPGAL_MIXINL_VOL - [5:3] */
1763#define WM8962_IN3L_MIXINL_VOL_MASK 0x0007 /* IN3L_MIXINL_VOL - [2:0] */
1764#define WM8962_IN3L_MIXINL_VOL_SHIFT 0 /* IN3L_MIXINL_VOL - [2:0] */
1765#define WM8962_IN3L_MIXINL_VOL_WIDTH 3 /* IN3L_MIXINL_VOL - [2:0] */
1766
1767/*
1768 * R33 (0x21) - Right input mixer volume
1769 */
1770#define WM8962_IN2R_MIXINR_VOL_MASK 0x01C0 /* IN2R_MIXINR_VOL - [8:6] */
1771#define WM8962_IN2R_MIXINR_VOL_SHIFT 6 /* IN2R_MIXINR_VOL - [8:6] */
1772#define WM8962_IN2R_MIXINR_VOL_WIDTH 3 /* IN2R_MIXINR_VOL - [8:6] */
1773#define WM8962_INPGAR_MIXINR_VOL_MASK 0x0038 /* INPGAR_MIXINR_VOL - [5:3] */
1774#define WM8962_INPGAR_MIXINR_VOL_SHIFT 3 /* INPGAR_MIXINR_VOL - [5:3] */
1775#define WM8962_INPGAR_MIXINR_VOL_WIDTH 3 /* INPGAR_MIXINR_VOL - [5:3] */
1776#define WM8962_IN3R_MIXINR_VOL_MASK 0x0007 /* IN3R_MIXINR_VOL - [2:0] */
1777#define WM8962_IN3R_MIXINR_VOL_SHIFT 0 /* IN3R_MIXINR_VOL - [2:0] */
1778#define WM8962_IN3R_MIXINR_VOL_WIDTH 3 /* IN3R_MIXINR_VOL - [2:0] */
1779
1780/*
1781 * R34 (0x22) - Input mixer control (2)
1782 */
1783#define WM8962_IN2L_TO_MIXINL 0x0020 /* IN2L_TO_MIXINL */
1784#define WM8962_IN2L_TO_MIXINL_MASK 0x0020 /* IN2L_TO_MIXINL */
1785#define WM8962_IN2L_TO_MIXINL_SHIFT 5 /* IN2L_TO_MIXINL */
1786#define WM8962_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
1787#define WM8962_IN3L_TO_MIXINL 0x0010 /* IN3L_TO_MIXINL */
1788#define WM8962_IN3L_TO_MIXINL_MASK 0x0010 /* IN3L_TO_MIXINL */
1789#define WM8962_IN3L_TO_MIXINL_SHIFT 4 /* IN3L_TO_MIXINL */
1790#define WM8962_IN3L_TO_MIXINL_WIDTH 1 /* IN3L_TO_MIXINL */
1791#define WM8962_INPGAL_TO_MIXINL 0x0008 /* INPGAL_TO_MIXINL */
1792#define WM8962_INPGAL_TO_MIXINL_MASK 0x0008 /* INPGAL_TO_MIXINL */
1793#define WM8962_INPGAL_TO_MIXINL_SHIFT 3 /* INPGAL_TO_MIXINL */
1794#define WM8962_INPGAL_TO_MIXINL_WIDTH 1 /* INPGAL_TO_MIXINL */
1795#define WM8962_IN2R_TO_MIXINR 0x0004 /* IN2R_TO_MIXINR */
1796#define WM8962_IN2R_TO_MIXINR_MASK 0x0004 /* IN2R_TO_MIXINR */
1797#define WM8962_IN2R_TO_MIXINR_SHIFT 2 /* IN2R_TO_MIXINR */
1798#define WM8962_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
1799#define WM8962_IN3R_TO_MIXINR 0x0002 /* IN3R_TO_MIXINR */
1800#define WM8962_IN3R_TO_MIXINR_MASK 0x0002 /* IN3R_TO_MIXINR */
1801#define WM8962_IN3R_TO_MIXINR_SHIFT 1 /* IN3R_TO_MIXINR */
1802#define WM8962_IN3R_TO_MIXINR_WIDTH 1 /* IN3R_TO_MIXINR */
1803#define WM8962_INPGAR_TO_MIXINR 0x0001 /* INPGAR_TO_MIXINR */
1804#define WM8962_INPGAR_TO_MIXINR_MASK 0x0001 /* INPGAR_TO_MIXINR */
1805#define WM8962_INPGAR_TO_MIXINR_SHIFT 0 /* INPGAR_TO_MIXINR */
1806#define WM8962_INPGAR_TO_MIXINR_WIDTH 1 /* INPGAR_TO_MIXINR */
1807
1808/*
1809 * R35 (0x23) - Input bias control
1810 */
1811#define WM8962_MIXIN_BIAS_MASK 0x0038 /* MIXIN_BIAS - [5:3] */
1812#define WM8962_MIXIN_BIAS_SHIFT 3 /* MIXIN_BIAS - [5:3] */
1813#define WM8962_MIXIN_BIAS_WIDTH 3 /* MIXIN_BIAS - [5:3] */
1814#define WM8962_INPGA_BIAS_MASK 0x0007 /* INPGA_BIAS - [2:0] */
1815#define WM8962_INPGA_BIAS_SHIFT 0 /* INPGA_BIAS - [2:0] */
1816#define WM8962_INPGA_BIAS_WIDTH 3 /* INPGA_BIAS - [2:0] */
1817
1818/*
1819 * R37 (0x25) - Left input PGA control
1820 */
1821#define WM8962_INPGAL_ENA 0x0010 /* INPGAL_ENA */
1822#define WM8962_INPGAL_ENA_MASK 0x0010 /* INPGAL_ENA */
1823#define WM8962_INPGAL_ENA_SHIFT 4 /* INPGAL_ENA */
1824#define WM8962_INPGAL_ENA_WIDTH 1 /* INPGAL_ENA */
1825#define WM8962_IN1L_TO_INPGAL 0x0008 /* IN1L_TO_INPGAL */
1826#define WM8962_IN1L_TO_INPGAL_MASK 0x0008 /* IN1L_TO_INPGAL */
1827#define WM8962_IN1L_TO_INPGAL_SHIFT 3 /* IN1L_TO_INPGAL */
1828#define WM8962_IN1L_TO_INPGAL_WIDTH 1 /* IN1L_TO_INPGAL */
1829#define WM8962_IN2L_TO_INPGAL 0x0004 /* IN2L_TO_INPGAL */
1830#define WM8962_IN2L_TO_INPGAL_MASK 0x0004 /* IN2L_TO_INPGAL */
1831#define WM8962_IN2L_TO_INPGAL_SHIFT 2 /* IN2L_TO_INPGAL */
1832#define WM8962_IN2L_TO_INPGAL_WIDTH 1 /* IN2L_TO_INPGAL */
1833#define WM8962_IN3L_TO_INPGAL 0x0002 /* IN3L_TO_INPGAL */
1834#define WM8962_IN3L_TO_INPGAL_MASK 0x0002 /* IN3L_TO_INPGAL */
1835#define WM8962_IN3L_TO_INPGAL_SHIFT 1 /* IN3L_TO_INPGAL */
1836#define WM8962_IN3L_TO_INPGAL_WIDTH 1 /* IN3L_TO_INPGAL */
1837#define WM8962_IN4L_TO_INPGAL 0x0001 /* IN4L_TO_INPGAL */
1838#define WM8962_IN4L_TO_INPGAL_MASK 0x0001 /* IN4L_TO_INPGAL */
1839#define WM8962_IN4L_TO_INPGAL_SHIFT 0 /* IN4L_TO_INPGAL */
1840#define WM8962_IN4L_TO_INPGAL_WIDTH 1 /* IN4L_TO_INPGAL */
1841
1842/*
1843 * R38 (0x26) - Right input PGA control
1844 */
1845#define WM8962_INPGAR_ENA 0x0010 /* INPGAR_ENA */
1846#define WM8962_INPGAR_ENA_MASK 0x0010 /* INPGAR_ENA */
1847#define WM8962_INPGAR_ENA_SHIFT 4 /* INPGAR_ENA */
1848#define WM8962_INPGAR_ENA_WIDTH 1 /* INPGAR_ENA */
1849#define WM8962_IN1R_TO_INPGAR 0x0008 /* IN1R_TO_INPGAR */
1850#define WM8962_IN1R_TO_INPGAR_MASK 0x0008 /* IN1R_TO_INPGAR */
1851#define WM8962_IN1R_TO_INPGAR_SHIFT 3 /* IN1R_TO_INPGAR */
1852#define WM8962_IN1R_TO_INPGAR_WIDTH 1 /* IN1R_TO_INPGAR */
1853#define WM8962_IN2R_TO_INPGAR 0x0004 /* IN2R_TO_INPGAR */
1854#define WM8962_IN2R_TO_INPGAR_MASK 0x0004 /* IN2R_TO_INPGAR */
1855#define WM8962_IN2R_TO_INPGAR_SHIFT 2 /* IN2R_TO_INPGAR */
1856#define WM8962_IN2R_TO_INPGAR_WIDTH 1 /* IN2R_TO_INPGAR */
1857#define WM8962_IN3R_TO_INPGAR 0x0002 /* IN3R_TO_INPGAR */
1858#define WM8962_IN3R_TO_INPGAR_MASK 0x0002 /* IN3R_TO_INPGAR */
1859#define WM8962_IN3R_TO_INPGAR_SHIFT 1 /* IN3R_TO_INPGAR */
1860#define WM8962_IN3R_TO_INPGAR_WIDTH 1 /* IN3R_TO_INPGAR */
1861#define WM8962_IN4R_TO_INPGAR 0x0001 /* IN4R_TO_INPGAR */
1862#define WM8962_IN4R_TO_INPGAR_MASK 0x0001 /* IN4R_TO_INPGAR */
1863#define WM8962_IN4R_TO_INPGAR_SHIFT 0 /* IN4R_TO_INPGAR */
1864#define WM8962_IN4R_TO_INPGAR_WIDTH 1 /* IN4R_TO_INPGAR */
1865
1866/*
1867 * R40 (0x28) - SPKOUTL volume
1868 */
1869#define WM8962_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1870#define WM8962_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1871#define WM8962_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1872#define WM8962_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1873#define WM8962_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
1874#define WM8962_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
1875#define WM8962_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
1876#define WM8962_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
1877#define WM8962_SPKOUTL_VOL_MASK 0x007F /* SPKOUTL_VOL - [6:0] */
1878#define WM8962_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [6:0] */
1879#define WM8962_SPKOUTL_VOL_WIDTH 7 /* SPKOUTL_VOL - [6:0] */
1880
1881/*
1882 * R41 (0x29) - SPKOUTR volume
1883 */
1884#define WM8962_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
1885#define WM8962_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
1886#define WM8962_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
1887#define WM8962_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
1888#define WM8962_SPKOUTR_VOL_MASK 0x007F /* SPKOUTR_VOL - [6:0] */
1889#define WM8962_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [6:0] */
1890#define WM8962_SPKOUTR_VOL_WIDTH 7 /* SPKOUTR_VOL - [6:0] */
1891
1892/*
1893 * R47 (0x2F) - Thermal Shutdown Status
1894 */
1895#define WM8962_TEMP_ERR_HP 0x0008 /* TEMP_ERR_HP */
1896#define WM8962_TEMP_ERR_HP_MASK 0x0008 /* TEMP_ERR_HP */
1897#define WM8962_TEMP_ERR_HP_SHIFT 3 /* TEMP_ERR_HP */
1898#define WM8962_TEMP_ERR_HP_WIDTH 1 /* TEMP_ERR_HP */
1899#define WM8962_TEMP_WARN_HP 0x0004 /* TEMP_WARN_HP */
1900#define WM8962_TEMP_WARN_HP_MASK 0x0004 /* TEMP_WARN_HP */
1901#define WM8962_TEMP_WARN_HP_SHIFT 2 /* TEMP_WARN_HP */
1902#define WM8962_TEMP_WARN_HP_WIDTH 1 /* TEMP_WARN_HP */
1903#define WM8962_TEMP_ERR_SPK 0x0002 /* TEMP_ERR_SPK */
1904#define WM8962_TEMP_ERR_SPK_MASK 0x0002 /* TEMP_ERR_SPK */
1905#define WM8962_TEMP_ERR_SPK_SHIFT 1 /* TEMP_ERR_SPK */
1906#define WM8962_TEMP_ERR_SPK_WIDTH 1 /* TEMP_ERR_SPK */
1907#define WM8962_TEMP_WARN_SPK 0x0001 /* TEMP_WARN_SPK */
1908#define WM8962_TEMP_WARN_SPK_MASK 0x0001 /* TEMP_WARN_SPK */
1909#define WM8962_TEMP_WARN_SPK_SHIFT 0 /* TEMP_WARN_SPK */
1910#define WM8962_TEMP_WARN_SPK_WIDTH 1 /* TEMP_WARN_SPK */
1911
1912/*
1913 * R48 (0x30) - Additional Control (4)
1914 */
1915#define WM8962_MICDET_THR_MASK 0x7000 /* MICDET_THR - [14:12] */
1916#define WM8962_MICDET_THR_SHIFT 12 /* MICDET_THR - [14:12] */
1917#define WM8962_MICDET_THR_WIDTH 3 /* MICDET_THR - [14:12] */
1918#define WM8962_MICSHORT_THR_MASK 0x0C00 /* MICSHORT_THR - [11:10] */
1919#define WM8962_MICSHORT_THR_SHIFT 10 /* MICSHORT_THR - [11:10] */
1920#define WM8962_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [11:10] */
1921#define WM8962_MICDET_ENA 0x0200 /* MICDET_ENA */
1922#define WM8962_MICDET_ENA_MASK 0x0200 /* MICDET_ENA */
1923#define WM8962_MICDET_ENA_SHIFT 9 /* MICDET_ENA */
1924#define WM8962_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
1925#define WM8962_MICDET_STS 0x0080 /* MICDET_STS */
1926#define WM8962_MICDET_STS_MASK 0x0080 /* MICDET_STS */
1927#define WM8962_MICDET_STS_SHIFT 7 /* MICDET_STS */
1928#define WM8962_MICDET_STS_WIDTH 1 /* MICDET_STS */
1929#define WM8962_MICSHORT_STS 0x0040 /* MICSHORT_STS */
1930#define WM8962_MICSHORT_STS_MASK 0x0040 /* MICSHORT_STS */
1931#define WM8962_MICSHORT_STS_SHIFT 6 /* MICSHORT_STS */
1932#define WM8962_MICSHORT_STS_WIDTH 1 /* MICSHORT_STS */
1933#define WM8962_TEMP_ENA_HP 0x0004 /* TEMP_ENA_HP */
1934#define WM8962_TEMP_ENA_HP_MASK 0x0004 /* TEMP_ENA_HP */
1935#define WM8962_TEMP_ENA_HP_SHIFT 2 /* TEMP_ENA_HP */
1936#define WM8962_TEMP_ENA_HP_WIDTH 1 /* TEMP_ENA_HP */
1937#define WM8962_TEMP_ENA_SPK 0x0002 /* TEMP_ENA_SPK */
1938#define WM8962_TEMP_ENA_SPK_MASK 0x0002 /* TEMP_ENA_SPK */
1939#define WM8962_TEMP_ENA_SPK_SHIFT 1 /* TEMP_ENA_SPK */
1940#define WM8962_TEMP_ENA_SPK_WIDTH 1 /* TEMP_ENA_SPK */
1941#define WM8962_MICBIAS_LVL 0x0001 /* MICBIAS_LVL */
1942#define WM8962_MICBIAS_LVL_MASK 0x0001 /* MICBIAS_LVL */
1943#define WM8962_MICBIAS_LVL_SHIFT 0 /* MICBIAS_LVL */
1944#define WM8962_MICBIAS_LVL_WIDTH 1 /* MICBIAS_LVL */
1945
1946/*
1947 * R49 (0x31) - Class D Control 1
1948 */
1949#define WM8962_SPKOUTR_ENA 0x0080 /* SPKOUTR_ENA */
1950#define WM8962_SPKOUTR_ENA_MASK 0x0080 /* SPKOUTR_ENA */
1951#define WM8962_SPKOUTR_ENA_SHIFT 7 /* SPKOUTR_ENA */
1952#define WM8962_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
1953#define WM8962_SPKOUTL_ENA 0x0040 /* SPKOUTL_ENA */
1954#define WM8962_SPKOUTL_ENA_MASK 0x0040 /* SPKOUTL_ENA */
1955#define WM8962_SPKOUTL_ENA_SHIFT 6 /* SPKOUTL_ENA */
1956#define WM8962_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
1957#define WM8962_SPKOUTL_PGA_MUTE 0x0002 /* SPKOUTL_PGA_MUTE */
1958#define WM8962_SPKOUTL_PGA_MUTE_MASK 0x0002 /* SPKOUTL_PGA_MUTE */
1959#define WM8962_SPKOUTL_PGA_MUTE_SHIFT 1 /* SPKOUTL_PGA_MUTE */
1960#define WM8962_SPKOUTL_PGA_MUTE_WIDTH 1 /* SPKOUTL_PGA_MUTE */
1961#define WM8962_SPKOUTR_PGA_MUTE 0x0001 /* SPKOUTR_PGA_MUTE */
1962#define WM8962_SPKOUTR_PGA_MUTE_MASK 0x0001 /* SPKOUTR_PGA_MUTE */
1963#define WM8962_SPKOUTR_PGA_MUTE_SHIFT 0 /* SPKOUTR_PGA_MUTE */
1964#define WM8962_SPKOUTR_PGA_MUTE_WIDTH 1 /* SPKOUTR_PGA_MUTE */
1965
1966/*
1967 * R51 (0x33) - Class D Control 2
1968 */
1969#define WM8962_SPK_MONO 0x0040 /* SPK_MONO */
1970#define WM8962_SPK_MONO_MASK 0x0040 /* SPK_MONO */
1971#define WM8962_SPK_MONO_SHIFT 6 /* SPK_MONO */
1972#define WM8962_SPK_MONO_WIDTH 1 /* SPK_MONO */
1973#define WM8962_CLASSD_VOL_MASK 0x0007 /* CLASSD_VOL - [2:0] */
1974#define WM8962_CLASSD_VOL_SHIFT 0 /* CLASSD_VOL - [2:0] */
1975#define WM8962_CLASSD_VOL_WIDTH 3 /* CLASSD_VOL - [2:0] */
1976
1977/*
1978 * R56 (0x38) - Clocking 4
1979 */
1980#define WM8962_SYSCLK_RATE_MASK 0x001E /* SYSCLK_RATE - [4:1] */
1981#define WM8962_SYSCLK_RATE_SHIFT 1 /* SYSCLK_RATE - [4:1] */
1982#define WM8962_SYSCLK_RATE_WIDTH 4 /* SYSCLK_RATE - [4:1] */
1983
1984/*
1985 * R57 (0x39) - DAC DSP Mixing (1)
1986 */
1987#define WM8962_DAC_MONOMIX 0x0200 /* DAC_MONOMIX */
1988#define WM8962_DAC_MONOMIX_MASK 0x0200 /* DAC_MONOMIX */
1989#define WM8962_DAC_MONOMIX_SHIFT 9 /* DAC_MONOMIX */
1990#define WM8962_DAC_MONOMIX_WIDTH 1 /* DAC_MONOMIX */
1991#define WM8962_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
1992#define WM8962_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
1993#define WM8962_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
1994#define WM8962_ADC_TO_DACR_MASK 0x000C /* ADC_TO_DACR - [3:2] */
1995#define WM8962_ADC_TO_DACR_SHIFT 2 /* ADC_TO_DACR - [3:2] */
1996#define WM8962_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [3:2] */
1997
1998/*
1999 * R58 (0x3A) - DAC DSP Mixing (2)
2000 */
2001#define WM8962_ADCL_DAC_SVOL_MASK 0x00F0 /* ADCL_DAC_SVOL - [7:4] */
2002#define WM8962_ADCL_DAC_SVOL_SHIFT 4 /* ADCL_DAC_SVOL - [7:4] */
2003#define WM8962_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [7:4] */
2004#define WM8962_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
2005#define WM8962_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
2006#define WM8962_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
2007
2008/*
2009 * R60 (0x3C) - DC Servo 0
2010 */
2011#define WM8962_INL_DCS_ENA 0x0080 /* INL_DCS_ENA */
2012#define WM8962_INL_DCS_ENA_MASK 0x0080 /* INL_DCS_ENA */
2013#define WM8962_INL_DCS_ENA_SHIFT 7 /* INL_DCS_ENA */
2014#define WM8962_INL_DCS_ENA_WIDTH 1 /* INL_DCS_ENA */
2015#define WM8962_INL_DCS_STARTUP 0x0040 /* INL_DCS_STARTUP */
2016#define WM8962_INL_DCS_STARTUP_MASK 0x0040 /* INL_DCS_STARTUP */
2017#define WM8962_INL_DCS_STARTUP_SHIFT 6 /* INL_DCS_STARTUP */
2018#define WM8962_INL_DCS_STARTUP_WIDTH 1 /* INL_DCS_STARTUP */
2019#define WM8962_INR_DCS_ENA 0x0008 /* INR_DCS_ENA */
2020#define WM8962_INR_DCS_ENA_MASK 0x0008 /* INR_DCS_ENA */
2021#define WM8962_INR_DCS_ENA_SHIFT 3 /* INR_DCS_ENA */
2022#define WM8962_INR_DCS_ENA_WIDTH 1 /* INR_DCS_ENA */
2023#define WM8962_INR_DCS_STARTUP 0x0004 /* INR_DCS_STARTUP */
2024#define WM8962_INR_DCS_STARTUP_MASK 0x0004 /* INR_DCS_STARTUP */
2025#define WM8962_INR_DCS_STARTUP_SHIFT 2 /* INR_DCS_STARTUP */
2026#define WM8962_INR_DCS_STARTUP_WIDTH 1 /* INR_DCS_STARTUP */
2027
2028/*
2029 * R61 (0x3D) - DC Servo 1
2030 */
2031#define WM8962_HP1L_DCS_ENA 0x0080 /* HP1L_DCS_ENA */
2032#define WM8962_HP1L_DCS_ENA_MASK 0x0080 /* HP1L_DCS_ENA */
2033#define WM8962_HP1L_DCS_ENA_SHIFT 7 /* HP1L_DCS_ENA */
2034#define WM8962_HP1L_DCS_ENA_WIDTH 1 /* HP1L_DCS_ENA */
2035#define WM8962_HP1L_DCS_STARTUP 0x0040 /* HP1L_DCS_STARTUP */
2036#define WM8962_HP1L_DCS_STARTUP_MASK 0x0040 /* HP1L_DCS_STARTUP */
2037#define WM8962_HP1L_DCS_STARTUP_SHIFT 6 /* HP1L_DCS_STARTUP */
2038#define WM8962_HP1L_DCS_STARTUP_WIDTH 1 /* HP1L_DCS_STARTUP */
2039#define WM8962_HP1L_DCS_SYNC 0x0010 /* HP1L_DCS_SYNC */
2040#define WM8962_HP1L_DCS_SYNC_MASK 0x0010 /* HP1L_DCS_SYNC */
2041#define WM8962_HP1L_DCS_SYNC_SHIFT 4 /* HP1L_DCS_SYNC */
2042#define WM8962_HP1L_DCS_SYNC_WIDTH 1 /* HP1L_DCS_SYNC */
2043#define WM8962_HP1R_DCS_ENA 0x0008 /* HP1R_DCS_ENA */
2044#define WM8962_HP1R_DCS_ENA_MASK 0x0008 /* HP1R_DCS_ENA */
2045#define WM8962_HP1R_DCS_ENA_SHIFT 3 /* HP1R_DCS_ENA */
2046#define WM8962_HP1R_DCS_ENA_WIDTH 1 /* HP1R_DCS_ENA */
2047#define WM8962_HP1R_DCS_STARTUP 0x0004 /* HP1R_DCS_STARTUP */
2048#define WM8962_HP1R_DCS_STARTUP_MASK 0x0004 /* HP1R_DCS_STARTUP */
2049#define WM8962_HP1R_DCS_STARTUP_SHIFT 2 /* HP1R_DCS_STARTUP */
2050#define WM8962_HP1R_DCS_STARTUP_WIDTH 1 /* HP1R_DCS_STARTUP */
2051#define WM8962_HP1R_DCS_SYNC 0x0001 /* HP1R_DCS_SYNC */
2052#define WM8962_HP1R_DCS_SYNC_MASK 0x0001 /* HP1R_DCS_SYNC */
2053#define WM8962_HP1R_DCS_SYNC_SHIFT 0 /* HP1R_DCS_SYNC */
2054#define WM8962_HP1R_DCS_SYNC_WIDTH 1 /* HP1R_DCS_SYNC */
2055
2056/*
2057 * R64 (0x40) - DC Servo 4
2058 */
2059#define WM8962_HP1_DCS_SYNC_STEPS_MASK 0x3F80 /* HP1_DCS_SYNC_STEPS - [13:7] */
2060#define WM8962_HP1_DCS_SYNC_STEPS_SHIFT 7 /* HP1_DCS_SYNC_STEPS - [13:7] */
2061#define WM8962_HP1_DCS_SYNC_STEPS_WIDTH 7 /* HP1_DCS_SYNC_STEPS - [13:7] */
2062
2063/*
2064 * R66 (0x42) - DC Servo 6
2065 */
2066#define WM8962_DCS_STARTUP_DONE_INL 0x0400 /* DCS_STARTUP_DONE_INL */
2067#define WM8962_DCS_STARTUP_DONE_INL_MASK 0x0400 /* DCS_STARTUP_DONE_INL */
2068#define WM8962_DCS_STARTUP_DONE_INL_SHIFT 10 /* DCS_STARTUP_DONE_INL */
2069#define WM8962_DCS_STARTUP_DONE_INL_WIDTH 1 /* DCS_STARTUP_DONE_INL */
2070#define WM8962_DCS_STARTUP_DONE_INR 0x0200 /* DCS_STARTUP_DONE_INR */
2071#define WM8962_DCS_STARTUP_DONE_INR_MASK 0x0200 /* DCS_STARTUP_DONE_INR */
2072#define WM8962_DCS_STARTUP_DONE_INR_SHIFT 9 /* DCS_STARTUP_DONE_INR */
2073#define WM8962_DCS_STARTUP_DONE_INR_WIDTH 1 /* DCS_STARTUP_DONE_INR */
2074#define WM8962_DCS_STARTUP_DONE_HP1L 0x0100 /* DCS_STARTUP_DONE_HP1L */
2075#define WM8962_DCS_STARTUP_DONE_HP1L_MASK 0x0100 /* DCS_STARTUP_DONE_HP1L */
2076#define WM8962_DCS_STARTUP_DONE_HP1L_SHIFT 8 /* DCS_STARTUP_DONE_HP1L */
2077#define WM8962_DCS_STARTUP_DONE_HP1L_WIDTH 1 /* DCS_STARTUP_DONE_HP1L */
2078#define WM8962_DCS_STARTUP_DONE_HP1R 0x0080 /* DCS_STARTUP_DONE_HP1R */
2079#define WM8962_DCS_STARTUP_DONE_HP1R_MASK 0x0080 /* DCS_STARTUP_DONE_HP1R */
2080#define WM8962_DCS_STARTUP_DONE_HP1R_SHIFT 7 /* DCS_STARTUP_DONE_HP1R */
2081#define WM8962_DCS_STARTUP_DONE_HP1R_WIDTH 1 /* DCS_STARTUP_DONE_HP1R */
2082
2083/*
2084 * R68 (0x44) - Analogue PGA Bias
2085 */
2086#define WM8962_HP_PGAS_BIAS_MASK 0x0007 /* HP_PGAS_BIAS - [2:0] */
2087#define WM8962_HP_PGAS_BIAS_SHIFT 0 /* HP_PGAS_BIAS - [2:0] */
2088#define WM8962_HP_PGAS_BIAS_WIDTH 3 /* HP_PGAS_BIAS - [2:0] */
2089
2090/*
2091 * R69 (0x45) - Analogue HP 0
2092 */
2093#define WM8962_HP1L_RMV_SHORT 0x0080 /* HP1L_RMV_SHORT */
2094#define WM8962_HP1L_RMV_SHORT_MASK 0x0080 /* HP1L_RMV_SHORT */
2095#define WM8962_HP1L_RMV_SHORT_SHIFT 7 /* HP1L_RMV_SHORT */
2096#define WM8962_HP1L_RMV_SHORT_WIDTH 1 /* HP1L_RMV_SHORT */
2097#define WM8962_HP1L_ENA_OUTP 0x0040 /* HP1L_ENA_OUTP */
2098#define WM8962_HP1L_ENA_OUTP_MASK 0x0040 /* HP1L_ENA_OUTP */
2099#define WM8962_HP1L_ENA_OUTP_SHIFT 6 /* HP1L_ENA_OUTP */
2100#define WM8962_HP1L_ENA_OUTP_WIDTH 1 /* HP1L_ENA_OUTP */
2101#define WM8962_HP1L_ENA_DLY 0x0020 /* HP1L_ENA_DLY */
2102#define WM8962_HP1L_ENA_DLY_MASK 0x0020 /* HP1L_ENA_DLY */
2103#define WM8962_HP1L_ENA_DLY_SHIFT 5 /* HP1L_ENA_DLY */
2104#define WM8962_HP1L_ENA_DLY_WIDTH 1 /* HP1L_ENA_DLY */
2105#define WM8962_HP1L_ENA 0x0010 /* HP1L_ENA */
2106#define WM8962_HP1L_ENA_MASK 0x0010 /* HP1L_ENA */
2107#define WM8962_HP1L_ENA_SHIFT 4 /* HP1L_ENA */
2108#define WM8962_HP1L_ENA_WIDTH 1 /* HP1L_ENA */
2109#define WM8962_HP1R_RMV_SHORT 0x0008 /* HP1R_RMV_SHORT */
2110#define WM8962_HP1R_RMV_SHORT_MASK 0x0008 /* HP1R_RMV_SHORT */
2111#define WM8962_HP1R_RMV_SHORT_SHIFT 3 /* HP1R_RMV_SHORT */
2112#define WM8962_HP1R_RMV_SHORT_WIDTH 1 /* HP1R_RMV_SHORT */
2113#define WM8962_HP1R_ENA_OUTP 0x0004 /* HP1R_ENA_OUTP */
2114#define WM8962_HP1R_ENA_OUTP_MASK 0x0004 /* HP1R_ENA_OUTP */
2115#define WM8962_HP1R_ENA_OUTP_SHIFT 2 /* HP1R_ENA_OUTP */
2116#define WM8962_HP1R_ENA_OUTP_WIDTH 1 /* HP1R_ENA_OUTP */
2117#define WM8962_HP1R_ENA_DLY 0x0002 /* HP1R_ENA_DLY */
2118#define WM8962_HP1R_ENA_DLY_MASK 0x0002 /* HP1R_ENA_DLY */
2119#define WM8962_HP1R_ENA_DLY_SHIFT 1 /* HP1R_ENA_DLY */
2120#define WM8962_HP1R_ENA_DLY_WIDTH 1 /* HP1R_ENA_DLY */
2121#define WM8962_HP1R_ENA 0x0001 /* HP1R_ENA */
2122#define WM8962_HP1R_ENA_MASK 0x0001 /* HP1R_ENA */
2123#define WM8962_HP1R_ENA_SHIFT 0 /* HP1R_ENA */
2124#define WM8962_HP1R_ENA_WIDTH 1 /* HP1R_ENA */
2125
2126/*
2127 * R71 (0x47) - Analogue HP 2
2128 */
2129#define WM8962_HP1L_VOL_MASK 0x01C0 /* HP1L_VOL - [8:6] */
2130#define WM8962_HP1L_VOL_SHIFT 6 /* HP1L_VOL - [8:6] */
2131#define WM8962_HP1L_VOL_WIDTH 3 /* HP1L_VOL - [8:6] */
2132#define WM8962_HP1R_VOL_MASK 0x0038 /* HP1R_VOL - [5:3] */
2133#define WM8962_HP1R_VOL_SHIFT 3 /* HP1R_VOL - [5:3] */
2134#define WM8962_HP1R_VOL_WIDTH 3 /* HP1R_VOL - [5:3] */
2135#define WM8962_HP_BIAS_BOOST_MASK 0x0007 /* HP_BIAS_BOOST - [2:0] */
2136#define WM8962_HP_BIAS_BOOST_SHIFT 0 /* HP_BIAS_BOOST - [2:0] */
2137#define WM8962_HP_BIAS_BOOST_WIDTH 3 /* HP_BIAS_BOOST - [2:0] */
2138
2139/*
2140 * R72 (0x48) - Charge Pump 1
2141 */
2142#define WM8962_CP_ENA 0x0001 /* CP_ENA */
2143#define WM8962_CP_ENA_MASK 0x0001 /* CP_ENA */
2144#define WM8962_CP_ENA_SHIFT 0 /* CP_ENA */
2145#define WM8962_CP_ENA_WIDTH 1 /* CP_ENA */
2146
2147/*
2148 * R82 (0x52) - Charge Pump B
2149 */
2150#define WM8962_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
2151#define WM8962_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
2152#define WM8962_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
2153#define WM8962_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
2154
2155/*
2156 * R87 (0x57) - Write Sequencer Control 1
2157 */
2158#define WM8962_WSEQ_AUTOSEQ_ENA 0x0080 /* WSEQ_AUTOSEQ_ENA */
2159#define WM8962_WSEQ_AUTOSEQ_ENA_MASK 0x0080 /* WSEQ_AUTOSEQ_ENA */
2160#define WM8962_WSEQ_AUTOSEQ_ENA_SHIFT 7 /* WSEQ_AUTOSEQ_ENA */
2161#define WM8962_WSEQ_AUTOSEQ_ENA_WIDTH 1 /* WSEQ_AUTOSEQ_ENA */
2162#define WM8962_WSEQ_ENA 0x0020 /* WSEQ_ENA */
2163#define WM8962_WSEQ_ENA_MASK 0x0020 /* WSEQ_ENA */
2164#define WM8962_WSEQ_ENA_SHIFT 5 /* WSEQ_ENA */
2165#define WM8962_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
2166
2167/*
2168 * R90 (0x5A) - Write Sequencer Control 2
2169 */
2170#define WM8962_WSEQ_ABORT 0x0100 /* WSEQ_ABORT */
2171#define WM8962_WSEQ_ABORT_MASK 0x0100 /* WSEQ_ABORT */
2172#define WM8962_WSEQ_ABORT_SHIFT 8 /* WSEQ_ABORT */
2173#define WM8962_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
2174#define WM8962_WSEQ_START 0x0080 /* WSEQ_START */
2175#define WM8962_WSEQ_START_MASK 0x0080 /* WSEQ_START */
2176#define WM8962_WSEQ_START_SHIFT 7 /* WSEQ_START */
2177#define WM8962_WSEQ_START_WIDTH 1 /* WSEQ_START */
2178#define WM8962_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
2179#define WM8962_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
2180#define WM8962_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
2181
2182/*
2183 * R93 (0x5D) - Write Sequencer Control 3
2184 */
2185#define WM8962_WSEQ_CURRENT_INDEX_MASK 0x03F8 /* WSEQ_CURRENT_INDEX - [9:3] */
2186#define WM8962_WSEQ_CURRENT_INDEX_SHIFT 3 /* WSEQ_CURRENT_INDEX - [9:3] */
2187#define WM8962_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [9:3] */
2188#define WM8962_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
2189#define WM8962_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
2190#define WM8962_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
2191#define WM8962_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
2192
2193/*
2194 * R94 (0x5E) - Control Interface
2195 */
2196#define WM8962_SPI_CONTRD 0x0040 /* SPI_CONTRD */
2197#define WM8962_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
2198#define WM8962_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
2199#define WM8962_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
2200#define WM8962_SPI_4WIRE 0x0020 /* SPI_4WIRE */
2201#define WM8962_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
2202#define WM8962_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
2203#define WM8962_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
2204#define WM8962_SPI_CFG 0x0010 /* SPI_CFG */
2205#define WM8962_SPI_CFG_MASK 0x0010 /* SPI_CFG */
2206#define WM8962_SPI_CFG_SHIFT 4 /* SPI_CFG */
2207#define WM8962_SPI_CFG_WIDTH 1 /* SPI_CFG */
2208
2209/*
2210 * R99 (0x63) - Mixer Enables
2211 */
2212#define WM8962_HPMIXL_ENA 0x0008 /* HPMIXL_ENA */
2213#define WM8962_HPMIXL_ENA_MASK 0x0008 /* HPMIXL_ENA */
2214#define WM8962_HPMIXL_ENA_SHIFT 3 /* HPMIXL_ENA */
2215#define WM8962_HPMIXL_ENA_WIDTH 1 /* HPMIXL_ENA */
2216#define WM8962_HPMIXR_ENA 0x0004 /* HPMIXR_ENA */
2217#define WM8962_HPMIXR_ENA_MASK 0x0004 /* HPMIXR_ENA */
2218#define WM8962_HPMIXR_ENA_SHIFT 2 /* HPMIXR_ENA */
2219#define WM8962_HPMIXR_ENA_WIDTH 1 /* HPMIXR_ENA */
2220#define WM8962_SPKMIXL_ENA 0x0002 /* SPKMIXL_ENA */
2221#define WM8962_SPKMIXL_ENA_MASK 0x0002 /* SPKMIXL_ENA */
2222#define WM8962_SPKMIXL_ENA_SHIFT 1 /* SPKMIXL_ENA */
2223#define WM8962_SPKMIXL_ENA_WIDTH 1 /* SPKMIXL_ENA */
2224#define WM8962_SPKMIXR_ENA 0x0001 /* SPKMIXR_ENA */
2225#define WM8962_SPKMIXR_ENA_MASK 0x0001 /* SPKMIXR_ENA */
2226#define WM8962_SPKMIXR_ENA_SHIFT 0 /* SPKMIXR_ENA */
2227#define WM8962_SPKMIXR_ENA_WIDTH 1 /* SPKMIXR_ENA */
2228
2229/*
2230 * R100 (0x64) - Headphone Mixer (1)
2231 */
2232#define WM8962_HPMIXL_TO_HPOUTL_PGA 0x0080 /* HPMIXL_TO_HPOUTL_PGA */
2233#define WM8962_HPMIXL_TO_HPOUTL_PGA_MASK 0x0080 /* HPMIXL_TO_HPOUTL_PGA */
2234#define WM8962_HPMIXL_TO_HPOUTL_PGA_SHIFT 7 /* HPMIXL_TO_HPOUTL_PGA */
2235#define WM8962_HPMIXL_TO_HPOUTL_PGA_WIDTH 1 /* HPMIXL_TO_HPOUTL_PGA */
2236#define WM8962_DACL_TO_HPMIXL 0x0020 /* DACL_TO_HPMIXL */
2237#define WM8962_DACL_TO_HPMIXL_MASK 0x0020 /* DACL_TO_HPMIXL */
2238#define WM8962_DACL_TO_HPMIXL_SHIFT 5 /* DACL_TO_HPMIXL */
2239#define WM8962_DACL_TO_HPMIXL_WIDTH 1 /* DACL_TO_HPMIXL */
2240#define WM8962_DACR_TO_HPMIXL 0x0010 /* DACR_TO_HPMIXL */
2241#define WM8962_DACR_TO_HPMIXL_MASK 0x0010 /* DACR_TO_HPMIXL */
2242#define WM8962_DACR_TO_HPMIXL_SHIFT 4 /* DACR_TO_HPMIXL */
2243#define WM8962_DACR_TO_HPMIXL_WIDTH 1 /* DACR_TO_HPMIXL */
2244#define WM8962_MIXINL_TO_HPMIXL 0x0008 /* MIXINL_TO_HPMIXL */
2245#define WM8962_MIXINL_TO_HPMIXL_MASK 0x0008 /* MIXINL_TO_HPMIXL */
2246#define WM8962_MIXINL_TO_HPMIXL_SHIFT 3 /* MIXINL_TO_HPMIXL */
2247#define WM8962_MIXINL_TO_HPMIXL_WIDTH 1 /* MIXINL_TO_HPMIXL */
2248#define WM8962_MIXINR_TO_HPMIXL 0x0004 /* MIXINR_TO_HPMIXL */
2249#define WM8962_MIXINR_TO_HPMIXL_MASK 0x0004 /* MIXINR_TO_HPMIXL */
2250#define WM8962_MIXINR_TO_HPMIXL_SHIFT 2 /* MIXINR_TO_HPMIXL */
2251#define WM8962_MIXINR_TO_HPMIXL_WIDTH 1 /* MIXINR_TO_HPMIXL */
2252#define WM8962_IN4L_TO_HPMIXL 0x0002 /* IN4L_TO_HPMIXL */
2253#define WM8962_IN4L_TO_HPMIXL_MASK 0x0002 /* IN4L_TO_HPMIXL */
2254#define WM8962_IN4L_TO_HPMIXL_SHIFT 1 /* IN4L_TO_HPMIXL */
2255#define WM8962_IN4L_TO_HPMIXL_WIDTH 1 /* IN4L_TO_HPMIXL */
2256#define WM8962_IN4R_TO_HPMIXL 0x0001 /* IN4R_TO_HPMIXL */
2257#define WM8962_IN4R_TO_HPMIXL_MASK 0x0001 /* IN4R_TO_HPMIXL */
2258#define WM8962_IN4R_TO_HPMIXL_SHIFT 0 /* IN4R_TO_HPMIXL */
2259#define WM8962_IN4R_TO_HPMIXL_WIDTH 1 /* IN4R_TO_HPMIXL */
2260
2261/*
2262 * R101 (0x65) - Headphone Mixer (2)
2263 */
2264#define WM8962_HPMIXR_TO_HPOUTR_PGA 0x0080 /* HPMIXR_TO_HPOUTR_PGA */
2265#define WM8962_HPMIXR_TO_HPOUTR_PGA_MASK 0x0080 /* HPMIXR_TO_HPOUTR_PGA */
2266#define WM8962_HPMIXR_TO_HPOUTR_PGA_SHIFT 7 /* HPMIXR_TO_HPOUTR_PGA */
2267#define WM8962_HPMIXR_TO_HPOUTR_PGA_WIDTH 1 /* HPMIXR_TO_HPOUTR_PGA */
2268#define WM8962_DACL_TO_HPMIXR 0x0020 /* DACL_TO_HPMIXR */
2269#define WM8962_DACL_TO_HPMIXR_MASK 0x0020 /* DACL_TO_HPMIXR */
2270#define WM8962_DACL_TO_HPMIXR_SHIFT 5 /* DACL_TO_HPMIXR */
2271#define WM8962_DACL_TO_HPMIXR_WIDTH 1 /* DACL_TO_HPMIXR */
2272#define WM8962_DACR_TO_HPMIXR 0x0010 /* DACR_TO_HPMIXR */
2273#define WM8962_DACR_TO_HPMIXR_MASK 0x0010 /* DACR_TO_HPMIXR */
2274#define WM8962_DACR_TO_HPMIXR_SHIFT 4 /* DACR_TO_HPMIXR */
2275#define WM8962_DACR_TO_HPMIXR_WIDTH 1 /* DACR_TO_HPMIXR */
2276#define WM8962_MIXINL_TO_HPMIXR 0x0008 /* MIXINL_TO_HPMIXR */
2277#define WM8962_MIXINL_TO_HPMIXR_MASK 0x0008 /* MIXINL_TO_HPMIXR */
2278#define WM8962_MIXINL_TO_HPMIXR_SHIFT 3 /* MIXINL_TO_HPMIXR */
2279#define WM8962_MIXINL_TO_HPMIXR_WIDTH 1 /* MIXINL_TO_HPMIXR */
2280#define WM8962_MIXINR_TO_HPMIXR 0x0004 /* MIXINR_TO_HPMIXR */
2281#define WM8962_MIXINR_TO_HPMIXR_MASK 0x0004 /* MIXINR_TO_HPMIXR */
2282#define WM8962_MIXINR_TO_HPMIXR_SHIFT 2 /* MIXINR_TO_HPMIXR */
2283#define WM8962_MIXINR_TO_HPMIXR_WIDTH 1 /* MIXINR_TO_HPMIXR */
2284#define WM8962_IN4L_TO_HPMIXR 0x0002 /* IN4L_TO_HPMIXR */
2285#define WM8962_IN4L_TO_HPMIXR_MASK 0x0002 /* IN4L_TO_HPMIXR */
2286#define WM8962_IN4L_TO_HPMIXR_SHIFT 1 /* IN4L_TO_HPMIXR */
2287#define WM8962_IN4L_TO_HPMIXR_WIDTH 1 /* IN4L_TO_HPMIXR */
2288#define WM8962_IN4R_TO_HPMIXR 0x0001 /* IN4R_TO_HPMIXR */
2289#define WM8962_IN4R_TO_HPMIXR_MASK 0x0001 /* IN4R_TO_HPMIXR */
2290#define WM8962_IN4R_TO_HPMIXR_SHIFT 0 /* IN4R_TO_HPMIXR */
2291#define WM8962_IN4R_TO_HPMIXR_WIDTH 1 /* IN4R_TO_HPMIXR */
2292
2293/*
2294 * R102 (0x66) - Headphone Mixer (3)
2295 */
2296#define WM8962_HPMIXL_MUTE 0x0100 /* HPMIXL_MUTE */
2297#define WM8962_HPMIXL_MUTE_MASK 0x0100 /* HPMIXL_MUTE */
2298#define WM8962_HPMIXL_MUTE_SHIFT 8 /* HPMIXL_MUTE */
2299#define WM8962_HPMIXL_MUTE_WIDTH 1 /* HPMIXL_MUTE */
2300#define WM8962_MIXINL_HPMIXL_VOL 0x0080 /* MIXINL_HPMIXL_VOL */
2301#define WM8962_MIXINL_HPMIXL_VOL_MASK 0x0080 /* MIXINL_HPMIXL_VOL */
2302#define WM8962_MIXINL_HPMIXL_VOL_SHIFT 7 /* MIXINL_HPMIXL_VOL */
2303#define WM8962_MIXINL_HPMIXL_VOL_WIDTH 1 /* MIXINL_HPMIXL_VOL */
2304#define WM8962_MIXINR_HPMIXL_VOL 0x0040 /* MIXINR_HPMIXL_VOL */
2305#define WM8962_MIXINR_HPMIXL_VOL_MASK 0x0040 /* MIXINR_HPMIXL_VOL */
2306#define WM8962_MIXINR_HPMIXL_VOL_SHIFT 6 /* MIXINR_HPMIXL_VOL */
2307#define WM8962_MIXINR_HPMIXL_VOL_WIDTH 1 /* MIXINR_HPMIXL_VOL */
2308#define WM8962_IN4L_HPMIXL_VOL_MASK 0x0038 /* IN4L_HPMIXL_VOL - [5:3] */
2309#define WM8962_IN4L_HPMIXL_VOL_SHIFT 3 /* IN4L_HPMIXL_VOL - [5:3] */
2310#define WM8962_IN4L_HPMIXL_VOL_WIDTH 3 /* IN4L_HPMIXL_VOL - [5:3] */
2311#define WM8962_IN4R_HPMIXL_VOL_MASK 0x0007 /* IN4R_HPMIXL_VOL - [2:0] */
2312#define WM8962_IN4R_HPMIXL_VOL_SHIFT 0 /* IN4R_HPMIXL_VOL - [2:0] */
2313#define WM8962_IN4R_HPMIXL_VOL_WIDTH 3 /* IN4R_HPMIXL_VOL - [2:0] */
2314
2315/*
2316 * R103 (0x67) - Headphone Mixer (4)
2317 */
2318#define WM8962_HPMIXR_MUTE 0x0100 /* HPMIXR_MUTE */
2319#define WM8962_HPMIXR_MUTE_MASK 0x0100 /* HPMIXR_MUTE */
2320#define WM8962_HPMIXR_MUTE_SHIFT 8 /* HPMIXR_MUTE */
2321#define WM8962_HPMIXR_MUTE_WIDTH 1 /* HPMIXR_MUTE */
2322#define WM8962_MIXINL_HPMIXR_VOL 0x0080 /* MIXINL_HPMIXR_VOL */
2323#define WM8962_MIXINL_HPMIXR_VOL_MASK 0x0080 /* MIXINL_HPMIXR_VOL */
2324#define WM8962_MIXINL_HPMIXR_VOL_SHIFT 7 /* MIXINL_HPMIXR_VOL */
2325#define WM8962_MIXINL_HPMIXR_VOL_WIDTH 1 /* MIXINL_HPMIXR_VOL */
2326#define WM8962_MIXINR_HPMIXR_VOL 0x0040 /* MIXINR_HPMIXR_VOL */
2327#define WM8962_MIXINR_HPMIXR_VOL_MASK 0x0040 /* MIXINR_HPMIXR_VOL */
2328#define WM8962_MIXINR_HPMIXR_VOL_SHIFT 6 /* MIXINR_HPMIXR_VOL */
2329#define WM8962_MIXINR_HPMIXR_VOL_WIDTH 1 /* MIXINR_HPMIXR_VOL */
2330#define WM8962_IN4L_HPMIXR_VOL_MASK 0x0038 /* IN4L_HPMIXR_VOL - [5:3] */
2331#define WM8962_IN4L_HPMIXR_VOL_SHIFT 3 /* IN4L_HPMIXR_VOL - [5:3] */
2332#define WM8962_IN4L_HPMIXR_VOL_WIDTH 3 /* IN4L_HPMIXR_VOL - [5:3] */
2333#define WM8962_IN4R_HPMIXR_VOL_MASK 0x0007 /* IN4R_HPMIXR_VOL - [2:0] */
2334#define WM8962_IN4R_HPMIXR_VOL_SHIFT 0 /* IN4R_HPMIXR_VOL - [2:0] */
2335#define WM8962_IN4R_HPMIXR_VOL_WIDTH 3 /* IN4R_HPMIXR_VOL - [2:0] */
2336
2337/*
2338 * R105 (0x69) - Speaker Mixer (1)
2339 */
2340#define WM8962_SPKMIXL_TO_SPKOUTL_PGA 0x0080 /* SPKMIXL_TO_SPKOUTL_PGA */
2341#define WM8962_SPKMIXL_TO_SPKOUTL_PGA_MASK 0x0080 /* SPKMIXL_TO_SPKOUTL_PGA */
2342#define WM8962_SPKMIXL_TO_SPKOUTL_PGA_SHIFT 7 /* SPKMIXL_TO_SPKOUTL_PGA */
2343#define WM8962_SPKMIXL_TO_SPKOUTL_PGA_WIDTH 1 /* SPKMIXL_TO_SPKOUTL_PGA */
2344#define WM8962_DACL_TO_SPKMIXL 0x0020 /* DACL_TO_SPKMIXL */
2345#define WM8962_DACL_TO_SPKMIXL_MASK 0x0020 /* DACL_TO_SPKMIXL */
2346#define WM8962_DACL_TO_SPKMIXL_SHIFT 5 /* DACL_TO_SPKMIXL */
2347#define WM8962_DACL_TO_SPKMIXL_WIDTH 1 /* DACL_TO_SPKMIXL */
2348#define WM8962_DACR_TO_SPKMIXL 0x0010 /* DACR_TO_SPKMIXL */
2349#define WM8962_DACR_TO_SPKMIXL_MASK 0x0010 /* DACR_TO_SPKMIXL */
2350#define WM8962_DACR_TO_SPKMIXL_SHIFT 4 /* DACR_TO_SPKMIXL */
2351#define WM8962_DACR_TO_SPKMIXL_WIDTH 1 /* DACR_TO_SPKMIXL */
2352#define WM8962_MIXINL_TO_SPKMIXL 0x0008 /* MIXINL_TO_SPKMIXL */
2353#define WM8962_MIXINL_TO_SPKMIXL_MASK 0x0008 /* MIXINL_TO_SPKMIXL */
2354#define WM8962_MIXINL_TO_SPKMIXL_SHIFT 3 /* MIXINL_TO_SPKMIXL */
2355#define WM8962_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
2356#define WM8962_MIXINR_TO_SPKMIXL 0x0004 /* MIXINR_TO_SPKMIXL */
2357#define WM8962_MIXINR_TO_SPKMIXL_MASK 0x0004 /* MIXINR_TO_SPKMIXL */
2358#define WM8962_MIXINR_TO_SPKMIXL_SHIFT 2 /* MIXINR_TO_SPKMIXL */
2359#define WM8962_MIXINR_TO_SPKMIXL_WIDTH 1 /* MIXINR_TO_SPKMIXL */
2360#define WM8962_IN4L_TO_SPKMIXL 0x0002 /* IN4L_TO_SPKMIXL */
2361#define WM8962_IN4L_TO_SPKMIXL_MASK 0x0002 /* IN4L_TO_SPKMIXL */
2362#define WM8962_IN4L_TO_SPKMIXL_SHIFT 1 /* IN4L_TO_SPKMIXL */
2363#define WM8962_IN4L_TO_SPKMIXL_WIDTH 1 /* IN4L_TO_SPKMIXL */
2364#define WM8962_IN4R_TO_SPKMIXL 0x0001 /* IN4R_TO_SPKMIXL */
2365#define WM8962_IN4R_TO_SPKMIXL_MASK 0x0001 /* IN4R_TO_SPKMIXL */
2366#define WM8962_IN4R_TO_SPKMIXL_SHIFT 0 /* IN4R_TO_SPKMIXL */
2367#define WM8962_IN4R_TO_SPKMIXL_WIDTH 1 /* IN4R_TO_SPKMIXL */
2368
2369/*
2370 * R106 (0x6A) - Speaker Mixer (2)
2371 */
2372#define WM8962_SPKMIXR_TO_SPKOUTR_PGA 0x0080 /* SPKMIXR_TO_SPKOUTR_PGA */
2373#define WM8962_SPKMIXR_TO_SPKOUTR_PGA_MASK 0x0080 /* SPKMIXR_TO_SPKOUTR_PGA */
2374#define WM8962_SPKMIXR_TO_SPKOUTR_PGA_SHIFT 7 /* SPKMIXR_TO_SPKOUTR_PGA */
2375#define WM8962_SPKMIXR_TO_SPKOUTR_PGA_WIDTH 1 /* SPKMIXR_TO_SPKOUTR_PGA */
2376#define WM8962_DACL_TO_SPKMIXR 0x0020 /* DACL_TO_SPKMIXR */
2377#define WM8962_DACL_TO_SPKMIXR_MASK 0x0020 /* DACL_TO_SPKMIXR */
2378#define WM8962_DACL_TO_SPKMIXR_SHIFT 5 /* DACL_TO_SPKMIXR */
2379#define WM8962_DACL_TO_SPKMIXR_WIDTH 1 /* DACL_TO_SPKMIXR */
2380#define WM8962_DACR_TO_SPKMIXR 0x0010 /* DACR_TO_SPKMIXR */
2381#define WM8962_DACR_TO_SPKMIXR_MASK 0x0010 /* DACR_TO_SPKMIXR */
2382#define WM8962_DACR_TO_SPKMIXR_SHIFT 4 /* DACR_TO_SPKMIXR */
2383#define WM8962_DACR_TO_SPKMIXR_WIDTH 1 /* DACR_TO_SPKMIXR */
2384#define WM8962_MIXINL_TO_SPKMIXR 0x0008 /* MIXINL_TO_SPKMIXR */
2385#define WM8962_MIXINL_TO_SPKMIXR_MASK 0x0008 /* MIXINL_TO_SPKMIXR */
2386#define WM8962_MIXINL_TO_SPKMIXR_SHIFT 3 /* MIXINL_TO_SPKMIXR */
2387#define WM8962_MIXINL_TO_SPKMIXR_WIDTH 1 /* MIXINL_TO_SPKMIXR */
2388#define WM8962_MIXINR_TO_SPKMIXR 0x0004 /* MIXINR_TO_SPKMIXR */
2389#define WM8962_MIXINR_TO_SPKMIXR_MASK 0x0004 /* MIXINR_TO_SPKMIXR */
2390#define WM8962_MIXINR_TO_SPKMIXR_SHIFT 2 /* MIXINR_TO_SPKMIXR */
2391#define WM8962_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
2392#define WM8962_IN4L_TO_SPKMIXR 0x0002 /* IN4L_TO_SPKMIXR */
2393#define WM8962_IN4L_TO_SPKMIXR_MASK 0x0002 /* IN4L_TO_SPKMIXR */
2394#define WM8962_IN4L_TO_SPKMIXR_SHIFT 1 /* IN4L_TO_SPKMIXR */
2395#define WM8962_IN4L_TO_SPKMIXR_WIDTH 1 /* IN4L_TO_SPKMIXR */
2396#define WM8962_IN4R_TO_SPKMIXR 0x0001 /* IN4R_TO_SPKMIXR */
2397#define WM8962_IN4R_TO_SPKMIXR_MASK 0x0001 /* IN4R_TO_SPKMIXR */
2398#define WM8962_IN4R_TO_SPKMIXR_SHIFT 0 /* IN4R_TO_SPKMIXR */
2399#define WM8962_IN4R_TO_SPKMIXR_WIDTH 1 /* IN4R_TO_SPKMIXR */
2400
2401/*
2402 * R107 (0x6B) - Speaker Mixer (3)
2403 */
2404#define WM8962_SPKMIXL_MUTE 0x0100 /* SPKMIXL_MUTE */
2405#define WM8962_SPKMIXL_MUTE_MASK 0x0100 /* SPKMIXL_MUTE */
2406#define WM8962_SPKMIXL_MUTE_SHIFT 8 /* SPKMIXL_MUTE */
2407#define WM8962_SPKMIXL_MUTE_WIDTH 1 /* SPKMIXL_MUTE */
2408#define WM8962_MIXINL_SPKMIXL_VOL 0x0080 /* MIXINL_SPKMIXL_VOL */
2409#define WM8962_MIXINL_SPKMIXL_VOL_MASK 0x0080 /* MIXINL_SPKMIXL_VOL */
2410#define WM8962_MIXINL_SPKMIXL_VOL_SHIFT 7 /* MIXINL_SPKMIXL_VOL */
2411#define WM8962_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
2412#define WM8962_MIXINR_SPKMIXL_VOL 0x0040 /* MIXINR_SPKMIXL_VOL */
2413#define WM8962_MIXINR_SPKMIXL_VOL_MASK 0x0040 /* MIXINR_SPKMIXL_VOL */
2414#define WM8962_MIXINR_SPKMIXL_VOL_SHIFT 6 /* MIXINR_SPKMIXL_VOL */
2415#define WM8962_MIXINR_SPKMIXL_VOL_WIDTH 1 /* MIXINR_SPKMIXL_VOL */
2416#define WM8962_IN4L_SPKMIXL_VOL_MASK 0x0038 /* IN4L_SPKMIXL_VOL - [5:3] */
2417#define WM8962_IN4L_SPKMIXL_VOL_SHIFT 3 /* IN4L_SPKMIXL_VOL - [5:3] */
2418#define WM8962_IN4L_SPKMIXL_VOL_WIDTH 3 /* IN4L_SPKMIXL_VOL - [5:3] */
2419#define WM8962_IN4R_SPKMIXL_VOL_MASK 0x0007 /* IN4R_SPKMIXL_VOL - [2:0] */
2420#define WM8962_IN4R_SPKMIXL_VOL_SHIFT 0 /* IN4R_SPKMIXL_VOL - [2:0] */
2421#define WM8962_IN4R_SPKMIXL_VOL_WIDTH 3 /* IN4R_SPKMIXL_VOL - [2:0] */
2422
2423/*
2424 * R108 (0x6C) - Speaker Mixer (4)
2425 */
2426#define WM8962_SPKMIXR_MUTE 0x0100 /* SPKMIXR_MUTE */
2427#define WM8962_SPKMIXR_MUTE_MASK 0x0100 /* SPKMIXR_MUTE */
2428#define WM8962_SPKMIXR_MUTE_SHIFT 8 /* SPKMIXR_MUTE */
2429#define WM8962_SPKMIXR_MUTE_WIDTH 1 /* SPKMIXR_MUTE */
2430#define WM8962_MIXINL_SPKMIXR_VOL 0x0080 /* MIXINL_SPKMIXR_VOL */
2431#define WM8962_MIXINL_SPKMIXR_VOL_MASK 0x0080 /* MIXINL_SPKMIXR_VOL */
2432#define WM8962_MIXINL_SPKMIXR_VOL_SHIFT 7 /* MIXINL_SPKMIXR_VOL */
2433#define WM8962_MIXINL_SPKMIXR_VOL_WIDTH 1 /* MIXINL_SPKMIXR_VOL */
2434#define WM8962_MIXINR_SPKMIXR_VOL 0x0040 /* MIXINR_SPKMIXR_VOL */
2435#define WM8962_MIXINR_SPKMIXR_VOL_MASK 0x0040 /* MIXINR_SPKMIXR_VOL */
2436#define WM8962_MIXINR_SPKMIXR_VOL_SHIFT 6 /* MIXINR_SPKMIXR_VOL */
2437#define WM8962_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
2438#define WM8962_IN4L_SPKMIXR_VOL_MASK 0x0038 /* IN4L_SPKMIXR_VOL - [5:3] */
2439#define WM8962_IN4L_SPKMIXR_VOL_SHIFT 3 /* IN4L_SPKMIXR_VOL - [5:3] */
2440#define WM8962_IN4L_SPKMIXR_VOL_WIDTH 3 /* IN4L_SPKMIXR_VOL - [5:3] */
2441#define WM8962_IN4R_SPKMIXR_VOL_MASK 0x0007 /* IN4R_SPKMIXR_VOL - [2:0] */
2442#define WM8962_IN4R_SPKMIXR_VOL_SHIFT 0 /* IN4R_SPKMIXR_VOL - [2:0] */
2443#define WM8962_IN4R_SPKMIXR_VOL_WIDTH 3 /* IN4R_SPKMIXR_VOL - [2:0] */
2444
2445/*
2446 * R109 (0x6D) - Speaker Mixer (5)
2447 */
2448#define WM8962_DACL_SPKMIXL_VOL 0x0080 /* DACL_SPKMIXL_VOL */
2449#define WM8962_DACL_SPKMIXL_VOL_MASK 0x0080 /* DACL_SPKMIXL_VOL */
2450#define WM8962_DACL_SPKMIXL_VOL_SHIFT 7 /* DACL_SPKMIXL_VOL */
2451#define WM8962_DACL_SPKMIXL_VOL_WIDTH 1 /* DACL_SPKMIXL_VOL */
2452#define WM8962_DACR_SPKMIXL_VOL 0x0040 /* DACR_SPKMIXL_VOL */
2453#define WM8962_DACR_SPKMIXL_VOL_MASK 0x0040 /* DACR_SPKMIXL_VOL */
2454#define WM8962_DACR_SPKMIXL_VOL_SHIFT 6 /* DACR_SPKMIXL_VOL */
2455#define WM8962_DACR_SPKMIXL_VOL_WIDTH 1 /* DACR_SPKMIXL_VOL */
2456#define WM8962_DACL_SPKMIXR_VOL 0x0020 /* DACL_SPKMIXR_VOL */
2457#define WM8962_DACL_SPKMIXR_VOL_MASK 0x0020 /* DACL_SPKMIXR_VOL */
2458#define WM8962_DACL_SPKMIXR_VOL_SHIFT 5 /* DACL_SPKMIXR_VOL */
2459#define WM8962_DACL_SPKMIXR_VOL_WIDTH 1 /* DACL_SPKMIXR_VOL */
2460#define WM8962_DACR_SPKMIXR_VOL 0x0010 /* DACR_SPKMIXR_VOL */
2461#define WM8962_DACR_SPKMIXR_VOL_MASK 0x0010 /* DACR_SPKMIXR_VOL */
2462#define WM8962_DACR_SPKMIXR_VOL_SHIFT 4 /* DACR_SPKMIXR_VOL */
2463#define WM8962_DACR_SPKMIXR_VOL_WIDTH 1 /* DACR_SPKMIXR_VOL */
2464
2465/*
2466 * R110 (0x6E) - Beep Generator (1)
2467 */
2468#define WM8962_BEEP_GAIN_MASK 0x00F0 /* BEEP_GAIN - [7:4] */
2469#define WM8962_BEEP_GAIN_SHIFT 4 /* BEEP_GAIN - [7:4] */
2470#define WM8962_BEEP_GAIN_WIDTH 4 /* BEEP_GAIN - [7:4] */
2471#define WM8962_BEEP_RATE_MASK 0x0006 /* BEEP_RATE - [2:1] */
2472#define WM8962_BEEP_RATE_SHIFT 1 /* BEEP_RATE - [2:1] */
2473#define WM8962_BEEP_RATE_WIDTH 2 /* BEEP_RATE - [2:1] */
2474#define WM8962_BEEP_ENA 0x0001 /* BEEP_ENA */
2475#define WM8962_BEEP_ENA_MASK 0x0001 /* BEEP_ENA */
2476#define WM8962_BEEP_ENA_SHIFT 0 /* BEEP_ENA */
2477#define WM8962_BEEP_ENA_WIDTH 1 /* BEEP_ENA */
2478
2479/*
2480 * R115 (0x73) - Oscillator Trim (3)
2481 */
2482#define WM8962_OSC_TRIM_XTI_MASK 0x001F /* OSC_TRIM_XTI - [4:0] */
2483#define WM8962_OSC_TRIM_XTI_SHIFT 0 /* OSC_TRIM_XTI - [4:0] */
2484#define WM8962_OSC_TRIM_XTI_WIDTH 5 /* OSC_TRIM_XTI - [4:0] */
2485
2486/*
2487 * R116 (0x74) - Oscillator Trim (4)
2488 */
2489#define WM8962_OSC_TRIM_XTO_MASK 0x001F /* OSC_TRIM_XTO - [4:0] */
2490#define WM8962_OSC_TRIM_XTO_SHIFT 0 /* OSC_TRIM_XTO - [4:0] */
2491#define WM8962_OSC_TRIM_XTO_WIDTH 5 /* OSC_TRIM_XTO - [4:0] */
2492
2493/*
2494 * R119 (0x77) - Oscillator Trim (7)
2495 */
2496#define WM8962_XTO_CAP_SEL_MASK 0x00F0 /* XTO_CAP_SEL - [7:4] */
2497#define WM8962_XTO_CAP_SEL_SHIFT 4 /* XTO_CAP_SEL - [7:4] */
2498#define WM8962_XTO_CAP_SEL_WIDTH 4 /* XTO_CAP_SEL - [7:4] */
2499#define WM8962_XTI_CAP_SEL_MASK 0x000F /* XTI_CAP_SEL - [3:0] */
2500#define WM8962_XTI_CAP_SEL_SHIFT 0 /* XTI_CAP_SEL - [3:0] */
2501#define WM8962_XTI_CAP_SEL_WIDTH 4 /* XTI_CAP_SEL - [3:0] */
2502
2503/*
2504 * R124 (0x7C) - Analogue Clocking1
2505 */
2506#define WM8962_CLKOUT2_SEL_MASK 0x0060 /* CLKOUT2_SEL - [6:5] */
2507#define WM8962_CLKOUT2_SEL_SHIFT 5 /* CLKOUT2_SEL - [6:5] */
2508#define WM8962_CLKOUT2_SEL_WIDTH 2 /* CLKOUT2_SEL - [6:5] */
2509#define WM8962_CLKOUT3_SEL_MASK 0x0018 /* CLKOUT3_SEL - [4:3] */
2510#define WM8962_CLKOUT3_SEL_SHIFT 3 /* CLKOUT3_SEL - [4:3] */
2511#define WM8962_CLKOUT3_SEL_WIDTH 2 /* CLKOUT3_SEL - [4:3] */
2512#define WM8962_CLKOUT5_SEL 0x0001 /* CLKOUT5_SEL */
2513#define WM8962_CLKOUT5_SEL_MASK 0x0001 /* CLKOUT5_SEL */
2514#define WM8962_CLKOUT5_SEL_SHIFT 0 /* CLKOUT5_SEL */
2515#define WM8962_CLKOUT5_SEL_WIDTH 1 /* CLKOUT5_SEL */
2516
2517/*
2518 * R125 (0x7D) - Analogue Clocking2
2519 */
2520#define WM8962_PLL2_OUTDIV 0x0080 /* PLL2_OUTDIV */
2521#define WM8962_PLL2_OUTDIV_MASK 0x0080 /* PLL2_OUTDIV */
2522#define WM8962_PLL2_OUTDIV_SHIFT 7 /* PLL2_OUTDIV */
2523#define WM8962_PLL2_OUTDIV_WIDTH 1 /* PLL2_OUTDIV */
2524#define WM8962_PLL3_OUTDIV 0x0040 /* PLL3_OUTDIV */
2525#define WM8962_PLL3_OUTDIV_MASK 0x0040 /* PLL3_OUTDIV */
2526#define WM8962_PLL3_OUTDIV_SHIFT 6 /* PLL3_OUTDIV */
2527#define WM8962_PLL3_OUTDIV_WIDTH 1 /* PLL3_OUTDIV */
2528#define WM8962_PLL_SYSCLK_DIV_MASK 0x0018 /* PLL_SYSCLK_DIV - [4:3] */
2529#define WM8962_PLL_SYSCLK_DIV_SHIFT 3 /* PLL_SYSCLK_DIV - [4:3] */
2530#define WM8962_PLL_SYSCLK_DIV_WIDTH 2 /* PLL_SYSCLK_DIV - [4:3] */
2531#define WM8962_CLKOUT3_DIV 0x0004 /* CLKOUT3_DIV */
2532#define WM8962_CLKOUT3_DIV_MASK 0x0004 /* CLKOUT3_DIV */
2533#define WM8962_CLKOUT3_DIV_SHIFT 2 /* CLKOUT3_DIV */
2534#define WM8962_CLKOUT3_DIV_WIDTH 1 /* CLKOUT3_DIV */
2535#define WM8962_CLKOUT2_DIV 0x0002 /* CLKOUT2_DIV */
2536#define WM8962_CLKOUT2_DIV_MASK 0x0002 /* CLKOUT2_DIV */
2537#define WM8962_CLKOUT2_DIV_SHIFT 1 /* CLKOUT2_DIV */
2538#define WM8962_CLKOUT2_DIV_WIDTH 1 /* CLKOUT2_DIV */
2539#define WM8962_CLKOUT5_DIV 0x0001 /* CLKOUT5_DIV */
2540#define WM8962_CLKOUT5_DIV_MASK 0x0001 /* CLKOUT5_DIV */
2541#define WM8962_CLKOUT5_DIV_SHIFT 0 /* CLKOUT5_DIV */
2542#define WM8962_CLKOUT5_DIV_WIDTH 1 /* CLKOUT5_DIV */
2543
2544/*
2545 * R126 (0x7E) - Analogue Clocking3
2546 */
2547#define WM8962_CLKOUT2_OE 0x0008 /* CLKOUT2_OE */
2548#define WM8962_CLKOUT2_OE_MASK 0x0008 /* CLKOUT2_OE */
2549#define WM8962_CLKOUT2_OE_SHIFT 3 /* CLKOUT2_OE */
2550#define WM8962_CLKOUT2_OE_WIDTH 1 /* CLKOUT2_OE */
2551#define WM8962_CLKOUT3_OE 0x0004 /* CLKOUT3_OE */
2552#define WM8962_CLKOUT3_OE_MASK 0x0004 /* CLKOUT3_OE */
2553#define WM8962_CLKOUT3_OE_SHIFT 2 /* CLKOUT3_OE */
2554#define WM8962_CLKOUT3_OE_WIDTH 1 /* CLKOUT3_OE */
2555#define WM8962_CLKOUT5_OE 0x0001 /* CLKOUT5_OE */
2556#define WM8962_CLKOUT5_OE_MASK 0x0001 /* CLKOUT5_OE */
2557#define WM8962_CLKOUT5_OE_SHIFT 0 /* CLKOUT5_OE */
2558#define WM8962_CLKOUT5_OE_WIDTH 1 /* CLKOUT5_OE */
2559
2560/*
2561 * R127 (0x7F) - PLL Software Reset
2562 */
2563#define WM8962_SW_RESET_PLL_MASK 0xFFFF /* SW_RESET_PLL - [15:0] */
2564#define WM8962_SW_RESET_PLL_SHIFT 0 /* SW_RESET_PLL - [15:0] */
2565#define WM8962_SW_RESET_PLL_WIDTH 16 /* SW_RESET_PLL - [15:0] */
2566
2567/*
2568 * R129 (0x81) - PLL2
2569 */
2570#define WM8962_OSC_ENA 0x0080 /* OSC_ENA */
2571#define WM8962_OSC_ENA_MASK 0x0080 /* OSC_ENA */
2572#define WM8962_OSC_ENA_SHIFT 7 /* OSC_ENA */
2573#define WM8962_OSC_ENA_WIDTH 1 /* OSC_ENA */
2574#define WM8962_PLL2_ENA 0x0020 /* PLL2_ENA */
2575#define WM8962_PLL2_ENA_MASK 0x0020 /* PLL2_ENA */
2576#define WM8962_PLL2_ENA_SHIFT 5 /* PLL2_ENA */
2577#define WM8962_PLL2_ENA_WIDTH 1 /* PLL2_ENA */
2578#define WM8962_PLL3_ENA 0x0010 /* PLL3_ENA */
2579#define WM8962_PLL3_ENA_MASK 0x0010 /* PLL3_ENA */
2580#define WM8962_PLL3_ENA_SHIFT 4 /* PLL3_ENA */
2581#define WM8962_PLL3_ENA_WIDTH 1 /* PLL3_ENA */
2582
2583/*
2584 * R131 (0x83) - PLL 4
2585 */
2586#define WM8962_PLL_CLK_SRC 0x0002 /* PLL_CLK_SRC */
2587#define WM8962_PLL_CLK_SRC_MASK 0x0002 /* PLL_CLK_SRC */
2588#define WM8962_PLL_CLK_SRC_SHIFT 1 /* PLL_CLK_SRC */
2589#define WM8962_PLL_CLK_SRC_WIDTH 1 /* PLL_CLK_SRC */
2590#define WM8962_FLL_TO_PLL3 0x0001 /* FLL_TO_PLL3 */
2591#define WM8962_FLL_TO_PLL3_MASK 0x0001 /* FLL_TO_PLL3 */
2592#define WM8962_FLL_TO_PLL3_SHIFT 0 /* FLL_TO_PLL3 */
2593#define WM8962_FLL_TO_PLL3_WIDTH 1 /* FLL_TO_PLL3 */
2594
2595/*
2596 * R136 (0x88) - PLL 9
2597 */
2598#define WM8962_PLL2_FRAC 0x0040 /* PLL2_FRAC */
2599#define WM8962_PLL2_FRAC_MASK 0x0040 /* PLL2_FRAC */
2600#define WM8962_PLL2_FRAC_SHIFT 6 /* PLL2_FRAC */
2601#define WM8962_PLL2_FRAC_WIDTH 1 /* PLL2_FRAC */
2602#define WM8962_PLL2_N_MASK 0x001F /* PLL2_N - [4:0] */
2603#define WM8962_PLL2_N_SHIFT 0 /* PLL2_N - [4:0] */
2604#define WM8962_PLL2_N_WIDTH 5 /* PLL2_N - [4:0] */
2605
2606/*
2607 * R137 (0x89) - PLL 10
2608 */
2609#define WM8962_PLL2_K_MASK 0x00FF /* PLL2_K - [7:0] */
2610#define WM8962_PLL2_K_SHIFT 0 /* PLL2_K - [7:0] */
2611#define WM8962_PLL2_K_WIDTH 8 /* PLL2_K - [7:0] */
2612
2613/*
2614 * R138 (0x8A) - PLL 11
2615 */
2616#define WM8962_PLL2_K_MASK 0x00FF /* PLL2_K - [7:0] */
2617#define WM8962_PLL2_K_SHIFT 0 /* PLL2_K - [7:0] */
2618#define WM8962_PLL2_K_WIDTH 8 /* PLL2_K - [7:0] */
2619
2620/*
2621 * R139 (0x8B) - PLL 12
2622 */
2623#define WM8962_PLL2_K_MASK 0x00FF /* PLL2_K - [7:0] */
2624#define WM8962_PLL2_K_SHIFT 0 /* PLL2_K - [7:0] */
2625#define WM8962_PLL2_K_WIDTH 8 /* PLL2_K - [7:0] */
2626
2627/*
2628 * R140 (0x8C) - PLL 13
2629 */
2630#define WM8962_PLL3_FRAC 0x0040 /* PLL3_FRAC */
2631#define WM8962_PLL3_FRAC_MASK 0x0040 /* PLL3_FRAC */
2632#define WM8962_PLL3_FRAC_SHIFT 6 /* PLL3_FRAC */
2633#define WM8962_PLL3_FRAC_WIDTH 1 /* PLL3_FRAC */
2634#define WM8962_PLL3_N_MASK 0x001F /* PLL3_N - [4:0] */
2635#define WM8962_PLL3_N_SHIFT 0 /* PLL3_N - [4:0] */
2636#define WM8962_PLL3_N_WIDTH 5 /* PLL3_N - [4:0] */
2637
2638/*
2639 * R141 (0x8D) - PLL 14
2640 */
2641#define WM8962_PLL3_K_MASK 0x00FF /* PLL3_K - [7:0] */
2642#define WM8962_PLL3_K_SHIFT 0 /* PLL3_K - [7:0] */
2643#define WM8962_PLL3_K_WIDTH 8 /* PLL3_K - [7:0] */
2644
2645/*
2646 * R142 (0x8E) - PLL 15
2647 */
2648#define WM8962_PLL3_K_MASK 0x00FF /* PLL3_K - [7:0] */
2649#define WM8962_PLL3_K_SHIFT 0 /* PLL3_K - [7:0] */
2650#define WM8962_PLL3_K_WIDTH 8 /* PLL3_K - [7:0] */
2651
2652/*
2653 * R143 (0x8F) - PLL 16
2654 */
2655#define WM8962_PLL3_K_MASK 0x00FF /* PLL3_K - [7:0] */
2656#define WM8962_PLL3_K_SHIFT 0 /* PLL3_K - [7:0] */
2657#define WM8962_PLL3_K_WIDTH 8 /* PLL3_K - [7:0] */
2658
2659/*
2660 * R155 (0x9B) - FLL Control (1)
2661 */
2662#define WM8962_FLL_REFCLK_SRC_MASK 0x0060 /* FLL_REFCLK_SRC - [6:5] */
2663#define WM8962_FLL_REFCLK_SRC_SHIFT 5 /* FLL_REFCLK_SRC - [6:5] */
2664#define WM8962_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [6:5] */
2665#define WM8962_FLL_FRAC 0x0004 /* FLL_FRAC */
2666#define WM8962_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */
2667#define WM8962_FLL_FRAC_SHIFT 2 /* FLL_FRAC */
2668#define WM8962_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
2669#define WM8962_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
2670#define WM8962_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
2671#define WM8962_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
2672#define WM8962_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
2673#define WM8962_FLL_ENA 0x0001 /* FLL_ENA */
2674#define WM8962_FLL_ENA_MASK 0x0001 /* FLL_ENA */
2675#define WM8962_FLL_ENA_SHIFT 0 /* FLL_ENA */
2676#define WM8962_FLL_ENA_WIDTH 1 /* FLL_ENA */
2677
2678/*
2679 * R156 (0x9C) - FLL Control (2)
2680 */
2681#define WM8962_FLL_OUTDIV_MASK 0x01F8 /* FLL_OUTDIV - [8:3] */
2682#define WM8962_FLL_OUTDIV_SHIFT 3 /* FLL_OUTDIV - [8:3] */
2683#define WM8962_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [8:3] */
2684#define WM8962_FLL_REFCLK_DIV_MASK 0x0003 /* FLL_REFCLK_DIV - [1:0] */
2685#define WM8962_FLL_REFCLK_DIV_SHIFT 0 /* FLL_REFCLK_DIV - [1:0] */
2686#define WM8962_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [1:0] */
2687
2688/*
2689 * R157 (0x9D) - FLL Control (3)
2690 */
2691#define WM8962_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
2692#define WM8962_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
2693#define WM8962_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
2694
2695/*
2696 * R159 (0x9F) - FLL Control (5)
2697 */
2698#define WM8962_FLL_FRC_NCO_VAL_MASK 0x007E /* FLL_FRC_NCO_VAL - [6:1] */
2699#define WM8962_FLL_FRC_NCO_VAL_SHIFT 1 /* FLL_FRC_NCO_VAL - [6:1] */
2700#define WM8962_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [6:1] */
2701#define WM8962_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
2702#define WM8962_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
2703#define WM8962_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
2704#define WM8962_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
2705
2706/*
2707 * R160 (0xA0) - FLL Control (6)
2708 */
2709#define WM8962_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */
2710#define WM8962_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */
2711#define WM8962_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */
2712
2713/*
2714 * R161 (0xA1) - FLL Control (7)
2715 */
2716#define WM8962_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */
2717#define WM8962_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */
2718#define WM8962_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */
2719
2720/*
2721 * R162 (0xA2) - FLL Control (8)
2722 */
2723#define WM8962_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */
2724#define WM8962_FLL_N_SHIFT 0 /* FLL_N - [9:0] */
2725#define WM8962_FLL_N_WIDTH 10 /* FLL_N - [9:0] */
2726
2727/*
2728 * R252 (0xFC) - General test 1
2729 */
2730#define WM8962_REG_SYNC 0x0004 /* REG_SYNC */
2731#define WM8962_REG_SYNC_MASK 0x0004 /* REG_SYNC */
2732#define WM8962_REG_SYNC_SHIFT 2 /* REG_SYNC */
2733#define WM8962_REG_SYNC_WIDTH 1 /* REG_SYNC */
2734#define WM8962_AUTO_INC 0x0001 /* AUTO_INC */
2735#define WM8962_AUTO_INC_MASK 0x0001 /* AUTO_INC */
2736#define WM8962_AUTO_INC_SHIFT 0 /* AUTO_INC */
2737#define WM8962_AUTO_INC_WIDTH 1 /* AUTO_INC */
2738
2739/*
2740 * R256 (0x100) - DF1
2741 */
2742#define WM8962_DRC_DF1_ENA 0x0008 /* DRC_DF1_ENA */
2743#define WM8962_DRC_DF1_ENA_MASK 0x0008 /* DRC_DF1_ENA */
2744#define WM8962_DRC_DF1_ENA_SHIFT 3 /* DRC_DF1_ENA */
2745#define WM8962_DRC_DF1_ENA_WIDTH 1 /* DRC_DF1_ENA */
2746#define WM8962_DF1_SHARED_COEFF 0x0004 /* DF1_SHARED_COEFF */
2747#define WM8962_DF1_SHARED_COEFF_MASK 0x0004 /* DF1_SHARED_COEFF */
2748#define WM8962_DF1_SHARED_COEFF_SHIFT 2 /* DF1_SHARED_COEFF */
2749#define WM8962_DF1_SHARED_COEFF_WIDTH 1 /* DF1_SHARED_COEFF */
2750#define WM8962_DF1_SHARED_COEFF_SEL 0x0002 /* DF1_SHARED_COEFF_SEL */
2751#define WM8962_DF1_SHARED_COEFF_SEL_MASK 0x0002 /* DF1_SHARED_COEFF_SEL */
2752#define WM8962_DF1_SHARED_COEFF_SEL_SHIFT 1 /* DF1_SHARED_COEFF_SEL */
2753#define WM8962_DF1_SHARED_COEFF_SEL_WIDTH 1 /* DF1_SHARED_COEFF_SEL */
2754#define WM8962_DF1_ENA 0x0001 /* DF1_ENA */
2755#define WM8962_DF1_ENA_MASK 0x0001 /* DF1_ENA */
2756#define WM8962_DF1_ENA_SHIFT 0 /* DF1_ENA */
2757#define WM8962_DF1_ENA_WIDTH 1 /* DF1_ENA */
2758
2759/*
2760 * R257 (0x101) - DF2
2761 */
2762#define WM8962_DF1_COEFF_L0_MASK 0xFFFF /* DF1_COEFF_L0 - [15:0] */
2763#define WM8962_DF1_COEFF_L0_SHIFT 0 /* DF1_COEFF_L0 - [15:0] */
2764#define WM8962_DF1_COEFF_L0_WIDTH 16 /* DF1_COEFF_L0 - [15:0] */
2765
2766/*
2767 * R258 (0x102) - DF3
2768 */
2769#define WM8962_DF1_COEFF_L1_MASK 0xFFFF /* DF1_COEFF_L1 - [15:0] */
2770#define WM8962_DF1_COEFF_L1_SHIFT 0 /* DF1_COEFF_L1 - [15:0] */
2771#define WM8962_DF1_COEFF_L1_WIDTH 16 /* DF1_COEFF_L1 - [15:0] */
2772
2773/*
2774 * R259 (0x103) - DF4
2775 */
2776#define WM8962_DF1_COEFF_L2_MASK 0xFFFF /* DF1_COEFF_L2 - [15:0] */
2777#define WM8962_DF1_COEFF_L2_SHIFT 0 /* DF1_COEFF_L2 - [15:0] */
2778#define WM8962_DF1_COEFF_L2_WIDTH 16 /* DF1_COEFF_L2 - [15:0] */
2779
2780/*
2781 * R260 (0x104) - DF5
2782 */
2783#define WM8962_DF1_COEFF_R0_MASK 0xFFFF /* DF1_COEFF_R0 - [15:0] */
2784#define WM8962_DF1_COEFF_R0_SHIFT 0 /* DF1_COEFF_R0 - [15:0] */
2785#define WM8962_DF1_COEFF_R0_WIDTH 16 /* DF1_COEFF_R0 - [15:0] */
2786
2787/*
2788 * R261 (0x105) - DF6
2789 */
2790#define WM8962_DF1_COEFF_R1_MASK 0xFFFF /* DF1_COEFF_R1 - [15:0] */
2791#define WM8962_DF1_COEFF_R1_SHIFT 0 /* DF1_COEFF_R1 - [15:0] */
2792#define WM8962_DF1_COEFF_R1_WIDTH 16 /* DF1_COEFF_R1 - [15:0] */
2793
2794/*
2795 * R262 (0x106) - DF7
2796 */
2797#define WM8962_DF1_COEFF_R2_MASK 0xFFFF /* DF1_COEFF_R2 - [15:0] */
2798#define WM8962_DF1_COEFF_R2_SHIFT 0 /* DF1_COEFF_R2 - [15:0] */
2799#define WM8962_DF1_COEFF_R2_WIDTH 16 /* DF1_COEFF_R2 - [15:0] */
2800
2801/*
2802 * R264 (0x108) - LHPF1
2803 */
2804#define WM8962_LHPF_MODE 0x0002 /* LHPF_MODE */
2805#define WM8962_LHPF_MODE_MASK 0x0002 /* LHPF_MODE */
2806#define WM8962_LHPF_MODE_SHIFT 1 /* LHPF_MODE */
2807#define WM8962_LHPF_MODE_WIDTH 1 /* LHPF_MODE */
2808#define WM8962_LHPF_ENA 0x0001 /* LHPF_ENA */
2809#define WM8962_LHPF_ENA_MASK 0x0001 /* LHPF_ENA */
2810#define WM8962_LHPF_ENA_SHIFT 0 /* LHPF_ENA */
2811#define WM8962_LHPF_ENA_WIDTH 1 /* LHPF_ENA */
2812
2813/*
2814 * R265 (0x109) - LHPF2
2815 */
2816#define WM8962_LHPF_COEFF_MASK 0xFFFF /* LHPF_COEFF - [15:0] */
2817#define WM8962_LHPF_COEFF_SHIFT 0 /* LHPF_COEFF - [15:0] */
2818#define WM8962_LHPF_COEFF_WIDTH 16 /* LHPF_COEFF - [15:0] */
2819
2820/*
2821 * R268 (0x10C) - THREED1
2822 */
2823#define WM8962_ADC_MONOMIX 0x0040 /* ADC_MONOMIX */
2824#define WM8962_ADC_MONOMIX_MASK 0x0040 /* ADC_MONOMIX */
2825#define WM8962_ADC_MONOMIX_SHIFT 6 /* ADC_MONOMIX */
2826#define WM8962_ADC_MONOMIX_WIDTH 1 /* ADC_MONOMIX */
2827#define WM8962_THREED_SIGN_L 0x0020 /* THREED_SIGN_L */
2828#define WM8962_THREED_SIGN_L_MASK 0x0020 /* THREED_SIGN_L */
2829#define WM8962_THREED_SIGN_L_SHIFT 5 /* THREED_SIGN_L */
2830#define WM8962_THREED_SIGN_L_WIDTH 1 /* THREED_SIGN_L */
2831#define WM8962_THREED_SIGN_R 0x0010 /* THREED_SIGN_R */
2832#define WM8962_THREED_SIGN_R_MASK 0x0010 /* THREED_SIGN_R */
2833#define WM8962_THREED_SIGN_R_SHIFT 4 /* THREED_SIGN_R */
2834#define WM8962_THREED_SIGN_R_WIDTH 1 /* THREED_SIGN_R */
2835#define WM8962_THREED_LHPF_MODE 0x0004 /* THREED_LHPF_MODE */
2836#define WM8962_THREED_LHPF_MODE_MASK 0x0004 /* THREED_LHPF_MODE */
2837#define WM8962_THREED_LHPF_MODE_SHIFT 2 /* THREED_LHPF_MODE */
2838#define WM8962_THREED_LHPF_MODE_WIDTH 1 /* THREED_LHPF_MODE */
2839#define WM8962_THREED_LHPF_ENA 0x0002 /* THREED_LHPF_ENA */
2840#define WM8962_THREED_LHPF_ENA_MASK 0x0002 /* THREED_LHPF_ENA */
2841#define WM8962_THREED_LHPF_ENA_SHIFT 1 /* THREED_LHPF_ENA */
2842#define WM8962_THREED_LHPF_ENA_WIDTH 1 /* THREED_LHPF_ENA */
2843#define WM8962_THREED_ENA 0x0001 /* THREED_ENA */
2844#define WM8962_THREED_ENA_MASK 0x0001 /* THREED_ENA */
2845#define WM8962_THREED_ENA_SHIFT 0 /* THREED_ENA */
2846#define WM8962_THREED_ENA_WIDTH 1 /* THREED_ENA */
2847
2848/*
2849 * R269 (0x10D) - THREED2
2850 */
2851#define WM8962_THREED_FGAINL_MASK 0xF800 /* THREED_FGAINL - [15:11] */
2852#define WM8962_THREED_FGAINL_SHIFT 11 /* THREED_FGAINL - [15:11] */
2853#define WM8962_THREED_FGAINL_WIDTH 5 /* THREED_FGAINL - [15:11] */
2854#define WM8962_THREED_CGAINL_MASK 0x07C0 /* THREED_CGAINL - [10:6] */
2855#define WM8962_THREED_CGAINL_SHIFT 6 /* THREED_CGAINL - [10:6] */
2856#define WM8962_THREED_CGAINL_WIDTH 5 /* THREED_CGAINL - [10:6] */
2857#define WM8962_THREED_DELAYL_MASK 0x003C /* THREED_DELAYL - [5:2] */
2858#define WM8962_THREED_DELAYL_SHIFT 2 /* THREED_DELAYL - [5:2] */
2859#define WM8962_THREED_DELAYL_WIDTH 4 /* THREED_DELAYL - [5:2] */
2860
2861/*
2862 * R270 (0x10E) - THREED3
2863 */
2864#define WM8962_THREED_LHPF_COEFF_MASK 0xFFFF /* THREED_LHPF_COEFF - [15:0] */
2865#define WM8962_THREED_LHPF_COEFF_SHIFT 0 /* THREED_LHPF_COEFF - [15:0] */
2866#define WM8962_THREED_LHPF_COEFF_WIDTH 16 /* THREED_LHPF_COEFF - [15:0] */
2867
2868/*
2869 * R271 (0x10F) - THREED4
2870 */
2871#define WM8962_THREED_FGAINR_MASK 0xF800 /* THREED_FGAINR - [15:11] */
2872#define WM8962_THREED_FGAINR_SHIFT 11 /* THREED_FGAINR - [15:11] */
2873#define WM8962_THREED_FGAINR_WIDTH 5 /* THREED_FGAINR - [15:11] */
2874#define WM8962_THREED_CGAINR_MASK 0x07C0 /* THREED_CGAINR - [10:6] */
2875#define WM8962_THREED_CGAINR_SHIFT 6 /* THREED_CGAINR - [10:6] */
2876#define WM8962_THREED_CGAINR_WIDTH 5 /* THREED_CGAINR - [10:6] */
2877#define WM8962_THREED_DELAYR_MASK 0x003C /* THREED_DELAYR - [5:2] */
2878#define WM8962_THREED_DELAYR_SHIFT 2 /* THREED_DELAYR - [5:2] */
2879#define WM8962_THREED_DELAYR_WIDTH 4 /* THREED_DELAYR - [5:2] */
2880
2881/*
2882 * R276 (0x114) - DRC 1
2883 */
2884#define WM8962_DRC_SIG_DET_RMS_MASK 0x7C00 /* DRC_SIG_DET_RMS - [14:10] */
2885#define WM8962_DRC_SIG_DET_RMS_SHIFT 10 /* DRC_SIG_DET_RMS - [14:10] */
2886#define WM8962_DRC_SIG_DET_RMS_WIDTH 5 /* DRC_SIG_DET_RMS - [14:10] */
2887#define WM8962_DRC_SIG_DET_PK_MASK 0x0300 /* DRC_SIG_DET_PK - [9:8] */
2888#define WM8962_DRC_SIG_DET_PK_SHIFT 8 /* DRC_SIG_DET_PK - [9:8] */
2889#define WM8962_DRC_SIG_DET_PK_WIDTH 2 /* DRC_SIG_DET_PK - [9:8] */
2890#define WM8962_DRC_NG_ENA 0x0080 /* DRC_NG_ENA */
2891#define WM8962_DRC_NG_ENA_MASK 0x0080 /* DRC_NG_ENA */
2892#define WM8962_DRC_NG_ENA_SHIFT 7 /* DRC_NG_ENA */
2893#define WM8962_DRC_NG_ENA_WIDTH 1 /* DRC_NG_ENA */
2894#define WM8962_DRC_SIG_DET_MODE 0x0040 /* DRC_SIG_DET_MODE */
2895#define WM8962_DRC_SIG_DET_MODE_MASK 0x0040 /* DRC_SIG_DET_MODE */
2896#define WM8962_DRC_SIG_DET_MODE_SHIFT 6 /* DRC_SIG_DET_MODE */
2897#define WM8962_DRC_SIG_DET_MODE_WIDTH 1 /* DRC_SIG_DET_MODE */
2898#define WM8962_DRC_SIG_DET 0x0020 /* DRC_SIG_DET */
2899#define WM8962_DRC_SIG_DET_MASK 0x0020 /* DRC_SIG_DET */
2900#define WM8962_DRC_SIG_DET_SHIFT 5 /* DRC_SIG_DET */
2901#define WM8962_DRC_SIG_DET_WIDTH 1 /* DRC_SIG_DET */
2902#define WM8962_DRC_KNEE2_OP_ENA 0x0010 /* DRC_KNEE2_OP_ENA */
2903#define WM8962_DRC_KNEE2_OP_ENA_MASK 0x0010 /* DRC_KNEE2_OP_ENA */
2904#define WM8962_DRC_KNEE2_OP_ENA_SHIFT 4 /* DRC_KNEE2_OP_ENA */
2905#define WM8962_DRC_KNEE2_OP_ENA_WIDTH 1 /* DRC_KNEE2_OP_ENA */
2906#define WM8962_DRC_QR 0x0008 /* DRC_QR */
2907#define WM8962_DRC_QR_MASK 0x0008 /* DRC_QR */
2908#define WM8962_DRC_QR_SHIFT 3 /* DRC_QR */
2909#define WM8962_DRC_QR_WIDTH 1 /* DRC_QR */
2910#define WM8962_DRC_ANTICLIP 0x0004 /* DRC_ANTICLIP */
2911#define WM8962_DRC_ANTICLIP_MASK 0x0004 /* DRC_ANTICLIP */
2912#define WM8962_DRC_ANTICLIP_SHIFT 2 /* DRC_ANTICLIP */
2913#define WM8962_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
2914#define WM8962_DRC_MODE 0x0002 /* DRC_MODE */
2915#define WM8962_DRC_MODE_MASK 0x0002 /* DRC_MODE */
2916#define WM8962_DRC_MODE_SHIFT 1 /* DRC_MODE */
2917#define WM8962_DRC_MODE_WIDTH 1 /* DRC_MODE */
2918#define WM8962_DRC_ENA 0x0001 /* DRC_ENA */
2919#define WM8962_DRC_ENA_MASK 0x0001 /* DRC_ENA */
2920#define WM8962_DRC_ENA_SHIFT 0 /* DRC_ENA */
2921#define WM8962_DRC_ENA_WIDTH 1 /* DRC_ENA */
2922
2923/*
2924 * R277 (0x115) - DRC 2
2925 */
2926#define WM8962_DRC_ATK_MASK 0x1E00 /* DRC_ATK - [12:9] */
2927#define WM8962_DRC_ATK_SHIFT 9 /* DRC_ATK - [12:9] */
2928#define WM8962_DRC_ATK_WIDTH 4 /* DRC_ATK - [12:9] */
2929#define WM8962_DRC_DCY_MASK 0x01E0 /* DRC_DCY - [8:5] */
2930#define WM8962_DRC_DCY_SHIFT 5 /* DRC_DCY - [8:5] */
2931#define WM8962_DRC_DCY_WIDTH 4 /* DRC_DCY - [8:5] */
2932#define WM8962_DRC_MINGAIN_MASK 0x001C /* DRC_MINGAIN - [4:2] */
2933#define WM8962_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [4:2] */
2934#define WM8962_DRC_MINGAIN_WIDTH 3 /* DRC_MINGAIN - [4:2] */
2935#define WM8962_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
2936#define WM8962_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
2937#define WM8962_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
2938
2939/*
2940 * R278 (0x116) - DRC 3
2941 */
2942#define WM8962_DRC_NG_MINGAIN_MASK 0xF000 /* DRC_NG_MINGAIN - [15:12] */
2943#define WM8962_DRC_NG_MINGAIN_SHIFT 12 /* DRC_NG_MINGAIN - [15:12] */
2944#define WM8962_DRC_NG_MINGAIN_WIDTH 4 /* DRC_NG_MINGAIN - [15:12] */
2945#define WM8962_DRC_QR_THR_MASK 0x0C00 /* DRC_QR_THR - [11:10] */
2946#define WM8962_DRC_QR_THR_SHIFT 10 /* DRC_QR_THR - [11:10] */
2947#define WM8962_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [11:10] */
2948#define WM8962_DRC_QR_DCY_MASK 0x0300 /* DRC_QR_DCY - [9:8] */
2949#define WM8962_DRC_QR_DCY_SHIFT 8 /* DRC_QR_DCY - [9:8] */
2950#define WM8962_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [9:8] */
2951#define WM8962_DRC_NG_EXP_MASK 0x00C0 /* DRC_NG_EXP - [7:6] */
2952#define WM8962_DRC_NG_EXP_SHIFT 6 /* DRC_NG_EXP - [7:6] */
2953#define WM8962_DRC_NG_EXP_WIDTH 2 /* DRC_NG_EXP - [7:6] */
2954#define WM8962_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
2955#define WM8962_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
2956#define WM8962_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
2957#define WM8962_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
2958#define WM8962_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
2959#define WM8962_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
2960
2961/*
2962 * R279 (0x117) - DRC 4
2963 */
2964#define WM8962_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
2965#define WM8962_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
2966#define WM8962_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
2967#define WM8962_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
2968#define WM8962_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
2969#define WM8962_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
2970
2971/*
2972 * R280 (0x118) - DRC 5
2973 */
2974#define WM8962_DRC_KNEE2_IP_MASK 0x03E0 /* DRC_KNEE2_IP - [9:5] */
2975#define WM8962_DRC_KNEE2_IP_SHIFT 5 /* DRC_KNEE2_IP - [9:5] */
2976#define WM8962_DRC_KNEE2_IP_WIDTH 5 /* DRC_KNEE2_IP - [9:5] */
2977#define WM8962_DRC_KNEE2_OP_MASK 0x001F /* DRC_KNEE2_OP - [4:0] */
2978#define WM8962_DRC_KNEE2_OP_SHIFT 0 /* DRC_KNEE2_OP - [4:0] */
2979#define WM8962_DRC_KNEE2_OP_WIDTH 5 /* DRC_KNEE2_OP - [4:0] */
2980
2981/*
2982 * R285 (0x11D) - Tloopback
2983 */
2984#define WM8962_TLB_ENA 0x0002 /* TLB_ENA */
2985#define WM8962_TLB_ENA_MASK 0x0002 /* TLB_ENA */
2986#define WM8962_TLB_ENA_SHIFT 1 /* TLB_ENA */
2987#define WM8962_TLB_ENA_WIDTH 1 /* TLB_ENA */
2988#define WM8962_TLB_MODE 0x0001 /* TLB_MODE */
2989#define WM8962_TLB_MODE_MASK 0x0001 /* TLB_MODE */
2990#define WM8962_TLB_MODE_SHIFT 0 /* TLB_MODE */
2991#define WM8962_TLB_MODE_WIDTH 1 /* TLB_MODE */
2992
2993/*
2994 * R335 (0x14F) - EQ1
2995 */
2996#define WM8962_EQ_SHARED_COEFF 0x0004 /* EQ_SHARED_COEFF */
2997#define WM8962_EQ_SHARED_COEFF_MASK 0x0004 /* EQ_SHARED_COEFF */
2998#define WM8962_EQ_SHARED_COEFF_SHIFT 2 /* EQ_SHARED_COEFF */
2999#define WM8962_EQ_SHARED_COEFF_WIDTH 1 /* EQ_SHARED_COEFF */
3000#define WM8962_EQ_SHARED_COEFF_SEL 0x0002 /* EQ_SHARED_COEFF_SEL */
3001#define WM8962_EQ_SHARED_COEFF_SEL_MASK 0x0002 /* EQ_SHARED_COEFF_SEL */
3002#define WM8962_EQ_SHARED_COEFF_SEL_SHIFT 1 /* EQ_SHARED_COEFF_SEL */
3003#define WM8962_EQ_SHARED_COEFF_SEL_WIDTH 1 /* EQ_SHARED_COEFF_SEL */
3004#define WM8962_EQ_ENA 0x0001 /* EQ_ENA */
3005#define WM8962_EQ_ENA_MASK 0x0001 /* EQ_ENA */
3006#define WM8962_EQ_ENA_SHIFT 0 /* EQ_ENA */
3007#define WM8962_EQ_ENA_WIDTH 1 /* EQ_ENA */
3008
3009/*
3010 * R336 (0x150) - EQ2
3011 */
3012#define WM8962_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */
3013#define WM8962_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */
3014#define WM8962_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */
3015#define WM8962_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */
3016#define WM8962_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */
3017#define WM8962_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */
3018#define WM8962_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */
3019#define WM8962_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */
3020#define WM8962_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */
3021
3022/*
3023 * R337 (0x151) - EQ3
3024 */
3025#define WM8962_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */
3026#define WM8962_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */
3027#define WM8962_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */
3028#define WM8962_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */
3029#define WM8962_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */
3030#define WM8962_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */
3031
3032/*
3033 * R338 (0x152) - EQ4
3034 */
3035#define WM8962_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */
3036#define WM8962_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */
3037#define WM8962_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */
3038
3039/*
3040 * R339 (0x153) - EQ5
3041 */
3042#define WM8962_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */
3043#define WM8962_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */
3044#define WM8962_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */
3045
3046/*
3047 * R340 (0x154) - EQ6
3048 */
3049#define WM8962_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */
3050#define WM8962_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */
3051#define WM8962_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */
3052
3053/*
3054 * R341 (0x155) - EQ7
3055 */
3056#define WM8962_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */
3057#define WM8962_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */
3058#define WM8962_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */
3059
3060/*
3061 * R342 (0x156) - EQ8
3062 */
3063#define WM8962_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */
3064#define WM8962_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */
3065#define WM8962_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */
3066
3067/*
3068 * R343 (0x157) - EQ9
3069 */
3070#define WM8962_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */
3071#define WM8962_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */
3072#define WM8962_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */
3073
3074/*
3075 * R344 (0x158) - EQ10
3076 */
3077#define WM8962_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */
3078#define WM8962_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */
3079#define WM8962_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */
3080
3081/*
3082 * R345 (0x159) - EQ11
3083 */
3084#define WM8962_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */
3085#define WM8962_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */
3086#define WM8962_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */
3087
3088/*
3089 * R346 (0x15A) - EQ12
3090 */
3091#define WM8962_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */
3092#define WM8962_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */
3093#define WM8962_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */
3094
3095/*
3096 * R347 (0x15B) - EQ13
3097 */
3098#define WM8962_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */
3099#define WM8962_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */
3100#define WM8962_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */
3101
3102/*
3103 * R348 (0x15C) - EQ14
3104 */
3105#define WM8962_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */
3106#define WM8962_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */
3107#define WM8962_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */
3108
3109/*
3110 * R349 (0x15D) - EQ15
3111 */
3112#define WM8962_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */
3113#define WM8962_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */
3114#define WM8962_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */
3115
3116/*
3117 * R350 (0x15E) - EQ16
3118 */
3119#define WM8962_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */
3120#define WM8962_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */
3121#define WM8962_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */
3122
3123/*
3124 * R351 (0x15F) - EQ17
3125 */
3126#define WM8962_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */
3127#define WM8962_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */
3128#define WM8962_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */
3129
3130/*
3131 * R352 (0x160) - EQ18
3132 */
3133#define WM8962_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */
3134#define WM8962_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */
3135#define WM8962_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */
3136
3137/*
3138 * R353 (0x161) - EQ19
3139 */
3140#define WM8962_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */
3141#define WM8962_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */
3142#define WM8962_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */
3143
3144/*
3145 * R354 (0x162) - EQ20
3146 */
3147#define WM8962_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */
3148#define WM8962_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */
3149#define WM8962_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */
3150
3151/*
3152 * R355 (0x163) - EQ21
3153 */
3154#define WM8962_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */
3155#define WM8962_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */
3156#define WM8962_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */
3157
3158/*
3159 * R356 (0x164) - EQ22
3160 */
3161#define WM8962_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */
3162#define WM8962_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */
3163#define WM8962_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */
3164#define WM8962_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */
3165#define WM8962_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */
3166#define WM8962_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */
3167#define WM8962_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */
3168#define WM8962_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */
3169#define WM8962_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */
3170
3171/*
3172 * R357 (0x165) - EQ23
3173 */
3174#define WM8962_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */
3175#define WM8962_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */
3176#define WM8962_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */
3177#define WM8962_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */
3178#define WM8962_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */
3179#define WM8962_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */
3180
3181/*
3182 * R358 (0x166) - EQ24
3183 */
3184#define WM8962_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */
3185#define WM8962_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */
3186#define WM8962_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */
3187
3188/*
3189 * R359 (0x167) - EQ25
3190 */
3191#define WM8962_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */
3192#define WM8962_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */
3193#define WM8962_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */
3194
3195/*
3196 * R360 (0x168) - EQ26
3197 */
3198#define WM8962_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */
3199#define WM8962_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */
3200#define WM8962_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */
3201
3202/*
3203 * R361 (0x169) - EQ27
3204 */
3205#define WM8962_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */
3206#define WM8962_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */
3207#define WM8962_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */
3208
3209/*
3210 * R362 (0x16A) - EQ28
3211 */
3212#define WM8962_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */
3213#define WM8962_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */
3214#define WM8962_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */
3215
3216/*
3217 * R363 (0x16B) - EQ29
3218 */
3219#define WM8962_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */
3220#define WM8962_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */
3221#define WM8962_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */
3222
3223/*
3224 * R364 (0x16C) - EQ30
3225 */
3226#define WM8962_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */
3227#define WM8962_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */
3228#define WM8962_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */
3229
3230/*
3231 * R365 (0x16D) - EQ31
3232 */
3233#define WM8962_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */
3234#define WM8962_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */
3235#define WM8962_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */
3236
3237/*
3238 * R366 (0x16E) - EQ32
3239 */
3240#define WM8962_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */
3241#define WM8962_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */
3242#define WM8962_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */
3243
3244/*
3245 * R367 (0x16F) - EQ33
3246 */
3247#define WM8962_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */
3248#define WM8962_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */
3249#define WM8962_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */
3250
3251/*
3252 * R368 (0x170) - EQ34
3253 */
3254#define WM8962_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */
3255#define WM8962_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */
3256#define WM8962_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */
3257
3258/*
3259 * R369 (0x171) - EQ35
3260 */
3261#define WM8962_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */
3262#define WM8962_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */
3263#define WM8962_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */
3264
3265/*
3266 * R370 (0x172) - EQ36
3267 */
3268#define WM8962_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */
3269#define WM8962_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */
3270#define WM8962_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */
3271
3272/*
3273 * R371 (0x173) - EQ37
3274 */
3275#define WM8962_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */
3276#define WM8962_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */
3277#define WM8962_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */
3278
3279/*
3280 * R372 (0x174) - EQ38
3281 */
3282#define WM8962_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */
3283#define WM8962_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */
3284#define WM8962_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */
3285
3286/*
3287 * R373 (0x175) - EQ39
3288 */
3289#define WM8962_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */
3290#define WM8962_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */
3291#define WM8962_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */
3292
3293/*
3294 * R374 (0x176) - EQ40
3295 */
3296#define WM8962_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */
3297#define WM8962_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */
3298#define WM8962_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */
3299
3300/*
3301 * R375 (0x177) - EQ41
3302 */
3303#define WM8962_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */
3304#define WM8962_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */
3305#define WM8962_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */
3306
3307/*
3308 * R513 (0x201) - GPIO 2
3309 */
3310#define WM8962_GP2_POL 0x0400 /* GP2_POL */
3311#define WM8962_GP2_POL_MASK 0x0400 /* GP2_POL */
3312#define WM8962_GP2_POL_SHIFT 10 /* GP2_POL */
3313#define WM8962_GP2_POL_WIDTH 1 /* GP2_POL */
3314#define WM8962_GP2_LVL 0x0040 /* GP2_LVL */
3315#define WM8962_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3316#define WM8962_GP2_LVL_SHIFT 6 /* GP2_LVL */
3317#define WM8962_GP2_LVL_WIDTH 1 /* GP2_LVL */
3318#define WM8962_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
3319#define WM8962_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
3320#define WM8962_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
3321
3322/*
3323 * R514 (0x202) - GPIO 3
3324 */
3325#define WM8962_GP3_POL 0x0400 /* GP3_POL */
3326#define WM8962_GP3_POL_MASK 0x0400 /* GP3_POL */
3327#define WM8962_GP3_POL_SHIFT 10 /* GP3_POL */
3328#define WM8962_GP3_POL_WIDTH 1 /* GP3_POL */
3329#define WM8962_GP3_LVL 0x0040 /* GP3_LVL */
3330#define WM8962_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3331#define WM8962_GP3_LVL_SHIFT 6 /* GP3_LVL */
3332#define WM8962_GP3_LVL_WIDTH 1 /* GP3_LVL */
3333#define WM8962_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
3334#define WM8962_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
3335#define WM8962_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
3336
3337/*
3338 * R516 (0x204) - GPIO 5
3339 */
3340#define WM8962_GP5_DIR 0x8000 /* GP5_DIR */
3341#define WM8962_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3342#define WM8962_GP5_DIR_SHIFT 15 /* GP5_DIR */
3343#define WM8962_GP5_DIR_WIDTH 1 /* GP5_DIR */
3344#define WM8962_GP5_PU 0x4000 /* GP5_PU */
3345#define WM8962_GP5_PU_MASK 0x4000 /* GP5_PU */
3346#define WM8962_GP5_PU_SHIFT 14 /* GP5_PU */
3347#define WM8962_GP5_PU_WIDTH 1 /* GP5_PU */
3348#define WM8962_GP5_PD 0x2000 /* GP5_PD */
3349#define WM8962_GP5_PD_MASK 0x2000 /* GP5_PD */
3350#define WM8962_GP5_PD_SHIFT 13 /* GP5_PD */
3351#define WM8962_GP5_PD_WIDTH 1 /* GP5_PD */
3352#define WM8962_GP5_POL 0x0400 /* GP5_POL */
3353#define WM8962_GP5_POL_MASK 0x0400 /* GP5_POL */
3354#define WM8962_GP5_POL_SHIFT 10 /* GP5_POL */
3355#define WM8962_GP5_POL_WIDTH 1 /* GP5_POL */
3356#define WM8962_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3357#define WM8962_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3358#define WM8962_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3359#define WM8962_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3360#define WM8962_GP5_DB 0x0100 /* GP5_DB */
3361#define WM8962_GP5_DB_MASK 0x0100 /* GP5_DB */
3362#define WM8962_GP5_DB_SHIFT 8 /* GP5_DB */
3363#define WM8962_GP5_DB_WIDTH 1 /* GP5_DB */
3364#define WM8962_GP5_LVL 0x0040 /* GP5_LVL */
3365#define WM8962_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3366#define WM8962_GP5_LVL_SHIFT 6 /* GP5_LVL */
3367#define WM8962_GP5_LVL_WIDTH 1 /* GP5_LVL */
3368#define WM8962_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
3369#define WM8962_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
3370#define WM8962_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
3371
3372/*
3373 * R517 (0x205) - GPIO 6
3374 */
3375#define WM8962_GP6_DIR 0x8000 /* GP6_DIR */
3376#define WM8962_GP6_DIR_MASK 0x8000 /* GP6_DIR */
3377#define WM8962_GP6_DIR_SHIFT 15 /* GP6_DIR */
3378#define WM8962_GP6_DIR_WIDTH 1 /* GP6_DIR */
3379#define WM8962_GP6_PU 0x4000 /* GP6_PU */
3380#define WM8962_GP6_PU_MASK 0x4000 /* GP6_PU */
3381#define WM8962_GP6_PU_SHIFT 14 /* GP6_PU */
3382#define WM8962_GP6_PU_WIDTH 1 /* GP6_PU */
3383#define WM8962_GP6_PD 0x2000 /* GP6_PD */
3384#define WM8962_GP6_PD_MASK 0x2000 /* GP6_PD */
3385#define WM8962_GP6_PD_SHIFT 13 /* GP6_PD */
3386#define WM8962_GP6_PD_WIDTH 1 /* GP6_PD */
3387#define WM8962_GP6_POL 0x0400 /* GP6_POL */
3388#define WM8962_GP6_POL_MASK 0x0400 /* GP6_POL */
3389#define WM8962_GP6_POL_SHIFT 10 /* GP6_POL */
3390#define WM8962_GP6_POL_WIDTH 1 /* GP6_POL */
3391#define WM8962_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
3392#define WM8962_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
3393#define WM8962_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
3394#define WM8962_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
3395#define WM8962_GP6_DB 0x0100 /* GP6_DB */
3396#define WM8962_GP6_DB_MASK 0x0100 /* GP6_DB */
3397#define WM8962_GP6_DB_SHIFT 8 /* GP6_DB */
3398#define WM8962_GP6_DB_WIDTH 1 /* GP6_DB */
3399#define WM8962_GP6_LVL 0x0040 /* GP6_LVL */
3400#define WM8962_GP6_LVL_MASK 0x0040 /* GP6_LVL */
3401#define WM8962_GP6_LVL_SHIFT 6 /* GP6_LVL */
3402#define WM8962_GP6_LVL_WIDTH 1 /* GP6_LVL */
3403#define WM8962_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
3404#define WM8962_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
3405#define WM8962_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
3406
3407/*
3408 * R560 (0x230) - Interrupt Status 1
3409 */
3410#define WM8962_GP6_EINT 0x0020 /* GP6_EINT */
3411#define WM8962_GP6_EINT_MASK 0x0020 /* GP6_EINT */
3412#define WM8962_GP6_EINT_SHIFT 5 /* GP6_EINT */
3413#define WM8962_GP6_EINT_WIDTH 1 /* GP6_EINT */
3414#define WM8962_GP5_EINT 0x0010 /* GP5_EINT */
3415#define WM8962_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3416#define WM8962_GP5_EINT_SHIFT 4 /* GP5_EINT */
3417#define WM8962_GP5_EINT_WIDTH 1 /* GP5_EINT */
3418
3419/*
3420 * R561 (0x231) - Interrupt Status 2
3421 */
3422#define WM8962_MICSCD_EINT 0x8000 /* MICSCD_EINT */
3423#define WM8962_MICSCD_EINT_MASK 0x8000 /* MICSCD_EINT */
3424#define WM8962_MICSCD_EINT_SHIFT 15 /* MICSCD_EINT */
3425#define WM8962_MICSCD_EINT_WIDTH 1 /* MICSCD_EINT */
3426#define WM8962_MICD_EINT 0x4000 /* MICD_EINT */
3427#define WM8962_MICD_EINT_MASK 0x4000 /* MICD_EINT */
3428#define WM8962_MICD_EINT_SHIFT 14 /* MICD_EINT */
3429#define WM8962_MICD_EINT_WIDTH 1 /* MICD_EINT */
3430#define WM8962_FIFOS_ERR_EINT 0x2000 /* FIFOS_ERR_EINT */
3431#define WM8962_FIFOS_ERR_EINT_MASK 0x2000 /* FIFOS_ERR_EINT */
3432#define WM8962_FIFOS_ERR_EINT_SHIFT 13 /* FIFOS_ERR_EINT */
3433#define WM8962_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3434#define WM8962_ALC_LOCK_EINT 0x1000 /* ALC_LOCK_EINT */
3435#define WM8962_ALC_LOCK_EINT_MASK 0x1000 /* ALC_LOCK_EINT */
3436#define WM8962_ALC_LOCK_EINT_SHIFT 12 /* ALC_LOCK_EINT */
3437#define WM8962_ALC_LOCK_EINT_WIDTH 1 /* ALC_LOCK_EINT */
3438#define WM8962_ALC_THRESH_EINT 0x0800 /* ALC_THRESH_EINT */
3439#define WM8962_ALC_THRESH_EINT_MASK 0x0800 /* ALC_THRESH_EINT */
3440#define WM8962_ALC_THRESH_EINT_SHIFT 11 /* ALC_THRESH_EINT */
3441#define WM8962_ALC_THRESH_EINT_WIDTH 1 /* ALC_THRESH_EINT */
3442#define WM8962_ALC_SAT_EINT 0x0400 /* ALC_SAT_EINT */
3443#define WM8962_ALC_SAT_EINT_MASK 0x0400 /* ALC_SAT_EINT */
3444#define WM8962_ALC_SAT_EINT_SHIFT 10 /* ALC_SAT_EINT */
3445#define WM8962_ALC_SAT_EINT_WIDTH 1 /* ALC_SAT_EINT */
3446#define WM8962_ALC_PKOVR_EINT 0x0200 /* ALC_PKOVR_EINT */
3447#define WM8962_ALC_PKOVR_EINT_MASK 0x0200 /* ALC_PKOVR_EINT */
3448#define WM8962_ALC_PKOVR_EINT_SHIFT 9 /* ALC_PKOVR_EINT */
3449#define WM8962_ALC_PKOVR_EINT_WIDTH 1 /* ALC_PKOVR_EINT */
3450#define WM8962_ALC_NGATE_EINT 0x0100 /* ALC_NGATE_EINT */
3451#define WM8962_ALC_NGATE_EINT_MASK 0x0100 /* ALC_NGATE_EINT */
3452#define WM8962_ALC_NGATE_EINT_SHIFT 8 /* ALC_NGATE_EINT */
3453#define WM8962_ALC_NGATE_EINT_WIDTH 1 /* ALC_NGATE_EINT */
3454#define WM8962_WSEQ_DONE_EINT 0x0080 /* WSEQ_DONE_EINT */
3455#define WM8962_WSEQ_DONE_EINT_MASK 0x0080 /* WSEQ_DONE_EINT */
3456#define WM8962_WSEQ_DONE_EINT_SHIFT 7 /* WSEQ_DONE_EINT */
3457#define WM8962_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3458#define WM8962_DRC_ACTDET_EINT 0x0040 /* DRC_ACTDET_EINT */
3459#define WM8962_DRC_ACTDET_EINT_MASK 0x0040 /* DRC_ACTDET_EINT */
3460#define WM8962_DRC_ACTDET_EINT_SHIFT 6 /* DRC_ACTDET_EINT */
3461#define WM8962_DRC_ACTDET_EINT_WIDTH 1 /* DRC_ACTDET_EINT */
3462#define WM8962_FLL_LOCK_EINT 0x0020 /* FLL_LOCK_EINT */
3463#define WM8962_FLL_LOCK_EINT_MASK 0x0020 /* FLL_LOCK_EINT */
3464#define WM8962_FLL_LOCK_EINT_SHIFT 5 /* FLL_LOCK_EINT */
3465#define WM8962_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
3466#define WM8962_PLL3_LOCK_EINT 0x0008 /* PLL3_LOCK_EINT */
3467#define WM8962_PLL3_LOCK_EINT_MASK 0x0008 /* PLL3_LOCK_EINT */
3468#define WM8962_PLL3_LOCK_EINT_SHIFT 3 /* PLL3_LOCK_EINT */
3469#define WM8962_PLL3_LOCK_EINT_WIDTH 1 /* PLL3_LOCK_EINT */
3470#define WM8962_PLL2_LOCK_EINT 0x0004 /* PLL2_LOCK_EINT */
3471#define WM8962_PLL2_LOCK_EINT_MASK 0x0004 /* PLL2_LOCK_EINT */
3472#define WM8962_PLL2_LOCK_EINT_SHIFT 2 /* PLL2_LOCK_EINT */
3473#define WM8962_PLL2_LOCK_EINT_WIDTH 1 /* PLL2_LOCK_EINT */
3474#define WM8962_TEMP_SHUT_EINT 0x0001 /* TEMP_SHUT_EINT */
3475#define WM8962_TEMP_SHUT_EINT_MASK 0x0001 /* TEMP_SHUT_EINT */
3476#define WM8962_TEMP_SHUT_EINT_SHIFT 0 /* TEMP_SHUT_EINT */
3477#define WM8962_TEMP_SHUT_EINT_WIDTH 1 /* TEMP_SHUT_EINT */
3478
3479/*
3480 * R568 (0x238) - Interrupt Status 1 Mask
3481 */
3482#define WM8962_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
3483#define WM8962_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
3484#define WM8962_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
3485#define WM8962_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
3486#define WM8962_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
3487#define WM8962_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
3488#define WM8962_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
3489#define WM8962_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
3490
3491/*
3492 * R569 (0x239) - Interrupt Status 2 Mask
3493 */
3494#define WM8962_IM_MICSCD_EINT 0x8000 /* IM_MICSCD_EINT */
3495#define WM8962_IM_MICSCD_EINT_MASK 0x8000 /* IM_MICSCD_EINT */
3496#define WM8962_IM_MICSCD_EINT_SHIFT 15 /* IM_MICSCD_EINT */
3497#define WM8962_IM_MICSCD_EINT_WIDTH 1 /* IM_MICSCD_EINT */
3498#define WM8962_IM_MICD_EINT 0x4000 /* IM_MICD_EINT */
3499#define WM8962_IM_MICD_EINT_MASK 0x4000 /* IM_MICD_EINT */
3500#define WM8962_IM_MICD_EINT_SHIFT 14 /* IM_MICD_EINT */
3501#define WM8962_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
3502#define WM8962_IM_FIFOS_ERR_EINT 0x2000 /* IM_FIFOS_ERR_EINT */
3503#define WM8962_IM_FIFOS_ERR_EINT_MASK 0x2000 /* IM_FIFOS_ERR_EINT */
3504#define WM8962_IM_FIFOS_ERR_EINT_SHIFT 13 /* IM_FIFOS_ERR_EINT */
3505#define WM8962_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
3506#define WM8962_IM_ALC_LOCK_EINT 0x1000 /* IM_ALC_LOCK_EINT */
3507#define WM8962_IM_ALC_LOCK_EINT_MASK 0x1000 /* IM_ALC_LOCK_EINT */
3508#define WM8962_IM_ALC_LOCK_EINT_SHIFT 12 /* IM_ALC_LOCK_EINT */
3509#define WM8962_IM_ALC_LOCK_EINT_WIDTH 1 /* IM_ALC_LOCK_EINT */
3510#define WM8962_IM_ALC_THRESH_EINT 0x0800 /* IM_ALC_THRESH_EINT */
3511#define WM8962_IM_ALC_THRESH_EINT_MASK 0x0800 /* IM_ALC_THRESH_EINT */
3512#define WM8962_IM_ALC_THRESH_EINT_SHIFT 11 /* IM_ALC_THRESH_EINT */
3513#define WM8962_IM_ALC_THRESH_EINT_WIDTH 1 /* IM_ALC_THRESH_EINT */
3514#define WM8962_IM_ALC_SAT_EINT 0x0400 /* IM_ALC_SAT_EINT */
3515#define WM8962_IM_ALC_SAT_EINT_MASK 0x0400 /* IM_ALC_SAT_EINT */
3516#define WM8962_IM_ALC_SAT_EINT_SHIFT 10 /* IM_ALC_SAT_EINT */
3517#define WM8962_IM_ALC_SAT_EINT_WIDTH 1 /* IM_ALC_SAT_EINT */
3518#define WM8962_IM_ALC_PKOVR_EINT 0x0200 /* IM_ALC_PKOVR_EINT */
3519#define WM8962_IM_ALC_PKOVR_EINT_MASK 0x0200 /* IM_ALC_PKOVR_EINT */
3520#define WM8962_IM_ALC_PKOVR_EINT_SHIFT 9 /* IM_ALC_PKOVR_EINT */
3521#define WM8962_IM_ALC_PKOVR_EINT_WIDTH 1 /* IM_ALC_PKOVR_EINT */
3522#define WM8962_IM_ALC_NGATE_EINT 0x0100 /* IM_ALC_NGATE_EINT */
3523#define WM8962_IM_ALC_NGATE_EINT_MASK 0x0100 /* IM_ALC_NGATE_EINT */
3524#define WM8962_IM_ALC_NGATE_EINT_SHIFT 8 /* IM_ALC_NGATE_EINT */
3525#define WM8962_IM_ALC_NGATE_EINT_WIDTH 1 /* IM_ALC_NGATE_EINT */
3526#define WM8962_IM_WSEQ_DONE_EINT 0x0080 /* IM_WSEQ_DONE_EINT */
3527#define WM8962_IM_WSEQ_DONE_EINT_MASK 0x0080 /* IM_WSEQ_DONE_EINT */
3528#define WM8962_IM_WSEQ_DONE_EINT_SHIFT 7 /* IM_WSEQ_DONE_EINT */
3529#define WM8962_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
3530#define WM8962_IM_DRC_ACTDET_EINT 0x0040 /* IM_DRC_ACTDET_EINT */
3531#define WM8962_IM_DRC_ACTDET_EINT_MASK 0x0040 /* IM_DRC_ACTDET_EINT */
3532#define WM8962_IM_DRC_ACTDET_EINT_SHIFT 6 /* IM_DRC_ACTDET_EINT */
3533#define WM8962_IM_DRC_ACTDET_EINT_WIDTH 1 /* IM_DRC_ACTDET_EINT */
3534#define WM8962_IM_FLL_LOCK_EINT 0x0020 /* IM_FLL_LOCK_EINT */
3535#define WM8962_IM_FLL_LOCK_EINT_MASK 0x0020 /* IM_FLL_LOCK_EINT */
3536#define WM8962_IM_FLL_LOCK_EINT_SHIFT 5 /* IM_FLL_LOCK_EINT */
3537#define WM8962_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
3538#define WM8962_IM_PLL3_LOCK_EINT 0x0008 /* IM_PLL3_LOCK_EINT */
3539#define WM8962_IM_PLL3_LOCK_EINT_MASK 0x0008 /* IM_PLL3_LOCK_EINT */
3540#define WM8962_IM_PLL3_LOCK_EINT_SHIFT 3 /* IM_PLL3_LOCK_EINT */
3541#define WM8962_IM_PLL3_LOCK_EINT_WIDTH 1 /* IM_PLL3_LOCK_EINT */
3542#define WM8962_IM_PLL2_LOCK_EINT 0x0004 /* IM_PLL2_LOCK_EINT */
3543#define WM8962_IM_PLL2_LOCK_EINT_MASK 0x0004 /* IM_PLL2_LOCK_EINT */
3544#define WM8962_IM_PLL2_LOCK_EINT_SHIFT 2 /* IM_PLL2_LOCK_EINT */
3545#define WM8962_IM_PLL2_LOCK_EINT_WIDTH 1 /* IM_PLL2_LOCK_EINT */
3546#define WM8962_IM_TEMP_SHUT_EINT 0x0001 /* IM_TEMP_SHUT_EINT */
3547#define WM8962_IM_TEMP_SHUT_EINT_MASK 0x0001 /* IM_TEMP_SHUT_EINT */
3548#define WM8962_IM_TEMP_SHUT_EINT_SHIFT 0 /* IM_TEMP_SHUT_EINT */
3549#define WM8962_IM_TEMP_SHUT_EINT_WIDTH 1 /* IM_TEMP_SHUT_EINT */
3550
3551/*
3552 * R576 (0x240) - Interrupt Control
3553 */
3554#define WM8962_IRQ_POL 0x0001 /* IRQ_POL */
3555#define WM8962_IRQ_POL_MASK 0x0001 /* IRQ_POL */
3556#define WM8962_IRQ_POL_SHIFT 0 /* IRQ_POL */
3557#define WM8962_IRQ_POL_WIDTH 1 /* IRQ_POL */
3558
3559/*
3560 * R584 (0x248) - IRQ Debounce
3561 */
3562#define WM8962_FLL_LOCK_DB 0x0020 /* FLL_LOCK_DB */
3563#define WM8962_FLL_LOCK_DB_MASK 0x0020 /* FLL_LOCK_DB */
3564#define WM8962_FLL_LOCK_DB_SHIFT 5 /* FLL_LOCK_DB */
3565#define WM8962_FLL_LOCK_DB_WIDTH 1 /* FLL_LOCK_DB */
3566#define WM8962_PLL3_LOCK_DB 0x0008 /* PLL3_LOCK_DB */
3567#define WM8962_PLL3_LOCK_DB_MASK 0x0008 /* PLL3_LOCK_DB */
3568#define WM8962_PLL3_LOCK_DB_SHIFT 3 /* PLL3_LOCK_DB */
3569#define WM8962_PLL3_LOCK_DB_WIDTH 1 /* PLL3_LOCK_DB */
3570#define WM8962_PLL2_LOCK_DB 0x0004 /* PLL2_LOCK_DB */
3571#define WM8962_PLL2_LOCK_DB_MASK 0x0004 /* PLL2_LOCK_DB */
3572#define WM8962_PLL2_LOCK_DB_SHIFT 2 /* PLL2_LOCK_DB */
3573#define WM8962_PLL2_LOCK_DB_WIDTH 1 /* PLL2_LOCK_DB */
3574#define WM8962_TEMP_SHUT_DB 0x0001 /* TEMP_SHUT_DB */
3575#define WM8962_TEMP_SHUT_DB_MASK 0x0001 /* TEMP_SHUT_DB */
3576#define WM8962_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
3577#define WM8962_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
3578
3579/*
3580 * R586 (0x24A) - MICINT Source Pol
3581 */
3582#define WM8962_MICSCD_IRQ_POL 0x8000 /* MICSCD_IRQ_POL */
3583#define WM8962_MICSCD_IRQ_POL_MASK 0x8000 /* MICSCD_IRQ_POL */
3584#define WM8962_MICSCD_IRQ_POL_SHIFT 15 /* MICSCD_IRQ_POL */
3585#define WM8962_MICSCD_IRQ_POL_WIDTH 1 /* MICSCD_IRQ_POL */
3586#define WM8962_MICD_IRQ_POL 0x4000 /* MICD_IRQ_POL */
3587#define WM8962_MICD_IRQ_POL_MASK 0x4000 /* MICD_IRQ_POL */
3588#define WM8962_MICD_IRQ_POL_SHIFT 14 /* MICD_IRQ_POL */
3589#define WM8962_MICD_IRQ_POL_WIDTH 1 /* MICD_IRQ_POL */
3590
3591/*
3592 * R768 (0x300) - DSP2 Power Management
3593 */
3594#define WM8962_DSP2_ENA 0x0001 /* DSP2_ENA */
3595#define WM8962_DSP2_ENA_MASK 0x0001 /* DSP2_ENA */
3596#define WM8962_DSP2_ENA_SHIFT 0 /* DSP2_ENA */
3597#define WM8962_DSP2_ENA_WIDTH 1 /* DSP2_ENA */
3598
3599/*
3600 * R1037 (0x40D) - DSP2_ExecControl
3601 */
3602#define WM8962_DSP2_STOPC 0x0020 /* DSP2_STOPC */
3603#define WM8962_DSP2_STOPC_MASK 0x0020 /* DSP2_STOPC */
3604#define WM8962_DSP2_STOPC_SHIFT 5 /* DSP2_STOPC */
3605#define WM8962_DSP2_STOPC_WIDTH 1 /* DSP2_STOPC */
3606#define WM8962_DSP2_STOPS 0x0010 /* DSP2_STOPS */
3607#define WM8962_DSP2_STOPS_MASK 0x0010 /* DSP2_STOPS */
3608#define WM8962_DSP2_STOPS_SHIFT 4 /* DSP2_STOPS */
3609#define WM8962_DSP2_STOPS_WIDTH 1 /* DSP2_STOPS */
3610#define WM8962_DSP2_STOPI 0x0008 /* DSP2_STOPI */
3611#define WM8962_DSP2_STOPI_MASK 0x0008 /* DSP2_STOPI */
3612#define WM8962_DSP2_STOPI_SHIFT 3 /* DSP2_STOPI */
3613#define WM8962_DSP2_STOPI_WIDTH 1 /* DSP2_STOPI */
3614#define WM8962_DSP2_STOP 0x0004 /* DSP2_STOP */
3615#define WM8962_DSP2_STOP_MASK 0x0004 /* DSP2_STOP */
3616#define WM8962_DSP2_STOP_SHIFT 2 /* DSP2_STOP */
3617#define WM8962_DSP2_STOP_WIDTH 1 /* DSP2_STOP */
3618#define WM8962_DSP2_RUNR 0x0002 /* DSP2_RUNR */
3619#define WM8962_DSP2_RUNR_MASK 0x0002 /* DSP2_RUNR */
3620#define WM8962_DSP2_RUNR_SHIFT 1 /* DSP2_RUNR */
3621#define WM8962_DSP2_RUNR_WIDTH 1 /* DSP2_RUNR */
3622#define WM8962_DSP2_RUN 0x0001 /* DSP2_RUN */
3623#define WM8962_DSP2_RUN_MASK 0x0001 /* DSP2_RUN */
3624#define WM8962_DSP2_RUN_SHIFT 0 /* DSP2_RUN */
3625#define WM8962_DSP2_RUN_WIDTH 1 /* DSP2_RUN */
3626
3627/*
3628 * R8192 (0x2000) - DSP2 Instruction RAM 0
3629 */
3630#define WM8962_DSP2_INSTR_RAM_1024_10_9_0_MASK 0x03FF /* DSP2_INSTR_RAM_1024_10_9_0 - [9:0] */
3631#define WM8962_DSP2_INSTR_RAM_1024_10_9_0_SHIFT 0 /* DSP2_INSTR_RAM_1024_10_9_0 - [9:0] */
3632#define WM8962_DSP2_INSTR_RAM_1024_10_9_0_WIDTH 10 /* DSP2_INSTR_RAM_1024_10_9_0 - [9:0] */
3633
3634/*
3635 * R9216 (0x2400) - DSP2 Address RAM 2
3636 */
3637#define WM8962_DSP2_ADDR_RAM_1024_38_37_32_MASK 0x003F /* DSP2_ADDR_RAM_1024_38_37_32 - [5:0] */
3638#define WM8962_DSP2_ADDR_RAM_1024_38_37_32_SHIFT 0 /* DSP2_ADDR_RAM_1024_38_37_32 - [5:0] */
3639#define WM8962_DSP2_ADDR_RAM_1024_38_37_32_WIDTH 6 /* DSP2_ADDR_RAM_1024_38_37_32 - [5:0] */
3640
3641/*
3642 * R9217 (0x2401) - DSP2 Address RAM 1
3643 */
3644#define WM8962_DSP2_ADDR_RAM_1024_38_31_16_MASK 0xFFFF /* DSP2_ADDR_RAM_1024_38_31_16 - [15:0] */
3645#define WM8962_DSP2_ADDR_RAM_1024_38_31_16_SHIFT 0 /* DSP2_ADDR_RAM_1024_38_31_16 - [15:0] */
3646#define WM8962_DSP2_ADDR_RAM_1024_38_31_16_WIDTH 16 /* DSP2_ADDR_RAM_1024_38_31_16 - [15:0] */
3647
3648/*
3649 * R9218 (0x2402) - DSP2 Address RAM 0
3650 */
3651#define WM8962_DSP2_ADDR_RAM_1024_38_15_0_MASK 0xFFFF /* DSP2_ADDR_RAM_1024_38_15_0 - [15:0] */
3652#define WM8962_DSP2_ADDR_RAM_1024_38_15_0_SHIFT 0 /* DSP2_ADDR_RAM_1024_38_15_0 - [15:0] */
3653#define WM8962_DSP2_ADDR_RAM_1024_38_15_0_WIDTH 16 /* DSP2_ADDR_RAM_1024_38_15_0 - [15:0] */
3654
3655/*
3656 * R12288 (0x3000) - DSP2 Data1 RAM 1
3657 */
3658#define WM8962_DSP2_DATA1_RAM_384_24_23_16_MASK 0x00FF /* DSP2_DATA1_RAM_384_24_23_16 - [7:0] */
3659#define WM8962_DSP2_DATA1_RAM_384_24_23_16_SHIFT 0 /* DSP2_DATA1_RAM_384_24_23_16 - [7:0] */
3660#define WM8962_DSP2_DATA1_RAM_384_24_23_16_WIDTH 8 /* DSP2_DATA1_RAM_384_24_23_16 - [7:0] */
3661
3662/*
3663 * R12289 (0x3001) - DSP2 Data1 RAM 0
3664 */
3665#define WM8962_DSP2_DATA1_RAM_384_24_15_0_MASK 0xFFFF /* DSP2_DATA1_RAM_384_24_15_0 - [15:0] */
3666#define WM8962_DSP2_DATA1_RAM_384_24_15_0_SHIFT 0 /* DSP2_DATA1_RAM_384_24_15_0 - [15:0] */
3667#define WM8962_DSP2_DATA1_RAM_384_24_15_0_WIDTH 16 /* DSP2_DATA1_RAM_384_24_15_0 - [15:0] */
3668
3669/*
3670 * R13312 (0x3400) - DSP2 Data2 RAM 1
3671 */
3672#define WM8962_DSP2_DATA2_RAM_384_24_23_16_MASK 0x00FF /* DSP2_DATA2_RAM_384_24_23_16 - [7:0] */
3673#define WM8962_DSP2_DATA2_RAM_384_24_23_16_SHIFT 0 /* DSP2_DATA2_RAM_384_24_23_16 - [7:0] */
3674#define WM8962_DSP2_DATA2_RAM_384_24_23_16_WIDTH 8 /* DSP2_DATA2_RAM_384_24_23_16 - [7:0] */
3675
3676/*
3677 * R13313 (0x3401) - DSP2 Data2 RAM 0
3678 */
3679#define WM8962_DSP2_DATA2_RAM_384_24_15_0_MASK 0xFFFF /* DSP2_DATA2_RAM_384_24_15_0 - [15:0] */
3680#define WM8962_DSP2_DATA2_RAM_384_24_15_0_SHIFT 0 /* DSP2_DATA2_RAM_384_24_15_0 - [15:0] */
3681#define WM8962_DSP2_DATA2_RAM_384_24_15_0_WIDTH 16 /* DSP2_DATA2_RAM_384_24_15_0 - [15:0] */
3682
3683/*
3684 * R14336 (0x3800) - DSP2 Data3 RAM 1
3685 */
3686#define WM8962_DSP2_DATA3_RAM_384_24_23_16_MASK 0x00FF /* DSP2_DATA3_RAM_384_24_23_16 - [7:0] */
3687#define WM8962_DSP2_DATA3_RAM_384_24_23_16_SHIFT 0 /* DSP2_DATA3_RAM_384_24_23_16 - [7:0] */
3688#define WM8962_DSP2_DATA3_RAM_384_24_23_16_WIDTH 8 /* DSP2_DATA3_RAM_384_24_23_16 - [7:0] */
3689
3690/*
3691 * R14337 (0x3801) - DSP2 Data3 RAM 0
3692 */
3693#define WM8962_DSP2_DATA3_RAM_384_24_15_0_MASK 0xFFFF /* DSP2_DATA3_RAM_384_24_15_0 - [15:0] */
3694#define WM8962_DSP2_DATA3_RAM_384_24_15_0_SHIFT 0 /* DSP2_DATA3_RAM_384_24_15_0 - [15:0] */
3695#define WM8962_DSP2_DATA3_RAM_384_24_15_0_WIDTH 16 /* DSP2_DATA3_RAM_384_24_15_0 - [15:0] */
3696
3697/*
3698 * R15360 (0x3C00) - DSP2 Coeff RAM 0
3699 */
3700#define WM8962_DSP2_CMAP_RAM_384_11_10_0_MASK 0x07FF /* DSP2_CMAP_RAM_384_11_10_0 - [10:0] */
3701#define WM8962_DSP2_CMAP_RAM_384_11_10_0_SHIFT 0 /* DSP2_CMAP_RAM_384_11_10_0 - [10:0] */
3702#define WM8962_DSP2_CMAP_RAM_384_11_10_0_WIDTH 11 /* DSP2_CMAP_RAM_384_11_10_0 - [10:0] */
3703
3704/*
3705 * R16384 (0x4000) - RETUNEADC_SHARED_COEFF_1
3706 */
3707#define WM8962_ADC_RETUNE_SCV 0x0080 /* ADC_RETUNE_SCV */
3708#define WM8962_ADC_RETUNE_SCV_MASK 0x0080 /* ADC_RETUNE_SCV */
3709#define WM8962_ADC_RETUNE_SCV_SHIFT 7 /* ADC_RETUNE_SCV */
3710#define WM8962_ADC_RETUNE_SCV_WIDTH 1 /* ADC_RETUNE_SCV */
3711#define WM8962_RETUNEADC_SHARED_COEFF_22_16_MASK 0x007F /* RETUNEADC_SHARED_COEFF_22_16 - [6:0] */
3712#define WM8962_RETUNEADC_SHARED_COEFF_22_16_SHIFT 0 /* RETUNEADC_SHARED_COEFF_22_16 - [6:0] */
3713#define WM8962_RETUNEADC_SHARED_COEFF_22_16_WIDTH 7 /* RETUNEADC_SHARED_COEFF_22_16 - [6:0] */
3714
3715/*
3716 * R16385 (0x4001) - RETUNEADC_SHARED_COEFF_0
3717 */
3718#define WM8962_RETUNEADC_SHARED_COEFF_15_00_MASK 0xFFFF /* RETUNEADC_SHARED_COEFF_15_00 - [15:0] */
3719#define WM8962_RETUNEADC_SHARED_COEFF_15_00_SHIFT 0 /* RETUNEADC_SHARED_COEFF_15_00 - [15:0] */
3720#define WM8962_RETUNEADC_SHARED_COEFF_15_00_WIDTH 16 /* RETUNEADC_SHARED_COEFF_15_00 - [15:0] */
3721
3722/*
3723 * R16386 (0x4002) - RETUNEDAC_SHARED_COEFF_1
3724 */
3725#define WM8962_DAC_RETUNE_SCV 0x0080 /* DAC_RETUNE_SCV */
3726#define WM8962_DAC_RETUNE_SCV_MASK 0x0080 /* DAC_RETUNE_SCV */
3727#define WM8962_DAC_RETUNE_SCV_SHIFT 7 /* DAC_RETUNE_SCV */
3728#define WM8962_DAC_RETUNE_SCV_WIDTH 1 /* DAC_RETUNE_SCV */
3729#define WM8962_RETUNEDAC_SHARED_COEFF_23_16_MASK 0x007F /* RETUNEDAC_SHARED_COEFF_23_16 - [6:0] */
3730#define WM8962_RETUNEDAC_SHARED_COEFF_23_16_SHIFT 0 /* RETUNEDAC_SHARED_COEFF_23_16 - [6:0] */
3731#define WM8962_RETUNEDAC_SHARED_COEFF_23_16_WIDTH 7 /* RETUNEDAC_SHARED_COEFF_23_16 - [6:0] */
3732
3733/*
3734 * R16387 (0x4003) - RETUNEDAC_SHARED_COEFF_0
3735 */
3736#define WM8962_RETUNEDAC_SHARED_COEFF_15_00_MASK 0xFFFF /* RETUNEDAC_SHARED_COEFF_15_00 - [15:0] */
3737#define WM8962_RETUNEDAC_SHARED_COEFF_15_00_SHIFT 0 /* RETUNEDAC_SHARED_COEFF_15_00 - [15:0] */
3738#define WM8962_RETUNEDAC_SHARED_COEFF_15_00_WIDTH 16 /* RETUNEDAC_SHARED_COEFF_15_00 - [15:0] */
3739
3740/*
3741 * R16388 (0x4004) - SOUNDSTAGE_ENABLES_1
3742 */
3743#define WM8962_SOUNDSTAGE_ENABLES_23_16_MASK 0x00FF /* SOUNDSTAGE_ENABLES_23_16 - [7:0] */
3744#define WM8962_SOUNDSTAGE_ENABLES_23_16_SHIFT 0 /* SOUNDSTAGE_ENABLES_23_16 - [7:0] */
3745#define WM8962_SOUNDSTAGE_ENABLES_23_16_WIDTH 8 /* SOUNDSTAGE_ENABLES_23_16 - [7:0] */
3746
3747/*
3748 * R16389 (0x4005) - SOUNDSTAGE_ENABLES_0
3749 */
3750#define WM8962_SOUNDSTAGE_ENABLES_15_06_MASK 0xFFC0 /* SOUNDSTAGE_ENABLES_15_06 - [15:6] */
3751#define WM8962_SOUNDSTAGE_ENABLES_15_06_SHIFT 6 /* SOUNDSTAGE_ENABLES_15_06 - [15:6] */
3752#define WM8962_SOUNDSTAGE_ENABLES_15_06_WIDTH 10 /* SOUNDSTAGE_ENABLES_15_06 - [15:6] */
3753#define WM8962_RTN_ADC_ENA 0x0020 /* RTN_ADC_ENA */
3754#define WM8962_RTN_ADC_ENA_MASK 0x0020 /* RTN_ADC_ENA */
3755#define WM8962_RTN_ADC_ENA_SHIFT 5 /* RTN_ADC_ENA */
3756#define WM8962_RTN_ADC_ENA_WIDTH 1 /* RTN_ADC_ENA */
3757#define WM8962_RTN_DAC_ENA 0x0010 /* RTN_DAC_ENA */
3758#define WM8962_RTN_DAC_ENA_MASK 0x0010 /* RTN_DAC_ENA */
3759#define WM8962_RTN_DAC_ENA_SHIFT 4 /* RTN_DAC_ENA */
3760#define WM8962_RTN_DAC_ENA_WIDTH 1 /* RTN_DAC_ENA */
3761#define WM8962_HDBASS_ENA 0x0008 /* HDBASS_ENA */
3762#define WM8962_HDBASS_ENA_MASK 0x0008 /* HDBASS_ENA */
3763#define WM8962_HDBASS_ENA_SHIFT 3 /* HDBASS_ENA */
3764#define WM8962_HDBASS_ENA_WIDTH 1 /* HDBASS_ENA */
3765#define WM8962_HPF2_ENA 0x0004 /* HPF2_ENA */
3766#define WM8962_HPF2_ENA_MASK 0x0004 /* HPF2_ENA */
3767#define WM8962_HPF2_ENA_SHIFT 2 /* HPF2_ENA */
3768#define WM8962_HPF2_ENA_WIDTH 1 /* HPF2_ENA */
3769#define WM8962_HPF1_ENA 0x0002 /* HPF1_ENA */
3770#define WM8962_HPF1_ENA_MASK 0x0002 /* HPF1_ENA */
3771#define WM8962_HPF1_ENA_SHIFT 1 /* HPF1_ENA */
3772#define WM8962_HPF1_ENA_WIDTH 1 /* HPF1_ENA */
3773#define WM8962_VSS_ENA 0x0001 /* VSS_ENA */
3774#define WM8962_VSS_ENA_MASK 0x0001 /* VSS_ENA */
3775#define WM8962_VSS_ENA_SHIFT 0 /* VSS_ENA */
3776#define WM8962_VSS_ENA_WIDTH 1 /* VSS_ENA */
3777
3778int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
3779
3780#endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index a99620f335d2..572bb80627a4 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -25,19 +25,17 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31#include "wm8971.h" 30#include "wm8971.h"
32 31
33#define WM8971_VERSION "0.9"
34
35#define WM8971_REG_COUNT 43 32#define WM8971_REG_COUNT 43
36 33
37static struct workqueue_struct *wm8971_workq = NULL; 34static struct workqueue_struct *wm8971_workq = NULL;
38 35
39/* codec private data */ 36/* codec private data */
40struct wm8971_priv { 37struct wm8971_priv {
38 enum snd_soc_control_type control_type;
41 unsigned int sysclk; 39 unsigned int sysclk;
42}; 40};
43 41
@@ -334,10 +332,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
334 332
335static int wm8971_add_widgets(struct snd_soc_codec *codec) 333static int wm8971_add_widgets(struct snd_soc_codec *codec)
336{ 334{
337 snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets, 335 struct snd_soc_dapm_context *dapm = &codec->dapm;
338 ARRAY_SIZE(wm8971_dapm_widgets));
339 336
340 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 337 snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
338 ARRAY_SIZE(wm8971_dapm_widgets));
339 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
341 340
342 return 0; 341 return 0;
343} 342}
@@ -492,8 +491,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
492 struct snd_soc_dai *dai) 491 struct snd_soc_dai *dai)
493{ 492{
494 struct snd_soc_pcm_runtime *rtd = substream->private_data; 493 struct snd_soc_pcm_runtime *rtd = substream->private_data;
495 struct snd_soc_device *socdev = rtd->socdev; 494 struct snd_soc_codec *codec = rtd->codec;
496 struct snd_soc_codec *codec = socdev->card->codec;
497 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); 495 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
498 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3; 496 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
499 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0; 497 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
@@ -555,7 +553,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
555 snd_soc_write(codec, WM8971_PWR1, 0x0001); 553 snd_soc_write(codec, WM8971_PWR1, 0x0001);
556 break; 554 break;
557 } 555 }
558 codec->bias_level = level; 556 codec->dapm.bias_level = level;
559 return 0; 557 return 0;
560} 558}
561 559
@@ -573,8 +571,8 @@ static struct snd_soc_dai_ops wm8971_dai_ops = {
573 .set_sysclk = wm8971_set_dai_sysclk, 571 .set_sysclk = wm8971_set_dai_sysclk,
574}; 572};
575 573
576struct snd_soc_dai wm8971_dai = { 574static struct snd_soc_dai_driver wm8971_dai = {
577 .name = "WM8971", 575 .name = "wm8971-hifi",
578 .playback = { 576 .playback = {
579 .stream_name = "Playback", 577 .stream_name = "Playback",
580 .channels_min = 1, 578 .channels_min = 1,
@@ -589,28 +587,24 @@ struct snd_soc_dai wm8971_dai = {
589 .formats = WM8971_FORMATS,}, 587 .formats = WM8971_FORMATS,},
590 .ops = &wm8971_dai_ops, 588 .ops = &wm8971_dai_ops,
591}; 589};
592EXPORT_SYMBOL_GPL(wm8971_dai);
593 590
594static void wm8971_work(struct work_struct *work) 591static void wm8971_work(struct work_struct *work)
595{ 592{
596 struct snd_soc_codec *codec = 593 struct snd_soc_dapm_context *dapm =
597 container_of(work, struct snd_soc_codec, delayed_work.work); 594 container_of(work, struct snd_soc_dapm_context,
598 wm8971_set_bias_level(codec, codec->bias_level); 595 delayed_work.work);
596 struct snd_soc_codec *codec = dapm->codec;
597 wm8971_set_bias_level(codec, codec->dapm.bias_level);
599} 598}
600 599
601static int wm8971_suspend(struct platform_device *pdev, pm_message_t state) 600static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
602{ 601{
603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
604 struct snd_soc_codec *codec = socdev->card->codec;
605
606 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); 602 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
607 return 0; 603 return 0;
608} 604}
609 605
610static int wm8971_resume(struct platform_device *pdev) 606static int wm8971_resume(struct snd_soc_codec *codec)
611{ 607{
612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
613 struct snd_soc_codec *codec = socdev->card->codec;
614 int i; 608 int i;
615 u8 data[2]; 609 u8 data[2];
616 u16 *cache = codec->reg_cache; 610 u16 *cache = codec->reg_cache;
@@ -628,54 +622,41 @@ static int wm8971_resume(struct platform_device *pdev)
628 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 622 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
629 623
630 /* charge wm8971 caps */ 624 /* charge wm8971 caps */
631 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 625 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
632 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 626 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
633 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); 627 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
634 codec->bias_level = SND_SOC_BIAS_ON; 628 codec->dapm.bias_level = SND_SOC_BIAS_ON;
635 queue_delayed_work(wm8971_workq, &codec->delayed_work, 629 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
636 msecs_to_jiffies(1000)); 630 msecs_to_jiffies(1000));
637 } 631 }
638 632
639 return 0; 633 return 0;
640} 634}
641 635
642static int wm8971_init(struct snd_soc_device *socdev, 636static int wm8971_probe(struct snd_soc_codec *codec)
643 enum snd_soc_control_type control)
644{ 637{
645 struct snd_soc_codec *codec = socdev->card->codec; 638 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
646 int reg, ret = 0; 639 int ret = 0;
647 640 u16 reg;
648 codec->name = "WM8971";
649 codec->owner = THIS_MODULE;
650 codec->set_bias_level = wm8971_set_bias_level;
651 codec->dai = &wm8971_dai;
652 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
653 codec->num_dai = 1;
654 codec->reg_cache = kmemdup(wm8971_reg, sizeof(wm8971_reg), GFP_KERNEL);
655
656 if (codec->reg_cache == NULL)
657 return -ENOMEM;
658 641
659 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 642 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type);
660 if (ret < 0) { 643 if (ret < 0) {
661 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); 644 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
662 goto err; 645 return ret;
663 } 646 }
664 647
665 wm8971_reset(codec); 648 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
649 wm8971_workq = create_workqueue("wm8971");
650 if (wm8971_workq == NULL)
651 return -ENOMEM;
666 652
667 /* register pcms */ 653 wm8971_reset(codec);
668 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
669 if (ret < 0) {
670 printk(KERN_ERR "wm8971: failed to create pcms\n");
671 goto err;
672 }
673 654
674 /* charge output caps - set vmid to 5k for quick power up */ 655 /* charge output caps - set vmid to 5k for quick power up */
675 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 656 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
676 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); 657 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
677 codec->bias_level = SND_SOC_BIAS_STANDBY; 658 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
678 queue_delayed_work(wm8971_workq, &codec->delayed_work, 659 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
679 msecs_to_jiffies(1000)); 660 msecs_to_jiffies(1000));
680 661
681 /* set the update bits */ 662 /* set the update bits */
@@ -704,40 +685,55 @@ static int wm8971_init(struct snd_soc_device *socdev,
704 wm8971_add_widgets(codec); 685 wm8971_add_widgets(codec);
705 686
706 return ret; 687 return ret;
707
708err:
709 kfree(codec->reg_cache);
710 return ret;
711} 688}
712 689
713/* If the i2c layer weren't so broken, we could pass this kind of data
714 around */
715static struct snd_soc_device *wm8971_socdev;
716 690
717#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 691/* power down chip */
692static int wm8971_remove(struct snd_soc_codec *codec)
693{
694 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
718 695
719static int wm8971_i2c_probe(struct i2c_client *i2c, 696 if (wm8971_workq)
720 const struct i2c_device_id *id) 697 destroy_workqueue(wm8971_workq);
698 return 0;
699}
700
701static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
702 .probe = wm8971_probe,
703 .remove = wm8971_remove,
704 .suspend = wm8971_suspend,
705 .resume = wm8971_resume,
706 .set_bias_level = wm8971_set_bias_level,
707 .reg_cache_size = ARRAY_SIZE(wm8971_reg),
708 .reg_word_size = sizeof(u16),
709 .reg_cache_default = wm8971_reg,
710};
711
712#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
713static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
714 const struct i2c_device_id *id)
721{ 715{
722 struct snd_soc_device *socdev = wm8971_socdev; 716 struct wm8971_priv *wm8971;
723 struct snd_soc_codec *codec = socdev->card->codec;
724 int ret; 717 int ret;
725 718
726 i2c_set_clientdata(i2c, codec); 719 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
720 if (wm8971 == NULL)
721 return -ENOMEM;
727 722
728 codec->control_data = i2c; 723 wm8971->control_type = SND_SOC_I2C;
724 i2c_set_clientdata(i2c, wm8971);
729 725
730 ret = wm8971_init(socdev, SND_SOC_I2C); 726 ret = snd_soc_register_codec(&i2c->dev,
727 &soc_codec_dev_wm8971, &wm8971_dai, 1);
731 if (ret < 0) 728 if (ret < 0)
732 pr_err("failed to initialise WM8971\n"); 729 kfree(wm8971);
733
734 return ret; 730 return ret;
735} 731}
736 732
737static int wm8971_i2c_remove(struct i2c_client *client) 733static __devexit int wm8971_i2c_remove(struct i2c_client *client)
738{ 734{
739 struct snd_soc_codec *codec = i2c_get_clientdata(client); 735 snd_soc_unregister_codec(&client->dev);
740 kfree(codec->reg_cache); 736 kfree(i2c_get_clientdata(client));
741 return 0; 737 return 0;
742} 738}
743 739
@@ -749,148 +745,34 @@ MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
749 745
750static struct i2c_driver wm8971_i2c_driver = { 746static struct i2c_driver wm8971_i2c_driver = {
751 .driver = { 747 .driver = {
752 .name = "WM8971 I2C Codec", 748 .name = "wm8971-codec",
753 .owner = THIS_MODULE, 749 .owner = THIS_MODULE,
754 }, 750 },
755 .probe = wm8971_i2c_probe, 751 .probe = wm8971_i2c_probe,
756 .remove = wm8971_i2c_remove, 752 .remove = __devexit_p(wm8971_i2c_remove),
757 .id_table = wm8971_i2c_id, 753 .id_table = wm8971_i2c_id,
758}; 754};
759
760static int wm8971_add_i2c_device(struct platform_device *pdev,
761 const struct wm8971_setup_data *setup)
762{
763 struct i2c_board_info info;
764 struct i2c_adapter *adapter;
765 struct i2c_client *client;
766 int ret;
767
768 ret = i2c_add_driver(&wm8971_i2c_driver);
769 if (ret != 0) {
770 dev_err(&pdev->dev, "can't add i2c driver\n");
771 return ret;
772 }
773
774 memset(&info, 0, sizeof(struct i2c_board_info));
775 info.addr = setup->i2c_address;
776 strlcpy(info.type, "wm8971", I2C_NAME_SIZE);
777
778 adapter = i2c_get_adapter(setup->i2c_bus);
779 if (!adapter) {
780 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
781 setup->i2c_bus);
782 goto err_driver;
783 }
784
785 client = i2c_new_device(adapter, &info);
786 i2c_put_adapter(adapter);
787 if (!client) {
788 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
789 (unsigned int)info.addr);
790 goto err_driver;
791 }
792
793 return 0;
794
795err_driver:
796 i2c_del_driver(&wm8971_i2c_driver);
797 return -ENODEV;
798}
799
800#endif 755#endif
801 756
802static int wm8971_probe(struct platform_device *pdev) 757static int __init wm8971_modinit(void)
803{ 758{
804 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
805 struct wm8971_setup_data *setup;
806 struct snd_soc_codec *codec;
807 struct wm8971_priv *wm8971;
808 int ret = 0; 759 int ret = 0;
809 760#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
810 pr_info("WM8971 Audio Codec %s", WM8971_VERSION); 761 ret = i2c_add_driver(&wm8971_i2c_driver);
811
812 setup = socdev->codec_data;
813 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
814 if (codec == NULL)
815 return -ENOMEM;
816
817 wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
818 if (wm8971 == NULL) {
819 kfree(codec);
820 return -ENOMEM;
821 }
822
823 snd_soc_codec_set_drvdata(codec, wm8971);
824 socdev->card->codec = codec;
825 mutex_init(&codec->mutex);
826 INIT_LIST_HEAD(&codec->dapm_widgets);
827 INIT_LIST_HEAD(&codec->dapm_paths);
828 wm8971_socdev = socdev;
829
830 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
831 wm8971_workq = create_workqueue("wm8971");
832 if (wm8971_workq == NULL) {
833 kfree(snd_soc_codec_get_drvdata(codec));
834 kfree(codec);
835 return -ENOMEM;
836 }
837
838#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
839 if (setup->i2c_address) {
840 ret = wm8971_add_i2c_device(pdev, setup);
841 }
842#endif
843 /* Add other interfaces here */
844
845 if (ret != 0) { 762 if (ret != 0) {
846 destroy_workqueue(wm8971_workq); 763 printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
847 kfree(snd_soc_codec_get_drvdata(codec)); 764 ret);
848 kfree(codec);
849 } 765 }
850
851 return ret;
852}
853
854/* power down chip */
855static int wm8971_remove(struct platform_device *pdev)
856{
857 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
858 struct snd_soc_codec *codec = socdev->card->codec;
859
860 if (codec->control_data)
861 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
862 if (wm8971_workq)
863 destroy_workqueue(wm8971_workq);
864 snd_soc_free_pcms(socdev);
865 snd_soc_dapm_free(socdev);
866#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
867 i2c_unregister_device(codec->control_data);
868 i2c_del_driver(&wm8971_i2c_driver);
869#endif 766#endif
870 kfree(snd_soc_codec_get_drvdata(codec)); 767 return ret;
871 kfree(codec);
872
873 return 0;
874}
875
876struct snd_soc_codec_device soc_codec_dev_wm8971 = {
877 .probe = wm8971_probe,
878 .remove = wm8971_remove,
879 .suspend = wm8971_suspend,
880 .resume = wm8971_resume,
881};
882
883EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
884
885static int __init wm8971_modinit(void)
886{
887 return snd_soc_register_dai(&wm8971_dai);
888} 768}
889module_init(wm8971_modinit); 769module_init(wm8971_modinit);
890 770
891static void __exit wm8971_exit(void) 771static void __exit wm8971_exit(void)
892{ 772{
893 snd_soc_unregister_dai(&wm8971_dai); 773#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
774 i2c_del_driver(&wm8971_i2c_driver);
775#endif
894} 776}
895module_exit(wm8971_exit); 777module_exit(wm8971_exit);
896 778
diff --git a/sound/soc/codecs/wm8971.h b/sound/soc/codecs/wm8971.h
index ef4f08f9f344..f31c38fddfc4 100644
--- a/sound/soc/codecs/wm8971.h
+++ b/sound/soc/codecs/wm8971.h
@@ -53,12 +53,4 @@
53 53
54#define WM8971_SYSCLK 0 54#define WM8971_SYSCLK 0
55 55
56struct wm8971_setup_data {
57 int i2c_bus;
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8971_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8971;
63
64#endif 56#endif
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 1468fe10cbbe..ca646a822444 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -51,12 +50,9 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
51#define WM8974_POWER1_BUFIOEN 0x04 50#define WM8974_POWER1_BUFIOEN 0x04
52 51
53struct wm8974_priv { 52struct wm8974_priv {
54 struct snd_soc_codec codec; 53 enum snd_soc_control_type control_type;
55 u16 reg_cache[WM8974_CACHEREGNUM];
56}; 54};
57 55
58static struct snd_soc_codec *wm8974_codec;
59
60#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) 56#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
61 57
62static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" }; 58static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
@@ -276,10 +272,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
276 272
277static int wm8974_add_widgets(struct snd_soc_codec *codec) 273static int wm8974_add_widgets(struct snd_soc_codec *codec)
278{ 274{
279 snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets, 275 struct snd_soc_dapm_context *dapm = &codec->dapm;
280 ARRAY_SIZE(wm8974_dapm_widgets));
281 276
282 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 277 snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets,
278 ARRAY_SIZE(wm8974_dapm_widgets));
279 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
283 280
284 return 0; 281 return 0;
285} 282}
@@ -532,7 +529,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
532 case SND_SOC_BIAS_STANDBY: 529 case SND_SOC_BIAS_STANDBY:
533 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; 530 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
534 531
535 if (codec->bias_level == SND_SOC_BIAS_OFF) { 532 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
536 /* Initial cap charge at VMID 5k */ 533 /* Initial cap charge at VMID 5k */
537 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); 534 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
538 mdelay(100); 535 mdelay(100);
@@ -549,7 +546,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
549 break; 546 break;
550 } 547 }
551 548
552 codec->bias_level = level; 549 codec->dapm.bias_level = level;
553 return 0; 550 return 0;
554} 551}
555 552
@@ -566,8 +563,8 @@ static struct snd_soc_dai_ops wm8974_ops = {
566 .set_pll = wm8974_set_dai_pll, 563 .set_pll = wm8974_set_dai_pll,
567}; 564};
568 565
569struct snd_soc_dai wm8974_dai = { 566static struct snd_soc_dai_driver wm8974_dai = {
570 .name = "WM8974 HiFi", 567 .name = "wm8974-hifi",
571 .playback = { 568 .playback = {
572 .stream_name = "Playback", 569 .stream_name = "Playback",
573 .channels_min = 1, 570 .channels_min = 1,
@@ -583,21 +580,15 @@ struct snd_soc_dai wm8974_dai = {
583 .ops = &wm8974_ops, 580 .ops = &wm8974_ops,
584 .symmetric_rates = 1, 581 .symmetric_rates = 1,
585}; 582};
586EXPORT_SYMBOL_GPL(wm8974_dai);
587 583
588static int wm8974_suspend(struct platform_device *pdev, pm_message_t state) 584static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state)
589{ 585{
590 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
591 struct snd_soc_codec *codec = socdev->card->codec;
592
593 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF); 586 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
594 return 0; 587 return 0;
595} 588}
596 589
597static int wm8974_resume(struct platform_device *pdev) 590static int wm8974_resume(struct snd_soc_codec *codec)
598{ 591{
599 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
600 struct snd_soc_codec *codec = socdev->card->codec;
601 int i; 592 int i;
602 u8 data[2]; 593 u8 data[2];
603 u16 *cache = codec->reg_cache; 594 u16 *cache = codec->reg_cache;
@@ -613,156 +604,72 @@ static int wm8974_resume(struct platform_device *pdev)
613 return 0; 604 return 0;
614} 605}
615 606
616static int wm8974_probe(struct platform_device *pdev) 607static int wm8974_probe(struct snd_soc_codec *codec)
617{ 608{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619 struct snd_soc_codec *codec;
620 int ret = 0; 609 int ret = 0;
621 610
622 if (wm8974_codec == NULL) { 611 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
623 dev_err(&pdev->dev, "Codec device not registered\n"); 612 if (ret < 0) {
624 return -ENODEV; 613 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
614 return ret;
625 } 615 }
626 616
627 socdev->card->codec = wm8974_codec; 617 ret = wm8974_reset(codec);
628 codec = wm8974_codec;
629
630 /* register pcms */
631 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
632 if (ret < 0) { 618 if (ret < 0) {
633 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 619 dev_err(codec->dev, "Failed to issue reset\n");
634 goto pcm_err; 620 return ret;
635 } 621 }
636 622
623 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
637 snd_soc_add_controls(codec, wm8974_snd_controls, 624 snd_soc_add_controls(codec, wm8974_snd_controls,
638 ARRAY_SIZE(wm8974_snd_controls)); 625 ARRAY_SIZE(wm8974_snd_controls));
639 wm8974_add_widgets(codec); 626 wm8974_add_widgets(codec);
640 627
641 return ret; 628 return ret;
642
643pcm_err:
644 return ret;
645} 629}
646 630
647/* power down chip */ 631/* power down chip */
648static int wm8974_remove(struct platform_device *pdev) 632static int wm8974_remove(struct snd_soc_codec *codec)
649{ 633{
650 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 634 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
651
652 snd_soc_free_pcms(socdev);
653 snd_soc_dapm_free(socdev);
654
655 return 0; 635 return 0;
656} 636}
657 637
658struct snd_soc_codec_device soc_codec_dev_wm8974 = { 638static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
659 .probe = wm8974_probe, 639 .probe = wm8974_probe,
660 .remove = wm8974_remove, 640 .remove = wm8974_remove,
661 .suspend = wm8974_suspend, 641 .suspend = wm8974_suspend,
662 .resume = wm8974_resume, 642 .resume = wm8974_resume,
643 .set_bias_level = wm8974_set_bias_level,
644 .reg_cache_size = ARRAY_SIZE(wm8974_reg),
645 .reg_word_size = sizeof(u16),
646 .reg_cache_default = wm8974_reg,
663}; 647};
664EXPORT_SYMBOL_GPL(soc_codec_dev_wm8974);
665
666static __devinit int wm8974_register(struct wm8974_priv *wm8974)
667{
668 int ret;
669 struct snd_soc_codec *codec = &wm8974->codec;
670
671 if (wm8974_codec) {
672 dev_err(codec->dev, "Another WM8974 is registered\n");
673 ret = -EINVAL;
674 goto err;
675 }
676
677 mutex_init(&codec->mutex);
678 INIT_LIST_HEAD(&codec->dapm_widgets);
679 INIT_LIST_HEAD(&codec->dapm_paths);
680
681 snd_soc_codec_set_drvdata(codec, wm8974);
682 codec->name = "WM8974";
683 codec->owner = THIS_MODULE;
684 codec->bias_level = SND_SOC_BIAS_OFF;
685 codec->set_bias_level = wm8974_set_bias_level;
686 codec->dai = &wm8974_dai;
687 codec->num_dai = 1;
688 codec->reg_cache_size = WM8974_CACHEREGNUM;
689 codec->reg_cache = &wm8974->reg_cache;
690
691 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
692 if (ret < 0) {
693 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
694 goto err;
695 }
696
697 memcpy(codec->reg_cache, wm8974_reg, sizeof(wm8974_reg));
698
699 ret = wm8974_reset(codec);
700 if (ret < 0) {
701 dev_err(codec->dev, "Failed to issue reset\n");
702 goto err;
703 }
704
705 wm8974_dai.dev = codec->dev;
706
707 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
708
709 wm8974_codec = codec;
710
711 ret = snd_soc_register_codec(codec);
712 if (ret != 0) {
713 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
714 goto err;
715 }
716
717 ret = snd_soc_register_dai(&wm8974_dai);
718 if (ret != 0) {
719 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
720 goto err_codec;
721 }
722
723 return 0;
724
725err_codec:
726 snd_soc_unregister_codec(codec);
727err:
728 kfree(wm8974);
729 return ret;
730}
731
732static __devexit void wm8974_unregister(struct wm8974_priv *wm8974)
733{
734 wm8974_set_bias_level(&wm8974->codec, SND_SOC_BIAS_OFF);
735 snd_soc_unregister_dai(&wm8974_dai);
736 snd_soc_unregister_codec(&wm8974->codec);
737 kfree(wm8974);
738 wm8974_codec = NULL;
739}
740 648
649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
741static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, 650static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
742 const struct i2c_device_id *id) 651 const struct i2c_device_id *id)
743{ 652{
744 struct wm8974_priv *wm8974; 653 struct wm8974_priv *wm8974;
745 struct snd_soc_codec *codec; 654 int ret;
746 655
747 wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL); 656 wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL);
748 if (wm8974 == NULL) 657 if (wm8974 == NULL)
749 return -ENOMEM; 658 return -ENOMEM;
750 659
751 codec = &wm8974->codec;
752 codec->hw_write = (hw_write_t)i2c_master_send;
753
754 i2c_set_clientdata(i2c, wm8974); 660 i2c_set_clientdata(i2c, wm8974);
755 codec->control_data = i2c;
756
757 codec->dev = &i2c->dev;
758 661
759 return wm8974_register(wm8974); 662 ret = snd_soc_register_codec(&i2c->dev,
663 &soc_codec_dev_wm8974, &wm8974_dai, 1);
664 if (ret < 0)
665 kfree(wm8974);
666 return ret;
760} 667}
761 668
762static __devexit int wm8974_i2c_remove(struct i2c_client *client) 669static __devexit int wm8974_i2c_remove(struct i2c_client *client)
763{ 670{
764 struct wm8974_priv *wm8974 = i2c_get_clientdata(client); 671 snd_soc_unregister_codec(&client->dev);
765 wm8974_unregister(wm8974); 672 kfree(i2c_get_clientdata(client));
766 return 0; 673 return 0;
767} 674}
768 675
@@ -774,23 +681,34 @@ MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
774 681
775static struct i2c_driver wm8974_i2c_driver = { 682static struct i2c_driver wm8974_i2c_driver = {
776 .driver = { 683 .driver = {
777 .name = "WM8974", 684 .name = "wm8974-codec",
778 .owner = THIS_MODULE, 685 .owner = THIS_MODULE,
779 }, 686 },
780 .probe = wm8974_i2c_probe, 687 .probe = wm8974_i2c_probe,
781 .remove = __devexit_p(wm8974_i2c_remove), 688 .remove = __devexit_p(wm8974_i2c_remove),
782 .id_table = wm8974_i2c_id, 689 .id_table = wm8974_i2c_id,
783}; 690};
691#endif
784 692
785static int __init wm8974_modinit(void) 693static int __init wm8974_modinit(void)
786{ 694{
787 return i2c_add_driver(&wm8974_i2c_driver); 695 int ret = 0;
696#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
697 ret = i2c_add_driver(&wm8974_i2c_driver);
698 if (ret != 0) {
699 printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
700 ret);
701 }
702#endif
703 return ret;
788} 704}
789module_init(wm8974_modinit); 705module_init(wm8974_modinit);
790 706
791static void __exit wm8974_exit(void) 707static void __exit wm8974_exit(void)
792{ 708{
709#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
793 i2c_del_driver(&wm8974_i2c_driver); 710 i2c_del_driver(&wm8974_i2c_driver);
711#endif
794} 712}
795module_exit(wm8974_exit); 713module_exit(wm8974_exit);
796 714
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 896a7f0f3fc4..3c94e7bb55a6 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -83,7 +83,4 @@
83#define WM8974_MCLKDIV_8 (6 << 5) 83#define WM8974_MCLKDIV_8 (6 << 5)
84#define WM8974_MCLKDIV_12 (7 << 5) 84#define WM8974_MCLKDIV_12 (7 << 5)
85 85
86extern struct snd_soc_dai wm8974_dai;
87extern struct snd_soc_codec_device soc_codec_dev_wm8974;
88
89#endif 86#endif
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 8a1ad778e7e3..85e3e630e763 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -24,15 +24,12 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <asm/div64.h> 29#include <asm/div64.h>
31 30
32#include "wm8978.h" 31#include "wm8978.h"
33 32
34static struct snd_soc_codec *wm8978_codec;
35
36/* wm8978 register cache. Note that register 0 is not included in the cache. */ 33/* wm8978 register cache. Note that register 0 is not included in the cache. */
37static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { 34static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
38 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */ 35 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
@@ -54,14 +51,14 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
54 51
55/* codec private data */ 52/* codec private data */
56struct wm8978_priv { 53struct wm8978_priv {
57 struct snd_soc_codec codec; 54 enum snd_soc_control_type control_type;
55 void *control_data;
58 unsigned int f_pllout; 56 unsigned int f_pllout;
59 unsigned int f_mclk; 57 unsigned int f_mclk;
60 unsigned int f_256fs; 58 unsigned int f_256fs;
61 unsigned int f_opclk; 59 unsigned int f_opclk;
62 int mclk_idx; 60 int mclk_idx;
63 enum wm8978_sysclk_src sysclk; 61 enum wm8978_sysclk_src sysclk;
64 u16 reg_cache[WM8978_CACHEREGNUM];
65}; 62};
66 63
67static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"}; 64static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
@@ -96,6 +93,7 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
96static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0); 93static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
97static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0); 94static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
98static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1); 95static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
96static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);
99 97
100static const struct snd_kcontrol_new wm8978_snd_controls[] = { 98static const struct snd_kcontrol_new wm8978_snd_controls[] = {
101 99
@@ -147,19 +145,19 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
147 145
148 SOC_SINGLE("DAC Playback Limiter Threshold", 146 SOC_SINGLE("DAC Playback Limiter Threshold",
149 WM8978_DAC_LIMITER_2, 4, 7, 0), 147 WM8978_DAC_LIMITER_2, 4, 7, 0),
150 SOC_SINGLE("DAC Playback Limiter Boost", 148 SOC_SINGLE_TLV("DAC Playback Limiter Volume",
151 WM8978_DAC_LIMITER_2, 0, 15, 0), 149 WM8978_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),
152 150
153 SOC_ENUM("ALC Enable Switch", alc1), 151 SOC_ENUM("ALC Enable Switch", alc1),
154 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0), 152 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
155 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0), 153 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
156 154
157 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0), 155 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 10, 0),
158 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0), 156 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
159 157
160 SOC_ENUM("ALC Capture Mode", alc3), 158 SOC_ENUM("ALC Capture Mode", alc3),
161 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0), 159 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 10, 0),
162 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0), 160 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 10, 0),
163 161
164 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0), 162 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
165 SOC_SINGLE("ALC Capture Noise Gate Threshold", 163 SOC_SINGLE("ALC Capture Noise Gate Threshold",
@@ -214,8 +212,10 @@ static const struct snd_kcontrol_new wm8978_snd_controls[] = {
214 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1), 212 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
215 213
216 /* DAC / ADC oversampling */ 214 /* DAC / ADC oversampling */
217 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0), 215 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL,
218 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0), 216 5, 1, 0),
217 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL,
218 5, 1, 0),
219}; 219};
220 220
221/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */ 221/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
@@ -356,11 +356,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
356 356
357static int wm8978_add_widgets(struct snd_soc_codec *codec) 357static int wm8978_add_widgets(struct snd_soc_codec *codec)
358{ 358{
359 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets, 359 struct snd_soc_dapm_context *dapm = &codec->dapm;
360 ARRAY_SIZE(wm8978_dapm_widgets));
361 360
361 snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
362 ARRAY_SIZE(wm8978_dapm_widgets));
362 /* set up the WM8978 audio map */ 363 /* set up the WM8978 audio map */
363 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 364 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
364 365
365 return 0; 366 return 0;
366} 367}
@@ -374,8 +375,8 @@ struct wm8978_pll_div {
374 375
375#define FIXED_PLL_SIZE (1 << 24) 376#define FIXED_PLL_SIZE (1 << 24)
376 377
377static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target, 378static void pll_factors(struct snd_soc_codec *codec,
378 unsigned int source) 379 struct wm8978_pll_div *pll_div, unsigned int target, unsigned int source)
379{ 380{
380 u64 k_part; 381 u64 k_part;
381 unsigned int k, n_div, n_mod; 382 unsigned int k, n_div, n_mod;
@@ -390,7 +391,7 @@ static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
390 } 391 }
391 392
392 if (n_div < 6 || n_div > 12) 393 if (n_div < 6 || n_div > 12)
393 dev_warn(wm8978_codec->dev, 394 dev_warn(codec->dev,
394 "WM8978 N value exceeds recommended range! N = %u\n", 395 "WM8978 N value exceeds recommended range! N = %u\n",
395 n_div); 396 n_div);
396 397
@@ -505,7 +506,7 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec)
505 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__, 506 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
506 wm8978->f_mclk, wm8978->f_pllout); 507 wm8978->f_mclk, wm8978->f_pllout);
507 508
508 pll_factors(&pll_div, f2, wm8978->f_mclk); 509 pll_factors(codec, &pll_div, f2, wm8978->f_mclk);
509 510
510 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n", 511 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
511 __func__, pll_div.n, pll_div.k, pll_div.div2); 512 __func__, pll_div.n, pll_div.k, pll_div.div2);
@@ -690,8 +691,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
690 struct snd_soc_dai *dai) 691 struct snd_soc_dai *dai)
691{ 692{
692 struct snd_soc_pcm_runtime *rtd = substream->private_data; 693 struct snd_soc_pcm_runtime *rtd = substream->private_data;
693 struct snd_soc_device *socdev = rtd->socdev; 694 struct snd_soc_codec *codec = rtd->codec;
694 struct snd_soc_codec *codec = socdev->card->codec;
695 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 695 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
696 /* Word length mask = 0x60 */ 696 /* Word length mask = 0x60 */
697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60; 697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
@@ -839,7 +839,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
839 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */ 839 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
840 power1 |= 0xc; 840 power1 |= 0xc;
841 841
842 if (codec->bias_level == SND_SOC_BIAS_OFF) { 842 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
843 /* Initial cap charge at VMID 5k */ 843 /* Initial cap charge at VMID 5k */
844 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 844 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
845 power1 | 0x3); 845 power1 | 0x3);
@@ -859,7 +859,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
859 859
860 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1); 860 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
861 861
862 codec->bias_level = level; 862 codec->dapm.bias_level = level;
863 return 0; 863 return 0;
864} 864}
865 865
@@ -875,9 +875,8 @@ static struct snd_soc_dai_ops wm8978_dai_ops = {
875}; 875};
876 876
877/* Also supports 12kHz */ 877/* Also supports 12kHz */
878struct snd_soc_dai wm8978_dai = { 878static struct snd_soc_dai_driver wm8978_dai = {
879 .name = "WM8978 HiFi", 879 .name = "wm8978-hifi",
880 .id = 1,
881 .playback = { 880 .playback = {
882 .stream_name = "Playback", 881 .stream_name = "Playback",
883 .channels_min = 1, 882 .channels_min = 1,
@@ -894,13 +893,9 @@ struct snd_soc_dai wm8978_dai = {
894 }, 893 },
895 .ops = &wm8978_dai_ops, 894 .ops = &wm8978_dai_ops,
896}; 895};
897EXPORT_SYMBOL_GPL(wm8978_dai);
898 896
899static int wm8978_suspend(struct platform_device *pdev, pm_message_t state) 897static int wm8978_suspend(struct snd_soc_codec *codec, pm_message_t state)
900{ 898{
901 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
902 struct snd_soc_codec *codec = socdev->card->codec;
903
904 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); 899 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
905 /* Also switch PLL off */ 900 /* Also switch PLL off */
906 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0); 901 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
@@ -908,10 +903,8 @@ static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
908 return 0; 903 return 0;
909} 904}
910 905
911static int wm8978_resume(struct platform_device *pdev) 906static int wm8978_resume(struct snd_soc_codec *codec)
912{ 907{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec = socdev->card->codec;
915 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 908 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
916 int i; 909 int i;
917 u16 *cache = codec->reg_cache; 910 u16 *cache = codec->reg_cache;
@@ -933,54 +926,6 @@ static int wm8978_resume(struct platform_device *pdev)
933 return 0; 926 return 0;
934} 927}
935 928
936static int wm8978_probe(struct platform_device *pdev)
937{
938 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
939 struct snd_soc_codec *codec;
940 int ret = 0;
941
942 if (wm8978_codec == NULL) {
943 dev_err(&pdev->dev, "Codec device not registered\n");
944 return -ENODEV;
945 }
946
947 socdev->card->codec = wm8978_codec;
948 codec = wm8978_codec;
949
950 /* register pcms */
951 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
952 if (ret < 0) {
953 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
954 goto pcm_err;
955 }
956
957 snd_soc_add_controls(codec, wm8978_snd_controls,
958 ARRAY_SIZE(wm8978_snd_controls));
959 wm8978_add_widgets(codec);
960
961pcm_err:
962 return ret;
963}
964
965/* power down chip */
966static int wm8978_remove(struct platform_device *pdev)
967{
968 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
969
970 snd_soc_free_pcms(socdev);
971 snd_soc_dapm_free(socdev);
972
973 return 0;
974}
975
976struct snd_soc_codec_device soc_codec_dev_wm8978 = {
977 .probe = wm8978_probe,
978 .remove = wm8978_remove,
979 .suspend = wm8978_suspend,
980 .resume = wm8978_resume,
981};
982EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
983
984/* 929/*
985 * These registers contain an "update" bit - bit 8. This means, for example, 930 * These registers contain an "update" bit - bit 8. This means, for example,
986 * that one can write new DAC digital volume for both channels, but only when 931 * that one can write new DAC digital volume for both channels, but only when
@@ -1000,124 +945,90 @@ static const int update_reg[] = {
1000 WM8978_ROUT2_SPK_CONTROL, 945 WM8978_ROUT2_SPK_CONTROL,
1001}; 946};
1002 947
1003static __devinit int wm8978_register(struct wm8978_priv *wm8978) 948static int wm8978_probe(struct snd_soc_codec *codec)
1004{ 949{
1005 int ret, i; 950 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
1006 struct snd_soc_codec *codec = &wm8978->codec; 951 int ret = 0, i;
1007
1008 if (wm8978_codec) {
1009 dev_err(codec->dev, "Another WM8978 is registered\n");
1010 return -EINVAL;
1011 }
1012 952
1013 /* 953 /*
1014 * Set default system clock to PLL, it is more precise, this is also the 954 * Set default system clock to PLL, it is more precise, this is also the
1015 * default hardware setting 955 * default hardware setting
1016 */ 956 */
1017 wm8978->sysclk = WM8978_PLL; 957 wm8978->sysclk = WM8978_PLL;
1018 958 codec->control_data = wm8978->control_data;
1019 mutex_init(&codec->mutex);
1020 INIT_LIST_HEAD(&codec->dapm_widgets);
1021 INIT_LIST_HEAD(&codec->dapm_paths);
1022
1023 snd_soc_codec_set_drvdata(codec, wm8978);
1024 codec->name = "WM8978";
1025 codec->owner = THIS_MODULE;
1026 codec->bias_level = SND_SOC_BIAS_OFF;
1027 codec->set_bias_level = wm8978_set_bias_level;
1028 codec->dai = &wm8978_dai;
1029 codec->num_dai = 1;
1030 codec->reg_cache_size = WM8978_CACHEREGNUM;
1031 codec->reg_cache = &wm8978->reg_cache;
1032
1033 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); 959 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1034 if (ret < 0) { 960 if (ret < 0) {
1035 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 961 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1036 goto err; 962 return ret;
1037 } 963 }
1038 964
1039 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1040
1041 /* 965 /*
1042 * Set the update bit in all registers, that have one. This way all 966 * Set the update bit in all registers, that have one. This way all
1043 * writes to those registers will also cause the update bit to be 967 * writes to those registers will also cause the update bit to be
1044 * written. 968 * written.
1045 */ 969 */
1046 for (i = 0; i < ARRAY_SIZE(update_reg); i++) 970 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
1047 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100; 971 snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
1048 972
1049 /* Reset the codec */ 973 /* Reset the codec */
1050 ret = snd_soc_write(codec, WM8978_RESET, 0); 974 ret = snd_soc_write(codec, WM8978_RESET, 0);
1051 if (ret < 0) { 975 if (ret < 0) {
1052 dev_err(codec->dev, "Failed to issue reset\n"); 976 dev_err(codec->dev, "Failed to issue reset\n");
1053 goto err; 977 return ret;
1054 } 978 }
1055 979
1056 wm8978_dai.dev = codec->dev;
1057
1058 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 980 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1059 981
1060 wm8978_codec = codec; 982 snd_soc_add_controls(codec, wm8978_snd_controls,
1061 983 ARRAY_SIZE(wm8978_snd_controls));
1062 ret = snd_soc_register_codec(codec); 984 wm8978_add_widgets(codec);
1063 if (ret != 0) {
1064 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1065 goto err;
1066 }
1067
1068 ret = snd_soc_register_dai(&wm8978_dai);
1069 if (ret != 0) {
1070 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1071 goto err_codec;
1072 }
1073 985
1074 return 0; 986 return 0;
1075
1076err_codec:
1077 snd_soc_unregister_codec(codec);
1078err:
1079 return ret;
1080} 987}
1081 988
1082static __devexit void wm8978_unregister(struct wm8978_priv *wm8978) 989/* power down chip */
990static int wm8978_remove(struct snd_soc_codec *codec)
1083{ 991{
1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF); 992 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
1085 snd_soc_unregister_dai(&wm8978_dai); 993 return 0;
1086 snd_soc_unregister_codec(&wm8978->codec);
1087 wm8978_codec = NULL;
1088} 994}
1089 995
996static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
997 .probe = wm8978_probe,
998 .remove = wm8978_remove,
999 .suspend = wm8978_suspend,
1000 .resume = wm8978_resume,
1001 .set_bias_level = wm8978_set_bias_level,
1002 .reg_cache_size = ARRAY_SIZE(wm8978_reg),
1003 .reg_word_size = sizeof(u16),
1004 .reg_cache_default = wm8978_reg,
1005};
1006
1007#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1090static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, 1008static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1091 const struct i2c_device_id *id) 1009 const struct i2c_device_id *id)
1092{ 1010{
1093 int ret;
1094 struct wm8978_priv *wm8978; 1011 struct wm8978_priv *wm8978;
1095 struct snd_soc_codec *codec; 1012 int ret;
1096 1013
1097 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL); 1014 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1098 if (wm8978 == NULL) 1015 if (wm8978 == NULL)
1099 return -ENOMEM; 1016 return -ENOMEM;
1100 1017
1101 codec = &wm8978->codec;
1102 codec->hw_write = (hw_write_t)i2c_master_send;
1103
1104 i2c_set_clientdata(i2c, wm8978); 1018 i2c_set_clientdata(i2c, wm8978);
1105 codec->control_data = i2c; 1019 wm8978->control_data = i2c;
1106
1107 codec->dev = &i2c->dev;
1108 1020
1109 ret = wm8978_register(wm8978); 1021 ret = snd_soc_register_codec(&i2c->dev,
1022 &soc_codec_dev_wm8978, &wm8978_dai, 1);
1110 if (ret < 0) 1023 if (ret < 0)
1111 kfree(wm8978); 1024 kfree(wm8978);
1112
1113 return ret; 1025 return ret;
1114} 1026}
1115 1027
1116static __devexit int wm8978_i2c_remove(struct i2c_client *client) 1028static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1117{ 1029{
1118 struct wm8978_priv *wm8978 = i2c_get_clientdata(client); 1030 snd_soc_unregister_codec(&client->dev);
1119 wm8978_unregister(wm8978); 1031 kfree(i2c_get_clientdata(client));
1120 kfree(wm8978);
1121 return 0; 1032 return 0;
1122} 1033}
1123 1034
@@ -1129,23 +1040,34 @@ MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1129 1040
1130static struct i2c_driver wm8978_i2c_driver = { 1041static struct i2c_driver wm8978_i2c_driver = {
1131 .driver = { 1042 .driver = {
1132 .name = "WM8978", 1043 .name = "wm8978",
1133 .owner = THIS_MODULE, 1044 .owner = THIS_MODULE,
1134 }, 1045 },
1135 .probe = wm8978_i2c_probe, 1046 .probe = wm8978_i2c_probe,
1136 .remove = __devexit_p(wm8978_i2c_remove), 1047 .remove = __devexit_p(wm8978_i2c_remove),
1137 .id_table = wm8978_i2c_id, 1048 .id_table = wm8978_i2c_id,
1138}; 1049};
1050#endif
1139 1051
1140static int __init wm8978_modinit(void) 1052static int __init wm8978_modinit(void)
1141{ 1053{
1142 return i2c_add_driver(&wm8978_i2c_driver); 1054 int ret = 0;
1055#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1056 ret = i2c_add_driver(&wm8978_i2c_driver);
1057 if (ret != 0) {
1058 printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
1059 ret);
1060 }
1061#endif
1062 return ret;
1143} 1063}
1144module_init(wm8978_modinit); 1064module_init(wm8978_modinit);
1145 1065
1146static void __exit wm8978_exit(void) 1066static void __exit wm8978_exit(void)
1147{ 1067{
1068#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1148 i2c_del_driver(&wm8978_i2c_driver); 1069 i2c_del_driver(&wm8978_i2c_driver);
1070#endif
1149} 1071}
1150module_exit(wm8978_exit); 1072module_exit(wm8978_exit);
1151 1073
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
index 56ec83270917..c75525b7f154 100644
--- a/sound/soc/codecs/wm8978.h
+++ b/sound/soc/codecs/wm8978.h
@@ -80,7 +80,4 @@ enum wm8978_sysclk_src {
80 WM8978_MCLK 80 WM8978_MCLK
81}; 81};
82 82
83extern struct snd_soc_dai wm8978_dai;
84extern struct snd_soc_codec_device soc_codec_dev_wm8978;
85
86#endif /* __WM8978_H__ */ 83#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
new file mode 100644
index 000000000000..bae510acdec8
--- /dev/null
+++ b/sound/soc/codecs/wm8985.c
@@ -0,0 +1,1192 @@
1/*
2 * wm8985.c -- WM8985 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * TODO:
13 * o Add OUT3/OUT4 mixer controls.
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/i2c.h>
22#include <linux/regulator/consumer.h>
23#include <linux/spi/spi.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31
32#include "wm8985.h"
33
34#define WM8985_NUM_SUPPLIES 4
35static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
36 "DCVDD",
37 "DBVDD",
38 "AVDD1",
39 "AVDD2"
40};
41
42static const u16 wm8985_reg_defs[] = {
43 0x0000, /* R0 - Software Reset */
44 0x0000, /* R1 - Power management 1 */
45 0x0000, /* R2 - Power management 2 */
46 0x0000, /* R3 - Power management 3 */
47 0x0050, /* R4 - Audio Interface */
48 0x0000, /* R5 - Companding control */
49 0x0140, /* R6 - Clock Gen control */
50 0x0000, /* R7 - Additional control */
51 0x0000, /* R8 - GPIO Control */
52 0x0000, /* R9 - Jack Detect Control 1 */
53 0x0000, /* R10 - DAC Control */
54 0x00FF, /* R11 - Left DAC digital Vol */
55 0x00FF, /* R12 - Right DAC digital vol */
56 0x0000, /* R13 - Jack Detect Control 2 */
57 0x0100, /* R14 - ADC Control */
58 0x00FF, /* R15 - Left ADC Digital Vol */
59 0x00FF, /* R16 - Right ADC Digital Vol */
60 0x0000, /* R17 */
61 0x012C, /* R18 - EQ1 - low shelf */
62 0x002C, /* R19 - EQ2 - peak 1 */
63 0x002C, /* R20 - EQ3 - peak 2 */
64 0x002C, /* R21 - EQ4 - peak 3 */
65 0x002C, /* R22 - EQ5 - high shelf */
66 0x0000, /* R23 */
67 0x0032, /* R24 - DAC Limiter 1 */
68 0x0000, /* R25 - DAC Limiter 2 */
69 0x0000, /* R26 */
70 0x0000, /* R27 - Notch Filter 1 */
71 0x0000, /* R28 - Notch Filter 2 */
72 0x0000, /* R29 - Notch Filter 3 */
73 0x0000, /* R30 - Notch Filter 4 */
74 0x0000, /* R31 */
75 0x0038, /* R32 - ALC control 1 */
76 0x000B, /* R33 - ALC control 2 */
77 0x0032, /* R34 - ALC control 3 */
78 0x0000, /* R35 - Noise Gate */
79 0x0008, /* R36 - PLL N */
80 0x000C, /* R37 - PLL K 1 */
81 0x0093, /* R38 - PLL K 2 */
82 0x00E9, /* R39 - PLL K 3 */
83 0x0000, /* R40 */
84 0x0000, /* R41 - 3D control */
85 0x0000, /* R42 - OUT4 to ADC */
86 0x0000, /* R43 - Beep control */
87 0x0033, /* R44 - Input ctrl */
88 0x0010, /* R45 - Left INP PGA gain ctrl */
89 0x0010, /* R46 - Right INP PGA gain ctrl */
90 0x0100, /* R47 - Left ADC BOOST ctrl */
91 0x0100, /* R48 - Right ADC BOOST ctrl */
92 0x0002, /* R49 - Output ctrl */
93 0x0001, /* R50 - Left mixer ctrl */
94 0x0001, /* R51 - Right mixer ctrl */
95 0x0039, /* R52 - LOUT1 (HP) volume ctrl */
96 0x0039, /* R53 - ROUT1 (HP) volume ctrl */
97 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */
98 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */
99 0x0001, /* R56 - OUT3 mixer ctrl */
100 0x0001, /* R57 - OUT4 (MONO) mix ctrl */
101 0x0001, /* R58 */
102 0x0000, /* R59 */
103 0x0004, /* R60 - OUTPUT ctrl */
104 0x0000, /* R61 - BIAS CTRL */
105 0x0180, /* R62 */
106 0x0000 /* R63 */
107};
108
109/*
110 * latch bit 8 of these registers to ensure instant
111 * volume updates
112 */
113static const int volume_update_regs[] = {
114 WM8985_LEFT_DAC_DIGITAL_VOL,
115 WM8985_RIGHT_DAC_DIGITAL_VOL,
116 WM8985_LEFT_ADC_DIGITAL_VOL,
117 WM8985_RIGHT_ADC_DIGITAL_VOL,
118 WM8985_LOUT2_SPK_VOLUME_CTRL,
119 WM8985_ROUT2_SPK_VOLUME_CTRL,
120 WM8985_LOUT1_HP_VOLUME_CTRL,
121 WM8985_ROUT1_HP_VOLUME_CTRL,
122 WM8985_LEFT_INP_PGA_GAIN_CTRL,
123 WM8985_RIGHT_INP_PGA_GAIN_CTRL
124};
125
126struct wm8985_priv {
127 enum snd_soc_control_type control_type;
128 struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES];
129 unsigned int sysclk;
130 unsigned int bclk;
131};
132
133static const struct {
134 int div;
135 int ratio;
136} fs_ratios[] = {
137 { 10, 128 },
138 { 15, 192 },
139 { 20, 256 },
140 { 30, 384 },
141 { 40, 512 },
142 { 60, 768 },
143 { 80, 1024 },
144 { 120, 1536 }
145};
146
147static const int srates[] = { 48000, 32000, 24000, 16000, 12000, 8000 };
148
149static const int bclk_divs[] = {
150 1, 2, 4, 8, 16, 32
151};
152
153static int eqmode_get(struct snd_kcontrol *kcontrol,
154 struct snd_ctl_elem_value *ucontrol);
155static int eqmode_put(struct snd_kcontrol *kcontrol,
156 struct snd_ctl_elem_value *ucontrol);
157
158static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
159static const DECLARE_TLV_DB_SCALE(adc_tlv, -12700, 50, 1);
160static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
161static const DECLARE_TLV_DB_SCALE(lim_thresh_tlv, -600, 100, 0);
162static const DECLARE_TLV_DB_SCALE(lim_boost_tlv, 0, 100, 0);
163static const DECLARE_TLV_DB_SCALE(alc_min_tlv, -1200, 600, 0);
164static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -675, 600, 0);
165static const DECLARE_TLV_DB_SCALE(alc_tar_tlv, -2250, 150, 0);
166static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1200, 75, 0);
167static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1);
168static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
169static const DECLARE_TLV_DB_SCALE(aux_tlv, -1500, 300, 0);
170static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
171static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);
172
173static const char *alc_sel_text[] = { "Off", "Right", "Left", "Stereo" };
174static const SOC_ENUM_SINGLE_DECL(alc_sel, WM8985_ALC_CONTROL_1, 7,
175 alc_sel_text);
176
177static const char *alc_mode_text[] = { "ALC", "Limiter" };
178static const SOC_ENUM_SINGLE_DECL(alc_mode, WM8985_ALC_CONTROL_3, 8,
179 alc_mode_text);
180
181static const char *filter_mode_text[] = { "Audio", "Application" };
182static const SOC_ENUM_SINGLE_DECL(filter_mode, WM8985_ADC_CONTROL, 7,
183 filter_mode_text);
184
185static const char *eq_bw_text[] = { "Narrow", "Wide" };
186static const char *eqmode_text[] = { "Capture", "Playback" };
187static const SOC_ENUM_SINGLE_EXT_DECL(eqmode, eqmode_text);
188
189static const char *eq1_cutoff_text[] = {
190 "80Hz", "105Hz", "135Hz", "175Hz"
191};
192static const SOC_ENUM_SINGLE_DECL(eq1_cutoff, WM8985_EQ1_LOW_SHELF, 5,
193 eq1_cutoff_text);
194static const char *eq2_cutoff_text[] = {
195 "230Hz", "300Hz", "385Hz", "500Hz"
196};
197static const SOC_ENUM_SINGLE_DECL(eq2_bw, WM8985_EQ2_PEAK_1, 8, eq_bw_text);
198static const SOC_ENUM_SINGLE_DECL(eq2_cutoff, WM8985_EQ2_PEAK_1, 5,
199 eq2_cutoff_text);
200static const char *eq3_cutoff_text[] = {
201 "650Hz", "850Hz", "1.1kHz", "1.4kHz"
202};
203static const SOC_ENUM_SINGLE_DECL(eq3_bw, WM8985_EQ3_PEAK_2, 8, eq_bw_text);
204static const SOC_ENUM_SINGLE_DECL(eq3_cutoff, WM8985_EQ3_PEAK_2, 5,
205 eq3_cutoff_text);
206static const char *eq4_cutoff_text[] = {
207 "1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"
208};
209static const SOC_ENUM_SINGLE_DECL(eq4_bw, WM8985_EQ4_PEAK_3, 8, eq_bw_text);
210static const SOC_ENUM_SINGLE_DECL(eq4_cutoff, WM8985_EQ4_PEAK_3, 5,
211 eq4_cutoff_text);
212static const char *eq5_cutoff_text[] = {
213 "5.3kHz", "6.9kHz", "9kHz", "11.7kHz"
214};
215static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8985_EQ5_HIGH_SHELF, 5,
216 eq5_cutoff_text);
217
218static const char *speaker_mode_text[] = { "Class A/B", "Class D" };
219static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text);
220
221static const char *depth_3d_text[] = {
222 "Off",
223 "6.67%",
224 "13.3%",
225 "20%",
226 "26.7%",
227 "33.3%",
228 "40%",
229 "46.6%",
230 "53.3%",
231 "60%",
232 "66.7%",
233 "73.3%",
234 "80%",
235 "86.7%",
236 "93.3%",
237 "100%"
238};
239static const SOC_ENUM_SINGLE_DECL(depth_3d, WM8985_3D_CONTROL, 0,
240 depth_3d_text);
241
242static const struct snd_kcontrol_new wm8985_snd_controls[] = {
243 SOC_SINGLE("Digital Loopback Switch", WM8985_COMPANDING_CONTROL,
244 0, 1, 0),
245
246 SOC_ENUM("ALC Capture Function", alc_sel),
247 SOC_SINGLE_TLV("ALC Capture Max Volume", WM8985_ALC_CONTROL_1,
248 3, 7, 0, alc_max_tlv),
249 SOC_SINGLE_TLV("ALC Capture Min Volume", WM8985_ALC_CONTROL_1,
250 0, 7, 0, alc_min_tlv),
251 SOC_SINGLE_TLV("ALC Capture Target Volume", WM8985_ALC_CONTROL_2,
252 0, 15, 0, alc_tar_tlv),
253 SOC_SINGLE("ALC Capture Attack", WM8985_ALC_CONTROL_3, 0, 10, 0),
254 SOC_SINGLE("ALC Capture Hold", WM8985_ALC_CONTROL_2, 4, 10, 0),
255 SOC_SINGLE("ALC Capture Decay", WM8985_ALC_CONTROL_3, 4, 10, 0),
256 SOC_ENUM("ALC Mode", alc_mode),
257 SOC_SINGLE("ALC Capture NG Switch", WM8985_NOISE_GATE,
258 3, 1, 0),
259 SOC_SINGLE("ALC Capture NG Threshold", WM8985_NOISE_GATE,
260 0, 7, 1),
261
262 SOC_DOUBLE_R_TLV("Capture Volume", WM8985_LEFT_ADC_DIGITAL_VOL,
263 WM8985_RIGHT_ADC_DIGITAL_VOL, 0, 255, 0, adc_tlv),
264 SOC_DOUBLE_R("Capture PGA ZC Switch", WM8985_LEFT_INP_PGA_GAIN_CTRL,
265 WM8985_RIGHT_INP_PGA_GAIN_CTRL, 7, 1, 0),
266 SOC_DOUBLE_R_TLV("Capture PGA Volume", WM8985_LEFT_INP_PGA_GAIN_CTRL,
267 WM8985_RIGHT_INP_PGA_GAIN_CTRL, 0, 63, 0, pga_vol_tlv),
268
269 SOC_DOUBLE_R_TLV("Capture PGA Boost Volume",
270 WM8985_LEFT_ADC_BOOST_CTRL, WM8985_RIGHT_ADC_BOOST_CTRL,
271 8, 1, 0, pga_boost_tlv),
272
273 SOC_DOUBLE("ADC Inversion Switch", WM8985_ADC_CONTROL, 0, 1, 1, 0),
274 SOC_SINGLE("ADC 128x Oversampling Switch", WM8985_ADC_CONTROL, 8, 1, 0),
275
276 SOC_DOUBLE_R_TLV("Playback Volume", WM8985_LEFT_DAC_DIGITAL_VOL,
277 WM8985_RIGHT_DAC_DIGITAL_VOL, 0, 255, 0, dac_tlv),
278
279 SOC_SINGLE("DAC Playback Limiter Switch", WM8985_DAC_LIMITER_1, 8, 1, 0),
280 SOC_SINGLE("DAC Playback Limiter Decay", WM8985_DAC_LIMITER_1, 4, 10, 0),
281 SOC_SINGLE("DAC Playback Limiter Attack", WM8985_DAC_LIMITER_1, 0, 11, 0),
282 SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8985_DAC_LIMITER_2,
283 4, 7, 1, lim_thresh_tlv),
284 SOC_SINGLE_TLV("DAC Playback Limiter Boost Volume", WM8985_DAC_LIMITER_2,
285 0, 12, 0, lim_boost_tlv),
286 SOC_DOUBLE("DAC Inversion Switch", WM8985_DAC_CONTROL, 0, 1, 1, 0),
287 SOC_SINGLE("DAC Auto Mute Switch", WM8985_DAC_CONTROL, 2, 1, 0),
288 SOC_SINGLE("DAC 128x Oversampling Switch", WM8985_DAC_CONTROL, 3, 1, 0),
289
290 SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8985_LOUT1_HP_VOLUME_CTRL,
291 WM8985_ROUT1_HP_VOLUME_CTRL, 0, 63, 0, out_tlv),
292 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8985_LOUT1_HP_VOLUME_CTRL,
293 WM8985_ROUT1_HP_VOLUME_CTRL, 7, 1, 0),
294 SOC_DOUBLE_R("Headphone Switch", WM8985_LOUT1_HP_VOLUME_CTRL,
295 WM8985_ROUT1_HP_VOLUME_CTRL, 6, 1, 1),
296
297 SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8985_LOUT2_SPK_VOLUME_CTRL,
298 WM8985_ROUT2_SPK_VOLUME_CTRL, 0, 63, 0, out_tlv),
299 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8985_LOUT2_SPK_VOLUME_CTRL,
300 WM8985_ROUT2_SPK_VOLUME_CTRL, 7, 1, 0),
301 SOC_DOUBLE_R("Speaker Switch", WM8985_LOUT2_SPK_VOLUME_CTRL,
302 WM8985_ROUT2_SPK_VOLUME_CTRL, 6, 1, 1),
303
304 SOC_SINGLE("High Pass Filter Switch", WM8985_ADC_CONTROL, 8, 1, 0),
305 SOC_ENUM("High Pass Filter Mode", filter_mode),
306 SOC_SINGLE("High Pass Filter Cutoff", WM8985_ADC_CONTROL, 4, 7, 0),
307
308 SOC_DOUBLE_R_TLV("Aux Bypass Volume",
309 WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 6, 7, 0,
310 aux_tlv),
311
312 SOC_DOUBLE_R_TLV("Input PGA Bypass Volume",
313 WM8985_LEFT_MIXER_CTRL, WM8985_RIGHT_MIXER_CTRL, 2, 7, 0,
314 bypass_tlv),
315
316 SOC_ENUM_EXT("Equalizer Function", eqmode, eqmode_get, eqmode_put),
317 SOC_ENUM("EQ1 Cutoff", eq1_cutoff),
318 SOC_SINGLE_TLV("EQ1 Volume", WM8985_EQ1_LOW_SHELF, 0, 24, 1, eq_tlv),
319 SOC_ENUM("EQ2 Bandwith", eq2_bw),
320 SOC_ENUM("EQ2 Cutoff", eq2_cutoff),
321 SOC_SINGLE_TLV("EQ2 Volume", WM8985_EQ2_PEAK_1, 0, 24, 1, eq_tlv),
322 SOC_ENUM("EQ3 Bandwith", eq3_bw),
323 SOC_ENUM("EQ3 Cutoff", eq3_cutoff),
324 SOC_SINGLE_TLV("EQ3 Volume", WM8985_EQ3_PEAK_2, 0, 24, 1, eq_tlv),
325 SOC_ENUM("EQ4 Bandwith", eq4_bw),
326 SOC_ENUM("EQ4 Cutoff", eq4_cutoff),
327 SOC_SINGLE_TLV("EQ4 Volume", WM8985_EQ4_PEAK_3, 0, 24, 1, eq_tlv),
328 SOC_ENUM("EQ5 Cutoff", eq5_cutoff),
329 SOC_SINGLE_TLV("EQ5 Volume", WM8985_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
330
331 SOC_ENUM("3D Depth", depth_3d),
332
333 SOC_ENUM("Speaker Mode", speaker_mode)
334};
335
336static const struct snd_kcontrol_new left_out_mixer[] = {
337 SOC_DAPM_SINGLE("Line Switch", WM8985_LEFT_MIXER_CTRL, 1, 1, 0),
338 SOC_DAPM_SINGLE("Aux Switch", WM8985_LEFT_MIXER_CTRL, 5, 1, 0),
339 SOC_DAPM_SINGLE("PCM Switch", WM8985_LEFT_MIXER_CTRL, 0, 1, 0),
340};
341
342static const struct snd_kcontrol_new right_out_mixer[] = {
343 SOC_DAPM_SINGLE("Line Switch", WM8985_RIGHT_MIXER_CTRL, 1, 1, 0),
344 SOC_DAPM_SINGLE("Aux Switch", WM8985_RIGHT_MIXER_CTRL, 5, 1, 0),
345 SOC_DAPM_SINGLE("PCM Switch", WM8985_RIGHT_MIXER_CTRL, 0, 1, 0),
346};
347
348static const struct snd_kcontrol_new left_input_mixer[] = {
349 SOC_DAPM_SINGLE("L2 Switch", WM8985_INPUT_CTRL, 2, 1, 0),
350 SOC_DAPM_SINGLE("MicN Switch", WM8985_INPUT_CTRL, 1, 1, 0),
351 SOC_DAPM_SINGLE("MicP Switch", WM8985_INPUT_CTRL, 0, 1, 0),
352};
353
354static const struct snd_kcontrol_new right_input_mixer[] = {
355 SOC_DAPM_SINGLE("R2 Switch", WM8985_INPUT_CTRL, 6, 1, 0),
356 SOC_DAPM_SINGLE("MicN Switch", WM8985_INPUT_CTRL, 5, 1, 0),
357 SOC_DAPM_SINGLE("MicP Switch", WM8985_INPUT_CTRL, 4, 1, 0),
358};
359
360static const struct snd_kcontrol_new left_boost_mixer[] = {
361 SOC_DAPM_SINGLE_TLV("L2 Volume", WM8985_LEFT_ADC_BOOST_CTRL,
362 4, 7, 0, boost_tlv),
363 SOC_DAPM_SINGLE_TLV("AUXL Volume", WM8985_LEFT_ADC_BOOST_CTRL,
364 0, 7, 0, boost_tlv)
365};
366
367static const struct snd_kcontrol_new right_boost_mixer[] = {
368 SOC_DAPM_SINGLE_TLV("R2 Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
369 4, 7, 0, boost_tlv),
370 SOC_DAPM_SINGLE_TLV("AUXR Volume", WM8985_RIGHT_ADC_BOOST_CTRL,
371 0, 7, 0, boost_tlv)
372};
373
374static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
375 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8985_POWER_MANAGEMENT_3,
376 0, 0),
377 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8985_POWER_MANAGEMENT_3,
378 1, 0),
379 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8985_POWER_MANAGEMENT_2,
380 0, 0),
381 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8985_POWER_MANAGEMENT_2,
382 1, 0),
383
384 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8985_POWER_MANAGEMENT_3,
385 2, 0, left_out_mixer, ARRAY_SIZE(left_out_mixer)),
386 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8985_POWER_MANAGEMENT_3,
387 3, 0, right_out_mixer, ARRAY_SIZE(right_out_mixer)),
388
389 SND_SOC_DAPM_MIXER("Left Input Mixer", WM8985_POWER_MANAGEMENT_2,
390 2, 0, left_input_mixer, ARRAY_SIZE(left_input_mixer)),
391 SND_SOC_DAPM_MIXER("Right Input Mixer", WM8985_POWER_MANAGEMENT_2,
392 3, 0, right_input_mixer, ARRAY_SIZE(right_input_mixer)),
393
394 SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8985_POWER_MANAGEMENT_2,
395 4, 0, left_boost_mixer, ARRAY_SIZE(left_boost_mixer)),
396 SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8985_POWER_MANAGEMENT_2,
397 5, 0, right_boost_mixer, ARRAY_SIZE(right_boost_mixer)),
398
399 SND_SOC_DAPM_PGA("Left Capture PGA", WM8985_LEFT_INP_PGA_GAIN_CTRL,
400 6, 1, NULL, 0),
401 SND_SOC_DAPM_PGA("Right Capture PGA", WM8985_RIGHT_INP_PGA_GAIN_CTRL,
402 6, 1, NULL, 0),
403
404 SND_SOC_DAPM_PGA("Left Headphone Out", WM8985_POWER_MANAGEMENT_2,
405 7, 0, NULL, 0),
406 SND_SOC_DAPM_PGA("Right Headphone Out", WM8985_POWER_MANAGEMENT_2,
407 8, 0, NULL, 0),
408
409 SND_SOC_DAPM_PGA("Left Speaker Out", WM8985_POWER_MANAGEMENT_3,
410 5, 0, NULL, 0),
411 SND_SOC_DAPM_PGA("Right Speaker Out", WM8985_POWER_MANAGEMENT_3,
412 6, 0, NULL, 0),
413
414 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0),
415
416 SND_SOC_DAPM_INPUT("LIN"),
417 SND_SOC_DAPM_INPUT("LIP"),
418 SND_SOC_DAPM_INPUT("RIN"),
419 SND_SOC_DAPM_INPUT("RIP"),
420 SND_SOC_DAPM_INPUT("AUXL"),
421 SND_SOC_DAPM_INPUT("AUXR"),
422 SND_SOC_DAPM_INPUT("L2"),
423 SND_SOC_DAPM_INPUT("R2"),
424 SND_SOC_DAPM_OUTPUT("HPL"),
425 SND_SOC_DAPM_OUTPUT("HPR"),
426 SND_SOC_DAPM_OUTPUT("SPKL"),
427 SND_SOC_DAPM_OUTPUT("SPKR")
428};
429
430static const struct snd_soc_dapm_route audio_map[] = {
431 { "Right Output Mixer", "PCM Switch", "Right DAC" },
432 { "Right Output Mixer", "Aux Switch", "AUXR" },
433 { "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
434
435 { "Left Output Mixer", "PCM Switch", "Left DAC" },
436 { "Left Output Mixer", "Aux Switch", "AUXL" },
437 { "Left Output Mixer", "Line Switch", "Left Boost Mixer" },
438
439 { "Right Headphone Out", NULL, "Right Output Mixer" },
440 { "HPR", NULL, "Right Headphone Out" },
441
442 { "Left Headphone Out", NULL, "Left Output Mixer" },
443 { "HPL", NULL, "Left Headphone Out" },
444
445 { "Right Speaker Out", NULL, "Right Output Mixer" },
446 { "SPKR", NULL, "Right Speaker Out" },
447
448 { "Left Speaker Out", NULL, "Left Output Mixer" },
449 { "SPKL", NULL, "Left Speaker Out" },
450
451 { "Right ADC", NULL, "Right Boost Mixer" },
452
453 { "Right Boost Mixer", "AUXR Volume", "AUXR" },
454 { "Right Boost Mixer", NULL, "Right Capture PGA" },
455 { "Right Boost Mixer", "R2 Volume", "R2" },
456
457 { "Left ADC", NULL, "Left Boost Mixer" },
458
459 { "Left Boost Mixer", "AUXL Volume", "AUXL" },
460 { "Left Boost Mixer", NULL, "Left Capture PGA" },
461 { "Left Boost Mixer", "L2 Volume", "L2" },
462
463 { "Right Capture PGA", NULL, "Right Input Mixer" },
464 { "Left Capture PGA", NULL, "Left Input Mixer" },
465
466 { "Right Input Mixer", "R2 Switch", "R2" },
467 { "Right Input Mixer", "MicN Switch", "RIN" },
468 { "Right Input Mixer", "MicP Switch", "RIP" },
469
470 { "Left Input Mixer", "L2 Switch", "L2" },
471 { "Left Input Mixer", "MicN Switch", "LIN" },
472 { "Left Input Mixer", "MicP Switch", "LIP" },
473};
474
475static int eqmode_get(struct snd_kcontrol *kcontrol,
476 struct snd_ctl_elem_value *ucontrol)
477{
478 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
479 unsigned int reg;
480
481 reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF);
482 if (reg & WM8985_EQ3DMODE)
483 ucontrol->value.integer.value[0] = 1;
484 else
485 ucontrol->value.integer.value[0] = 0;
486
487 return 0;
488}
489
490static int eqmode_put(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
492{
493 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
494 unsigned int regpwr2, regpwr3;
495 unsigned int reg_eq;
496
497 if (ucontrol->value.integer.value[0] != 0
498 && ucontrol->value.integer.value[0] != 1)
499 return -EINVAL;
500
501 reg_eq = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF);
502 switch ((reg_eq & WM8985_EQ3DMODE) >> WM8985_EQ3DMODE_SHIFT) {
503 case 0:
504 if (!ucontrol->value.integer.value[0])
505 return 0;
506 break;
507 case 1:
508 if (ucontrol->value.integer.value[0])
509 return 0;
510 break;
511 }
512
513 regpwr2 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_2);
514 regpwr3 = snd_soc_read(codec, WM8985_POWER_MANAGEMENT_3);
515 /* disable the DACs and ADCs */
516 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_2,
517 WM8985_ADCENR_MASK | WM8985_ADCENL_MASK, 0);
518 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_3,
519 WM8985_DACENR_MASK | WM8985_DACENL_MASK, 0);
520 snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL,
521 WM8985_M128ENB_MASK, WM8985_M128ENB);
522 /* set the desired eqmode */
523 snd_soc_update_bits(codec, WM8985_EQ1_LOW_SHELF,
524 WM8985_EQ3DMODE_MASK,
525 ucontrol->value.integer.value[0]
526 << WM8985_EQ3DMODE_SHIFT);
527 /* restore DAC/ADC configuration */
528 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, regpwr2);
529 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, regpwr3);
530 return 0;
531}
532
533static int wm8985_add_widgets(struct snd_soc_codec *codec)
534{
535 struct snd_soc_dapm_context *dapm = &codec->dapm;
536
537 snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
538 ARRAY_SIZE(wm8985_dapm_widgets));
539 snd_soc_dapm_add_routes(dapm, audio_map,
540 ARRAY_SIZE(audio_map));
541 return 0;
542}
543
544static int wm8985_reset(struct snd_soc_codec *codec)
545{
546 return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0);
547}
548
549static int wm8985_dac_mute(struct snd_soc_dai *dai, int mute)
550{
551 struct snd_soc_codec *codec = dai->codec;
552
553 return snd_soc_update_bits(codec, WM8985_DAC_CONTROL,
554 WM8985_SOFTMUTE_MASK,
555 !!mute << WM8985_SOFTMUTE_SHIFT);
556}
557
558static int wm8985_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
559{
560 struct snd_soc_codec *codec;
561 u16 format, master, bcp, lrp;
562
563 codec = dai->codec;
564
565 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
566 case SND_SOC_DAIFMT_I2S:
567 format = 0x2;
568 break;
569 case SND_SOC_DAIFMT_RIGHT_J:
570 format = 0x0;
571 break;
572 case SND_SOC_DAIFMT_LEFT_J:
573 format = 0x1;
574 break;
575 case SND_SOC_DAIFMT_DSP_A:
576 case SND_SOC_DAIFMT_DSP_B:
577 format = 0x3;
578 break;
579 default:
580 dev_err(dai->dev, "Unknown dai format\n");
581 return -EINVAL;
582 }
583
584 snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
585 WM8985_FMT_MASK, format << WM8985_FMT_SHIFT);
586
587 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
588 case SND_SOC_DAIFMT_CBM_CFM:
589 master = 1;
590 break;
591 case SND_SOC_DAIFMT_CBS_CFS:
592 master = 0;
593 break;
594 default:
595 dev_err(dai->dev, "Unknown master/slave configuration\n");
596 return -EINVAL;
597 }
598
599 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
600 WM8985_MS_MASK, master << WM8985_MS_SHIFT);
601
602 /* frame inversion is not valid for dsp modes */
603 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
604 case SND_SOC_DAIFMT_DSP_A:
605 case SND_SOC_DAIFMT_DSP_B:
606 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
607 case SND_SOC_DAIFMT_IB_IF:
608 case SND_SOC_DAIFMT_NB_IF:
609 return -EINVAL;
610 default:
611 break;
612 }
613 break;
614 default:
615 break;
616 }
617
618 bcp = lrp = 0;
619 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
620 case SND_SOC_DAIFMT_NB_NF:
621 break;
622 case SND_SOC_DAIFMT_IB_IF:
623 bcp = lrp = 1;
624 break;
625 case SND_SOC_DAIFMT_IB_NF:
626 bcp = 1;
627 break;
628 case SND_SOC_DAIFMT_NB_IF:
629 lrp = 1;
630 break;
631 default:
632 dev_err(dai->dev, "Unknown polarity configuration\n");
633 return -EINVAL;
634 }
635
636 snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
637 WM8985_LRP_MASK, lrp << WM8985_LRP_SHIFT);
638 snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
639 WM8985_BCP_MASK, bcp << WM8985_BCP_SHIFT);
640 return 0;
641}
642
643static int wm8985_hw_params(struct snd_pcm_substream *substream,
644 struct snd_pcm_hw_params *params,
645 struct snd_soc_dai *dai)
646{
647 int i;
648 struct snd_soc_codec *codec;
649 struct wm8985_priv *wm8985;
650 u16 blen, srate_idx;
651 unsigned int tmp;
652 int srate_best;
653
654 codec = dai->codec;
655 wm8985 = snd_soc_codec_get_drvdata(codec);
656
657 wm8985->bclk = snd_soc_params_to_bclk(params);
658 if ((int)wm8985->bclk < 0)
659 return wm8985->bclk;
660
661 switch (params_format(params)) {
662 case SNDRV_PCM_FORMAT_S16_LE:
663 blen = 0x0;
664 break;
665 case SNDRV_PCM_FORMAT_S20_3LE:
666 blen = 0x1;
667 break;
668 case SNDRV_PCM_FORMAT_S24_LE:
669 blen = 0x2;
670 break;
671 case SNDRV_PCM_FORMAT_S32_LE:
672 blen = 0x3;
673 break;
674 default:
675 dev_err(dai->dev, "Unsupported word length %u\n",
676 params_format(params));
677 return -EINVAL;
678 }
679
680 snd_soc_update_bits(codec, WM8985_AUDIO_INTERFACE,
681 WM8985_WL_MASK, blen << WM8985_WL_SHIFT);
682
683 /*
684 * match to the nearest possible sample rate and rely
685 * on the array index to configure the SR register
686 */
687 srate_idx = 0;
688 srate_best = abs(srates[0] - params_rate(params));
689 for (i = 1; i < ARRAY_SIZE(srates); ++i) {
690 if (abs(srates[i] - params_rate(params)) >= srate_best)
691 continue;
692 srate_idx = i;
693 srate_best = abs(srates[i] - params_rate(params));
694 }
695
696 dev_dbg(dai->dev, "Selected SRATE = %d\n", srates[srate_idx]);
697 snd_soc_update_bits(codec, WM8985_ADDITIONAL_CONTROL,
698 WM8985_SR_MASK, srate_idx << WM8985_SR_SHIFT);
699
700 dev_dbg(dai->dev, "Target BCLK = %uHz\n", wm8985->bclk);
701 dev_dbg(dai->dev, "SYSCLK = %uHz\n", wm8985->sysclk);
702
703 for (i = 0; i < ARRAY_SIZE(fs_ratios); ++i) {
704 if (wm8985->sysclk / params_rate(params)
705 == fs_ratios[i].ratio)
706 break;
707 }
708
709 if (i == ARRAY_SIZE(fs_ratios)) {
710 dev_err(dai->dev, "Unable to configure MCLK ratio %u/%u\n",
711 wm8985->sysclk, params_rate(params));
712 return -EINVAL;
713 }
714
715 dev_dbg(dai->dev, "MCLK ratio = %dfs\n", fs_ratios[i].ratio);
716 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
717 WM8985_MCLKDIV_MASK, i << WM8985_MCLKDIV_SHIFT);
718
719 /* select the appropriate bclk divider */
720 tmp = (wm8985->sysclk / fs_ratios[i].div) * 10;
721 for (i = 0; i < ARRAY_SIZE(bclk_divs); ++i) {
722 if (wm8985->bclk == tmp / bclk_divs[i])
723 break;
724 }
725
726 if (i == ARRAY_SIZE(bclk_divs)) {
727 dev_err(dai->dev, "No matching BCLK divider found\n");
728 return -EINVAL;
729 }
730
731 dev_dbg(dai->dev, "BCLK div = %d\n", i);
732 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
733 WM8985_BCLKDIV_MASK, i << WM8985_BCLKDIV_SHIFT);
734 return 0;
735}
736
737struct pll_div {
738 u32 div2:1;
739 u32 n:4;
740 u32 k:24;
741};
742
743#define FIXED_PLL_SIZE ((1ULL << 24) * 10)
744static int pll_factors(struct pll_div *pll_div, unsigned int target,
745 unsigned int source)
746{
747 u64 Kpart;
748 unsigned long int K, Ndiv, Nmod;
749
750 pll_div->div2 = 0;
751 Ndiv = target / source;
752 if (Ndiv < 6) {
753 source >>= 1;
754 pll_div->div2 = 1;
755 Ndiv = target / source;
756 }
757
758 if (Ndiv < 6 || Ndiv > 12) {
759 printk(KERN_ERR "%s: WM8985 N value is not within"
760 " the recommended range: %lu\n", __func__, Ndiv);
761 return -EINVAL;
762 }
763 pll_div->n = Ndiv;
764
765 Nmod = target % source;
766 Kpart = FIXED_PLL_SIZE * (u64)Nmod;
767
768 do_div(Kpart, source);
769
770 K = Kpart & 0xffffffff;
771 if ((K % 10) >= 5)
772 K += 5;
773 K /= 10;
774 pll_div->k = K;
775
776 return 0;
777}
778
779static int wm8985_set_pll(struct snd_soc_dai *dai, int pll_id,
780 int source, unsigned int freq_in,
781 unsigned int freq_out)
782{
783 int ret;
784 struct snd_soc_codec *codec;
785 struct pll_div pll_div;
786
787 codec = dai->codec;
788 if (freq_in && freq_out) {
789 ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
790 if (ret)
791 return ret;
792 }
793
794 /* disable the PLL before reprogramming it */
795 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
796 WM8985_PLLEN_MASK, 0);
797
798 if (!freq_in || !freq_out)
799 return 0;
800
801 /* set PLLN and PRESCALE */
802 snd_soc_write(codec, WM8985_PLL_N,
803 (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT)
804 | pll_div.n);
805 /* set PLLK */
806 snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff);
807 snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
808 snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18));
809 /* set the source of the clock to be the PLL */
810 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
811 WM8985_CLKSEL_MASK, WM8985_CLKSEL);
812 /* enable the PLL */
813 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
814 WM8985_PLLEN_MASK, WM8985_PLLEN);
815 return 0;
816}
817
818static int wm8985_set_sysclk(struct snd_soc_dai *dai,
819 int clk_id, unsigned int freq, int dir)
820{
821 struct snd_soc_codec *codec;
822 struct wm8985_priv *wm8985;
823
824 codec = dai->codec;
825 wm8985 = snd_soc_codec_get_drvdata(codec);
826
827 switch (clk_id) {
828 case WM8985_CLKSRC_MCLK:
829 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
830 WM8985_CLKSEL_MASK, 0);
831 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
832 WM8985_PLLEN_MASK, 0);
833 break;
834 case WM8985_CLKSRC_PLL:
835 snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
836 WM8985_CLKSEL_MASK, WM8985_CLKSEL);
837 break;
838 default:
839 dev_err(dai->dev, "Unknown clock source %d\n", clk_id);
840 return -EINVAL;
841 }
842
843 wm8985->sysclk = freq;
844 return 0;
845}
846
847static void wm8985_sync_cache(struct snd_soc_codec *codec)
848{
849 short i;
850 u16 *cache;
851
852 if (!codec->cache_sync)
853 return;
854 codec->cache_only = 0;
855 /* restore cache */
856 cache = codec->reg_cache;
857 for (i = 0; i < codec->driver->reg_cache_size; i++) {
858 if (i == WM8985_SOFTWARE_RESET
859 || cache[i] == wm8985_reg_defs[i])
860 continue;
861 snd_soc_write(codec, i, cache[i]);
862 }
863 codec->cache_sync = 0;
864}
865
866static int wm8985_set_bias_level(struct snd_soc_codec *codec,
867 enum snd_soc_bias_level level)
868{
869 int ret;
870 struct wm8985_priv *wm8985;
871
872 wm8985 = snd_soc_codec_get_drvdata(codec);
873 switch (level) {
874 case SND_SOC_BIAS_ON:
875 case SND_SOC_BIAS_PREPARE:
876 /* VMID at 75k */
877 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
878 WM8985_VMIDSEL_MASK,
879 1 << WM8985_VMIDSEL_SHIFT);
880 break;
881 case SND_SOC_BIAS_STANDBY:
882 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
883 ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
884 wm8985->supplies);
885 if (ret) {
886 dev_err(codec->dev,
887 "Failed to enable supplies: %d\n",
888 ret);
889 return ret;
890 }
891
892 wm8985_sync_cache(codec);
893
894 /* enable anti-pop features */
895 snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
896 WM8985_POBCTRL_MASK,
897 WM8985_POBCTRL);
898 /* enable thermal shutdown */
899 snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
900 WM8985_TSDEN_MASK, WM8985_TSDEN);
901 snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
902 WM8985_TSOPCTRL_MASK,
903 WM8985_TSOPCTRL);
904 /* enable BIASEN */
905 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
906 WM8985_BIASEN_MASK, WM8985_BIASEN);
907 /* VMID at 75k */
908 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
909 WM8985_VMIDSEL_MASK,
910 1 << WM8985_VMIDSEL_SHIFT);
911 msleep(500);
912 /* disable anti-pop features */
913 snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
914 WM8985_POBCTRL_MASK, 0);
915 }
916 /* VMID at 300k */
917 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
918 WM8985_VMIDSEL_MASK,
919 2 << WM8985_VMIDSEL_SHIFT);
920 break;
921 case SND_SOC_BIAS_OFF:
922 /* disable thermal shutdown */
923 snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
924 WM8985_TSOPCTRL_MASK, 0);
925 snd_soc_update_bits(codec, WM8985_OUTPUT_CTRL0,
926 WM8985_TSDEN_MASK, 0);
927 /* disable VMIDSEL and BIASEN */
928 snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
929 WM8985_VMIDSEL_MASK | WM8985_BIASEN_MASK,
930 0);
931 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_1, 0);
932 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0);
933 snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0);
934
935 codec->cache_sync = 1;
936
937 regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies),
938 wm8985->supplies);
939 break;
940 }
941
942 codec->dapm.bias_level = level;
943 return 0;
944}
945
946#ifdef CONFIG_PM
947static int wm8985_suspend(struct snd_soc_codec *codec, pm_message_t state)
948{
949 wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF);
950 return 0;
951}
952
953static int wm8985_resume(struct snd_soc_codec *codec)
954{
955 wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
956 return 0;
957}
958#else
959#define wm8985_suspend NULL
960#define wm8985_resume NULL
961#endif
962
963static int wm8985_remove(struct snd_soc_codec *codec)
964{
965 struct wm8985_priv *wm8985;
966
967 wm8985 = snd_soc_codec_get_drvdata(codec);
968 wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF);
969 regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies);
970 return 0;
971}
972
973static int wm8985_probe(struct snd_soc_codec *codec)
974{
975 size_t i;
976 struct wm8985_priv *wm8985;
977 int ret;
978 u16 *cache;
979
980 wm8985 = snd_soc_codec_get_drvdata(codec);
981
982 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type);
983 if (ret < 0) {
984 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
985 return ret;
986 }
987
988 for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++)
989 wm8985->supplies[i].supply = wm8985_supply_names[i];
990
991 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8985->supplies),
992 wm8985->supplies);
993 if (ret) {
994 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
995 return ret;
996 }
997
998 ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
999 wm8985->supplies);
1000 if (ret) {
1001 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1002 goto err_reg_get;
1003 }
1004
1005 ret = wm8985_reset(codec);
1006 if (ret < 0) {
1007 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1008 goto err_reg_enable;
1009 }
1010
1011 cache = codec->reg_cache;
1012 /* latch volume update bits */
1013 for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i)
1014 cache[volume_update_regs[i]] |= 0x100;
1015 /* enable BIASCUT */
1016 cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT;
1017 codec->cache_sync = 1;
1018
1019 snd_soc_add_controls(codec, wm8985_snd_controls,
1020 ARRAY_SIZE(wm8985_snd_controls));
1021 wm8985_add_widgets(codec);
1022
1023 wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1024 return 0;
1025
1026err_reg_enable:
1027 regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies);
1028err_reg_get:
1029 regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies);
1030 return ret;
1031}
1032
1033static struct snd_soc_dai_ops wm8985_dai_ops = {
1034 .digital_mute = wm8985_dac_mute,
1035 .hw_params = wm8985_hw_params,
1036 .set_fmt = wm8985_set_fmt,
1037 .set_sysclk = wm8985_set_sysclk,
1038 .set_pll = wm8985_set_pll
1039};
1040
1041#define WM8985_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1042 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1043
1044static struct snd_soc_dai_driver wm8985_dai = {
1045 .name = "wm8985-hifi",
1046 .playback = {
1047 .stream_name = "Playback",
1048 .channels_min = 2,
1049 .channels_max = 2,
1050 .rates = SNDRV_PCM_RATE_8000_48000,
1051 .formats = WM8985_FORMATS,
1052 },
1053 .capture = {
1054 .stream_name = "Capture",
1055 .channels_min = 2,
1056 .channels_max = 2,
1057 .rates = SNDRV_PCM_RATE_8000_48000,
1058 .formats = WM8985_FORMATS,
1059 },
1060 .ops = &wm8985_dai_ops,
1061 .symmetric_rates = 1
1062};
1063
1064static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
1065 .probe = wm8985_probe,
1066 .remove = wm8985_remove,
1067 .suspend = wm8985_suspend,
1068 .resume = wm8985_resume,
1069 .set_bias_level = wm8985_set_bias_level,
1070 .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs),
1071 .reg_word_size = sizeof(u16),
1072 .reg_cache_default = wm8985_reg_defs
1073};
1074
1075#if defined(CONFIG_SPI_MASTER)
1076static int __devinit wm8985_spi_probe(struct spi_device *spi)
1077{
1078 struct wm8985_priv *wm8985;
1079 int ret;
1080
1081 wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL);
1082 if (!wm8985)
1083 return -ENOMEM;
1084
1085 wm8985->control_type = SND_SOC_SPI;
1086 spi_set_drvdata(spi, wm8985);
1087
1088 ret = snd_soc_register_codec(&spi->dev,
1089 &soc_codec_dev_wm8985, &wm8985_dai, 1);
1090 if (ret < 0)
1091 kfree(wm8985);
1092 return ret;
1093}
1094
1095static int __devexit wm8985_spi_remove(struct spi_device *spi)
1096{
1097 snd_soc_unregister_codec(&spi->dev);
1098 kfree(spi_get_drvdata(spi));
1099 return 0;
1100}
1101
1102static struct spi_driver wm8985_spi_driver = {
1103 .driver = {
1104 .name = "wm8985",
1105 .owner = THIS_MODULE,
1106 },
1107 .probe = wm8985_spi_probe,
1108 .remove = __devexit_p(wm8985_spi_remove)
1109};
1110#endif
1111
1112#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1113static __devinit int wm8985_i2c_probe(struct i2c_client *i2c,
1114 const struct i2c_device_id *id)
1115{
1116 struct wm8985_priv *wm8985;
1117 int ret;
1118
1119 wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL);
1120 if (!wm8985)
1121 return -ENOMEM;
1122
1123 wm8985->control_type = SND_SOC_I2C;
1124 i2c_set_clientdata(i2c, wm8985);
1125
1126 ret = snd_soc_register_codec(&i2c->dev,
1127 &soc_codec_dev_wm8985, &wm8985_dai, 1);
1128 if (ret < 0)
1129 kfree(wm8985);
1130 return ret;
1131}
1132
1133static __devexit int wm8985_i2c_remove(struct i2c_client *client)
1134{
1135 snd_soc_unregister_codec(&client->dev);
1136 kfree(i2c_get_clientdata(client));
1137 return 0;
1138}
1139
1140static const struct i2c_device_id wm8985_i2c_id[] = {
1141 { "wm8985", 0 },
1142 { }
1143};
1144MODULE_DEVICE_TABLE(i2c, wm8985_i2c_id);
1145
1146static struct i2c_driver wm8985_i2c_driver = {
1147 .driver = {
1148 .name = "wm8985",
1149 .owner = THIS_MODULE,
1150 },
1151 .probe = wm8985_i2c_probe,
1152 .remove = __devexit_p(wm8985_i2c_remove),
1153 .id_table = wm8985_i2c_id
1154};
1155#endif
1156
1157static int __init wm8985_modinit(void)
1158{
1159 int ret = 0;
1160
1161#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1162 ret = i2c_add_driver(&wm8985_i2c_driver);
1163 if (ret) {
1164 printk(KERN_ERR "Failed to register wm8985 I2C driver: %d\n",
1165 ret);
1166 }
1167#endif
1168#if defined(CONFIG_SPI_MASTER)
1169 ret = spi_register_driver(&wm8985_spi_driver);
1170 if (ret != 0) {
1171 printk(KERN_ERR "Failed to register wm8985 SPI driver: %d\n",
1172 ret);
1173 }
1174#endif
1175 return ret;
1176}
1177module_init(wm8985_modinit);
1178
1179static void __exit wm8985_exit(void)
1180{
1181#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1182 i2c_del_driver(&wm8985_i2c_driver);
1183#endif
1184#if defined(CONFIG_SPI_MASTER)
1185 spi_unregister_driver(&wm8985_spi_driver);
1186#endif
1187}
1188module_exit(wm8985_exit);
1189
1190MODULE_DESCRIPTION("ASoC WM8985 driver");
1191MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
1192MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8985.h b/sound/soc/codecs/wm8985.h
new file mode 100644
index 000000000000..2e71ff507638
--- /dev/null
+++ b/sound/soc/codecs/wm8985.h
@@ -0,0 +1,1045 @@
1/*
2 * wm8985.h -- WM8985 ASoC driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8985_H
14#define _WM8985_H
15
16#define WM8985_SOFTWARE_RESET 0x00
17#define WM8985_POWER_MANAGEMENT_1 0x01
18#define WM8985_POWER_MANAGEMENT_2 0x02
19#define WM8985_POWER_MANAGEMENT_3 0x03
20#define WM8985_AUDIO_INTERFACE 0x04
21#define WM8985_COMPANDING_CONTROL 0x05
22#define WM8985_CLOCK_GEN_CONTROL 0x06
23#define WM8985_ADDITIONAL_CONTROL 0x07
24#define WM8985_GPIO_CONTROL 0x08
25#define WM8985_JACK_DETECT_CONTROL_1 0x09
26#define WM8985_DAC_CONTROL 0x0A
27#define WM8985_LEFT_DAC_DIGITAL_VOL 0x0B
28#define WM8985_RIGHT_DAC_DIGITAL_VOL 0x0C
29#define WM8985_JACK_DETECT_CONTROL_2 0x0D
30#define WM8985_ADC_CONTROL 0x0E
31#define WM8985_LEFT_ADC_DIGITAL_VOL 0x0F
32#define WM8985_RIGHT_ADC_DIGITAL_VOL 0x10
33#define WM8985_EQ1_LOW_SHELF 0x12
34#define WM8985_EQ2_PEAK_1 0x13
35#define WM8985_EQ3_PEAK_2 0x14
36#define WM8985_EQ4_PEAK_3 0x15
37#define WM8985_EQ5_HIGH_SHELF 0x16
38#define WM8985_DAC_LIMITER_1 0x18
39#define WM8985_DAC_LIMITER_2 0x19
40#define WM8985_NOTCH_FILTER_1 0x1B
41#define WM8985_NOTCH_FILTER_2 0x1C
42#define WM8985_NOTCH_FILTER_3 0x1D
43#define WM8985_NOTCH_FILTER_4 0x1E
44#define WM8985_ALC_CONTROL_1 0x20
45#define WM8985_ALC_CONTROL_2 0x21
46#define WM8985_ALC_CONTROL_3 0x22
47#define WM8985_NOISE_GATE 0x23
48#define WM8985_PLL_N 0x24
49#define WM8985_PLL_K_1 0x25
50#define WM8985_PLL_K_2 0x26
51#define WM8985_PLL_K_3 0x27
52#define WM8985_3D_CONTROL 0x29
53#define WM8985_OUT4_TO_ADC 0x2A
54#define WM8985_BEEP_CONTROL 0x2B
55#define WM8985_INPUT_CTRL 0x2C
56#define WM8985_LEFT_INP_PGA_GAIN_CTRL 0x2D
57#define WM8985_RIGHT_INP_PGA_GAIN_CTRL 0x2E
58#define WM8985_LEFT_ADC_BOOST_CTRL 0x2F
59#define WM8985_RIGHT_ADC_BOOST_CTRL 0x30
60#define WM8985_OUTPUT_CTRL0 0x31
61#define WM8985_LEFT_MIXER_CTRL 0x32
62#define WM8985_RIGHT_MIXER_CTRL 0x33
63#define WM8985_LOUT1_HP_VOLUME_CTRL 0x34
64#define WM8985_ROUT1_HP_VOLUME_CTRL 0x35
65#define WM8985_LOUT2_SPK_VOLUME_CTRL 0x36
66#define WM8985_ROUT2_SPK_VOLUME_CTRL 0x37
67#define WM8985_OUT3_MIXER_CTRL 0x38
68#define WM8985_OUT4_MONO_MIX_CTRL 0x39
69#define WM8985_OUTPUT_CTRL1 0x3C
70#define WM8985_BIAS_CTRL 0x3D
71
72#define WM8985_REGISTER_COUNT 59
73#define WM8985_MAX_REGISTER 0x3F
74
75/*
76 * Field Definitions.
77 */
78
79/*
80 * R0 (0x00) - Software Reset
81 */
82#define WM8985_SOFTWARE_RESET_MASK 0x01FF /* SOFTWARE_RESET - [8:0] */
83#define WM8985_SOFTWARE_RESET_SHIFT 0 /* SOFTWARE_RESET - [8:0] */
84#define WM8985_SOFTWARE_RESET_WIDTH 9 /* SOFTWARE_RESET - [8:0] */
85
86/*
87 * R1 (0x01) - Power management 1
88 */
89#define WM8985_OUT4MIXEN 0x0080 /* OUT4MIXEN */
90#define WM8985_OUT4MIXEN_MASK 0x0080 /* OUT4MIXEN */
91#define WM8985_OUT4MIXEN_SHIFT 7 /* OUT4MIXEN */
92#define WM8985_OUT4MIXEN_WIDTH 1 /* OUT4MIXEN */
93#define WM8985_OUT3MIXEN 0x0040 /* OUT3MIXEN */
94#define WM8985_OUT3MIXEN_MASK 0x0040 /* OUT3MIXEN */
95#define WM8985_OUT3MIXEN_SHIFT 6 /* OUT3MIXEN */
96#define WM8985_OUT3MIXEN_WIDTH 1 /* OUT3MIXEN */
97#define WM8985_PLLEN 0x0020 /* PLLEN */
98#define WM8985_PLLEN_MASK 0x0020 /* PLLEN */
99#define WM8985_PLLEN_SHIFT 5 /* PLLEN */
100#define WM8985_PLLEN_WIDTH 1 /* PLLEN */
101#define WM8985_MICBEN 0x0010 /* MICBEN */
102#define WM8985_MICBEN_MASK 0x0010 /* MICBEN */
103#define WM8985_MICBEN_SHIFT 4 /* MICBEN */
104#define WM8985_MICBEN_WIDTH 1 /* MICBEN */
105#define WM8985_BIASEN 0x0008 /* BIASEN */
106#define WM8985_BIASEN_MASK 0x0008 /* BIASEN */
107#define WM8985_BIASEN_SHIFT 3 /* BIASEN */
108#define WM8985_BIASEN_WIDTH 1 /* BIASEN */
109#define WM8985_BUFIOEN 0x0004 /* BUFIOEN */
110#define WM8985_BUFIOEN_MASK 0x0004 /* BUFIOEN */
111#define WM8985_BUFIOEN_SHIFT 2 /* BUFIOEN */
112#define WM8985_BUFIOEN_WIDTH 1 /* BUFIOEN */
113#define WM8985_VMIDSEL 0x0003 /* VMIDSEL */
114#define WM8985_VMIDSEL_MASK 0x0003 /* VMIDSEL - [1:0] */
115#define WM8985_VMIDSEL_SHIFT 0 /* VMIDSEL - [1:0] */
116#define WM8985_VMIDSEL_WIDTH 2 /* VMIDSEL - [1:0] */
117
118/*
119 * R2 (0x02) - Power management 2
120 */
121#define WM8985_ROUT1EN 0x0100 /* ROUT1EN */
122#define WM8985_ROUT1EN_MASK 0x0100 /* ROUT1EN */
123#define WM8985_ROUT1EN_SHIFT 8 /* ROUT1EN */
124#define WM8985_ROUT1EN_WIDTH 1 /* ROUT1EN */
125#define WM8985_LOUT1EN 0x0080 /* LOUT1EN */
126#define WM8985_LOUT1EN_MASK 0x0080 /* LOUT1EN */
127#define WM8985_LOUT1EN_SHIFT 7 /* LOUT1EN */
128#define WM8985_LOUT1EN_WIDTH 1 /* LOUT1EN */
129#define WM8985_SLEEP 0x0040 /* SLEEP */
130#define WM8985_SLEEP_MASK 0x0040 /* SLEEP */
131#define WM8985_SLEEP_SHIFT 6 /* SLEEP */
132#define WM8985_SLEEP_WIDTH 1 /* SLEEP */
133#define WM8985_BOOSTENR 0x0020 /* BOOSTENR */
134#define WM8985_BOOSTENR_MASK 0x0020 /* BOOSTENR */
135#define WM8985_BOOSTENR_SHIFT 5 /* BOOSTENR */
136#define WM8985_BOOSTENR_WIDTH 1 /* BOOSTENR */
137#define WM8985_BOOSTENL 0x0010 /* BOOSTENL */
138#define WM8985_BOOSTENL_MASK 0x0010 /* BOOSTENL */
139#define WM8985_BOOSTENL_SHIFT 4 /* BOOSTENL */
140#define WM8985_BOOSTENL_WIDTH 1 /* BOOSTENL */
141#define WM8985_INPGAENR 0x0008 /* INPGAENR */
142#define WM8985_INPGAENR_MASK 0x0008 /* INPGAENR */
143#define WM8985_INPGAENR_SHIFT 3 /* INPGAENR */
144#define WM8985_INPGAENR_WIDTH 1 /* INPGAENR */
145#define WM8985_INPPGAENL 0x0004 /* INPPGAENL */
146#define WM8985_INPPGAENL_MASK 0x0004 /* INPPGAENL */
147#define WM8985_INPPGAENL_SHIFT 2 /* INPPGAENL */
148#define WM8985_INPPGAENL_WIDTH 1 /* INPPGAENL */
149#define WM8985_ADCENR 0x0002 /* ADCENR */
150#define WM8985_ADCENR_MASK 0x0002 /* ADCENR */
151#define WM8985_ADCENR_SHIFT 1 /* ADCENR */
152#define WM8985_ADCENR_WIDTH 1 /* ADCENR */
153#define WM8985_ADCENL 0x0001 /* ADCENL */
154#define WM8985_ADCENL_MASK 0x0001 /* ADCENL */
155#define WM8985_ADCENL_SHIFT 0 /* ADCENL */
156#define WM8985_ADCENL_WIDTH 1 /* ADCENL */
157
158/*
159 * R3 (0x03) - Power management 3
160 */
161#define WM8985_OUT4EN 0x0100 /* OUT4EN */
162#define WM8985_OUT4EN_MASK 0x0100 /* OUT4EN */
163#define WM8985_OUT4EN_SHIFT 8 /* OUT4EN */
164#define WM8985_OUT4EN_WIDTH 1 /* OUT4EN */
165#define WM8985_OUT3EN 0x0080 /* OUT3EN */
166#define WM8985_OUT3EN_MASK 0x0080 /* OUT3EN */
167#define WM8985_OUT3EN_SHIFT 7 /* OUT3EN */
168#define WM8985_OUT3EN_WIDTH 1 /* OUT3EN */
169#define WM8985_ROUT2EN 0x0040 /* ROUT2EN */
170#define WM8985_ROUT2EN_MASK 0x0040 /* ROUT2EN */
171#define WM8985_ROUT2EN_SHIFT 6 /* ROUT2EN */
172#define WM8985_ROUT2EN_WIDTH 1 /* ROUT2EN */
173#define WM8985_LOUT2EN 0x0020 /* LOUT2EN */
174#define WM8985_LOUT2EN_MASK 0x0020 /* LOUT2EN */
175#define WM8985_LOUT2EN_SHIFT 5 /* LOUT2EN */
176#define WM8985_LOUT2EN_WIDTH 1 /* LOUT2EN */
177#define WM8985_RMIXEN 0x0008 /* RMIXEN */
178#define WM8985_RMIXEN_MASK 0x0008 /* RMIXEN */
179#define WM8985_RMIXEN_SHIFT 3 /* RMIXEN */
180#define WM8985_RMIXEN_WIDTH 1 /* RMIXEN */
181#define WM8985_LMIXEN 0x0004 /* LMIXEN */
182#define WM8985_LMIXEN_MASK 0x0004 /* LMIXEN */
183#define WM8985_LMIXEN_SHIFT 2 /* LMIXEN */
184#define WM8985_LMIXEN_WIDTH 1 /* LMIXEN */
185#define WM8985_DACENR 0x0002 /* DACENR */
186#define WM8985_DACENR_MASK 0x0002 /* DACENR */
187#define WM8985_DACENR_SHIFT 1 /* DACENR */
188#define WM8985_DACENR_WIDTH 1 /* DACENR */
189#define WM8985_DACENL 0x0001 /* DACENL */
190#define WM8985_DACENL_MASK 0x0001 /* DACENL */
191#define WM8985_DACENL_SHIFT 0 /* DACENL */
192#define WM8985_DACENL_WIDTH 1 /* DACENL */
193
194/*
195 * R4 (0x04) - Audio Interface
196 */
197#define WM8985_BCP 0x0100 /* BCP */
198#define WM8985_BCP_MASK 0x0100 /* BCP */
199#define WM8985_BCP_SHIFT 8 /* BCP */
200#define WM8985_BCP_WIDTH 1 /* BCP */
201#define WM8985_LRP 0x0080 /* LRP */
202#define WM8985_LRP_MASK 0x0080 /* LRP */
203#define WM8985_LRP_SHIFT 7 /* LRP */
204#define WM8985_LRP_WIDTH 1 /* LRP */
205#define WM8985_WL_MASK 0x0060 /* WL - [6:5] */
206#define WM8985_WL_SHIFT 5 /* WL - [6:5] */
207#define WM8985_WL_WIDTH 2 /* WL - [6:5] */
208#define WM8985_FMT_MASK 0x0018 /* FMT - [4:3] */
209#define WM8985_FMT_SHIFT 3 /* FMT - [4:3] */
210#define WM8985_FMT_WIDTH 2 /* FMT - [4:3] */
211#define WM8985_DLRSWAP 0x0004 /* DLRSWAP */
212#define WM8985_DLRSWAP_MASK 0x0004 /* DLRSWAP */
213#define WM8985_DLRSWAP_SHIFT 2 /* DLRSWAP */
214#define WM8985_DLRSWAP_WIDTH 1 /* DLRSWAP */
215#define WM8985_ALRSWAP 0x0002 /* ALRSWAP */
216#define WM8985_ALRSWAP_MASK 0x0002 /* ALRSWAP */
217#define WM8985_ALRSWAP_SHIFT 1 /* ALRSWAP */
218#define WM8985_ALRSWAP_WIDTH 1 /* ALRSWAP */
219#define WM8985_MONO 0x0001 /* MONO */
220#define WM8985_MONO_MASK 0x0001 /* MONO */
221#define WM8985_MONO_SHIFT 0 /* MONO */
222#define WM8985_MONO_WIDTH 1 /* MONO */
223
224/*
225 * R5 (0x05) - Companding control
226 */
227#define WM8985_WL8 0x0020 /* WL8 */
228#define WM8985_WL8_MASK 0x0020 /* WL8 */
229#define WM8985_WL8_SHIFT 5 /* WL8 */
230#define WM8985_WL8_WIDTH 1 /* WL8 */
231#define WM8985_DAC_COMP_MASK 0x0018 /* DAC_COMP - [4:3] */
232#define WM8985_DAC_COMP_SHIFT 3 /* DAC_COMP - [4:3] */
233#define WM8985_DAC_COMP_WIDTH 2 /* DAC_COMP - [4:3] */
234#define WM8985_ADC_COMP_MASK 0x0006 /* ADC_COMP - [2:1] */
235#define WM8985_ADC_COMP_SHIFT 1 /* ADC_COMP - [2:1] */
236#define WM8985_ADC_COMP_WIDTH 2 /* ADC_COMP - [2:1] */
237#define WM8985_LOOPBACK 0x0001 /* LOOPBACK */
238#define WM8985_LOOPBACK_MASK 0x0001 /* LOOPBACK */
239#define WM8985_LOOPBACK_SHIFT 0 /* LOOPBACK */
240#define WM8985_LOOPBACK_WIDTH 1 /* LOOPBACK */
241
242/*
243 * R6 (0x06) - Clock Gen control
244 */
245#define WM8985_CLKSEL 0x0100 /* CLKSEL */
246#define WM8985_CLKSEL_MASK 0x0100 /* CLKSEL */
247#define WM8985_CLKSEL_SHIFT 8 /* CLKSEL */
248#define WM8985_CLKSEL_WIDTH 1 /* CLKSEL */
249#define WM8985_MCLKDIV_MASK 0x00E0 /* MCLKDIV - [7:5] */
250#define WM8985_MCLKDIV_SHIFT 5 /* MCLKDIV - [7:5] */
251#define WM8985_MCLKDIV_WIDTH 3 /* MCLKDIV - [7:5] */
252#define WM8985_BCLKDIV_MASK 0x001C /* BCLKDIV - [4:2] */
253#define WM8985_BCLKDIV_SHIFT 2 /* BCLKDIV - [4:2] */
254#define WM8985_BCLKDIV_WIDTH 3 /* BCLKDIV - [4:2] */
255#define WM8985_MS 0x0001 /* MS */
256#define WM8985_MS_MASK 0x0001 /* MS */
257#define WM8985_MS_SHIFT 0 /* MS */
258#define WM8985_MS_WIDTH 1 /* MS */
259
260/*
261 * R7 (0x07) - Additional control
262 */
263#define WM8985_M128ENB 0x0100 /* M128ENB */
264#define WM8985_M128ENB_MASK 0x0100 /* M128ENB */
265#define WM8985_M128ENB_SHIFT 8 /* M128ENB */
266#define WM8985_M128ENB_WIDTH 1 /* M128ENB */
267#define WM8985_DCLKDIV_MASK 0x00F0 /* DCLKDIV - [7:4] */
268#define WM8985_DCLKDIV_SHIFT 4 /* DCLKDIV - [7:4] */
269#define WM8985_DCLKDIV_WIDTH 4 /* DCLKDIV - [7:4] */
270#define WM8985_SR_MASK 0x000E /* SR - [3:1] */
271#define WM8985_SR_SHIFT 1 /* SR - [3:1] */
272#define WM8985_SR_WIDTH 3 /* SR - [3:1] */
273#define WM8985_SLOWCLKEN 0x0001 /* SLOWCLKEN */
274#define WM8985_SLOWCLKEN_MASK 0x0001 /* SLOWCLKEN */
275#define WM8985_SLOWCLKEN_SHIFT 0 /* SLOWCLKEN */
276#define WM8985_SLOWCLKEN_WIDTH 1 /* SLOWCLKEN */
277
278/*
279 * R8 (0x08) - GPIO Control
280 */
281#define WM8985_GPIO1GP 0x0100 /* GPIO1GP */
282#define WM8985_GPIO1GP_MASK 0x0100 /* GPIO1GP */
283#define WM8985_GPIO1GP_SHIFT 8 /* GPIO1GP */
284#define WM8985_GPIO1GP_WIDTH 1 /* GPIO1GP */
285#define WM8985_GPIO1GPU 0x0080 /* GPIO1GPU */
286#define WM8985_GPIO1GPU_MASK 0x0080 /* GPIO1GPU */
287#define WM8985_GPIO1GPU_SHIFT 7 /* GPIO1GPU */
288#define WM8985_GPIO1GPU_WIDTH 1 /* GPIO1GPU */
289#define WM8985_GPIO1GPD 0x0040 /* GPIO1GPD */
290#define WM8985_GPIO1GPD_MASK 0x0040 /* GPIO1GPD */
291#define WM8985_GPIO1GPD_SHIFT 6 /* GPIO1GPD */
292#define WM8985_GPIO1GPD_WIDTH 1 /* GPIO1GPD */
293#define WM8985_GPIO1POL 0x0008 /* GPIO1POL */
294#define WM8985_GPIO1POL_MASK 0x0008 /* GPIO1POL */
295#define WM8985_GPIO1POL_SHIFT 3 /* GPIO1POL */
296#define WM8985_GPIO1POL_WIDTH 1 /* GPIO1POL */
297#define WM8985_GPIO1SEL_MASK 0x0007 /* GPIO1SEL - [2:0] */
298#define WM8985_GPIO1SEL_SHIFT 0 /* GPIO1SEL - [2:0] */
299#define WM8985_GPIO1SEL_WIDTH 3 /* GPIO1SEL - [2:0] */
300
301/*
302 * R9 (0x09) - Jack Detect Control 1
303 */
304#define WM8985_JD_EN 0x0040 /* JD_EN */
305#define WM8985_JD_EN_MASK 0x0040 /* JD_EN */
306#define WM8985_JD_EN_SHIFT 6 /* JD_EN */
307#define WM8985_JD_EN_WIDTH 1 /* JD_EN */
308#define WM8985_JD_SEL_MASK 0x0030 /* JD_SEL - [5:4] */
309#define WM8985_JD_SEL_SHIFT 4 /* JD_SEL - [5:4] */
310#define WM8985_JD_SEL_WIDTH 2 /* JD_SEL - [5:4] */
311
312/*
313 * R10 (0x0A) - DAC Control
314 */
315#define WM8985_SOFTMUTE 0x0040 /* SOFTMUTE */
316#define WM8985_SOFTMUTE_MASK 0x0040 /* SOFTMUTE */
317#define WM8985_SOFTMUTE_SHIFT 6 /* SOFTMUTE */
318#define WM8985_SOFTMUTE_WIDTH 1 /* SOFTMUTE */
319#define WM8985_DACOSR128 0x0008 /* DACOSR128 */
320#define WM8985_DACOSR128_MASK 0x0008 /* DACOSR128 */
321#define WM8985_DACOSR128_SHIFT 3 /* DACOSR128 */
322#define WM8985_DACOSR128_WIDTH 1 /* DACOSR128 */
323#define WM8985_AMUTE 0x0004 /* AMUTE */
324#define WM8985_AMUTE_MASK 0x0004 /* AMUTE */
325#define WM8985_AMUTE_SHIFT 2 /* AMUTE */
326#define WM8985_AMUTE_WIDTH 1 /* AMUTE */
327#define WM8985_DACPOLR 0x0002 /* DACPOLR */
328#define WM8985_DACPOLR_MASK 0x0002 /* DACPOLR */
329#define WM8985_DACPOLR_SHIFT 1 /* DACPOLR */
330#define WM8985_DACPOLR_WIDTH 1 /* DACPOLR */
331#define WM8985_DACPOLL 0x0001 /* DACPOLL */
332#define WM8985_DACPOLL_MASK 0x0001 /* DACPOLL */
333#define WM8985_DACPOLL_SHIFT 0 /* DACPOLL */
334#define WM8985_DACPOLL_WIDTH 1 /* DACPOLL */
335
336/*
337 * R11 (0x0B) - Left DAC digital Vol
338 */
339#define WM8985_DACVU 0x0100 /* DACVU */
340#define WM8985_DACVU_MASK 0x0100 /* DACVU */
341#define WM8985_DACVU_SHIFT 8 /* DACVU */
342#define WM8985_DACVU_WIDTH 1 /* DACVU */
343#define WM8985_DACVOLL_MASK 0x00FF /* DACVOLL - [7:0] */
344#define WM8985_DACVOLL_SHIFT 0 /* DACVOLL - [7:0] */
345#define WM8985_DACVOLL_WIDTH 8 /* DACVOLL - [7:0] */
346
347/*
348 * R12 (0x0C) - Right DAC digital vol
349 */
350#define WM8985_DACVU 0x0100 /* DACVU */
351#define WM8985_DACVU_MASK 0x0100 /* DACVU */
352#define WM8985_DACVU_SHIFT 8 /* DACVU */
353#define WM8985_DACVU_WIDTH 1 /* DACVU */
354#define WM8985_DACVOLR_MASK 0x00FF /* DACVOLR - [7:0] */
355#define WM8985_DACVOLR_SHIFT 0 /* DACVOLR - [7:0] */
356#define WM8985_DACVOLR_WIDTH 8 /* DACVOLR - [7:0] */
357
358/*
359 * R13 (0x0D) - Jack Detect Control 2
360 */
361#define WM8985_JD_EN1_MASK 0x00F0 /* JD_EN1 - [7:4] */
362#define WM8985_JD_EN1_SHIFT 4 /* JD_EN1 - [7:4] */
363#define WM8985_JD_EN1_WIDTH 4 /* JD_EN1 - [7:4] */
364#define WM8985_JD_EN0_MASK 0x000F /* JD_EN0 - [3:0] */
365#define WM8985_JD_EN0_SHIFT 0 /* JD_EN0 - [3:0] */
366#define WM8985_JD_EN0_WIDTH 4 /* JD_EN0 - [3:0] */
367
368/*
369 * R14 (0x0E) - ADC Control
370 */
371#define WM8985_HPFEN 0x0100 /* HPFEN */
372#define WM8985_HPFEN_MASK 0x0100 /* HPFEN */
373#define WM8985_HPFEN_SHIFT 8 /* HPFEN */
374#define WM8985_HPFEN_WIDTH 1 /* HPFEN */
375#define WM8985_HPFAPP 0x0080 /* HPFAPP */
376#define WM8985_HPFAPP_MASK 0x0080 /* HPFAPP */
377#define WM8985_HPFAPP_SHIFT 7 /* HPFAPP */
378#define WM8985_HPFAPP_WIDTH 1 /* HPFAPP */
379#define WM8985_HPFCUT_MASK 0x0070 /* HPFCUT - [6:4] */
380#define WM8985_HPFCUT_SHIFT 4 /* HPFCUT - [6:4] */
381#define WM8985_HPFCUT_WIDTH 3 /* HPFCUT - [6:4] */
382#define WM8985_ADCOSR128 0x0008 /* ADCOSR128 */
383#define WM8985_ADCOSR128_MASK 0x0008 /* ADCOSR128 */
384#define WM8985_ADCOSR128_SHIFT 3 /* ADCOSR128 */
385#define WM8985_ADCOSR128_WIDTH 1 /* ADCOSR128 */
386#define WM8985_ADCRPOL 0x0002 /* ADCRPOL */
387#define WM8985_ADCRPOL_MASK 0x0002 /* ADCRPOL */
388#define WM8985_ADCRPOL_SHIFT 1 /* ADCRPOL */
389#define WM8985_ADCRPOL_WIDTH 1 /* ADCRPOL */
390#define WM8985_ADCLPOL 0x0001 /* ADCLPOL */
391#define WM8985_ADCLPOL_MASK 0x0001 /* ADCLPOL */
392#define WM8985_ADCLPOL_SHIFT 0 /* ADCLPOL */
393#define WM8985_ADCLPOL_WIDTH 1 /* ADCLPOL */
394
395/*
396 * R15 (0x0F) - Left ADC Digital Vol
397 */
398#define WM8985_ADCVU 0x0100 /* ADCVU */
399#define WM8985_ADCVU_MASK 0x0100 /* ADCVU */
400#define WM8985_ADCVU_SHIFT 8 /* ADCVU */
401#define WM8985_ADCVU_WIDTH 1 /* ADCVU */
402#define WM8985_ADCVOLL_MASK 0x00FF /* ADCVOLL - [7:0] */
403#define WM8985_ADCVOLL_SHIFT 0 /* ADCVOLL - [7:0] */
404#define WM8985_ADCVOLL_WIDTH 8 /* ADCVOLL - [7:0] */
405
406/*
407 * R16 (0x10) - Right ADC Digital Vol
408 */
409#define WM8985_ADCVU 0x0100 /* ADCVU */
410#define WM8985_ADCVU_MASK 0x0100 /* ADCVU */
411#define WM8985_ADCVU_SHIFT 8 /* ADCVU */
412#define WM8985_ADCVU_WIDTH 1 /* ADCVU */
413#define WM8985_ADCVOLR_MASK 0x00FF /* ADCVOLR - [7:0] */
414#define WM8985_ADCVOLR_SHIFT 0 /* ADCVOLR - [7:0] */
415#define WM8985_ADCVOLR_WIDTH 8 /* ADCVOLR - [7:0] */
416
417/*
418 * R18 (0x12) - EQ1 - low shelf
419 */
420#define WM8985_EQ3DMODE 0x0100 /* EQ3DMODE */
421#define WM8985_EQ3DMODE_MASK 0x0100 /* EQ3DMODE */
422#define WM8985_EQ3DMODE_SHIFT 8 /* EQ3DMODE */
423#define WM8985_EQ3DMODE_WIDTH 1 /* EQ3DMODE */
424#define WM8985_EQ1C_MASK 0x0060 /* EQ1C - [6:5] */
425#define WM8985_EQ1C_SHIFT 5 /* EQ1C - [6:5] */
426#define WM8985_EQ1C_WIDTH 2 /* EQ1C - [6:5] */
427#define WM8985_EQ1G_MASK 0x001F /* EQ1G - [4:0] */
428#define WM8985_EQ1G_SHIFT 0 /* EQ1G - [4:0] */
429#define WM8985_EQ1G_WIDTH 5 /* EQ1G - [4:0] */
430
431/*
432 * R19 (0x13) - EQ2 - peak 1
433 */
434#define WM8985_EQ2BW 0x0100 /* EQ2BW */
435#define WM8985_EQ2BW_MASK 0x0100 /* EQ2BW */
436#define WM8985_EQ2BW_SHIFT 8 /* EQ2BW */
437#define WM8985_EQ2BW_WIDTH 1 /* EQ2BW */
438#define WM8985_EQ2C_MASK 0x0060 /* EQ2C - [6:5] */
439#define WM8985_EQ2C_SHIFT 5 /* EQ2C - [6:5] */
440#define WM8985_EQ2C_WIDTH 2 /* EQ2C - [6:5] */
441#define WM8985_EQ2G_MASK 0x001F /* EQ2G - [4:0] */
442#define WM8985_EQ2G_SHIFT 0 /* EQ2G - [4:0] */
443#define WM8985_EQ2G_WIDTH 5 /* EQ2G - [4:0] */
444
445/*
446 * R20 (0x14) - EQ3 - peak 2
447 */
448#define WM8985_EQ3BW 0x0100 /* EQ3BW */
449#define WM8985_EQ3BW_MASK 0x0100 /* EQ3BW */
450#define WM8985_EQ3BW_SHIFT 8 /* EQ3BW */
451#define WM8985_EQ3BW_WIDTH 1 /* EQ3BW */
452#define WM8985_EQ3C_MASK 0x0060 /* EQ3C - [6:5] */
453#define WM8985_EQ3C_SHIFT 5 /* EQ3C - [6:5] */
454#define WM8985_EQ3C_WIDTH 2 /* EQ3C - [6:5] */
455#define WM8985_EQ3G_MASK 0x001F /* EQ3G - [4:0] */
456#define WM8985_EQ3G_SHIFT 0 /* EQ3G - [4:0] */
457#define WM8985_EQ3G_WIDTH 5 /* EQ3G - [4:0] */
458
459/*
460 * R21 (0x15) - EQ4 - peak 3
461 */
462#define WM8985_EQ4BW 0x0100 /* EQ4BW */
463#define WM8985_EQ4BW_MASK 0x0100 /* EQ4BW */
464#define WM8985_EQ4BW_SHIFT 8 /* EQ4BW */
465#define WM8985_EQ4BW_WIDTH 1 /* EQ4BW */
466#define WM8985_EQ4C_MASK 0x0060 /* EQ4C - [6:5] */
467#define WM8985_EQ4C_SHIFT 5 /* EQ4C - [6:5] */
468#define WM8985_EQ4C_WIDTH 2 /* EQ4C - [6:5] */
469#define WM8985_EQ4G_MASK 0x001F /* EQ4G - [4:0] */
470#define WM8985_EQ4G_SHIFT 0 /* EQ4G - [4:0] */
471#define WM8985_EQ4G_WIDTH 5 /* EQ4G - [4:0] */
472
473/*
474 * R22 (0x16) - EQ5 - high shelf
475 */
476#define WM8985_EQ5C_MASK 0x0060 /* EQ5C - [6:5] */
477#define WM8985_EQ5C_SHIFT 5 /* EQ5C - [6:5] */
478#define WM8985_EQ5C_WIDTH 2 /* EQ5C - [6:5] */
479#define WM8985_EQ5G_MASK 0x001F /* EQ5G - [4:0] */
480#define WM8985_EQ5G_SHIFT 0 /* EQ5G - [4:0] */
481#define WM8985_EQ5G_WIDTH 5 /* EQ5G - [4:0] */
482
483/*
484 * R24 (0x18) - DAC Limiter 1
485 */
486#define WM8985_LIMEN 0x0100 /* LIMEN */
487#define WM8985_LIMEN_MASK 0x0100 /* LIMEN */
488#define WM8985_LIMEN_SHIFT 8 /* LIMEN */
489#define WM8985_LIMEN_WIDTH 1 /* LIMEN */
490#define WM8985_LIMDCY_MASK 0x00F0 /* LIMDCY - [7:4] */
491#define WM8985_LIMDCY_SHIFT 4 /* LIMDCY - [7:4] */
492#define WM8985_LIMDCY_WIDTH 4 /* LIMDCY - [7:4] */
493#define WM8985_LIMATK_MASK 0x000F /* LIMATK - [3:0] */
494#define WM8985_LIMATK_SHIFT 0 /* LIMATK - [3:0] */
495#define WM8985_LIMATK_WIDTH 4 /* LIMATK - [3:0] */
496
497/*
498 * R25 (0x19) - DAC Limiter 2
499 */
500#define WM8985_LIMLVL_MASK 0x0070 /* LIMLVL - [6:4] */
501#define WM8985_LIMLVL_SHIFT 4 /* LIMLVL - [6:4] */
502#define WM8985_LIMLVL_WIDTH 3 /* LIMLVL - [6:4] */
503#define WM8985_LIMBOOST_MASK 0x000F /* LIMBOOST - [3:0] */
504#define WM8985_LIMBOOST_SHIFT 0 /* LIMBOOST - [3:0] */
505#define WM8985_LIMBOOST_WIDTH 4 /* LIMBOOST - [3:0] */
506
507/*
508 * R27 (0x1B) - Notch Filter 1
509 */
510#define WM8985_NFU 0x0100 /* NFU */
511#define WM8985_NFU_MASK 0x0100 /* NFU */
512#define WM8985_NFU_SHIFT 8 /* NFU */
513#define WM8985_NFU_WIDTH 1 /* NFU */
514#define WM8985_NFEN 0x0080 /* NFEN */
515#define WM8985_NFEN_MASK 0x0080 /* NFEN */
516#define WM8985_NFEN_SHIFT 7 /* NFEN */
517#define WM8985_NFEN_WIDTH 1 /* NFEN */
518#define WM8985_NFA0_13_7_MASK 0x007F /* NFA0(13:7) - [6:0] */
519#define WM8985_NFA0_13_7_SHIFT 0 /* NFA0(13:7) - [6:0] */
520#define WM8985_NFA0_13_7_WIDTH 7 /* NFA0(13:7) - [6:0] */
521
522/*
523 * R28 (0x1C) - Notch Filter 2
524 */
525#define WM8985_NFU 0x0100 /* NFU */
526#define WM8985_NFU_MASK 0x0100 /* NFU */
527#define WM8985_NFU_SHIFT 8 /* NFU */
528#define WM8985_NFU_WIDTH 1 /* NFU */
529#define WM8985_NFA0_6_0_MASK 0x007F /* NFA0(6:0) - [6:0] */
530#define WM8985_NFA0_6_0_SHIFT 0 /* NFA0(6:0) - [6:0] */
531#define WM8985_NFA0_6_0_WIDTH 7 /* NFA0(6:0) - [6:0] */
532
533/*
534 * R29 (0x1D) - Notch Filter 3
535 */
536#define WM8985_NFU 0x0100 /* NFU */
537#define WM8985_NFU_MASK 0x0100 /* NFU */
538#define WM8985_NFU_SHIFT 8 /* NFU */
539#define WM8985_NFU_WIDTH 1 /* NFU */
540#define WM8985_NFA1_13_7_MASK 0x007F /* NFA1(13:7) - [6:0] */
541#define WM8985_NFA1_13_7_SHIFT 0 /* NFA1(13:7) - [6:0] */
542#define WM8985_NFA1_13_7_WIDTH 7 /* NFA1(13:7) - [6:0] */
543
544/*
545 * R30 (0x1E) - Notch Filter 4
546 */
547#define WM8985_NFU 0x0100 /* NFU */
548#define WM8985_NFU_MASK 0x0100 /* NFU */
549#define WM8985_NFU_SHIFT 8 /* NFU */
550#define WM8985_NFU_WIDTH 1 /* NFU */
551#define WM8985_NFA1_6_0_MASK 0x007F /* NFA1(6:0) - [6:0] */
552#define WM8985_NFA1_6_0_SHIFT 0 /* NFA1(6:0) - [6:0] */
553#define WM8985_NFA1_6_0_WIDTH 7 /* NFA1(6:0) - [6:0] */
554
555/*
556 * R32 (0x20) - ALC control 1
557 */
558#define WM8985_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
559#define WM8985_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
560#define WM8985_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
561#define WM8985_ALCMAX_MASK 0x0038 /* ALCMAX - [5:3] */
562#define WM8985_ALCMAX_SHIFT 3 /* ALCMAX - [5:3] */
563#define WM8985_ALCMAX_WIDTH 3 /* ALCMAX - [5:3] */
564#define WM8985_ALCMIN_MASK 0x0007 /* ALCMIN - [2:0] */
565#define WM8985_ALCMIN_SHIFT 0 /* ALCMIN - [2:0] */
566#define WM8985_ALCMIN_WIDTH 3 /* ALCMIN - [2:0] */
567
568/*
569 * R33 (0x21) - ALC control 2
570 */
571#define WM8985_ALCHLD_MASK 0x00F0 /* ALCHLD - [7:4] */
572#define WM8985_ALCHLD_SHIFT 4 /* ALCHLD - [7:4] */
573#define WM8985_ALCHLD_WIDTH 4 /* ALCHLD - [7:4] */
574#define WM8985_ALCLVL_MASK 0x000F /* ALCLVL - [3:0] */
575#define WM8985_ALCLVL_SHIFT 0 /* ALCLVL - [3:0] */
576#define WM8985_ALCLVL_WIDTH 4 /* ALCLVL - [3:0] */
577
578/*
579 * R34 (0x22) - ALC control 3
580 */
581#define WM8985_ALCMODE 0x0100 /* ALCMODE */
582#define WM8985_ALCMODE_MASK 0x0100 /* ALCMODE */
583#define WM8985_ALCMODE_SHIFT 8 /* ALCMODE */
584#define WM8985_ALCMODE_WIDTH 1 /* ALCMODE */
585#define WM8985_ALCDCY_MASK 0x00F0 /* ALCDCY - [7:4] */
586#define WM8985_ALCDCY_SHIFT 4 /* ALCDCY - [7:4] */
587#define WM8985_ALCDCY_WIDTH 4 /* ALCDCY - [7:4] */
588#define WM8985_ALCATK_MASK 0x000F /* ALCATK - [3:0] */
589#define WM8985_ALCATK_SHIFT 0 /* ALCATK - [3:0] */
590#define WM8985_ALCATK_WIDTH 4 /* ALCATK - [3:0] */
591
592/*
593 * R35 (0x23) - Noise Gate
594 */
595#define WM8985_NGEN 0x0008 /* NGEN */
596#define WM8985_NGEN_MASK 0x0008 /* NGEN */
597#define WM8985_NGEN_SHIFT 3 /* NGEN */
598#define WM8985_NGEN_WIDTH 1 /* NGEN */
599#define WM8985_NGTH_MASK 0x0007 /* NGTH - [2:0] */
600#define WM8985_NGTH_SHIFT 0 /* NGTH - [2:0] */
601#define WM8985_NGTH_WIDTH 3 /* NGTH - [2:0] */
602
603/*
604 * R36 (0x24) - PLL N
605 */
606#define WM8985_PLL_PRESCALE 0x0010 /* PLL_PRESCALE */
607#define WM8985_PLL_PRESCALE_MASK 0x0010 /* PLL_PRESCALE */
608#define WM8985_PLL_PRESCALE_SHIFT 4 /* PLL_PRESCALE */
609#define WM8985_PLL_PRESCALE_WIDTH 1 /* PLL_PRESCALE */
610#define WM8985_PLLN_MASK 0x000F /* PLLN - [3:0] */
611#define WM8985_PLLN_SHIFT 0 /* PLLN - [3:0] */
612#define WM8985_PLLN_WIDTH 4 /* PLLN - [3:0] */
613
614/*
615 * R37 (0x25) - PLL K 1
616 */
617#define WM8985_PLLK_23_18_MASK 0x003F /* PLLK(23:18) - [5:0] */
618#define WM8985_PLLK_23_18_SHIFT 0 /* PLLK(23:18) - [5:0] */
619#define WM8985_PLLK_23_18_WIDTH 6 /* PLLK(23:18) - [5:0] */
620
621/*
622 * R38 (0x26) - PLL K 2
623 */
624#define WM8985_PLLK_17_9_MASK 0x01FF /* PLLK(17:9) - [8:0] */
625#define WM8985_PLLK_17_9_SHIFT 0 /* PLLK(17:9) - [8:0] */
626#define WM8985_PLLK_17_9_WIDTH 9 /* PLLK(17:9) - [8:0] */
627
628/*
629 * R39 (0x27) - PLL K 3
630 */
631#define WM8985_PLLK_8_0_MASK 0x01FF /* PLLK(8:0) - [8:0] */
632#define WM8985_PLLK_8_0_SHIFT 0 /* PLLK(8:0) - [8:0] */
633#define WM8985_PLLK_8_0_WIDTH 9 /* PLLK(8:0) - [8:0] */
634
635/*
636 * R41 (0x29) - 3D control
637 */
638#define WM8985_DEPTH3D_MASK 0x000F /* DEPTH3D - [3:0] */
639#define WM8985_DEPTH3D_SHIFT 0 /* DEPTH3D - [3:0] */
640#define WM8985_DEPTH3D_WIDTH 4 /* DEPTH3D - [3:0] */
641
642/*
643 * R42 (0x2A) - OUT4 to ADC
644 */
645#define WM8985_OUT4_2ADCVOL_MASK 0x01C0 /* OUT4_2ADCVOL - [8:6] */
646#define WM8985_OUT4_2ADCVOL_SHIFT 6 /* OUT4_2ADCVOL - [8:6] */
647#define WM8985_OUT4_2ADCVOL_WIDTH 3 /* OUT4_2ADCVOL - [8:6] */
648#define WM8985_OUT4_2LNR 0x0020 /* OUT4_2LNR */
649#define WM8985_OUT4_2LNR_MASK 0x0020 /* OUT4_2LNR */
650#define WM8985_OUT4_2LNR_SHIFT 5 /* OUT4_2LNR */
651#define WM8985_OUT4_2LNR_WIDTH 1 /* OUT4_2LNR */
652#define WM8985_POBCTRL 0x0004 /* POBCTRL */
653#define WM8985_POBCTRL_MASK 0x0004 /* POBCTRL */
654#define WM8985_POBCTRL_SHIFT 2 /* POBCTRL */
655#define WM8985_POBCTRL_WIDTH 1 /* POBCTRL */
656#define WM8985_DELEN 0x0002 /* DELEN */
657#define WM8985_DELEN_MASK 0x0002 /* DELEN */
658#define WM8985_DELEN_SHIFT 1 /* DELEN */
659#define WM8985_DELEN_WIDTH 1 /* DELEN */
660#define WM8985_OUT1DEL 0x0001 /* OUT1DEL */
661#define WM8985_OUT1DEL_MASK 0x0001 /* OUT1DEL */
662#define WM8985_OUT1DEL_SHIFT 0 /* OUT1DEL */
663#define WM8985_OUT1DEL_WIDTH 1 /* OUT1DEL */
664
665/*
666 * R43 (0x2B) - Beep control
667 */
668#define WM8985_BYPL2RMIX 0x0100 /* BYPL2RMIX */
669#define WM8985_BYPL2RMIX_MASK 0x0100 /* BYPL2RMIX */
670#define WM8985_BYPL2RMIX_SHIFT 8 /* BYPL2RMIX */
671#define WM8985_BYPL2RMIX_WIDTH 1 /* BYPL2RMIX */
672#define WM8985_BYPR2LMIX 0x0080 /* BYPR2LMIX */
673#define WM8985_BYPR2LMIX_MASK 0x0080 /* BYPR2LMIX */
674#define WM8985_BYPR2LMIX_SHIFT 7 /* BYPR2LMIX */
675#define WM8985_BYPR2LMIX_WIDTH 1 /* BYPR2LMIX */
676#define WM8985_MUTERPGA2INV 0x0020 /* MUTERPGA2INV */
677#define WM8985_MUTERPGA2INV_MASK 0x0020 /* MUTERPGA2INV */
678#define WM8985_MUTERPGA2INV_SHIFT 5 /* MUTERPGA2INV */
679#define WM8985_MUTERPGA2INV_WIDTH 1 /* MUTERPGA2INV */
680#define WM8985_INVROUT2 0x0010 /* INVROUT2 */
681#define WM8985_INVROUT2_MASK 0x0010 /* INVROUT2 */
682#define WM8985_INVROUT2_SHIFT 4 /* INVROUT2 */
683#define WM8985_INVROUT2_WIDTH 1 /* INVROUT2 */
684#define WM8985_BEEPVOL_MASK 0x000E /* BEEPVOL - [3:1] */
685#define WM8985_BEEPVOL_SHIFT 1 /* BEEPVOL - [3:1] */
686#define WM8985_BEEPVOL_WIDTH 3 /* BEEPVOL - [3:1] */
687#define WM8985_BEEPEN 0x0001 /* BEEPEN */
688#define WM8985_BEEPEN_MASK 0x0001 /* BEEPEN */
689#define WM8985_BEEPEN_SHIFT 0 /* BEEPEN */
690#define WM8985_BEEPEN_WIDTH 1 /* BEEPEN */
691
692/*
693 * R44 (0x2C) - Input ctrl
694 */
695#define WM8985_MBVSEL 0x0100 /* MBVSEL */
696#define WM8985_MBVSEL_MASK 0x0100 /* MBVSEL */
697#define WM8985_MBVSEL_SHIFT 8 /* MBVSEL */
698#define WM8985_MBVSEL_WIDTH 1 /* MBVSEL */
699#define WM8985_R2_2INPPGA 0x0040 /* R2_2INPPGA */
700#define WM8985_R2_2INPPGA_MASK 0x0040 /* R2_2INPPGA */
701#define WM8985_R2_2INPPGA_SHIFT 6 /* R2_2INPPGA */
702#define WM8985_R2_2INPPGA_WIDTH 1 /* R2_2INPPGA */
703#define WM8985_RIN2INPPGA 0x0020 /* RIN2INPPGA */
704#define WM8985_RIN2INPPGA_MASK 0x0020 /* RIN2INPPGA */
705#define WM8985_RIN2INPPGA_SHIFT 5 /* RIN2INPPGA */
706#define WM8985_RIN2INPPGA_WIDTH 1 /* RIN2INPPGA */
707#define WM8985_RIP2INPPGA 0x0010 /* RIP2INPPGA */
708#define WM8985_RIP2INPPGA_MASK 0x0010 /* RIP2INPPGA */
709#define WM8985_RIP2INPPGA_SHIFT 4 /* RIP2INPPGA */
710#define WM8985_RIP2INPPGA_WIDTH 1 /* RIP2INPPGA */
711#define WM8985_L2_2INPPGA 0x0004 /* L2_2INPPGA */
712#define WM8985_L2_2INPPGA_MASK 0x0004 /* L2_2INPPGA */
713#define WM8985_L2_2INPPGA_SHIFT 2 /* L2_2INPPGA */
714#define WM8985_L2_2INPPGA_WIDTH 1 /* L2_2INPPGA */
715#define WM8985_LIN2INPPGA 0x0002 /* LIN2INPPGA */
716#define WM8985_LIN2INPPGA_MASK 0x0002 /* LIN2INPPGA */
717#define WM8985_LIN2INPPGA_SHIFT 1 /* LIN2INPPGA */
718#define WM8985_LIN2INPPGA_WIDTH 1 /* LIN2INPPGA */
719#define WM8985_LIP2INPPGA 0x0001 /* LIP2INPPGA */
720#define WM8985_LIP2INPPGA_MASK 0x0001 /* LIP2INPPGA */
721#define WM8985_LIP2INPPGA_SHIFT 0 /* LIP2INPPGA */
722#define WM8985_LIP2INPPGA_WIDTH 1 /* LIP2INPPGA */
723
724/*
725 * R45 (0x2D) - Left INP PGA gain ctrl
726 */
727#define WM8985_INPGAVU 0x0100 /* INPGAVU */
728#define WM8985_INPGAVU_MASK 0x0100 /* INPGAVU */
729#define WM8985_INPGAVU_SHIFT 8 /* INPGAVU */
730#define WM8985_INPGAVU_WIDTH 1 /* INPGAVU */
731#define WM8985_INPPGAZCL 0x0080 /* INPPGAZCL */
732#define WM8985_INPPGAZCL_MASK 0x0080 /* INPPGAZCL */
733#define WM8985_INPPGAZCL_SHIFT 7 /* INPPGAZCL */
734#define WM8985_INPPGAZCL_WIDTH 1 /* INPPGAZCL */
735#define WM8985_INPPGAMUTEL 0x0040 /* INPPGAMUTEL */
736#define WM8985_INPPGAMUTEL_MASK 0x0040 /* INPPGAMUTEL */
737#define WM8985_INPPGAMUTEL_SHIFT 6 /* INPPGAMUTEL */
738#define WM8985_INPPGAMUTEL_WIDTH 1 /* INPPGAMUTEL */
739#define WM8985_INPPGAVOLL_MASK 0x003F /* INPPGAVOLL - [5:0] */
740#define WM8985_INPPGAVOLL_SHIFT 0 /* INPPGAVOLL - [5:0] */
741#define WM8985_INPPGAVOLL_WIDTH 6 /* INPPGAVOLL - [5:0] */
742
743/*
744 * R46 (0x2E) - Right INP PGA gain ctrl
745 */
746#define WM8985_INPGAVU 0x0100 /* INPGAVU */
747#define WM8985_INPGAVU_MASK 0x0100 /* INPGAVU */
748#define WM8985_INPGAVU_SHIFT 8 /* INPGAVU */
749#define WM8985_INPGAVU_WIDTH 1 /* INPGAVU */
750#define WM8985_INPPGAZCR 0x0080 /* INPPGAZCR */
751#define WM8985_INPPGAZCR_MASK 0x0080 /* INPPGAZCR */
752#define WM8985_INPPGAZCR_SHIFT 7 /* INPPGAZCR */
753#define WM8985_INPPGAZCR_WIDTH 1 /* INPPGAZCR */
754#define WM8985_INPPGAMUTER 0x0040 /* INPPGAMUTER */
755#define WM8985_INPPGAMUTER_MASK 0x0040 /* INPPGAMUTER */
756#define WM8985_INPPGAMUTER_SHIFT 6 /* INPPGAMUTER */
757#define WM8985_INPPGAMUTER_WIDTH 1 /* INPPGAMUTER */
758#define WM8985_INPPGAVOLR_MASK 0x003F /* INPPGAVOLR - [5:0] */
759#define WM8985_INPPGAVOLR_SHIFT 0 /* INPPGAVOLR - [5:0] */
760#define WM8985_INPPGAVOLR_WIDTH 6 /* INPPGAVOLR - [5:0] */
761
762/*
763 * R47 (0x2F) - Left ADC BOOST ctrl
764 */
765#define WM8985_PGABOOSTL 0x0100 /* PGABOOSTL */
766#define WM8985_PGABOOSTL_MASK 0x0100 /* PGABOOSTL */
767#define WM8985_PGABOOSTL_SHIFT 8 /* PGABOOSTL */
768#define WM8985_PGABOOSTL_WIDTH 1 /* PGABOOSTL */
769#define WM8985_L2_2BOOSTVOL_MASK 0x0070 /* L2_2BOOSTVOL - [6:4] */
770#define WM8985_L2_2BOOSTVOL_SHIFT 4 /* L2_2BOOSTVOL - [6:4] */
771#define WM8985_L2_2BOOSTVOL_WIDTH 3 /* L2_2BOOSTVOL - [6:4] */
772#define WM8985_AUXL2BOOSTVOL_MASK 0x0007 /* AUXL2BOOSTVOL - [2:0] */
773#define WM8985_AUXL2BOOSTVOL_SHIFT 0 /* AUXL2BOOSTVOL - [2:0] */
774#define WM8985_AUXL2BOOSTVOL_WIDTH 3 /* AUXL2BOOSTVOL - [2:0] */
775
776/*
777 * R48 (0x30) - Right ADC BOOST ctrl
778 */
779#define WM8985_PGABOOSTR 0x0100 /* PGABOOSTR */
780#define WM8985_PGABOOSTR_MASK 0x0100 /* PGABOOSTR */
781#define WM8985_PGABOOSTR_SHIFT 8 /* PGABOOSTR */
782#define WM8985_PGABOOSTR_WIDTH 1 /* PGABOOSTR */
783#define WM8985_R2_2BOOSTVOL_MASK 0x0070 /* R2_2BOOSTVOL - [6:4] */
784#define WM8985_R2_2BOOSTVOL_SHIFT 4 /* R2_2BOOSTVOL - [6:4] */
785#define WM8985_R2_2BOOSTVOL_WIDTH 3 /* R2_2BOOSTVOL - [6:4] */
786#define WM8985_AUXR2BOOSTVOL_MASK 0x0007 /* AUXR2BOOSTVOL - [2:0] */
787#define WM8985_AUXR2BOOSTVOL_SHIFT 0 /* AUXR2BOOSTVOL - [2:0] */
788#define WM8985_AUXR2BOOSTVOL_WIDTH 3 /* AUXR2BOOSTVOL - [2:0] */
789
790/*
791 * R49 (0x31) - Output ctrl
792 */
793#define WM8985_DACL2RMIX 0x0040 /* DACL2RMIX */
794#define WM8985_DACL2RMIX_MASK 0x0040 /* DACL2RMIX */
795#define WM8985_DACL2RMIX_SHIFT 6 /* DACL2RMIX */
796#define WM8985_DACL2RMIX_WIDTH 1 /* DACL2RMIX */
797#define WM8985_DACR2LMIX 0x0020 /* DACR2LMIX */
798#define WM8985_DACR2LMIX_MASK 0x0020 /* DACR2LMIX */
799#define WM8985_DACR2LMIX_SHIFT 5 /* DACR2LMIX */
800#define WM8985_DACR2LMIX_WIDTH 1 /* DACR2LMIX */
801#define WM8985_OUT4BOOST 0x0010 /* OUT4BOOST */
802#define WM8985_OUT4BOOST_MASK 0x0010 /* OUT4BOOST */
803#define WM8985_OUT4BOOST_SHIFT 4 /* OUT4BOOST */
804#define WM8985_OUT4BOOST_WIDTH 1 /* OUT4BOOST */
805#define WM8985_OUT3BOOST 0x0008 /* OUT3BOOST */
806#define WM8985_OUT3BOOST_MASK 0x0008 /* OUT3BOOST */
807#define WM8985_OUT3BOOST_SHIFT 3 /* OUT3BOOST */
808#define WM8985_OUT3BOOST_WIDTH 1 /* OUT3BOOST */
809#define WM8985_TSOPCTRL 0x0004 /* TSOPCTRL */
810#define WM8985_TSOPCTRL_MASK 0x0004 /* TSOPCTRL */
811#define WM8985_TSOPCTRL_SHIFT 2 /* TSOPCTRL */
812#define WM8985_TSOPCTRL_WIDTH 1 /* TSOPCTRL */
813#define WM8985_TSDEN 0x0002 /* TSDEN */
814#define WM8985_TSDEN_MASK 0x0002 /* TSDEN */
815#define WM8985_TSDEN_SHIFT 1 /* TSDEN */
816#define WM8985_TSDEN_WIDTH 1 /* TSDEN */
817#define WM8985_VROI 0x0001 /* VROI */
818#define WM8985_VROI_MASK 0x0001 /* VROI */
819#define WM8985_VROI_SHIFT 0 /* VROI */
820#define WM8985_VROI_WIDTH 1 /* VROI */
821
822/*
823 * R50 (0x32) - Left mixer ctrl
824 */
825#define WM8985_AUXLMIXVOL_MASK 0x01C0 /* AUXLMIXVOL - [8:6] */
826#define WM8985_AUXLMIXVOL_SHIFT 6 /* AUXLMIXVOL - [8:6] */
827#define WM8985_AUXLMIXVOL_WIDTH 3 /* AUXLMIXVOL - [8:6] */
828#define WM8985_AUXL2LMIX 0x0020 /* AUXL2LMIX */
829#define WM8985_AUXL2LMIX_MASK 0x0020 /* AUXL2LMIX */
830#define WM8985_AUXL2LMIX_SHIFT 5 /* AUXL2LMIX */
831#define WM8985_AUXL2LMIX_WIDTH 1 /* AUXL2LMIX */
832#define WM8985_BYPLMIXVOL_MASK 0x001C /* BYPLMIXVOL - [4:2] */
833#define WM8985_BYPLMIXVOL_SHIFT 2 /* BYPLMIXVOL - [4:2] */
834#define WM8985_BYPLMIXVOL_WIDTH 3 /* BYPLMIXVOL - [4:2] */
835#define WM8985_BYPL2LMIX 0x0002 /* BYPL2LMIX */
836#define WM8985_BYPL2LMIX_MASK 0x0002 /* BYPL2LMIX */
837#define WM8985_BYPL2LMIX_SHIFT 1 /* BYPL2LMIX */
838#define WM8985_BYPL2LMIX_WIDTH 1 /* BYPL2LMIX */
839#define WM8985_DACL2LMIX 0x0001 /* DACL2LMIX */
840#define WM8985_DACL2LMIX_MASK 0x0001 /* DACL2LMIX */
841#define WM8985_DACL2LMIX_SHIFT 0 /* DACL2LMIX */
842#define WM8985_DACL2LMIX_WIDTH 1 /* DACL2LMIX */
843
844/*
845 * R51 (0x33) - Right mixer ctrl
846 */
847#define WM8985_AUXRMIXVOL_MASK 0x01C0 /* AUXRMIXVOL - [8:6] */
848#define WM8985_AUXRMIXVOL_SHIFT 6 /* AUXRMIXVOL - [8:6] */
849#define WM8985_AUXRMIXVOL_WIDTH 3 /* AUXRMIXVOL - [8:6] */
850#define WM8985_AUXR2RMIX 0x0020 /* AUXR2RMIX */
851#define WM8985_AUXR2RMIX_MASK 0x0020 /* AUXR2RMIX */
852#define WM8985_AUXR2RMIX_SHIFT 5 /* AUXR2RMIX */
853#define WM8985_AUXR2RMIX_WIDTH 1 /* AUXR2RMIX */
854#define WM8985_BYPRMIXVOL_MASK 0x001C /* BYPRMIXVOL - [4:2] */
855#define WM8985_BYPRMIXVOL_SHIFT 2 /* BYPRMIXVOL - [4:2] */
856#define WM8985_BYPRMIXVOL_WIDTH 3 /* BYPRMIXVOL - [4:2] */
857#define WM8985_BYPR2RMIX 0x0002 /* BYPR2RMIX */
858#define WM8985_BYPR2RMIX_MASK 0x0002 /* BYPR2RMIX */
859#define WM8985_BYPR2RMIX_SHIFT 1 /* BYPR2RMIX */
860#define WM8985_BYPR2RMIX_WIDTH 1 /* BYPR2RMIX */
861#define WM8985_DACR2RMIX 0x0001 /* DACR2RMIX */
862#define WM8985_DACR2RMIX_MASK 0x0001 /* DACR2RMIX */
863#define WM8985_DACR2RMIX_SHIFT 0 /* DACR2RMIX */
864#define WM8985_DACR2RMIX_WIDTH 1 /* DACR2RMIX */
865
866/*
867 * R52 (0x34) - LOUT1 (HP) volume ctrl
868 */
869#define WM8985_OUT1VU 0x0100 /* OUT1VU */
870#define WM8985_OUT1VU_MASK 0x0100 /* OUT1VU */
871#define WM8985_OUT1VU_SHIFT 8 /* OUT1VU */
872#define WM8985_OUT1VU_WIDTH 1 /* OUT1VU */
873#define WM8985_LOUT1ZC 0x0080 /* LOUT1ZC */
874#define WM8985_LOUT1ZC_MASK 0x0080 /* LOUT1ZC */
875#define WM8985_LOUT1ZC_SHIFT 7 /* LOUT1ZC */
876#define WM8985_LOUT1ZC_WIDTH 1 /* LOUT1ZC */
877#define WM8985_LOUT1MUTE 0x0040 /* LOUT1MUTE */
878#define WM8985_LOUT1MUTE_MASK 0x0040 /* LOUT1MUTE */
879#define WM8985_LOUT1MUTE_SHIFT 6 /* LOUT1MUTE */
880#define WM8985_LOUT1MUTE_WIDTH 1 /* LOUT1MUTE */
881#define WM8985_LOUT1VOL_MASK 0x003F /* LOUT1VOL - [5:0] */
882#define WM8985_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [5:0] */
883#define WM8985_LOUT1VOL_WIDTH 6 /* LOUT1VOL - [5:0] */
884
885/*
886 * R53 (0x35) - ROUT1 (HP) volume ctrl
887 */
888#define WM8985_OUT1VU 0x0100 /* OUT1VU */
889#define WM8985_OUT1VU_MASK 0x0100 /* OUT1VU */
890#define WM8985_OUT1VU_SHIFT 8 /* OUT1VU */
891#define WM8985_OUT1VU_WIDTH 1 /* OUT1VU */
892#define WM8985_ROUT1ZC 0x0080 /* ROUT1ZC */
893#define WM8985_ROUT1ZC_MASK 0x0080 /* ROUT1ZC */
894#define WM8985_ROUT1ZC_SHIFT 7 /* ROUT1ZC */
895#define WM8985_ROUT1ZC_WIDTH 1 /* ROUT1ZC */
896#define WM8985_ROUT1MUTE 0x0040 /* ROUT1MUTE */
897#define WM8985_ROUT1MUTE_MASK 0x0040 /* ROUT1MUTE */
898#define WM8985_ROUT1MUTE_SHIFT 6 /* ROUT1MUTE */
899#define WM8985_ROUT1MUTE_WIDTH 1 /* ROUT1MUTE */
900#define WM8985_ROUT1VOL_MASK 0x003F /* ROUT1VOL - [5:0] */
901#define WM8985_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [5:0] */
902#define WM8985_ROUT1VOL_WIDTH 6 /* ROUT1VOL - [5:0] */
903
904/*
905 * R54 (0x36) - LOUT2 (SPK) volume ctrl
906 */
907#define WM8985_OUT2VU 0x0100 /* OUT2VU */
908#define WM8985_OUT2VU_MASK 0x0100 /* OUT2VU */
909#define WM8985_OUT2VU_SHIFT 8 /* OUT2VU */
910#define WM8985_OUT2VU_WIDTH 1 /* OUT2VU */
911#define WM8985_LOUT2ZC 0x0080 /* LOUT2ZC */
912#define WM8985_LOUT2ZC_MASK 0x0080 /* LOUT2ZC */
913#define WM8985_LOUT2ZC_SHIFT 7 /* LOUT2ZC */
914#define WM8985_LOUT2ZC_WIDTH 1 /* LOUT2ZC */
915#define WM8985_LOUT2MUTE 0x0040 /* LOUT2MUTE */
916#define WM8985_LOUT2MUTE_MASK 0x0040 /* LOUT2MUTE */
917#define WM8985_LOUT2MUTE_SHIFT 6 /* LOUT2MUTE */
918#define WM8985_LOUT2MUTE_WIDTH 1 /* LOUT2MUTE */
919#define WM8985_LOUT2VOL_MASK 0x003F /* LOUT2VOL - [5:0] */
920#define WM8985_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [5:0] */
921#define WM8985_LOUT2VOL_WIDTH 6 /* LOUT2VOL - [5:0] */
922
923/*
924 * R55 (0x37) - ROUT2 (SPK) volume ctrl
925 */
926#define WM8985_OUT2VU 0x0100 /* OUT2VU */
927#define WM8985_OUT2VU_MASK 0x0100 /* OUT2VU */
928#define WM8985_OUT2VU_SHIFT 8 /* OUT2VU */
929#define WM8985_OUT2VU_WIDTH 1 /* OUT2VU */
930#define WM8985_ROUT2ZC 0x0080 /* ROUT2ZC */
931#define WM8985_ROUT2ZC_MASK 0x0080 /* ROUT2ZC */
932#define WM8985_ROUT2ZC_SHIFT 7 /* ROUT2ZC */
933#define WM8985_ROUT2ZC_WIDTH 1 /* ROUT2ZC */
934#define WM8985_ROUT2MUTE 0x0040 /* ROUT2MUTE */
935#define WM8985_ROUT2MUTE_MASK 0x0040 /* ROUT2MUTE */
936#define WM8985_ROUT2MUTE_SHIFT 6 /* ROUT2MUTE */
937#define WM8985_ROUT2MUTE_WIDTH 1 /* ROUT2MUTE */
938#define WM8985_ROUT2VOL_MASK 0x003F /* ROUT2VOL - [5:0] */
939#define WM8985_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [5:0] */
940#define WM8985_ROUT2VOL_WIDTH 6 /* ROUT2VOL - [5:0] */
941
942/*
943 * R56 (0x38) - OUT3 mixer ctrl
944 */
945#define WM8985_OUT3MUTE 0x0040 /* OUT3MUTE */
946#define WM8985_OUT3MUTE_MASK 0x0040 /* OUT3MUTE */
947#define WM8985_OUT3MUTE_SHIFT 6 /* OUT3MUTE */
948#define WM8985_OUT3MUTE_WIDTH 1 /* OUT3MUTE */
949#define WM8985_OUT4_2OUT3 0x0008 /* OUT4_2OUT3 */
950#define WM8985_OUT4_2OUT3_MASK 0x0008 /* OUT4_2OUT3 */
951#define WM8985_OUT4_2OUT3_SHIFT 3 /* OUT4_2OUT3 */
952#define WM8985_OUT4_2OUT3_WIDTH 1 /* OUT4_2OUT3 */
953#define WM8985_BYPL2OUT3 0x0004 /* BYPL2OUT3 */
954#define WM8985_BYPL2OUT3_MASK 0x0004 /* BYPL2OUT3 */
955#define WM8985_BYPL2OUT3_SHIFT 2 /* BYPL2OUT3 */
956#define WM8985_BYPL2OUT3_WIDTH 1 /* BYPL2OUT3 */
957#define WM8985_LMIX2OUT3 0x0002 /* LMIX2OUT3 */
958#define WM8985_LMIX2OUT3_MASK 0x0002 /* LMIX2OUT3 */
959#define WM8985_LMIX2OUT3_SHIFT 1 /* LMIX2OUT3 */
960#define WM8985_LMIX2OUT3_WIDTH 1 /* LMIX2OUT3 */
961#define WM8985_LDAC2OUT3 0x0001 /* LDAC2OUT3 */
962#define WM8985_LDAC2OUT3_MASK 0x0001 /* LDAC2OUT3 */
963#define WM8985_LDAC2OUT3_SHIFT 0 /* LDAC2OUT3 */
964#define WM8985_LDAC2OUT3_WIDTH 1 /* LDAC2OUT3 */
965
966/*
967 * R57 (0x39) - OUT4 (MONO) mix ctrl
968 */
969#define WM8985_OUT3_2OUT4 0x0080 /* OUT3_2OUT4 */
970#define WM8985_OUT3_2OUT4_MASK 0x0080 /* OUT3_2OUT4 */
971#define WM8985_OUT3_2OUT4_SHIFT 7 /* OUT3_2OUT4 */
972#define WM8985_OUT3_2OUT4_WIDTH 1 /* OUT3_2OUT4 */
973#define WM8985_OUT4MUTE 0x0040 /* OUT4MUTE */
974#define WM8985_OUT4MUTE_MASK 0x0040 /* OUT4MUTE */
975#define WM8985_OUT4MUTE_SHIFT 6 /* OUT4MUTE */
976#define WM8985_OUT4MUTE_WIDTH 1 /* OUT4MUTE */
977#define WM8985_OUT4ATTN 0x0020 /* OUT4ATTN */
978#define WM8985_OUT4ATTN_MASK 0x0020 /* OUT4ATTN */
979#define WM8985_OUT4ATTN_SHIFT 5 /* OUT4ATTN */
980#define WM8985_OUT4ATTN_WIDTH 1 /* OUT4ATTN */
981#define WM8985_LMIX2OUT4 0x0010 /* LMIX2OUT4 */
982#define WM8985_LMIX2OUT4_MASK 0x0010 /* LMIX2OUT4 */
983#define WM8985_LMIX2OUT4_SHIFT 4 /* LMIX2OUT4 */
984#define WM8985_LMIX2OUT4_WIDTH 1 /* LMIX2OUT4 */
985#define WM8985_LDAC2OUT4 0x0008 /* LDAC2OUT4 */
986#define WM8985_LDAC2OUT4_MASK 0x0008 /* LDAC2OUT4 */
987#define WM8985_LDAC2OUT4_SHIFT 3 /* LDAC2OUT4 */
988#define WM8985_LDAC2OUT4_WIDTH 1 /* LDAC2OUT4 */
989#define WM8985_BYPR2OUT4 0x0004 /* BYPR2OUT4 */
990#define WM8985_BYPR2OUT4_MASK 0x0004 /* BYPR2OUT4 */
991#define WM8985_BYPR2OUT4_SHIFT 2 /* BYPR2OUT4 */
992#define WM8985_BYPR2OUT4_WIDTH 1 /* BYPR2OUT4 */
993#define WM8985_RMIX2OUT4 0x0002 /* RMIX2OUT4 */
994#define WM8985_RMIX2OUT4_MASK 0x0002 /* RMIX2OUT4 */
995#define WM8985_RMIX2OUT4_SHIFT 1 /* RMIX2OUT4 */
996#define WM8985_RMIX2OUT4_WIDTH 1 /* RMIX2OUT4 */
997#define WM8985_RDAC2OUT4 0x0001 /* RDAC2OUT4 */
998#define WM8985_RDAC2OUT4_MASK 0x0001 /* RDAC2OUT4 */
999#define WM8985_RDAC2OUT4_SHIFT 0 /* RDAC2OUT4 */
1000#define WM8985_RDAC2OUT4_WIDTH 1 /* RDAC2OUT4 */
1001
1002/*
1003 * R60 (0x3C) - OUTPUT ctrl
1004 */
1005#define WM8985_VIDBUFFTST_MASK 0x01E0 /* VIDBUFFTST - [8:5] */
1006#define WM8985_VIDBUFFTST_SHIFT 5 /* VIDBUFFTST - [8:5] */
1007#define WM8985_VIDBUFFTST_WIDTH 4 /* VIDBUFFTST - [8:5] */
1008#define WM8985_HPTOG 0x0008 /* HPTOG */
1009#define WM8985_HPTOG_MASK 0x0008 /* HPTOG */
1010#define WM8985_HPTOG_SHIFT 3 /* HPTOG */
1011#define WM8985_HPTOG_WIDTH 1 /* HPTOG */
1012
1013/*
1014 * R61 (0x3D) - BIAS CTRL
1015 */
1016#define WM8985_BIASCUT 0x0100 /* BIASCUT */
1017#define WM8985_BIASCUT_MASK 0x0100 /* BIASCUT */
1018#define WM8985_BIASCUT_SHIFT 8 /* BIASCUT */
1019#define WM8985_BIASCUT_WIDTH 1 /* BIASCUT */
1020#define WM8985_HALFIPBIAS 0x0080 /* HALFIPBIAS */
1021#define WM8985_HALFIPBIAS_MASK 0x0080 /* HALFIPBIAS */
1022#define WM8985_HALFIPBIAS_SHIFT 7 /* HALFIPBIAS */
1023#define WM8985_HALFIPBIAS_WIDTH 1 /* HALFIPBIAS */
1024#define WM8985_VBBIASTST_MASK 0x0060 /* VBBIASTST - [6:5] */
1025#define WM8985_VBBIASTST_SHIFT 5 /* VBBIASTST - [6:5] */
1026#define WM8985_VBBIASTST_WIDTH 2 /* VBBIASTST - [6:5] */
1027#define WM8985_BUFBIAS_MASK 0x0018 /* BUFBIAS - [4:3] */
1028#define WM8985_BUFBIAS_SHIFT 3 /* BUFBIAS - [4:3] */
1029#define WM8985_BUFBIAS_WIDTH 2 /* BUFBIAS - [4:3] */
1030#define WM8985_ADCBIAS_MASK 0x0006 /* ADCBIAS - [2:1] */
1031#define WM8985_ADCBIAS_SHIFT 1 /* ADCBIAS - [2:1] */
1032#define WM8985_ADCBIAS_WIDTH 2 /* ADCBIAS - [2:1] */
1033#define WM8985_HALFOPBIAS 0x0001 /* HALFOPBIAS */
1034#define WM8985_HALFOPBIAS_MASK 0x0001 /* HALFOPBIAS */
1035#define WM8985_HALFOPBIAS_SHIFT 0 /* HALFOPBIAS */
1036#define WM8985_HALFOPBIAS_WIDTH 1 /* HALFOPBIAS */
1037
1038enum clk_src {
1039 WM8985_CLKSRC_MCLK,
1040 WM8985_CLKSRC_PLL
1041};
1042
1043#define WM8985_PLL 0
1044
1045#endif
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 19ad590ca0b3..d7170f1381aa 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -25,7 +25,6 @@
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31#include "wm8988.h" 30#include "wm8988.h"
@@ -52,9 +51,8 @@ static const u16 wm8988_reg[] = {
52/* codec private data */ 51/* codec private data */
53struct wm8988_priv { 52struct wm8988_priv {
54 unsigned int sysclk; 53 unsigned int sysclk;
55 struct snd_soc_codec codec; 54 enum snd_soc_control_type control_type;
56 struct snd_pcm_hw_constraint_list *sysclk_constraints; 55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
57 u16 reg_cache[WM8988_NUM_REG];
58}; 56};
59 57
60 58
@@ -608,8 +606,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
608 struct snd_soc_dai *dai) 606 struct snd_soc_dai *dai)
609{ 607{
610 struct snd_soc_pcm_runtime *rtd = substream->private_data; 608 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_device *socdev = rtd->socdev; 609 struct snd_soc_codec *codec = rtd->codec;
612 struct snd_soc_codec *codec = socdev->card->codec;
613 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 610 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
614 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3; 611 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
615 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180; 612 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
@@ -678,7 +675,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
678 break; 675 break;
679 676
680 case SND_SOC_BIAS_STANDBY: 677 case SND_SOC_BIAS_STANDBY:
681 if (codec->bias_level == SND_SOC_BIAS_OFF) { 678 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
682 /* VREF, VMID=2x5k */ 679 /* VREF, VMID=2x5k */
683 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
684 681
@@ -694,7 +691,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
694 snd_soc_write(codec, WM8988_PWR1, 0x0000); 691 snd_soc_write(codec, WM8988_PWR1, 0x0000);
695 break; 692 break;
696 } 693 }
697 codec->bias_level = level; 694 codec->dapm.bias_level = level;
698 return 0; 695 return 0;
699} 696}
700 697
@@ -711,8 +708,8 @@ static struct snd_soc_dai_ops wm8988_ops = {
711 .digital_mute = wm8988_mute, 708 .digital_mute = wm8988_mute,
712}; 709};
713 710
714struct snd_soc_dai wm8988_dai = { 711static struct snd_soc_dai_driver wm8988_dai = {
715 .name = "WM8988", 712 .name = "wm8988-hifi",
716 .playback = { 713 .playback = {
717 .stream_name = "Playback", 714 .stream_name = "Playback",
718 .channels_min = 1, 715 .channels_min = 1,
@@ -730,21 +727,15 @@ struct snd_soc_dai wm8988_dai = {
730 .ops = &wm8988_ops, 727 .ops = &wm8988_ops,
731 .symmetric_rates = 1, 728 .symmetric_rates = 1,
732}; 729};
733EXPORT_SYMBOL_GPL(wm8988_dai);
734 730
735static int wm8988_suspend(struct platform_device *pdev, pm_message_t state) 731static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state)
736{ 732{
737 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
738 struct snd_soc_codec *codec = socdev->card->codec;
739
740 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 733 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
741 return 0; 734 return 0;
742} 735}
743 736
744static int wm8988_resume(struct platform_device *pdev) 737static int wm8988_resume(struct snd_soc_codec *codec)
745{ 738{
746 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
747 struct snd_soc_codec *codec = socdev->card->codec;
748 int i; 739 int i;
749 u8 data[2]; 740 u8 data[2];
750 u16 *cache = codec->reg_cache; 741 u16 *cache = codec->reg_cache;
@@ -763,99 +754,23 @@ static int wm8988_resume(struct platform_device *pdev)
763 return 0; 754 return 0;
764} 755}
765 756
766static struct snd_soc_codec *wm8988_codec; 757static int wm8988_probe(struct snd_soc_codec *codec)
767
768static int wm8988_probe(struct platform_device *pdev)
769{ 758{
770 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 759 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
771 struct snd_soc_codec *codec; 760 struct snd_soc_dapm_context *dapm = &codec->dapm;
772 int ret = 0; 761 int ret = 0;
773
774 if (wm8988_codec == NULL) {
775 dev_err(&pdev->dev, "Codec device not registered\n");
776 return -ENODEV;
777 }
778
779 socdev->card->codec = wm8988_codec;
780 codec = wm8988_codec;
781
782 /* register pcms */
783 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
784 if (ret < 0) {
785 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
786 goto pcm_err;
787 }
788
789 snd_soc_add_controls(codec, wm8988_snd_controls,
790 ARRAY_SIZE(wm8988_snd_controls));
791 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
792 ARRAY_SIZE(wm8988_dapm_widgets));
793 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
794
795 return ret;
796
797pcm_err:
798 return ret;
799}
800
801static int wm8988_remove(struct platform_device *pdev)
802{
803 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
804
805 snd_soc_free_pcms(socdev);
806 snd_soc_dapm_free(socdev);
807
808 return 0;
809}
810
811struct snd_soc_codec_device soc_codec_dev_wm8988 = {
812 .probe = wm8988_probe,
813 .remove = wm8988_remove,
814 .suspend = wm8988_suspend,
815 .resume = wm8988_resume,
816};
817EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
818
819static int wm8988_register(struct wm8988_priv *wm8988,
820 enum snd_soc_control_type control)
821{
822 struct snd_soc_codec *codec = &wm8988->codec;
823 int ret;
824 u16 reg; 762 u16 reg;
825 763
826 if (wm8988_codec) { 764 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
827 dev_err(codec->dev, "Another WM8988 is registered\n");
828 ret = -EINVAL;
829 goto err;
830 }
831
832 mutex_init(&codec->mutex);
833 INIT_LIST_HEAD(&codec->dapm_widgets);
834 INIT_LIST_HEAD(&codec->dapm_paths);
835
836 snd_soc_codec_set_drvdata(codec, wm8988);
837 codec->name = "WM8988";
838 codec->owner = THIS_MODULE;
839 codec->dai = &wm8988_dai;
840 codec->num_dai = 1;
841 codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
842 codec->reg_cache = &wm8988->reg_cache;
843 codec->bias_level = SND_SOC_BIAS_OFF;
844 codec->set_bias_level = wm8988_set_bias_level;
845
846 memcpy(codec->reg_cache, wm8988_reg,
847 sizeof(wm8988_reg));
848
849 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
850 if (ret < 0) { 765 if (ret < 0) {
851 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 766 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
852 goto err; 767 return ret;
853 } 768 }
854 769
855 ret = wm8988_reset(codec); 770 ret = wm8988_reset(codec);
856 if (ret < 0) { 771 if (ret < 0) {
857 dev_err(codec->dev, "Failed to issue reset\n"); 772 dev_err(codec->dev, "Failed to issue reset\n");
858 goto err; 773 return ret;
859 } 774 }
860 775
861 /* set the update bits (we always update left then right) */ 776 /* set the update bits (we always update left then right) */
@@ -870,139 +785,132 @@ static int wm8988_register(struct wm8988_priv *wm8988,
870 reg = snd_soc_read(codec, WM8988_RINVOL); 785 reg = snd_soc_read(codec, WM8988_RINVOL);
871 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100); 786 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
872 787
873 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); 788 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
874
875 wm8988_dai.dev = codec->dev;
876
877 wm8988_codec = codec;
878
879 ret = snd_soc_register_codec(codec);
880 if (ret != 0) {
881 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
882 goto err;
883 }
884 789
885 ret = snd_soc_register_dai(&wm8988_dai); 790 snd_soc_add_controls(codec, wm8988_snd_controls,
886 if (ret != 0) { 791 ARRAY_SIZE(wm8988_snd_controls));
887 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 792 snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
888 goto err_codec; 793 ARRAY_SIZE(wm8988_dapm_widgets));
889 } 794 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
890 795
891 return 0; 796 return 0;
892
893err_codec:
894 snd_soc_unregister_codec(codec);
895err:
896 kfree(wm8988);
897 return ret;
898} 797}
899 798
900static void wm8988_unregister(struct wm8988_priv *wm8988) 799static int wm8988_remove(struct snd_soc_codec *codec)
901{ 800{
902 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF); 801 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
903 snd_soc_unregister_dai(&wm8988_dai); 802 return 0;
904 snd_soc_unregister_codec(&wm8988->codec);
905 kfree(wm8988);
906 wm8988_codec = NULL;
907} 803}
908 804
909#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 805static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
910static int wm8988_i2c_probe(struct i2c_client *i2c, 806 .probe = wm8988_probe,
911 const struct i2c_device_id *id) 807 .remove = wm8988_remove,
808 .suspend = wm8988_suspend,
809 .resume = wm8988_resume,
810 .set_bias_level = wm8988_set_bias_level,
811 .reg_cache_size = ARRAY_SIZE(wm8988_reg),
812 .reg_word_size = sizeof(u16),
813 .reg_cache_default = wm8988_reg,
814};
815
816#if defined(CONFIG_SPI_MASTER)
817static int __devinit wm8988_spi_probe(struct spi_device *spi)
912{ 818{
913 struct wm8988_priv *wm8988; 819 struct wm8988_priv *wm8988;
914 struct snd_soc_codec *codec; 820 int ret;
915 821
916 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); 822 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
917 if (wm8988 == NULL) 823 if (wm8988 == NULL)
918 return -ENOMEM; 824 return -ENOMEM;
919 825
920 codec = &wm8988->codec; 826 wm8988->control_type = SND_SOC_SPI;
921 827 spi_set_drvdata(spi, wm8988);
922 i2c_set_clientdata(i2c, wm8988);
923 codec->control_data = i2c;
924
925 codec->dev = &i2c->dev;
926 828
927 return wm8988_register(wm8988, SND_SOC_I2C); 829 ret = snd_soc_register_codec(&spi->dev,
830 &soc_codec_dev_wm8988, &wm8988_dai, 1);
831 if (ret < 0)
832 kfree(wm8988);
833 return ret;
928} 834}
929 835
930static int wm8988_i2c_remove(struct i2c_client *client) 836static int __devexit wm8988_spi_remove(struct spi_device *spi)
931{ 837{
932 struct wm8988_priv *wm8988 = i2c_get_clientdata(client); 838 snd_soc_unregister_codec(&spi->dev);
933 wm8988_unregister(wm8988); 839 kfree(spi_get_drvdata(spi));
934 return 0; 840 return 0;
935} 841}
936 842
937static const struct i2c_device_id wm8988_i2c_id[] = { 843static struct spi_driver wm8988_spi_driver = {
938 { "wm8988", 0 },
939 { }
940};
941MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
942
943static struct i2c_driver wm8988_i2c_driver = {
944 .driver = { 844 .driver = {
945 .name = "WM8988", 845 .name = "wm8988-codec",
946 .owner = THIS_MODULE, 846 .owner = THIS_MODULE,
947 }, 847 },
948 .probe = wm8988_i2c_probe, 848 .probe = wm8988_spi_probe,
949 .remove = wm8988_i2c_remove, 849 .remove = __devexit_p(wm8988_spi_remove),
950 .id_table = wm8988_i2c_id,
951}; 850};
952#endif 851#endif /* CONFIG_SPI_MASTER */
953 852
954#if defined(CONFIG_SPI_MASTER) 853#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
955static int __devinit wm8988_spi_probe(struct spi_device *spi) 854static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
855 const struct i2c_device_id *id)
956{ 856{
957 struct wm8988_priv *wm8988; 857 struct wm8988_priv *wm8988;
958 struct snd_soc_codec *codec; 858 int ret;
959 859
960 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); 860 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
961 if (wm8988 == NULL) 861 if (wm8988 == NULL)
962 return -ENOMEM; 862 return -ENOMEM;
963 863
964 codec = &wm8988->codec; 864 i2c_set_clientdata(i2c, wm8988);
965 codec->control_data = spi; 865 wm8988->control_type = SND_SOC_I2C;
966 codec->dev = &spi->dev;
967
968 dev_set_drvdata(&spi->dev, wm8988);
969 866
970 return wm8988_register(wm8988, SND_SOC_SPI); 867 ret = snd_soc_register_codec(&i2c->dev,
868 &soc_codec_dev_wm8988, &wm8988_dai, 1);
869 if (ret < 0)
870 kfree(wm8988);
871 return ret;
971} 872}
972 873
973static int __devexit wm8988_spi_remove(struct spi_device *spi) 874static __devexit int wm8988_i2c_remove(struct i2c_client *client)
974{ 875{
975 struct wm8988_priv *wm8988 = dev_get_drvdata(&spi->dev); 876 snd_soc_unregister_codec(&client->dev);
976 877 kfree(i2c_get_clientdata(client));
977 wm8988_unregister(wm8988);
978
979 return 0; 878 return 0;
980} 879}
981 880
982static struct spi_driver wm8988_spi_driver = { 881static const struct i2c_device_id wm8988_i2c_id[] = {
882 { "wm8988", 0 },
883 { }
884};
885MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
886
887static struct i2c_driver wm8988_i2c_driver = {
983 .driver = { 888 .driver = {
984 .name = "wm8988", 889 .name = "wm8988-codec",
985 .bus = &spi_bus_type, 890 .owner = THIS_MODULE,
986 .owner = THIS_MODULE,
987 }, 891 },
988 .probe = wm8988_spi_probe, 892 .probe = wm8988_i2c_probe,
989 .remove = __devexit_p(wm8988_spi_remove), 893 .remove = __devexit_p(wm8988_i2c_remove),
894 .id_table = wm8988_i2c_id,
990}; 895};
991#endif 896#endif
992 897
993static int __init wm8988_modinit(void) 898static int __init wm8988_modinit(void)
994{ 899{
995 int ret; 900 int ret = 0;
996
997#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 901#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
998 ret = i2c_add_driver(&wm8988_i2c_driver); 902 ret = i2c_add_driver(&wm8988_i2c_driver);
999 if (ret != 0) 903 if (ret != 0) {
1000 pr_err("WM8988: Unable to register I2C driver: %d\n", ret); 904 printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
905 ret);
906 }
1001#endif 907#endif
1002#if defined(CONFIG_SPI_MASTER) 908#if defined(CONFIG_SPI_MASTER)
1003 ret = spi_register_driver(&wm8988_spi_driver); 909 ret = spi_register_driver(&wm8988_spi_driver);
1004 if (ret != 0) 910 if (ret != 0) {
1005 pr_err("WM8988: Unable to register SPI driver: %d\n", ret); 911 printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n",
912 ret);
913 }
1006#endif 914#endif
1007 return ret; 915 return ret;
1008} 916}
diff --git a/sound/soc/codecs/wm8988.h b/sound/soc/codecs/wm8988.h
index 4552d37fdd41..5c04024e5f9f 100644
--- a/sound/soc/codecs/wm8988.h
+++ b/sound/soc/codecs/wm8988.h
@@ -54,7 +54,4 @@
54 54
55#define WM8988_SYSCLK 0 55#define WM8988_SYSCLK 0
56 56
57extern struct snd_soc_dai wm8988_dai;
58extern struct snd_soc_codec_device soc_codec_dev_wm8988;
59
60#endif 57#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index dd8d909788c1..100aeee5ba96 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29#include <asm/div64.h> 28#include <asm/div64.h>
@@ -32,6 +31,7 @@
32 31
33/* codec private data */ 32/* codec private data */
34struct wm8990_priv { 33struct wm8990_priv {
34 enum snd_soc_control_type control_type;
35 unsigned int sysclk; 35 unsigned int sysclk;
36 unsigned int pcmclk; 36 unsigned int pcmclk;
37}; 37};
@@ -913,11 +913,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
913 913
914static int wm8990_add_widgets(struct snd_soc_codec *codec) 914static int wm8990_add_widgets(struct snd_soc_codec *codec)
915{ 915{
916 snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets, 916 struct snd_soc_dapm_context *dapm = &codec->dapm;
917 ARRAY_SIZE(wm8990_dapm_widgets));
918 917
918 snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets,
919 ARRAY_SIZE(wm8990_dapm_widgets));
919 /* set up the WM8990 audio map */ 920 /* set up the WM8990 audio map */
920 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 921 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
921 922
922 return 0; 923 return 0;
923} 924}
@@ -1114,8 +1115,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1114 struct snd_soc_dai *dai) 1115 struct snd_soc_dai *dai)
1115{ 1116{
1116 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1117 struct snd_soc_device *socdev = rtd->socdev; 1118 struct snd_soc_codec *codec = rtd->codec;
1118 struct snd_soc_codec *codec = socdev->card->codec;
1119 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1); 1119 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1120 1120
1121 audio1 &= ~WM8990_AIF_WL_MASK; 1121 audio1 &= ~WM8990_AIF_WL_MASK;
@@ -1170,7 +1170,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1170 break; 1170 break;
1171 1171
1172 case SND_SOC_BIAS_STANDBY: 1172 case SND_SOC_BIAS_STANDBY:
1173 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1173 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1174 /* Enable all output discharge bits */ 1174 /* Enable all output discharge bits */
1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
@@ -1183,7 +1183,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1183 WM8990_VMIDTOG); 1183 WM8990_VMIDTOG);
1184 1184
1185 /* Delay to allow output caps to discharge */ 1185 /* Delay to allow output caps to discharge */
1186 msleep(msecs_to_jiffies(300)); 1186 msleep(300);
1187 1187
1188 /* Disable VMIDTOG */ 1188 /* Disable VMIDTOG */
1189 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1189 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
@@ -1195,17 +1195,17 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1195 /* Enable outputs */ 1195 /* Enable outputs */
1196 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00); 1196 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
1197 1197
1198 msleep(msecs_to_jiffies(50)); 1198 msleep(50);
1199 1199
1200 /* Enable VMID at 2x50k */ 1200 /* Enable VMID at 2x50k */
1201 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02); 1201 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
1202 1202
1203 msleep(msecs_to_jiffies(100)); 1203 msleep(100);
1204 1204
1205 /* Enable VREF */ 1205 /* Enable VREF */
1206 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1206 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1207 1207
1208 msleep(msecs_to_jiffies(600)); 1208 msleep(600);
1209 1209
1210 /* Enable BUFIOEN */ 1210 /* Enable BUFIOEN */
1211 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1211 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
@@ -1250,7 +1250,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1250 /* Disable VMID */ 1250 /* Disable VMID */
1251 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01); 1251 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
1252 1252
1253 msleep(msecs_to_jiffies(300)); 1253 msleep(300);
1254 1254
1255 /* Enable all output discharge bits */ 1255 /* Enable all output discharge bits */
1256 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1256 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
@@ -1266,7 +1266,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1266 break; 1266 break;
1267 } 1267 }
1268 1268
1269 codec->bias_level = level; 1269 codec->dapm.bias_level = level;
1270 return 0; 1270 return 0;
1271} 1271}
1272 1272
@@ -1293,10 +1293,9 @@ static struct snd_soc_dai_ops wm8990_dai_ops = {
1293 .set_sysclk = wm8990_set_dai_sysclk, 1293 .set_sysclk = wm8990_set_dai_sysclk,
1294}; 1294};
1295 1295
1296struct snd_soc_dai wm8990_dai = { 1296static struct snd_soc_dai_driver wm8990_dai = {
1297/* ADC/DAC on primary */ 1297/* ADC/DAC on primary */
1298 .name = "WM8990 ADC/DAC Primary", 1298 .name = "wm8990-hifi",
1299 .id = 1,
1300 .playback = { 1299 .playback = {
1301 .stream_name = "Playback", 1300 .stream_name = "Playback",
1302 .channels_min = 1, 1301 .channels_min = 1,
@@ -1311,21 +1310,15 @@ struct snd_soc_dai wm8990_dai = {
1311 .formats = WM8990_FORMATS,}, 1310 .formats = WM8990_FORMATS,},
1312 .ops = &wm8990_dai_ops, 1311 .ops = &wm8990_dai_ops,
1313}; 1312};
1314EXPORT_SYMBOL_GPL(wm8990_dai);
1315 1313
1316static int wm8990_suspend(struct platform_device *pdev, pm_message_t state) 1314static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state)
1317{ 1315{
1318 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1319 struct snd_soc_codec *codec = socdev->card->codec;
1320
1321 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1316 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1322 return 0; 1317 return 0;
1323} 1318}
1324 1319
1325static int wm8990_resume(struct platform_device *pdev) 1320static int wm8990_resume(struct snd_soc_codec *codec)
1326{ 1321{
1327 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1328 struct snd_soc_codec *codec = socdev->card->codec;
1329 int i; 1322 int i;
1330 u8 data[2]; 1323 u8 data[2];
1331 u16 *cache = codec->reg_cache; 1324 u16 *cache = codec->reg_cache;
@@ -1347,40 +1340,20 @@ static int wm8990_resume(struct platform_device *pdev)
1347 * initialise the WM8990 driver 1340 * initialise the WM8990 driver
1348 * register the mixer and dsp interfaces with the kernel 1341 * register the mixer and dsp interfaces with the kernel
1349 */ 1342 */
1350static int wm8990_init(struct snd_soc_device *socdev) 1343static int wm8990_probe(struct snd_soc_codec *codec)
1351{ 1344{
1352 struct snd_soc_codec *codec = socdev->card->codec; 1345 int ret;
1353 u16 reg; 1346 u16 reg;
1354 int ret = 0;
1355
1356 codec->name = "WM8990";
1357 codec->owner = THIS_MODULE;
1358 codec->set_bias_level = wm8990_set_bias_level;
1359 codec->dai = &wm8990_dai;
1360 codec->num_dai = 2;
1361 codec->reg_cache_size = ARRAY_SIZE(wm8990_reg);
1362 codec->reg_cache = kmemdup(wm8990_reg, sizeof(wm8990_reg), GFP_KERNEL);
1363
1364 if (codec->reg_cache == NULL)
1365 return -ENOMEM;
1366 1347
1367 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1348 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1368 if (ret < 0) { 1349 if (ret < 0) {
1369 printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret); 1350 printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
1370 goto pcm_err; 1351 return ret;
1371 } 1352 }
1372 1353
1373 wm8990_reset(codec); 1354 wm8990_reset(codec);
1374 1355
1375 /* register pcms */
1376 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1377 if (ret < 0) {
1378 printk(KERN_ERR "wm8990: failed to create pcms\n");
1379 goto pcm_err;
1380 }
1381
1382 /* charge output caps */ 1356 /* charge output caps */
1383 codec->bias_level = SND_SOC_BIAS_OFF;
1384 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1357 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1385 1358
1386 reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4); 1359 reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4);
@@ -1400,47 +1373,51 @@ static int wm8990_init(struct snd_soc_device *socdev)
1400 ARRAY_SIZE(wm8990_snd_controls)); 1373 ARRAY_SIZE(wm8990_snd_controls));
1401 wm8990_add_widgets(codec); 1374 wm8990_add_widgets(codec);
1402 1375
1403 return ret; 1376 return 0;
1377}
1404 1378
1405pcm_err: 1379/* power down chip */
1406 kfree(codec->reg_cache); 1380static int wm8990_remove(struct snd_soc_codec *codec)
1407 return ret; 1381{
1382 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1383 return 0;
1408} 1384}
1409 1385
1410/* If the i2c layer weren't so broken, we could pass this kind of data 1386static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
1411 around */ 1387 .probe = wm8990_probe,
1412static struct snd_soc_device *wm8990_socdev; 1388 .remove = wm8990_remove,
1389 .suspend = wm8990_suspend,
1390 .resume = wm8990_resume,
1391 .set_bias_level = wm8990_set_bias_level,
1392 .reg_cache_size = ARRAY_SIZE(wm8990_reg),
1393 .reg_word_size = sizeof(u16),
1394 .reg_cache_default = wm8990_reg,
1395};
1413 1396
1414#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1397#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1415 1398static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
1416/* 1399 const struct i2c_device_id *id)
1417 * WM891 2 wire address is determined by GPIO5
1418 * state during powerup.
1419 * low = 0x34
1420 * high = 0x36
1421 */
1422
1423static int wm8990_i2c_probe(struct i2c_client *i2c,
1424 const struct i2c_device_id *id)
1425{ 1400{
1426 struct snd_soc_device *socdev = wm8990_socdev; 1401 struct wm8990_priv *wm8990;
1427 struct snd_soc_codec *codec = socdev->card->codec;
1428 int ret; 1402 int ret;
1429 1403
1430 i2c_set_clientdata(i2c, codec); 1404 wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
1431 codec->control_data = i2c; 1405 if (wm8990 == NULL)
1406 return -ENOMEM;
1407
1408 i2c_set_clientdata(i2c, wm8990);
1432 1409
1433 ret = wm8990_init(socdev); 1410 ret = snd_soc_register_codec(&i2c->dev,
1411 &soc_codec_dev_wm8990, &wm8990_dai, 1);
1434 if (ret < 0) 1412 if (ret < 0)
1435 pr_err("failed to initialise WM8990\n"); 1413 kfree(wm8990);
1436
1437 return ret; 1414 return ret;
1438} 1415}
1439 1416
1440static int wm8990_i2c_remove(struct i2c_client *client) 1417static __devexit int wm8990_i2c_remove(struct i2c_client *client)
1441{ 1418{
1442 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1419 snd_soc_unregister_codec(&client->dev);
1443 kfree(codec->reg_cache); 1420 kfree(i2c_get_clientdata(client));
1444 return 0; 1421 return 0;
1445} 1422}
1446 1423
@@ -1452,134 +1429,34 @@ MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
1452 1429
1453static struct i2c_driver wm8990_i2c_driver = { 1430static struct i2c_driver wm8990_i2c_driver = {
1454 .driver = { 1431 .driver = {
1455 .name = "WM8990 I2C Codec", 1432 .name = "wm8990-codec",
1456 .owner = THIS_MODULE, 1433 .owner = THIS_MODULE,
1457 }, 1434 },
1458 .probe = wm8990_i2c_probe, 1435 .probe = wm8990_i2c_probe,
1459 .remove = wm8990_i2c_remove, 1436 .remove = __devexit_p(wm8990_i2c_remove),
1460 .id_table = wm8990_i2c_id, 1437 .id_table = wm8990_i2c_id,
1461}; 1438};
1462
1463static int wm8990_add_i2c_device(struct platform_device *pdev,
1464 const struct wm8990_setup_data *setup)
1465{
1466 struct i2c_board_info info;
1467 struct i2c_adapter *adapter;
1468 struct i2c_client *client;
1469 int ret;
1470
1471 ret = i2c_add_driver(&wm8990_i2c_driver);
1472 if (ret != 0) {
1473 dev_err(&pdev->dev, "can't add i2c driver\n");
1474 return ret;
1475 }
1476
1477 memset(&info, 0, sizeof(struct i2c_board_info));
1478 info.addr = setup->i2c_address;
1479 strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
1480
1481 adapter = i2c_get_adapter(setup->i2c_bus);
1482 if (!adapter) {
1483 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1484 setup->i2c_bus);
1485 goto err_driver;
1486 }
1487
1488 client = i2c_new_device(adapter, &info);
1489 i2c_put_adapter(adapter);
1490 if (!client) {
1491 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1492 (unsigned int)info.addr);
1493 goto err_driver;
1494 }
1495
1496 return 0;
1497
1498err_driver:
1499 i2c_del_driver(&wm8990_i2c_driver);
1500 return -ENODEV;
1501}
1502#endif 1439#endif
1503 1440
1504static int wm8990_probe(struct platform_device *pdev) 1441static int __init wm8990_modinit(void)
1505{ 1442{
1506 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1443 int ret = 0;
1507 struct wm8990_setup_data *setup;
1508 struct snd_soc_codec *codec;
1509 struct wm8990_priv *wm8990;
1510 int ret;
1511
1512 setup = socdev->codec_data;
1513 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1514 if (codec == NULL)
1515 return -ENOMEM;
1516
1517 wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
1518 if (wm8990 == NULL) {
1519 kfree(codec);
1520 return -ENOMEM;
1521 }
1522
1523 snd_soc_codec_set_drvdata(codec, wm8990);
1524 socdev->card->codec = codec;
1525 mutex_init(&codec->mutex);
1526 INIT_LIST_HEAD(&codec->dapm_widgets);
1527 INIT_LIST_HEAD(&codec->dapm_paths);
1528 wm8990_socdev = socdev;
1529
1530 ret = -ENODEV;
1531
1532#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1444#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1533 if (setup->i2c_address) { 1445 ret = i2c_add_driver(&wm8990_i2c_driver);
1534 codec->hw_write = (hw_write_t)i2c_master_send;
1535 ret = wm8990_add_i2c_device(pdev, setup);
1536 }
1537#endif
1538
1539 if (ret != 0) { 1446 if (ret != 0) {
1540 kfree(snd_soc_codec_get_drvdata(codec)); 1447 printk(KERN_ERR "Failed to register wm8990 I2C driver: %d\n",
1541 kfree(codec); 1448 ret);
1542 } 1449 }
1450#endif
1543 return ret; 1451 return ret;
1544} 1452}
1453module_init(wm8990_modinit);
1545 1454
1546/* power down chip */ 1455static void __exit wm8990_exit(void)
1547static int wm8990_remove(struct platform_device *pdev)
1548{ 1456{
1549 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1550 struct snd_soc_codec *codec = socdev->card->codec;
1551
1552 if (codec->control_data)
1553 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1554 snd_soc_free_pcms(socdev);
1555 snd_soc_dapm_free(socdev);
1556#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1457#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1557 i2c_unregister_device(codec->control_data);
1558 i2c_del_driver(&wm8990_i2c_driver); 1458 i2c_del_driver(&wm8990_i2c_driver);
1559#endif 1459#endif
1560 kfree(snd_soc_codec_get_drvdata(codec));
1561 kfree(codec);
1562
1563 return 0;
1564}
1565
1566struct snd_soc_codec_device soc_codec_dev_wm8990 = {
1567 .probe = wm8990_probe,
1568 .remove = wm8990_remove,
1569 .suspend = wm8990_suspend,
1570 .resume = wm8990_resume,
1571};
1572EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
1573
1574static int __init wm8990_modinit(void)
1575{
1576 return snd_soc_register_dai(&wm8990_dai);
1577}
1578module_init(wm8990_modinit);
1579
1580static void __exit wm8990_exit(void)
1581{
1582 snd_soc_unregister_dai(&wm8990_dai);
1583} 1460}
1584module_exit(wm8990_exit); 1461module_exit(wm8990_exit);
1585 1462
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 7114ddc88b4b..77c98a4bfe9c 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -826,18 +826,10 @@
826#define WM8990_INMIXR_PWR_BIT 2 826#define WM8990_INMIXR_PWR_BIT 2
827#define WM8990_AINRMUX_PWR_BIT 3 827#define WM8990_AINRMUX_PWR_BIT 3
828 828
829struct wm8990_setup_data {
830 unsigned i2c_bus;
831 unsigned short i2c_address;
832};
833
834#define WM8990_MCLK_DIV 0 829#define WM8990_MCLK_DIV 0
835#define WM8990_DACCLK_DIV 1 830#define WM8990_DACCLK_DIV 1
836#define WM8990_ADCCLK_DIV 2 831#define WM8990_ADCCLK_DIV 2
837#define WM8990_BCLK_DIV 3 832#define WM8990_BCLK_DIV 3
838 833
839extern struct snd_soc_dai wm8990_dai;
840extern struct snd_soc_codec_device soc_codec_dev_wm8990;
841
842#endif /* __WM8990REGISTERDEFS_H__ */ 834#endif /* __WM8990REGISTERDEFS_H__ */
843/*------------------------------ END OF FILE ---------------------------------*/ 835/*------------------------------ END OF FILE ---------------------------------*/
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
new file mode 100644
index 000000000000..6af23d06870f
--- /dev/null
+++ b/sound/soc/codecs/wm8991.c
@@ -0,0 +1,1426 @@
1/*
2 * wm8991.c -- WM8991 ALSA Soc Audio driver
3 *
4 * Copyright 2007-2010 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <asm/div64.h>
31
32#include "wm8991.h"
33
34struct wm8991_priv {
35 enum snd_soc_control_type control_type;
36 unsigned int pcmclk;
37};
38
39static const u16 wm8991_reg_defs[] = {
40 0x8991, /* R0 - Reset */
41 0x0000, /* R1 - Power Management (1) */
42 0x6000, /* R2 - Power Management (2) */
43 0x0000, /* R3 - Power Management (3) */
44 0x4050, /* R4 - Audio Interface (1) */
45 0x4000, /* R5 - Audio Interface (2) */
46 0x01C8, /* R6 - Clocking (1) */
47 0x0000, /* R7 - Clocking (2) */
48 0x0040, /* R8 - Audio Interface (3) */
49 0x0040, /* R9 - Audio Interface (4) */
50 0x0004, /* R10 - DAC CTRL */
51 0x00C0, /* R11 - Left DAC Digital Volume */
52 0x00C0, /* R12 - Right DAC Digital Volume */
53 0x0000, /* R13 - Digital Side Tone */
54 0x0100, /* R14 - ADC CTRL */
55 0x00C0, /* R15 - Left ADC Digital Volume */
56 0x00C0, /* R16 - Right ADC Digital Volume */
57 0x0000, /* R17 */
58 0x0000, /* R18 - GPIO CTRL 1 */
59 0x1000, /* R19 - GPIO1 & GPIO2 */
60 0x1010, /* R20 - GPIO3 & GPIO4 */
61 0x1010, /* R21 - GPIO5 & GPIO6 */
62 0x8000, /* R22 - GPIOCTRL 2 */
63 0x0800, /* R23 - GPIO_POL */
64 0x008B, /* R24 - Left Line Input 1&2 Volume */
65 0x008B, /* R25 - Left Line Input 3&4 Volume */
66 0x008B, /* R26 - Right Line Input 1&2 Volume */
67 0x008B, /* R27 - Right Line Input 3&4 Volume */
68 0x0000, /* R28 - Left Output Volume */
69 0x0000, /* R29 - Right Output Volume */
70 0x0066, /* R30 - Line Outputs Volume */
71 0x0022, /* R31 - Out3/4 Volume */
72 0x0079, /* R32 - Left OPGA Volume */
73 0x0079, /* R33 - Right OPGA Volume */
74 0x0003, /* R34 - Speaker Volume */
75 0x0003, /* R35 - ClassD1 */
76 0x0000, /* R36 */
77 0x0100, /* R37 - ClassD3 */
78 0x0000, /* R38 */
79 0x0000, /* R39 - Input Mixer1 */
80 0x0000, /* R40 - Input Mixer2 */
81 0x0000, /* R41 - Input Mixer3 */
82 0x0000, /* R42 - Input Mixer4 */
83 0x0000, /* R43 - Input Mixer5 */
84 0x0000, /* R44 - Input Mixer6 */
85 0x0000, /* R45 - Output Mixer1 */
86 0x0000, /* R46 - Output Mixer2 */
87 0x0000, /* R47 - Output Mixer3 */
88 0x0000, /* R48 - Output Mixer4 */
89 0x0000, /* R49 - Output Mixer5 */
90 0x0000, /* R50 - Output Mixer6 */
91 0x0180, /* R51 - Out3/4 Mixer */
92 0x0000, /* R52 - Line Mixer1 */
93 0x0000, /* R53 - Line Mixer2 */
94 0x0000, /* R54 - Speaker Mixer */
95 0x0000, /* R55 - Additional Control */
96 0x0000, /* R56 - AntiPOP1 */
97 0x0000, /* R57 - AntiPOP2 */
98 0x0000, /* R58 - MICBIAS */
99 0x0000, /* R59 */
100 0x0008, /* R60 - PLL1 */
101 0x0031, /* R61 - PLL2 */
102 0x0026, /* R62 - PLL3 */
103};
104
105#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0)
106
107static const unsigned int rec_mix_tlv[] = {
108 TLV_DB_RANGE_HEAD(1),
109 0, 7, TLV_DB_LINEAR_ITEM(-1500, 600),
110};
111
112static const unsigned int in_pga_tlv[] = {
113 TLV_DB_RANGE_HEAD(1),
114 0, 0x1F, TLV_DB_LINEAR_ITEM(-1650, 3000),
115};
116
117static const unsigned int out_mix_tlv[] = {
118 TLV_DB_RANGE_HEAD(1),
119 0, 7, TLV_DB_LINEAR_ITEM(0, -2100),
120};
121
122static const unsigned int out_pga_tlv[] = {
123 TLV_DB_RANGE_HEAD(1),
124 0, 127, TLV_DB_LINEAR_ITEM(-7300, 600),
125};
126
127static const unsigned int out_omix_tlv[] = {
128 TLV_DB_RANGE_HEAD(1),
129 0, 7, TLV_DB_LINEAR_ITEM(-600, 0),
130};
131
132static const unsigned int out_dac_tlv[] = {
133 TLV_DB_RANGE_HEAD(1),
134 0, 255, TLV_DB_LINEAR_ITEM(-7163, 0),
135};
136
137static const unsigned int in_adc_tlv[] = {
138 TLV_DB_RANGE_HEAD(1),
139 0, 255, TLV_DB_LINEAR_ITEM(-7163, 1763),
140};
141
142static const unsigned int out_sidetone_tlv[] = {
143 TLV_DB_RANGE_HEAD(1),
144 0, 31, TLV_DB_LINEAR_ITEM(-3600, 0),
145};
146
147static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
148 struct snd_ctl_elem_value *ucontrol)
149{
150 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
151 int reg = kcontrol->private_value & 0xff;
152 int ret;
153 u16 val;
154
155 ret = snd_soc_put_volsw(kcontrol, ucontrol);
156 if (ret < 0)
157 return ret;
158
159 /* now hit the volume update bits (always bit 8) */
160 val = snd_soc_read(codec, reg);
161 return snd_soc_write(codec, reg, val | 0x0100);
162}
163
164static const char *wm8991_digital_sidetone[] =
165{"None", "Left ADC", "Right ADC", "Reserved"};
166
167static const struct soc_enum wm8991_left_digital_sidetone_enum =
168 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
169 WM8991_ADC_TO_DACL_SHIFT,
170 WM8991_ADC_TO_DACL_MASK,
171 wm8991_digital_sidetone);
172
173static const struct soc_enum wm8991_right_digital_sidetone_enum =
174 SOC_ENUM_SINGLE(WM8991_DIGITAL_SIDE_TONE,
175 WM8991_ADC_TO_DACR_SHIFT,
176 WM8991_ADC_TO_DACR_MASK,
177 wm8991_digital_sidetone);
178
179static const char *wm8991_adcmode[] =
180{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
181
182static const struct soc_enum wm8991_right_adcmode_enum =
183 SOC_ENUM_SINGLE(WM8991_ADC_CTRL,
184 WM8991_ADC_HPF_CUT_SHIFT,
185 WM8991_ADC_HPF_CUT_MASK,
186 wm8991_adcmode);
187
188static const struct snd_kcontrol_new wm8991_snd_controls[] = {
189 /* INMIXL */
190 SOC_SINGLE("LIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L12MNBST_BIT, 1, 0),
191 SOC_SINGLE("LIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_L34MNBST_BIT, 1, 0),
192 /* INMIXR */
193 SOC_SINGLE("RIN12 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R12MNBST_BIT, 1, 0),
194 SOC_SINGLE("RIN34 PGA Boost", WM8991_INPUT_MIXER3, WM8991_R34MNBST_BIT, 1, 0),
195
196 /* LOMIX */
197 SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER3,
198 WM8991_LLI3LOVOL_SHIFT, WM8991_LLI3LOVOL_MASK, 1, out_mix_tlv),
199 SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
200 WM8991_LR12LOVOL_SHIFT, WM8991_LR12LOVOL_MASK, 1, out_mix_tlv),
201 SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER3,
202 WM8991_LL12LOVOL_SHIFT, WM8991_LL12LOVOL_MASK, 1, out_mix_tlv),
203 SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER5,
204 WM8991_LRI3LOVOL_SHIFT, WM8991_LRI3LOVOL_MASK, 1, out_mix_tlv),
205 SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
206 WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
207 SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER5,
208 WM8991_LRBLOVOL_SHIFT, WM8991_LRBLOVOL_MASK, 1, out_mix_tlv),
209
210 /* ROMIX */
211 SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8991_OUTPUT_MIXER4,
212 WM8991_RRI3ROVOL_SHIFT, WM8991_RRI3ROVOL_MASK, 1, out_mix_tlv),
213 SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
214 WM8991_RL12ROVOL_SHIFT, WM8991_RL12ROVOL_MASK, 1, out_mix_tlv),
215 SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8991_OUTPUT_MIXER4,
216 WM8991_RR12ROVOL_SHIFT, WM8991_RR12ROVOL_MASK, 1, out_mix_tlv),
217 SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8991_OUTPUT_MIXER6,
218 WM8991_RLI3ROVOL_SHIFT, WM8991_RLI3ROVOL_MASK, 1, out_mix_tlv),
219 SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
220 WM8991_RLBROVOL_SHIFT, WM8991_RLBROVOL_MASK, 1, out_mix_tlv),
221 SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8991_OUTPUT_MIXER6,
222 WM8991_RRBROVOL_SHIFT, WM8991_RRBROVOL_MASK, 1, out_mix_tlv),
223
224 /* LOUT */
225 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8991_LEFT_OUTPUT_VOLUME,
226 WM8991_LOUTVOL_SHIFT, WM8991_LOUTVOL_MASK, 0, out_pga_tlv),
227 SOC_SINGLE("LOUT ZC", WM8991_LEFT_OUTPUT_VOLUME, WM8991_LOZC_BIT, 1, 0),
228
229 /* ROUT */
230 SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8991_RIGHT_OUTPUT_VOLUME,
231 WM8991_ROUTVOL_SHIFT, WM8991_ROUTVOL_MASK, 0, out_pga_tlv),
232 SOC_SINGLE("ROUT ZC", WM8991_RIGHT_OUTPUT_VOLUME, WM8991_ROZC_BIT, 1, 0),
233
234 /* LOPGA */
235 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8991_LEFT_OPGA_VOLUME,
236 WM8991_LOPGAVOL_SHIFT, WM8991_LOPGAVOL_MASK, 0, out_pga_tlv),
237 SOC_SINGLE("LOPGA ZC Switch", WM8991_LEFT_OPGA_VOLUME,
238 WM8991_LOPGAZC_BIT, 1, 0),
239
240 /* ROPGA */
241 SOC_WM899X_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8991_RIGHT_OPGA_VOLUME,
242 WM8991_ROPGAVOL_SHIFT, WM8991_ROPGAVOL_MASK, 0, out_pga_tlv),
243 SOC_SINGLE("ROPGA ZC Switch", WM8991_RIGHT_OPGA_VOLUME,
244 WM8991_ROPGAZC_BIT, 1, 0),
245
246 SOC_SINGLE("LON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
247 WM8991_LONMUTE_BIT, 1, 0),
248 SOC_SINGLE("LOP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
249 WM8991_LOPMUTE_BIT, 1, 0),
250 SOC_SINGLE("LOP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
251 WM8991_LOATTN_BIT, 1, 0),
252 SOC_SINGLE("RON Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
253 WM8991_RONMUTE_BIT, 1, 0),
254 SOC_SINGLE("ROP Mute Switch", WM8991_LINE_OUTPUTS_VOLUME,
255 WM8991_ROPMUTE_BIT, 1, 0),
256 SOC_SINGLE("ROP Attenuation Switch", WM8991_LINE_OUTPUTS_VOLUME,
257 WM8991_ROATTN_BIT, 1, 0),
258
259 SOC_SINGLE("OUT3 Mute Switch", WM8991_OUT3_4_VOLUME,
260 WM8991_OUT3MUTE_BIT, 1, 0),
261 SOC_SINGLE("OUT3 Attenuation Switch", WM8991_OUT3_4_VOLUME,
262 WM8991_OUT3ATTN_BIT, 1, 0),
263
264 SOC_SINGLE("OUT4 Mute Switch", WM8991_OUT3_4_VOLUME,
265 WM8991_OUT4MUTE_BIT, 1, 0),
266 SOC_SINGLE("OUT4 Attenuation Switch", WM8991_OUT3_4_VOLUME,
267 WM8991_OUT4ATTN_BIT, 1, 0),
268
269 SOC_SINGLE("Speaker Mode Switch", WM8991_CLASSD1,
270 WM8991_CDMODE_BIT, 1, 0),
271
272 SOC_SINGLE("Speaker Output Attenuation Volume", WM8991_SPEAKER_VOLUME,
273 WM8991_SPKVOL_SHIFT, WM8991_SPKVOL_MASK, 0),
274 SOC_SINGLE("Speaker DC Boost Volume", WM8991_CLASSD3,
275 WM8991_DCGAIN_SHIFT, WM8991_DCGAIN_MASK, 0),
276 SOC_SINGLE("Speaker AC Boost Volume", WM8991_CLASSD3,
277 WM8991_ACGAIN_SHIFT, WM8991_ACGAIN_MASK, 0),
278
279 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
280 WM8991_LEFT_DAC_DIGITAL_VOLUME,
281 WM8991_DACL_VOL_SHIFT,
282 WM8991_DACL_VOL_MASK,
283 0,
284 out_dac_tlv),
285
286 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
287 WM8991_RIGHT_DAC_DIGITAL_VOLUME,
288 WM8991_DACR_VOL_SHIFT,
289 WM8991_DACR_VOL_MASK,
290 0,
291 out_dac_tlv),
292
293 SOC_ENUM("Left Digital Sidetone", wm8991_left_digital_sidetone_enum),
294 SOC_ENUM("Right Digital Sidetone", wm8991_right_digital_sidetone_enum),
295
296 SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
297 WM8991_ADCL_DAC_SVOL_SHIFT, WM8991_ADCL_DAC_SVOL_MASK, 0,
298 out_sidetone_tlv),
299 SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8991_DIGITAL_SIDE_TONE,
300 WM8991_ADCR_DAC_SVOL_SHIFT, WM8991_ADCR_DAC_SVOL_MASK, 0,
301 out_sidetone_tlv),
302
303 SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8991_ADC_CTRL,
304 WM8991_ADC_HPF_ENA_BIT, 1, 0),
305
306 SOC_ENUM("ADC HPF Mode", wm8991_right_adcmode_enum),
307
308 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
309 WM8991_LEFT_ADC_DIGITAL_VOLUME,
310 WM8991_ADCL_VOL_SHIFT,
311 WM8991_ADCL_VOL_MASK,
312 0,
313 in_adc_tlv),
314
315 SOC_WM899X_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
316 WM8991_RIGHT_ADC_DIGITAL_VOLUME,
317 WM8991_ADCR_VOL_SHIFT,
318 WM8991_ADCR_VOL_MASK,
319 0,
320 in_adc_tlv),
321
322 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
323 WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
324 WM8991_LIN12VOL_SHIFT,
325 WM8991_LIN12VOL_MASK,
326 0,
327 in_pga_tlv),
328
329 SOC_SINGLE("LIN12 ZC Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
330 WM8991_LI12ZC_BIT, 1, 0),
331
332 SOC_SINGLE("LIN12 Mute Switch", WM8991_LEFT_LINE_INPUT_1_2_VOLUME,
333 WM8991_LI12MUTE_BIT, 1, 0),
334
335 SOC_WM899X_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
336 WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
337 WM8991_LIN34VOL_SHIFT,
338 WM8991_LIN34VOL_MASK,
339 0,
340 in_pga_tlv),
341
342 SOC_SINGLE("LIN34 ZC Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
343 WM8991_LI34ZC_BIT, 1, 0),
344
345 SOC_SINGLE("LIN34 Mute Switch", WM8991_LEFT_LINE_INPUT_3_4_VOLUME,
346 WM8991_LI34MUTE_BIT, 1, 0),
347
348 SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
349 WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
350 WM8991_RIN12VOL_SHIFT,
351 WM8991_RIN12VOL_MASK,
352 0,
353 in_pga_tlv),
354
355 SOC_SINGLE("RIN12 ZC Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
356 WM8991_RI12ZC_BIT, 1, 0),
357
358 SOC_SINGLE("RIN12 Mute Switch", WM8991_RIGHT_LINE_INPUT_1_2_VOLUME,
359 WM8991_RI12MUTE_BIT, 1, 0),
360
361 SOC_WM899X_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
362 WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
363 WM8991_RIN34VOL_SHIFT,
364 WM8991_RIN34VOL_MASK,
365 0,
366 in_pga_tlv),
367
368 SOC_SINGLE("RIN34 ZC Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
369 WM8991_RI34ZC_BIT, 1, 0),
370
371 SOC_SINGLE("RIN34 Mute Switch", WM8991_RIGHT_LINE_INPUT_3_4_VOLUME,
372 WM8991_RI34MUTE_BIT, 1, 0),
373};
374
375/*
376 * _DAPM_ Controls
377 */
378static int inmixer_event(struct snd_soc_dapm_widget *w,
379 struct snd_kcontrol *kcontrol, int event)
380{
381 u16 reg, fakepower;
382
383 reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2);
384 fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS);
385
386 if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) |
387 (1 << WM8991_AINLMUX_PWR_BIT)))
388 reg |= WM8991_AINL_ENA;
389 else
390 reg &= ~WM8991_AINL_ENA;
391
392 if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) |
393 (1 << WM8991_AINRMUX_PWR_BIT)))
394 reg |= WM8991_AINR_ENA;
395 else
396 reg &= ~WM8991_AINL_ENA;
397
398 snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg);
399 return 0;
400}
401
402static int outmixer_event(struct snd_soc_dapm_widget *w,
403 struct snd_kcontrol *kcontrol, int event)
404{
405 u32 reg_shift = kcontrol->private_value & 0xfff;
406 int ret = 0;
407 u16 reg;
408
409 switch (reg_shift) {
410 case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
411 reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER1);
412 if (reg & WM8991_LDLO) {
413 printk(KERN_WARNING
414 "Cannot set as Output Mixer 1 LDLO Set\n");
415 ret = -1;
416 }
417 break;
418
419 case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
420 reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER2);
421 if (reg & WM8991_RDRO) {
422 printk(KERN_WARNING
423 "Cannot set as Output Mixer 2 RDRO Set\n");
424 ret = -1;
425 }
426 break;
427
428 case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
429 reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
430 if (reg & WM8991_LDSPK) {
431 printk(KERN_WARNING
432 "Cannot set as Speaker Mixer LDSPK Set\n");
433 ret = -1;
434 }
435 break;
436
437 case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
438 reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
439 if (reg & WM8991_RDSPK) {
440 printk(KERN_WARNING
441 "Cannot set as Speaker Mixer RDSPK Set\n");
442 ret = -1;
443 }
444 break;
445 }
446
447 return ret;
448}
449
450/* INMIX dB values */
451static const unsigned int in_mix_tlv[] = {
452 TLV_DB_RANGE_HEAD(1),
453 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600),
454};
455
456/* Left In PGA Connections */
457static const struct snd_kcontrol_new wm8991_dapm_lin12_pga_controls[] = {
458 SOC_DAPM_SINGLE("LIN1 Switch", WM8991_INPUT_MIXER2, WM8991_LMN1_BIT, 1, 0),
459 SOC_DAPM_SINGLE("LIN2 Switch", WM8991_INPUT_MIXER2, WM8991_LMP2_BIT, 1, 0),
460};
461
462static const struct snd_kcontrol_new wm8991_dapm_lin34_pga_controls[] = {
463 SOC_DAPM_SINGLE("LIN3 Switch", WM8991_INPUT_MIXER2, WM8991_LMN3_BIT, 1, 0),
464 SOC_DAPM_SINGLE("LIN4 Switch", WM8991_INPUT_MIXER2, WM8991_LMP4_BIT, 1, 0),
465};
466
467/* Right In PGA Connections */
468static const struct snd_kcontrol_new wm8991_dapm_rin12_pga_controls[] = {
469 SOC_DAPM_SINGLE("RIN1 Switch", WM8991_INPUT_MIXER2, WM8991_RMN1_BIT, 1, 0),
470 SOC_DAPM_SINGLE("RIN2 Switch", WM8991_INPUT_MIXER2, WM8991_RMP2_BIT, 1, 0),
471};
472
473static const struct snd_kcontrol_new wm8991_dapm_rin34_pga_controls[] = {
474 SOC_DAPM_SINGLE("RIN3 Switch", WM8991_INPUT_MIXER2, WM8991_RMN3_BIT, 1, 0),
475 SOC_DAPM_SINGLE("RIN4 Switch", WM8991_INPUT_MIXER2, WM8991_RMP4_BIT, 1, 0),
476};
477
478/* INMIXL */
479static const struct snd_kcontrol_new wm8991_dapm_inmixl_controls[] = {
480 SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8991_INPUT_MIXER3,
481 WM8991_LDBVOL_SHIFT, WM8991_LDBVOL_MASK, 0, in_mix_tlv),
482 SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8991_INPUT_MIXER5, WM8991_LI2BVOL_SHIFT,
483 7, 0, in_mix_tlv),
484 SOC_DAPM_SINGLE("LINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
485 1, 0),
486 SOC_DAPM_SINGLE("LINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
487 1, 0),
488};
489
490/* INMIXR */
491static const struct snd_kcontrol_new wm8991_dapm_inmixr_controls[] = {
492 SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8991_INPUT_MIXER4,
493 WM8991_RDBVOL_SHIFT, WM8991_RDBVOL_MASK, 0, in_mix_tlv),
494 SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8991_INPUT_MIXER6, WM8991_RI2BVOL_SHIFT,
495 7, 0, in_mix_tlv),
496 SOC_DAPM_SINGLE("RINPGA12 Switch", WM8991_INPUT_MIXER3, WM8991_L12MNB_BIT,
497 1, 0),
498 SOC_DAPM_SINGLE("RINPGA34 Switch", WM8991_INPUT_MIXER3, WM8991_L34MNB_BIT,
499 1, 0),
500};
501
502/* AINLMUX */
503static const char *wm8991_ainlmux[] =
504{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
505
506static const struct soc_enum wm8991_ainlmux_enum =
507 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINLMODE_SHIFT,
508 ARRAY_SIZE(wm8991_ainlmux), wm8991_ainlmux);
509
510static const struct snd_kcontrol_new wm8991_dapm_ainlmux_controls =
511 SOC_DAPM_ENUM("Route", wm8991_ainlmux_enum);
512
513/* DIFFINL */
514
515/* AINRMUX */
516static const char *wm8991_ainrmux[] =
517{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
518
519static const struct soc_enum wm8991_ainrmux_enum =
520 SOC_ENUM_SINGLE(WM8991_INPUT_MIXER1, WM8991_AINRMODE_SHIFT,
521 ARRAY_SIZE(wm8991_ainrmux), wm8991_ainrmux);
522
523static const struct snd_kcontrol_new wm8991_dapm_ainrmux_controls =
524 SOC_DAPM_ENUM("Route", wm8991_ainrmux_enum);
525
526/* RXVOICE */
527static const struct snd_kcontrol_new wm8991_dapm_rxvoice_controls[] = {
528 SOC_DAPM_SINGLE_TLV("LIN4RXN", WM8991_INPUT_MIXER5, WM8991_LR4BVOL_SHIFT,
529 WM8991_LR4BVOL_MASK, 0, in_mix_tlv),
530 SOC_DAPM_SINGLE_TLV("RIN4RXP", WM8991_INPUT_MIXER6, WM8991_RL4BVOL_SHIFT,
531 WM8991_RL4BVOL_MASK, 0, in_mix_tlv),
532};
533
534/* LOMIX */
535static const struct snd_kcontrol_new wm8991_dapm_lomix_controls[] = {
536 SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
537 WM8991_LRBLO_BIT, 1, 0),
538 SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER1,
539 WM8991_LLBLO_BIT, 1, 0),
540 SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
541 WM8991_LRI3LO_BIT, 1, 0),
542 SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER1,
543 WM8991_LLI3LO_BIT, 1, 0),
544 SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
545 WM8991_LR12LO_BIT, 1, 0),
546 SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER1,
547 WM8991_LL12LO_BIT, 1, 0),
548 SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8991_OUTPUT_MIXER1,
549 WM8991_LDLO_BIT, 1, 0),
550};
551
552/* ROMIX */
553static const struct snd_kcontrol_new wm8991_dapm_romix_controls[] = {
554 SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
555 WM8991_RLBRO_BIT, 1, 0),
556 SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8991_OUTPUT_MIXER2,
557 WM8991_RRBRO_BIT, 1, 0),
558 SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
559 WM8991_RLI3RO_BIT, 1, 0),
560 SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8991_OUTPUT_MIXER2,
561 WM8991_RRI3RO_BIT, 1, 0),
562 SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
563 WM8991_RL12RO_BIT, 1, 0),
564 SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8991_OUTPUT_MIXER2,
565 WM8991_RR12RO_BIT, 1, 0),
566 SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8991_OUTPUT_MIXER2,
567 WM8991_RDRO_BIT, 1, 0),
568};
569
570/* LONMIX */
571static const struct snd_kcontrol_new wm8991_dapm_lonmix_controls[] = {
572 SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
573 WM8991_LLOPGALON_BIT, 1, 0),
574 SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER1,
575 WM8991_LROPGALON_BIT, 1, 0),
576 SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8991_LINE_MIXER1,
577 WM8991_LOPLON_BIT, 1, 0),
578};
579
580/* LOPMIX */
581static const struct snd_kcontrol_new wm8991_dapm_lopmix_controls[] = {
582 SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER1,
583 WM8991_LR12LOP_BIT, 1, 0),
584 SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER1,
585 WM8991_LL12LOP_BIT, 1, 0),
586 SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8991_LINE_MIXER1,
587 WM8991_LLOPGALOP_BIT, 1, 0),
588};
589
590/* RONMIX */
591static const struct snd_kcontrol_new wm8991_dapm_ronmix_controls[] = {
592 SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
593 WM8991_RROPGARON_BIT, 1, 0),
594 SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8991_LINE_MIXER2,
595 WM8991_RLOPGARON_BIT, 1, 0),
596 SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8991_LINE_MIXER2,
597 WM8991_ROPRON_BIT, 1, 0),
598};
599
600/* ROPMIX */
601static const struct snd_kcontrol_new wm8991_dapm_ropmix_controls[] = {
602 SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8991_LINE_MIXER2,
603 WM8991_RL12ROP_BIT, 1, 0),
604 SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8991_LINE_MIXER2,
605 WM8991_RR12ROP_BIT, 1, 0),
606 SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8991_LINE_MIXER2,
607 WM8991_RROPGAROP_BIT, 1, 0),
608};
609
610/* OUT3MIX */
611static const struct snd_kcontrol_new wm8991_dapm_out3mix_controls[] = {
612 SOC_DAPM_SINGLE("OUT3MIX LIN4RXN Bypass Switch", WM8991_OUT3_4_MIXER,
613 WM8991_LI4O3_BIT, 1, 0),
614 SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8991_OUT3_4_MIXER,
615 WM8991_LPGAO3_BIT, 1, 0),
616};
617
618/* OUT4MIX */
619static const struct snd_kcontrol_new wm8991_dapm_out4mix_controls[] = {
620 SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8991_OUT3_4_MIXER,
621 WM8991_RPGAO4_BIT, 1, 0),
622 SOC_DAPM_SINGLE("OUT4MIX RIN4RXP Bypass Switch", WM8991_OUT3_4_MIXER,
623 WM8991_RI4O4_BIT, 1, 0),
624};
625
626/* SPKMIX */
627static const struct snd_kcontrol_new wm8991_dapm_spkmix_controls[] = {
628 SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
629 WM8991_LI2SPK_BIT, 1, 0),
630 SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8991_SPEAKER_MIXER,
631 WM8991_LB2SPK_BIT, 1, 0),
632 SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8991_SPEAKER_MIXER,
633 WM8991_LOPGASPK_BIT, 1, 0),
634 SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8991_SPEAKER_MIXER,
635 WM8991_LDSPK_BIT, 1, 0),
636 SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8991_SPEAKER_MIXER,
637 WM8991_RDSPK_BIT, 1, 0),
638 SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8991_SPEAKER_MIXER,
639 WM8991_ROPGASPK_BIT, 1, 0),
640 SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8991_SPEAKER_MIXER,
641 WM8991_RL12ROP_BIT, 1, 0),
642 SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8991_SPEAKER_MIXER,
643 WM8991_RI2SPK_BIT, 1, 0),
644};
645
646static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = {
647 /* Input Side */
648 /* Input Lines */
649 SND_SOC_DAPM_INPUT("LIN1"),
650 SND_SOC_DAPM_INPUT("LIN2"),
651 SND_SOC_DAPM_INPUT("LIN3"),
652 SND_SOC_DAPM_INPUT("LIN4RXN"),
653 SND_SOC_DAPM_INPUT("RIN3"),
654 SND_SOC_DAPM_INPUT("RIN4RXP"),
655 SND_SOC_DAPM_INPUT("RIN1"),
656 SND_SOC_DAPM_INPUT("RIN2"),
657 SND_SOC_DAPM_INPUT("Internal ADC Source"),
658
659 /* DACs */
660 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2,
661 WM8991_ADCL_ENA_BIT, 0),
662 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8991_POWER_MANAGEMENT_2,
663 WM8991_ADCR_ENA_BIT, 0),
664
665 /* Input PGAs */
666 SND_SOC_DAPM_MIXER("LIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN12_ENA_BIT,
667 0, &wm8991_dapm_lin12_pga_controls[0],
668 ARRAY_SIZE(wm8991_dapm_lin12_pga_controls)),
669 SND_SOC_DAPM_MIXER("LIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_LIN34_ENA_BIT,
670 0, &wm8991_dapm_lin34_pga_controls[0],
671 ARRAY_SIZE(wm8991_dapm_lin34_pga_controls)),
672 SND_SOC_DAPM_MIXER("RIN12 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN12_ENA_BIT,
673 0, &wm8991_dapm_rin12_pga_controls[0],
674 ARRAY_SIZE(wm8991_dapm_rin12_pga_controls)),
675 SND_SOC_DAPM_MIXER("RIN34 PGA", WM8991_POWER_MANAGEMENT_2, WM8991_RIN34_ENA_BIT,
676 0, &wm8991_dapm_rin34_pga_controls[0],
677 ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)),
678
679 /* INMIXL */
680 SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0,
681 &wm8991_dapm_inmixl_controls[0],
682 ARRAY_SIZE(wm8991_dapm_inmixl_controls),
683 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
684
685 /* AINLMUX */
686 SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0,
687 &wm8991_dapm_ainlmux_controls, inmixer_event,
688 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
689
690 /* INMIXR */
691 SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0,
692 &wm8991_dapm_inmixr_controls[0],
693 ARRAY_SIZE(wm8991_dapm_inmixr_controls),
694 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
695
696 /* AINRMUX */
697 SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0,
698 &wm8991_dapm_ainrmux_controls, inmixer_event,
699 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
700
701 /* Output Side */
702 /* DACs */
703 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8991_POWER_MANAGEMENT_3,
704 WM8991_DACL_ENA_BIT, 0),
705 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8991_POWER_MANAGEMENT_3,
706 WM8991_DACR_ENA_BIT, 0),
707
708 /* LOMIX */
709 SND_SOC_DAPM_MIXER_E("LOMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOMIX_ENA_BIT,
710 0, &wm8991_dapm_lomix_controls[0],
711 ARRAY_SIZE(wm8991_dapm_lomix_controls),
712 outmixer_event, SND_SOC_DAPM_PRE_REG),
713
714 /* LONMIX */
715 SND_SOC_DAPM_MIXER("LONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LON_ENA_BIT, 0,
716 &wm8991_dapm_lonmix_controls[0],
717 ARRAY_SIZE(wm8991_dapm_lonmix_controls)),
718
719 /* LOPMIX */
720 SND_SOC_DAPM_MIXER("LOPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_LOP_ENA_BIT, 0,
721 &wm8991_dapm_lopmix_controls[0],
722 ARRAY_SIZE(wm8991_dapm_lopmix_controls)),
723
724 /* OUT3MIX */
725 SND_SOC_DAPM_MIXER("OUT3MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT3_ENA_BIT, 0,
726 &wm8991_dapm_out3mix_controls[0],
727 ARRAY_SIZE(wm8991_dapm_out3mix_controls)),
728
729 /* SPKMIX */
730 SND_SOC_DAPM_MIXER_E("SPKMIX", WM8991_POWER_MANAGEMENT_1, WM8991_SPK_ENA_BIT, 0,
731 &wm8991_dapm_spkmix_controls[0],
732 ARRAY_SIZE(wm8991_dapm_spkmix_controls), outmixer_event,
733 SND_SOC_DAPM_PRE_REG),
734
735 /* OUT4MIX */
736 SND_SOC_DAPM_MIXER("OUT4MIX", WM8991_POWER_MANAGEMENT_1, WM8991_OUT4_ENA_BIT, 0,
737 &wm8991_dapm_out4mix_controls[0],
738 ARRAY_SIZE(wm8991_dapm_out4mix_controls)),
739
740 /* ROPMIX */
741 SND_SOC_DAPM_MIXER("ROPMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROP_ENA_BIT, 0,
742 &wm8991_dapm_ropmix_controls[0],
743 ARRAY_SIZE(wm8991_dapm_ropmix_controls)),
744
745 /* RONMIX */
746 SND_SOC_DAPM_MIXER("RONMIX", WM8991_POWER_MANAGEMENT_3, WM8991_RON_ENA_BIT, 0,
747 &wm8991_dapm_ronmix_controls[0],
748 ARRAY_SIZE(wm8991_dapm_ronmix_controls)),
749
750 /* ROMIX */
751 SND_SOC_DAPM_MIXER_E("ROMIX", WM8991_POWER_MANAGEMENT_3, WM8991_ROMIX_ENA_BIT,
752 0, &wm8991_dapm_romix_controls[0],
753 ARRAY_SIZE(wm8991_dapm_romix_controls),
754 outmixer_event, SND_SOC_DAPM_PRE_REG),
755
756 /* LOUT PGA */
757 SND_SOC_DAPM_PGA("LOUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_LOUT_ENA_BIT, 0,
758 NULL, 0),
759
760 /* ROUT PGA */
761 SND_SOC_DAPM_PGA("ROUT PGA", WM8991_POWER_MANAGEMENT_1, WM8991_ROUT_ENA_BIT, 0,
762 NULL, 0),
763
764 /* LOPGA */
765 SND_SOC_DAPM_PGA("LOPGA", WM8991_POWER_MANAGEMENT_3, WM8991_LOPGA_ENA_BIT, 0,
766 NULL, 0),
767
768 /* ROPGA */
769 SND_SOC_DAPM_PGA("ROPGA", WM8991_POWER_MANAGEMENT_3, WM8991_ROPGA_ENA_BIT, 0,
770 NULL, 0),
771
772 /* MICBIAS */
773 SND_SOC_DAPM_MICBIAS("MICBIAS", WM8991_POWER_MANAGEMENT_1,
774 WM8991_MICBIAS_ENA_BIT, 0),
775
776 SND_SOC_DAPM_OUTPUT("LON"),
777 SND_SOC_DAPM_OUTPUT("LOP"),
778 SND_SOC_DAPM_OUTPUT("OUT3"),
779 SND_SOC_DAPM_OUTPUT("LOUT"),
780 SND_SOC_DAPM_OUTPUT("SPKN"),
781 SND_SOC_DAPM_OUTPUT("SPKP"),
782 SND_SOC_DAPM_OUTPUT("ROUT"),
783 SND_SOC_DAPM_OUTPUT("OUT4"),
784 SND_SOC_DAPM_OUTPUT("ROP"),
785 SND_SOC_DAPM_OUTPUT("RON"),
786 SND_SOC_DAPM_OUTPUT("OUT"),
787
788 SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
789};
790
791static const struct snd_soc_dapm_route audio_map[] = {
792 /* Make DACs turn on when playing even if not mixed into any outputs */
793 {"Internal DAC Sink", NULL, "Left DAC"},
794 {"Internal DAC Sink", NULL, "Right DAC"},
795
796 /* Make ADCs turn on when recording even if not mixed from any inputs */
797 {"Left ADC", NULL, "Internal ADC Source"},
798 {"Right ADC", NULL, "Internal ADC Source"},
799
800 /* Input Side */
801 /* LIN12 PGA */
802 {"LIN12 PGA", "LIN1 Switch", "LIN1"},
803 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
804 /* LIN34 PGA */
805 {"LIN34 PGA", "LIN3 Switch", "LIN3"},
806 {"LIN34 PGA", "LIN4 Switch", "LIN4RXN"},
807 /* INMIXL */
808 {"INMIXL", "Record Left Volume", "LOMIX"},
809 {"INMIXL", "LIN2 Volume", "LIN2"},
810 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
811 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
812 /* AINLMUX */
813 {"AINLMUX", "INMIXL Mix", "INMIXL"},
814 {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
815 {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
816 {"AINLMUX", "RXVOICE Mix", "LIN4RXN"},
817 {"AINLMUX", "RXVOICE Mix", "RIN4RXP"},
818 /* ADC */
819 {"Left ADC", NULL, "AINLMUX"},
820
821 /* RIN12 PGA */
822 {"RIN12 PGA", "RIN1 Switch", "RIN1"},
823 {"RIN12 PGA", "RIN2 Switch", "RIN2"},
824 /* RIN34 PGA */
825 {"RIN34 PGA", "RIN3 Switch", "RIN3"},
826 {"RIN34 PGA", "RIN4 Switch", "RIN4RXP"},
827 /* INMIXL */
828 {"INMIXR", "Record Right Volume", "ROMIX"},
829 {"INMIXR", "RIN2 Volume", "RIN2"},
830 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
831 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
832 /* AINRMUX */
833 {"AINRMUX", "INMIXR Mix", "INMIXR"},
834 {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
835 {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
836 {"AINRMUX", "RXVOICE Mix", "LIN4RXN"},
837 {"AINRMUX", "RXVOICE Mix", "RIN4RXP"},
838 /* ADC */
839 {"Right ADC", NULL, "AINRMUX"},
840
841 /* LOMIX */
842 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
843 {"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
844 {"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
845 {"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
846 {"LOMIX", "LOMIX Right ADC Bypass Switch", "AINRMUX"},
847 {"LOMIX", "LOMIX Left ADC Bypass Switch", "AINLMUX"},
848 {"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
849
850 /* ROMIX */
851 {"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
852 {"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
853 {"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
854 {"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
855 {"ROMIX", "ROMIX Right ADC Bypass Switch", "AINRMUX"},
856 {"ROMIX", "ROMIX Left ADC Bypass Switch", "AINLMUX"},
857 {"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
858
859 /* SPKMIX */
860 {"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
861 {"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
862 {"SPKMIX", "SPKMIX LADC Bypass Switch", "AINLMUX"},
863 {"SPKMIX", "SPKMIX RADC Bypass Switch", "AINRMUX"},
864 {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
865 {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
866 {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
867 {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
868
869 /* LONMIX */
870 {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
871 {"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
872 {"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
873
874 /* LOPMIX */
875 {"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
876 {"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
877 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
878
879 /* OUT3MIX */
880 {"OUT3MIX", "OUT3MIX LIN4RXN Bypass Switch", "LIN4RXN"},
881 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
882
883 /* OUT4MIX */
884 {"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
885 {"OUT4MIX", "OUT4MIX RIN4RXP Bypass Switch", "RIN4RXP"},
886
887 /* RONMIX */
888 {"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
889 {"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
890 {"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
891
892 /* ROPMIX */
893 {"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
894 {"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
895 {"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
896
897 /* Out Mixer PGAs */
898 {"LOPGA", NULL, "LOMIX"},
899 {"ROPGA", NULL, "ROMIX"},
900
901 {"LOUT PGA", NULL, "LOMIX"},
902 {"ROUT PGA", NULL, "ROMIX"},
903
904 /* Output Pins */
905 {"LON", NULL, "LONMIX"},
906 {"LOP", NULL, "LOPMIX"},
907 {"OUT", NULL, "OUT3MIX"},
908 {"LOUT", NULL, "LOUT PGA"},
909 {"SPKN", NULL, "SPKMIX"},
910 {"ROUT", NULL, "ROUT PGA"},
911 {"OUT4", NULL, "OUT4MIX"},
912 {"ROP", NULL, "ROPMIX"},
913 {"RON", NULL, "RONMIX"},
914};
915
916/* PLL divisors */
917struct _pll_div {
918 u32 div2;
919 u32 n;
920 u32 k;
921};
922
923/* The size in bits of the pll divide multiplied by 10
924 * to allow rounding later */
925#define FIXED_PLL_SIZE ((1 << 16) * 10)
926
927static void pll_factors(struct _pll_div *pll_div, unsigned int target,
928 unsigned int source)
929{
930 u64 Kpart;
931 unsigned int K, Ndiv, Nmod;
932
933
934 Ndiv = target / source;
935 if (Ndiv < 6) {
936 source >>= 1;
937 pll_div->div2 = 1;
938 Ndiv = target / source;
939 } else
940 pll_div->div2 = 0;
941
942 if ((Ndiv < 6) || (Ndiv > 12))
943 printk(KERN_WARNING
944 "WM8991 N value outwith recommended range! N = %d\n", Ndiv);
945
946 pll_div->n = Ndiv;
947 Nmod = target % source;
948 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
949
950 do_div(Kpart, source);
951
952 K = Kpart & 0xFFFFFFFF;
953
954 /* Check if we need to round */
955 if ((K % 10) >= 5)
956 K += 5;
957
958 /* Move down to proper range now rounding is done */
959 K /= 10;
960
961 pll_div->k = K;
962}
963
964static int wm8991_set_dai_pll(struct snd_soc_dai *codec_dai,
965 int pll_id, int src, unsigned int freq_in, unsigned int freq_out)
966{
967 u16 reg;
968 struct snd_soc_codec *codec = codec_dai->codec;
969 struct _pll_div pll_div;
970
971 if (freq_in && freq_out) {
972 pll_factors(&pll_div, freq_out * 4, freq_in);
973
974 /* Turn on PLL */
975 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
976 reg |= WM8991_PLL_ENA;
977 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
978
979 /* sysclk comes from PLL */
980 reg = snd_soc_read(codec, WM8991_CLOCKING_2);
981 snd_soc_write(codec, WM8991_CLOCKING_2, reg | WM8991_SYSCLK_SRC);
982
983 /* set up N , fractional mode and pre-divisor if necessary */
984 snd_soc_write(codec, WM8991_PLL1, pll_div.n | WM8991_SDM |
985 (pll_div.div2 ? WM8991_PRESCALE : 0));
986 snd_soc_write(codec, WM8991_PLL2, (u8)(pll_div.k>>8));
987 snd_soc_write(codec, WM8991_PLL3, (u8)(pll_div.k & 0xFF));
988 } else {
989 /* Turn on PLL */
990 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
991 reg &= ~WM8991_PLL_ENA;
992 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg);
993 }
994 return 0;
995}
996
997/*
998 * Set's ADC and Voice DAC format.
999 */
1000static int wm8991_set_dai_fmt(struct snd_soc_dai *codec_dai,
1001 unsigned int fmt)
1002{
1003 struct snd_soc_codec *codec = codec_dai->codec;
1004 u16 audio1, audio3;
1005
1006 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
1007 audio3 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_3);
1008
1009 /* set master/slave audio interface */
1010 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1011 case SND_SOC_DAIFMT_CBS_CFS:
1012 audio3 &= ~WM8991_AIF_MSTR1;
1013 break;
1014 case SND_SOC_DAIFMT_CBM_CFM:
1015 audio3 |= WM8991_AIF_MSTR1;
1016 break;
1017 default:
1018 return -EINVAL;
1019 }
1020
1021 audio1 &= ~WM8991_AIF_FMT_MASK;
1022
1023 /* interface format */
1024 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1025 case SND_SOC_DAIFMT_I2S:
1026 audio1 |= WM8991_AIF_TMF_I2S;
1027 audio1 &= ~WM8991_AIF_LRCLK_INV;
1028 break;
1029 case SND_SOC_DAIFMT_RIGHT_J:
1030 audio1 |= WM8991_AIF_TMF_RIGHTJ;
1031 audio1 &= ~WM8991_AIF_LRCLK_INV;
1032 break;
1033 case SND_SOC_DAIFMT_LEFT_J:
1034 audio1 |= WM8991_AIF_TMF_LEFTJ;
1035 audio1 &= ~WM8991_AIF_LRCLK_INV;
1036 break;
1037 case SND_SOC_DAIFMT_DSP_A:
1038 audio1 |= WM8991_AIF_TMF_DSP;
1039 audio1 &= ~WM8991_AIF_LRCLK_INV;
1040 break;
1041 case SND_SOC_DAIFMT_DSP_B:
1042 audio1 |= WM8991_AIF_TMF_DSP | WM8991_AIF_LRCLK_INV;
1043 break;
1044 default:
1045 return -EINVAL;
1046 }
1047
1048 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
1049 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_3, audio3);
1050 return 0;
1051}
1052
1053static int wm8991_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1054 int div_id, int div)
1055{
1056 struct snd_soc_codec *codec = codec_dai->codec;
1057 u16 reg;
1058
1059 switch (div_id) {
1060 case WM8991_MCLK_DIV:
1061 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1062 ~WM8991_MCLK_DIV_MASK;
1063 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1064 break;
1065 case WM8991_DACCLK_DIV:
1066 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1067 ~WM8991_DAC_CLKDIV_MASK;
1068 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1069 break;
1070 case WM8991_ADCCLK_DIV:
1071 reg = snd_soc_read(codec, WM8991_CLOCKING_2) &
1072 ~WM8991_ADC_CLKDIV_MASK;
1073 snd_soc_write(codec, WM8991_CLOCKING_2, reg | div);
1074 break;
1075 case WM8991_BCLK_DIV:
1076 reg = snd_soc_read(codec, WM8991_CLOCKING_1) &
1077 ~WM8991_BCLK_DIV_MASK;
1078 snd_soc_write(codec, WM8991_CLOCKING_1, reg | div);
1079 break;
1080 default:
1081 return -EINVAL;
1082 }
1083
1084 return 0;
1085}
1086
1087/*
1088 * Set PCM DAI bit size and sample rate.
1089 */
1090static int wm8991_hw_params(struct snd_pcm_substream *substream,
1091 struct snd_pcm_hw_params *params,
1092 struct snd_soc_dai *dai)
1093{
1094 struct snd_soc_codec *codec = dai->codec;
1095 u16 audio1 = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_1);
1096
1097 audio1 &= ~WM8991_AIF_WL_MASK;
1098 /* bit size */
1099 switch (params_format(params)) {
1100 case SNDRV_PCM_FORMAT_S16_LE:
1101 break;
1102 case SNDRV_PCM_FORMAT_S20_3LE:
1103 audio1 |= WM8991_AIF_WL_20BITS;
1104 break;
1105 case SNDRV_PCM_FORMAT_S24_LE:
1106 audio1 |= WM8991_AIF_WL_24BITS;
1107 break;
1108 case SNDRV_PCM_FORMAT_S32_LE:
1109 audio1 |= WM8991_AIF_WL_32BITS;
1110 break;
1111 }
1112
1113 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_1, audio1);
1114 return 0;
1115}
1116
1117static int wm8991_mute(struct snd_soc_dai *dai, int mute)
1118{
1119 struct snd_soc_codec *codec = dai->codec;
1120 u16 val;
1121
1122 val = snd_soc_read(codec, WM8991_DAC_CTRL) & ~WM8991_DAC_MUTE;
1123 if (mute)
1124 snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
1125 else
1126 snd_soc_write(codec, WM8991_DAC_CTRL, val);
1127 return 0;
1128}
1129
1130static int wm8991_set_bias_level(struct snd_soc_codec *codec,
1131 enum snd_soc_bias_level level)
1132{
1133 u16 val;
1134
1135 switch (level) {
1136 case SND_SOC_BIAS_ON:
1137 break;
1138
1139 case SND_SOC_BIAS_PREPARE:
1140 /* VMID=2*50k */
1141 val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
1142 ~WM8991_VMID_MODE_MASK;
1143 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x2);
1144 break;
1145
1146 case SND_SOC_BIAS_STANDBY:
1147 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1148 snd_soc_cache_sync(codec);
1149 /* Enable all output discharge bits */
1150 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1151 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
1152 WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
1153 WM8991_DIS_ROUT);
1154
1155 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1156 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1157 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1158 WM8991_VMIDTOG);
1159
1160 /* Delay to allow output caps to discharge */
1161 msleep(300);
1162
1163 /* Disable VMIDTOG */
1164 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1165 WM8991_BUFDCOPEN | WM8991_POBCTRL);
1166
1167 /* disable all output discharge bits */
1168 snd_soc_write(codec, WM8991_ANTIPOP1, 0);
1169
1170 /* Enable outputs */
1171 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1b00);
1172
1173 msleep(50);
1174
1175 /* Enable VMID at 2x50k */
1176 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f02);
1177
1178 msleep(100);
1179
1180 /* Enable VREF */
1181 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
1182
1183 msleep(600);
1184
1185 /* Enable BUFIOEN */
1186 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1187 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1188 WM8991_BUFIOEN);
1189
1190 /* Disable outputs */
1191 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x3);
1192
1193 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1194 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_BUFIOEN);
1195 }
1196
1197 /* VMID=2*250k */
1198 val = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1) &
1199 ~WM8991_VMID_MODE_MASK;
1200 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, val | 0x4);
1201 break;
1202
1203 case SND_SOC_BIAS_OFF:
1204 /* Enable POBCTRL and SOFT_ST */
1205 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1206 WM8991_POBCTRL | WM8991_BUFIOEN);
1207
1208 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1209 snd_soc_write(codec, WM8991_ANTIPOP2, WM8991_SOFTST |
1210 WM8991_BUFDCOPEN | WM8991_POBCTRL |
1211 WM8991_BUFIOEN);
1212
1213 /* mute DAC */
1214 val = snd_soc_read(codec, WM8991_DAC_CTRL);
1215 snd_soc_write(codec, WM8991_DAC_CTRL, val | WM8991_DAC_MUTE);
1216
1217 /* Enable any disabled outputs */
1218 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f03);
1219
1220 /* Disable VMID */
1221 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x1f01);
1222
1223 msleep(300);
1224
1225 /* Enable all output discharge bits */
1226 snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE |
1227 WM8991_DIS_RLINE | WM8991_DIS_OUT3 |
1228 WM8991_DIS_OUT4 | WM8991_DIS_LOUT |
1229 WM8991_DIS_ROUT);
1230
1231 /* Disable VREF */
1232 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, 0x0);
1233
1234 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1235 snd_soc_write(codec, WM8991_ANTIPOP2, 0x0);
1236 codec->cache_sync = 1;
1237 break;
1238 }
1239
1240 codec->dapm.bias_level = level;
1241 return 0;
1242}
1243
1244static int wm8991_suspend(struct snd_soc_codec *codec, pm_message_t state)
1245{
1246 wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
1247 return 0;
1248}
1249
1250static int wm8991_resume(struct snd_soc_codec *codec)
1251{
1252 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1253 return 0;
1254}
1255
1256/* power down chip */
1257static int wm8991_remove(struct snd_soc_codec *codec)
1258{
1259 wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF);
1260 return 0;
1261}
1262
1263static int wm8991_probe(struct snd_soc_codec *codec)
1264{
1265 struct wm8991_priv *wm8991;
1266 int ret;
1267 unsigned int reg;
1268
1269 wm8991 = snd_soc_codec_get_drvdata(codec);
1270
1271 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type);
1272 if (ret < 0) {
1273 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1274 return ret;
1275 }
1276
1277 ret = wm8991_reset(codec);
1278 if (ret < 0) {
1279 dev_err(codec->dev, "Failed to issue reset\n");
1280 return ret;
1281 }
1282
1283 wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1284
1285 reg = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_4);
1286 snd_soc_write(codec, WM8991_AUDIO_INTERFACE_4, reg | WM8991_ALRCGPIO1);
1287
1288 reg = snd_soc_read(codec, WM8991_GPIO1_GPIO2) &
1289 ~WM8991_GPIO1_SEL_MASK;
1290 snd_soc_write(codec, WM8991_GPIO1_GPIO2, reg | 1);
1291
1292 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1);
1293 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, reg | WM8991_VREF_ENA|
1294 WM8991_VMID_MODE_MASK);
1295
1296 reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2);
1297 snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg | WM8991_OPCLK_ENA);
1298
1299 snd_soc_write(codec, WM8991_DAC_CTRL, 0);
1300 snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1301 snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1302
1303 snd_soc_add_controls(codec, wm8991_snd_controls,
1304 ARRAY_SIZE(wm8991_snd_controls));
1305
1306 snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
1307 ARRAY_SIZE(wm8991_dapm_widgets));
1308 snd_soc_dapm_add_routes(&codec->dapm, audio_map,
1309 ARRAY_SIZE(audio_map));
1310 return 0;
1311}
1312
1313#define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1314 SNDRV_PCM_FMTBIT_S24_LE)
1315
1316static struct snd_soc_dai_ops wm8991_ops = {
1317 .hw_params = wm8991_hw_params,
1318 .digital_mute = wm8991_mute,
1319 .set_fmt = wm8991_set_dai_fmt,
1320 .set_clkdiv = wm8991_set_dai_clkdiv,
1321 .set_pll = wm8991_set_dai_pll
1322};
1323
1324/*
1325 * The WM8991 supports 2 different and mutually exclusive DAI
1326 * configurations.
1327 *
1328 * 1. ADC/DAC on Primary Interface
1329 * 2. ADC on Primary Interface/DAC on secondary
1330 */
1331static struct snd_soc_dai_driver wm8991_dai = {
1332 /* ADC/DAC on primary */
1333 .name = "wm8991",
1334 .id = 1,
1335 .playback = {
1336 .stream_name = "Playback",
1337 .channels_min = 1,
1338 .channels_max = 2,
1339 .rates = SNDRV_PCM_RATE_8000_96000,
1340 .formats = WM8991_FORMATS
1341 },
1342 .capture = {
1343 .stream_name = "Capture",
1344 .channels_min = 1,
1345 .channels_max = 2,
1346 .rates = SNDRV_PCM_RATE_8000_96000,
1347 .formats = WM8991_FORMATS
1348 },
1349 .ops = &wm8991_ops
1350};
1351
1352static struct snd_soc_codec_driver soc_codec_dev_wm8991 = {
1353 .probe = wm8991_probe,
1354 .remove = wm8991_remove,
1355 .suspend = wm8991_suspend,
1356 .resume = wm8991_resume,
1357 .set_bias_level = wm8991_set_bias_level,
1358 .reg_cache_size = WM8991_MAX_REGISTER + 1,
1359 .reg_word_size = sizeof(u16),
1360 .reg_cache_default = wm8991_reg_defs
1361};
1362
1363static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
1364 const struct i2c_device_id *id)
1365{
1366 struct wm8991_priv *wm8991;
1367 int ret;
1368
1369 wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL);
1370 if (!wm8991)
1371 return -ENOMEM;
1372
1373 wm8991->control_type = SND_SOC_I2C;
1374 i2c_set_clientdata(i2c, wm8991);
1375
1376 ret = snd_soc_register_codec(&i2c->dev,
1377 &soc_codec_dev_wm8991, &wm8991_dai, 1);
1378 if (ret < 0)
1379 kfree(wm8991);
1380 return ret;
1381}
1382
1383static __devexit int wm8991_i2c_remove(struct i2c_client *client)
1384{
1385 snd_soc_unregister_codec(&client->dev);
1386 kfree(i2c_get_clientdata(client));
1387 return 0;
1388}
1389
1390static const struct i2c_device_id wm8991_i2c_id[] = {
1391 { "wm8991", 0 },
1392 { }
1393};
1394MODULE_DEVICE_TABLE(i2c, wm8991_i2c_id);
1395
1396static struct i2c_driver wm8991_i2c_driver = {
1397 .driver = {
1398 .name = "wm8991",
1399 .owner = THIS_MODULE,
1400 },
1401 .probe = wm8991_i2c_probe,
1402 .remove = __devexit_p(wm8991_i2c_remove),
1403 .id_table = wm8991_i2c_id,
1404};
1405
1406static int __init wm8991_modinit(void)
1407{
1408 int ret;
1409 ret = i2c_add_driver(&wm8991_i2c_driver);
1410 if (ret != 0) {
1411 printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
1412 ret);
1413 }
1414 return 0;
1415}
1416module_init(wm8991_modinit);
1417
1418static void __exit wm8991_exit(void)
1419{
1420 i2c_del_driver(&wm8991_i2c_driver);
1421}
1422module_exit(wm8991_exit);
1423
1424MODULE_DESCRIPTION("ASoC WM8991 driver");
1425MODULE_AUTHOR("Graeme Gregory");
1426MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h
new file mode 100644
index 000000000000..8a942efd18a5
--- /dev/null
+++ b/sound/soc/codecs/wm8991.h
@@ -0,0 +1,833 @@
1/*
2 * wm8991.h -- audio driver for WM8991
3 *
4 * Copyright 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef _WM8991_H
15#define _WM8991_H
16
17/*
18 * Register values.
19 */
20#define WM8991_RESET 0x00
21#define WM8991_POWER_MANAGEMENT_1 0x01
22#define WM8991_POWER_MANAGEMENT_2 0x02
23#define WM8991_POWER_MANAGEMENT_3 0x03
24#define WM8991_AUDIO_INTERFACE_1 0x04
25#define WM8991_AUDIO_INTERFACE_2 0x05
26#define WM8991_CLOCKING_1 0x06
27#define WM8991_CLOCKING_2 0x07
28#define WM8991_AUDIO_INTERFACE_3 0x08
29#define WM8991_AUDIO_INTERFACE_4 0x09
30#define WM8991_DAC_CTRL 0x0A
31#define WM8991_LEFT_DAC_DIGITAL_VOLUME 0x0B
32#define WM8991_RIGHT_DAC_DIGITAL_VOLUME 0x0C
33#define WM8991_DIGITAL_SIDE_TONE 0x0D
34#define WM8991_ADC_CTRL 0x0E
35#define WM8991_LEFT_ADC_DIGITAL_VOLUME 0x0F
36#define WM8991_RIGHT_ADC_DIGITAL_VOLUME 0x10
37#define WM8991_GPIO_CTRL_1 0x12
38#define WM8991_GPIO1_GPIO2 0x13
39#define WM8991_GPIO3_GPIO4 0x14
40#define WM8991_GPIO5_GPIO6 0x15
41#define WM8991_GPIOCTRL_2 0x16
42#define WM8991_GPIO_POL 0x17
43#define WM8991_LEFT_LINE_INPUT_1_2_VOLUME 0x18
44#define WM8991_LEFT_LINE_INPUT_3_4_VOLUME 0x19
45#define WM8991_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
46#define WM8991_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
47#define WM8991_LEFT_OUTPUT_VOLUME 0x1C
48#define WM8991_RIGHT_OUTPUT_VOLUME 0x1D
49#define WM8991_LINE_OUTPUTS_VOLUME 0x1E
50#define WM8991_OUT3_4_VOLUME 0x1F
51#define WM8991_LEFT_OPGA_VOLUME 0x20
52#define WM8991_RIGHT_OPGA_VOLUME 0x21
53#define WM8991_SPEAKER_VOLUME 0x22
54#define WM8991_CLASSD1 0x23
55#define WM8991_CLASSD3 0x25
56#define WM8991_INPUT_MIXER1 0x27
57#define WM8991_INPUT_MIXER2 0x28
58#define WM8991_INPUT_MIXER3 0x29
59#define WM8991_INPUT_MIXER4 0x2A
60#define WM8991_INPUT_MIXER5 0x2B
61#define WM8991_INPUT_MIXER6 0x2C
62#define WM8991_OUTPUT_MIXER1 0x2D
63#define WM8991_OUTPUT_MIXER2 0x2E
64#define WM8991_OUTPUT_MIXER3 0x2F
65#define WM8991_OUTPUT_MIXER4 0x30
66#define WM8991_OUTPUT_MIXER5 0x31
67#define WM8991_OUTPUT_MIXER6 0x32
68#define WM8991_OUT3_4_MIXER 0x33
69#define WM8991_LINE_MIXER1 0x34
70#define WM8991_LINE_MIXER2 0x35
71#define WM8991_SPEAKER_MIXER 0x36
72#define WM8991_ADDITIONAL_CONTROL 0x37
73#define WM8991_ANTIPOP1 0x38
74#define WM8991_ANTIPOP2 0x39
75#define WM8991_MICBIAS 0x3A
76#define WM8991_PLL1 0x3C
77#define WM8991_PLL2 0x3D
78#define WM8991_PLL3 0x3E
79#define WM8991_INTDRIVBITS 0x3F
80
81#define WM8991_REGISTER_COUNT 60
82#define WM8991_MAX_REGISTER 0x3F
83
84/*
85 * Field Definitions.
86 */
87
88/*
89 * R0 (0x00) - Reset
90 */
91#define WM8991_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET_CHIP_ID - [15:0] */
92
93/*
94 * R1 (0x01) - Power Management (1)
95 */
96#define WM8991_SPK_ENA 0x1000 /* SPK_ENA */
97#define WM8991_SPK_ENA_BIT 12
98#define WM8991_OUT3_ENA 0x0800 /* OUT3_ENA */
99#define WM8991_OUT3_ENA_BIT 11
100#define WM8991_OUT4_ENA 0x0400 /* OUT4_ENA */
101#define WM8991_OUT4_ENA_BIT 10
102#define WM8991_LOUT_ENA 0x0200 /* LOUT_ENA */
103#define WM8991_LOUT_ENA_BIT 9
104#define WM8991_ROUT_ENA 0x0100 /* ROUT_ENA */
105#define WM8991_ROUT_ENA_BIT 8
106#define WM8991_MICBIAS_ENA 0x0010 /* MICBIAS_ENA */
107#define WM8991_MICBIAS_ENA_BIT 4
108#define WM8991_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */
109#define WM8991_VREF_ENA 0x0001 /* VREF_ENA */
110#define WM8991_VREF_ENA_BIT 0
111
112/*
113 * R2 (0x02) - Power Management (2)
114 */
115#define WM8991_PLL_ENA 0x8000 /* PLL_ENA */
116#define WM8991_PLL_ENA_BIT 15
117#define WM8991_TSHUT_ENA 0x4000 /* TSHUT_ENA */
118#define WM8991_TSHUT_ENA_BIT 14
119#define WM8991_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
120#define WM8991_TSHUT_OPDIS_BIT 13
121#define WM8991_OPCLK_ENA 0x0800 /* OPCLK_ENA */
122#define WM8991_OPCLK_ENA_BIT 11
123#define WM8991_AINL_ENA 0x0200 /* AINL_ENA */
124#define WM8991_AINL_ENA_BIT 9
125#define WM8991_AINR_ENA 0x0100 /* AINR_ENA */
126#define WM8991_AINR_ENA_BIT 8
127#define WM8991_LIN34_ENA 0x0080 /* LIN34_ENA */
128#define WM8991_LIN34_ENA_BIT 7
129#define WM8991_LIN12_ENA 0x0040 /* LIN12_ENA */
130#define WM8991_LIN12_ENA_BIT 6
131#define WM8991_RIN34_ENA 0x0020 /* RIN34_ENA */
132#define WM8991_RIN34_ENA_BIT 5
133#define WM8991_RIN12_ENA 0x0010 /* RIN12_ENA */
134#define WM8991_RIN12_ENA_BIT 4
135#define WM8991_ADCL_ENA 0x0002 /* ADCL_ENA */
136#define WM8991_ADCL_ENA_BIT 1
137#define WM8991_ADCR_ENA 0x0001 /* ADCR_ENA */
138#define WM8991_ADCR_ENA_BIT 0
139
140/*
141 * R3 (0x03) - Power Management (3)
142 */
143#define WM8991_LON_ENA 0x2000 /* LON_ENA */
144#define WM8991_LON_ENA_BIT 13
145#define WM8991_LOP_ENA 0x1000 /* LOP_ENA */
146#define WM8991_LOP_ENA_BIT 12
147#define WM8991_RON_ENA 0x0800 /* RON_ENA */
148#define WM8991_RON_ENA_BIT 11
149#define WM8991_ROP_ENA 0x0400 /* ROP_ENA */
150#define WM8991_ROP_ENA_BIT 10
151#define WM8991_LOPGA_ENA 0x0080 /* LOPGA_ENA */
152#define WM8991_LOPGA_ENA_BIT 7
153#define WM8991_ROPGA_ENA 0x0040 /* ROPGA_ENA */
154#define WM8991_ROPGA_ENA_BIT 6
155#define WM8991_LOMIX_ENA 0x0020 /* LOMIX_ENA */
156#define WM8991_LOMIX_ENA_BIT 5
157#define WM8991_ROMIX_ENA 0x0010 /* ROMIX_ENA */
158#define WM8991_ROMIX_ENA_BIT 4
159#define WM8991_DACL_ENA 0x0002 /* DACL_ENA */
160#define WM8991_DACL_ENA_BIT 1
161#define WM8991_DACR_ENA 0x0001 /* DACR_ENA */
162#define WM8991_DACR_ENA_BIT 0
163
164/*
165 * R4 (0x04) - Audio Interface (1)
166 */
167#define WM8991_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
168#define WM8991_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
169#define WM8991_AIFADC_TDM 0x2000 /* AIFADC_TDM */
170#define WM8991_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
171#define WM8991_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
172#define WM8991_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
173#define WM8991_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
174#define WM8991_AIF_WL_16BITS (0 << 5)
175#define WM8991_AIF_WL_20BITS (1 << 5)
176#define WM8991_AIF_WL_24BITS (2 << 5)
177#define WM8991_AIF_WL_32BITS (3 << 5)
178#define WM8991_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
179#define WM8991_AIF_TMF_RIGHTJ (0 << 3)
180#define WM8991_AIF_TMF_LEFTJ (1 << 3)
181#define WM8991_AIF_TMF_I2S (2 << 3)
182#define WM8991_AIF_TMF_DSP (3 << 3)
183
184/*
185 * R5 (0x05) - Audio Interface (2)
186 */
187#define WM8991_DACL_SRC 0x8000 /* DACL_SRC */
188#define WM8991_DACR_SRC 0x4000 /* DACR_SRC */
189#define WM8991_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
190#define WM8991_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
191#define WM8991_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
192#define WM8991_DAC_COMP 0x0010 /* DAC_COMP */
193#define WM8991_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
194#define WM8991_ADC_COMP 0x0004 /* ADC_COMP */
195#define WM8991_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
196#define WM8991_LOOPBACK 0x0001 /* LOOPBACK */
197
198/*
199 * R6 (0x06) - Clocking (1)
200 */
201#define WM8991_TOCLK_RATE 0x8000 /* TOCLK_RATE */
202#define WM8991_TOCLK_ENA 0x4000 /* TOCLK_ENA */
203#define WM8991_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */
204#define WM8991_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
205#define WM8991_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
206#define WM8991_BCLK_DIV_1 (0x0 << 1)
207#define WM8991_BCLK_DIV_1_5 (0x1 << 1)
208#define WM8991_BCLK_DIV_2 (0x2 << 1)
209#define WM8991_BCLK_DIV_3 (0x3 << 1)
210#define WM8991_BCLK_DIV_4 (0x4 << 1)
211#define WM8991_BCLK_DIV_5_5 (0x5 << 1)
212#define WM8991_BCLK_DIV_6 (0x6 << 1)
213#define WM8991_BCLK_DIV_8 (0x7 << 1)
214#define WM8991_BCLK_DIV_11 (0x8 << 1)
215#define WM8991_BCLK_DIV_12 (0x9 << 1)
216#define WM8991_BCLK_DIV_16 (0xA << 1)
217#define WM8991_BCLK_DIV_22 (0xB << 1)
218#define WM8991_BCLK_DIV_24 (0xC << 1)
219#define WM8991_BCLK_DIV_32 (0xD << 1)
220#define WM8991_BCLK_DIV_44 (0xE << 1)
221#define WM8991_BCLK_DIV_48 (0xF << 1)
222
223/*
224 * R7 (0x07) - Clocking (2)
225 */
226#define WM8991_MCLK_SRC 0x8000 /* MCLK_SRC */
227#define WM8991_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
228#define WM8991_CLK_FORCE 0x2000 /* CLK_FORCE */
229#define WM8991_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */
230#define WM8991_MCLK_DIV_1 (0 << 11)
231#define WM8991_MCLK_DIV_2 ( 2 << 11)
232#define WM8991_MCLK_INV 0x0400 /* MCLK_INV */
233#define WM8991_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV - [7:5] */
234#define WM8991_ADC_CLKDIV_1 (0 << 5)
235#define WM8991_ADC_CLKDIV_1_5 (1 << 5)
236#define WM8991_ADC_CLKDIV_2 (2 << 5)
237#define WM8991_ADC_CLKDIV_3 (3 << 5)
238#define WM8991_ADC_CLKDIV_4 (4 << 5)
239#define WM8991_ADC_CLKDIV_5_5 (5 << 5)
240#define WM8991_ADC_CLKDIV_6 (6 << 5)
241#define WM8991_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */
242#define WM8991_DAC_CLKDIV_1 (0 << 2)
243#define WM8991_DAC_CLKDIV_1_5 (1 << 2)
244#define WM8991_DAC_CLKDIV_2 (2 << 2)
245#define WM8991_DAC_CLKDIV_3 (3 << 2)
246#define WM8991_DAC_CLKDIV_4 (4 << 2)
247#define WM8991_DAC_CLKDIV_5_5 (5 << 2)
248#define WM8991_DAC_CLKDIV_6 (6 << 2)
249
250/*
251 * R8 (0x08) - Audio Interface (3)
252 */
253#define WM8991_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
254#define WM8991_AIF_MSTR2 0x4000 /* AIF_MSTR2 */
255#define WM8991_AIF_SEL 0x2000 /* AIF_SEL */
256#define WM8991_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */
257#define WM8991_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE - [10:0] */
258
259/*
260 * R9 (0x09) - Audio Interface (4)
261 */
262#define WM8991_ALRCGPIO1 0x8000 /* ALRCGPIO1 */
263#define WM8991_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */
264#define WM8991_AIF_TRIS 0x2000 /* AIF_TRIS */
265#define WM8991_DACLRC_DIR 0x0800 /* DACLRC_DIR */
266#define WM8991_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE - [10:0] */
267
268/*
269 * R10 (0x0A) - DAC CTRL
270 */
271#define WM8991_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */
272#define WM8991_DAC_MONO 0x0200 /* DAC_MONO */
273#define WM8991_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
274#define WM8991_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
275#define WM8991_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */
276#define WM8991_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */
277#define WM8991_DAC_MUTE 0x0004 /* DAC_MUTE */
278#define WM8991_DACL_DATINV 0x0002 /* DACL_DATINV */
279#define WM8991_DACR_DATINV 0x0001 /* DACR_DATINV */
280
281/*
282 * R11 (0x0B) - Left DAC Digital Volume
283 */
284#define WM8991_DAC_VU 0x0100 /* DAC_VU */
285#define WM8991_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
286#define WM8991_DACL_VOL_SHIFT 0
287/*
288 * R12 (0x0C) - Right DAC Digital Volume
289 */
290#define WM8991_DAC_VU 0x0100 /* DAC_VU */
291#define WM8991_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
292#define WM8991_DACR_VOL_SHIFT 0
293/*
294 * R13 (0x0D) - Digital Side Tone
295 */
296#define WM8991_ADCL_DAC_SVOL_MASK 0x0F /* ADCL_DAC_SVOL - [12:9] */
297#define WM8991_ADCL_DAC_SVOL_SHIFT 9
298#define WM8991_ADCR_DAC_SVOL_MASK 0x0F /* ADCR_DAC_SVOL - [8:5] */
299#define WM8991_ADCR_DAC_SVOL_SHIFT 5
300#define WM8991_ADC_TO_DACL_MASK 0x03 /* ADC_TO_DACL - [3:2] */
301#define WM8991_ADC_TO_DACL_SHIFT 2
302#define WM8991_ADC_TO_DACR_MASK 0x03 /* ADC_TO_DACR - [1:0] */
303#define WM8991_ADC_TO_DACR_SHIFT 0
304
305/*
306 * R14 (0x0E) - ADC CTRL
307 */
308#define WM8991_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */
309#define WM8991_ADC_HPF_ENA_BIT 8
310#define WM8991_ADC_HPF_CUT_MASK 0x03 /* ADC_HPF_CUT - [6:5] */
311#define WM8991_ADC_HPF_CUT_SHIFT 5
312#define WM8991_ADCL_DATINV 0x0002 /* ADCL_DATINV */
313#define WM8991_ADCL_DATINV_BIT 1
314#define WM8991_ADCR_DATINV 0x0001 /* ADCR_DATINV */
315#define WM8991_ADCR_DATINV_BIT 0
316
317/*
318 * R15 (0x0F) - Left ADC Digital Volume
319 */
320#define WM8991_ADC_VU 0x0100 /* ADC_VU */
321#define WM8991_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
322#define WM8991_ADCL_VOL_SHIFT 0
323
324/*
325 * R16 (0x10) - Right ADC Digital Volume
326 */
327#define WM8991_ADC_VU 0x0100 /* ADC_VU */
328#define WM8991_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
329#define WM8991_ADCR_VOL_SHIFT 0
330
331/*
332 * R18 (0x12) - GPIO CTRL 1
333 */
334#define WM8991_IRQ 0x1000 /* IRQ */
335#define WM8991_TEMPOK 0x0800 /* TEMPOK */
336#define WM8991_MICSHRT 0x0400 /* MICSHRT */
337#define WM8991_MICDET 0x0200 /* MICDET */
338#define WM8991_PLL_LCK 0x0100 /* PLL_LCK */
339#define WM8991_GPI8_STATUS 0x0080 /* GPI8_STATUS */
340#define WM8991_GPI7_STATUS 0x0040 /* GPI7_STATUS */
341#define WM8991_GPIO6_STATUS 0x0020 /* GPIO6_STATUS */
342#define WM8991_GPIO5_STATUS 0x0010 /* GPIO5_STATUS */
343#define WM8991_GPIO4_STATUS 0x0008 /* GPIO4_STATUS */
344#define WM8991_GPIO3_STATUS 0x0004 /* GPIO3_STATUS */
345#define WM8991_GPIO2_STATUS 0x0002 /* GPIO2_STATUS */
346#define WM8991_GPIO1_STATUS 0x0001 /* GPIO1_STATUS */
347
348/*
349 * R19 (0x13) - GPIO1 & GPIO2
350 */
351#define WM8991_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */
352#define WM8991_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */
353#define WM8991_GPIO2_PU 0x2000 /* GPIO2_PU */
354#define WM8991_GPIO2_PD 0x1000 /* GPIO2_PD */
355#define WM8991_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */
356#define WM8991_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */
357#define WM8991_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */
358#define WM8991_GPIO1_PU 0x0020 /* GPIO1_PU */
359#define WM8991_GPIO1_PD 0x0010 /* GPIO1_PD */
360#define WM8991_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
361
362/*
363 * R20 (0x14) - GPIO3 & GPIO4
364 */
365#define WM8991_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */
366#define WM8991_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */
367#define WM8991_GPIO4_PU 0x2000 /* GPIO4_PU */
368#define WM8991_GPIO4_PD 0x1000 /* GPIO4_PD */
369#define WM8991_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */
370#define WM8991_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */
371#define WM8991_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */
372#define WM8991_GPIO3_PU 0x0020 /* GPIO3_PU */
373#define WM8991_GPIO3_PD 0x0010 /* GPIO3_PD */
374#define WM8991_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
375
376/*
377 * R21 (0x15) - GPIO5 & GPIO6
378 */
379#define WM8991_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */
380#define WM8991_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */
381#define WM8991_GPIO6_PU 0x2000 /* GPIO6_PU */
382#define WM8991_GPIO6_PD 0x1000 /* GPIO6_PD */
383#define WM8991_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */
384#define WM8991_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */
385#define WM8991_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */
386#define WM8991_GPIO5_PU 0x0020 /* GPIO5_PU */
387#define WM8991_GPIO5_PD 0x0010 /* GPIO5_PD */
388#define WM8991_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */
389
390/*
391 * R22 (0x16) - GPIOCTRL 2
392 */
393#define WM8991_RD_3W_ENA 0x8000 /* RD_3W_ENA */
394#define WM8991_MODE_3W4W 0x4000 /* MODE_3W4W */
395#define WM8991_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */
396#define WM8991_MICSHRT_IRQ_ENA 0x0400 /* MICSHRT_IRQ_ENA */
397#define WM8991_MICDET_IRQ_ENA 0x0200 /* MICDET_IRQ_ENA */
398#define WM8991_PLL_LCK_IRQ_ENA 0x0100 /* PLL_LCK_IRQ_ENA */
399#define WM8991_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */
400#define WM8991_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */
401#define WM8991_GPI8_ENA 0x0010 /* GPI8_ENA */
402#define WM8991_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */
403#define WM8991_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */
404#define WM8991_GPI7_ENA 0x0001 /* GPI7_ENA */
405
406/*
407 * R23 (0x17) - GPIO_POL
408 */
409#define WM8991_IRQ_INV 0x1000 /* IRQ_INV */
410#define WM8991_TEMPOK_POL 0x0800 /* TEMPOK_POL */
411#define WM8991_MICSHRT_POL 0x0400 /* MICSHRT_POL */
412#define WM8991_MICDET_POL 0x0200 /* MICDET_POL */
413#define WM8991_PLL_LCK_POL 0x0100 /* PLL_LCK_POL */
414#define WM8991_GPI8_POL 0x0080 /* GPI8_POL */
415#define WM8991_GPI7_POL 0x0040 /* GPI7_POL */
416#define WM8991_GPIO6_POL 0x0020 /* GPIO6_POL */
417#define WM8991_GPIO5_POL 0x0010 /* GPIO5_POL */
418#define WM8991_GPIO4_POL 0x0008 /* GPIO4_POL */
419#define WM8991_GPIO3_POL 0x0004 /* GPIO3_POL */
420#define WM8991_GPIO2_POL 0x0002 /* GPIO2_POL */
421#define WM8991_GPIO1_POL 0x0001 /* GPIO1_POL */
422
423/*
424 * R24 (0x18) - Left Line Input 1&2 Volume
425 */
426#define WM8991_IPVU 0x0100 /* IPVU */
427#define WM8991_LI12MUTE 0x0080 /* LI12MUTE */
428#define WM8991_LI12MUTE_BIT 7
429#define WM8991_LI12ZC 0x0040 /* LI12ZC */
430#define WM8991_LI12ZC_BIT 6
431#define WM8991_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */
432#define WM8991_LIN12VOL_SHIFT 0
433/*
434 * R25 (0x19) - Left Line Input 3&4 Volume
435 */
436#define WM8991_IPVU 0x0100 /* IPVU */
437#define WM8991_LI34MUTE 0x0080 /* LI34MUTE */
438#define WM8991_LI34MUTE_BIT 7
439#define WM8991_LI34ZC 0x0040 /* LI34ZC */
440#define WM8991_LI34ZC_BIT 6
441#define WM8991_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */
442#define WM8991_LIN34VOL_SHIFT 0
443
444/*
445 * R26 (0x1A) - Right Line Input 1&2 Volume
446 */
447#define WM8991_IPVU 0x0100 /* IPVU */
448#define WM8991_RI12MUTE 0x0080 /* RI12MUTE */
449#define WM8991_RI12MUTE_BIT 7
450#define WM8991_RI12ZC 0x0040 /* RI12ZC */
451#define WM8991_RI12ZC_BIT 6
452#define WM8991_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */
453#define WM8991_RIN12VOL_SHIFT 0
454
455/*
456 * R27 (0x1B) - Right Line Input 3&4 Volume
457 */
458#define WM8991_IPVU 0x0100 /* IPVU */
459#define WM8991_RI34MUTE 0x0080 /* RI34MUTE */
460#define WM8991_RI34MUTE_BIT 7
461#define WM8991_RI34ZC 0x0040 /* RI34ZC */
462#define WM8991_RI34ZC_BIT 6
463#define WM8991_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */
464#define WM8991_RIN34VOL_SHIFT 0
465
466/*
467 * R28 (0x1C) - Left Output Volume
468 */
469#define WM8991_OPVU 0x0100 /* OPVU */
470#define WM8991_LOZC 0x0080 /* LOZC */
471#define WM8991_LOZC_BIT 7
472#define WM8991_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
473#define WM8991_LOUTVOL_SHIFT 0
474/*
475 * R29 (0x1D) - Right Output Volume
476 */
477#define WM8991_OPVU 0x0100 /* OPVU */
478#define WM8991_ROZC 0x0080 /* ROZC */
479#define WM8991_ROZC_BIT 7
480#define WM8991_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
481#define WM8991_ROUTVOL_SHIFT 0
482/*
483 * R30 (0x1E) - Line Outputs Volume
484 */
485#define WM8991_LONMUTE 0x0040 /* LONMUTE */
486#define WM8991_LONMUTE_BIT 6
487#define WM8991_LOPMUTE 0x0020 /* LOPMUTE */
488#define WM8991_LOPMUTE_BIT 5
489#define WM8991_LOATTN 0x0010 /* LOATTN */
490#define WM8991_LOATTN_BIT 4
491#define WM8991_RONMUTE 0x0004 /* RONMUTE */
492#define WM8991_RONMUTE_BIT 2
493#define WM8991_ROPMUTE 0x0002 /* ROPMUTE */
494#define WM8991_ROPMUTE_BIT 1
495#define WM8991_ROATTN 0x0001 /* ROATTN */
496#define WM8991_ROATTN_BIT 0
497
498/*
499 * R31 (0x1F) - Out3/4 Volume
500 */
501#define WM8991_OUT3MUTE 0x0020 /* OUT3MUTE */
502#define WM8991_OUT3MUTE_BIT 5
503#define WM8991_OUT3ATTN 0x0010 /* OUT3ATTN */
504#define WM8991_OUT3ATTN_BIT 4
505#define WM8991_OUT4MUTE 0x0002 /* OUT4MUTE */
506#define WM8991_OUT4MUTE_BIT 1
507#define WM8991_OUT4ATTN 0x0001 /* OUT4ATTN */
508#define WM8991_OUT4ATTN_BIT 0
509
510/*
511 * R32 (0x20) - Left OPGA Volume
512 */
513#define WM8991_OPVU 0x0100 /* OPVU */
514#define WM8991_LOPGAZC 0x0080 /* LOPGAZC */
515#define WM8991_LOPGAZC_BIT 7
516#define WM8991_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */
517#define WM8991_LOPGAVOL_SHIFT 0
518
519/*
520 * R33 (0x21) - Right OPGA Volume
521 */
522#define WM8991_OPVU 0x0100 /* OPVU */
523#define WM8991_ROPGAZC 0x0080 /* ROPGAZC */
524#define WM8991_ROPGAZC_BIT 7
525#define WM8991_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */
526#define WM8991_ROPGAVOL_SHIFT 0
527/*
528 * R34 (0x22) - Speaker Volume
529 */
530#define WM8991_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */
531#define WM8991_SPKVOL_SHIFT 0
532
533/*
534 * R35 (0x23) - ClassD1
535 */
536#define WM8991_CDMODE 0x0100 /* CDMODE */
537#define WM8991_CDMODE_BIT 8
538
539/*
540 * R37 (0x25) - ClassD3
541 */
542#define WM8991_DCGAIN_MASK 0x0007 /* DCGAIN - [5:3] */
543#define WM8991_DCGAIN_SHIFT 3
544#define WM8991_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */
545#define WM8991_ACGAIN_SHIFT 0
546/*
547 * R39 (0x27) - Input Mixer1
548 */
549#define WM8991_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */
550#define WM8991_AINLMODE_SHIFT 2
551#define WM8991_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */
552#define WM8991_AINRMODE_SHIFT 0
553
554/*
555 * R40 (0x28) - Input Mixer2
556 */
557#define WM8991_LMP4 0x0080 /* LMP4 */
558#define WM8991_LMP4_BIT 7 /* LMP4 */
559#define WM8991_LMN3 0x0040 /* LMN3 */
560#define WM8991_LMN3_BIT 6 /* LMN3 */
561#define WM8991_LMP2 0x0020 /* LMP2 */
562#define WM8991_LMP2_BIT 5 /* LMP2 */
563#define WM8991_LMN1 0x0010 /* LMN1 */
564#define WM8991_LMN1_BIT 4 /* LMN1 */
565#define WM8991_RMP4 0x0008 /* RMP4 */
566#define WM8991_RMP4_BIT 3 /* RMP4 */
567#define WM8991_RMN3 0x0004 /* RMN3 */
568#define WM8991_RMN3_BIT 2 /* RMN3 */
569#define WM8991_RMP2 0x0002 /* RMP2 */
570#define WM8991_RMP2_BIT 1 /* RMP2 */
571#define WM8991_RMN1 0x0001 /* RMN1 */
572#define WM8991_RMN1_BIT 0 /* RMN1 */
573
574/*
575 * R41 (0x29) - Input Mixer3
576 */
577#define WM8991_L34MNB 0x0100 /* L34MNB */
578#define WM8991_L34MNB_BIT 8
579#define WM8991_L34MNBST 0x0080 /* L34MNBST */
580#define WM8991_L34MNBST_BIT 7
581#define WM8991_L12MNB 0x0020 /* L12MNB */
582#define WM8991_L12MNB_BIT 5
583#define WM8991_L12MNBST 0x0010 /* L12MNBST */
584#define WM8991_L12MNBST_BIT 4
585#define WM8991_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */
586#define WM8991_LDBVOL_SHIFT 0
587
588/*
589 * R42 (0x2A) - Input Mixer4
590 */
591#define WM8991_R34MNB 0x0100 /* R34MNB */
592#define WM8991_R34MNB_BIT 8
593#define WM8991_R34MNBST 0x0080 /* R34MNBST */
594#define WM8991_R34MNBST_BIT 7
595#define WM8991_R12MNB 0x0020 /* R12MNB */
596#define WM8991_R12MNB_BIT 5
597#define WM8991_R12MNBST 0x0010 /* R12MNBST */
598#define WM8991_R12MNBST_BIT 4
599#define WM8991_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */
600#define WM8991_RDBVOL_SHIFT 0
601
602/*
603 * R43 (0x2B) - Input Mixer5
604 */
605#define WM8991_LI2BVOL_MASK 0x07 /* LI2BVOL - [8:6] */
606#define WM8991_LI2BVOL_SHIFT 6
607#define WM8991_LR4BVOL_MASK 0x07 /* LR4BVOL - [5:3] */
608#define WM8991_LR4BVOL_SHIFT 3
609#define WM8991_LL4BVOL_MASK 0x07 /* LL4BVOL - [2:0] */
610#define WM8991_LL4BVOL_SHIFT 0
611
612/*
613 * R44 (0x2C) - Input Mixer6
614 */
615#define WM8991_RI2BVOL_MASK 0x07 /* RI2BVOL - [8:6] */
616#define WM8991_RI2BVOL_SHIFT 6
617#define WM8991_RL4BVOL_MASK 0x07 /* RL4BVOL - [5:3] */
618#define WM8991_RL4BVOL_SHIFT 3
619#define WM8991_RR4BVOL_MASK 0x07 /* RR4BVOL - [2:0] */
620#define WM8991_RR4BVOL_SHIFT 0
621
622/*
623 * R45 (0x2D) - Output Mixer1
624 */
625#define WM8991_LRBLO 0x0080 /* LRBLO */
626#define WM8991_LRBLO_BIT 7
627#define WM8991_LLBLO 0x0040 /* LLBLO */
628#define WM8991_LLBLO_BIT 6
629#define WM8991_LRI3LO 0x0020 /* LRI3LO */
630#define WM8991_LRI3LO_BIT 5
631#define WM8991_LLI3LO 0x0010 /* LLI3LO */
632#define WM8991_LLI3LO_BIT 4
633#define WM8991_LR12LO 0x0008 /* LR12LO */
634#define WM8991_LR12LO_BIT 3
635#define WM8991_LL12LO 0x0004 /* LL12LO */
636#define WM8991_LL12LO_BIT 2
637#define WM8991_LDLO 0x0001 /* LDLO */
638#define WM8991_LDLO_BIT 0
639
640/*
641 * R46 (0x2E) - Output Mixer2
642 */
643#define WM8991_RLBRO 0x0080 /* RLBRO */
644#define WM8991_RLBRO_BIT 7
645#define WM8991_RRBRO 0x0040 /* RRBRO */
646#define WM8991_RRBRO_BIT 6
647#define WM8991_RLI3RO 0x0020 /* RLI3RO */
648#define WM8991_RLI3RO_BIT 5
649#define WM8991_RRI3RO 0x0010 /* RRI3RO */
650#define WM8991_RRI3RO_BIT 4
651#define WM8991_RL12RO 0x0008 /* RL12RO */
652#define WM8991_RL12RO_BIT 3
653#define WM8991_RR12RO 0x0004 /* RR12RO */
654#define WM8991_RR12RO_BIT 2
655#define WM8991_RDRO 0x0001 /* RDRO */
656#define WM8991_RDRO_BIT 0
657
658/*
659 * R47 (0x2F) - Output Mixer3
660 */
661#define WM8991_LLI3LOVOL_MASK 0x07 /* LLI3LOVOL - [8:6] */
662#define WM8991_LLI3LOVOL_SHIFT 6
663#define WM8991_LR12LOVOL_MASK 0x07 /* LR12LOVOL - [5:3] */
664#define WM8991_LR12LOVOL_SHIFT 3
665#define WM8991_LL12LOVOL_MASK 0x07 /* LL12LOVOL - [2:0] */
666#define WM8991_LL12LOVOL_SHIFT 0
667
668/*
669 * R48 (0x30) - Output Mixer4
670 */
671#define WM8991_RRI3ROVOL_MASK 0x07 /* RRI3ROVOL - [8:6] */
672#define WM8991_RRI3ROVOL_SHIFT 6
673#define WM8991_RL12ROVOL_MASK 0x07 /* RL12ROVOL - [5:3] */
674#define WM8991_RL12ROVOL_SHIFT 3
675#define WM8991_RR12ROVOL_MASK 0x07 /* RR12ROVOL - [2:0] */
676#define WM8991_RR12ROVOL_SHIFT 0
677
678/*
679 * R49 (0x31) - Output Mixer5
680 */
681#define WM8991_LRI3LOVOL_MASK 0x07 /* LRI3LOVOL - [8:6] */
682#define WM8991_LRI3LOVOL_SHIFT 6
683#define WM8991_LRBLOVOL_MASK 0x07 /* LRBLOVOL - [5:3] */
684#define WM8991_LRBLOVOL_SHIFT 3
685#define WM8991_LLBLOVOL_MASK 0x07 /* LLBLOVOL - [2:0] */
686#define WM8991_LLBLOVOL_SHIFT 0
687
688/*
689 * R50 (0x32) - Output Mixer6
690 */
691#define WM8991_RLI3ROVOL_MASK 0x07 /* RLI3ROVOL - [8:6] */
692#define WM8991_RLI3ROVOL_SHIFT 6
693#define WM8991_RLBROVOL_MASK 0x07 /* RLBROVOL - [5:3] */
694#define WM8991_RLBROVOL_SHIFT 3
695#define WM8991_RRBROVOL_MASK 0x07 /* RRBROVOL - [2:0] */
696#define WM8991_RRBROVOL_SHIFT 0
697
698/*
699 * R51 (0x33) - Out3/4 Mixer
700 */
701#define WM8991_VSEL_MASK 0x0180 /* VSEL - [8:7] */
702#define WM8991_LI4O3 0x0020 /* LI4O3 */
703#define WM8991_LI4O3_BIT 5
704#define WM8991_LPGAO3 0x0010 /* LPGAO3 */
705#define WM8991_LPGAO3_BIT 4
706#define WM8991_RI4O4 0x0002 /* RI4O4 */
707#define WM8991_RI4O4_BIT 1
708#define WM8991_RPGAO4 0x0001 /* RPGAO4 */
709#define WM8991_RPGAO4_BIT 0
710/*
711 * R52 (0x34) - Line Mixer1
712 */
713#define WM8991_LLOPGALON 0x0040 /* LLOPGALON */
714#define WM8991_LLOPGALON_BIT 6
715#define WM8991_LROPGALON 0x0020 /* LROPGALON */
716#define WM8991_LROPGALON_BIT 5
717#define WM8991_LOPLON 0x0010 /* LOPLON */
718#define WM8991_LOPLON_BIT 4
719#define WM8991_LR12LOP 0x0004 /* LR12LOP */
720#define WM8991_LR12LOP_BIT 2
721#define WM8991_LL12LOP 0x0002 /* LL12LOP */
722#define WM8991_LL12LOP_BIT 1
723#define WM8991_LLOPGALOP 0x0001 /* LLOPGALOP */
724#define WM8991_LLOPGALOP_BIT 0
725/*
726 * R53 (0x35) - Line Mixer2
727 */
728#define WM8991_RROPGARON 0x0040 /* RROPGARON */
729#define WM8991_RROPGARON_BIT 6
730#define WM8991_RLOPGARON 0x0020 /* RLOPGARON */
731#define WM8991_RLOPGARON_BIT 5
732#define WM8991_ROPRON 0x0010 /* ROPRON */
733#define WM8991_ROPRON_BIT 4
734#define WM8991_RL12ROP 0x0004 /* RL12ROP */
735#define WM8991_RL12ROP_BIT 2
736#define WM8991_RR12ROP 0x0002 /* RR12ROP */
737#define WM8991_RR12ROP_BIT 1
738#define WM8991_RROPGAROP 0x0001 /* RROPGAROP */
739#define WM8991_RROPGAROP_BIT 0
740
741/*
742 * R54 (0x36) - Speaker Mixer
743 */
744#define WM8991_LB2SPK 0x0080 /* LB2SPK */
745#define WM8991_LB2SPK_BIT 7
746#define WM8991_RB2SPK 0x0040 /* RB2SPK */
747#define WM8991_RB2SPK_BIT 6
748#define WM8991_LI2SPK 0x0020 /* LI2SPK */
749#define WM8991_LI2SPK_BIT 5
750#define WM8991_RI2SPK 0x0010 /* RI2SPK */
751#define WM8991_RI2SPK_BIT 4
752#define WM8991_LOPGASPK 0x0008 /* LOPGASPK */
753#define WM8991_LOPGASPK_BIT 3
754#define WM8991_ROPGASPK 0x0004 /* ROPGASPK */
755#define WM8991_ROPGASPK_BIT 2
756#define WM8991_LDSPK 0x0002 /* LDSPK */
757#define WM8991_LDSPK_BIT 1
758#define WM8991_RDSPK 0x0001 /* RDSPK */
759#define WM8991_RDSPK_BIT 0
760
761/*
762 * R55 (0x37) - Additional Control
763 */
764#define WM8991_VROI 0x0001 /* VROI */
765
766/*
767 * R56 (0x38) - AntiPOP1
768 */
769#define WM8991_DIS_LLINE 0x0020 /* DIS_LLINE */
770#define WM8991_DIS_RLINE 0x0010 /* DIS_RLINE */
771#define WM8991_DIS_OUT3 0x0008 /* DIS_OUT3 */
772#define WM8991_DIS_OUT4 0x0004 /* DIS_OUT4 */
773#define WM8991_DIS_LOUT 0x0002 /* DIS_LOUT */
774#define WM8991_DIS_ROUT 0x0001 /* DIS_ROUT */
775
776/*
777 * R57 (0x39) - AntiPOP2
778 */
779#define WM8991_SOFTST 0x0040 /* SOFTST */
780#define WM8991_BUFIOEN 0x0008 /* BUFIOEN */
781#define WM8991_BUFDCOPEN 0x0004 /* BUFDCOPEN */
782#define WM8991_POBCTRL 0x0002 /* POBCTRL */
783#define WM8991_VMIDTOG 0x0001 /* VMIDTOG */
784
785/*
786 * R58 (0x3A) - MICBIAS
787 */
788#define WM8991_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */
789#define WM8991_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */
790#define WM8991_MCD 0x0004 /* MCD */
791#define WM8991_MBSEL 0x0001 /* MBSEL */
792
793/*
794 * R60 (0x3C) - PLL1
795 */
796#define WM8991_SDM 0x0080 /* SDM */
797#define WM8991_PRESCALE 0x0040 /* PRESCALE */
798#define WM8991_PLLN_MASK 0x000F /* PLLN - [3:0] */
799
800/*
801 * R61 (0x3D) - PLL2
802 */
803#define WM8991_PLLK1_MASK 0x00FF /* PLLK1 - [7:0] */
804
805/*
806 * R62 (0x3E) - PLL3
807 */
808#define WM8991_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */
809
810/*
811 * R63 (0x3F) - Internal Driver Bits
812 */
813#define WM8991_INMIXL_PWR_BIT 0
814#define WM8991_AINLMUX_PWR_BIT 1
815#define WM8991_INMIXR_PWR_BIT 2
816#define WM8991_AINRMUX_PWR_BIT 3
817
818#define WM8991_MCLK_DIV 0
819#define WM8991_DACCLK_DIV 1
820#define WM8991_ADCCLK_DIV 2
821#define WM8991_BCLK_DIV 3
822
823#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
824 tlv_array) \
825{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
826 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
827 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
828 .tlv.p = (tlv_array), \
829 .info = snd_soc_info_volsw, \
830 .get = snd_soc_get_volsw, .put = wm899x_outpga_put_volsw_vu, \
831 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
832
833#endif /* _WM8991_H */
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d8d300c6175f..9e5ff789b805 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -24,7 +24,6 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/tlv.h> 25#include <sound/tlv.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/wm8993.h> 28#include <sound/wm8993.h>
30 29
@@ -226,10 +225,9 @@ static struct {
226 225
227struct wm8993_priv { 226struct wm8993_priv {
228 struct wm_hubs_data hubs_data; 227 struct wm_hubs_data hubs_data;
229 u16 reg_cache[WM8993_REGISTER_COUNT];
230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; 228 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
231 struct wm8993_platform_data pdata; 229 struct wm8993_platform_data pdata;
232 struct snd_soc_codec codec; 230 enum snd_soc_control_type control_type;
233 int master; 231 int master;
234 int sysclk_source; 232 int sysclk_source;
235 int tdm_slots; 233 int tdm_slots;
@@ -244,7 +242,7 @@ struct wm8993_priv {
244 int fll_src; 242 int fll_src;
245}; 243};
246 244
247static int wm8993_volatile(unsigned int reg) 245static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg)
248{ 246{
249 switch (reg) { 247 switch (reg) {
250 case WM8993_SOFTWARE_RESET: 248 case WM8993_SOFTWARE_RESET:
@@ -326,7 +324,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
326 324
327 pr_debug("Fvco=%dHz\n", target); 325 pr_debug("Fvco=%dHz\n", target);
328 326
329 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 327 /* Find an appropriate FLL_FRATIO and factor it out of the target */
330 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 328 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
331 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 329 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
332 fll_div->fll_fratio = fll_fratios[i].fll_fratio; 330 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
@@ -367,10 +365,9 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
367 return 0; 365 return 0;
368} 366}
369 367
370static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, 368static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
371 unsigned int Fref, unsigned int Fout) 369 unsigned int Fref, unsigned int Fout)
372{ 370{
373 struct snd_soc_codec *codec = dai->codec;
374 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 371 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
375 u16 reg1, reg4, reg5; 372 u16 reg1, reg4, reg5;
376 struct _fll_div fll_div; 373 struct _fll_div fll_div;
@@ -456,6 +453,12 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
456 return 0; 453 return 0;
457} 454}
458 455
456static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
457 unsigned int Fref, unsigned int Fout)
458{
459 return _wm8993_set_fll(dai->codec, fll_id, source, Fref, Fout);
460}
461
459static int configure_clock(struct snd_soc_codec *codec) 462static int configure_clock(struct snd_soc_codec *codec)
460{ 463{
461 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 464 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
@@ -715,7 +718,8 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
715static int class_w_put(struct snd_kcontrol *kcontrol, 718static int class_w_put(struct snd_kcontrol *kcontrol,
716 struct snd_ctl_elem_value *ucontrol) 719 struct snd_ctl_elem_value *ucontrol)
717{ 720{
718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 721 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
722 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
719 struct snd_soc_codec *codec = widget->codec; 723 struct snd_soc_codec *codec = widget->codec;
720 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 724 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
721 int ret; 725 int ret;
@@ -730,6 +734,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
730 0); 734 0);
731 } 735 }
732 wm8993->class_w_users++; 736 wm8993->class_w_users++;
737 wm8993->hubs_data.class_w = true;
733 } 738 }
734 739
735 /* Implement the change */ 740 /* Implement the change */
@@ -746,6 +751,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
746 WM8993_CP_DYN_V); 751 WM8993_CP_DYN_V);
747 } 752 }
748 wm8993->class_w_users--; 753 wm8993->class_w_users--;
754 wm8993->hubs_data.class_w = false;
749 } 755 }
750 756
751 dev_dbg(codec->dev, "Indirect DAC use count now %d\n", 757 dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
@@ -963,7 +969,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
963 break; 969 break;
964 970
965 case SND_SOC_BIAS_STANDBY: 971 case SND_SOC_BIAS_STANDBY:
966 if (codec->bias_level == SND_SOC_BIAS_OFF) { 972 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
967 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), 973 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
968 wm8993->supplies); 974 wm8993->supplies);
969 if (ret != 0) 975 if (ret != 0)
@@ -1024,6 +1030,12 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1024 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1030 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1025 0); 1031 0);
1026 1032
1033 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1034 WM8993_STARTUP_BIAS_ENA |
1035 WM8993_VMID_BUF_ENA |
1036 WM8993_VMID_RAMP_MASK |
1037 WM8993_BIAS_SRC, 0);
1038
1027#ifdef CONFIG_REGULATOR 1039#ifdef CONFIG_REGULATOR
1028 /* Post 2.6.34 we will be able to get a callback when 1040 /* Post 2.6.34 we will be able to get a callback when
1029 * the regulators are disabled which we can use but 1041 * the regulators are disabled which we can use but
@@ -1038,7 +1050,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1038 break; 1050 break;
1039 } 1051 }
1040 1052
1041 codec->bias_level = level; 1053 codec->dapm.bias_level = level;
1042 1054
1043 return 0; 1055 return 0;
1044} 1056}
@@ -1220,7 +1232,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1220 - wm8993->fs); 1232 - wm8993->fs);
1221 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { 1233 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1222 cur_val = abs((wm8993->sysclk_rate / 1234 cur_val = abs((wm8993->sysclk_rate /
1223 clk_sys_rates[i].ratio) - wm8993->fs);; 1235 clk_sys_rates[i].ratio) - wm8993->fs);
1224 if (cur_val < best_val) { 1236 if (cur_val < best_val) {
1225 best = i; 1237 best = i;
1226 best_val = cur_val; 1238 best_val = cur_val;
@@ -1394,8 +1406,8 @@ static struct snd_soc_dai_ops wm8993_ops = {
1394 SNDRV_PCM_FMTBIT_S24_LE |\ 1406 SNDRV_PCM_FMTBIT_S24_LE |\
1395 SNDRV_PCM_FMTBIT_S32_LE) 1407 SNDRV_PCM_FMTBIT_S32_LE)
1396 1408
1397struct snd_soc_dai wm8993_dai = { 1409static struct snd_soc_dai_driver wm8993_dai = {
1398 .name = "WM8993", 1410 .name = "wm8993-hifi",
1399 .playback = { 1411 .playback = {
1400 .stream_name = "Playback", 1412 .stream_name = "Playback",
1401 .channels_min = 1, 1413 .channels_min = 1,
@@ -1413,32 +1425,82 @@ struct snd_soc_dai wm8993_dai = {
1413 .ops = &wm8993_ops, 1425 .ops = &wm8993_ops,
1414 .symmetric_rates = 1, 1426 .symmetric_rates = 1,
1415}; 1427};
1416EXPORT_SYMBOL_GPL(wm8993_dai);
1417
1418static struct snd_soc_codec *wm8993_codec;
1419 1428
1420static int wm8993_probe(struct platform_device *pdev) 1429static int wm8993_probe(struct snd_soc_codec *codec)
1421{ 1430{
1422 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1431 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1423 struct snd_soc_codec *codec; 1432 struct snd_soc_dapm_context *dapm = &codec->dapm;
1424 struct wm8993_priv *wm8993; 1433 int ret, i, val;
1425 int ret = 0;
1426 1434
1427 if (!wm8993_codec) { 1435 wm8993->hubs_data.hp_startup_mode = 1;
1428 dev_err(&pdev->dev, "I2C device not yet probed\n"); 1436 wm8993->hubs_data.dcs_codes = -2;
1429 goto err; 1437
1438 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1439 if (ret != 0) {
1440 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1441 return ret;
1430 } 1442 }
1431 1443
1432 socdev->card->codec = wm8993_codec; 1444 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1433 codec = wm8993_codec; 1445 wm8993->supplies[i].supply = wm8993_supply_names[i];
1434 wm8993 = snd_soc_codec_get_drvdata(codec);
1435 1446
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1447 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1437 if (ret < 0) { 1448 wm8993->supplies);
1438 dev_err(codec->dev, "failed to create pcms\n"); 1449 if (ret != 0) {
1439 goto err; 1450 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1451 return ret;
1452 }
1453
1454 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1455 wm8993->supplies);
1456 if (ret != 0) {
1457 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1458 goto err_get;
1440 } 1459 }
1441 1460
1461 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1462 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1463 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1464 ret = -EINVAL;
1465 goto err_enable;
1466 }
1467
1468 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1469 if (ret != 0)
1470 goto err_enable;
1471
1472 codec->cache_only = 1;
1473
1474 /* By default we're using the output mixers */
1475 wm8993->class_w_users = 2;
1476
1477 /* Latch volume update bits and default ZC on */
1478 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1479 WM8993_DAC_VU, WM8993_DAC_VU);
1480 snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
1481 WM8993_ADC_VU, WM8993_ADC_VU);
1482
1483 /* Manualy manage the HPOUT sequencing for independent stereo
1484 * control. */
1485 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
1486 WM8993_HPOUT1_AUTO_PU, 0);
1487
1488 /* Use automatic clock configuration */
1489 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1490
1491 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1492 wm8993->pdata.lineout2_diff,
1493 wm8993->pdata.lineout1fb,
1494 wm8993->pdata.lineout2fb,
1495 wm8993->pdata.jd_scthr,
1496 wm8993->pdata.jd_thr,
1497 wm8993->pdata.micbias1_lvl,
1498 wm8993->pdata.micbias2_lvl);
1499
1500 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1501 if (ret != 0)
1502 goto err_enable;
1503
1442 snd_soc_add_controls(codec, wm8993_snd_controls, 1504 snd_soc_add_controls(codec, wm8993_snd_controls,
1443 ARRAY_SIZE(wm8993_snd_controls)); 1505 ARRAY_SIZE(wm8993_snd_controls));
1444 if (wm8993->pdata.num_retune_configs != 0) { 1506 if (wm8993->pdata.num_retune_configs != 0) {
@@ -1449,44 +1511,44 @@ static int wm8993_probe(struct platform_device *pdev)
1449 ARRAY_SIZE(wm8993_eq_controls)); 1511 ARRAY_SIZE(wm8993_eq_controls));
1450 } 1512 }
1451 1513
1452 snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets, 1514 snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
1453 ARRAY_SIZE(wm8993_dapm_widgets)); 1515 ARRAY_SIZE(wm8993_dapm_widgets));
1454 wm_hubs_add_analogue_controls(codec); 1516 wm_hubs_add_analogue_controls(codec);
1455 1517
1456 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 1518 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1457 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1519 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1458 wm8993->pdata.lineout2_diff); 1520 wm8993->pdata.lineout2_diff);
1459 1521
1460 return ret; 1522 return 0;
1461 1523
1462err: 1524err_enable:
1525 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1526err_get:
1527 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1463 return ret; 1528 return ret;
1464} 1529}
1465 1530
1466static int wm8993_remove(struct platform_device *pdev) 1531static int wm8993_remove(struct snd_soc_codec *codec)
1467{ 1532{
1468 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1533 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1469
1470 snd_soc_free_pcms(socdev);
1471 snd_soc_dapm_free(socdev);
1472 1534
1535 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1536 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1473 return 0; 1537 return 0;
1474} 1538}
1475 1539
1476#ifdef CONFIG_PM 1540#ifdef CONFIG_PM
1477static int wm8993_suspend(struct platform_device *pdev, pm_message_t state) 1541static int wm8993_suspend(struct snd_soc_codec *codec, pm_message_t state)
1478{ 1542{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1543 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1482 int fll_fout = wm8993->fll_fout; 1544 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref; 1545 int fll_fref = wm8993->fll_fref;
1484 int ret; 1546 int ret;
1485 1547
1486 /* Stop the FLL in an orderly fashion */ 1548 /* Stop the FLL in an orderly fashion */
1487 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0); 1549 ret = _wm8993_set_fll(codec, 0, 0, 0, 0);
1488 if (ret != 0) { 1550 if (ret != 0) {
1489 dev_err(&pdev->dev, "Failed to stop FLL\n"); 1551 dev_err(codec->dev, "Failed to stop FLL\n");
1490 return ret; 1552 return ret;
1491 } 1553 }
1492 1554
@@ -1498,10 +1560,8 @@ static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1498 return 0; 1560 return 0;
1499} 1561}
1500 1562
1501static int wm8993_resume(struct platform_device *pdev) 1563static int wm8993_resume(struct snd_soc_codec *codec)
1502{ 1564{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1565 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1506 int ret; 1566 int ret;
1507 1567
@@ -1515,7 +1575,7 @@ static int wm8993_resume(struct platform_device *pdev)
1515 wm8993->fll_fref = 0; 1575 wm8993->fll_fref = 0;
1516 wm8993->fll_fout = 0; 1576 wm8993->fll_fout = 0;
1517 1577
1518 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src, 1578 ret = _wm8993_set_fll(codec, 0, wm8993->fll_src,
1519 fll_fref, fll_fout); 1579 fll_fref, fll_fout);
1520 if (ret != 0) 1580 if (ret != 0)
1521 dev_err(codec->dev, "Failed to restart FLL\n"); 1581 dev_err(codec->dev, "Failed to restart FLL\n");
@@ -1528,162 +1588,42 @@ static int wm8993_resume(struct platform_device *pdev)
1528#define wm8993_resume NULL 1588#define wm8993_resume NULL
1529#endif 1589#endif
1530 1590
1531struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1591static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
1532 .probe = wm8993_probe, 1592 .probe = wm8993_probe,
1533 .remove = wm8993_remove, 1593 .remove = wm8993_remove,
1534 .suspend = wm8993_suspend, 1594 .suspend = wm8993_suspend,
1535 .resume = wm8993_resume, 1595 .resume = wm8993_resume,
1596 .set_bias_level = wm8993_set_bias_level,
1597 .reg_cache_size = ARRAY_SIZE(wm8993_reg_defaults),
1598 .reg_word_size = sizeof(u16),
1599 .reg_cache_default = wm8993_reg_defaults,
1600 .volatile_register = wm8993_volatile,
1536}; 1601};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1538 1602
1539static int wm8993_i2c_probe(struct i2c_client *i2c, 1603#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1540 const struct i2c_device_id *id) 1604static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
1605 const struct i2c_device_id *id)
1541{ 1606{
1542 struct wm8993_priv *wm8993; 1607 struct wm8993_priv *wm8993;
1543 struct snd_soc_codec *codec;
1544 unsigned int val;
1545 int ret; 1608 int ret;
1546 int i;
1547
1548 if (wm8993_codec) {
1549 dev_err(&i2c->dev, "A WM8993 is already registered\n");
1550 return -EINVAL;
1551 }
1552 1609
1553 wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL); 1610 wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
1554 if (wm8993 == NULL) 1611 if (wm8993 == NULL)
1555 return -ENOMEM; 1612 return -ENOMEM;
1556 1613
1557 codec = &wm8993->codec;
1558 if (i2c->dev.platform_data)
1559 memcpy(&wm8993->pdata, i2c->dev.platform_data,
1560 sizeof(wm8993->pdata));
1561
1562 mutex_init(&codec->mutex);
1563 INIT_LIST_HEAD(&codec->dapm_widgets);
1564 INIT_LIST_HEAD(&codec->dapm_paths);
1565
1566 codec->name = "WM8993";
1567 codec->volatile_register = wm8993_volatile;
1568 codec->reg_cache = wm8993->reg_cache;
1569 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1570 codec->bias_level = SND_SOC_BIAS_OFF;
1571 codec->set_bias_level = wm8993_set_bias_level;
1572 codec->dai = &wm8993_dai;
1573 codec->num_dai = 1;
1574 snd_soc_codec_set_drvdata(codec, wm8993);
1575
1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2;
1578
1579 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1580 sizeof(wm8993->reg_cache));
1581
1582 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1583 if (ret != 0) {
1584 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1585 goto err;
1586 }
1587
1588 i2c_set_clientdata(i2c, wm8993); 1614 i2c_set_clientdata(i2c, wm8993);
1589 codec->control_data = i2c;
1590 wm8993_codec = codec;
1591
1592 codec->dev = &i2c->dev;
1593
1594 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1595 wm8993->supplies[i].supply = wm8993_supply_names[i];
1596
1597 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1598 wm8993->supplies);
1599 if (ret != 0) {
1600 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1601 goto err;
1602 }
1603
1604 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1605 wm8993->supplies);
1606 if (ret != 0) {
1607 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1608 goto err_get;
1609 }
1610
1611 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1612 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1613 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1614 ret = -EINVAL;
1615 goto err_enable;
1616 }
1617
1618 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1619 if (ret != 0)
1620 goto err_enable;
1621
1622 codec->cache_only = 1;
1623
1624 /* By default we're using the output mixers */
1625 wm8993->class_w_users = 2;
1626
1627 /* Latch volume update bits and default ZC on */
1628 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1629 WM8993_DAC_VU, WM8993_DAC_VU);
1630 snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
1631 WM8993_ADC_VU, WM8993_ADC_VU);
1632 1615
1633 /* Manualy manage the HPOUT sequencing for independent stereo 1616 ret = snd_soc_register_codec(&i2c->dev,
1634 * control. */ 1617 &soc_codec_dev_wm8993, &wm8993_dai, 1);
1635 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, 1618 if (ret < 0)
1636 WM8993_HPOUT1_AUTO_PU, 0); 1619 kfree(wm8993);
1637
1638 /* Use automatic clock configuration */
1639 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1640
1641 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1642 wm8993->pdata.lineout2_diff,
1643 wm8993->pdata.lineout1fb,
1644 wm8993->pdata.lineout2fb,
1645 wm8993->pdata.jd_scthr,
1646 wm8993->pdata.jd_thr,
1647 wm8993->pdata.micbias1_lvl,
1648 wm8993->pdata.micbias2_lvl);
1649
1650 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1651 if (ret != 0)
1652 goto err_enable;
1653
1654 wm8993_dai.dev = codec->dev;
1655
1656 ret = snd_soc_register_dai(&wm8993_dai);
1657 if (ret != 0)
1658 goto err_bias;
1659
1660 ret = snd_soc_register_codec(codec);
1661
1662 return 0;
1663
1664err_bias:
1665 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1666err_enable:
1667 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1668err_get:
1669 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1670err:
1671 wm8993_codec = NULL;
1672 kfree(wm8993);
1673 return ret; 1620 return ret;
1674} 1621}
1675 1622
1676static int wm8993_i2c_remove(struct i2c_client *client) 1623static __devexit int wm8993_i2c_remove(struct i2c_client *client)
1677{ 1624{
1678 struct wm8993_priv *wm8993 = i2c_get_clientdata(client); 1625 snd_soc_unregister_codec(&client->dev);
1679 1626 kfree(i2c_get_clientdata(client));
1680 snd_soc_unregister_codec(&wm8993->codec);
1681 snd_soc_unregister_dai(&wm8993_dai);
1682
1683 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1684 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1685 kfree(wm8993);
1686
1687 return 0; 1627 return 0;
1688} 1628}
1689 1629
@@ -1695,30 +1635,34 @@ MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id);
1695 1635
1696static struct i2c_driver wm8993_i2c_driver = { 1636static struct i2c_driver wm8993_i2c_driver = {
1697 .driver = { 1637 .driver = {
1698 .name = "WM8993", 1638 .name = "wm8993-codec",
1699 .owner = THIS_MODULE, 1639 .owner = THIS_MODULE,
1700 }, 1640 },
1701 .probe = wm8993_i2c_probe, 1641 .probe = wm8993_i2c_probe,
1702 .remove = wm8993_i2c_remove, 1642 .remove = __devexit_p(wm8993_i2c_remove),
1703 .id_table = wm8993_i2c_id, 1643 .id_table = wm8993_i2c_id,
1704}; 1644};
1705 1645#endif
1706 1646
1707static int __init wm8993_modinit(void) 1647static int __init wm8993_modinit(void)
1708{ 1648{
1709 int ret; 1649 int ret = 0;
1710 1650#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1711 ret = i2c_add_driver(&wm8993_i2c_driver); 1651 ret = i2c_add_driver(&wm8993_i2c_driver);
1712 if (ret != 0) 1652 if (ret != 0) {
1713 pr_err("WM8993: Unable to register I2C driver: %d\n", ret); 1653 pr_err("WM8993: Unable to register I2C driver: %d\n",
1714 1654 ret);
1655 }
1656#endif
1715 return ret; 1657 return ret;
1716} 1658}
1717module_init(wm8993_modinit); 1659module_init(wm8993_modinit);
1718 1660
1719static void __exit wm8993_exit(void) 1661static void __exit wm8993_exit(void)
1720{ 1662{
1663#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1721 i2c_del_driver(&wm8993_i2c_driver); 1664 i2c_del_driver(&wm8993_i2c_driver);
1665#endif
1722} 1666}
1723module_exit(wm8993_exit); 1667module_exit(wm8993_exit);
1724 1668
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 30e71ca88dad..2184617b9611 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -1,9 +1,6 @@
1#ifndef WM8993_H 1#ifndef WM8993_H
2#define WM8993_H 2#define WM8993_H
3 3
4extern struct snd_soc_dai wm8993_dai;
5extern struct snd_soc_codec_device soc_codec_dev_wm8993;
6
7#define WM8993_SYSCLK_MCLK 1 4#define WM8993_SYSCLK_MCLK 1
8#define WM8993_SYSCLK_FLL 2 5#define WM8993_SYSCLK_FLL 2
9 6
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
new file mode 100644
index 000000000000..a87adbd05ee1
--- /dev/null
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -0,0 +1,3147 @@
1#include "wm8994.h"
2
3const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
4 { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
5 { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
6 { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
7 { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
8 { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
9 { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
10 { 0x003F, 0x003F }, /* R6 - Power Management (6) */
11 { 0x0000, 0x0000 }, /* R7 */
12 { 0x0000, 0x0000 }, /* R8 */
13 { 0x0000, 0x0000 }, /* R9 */
14 { 0x0000, 0x0000 }, /* R10 */
15 { 0x0000, 0x0000 }, /* R11 */
16 { 0x0000, 0x0000 }, /* R12 */
17 { 0x0000, 0x0000 }, /* R13 */
18 { 0x0000, 0x0000 }, /* R14 */
19 { 0x0000, 0x0000 }, /* R15 */
20 { 0x0000, 0x0000 }, /* R16 */
21 { 0x0000, 0x0000 }, /* R17 */
22 { 0x0000, 0x0000 }, /* R18 */
23 { 0x0000, 0x0000 }, /* R19 */
24 { 0x0000, 0x0000 }, /* R20 */
25 { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
26 { 0x0000, 0x0000 }, /* R22 */
27 { 0x0000, 0x0000 }, /* R23 */
28 { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
29 { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
30 { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
31 { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
32 { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
33 { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
34 { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
35 { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
36 { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
37 { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
38 { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
39 { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
40 { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
41 { 0x003F, 0x003F }, /* R37 - ClassD */
42 { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
43 { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
44 { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
45 { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
46 { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
47 { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
48 { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
49 { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
50 { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
51 { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
52 { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
53 { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
54 { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
55 { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
56 { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
57 { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
58 { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
59 { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
60 { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
61 { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
63 { 0x000F, 0x000F }, /* R59 - LDO 1 */
64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */
65 { 0xFFFF, 0xFFFF }, /* R61 */
66 { 0xFFFF, 0xFFFF }, /* R62 */
67 { 0x0000, 0x0000 }, /* R63 */
68 { 0x0000, 0x0000 }, /* R64 */
69 { 0x0000, 0x0000 }, /* R65 */
70 { 0x0000, 0x0000 }, /* R66 */
71 { 0x0000, 0x0000 }, /* R67 */
72 { 0x0000, 0x0000 }, /* R68 */
73 { 0x0000, 0x0000 }, /* R69 */
74 { 0x0000, 0x0000 }, /* R70 */
75 { 0x0000, 0x0000 }, /* R71 */
76 { 0x0000, 0x0000 }, /* R72 */
77 { 0x0000, 0x0000 }, /* R73 */
78 { 0x0000, 0x0000 }, /* R74 */
79 { 0x0000, 0x0000 }, /* R75 */
80 { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
81 { 0x0000, 0x0000 }, /* R77 */
82 { 0x0000, 0x0000 }, /* R78 */
83 { 0x0000, 0x0000 }, /* R79 */
84 { 0x0000, 0x0000 }, /* R80 */
85 { 0x0301, 0x0301 }, /* R81 - Class W (1) */
86 { 0x0000, 0x0000 }, /* R82 */
87 { 0x0000, 0x0000 }, /* R83 */
88 { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
89 { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
90 { 0x0000, 0x0000 }, /* R86 */
91 { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
92 { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
93 { 0x0000, 0x0000 }, /* R89 */
94 { 0x0000, 0x0000 }, /* R90 */
95 { 0x0000, 0x0000 }, /* R91 */
96 { 0x0000, 0x0000 }, /* R92 */
97 { 0x0000, 0x0000 }, /* R93 */
98 { 0x0000, 0x0000 }, /* R94 */
99 { 0x0000, 0x0000 }, /* R95 */
100 { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
101 { 0x0000, 0x0000 }, /* R97 */
102 { 0x0000, 0x0000 }, /* R98 */
103 { 0x0000, 0x0000 }, /* R99 */
104 { 0x0000, 0x0000 }, /* R100 */
105 { 0x0000, 0x0000 }, /* R101 */
106 { 0x0000, 0x0000 }, /* R102 */
107 { 0x0000, 0x0000 }, /* R103 */
108 { 0x0000, 0x0000 }, /* R104 */
109 { 0x0000, 0x0000 }, /* R105 */
110 { 0x0000, 0x0000 }, /* R106 */
111 { 0x0000, 0x0000 }, /* R107 */
112 { 0x0000, 0x0000 }, /* R108 */
113 { 0x0000, 0x0000 }, /* R109 */
114 { 0x0000, 0x0000 }, /* R110 */
115 { 0x0000, 0x0000 }, /* R111 */
116 { 0x0000, 0x0000 }, /* R112 */
117 { 0x0000, 0x0000 }, /* R113 */
118 { 0x0000, 0x0000 }, /* R114 */
119 { 0x0000, 0x0000 }, /* R115 */
120 { 0x0000, 0x0000 }, /* R116 */
121 { 0x0000, 0x0000 }, /* R117 */
122 { 0x0000, 0x0000 }, /* R118 */
123 { 0x0000, 0x0000 }, /* R119 */
124 { 0x0000, 0x0000 }, /* R120 */
125 { 0x0000, 0x0000 }, /* R121 */
126 { 0x0000, 0x0000 }, /* R122 */
127 { 0x0000, 0x0000 }, /* R123 */
128 { 0x0000, 0x0000 }, /* R124 */
129 { 0x0000, 0x0000 }, /* R125 */
130 { 0x0000, 0x0000 }, /* R126 */
131 { 0x0000, 0x0000 }, /* R127 */
132 { 0x0000, 0x0000 }, /* R128 */
133 { 0x0000, 0x0000 }, /* R129 */
134 { 0x0000, 0x0000 }, /* R130 */
135 { 0x0000, 0x0000 }, /* R131 */
136 { 0x0000, 0x0000 }, /* R132 */
137 { 0x0000, 0x0000 }, /* R133 */
138 { 0x0000, 0x0000 }, /* R134 */
139 { 0x0000, 0x0000 }, /* R135 */
140 { 0x0000, 0x0000 }, /* R136 */
141 { 0x0000, 0x0000 }, /* R137 */
142 { 0x0000, 0x0000 }, /* R138 */
143 { 0x0000, 0x0000 }, /* R139 */
144 { 0x0000, 0x0000 }, /* R140 */
145 { 0x0000, 0x0000 }, /* R141 */
146 { 0x0000, 0x0000 }, /* R142 */
147 { 0x0000, 0x0000 }, /* R143 */
148 { 0x0000, 0x0000 }, /* R144 */
149 { 0x0000, 0x0000 }, /* R145 */
150 { 0x0000, 0x0000 }, /* R146 */
151 { 0x0000, 0x0000 }, /* R147 */
152 { 0x0000, 0x0000 }, /* R148 */
153 { 0x0000, 0x0000 }, /* R149 */
154 { 0x0000, 0x0000 }, /* R150 */
155 { 0x0000, 0x0000 }, /* R151 */
156 { 0x0000, 0x0000 }, /* R152 */
157 { 0x0000, 0x0000 }, /* R153 */
158 { 0x0000, 0x0000 }, /* R154 */
159 { 0x0000, 0x0000 }, /* R155 */
160 { 0x0000, 0x0000 }, /* R156 */
161 { 0x0000, 0x0000 }, /* R157 */
162 { 0x0000, 0x0000 }, /* R158 */
163 { 0x0000, 0x0000 }, /* R159 */
164 { 0x0000, 0x0000 }, /* R160 */
165 { 0x0000, 0x0000 }, /* R161 */
166 { 0x0000, 0x0000 }, /* R162 */
167 { 0x0000, 0x0000 }, /* R163 */
168 { 0x0000, 0x0000 }, /* R164 */
169 { 0x0000, 0x0000 }, /* R165 */
170 { 0x0000, 0x0000 }, /* R166 */
171 { 0x0000, 0x0000 }, /* R167 */
172 { 0x0000, 0x0000 }, /* R168 */
173 { 0x0000, 0x0000 }, /* R169 */
174 { 0x0000, 0x0000 }, /* R170 */
175 { 0x0000, 0x0000 }, /* R171 */
176 { 0x0000, 0x0000 }, /* R172 */
177 { 0x0000, 0x0000 }, /* R173 */
178 { 0x0000, 0x0000 }, /* R174 */
179 { 0x0000, 0x0000 }, /* R175 */
180 { 0x0000, 0x0000 }, /* R176 */
181 { 0x0000, 0x0000 }, /* R177 */
182 { 0x0000, 0x0000 }, /* R178 */
183 { 0x0000, 0x0000 }, /* R179 */
184 { 0x0000, 0x0000 }, /* R180 */
185 { 0x0000, 0x0000 }, /* R181 */
186 { 0x0000, 0x0000 }, /* R182 */
187 { 0x0000, 0x0000 }, /* R183 */
188 { 0x0000, 0x0000 }, /* R184 */
189 { 0x0000, 0x0000 }, /* R185 */
190 { 0x0000, 0x0000 }, /* R186 */
191 { 0x0000, 0x0000 }, /* R187 */
192 { 0x0000, 0x0000 }, /* R188 */
193 { 0x0000, 0x0000 }, /* R189 */
194 { 0x0000, 0x0000 }, /* R190 */
195 { 0x0000, 0x0000 }, /* R191 */
196 { 0x0000, 0x0000 }, /* R192 */
197 { 0x0000, 0x0000 }, /* R193 */
198 { 0x0000, 0x0000 }, /* R194 */
199 { 0x0000, 0x0000 }, /* R195 */
200 { 0x0000, 0x0000 }, /* R196 */
201 { 0x0000, 0x0000 }, /* R197 */
202 { 0x0000, 0x0000 }, /* R198 */
203 { 0x0000, 0x0000 }, /* R199 */
204 { 0x0000, 0x0000 }, /* R200 */
205 { 0x0000, 0x0000 }, /* R201 */
206 { 0x0000, 0x0000 }, /* R202 */
207 { 0x0000, 0x0000 }, /* R203 */
208 { 0x0000, 0x0000 }, /* R204 */
209 { 0x0000, 0x0000 }, /* R205 */
210 { 0x0000, 0x0000 }, /* R206 */
211 { 0x0000, 0x0000 }, /* R207 */
212 { 0xFFFF, 0xFFFF }, /* R208 */
213 { 0xFFFF, 0xFFFF }, /* R209 */
214 { 0xFFFF, 0xFFFF }, /* R210 */
215 { 0x0000, 0x0000 }, /* R211 */
216 { 0x0000, 0x0000 }, /* R212 */
217 { 0x0000, 0x0000 }, /* R213 */
218 { 0x0000, 0x0000 }, /* R214 */
219 { 0x0000, 0x0000 }, /* R215 */
220 { 0x0000, 0x0000 }, /* R216 */
221 { 0x0000, 0x0000 }, /* R217 */
222 { 0x0000, 0x0000 }, /* R218 */
223 { 0x0000, 0x0000 }, /* R219 */
224 { 0x0000, 0x0000 }, /* R220 */
225 { 0x0000, 0x0000 }, /* R221 */
226 { 0x0000, 0x0000 }, /* R222 */
227 { 0x0000, 0x0000 }, /* R223 */
228 { 0x0000, 0x0000 }, /* R224 */
229 { 0x0000, 0x0000 }, /* R225 */
230 { 0x0000, 0x0000 }, /* R226 */
231 { 0x0000, 0x0000 }, /* R227 */
232 { 0x0000, 0x0000 }, /* R228 */
233 { 0x0000, 0x0000 }, /* R229 */
234 { 0x0000, 0x0000 }, /* R230 */
235 { 0x0000, 0x0000 }, /* R231 */
236 { 0x0000, 0x0000 }, /* R232 */
237 { 0x0000, 0x0000 }, /* R233 */
238 { 0x0000, 0x0000 }, /* R234 */
239 { 0x0000, 0x0000 }, /* R235 */
240 { 0x0000, 0x0000 }, /* R236 */
241 { 0x0000, 0x0000 }, /* R237 */
242 { 0x0000, 0x0000 }, /* R238 */
243 { 0x0000, 0x0000 }, /* R239 */
244 { 0x0000, 0x0000 }, /* R240 */
245 { 0x0000, 0x0000 }, /* R241 */
246 { 0x0000, 0x0000 }, /* R242 */
247 { 0x0000, 0x0000 }, /* R243 */
248 { 0x0000, 0x0000 }, /* R244 */
249 { 0x0000, 0x0000 }, /* R245 */
250 { 0x0000, 0x0000 }, /* R246 */
251 { 0x0000, 0x0000 }, /* R247 */
252 { 0x0000, 0x0000 }, /* R248 */
253 { 0x0000, 0x0000 }, /* R249 */
254 { 0x0000, 0x0000 }, /* R250 */
255 { 0x0000, 0x0000 }, /* R251 */
256 { 0x0000, 0x0000 }, /* R252 */
257 { 0x0000, 0x0000 }, /* R253 */
258 { 0x0000, 0x0000 }, /* R254 */
259 { 0x0000, 0x0000 }, /* R255 */
260 { 0x000F, 0x0000 }, /* R256 - Chip Revision */
261 { 0x0074, 0x0074 }, /* R257 - Control Interface */
262 { 0x0000, 0x0000 }, /* R258 */
263 { 0x0000, 0x0000 }, /* R259 */
264 { 0x0000, 0x0000 }, /* R260 */
265 { 0x0000, 0x0000 }, /* R261 */
266 { 0x0000, 0x0000 }, /* R262 */
267 { 0x0000, 0x0000 }, /* R263 */
268 { 0x0000, 0x0000 }, /* R264 */
269 { 0x0000, 0x0000 }, /* R265 */
270 { 0x0000, 0x0000 }, /* R266 */
271 { 0x0000, 0x0000 }, /* R267 */
272 { 0x0000, 0x0000 }, /* R268 */
273 { 0x0000, 0x0000 }, /* R269 */
274 { 0x0000, 0x0000 }, /* R270 */
275 { 0x0000, 0x0000 }, /* R271 */
276 { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
277 { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
278 { 0x0000, 0x0000 }, /* R274 */
279 { 0x0000, 0x0000 }, /* R275 */
280 { 0x0000, 0x0000 }, /* R276 */
281 { 0x0000, 0x0000 }, /* R277 */
282 { 0x0000, 0x0000 }, /* R278 */
283 { 0x0000, 0x0000 }, /* R279 */
284 { 0x0000, 0x0000 }, /* R280 */
285 { 0x0000, 0x0000 }, /* R281 */
286 { 0x0000, 0x0000 }, /* R282 */
287 { 0x0000, 0x0000 }, /* R283 */
288 { 0x0000, 0x0000 }, /* R284 */
289 { 0x0000, 0x0000 }, /* R285 */
290 { 0x0000, 0x0000 }, /* R286 */
291 { 0x0000, 0x0000 }, /* R287 */
292 { 0x0000, 0x0000 }, /* R288 */
293 { 0x0000, 0x0000 }, /* R289 */
294 { 0x0000, 0x0000 }, /* R290 */
295 { 0x0000, 0x0000 }, /* R291 */
296 { 0x0000, 0x0000 }, /* R292 */
297 { 0x0000, 0x0000 }, /* R293 */
298 { 0x0000, 0x0000 }, /* R294 */
299 { 0x0000, 0x0000 }, /* R295 */
300 { 0x0000, 0x0000 }, /* R296 */
301 { 0x0000, 0x0000 }, /* R297 */
302 { 0x0000, 0x0000 }, /* R298 */
303 { 0x0000, 0x0000 }, /* R299 */
304 { 0x0000, 0x0000 }, /* R300 */
305 { 0x0000, 0x0000 }, /* R301 */
306 { 0x0000, 0x0000 }, /* R302 */
307 { 0x0000, 0x0000 }, /* R303 */
308 { 0x0000, 0x0000 }, /* R304 */
309 { 0x0000, 0x0000 }, /* R305 */
310 { 0x0000, 0x0000 }, /* R306 */
311 { 0x0000, 0x0000 }, /* R307 */
312 { 0x0000, 0x0000 }, /* R308 */
313 { 0x0000, 0x0000 }, /* R309 */
314 { 0x0000, 0x0000 }, /* R310 */
315 { 0x0000, 0x0000 }, /* R311 */
316 { 0x0000, 0x0000 }, /* R312 */
317 { 0x0000, 0x0000 }, /* R313 */
318 { 0x0000, 0x0000 }, /* R314 */
319 { 0x0000, 0x0000 }, /* R315 */
320 { 0x0000, 0x0000 }, /* R316 */
321 { 0x0000, 0x0000 }, /* R317 */
322 { 0x0000, 0x0000 }, /* R318 */
323 { 0x0000, 0x0000 }, /* R319 */
324 { 0x0000, 0x0000 }, /* R320 */
325 { 0x0000, 0x0000 }, /* R321 */
326 { 0x0000, 0x0000 }, /* R322 */
327 { 0x0000, 0x0000 }, /* R323 */
328 { 0x0000, 0x0000 }, /* R324 */
329 { 0x0000, 0x0000 }, /* R325 */
330 { 0x0000, 0x0000 }, /* R326 */
331 { 0x0000, 0x0000 }, /* R327 */
332 { 0x0000, 0x0000 }, /* R328 */
333 { 0x0000, 0x0000 }, /* R329 */
334 { 0x0000, 0x0000 }, /* R330 */
335 { 0x0000, 0x0000 }, /* R331 */
336 { 0x0000, 0x0000 }, /* R332 */
337 { 0x0000, 0x0000 }, /* R333 */
338 { 0x0000, 0x0000 }, /* R334 */
339 { 0x0000, 0x0000 }, /* R335 */
340 { 0x0000, 0x0000 }, /* R336 */
341 { 0x0000, 0x0000 }, /* R337 */
342 { 0x0000, 0x0000 }, /* R338 */
343 { 0x0000, 0x0000 }, /* R339 */
344 { 0x0000, 0x0000 }, /* R340 */
345 { 0x0000, 0x0000 }, /* R341 */
346 { 0x0000, 0x0000 }, /* R342 */
347 { 0x0000, 0x0000 }, /* R343 */
348 { 0x0000, 0x0000 }, /* R344 */
349 { 0x0000, 0x0000 }, /* R345 */
350 { 0x0000, 0x0000 }, /* R346 */
351 { 0x0000, 0x0000 }, /* R347 */
352 { 0x0000, 0x0000 }, /* R348 */
353 { 0x0000, 0x0000 }, /* R349 */
354 { 0x0000, 0x0000 }, /* R350 */
355 { 0x0000, 0x0000 }, /* R351 */
356 { 0x0000, 0x0000 }, /* R352 */
357 { 0x0000, 0x0000 }, /* R353 */
358 { 0x0000, 0x0000 }, /* R354 */
359 { 0x0000, 0x0000 }, /* R355 */
360 { 0x0000, 0x0000 }, /* R356 */
361 { 0x0000, 0x0000 }, /* R357 */
362 { 0x0000, 0x0000 }, /* R358 */
363 { 0x0000, 0x0000 }, /* R359 */
364 { 0x0000, 0x0000 }, /* R360 */
365 { 0x0000, 0x0000 }, /* R361 */
366 { 0x0000, 0x0000 }, /* R362 */
367 { 0x0000, 0x0000 }, /* R363 */
368 { 0x0000, 0x0000 }, /* R364 */
369 { 0x0000, 0x0000 }, /* R365 */
370 { 0x0000, 0x0000 }, /* R366 */
371 { 0x0000, 0x0000 }, /* R367 */
372 { 0x0000, 0x0000 }, /* R368 */
373 { 0x0000, 0x0000 }, /* R369 */
374 { 0x0000, 0x0000 }, /* R370 */
375 { 0x0000, 0x0000 }, /* R371 */
376 { 0x0000, 0x0000 }, /* R372 */
377 { 0x0000, 0x0000 }, /* R373 */
378 { 0x0000, 0x0000 }, /* R374 */
379 { 0x0000, 0x0000 }, /* R375 */
380 { 0x0000, 0x0000 }, /* R376 */
381 { 0x0000, 0x0000 }, /* R377 */
382 { 0x0000, 0x0000 }, /* R378 */
383 { 0x0000, 0x0000 }, /* R379 */
384 { 0x0000, 0x0000 }, /* R380 */
385 { 0x0000, 0x0000 }, /* R381 */
386 { 0x0000, 0x0000 }, /* R382 */
387 { 0x0000, 0x0000 }, /* R383 */
388 { 0x0000, 0x0000 }, /* R384 */
389 { 0x0000, 0x0000 }, /* R385 */
390 { 0x0000, 0x0000 }, /* R386 */
391 { 0x0000, 0x0000 }, /* R387 */
392 { 0x0000, 0x0000 }, /* R388 */
393 { 0x0000, 0x0000 }, /* R389 */
394 { 0x0000, 0x0000 }, /* R390 */
395 { 0x0000, 0x0000 }, /* R391 */
396 { 0x0000, 0x0000 }, /* R392 */
397 { 0x0000, 0x0000 }, /* R393 */
398 { 0x0000, 0x0000 }, /* R394 */
399 { 0x0000, 0x0000 }, /* R395 */
400 { 0x0000, 0x0000 }, /* R396 */
401 { 0x0000, 0x0000 }, /* R397 */
402 { 0x0000, 0x0000 }, /* R398 */
403 { 0x0000, 0x0000 }, /* R399 */
404 { 0x0000, 0x0000 }, /* R400 */
405 { 0x0000, 0x0000 }, /* R401 */
406 { 0x0000, 0x0000 }, /* R402 */
407 { 0x0000, 0x0000 }, /* R403 */
408 { 0x0000, 0x0000 }, /* R404 */
409 { 0x0000, 0x0000 }, /* R405 */
410 { 0x0000, 0x0000 }, /* R406 */
411 { 0x0000, 0x0000 }, /* R407 */
412 { 0x0000, 0x0000 }, /* R408 */
413 { 0x0000, 0x0000 }, /* R409 */
414 { 0x0000, 0x0000 }, /* R410 */
415 { 0x0000, 0x0000 }, /* R411 */
416 { 0x0000, 0x0000 }, /* R412 */
417 { 0x0000, 0x0000 }, /* R413 */
418 { 0x0000, 0x0000 }, /* R414 */
419 { 0x0000, 0x0000 }, /* R415 */
420 { 0x0000, 0x0000 }, /* R416 */
421 { 0x0000, 0x0000 }, /* R417 */
422 { 0x0000, 0x0000 }, /* R418 */
423 { 0x0000, 0x0000 }, /* R419 */
424 { 0x0000, 0x0000 }, /* R420 */
425 { 0x0000, 0x0000 }, /* R421 */
426 { 0x0000, 0x0000 }, /* R422 */
427 { 0x0000, 0x0000 }, /* R423 */
428 { 0x0000, 0x0000 }, /* R424 */
429 { 0x0000, 0x0000 }, /* R425 */
430 { 0x0000, 0x0000 }, /* R426 */
431 { 0x0000, 0x0000 }, /* R427 */
432 { 0x0000, 0x0000 }, /* R428 */
433 { 0x0000, 0x0000 }, /* R429 */
434 { 0x0000, 0x0000 }, /* R430 */
435 { 0x0000, 0x0000 }, /* R431 */
436 { 0x0000, 0x0000 }, /* R432 */
437 { 0x0000, 0x0000 }, /* R433 */
438 { 0x0000, 0x0000 }, /* R434 */
439 { 0x0000, 0x0000 }, /* R435 */
440 { 0x0000, 0x0000 }, /* R436 */
441 { 0x0000, 0x0000 }, /* R437 */
442 { 0x0000, 0x0000 }, /* R438 */
443 { 0x0000, 0x0000 }, /* R439 */
444 { 0x0000, 0x0000 }, /* R440 */
445 { 0x0000, 0x0000 }, /* R441 */
446 { 0x0000, 0x0000 }, /* R442 */
447 { 0x0000, 0x0000 }, /* R443 */
448 { 0x0000, 0x0000 }, /* R444 */
449 { 0x0000, 0x0000 }, /* R445 */
450 { 0x0000, 0x0000 }, /* R446 */
451 { 0x0000, 0x0000 }, /* R447 */
452 { 0x0000, 0x0000 }, /* R448 */
453 { 0x0000, 0x0000 }, /* R449 */
454 { 0x0000, 0x0000 }, /* R450 */
455 { 0x0000, 0x0000 }, /* R451 */
456 { 0x0000, 0x0000 }, /* R452 */
457 { 0x0000, 0x0000 }, /* R453 */
458 { 0x0000, 0x0000 }, /* R454 */
459 { 0x0000, 0x0000 }, /* R455 */
460 { 0x0000, 0x0000 }, /* R456 */
461 { 0x0000, 0x0000 }, /* R457 */
462 { 0x0000, 0x0000 }, /* R458 */
463 { 0x0000, 0x0000 }, /* R459 */
464 { 0x0000, 0x0000 }, /* R460 */
465 { 0x0000, 0x0000 }, /* R461 */
466 { 0x0000, 0x0000 }, /* R462 */
467 { 0x0000, 0x0000 }, /* R463 */
468 { 0x0000, 0x0000 }, /* R464 */
469 { 0x0000, 0x0000 }, /* R465 */
470 { 0x0000, 0x0000 }, /* R466 */
471 { 0x0000, 0x0000 }, /* R467 */
472 { 0x0000, 0x0000 }, /* R468 */
473 { 0x0000, 0x0000 }, /* R469 */
474 { 0x0000, 0x0000 }, /* R470 */
475 { 0x0000, 0x0000 }, /* R471 */
476 { 0x0000, 0x0000 }, /* R472 */
477 { 0x0000, 0x0000 }, /* R473 */
478 { 0x0000, 0x0000 }, /* R474 */
479 { 0x0000, 0x0000 }, /* R475 */
480 { 0x0000, 0x0000 }, /* R476 */
481 { 0x0000, 0x0000 }, /* R477 */
482 { 0x0000, 0x0000 }, /* R478 */
483 { 0x0000, 0x0000 }, /* R479 */
484 { 0x0000, 0x0000 }, /* R480 */
485 { 0x0000, 0x0000 }, /* R481 */
486 { 0x0000, 0x0000 }, /* R482 */
487 { 0x0000, 0x0000 }, /* R483 */
488 { 0x0000, 0x0000 }, /* R484 */
489 { 0x0000, 0x0000 }, /* R485 */
490 { 0x0000, 0x0000 }, /* R486 */
491 { 0x0000, 0x0000 }, /* R487 */
492 { 0x0000, 0x0000 }, /* R488 */
493 { 0x0000, 0x0000 }, /* R489 */
494 { 0x0000, 0x0000 }, /* R490 */
495 { 0x0000, 0x0000 }, /* R491 */
496 { 0x0000, 0x0000 }, /* R492 */
497 { 0x0000, 0x0000 }, /* R493 */
498 { 0x0000, 0x0000 }, /* R494 */
499 { 0x0000, 0x0000 }, /* R495 */
500 { 0x0000, 0x0000 }, /* R496 */
501 { 0x0000, 0x0000 }, /* R497 */
502 { 0x0000, 0x0000 }, /* R498 */
503 { 0x0000, 0x0000 }, /* R499 */
504 { 0x0000, 0x0000 }, /* R500 */
505 { 0x0000, 0x0000 }, /* R501 */
506 { 0x0000, 0x0000 }, /* R502 */
507 { 0x0000, 0x0000 }, /* R503 */
508 { 0x0000, 0x0000 }, /* R504 */
509 { 0x0000, 0x0000 }, /* R505 */
510 { 0x0000, 0x0000 }, /* R506 */
511 { 0x0000, 0x0000 }, /* R507 */
512 { 0x0000, 0x0000 }, /* R508 */
513 { 0x0000, 0x0000 }, /* R509 */
514 { 0x0000, 0x0000 }, /* R510 */
515 { 0x0000, 0x0000 }, /* R511 */
516 { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
517 { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
518 { 0x0000, 0x0000 }, /* R514 */
519 { 0x0000, 0x0000 }, /* R515 */
520 { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
521 { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
522 { 0x0000, 0x0000 }, /* R518 */
523 { 0x0000, 0x0000 }, /* R519 */
524 { 0x001F, 0x001F }, /* R520 - Clocking (1) */
525 { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
526 { 0x0000, 0x0000 }, /* R522 */
527 { 0x0000, 0x0000 }, /* R523 */
528 { 0x0000, 0x0000 }, /* R524 */
529 { 0x0000, 0x0000 }, /* R525 */
530 { 0x0000, 0x0000 }, /* R526 */
531 { 0x0000, 0x0000 }, /* R527 */
532 { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
533 { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
534 { 0x000F, 0x0000 }, /* R530 - Rate Status */
535 { 0x0000, 0x0000 }, /* R531 */
536 { 0x0000, 0x0000 }, /* R532 */
537 { 0x0000, 0x0000 }, /* R533 */
538 { 0x0000, 0x0000 }, /* R534 */
539 { 0x0000, 0x0000 }, /* R535 */
540 { 0x0000, 0x0000 }, /* R536 */
541 { 0x0000, 0x0000 }, /* R537 */
542 { 0x0000, 0x0000 }, /* R538 */
543 { 0x0000, 0x0000 }, /* R539 */
544 { 0x0000, 0x0000 }, /* R540 */
545 { 0x0000, 0x0000 }, /* R541 */
546 { 0x0000, 0x0000 }, /* R542 */
547 { 0x0000, 0x0000 }, /* R543 */
548 { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
549 { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
550 { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
551 { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
552 { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
553 { 0x0000, 0x0000 }, /* R549 */
554 { 0x0000, 0x0000 }, /* R550 */
555 { 0x0000, 0x0000 }, /* R551 */
556 { 0x0000, 0x0000 }, /* R552 */
557 { 0x0000, 0x0000 }, /* R553 */
558 { 0x0000, 0x0000 }, /* R554 */
559 { 0x0000, 0x0000 }, /* R555 */
560 { 0x0000, 0x0000 }, /* R556 */
561 { 0x0000, 0x0000 }, /* R557 */
562 { 0x0000, 0x0000 }, /* R558 */
563 { 0x0000, 0x0000 }, /* R559 */
564 { 0x0000, 0x0000 }, /* R560 */
565 { 0x0000, 0x0000 }, /* R561 */
566 { 0x0000, 0x0000 }, /* R562 */
567 { 0x0000, 0x0000 }, /* R563 */
568 { 0x0000, 0x0000 }, /* R564 */
569 { 0x0000, 0x0000 }, /* R565 */
570 { 0x0000, 0x0000 }, /* R566 */
571 { 0x0000, 0x0000 }, /* R567 */
572 { 0x0000, 0x0000 }, /* R568 */
573 { 0x0000, 0x0000 }, /* R569 */
574 { 0x0000, 0x0000 }, /* R570 */
575 { 0x0000, 0x0000 }, /* R571 */
576 { 0x0000, 0x0000 }, /* R572 */
577 { 0x0000, 0x0000 }, /* R573 */
578 { 0x0000, 0x0000 }, /* R574 */
579 { 0x0000, 0x0000 }, /* R575 */
580 { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
581 { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
582 { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
583 { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
584 { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
585 { 0x0000, 0x0000 }, /* R581 */
586 { 0x0000, 0x0000 }, /* R582 */
587 { 0x0000, 0x0000 }, /* R583 */
588 { 0x0000, 0x0000 }, /* R584 */
589 { 0x0000, 0x0000 }, /* R585 */
590 { 0x0000, 0x0000 }, /* R586 */
591 { 0x0000, 0x0000 }, /* R587 */
592 { 0x0000, 0x0000 }, /* R588 */
593 { 0x0000, 0x0000 }, /* R589 */
594 { 0x0000, 0x0000 }, /* R590 */
595 { 0x0000, 0x0000 }, /* R591 */
596 { 0x0000, 0x0000 }, /* R592 */
597 { 0x0000, 0x0000 }, /* R593 */
598 { 0x0000, 0x0000 }, /* R594 */
599 { 0x0000, 0x0000 }, /* R595 */
600 { 0x0000, 0x0000 }, /* R596 */
601 { 0x0000, 0x0000 }, /* R597 */
602 { 0x0000, 0x0000 }, /* R598 */
603 { 0x0000, 0x0000 }, /* R599 */
604 { 0x0000, 0x0000 }, /* R600 */
605 { 0x0000, 0x0000 }, /* R601 */
606 { 0x0000, 0x0000 }, /* R602 */
607 { 0x0000, 0x0000 }, /* R603 */
608 { 0x0000, 0x0000 }, /* R604 */
609 { 0x0000, 0x0000 }, /* R605 */
610 { 0x0000, 0x0000 }, /* R606 */
611 { 0x0000, 0x0000 }, /* R607 */
612 { 0x0000, 0x0000 }, /* R608 */
613 { 0x0000, 0x0000 }, /* R609 */
614 { 0x0000, 0x0000 }, /* R610 */
615 { 0x0000, 0x0000 }, /* R611 */
616 { 0x0000, 0x0000 }, /* R612 */
617 { 0x0000, 0x0000 }, /* R613 */
618 { 0x0000, 0x0000 }, /* R614 */
619 { 0x0000, 0x0000 }, /* R615 */
620 { 0x0000, 0x0000 }, /* R616 */
621 { 0x0000, 0x0000 }, /* R617 */
622 { 0x0000, 0x0000 }, /* R618 */
623 { 0x0000, 0x0000 }, /* R619 */
624 { 0x0000, 0x0000 }, /* R620 */
625 { 0x0000, 0x0000 }, /* R621 */
626 { 0x0000, 0x0000 }, /* R622 */
627 { 0x0000, 0x0000 }, /* R623 */
628 { 0x0000, 0x0000 }, /* R624 */
629 { 0x0000, 0x0000 }, /* R625 */
630 { 0x0000, 0x0000 }, /* R626 */
631 { 0x0000, 0x0000 }, /* R627 */
632 { 0x0000, 0x0000 }, /* R628 */
633 { 0x0000, 0x0000 }, /* R629 */
634 { 0x0000, 0x0000 }, /* R630 */
635 { 0x0000, 0x0000 }, /* R631 */
636 { 0x0000, 0x0000 }, /* R632 */
637 { 0x0000, 0x0000 }, /* R633 */
638 { 0x0000, 0x0000 }, /* R634 */
639 { 0x0000, 0x0000 }, /* R635 */
640 { 0x0000, 0x0000 }, /* R636 */
641 { 0x0000, 0x0000 }, /* R637 */
642 { 0x0000, 0x0000 }, /* R638 */
643 { 0x0000, 0x0000 }, /* R639 */
644 { 0x0000, 0x0000 }, /* R640 */
645 { 0x0000, 0x0000 }, /* R641 */
646 { 0x0000, 0x0000 }, /* R642 */
647 { 0x0000, 0x0000 }, /* R643 */
648 { 0x0000, 0x0000 }, /* R644 */
649 { 0x0000, 0x0000 }, /* R645 */
650 { 0x0000, 0x0000 }, /* R646 */
651 { 0x0000, 0x0000 }, /* R647 */
652 { 0x0000, 0x0000 }, /* R648 */
653 { 0x0000, 0x0000 }, /* R649 */
654 { 0x0000, 0x0000 }, /* R650 */
655 { 0x0000, 0x0000 }, /* R651 */
656 { 0x0000, 0x0000 }, /* R652 */
657 { 0x0000, 0x0000 }, /* R653 */
658 { 0x0000, 0x0000 }, /* R654 */
659 { 0x0000, 0x0000 }, /* R655 */
660 { 0x0000, 0x0000 }, /* R656 */
661 { 0x0000, 0x0000 }, /* R657 */
662 { 0x0000, 0x0000 }, /* R658 */
663 { 0x0000, 0x0000 }, /* R659 */
664 { 0x0000, 0x0000 }, /* R660 */
665 { 0x0000, 0x0000 }, /* R661 */
666 { 0x0000, 0x0000 }, /* R662 */
667 { 0x0000, 0x0000 }, /* R663 */
668 { 0x0000, 0x0000 }, /* R664 */
669 { 0x0000, 0x0000 }, /* R665 */
670 { 0x0000, 0x0000 }, /* R666 */
671 { 0x0000, 0x0000 }, /* R667 */
672 { 0x0000, 0x0000 }, /* R668 */
673 { 0x0000, 0x0000 }, /* R669 */
674 { 0x0000, 0x0000 }, /* R670 */
675 { 0x0000, 0x0000 }, /* R671 */
676 { 0x0000, 0x0000 }, /* R672 */
677 { 0x0000, 0x0000 }, /* R673 */
678 { 0x0000, 0x0000 }, /* R674 */
679 { 0x0000, 0x0000 }, /* R675 */
680 { 0x0000, 0x0000 }, /* R676 */
681 { 0x0000, 0x0000 }, /* R677 */
682 { 0x0000, 0x0000 }, /* R678 */
683 { 0x0000, 0x0000 }, /* R679 */
684 { 0x0000, 0x0000 }, /* R680 */
685 { 0x0000, 0x0000 }, /* R681 */
686 { 0x0000, 0x0000 }, /* R682 */
687 { 0x0000, 0x0000 }, /* R683 */
688 { 0x0000, 0x0000 }, /* R684 */
689 { 0x0000, 0x0000 }, /* R685 */
690 { 0x0000, 0x0000 }, /* R686 */
691 { 0x0000, 0x0000 }, /* R687 */
692 { 0x0000, 0x0000 }, /* R688 */
693 { 0x0000, 0x0000 }, /* R689 */
694 { 0x0000, 0x0000 }, /* R690 */
695 { 0x0000, 0x0000 }, /* R691 */
696 { 0x0000, 0x0000 }, /* R692 */
697 { 0x0000, 0x0000 }, /* R693 */
698 { 0x0000, 0x0000 }, /* R694 */
699 { 0x0000, 0x0000 }, /* R695 */
700 { 0x0000, 0x0000 }, /* R696 */
701 { 0x0000, 0x0000 }, /* R697 */
702 { 0x0000, 0x0000 }, /* R698 */
703 { 0x0000, 0x0000 }, /* R699 */
704 { 0x0000, 0x0000 }, /* R700 */
705 { 0x0000, 0x0000 }, /* R701 */
706 { 0x0000, 0x0000 }, /* R702 */
707 { 0x0000, 0x0000 }, /* R703 */
708 { 0x0000, 0x0000 }, /* R704 */
709 { 0x0000, 0x0000 }, /* R705 */
710 { 0x0000, 0x0000 }, /* R706 */
711 { 0x0000, 0x0000 }, /* R707 */
712 { 0x0000, 0x0000 }, /* R708 */
713 { 0x0000, 0x0000 }, /* R709 */
714 { 0x0000, 0x0000 }, /* R710 */
715 { 0x0000, 0x0000 }, /* R711 */
716 { 0x0000, 0x0000 }, /* R712 */
717 { 0x0000, 0x0000 }, /* R713 */
718 { 0x0000, 0x0000 }, /* R714 */
719 { 0x0000, 0x0000 }, /* R715 */
720 { 0x0000, 0x0000 }, /* R716 */
721 { 0x0000, 0x0000 }, /* R717 */
722 { 0x0000, 0x0000 }, /* R718 */
723 { 0x0000, 0x0000 }, /* R719 */
724 { 0x0000, 0x0000 }, /* R720 */
725 { 0x0000, 0x0000 }, /* R721 */
726 { 0x0000, 0x0000 }, /* R722 */
727 { 0x0000, 0x0000 }, /* R723 */
728 { 0x0000, 0x0000 }, /* R724 */
729 { 0x0000, 0x0000 }, /* R725 */
730 { 0x0000, 0x0000 }, /* R726 */
731 { 0x0000, 0x0000 }, /* R727 */
732 { 0x0000, 0x0000 }, /* R728 */
733 { 0x0000, 0x0000 }, /* R729 */
734 { 0x0000, 0x0000 }, /* R730 */
735 { 0x0000, 0x0000 }, /* R731 */
736 { 0x0000, 0x0000 }, /* R732 */
737 { 0x0000, 0x0000 }, /* R733 */
738 { 0x0000, 0x0000 }, /* R734 */
739 { 0x0000, 0x0000 }, /* R735 */
740 { 0x0000, 0x0000 }, /* R736 */
741 { 0x0000, 0x0000 }, /* R737 */
742 { 0x0000, 0x0000 }, /* R738 */
743 { 0x0000, 0x0000 }, /* R739 */
744 { 0x0000, 0x0000 }, /* R740 */
745 { 0x0000, 0x0000 }, /* R741 */
746 { 0x0000, 0x0000 }, /* R742 */
747 { 0x0000, 0x0000 }, /* R743 */
748 { 0x0000, 0x0000 }, /* R744 */
749 { 0x0000, 0x0000 }, /* R745 */
750 { 0x0000, 0x0000 }, /* R746 */
751 { 0x0000, 0x0000 }, /* R747 */
752 { 0x0000, 0x0000 }, /* R748 */
753 { 0x0000, 0x0000 }, /* R749 */
754 { 0x0000, 0x0000 }, /* R750 */
755 { 0x0000, 0x0000 }, /* R751 */
756 { 0x0000, 0x0000 }, /* R752 */
757 { 0x0000, 0x0000 }, /* R753 */
758 { 0x0000, 0x0000 }, /* R754 */
759 { 0x0000, 0x0000 }, /* R755 */
760 { 0x0000, 0x0000 }, /* R756 */
761 { 0x0000, 0x0000 }, /* R757 */
762 { 0x0000, 0x0000 }, /* R758 */
763 { 0x0000, 0x0000 }, /* R759 */
764 { 0x0000, 0x0000 }, /* R760 */
765 { 0x0000, 0x0000 }, /* R761 */
766 { 0x0000, 0x0000 }, /* R762 */
767 { 0x0000, 0x0000 }, /* R763 */
768 { 0x0000, 0x0000 }, /* R764 */
769 { 0x0000, 0x0000 }, /* R765 */
770 { 0x0000, 0x0000 }, /* R766 */
771 { 0x0000, 0x0000 }, /* R767 */
772 { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
773 { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
774 { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
775 { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
776 { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
777 { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
778 { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
779 { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
780 { 0x0000, 0x0000 }, /* R776 */
781 { 0x0000, 0x0000 }, /* R777 */
782 { 0x0000, 0x0000 }, /* R778 */
783 { 0x0000, 0x0000 }, /* R779 */
784 { 0x0000, 0x0000 }, /* R780 */
785 { 0x0000, 0x0000 }, /* R781 */
786 { 0x0000, 0x0000 }, /* R782 */
787 { 0x0000, 0x0000 }, /* R783 */
788 { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
789 { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
790 { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
791 { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
792 { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
793 { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
794 { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
795 { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
796 { 0x0000, 0x0000 }, /* R792 */
797 { 0x0000, 0x0000 }, /* R793 */
798 { 0x0000, 0x0000 }, /* R794 */
799 { 0x0000, 0x0000 }, /* R795 */
800 { 0x0000, 0x0000 }, /* R796 */
801 { 0x0000, 0x0000 }, /* R797 */
802 { 0x0000, 0x0000 }, /* R798 */
803 { 0x0000, 0x0000 }, /* R799 */
804 { 0x0000, 0x0000 }, /* R800 */
805 { 0x0000, 0x0000 }, /* R801 */
806 { 0x0000, 0x0000 }, /* R802 */
807 { 0x0000, 0x0000 }, /* R803 */
808 { 0x0000, 0x0000 }, /* R804 */
809 { 0x0000, 0x0000 }, /* R805 */
810 { 0x0000, 0x0000 }, /* R806 */
811 { 0x0000, 0x0000 }, /* R807 */
812 { 0x0000, 0x0000 }, /* R808 */
813 { 0x0000, 0x0000 }, /* R809 */
814 { 0x0000, 0x0000 }, /* R810 */
815 { 0x0000, 0x0000 }, /* R811 */
816 { 0x0000, 0x0000 }, /* R812 */
817 { 0x0000, 0x0000 }, /* R813 */
818 { 0x0000, 0x0000 }, /* R814 */
819 { 0x0000, 0x0000 }, /* R815 */
820 { 0x0000, 0x0000 }, /* R816 */
821 { 0x0000, 0x0000 }, /* R817 */
822 { 0x0000, 0x0000 }, /* R818 */
823 { 0x0000, 0x0000 }, /* R819 */
824 { 0x0000, 0x0000 }, /* R820 */
825 { 0x0000, 0x0000 }, /* R821 */
826 { 0x0000, 0x0000 }, /* R822 */
827 { 0x0000, 0x0000 }, /* R823 */
828 { 0x0000, 0x0000 }, /* R824 */
829 { 0x0000, 0x0000 }, /* R825 */
830 { 0x0000, 0x0000 }, /* R826 */
831 { 0x0000, 0x0000 }, /* R827 */
832 { 0x0000, 0x0000 }, /* R828 */
833 { 0x0000, 0x0000 }, /* R829 */
834 { 0x0000, 0x0000 }, /* R830 */
835 { 0x0000, 0x0000 }, /* R831 */
836 { 0x0000, 0x0000 }, /* R832 */
837 { 0x0000, 0x0000 }, /* R833 */
838 { 0x0000, 0x0000 }, /* R834 */
839 { 0x0000, 0x0000 }, /* R835 */
840 { 0x0000, 0x0000 }, /* R836 */
841 { 0x0000, 0x0000 }, /* R837 */
842 { 0x0000, 0x0000 }, /* R838 */
843 { 0x0000, 0x0000 }, /* R839 */
844 { 0x0000, 0x0000 }, /* R840 */
845 { 0x0000, 0x0000 }, /* R841 */
846 { 0x0000, 0x0000 }, /* R842 */
847 { 0x0000, 0x0000 }, /* R843 */
848 { 0x0000, 0x0000 }, /* R844 */
849 { 0x0000, 0x0000 }, /* R845 */
850 { 0x0000, 0x0000 }, /* R846 */
851 { 0x0000, 0x0000 }, /* R847 */
852 { 0x0000, 0x0000 }, /* R848 */
853 { 0x0000, 0x0000 }, /* R849 */
854 { 0x0000, 0x0000 }, /* R850 */
855 { 0x0000, 0x0000 }, /* R851 */
856 { 0x0000, 0x0000 }, /* R852 */
857 { 0x0000, 0x0000 }, /* R853 */
858 { 0x0000, 0x0000 }, /* R854 */
859 { 0x0000, 0x0000 }, /* R855 */
860 { 0x0000, 0x0000 }, /* R856 */
861 { 0x0000, 0x0000 }, /* R857 */
862 { 0x0000, 0x0000 }, /* R858 */
863 { 0x0000, 0x0000 }, /* R859 */
864 { 0x0000, 0x0000 }, /* R860 */
865 { 0x0000, 0x0000 }, /* R861 */
866 { 0x0000, 0x0000 }, /* R862 */
867 { 0x0000, 0x0000 }, /* R863 */
868 { 0x0000, 0x0000 }, /* R864 */
869 { 0x0000, 0x0000 }, /* R865 */
870 { 0x0000, 0x0000 }, /* R866 */
871 { 0x0000, 0x0000 }, /* R867 */
872 { 0x0000, 0x0000 }, /* R868 */
873 { 0x0000, 0x0000 }, /* R869 */
874 { 0x0000, 0x0000 }, /* R870 */
875 { 0x0000, 0x0000 }, /* R871 */
876 { 0x0000, 0x0000 }, /* R872 */
877 { 0x0000, 0x0000 }, /* R873 */
878 { 0x0000, 0x0000 }, /* R874 */
879 { 0x0000, 0x0000 }, /* R875 */
880 { 0x0000, 0x0000 }, /* R876 */
881 { 0x0000, 0x0000 }, /* R877 */
882 { 0x0000, 0x0000 }, /* R878 */
883 { 0x0000, 0x0000 }, /* R879 */
884 { 0x0000, 0x0000 }, /* R880 */
885 { 0x0000, 0x0000 }, /* R881 */
886 { 0x0000, 0x0000 }, /* R882 */
887 { 0x0000, 0x0000 }, /* R883 */
888 { 0x0000, 0x0000 }, /* R884 */
889 { 0x0000, 0x0000 }, /* R885 */
890 { 0x0000, 0x0000 }, /* R886 */
891 { 0x0000, 0x0000 }, /* R887 */
892 { 0x0000, 0x0000 }, /* R888 */
893 { 0x0000, 0x0000 }, /* R889 */
894 { 0x0000, 0x0000 }, /* R890 */
895 { 0x0000, 0x0000 }, /* R891 */
896 { 0x0000, 0x0000 }, /* R892 */
897 { 0x0000, 0x0000 }, /* R893 */
898 { 0x0000, 0x0000 }, /* R894 */
899 { 0x0000, 0x0000 }, /* R895 */
900 { 0x0000, 0x0000 }, /* R896 */
901 { 0x0000, 0x0000 }, /* R897 */
902 { 0x0000, 0x0000 }, /* R898 */
903 { 0x0000, 0x0000 }, /* R899 */
904 { 0x0000, 0x0000 }, /* R900 */
905 { 0x0000, 0x0000 }, /* R901 */
906 { 0x0000, 0x0000 }, /* R902 */
907 { 0x0000, 0x0000 }, /* R903 */
908 { 0x0000, 0x0000 }, /* R904 */
909 { 0x0000, 0x0000 }, /* R905 */
910 { 0x0000, 0x0000 }, /* R906 */
911 { 0x0000, 0x0000 }, /* R907 */
912 { 0x0000, 0x0000 }, /* R908 */
913 { 0x0000, 0x0000 }, /* R909 */
914 { 0x0000, 0x0000 }, /* R910 */
915 { 0x0000, 0x0000 }, /* R911 */
916 { 0x0000, 0x0000 }, /* R912 */
917 { 0x0000, 0x0000 }, /* R913 */
918 { 0x0000, 0x0000 }, /* R914 */
919 { 0x0000, 0x0000 }, /* R915 */
920 { 0x0000, 0x0000 }, /* R916 */
921 { 0x0000, 0x0000 }, /* R917 */
922 { 0x0000, 0x0000 }, /* R918 */
923 { 0x0000, 0x0000 }, /* R919 */
924 { 0x0000, 0x0000 }, /* R920 */
925 { 0x0000, 0x0000 }, /* R921 */
926 { 0x0000, 0x0000 }, /* R922 */
927 { 0x0000, 0x0000 }, /* R923 */
928 { 0x0000, 0x0000 }, /* R924 */
929 { 0x0000, 0x0000 }, /* R925 */
930 { 0x0000, 0x0000 }, /* R926 */
931 { 0x0000, 0x0000 }, /* R927 */
932 { 0x0000, 0x0000 }, /* R928 */
933 { 0x0000, 0x0000 }, /* R929 */
934 { 0x0000, 0x0000 }, /* R930 */
935 { 0x0000, 0x0000 }, /* R931 */
936 { 0x0000, 0x0000 }, /* R932 */
937 { 0x0000, 0x0000 }, /* R933 */
938 { 0x0000, 0x0000 }, /* R934 */
939 { 0x0000, 0x0000 }, /* R935 */
940 { 0x0000, 0x0000 }, /* R936 */
941 { 0x0000, 0x0000 }, /* R937 */
942 { 0x0000, 0x0000 }, /* R938 */
943 { 0x0000, 0x0000 }, /* R939 */
944 { 0x0000, 0x0000 }, /* R940 */
945 { 0x0000, 0x0000 }, /* R941 */
946 { 0x0000, 0x0000 }, /* R942 */
947 { 0x0000, 0x0000 }, /* R943 */
948 { 0x0000, 0x0000 }, /* R944 */
949 { 0x0000, 0x0000 }, /* R945 */
950 { 0x0000, 0x0000 }, /* R946 */
951 { 0x0000, 0x0000 }, /* R947 */
952 { 0x0000, 0x0000 }, /* R948 */
953 { 0x0000, 0x0000 }, /* R949 */
954 { 0x0000, 0x0000 }, /* R950 */
955 { 0x0000, 0x0000 }, /* R951 */
956 { 0x0000, 0x0000 }, /* R952 */
957 { 0x0000, 0x0000 }, /* R953 */
958 { 0x0000, 0x0000 }, /* R954 */
959 { 0x0000, 0x0000 }, /* R955 */
960 { 0x0000, 0x0000 }, /* R956 */
961 { 0x0000, 0x0000 }, /* R957 */
962 { 0x0000, 0x0000 }, /* R958 */
963 { 0x0000, 0x0000 }, /* R959 */
964 { 0x0000, 0x0000 }, /* R960 */
965 { 0x0000, 0x0000 }, /* R961 */
966 { 0x0000, 0x0000 }, /* R962 */
967 { 0x0000, 0x0000 }, /* R963 */
968 { 0x0000, 0x0000 }, /* R964 */
969 { 0x0000, 0x0000 }, /* R965 */
970 { 0x0000, 0x0000 }, /* R966 */
971 { 0x0000, 0x0000 }, /* R967 */
972 { 0x0000, 0x0000 }, /* R968 */
973 { 0x0000, 0x0000 }, /* R969 */
974 { 0x0000, 0x0000 }, /* R970 */
975 { 0x0000, 0x0000 }, /* R971 */
976 { 0x0000, 0x0000 }, /* R972 */
977 { 0x0000, 0x0000 }, /* R973 */
978 { 0x0000, 0x0000 }, /* R974 */
979 { 0x0000, 0x0000 }, /* R975 */
980 { 0x0000, 0x0000 }, /* R976 */
981 { 0x0000, 0x0000 }, /* R977 */
982 { 0x0000, 0x0000 }, /* R978 */
983 { 0x0000, 0x0000 }, /* R979 */
984 { 0x0000, 0x0000 }, /* R980 */
985 { 0x0000, 0x0000 }, /* R981 */
986 { 0x0000, 0x0000 }, /* R982 */
987 { 0x0000, 0x0000 }, /* R983 */
988 { 0x0000, 0x0000 }, /* R984 */
989 { 0x0000, 0x0000 }, /* R985 */
990 { 0x0000, 0x0000 }, /* R986 */
991 { 0x0000, 0x0000 }, /* R987 */
992 { 0x0000, 0x0000 }, /* R988 */
993 { 0x0000, 0x0000 }, /* R989 */
994 { 0x0000, 0x0000 }, /* R990 */
995 { 0x0000, 0x0000 }, /* R991 */
996 { 0x0000, 0x0000 }, /* R992 */
997 { 0x0000, 0x0000 }, /* R993 */
998 { 0x0000, 0x0000 }, /* R994 */
999 { 0x0000, 0x0000 }, /* R995 */
1000 { 0x0000, 0x0000 }, /* R996 */
1001 { 0x0000, 0x0000 }, /* R997 */
1002 { 0x0000, 0x0000 }, /* R998 */
1003 { 0x0000, 0x0000 }, /* R999 */
1004 { 0x0000, 0x0000 }, /* R1000 */
1005 { 0x0000, 0x0000 }, /* R1001 */
1006 { 0x0000, 0x0000 }, /* R1002 */
1007 { 0x0000, 0x0000 }, /* R1003 */
1008 { 0x0000, 0x0000 }, /* R1004 */
1009 { 0x0000, 0x0000 }, /* R1005 */
1010 { 0x0000, 0x0000 }, /* R1006 */
1011 { 0x0000, 0x0000 }, /* R1007 */
1012 { 0x0000, 0x0000 }, /* R1008 */
1013 { 0x0000, 0x0000 }, /* R1009 */
1014 { 0x0000, 0x0000 }, /* R1010 */
1015 { 0x0000, 0x0000 }, /* R1011 */
1016 { 0x0000, 0x0000 }, /* R1012 */
1017 { 0x0000, 0x0000 }, /* R1013 */
1018 { 0x0000, 0x0000 }, /* R1014 */
1019 { 0x0000, 0x0000 }, /* R1015 */
1020 { 0x0000, 0x0000 }, /* R1016 */
1021 { 0x0000, 0x0000 }, /* R1017 */
1022 { 0x0000, 0x0000 }, /* R1018 */
1023 { 0x0000, 0x0000 }, /* R1019 */
1024 { 0x0000, 0x0000 }, /* R1020 */
1025 { 0x0000, 0x0000 }, /* R1021 */
1026 { 0x0000, 0x0000 }, /* R1022 */
1027 { 0x0000, 0x0000 }, /* R1023 */
1028 { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
1029 { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
1030 { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
1031 { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
1032 { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
1033 { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
1034 { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
1035 { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
1036 { 0x0000, 0x0000 }, /* R1032 */
1037 { 0x0000, 0x0000 }, /* R1033 */
1038 { 0x0000, 0x0000 }, /* R1034 */
1039 { 0x0000, 0x0000 }, /* R1035 */
1040 { 0x0000, 0x0000 }, /* R1036 */
1041 { 0x0000, 0x0000 }, /* R1037 */
1042 { 0x0000, 0x0000 }, /* R1038 */
1043 { 0x0000, 0x0000 }, /* R1039 */
1044 { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
1045 { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
1046 { 0x0000, 0x0000 }, /* R1042 */
1047 { 0x0000, 0x0000 }, /* R1043 */
1048 { 0x0000, 0x0000 }, /* R1044 */
1049 { 0x0000, 0x0000 }, /* R1045 */
1050 { 0x0000, 0x0000 }, /* R1046 */
1051 { 0x0000, 0x0000 }, /* R1047 */
1052 { 0x0000, 0x0000 }, /* R1048 */
1053 { 0x0000, 0x0000 }, /* R1049 */
1054 { 0x0000, 0x0000 }, /* R1050 */
1055 { 0x0000, 0x0000 }, /* R1051 */
1056 { 0x0000, 0x0000 }, /* R1052 */
1057 { 0x0000, 0x0000 }, /* R1053 */
1058 { 0x0000, 0x0000 }, /* R1054 */
1059 { 0x0000, 0x0000 }, /* R1055 */
1060 { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
1061 { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
1062 { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
1063 { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
1064 { 0x0000, 0x0000 }, /* R1060 */
1065 { 0x0000, 0x0000 }, /* R1061 */
1066 { 0x0000, 0x0000 }, /* R1062 */
1067 { 0x0000, 0x0000 }, /* R1063 */
1068 { 0x0000, 0x0000 }, /* R1064 */
1069 { 0x0000, 0x0000 }, /* R1065 */
1070 { 0x0000, 0x0000 }, /* R1066 */
1071 { 0x0000, 0x0000 }, /* R1067 */
1072 { 0x0000, 0x0000 }, /* R1068 */
1073 { 0x0000, 0x0000 }, /* R1069 */
1074 { 0x0000, 0x0000 }, /* R1070 */
1075 { 0x0000, 0x0000 }, /* R1071 */
1076 { 0x0000, 0x0000 }, /* R1072 */
1077 { 0x0000, 0x0000 }, /* R1073 */
1078 { 0x0000, 0x0000 }, /* R1074 */
1079 { 0x0000, 0x0000 }, /* R1075 */
1080 { 0x0000, 0x0000 }, /* R1076 */
1081 { 0x0000, 0x0000 }, /* R1077 */
1082 { 0x0000, 0x0000 }, /* R1078 */
1083 { 0x0000, 0x0000 }, /* R1079 */
1084 { 0x0000, 0x0000 }, /* R1080 */
1085 { 0x0000, 0x0000 }, /* R1081 */
1086 { 0x0000, 0x0000 }, /* R1082 */
1087 { 0x0000, 0x0000 }, /* R1083 */
1088 { 0x0000, 0x0000 }, /* R1084 */
1089 { 0x0000, 0x0000 }, /* R1085 */
1090 { 0x0000, 0x0000 }, /* R1086 */
1091 { 0x0000, 0x0000 }, /* R1087 */
1092 { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
1093 { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
1094 { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
1095 { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
1096 { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
1097 { 0x0000, 0x0000 }, /* R1093 */
1098 { 0x0000, 0x0000 }, /* R1094 */
1099 { 0x0000, 0x0000 }, /* R1095 */
1100 { 0x0000, 0x0000 }, /* R1096 */
1101 { 0x0000, 0x0000 }, /* R1097 */
1102 { 0x0000, 0x0000 }, /* R1098 */
1103 { 0x0000, 0x0000 }, /* R1099 */
1104 { 0x0000, 0x0000 }, /* R1100 */
1105 { 0x0000, 0x0000 }, /* R1101 */
1106 { 0x0000, 0x0000 }, /* R1102 */
1107 { 0x0000, 0x0000 }, /* R1103 */
1108 { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
1109 { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
1110 { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
1111 { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
1112 { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
1113 { 0x0000, 0x0000 }, /* R1109 */
1114 { 0x0000, 0x0000 }, /* R1110 */
1115 { 0x0000, 0x0000 }, /* R1111 */
1116 { 0x0000, 0x0000 }, /* R1112 */
1117 { 0x0000, 0x0000 }, /* R1113 */
1118 { 0x0000, 0x0000 }, /* R1114 */
1119 { 0x0000, 0x0000 }, /* R1115 */
1120 { 0x0000, 0x0000 }, /* R1116 */
1121 { 0x0000, 0x0000 }, /* R1117 */
1122 { 0x0000, 0x0000 }, /* R1118 */
1123 { 0x0000, 0x0000 }, /* R1119 */
1124 { 0x0000, 0x0000 }, /* R1120 */
1125 { 0x0000, 0x0000 }, /* R1121 */
1126 { 0x0000, 0x0000 }, /* R1122 */
1127 { 0x0000, 0x0000 }, /* R1123 */
1128 { 0x0000, 0x0000 }, /* R1124 */
1129 { 0x0000, 0x0000 }, /* R1125 */
1130 { 0x0000, 0x0000 }, /* R1126 */
1131 { 0x0000, 0x0000 }, /* R1127 */
1132 { 0x0000, 0x0000 }, /* R1128 */
1133 { 0x0000, 0x0000 }, /* R1129 */
1134 { 0x0000, 0x0000 }, /* R1130 */
1135 { 0x0000, 0x0000 }, /* R1131 */
1136 { 0x0000, 0x0000 }, /* R1132 */
1137 { 0x0000, 0x0000 }, /* R1133 */
1138 { 0x0000, 0x0000 }, /* R1134 */
1139 { 0x0000, 0x0000 }, /* R1135 */
1140 { 0x0000, 0x0000 }, /* R1136 */
1141 { 0x0000, 0x0000 }, /* R1137 */
1142 { 0x0000, 0x0000 }, /* R1138 */
1143 { 0x0000, 0x0000 }, /* R1139 */
1144 { 0x0000, 0x0000 }, /* R1140 */
1145 { 0x0000, 0x0000 }, /* R1141 */
1146 { 0x0000, 0x0000 }, /* R1142 */
1147 { 0x0000, 0x0000 }, /* R1143 */
1148 { 0x0000, 0x0000 }, /* R1144 */
1149 { 0x0000, 0x0000 }, /* R1145 */
1150 { 0x0000, 0x0000 }, /* R1146 */
1151 { 0x0000, 0x0000 }, /* R1147 */
1152 { 0x0000, 0x0000 }, /* R1148 */
1153 { 0x0000, 0x0000 }, /* R1149 */
1154 { 0x0000, 0x0000 }, /* R1150 */
1155 { 0x0000, 0x0000 }, /* R1151 */
1156 { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1157 { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1158 { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1159 { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1160 { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1161 { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1162 { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1163 { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1164 { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1165 { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1166 { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1167 { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1168 { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1169 { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1170 { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1171 { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1172 { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1173 { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1174 { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1175 { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1176 { 0x0000, 0x0000 }, /* R1172 */
1177 { 0x0000, 0x0000 }, /* R1173 */
1178 { 0x0000, 0x0000 }, /* R1174 */
1179 { 0x0000, 0x0000 }, /* R1175 */
1180 { 0x0000, 0x0000 }, /* R1176 */
1181 { 0x0000, 0x0000 }, /* R1177 */
1182 { 0x0000, 0x0000 }, /* R1178 */
1183 { 0x0000, 0x0000 }, /* R1179 */
1184 { 0x0000, 0x0000 }, /* R1180 */
1185 { 0x0000, 0x0000 }, /* R1181 */
1186 { 0x0000, 0x0000 }, /* R1182 */
1187 { 0x0000, 0x0000 }, /* R1183 */
1188 { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1189 { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1190 { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1191 { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1192 { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1193 { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1194 { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1195 { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1196 { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1197 { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1198 { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1199 { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1200 { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1201 { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1202 { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1203 { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1204 { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1205 { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1206 { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1207 { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1208 { 0x0000, 0x0000 }, /* R1204 */
1209 { 0x0000, 0x0000 }, /* R1205 */
1210 { 0x0000, 0x0000 }, /* R1206 */
1211 { 0x0000, 0x0000 }, /* R1207 */
1212 { 0x0000, 0x0000 }, /* R1208 */
1213 { 0x0000, 0x0000 }, /* R1209 */
1214 { 0x0000, 0x0000 }, /* R1210 */
1215 { 0x0000, 0x0000 }, /* R1211 */
1216 { 0x0000, 0x0000 }, /* R1212 */
1217 { 0x0000, 0x0000 }, /* R1213 */
1218 { 0x0000, 0x0000 }, /* R1214 */
1219 { 0x0000, 0x0000 }, /* R1215 */
1220 { 0x0000, 0x0000 }, /* R1216 */
1221 { 0x0000, 0x0000 }, /* R1217 */
1222 { 0x0000, 0x0000 }, /* R1218 */
1223 { 0x0000, 0x0000 }, /* R1219 */
1224 { 0x0000, 0x0000 }, /* R1220 */
1225 { 0x0000, 0x0000 }, /* R1221 */
1226 { 0x0000, 0x0000 }, /* R1222 */
1227 { 0x0000, 0x0000 }, /* R1223 */
1228 { 0x0000, 0x0000 }, /* R1224 */
1229 { 0x0000, 0x0000 }, /* R1225 */
1230 { 0x0000, 0x0000 }, /* R1226 */
1231 { 0x0000, 0x0000 }, /* R1227 */
1232 { 0x0000, 0x0000 }, /* R1228 */
1233 { 0x0000, 0x0000 }, /* R1229 */
1234 { 0x0000, 0x0000 }, /* R1230 */
1235 { 0x0000, 0x0000 }, /* R1231 */
1236 { 0x0000, 0x0000 }, /* R1232 */
1237 { 0x0000, 0x0000 }, /* R1233 */
1238 { 0x0000, 0x0000 }, /* R1234 */
1239 { 0x0000, 0x0000 }, /* R1235 */
1240 { 0x0000, 0x0000 }, /* R1236 */
1241 { 0x0000, 0x0000 }, /* R1237 */
1242 { 0x0000, 0x0000 }, /* R1238 */
1243 { 0x0000, 0x0000 }, /* R1239 */
1244 { 0x0000, 0x0000 }, /* R1240 */
1245 { 0x0000, 0x0000 }, /* R1241 */
1246 { 0x0000, 0x0000 }, /* R1242 */
1247 { 0x0000, 0x0000 }, /* R1243 */
1248 { 0x0000, 0x0000 }, /* R1244 */
1249 { 0x0000, 0x0000 }, /* R1245 */
1250 { 0x0000, 0x0000 }, /* R1246 */
1251 { 0x0000, 0x0000 }, /* R1247 */
1252 { 0x0000, 0x0000 }, /* R1248 */
1253 { 0x0000, 0x0000 }, /* R1249 */
1254 { 0x0000, 0x0000 }, /* R1250 */
1255 { 0x0000, 0x0000 }, /* R1251 */
1256 { 0x0000, 0x0000 }, /* R1252 */
1257 { 0x0000, 0x0000 }, /* R1253 */
1258 { 0x0000, 0x0000 }, /* R1254 */
1259 { 0x0000, 0x0000 }, /* R1255 */
1260 { 0x0000, 0x0000 }, /* R1256 */
1261 { 0x0000, 0x0000 }, /* R1257 */
1262 { 0x0000, 0x0000 }, /* R1258 */
1263 { 0x0000, 0x0000 }, /* R1259 */
1264 { 0x0000, 0x0000 }, /* R1260 */
1265 { 0x0000, 0x0000 }, /* R1261 */
1266 { 0x0000, 0x0000 }, /* R1262 */
1267 { 0x0000, 0x0000 }, /* R1263 */
1268 { 0x0000, 0x0000 }, /* R1264 */
1269 { 0x0000, 0x0000 }, /* R1265 */
1270 { 0x0000, 0x0000 }, /* R1266 */
1271 { 0x0000, 0x0000 }, /* R1267 */
1272 { 0x0000, 0x0000 }, /* R1268 */
1273 { 0x0000, 0x0000 }, /* R1269 */
1274 { 0x0000, 0x0000 }, /* R1270 */
1275 { 0x0000, 0x0000 }, /* R1271 */
1276 { 0x0000, 0x0000 }, /* R1272 */
1277 { 0x0000, 0x0000 }, /* R1273 */
1278 { 0x0000, 0x0000 }, /* R1274 */
1279 { 0x0000, 0x0000 }, /* R1275 */
1280 { 0x0000, 0x0000 }, /* R1276 */
1281 { 0x0000, 0x0000 }, /* R1277 */
1282 { 0x0000, 0x0000 }, /* R1278 */
1283 { 0x0000, 0x0000 }, /* R1279 */
1284 { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
1285 { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
1286 { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
1287 { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
1288 { 0x0000, 0x0000 }, /* R1284 */
1289 { 0x0000, 0x0000 }, /* R1285 */
1290 { 0x0000, 0x0000 }, /* R1286 */
1291 { 0x0000, 0x0000 }, /* R1287 */
1292 { 0x0000, 0x0000 }, /* R1288 */
1293 { 0x0000, 0x0000 }, /* R1289 */
1294 { 0x0000, 0x0000 }, /* R1290 */
1295 { 0x0000, 0x0000 }, /* R1291 */
1296 { 0x0000, 0x0000 }, /* R1292 */
1297 { 0x0000, 0x0000 }, /* R1293 */
1298 { 0x0000, 0x0000 }, /* R1294 */
1299 { 0x0000, 0x0000 }, /* R1295 */
1300 { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
1301 { 0x0000, 0x0000 }, /* R1297 */
1302 { 0x0000, 0x0000 }, /* R1298 */
1303 { 0x0000, 0x0000 }, /* R1299 */
1304 { 0x0000, 0x0000 }, /* R1300 */
1305 { 0x0000, 0x0000 }, /* R1301 */
1306 { 0x0000, 0x0000 }, /* R1302 */
1307 { 0x0000, 0x0000 }, /* R1303 */
1308 { 0x0000, 0x0000 }, /* R1304 */
1309 { 0x0000, 0x0000 }, /* R1305 */
1310 { 0x0000, 0x0000 }, /* R1306 */
1311 { 0x0000, 0x0000 }, /* R1307 */
1312 { 0x0000, 0x0000 }, /* R1308 */
1313 { 0x0000, 0x0000 }, /* R1309 */
1314 { 0x0000, 0x0000 }, /* R1310 */
1315 { 0x0000, 0x0000 }, /* R1311 */
1316 { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
1317 { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
1318 { 0x0000, 0x0000 }, /* R1314 */
1319 { 0x0000, 0x0000 }, /* R1315 */
1320 { 0x0000, 0x0000 }, /* R1316 */
1321 { 0x0000, 0x0000 }, /* R1317 */
1322 { 0x0000, 0x0000 }, /* R1318 */
1323 { 0x0000, 0x0000 }, /* R1319 */
1324 { 0x0000, 0x0000 }, /* R1320 */
1325 { 0x0000, 0x0000 }, /* R1321 */
1326 { 0x0000, 0x0000 }, /* R1322 */
1327 { 0x0000, 0x0000 }, /* R1323 */
1328 { 0x0000, 0x0000 }, /* R1324 */
1329 { 0x0000, 0x0000 }, /* R1325 */
1330 { 0x0000, 0x0000 }, /* R1326 */
1331 { 0x0000, 0x0000 }, /* R1327 */
1332 { 0x0000, 0x0000 }, /* R1328 */
1333 { 0x0000, 0x0000 }, /* R1329 */
1334 { 0x0000, 0x0000 }, /* R1330 */
1335 { 0x0000, 0x0000 }, /* R1331 */
1336 { 0x0000, 0x0000 }, /* R1332 */
1337 { 0x0000, 0x0000 }, /* R1333 */
1338 { 0x0000, 0x0000 }, /* R1334 */
1339 { 0x0000, 0x0000 }, /* R1335 */
1340 { 0x0000, 0x0000 }, /* R1336 */
1341 { 0x0000, 0x0000 }, /* R1337 */
1342 { 0x0000, 0x0000 }, /* R1338 */
1343 { 0x0000, 0x0000 }, /* R1339 */
1344 { 0x0000, 0x0000 }, /* R1340 */
1345 { 0x0000, 0x0000 }, /* R1341 */
1346 { 0x0000, 0x0000 }, /* R1342 */
1347 { 0x0000, 0x0000 }, /* R1343 */
1348 { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
1349 { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
1350 { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
1351 { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
1352 { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
1353 { 0x0000, 0x0000 }, /* R1349 */
1354 { 0x0000, 0x0000 }, /* R1350 */
1355 { 0x0000, 0x0000 }, /* R1351 */
1356 { 0x0000, 0x0000 }, /* R1352 */
1357 { 0x0000, 0x0000 }, /* R1353 */
1358 { 0x0000, 0x0000 }, /* R1354 */
1359 { 0x0000, 0x0000 }, /* R1355 */
1360 { 0x0000, 0x0000 }, /* R1356 */
1361 { 0x0000, 0x0000 }, /* R1357 */
1362 { 0x0000, 0x0000 }, /* R1358 */
1363 { 0x0000, 0x0000 }, /* R1359 */
1364 { 0x0000, 0x0000 }, /* R1360 */
1365 { 0x0000, 0x0000 }, /* R1361 */
1366 { 0x0000, 0x0000 }, /* R1362 */
1367 { 0x0000, 0x0000 }, /* R1363 */
1368 { 0x0000, 0x0000 }, /* R1364 */
1369 { 0x0000, 0x0000 }, /* R1365 */
1370 { 0x0000, 0x0000 }, /* R1366 */
1371 { 0x0000, 0x0000 }, /* R1367 */
1372 { 0x0000, 0x0000 }, /* R1368 */
1373 { 0x0000, 0x0000 }, /* R1369 */
1374 { 0x0000, 0x0000 }, /* R1370 */
1375 { 0x0000, 0x0000 }, /* R1371 */
1376 { 0x0000, 0x0000 }, /* R1372 */
1377 { 0x0000, 0x0000 }, /* R1373 */
1378 { 0x0000, 0x0000 }, /* R1374 */
1379 { 0x0000, 0x0000 }, /* R1375 */
1380 { 0x0000, 0x0000 }, /* R1376 */
1381 { 0x0000, 0x0000 }, /* R1377 */
1382 { 0x0000, 0x0000 }, /* R1378 */
1383 { 0x0000, 0x0000 }, /* R1379 */
1384 { 0x0000, 0x0000 }, /* R1380 */
1385 { 0x0000, 0x0000 }, /* R1381 */
1386 { 0x0000, 0x0000 }, /* R1382 */
1387 { 0x0000, 0x0000 }, /* R1383 */
1388 { 0x0000, 0x0000 }, /* R1384 */
1389 { 0x0000, 0x0000 }, /* R1385 */
1390 { 0x0000, 0x0000 }, /* R1386 */
1391 { 0x0000, 0x0000 }, /* R1387 */
1392 { 0x0000, 0x0000 }, /* R1388 */
1393 { 0x0000, 0x0000 }, /* R1389 */
1394 { 0x0000, 0x0000 }, /* R1390 */
1395 { 0x0000, 0x0000 }, /* R1391 */
1396 { 0x0000, 0x0000 }, /* R1392 */
1397 { 0x0000, 0x0000 }, /* R1393 */
1398 { 0x0000, 0x0000 }, /* R1394 */
1399 { 0x0000, 0x0000 }, /* R1395 */
1400 { 0x0000, 0x0000 }, /* R1396 */
1401 { 0x0000, 0x0000 }, /* R1397 */
1402 { 0x0000, 0x0000 }, /* R1398 */
1403 { 0x0000, 0x0000 }, /* R1399 */
1404 { 0x0000, 0x0000 }, /* R1400 */
1405 { 0x0000, 0x0000 }, /* R1401 */
1406 { 0x0000, 0x0000 }, /* R1402 */
1407 { 0x0000, 0x0000 }, /* R1403 */
1408 { 0x0000, 0x0000 }, /* R1404 */
1409 { 0x0000, 0x0000 }, /* R1405 */
1410 { 0x0000, 0x0000 }, /* R1406 */
1411 { 0x0000, 0x0000 }, /* R1407 */
1412 { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
1413 { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
1414 { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
1415 { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
1416 { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
1417 { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
1418 { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
1419 { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
1420 { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
1421 { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
1422 { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
1423 { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
1424 { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
1425 { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
1426 { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
1427 { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
1428 { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
1429 { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
1430 { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
1431 { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
1432 { 0x0000, 0x0000 }, /* R1428 */
1433 { 0x0000, 0x0000 }, /* R1429 */
1434 { 0x0000, 0x0000 }, /* R1430 */
1435 { 0x0000, 0x0000 }, /* R1431 */
1436 { 0x0000, 0x0000 }, /* R1432 */
1437 { 0x0000, 0x0000 }, /* R1433 */
1438 { 0x0000, 0x0000 }, /* R1434 */
1439 { 0x0000, 0x0000 }, /* R1435 */
1440 { 0x0000, 0x0000 }, /* R1436 */
1441 { 0x0000, 0x0000 }, /* R1437 */
1442 { 0x0000, 0x0000 }, /* R1438 */
1443 { 0x0000, 0x0000 }, /* R1439 */
1444 { 0x0000, 0x0000 }, /* R1440 */
1445 { 0x0000, 0x0000 }, /* R1441 */
1446 { 0x0000, 0x0000 }, /* R1442 */
1447 { 0x0000, 0x0000 }, /* R1443 */
1448 { 0x0000, 0x0000 }, /* R1444 */
1449 { 0x0000, 0x0000 }, /* R1445 */
1450 { 0x0000, 0x0000 }, /* R1446 */
1451 { 0x0000, 0x0000 }, /* R1447 */
1452 { 0x0000, 0x0000 }, /* R1448 */
1453 { 0x0000, 0x0000 }, /* R1449 */
1454 { 0x0000, 0x0000 }, /* R1450 */
1455 { 0x0000, 0x0000 }, /* R1451 */
1456 { 0x0000, 0x0000 }, /* R1452 */
1457 { 0x0000, 0x0000 }, /* R1453 */
1458 { 0x0000, 0x0000 }, /* R1454 */
1459 { 0x0000, 0x0000 }, /* R1455 */
1460 { 0x0000, 0x0000 }, /* R1456 */
1461 { 0x0000, 0x0000 }, /* R1457 */
1462 { 0x0000, 0x0000 }, /* R1458 */
1463 { 0x0000, 0x0000 }, /* R1459 */
1464 { 0x0000, 0x0000 }, /* R1460 */
1465 { 0x0000, 0x0000 }, /* R1461 */
1466 { 0x0000, 0x0000 }, /* R1462 */
1467 { 0x0000, 0x0000 }, /* R1463 */
1468 { 0x0000, 0x0000 }, /* R1464 */
1469 { 0x0000, 0x0000 }, /* R1465 */
1470 { 0x0000, 0x0000 }, /* R1466 */
1471 { 0x0000, 0x0000 }, /* R1467 */
1472 { 0x0000, 0x0000 }, /* R1468 */
1473 { 0x0000, 0x0000 }, /* R1469 */
1474 { 0x0000, 0x0000 }, /* R1470 */
1475 { 0x0000, 0x0000 }, /* R1471 */
1476 { 0x0000, 0x0000 }, /* R1472 */
1477 { 0x0000, 0x0000 }, /* R1473 */
1478 { 0x0000, 0x0000 }, /* R1474 */
1479 { 0x0000, 0x0000 }, /* R1475 */
1480 { 0x0000, 0x0000 }, /* R1476 */
1481 { 0x0000, 0x0000 }, /* R1477 */
1482 { 0x0000, 0x0000 }, /* R1478 */
1483 { 0x0000, 0x0000 }, /* R1479 */
1484 { 0x0000, 0x0000 }, /* R1480 */
1485 { 0x0000, 0x0000 }, /* R1481 */
1486 { 0x0000, 0x0000 }, /* R1482 */
1487 { 0x0000, 0x0000 }, /* R1483 */
1488 { 0x0000, 0x0000 }, /* R1484 */
1489 { 0x0000, 0x0000 }, /* R1485 */
1490 { 0x0000, 0x0000 }, /* R1486 */
1491 { 0x0000, 0x0000 }, /* R1487 */
1492 { 0x0000, 0x0000 }, /* R1488 */
1493 { 0x0000, 0x0000 }, /* R1489 */
1494 { 0x0000, 0x0000 }, /* R1490 */
1495 { 0x0000, 0x0000 }, /* R1491 */
1496 { 0x0000, 0x0000 }, /* R1492 */
1497 { 0x0000, 0x0000 }, /* R1493 */
1498 { 0x0000, 0x0000 }, /* R1494 */
1499 { 0x0000, 0x0000 }, /* R1495 */
1500 { 0x0000, 0x0000 }, /* R1496 */
1501 { 0x0000, 0x0000 }, /* R1497 */
1502 { 0x0000, 0x0000 }, /* R1498 */
1503 { 0x0000, 0x0000 }, /* R1499 */
1504 { 0x0000, 0x0000 }, /* R1500 */
1505 { 0x0000, 0x0000 }, /* R1501 */
1506 { 0x0000, 0x0000 }, /* R1502 */
1507 { 0x0000, 0x0000 }, /* R1503 */
1508 { 0x0000, 0x0000 }, /* R1504 */
1509 { 0x0000, 0x0000 }, /* R1505 */
1510 { 0x0000, 0x0000 }, /* R1506 */
1511 { 0x0000, 0x0000 }, /* R1507 */
1512 { 0x0000, 0x0000 }, /* R1508 */
1513 { 0x0000, 0x0000 }, /* R1509 */
1514 { 0x0000, 0x0000 }, /* R1510 */
1515 { 0x0000, 0x0000 }, /* R1511 */
1516 { 0x0000, 0x0000 }, /* R1512 */
1517 { 0x0000, 0x0000 }, /* R1513 */
1518 { 0x0000, 0x0000 }, /* R1514 */
1519 { 0x0000, 0x0000 }, /* R1515 */
1520 { 0x0000, 0x0000 }, /* R1516 */
1521 { 0x0000, 0x0000 }, /* R1517 */
1522 { 0x0000, 0x0000 }, /* R1518 */
1523 { 0x0000, 0x0000 }, /* R1519 */
1524 { 0x0000, 0x0000 }, /* R1520 */
1525 { 0x0000, 0x0000 }, /* R1521 */
1526 { 0x0000, 0x0000 }, /* R1522 */
1527 { 0x0000, 0x0000 }, /* R1523 */
1528 { 0x0000, 0x0000 }, /* R1524 */
1529 { 0x0000, 0x0000 }, /* R1525 */
1530 { 0x0000, 0x0000 }, /* R1526 */
1531 { 0x0000, 0x0000 }, /* R1527 */
1532 { 0x0000, 0x0000 }, /* R1528 */
1533 { 0x0000, 0x0000 }, /* R1529 */
1534 { 0x0000, 0x0000 }, /* R1530 */
1535 { 0x0000, 0x0000 }, /* R1531 */
1536 { 0x0000, 0x0000 }, /* R1532 */
1537 { 0x0000, 0x0000 }, /* R1533 */
1538 { 0x0000, 0x0000 }, /* R1534 */
1539 { 0x0000, 0x0000 }, /* R1535 */
1540 { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
1541 { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
1542 { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
1543 { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
1544 { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
1545 { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
1546 { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1547 { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1548 { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1549 { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1550 { 0x0000, 0x0000 }, /* R1546 */
1551 { 0x0000, 0x0000 }, /* R1547 */
1552 { 0x0000, 0x0000 }, /* R1548 */
1553 { 0x0000, 0x0000 }, /* R1549 */
1554 { 0x0000, 0x0000 }, /* R1550 */
1555 { 0x0000, 0x0000 }, /* R1551 */
1556 { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
1557 { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
1558 { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
1559 { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
1560 { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
1561 { 0x0000, 0x0000 }, /* R1557 */
1562 { 0x0000, 0x0000 }, /* R1558 */
1563 { 0x0000, 0x0000 }, /* R1559 */
1564 { 0x0000, 0x0000 }, /* R1560 */
1565 { 0x0000, 0x0000 }, /* R1561 */
1566 { 0x0000, 0x0000 }, /* R1562 */
1567 { 0x0000, 0x0000 }, /* R1563 */
1568 { 0x0000, 0x0000 }, /* R1564 */
1569 { 0x0000, 0x0000 }, /* R1565 */
1570 { 0x0000, 0x0000 }, /* R1566 */
1571 { 0x0000, 0x0000 }, /* R1567 */
1572 { 0x0003, 0x0003 }, /* R1568 - Oversampling */
1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
1574};
1575
1576const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1577 0x8994, /* R0 - Software Reset */
1578 0x0000, /* R1 - Power Management (1) */
1579 0x6000, /* R2 - Power Management (2) */
1580 0x0000, /* R3 - Power Management (3) */
1581 0x0000, /* R4 - Power Management (4) */
1582 0x0000, /* R5 - Power Management (5) */
1583 0x0000, /* R6 - Power Management (6) */
1584 0x0000, /* R7 */
1585 0x0000, /* R8 */
1586 0x0000, /* R9 */
1587 0x0000, /* R10 */
1588 0x0000, /* R11 */
1589 0x0000, /* R12 */
1590 0x0000, /* R13 */
1591 0x0000, /* R14 */
1592 0x0000, /* R15 */
1593 0x0000, /* R16 */
1594 0x0000, /* R17 */
1595 0x0000, /* R18 */
1596 0x0000, /* R19 */
1597 0x0000, /* R20 */
1598 0x0000, /* R21 - Input Mixer (1) */
1599 0x0000, /* R22 */
1600 0x0000, /* R23 */
1601 0x008B, /* R24 - Left Line Input 1&2 Volume */
1602 0x008B, /* R25 - Left Line Input 3&4 Volume */
1603 0x008B, /* R26 - Right Line Input 1&2 Volume */
1604 0x008B, /* R27 - Right Line Input 3&4 Volume */
1605 0x006D, /* R28 - Left Output Volume */
1606 0x006D, /* R29 - Right Output Volume */
1607 0x0066, /* R30 - Line Outputs Volume */
1608 0x0020, /* R31 - HPOUT2 Volume */
1609 0x0079, /* R32 - Left OPGA Volume */
1610 0x0079, /* R33 - Right OPGA Volume */
1611 0x0003, /* R34 - SPKMIXL Attenuation */
1612 0x0003, /* R35 - SPKMIXR Attenuation */
1613 0x0011, /* R36 - SPKOUT Mixers */
1614 0x0140, /* R37 - ClassD */
1615 0x0079, /* R38 - Speaker Volume Left */
1616 0x0079, /* R39 - Speaker Volume Right */
1617 0x0000, /* R40 - Input Mixer (2) */
1618 0x0000, /* R41 - Input Mixer (3) */
1619 0x0000, /* R42 - Input Mixer (4) */
1620 0x0000, /* R43 - Input Mixer (5) */
1621 0x0000, /* R44 - Input Mixer (6) */
1622 0x0000, /* R45 - Output Mixer (1) */
1623 0x0000, /* R46 - Output Mixer (2) */
1624 0x0000, /* R47 - Output Mixer (3) */
1625 0x0000, /* R48 - Output Mixer (4) */
1626 0x0000, /* R49 - Output Mixer (5) */
1627 0x0000, /* R50 - Output Mixer (6) */
1628 0x0000, /* R51 - HPOUT2 Mixer */
1629 0x0000, /* R52 - Line Mixer (1) */
1630 0x0000, /* R53 - Line Mixer (2) */
1631 0x0000, /* R54 - Speaker Mixer */
1632 0x0000, /* R55 - Additional Control */
1633 0x0000, /* R56 - AntiPOP (1) */
1634 0x0000, /* R57 - AntiPOP (2) */
1635 0x0000, /* R58 - MICBIAS */
1636 0x000D, /* R59 - LDO 1 */
1637 0x0003, /* R60 - LDO 2 */
1638 0x0000, /* R61 */
1639 0x0000, /* R62 */
1640 0x0000, /* R63 */
1641 0x0000, /* R64 */
1642 0x0000, /* R65 */
1643 0x0000, /* R66 */
1644 0x0000, /* R67 */
1645 0x0000, /* R68 */
1646 0x0000, /* R69 */
1647 0x0000, /* R70 */
1648 0x0000, /* R71 */
1649 0x0000, /* R72 */
1650 0x0000, /* R73 */
1651 0x0000, /* R74 */
1652 0x0000, /* R75 */
1653 0x1F25, /* R76 - Charge Pump (1) */
1654 0x0000, /* R77 */
1655 0x0000, /* R78 */
1656 0x0000, /* R79 */
1657 0x0000, /* R80 */
1658 0x0004, /* R81 - Class W (1) */
1659 0x0000, /* R82 */
1660 0x0000, /* R83 */
1661 0x0000, /* R84 - DC Servo (1) */
1662 0x054A, /* R85 - DC Servo (2) */
1663 0x0000, /* R86 */
1664 0x0000, /* R87 - DC Servo (4) */
1665 0x0000, /* R88 - DC Servo Readback */
1666 0x0000, /* R89 */
1667 0x0000, /* R90 */
1668 0x0000, /* R91 */
1669 0x0000, /* R92 */
1670 0x0000, /* R93 */
1671 0x0000, /* R94 */
1672 0x0000, /* R95 */
1673 0x0000, /* R96 - Analogue HP (1) */
1674 0x0000, /* R97 */
1675 0x0000, /* R98 */
1676 0x0000, /* R99 */
1677 0x0000, /* R100 */
1678 0x0000, /* R101 */
1679 0x0000, /* R102 */
1680 0x0000, /* R103 */
1681 0x0000, /* R104 */
1682 0x0000, /* R105 */
1683 0x0000, /* R106 */
1684 0x0000, /* R107 */
1685 0x0000, /* R108 */
1686 0x0000, /* R109 */
1687 0x0000, /* R110 */
1688 0x0000, /* R111 */
1689 0x0000, /* R112 */
1690 0x0000, /* R113 */
1691 0x0000, /* R114 */
1692 0x0000, /* R115 */
1693 0x0000, /* R116 */
1694 0x0000, /* R117 */
1695 0x0000, /* R118 */
1696 0x0000, /* R119 */
1697 0x0000, /* R120 */
1698 0x0000, /* R121 */
1699 0x0000, /* R122 */
1700 0x0000, /* R123 */
1701 0x0000, /* R124 */
1702 0x0000, /* R125 */
1703 0x0000, /* R126 */
1704 0x0000, /* R127 */
1705 0x0000, /* R128 */
1706 0x0000, /* R129 */
1707 0x0000, /* R130 */
1708 0x0000, /* R131 */
1709 0x0000, /* R132 */
1710 0x0000, /* R133 */
1711 0x0000, /* R134 */
1712 0x0000, /* R135 */
1713 0x0000, /* R136 */
1714 0x0000, /* R137 */
1715 0x0000, /* R138 */
1716 0x0000, /* R139 */
1717 0x0000, /* R140 */
1718 0x0000, /* R141 */
1719 0x0000, /* R142 */
1720 0x0000, /* R143 */
1721 0x0000, /* R144 */
1722 0x0000, /* R145 */
1723 0x0000, /* R146 */
1724 0x0000, /* R147 */
1725 0x0000, /* R148 */
1726 0x0000, /* R149 */
1727 0x0000, /* R150 */
1728 0x0000, /* R151 */
1729 0x0000, /* R152 */
1730 0x0000, /* R153 */
1731 0x0000, /* R154 */
1732 0x0000, /* R155 */
1733 0x0000, /* R156 */
1734 0x0000, /* R157 */
1735 0x0000, /* R158 */
1736 0x0000, /* R159 */
1737 0x0000, /* R160 */
1738 0x0000, /* R161 */
1739 0x0000, /* R162 */
1740 0x0000, /* R163 */
1741 0x0000, /* R164 */
1742 0x0000, /* R165 */
1743 0x0000, /* R166 */
1744 0x0000, /* R167 */
1745 0x0000, /* R168 */
1746 0x0000, /* R169 */
1747 0x0000, /* R170 */
1748 0x0000, /* R171 */
1749 0x0000, /* R172 */
1750 0x0000, /* R173 */
1751 0x0000, /* R174 */
1752 0x0000, /* R175 */
1753 0x0000, /* R176 */
1754 0x0000, /* R177 */
1755 0x0000, /* R178 */
1756 0x0000, /* R179 */
1757 0x0000, /* R180 */
1758 0x0000, /* R181 */
1759 0x0000, /* R182 */
1760 0x0000, /* R183 */
1761 0x0000, /* R184 */
1762 0x0000, /* R185 */
1763 0x0000, /* R186 */
1764 0x0000, /* R187 */
1765 0x0000, /* R188 */
1766 0x0000, /* R189 */
1767 0x0000, /* R190 */
1768 0x0000, /* R191 */
1769 0x0000, /* R192 */
1770 0x0000, /* R193 */
1771 0x0000, /* R194 */
1772 0x0000, /* R195 */
1773 0x0000, /* R196 */
1774 0x0000, /* R197 */
1775 0x0000, /* R198 */
1776 0x0000, /* R199 */
1777 0x0000, /* R200 */
1778 0x0000, /* R201 */
1779 0x0000, /* R202 */
1780 0x0000, /* R203 */
1781 0x0000, /* R204 */
1782 0x0000, /* R205 */
1783 0x0000, /* R206 */
1784 0x0000, /* R207 */
1785 0x0000, /* R208 */
1786 0x0000, /* R209 */
1787 0x0000, /* R210 */
1788 0x0000, /* R211 */
1789 0x0000, /* R212 */
1790 0x0000, /* R213 */
1791 0x0000, /* R214 */
1792 0x0000, /* R215 */
1793 0x0000, /* R216 */
1794 0x0000, /* R217 */
1795 0x0000, /* R218 */
1796 0x0000, /* R219 */
1797 0x0000, /* R220 */
1798 0x0000, /* R221 */
1799 0x0000, /* R222 */
1800 0x0000, /* R223 */
1801 0x0000, /* R224 */
1802 0x0000, /* R225 */
1803 0x0000, /* R226 */
1804 0x0000, /* R227 */
1805 0x0000, /* R228 */
1806 0x0000, /* R229 */
1807 0x0000, /* R230 */
1808 0x0000, /* R231 */
1809 0x0000, /* R232 */
1810 0x0000, /* R233 */
1811 0x0000, /* R234 */
1812 0x0000, /* R235 */
1813 0x0000, /* R236 */
1814 0x0000, /* R237 */
1815 0x0000, /* R238 */
1816 0x0000, /* R239 */
1817 0x0000, /* R240 */
1818 0x0000, /* R241 */
1819 0x0000, /* R242 */
1820 0x0000, /* R243 */
1821 0x0000, /* R244 */
1822 0x0000, /* R245 */
1823 0x0000, /* R246 */
1824 0x0000, /* R247 */
1825 0x0000, /* R248 */
1826 0x0000, /* R249 */
1827 0x0000, /* R250 */
1828 0x0000, /* R251 */
1829 0x0000, /* R252 */
1830 0x0000, /* R253 */
1831 0x0000, /* R254 */
1832 0x0000, /* R255 */
1833 0x0003, /* R256 - Chip Revision */
1834 0x8004, /* R257 - Control Interface */
1835 0x0000, /* R258 */
1836 0x0000, /* R259 */
1837 0x0000, /* R260 */
1838 0x0000, /* R261 */
1839 0x0000, /* R262 */
1840 0x0000, /* R263 */
1841 0x0000, /* R264 */
1842 0x0000, /* R265 */
1843 0x0000, /* R266 */
1844 0x0000, /* R267 */
1845 0x0000, /* R268 */
1846 0x0000, /* R269 */
1847 0x0000, /* R270 */
1848 0x0000, /* R271 */
1849 0x0000, /* R272 - Write Sequencer Ctrl (1) */
1850 0x0000, /* R273 - Write Sequencer Ctrl (2) */
1851 0x0000, /* R274 */
1852 0x0000, /* R275 */
1853 0x0000, /* R276 */
1854 0x0000, /* R277 */
1855 0x0000, /* R278 */
1856 0x0000, /* R279 */
1857 0x0000, /* R280 */
1858 0x0000, /* R281 */
1859 0x0000, /* R282 */
1860 0x0000, /* R283 */
1861 0x0000, /* R284 */
1862 0x0000, /* R285 */
1863 0x0000, /* R286 */
1864 0x0000, /* R287 */
1865 0x0000, /* R288 */
1866 0x0000, /* R289 */
1867 0x0000, /* R290 */
1868 0x0000, /* R291 */
1869 0x0000, /* R292 */
1870 0x0000, /* R293 */
1871 0x0000, /* R294 */
1872 0x0000, /* R295 */
1873 0x0000, /* R296 */
1874 0x0000, /* R297 */
1875 0x0000, /* R298 */
1876 0x0000, /* R299 */
1877 0x0000, /* R300 */
1878 0x0000, /* R301 */
1879 0x0000, /* R302 */
1880 0x0000, /* R303 */
1881 0x0000, /* R304 */
1882 0x0000, /* R305 */
1883 0x0000, /* R306 */
1884 0x0000, /* R307 */
1885 0x0000, /* R308 */
1886 0x0000, /* R309 */
1887 0x0000, /* R310 */
1888 0x0000, /* R311 */
1889 0x0000, /* R312 */
1890 0x0000, /* R313 */
1891 0x0000, /* R314 */
1892 0x0000, /* R315 */
1893 0x0000, /* R316 */
1894 0x0000, /* R317 */
1895 0x0000, /* R318 */
1896 0x0000, /* R319 */
1897 0x0000, /* R320 */
1898 0x0000, /* R321 */
1899 0x0000, /* R322 */
1900 0x0000, /* R323 */
1901 0x0000, /* R324 */
1902 0x0000, /* R325 */
1903 0x0000, /* R326 */
1904 0x0000, /* R327 */
1905 0x0000, /* R328 */
1906 0x0000, /* R329 */
1907 0x0000, /* R330 */
1908 0x0000, /* R331 */
1909 0x0000, /* R332 */
1910 0x0000, /* R333 */
1911 0x0000, /* R334 */
1912 0x0000, /* R335 */
1913 0x0000, /* R336 */
1914 0x0000, /* R337 */
1915 0x0000, /* R338 */
1916 0x0000, /* R339 */
1917 0x0000, /* R340 */
1918 0x0000, /* R341 */
1919 0x0000, /* R342 */
1920 0x0000, /* R343 */
1921 0x0000, /* R344 */
1922 0x0000, /* R345 */
1923 0x0000, /* R346 */
1924 0x0000, /* R347 */
1925 0x0000, /* R348 */
1926 0x0000, /* R349 */
1927 0x0000, /* R350 */
1928 0x0000, /* R351 */
1929 0x0000, /* R352 */
1930 0x0000, /* R353 */
1931 0x0000, /* R354 */
1932 0x0000, /* R355 */
1933 0x0000, /* R356 */
1934 0x0000, /* R357 */
1935 0x0000, /* R358 */
1936 0x0000, /* R359 */
1937 0x0000, /* R360 */
1938 0x0000, /* R361 */
1939 0x0000, /* R362 */
1940 0x0000, /* R363 */
1941 0x0000, /* R364 */
1942 0x0000, /* R365 */
1943 0x0000, /* R366 */
1944 0x0000, /* R367 */
1945 0x0000, /* R368 */
1946 0x0000, /* R369 */
1947 0x0000, /* R370 */
1948 0x0000, /* R371 */
1949 0x0000, /* R372 */
1950 0x0000, /* R373 */
1951 0x0000, /* R374 */
1952 0x0000, /* R375 */
1953 0x0000, /* R376 */
1954 0x0000, /* R377 */
1955 0x0000, /* R378 */
1956 0x0000, /* R379 */
1957 0x0000, /* R380 */
1958 0x0000, /* R381 */
1959 0x0000, /* R382 */
1960 0x0000, /* R383 */
1961 0x0000, /* R384 */
1962 0x0000, /* R385 */
1963 0x0000, /* R386 */
1964 0x0000, /* R387 */
1965 0x0000, /* R388 */
1966 0x0000, /* R389 */
1967 0x0000, /* R390 */
1968 0x0000, /* R391 */
1969 0x0000, /* R392 */
1970 0x0000, /* R393 */
1971 0x0000, /* R394 */
1972 0x0000, /* R395 */
1973 0x0000, /* R396 */
1974 0x0000, /* R397 */
1975 0x0000, /* R398 */
1976 0x0000, /* R399 */
1977 0x0000, /* R400 */
1978 0x0000, /* R401 */
1979 0x0000, /* R402 */
1980 0x0000, /* R403 */
1981 0x0000, /* R404 */
1982 0x0000, /* R405 */
1983 0x0000, /* R406 */
1984 0x0000, /* R407 */
1985 0x0000, /* R408 */
1986 0x0000, /* R409 */
1987 0x0000, /* R410 */
1988 0x0000, /* R411 */
1989 0x0000, /* R412 */
1990 0x0000, /* R413 */
1991 0x0000, /* R414 */
1992 0x0000, /* R415 */
1993 0x0000, /* R416 */
1994 0x0000, /* R417 */
1995 0x0000, /* R418 */
1996 0x0000, /* R419 */
1997 0x0000, /* R420 */
1998 0x0000, /* R421 */
1999 0x0000, /* R422 */
2000 0x0000, /* R423 */
2001 0x0000, /* R424 */
2002 0x0000, /* R425 */
2003 0x0000, /* R426 */
2004 0x0000, /* R427 */
2005 0x0000, /* R428 */
2006 0x0000, /* R429 */
2007 0x0000, /* R430 */
2008 0x0000, /* R431 */
2009 0x0000, /* R432 */
2010 0x0000, /* R433 */
2011 0x0000, /* R434 */
2012 0x0000, /* R435 */
2013 0x0000, /* R436 */
2014 0x0000, /* R437 */
2015 0x0000, /* R438 */
2016 0x0000, /* R439 */
2017 0x0000, /* R440 */
2018 0x0000, /* R441 */
2019 0x0000, /* R442 */
2020 0x0000, /* R443 */
2021 0x0000, /* R444 */
2022 0x0000, /* R445 */
2023 0x0000, /* R446 */
2024 0x0000, /* R447 */
2025 0x0000, /* R448 */
2026 0x0000, /* R449 */
2027 0x0000, /* R450 */
2028 0x0000, /* R451 */
2029 0x0000, /* R452 */
2030 0x0000, /* R453 */
2031 0x0000, /* R454 */
2032 0x0000, /* R455 */
2033 0x0000, /* R456 */
2034 0x0000, /* R457 */
2035 0x0000, /* R458 */
2036 0x0000, /* R459 */
2037 0x0000, /* R460 */
2038 0x0000, /* R461 */
2039 0x0000, /* R462 */
2040 0x0000, /* R463 */
2041 0x0000, /* R464 */
2042 0x0000, /* R465 */
2043 0x0000, /* R466 */
2044 0x0000, /* R467 */
2045 0x0000, /* R468 */
2046 0x0000, /* R469 */
2047 0x0000, /* R470 */
2048 0x0000, /* R471 */
2049 0x0000, /* R472 */
2050 0x0000, /* R473 */
2051 0x0000, /* R474 */
2052 0x0000, /* R475 */
2053 0x0000, /* R476 */
2054 0x0000, /* R477 */
2055 0x0000, /* R478 */
2056 0x0000, /* R479 */
2057 0x0000, /* R480 */
2058 0x0000, /* R481 */
2059 0x0000, /* R482 */
2060 0x0000, /* R483 */
2061 0x0000, /* R484 */
2062 0x0000, /* R485 */
2063 0x0000, /* R486 */
2064 0x0000, /* R487 */
2065 0x0000, /* R488 */
2066 0x0000, /* R489 */
2067 0x0000, /* R490 */
2068 0x0000, /* R491 */
2069 0x0000, /* R492 */
2070 0x0000, /* R493 */
2071 0x0000, /* R494 */
2072 0x0000, /* R495 */
2073 0x0000, /* R496 */
2074 0x0000, /* R497 */
2075 0x0000, /* R498 */
2076 0x0000, /* R499 */
2077 0x0000, /* R500 */
2078 0x0000, /* R501 */
2079 0x0000, /* R502 */
2080 0x0000, /* R503 */
2081 0x0000, /* R504 */
2082 0x0000, /* R505 */
2083 0x0000, /* R506 */
2084 0x0000, /* R507 */
2085 0x0000, /* R508 */
2086 0x0000, /* R509 */
2087 0x0000, /* R510 */
2088 0x0000, /* R511 */
2089 0x0000, /* R512 - AIF1 Clocking (1) */
2090 0x0000, /* R513 - AIF1 Clocking (2) */
2091 0x0000, /* R514 */
2092 0x0000, /* R515 */
2093 0x0000, /* R516 - AIF2 Clocking (1) */
2094 0x0000, /* R517 - AIF2 Clocking (2) */
2095 0x0000, /* R518 */
2096 0x0000, /* R519 */
2097 0x0000, /* R520 - Clocking (1) */
2098 0x0000, /* R521 - Clocking (2) */
2099 0x0000, /* R522 */
2100 0x0000, /* R523 */
2101 0x0000, /* R524 */
2102 0x0000, /* R525 */
2103 0x0000, /* R526 */
2104 0x0000, /* R527 */
2105 0x0083, /* R528 - AIF1 Rate */
2106 0x0083, /* R529 - AIF2 Rate */
2107 0x0000, /* R530 - Rate Status */
2108 0x0000, /* R531 */
2109 0x0000, /* R532 */
2110 0x0000, /* R533 */
2111 0x0000, /* R534 */
2112 0x0000, /* R535 */
2113 0x0000, /* R536 */
2114 0x0000, /* R537 */
2115 0x0000, /* R538 */
2116 0x0000, /* R539 */
2117 0x0000, /* R540 */
2118 0x0000, /* R541 */
2119 0x0000, /* R542 */
2120 0x0000, /* R543 */
2121 0x0000, /* R544 - FLL1 Control (1) */
2122 0x0000, /* R545 - FLL1 Control (2) */
2123 0x0000, /* R546 - FLL1 Control (3) */
2124 0x0000, /* R547 - FLL1 Control (4) */
2125 0x0C80, /* R548 - FLL1 Control (5) */
2126 0x0000, /* R549 */
2127 0x0000, /* R550 */
2128 0x0000, /* R551 */
2129 0x0000, /* R552 */
2130 0x0000, /* R553 */
2131 0x0000, /* R554 */
2132 0x0000, /* R555 */
2133 0x0000, /* R556 */
2134 0x0000, /* R557 */
2135 0x0000, /* R558 */
2136 0x0000, /* R559 */
2137 0x0000, /* R560 */
2138 0x0000, /* R561 */
2139 0x0000, /* R562 */
2140 0x0000, /* R563 */
2141 0x0000, /* R564 */
2142 0x0000, /* R565 */
2143 0x0000, /* R566 */
2144 0x0000, /* R567 */
2145 0x0000, /* R568 */
2146 0x0000, /* R569 */
2147 0x0000, /* R570 */
2148 0x0000, /* R571 */
2149 0x0000, /* R572 */
2150 0x0000, /* R573 */
2151 0x0000, /* R574 */
2152 0x0000, /* R575 */
2153 0x0000, /* R576 - FLL2 Control (1) */
2154 0x0000, /* R577 - FLL2 Control (2) */
2155 0x0000, /* R578 - FLL2 Control (3) */
2156 0x0000, /* R579 - FLL2 Control (4) */
2157 0x0C80, /* R580 - FLL2 Control (5) */
2158 0x0000, /* R581 */
2159 0x0000, /* R582 */
2160 0x0000, /* R583 */
2161 0x0000, /* R584 */
2162 0x0000, /* R585 */
2163 0x0000, /* R586 */
2164 0x0000, /* R587 */
2165 0x0000, /* R588 */
2166 0x0000, /* R589 */
2167 0x0000, /* R590 */
2168 0x0000, /* R591 */
2169 0x0000, /* R592 */
2170 0x0000, /* R593 */
2171 0x0000, /* R594 */
2172 0x0000, /* R595 */
2173 0x0000, /* R596 */
2174 0x0000, /* R597 */
2175 0x0000, /* R598 */
2176 0x0000, /* R599 */
2177 0x0000, /* R600 */
2178 0x0000, /* R601 */
2179 0x0000, /* R602 */
2180 0x0000, /* R603 */
2181 0x0000, /* R604 */
2182 0x0000, /* R605 */
2183 0x0000, /* R606 */
2184 0x0000, /* R607 */
2185 0x0000, /* R608 */
2186 0x0000, /* R609 */
2187 0x0000, /* R610 */
2188 0x0000, /* R611 */
2189 0x0000, /* R612 */
2190 0x0000, /* R613 */
2191 0x0000, /* R614 */
2192 0x0000, /* R615 */
2193 0x0000, /* R616 */
2194 0x0000, /* R617 */
2195 0x0000, /* R618 */
2196 0x0000, /* R619 */
2197 0x0000, /* R620 */
2198 0x0000, /* R621 */
2199 0x0000, /* R622 */
2200 0x0000, /* R623 */
2201 0x0000, /* R624 */
2202 0x0000, /* R625 */
2203 0x0000, /* R626 */
2204 0x0000, /* R627 */
2205 0x0000, /* R628 */
2206 0x0000, /* R629 */
2207 0x0000, /* R630 */
2208 0x0000, /* R631 */
2209 0x0000, /* R632 */
2210 0x0000, /* R633 */
2211 0x0000, /* R634 */
2212 0x0000, /* R635 */
2213 0x0000, /* R636 */
2214 0x0000, /* R637 */
2215 0x0000, /* R638 */
2216 0x0000, /* R639 */
2217 0x0000, /* R640 */
2218 0x0000, /* R641 */
2219 0x0000, /* R642 */
2220 0x0000, /* R643 */
2221 0x0000, /* R644 */
2222 0x0000, /* R645 */
2223 0x0000, /* R646 */
2224 0x0000, /* R647 */
2225 0x0000, /* R648 */
2226 0x0000, /* R649 */
2227 0x0000, /* R650 */
2228 0x0000, /* R651 */
2229 0x0000, /* R652 */
2230 0x0000, /* R653 */
2231 0x0000, /* R654 */
2232 0x0000, /* R655 */
2233 0x0000, /* R656 */
2234 0x0000, /* R657 */
2235 0x0000, /* R658 */
2236 0x0000, /* R659 */
2237 0x0000, /* R660 */
2238 0x0000, /* R661 */
2239 0x0000, /* R662 */
2240 0x0000, /* R663 */
2241 0x0000, /* R664 */
2242 0x0000, /* R665 */
2243 0x0000, /* R666 */
2244 0x0000, /* R667 */
2245 0x0000, /* R668 */
2246 0x0000, /* R669 */
2247 0x0000, /* R670 */
2248 0x0000, /* R671 */
2249 0x0000, /* R672 */
2250 0x0000, /* R673 */
2251 0x0000, /* R674 */
2252 0x0000, /* R675 */
2253 0x0000, /* R676 */
2254 0x0000, /* R677 */
2255 0x0000, /* R678 */
2256 0x0000, /* R679 */
2257 0x0000, /* R680 */
2258 0x0000, /* R681 */
2259 0x0000, /* R682 */
2260 0x0000, /* R683 */
2261 0x0000, /* R684 */
2262 0x0000, /* R685 */
2263 0x0000, /* R686 */
2264 0x0000, /* R687 */
2265 0x0000, /* R688 */
2266 0x0000, /* R689 */
2267 0x0000, /* R690 */
2268 0x0000, /* R691 */
2269 0x0000, /* R692 */
2270 0x0000, /* R693 */
2271 0x0000, /* R694 */
2272 0x0000, /* R695 */
2273 0x0000, /* R696 */
2274 0x0000, /* R697 */
2275 0x0000, /* R698 */
2276 0x0000, /* R699 */
2277 0x0000, /* R700 */
2278 0x0000, /* R701 */
2279 0x0000, /* R702 */
2280 0x0000, /* R703 */
2281 0x0000, /* R704 */
2282 0x0000, /* R705 */
2283 0x0000, /* R706 */
2284 0x0000, /* R707 */
2285 0x0000, /* R708 */
2286 0x0000, /* R709 */
2287 0x0000, /* R710 */
2288 0x0000, /* R711 */
2289 0x0000, /* R712 */
2290 0x0000, /* R713 */
2291 0x0000, /* R714 */
2292 0x0000, /* R715 */
2293 0x0000, /* R716 */
2294 0x0000, /* R717 */
2295 0x0000, /* R718 */
2296 0x0000, /* R719 */
2297 0x0000, /* R720 */
2298 0x0000, /* R721 */
2299 0x0000, /* R722 */
2300 0x0000, /* R723 */
2301 0x0000, /* R724 */
2302 0x0000, /* R725 */
2303 0x0000, /* R726 */
2304 0x0000, /* R727 */
2305 0x0000, /* R728 */
2306 0x0000, /* R729 */
2307 0x0000, /* R730 */
2308 0x0000, /* R731 */
2309 0x0000, /* R732 */
2310 0x0000, /* R733 */
2311 0x0000, /* R734 */
2312 0x0000, /* R735 */
2313 0x0000, /* R736 */
2314 0x0000, /* R737 */
2315 0x0000, /* R738 */
2316 0x0000, /* R739 */
2317 0x0000, /* R740 */
2318 0x0000, /* R741 */
2319 0x0000, /* R742 */
2320 0x0000, /* R743 */
2321 0x0000, /* R744 */
2322 0x0000, /* R745 */
2323 0x0000, /* R746 */
2324 0x0000, /* R747 */
2325 0x0000, /* R748 */
2326 0x0000, /* R749 */
2327 0x0000, /* R750 */
2328 0x0000, /* R751 */
2329 0x0000, /* R752 */
2330 0x0000, /* R753 */
2331 0x0000, /* R754 */
2332 0x0000, /* R755 */
2333 0x0000, /* R756 */
2334 0x0000, /* R757 */
2335 0x0000, /* R758 */
2336 0x0000, /* R759 */
2337 0x0000, /* R760 */
2338 0x0000, /* R761 */
2339 0x0000, /* R762 */
2340 0x0000, /* R763 */
2341 0x0000, /* R764 */
2342 0x0000, /* R765 */
2343 0x0000, /* R766 */
2344 0x0000, /* R767 */
2345 0x4050, /* R768 - AIF1 Control (1) */
2346 0x4000, /* R769 - AIF1 Control (2) */
2347 0x0000, /* R770 - AIF1 Master/Slave */
2348 0x0040, /* R771 - AIF1 BCLK */
2349 0x0040, /* R772 - AIF1ADC LRCLK */
2350 0x0040, /* R773 - AIF1DAC LRCLK */
2351 0x0004, /* R774 - AIF1DAC Data */
2352 0x0100, /* R775 - AIF1ADC Data */
2353 0x0000, /* R776 */
2354 0x0000, /* R777 */
2355 0x0000, /* R778 */
2356 0x0000, /* R779 */
2357 0x0000, /* R780 */
2358 0x0000, /* R781 */
2359 0x0000, /* R782 */
2360 0x0000, /* R783 */
2361 0x4050, /* R784 - AIF2 Control (1) */
2362 0x4000, /* R785 - AIF2 Control (2) */
2363 0x0000, /* R786 - AIF2 Master/Slave */
2364 0x0040, /* R787 - AIF2 BCLK */
2365 0x0040, /* R788 - AIF2ADC LRCLK */
2366 0x0040, /* R789 - AIF2DAC LRCLK */
2367 0x0000, /* R790 - AIF2DAC Data */
2368 0x0000, /* R791 - AIF2ADC Data */
2369 0x0000, /* R792 */
2370 0x0000, /* R793 */
2371 0x0000, /* R794 */
2372 0x0000, /* R795 */
2373 0x0000, /* R796 */
2374 0x0000, /* R797 */
2375 0x0000, /* R798 */
2376 0x0000, /* R799 */
2377 0x0000, /* R800 */
2378 0x0000, /* R801 */
2379 0x0000, /* R802 */
2380 0x0000, /* R803 */
2381 0x0000, /* R804 */
2382 0x0000, /* R805 */
2383 0x0000, /* R806 */
2384 0x0000, /* R807 */
2385 0x0000, /* R808 */
2386 0x0000, /* R809 */
2387 0x0000, /* R810 */
2388 0x0000, /* R811 */
2389 0x0000, /* R812 */
2390 0x0000, /* R813 */
2391 0x0000, /* R814 */
2392 0x0000, /* R815 */
2393 0x0000, /* R816 */
2394 0x0000, /* R817 */
2395 0x0000, /* R818 */
2396 0x0000, /* R819 */
2397 0x0000, /* R820 */
2398 0x0000, /* R821 */
2399 0x0000, /* R822 */
2400 0x0000, /* R823 */
2401 0x0000, /* R824 */
2402 0x0000, /* R825 */
2403 0x0000, /* R826 */
2404 0x0000, /* R827 */
2405 0x0000, /* R828 */
2406 0x0000, /* R829 */
2407 0x0000, /* R830 */
2408 0x0000, /* R831 */
2409 0x0000, /* R832 */
2410 0x0000, /* R833 */
2411 0x0000, /* R834 */
2412 0x0000, /* R835 */
2413 0x0000, /* R836 */
2414 0x0000, /* R837 */
2415 0x0000, /* R838 */
2416 0x0000, /* R839 */
2417 0x0000, /* R840 */
2418 0x0000, /* R841 */
2419 0x0000, /* R842 */
2420 0x0000, /* R843 */
2421 0x0000, /* R844 */
2422 0x0000, /* R845 */
2423 0x0000, /* R846 */
2424 0x0000, /* R847 */
2425 0x0000, /* R848 */
2426 0x0000, /* R849 */
2427 0x0000, /* R850 */
2428 0x0000, /* R851 */
2429 0x0000, /* R852 */
2430 0x0000, /* R853 */
2431 0x0000, /* R854 */
2432 0x0000, /* R855 */
2433 0x0000, /* R856 */
2434 0x0000, /* R857 */
2435 0x0000, /* R858 */
2436 0x0000, /* R859 */
2437 0x0000, /* R860 */
2438 0x0000, /* R861 */
2439 0x0000, /* R862 */
2440 0x0000, /* R863 */
2441 0x0000, /* R864 */
2442 0x0000, /* R865 */
2443 0x0000, /* R866 */
2444 0x0000, /* R867 */
2445 0x0000, /* R868 */
2446 0x0000, /* R869 */
2447 0x0000, /* R870 */
2448 0x0000, /* R871 */
2449 0x0000, /* R872 */
2450 0x0000, /* R873 */
2451 0x0000, /* R874 */
2452 0x0000, /* R875 */
2453 0x0000, /* R876 */
2454 0x0000, /* R877 */
2455 0x0000, /* R878 */
2456 0x0000, /* R879 */
2457 0x0000, /* R880 */
2458 0x0000, /* R881 */
2459 0x0000, /* R882 */
2460 0x0000, /* R883 */
2461 0x0000, /* R884 */
2462 0x0000, /* R885 */
2463 0x0000, /* R886 */
2464 0x0000, /* R887 */
2465 0x0000, /* R888 */
2466 0x0000, /* R889 */
2467 0x0000, /* R890 */
2468 0x0000, /* R891 */
2469 0x0000, /* R892 */
2470 0x0000, /* R893 */
2471 0x0000, /* R894 */
2472 0x0000, /* R895 */
2473 0x0000, /* R896 */
2474 0x0000, /* R897 */
2475 0x0000, /* R898 */
2476 0x0000, /* R899 */
2477 0x0000, /* R900 */
2478 0x0000, /* R901 */
2479 0x0000, /* R902 */
2480 0x0000, /* R903 */
2481 0x0000, /* R904 */
2482 0x0000, /* R905 */
2483 0x0000, /* R906 */
2484 0x0000, /* R907 */
2485 0x0000, /* R908 */
2486 0x0000, /* R909 */
2487 0x0000, /* R910 */
2488 0x0000, /* R911 */
2489 0x0000, /* R912 */
2490 0x0000, /* R913 */
2491 0x0000, /* R914 */
2492 0x0000, /* R915 */
2493 0x0000, /* R916 */
2494 0x0000, /* R917 */
2495 0x0000, /* R918 */
2496 0x0000, /* R919 */
2497 0x0000, /* R920 */
2498 0x0000, /* R921 */
2499 0x0000, /* R922 */
2500 0x0000, /* R923 */
2501 0x0000, /* R924 */
2502 0x0000, /* R925 */
2503 0x0000, /* R926 */
2504 0x0000, /* R927 */
2505 0x0000, /* R928 */
2506 0x0000, /* R929 */
2507 0x0000, /* R930 */
2508 0x0000, /* R931 */
2509 0x0000, /* R932 */
2510 0x0000, /* R933 */
2511 0x0000, /* R934 */
2512 0x0000, /* R935 */
2513 0x0000, /* R936 */
2514 0x0000, /* R937 */
2515 0x0000, /* R938 */
2516 0x0000, /* R939 */
2517 0x0000, /* R940 */
2518 0x0000, /* R941 */
2519 0x0000, /* R942 */
2520 0x0000, /* R943 */
2521 0x0000, /* R944 */
2522 0x0000, /* R945 */
2523 0x0000, /* R946 */
2524 0x0000, /* R947 */
2525 0x0000, /* R948 */
2526 0x0000, /* R949 */
2527 0x0000, /* R950 */
2528 0x0000, /* R951 */
2529 0x0000, /* R952 */
2530 0x0000, /* R953 */
2531 0x0000, /* R954 */
2532 0x0000, /* R955 */
2533 0x0000, /* R956 */
2534 0x0000, /* R957 */
2535 0x0000, /* R958 */
2536 0x0000, /* R959 */
2537 0x0000, /* R960 */
2538 0x0000, /* R961 */
2539 0x0000, /* R962 */
2540 0x0000, /* R963 */
2541 0x0000, /* R964 */
2542 0x0000, /* R965 */
2543 0x0000, /* R966 */
2544 0x0000, /* R967 */
2545 0x0000, /* R968 */
2546 0x0000, /* R969 */
2547 0x0000, /* R970 */
2548 0x0000, /* R971 */
2549 0x0000, /* R972 */
2550 0x0000, /* R973 */
2551 0x0000, /* R974 */
2552 0x0000, /* R975 */
2553 0x0000, /* R976 */
2554 0x0000, /* R977 */
2555 0x0000, /* R978 */
2556 0x0000, /* R979 */
2557 0x0000, /* R980 */
2558 0x0000, /* R981 */
2559 0x0000, /* R982 */
2560 0x0000, /* R983 */
2561 0x0000, /* R984 */
2562 0x0000, /* R985 */
2563 0x0000, /* R986 */
2564 0x0000, /* R987 */
2565 0x0000, /* R988 */
2566 0x0000, /* R989 */
2567 0x0000, /* R990 */
2568 0x0000, /* R991 */
2569 0x0000, /* R992 */
2570 0x0000, /* R993 */
2571 0x0000, /* R994 */
2572 0x0000, /* R995 */
2573 0x0000, /* R996 */
2574 0x0000, /* R997 */
2575 0x0000, /* R998 */
2576 0x0000, /* R999 */
2577 0x0000, /* R1000 */
2578 0x0000, /* R1001 */
2579 0x0000, /* R1002 */
2580 0x0000, /* R1003 */
2581 0x0000, /* R1004 */
2582 0x0000, /* R1005 */
2583 0x0000, /* R1006 */
2584 0x0000, /* R1007 */
2585 0x0000, /* R1008 */
2586 0x0000, /* R1009 */
2587 0x0000, /* R1010 */
2588 0x0000, /* R1011 */
2589 0x0000, /* R1012 */
2590 0x0000, /* R1013 */
2591 0x0000, /* R1014 */
2592 0x0000, /* R1015 */
2593 0x0000, /* R1016 */
2594 0x0000, /* R1017 */
2595 0x0000, /* R1018 */
2596 0x0000, /* R1019 */
2597 0x0000, /* R1020 */
2598 0x0000, /* R1021 */
2599 0x0000, /* R1022 */
2600 0x0000, /* R1023 */
2601 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */
2602 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */
2603 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */
2604 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */
2605 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */
2606 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */
2607 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */
2608 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */
2609 0x0000, /* R1032 */
2610 0x0000, /* R1033 */
2611 0x0000, /* R1034 */
2612 0x0000, /* R1035 */
2613 0x0000, /* R1036 */
2614 0x0000, /* R1037 */
2615 0x0000, /* R1038 */
2616 0x0000, /* R1039 */
2617 0x0000, /* R1040 - AIF1 ADC1 Filters */
2618 0x0000, /* R1041 - AIF1 ADC2 Filters */
2619 0x0000, /* R1042 */
2620 0x0000, /* R1043 */
2621 0x0000, /* R1044 */
2622 0x0000, /* R1045 */
2623 0x0000, /* R1046 */
2624 0x0000, /* R1047 */
2625 0x0000, /* R1048 */
2626 0x0000, /* R1049 */
2627 0x0000, /* R1050 */
2628 0x0000, /* R1051 */
2629 0x0000, /* R1052 */
2630 0x0000, /* R1053 */
2631 0x0000, /* R1054 */
2632 0x0000, /* R1055 */
2633 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */
2634 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */
2635 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */
2636 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */
2637 0x0000, /* R1060 */
2638 0x0000, /* R1061 */
2639 0x0000, /* R1062 */
2640 0x0000, /* R1063 */
2641 0x0000, /* R1064 */
2642 0x0000, /* R1065 */
2643 0x0000, /* R1066 */
2644 0x0000, /* R1067 */
2645 0x0000, /* R1068 */
2646 0x0000, /* R1069 */
2647 0x0000, /* R1070 */
2648 0x0000, /* R1071 */
2649 0x0000, /* R1072 */
2650 0x0000, /* R1073 */
2651 0x0000, /* R1074 */
2652 0x0000, /* R1075 */
2653 0x0000, /* R1076 */
2654 0x0000, /* R1077 */
2655 0x0000, /* R1078 */
2656 0x0000, /* R1079 */
2657 0x0000, /* R1080 */
2658 0x0000, /* R1081 */
2659 0x0000, /* R1082 */
2660 0x0000, /* R1083 */
2661 0x0000, /* R1084 */
2662 0x0000, /* R1085 */
2663 0x0000, /* R1086 */
2664 0x0000, /* R1087 */
2665 0x0098, /* R1088 - AIF1 DRC1 (1) */
2666 0x0845, /* R1089 - AIF1 DRC1 (2) */
2667 0x0000, /* R1090 - AIF1 DRC1 (3) */
2668 0x0000, /* R1091 - AIF1 DRC1 (4) */
2669 0x0000, /* R1092 - AIF1 DRC1 (5) */
2670 0x0000, /* R1093 */
2671 0x0000, /* R1094 */
2672 0x0000, /* R1095 */
2673 0x0000, /* R1096 */
2674 0x0000, /* R1097 */
2675 0x0000, /* R1098 */
2676 0x0000, /* R1099 */
2677 0x0000, /* R1100 */
2678 0x0000, /* R1101 */
2679 0x0000, /* R1102 */
2680 0x0000, /* R1103 */
2681 0x0098, /* R1104 - AIF1 DRC2 (1) */
2682 0x0845, /* R1105 - AIF1 DRC2 (2) */
2683 0x0000, /* R1106 - AIF1 DRC2 (3) */
2684 0x0000, /* R1107 - AIF1 DRC2 (4) */
2685 0x0000, /* R1108 - AIF1 DRC2 (5) */
2686 0x0000, /* R1109 */
2687 0x0000, /* R1110 */
2688 0x0000, /* R1111 */
2689 0x0000, /* R1112 */
2690 0x0000, /* R1113 */
2691 0x0000, /* R1114 */
2692 0x0000, /* R1115 */
2693 0x0000, /* R1116 */
2694 0x0000, /* R1117 */
2695 0x0000, /* R1118 */
2696 0x0000, /* R1119 */
2697 0x0000, /* R1120 */
2698 0x0000, /* R1121 */
2699 0x0000, /* R1122 */
2700 0x0000, /* R1123 */
2701 0x0000, /* R1124 */
2702 0x0000, /* R1125 */
2703 0x0000, /* R1126 */
2704 0x0000, /* R1127 */
2705 0x0000, /* R1128 */
2706 0x0000, /* R1129 */
2707 0x0000, /* R1130 */
2708 0x0000, /* R1131 */
2709 0x0000, /* R1132 */
2710 0x0000, /* R1133 */
2711 0x0000, /* R1134 */
2712 0x0000, /* R1135 */
2713 0x0000, /* R1136 */
2714 0x0000, /* R1137 */
2715 0x0000, /* R1138 */
2716 0x0000, /* R1139 */
2717 0x0000, /* R1140 */
2718 0x0000, /* R1141 */
2719 0x0000, /* R1142 */
2720 0x0000, /* R1143 */
2721 0x0000, /* R1144 */
2722 0x0000, /* R1145 */
2723 0x0000, /* R1146 */
2724 0x0000, /* R1147 */
2725 0x0000, /* R1148 */
2726 0x0000, /* R1149 */
2727 0x0000, /* R1150 */
2728 0x0000, /* R1151 */
2729 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */
2730 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */
2731 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */
2732 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */
2733 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
2734 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */
2735 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */
2736 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */
2737 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
2738 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */
2739 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */
2740 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */
2741 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
2742 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */
2743 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */
2744 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */
2745 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
2746 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */
2747 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */
2748 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
2749 0x0000, /* R1172 */
2750 0x0000, /* R1173 */
2751 0x0000, /* R1174 */
2752 0x0000, /* R1175 */
2753 0x0000, /* R1176 */
2754 0x0000, /* R1177 */
2755 0x0000, /* R1178 */
2756 0x0000, /* R1179 */
2757 0x0000, /* R1180 */
2758 0x0000, /* R1181 */
2759 0x0000, /* R1182 */
2760 0x0000, /* R1183 */
2761 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */
2762 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */
2763 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */
2764 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */
2765 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
2766 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */
2767 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */
2768 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */
2769 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
2770 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */
2771 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */
2772 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */
2773 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
2774 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */
2775 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */
2776 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */
2777 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
2778 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */
2779 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */
2780 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
2781 0x0000, /* R1204 */
2782 0x0000, /* R1205 */
2783 0x0000, /* R1206 */
2784 0x0000, /* R1207 */
2785 0x0000, /* R1208 */
2786 0x0000, /* R1209 */
2787 0x0000, /* R1210 */
2788 0x0000, /* R1211 */
2789 0x0000, /* R1212 */
2790 0x0000, /* R1213 */
2791 0x0000, /* R1214 */
2792 0x0000, /* R1215 */
2793 0x0000, /* R1216 */
2794 0x0000, /* R1217 */
2795 0x0000, /* R1218 */
2796 0x0000, /* R1219 */
2797 0x0000, /* R1220 */
2798 0x0000, /* R1221 */
2799 0x0000, /* R1222 */
2800 0x0000, /* R1223 */
2801 0x0000, /* R1224 */
2802 0x0000, /* R1225 */
2803 0x0000, /* R1226 */
2804 0x0000, /* R1227 */
2805 0x0000, /* R1228 */
2806 0x0000, /* R1229 */
2807 0x0000, /* R1230 */
2808 0x0000, /* R1231 */
2809 0x0000, /* R1232 */
2810 0x0000, /* R1233 */
2811 0x0000, /* R1234 */
2812 0x0000, /* R1235 */
2813 0x0000, /* R1236 */
2814 0x0000, /* R1237 */
2815 0x0000, /* R1238 */
2816 0x0000, /* R1239 */
2817 0x0000, /* R1240 */
2818 0x0000, /* R1241 */
2819 0x0000, /* R1242 */
2820 0x0000, /* R1243 */
2821 0x0000, /* R1244 */
2822 0x0000, /* R1245 */
2823 0x0000, /* R1246 */
2824 0x0000, /* R1247 */
2825 0x0000, /* R1248 */
2826 0x0000, /* R1249 */
2827 0x0000, /* R1250 */
2828 0x0000, /* R1251 */
2829 0x0000, /* R1252 */
2830 0x0000, /* R1253 */
2831 0x0000, /* R1254 */
2832 0x0000, /* R1255 */
2833 0x0000, /* R1256 */
2834 0x0000, /* R1257 */
2835 0x0000, /* R1258 */
2836 0x0000, /* R1259 */
2837 0x0000, /* R1260 */
2838 0x0000, /* R1261 */
2839 0x0000, /* R1262 */
2840 0x0000, /* R1263 */
2841 0x0000, /* R1264 */
2842 0x0000, /* R1265 */
2843 0x0000, /* R1266 */
2844 0x0000, /* R1267 */
2845 0x0000, /* R1268 */
2846 0x0000, /* R1269 */
2847 0x0000, /* R1270 */
2848 0x0000, /* R1271 */
2849 0x0000, /* R1272 */
2850 0x0000, /* R1273 */
2851 0x0000, /* R1274 */
2852 0x0000, /* R1275 */
2853 0x0000, /* R1276 */
2854 0x0000, /* R1277 */
2855 0x0000, /* R1278 */
2856 0x0000, /* R1279 */
2857 0x00C0, /* R1280 - AIF2 ADC Left Volume */
2858 0x00C0, /* R1281 - AIF2 ADC Right Volume */
2859 0x00C0, /* R1282 - AIF2 DAC Left Volume */
2860 0x00C0, /* R1283 - AIF2 DAC Right Volume */
2861 0x0000, /* R1284 */
2862 0x0000, /* R1285 */
2863 0x0000, /* R1286 */
2864 0x0000, /* R1287 */
2865 0x0000, /* R1288 */
2866 0x0000, /* R1289 */
2867 0x0000, /* R1290 */
2868 0x0000, /* R1291 */
2869 0x0000, /* R1292 */
2870 0x0000, /* R1293 */
2871 0x0000, /* R1294 */
2872 0x0000, /* R1295 */
2873 0x0000, /* R1296 - AIF2 ADC Filters */
2874 0x0000, /* R1297 */
2875 0x0000, /* R1298 */
2876 0x0000, /* R1299 */
2877 0x0000, /* R1300 */
2878 0x0000, /* R1301 */
2879 0x0000, /* R1302 */
2880 0x0000, /* R1303 */
2881 0x0000, /* R1304 */
2882 0x0000, /* R1305 */
2883 0x0000, /* R1306 */
2884 0x0000, /* R1307 */
2885 0x0000, /* R1308 */
2886 0x0000, /* R1309 */
2887 0x0000, /* R1310 */
2888 0x0000, /* R1311 */
2889 0x0200, /* R1312 - AIF2 DAC Filters (1) */
2890 0x0010, /* R1313 - AIF2 DAC Filters (2) */
2891 0x0000, /* R1314 */
2892 0x0000, /* R1315 */
2893 0x0000, /* R1316 */
2894 0x0000, /* R1317 */
2895 0x0000, /* R1318 */
2896 0x0000, /* R1319 */
2897 0x0000, /* R1320 */
2898 0x0000, /* R1321 */
2899 0x0000, /* R1322 */
2900 0x0000, /* R1323 */
2901 0x0000, /* R1324 */
2902 0x0000, /* R1325 */
2903 0x0000, /* R1326 */
2904 0x0000, /* R1327 */
2905 0x0000, /* R1328 */
2906 0x0000, /* R1329 */
2907 0x0000, /* R1330 */
2908 0x0000, /* R1331 */
2909 0x0000, /* R1332 */
2910 0x0000, /* R1333 */
2911 0x0000, /* R1334 */
2912 0x0000, /* R1335 */
2913 0x0000, /* R1336 */
2914 0x0000, /* R1337 */
2915 0x0000, /* R1338 */
2916 0x0000, /* R1339 */
2917 0x0000, /* R1340 */
2918 0x0000, /* R1341 */
2919 0x0000, /* R1342 */
2920 0x0000, /* R1343 */
2921 0x0098, /* R1344 - AIF2 DRC (1) */
2922 0x0845, /* R1345 - AIF2 DRC (2) */
2923 0x0000, /* R1346 - AIF2 DRC (3) */
2924 0x0000, /* R1347 - AIF2 DRC (4) */
2925 0x0000, /* R1348 - AIF2 DRC (5) */
2926 0x0000, /* R1349 */
2927 0x0000, /* R1350 */
2928 0x0000, /* R1351 */
2929 0x0000, /* R1352 */
2930 0x0000, /* R1353 */
2931 0x0000, /* R1354 */
2932 0x0000, /* R1355 */
2933 0x0000, /* R1356 */
2934 0x0000, /* R1357 */
2935 0x0000, /* R1358 */
2936 0x0000, /* R1359 */
2937 0x0000, /* R1360 */
2938 0x0000, /* R1361 */
2939 0x0000, /* R1362 */
2940 0x0000, /* R1363 */
2941 0x0000, /* R1364 */
2942 0x0000, /* R1365 */
2943 0x0000, /* R1366 */
2944 0x0000, /* R1367 */
2945 0x0000, /* R1368 */
2946 0x0000, /* R1369 */
2947 0x0000, /* R1370 */
2948 0x0000, /* R1371 */
2949 0x0000, /* R1372 */
2950 0x0000, /* R1373 */
2951 0x0000, /* R1374 */
2952 0x0000, /* R1375 */
2953 0x0000, /* R1376 */
2954 0x0000, /* R1377 */
2955 0x0000, /* R1378 */
2956 0x0000, /* R1379 */
2957 0x0000, /* R1380 */
2958 0x0000, /* R1381 */
2959 0x0000, /* R1382 */
2960 0x0000, /* R1383 */
2961 0x0000, /* R1384 */
2962 0x0000, /* R1385 */
2963 0x0000, /* R1386 */
2964 0x0000, /* R1387 */
2965 0x0000, /* R1388 */
2966 0x0000, /* R1389 */
2967 0x0000, /* R1390 */
2968 0x0000, /* R1391 */
2969 0x0000, /* R1392 */
2970 0x0000, /* R1393 */
2971 0x0000, /* R1394 */
2972 0x0000, /* R1395 */
2973 0x0000, /* R1396 */
2974 0x0000, /* R1397 */
2975 0x0000, /* R1398 */
2976 0x0000, /* R1399 */
2977 0x0000, /* R1400 */
2978 0x0000, /* R1401 */
2979 0x0000, /* R1402 */
2980 0x0000, /* R1403 */
2981 0x0000, /* R1404 */
2982 0x0000, /* R1405 */
2983 0x0000, /* R1406 */
2984 0x0000, /* R1407 */
2985 0x6318, /* R1408 - AIF2 EQ Gains (1) */
2986 0x6300, /* R1409 - AIF2 EQ Gains (2) */
2987 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */
2988 0x0400, /* R1411 - AIF2 EQ Band 1 B */
2989 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */
2990 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */
2991 0xF145, /* R1414 - AIF2 EQ Band 2 B */
2992 0x0B75, /* R1415 - AIF2 EQ Band 2 C */
2993 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */
2994 0x1C58, /* R1417 - AIF2 EQ Band 3 A */
2995 0xF373, /* R1418 - AIF2 EQ Band 3 B */
2996 0x0A54, /* R1419 - AIF2 EQ Band 3 C */
2997 0x0558, /* R1420 - AIF2 EQ Band 3 PG */
2998 0x168E, /* R1421 - AIF2 EQ Band 4 A */
2999 0xF829, /* R1422 - AIF2 EQ Band 4 B */
3000 0x07AD, /* R1423 - AIF2 EQ Band 4 C */
3001 0x1103, /* R1424 - AIF2 EQ Band 4 PG */
3002 0x0564, /* R1425 - AIF2 EQ Band 5 A */
3003 0x0559, /* R1426 - AIF2 EQ Band 5 B */
3004 0x4000, /* R1427 - AIF2 EQ Band 5 PG */
3005 0x0000, /* R1428 */
3006 0x0000, /* R1429 */
3007 0x0000, /* R1430 */
3008 0x0000, /* R1431 */
3009 0x0000, /* R1432 */
3010 0x0000, /* R1433 */
3011 0x0000, /* R1434 */
3012 0x0000, /* R1435 */
3013 0x0000, /* R1436 */
3014 0x0000, /* R1437 */
3015 0x0000, /* R1438 */
3016 0x0000, /* R1439 */
3017 0x0000, /* R1440 */
3018 0x0000, /* R1441 */
3019 0x0000, /* R1442 */
3020 0x0000, /* R1443 */
3021 0x0000, /* R1444 */
3022 0x0000, /* R1445 */
3023 0x0000, /* R1446 */
3024 0x0000, /* R1447 */
3025 0x0000, /* R1448 */
3026 0x0000, /* R1449 */
3027 0x0000, /* R1450 */
3028 0x0000, /* R1451 */
3029 0x0000, /* R1452 */
3030 0x0000, /* R1453 */
3031 0x0000, /* R1454 */
3032 0x0000, /* R1455 */
3033 0x0000, /* R1456 */
3034 0x0000, /* R1457 */
3035 0x0000, /* R1458 */
3036 0x0000, /* R1459 */
3037 0x0000, /* R1460 */
3038 0x0000, /* R1461 */
3039 0x0000, /* R1462 */
3040 0x0000, /* R1463 */
3041 0x0000, /* R1464 */
3042 0x0000, /* R1465 */
3043 0x0000, /* R1466 */
3044 0x0000, /* R1467 */
3045 0x0000, /* R1468 */
3046 0x0000, /* R1469 */
3047 0x0000, /* R1470 */
3048 0x0000, /* R1471 */
3049 0x0000, /* R1472 */
3050 0x0000, /* R1473 */
3051 0x0000, /* R1474 */
3052 0x0000, /* R1475 */
3053 0x0000, /* R1476 */
3054 0x0000, /* R1477 */
3055 0x0000, /* R1478 */
3056 0x0000, /* R1479 */
3057 0x0000, /* R1480 */
3058 0x0000, /* R1481 */
3059 0x0000, /* R1482 */
3060 0x0000, /* R1483 */
3061 0x0000, /* R1484 */
3062 0x0000, /* R1485 */
3063 0x0000, /* R1486 */
3064 0x0000, /* R1487 */
3065 0x0000, /* R1488 */
3066 0x0000, /* R1489 */
3067 0x0000, /* R1490 */
3068 0x0000, /* R1491 */
3069 0x0000, /* R1492 */
3070 0x0000, /* R1493 */
3071 0x0000, /* R1494 */
3072 0x0000, /* R1495 */
3073 0x0000, /* R1496 */
3074 0x0000, /* R1497 */
3075 0x0000, /* R1498 */
3076 0x0000, /* R1499 */
3077 0x0000, /* R1500 */
3078 0x0000, /* R1501 */
3079 0x0000, /* R1502 */
3080 0x0000, /* R1503 */
3081 0x0000, /* R1504 */
3082 0x0000, /* R1505 */
3083 0x0000, /* R1506 */
3084 0x0000, /* R1507 */
3085 0x0000, /* R1508 */
3086 0x0000, /* R1509 */
3087 0x0000, /* R1510 */
3088 0x0000, /* R1511 */
3089 0x0000, /* R1512 */
3090 0x0000, /* R1513 */
3091 0x0000, /* R1514 */
3092 0x0000, /* R1515 */
3093 0x0000, /* R1516 */
3094 0x0000, /* R1517 */
3095 0x0000, /* R1518 */
3096 0x0000, /* R1519 */
3097 0x0000, /* R1520 */
3098 0x0000, /* R1521 */
3099 0x0000, /* R1522 */
3100 0x0000, /* R1523 */
3101 0x0000, /* R1524 */
3102 0x0000, /* R1525 */
3103 0x0000, /* R1526 */
3104 0x0000, /* R1527 */
3105 0x0000, /* R1528 */
3106 0x0000, /* R1529 */
3107 0x0000, /* R1530 */
3108 0x0000, /* R1531 */
3109 0x0000, /* R1532 */
3110 0x0000, /* R1533 */
3111 0x0000, /* R1534 */
3112 0x0000, /* R1535 */
3113 0x0000, /* R1536 - DAC1 Mixer Volumes */
3114 0x0000, /* R1537 - DAC1 Left Mixer Routing */
3115 0x0000, /* R1538 - DAC1 Right Mixer Routing */
3116 0x0000, /* R1539 - DAC2 Mixer Volumes */
3117 0x0000, /* R1540 - DAC2 Left Mixer Routing */
3118 0x0000, /* R1541 - DAC2 Right Mixer Routing */
3119 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */
3120 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */
3121 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */
3122 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */
3123 0x0000, /* R1546 */
3124 0x0000, /* R1547 */
3125 0x0000, /* R1548 */
3126 0x0000, /* R1549 */
3127 0x0000, /* R1550 */
3128 0x0000, /* R1551 */
3129 0x02C0, /* R1552 - DAC1 Left Volume */
3130 0x02C0, /* R1553 - DAC1 Right Volume */
3131 0x02C0, /* R1554 - DAC2 Left Volume */
3132 0x02C0, /* R1555 - DAC2 Right Volume */
3133 0x0000, /* R1556 - DAC Softmute */
3134 0x0000, /* R1557 */
3135 0x0000, /* R1558 */
3136 0x0000, /* R1559 */
3137 0x0000, /* R1560 */
3138 0x0000, /* R1561 */
3139 0x0000, /* R1562 */
3140 0x0000, /* R1563 */
3141 0x0000, /* R1564 */
3142 0x0000, /* R1565 */
3143 0x0000, /* R1566 */
3144 0x0000, /* R1567 */
3145 0x0002, /* R1568 - Oversampling */
3146 0x0000, /* R1569 - Sidetone */
3147};
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 522249d5c2b4..83014a7c2e14 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -18,15 +18,17 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/jack.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
25#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
26#include <sound/soc.h> 28#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 29#include <sound/initval.h>
29#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <trace/events/asoc.h>
30 32
31#include <linux/mfd/wm8994/core.h> 33#include <linux/mfd/wm8994/core.h>
32#include <linux/mfd/wm8994/registers.h> 34#include <linux/mfd/wm8994/registers.h>
@@ -36,15 +38,6 @@
36#include "wm8994.h" 38#include "wm8994.h"
37#include "wm_hubs.h" 39#include "wm_hubs.h"
38 40
39static struct snd_soc_codec *wm8994_codec;
40struct snd_soc_codec_device soc_codec_dev_wm8994;
41
42struct fll_config {
43 int src;
44 int in;
45 int out;
46};
47
48#define WM8994_NUM_DRC 3 41#define WM8994_NUM_DRC 3
49#define WM8994_NUM_EQ 3 42#define WM8994_NUM_EQ 3
50 43
@@ -60,1624 +53,11 @@ static int wm8994_retune_mobile_base[] = {
60 WM8994_AIF2_EQ_GAINS_1, 53 WM8994_AIF2_EQ_GAINS_1,
61}; 54};
62 55
63#define WM8994_REG_CACHE_SIZE 0x621 56static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg)
64
65struct wm8994_micdet {
66 struct snd_soc_jack *jack;
67 int det;
68 int shrt;
69};
70
71/* codec private data */
72struct wm8994_priv {
73 struct wm_hubs_data hubs;
74 struct snd_soc_codec codec;
75 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
76 int sysclk[2];
77 int sysclk_rate[2];
78 int mclk[2];
79 int aifclk[2];
80 struct fll_config fll[2], fll_suspend[2];
81
82 int dac_rates[2];
83 int lrclk_shared[2];
84
85 /* Platform dependant DRC configuration */
86 const char **drc_texts;
87 int drc_cfg[WM8994_NUM_DRC];
88 struct soc_enum drc_enum;
89
90 /* Platform dependant ReTune mobile configuration */
91 int num_retune_mobile_texts;
92 const char **retune_mobile_texts;
93 int retune_mobile_cfg[WM8994_NUM_EQ];
94 struct soc_enum retune_mobile_enum;
95
96 struct wm8994_micdet micdet[2];
97
98 int revision;
99 struct wm8994_pdata *pdata;
100};
101
102static struct {
103 unsigned short readable; /* Mask of readable bits */
104 unsigned short writable; /* Mask of writable bits */
105 unsigned short vol; /* Mask of volatile bits */
106} access_masks[] = {
107 { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
108 { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
109 { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
110 { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
111 { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
112 { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
113 { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
114 { 0x0000, 0x0000, 0x0000 }, /* R7 */
115 { 0x0000, 0x0000, 0x0000 }, /* R8 */
116 { 0x0000, 0x0000, 0x0000 }, /* R9 */
117 { 0x0000, 0x0000, 0x0000 }, /* R10 */
118 { 0x0000, 0x0000, 0x0000 }, /* R11 */
119 { 0x0000, 0x0000, 0x0000 }, /* R12 */
120 { 0x0000, 0x0000, 0x0000 }, /* R13 */
121 { 0x0000, 0x0000, 0x0000 }, /* R14 */
122 { 0x0000, 0x0000, 0x0000 }, /* R15 */
123 { 0x0000, 0x0000, 0x0000 }, /* R16 */
124 { 0x0000, 0x0000, 0x0000 }, /* R17 */
125 { 0x0000, 0x0000, 0x0000 }, /* R18 */
126 { 0x0000, 0x0000, 0x0000 }, /* R19 */
127 { 0x0000, 0x0000, 0x0000 }, /* R20 */
128 { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
129 { 0x0000, 0x0000, 0x0000 }, /* R22 */
130 { 0x0000, 0x0000, 0x0000 }, /* R23 */
131 { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
132 { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
133 { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
134 { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
135 { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
136 { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
137 { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
138 { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
139 { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
140 { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
141 { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
142 { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
143 { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
144 { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
145 { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
146 { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
147 { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
148 { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
149 { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
150 { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
151 { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
152 { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
153 { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
154 { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
155 { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
156 { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
157 { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
158 { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
159 { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
160 { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
161 { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
162 { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
163 { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
164 { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
165 { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
166 { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
167 { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
168 { 0x0000, 0x0000, 0x0000 }, /* R61 */
169 { 0x0000, 0x0000, 0x0000 }, /* R62 */
170 { 0x0000, 0x0000, 0x0000 }, /* R63 */
171 { 0x0000, 0x0000, 0x0000 }, /* R64 */
172 { 0x0000, 0x0000, 0x0000 }, /* R65 */
173 { 0x0000, 0x0000, 0x0000 }, /* R66 */
174 { 0x0000, 0x0000, 0x0000 }, /* R67 */
175 { 0x0000, 0x0000, 0x0000 }, /* R68 */
176 { 0x0000, 0x0000, 0x0000 }, /* R69 */
177 { 0x0000, 0x0000, 0x0000 }, /* R70 */
178 { 0x0000, 0x0000, 0x0000 }, /* R71 */
179 { 0x0000, 0x0000, 0x0000 }, /* R72 */
180 { 0x0000, 0x0000, 0x0000 }, /* R73 */
181 { 0x0000, 0x0000, 0x0000 }, /* R74 */
182 { 0x0000, 0x0000, 0x0000 }, /* R75 */
183 { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
184 { 0x0000, 0x0000, 0x0000 }, /* R77 */
185 { 0x0000, 0x0000, 0x0000 }, /* R78 */
186 { 0x0000, 0x0000, 0x0000 }, /* R79 */
187 { 0x0000, 0x0000, 0x0000 }, /* R80 */
188 { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
189 { 0x0000, 0x0000, 0x0000 }, /* R82 */
190 { 0x0000, 0x0000, 0x0000 }, /* R83 */
191 { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
192 { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
193 { 0x0000, 0x0000, 0x0000 }, /* R86 */
194 { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
195 { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
196 { 0x0000, 0x0000, 0x0000 }, /* R89 */
197 { 0x0000, 0x0000, 0x0000 }, /* R90 */
198 { 0x0000, 0x0000, 0x0000 }, /* R91 */
199 { 0x0000, 0x0000, 0x0000 }, /* R92 */
200 { 0x0000, 0x0000, 0x0000 }, /* R93 */
201 { 0x0000, 0x0000, 0x0000 }, /* R94 */
202 { 0x0000, 0x0000, 0x0000 }, /* R95 */
203 { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
204 { 0x0000, 0x0000, 0x0000 }, /* R97 */
205 { 0x0000, 0x0000, 0x0000 }, /* R98 */
206 { 0x0000, 0x0000, 0x0000 }, /* R99 */
207 { 0x0000, 0x0000, 0x0000 }, /* R100 */
208 { 0x0000, 0x0000, 0x0000 }, /* R101 */
209 { 0x0000, 0x0000, 0x0000 }, /* R102 */
210 { 0x0000, 0x0000, 0x0000 }, /* R103 */
211 { 0x0000, 0x0000, 0x0000 }, /* R104 */
212 { 0x0000, 0x0000, 0x0000 }, /* R105 */
213 { 0x0000, 0x0000, 0x0000 }, /* R106 */
214 { 0x0000, 0x0000, 0x0000 }, /* R107 */
215 { 0x0000, 0x0000, 0x0000 }, /* R108 */
216 { 0x0000, 0x0000, 0x0000 }, /* R109 */
217 { 0x0000, 0x0000, 0x0000 }, /* R110 */
218 { 0x0000, 0x0000, 0x0000 }, /* R111 */
219 { 0x0000, 0x0000, 0x0000 }, /* R112 */
220 { 0x0000, 0x0000, 0x0000 }, /* R113 */
221 { 0x0000, 0x0000, 0x0000 }, /* R114 */
222 { 0x0000, 0x0000, 0x0000 }, /* R115 */
223 { 0x0000, 0x0000, 0x0000 }, /* R116 */
224 { 0x0000, 0x0000, 0x0000 }, /* R117 */
225 { 0x0000, 0x0000, 0x0000 }, /* R118 */
226 { 0x0000, 0x0000, 0x0000 }, /* R119 */
227 { 0x0000, 0x0000, 0x0000 }, /* R120 */
228 { 0x0000, 0x0000, 0x0000 }, /* R121 */
229 { 0x0000, 0x0000, 0x0000 }, /* R122 */
230 { 0x0000, 0x0000, 0x0000 }, /* R123 */
231 { 0x0000, 0x0000, 0x0000 }, /* R124 */
232 { 0x0000, 0x0000, 0x0000 }, /* R125 */
233 { 0x0000, 0x0000, 0x0000 }, /* R126 */
234 { 0x0000, 0x0000, 0x0000 }, /* R127 */
235 { 0x0000, 0x0000, 0x0000 }, /* R128 */
236 { 0x0000, 0x0000, 0x0000 }, /* R129 */
237 { 0x0000, 0x0000, 0x0000 }, /* R130 */
238 { 0x0000, 0x0000, 0x0000 }, /* R131 */
239 { 0x0000, 0x0000, 0x0000 }, /* R132 */
240 { 0x0000, 0x0000, 0x0000 }, /* R133 */
241 { 0x0000, 0x0000, 0x0000 }, /* R134 */
242 { 0x0000, 0x0000, 0x0000 }, /* R135 */
243 { 0x0000, 0x0000, 0x0000 }, /* R136 */
244 { 0x0000, 0x0000, 0x0000 }, /* R137 */
245 { 0x0000, 0x0000, 0x0000 }, /* R138 */
246 { 0x0000, 0x0000, 0x0000 }, /* R139 */
247 { 0x0000, 0x0000, 0x0000 }, /* R140 */
248 { 0x0000, 0x0000, 0x0000 }, /* R141 */
249 { 0x0000, 0x0000, 0x0000 }, /* R142 */
250 { 0x0000, 0x0000, 0x0000 }, /* R143 */
251 { 0x0000, 0x0000, 0x0000 }, /* R144 */
252 { 0x0000, 0x0000, 0x0000 }, /* R145 */
253 { 0x0000, 0x0000, 0x0000 }, /* R146 */
254 { 0x0000, 0x0000, 0x0000 }, /* R147 */
255 { 0x0000, 0x0000, 0x0000 }, /* R148 */
256 { 0x0000, 0x0000, 0x0000 }, /* R149 */
257 { 0x0000, 0x0000, 0x0000 }, /* R150 */
258 { 0x0000, 0x0000, 0x0000 }, /* R151 */
259 { 0x0000, 0x0000, 0x0000 }, /* R152 */
260 { 0x0000, 0x0000, 0x0000 }, /* R153 */
261 { 0x0000, 0x0000, 0x0000 }, /* R154 */
262 { 0x0000, 0x0000, 0x0000 }, /* R155 */
263 { 0x0000, 0x0000, 0x0000 }, /* R156 */
264 { 0x0000, 0x0000, 0x0000 }, /* R157 */
265 { 0x0000, 0x0000, 0x0000 }, /* R158 */
266 { 0x0000, 0x0000, 0x0000 }, /* R159 */
267 { 0x0000, 0x0000, 0x0000 }, /* R160 */
268 { 0x0000, 0x0000, 0x0000 }, /* R161 */
269 { 0x0000, 0x0000, 0x0000 }, /* R162 */
270 { 0x0000, 0x0000, 0x0000 }, /* R163 */
271 { 0x0000, 0x0000, 0x0000 }, /* R164 */
272 { 0x0000, 0x0000, 0x0000 }, /* R165 */
273 { 0x0000, 0x0000, 0x0000 }, /* R166 */
274 { 0x0000, 0x0000, 0x0000 }, /* R167 */
275 { 0x0000, 0x0000, 0x0000 }, /* R168 */
276 { 0x0000, 0x0000, 0x0000 }, /* R169 */
277 { 0x0000, 0x0000, 0x0000 }, /* R170 */
278 { 0x0000, 0x0000, 0x0000 }, /* R171 */
279 { 0x0000, 0x0000, 0x0000 }, /* R172 */
280 { 0x0000, 0x0000, 0x0000 }, /* R173 */
281 { 0x0000, 0x0000, 0x0000 }, /* R174 */
282 { 0x0000, 0x0000, 0x0000 }, /* R175 */
283 { 0x0000, 0x0000, 0x0000 }, /* R176 */
284 { 0x0000, 0x0000, 0x0000 }, /* R177 */
285 { 0x0000, 0x0000, 0x0000 }, /* R178 */
286 { 0x0000, 0x0000, 0x0000 }, /* R179 */
287 { 0x0000, 0x0000, 0x0000 }, /* R180 */
288 { 0x0000, 0x0000, 0x0000 }, /* R181 */
289 { 0x0000, 0x0000, 0x0000 }, /* R182 */
290 { 0x0000, 0x0000, 0x0000 }, /* R183 */
291 { 0x0000, 0x0000, 0x0000 }, /* R184 */
292 { 0x0000, 0x0000, 0x0000 }, /* R185 */
293 { 0x0000, 0x0000, 0x0000 }, /* R186 */
294 { 0x0000, 0x0000, 0x0000 }, /* R187 */
295 { 0x0000, 0x0000, 0x0000 }, /* R188 */
296 { 0x0000, 0x0000, 0x0000 }, /* R189 */
297 { 0x0000, 0x0000, 0x0000 }, /* R190 */
298 { 0x0000, 0x0000, 0x0000 }, /* R191 */
299 { 0x0000, 0x0000, 0x0000 }, /* R192 */
300 { 0x0000, 0x0000, 0x0000 }, /* R193 */
301 { 0x0000, 0x0000, 0x0000 }, /* R194 */
302 { 0x0000, 0x0000, 0x0000 }, /* R195 */
303 { 0x0000, 0x0000, 0x0000 }, /* R196 */
304 { 0x0000, 0x0000, 0x0000 }, /* R197 */
305 { 0x0000, 0x0000, 0x0000 }, /* R198 */
306 { 0x0000, 0x0000, 0x0000 }, /* R199 */
307 { 0x0000, 0x0000, 0x0000 }, /* R200 */
308 { 0x0000, 0x0000, 0x0000 }, /* R201 */
309 { 0x0000, 0x0000, 0x0000 }, /* R202 */
310 { 0x0000, 0x0000, 0x0000 }, /* R203 */
311 { 0x0000, 0x0000, 0x0000 }, /* R204 */
312 { 0x0000, 0x0000, 0x0000 }, /* R205 */
313 { 0x0000, 0x0000, 0x0000 }, /* R206 */
314 { 0x0000, 0x0000, 0x0000 }, /* R207 */
315 { 0x0000, 0x0000, 0x0000 }, /* R208 */
316 { 0x0000, 0x0000, 0x0000 }, /* R209 */
317 { 0x0000, 0x0000, 0x0000 }, /* R210 */
318 { 0x0000, 0x0000, 0x0000 }, /* R211 */
319 { 0x0000, 0x0000, 0x0000 }, /* R212 */
320 { 0x0000, 0x0000, 0x0000 }, /* R213 */
321 { 0x0000, 0x0000, 0x0000 }, /* R214 */
322 { 0x0000, 0x0000, 0x0000 }, /* R215 */
323 { 0x0000, 0x0000, 0x0000 }, /* R216 */
324 { 0x0000, 0x0000, 0x0000 }, /* R217 */
325 { 0x0000, 0x0000, 0x0000 }, /* R218 */
326 { 0x0000, 0x0000, 0x0000 }, /* R219 */
327 { 0x0000, 0x0000, 0x0000 }, /* R220 */
328 { 0x0000, 0x0000, 0x0000 }, /* R221 */
329 { 0x0000, 0x0000, 0x0000 }, /* R222 */
330 { 0x0000, 0x0000, 0x0000 }, /* R223 */
331 { 0x0000, 0x0000, 0x0000 }, /* R224 */
332 { 0x0000, 0x0000, 0x0000 }, /* R225 */
333 { 0x0000, 0x0000, 0x0000 }, /* R226 */
334 { 0x0000, 0x0000, 0x0000 }, /* R227 */
335 { 0x0000, 0x0000, 0x0000 }, /* R228 */
336 { 0x0000, 0x0000, 0x0000 }, /* R229 */
337 { 0x0000, 0x0000, 0x0000 }, /* R230 */
338 { 0x0000, 0x0000, 0x0000 }, /* R231 */
339 { 0x0000, 0x0000, 0x0000 }, /* R232 */
340 { 0x0000, 0x0000, 0x0000 }, /* R233 */
341 { 0x0000, 0x0000, 0x0000 }, /* R234 */
342 { 0x0000, 0x0000, 0x0000 }, /* R235 */
343 { 0x0000, 0x0000, 0x0000 }, /* R236 */
344 { 0x0000, 0x0000, 0x0000 }, /* R237 */
345 { 0x0000, 0x0000, 0x0000 }, /* R238 */
346 { 0x0000, 0x0000, 0x0000 }, /* R239 */
347 { 0x0000, 0x0000, 0x0000 }, /* R240 */
348 { 0x0000, 0x0000, 0x0000 }, /* R241 */
349 { 0x0000, 0x0000, 0x0000 }, /* R242 */
350 { 0x0000, 0x0000, 0x0000 }, /* R243 */
351 { 0x0000, 0x0000, 0x0000 }, /* R244 */
352 { 0x0000, 0x0000, 0x0000 }, /* R245 */
353 { 0x0000, 0x0000, 0x0000 }, /* R246 */
354 { 0x0000, 0x0000, 0x0000 }, /* R247 */
355 { 0x0000, 0x0000, 0x0000 }, /* R248 */
356 { 0x0000, 0x0000, 0x0000 }, /* R249 */
357 { 0x0000, 0x0000, 0x0000 }, /* R250 */
358 { 0x0000, 0x0000, 0x0000 }, /* R251 */
359 { 0x0000, 0x0000, 0x0000 }, /* R252 */
360 { 0x0000, 0x0000, 0x0000 }, /* R253 */
361 { 0x0000, 0x0000, 0x0000 }, /* R254 */
362 { 0x0000, 0x0000, 0x0000 }, /* R255 */
363 { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
364 { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
365 { 0x0000, 0x0000, 0x0000 }, /* R258 */
366 { 0x0000, 0x0000, 0x0000 }, /* R259 */
367 { 0x0000, 0x0000, 0x0000 }, /* R260 */
368 { 0x0000, 0x0000, 0x0000 }, /* R261 */
369 { 0x0000, 0x0000, 0x0000 }, /* R262 */
370 { 0x0000, 0x0000, 0x0000 }, /* R263 */
371 { 0x0000, 0x0000, 0x0000 }, /* R264 */
372 { 0x0000, 0x0000, 0x0000 }, /* R265 */
373 { 0x0000, 0x0000, 0x0000 }, /* R266 */
374 { 0x0000, 0x0000, 0x0000 }, /* R267 */
375 { 0x0000, 0x0000, 0x0000 }, /* R268 */
376 { 0x0000, 0x0000, 0x0000 }, /* R269 */
377 { 0x0000, 0x0000, 0x0000 }, /* R270 */
378 { 0x0000, 0x0000, 0x0000 }, /* R271 */
379 { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
380 { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
381 { 0x0000, 0x0000, 0x0000 }, /* R274 */
382 { 0x0000, 0x0000, 0x0000 }, /* R275 */
383 { 0x0000, 0x0000, 0x0000 }, /* R276 */
384 { 0x0000, 0x0000, 0x0000 }, /* R277 */
385 { 0x0000, 0x0000, 0x0000 }, /* R278 */
386 { 0x0000, 0x0000, 0x0000 }, /* R279 */
387 { 0x0000, 0x0000, 0x0000 }, /* R280 */
388 { 0x0000, 0x0000, 0x0000 }, /* R281 */
389 { 0x0000, 0x0000, 0x0000 }, /* R282 */
390 { 0x0000, 0x0000, 0x0000 }, /* R283 */
391 { 0x0000, 0x0000, 0x0000 }, /* R284 */
392 { 0x0000, 0x0000, 0x0000 }, /* R285 */
393 { 0x0000, 0x0000, 0x0000 }, /* R286 */
394 { 0x0000, 0x0000, 0x0000 }, /* R287 */
395 { 0x0000, 0x0000, 0x0000 }, /* R288 */
396 { 0x0000, 0x0000, 0x0000 }, /* R289 */
397 { 0x0000, 0x0000, 0x0000 }, /* R290 */
398 { 0x0000, 0x0000, 0x0000 }, /* R291 */
399 { 0x0000, 0x0000, 0x0000 }, /* R292 */
400 { 0x0000, 0x0000, 0x0000 }, /* R293 */
401 { 0x0000, 0x0000, 0x0000 }, /* R294 */
402 { 0x0000, 0x0000, 0x0000 }, /* R295 */
403 { 0x0000, 0x0000, 0x0000 }, /* R296 */
404 { 0x0000, 0x0000, 0x0000 }, /* R297 */
405 { 0x0000, 0x0000, 0x0000 }, /* R298 */
406 { 0x0000, 0x0000, 0x0000 }, /* R299 */
407 { 0x0000, 0x0000, 0x0000 }, /* R300 */
408 { 0x0000, 0x0000, 0x0000 }, /* R301 */
409 { 0x0000, 0x0000, 0x0000 }, /* R302 */
410 { 0x0000, 0x0000, 0x0000 }, /* R303 */
411 { 0x0000, 0x0000, 0x0000 }, /* R304 */
412 { 0x0000, 0x0000, 0x0000 }, /* R305 */
413 { 0x0000, 0x0000, 0x0000 }, /* R306 */
414 { 0x0000, 0x0000, 0x0000 }, /* R307 */
415 { 0x0000, 0x0000, 0x0000 }, /* R308 */
416 { 0x0000, 0x0000, 0x0000 }, /* R309 */
417 { 0x0000, 0x0000, 0x0000 }, /* R310 */
418 { 0x0000, 0x0000, 0x0000 }, /* R311 */
419 { 0x0000, 0x0000, 0x0000 }, /* R312 */
420 { 0x0000, 0x0000, 0x0000 }, /* R313 */
421 { 0x0000, 0x0000, 0x0000 }, /* R314 */
422 { 0x0000, 0x0000, 0x0000 }, /* R315 */
423 { 0x0000, 0x0000, 0x0000 }, /* R316 */
424 { 0x0000, 0x0000, 0x0000 }, /* R317 */
425 { 0x0000, 0x0000, 0x0000 }, /* R318 */
426 { 0x0000, 0x0000, 0x0000 }, /* R319 */
427 { 0x0000, 0x0000, 0x0000 }, /* R320 */
428 { 0x0000, 0x0000, 0x0000 }, /* R321 */
429 { 0x0000, 0x0000, 0x0000 }, /* R322 */
430 { 0x0000, 0x0000, 0x0000 }, /* R323 */
431 { 0x0000, 0x0000, 0x0000 }, /* R324 */
432 { 0x0000, 0x0000, 0x0000 }, /* R325 */
433 { 0x0000, 0x0000, 0x0000 }, /* R326 */
434 { 0x0000, 0x0000, 0x0000 }, /* R327 */
435 { 0x0000, 0x0000, 0x0000 }, /* R328 */
436 { 0x0000, 0x0000, 0x0000 }, /* R329 */
437 { 0x0000, 0x0000, 0x0000 }, /* R330 */
438 { 0x0000, 0x0000, 0x0000 }, /* R331 */
439 { 0x0000, 0x0000, 0x0000 }, /* R332 */
440 { 0x0000, 0x0000, 0x0000 }, /* R333 */
441 { 0x0000, 0x0000, 0x0000 }, /* R334 */
442 { 0x0000, 0x0000, 0x0000 }, /* R335 */
443 { 0x0000, 0x0000, 0x0000 }, /* R336 */
444 { 0x0000, 0x0000, 0x0000 }, /* R337 */
445 { 0x0000, 0x0000, 0x0000 }, /* R338 */
446 { 0x0000, 0x0000, 0x0000 }, /* R339 */
447 { 0x0000, 0x0000, 0x0000 }, /* R340 */
448 { 0x0000, 0x0000, 0x0000 }, /* R341 */
449 { 0x0000, 0x0000, 0x0000 }, /* R342 */
450 { 0x0000, 0x0000, 0x0000 }, /* R343 */
451 { 0x0000, 0x0000, 0x0000 }, /* R344 */
452 { 0x0000, 0x0000, 0x0000 }, /* R345 */
453 { 0x0000, 0x0000, 0x0000 }, /* R346 */
454 { 0x0000, 0x0000, 0x0000 }, /* R347 */
455 { 0x0000, 0x0000, 0x0000 }, /* R348 */
456 { 0x0000, 0x0000, 0x0000 }, /* R349 */
457 { 0x0000, 0x0000, 0x0000 }, /* R350 */
458 { 0x0000, 0x0000, 0x0000 }, /* R351 */
459 { 0x0000, 0x0000, 0x0000 }, /* R352 */
460 { 0x0000, 0x0000, 0x0000 }, /* R353 */
461 { 0x0000, 0x0000, 0x0000 }, /* R354 */
462 { 0x0000, 0x0000, 0x0000 }, /* R355 */
463 { 0x0000, 0x0000, 0x0000 }, /* R356 */
464 { 0x0000, 0x0000, 0x0000 }, /* R357 */
465 { 0x0000, 0x0000, 0x0000 }, /* R358 */
466 { 0x0000, 0x0000, 0x0000 }, /* R359 */
467 { 0x0000, 0x0000, 0x0000 }, /* R360 */
468 { 0x0000, 0x0000, 0x0000 }, /* R361 */
469 { 0x0000, 0x0000, 0x0000 }, /* R362 */
470 { 0x0000, 0x0000, 0x0000 }, /* R363 */
471 { 0x0000, 0x0000, 0x0000 }, /* R364 */
472 { 0x0000, 0x0000, 0x0000 }, /* R365 */
473 { 0x0000, 0x0000, 0x0000 }, /* R366 */
474 { 0x0000, 0x0000, 0x0000 }, /* R367 */
475 { 0x0000, 0x0000, 0x0000 }, /* R368 */
476 { 0x0000, 0x0000, 0x0000 }, /* R369 */
477 { 0x0000, 0x0000, 0x0000 }, /* R370 */
478 { 0x0000, 0x0000, 0x0000 }, /* R371 */
479 { 0x0000, 0x0000, 0x0000 }, /* R372 */
480 { 0x0000, 0x0000, 0x0000 }, /* R373 */
481 { 0x0000, 0x0000, 0x0000 }, /* R374 */
482 { 0x0000, 0x0000, 0x0000 }, /* R375 */
483 { 0x0000, 0x0000, 0x0000 }, /* R376 */
484 { 0x0000, 0x0000, 0x0000 }, /* R377 */
485 { 0x0000, 0x0000, 0x0000 }, /* R378 */
486 { 0x0000, 0x0000, 0x0000 }, /* R379 */
487 { 0x0000, 0x0000, 0x0000 }, /* R380 */
488 { 0x0000, 0x0000, 0x0000 }, /* R381 */
489 { 0x0000, 0x0000, 0x0000 }, /* R382 */
490 { 0x0000, 0x0000, 0x0000 }, /* R383 */
491 { 0x0000, 0x0000, 0x0000 }, /* R384 */
492 { 0x0000, 0x0000, 0x0000 }, /* R385 */
493 { 0x0000, 0x0000, 0x0000 }, /* R386 */
494 { 0x0000, 0x0000, 0x0000 }, /* R387 */
495 { 0x0000, 0x0000, 0x0000 }, /* R388 */
496 { 0x0000, 0x0000, 0x0000 }, /* R389 */
497 { 0x0000, 0x0000, 0x0000 }, /* R390 */
498 { 0x0000, 0x0000, 0x0000 }, /* R391 */
499 { 0x0000, 0x0000, 0x0000 }, /* R392 */
500 { 0x0000, 0x0000, 0x0000 }, /* R393 */
501 { 0x0000, 0x0000, 0x0000 }, /* R394 */
502 { 0x0000, 0x0000, 0x0000 }, /* R395 */
503 { 0x0000, 0x0000, 0x0000 }, /* R396 */
504 { 0x0000, 0x0000, 0x0000 }, /* R397 */
505 { 0x0000, 0x0000, 0x0000 }, /* R398 */
506 { 0x0000, 0x0000, 0x0000 }, /* R399 */
507 { 0x0000, 0x0000, 0x0000 }, /* R400 */
508 { 0x0000, 0x0000, 0x0000 }, /* R401 */
509 { 0x0000, 0x0000, 0x0000 }, /* R402 */
510 { 0x0000, 0x0000, 0x0000 }, /* R403 */
511 { 0x0000, 0x0000, 0x0000 }, /* R404 */
512 { 0x0000, 0x0000, 0x0000 }, /* R405 */
513 { 0x0000, 0x0000, 0x0000 }, /* R406 */
514 { 0x0000, 0x0000, 0x0000 }, /* R407 */
515 { 0x0000, 0x0000, 0x0000 }, /* R408 */
516 { 0x0000, 0x0000, 0x0000 }, /* R409 */
517 { 0x0000, 0x0000, 0x0000 }, /* R410 */
518 { 0x0000, 0x0000, 0x0000 }, /* R411 */
519 { 0x0000, 0x0000, 0x0000 }, /* R412 */
520 { 0x0000, 0x0000, 0x0000 }, /* R413 */
521 { 0x0000, 0x0000, 0x0000 }, /* R414 */
522 { 0x0000, 0x0000, 0x0000 }, /* R415 */
523 { 0x0000, 0x0000, 0x0000 }, /* R416 */
524 { 0x0000, 0x0000, 0x0000 }, /* R417 */
525 { 0x0000, 0x0000, 0x0000 }, /* R418 */
526 { 0x0000, 0x0000, 0x0000 }, /* R419 */
527 { 0x0000, 0x0000, 0x0000 }, /* R420 */
528 { 0x0000, 0x0000, 0x0000 }, /* R421 */
529 { 0x0000, 0x0000, 0x0000 }, /* R422 */
530 { 0x0000, 0x0000, 0x0000 }, /* R423 */
531 { 0x0000, 0x0000, 0x0000 }, /* R424 */
532 { 0x0000, 0x0000, 0x0000 }, /* R425 */
533 { 0x0000, 0x0000, 0x0000 }, /* R426 */
534 { 0x0000, 0x0000, 0x0000 }, /* R427 */
535 { 0x0000, 0x0000, 0x0000 }, /* R428 */
536 { 0x0000, 0x0000, 0x0000 }, /* R429 */
537 { 0x0000, 0x0000, 0x0000 }, /* R430 */
538 { 0x0000, 0x0000, 0x0000 }, /* R431 */
539 { 0x0000, 0x0000, 0x0000 }, /* R432 */
540 { 0x0000, 0x0000, 0x0000 }, /* R433 */
541 { 0x0000, 0x0000, 0x0000 }, /* R434 */
542 { 0x0000, 0x0000, 0x0000 }, /* R435 */
543 { 0x0000, 0x0000, 0x0000 }, /* R436 */
544 { 0x0000, 0x0000, 0x0000 }, /* R437 */
545 { 0x0000, 0x0000, 0x0000 }, /* R438 */
546 { 0x0000, 0x0000, 0x0000 }, /* R439 */
547 { 0x0000, 0x0000, 0x0000 }, /* R440 */
548 { 0x0000, 0x0000, 0x0000 }, /* R441 */
549 { 0x0000, 0x0000, 0x0000 }, /* R442 */
550 { 0x0000, 0x0000, 0x0000 }, /* R443 */
551 { 0x0000, 0x0000, 0x0000 }, /* R444 */
552 { 0x0000, 0x0000, 0x0000 }, /* R445 */
553 { 0x0000, 0x0000, 0x0000 }, /* R446 */
554 { 0x0000, 0x0000, 0x0000 }, /* R447 */
555 { 0x0000, 0x0000, 0x0000 }, /* R448 */
556 { 0x0000, 0x0000, 0x0000 }, /* R449 */
557 { 0x0000, 0x0000, 0x0000 }, /* R450 */
558 { 0x0000, 0x0000, 0x0000 }, /* R451 */
559 { 0x0000, 0x0000, 0x0000 }, /* R452 */
560 { 0x0000, 0x0000, 0x0000 }, /* R453 */
561 { 0x0000, 0x0000, 0x0000 }, /* R454 */
562 { 0x0000, 0x0000, 0x0000 }, /* R455 */
563 { 0x0000, 0x0000, 0x0000 }, /* R456 */
564 { 0x0000, 0x0000, 0x0000 }, /* R457 */
565 { 0x0000, 0x0000, 0x0000 }, /* R458 */
566 { 0x0000, 0x0000, 0x0000 }, /* R459 */
567 { 0x0000, 0x0000, 0x0000 }, /* R460 */
568 { 0x0000, 0x0000, 0x0000 }, /* R461 */
569 { 0x0000, 0x0000, 0x0000 }, /* R462 */
570 { 0x0000, 0x0000, 0x0000 }, /* R463 */
571 { 0x0000, 0x0000, 0x0000 }, /* R464 */
572 { 0x0000, 0x0000, 0x0000 }, /* R465 */
573 { 0x0000, 0x0000, 0x0000 }, /* R466 */
574 { 0x0000, 0x0000, 0x0000 }, /* R467 */
575 { 0x0000, 0x0000, 0x0000 }, /* R468 */
576 { 0x0000, 0x0000, 0x0000 }, /* R469 */
577 { 0x0000, 0x0000, 0x0000 }, /* R470 */
578 { 0x0000, 0x0000, 0x0000 }, /* R471 */
579 { 0x0000, 0x0000, 0x0000 }, /* R472 */
580 { 0x0000, 0x0000, 0x0000 }, /* R473 */
581 { 0x0000, 0x0000, 0x0000 }, /* R474 */
582 { 0x0000, 0x0000, 0x0000 }, /* R475 */
583 { 0x0000, 0x0000, 0x0000 }, /* R476 */
584 { 0x0000, 0x0000, 0x0000 }, /* R477 */
585 { 0x0000, 0x0000, 0x0000 }, /* R478 */
586 { 0x0000, 0x0000, 0x0000 }, /* R479 */
587 { 0x0000, 0x0000, 0x0000 }, /* R480 */
588 { 0x0000, 0x0000, 0x0000 }, /* R481 */
589 { 0x0000, 0x0000, 0x0000 }, /* R482 */
590 { 0x0000, 0x0000, 0x0000 }, /* R483 */
591 { 0x0000, 0x0000, 0x0000 }, /* R484 */
592 { 0x0000, 0x0000, 0x0000 }, /* R485 */
593 { 0x0000, 0x0000, 0x0000 }, /* R486 */
594 { 0x0000, 0x0000, 0x0000 }, /* R487 */
595 { 0x0000, 0x0000, 0x0000 }, /* R488 */
596 { 0x0000, 0x0000, 0x0000 }, /* R489 */
597 { 0x0000, 0x0000, 0x0000 }, /* R490 */
598 { 0x0000, 0x0000, 0x0000 }, /* R491 */
599 { 0x0000, 0x0000, 0x0000 }, /* R492 */
600 { 0x0000, 0x0000, 0x0000 }, /* R493 */
601 { 0x0000, 0x0000, 0x0000 }, /* R494 */
602 { 0x0000, 0x0000, 0x0000 }, /* R495 */
603 { 0x0000, 0x0000, 0x0000 }, /* R496 */
604 { 0x0000, 0x0000, 0x0000 }, /* R497 */
605 { 0x0000, 0x0000, 0x0000 }, /* R498 */
606 { 0x0000, 0x0000, 0x0000 }, /* R499 */
607 { 0x0000, 0x0000, 0x0000 }, /* R500 */
608 { 0x0000, 0x0000, 0x0000 }, /* R501 */
609 { 0x0000, 0x0000, 0x0000 }, /* R502 */
610 { 0x0000, 0x0000, 0x0000 }, /* R503 */
611 { 0x0000, 0x0000, 0x0000 }, /* R504 */
612 { 0x0000, 0x0000, 0x0000 }, /* R505 */
613 { 0x0000, 0x0000, 0x0000 }, /* R506 */
614 { 0x0000, 0x0000, 0x0000 }, /* R507 */
615 { 0x0000, 0x0000, 0x0000 }, /* R508 */
616 { 0x0000, 0x0000, 0x0000 }, /* R509 */
617 { 0x0000, 0x0000, 0x0000 }, /* R510 */
618 { 0x0000, 0x0000, 0x0000 }, /* R511 */
619 { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
620 { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
621 { 0x0000, 0x0000, 0x0000 }, /* R514 */
622 { 0x0000, 0x0000, 0x0000 }, /* R515 */
623 { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
624 { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
625 { 0x0000, 0x0000, 0x0000 }, /* R518 */
626 { 0x0000, 0x0000, 0x0000 }, /* R519 */
627 { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
628 { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
629 { 0x0000, 0x0000, 0x0000 }, /* R522 */
630 { 0x0000, 0x0000, 0x0000 }, /* R523 */
631 { 0x0000, 0x0000, 0x0000 }, /* R524 */
632 { 0x0000, 0x0000, 0x0000 }, /* R525 */
633 { 0x0000, 0x0000, 0x0000 }, /* R526 */
634 { 0x0000, 0x0000, 0x0000 }, /* R527 */
635 { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
636 { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
637 { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
638 { 0x0000, 0x0000, 0x0000 }, /* R531 */
639 { 0x0000, 0x0000, 0x0000 }, /* R532 */
640 { 0x0000, 0x0000, 0x0000 }, /* R533 */
641 { 0x0000, 0x0000, 0x0000 }, /* R534 */
642 { 0x0000, 0x0000, 0x0000 }, /* R535 */
643 { 0x0000, 0x0000, 0x0000 }, /* R536 */
644 { 0x0000, 0x0000, 0x0000 }, /* R537 */
645 { 0x0000, 0x0000, 0x0000 }, /* R538 */
646 { 0x0000, 0x0000, 0x0000 }, /* R539 */
647 { 0x0000, 0x0000, 0x0000 }, /* R540 */
648 { 0x0000, 0x0000, 0x0000 }, /* R541 */
649 { 0x0000, 0x0000, 0x0000 }, /* R542 */
650 { 0x0000, 0x0000, 0x0000 }, /* R543 */
651 { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
652 { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
653 { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
654 { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
655 { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
656 { 0x0000, 0x0000, 0x0000 }, /* R549 */
657 { 0x0000, 0x0000, 0x0000 }, /* R550 */
658 { 0x0000, 0x0000, 0x0000 }, /* R551 */
659 { 0x0000, 0x0000, 0x0000 }, /* R552 */
660 { 0x0000, 0x0000, 0x0000 }, /* R553 */
661 { 0x0000, 0x0000, 0x0000 }, /* R554 */
662 { 0x0000, 0x0000, 0x0000 }, /* R555 */
663 { 0x0000, 0x0000, 0x0000 }, /* R556 */
664 { 0x0000, 0x0000, 0x0000 }, /* R557 */
665 { 0x0000, 0x0000, 0x0000 }, /* R558 */
666 { 0x0000, 0x0000, 0x0000 }, /* R559 */
667 { 0x0000, 0x0000, 0x0000 }, /* R560 */
668 { 0x0000, 0x0000, 0x0000 }, /* R561 */
669 { 0x0000, 0x0000, 0x0000 }, /* R562 */
670 { 0x0000, 0x0000, 0x0000 }, /* R563 */
671 { 0x0000, 0x0000, 0x0000 }, /* R564 */
672 { 0x0000, 0x0000, 0x0000 }, /* R565 */
673 { 0x0000, 0x0000, 0x0000 }, /* R566 */
674 { 0x0000, 0x0000, 0x0000 }, /* R567 */
675 { 0x0000, 0x0000, 0x0000 }, /* R568 */
676 { 0x0000, 0x0000, 0x0000 }, /* R569 */
677 { 0x0000, 0x0000, 0x0000 }, /* R570 */
678 { 0x0000, 0x0000, 0x0000 }, /* R571 */
679 { 0x0000, 0x0000, 0x0000 }, /* R572 */
680 { 0x0000, 0x0000, 0x0000 }, /* R573 */
681 { 0x0000, 0x0000, 0x0000 }, /* R574 */
682 { 0x0000, 0x0000, 0x0000 }, /* R575 */
683 { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
684 { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
685 { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
686 { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
687 { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
688 { 0x0000, 0x0000, 0x0000 }, /* R581 */
689 { 0x0000, 0x0000, 0x0000 }, /* R582 */
690 { 0x0000, 0x0000, 0x0000 }, /* R583 */
691 { 0x0000, 0x0000, 0x0000 }, /* R584 */
692 { 0x0000, 0x0000, 0x0000 }, /* R585 */
693 { 0x0000, 0x0000, 0x0000 }, /* R586 */
694 { 0x0000, 0x0000, 0x0000 }, /* R587 */
695 { 0x0000, 0x0000, 0x0000 }, /* R588 */
696 { 0x0000, 0x0000, 0x0000 }, /* R589 */
697 { 0x0000, 0x0000, 0x0000 }, /* R590 */
698 { 0x0000, 0x0000, 0x0000 }, /* R591 */
699 { 0x0000, 0x0000, 0x0000 }, /* R592 */
700 { 0x0000, 0x0000, 0x0000 }, /* R593 */
701 { 0x0000, 0x0000, 0x0000 }, /* R594 */
702 { 0x0000, 0x0000, 0x0000 }, /* R595 */
703 { 0x0000, 0x0000, 0x0000 }, /* R596 */
704 { 0x0000, 0x0000, 0x0000 }, /* R597 */
705 { 0x0000, 0x0000, 0x0000 }, /* R598 */
706 { 0x0000, 0x0000, 0x0000 }, /* R599 */
707 { 0x0000, 0x0000, 0x0000 }, /* R600 */
708 { 0x0000, 0x0000, 0x0000 }, /* R601 */
709 { 0x0000, 0x0000, 0x0000 }, /* R602 */
710 { 0x0000, 0x0000, 0x0000 }, /* R603 */
711 { 0x0000, 0x0000, 0x0000 }, /* R604 */
712 { 0x0000, 0x0000, 0x0000 }, /* R605 */
713 { 0x0000, 0x0000, 0x0000 }, /* R606 */
714 { 0x0000, 0x0000, 0x0000 }, /* R607 */
715 { 0x0000, 0x0000, 0x0000 }, /* R608 */
716 { 0x0000, 0x0000, 0x0000 }, /* R609 */
717 { 0x0000, 0x0000, 0x0000 }, /* R610 */
718 { 0x0000, 0x0000, 0x0000 }, /* R611 */
719 { 0x0000, 0x0000, 0x0000 }, /* R612 */
720 { 0x0000, 0x0000, 0x0000 }, /* R613 */
721 { 0x0000, 0x0000, 0x0000 }, /* R614 */
722 { 0x0000, 0x0000, 0x0000 }, /* R615 */
723 { 0x0000, 0x0000, 0x0000 }, /* R616 */
724 { 0x0000, 0x0000, 0x0000 }, /* R617 */
725 { 0x0000, 0x0000, 0x0000 }, /* R618 */
726 { 0x0000, 0x0000, 0x0000 }, /* R619 */
727 { 0x0000, 0x0000, 0x0000 }, /* R620 */
728 { 0x0000, 0x0000, 0x0000 }, /* R621 */
729 { 0x0000, 0x0000, 0x0000 }, /* R622 */
730 { 0x0000, 0x0000, 0x0000 }, /* R623 */
731 { 0x0000, 0x0000, 0x0000 }, /* R624 */
732 { 0x0000, 0x0000, 0x0000 }, /* R625 */
733 { 0x0000, 0x0000, 0x0000 }, /* R626 */
734 { 0x0000, 0x0000, 0x0000 }, /* R627 */
735 { 0x0000, 0x0000, 0x0000 }, /* R628 */
736 { 0x0000, 0x0000, 0x0000 }, /* R629 */
737 { 0x0000, 0x0000, 0x0000 }, /* R630 */
738 { 0x0000, 0x0000, 0x0000 }, /* R631 */
739 { 0x0000, 0x0000, 0x0000 }, /* R632 */
740 { 0x0000, 0x0000, 0x0000 }, /* R633 */
741 { 0x0000, 0x0000, 0x0000 }, /* R634 */
742 { 0x0000, 0x0000, 0x0000 }, /* R635 */
743 { 0x0000, 0x0000, 0x0000 }, /* R636 */
744 { 0x0000, 0x0000, 0x0000 }, /* R637 */
745 { 0x0000, 0x0000, 0x0000 }, /* R638 */
746 { 0x0000, 0x0000, 0x0000 }, /* R639 */
747 { 0x0000, 0x0000, 0x0000 }, /* R640 */
748 { 0x0000, 0x0000, 0x0000 }, /* R641 */
749 { 0x0000, 0x0000, 0x0000 }, /* R642 */
750 { 0x0000, 0x0000, 0x0000 }, /* R643 */
751 { 0x0000, 0x0000, 0x0000 }, /* R644 */
752 { 0x0000, 0x0000, 0x0000 }, /* R645 */
753 { 0x0000, 0x0000, 0x0000 }, /* R646 */
754 { 0x0000, 0x0000, 0x0000 }, /* R647 */
755 { 0x0000, 0x0000, 0x0000 }, /* R648 */
756 { 0x0000, 0x0000, 0x0000 }, /* R649 */
757 { 0x0000, 0x0000, 0x0000 }, /* R650 */
758 { 0x0000, 0x0000, 0x0000 }, /* R651 */
759 { 0x0000, 0x0000, 0x0000 }, /* R652 */
760 { 0x0000, 0x0000, 0x0000 }, /* R653 */
761 { 0x0000, 0x0000, 0x0000 }, /* R654 */
762 { 0x0000, 0x0000, 0x0000 }, /* R655 */
763 { 0x0000, 0x0000, 0x0000 }, /* R656 */
764 { 0x0000, 0x0000, 0x0000 }, /* R657 */
765 { 0x0000, 0x0000, 0x0000 }, /* R658 */
766 { 0x0000, 0x0000, 0x0000 }, /* R659 */
767 { 0x0000, 0x0000, 0x0000 }, /* R660 */
768 { 0x0000, 0x0000, 0x0000 }, /* R661 */
769 { 0x0000, 0x0000, 0x0000 }, /* R662 */
770 { 0x0000, 0x0000, 0x0000 }, /* R663 */
771 { 0x0000, 0x0000, 0x0000 }, /* R664 */
772 { 0x0000, 0x0000, 0x0000 }, /* R665 */
773 { 0x0000, 0x0000, 0x0000 }, /* R666 */
774 { 0x0000, 0x0000, 0x0000 }, /* R667 */
775 { 0x0000, 0x0000, 0x0000 }, /* R668 */
776 { 0x0000, 0x0000, 0x0000 }, /* R669 */
777 { 0x0000, 0x0000, 0x0000 }, /* R670 */
778 { 0x0000, 0x0000, 0x0000 }, /* R671 */
779 { 0x0000, 0x0000, 0x0000 }, /* R672 */
780 { 0x0000, 0x0000, 0x0000 }, /* R673 */
781 { 0x0000, 0x0000, 0x0000 }, /* R674 */
782 { 0x0000, 0x0000, 0x0000 }, /* R675 */
783 { 0x0000, 0x0000, 0x0000 }, /* R676 */
784 { 0x0000, 0x0000, 0x0000 }, /* R677 */
785 { 0x0000, 0x0000, 0x0000 }, /* R678 */
786 { 0x0000, 0x0000, 0x0000 }, /* R679 */
787 { 0x0000, 0x0000, 0x0000 }, /* R680 */
788 { 0x0000, 0x0000, 0x0000 }, /* R681 */
789 { 0x0000, 0x0000, 0x0000 }, /* R682 */
790 { 0x0000, 0x0000, 0x0000 }, /* R683 */
791 { 0x0000, 0x0000, 0x0000 }, /* R684 */
792 { 0x0000, 0x0000, 0x0000 }, /* R685 */
793 { 0x0000, 0x0000, 0x0000 }, /* R686 */
794 { 0x0000, 0x0000, 0x0000 }, /* R687 */
795 { 0x0000, 0x0000, 0x0000 }, /* R688 */
796 { 0x0000, 0x0000, 0x0000 }, /* R689 */
797 { 0x0000, 0x0000, 0x0000 }, /* R690 */
798 { 0x0000, 0x0000, 0x0000 }, /* R691 */
799 { 0x0000, 0x0000, 0x0000 }, /* R692 */
800 { 0x0000, 0x0000, 0x0000 }, /* R693 */
801 { 0x0000, 0x0000, 0x0000 }, /* R694 */
802 { 0x0000, 0x0000, 0x0000 }, /* R695 */
803 { 0x0000, 0x0000, 0x0000 }, /* R696 */
804 { 0x0000, 0x0000, 0x0000 }, /* R697 */
805 { 0x0000, 0x0000, 0x0000 }, /* R698 */
806 { 0x0000, 0x0000, 0x0000 }, /* R699 */
807 { 0x0000, 0x0000, 0x0000 }, /* R700 */
808 { 0x0000, 0x0000, 0x0000 }, /* R701 */
809 { 0x0000, 0x0000, 0x0000 }, /* R702 */
810 { 0x0000, 0x0000, 0x0000 }, /* R703 */
811 { 0x0000, 0x0000, 0x0000 }, /* R704 */
812 { 0x0000, 0x0000, 0x0000 }, /* R705 */
813 { 0x0000, 0x0000, 0x0000 }, /* R706 */
814 { 0x0000, 0x0000, 0x0000 }, /* R707 */
815 { 0x0000, 0x0000, 0x0000 }, /* R708 */
816 { 0x0000, 0x0000, 0x0000 }, /* R709 */
817 { 0x0000, 0x0000, 0x0000 }, /* R710 */
818 { 0x0000, 0x0000, 0x0000 }, /* R711 */
819 { 0x0000, 0x0000, 0x0000 }, /* R712 */
820 { 0x0000, 0x0000, 0x0000 }, /* R713 */
821 { 0x0000, 0x0000, 0x0000 }, /* R714 */
822 { 0x0000, 0x0000, 0x0000 }, /* R715 */
823 { 0x0000, 0x0000, 0x0000 }, /* R716 */
824 { 0x0000, 0x0000, 0x0000 }, /* R717 */
825 { 0x0000, 0x0000, 0x0000 }, /* R718 */
826 { 0x0000, 0x0000, 0x0000 }, /* R719 */
827 { 0x0000, 0x0000, 0x0000 }, /* R720 */
828 { 0x0000, 0x0000, 0x0000 }, /* R721 */
829 { 0x0000, 0x0000, 0x0000 }, /* R722 */
830 { 0x0000, 0x0000, 0x0000 }, /* R723 */
831 { 0x0000, 0x0000, 0x0000 }, /* R724 */
832 { 0x0000, 0x0000, 0x0000 }, /* R725 */
833 { 0x0000, 0x0000, 0x0000 }, /* R726 */
834 { 0x0000, 0x0000, 0x0000 }, /* R727 */
835 { 0x0000, 0x0000, 0x0000 }, /* R728 */
836 { 0x0000, 0x0000, 0x0000 }, /* R729 */
837 { 0x0000, 0x0000, 0x0000 }, /* R730 */
838 { 0x0000, 0x0000, 0x0000 }, /* R731 */
839 { 0x0000, 0x0000, 0x0000 }, /* R732 */
840 { 0x0000, 0x0000, 0x0000 }, /* R733 */
841 { 0x0000, 0x0000, 0x0000 }, /* R734 */
842 { 0x0000, 0x0000, 0x0000 }, /* R735 */
843 { 0x0000, 0x0000, 0x0000 }, /* R736 */
844 { 0x0000, 0x0000, 0x0000 }, /* R737 */
845 { 0x0000, 0x0000, 0x0000 }, /* R738 */
846 { 0x0000, 0x0000, 0x0000 }, /* R739 */
847 { 0x0000, 0x0000, 0x0000 }, /* R740 */
848 { 0x0000, 0x0000, 0x0000 }, /* R741 */
849 { 0x0000, 0x0000, 0x0000 }, /* R742 */
850 { 0x0000, 0x0000, 0x0000 }, /* R743 */
851 { 0x0000, 0x0000, 0x0000 }, /* R744 */
852 { 0x0000, 0x0000, 0x0000 }, /* R745 */
853 { 0x0000, 0x0000, 0x0000 }, /* R746 */
854 { 0x0000, 0x0000, 0x0000 }, /* R747 */
855 { 0x0000, 0x0000, 0x0000 }, /* R748 */
856 { 0x0000, 0x0000, 0x0000 }, /* R749 */
857 { 0x0000, 0x0000, 0x0000 }, /* R750 */
858 { 0x0000, 0x0000, 0x0000 }, /* R751 */
859 { 0x0000, 0x0000, 0x0000 }, /* R752 */
860 { 0x0000, 0x0000, 0x0000 }, /* R753 */
861 { 0x0000, 0x0000, 0x0000 }, /* R754 */
862 { 0x0000, 0x0000, 0x0000 }, /* R755 */
863 { 0x0000, 0x0000, 0x0000 }, /* R756 */
864 { 0x0000, 0x0000, 0x0000 }, /* R757 */
865 { 0x0000, 0x0000, 0x0000 }, /* R758 */
866 { 0x0000, 0x0000, 0x0000 }, /* R759 */
867 { 0x0000, 0x0000, 0x0000 }, /* R760 */
868 { 0x0000, 0x0000, 0x0000 }, /* R761 */
869 { 0x0000, 0x0000, 0x0000 }, /* R762 */
870 { 0x0000, 0x0000, 0x0000 }, /* R763 */
871 { 0x0000, 0x0000, 0x0000 }, /* R764 */
872 { 0x0000, 0x0000, 0x0000 }, /* R765 */
873 { 0x0000, 0x0000, 0x0000 }, /* R766 */
874 { 0x0000, 0x0000, 0x0000 }, /* R767 */
875 { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
876 { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
877 { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
878 { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
879 { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
880 { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
881 { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
882 { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
883 { 0x0000, 0x0000, 0x0000 }, /* R776 */
884 { 0x0000, 0x0000, 0x0000 }, /* R777 */
885 { 0x0000, 0x0000, 0x0000 }, /* R778 */
886 { 0x0000, 0x0000, 0x0000 }, /* R779 */
887 { 0x0000, 0x0000, 0x0000 }, /* R780 */
888 { 0x0000, 0x0000, 0x0000 }, /* R781 */
889 { 0x0000, 0x0000, 0x0000 }, /* R782 */
890 { 0x0000, 0x0000, 0x0000 }, /* R783 */
891 { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
892 { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
893 { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
894 { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
895 { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
896 { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
897 { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
898 { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
899 { 0x0000, 0x0000, 0x0000 }, /* R792 */
900 { 0x0000, 0x0000, 0x0000 }, /* R793 */
901 { 0x0000, 0x0000, 0x0000 }, /* R794 */
902 { 0x0000, 0x0000, 0x0000 }, /* R795 */
903 { 0x0000, 0x0000, 0x0000 }, /* R796 */
904 { 0x0000, 0x0000, 0x0000 }, /* R797 */
905 { 0x0000, 0x0000, 0x0000 }, /* R798 */
906 { 0x0000, 0x0000, 0x0000 }, /* R799 */
907 { 0x0000, 0x0000, 0x0000 }, /* R800 */
908 { 0x0000, 0x0000, 0x0000 }, /* R801 */
909 { 0x0000, 0x0000, 0x0000 }, /* R802 */
910 { 0x0000, 0x0000, 0x0000 }, /* R803 */
911 { 0x0000, 0x0000, 0x0000 }, /* R804 */
912 { 0x0000, 0x0000, 0x0000 }, /* R805 */
913 { 0x0000, 0x0000, 0x0000 }, /* R806 */
914 { 0x0000, 0x0000, 0x0000 }, /* R807 */
915 { 0x0000, 0x0000, 0x0000 }, /* R808 */
916 { 0x0000, 0x0000, 0x0000 }, /* R809 */
917 { 0x0000, 0x0000, 0x0000 }, /* R810 */
918 { 0x0000, 0x0000, 0x0000 }, /* R811 */
919 { 0x0000, 0x0000, 0x0000 }, /* R812 */
920 { 0x0000, 0x0000, 0x0000 }, /* R813 */
921 { 0x0000, 0x0000, 0x0000 }, /* R814 */
922 { 0x0000, 0x0000, 0x0000 }, /* R815 */
923 { 0x0000, 0x0000, 0x0000 }, /* R816 */
924 { 0x0000, 0x0000, 0x0000 }, /* R817 */
925 { 0x0000, 0x0000, 0x0000 }, /* R818 */
926 { 0x0000, 0x0000, 0x0000 }, /* R819 */
927 { 0x0000, 0x0000, 0x0000 }, /* R820 */
928 { 0x0000, 0x0000, 0x0000 }, /* R821 */
929 { 0x0000, 0x0000, 0x0000 }, /* R822 */
930 { 0x0000, 0x0000, 0x0000 }, /* R823 */
931 { 0x0000, 0x0000, 0x0000 }, /* R824 */
932 { 0x0000, 0x0000, 0x0000 }, /* R825 */
933 { 0x0000, 0x0000, 0x0000 }, /* R826 */
934 { 0x0000, 0x0000, 0x0000 }, /* R827 */
935 { 0x0000, 0x0000, 0x0000 }, /* R828 */
936 { 0x0000, 0x0000, 0x0000 }, /* R829 */
937 { 0x0000, 0x0000, 0x0000 }, /* R830 */
938 { 0x0000, 0x0000, 0x0000 }, /* R831 */
939 { 0x0000, 0x0000, 0x0000 }, /* R832 */
940 { 0x0000, 0x0000, 0x0000 }, /* R833 */
941 { 0x0000, 0x0000, 0x0000 }, /* R834 */
942 { 0x0000, 0x0000, 0x0000 }, /* R835 */
943 { 0x0000, 0x0000, 0x0000 }, /* R836 */
944 { 0x0000, 0x0000, 0x0000 }, /* R837 */
945 { 0x0000, 0x0000, 0x0000 }, /* R838 */
946 { 0x0000, 0x0000, 0x0000 }, /* R839 */
947 { 0x0000, 0x0000, 0x0000 }, /* R840 */
948 { 0x0000, 0x0000, 0x0000 }, /* R841 */
949 { 0x0000, 0x0000, 0x0000 }, /* R842 */
950 { 0x0000, 0x0000, 0x0000 }, /* R843 */
951 { 0x0000, 0x0000, 0x0000 }, /* R844 */
952 { 0x0000, 0x0000, 0x0000 }, /* R845 */
953 { 0x0000, 0x0000, 0x0000 }, /* R846 */
954 { 0x0000, 0x0000, 0x0000 }, /* R847 */
955 { 0x0000, 0x0000, 0x0000 }, /* R848 */
956 { 0x0000, 0x0000, 0x0000 }, /* R849 */
957 { 0x0000, 0x0000, 0x0000 }, /* R850 */
958 { 0x0000, 0x0000, 0x0000 }, /* R851 */
959 { 0x0000, 0x0000, 0x0000 }, /* R852 */
960 { 0x0000, 0x0000, 0x0000 }, /* R853 */
961 { 0x0000, 0x0000, 0x0000 }, /* R854 */
962 { 0x0000, 0x0000, 0x0000 }, /* R855 */
963 { 0x0000, 0x0000, 0x0000 }, /* R856 */
964 { 0x0000, 0x0000, 0x0000 }, /* R857 */
965 { 0x0000, 0x0000, 0x0000 }, /* R858 */
966 { 0x0000, 0x0000, 0x0000 }, /* R859 */
967 { 0x0000, 0x0000, 0x0000 }, /* R860 */
968 { 0x0000, 0x0000, 0x0000 }, /* R861 */
969 { 0x0000, 0x0000, 0x0000 }, /* R862 */
970 { 0x0000, 0x0000, 0x0000 }, /* R863 */
971 { 0x0000, 0x0000, 0x0000 }, /* R864 */
972 { 0x0000, 0x0000, 0x0000 }, /* R865 */
973 { 0x0000, 0x0000, 0x0000 }, /* R866 */
974 { 0x0000, 0x0000, 0x0000 }, /* R867 */
975 { 0x0000, 0x0000, 0x0000 }, /* R868 */
976 { 0x0000, 0x0000, 0x0000 }, /* R869 */
977 { 0x0000, 0x0000, 0x0000 }, /* R870 */
978 { 0x0000, 0x0000, 0x0000 }, /* R871 */
979 { 0x0000, 0x0000, 0x0000 }, /* R872 */
980 { 0x0000, 0x0000, 0x0000 }, /* R873 */
981 { 0x0000, 0x0000, 0x0000 }, /* R874 */
982 { 0x0000, 0x0000, 0x0000 }, /* R875 */
983 { 0x0000, 0x0000, 0x0000 }, /* R876 */
984 { 0x0000, 0x0000, 0x0000 }, /* R877 */
985 { 0x0000, 0x0000, 0x0000 }, /* R878 */
986 { 0x0000, 0x0000, 0x0000 }, /* R879 */
987 { 0x0000, 0x0000, 0x0000 }, /* R880 */
988 { 0x0000, 0x0000, 0x0000 }, /* R881 */
989 { 0x0000, 0x0000, 0x0000 }, /* R882 */
990 { 0x0000, 0x0000, 0x0000 }, /* R883 */
991 { 0x0000, 0x0000, 0x0000 }, /* R884 */
992 { 0x0000, 0x0000, 0x0000 }, /* R885 */
993 { 0x0000, 0x0000, 0x0000 }, /* R886 */
994 { 0x0000, 0x0000, 0x0000 }, /* R887 */
995 { 0x0000, 0x0000, 0x0000 }, /* R888 */
996 { 0x0000, 0x0000, 0x0000 }, /* R889 */
997 { 0x0000, 0x0000, 0x0000 }, /* R890 */
998 { 0x0000, 0x0000, 0x0000 }, /* R891 */
999 { 0x0000, 0x0000, 0x0000 }, /* R892 */
1000 { 0x0000, 0x0000, 0x0000 }, /* R893 */
1001 { 0x0000, 0x0000, 0x0000 }, /* R894 */
1002 { 0x0000, 0x0000, 0x0000 }, /* R895 */
1003 { 0x0000, 0x0000, 0x0000 }, /* R896 */
1004 { 0x0000, 0x0000, 0x0000 }, /* R897 */
1005 { 0x0000, 0x0000, 0x0000 }, /* R898 */
1006 { 0x0000, 0x0000, 0x0000 }, /* R899 */
1007 { 0x0000, 0x0000, 0x0000 }, /* R900 */
1008 { 0x0000, 0x0000, 0x0000 }, /* R901 */
1009 { 0x0000, 0x0000, 0x0000 }, /* R902 */
1010 { 0x0000, 0x0000, 0x0000 }, /* R903 */
1011 { 0x0000, 0x0000, 0x0000 }, /* R904 */
1012 { 0x0000, 0x0000, 0x0000 }, /* R905 */
1013 { 0x0000, 0x0000, 0x0000 }, /* R906 */
1014 { 0x0000, 0x0000, 0x0000 }, /* R907 */
1015 { 0x0000, 0x0000, 0x0000 }, /* R908 */
1016 { 0x0000, 0x0000, 0x0000 }, /* R909 */
1017 { 0x0000, 0x0000, 0x0000 }, /* R910 */
1018 { 0x0000, 0x0000, 0x0000 }, /* R911 */
1019 { 0x0000, 0x0000, 0x0000 }, /* R912 */
1020 { 0x0000, 0x0000, 0x0000 }, /* R913 */
1021 { 0x0000, 0x0000, 0x0000 }, /* R914 */
1022 { 0x0000, 0x0000, 0x0000 }, /* R915 */
1023 { 0x0000, 0x0000, 0x0000 }, /* R916 */
1024 { 0x0000, 0x0000, 0x0000 }, /* R917 */
1025 { 0x0000, 0x0000, 0x0000 }, /* R918 */
1026 { 0x0000, 0x0000, 0x0000 }, /* R919 */
1027 { 0x0000, 0x0000, 0x0000 }, /* R920 */
1028 { 0x0000, 0x0000, 0x0000 }, /* R921 */
1029 { 0x0000, 0x0000, 0x0000 }, /* R922 */
1030 { 0x0000, 0x0000, 0x0000 }, /* R923 */
1031 { 0x0000, 0x0000, 0x0000 }, /* R924 */
1032 { 0x0000, 0x0000, 0x0000 }, /* R925 */
1033 { 0x0000, 0x0000, 0x0000 }, /* R926 */
1034 { 0x0000, 0x0000, 0x0000 }, /* R927 */
1035 { 0x0000, 0x0000, 0x0000 }, /* R928 */
1036 { 0x0000, 0x0000, 0x0000 }, /* R929 */
1037 { 0x0000, 0x0000, 0x0000 }, /* R930 */
1038 { 0x0000, 0x0000, 0x0000 }, /* R931 */
1039 { 0x0000, 0x0000, 0x0000 }, /* R932 */
1040 { 0x0000, 0x0000, 0x0000 }, /* R933 */
1041 { 0x0000, 0x0000, 0x0000 }, /* R934 */
1042 { 0x0000, 0x0000, 0x0000 }, /* R935 */
1043 { 0x0000, 0x0000, 0x0000 }, /* R936 */
1044 { 0x0000, 0x0000, 0x0000 }, /* R937 */
1045 { 0x0000, 0x0000, 0x0000 }, /* R938 */
1046 { 0x0000, 0x0000, 0x0000 }, /* R939 */
1047 { 0x0000, 0x0000, 0x0000 }, /* R940 */
1048 { 0x0000, 0x0000, 0x0000 }, /* R941 */
1049 { 0x0000, 0x0000, 0x0000 }, /* R942 */
1050 { 0x0000, 0x0000, 0x0000 }, /* R943 */
1051 { 0x0000, 0x0000, 0x0000 }, /* R944 */
1052 { 0x0000, 0x0000, 0x0000 }, /* R945 */
1053 { 0x0000, 0x0000, 0x0000 }, /* R946 */
1054 { 0x0000, 0x0000, 0x0000 }, /* R947 */
1055 { 0x0000, 0x0000, 0x0000 }, /* R948 */
1056 { 0x0000, 0x0000, 0x0000 }, /* R949 */
1057 { 0x0000, 0x0000, 0x0000 }, /* R950 */
1058 { 0x0000, 0x0000, 0x0000 }, /* R951 */
1059 { 0x0000, 0x0000, 0x0000 }, /* R952 */
1060 { 0x0000, 0x0000, 0x0000 }, /* R953 */
1061 { 0x0000, 0x0000, 0x0000 }, /* R954 */
1062 { 0x0000, 0x0000, 0x0000 }, /* R955 */
1063 { 0x0000, 0x0000, 0x0000 }, /* R956 */
1064 { 0x0000, 0x0000, 0x0000 }, /* R957 */
1065 { 0x0000, 0x0000, 0x0000 }, /* R958 */
1066 { 0x0000, 0x0000, 0x0000 }, /* R959 */
1067 { 0x0000, 0x0000, 0x0000 }, /* R960 */
1068 { 0x0000, 0x0000, 0x0000 }, /* R961 */
1069 { 0x0000, 0x0000, 0x0000 }, /* R962 */
1070 { 0x0000, 0x0000, 0x0000 }, /* R963 */
1071 { 0x0000, 0x0000, 0x0000 }, /* R964 */
1072 { 0x0000, 0x0000, 0x0000 }, /* R965 */
1073 { 0x0000, 0x0000, 0x0000 }, /* R966 */
1074 { 0x0000, 0x0000, 0x0000 }, /* R967 */
1075 { 0x0000, 0x0000, 0x0000 }, /* R968 */
1076 { 0x0000, 0x0000, 0x0000 }, /* R969 */
1077 { 0x0000, 0x0000, 0x0000 }, /* R970 */
1078 { 0x0000, 0x0000, 0x0000 }, /* R971 */
1079 { 0x0000, 0x0000, 0x0000 }, /* R972 */
1080 { 0x0000, 0x0000, 0x0000 }, /* R973 */
1081 { 0x0000, 0x0000, 0x0000 }, /* R974 */
1082 { 0x0000, 0x0000, 0x0000 }, /* R975 */
1083 { 0x0000, 0x0000, 0x0000 }, /* R976 */
1084 { 0x0000, 0x0000, 0x0000 }, /* R977 */
1085 { 0x0000, 0x0000, 0x0000 }, /* R978 */
1086 { 0x0000, 0x0000, 0x0000 }, /* R979 */
1087 { 0x0000, 0x0000, 0x0000 }, /* R980 */
1088 { 0x0000, 0x0000, 0x0000 }, /* R981 */
1089 { 0x0000, 0x0000, 0x0000 }, /* R982 */
1090 { 0x0000, 0x0000, 0x0000 }, /* R983 */
1091 { 0x0000, 0x0000, 0x0000 }, /* R984 */
1092 { 0x0000, 0x0000, 0x0000 }, /* R985 */
1093 { 0x0000, 0x0000, 0x0000 }, /* R986 */
1094 { 0x0000, 0x0000, 0x0000 }, /* R987 */
1095 { 0x0000, 0x0000, 0x0000 }, /* R988 */
1096 { 0x0000, 0x0000, 0x0000 }, /* R989 */
1097 { 0x0000, 0x0000, 0x0000 }, /* R990 */
1098 { 0x0000, 0x0000, 0x0000 }, /* R991 */
1099 { 0x0000, 0x0000, 0x0000 }, /* R992 */
1100 { 0x0000, 0x0000, 0x0000 }, /* R993 */
1101 { 0x0000, 0x0000, 0x0000 }, /* R994 */
1102 { 0x0000, 0x0000, 0x0000 }, /* R995 */
1103 { 0x0000, 0x0000, 0x0000 }, /* R996 */
1104 { 0x0000, 0x0000, 0x0000 }, /* R997 */
1105 { 0x0000, 0x0000, 0x0000 }, /* R998 */
1106 { 0x0000, 0x0000, 0x0000 }, /* R999 */
1107 { 0x0000, 0x0000, 0x0000 }, /* R1000 */
1108 { 0x0000, 0x0000, 0x0000 }, /* R1001 */
1109 { 0x0000, 0x0000, 0x0000 }, /* R1002 */
1110 { 0x0000, 0x0000, 0x0000 }, /* R1003 */
1111 { 0x0000, 0x0000, 0x0000 }, /* R1004 */
1112 { 0x0000, 0x0000, 0x0000 }, /* R1005 */
1113 { 0x0000, 0x0000, 0x0000 }, /* R1006 */
1114 { 0x0000, 0x0000, 0x0000 }, /* R1007 */
1115 { 0x0000, 0x0000, 0x0000 }, /* R1008 */
1116 { 0x0000, 0x0000, 0x0000 }, /* R1009 */
1117 { 0x0000, 0x0000, 0x0000 }, /* R1010 */
1118 { 0x0000, 0x0000, 0x0000 }, /* R1011 */
1119 { 0x0000, 0x0000, 0x0000 }, /* R1012 */
1120 { 0x0000, 0x0000, 0x0000 }, /* R1013 */
1121 { 0x0000, 0x0000, 0x0000 }, /* R1014 */
1122 { 0x0000, 0x0000, 0x0000 }, /* R1015 */
1123 { 0x0000, 0x0000, 0x0000 }, /* R1016 */
1124 { 0x0000, 0x0000, 0x0000 }, /* R1017 */
1125 { 0x0000, 0x0000, 0x0000 }, /* R1018 */
1126 { 0x0000, 0x0000, 0x0000 }, /* R1019 */
1127 { 0x0000, 0x0000, 0x0000 }, /* R1020 */
1128 { 0x0000, 0x0000, 0x0000 }, /* R1021 */
1129 { 0x0000, 0x0000, 0x0000 }, /* R1022 */
1130 { 0x0000, 0x0000, 0x0000 }, /* R1023 */
1131 { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
1132 { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
1133 { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
1134 { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
1135 { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
1136 { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
1137 { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
1138 { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
1139 { 0x0000, 0x0000, 0x0000 }, /* R1032 */
1140 { 0x0000, 0x0000, 0x0000 }, /* R1033 */
1141 { 0x0000, 0x0000, 0x0000 }, /* R1034 */
1142 { 0x0000, 0x0000, 0x0000 }, /* R1035 */
1143 { 0x0000, 0x0000, 0x0000 }, /* R1036 */
1144 { 0x0000, 0x0000, 0x0000 }, /* R1037 */
1145 { 0x0000, 0x0000, 0x0000 }, /* R1038 */
1146 { 0x0000, 0x0000, 0x0000 }, /* R1039 */
1147 { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
1148 { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
1149 { 0x0000, 0x0000, 0x0000 }, /* R1042 */
1150 { 0x0000, 0x0000, 0x0000 }, /* R1043 */
1151 { 0x0000, 0x0000, 0x0000 }, /* R1044 */
1152 { 0x0000, 0x0000, 0x0000 }, /* R1045 */
1153 { 0x0000, 0x0000, 0x0000 }, /* R1046 */
1154 { 0x0000, 0x0000, 0x0000 }, /* R1047 */
1155 { 0x0000, 0x0000, 0x0000 }, /* R1048 */
1156 { 0x0000, 0x0000, 0x0000 }, /* R1049 */
1157 { 0x0000, 0x0000, 0x0000 }, /* R1050 */
1158 { 0x0000, 0x0000, 0x0000 }, /* R1051 */
1159 { 0x0000, 0x0000, 0x0000 }, /* R1052 */
1160 { 0x0000, 0x0000, 0x0000 }, /* R1053 */
1161 { 0x0000, 0x0000, 0x0000 }, /* R1054 */
1162 { 0x0000, 0x0000, 0x0000 }, /* R1055 */
1163 { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
1164 { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
1165 { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
1166 { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
1167 { 0x0000, 0x0000, 0x0000 }, /* R1060 */
1168 { 0x0000, 0x0000, 0x0000 }, /* R1061 */
1169 { 0x0000, 0x0000, 0x0000 }, /* R1062 */
1170 { 0x0000, 0x0000, 0x0000 }, /* R1063 */
1171 { 0x0000, 0x0000, 0x0000 }, /* R1064 */
1172 { 0x0000, 0x0000, 0x0000 }, /* R1065 */
1173 { 0x0000, 0x0000, 0x0000 }, /* R1066 */
1174 { 0x0000, 0x0000, 0x0000 }, /* R1067 */
1175 { 0x0000, 0x0000, 0x0000 }, /* R1068 */
1176 { 0x0000, 0x0000, 0x0000 }, /* R1069 */
1177 { 0x0000, 0x0000, 0x0000 }, /* R1070 */
1178 { 0x0000, 0x0000, 0x0000 }, /* R1071 */
1179 { 0x0000, 0x0000, 0x0000 }, /* R1072 */
1180 { 0x0000, 0x0000, 0x0000 }, /* R1073 */
1181 { 0x0000, 0x0000, 0x0000 }, /* R1074 */
1182 { 0x0000, 0x0000, 0x0000 }, /* R1075 */
1183 { 0x0000, 0x0000, 0x0000 }, /* R1076 */
1184 { 0x0000, 0x0000, 0x0000 }, /* R1077 */
1185 { 0x0000, 0x0000, 0x0000 }, /* R1078 */
1186 { 0x0000, 0x0000, 0x0000 }, /* R1079 */
1187 { 0x0000, 0x0000, 0x0000 }, /* R1080 */
1188 { 0x0000, 0x0000, 0x0000 }, /* R1081 */
1189 { 0x0000, 0x0000, 0x0000 }, /* R1082 */
1190 { 0x0000, 0x0000, 0x0000 }, /* R1083 */
1191 { 0x0000, 0x0000, 0x0000 }, /* R1084 */
1192 { 0x0000, 0x0000, 0x0000 }, /* R1085 */
1193 { 0x0000, 0x0000, 0x0000 }, /* R1086 */
1194 { 0x0000, 0x0000, 0x0000 }, /* R1087 */
1195 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
1196 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
1197 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
1198 { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
1199 { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
1200 { 0x0000, 0x0000, 0x0000 }, /* R1093 */
1201 { 0x0000, 0x0000, 0x0000 }, /* R1094 */
1202 { 0x0000, 0x0000, 0x0000 }, /* R1095 */
1203 { 0x0000, 0x0000, 0x0000 }, /* R1096 */
1204 { 0x0000, 0x0000, 0x0000 }, /* R1097 */
1205 { 0x0000, 0x0000, 0x0000 }, /* R1098 */
1206 { 0x0000, 0x0000, 0x0000 }, /* R1099 */
1207 { 0x0000, 0x0000, 0x0000 }, /* R1100 */
1208 { 0x0000, 0x0000, 0x0000 }, /* R1101 */
1209 { 0x0000, 0x0000, 0x0000 }, /* R1102 */
1210 { 0x0000, 0x0000, 0x0000 }, /* R1103 */
1211 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
1212 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
1213 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
1214 { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
1215 { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
1216 { 0x0000, 0x0000, 0x0000 }, /* R1109 */
1217 { 0x0000, 0x0000, 0x0000 }, /* R1110 */
1218 { 0x0000, 0x0000, 0x0000 }, /* R1111 */
1219 { 0x0000, 0x0000, 0x0000 }, /* R1112 */
1220 { 0x0000, 0x0000, 0x0000 }, /* R1113 */
1221 { 0x0000, 0x0000, 0x0000 }, /* R1114 */
1222 { 0x0000, 0x0000, 0x0000 }, /* R1115 */
1223 { 0x0000, 0x0000, 0x0000 }, /* R1116 */
1224 { 0x0000, 0x0000, 0x0000 }, /* R1117 */
1225 { 0x0000, 0x0000, 0x0000 }, /* R1118 */
1226 { 0x0000, 0x0000, 0x0000 }, /* R1119 */
1227 { 0x0000, 0x0000, 0x0000 }, /* R1120 */
1228 { 0x0000, 0x0000, 0x0000 }, /* R1121 */
1229 { 0x0000, 0x0000, 0x0000 }, /* R1122 */
1230 { 0x0000, 0x0000, 0x0000 }, /* R1123 */
1231 { 0x0000, 0x0000, 0x0000 }, /* R1124 */
1232 { 0x0000, 0x0000, 0x0000 }, /* R1125 */
1233 { 0x0000, 0x0000, 0x0000 }, /* R1126 */
1234 { 0x0000, 0x0000, 0x0000 }, /* R1127 */
1235 { 0x0000, 0x0000, 0x0000 }, /* R1128 */
1236 { 0x0000, 0x0000, 0x0000 }, /* R1129 */
1237 { 0x0000, 0x0000, 0x0000 }, /* R1130 */
1238 { 0x0000, 0x0000, 0x0000 }, /* R1131 */
1239 { 0x0000, 0x0000, 0x0000 }, /* R1132 */
1240 { 0x0000, 0x0000, 0x0000 }, /* R1133 */
1241 { 0x0000, 0x0000, 0x0000 }, /* R1134 */
1242 { 0x0000, 0x0000, 0x0000 }, /* R1135 */
1243 { 0x0000, 0x0000, 0x0000 }, /* R1136 */
1244 { 0x0000, 0x0000, 0x0000 }, /* R1137 */
1245 { 0x0000, 0x0000, 0x0000 }, /* R1138 */
1246 { 0x0000, 0x0000, 0x0000 }, /* R1139 */
1247 { 0x0000, 0x0000, 0x0000 }, /* R1140 */
1248 { 0x0000, 0x0000, 0x0000 }, /* R1141 */
1249 { 0x0000, 0x0000, 0x0000 }, /* R1142 */
1250 { 0x0000, 0x0000, 0x0000 }, /* R1143 */
1251 { 0x0000, 0x0000, 0x0000 }, /* R1144 */
1252 { 0x0000, 0x0000, 0x0000 }, /* R1145 */
1253 { 0x0000, 0x0000, 0x0000 }, /* R1146 */
1254 { 0x0000, 0x0000, 0x0000 }, /* R1147 */
1255 { 0x0000, 0x0000, 0x0000 }, /* R1148 */
1256 { 0x0000, 0x0000, 0x0000 }, /* R1149 */
1257 { 0x0000, 0x0000, 0x0000 }, /* R1150 */
1258 { 0x0000, 0x0000, 0x0000 }, /* R1151 */
1259 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1260 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1261 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1262 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1263 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1264 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1265 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1266 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1267 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1268 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1269 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1270 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1271 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1272 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1273 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1274 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1275 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1276 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1277 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1278 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1279 { 0x0000, 0x0000, 0x0000 }, /* R1172 */
1280 { 0x0000, 0x0000, 0x0000 }, /* R1173 */
1281 { 0x0000, 0x0000, 0x0000 }, /* R1174 */
1282 { 0x0000, 0x0000, 0x0000 }, /* R1175 */
1283 { 0x0000, 0x0000, 0x0000 }, /* R1176 */
1284 { 0x0000, 0x0000, 0x0000 }, /* R1177 */
1285 { 0x0000, 0x0000, 0x0000 }, /* R1178 */
1286 { 0x0000, 0x0000, 0x0000 }, /* R1179 */
1287 { 0x0000, 0x0000, 0x0000 }, /* R1180 */
1288 { 0x0000, 0x0000, 0x0000 }, /* R1181 */
1289 { 0x0000, 0x0000, 0x0000 }, /* R1182 */
1290 { 0x0000, 0x0000, 0x0000 }, /* R1183 */
1291 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1292 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1293 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1294 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1295 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1296 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1297 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1298 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1299 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1300 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1301 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1302 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1303 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1304 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1305 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1306 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1307 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1308 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1309 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1310 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1311 { 0x0000, 0x0000, 0x0000 }, /* R1204 */
1312 { 0x0000, 0x0000, 0x0000 }, /* R1205 */
1313 { 0x0000, 0x0000, 0x0000 }, /* R1206 */
1314 { 0x0000, 0x0000, 0x0000 }, /* R1207 */
1315 { 0x0000, 0x0000, 0x0000 }, /* R1208 */
1316 { 0x0000, 0x0000, 0x0000 }, /* R1209 */
1317 { 0x0000, 0x0000, 0x0000 }, /* R1210 */
1318 { 0x0000, 0x0000, 0x0000 }, /* R1211 */
1319 { 0x0000, 0x0000, 0x0000 }, /* R1212 */
1320 { 0x0000, 0x0000, 0x0000 }, /* R1213 */
1321 { 0x0000, 0x0000, 0x0000 }, /* R1214 */
1322 { 0x0000, 0x0000, 0x0000 }, /* R1215 */
1323 { 0x0000, 0x0000, 0x0000 }, /* R1216 */
1324 { 0x0000, 0x0000, 0x0000 }, /* R1217 */
1325 { 0x0000, 0x0000, 0x0000 }, /* R1218 */
1326 { 0x0000, 0x0000, 0x0000 }, /* R1219 */
1327 { 0x0000, 0x0000, 0x0000 }, /* R1220 */
1328 { 0x0000, 0x0000, 0x0000 }, /* R1221 */
1329 { 0x0000, 0x0000, 0x0000 }, /* R1222 */
1330 { 0x0000, 0x0000, 0x0000 }, /* R1223 */
1331 { 0x0000, 0x0000, 0x0000 }, /* R1224 */
1332 { 0x0000, 0x0000, 0x0000 }, /* R1225 */
1333 { 0x0000, 0x0000, 0x0000 }, /* R1226 */
1334 { 0x0000, 0x0000, 0x0000 }, /* R1227 */
1335 { 0x0000, 0x0000, 0x0000 }, /* R1228 */
1336 { 0x0000, 0x0000, 0x0000 }, /* R1229 */
1337 { 0x0000, 0x0000, 0x0000 }, /* R1230 */
1338 { 0x0000, 0x0000, 0x0000 }, /* R1231 */
1339 { 0x0000, 0x0000, 0x0000 }, /* R1232 */
1340 { 0x0000, 0x0000, 0x0000 }, /* R1233 */
1341 { 0x0000, 0x0000, 0x0000 }, /* R1234 */
1342 { 0x0000, 0x0000, 0x0000 }, /* R1235 */
1343 { 0x0000, 0x0000, 0x0000 }, /* R1236 */
1344 { 0x0000, 0x0000, 0x0000 }, /* R1237 */
1345 { 0x0000, 0x0000, 0x0000 }, /* R1238 */
1346 { 0x0000, 0x0000, 0x0000 }, /* R1239 */
1347 { 0x0000, 0x0000, 0x0000 }, /* R1240 */
1348 { 0x0000, 0x0000, 0x0000 }, /* R1241 */
1349 { 0x0000, 0x0000, 0x0000 }, /* R1242 */
1350 { 0x0000, 0x0000, 0x0000 }, /* R1243 */
1351 { 0x0000, 0x0000, 0x0000 }, /* R1244 */
1352 { 0x0000, 0x0000, 0x0000 }, /* R1245 */
1353 { 0x0000, 0x0000, 0x0000 }, /* R1246 */
1354 { 0x0000, 0x0000, 0x0000 }, /* R1247 */
1355 { 0x0000, 0x0000, 0x0000 }, /* R1248 */
1356 { 0x0000, 0x0000, 0x0000 }, /* R1249 */
1357 { 0x0000, 0x0000, 0x0000 }, /* R1250 */
1358 { 0x0000, 0x0000, 0x0000 }, /* R1251 */
1359 { 0x0000, 0x0000, 0x0000 }, /* R1252 */
1360 { 0x0000, 0x0000, 0x0000 }, /* R1253 */
1361 { 0x0000, 0x0000, 0x0000 }, /* R1254 */
1362 { 0x0000, 0x0000, 0x0000 }, /* R1255 */
1363 { 0x0000, 0x0000, 0x0000 }, /* R1256 */
1364 { 0x0000, 0x0000, 0x0000 }, /* R1257 */
1365 { 0x0000, 0x0000, 0x0000 }, /* R1258 */
1366 { 0x0000, 0x0000, 0x0000 }, /* R1259 */
1367 { 0x0000, 0x0000, 0x0000 }, /* R1260 */
1368 { 0x0000, 0x0000, 0x0000 }, /* R1261 */
1369 { 0x0000, 0x0000, 0x0000 }, /* R1262 */
1370 { 0x0000, 0x0000, 0x0000 }, /* R1263 */
1371 { 0x0000, 0x0000, 0x0000 }, /* R1264 */
1372 { 0x0000, 0x0000, 0x0000 }, /* R1265 */
1373 { 0x0000, 0x0000, 0x0000 }, /* R1266 */
1374 { 0x0000, 0x0000, 0x0000 }, /* R1267 */
1375 { 0x0000, 0x0000, 0x0000 }, /* R1268 */
1376 { 0x0000, 0x0000, 0x0000 }, /* R1269 */
1377 { 0x0000, 0x0000, 0x0000 }, /* R1270 */
1378 { 0x0000, 0x0000, 0x0000 }, /* R1271 */
1379 { 0x0000, 0x0000, 0x0000 }, /* R1272 */
1380 { 0x0000, 0x0000, 0x0000 }, /* R1273 */
1381 { 0x0000, 0x0000, 0x0000 }, /* R1274 */
1382 { 0x0000, 0x0000, 0x0000 }, /* R1275 */
1383 { 0x0000, 0x0000, 0x0000 }, /* R1276 */
1384 { 0x0000, 0x0000, 0x0000 }, /* R1277 */
1385 { 0x0000, 0x0000, 0x0000 }, /* R1278 */
1386 { 0x0000, 0x0000, 0x0000 }, /* R1279 */
1387 { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
1388 { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
1389 { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
1390 { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
1391 { 0x0000, 0x0000, 0x0000 }, /* R1284 */
1392 { 0x0000, 0x0000, 0x0000 }, /* R1285 */
1393 { 0x0000, 0x0000, 0x0000 }, /* R1286 */
1394 { 0x0000, 0x0000, 0x0000 }, /* R1287 */
1395 { 0x0000, 0x0000, 0x0000 }, /* R1288 */
1396 { 0x0000, 0x0000, 0x0000 }, /* R1289 */
1397 { 0x0000, 0x0000, 0x0000 }, /* R1290 */
1398 { 0x0000, 0x0000, 0x0000 }, /* R1291 */
1399 { 0x0000, 0x0000, 0x0000 }, /* R1292 */
1400 { 0x0000, 0x0000, 0x0000 }, /* R1293 */
1401 { 0x0000, 0x0000, 0x0000 }, /* R1294 */
1402 { 0x0000, 0x0000, 0x0000 }, /* R1295 */
1403 { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
1404 { 0x0000, 0x0000, 0x0000 }, /* R1297 */
1405 { 0x0000, 0x0000, 0x0000 }, /* R1298 */
1406 { 0x0000, 0x0000, 0x0000 }, /* R1299 */
1407 { 0x0000, 0x0000, 0x0000 }, /* R1300 */
1408 { 0x0000, 0x0000, 0x0000 }, /* R1301 */
1409 { 0x0000, 0x0000, 0x0000 }, /* R1302 */
1410 { 0x0000, 0x0000, 0x0000 }, /* R1303 */
1411 { 0x0000, 0x0000, 0x0000 }, /* R1304 */
1412 { 0x0000, 0x0000, 0x0000 }, /* R1305 */
1413 { 0x0000, 0x0000, 0x0000 }, /* R1306 */
1414 { 0x0000, 0x0000, 0x0000 }, /* R1307 */
1415 { 0x0000, 0x0000, 0x0000 }, /* R1308 */
1416 { 0x0000, 0x0000, 0x0000 }, /* R1309 */
1417 { 0x0000, 0x0000, 0x0000 }, /* R1310 */
1418 { 0x0000, 0x0000, 0x0000 }, /* R1311 */
1419 { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
1420 { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
1421 { 0x0000, 0x0000, 0x0000 }, /* R1314 */
1422 { 0x0000, 0x0000, 0x0000 }, /* R1315 */
1423 { 0x0000, 0x0000, 0x0000 }, /* R1316 */
1424 { 0x0000, 0x0000, 0x0000 }, /* R1317 */
1425 { 0x0000, 0x0000, 0x0000 }, /* R1318 */
1426 { 0x0000, 0x0000, 0x0000 }, /* R1319 */
1427 { 0x0000, 0x0000, 0x0000 }, /* R1320 */
1428 { 0x0000, 0x0000, 0x0000 }, /* R1321 */
1429 { 0x0000, 0x0000, 0x0000 }, /* R1322 */
1430 { 0x0000, 0x0000, 0x0000 }, /* R1323 */
1431 { 0x0000, 0x0000, 0x0000 }, /* R1324 */
1432 { 0x0000, 0x0000, 0x0000 }, /* R1325 */
1433 { 0x0000, 0x0000, 0x0000 }, /* R1326 */
1434 { 0x0000, 0x0000, 0x0000 }, /* R1327 */
1435 { 0x0000, 0x0000, 0x0000 }, /* R1328 */
1436 { 0x0000, 0x0000, 0x0000 }, /* R1329 */
1437 { 0x0000, 0x0000, 0x0000 }, /* R1330 */
1438 { 0x0000, 0x0000, 0x0000 }, /* R1331 */
1439 { 0x0000, 0x0000, 0x0000 }, /* R1332 */
1440 { 0x0000, 0x0000, 0x0000 }, /* R1333 */
1441 { 0x0000, 0x0000, 0x0000 }, /* R1334 */
1442 { 0x0000, 0x0000, 0x0000 }, /* R1335 */
1443 { 0x0000, 0x0000, 0x0000 }, /* R1336 */
1444 { 0x0000, 0x0000, 0x0000 }, /* R1337 */
1445 { 0x0000, 0x0000, 0x0000 }, /* R1338 */
1446 { 0x0000, 0x0000, 0x0000 }, /* R1339 */
1447 { 0x0000, 0x0000, 0x0000 }, /* R1340 */
1448 { 0x0000, 0x0000, 0x0000 }, /* R1341 */
1449 { 0x0000, 0x0000, 0x0000 }, /* R1342 */
1450 { 0x0000, 0x0000, 0x0000 }, /* R1343 */
1451 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
1452 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
1453 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
1454 { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
1455 { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
1456 { 0x0000, 0x0000, 0x0000 }, /* R1349 */
1457 { 0x0000, 0x0000, 0x0000 }, /* R1350 */
1458 { 0x0000, 0x0000, 0x0000 }, /* R1351 */
1459 { 0x0000, 0x0000, 0x0000 }, /* R1352 */
1460 { 0x0000, 0x0000, 0x0000 }, /* R1353 */
1461 { 0x0000, 0x0000, 0x0000 }, /* R1354 */
1462 { 0x0000, 0x0000, 0x0000 }, /* R1355 */
1463 { 0x0000, 0x0000, 0x0000 }, /* R1356 */
1464 { 0x0000, 0x0000, 0x0000 }, /* R1357 */
1465 { 0x0000, 0x0000, 0x0000 }, /* R1358 */
1466 { 0x0000, 0x0000, 0x0000 }, /* R1359 */
1467 { 0x0000, 0x0000, 0x0000 }, /* R1360 */
1468 { 0x0000, 0x0000, 0x0000 }, /* R1361 */
1469 { 0x0000, 0x0000, 0x0000 }, /* R1362 */
1470 { 0x0000, 0x0000, 0x0000 }, /* R1363 */
1471 { 0x0000, 0x0000, 0x0000 }, /* R1364 */
1472 { 0x0000, 0x0000, 0x0000 }, /* R1365 */
1473 { 0x0000, 0x0000, 0x0000 }, /* R1366 */
1474 { 0x0000, 0x0000, 0x0000 }, /* R1367 */
1475 { 0x0000, 0x0000, 0x0000 }, /* R1368 */
1476 { 0x0000, 0x0000, 0x0000 }, /* R1369 */
1477 { 0x0000, 0x0000, 0x0000 }, /* R1370 */
1478 { 0x0000, 0x0000, 0x0000 }, /* R1371 */
1479 { 0x0000, 0x0000, 0x0000 }, /* R1372 */
1480 { 0x0000, 0x0000, 0x0000 }, /* R1373 */
1481 { 0x0000, 0x0000, 0x0000 }, /* R1374 */
1482 { 0x0000, 0x0000, 0x0000 }, /* R1375 */
1483 { 0x0000, 0x0000, 0x0000 }, /* R1376 */
1484 { 0x0000, 0x0000, 0x0000 }, /* R1377 */
1485 { 0x0000, 0x0000, 0x0000 }, /* R1378 */
1486 { 0x0000, 0x0000, 0x0000 }, /* R1379 */
1487 { 0x0000, 0x0000, 0x0000 }, /* R1380 */
1488 { 0x0000, 0x0000, 0x0000 }, /* R1381 */
1489 { 0x0000, 0x0000, 0x0000 }, /* R1382 */
1490 { 0x0000, 0x0000, 0x0000 }, /* R1383 */
1491 { 0x0000, 0x0000, 0x0000 }, /* R1384 */
1492 { 0x0000, 0x0000, 0x0000 }, /* R1385 */
1493 { 0x0000, 0x0000, 0x0000 }, /* R1386 */
1494 { 0x0000, 0x0000, 0x0000 }, /* R1387 */
1495 { 0x0000, 0x0000, 0x0000 }, /* R1388 */
1496 { 0x0000, 0x0000, 0x0000 }, /* R1389 */
1497 { 0x0000, 0x0000, 0x0000 }, /* R1390 */
1498 { 0x0000, 0x0000, 0x0000 }, /* R1391 */
1499 { 0x0000, 0x0000, 0x0000 }, /* R1392 */
1500 { 0x0000, 0x0000, 0x0000 }, /* R1393 */
1501 { 0x0000, 0x0000, 0x0000 }, /* R1394 */
1502 { 0x0000, 0x0000, 0x0000 }, /* R1395 */
1503 { 0x0000, 0x0000, 0x0000 }, /* R1396 */
1504 { 0x0000, 0x0000, 0x0000 }, /* R1397 */
1505 { 0x0000, 0x0000, 0x0000 }, /* R1398 */
1506 { 0x0000, 0x0000, 0x0000 }, /* R1399 */
1507 { 0x0000, 0x0000, 0x0000 }, /* R1400 */
1508 { 0x0000, 0x0000, 0x0000 }, /* R1401 */
1509 { 0x0000, 0x0000, 0x0000 }, /* R1402 */
1510 { 0x0000, 0x0000, 0x0000 }, /* R1403 */
1511 { 0x0000, 0x0000, 0x0000 }, /* R1404 */
1512 { 0x0000, 0x0000, 0x0000 }, /* R1405 */
1513 { 0x0000, 0x0000, 0x0000 }, /* R1406 */
1514 { 0x0000, 0x0000, 0x0000 }, /* R1407 */
1515 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
1516 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
1517 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
1518 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
1519 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
1520 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
1521 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
1522 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
1523 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
1524 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
1525 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
1526 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
1527 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
1528 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
1529 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
1530 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
1531 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
1532 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
1533 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
1534 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
1535 { 0x0000, 0x0000, 0x0000 }, /* R1428 */
1536 { 0x0000, 0x0000, 0x0000 }, /* R1429 */
1537 { 0x0000, 0x0000, 0x0000 }, /* R1430 */
1538 { 0x0000, 0x0000, 0x0000 }, /* R1431 */
1539 { 0x0000, 0x0000, 0x0000 }, /* R1432 */
1540 { 0x0000, 0x0000, 0x0000 }, /* R1433 */
1541 { 0x0000, 0x0000, 0x0000 }, /* R1434 */
1542 { 0x0000, 0x0000, 0x0000 }, /* R1435 */
1543 { 0x0000, 0x0000, 0x0000 }, /* R1436 */
1544 { 0x0000, 0x0000, 0x0000 }, /* R1437 */
1545 { 0x0000, 0x0000, 0x0000 }, /* R1438 */
1546 { 0x0000, 0x0000, 0x0000 }, /* R1439 */
1547 { 0x0000, 0x0000, 0x0000 }, /* R1440 */
1548 { 0x0000, 0x0000, 0x0000 }, /* R1441 */
1549 { 0x0000, 0x0000, 0x0000 }, /* R1442 */
1550 { 0x0000, 0x0000, 0x0000 }, /* R1443 */
1551 { 0x0000, 0x0000, 0x0000 }, /* R1444 */
1552 { 0x0000, 0x0000, 0x0000 }, /* R1445 */
1553 { 0x0000, 0x0000, 0x0000 }, /* R1446 */
1554 { 0x0000, 0x0000, 0x0000 }, /* R1447 */
1555 { 0x0000, 0x0000, 0x0000 }, /* R1448 */
1556 { 0x0000, 0x0000, 0x0000 }, /* R1449 */
1557 { 0x0000, 0x0000, 0x0000 }, /* R1450 */
1558 { 0x0000, 0x0000, 0x0000 }, /* R1451 */
1559 { 0x0000, 0x0000, 0x0000 }, /* R1452 */
1560 { 0x0000, 0x0000, 0x0000 }, /* R1453 */
1561 { 0x0000, 0x0000, 0x0000 }, /* R1454 */
1562 { 0x0000, 0x0000, 0x0000 }, /* R1455 */
1563 { 0x0000, 0x0000, 0x0000 }, /* R1456 */
1564 { 0x0000, 0x0000, 0x0000 }, /* R1457 */
1565 { 0x0000, 0x0000, 0x0000 }, /* R1458 */
1566 { 0x0000, 0x0000, 0x0000 }, /* R1459 */
1567 { 0x0000, 0x0000, 0x0000 }, /* R1460 */
1568 { 0x0000, 0x0000, 0x0000 }, /* R1461 */
1569 { 0x0000, 0x0000, 0x0000 }, /* R1462 */
1570 { 0x0000, 0x0000, 0x0000 }, /* R1463 */
1571 { 0x0000, 0x0000, 0x0000 }, /* R1464 */
1572 { 0x0000, 0x0000, 0x0000 }, /* R1465 */
1573 { 0x0000, 0x0000, 0x0000 }, /* R1466 */
1574 { 0x0000, 0x0000, 0x0000 }, /* R1467 */
1575 { 0x0000, 0x0000, 0x0000 }, /* R1468 */
1576 { 0x0000, 0x0000, 0x0000 }, /* R1469 */
1577 { 0x0000, 0x0000, 0x0000 }, /* R1470 */
1578 { 0x0000, 0x0000, 0x0000 }, /* R1471 */
1579 { 0x0000, 0x0000, 0x0000 }, /* R1472 */
1580 { 0x0000, 0x0000, 0x0000 }, /* R1473 */
1581 { 0x0000, 0x0000, 0x0000 }, /* R1474 */
1582 { 0x0000, 0x0000, 0x0000 }, /* R1475 */
1583 { 0x0000, 0x0000, 0x0000 }, /* R1476 */
1584 { 0x0000, 0x0000, 0x0000 }, /* R1477 */
1585 { 0x0000, 0x0000, 0x0000 }, /* R1478 */
1586 { 0x0000, 0x0000, 0x0000 }, /* R1479 */
1587 { 0x0000, 0x0000, 0x0000 }, /* R1480 */
1588 { 0x0000, 0x0000, 0x0000 }, /* R1481 */
1589 { 0x0000, 0x0000, 0x0000 }, /* R1482 */
1590 { 0x0000, 0x0000, 0x0000 }, /* R1483 */
1591 { 0x0000, 0x0000, 0x0000 }, /* R1484 */
1592 { 0x0000, 0x0000, 0x0000 }, /* R1485 */
1593 { 0x0000, 0x0000, 0x0000 }, /* R1486 */
1594 { 0x0000, 0x0000, 0x0000 }, /* R1487 */
1595 { 0x0000, 0x0000, 0x0000 }, /* R1488 */
1596 { 0x0000, 0x0000, 0x0000 }, /* R1489 */
1597 { 0x0000, 0x0000, 0x0000 }, /* R1490 */
1598 { 0x0000, 0x0000, 0x0000 }, /* R1491 */
1599 { 0x0000, 0x0000, 0x0000 }, /* R1492 */
1600 { 0x0000, 0x0000, 0x0000 }, /* R1493 */
1601 { 0x0000, 0x0000, 0x0000 }, /* R1494 */
1602 { 0x0000, 0x0000, 0x0000 }, /* R1495 */
1603 { 0x0000, 0x0000, 0x0000 }, /* R1496 */
1604 { 0x0000, 0x0000, 0x0000 }, /* R1497 */
1605 { 0x0000, 0x0000, 0x0000 }, /* R1498 */
1606 { 0x0000, 0x0000, 0x0000 }, /* R1499 */
1607 { 0x0000, 0x0000, 0x0000 }, /* R1500 */
1608 { 0x0000, 0x0000, 0x0000 }, /* R1501 */
1609 { 0x0000, 0x0000, 0x0000 }, /* R1502 */
1610 { 0x0000, 0x0000, 0x0000 }, /* R1503 */
1611 { 0x0000, 0x0000, 0x0000 }, /* R1504 */
1612 { 0x0000, 0x0000, 0x0000 }, /* R1505 */
1613 { 0x0000, 0x0000, 0x0000 }, /* R1506 */
1614 { 0x0000, 0x0000, 0x0000 }, /* R1507 */
1615 { 0x0000, 0x0000, 0x0000 }, /* R1508 */
1616 { 0x0000, 0x0000, 0x0000 }, /* R1509 */
1617 { 0x0000, 0x0000, 0x0000 }, /* R1510 */
1618 { 0x0000, 0x0000, 0x0000 }, /* R1511 */
1619 { 0x0000, 0x0000, 0x0000 }, /* R1512 */
1620 { 0x0000, 0x0000, 0x0000 }, /* R1513 */
1621 { 0x0000, 0x0000, 0x0000 }, /* R1514 */
1622 { 0x0000, 0x0000, 0x0000 }, /* R1515 */
1623 { 0x0000, 0x0000, 0x0000 }, /* R1516 */
1624 { 0x0000, 0x0000, 0x0000 }, /* R1517 */
1625 { 0x0000, 0x0000, 0x0000 }, /* R1518 */
1626 { 0x0000, 0x0000, 0x0000 }, /* R1519 */
1627 { 0x0000, 0x0000, 0x0000 }, /* R1520 */
1628 { 0x0000, 0x0000, 0x0000 }, /* R1521 */
1629 { 0x0000, 0x0000, 0x0000 }, /* R1522 */
1630 { 0x0000, 0x0000, 0x0000 }, /* R1523 */
1631 { 0x0000, 0x0000, 0x0000 }, /* R1524 */
1632 { 0x0000, 0x0000, 0x0000 }, /* R1525 */
1633 { 0x0000, 0x0000, 0x0000 }, /* R1526 */
1634 { 0x0000, 0x0000, 0x0000 }, /* R1527 */
1635 { 0x0000, 0x0000, 0x0000 }, /* R1528 */
1636 { 0x0000, 0x0000, 0x0000 }, /* R1529 */
1637 { 0x0000, 0x0000, 0x0000 }, /* R1530 */
1638 { 0x0000, 0x0000, 0x0000 }, /* R1531 */
1639 { 0x0000, 0x0000, 0x0000 }, /* R1532 */
1640 { 0x0000, 0x0000, 0x0000 }, /* R1533 */
1641 { 0x0000, 0x0000, 0x0000 }, /* R1534 */
1642 { 0x0000, 0x0000, 0x0000 }, /* R1535 */
1643 { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
1644 { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
1645 { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
1646 { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
1647 { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
1648 { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
1649 { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1650 { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1651 { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1652 { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1653 { 0x0000, 0x0000, 0x0000 }, /* R1546 */
1654 { 0x0000, 0x0000, 0x0000 }, /* R1547 */
1655 { 0x0000, 0x0000, 0x0000 }, /* R1548 */
1656 { 0x0000, 0x0000, 0x0000 }, /* R1549 */
1657 { 0x0000, 0x0000, 0x0000 }, /* R1550 */
1658 { 0x0000, 0x0000, 0x0000 }, /* R1551 */
1659 { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
1660 { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
1661 { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
1662 { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
1663 { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
1664 { 0x0000, 0x0000, 0x0000 }, /* R1557 */
1665 { 0x0000, 0x0000, 0x0000 }, /* R1558 */
1666 { 0x0000, 0x0000, 0x0000 }, /* R1559 */
1667 { 0x0000, 0x0000, 0x0000 }, /* R1560 */
1668 { 0x0000, 0x0000, 0x0000 }, /* R1561 */
1669 { 0x0000, 0x0000, 0x0000 }, /* R1562 */
1670 { 0x0000, 0x0000, 0x0000 }, /* R1563 */
1671 { 0x0000, 0x0000, 0x0000 }, /* R1564 */
1672 { 0x0000, 0x0000, 0x0000 }, /* R1565 */
1673 { 0x0000, 0x0000, 0x0000 }, /* R1566 */
1674 { 0x0000, 0x0000, 0x0000 }, /* R1567 */
1675 { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
1676 { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
1677};
1678
1679static int wm8994_readable(unsigned int reg)
1680{ 57{
58 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
59 struct wm8994 *control = wm8994->control_data;
60
1681 switch (reg) { 61 switch (reg) {
1682 case WM8994_GPIO_1: 62 case WM8994_GPIO_1:
1683 case WM8994_GPIO_2: 63 case WM8994_GPIO_2:
@@ -1694,18 +74,27 @@ static int wm8994_readable(unsigned int reg)
1694 case WM8994_INTERRUPT_STATUS_2: 74 case WM8994_INTERRUPT_STATUS_2:
1695 case WM8994_INTERRUPT_RAW_STATUS_2: 75 case WM8994_INTERRUPT_RAW_STATUS_2:
1696 return 1; 76 return 1;
77
78 case WM8958_DSP2_PROGRAM:
79 case WM8958_DSP2_CONFIG:
80 case WM8958_DSP2_EXECCONTROL:
81 if (control->type == WM8958)
82 return 1;
83 else
84 return 0;
85
1697 default: 86 default:
1698 break; 87 break;
1699 } 88 }
1700 89
1701 if (reg >= ARRAY_SIZE(access_masks)) 90 if (reg >= WM8994_CACHE_SIZE)
1702 return 0; 91 return 0;
1703 return access_masks[reg].readable != 0; 92 return wm8994_access_masks[reg].readable != 0;
1704} 93}
1705 94
1706static int wm8994_volatile(unsigned int reg) 95static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg)
1707{ 96{
1708 if (reg >= WM8994_REG_CACHE_SIZE) 97 if (reg >= WM8994_CACHE_SIZE)
1709 return 1; 98 return 1;
1710 99
1711 switch (reg) { 100 switch (reg) {
@@ -1716,6 +105,8 @@ static int wm8994_volatile(unsigned int reg)
1716 case WM8994_RATE_STATUS: 105 case WM8994_RATE_STATUS:
1717 case WM8994_LDO_1: 106 case WM8994_LDO_1:
1718 case WM8994_LDO_2: 107 case WM8994_LDO_2:
108 case WM8958_DSP2_EXECCONTROL:
109 case WM8958_MIC_DETECT_3:
1719 return 1; 110 return 1;
1720 default: 111 default:
1721 return 0; 112 return 0;
@@ -1725,14 +116,16 @@ static int wm8994_volatile(unsigned int reg)
1725static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, 116static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1726 unsigned int value) 117 unsigned int value)
1727{ 118{
1728 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 119 int ret;
1729 120
1730 BUG_ON(reg > WM8994_MAX_REGISTER); 121 BUG_ON(reg > WM8994_MAX_REGISTER);
1731 122
1732 if (!wm8994_volatile(reg)) 123 if (!wm8994_volatile(codec, reg)) {
1733 wm8994->reg_cache[reg] = value; 124 ret = snd_soc_cache_write(codec, reg, value);
1734 125 if (ret != 0)
1735 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 126 dev_err(codec->dev, "Cache write to %x failed: %d\n",
127 reg, ret);
128 }
1736 129
1737 return wm8994_reg_write(codec->control_data, reg, value); 130 return wm8994_reg_write(codec->control_data, reg, value);
1738} 131}
@@ -1740,14 +133,22 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1740static unsigned int wm8994_read(struct snd_soc_codec *codec, 133static unsigned int wm8994_read(struct snd_soc_codec *codec,
1741 unsigned int reg) 134 unsigned int reg)
1742{ 135{
1743 u16 *reg_cache = codec->reg_cache; 136 unsigned int val;
137 int ret;
1744 138
1745 BUG_ON(reg > WM8994_MAX_REGISTER); 139 BUG_ON(reg > WM8994_MAX_REGISTER);
1746 140
1747 if (wm8994_volatile(reg)) 141 if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) &&
1748 return wm8994_reg_read(codec->control_data, reg); 142 reg < codec->driver->reg_cache_size) {
1749 else 143 ret = snd_soc_cache_read(codec, reg, &val);
1750 return reg_cache[reg]; 144 if (ret >= 0)
145 return val;
146 else
147 dev_err(codec->dev, "Cache read from %x failed: %d\n",
148 reg, ret);
149 }
150
151 return wm8994_reg_read(codec->control_data, reg);
1751} 152}
1752 153
1753static int configure_aif_clock(struct snd_soc_codec *codec, int aif) 154static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
@@ -1839,7 +240,7 @@ static int configure_clock(struct snd_soc_codec *codec)
1839 240
1840 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); 241 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1841 242
1842 snd_soc_dapm_sync(codec); 243 snd_soc_dapm_sync(&codec->dapm);
1843 244
1844 return 0; 245 return 0;
1845} 246}
@@ -1866,6 +267,19 @@ static const char *sidetone_hpf_text[] = {
1866static const struct soc_enum sidetone_hpf = 267static const struct soc_enum sidetone_hpf =
1867 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); 268 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1868 269
270static const char *adc_hpf_text[] = {
271 "HiFi", "Voice 1", "Voice 2", "Voice 3"
272};
273
274static const struct soc_enum aif1adc1_hpf =
275 SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text);
276
277static const struct soc_enum aif1adc2_hpf =
278 SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text);
279
280static const struct soc_enum aif2adc_hpf =
281 SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text);
282
1869static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); 283static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1870static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 284static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1871static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); 285static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
@@ -1902,8 +316,6 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1902 return snd_soc_put_volsw(kcontrol, ucontrol); 316 return snd_soc_put_volsw(kcontrol, ucontrol);
1903} 317}
1904 318
1905
1906
1907static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) 319static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1908{ 320{
1909 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 321 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1942,7 +354,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1942 struct snd_ctl_elem_value *ucontrol) 354 struct snd_ctl_elem_value *ucontrol)
1943{ 355{
1944 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 356 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1945 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 357 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1946 struct wm8994_pdata *pdata = wm8994->pdata; 358 struct wm8994_pdata *pdata = wm8994->pdata;
1947 int drc = wm8994_get_drc(kcontrol->id.name); 359 int drc = wm8994_get_drc(kcontrol->id.name);
1948 int value = ucontrol->value.integer.value[0]; 360 int value = ucontrol->value.integer.value[0];
@@ -2045,7 +457,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2045 struct snd_ctl_elem_value *ucontrol) 457 struct snd_ctl_elem_value *ucontrol)
2046{ 458{
2047 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 459 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2048 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 460 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2049 struct wm8994_pdata *pdata = wm8994->pdata; 461 struct wm8994_pdata *pdata = wm8994->pdata;
2050 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 462 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2051 int value = ucontrol->value.integer.value[0]; 463 int value = ucontrol->value.integer.value[0];
@@ -2075,6 +487,44 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2075 return 0; 487 return 0;
2076} 488}
2077 489
490static const char *aif_chan_src_text[] = {
491 "Left", "Right"
492};
493
494static const struct soc_enum aif1adcl_src =
495 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text);
496
497static const struct soc_enum aif1adcr_src =
498 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text);
499
500static const struct soc_enum aif2adcl_src =
501 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text);
502
503static const struct soc_enum aif2adcr_src =
504 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text);
505
506static const struct soc_enum aif1dacl_src =
507 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text);
508
509static const struct soc_enum aif1dacr_src =
510 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text);
511
512static const struct soc_enum aif2dacl_src =
513 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text);
514
515static const struct soc_enum aif2dacr_src =
516 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);
517
518static const char *osr_text[] = {
519 "Low Power", "High Performance",
520};
521
522static const struct soc_enum dac_osr =
523 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);
524
525static const struct soc_enum adc_osr =
526 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
527
2078static const struct snd_kcontrol_new wm8994_snd_controls[] = { 528static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2079SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, 529SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
2080 WM8994_AIF1_ADC1_RIGHT_VOLUME, 530 WM8994_AIF1_ADC1_RIGHT_VOLUME,
@@ -2086,6 +536,16 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2086 WM8994_AIF2_ADC_RIGHT_VOLUME, 536 WM8994_AIF2_ADC_RIGHT_VOLUME,
2087 1, 119, 0, digital_tlv), 537 1, 119, 0, digital_tlv),
2088 538
539SOC_ENUM("AIF1ADCL Source", aif1adcl_src),
540SOC_ENUM("AIF1ADCR Source", aif1adcr_src),
541SOC_ENUM("AIF2ADCL Source", aif2adcl_src),
542SOC_ENUM("AIF2ADCR Source", aif2adcr_src),
543
544SOC_ENUM("AIF1DACL Source", aif1dacl_src),
545SOC_ENUM("AIF1DACR Source", aif1dacr_src),
546SOC_ENUM("AIF2DACL Source", aif2dacl_src),
547SOC_ENUM("AIF2DACR Source", aif2dacr_src),
548
2089SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME, 549SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2090 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), 550 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2091SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME, 551SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
@@ -2123,6 +583,18 @@ SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2123SOC_ENUM("Sidetone HPF Mux", sidetone_hpf), 583SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2124SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0), 584SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2125 585
586SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
587SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
588
589SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
590SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
591
592SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
593SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
594
595SOC_ENUM("ADC OSR", adc_osr),
596SOC_ENUM("DAC OSR", dac_osr),
597
2126SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME, 598SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2127 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), 599 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2128SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME, 600SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
@@ -2145,15 +617,15 @@ SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2145 617
2146SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, 618SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2147 10, 15, 0, wm8994_3d_tlv), 619 10, 15, 0, wm8994_3d_tlv),
2148SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 620SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC1_FILTERS_2,
2149 8, 1, 0), 621 8, 1, 0),
2150SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2, 622SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2151 10, 15, 0, wm8994_3d_tlv), 623 10, 15, 0, wm8994_3d_tlv),
2152SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 624SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2153 8, 1, 0), 625 8, 1, 0),
2154SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, 626SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF2_DAC_FILTERS_2,
2155 10, 15, 0, wm8994_3d_tlv), 627 10, 15, 0, wm8994_3d_tlv),
2156SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 628SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2,
2157 8, 1, 0), 629 8, 1, 0),
2158}; 630};
2159 631
@@ -2192,6 +664,10 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2192 eq_tlv), 664 eq_tlv),
2193}; 665};
2194 666
667static const struct snd_kcontrol_new wm8958_snd_controls[] = {
668SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
669};
670
2195static int clk_sys_event(struct snd_soc_dapm_widget *w, 671static int clk_sys_event(struct snd_soc_dapm_widget *w,
2196 struct snd_kcontrol *kcontrol, int event) 672 struct snd_kcontrol *kcontrol, int event)
2197{ 673{
@@ -2211,6 +687,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
2211 687
2212static void wm8994_update_class_w(struct snd_soc_codec *codec) 688static void wm8994_update_class_w(struct snd_soc_codec *codec)
2213{ 689{
690 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2214 int enable = 1; 691 int enable = 1;
2215 int source = 0; /* GCC flow analysis can't track enable */ 692 int source = 0; /* GCC flow analysis can't track enable */
2216 int reg, reg_r; 693 int reg, reg_r;
@@ -2261,12 +738,128 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
2261 WM8994_CP_DYN_PWR | 738 WM8994_CP_DYN_PWR |
2262 WM8994_CP_DYN_SRC_SEL_MASK, 739 WM8994_CP_DYN_SRC_SEL_MASK,
2263 source | WM8994_CP_DYN_PWR); 740 source | WM8994_CP_DYN_PWR);
741 wm8994->hubs.class_w = true;
2264 742
2265 } else { 743 } else {
2266 dev_dbg(codec->dev, "Class W disabled\n"); 744 dev_dbg(codec->dev, "Class W disabled\n");
2267 snd_soc_update_bits(codec, WM8994_CLASS_W_1, 745 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2268 WM8994_CP_DYN_PWR, 0); 746 WM8994_CP_DYN_PWR, 0);
747 wm8994->hubs.class_w = false;
748 }
749}
750
751static int late_enable_ev(struct snd_soc_dapm_widget *w,
752 struct snd_kcontrol *kcontrol, int event)
753{
754 struct snd_soc_codec *codec = w->codec;
755 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
756
757 switch (event) {
758 case SND_SOC_DAPM_PRE_PMU:
759 if (wm8994->aif1clk_enable) {
760 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
761 WM8994_AIF1CLK_ENA_MASK,
762 WM8994_AIF1CLK_ENA);
763 wm8994->aif1clk_enable = 0;
764 }
765 if (wm8994->aif2clk_enable) {
766 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
767 WM8994_AIF2CLK_ENA_MASK,
768 WM8994_AIF2CLK_ENA);
769 wm8994->aif2clk_enable = 0;
770 }
771 break;
772 }
773
774 /* We may also have postponed startup of DSP, handle that. */
775 wm8958_aif_ev(w, kcontrol, event);
776
777 return 0;
778}
779
780static int late_disable_ev(struct snd_soc_dapm_widget *w,
781 struct snd_kcontrol *kcontrol, int event)
782{
783 struct snd_soc_codec *codec = w->codec;
784 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
785
786 switch (event) {
787 case SND_SOC_DAPM_POST_PMD:
788 if (wm8994->aif1clk_disable) {
789 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
790 WM8994_AIF1CLK_ENA_MASK, 0);
791 wm8994->aif1clk_disable = 0;
792 }
793 if (wm8994->aif2clk_disable) {
794 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
795 WM8994_AIF2CLK_ENA_MASK, 0);
796 wm8994->aif2clk_disable = 0;
797 }
798 break;
799 }
800
801 return 0;
802}
803
804static int aif1clk_ev(struct snd_soc_dapm_widget *w,
805 struct snd_kcontrol *kcontrol, int event)
806{
807 struct snd_soc_codec *codec = w->codec;
808 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
809
810 switch (event) {
811 case SND_SOC_DAPM_PRE_PMU:
812 wm8994->aif1clk_enable = 1;
813 break;
814 case SND_SOC_DAPM_POST_PMD:
815 wm8994->aif1clk_disable = 1;
816 break;
817 }
818
819 return 0;
820}
821
822static int aif2clk_ev(struct snd_soc_dapm_widget *w,
823 struct snd_kcontrol *kcontrol, int event)
824{
825 struct snd_soc_codec *codec = w->codec;
826 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
827
828 switch (event) {
829 case SND_SOC_DAPM_PRE_PMU:
830 wm8994->aif2clk_enable = 1;
831 break;
832 case SND_SOC_DAPM_POST_PMD:
833 wm8994->aif2clk_disable = 1;
834 break;
2269 } 835 }
836
837 return 0;
838}
839
840static int adc_mux_ev(struct snd_soc_dapm_widget *w,
841 struct snd_kcontrol *kcontrol, int event)
842{
843 late_enable_ev(w, kcontrol, event);
844 return 0;
845}
846
847static int micbias_ev(struct snd_soc_dapm_widget *w,
848 struct snd_kcontrol *kcontrol, int event)
849{
850 late_enable_ev(w, kcontrol, event);
851 return 0;
852}
853
854static int dac_ev(struct snd_soc_dapm_widget *w,
855 struct snd_kcontrol *kcontrol, int event)
856{
857 struct snd_soc_codec *codec = w->codec;
858 unsigned int mask = 1 << w->shift;
859
860 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
861 mask, mask);
862 return 0;
2270} 863}
2271 864
2272static const char *hp_mux_text[] = { 865static const char *hp_mux_text[] = {
@@ -2284,7 +877,8 @@ static const char *hp_mux_text[] = {
2284static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol, 877static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
2285 struct snd_ctl_elem_value *ucontrol) 878 struct snd_ctl_elem_value *ucontrol)
2286{ 879{
2287 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 880 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
881 struct snd_soc_dapm_widget *w = wlist->widgets[0];
2288 struct snd_soc_codec *codec = w->codec; 882 struct snd_soc_codec *codec = w->codec;
2289 int ret; 883 int ret;
2290 884
@@ -2411,7 +1005,8 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2411static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1005static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
2412 struct snd_ctl_elem_value *ucontrol) 1006 struct snd_ctl_elem_value *ucontrol)
2413{ 1007{
2414 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); 1008 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1009 struct snd_soc_dapm_widget *w = wlist->widgets[0];
2415 struct snd_soc_codec *codec = w->codec; 1010 struct snd_soc_codec *codec = w->codec;
2416 int ret; 1011 int ret;
2417 1012
@@ -2495,20 +1090,109 @@ static const struct snd_kcontrol_new aif2adc_mux =
2495 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); 1090 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2496 1091
2497static const char *aif3adc_text[] = { 1092static const char *aif3adc_text[] = {
2498 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", 1093 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
2499}; 1094};
2500 1095
2501static const struct soc_enum aif3adc_enum = 1096static const struct soc_enum wm8994_aif3adc_enum =
2502 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); 1097 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2503 1098
2504static const struct snd_kcontrol_new aif3adc_mux = 1099static const struct snd_kcontrol_new wm8994_aif3adc_mux =
2505 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum); 1100 SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
1101
1102static const struct soc_enum wm8958_aif3adc_enum =
1103 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
1104
1105static const struct snd_kcontrol_new wm8958_aif3adc_mux =
1106 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
1107
1108static const char *mono_pcm_out_text[] = {
1109 "None", "AIF2ADCL", "AIF2ADCR",
1110};
1111
1112static const struct soc_enum mono_pcm_out_enum =
1113 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
1114
1115static const struct snd_kcontrol_new mono_pcm_out_mux =
1116 SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
1117
1118static const char *aif2dac_src_text[] = {
1119 "AIF2", "AIF3",
1120};
1121
1122/* Note that these two control shouldn't be simultaneously switched to AIF3 */
1123static const struct soc_enum aif2dacl_src_enum =
1124 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
1125
1126static const struct snd_kcontrol_new aif2dacl_src_mux =
1127 SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
1128
1129static const struct soc_enum aif2dacr_src_enum =
1130 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
1131
1132static const struct snd_kcontrol_new aif2dacr_src_mux =
1133 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
1134
1135static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = {
1136SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev,
1137 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1138SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev,
1139 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1140
1141SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1142 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1143SND_SOC_DAPM_PGA_E("Late DAC1R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1144 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1145SND_SOC_DAPM_PGA_E("Late DAC2L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1146 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1147SND_SOC_DAPM_PGA_E("Late DAC2R Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
1148 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1149
1150SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
1151};
1152
1153static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = {
1154SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
1155SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0)
1156};
1157
1158static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
1159SND_SOC_DAPM_DAC_E("DAC2L", NULL, SND_SOC_NOPM, 3, 0,
1160 dac_ev, SND_SOC_DAPM_PRE_PMU),
1161SND_SOC_DAPM_DAC_E("DAC2R", NULL, SND_SOC_NOPM, 2, 0,
1162 dac_ev, SND_SOC_DAPM_PRE_PMU),
1163SND_SOC_DAPM_DAC_E("DAC1L", NULL, SND_SOC_NOPM, 1, 0,
1164 dac_ev, SND_SOC_DAPM_PRE_PMU),
1165SND_SOC_DAPM_DAC_E("DAC1R", NULL, SND_SOC_NOPM, 0, 0,
1166 dac_ev, SND_SOC_DAPM_PRE_PMU),
1167};
1168
1169static const struct snd_soc_dapm_widget wm8994_dac_widgets[] = {
1170SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
1171SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
1172SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
1173SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
1174};
1175
1176static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = {
1177SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux,
1178 adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
1179SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux,
1180 adc_mux_ev, SND_SOC_DAPM_PRE_PMU),
1181};
1182
1183static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = {
1184SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
1185SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
1186};
2506 1187
2507static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 1188static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2508SND_SOC_DAPM_INPUT("DMIC1DAT"), 1189SND_SOC_DAPM_INPUT("DMIC1DAT"),
2509SND_SOC_DAPM_INPUT("DMIC2DAT"), 1190SND_SOC_DAPM_INPUT("DMIC2DAT"),
2510SND_SOC_DAPM_INPUT("Clock"), 1191SND_SOC_DAPM_INPUT("Clock"),
2511 1192
1193SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
1194 SND_SOC_DAPM_PRE_PMU),
1195
2512SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, 1196SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2513 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1197 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2514 1198
@@ -2516,26 +1200,27 @@ SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
2516SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), 1200SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
2517SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), 1201SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
2518 1202
2519SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), 1203SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL,
2520SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
2521
2522SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2523 0, WM8994_POWER_MANAGEMENT_4, 9, 0), 1204 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2524SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 1205SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL,
2525 0, WM8994_POWER_MANAGEMENT_4, 8, 0), 1206 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2526SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, 1207SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
2527 WM8994_POWER_MANAGEMENT_5, 9, 0), 1208 WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
2528SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, 1209 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2529 WM8994_POWER_MANAGEMENT_5, 8, 0), 1210SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
2530 1211 WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
2531SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", 1212 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1213
1214SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL,
2532 0, WM8994_POWER_MANAGEMENT_4, 11, 0), 1215 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2533SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 1216SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL,
2534 0, WM8994_POWER_MANAGEMENT_4, 10, 0), 1217 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2535SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, 1218SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
2536 WM8994_POWER_MANAGEMENT_5, 11, 0), 1219 WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
2537SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, 1220 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2538 WM8994_POWER_MANAGEMENT_5, 10, 0), 1221SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
1222 WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev,
1223 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2539 1224
2540SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, 1225SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2541 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)), 1226 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
@@ -2564,19 +1249,21 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2564 WM8994_POWER_MANAGEMENT_4, 13, 0), 1249 WM8994_POWER_MANAGEMENT_4, 13, 0),
2565SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, 1250SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2566 WM8994_POWER_MANAGEMENT_4, 12, 0), 1251 WM8994_POWER_MANAGEMENT_4, 12, 0),
2567SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0, 1252SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
2568 WM8994_POWER_MANAGEMENT_5, 13, 0), 1253 WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev,
2569SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0, 1254 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2570 WM8994_POWER_MANAGEMENT_5, 12, 0), 1255SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
1256 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
1257 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2571 1258
2572SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1259SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2573SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 1260SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
1261SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
2574SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 1262SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2575 1263
2576SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1264SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2577SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), 1265SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2578SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1266SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2579SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2580 1267
2581SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1268SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2582SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1269SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
@@ -2595,14 +1282,6 @@ SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
2595SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0), 1282SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
2596SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), 1283SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
2597 1284
2598SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
2599SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
2600
2601SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
2602SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
2603SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
2604SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
2605
2606SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), 1285SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
2607SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), 1286SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
2608 1287
@@ -2614,8 +1293,18 @@ SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2614SND_SOC_DAPM_POST("Debug log", post_ev), 1293SND_SOC_DAPM_POST("Debug log", post_ev),
2615}; 1294};
2616 1295
2617static const struct snd_soc_dapm_route intercon[] = { 1296static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
1297SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
1298};
1299
1300static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
1301SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
1302SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
1303SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
1304SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux),
1305};
2618 1306
1307static const struct snd_soc_dapm_route intercon[] = {
2619 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys }, 1308 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2620 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys }, 1309 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2621 1310
@@ -2723,9 +1412,6 @@ static const struct snd_soc_dapm_route intercon[] = {
2723 { "AIF1DAC2L", NULL, "AIF1DAC Mux" }, 1412 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2724 { "AIF1DAC2R", NULL, "AIF1DAC Mux" }, 1413 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2725 1414
2726 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2727 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2728
2729 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" }, 1415 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2730 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, 1416 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2731 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" }, 1417 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
@@ -2735,14 +1421,12 @@ static const struct snd_soc_dapm_route intercon[] = {
2735 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" }, 1421 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
2736 1422
2737 /* DAC1 inputs */ 1423 /* DAC1 inputs */
2738 { "DAC1L", NULL, "DAC1L Mixer" },
2739 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" }, 1424 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2740 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, 1425 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2741 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, 1426 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2742 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, 1427 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2743 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1428 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2744 1429
2745 { "DAC1R", NULL, "DAC1R Mixer" },
2746 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" }, 1430 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2747 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, 1431 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2748 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, 1432 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
@@ -2751,7 +1435,6 @@ static const struct snd_soc_dapm_route intercon[] = {
2751 1435
2752 /* DAC2/AIF2 outputs */ 1436 /* DAC2/AIF2 outputs */
2753 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" }, 1437 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
2754 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
2755 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" }, 1438 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2756 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, 1439 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2757 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, 1440 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
@@ -2759,13 +1442,17 @@ static const struct snd_soc_dapm_route intercon[] = {
2759 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1442 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2760 1443
2761 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" }, 1444 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
2762 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
2763 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" }, 1445 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2764 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, 1446 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2765 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, 1447 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2766 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, 1448 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2767 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, 1449 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2768 1450
1451 { "AIF1ADCDAT", NULL, "AIF1ADC1L" },
1452 { "AIF1ADCDAT", NULL, "AIF1ADC1R" },
1453 { "AIF1ADCDAT", NULL, "AIF1ADC2L" },
1454 { "AIF1ADCDAT", NULL, "AIF1ADC2R" },
1455
2769 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" }, 1456 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
2770 1457
2771 /* AIF3 output */ 1458 /* AIF3 output */
@@ -2798,6 +1485,55 @@ static const struct snd_soc_dapm_route intercon[] = {
2798 { "Right Headphone Mux", "DAC", "DAC1R" }, 1485 { "Right Headphone Mux", "DAC", "DAC1R" },
2799}; 1486};
2800 1487
1488static const struct snd_soc_dapm_route wm8994_lateclk_revd_intercon[] = {
1489 { "DAC1L", NULL, "Late DAC1L Enable PGA" },
1490 { "Late DAC1L Enable PGA", NULL, "DAC1L Mixer" },
1491 { "DAC1R", NULL, "Late DAC1R Enable PGA" },
1492 { "Late DAC1R Enable PGA", NULL, "DAC1R Mixer" },
1493 { "DAC2L", NULL, "Late DAC2L Enable PGA" },
1494 { "Late DAC2L Enable PGA", NULL, "AIF2DAC2L Mixer" },
1495 { "DAC2R", NULL, "Late DAC2R Enable PGA" },
1496 { "Late DAC2R Enable PGA", NULL, "AIF2DAC2R Mixer" }
1497};
1498
1499static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = {
1500 { "DAC1L", NULL, "DAC1L Mixer" },
1501 { "DAC1R", NULL, "DAC1R Mixer" },
1502 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
1503 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
1504};
1505
1506static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
1507 { "AIF1DACDAT", NULL, "AIF2DACDAT" },
1508 { "AIF2DACDAT", NULL, "AIF1DACDAT" },
1509 { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
1510 { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
1511 { "MICBIAS1", NULL, "CLK_SYS" },
1512 { "MICBIAS1", NULL, "MICBIAS Supply" },
1513 { "MICBIAS2", NULL, "CLK_SYS" },
1514 { "MICBIAS2", NULL, "MICBIAS Supply" },
1515};
1516
1517static const struct snd_soc_dapm_route wm8994_intercon[] = {
1518 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1519 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1520};
1521
1522static const struct snd_soc_dapm_route wm8958_intercon[] = {
1523 { "AIF2DACL", NULL, "AIF2DACL Mux" },
1524 { "AIF2DACR", NULL, "AIF2DACR Mux" },
1525
1526 { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" },
1527 { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" },
1528 { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
1529 { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
1530
1531 { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
1532 { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
1533
1534 { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
1535};
1536
2801/* The size in bits of the FLL divide multiplied by 10 1537/* The size in bits of the FLL divide multiplied by 10
2802 * to allow rounding later */ 1538 * to allow rounding later */
2803#define FIXED_FLL_SIZE ((1 << 16) * 10) 1539#define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -2881,10 +1617,9 @@ static int wm8994_get_fll_config(struct fll_div *fll,
2881 return 0; 1617 return 0;
2882} 1618}
2883 1619
2884static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, 1620static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2885 unsigned int freq_in, unsigned int freq_out) 1621 unsigned int freq_in, unsigned int freq_out)
2886{ 1622{
2887 struct snd_soc_codec *codec = dai->codec;
2888 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1623 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2889 int reg_offset, ret; 1624 int reg_offset, ret;
2890 struct fll_div fll; 1625 struct fll_div fll;
@@ -2914,6 +1649,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2914 /* Allow no source specification when stopping */ 1649 /* Allow no source specification when stopping */
2915 if (freq_out) 1650 if (freq_out)
2916 return -EINVAL; 1651 return -EINVAL;
1652 src = wm8994->fll[id].src;
2917 break; 1653 break;
2918 case WM8994_FLL_SRC_MCLK1: 1654 case WM8994_FLL_SRC_MCLK1:
2919 case WM8994_FLL_SRC_MCLK2: 1655 case WM8994_FLL_SRC_MCLK2:
@@ -2978,6 +1714,8 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2978 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, 1714 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2979 WM8994_FLL1_ENA | WM8994_FLL1_FRAC, 1715 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
2980 reg); 1716 reg);
1717
1718 msleep(5);
2981 } 1719 }
2982 1720
2983 wm8994->fll[id].in = freq_in; 1721 wm8994->fll[id].in = freq_in;
@@ -2995,8 +1733,15 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2995 return 0; 1733 return 0;
2996} 1734}
2997 1735
1736
2998static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 }; 1737static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
2999 1738
1739static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
1740 unsigned int freq_in, unsigned int freq_out)
1741{
1742 return _wm8994_set_fll(dai->codec, id, src, freq_in, freq_out);
1743}
1744
3000static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, 1745static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
3001 int clk_id, unsigned int freq, int dir) 1746 int clk_id, unsigned int freq, int dir)
3002{ 1747{
@@ -3071,6 +1816,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
3071static int wm8994_set_bias_level(struct snd_soc_codec *codec, 1816static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3072 enum snd_soc_bias_level level) 1817 enum snd_soc_bias_level level)
3073{ 1818{
1819 struct wm8994 *control = codec->control_data;
3074 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1820 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3075 1821
3076 switch (level) { 1822 switch (level) {
@@ -3084,16 +1830,36 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3084 break; 1830 break;
3085 1831
3086 case SND_SOC_BIAS_STANDBY: 1832 case SND_SOC_BIAS_STANDBY:
3087 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1833 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
3088 /* Tweak DC servo and DSP configuration for 1834 pm_runtime_get_sync(codec->dev);
3089 * improved performance. */ 1835
3090 if (wm8994->revision < 4) { 1836 switch (control->type) {
3091 /* Tweak DC servo and DSP configuration for 1837 case WM8994:
3092 * improved performance. */ 1838 if (wm8994->revision < 4) {
3093 snd_soc_write(codec, 0x102, 0x3); 1839 /* Tweak DC servo and DSP
3094 snd_soc_write(codec, 0x56, 0x3); 1840 * configuration for improved
3095 snd_soc_write(codec, 0x817, 0); 1841 * performance. */
3096 snd_soc_write(codec, 0x102, 0); 1842 snd_soc_write(codec, 0x102, 0x3);
1843 snd_soc_write(codec, 0x56, 0x3);
1844 snd_soc_write(codec, 0x817, 0);
1845 snd_soc_write(codec, 0x102, 0);
1846 }
1847 break;
1848
1849 case WM8958:
1850 if (wm8994->revision == 0) {
1851 /* Optimise performance for rev A */
1852 snd_soc_write(codec, 0x102, 0x3);
1853 snd_soc_write(codec, 0xcb, 0x81);
1854 snd_soc_write(codec, 0x817, 0);
1855 snd_soc_write(codec, 0x102, 0);
1856
1857 snd_soc_update_bits(codec,
1858 WM8958_CHARGE_PUMP_2,
1859 WM8958_CP_DISCH,
1860 WM8958_CP_DISCH);
1861 }
1862 break;
3097 } 1863 }
3098 1864
3099 /* Discharge LINEOUT1 & 2 */ 1865 /* Discharge LINEOUT1 & 2 */
@@ -3128,7 +1894,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3128 break; 1894 break;
3129 1895
3130 case SND_SOC_BIAS_OFF: 1896 case SND_SOC_BIAS_OFF:
3131 if (codec->bias_level == SND_SOC_BIAS_STANDBY) { 1897 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
3132 /* Switch over to startup biases */ 1898 /* Switch over to startup biases */
3133 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 1899 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3134 WM8994_BIAS_SRC | 1900 WM8994_BIAS_SRC |
@@ -3160,16 +1926,21 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3160 WM8994_STARTUP_BIAS_ENA | 1926 WM8994_STARTUP_BIAS_ENA |
3161 WM8994_VMID_BUF_ENA | 1927 WM8994_VMID_BUF_ENA |
3162 WM8994_VMID_RAMP_MASK, 0); 1928 WM8994_VMID_RAMP_MASK, 0);
1929
1930 wm8994->cur_fw = NULL;
1931
1932 pm_runtime_put(codec->dev);
3163 } 1933 }
3164 break; 1934 break;
3165 } 1935 }
3166 codec->bias_level = level; 1936 codec->dapm.bias_level = level;
3167 return 0; 1937 return 0;
3168} 1938}
3169 1939
3170static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1940static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3171{ 1941{
3172 struct snd_soc_codec *codec = dai->codec; 1942 struct snd_soc_codec *codec = dai->codec;
1943 struct wm8994 *control = codec->control_data;
3173 int ms_reg; 1944 int ms_reg;
3174 int aif1_reg; 1945 int aif1_reg;
3175 int ms = 0; 1946 int ms = 0;
@@ -3254,6 +2025,13 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3254 return -EINVAL; 2025 return -EINVAL;
3255 } 2026 }
3256 2027
2028 /* The AIF2 format configuration needs to be mirrored to AIF3
2029 * on WM8958 if it's in use so just do it all the time. */
2030 if (control->type == WM8958 && dai->id == 2)
2031 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
2032 WM8994_AIF1_LRCLK_INV |
2033 WM8958_AIF3_FMT_MASK, aif1);
2034
3257 snd_soc_update_bits(codec, aif1_reg, 2035 snd_soc_update_bits(codec, aif1_reg,
3258 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | 2036 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3259 WM8994_AIF1_FMT_MASK, 2037 WM8994_AIF1_FMT_MASK,
@@ -3294,12 +2072,15 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3294 struct snd_soc_dai *dai) 2072 struct snd_soc_dai *dai)
3295{ 2073{
3296 struct snd_soc_codec *codec = dai->codec; 2074 struct snd_soc_codec *codec = dai->codec;
2075 struct wm8994 *control = codec->control_data;
3297 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2076 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3298 int aif1_reg; 2077 int aif1_reg;
2078 int aif2_reg;
3299 int bclk_reg; 2079 int bclk_reg;
3300 int lrclk_reg; 2080 int lrclk_reg;
3301 int rate_reg; 2081 int rate_reg;
3302 int aif1 = 0; 2082 int aif1 = 0;
2083 int aif2 = 0;
3303 int bclk = 0; 2084 int bclk = 0;
3304 int lrclk = 0; 2085 int lrclk = 0;
3305 int rate_val = 0; 2086 int rate_val = 0;
@@ -3310,24 +2091,38 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3310 switch (dai->id) { 2091 switch (dai->id) {
3311 case 1: 2092 case 1:
3312 aif1_reg = WM8994_AIF1_CONTROL_1; 2093 aif1_reg = WM8994_AIF1_CONTROL_1;
2094 aif2_reg = WM8994_AIF1_CONTROL_2;
3313 bclk_reg = WM8994_AIF1_BCLK; 2095 bclk_reg = WM8994_AIF1_BCLK;
3314 rate_reg = WM8994_AIF1_RATE; 2096 rate_reg = WM8994_AIF1_RATE;
3315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || 2097 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3316 wm8994->lrclk_shared[0]) 2098 wm8994->lrclk_shared[0]) {
3317 lrclk_reg = WM8994_AIF1DAC_LRCLK; 2099 lrclk_reg = WM8994_AIF1DAC_LRCLK;
3318 else 2100 } else {
3319 lrclk_reg = WM8994_AIF1ADC_LRCLK; 2101 lrclk_reg = WM8994_AIF1ADC_LRCLK;
2102 dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
2103 }
3320 break; 2104 break;
3321 case 2: 2105 case 2:
3322 aif1_reg = WM8994_AIF2_CONTROL_1; 2106 aif1_reg = WM8994_AIF2_CONTROL_1;
2107 aif2_reg = WM8994_AIF2_CONTROL_2;
3323 bclk_reg = WM8994_AIF2_BCLK; 2108 bclk_reg = WM8994_AIF2_BCLK;
3324 rate_reg = WM8994_AIF2_RATE; 2109 rate_reg = WM8994_AIF2_RATE;
3325 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || 2110 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3326 wm8994->lrclk_shared[1]) 2111 wm8994->lrclk_shared[1]) {
3327 lrclk_reg = WM8994_AIF2DAC_LRCLK; 2112 lrclk_reg = WM8994_AIF2DAC_LRCLK;
3328 else 2113 } else {
3329 lrclk_reg = WM8994_AIF2ADC_LRCLK; 2114 lrclk_reg = WM8994_AIF2ADC_LRCLK;
2115 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
2116 }
3330 break; 2117 break;
2118 case 3:
2119 switch (control->type) {
2120 case WM8958:
2121 aif1_reg = WM8958_AIF3_CONTROL_1;
2122 break;
2123 default:
2124 return 0;
2125 }
3331 default: 2126 default:
3332 return -EINVAL; 2127 return -EINVAL;
3333 } 2128 }
@@ -3365,6 +2160,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3365 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", 2160 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3366 dai->id, wm8994->aifclk[id], bclk_rate); 2161 dai->id, wm8994->aifclk[id], bclk_rate);
3367 2162
2163 if (params_channels(params) == 1 &&
2164 (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18)
2165 aif2 |= WM8994_AIF1_MONO;
2166
3368 if (wm8994->aifclk[id] == 0) { 2167 if (wm8994->aifclk[id] == 0) {
3369 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id); 2168 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3370 return -EINVAL; 2169 return -EINVAL;
@@ -3408,6 +2207,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3408 lrclk, bclk_rate / lrclk); 2207 lrclk, bclk_rate / lrclk);
3409 2208
3410 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); 2209 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2210 snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2);
3411 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk); 2211 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3412 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK, 2212 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3413 lrclk); 2213 lrclk);
@@ -3431,6 +2231,47 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3431 return 0; 2231 return 0;
3432} 2232}
3433 2233
2234static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2235 struct snd_pcm_hw_params *params,
2236 struct snd_soc_dai *dai)
2237{
2238 struct snd_soc_codec *codec = dai->codec;
2239 struct wm8994 *control = codec->control_data;
2240 int aif1_reg;
2241 int aif1 = 0;
2242
2243 switch (dai->id) {
2244 case 3:
2245 switch (control->type) {
2246 case WM8958:
2247 aif1_reg = WM8958_AIF3_CONTROL_1;
2248 break;
2249 default:
2250 return 0;
2251 }
2252 default:
2253 return 0;
2254 }
2255
2256 switch (params_format(params)) {
2257 case SNDRV_PCM_FORMAT_S16_LE:
2258 break;
2259 case SNDRV_PCM_FORMAT_S20_3LE:
2260 aif1 |= 0x20;
2261 break;
2262 case SNDRV_PCM_FORMAT_S24_LE:
2263 aif1 |= 0x40;
2264 break;
2265 case SNDRV_PCM_FORMAT_S32_LE:
2266 aif1 |= 0x60;
2267 break;
2268 default:
2269 return -EINVAL;
2270 }
2271
2272 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2273}
2274
3434static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2275static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3435{ 2276{
3436 struct snd_soc_codec *codec = codec_dai->codec; 2277 struct snd_soc_codec *codec = codec_dai->codec;
@@ -3485,13 +2326,13 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
3485 else 2326 else
3486 val = 0; 2327 val = 0;
3487 2328
3488 return snd_soc_update_bits(codec, reg, mask, reg); 2329 return snd_soc_update_bits(codec, reg, mask, val);
3489} 2330}
3490 2331
3491#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 2332#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3492 2333
3493#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 2334#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3494 SNDRV_PCM_FMTBIT_S24_LE) 2335 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
3495 2336
3496static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { 2337static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3497 .set_sysclk = wm8994_set_dai_sysclk, 2338 .set_sysclk = wm8994_set_dai_sysclk,
@@ -3512,23 +2353,24 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3512}; 2353};
3513 2354
3514static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { 2355static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
2356 .hw_params = wm8994_aif3_hw_params,
3515 .set_tristate = wm8994_set_tristate, 2357 .set_tristate = wm8994_set_tristate,
3516}; 2358};
3517 2359
3518struct snd_soc_dai wm8994_dai[] = { 2360static struct snd_soc_dai_driver wm8994_dai[] = {
3519 { 2361 {
3520 .name = "WM8994 AIF1", 2362 .name = "wm8994-aif1",
3521 .id = 1, 2363 .id = 1,
3522 .playback = { 2364 .playback = {
3523 .stream_name = "AIF1 Playback", 2365 .stream_name = "AIF1 Playback",
3524 .channels_min = 2, 2366 .channels_min = 1,
3525 .channels_max = 2, 2367 .channels_max = 2,
3526 .rates = WM8994_RATES, 2368 .rates = WM8994_RATES,
3527 .formats = WM8994_FORMATS, 2369 .formats = WM8994_FORMATS,
3528 }, 2370 },
3529 .capture = { 2371 .capture = {
3530 .stream_name = "AIF1 Capture", 2372 .stream_name = "AIF1 Capture",
3531 .channels_min = 2, 2373 .channels_min = 1,
3532 .channels_max = 2, 2374 .channels_max = 2,
3533 .rates = WM8994_RATES, 2375 .rates = WM8994_RATES,
3534 .formats = WM8994_FORMATS, 2376 .formats = WM8994_FORMATS,
@@ -3536,18 +2378,18 @@ struct snd_soc_dai wm8994_dai[] = {
3536 .ops = &wm8994_aif1_dai_ops, 2378 .ops = &wm8994_aif1_dai_ops,
3537 }, 2379 },
3538 { 2380 {
3539 .name = "WM8994 AIF2", 2381 .name = "wm8994-aif2",
3540 .id = 2, 2382 .id = 2,
3541 .playback = { 2383 .playback = {
3542 .stream_name = "AIF2 Playback", 2384 .stream_name = "AIF2 Playback",
3543 .channels_min = 2, 2385 .channels_min = 1,
3544 .channels_max = 2, 2386 .channels_max = 2,
3545 .rates = WM8994_RATES, 2387 .rates = WM8994_RATES,
3546 .formats = WM8994_FORMATS, 2388 .formats = WM8994_FORMATS,
3547 }, 2389 },
3548 .capture = { 2390 .capture = {
3549 .stream_name = "AIF2 Capture", 2391 .stream_name = "AIF2 Capture",
3550 .channels_min = 2, 2392 .channels_min = 1,
3551 .channels_max = 2, 2393 .channels_max = 2,
3552 .rates = WM8994_RATES, 2394 .rates = WM8994_RATES,
3553 .formats = WM8994_FORMATS, 2395 .formats = WM8994_FORMATS,
@@ -3555,18 +2397,18 @@ struct snd_soc_dai wm8994_dai[] = {
3555 .ops = &wm8994_aif2_dai_ops, 2397 .ops = &wm8994_aif2_dai_ops,
3556 }, 2398 },
3557 { 2399 {
3558 .name = "WM8994 AIF3", 2400 .name = "wm8994-aif3",
3559 .id = 3, 2401 .id = 3,
3560 .playback = { 2402 .playback = {
3561 .stream_name = "AIF3 Playback", 2403 .stream_name = "AIF3 Playback",
3562 .channels_min = 2, 2404 .channels_min = 1,
3563 .channels_max = 2, 2405 .channels_max = 2,
3564 .rates = WM8994_RATES, 2406 .rates = WM8994_RATES,
3565 .formats = WM8994_FORMATS, 2407 .formats = WM8994_FORMATS,
3566 }, 2408 },
3567 .capture = { 2409 .capture = {
3568 .stream_name = "AIF3 Capture", 2410 .stream_name = "AIF3 Capture",
3569 .channels_min = 2, 2411 .channels_min = 1,
3570 .channels_max = 2, 2412 .channels_max = 2,
3571 .rates = WM8994_RATES, 2413 .rates = WM8994_RATES,
3572 .formats = WM8994_FORMATS, 2414 .formats = WM8994_FORMATS,
@@ -3574,20 +2416,28 @@ struct snd_soc_dai wm8994_dai[] = {
3574 .ops = &wm8994_aif3_dai_ops, 2416 .ops = &wm8994_aif3_dai_ops,
3575 } 2417 }
3576}; 2418};
3577EXPORT_SYMBOL_GPL(wm8994_dai);
3578 2419
3579#ifdef CONFIG_PM 2420#ifdef CONFIG_PM
3580static int wm8994_suspend(struct platform_device *pdev, pm_message_t state) 2421static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
3581{ 2422{
3582 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3583 struct snd_soc_codec *codec = socdev->card->codec;
3584 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2423 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2424 struct wm8994 *control = codec->control_data;
3585 int i, ret; 2425 int i, ret;
3586 2426
2427 switch (control->type) {
2428 case WM8994:
2429 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2430 break;
2431 case WM8958:
2432 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2433 WM8958_MICD_ENA, 0);
2434 break;
2435 }
2436
3587 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2437 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3588 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 2438 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3589 sizeof(struct fll_config)); 2439 sizeof(struct wm8994_fll_config));
3590 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0); 2440 ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
3591 if (ret < 0) 2441 if (ret < 0)
3592 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n", 2442 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3593 i + 1, ret); 2443 i + 1, ret);
@@ -3598,31 +2448,32 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3598 return 0; 2448 return 0;
3599} 2449}
3600 2450
3601static int wm8994_resume(struct platform_device *pdev) 2451static int wm8994_resume(struct snd_soc_codec *codec)
3602{ 2452{
3603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3604 struct snd_soc_codec *codec = socdev->card->codec;
3605 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2453 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3606 u16 *reg_cache = codec->reg_cache; 2454 struct wm8994 *control = codec->control_data;
3607 int i, ret; 2455 int i, ret;
2456 unsigned int val, mask;
2457
2458 if (wm8994->revision < 4) {
2459 /* force a HW read */
2460 val = wm8994_reg_read(codec->control_data,
2461 WM8994_POWER_MANAGEMENT_5);
2462
2463 /* modify the cache only */
2464 codec->cache_only = 1;
2465 mask = WM8994_DAC1R_ENA | WM8994_DAC1L_ENA |
2466 WM8994_DAC2R_ENA | WM8994_DAC2L_ENA;
2467 val &= mask;
2468 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
2469 mask, val);
2470 codec->cache_only = 0;
2471 }
3608 2472
3609 /* Restore the registers */ 2473 /* Restore the registers */
3610 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) { 2474 ret = snd_soc_cache_sync(codec);
3611 switch (i) { 2475 if (ret != 0)
3612 case WM8994_LDO_1: 2476 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
3613 case WM8994_LDO_2:
3614 case WM8994_SOFTWARE_RESET:
3615 /* Handled by other MFD drivers */
3616 continue;
3617 default:
3618 break;
3619 }
3620
3621 if (!access_masks[i].writable)
3622 continue;
3623
3624 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3625 }
3626 2477
3627 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2478 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3628 2479
@@ -3630,7 +2481,7 @@ static int wm8994_resume(struct platform_device *pdev)
3630 if (!wm8994->fll_suspend[i].out) 2481 if (!wm8994->fll_suspend[i].out)
3631 continue; 2482 continue;
3632 2483
3633 ret = wm8994_set_fll(&codec->dai[0], i + 1, 2484 ret = _wm8994_set_fll(codec, i + 1,
3634 wm8994->fll_suspend[i].src, 2485 wm8994->fll_suspend[i].src,
3635 wm8994->fll_suspend[i].in, 2486 wm8994->fll_suspend[i].in,
3636 wm8994->fll_suspend[i].out); 2487 wm8994->fll_suspend[i].out);
@@ -3639,6 +2490,19 @@ static int wm8994_resume(struct platform_device *pdev)
3639 i + 1, ret); 2490 i + 1, ret);
3640 } 2491 }
3641 2492
2493 switch (control->type) {
2494 case WM8994:
2495 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
2496 snd_soc_update_bits(codec, WM8994_MICBIAS,
2497 WM8994_MICD_ENA, WM8994_MICD_ENA);
2498 break;
2499 case WM8958:
2500 if (wm8994->jack_cb)
2501 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2502 WM8958_MICD_ENA, WM8958_MICD_ENA);
2503 break;
2504 }
2505
3642 return 0; 2506 return 0;
3643} 2507}
3644#else 2508#else
@@ -3648,7 +2512,7 @@ static int wm8994_resume(struct platform_device *pdev)
3648 2512
3649static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) 2513static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3650{ 2514{
3651 struct snd_soc_codec *codec = &wm8994->codec; 2515 struct snd_soc_codec *codec = wm8994->codec;
3652 struct wm8994_pdata *pdata = wm8994->pdata; 2516 struct wm8994_pdata *pdata = wm8994->pdata;
3653 struct snd_kcontrol_new controls[] = { 2517 struct snd_kcontrol_new controls[] = {
3654 SOC_ENUM_EXT("AIF1.1 EQ Mode", 2518 SOC_ENUM_EXT("AIF1.1 EQ Mode",
@@ -3706,16 +2570,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3706 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; 2570 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3707 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; 2571 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3708 2572
3709 ret = snd_soc_add_controls(&wm8994->codec, controls, 2573 ret = snd_soc_add_controls(wm8994->codec, controls,
3710 ARRAY_SIZE(controls)); 2574 ARRAY_SIZE(controls));
3711 if (ret != 0) 2575 if (ret != 0)
3712 dev_err(wm8994->codec.dev, 2576 dev_err(wm8994->codec->dev,
3713 "Failed to add ReTune Mobile controls: %d\n", ret); 2577 "Failed to add ReTune Mobile controls: %d\n", ret);
3714} 2578}
3715 2579
3716static void wm8994_handle_pdata(struct wm8994_priv *wm8994) 2580static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3717{ 2581{
3718 struct snd_soc_codec *codec = &wm8994->codec; 2582 struct snd_soc_codec *codec = wm8994->codec;
3719 struct wm8994_pdata *pdata = wm8994->pdata; 2583 struct wm8994_pdata *pdata = wm8994->pdata;
3720 int ret, i; 2584 int ret, i;
3721 2585
@@ -3747,7 +2611,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3747 wm8994->drc_texts = kmalloc(sizeof(char *) 2611 wm8994->drc_texts = kmalloc(sizeof(char *)
3748 * pdata->num_drc_cfgs, GFP_KERNEL); 2612 * pdata->num_drc_cfgs, GFP_KERNEL);
3749 if (!wm8994->drc_texts) { 2613 if (!wm8994->drc_texts) {
3750 dev_err(wm8994->codec.dev, 2614 dev_err(wm8994->codec->dev,
3751 "Failed to allocate %d DRC config texts\n", 2615 "Failed to allocate %d DRC config texts\n",
3752 pdata->num_drc_cfgs); 2616 pdata->num_drc_cfgs);
3753 return; 2617 return;
@@ -3759,10 +2623,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3759 wm8994->drc_enum.max = pdata->num_drc_cfgs; 2623 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3760 wm8994->drc_enum.texts = wm8994->drc_texts; 2624 wm8994->drc_enum.texts = wm8994->drc_texts;
3761 2625
3762 ret = snd_soc_add_controls(&wm8994->codec, controls, 2626 ret = snd_soc_add_controls(wm8994->codec, controls,
3763 ARRAY_SIZE(controls)); 2627 ARRAY_SIZE(controls));
3764 if (ret != 0) 2628 if (ret != 0)
3765 dev_err(wm8994->codec.dev, 2629 dev_err(wm8994->codec->dev,
3766 "Failed to add DRC mode controls: %d\n", ret); 2630 "Failed to add DRC mode controls: %d\n", ret);
3767 2631
3768 for (i = 0; i < WM8994_NUM_DRC; i++) 2632 for (i = 0; i < WM8994_NUM_DRC; i++)
@@ -3775,62 +2639,17 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3775 if (pdata->num_retune_mobile_cfgs) 2639 if (pdata->num_retune_mobile_cfgs)
3776 wm8994_handle_retune_mobile_pdata(wm8994); 2640 wm8994_handle_retune_mobile_pdata(wm8994);
3777 else 2641 else
3778 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls, 2642 snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
3779 ARRAY_SIZE(wm8994_eq_controls)); 2643 ARRAY_SIZE(wm8994_eq_controls));
3780}
3781
3782static int wm8994_probe(struct platform_device *pdev)
3783{
3784 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3785 struct snd_soc_codec *codec;
3786 int ret = 0;
3787
3788 if (wm8994_codec == NULL) {
3789 dev_err(&pdev->dev, "Codec device not registered\n");
3790 return -ENODEV;
3791 }
3792 2644
3793 socdev->card->codec = wm8994_codec; 2645 for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
3794 codec = wm8994_codec; 2646 if (pdata->micbias[i]) {
3795 2647 snd_soc_write(codec, WM8958_MICBIAS1 + i,
3796 /* register pcms */ 2648 pdata->micbias[i] & 0xffff);
3797 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2649 }
3798 if (ret < 0) {
3799 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3800 return ret;
3801 } 2650 }
3802
3803 wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec));
3804
3805 wm_hubs_add_analogue_controls(codec);
3806 snd_soc_add_controls(codec, wm8994_snd_controls,
3807 ARRAY_SIZE(wm8994_snd_controls));
3808 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3809 ARRAY_SIZE(wm8994_dapm_widgets));
3810 wm_hubs_add_analogue_routes(codec, 0, 0);
3811 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3812
3813 return 0;
3814}
3815
3816static int wm8994_remove(struct platform_device *pdev)
3817{
3818 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3819
3820 snd_soc_free_pcms(socdev);
3821 snd_soc_dapm_free(socdev);
3822
3823 return 0;
3824} 2651}
3825 2652
3826struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3827 .probe = wm8994_probe,
3828 .remove = wm8994_remove,
3829 .suspend = wm8994_suspend,
3830 .resume = wm8994_resume,
3831};
3832EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3833
3834/** 2653/**
3835 * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ 2654 * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
3836 * 2655 *
@@ -3842,7 +2661,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3842 * 2661 *
3843 * Enable microphone detection via IRQ on the WM8994. If GPIOs are 2662 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
3844 * being used to bring out signals to the processor then only platform 2663 * being used to bring out signals to the processor then only platform
3845 * data configuration is needed for WM8903 and processor GPIOs should 2664 * data configuration is needed for WM8994 and processor GPIOs should
3846 * be configured using snd_soc_jack_add_gpios() instead. 2665 * be configured using snd_soc_jack_add_gpios() instead.
3847 * 2666 *
3848 * Configuration of detection levels is available via the micbias1_lvl 2667 * Configuration of detection levels is available via the micbias1_lvl
@@ -3853,8 +2672,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3853{ 2672{
3854 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2673 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3855 struct wm8994_micdet *micdet; 2674 struct wm8994_micdet *micdet;
2675 struct wm8994 *control = codec->control_data;
3856 int reg; 2676 int reg;
3857 2677
2678 if (control->type != WM8994)
2679 return -EINVAL;
2680
3858 switch (micbias) { 2681 switch (micbias) {
3859 case 1: 2682 case 1:
3860 micdet = &wm8994->micdet[0]; 2683 micdet = &wm8994->micdet[0];
@@ -3889,10 +2712,14 @@ EXPORT_SYMBOL_GPL(wm8994_mic_detect);
3889static irqreturn_t wm8994_mic_irq(int irq, void *data) 2712static irqreturn_t wm8994_mic_irq(int irq, void *data)
3890{ 2713{
3891 struct wm8994_priv *priv = data; 2714 struct wm8994_priv *priv = data;
3892 struct snd_soc_codec *codec = &priv->codec; 2715 struct snd_soc_codec *codec = priv->codec;
3893 int reg; 2716 int reg;
3894 int report; 2717 int report;
3895 2718
2719#ifndef CONFIG_SND_SOC_WM8994_MODULE
2720 trace_snd_soc_jack_irq(dev_name(codec->dev));
2721#endif
2722
3896 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); 2723 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
3897 if (reg < 0) { 2724 if (reg < 0) {
3898 dev_err(codec->dev, "Failed to read microphone status: %d\n", 2725 dev_err(codec->dev, "Failed to read microphone status: %d\n",
@@ -3921,101 +2748,233 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3921 return IRQ_HANDLED; 2748 return IRQ_HANDLED;
3922} 2749}
3923 2750
3924static int wm8994_codec_probe(struct platform_device *pdev) 2751/* Default microphone detection handler for WM8958 - the user can
2752 * override this if they wish.
2753 */
2754static void wm8958_default_micdet(u16 status, void *data)
3925{ 2755{
3926 int ret; 2756 struct snd_soc_codec *codec = data;
3927 struct wm8994_priv *wm8994; 2757 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3928 struct snd_soc_codec *codec; 2758 int report = 0;
3929 int i; 2759
2760 /* If nothing present then clear our statuses */
2761 if (!(status & WM8958_MICD_STS))
2762 goto done;
2763
2764 report = SND_JACK_MICROPHONE;
2765
2766 /* Everything else is buttons; just assign slots */
2767 if (status & 0x1c)
2768 report |= SND_JACK_BTN_0;
2769
2770done:
2771 snd_soc_jack_report(wm8994->micdet[0].jack, report,
2772 SND_JACK_BTN_0 | SND_JACK_MICROPHONE);
2773}
2774
2775/**
2776 * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
2777 *
2778 * @codec: WM8958 codec
2779 * @jack: jack to report detection events on
2780 *
2781 * Enable microphone detection functionality for the WM8958. By
2782 * default simple detection which supports the detection of up to 6
2783 * buttons plus video and microphone functionality is supported.
2784 *
2785 * The WM8958 has an advanced jack detection facility which is able to
2786 * support complex accessory detection, especially when used in
2787 * conjunction with external circuitry. In order to provide maximum
2788 * flexiblity a callback is provided which allows a completely custom
2789 * detection algorithm.
2790 */
2791int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2792 wm8958_micdet_cb cb, void *cb_data)
2793{
2794 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2795 struct wm8994 *control = codec->control_data;
3930 2796
3931 if (wm8994_codec) { 2797 if (control->type != WM8958)
3932 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3933 return -EINVAL; 2798 return -EINVAL;
2799
2800 if (jack) {
2801 if (!cb) {
2802 dev_dbg(codec->dev, "Using default micdet callback\n");
2803 cb = wm8958_default_micdet;
2804 cb_data = codec;
2805 }
2806
2807 wm8994->micdet[0].jack = jack;
2808 wm8994->jack_cb = cb;
2809 wm8994->jack_cb_data = cb_data;
2810
2811 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2812 WM8958_MICD_ENA, WM8958_MICD_ENA);
2813 } else {
2814 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2815 WM8958_MICD_ENA, 0);
3934 } 2816 }
3935 2817
3936 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); 2818 return 0;
3937 if (!wm8994) { 2819}
3938 dev_err(&pdev->dev, "Failed to allocate private data\n"); 2820EXPORT_SYMBOL_GPL(wm8958_mic_detect);
3939 return -ENOMEM; 2821
2822static irqreturn_t wm8958_mic_irq(int irq, void *data)
2823{
2824 struct wm8994_priv *wm8994 = data;
2825 struct snd_soc_codec *codec = wm8994->codec;
2826 int reg;
2827
2828 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
2829 if (reg < 0) {
2830 dev_err(codec->dev, "Failed to read mic detect status: %d\n",
2831 reg);
2832 return IRQ_NONE;
3940 } 2833 }
3941 2834
3942 codec = &wm8994->codec; 2835 if (!(reg & WM8958_MICD_VALID)) {
2836 dev_dbg(codec->dev, "Mic detect data not valid\n");
2837 goto out;
2838 }
2839
2840#ifndef CONFIG_SND_SOC_WM8994_MODULE
2841 trace_snd_soc_jack_irq(dev_name(codec->dev));
2842#endif
2843
2844 if (wm8994->jack_cb)
2845 wm8994->jack_cb(reg, wm8994->jack_cb_data);
2846 else
2847 dev_warn(codec->dev, "Accessory detection with no callback\n");
2848
2849out:
2850 return IRQ_HANDLED;
2851}
2852
2853static int wm8994_codec_probe(struct snd_soc_codec *codec)
2854{
2855 struct wm8994 *control;
2856 struct wm8994_priv *wm8994;
2857 struct snd_soc_dapm_context *dapm = &codec->dapm;
2858 int ret, i;
3943 2859
3944 mutex_init(&codec->mutex); 2860 codec->control_data = dev_get_drvdata(codec->dev->parent);
3945 INIT_LIST_HEAD(&codec->dapm_widgets); 2861 control = codec->control_data;
3946 INIT_LIST_HEAD(&codec->dapm_paths);
3947 2862
2863 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
2864 if (wm8994 == NULL)
2865 return -ENOMEM;
3948 snd_soc_codec_set_drvdata(codec, wm8994); 2866 snd_soc_codec_set_drvdata(codec, wm8994);
3949 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3950 codec->name = "WM8994";
3951 codec->owner = THIS_MODULE;
3952 codec->read = wm8994_read;
3953 codec->write = wm8994_write;
3954 codec->readable_register = wm8994_readable;
3955 codec->bias_level = SND_SOC_BIAS_OFF;
3956 codec->set_bias_level = wm8994_set_bias_level;
3957 codec->dai = &wm8994_dai[0];
3958 codec->num_dai = 3;
3959 codec->reg_cache_size = WM8994_MAX_REGISTER;
3960 codec->reg_cache = &wm8994->reg_cache;
3961 codec->dev = &pdev->dev;
3962
3963 wm8994->pdata = pdev->dev.parent->platform_data;
3964
3965 /* Fill the cache with physical values we inherited; don't reset */
3966 ret = wm8994_bulk_read(codec->control_data, 0,
3967 ARRAY_SIZE(wm8994->reg_cache) - 1,
3968 codec->reg_cache);
3969 if (ret < 0) {
3970 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3971 ret);
3972 goto err;
3973 }
3974 2867
3975 /* Clear the cached values for unreadable/volatile registers to 2868 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3976 * avoid potential confusion. 2869 wm8994->codec = codec;
3977 */ 2870
3978 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++) 2871 if (wm8994->pdata && wm8994->pdata->micdet_irq)
3979 if (wm8994_volatile(i) || !wm8994_readable(i)) 2872 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
3980 wm8994->reg_cache[i] = 0; 2873 else if (wm8994->pdata && wm8994->pdata->irq_base)
2874 wm8994->micdet_irq = wm8994->pdata->irq_base +
2875 WM8994_IRQ_MIC1_DET;
2876
2877 pm_runtime_enable(codec->dev);
2878 pm_runtime_resume(codec->dev);
2879
2880 /* Read our current status back from the chip - we don't want to
2881 * reset as this may interfere with the GPIO or LDO operation. */
2882 for (i = 0; i < WM8994_CACHE_SIZE; i++) {
2883 if (!wm8994_readable(codec, i) || wm8994_volatile(codec, i))
2884 continue;
2885
2886 ret = wm8994_reg_read(codec->control_data, i);
2887 if (ret <= 0)
2888 continue;
2889
2890 ret = snd_soc_cache_write(codec, i, ret);
2891 if (ret != 0) {
2892 dev_err(codec->dev,
2893 "Failed to initialise cache for 0x%x: %d\n",
2894 i, ret);
2895 goto err;
2896 }
2897 }
3981 2898
3982 /* Set revision-specific configuration */ 2899 /* Set revision-specific configuration */
3983 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); 2900 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3984 switch (wm8994->revision) { 2901 switch (control->type) {
3985 case 2: 2902 case WM8994:
3986 case 3: 2903 switch (wm8994->revision) {
3987 wm8994->hubs.dcs_codes = -5; 2904 case 2:
3988 wm8994->hubs.hp_startup_mode = 1; 2905 case 3:
2906 wm8994->hubs.dcs_codes = -5;
2907 wm8994->hubs.hp_startup_mode = 1;
2908 wm8994->hubs.dcs_readback_mode = 1;
2909 break;
2910 default:
2911 wm8994->hubs.dcs_readback_mode = 1;
2912 break;
2913 }
2914
2915 case WM8958:
3989 wm8994->hubs.dcs_readback_mode = 1; 2916 wm8994->hubs.dcs_readback_mode = 1;
3990 break; 2917 break;
2918
3991 default: 2919 default:
3992 wm8994->hubs.dcs_readback_mode = 1;
3993 break; 2920 break;
3994 } 2921 }
3995 2922
3996 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 2923 switch (control->type) {
3997 wm8994_mic_irq, "Mic 1 detect", wm8994); 2924 case WM8994:
3998 if (ret != 0) 2925 if (wm8994->micdet_irq) {
3999 dev_warn(&pdev->dev, 2926 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
4000 "Failed to request Mic1 detect IRQ: %d\n", ret); 2927 wm8994_mic_irq,
4001 2928 IRQF_TRIGGER_RISING,
4002 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 2929 "Mic1 detect",
4003 wm8994_mic_irq, "Mic 1 short", wm8994); 2930 wm8994);
4004 if (ret != 0) 2931 if (ret != 0)
4005 dev_warn(&pdev->dev, 2932 dev_warn(codec->dev,
4006 "Failed to request Mic1 short IRQ: %d\n", ret); 2933 "Failed to request Mic1 detect IRQ: %d\n",
2934 ret);
2935 }
4007 2936
4008 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 2937 ret = wm8994_request_irq(codec->control_data,
4009 wm8994_mic_irq, "Mic 2 detect", wm8994); 2938 WM8994_IRQ_MIC1_SHRT,
4010 if (ret != 0) 2939 wm8994_mic_irq, "Mic 1 short",
4011 dev_warn(&pdev->dev, 2940 wm8994);
4012 "Failed to request Mic2 detect IRQ: %d\n", ret); 2941 if (ret != 0)
2942 dev_warn(codec->dev,
2943 "Failed to request Mic1 short IRQ: %d\n",
2944 ret);
2945
2946 ret = wm8994_request_irq(codec->control_data,
2947 WM8994_IRQ_MIC2_DET,
2948 wm8994_mic_irq, "Mic 2 detect",
2949 wm8994);
2950 if (ret != 0)
2951 dev_warn(codec->dev,
2952 "Failed to request Mic2 detect IRQ: %d\n",
2953 ret);
2954
2955 ret = wm8994_request_irq(codec->control_data,
2956 WM8994_IRQ_MIC2_SHRT,
2957 wm8994_mic_irq, "Mic 2 short",
2958 wm8994);
2959 if (ret != 0)
2960 dev_warn(codec->dev,
2961 "Failed to request Mic2 short IRQ: %d\n",
2962 ret);
2963 break;
4013 2964
4014 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 2965 case WM8958:
4015 wm8994_mic_irq, "Mic 2 short", wm8994); 2966 if (wm8994->micdet_irq) {
4016 if (ret != 0) 2967 ret = request_threaded_irq(wm8994->micdet_irq, NULL,
4017 dev_warn(&pdev->dev, 2968 wm8958_mic_irq,
4018 "Failed to request Mic2 short IRQ: %d\n", ret); 2969 IRQF_TRIGGER_RISING,
2970 "Mic detect",
2971 wm8994);
2972 if (ret != 0)
2973 dev_warn(codec->dev,
2974 "Failed to request Mic detect IRQ: %d\n",
2975 ret);
2976 }
2977 }
4019 2978
4020 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 2979 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
4021 * configured on init - if a system wants to do this dynamically 2980 * configured on init - if a system wants to do this dynamically
@@ -4045,28 +3004,39 @@ static int wm8994_codec_probe(struct platform_device *pdev)
4045 wm8994->lrclk_shared[1] = 0; 3004 wm8994->lrclk_shared[1] = 0;
4046 } 3005 }
4047 3006
4048 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
4049 wm8994_dai[i].dev = codec->dev;
4050
4051 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3007 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
4052 3008
4053 wm8994_codec = codec;
4054
4055 /* Latch volume updates (right only; we always do left then right). */ 3009 /* Latch volume updates (right only; we always do left then right). */
3010 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME,
3011 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
4056 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME, 3012 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
4057 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU); 3013 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
3014 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_LEFT_VOLUME,
3015 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
4058 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME, 3016 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
4059 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU); 3017 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
3018 snd_soc_update_bits(codec, WM8994_AIF2_DAC_LEFT_VOLUME,
3019 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
4060 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME, 3020 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
4061 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU); 3021 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
3022 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_LEFT_VOLUME,
3023 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
4062 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME, 3024 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
4063 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU); 3025 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
3026 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_LEFT_VOLUME,
3027 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
4064 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME, 3028 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
4065 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU); 3029 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
3030 snd_soc_update_bits(codec, WM8994_AIF2_ADC_LEFT_VOLUME,
3031 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
4066 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME, 3032 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
4067 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU); 3033 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
3034 snd_soc_update_bits(codec, WM8994_DAC1_LEFT_VOLUME,
3035 WM8994_DAC1_VU, WM8994_DAC1_VU);
4068 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME, 3036 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
4069 WM8994_DAC1_VU, WM8994_DAC1_VU); 3037 WM8994_DAC1_VU, WM8994_DAC1_VU);
3038 snd_soc_update_bits(codec, WM8994_DAC2_LEFT_VOLUME,
3039 WM8994_DAC2_VU, WM8994_DAC2_VU);
4070 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME, 3040 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
4071 WM8994_DAC2_VU, WM8994_DAC2_VU); 3041 WM8994_DAC2_VU, WM8994_DAC2_VU);
4072 3042
@@ -4088,59 +3058,181 @@ static int wm8994_codec_probe(struct platform_device *pdev)
4088 3058
4089 wm8994_update_class_w(codec); 3059 wm8994_update_class_w(codec);
4090 3060
4091 ret = snd_soc_register_codec(codec); 3061 wm8994_handle_pdata(wm8994);
4092 if (ret != 0) {
4093 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
4094 goto err_irq;
4095 }
4096 3062
4097 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 3063 wm_hubs_add_analogue_controls(codec);
4098 if (ret != 0) { 3064 snd_soc_add_controls(codec, wm8994_snd_controls,
4099 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); 3065 ARRAY_SIZE(wm8994_snd_controls));
4100 goto err_codec; 3066 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
3067 ARRAY_SIZE(wm8994_dapm_widgets));
3068
3069 switch (control->type) {
3070 case WM8994:
3071 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
3072 ARRAY_SIZE(wm8994_specific_dapm_widgets));
3073 if (wm8994->revision < 4) {
3074 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3075 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3076 snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
3077 ARRAY_SIZE(wm8994_adc_revd_widgets));
3078 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3079 ARRAY_SIZE(wm8994_dac_revd_widgets));
3080 } else {
3081 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3082 ARRAY_SIZE(wm8994_lateclk_widgets));
3083 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3084 ARRAY_SIZE(wm8994_adc_widgets));
3085 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3086 ARRAY_SIZE(wm8994_dac_widgets));
3087 }
3088 break;
3089 case WM8958:
3090 snd_soc_add_controls(codec, wm8958_snd_controls,
3091 ARRAY_SIZE(wm8958_snd_controls));
3092 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3093 ARRAY_SIZE(wm8958_dapm_widgets));
3094 if (wm8994->revision < 1) {
3095 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
3096 ARRAY_SIZE(wm8994_lateclk_revd_widgets));
3097 snd_soc_dapm_new_controls(dapm, wm8994_adc_revd_widgets,
3098 ARRAY_SIZE(wm8994_adc_revd_widgets));
3099 snd_soc_dapm_new_controls(dapm, wm8994_dac_revd_widgets,
3100 ARRAY_SIZE(wm8994_dac_revd_widgets));
3101 } else {
3102 snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets,
3103 ARRAY_SIZE(wm8994_lateclk_widgets));
3104 snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets,
3105 ARRAY_SIZE(wm8994_adc_widgets));
3106 snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets,
3107 ARRAY_SIZE(wm8994_dac_widgets));
3108 }
3109 break;
4101 } 3110 }
3111
4102 3112
4103 platform_set_drvdata(pdev, wm8994); 3113 wm_hubs_add_analogue_routes(codec, 0, 0);
3114 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
3115
3116 switch (control->type) {
3117 case WM8994:
3118 snd_soc_dapm_add_routes(dapm, wm8994_intercon,
3119 ARRAY_SIZE(wm8994_intercon));
3120
3121 if (wm8994->revision < 4) {
3122 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3123 ARRAY_SIZE(wm8994_revd_intercon));
3124 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3125 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3126 } else {
3127 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3128 ARRAY_SIZE(wm8994_lateclk_intercon));
3129 }
3130 break;
3131 case WM8958:
3132 if (wm8994->revision < 1) {
3133 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
3134 ARRAY_SIZE(wm8994_revd_intercon));
3135 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
3136 ARRAY_SIZE(wm8994_lateclk_revd_intercon));
3137 } else {
3138 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon,
3139 ARRAY_SIZE(wm8994_lateclk_intercon));
3140 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3141 ARRAY_SIZE(wm8958_intercon));
3142 }
3143
3144 wm8958_dsp2_init(codec);
3145 break;
3146 }
4104 3147
4105 return 0; 3148 return 0;
4106 3149
4107err_codec:
4108 snd_soc_unregister_codec(codec);
4109err_irq: 3150err_irq:
4110 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 3151 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4111 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 3152 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
4112 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3153 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
4113 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 3154 if (wm8994->micdet_irq)
3155 free_irq(wm8994->micdet_irq, wm8994);
4114err: 3156err:
4115 kfree(wm8994); 3157 kfree(wm8994);
4116 return ret; 3158 return ret;
4117} 3159}
4118 3160
4119static int __devexit wm8994_codec_remove(struct platform_device *pdev) 3161static int wm8994_codec_remove(struct snd_soc_codec *codec)
4120{ 3162{
4121 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev); 3163 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
4122 struct snd_soc_codec *codec = &wm8994->codec; 3164 struct wm8994 *control = codec->control_data;
4123 3165
4124 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 3166 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
4125 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 3167
4126 snd_soc_unregister_codec(&wm8994->codec); 3168 pm_runtime_disable(codec->dev);
4127 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 3169
4128 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 3170 switch (control->type) {
4129 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3171 case WM8994:
4130 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 3172 if (wm8994->micdet_irq)
3173 free_irq(wm8994->micdet_irq, wm8994);
3174 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3175 wm8994);
3176 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
3177 wm8994);
3178 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
3179 wm8994);
3180 break;
3181
3182 case WM8958:
3183 if (wm8994->micdet_irq)
3184 free_irq(wm8994->micdet_irq, wm8994);
3185 break;
3186 }
3187 if (wm8994->mbc)
3188 release_firmware(wm8994->mbc);
3189 if (wm8994->mbc_vss)
3190 release_firmware(wm8994->mbc_vss);
3191 if (wm8994->enh_eq)
3192 release_firmware(wm8994->enh_eq);
3193 kfree(wm8994->retune_mobile_texts);
3194 kfree(wm8994->drc_texts);
4131 kfree(wm8994); 3195 kfree(wm8994);
4132 wm8994_codec = NULL;
4133 3196
4134 return 0; 3197 return 0;
4135} 3198}
4136 3199
3200static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
3201 .probe = wm8994_codec_probe,
3202 .remove = wm8994_codec_remove,
3203 .suspend = wm8994_suspend,
3204 .resume = wm8994_resume,
3205 .read = wm8994_read,
3206 .write = wm8994_write,
3207 .readable_register = wm8994_readable,
3208 .volatile_register = wm8994_volatile,
3209 .set_bias_level = wm8994_set_bias_level,
3210
3211 .reg_cache_size = WM8994_CACHE_SIZE,
3212 .reg_cache_default = wm8994_reg_defaults,
3213 .reg_word_size = 2,
3214 .compress_type = SND_SOC_RBTREE_COMPRESSION,
3215};
3216
3217static int __devinit wm8994_probe(struct platform_device *pdev)
3218{
3219 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
3220 wm8994_dai, ARRAY_SIZE(wm8994_dai));
3221}
3222
3223static int __devexit wm8994_remove(struct platform_device *pdev)
3224{
3225 snd_soc_unregister_codec(&pdev->dev);
3226 return 0;
3227}
3228
4137static struct platform_driver wm8994_codec_driver = { 3229static struct platform_driver wm8994_codec_driver = {
4138 .driver = { 3230 .driver = {
4139 .name = "wm8994-codec", 3231 .name = "wm8994-codec",
4140 .owner = THIS_MODULE, 3232 .owner = THIS_MODULE,
4141 }, 3233 },
4142 .probe = wm8994_codec_probe, 3234 .probe = wm8994_probe,
4143 .remove = __devexit_p(wm8994_codec_remove), 3235 .remove = __devexit_p(wm8994_remove),
4144}; 3236};
4145 3237
4146static __init int wm8994_init(void) 3238static __init int wm8994_init(void)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 2e0ca67a8df7..0a1db04b73bd 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -10,9 +10,9 @@
10#define _WM8994_H 10#define _WM8994_H
11 11
12#include <sound/soc.h> 12#include <sound/soc.h>
13#include <linux/firmware.h>
13 14
14extern struct snd_soc_codec_device soc_codec_dev_wm8994; 15#include "wm_hubs.h"
15extern struct snd_soc_dai wm8994_dai[];
16 16
17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ 17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
18#define WM8994_SYSCLK_MCLK1 1 18#define WM8994_SYSCLK_MCLK1 1
@@ -31,7 +31,115 @@ extern struct snd_soc_dai wm8994_dai[];
31#define WM8994_FLL_SRC_LRCLK 3 31#define WM8994_FLL_SRC_LRCLK 3
32#define WM8994_FLL_SRC_BCLK 4 32#define WM8994_FLL_SRC_BCLK 4
33 33
34typedef void (*wm8958_micdet_cb)(u16 status, void *data);
35
34int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 36int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
35 int micbias, int det, int shrt); 37 int micbias, int det, int shrt);
38int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
39 wm8958_micdet_cb cb, void *cb_data);
40
41#define WM8994_CACHE_SIZE 1570
42
43struct wm8994_access_mask {
44 unsigned short readable; /* Mask of readable bits */
45 unsigned short writable; /* Mask of writable bits */
46};
47
48extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
49extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
50
51int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
52 struct snd_kcontrol *kcontrol, int event);
53
54void wm8958_dsp2_init(struct snd_soc_codec *codec);
55
56struct wm8994_micdet {
57 struct snd_soc_jack *jack;
58 int det;
59 int shrt;
60};
61
62/* codec private data */
63struct wm8994_fll_config {
64 int src;
65 int in;
66 int out;
67};
68
69#define WM8994_NUM_DRC 3
70#define WM8994_NUM_EQ 3
71
72struct wm8994_priv {
73 struct wm_hubs_data hubs;
74 enum snd_soc_control_type control_type;
75 void *control_data;
76 struct snd_soc_codec *codec;
77 int sysclk[2];
78 int sysclk_rate[2];
79 int mclk[2];
80 int aifclk[2];
81 struct wm8994_fll_config fll[2], fll_suspend[2];
82
83 int dac_rates[2];
84 int lrclk_shared[2];
85
86 int mbc_ena[3];
87 int hpf1_ena[3];
88 int hpf2_ena[3];
89 int vss_ena[3];
90 int enh_eq_ena[3];
91
92 /* Platform dependant DRC configuration */
93 const char **drc_texts;
94 int drc_cfg[WM8994_NUM_DRC];
95 struct soc_enum drc_enum;
96
97 /* Platform dependant ReTune mobile configuration */
98 int num_retune_mobile_texts;
99 const char **retune_mobile_texts;
100 int retune_mobile_cfg[WM8994_NUM_EQ];
101 struct soc_enum retune_mobile_enum;
102
103 /* Platform dependant MBC configuration */
104 int mbc_cfg;
105 const char **mbc_texts;
106 struct soc_enum mbc_enum;
107
108 /* Platform dependant VSS configuration */
109 int vss_cfg;
110 const char **vss_texts;
111 struct soc_enum vss_enum;
112
113 /* Platform dependant VSS HPF configuration */
114 int vss_hpf_cfg;
115 const char **vss_hpf_texts;
116 struct soc_enum vss_hpf_enum;
117
118 /* Platform dependant enhanced EQ configuration */
119 int enh_eq_cfg;
120 const char **enh_eq_texts;
121 struct soc_enum enh_eq_enum;
122
123 struct wm8994_micdet micdet[2];
124
125 wm8958_micdet_cb jack_cb;
126 void *jack_cb_data;
127 int micdet_irq;
128
129 int revision;
130 struct wm8994_pdata *pdata;
131
132 unsigned int aif1clk_enable:1;
133 unsigned int aif2clk_enable:1;
134
135 unsigned int aif1clk_disable:1;
136 unsigned int aif2clk_disable:1;
137
138 int dsp_active;
139 const struct firmware *cur_fw;
140 const struct firmware *mbc;
141 const struct firmware *mbc_vss;
142 const struct firmware *enh_eq;
143};
36 144
37#endif 145#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
new file mode 100644
index 000000000000..5ad873fda814
--- /dev/null
+++ b/sound/soc/codecs/wm8995.c
@@ -0,0 +1,1911 @@
1/*
2 * wm8995.c -- WM8995 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * Based on wm8994.c and wm_hubs.c by Mark Brown
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/spi/spi.h>
22#include <linux/regulator/consumer.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h>
30#include <sound/tlv.h>
31
32#include "wm8995.h"
33
34#define WM8995_NUM_SUPPLIES 8
35static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = {
36 "DCVDD",
37 "DBVDD1",
38 "DBVDD2",
39 "DBVDD3",
40 "AVDD1",
41 "AVDD2",
42 "CPVDD",
43 "MICVDD"
44};
45
46static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = {
47 [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b,
48 [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0,
49 [28] = 0x000f, [32] = 0x0005, [33] = 0x0005, [40] = 0x0003,
50 [41] = 0x0013, [48] = 0x0004, [56] = 0x09f8, [64] = 0x1f25,
51 [69] = 0x0004, [82] = 0xaaaa, [84] = 0x2a2a, [146] = 0x0060,
52 [256] = 0x0002, [257] = 0x8004, [520] = 0x0010, [528] = 0x0083,
53 [529] = 0x0083, [548] = 0x0c80, [580] = 0x0c80, [768] = 0x4050,
54 [769] = 0x4000, [771] = 0x0040, [772] = 0x0040, [773] = 0x0040,
55 [774] = 0x0004, [775] = 0x0100, [784] = 0x4050, [785] = 0x4000,
56 [787] = 0x0040, [788] = 0x0040, [789] = 0x0040, [1024] = 0x00c0,
57 [1025] = 0x00c0, [1026] = 0x00c0, [1027] = 0x00c0, [1028] = 0x00c0,
58 [1029] = 0x00c0, [1030] = 0x00c0, [1031] = 0x00c0, [1056] = 0x0200,
59 [1057] = 0x0010, [1058] = 0x0200, [1059] = 0x0010, [1088] = 0x0098,
60 [1089] = 0x0845, [1104] = 0x0098, [1105] = 0x0845, [1152] = 0x6318,
61 [1153] = 0x6300, [1154] = 0x0fca, [1155] = 0x0400, [1156] = 0x00d8,
62 [1157] = 0x1eb5, [1158] = 0xf145, [1159] = 0x0b75, [1160] = 0x01c5,
63 [1161] = 0x1c58, [1162] = 0xf373, [1163] = 0x0a54, [1164] = 0x0558,
64 [1165] = 0x168e, [1166] = 0xf829, [1167] = 0x07ad, [1168] = 0x1103,
65 [1169] = 0x0564, [1170] = 0x0559, [1171] = 0x4000, [1184] = 0x6318,
66 [1185] = 0x6300, [1186] = 0x0fca, [1187] = 0x0400, [1188] = 0x00d8,
67 [1189] = 0x1eb5, [1190] = 0xf145, [1191] = 0x0b75, [1192] = 0x01c5,
68 [1193] = 0x1c58, [1194] = 0xf373, [1195] = 0x0a54, [1196] = 0x0558,
69 [1197] = 0x168e, [1198] = 0xf829, [1199] = 0x07ad, [1200] = 0x1103,
70 [1201] = 0x0564, [1202] = 0x0559, [1203] = 0x4000, [1280] = 0x00c0,
71 [1281] = 0x00c0, [1282] = 0x00c0, [1283] = 0x00c0, [1312] = 0x0200,
72 [1313] = 0x0010, [1344] = 0x0098, [1345] = 0x0845, [1408] = 0x6318,
73 [1409] = 0x6300, [1410] = 0x0fca, [1411] = 0x0400, [1412] = 0x00d8,
74 [1413] = 0x1eb5, [1414] = 0xf145, [1415] = 0x0b75, [1416] = 0x01c5,
75 [1417] = 0x1c58, [1418] = 0xf373, [1419] = 0x0a54, [1420] = 0x0558,
76 [1421] = 0x168e, [1422] = 0xf829, [1423] = 0x07ad, [1424] = 0x1103,
77 [1425] = 0x0564, [1426] = 0x0559, [1427] = 0x4000, [1568] = 0x0002,
78 [1792] = 0xa100, [1793] = 0xa101, [1794] = 0xa101, [1795] = 0xa101,
79 [1796] = 0xa101, [1797] = 0xa101, [1798] = 0xa101, [1799] = 0xa101,
80 [1800] = 0xa101, [1801] = 0xa101, [1802] = 0xa101, [1803] = 0xa101,
81 [1804] = 0xa101, [1805] = 0xa101, [1825] = 0x0055, [1848] = 0x3fff,
82 [1849] = 0x1fff, [2049] = 0x0001, [2050] = 0x0069, [2056] = 0x0002,
83 [2057] = 0x0003, [2058] = 0x0069, [12288] = 0x0001, [12289] = 0x0001,
84 [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f,
85 [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104,
86 [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050,
87 [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003,
88 [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b,
89 [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff,
90 [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff,
91 [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001,
92 [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001,
93 [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003,
94 [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401,
95 [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060,
96 [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff,
97 [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff,
98 [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff,
99 [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006,
100 [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006,
101 [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061,
102 [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003,
103 [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106,
104 [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502,
105 [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff,
106 [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff,
107 [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001,
108 [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f,
109 [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106,
110 [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050,
111 [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b,
112 [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff,
113 [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff,
114 [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff,
115 [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100,
116 [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff,
117 [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff,
118 [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff,
119 [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff,
120 [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102,
121 [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff,
122 [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff,
123 [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff,
124 [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff,
125 [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601,
126 [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304,
127 [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100
128};
129
130struct fll_config {
131 int src;
132 int in;
133 int out;
134};
135
136struct wm8995_priv {
137 enum snd_soc_control_type control_type;
138 int sysclk[2];
139 int mclk[2];
140 int aifclk[2];
141 struct fll_config fll[2], fll_suspend[2];
142 struct regulator_bulk_data supplies[WM8995_NUM_SUPPLIES];
143 struct notifier_block disable_nb[WM8995_NUM_SUPPLIES];
144 struct snd_soc_codec *codec;
145};
146
147/*
148 * We can't use the same notifier block for more than one supply and
149 * there's no way I can see to get from a callback to the caller
150 * except container_of().
151 */
152#define WM8995_REGULATOR_EVENT(n) \
153static int wm8995_regulator_event_##n(struct notifier_block *nb, \
154 unsigned long event, void *data) \
155{ \
156 struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \
157 disable_nb[n]); \
158 if (event & REGULATOR_EVENT_DISABLE) { \
159 wm8995->codec->cache_sync = 1; \
160 } \
161 return 0; \
162}
163
164WM8995_REGULATOR_EVENT(0)
165WM8995_REGULATOR_EVENT(1)
166WM8995_REGULATOR_EVENT(2)
167WM8995_REGULATOR_EVENT(3)
168WM8995_REGULATOR_EVENT(4)
169WM8995_REGULATOR_EVENT(5)
170WM8995_REGULATOR_EVENT(6)
171WM8995_REGULATOR_EVENT(7)
172
173static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
174static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
175static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0);
176static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
177
178static const char *in1l_text[] = {
179 "Differential", "Single-ended IN1LN", "Single-ended IN1LP"
180};
181
182static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
183 2, in1l_text);
184
185static const char *in1r_text[] = {
186 "Differential", "Single-ended IN1RN", "Single-ended IN1RP"
187};
188
189static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
190 0, in1r_text);
191
192static const char *dmic_src_text[] = {
193 "DMICDAT1", "DMICDAT2", "DMICDAT3"
194};
195
196static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5,
197 8, dmic_src_text);
198static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5,
199 6, dmic_src_text);
200
201static const struct snd_kcontrol_new wm8995_snd_controls[] = {
202 SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME,
203 WM8995_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
204 SOC_DOUBLE_R("DAC1 Switch", WM8995_DAC1_LEFT_VOLUME,
205 WM8995_DAC1_RIGHT_VOLUME, 9, 1, 1),
206
207 SOC_DOUBLE_R_TLV("DAC2 Volume", WM8995_DAC2_LEFT_VOLUME,
208 WM8995_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
209 SOC_DOUBLE_R("DAC2 Switch", WM8995_DAC2_LEFT_VOLUME,
210 WM8995_DAC2_RIGHT_VOLUME, 9, 1, 1),
211
212 SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8995_AIF1_DAC1_LEFT_VOLUME,
213 WM8995_AIF1_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
214 SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8995_AIF1_DAC2_LEFT_VOLUME,
215 WM8995_AIF1_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
216 SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8995_AIF2_DAC_LEFT_VOLUME,
217 WM8995_AIF2_DAC_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
218
219 SOC_DOUBLE_R_TLV("IN1LR Volume", WM8995_LEFT_LINE_INPUT_1_VOLUME,
220 WM8995_RIGHT_LINE_INPUT_1_VOLUME, 0, 31, 0, in1lr_pga_tlv),
221
222 SOC_SINGLE_TLV("IN1L Boost", WM8995_LEFT_LINE_INPUT_CONTROL,
223 4, 3, 0, in1l_boost_tlv),
224
225 SOC_ENUM("IN1L Mode", in1l_enum),
226 SOC_ENUM("IN1R Mode", in1r_enum),
227
228 SOC_ENUM("DMIC1 SRC", dmic_src1_enum),
229 SOC_ENUM("DMIC2 SRC", dmic_src2_enum),
230
231 SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8995_DAC1_MIXER_VOLUMES, 0, 5,
232 24, 0, sidetone_tlv),
233 SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8995_DAC2_MIXER_VOLUMES, 0, 5,
234 24, 0, sidetone_tlv),
235
236 SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8995_AIF1_ADC1_LEFT_VOLUME,
237 WM8995_AIF1_ADC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
238 SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8995_AIF1_ADC2_LEFT_VOLUME,
239 WM8995_AIF1_ADC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
240 SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8995_AIF2_ADC_LEFT_VOLUME,
241 WM8995_AIF2_ADC_RIGHT_VOLUME, 0, 96, 0, digital_tlv)
242};
243
244static void wm8995_update_class_w(struct snd_soc_codec *codec)
245{
246 int enable = 1;
247 int source = 0; /* GCC flow analysis can't track enable */
248 int reg, reg_r;
249
250 /* We also need the same setting for L/R and only one path */
251 reg = snd_soc_read(codec, WM8995_DAC1_LEFT_MIXER_ROUTING);
252 switch (reg) {
253 case WM8995_AIF2DACL_TO_DAC1L:
254 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
255 source = 2 << WM8995_CP_DYN_SRC_SEL_SHIFT;
256 break;
257 case WM8995_AIF1DAC2L_TO_DAC1L:
258 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
259 source = 1 << WM8995_CP_DYN_SRC_SEL_SHIFT;
260 break;
261 case WM8995_AIF1DAC1L_TO_DAC1L:
262 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
263 source = 0 << WM8995_CP_DYN_SRC_SEL_SHIFT;
264 break;
265 default:
266 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
267 enable = 0;
268 break;
269 }
270
271 reg_r = snd_soc_read(codec, WM8995_DAC1_RIGHT_MIXER_ROUTING);
272 if (reg_r != reg) {
273 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
274 enable = 0;
275 }
276
277 if (enable) {
278 dev_dbg(codec->dev, "Class W enabled\n");
279 snd_soc_update_bits(codec, WM8995_CLASS_W_1,
280 WM8995_CP_DYN_PWR_MASK |
281 WM8995_CP_DYN_SRC_SEL_MASK,
282 source | WM8995_CP_DYN_PWR);
283 } else {
284 dev_dbg(codec->dev, "Class W disabled\n");
285 snd_soc_update_bits(codec, WM8995_CLASS_W_1,
286 WM8995_CP_DYN_PWR_MASK, 0);
287 }
288}
289
290static int check_clk_sys(struct snd_soc_dapm_widget *source,
291 struct snd_soc_dapm_widget *sink)
292{
293 unsigned int reg;
294 const char *clk;
295
296 reg = snd_soc_read(source->codec, WM8995_CLOCKING_1);
297 /* Check what we're currently using for CLK_SYS */
298 if (reg & WM8995_SYSCLK_SRC)
299 clk = "AIF2CLK";
300 else
301 clk = "AIF1CLK";
302 return !strcmp(source->name, clk);
303}
304
305static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
306 struct snd_ctl_elem_value *ucontrol)
307{
308 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
309 struct snd_soc_dapm_widget *w = wlist->widgets[0];
310 struct snd_soc_codec *codec;
311 int ret;
312
313 codec = w->codec;
314 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
315 wm8995_update_class_w(codec);
316 return ret;
317}
318
319static int hp_supply_event(struct snd_soc_dapm_widget *w,
320 struct snd_kcontrol *kcontrol, int event)
321{
322 struct snd_soc_codec *codec;
323 struct wm8995_priv *wm8995;
324
325 codec = w->codec;
326 wm8995 = snd_soc_codec_get_drvdata(codec);
327
328 switch (event) {
329 case SND_SOC_DAPM_PRE_PMU:
330 /* Enable the headphone amp */
331 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
332 WM8995_HPOUT1L_ENA_MASK |
333 WM8995_HPOUT1R_ENA_MASK,
334 WM8995_HPOUT1L_ENA |
335 WM8995_HPOUT1R_ENA);
336
337 /* Enable the second stage */
338 snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
339 WM8995_HPOUT1L_DLY_MASK |
340 WM8995_HPOUT1R_DLY_MASK,
341 WM8995_HPOUT1L_DLY |
342 WM8995_HPOUT1R_DLY);
343 break;
344 case SND_SOC_DAPM_PRE_PMD:
345 snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
346 WM8995_CP_ENA_MASK, 0);
347 break;
348 }
349
350 return 0;
351}
352
353static void dc_servo_cmd(struct snd_soc_codec *codec,
354 unsigned int reg, unsigned int val, unsigned int mask)
355{
356 int timeout = 10;
357
358 dev_dbg(codec->dev, "%s: reg = %#x, val = %#x, mask = %#x\n",
359 __func__, reg, val, mask);
360
361 snd_soc_write(codec, reg, val);
362 while (timeout--) {
363 msleep(10);
364 val = snd_soc_read(codec, WM8995_DC_SERVO_READBACK_0);
365 if ((val & mask) == mask)
366 return;
367 }
368
369 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
370}
371
372static int hp_event(struct snd_soc_dapm_widget *w,
373 struct snd_kcontrol *kcontrol, int event)
374{
375 struct snd_soc_codec *codec;
376 unsigned int reg;
377
378 codec = w->codec;
379 reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1);
380
381 switch (event) {
382 case SND_SOC_DAPM_POST_PMU:
383 snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
384 WM8995_CP_ENA_MASK, WM8995_CP_ENA);
385
386 msleep(5);
387
388 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
389 WM8995_HPOUT1L_ENA_MASK |
390 WM8995_HPOUT1R_ENA_MASK,
391 WM8995_HPOUT1L_ENA | WM8995_HPOUT1R_ENA);
392
393 udelay(20);
394
395 reg |= WM8995_HPOUT1L_DLY | WM8995_HPOUT1R_DLY;
396 snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
397
398 snd_soc_write(codec, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 |
399 WM8995_DCS_ENA_CHAN_1);
400
401 dc_servo_cmd(codec, WM8995_DC_SERVO_2,
402 WM8995_DCS_TRIG_STARTUP_0 |
403 WM8995_DCS_TRIG_STARTUP_1,
404 WM8995_DCS_TRIG_DAC_WR_0 |
405 WM8995_DCS_TRIG_DAC_WR_1);
406
407 reg |= WM8995_HPOUT1R_OUTP | WM8995_HPOUT1R_RMV_SHORT |
408 WM8995_HPOUT1L_OUTP | WM8995_HPOUT1L_RMV_SHORT;
409 snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
410
411 break;
412 case SND_SOC_DAPM_PRE_PMD:
413 snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
414 WM8995_HPOUT1L_OUTP_MASK |
415 WM8995_HPOUT1R_OUTP_MASK |
416 WM8995_HPOUT1L_RMV_SHORT_MASK |
417 WM8995_HPOUT1R_RMV_SHORT_MASK, 0);
418
419 snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
420 WM8995_HPOUT1L_DLY_MASK |
421 WM8995_HPOUT1R_DLY_MASK, 0);
422
423 snd_soc_write(codec, WM8995_DC_SERVO_1, 0);
424
425 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
426 WM8995_HPOUT1L_ENA_MASK |
427 WM8995_HPOUT1R_ENA_MASK,
428 0);
429 break;
430 }
431
432 return 0;
433}
434
435static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
436{
437 struct wm8995_priv *wm8995;
438 int rate;
439 int reg1 = 0;
440 int offset;
441
442 wm8995 = snd_soc_codec_get_drvdata(codec);
443
444 if (aif)
445 offset = 4;
446 else
447 offset = 0;
448
449 switch (wm8995->sysclk[aif]) {
450 case WM8995_SYSCLK_MCLK1:
451 rate = wm8995->mclk[0];
452 break;
453 case WM8995_SYSCLK_MCLK2:
454 reg1 |= 0x8;
455 rate = wm8995->mclk[1];
456 break;
457 case WM8995_SYSCLK_FLL1:
458 reg1 |= 0x10;
459 rate = wm8995->fll[0].out;
460 break;
461 case WM8995_SYSCLK_FLL2:
462 reg1 |= 0x18;
463 rate = wm8995->fll[1].out;
464 break;
465 default:
466 return -EINVAL;
467 }
468
469 if (rate >= 13500000) {
470 rate /= 2;
471 reg1 |= WM8995_AIF1CLK_DIV;
472
473 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
474 aif + 1, rate);
475 }
476
477 wm8995->aifclk[aif] = rate;
478
479 snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1 + offset,
480 WM8995_AIF1CLK_SRC_MASK | WM8995_AIF1CLK_DIV_MASK,
481 reg1);
482 return 0;
483}
484
485static int configure_clock(struct snd_soc_codec *codec)
486{
487 struct wm8995_priv *wm8995;
488 int old, new;
489
490 wm8995 = snd_soc_codec_get_drvdata(codec);
491
492 /* Bring up the AIF clocks first */
493 configure_aif_clock(codec, 0);
494 configure_aif_clock(codec, 1);
495
496 /*
497 * Then switch CLK_SYS over to the higher of them; a change
498 * can only happen as a result of a clocking change which can
499 * only be made outside of DAPM so we can safely redo the
500 * clocking.
501 */
502
503 /* If they're equal it doesn't matter which is used */
504 if (wm8995->aifclk[0] == wm8995->aifclk[1])
505 return 0;
506
507 if (wm8995->aifclk[0] < wm8995->aifclk[1])
508 new = WM8995_SYSCLK_SRC;
509 else
510 new = 0;
511
512 old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC;
513
514 /* If there's no change then we're done. */
515 if (old == new)
516 return 0;
517
518 snd_soc_update_bits(codec, WM8995_CLOCKING_1,
519 WM8995_SYSCLK_SRC_MASK, new);
520
521 snd_soc_dapm_sync(&codec->dapm);
522
523 return 0;
524}
525
526static int clk_sys_event(struct snd_soc_dapm_widget *w,
527 struct snd_kcontrol *kcontrol, int event)
528{
529 struct snd_soc_codec *codec;
530
531 codec = w->codec;
532
533 switch (event) {
534 case SND_SOC_DAPM_PRE_PMU:
535 return configure_clock(codec);
536
537 case SND_SOC_DAPM_POST_PMD:
538 configure_clock(codec);
539 break;
540 }
541
542 return 0;
543}
544
545static const char *sidetone_text[] = {
546 "ADC/DMIC1", "DMIC2",
547};
548
549static const struct soc_enum sidetone1_enum =
550 SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text);
551
552static const struct snd_kcontrol_new sidetone1_mux =
553 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
554
555static const struct soc_enum sidetone2_enum =
556 SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text);
557
558static const struct snd_kcontrol_new sidetone2_mux =
559 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
560
561static const struct snd_kcontrol_new aif1adc1l_mix[] = {
562 SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
563 1, 1, 0),
564 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
565 0, 1, 0),
566};
567
568static const struct snd_kcontrol_new aif1adc1r_mix[] = {
569 SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
570 1, 1, 0),
571 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
572 0, 1, 0),
573};
574
575static const struct snd_kcontrol_new aif1adc2l_mix[] = {
576 SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
577 1, 1, 0),
578 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
579 0, 1, 0),
580};
581
582static const struct snd_kcontrol_new aif1adc2r_mix[] = {
583 SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
584 1, 1, 0),
585 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
586 0, 1, 0),
587};
588
589static const struct snd_kcontrol_new dac1l_mix[] = {
590 WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
591 5, 1, 0),
592 WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
593 4, 1, 0),
594 WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
595 2, 1, 0),
596 WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
597 1, 1, 0),
598 WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
599 0, 1, 0),
600};
601
602static const struct snd_kcontrol_new dac1r_mix[] = {
603 WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
604 5, 1, 0),
605 WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
606 4, 1, 0),
607 WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
608 2, 1, 0),
609 WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
610 1, 1, 0),
611 WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
612 0, 1, 0),
613};
614
615static const struct snd_kcontrol_new aif2dac2l_mix[] = {
616 SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
617 5, 1, 0),
618 SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
619 4, 1, 0),
620 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
621 2, 1, 0),
622 SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
623 1, 1, 0),
624 SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
625 0, 1, 0),
626};
627
628static const struct snd_kcontrol_new aif2dac2r_mix[] = {
629 SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
630 5, 1, 0),
631 SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
632 4, 1, 0),
633 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
634 2, 1, 0),
635 SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
636 1, 1, 0),
637 SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
638 0, 1, 0),
639};
640
641static const struct snd_kcontrol_new in1l_pga =
642 SOC_DAPM_SINGLE("IN1L Switch", WM8995_POWER_MANAGEMENT_2, 5, 1, 0);
643
644static const struct snd_kcontrol_new in1r_pga =
645 SOC_DAPM_SINGLE("IN1R Switch", WM8995_POWER_MANAGEMENT_2, 4, 1, 0);
646
647static const char *adc_mux_text[] = {
648 "ADC",
649 "DMIC",
650};
651
652static const struct soc_enum adc_enum =
653 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
654
655static const struct snd_kcontrol_new adcl_mux =
656 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
657
658static const struct snd_kcontrol_new adcr_mux =
659 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
660
661static const char *spk_src_text[] = {
662 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
663};
664
665static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1,
666 0, spk_src_text);
667static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1,
668 0, spk_src_text);
669static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2,
670 0, spk_src_text);
671static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2,
672 0, spk_src_text);
673
674static const struct snd_kcontrol_new spk1l_mux =
675 SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum);
676static const struct snd_kcontrol_new spk1r_mux =
677 SOC_DAPM_ENUM("SPK1R SRC", spk1r_src_enum);
678static const struct snd_kcontrol_new spk2l_mux =
679 SOC_DAPM_ENUM("SPK2L SRC", spk2l_src_enum);
680static const struct snd_kcontrol_new spk2r_mux =
681 SOC_DAPM_ENUM("SPK2R SRC", spk2r_src_enum);
682
683static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = {
684 SND_SOC_DAPM_INPUT("DMIC1DAT"),
685 SND_SOC_DAPM_INPUT("DMIC2DAT"),
686
687 SND_SOC_DAPM_INPUT("IN1L"),
688 SND_SOC_DAPM_INPUT("IN1R"),
689
690 SND_SOC_DAPM_MIXER("IN1L PGA", SND_SOC_NOPM, 0, 0,
691 &in1l_pga, 1),
692 SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0,
693 &in1r_pga, 1),
694
695 SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0),
696 SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0),
697
698 SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0),
699 SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0),
700 SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8995_CLOCKING_1, 3, 0, NULL, 0),
701 SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8995_CLOCKING_1, 2, 0, NULL, 0),
702 SND_SOC_DAPM_SUPPLY("SYSDSPCLK", WM8995_CLOCKING_1, 1, 0, NULL, 0),
703 SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
704 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
705
706 SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", 0,
707 WM8995_POWER_MANAGEMENT_3, 9, 0),
708 SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0,
709 WM8995_POWER_MANAGEMENT_3, 8, 0),
710 SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0,
711 SND_SOC_NOPM, 0, 0),
712 SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
713 0, WM8995_POWER_MANAGEMENT_3, 11, 0),
714 SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
715 0, WM8995_POWER_MANAGEMENT_3, 10, 0),
716
717 SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0,
718 &adcl_mux),
719 SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
720 &adcr_mux),
721
722 SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0),
723 SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0),
724 SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8995_POWER_MANAGEMENT_3, 3, 0),
725 SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8995_POWER_MANAGEMENT_3, 2, 0),
726
727 SND_SOC_DAPM_ADC("ADCL", NULL, WM8995_POWER_MANAGEMENT_3, 1, 0),
728 SND_SOC_DAPM_ADC("ADCR", NULL, WM8995_POWER_MANAGEMENT_3, 0, 0),
729
730 SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
731 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
732 SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
733 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
734 SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
735 aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
736 SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
737 aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
738
739 SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
740 9, 0),
741 SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
742 8, 0),
743 SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM,
744 0, 0),
745
746 SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
747 11, 0),
748 SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
749 10, 0),
750
751 SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
752 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
753 SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
754 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
755
756 SND_SOC_DAPM_DAC("DAC2L", NULL, WM8995_POWER_MANAGEMENT_4, 3, 0),
757 SND_SOC_DAPM_DAC("DAC2R", NULL, WM8995_POWER_MANAGEMENT_4, 2, 0),
758 SND_SOC_DAPM_DAC("DAC1L", NULL, WM8995_POWER_MANAGEMENT_4, 1, 0),
759 SND_SOC_DAPM_DAC("DAC1R", NULL, WM8995_POWER_MANAGEMENT_4, 0, 0),
760
761 SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, dac1l_mix,
762 ARRAY_SIZE(dac1l_mix)),
763 SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix,
764 ARRAY_SIZE(dac1r_mix)),
765
766 SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
767 SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
768
769 SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
770 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
771
772 SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0,
773 hp_supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
774
775 SND_SOC_DAPM_MUX("SPK1L Driver", WM8995_LEFT_PDM_SPEAKER_1,
776 4, 0, &spk1l_mux),
777 SND_SOC_DAPM_MUX("SPK1R Driver", WM8995_RIGHT_PDM_SPEAKER_1,
778 4, 0, &spk1r_mux),
779 SND_SOC_DAPM_MUX("SPK2L Driver", WM8995_LEFT_PDM_SPEAKER_2,
780 4, 0, &spk2l_mux),
781 SND_SOC_DAPM_MUX("SPK2R Driver", WM8995_RIGHT_PDM_SPEAKER_2,
782 4, 0, &spk2r_mux),
783
784 SND_SOC_DAPM_SUPPLY("LDO2", WM8995_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
785
786 SND_SOC_DAPM_OUTPUT("HP1L"),
787 SND_SOC_DAPM_OUTPUT("HP1R"),
788 SND_SOC_DAPM_OUTPUT("SPK1L"),
789 SND_SOC_DAPM_OUTPUT("SPK1R"),
790 SND_SOC_DAPM_OUTPUT("SPK2L"),
791 SND_SOC_DAPM_OUTPUT("SPK2R")
792};
793
794static const struct snd_soc_dapm_route wm8995_intercon[] = {
795 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
796 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
797
798 { "DSP1CLK", NULL, "CLK_SYS" },
799 { "DSP2CLK", NULL, "CLK_SYS" },
800 { "SYSDSPCLK", NULL, "CLK_SYS" },
801
802 { "AIF1ADC1L", NULL, "AIF1CLK" },
803 { "AIF1ADC1L", NULL, "DSP1CLK" },
804 { "AIF1ADC1R", NULL, "AIF1CLK" },
805 { "AIF1ADC1R", NULL, "DSP1CLK" },
806 { "AIF1ADC1R", NULL, "SYSDSPCLK" },
807
808 { "AIF1ADC2L", NULL, "AIF1CLK" },
809 { "AIF1ADC2L", NULL, "DSP1CLK" },
810 { "AIF1ADC2R", NULL, "AIF1CLK" },
811 { "AIF1ADC2R", NULL, "DSP1CLK" },
812 { "AIF1ADC2R", NULL, "SYSDSPCLK" },
813
814 { "DMIC1L", NULL, "DMIC1DAT" },
815 { "DMIC1L", NULL, "CLK_SYS" },
816 { "DMIC1R", NULL, "DMIC1DAT" },
817 { "DMIC1R", NULL, "CLK_SYS" },
818 { "DMIC2L", NULL, "DMIC2DAT" },
819 { "DMIC2L", NULL, "CLK_SYS" },
820 { "DMIC2R", NULL, "DMIC2DAT" },
821 { "DMIC2R", NULL, "CLK_SYS" },
822
823 { "ADCL", NULL, "AIF1CLK" },
824 { "ADCL", NULL, "DSP1CLK" },
825 { "ADCL", NULL, "SYSDSPCLK" },
826
827 { "ADCR", NULL, "AIF1CLK" },
828 { "ADCR", NULL, "DSP1CLK" },
829 { "ADCR", NULL, "SYSDSPCLK" },
830
831 { "IN1L PGA", "IN1L Switch", "IN1L" },
832 { "IN1R PGA", "IN1R Switch", "IN1R" },
833 { "IN1L PGA", NULL, "LDO2" },
834 { "IN1R PGA", NULL, "LDO2" },
835
836 { "ADCL", NULL, "IN1L PGA" },
837 { "ADCR", NULL, "IN1R PGA" },
838
839 { "ADCL Mux", "ADC", "ADCL" },
840 { "ADCL Mux", "DMIC", "DMIC1L" },
841 { "ADCR Mux", "ADC", "ADCR" },
842 { "ADCR Mux", "DMIC", "DMIC1R" },
843
844 /* AIF1 outputs */
845 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
846 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
847
848 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
849 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
850
851 { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
852 { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
853
854 { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
855 { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
856
857 /* Sidetone */
858 { "Left Sidetone", "ADC/DMIC1", "AIF1ADC1L" },
859 { "Left Sidetone", "DMIC2", "AIF1ADC2L" },
860 { "Right Sidetone", "ADC/DMIC1", "AIF1ADC1R" },
861 { "Right Sidetone", "DMIC2", "AIF1ADC2R" },
862
863 { "AIF1DAC1L", NULL, "AIF1CLK" },
864 { "AIF1DAC1L", NULL, "DSP1CLK" },
865 { "AIF1DAC1R", NULL, "AIF1CLK" },
866 { "AIF1DAC1R", NULL, "DSP1CLK" },
867 { "AIF1DAC1R", NULL, "SYSDSPCLK" },
868
869 { "AIF1DAC2L", NULL, "AIF1CLK" },
870 { "AIF1DAC2L", NULL, "DSP1CLK" },
871 { "AIF1DAC2R", NULL, "AIF1CLK" },
872 { "AIF1DAC2R", NULL, "DSP1CLK" },
873 { "AIF1DAC2R", NULL, "SYSDSPCLK" },
874
875 { "DAC1L", NULL, "AIF1CLK" },
876 { "DAC1L", NULL, "DSP1CLK" },
877 { "DAC1L", NULL, "SYSDSPCLK" },
878
879 { "DAC1R", NULL, "AIF1CLK" },
880 { "DAC1R", NULL, "DSP1CLK" },
881 { "DAC1R", NULL, "SYSDSPCLK" },
882
883 { "AIF1DAC1L", NULL, "AIF1DACDAT" },
884 { "AIF1DAC1R", NULL, "AIF1DACDAT" },
885 { "AIF1DAC2L", NULL, "AIF1DACDAT" },
886 { "AIF1DAC2R", NULL, "AIF1DACDAT" },
887
888 /* DAC1 inputs */
889 { "DAC1L", NULL, "DAC1L Mixer" },
890 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
891 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
892 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
893 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
894
895 { "DAC1R", NULL, "DAC1R Mixer" },
896 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
897 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
898 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
899 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
900
901 /* DAC2/AIF2 outputs */
902 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
903 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
904 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
905
906 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
907 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
908 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
909
910 /* Output stages */
911 { "Headphone PGA", NULL, "DAC1L" },
912 { "Headphone PGA", NULL, "DAC1R" },
913
914 { "Headphone PGA", NULL, "DAC2L" },
915 { "Headphone PGA", NULL, "DAC2R" },
916
917 { "Headphone PGA", NULL, "Headphone Supply" },
918 { "Headphone PGA", NULL, "CLK_SYS" },
919 { "Headphone PGA", NULL, "LDO2" },
920
921 { "HP1L", NULL, "Headphone PGA" },
922 { "HP1R", NULL, "Headphone PGA" },
923
924 { "SPK1L Driver", "DAC1L", "DAC1L" },
925 { "SPK1L Driver", "DAC1R", "DAC1R" },
926 { "SPK1L Driver", "DAC2L", "DAC2L" },
927 { "SPK1L Driver", "DAC2R", "DAC2R" },
928 { "SPK1L Driver", NULL, "CLK_SYS" },
929
930 { "SPK1R Driver", "DAC1L", "DAC1L" },
931 { "SPK1R Driver", "DAC1R", "DAC1R" },
932 { "SPK1R Driver", "DAC2L", "DAC2L" },
933 { "SPK1R Driver", "DAC2R", "DAC2R" },
934 { "SPK1R Driver", NULL, "CLK_SYS" },
935
936 { "SPK2L Driver", "DAC1L", "DAC1L" },
937 { "SPK2L Driver", "DAC1R", "DAC1R" },
938 { "SPK2L Driver", "DAC2L", "DAC2L" },
939 { "SPK2L Driver", "DAC2R", "DAC2R" },
940 { "SPK2L Driver", NULL, "CLK_SYS" },
941
942 { "SPK2R Driver", "DAC1L", "DAC1L" },
943 { "SPK2R Driver", "DAC1R", "DAC1R" },
944 { "SPK2R Driver", "DAC2L", "DAC2L" },
945 { "SPK2R Driver", "DAC2R", "DAC2R" },
946 { "SPK2R Driver", NULL, "CLK_SYS" },
947
948 { "SPK1L", NULL, "SPK1L Driver" },
949 { "SPK1R", NULL, "SPK1R Driver" },
950 { "SPK2L", NULL, "SPK2L Driver" },
951 { "SPK2R", NULL, "SPK2R Driver" }
952};
953
954static int wm8995_volatile(struct snd_soc_codec *codec, unsigned int reg)
955{
956 /* out of bounds registers are generally considered
957 * volatile to support register banks that are partially
958 * owned by something else for e.g. a DSP
959 */
960 if (reg > WM8995_MAX_CACHED_REGISTER)
961 return 1;
962
963 switch (reg) {
964 case WM8995_SOFTWARE_RESET:
965 case WM8995_DC_SERVO_READBACK_0:
966 case WM8995_INTERRUPT_STATUS_1:
967 case WM8995_INTERRUPT_STATUS_2:
968 case WM8995_INTERRUPT_STATUS_1_MASK:
969 case WM8995_INTERRUPT_STATUS_2_MASK:
970 case WM8995_INTERRUPT_CONTROL:
971 case WM8995_ACCESSORY_DETECT_MODE1:
972 case WM8995_ACCESSORY_DETECT_MODE2:
973 case WM8995_HEADPHONE_DETECT1:
974 case WM8995_HEADPHONE_DETECT2:
975 return 1;
976 }
977
978 return 0;
979}
980
981static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
982{
983 struct snd_soc_codec *codec = dai->codec;
984 int mute_reg;
985
986 switch (dai->id) {
987 case 0:
988 mute_reg = WM8995_AIF1_DAC1_FILTERS_1;
989 break;
990 case 1:
991 mute_reg = WM8995_AIF2_DAC_FILTERS_1;
992 break;
993 default:
994 return -EINVAL;
995 }
996
997 snd_soc_update_bits(codec, mute_reg, WM8995_AIF1DAC1_MUTE_MASK,
998 !!mute << WM8995_AIF1DAC1_MUTE_SHIFT);
999 return 0;
1000}
1001
1002static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1003{
1004 struct snd_soc_codec *codec;
1005 int master;
1006 int aif;
1007
1008 codec = dai->codec;
1009
1010 master = 0;
1011 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1012 case SND_SOC_DAIFMT_CBS_CFS:
1013 break;
1014 case SND_SOC_DAIFMT_CBM_CFM:
1015 master = WM8995_AIF1_MSTR;
1016 break;
1017 default:
1018 dev_err(dai->dev, "Unknown master/slave configuration\n");
1019 return -EINVAL;
1020 }
1021
1022 aif = 0;
1023 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1024 case SND_SOC_DAIFMT_DSP_B:
1025 aif |= WM8995_AIF1_LRCLK_INV;
1026 case SND_SOC_DAIFMT_DSP_A:
1027 aif |= (0x3 << WM8995_AIF1_FMT_SHIFT);
1028 break;
1029 case SND_SOC_DAIFMT_I2S:
1030 aif |= (0x2 << WM8995_AIF1_FMT_SHIFT);
1031 break;
1032 case SND_SOC_DAIFMT_RIGHT_J:
1033 break;
1034 case SND_SOC_DAIFMT_LEFT_J:
1035 aif |= (0x1 << WM8995_AIF1_FMT_SHIFT);
1036 break;
1037 default:
1038 dev_err(dai->dev, "Unknown dai format\n");
1039 return -EINVAL;
1040 }
1041
1042 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1043 case SND_SOC_DAIFMT_DSP_A:
1044 case SND_SOC_DAIFMT_DSP_B:
1045 /* frame inversion not valid for DSP modes */
1046 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1047 case SND_SOC_DAIFMT_NB_NF:
1048 break;
1049 case SND_SOC_DAIFMT_IB_NF:
1050 aif |= WM8995_AIF1_BCLK_INV;
1051 break;
1052 default:
1053 return -EINVAL;
1054 }
1055 break;
1056
1057 case SND_SOC_DAIFMT_I2S:
1058 case SND_SOC_DAIFMT_RIGHT_J:
1059 case SND_SOC_DAIFMT_LEFT_J:
1060 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1061 case SND_SOC_DAIFMT_NB_NF:
1062 break;
1063 case SND_SOC_DAIFMT_IB_IF:
1064 aif |= WM8995_AIF1_BCLK_INV | WM8995_AIF1_LRCLK_INV;
1065 break;
1066 case SND_SOC_DAIFMT_IB_NF:
1067 aif |= WM8995_AIF1_BCLK_INV;
1068 break;
1069 case SND_SOC_DAIFMT_NB_IF:
1070 aif |= WM8995_AIF1_LRCLK_INV;
1071 break;
1072 default:
1073 return -EINVAL;
1074 }
1075 break;
1076 default:
1077 return -EINVAL;
1078 }
1079
1080 snd_soc_update_bits(codec, WM8995_AIF1_CONTROL_1,
1081 WM8995_AIF1_BCLK_INV_MASK |
1082 WM8995_AIF1_LRCLK_INV_MASK |
1083 WM8995_AIF1_FMT_MASK, aif);
1084 snd_soc_update_bits(codec, WM8995_AIF1_MASTER_SLAVE,
1085 WM8995_AIF1_MSTR_MASK, master);
1086 return 0;
1087}
1088
1089static const int srs[] = {
1090 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
1091 48000, 88200, 96000
1092};
1093
1094static const int fs_ratios[] = {
1095 -1 /* reserved */,
1096 128, 192, 256, 384, 512, 768, 1024, 1408, 1536
1097};
1098
1099static const int bclk_divs[] = {
1100 10, 15, 20, 30, 40, 55, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480
1101};
1102
1103static int wm8995_hw_params(struct snd_pcm_substream *substream,
1104 struct snd_pcm_hw_params *params,
1105 struct snd_soc_dai *dai)
1106{
1107 struct snd_soc_codec *codec;
1108 struct wm8995_priv *wm8995;
1109 int aif1_reg;
1110 int bclk_reg;
1111 int lrclk_reg;
1112 int rate_reg;
1113 int bclk_rate;
1114 int aif1;
1115 int lrclk, bclk;
1116 int i, rate_val, best, best_val, cur_val;
1117
1118 codec = dai->codec;
1119 wm8995 = snd_soc_codec_get_drvdata(codec);
1120
1121 switch (dai->id) {
1122 case 0:
1123 aif1_reg = WM8995_AIF1_CONTROL_1;
1124 bclk_reg = WM8995_AIF1_BCLK;
1125 rate_reg = WM8995_AIF1_RATE;
1126 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
1127 wm8995->lrclk_shared[0] */) {
1128 lrclk_reg = WM8995_AIF1DAC_LRCLK;
1129 } else {
1130 lrclk_reg = WM8995_AIF1ADC_LRCLK;
1131 dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
1132 }
1133 break;
1134 case 1:
1135 aif1_reg = WM8995_AIF2_CONTROL_1;
1136 bclk_reg = WM8995_AIF2_BCLK;
1137 rate_reg = WM8995_AIF2_RATE;
1138 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
1139 wm8995->lrclk_shared[1] */) {
1140 lrclk_reg = WM8995_AIF2DAC_LRCLK;
1141 } else {
1142 lrclk_reg = WM8995_AIF2ADC_LRCLK;
1143 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
1144 }
1145 break;
1146 default:
1147 return -EINVAL;
1148 }
1149
1150 bclk_rate = snd_soc_params_to_bclk(params);
1151 if (bclk_rate < 0)
1152 return bclk_rate;
1153
1154 aif1 = 0;
1155 switch (params_format(params)) {
1156 case SNDRV_PCM_FORMAT_S16_LE:
1157 break;
1158 case SNDRV_PCM_FORMAT_S20_3LE:
1159 aif1 |= (0x1 << WM8995_AIF1_WL_SHIFT);
1160 break;
1161 case SNDRV_PCM_FORMAT_S24_LE:
1162 aif1 |= (0x2 << WM8995_AIF1_WL_SHIFT);
1163 break;
1164 case SNDRV_PCM_FORMAT_S32_LE:
1165 aif1 |= (0x3 << WM8995_AIF1_WL_SHIFT);
1166 break;
1167 default:
1168 dev_err(dai->dev, "Unsupported word length %u\n",
1169 params_format(params));
1170 return -EINVAL;
1171 }
1172
1173 /* try to find a suitable sample rate */
1174 for (i = 0; i < ARRAY_SIZE(srs); ++i)
1175 if (srs[i] == params_rate(params))
1176 break;
1177 if (i == ARRAY_SIZE(srs)) {
1178 dev_err(dai->dev, "Sample rate %d is not supported\n",
1179 params_rate(params));
1180 return -EINVAL;
1181 }
1182 rate_val = i << WM8995_AIF1_SR_SHIFT;
1183
1184 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i]);
1185 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
1186 dai->id + 1, wm8995->aifclk[dai->id], bclk_rate);
1187
1188 /* AIFCLK/fs ratio; look for a close match in either direction */
1189 best = 1;
1190 best_val = abs((fs_ratios[1] * params_rate(params))
1191 - wm8995->aifclk[dai->id]);
1192 for (i = 2; i < ARRAY_SIZE(fs_ratios); i++) {
1193 cur_val = abs((fs_ratios[i] * params_rate(params))
1194 - wm8995->aifclk[dai->id]);
1195 if (cur_val >= best_val)
1196 continue;
1197 best = i;
1198 best_val = cur_val;
1199 }
1200 rate_val |= best;
1201
1202 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
1203 dai->id + 1, fs_ratios[best]);
1204
1205 /*
1206 * We may not get quite the right frequency if using
1207 * approximate clocks so look for the closest match that is
1208 * higher than the target (we need to ensure that there enough
1209 * BCLKs to clock out the samples).
1210 */
1211 best = 0;
1212 bclk = 0;
1213 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1214 cur_val = (wm8995->aifclk[dai->id] * 10 / bclk_divs[i]) - bclk_rate;
1215 if (cur_val < 0) /* BCLK table is sorted */
1216 break;
1217 best = i;
1218 }
1219 bclk |= best << WM8995_AIF1_BCLK_DIV_SHIFT;
1220
1221 bclk_rate = wm8995->aifclk[dai->id] * 10 / bclk_divs[best];
1222 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1223 bclk_divs[best], bclk_rate);
1224
1225 lrclk = bclk_rate / params_rate(params);
1226 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
1227 lrclk, bclk_rate / lrclk);
1228
1229 snd_soc_update_bits(codec, aif1_reg,
1230 WM8995_AIF1_WL_MASK, aif1);
1231 snd_soc_update_bits(codec, bclk_reg,
1232 WM8995_AIF1_BCLK_DIV_MASK, bclk);
1233 snd_soc_update_bits(codec, lrclk_reg,
1234 WM8995_AIF1DAC_RATE_MASK, lrclk);
1235 snd_soc_update_bits(codec, rate_reg,
1236 WM8995_AIF1_SR_MASK |
1237 WM8995_AIF1CLK_RATE_MASK, rate_val);
1238 return 0;
1239}
1240
1241static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
1242{
1243 struct snd_soc_codec *codec = codec_dai->codec;
1244 int reg, val, mask;
1245
1246 switch (codec_dai->id) {
1247 case 0:
1248 reg = WM8995_AIF1_MASTER_SLAVE;
1249 mask = WM8995_AIF1_TRI;
1250 break;
1251 case 1:
1252 reg = WM8995_AIF2_MASTER_SLAVE;
1253 mask = WM8995_AIF2_TRI;
1254 break;
1255 case 2:
1256 reg = WM8995_POWER_MANAGEMENT_5;
1257 mask = WM8995_AIF3_TRI;
1258 break;
1259 default:
1260 return -EINVAL;
1261 }
1262
1263 if (tristate)
1264 val = mask;
1265 else
1266 val = 0;
1267
1268 return snd_soc_update_bits(codec, reg, mask, val);
1269}
1270
1271/* The size in bits of the FLL divide multiplied by 10
1272 * to allow rounding later */
1273#define FIXED_FLL_SIZE ((1 << 16) * 10)
1274
1275struct fll_div {
1276 u16 outdiv;
1277 u16 n;
1278 u16 k;
1279 u16 clk_ref_div;
1280 u16 fll_fratio;
1281};
1282
1283static int wm8995_get_fll_config(struct fll_div *fll,
1284 int freq_in, int freq_out)
1285{
1286 u64 Kpart;
1287 unsigned int K, Ndiv, Nmod;
1288
1289 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
1290
1291 /* Scale the input frequency down to <= 13.5MHz */
1292 fll->clk_ref_div = 0;
1293 while (freq_in > 13500000) {
1294 fll->clk_ref_div++;
1295 freq_in /= 2;
1296
1297 if (fll->clk_ref_div > 3)
1298 return -EINVAL;
1299 }
1300 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
1301
1302 /* Scale the output to give 90MHz<=Fvco<=100MHz */
1303 fll->outdiv = 3;
1304 while (freq_out * (fll->outdiv + 1) < 90000000) {
1305 fll->outdiv++;
1306 if (fll->outdiv > 63)
1307 return -EINVAL;
1308 }
1309 freq_out *= fll->outdiv + 1;
1310 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
1311
1312 if (freq_in > 1000000) {
1313 fll->fll_fratio = 0;
1314 } else if (freq_in > 256000) {
1315 fll->fll_fratio = 1;
1316 freq_in *= 2;
1317 } else if (freq_in > 128000) {
1318 fll->fll_fratio = 2;
1319 freq_in *= 4;
1320 } else if (freq_in > 64000) {
1321 fll->fll_fratio = 3;
1322 freq_in *= 8;
1323 } else {
1324 fll->fll_fratio = 4;
1325 freq_in *= 16;
1326 }
1327 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
1328
1329 /* Now, calculate N.K */
1330 Ndiv = freq_out / freq_in;
1331
1332 fll->n = Ndiv;
1333 Nmod = freq_out % freq_in;
1334 pr_debug("Nmod=%d\n", Nmod);
1335
1336 /* Calculate fractional part - scale up so we can round. */
1337 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1338
1339 do_div(Kpart, freq_in);
1340
1341 K = Kpart & 0xFFFFFFFF;
1342
1343 if ((K % 10) >= 5)
1344 K += 5;
1345
1346 /* Move down to proper range now rounding is done */
1347 fll->k = K / 10;
1348
1349 pr_debug("N=%x K=%x\n", fll->n, fll->k);
1350
1351 return 0;
1352}
1353
1354static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
1355 int src, unsigned int freq_in,
1356 unsigned int freq_out)
1357{
1358 struct snd_soc_codec *codec;
1359 struct wm8995_priv *wm8995;
1360 int reg_offset, ret;
1361 struct fll_div fll;
1362 u16 reg, aif1, aif2;
1363
1364 codec = dai->codec;
1365 wm8995 = snd_soc_codec_get_drvdata(codec);
1366
1367 aif1 = snd_soc_read(codec, WM8995_AIF1_CLOCKING_1)
1368 & WM8995_AIF1CLK_ENA;
1369
1370 aif2 = snd_soc_read(codec, WM8995_AIF2_CLOCKING_1)
1371 & WM8995_AIF2CLK_ENA;
1372
1373 switch (id) {
1374 case WM8995_FLL1:
1375 reg_offset = 0;
1376 id = 0;
1377 break;
1378 case WM8995_FLL2:
1379 reg_offset = 0x20;
1380 id = 1;
1381 break;
1382 default:
1383 return -EINVAL;
1384 }
1385
1386 switch (src) {
1387 case 0:
1388 /* Allow no source specification when stopping */
1389 if (freq_out)
1390 return -EINVAL;
1391 break;
1392 case WM8995_FLL_SRC_MCLK1:
1393 case WM8995_FLL_SRC_MCLK2:
1394 case WM8995_FLL_SRC_LRCLK:
1395 case WM8995_FLL_SRC_BCLK:
1396 break;
1397 default:
1398 return -EINVAL;
1399 }
1400
1401 /* Are we changing anything? */
1402 if (wm8995->fll[id].src == src &&
1403 wm8995->fll[id].in == freq_in && wm8995->fll[id].out == freq_out)
1404 return 0;
1405
1406 /* If we're stopping the FLL redo the old config - no
1407 * registers will actually be written but we avoid GCC flow
1408 * analysis bugs spewing warnings.
1409 */
1410 if (freq_out)
1411 ret = wm8995_get_fll_config(&fll, freq_in, freq_out);
1412 else
1413 ret = wm8995_get_fll_config(&fll, wm8995->fll[id].in,
1414 wm8995->fll[id].out);
1415 if (ret < 0)
1416 return ret;
1417
1418 /* Gate the AIF clocks while we reclock */
1419 snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
1420 WM8995_AIF1CLK_ENA_MASK, 0);
1421 snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
1422 WM8995_AIF2CLK_ENA_MASK, 0);
1423
1424 /* We always need to disable the FLL while reconfiguring */
1425 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
1426 WM8995_FLL1_ENA_MASK, 0);
1427
1428 reg = (fll.outdiv << WM8995_FLL1_OUTDIV_SHIFT) |
1429 (fll.fll_fratio << WM8995_FLL1_FRATIO_SHIFT);
1430 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_2 + reg_offset,
1431 WM8995_FLL1_OUTDIV_MASK |
1432 WM8995_FLL1_FRATIO_MASK, reg);
1433
1434 snd_soc_write(codec, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k);
1435
1436 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_4 + reg_offset,
1437 WM8995_FLL1_N_MASK,
1438 fll.n << WM8995_FLL1_N_SHIFT);
1439
1440 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_5 + reg_offset,
1441 WM8995_FLL1_REFCLK_DIV_MASK |
1442 WM8995_FLL1_REFCLK_SRC_MASK,
1443 (fll.clk_ref_div << WM8995_FLL1_REFCLK_DIV_SHIFT) |
1444 (src - 1));
1445
1446 if (freq_out)
1447 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
1448 WM8995_FLL1_ENA_MASK, WM8995_FLL1_ENA);
1449
1450 wm8995->fll[id].in = freq_in;
1451 wm8995->fll[id].out = freq_out;
1452 wm8995->fll[id].src = src;
1453
1454 /* Enable any gated AIF clocks */
1455 snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
1456 WM8995_AIF1CLK_ENA_MASK, aif1);
1457 snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
1458 WM8995_AIF2CLK_ENA_MASK, aif2);
1459
1460 configure_clock(codec);
1461
1462 return 0;
1463}
1464
1465static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
1466 int clk_id, unsigned int freq, int dir)
1467{
1468 struct snd_soc_codec *codec;
1469 struct wm8995_priv *wm8995;
1470
1471 codec = dai->codec;
1472 wm8995 = snd_soc_codec_get_drvdata(codec);
1473
1474 switch (dai->id) {
1475 case 0:
1476 case 1:
1477 break;
1478 default:
1479 /* AIF3 shares clocking with AIF1/2 */
1480 return -EINVAL;
1481 }
1482
1483 switch (clk_id) {
1484 case WM8995_SYSCLK_MCLK1:
1485 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
1486 wm8995->mclk[0] = freq;
1487 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
1488 dai->id + 1, freq);
1489 break;
1490 case WM8995_SYSCLK_MCLK2:
1491 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
1492 wm8995->mclk[1] = freq;
1493 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
1494 dai->id + 1, freq);
1495 break;
1496 case WM8995_SYSCLK_FLL1:
1497 wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL1;
1498 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id + 1);
1499 break;
1500 case WM8995_SYSCLK_FLL2:
1501 wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL2;
1502 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id + 1);
1503 break;
1504 case WM8995_SYSCLK_OPCLK:
1505 default:
1506 dev_err(dai->dev, "Unknown clock source %d\n", clk_id);
1507 return -EINVAL;
1508 }
1509
1510 configure_clock(codec);
1511
1512 return 0;
1513}
1514
1515static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1516 enum snd_soc_bias_level level)
1517{
1518 struct wm8995_priv *wm8995;
1519 int ret;
1520
1521 wm8995 = snd_soc_codec_get_drvdata(codec);
1522 switch (level) {
1523 case SND_SOC_BIAS_ON:
1524 case SND_SOC_BIAS_PREPARE:
1525 break;
1526 case SND_SOC_BIAS_STANDBY:
1527 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1528 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
1529 wm8995->supplies);
1530 if (ret)
1531 return ret;
1532
1533 ret = snd_soc_cache_sync(codec);
1534 if (ret) {
1535 dev_err(codec->dev,
1536 "Failed to sync cache: %d\n", ret);
1537 return ret;
1538 }
1539
1540 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1541 WM8995_BG_ENA_MASK, WM8995_BG_ENA);
1542 }
1543 break;
1544 case SND_SOC_BIAS_OFF:
1545 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1546 WM8995_BG_ENA_MASK, 0);
1547 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies),
1548 wm8995->supplies);
1549 break;
1550 }
1551
1552 codec->dapm.bias_level = level;
1553 return 0;
1554}
1555
1556#ifdef CONFIG_PM
1557static int wm8995_suspend(struct snd_soc_codec *codec, pm_message_t state)
1558{
1559 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1560 return 0;
1561}
1562
1563static int wm8995_resume(struct snd_soc_codec *codec)
1564{
1565 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1566 return 0;
1567}
1568#else
1569#define wm8995_suspend NULL
1570#define wm8995_resume NULL
1571#endif
1572
1573static int wm8995_remove(struct snd_soc_codec *codec)
1574{
1575 struct wm8995_priv *wm8995;
1576 struct i2c_client *i2c;
1577
1578 i2c = container_of(codec->dev, struct i2c_client, dev);
1579 wm8995 = snd_soc_codec_get_drvdata(codec);
1580 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1581 return 0;
1582}
1583
1584static int wm8995_probe(struct snd_soc_codec *codec)
1585{
1586 struct wm8995_priv *wm8995;
1587 int i;
1588 int ret;
1589
1590 codec->dapm.idle_bias_off = 1;
1591 wm8995 = snd_soc_codec_get_drvdata(codec);
1592 wm8995->codec = codec;
1593
1594 ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
1595 if (ret < 0) {
1596 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1597 return ret;
1598 }
1599
1600 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++)
1601 wm8995->supplies[i].supply = wm8995_supply_names[i];
1602
1603 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8995->supplies),
1604 wm8995->supplies);
1605 if (ret) {
1606 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1607 return ret;
1608 }
1609
1610 wm8995->disable_nb[0].notifier_call = wm8995_regulator_event_0;
1611 wm8995->disable_nb[1].notifier_call = wm8995_regulator_event_1;
1612 wm8995->disable_nb[2].notifier_call = wm8995_regulator_event_2;
1613 wm8995->disable_nb[3].notifier_call = wm8995_regulator_event_3;
1614 wm8995->disable_nb[4].notifier_call = wm8995_regulator_event_4;
1615 wm8995->disable_nb[5].notifier_call = wm8995_regulator_event_5;
1616 wm8995->disable_nb[6].notifier_call = wm8995_regulator_event_6;
1617 wm8995->disable_nb[7].notifier_call = wm8995_regulator_event_7;
1618
1619 /* This should really be moved into the regulator core */
1620 for (i = 0; i < ARRAY_SIZE(wm8995->supplies); i++) {
1621 ret = regulator_register_notifier(wm8995->supplies[i].consumer,
1622 &wm8995->disable_nb[i]);
1623 if (ret) {
1624 dev_err(codec->dev,
1625 "Failed to register regulator notifier: %d\n",
1626 ret);
1627 }
1628 }
1629
1630 ret = regulator_bulk_enable(ARRAY_SIZE(wm8995->supplies),
1631 wm8995->supplies);
1632 if (ret) {
1633 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1634 goto err_reg_get;
1635 }
1636
1637 ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
1638 if (ret < 0) {
1639 dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
1640 goto err_reg_enable;
1641 }
1642
1643 if (ret != 0x8995) {
1644 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1645 goto err_reg_enable;
1646 }
1647
1648 ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
1649 if (ret < 0) {
1650 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1651 goto err_reg_enable;
1652 }
1653
1654 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1655
1656 /* Latch volume updates (right only; we always do left then right). */
1657 snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME,
1658 WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU);
1659 snd_soc_update_bits(codec, WM8995_AIF1_DAC2_RIGHT_VOLUME,
1660 WM8995_AIF1DAC2_VU_MASK, WM8995_AIF1DAC2_VU);
1661 snd_soc_update_bits(codec, WM8995_AIF2_DAC_RIGHT_VOLUME,
1662 WM8995_AIF2DAC_VU_MASK, WM8995_AIF2DAC_VU);
1663 snd_soc_update_bits(codec, WM8995_AIF1_ADC1_RIGHT_VOLUME,
1664 WM8995_AIF1ADC1_VU_MASK, WM8995_AIF1ADC1_VU);
1665 snd_soc_update_bits(codec, WM8995_AIF1_ADC2_RIGHT_VOLUME,
1666 WM8995_AIF1ADC2_VU_MASK, WM8995_AIF1ADC2_VU);
1667 snd_soc_update_bits(codec, WM8995_AIF2_ADC_RIGHT_VOLUME,
1668 WM8995_AIF2ADC_VU_MASK, WM8995_AIF1ADC2_VU);
1669 snd_soc_update_bits(codec, WM8995_DAC1_RIGHT_VOLUME,
1670 WM8995_DAC1_VU_MASK, WM8995_DAC1_VU);
1671 snd_soc_update_bits(codec, WM8995_DAC2_RIGHT_VOLUME,
1672 WM8995_DAC2_VU_MASK, WM8995_DAC2_VU);
1673 snd_soc_update_bits(codec, WM8995_RIGHT_LINE_INPUT_1_VOLUME,
1674 WM8995_IN1_VU_MASK, WM8995_IN1_VU);
1675
1676 wm8995_update_class_w(codec);
1677
1678 snd_soc_add_controls(codec, wm8995_snd_controls,
1679 ARRAY_SIZE(wm8995_snd_controls));
1680 snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
1681 ARRAY_SIZE(wm8995_dapm_widgets));
1682 snd_soc_dapm_add_routes(&codec->dapm, wm8995_intercon,
1683 ARRAY_SIZE(wm8995_intercon));
1684
1685 return 0;
1686
1687err_reg_enable:
1688 regulator_bulk_disable(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1689err_reg_get:
1690 regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies);
1691 return ret;
1692}
1693
1694#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1695 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1696
1697static struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
1698 .set_sysclk = wm8995_set_dai_sysclk,
1699 .set_fmt = wm8995_set_dai_fmt,
1700 .hw_params = wm8995_hw_params,
1701 .digital_mute = wm8995_aif_mute,
1702 .set_pll = wm8995_set_fll,
1703 .set_tristate = wm8995_set_tristate,
1704};
1705
1706static struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
1707 .set_sysclk = wm8995_set_dai_sysclk,
1708 .set_fmt = wm8995_set_dai_fmt,
1709 .hw_params = wm8995_hw_params,
1710 .digital_mute = wm8995_aif_mute,
1711 .set_pll = wm8995_set_fll,
1712 .set_tristate = wm8995_set_tristate,
1713};
1714
1715static struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
1716 .set_tristate = wm8995_set_tristate,
1717};
1718
1719static struct snd_soc_dai_driver wm8995_dai[] = {
1720 {
1721 .name = "wm8995-aif1",
1722 .playback = {
1723 .stream_name = "AIF1 Playback",
1724 .channels_min = 2,
1725 .channels_max = 2,
1726 .rates = SNDRV_PCM_RATE_8000_96000,
1727 .formats = WM8995_FORMATS
1728 },
1729 .capture = {
1730 .stream_name = "AIF1 Capture",
1731 .channels_min = 2,
1732 .channels_max = 2,
1733 .rates = SNDRV_PCM_RATE_8000_48000,
1734 .formats = WM8995_FORMATS
1735 },
1736 .ops = &wm8995_aif1_dai_ops
1737 },
1738 {
1739 .name = "wm8995-aif2",
1740 .playback = {
1741 .stream_name = "AIF2 Playback",
1742 .channels_min = 2,
1743 .channels_max = 2,
1744 .rates = SNDRV_PCM_RATE_8000_96000,
1745 .formats = WM8995_FORMATS
1746 },
1747 .capture = {
1748 .stream_name = "AIF2 Capture",
1749 .channels_min = 2,
1750 .channels_max = 2,
1751 .rates = SNDRV_PCM_RATE_8000_48000,
1752 .formats = WM8995_FORMATS
1753 },
1754 .ops = &wm8995_aif2_dai_ops
1755 },
1756 {
1757 .name = "wm8995-aif3",
1758 .playback = {
1759 .stream_name = "AIF3 Playback",
1760 .channels_min = 2,
1761 .channels_max = 2,
1762 .rates = SNDRV_PCM_RATE_8000_96000,
1763 .formats = WM8995_FORMATS
1764 },
1765 .capture = {
1766 .stream_name = "AIF3 Capture",
1767 .channels_min = 2,
1768 .channels_max = 2,
1769 .rates = SNDRV_PCM_RATE_8000_48000,
1770 .formats = WM8995_FORMATS
1771 },
1772 .ops = &wm8995_aif3_dai_ops
1773 }
1774};
1775
1776static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
1777 .probe = wm8995_probe,
1778 .remove = wm8995_remove,
1779 .suspend = wm8995_suspend,
1780 .resume = wm8995_resume,
1781 .set_bias_level = wm8995_set_bias_level,
1782 .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs),
1783 .reg_word_size = sizeof(u16),
1784 .reg_cache_default = wm8995_reg_defs,
1785 .volatile_register = wm8995_volatile,
1786 .compress_type = SND_SOC_RBTREE_COMPRESSION
1787};
1788
1789#if defined(CONFIG_SPI_MASTER)
1790static int __devinit wm8995_spi_probe(struct spi_device *spi)
1791{
1792 struct wm8995_priv *wm8995;
1793 int ret;
1794
1795 wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
1796 if (!wm8995)
1797 return -ENOMEM;
1798
1799 wm8995->control_type = SND_SOC_SPI;
1800 spi_set_drvdata(spi, wm8995);
1801
1802 ret = snd_soc_register_codec(&spi->dev,
1803 &soc_codec_dev_wm8995, wm8995_dai,
1804 ARRAY_SIZE(wm8995_dai));
1805 if (ret < 0)
1806 kfree(wm8995);
1807 return ret;
1808}
1809
1810static int __devexit wm8995_spi_remove(struct spi_device *spi)
1811{
1812 snd_soc_unregister_codec(&spi->dev);
1813 kfree(spi_get_drvdata(spi));
1814 return 0;
1815}
1816
1817static struct spi_driver wm8995_spi_driver = {
1818 .driver = {
1819 .name = "wm8995",
1820 .owner = THIS_MODULE,
1821 },
1822 .probe = wm8995_spi_probe,
1823 .remove = __devexit_p(wm8995_spi_remove)
1824};
1825#endif
1826
1827#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1828static __devinit int wm8995_i2c_probe(struct i2c_client *i2c,
1829 const struct i2c_device_id *id)
1830{
1831 struct wm8995_priv *wm8995;
1832 int ret;
1833
1834 wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
1835 if (!wm8995)
1836 return -ENOMEM;
1837
1838 wm8995->control_type = SND_SOC_I2C;
1839 i2c_set_clientdata(i2c, wm8995);
1840
1841 ret = snd_soc_register_codec(&i2c->dev,
1842 &soc_codec_dev_wm8995, wm8995_dai,
1843 ARRAY_SIZE(wm8995_dai));
1844 if (ret < 0)
1845 kfree(wm8995);
1846 return ret;
1847}
1848
1849static __devexit int wm8995_i2c_remove(struct i2c_client *client)
1850{
1851 snd_soc_unregister_codec(&client->dev);
1852 kfree(i2c_get_clientdata(client));
1853 return 0;
1854}
1855
1856static const struct i2c_device_id wm8995_i2c_id[] = {
1857 {"wm8995", 0},
1858 {}
1859};
1860
1861MODULE_DEVICE_TABLE(i2c, wm8995_i2c_id);
1862
1863static struct i2c_driver wm8995_i2c_driver = {
1864 .driver = {
1865 .name = "wm8995",
1866 .owner = THIS_MODULE,
1867 },
1868 .probe = wm8995_i2c_probe,
1869 .remove = __devexit_p(wm8995_i2c_remove),
1870 .id_table = wm8995_i2c_id
1871};
1872#endif
1873
1874static int __init wm8995_modinit(void)
1875{
1876 int ret = 0;
1877
1878#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1879 ret = i2c_add_driver(&wm8995_i2c_driver);
1880 if (ret) {
1881 printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n",
1882 ret);
1883 }
1884#endif
1885#if defined(CONFIG_SPI_MASTER)
1886 ret = spi_register_driver(&wm8995_spi_driver);
1887 if (ret) {
1888 printk(KERN_ERR "Failed to register wm8995 SPI driver: %d\n",
1889 ret);
1890 }
1891#endif
1892 return ret;
1893}
1894
1895module_init(wm8995_modinit);
1896
1897static void __exit wm8995_exit(void)
1898{
1899#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1900 i2c_del_driver(&wm8995_i2c_driver);
1901#endif
1902#if defined(CONFIG_SPI_MASTER)
1903 spi_unregister_driver(&wm8995_spi_driver);
1904#endif
1905}
1906
1907module_exit(wm8995_exit);
1908
1909MODULE_DESCRIPTION("ASoC WM8995 driver");
1910MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
1911MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h
new file mode 100644
index 000000000000..5642121c4977
--- /dev/null
+++ b/sound/soc/codecs/wm8995.h
@@ -0,0 +1,4269 @@
1/*
2 * wm8995.h -- WM8995 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8995_H
14#define _WM8995_H
15
16#include <asm/types.h>
17
18/*
19 * Register values.
20 */
21#define WM8995_SOFTWARE_RESET 0x00
22#define WM8995_POWER_MANAGEMENT_1 0x01
23#define WM8995_POWER_MANAGEMENT_2 0x02
24#define WM8995_POWER_MANAGEMENT_3 0x03
25#define WM8995_POWER_MANAGEMENT_4 0x04
26#define WM8995_POWER_MANAGEMENT_5 0x05
27#define WM8995_LEFT_LINE_INPUT_1_VOLUME 0x10
28#define WM8995_RIGHT_LINE_INPUT_1_VOLUME 0x11
29#define WM8995_LEFT_LINE_INPUT_CONTROL 0x12
30#define WM8995_DAC1_LEFT_VOLUME 0x18
31#define WM8995_DAC1_RIGHT_VOLUME 0x19
32#define WM8995_DAC2_LEFT_VOLUME 0x1A
33#define WM8995_DAC2_RIGHT_VOLUME 0x1B
34#define WM8995_OUTPUT_VOLUME_ZC_1 0x1C
35#define WM8995_MICBIAS_1 0x20
36#define WM8995_MICBIAS_2 0x21
37#define WM8995_LDO_1 0x28
38#define WM8995_LDO_2 0x29
39#define WM8995_ACCESSORY_DETECT_MODE1 0x30
40#define WM8995_ACCESSORY_DETECT_MODE2 0x31
41#define WM8995_HEADPHONE_DETECT1 0x34
42#define WM8995_HEADPHONE_DETECT2 0x35
43#define WM8995_MIC_DETECT_1 0x38
44#define WM8995_MIC_DETECT_2 0x39
45#define WM8995_CHARGE_PUMP_1 0x40
46#define WM8995_CLASS_W_1 0x45
47#define WM8995_DC_SERVO_1 0x50
48#define WM8995_DC_SERVO_2 0x51
49#define WM8995_DC_SERVO_3 0x52
50#define WM8995_DC_SERVO_5 0x54
51#define WM8995_DC_SERVO_6 0x55
52#define WM8995_DC_SERVO_7 0x56
53#define WM8995_DC_SERVO_READBACK_0 0x57
54#define WM8995_ANALOGUE_HP_1 0x60
55#define WM8995_ANALOGUE_HP_2 0x61
56#define WM8995_CHIP_REVISION 0x100
57#define WM8995_CONTROL_INTERFACE_1 0x101
58#define WM8995_CONTROL_INTERFACE_2 0x102
59#define WM8995_WRITE_SEQUENCER_CTRL_1 0x110
60#define WM8995_WRITE_SEQUENCER_CTRL_2 0x111
61#define WM8995_AIF1_CLOCKING_1 0x200
62#define WM8995_AIF1_CLOCKING_2 0x201
63#define WM8995_AIF2_CLOCKING_1 0x204
64#define WM8995_AIF2_CLOCKING_2 0x205
65#define WM8995_CLOCKING_1 0x208
66#define WM8995_CLOCKING_2 0x209
67#define WM8995_AIF1_RATE 0x210
68#define WM8995_AIF2_RATE 0x211
69#define WM8995_RATE_STATUS 0x212
70#define WM8995_FLL1_CONTROL_1 0x220
71#define WM8995_FLL1_CONTROL_2 0x221
72#define WM8995_FLL1_CONTROL_3 0x222
73#define WM8995_FLL1_CONTROL_4 0x223
74#define WM8995_FLL1_CONTROL_5 0x224
75#define WM8995_FLL2_CONTROL_1 0x240
76#define WM8995_FLL2_CONTROL_2 0x241
77#define WM8995_FLL2_CONTROL_3 0x242
78#define WM8995_FLL2_CONTROL_4 0x243
79#define WM8995_FLL2_CONTROL_5 0x244
80#define WM8995_AIF1_CONTROL_1 0x300
81#define WM8995_AIF1_CONTROL_2 0x301
82#define WM8995_AIF1_MASTER_SLAVE 0x302
83#define WM8995_AIF1_BCLK 0x303
84#define WM8995_AIF1ADC_LRCLK 0x304
85#define WM8995_AIF1DAC_LRCLK 0x305
86#define WM8995_AIF1DAC_DATA 0x306
87#define WM8995_AIF1ADC_DATA 0x307
88#define WM8995_AIF2_CONTROL_1 0x310
89#define WM8995_AIF2_CONTROL_2 0x311
90#define WM8995_AIF2_MASTER_SLAVE 0x312
91#define WM8995_AIF2_BCLK 0x313
92#define WM8995_AIF2ADC_LRCLK 0x314
93#define WM8995_AIF2DAC_LRCLK 0x315
94#define WM8995_AIF2DAC_DATA 0x316
95#define WM8995_AIF2ADC_DATA 0x317
96#define WM8995_AIF1_ADC1_LEFT_VOLUME 0x400
97#define WM8995_AIF1_ADC1_RIGHT_VOLUME 0x401
98#define WM8995_AIF1_DAC1_LEFT_VOLUME 0x402
99#define WM8995_AIF1_DAC1_RIGHT_VOLUME 0x403
100#define WM8995_AIF1_ADC2_LEFT_VOLUME 0x404
101#define WM8995_AIF1_ADC2_RIGHT_VOLUME 0x405
102#define WM8995_AIF1_DAC2_LEFT_VOLUME 0x406
103#define WM8995_AIF1_DAC2_RIGHT_VOLUME 0x407
104#define WM8995_AIF1_ADC1_FILTERS 0x410
105#define WM8995_AIF1_ADC2_FILTERS 0x411
106#define WM8995_AIF1_DAC1_FILTERS_1 0x420
107#define WM8995_AIF1_DAC1_FILTERS_2 0x421
108#define WM8995_AIF1_DAC2_FILTERS_1 0x422
109#define WM8995_AIF1_DAC2_FILTERS_2 0x423
110#define WM8995_AIF1_DRC1_1 0x440
111#define WM8995_AIF1_DRC1_2 0x441
112#define WM8995_AIF1_DRC1_3 0x442
113#define WM8995_AIF1_DRC1_4 0x443
114#define WM8995_AIF1_DRC1_5 0x444
115#define WM8995_AIF1_DRC2_1 0x450
116#define WM8995_AIF1_DRC2_2 0x451
117#define WM8995_AIF1_DRC2_3 0x452
118#define WM8995_AIF1_DRC2_4 0x453
119#define WM8995_AIF1_DRC2_5 0x454
120#define WM8995_AIF1_DAC1_EQ_GAINS_1 0x480
121#define WM8995_AIF1_DAC1_EQ_GAINS_2 0x481
122#define WM8995_AIF1_DAC1_EQ_BAND_1_A 0x482
123#define WM8995_AIF1_DAC1_EQ_BAND_1_B 0x483
124#define WM8995_AIF1_DAC1_EQ_BAND_1_PG 0x484
125#define WM8995_AIF1_DAC1_EQ_BAND_2_A 0x485
126#define WM8995_AIF1_DAC1_EQ_BAND_2_B 0x486
127#define WM8995_AIF1_DAC1_EQ_BAND_2_C 0x487
128#define WM8995_AIF1_DAC1_EQ_BAND_2_PG 0x488
129#define WM8995_AIF1_DAC1_EQ_BAND_3_A 0x489
130#define WM8995_AIF1_DAC1_EQ_BAND_3_B 0x48A
131#define WM8995_AIF1_DAC1_EQ_BAND_3_C 0x48B
132#define WM8995_AIF1_DAC1_EQ_BAND_3_PG 0x48C
133#define WM8995_AIF1_DAC1_EQ_BAND_4_A 0x48D
134#define WM8995_AIF1_DAC1_EQ_BAND_4_B 0x48E
135#define WM8995_AIF1_DAC1_EQ_BAND_4_C 0x48F
136#define WM8995_AIF1_DAC1_EQ_BAND_4_PG 0x490
137#define WM8995_AIF1_DAC1_EQ_BAND_5_A 0x491
138#define WM8995_AIF1_DAC1_EQ_BAND_5_B 0x492
139#define WM8995_AIF1_DAC1_EQ_BAND_5_PG 0x493
140#define WM8995_AIF1_DAC2_EQ_GAINS_1 0x4A0
141#define WM8995_AIF1_DAC2_EQ_GAINS_2 0x4A1
142#define WM8995_AIF1_DAC2_EQ_BAND_1_A 0x4A2
143#define WM8995_AIF1_DAC2_EQ_BAND_1_B 0x4A3
144#define WM8995_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
145#define WM8995_AIF1_DAC2_EQ_BAND_2_A 0x4A5
146#define WM8995_AIF1_DAC2_EQ_BAND_2_B 0x4A6
147#define WM8995_AIF1_DAC2_EQ_BAND_2_C 0x4A7
148#define WM8995_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
149#define WM8995_AIF1_DAC2_EQ_BAND_3_A 0x4A9
150#define WM8995_AIF1_DAC2_EQ_BAND_3_B 0x4AA
151#define WM8995_AIF1_DAC2_EQ_BAND_3_C 0x4AB
152#define WM8995_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
153#define WM8995_AIF1_DAC2_EQ_BAND_4_A 0x4AD
154#define WM8995_AIF1_DAC2_EQ_BAND_4_B 0x4AE
155#define WM8995_AIF1_DAC2_EQ_BAND_4_C 0x4AF
156#define WM8995_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
157#define WM8995_AIF1_DAC2_EQ_BAND_5_A 0x4B1
158#define WM8995_AIF1_DAC2_EQ_BAND_5_B 0x4B2
159#define WM8995_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
160#define WM8995_AIF2_ADC_LEFT_VOLUME 0x500
161#define WM8995_AIF2_ADC_RIGHT_VOLUME 0x501
162#define WM8995_AIF2_DAC_LEFT_VOLUME 0x502
163#define WM8995_AIF2_DAC_RIGHT_VOLUME 0x503
164#define WM8995_AIF2_ADC_FILTERS 0x510
165#define WM8995_AIF2_DAC_FILTERS_1 0x520
166#define WM8995_AIF2_DAC_FILTERS_2 0x521
167#define WM8995_AIF2_DRC_1 0x540
168#define WM8995_AIF2_DRC_2 0x541
169#define WM8995_AIF2_DRC_3 0x542
170#define WM8995_AIF2_DRC_4 0x543
171#define WM8995_AIF2_DRC_5 0x544
172#define WM8995_AIF2_EQ_GAINS_1 0x580
173#define WM8995_AIF2_EQ_GAINS_2 0x581
174#define WM8995_AIF2_EQ_BAND_1_A 0x582
175#define WM8995_AIF2_EQ_BAND_1_B 0x583
176#define WM8995_AIF2_EQ_BAND_1_PG 0x584
177#define WM8995_AIF2_EQ_BAND_2_A 0x585
178#define WM8995_AIF2_EQ_BAND_2_B 0x586
179#define WM8995_AIF2_EQ_BAND_2_C 0x587
180#define WM8995_AIF2_EQ_BAND_2_PG 0x588
181#define WM8995_AIF2_EQ_BAND_3_A 0x589
182#define WM8995_AIF2_EQ_BAND_3_B 0x58A
183#define WM8995_AIF2_EQ_BAND_3_C 0x58B
184#define WM8995_AIF2_EQ_BAND_3_PG 0x58C
185#define WM8995_AIF2_EQ_BAND_4_A 0x58D
186#define WM8995_AIF2_EQ_BAND_4_B 0x58E
187#define WM8995_AIF2_EQ_BAND_4_C 0x58F
188#define WM8995_AIF2_EQ_BAND_4_PG 0x590
189#define WM8995_AIF2_EQ_BAND_5_A 0x591
190#define WM8995_AIF2_EQ_BAND_5_B 0x592
191#define WM8995_AIF2_EQ_BAND_5_PG 0x593
192#define WM8995_DAC1_MIXER_VOLUMES 0x600
193#define WM8995_DAC1_LEFT_MIXER_ROUTING 0x601
194#define WM8995_DAC1_RIGHT_MIXER_ROUTING 0x602
195#define WM8995_DAC2_MIXER_VOLUMES 0x603
196#define WM8995_DAC2_LEFT_MIXER_ROUTING 0x604
197#define WM8995_DAC2_RIGHT_MIXER_ROUTING 0x605
198#define WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
199#define WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
200#define WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
201#define WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
202#define WM8995_DAC_SOFTMUTE 0x610
203#define WM8995_OVERSAMPLING 0x620
204#define WM8995_SIDETONE 0x621
205#define WM8995_GPIO_1 0x700
206#define WM8995_GPIO_2 0x701
207#define WM8995_GPIO_3 0x702
208#define WM8995_GPIO_4 0x703
209#define WM8995_GPIO_5 0x704
210#define WM8995_GPIO_6 0x705
211#define WM8995_GPIO_7 0x706
212#define WM8995_GPIO_8 0x707
213#define WM8995_GPIO_9 0x708
214#define WM8995_GPIO_10 0x709
215#define WM8995_GPIO_11 0x70A
216#define WM8995_GPIO_12 0x70B
217#define WM8995_GPIO_13 0x70C
218#define WM8995_GPIO_14 0x70D
219#define WM8995_PULL_CONTROL_1 0x720
220#define WM8995_PULL_CONTROL_2 0x721
221#define WM8995_INTERRUPT_STATUS_1 0x730
222#define WM8995_INTERRUPT_STATUS_2 0x731
223#define WM8995_INTERRUPT_RAW_STATUS_2 0x732
224#define WM8995_INTERRUPT_STATUS_1_MASK 0x738
225#define WM8995_INTERRUPT_STATUS_2_MASK 0x739
226#define WM8995_INTERRUPT_CONTROL 0x740
227#define WM8995_LEFT_PDM_SPEAKER_1 0x800
228#define WM8995_RIGHT_PDM_SPEAKER_1 0x801
229#define WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE 0x802
230#define WM8995_LEFT_PDM_SPEAKER_2 0x808
231#define WM8995_RIGHT_PDM_SPEAKER_2 0x809
232#define WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE 0x80A
233#define WM8995_WRITE_SEQUENCER_0 0x3000
234#define WM8995_WRITE_SEQUENCER_1 0x3001
235#define WM8995_WRITE_SEQUENCER_2 0x3002
236#define WM8995_WRITE_SEQUENCER_3 0x3003
237#define WM8995_WRITE_SEQUENCER_4 0x3004
238#define WM8995_WRITE_SEQUENCER_5 0x3005
239#define WM8995_WRITE_SEQUENCER_6 0x3006
240#define WM8995_WRITE_SEQUENCER_7 0x3007
241#define WM8995_WRITE_SEQUENCER_8 0x3008
242#define WM8995_WRITE_SEQUENCER_9 0x3009
243#define WM8995_WRITE_SEQUENCER_10 0x300A
244#define WM8995_WRITE_SEQUENCER_11 0x300B
245#define WM8995_WRITE_SEQUENCER_12 0x300C
246#define WM8995_WRITE_SEQUENCER_13 0x300D
247#define WM8995_WRITE_SEQUENCER_14 0x300E
248#define WM8995_WRITE_SEQUENCER_15 0x300F
249#define WM8995_WRITE_SEQUENCER_16 0x3010
250#define WM8995_WRITE_SEQUENCER_17 0x3011
251#define WM8995_WRITE_SEQUENCER_18 0x3012
252#define WM8995_WRITE_SEQUENCER_19 0x3013
253#define WM8995_WRITE_SEQUENCER_20 0x3014
254#define WM8995_WRITE_SEQUENCER_21 0x3015
255#define WM8995_WRITE_SEQUENCER_22 0x3016
256#define WM8995_WRITE_SEQUENCER_23 0x3017
257#define WM8995_WRITE_SEQUENCER_24 0x3018
258#define WM8995_WRITE_SEQUENCER_25 0x3019
259#define WM8995_WRITE_SEQUENCER_26 0x301A
260#define WM8995_WRITE_SEQUENCER_27 0x301B
261#define WM8995_WRITE_SEQUENCER_28 0x301C
262#define WM8995_WRITE_SEQUENCER_29 0x301D
263#define WM8995_WRITE_SEQUENCER_30 0x301E
264#define WM8995_WRITE_SEQUENCER_31 0x301F
265#define WM8995_WRITE_SEQUENCER_32 0x3020
266#define WM8995_WRITE_SEQUENCER_33 0x3021
267#define WM8995_WRITE_SEQUENCER_34 0x3022
268#define WM8995_WRITE_SEQUENCER_35 0x3023
269#define WM8995_WRITE_SEQUENCER_36 0x3024
270#define WM8995_WRITE_SEQUENCER_37 0x3025
271#define WM8995_WRITE_SEQUENCER_38 0x3026
272#define WM8995_WRITE_SEQUENCER_39 0x3027
273#define WM8995_WRITE_SEQUENCER_40 0x3028
274#define WM8995_WRITE_SEQUENCER_41 0x3029
275#define WM8995_WRITE_SEQUENCER_42 0x302A
276#define WM8995_WRITE_SEQUENCER_43 0x302B
277#define WM8995_WRITE_SEQUENCER_44 0x302C
278#define WM8995_WRITE_SEQUENCER_45 0x302D
279#define WM8995_WRITE_SEQUENCER_46 0x302E
280#define WM8995_WRITE_SEQUENCER_47 0x302F
281#define WM8995_WRITE_SEQUENCER_48 0x3030
282#define WM8995_WRITE_SEQUENCER_49 0x3031
283#define WM8995_WRITE_SEQUENCER_50 0x3032
284#define WM8995_WRITE_SEQUENCER_51 0x3033
285#define WM8995_WRITE_SEQUENCER_52 0x3034
286#define WM8995_WRITE_SEQUENCER_53 0x3035
287#define WM8995_WRITE_SEQUENCER_54 0x3036
288#define WM8995_WRITE_SEQUENCER_55 0x3037
289#define WM8995_WRITE_SEQUENCER_56 0x3038
290#define WM8995_WRITE_SEQUENCER_57 0x3039
291#define WM8995_WRITE_SEQUENCER_58 0x303A
292#define WM8995_WRITE_SEQUENCER_59 0x303B
293#define WM8995_WRITE_SEQUENCER_60 0x303C
294#define WM8995_WRITE_SEQUENCER_61 0x303D
295#define WM8995_WRITE_SEQUENCER_62 0x303E
296#define WM8995_WRITE_SEQUENCER_63 0x303F
297#define WM8995_WRITE_SEQUENCER_64 0x3040
298#define WM8995_WRITE_SEQUENCER_65 0x3041
299#define WM8995_WRITE_SEQUENCER_66 0x3042
300#define WM8995_WRITE_SEQUENCER_67 0x3043
301#define WM8995_WRITE_SEQUENCER_68 0x3044
302#define WM8995_WRITE_SEQUENCER_69 0x3045
303#define WM8995_WRITE_SEQUENCER_70 0x3046
304#define WM8995_WRITE_SEQUENCER_71 0x3047
305#define WM8995_WRITE_SEQUENCER_72 0x3048
306#define WM8995_WRITE_SEQUENCER_73 0x3049
307#define WM8995_WRITE_SEQUENCER_74 0x304A
308#define WM8995_WRITE_SEQUENCER_75 0x304B
309#define WM8995_WRITE_SEQUENCER_76 0x304C
310#define WM8995_WRITE_SEQUENCER_77 0x304D
311#define WM8995_WRITE_SEQUENCER_78 0x304E
312#define WM8995_WRITE_SEQUENCER_79 0x304F
313#define WM8995_WRITE_SEQUENCER_80 0x3050
314#define WM8995_WRITE_SEQUENCER_81 0x3051
315#define WM8995_WRITE_SEQUENCER_82 0x3052
316#define WM8995_WRITE_SEQUENCER_83 0x3053
317#define WM8995_WRITE_SEQUENCER_84 0x3054
318#define WM8995_WRITE_SEQUENCER_85 0x3055
319#define WM8995_WRITE_SEQUENCER_86 0x3056
320#define WM8995_WRITE_SEQUENCER_87 0x3057
321#define WM8995_WRITE_SEQUENCER_88 0x3058
322#define WM8995_WRITE_SEQUENCER_89 0x3059
323#define WM8995_WRITE_SEQUENCER_90 0x305A
324#define WM8995_WRITE_SEQUENCER_91 0x305B
325#define WM8995_WRITE_SEQUENCER_92 0x305C
326#define WM8995_WRITE_SEQUENCER_93 0x305D
327#define WM8995_WRITE_SEQUENCER_94 0x305E
328#define WM8995_WRITE_SEQUENCER_95 0x305F
329#define WM8995_WRITE_SEQUENCER_96 0x3060
330#define WM8995_WRITE_SEQUENCER_97 0x3061
331#define WM8995_WRITE_SEQUENCER_98 0x3062
332#define WM8995_WRITE_SEQUENCER_99 0x3063
333#define WM8995_WRITE_SEQUENCER_100 0x3064
334#define WM8995_WRITE_SEQUENCER_101 0x3065
335#define WM8995_WRITE_SEQUENCER_102 0x3066
336#define WM8995_WRITE_SEQUENCER_103 0x3067
337#define WM8995_WRITE_SEQUENCER_104 0x3068
338#define WM8995_WRITE_SEQUENCER_105 0x3069
339#define WM8995_WRITE_SEQUENCER_106 0x306A
340#define WM8995_WRITE_SEQUENCER_107 0x306B
341#define WM8995_WRITE_SEQUENCER_108 0x306C
342#define WM8995_WRITE_SEQUENCER_109 0x306D
343#define WM8995_WRITE_SEQUENCER_110 0x306E
344#define WM8995_WRITE_SEQUENCER_111 0x306F
345#define WM8995_WRITE_SEQUENCER_112 0x3070
346#define WM8995_WRITE_SEQUENCER_113 0x3071
347#define WM8995_WRITE_SEQUENCER_114 0x3072
348#define WM8995_WRITE_SEQUENCER_115 0x3073
349#define WM8995_WRITE_SEQUENCER_116 0x3074
350#define WM8995_WRITE_SEQUENCER_117 0x3075
351#define WM8995_WRITE_SEQUENCER_118 0x3076
352#define WM8995_WRITE_SEQUENCER_119 0x3077
353#define WM8995_WRITE_SEQUENCER_120 0x3078
354#define WM8995_WRITE_SEQUENCER_121 0x3079
355#define WM8995_WRITE_SEQUENCER_122 0x307A
356#define WM8995_WRITE_SEQUENCER_123 0x307B
357#define WM8995_WRITE_SEQUENCER_124 0x307C
358#define WM8995_WRITE_SEQUENCER_125 0x307D
359#define WM8995_WRITE_SEQUENCER_126 0x307E
360#define WM8995_WRITE_SEQUENCER_127 0x307F
361#define WM8995_WRITE_SEQUENCER_128 0x3080
362#define WM8995_WRITE_SEQUENCER_129 0x3081
363#define WM8995_WRITE_SEQUENCER_130 0x3082
364#define WM8995_WRITE_SEQUENCER_131 0x3083
365#define WM8995_WRITE_SEQUENCER_132 0x3084
366#define WM8995_WRITE_SEQUENCER_133 0x3085
367#define WM8995_WRITE_SEQUENCER_134 0x3086
368#define WM8995_WRITE_SEQUENCER_135 0x3087
369#define WM8995_WRITE_SEQUENCER_136 0x3088
370#define WM8995_WRITE_SEQUENCER_137 0x3089
371#define WM8995_WRITE_SEQUENCER_138 0x308A
372#define WM8995_WRITE_SEQUENCER_139 0x308B
373#define WM8995_WRITE_SEQUENCER_140 0x308C
374#define WM8995_WRITE_SEQUENCER_141 0x308D
375#define WM8995_WRITE_SEQUENCER_142 0x308E
376#define WM8995_WRITE_SEQUENCER_143 0x308F
377#define WM8995_WRITE_SEQUENCER_144 0x3090
378#define WM8995_WRITE_SEQUENCER_145 0x3091
379#define WM8995_WRITE_SEQUENCER_146 0x3092
380#define WM8995_WRITE_SEQUENCER_147 0x3093
381#define WM8995_WRITE_SEQUENCER_148 0x3094
382#define WM8995_WRITE_SEQUENCER_149 0x3095
383#define WM8995_WRITE_SEQUENCER_150 0x3096
384#define WM8995_WRITE_SEQUENCER_151 0x3097
385#define WM8995_WRITE_SEQUENCER_152 0x3098
386#define WM8995_WRITE_SEQUENCER_153 0x3099
387#define WM8995_WRITE_SEQUENCER_154 0x309A
388#define WM8995_WRITE_SEQUENCER_155 0x309B
389#define WM8995_WRITE_SEQUENCER_156 0x309C
390#define WM8995_WRITE_SEQUENCER_157 0x309D
391#define WM8995_WRITE_SEQUENCER_158 0x309E
392#define WM8995_WRITE_SEQUENCER_159 0x309F
393#define WM8995_WRITE_SEQUENCER_160 0x30A0
394#define WM8995_WRITE_SEQUENCER_161 0x30A1
395#define WM8995_WRITE_SEQUENCER_162 0x30A2
396#define WM8995_WRITE_SEQUENCER_163 0x30A3
397#define WM8995_WRITE_SEQUENCER_164 0x30A4
398#define WM8995_WRITE_SEQUENCER_165 0x30A5
399#define WM8995_WRITE_SEQUENCER_166 0x30A6
400#define WM8995_WRITE_SEQUENCER_167 0x30A7
401#define WM8995_WRITE_SEQUENCER_168 0x30A8
402#define WM8995_WRITE_SEQUENCER_169 0x30A9
403#define WM8995_WRITE_SEQUENCER_170 0x30AA
404#define WM8995_WRITE_SEQUENCER_171 0x30AB
405#define WM8995_WRITE_SEQUENCER_172 0x30AC
406#define WM8995_WRITE_SEQUENCER_173 0x30AD
407#define WM8995_WRITE_SEQUENCER_174 0x30AE
408#define WM8995_WRITE_SEQUENCER_175 0x30AF
409#define WM8995_WRITE_SEQUENCER_176 0x30B0
410#define WM8995_WRITE_SEQUENCER_177 0x30B1
411#define WM8995_WRITE_SEQUENCER_178 0x30B2
412#define WM8995_WRITE_SEQUENCER_179 0x30B3
413#define WM8995_WRITE_SEQUENCER_180 0x30B4
414#define WM8995_WRITE_SEQUENCER_181 0x30B5
415#define WM8995_WRITE_SEQUENCER_182 0x30B6
416#define WM8995_WRITE_SEQUENCER_183 0x30B7
417#define WM8995_WRITE_SEQUENCER_184 0x30B8
418#define WM8995_WRITE_SEQUENCER_185 0x30B9
419#define WM8995_WRITE_SEQUENCER_186 0x30BA
420#define WM8995_WRITE_SEQUENCER_187 0x30BB
421#define WM8995_WRITE_SEQUENCER_188 0x30BC
422#define WM8995_WRITE_SEQUENCER_189 0x30BD
423#define WM8995_WRITE_SEQUENCER_190 0x30BE
424#define WM8995_WRITE_SEQUENCER_191 0x30BF
425#define WM8995_WRITE_SEQUENCER_192 0x30C0
426#define WM8995_WRITE_SEQUENCER_193 0x30C1
427#define WM8995_WRITE_SEQUENCER_194 0x30C2
428#define WM8995_WRITE_SEQUENCER_195 0x30C3
429#define WM8995_WRITE_SEQUENCER_196 0x30C4
430#define WM8995_WRITE_SEQUENCER_197 0x30C5
431#define WM8995_WRITE_SEQUENCER_198 0x30C6
432#define WM8995_WRITE_SEQUENCER_199 0x30C7
433#define WM8995_WRITE_SEQUENCER_200 0x30C8
434#define WM8995_WRITE_SEQUENCER_201 0x30C9
435#define WM8995_WRITE_SEQUENCER_202 0x30CA
436#define WM8995_WRITE_SEQUENCER_203 0x30CB
437#define WM8995_WRITE_SEQUENCER_204 0x30CC
438#define WM8995_WRITE_SEQUENCER_205 0x30CD
439#define WM8995_WRITE_SEQUENCER_206 0x30CE
440#define WM8995_WRITE_SEQUENCER_207 0x30CF
441#define WM8995_WRITE_SEQUENCER_208 0x30D0
442#define WM8995_WRITE_SEQUENCER_209 0x30D1
443#define WM8995_WRITE_SEQUENCER_210 0x30D2
444#define WM8995_WRITE_SEQUENCER_211 0x30D3
445#define WM8995_WRITE_SEQUENCER_212 0x30D4
446#define WM8995_WRITE_SEQUENCER_213 0x30D5
447#define WM8995_WRITE_SEQUENCER_214 0x30D6
448#define WM8995_WRITE_SEQUENCER_215 0x30D7
449#define WM8995_WRITE_SEQUENCER_216 0x30D8
450#define WM8995_WRITE_SEQUENCER_217 0x30D9
451#define WM8995_WRITE_SEQUENCER_218 0x30DA
452#define WM8995_WRITE_SEQUENCER_219 0x30DB
453#define WM8995_WRITE_SEQUENCER_220 0x30DC
454#define WM8995_WRITE_SEQUENCER_221 0x30DD
455#define WM8995_WRITE_SEQUENCER_222 0x30DE
456#define WM8995_WRITE_SEQUENCER_223 0x30DF
457#define WM8995_WRITE_SEQUENCER_224 0x30E0
458#define WM8995_WRITE_SEQUENCER_225 0x30E1
459#define WM8995_WRITE_SEQUENCER_226 0x30E2
460#define WM8995_WRITE_SEQUENCER_227 0x30E3
461#define WM8995_WRITE_SEQUENCER_228 0x30E4
462#define WM8995_WRITE_SEQUENCER_229 0x30E5
463#define WM8995_WRITE_SEQUENCER_230 0x30E6
464#define WM8995_WRITE_SEQUENCER_231 0x30E7
465#define WM8995_WRITE_SEQUENCER_232 0x30E8
466#define WM8995_WRITE_SEQUENCER_233 0x30E9
467#define WM8995_WRITE_SEQUENCER_234 0x30EA
468#define WM8995_WRITE_SEQUENCER_235 0x30EB
469#define WM8995_WRITE_SEQUENCER_236 0x30EC
470#define WM8995_WRITE_SEQUENCER_237 0x30ED
471#define WM8995_WRITE_SEQUENCER_238 0x30EE
472#define WM8995_WRITE_SEQUENCER_239 0x30EF
473#define WM8995_WRITE_SEQUENCER_240 0x30F0
474#define WM8995_WRITE_SEQUENCER_241 0x30F1
475#define WM8995_WRITE_SEQUENCER_242 0x30F2
476#define WM8995_WRITE_SEQUENCER_243 0x30F3
477#define WM8995_WRITE_SEQUENCER_244 0x30F4
478#define WM8995_WRITE_SEQUENCER_245 0x30F5
479#define WM8995_WRITE_SEQUENCER_246 0x30F6
480#define WM8995_WRITE_SEQUENCER_247 0x30F7
481#define WM8995_WRITE_SEQUENCER_248 0x30F8
482#define WM8995_WRITE_SEQUENCER_249 0x30F9
483#define WM8995_WRITE_SEQUENCER_250 0x30FA
484#define WM8995_WRITE_SEQUENCER_251 0x30FB
485#define WM8995_WRITE_SEQUENCER_252 0x30FC
486#define WM8995_WRITE_SEQUENCER_253 0x30FD
487#define WM8995_WRITE_SEQUENCER_254 0x30FE
488#define WM8995_WRITE_SEQUENCER_255 0x30FF
489#define WM8995_WRITE_SEQUENCER_256 0x3100
490#define WM8995_WRITE_SEQUENCER_257 0x3101
491#define WM8995_WRITE_SEQUENCER_258 0x3102
492#define WM8995_WRITE_SEQUENCER_259 0x3103
493#define WM8995_WRITE_SEQUENCER_260 0x3104
494#define WM8995_WRITE_SEQUENCER_261 0x3105
495#define WM8995_WRITE_SEQUENCER_262 0x3106
496#define WM8995_WRITE_SEQUENCER_263 0x3107
497#define WM8995_WRITE_SEQUENCER_264 0x3108
498#define WM8995_WRITE_SEQUENCER_265 0x3109
499#define WM8995_WRITE_SEQUENCER_266 0x310A
500#define WM8995_WRITE_SEQUENCER_267 0x310B
501#define WM8995_WRITE_SEQUENCER_268 0x310C
502#define WM8995_WRITE_SEQUENCER_269 0x310D
503#define WM8995_WRITE_SEQUENCER_270 0x310E
504#define WM8995_WRITE_SEQUENCER_271 0x310F
505#define WM8995_WRITE_SEQUENCER_272 0x3110
506#define WM8995_WRITE_SEQUENCER_273 0x3111
507#define WM8995_WRITE_SEQUENCER_274 0x3112
508#define WM8995_WRITE_SEQUENCER_275 0x3113
509#define WM8995_WRITE_SEQUENCER_276 0x3114
510#define WM8995_WRITE_SEQUENCER_277 0x3115
511#define WM8995_WRITE_SEQUENCER_278 0x3116
512#define WM8995_WRITE_SEQUENCER_279 0x3117
513#define WM8995_WRITE_SEQUENCER_280 0x3118
514#define WM8995_WRITE_SEQUENCER_281 0x3119
515#define WM8995_WRITE_SEQUENCER_282 0x311A
516#define WM8995_WRITE_SEQUENCER_283 0x311B
517#define WM8995_WRITE_SEQUENCER_284 0x311C
518#define WM8995_WRITE_SEQUENCER_285 0x311D
519#define WM8995_WRITE_SEQUENCER_286 0x311E
520#define WM8995_WRITE_SEQUENCER_287 0x311F
521#define WM8995_WRITE_SEQUENCER_288 0x3120
522#define WM8995_WRITE_SEQUENCER_289 0x3121
523#define WM8995_WRITE_SEQUENCER_290 0x3122
524#define WM8995_WRITE_SEQUENCER_291 0x3123
525#define WM8995_WRITE_SEQUENCER_292 0x3124
526#define WM8995_WRITE_SEQUENCER_293 0x3125
527#define WM8995_WRITE_SEQUENCER_294 0x3126
528#define WM8995_WRITE_SEQUENCER_295 0x3127
529#define WM8995_WRITE_SEQUENCER_296 0x3128
530#define WM8995_WRITE_SEQUENCER_297 0x3129
531#define WM8995_WRITE_SEQUENCER_298 0x312A
532#define WM8995_WRITE_SEQUENCER_299 0x312B
533#define WM8995_WRITE_SEQUENCER_300 0x312C
534#define WM8995_WRITE_SEQUENCER_301 0x312D
535#define WM8995_WRITE_SEQUENCER_302 0x312E
536#define WM8995_WRITE_SEQUENCER_303 0x312F
537#define WM8995_WRITE_SEQUENCER_304 0x3130
538#define WM8995_WRITE_SEQUENCER_305 0x3131
539#define WM8995_WRITE_SEQUENCER_306 0x3132
540#define WM8995_WRITE_SEQUENCER_307 0x3133
541#define WM8995_WRITE_SEQUENCER_308 0x3134
542#define WM8995_WRITE_SEQUENCER_309 0x3135
543#define WM8995_WRITE_SEQUENCER_310 0x3136
544#define WM8995_WRITE_SEQUENCER_311 0x3137
545#define WM8995_WRITE_SEQUENCER_312 0x3138
546#define WM8995_WRITE_SEQUENCER_313 0x3139
547#define WM8995_WRITE_SEQUENCER_314 0x313A
548#define WM8995_WRITE_SEQUENCER_315 0x313B
549#define WM8995_WRITE_SEQUENCER_316 0x313C
550#define WM8995_WRITE_SEQUENCER_317 0x313D
551#define WM8995_WRITE_SEQUENCER_318 0x313E
552#define WM8995_WRITE_SEQUENCER_319 0x313F
553#define WM8995_WRITE_SEQUENCER_320 0x3140
554#define WM8995_WRITE_SEQUENCER_321 0x3141
555#define WM8995_WRITE_SEQUENCER_322 0x3142
556#define WM8995_WRITE_SEQUENCER_323 0x3143
557#define WM8995_WRITE_SEQUENCER_324 0x3144
558#define WM8995_WRITE_SEQUENCER_325 0x3145
559#define WM8995_WRITE_SEQUENCER_326 0x3146
560#define WM8995_WRITE_SEQUENCER_327 0x3147
561#define WM8995_WRITE_SEQUENCER_328 0x3148
562#define WM8995_WRITE_SEQUENCER_329 0x3149
563#define WM8995_WRITE_SEQUENCER_330 0x314A
564#define WM8995_WRITE_SEQUENCER_331 0x314B
565#define WM8995_WRITE_SEQUENCER_332 0x314C
566#define WM8995_WRITE_SEQUENCER_333 0x314D
567#define WM8995_WRITE_SEQUENCER_334 0x314E
568#define WM8995_WRITE_SEQUENCER_335 0x314F
569#define WM8995_WRITE_SEQUENCER_336 0x3150
570#define WM8995_WRITE_SEQUENCER_337 0x3151
571#define WM8995_WRITE_SEQUENCER_338 0x3152
572#define WM8995_WRITE_SEQUENCER_339 0x3153
573#define WM8995_WRITE_SEQUENCER_340 0x3154
574#define WM8995_WRITE_SEQUENCER_341 0x3155
575#define WM8995_WRITE_SEQUENCER_342 0x3156
576#define WM8995_WRITE_SEQUENCER_343 0x3157
577#define WM8995_WRITE_SEQUENCER_344 0x3158
578#define WM8995_WRITE_SEQUENCER_345 0x3159
579#define WM8995_WRITE_SEQUENCER_346 0x315A
580#define WM8995_WRITE_SEQUENCER_347 0x315B
581#define WM8995_WRITE_SEQUENCER_348 0x315C
582#define WM8995_WRITE_SEQUENCER_349 0x315D
583#define WM8995_WRITE_SEQUENCER_350 0x315E
584#define WM8995_WRITE_SEQUENCER_351 0x315F
585#define WM8995_WRITE_SEQUENCER_352 0x3160
586#define WM8995_WRITE_SEQUENCER_353 0x3161
587#define WM8995_WRITE_SEQUENCER_354 0x3162
588#define WM8995_WRITE_SEQUENCER_355 0x3163
589#define WM8995_WRITE_SEQUENCER_356 0x3164
590#define WM8995_WRITE_SEQUENCER_357 0x3165
591#define WM8995_WRITE_SEQUENCER_358 0x3166
592#define WM8995_WRITE_SEQUENCER_359 0x3167
593#define WM8995_WRITE_SEQUENCER_360 0x3168
594#define WM8995_WRITE_SEQUENCER_361 0x3169
595#define WM8995_WRITE_SEQUENCER_362 0x316A
596#define WM8995_WRITE_SEQUENCER_363 0x316B
597#define WM8995_WRITE_SEQUENCER_364 0x316C
598#define WM8995_WRITE_SEQUENCER_365 0x316D
599#define WM8995_WRITE_SEQUENCER_366 0x316E
600#define WM8995_WRITE_SEQUENCER_367 0x316F
601#define WM8995_WRITE_SEQUENCER_368 0x3170
602#define WM8995_WRITE_SEQUENCER_369 0x3171
603#define WM8995_WRITE_SEQUENCER_370 0x3172
604#define WM8995_WRITE_SEQUENCER_371 0x3173
605#define WM8995_WRITE_SEQUENCER_372 0x3174
606#define WM8995_WRITE_SEQUENCER_373 0x3175
607#define WM8995_WRITE_SEQUENCER_374 0x3176
608#define WM8995_WRITE_SEQUENCER_375 0x3177
609#define WM8995_WRITE_SEQUENCER_376 0x3178
610#define WM8995_WRITE_SEQUENCER_377 0x3179
611#define WM8995_WRITE_SEQUENCER_378 0x317A
612#define WM8995_WRITE_SEQUENCER_379 0x317B
613#define WM8995_WRITE_SEQUENCER_380 0x317C
614#define WM8995_WRITE_SEQUENCER_381 0x317D
615#define WM8995_WRITE_SEQUENCER_382 0x317E
616#define WM8995_WRITE_SEQUENCER_383 0x317F
617#define WM8995_WRITE_SEQUENCER_384 0x3180
618#define WM8995_WRITE_SEQUENCER_385 0x3181
619#define WM8995_WRITE_SEQUENCER_386 0x3182
620#define WM8995_WRITE_SEQUENCER_387 0x3183
621#define WM8995_WRITE_SEQUENCER_388 0x3184
622#define WM8995_WRITE_SEQUENCER_389 0x3185
623#define WM8995_WRITE_SEQUENCER_390 0x3186
624#define WM8995_WRITE_SEQUENCER_391 0x3187
625#define WM8995_WRITE_SEQUENCER_392 0x3188
626#define WM8995_WRITE_SEQUENCER_393 0x3189
627#define WM8995_WRITE_SEQUENCER_394 0x318A
628#define WM8995_WRITE_SEQUENCER_395 0x318B
629#define WM8995_WRITE_SEQUENCER_396 0x318C
630#define WM8995_WRITE_SEQUENCER_397 0x318D
631#define WM8995_WRITE_SEQUENCER_398 0x318E
632#define WM8995_WRITE_SEQUENCER_399 0x318F
633#define WM8995_WRITE_SEQUENCER_400 0x3190
634#define WM8995_WRITE_SEQUENCER_401 0x3191
635#define WM8995_WRITE_SEQUENCER_402 0x3192
636#define WM8995_WRITE_SEQUENCER_403 0x3193
637#define WM8995_WRITE_SEQUENCER_404 0x3194
638#define WM8995_WRITE_SEQUENCER_405 0x3195
639#define WM8995_WRITE_SEQUENCER_406 0x3196
640#define WM8995_WRITE_SEQUENCER_407 0x3197
641#define WM8995_WRITE_SEQUENCER_408 0x3198
642#define WM8995_WRITE_SEQUENCER_409 0x3199
643#define WM8995_WRITE_SEQUENCER_410 0x319A
644#define WM8995_WRITE_SEQUENCER_411 0x319B
645#define WM8995_WRITE_SEQUENCER_412 0x319C
646#define WM8995_WRITE_SEQUENCER_413 0x319D
647#define WM8995_WRITE_SEQUENCER_414 0x319E
648#define WM8995_WRITE_SEQUENCER_415 0x319F
649#define WM8995_WRITE_SEQUENCER_416 0x31A0
650#define WM8995_WRITE_SEQUENCER_417 0x31A1
651#define WM8995_WRITE_SEQUENCER_418 0x31A2
652#define WM8995_WRITE_SEQUENCER_419 0x31A3
653#define WM8995_WRITE_SEQUENCER_420 0x31A4
654#define WM8995_WRITE_SEQUENCER_421 0x31A5
655#define WM8995_WRITE_SEQUENCER_422 0x31A6
656#define WM8995_WRITE_SEQUENCER_423 0x31A7
657#define WM8995_WRITE_SEQUENCER_424 0x31A8
658#define WM8995_WRITE_SEQUENCER_425 0x31A9
659#define WM8995_WRITE_SEQUENCER_426 0x31AA
660#define WM8995_WRITE_SEQUENCER_427 0x31AB
661#define WM8995_WRITE_SEQUENCER_428 0x31AC
662#define WM8995_WRITE_SEQUENCER_429 0x31AD
663#define WM8995_WRITE_SEQUENCER_430 0x31AE
664#define WM8995_WRITE_SEQUENCER_431 0x31AF
665#define WM8995_WRITE_SEQUENCER_432 0x31B0
666#define WM8995_WRITE_SEQUENCER_433 0x31B1
667#define WM8995_WRITE_SEQUENCER_434 0x31B2
668#define WM8995_WRITE_SEQUENCER_435 0x31B3
669#define WM8995_WRITE_SEQUENCER_436 0x31B4
670#define WM8995_WRITE_SEQUENCER_437 0x31B5
671#define WM8995_WRITE_SEQUENCER_438 0x31B6
672#define WM8995_WRITE_SEQUENCER_439 0x31B7
673#define WM8995_WRITE_SEQUENCER_440 0x31B8
674#define WM8995_WRITE_SEQUENCER_441 0x31B9
675#define WM8995_WRITE_SEQUENCER_442 0x31BA
676#define WM8995_WRITE_SEQUENCER_443 0x31BB
677#define WM8995_WRITE_SEQUENCER_444 0x31BC
678#define WM8995_WRITE_SEQUENCER_445 0x31BD
679#define WM8995_WRITE_SEQUENCER_446 0x31BE
680#define WM8995_WRITE_SEQUENCER_447 0x31BF
681#define WM8995_WRITE_SEQUENCER_448 0x31C0
682#define WM8995_WRITE_SEQUENCER_449 0x31C1
683#define WM8995_WRITE_SEQUENCER_450 0x31C2
684#define WM8995_WRITE_SEQUENCER_451 0x31C3
685#define WM8995_WRITE_SEQUENCER_452 0x31C4
686#define WM8995_WRITE_SEQUENCER_453 0x31C5
687#define WM8995_WRITE_SEQUENCER_454 0x31C6
688#define WM8995_WRITE_SEQUENCER_455 0x31C7
689#define WM8995_WRITE_SEQUENCER_456 0x31C8
690#define WM8995_WRITE_SEQUENCER_457 0x31C9
691#define WM8995_WRITE_SEQUENCER_458 0x31CA
692#define WM8995_WRITE_SEQUENCER_459 0x31CB
693#define WM8995_WRITE_SEQUENCER_460 0x31CC
694#define WM8995_WRITE_SEQUENCER_461 0x31CD
695#define WM8995_WRITE_SEQUENCER_462 0x31CE
696#define WM8995_WRITE_SEQUENCER_463 0x31CF
697#define WM8995_WRITE_SEQUENCER_464 0x31D0
698#define WM8995_WRITE_SEQUENCER_465 0x31D1
699#define WM8995_WRITE_SEQUENCER_466 0x31D2
700#define WM8995_WRITE_SEQUENCER_467 0x31D3
701#define WM8995_WRITE_SEQUENCER_468 0x31D4
702#define WM8995_WRITE_SEQUENCER_469 0x31D5
703#define WM8995_WRITE_SEQUENCER_470 0x31D6
704#define WM8995_WRITE_SEQUENCER_471 0x31D7
705#define WM8995_WRITE_SEQUENCER_472 0x31D8
706#define WM8995_WRITE_SEQUENCER_473 0x31D9
707#define WM8995_WRITE_SEQUENCER_474 0x31DA
708#define WM8995_WRITE_SEQUENCER_475 0x31DB
709#define WM8995_WRITE_SEQUENCER_476 0x31DC
710#define WM8995_WRITE_SEQUENCER_477 0x31DD
711#define WM8995_WRITE_SEQUENCER_478 0x31DE
712#define WM8995_WRITE_SEQUENCER_479 0x31DF
713#define WM8995_WRITE_SEQUENCER_480 0x31E0
714#define WM8995_WRITE_SEQUENCER_481 0x31E1
715#define WM8995_WRITE_SEQUENCER_482 0x31E2
716#define WM8995_WRITE_SEQUENCER_483 0x31E3
717#define WM8995_WRITE_SEQUENCER_484 0x31E4
718#define WM8995_WRITE_SEQUENCER_485 0x31E5
719#define WM8995_WRITE_SEQUENCER_486 0x31E6
720#define WM8995_WRITE_SEQUENCER_487 0x31E7
721#define WM8995_WRITE_SEQUENCER_488 0x31E8
722#define WM8995_WRITE_SEQUENCER_489 0x31E9
723#define WM8995_WRITE_SEQUENCER_490 0x31EA
724#define WM8995_WRITE_SEQUENCER_491 0x31EB
725#define WM8995_WRITE_SEQUENCER_492 0x31EC
726#define WM8995_WRITE_SEQUENCER_493 0x31ED
727#define WM8995_WRITE_SEQUENCER_494 0x31EE
728#define WM8995_WRITE_SEQUENCER_495 0x31EF
729#define WM8995_WRITE_SEQUENCER_496 0x31F0
730#define WM8995_WRITE_SEQUENCER_497 0x31F1
731#define WM8995_WRITE_SEQUENCER_498 0x31F2
732#define WM8995_WRITE_SEQUENCER_499 0x31F3
733#define WM8995_WRITE_SEQUENCER_500 0x31F4
734#define WM8995_WRITE_SEQUENCER_501 0x31F5
735#define WM8995_WRITE_SEQUENCER_502 0x31F6
736#define WM8995_WRITE_SEQUENCER_503 0x31F7
737#define WM8995_WRITE_SEQUENCER_504 0x31F8
738#define WM8995_WRITE_SEQUENCER_505 0x31F9
739#define WM8995_WRITE_SEQUENCER_506 0x31FA
740#define WM8995_WRITE_SEQUENCER_507 0x31FB
741#define WM8995_WRITE_SEQUENCER_508 0x31FC
742#define WM8995_WRITE_SEQUENCER_509 0x31FD
743#define WM8995_WRITE_SEQUENCER_510 0x31FE
744#define WM8995_WRITE_SEQUENCER_511 0x31FF
745
746#define WM8995_REGISTER_COUNT 725
747#define WM8995_MAX_REGISTER 0x31FF
748
749#define WM8995_MAX_CACHED_REGISTER WM8995_MAX_REGISTER
750
751/*
752 * Field Definitions.
753 */
754
755/*
756 * R0 (0x00) - Software Reset
757 */
758#define WM8995_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
759#define WM8995_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
760#define WM8995_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
761
762/*
763 * R1 (0x01) - Power Management (1)
764 */
765#define WM8995_MICB2_ENA 0x0200 /* MICB2_ENA */
766#define WM8995_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
767#define WM8995_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
768#define WM8995_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
769#define WM8995_MICB1_ENA 0x0100 /* MICB1_ENA */
770#define WM8995_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
771#define WM8995_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
772#define WM8995_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
773#define WM8995_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
774#define WM8995_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
775#define WM8995_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
776#define WM8995_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
777#define WM8995_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
778#define WM8995_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
779#define WM8995_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
780#define WM8995_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
781#define WM8995_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
782#define WM8995_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
783#define WM8995_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
784#define WM8995_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
785#define WM8995_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
786#define WM8995_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
787#define WM8995_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
788#define WM8995_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
789#define WM8995_BG_ENA 0x0001 /* BG_ENA */
790#define WM8995_BG_ENA_MASK 0x0001 /* BG_ENA */
791#define WM8995_BG_ENA_SHIFT 0 /* BG_ENA */
792#define WM8995_BG_ENA_WIDTH 1 /* BG_ENA */
793
794/*
795 * R2 (0x02) - Power Management (2)
796 */
797#define WM8995_OPCLK_ENA 0x0800 /* OPCLK_ENA */
798#define WM8995_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
799#define WM8995_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
800#define WM8995_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
801#define WM8995_IN1L_ENA 0x0020 /* IN1L_ENA */
802#define WM8995_IN1L_ENA_MASK 0x0020 /* IN1L_ENA */
803#define WM8995_IN1L_ENA_SHIFT 5 /* IN1L_ENA */
804#define WM8995_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
805#define WM8995_IN1R_ENA 0x0010 /* IN1R_ENA */
806#define WM8995_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
807#define WM8995_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
808#define WM8995_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
809#define WM8995_LDO2_ENA 0x0002 /* LDO2_ENA */
810#define WM8995_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
811#define WM8995_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
812#define WM8995_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
813
814/*
815 * R3 (0x03) - Power Management (3)
816 */
817#define WM8995_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
818#define WM8995_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
819#define WM8995_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
820#define WM8995_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
821#define WM8995_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
822#define WM8995_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
823#define WM8995_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
824#define WM8995_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
825#define WM8995_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
826#define WM8995_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
827#define WM8995_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
828#define WM8995_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
829#define WM8995_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
830#define WM8995_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
831#define WM8995_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
832#define WM8995_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
833#define WM8995_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
834#define WM8995_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
835#define WM8995_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
836#define WM8995_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
837#define WM8995_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
838#define WM8995_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
839#define WM8995_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
840#define WM8995_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
841#define WM8995_DMIC3L_ENA 0x0080 /* DMIC3L_ENA */
842#define WM8995_DMIC3L_ENA_MASK 0x0080 /* DMIC3L_ENA */
843#define WM8995_DMIC3L_ENA_SHIFT 7 /* DMIC3L_ENA */
844#define WM8995_DMIC3L_ENA_WIDTH 1 /* DMIC3L_ENA */
845#define WM8995_DMIC3R_ENA 0x0040 /* DMIC3R_ENA */
846#define WM8995_DMIC3R_ENA_MASK 0x0040 /* DMIC3R_ENA */
847#define WM8995_DMIC3R_ENA_SHIFT 6 /* DMIC3R_ENA */
848#define WM8995_DMIC3R_ENA_WIDTH 1 /* DMIC3R_ENA */
849#define WM8995_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
850#define WM8995_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
851#define WM8995_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
852#define WM8995_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
853#define WM8995_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
854#define WM8995_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
855#define WM8995_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
856#define WM8995_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
857#define WM8995_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
858#define WM8995_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
859#define WM8995_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
860#define WM8995_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
861#define WM8995_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
862#define WM8995_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
863#define WM8995_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
864#define WM8995_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
865#define WM8995_ADCL_ENA 0x0002 /* ADCL_ENA */
866#define WM8995_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
867#define WM8995_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
868#define WM8995_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
869#define WM8995_ADCR_ENA 0x0001 /* ADCR_ENA */
870#define WM8995_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
871#define WM8995_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
872#define WM8995_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
873
874/*
875 * R4 (0x04) - Power Management (4)
876 */
877#define WM8995_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
878#define WM8995_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
879#define WM8995_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
880#define WM8995_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
881#define WM8995_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
882#define WM8995_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
883#define WM8995_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
884#define WM8995_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
885#define WM8995_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
886#define WM8995_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
887#define WM8995_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
888#define WM8995_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
889#define WM8995_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
890#define WM8995_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
891#define WM8995_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
892#define WM8995_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
893#define WM8995_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
894#define WM8995_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
895#define WM8995_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
896#define WM8995_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
897#define WM8995_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
898#define WM8995_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
899#define WM8995_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
900#define WM8995_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
901#define WM8995_DAC2L_ENA 0x0008 /* DAC2L_ENA */
902#define WM8995_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
903#define WM8995_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
904#define WM8995_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
905#define WM8995_DAC2R_ENA 0x0004 /* DAC2R_ENA */
906#define WM8995_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
907#define WM8995_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
908#define WM8995_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
909#define WM8995_DAC1L_ENA 0x0002 /* DAC1L_ENA */
910#define WM8995_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
911#define WM8995_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
912#define WM8995_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
913#define WM8995_DAC1R_ENA 0x0001 /* DAC1R_ENA */
914#define WM8995_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
915#define WM8995_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
916#define WM8995_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
917
918/*
919 * R5 (0x05) - Power Management (5)
920 */
921#define WM8995_DMIC_SRC2_MASK 0x0300 /* DMIC_SRC2 - [9:8] */
922#define WM8995_DMIC_SRC2_SHIFT 8 /* DMIC_SRC2 - [9:8] */
923#define WM8995_DMIC_SRC2_WIDTH 2 /* DMIC_SRC2 - [9:8] */
924#define WM8995_DMIC_SRC1_MASK 0x00C0 /* DMIC_SRC1 - [7:6] */
925#define WM8995_DMIC_SRC1_SHIFT 6 /* DMIC_SRC1 - [7:6] */
926#define WM8995_DMIC_SRC1_WIDTH 2 /* DMIC_SRC1 - [7:6] */
927#define WM8995_AIF3_TRI 0x0020 /* AIF3_TRI */
928#define WM8995_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
929#define WM8995_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
930#define WM8995_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
931#define WM8995_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
932#define WM8995_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
933#define WM8995_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
934#define WM8995_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
935#define WM8995_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
936#define WM8995_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
937#define WM8995_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
938#define WM8995_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
939#define WM8995_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
940#define WM8995_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
941#define WM8995_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
942#define WM8995_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
943#define WM8995_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
944#define WM8995_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
945#define WM8995_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
946
947/*
948 * R16 (0x10) - Left Line Input 1 Volume
949 */
950#define WM8995_IN1_VU 0x0080 /* IN1_VU */
951#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
952#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
953#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
954#define WM8995_IN1L_ZC 0x0020 /* IN1L_ZC */
955#define WM8995_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
956#define WM8995_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
957#define WM8995_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
958#define WM8995_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
959#define WM8995_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
960#define WM8995_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
961
962/*
963 * R17 (0x11) - Right Line Input 1 Volume
964 */
965#define WM8995_IN1_VU 0x0080 /* IN1_VU */
966#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
967#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
968#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
969#define WM8995_IN1R_ZC 0x0020 /* IN1R_ZC */
970#define WM8995_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
971#define WM8995_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
972#define WM8995_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
973#define WM8995_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
974#define WM8995_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
975#define WM8995_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
976
977/*
978 * R18 (0x12) - Left Line Input Control
979 */
980#define WM8995_IN1L_BOOST_MASK 0x0030 /* IN1L_BOOST - [5:4] */
981#define WM8995_IN1L_BOOST_SHIFT 4 /* IN1L_BOOST - [5:4] */
982#define WM8995_IN1L_BOOST_WIDTH 2 /* IN1L_BOOST - [5:4] */
983#define WM8995_IN1L_MODE_MASK 0x000C /* IN1L_MODE - [3:2] */
984#define WM8995_IN1L_MODE_SHIFT 2 /* IN1L_MODE - [3:2] */
985#define WM8995_IN1L_MODE_WIDTH 2 /* IN1L_MODE - [3:2] */
986#define WM8995_IN1R_MODE_MASK 0x0003 /* IN1R_MODE - [1:0] */
987#define WM8995_IN1R_MODE_SHIFT 0 /* IN1R_MODE - [1:0] */
988#define WM8995_IN1R_MODE_WIDTH 2 /* IN1R_MODE - [1:0] */
989
990/*
991 * R24 (0x18) - DAC1 Left Volume
992 */
993#define WM8995_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
994#define WM8995_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
995#define WM8995_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
996#define WM8995_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
997#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
998#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
999#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
1000#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
1001#define WM8995_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
1002#define WM8995_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
1003#define WM8995_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
1004
1005/*
1006 * R25 (0x19) - DAC1 Right Volume
1007 */
1008#define WM8995_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
1009#define WM8995_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
1010#define WM8995_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
1011#define WM8995_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
1012#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
1013#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1014#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
1015#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
1016#define WM8995_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
1017#define WM8995_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
1018#define WM8995_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
1019
1020/*
1021 * R26 (0x1A) - DAC2 Left Volume
1022 */
1023#define WM8995_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
1024#define WM8995_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
1025#define WM8995_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
1026#define WM8995_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
1027#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
1028#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1029#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
1030#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
1031#define WM8995_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
1032#define WM8995_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
1033#define WM8995_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
1034
1035/*
1036 * R27 (0x1B) - DAC2 Right Volume
1037 */
1038#define WM8995_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
1039#define WM8995_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
1040#define WM8995_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
1041#define WM8995_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
1042#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
1043#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1044#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
1045#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
1046#define WM8995_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
1047#define WM8995_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
1048#define WM8995_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
1049
1050/*
1051 * R28 (0x1C) - Output Volume ZC (1)
1052 */
1053#define WM8995_HPOUT2L_ZC 0x0008 /* HPOUT2L_ZC */
1054#define WM8995_HPOUT2L_ZC_MASK 0x0008 /* HPOUT2L_ZC */
1055#define WM8995_HPOUT2L_ZC_SHIFT 3 /* HPOUT2L_ZC */
1056#define WM8995_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
1057#define WM8995_HPOUT2R_ZC 0x0004 /* HPOUT2R_ZC */
1058#define WM8995_HPOUT2R_ZC_MASK 0x0004 /* HPOUT2R_ZC */
1059#define WM8995_HPOUT2R_ZC_SHIFT 2 /* HPOUT2R_ZC */
1060#define WM8995_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
1061#define WM8995_HPOUT1L_ZC 0x0002 /* HPOUT1L_ZC */
1062#define WM8995_HPOUT1L_ZC_MASK 0x0002 /* HPOUT1L_ZC */
1063#define WM8995_HPOUT1L_ZC_SHIFT 1 /* HPOUT1L_ZC */
1064#define WM8995_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1065#define WM8995_HPOUT1R_ZC 0x0001 /* HPOUT1R_ZC */
1066#define WM8995_HPOUT1R_ZC_MASK 0x0001 /* HPOUT1R_ZC */
1067#define WM8995_HPOUT1R_ZC_SHIFT 0 /* HPOUT1R_ZC */
1068#define WM8995_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1069
1070/*
1071 * R32 (0x20) - MICBIAS (1)
1072 */
1073#define WM8995_MICB1_MODE 0x0008 /* MICB1_MODE */
1074#define WM8995_MICB1_MODE_MASK 0x0008 /* MICB1_MODE */
1075#define WM8995_MICB1_MODE_SHIFT 3 /* MICB1_MODE */
1076#define WM8995_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1077#define WM8995_MICB1_LVL_MASK 0x0006 /* MICB1_LVL - [2:1] */
1078#define WM8995_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [2:1] */
1079#define WM8995_MICB1_LVL_WIDTH 2 /* MICB1_LVL - [2:1] */
1080#define WM8995_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1081#define WM8995_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1082#define WM8995_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1083#define WM8995_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1084
1085/*
1086 * R33 (0x21) - MICBIAS (2)
1087 */
1088#define WM8995_MICB2_MODE 0x0008 /* MICB2_MODE */
1089#define WM8995_MICB2_MODE_MASK 0x0008 /* MICB2_MODE */
1090#define WM8995_MICB2_MODE_SHIFT 3 /* MICB2_MODE */
1091#define WM8995_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1092#define WM8995_MICB2_LVL_MASK 0x0006 /* MICB2_LVL - [2:1] */
1093#define WM8995_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [2:1] */
1094#define WM8995_MICB2_LVL_WIDTH 2 /* MICB2_LVL - [2:1] */
1095#define WM8995_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1096#define WM8995_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1097#define WM8995_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1098#define WM8995_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1099
1100/*
1101 * R40 (0x28) - LDO 1
1102 */
1103#define WM8995_LDO1_MODE 0x0020 /* LDO1_MODE */
1104#define WM8995_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
1105#define WM8995_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
1106#define WM8995_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
1107#define WM8995_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
1108#define WM8995_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
1109#define WM8995_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
1110#define WM8995_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1111#define WM8995_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1112#define WM8995_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1113#define WM8995_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1114
1115/*
1116 * R41 (0x29) - LDO 2
1117 */
1118#define WM8995_LDO2_MODE 0x0020 /* LDO2_MODE */
1119#define WM8995_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
1120#define WM8995_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
1121#define WM8995_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
1122#define WM8995_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
1123#define WM8995_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
1124#define WM8995_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
1125#define WM8995_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1126#define WM8995_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1127#define WM8995_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1128#define WM8995_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1129
1130/*
1131 * R48 (0x30) - Accessory Detect Mode1
1132 */
1133#define WM8995_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
1134#define WM8995_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
1135#define WM8995_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
1136
1137/*
1138 * R49 (0x31) - Accessory Detect Mode2
1139 */
1140#define WM8995_VID_ENA 0x0001 /* VID_ENA */
1141#define WM8995_VID_ENA_MASK 0x0001 /* VID_ENA */
1142#define WM8995_VID_ENA_SHIFT 0 /* VID_ENA */
1143#define WM8995_VID_ENA_WIDTH 1 /* VID_ENA */
1144
1145/*
1146 * R52 (0x34) - Headphone Detect1
1147 */
1148#define WM8995_HP_RAMPRATE 0x0002 /* HP_RAMPRATE */
1149#define WM8995_HP_RAMPRATE_MASK 0x0002 /* HP_RAMPRATE */
1150#define WM8995_HP_RAMPRATE_SHIFT 1 /* HP_RAMPRATE */
1151#define WM8995_HP_RAMPRATE_WIDTH 1 /* HP_RAMPRATE */
1152#define WM8995_HP_POLL 0x0001 /* HP_POLL */
1153#define WM8995_HP_POLL_MASK 0x0001 /* HP_POLL */
1154#define WM8995_HP_POLL_SHIFT 0 /* HP_POLL */
1155#define WM8995_HP_POLL_WIDTH 1 /* HP_POLL */
1156
1157/*
1158 * R53 (0x35) - Headphone Detect2
1159 */
1160#define WM8995_HP_DONE 0x0080 /* HP_DONE */
1161#define WM8995_HP_DONE_MASK 0x0080 /* HP_DONE */
1162#define WM8995_HP_DONE_SHIFT 7 /* HP_DONE */
1163#define WM8995_HP_DONE_WIDTH 1 /* HP_DONE */
1164#define WM8995_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1165#define WM8995_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1166#define WM8995_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1167
1168/*
1169 * R56 (0x38) - Mic Detect (1)
1170 */
1171#define WM8995_MICD_RATE_MASK 0x7800 /* MICD_RATE - [14:11] */
1172#define WM8995_MICD_RATE_SHIFT 11 /* MICD_RATE - [14:11] */
1173#define WM8995_MICD_RATE_WIDTH 4 /* MICD_RATE - [14:11] */
1174#define WM8995_MICD_LVL_SEL_MASK 0x01F8 /* MICD_LVL_SEL - [8:3] */
1175#define WM8995_MICD_LVL_SEL_SHIFT 3 /* MICD_LVL_SEL - [8:3] */
1176#define WM8995_MICD_LVL_SEL_WIDTH 6 /* MICD_LVL_SEL - [8:3] */
1177#define WM8995_MICD_DBTIME 0x0002 /* MICD_DBTIME */
1178#define WM8995_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
1179#define WM8995_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
1180#define WM8995_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
1181#define WM8995_MICD_ENA 0x0001 /* MICD_ENA */
1182#define WM8995_MICD_ENA_MASK 0x0001 /* MICD_ENA */
1183#define WM8995_MICD_ENA_SHIFT 0 /* MICD_ENA */
1184#define WM8995_MICD_ENA_WIDTH 1 /* MICD_ENA */
1185
1186/*
1187 * R57 (0x39) - Mic Detect (2)
1188 */
1189#define WM8995_MICD_LVL_MASK 0x01FC /* MICD_LVL - [8:2] */
1190#define WM8995_MICD_LVL_SHIFT 2 /* MICD_LVL - [8:2] */
1191#define WM8995_MICD_LVL_WIDTH 7 /* MICD_LVL - [8:2] */
1192#define WM8995_MICD_VALID 0x0002 /* MICD_VALID */
1193#define WM8995_MICD_VALID_MASK 0x0002 /* MICD_VALID */
1194#define WM8995_MICD_VALID_SHIFT 1 /* MICD_VALID */
1195#define WM8995_MICD_VALID_WIDTH 1 /* MICD_VALID */
1196#define WM8995_MICD_STS 0x0001 /* MICD_STS */
1197#define WM8995_MICD_STS_MASK 0x0001 /* MICD_STS */
1198#define WM8995_MICD_STS_SHIFT 0 /* MICD_STS */
1199#define WM8995_MICD_STS_WIDTH 1 /* MICD_STS */
1200
1201/*
1202 * R64 (0x40) - Charge Pump (1)
1203 */
1204#define WM8995_CP_ENA 0x8000 /* CP_ENA */
1205#define WM8995_CP_ENA_MASK 0x8000 /* CP_ENA */
1206#define WM8995_CP_ENA_SHIFT 15 /* CP_ENA */
1207#define WM8995_CP_ENA_WIDTH 1 /* CP_ENA */
1208
1209/*
1210 * R69 (0x45) - Class W (1)
1211 */
1212#define WM8995_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
1213#define WM8995_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
1214#define WM8995_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
1215#define WM8995_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1216#define WM8995_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1217#define WM8995_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1218#define WM8995_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1219
1220/*
1221 * R80 (0x50) - DC Servo (1)
1222 */
1223#define WM8995_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
1224#define WM8995_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
1225#define WM8995_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
1226#define WM8995_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
1227#define WM8995_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
1228#define WM8995_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
1229#define WM8995_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
1230#define WM8995_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
1231#define WM8995_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1232#define WM8995_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1233#define WM8995_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1234#define WM8995_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1235#define WM8995_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1236#define WM8995_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1237#define WM8995_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1238#define WM8995_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1239
1240/*
1241 * R81 (0x51) - DC Servo (2)
1242 */
1243#define WM8995_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
1244#define WM8995_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
1245#define WM8995_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
1246#define WM8995_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
1247#define WM8995_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
1248#define WM8995_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
1249#define WM8995_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
1250#define WM8995_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
1251#define WM8995_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1252#define WM8995_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1253#define WM8995_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1254#define WM8995_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1255#define WM8995_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1256#define WM8995_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1257#define WM8995_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1258#define WM8995_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1259#define WM8995_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
1260#define WM8995_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
1261#define WM8995_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
1262#define WM8995_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
1263#define WM8995_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
1264#define WM8995_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
1265#define WM8995_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
1266#define WM8995_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
1267#define WM8995_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1268#define WM8995_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1269#define WM8995_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1270#define WM8995_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1271#define WM8995_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1272#define WM8995_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1273#define WM8995_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1274#define WM8995_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1275#define WM8995_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
1276#define WM8995_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
1277#define WM8995_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
1278#define WM8995_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
1279#define WM8995_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
1280#define WM8995_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
1281#define WM8995_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
1282#define WM8995_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
1283#define WM8995_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1284#define WM8995_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1285#define WM8995_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1286#define WM8995_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1287#define WM8995_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1288#define WM8995_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1289#define WM8995_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1290#define WM8995_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1291#define WM8995_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
1292#define WM8995_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
1293#define WM8995_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
1294#define WM8995_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
1295#define WM8995_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
1296#define WM8995_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
1297#define WM8995_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
1298#define WM8995_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
1299#define WM8995_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
1300#define WM8995_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
1301#define WM8995_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
1302#define WM8995_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1303#define WM8995_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
1304#define WM8995_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
1305#define WM8995_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
1306#define WM8995_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1307
1308/*
1309 * R82 (0x52) - DC Servo (3)
1310 */
1311#define WM8995_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
1312#define WM8995_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
1313#define WM8995_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
1314#define WM8995_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1315#define WM8995_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1316#define WM8995_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1317
1318/*
1319 * R84 (0x54) - DC Servo (5)
1320 */
1321#define WM8995_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
1322#define WM8995_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
1323#define WM8995_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
1324#define WM8995_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
1325#define WM8995_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
1326#define WM8995_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
1327
1328/*
1329 * R85 (0x55) - DC Servo (6)
1330 */
1331#define WM8995_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
1332#define WM8995_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1333#define WM8995_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1334#define WM8995_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
1335#define WM8995_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
1336#define WM8995_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
1337
1338/*
1339 * R86 (0x56) - DC Servo (7)
1340 */
1341#define WM8995_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1342#define WM8995_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1343#define WM8995_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1344#define WM8995_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1345#define WM8995_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1346#define WM8995_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1347
1348/*
1349 * R87 (0x57) - DC Servo Readback 0
1350 */
1351#define WM8995_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
1352#define WM8995_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
1353#define WM8995_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
1354#define WM8995_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
1355#define WM8995_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1356#define WM8995_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1357#define WM8995_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
1358#define WM8995_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
1359#define WM8995_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
1360
1361/*
1362 * R96 (0x60) - Analogue HP (1)
1363 */
1364#define WM8995_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1365#define WM8995_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1366#define WM8995_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1367#define WM8995_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1368#define WM8995_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1369#define WM8995_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1370#define WM8995_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1371#define WM8995_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1372#define WM8995_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1373#define WM8995_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1374#define WM8995_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1375#define WM8995_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1376#define WM8995_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1377#define WM8995_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1378#define WM8995_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1379#define WM8995_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1380#define WM8995_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1381#define WM8995_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1382#define WM8995_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1383#define WM8995_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1384#define WM8995_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1385#define WM8995_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1386#define WM8995_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1387#define WM8995_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1388
1389/*
1390 * R97 (0x61) - Analogue HP (2)
1391 */
1392#define WM8995_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
1393#define WM8995_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
1394#define WM8995_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
1395#define WM8995_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
1396#define WM8995_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
1397#define WM8995_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
1398#define WM8995_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
1399#define WM8995_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
1400#define WM8995_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
1401#define WM8995_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
1402#define WM8995_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
1403#define WM8995_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
1404#define WM8995_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
1405#define WM8995_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
1406#define WM8995_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
1407#define WM8995_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
1408#define WM8995_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
1409#define WM8995_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
1410#define WM8995_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
1411#define WM8995_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
1412#define WM8995_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
1413#define WM8995_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
1414#define WM8995_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
1415#define WM8995_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
1416
1417/*
1418 * R256 (0x100) - Chip Revision
1419 */
1420#define WM8995_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1421#define WM8995_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1422#define WM8995_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1423
1424/*
1425 * R257 (0x101) - Control Interface (1)
1426 */
1427#define WM8995_REG_SYNC 0x8000 /* REG_SYNC */
1428#define WM8995_REG_SYNC_MASK 0x8000 /* REG_SYNC */
1429#define WM8995_REG_SYNC_SHIFT 15 /* REG_SYNC */
1430#define WM8995_REG_SYNC_WIDTH 1 /* REG_SYNC */
1431#define WM8995_SPI_CONTRD 0x0040 /* SPI_CONTRD */
1432#define WM8995_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
1433#define WM8995_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
1434#define WM8995_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
1435#define WM8995_SPI_4WIRE 0x0020 /* SPI_4WIRE */
1436#define WM8995_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
1437#define WM8995_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
1438#define WM8995_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
1439#define WM8995_SPI_CFG 0x0010 /* SPI_CFG */
1440#define WM8995_SPI_CFG_MASK 0x0010 /* SPI_CFG */
1441#define WM8995_SPI_CFG_SHIFT 4 /* SPI_CFG */
1442#define WM8995_SPI_CFG_WIDTH 1 /* SPI_CFG */
1443#define WM8995_AUTO_INC 0x0004 /* AUTO_INC */
1444#define WM8995_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1445#define WM8995_AUTO_INC_SHIFT 2 /* AUTO_INC */
1446#define WM8995_AUTO_INC_WIDTH 1 /* AUTO_INC */
1447
1448/*
1449 * R258 (0x102) - Control Interface (2)
1450 */
1451#define WM8995_CTRL_IF_SRC 0x0001 /* CTRL_IF_SRC */
1452#define WM8995_CTRL_IF_SRC_MASK 0x0001 /* CTRL_IF_SRC */
1453#define WM8995_CTRL_IF_SRC_SHIFT 0 /* CTRL_IF_SRC */
1454#define WM8995_CTRL_IF_SRC_WIDTH 1 /* CTRL_IF_SRC */
1455
1456/*
1457 * R272 (0x110) - Write Sequencer Ctrl (1)
1458 */
1459#define WM8995_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1460#define WM8995_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1461#define WM8995_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1462#define WM8995_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1463#define WM8995_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1464#define WM8995_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1465#define WM8995_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1466#define WM8995_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1467#define WM8995_WSEQ_START 0x0100 /* WSEQ_START */
1468#define WM8995_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1469#define WM8995_WSEQ_START_SHIFT 8 /* WSEQ_START */
1470#define WM8995_WSEQ_START_WIDTH 1 /* WSEQ_START */
1471#define WM8995_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1472#define WM8995_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1473#define WM8995_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1474
1475/*
1476 * R273 (0x111) - Write Sequencer Ctrl (2)
1477 */
1478#define WM8995_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
1479#define WM8995_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
1480#define WM8995_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
1481#define WM8995_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1482#define WM8995_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
1483#define WM8995_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
1484#define WM8995_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
1485
1486/*
1487 * R512 (0x200) - AIF1 Clocking (1)
1488 */
1489#define WM8995_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
1490#define WM8995_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
1491#define WM8995_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
1492#define WM8995_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
1493#define WM8995_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
1494#define WM8995_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
1495#define WM8995_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
1496#define WM8995_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
1497#define WM8995_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
1498#define WM8995_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
1499#define WM8995_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
1500#define WM8995_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
1501#define WM8995_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
1502#define WM8995_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
1503#define WM8995_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
1504
1505/*
1506 * R513 (0x201) - AIF1 Clocking (2)
1507 */
1508#define WM8995_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
1509#define WM8995_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
1510#define WM8995_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
1511#define WM8995_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
1512#define WM8995_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
1513#define WM8995_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
1514
1515/*
1516 * R516 (0x204) - AIF2 Clocking (1)
1517 */
1518#define WM8995_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
1519#define WM8995_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
1520#define WM8995_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
1521#define WM8995_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
1522#define WM8995_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
1523#define WM8995_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
1524#define WM8995_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
1525#define WM8995_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
1526#define WM8995_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
1527#define WM8995_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
1528#define WM8995_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
1529#define WM8995_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
1530#define WM8995_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
1531#define WM8995_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
1532#define WM8995_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
1533
1534/*
1535 * R517 (0x205) - AIF2 Clocking (2)
1536 */
1537#define WM8995_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
1538#define WM8995_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
1539#define WM8995_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
1540#define WM8995_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
1541#define WM8995_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
1542#define WM8995_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
1543
1544/*
1545 * R520 (0x208) - Clocking (1)
1546 */
1547#define WM8995_LFCLK_ENA 0x0020 /* LFCLK_ENA */
1548#define WM8995_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
1549#define WM8995_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
1550#define WM8995_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
1551#define WM8995_TOCLK_ENA 0x0010 /* TOCLK_ENA */
1552#define WM8995_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
1553#define WM8995_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
1554#define WM8995_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1555#define WM8995_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */
1556#define WM8995_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */
1557#define WM8995_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */
1558#define WM8995_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */
1559#define WM8995_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */
1560#define WM8995_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */
1561#define WM8995_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */
1562#define WM8995_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */
1563#define WM8995_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
1564#define WM8995_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
1565#define WM8995_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
1566#define WM8995_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
1567#define WM8995_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
1568#define WM8995_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
1569#define WM8995_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
1570#define WM8995_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
1571
1572/*
1573 * R521 (0x209) - Clocking (2)
1574 */
1575#define WM8995_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
1576#define WM8995_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
1577#define WM8995_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
1578#define WM8995_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
1579#define WM8995_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
1580#define WM8995_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
1581#define WM8995_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
1582#define WM8995_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
1583#define WM8995_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
1584
1585/*
1586 * R528 (0x210) - AIF1 Rate
1587 */
1588#define WM8995_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
1589#define WM8995_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
1590#define WM8995_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
1591#define WM8995_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
1592#define WM8995_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
1593#define WM8995_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
1594
1595/*
1596 * R529 (0x211) - AIF2 Rate
1597 */
1598#define WM8995_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
1599#define WM8995_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
1600#define WM8995_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
1601#define WM8995_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
1602#define WM8995_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
1603#define WM8995_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
1604
1605/*
1606 * R530 (0x212) - Rate Status
1607 */
1608#define WM8995_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
1609#define WM8995_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
1610#define WM8995_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
1611
1612/*
1613 * R544 (0x220) - FLL1 Control (1)
1614 */
1615#define WM8995_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
1616#define WM8995_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
1617#define WM8995_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
1618#define WM8995_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
1619#define WM8995_FLL1_ENA 0x0001 /* FLL1_ENA */
1620#define WM8995_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
1621#define WM8995_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
1622#define WM8995_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
1623
1624/*
1625 * R545 (0x221) - FLL1 Control (2)
1626 */
1627#define WM8995_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
1628#define WM8995_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
1629#define WM8995_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
1630#define WM8995_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
1631#define WM8995_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
1632#define WM8995_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
1633#define WM8995_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
1634#define WM8995_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
1635#define WM8995_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
1636
1637/*
1638 * R546 (0x222) - FLL1 Control (3)
1639 */
1640#define WM8995_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
1641#define WM8995_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
1642#define WM8995_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
1643
1644/*
1645 * R547 (0x223) - FLL1 Control (4)
1646 */
1647#define WM8995_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
1648#define WM8995_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
1649#define WM8995_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
1650#define WM8995_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */
1651#define WM8995_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */
1652#define WM8995_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */
1653
1654/*
1655 * R548 (0x224) - FLL1 Control (5)
1656 */
1657#define WM8995_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
1658#define WM8995_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
1659#define WM8995_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
1660#define WM8995_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
1661#define WM8995_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
1662#define WM8995_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
1663#define WM8995_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
1664#define WM8995_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */
1665#define WM8995_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */
1666#define WM8995_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */
1667#define WM8995_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */
1668#define WM8995_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */
1669#define WM8995_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
1670
1671/*
1672 * R576 (0x240) - FLL2 Control (1)
1673 */
1674#define WM8995_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
1675#define WM8995_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
1676#define WM8995_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
1677#define WM8995_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
1678#define WM8995_FLL2_ENA 0x0001 /* FLL2_ENA */
1679#define WM8995_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
1680#define WM8995_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
1681#define WM8995_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
1682
1683/*
1684 * R577 (0x241) - FLL2 Control (2)
1685 */
1686#define WM8995_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
1687#define WM8995_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
1688#define WM8995_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
1689#define WM8995_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
1690#define WM8995_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
1691#define WM8995_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
1692#define WM8995_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
1693#define WM8995_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
1694#define WM8995_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
1695
1696/*
1697 * R578 (0x242) - FLL2 Control (3)
1698 */
1699#define WM8995_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
1700#define WM8995_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
1701#define WM8995_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
1702
1703/*
1704 * R579 (0x243) - FLL2 Control (4)
1705 */
1706#define WM8995_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
1707#define WM8995_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
1708#define WM8995_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
1709#define WM8995_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */
1710#define WM8995_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */
1711#define WM8995_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */
1712
1713/*
1714 * R580 (0x244) - FLL2 Control (5)
1715 */
1716#define WM8995_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
1717#define WM8995_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
1718#define WM8995_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
1719#define WM8995_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
1720#define WM8995_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
1721#define WM8995_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
1722#define WM8995_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
1723#define WM8995_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */
1724#define WM8995_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */
1725#define WM8995_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */
1726#define WM8995_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */
1727#define WM8995_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */
1728#define WM8995_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
1729
1730/*
1731 * R768 (0x300) - AIF1 Control (1)
1732 */
1733#define WM8995_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
1734#define WM8995_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
1735#define WM8995_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
1736#define WM8995_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
1737#define WM8995_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
1738#define WM8995_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
1739#define WM8995_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
1740#define WM8995_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
1741#define WM8995_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
1742#define WM8995_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
1743#define WM8995_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
1744#define WM8995_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
1745#define WM8995_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
1746#define WM8995_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
1747#define WM8995_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
1748#define WM8995_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1749#define WM8995_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
1750#define WM8995_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
1751#define WM8995_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
1752#define WM8995_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
1753#define WM8995_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
1754#define WM8995_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
1755#define WM8995_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
1756#define WM8995_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
1757#define WM8995_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
1758#define WM8995_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
1759
1760/*
1761 * R769 (0x301) - AIF1 Control (2)
1762 */
1763#define WM8995_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
1764#define WM8995_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
1765#define WM8995_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
1766#define WM8995_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
1767#define WM8995_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
1768#define WM8995_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
1769#define WM8995_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
1770#define WM8995_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
1771#define WM8995_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
1772#define WM8995_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
1773#define WM8995_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
1774#define WM8995_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
1775#define WM8995_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
1776#define WM8995_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
1777#define WM8995_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
1778#define WM8995_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
1779#define WM8995_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
1780#define WM8995_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
1781#define WM8995_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
1782#define WM8995_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
1783#define WM8995_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
1784#define WM8995_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
1785#define WM8995_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
1786#define WM8995_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
1787#define WM8995_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
1788#define WM8995_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
1789#define WM8995_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
1790#define WM8995_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
1791#define WM8995_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
1792#define WM8995_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
1793#define WM8995_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
1794
1795/*
1796 * R770 (0x302) - AIF1 Master/Slave
1797 */
1798#define WM8995_AIF1_TRI 0x8000 /* AIF1_TRI */
1799#define WM8995_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
1800#define WM8995_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
1801#define WM8995_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1802#define WM8995_AIF1_MSTR 0x4000 /* AIF1_MSTR */
1803#define WM8995_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
1804#define WM8995_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
1805#define WM8995_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
1806#define WM8995_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
1807#define WM8995_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
1808#define WM8995_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
1809#define WM8995_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
1810#define WM8995_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
1811#define WM8995_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
1812#define WM8995_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
1813#define WM8995_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
1814
1815/*
1816 * R771 (0x303) - AIF1 BCLK
1817 */
1818#define WM8995_AIF1_BCLK_DIV_MASK 0x00F0 /* AIF1_BCLK_DIV - [7:4] */
1819#define WM8995_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [7:4] */
1820#define WM8995_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [7:4] */
1821
1822/*
1823 * R772 (0x304) - AIF1ADC LRCLK
1824 */
1825#define WM8995_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
1826#define WM8995_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
1827#define WM8995_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
1828#define WM8995_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
1829#define WM8995_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
1830#define WM8995_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
1831#define WM8995_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
1832
1833/*
1834 * R773 (0x305) - AIF1DAC LRCLK
1835 */
1836#define WM8995_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
1837#define WM8995_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
1838#define WM8995_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
1839#define WM8995_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
1840#define WM8995_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
1841#define WM8995_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
1842#define WM8995_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
1843
1844/*
1845 * R774 (0x306) - AIF1DAC Data
1846 */
1847#define WM8995_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
1848#define WM8995_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
1849#define WM8995_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
1850#define WM8995_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
1851#define WM8995_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
1852#define WM8995_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
1853#define WM8995_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
1854#define WM8995_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
1855
1856/*
1857 * R775 (0x307) - AIF1ADC Data
1858 */
1859#define WM8995_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
1860#define WM8995_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
1861#define WM8995_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
1862#define WM8995_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
1863#define WM8995_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
1864#define WM8995_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
1865#define WM8995_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
1866#define WM8995_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
1867
1868/*
1869 * R784 (0x310) - AIF2 Control (1)
1870 */
1871#define WM8995_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
1872#define WM8995_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
1873#define WM8995_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
1874#define WM8995_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
1875#define WM8995_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
1876#define WM8995_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
1877#define WM8995_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
1878#define WM8995_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
1879#define WM8995_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
1880#define WM8995_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
1881#define WM8995_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
1882#define WM8995_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
1883#define WM8995_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
1884#define WM8995_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
1885#define WM8995_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
1886#define WM8995_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
1887#define WM8995_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
1888#define WM8995_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
1889#define WM8995_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
1890#define WM8995_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
1891#define WM8995_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
1892#define WM8995_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
1893#define WM8995_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
1894#define WM8995_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
1895#define WM8995_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
1896#define WM8995_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
1897#define WM8995_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
1898#define WM8995_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
1899#define WM8995_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
1900#define WM8995_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
1901
1902/*
1903 * R785 (0x311) - AIF2 Control (2)
1904 */
1905#define WM8995_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
1906#define WM8995_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
1907#define WM8995_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
1908#define WM8995_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
1909#define WM8995_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
1910#define WM8995_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
1911#define WM8995_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
1912#define WM8995_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
1913#define WM8995_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
1914#define WM8995_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
1915#define WM8995_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
1916#define WM8995_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
1917#define WM8995_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
1918#define WM8995_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
1919#define WM8995_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
1920#define WM8995_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
1921#define WM8995_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
1922#define WM8995_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
1923#define WM8995_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
1924#define WM8995_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
1925#define WM8995_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
1926#define WM8995_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
1927#define WM8995_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
1928#define WM8995_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
1929#define WM8995_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
1930#define WM8995_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
1931#define WM8995_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
1932#define WM8995_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
1933#define WM8995_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
1934#define WM8995_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
1935#define WM8995_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
1936#define WM8995_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
1937#define WM8995_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
1938#define WM8995_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
1939#define WM8995_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
1940#define WM8995_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
1941#define WM8995_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
1942#define WM8995_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
1943#define WM8995_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
1944
1945/*
1946 * R786 (0x312) - AIF2 Master/Slave
1947 */
1948#define WM8995_AIF2_TRI 0x8000 /* AIF2_TRI */
1949#define WM8995_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
1950#define WM8995_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
1951#define WM8995_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
1952#define WM8995_AIF2_MSTR 0x4000 /* AIF2_MSTR */
1953#define WM8995_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
1954#define WM8995_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
1955#define WM8995_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
1956#define WM8995_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
1957#define WM8995_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
1958#define WM8995_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
1959#define WM8995_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
1960#define WM8995_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
1961#define WM8995_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
1962#define WM8995_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
1963#define WM8995_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
1964
1965/*
1966 * R787 (0x313) - AIF2 BCLK
1967 */
1968#define WM8995_AIF2_BCLK_DIV_MASK 0x00F0 /* AIF2_BCLK_DIV - [7:4] */
1969#define WM8995_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [7:4] */
1970#define WM8995_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [7:4] */
1971
1972/*
1973 * R788 (0x314) - AIF2ADC LRCLK
1974 */
1975#define WM8995_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
1976#define WM8995_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
1977#define WM8995_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
1978#define WM8995_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
1979#define WM8995_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
1980#define WM8995_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
1981#define WM8995_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
1982
1983/*
1984 * R789 (0x315) - AIF2DAC LRCLK
1985 */
1986#define WM8995_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
1987#define WM8995_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
1988#define WM8995_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
1989#define WM8995_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
1990#define WM8995_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
1991#define WM8995_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
1992#define WM8995_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
1993
1994/*
1995 * R790 (0x316) - AIF2DAC Data
1996 */
1997#define WM8995_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
1998#define WM8995_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
1999#define WM8995_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
2000#define WM8995_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
2001#define WM8995_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
2002#define WM8995_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
2003#define WM8995_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
2004#define WM8995_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
2005
2006/*
2007 * R791 (0x317) - AIF2ADC Data
2008 */
2009#define WM8995_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
2010#define WM8995_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
2011#define WM8995_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
2012#define WM8995_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
2013#define WM8995_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
2014#define WM8995_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
2015#define WM8995_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
2016#define WM8995_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
2017
2018/*
2019 * R1024 (0x400) - AIF1 ADC1 Left Volume
2020 */
2021#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
2022#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
2023#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
2024#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
2025#define WM8995_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
2026#define WM8995_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
2027#define WM8995_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
2028
2029/*
2030 * R1025 (0x401) - AIF1 ADC1 Right Volume
2031 */
2032#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
2033#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
2034#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
2035#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
2036#define WM8995_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
2037#define WM8995_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
2038#define WM8995_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
2039
2040/*
2041 * R1026 (0x402) - AIF1 DAC1 Left Volume
2042 */
2043#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
2044#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
2045#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
2046#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
2047#define WM8995_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
2048#define WM8995_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
2049#define WM8995_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
2050
2051/*
2052 * R1027 (0x403) - AIF1 DAC1 Right Volume
2053 */
2054#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
2055#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
2056#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
2057#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
2058#define WM8995_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
2059#define WM8995_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
2060#define WM8995_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
2061
2062/*
2063 * R1028 (0x404) - AIF1 ADC2 Left Volume
2064 */
2065#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
2066#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
2067#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
2068#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
2069#define WM8995_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
2070#define WM8995_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
2071#define WM8995_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
2072
2073/*
2074 * R1029 (0x405) - AIF1 ADC2 Right Volume
2075 */
2076#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
2077#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
2078#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
2079#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
2080#define WM8995_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
2081#define WM8995_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
2082#define WM8995_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
2083
2084/*
2085 * R1030 (0x406) - AIF1 DAC2 Left Volume
2086 */
2087#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
2088#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
2089#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
2090#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
2091#define WM8995_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
2092#define WM8995_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
2093#define WM8995_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
2094
2095/*
2096 * R1031 (0x407) - AIF1 DAC2 Right Volume
2097 */
2098#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
2099#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
2100#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
2101#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
2102#define WM8995_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
2103#define WM8995_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
2104#define WM8995_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
2105
2106/*
2107 * R1040 (0x410) - AIF1 ADC1 Filters
2108 */
2109#define WM8995_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */
2110#define WM8995_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */
2111#define WM8995_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */
2112#define WM8995_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */
2113#define WM8995_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
2114#define WM8995_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
2115#define WM8995_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
2116#define WM8995_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
2117#define WM8995_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
2118#define WM8995_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
2119#define WM8995_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
2120#define WM8995_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
2121#define WM8995_AIF1ADC1_HPF_MODE 0x0008 /* AIF1ADC1_HPF_MODE */
2122#define WM8995_AIF1ADC1_HPF_MODE_MASK 0x0008 /* AIF1ADC1_HPF_MODE */
2123#define WM8995_AIF1ADC1_HPF_MODE_SHIFT 3 /* AIF1ADC1_HPF_MODE */
2124#define WM8995_AIF1ADC1_HPF_MODE_WIDTH 1 /* AIF1ADC1_HPF_MODE */
2125#define WM8995_AIF1ADC1_HPF_CUT_MASK 0x0007 /* AIF1ADC1_HPF_CUT - [2:0] */
2126#define WM8995_AIF1ADC1_HPF_CUT_SHIFT 0 /* AIF1ADC1_HPF_CUT - [2:0] */
2127#define WM8995_AIF1ADC1_HPF_CUT_WIDTH 3 /* AIF1ADC1_HPF_CUT - [2:0] */
2128
2129/*
2130 * R1041 (0x411) - AIF1 ADC2 Filters
2131 */
2132#define WM8995_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
2133#define WM8995_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
2134#define WM8995_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
2135#define WM8995_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
2136#define WM8995_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
2137#define WM8995_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
2138#define WM8995_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
2139#define WM8995_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
2140#define WM8995_AIF1ADC2_HPF_MODE 0x0008 /* AIF1ADC2_HPF_MODE */
2141#define WM8995_AIF1ADC2_HPF_MODE_MASK 0x0008 /* AIF1ADC2_HPF_MODE */
2142#define WM8995_AIF1ADC2_HPF_MODE_SHIFT 3 /* AIF1ADC2_HPF_MODE */
2143#define WM8995_AIF1ADC2_HPF_MODE_WIDTH 1 /* AIF1ADC2_HPF_MODE */
2144#define WM8995_AIF1ADC2_HPF_CUT_MASK 0x0007 /* AIF1ADC2_HPF_CUT - [2:0] */
2145#define WM8995_AIF1ADC2_HPF_CUT_SHIFT 0 /* AIF1ADC2_HPF_CUT - [2:0] */
2146#define WM8995_AIF1ADC2_HPF_CUT_WIDTH 3 /* AIF1ADC2_HPF_CUT - [2:0] */
2147
2148/*
2149 * R1056 (0x420) - AIF1 DAC1 Filters (1)
2150 */
2151#define WM8995_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
2152#define WM8995_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
2153#define WM8995_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
2154#define WM8995_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
2155#define WM8995_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
2156#define WM8995_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
2157#define WM8995_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
2158#define WM8995_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
2159#define WM8995_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
2160#define WM8995_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
2161#define WM8995_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
2162#define WM8995_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
2163#define WM8995_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
2164#define WM8995_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
2165#define WM8995_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
2166#define WM8995_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
2167#define WM8995_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
2168#define WM8995_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
2169#define WM8995_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
2170
2171/*
2172 * R1057 (0x421) - AIF1 DAC1 Filters (2)
2173 */
2174#define WM8995_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
2175#define WM8995_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
2176#define WM8995_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
2177#define WM8995_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
2178#define WM8995_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
2179#define WM8995_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
2180#define WM8995_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
2181
2182/*
2183 * R1058 (0x422) - AIF1 DAC2 Filters (1)
2184 */
2185#define WM8995_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
2186#define WM8995_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
2187#define WM8995_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
2188#define WM8995_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
2189#define WM8995_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
2190#define WM8995_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
2191#define WM8995_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
2192#define WM8995_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
2193#define WM8995_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
2194#define WM8995_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
2195#define WM8995_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
2196#define WM8995_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
2197#define WM8995_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
2198#define WM8995_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
2199#define WM8995_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
2200#define WM8995_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
2201#define WM8995_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
2202#define WM8995_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
2203#define WM8995_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
2204
2205/*
2206 * R1059 (0x423) - AIF1 DAC2 Filters (2)
2207 */
2208#define WM8995_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
2209#define WM8995_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
2210#define WM8995_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
2211#define WM8995_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
2212#define WM8995_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
2213#define WM8995_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
2214#define WM8995_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
2215
2216/*
2217 * R1088 (0x440) - AIF1 DRC1 (1)
2218 */
2219#define WM8995_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2220#define WM8995_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2221#define WM8995_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2222#define WM8995_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2223#define WM8995_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2224#define WM8995_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2225#define WM8995_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
2226#define WM8995_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
2227#define WM8995_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
2228#define WM8995_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
2229#define WM8995_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
2230#define WM8995_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
2231#define WM8995_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
2232#define WM8995_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
2233#define WM8995_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
2234#define WM8995_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
2235#define WM8995_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
2236#define WM8995_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
2237#define WM8995_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
2238#define WM8995_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
2239#define WM8995_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
2240#define WM8995_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
2241#define WM8995_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
2242#define WM8995_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
2243#define WM8995_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
2244#define WM8995_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
2245#define WM8995_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
2246#define WM8995_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
2247#define WM8995_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
2248#define WM8995_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
2249#define WM8995_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
2250#define WM8995_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
2251#define WM8995_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
2252#define WM8995_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
2253#define WM8995_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
2254#define WM8995_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
2255#define WM8995_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
2256#define WM8995_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
2257#define WM8995_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
2258#define WM8995_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
2259#define WM8995_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
2260#define WM8995_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
2261
2262/*
2263 * R1089 (0x441) - AIF1 DRC1 (2)
2264 */
2265#define WM8995_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
2266#define WM8995_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
2267#define WM8995_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
2268#define WM8995_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
2269#define WM8995_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
2270#define WM8995_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
2271#define WM8995_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
2272#define WM8995_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
2273#define WM8995_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
2274#define WM8995_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
2275#define WM8995_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
2276#define WM8995_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
2277
2278/*
2279 * R1090 (0x442) - AIF1 DRC1 (3)
2280 */
2281#define WM8995_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2282#define WM8995_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2283#define WM8995_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2284#define WM8995_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
2285#define WM8995_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
2286#define WM8995_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
2287#define WM8995_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
2288#define WM8995_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
2289#define WM8995_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
2290#define WM8995_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
2291#define WM8995_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
2292#define WM8995_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
2293#define WM8995_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
2294#define WM8995_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
2295#define WM8995_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
2296#define WM8995_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
2297#define WM8995_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
2298#define WM8995_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
2299
2300/*
2301 * R1091 (0x443) - AIF1 DRC1 (4)
2302 */
2303#define WM8995_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
2304#define WM8995_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
2305#define WM8995_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
2306#define WM8995_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
2307#define WM8995_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
2308#define WM8995_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
2309
2310/*
2311 * R1092 (0x444) - AIF1 DRC1 (5)
2312 */
2313#define WM8995_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
2314#define WM8995_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
2315#define WM8995_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
2316#define WM8995_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
2317#define WM8995_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
2318#define WM8995_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
2319
2320/*
2321 * R1104 (0x450) - AIF1 DRC2 (1)
2322 */
2323#define WM8995_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2324#define WM8995_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2325#define WM8995_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2326#define WM8995_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2327#define WM8995_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2328#define WM8995_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2329#define WM8995_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
2330#define WM8995_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
2331#define WM8995_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
2332#define WM8995_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
2333#define WM8995_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
2334#define WM8995_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
2335#define WM8995_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
2336#define WM8995_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
2337#define WM8995_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
2338#define WM8995_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
2339#define WM8995_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
2340#define WM8995_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
2341#define WM8995_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
2342#define WM8995_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
2343#define WM8995_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
2344#define WM8995_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
2345#define WM8995_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
2346#define WM8995_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
2347#define WM8995_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
2348#define WM8995_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
2349#define WM8995_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
2350#define WM8995_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
2351#define WM8995_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
2352#define WM8995_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
2353#define WM8995_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
2354#define WM8995_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
2355#define WM8995_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
2356#define WM8995_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
2357#define WM8995_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
2358#define WM8995_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
2359#define WM8995_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
2360#define WM8995_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
2361#define WM8995_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
2362#define WM8995_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
2363#define WM8995_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
2364#define WM8995_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
2365
2366/*
2367 * R1105 (0x451) - AIF1 DRC2 (2)
2368 */
2369#define WM8995_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
2370#define WM8995_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
2371#define WM8995_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
2372#define WM8995_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
2373#define WM8995_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
2374#define WM8995_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
2375#define WM8995_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
2376#define WM8995_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
2377#define WM8995_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
2378#define WM8995_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
2379#define WM8995_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
2380#define WM8995_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
2381
2382/*
2383 * R1106 (0x452) - AIF1 DRC2 (3)
2384 */
2385#define WM8995_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2386#define WM8995_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2387#define WM8995_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2388#define WM8995_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
2389#define WM8995_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
2390#define WM8995_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
2391#define WM8995_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
2392#define WM8995_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
2393#define WM8995_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
2394#define WM8995_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
2395#define WM8995_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
2396#define WM8995_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
2397#define WM8995_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
2398#define WM8995_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
2399#define WM8995_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
2400#define WM8995_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
2401#define WM8995_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
2402#define WM8995_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
2403
2404/*
2405 * R1107 (0x453) - AIF1 DRC2 (4)
2406 */
2407#define WM8995_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
2408#define WM8995_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
2409#define WM8995_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
2410#define WM8995_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
2411#define WM8995_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
2412#define WM8995_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
2413
2414/*
2415 * R1108 (0x454) - AIF1 DRC2 (5)
2416 */
2417#define WM8995_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
2418#define WM8995_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
2419#define WM8995_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
2420#define WM8995_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
2421#define WM8995_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
2422#define WM8995_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
2423
2424/*
2425 * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
2426 */
2427#define WM8995_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2428#define WM8995_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2429#define WM8995_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2430#define WM8995_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2431#define WM8995_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2432#define WM8995_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2433#define WM8995_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2434#define WM8995_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2435#define WM8995_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2436#define WM8995_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
2437#define WM8995_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
2438#define WM8995_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
2439#define WM8995_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
2440
2441/*
2442 * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
2443 */
2444#define WM8995_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2445#define WM8995_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2446#define WM8995_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2447#define WM8995_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2448#define WM8995_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2449#define WM8995_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2450
2451/*
2452 * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
2453 */
2454#define WM8995_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
2455#define WM8995_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
2456#define WM8995_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
2457
2458/*
2459 * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
2460 */
2461#define WM8995_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
2462#define WM8995_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
2463#define WM8995_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
2464
2465/*
2466 * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
2467 */
2468#define WM8995_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
2469#define WM8995_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
2470#define WM8995_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
2471
2472/*
2473 * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
2474 */
2475#define WM8995_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
2476#define WM8995_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
2477#define WM8995_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
2478
2479/*
2480 * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
2481 */
2482#define WM8995_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
2483#define WM8995_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
2484#define WM8995_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
2485
2486/*
2487 * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
2488 */
2489#define WM8995_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
2490#define WM8995_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
2491#define WM8995_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
2492
2493/*
2494 * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
2495 */
2496#define WM8995_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
2497#define WM8995_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
2498#define WM8995_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
2499
2500/*
2501 * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
2502 */
2503#define WM8995_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
2504#define WM8995_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
2505#define WM8995_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
2506
2507/*
2508 * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
2509 */
2510#define WM8995_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
2511#define WM8995_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
2512#define WM8995_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
2513
2514/*
2515 * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
2516 */
2517#define WM8995_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
2518#define WM8995_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
2519#define WM8995_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
2520
2521/*
2522 * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
2523 */
2524#define WM8995_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
2525#define WM8995_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
2526#define WM8995_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
2527
2528/*
2529 * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
2530 */
2531#define WM8995_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
2532#define WM8995_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
2533#define WM8995_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
2534
2535/*
2536 * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
2537 */
2538#define WM8995_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
2539#define WM8995_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
2540#define WM8995_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
2541
2542/*
2543 * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
2544 */
2545#define WM8995_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
2546#define WM8995_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
2547#define WM8995_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
2548
2549/*
2550 * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
2551 */
2552#define WM8995_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
2553#define WM8995_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
2554#define WM8995_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
2555
2556/*
2557 * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
2558 */
2559#define WM8995_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
2560#define WM8995_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
2561#define WM8995_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
2562
2563/*
2564 * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
2565 */
2566#define WM8995_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
2567#define WM8995_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
2568#define WM8995_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
2569
2570/*
2571 * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
2572 */
2573#define WM8995_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
2574#define WM8995_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
2575#define WM8995_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
2576
2577/*
2578 * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
2579 */
2580#define WM8995_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
2581#define WM8995_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
2582#define WM8995_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
2583#define WM8995_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
2584#define WM8995_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
2585#define WM8995_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
2586#define WM8995_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
2587#define WM8995_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
2588#define WM8995_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
2589#define WM8995_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
2590#define WM8995_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
2591#define WM8995_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
2592#define WM8995_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
2593
2594/*
2595 * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
2596 */
2597#define WM8995_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
2598#define WM8995_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
2599#define WM8995_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
2600#define WM8995_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
2601#define WM8995_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
2602#define WM8995_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
2603
2604/*
2605 * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
2606 */
2607#define WM8995_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
2608#define WM8995_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
2609#define WM8995_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
2610
2611/*
2612 * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
2613 */
2614#define WM8995_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
2615#define WM8995_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
2616#define WM8995_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
2617
2618/*
2619 * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
2620 */
2621#define WM8995_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
2622#define WM8995_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
2623#define WM8995_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
2624
2625/*
2626 * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
2627 */
2628#define WM8995_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
2629#define WM8995_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
2630#define WM8995_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
2631
2632/*
2633 * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
2634 */
2635#define WM8995_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
2636#define WM8995_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
2637#define WM8995_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
2638
2639/*
2640 * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
2641 */
2642#define WM8995_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
2643#define WM8995_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
2644#define WM8995_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
2645
2646/*
2647 * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
2648 */
2649#define WM8995_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
2650#define WM8995_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
2651#define WM8995_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
2652
2653/*
2654 * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
2655 */
2656#define WM8995_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
2657#define WM8995_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
2658#define WM8995_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
2659
2660/*
2661 * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
2662 */
2663#define WM8995_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
2664#define WM8995_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
2665#define WM8995_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
2666
2667/*
2668 * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
2669 */
2670#define WM8995_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
2671#define WM8995_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
2672#define WM8995_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
2673
2674/*
2675 * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
2676 */
2677#define WM8995_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
2678#define WM8995_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
2679#define WM8995_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
2680
2681/*
2682 * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
2683 */
2684#define WM8995_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
2685#define WM8995_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
2686#define WM8995_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
2687
2688/*
2689 * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
2690 */
2691#define WM8995_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
2692#define WM8995_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
2693#define WM8995_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
2694
2695/*
2696 * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
2697 */
2698#define WM8995_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
2699#define WM8995_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
2700#define WM8995_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
2701
2702/*
2703 * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
2704 */
2705#define WM8995_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
2706#define WM8995_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
2707#define WM8995_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
2708
2709/*
2710 * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
2711 */
2712#define WM8995_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
2713#define WM8995_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
2714#define WM8995_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
2715
2716/*
2717 * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
2718 */
2719#define WM8995_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
2720#define WM8995_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
2721#define WM8995_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
2722
2723/*
2724 * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
2725 */
2726#define WM8995_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
2727#define WM8995_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
2728#define WM8995_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
2729
2730/*
2731 * R1280 (0x500) - AIF2 ADC Left Volume
2732 */
2733#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
2734#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
2735#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
2736#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
2737#define WM8995_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
2738#define WM8995_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
2739#define WM8995_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
2740
2741/*
2742 * R1281 (0x501) - AIF2 ADC Right Volume
2743 */
2744#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
2745#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
2746#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
2747#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
2748#define WM8995_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
2749#define WM8995_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
2750#define WM8995_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
2751
2752/*
2753 * R1282 (0x502) - AIF2 DAC Left Volume
2754 */
2755#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
2756#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
2757#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
2758#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
2759#define WM8995_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
2760#define WM8995_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
2761#define WM8995_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
2762
2763/*
2764 * R1283 (0x503) - AIF2 DAC Right Volume
2765 */
2766#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
2767#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
2768#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
2769#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
2770#define WM8995_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
2771#define WM8995_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
2772#define WM8995_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
2773
2774/*
2775 * R1296 (0x510) - AIF2 ADC Filters
2776 */
2777#define WM8995_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
2778#define WM8995_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
2779#define WM8995_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
2780#define WM8995_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
2781#define WM8995_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
2782#define WM8995_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
2783#define WM8995_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
2784#define WM8995_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
2785#define WM8995_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
2786#define WM8995_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
2787#define WM8995_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
2788#define WM8995_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
2789#define WM8995_AIF2ADC_HPF_MODE 0x0008 /* AIF2ADC_HPF_MODE */
2790#define WM8995_AIF2ADC_HPF_MODE_MASK 0x0008 /* AIF2ADC_HPF_MODE */
2791#define WM8995_AIF2ADC_HPF_MODE_SHIFT 3 /* AIF2ADC_HPF_MODE */
2792#define WM8995_AIF2ADC_HPF_MODE_WIDTH 1 /* AIF2ADC_HPF_MODE */
2793#define WM8995_AIF2ADC_HPF_CUT_MASK 0x0007 /* AIF2ADC_HPF_CUT - [2:0] */
2794#define WM8995_AIF2ADC_HPF_CUT_SHIFT 0 /* AIF2ADC_HPF_CUT - [2:0] */
2795#define WM8995_AIF2ADC_HPF_CUT_WIDTH 3 /* AIF2ADC_HPF_CUT - [2:0] */
2796
2797/*
2798 * R1312 (0x520) - AIF2 DAC Filters (1)
2799 */
2800#define WM8995_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
2801#define WM8995_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
2802#define WM8995_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
2803#define WM8995_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
2804#define WM8995_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
2805#define WM8995_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
2806#define WM8995_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
2807#define WM8995_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
2808#define WM8995_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
2809#define WM8995_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
2810#define WM8995_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
2811#define WM8995_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
2812#define WM8995_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
2813#define WM8995_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
2814#define WM8995_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
2815#define WM8995_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
2816#define WM8995_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
2817#define WM8995_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
2818#define WM8995_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
2819
2820/*
2821 * R1313 (0x521) - AIF2 DAC Filters (2)
2822 */
2823#define WM8995_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
2824#define WM8995_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
2825#define WM8995_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
2826#define WM8995_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
2827#define WM8995_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
2828#define WM8995_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
2829#define WM8995_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
2830
2831/*
2832 * R1344 (0x540) - AIF2 DRC (1)
2833 */
2834#define WM8995_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
2835#define WM8995_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
2836#define WM8995_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
2837#define WM8995_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
2838#define WM8995_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
2839#define WM8995_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
2840#define WM8995_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
2841#define WM8995_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
2842#define WM8995_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
2843#define WM8995_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
2844#define WM8995_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
2845#define WM8995_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
2846#define WM8995_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
2847#define WM8995_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
2848#define WM8995_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
2849#define WM8995_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
2850#define WM8995_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
2851#define WM8995_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
2852#define WM8995_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
2853#define WM8995_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
2854#define WM8995_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
2855#define WM8995_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
2856#define WM8995_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
2857#define WM8995_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
2858#define WM8995_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
2859#define WM8995_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
2860#define WM8995_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
2861#define WM8995_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
2862#define WM8995_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
2863#define WM8995_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
2864#define WM8995_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
2865#define WM8995_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
2866#define WM8995_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
2867#define WM8995_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
2868#define WM8995_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
2869#define WM8995_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
2870#define WM8995_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
2871#define WM8995_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
2872#define WM8995_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
2873#define WM8995_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
2874#define WM8995_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
2875#define WM8995_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
2876
2877/*
2878 * R1345 (0x541) - AIF2 DRC (2)
2879 */
2880#define WM8995_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
2881#define WM8995_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
2882#define WM8995_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
2883#define WM8995_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
2884#define WM8995_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
2885#define WM8995_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
2886#define WM8995_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
2887#define WM8995_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
2888#define WM8995_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
2889#define WM8995_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
2890#define WM8995_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
2891#define WM8995_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
2892
2893/*
2894 * R1346 (0x542) - AIF2 DRC (3)
2895 */
2896#define WM8995_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
2897#define WM8995_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
2898#define WM8995_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
2899#define WM8995_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
2900#define WM8995_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
2901#define WM8995_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
2902#define WM8995_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
2903#define WM8995_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
2904#define WM8995_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
2905#define WM8995_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
2906#define WM8995_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
2907#define WM8995_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
2908#define WM8995_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
2909#define WM8995_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
2910#define WM8995_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
2911#define WM8995_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
2912#define WM8995_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
2913#define WM8995_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
2914
2915/*
2916 * R1347 (0x543) - AIF2 DRC (4)
2917 */
2918#define WM8995_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
2919#define WM8995_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
2920#define WM8995_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
2921#define WM8995_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
2922#define WM8995_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
2923#define WM8995_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
2924
2925/*
2926 * R1348 (0x544) - AIF2 DRC (5)
2927 */
2928#define WM8995_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
2929#define WM8995_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
2930#define WM8995_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
2931#define WM8995_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
2932#define WM8995_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
2933#define WM8995_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
2934
2935/*
2936 * R1408 (0x580) - AIF2 EQ Gains (1)
2937 */
2938#define WM8995_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
2939#define WM8995_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
2940#define WM8995_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
2941#define WM8995_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
2942#define WM8995_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
2943#define WM8995_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
2944#define WM8995_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
2945#define WM8995_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
2946#define WM8995_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
2947#define WM8995_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
2948#define WM8995_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
2949#define WM8995_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
2950#define WM8995_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
2951
2952/*
2953 * R1409 (0x581) - AIF2 EQ Gains (2)
2954 */
2955#define WM8995_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
2956#define WM8995_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
2957#define WM8995_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
2958#define WM8995_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
2959#define WM8995_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
2960#define WM8995_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
2961
2962/*
2963 * R1410 (0x582) - AIF2 EQ Band 1 A
2964 */
2965#define WM8995_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
2966#define WM8995_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
2967#define WM8995_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
2968
2969/*
2970 * R1411 (0x583) - AIF2 EQ Band 1 B
2971 */
2972#define WM8995_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
2973#define WM8995_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
2974#define WM8995_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
2975
2976/*
2977 * R1412 (0x584) - AIF2 EQ Band 1 PG
2978 */
2979#define WM8995_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
2980#define WM8995_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
2981#define WM8995_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
2982
2983/*
2984 * R1413 (0x585) - AIF2 EQ Band 2 A
2985 */
2986#define WM8995_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
2987#define WM8995_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
2988#define WM8995_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
2989
2990/*
2991 * R1414 (0x586) - AIF2 EQ Band 2 B
2992 */
2993#define WM8995_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
2994#define WM8995_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
2995#define WM8995_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
2996
2997/*
2998 * R1415 (0x587) - AIF2 EQ Band 2 C
2999 */
3000#define WM8995_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
3001#define WM8995_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
3002#define WM8995_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
3003
3004/*
3005 * R1416 (0x588) - AIF2 EQ Band 2 PG
3006 */
3007#define WM8995_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
3008#define WM8995_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
3009#define WM8995_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
3010
3011/*
3012 * R1417 (0x589) - AIF2 EQ Band 3 A
3013 */
3014#define WM8995_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
3015#define WM8995_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
3016#define WM8995_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
3017
3018/*
3019 * R1418 (0x58A) - AIF2 EQ Band 3 B
3020 */
3021#define WM8995_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
3022#define WM8995_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
3023#define WM8995_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
3024
3025/*
3026 * R1419 (0x58B) - AIF2 EQ Band 3 C
3027 */
3028#define WM8995_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
3029#define WM8995_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
3030#define WM8995_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
3031
3032/*
3033 * R1420 (0x58C) - AIF2 EQ Band 3 PG
3034 */
3035#define WM8995_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
3036#define WM8995_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
3037#define WM8995_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
3038
3039/*
3040 * R1421 (0x58D) - AIF2 EQ Band 4 A
3041 */
3042#define WM8995_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
3043#define WM8995_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
3044#define WM8995_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
3045
3046/*
3047 * R1422 (0x58E) - AIF2 EQ Band 4 B
3048 */
3049#define WM8995_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
3050#define WM8995_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
3051#define WM8995_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
3052
3053/*
3054 * R1423 (0x58F) - AIF2 EQ Band 4 C
3055 */
3056#define WM8995_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
3057#define WM8995_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
3058#define WM8995_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
3059
3060/*
3061 * R1424 (0x590) - AIF2 EQ Band 4 PG
3062 */
3063#define WM8995_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
3064#define WM8995_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
3065#define WM8995_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
3066
3067/*
3068 * R1425 (0x591) - AIF2 EQ Band 5 A
3069 */
3070#define WM8995_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
3071#define WM8995_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
3072#define WM8995_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
3073
3074/*
3075 * R1426 (0x592) - AIF2 EQ Band 5 B
3076 */
3077#define WM8995_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
3078#define WM8995_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
3079#define WM8995_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
3080
3081/*
3082 * R1427 (0x593) - AIF2 EQ Band 5 PG
3083 */
3084#define WM8995_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
3085#define WM8995_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
3086#define WM8995_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
3087
3088/*
3089 * R1536 (0x600) - DAC1 Mixer Volumes
3090 */
3091#define WM8995_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
3092#define WM8995_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
3093#define WM8995_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
3094#define WM8995_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
3095#define WM8995_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
3096#define WM8995_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
3097
3098/*
3099 * R1537 (0x601) - DAC1 Left Mixer Routing
3100 */
3101#define WM8995_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3102#define WM8995_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3103#define WM8995_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3104#define WM8995_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3105#define WM8995_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3106#define WM8995_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3107#define WM8995_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3108#define WM8995_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3109#define WM8995_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
3110#define WM8995_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
3111#define WM8995_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
3112#define WM8995_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
3113#define WM8995_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
3114#define WM8995_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
3115#define WM8995_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
3116#define WM8995_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
3117#define WM8995_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
3118#define WM8995_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
3119#define WM8995_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
3120#define WM8995_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
3121
3122/*
3123 * R1538 (0x602) - DAC1 Right Mixer Routing
3124 */
3125#define WM8995_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3126#define WM8995_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3127#define WM8995_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3128#define WM8995_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3129#define WM8995_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3130#define WM8995_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3131#define WM8995_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3132#define WM8995_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3133#define WM8995_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
3134#define WM8995_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
3135#define WM8995_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
3136#define WM8995_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
3137#define WM8995_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
3138#define WM8995_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
3139#define WM8995_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
3140#define WM8995_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
3141#define WM8995_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
3142#define WM8995_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
3143#define WM8995_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
3144#define WM8995_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
3145
3146/*
3147 * R1539 (0x603) - DAC2 Mixer Volumes
3148 */
3149#define WM8995_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
3150#define WM8995_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
3151#define WM8995_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
3152#define WM8995_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
3153#define WM8995_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
3154#define WM8995_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
3155
3156/*
3157 * R1540 (0x604) - DAC2 Left Mixer Routing
3158 */
3159#define WM8995_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3160#define WM8995_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3161#define WM8995_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3162#define WM8995_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3163#define WM8995_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3164#define WM8995_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3165#define WM8995_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3166#define WM8995_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3167#define WM8995_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
3168#define WM8995_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
3169#define WM8995_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
3170#define WM8995_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
3171#define WM8995_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
3172#define WM8995_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
3173#define WM8995_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
3174#define WM8995_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
3175#define WM8995_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
3176#define WM8995_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
3177#define WM8995_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
3178#define WM8995_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
3179
3180/*
3181 * R1541 (0x605) - DAC2 Right Mixer Routing
3182 */
3183#define WM8995_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3184#define WM8995_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3185#define WM8995_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3186#define WM8995_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3187#define WM8995_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3188#define WM8995_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3189#define WM8995_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3190#define WM8995_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3191#define WM8995_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
3192#define WM8995_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
3193#define WM8995_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
3194#define WM8995_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
3195#define WM8995_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
3196#define WM8995_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
3197#define WM8995_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
3198#define WM8995_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
3199#define WM8995_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
3200#define WM8995_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
3201#define WM8995_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
3202#define WM8995_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
3203
3204/*
3205 * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
3206 */
3207#define WM8995_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
3208#define WM8995_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
3209#define WM8995_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
3210#define WM8995_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
3211#define WM8995_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
3212#define WM8995_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
3213#define WM8995_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
3214#define WM8995_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
3215
3216/*
3217 * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
3218 */
3219#define WM8995_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
3220#define WM8995_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
3221#define WM8995_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
3222#define WM8995_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
3223#define WM8995_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
3224#define WM8995_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
3225#define WM8995_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
3226#define WM8995_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
3227
3228/*
3229 * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
3230 */
3231#define WM8995_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
3232#define WM8995_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
3233#define WM8995_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
3234#define WM8995_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
3235#define WM8995_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
3236#define WM8995_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
3237#define WM8995_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
3238#define WM8995_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
3239
3240/*
3241 * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
3242 */
3243#define WM8995_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
3244#define WM8995_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
3245#define WM8995_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
3246#define WM8995_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
3247#define WM8995_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
3248#define WM8995_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
3249#define WM8995_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
3250#define WM8995_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
3251
3252/*
3253 * R1552 (0x610) - DAC Softmute
3254 */
3255#define WM8995_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3256#define WM8995_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3257#define WM8995_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3258#define WM8995_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3259#define WM8995_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3260#define WM8995_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3261#define WM8995_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3262#define WM8995_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3263
3264/*
3265 * R1568 (0x620) - Oversampling
3266 */
3267#define WM8995_ADC_OSR128 0x0002 /* ADC_OSR128 */
3268#define WM8995_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3269#define WM8995_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3270#define WM8995_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3271#define WM8995_DAC_OSR128 0x0001 /* DAC_OSR128 */
3272#define WM8995_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3273#define WM8995_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3274#define WM8995_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3275
3276/*
3277 * R1569 (0x621) - Sidetone
3278 */
3279#define WM8995_ST_LPF 0x1000 /* ST_LPF */
3280#define WM8995_ST_LPF_MASK 0x1000 /* ST_LPF */
3281#define WM8995_ST_LPF_SHIFT 12 /* ST_LPF */
3282#define WM8995_ST_LPF_WIDTH 1 /* ST_LPF */
3283#define WM8995_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3284#define WM8995_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3285#define WM8995_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3286#define WM8995_ST_HPF 0x0040 /* ST_HPF */
3287#define WM8995_ST_HPF_MASK 0x0040 /* ST_HPF */
3288#define WM8995_ST_HPF_SHIFT 6 /* ST_HPF */
3289#define WM8995_ST_HPF_WIDTH 1 /* ST_HPF */
3290#define WM8995_STR_SEL 0x0002 /* STR_SEL */
3291#define WM8995_STR_SEL_MASK 0x0002 /* STR_SEL */
3292#define WM8995_STR_SEL_SHIFT 1 /* STR_SEL */
3293#define WM8995_STR_SEL_WIDTH 1 /* STR_SEL */
3294#define WM8995_STL_SEL 0x0001 /* STL_SEL */
3295#define WM8995_STL_SEL_MASK 0x0001 /* STL_SEL */
3296#define WM8995_STL_SEL_SHIFT 0 /* STL_SEL */
3297#define WM8995_STL_SEL_WIDTH 1 /* STL_SEL */
3298
3299/*
3300 * R1792 (0x700) - GPIO 1
3301 */
3302#define WM8995_GP1_DIR 0x8000 /* GP1_DIR */
3303#define WM8995_GP1_DIR_MASK 0x8000 /* GP1_DIR */
3304#define WM8995_GP1_DIR_SHIFT 15 /* GP1_DIR */
3305#define WM8995_GP1_DIR_WIDTH 1 /* GP1_DIR */
3306#define WM8995_GP1_PU 0x4000 /* GP1_PU */
3307#define WM8995_GP1_PU_MASK 0x4000 /* GP1_PU */
3308#define WM8995_GP1_PU_SHIFT 14 /* GP1_PU */
3309#define WM8995_GP1_PU_WIDTH 1 /* GP1_PU */
3310#define WM8995_GP1_PD 0x2000 /* GP1_PD */
3311#define WM8995_GP1_PD_MASK 0x2000 /* GP1_PD */
3312#define WM8995_GP1_PD_SHIFT 13 /* GP1_PD */
3313#define WM8995_GP1_PD_WIDTH 1 /* GP1_PD */
3314#define WM8995_GP1_POL 0x0400 /* GP1_POL */
3315#define WM8995_GP1_POL_MASK 0x0400 /* GP1_POL */
3316#define WM8995_GP1_POL_SHIFT 10 /* GP1_POL */
3317#define WM8995_GP1_POL_WIDTH 1 /* GP1_POL */
3318#define WM8995_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
3319#define WM8995_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
3320#define WM8995_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
3321#define WM8995_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
3322#define WM8995_GP1_DB 0x0100 /* GP1_DB */
3323#define WM8995_GP1_DB_MASK 0x0100 /* GP1_DB */
3324#define WM8995_GP1_DB_SHIFT 8 /* GP1_DB */
3325#define WM8995_GP1_DB_WIDTH 1 /* GP1_DB */
3326#define WM8995_GP1_LVL 0x0040 /* GP1_LVL */
3327#define WM8995_GP1_LVL_MASK 0x0040 /* GP1_LVL */
3328#define WM8995_GP1_LVL_SHIFT 6 /* GP1_LVL */
3329#define WM8995_GP1_LVL_WIDTH 1 /* GP1_LVL */
3330#define WM8995_GP1_FN_MASK 0x001F /* GP1_FN - [4:0] */
3331#define WM8995_GP1_FN_SHIFT 0 /* GP1_FN - [4:0] */
3332#define WM8995_GP1_FN_WIDTH 5 /* GP1_FN - [4:0] */
3333
3334/*
3335 * R1793 (0x701) - GPIO 2
3336 */
3337#define WM8995_GP2_DIR 0x8000 /* GP2_DIR */
3338#define WM8995_GP2_DIR_MASK 0x8000 /* GP2_DIR */
3339#define WM8995_GP2_DIR_SHIFT 15 /* GP2_DIR */
3340#define WM8995_GP2_DIR_WIDTH 1 /* GP2_DIR */
3341#define WM8995_GP2_PU 0x4000 /* GP2_PU */
3342#define WM8995_GP2_PU_MASK 0x4000 /* GP2_PU */
3343#define WM8995_GP2_PU_SHIFT 14 /* GP2_PU */
3344#define WM8995_GP2_PU_WIDTH 1 /* GP2_PU */
3345#define WM8995_GP2_PD 0x2000 /* GP2_PD */
3346#define WM8995_GP2_PD_MASK 0x2000 /* GP2_PD */
3347#define WM8995_GP2_PD_SHIFT 13 /* GP2_PD */
3348#define WM8995_GP2_PD_WIDTH 1 /* GP2_PD */
3349#define WM8995_GP2_POL 0x0400 /* GP2_POL */
3350#define WM8995_GP2_POL_MASK 0x0400 /* GP2_POL */
3351#define WM8995_GP2_POL_SHIFT 10 /* GP2_POL */
3352#define WM8995_GP2_POL_WIDTH 1 /* GP2_POL */
3353#define WM8995_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
3354#define WM8995_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
3355#define WM8995_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
3356#define WM8995_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
3357#define WM8995_GP2_DB 0x0100 /* GP2_DB */
3358#define WM8995_GP2_DB_MASK 0x0100 /* GP2_DB */
3359#define WM8995_GP2_DB_SHIFT 8 /* GP2_DB */
3360#define WM8995_GP2_DB_WIDTH 1 /* GP2_DB */
3361#define WM8995_GP2_LVL 0x0040 /* GP2_LVL */
3362#define WM8995_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3363#define WM8995_GP2_LVL_SHIFT 6 /* GP2_LVL */
3364#define WM8995_GP2_LVL_WIDTH 1 /* GP2_LVL */
3365#define WM8995_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
3366#define WM8995_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
3367#define WM8995_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
3368
3369/*
3370 * R1794 (0x702) - GPIO 3
3371 */
3372#define WM8995_GP3_DIR 0x8000 /* GP3_DIR */
3373#define WM8995_GP3_DIR_MASK 0x8000 /* GP3_DIR */
3374#define WM8995_GP3_DIR_SHIFT 15 /* GP3_DIR */
3375#define WM8995_GP3_DIR_WIDTH 1 /* GP3_DIR */
3376#define WM8995_GP3_PU 0x4000 /* GP3_PU */
3377#define WM8995_GP3_PU_MASK 0x4000 /* GP3_PU */
3378#define WM8995_GP3_PU_SHIFT 14 /* GP3_PU */
3379#define WM8995_GP3_PU_WIDTH 1 /* GP3_PU */
3380#define WM8995_GP3_PD 0x2000 /* GP3_PD */
3381#define WM8995_GP3_PD_MASK 0x2000 /* GP3_PD */
3382#define WM8995_GP3_PD_SHIFT 13 /* GP3_PD */
3383#define WM8995_GP3_PD_WIDTH 1 /* GP3_PD */
3384#define WM8995_GP3_POL 0x0400 /* GP3_POL */
3385#define WM8995_GP3_POL_MASK 0x0400 /* GP3_POL */
3386#define WM8995_GP3_POL_SHIFT 10 /* GP3_POL */
3387#define WM8995_GP3_POL_WIDTH 1 /* GP3_POL */
3388#define WM8995_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3389#define WM8995_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3390#define WM8995_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3391#define WM8995_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3392#define WM8995_GP3_DB 0x0100 /* GP3_DB */
3393#define WM8995_GP3_DB_MASK 0x0100 /* GP3_DB */
3394#define WM8995_GP3_DB_SHIFT 8 /* GP3_DB */
3395#define WM8995_GP3_DB_WIDTH 1 /* GP3_DB */
3396#define WM8995_GP3_LVL 0x0040 /* GP3_LVL */
3397#define WM8995_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3398#define WM8995_GP3_LVL_SHIFT 6 /* GP3_LVL */
3399#define WM8995_GP3_LVL_WIDTH 1 /* GP3_LVL */
3400#define WM8995_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
3401#define WM8995_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
3402#define WM8995_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
3403
3404/*
3405 * R1795 (0x703) - GPIO 4
3406 */
3407#define WM8995_GP4_DIR 0x8000 /* GP4_DIR */
3408#define WM8995_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3409#define WM8995_GP4_DIR_SHIFT 15 /* GP4_DIR */
3410#define WM8995_GP4_DIR_WIDTH 1 /* GP4_DIR */
3411#define WM8995_GP4_PU 0x4000 /* GP4_PU */
3412#define WM8995_GP4_PU_MASK 0x4000 /* GP4_PU */
3413#define WM8995_GP4_PU_SHIFT 14 /* GP4_PU */
3414#define WM8995_GP4_PU_WIDTH 1 /* GP4_PU */
3415#define WM8995_GP4_PD 0x2000 /* GP4_PD */
3416#define WM8995_GP4_PD_MASK 0x2000 /* GP4_PD */
3417#define WM8995_GP4_PD_SHIFT 13 /* GP4_PD */
3418#define WM8995_GP4_PD_WIDTH 1 /* GP4_PD */
3419#define WM8995_GP4_POL 0x0400 /* GP4_POL */
3420#define WM8995_GP4_POL_MASK 0x0400 /* GP4_POL */
3421#define WM8995_GP4_POL_SHIFT 10 /* GP4_POL */
3422#define WM8995_GP4_POL_WIDTH 1 /* GP4_POL */
3423#define WM8995_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3424#define WM8995_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3425#define WM8995_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3426#define WM8995_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3427#define WM8995_GP4_DB 0x0100 /* GP4_DB */
3428#define WM8995_GP4_DB_MASK 0x0100 /* GP4_DB */
3429#define WM8995_GP4_DB_SHIFT 8 /* GP4_DB */
3430#define WM8995_GP4_DB_WIDTH 1 /* GP4_DB */
3431#define WM8995_GP4_LVL 0x0040 /* GP4_LVL */
3432#define WM8995_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3433#define WM8995_GP4_LVL_SHIFT 6 /* GP4_LVL */
3434#define WM8995_GP4_LVL_WIDTH 1 /* GP4_LVL */
3435#define WM8995_GP4_FN_MASK 0x001F /* GP4_FN - [4:0] */
3436#define WM8995_GP4_FN_SHIFT 0 /* GP4_FN - [4:0] */
3437#define WM8995_GP4_FN_WIDTH 5 /* GP4_FN - [4:0] */
3438
3439/*
3440 * R1796 (0x704) - GPIO 5
3441 */
3442#define WM8995_GP5_DIR 0x8000 /* GP5_DIR */
3443#define WM8995_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3444#define WM8995_GP5_DIR_SHIFT 15 /* GP5_DIR */
3445#define WM8995_GP5_DIR_WIDTH 1 /* GP5_DIR */
3446#define WM8995_GP5_PU 0x4000 /* GP5_PU */
3447#define WM8995_GP5_PU_MASK 0x4000 /* GP5_PU */
3448#define WM8995_GP5_PU_SHIFT 14 /* GP5_PU */
3449#define WM8995_GP5_PU_WIDTH 1 /* GP5_PU */
3450#define WM8995_GP5_PD 0x2000 /* GP5_PD */
3451#define WM8995_GP5_PD_MASK 0x2000 /* GP5_PD */
3452#define WM8995_GP5_PD_SHIFT 13 /* GP5_PD */
3453#define WM8995_GP5_PD_WIDTH 1 /* GP5_PD */
3454#define WM8995_GP5_POL 0x0400 /* GP5_POL */
3455#define WM8995_GP5_POL_MASK 0x0400 /* GP5_POL */
3456#define WM8995_GP5_POL_SHIFT 10 /* GP5_POL */
3457#define WM8995_GP5_POL_WIDTH 1 /* GP5_POL */
3458#define WM8995_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3459#define WM8995_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3460#define WM8995_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3461#define WM8995_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3462#define WM8995_GP5_DB 0x0100 /* GP5_DB */
3463#define WM8995_GP5_DB_MASK 0x0100 /* GP5_DB */
3464#define WM8995_GP5_DB_SHIFT 8 /* GP5_DB */
3465#define WM8995_GP5_DB_WIDTH 1 /* GP5_DB */
3466#define WM8995_GP5_LVL 0x0040 /* GP5_LVL */
3467#define WM8995_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3468#define WM8995_GP5_LVL_SHIFT 6 /* GP5_LVL */
3469#define WM8995_GP5_LVL_WIDTH 1 /* GP5_LVL */
3470#define WM8995_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
3471#define WM8995_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
3472#define WM8995_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
3473
3474/*
3475 * R1797 (0x705) - GPIO 6
3476 */
3477#define WM8995_GP6_DIR 0x8000 /* GP6_DIR */
3478#define WM8995_GP6_DIR_MASK 0x8000 /* GP6_DIR */
3479#define WM8995_GP6_DIR_SHIFT 15 /* GP6_DIR */
3480#define WM8995_GP6_DIR_WIDTH 1 /* GP6_DIR */
3481#define WM8995_GP6_PU 0x4000 /* GP6_PU */
3482#define WM8995_GP6_PU_MASK 0x4000 /* GP6_PU */
3483#define WM8995_GP6_PU_SHIFT 14 /* GP6_PU */
3484#define WM8995_GP6_PU_WIDTH 1 /* GP6_PU */
3485#define WM8995_GP6_PD 0x2000 /* GP6_PD */
3486#define WM8995_GP6_PD_MASK 0x2000 /* GP6_PD */
3487#define WM8995_GP6_PD_SHIFT 13 /* GP6_PD */
3488#define WM8995_GP6_PD_WIDTH 1 /* GP6_PD */
3489#define WM8995_GP6_POL 0x0400 /* GP6_POL */
3490#define WM8995_GP6_POL_MASK 0x0400 /* GP6_POL */
3491#define WM8995_GP6_POL_SHIFT 10 /* GP6_POL */
3492#define WM8995_GP6_POL_WIDTH 1 /* GP6_POL */
3493#define WM8995_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
3494#define WM8995_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
3495#define WM8995_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
3496#define WM8995_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
3497#define WM8995_GP6_DB 0x0100 /* GP6_DB */
3498#define WM8995_GP6_DB_MASK 0x0100 /* GP6_DB */
3499#define WM8995_GP6_DB_SHIFT 8 /* GP6_DB */
3500#define WM8995_GP6_DB_WIDTH 1 /* GP6_DB */
3501#define WM8995_GP6_LVL 0x0040 /* GP6_LVL */
3502#define WM8995_GP6_LVL_MASK 0x0040 /* GP6_LVL */
3503#define WM8995_GP6_LVL_SHIFT 6 /* GP6_LVL */
3504#define WM8995_GP6_LVL_WIDTH 1 /* GP6_LVL */
3505#define WM8995_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
3506#define WM8995_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
3507#define WM8995_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
3508
3509/*
3510 * R1798 (0x706) - GPIO 7
3511 */
3512#define WM8995_GP7_DIR 0x8000 /* GP7_DIR */
3513#define WM8995_GP7_DIR_MASK 0x8000 /* GP7_DIR */
3514#define WM8995_GP7_DIR_SHIFT 15 /* GP7_DIR */
3515#define WM8995_GP7_DIR_WIDTH 1 /* GP7_DIR */
3516#define WM8995_GP7_PU 0x4000 /* GP7_PU */
3517#define WM8995_GP7_PU_MASK 0x4000 /* GP7_PU */
3518#define WM8995_GP7_PU_SHIFT 14 /* GP7_PU */
3519#define WM8995_GP7_PU_WIDTH 1 /* GP7_PU */
3520#define WM8995_GP7_PD 0x2000 /* GP7_PD */
3521#define WM8995_GP7_PD_MASK 0x2000 /* GP7_PD */
3522#define WM8995_GP7_PD_SHIFT 13 /* GP7_PD */
3523#define WM8995_GP7_PD_WIDTH 1 /* GP7_PD */
3524#define WM8995_GP7_POL 0x0400 /* GP7_POL */
3525#define WM8995_GP7_POL_MASK 0x0400 /* GP7_POL */
3526#define WM8995_GP7_POL_SHIFT 10 /* GP7_POL */
3527#define WM8995_GP7_POL_WIDTH 1 /* GP7_POL */
3528#define WM8995_GP7_OP_CFG 0x0200 /* GP7_OP_CFG */
3529#define WM8995_GP7_OP_CFG_MASK 0x0200 /* GP7_OP_CFG */
3530#define WM8995_GP7_OP_CFG_SHIFT 9 /* GP7_OP_CFG */
3531#define WM8995_GP7_OP_CFG_WIDTH 1 /* GP7_OP_CFG */
3532#define WM8995_GP7_DB 0x0100 /* GP7_DB */
3533#define WM8995_GP7_DB_MASK 0x0100 /* GP7_DB */
3534#define WM8995_GP7_DB_SHIFT 8 /* GP7_DB */
3535#define WM8995_GP7_DB_WIDTH 1 /* GP7_DB */
3536#define WM8995_GP7_LVL 0x0040 /* GP7_LVL */
3537#define WM8995_GP7_LVL_MASK 0x0040 /* GP7_LVL */
3538#define WM8995_GP7_LVL_SHIFT 6 /* GP7_LVL */
3539#define WM8995_GP7_LVL_WIDTH 1 /* GP7_LVL */
3540#define WM8995_GP7_FN_MASK 0x001F /* GP7_FN - [4:0] */
3541#define WM8995_GP7_FN_SHIFT 0 /* GP7_FN - [4:0] */
3542#define WM8995_GP7_FN_WIDTH 5 /* GP7_FN - [4:0] */
3543
3544/*
3545 * R1799 (0x707) - GPIO 8
3546 */
3547#define WM8995_GP8_DIR 0x8000 /* GP8_DIR */
3548#define WM8995_GP8_DIR_MASK 0x8000 /* GP8_DIR */
3549#define WM8995_GP8_DIR_SHIFT 15 /* GP8_DIR */
3550#define WM8995_GP8_DIR_WIDTH 1 /* GP8_DIR */
3551#define WM8995_GP8_PU 0x4000 /* GP8_PU */
3552#define WM8995_GP8_PU_MASK 0x4000 /* GP8_PU */
3553#define WM8995_GP8_PU_SHIFT 14 /* GP8_PU */
3554#define WM8995_GP8_PU_WIDTH 1 /* GP8_PU */
3555#define WM8995_GP8_PD 0x2000 /* GP8_PD */
3556#define WM8995_GP8_PD_MASK 0x2000 /* GP8_PD */
3557#define WM8995_GP8_PD_SHIFT 13 /* GP8_PD */
3558#define WM8995_GP8_PD_WIDTH 1 /* GP8_PD */
3559#define WM8995_GP8_POL 0x0400 /* GP8_POL */
3560#define WM8995_GP8_POL_MASK 0x0400 /* GP8_POL */
3561#define WM8995_GP8_POL_SHIFT 10 /* GP8_POL */
3562#define WM8995_GP8_POL_WIDTH 1 /* GP8_POL */
3563#define WM8995_GP8_OP_CFG 0x0200 /* GP8_OP_CFG */
3564#define WM8995_GP8_OP_CFG_MASK 0x0200 /* GP8_OP_CFG */
3565#define WM8995_GP8_OP_CFG_SHIFT 9 /* GP8_OP_CFG */
3566#define WM8995_GP8_OP_CFG_WIDTH 1 /* GP8_OP_CFG */
3567#define WM8995_GP8_DB 0x0100 /* GP8_DB */
3568#define WM8995_GP8_DB_MASK 0x0100 /* GP8_DB */
3569#define WM8995_GP8_DB_SHIFT 8 /* GP8_DB */
3570#define WM8995_GP8_DB_WIDTH 1 /* GP8_DB */
3571#define WM8995_GP8_LVL 0x0040 /* GP8_LVL */
3572#define WM8995_GP8_LVL_MASK 0x0040 /* GP8_LVL */
3573#define WM8995_GP8_LVL_SHIFT 6 /* GP8_LVL */
3574#define WM8995_GP8_LVL_WIDTH 1 /* GP8_LVL */
3575#define WM8995_GP8_FN_MASK 0x001F /* GP8_FN - [4:0] */
3576#define WM8995_GP8_FN_SHIFT 0 /* GP8_FN - [4:0] */
3577#define WM8995_GP8_FN_WIDTH 5 /* GP8_FN - [4:0] */
3578
3579/*
3580 * R1800 (0x708) - GPIO 9
3581 */
3582#define WM8995_GP9_DIR 0x8000 /* GP9_DIR */
3583#define WM8995_GP9_DIR_MASK 0x8000 /* GP9_DIR */
3584#define WM8995_GP9_DIR_SHIFT 15 /* GP9_DIR */
3585#define WM8995_GP9_DIR_WIDTH 1 /* GP9_DIR */
3586#define WM8995_GP9_PU 0x4000 /* GP9_PU */
3587#define WM8995_GP9_PU_MASK 0x4000 /* GP9_PU */
3588#define WM8995_GP9_PU_SHIFT 14 /* GP9_PU */
3589#define WM8995_GP9_PU_WIDTH 1 /* GP9_PU */
3590#define WM8995_GP9_PD 0x2000 /* GP9_PD */
3591#define WM8995_GP9_PD_MASK 0x2000 /* GP9_PD */
3592#define WM8995_GP9_PD_SHIFT 13 /* GP9_PD */
3593#define WM8995_GP9_PD_WIDTH 1 /* GP9_PD */
3594#define WM8995_GP9_POL 0x0400 /* GP9_POL */
3595#define WM8995_GP9_POL_MASK 0x0400 /* GP9_POL */
3596#define WM8995_GP9_POL_SHIFT 10 /* GP9_POL */
3597#define WM8995_GP9_POL_WIDTH 1 /* GP9_POL */
3598#define WM8995_GP9_OP_CFG 0x0200 /* GP9_OP_CFG */
3599#define WM8995_GP9_OP_CFG_MASK 0x0200 /* GP9_OP_CFG */
3600#define WM8995_GP9_OP_CFG_SHIFT 9 /* GP9_OP_CFG */
3601#define WM8995_GP9_OP_CFG_WIDTH 1 /* GP9_OP_CFG */
3602#define WM8995_GP9_DB 0x0100 /* GP9_DB */
3603#define WM8995_GP9_DB_MASK 0x0100 /* GP9_DB */
3604#define WM8995_GP9_DB_SHIFT 8 /* GP9_DB */
3605#define WM8995_GP9_DB_WIDTH 1 /* GP9_DB */
3606#define WM8995_GP9_LVL 0x0040 /* GP9_LVL */
3607#define WM8995_GP9_LVL_MASK 0x0040 /* GP9_LVL */
3608#define WM8995_GP9_LVL_SHIFT 6 /* GP9_LVL */
3609#define WM8995_GP9_LVL_WIDTH 1 /* GP9_LVL */
3610#define WM8995_GP9_FN_MASK 0x001F /* GP9_FN - [4:0] */
3611#define WM8995_GP9_FN_SHIFT 0 /* GP9_FN - [4:0] */
3612#define WM8995_GP9_FN_WIDTH 5 /* GP9_FN - [4:0] */
3613
3614/*
3615 * R1801 (0x709) - GPIO 10
3616 */
3617#define WM8995_GP10_DIR 0x8000 /* GP10_DIR */
3618#define WM8995_GP10_DIR_MASK 0x8000 /* GP10_DIR */
3619#define WM8995_GP10_DIR_SHIFT 15 /* GP10_DIR */
3620#define WM8995_GP10_DIR_WIDTH 1 /* GP10_DIR */
3621#define WM8995_GP10_PU 0x4000 /* GP10_PU */
3622#define WM8995_GP10_PU_MASK 0x4000 /* GP10_PU */
3623#define WM8995_GP10_PU_SHIFT 14 /* GP10_PU */
3624#define WM8995_GP10_PU_WIDTH 1 /* GP10_PU */
3625#define WM8995_GP10_PD 0x2000 /* GP10_PD */
3626#define WM8995_GP10_PD_MASK 0x2000 /* GP10_PD */
3627#define WM8995_GP10_PD_SHIFT 13 /* GP10_PD */
3628#define WM8995_GP10_PD_WIDTH 1 /* GP10_PD */
3629#define WM8995_GP10_POL 0x0400 /* GP10_POL */
3630#define WM8995_GP10_POL_MASK 0x0400 /* GP10_POL */
3631#define WM8995_GP10_POL_SHIFT 10 /* GP10_POL */
3632#define WM8995_GP10_POL_WIDTH 1 /* GP10_POL */
3633#define WM8995_GP10_OP_CFG 0x0200 /* GP10_OP_CFG */
3634#define WM8995_GP10_OP_CFG_MASK 0x0200 /* GP10_OP_CFG */
3635#define WM8995_GP10_OP_CFG_SHIFT 9 /* GP10_OP_CFG */
3636#define WM8995_GP10_OP_CFG_WIDTH 1 /* GP10_OP_CFG */
3637#define WM8995_GP10_DB 0x0100 /* GP10_DB */
3638#define WM8995_GP10_DB_MASK 0x0100 /* GP10_DB */
3639#define WM8995_GP10_DB_SHIFT 8 /* GP10_DB */
3640#define WM8995_GP10_DB_WIDTH 1 /* GP10_DB */
3641#define WM8995_GP10_LVL 0x0040 /* GP10_LVL */
3642#define WM8995_GP10_LVL_MASK 0x0040 /* GP10_LVL */
3643#define WM8995_GP10_LVL_SHIFT 6 /* GP10_LVL */
3644#define WM8995_GP10_LVL_WIDTH 1 /* GP10_LVL */
3645#define WM8995_GP10_FN_MASK 0x001F /* GP10_FN - [4:0] */
3646#define WM8995_GP10_FN_SHIFT 0 /* GP10_FN - [4:0] */
3647#define WM8995_GP10_FN_WIDTH 5 /* GP10_FN - [4:0] */
3648
3649/*
3650 * R1802 (0x70A) - GPIO 11
3651 */
3652#define WM8995_GP11_DIR 0x8000 /* GP11_DIR */
3653#define WM8995_GP11_DIR_MASK 0x8000 /* GP11_DIR */
3654#define WM8995_GP11_DIR_SHIFT 15 /* GP11_DIR */
3655#define WM8995_GP11_DIR_WIDTH 1 /* GP11_DIR */
3656#define WM8995_GP11_PU 0x4000 /* GP11_PU */
3657#define WM8995_GP11_PU_MASK 0x4000 /* GP11_PU */
3658#define WM8995_GP11_PU_SHIFT 14 /* GP11_PU */
3659#define WM8995_GP11_PU_WIDTH 1 /* GP11_PU */
3660#define WM8995_GP11_PD 0x2000 /* GP11_PD */
3661#define WM8995_GP11_PD_MASK 0x2000 /* GP11_PD */
3662#define WM8995_GP11_PD_SHIFT 13 /* GP11_PD */
3663#define WM8995_GP11_PD_WIDTH 1 /* GP11_PD */
3664#define WM8995_GP11_POL 0x0400 /* GP11_POL */
3665#define WM8995_GP11_POL_MASK 0x0400 /* GP11_POL */
3666#define WM8995_GP11_POL_SHIFT 10 /* GP11_POL */
3667#define WM8995_GP11_POL_WIDTH 1 /* GP11_POL */
3668#define WM8995_GP11_OP_CFG 0x0200 /* GP11_OP_CFG */
3669#define WM8995_GP11_OP_CFG_MASK 0x0200 /* GP11_OP_CFG */
3670#define WM8995_GP11_OP_CFG_SHIFT 9 /* GP11_OP_CFG */
3671#define WM8995_GP11_OP_CFG_WIDTH 1 /* GP11_OP_CFG */
3672#define WM8995_GP11_DB 0x0100 /* GP11_DB */
3673#define WM8995_GP11_DB_MASK 0x0100 /* GP11_DB */
3674#define WM8995_GP11_DB_SHIFT 8 /* GP11_DB */
3675#define WM8995_GP11_DB_WIDTH 1 /* GP11_DB */
3676#define WM8995_GP11_LVL 0x0040 /* GP11_LVL */
3677#define WM8995_GP11_LVL_MASK 0x0040 /* GP11_LVL */
3678#define WM8995_GP11_LVL_SHIFT 6 /* GP11_LVL */
3679#define WM8995_GP11_LVL_WIDTH 1 /* GP11_LVL */
3680#define WM8995_GP11_FN_MASK 0x001F /* GP11_FN - [4:0] */
3681#define WM8995_GP11_FN_SHIFT 0 /* GP11_FN - [4:0] */
3682#define WM8995_GP11_FN_WIDTH 5 /* GP11_FN - [4:0] */
3683
3684/*
3685 * R1803 (0x70B) - GPIO 12
3686 */
3687#define WM8995_GP12_DIR 0x8000 /* GP12_DIR */
3688#define WM8995_GP12_DIR_MASK 0x8000 /* GP12_DIR */
3689#define WM8995_GP12_DIR_SHIFT 15 /* GP12_DIR */
3690#define WM8995_GP12_DIR_WIDTH 1 /* GP12_DIR */
3691#define WM8995_GP12_PU 0x4000 /* GP12_PU */
3692#define WM8995_GP12_PU_MASK 0x4000 /* GP12_PU */
3693#define WM8995_GP12_PU_SHIFT 14 /* GP12_PU */
3694#define WM8995_GP12_PU_WIDTH 1 /* GP12_PU */
3695#define WM8995_GP12_PD 0x2000 /* GP12_PD */
3696#define WM8995_GP12_PD_MASK 0x2000 /* GP12_PD */
3697#define WM8995_GP12_PD_SHIFT 13 /* GP12_PD */
3698#define WM8995_GP12_PD_WIDTH 1 /* GP12_PD */
3699#define WM8995_GP12_POL 0x0400 /* GP12_POL */
3700#define WM8995_GP12_POL_MASK 0x0400 /* GP12_POL */
3701#define WM8995_GP12_POL_SHIFT 10 /* GP12_POL */
3702#define WM8995_GP12_POL_WIDTH 1 /* GP12_POL */
3703#define WM8995_GP12_OP_CFG 0x0200 /* GP12_OP_CFG */
3704#define WM8995_GP12_OP_CFG_MASK 0x0200 /* GP12_OP_CFG */
3705#define WM8995_GP12_OP_CFG_SHIFT 9 /* GP12_OP_CFG */
3706#define WM8995_GP12_OP_CFG_WIDTH 1 /* GP12_OP_CFG */
3707#define WM8995_GP12_DB 0x0100 /* GP12_DB */
3708#define WM8995_GP12_DB_MASK 0x0100 /* GP12_DB */
3709#define WM8995_GP12_DB_SHIFT 8 /* GP12_DB */
3710#define WM8995_GP12_DB_WIDTH 1 /* GP12_DB */
3711#define WM8995_GP12_LVL 0x0040 /* GP12_LVL */
3712#define WM8995_GP12_LVL_MASK 0x0040 /* GP12_LVL */
3713#define WM8995_GP12_LVL_SHIFT 6 /* GP12_LVL */
3714#define WM8995_GP12_LVL_WIDTH 1 /* GP12_LVL */
3715#define WM8995_GP12_FN_MASK 0x001F /* GP12_FN - [4:0] */
3716#define WM8995_GP12_FN_SHIFT 0 /* GP12_FN - [4:0] */
3717#define WM8995_GP12_FN_WIDTH 5 /* GP12_FN - [4:0] */
3718
3719/*
3720 * R1804 (0x70C) - GPIO 13
3721 */
3722#define WM8995_GP13_DIR 0x8000 /* GP13_DIR */
3723#define WM8995_GP13_DIR_MASK 0x8000 /* GP13_DIR */
3724#define WM8995_GP13_DIR_SHIFT 15 /* GP13_DIR */
3725#define WM8995_GP13_DIR_WIDTH 1 /* GP13_DIR */
3726#define WM8995_GP13_PU 0x4000 /* GP13_PU */
3727#define WM8995_GP13_PU_MASK 0x4000 /* GP13_PU */
3728#define WM8995_GP13_PU_SHIFT 14 /* GP13_PU */
3729#define WM8995_GP13_PU_WIDTH 1 /* GP13_PU */
3730#define WM8995_GP13_PD 0x2000 /* GP13_PD */
3731#define WM8995_GP13_PD_MASK 0x2000 /* GP13_PD */
3732#define WM8995_GP13_PD_SHIFT 13 /* GP13_PD */
3733#define WM8995_GP13_PD_WIDTH 1 /* GP13_PD */
3734#define WM8995_GP13_POL 0x0400 /* GP13_POL */
3735#define WM8995_GP13_POL_MASK 0x0400 /* GP13_POL */
3736#define WM8995_GP13_POL_SHIFT 10 /* GP13_POL */
3737#define WM8995_GP13_POL_WIDTH 1 /* GP13_POL */
3738#define WM8995_GP13_OP_CFG 0x0200 /* GP13_OP_CFG */
3739#define WM8995_GP13_OP_CFG_MASK 0x0200 /* GP13_OP_CFG */
3740#define WM8995_GP13_OP_CFG_SHIFT 9 /* GP13_OP_CFG */
3741#define WM8995_GP13_OP_CFG_WIDTH 1 /* GP13_OP_CFG */
3742#define WM8995_GP13_DB 0x0100 /* GP13_DB */
3743#define WM8995_GP13_DB_MASK 0x0100 /* GP13_DB */
3744#define WM8995_GP13_DB_SHIFT 8 /* GP13_DB */
3745#define WM8995_GP13_DB_WIDTH 1 /* GP13_DB */
3746#define WM8995_GP13_LVL 0x0040 /* GP13_LVL */
3747#define WM8995_GP13_LVL_MASK 0x0040 /* GP13_LVL */
3748#define WM8995_GP13_LVL_SHIFT 6 /* GP13_LVL */
3749#define WM8995_GP13_LVL_WIDTH 1 /* GP13_LVL */
3750#define WM8995_GP13_FN_MASK 0x001F /* GP13_FN - [4:0] */
3751#define WM8995_GP13_FN_SHIFT 0 /* GP13_FN - [4:0] */
3752#define WM8995_GP13_FN_WIDTH 5 /* GP13_FN - [4:0] */
3753
3754/*
3755 * R1805 (0x70D) - GPIO 14
3756 */
3757#define WM8995_GP14_DIR 0x8000 /* GP14_DIR */
3758#define WM8995_GP14_DIR_MASK 0x8000 /* GP14_DIR */
3759#define WM8995_GP14_DIR_SHIFT 15 /* GP14_DIR */
3760#define WM8995_GP14_DIR_WIDTH 1 /* GP14_DIR */
3761#define WM8995_GP14_PU 0x4000 /* GP14_PU */
3762#define WM8995_GP14_PU_MASK 0x4000 /* GP14_PU */
3763#define WM8995_GP14_PU_SHIFT 14 /* GP14_PU */
3764#define WM8995_GP14_PU_WIDTH 1 /* GP14_PU */
3765#define WM8995_GP14_PD 0x2000 /* GP14_PD */
3766#define WM8995_GP14_PD_MASK 0x2000 /* GP14_PD */
3767#define WM8995_GP14_PD_SHIFT 13 /* GP14_PD */
3768#define WM8995_GP14_PD_WIDTH 1 /* GP14_PD */
3769#define WM8995_GP14_POL 0x0400 /* GP14_POL */
3770#define WM8995_GP14_POL_MASK 0x0400 /* GP14_POL */
3771#define WM8995_GP14_POL_SHIFT 10 /* GP14_POL */
3772#define WM8995_GP14_POL_WIDTH 1 /* GP14_POL */
3773#define WM8995_GP14_OP_CFG 0x0200 /* GP14_OP_CFG */
3774#define WM8995_GP14_OP_CFG_MASK 0x0200 /* GP14_OP_CFG */
3775#define WM8995_GP14_OP_CFG_SHIFT 9 /* GP14_OP_CFG */
3776#define WM8995_GP14_OP_CFG_WIDTH 1 /* GP14_OP_CFG */
3777#define WM8995_GP14_DB 0x0100 /* GP14_DB */
3778#define WM8995_GP14_DB_MASK 0x0100 /* GP14_DB */
3779#define WM8995_GP14_DB_SHIFT 8 /* GP14_DB */
3780#define WM8995_GP14_DB_WIDTH 1 /* GP14_DB */
3781#define WM8995_GP14_LVL 0x0040 /* GP14_LVL */
3782#define WM8995_GP14_LVL_MASK 0x0040 /* GP14_LVL */
3783#define WM8995_GP14_LVL_SHIFT 6 /* GP14_LVL */
3784#define WM8995_GP14_LVL_WIDTH 1 /* GP14_LVL */
3785#define WM8995_GP14_FN_MASK 0x001F /* GP14_FN - [4:0] */
3786#define WM8995_GP14_FN_SHIFT 0 /* GP14_FN - [4:0] */
3787#define WM8995_GP14_FN_WIDTH 5 /* GP14_FN - [4:0] */
3788
3789/*
3790 * R1824 (0x720) - Pull Control (1)
3791 */
3792#define WM8995_DMICDAT3_PD 0x4000 /* DMICDAT3_PD */
3793#define WM8995_DMICDAT3_PD_MASK 0x4000 /* DMICDAT3_PD */
3794#define WM8995_DMICDAT3_PD_SHIFT 14 /* DMICDAT3_PD */
3795#define WM8995_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
3796#define WM8995_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
3797#define WM8995_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
3798#define WM8995_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
3799#define WM8995_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3800#define WM8995_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
3801#define WM8995_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
3802#define WM8995_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
3803#define WM8995_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3804#define WM8995_MCLK2_PU 0x0200 /* MCLK2_PU */
3805#define WM8995_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
3806#define WM8995_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
3807#define WM8995_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
3808#define WM8995_MCLK2_PD 0x0100 /* MCLK2_PD */
3809#define WM8995_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
3810#define WM8995_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
3811#define WM8995_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3812#define WM8995_MCLK1_PU 0x0080 /* MCLK1_PU */
3813#define WM8995_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3814#define WM8995_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3815#define WM8995_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3816#define WM8995_MCLK1_PD 0x0040 /* MCLK1_PD */
3817#define WM8995_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3818#define WM8995_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3819#define WM8995_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3820#define WM8995_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3821#define WM8995_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3822#define WM8995_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3823#define WM8995_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3824#define WM8995_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3825#define WM8995_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3826#define WM8995_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3827#define WM8995_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3828#define WM8995_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3829#define WM8995_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3830#define WM8995_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3831#define WM8995_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3832#define WM8995_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3833#define WM8995_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3834#define WM8995_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3835#define WM8995_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3836#define WM8995_BCLK1_PU 0x0002 /* BCLK1_PU */
3837#define WM8995_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3838#define WM8995_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3839#define WM8995_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3840#define WM8995_BCLK1_PD 0x0001 /* BCLK1_PD */
3841#define WM8995_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3842#define WM8995_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3843#define WM8995_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3844
3845/*
3846 * R1825 (0x721) - Pull Control (2)
3847 */
3848#define WM8995_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */
3849#define WM8995_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */
3850#define WM8995_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */
3851#define WM8995_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3852#define WM8995_MODE_PD 0x0004 /* MODE_PD */
3853#define WM8995_MODE_PD_MASK 0x0004 /* MODE_PD */
3854#define WM8995_MODE_PD_SHIFT 2 /* MODE_PD */
3855#define WM8995_MODE_PD_WIDTH 1 /* MODE_PD */
3856#define WM8995_CSNADDR_PD 0x0001 /* CSNADDR_PD */
3857#define WM8995_CSNADDR_PD_MASK 0x0001 /* CSNADDR_PD */
3858#define WM8995_CSNADDR_PD_SHIFT 0 /* CSNADDR_PD */
3859#define WM8995_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */
3860
3861/*
3862 * R1840 (0x730) - Interrupt Status 1
3863 */
3864#define WM8995_GP14_EINT 0x2000 /* GP14_EINT */
3865#define WM8995_GP14_EINT_MASK 0x2000 /* GP14_EINT */
3866#define WM8995_GP14_EINT_SHIFT 13 /* GP14_EINT */
3867#define WM8995_GP14_EINT_WIDTH 1 /* GP14_EINT */
3868#define WM8995_GP13_EINT 0x1000 /* GP13_EINT */
3869#define WM8995_GP13_EINT_MASK 0x1000 /* GP13_EINT */
3870#define WM8995_GP13_EINT_SHIFT 12 /* GP13_EINT */
3871#define WM8995_GP13_EINT_WIDTH 1 /* GP13_EINT */
3872#define WM8995_GP12_EINT 0x0800 /* GP12_EINT */
3873#define WM8995_GP12_EINT_MASK 0x0800 /* GP12_EINT */
3874#define WM8995_GP12_EINT_SHIFT 11 /* GP12_EINT */
3875#define WM8995_GP12_EINT_WIDTH 1 /* GP12_EINT */
3876#define WM8995_GP11_EINT 0x0400 /* GP11_EINT */
3877#define WM8995_GP11_EINT_MASK 0x0400 /* GP11_EINT */
3878#define WM8995_GP11_EINT_SHIFT 10 /* GP11_EINT */
3879#define WM8995_GP11_EINT_WIDTH 1 /* GP11_EINT */
3880#define WM8995_GP10_EINT 0x0200 /* GP10_EINT */
3881#define WM8995_GP10_EINT_MASK 0x0200 /* GP10_EINT */
3882#define WM8995_GP10_EINT_SHIFT 9 /* GP10_EINT */
3883#define WM8995_GP10_EINT_WIDTH 1 /* GP10_EINT */
3884#define WM8995_GP9_EINT 0x0100 /* GP9_EINT */
3885#define WM8995_GP9_EINT_MASK 0x0100 /* GP9_EINT */
3886#define WM8995_GP9_EINT_SHIFT 8 /* GP9_EINT */
3887#define WM8995_GP9_EINT_WIDTH 1 /* GP9_EINT */
3888#define WM8995_GP8_EINT 0x0080 /* GP8_EINT */
3889#define WM8995_GP8_EINT_MASK 0x0080 /* GP8_EINT */
3890#define WM8995_GP8_EINT_SHIFT 7 /* GP8_EINT */
3891#define WM8995_GP8_EINT_WIDTH 1 /* GP8_EINT */
3892#define WM8995_GP7_EINT 0x0040 /* GP7_EINT */
3893#define WM8995_GP7_EINT_MASK 0x0040 /* GP7_EINT */
3894#define WM8995_GP7_EINT_SHIFT 6 /* GP7_EINT */
3895#define WM8995_GP7_EINT_WIDTH 1 /* GP7_EINT */
3896#define WM8995_GP6_EINT 0x0020 /* GP6_EINT */
3897#define WM8995_GP6_EINT_MASK 0x0020 /* GP6_EINT */
3898#define WM8995_GP6_EINT_SHIFT 5 /* GP6_EINT */
3899#define WM8995_GP6_EINT_WIDTH 1 /* GP6_EINT */
3900#define WM8995_GP5_EINT 0x0010 /* GP5_EINT */
3901#define WM8995_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3902#define WM8995_GP5_EINT_SHIFT 4 /* GP5_EINT */
3903#define WM8995_GP5_EINT_WIDTH 1 /* GP5_EINT */
3904#define WM8995_GP4_EINT 0x0008 /* GP4_EINT */
3905#define WM8995_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3906#define WM8995_GP4_EINT_SHIFT 3 /* GP4_EINT */
3907#define WM8995_GP4_EINT_WIDTH 1 /* GP4_EINT */
3908#define WM8995_GP3_EINT 0x0004 /* GP3_EINT */
3909#define WM8995_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3910#define WM8995_GP3_EINT_SHIFT 2 /* GP3_EINT */
3911#define WM8995_GP3_EINT_WIDTH 1 /* GP3_EINT */
3912#define WM8995_GP2_EINT 0x0002 /* GP2_EINT */
3913#define WM8995_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3914#define WM8995_GP2_EINT_SHIFT 1 /* GP2_EINT */
3915#define WM8995_GP2_EINT_WIDTH 1 /* GP2_EINT */
3916#define WM8995_GP1_EINT 0x0001 /* GP1_EINT */
3917#define WM8995_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3918#define WM8995_GP1_EINT_SHIFT 0 /* GP1_EINT */
3919#define WM8995_GP1_EINT_WIDTH 1 /* GP1_EINT */
3920
3921/*
3922 * R1841 (0x731) - Interrupt Status 2
3923 */
3924#define WM8995_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
3925#define WM8995_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
3926#define WM8995_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
3927#define WM8995_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
3928#define WM8995_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
3929#define WM8995_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
3930#define WM8995_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
3931#define WM8995_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
3932#define WM8995_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
3933#define WM8995_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
3934#define WM8995_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
3935#define WM8995_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3936#define WM8995_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
3937#define WM8995_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
3938#define WM8995_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
3939#define WM8995_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3940#define WM8995_AIF2DRC_SIG_DET_EINT 0x0100 /* AIF2DRC_SIG_DET_EINT */
3941#define WM8995_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* AIF2DRC_SIG_DET_EINT */
3942#define WM8995_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* AIF2DRC_SIG_DET_EINT */
3943#define WM8995_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */
3944#define WM8995_AIF1DRC2_SIG_DET_EINT 0x0080 /* AIF1DRC2_SIG_DET_EINT */
3945#define WM8995_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* AIF1DRC2_SIG_DET_EINT */
3946#define WM8995_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* AIF1DRC2_SIG_DET_EINT */
3947#define WM8995_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */
3948#define WM8995_AIF1DRC1_SIG_DET_EINT 0x0040 /* AIF1DRC1_SIG_DET_EINT */
3949#define WM8995_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* AIF1DRC1_SIG_DET_EINT */
3950#define WM8995_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* AIF1DRC1_SIG_DET_EINT */
3951#define WM8995_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */
3952#define WM8995_SRC2_LOCK_EINT 0x0020 /* SRC2_LOCK_EINT */
3953#define WM8995_SRC2_LOCK_EINT_MASK 0x0020 /* SRC2_LOCK_EINT */
3954#define WM8995_SRC2_LOCK_EINT_SHIFT 5 /* SRC2_LOCK_EINT */
3955#define WM8995_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
3956#define WM8995_SRC1_LOCK_EINT 0x0010 /* SRC1_LOCK_EINT */
3957#define WM8995_SRC1_LOCK_EINT_MASK 0x0010 /* SRC1_LOCK_EINT */
3958#define WM8995_SRC1_LOCK_EINT_SHIFT 4 /* SRC1_LOCK_EINT */
3959#define WM8995_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
3960#define WM8995_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
3961#define WM8995_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
3962#define WM8995_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
3963#define WM8995_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
3964#define WM8995_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
3965#define WM8995_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
3966#define WM8995_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
3967#define WM8995_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
3968#define WM8995_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
3969#define WM8995_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
3970#define WM8995_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
3971#define WM8995_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
3972#define WM8995_MICD_EINT 0x0001 /* MICD_EINT */
3973#define WM8995_MICD_EINT_MASK 0x0001 /* MICD_EINT */
3974#define WM8995_MICD_EINT_SHIFT 0 /* MICD_EINT */
3975#define WM8995_MICD_EINT_WIDTH 1 /* MICD_EINT */
3976
3977/*
3978 * R1842 (0x732) - Interrupt Raw Status 2
3979 */
3980#define WM8995_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
3981#define WM8995_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
3982#define WM8995_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
3983#define WM8995_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
3984#define WM8995_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
3985#define WM8995_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
3986#define WM8995_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
3987#define WM8995_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
3988#define WM8995_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
3989#define WM8995_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
3990#define WM8995_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
3991#define WM8995_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
3992#define WM8995_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
3993#define WM8995_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
3994#define WM8995_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
3995#define WM8995_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
3996#define WM8995_AIF2DRC_SIG_DET_STS 0x0100 /* AIF2DRC_SIG_DET_STS */
3997#define WM8995_AIF2DRC_SIG_DET_STS_MASK 0x0100 /* AIF2DRC_SIG_DET_STS */
3998#define WM8995_AIF2DRC_SIG_DET_STS_SHIFT 8 /* AIF2DRC_SIG_DET_STS */
3999#define WM8995_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */
4000#define WM8995_AIF1DRC2_SIG_DET_STS 0x0080 /* AIF1DRC2_SIG_DET_STS */
4001#define WM8995_AIF1DRC2_SIG_DET_STS_MASK 0x0080 /* AIF1DRC2_SIG_DET_STS */
4002#define WM8995_AIF1DRC2_SIG_DET_STS_SHIFT 7 /* AIF1DRC2_SIG_DET_STS */
4003#define WM8995_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */
4004#define WM8995_AIF1DRC1_SIG_DET_STS 0x0040 /* AIF1DRC1_SIG_DET_STS */
4005#define WM8995_AIF1DRC1_SIG_DET_STS_MASK 0x0040 /* AIF1DRC1_SIG_DET_STS */
4006#define WM8995_AIF1DRC1_SIG_DET_STS_SHIFT 6 /* AIF1DRC1_SIG_DET_STS */
4007#define WM8995_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */
4008#define WM8995_SRC2_LOCK_STS 0x0020 /* SRC2_LOCK_STS */
4009#define WM8995_SRC2_LOCK_STS_MASK 0x0020 /* SRC2_LOCK_STS */
4010#define WM8995_SRC2_LOCK_STS_SHIFT 5 /* SRC2_LOCK_STS */
4011#define WM8995_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */
4012#define WM8995_SRC1_LOCK_STS 0x0010 /* SRC1_LOCK_STS */
4013#define WM8995_SRC1_LOCK_STS_MASK 0x0010 /* SRC1_LOCK_STS */
4014#define WM8995_SRC1_LOCK_STS_SHIFT 4 /* SRC1_LOCK_STS */
4015#define WM8995_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */
4016#define WM8995_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
4017#define WM8995_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
4018#define WM8995_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
4019#define WM8995_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
4020#define WM8995_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
4021#define WM8995_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
4022#define WM8995_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
4023#define WM8995_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
4024
4025/*
4026 * R1848 (0x738) - Interrupt Status 1 Mask
4027 */
4028#define WM8995_IM_GP14_EINT 0x2000 /* IM_GP14_EINT */
4029#define WM8995_IM_GP14_EINT_MASK 0x2000 /* IM_GP14_EINT */
4030#define WM8995_IM_GP14_EINT_SHIFT 13 /* IM_GP14_EINT */
4031#define WM8995_IM_GP14_EINT_WIDTH 1 /* IM_GP14_EINT */
4032#define WM8995_IM_GP13_EINT 0x1000 /* IM_GP13_EINT */
4033#define WM8995_IM_GP13_EINT_MASK 0x1000 /* IM_GP13_EINT */
4034#define WM8995_IM_GP13_EINT_SHIFT 12 /* IM_GP13_EINT */
4035#define WM8995_IM_GP13_EINT_WIDTH 1 /* IM_GP13_EINT */
4036#define WM8995_IM_GP12_EINT 0x0800 /* IM_GP12_EINT */
4037#define WM8995_IM_GP12_EINT_MASK 0x0800 /* IM_GP12_EINT */
4038#define WM8995_IM_GP12_EINT_SHIFT 11 /* IM_GP12_EINT */
4039#define WM8995_IM_GP12_EINT_WIDTH 1 /* IM_GP12_EINT */
4040#define WM8995_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
4041#define WM8995_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
4042#define WM8995_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
4043#define WM8995_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
4044#define WM8995_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
4045#define WM8995_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
4046#define WM8995_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
4047#define WM8995_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
4048#define WM8995_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
4049#define WM8995_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
4050#define WM8995_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
4051#define WM8995_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
4052#define WM8995_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
4053#define WM8995_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
4054#define WM8995_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
4055#define WM8995_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
4056#define WM8995_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
4057#define WM8995_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
4058#define WM8995_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
4059#define WM8995_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
4060#define WM8995_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
4061#define WM8995_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
4062#define WM8995_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
4063#define WM8995_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
4064#define WM8995_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
4065#define WM8995_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
4066#define WM8995_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
4067#define WM8995_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
4068#define WM8995_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
4069#define WM8995_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
4070#define WM8995_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
4071#define WM8995_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
4072#define WM8995_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
4073#define WM8995_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
4074#define WM8995_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
4075#define WM8995_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
4076#define WM8995_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
4077#define WM8995_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
4078#define WM8995_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
4079#define WM8995_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
4080#define WM8995_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
4081#define WM8995_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
4082#define WM8995_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
4083#define WM8995_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
4084
4085/*
4086 * R1849 (0x739) - Interrupt Status 2 Mask
4087 */
4088#define WM8995_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
4089#define WM8995_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
4090#define WM8995_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
4091#define WM8995_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
4092#define WM8995_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
4093#define WM8995_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
4094#define WM8995_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
4095#define WM8995_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
4096#define WM8995_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
4097#define WM8995_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
4098#define WM8995_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
4099#define WM8995_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
4100#define WM8995_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
4101#define WM8995_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
4102#define WM8995_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
4103#define WM8995_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
4104#define WM8995_IM_AIF2DRC_SIG_DET_EINT 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
4105#define WM8995_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
4106#define WM8995_IM_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* IM_AIF2DRC_SIG_DET_EINT */
4107#define WM8995_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */
4108#define WM8995_IM_AIF1DRC2_SIG_DET_EINT 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
4109#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
4110#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* IM_AIF1DRC2_SIG_DET_EINT */
4111#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */
4112#define WM8995_IM_AIF1DRC1_SIG_DET_EINT 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
4113#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
4114#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* IM_AIF1DRC1_SIG_DET_EINT */
4115#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */
4116#define WM8995_IM_SRC2_LOCK_EINT 0x0020 /* IM_SRC2_LOCK_EINT */
4117#define WM8995_IM_SRC2_LOCK_EINT_MASK 0x0020 /* IM_SRC2_LOCK_EINT */
4118#define WM8995_IM_SRC2_LOCK_EINT_SHIFT 5 /* IM_SRC2_LOCK_EINT */
4119#define WM8995_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
4120#define WM8995_IM_SRC1_LOCK_EINT 0x0010 /* IM_SRC1_LOCK_EINT */
4121#define WM8995_IM_SRC1_LOCK_EINT_MASK 0x0010 /* IM_SRC1_LOCK_EINT */
4122#define WM8995_IM_SRC1_LOCK_EINT_SHIFT 4 /* IM_SRC1_LOCK_EINT */
4123#define WM8995_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
4124#define WM8995_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
4125#define WM8995_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
4126#define WM8995_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
4127#define WM8995_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
4128#define WM8995_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
4129#define WM8995_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
4130#define WM8995_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
4131#define WM8995_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
4132#define WM8995_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
4133#define WM8995_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
4134#define WM8995_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
4135#define WM8995_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
4136#define WM8995_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
4137#define WM8995_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
4138#define WM8995_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
4139#define WM8995_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
4140
4141/*
4142 * R1856 (0x740) - Interrupt Control
4143 */
4144#define WM8995_IM_IRQ 0x0001 /* IM_IRQ */
4145#define WM8995_IM_IRQ_MASK 0x0001 /* IM_IRQ */
4146#define WM8995_IM_IRQ_SHIFT 0 /* IM_IRQ */
4147#define WM8995_IM_IRQ_WIDTH 1 /* IM_IRQ */
4148
4149/*
4150 * R2048 (0x800) - Left PDM Speaker 1
4151 */
4152#define WM8995_SPK1L_ENA 0x0010 /* SPK1L_ENA */
4153#define WM8995_SPK1L_ENA_MASK 0x0010 /* SPK1L_ENA */
4154#define WM8995_SPK1L_ENA_SHIFT 4 /* SPK1L_ENA */
4155#define WM8995_SPK1L_ENA_WIDTH 1 /* SPK1L_ENA */
4156#define WM8995_SPK1L_MUTE 0x0008 /* SPK1L_MUTE */
4157#define WM8995_SPK1L_MUTE_MASK 0x0008 /* SPK1L_MUTE */
4158#define WM8995_SPK1L_MUTE_SHIFT 3 /* SPK1L_MUTE */
4159#define WM8995_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
4160#define WM8995_SPK1L_MUTE_ZC 0x0004 /* SPK1L_MUTE_ZC */
4161#define WM8995_SPK1L_MUTE_ZC_MASK 0x0004 /* SPK1L_MUTE_ZC */
4162#define WM8995_SPK1L_MUTE_ZC_SHIFT 2 /* SPK1L_MUTE_ZC */
4163#define WM8995_SPK1L_MUTE_ZC_WIDTH 1 /* SPK1L_MUTE_ZC */
4164#define WM8995_SPK1L_SRC_MASK 0x0003 /* SPK1L_SRC - [1:0] */
4165#define WM8995_SPK1L_SRC_SHIFT 0 /* SPK1L_SRC - [1:0] */
4166#define WM8995_SPK1L_SRC_WIDTH 2 /* SPK1L_SRC - [1:0] */
4167
4168/*
4169 * R2049 (0x801) - Right PDM Speaker 1
4170 */
4171#define WM8995_SPK1R_ENA 0x0010 /* SPK1R_ENA */
4172#define WM8995_SPK1R_ENA_MASK 0x0010 /* SPK1R_ENA */
4173#define WM8995_SPK1R_ENA_SHIFT 4 /* SPK1R_ENA */
4174#define WM8995_SPK1R_ENA_WIDTH 1 /* SPK1R_ENA */
4175#define WM8995_SPK1R_MUTE 0x0008 /* SPK1R_MUTE */
4176#define WM8995_SPK1R_MUTE_MASK 0x0008 /* SPK1R_MUTE */
4177#define WM8995_SPK1R_MUTE_SHIFT 3 /* SPK1R_MUTE */
4178#define WM8995_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
4179#define WM8995_SPK1R_MUTE_ZC 0x0004 /* SPK1R_MUTE_ZC */
4180#define WM8995_SPK1R_MUTE_ZC_MASK 0x0004 /* SPK1R_MUTE_ZC */
4181#define WM8995_SPK1R_MUTE_ZC_SHIFT 2 /* SPK1R_MUTE_ZC */
4182#define WM8995_SPK1R_MUTE_ZC_WIDTH 1 /* SPK1R_MUTE_ZC */
4183#define WM8995_SPK1R_SRC_MASK 0x0003 /* SPK1R_SRC - [1:0] */
4184#define WM8995_SPK1R_SRC_SHIFT 0 /* SPK1R_SRC - [1:0] */
4185#define WM8995_SPK1R_SRC_WIDTH 2 /* SPK1R_SRC - [1:0] */
4186
4187/*
4188 * R2050 (0x802) - PDM Speaker 1 Mute Sequence
4189 */
4190#define WM8995_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
4191#define WM8995_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
4192#define WM8995_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
4193
4194/*
4195 * R2056 (0x808) - Left PDM Speaker 2
4196 */
4197#define WM8995_SPK2L_ENA 0x0010 /* SPK2L_ENA */
4198#define WM8995_SPK2L_ENA_MASK 0x0010 /* SPK2L_ENA */
4199#define WM8995_SPK2L_ENA_SHIFT 4 /* SPK2L_ENA */
4200#define WM8995_SPK2L_ENA_WIDTH 1 /* SPK2L_ENA */
4201#define WM8995_SPK2L_MUTE 0x0008 /* SPK2L_MUTE */
4202#define WM8995_SPK2L_MUTE_MASK 0x0008 /* SPK2L_MUTE */
4203#define WM8995_SPK2L_MUTE_SHIFT 3 /* SPK2L_MUTE */
4204#define WM8995_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
4205#define WM8995_SPK2L_MUTE_ZC 0x0004 /* SPK2L_MUTE_ZC */
4206#define WM8995_SPK2L_MUTE_ZC_MASK 0x0004 /* SPK2L_MUTE_ZC */
4207#define WM8995_SPK2L_MUTE_ZC_SHIFT 2 /* SPK2L_MUTE_ZC */
4208#define WM8995_SPK2L_MUTE_ZC_WIDTH 1 /* SPK2L_MUTE_ZC */
4209#define WM8995_SPK2L_SRC_MASK 0x0003 /* SPK2L_SRC - [1:0] */
4210#define WM8995_SPK2L_SRC_SHIFT 0 /* SPK2L_SRC - [1:0] */
4211#define WM8995_SPK2L_SRC_WIDTH 2 /* SPK2L_SRC - [1:0] */
4212
4213/*
4214 * R2057 (0x809) - Right PDM Speaker 2
4215 */
4216#define WM8995_SPK2R_ENA 0x0010 /* SPK2R_ENA */
4217#define WM8995_SPK2R_ENA_MASK 0x0010 /* SPK2R_ENA */
4218#define WM8995_SPK2R_ENA_SHIFT 4 /* SPK2R_ENA */
4219#define WM8995_SPK2R_ENA_WIDTH 1 /* SPK2R_ENA */
4220#define WM8995_SPK2R_MUTE 0x0008 /* SPK2R_MUTE */
4221#define WM8995_SPK2R_MUTE_MASK 0x0008 /* SPK2R_MUTE */
4222#define WM8995_SPK2R_MUTE_SHIFT 3 /* SPK2R_MUTE */
4223#define WM8995_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
4224#define WM8995_SPK2R_MUTE_ZC 0x0004 /* SPK2R_MUTE_ZC */
4225#define WM8995_SPK2R_MUTE_ZC_MASK 0x0004 /* SPK2R_MUTE_ZC */
4226#define WM8995_SPK2R_MUTE_ZC_SHIFT 2 /* SPK2R_MUTE_ZC */
4227#define WM8995_SPK2R_MUTE_ZC_WIDTH 1 /* SPK2R_MUTE_ZC */
4228#define WM8995_SPK2R_SRC_MASK 0x0003 /* SPK2R_SRC - [1:0] */
4229#define WM8995_SPK2R_SRC_SHIFT 0 /* SPK2R_SRC - [1:0] */
4230#define WM8995_SPK2R_SRC_WIDTH 2 /* SPK2R_SRC - [1:0] */
4231
4232/*
4233 * R2058 (0x80A) - PDM Speaker 2 Mute Sequence
4234 */
4235#define WM8995_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
4236#define WM8995_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
4238
4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
4240{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
4241 .info = snd_soc_info_volsw, \
4242 .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
4243 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
4244}
4245
4246struct wm8995_reg_access {
4247 u16 read;
4248 u16 write;
4249 u16 vol;
4250};
4251
4252/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
4253enum clk_src {
4254 WM8995_SYSCLK_MCLK1 = 1,
4255 WM8995_SYSCLK_MCLK2,
4256 WM8995_SYSCLK_FLL1,
4257 WM8995_SYSCLK_FLL2,
4258 WM8995_SYSCLK_OPCLK
4259};
4260
4261#define WM8995_FLL1 1
4262#define WM8995_FLL2 2
4263
4264#define WM8995_FLL_SRC_MCLK1 1
4265#define WM8995_FLL_SRC_MCLK2 2
4266#define WM8995_FLL_SRC_LRCLK 3
4267#define WM8995_FLL_SRC_BCLK 4
4268
4269#endif /* _WM8995_H */
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 76b37ff6c264..91c6b39de50c 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -15,6 +15,7 @@
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h>
18#include <linux/pm.h> 19#include <linux/pm.h>
19#include <linux/i2c.h> 20#include <linux/i2c.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
@@ -23,7 +24,6 @@
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
25#include <sound/soc.h> 26#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/tlv.h> 28#include <sound/tlv.h>
29 29
@@ -156,8 +156,8 @@ static struct {
156}; 156};
157 157
158struct wm9081_priv { 158struct wm9081_priv {
159 struct snd_soc_codec codec; 159 enum snd_soc_control_type control_type;
160 u16 reg_cache[WM9081_MAX_REGISTER + 1]; 160 void *control_data;
161 int sysclk_source; 161 int sysclk_source;
162 int mclk_rate; 162 int mclk_rate;
163 int sysclk_rate; 163 int sysclk_rate;
@@ -167,10 +167,10 @@ struct wm9081_priv {
167 int fll_fref; 167 int fll_fref;
168 int fll_fout; 168 int fll_fout;
169 int tdm_width; 169 int tdm_width;
170 struct wm9081_retune_mobile_config *retune; 170 struct wm9081_pdata pdata;
171}; 171};
172 172
173static int wm9081_volatile_register(unsigned int reg) 173static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
174{ 174{
175 switch (reg) { 175 switch (reg) {
176 case WM9081_SOFTWARE_RESET: 176 case WM9081_SOFTWARE_RESET:
@@ -305,7 +305,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol,
305/* 305/*
306 * Stop any attempts to change speaker mode while the speaker is enabled. 306 * Stop any attempts to change speaker mode while the speaker is enabled.
307 * 307 *
308 * We also have some special anti-pop controls dependant on speaker 308 * We also have some special anti-pop controls dependent on speaker
309 * mode which must be changed along with the mode. 309 * mode which must be changed along with the mode.
310 */ 310 */
311static int speaker_mode_put(struct snd_kcontrol *kcontrol, 311static int speaker_mode_put(struct snd_kcontrol *kcontrol,
@@ -389,27 +389,6 @@ SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), 389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
390}; 390};
391 391
392static int speaker_event(struct snd_soc_dapm_widget *w,
393 struct snd_kcontrol *kcontrol, int event)
394{
395 struct snd_soc_codec *codec = w->codec;
396 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
397
398 switch (event) {
399 case SND_SOC_DAPM_POST_PMU:
400 reg |= WM9081_SPK_ENA;
401 break;
402
403 case SND_SOC_DAPM_PRE_PMD:
404 reg &= ~WM9081_SPK_ENA;
405 break;
406 }
407
408 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
409
410 return 0;
411}
412
413struct _fll_div { 392struct _fll_div {
414 u16 fll_fratio; 393 u16 fll_fratio;
415 u16 fll_outdiv; 394 u16 fll_outdiv;
@@ -477,7 +456,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
477 456
478 pr_debug("Fvco=%dHz\n", target); 457 pr_debug("Fvco=%dHz\n", target);
479 458
480 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 459 /* Find an appropriate FLL_FRATIO and factor it out of the target */
481 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 460 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
482 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 461 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
483 fll_div->fll_fratio = fll_fratios[i].fll_fratio; 462 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
@@ -590,6 +569,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
590 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; 569 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
591 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5); 570 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
592 571
572 /* Set gain to the recommended value */
573 snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
574 WM9081_FLL_GAIN_MASK, 0);
575
593 /* Enable the FLL */ 576 /* Enable the FLL */
594 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); 577 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
595 578
@@ -743,9 +726,8 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
743 726
744SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), 727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
745 728
746SND_SOC_DAPM_PGA_E("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0, 729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
747 speaker_event, 730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
748 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
749 731
750SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
751SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -758,7 +740,7 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
758}; 740};
759 741
760 742
761static const struct snd_soc_dapm_route audio_paths[] = { 743static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
762 { "DAC", NULL, "CLK_SYS" }, 744 { "DAC", NULL, "CLK_SYS" },
763 { "DAC", NULL, "CLK_DSP" }, 745 { "DAC", NULL, "CLK_DSP" },
764 746
@@ -776,8 +758,10 @@ static const struct snd_soc_dapm_route audio_paths[] = {
776 { "Speaker PGA", NULL, "TOCLK" }, 758 { "Speaker PGA", NULL, "TOCLK" },
777 { "Speaker PGA", NULL, "CLK_SYS" }, 759 { "Speaker PGA", NULL, "CLK_SYS" },
778 760
779 { "SPKN", NULL, "Speaker PGA" }, 761 { "Speaker", NULL, "Speaker PGA" },
780 { "SPKP", NULL, "Speaker PGA" }, 762
763 { "SPKN", NULL, "Speaker" },
764 { "SPKP", NULL, "Speaker" },
781}; 765};
782 766
783static int wm9081_set_bias_level(struct snd_soc_codec *codec, 767static int wm9081_set_bias_level(struct snd_soc_codec *codec,
@@ -804,7 +788,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
804 788
805 case SND_SOC_BIAS_STANDBY: 789 case SND_SOC_BIAS_STANDBY:
806 /* Initial cold start */ 790 /* Initial cold start */
807 if (codec->bias_level == SND_SOC_BIAS_OFF) { 791 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
808 /* Disable LINEOUT discharge */ 792 /* Disable LINEOUT discharge */
809 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); 793 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
810 reg &= ~WM9081_LINEOUT_DISCH; 794 reg &= ~WM9081_LINEOUT_DISCH;
@@ -864,7 +848,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
864 break; 848 break;
865 } 849 }
866 850
867 codec->bias_level = level; 851 codec->dapm.bias_level = level;
868 852
869 return 0; 853 return 0;
870} 854}
@@ -1078,21 +1062,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1078 aif4 |= wm9081->bclk / wm9081->fs; 1062 aif4 |= wm9081->bclk / wm9081->fs;
1079 1063
1080 /* Apply a ReTune Mobile configuration if it's in use */ 1064 /* Apply a ReTune Mobile configuration if it's in use */
1081 if (wm9081->retune) { 1065 if (wm9081->pdata.num_retune_configs) {
1082 struct wm9081_retune_mobile_config *retune = wm9081->retune; 1066 struct wm9081_pdata *pdata = &wm9081->pdata;
1083 struct wm9081_retune_mobile_setting *s; 1067 struct wm9081_retune_mobile_setting *s;
1084 int eq1; 1068 int eq1;
1085 1069
1086 best = 0; 1070 best = 0;
1087 best_val = abs(retune->configs[0].rate - wm9081->fs); 1071 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
1088 for (i = 0; i < retune->num_configs; i++) { 1072 for (i = 0; i < pdata->num_retune_configs; i++) {
1089 cur_val = abs(retune->configs[i].rate - wm9081->fs); 1073 cur_val = abs(pdata->retune_configs[i].rate -
1074 wm9081->fs);
1090 if (cur_val < best_val) { 1075 if (cur_val < best_val) {
1091 best_val = cur_val; 1076 best_val = cur_val;
1092 best = i; 1077 best = i;
1093 } 1078 }
1094 } 1079 }
1095 s = &retune->configs[best]; 1080 s = &pdata->retune_configs[best];
1096 1081
1097 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", 1082 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1098 s->name, s->rate); 1083 s->name, s->rate);
@@ -1135,10 +1120,9 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1135 return 0; 1120 return 0;
1136} 1121}
1137 1122
1138static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec,
1139 int clk_id, unsigned int freq, int dir) 1124 int clk_id, unsigned int freq, int dir)
1140{ 1125{
1141 struct snd_soc_codec *codec = codec_dai->codec;
1142 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1143 1127
1144 switch (clk_id) { 1128 switch (clk_id) {
@@ -1203,7 +1187,6 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1203 1187
1204static struct snd_soc_dai_ops wm9081_dai_ops = { 1188static struct snd_soc_dai_ops wm9081_dai_ops = {
1205 .hw_params = wm9081_hw_params, 1189 .hw_params = wm9081_hw_params,
1206 .set_sysclk = wm9081_set_sysclk,
1207 .set_fmt = wm9081_set_dai_fmt, 1190 .set_fmt = wm9081_set_dai_fmt,
1208 .digital_mute = wm9081_digital_mute, 1191 .digital_mute = wm9081_digital_mute,
1209 .set_tdm_slot = wm9081_set_tdm_slot, 1192 .set_tdm_slot = wm9081_set_tdm_slot,
@@ -1212,8 +1195,8 @@ static struct snd_soc_dai_ops wm9081_dai_ops = {
1212/* We report two channels because the CODEC processes a stereo signal, even 1195/* We report two channels because the CODEC processes a stereo signal, even
1213 * though it is only capable of handling a mono output. 1196 * though it is only capable of handling a mono output.
1214 */ 1197 */
1215struct snd_soc_dai wm9081_dai = { 1198static struct snd_soc_dai_driver wm9081_dai = {
1216 .name = "WM9081", 1199 .name = "wm9081-hifi",
1217 .playback = { 1200 .playback = {
1218 .stream_name = "HiFi Playback", 1201 .stream_name = "HiFi Playback",
1219 .channels_min = 1, 1202 .channels_min = 1,
@@ -1223,82 +1206,82 @@ struct snd_soc_dai wm9081_dai = {
1223 }, 1206 },
1224 .ops = &wm9081_dai_ops, 1207 .ops = &wm9081_dai_ops,
1225}; 1208};
1226EXPORT_SYMBOL_GPL(wm9081_dai);
1227 1209
1228 1210static int wm9081_probe(struct snd_soc_codec *codec)
1229static struct snd_soc_codec *wm9081_codec;
1230
1231static int wm9081_probe(struct platform_device *pdev)
1232{ 1211{
1233 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1212 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1234 struct snd_soc_codec *codec; 1213 int ret;
1235 struct wm9081_priv *wm9081; 1214 u16 reg;
1236 int ret = 0;
1237 1215
1238 if (wm9081_codec == NULL) { 1216 codec->control_data = wm9081->control_data;
1239 dev_err(&pdev->dev, "Codec device not registered\n"); 1217 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
1240 return -ENODEV; 1218 if (ret != 0) {
1219 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1220 return ret;
1241 } 1221 }
1242 1222
1243 socdev->card->codec = wm9081_codec; 1223 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1244 codec = wm9081_codec; 1224 if (reg != 0x9081) {
1245 wm9081 = snd_soc_codec_get_drvdata(codec); 1225 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1226 ret = -EINVAL;
1227 return ret;
1228 }
1246 1229
1247 /* register pcms */ 1230 ret = wm9081_reset(codec);
1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1249 if (ret < 0) { 1231 if (ret < 0) {
1250 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 1232 dev_err(codec->dev, "Failed to issue reset\n");
1251 goto pcm_err; 1233 return ret;
1252 } 1234 }
1253 1235
1236 reg = 0;
1237 if (wm9081->pdata.irq_high)
1238 reg |= WM9081_IRQ_POL;
1239 if (!wm9081->pdata.irq_cmos)
1240 reg |= WM9081_IRQ_OP_CTRL;
1241 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1242 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1243
1244 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1245
1246 /* Enable zero cross by default */
1247 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1248 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1249 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1250 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1251 reg | WM9081_SPKPGAZC);
1252
1254 snd_soc_add_controls(codec, wm9081_snd_controls, 1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1255 ARRAY_SIZE(wm9081_snd_controls)); 1254 ARRAY_SIZE(wm9081_snd_controls));
1256 if (!wm9081->retune) { 1255 if (!wm9081->pdata.num_retune_configs) {
1257 dev_dbg(codec->dev, 1256 dev_dbg(codec->dev,
1258 "No ReTune Mobile data, using normal EQ\n"); 1257 "No ReTune Mobile data, using normal EQ\n");
1259 snd_soc_add_controls(codec, wm9081_eq_controls, 1258 snd_soc_add_controls(codec, wm9081_eq_controls,
1260 ARRAY_SIZE(wm9081_eq_controls)); 1259 ARRAY_SIZE(wm9081_eq_controls));
1261 } 1260 }
1262 1261
1263 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
1264 ARRAY_SIZE(wm9081_dapm_widgets));
1265 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1266
1267 return ret;
1268
1269pcm_err:
1270 return ret; 1262 return ret;
1271} 1263}
1272 1264
1273static int wm9081_remove(struct platform_device *pdev) 1265static int wm9081_remove(struct snd_soc_codec *codec)
1274{ 1266{
1275 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1267 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1276
1277 snd_soc_free_pcms(socdev);
1278 snd_soc_dapm_free(socdev);
1279
1280 return 0; 1268 return 0;
1281} 1269}
1282 1270
1283#ifdef CONFIG_PM 1271#ifdef CONFIG_PM
1284static int wm9081_suspend(struct platform_device *pdev, pm_message_t state) 1272static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state)
1285{ 1273{
1286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1287 struct snd_soc_codec *codec = socdev->card->codec;
1288
1289 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); 1274 wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
1290 1275
1291 return 0; 1276 return 0;
1292} 1277}
1293 1278
1294static int wm9081_resume(struct platform_device *pdev) 1279static int wm9081_resume(struct snd_soc_codec *codec)
1295{ 1280{
1296 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1297 struct snd_soc_codec *codec = socdev->card->codec;
1298 u16 *reg_cache = codec->reg_cache; 1281 u16 *reg_cache = codec->reg_cache;
1299 int i; 1282 int i;
1300 1283
1301 for (i = 0; i < codec->reg_cache_size; i++) { 1284 for (i = 0; i < codec->driver->reg_cache_size; i++) {
1302 if (i == WM9081_SOFTWARE_RESET) 1285 if (i == WM9081_SOFTWARE_RESET)
1303 continue; 1286 continue;
1304 1287
@@ -1314,133 +1297,56 @@ static int wm9081_resume(struct platform_device *pdev)
1314#define wm9081_resume NULL 1297#define wm9081_resume NULL
1315#endif 1298#endif
1316 1299
1317struct snd_soc_codec_device soc_codec_dev_wm9081 = { 1300static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1318 .probe = wm9081_probe, 1301 .probe = wm9081_probe,
1319 .remove = wm9081_remove, 1302 .remove = wm9081_remove,
1320 .suspend = wm9081_suspend, 1303 .suspend = wm9081_suspend,
1321 .resume = wm9081_resume, 1304 .resume = wm9081_resume,
1322};
1323EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081);
1324 1305
1325static int wm9081_register(struct wm9081_priv *wm9081, 1306 .set_sysclk = wm9081_set_sysclk,
1326 enum snd_soc_control_type control) 1307 .set_bias_level = wm9081_set_bias_level,
1327{
1328 struct snd_soc_codec *codec = &wm9081->codec;
1329 int ret;
1330 u16 reg;
1331
1332 if (wm9081_codec) {
1333 dev_err(codec->dev, "Another WM9081 is registered\n");
1334 ret = -EINVAL;
1335 goto err;
1336 }
1337
1338 mutex_init(&codec->mutex);
1339 INIT_LIST_HEAD(&codec->dapm_widgets);
1340 INIT_LIST_HEAD(&codec->dapm_paths);
1341
1342 snd_soc_codec_set_drvdata(codec, wm9081);
1343 codec->name = "WM9081";
1344 codec->owner = THIS_MODULE;
1345 codec->dai = &wm9081_dai;
1346 codec->num_dai = 1;
1347 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache);
1348 codec->reg_cache = &wm9081->reg_cache;
1349 codec->bias_level = SND_SOC_BIAS_OFF;
1350 codec->set_bias_level = wm9081_set_bias_level;
1351 codec->volatile_register = wm9081_volatile_register;
1352
1353 memcpy(codec->reg_cache, wm9081_reg_defaults,
1354 sizeof(wm9081_reg_defaults));
1355
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1357 if (ret != 0) {
1358 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1359 goto err;
1360 }
1361
1362 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1363 if (reg != 0x9081) {
1364 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1365 ret = -EINVAL;
1366 goto err;
1367 }
1368
1369 ret = wm9081_reset(codec);
1370 if (ret < 0) {
1371 dev_err(codec->dev, "Failed to issue reset\n");
1372 goto err;
1373 }
1374
1375 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1376
1377 /* Enable zero cross by default */
1378 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1379 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1380 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1381 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1382 reg | WM9081_SPKPGAZC);
1383
1384 wm9081_dai.dev = codec->dev;
1385
1386 wm9081_codec = codec;
1387
1388 ret = snd_soc_register_codec(codec);
1389 if (ret != 0) {
1390 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1391 goto err;
1392 }
1393
1394 ret = snd_soc_register_dai(&wm9081_dai);
1395 if (ret != 0) {
1396 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1397 goto err_codec;
1398 }
1399
1400 return 0;
1401 1308
1402err_codec: 1309 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
1403 snd_soc_unregister_codec(codec); 1310 .reg_word_size = sizeof(u16),
1404err: 1311 .reg_cache_default = wm9081_reg_defaults,
1405 kfree(wm9081); 1312 .volatile_register = wm9081_volatile_register,
1406 return ret;
1407}
1408 1313
1409static void wm9081_unregister(struct wm9081_priv *wm9081) 1314 .dapm_widgets = wm9081_dapm_widgets,
1410{ 1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1411 wm9081_set_bias_level(&wm9081->codec, SND_SOC_BIAS_OFF); 1316 .dapm_routes = wm9081_audio_paths,
1412 snd_soc_unregister_dai(&wm9081_dai); 1317 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
1413 snd_soc_unregister_codec(&wm9081->codec); 1318};
1414 kfree(wm9081);
1415 wm9081_codec = NULL;
1416}
1417 1319
1320#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1418static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, 1321static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1419 const struct i2c_device_id *id) 1322 const struct i2c_device_id *id)
1420{ 1323{
1421 struct wm9081_priv *wm9081; 1324 struct wm9081_priv *wm9081;
1422 struct snd_soc_codec *codec; 1325 int ret;
1423 1326
1424 wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); 1327 wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL);
1425 if (wm9081 == NULL) 1328 if (wm9081 == NULL)
1426 return -ENOMEM; 1329 return -ENOMEM;
1427 1330
1428 codec = &wm9081->codec;
1429 codec->hw_write = (hw_write_t)i2c_master_send;
1430 wm9081->retune = i2c->dev.platform_data;
1431
1432 i2c_set_clientdata(i2c, wm9081); 1331 i2c_set_clientdata(i2c, wm9081);
1433 codec->control_data = i2c; 1332 wm9081->control_type = SND_SOC_I2C;
1333 wm9081->control_data = i2c;
1434 1334
1435 codec->dev = &i2c->dev; 1335 if (dev_get_platdata(&i2c->dev))
1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1337 sizeof(wm9081->pdata));
1436 1338
1437 return wm9081_register(wm9081, SND_SOC_I2C); 1339 ret = snd_soc_register_codec(&i2c->dev,
1340 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1341 if (ret < 0)
1342 kfree(wm9081);
1343 return ret;
1438} 1344}
1439 1345
1440static __devexit int wm9081_i2c_remove(struct i2c_client *client) 1346static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1441{ 1347{
1442 struct wm9081_priv *wm9081 = i2c_get_clientdata(client); 1348 snd_soc_unregister_codec(&client->dev);
1443 wm9081_unregister(wm9081); 1349 kfree(i2c_get_clientdata(client));
1444 return 0; 1350 return 0;
1445} 1351}
1446 1352
@@ -1459,24 +1365,27 @@ static struct i2c_driver wm9081_i2c_driver = {
1459 .remove = __devexit_p(wm9081_i2c_remove), 1365 .remove = __devexit_p(wm9081_i2c_remove),
1460 .id_table = wm9081_i2c_id, 1366 .id_table = wm9081_i2c_id,
1461}; 1367};
1368#endif
1462 1369
1463static int __init wm9081_modinit(void) 1370static int __init wm9081_modinit(void)
1464{ 1371{
1465 int ret; 1372 int ret = 0;
1466 1373#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1467 ret = i2c_add_driver(&wm9081_i2c_driver); 1374 ret = i2c_add_driver(&wm9081_i2c_driver);
1468 if (ret != 0) { 1375 if (ret != 0) {
1469 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", 1376 printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
1470 ret); 1377 ret);
1471 } 1378 }
1472 1379#endif
1473 return ret; 1380 return ret;
1474} 1381}
1475module_init(wm9081_modinit); 1382module_init(wm9081_modinit);
1476 1383
1477static void __exit wm9081_exit(void) 1384static void __exit wm9081_exit(void)
1478{ 1385{
1386#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1479 i2c_del_driver(&wm9081_i2c_driver); 1387 i2c_del_driver(&wm9081_i2c_driver);
1388#endif
1480} 1389}
1481module_exit(wm9081_exit); 1390module_exit(wm9081_exit);
1482 1391
diff --git a/sound/soc/codecs/wm9081.h b/sound/soc/codecs/wm9081.h
index 42d3bc757021..871cccb066dc 100644
--- a/sound/soc/codecs/wm9081.h
+++ b/sound/soc/codecs/wm9081.h
@@ -15,9 +15,6 @@
15 15
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18extern struct snd_soc_dai wm9081_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm9081;
20
21/* 18/*
22 * SYSCLK sources 19 * SYSCLK sources
23 */ 20 */
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 1592250daec0..4de12203e611 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -28,14 +28,11 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <sound/initval.h> 29#include <sound/initval.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h> 31#include <sound/tlv.h>
33#include <sound/wm9090.h> 32#include <sound/wm9090.h>
34 33
35#include "wm9090.h" 34#include "wm9090.h"
36 35
37static struct snd_soc_codec *wm9090_codec;
38
39static const u16 wm9090_reg_defaults[] = { 36static const u16 wm9090_reg_defaults[] = {
40 0x9093, /* R0 - Software Reset */ 37 0x9093, /* R0 - Software Reset */
41 0x0006, /* R1 - Power Management (1) */ 38 0x0006, /* R1 - Power Management (1) */
@@ -142,18 +139,12 @@ static const u16 wm9090_reg_defaults[] = {
142 139
143/* This struct is used to save the context */ 140/* This struct is used to save the context */
144struct wm9090_priv { 141struct wm9090_priv {
145 /* We're not really registering as a CODEC since ASoC core
146 * does not yet support multiple CODECs but having the CODEC
147 * structure means we can reuse some of the ASoC core
148 * features.
149 */
150 struct snd_soc_codec codec;
151 struct mutex mutex; 142 struct mutex mutex;
152 u16 reg_cache[WM9090_MAX_REGISTER + 1];
153 struct wm9090_platform_data pdata; 143 struct wm9090_platform_data pdata;
144 void *control_data;
154}; 145};
155 146
156static int wm9090_volatile(unsigned int reg) 147static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
157{ 148{
158 switch (reg) { 149 switch (reg) {
159 case WM9090_SOFTWARE_RESET: 150 case WM9090_SOFTWARE_RESET:
@@ -450,31 +441,32 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
450static int wm9090_add_controls(struct snd_soc_codec *codec) 441static int wm9090_add_controls(struct snd_soc_codec *codec)
451{ 442{
452 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); 443 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
444 struct snd_soc_dapm_context *dapm = &codec->dapm;
453 int i; 445 int i;
454 446
455 snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets, 447 snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
456 ARRAY_SIZE(wm9090_dapm_widgets)); 448 ARRAY_SIZE(wm9090_dapm_widgets));
457 449
458 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 450 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
459 451
460 snd_soc_add_controls(codec, wm9090_controls, 452 snd_soc_add_controls(codec, wm9090_controls,
461 ARRAY_SIZE(wm9090_controls)); 453 ARRAY_SIZE(wm9090_controls));
462 454
463 if (wm9090->pdata.lin1_diff) { 455 if (wm9090->pdata.lin1_diff) {
464 snd_soc_dapm_add_routes(codec, audio_map_in1_diff, 456 snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
465 ARRAY_SIZE(audio_map_in1_diff)); 457 ARRAY_SIZE(audio_map_in1_diff));
466 } else { 458 } else {
467 snd_soc_dapm_add_routes(codec, audio_map_in1_se, 459 snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
468 ARRAY_SIZE(audio_map_in1_se)); 460 ARRAY_SIZE(audio_map_in1_se));
469 snd_soc_add_controls(codec, wm9090_in1_se_controls, 461 snd_soc_add_controls(codec, wm9090_in1_se_controls,
470 ARRAY_SIZE(wm9090_in1_se_controls)); 462 ARRAY_SIZE(wm9090_in1_se_controls));
471 } 463 }
472 464
473 if (wm9090->pdata.lin2_diff) { 465 if (wm9090->pdata.lin2_diff) {
474 snd_soc_dapm_add_routes(codec, audio_map_in2_diff, 466 snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
475 ARRAY_SIZE(audio_map_in2_diff)); 467 ARRAY_SIZE(audio_map_in2_diff));
476 } else { 468 } else {
477 snd_soc_dapm_add_routes(codec, audio_map_in2_se, 469 snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
478 ARRAY_SIZE(audio_map_in2_se)); 470 ARRAY_SIZE(audio_map_in2_se));
479 snd_soc_add_controls(codec, wm9090_in2_se_controls, 471 snd_soc_add_controls(codec, wm9090_in2_se_controls,
480 ARRAY_SIZE(wm9090_in2_se_controls)); 472 ARRAY_SIZE(wm9090_in2_se_controls));
@@ -521,12 +513,12 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
521 break; 513 break;
522 514
523 case SND_SOC_BIAS_STANDBY: 515 case SND_SOC_BIAS_STANDBY:
524 if (codec->bias_level == SND_SOC_BIAS_OFF) { 516 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
525 /* Restore the register cache */ 517 /* Restore the register cache */
526 for (i = 1; i < codec->reg_cache_size; i++) { 518 for (i = 1; i < codec->driver->reg_cache_size; i++) {
527 if (reg_cache[i] == wm9090_reg_defaults[i]) 519 if (reg_cache[i] == wm9090_reg_defaults[i])
528 continue; 520 continue;
529 if (wm9090_volatile(i)) 521 if (wm9090_volatile(codec, i))
530 continue; 522 continue;
531 523
532 ret = snd_soc_write(codec, i, reg_cache[i]); 524 ret = snd_soc_write(codec, i, reg_cache[i]);
@@ -551,56 +543,80 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
551 break; 543 break;
552 } 544 }
553 545
554 codec->bias_level = level; 546 codec->dapm.bias_level = level;
555 547
556 return 0; 548 return 0;
557} 549}
558 550
559static int wm9090_probe(struct platform_device *pdev) 551static int wm9090_probe(struct snd_soc_codec *codec)
560{ 552{
561 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 553 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
562 struct snd_soc_codec *codec; 554 int ret;
563 int ret = 0;
564 555
565 if (wm9090_codec == NULL) { 556 codec->control_data = wm9090->control_data;
566 dev_err(&pdev->dev, "Codec device not registered\n"); 557 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
567 return -ENODEV; 558 if (ret != 0) {
559 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
560 return ret;
568 } 561 }
569 562
570 socdev->card->codec = wm9090_codec; 563 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
571 codec = wm9090_codec; 564 if (ret < 0)
572 565 return ret;
573 /* register pcms */ 566 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
574 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 567 dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret);
575 if (ret < 0) { 568 return -EINVAL;
576 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
577 goto pcm_err;
578 } 569 }
579 570
571 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
572 if (ret < 0)
573 return ret;
574
575 /* Configure some defaults; they will be written out when we
576 * bring the bias up.
577 */
578 snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_A_VOLUME,
579 WM9090_IN1_VU | WM9090_IN1A_ZC,
580 WM9090_IN1_VU | WM9090_IN1A_ZC);
581 snd_soc_update_bits(codec, WM9090_IN1_LINE_INPUT_B_VOLUME,
582 WM9090_IN1_VU | WM9090_IN1B_ZC,
583 WM9090_IN1_VU | WM9090_IN1B_ZC);
584 snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_A_VOLUME,
585 WM9090_IN2_VU | WM9090_IN2A_ZC,
586 WM9090_IN2_VU | WM9090_IN2A_ZC);
587 snd_soc_update_bits(codec, WM9090_IN2_LINE_INPUT_B_VOLUME,
588 WM9090_IN2_VU | WM9090_IN2B_ZC,
589 WM9090_IN2_VU | WM9090_IN2B_ZC);
590 snd_soc_update_bits(codec, WM9090_SPEAKER_VOLUME_LEFT,
591 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
592 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
593 snd_soc_update_bits(codec, WM9090_LEFT_OUTPUT_VOLUME,
594 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
595 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
596 snd_soc_update_bits(codec, WM9090_RIGHT_OUTPUT_VOLUME,
597 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
598 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
599
600 snd_soc_update_bits(codec, WM9090_CLOCKING_1,
601 WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
602
603 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
604
580 wm9090_add_controls(codec); 605 wm9090_add_controls(codec);
581 606
582 return 0; 607 return 0;
583
584pcm_err:
585 return ret;
586} 608}
587 609
588#ifdef CONFIG_PM 610#ifdef CONFIG_PM
589static int wm9090_suspend(struct platform_device *pdev, pm_message_t state) 611static int wm9090_suspend(struct snd_soc_codec *codec, pm_message_t state)
590{ 612{
591 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
592 struct snd_soc_codec *codec = socdev->card->codec;
593
594 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF); 613 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
595 614
596 return 0; 615 return 0;
597} 616}
598 617
599static int wm9090_resume(struct platform_device *pdev) 618static int wm9090_resume(struct snd_soc_codec *codec)
600{ 619{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = socdev->card->codec;
603
604 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 620 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
605 621
606 return 0; 622 return 0;
@@ -610,29 +626,29 @@ static int wm9090_resume(struct platform_device *pdev)
610#define wm9090_resume NULL 626#define wm9090_resume NULL
611#endif 627#endif
612 628
613static int wm9090_remove(struct platform_device *pdev) 629static int wm9090_remove(struct snd_soc_codec *codec)
614{ 630{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 631 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
616
617 snd_soc_free_pcms(socdev);
618 snd_soc_dapm_free(socdev);
619 632
620 return 0; 633 return 0;
621} 634}
622 635
623struct snd_soc_codec_device soc_codec_dev_wm9090 = { 636static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
624 .probe = wm9090_probe, 637 .probe = wm9090_probe,
625 .remove = wm9090_remove, 638 .remove = wm9090_remove,
626 .suspend = wm9090_suspend, 639 .suspend = wm9090_suspend,
627 .resume = wm9090_resume, 640 .resume = wm9090_resume,
641 .set_bias_level = wm9090_set_bias_level,
642 .reg_cache_size = (WM9090_MAX_REGISTER + 1),
643 .reg_word_size = sizeof(u16),
644 .reg_cache_default = wm9090_reg_defaults,
645 .volatile_register = wm9090_volatile,
628}; 646};
629EXPORT_SYMBOL_GPL(soc_codec_dev_wm9090);
630 647
631static int wm9090_i2c_probe(struct i2c_client *i2c, 648static int wm9090_i2c_probe(struct i2c_client *i2c,
632 const struct i2c_device_id *id) 649 const struct i2c_device_id *id)
633{ 650{
634 struct wm9090_priv *wm9090; 651 struct wm9090_priv *wm9090;
635 struct snd_soc_codec *codec;
636 int ret; 652 int ret;
637 653
638 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL); 654 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
@@ -640,102 +656,28 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
640 dev_err(&i2c->dev, "Can not allocate memory\n"); 656 dev_err(&i2c->dev, "Can not allocate memory\n");
641 return -ENOMEM; 657 return -ENOMEM;
642 } 658 }
643 codec = &wm9090->codec;
644 659
645 if (i2c->dev.platform_data) 660 if (i2c->dev.platform_data)
646 memcpy(&wm9090->pdata, i2c->dev.platform_data, 661 memcpy(&wm9090->pdata, i2c->dev.platform_data,
647 sizeof(wm9090->pdata)); 662 sizeof(wm9090->pdata));
648 663
649 wm9090_codec = codec;
650
651 i2c_set_clientdata(i2c, wm9090); 664 i2c_set_clientdata(i2c, wm9090);
665 wm9090->control_data = i2c;
666 mutex_init(&wm9090->mutex);
652 667
653 mutex_init(&codec->mutex); 668 ret = snd_soc_register_codec(&i2c->dev,
654 INIT_LIST_HEAD(&codec->dapm_widgets); 669 &soc_codec_dev_wm9090, NULL, 0);
655 INIT_LIST_HEAD(&codec->dapm_paths);
656
657 codec->control_data = i2c;
658 snd_soc_codec_set_drvdata(codec, wm9090);
659 codec->dev = &i2c->dev;
660 codec->name = "WM9090";
661 codec->owner = THIS_MODULE;
662 codec->bias_level = SND_SOC_BIAS_OFF;
663 codec->set_bias_level = wm9090_set_bias_level,
664 codec->reg_cache_size = WM9090_MAX_REGISTER + 1;
665 codec->reg_cache = &wm9090->reg_cache;
666 codec->volatile_register = wm9090_volatile;
667
668 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
669 if (ret != 0) {
670 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
671 goto err;
672 }
673
674 memcpy(&wm9090->reg_cache, wm9090_reg_defaults,
675 sizeof(wm9090->reg_cache));
676
677 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
678 if (ret < 0) 670 if (ret < 0)
679 goto err; 671 kfree(wm9090);
680 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
681 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret);
682 ret = -EINVAL;
683 goto err;
684 }
685
686 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
687 if (ret < 0)
688 goto err;
689
690 /* Configure some defaults; they will be written out when we
691 * bring the bias up.
692 */
693 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
694 | WM9090_IN1A_ZC;
695 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
696 | WM9090_IN1B_ZC;
697 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
698 | WM9090_IN2A_ZC;
699 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
700 | WM9090_IN2B_ZC;
701 wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
702 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
703 wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
704 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
705 wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
706 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
707
708 wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
709
710 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
711
712 ret = snd_soc_register_codec(codec);
713 if (ret != 0) {
714 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
715 goto err_bias;
716 }
717
718 return 0;
719
720err_bias:
721 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
722err:
723 kfree(wm9090);
724 i2c_set_clientdata(i2c, NULL);
725 wm9090_codec = NULL;
726
727 return ret; 672 return ret;
728} 673}
729 674
730static int wm9090_i2c_remove(struct i2c_client *i2c) 675static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
731{ 676{
732 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); 677 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
733 struct snd_soc_codec *codec = &wm9090->codec;
734 678
735 snd_soc_unregister_codec(codec); 679 snd_soc_unregister_codec(&i2c->dev);
736 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
737 kfree(wm9090); 680 kfree(wm9090);
738 wm9090_codec = NULL;
739 681
740 return 0; 682 return 0;
741} 683}
@@ -748,7 +690,7 @@ MODULE_DEVICE_TABLE(i2c, wm9090_id);
748 690
749static struct i2c_driver wm9090_i2c_driver = { 691static struct i2c_driver wm9090_i2c_driver = {
750 .driver = { 692 .driver = {
751 .name = "wm9090", 693 .name = "wm9090-codec",
752 .owner = THIS_MODULE, 694 .owner = THIS_MODULE,
753 }, 695 },
754 .probe = wm9090_i2c_probe, 696 .probe = wm9090_i2c_probe,
diff --git a/sound/soc/codecs/wm9090.h b/sound/soc/codecs/wm9090.h
index b08eab932a5b..29b9d9fc70b4 100644
--- a/sound/soc/codecs/wm9090.h
+++ b/sound/soc/codecs/wm9090.h
@@ -23,8 +23,6 @@
23#ifndef __WM9090_H 23#ifndef __WM9090_H
24#define __WM9090_H 24#define __WM9090_H
25 25
26extern struct snd_soc_codec_device soc_codec_dev_wm9090;
27
28/* 26/*
29 * Register values. 27 * Register values.
30 */ 28 */
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 8793341849d1..646b58dda849 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -19,7 +19,6 @@
19#include <sound/ac97_codec.h> 19#include <sound/ac97_codec.h>
20#include <sound/initval.h> 20#include <sound/initval.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23 22
24#include "wm9705.h" 23#include "wm9705.h"
25 24
@@ -143,7 +142,7 @@ static const struct snd_soc_dapm_widget wm9705_dapm_widgets[] = {
143 * constantly enabled, we use the mutes on those inputs to simulate such 142 * constantly enabled, we use the mutes on those inputs to simulate such
144 * controls. 143 * controls.
145 */ 144 */
146static const struct snd_soc_dapm_route audio_map[] = { 145static const struct snd_soc_dapm_route wm9705_audio_map[] = {
147 /* HP mixer */ 146 /* HP mixer */
148 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"}, 147 {"HP Mixer", "PCBeep Playback Switch", "PCBEEP PGA"},
149 {"HP Mixer", "CD Playback Switch", "CD PGA"}, 148 {"HP Mixer", "CD Playback Switch", "CD PGA"},
@@ -201,15 +200,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
201 {"Right ADC", NULL, "ADC PGA"}, 200 {"Right ADC", NULL, "ADC PGA"},
202}; 201};
203 202
204static int wm9705_add_widgets(struct snd_soc_codec *codec)
205{
206 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
207 ARRAY_SIZE(wm9705_dapm_widgets));
208 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
209
210 return 0;
211}
212
213/* We use a register cache to enhance read performance. */ 203/* We use a register cache to enhance read performance. */
214static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) 204static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)
215{ 205{
@@ -248,8 +238,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
248{ 238{
249 struct snd_pcm_runtime *runtime = substream->runtime; 239 struct snd_pcm_runtime *runtime = substream->runtime;
250 struct snd_soc_pcm_runtime *rtd = substream->private_data; 240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
251 struct snd_soc_device *socdev = rtd->socdev; 241 struct snd_soc_codec *codec = rtd->codec;
252 struct snd_soc_codec *codec = socdev->card->codec;
253 int reg; 242 int reg;
254 u16 vra; 243 u16 vra;
255 244
@@ -273,9 +262,9 @@ static struct snd_soc_dai_ops wm9705_dai_ops = {
273 .prepare = ac97_prepare, 262 .prepare = ac97_prepare,
274}; 263};
275 264
276struct snd_soc_dai wm9705_dai[] = { 265static struct snd_soc_dai_driver wm9705_dai[] = {
277 { 266 {
278 .name = "AC97 HiFi", 267 .name = "wm9705-hifi",
279 .ac97_control = 1, 268 .ac97_control = 1,
280 .playback = { 269 .playback = {
281 .stream_name = "HiFi Playback", 270 .stream_name = "HiFi Playback",
@@ -294,7 +283,7 @@ struct snd_soc_dai wm9705_dai[] = {
294 .ops = &wm9705_dai_ops, 283 .ops = &wm9705_dai_ops,
295 }, 284 },
296 { 285 {
297 .name = "AC97 Aux", 286 .name = "wm9705-aux",
298 .playback = { 287 .playback = {
299 .stream_name = "Aux Playback", 288 .stream_name = "Aux Playback",
300 .channels_min = 1, 289 .channels_min = 1,
@@ -304,7 +293,6 @@ struct snd_soc_dai wm9705_dai[] = {
304 }, 293 },
305 } 294 }
306}; 295};
307EXPORT_SYMBOL_GPL(wm9705_dai);
308 296
309static int wm9705_reset(struct snd_soc_codec *codec) 297static int wm9705_reset(struct snd_soc_codec *codec)
310{ 298{
@@ -318,20 +306,15 @@ static int wm9705_reset(struct snd_soc_codec *codec)
318} 306}
319 307
320#ifdef CONFIG_PM 308#ifdef CONFIG_PM
321static int wm9705_soc_suspend(struct platform_device *pdev, pm_message_t msg) 309static int wm9705_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
322{ 310{
323 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
324 struct snd_soc_codec *codec = socdev->card->codec;
325
326 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); 311 soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
327 312
328 return 0; 313 return 0;
329} 314}
330 315
331static int wm9705_soc_resume(struct platform_device *pdev) 316static int wm9705_soc_resume(struct snd_soc_codec *codec)
332{ 317{
333 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
334 struct snd_soc_codec *codec = socdev->card->codec;
335 int i, ret; 318 int i, ret;
336 u16 *cache = codec->reg_cache; 319 u16 *cache = codec->reg_cache;
337 320
@@ -352,94 +335,88 @@ static int wm9705_soc_resume(struct platform_device *pdev)
352#define wm9705_soc_resume NULL 335#define wm9705_soc_resume NULL
353#endif 336#endif
354 337
355static int wm9705_soc_probe(struct platform_device *pdev) 338static int wm9705_soc_probe(struct snd_soc_codec *codec)
356{ 339{
357 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
358 struct snd_soc_codec *codec;
359 int ret = 0; 340 int ret = 0;
360 341
361 printk(KERN_INFO "WM9705 SoC Audio Codec\n"); 342 printk(KERN_INFO "WM9705 SoC Audio Codec\n");
362 343
363 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
364 GFP_KERNEL);
365 if (socdev->card->codec == NULL)
366 return -ENOMEM;
367 codec = socdev->card->codec;
368 mutex_init(&codec->mutex);
369
370 codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL);
371 if (codec->reg_cache == NULL) {
372 ret = -ENOMEM;
373 goto cache_err;
374 }
375 codec->reg_cache_size = sizeof(wm9705_reg);
376 codec->reg_cache_step = 2;
377
378 codec->name = "WM9705";
379 codec->owner = THIS_MODULE;
380 codec->dai = wm9705_dai;
381 codec->num_dai = ARRAY_SIZE(wm9705_dai);
382 codec->write = ac97_write;
383 codec->read = ac97_read;
384 INIT_LIST_HEAD(&codec->dapm_widgets);
385 INIT_LIST_HEAD(&codec->dapm_paths);
386
387 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 344 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
388 if (ret < 0) { 345 if (ret < 0) {
389 printk(KERN_ERR "wm9705: failed to register AC97 codec\n"); 346 printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
390 goto codec_err; 347 return ret;
391 } 348 }
392 349
393 /* register pcms */
394 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
395 if (ret < 0)
396 goto pcm_err;
397
398 ret = wm9705_reset(codec); 350 ret = wm9705_reset(codec);
399 if (ret) 351 if (ret)
400 goto reset_err; 352 goto reset_err;
401 353
402 snd_soc_add_controls(codec, wm9705_snd_ac97_controls, 354 snd_soc_add_controls(codec, wm9705_snd_ac97_controls,
403 ARRAY_SIZE(wm9705_snd_ac97_controls)); 355 ARRAY_SIZE(wm9705_snd_ac97_controls));
404 wm9705_add_widgets(codec);
405 356
406 return 0; 357 return 0;
407 358
408reset_err: 359reset_err:
409 snd_soc_free_pcms(socdev);
410pcm_err:
411 snd_soc_free_ac97_codec(codec); 360 snd_soc_free_ac97_codec(codec);
412codec_err:
413 kfree(codec->reg_cache);
414cache_err:
415 kfree(socdev->card->codec);
416 socdev->card->codec = NULL;
417 return ret; 361 return ret;
418} 362}
419 363
420static int wm9705_soc_remove(struct platform_device *pdev) 364static int wm9705_soc_remove(struct snd_soc_codec *codec)
421{ 365{
422 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
423 struct snd_soc_codec *codec = socdev->card->codec;
424
425 if (codec == NULL)
426 return 0;
427
428 snd_soc_dapm_free(socdev);
429 snd_soc_free_pcms(socdev);
430 snd_soc_free_ac97_codec(codec); 366 snd_soc_free_ac97_codec(codec);
431 kfree(codec->reg_cache);
432 kfree(codec);
433 return 0; 367 return 0;
434} 368}
435 369
436struct snd_soc_codec_device soc_codec_dev_wm9705 = { 370static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
437 .probe = wm9705_soc_probe, 371 .probe = wm9705_soc_probe,
438 .remove = wm9705_soc_remove, 372 .remove = wm9705_soc_remove,
439 .suspend = wm9705_soc_suspend, 373 .suspend = wm9705_soc_suspend,
440 .resume = wm9705_soc_resume, 374 .resume = wm9705_soc_resume,
375 .read = ac97_read,
376 .write = ac97_write,
377 .reg_cache_size = ARRAY_SIZE(wm9705_reg),
378 .reg_word_size = sizeof(u16),
379 .reg_cache_step = 2,
380 .reg_cache_default = wm9705_reg,
381 .dapm_widgets = wm9705_dapm_widgets,
382 .num_dapm_widgets = ARRAY_SIZE(wm9705_dapm_widgets),
383 .dapm_routes = wm9705_audio_map,
384 .num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
441}; 385};
442EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); 386
387static __devinit int wm9705_probe(struct platform_device *pdev)
388{
389 return snd_soc_register_codec(&pdev->dev,
390 &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
391}
392
393static int __devexit wm9705_remove(struct platform_device *pdev)
394{
395 snd_soc_unregister_codec(&pdev->dev);
396 return 0;
397}
398
399static struct platform_driver wm9705_codec_driver = {
400 .driver = {
401 .name = "wm9705-codec",
402 .owner = THIS_MODULE,
403 },
404
405 .probe = wm9705_probe,
406 .remove = __devexit_p(wm9705_remove),
407};
408
409static int __init wm9705_init(void)
410{
411 return platform_driver_register(&wm9705_codec_driver);
412}
413module_init(wm9705_init);
414
415static void __exit wm9705_exit(void)
416{
417 platform_driver_unregister(&wm9705_codec_driver);
418}
419module_exit(wm9705_exit);
443 420
444MODULE_DESCRIPTION("ASoC WM9705 driver"); 421MODULE_DESCRIPTION("ASoC WM9705 driver");
445MODULE_AUTHOR("Ian Molton"); 422MODULE_AUTHOR("Ian Molton");
diff --git a/sound/soc/codecs/wm9705.h b/sound/soc/codecs/wm9705.h
index d380f110f9e2..23ea9ce47359 100644
--- a/sound/soc/codecs/wm9705.h
+++ b/sound/soc/codecs/wm9705.h
@@ -8,7 +8,4 @@
8#define WM9705_DAI_AC97_HIFI 0 8#define WM9705_DAI_AC97_HIFI 0
9#define WM9705_DAI_AC97_AUX 1 9#define WM9705_DAI_AC97_AUX 1
10 10
11extern struct snd_soc_dai wm9705_dai[2];
12extern struct snd_soc_codec_device soc_codec_dev_wm9705;
13
14#endif 11#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 28790a2ffe8d..90117f8156e8 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,7 +20,6 @@
20#include <sound/ac97_codec.h> 20#include <sound/ac97_codec.h>
21#include <sound/initval.h> 21#include <sound/initval.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include "wm9712.h" 23#include "wm9712.h"
25 24
26#define WM9712_VERSION "0.4" 25#define WM9712_VERSION "0.4"
@@ -333,7 +332,7 @@ SND_SOC_DAPM_INPUT("MIC1"),
333SND_SOC_DAPM_INPUT("MIC2"), 332SND_SOC_DAPM_INPUT("MIC2"),
334}; 333};
335 334
336static const struct snd_soc_dapm_route audio_map[] = { 335static const struct snd_soc_dapm_route wm9712_audio_map[] = {
337 /* virtual mixer - mixes left & right channels for spk and mono */ 336 /* virtual mixer - mixes left & right channels for spk and mono */
338 {"AC97 Mixer", NULL, "Left DAC"}, 337 {"AC97 Mixer", NULL, "Left DAC"},
339 {"AC97 Mixer", NULL, "Right DAC"}, 338 {"AC97 Mixer", NULL, "Right DAC"},
@@ -430,16 +429,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
430 {"ROUT2", NULL, "Speaker PGA"}, 429 {"ROUT2", NULL, "Speaker PGA"},
431}; 430};
432 431
433static int wm9712_add_widgets(struct snd_soc_codec *codec)
434{
435 snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets,
436 ARRAY_SIZE(wm9712_dapm_widgets));
437
438 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
439
440 return 0;
441}
442
443static unsigned int ac97_read(struct snd_soc_codec *codec, 432static unsigned int ac97_read(struct snd_soc_codec *codec,
444 unsigned int reg) 433 unsigned int reg)
445{ 434{
@@ -478,8 +467,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
478{ 467{
479 struct snd_pcm_runtime *runtime = substream->runtime; 468 struct snd_pcm_runtime *runtime = substream->runtime;
480 struct snd_soc_pcm_runtime *rtd = substream->private_data; 469 struct snd_soc_pcm_runtime *rtd = substream->private_data;
481 struct snd_soc_device *socdev = rtd->socdev; 470 struct snd_soc_codec *codec =rtd->codec;
482 struct snd_soc_codec *codec = socdev->card->codec;
483 int reg; 471 int reg;
484 u16 vra; 472 u16 vra;
485 473
@@ -499,8 +487,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
499{ 487{
500 struct snd_pcm_runtime *runtime = substream->runtime; 488 struct snd_pcm_runtime *runtime = substream->runtime;
501 struct snd_soc_pcm_runtime *rtd = substream->private_data; 489 struct snd_soc_pcm_runtime *rtd = substream->private_data;
502 struct snd_soc_device *socdev = rtd->socdev; 490 struct snd_soc_codec *codec = rtd->codec;
503 struct snd_soc_codec *codec = socdev->card->codec;
504 u16 vra, xsle; 491 u16 vra, xsle;
505 492
506 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 493 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -526,9 +513,9 @@ static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
526 .prepare = ac97_aux_prepare, 513 .prepare = ac97_aux_prepare,
527}; 514};
528 515
529struct snd_soc_dai wm9712_dai[] = { 516static struct snd_soc_dai_driver wm9712_dai[] = {
530{ 517{
531 .name = "AC97 HiFi", 518 .name = "wm9712-hifi",
532 .ac97_control = 1, 519 .ac97_control = 1,
533 .playback = { 520 .playback = {
534 .stream_name = "HiFi Playback", 521 .stream_name = "HiFi Playback",
@@ -545,7 +532,7 @@ struct snd_soc_dai wm9712_dai[] = {
545 .ops = &wm9712_dai_ops_hifi, 532 .ops = &wm9712_dai_ops_hifi,
546}, 533},
547{ 534{
548 .name = "AC97 Aux", 535 .name = "wm9712-aux",
549 .playback = { 536 .playback = {
550 .stream_name = "Aux Playback", 537 .stream_name = "Aux Playback",
551 .channels_min = 1, 538 .channels_min = 1,
@@ -555,7 +542,6 @@ struct snd_soc_dai wm9712_dai[] = {
555 .ops = &wm9712_dai_ops_aux, 542 .ops = &wm9712_dai_ops_aux,
556} 543}
557}; 544};
558EXPORT_SYMBOL_GPL(wm9712_dai);
559 545
560static int wm9712_set_bias_level(struct snd_soc_codec *codec, 546static int wm9712_set_bias_level(struct snd_soc_codec *codec,
561 enum snd_soc_bias_level level) 547 enum snd_soc_bias_level level)
@@ -573,7 +559,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
573 ac97_write(codec, AC97_POWERDOWN, 0xffff); 559 ac97_write(codec, AC97_POWERDOWN, 0xffff);
574 break; 560 break;
575 } 561 }
576 codec->bias_level = level; 562 codec->dapm.bias_level = level;
577 return 0; 563 return 0;
578} 564}
579 565
@@ -597,20 +583,15 @@ err:
597 return -EIO; 583 return -EIO;
598} 584}
599 585
600static int wm9712_soc_suspend(struct platform_device *pdev, 586static int wm9712_soc_suspend(struct snd_soc_codec *codec,
601 pm_message_t state) 587 pm_message_t state)
602{ 588{
603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
604 struct snd_soc_codec *codec = socdev->card->codec;
605
606 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); 589 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
607 return 0; 590 return 0;
608} 591}
609 592
610static int wm9712_soc_resume(struct platform_device *pdev) 593static int wm9712_soc_resume(struct snd_soc_codec *codec)
611{ 594{
612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
613 struct snd_soc_codec *codec = socdev->card->codec;
614 int i, ret; 595 int i, ret;
615 u16 *cache = codec->reg_cache; 596 u16 *cache = codec->reg_cache;
616 597
@@ -635,51 +616,18 @@ static int wm9712_soc_resume(struct platform_device *pdev)
635 return ret; 616 return ret;
636} 617}
637 618
638static int wm9712_soc_probe(struct platform_device *pdev) 619static int wm9712_soc_probe(struct snd_soc_codec *codec)
639{ 620{
640 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
641 struct snd_soc_codec *codec;
642 int ret = 0; 621 int ret = 0;
643 622
644 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); 623 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
645 624
646 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
647 GFP_KERNEL);
648 if (socdev->card->codec == NULL)
649 return -ENOMEM;
650 codec = socdev->card->codec;
651 mutex_init(&codec->mutex);
652
653 codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
654
655 if (codec->reg_cache == NULL) {
656 ret = -ENOMEM;
657 goto cache_err;
658 }
659 codec->reg_cache_size = sizeof(wm9712_reg);
660 codec->reg_cache_step = 2;
661
662 codec->name = "WM9712";
663 codec->owner = THIS_MODULE;
664 codec->dai = wm9712_dai;
665 codec->num_dai = ARRAY_SIZE(wm9712_dai);
666 codec->write = ac97_write;
667 codec->read = ac97_read;
668 codec->set_bias_level = wm9712_set_bias_level;
669 INIT_LIST_HEAD(&codec->dapm_widgets);
670 INIT_LIST_HEAD(&codec->dapm_paths);
671
672 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 625 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
673 if (ret < 0) { 626 if (ret < 0) {
674 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 627 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
675 goto codec_err; 628 return ret;
676 } 629 }
677 630
678 /* register pcms */
679 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
680 if (ret < 0)
681 goto pcm_err;
682
683 ret = wm9712_reset(codec, 0); 631 ret = wm9712_reset(codec, 0);
684 if (ret < 0) { 632 if (ret < 0) {
685 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n"); 633 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
@@ -692,47 +640,71 @@ static int wm9712_soc_probe(struct platform_device *pdev)
692 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 640 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
693 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 641 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
694 ARRAY_SIZE(wm9712_snd_ac97_controls)); 642 ARRAY_SIZE(wm9712_snd_ac97_controls));
695 wm9712_add_widgets(codec);
696 643
697 return 0; 644 return 0;
698 645
699reset_err: 646reset_err:
700 snd_soc_free_pcms(socdev);
701pcm_err:
702 snd_soc_free_ac97_codec(codec); 647 snd_soc_free_ac97_codec(codec);
703
704codec_err:
705 kfree(codec->reg_cache);
706
707cache_err:
708 kfree(socdev->card->codec);
709 socdev->card->codec = NULL;
710 return ret; 648 return ret;
711} 649}
712 650
713static int wm9712_soc_remove(struct platform_device *pdev) 651static int wm9712_soc_remove(struct snd_soc_codec *codec)
714{ 652{
715 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
716 struct snd_soc_codec *codec = socdev->card->codec;
717
718 if (codec == NULL)
719 return 0;
720
721 snd_soc_dapm_free(socdev);
722 snd_soc_free_pcms(socdev);
723 snd_soc_free_ac97_codec(codec); 653 snd_soc_free_ac97_codec(codec);
724 kfree(codec->reg_cache);
725 kfree(codec);
726 return 0; 654 return 0;
727} 655}
728 656
729struct snd_soc_codec_device soc_codec_dev_wm9712 = { 657static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
730 .probe = wm9712_soc_probe, 658 .probe = wm9712_soc_probe,
731 .remove = wm9712_soc_remove, 659 .remove = wm9712_soc_remove,
732 .suspend = wm9712_soc_suspend, 660 .suspend = wm9712_soc_suspend,
733 .resume = wm9712_soc_resume, 661 .resume = wm9712_soc_resume,
662 .read = ac97_read,
663 .write = ac97_write,
664 .set_bias_level = wm9712_set_bias_level,
665 .reg_cache_size = ARRAY_SIZE(wm9712_reg),
666 .reg_word_size = sizeof(u16),
667 .reg_cache_step = 2,
668 .reg_cache_default = wm9712_reg,
669 .dapm_widgets = wm9712_dapm_widgets,
670 .num_dapm_widgets = ARRAY_SIZE(wm9712_dapm_widgets),
671 .dapm_routes = wm9712_audio_map,
672 .num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
734}; 673};
735EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712); 674
675static __devinit int wm9712_probe(struct platform_device *pdev)
676{
677 return snd_soc_register_codec(&pdev->dev,
678 &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
679}
680
681static int __devexit wm9712_remove(struct platform_device *pdev)
682{
683 snd_soc_unregister_codec(&pdev->dev);
684 return 0;
685}
686
687static struct platform_driver wm9712_codec_driver = {
688 .driver = {
689 .name = "wm9712-codec",
690 .owner = THIS_MODULE,
691 },
692
693 .probe = wm9712_probe,
694 .remove = __devexit_p(wm9712_remove),
695};
696
697static int __init wm9712_init(void)
698{
699 return platform_driver_register(&wm9712_codec_driver);
700}
701module_init(wm9712_init);
702
703static void __exit wm9712_exit(void)
704{
705 platform_driver_unregister(&wm9712_codec_driver);
706}
707module_exit(wm9712_exit);
736 708
737MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver"); 709MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
738MODULE_AUTHOR("Liam Girdwood"); 710MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9712.h b/sound/soc/codecs/wm9712.h
index d29e8a18ca6d..fb69c3aa4ed0 100644
--- a/sound/soc/codecs/wm9712.h
+++ b/sound/soc/codecs/wm9712.h
@@ -8,7 +8,4 @@
8#define WM9712_DAI_AC97_HIFI 0 8#define WM9712_DAI_AC97_HIFI 0
9#define WM9712_DAI_AC97_AUX 1 9#define WM9712_DAI_AC97_AUX 1
10 10
11extern struct snd_soc_dai wm9712_dai[2];
12extern struct snd_soc_codec_device soc_codec_dev_wm9712;
13
14#endif 11#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 34e0c91092fa..7167cb6787db 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -26,7 +26,6 @@
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/tlv.h> 27#include <sound/tlv.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include "wm9713.h" 30#include "wm9713.h"
32 31
@@ -488,7 +487,7 @@ SND_SOC_DAPM_INPUT("MIC2B"),
488SND_SOC_DAPM_VMID("VMID"), 487SND_SOC_DAPM_VMID("VMID"),
489}; 488};
490 489
491static const struct snd_soc_dapm_route audio_map[] = { 490static const struct snd_soc_dapm_route wm9713_audio_map[] = {
492 /* left HP mixer */ 491 /* left HP mixer */
493 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"}, 492 {"Left HP Mixer", "Beep Playback Switch", "PCBEEP"},
494 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"}, 493 {"Left HP Mixer", "Voice Playback Switch", "Voice DAC"},
@@ -645,16 +644,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
645 {"Capture Mono Mux", "Right", "Right Capture Source"}, 644 {"Capture Mono Mux", "Right", "Right Capture Source"},
646}; 645};
647 646
648static int wm9713_add_widgets(struct snd_soc_codec *codec)
649{
650 snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets,
651 ARRAY_SIZE(wm9713_dapm_widgets));
652
653 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
654
655 return 0;
656}
657
658static unsigned int ac97_read(struct snd_soc_codec *codec, 647static unsigned int ac97_read(struct snd_soc_codec *codec,
659 unsigned int reg) 648 unsigned int reg)
660{ 649{
@@ -1057,9 +1046,9 @@ static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
1057 .set_tristate = wm9713_set_dai_tristate, 1046 .set_tristate = wm9713_set_dai_tristate,
1058}; 1047};
1059 1048
1060struct snd_soc_dai wm9713_dai[] = { 1049static struct snd_soc_dai_driver wm9713_dai[] = {
1061{ 1050{
1062 .name = "AC97 HiFi", 1051 .name = "wm9713-hifi",
1063 .ac97_control = 1, 1052 .ac97_control = 1,
1064 .playback = { 1053 .playback = {
1065 .stream_name = "HiFi Playback", 1054 .stream_name = "HiFi Playback",
@@ -1076,7 +1065,7 @@ struct snd_soc_dai wm9713_dai[] = {
1076 .ops = &wm9713_dai_ops_hifi, 1065 .ops = &wm9713_dai_ops_hifi,
1077 }, 1066 },
1078 { 1067 {
1079 .name = "AC97 Aux", 1068 .name = "wm9713-aux",
1080 .playback = { 1069 .playback = {
1081 .stream_name = "Aux Playback", 1070 .stream_name = "Aux Playback",
1082 .channels_min = 1, 1071 .channels_min = 1,
@@ -1086,7 +1075,7 @@ struct snd_soc_dai wm9713_dai[] = {
1086 .ops = &wm9713_dai_ops_aux, 1075 .ops = &wm9713_dai_ops_aux,
1087 }, 1076 },
1088 { 1077 {
1089 .name = "WM9713 Voice", 1078 .name = "wm9713-voice",
1090 .playback = { 1079 .playback = {
1091 .stream_name = "Voice Playback", 1080 .stream_name = "Voice Playback",
1092 .channels_min = 1, 1081 .channels_min = 1,
@@ -1103,7 +1092,6 @@ struct snd_soc_dai wm9713_dai[] = {
1103 .symmetric_rates = 1, 1092 .symmetric_rates = 1,
1104 }, 1093 },
1105}; 1094};
1106EXPORT_SYMBOL_GPL(wm9713_dai);
1107 1095
1108int wm9713_reset(struct snd_soc_codec *codec, int try_warm) 1096int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1109{ 1097{
@@ -1148,15 +1136,13 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1148 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1136 ac97_write(codec, AC97_POWERDOWN, 0xffff);
1149 break; 1137 break;
1150 } 1138 }
1151 codec->bias_level = level; 1139 codec->dapm.bias_level = level;
1152 return 0; 1140 return 0;
1153} 1141}
1154 1142
1155static int wm9713_soc_suspend(struct platform_device *pdev, 1143static int wm9713_soc_suspend(struct snd_soc_codec *codec,
1156 pm_message_t state) 1144 pm_message_t state)
1157{ 1145{
1158 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1159 struct snd_soc_codec *codec = socdev->card->codec;
1160 u16 reg; 1146 u16 reg;
1161 1147
1162 /* Disable everything except touchpanel - that will be handled 1148 /* Disable everything except touchpanel - that will be handled
@@ -1171,10 +1157,8 @@ static int wm9713_soc_suspend(struct platform_device *pdev,
1171 return 0; 1157 return 0;
1172} 1158}
1173 1159
1174static int wm9713_soc_resume(struct platform_device *pdev) 1160static int wm9713_soc_resume(struct snd_soc_codec *codec)
1175{ 1161{
1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1177 struct snd_soc_codec *codec = socdev->card->codec;
1178 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec); 1162 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1179 int i, ret; 1163 int i, ret;
1180 u16 *cache = codec->reg_cache; 1164 u16 *cache = codec->reg_cache;
@@ -1204,53 +1188,20 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1204 return ret; 1188 return ret;
1205} 1189}
1206 1190
1207static int wm9713_soc_probe(struct platform_device *pdev) 1191static int wm9713_soc_probe(struct snd_soc_codec *codec)
1208{ 1192{
1209 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1193 struct wm9713_priv *wm9713;
1210 struct snd_soc_codec *codec;
1211 int ret = 0, reg; 1194 int ret = 0, reg;
1212 1195
1213 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1196 wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL);
1214 GFP_KERNEL); 1197 if (wm9713 == NULL)
1215 if (socdev->card->codec == NULL)
1216 return -ENOMEM; 1198 return -ENOMEM;
1217 codec = socdev->card->codec; 1199 snd_soc_codec_set_drvdata(codec, wm9713);
1218 mutex_init(&codec->mutex);
1219
1220 codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL);
1221 if (codec->reg_cache == NULL) {
1222 ret = -ENOMEM;
1223 goto cache_err;
1224 }
1225 codec->reg_cache_size = sizeof(wm9713_reg);
1226 codec->reg_cache_step = 2;
1227
1228 snd_soc_codec_set_drvdata(codec, kzalloc(sizeof(struct wm9713_priv),
1229 GFP_KERNEL));
1230 if (snd_soc_codec_get_drvdata(codec) == NULL) {
1231 ret = -ENOMEM;
1232 goto priv_err;
1233 }
1234
1235 codec->name = "WM9713";
1236 codec->owner = THIS_MODULE;
1237 codec->dai = wm9713_dai;
1238 codec->num_dai = ARRAY_SIZE(wm9713_dai);
1239 codec->write = ac97_write;
1240 codec->read = ac97_read;
1241 codec->set_bias_level = wm9713_set_bias_level;
1242 INIT_LIST_HEAD(&codec->dapm_widgets);
1243 INIT_LIST_HEAD(&codec->dapm_paths);
1244 1200
1245 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1201 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
1246 if (ret < 0) 1202 if (ret < 0)
1247 goto codec_err; 1203 goto codec_err;
1248 1204
1249 /* register pcms */
1250 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1251 if (ret < 0)
1252 goto pcm_err;
1253
1254 /* do a cold reset for the controller and then try 1205 /* do a cold reset for the controller and then try
1255 * a warm reset followed by an optional cold reset for codec */ 1206 * a warm reset followed by an optional cold reset for codec */
1256 wm9713_reset(codec, 0); 1207 wm9713_reset(codec, 0);
@@ -1268,51 +1219,75 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1268 1219
1269 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1220 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1270 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1221 ARRAY_SIZE(wm9713_snd_ac97_controls));
1271 wm9713_add_widgets(codec);
1272 1222
1273 return 0; 1223 return 0;
1274 1224
1275reset_err: 1225reset_err:
1276 snd_soc_free_pcms(socdev);
1277pcm_err:
1278 snd_soc_free_ac97_codec(codec); 1226 snd_soc_free_ac97_codec(codec);
1279
1280codec_err: 1227codec_err:
1281 kfree(snd_soc_codec_get_drvdata(codec)); 1228 kfree(wm9713);
1282
1283priv_err:
1284 kfree(codec->reg_cache);
1285
1286cache_err:
1287 kfree(socdev->card->codec);
1288 socdev->card->codec = NULL;
1289 return ret; 1229 return ret;
1290} 1230}
1291 1231
1292static int wm9713_soc_remove(struct platform_device *pdev) 1232static int wm9713_soc_remove(struct snd_soc_codec *codec)
1293{ 1233{
1294 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1234 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1295 struct snd_soc_codec *codec = socdev->card->codec;
1296
1297 if (codec == NULL)
1298 return 0;
1299
1300 snd_soc_dapm_free(socdev);
1301 snd_soc_free_pcms(socdev);
1302 snd_soc_free_ac97_codec(codec); 1235 snd_soc_free_ac97_codec(codec);
1303 kfree(snd_soc_codec_get_drvdata(codec)); 1236 kfree(wm9713);
1304 kfree(codec->reg_cache);
1305 kfree(codec);
1306 return 0; 1237 return 0;
1307} 1238}
1308 1239
1309struct snd_soc_codec_device soc_codec_dev_wm9713 = { 1240static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
1310 .probe = wm9713_soc_probe, 1241 .probe = wm9713_soc_probe,
1311 .remove = wm9713_soc_remove, 1242 .remove = wm9713_soc_remove,
1312 .suspend = wm9713_soc_suspend, 1243 .suspend = wm9713_soc_suspend,
1313 .resume = wm9713_soc_resume, 1244 .resume = wm9713_soc_resume,
1245 .read = ac97_read,
1246 .write = ac97_write,
1247 .set_bias_level = wm9713_set_bias_level,
1248 .reg_cache_size = ARRAY_SIZE(wm9713_reg),
1249 .reg_word_size = sizeof(u16),
1250 .reg_cache_step = 2,
1251 .reg_cache_default = wm9713_reg,
1252 .dapm_widgets = wm9713_dapm_widgets,
1253 .num_dapm_widgets = ARRAY_SIZE(wm9713_dapm_widgets),
1254 .dapm_routes = wm9713_audio_map,
1255 .num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
1256};
1257
1258static __devinit int wm9713_probe(struct platform_device *pdev)
1259{
1260 return snd_soc_register_codec(&pdev->dev,
1261 &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
1262}
1263
1264static int __devexit wm9713_remove(struct platform_device *pdev)
1265{
1266 snd_soc_unregister_codec(&pdev->dev);
1267 return 0;
1268}
1269
1270static struct platform_driver wm9713_codec_driver = {
1271 .driver = {
1272 .name = "wm9713-codec",
1273 .owner = THIS_MODULE,
1274 },
1275
1276 .probe = wm9713_probe,
1277 .remove = __devexit_p(wm9713_remove),
1314}; 1278};
1315EXPORT_SYMBOL_GPL(soc_codec_dev_wm9713); 1279
1280static int __init wm9713_init(void)
1281{
1282 return platform_driver_register(&wm9713_codec_driver);
1283}
1284module_init(wm9713_init);
1285
1286static void __exit wm9713_exit(void)
1287{
1288 platform_driver_unregister(&wm9713_codec_driver);
1289}
1290module_exit(wm9713_exit);
1316 1291
1317MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver"); 1292MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
1318MODULE_AUTHOR("Liam Girdwood"); 1293MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h
index 63b8d81756e3..793da863a03d 100644
--- a/sound/soc/codecs/wm9713.h
+++ b/sound/soc/codecs/wm9713.h
@@ -45,9 +45,6 @@
45#define WM9713_DAI_AC97_AUX 1 45#define WM9713_DAI_AC97_AUX 1
46#define WM9713_DAI_PCM_VOICE 2 46#define WM9713_DAI_PCM_VOICE 2
47 47
48extern struct snd_soc_codec_device soc_codec_dev_wm9713;
49extern struct snd_soc_dai wm9713_dai[3];
50
51int wm9713_reset(struct snd_soc_codec *codec, int try_warm); 48int wm9713_reset(struct snd_soc_codec *codec, int try_warm);
52 49
53#endif 50#endif
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 2cb81538cd91..9e370d14ad88 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -22,7 +22,6 @@
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h> 25#include <sound/initval.h>
27#include <sound/tlv.h> 26#include <sound/tlv.h>
28 27
@@ -83,7 +82,8 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
83 } while (reg & op && count < 400); 82 } while (reg & op && count < 400);
84 83
85 if (reg & op) 84 if (reg & op)
86 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 85 dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
86 op);
87} 87}
88 88
89/* 89/*
@@ -92,54 +92,73 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
92static void calibrate_dc_servo(struct snd_soc_codec *codec) 92static void calibrate_dc_servo(struct snd_soc_codec *codec)
93{ 93{
94 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 94 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
95 s8 offset;
95 u16 reg, reg_l, reg_r, dcs_cfg; 96 u16 reg, reg_l, reg_r, dcs_cfg;
96 97
97 /* Set for 32 series updates */ 98 /* If we're using a digital only path and have a previously
98 snd_soc_update_bits(codec, WM8993_DC_SERVO_1, 99 * callibrated DC servo offset stored then use that. */
99 WM8993_DCS_SERIES_NO_01_MASK, 100 if (hubs->class_w && hubs->class_w_dcs) {
100 32 << WM8993_DCS_SERIES_NO_01_SHIFT); 101 dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
101 wait_for_dc_servo(codec, 102 hubs->class_w_dcs);
102 WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); 103 snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs);
104 wait_for_dc_servo(codec,
105 WM8993_DCS_TRIG_DAC_WR_0 |
106 WM8993_DCS_TRIG_DAC_WR_1);
107 return;
108 }
109
110 /* Devices not using a DCS code correction have startup mode */
111 if (hubs->dcs_codes) {
112 /* Set for 32 series updates */
113 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
114 WM8993_DCS_SERIES_NO_01_MASK,
115 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
116 wait_for_dc_servo(codec,
117 WM8993_DCS_TRIG_SERIES_0 |
118 WM8993_DCS_TRIG_SERIES_1);
119 } else {
120 wait_for_dc_servo(codec,
121 WM8993_DCS_TRIG_STARTUP_0 |
122 WM8993_DCS_TRIG_STARTUP_1);
123 }
124
125 /* Different chips in the family support different readback
126 * methods.
127 */
128 switch (hubs->dcs_readback_mode) {
129 case 0:
130 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
131 & WM8993_DCS_INTEG_CHAN_0_MASK;
132 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
133 & WM8993_DCS_INTEG_CHAN_1_MASK;
134 break;
135 case 1:
136 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
137 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
138 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
139 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
140 break;
141 default:
142 WARN(1, "Unknown DCS readback method\n");
143 break;
144 }
145
146 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
103 147
104 /* Apply correction to DC servo result */ 148 /* Apply correction to DC servo result */
105 if (hubs->dcs_codes) { 149 if (hubs->dcs_codes) {
106 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 150 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
107 hubs->dcs_codes); 151 hubs->dcs_codes);
108 152
109 /* Different chips in the family support different
110 * readback methods.
111 */
112 switch (hubs->dcs_readback_mode) {
113 case 0:
114 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
115 & WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
117 & WM8993_DCS_INTEG_CHAN_1_MASK;
118 break;
119 case 1:
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
121 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
122 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
123 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
124 break;
125 default:
126 WARN(1, "Unknown DCS readback method");
127 break;
128 }
129
130 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
131
132 /* HPOUT1L */ 153 /* HPOUT1L */
133 if (reg_l + hubs->dcs_codes > 0 && 154 offset = reg_l;
134 reg_l + hubs->dcs_codes < 0xff) 155 offset += hubs->dcs_codes;
135 reg_l += hubs->dcs_codes; 156 dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
136 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
137 157
138 /* HPOUT1R */ 158 /* HPOUT1R */
139 if (reg_r + hubs->dcs_codes > 0 && 159 offset = reg_r;
140 reg_r + hubs->dcs_codes < 0xff) 160 offset += hubs->dcs_codes;
141 reg_r += hubs->dcs_codes; 161 dcs_cfg |= (u8)offset;
142 dcs_cfg |= reg_r;
143 162
144 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); 163 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
145 164
@@ -148,7 +167,15 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
148 wait_for_dc_servo(codec, 167 wait_for_dc_servo(codec,
149 WM8993_DCS_TRIG_DAC_WR_0 | 168 WM8993_DCS_TRIG_DAC_WR_0 |
150 WM8993_DCS_TRIG_DAC_WR_1); 169 WM8993_DCS_TRIG_DAC_WR_1);
170 } else {
171 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
172 dcs_cfg |= reg_r;
151 } 173 }
174
175 /* Save the callibrated offset if we're in class W mode and
176 * therefore don't have any analogue signal mixed in. */
177 if (hubs->class_w)
178 hubs->class_w_dcs = dcs_cfg;
152} 179}
153 180
154/* 181/*
@@ -163,6 +190,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
163 190
164 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 191 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
165 192
193 /* Updating the analogue gains invalidates the DC servo cache */
194 hubs->class_w_dcs = 0;
195
166 /* If we're applying an offset correction then updating the 196 /* If we're applying an offset correction then updating the
167 * callibration would be likely to introduce further offsets. */ 197 * callibration would be likely to introduce further offsets. */
168 if (hubs->dcs_codes) 198 if (hubs->dcs_codes)
@@ -185,23 +215,23 @@ static const struct snd_kcontrol_new analogue_snd_controls[] = {
185SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, 215SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
186 inpga_tlv), 216 inpga_tlv),
187SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), 217SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
188SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 0), 218SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 6, 1, 0),
189 219
190SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, 220SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
191 inpga_tlv), 221 inpga_tlv),
192SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), 222SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
193SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 0), 223SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 6, 1, 0),
194 224
195 225
196SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, 226SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
197 inpga_tlv), 227 inpga_tlv),
198SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), 228SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
199SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 0), 229SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 6, 1, 0),
200 230
201SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, 231SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
202 inpga_tlv), 232 inpga_tlv),
203SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), 233SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
204SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 0), 234SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 6, 1, 0),
205 235
206SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0, 236SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0,
207 inmix_sw_tlv), 237 inmix_sw_tlv),
@@ -293,7 +323,7 @@ SOC_DOUBLE_R("Speaker Switch",
293SOC_DOUBLE_R("Speaker ZC Switch", 323SOC_DOUBLE_R("Speaker ZC Switch",
294 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, 324 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
295 7, 1, 0), 325 7, 1, 0),
296SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0, 326SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
297 spkboost_tlv), 327 spkboost_tlv),
298SOC_ENUM("Speaker Reference", speaker_ref), 328SOC_ENUM("Speaker Reference", speaker_ref),
299SOC_ENUM("Speaker Mode", speaker_mode), 329SOC_ENUM("Speaker Mode", speaker_mode),
@@ -645,6 +675,9 @@ SND_SOC_DAPM_OUTPUT("LINEOUT2N"),
645}; 675};
646 676
647static const struct snd_soc_dapm_route analogue_routes[] = { 677static const struct snd_soc_dapm_route analogue_routes[] = {
678 { "MICBIAS1", NULL, "CLK_SYS" },
679 { "MICBIAS2", NULL, "CLK_SYS" },
680
648 { "IN1L PGA", "IN1LP Switch", "IN1LP" }, 681 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
649 { "IN1L PGA", "IN1LN Switch", "IN1LN" }, 682 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
650 683
@@ -707,12 +740,12 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
707 740
708 { "SPKL", "Input Switch", "MIXINL" }, 741 { "SPKL", "Input Switch", "MIXINL" },
709 { "SPKL", "IN1LP Switch", "IN1LP" }, 742 { "SPKL", "IN1LP Switch", "IN1LP" },
710 { "SPKL", "Output Switch", "Left Output Mixer" }, 743 { "SPKL", "Output Switch", "Left Output PGA" },
711 { "SPKL", NULL, "TOCLK" }, 744 { "SPKL", NULL, "TOCLK" },
712 745
713 { "SPKR", "Input Switch", "MIXINR" }, 746 { "SPKR", "Input Switch", "MIXINR" },
714 { "SPKR", "IN1RP Switch", "IN1RP" }, 747 { "SPKR", "IN1RP Switch", "IN1RP" },
715 { "SPKR", "Output Switch", "Right Output Mixer" }, 748 { "SPKR", "Output Switch", "Right Output PGA" },
716 { "SPKR", NULL, "TOCLK" }, 749 { "SPKR", NULL, "TOCLK" },
717 750
718 { "SPKL Boost", "Direct Voice Switch", "Direct Voice" }, 751 { "SPKL Boost", "Direct Voice Switch", "Direct Voice" },
@@ -734,8 +767,8 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
734 { "SPKOUTRP", NULL, "SPKR Driver" }, 767 { "SPKOUTRP", NULL, "SPKR Driver" },
735 { "SPKOUTRN", NULL, "SPKR Driver" }, 768 { "SPKOUTRN", NULL, "SPKR Driver" },
736 769
737 { "Left Headphone Mux", "Mixer", "Left Output Mixer" }, 770 { "Left Headphone Mux", "Mixer", "Left Output PGA" },
738 { "Right Headphone Mux", "Mixer", "Right Output Mixer" }, 771 { "Right Headphone Mux", "Mixer", "Right Output PGA" },
739 772
740 { "Headphone PGA", NULL, "Left Headphone Mux" }, 773 { "Headphone PGA", NULL, "Left Headphone Mux" },
741 { "Headphone PGA", NULL, "Right Headphone Mux" }, 774 { "Headphone PGA", NULL, "Right Headphone Mux" },
@@ -754,17 +787,17 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
754static const struct snd_soc_dapm_route lineout1_diff_routes[] = { 787static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
755 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" }, 788 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" },
756 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" }, 789 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" },
757 { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" }, 790 { "LINEOUT1 Mixer", "Output Switch", "Left Output PGA" },
758 791
759 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" }, 792 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" },
760 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" }, 793 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" },
761}; 794};
762 795
763static const struct snd_soc_dapm_route lineout1_se_routes[] = { 796static const struct snd_soc_dapm_route lineout1_se_routes[] = {
764 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" }, 797 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output PGA" },
765 { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" }, 798 { "LINEOUT1N Mixer", "Right Output Switch", "Right Output PGA" },
766 799
767 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" }, 800 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output PGA" },
768 801
769 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" }, 802 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
770 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" }, 803 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" },
@@ -773,17 +806,17 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = {
773static const struct snd_soc_dapm_route lineout2_diff_routes[] = { 806static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
774 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, 807 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
775 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, 808 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
776 { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" }, 809 { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" },
777 810
778 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, 811 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
779 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" }, 812 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" },
780}; 813};
781 814
782static const struct snd_soc_dapm_route lineout2_se_routes[] = { 815static const struct snd_soc_dapm_route lineout2_se_routes[] = {
783 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" }, 816 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output PGA" },
784 { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" }, 817 { "LINEOUT2N Mixer", "Right Output Switch", "Right Output PGA" },
785 818
786 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" }, 819 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output PGA" },
787 820
788 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" }, 821 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
789 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" }, 822 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
@@ -791,6 +824,8 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = {
791 824
792int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) 825int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
793{ 826{
827 struct snd_soc_dapm_context *dapm = &codec->dapm;
828
794 /* Latch volume update bits & default ZC on */ 829 /* Latch volume update bits & default ZC on */
795 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 830 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
796 WM8993_IN1_VU, WM8993_IN1_VU); 831 WM8993_IN1_VU, WM8993_IN1_VU);
@@ -801,17 +836,21 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
801 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 836 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
802 WM8993_IN2_VU, WM8993_IN2_VU); 837 WM8993_IN2_VU, WM8993_IN2_VU);
803 838
839 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_LEFT,
840 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
804 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT, 841 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
805 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU); 842 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
806 843
807 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME, 844 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
808 WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC); 845 WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC,
846 WM8993_HPOUT1_VU | WM8993_HPOUT1L_ZC);
809 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME, 847 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
810 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC, 848 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
811 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC); 849 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
812 850
813 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME, 851 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
814 WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC); 852 WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU,
853 WM8993_MIXOUTL_ZC | WM8993_MIXOUT_VU);
815 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME, 854 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
816 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, 855 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
817 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); 856 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
@@ -819,7 +858,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
819 snd_soc_add_controls(codec, analogue_snd_controls, 858 snd_soc_add_controls(codec, analogue_snd_controls,
820 ARRAY_SIZE(analogue_snd_controls)); 859 ARRAY_SIZE(analogue_snd_controls));
821 860
822 snd_soc_dapm_new_controls(codec, analogue_dapm_widgets, 861 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
823 ARRAY_SIZE(analogue_dapm_widgets)); 862 ARRAY_SIZE(analogue_dapm_widgets));
824 return 0; 863 return 0;
825} 864}
@@ -828,24 +867,26 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
828int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, 867int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
829 int lineout1_diff, int lineout2_diff) 868 int lineout1_diff, int lineout2_diff)
830{ 869{
831 snd_soc_dapm_add_routes(codec, analogue_routes, 870 struct snd_soc_dapm_context *dapm = &codec->dapm;
871
872 snd_soc_dapm_add_routes(dapm, analogue_routes,
832 ARRAY_SIZE(analogue_routes)); 873 ARRAY_SIZE(analogue_routes));
833 874
834 if (lineout1_diff) 875 if (lineout1_diff)
835 snd_soc_dapm_add_routes(codec, 876 snd_soc_dapm_add_routes(dapm,
836 lineout1_diff_routes, 877 lineout1_diff_routes,
837 ARRAY_SIZE(lineout1_diff_routes)); 878 ARRAY_SIZE(lineout1_diff_routes));
838 else 879 else
839 snd_soc_dapm_add_routes(codec, 880 snd_soc_dapm_add_routes(dapm,
840 lineout1_se_routes, 881 lineout1_se_routes,
841 ARRAY_SIZE(lineout1_se_routes)); 882 ARRAY_SIZE(lineout1_se_routes));
842 883
843 if (lineout2_diff) 884 if (lineout2_diff)
844 snd_soc_dapm_add_routes(codec, 885 snd_soc_dapm_add_routes(dapm,
845 lineout2_diff_routes, 886 lineout2_diff_routes,
846 ARRAY_SIZE(lineout2_diff_routes)); 887 ARRAY_SIZE(lineout2_diff_routes));
847 else 888 else
848 snd_soc_dapm_add_routes(codec, 889 snd_soc_dapm_add_routes(dapm,
849 lineout2_se_routes, 890 lineout2_se_routes,
850 ARRAY_SIZE(lineout2_se_routes)); 891 ARRAY_SIZE(lineout2_se_routes));
851 892
@@ -872,7 +913,7 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
872 * VMID as an output and can disable it. 913 * VMID as an output and can disable it.
873 */ 914 */
874 if (lineout1_diff && lineout2_diff) 915 if (lineout1_diff && lineout2_diff)
875 codec->idle_bias_off = 1; 916 codec->dapm.idle_bias_off = 1;
876 917
877 if (lineout1fb) 918 if (lineout1fb)
878 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 919 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index e51c16683589..f8a5e976b5e6 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,6 +23,9 @@ struct wm_hubs_data {
23 int dcs_codes; 23 int dcs_codes;
24 int dcs_readback_mode; 24 int dcs_readback_mode;
25 int hp_startup_mode; 25 int hp_startup_mode;
26
27 bool class_w;
28 u16 class_w_dcs;
26}; 29};
27 30
28extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 31extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);