hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/codecs/cx2072x.c
....@@ -1,309 +1,90 @@
11 // SPDX-License-Identifier: GPL-2.0
22 //
3
-// ALSA SoC CX20721/cx20723 Solana codec driver
3
+// ALSA SoC CX20721/CX20723 codec driver
44 //
5
-// Copyright: (C) 2016 Conexant Systems, Inc.
5
+// Copyright: (C) 2017 Conexant Systems, Inc.
6
+// Author: Simon Ho, <Simon.ho@conexant.com>
7
+//
8
+// TODO: add support for TDM mode.
9
+//
610
7
-/* #define DEBUG */
8
-/* #define INTEL_MCLK_CONTROL */
9
-/* #define ENABLE_MIC_POP_WA */
10
-#include <linux/module.h>
11
-#include <linux/moduleparam.h>
12
-#include <linux/init.h>
11
+#include <linux/acpi.h>
12
+#include <linux/clk.h>
1313 #include <linux/delay.h>
14
-#include <linux/pm.h>
14
+#include <linux/gpio.h>
15
+#include <linux/init.h>
16
+#include <linux/i2c.h>
17
+#include <linux/module.h>
1518 #include <linux/platform_device.h>
19
+#include <linux/pm.h>
20
+#include <linux/pm_runtime.h>
21
+#include <linux/regmap.h>
22
+#include <linux/slab.h>
1623 #include <sound/core.h>
24
+#include <sound/initval.h>
25
+#include <sound/jack.h>
1726 #include <sound/pcm.h>
1827 #include <sound/pcm_params.h>
28
+#include <sound/tlv.h>
1929 #include <sound/soc.h>
2030 #include <sound/soc-dapm.h>
21
-#include <sound/initval.h>
22
-#include <sound/tlv.h>
23
-#include <linux/of_gpio.h>
24
-#include <linux/gpio.h>
25
-#include <sound/jack.h>
26
-#include <linux/slab.h>
27
-#include <linux/clk.h>
28
-#include <linux/i2c.h>
29
-#include <linux/firmware.h>
30
-#include <linux/regmap.h>
31
-#include <linux/proc_fs.h>
32
-#include <linux/interrupt.h>
33
-#include <linux/irq.h>
34
-#include <linux/acpi.h>
35
-#include <linux/version.h>
36
-#ifdef INTEL_MCLK_CONTROL
37
-#include <linux/vlv2_plat_clock.h>
38
-#endif
3931 #include "cx2072x.h"
40
-#define PLL_OUT_HZ_48 (1024 * 3 * 48000)
41
-#define SUPPORT_RKI2S_FORMAT
42
-#define CX2072X_REV_A2 0x00100002
43
-#define CXDBG_REG_DUMP
4432
45
-#ifdef INTEL_MCLK_CONTROL
46
-#define VLV2_PLAT_CLK_AUDIO 3
47
-#define PLAT_CLK_FORCE_ON 1
48
-#define PLAT_CLK_FORCE_OFF 2
49
-#endif
50
-
51
-static struct snd_soc_component *cx2072x_component;
52
-
53
-/* FIXME: need to move the EQ/DRC setting to device tree */
54
-static unsigned char cx2072x_eq_coeff_array[MAX_EQ_BAND][MAC_EQ_COEFF] = {
55
- {0x77, 0x26, 0x13, 0xb3, 0x76, 0x26, 0x0a, 0x3d, 0xd4, 0xe2, 0x04},
56
- {0x97, 0x3e, 0xb3, 0x86, 0xc2, 0x3b, 0x4d, 0x79, 0xa7, 0xc5, 0x03},
57
- {0x0f, 0x39, 0x76, 0xa3, 0x1b, 0x2b, 0x89, 0x5c, 0xd7, 0xdb, 0x03},
58
- {0x21, 0x46, 0xfe, 0xa6, 0xec, 0x24, 0x01, 0x59, 0xf4, 0xd4, 0x03},
59
- {0xe9, 0x78, 0x9c, 0xb0, 0x8a, 0x56, 0x64, 0x4f, 0x8d, 0xb0, 0x02},
60
- {0x60, 0x6e, 0x57, 0xee, 0xec, 0x18, 0xa8, 0x11, 0xb5, 0xf8, 0x02},
61
- {0x5a, 0x14, 0x68, 0xe9, 0x1d, 0x06, 0xb9, 0x5f, 0x68, 0xdc, 0x03},
62
-};
63
-
64
-static unsigned char cx2072x_drc_array[MAX_DRC_REGS] = {
65
- 0x65, 0x55, 0x3C, 0x01, 0x05, 0x39, 0x76, 0x1A, 0x00
66
-};
67
-
68
-/* #define CXDBG_REG_DUMP */
69
-#ifdef CXDBG_REG_DUMP
70
-
71
-#define CX2072X_FORMATS (SNDRV_PCM_FMTBIT_S24_LE \
72
- | SNDRV_PCM_FMTBIT_S16_LE)
73
-#define BITS_PER_SLOT 8
74
-
75
-#define _REG(_name_, _size_, _access_, _volatile_) { \
76
- #_name_, _name_, (_size_) | (_access_) | (_volatile_)}
77
-
78
-struct CX2072X_REG_DEF {
79
- const char *name;
80
- unsigned int addr;
81
- unsigned int attr;
82
-};
83
-
84
-#define WO 0x0100
85
-#define RO 0x0200
86
-#define RW 0x0300
87
-#define VO 0x8000
88
-#define NV 0x0000
89
-#define REGISTER_SIZE_MASK 0x000F
90
-#define REGISTER_ASSCESS_MASK 0x0F00
91
-#define REGISTER_VOLATILE_MASK 0x8000
92
-#define UNAVAILABLE 0
93
-
94
-static const struct CX2072X_REG_DEF cx2072x_regs[] = {
95
- _REG(CX2072X_VENDOR_ID, 4, RO, VO),
96
- _REG(CX2072X_REVISION_ID, 4, RO, VO),
97
- _REG(CX2072X_CURRENT_BCLK_FREQUENCY, 4, RO, VO),
98
- _REG(CX2072X_AFG_POWER_STATE, 1, RW, NV),
99
- _REG(CX2072X_UM_RESPONSE, 1, RW, NV),
100
- _REG(CX2072X_GPIO_DATA, 1, RW, NV),
101
- _REG(CX2072X_GPIO_ENABLE, 1, RW, NV),
102
- _REG(CX2072X_GPIO_DIRECTION, 1, RW, NV),
103
- _REG(CX2072X_GPIO_WAKE, 1, RW, NV),
104
- _REG(CX2072X_GPIO_UM_ENABLE, 1, RW, NV),
105
- _REG(CX2072X_GPIO_STICKY_MASK, 1, RW, NV),
106
- _REG(CX2072X_AFG_FUNCTION_RESET, 1, WO, NV),
107
- _REG(CX2072X_DAC1_CONVERTER_FORMAT, 2, RW, NV),
108
- _REG(CX2072X_DAC1_AMP_GAIN_RIGHT, 1, RW, NV),
109
- _REG(CX2072X_DAC1_AMP_GAIN_LEFT, 1, RW, NV),
110
- _REG(CX2072X_DAC1_POWER_STATE, 1, RW, NV),
111
- _REG(CX2072X_DAC1_CONVERTER_STREAM_CHANNEL, 1, RW, NV),
112
- _REG(CX2072X_DAC1_EAPD_ENABLE, 1, RW, NV),
113
- _REG(CX2072X_DAC2_CONVERTER_FORMAT, 2, RW, NV),
114
- _REG(CX2072X_DAC2_AMP_GAIN_RIGHT, 1, RW, NV),
115
- _REG(CX2072X_DAC2_AMP_GAIN_LEFT, 1, RW, NV),
116
- _REG(CX2072X_DAC2_POWER_STATE, 1, RW, NV),
117
- _REG(CX2072X_DAC2_CONVERTER_STREAM_CHANNEL, 1, RW, NV),
118
- _REG(CX2072X_ADC1_CONVERTER_FORMAT, 2, RW, NV),
119
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_0, 1, RW, NV),
120
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_0, 1, RW, NV),
121
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_1, 1, RW, NV),
122
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_1, 1, RW, NV),
123
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_2, 1, RW, NV),
124
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_2, 1, RW, NV),
125
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_3, 1, RW, NV),
126
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_3, 1, RW, NV),
127
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_4, 1, RW, NV),
128
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_4, 1, RW, NV),
129
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_5, 1, RW, NV),
130
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_5, 1, RW, NV),
131
- _REG(CX2072X_ADC1_AMP_GAIN_RIGHT_6, 1, RW, NV),
132
- _REG(CX2072X_ADC1_AMP_GAIN_LEFT_6, 1, RW, NV),
133
- _REG(CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 1, RW, NV),
134
- _REG(CX2072X_ADC1_POWER_STATE, 1, RW, NV),
135
- _REG(CX2072X_ADC1_CONVERTER_STREAM_CHANNEL, 1, RW, NV),
136
- _REG(CX2072X_ADC2_CONVERTER_FORMAT, 2, WO, NV),
137
- _REG(CX2072X_ADC2_AMP_GAIN_RIGHT_0, 1, RW, NV),
138
- _REG(CX2072X_ADC2_AMP_GAIN_LEFT_0, 1, RW, NV),
139
- _REG(CX2072X_ADC2_AMP_GAIN_RIGHT_1, 1, RW, NV),
140
- _REG(CX2072X_ADC2_AMP_GAIN_LEFT_1, 1, RW, NV),
141
- _REG(CX2072X_ADC2_AMP_GAIN_RIGHT_2, 1, RW, NV),
142
- _REG(CX2072X_ADC2_AMP_GAIN_LEFT_2, 1, RW, NV),
143
- _REG(CX2072X_ADC2_CONNECTION_SELECT_CONTROL, 1, RW, NV),
144
- _REG(CX2072X_ADC2_POWER_STATE, 1, RW, NV),
145
- _REG(CX2072X_ADC2_CONVERTER_STREAM_CHANNEL, 1, RW, NV),
146
- _REG(CX2072X_PORTA_CONNECTION_SELECT_CTRL, 1, RW, NV),
147
- _REG(CX2072X_PORTA_POWER_STATE, 1, RW, NV),
148
- _REG(CX2072X_PORTA_PIN_CTRL, 1, RW, NV),
149
- _REG(CX2072X_PORTA_UNSOLICITED_RESPONSE, 1, RW, NV),
150
- _REG(CX2072X_PORTA_PIN_SENSE, 4, RO, VO),
151
- _REG(CX2072X_PORTA_EAPD_BTL, 1, RW, NV),
152
- _REG(CX2072X_PORTB_POWER_STATE, 1, RW, NV),
153
- _REG(CX2072X_PORTB_PIN_CTRL, 1, RW, NV),
154
- _REG(CX2072X_PORTB_UNSOLICITED_RESPONSE, 1, RW, NV),
155
- _REG(CX2072X_PORTB_PIN_SENSE, 4, RO, VO),
156
- _REG(CX2072X_PORTB_EAPD_BTL, 1, RW, NV),
157
- _REG(CX2072X_PORTB_GAIN_RIGHT, 1, RW, NV),
158
- _REG(CX2072X_PORTB_GAIN_LEFT, 1, RW, NV),
159
- _REG(CX2072X_PORTC_POWER_STATE, 1, RW, NV),
160
- _REG(CX2072X_PORTC_PIN_CTRL, 1, RW, NV),
161
- _REG(CX2072X_PORTC_GAIN_RIGHT, 1, RW, NV),
162
- _REG(CX2072X_PORTC_GAIN_LEFT, 1, RW, NV),
163
- _REG(CX2072X_PORTD_POWER_STATE, 1, RW, NV),
164
- _REG(CX2072X_PORTD_PIN_CTRL, 1, RW, NV),
165
- _REG(CX2072X_PORTD_UNSOLICITED_RESPONSE, 1, RW, NV),
166
- _REG(CX2072X_PORTD_PIN_SENSE, 4, RO, VO),
167
- _REG(CX2072X_PORTD_GAIN_RIGHT, 1, RW, NV),
168
- _REG(CX2072X_PORTD_GAIN_LEFT, 1, RW, NV),
169
- _REG(CX2072X_PORTE_CONNECTION_SELECT_CTRL, 1, RW, NV),
170
- _REG(CX2072X_PORTE_POWER_STATE, 1, RW, NV),
171
- _REG(CX2072X_PORTE_PIN_CTRL, 1, RW, NV),
172
- _REG(CX2072X_PORTE_UNSOLICITED_RESPONSE, 1, RW, NV),
173
- _REG(CX2072X_PORTE_PIN_SENSE, 4, RO, VO),
174
- _REG(CX2072X_PORTE_EAPD_BTL, 1, RW, NV),
175
- _REG(CX2072X_PORTE_GAIN_RIGHT, 1, RW, NV),
176
- _REG(CX2072X_PORTE_GAIN_LEFT, 1, RW, NV),
177
- _REG(CX2072X_PORTF_POWER_STATE, 1, RW, NV),
178
- _REG(CX2072X_PORTF_PIN_CTRL, 1, RW, NV),
179
- _REG(CX2072X_PORTF_UNSOLICITED_RESPONSE, 1, RW, NV),
180
- _REG(CX2072X_PORTF_PIN_SENSE, 4, RO, VO),
181
- _REG(CX2072X_PORTF_GAIN_RIGHT, 1, RW, NV),
182
- _REG(CX2072X_PORTF_GAIN_LEFT, 1, RW, NV),
183
- _REG(CX2072X_PORTG_POWER_STATE, 1, RW, NV),
184
- _REG(CX2072X_PORTG_PIN_CTRL, 1, RW, NV),
185
- _REG(CX2072X_PORTG_CONNECTION_SELECT_CTRL, 1, RW, NV),
186
- _REG(CX2072X_PORTG_EAPD_BTL, 1, RW, NV),
187
- _REG(CX2072X_PORTM_POWER_STATE, 1, RW, NV),
188
- _REG(CX2072X_PORTM_PIN_CTRL, 1, RW, NV),
189
- _REG(CX2072X_PORTM_CONNECTION_SELECT_CTRL, 1, RW, NV),
190
- _REG(CX2072X_PORTM_EAPD_BTL, 1, RW, NV),
191
- _REG(CX2072X_MIXER_POWER_STATE, 1, RW, NV),
192
- _REG(CX2072X_MIXER_GAIN_RIGHT_0, 1, RW, NV),
193
- _REG(CX2072X_MIXER_GAIN_LEFT_0, 1, WO, NV),
194
- _REG(CX2072X_MIXER_GAIN_RIGHT_1, 1, RW, NV),
195
- _REG(CX2072X_MIXER_GAIN_LEFT_1, 1, RW, NV),
196
- _REG(CX2072X_EQ_ENABLE_BYPASS, 2, RW, NV),
197
- _REG(CX2072X_EQ_B0_COEFF, 2, WO, VO),
198
- _REG(CX2072X_EQ_B1_COEFF, 2, WO, VO),
199
- _REG(CX2072X_EQ_B2_COEFF, 2, WO, VO),
200
- _REG(CX2072X_EQ_A1_COEFF, 2, WO, VO),
201
- _REG(CX2072X_EQ_A2_COEFF, 2, WO, VO),
202
- _REG(CX2072X_EQ_G_COEFF, 1, WO, VO),
203
- _REG(CX2072X_EQ_BAND, 1, WO, VO),
204
- _REG(CX2072X_SPKR_DRC_ENABLE_STEP, 1, RW, NV),
205
- _REG(CX2072X_SPKR_DRC_CONTROL, 4, RW, NV),
206
- _REG(CX2072X_SPKR_DRC_TEST, 4, RW, NV),
207
- _REG(CX2072X_DIGITAL_BIOS_TEST0, 4, RW, NV),
208
- _REG(CX2072X_DIGITAL_BIOS_TEST2, 4, RW, NV),
209
- _REG(CX2072X_I2SPCM_CONTROL1, 4, RW, NV),
210
- _REG(CX2072X_I2SPCM_CONTROL2, 4, RW, NV),
211
- _REG(CX2072X_I2SPCM_CONTROL3, 4, RW, NV),
212
- _REG(CX2072X_I2SPCM_CONTROL4, 4, RW, NV),
213
- _REG(CX2072X_I2SPCM_CONTROL5, 4, RW, NV),
214
- _REG(CX2072X_I2SPCM_CONTROL6, 4, RW, NV),
215
- _REG(CX2072X_UM_INTERRUPT_CRTL_E, 4, RW, NV),
216
- _REG(CX2072X_CODEC_TEST20, 2, RW, NV),
217
- _REG(CX2072X_CODEC_TEST26, 2, RW, NV),
218
- _REG(CX2072X_ANALOG_TEST4, 2, RW, NV),
219
- _REG(CX2072X_ANALOG_TEST5, 2, RW, NV),
220
- _REG(CX2072X_ANALOG_TEST6, 2, WO, NV),
221
- _REG(CX2072X_ANALOG_TEST7, 2, RW, NV),
222
- _REG(CX2072X_ANALOG_TEST8, 2, RW, NV),
223
- _REG(CX2072X_ANALOG_TEST9, 2, RW, NV),
224
- _REG(CX2072X_ANALOG_TEST10, 2, RW, NV),
225
- _REG(CX2072X_ANALOG_TEST11, 2, RW, NV),
226
- _REG(CX2072X_ANALOG_TEST12, 2, RW, NV),
227
- _REG(CX2072X_ANALOG_TEST13, 2, RW, NV),
228
- _REG(CX2072X_DIGITAL_TEST0, 2, RW, NV),
229
- _REG(CX2072X_DIGITAL_TEST1, 2, RW, NV),
230
- _REG(CX2072X_DIGITAL_TEST11, 2, RW, NV),
231
- _REG(CX2072X_DIGITAL_TEST12, 2, RW, NV),
232
- _REG(CX2072X_DIGITAL_TEST15, 2, RW, NV),
233
- _REG(CX2072X_DIGITAL_TEST16, 2, RW, NV),
234
- _REG(CX2072X_DIGITAL_TEST17, 2, RW, NV),
235
- _REG(CX2072X_DIGITAL_TEST18, 2, RW, NV),
236
- _REG(CX2072X_DIGITAL_TEST19, 2, RW, NV),
237
- _REG(CX2072X_DIGITAL_TEST20, 2, RW, NV),
238
-};
239
-#endif
33
+#define PLL_OUT_HZ_48 (1024 * 3 * 48000)
34
+#define BITS_PER_SLOT 8
24035
24136 /* codec private data */
24237 struct cx2072x_priv {
24338 struct regmap *regmap;
244
- unsigned int mclk;
39
+ struct clk *mclk;
40
+ unsigned int mclk_rate;
24541 struct device *dev;
246
- struct snd_soc_component *component;
247
- struct snd_soc_dai_driver *dai_drv;
248
- int is_biason;
249
- struct snd_soc_jack *jack;
250
- bool jack_detecting;
251
- bool jack_mic;
252
- int jack_mode;
253
- int jack_flips;
254
- unsigned int jack_state;
255
- int audsmt_enable;
256
- /* lock for probe */
42
+ struct snd_soc_component *codec;
43
+ struct snd_soc_jack_gpio jack_gpio;
25744 struct mutex lock;
25845 unsigned int bclk_ratio;
259
-
260
-#ifdef ENABLE_MIC_POP_WA
261
- struct delayed_work mic_pop_workq;
262
-#endif
263
- bool plbk_dsp_en;
264
- bool plbk_dsp_changed;
265
- bool plbk_dsp_init;
26646 bool pll_changed;
26747 bool i2spcm_changed;
268
- int sample_size; /* used for non-PCM mode */
269
- int frame_size; /* used for non-PCM mode */
48
+ int sample_size;
49
+ int frame_size;
27050 int sample_rate;
27151 unsigned int dai_fmt;
272
- int tdm_rx_mask;
273
- int tdm_tx_mask;
274
- int tdm_slot_width;
275
- int tdm_slots;
276
- u32 rev_id;
277
- struct gpio_desc *spk_ctl_gpio;
278
- struct clk *mclk_clock;
52
+ bool en_aec_ref;
27953 };
28054
28155 /*
28256 * DAC/ADC Volume
28357 *
28458 * max : 74 : 0 dB
285
- * ( in 1 dB step )
59
+ * ( in 1 dB step )
28660 * min : 0 : -74 dB
28761 */
28862 static const DECLARE_TLV_DB_SCALE(adc_tlv, -7400, 100, 0);
28963 static const DECLARE_TLV_DB_SCALE(dac_tlv, -7400, 100, 0);
29064 static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 1200, 0);
29165
292
-#define get_cx2072x_priv(_component_) \
293
- ((struct cx2072x_priv *)snd_soc_component_get_drvdata(_component_))
66
+struct cx2072x_eq_ctrl {
67
+ u8 ch;
68
+ u8 band;
69
+};
70
+
71
+static const DECLARE_TLV_DB_RANGE(hpf_tlv,
72
+ 0, 0, TLV_DB_SCALE_ITEM(120, 0, 0),
73
+ 1, 63, TLV_DB_SCALE_ITEM(30, 30, 0)
74
+);
29475
29576 /* Lookup table for PRE_DIV */
296
-static struct {
77
+static const struct {
29778 unsigned int mclk;
29879 unsigned int div;
299
-} MCLK_PRE_DIV[] = {
80
+} mclk_pre_div[] = {
30081 { 6144000, 1 },
30182 { 12288000, 2 },
30283 { 19200000, 3 },
30384 { 26000000, 4 },
30485 { 28224000, 5 },
30586 { 36864000, 6 },
306
- { 36864000, 7 },/* Don't use div 7 */
87
+ { 36864000, 7 },
30788 { 48000000, 8 },
30889 { 49152000, 8 },
30990 };
....@@ -312,164 +93,164 @@
31293 * cx2072x register cache.
31394 */
31495 static const struct reg_default cx2072x_reg_defaults[] = {
315
- { 0x0414, 0x00000003 }, /* 2072X_AFG_POWER_STATE */
316
- { 0x0420, 0x00000000 }, /* 2072X_UM_RESPONSE */
317
- { 0x0454, 0x00000000 }, /* 2072X_GPIO_DATA */
318
- { 0x0458, 0x00000000 }, /* 2072X_GPIO_ENABLE */
319
- { 0x045c, 0x00000000 }, /* 2072X_GPIO_DIRECTION */
320
- { 0x0460, 0x00000000 }, /* 2072X_GPIO_WAKE */
321
- { 0x0464, 0x00000000 }, /* 2072X_GPIO_UM_ENABLE */
322
- { 0x0468, 0x00000000 }, /* 2072X_GPIO_STICKY_MASK */
323
- { 0x43c8, 0x00000031 }, /* 2072X_DAC1_CONVERTER_FORMAT */
324
- { 0x41c0, 0x0000004a }, /* 2072X_DAC1_AMP_GAIN_RIGHT */
325
- { 0x41e0, 0x0000004a }, /* 2072X_DAC1_AMP_GAIN_LEFT */
326
- { 0x4014, 0x00000433 }, /* 2072X_DAC1_POWER_STATE */
327
- { 0x4018, 0x00000000 }, /* 2072X_DAC1_CONVERTER_STREAM_CHANNEL */
328
- { 0x4030, 0x00000000 }, /* 2072X_DAC1_EAPD_ENABLE */
329
- { 0x47c8, 0x00000031 }, /* 2072X_DAC2_CONVERTER_FORMAT */
330
- { 0x45c0, 0x0000004a }, /* 2072X_DAC2_AMP_GAIN_RIGHT */
331
- { 0x45e0, 0x0000004a }, /* 2072X_DAC2_AMP_GAIN_LEFT */
332
- { 0x4414, 0x00000433 }, /* 2072X_DAC2_POWER_STATE */
333
- { 0x4418, 0x00000000 }, /* 2072X_DAC2_CONVERTER_STREAM_CHANNEL */
334
- { 0x4fc8, 0x00000031 }, /* 2072X_ADC1_CONVERTER_FORMAT */
335
- { 0x4d80, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_0 */
336
- { 0x4da0, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_0 */
337
- { 0x4d84, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_1 */
338
- { 0x4da4, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_1 */
339
- { 0x4d88, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_2 */
340
- { 0x4da8, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_2 */
341
- { 0x4d8c, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_3 */
342
- { 0x4dac, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_3 */
343
- { 0x4d90, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_4 */
344
- { 0x4db0, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_4 */
345
- { 0x4d94, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_5 */
346
- { 0x4db4, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_5 */
347
- { 0x4d98, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_RIGHT_6 */
348
- { 0x4db8, 0x0000004a }, /* 2072X_ADC1_AMP_GAIN_LEFT_6 */
349
- { 0x4c04, 0x00000000 }, /* 2072X_ADC1_CONNECTION_SELECT_CONTROL */
350
- { 0x4c14, 0x00000433 }, /* 2072X_ADC1_POWER_STATE */
351
- { 0x4c18, 0x00000000 }, /* 2072X_ADC1_CONVERTER_STREAM_CHANNEL */
352
- { 0x53c8, 0x00000031 }, /* 2072X_ADC2_CONVERTER_FORMAT */
353
- { 0x5180, 0x0000004a }, /* 2072X_ADC2_AMP_GAIN_RIGHT_0 */
354
- { 0x51a0, 0x0000004a }, /* 2072X_ADC2_AMP_GAIN_LEFT_0 */
355
- { 0x5184, 0x0000004a }, /* 2072X_ADC2_AMP_GAIN_RIGHT_1 */
356
- { 0x51a4, 0x0000004a }, /* 2072X_ADC2_AMP_GAIN_LEFT_1 */
357
- { 0x5188, 0x0000004a }, /* 2072X_ADC2_AMP_GAIN_RIGHT_2 */
358
- { 0x51a8, 0x0000004a }, /* 2072X_ADC2_AMP_GAIN_LEFT_2 */
359
- { 0x5004, 0x00000000 }, /* 2072X_ADC2_CONNECTION_SELECT_CONTROL */
360
- { 0x5014, 0x00000433 }, /* 2072X_ADC2_POWER_STATE */
361
- { 0x5018, 0x00000000 }, /* 2072X_ADC2_CONVERTER_STREAM_CHANNEL */
362
- { 0x5804, 0x00000000 }, /* 2072X_PORTA_CONNECTION_SELECT_CTRL */
363
- { 0x5814, 0x00000433 }, /* 2072X_PORTA_POWER_STATE */
364
- { 0x581c, 0x000000c0 }, /* 2072X_PORTA_PIN_CTRL */
365
- { 0x5820, 0x00000000 }, /* 2072X_PORTA_UNSOLICITED_RESPONSE */
366
- { 0x5824, 0x00000000 }, /* 2072X_PORTA_PIN_SENSE */
367
- { 0x5830, 0x00000002 }, /* 2072X_PORTA_EAPD_BTL */
368
- { 0x6014, 0x00000433 }, /* 2072X_PORTB_POWER_STATE */
369
- { 0x601c, 0x00000000 }, /* 2072X_PORTB_PIN_CTRL */
370
- { 0x6020, 0x00000000 }, /* 2072X_PORTB_UNSOLICITED_RESPONSE */
371
- { 0x6024, 0x00000000 }, /* 2072X_PORTB_PIN_SENSE */
372
- { 0x6030, 0x00000002 }, /* 2072X_PORTB_EAPD_BTL */
373
- { 0x6180, 0x00000000 }, /* 2072X_PORTB_GAIN_RIGHT */
374
- { 0x61a0, 0x00000000 }, /* 2072X_PORTB_GAIN_LEFT */
375
- { 0x6814, 0x00000433 }, /* 2072X_PORTC_POWER_STATE */
376
- { 0x681c, 0x00000000 }, /* 2072X_PORTC_PIN_CTRL */
377
- { 0x6980, 0x00000000 }, /* 2072X_PORTC_GAIN_RIGHT */
378
- { 0x69a0, 0x00000000 }, /* 2072X_PORTC_GAIN_LEFT */
379
- { 0x6414, 0x00000433 }, /* 2072X_PORTD_POWER_STATE */
380
- { 0x641c, 0x00000020 }, /* 2072X_PORTD_PIN_CTRL */
381
- { 0x6420, 0x00000000 }, /* 2072X_PORTD_UNSOLICITED_RESPONSE */
382
- { 0x6424, 0x00000000 }, /* 2072X_PORTD_PIN_SENSE */
383
- { 0x6580, 0x00000000 }, /* 2072X_PORTD_GAIN_RIGHT */
384
- { 0x65a0, 0x00000000 }, /* 2072X_PORTD_GAIN_LEFT */
385
- { 0x7404, 0x00000000 }, /* 2072X_PORTE_CONNECTION_SELECT_CTRL */
386
- { 0x7414, 0x00000433 }, /* 2072X_PORTE_POWER_STATE */
387
- { 0x741c, 0x00000040 }, /* 2072X_PORTE_PIN_CTRL */
388
- { 0x7420, 0x00000000 }, /* 2072X_PORTE_UNSOLICITED_RESPONSE */
389
- { 0x7424, 0x00000000 }, /* 2072X_PORTE_PIN_SENSE */
390
- { 0x7430, 0x00000002 }, /* 2072X_PORTE_EAPD_BTL */
391
- { 0x7580, 0x00000000 }, /* 2072X_PORTE_GAIN_RIGHT */
392
- { 0x75a0, 0x00000000 }, /* 2072X_PORTE_GAIN_LEFT */
393
- { 0x7814, 0x00000433 }, /* 2072X_PORTF_POWER_STATE */
394
- { 0x781c, 0x00000000 }, /* 2072X_PORTF_PIN_CTRL */
395
- { 0x7820, 0x00000000 }, /* 2072X_PORTF_UNSOLICITED_RESPONSE */
396
- { 0x7824, 0x00000000 }, /* 2072X_PORTF_PIN_SENSE */
397
- { 0x7980, 0x00000000 }, /* 2072X_PORTF_GAIN_RIGHT */
398
- { 0x79a0, 0x00000000 }, /* 2072X_PORTF_GAIN_LEFT */
399
- { 0x5c14, 0x00000433 }, /* 2072X_PORTG_POWER_STATE */
400
- { 0x5c1c, 0x00000040 }, /* 2072X_PORTG_PIN_CTRL */
401
- { 0x5c04, 0x00000000 }, /* 2072X_PORTG_CONNECTION_SELECT_CTRL */
402
- { 0x5c30, 0x00000002 }, /* 2072X_PORTG_EAPD_BTL */
403
- { 0x8814, 0x00000433 }, /* 2072X_PORTM_POWER_STATE */
404
- { 0x881c, 0x00000000 }, /* 2072X_PORTM_PIN_CTRL */
405
- { 0x8804, 0x00000000 }, /* 2072X_PORTM_CONNECTION_SELECT_CTRL */
406
- { 0x8830, 0x00000002 }, /* 2072X_PORTM_EAPD_BTL */
407
- { 0x5414, 0x00000433 }, /* 2072X_MIXER_POWER_STATE */
408
- { 0x5580, 0x0000004a }, /* 2072X_MIXER_GAIN_RIGHT_0 */
409
- { 0x55a0, 0x0000004a }, /* 2072X_MIXER_GAIN_LEFT_0 */
410
- { 0x5584, 0x0000004a }, /* 2072X_MIXER_GAIN_RIGHT_1 */
411
- { 0x55a4, 0x0000004a }, /* 2072X_MIXER_GAIN_LEFT_1 */
412
- { 0x6d00, 0x0000720c }, /* 2072X_EQ_ENABLE_BYPASS */
413
- { 0x6d10, 0x040065a4 }, /* 2072X_SPKR_DRC_ENABLE_STEP */
414
- { 0x6d14, 0x007b0024 }, /* 2072X_SPKR_DRC_CONTROL */
415
- { 0X6D18, 0x00000000 }, /* 2072X_SPKR_DRC_TEST */
416
- { 0x6d80, 0x001f008a }, /* 2072X_DIGITAL_BIOS_TEST0 */
417
- { 0x6d84, 0x00990026 }, /* 2072X_DIGITAL_BIOS_TEST2 */
418
- { 0x6e00, 0x00010001 }, /* 2072X_I2SPCM_CONTROL1 */
419
- { 0x6e04, 0x00000000 }, /* 2072X_I2SPCM_CONTROL2 */
420
- { 0x6e08, 0x00000000 }, /* 2072X_I2SPCM_CONTROL3 */
421
- { 0x6e0c, 0x00000000 }, /* 2072X_I2SPCM_CONTROL4 */
422
- { 0x6e10, 0x00000000 }, /* 2072X_I2SPCM_CONTROL5 */
423
- { 0x6e18, 0x00000000 }, /* 2072X_I2SPCM_CONTROL6 */
424
- { 0x6e14, 0x00000000 }, /* 2072X_UM_INTERRUPT_CRTL_E */
425
- { 0x7108, 0x00000000 }, /*2072X_CODEC_TEST2 */
426
- { 0x7124, 0x00000004 }, /*2072X_CODEC_TEST9 */
427
- { 0x7310, 0x00000600 }, /* 2072X_CODEC_TEST20 */
428
- { 0x7328, 0x00000208 }, /* 2072X_CODEC_TEST26 */
429
- { 0x7190, 0x00000000 }, /* 2072X_ANALOG_TEST4 */
430
- { 0x7194, 0x00000000 }, /* 2072X_ANALOG_TEST5 */
431
- { 0x7198, 0x0000059a }, /* 2072X_ANALOG_TEST6 */
432
- { 0x719c, 0x000000a7 }, /* 2072X_ANALOG_TEST7 */
433
- { 0x71a0, 0x00000017 }, /* 2072X_ANALOG_TEST8 */
434
- { 0x71a4, 0x00000000 }, /* 2072X_ANALOG_TEST9 */
435
- { 0x71a8, 0x00000285 }, /* 2072X_ANALOG_TEST10 */
436
- { 0x71ac, 0x00000000 }, /* 2072X_ANALOG_TEST11 */
437
- { 0x71b0, 0x00000000 }, /* 2072X_ANALOG_TEST12 */
438
- { 0x71b4, 0x00000000 }, /* 2072X_ANALOG_TEST13 */
439
- { 0x7204, 0x00000242 }, /* 2072X_DIGITAL_TEST1 */
440
- { 0x7224, 0x00000000 }, /* 2072X_DIGITAL_TEST11 */
441
- { 0x7230, 0x00000084 }, /* 2072X_DIGITAL_TEST12 */
442
- { 0x723c, 0x00000077 }, /* 2072X_DIGITAL_TEST15 */
443
- { 0x7080, 0x00000021 }, /* 2072X_DIGITAL_TEST16 */
444
- { 0x7084, 0x00000018 }, /* 2072X_DIGITAL_TEST17 */
445
- { 0x7088, 0x00000024 }, /* 2072X_DIGITAL_TEST18 */
446
- { 0x708c, 0x00000001 }, /* 2072X_DIGITAL_TEST19 */
447
- { 0x7090, 0x00000002 }, /* 2072X_DIGITAL_TEST20 */
96
+ { CX2072X_AFG_POWER_STATE, 0x00000003 },
97
+ { CX2072X_UM_RESPONSE, 0x00000000 },
98
+ { CX2072X_GPIO_DATA, 0x00000000 },
99
+ { CX2072X_GPIO_ENABLE, 0x00000000 },
100
+ { CX2072X_GPIO_DIRECTION, 0x00000000 },
101
+ { CX2072X_GPIO_WAKE, 0x00000000 },
102
+ { CX2072X_GPIO_UM_ENABLE, 0x00000000 },
103
+ { CX2072X_GPIO_STICKY_MASK, 0x00000000 },
104
+ { CX2072X_DAC1_CONVERTER_FORMAT, 0x00000031 },
105
+ { CX2072X_DAC1_AMP_GAIN_RIGHT, 0x0000004a },
106
+ { CX2072X_DAC1_AMP_GAIN_LEFT, 0x0000004a },
107
+ { CX2072X_DAC1_POWER_STATE, 0x00000433 },
108
+ { CX2072X_DAC1_CONVERTER_STREAM_CHANNEL, 0x00000000 },
109
+ { CX2072X_DAC1_EAPD_ENABLE, 0x00000000 },
110
+ { CX2072X_DAC2_CONVERTER_FORMAT, 0x00000031 },
111
+ { CX2072X_DAC2_AMP_GAIN_RIGHT, 0x0000004a },
112
+ { CX2072X_DAC2_AMP_GAIN_LEFT, 0x0000004a },
113
+ { CX2072X_DAC2_POWER_STATE, 0x00000433 },
114
+ { CX2072X_DAC2_CONVERTER_STREAM_CHANNEL, 0x00000000 },
115
+ { CX2072X_ADC1_CONVERTER_FORMAT, 0x00000031 },
116
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_0, 0x0000004a },
117
+ { CX2072X_ADC1_AMP_GAIN_LEFT_0, 0x0000004a },
118
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_1, 0x0000004a },
119
+ { CX2072X_ADC1_AMP_GAIN_LEFT_1, 0x0000004a },
120
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_2, 0x0000004a },
121
+ { CX2072X_ADC1_AMP_GAIN_LEFT_2, 0x0000004a },
122
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_3, 0x0000004a },
123
+ { CX2072X_ADC1_AMP_GAIN_LEFT_3, 0x0000004a },
124
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_4, 0x0000004a },
125
+ { CX2072X_ADC1_AMP_GAIN_LEFT_4, 0x0000004a },
126
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_5, 0x0000004a },
127
+ { CX2072X_ADC1_AMP_GAIN_LEFT_5, 0x0000004a },
128
+ { CX2072X_ADC1_AMP_GAIN_RIGHT_6, 0x0000004a },
129
+ { CX2072X_ADC1_AMP_GAIN_LEFT_6, 0x0000004a },
130
+ { CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 0x00000000 },
131
+ { CX2072X_ADC1_POWER_STATE, 0x00000433 },
132
+ { CX2072X_ADC1_CONVERTER_STREAM_CHANNEL, 0x00000000 },
133
+ { CX2072X_ADC2_CONVERTER_FORMAT, 0x00000031 },
134
+ { CX2072X_ADC2_AMP_GAIN_RIGHT_0, 0x0000004a },
135
+ { CX2072X_ADC2_AMP_GAIN_LEFT_0, 0x0000004a },
136
+ { CX2072X_ADC2_AMP_GAIN_RIGHT_1, 0x0000004a },
137
+ { CX2072X_ADC2_AMP_GAIN_LEFT_1, 0x0000004a },
138
+ { CX2072X_ADC2_AMP_GAIN_RIGHT_2, 0x0000004a },
139
+ { CX2072X_ADC2_AMP_GAIN_LEFT_2, 0x0000004a },
140
+ { CX2072X_ADC2_CONNECTION_SELECT_CONTROL, 0x00000000 },
141
+ { CX2072X_ADC2_POWER_STATE, 0x00000433 },
142
+ { CX2072X_ADC2_CONVERTER_STREAM_CHANNEL, 0x00000000 },
143
+ { CX2072X_PORTA_CONNECTION_SELECT_CTRL, 0x00000000 },
144
+ { CX2072X_PORTA_POWER_STATE, 0x00000433 },
145
+ { CX2072X_PORTA_PIN_CTRL, 0x000000c0 },
146
+ { CX2072X_PORTA_UNSOLICITED_RESPONSE, 0x00000000 },
147
+ { CX2072X_PORTA_PIN_SENSE, 0x00000000 },
148
+ { CX2072X_PORTA_EAPD_BTL, 0x00000002 },
149
+ { CX2072X_PORTB_POWER_STATE, 0x00000433 },
150
+ { CX2072X_PORTB_PIN_CTRL, 0x00000000 },
151
+ { CX2072X_PORTB_UNSOLICITED_RESPONSE, 0x00000000 },
152
+ { CX2072X_PORTB_PIN_SENSE, 0x00000000 },
153
+ { CX2072X_PORTB_EAPD_BTL, 0x00000002 },
154
+ { CX2072X_PORTB_GAIN_RIGHT, 0x00000000 },
155
+ { CX2072X_PORTB_GAIN_LEFT, 0x00000000 },
156
+ { CX2072X_PORTC_POWER_STATE, 0x00000433 },
157
+ { CX2072X_PORTC_PIN_CTRL, 0x00000000 },
158
+ { CX2072X_PORTC_GAIN_RIGHT, 0x00000000 },
159
+ { CX2072X_PORTC_GAIN_LEFT, 0x00000000 },
160
+ { CX2072X_PORTD_POWER_STATE, 0x00000433 },
161
+ { CX2072X_PORTD_PIN_CTRL, 0x00000020 },
162
+ { CX2072X_PORTD_UNSOLICITED_RESPONSE, 0x00000000 },
163
+ { CX2072X_PORTD_PIN_SENSE, 0x00000000 },
164
+ { CX2072X_PORTD_GAIN_RIGHT, 0x00000000 },
165
+ { CX2072X_PORTD_GAIN_LEFT, 0x00000000 },
166
+ { CX2072X_PORTE_CONNECTION_SELECT_CTRL, 0x00000000 },
167
+ { CX2072X_PORTE_POWER_STATE, 0x00000433 },
168
+ { CX2072X_PORTE_PIN_CTRL, 0x00000040 },
169
+ { CX2072X_PORTE_UNSOLICITED_RESPONSE, 0x00000000 },
170
+ { CX2072X_PORTE_PIN_SENSE, 0x00000000 },
171
+ { CX2072X_PORTE_EAPD_BTL, 0x00000002 },
172
+ { CX2072X_PORTE_GAIN_RIGHT, 0x00000000 },
173
+ { CX2072X_PORTE_GAIN_LEFT, 0x00000000 },
174
+ { CX2072X_PORTF_POWER_STATE, 0x00000433 },
175
+ { CX2072X_PORTF_PIN_CTRL, 0x00000000 },
176
+ { CX2072X_PORTF_UNSOLICITED_RESPONSE, 0x00000000 },
177
+ { CX2072X_PORTF_PIN_SENSE, 0x00000000 },
178
+ { CX2072X_PORTF_GAIN_RIGHT, 0x00000000 },
179
+ { CX2072X_PORTF_GAIN_LEFT, 0x00000000 },
180
+ { CX2072X_PORTG_POWER_STATE, 0x00000433 },
181
+ { CX2072X_PORTG_PIN_CTRL, 0x00000040 },
182
+ { CX2072X_PORTG_CONNECTION_SELECT_CTRL, 0x00000000 },
183
+ { CX2072X_PORTG_EAPD_BTL, 0x00000002 },
184
+ { CX2072X_PORTM_POWER_STATE, 0x00000433 },
185
+ { CX2072X_PORTM_PIN_CTRL, 0x00000000 },
186
+ { CX2072X_PORTM_CONNECTION_SELECT_CTRL, 0x00000000 },
187
+ { CX2072X_PORTM_EAPD_BTL, 0x00000002 },
188
+ { CX2072X_MIXER_POWER_STATE, 0x00000433 },
189
+ { CX2072X_MIXER_GAIN_RIGHT_0, 0x0000004a },
190
+ { CX2072X_MIXER_GAIN_LEFT_0, 0x0000004a },
191
+ { CX2072X_MIXER_GAIN_RIGHT_1, 0x0000004a },
192
+ { CX2072X_MIXER_GAIN_LEFT_1, 0x0000004a },
193
+ { CX2072X_SPKR_DRC_ENABLE_STEP, 0x040065a4 },
194
+ { CX2072X_SPKR_DRC_CONTROL, 0x007b0024 },
195
+ { CX2072X_SPKR_DRC_TEST, 0x00000000 },
196
+ { CX2072X_DIGITAL_BIOS_TEST0, 0x001f008a },
197
+ { CX2072X_DIGITAL_BIOS_TEST2, 0x00990026 },
198
+ { CX2072X_I2SPCM_CONTROL1, 0x00010001 },
199
+ { CX2072X_I2SPCM_CONTROL2, 0x00000000 },
200
+ { CX2072X_I2SPCM_CONTROL3, 0x00000000 },
201
+ { CX2072X_I2SPCM_CONTROL4, 0x00000000 },
202
+ { CX2072X_I2SPCM_CONTROL5, 0x00000000 },
203
+ { CX2072X_I2SPCM_CONTROL6, 0x00000000 },
204
+ { CX2072X_UM_INTERRUPT_CRTL_E, 0x00000000 },
205
+ { CX2072X_CODEC_TEST2, 0x00000000 },
206
+ { CX2072X_CODEC_TEST9, 0x00000004 },
207
+ { CX2072X_CODEC_TEST20, 0x00000600 },
208
+ { CX2072X_CODEC_TEST26, 0x00000208 },
209
+ { CX2072X_ANALOG_TEST4, 0x00000000 },
210
+ { CX2072X_ANALOG_TEST5, 0x00000000 },
211
+ { CX2072X_ANALOG_TEST6, 0x0000059a },
212
+ { CX2072X_ANALOG_TEST7, 0x000000a7 },
213
+ { CX2072X_ANALOG_TEST8, 0x00000017 },
214
+ { CX2072X_ANALOG_TEST9, 0x00000000 },
215
+ { CX2072X_ANALOG_TEST10, 0x00000285 },
216
+ { CX2072X_ANALOG_TEST11, 0x00000000 },
217
+ { CX2072X_ANALOG_TEST12, 0x00000000 },
218
+ { CX2072X_ANALOG_TEST13, 0x00000000 },
219
+ { CX2072X_DIGITAL_TEST1, 0x00000242 },
220
+ { CX2072X_DIGITAL_TEST11, 0x00000000 },
221
+ { CX2072X_DIGITAL_TEST12, 0x00000084 },
222
+ { CX2072X_DIGITAL_TEST15, 0x00000077 },
223
+ { CX2072X_DIGITAL_TEST16, 0x00000021 },
224
+ { CX2072X_DIGITAL_TEST17, 0x00000018 },
225
+ { CX2072X_DIGITAL_TEST18, 0x00000024 },
226
+ { CX2072X_DIGITAL_TEST19, 0x00000001 },
227
+ { CX2072X_DIGITAL_TEST20, 0x00000002 },
448228 };
449229
450230 /*
451
- * cx2072x patch.
231
+ * register initialization
452232 */
453
-static const struct reg_sequence cx2072x_patch[] = {
454
- { 0x71A4, 0x080 }, /* DC offset Calibration */
455
- { 0x71a8, 0x287 }, /* Set max spk power to 1.5 W */
456
- { 0x7328, 0xa8c }, /* Set average spk power to 1.5W*/
457
- { 0x7310, 0xf01 }, /* */
458
- { 0x7328, 0xa8f }, /* */
459
- { 0x7124, 0x001 }, /* Enable 30 Hz High pass filter*/
460
- { 0x718c, 0x300 }, /* Disable PCBEEP pad */
461
- { 0x731c, 0x100 }, /* Disable SnM mode */
462
- { 0x641c, 0x020 }, /* Enable PortD input */
463
- { 0x0458, 0x040 }, /* Enable GPIO7 pin for button */
464
- { 0x0464, 0x040 }, /* Enable UM for GPIO7 */
465
- { 0x0420, 0x080 }, /* Enable button response */
466
- { 0x7230, 0x0c4 }, /* Enable headset button */
467
- { 0x7200, 0x415 }, /* Power down class-d during idle*/
233
+static const struct reg_sequence cx2072x_reg_init[] = {
234
+ { CX2072X_ANALOG_TEST9, 0x080 }, /* DC offset Calibration */
235
+ { CX2072X_CODEC_TEST26, 0x65f }, /* Disable the PA */
236
+ { CX2072X_ANALOG_TEST10, 0x289 }, /* Set the speaker output gain */
237
+ { CX2072X_CODEC_TEST20, 0xf05 },
238
+ { CX2072X_CODEC_TESTXX, 0x380 },
239
+ { CX2072X_CODEC_TEST26, 0xb90 },
240
+ { CX2072X_CODEC_TEST9, 0x001 }, /* Enable 30 Hz High pass filter */
241
+ { CX2072X_ANALOG_TEST3, 0x300 }, /* Disable PCBEEP pad */
242
+ { CX2072X_CODEC_TEST24, 0x100 }, /* Disable SnM mode */
243
+ { CX2072X_PORTD_PIN_CTRL, 0x020 }, /* Enable PortD input */
244
+ { CX2072X_GPIO_ENABLE, 0x040 }, /* Enable GPIO7 pin for button */
245
+ { CX2072X_GPIO_UM_ENABLE, 0x040 }, /* Enable UM for GPIO7 */
246
+ { CX2072X_UM_RESPONSE, 0x080 }, /* Enable button response */
247
+ { CX2072X_DIGITAL_TEST12, 0x0c4 }, /* Enable headset button */
248
+ { CX2072X_DIGITAL_TEST0, 0x415 }, /* Power down class-D during idle */
249
+ { CX2072X_I2SPCM_CONTROL2, 0x00f }, /* Enable I2S TX */
250
+ { CX2072X_I2SPCM_CONTROL3, 0x00f }, /* Enable I2S RX */
468251 };
469252
470
-/* return register size */
471
-static unsigned int cx2072x_register_size(struct device *dev,
472
- unsigned int reg)
253
+static unsigned int cx2072x_register_size(unsigned int reg)
473254 {
474255 switch (reg) {
475256 case CX2072X_VENDOR_ID:
....@@ -487,7 +268,6 @@
487268 case CX2072X_I2SPCM_CONTROL6:
488269 case CX2072X_UM_INTERRUPT_CRTL_E:
489270 case CX2072X_EQ_G_COEFF:
490
- /* case CX2072X_SPKR_DRC_ENABLE_STEP: */
491271 case CX2072X_SPKR_DRC_CONTROL:
492272 case CX2072X_SPKR_DRC_TEST:
493273 case CX2072X_DIGITAL_BIOS_TEST0:
....@@ -533,1267 +313,6 @@
533313 return 1;
534314 }
535315 }
536
-
537
-#ifdef CXDBG_REG_DUMP
538
-static const char *cx2072x_get_reg_name(struct device *dev, unsigned int reg)
539
-{
540
- int i;
541
-
542
- for (i = 0; i < ARRAY_SIZE(cx2072x_regs); i++)
543
- if (cx2072x_regs[i].addr == reg)
544
- return cx2072x_regs[i].name;
545
-
546
- dev_err(dev, "Unknown reg %08x\n", reg);
547
-
548
- return "Unknown reg";
549
-}
550
-#endif
551
-
552
-static int cx2072x_reg_write(void *context, unsigned int reg,
553
- unsigned int value)
554
-{
555
- struct i2c_client *client = context;
556
- unsigned int i;
557
- unsigned int size;
558
- u8 buf[6];
559
- int ret;
560
- struct device *dev = &client->dev;
561
-
562
- size = cx2072x_register_size(dev, reg);
563
- if (size == 0)
564
- return -EINVAL;
565
-#ifdef CXDBG_REG_DUMP
566
- dev_dbg(dev, "I2C write address %40s,%d <= %08x\n",
567
- cx2072x_get_reg_name(dev, reg), size, value);
568
-#endif
569
-
570
- if (reg == CX2072X_UM_INTERRUPT_CRTL_E) {
571
- /* workaround to update the MSB byte only */
572
- reg += 3;
573
- size = 1;
574
- value >>= 24;
575
- }
576
-
577
- buf[0] = reg >> 8;
578
- buf[1] = reg & 0xff;
579
-
580
- for (i = 2; i < (size + 2); ++i) {
581
- buf[i] = value;
582
- value >>= 8;
583
- }
584
-
585
- ret = i2c_master_send(client, buf, size + 2);
586
- if (ret == size + 2) {
587
- ret = 0;
588
- } else if (ret < 0) {
589
- dev_err(dev,
590
- "I2C write address failed\n");
591
- } else {
592
- dev_err(dev,
593
- "I2C write failed\n");
594
- ret = -EIO;
595
- }
596
- return ret;
597
-}
598
-
599
-static int cx2072x_reg_bulk_write(struct snd_soc_component *component,
600
- unsigned int reg, const void *val,
601
- size_t val_count)
602
-{
603
- /* fix me */
604
- struct i2c_client *client = to_i2c_client(component->dev);
605
- u8 buf[2 + MAC_EQ_COEFF];
606
- int ret;
607
- struct device *dev = &client->dev;
608
-
609
-#ifdef CXDBG_REG_DUMP
610
- dev_dbg(dev, "I2C bulk write address %40s,%ld\n",
611
- cx2072x_get_reg_name(dev, reg), val_count);
612
-#endif
613
-
614
- if (val_count > MAC_EQ_COEFF) {
615
- dev_err(dev, "%s failed, writing count = %ld\n", __func__, val_count);
616
- return -EINVAL;
617
- }
618
-
619
- buf[0] = reg >> 8;
620
- buf[1] = reg & 0xff;
621
-
622
- memcpy(&buf[2], val, val_count);
623
-
624
- ret = i2c_master_send(client, buf, val_count + 2);
625
- if (ret == val_count + 2) {
626
- return 0;
627
- } else if (ret < 0) {
628
- dev_err(dev,
629
- "I2C bulk write address failed\n");
630
- } else {
631
- dev_err(dev,
632
- "I2C bulk write address failed\n");
633
- ret = -EIO;
634
- }
635
- return ret;
636
-}
637
-
638
-/* get suggested pre_div valuce from mclk frequency */
639
-static unsigned int get_div_from_mclk(unsigned int mclk)
640
-{
641
- unsigned int div = 8;
642
- int i = 0;
643
-
644
- for (i = 0; i < ARRAY_SIZE(MCLK_PRE_DIV); i++) {
645
- if (mclk <= MCLK_PRE_DIV[i].mclk) {
646
- div = MCLK_PRE_DIV[i].div;
647
- break;
648
- }
649
- }
650
- return div;
651
-}
652
-
653
-static int cx2072x_reg_read(void *context, unsigned int reg,
654
- unsigned int *value)
655
-{
656
- int ret;
657
- unsigned int size;
658
- u8 send_buf[2];
659
- unsigned int recv_buf = 0;
660
- struct i2c_client *client = context;
661
- struct i2c_msg msgs[2];
662
- struct device *dev = &client->dev;
663
-
664
- size = cx2072x_register_size(dev, reg);
665
- if (size == 0)
666
- return -EINVAL;
667
-
668
- send_buf[0] = reg >> 8;
669
- send_buf[1] = reg & 0xff;
670
-
671
- msgs[0].addr = client->addr;
672
- msgs[0].len = sizeof(send_buf);
673
- msgs[0].buf = send_buf;
674
- msgs[0].flags = 0;
675
-
676
- msgs[1].addr = client->addr;
677
- msgs[1].len = size;
678
- msgs[1].buf = (uint8_t *)&recv_buf;
679
- msgs[1].flags = I2C_M_RD;
680
-
681
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
682
- if (ret < 0) {
683
- dev_err(dev,
684
- "Failed to register codec: %d\n", ret);
685
- return ret;
686
- } else if (ret != ARRAY_SIZE(msgs)) {
687
- dev_err(dev,
688
- "Failed to register codec: %d\n", ret);
689
- return -EIO;
690
- }
691
-
692
- *value = recv_buf;
693
-
694
-#ifdef CXDBG_REG_DUMP
695
- dev_dbg(dev,
696
- "I2C read address %40s,%d => %08x\n",
697
- cx2072x_get_reg_name(dev, reg), size, *value);
698
-#endif
699
- return 0;
700
-}
701
-
702
-static int cx2072x_config_headset_det(struct cx2072x_priv *cx2072x)
703
-{
704
- const int interrupt_gpio_pin = 1;
705
-
706
- dev_dbg(cx2072x->dev,
707
- "Configure interrupt pin: %d\n", interrupt_gpio_pin);
708
- /* No-sticky input type */
709
- regmap_write(cx2072x->regmap, CX2072X_GPIO_STICKY_MASK, 0x1f);
710
- /* Use GPOI0 as interrupt output pin */
711
- regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0x12 << 24);
712
-
713
- /* Enables unsolitited message on PortA */
714
- regmap_write(cx2072x->regmap, CX2072X_PORTA_UNSOLICITED_RESPONSE, 0x80);
715
-
716
- /* support both nokia and apple headset set. Monitor time = 275 ms */
717
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST15, 0x73);
718
-
719
- /* Disable TIP detection*/
720
- regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST12, 0x300);
721
-
722
- /* Switch MusicD3Live pin to GPIO */
723
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST1, 0);
724
-
725
- /*
726
- * invert JSENSE if necessary
727
- * regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_TEST12,
728
- * 0x200, 0x200);
729
- */
730
-
731
- return 0;
732
-}
733
-
734
-static int cx2072x_config_pll(struct cx2072x_priv *cx2072x)
735
-{
736
- struct device *dev = cx2072x->dev;
737
- unsigned int pre_div;
738
- unsigned int pre_div_val;
739
- unsigned int pll_input;
740
- unsigned int pll_output;
741
- unsigned int int_div;
742
- unsigned int frac_div;
743
- u64 frac_num = 0;
744
- unsigned int sample_rate = cx2072x->sample_rate;
745
- int pt_sample_per_sync = 2;
746
- int pt_clock_per_sample = 96;
747
-
748
- switch (sample_rate) {
749
- case 48000:
750
- case 32000:
751
- case 24000:
752
- case 16000:
753
- break;
754
- case 96000:
755
- pt_sample_per_sync = 1;
756
- pt_clock_per_sample = 48;
757
- break;
758
- case 192000:
759
- pt_sample_per_sync = 0;
760
- pt_clock_per_sample = 24;
761
- break;
762
- default:
763
- dev_err(dev, "Unsupported sample rate %d\n", sample_rate);
764
- return -EINVAL;
765
- }
766
-
767
- /* Configure PLL settings */
768
- pre_div = get_div_from_mclk(cx2072x->mclk);
769
- pll_input = cx2072x->mclk / pre_div;
770
- pll_output = sample_rate * 3072;
771
- int_div = pll_output / pll_input;
772
- frac_div = pll_output - (int_div * pll_input);
773
-
774
- if (frac_div) {
775
- frac_div *= 1000;
776
- frac_div /= pll_input;
777
- frac_num = ((4000ULL + frac_div) * ((1 << 20) - 4));
778
- frac_num = div_u64(frac_num, 7);
779
- frac_num = div_u64(frac_num + 499, 1000);
780
- }
781
- pre_div_val = (pre_div - 1) * 2;
782
-
783
- regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST4, 0X40 |
784
- (pre_div_val << 8));
785
- if (frac_div == 0) {
786
- /* Int mode */
787
- regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST7, 0x100);
788
- } else {
789
- /* frac mode */
790
- regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST6,
791
- frac_num & 0xfff);
792
- regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST7,
793
- (unsigned char)(frac_num >> 12));
794
- }
795
- int_div--;
796
- regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST8,
797
- (unsigned char)int_div & 0xffff);
798
-
799
- /* configure PLL tracking */
800
- if (frac_div == 0) {
801
- /* disable PLL tracking */
802
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST16, 0x00);
803
- } else {
804
- /* configure and enable PLL tracking */
805
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST16,
806
- (pt_sample_per_sync << 4) & 0xf0);
807
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST17,
808
- pt_clock_per_sample);
809
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST18,
810
- pt_clock_per_sample * 3 / 2);
811
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST19, 0x01);
812
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST20, 0x02);
813
- regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_TEST16,
814
- 0X01, 0X01);
815
- }
816
- return 0;
817
-}
818
-
819
-static int cx2072x_config_i2spcm(struct cx2072x_priv *cx2072x)
820
-{
821
- struct device *dev = cx2072x->dev;
822
- unsigned int bclk_rate = 0;
823
- int is_i2s = 0;
824
- int has_one_bit_delay = 0;
825
- int is_frame_inv = 0;
826
- int is_bclk_inv = 0;
827
- int pulse_len = 1;
828
- int frame_len = cx2072x->frame_size;
829
- int sample_size = cx2072x->sample_size;
830
- int i2s_right_slot;
831
- int i2s_right_pause_interval = 0;
832
- int i2s_right_pause_pos;
833
- int is_big_endian = 1;
834
- const int slots_per_channel = cx2072x->tdm_slot_width / BITS_PER_SLOT;
835
- const unsigned int fmt = cx2072x->dai_fmt;
836
- u64 mod, div;
837
- union REG_I2SPCM_CTRL_REG1 reg1;
838
- union REG_I2SPCM_CTRL_REG2 reg2;
839
- union REG_I2SPCM_CTRL_REG3 reg3;
840
- union REG_I2SPCM_CTRL_REG4 reg4;
841
- union REG_I2SPCM_CTRL_REG5 reg5;
842
- union REG_I2SPCM_CTRL_REG6 reg6;
843
- union REG_DIGITAL_BIOS_TEST2 reg_dbt2;
844
-
845
- reg4.ulval = 0x0;
846
- reg6.ulval = 0x0;
847
-
848
- if (frame_len <= 0) {
849
- dev_err(dev, "Incorrect frame len %d\n", frame_len);
850
- return -EINVAL;
851
- }
852
-
853
- if (sample_size <= 0) {
854
- dev_err(dev, "Incorrect sample size %d\n", sample_size);
855
- return -EINVAL;
856
- }
857
-
858
- /* fix me */
859
- reg_dbt2.ulval = 0xac;
860
-
861
- /* set master/slave */
862
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
863
- case SND_SOC_DAIFMT_CBM_CFM:
864
- reg2.r.tx_master = 1;
865
- reg3.r.rx_master = 1;
866
- break;
867
- case SND_SOC_DAIFMT_CBS_CFS:
868
- reg2.r.tx_master = 0;
869
- reg3.r.rx_master = 0;
870
- break;
871
- default:
872
- dev_err(dev, "Unsupported DAI master mode\n");
873
- return -EINVAL;
874
- }
875
-
876
- /* set format */
877
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
878
- case SND_SOC_DAIFMT_I2S:
879
- is_i2s = 1;
880
- has_one_bit_delay = 1;
881
- pulse_len = frame_len / 2;
882
- break;
883
- case SND_SOC_DAIFMT_RIGHT_J:
884
- is_i2s = 1;
885
- pulse_len = frame_len / 2;
886
- break;
887
- case SND_SOC_DAIFMT_LEFT_J:
888
- is_i2s = 1;
889
- pulse_len = frame_len / 2;
890
- break;
891
- case SND_SOC_DAIFMT_DSP_A:
892
- has_one_bit_delay = 1;
893
- break;
894
- case SND_SOC_DAIFMT_DSP_B:
895
- break;
896
- default:
897
- dev_err(dev, "Unsupported DAI format\n");
898
- return -EINVAL;
899
- }
900
-
901
- /* clock inversion */
902
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
903
- case SND_SOC_DAIFMT_NB_NF:
904
- is_frame_inv = is_i2s ? 1 : 0;
905
- is_bclk_inv = is_i2s ? 1 : 0;
906
- break;
907
- case SND_SOC_DAIFMT_IB_IF:
908
- is_frame_inv = is_i2s ? 0 : 1;
909
- is_bclk_inv = is_i2s ? 0 : 1;
910
- break;
911
- case SND_SOC_DAIFMT_IB_NF:
912
- is_frame_inv = is_i2s ? 1 : 0;
913
- is_bclk_inv = is_i2s ? 0 : 1;
914
- break;
915
- case SND_SOC_DAIFMT_NB_IF:
916
- is_frame_inv = is_i2s ? 0 : 1;
917
- is_bclk_inv = is_i2s ? 1 : 0;
918
- break;
919
- default:
920
- dev_err(dev, "Unsupported DAI clock inversion\n");
921
- return -EINVAL;
922
- }
923
-
924
- cx2072x->dai_fmt = fmt;
925
-
926
- reg1.r.rx_data_one_line = 1;
927
- reg1.r.tx_data_one_line = 1;
928
-
929
- if (is_i2s) {
930
- i2s_right_slot = (frame_len / 2) / BITS_PER_SLOT;
931
- i2s_right_pause_interval = (frame_len / 2) % BITS_PER_SLOT;
932
- i2s_right_pause_pos = i2s_right_slot * BITS_PER_SLOT;
933
- }
934
-
935
- reg1.r.rx_ws_pol = is_frame_inv;
936
- reg1.r.rx_ws_wid = pulse_len - 1;
937
-
938
- reg1.r.rx_frm_len = frame_len / BITS_PER_SLOT - 1;
939
- reg1.r.rx_sa_size = (sample_size / BITS_PER_SLOT) - 1;
940
-
941
- reg1.r.tx_ws_pol = reg1.r.rx_ws_pol;
942
- reg1.r.tx_ws_wid = pulse_len - 1;
943
- reg1.r.tx_frm_len = reg1.r.rx_frm_len;
944
- reg1.r.tx_sa_size = reg1.r.rx_sa_size;
945
-
946
- reg2.r.tx_endian_sel = is_big_endian ? 0 : 1;
947
- reg2.r.tx_dstart_dly = has_one_bit_delay;
948
-
949
- reg3.r.rx_endian_sel = is_big_endian ? 0 : 1;
950
- reg3.r.rx_dstart_dly = has_one_bit_delay;
951
-
952
- if (is_i2s) {
953
- reg2.r.tx_en_ch1 = 1;
954
- reg2.r.tx_en_ch2 = 1;
955
- reg2.r.tx_slot_1 = 0;
956
- reg2.r.tx_slot_2 = i2s_right_slot;
957
- reg3.r.rx_en_ch1 = 1;
958
- reg3.r.rx_en_ch2 = 1;
959
- reg3.r.rx_slot_1 = 0;
960
- reg3.r.rx_slot_2 = i2s_right_slot;
961
- reg6.r.rx_pause_start_pos = i2s_right_pause_pos;
962
- reg6.r.rx_pause_cycles = i2s_right_pause_interval;
963
- reg6.r.tx_pause_start_pos = i2s_right_pause_pos;
964
- reg6.r.tx_pause_cycles = i2s_right_pause_interval;
965
- } else {
966
- reg2.r.tx_en_ch1 = cx2072x->tdm_tx_mask & 0x01 ? 1 : 0;
967
- reg2.r.tx_en_ch2 = cx2072x->tdm_tx_mask & 0x02 ? 1 : 0;
968
- reg2.r.tx_en_ch3 = cx2072x->tdm_tx_mask & 0x04 ? 1 : 0;
969
- reg2.r.tx_en_ch4 = cx2072x->tdm_tx_mask & 0x08 ? 1 : 0;
970
- reg2.r.tx_slot_1 = 0;
971
- reg2.r.tx_slot_2 = slots_per_channel * 1;
972
- reg2.r.tx_slot_3 = slots_per_channel * 2;
973
- reg2.r.tx_slot_4 = slots_per_channel * 3;
974
-
975
- reg3.r.rx_en_ch1 = cx2072x->tdm_rx_mask & 0x01 ? 1 : 0;
976
- reg3.r.rx_en_ch2 = cx2072x->tdm_rx_mask & 0x02 ? 1 : 0;
977
- reg3.r.rx_en_ch3 = cx2072x->tdm_rx_mask & 0x04 ? 1 : 0;
978
- reg3.r.rx_en_ch4 = cx2072x->tdm_rx_mask & 0x08 ? 1 : 0;
979
- reg3.r.rx_slot_1 = 0;
980
- reg3.r.rx_slot_2 = slots_per_channel * 1;
981
- reg3.r.rx_slot_3 = slots_per_channel * 2;
982
- reg3.r.rx_slot_4 = slots_per_channel * 3;
983
- }
984
- reg_dbt2.r.i2s_bclk_invert = is_bclk_inv;
985
-
986
- reg1.r.rx_data_one_line = 1;
987
- reg1.r.tx_data_one_line = 1;
988
-
989
-#ifdef ENABLE_MIC_POP_WA
990
- /* Mute I2S TX */
991
- reg4.ulval |= 0x2;
992
-#endif
993
- /* Configure the BCLK output */
994
- bclk_rate = cx2072x->sample_rate * frame_len;
995
- reg5.r.i2s_pcm_clk_div_chan_en = 0;
996
- /* disable bclk output before setting new value */
997
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL5, 0);
998
- if (reg2.r.tx_master == 1) {
999
- /* Sets codec as Master mode */
1000
- div = PLL_OUT_HZ_48;
1001
- mod = do_div(div, bclk_rate);
1002
- if (mod) {
1003
- dev_err(dev, "Unsupported BCLK %dHz\n", bclk_rate);
1004
- return -EINVAL;
1005
- }
1006
- reg5.r.i2s_pcm_clk_div = div - 1;
1007
- }
1008
-
1009
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL1, reg1.ulval);
1010
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL2, reg2.ulval);
1011
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL3, reg3.ulval);
1012
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL4, reg4.ulval);
1013
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL6, reg6.ulval);
1014
- regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL5, reg5.ulval);
1015
- /* enable bclk and EAPD input */
1016
- if (cx2072x->rev_id == CX2072X_REV_A2)
1017
- regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2,
1018
- 0x84, 0xFF);
1019
- else
1020
- regmap_write(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2,
1021
- reg_dbt2.ulval);
1022
-
1023
- return 0;
1024
-}
1025
-
1026
-static void cx2072x_dsp_init(struct snd_soc_component *component)
1027
-{
1028
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1029
- int i, j, band;
1030
- unsigned char *pcoef = &cx2072x_eq_coeff_array[0][0];
1031
-
1032
- regmap_write(cx2072x->regmap, CX2072X_EQ_ENABLE_BYPASS, 0x6e0f);
1033
-
1034
- for (i = 0; i < MAX_EQ_BAND; i++) {
1035
- for (j = 0; j < 2; j++) {
1036
- cx2072x_reg_bulk_write(component, CX2072X_EQ_B0_COEFF,
1037
- pcoef + (MAC_EQ_COEFF * i),
1038
- MAC_EQ_COEFF);
1039
- band = i + (j << 3) + (1 << 6);
1040
- regmap_write(cx2072x->regmap, CX2072X_EQ_BAND, band);
1041
- mdelay(5);
1042
- }
1043
- }
1044
-
1045
- cx2072x_reg_bulk_write(component, CX2072X_SPKR_DRC_ENABLE_STEP,
1046
- cx2072x_drc_array, MAX_DRC_REGS);
1047
-}
1048
-
1049
-static void cx2072x_update_dsp(struct snd_soc_component *component)
1050
-{
1051
- unsigned int afg_reg;
1052
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1053
-
1054
- regmap_read(cx2072x->regmap, CX2072X_AFG_POWER_STATE, &afg_reg);
1055
-
1056
- if (!cx2072x->plbk_dsp_changed) {
1057
- /* nothing change */
1058
- return;
1059
- }
1060
-
1061
- if ((afg_reg & 0xf) != 0) {
1062
- /* skip since device is on D3 mode */
1063
- return;
1064
- }
1065
-
1066
- if (cx2072x->plbk_dsp_en && !cx2072x->plbk_dsp_init) {
1067
- cx2072x_dsp_init(component);
1068
- cx2072x->plbk_dsp_init = true;
1069
- }
1070
-
1071
- if (cx2072x->plbk_dsp_en) {
1072
- regmap_write(cx2072x->regmap, CX2072X_EQ_ENABLE_BYPASS,
1073
- 0x6203);
1074
- regmap_write(cx2072x->regmap, CX2072X_SPKR_DRC_ENABLE_STEP,
1075
- 0x65);
1076
- } else {
1077
- /* By pass DRC and EQ */
1078
- regmap_write(cx2072x->regmap, CX2072X_EQ_ENABLE_BYPASS,
1079
- 0x620c);
1080
- regmap_write(cx2072x->regmap, CX2072X_SPKR_DRC_ENABLE_STEP,
1081
- 0xa4);
1082
- }
1083
- cx2072x->plbk_dsp_changed = false;
1084
-}
1085
-
1086
-static int afg_power_ev(struct snd_soc_dapm_widget *w,
1087
- struct snd_kcontrol *kcontrol, int event)
1088
-{
1089
- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1090
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1091
-
1092
- switch (event) {
1093
- case SND_SOC_DAPM_POST_PMU:
1094
- regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST0,
1095
- 0x00, 0x10);
1096
- break;
1097
-
1098
- case SND_SOC_DAPM_PRE_PMD:
1099
- regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST0,
1100
- 0x10, 0x10);
1101
- break;
1102
- }
1103
- return 0;
1104
-}
1105
-
1106
-#ifdef ENABLE_MIC_POP_WA
1107
-/*
1108
- * This work will be called at ADC widget power on time.
1109
- * to reduce initial mic pop noise caused by hardware
1110
- */
1111
-
1112
-static void cx2072x_anit_mic_pop_work(struct work_struct *work)
1113
-{
1114
- struct snd_soc_dapm_context *dapm = container_of(work, struct snd_soc_dapm_context,
1115
- delayed_work.work);
1116
- struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
1117
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1118
-
1119
- dev_dbg(cx2072x->dev, "Unmute I2S TX\n");
1120
- /* Unmute I2S TX */
1121
-
1122
- regmap_update_bits(cx2072x->regmap, CX2072X_I2SPCM_CONTROL4,
1123
- 0x2, 0x0);
1124
-}
1125
-#endif
1126
-
1127
-static int adc1_power_ev(struct snd_soc_dapm_widget *w,
1128
- struct snd_kcontrol *kcontrol, int event)
1129
-{
1130
-#ifdef ENABLE_MIC_POP_WA
1131
- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1132
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1133
-
1134
- switch (event) {
1135
- case SND_SOC_DAPM_POST_PMU:
1136
- /*
1137
- * Umute I2S TX after 300 ms to get around the mic
1138
- * pop noise issue.
1139
- */
1140
- schedule_delayed_work(&codec->dapm.delayed_work,
1141
- msecs_to_jiffies(300));
1142
- break;
1143
-
1144
- case SND_SOC_DAPM_POST_PMD:
1145
- /* Mute TX I2S */
1146
- regmap_update_bits(cx2072x->regmap, CX2072X_I2SPCM_CONTROL4,
1147
- 0x2, 0x2);
1148
- break;
1149
- }
1150
-#endif
1151
- return 0;
1152
-}
1153
-
1154
-static int portg_power_ev(struct snd_soc_dapm_widget *w,
1155
- struct snd_kcontrol *kcontrol, int event)
1156
-{
1157
- struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1158
-
1159
- switch (event) {
1160
- case SND_SOC_DAPM_POST_PMU:
1161
- cx2072x_update_dsp(component);
1162
- break;
1163
- default:
1164
- break;
1165
- }
1166
- return 0;
1167
-}
1168
-
1169
-static int cx2072x_plbk_dsp_info(struct snd_kcontrol *kcontrol,
1170
- struct snd_ctl_elem_info *uinfo)
1171
-{
1172
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1173
- uinfo->count = 1;
1174
- uinfo->value.integer.min = 0;
1175
- uinfo->value.integer.max = 1;
1176
- return 0;
1177
-}
1178
-
1179
-static int cx2072x_plbk_dsp_get(struct snd_kcontrol *kcontrol,
1180
- struct snd_ctl_elem_value *ucontrol)
1181
-{
1182
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1183
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1184
-
1185
- ucontrol->value.integer.value[0] = cx2072x->plbk_dsp_en;
1186
-
1187
- return 0;
1188
-}
1189
-
1190
-static int cx2072x_plbk_dsp_put(struct snd_kcontrol *kcontrol,
1191
- struct snd_ctl_elem_value *ucontrol)
1192
-{
1193
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1194
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1195
- const bool en_dsp = ucontrol->value.integer.value[0];
1196
-
1197
- if (ucontrol->value.integer.value[0] > 1)
1198
- return -EINVAL;
1199
-
1200
- if (cx2072x->plbk_dsp_en != en_dsp) {
1201
- cx2072x->plbk_dsp_en = en_dsp;
1202
- cx2072x->plbk_dsp_changed = true;
1203
- cx2072x_update_dsp(component);
1204
- }
1205
- return 0;
1206
-}
1207
-
1208
-#define CX2072X_PLBK_DSP_SWITCH(xname) {\
1209
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
1210
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
1211
- .info = cx2072x_plbk_dsp_info, \
1212
- .get = cx2072x_plbk_dsp_get, .put = cx2072x_plbk_dsp_put}
1213
-
1214
-static const struct snd_kcontrol_new cx2072x_snd_controls[] = {
1215
- SOC_DOUBLE_R_TLV("PortD Boost", CX2072X_PORTD_GAIN_LEFT,
1216
- CX2072X_PORTD_GAIN_RIGHT, 0, 3, 0, boost_tlv),
1217
- SOC_DOUBLE_R_TLV("PortC Boost", CX2072X_PORTC_GAIN_LEFT,
1218
- CX2072X_PORTC_GAIN_RIGHT, 0, 3, 0, boost_tlv),
1219
- SOC_DOUBLE_R_TLV("PortB Boost", CX2072X_PORTB_GAIN_LEFT,
1220
- CX2072X_PORTB_GAIN_RIGHT, 0, 3, 0, boost_tlv),
1221
-
1222
- SOC_DOUBLE_R_TLV("PortD ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_1,
1223
- CX2072X_ADC1_AMP_GAIN_RIGHT_1, 0, 0x4a, 0, adc_tlv),
1224
- SOC_DOUBLE_R_TLV("PortC ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_2,
1225
- CX2072X_ADC1_AMP_GAIN_RIGHT_2, 0, 0x4a, 0, adc_tlv),
1226
- SOC_DOUBLE_R_TLV("PortB ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_0,
1227
- CX2072X_ADC1_AMP_GAIN_RIGHT_0, 0, 0x4a, 0, adc_tlv),
1228
-
1229
- SOC_DOUBLE_R_TLV("DAC1 Volume", CX2072X_DAC1_AMP_GAIN_LEFT,
1230
- CX2072X_DAC1_AMP_GAIN_RIGHT, 0, 0x4a, 0, dac_tlv),
1231
-
1232
- SOC_DOUBLE_R("DAC1 Mute", CX2072X_DAC1_AMP_GAIN_LEFT,
1233
- CX2072X_DAC1_AMP_GAIN_RIGHT, 7, 1, 0),
1234
-
1235
- SOC_DOUBLE_R_TLV("DAC2 Volume", CX2072X_DAC2_AMP_GAIN_LEFT,
1236
- CX2072X_DAC2_AMP_GAIN_RIGHT, 0, 0x4a, 0, dac_tlv),
1237
-
1238
- CX2072X_PLBK_DSP_SWITCH("Playback DSP Switch"),
1239
-};
1240
-
1241
-/*
1242
- * cx2072x_hs_jack_report: Report jack notification to upper layer
1243
- * @codec : pointer variable to codec having information related to codec
1244
- * @jack : Pointer variable to snd_soc_jack having information of codec
1245
- * and pin number$
1246
- * @report : Provides informaton of whether it is headphone or microphone
1247
- */
1248
-int cx2072x_hs_jack_report(struct snd_soc_component *component)
1249
-{
1250
- unsigned int jack;
1251
- unsigned int type = 0;
1252
- int state = 0;
1253
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1254
-
1255
- regcache_cache_bypass(cx2072x->regmap, true);
1256
- cx2072x->jack_state = CX_JACK_NONE;
1257
- regmap_read(cx2072x->regmap, CX2072X_PORTA_PIN_SENSE, &jack);
1258
- jack = jack >> 24;
1259
- regmap_read(cx2072x->regmap, CX2072X_DIGITAL_TEST11, &type);
1260
- regcache_cache_bypass(cx2072x->regmap, false);
1261
- if (jack == 0x80) {
1262
- type = type >> 8;
1263
-
1264
- if (type & 0x8) {
1265
- state |= SND_JACK_HEADSET;
1266
- cx2072x->jack_state = CX_JACK_APPLE_HEADSET;
1267
- if (type & 0x2)
1268
- state |= SND_JACK_BTN_0;
1269
- } else if (type & 0x4) {
1270
- state |= SND_JACK_HEADPHONE;
1271
- cx2072x->jack_state = CX_JACK_NOKIE_HEADSET;
1272
- } else {
1273
- state |= SND_JACK_HEADPHONE;
1274
- cx2072x->jack_state = CX_JACK_HEADPHONE;
1275
- }
1276
- }
1277
- /* clear interrupt */
1278
- regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0x12 << 24);
1279
-
1280
- dev_err(component->dev, "CX2072X_HSDETECT type=0x%X,Jack state = %x\n",
1281
- type, state);
1282
- return state;
1283
-}
1284
-
1285
-int cx2072x_jack_report(void)
1286
-{
1287
- u32 state, old_state;
1288
-
1289
- if (!cx2072x_component)
1290
- return -1;
1291
-
1292
- msleep(400);
1293
-
1294
- do {
1295
- old_state = cx2072x_hs_jack_report(cx2072x_component);
1296
- msleep(50);
1297
- state = cx2072x_hs_jack_report(cx2072x_component);
1298
- } while (state != old_state);
1299
-
1300
- return state;
1301
-}
1302
-EXPORT_SYMBOL_GPL(cx2072x_jack_report);
1303
-
1304
-static int cx2072x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1305
- unsigned int rx_mask, int slots, int slot_width)
1306
-{
1307
- struct snd_soc_component *component = dai->component;
1308
- struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(component);
1309
-
1310
- if (slots == 0)
1311
- goto out;
1312
-
1313
- switch (rx_mask) {
1314
- case 1 ... 0xf:
1315
- break;
1316
- default:
1317
- return -EINVAL;
1318
- }
1319
-
1320
- switch (tx_mask) {
1321
- case 1 ... 0xf:
1322
- break;
1323
- default:
1324
- return -EINVAL;
1325
- }
1326
-out:
1327
- cx2072x->tdm_rx_mask = rx_mask;
1328
- cx2072x->tdm_tx_mask = tx_mask;
1329
- cx2072x->tdm_slot_width = slot_width;
1330
- cx2072x->tdm_slots = slots;
1331
- return 0;
1332
-}
1333
-
1334
-static int cx2072x_hw_params(struct snd_pcm_substream *substream,
1335
- struct snd_pcm_hw_params *params,
1336
- struct snd_soc_dai *dai)
1337
-{
1338
- struct snd_soc_component *component = dai->component;
1339
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1340
- struct device *dev = component->dev;
1341
- const unsigned int sample_rate = params_rate(params);
1342
- int sample_size, frame_size;
1343
-
1344
- /* Data sizes if not using TDM */
1345
- sample_size = params_width(params);
1346
-
1347
- if (sample_size < 0)
1348
- return sample_size;
1349
-
1350
- frame_size = snd_soc_params_to_frame_size(params);
1351
- if (frame_size < 0)
1352
- return frame_size;
1353
-
1354
- if (cx2072x->bclk_ratio)
1355
- frame_size = cx2072x->bclk_ratio;
1356
-
1357
- switch (sample_rate) {
1358
- case 48000:
1359
- case 32000:
1360
- case 24000:
1361
- case 16000:
1362
- case 96000:
1363
- case 192000:
1364
- break;
1365
- default:
1366
- dev_err(dev, "Unsupported sample rate %d\n", sample_rate);
1367
- return -EINVAL;
1368
- }
1369
-
1370
- dev_dbg(dev, "Sample size %d bits, frame = %d bits, rate = %d Hz\n",
1371
- sample_size, frame_size, sample_rate);
1372
-
1373
- cx2072x->frame_size = frame_size;
1374
- cx2072x->sample_size = sample_size;
1375
- cx2072x->sample_rate = sample_rate;
1376
-
1377
- if (cx2072x->pll_changed) {
1378
- cx2072x_config_pll(cx2072x);
1379
- cx2072x->pll_changed = false;
1380
- }
1381
- if (cx2072x->i2spcm_changed) {
1382
- cx2072x_config_i2spcm(cx2072x);
1383
- cx2072x->i2spcm_changed = false;
1384
- }
1385
- return 0;
1386
-}
1387
-
1388
-static int cx2072x_digital_mute(struct snd_soc_dai *dai, int mute)
1389
-{
1390
- return 0;
1391
-}
1392
-
1393
-static int cx2072x_set_dai_bclk_ratio(struct snd_soc_dai *dai,
1394
- unsigned int ratio)
1395
-{
1396
- struct snd_soc_component *component = dai->component;
1397
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1398
-
1399
- cx2072x->bclk_ratio = ratio;
1400
- return 0;
1401
-}
1402
-
1403
-static int cx2072x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1404
- unsigned int freq, int dir)
1405
-{
1406
- struct snd_soc_component *component = dai->component;
1407
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1408
- struct device *dev = component->dev;
1409
-
1410
- if (freq == 0) {
1411
- dev_dbg(dev, "MCLK: Switch to internal OSC\n");
1412
- return 0;
1413
- }
1414
-
1415
- cx2072x->mclk = freq;
1416
-
1417
- switch (clk_id) {
1418
- case CX2072X_MCLK_EXTERNAL_PLL:
1419
- dev_dbg(dev, "MCLK: Switch to external PLL\n");
1420
- break;
1421
- case CX2072X_MCLK_INTERNAL_OSC:
1422
- dev_err(dev, "Unsupported DAI format\n");
1423
- break;
1424
- default:
1425
- dev_dbg(dev, "the MCLK is not configured\n");
1426
- break;
1427
- }
1428
-
1429
- return 0;
1430
-}
1431
-
1432
-static int cx2072x_set_dai_fmt(struct snd_soc_dai *dai,
1433
- unsigned int fmt)
1434
-{
1435
- struct snd_soc_component *component = dai->component;
1436
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1437
- struct device *dev = component->dev;
1438
-
1439
- /* set master/slave */
1440
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1441
- case SND_SOC_DAIFMT_CBM_CFM:
1442
- case SND_SOC_DAIFMT_CBS_CFS:
1443
- break;
1444
- default:
1445
- dev_err(dev, "Unsupported DAI master mode\n");
1446
- return -EINVAL;
1447
- }
1448
-
1449
- /* set format */
1450
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1451
- case SND_SOC_DAIFMT_I2S:
1452
- case SND_SOC_DAIFMT_RIGHT_J:
1453
- case SND_SOC_DAIFMT_LEFT_J:
1454
- case SND_SOC_DAIFMT_DSP_A:
1455
- case SND_SOC_DAIFMT_DSP_B:
1456
- break;
1457
- default:
1458
- dev_err(dev, "Unsupported DAI format\n");
1459
- return -EINVAL;
1460
- }
1461
-
1462
- /* clock inversion */
1463
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1464
- case SND_SOC_DAIFMT_NB_NF:
1465
- case SND_SOC_DAIFMT_IB_IF:
1466
- case SND_SOC_DAIFMT_IB_NF:
1467
- case SND_SOC_DAIFMT_NB_IF:
1468
- break;
1469
- default:
1470
- dev_err(dev, "Unsupported DAI clock inversion\n");
1471
- return -EINVAL;
1472
- }
1473
- cx2072x->dai_fmt = fmt;
1474
-
1475
- return 0;
1476
-}
1477
-
1478
-static const char * const dac_enum_text[] = {
1479
- "DAC1 Switch", "DAC2 Switch",
1480
-};
1481
-
1482
-static const struct soc_enum porta_dac_enum =
1483
-SOC_ENUM_SINGLE(CX2072X_PORTA_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1484
-
1485
-static const struct snd_kcontrol_new porta_mux =
1486
-SOC_DAPM_ENUM("PortA Mux", porta_dac_enum);
1487
-
1488
-static const struct soc_enum portg_dac_enum =
1489
-SOC_ENUM_SINGLE(CX2072X_PORTG_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1490
-
1491
-static const struct snd_kcontrol_new portg_mux =
1492
-SOC_DAPM_ENUM("PortG Mux", portg_dac_enum);
1493
-
1494
-static const struct soc_enum porte_dac_enum =
1495
-SOC_ENUM_SINGLE(CX2072X_PORTE_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1496
-
1497
-static const struct snd_kcontrol_new porte_mux =
1498
-SOC_DAPM_ENUM("PortE Mux", porte_dac_enum);
1499
-
1500
-static const char * const adc1in_sel_text[] = {
1501
- "PortB Switch", "PortD Switch", "PortC Switch", "Widget15 Switch",
1502
- "PortE Switch", "PortF Switch", "PortH Switch"
1503
-};
1504
-
1505
-static const struct soc_enum adc1in_sel_enum =
1506
-SOC_ENUM_SINGLE(CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 0, 7, adc1in_sel_text);
1507
-
1508
-static const struct snd_kcontrol_new adc1_mux =
1509
-SOC_DAPM_ENUM("ADC1 Mux", adc1in_sel_enum);
1510
-
1511
-#define CX2072X_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, wmask, won_val, \
1512
- woff_val, wevent, wflags) \
1513
- {.id = snd_soc_dapm_supply, .name = wname, .kcontrol_news = NULL, \
1514
- .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \
1515
- .on_val = won_val, .off_val = woff_val, \
1516
- .subseq = wsubseq, .event = wevent, .event_flags = wflags}
1517
-
1518
-#define CX2072X_DAPM_SWITCH(wname, wreg, wshift, wmask, won_val, woff_val, \
1519
- wevent, wflags) \
1520
- {.id = snd_soc_dapm_switch, .name = wname, .kcontrol_news = NULL, \
1521
- .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \
1522
- .on_val = won_val, .off_val = woff_val, \
1523
- .event = wevent, .event_flags = wflags}
1524
-
1525
-#define CX2072X_DAPM_SWITCH(wname, wreg, wshift, wmask, won_val, woff_val, \
1526
- wevent, wflags) \
1527
- {.id = snd_soc_dapm_switch, .name = wname, .kcontrol_news = NULL, \
1528
- .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \
1529
- .on_val = won_val, .off_val = woff_val, \
1530
- .event = wevent, .event_flags = wflags}
1531
-
1532
-#define CX2072X_DAPM_REG_E(wid, wname, wreg, wshift, wmask, won_val, woff_val, \
1533
- wevent, wflags) \
1534
- {.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
1535
- .reg = wreg, .shift = wshift, .mask = wmask, \
1536
- .on_val = won_val, .off_val = woff_val, \
1537
- .event = wevent, .event_flags = wflags}
1538
-
1539
-static const struct snd_soc_dapm_widget cx2072x_dapm_widgets[] = {
1540
- /* Playback */
1541
- SND_SOC_DAPM_AIF_IN("In AIF", "Playback", 0, SND_SOC_NOPM, 0, 0),
1542
-
1543
- SND_SOC_DAPM_REG(snd_soc_dapm_dac, "DAC1", CX2072X_DAC1_POWER_STATE,
1544
- 0, 0xFFF, 0x00, 0x03),
1545
-
1546
- SND_SOC_DAPM_REG(snd_soc_dapm_dac, "DAC2", CX2072X_DAC2_POWER_STATE,
1547
- 0, 0xFFF, 0x00, 0x03),
1548
-
1549
- SND_SOC_DAPM_MUX("PortA Mux", SND_SOC_NOPM, 0, 0, &porta_mux),
1550
- SND_SOC_DAPM_MUX("PortG Mux", SND_SOC_NOPM, 0, 0, &portg_mux),
1551
- SND_SOC_DAPM_MUX("PortE Mux", SND_SOC_NOPM, 0, 0, &porte_mux),
1552
-
1553
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "PortA",
1554
- CX2072X_PORTA_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1555
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "PortG",
1556
- CX2072X_PORTG_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1557
- CX2072X_DAPM_SWITCH("PortG", CX2072X_PORTG_POWER_STATE, 0, 0xFF,
1558
- 0x00, 0x03, portg_power_ev, SND_SOC_DAPM_POST_PMU),
1559
-
1560
- CX2072X_DAPM_SUPPLY_S("AFG Power", 0, CX2072X_AFG_POWER_STATE,
1561
- 0, 0xFFF, 0x00, 0x03, afg_power_ev,
1562
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1563
-
1564
- SND_SOC_DAPM_OUTPUT("PORTA"),
1565
- SND_SOC_DAPM_OUTPUT("PORTG"),
1566
- SND_SOC_DAPM_OUTPUT("PORTE"),
1567
- SND_SOC_DAPM_OUTPUT("AEC REF"),
1568
-
1569
- /* Capture */
1570
- SND_SOC_DAPM_AIF_OUT("Out AIF", "Capture", 0, SND_SOC_NOPM, 0, 0),
1571
-
1572
- CX2072X_DAPM_REG_E(snd_soc_dapm_adc, "ADC1", CX2072X_ADC1_POWER_STATE,
1573
- 0, 0xFF, 0x00, 0x03, adc1_power_ev,
1574
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
1575
-
1576
- SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC2", CX2072X_ADC2_POWER_STATE,
1577
- 0, 0xFF, 0x00, 0x03),
1578
-
1579
- SND_SOC_DAPM_MUX("ADC1 Mux", SND_SOC_NOPM, 0, 0, &adc1_mux),
1580
-
1581
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "PortB",
1582
- CX2072X_PORTB_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1583
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "PortC",
1584
- CX2072X_PORTC_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1585
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "PortD",
1586
- CX2072X_PORTD_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1587
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "PortE",
1588
- CX2072X_PORTE_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1589
- SND_SOC_DAPM_REG(snd_soc_dapm_switch, "Widget15",
1590
- CX2072X_MIXER_POWER_STATE, 0, 0xFFF, 0x00, 0x03),
1591
-
1592
- SND_SOC_DAPM_INPUT("PORTB"),
1593
- SND_SOC_DAPM_INPUT("PORTC"),
1594
- SND_SOC_DAPM_INPUT("PORTD"),
1595
-
1596
- SND_SOC_DAPM_MICBIAS("Headset Bias", CX2072X_ANALOG_TEST11, 1, 0),
1597
- SND_SOC_DAPM_MICBIAS("PortD Mic Bias", CX2072X_PORTD_PIN_CTRL, 2, 0),
1598
- SND_SOC_DAPM_MICBIAS("PortB Mic Bias", CX2072X_PORTB_PIN_CTRL, 2, 0),
1599
-};
1600
-
1601
-static const struct snd_soc_dapm_route cx2072x_intercon[] = {
1602
- /* Playback */
1603
- {"In AIF", NULL, "AFG Power"},
1604
- {"DAC1", NULL, "In AIF"},
1605
- {"DAC2", NULL, "In AIF"},
1606
- {"PortA Mux", "DAC1 Switch", "DAC1"},
1607
- {"PortA Mux", "DAC2 Switch", "DAC2"},
1608
- {"PortG Mux", "DAC1 Switch", "DAC1"},
1609
- {"PortG Mux", "DAC2 Switch", "DAC2"},
1610
- {"PortE Mux", "DAC1 Switch", "DAC1"},
1611
- {"PortE Mux", "DAC2 Switch", "DAC2"},
1612
- {"Widget15", NULL, "DAC1"},
1613
- {"Widget15", NULL, "DAC2"},
1614
- {"PortA", NULL, "PortA Mux"},
1615
- {"PortG", NULL, "PortG Mux"},
1616
- {"PortE", NULL, "PortE Mux"},
1617
- {"PORTA", NULL, "PortA"},
1618
- {"PORTG", NULL, "PortG"},
1619
- {"PORTE", NULL, "PortE"},
1620
-
1621
- /* Capture */
1622
- {"PORTD", NULL, "PortD Mic Bias"},
1623
- {"PortD", NULL, "PORTD"},
1624
- {"PortC", NULL, "PORTC"},
1625
- {"PortB", NULL, "PORTB"},
1626
- {"ADC1 Mux", "PortD Switch", "PortD"},
1627
- {"ADC1 Mux", "PortC Switch", "PortC"},
1628
- {"ADC1 Mux", "PortB Switch", "PortB"},
1629
- {"ADC1 Mux", "Widget15 Switch", "Widget15"},
1630
- {"ADC1", NULL, "ADC1 Mux"},
1631
- {"Out AIF", NULL, "ADC1"},
1632
- {"Out AIF", NULL, "AFG Power"},
1633
- {"AEC REF", NULL, "ADC1"},
1634
-};
1635
-
1636
-static void cx2072x_sw_reset(struct cx2072x_priv *cx2072x)
1637
-{
1638
- regmap_write(cx2072x->regmap, CX2072X_AFG_FUNCTION_RESET, 0x01);
1639
- regmap_write(cx2072x->regmap, CX2072X_AFG_FUNCTION_RESET, 0x01);
1640
-}
1641
-
1642
-static int cx2072x_init(struct snd_soc_component *component)
1643
-{
1644
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1645
-
1646
- cx2072x->plbk_dsp_changed = true;
1647
- cx2072x->plbk_dsp_init = false;
1648
-
1649
- regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 0);
1650
- regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_TEST15,
1651
- 0x00, 0x06); /* reduce the monitor time */
1652
-
1653
- cx2072x_config_headset_det(cx2072x);
1654
-
1655
- regmap_update_bits(cx2072x->regmap, CX2072X_PORTC_PIN_CTRL,
1656
- 0x20, 0x20); /* reduce the monitor time */
1657
-
1658
- /* enable bclk and EAPD input */
1659
- if (cx2072x->rev_id == CX2072X_REV_A2)
1660
- regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2,
1661
- 0x84, 0xFF);
1662
-
1663
- return 0;
1664
-}
1665
-
1666
-static int cx2072x_set_bias_level(struct snd_soc_component *component,
1667
- enum snd_soc_bias_level level)
1668
-{
1669
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1670
- int ret;
1671
- const enum snd_soc_bias_level old_level =
1672
- snd_soc_component_get_bias_level(component);
1673
-
1674
- switch (level) {
1675
- case SND_SOC_BIAS_ON:
1676
- dev_dbg(cx2072x->dev, "SND_SOC_BIAS_ON\n");
1677
- /* Enable Headset Mic Bias */
1678
- if (cx2072x->is_biason == 0)
1679
- cx2072x->is_biason = 1;
1680
- break;
1681
- case SND_SOC_BIAS_PREPARE:
1682
- dev_dbg(cx2072x->dev, "SND_SOC_BIAS_PREPARE\n");
1683
- if (old_level == SND_SOC_BIAS_STANDBY) {
1684
- dev_dbg(cx2072x->dev,
1685
- "SND_SOC_BIAS_STANDBY = > SND_SOC_BIAS_PREPARE\n");
1686
- }
1687
- break;
1688
- case SND_SOC_BIAS_STANDBY:
1689
- dev_dbg(cx2072x->dev, "SND_SOC_BIAS_STANDBY\n");
1690
- if (old_level == SND_SOC_BIAS_OFF) {
1691
- if (cx2072x->mclk_clock) {
1692
- dev_dbg(cx2072x->dev, "Turn on MCLK\n");
1693
- ret = clk_prepare_enable(cx2072x->mclk_clock);
1694
- if (ret)
1695
- return ret;
1696
- }
1697
- dev_dbg(component->dev, "cache only =>false\n");
1698
- regcache_cache_only(cx2072x->regmap, false);
1699
- dev_dbg(component->dev, "regcache_sync\n");
1700
- regmap_write(cx2072x->regmap,
1701
- CX2072X_AFG_POWER_STATE, 0);
1702
- regcache_sync(cx2072x->regmap);
1703
- dev_dbg(component->dev, "regcache_sync done\n");
1704
- }
1705
- break;
1706
- case SND_SOC_BIAS_OFF:
1707
- dev_dbg(cx2072x->dev, "SND_SOC_BIAS_OFF\n");
1708
- /* Shutdown codec completely */
1709
- cx2072x_sw_reset(cx2072x);
1710
- dev_dbg(component->dev, "cache only\n");
1711
- regcache_mark_dirty(cx2072x->regmap);
1712
- regcache_cache_only(cx2072x->regmap, true);
1713
- if (cx2072x->mclk_clock) {
1714
- dev_dbg(cx2072x->dev, "Turn off MCLK\n");
1715
- clk_disable_unprepare(cx2072x->mclk_clock);
1716
- }
1717
- break;
1718
- }
1719
-
1720
- return 0;
1721
-}
1722
-
1723
-static int cx2072x_probe(struct snd_soc_component *component)
1724
-{
1725
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1726
- int ret = 0;
1727
- unsigned int ven_id;
1728
-
1729
- cx2072x_component = component;
1730
- cx2072x->component = component;
1731
-
1732
- cx2072x->mclk_clock = devm_clk_get(component->dev, "mclk");
1733
- if (PTR_ERR(cx2072x->mclk_clock) == -EPROBE_DEFER)
1734
- return -EPROBE_DEFER;
1735
-
1736
- ret = clk_set_rate(cx2072x->mclk_clock, CX2072X_RATES_MCLK);
1737
- if (ret) {
1738
- dev_err(component->dev, "clk_set_rate is fail!\n");
1739
- return ret;
1740
- }
1741
-
1742
- ret = clk_prepare_enable(cx2072x->mclk_clock);
1743
- if (ret) {
1744
- dev_err(component->dev, "clk_prepare_enable is fail!\n");
1745
- return ret;
1746
- }
1747
-
1748
- cx2072x_init(component);
1749
-
1750
- ret = regmap_register_patch(cx2072x->regmap, cx2072x_patch,
1751
- ARRAY_SIZE(cx2072x_patch));
1752
- if (ret)
1753
- return ret;
1754
-
1755
- dev_dbg(component->dev, "codec version: 4.4.20\n");
1756
- regmap_read(cx2072x->regmap, CX2072X_VENDOR_ID, &ven_id);
1757
- regmap_read(cx2072x->regmap, CX2072X_REVISION_ID, &cx2072x->rev_id);
1758
- dev_err(component->dev, "codec version: %08x,%08x\n", ven_id,
1759
- cx2072x->rev_id);
1760
-#ifdef ENABLE_MIC_POP_WA
1761
- INIT_DELAYED_WORK(&codec->dapm.delayed_work,
1762
- cx2072x_anit_mic_pop_work);
1763
-#endif
1764
- return ret;
1765
-}
1766
-
1767
-static void cx2072x_remove(struct snd_soc_component *component)
1768
-{
1769
- struct cx2072x_priv *cx2072x = get_cx2072x_priv(component);
1770
- /* power off device */
1771
- cx2072x_set_bias_level(cx2072x->component, SND_SOC_BIAS_OFF);
1772
-}
1773
-
1774
-#ifdef CONFIG_PM
1775
-static int cx2072x_runtime_suspend(struct device *dev)
1776
-{
1777
- struct cx2072x_priv *cx2072x = dev_get_drvdata(dev);
1778
-
1779
- dev_dbg(cx2072x->component->dev, "%s----%d\n", __func__, __LINE__);
1780
- cx2072x_set_bias_level(cx2072x->component, SND_SOC_BIAS_OFF);
1781
-
1782
- return 0;
1783
-}
1784
-
1785
-static int cx2072x_runtime_resume(struct device *dev)
1786
-{
1787
- struct cx2072x_priv *cx2072x = dev_get_drvdata(dev);
1788
-
1789
- dev_dbg(cx2072x->component->dev, "%s----%d\n", __func__, __LINE__);
1790
- cx2072x_set_bias_level(cx2072x->component, SND_SOC_BIAS_STANDBY);
1791
- return 0;
1792
-}
1793
-#else
1794
-#define cx2072x_suspend NULL
1795
-#define cx2072x_resume NULL
1796
-#endif
1797316
1798317 static bool cx2072x_readable_register(struct device *dev, unsigned int reg)
1799318 {
....@@ -1918,6 +437,7 @@
1918437 case CX2072X_I2SPCM_CONTROL6:
1919438 case CX2072X_UM_INTERRUPT_CRTL_E:
1920439 case CX2072X_CODEC_TEST2:
440
+ case CX2072X_CODEC_TEST9:
1921441 case CX2072X_CODEC_TEST20:
1922442 case CX2072X_CODEC_TEST26:
1923443 case CX2072X_ANALOG_TEST4:
....@@ -1966,12 +486,1044 @@
1966486 }
1967487 }
1968488
489
+static int cx2072x_reg_raw_write(struct i2c_client *client,
490
+ unsigned int reg,
491
+ const void *val, size_t val_count)
492
+{
493
+ struct device *dev = &client->dev;
494
+ u8 buf[2 + CX2072X_MAX_EQ_COEFF];
495
+ int ret;
496
+
497
+ if (WARN_ON(val_count + 2 > sizeof(buf)))
498
+ return -EINVAL;
499
+
500
+ buf[0] = reg >> 8;
501
+ buf[1] = reg & 0xff;
502
+
503
+ memcpy(buf + 2, val, val_count);
504
+
505
+ ret = i2c_master_send(client, buf, val_count + 2);
506
+ if (ret != val_count + 2) {
507
+ dev_err(dev, "I2C write failed, ret = %d\n", ret);
508
+ return ret < 0 ? ret : -EIO;
509
+ }
510
+ return 0;
511
+}
512
+
513
+static int cx2072x_reg_write(void *context, unsigned int reg,
514
+ unsigned int value)
515
+{
516
+ __le32 raw_value;
517
+ unsigned int size;
518
+
519
+ size = cx2072x_register_size(reg);
520
+
521
+ if (reg == CX2072X_UM_INTERRUPT_CRTL_E) {
522
+ /* Update the MSB byte only */
523
+ reg += 3;
524
+ size = 1;
525
+ value >>= 24;
526
+ }
527
+
528
+ raw_value = cpu_to_le32(value);
529
+ return cx2072x_reg_raw_write(context, reg, &raw_value, size);
530
+}
531
+
532
+static int cx2072x_reg_read(void *context, unsigned int reg,
533
+ unsigned int *value)
534
+{
535
+ struct i2c_client *client = context;
536
+ struct device *dev = &client->dev;
537
+ __le32 recv_buf = 0;
538
+ struct i2c_msg msgs[2];
539
+ unsigned int size;
540
+ u8 send_buf[2];
541
+ int ret;
542
+
543
+ size = cx2072x_register_size(reg);
544
+
545
+ send_buf[0] = reg >> 8;
546
+ send_buf[1] = reg & 0xff;
547
+
548
+ msgs[0].addr = client->addr;
549
+ msgs[0].len = sizeof(send_buf);
550
+ msgs[0].buf = send_buf;
551
+ msgs[0].flags = 0;
552
+
553
+ msgs[1].addr = client->addr;
554
+ msgs[1].len = size;
555
+ msgs[1].buf = (u8 *)&recv_buf;
556
+ msgs[1].flags = I2C_M_RD;
557
+
558
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
559
+ if (ret != ARRAY_SIZE(msgs)) {
560
+ dev_err(dev, "Failed to read register, ret = %d\n", ret);
561
+ return ret < 0 ? ret : -EIO;
562
+ }
563
+
564
+ *value = le32_to_cpu(recv_buf);
565
+ return 0;
566
+}
567
+
568
+/* get suggested pre_div valuce from mclk frequency */
569
+static unsigned int get_div_from_mclk(unsigned int mclk)
570
+{
571
+ unsigned int div = 8;
572
+ int i;
573
+
574
+ for (i = 0; i < ARRAY_SIZE(mclk_pre_div); i++) {
575
+ if (mclk <= mclk_pre_div[i].mclk) {
576
+ div = mclk_pre_div[i].div;
577
+ break;
578
+ }
579
+ }
580
+ return div;
581
+}
582
+
583
+static int cx2072x_config_pll(struct cx2072x_priv *cx2072x)
584
+{
585
+ struct device *dev = cx2072x->dev;
586
+ unsigned int pre_div;
587
+ unsigned int pre_div_val;
588
+ unsigned int pll_input;
589
+ unsigned int pll_output;
590
+ unsigned int int_div;
591
+ unsigned int frac_div;
592
+ u64 frac_num;
593
+ unsigned int frac;
594
+ unsigned int sample_rate = cx2072x->sample_rate;
595
+ int pt_sample_per_sync = 2;
596
+ int pt_clock_per_sample = 96;
597
+
598
+ switch (sample_rate) {
599
+ case 48000:
600
+ case 32000:
601
+ case 24000:
602
+ case 16000:
603
+ break;
604
+
605
+ case 96000:
606
+ pt_sample_per_sync = 1;
607
+ pt_clock_per_sample = 48;
608
+ break;
609
+
610
+ case 192000:
611
+ pt_sample_per_sync = 0;
612
+ pt_clock_per_sample = 24;
613
+ break;
614
+
615
+ default:
616
+ dev_err(dev, "Unsupported sample rate %d\n", sample_rate);
617
+ return -EINVAL;
618
+ }
619
+
620
+ /* Configure PLL settings */
621
+ pre_div = get_div_from_mclk(cx2072x->mclk_rate);
622
+ pll_input = cx2072x->mclk_rate / pre_div;
623
+ pll_output = sample_rate * 3072;
624
+ int_div = pll_output / pll_input;
625
+ frac_div = pll_output - (int_div * pll_input);
626
+
627
+ if (frac_div) {
628
+ frac_div *= 1000;
629
+ frac_div /= pll_input;
630
+ frac_num = (u64)(4000 + frac_div) * ((1 << 20) - 4);
631
+ do_div(frac_num, 7);
632
+ frac = ((u32)frac_num + 499) / 1000;
633
+ }
634
+ pre_div_val = (pre_div - 1) * 2;
635
+
636
+ regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST4,
637
+ 0x40 | (pre_div_val << 8));
638
+ if (frac_div == 0) {
639
+ /* Int mode */
640
+ regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST7, 0x100);
641
+ } else {
642
+ /* frac mode */
643
+ regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST6,
644
+ frac & 0xfff);
645
+ regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST7,
646
+ (u8)(frac >> 12));
647
+ }
648
+
649
+ int_div--;
650
+ regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST8, int_div);
651
+
652
+ /* configure PLL tracking */
653
+ if (frac_div == 0) {
654
+ /* disable PLL tracking */
655
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST16, 0x00);
656
+ } else {
657
+ /* configure and enable PLL tracking */
658
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST16,
659
+ (pt_sample_per_sync << 4) & 0xf0);
660
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST17,
661
+ pt_clock_per_sample);
662
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST18,
663
+ pt_clock_per_sample * 3 / 2);
664
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST19, 0x01);
665
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST20, 0x02);
666
+ regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_TEST16,
667
+ 0x01, 0x01);
668
+ }
669
+
670
+ return 0;
671
+}
672
+
673
+static int cx2072x_config_i2spcm(struct cx2072x_priv *cx2072x)
674
+{
675
+ struct device *dev = cx2072x->dev;
676
+ unsigned int bclk_rate = 0;
677
+ int is_i2s = 0;
678
+ int has_one_bit_delay = 0;
679
+ int is_frame_inv = 0;
680
+ int is_bclk_inv = 0;
681
+ int pulse_len;
682
+ int frame_len = cx2072x->frame_size;
683
+ int sample_size = cx2072x->sample_size;
684
+ int i2s_right_slot;
685
+ int i2s_right_pause_interval = 0;
686
+ int i2s_right_pause_pos;
687
+ int is_big_endian = 1;
688
+ u64 div;
689
+ unsigned int mod;
690
+ union cx2072x_reg_i2spcm_ctrl_reg1 reg1;
691
+ union cx2072x_reg_i2spcm_ctrl_reg2 reg2;
692
+ union cx2072x_reg_i2spcm_ctrl_reg3 reg3;
693
+ union cx2072x_reg_i2spcm_ctrl_reg4 reg4;
694
+ union cx2072x_reg_i2spcm_ctrl_reg5 reg5;
695
+ union cx2072x_reg_i2spcm_ctrl_reg6 reg6;
696
+ union cx2072x_reg_digital_bios_test2 regdbt2;
697
+ const unsigned int fmt = cx2072x->dai_fmt;
698
+
699
+ if (frame_len <= 0) {
700
+ dev_err(dev, "Incorrect frame len %d\n", frame_len);
701
+ return -EINVAL;
702
+ }
703
+
704
+ if (sample_size <= 0) {
705
+ dev_err(dev, "Incorrect sample size %d\n", sample_size);
706
+ return -EINVAL;
707
+ }
708
+
709
+ dev_dbg(dev, "config_i2spcm set_dai_fmt- %08x\n", fmt);
710
+
711
+ regdbt2.ulval = 0xac;
712
+
713
+ /* set master/slave */
714
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
715
+ case SND_SOC_DAIFMT_CBM_CFM:
716
+ reg2.r.tx_master = 1;
717
+ reg3.r.rx_master = 1;
718
+ dev_dbg(dev, "Sets Master mode\n");
719
+ break;
720
+
721
+ case SND_SOC_DAIFMT_CBS_CFS:
722
+ reg2.r.tx_master = 0;
723
+ reg3.r.rx_master = 0;
724
+ dev_dbg(dev, "Sets Slave mode\n");
725
+ break;
726
+
727
+ default:
728
+ dev_err(dev, "Unsupported DAI master mode\n");
729
+ return -EINVAL;
730
+ }
731
+
732
+ /* set format */
733
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
734
+ case SND_SOC_DAIFMT_I2S:
735
+ is_i2s = 1;
736
+ has_one_bit_delay = 1;
737
+ pulse_len = frame_len / 2;
738
+ break;
739
+
740
+ case SND_SOC_DAIFMT_RIGHT_J:
741
+ is_i2s = 1;
742
+ pulse_len = frame_len / 2;
743
+ break;
744
+
745
+ case SND_SOC_DAIFMT_LEFT_J:
746
+ is_i2s = 1;
747
+ pulse_len = frame_len / 2;
748
+ break;
749
+
750
+ default:
751
+ dev_err(dev, "Unsupported DAI format\n");
752
+ return -EINVAL;
753
+ }
754
+
755
+ /* clock inversion */
756
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
757
+ case SND_SOC_DAIFMT_NB_NF:
758
+ is_frame_inv = is_i2s;
759
+ is_bclk_inv = is_i2s;
760
+ break;
761
+
762
+ case SND_SOC_DAIFMT_IB_IF:
763
+ is_frame_inv = !is_i2s;
764
+ is_bclk_inv = !is_i2s;
765
+ break;
766
+
767
+ case SND_SOC_DAIFMT_IB_NF:
768
+ is_frame_inv = is_i2s;
769
+ is_bclk_inv = !is_i2s;
770
+ break;
771
+
772
+ case SND_SOC_DAIFMT_NB_IF:
773
+ is_frame_inv = !is_i2s;
774
+ is_bclk_inv = is_i2s;
775
+ break;
776
+
777
+ default:
778
+ dev_err(dev, "Unsupported DAI clock inversion\n");
779
+ return -EINVAL;
780
+ }
781
+
782
+ reg1.r.rx_data_one_line = 1;
783
+ reg1.r.tx_data_one_line = 1;
784
+
785
+ if (is_i2s) {
786
+ i2s_right_slot = (frame_len / 2) / BITS_PER_SLOT;
787
+ i2s_right_pause_interval = (frame_len / 2) % BITS_PER_SLOT;
788
+ i2s_right_pause_pos = i2s_right_slot * BITS_PER_SLOT;
789
+ }
790
+
791
+ reg1.r.rx_ws_pol = is_frame_inv;
792
+ reg1.r.rx_ws_wid = pulse_len - 1;
793
+
794
+ reg1.r.rx_frm_len = frame_len / BITS_PER_SLOT - 1;
795
+ reg1.r.rx_sa_size = (sample_size / BITS_PER_SLOT) - 1;
796
+
797
+ reg1.r.tx_ws_pol = reg1.r.rx_ws_pol;
798
+ reg1.r.tx_ws_wid = pulse_len - 1;
799
+ reg1.r.tx_frm_len = reg1.r.rx_frm_len;
800
+ reg1.r.tx_sa_size = reg1.r.rx_sa_size;
801
+
802
+ reg2.r.tx_endian_sel = !is_big_endian;
803
+ reg2.r.tx_dstart_dly = has_one_bit_delay;
804
+ if (cx2072x->en_aec_ref)
805
+ reg2.r.tx_dstart_dly = 0;
806
+
807
+ reg3.r.rx_endian_sel = !is_big_endian;
808
+ reg3.r.rx_dstart_dly = has_one_bit_delay;
809
+
810
+ reg4.ulval = 0;
811
+
812
+ if (is_i2s) {
813
+ reg2.r.tx_slot_1 = 0;
814
+ reg2.r.tx_slot_2 = i2s_right_slot;
815
+ reg3.r.rx_slot_1 = 0;
816
+ if (cx2072x->en_aec_ref)
817
+ reg3.r.rx_slot_2 = 0;
818
+ else
819
+ reg3.r.rx_slot_2 = i2s_right_slot;
820
+ reg6.r.rx_pause_start_pos = i2s_right_pause_pos;
821
+ reg6.r.rx_pause_cycles = i2s_right_pause_interval;
822
+ reg6.r.tx_pause_start_pos = i2s_right_pause_pos;
823
+ reg6.r.tx_pause_cycles = i2s_right_pause_interval;
824
+ } else {
825
+ dev_err(dev, "TDM mode is not implemented yet\n");
826
+ return -EINVAL;
827
+ }
828
+ regdbt2.r.i2s_bclk_invert = is_bclk_inv;
829
+
830
+ reg1.r.rx_data_one_line = 1;
831
+ reg1.r.tx_data_one_line = 1;
832
+
833
+ /* Configures the BCLK output */
834
+ bclk_rate = cx2072x->sample_rate * frame_len;
835
+ reg5.r.i2s_pcm_clk_div_chan_en = 0;
836
+
837
+ /* Disables bclk output before setting new value */
838
+ regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL5, 0);
839
+
840
+ if (reg2.r.tx_master) {
841
+ /* Configures BCLK rate */
842
+ div = PLL_OUT_HZ_48;
843
+ mod = do_div(div, bclk_rate);
844
+ if (mod) {
845
+ dev_err(dev, "Unsupported BCLK %dHz\n", bclk_rate);
846
+ return -EINVAL;
847
+ }
848
+ dev_dbg(dev, "enables BCLK %dHz output\n", bclk_rate);
849
+ reg5.r.i2s_pcm_clk_div = (u32)div - 1;
850
+ reg5.r.i2s_pcm_clk_div_chan_en = 1;
851
+ }
852
+
853
+ regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL1, reg1.ulval);
854
+ regmap_update_bits(cx2072x->regmap, CX2072X_I2SPCM_CONTROL2, 0xffffffc0,
855
+ reg2.ulval);
856
+ regmap_update_bits(cx2072x->regmap, CX2072X_I2SPCM_CONTROL3, 0xffffffc0,
857
+ reg3.ulval);
858
+ regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL4, reg4.ulval);
859
+ regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL6, reg6.ulval);
860
+ regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL5, reg5.ulval);
861
+
862
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2,
863
+ regdbt2.ulval);
864
+
865
+ return 0;
866
+}
867
+
868
+static int afg_power_ev(struct snd_soc_dapm_widget *w,
869
+ struct snd_kcontrol *kcontrol, int event)
870
+{
871
+ struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
872
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
873
+
874
+ switch (event) {
875
+ case SND_SOC_DAPM_POST_PMU:
876
+ regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST0,
877
+ 0x00, 0x10);
878
+ break;
879
+
880
+ case SND_SOC_DAPM_PRE_PMD:
881
+ regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST0,
882
+ 0x10, 0x10);
883
+ break;
884
+ }
885
+
886
+ return 0;
887
+}
888
+
889
+static const struct snd_kcontrol_new cx2072x_snd_controls[] = {
890
+ SOC_DOUBLE_R_TLV("PortD Boost Volume", CX2072X_PORTD_GAIN_LEFT,
891
+ CX2072X_PORTD_GAIN_RIGHT, 0, 3, 0, boost_tlv),
892
+ SOC_DOUBLE_R_TLV("PortC Boost Volume", CX2072X_PORTC_GAIN_LEFT,
893
+ CX2072X_PORTC_GAIN_RIGHT, 0, 3, 0, boost_tlv),
894
+ SOC_DOUBLE_R_TLV("PortB Boost Volume", CX2072X_PORTB_GAIN_LEFT,
895
+ CX2072X_PORTB_GAIN_RIGHT, 0, 3, 0, boost_tlv),
896
+ SOC_DOUBLE_R_TLV("PortD ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_1,
897
+ CX2072X_ADC1_AMP_GAIN_RIGHT_1, 0, 0x4a, 0, adc_tlv),
898
+ SOC_DOUBLE_R_TLV("PortC ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_2,
899
+ CX2072X_ADC1_AMP_GAIN_RIGHT_2, 0, 0x4a, 0, adc_tlv),
900
+ SOC_DOUBLE_R_TLV("PortB ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_0,
901
+ CX2072X_ADC1_AMP_GAIN_RIGHT_0, 0, 0x4a, 0, adc_tlv),
902
+ SOC_DOUBLE_R_TLV("DAC1 Volume", CX2072X_DAC1_AMP_GAIN_LEFT,
903
+ CX2072X_DAC1_AMP_GAIN_RIGHT, 0, 0x4a, 0, dac_tlv),
904
+ SOC_DOUBLE_R("DAC1 Switch", CX2072X_DAC1_AMP_GAIN_LEFT,
905
+ CX2072X_DAC1_AMP_GAIN_RIGHT, 7, 1, 0),
906
+ SOC_DOUBLE_R_TLV("DAC2 Volume", CX2072X_DAC2_AMP_GAIN_LEFT,
907
+ CX2072X_DAC2_AMP_GAIN_RIGHT, 0, 0x4a, 0, dac_tlv),
908
+ SOC_SINGLE_TLV("HPF Freq", CX2072X_CODEC_TEST9, 0, 0x3f, 0, hpf_tlv),
909
+ SOC_DOUBLE("HPF Switch", CX2072X_CODEC_TEST9, 8, 9, 1, 1),
910
+ SOC_SINGLE("PortA HP Amp Switch", CX2072X_PORTA_PIN_CTRL, 7, 1, 0),
911
+};
912
+
913
+static int cx2072x_hw_params(struct snd_pcm_substream *substream,
914
+ struct snd_pcm_hw_params *params,
915
+ struct snd_soc_dai *dai)
916
+{
917
+ struct snd_soc_component *codec = dai->component;
918
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
919
+ struct device *dev = codec->dev;
920
+ const unsigned int sample_rate = params_rate(params);
921
+ int sample_size, frame_size;
922
+
923
+ /* Data sizes if not using TDM */
924
+ sample_size = params_width(params);
925
+
926
+ if (sample_size < 0)
927
+ return sample_size;
928
+
929
+ frame_size = snd_soc_params_to_frame_size(params);
930
+ if (frame_size < 0)
931
+ return frame_size;
932
+
933
+ if (cx2072x->mclk_rate == 0) {
934
+ dev_err(dev, "Master clock rate is not configured\n");
935
+ return -EINVAL;
936
+ }
937
+
938
+ if (cx2072x->bclk_ratio)
939
+ frame_size = cx2072x->bclk_ratio;
940
+
941
+ switch (sample_rate) {
942
+ case 48000:
943
+ case 32000:
944
+ case 24000:
945
+ case 16000:
946
+ case 96000:
947
+ case 192000:
948
+ break;
949
+
950
+ default:
951
+ dev_err(dev, "Unsupported sample rate %d\n", sample_rate);
952
+ return -EINVAL;
953
+ }
954
+
955
+ dev_dbg(dev, "Sample size %d bits, frame = %d bits, rate = %d Hz\n",
956
+ sample_size, frame_size, sample_rate);
957
+
958
+ cx2072x->frame_size = frame_size;
959
+ cx2072x->sample_size = sample_size;
960
+ cx2072x->sample_rate = sample_rate;
961
+
962
+ if (dai->id == CX2072X_DAI_DSP) {
963
+ cx2072x->en_aec_ref = true;
964
+ dev_dbg(cx2072x->dev, "enables aec reference\n");
965
+ regmap_write(cx2072x->regmap,
966
+ CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 3);
967
+ }
968
+
969
+ if (cx2072x->pll_changed) {
970
+ cx2072x_config_pll(cx2072x);
971
+ cx2072x->pll_changed = false;
972
+ }
973
+
974
+ if (cx2072x->i2spcm_changed) {
975
+ cx2072x_config_i2spcm(cx2072x);
976
+ cx2072x->i2spcm_changed = false;
977
+ }
978
+
979
+ return 0;
980
+}
981
+
982
+static int cx2072x_set_dai_bclk_ratio(struct snd_soc_dai *dai,
983
+ unsigned int ratio)
984
+{
985
+ struct snd_soc_component *codec = dai->component;
986
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
987
+
988
+ cx2072x->bclk_ratio = ratio;
989
+ return 0;
990
+}
991
+
992
+static int cx2072x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
993
+ unsigned int freq, int dir)
994
+{
995
+ struct snd_soc_component *codec = dai->component;
996
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
997
+
998
+ if (clk_set_rate(cx2072x->mclk, freq)) {
999
+ dev_err(codec->dev, "set clk rate failed\n");
1000
+ return -EINVAL;
1001
+ }
1002
+
1003
+ cx2072x->mclk_rate = freq;
1004
+ return 0;
1005
+}
1006
+
1007
+static int cx2072x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1008
+{
1009
+ struct snd_soc_component *codec = dai->component;
1010
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1011
+ struct device *dev = codec->dev;
1012
+
1013
+ dev_dbg(dev, "set_dai_fmt- %08x\n", fmt);
1014
+ /* set master/slave */
1015
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1016
+ case SND_SOC_DAIFMT_CBM_CFM:
1017
+ case SND_SOC_DAIFMT_CBS_CFS:
1018
+ break;
1019
+
1020
+ default:
1021
+ dev_err(dev, "Unsupported DAI master mode\n");
1022
+ return -EINVAL;
1023
+ }
1024
+
1025
+ /* set format */
1026
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1027
+ case SND_SOC_DAIFMT_I2S:
1028
+ case SND_SOC_DAIFMT_RIGHT_J:
1029
+ case SND_SOC_DAIFMT_LEFT_J:
1030
+ break;
1031
+
1032
+ default:
1033
+ dev_err(dev, "Unsupported DAI format\n");
1034
+ return -EINVAL;
1035
+ }
1036
+
1037
+ /* clock inversion */
1038
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1039
+ case SND_SOC_DAIFMT_NB_NF:
1040
+ case SND_SOC_DAIFMT_IB_IF:
1041
+ case SND_SOC_DAIFMT_IB_NF:
1042
+ case SND_SOC_DAIFMT_NB_IF:
1043
+ break;
1044
+
1045
+ default:
1046
+ dev_err(dev, "Unsupported DAI clock inversion\n");
1047
+ return -EINVAL;
1048
+ }
1049
+
1050
+ cx2072x->dai_fmt = fmt;
1051
+ return 0;
1052
+}
1053
+
1054
+static const struct snd_kcontrol_new portaouten_ctl =
1055
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTA_PIN_CTRL, 6, 1, 0);
1056
+
1057
+static const struct snd_kcontrol_new porteouten_ctl =
1058
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTE_PIN_CTRL, 6, 1, 0);
1059
+
1060
+static const struct snd_kcontrol_new portgouten_ctl =
1061
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTG_PIN_CTRL, 6, 1, 0);
1062
+
1063
+static const struct snd_kcontrol_new portmouten_ctl =
1064
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTM_PIN_CTRL, 6, 1, 0);
1065
+
1066
+static const struct snd_kcontrol_new portbinen_ctl =
1067
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTB_PIN_CTRL, 5, 1, 0);
1068
+
1069
+static const struct snd_kcontrol_new portcinen_ctl =
1070
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTC_PIN_CTRL, 5, 1, 0);
1071
+
1072
+static const struct snd_kcontrol_new portdinen_ctl =
1073
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTD_PIN_CTRL, 5, 1, 0);
1074
+
1075
+static const struct snd_kcontrol_new porteinen_ctl =
1076
+ SOC_DAPM_SINGLE("Switch", CX2072X_PORTE_PIN_CTRL, 5, 1, 0);
1077
+
1078
+static const struct snd_kcontrol_new i2sadc1l_ctl =
1079
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 0, 1, 0);
1080
+
1081
+static const struct snd_kcontrol_new i2sadc1r_ctl =
1082
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 1, 1, 0);
1083
+
1084
+static const struct snd_kcontrol_new i2sadc2l_ctl =
1085
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 2, 1, 0);
1086
+
1087
+static const struct snd_kcontrol_new i2sadc2r_ctl =
1088
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 3, 1, 0);
1089
+
1090
+static const struct snd_kcontrol_new i2sdac1l_ctl =
1091
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 0, 1, 0);
1092
+
1093
+static const struct snd_kcontrol_new i2sdac1r_ctl =
1094
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 1, 1, 0);
1095
+
1096
+static const struct snd_kcontrol_new i2sdac2l_ctl =
1097
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 2, 1, 0);
1098
+
1099
+static const struct snd_kcontrol_new i2sdac2r_ctl =
1100
+ SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 3, 1, 0);
1101
+
1102
+static const char * const dac_enum_text[] = {
1103
+ "DAC1 Switch", "DAC2 Switch",
1104
+};
1105
+
1106
+static const struct soc_enum porta_dac_enum =
1107
+SOC_ENUM_SINGLE(CX2072X_PORTA_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1108
+
1109
+static const struct snd_kcontrol_new porta_mux =
1110
+SOC_DAPM_ENUM("PortA Mux", porta_dac_enum);
1111
+
1112
+static const struct soc_enum portg_dac_enum =
1113
+SOC_ENUM_SINGLE(CX2072X_PORTG_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1114
+
1115
+static const struct snd_kcontrol_new portg_mux =
1116
+SOC_DAPM_ENUM("PortG Mux", portg_dac_enum);
1117
+
1118
+static const struct soc_enum porte_dac_enum =
1119
+SOC_ENUM_SINGLE(CX2072X_PORTE_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1120
+
1121
+static const struct snd_kcontrol_new porte_mux =
1122
+SOC_DAPM_ENUM("PortE Mux", porte_dac_enum);
1123
+
1124
+static const struct soc_enum portm_dac_enum =
1125
+SOC_ENUM_SINGLE(CX2072X_PORTM_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text);
1126
+
1127
+static const struct snd_kcontrol_new portm_mux =
1128
+SOC_DAPM_ENUM("PortM Mux", portm_dac_enum);
1129
+
1130
+static const char * const adc1in_sel_text[] = {
1131
+ "PortB Switch", "PortD Switch", "PortC Switch", "Widget15 Switch",
1132
+ "PortE Switch", "PortF Switch", "PortH Switch"
1133
+};
1134
+
1135
+static const struct soc_enum adc1in_sel_enum =
1136
+SOC_ENUM_SINGLE(CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 0, 7, adc1in_sel_text);
1137
+
1138
+static const struct snd_kcontrol_new adc1_mux =
1139
+SOC_DAPM_ENUM("ADC1 Mux", adc1in_sel_enum);
1140
+
1141
+static const char * const adc2in_sel_text[] = {
1142
+ "PortC Switch", "Widget15 Switch", "PortH Switch"
1143
+};
1144
+
1145
+static const struct soc_enum adc2in_sel_enum =
1146
+SOC_ENUM_SINGLE(CX2072X_ADC2_CONNECTION_SELECT_CONTROL, 0, 3, adc2in_sel_text);
1147
+
1148
+static const struct snd_kcontrol_new adc2_mux =
1149
+SOC_DAPM_ENUM("ADC2 Mux", adc2in_sel_enum);
1150
+
1151
+static const struct snd_kcontrol_new wid15_mix[] = {
1152
+ SOC_DAPM_SINGLE("DAC1L Switch", CX2072X_MIXER_GAIN_LEFT_0, 7, 1, 1),
1153
+ SOC_DAPM_SINGLE("DAC1R Switch", CX2072X_MIXER_GAIN_RIGHT_0, 7, 1, 1),
1154
+ SOC_DAPM_SINGLE("DAC2L Switch", CX2072X_MIXER_GAIN_LEFT_1, 7, 1, 1),
1155
+ SOC_DAPM_SINGLE("DAC2R Switch", CX2072X_MIXER_GAIN_RIGHT_1, 7, 1, 1),
1156
+};
1157
+
1158
+#define CX2072X_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, wmask, won_val, \
1159
+ woff_val, wevent, wflags) \
1160
+ {.id = snd_soc_dapm_supply, .name = wname, .kcontrol_news = NULL, \
1161
+ .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \
1162
+ .on_val = won_val, .off_val = woff_val, \
1163
+ .subseq = wsubseq, .event = wevent, .event_flags = wflags}
1164
+
1165
+#define CX2072X_DAPM_SWITCH(wname, wreg, wshift, wmask, won_val, woff_val, \
1166
+ wevent, wflags) \
1167
+ {.id = snd_soc_dapm_switch, .name = wname, .kcontrol_news = NULL, \
1168
+ .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \
1169
+ .on_val = won_val, .off_val = woff_val, \
1170
+ .event = wevent, .event_flags = wflags}
1171
+
1172
+#define CX2072X_DAPM_SWITCH(wname, wreg, wshift, wmask, won_val, woff_val, \
1173
+ wevent, wflags) \
1174
+ {.id = snd_soc_dapm_switch, .name = wname, .kcontrol_news = NULL, \
1175
+ .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \
1176
+ .on_val = won_val, .off_val = woff_val, \
1177
+ .event = wevent, .event_flags = wflags}
1178
+
1179
+#define CX2072X_DAPM_REG_E(wid, wname, wreg, wshift, wmask, won_val, woff_val, \
1180
+ wevent, wflags) \
1181
+ {.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
1182
+ .reg = wreg, .shift = wshift, .mask = wmask, \
1183
+ .on_val = won_val, .off_val = woff_val, \
1184
+ .event = wevent, .event_flags = wflags}
1185
+
1186
+static const struct snd_soc_dapm_widget cx2072x_dapm_widgets[] = {
1187
+ /*Playback*/
1188
+ SND_SOC_DAPM_AIF_IN("In AIF", "Playback", 0, SND_SOC_NOPM, 0, 0),
1189
+
1190
+ SND_SOC_DAPM_SWITCH("I2S DAC1L", SND_SOC_NOPM, 0, 0, &i2sdac1l_ctl),
1191
+ SND_SOC_DAPM_SWITCH("I2S DAC1R", SND_SOC_NOPM, 0, 0, &i2sdac1r_ctl),
1192
+ SND_SOC_DAPM_SWITCH("I2S DAC2L", SND_SOC_NOPM, 0, 0, &i2sdac2l_ctl),
1193
+ SND_SOC_DAPM_SWITCH("I2S DAC2R", SND_SOC_NOPM, 0, 0, &i2sdac2r_ctl),
1194
+
1195
+ SND_SOC_DAPM_REG(snd_soc_dapm_dac, "DAC1", CX2072X_DAC1_POWER_STATE,
1196
+ 0, 0xfff, 0x00, 0x03),
1197
+
1198
+ SND_SOC_DAPM_REG(snd_soc_dapm_dac, "DAC2", CX2072X_DAC2_POWER_STATE,
1199
+ 0, 0xfff, 0x00, 0x03),
1200
+
1201
+ SND_SOC_DAPM_MUX("PortA Mux", SND_SOC_NOPM, 0, 0, &porta_mux),
1202
+ SND_SOC_DAPM_MUX("PortG Mux", SND_SOC_NOPM, 0, 0, &portg_mux),
1203
+ SND_SOC_DAPM_MUX("PortE Mux", SND_SOC_NOPM, 0, 0, &porte_mux),
1204
+ SND_SOC_DAPM_MUX("PortM Mux", SND_SOC_NOPM, 0, 0, &portm_mux),
1205
+
1206
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortA Power",
1207
+ CX2072X_PORTA_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1208
+
1209
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortM Power",
1210
+ CX2072X_PORTM_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1211
+
1212
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortG Power",
1213
+ CX2072X_PORTG_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1214
+
1215
+ CX2072X_DAPM_SUPPLY_S("AFG Power", 0, CX2072X_AFG_POWER_STATE,
1216
+ 0, 0xfff, 0x00, 0x03, afg_power_ev,
1217
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1218
+
1219
+ SND_SOC_DAPM_SWITCH("PortA Out En", SND_SOC_NOPM, 0, 0,
1220
+ &portaouten_ctl),
1221
+ SND_SOC_DAPM_SWITCH("PortE Out En", SND_SOC_NOPM, 0, 0,
1222
+ &porteouten_ctl),
1223
+ SND_SOC_DAPM_SWITCH("PortG Out En", SND_SOC_NOPM, 0, 0,
1224
+ &portgouten_ctl),
1225
+ SND_SOC_DAPM_SWITCH("PortM Out En", SND_SOC_NOPM, 0, 0,
1226
+ &portmouten_ctl),
1227
+
1228
+ SND_SOC_DAPM_OUTPUT("PORTA"),
1229
+ SND_SOC_DAPM_OUTPUT("PORTG"),
1230
+ SND_SOC_DAPM_OUTPUT("PORTE"),
1231
+ SND_SOC_DAPM_OUTPUT("PORTM"),
1232
+ SND_SOC_DAPM_OUTPUT("AEC REF"),
1233
+
1234
+ /*Capture*/
1235
+ SND_SOC_DAPM_AIF_OUT("Out AIF", "Capture", 0, SND_SOC_NOPM, 0, 0),
1236
+
1237
+ SND_SOC_DAPM_SWITCH("I2S ADC1L", SND_SOC_NOPM, 0, 0, &i2sadc1l_ctl),
1238
+ SND_SOC_DAPM_SWITCH("I2S ADC1R", SND_SOC_NOPM, 0, 0, &i2sadc1r_ctl),
1239
+ SND_SOC_DAPM_SWITCH("I2S ADC2L", SND_SOC_NOPM, 0, 0, &i2sadc2l_ctl),
1240
+ SND_SOC_DAPM_SWITCH("I2S ADC2R", SND_SOC_NOPM, 0, 0, &i2sadc2r_ctl),
1241
+
1242
+ SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC1", CX2072X_ADC1_POWER_STATE,
1243
+ 0, 0xff, 0x00, 0x03),
1244
+ SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC2", CX2072X_ADC2_POWER_STATE,
1245
+ 0, 0xff, 0x00, 0x03),
1246
+
1247
+ SND_SOC_DAPM_MUX("ADC1 Mux", SND_SOC_NOPM, 0, 0, &adc1_mux),
1248
+ SND_SOC_DAPM_MUX("ADC2 Mux", SND_SOC_NOPM, 0, 0, &adc2_mux),
1249
+
1250
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortB Power",
1251
+ CX2072X_PORTB_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1252
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortC Power",
1253
+ CX2072X_PORTC_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1254
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortD Power",
1255
+ CX2072X_PORTD_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1256
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortE Power",
1257
+ CX2072X_PORTE_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1258
+ SND_SOC_DAPM_REG(snd_soc_dapm_supply, "Widget15 Power",
1259
+ CX2072X_MIXER_POWER_STATE, 0, 0xfff, 0x00, 0x03),
1260
+
1261
+ SND_SOC_DAPM_MIXER("Widget15 Mixer", SND_SOC_NOPM, 0, 0,
1262
+ wid15_mix, ARRAY_SIZE(wid15_mix)),
1263
+ SND_SOC_DAPM_SWITCH("PortB In En", SND_SOC_NOPM, 0, 0, &portbinen_ctl),
1264
+ SND_SOC_DAPM_SWITCH("PortC In En", SND_SOC_NOPM, 0, 0, &portcinen_ctl),
1265
+ SND_SOC_DAPM_SWITCH("PortD In En", SND_SOC_NOPM, 0, 0, &portdinen_ctl),
1266
+ SND_SOC_DAPM_SWITCH("PortE In En", SND_SOC_NOPM, 0, 0, &porteinen_ctl),
1267
+
1268
+ SND_SOC_DAPM_MICBIAS("Headset Bias", CX2072X_ANALOG_TEST11, 1, 0),
1269
+ SND_SOC_DAPM_MICBIAS("PortB Mic Bias", CX2072X_PORTB_PIN_CTRL, 2, 0),
1270
+ SND_SOC_DAPM_MICBIAS("PortD Mic Bias", CX2072X_PORTD_PIN_CTRL, 2, 0),
1271
+ SND_SOC_DAPM_MICBIAS("PortE Mic Bias", CX2072X_PORTE_PIN_CTRL, 2, 0),
1272
+ SND_SOC_DAPM_INPUT("PORTB"),
1273
+ SND_SOC_DAPM_INPUT("PORTC"),
1274
+ SND_SOC_DAPM_INPUT("PORTD"),
1275
+ SND_SOC_DAPM_INPUT("PORTEIN"),
1276
+
1277
+};
1278
+
1279
+static const struct snd_soc_dapm_route cx2072x_intercon[] = {
1280
+ /* Playback */
1281
+ {"In AIF", NULL, "AFG Power"},
1282
+ {"I2S DAC1L", "Switch", "In AIF"},
1283
+ {"I2S DAC1R", "Switch", "In AIF"},
1284
+ {"I2S DAC2L", "Switch", "In AIF"},
1285
+ {"I2S DAC2R", "Switch", "In AIF"},
1286
+ {"DAC1", NULL, "I2S DAC1L"},
1287
+ {"DAC1", NULL, "I2S DAC1R"},
1288
+ {"DAC2", NULL, "I2S DAC2L"},
1289
+ {"DAC2", NULL, "I2S DAC2R"},
1290
+ {"PortA Mux", "DAC1 Switch", "DAC1"},
1291
+ {"PortA Mux", "DAC2 Switch", "DAC2"},
1292
+ {"PortG Mux", "DAC1 Switch", "DAC1"},
1293
+ {"PortG Mux", "DAC2 Switch", "DAC2"},
1294
+ {"PortE Mux", "DAC1 Switch", "DAC1"},
1295
+ {"PortE Mux", "DAC2 Switch", "DAC2"},
1296
+ {"PortM Mux", "DAC1 Switch", "DAC1"},
1297
+ {"PortM Mux", "DAC2 Switch", "DAC2"},
1298
+ {"Widget15 Mixer", "DAC1L Switch", "DAC1"},
1299
+ {"Widget15 Mixer", "DAC1R Switch", "DAC2"},
1300
+ {"Widget15 Mixer", "DAC2L Switch", "DAC1"},
1301
+ {"Widget15 Mixer", "DAC2R Switch", "DAC2"},
1302
+ {"Widget15 Mixer", NULL, "Widget15 Power"},
1303
+ {"PortA Out En", "Switch", "PortA Mux"},
1304
+ {"PortG Out En", "Switch", "PortG Mux"},
1305
+ {"PortE Out En", "Switch", "PortE Mux"},
1306
+ {"PortM Out En", "Switch", "PortM Mux"},
1307
+ {"PortA Mux", NULL, "PortA Power"},
1308
+ {"PortG Mux", NULL, "PortG Power"},
1309
+ {"PortE Mux", NULL, "PortE Power"},
1310
+ {"PortM Mux", NULL, "PortM Power"},
1311
+ {"PortA Out En", NULL, "PortA Power"},
1312
+ {"PortG Out En", NULL, "PortG Power"},
1313
+ {"PortE Out En", NULL, "PortE Power"},
1314
+ {"PortM Out En", NULL, "PortM Power"},
1315
+ {"PORTA", NULL, "PortA Out En"},
1316
+ {"PORTG", NULL, "PortG Out En"},
1317
+ {"PORTE", NULL, "PortE Out En"},
1318
+ {"PORTM", NULL, "PortM Out En"},
1319
+
1320
+ /* Capture */
1321
+ {"PORTD", NULL, "Headset Bias"},
1322
+ {"PortB In En", "Switch", "PORTB"},
1323
+ {"PortC In En", "Switch", "PORTC"},
1324
+ {"PortD In En", "Switch", "PORTD"},
1325
+ {"PortE In En", "Switch", "PORTEIN"},
1326
+ {"ADC1 Mux", "PortB Switch", "PortB In En"},
1327
+ {"ADC1 Mux", "PortC Switch", "PortC In En"},
1328
+ {"ADC1 Mux", "PortD Switch", "PortD In En"},
1329
+ {"ADC1 Mux", "PortE Switch", "PortE In En"},
1330
+ {"ADC1 Mux", "Widget15 Switch", "Widget15 Mixer"},
1331
+ {"ADC2 Mux", "PortC Switch", "PortC In En"},
1332
+ {"ADC2 Mux", "Widget15 Switch", "Widget15 Mixer"},
1333
+ {"ADC1", NULL, "ADC1 Mux"},
1334
+ {"ADC2", NULL, "ADC2 Mux"},
1335
+ {"I2S ADC1L", "Switch", "ADC1"},
1336
+ {"I2S ADC1R", "Switch", "ADC1"},
1337
+ {"I2S ADC2L", "Switch", "ADC2"},
1338
+ {"I2S ADC2R", "Switch", "ADC2"},
1339
+ {"Out AIF", NULL, "I2S ADC1L"},
1340
+ {"Out AIF", NULL, "I2S ADC1R"},
1341
+ {"Out AIF", NULL, "I2S ADC2L"},
1342
+ {"Out AIF", NULL, "I2S ADC2R"},
1343
+ {"Out AIF", NULL, "AFG Power"},
1344
+ {"AEC REF", NULL, "Out AIF"},
1345
+ {"PortB In En", NULL, "PortB Power"},
1346
+ {"PortC In En", NULL, "PortC Power"},
1347
+ {"PortD In En", NULL, "PortD Power"},
1348
+ {"PortE In En", NULL, "PortE Power"},
1349
+};
1350
+
1351
+static int cx2072x_set_bias_level(struct snd_soc_component *codec,
1352
+ enum snd_soc_bias_level level)
1353
+{
1354
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1355
+ const enum snd_soc_bias_level old_level =
1356
+ snd_soc_component_get_bias_level(codec);
1357
+
1358
+ if (level == SND_SOC_BIAS_STANDBY && old_level == SND_SOC_BIAS_OFF)
1359
+ regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 0);
1360
+ else if (level == SND_SOC_BIAS_OFF && old_level != SND_SOC_BIAS_OFF)
1361
+ regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 3);
1362
+
1363
+ return 0;
1364
+}
1365
+
1366
+/*
1367
+ * FIXME: the whole jack detection code below is pretty platform-specific;
1368
+ * it has lots of implicit assumptions about the pins, etc.
1369
+ * However, since we have no other code and reference, take this hard-coded
1370
+ * setup for now. Once when we have different platform implementations,
1371
+ * this needs to be rewritten in a more generic form, or moving into the
1372
+ * platform data.
1373
+ */
1374
+static void cx2072x_enable_jack_detect(struct snd_soc_component *codec)
1375
+{
1376
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1377
+ struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
1378
+
1379
+ /* No-sticky input type */
1380
+ regmap_write(cx2072x->regmap, CX2072X_GPIO_STICKY_MASK, 0x1f);
1381
+
1382
+ /* Use GPOI0 as interrupt pin */
1383
+ regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0x12 << 24);
1384
+
1385
+ /* Enables unsolitited message on PortA */
1386
+ regmap_write(cx2072x->regmap, CX2072X_PORTA_UNSOLICITED_RESPONSE, 0x80);
1387
+
1388
+ /* support both nokia and apple headset set. Monitor time = 275 ms */
1389
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST15, 0x73);
1390
+
1391
+ /* Disable TIP detection */
1392
+ regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST12, 0x300);
1393
+
1394
+ /* Switch MusicD3Live pin to GPIO */
1395
+ regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST1, 0);
1396
+
1397
+ snd_soc_dapm_mutex_lock(dapm);
1398
+
1399
+ snd_soc_dapm_force_enable_pin_unlocked(dapm, "PORTD");
1400
+ snd_soc_dapm_force_enable_pin_unlocked(dapm, "Headset Bias");
1401
+ snd_soc_dapm_force_enable_pin_unlocked(dapm, "PortD Mic Bias");
1402
+
1403
+ snd_soc_dapm_mutex_unlock(dapm);
1404
+}
1405
+
1406
+static void cx2072x_disable_jack_detect(struct snd_soc_component *codec)
1407
+{
1408
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1409
+
1410
+ regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0);
1411
+ regmap_write(cx2072x->regmap, CX2072X_PORTA_UNSOLICITED_RESPONSE, 0);
1412
+}
1413
+
1414
+static int cx2072x_jack_status_check(void *data)
1415
+{
1416
+ struct snd_soc_component *codec = data;
1417
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1418
+ unsigned int jack;
1419
+ unsigned int type = 0;
1420
+ int state = 0;
1421
+
1422
+ mutex_lock(&cx2072x->lock);
1423
+
1424
+ regmap_read(cx2072x->regmap, CX2072X_PORTA_PIN_SENSE, &jack);
1425
+ jack = jack >> 24;
1426
+ regmap_read(cx2072x->regmap, CX2072X_DIGITAL_TEST11, &type);
1427
+
1428
+ if (jack == 0x80) {
1429
+ type = type >> 8;
1430
+
1431
+ if (type & 0x8) {
1432
+ /* Apple headset */
1433
+ state |= SND_JACK_HEADSET;
1434
+ if (type & 0x2)
1435
+ state |= SND_JACK_BTN_0;
1436
+ } else if (type & 0x4) {
1437
+ /* Nokia headset */
1438
+ state |= SND_JACK_HEADPHONE;
1439
+ } else {
1440
+ /* Headphone */
1441
+ state |= SND_JACK_HEADPHONE;
1442
+ }
1443
+ }
1444
+
1445
+ /* clear interrupt */
1446
+ regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0x12 << 24);
1447
+
1448
+ mutex_unlock(&cx2072x->lock);
1449
+
1450
+ dev_dbg(codec->dev, "CX2072X_HSDETECT type=0x%X,Jack state = %x\n",
1451
+ type, state);
1452
+ return state;
1453
+}
1454
+
1455
+static const struct snd_soc_jack_gpio cx2072x_jack_gpio = {
1456
+ .name = "headset",
1457
+ .report = SND_JACK_HEADSET | SND_JACK_BTN_0,
1458
+ .debounce_time = 150,
1459
+ .wake = true,
1460
+ .jack_status_check = cx2072x_jack_status_check,
1461
+};
1462
+
1463
+static int cx2072x_set_jack(struct snd_soc_component *codec,
1464
+ struct snd_soc_jack *jack, void *data)
1465
+{
1466
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1467
+ int err;
1468
+
1469
+ if (!jack) {
1470
+ cx2072x_disable_jack_detect(codec);
1471
+ return 0;
1472
+ }
1473
+
1474
+ if (!cx2072x->jack_gpio.gpiod_dev) {
1475
+ cx2072x->jack_gpio = cx2072x_jack_gpio;
1476
+ cx2072x->jack_gpio.gpiod_dev = codec->dev;
1477
+ cx2072x->jack_gpio.data = codec;
1478
+ err = snd_soc_jack_add_gpios(jack, 1, &cx2072x->jack_gpio);
1479
+ if (err) {
1480
+ cx2072x->jack_gpio.gpiod_dev = NULL;
1481
+ return err;
1482
+ }
1483
+ }
1484
+
1485
+ cx2072x_enable_jack_detect(codec);
1486
+ return 0;
1487
+}
1488
+
1489
+static int cx2072x_probe(struct snd_soc_component *codec)
1490
+{
1491
+ struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec);
1492
+
1493
+ cx2072x->codec = codec;
1494
+
1495
+ /*
1496
+ * FIXME: below is, again, a very platform-specific init sequence,
1497
+ * but we keep the code here just for simplicity. It seems that all
1498
+ * existing hardware implementations require this, so there is no very
1499
+ * much reason to move this out of the codec driver to the platform
1500
+ * data.
1501
+ * But of course it's no "right" thing; if you are a good boy, don't
1502
+ * read and follow the code like this!
1503
+ */
1504
+ pm_runtime_get_sync(codec->dev);
1505
+ regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 0);
1506
+
1507
+ regmap_multi_reg_write(cx2072x->regmap, cx2072x_reg_init,
1508
+ ARRAY_SIZE(cx2072x_reg_init));
1509
+
1510
+ /* configure PortC as input device */
1511
+ regmap_update_bits(cx2072x->regmap, CX2072X_PORTC_PIN_CTRL,
1512
+ 0x20, 0x20);
1513
+
1514
+ regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2,
1515
+ 0x84, 0xff);
1516
+
1517
+ regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 3);
1518
+ pm_runtime_put(codec->dev);
1519
+
1520
+ return 0;
1521
+}
1522
+
19691523 static const struct snd_soc_component_driver soc_codec_driver_cx2072x = {
19701524 .probe = cx2072x_probe,
1971
- .remove = cx2072x_remove,
19721525 .set_bias_level = cx2072x_set_bias_level,
1973
- .suspend_bias_off = 1,
1974
- .idle_bias_on = 1,
1526
+ .set_jack = cx2072x_set_jack,
19751527 .controls = cx2072x_snd_controls,
19761528 .num_controls = ARRAY_SIZE(cx2072x_snd_controls),
19771529 .dapm_widgets = cx2072x_dapm_widgets,
....@@ -1986,15 +1538,21 @@
19861538 static struct snd_soc_dai_ops cx2072x_dai_ops = {
19871539 .set_sysclk = cx2072x_set_dai_sysclk,
19881540 .set_fmt = cx2072x_set_dai_fmt,
1989
- .set_tdm_slot = cx2072x_set_tdm_slot,
19901541 .hw_params = cx2072x_hw_params,
1991
- .digital_mute = cx2072x_digital_mute,
19921542 .set_bclk_ratio = cx2072x_set_dai_bclk_ratio,
19931543 };
19941544
1995
-/*
1996
- * DAI driver
1997
- */
1545
+static int cx2072x_dsp_dai_probe(struct snd_soc_dai *dai)
1546
+{
1547
+ struct cx2072x_priv *cx2072x =
1548
+ snd_soc_component_get_drvdata(dai->component);
1549
+
1550
+ cx2072x->en_aec_ref = true;
1551
+ return 0;
1552
+}
1553
+
1554
+#define CX2072X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
1555
+
19981556 static struct snd_soc_dai_driver soc_codec_cx2072x_dai[] = {
19991557 { /* playback and capture */
20001558 .name = "cx2072x-hifi",
....@@ -2003,7 +1561,7 @@
20031561 .stream_name = "Playback",
20041562 .channels_min = 1,
20051563 .channels_max = 2,
2006
- .rates = CX2072X_RATES_DSP, /* CX2072X_RATES */
1564
+ .rates = CX2072X_RATES_DSP,
20071565 .formats = CX2072X_FORMATS,
20081566 },
20091567 .capture = {
....@@ -2016,11 +1574,12 @@
20161574 .ops = &cx2072x_dai_ops,
20171575 .symmetric_rates = 1,
20181576 },
2019
- { /* plabayck only, return echo reference through I2S TX */
1577
+ { /* plabayck only, return echo reference to Conexant DSP chip */
20201578 .name = "cx2072x-dsp",
2021
- .id = CX2072X_DAI_DSP,
1579
+ .id = CX2072X_DAI_DSP,
1580
+ .probe = cx2072x_dsp_dai_probe,
20221581 .playback = {
2023
- .stream_name = "Playback",
1582
+ .stream_name = "DSP Playback",
20241583 .channels_min = 2,
20251584 .channels_max = 2,
20261585 .rates = CX2072X_RATES_DSP,
....@@ -2028,8 +1587,18 @@
20281587 },
20291588 .ops = &cx2072x_dai_ops,
20301589 },
1590
+ { /* plabayck only, return echo reference through I2S TX */
1591
+ .name = "cx2072x-aec",
1592
+ .id = 3,
1593
+ .capture = {
1594
+ .stream_name = "AEC Capture",
1595
+ .channels_min = 2,
1596
+ .channels_max = 2,
1597
+ .rates = CX2072X_RATES_DSP,
1598
+ .formats = CX2072X_FORMATS,
1599
+ },
1600
+ },
20311601 };
2032
-EXPORT_SYMBOL_GPL(soc_codec_cx2072x_dai);
20331602
20341603 static const struct regmap_config cx2072x_regmap = {
20351604 .reg_bits = 16,
....@@ -2040,82 +1609,89 @@
20401609 .cache_type = REGCACHE_RBTREE,
20411610 .readable_reg = cx2072x_readable_register,
20421611 .volatile_reg = cx2072x_volatile_register,
1612
+ /* Needs custom read/write functions for various register lengths */
20431613 .reg_read = cx2072x_reg_read,
20441614 .reg_write = cx2072x_reg_write,
20451615 };
20461616
2047
-static void cx2072x_enable_spk(struct cx2072x_priv *cx2072x, bool enable)
1617
+static int __maybe_unused cx2072x_runtime_suspend(struct device *dev)
20481618 {
2049
- gpiod_set_value(cx2072x->spk_ctl_gpio, enable);
1619
+ struct cx2072x_priv *cx2072x = dev_get_drvdata(dev);
1620
+
1621
+ clk_disable_unprepare(cx2072x->mclk);
1622
+ return 0;
1623
+}
1624
+
1625
+static int __maybe_unused cx2072x_runtime_resume(struct device *dev)
1626
+{
1627
+ struct cx2072x_priv *cx2072x = dev_get_drvdata(dev);
1628
+
1629
+ return clk_prepare_enable(cx2072x->mclk);
20501630 }
20511631
20521632 static int cx2072x_i2c_probe(struct i2c_client *i2c,
20531633 const struct i2c_device_id *id)
20541634 {
20551635 struct cx2072x_priv *cx2072x;
1636
+ unsigned int ven_id, rev_id;
1637
+ int ret;
20561638
2057
- cx2072x = devm_kzalloc(&i2c->dev, sizeof(*cx2072x), GFP_KERNEL);
1639
+ cx2072x = devm_kzalloc(&i2c->dev, sizeof(struct cx2072x_priv),
1640
+ GFP_KERNEL);
20581641 if (!cx2072x)
20591642 return -ENOMEM;
20601643
2061
- mutex_init(&cx2072x->lock);
2062
-
2063
- cx2072x->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &cx2072x_regmap);
1644
+ cx2072x->regmap = devm_regmap_init(&i2c->dev, NULL, i2c,
1645
+ &cx2072x_regmap);
20641646 if (IS_ERR(cx2072x->regmap))
20651647 return PTR_ERR(cx2072x->regmap);
20661648
1649
+ mutex_init(&cx2072x->lock);
1650
+
20671651 i2c_set_clientdata(i2c, cx2072x);
2068
-
2069
- cx2072x->spk_ctl_gpio = devm_gpiod_get_optional(&i2c->dev, "spk-con-gpio",
2070
- GPIOD_OUT_LOW);
2071
- if (IS_ERR(cx2072x->spk_ctl_gpio))
2072
- return PTR_ERR(cx2072x->spk_ctl_gpio);
2073
-
2074
- cx2072x_enable_spk(cx2072x, true);
20751652
20761653 cx2072x->dev = &i2c->dev;
20771654 cx2072x->pll_changed = true;
20781655 cx2072x->i2spcm_changed = true;
2079
-
2080
- /*
2081
- * sets the frame size to
2082
- * Frame size = number of channel * sample width
2083
- */
20841656 cx2072x->bclk_ratio = 0;
20851657
2086
- return devm_snd_soc_register_component(cx2072x->dev,
2087
- &soc_codec_driver_cx2072x,
2088
- soc_codec_cx2072x_dai,
2089
- ARRAY_SIZE(soc_codec_cx2072x_dai));
1658
+ cx2072x->mclk = devm_clk_get(cx2072x->dev, "mclk");
1659
+ if (IS_ERR(cx2072x->mclk)) {
1660
+ dev_err(cx2072x->dev, "Failed to get MCLK\n");
1661
+ return PTR_ERR(cx2072x->mclk);
1662
+ }
1663
+
1664
+ regmap_read(cx2072x->regmap, CX2072X_VENDOR_ID, &ven_id);
1665
+ regmap_read(cx2072x->regmap, CX2072X_REVISION_ID, &rev_id);
1666
+
1667
+ dev_info(cx2072x->dev, "codec version: %08x,%08x\n", ven_id, rev_id);
1668
+
1669
+ ret = devm_snd_soc_register_component(cx2072x->dev,
1670
+ &soc_codec_driver_cx2072x,
1671
+ soc_codec_cx2072x_dai,
1672
+ ARRAY_SIZE(soc_codec_cx2072x_dai));
1673
+ if (ret < 0)
1674
+ return ret;
1675
+
1676
+ pm_runtime_use_autosuspend(cx2072x->dev);
1677
+ pm_runtime_enable(cx2072x->dev);
1678
+
1679
+ return 0;
20901680 }
20911681
2092
-static void cx2072x_i2c_shutdown(struct i2c_client *client)
1682
+static int cx2072x_i2c_remove(struct i2c_client *i2c)
20931683 {
2094
- struct cx2072x_priv *cx2072x = i2c_get_clientdata(client);
2095
-
2096
- cx2072x_set_bias_level(cx2072x->component, SND_SOC_BIAS_OFF);
1684
+ pm_runtime_disable(&i2c->dev);
1685
+ return 0;
20971686 }
2098
-
2099
-const struct dev_pm_ops cx2072x_pm_ops = {
2100
- SET_RUNTIME_PM_OPS(cx2072x_runtime_suspend, cx2072x_runtime_resume,
2101
- NULL)
2102
-};
21031687
21041688 static const struct i2c_device_id cx2072x_i2c_id[] = {
21051689 { "cx20721", 0 },
2106
- { "cx20722", 0 },
2107
- { "14F10720", 0 },
1690
+ { "cx20723", 0 },
21081691 {}
21091692 };
21101693 MODULE_DEVICE_TABLE(i2c, cx2072x_i2c_id);
21111694
2112
-static const struct of_device_id cx2072x_of_match[] = {
2113
- { .compatible = "cnxt,cx20721", },
2114
- { .compatible = "cnxt,cx20723", },
2115
- { .compatible = "cnxt,cx7601", },
2116
- {}
2117
-};
2118
-MODULE_DEVICE_TABLE(of, cx2072x_of_match);
21191695 #ifdef CONFIG_ACPI
21201696 static struct acpi_device_id cx2072x_acpi_match[] = {
21211697 { "14F10720", 0 },
....@@ -2124,18 +1700,22 @@
21241700 MODULE_DEVICE_TABLE(acpi, cx2072x_acpi_match);
21251701 #endif
21261702
1703
+static const struct dev_pm_ops cx2072x_runtime_pm = {
1704
+ SET_RUNTIME_PM_OPS(cx2072x_runtime_suspend, cx2072x_runtime_resume,
1705
+ NULL)
1706
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1707
+ pm_runtime_force_resume)
1708
+};
1709
+
21271710 static struct i2c_driver cx2072x_i2c_driver = {
2128
- .probe = cx2072x_i2c_probe,
2129
- .shutdown = cx2072x_i2c_shutdown,
2130
- .id_table = cx2072x_i2c_id,
21311711 .driver = {
21321712 .name = "cx2072x",
2133
- .of_match_table = cx2072x_of_match,
2134
-#ifdef CONFIG_ACPI
21351713 .acpi_match_table = ACPI_PTR(cx2072x_acpi_match),
2136
-#endif
2137
- .pm = &cx2072x_pm_ops,
1714
+ .pm = &cx2072x_runtime_pm,
21381715 },
1716
+ .probe = cx2072x_i2c_probe,
1717
+ .remove = cx2072x_i2c_remove,
1718
+ .id_table = cx2072x_i2c_id,
21391719 };
21401720
21411721 module_i2c_driver(cx2072x_i2c_driver);
....@@ -2143,4 +1723,3 @@
21431723 MODULE_DESCRIPTION("ASoC cx2072x Codec Driver");
21441724 MODULE_AUTHOR("Simon Ho <simon.ho@conexant.com>");
21451725 MODULE_LICENSE("GPL");
2146
-