0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/regmap.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/mfd/motorola-cpcap.h>
0015 #include <sound/core.h>
0016 #include <sound/soc.h>
0017 #include <sound/tlv.h>
0018
0019
0020 #define CPCAP_BIT_AUDIO_LOW_PWR 6
0021 #define CPCAP_BIT_AUD_LOWPWR_SPEED 5
0022 #define CPCAP_BIT_VAUDIOPRISTBY 4
0023 #define CPCAP_BIT_VAUDIO_MODE1 2
0024 #define CPCAP_BIT_VAUDIO_MODE0 1
0025 #define CPCAP_BIT_V_AUDIO_EN 0
0026
0027
0028 #define CPCAP_BIT_CDC_CLK2 15
0029 #define CPCAP_BIT_CDC_CLK1 14
0030 #define CPCAP_BIT_CDC_CLK0 13
0031 #define CPCAP_BIT_CDC_SR3 12
0032 #define CPCAP_BIT_CDC_SR2 11
0033 #define CPCAP_BIT_CDC_SR1 10
0034 #define CPCAP_BIT_CDC_SR0 9
0035 #define CPCAP_BIT_CDC_CLOCK_TREE_RESET 8
0036 #define CPCAP_BIT_MIC2_CDC_EN 7
0037 #define CPCAP_BIT_CDC_EN_RX 6
0038 #define CPCAP_BIT_DF_RESET 5
0039 #define CPCAP_BIT_MIC1_CDC_EN 4
0040 #define CPCAP_BIT_AUDOHPF_1 3
0041 #define CPCAP_BIT_AUDOHPF_0 2
0042 #define CPCAP_BIT_AUDIHPF_1 1
0043 #define CPCAP_BIT_AUDIHPF_0 0
0044
0045
0046 #define CPCAP_BIT_CDC_PLL_SEL 15
0047 #define CPCAP_BIT_CLK_IN_SEL 13
0048 #define CPCAP_BIT_DIG_AUD_IN 12
0049 #define CPCAP_BIT_CDC_CLK_EN 11
0050 #define CPCAP_BIT_CDC_DIG_AUD_FS1 10
0051 #define CPCAP_BIT_CDC_DIG_AUD_FS0 9
0052 #define CPCAP_BIT_MIC2_TIMESLOT2 8
0053 #define CPCAP_BIT_MIC2_TIMESLOT1 7
0054 #define CPCAP_BIT_MIC2_TIMESLOT0 6
0055 #define CPCAP_BIT_MIC1_RX_TIMESLOT2 5
0056 #define CPCAP_BIT_MIC1_RX_TIMESLOT1 4
0057 #define CPCAP_BIT_MIC1_RX_TIMESLOT0 3
0058 #define CPCAP_BIT_FS_INV 2
0059 #define CPCAP_BIT_CLK_INV 1
0060 #define CPCAP_BIT_SMB_CDC 0
0061
0062
0063 #define CPCAP_BIT_FSYNC_CLK_IN_COMMON 11
0064 #define CPCAP_BIT_SLAVE_PLL_CLK_INPUT 10
0065 #define CPCAP_BIT_ST_CLOCK_TREE_RESET 9
0066 #define CPCAP_BIT_DF_RESET_ST_DAC 8
0067 #define CPCAP_BIT_ST_SR3 7
0068 #define CPCAP_BIT_ST_SR2 6
0069 #define CPCAP_BIT_ST_SR1 5
0070 #define CPCAP_BIT_ST_SR0 4
0071 #define CPCAP_BIT_ST_DAC_CLK2 3
0072 #define CPCAP_BIT_ST_DAC_CLK1 2
0073 #define CPCAP_BIT_ST_DAC_CLK0 1
0074 #define CPCAP_BIT_ST_DAC_EN 0
0075
0076
0077 #define CPCAP_BIT_ST_L_TIMESLOT2 13
0078 #define CPCAP_BIT_ST_L_TIMESLOT1 12
0079 #define CPCAP_BIT_ST_L_TIMESLOT0 11
0080 #define CPCAP_BIT_ST_R_TIMESLOT2 10
0081 #define CPCAP_BIT_ST_R_TIMESLOT1 9
0082 #define CPCAP_BIT_ST_R_TIMESLOT0 8
0083 #define CPCAP_BIT_ST_DAC_CLK_IN_SEL 7
0084 #define CPCAP_BIT_ST_FS_INV 6
0085 #define CPCAP_BIT_ST_CLK_INV 5
0086 #define CPCAP_BIT_ST_DIG_AUD_FS1 4
0087 #define CPCAP_BIT_ST_DIG_AUD_FS0 3
0088 #define CPCAP_BIT_DIG_AUD_IN_ST_DAC 2
0089 #define CPCAP_BIT_ST_CLK_EN 1
0090 #define CPCAP_BIT_SMB_ST_DAC 0
0091
0092
0093 #define CPCAP_BIT_PTT_TH 15
0094 #define CPCAP_BIT_PTT_CMP_EN 14
0095 #define CPCAP_BIT_HS_ID_TX 13
0096 #define CPCAP_BIT_MB_ON2 12
0097 #define CPCAP_BIT_MB_ON1L 11
0098 #define CPCAP_BIT_MB_ON1R 10
0099 #define CPCAP_BIT_RX_L_ENCODE 9
0100 #define CPCAP_BIT_RX_R_ENCODE 8
0101 #define CPCAP_BIT_MIC2_MUX 7
0102 #define CPCAP_BIT_MIC2_PGA_EN 6
0103 #define CPCAP_BIT_CDET_DIS 5
0104 #define CPCAP_BIT_EMU_MIC_MUX 4
0105 #define CPCAP_BIT_HS_MIC_MUX 3
0106 #define CPCAP_BIT_MIC1_MUX 2
0107 #define CPCAP_BIT_MIC1_PGA_EN 1
0108 #define CPCAP_BIT_DLM 0
0109
0110
0111 #define CPCAP_BIT_MB_BIAS_R1 11
0112 #define CPCAP_BIT_MB_BIAS_R0 10
0113 #define CPCAP_BIT_MIC2_GAIN_4 9
0114 #define CPCAP_BIT_MIC2_GAIN_3 8
0115 #define CPCAP_BIT_MIC2_GAIN_2 7
0116 #define CPCAP_BIT_MIC2_GAIN_1 6
0117 #define CPCAP_BIT_MIC2_GAIN_0 5
0118 #define CPCAP_BIT_MIC1_GAIN_4 4
0119 #define CPCAP_BIT_MIC1_GAIN_3 3
0120 #define CPCAP_BIT_MIC1_GAIN_2 2
0121 #define CPCAP_BIT_MIC1_GAIN_1 1
0122 #define CPCAP_BIT_MIC1_GAIN_0 0
0123
0124
0125 #define CPCAP_BIT_UNUSED_519_15 15
0126 #define CPCAP_BIT_UNUSED_519_14 14
0127 #define CPCAP_BIT_UNUSED_519_13 13
0128 #define CPCAP_BIT_STDAC_LOW_PWR_DISABLE 12
0129 #define CPCAP_BIT_HS_LOW_PWR 11
0130 #define CPCAP_BIT_HS_ID_RX 10
0131 #define CPCAP_BIT_ST_HS_CP_EN 9
0132 #define CPCAP_BIT_EMU_SPKR_R_EN 8
0133 #define CPCAP_BIT_EMU_SPKR_L_EN 7
0134 #define CPCAP_BIT_HS_L_EN 6
0135 #define CPCAP_BIT_HS_R_EN 5
0136 #define CPCAP_BIT_A4_LINEOUT_L_EN 4
0137 #define CPCAP_BIT_A4_LINEOUT_R_EN 3
0138 #define CPCAP_BIT_A2_LDSP_L_EN 2
0139 #define CPCAP_BIT_A2_LDSP_R_EN 1
0140 #define CPCAP_BIT_A1_EAR_EN 0
0141
0142
0143 #define CPCAP_BIT_VOL_EXT3 15
0144 #define CPCAP_BIT_VOL_EXT2 14
0145 #define CPCAP_BIT_VOL_EXT1 13
0146 #define CPCAP_BIT_VOL_EXT0 12
0147 #define CPCAP_BIT_VOL_DAC3 11
0148 #define CPCAP_BIT_VOL_DAC2 10
0149 #define CPCAP_BIT_VOL_DAC1 9
0150 #define CPCAP_BIT_VOL_DAC0 8
0151 #define CPCAP_BIT_VOL_DAC_LSB_1dB1 7
0152 #define CPCAP_BIT_VOL_DAC_LSB_1dB0 6
0153 #define CPCAP_BIT_VOL_CDC3 5
0154 #define CPCAP_BIT_VOL_CDC2 4
0155 #define CPCAP_BIT_VOL_CDC1 3
0156 #define CPCAP_BIT_VOL_CDC0 2
0157 #define CPCAP_BIT_VOL_CDC_LSB_1dB1 1
0158 #define CPCAP_BIT_VOL_CDC_LSB_1dB0 0
0159
0160
0161 #define CPCAP_BIT_PGA_CDC_EN 10
0162 #define CPCAP_BIT_CDC_SW 9
0163 #define CPCAP_BIT_PGA_OUTR_USBDP_CDC_SW 8
0164 #define CPCAP_BIT_PGA_OUTL_USBDN_CDC_SW 7
0165 #define CPCAP_BIT_ALEFT_HS_CDC_SW 6
0166 #define CPCAP_BIT_ARIGHT_HS_CDC_SW 5
0167 #define CPCAP_BIT_A4_LINEOUT_L_CDC_SW 4
0168 #define CPCAP_BIT_A4_LINEOUT_R_CDC_SW 3
0169 #define CPCAP_BIT_A2_LDSP_L_CDC_SW 2
0170 #define CPCAP_BIT_A2_LDSP_R_CDC_SW 1
0171 #define CPCAP_BIT_A1_EAR_CDC_SW 0
0172
0173
0174 #define CPCAP_BIT_PGA_DAC_EN 12
0175 #define CPCAP_BIT_ST_DAC_SW 11
0176 #define CPCAP_BIT_MONO_DAC1 10
0177 #define CPCAP_BIT_MONO_DAC0 9
0178 #define CPCAP_BIT_PGA_OUTR_USBDP_DAC_SW 8
0179 #define CPCAP_BIT_PGA_OUTL_USBDN_DAC_SW 7
0180 #define CPCAP_BIT_ALEFT_HS_DAC_SW 6
0181 #define CPCAP_BIT_ARIGHT_HS_DAC_SW 5
0182 #define CPCAP_BIT_A4_LINEOUT_L_DAC_SW 4
0183 #define CPCAP_BIT_A4_LINEOUT_R_DAC_SW 3
0184 #define CPCAP_BIT_A2_LDSP_L_DAC_SW 2
0185 #define CPCAP_BIT_A2_LDSP_R_DAC_SW 1
0186 #define CPCAP_BIT_A1_EAR_DAC_SW 0
0187
0188
0189 #define CPCAP_BIT_PGA_EXT_L_EN 14
0190 #define CPCAP_BIT_PGA_EXT_R_EN 13
0191 #define CPCAP_BIT_PGA_IN_L_SW 12
0192 #define CPCAP_BIT_PGA_IN_R_SW 11
0193 #define CPCAP_BIT_MONO_EXT1 10
0194 #define CPCAP_BIT_MONO_EXT0 9
0195 #define CPCAP_BIT_PGA_OUTR_USBDP_EXT_SW 8
0196 #define CPCAP_BIT_PGA_OUTL_USBDN_EXT_SW 7
0197 #define CPCAP_BIT_ALEFT_HS_EXT_SW 6
0198 #define CPCAP_BIT_ARIGHT_HS_EXT_SW 5
0199 #define CPCAP_BIT_A4_LINEOUT_L_EXT_SW 4
0200 #define CPCAP_BIT_A4_LINEOUT_R_EXT_SW 3
0201 #define CPCAP_BIT_A2_LDSP_L_EXT_SW 2
0202 #define CPCAP_BIT_A2_LDSP_R_EXT_SW 1
0203 #define CPCAP_BIT_A1_EAR_EXT_SW 0
0204
0205
0206 #define CPCAP_BIT_NCP_CLK_SYNC 7
0207 #define CPCAP_BIT_A2_CLK_SYNC 6
0208 #define CPCAP_BIT_A2_FREE_RUN 5
0209 #define CPCAP_BIT_A2_CLK2 4
0210 #define CPCAP_BIT_A2_CLK1 3
0211 #define CPCAP_BIT_A2_CLK0 2
0212 #define CPCAP_BIT_A2_CLK_IN 1
0213 #define CPCAP_BIT_A2_CONFIG 0
0214
0215 #define SLEEP_ACTIVATE_POWER 2
0216 #define CLOCK_TREE_RESET_TIME 1
0217
0218
0219 #define STM_STDAC_ACTIVATE_RAMP_TIME 1
0220 #define STM_STDAC_EN_TEST_PRE 0x090C
0221 #define STM_STDAC_EN_TEST_POST 0x0000
0222 #define STM_STDAC_EN_ST_TEST1_PRE 0x2400
0223 #define STM_STDAC_EN_ST_TEST1_POST 0x0400
0224
0225 struct cpcap_reg_info {
0226 u16 reg;
0227 u16 mask;
0228 u16 val;
0229 };
0230
0231 static const struct cpcap_reg_info cpcap_default_regs[] = {
0232 { CPCAP_REG_VAUDIOC, 0x003F, 0x0000 },
0233 { CPCAP_REG_CC, 0xFFFF, 0x0000 },
0234 { CPCAP_REG_CC, 0xFFFF, 0x0000 },
0235 { CPCAP_REG_CDI, 0xBFFF, 0x0000 },
0236 { CPCAP_REG_SDAC, 0x0FFF, 0x0000 },
0237 { CPCAP_REG_SDACDI, 0x3FFF, 0x0000 },
0238 { CPCAP_REG_TXI, 0x0FDF, 0x0000 },
0239 { CPCAP_REG_TXMP, 0x0FFF, 0x0400 },
0240 { CPCAP_REG_RXOA, 0x01FF, 0x0000 },
0241 { CPCAP_REG_RXVC, 0xFF3C, 0x0000 },
0242 { CPCAP_REG_RXCOA, 0x07FF, 0x0000 },
0243 { CPCAP_REG_RXSDOA, 0x1FFF, 0x0000 },
0244 { CPCAP_REG_RXEPOA, 0x7FFF, 0x0000 },
0245 { CPCAP_REG_A2LA, BIT(CPCAP_BIT_A2_FREE_RUN),
0246 BIT(CPCAP_BIT_A2_FREE_RUN) },
0247 };
0248
0249 enum cpcap_dai {
0250 CPCAP_DAI_HIFI,
0251 CPCAP_DAI_VOICE,
0252 };
0253
0254 struct cpcap_audio {
0255 struct snd_soc_component *component;
0256 struct regmap *regmap;
0257
0258 u16 vendor;
0259
0260 int codec_clk_id;
0261 int codec_freq;
0262 int codec_format;
0263 };
0264
0265 static int cpcap_st_workaround(struct snd_soc_dapm_widget *w,
0266 struct snd_kcontrol *kcontrol, int event)
0267 {
0268 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0269 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0270 int err = 0;
0271
0272
0273 if (cpcap->vendor != CPCAP_VENDOR_ST)
0274 return 0;
0275
0276 switch (event) {
0277 case SND_SOC_DAPM_PRE_PMU:
0278 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
0279 STM_STDAC_EN_TEST_PRE);
0280 if (err)
0281 return err;
0282 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
0283 STM_STDAC_EN_ST_TEST1_PRE);
0284 break;
0285 case SND_SOC_DAPM_POST_PMU:
0286 msleep(STM_STDAC_ACTIVATE_RAMP_TIME);
0287
0288 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
0289 STM_STDAC_EN_ST_TEST1_POST);
0290 if (err)
0291 return err;
0292 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
0293 STM_STDAC_EN_TEST_POST);
0294 break;
0295 default:
0296 break;
0297 }
0298
0299 return err;
0300 }
0301
0302
0303 static const DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
0304
0305
0306 static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
0307
0308 static const struct snd_kcontrol_new cpcap_snd_controls[] = {
0309
0310 SOC_SINGLE_TLV("HiFi Playback Volume",
0311 CPCAP_REG_RXVC, CPCAP_BIT_VOL_DAC0, 0xF, 0, vol_tlv),
0312 SOC_SINGLE_TLV("Voice Playback Volume",
0313 CPCAP_REG_RXVC, CPCAP_BIT_VOL_CDC0, 0xF, 0, vol_tlv),
0314 SOC_SINGLE_TLV("Ext Playback Volume",
0315 CPCAP_REG_RXVC, CPCAP_BIT_VOL_EXT0, 0xF, 0, vol_tlv),
0316
0317
0318 SOC_SINGLE_TLV("Mic1 Capture Volume",
0319 CPCAP_REG_TXMP, CPCAP_BIT_MIC1_GAIN_0, 0x1F, 0, mic_gain_tlv),
0320 SOC_SINGLE_TLV("Mic2 Capture Volume",
0321 CPCAP_REG_TXMP, CPCAP_BIT_MIC2_GAIN_0, 0x1F, 0, mic_gain_tlv),
0322
0323
0324 SOC_SINGLE("Hifi Left Phase Invert Switch",
0325 CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC0, 1, 0),
0326 SOC_SINGLE("Ext Left Phase Invert Switch",
0327 CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
0328 };
0329
0330 static const char * const cpcap_out_mux_texts[] = {
0331 "Off", "Voice", "HiFi", "Ext"
0332 };
0333
0334 static const char * const cpcap_in_right_mux_texts[] = {
0335 "Off", "Mic 1", "Headset Mic", "EMU Mic", "Ext Right"
0336 };
0337
0338 static const char * const cpcap_in_left_mux_texts[] = {
0339 "Off", "Mic 2", "Ext Left"
0340 };
0341
0342
0343
0344
0345
0346 static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_left_mux_enum,
0347 cpcap_in_left_mux_texts);
0348 static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_right_mux_enum,
0349 cpcap_in_right_mux_texts);
0350
0351
0352
0353
0354
0355
0356 static SOC_ENUM_SINGLE_DECL(cpcap_earpiece_mux_enum, 0, 0, cpcap_out_mux_texts);
0357 static SOC_ENUM_SINGLE_DECL(cpcap_spkr_r_mux_enum, 0, 1, cpcap_out_mux_texts);
0358 static SOC_ENUM_SINGLE_DECL(cpcap_spkr_l_mux_enum, 0, 2, cpcap_out_mux_texts);
0359 static SOC_ENUM_SINGLE_DECL(cpcap_line_r_mux_enum, 0, 3, cpcap_out_mux_texts);
0360 static SOC_ENUM_SINGLE_DECL(cpcap_line_l_mux_enum, 0, 4, cpcap_out_mux_texts);
0361 static SOC_ENUM_SINGLE_DECL(cpcap_hs_r_mux_enum, 0, 5, cpcap_out_mux_texts);
0362 static SOC_ENUM_SINGLE_DECL(cpcap_hs_l_mux_enum, 0, 6, cpcap_out_mux_texts);
0363 static SOC_ENUM_SINGLE_DECL(cpcap_emu_l_mux_enum, 0, 7, cpcap_out_mux_texts);
0364 static SOC_ENUM_SINGLE_DECL(cpcap_emu_r_mux_enum, 0, 8, cpcap_out_mux_texts);
0365
0366 static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol,
0367 struct snd_ctl_elem_value *ucontrol)
0368 {
0369 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
0370 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0371 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0372 unsigned int shift = e->shift_l;
0373 int reg_voice, reg_hifi, reg_ext, status;
0374 int err;
0375
0376 err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, ®_voice);
0377 if (err)
0378 return err;
0379 err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, ®_hifi);
0380 if (err)
0381 return err;
0382 err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, ®_ext);
0383 if (err)
0384 return err;
0385
0386 reg_voice = (reg_voice >> shift) & 1;
0387 reg_hifi = (reg_hifi >> shift) & 1;
0388 reg_ext = (reg_ext >> shift) & 1;
0389 status = reg_ext << 2 | reg_hifi << 1 | reg_voice;
0390
0391 switch (status) {
0392 case 0x04:
0393 ucontrol->value.enumerated.item[0] = 3;
0394 break;
0395 case 0x02:
0396 ucontrol->value.enumerated.item[0] = 2;
0397 break;
0398 case 0x01:
0399 ucontrol->value.enumerated.item[0] = 1;
0400 break;
0401 default:
0402 ucontrol->value.enumerated.item[0] = 0;
0403 break;
0404 }
0405
0406 return 0;
0407 }
0408
0409 static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol,
0410 struct snd_ctl_elem_value *ucontrol)
0411 {
0412 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
0413 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0414 struct snd_soc_dapm_context *dapm =
0415 snd_soc_dapm_kcontrol_dapm(kcontrol);
0416 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0417 unsigned int muxval = ucontrol->value.enumerated.item[0];
0418 unsigned int mask = BIT(e->shift_l);
0419 u16 reg_voice = 0x00, reg_hifi = 0x00, reg_ext = 0x00;
0420 int err;
0421
0422 switch (muxval) {
0423 case 1:
0424 reg_voice = mask;
0425 break;
0426 case 2:
0427 reg_hifi = mask;
0428 break;
0429 case 3:
0430 reg_ext = mask;
0431 break;
0432 default:
0433 break;
0434 }
0435
0436 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
0437 mask, reg_voice);
0438 if (err)
0439 return err;
0440 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA,
0441 mask, reg_hifi);
0442 if (err)
0443 return err;
0444 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA,
0445 mask, reg_ext);
0446 if (err)
0447 return err;
0448
0449 snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
0450
0451 return 0;
0452 }
0453
0454 static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol,
0455 struct snd_ctl_elem_value *ucontrol)
0456 {
0457 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
0458 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0459 int regval, mask;
0460 int err;
0461
0462 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, ®val);
0463 if (err)
0464 return err;
0465
0466 mask = 0;
0467 mask |= BIT(CPCAP_BIT_MIC1_MUX);
0468 mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
0469 mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
0470 mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
0471
0472 switch (regval & mask) {
0473 case BIT(CPCAP_BIT_RX_R_ENCODE):
0474 ucontrol->value.enumerated.item[0] = 4;
0475 break;
0476 case BIT(CPCAP_BIT_EMU_MIC_MUX):
0477 ucontrol->value.enumerated.item[0] = 3;
0478 break;
0479 case BIT(CPCAP_BIT_HS_MIC_MUX):
0480 ucontrol->value.enumerated.item[0] = 2;
0481 break;
0482 case BIT(CPCAP_BIT_MIC1_MUX):
0483 ucontrol->value.enumerated.item[0] = 1;
0484 break;
0485 default:
0486 ucontrol->value.enumerated.item[0] = 0;
0487 break;
0488 }
0489
0490 return 0;
0491 }
0492
0493 static int cpcap_input_right_mux_put_enum(struct snd_kcontrol *kcontrol,
0494 struct snd_ctl_elem_value *ucontrol)
0495 {
0496 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
0497 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0498 struct snd_soc_dapm_context *dapm =
0499 snd_soc_dapm_kcontrol_dapm(kcontrol);
0500 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0501 unsigned int muxval = ucontrol->value.enumerated.item[0];
0502 int regval = 0, mask;
0503 int err;
0504
0505 mask = 0;
0506 mask |= BIT(CPCAP_BIT_MIC1_MUX);
0507 mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
0508 mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
0509 mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
0510
0511 switch (muxval) {
0512 case 1:
0513 regval = BIT(CPCAP_BIT_MIC1_MUX);
0514 break;
0515 case 2:
0516 regval = BIT(CPCAP_BIT_HS_MIC_MUX);
0517 break;
0518 case 3:
0519 regval = BIT(CPCAP_BIT_EMU_MIC_MUX);
0520 break;
0521 case 4:
0522 regval = BIT(CPCAP_BIT_RX_R_ENCODE);
0523 break;
0524 default:
0525 break;
0526 }
0527
0528 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
0529 mask, regval);
0530 if (err)
0531 return err;
0532
0533 snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
0534
0535 return 0;
0536 }
0537
0538 static int cpcap_input_left_mux_get_enum(struct snd_kcontrol *kcontrol,
0539 struct snd_ctl_elem_value *ucontrol)
0540 {
0541 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
0542 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0543 int regval, mask;
0544 int err;
0545
0546 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, ®val);
0547 if (err)
0548 return err;
0549
0550 mask = 0;
0551 mask |= BIT(CPCAP_BIT_MIC2_MUX);
0552 mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
0553
0554 switch (regval & mask) {
0555 case BIT(CPCAP_BIT_RX_L_ENCODE):
0556 ucontrol->value.enumerated.item[0] = 2;
0557 break;
0558 case BIT(CPCAP_BIT_MIC2_MUX):
0559 ucontrol->value.enumerated.item[0] = 1;
0560 break;
0561 default:
0562 ucontrol->value.enumerated.item[0] = 0;
0563 break;
0564 }
0565
0566 return 0;
0567 }
0568
0569 static int cpcap_input_left_mux_put_enum(struct snd_kcontrol *kcontrol,
0570 struct snd_ctl_elem_value *ucontrol)
0571 {
0572 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
0573 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
0574 struct snd_soc_dapm_context *dapm =
0575 snd_soc_dapm_kcontrol_dapm(kcontrol);
0576 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0577 unsigned int muxval = ucontrol->value.enumerated.item[0];
0578 int regval = 0, mask;
0579 int err;
0580
0581 mask = 0;
0582 mask |= BIT(CPCAP_BIT_MIC2_MUX);
0583 mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
0584
0585 switch (muxval) {
0586 case 1:
0587 regval = BIT(CPCAP_BIT_MIC2_MUX);
0588 break;
0589 case 2:
0590 regval = BIT(CPCAP_BIT_RX_L_ENCODE);
0591 break;
0592 default:
0593 break;
0594 }
0595
0596 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
0597 mask, regval);
0598 if (err)
0599 return err;
0600
0601 snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
0602
0603 return 0;
0604 }
0605
0606 static const struct snd_kcontrol_new cpcap_input_left_mux =
0607 SOC_DAPM_ENUM_EXT("Input Left", cpcap_input_left_mux_enum,
0608 cpcap_input_left_mux_get_enum,
0609 cpcap_input_left_mux_put_enum);
0610 static const struct snd_kcontrol_new cpcap_input_right_mux =
0611 SOC_DAPM_ENUM_EXT("Input Right", cpcap_input_right_mux_enum,
0612 cpcap_input_right_mux_get_enum,
0613 cpcap_input_right_mux_put_enum);
0614 static const struct snd_kcontrol_new cpcap_emu_left_mux =
0615 SOC_DAPM_ENUM_EXT("EMU Left", cpcap_emu_l_mux_enum,
0616 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0617 static const struct snd_kcontrol_new cpcap_emu_right_mux =
0618 SOC_DAPM_ENUM_EXT("EMU Right", cpcap_emu_r_mux_enum,
0619 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0620 static const struct snd_kcontrol_new cpcap_hs_left_mux =
0621 SOC_DAPM_ENUM_EXT("Headset Left", cpcap_hs_l_mux_enum,
0622 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0623 static const struct snd_kcontrol_new cpcap_hs_right_mux =
0624 SOC_DAPM_ENUM_EXT("Headset Right", cpcap_hs_r_mux_enum,
0625 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0626 static const struct snd_kcontrol_new cpcap_line_left_mux =
0627 SOC_DAPM_ENUM_EXT("Line Left", cpcap_line_l_mux_enum,
0628 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0629 static const struct snd_kcontrol_new cpcap_line_right_mux =
0630 SOC_DAPM_ENUM_EXT("Line Right", cpcap_line_r_mux_enum,
0631 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0632 static const struct snd_kcontrol_new cpcap_speaker_left_mux =
0633 SOC_DAPM_ENUM_EXT("Speaker Left", cpcap_spkr_l_mux_enum,
0634 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0635 static const struct snd_kcontrol_new cpcap_speaker_right_mux =
0636 SOC_DAPM_ENUM_EXT("Speaker Right", cpcap_spkr_r_mux_enum,
0637 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0638 static const struct snd_kcontrol_new cpcap_earpiece_mux =
0639 SOC_DAPM_ENUM_EXT("Earpiece", cpcap_earpiece_mux_enum,
0640 cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
0641
0642 static const struct snd_kcontrol_new cpcap_hifi_mono_mixer_controls[] = {
0643 SOC_DAPM_SINGLE("HiFi Mono Playback Switch",
0644 CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC1, 1, 0),
0645 };
0646 static const struct snd_kcontrol_new cpcap_ext_mono_mixer_controls[] = {
0647 SOC_DAPM_SINGLE("Ext Mono Playback Switch",
0648 CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
0649 };
0650
0651 static const struct snd_kcontrol_new cpcap_extr_mute_control =
0652 SOC_DAPM_SINGLE("Switch",
0653 CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_R_SW, 1, 0);
0654 static const struct snd_kcontrol_new cpcap_extl_mute_control =
0655 SOC_DAPM_SINGLE("Switch",
0656 CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_L_SW, 1, 0);
0657
0658 static const struct snd_kcontrol_new cpcap_voice_loopback =
0659 SOC_DAPM_SINGLE("Switch",
0660 CPCAP_REG_TXI, CPCAP_BIT_DLM, 1, 0);
0661
0662 static const struct snd_soc_dapm_widget cpcap_dapm_widgets[] = {
0663
0664 SND_SOC_DAPM_AIF_IN("HiFi RX", NULL, 0, SND_SOC_NOPM, 0, 0),
0665 SND_SOC_DAPM_AIF_IN("Voice RX", NULL, 0, SND_SOC_NOPM, 0, 0),
0666 SND_SOC_DAPM_AIF_OUT("Voice TX", NULL, 0, SND_SOC_NOPM, 0, 0),
0667
0668
0669 SND_SOC_DAPM_REGULATOR_SUPPLY("VAUDIO", SLEEP_ACTIVATE_POWER, 0),
0670
0671
0672 SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter RX",
0673 CPCAP_REG_CC, CPCAP_BIT_AUDIHPF_0, 0x3, 0x3, 0x0),
0674 SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter TX",
0675 CPCAP_REG_CC, CPCAP_BIT_AUDOHPF_0, 0x3, 0x3, 0x0),
0676
0677
0678 SND_SOC_DAPM_SUPPLY("HiFi DAI Clock",
0679 CPCAP_REG_SDACDI, CPCAP_BIT_ST_CLK_EN, 0, NULL, 0),
0680 SND_SOC_DAPM_SUPPLY("Voice DAI Clock",
0681 CPCAP_REG_CDI, CPCAP_BIT_CDC_CLK_EN, 0, NULL, 0),
0682
0683
0684 SND_SOC_DAPM_SUPPLY("MIC1R Bias",
0685 CPCAP_REG_TXI, CPCAP_BIT_MB_ON1R, 0, NULL, 0),
0686 SND_SOC_DAPM_SUPPLY("MIC1L Bias",
0687 CPCAP_REG_TXI, CPCAP_BIT_MB_ON1L, 0, NULL, 0),
0688 SND_SOC_DAPM_SUPPLY("MIC2 Bias",
0689 CPCAP_REG_TXI, CPCAP_BIT_MB_ON2, 0, NULL, 0),
0690
0691
0692 SND_SOC_DAPM_INPUT("MICR"),
0693 SND_SOC_DAPM_INPUT("HSMIC"),
0694 SND_SOC_DAPM_INPUT("EMUMIC"),
0695 SND_SOC_DAPM_INPUT("MICL"),
0696 SND_SOC_DAPM_INPUT("EXTR"),
0697 SND_SOC_DAPM_INPUT("EXTL"),
0698
0699
0700 SND_SOC_DAPM_MUX("Right Capture Route",
0701 SND_SOC_NOPM, 0, 0, &cpcap_input_right_mux),
0702 SND_SOC_DAPM_MUX("Left Capture Route",
0703 SND_SOC_NOPM, 0, 0, &cpcap_input_left_mux),
0704
0705
0706 SND_SOC_DAPM_PGA("Microphone 1 PGA",
0707 CPCAP_REG_TXI, CPCAP_BIT_MIC1_PGA_EN, 0, NULL, 0),
0708 SND_SOC_DAPM_PGA("Microphone 2 PGA",
0709 CPCAP_REG_TXI, CPCAP_BIT_MIC2_PGA_EN, 0, NULL, 0),
0710
0711
0712 SND_SOC_DAPM_ADC("ADC Right", NULL,
0713 CPCAP_REG_CC, CPCAP_BIT_MIC1_CDC_EN, 0),
0714 SND_SOC_DAPM_ADC("ADC Left", NULL,
0715 CPCAP_REG_CC, CPCAP_BIT_MIC2_CDC_EN, 0),
0716
0717
0718 SND_SOC_DAPM_DAC_E("DAC HiFi", NULL,
0719 CPCAP_REG_SDAC, CPCAP_BIT_ST_DAC_EN, 0,
0720 cpcap_st_workaround,
0721 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
0722 SND_SOC_DAPM_DAC_E("DAC Voice", NULL,
0723 CPCAP_REG_CC, CPCAP_BIT_CDC_EN_RX, 0,
0724 cpcap_st_workaround,
0725 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
0726
0727
0728 SND_SOC_DAPM_PGA("HiFi PGA",
0729 CPCAP_REG_RXSDOA, CPCAP_BIT_PGA_DAC_EN, 0, NULL, 0),
0730 SND_SOC_DAPM_PGA("Voice PGA",
0731 CPCAP_REG_RXCOA, CPCAP_BIT_PGA_CDC_EN, 0, NULL, 0),
0732 SND_SOC_DAPM_PGA_E("Ext Right PGA",
0733 CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_R_EN, 0,
0734 NULL, 0,
0735 cpcap_st_workaround,
0736 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
0737 SND_SOC_DAPM_PGA_E("Ext Left PGA",
0738 CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_L_EN, 0,
0739 NULL, 0,
0740 cpcap_st_workaround,
0741 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
0742
0743
0744 SND_SOC_DAPM_SWITCH("Ext Right Enable", SND_SOC_NOPM, 0, 0,
0745 &cpcap_extr_mute_control),
0746 SND_SOC_DAPM_SWITCH("Ext Left Enable", SND_SOC_NOPM, 0, 0,
0747 &cpcap_extl_mute_control),
0748
0749
0750 SND_SOC_DAPM_SWITCH("Voice Loopback", SND_SOC_NOPM, 0, 0,
0751 &cpcap_voice_loopback),
0752
0753
0754 SOC_MIXER_ARRAY("HiFi Mono Left Mixer", SND_SOC_NOPM, 0, 0,
0755 cpcap_hifi_mono_mixer_controls),
0756 SOC_MIXER_ARRAY("HiFi Mono Right Mixer", SND_SOC_NOPM, 0, 0,
0757 cpcap_hifi_mono_mixer_controls),
0758 SOC_MIXER_ARRAY("Ext Mono Left Mixer", SND_SOC_NOPM, 0, 0,
0759 cpcap_ext_mono_mixer_controls),
0760 SOC_MIXER_ARRAY("Ext Mono Right Mixer", SND_SOC_NOPM, 0, 0,
0761 cpcap_ext_mono_mixer_controls),
0762
0763
0764 SND_SOC_DAPM_MUX("Earpiece Playback Route", SND_SOC_NOPM, 0, 0,
0765 &cpcap_earpiece_mux),
0766 SND_SOC_DAPM_MUX("Speaker Right Playback Route", SND_SOC_NOPM, 0, 0,
0767 &cpcap_speaker_right_mux),
0768 SND_SOC_DAPM_MUX("Speaker Left Playback Route", SND_SOC_NOPM, 0, 0,
0769 &cpcap_speaker_left_mux),
0770 SND_SOC_DAPM_MUX("Lineout Right Playback Route", SND_SOC_NOPM, 0, 0,
0771 &cpcap_line_right_mux),
0772 SND_SOC_DAPM_MUX("Lineout Left Playback Route", SND_SOC_NOPM, 0, 0,
0773 &cpcap_line_left_mux),
0774 SND_SOC_DAPM_MUX("Headset Right Playback Route", SND_SOC_NOPM, 0, 0,
0775 &cpcap_hs_right_mux),
0776 SND_SOC_DAPM_MUX("Headset Left Playback Route", SND_SOC_NOPM, 0, 0,
0777 &cpcap_hs_left_mux),
0778 SND_SOC_DAPM_MUX("EMU Right Playback Route", SND_SOC_NOPM, 0, 0,
0779 &cpcap_emu_right_mux),
0780 SND_SOC_DAPM_MUX("EMU Left Playback Route", SND_SOC_NOPM, 0, 0,
0781 &cpcap_emu_left_mux),
0782
0783
0784 SND_SOC_DAPM_PGA("Earpiece PGA",
0785 CPCAP_REG_RXOA, CPCAP_BIT_A1_EAR_EN, 0, NULL, 0),
0786 SND_SOC_DAPM_PGA("Speaker Right PGA",
0787 CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_R_EN, 0, NULL, 0),
0788 SND_SOC_DAPM_PGA("Speaker Left PGA",
0789 CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_L_EN, 0, NULL, 0),
0790 SND_SOC_DAPM_PGA("Lineout Right PGA",
0791 CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_R_EN, 0, NULL, 0),
0792 SND_SOC_DAPM_PGA("Lineout Left PGA",
0793 CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_L_EN, 0, NULL, 0),
0794 SND_SOC_DAPM_PGA("Headset Right PGA",
0795 CPCAP_REG_RXOA, CPCAP_BIT_HS_R_EN, 0, NULL, 0),
0796 SND_SOC_DAPM_PGA("Headset Left PGA",
0797 CPCAP_REG_RXOA, CPCAP_BIT_HS_L_EN, 0, NULL, 0),
0798 SND_SOC_DAPM_PGA("EMU Right PGA",
0799 CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_R_EN, 0, NULL, 0),
0800 SND_SOC_DAPM_PGA("EMU Left PGA",
0801 CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_L_EN, 0, NULL, 0),
0802
0803
0804 SND_SOC_DAPM_SUPPLY("Headset Charge Pump",
0805 CPCAP_REG_RXOA, CPCAP_BIT_ST_HS_CP_EN, 0, NULL, 0),
0806
0807
0808 SND_SOC_DAPM_OUTPUT("EP"),
0809 SND_SOC_DAPM_OUTPUT("SPKR"),
0810 SND_SOC_DAPM_OUTPUT("SPKL"),
0811 SND_SOC_DAPM_OUTPUT("LINER"),
0812 SND_SOC_DAPM_OUTPUT("LINEL"),
0813 SND_SOC_DAPM_OUTPUT("HSR"),
0814 SND_SOC_DAPM_OUTPUT("HSL"),
0815 SND_SOC_DAPM_OUTPUT("EMUR"),
0816 SND_SOC_DAPM_OUTPUT("EMUL"),
0817 };
0818
0819 static const struct snd_soc_dapm_route intercon[] = {
0820
0821 {"HiFi PGA", NULL, "VAUDIO"},
0822 {"Voice PGA", NULL, "VAUDIO"},
0823 {"Ext Right PGA", NULL, "VAUDIO"},
0824 {"Ext Left PGA", NULL, "VAUDIO"},
0825 {"Microphone 1 PGA", NULL, "VAUDIO"},
0826 {"Microphone 2 PGA", NULL, "VAUDIO"},
0827
0828
0829 {"HiFi RX", NULL, "HiFi Playback"},
0830 {"Voice RX", NULL, "Voice Playback"},
0831 {"Voice Capture", NULL, "Voice TX"},
0832
0833
0834 {"HiFi RX", NULL, "HiFi DAI Clock"},
0835 {"Voice RX", NULL, "Voice DAI Clock"},
0836 {"Voice TX", NULL, "Voice DAI Clock"},
0837
0838
0839 {"Voice Loopback", "Switch", "Voice TX"},
0840 {"Voice RX", NULL, "Voice Loopback"},
0841
0842
0843 {"Highpass Filter RX", NULL, "Voice RX"},
0844 {"Voice TX", NULL, "Highpass Filter TX"},
0845
0846
0847 {"DAC HiFi", NULL, "HiFi RX"},
0848 {"DAC Voice", NULL, "Highpass Filter RX"},
0849
0850
0851 {"HiFi PGA", NULL, "DAC HiFi"},
0852 {"Voice PGA", NULL, "DAC Voice"},
0853
0854
0855 {"Ext Right PGA", NULL, "EXTR"},
0856 {"Ext Left PGA", NULL, "EXTL"},
0857
0858
0859 {"Ext Right Enable", "Switch", "Ext Right PGA"},
0860 {"Ext Left Enable", "Switch", "Ext Left PGA"},
0861
0862
0863 {"HiFi Mono Left Mixer", NULL, "HiFi PGA"},
0864 {"HiFi Mono Left Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
0865 {"HiFi Mono Right Mixer", NULL, "HiFi PGA"},
0866 {"HiFi Mono Right Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
0867
0868
0869 {"Ext Mono Right Mixer", NULL, "Ext Right Enable"},
0870 {"Ext Mono Right Mixer", "Ext Mono Playback Switch", "Ext Left Enable"},
0871 {"Ext Mono Left Mixer", NULL, "Ext Left Enable"},
0872 {"Ext Mono Left Mixer", "Ext Mono Playback Switch", "Ext Right Enable"},
0873
0874
0875 {"Earpiece Playback Route", "HiFi", "HiFi Mono Right Mixer"},
0876 {"Speaker Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
0877 {"Speaker Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
0878 {"Lineout Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
0879 {"Lineout Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
0880 {"Headset Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
0881 {"Headset Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
0882 {"EMU Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
0883 {"EMU Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
0884
0885
0886 {"Earpiece Playback Route", "Voice", "Voice PGA"},
0887 {"Speaker Right Playback Route", "Voice", "Voice PGA"},
0888 {"Speaker Left Playback Route", "Voice", "Voice PGA"},
0889 {"Lineout Right Playback Route", "Voice", "Voice PGA"},
0890 {"Lineout Left Playback Route", "Voice", "Voice PGA"},
0891 {"Headset Right Playback Route", "Voice", "Voice PGA"},
0892 {"Headset Left Playback Route", "Voice", "Voice PGA"},
0893 {"EMU Right Playback Route", "Voice", "Voice PGA"},
0894 {"EMU Left Playback Route", "Voice", "Voice PGA"},
0895
0896
0897 {"Earpiece Playback Route", "Ext", "Ext Mono Right Mixer"},
0898 {"Speaker Right Playback Route", "Ext", "Ext Mono Right Mixer"},
0899 {"Speaker Left Playback Route", "Ext", "Ext Mono Left Mixer"},
0900 {"Lineout Right Playback Route", "Ext", "Ext Mono Right Mixer"},
0901 {"Lineout Left Playback Route", "Ext", "Ext Mono Left Mixer"},
0902 {"Headset Right Playback Route", "Ext", "Ext Mono Right Mixer"},
0903 {"Headset Left Playback Route", "Ext", "Ext Mono Left Mixer"},
0904 {"EMU Right Playback Route", "Ext", "Ext Mono Right Mixer"},
0905 {"EMU Left Playback Route", "Ext", "Ext Mono Left Mixer"},
0906
0907
0908 {"Earpiece PGA", NULL, "Earpiece Playback Route"},
0909 {"Speaker Right PGA", NULL, "Speaker Right Playback Route"},
0910 {"Speaker Left PGA", NULL, "Speaker Left Playback Route"},
0911 {"Lineout Right PGA", NULL, "Lineout Right Playback Route"},
0912 {"Lineout Left PGA", NULL, "Lineout Left Playback Route"},
0913 {"Headset Right PGA", NULL, "Headset Right Playback Route"},
0914 {"Headset Left PGA", NULL, "Headset Left Playback Route"},
0915 {"EMU Right PGA", NULL, "EMU Right Playback Route"},
0916 {"EMU Left PGA", NULL, "EMU Left Playback Route"},
0917
0918
0919 {"EP", NULL, "Earpiece PGA"},
0920 {"SPKR", NULL, "Speaker Right PGA"},
0921 {"SPKL", NULL, "Speaker Left PGA"},
0922 {"LINER", NULL, "Lineout Right PGA"},
0923 {"LINEL", NULL, "Lineout Left PGA"},
0924 {"HSR", NULL, "Headset Right PGA"},
0925 {"HSL", NULL, "Headset Left PGA"},
0926 {"EMUR", NULL, "EMU Right PGA"},
0927 {"EMUL", NULL, "EMU Left PGA"},
0928
0929
0930 {"HSR", NULL, "Headset Charge Pump"},
0931 {"HSL", NULL, "Headset Charge Pump"},
0932
0933
0934 {"Right Capture Route", "Mic 1", "MICR"},
0935 {"Right Capture Route", "Headset Mic", "HSMIC"},
0936 {"Right Capture Route", "EMU Mic", "EMUMIC"},
0937 {"Right Capture Route", "Ext Right", "EXTR"},
0938 {"Left Capture Route", "Mic 2", "MICL"},
0939 {"Left Capture Route", "Ext Left", "EXTL"},
0940
0941
0942 {"Microphone 1 PGA", NULL, "Right Capture Route"},
0943 {"Microphone 2 PGA", NULL, "Left Capture Route"},
0944
0945
0946 {"ADC Right", NULL, "Microphone 1 PGA"},
0947 {"ADC Left", NULL, "Microphone 2 PGA"},
0948
0949
0950 {"Highpass Filter TX", NULL, "ADC Right"},
0951 {"Highpass Filter TX", NULL, "ADC Left"},
0952
0953
0954 {"MICL", NULL, "MIC1L Bias"},
0955 {"MICR", NULL, "MIC1R Bias"},
0956 };
0957
0958 static int cpcap_set_sysclk(struct cpcap_audio *cpcap, enum cpcap_dai dai,
0959 int clk_id, int freq)
0960 {
0961 u16 clkfreqreg, clkfreqshift;
0962 u16 clkfreqmask, clkfreqval;
0963 u16 clkidreg, clkidshift;
0964 u16 mask, val;
0965 int err;
0966
0967 switch (dai) {
0968 case CPCAP_DAI_HIFI:
0969 clkfreqreg = CPCAP_REG_SDAC;
0970 clkfreqshift = CPCAP_BIT_ST_DAC_CLK0;
0971 clkidreg = CPCAP_REG_SDACDI;
0972 clkidshift = CPCAP_BIT_ST_DAC_CLK_IN_SEL;
0973 break;
0974 case CPCAP_DAI_VOICE:
0975 clkfreqreg = CPCAP_REG_CC;
0976 clkfreqshift = CPCAP_BIT_CDC_CLK0;
0977 clkidreg = CPCAP_REG_CDI;
0978 clkidshift = CPCAP_BIT_CLK_IN_SEL;
0979 break;
0980 default:
0981 dev_err(cpcap->component->dev, "invalid DAI: %d", dai);
0982 return -EINVAL;
0983 }
0984
0985
0986 if (clk_id < 0 || clk_id > 1) {
0987 dev_err(cpcap->component->dev, "invalid clk id %d", clk_id);
0988 return -EINVAL;
0989 }
0990 err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift),
0991 clk_id ? BIT(clkidshift) : 0);
0992 if (err)
0993 return err;
0994
0995
0996 if (dai == CPCAP_DAI_VOICE) {
0997 mask = BIT(CPCAP_BIT_CDC_PLL_SEL);
0998 val = BIT(CPCAP_BIT_CDC_PLL_SEL);
0999 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
1000 mask, val);
1001 if (err)
1002 return err;
1003 }
1004
1005
1006 clkfreqmask = 0x7 << clkfreqshift;
1007 switch (freq) {
1008 case 15360000:
1009 clkfreqval = 0x01 << clkfreqshift;
1010 break;
1011 case 16800000:
1012 clkfreqval = 0x02 << clkfreqshift;
1013 break;
1014 case 19200000:
1015 clkfreqval = 0x03 << clkfreqshift;
1016 break;
1017 case 26000000:
1018 clkfreqval = 0x04 << clkfreqshift;
1019 break;
1020 case 33600000:
1021 clkfreqval = 0x05 << clkfreqshift;
1022 break;
1023 case 38400000:
1024 clkfreqval = 0x06 << clkfreqshift;
1025 break;
1026 default:
1027 dev_err(cpcap->component->dev, "unsupported freq %u", freq);
1028 return -EINVAL;
1029 }
1030
1031 err = regmap_update_bits(cpcap->regmap, clkfreqreg,
1032 clkfreqmask, clkfreqval);
1033 if (err)
1034 return err;
1035
1036 if (dai == CPCAP_DAI_VOICE) {
1037 cpcap->codec_clk_id = clk_id;
1038 cpcap->codec_freq = freq;
1039 }
1040
1041 return 0;
1042 }
1043
1044 static int cpcap_set_samprate(struct cpcap_audio *cpcap, enum cpcap_dai dai,
1045 int samplerate)
1046 {
1047 struct snd_soc_component *component = cpcap->component;
1048 u16 sampreg, sampmask, sampshift, sampval, sampreset;
1049 int err, sampreadval;
1050
1051 switch (dai) {
1052 case CPCAP_DAI_HIFI:
1053 sampreg = CPCAP_REG_SDAC;
1054 sampshift = CPCAP_BIT_ST_SR0;
1055 sampreset = BIT(CPCAP_BIT_DF_RESET_ST_DAC) |
1056 BIT(CPCAP_BIT_ST_CLOCK_TREE_RESET);
1057 break;
1058 case CPCAP_DAI_VOICE:
1059 sampreg = CPCAP_REG_CC;
1060 sampshift = CPCAP_BIT_CDC_SR0;
1061 sampreset = BIT(CPCAP_BIT_DF_RESET) |
1062 BIT(CPCAP_BIT_CDC_CLOCK_TREE_RESET);
1063 break;
1064 default:
1065 dev_err(component->dev, "invalid DAI: %d", dai);
1066 return -EINVAL;
1067 }
1068
1069 sampmask = 0xF << sampshift | sampreset;
1070 switch (samplerate) {
1071 case 48000:
1072 sampval = 0x8 << sampshift;
1073 break;
1074 case 44100:
1075 sampval = 0x7 << sampshift;
1076 break;
1077 case 32000:
1078 sampval = 0x6 << sampshift;
1079 break;
1080 case 24000:
1081 sampval = 0x5 << sampshift;
1082 break;
1083 case 22050:
1084 sampval = 0x4 << sampshift;
1085 break;
1086 case 16000:
1087 sampval = 0x3 << sampshift;
1088 break;
1089 case 12000:
1090 sampval = 0x2 << sampshift;
1091 break;
1092 case 11025:
1093 sampval = 0x1 << sampshift;
1094 break;
1095 case 8000:
1096 sampval = 0x0 << sampshift;
1097 break;
1098 default:
1099 dev_err(component->dev, "unsupported samplerate %d", samplerate);
1100 return -EINVAL;
1101 }
1102 err = regmap_update_bits(cpcap->regmap, sampreg,
1103 sampmask, sampval | sampreset);
1104 if (err)
1105 return err;
1106
1107
1108 mdelay(CLOCK_TREE_RESET_TIME);
1109
1110 err = regmap_read(cpcap->regmap, sampreg, &sampreadval);
1111 if (err)
1112 return err;
1113
1114 if (sampreadval & sampreset) {
1115 dev_err(component->dev, "reset self-clear failed: %04x",
1116 sampreadval);
1117 return -EIO;
1118 }
1119
1120 return 0;
1121 }
1122
1123 static int cpcap_hifi_hw_params(struct snd_pcm_substream *substream,
1124 struct snd_pcm_hw_params *params,
1125 struct snd_soc_dai *dai)
1126 {
1127 struct snd_soc_component *component = dai->component;
1128 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1129 int rate = params_rate(params);
1130
1131 dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate);
1132 return cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, rate);
1133 }
1134
1135 static int cpcap_hifi_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
1136 unsigned int freq, int dir)
1137 {
1138 struct snd_soc_component *component = codec_dai->component;
1139 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1140 struct device *dev = component->dev;
1141
1142 dev_dbg(dev, "HiFi setup sysclk: clk_id=%u, freq=%u", clk_id, freq);
1143 return cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, clk_id, freq);
1144 }
1145
1146 static int cpcap_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
1147 unsigned int fmt)
1148 {
1149 struct snd_soc_component *component = codec_dai->component;
1150 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1151 struct device *dev = component->dev;
1152 static const u16 reg = CPCAP_REG_SDACDI;
1153 static const u16 mask =
1154 BIT(CPCAP_BIT_SMB_ST_DAC) |
1155 BIT(CPCAP_BIT_ST_CLK_INV) |
1156 BIT(CPCAP_BIT_ST_FS_INV) |
1157 BIT(CPCAP_BIT_ST_DIG_AUD_FS0) |
1158 BIT(CPCAP_BIT_ST_DIG_AUD_FS1) |
1159 BIT(CPCAP_BIT_ST_L_TIMESLOT0) |
1160 BIT(CPCAP_BIT_ST_L_TIMESLOT1) |
1161 BIT(CPCAP_BIT_ST_L_TIMESLOT2) |
1162 BIT(CPCAP_BIT_ST_R_TIMESLOT0) |
1163 BIT(CPCAP_BIT_ST_R_TIMESLOT1) |
1164 BIT(CPCAP_BIT_ST_R_TIMESLOT2);
1165 u16 val = 0x0000;
1166
1167 dev_dbg(dev, "HiFi setup dai format (%08x)", fmt);
1168
1169
1170
1171
1172
1173
1174 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1175 case SND_SOC_DAIFMT_CBP_CFP:
1176 val &= ~BIT(CPCAP_BIT_SMB_ST_DAC);
1177 break;
1178 default:
1179 dev_err(dev, "HiFi dai fmt failed: CPCAP should be provider");
1180 return -EINVAL;
1181 }
1182
1183 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1184 case SND_SOC_DAIFMT_IB_IF:
1185 val |= BIT(CPCAP_BIT_ST_FS_INV);
1186 val |= BIT(CPCAP_BIT_ST_CLK_INV);
1187 break;
1188 case SND_SOC_DAIFMT_IB_NF:
1189 val &= ~BIT(CPCAP_BIT_ST_FS_INV);
1190 val |= BIT(CPCAP_BIT_ST_CLK_INV);
1191 break;
1192 case SND_SOC_DAIFMT_NB_IF:
1193 val |= BIT(CPCAP_BIT_ST_FS_INV);
1194 val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
1195 break;
1196 case SND_SOC_DAIFMT_NB_NF:
1197 val &= ~BIT(CPCAP_BIT_ST_FS_INV);
1198 val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
1199 break;
1200 default:
1201 dev_err(dev, "HiFi dai fmt failed: unsupported clock invert mode");
1202 return -EINVAL;
1203 }
1204
1205 if (val & BIT(CPCAP_BIT_ST_CLK_INV))
1206 val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
1207 else
1208 val |= BIT(CPCAP_BIT_ST_CLK_INV);
1209
1210 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1211 case SND_SOC_DAIFMT_I2S:
1212 val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
1213 val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
1214 break;
1215 default:
1216
1217 val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
1218 val &= ~BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
1219
1220 val |= BIT(CPCAP_BIT_ST_L_TIMESLOT0);
1221 break;
1222 }
1223
1224 dev_dbg(dev, "HiFi dai format: val=%04x", val);
1225 return regmap_update_bits(cpcap->regmap, reg, mask, val);
1226 }
1227
1228 static int cpcap_hifi_set_mute(struct snd_soc_dai *dai, int mute, int direction)
1229 {
1230 struct snd_soc_component *component = dai->component;
1231 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1232 static const u16 reg = CPCAP_REG_RXSDOA;
1233 static const u16 mask = BIT(CPCAP_BIT_ST_DAC_SW);
1234 u16 val;
1235
1236 if (mute)
1237 val = 0;
1238 else
1239 val = BIT(CPCAP_BIT_ST_DAC_SW);
1240
1241 dev_dbg(component->dev, "HiFi mute: %d", mute);
1242 return regmap_update_bits(cpcap->regmap, reg, mask, val);
1243 }
1244
1245 static const struct snd_soc_dai_ops cpcap_dai_hifi_ops = {
1246 .hw_params = cpcap_hifi_hw_params,
1247 .set_sysclk = cpcap_hifi_set_dai_sysclk,
1248 .set_fmt = cpcap_hifi_set_dai_fmt,
1249 .mute_stream = cpcap_hifi_set_mute,
1250 .no_capture_mute = 1,
1251 };
1252
1253 static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
1254 struct snd_pcm_hw_params *params,
1255 struct snd_soc_dai *dai)
1256 {
1257 struct snd_soc_component *component = dai->component;
1258 struct device *dev = component->dev;
1259 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1260 static const u16 reg_cdi = CPCAP_REG_CDI;
1261 int rate = params_rate(params);
1262 int channels = params_channels(params);
1263 int direction = substream->stream;
1264 u16 val, mask;
1265 int err;
1266
1267 dev_dbg(dev, "Voice setup HW params: rate=%d, direction=%d, chan=%d",
1268 rate, direction, channels);
1269
1270 err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate);
1271 if (err)
1272 return err;
1273
1274 if (direction == SNDRV_PCM_STREAM_CAPTURE) {
1275 mask = 0x0000;
1276 mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
1277 mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1);
1278 mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2);
1279 mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0);
1280 mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1);
1281 mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2);
1282 val = 0x0000;
1283 if (channels >= 2)
1284 val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
1285 err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val);
1286 if (err)
1287 return err;
1288 }
1289
1290 return 0;
1291 }
1292
1293 static int cpcap_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
1294 unsigned int freq, int dir)
1295 {
1296 struct snd_soc_component *component = codec_dai->component;
1297 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1298
1299 dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u",
1300 clk_id, freq);
1301 return cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, clk_id, freq);
1302 }
1303
1304 static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1305 unsigned int fmt)
1306 {
1307 struct snd_soc_component *component = codec_dai->component;
1308 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1309 static const u16 mask = BIT(CPCAP_BIT_SMB_CDC) |
1310 BIT(CPCAP_BIT_CLK_INV) |
1311 BIT(CPCAP_BIT_FS_INV) |
1312 BIT(CPCAP_BIT_CDC_DIG_AUD_FS0) |
1313 BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
1314 u16 val = 0x0000;
1315 int err;
1316
1317 dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt);
1318
1319
1320
1321
1322
1323
1324 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
1325 case SND_SOC_DAIFMT_CBP_CFP:
1326 val &= ~BIT(CPCAP_BIT_SMB_CDC);
1327 break;
1328 default:
1329 dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the provider");
1330 val &= ~BIT(CPCAP_BIT_SMB_CDC);
1331 break;
1332 }
1333
1334 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1335 case SND_SOC_DAIFMT_IB_IF:
1336 val |= BIT(CPCAP_BIT_CLK_INV);
1337 val |= BIT(CPCAP_BIT_FS_INV);
1338 break;
1339 case SND_SOC_DAIFMT_IB_NF:
1340 val |= BIT(CPCAP_BIT_CLK_INV);
1341 val &= ~BIT(CPCAP_BIT_FS_INV);
1342 break;
1343 case SND_SOC_DAIFMT_NB_IF:
1344 val &= ~BIT(CPCAP_BIT_CLK_INV);
1345 val |= BIT(CPCAP_BIT_FS_INV);
1346 break;
1347 case SND_SOC_DAIFMT_NB_NF:
1348 val &= ~BIT(CPCAP_BIT_CLK_INV);
1349 val &= ~BIT(CPCAP_BIT_FS_INV);
1350 break;
1351 default:
1352 dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode");
1353 break;
1354 }
1355
1356 if (val & BIT(CPCAP_BIT_CLK_INV))
1357 val &= ~BIT(CPCAP_BIT_CLK_INV);
1358 else
1359 val |= BIT(CPCAP_BIT_CLK_INV);
1360
1361 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1362 case SND_SOC_DAIFMT_I2S:
1363
1364 val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
1365 val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
1366 break;
1367 default:
1368
1369 val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
1370 val &= ~BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
1371 break;
1372 }
1373
1374 dev_dbg(component->dev, "Voice dai format: val=%04x", val);
1375 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val);
1376 if (err)
1377 return err;
1378
1379 cpcap->codec_format = val;
1380 return 0;
1381 }
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391 static int cpcap_voice_call(struct cpcap_audio *cpcap, struct snd_soc_dai *dai,
1392 bool voice_call)
1393 {
1394 int mask, err;
1395
1396
1397 mask = BIT(CPCAP_BIT_VAUDIO_MODE1);
1398 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC,
1399 mask, voice_call ? mask : 0);
1400 if (err)
1401 return err;
1402
1403
1404 mask = BIT(CPCAP_BIT_MIC1_MUX);
1405 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
1406 mask, voice_call ? 0 : mask);
1407 if (err)
1408 return err;
1409
1410
1411 mask = BIT(CPCAP_BIT_MB_ON1L) | BIT(CPCAP_BIT_MB_ON1R) |
1412 BIT(CPCAP_BIT_MIC2_MUX) | BIT(CPCAP_BIT_MIC2_PGA_EN);
1413 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
1414 mask, voice_call ? mask : 0);
1415 if (err)
1416 return err;
1417
1418
1419 mask = BIT(CPCAP_BIT_A2_LDSP_L_EN) | BIT(CPCAP_BIT_A2_LDSP_R_EN);
1420 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA,
1421 mask, voice_call ? mask : 0);
1422 if (err)
1423 return err;
1424
1425
1426 mask = BIT(CPCAP_BIT_PGA_CDC_EN);
1427 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
1428 mask, voice_call ? mask : 0);
1429 if (err)
1430 return err;
1431
1432
1433 if (dai) {
1434 err = snd_soc_dai_digital_mute(dai, !voice_call,
1435 SNDRV_PCM_STREAM_PLAYBACK);
1436 if (err)
1437 return err;
1438 }
1439
1440
1441 mask = BIT(CPCAP_BIT_MIC2_CDC_EN) | BIT(CPCAP_BIT_CDC_EN_RX) |
1442 BIT(CPCAP_BIT_AUDOHPF_1) | BIT(CPCAP_BIT_AUDOHPF_0) |
1443 BIT(CPCAP_BIT_AUDIHPF_1) | BIT(CPCAP_BIT_AUDIHPF_0);
1444 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC,
1445 mask, voice_call ? mask : 0);
1446 if (err)
1447 return err;
1448
1449
1450 mask = BIT(CPCAP_BIT_CDC_CLK_EN);
1451 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
1452 mask, voice_call ? mask : 0);
1453
1454 return err;
1455 }
1456
1457 static int cpcap_voice_set_tdm_slot(struct snd_soc_dai *dai,
1458 unsigned int tx_mask, unsigned int rx_mask,
1459 int slots, int slot_width)
1460 {
1461 struct snd_soc_component *component = dai->component;
1462 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1463 int err, ts_mask, mask;
1464 bool voice_call;
1465
1466
1467
1468
1469
1470 if (tx_mask == 0 && rx_mask == 1 && slot_width == 8)
1471 voice_call = true;
1472 else
1473 voice_call = false;
1474
1475 ts_mask = 0x7 << CPCAP_BIT_MIC2_TIMESLOT0;
1476 ts_mask |= 0x7 << CPCAP_BIT_MIC1_RX_TIMESLOT0;
1477
1478 mask = (tx_mask & 0x7) << CPCAP_BIT_MIC2_TIMESLOT0;
1479 mask |= (rx_mask & 0x7) << CPCAP_BIT_MIC1_RX_TIMESLOT0;
1480
1481 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
1482 ts_mask, mask);
1483 if (err)
1484 return err;
1485
1486 err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, slot_width * 1000);
1487 if (err)
1488 return err;
1489
1490 err = cpcap_voice_call(cpcap, dai, voice_call);
1491 if (err)
1492 return err;
1493
1494 return 0;
1495 }
1496
1497 static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute, int direction)
1498 {
1499 struct snd_soc_component *component = dai->component;
1500 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1501 static const u16 reg = CPCAP_REG_RXCOA;
1502 static const u16 mask = BIT(CPCAP_BIT_CDC_SW);
1503 u16 val;
1504
1505 if (mute)
1506 val = 0;
1507 else
1508 val = BIT(CPCAP_BIT_CDC_SW);
1509
1510 dev_dbg(component->dev, "Voice mute: %d", mute);
1511 return regmap_update_bits(cpcap->regmap, reg, mask, val);
1512 };
1513
1514 static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
1515 .hw_params = cpcap_voice_hw_params,
1516 .set_sysclk = cpcap_voice_set_dai_sysclk,
1517 .set_fmt = cpcap_voice_set_dai_fmt,
1518 .set_tdm_slot = cpcap_voice_set_tdm_slot,
1519 .mute_stream = cpcap_voice_set_mute,
1520 .no_capture_mute = 1,
1521 };
1522
1523 static struct snd_soc_dai_driver cpcap_dai[] = {
1524 {
1525 .id = 0,
1526 .name = "cpcap-hifi",
1527 .playback = {
1528 .stream_name = "HiFi Playback",
1529 .channels_min = 2,
1530 .channels_max = 2,
1531 .rates = SNDRV_PCM_RATE_8000_48000,
1532 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE,
1533 },
1534 .ops = &cpcap_dai_hifi_ops,
1535 },
1536 {
1537 .id = 1,
1538 .name = "cpcap-voice",
1539 .playback = {
1540 .stream_name = "Voice Playback",
1541 .channels_min = 1,
1542 .channels_max = 1,
1543 .rates = SNDRV_PCM_RATE_8000_48000,
1544 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1545 },
1546 .capture = {
1547 .stream_name = "Voice Capture",
1548 .channels_min = 1,
1549 .channels_max = 2,
1550 .rates = SNDRV_PCM_RATE_8000_48000,
1551 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1552 },
1553 .ops = &cpcap_dai_voice_ops,
1554 },
1555 };
1556
1557 static int cpcap_dai_mux(struct cpcap_audio *cpcap, bool swap_dai_configuration)
1558 {
1559 u16 hifi_val, voice_val;
1560 u16 hifi_mask = BIT(CPCAP_BIT_DIG_AUD_IN_ST_DAC);
1561 u16 voice_mask = BIT(CPCAP_BIT_DIG_AUD_IN);
1562 int err;
1563
1564
1565
1566 if (!swap_dai_configuration) {
1567
1568 voice_val = 0;
1569 hifi_val = hifi_mask;
1570 } else {
1571
1572 voice_val = voice_mask;
1573 hifi_val = 0;
1574 }
1575
1576 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
1577 voice_mask, voice_val);
1578 if (err)
1579 return err;
1580
1581 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI,
1582 hifi_mask, hifi_val);
1583 if (err)
1584 return err;
1585
1586 return 0;
1587 }
1588
1589 static int cpcap_audio_reset(struct snd_soc_component *component,
1590 bool swap_dai_configuration)
1591 {
1592 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
1593 int i, err = 0;
1594
1595 dev_dbg(component->dev, "init audio codec");
1596
1597 for (i = 0; i < ARRAY_SIZE(cpcap_default_regs); i++) {
1598 err = regmap_update_bits(cpcap->regmap,
1599 cpcap_default_regs[i].reg,
1600 cpcap_default_regs[i].mask,
1601 cpcap_default_regs[i].val);
1602 if (err)
1603 return err;
1604 }
1605
1606
1607 err = cpcap_dai_mux(cpcap, swap_dai_configuration);
1608 if (err)
1609 return err;
1610
1611 err = cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, 0, 26000000);
1612 if (err)
1613 return err;
1614 err = cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, 0, 26000000);
1615 if (err)
1616 return err;
1617
1618 err = cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, 48000);
1619 if (err)
1620 return err;
1621
1622 err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, 48000);
1623 if (err)
1624 return err;
1625
1626 return 0;
1627 }
1628
1629 static int cpcap_soc_probe(struct snd_soc_component *component)
1630 {
1631 struct cpcap_audio *cpcap;
1632 int err;
1633
1634 cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL);
1635 if (!cpcap)
1636 return -ENOMEM;
1637 snd_soc_component_set_drvdata(component, cpcap);
1638 cpcap->component = component;
1639
1640 cpcap->regmap = dev_get_regmap(component->dev->parent, NULL);
1641 if (!cpcap->regmap)
1642 return -ENODEV;
1643 snd_soc_component_init_regmap(component, cpcap->regmap);
1644
1645 err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor);
1646 if (err)
1647 return err;
1648
1649 return cpcap_audio_reset(component, false);
1650 }
1651
1652 static struct snd_soc_component_driver soc_codec_dev_cpcap = {
1653 .probe = cpcap_soc_probe,
1654 .controls = cpcap_snd_controls,
1655 .num_controls = ARRAY_SIZE(cpcap_snd_controls),
1656 .dapm_widgets = cpcap_dapm_widgets,
1657 .num_dapm_widgets = ARRAY_SIZE(cpcap_dapm_widgets),
1658 .dapm_routes = intercon,
1659 .num_dapm_routes = ARRAY_SIZE(intercon),
1660 .idle_bias_on = 1,
1661 .use_pmdown_time = 1,
1662 .endianness = 1,
1663 };
1664
1665 static int cpcap_codec_probe(struct platform_device *pdev)
1666 {
1667 struct device_node *codec_node =
1668 of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec");
1669 if (!codec_node)
1670 return -ENODEV;
1671
1672 pdev->dev.of_node = codec_node;
1673
1674 return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap,
1675 cpcap_dai, ARRAY_SIZE(cpcap_dai));
1676 }
1677
1678 static struct platform_driver cpcap_codec_driver = {
1679 .probe = cpcap_codec_probe,
1680 .driver = {
1681 .name = "cpcap-codec",
1682 },
1683 };
1684 module_platform_driver(cpcap_codec_driver);
1685
1686 MODULE_ALIAS("platform:cpcap-codec");
1687 MODULE_DESCRIPTION("ASoC CPCAP codec driver");
1688 MODULE_AUTHOR("Sebastian Reichel");
1689 MODULE_LICENSE("GPL v2");