~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/cx2072x.c

Version: ~ [ linux-5.16-rc1 ] ~ [ linux-5.15.2 ] ~ [ linux-5.14.18 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.79 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.159 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.217 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.255 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.290 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.292 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 //
  3 // ALSA SoC CX20721/CX20723 codec driver
  4 //
  5 // Copyright:   (C) 2017 Conexant Systems, Inc.
  6 // Author:      Simon Ho, <Simon.ho@conexant.com>
  7 //
  8 // TODO: add support for TDM mode.
  9 //
 10 
 11 #include <linux/acpi.h>
 12 #include <linux/clk.h>
 13 #include <linux/delay.h>
 14 #include <linux/gpio.h>
 15 #include <linux/init.h>
 16 #include <linux/i2c.h>
 17 #include <linux/module.h>
 18 #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>
 23 #include <sound/core.h>
 24 #include <sound/initval.h>
 25 #include <sound/jack.h>
 26 #include <sound/pcm.h>
 27 #include <sound/pcm_params.h>
 28 #include <sound/tlv.h>
 29 #include <sound/soc.h>
 30 #include <sound/soc-dapm.h>
 31 #include "cx2072x.h"
 32 
 33 #define PLL_OUT_HZ_48   (1024 * 3 * 48000)
 34 #define BITS_PER_SLOT   8
 35 
 36 /* codec private data */
 37 struct cx2072x_priv {
 38         struct regmap *regmap;
 39         struct clk *mclk;
 40         unsigned int mclk_rate;
 41         struct device *dev;
 42         struct snd_soc_component *codec;
 43         struct snd_soc_jack_gpio jack_gpio;
 44         struct mutex lock;
 45         unsigned int bclk_ratio;
 46         bool pll_changed;
 47         bool i2spcm_changed;
 48         int sample_size;
 49         int frame_size;
 50         int sample_rate;
 51         unsigned int dai_fmt;
 52         bool en_aec_ref;
 53 };
 54 
 55 /*
 56  * DAC/ADC Volume
 57  *
 58  * max : 74 : 0 dB
 59  *       ( in 1 dB  step )
 60  * min : 0 : -74 dB
 61  */
 62 static const DECLARE_TLV_DB_SCALE(adc_tlv, -7400, 100, 0);
 63 static const DECLARE_TLV_DB_SCALE(dac_tlv, -7400, 100, 0);
 64 static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 1200, 0);
 65 
 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 );
 75 
 76 /* Lookup table for PRE_DIV */
 77 static const struct {
 78         unsigned int mclk;
 79         unsigned int div;
 80 } mclk_pre_div[] = {
 81         { 6144000, 1 },
 82         { 12288000, 2 },
 83         { 19200000, 3 },
 84         { 26000000, 4 },
 85         { 28224000, 5 },
 86         { 36864000, 6 },
 87         { 36864000, 7 },
 88         { 48000000, 8 },
 89         { 49152000, 8 },
 90 };
 91 
 92 /*
 93  * cx2072x register cache.
 94  */
 95 static const struct reg_default cx2072x_reg_defaults[] = {
 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 },
228 };
229 
230 /*
231  * register initialization
232  */
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 */
251 };
252 
253 static unsigned int cx2072x_register_size(unsigned int reg)
254 {
255         switch (reg) {
256         case CX2072X_VENDOR_ID:
257         case CX2072X_REVISION_ID:
258         case CX2072X_PORTA_PIN_SENSE:
259         case CX2072X_PORTB_PIN_SENSE:
260         case CX2072X_PORTD_PIN_SENSE:
261         case CX2072X_PORTE_PIN_SENSE:
262         case CX2072X_PORTF_PIN_SENSE:
263         case CX2072X_I2SPCM_CONTROL1:
264         case CX2072X_I2SPCM_CONTROL2:
265         case CX2072X_I2SPCM_CONTROL3:
266         case CX2072X_I2SPCM_CONTROL4:
267         case CX2072X_I2SPCM_CONTROL5:
268         case CX2072X_I2SPCM_CONTROL6:
269         case CX2072X_UM_INTERRUPT_CRTL_E:
270         case CX2072X_EQ_G_COEFF:
271         case CX2072X_SPKR_DRC_CONTROL:
272         case CX2072X_SPKR_DRC_TEST:
273         case CX2072X_DIGITAL_BIOS_TEST0:
274         case CX2072X_DIGITAL_BIOS_TEST2:
275                 return 4;
276         case CX2072X_EQ_ENABLE_BYPASS:
277         case CX2072X_EQ_B0_COEFF:
278         case CX2072X_EQ_B1_COEFF:
279         case CX2072X_EQ_B2_COEFF:
280         case CX2072X_EQ_A1_COEFF:
281         case CX2072X_EQ_A2_COEFF:
282         case CX2072X_DAC1_CONVERTER_FORMAT:
283         case CX2072X_DAC2_CONVERTER_FORMAT:
284         case CX2072X_ADC1_CONVERTER_FORMAT:
285         case CX2072X_ADC2_CONVERTER_FORMAT:
286         case CX2072X_CODEC_TEST2:
287         case CX2072X_CODEC_TEST9:
288         case CX2072X_CODEC_TEST20:
289         case CX2072X_CODEC_TEST26:
290         case CX2072X_ANALOG_TEST3:
291         case CX2072X_ANALOG_TEST4:
292         case CX2072X_ANALOG_TEST5:
293         case CX2072X_ANALOG_TEST6:
294         case CX2072X_ANALOG_TEST7:
295         case CX2072X_ANALOG_TEST8:
296         case CX2072X_ANALOG_TEST9:
297         case CX2072X_ANALOG_TEST10:
298         case CX2072X_ANALOG_TEST11:
299         case CX2072X_ANALOG_TEST12:
300         case CX2072X_ANALOG_TEST13:
301         case CX2072X_DIGITAL_TEST0:
302         case CX2072X_DIGITAL_TEST1:
303         case CX2072X_DIGITAL_TEST11:
304         case CX2072X_DIGITAL_TEST12:
305         case CX2072X_DIGITAL_TEST15:
306         case CX2072X_DIGITAL_TEST16:
307         case CX2072X_DIGITAL_TEST17:
308         case CX2072X_DIGITAL_TEST18:
309         case CX2072X_DIGITAL_TEST19:
310         case CX2072X_DIGITAL_TEST20:
311                 return 2;
312         default:
313                 return 1;
314         }
315 }
316 
317 static bool cx2072x_readable_register(struct device *dev, unsigned int reg)
318 {
319         switch (reg) {
320         case CX2072X_VENDOR_ID:
321         case CX2072X_REVISION_ID:
322         case CX2072X_CURRENT_BCLK_FREQUENCY:
323         case CX2072X_AFG_POWER_STATE:
324         case CX2072X_UM_RESPONSE:
325         case CX2072X_GPIO_DATA:
326         case CX2072X_GPIO_ENABLE:
327         case CX2072X_GPIO_DIRECTION:
328         case CX2072X_GPIO_WAKE:
329         case CX2072X_GPIO_UM_ENABLE:
330         case CX2072X_GPIO_STICKY_MASK:
331         case CX2072X_DAC1_CONVERTER_FORMAT:
332         case CX2072X_DAC1_AMP_GAIN_RIGHT:
333         case CX2072X_DAC1_AMP_GAIN_LEFT:
334         case CX2072X_DAC1_POWER_STATE:
335         case CX2072X_DAC1_CONVERTER_STREAM_CHANNEL:
336         case CX2072X_DAC1_EAPD_ENABLE:
337         case CX2072X_DAC2_CONVERTER_FORMAT:
338         case CX2072X_DAC2_AMP_GAIN_RIGHT:
339         case CX2072X_DAC2_AMP_GAIN_LEFT:
340         case CX2072X_DAC2_POWER_STATE:
341         case CX2072X_DAC2_CONVERTER_STREAM_CHANNEL:
342         case CX2072X_ADC1_CONVERTER_FORMAT:
343         case CX2072X_ADC1_AMP_GAIN_RIGHT_0:
344         case CX2072X_ADC1_AMP_GAIN_LEFT_0:
345         case CX2072X_ADC1_AMP_GAIN_RIGHT_1:
346         case CX2072X_ADC1_AMP_GAIN_LEFT_1:
347         case CX2072X_ADC1_AMP_GAIN_RIGHT_2:
348         case CX2072X_ADC1_AMP_GAIN_LEFT_2:
349         case CX2072X_ADC1_AMP_GAIN_RIGHT_3:
350         case CX2072X_ADC1_AMP_GAIN_LEFT_3:
351         case CX2072X_ADC1_AMP_GAIN_RIGHT_4:
352         case CX2072X_ADC1_AMP_GAIN_LEFT_4:
353         case CX2072X_ADC1_AMP_GAIN_RIGHT_5:
354         case CX2072X_ADC1_AMP_GAIN_LEFT_5:
355         case CX2072X_ADC1_AMP_GAIN_RIGHT_6:
356         case CX2072X_ADC1_AMP_GAIN_LEFT_6:
357         case CX2072X_ADC1_CONNECTION_SELECT_CONTROL:
358         case CX2072X_ADC1_POWER_STATE:
359         case CX2072X_ADC1_CONVERTER_STREAM_CHANNEL:
360         case CX2072X_ADC2_CONVERTER_FORMAT:
361         case CX2072X_ADC2_AMP_GAIN_RIGHT_0:
362         case CX2072X_ADC2_AMP_GAIN_LEFT_0:
363         case CX2072X_ADC2_AMP_GAIN_RIGHT_1:
364         case CX2072X_ADC2_AMP_GAIN_LEFT_1:
365         case CX2072X_ADC2_AMP_GAIN_RIGHT_2:
366         case CX2072X_ADC2_AMP_GAIN_LEFT_2:
367         case CX2072X_ADC2_CONNECTION_SELECT_CONTROL:
368         case CX2072X_ADC2_POWER_STATE:
369         case CX2072X_ADC2_CONVERTER_STREAM_CHANNEL:
370         case CX2072X_PORTA_CONNECTION_SELECT_CTRL:
371         case CX2072X_PORTA_POWER_STATE:
372         case CX2072X_PORTA_PIN_CTRL:
373         case CX2072X_PORTA_UNSOLICITED_RESPONSE:
374         case CX2072X_PORTA_PIN_SENSE:
375         case CX2072X_PORTA_EAPD_BTL:
376         case CX2072X_PORTB_POWER_STATE:
377         case CX2072X_PORTB_PIN_CTRL:
378         case CX2072X_PORTB_UNSOLICITED_RESPONSE:
379         case CX2072X_PORTB_PIN_SENSE:
380         case CX2072X_PORTB_EAPD_BTL:
381         case CX2072X_PORTB_GAIN_RIGHT:
382         case CX2072X_PORTB_GAIN_LEFT:
383         case CX2072X_PORTC_POWER_STATE:
384         case CX2072X_PORTC_PIN_CTRL:
385         case CX2072X_PORTC_GAIN_RIGHT:
386         case CX2072X_PORTC_GAIN_LEFT:
387         case CX2072X_PORTD_POWER_STATE:
388         case CX2072X_PORTD_PIN_CTRL:
389         case CX2072X_PORTD_UNSOLICITED_RESPONSE:
390         case CX2072X_PORTD_PIN_SENSE:
391         case CX2072X_PORTD_GAIN_RIGHT:
392         case CX2072X_PORTD_GAIN_LEFT:
393         case CX2072X_PORTE_CONNECTION_SELECT_CTRL:
394         case CX2072X_PORTE_POWER_STATE:
395         case CX2072X_PORTE_PIN_CTRL:
396         case CX2072X_PORTE_UNSOLICITED_RESPONSE:
397         case CX2072X_PORTE_PIN_SENSE:
398         case CX2072X_PORTE_EAPD_BTL:
399         case CX2072X_PORTE_GAIN_RIGHT:
400         case CX2072X_PORTE_GAIN_LEFT:
401         case CX2072X_PORTF_POWER_STATE:
402         case CX2072X_PORTF_PIN_CTRL:
403         case CX2072X_PORTF_UNSOLICITED_RESPONSE:
404         case CX2072X_PORTF_PIN_SENSE:
405         case CX2072X_PORTF_GAIN_RIGHT:
406         case CX2072X_PORTF_GAIN_LEFT:
407         case CX2072X_PORTG_POWER_STATE:
408         case CX2072X_PORTG_PIN_CTRL:
409         case CX2072X_PORTG_CONNECTION_SELECT_CTRL:
410         case CX2072X_PORTG_EAPD_BTL:
411         case CX2072X_PORTM_POWER_STATE:
412         case CX2072X_PORTM_PIN_CTRL:
413         case CX2072X_PORTM_CONNECTION_SELECT_CTRL:
414         case CX2072X_PORTM_EAPD_BTL:
415         case CX2072X_MIXER_POWER_STATE:
416         case CX2072X_MIXER_GAIN_RIGHT_0:
417         case CX2072X_MIXER_GAIN_LEFT_0:
418         case CX2072X_MIXER_GAIN_RIGHT_1:
419         case CX2072X_MIXER_GAIN_LEFT_1:
420         case CX2072X_EQ_ENABLE_BYPASS:
421         case CX2072X_EQ_B0_COEFF:
422         case CX2072X_EQ_B1_COEFF:
423         case CX2072X_EQ_B2_COEFF:
424         case CX2072X_EQ_A1_COEFF:
425         case CX2072X_EQ_A2_COEFF:
426         case CX2072X_EQ_G_COEFF:
427         case CX2072X_SPKR_DRC_ENABLE_STEP:
428         case CX2072X_SPKR_DRC_CONTROL:
429         case CX2072X_SPKR_DRC_TEST:
430         case CX2072X_DIGITAL_BIOS_TEST0:
431         case CX2072X_DIGITAL_BIOS_TEST2:
432         case CX2072X_I2SPCM_CONTROL1:
433         case CX2072X_I2SPCM_CONTROL2:
434         case CX2072X_I2SPCM_CONTROL3:
435         case CX2072X_I2SPCM_CONTROL4:
436         case CX2072X_I2SPCM_CONTROL5:
437         case CX2072X_I2SPCM_CONTROL6:
438         case CX2072X_UM_INTERRUPT_CRTL_E:
439         case CX2072X_CODEC_TEST2:
440         case CX2072X_CODEC_TEST9:
441         case CX2072X_CODEC_TEST20:
442         case CX2072X_CODEC_TEST26:
443         case CX2072X_ANALOG_TEST4:
444         case CX2072X_ANALOG_TEST5:
445         case CX2072X_ANALOG_TEST6:
446         case CX2072X_ANALOG_TEST7:
447         case CX2072X_ANALOG_TEST8:
448         case CX2072X_ANALOG_TEST9:
449         case CX2072X_ANALOG_TEST10:
450         case CX2072X_ANALOG_TEST11:
451         case CX2072X_ANALOG_TEST12:
452         case CX2072X_ANALOG_TEST13:
453         case CX2072X_DIGITAL_TEST0:
454         case CX2072X_DIGITAL_TEST1:
455         case CX2072X_DIGITAL_TEST11:
456         case CX2072X_DIGITAL_TEST12:
457         case CX2072X_DIGITAL_TEST15:
458         case CX2072X_DIGITAL_TEST16:
459         case CX2072X_DIGITAL_TEST17:
460         case CX2072X_DIGITAL_TEST18:
461         case CX2072X_DIGITAL_TEST19:
462         case CX2072X_DIGITAL_TEST20:
463                 return true;
464         default:
465                 return false;
466         }
467 }
468 
469 static bool cx2072x_volatile_register(struct device *dev, unsigned int reg)
470 {
471         switch (reg) {
472         case CX2072X_VENDOR_ID:
473         case CX2072X_REVISION_ID:
474         case CX2072X_UM_INTERRUPT_CRTL_E:
475         case CX2072X_DIGITAL_TEST11:
476         case CX2072X_PORTA_PIN_SENSE:
477         case CX2072X_PORTB_PIN_SENSE:
478         case CX2072X_PORTD_PIN_SENSE:
479         case CX2072X_PORTE_PIN_SENSE:
480         case CX2072X_PORTF_PIN_SENSE:
481         case CX2072X_EQ_G_COEFF:
482         case CX2072X_EQ_BAND:
483                 return true;
484         default:
485                 return false;
486         }
487 }
488 
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 
1523 static const struct snd_soc_component_driver soc_codec_driver_cx2072x = {
1524         .probe = cx2072x_probe,
1525         .set_bias_level = cx2072x_set_bias_level,
1526         .set_jack = cx2072x_set_jack,
1527         .controls = cx2072x_snd_controls,
1528         .num_controls = ARRAY_SIZE(cx2072x_snd_controls),
1529         .dapm_widgets = cx2072x_dapm_widgets,
1530         .num_dapm_widgets = ARRAY_SIZE(cx2072x_dapm_widgets),
1531         .dapm_routes = cx2072x_intercon,
1532         .num_dapm_routes = ARRAY_SIZE(cx2072x_intercon),
1533 };
1534 
1535 /*
1536  * DAI ops
1537  */
1538 static struct snd_soc_dai_ops cx2072x_dai_ops = {
1539         .set_sysclk = cx2072x_set_dai_sysclk,
1540         .set_fmt = cx2072x_set_dai_fmt,
1541         .hw_params = cx2072x_hw_params,
1542         .set_bclk_ratio = cx2072x_set_dai_bclk_ratio,
1543 };
1544 
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 
1556 static struct snd_soc_dai_driver soc_codec_cx2072x_dai[] = {
1557         { /* playback and capture */
1558                 .name = "cx2072x-hifi",
1559                 .id     = CX2072X_DAI_HIFI,
1560                 .playback = {
1561                         .stream_name = "Playback",
1562                         .channels_min = 1,
1563                         .channels_max = 2,
1564                         .rates = CX2072X_RATES_DSP,
1565                         .formats = CX2072X_FORMATS,
1566                 },
1567                 .capture = {
1568                         .stream_name = "Capture",
1569                         .channels_min = 1,
1570                         .channels_max = 2,
1571                         .rates = CX2072X_RATES_DSP,
1572                         .formats = CX2072X_FORMATS,
1573                 },
1574                 .ops = &cx2072x_dai_ops,
1575                 .symmetric_rates = 1,
1576         },
1577         { /* plabayck only, return echo reference to Conexant DSP chip */
1578                 .name = "cx2072x-dsp",
1579                 .id     = CX2072X_DAI_DSP,
1580                 .probe = cx2072x_dsp_dai_probe,
1581                 .playback = {
1582                         .stream_name = "DSP Playback",
1583                         .channels_min = 2,
1584                         .channels_max = 2,
1585                         .rates = CX2072X_RATES_DSP,
1586                         .formats = CX2072X_FORMATS,
1587                 },
1588                 .ops = &cx2072x_dai_ops,
1589         },
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         },
1601 };
1602 
1603 static const struct regmap_config cx2072x_regmap = {
1604         .reg_bits = 16,
1605         .val_bits = 32,
1606         .max_register = CX2072X_REG_MAX,
1607         .reg_defaults = cx2072x_reg_defaults,
1608         .num_reg_defaults = ARRAY_SIZE(cx2072x_reg_defaults),
1609         .cache_type = REGCACHE_RBTREE,
1610         .readable_reg = cx2072x_readable_register,
1611         .volatile_reg = cx2072x_volatile_register,
1612         /* Needs custom read/write functions for various register lengths */
1613         .reg_read = cx2072x_reg_read,
1614         .reg_write = cx2072x_reg_write,
1615 };
1616 
1617 static int __maybe_unused cx2072x_runtime_suspend(struct device *dev)
1618 {
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);
1630 }
1631 
1632 static int cx2072x_i2c_probe(struct i2c_client *i2c,
1633                              const struct i2c_device_id *id)
1634 {
1635         struct cx2072x_priv *cx2072x;
1636         unsigned int ven_id, rev_id;
1637         int ret;
1638 
1639         cx2072x = devm_kzalloc(&i2c->dev, sizeof(struct cx2072x_priv),
1640                                GFP_KERNEL);
1641         if (!cx2072x)
1642                 return -ENOMEM;
1643 
1644         cx2072x->regmap = devm_regmap_init(&i2c->dev, NULL, i2c,
1645                                            &cx2072x_regmap);
1646         if (IS_ERR(cx2072x->regmap))
1647                 return PTR_ERR(cx2072x->regmap);
1648 
1649         mutex_init(&cx2072x->lock);
1650 
1651         i2c_set_clientdata(i2c, cx2072x);
1652 
1653         cx2072x->dev = &i2c->dev;
1654         cx2072x->pll_changed = true;
1655         cx2072x->i2spcm_changed = true;
1656         cx2072x->bclk_ratio = 0;
1657 
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;
1680 }
1681 
1682 static int cx2072x_i2c_remove(struct i2c_client *i2c)
1683 {
1684         pm_runtime_disable(&i2c->dev);
1685         return 0;
1686 }
1687 
1688 static const struct i2c_device_id cx2072x_i2c_id[] = {
1689         { "cx20721", 0 },
1690         { "cx20723", 0 },
1691         {}
1692 };
1693 MODULE_DEVICE_TABLE(i2c, cx2072x_i2c_id);
1694 
1695 #ifdef CONFIG_ACPI
1696 static struct acpi_device_id cx2072x_acpi_match[] = {
1697         { "14F10720", 0 },
1698         {},
1699 };
1700 MODULE_DEVICE_TABLE(acpi, cx2072x_acpi_match);
1701 #endif
1702 
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 
1710 static struct i2c_driver cx2072x_i2c_driver = {
1711         .driver = {
1712                 .name = "cx2072x",
1713                 .acpi_match_table = ACPI_PTR(cx2072x_acpi_match),
1714                 .pm = &cx2072x_runtime_pm,
1715         },
1716         .probe = cx2072x_i2c_probe,
1717         .remove = cx2072x_i2c_remove,
1718         .id_table = cx2072x_i2c_id,
1719 };
1720 
1721 module_i2c_driver(cx2072x_i2c_driver);
1722 
1723 MODULE_DESCRIPTION("ASoC cx2072x Codec Driver");
1724 MODULE_AUTHOR("Simon Ho <simon.ho@conexant.com>");
1725 MODULE_LICENSE("GPL");
1726 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp