0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/clk.h>
0012 #include <linux/delay.h>
0013 #include <linux/i2c.h>
0014 #include <linux/module.h>
0015 #include <linux/of_gpio.h>
0016 #include <linux/gpio/consumer.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <sound/pcm_params.h>
0019 #include <sound/soc.h>
0020 #include <sound/tlv.h>
0021
0022 #include "cs53l30.h"
0023 #include "cirrus_legacy.h"
0024
0025 #define CS53L30_NUM_SUPPLIES 2
0026 static const char *const cs53l30_supply_names[CS53L30_NUM_SUPPLIES] = {
0027 "VA",
0028 "VP",
0029 };
0030
0031 struct cs53l30_private {
0032 struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES];
0033 struct regmap *regmap;
0034 struct gpio_desc *reset_gpio;
0035 struct gpio_desc *mute_gpio;
0036 struct clk *mclk;
0037 bool use_sdout2;
0038 u32 mclk_rate;
0039 };
0040
0041 static const struct reg_default cs53l30_reg_defaults[] = {
0042 { CS53L30_PWRCTL, CS53L30_PWRCTL_DEFAULT },
0043 { CS53L30_MCLKCTL, CS53L30_MCLKCTL_DEFAULT },
0044 { CS53L30_INT_SR_CTL, CS53L30_INT_SR_CTL_DEFAULT },
0045 { CS53L30_MICBIAS_CTL, CS53L30_MICBIAS_CTL_DEFAULT },
0046 { CS53L30_ASPCFG_CTL, CS53L30_ASPCFG_CTL_DEFAULT },
0047 { CS53L30_ASP_CTL1, CS53L30_ASP_CTL1_DEFAULT },
0048 { CS53L30_ASP_TDMTX_CTL1, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
0049 { CS53L30_ASP_TDMTX_CTL2, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
0050 { CS53L30_ASP_TDMTX_CTL3, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
0051 { CS53L30_ASP_TDMTX_CTL4, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
0052 { CS53L30_ASP_TDMTX_EN1, CS53L30_ASP_TDMTX_ENx_DEFAULT },
0053 { CS53L30_ASP_TDMTX_EN2, CS53L30_ASP_TDMTX_ENx_DEFAULT },
0054 { CS53L30_ASP_TDMTX_EN3, CS53L30_ASP_TDMTX_ENx_DEFAULT },
0055 { CS53L30_ASP_TDMTX_EN4, CS53L30_ASP_TDMTX_ENx_DEFAULT },
0056 { CS53L30_ASP_TDMTX_EN5, CS53L30_ASP_TDMTX_ENx_DEFAULT },
0057 { CS53L30_ASP_TDMTX_EN6, CS53L30_ASP_TDMTX_ENx_DEFAULT },
0058 { CS53L30_ASP_CTL2, CS53L30_ASP_CTL2_DEFAULT },
0059 { CS53L30_SFT_RAMP, CS53L30_SFT_RMP_DEFAULT },
0060 { CS53L30_LRCK_CTL1, CS53L30_LRCK_CTLx_DEFAULT },
0061 { CS53L30_LRCK_CTL2, CS53L30_LRCK_CTLx_DEFAULT },
0062 { CS53L30_MUTEP_CTL1, CS53L30_MUTEP_CTL1_DEFAULT },
0063 { CS53L30_MUTEP_CTL2, CS53L30_MUTEP_CTL2_DEFAULT },
0064 { CS53L30_INBIAS_CTL1, CS53L30_INBIAS_CTL1_DEFAULT },
0065 { CS53L30_INBIAS_CTL2, CS53L30_INBIAS_CTL2_DEFAULT },
0066 { CS53L30_DMIC1_STR_CTL, CS53L30_DMIC1_STR_CTL_DEFAULT },
0067 { CS53L30_DMIC2_STR_CTL, CS53L30_DMIC2_STR_CTL_DEFAULT },
0068 { CS53L30_ADCDMIC1_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT },
0069 { CS53L30_ADCDMIC1_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT },
0070 { CS53L30_ADC1_CTL3, CS53L30_ADCx_CTL3_DEFAULT },
0071 { CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT },
0072 { CS53L30_ADC1A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
0073 { CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
0074 { CS53L30_ADC1A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
0075 { CS53L30_ADC1B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
0076 { CS53L30_ADCDMIC2_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT },
0077 { CS53L30_ADCDMIC2_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT },
0078 { CS53L30_ADC2_CTL3, CS53L30_ADCx_CTL3_DEFAULT },
0079 { CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT },
0080 { CS53L30_ADC2A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
0081 { CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
0082 { CS53L30_ADC2A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
0083 { CS53L30_ADC2B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
0084 { CS53L30_INT_MASK, CS53L30_DEVICE_INT_MASK },
0085 };
0086
0087 static bool cs53l30_volatile_register(struct device *dev, unsigned int reg)
0088 {
0089 if (reg == CS53L30_IS)
0090 return true;
0091 else
0092 return false;
0093 }
0094
0095 static bool cs53l30_writeable_register(struct device *dev, unsigned int reg)
0096 {
0097 switch (reg) {
0098 case CS53L30_DEVID_AB:
0099 case CS53L30_DEVID_CD:
0100 case CS53L30_DEVID_E:
0101 case CS53L30_REVID:
0102 case CS53L30_IS:
0103 return false;
0104 default:
0105 return true;
0106 }
0107 }
0108
0109 static bool cs53l30_readable_register(struct device *dev, unsigned int reg)
0110 {
0111 switch (reg) {
0112 case CS53L30_DEVID_AB:
0113 case CS53L30_DEVID_CD:
0114 case CS53L30_DEVID_E:
0115 case CS53L30_REVID:
0116 case CS53L30_PWRCTL:
0117 case CS53L30_MCLKCTL:
0118 case CS53L30_INT_SR_CTL:
0119 case CS53L30_MICBIAS_CTL:
0120 case CS53L30_ASPCFG_CTL:
0121 case CS53L30_ASP_CTL1:
0122 case CS53L30_ASP_TDMTX_CTL1:
0123 case CS53L30_ASP_TDMTX_CTL2:
0124 case CS53L30_ASP_TDMTX_CTL3:
0125 case CS53L30_ASP_TDMTX_CTL4:
0126 case CS53L30_ASP_TDMTX_EN1:
0127 case CS53L30_ASP_TDMTX_EN2:
0128 case CS53L30_ASP_TDMTX_EN3:
0129 case CS53L30_ASP_TDMTX_EN4:
0130 case CS53L30_ASP_TDMTX_EN5:
0131 case CS53L30_ASP_TDMTX_EN6:
0132 case CS53L30_ASP_CTL2:
0133 case CS53L30_SFT_RAMP:
0134 case CS53L30_LRCK_CTL1:
0135 case CS53L30_LRCK_CTL2:
0136 case CS53L30_MUTEP_CTL1:
0137 case CS53L30_MUTEP_CTL2:
0138 case CS53L30_INBIAS_CTL1:
0139 case CS53L30_INBIAS_CTL2:
0140 case CS53L30_DMIC1_STR_CTL:
0141 case CS53L30_DMIC2_STR_CTL:
0142 case CS53L30_ADCDMIC1_CTL1:
0143 case CS53L30_ADCDMIC1_CTL2:
0144 case CS53L30_ADC1_CTL3:
0145 case CS53L30_ADC1_NG_CTL:
0146 case CS53L30_ADC1A_AFE_CTL:
0147 case CS53L30_ADC1B_AFE_CTL:
0148 case CS53L30_ADC1A_DIG_VOL:
0149 case CS53L30_ADC1B_DIG_VOL:
0150 case CS53L30_ADCDMIC2_CTL1:
0151 case CS53L30_ADCDMIC2_CTL2:
0152 case CS53L30_ADC2_CTL3:
0153 case CS53L30_ADC2_NG_CTL:
0154 case CS53L30_ADC2A_AFE_CTL:
0155 case CS53L30_ADC2B_AFE_CTL:
0156 case CS53L30_ADC2A_DIG_VOL:
0157 case CS53L30_ADC2B_DIG_VOL:
0158 case CS53L30_INT_MASK:
0159 return true;
0160 default:
0161 return false;
0162 }
0163 }
0164
0165 static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2000, 0);
0166 static DECLARE_TLV_DB_SCALE(adc_ng_boost_tlv, 0, 3000, 0);
0167 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
0168 static DECLARE_TLV_DB_SCALE(dig_tlv, -9600, 100, 1);
0169 static DECLARE_TLV_DB_SCALE(pga_preamp_tlv, 0, 10000, 0);
0170
0171 static const char * const input1_sel_text[] = {
0172 "DMIC1 On AB In",
0173 "DMIC1 On A In",
0174 "DMIC1 On B In",
0175 "ADC1 On AB In",
0176 "ADC1 On A In",
0177 "ADC1 On B In",
0178 "DMIC1 Off ADC1 Off",
0179 };
0180
0181 static unsigned int const input1_sel_values[] = {
0182 CS53L30_CH_TYPE,
0183 CS53L30_ADCxB_PDN | CS53L30_CH_TYPE,
0184 CS53L30_ADCxA_PDN | CS53L30_CH_TYPE,
0185 CS53L30_DMICx_PDN,
0186 CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
0187 CS53L30_ADCxA_PDN | CS53L30_DMICx_PDN,
0188 CS53L30_ADCxA_PDN | CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
0189 };
0190
0191 static const char * const input2_sel_text[] = {
0192 "DMIC2 On AB In",
0193 "DMIC2 On A In",
0194 "DMIC2 On B In",
0195 "ADC2 On AB In",
0196 "ADC2 On A In",
0197 "ADC2 On B In",
0198 "DMIC2 Off ADC2 Off",
0199 };
0200
0201 static unsigned int const input2_sel_values[] = {
0202 0x0,
0203 CS53L30_ADCxB_PDN,
0204 CS53L30_ADCxA_PDN,
0205 CS53L30_DMICx_PDN,
0206 CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
0207 CS53L30_ADCxA_PDN | CS53L30_DMICx_PDN,
0208 CS53L30_ADCxA_PDN | CS53L30_ADCxB_PDN | CS53L30_DMICx_PDN,
0209 };
0210
0211 static const char * const input1_route_sel_text[] = {
0212 "ADC1_SEL", "DMIC1_SEL",
0213 };
0214
0215 static const struct soc_enum input1_route_sel_enum =
0216 SOC_ENUM_SINGLE(CS53L30_ADCDMIC1_CTL1, CS53L30_CH_TYPE_SHIFT,
0217 ARRAY_SIZE(input1_route_sel_text),
0218 input1_route_sel_text);
0219
0220 static SOC_VALUE_ENUM_SINGLE_DECL(input1_sel_enum, CS53L30_ADCDMIC1_CTL1, 0,
0221 CS53L30_ADCDMICx_PDN_MASK, input1_sel_text,
0222 input1_sel_values);
0223
0224 static const struct snd_kcontrol_new input1_route_sel_mux =
0225 SOC_DAPM_ENUM("Input 1 Route", input1_route_sel_enum);
0226
0227 static const char * const input2_route_sel_text[] = {
0228 "ADC2_SEL", "DMIC2_SEL",
0229 };
0230
0231
0232 static const struct soc_enum input2_route_sel_enum =
0233 SOC_ENUM_SINGLE(CS53L30_ADCDMIC1_CTL1, 0,
0234 ARRAY_SIZE(input2_route_sel_text),
0235 input2_route_sel_text);
0236
0237 static SOC_VALUE_ENUM_SINGLE_DECL(input2_sel_enum, CS53L30_ADCDMIC2_CTL1, 0,
0238 CS53L30_ADCDMICx_PDN_MASK, input2_sel_text,
0239 input2_sel_values);
0240
0241 static const struct snd_kcontrol_new input2_route_sel_mux =
0242 SOC_DAPM_ENUM("Input 2 Route", input2_route_sel_enum);
0243
0244
0245
0246
0247
0248
0249 static const char * const cs53l30_ng_delay_text[] = {
0250 "TB*50ms", "TB*100ms", "TB*150ms", "TB*200ms",
0251 };
0252
0253 static const struct soc_enum adc1_ng_delay_enum =
0254 SOC_ENUM_SINGLE(CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_DELAY_SHIFT,
0255 ARRAY_SIZE(cs53l30_ng_delay_text),
0256 cs53l30_ng_delay_text);
0257
0258 static const struct soc_enum adc2_ng_delay_enum =
0259 SOC_ENUM_SINGLE(CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_DELAY_SHIFT,
0260 ARRAY_SIZE(cs53l30_ng_delay_text),
0261 cs53l30_ng_delay_text);
0262
0263
0264 static const char * const cs53l30_ng_thres_text[] = {
0265 "-64dB/-34dB", "-66dB/-36dB", "-70dB/-40dB", "-73dB/-43dB",
0266 "-76dB/-46dB", "-82dB/-52dB", "-58dB", "-64dB",
0267 };
0268
0269 static const struct soc_enum adc1_ng_thres_enum =
0270 SOC_ENUM_SINGLE(CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_THRESH_SHIFT,
0271 ARRAY_SIZE(cs53l30_ng_thres_text),
0272 cs53l30_ng_thres_text);
0273
0274 static const struct soc_enum adc2_ng_thres_enum =
0275 SOC_ENUM_SINGLE(CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_THRESH_SHIFT,
0276 ARRAY_SIZE(cs53l30_ng_thres_text),
0277 cs53l30_ng_thres_text);
0278
0279
0280 static const char * const hpf_corner_freq_text[] = {
0281 "1.86Hz", "120Hz", "235Hz", "466Hz",
0282 };
0283
0284 static const struct soc_enum adc1_hpf_enum =
0285 SOC_ENUM_SINGLE(CS53L30_ADC1_CTL3, CS53L30_ADCx_HPF_CF_SHIFT,
0286 ARRAY_SIZE(hpf_corner_freq_text), hpf_corner_freq_text);
0287
0288 static const struct soc_enum adc2_hpf_enum =
0289 SOC_ENUM_SINGLE(CS53L30_ADC2_CTL3, CS53L30_ADCx_HPF_CF_SHIFT,
0290 ARRAY_SIZE(hpf_corner_freq_text), hpf_corner_freq_text);
0291
0292 static const struct snd_kcontrol_new cs53l30_snd_controls[] = {
0293 SOC_SINGLE("Digital Soft-Ramp Switch", CS53L30_SFT_RAMP,
0294 CS53L30_DIGSFT_SHIFT, 1, 0),
0295 SOC_SINGLE("ADC1 Noise Gate Ganging Switch", CS53L30_ADC1_CTL3,
0296 CS53L30_ADCx_NG_ALL_SHIFT, 1, 0),
0297 SOC_SINGLE("ADC2 Noise Gate Ganging Switch", CS53L30_ADC2_CTL3,
0298 CS53L30_ADCx_NG_ALL_SHIFT, 1, 0),
0299 SOC_SINGLE("ADC1A Noise Gate Enable Switch", CS53L30_ADC1_NG_CTL,
0300 CS53L30_ADCxA_NG_SHIFT, 1, 0),
0301 SOC_SINGLE("ADC1B Noise Gate Enable Switch", CS53L30_ADC1_NG_CTL,
0302 CS53L30_ADCxB_NG_SHIFT, 1, 0),
0303 SOC_SINGLE("ADC2A Noise Gate Enable Switch", CS53L30_ADC2_NG_CTL,
0304 CS53L30_ADCxA_NG_SHIFT, 1, 0),
0305 SOC_SINGLE("ADC2B Noise Gate Enable Switch", CS53L30_ADC2_NG_CTL,
0306 CS53L30_ADCxB_NG_SHIFT, 1, 0),
0307 SOC_SINGLE("ADC1 Notch Filter Switch", CS53L30_ADCDMIC1_CTL2,
0308 CS53L30_ADCx_NOTCH_DIS_SHIFT, 1, 1),
0309 SOC_SINGLE("ADC2 Notch Filter Switch", CS53L30_ADCDMIC2_CTL2,
0310 CS53L30_ADCx_NOTCH_DIS_SHIFT, 1, 1),
0311 SOC_SINGLE("ADC1A Invert Switch", CS53L30_ADCDMIC1_CTL2,
0312 CS53L30_ADCxA_INV_SHIFT, 1, 0),
0313 SOC_SINGLE("ADC1B Invert Switch", CS53L30_ADCDMIC1_CTL2,
0314 CS53L30_ADCxB_INV_SHIFT, 1, 0),
0315 SOC_SINGLE("ADC2A Invert Switch", CS53L30_ADCDMIC2_CTL2,
0316 CS53L30_ADCxA_INV_SHIFT, 1, 0),
0317 SOC_SINGLE("ADC2B Invert Switch", CS53L30_ADCDMIC2_CTL2,
0318 CS53L30_ADCxB_INV_SHIFT, 1, 0),
0319
0320 SOC_SINGLE_TLV("ADC1A Digital Boost Volume", CS53L30_ADCDMIC1_CTL2,
0321 CS53L30_ADCxA_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
0322 SOC_SINGLE_TLV("ADC1B Digital Boost Volume", CS53L30_ADCDMIC1_CTL2,
0323 CS53L30_ADCxB_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
0324 SOC_SINGLE_TLV("ADC2A Digital Boost Volume", CS53L30_ADCDMIC2_CTL2,
0325 CS53L30_ADCxA_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
0326 SOC_SINGLE_TLV("ADC2B Digital Boost Volume", CS53L30_ADCDMIC2_CTL2,
0327 CS53L30_ADCxB_DIG_BOOST_SHIFT, 1, 0, adc_boost_tlv),
0328 SOC_SINGLE_TLV("ADC1 NG Boost Volume", CS53L30_ADC1_NG_CTL,
0329 CS53L30_ADCx_NG_BOOST_SHIFT, 1, 0, adc_ng_boost_tlv),
0330 SOC_SINGLE_TLV("ADC2 NG Boost Volume", CS53L30_ADC2_NG_CTL,
0331 CS53L30_ADCx_NG_BOOST_SHIFT, 1, 0, adc_ng_boost_tlv),
0332
0333 SOC_DOUBLE_R_TLV("ADC1 Preamplifier Volume", CS53L30_ADC1A_AFE_CTL,
0334 CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_PREAMP_SHIFT,
0335 2, 0, pga_preamp_tlv),
0336 SOC_DOUBLE_R_TLV("ADC2 Preamplifier Volume", CS53L30_ADC2A_AFE_CTL,
0337 CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_PREAMP_SHIFT,
0338 2, 0, pga_preamp_tlv),
0339
0340 SOC_ENUM("Input 1 Channel Select", input1_sel_enum),
0341 SOC_ENUM("Input 2 Channel Select", input2_sel_enum),
0342
0343 SOC_ENUM("ADC1 HPF Select", adc1_hpf_enum),
0344 SOC_ENUM("ADC2 HPF Select", adc2_hpf_enum),
0345 SOC_ENUM("ADC1 NG Threshold", adc1_ng_thres_enum),
0346 SOC_ENUM("ADC2 NG Threshold", adc2_ng_thres_enum),
0347 SOC_ENUM("ADC1 NG Delay", adc1_ng_delay_enum),
0348 SOC_ENUM("ADC2 NG Delay", adc2_ng_delay_enum),
0349
0350 SOC_SINGLE_SX_TLV("ADC1A PGA Volume",
0351 CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
0352 SOC_SINGLE_SX_TLV("ADC1B PGA Volume",
0353 CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
0354 SOC_SINGLE_SX_TLV("ADC2A PGA Volume",
0355 CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
0356 SOC_SINGLE_SX_TLV("ADC2B PGA Volume",
0357 CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x24, pga_tlv),
0358
0359 SOC_SINGLE_SX_TLV("ADC1A Digital Volume",
0360 CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
0361 SOC_SINGLE_SX_TLV("ADC1B Digital Volume",
0362 CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
0363 SOC_SINGLE_SX_TLV("ADC2A Digital Volume",
0364 CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
0365 SOC_SINGLE_SX_TLV("ADC2B Digital Volume",
0366 CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv),
0367 };
0368
0369 static const struct snd_soc_dapm_widget cs53l30_dapm_widgets[] = {
0370 SND_SOC_DAPM_INPUT("IN1_DMIC1"),
0371 SND_SOC_DAPM_INPUT("IN2"),
0372 SND_SOC_DAPM_INPUT("IN3_DMIC2"),
0373 SND_SOC_DAPM_INPUT("IN4"),
0374 SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS53L30_MICBIAS_CTL,
0375 CS53L30_MIC1_BIAS_PDN_SHIFT, 1, NULL, 0),
0376 SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS53L30_MICBIAS_CTL,
0377 CS53L30_MIC2_BIAS_PDN_SHIFT, 1, NULL, 0),
0378 SND_SOC_DAPM_SUPPLY("MIC3 Bias", CS53L30_MICBIAS_CTL,
0379 CS53L30_MIC3_BIAS_PDN_SHIFT, 1, NULL, 0),
0380 SND_SOC_DAPM_SUPPLY("MIC4 Bias", CS53L30_MICBIAS_CTL,
0381 CS53L30_MIC4_BIAS_PDN_SHIFT, 1, NULL, 0),
0382
0383 SND_SOC_DAPM_AIF_OUT("ASP_SDOUT1", NULL, 0, CS53L30_ASP_CTL1,
0384 CS53L30_ASP_SDOUTx_PDN_SHIFT, 1),
0385 SND_SOC_DAPM_AIF_OUT("ASP_SDOUT2", NULL, 0, CS53L30_ASP_CTL2,
0386 CS53L30_ASP_SDOUTx_PDN_SHIFT, 1),
0387
0388 SND_SOC_DAPM_MUX("Input Mux 1", SND_SOC_NOPM, 0, 0,
0389 &input1_route_sel_mux),
0390 SND_SOC_DAPM_MUX("Input Mux 2", SND_SOC_NOPM, 0, 0,
0391 &input2_route_sel_mux),
0392
0393 SND_SOC_DAPM_ADC("ADC1A", NULL, CS53L30_ADCDMIC1_CTL1,
0394 CS53L30_ADCxA_PDN_SHIFT, 1),
0395 SND_SOC_DAPM_ADC("ADC1B", NULL, CS53L30_ADCDMIC1_CTL1,
0396 CS53L30_ADCxB_PDN_SHIFT, 1),
0397 SND_SOC_DAPM_ADC("ADC2A", NULL, CS53L30_ADCDMIC2_CTL1,
0398 CS53L30_ADCxA_PDN_SHIFT, 1),
0399 SND_SOC_DAPM_ADC("ADC2B", NULL, CS53L30_ADCDMIC2_CTL1,
0400 CS53L30_ADCxB_PDN_SHIFT, 1),
0401 SND_SOC_DAPM_ADC("DMIC1", NULL, CS53L30_ADCDMIC1_CTL1,
0402 CS53L30_DMICx_PDN_SHIFT, 1),
0403 SND_SOC_DAPM_ADC("DMIC2", NULL, CS53L30_ADCDMIC2_CTL1,
0404 CS53L30_DMICx_PDN_SHIFT, 1),
0405 };
0406
0407 static const struct snd_soc_dapm_route cs53l30_dapm_routes[] = {
0408
0409 {"ADC1A", NULL, "IN1_DMIC1"},
0410 {"Input Mux 1", "ADC1_SEL", "ADC1A"},
0411 {"ADC1B", NULL, "IN2"},
0412
0413 {"ADC2A", NULL, "IN3_DMIC2"},
0414 {"Input Mux 2", "ADC2_SEL", "ADC2A"},
0415 {"ADC2B", NULL, "IN4"},
0416
0417
0418 {"ADC1A", NULL, "MIC1 Bias"},
0419 {"ADC1B", NULL, "MIC2 Bias"},
0420 {"ADC2A", NULL, "MIC3 Bias"},
0421 {"ADC2B", NULL, "MIC4 Bias"},
0422
0423
0424 {"DMIC1", NULL, "IN1_DMIC1"},
0425 {"Input Mux 1", "DMIC1_SEL", "DMIC1"},
0426
0427 {"DMIC2", NULL, "IN3_DMIC2"},
0428 {"Input Mux 2", "DMIC2_SEL", "DMIC2"},
0429 };
0430
0431 static const struct snd_soc_dapm_route cs53l30_dapm_routes_sdout1[] = {
0432
0433 {"ASP_SDOUT1", NULL, "ADC1A" },
0434 {"ASP_SDOUT1", NULL, "Input Mux 1"},
0435 {"ASP_SDOUT1", NULL, "ADC1B"},
0436
0437 {"ASP_SDOUT1", NULL, "ADC2A"},
0438 {"ASP_SDOUT1", NULL, "Input Mux 2"},
0439 {"ASP_SDOUT1", NULL, "ADC2B"},
0440
0441 {"Capture", NULL, "ASP_SDOUT1"},
0442 };
0443
0444 static const struct snd_soc_dapm_route cs53l30_dapm_routes_sdout2[] = {
0445
0446 {"ASP_SDOUT1", NULL, "ADC1A" },
0447 {"ASP_SDOUT1", NULL, "Input Mux 1"},
0448 {"ASP_SDOUT1", NULL, "ADC1B"},
0449
0450 {"ASP_SDOUT2", NULL, "ADC2A"},
0451 {"ASP_SDOUT2", NULL, "Input Mux 2"},
0452 {"ASP_SDOUT2", NULL, "ADC2B"},
0453
0454 {"Capture", NULL, "ASP_SDOUT1"},
0455 {"Capture", NULL, "ASP_SDOUT2"},
0456 };
0457
0458 struct cs53l30_mclk_div {
0459 u32 mclk_rate;
0460 u32 srate;
0461 u8 asp_rate;
0462 u8 internal_fs_ratio;
0463 u8 mclk_int_scale;
0464 };
0465
0466 static const struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
0467
0468
0469
0470 {5644800, 11025, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0471 {5644800, 22050, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0472 {5644800, 44100, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0473
0474 {6000000, 8000, 0x1, 0, CS53L30_MCLK_INT_SCALE},
0475 {6000000, 11025, 0x2, 0, CS53L30_MCLK_INT_SCALE},
0476 {6000000, 12000, 0x4, 0, CS53L30_MCLK_INT_SCALE},
0477 {6000000, 16000, 0x5, 0, CS53L30_MCLK_INT_SCALE},
0478 {6000000, 22050, 0x6, 0, CS53L30_MCLK_INT_SCALE},
0479 {6000000, 24000, 0x8, 0, CS53L30_MCLK_INT_SCALE},
0480 {6000000, 32000, 0x9, 0, CS53L30_MCLK_INT_SCALE},
0481 {6000000, 44100, 0xA, 0, CS53L30_MCLK_INT_SCALE},
0482 {6000000, 48000, 0xC, 0, CS53L30_MCLK_INT_SCALE},
0483
0484 {6144000, 8000, 0x1, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0485 {6144000, 11025, 0x2, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0486 {6144000, 12000, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0487 {6144000, 16000, 0x5, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0488 {6144000, 22050, 0x6, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0489 {6144000, 24000, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0490 {6144000, 32000, 0x9, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0491 {6144000, 44100, 0xA, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0492 {6144000, 48000, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0493
0494 {6400000, 8000, 0x1, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0495 {6400000, 11025, 0x2, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0496 {6400000, 12000, 0x4, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0497 {6400000, 16000, 0x5, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0498 {6400000, 22050, 0x6, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0499 {6400000, 24000, 0x8, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0500 {6400000, 32000, 0x9, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0501 {6400000, 44100, 0xA, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0502 {6400000, 48000, 0xC, CS53L30_INTRNL_FS_RATIO, CS53L30_MCLK_INT_SCALE},
0503 };
0504
0505 struct cs53l30_mclkx_div {
0506 u32 mclkx;
0507 u8 ratio;
0508 u8 mclkdiv;
0509 };
0510
0511 static const struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
0512 {5644800, 1, CS53L30_MCLK_DIV_BY_1},
0513 {6000000, 1, CS53L30_MCLK_DIV_BY_1},
0514 {6144000, 1, CS53L30_MCLK_DIV_BY_1},
0515 {11289600, 2, CS53L30_MCLK_DIV_BY_2},
0516 {12288000, 2, CS53L30_MCLK_DIV_BY_2},
0517 {12000000, 2, CS53L30_MCLK_DIV_BY_2},
0518 {19200000, 3, CS53L30_MCLK_DIV_BY_3},
0519 };
0520
0521 static int cs53l30_get_mclkx_coeff(int mclkx)
0522 {
0523 int i;
0524
0525 for (i = 0; i < ARRAY_SIZE(cs53l30_mclkx_coeffs); i++) {
0526 if (cs53l30_mclkx_coeffs[i].mclkx == mclkx)
0527 return i;
0528 }
0529
0530 return -EINVAL;
0531 }
0532
0533 static int cs53l30_get_mclk_coeff(int mclk_rate, int srate)
0534 {
0535 int i;
0536
0537 for (i = 0; i < ARRAY_SIZE(cs53l30_mclk_coeffs); i++) {
0538 if (cs53l30_mclk_coeffs[i].mclk_rate == mclk_rate &&
0539 cs53l30_mclk_coeffs[i].srate == srate)
0540 return i;
0541 }
0542
0543 return -EINVAL;
0544 }
0545
0546 static int cs53l30_set_sysclk(struct snd_soc_dai *dai,
0547 int clk_id, unsigned int freq, int dir)
0548 {
0549 struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
0550 int mclkx_coeff;
0551 u32 mclk_rate;
0552
0553
0554 mclkx_coeff = cs53l30_get_mclkx_coeff(freq);
0555 if (mclkx_coeff < 0)
0556 return mclkx_coeff;
0557
0558 mclk_rate = cs53l30_mclkx_coeffs[mclkx_coeff].mclkx /
0559 cs53l30_mclkx_coeffs[mclkx_coeff].ratio;
0560
0561 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
0562 CS53L30_MCLK_DIV_MASK,
0563 cs53l30_mclkx_coeffs[mclkx_coeff].mclkdiv);
0564
0565 priv->mclk_rate = mclk_rate;
0566
0567 return 0;
0568 }
0569
0570 static int cs53l30_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0571 {
0572 struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
0573 u8 aspcfg = 0, aspctl1 = 0;
0574
0575 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0576 case SND_SOC_DAIFMT_CBM_CFM:
0577 aspcfg |= CS53L30_ASP_MS;
0578 break;
0579 case SND_SOC_DAIFMT_CBS_CFS:
0580 break;
0581 default:
0582 return -EINVAL;
0583 }
0584
0585
0586 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0587 case SND_SOC_DAIFMT_I2S:
0588
0589 aspctl1 |= CS53L30_ASP_TDM_PDN;
0590 break;
0591 case SND_SOC_DAIFMT_DSP_A:
0592
0593
0594
0595
0596
0597 aspctl1 |= CS53L30_SHIFT_LEFT;
0598 break;
0599 default:
0600 return -EINVAL;
0601 }
0602
0603
0604 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0605 case SND_SOC_DAIFMT_IB_NF:
0606 case SND_SOC_DAIFMT_IB_IF:
0607 aspcfg ^= CS53L30_ASP_SCLK_INV;
0608 break;
0609 default:
0610 break;
0611 }
0612
0613 regmap_update_bits(priv->regmap, CS53L30_ASPCFG_CTL,
0614 CS53L30_ASP_MS | CS53L30_ASP_SCLK_INV, aspcfg);
0615
0616 regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1,
0617 CS53L30_ASP_TDM_PDN | CS53L30_SHIFT_LEFT, aspctl1);
0618
0619 return 0;
0620 }
0621
0622 static int cs53l30_pcm_hw_params(struct snd_pcm_substream *substream,
0623 struct snd_pcm_hw_params *params,
0624 struct snd_soc_dai *dai)
0625 {
0626 struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
0627 int srate = params_rate(params);
0628 int mclk_coeff;
0629
0630
0631 mclk_coeff = cs53l30_get_mclk_coeff(priv->mclk_rate, srate);
0632 if (mclk_coeff < 0)
0633 return -EINVAL;
0634
0635 regmap_update_bits(priv->regmap, CS53L30_INT_SR_CTL,
0636 CS53L30_INTRNL_FS_RATIO_MASK,
0637 cs53l30_mclk_coeffs[mclk_coeff].internal_fs_ratio);
0638
0639 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
0640 CS53L30_MCLK_INT_SCALE_MASK,
0641 cs53l30_mclk_coeffs[mclk_coeff].mclk_int_scale);
0642
0643 regmap_update_bits(priv->regmap, CS53L30_ASPCFG_CTL,
0644 CS53L30_ASP_RATE_MASK,
0645 cs53l30_mclk_coeffs[mclk_coeff].asp_rate);
0646
0647 return 0;
0648 }
0649
0650 static int cs53l30_set_bias_level(struct snd_soc_component *component,
0651 enum snd_soc_bias_level level)
0652 {
0653 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0654 struct cs53l30_private *priv = snd_soc_component_get_drvdata(component);
0655 unsigned int reg;
0656 int i, inter_max_check, ret;
0657
0658 switch (level) {
0659 case SND_SOC_BIAS_ON:
0660 break;
0661 case SND_SOC_BIAS_PREPARE:
0662 if (dapm->bias_level == SND_SOC_BIAS_STANDBY)
0663 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
0664 CS53L30_PDN_LP_MASK, 0);
0665 break;
0666 case SND_SOC_BIAS_STANDBY:
0667 if (dapm->bias_level == SND_SOC_BIAS_OFF) {
0668 ret = clk_prepare_enable(priv->mclk);
0669 if (ret) {
0670 dev_err(component->dev,
0671 "failed to enable MCLK: %d\n", ret);
0672 return ret;
0673 }
0674 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
0675 CS53L30_MCLK_DIS_MASK, 0);
0676 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
0677 CS53L30_PDN_ULP_MASK, 0);
0678 msleep(50);
0679 } else {
0680 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
0681 CS53L30_PDN_ULP_MASK,
0682 CS53L30_PDN_ULP);
0683 }
0684 break;
0685 case SND_SOC_BIAS_OFF:
0686 regmap_update_bits(priv->regmap, CS53L30_INT_MASK,
0687 CS53L30_PDN_DONE, 0);
0688
0689
0690
0691
0692
0693
0694
0695 regmap_read(priv->regmap, CS53L30_SFT_RAMP, ®);
0696 if (reg & CS53L30_DIGSFT_MASK)
0697 inter_max_check = CS53L30_PDN_POLL_MAX;
0698 else
0699 inter_max_check = 10;
0700
0701 regmap_update_bits(priv->regmap, CS53L30_PWRCTL,
0702 CS53L30_PDN_ULP_MASK,
0703 CS53L30_PDN_ULP);
0704
0705 msleep(20);
0706
0707 regmap_read(priv->regmap, CS53L30_IS, ®);
0708 for (i = 0; i < inter_max_check; i++) {
0709 if (inter_max_check < 10) {
0710 usleep_range(1000, 1100);
0711 regmap_read(priv->regmap, CS53L30_IS, ®);
0712 if (reg & CS53L30_PDN_DONE)
0713 break;
0714 } else {
0715 usleep_range(10000, 10100);
0716 regmap_read(priv->regmap, CS53L30_IS, ®);
0717 if (reg & CS53L30_PDN_DONE)
0718 break;
0719 }
0720 }
0721
0722 regmap_update_bits(priv->regmap, CS53L30_INT_MASK,
0723 CS53L30_PDN_DONE, CS53L30_PDN_DONE);
0724 regmap_update_bits(priv->regmap, CS53L30_MCLKCTL,
0725 CS53L30_MCLK_DIS_MASK,
0726 CS53L30_MCLK_DIS);
0727 clk_disable_unprepare(priv->mclk);
0728 break;
0729 }
0730
0731 return 0;
0732 }
0733
0734 static int cs53l30_set_tristate(struct snd_soc_dai *dai, int tristate)
0735 {
0736 struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
0737 u8 val = tristate ? CS53L30_ASP_3ST : 0;
0738
0739 return regmap_update_bits(priv->regmap, CS53L30_ASP_CTL1,
0740 CS53L30_ASP_3ST_MASK, val);
0741 }
0742
0743 static unsigned int const cs53l30_src_rates[] = {
0744 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
0745 };
0746
0747 static const struct snd_pcm_hw_constraint_list src_constraints = {
0748 .count = ARRAY_SIZE(cs53l30_src_rates),
0749 .list = cs53l30_src_rates,
0750 };
0751
0752 static int cs53l30_pcm_startup(struct snd_pcm_substream *substream,
0753 struct snd_soc_dai *dai)
0754 {
0755 snd_pcm_hw_constraint_list(substream->runtime, 0,
0756 SNDRV_PCM_HW_PARAM_RATE, &src_constraints);
0757
0758 return 0;
0759 }
0760
0761
0762
0763
0764
0765
0766 static int cs53l30_set_dai_tdm_slot(struct snd_soc_dai *dai,
0767 unsigned int tx_mask, unsigned int rx_mask,
0768 int slots, int slot_width)
0769 {
0770 struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
0771 unsigned int loc[CS53L30_TDM_SLOT_MAX] = {48, 48, 48, 48};
0772 unsigned int slot_next, slot_step;
0773 u64 tx_enable = 0;
0774 int i;
0775
0776 if (!rx_mask) {
0777 dev_err(dai->dev, "rx masks must not be 0\n");
0778 return -EINVAL;
0779 }
0780
0781
0782 if (slots <= 0 || slot_width <= 0 || slot_width > 64) {
0783 dev_err(dai->dev, "invalid slot number or slot width\n");
0784 return -EINVAL;
0785 }
0786
0787 if (slot_width & 0x7) {
0788 dev_err(dai->dev, "slot width must count in byte\n");
0789 return -EINVAL;
0790 }
0791
0792
0793 slot_step = slot_width >> 3;
0794
0795 for (i = 0; rx_mask && i < CS53L30_TDM_SLOT_MAX; i++) {
0796
0797 slot_next = __ffs(rx_mask);
0798
0799 loc[i] = slot_next * slot_step;
0800
0801 tx_enable |= (u64)((u64)(1 << slot_step) - 1) << (u64)loc[i];
0802
0803 rx_mask &= ~(1 << slot_next);
0804 }
0805
0806
0807 if (rx_mask && i == CS53L30_TDM_SLOT_MAX) {
0808 dev_err(dai->dev, "rx_mask exceeds max slot number: %d\n",
0809 CS53L30_TDM_SLOT_MAX);
0810 return -EINVAL;
0811 }
0812
0813
0814 slot_next = loc[i - 1] + slot_step - 1;
0815 if (slot_next > 47) {
0816 dev_err(dai->dev, "slot selection out of bounds: %u\n",
0817 slot_next);
0818 return -EINVAL;
0819 }
0820
0821 for (i = 0; i < CS53L30_TDM_SLOT_MAX && loc[i] != 48; i++) {
0822 regmap_update_bits(priv->regmap, CS53L30_ASP_TDMTX_CTL(i),
0823 CS53L30_ASP_CHx_TX_LOC_MASK, loc[i]);
0824 dev_dbg(dai->dev, "loc[%d]=%x\n", i, loc[i]);
0825 }
0826
0827 for (i = 0; i < CS53L30_ASP_TDMTX_ENx_MAX && tx_enable; i++) {
0828 regmap_write(priv->regmap, CS53L30_ASP_TDMTX_ENx(i),
0829 tx_enable & 0xff);
0830 tx_enable >>= 8;
0831 dev_dbg(dai->dev, "en_reg=%x, tx_enable=%llx\n",
0832 CS53L30_ASP_TDMTX_ENx(i), tx_enable & 0xff);
0833 }
0834
0835 return 0;
0836 }
0837
0838 static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
0839 {
0840 struct cs53l30_private *priv = snd_soc_component_get_drvdata(dai->component);
0841
0842 gpiod_set_value_cansleep(priv->mute_gpio, mute);
0843
0844 return 0;
0845 }
0846
0847
0848 #define CS53L30_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT)
0849
0850 #define CS53L30_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0851 SNDRV_PCM_FMTBIT_S24_LE)
0852
0853 static const struct snd_soc_dai_ops cs53l30_ops = {
0854 .startup = cs53l30_pcm_startup,
0855 .hw_params = cs53l30_pcm_hw_params,
0856 .set_fmt = cs53l30_set_dai_fmt,
0857 .set_sysclk = cs53l30_set_sysclk,
0858 .set_tristate = cs53l30_set_tristate,
0859 .set_tdm_slot = cs53l30_set_dai_tdm_slot,
0860 .mute_stream = cs53l30_mute_stream,
0861 };
0862
0863 static struct snd_soc_dai_driver cs53l30_dai = {
0864 .name = "cs53l30",
0865 .capture = {
0866 .stream_name = "Capture",
0867 .channels_min = 1,
0868 .channels_max = 4,
0869 .rates = CS53L30_RATES,
0870 .formats = CS53L30_FORMATS,
0871 },
0872 .ops = &cs53l30_ops,
0873 .symmetric_rate = 1,
0874 };
0875
0876 static int cs53l30_component_probe(struct snd_soc_component *component)
0877 {
0878 struct cs53l30_private *priv = snd_soc_component_get_drvdata(component);
0879 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0880
0881 if (priv->use_sdout2)
0882 snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout2,
0883 ARRAY_SIZE(cs53l30_dapm_routes_sdout2));
0884 else
0885 snd_soc_dapm_add_routes(dapm, cs53l30_dapm_routes_sdout1,
0886 ARRAY_SIZE(cs53l30_dapm_routes_sdout1));
0887
0888 return 0;
0889 }
0890
0891 static const struct snd_soc_component_driver cs53l30_driver = {
0892 .probe = cs53l30_component_probe,
0893 .set_bias_level = cs53l30_set_bias_level,
0894 .controls = cs53l30_snd_controls,
0895 .num_controls = ARRAY_SIZE(cs53l30_snd_controls),
0896 .dapm_widgets = cs53l30_dapm_widgets,
0897 .num_dapm_widgets = ARRAY_SIZE(cs53l30_dapm_widgets),
0898 .dapm_routes = cs53l30_dapm_routes,
0899 .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes),
0900 .use_pmdown_time = 1,
0901 .endianness = 1,
0902 };
0903
0904 static struct regmap_config cs53l30_regmap = {
0905 .reg_bits = 8,
0906 .val_bits = 8,
0907
0908 .max_register = CS53L30_MAX_REGISTER,
0909 .reg_defaults = cs53l30_reg_defaults,
0910 .num_reg_defaults = ARRAY_SIZE(cs53l30_reg_defaults),
0911 .volatile_reg = cs53l30_volatile_register,
0912 .writeable_reg = cs53l30_writeable_register,
0913 .readable_reg = cs53l30_readable_register,
0914 .cache_type = REGCACHE_RBTREE,
0915
0916 .use_single_read = true,
0917 .use_single_write = true,
0918 };
0919
0920 static int cs53l30_i2c_probe(struct i2c_client *client)
0921 {
0922 const struct device_node *np = client->dev.of_node;
0923 struct device *dev = &client->dev;
0924 struct cs53l30_private *cs53l30;
0925 unsigned int reg;
0926 int ret = 0, i, devid;
0927 u8 val;
0928
0929 cs53l30 = devm_kzalloc(dev, sizeof(*cs53l30), GFP_KERNEL);
0930 if (!cs53l30)
0931 return -ENOMEM;
0932
0933 for (i = 0; i < ARRAY_SIZE(cs53l30->supplies); i++)
0934 cs53l30->supplies[i].supply = cs53l30_supply_names[i];
0935
0936 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs53l30->supplies),
0937 cs53l30->supplies);
0938 if (ret) {
0939 dev_err(dev, "failed to get supplies: %d\n", ret);
0940 return ret;
0941 }
0942
0943 ret = regulator_bulk_enable(ARRAY_SIZE(cs53l30->supplies),
0944 cs53l30->supplies);
0945 if (ret) {
0946 dev_err(dev, "failed to enable supplies: %d\n", ret);
0947 return ret;
0948 }
0949
0950
0951 cs53l30->reset_gpio = devm_gpiod_get_optional(dev, "reset",
0952 GPIOD_OUT_LOW);
0953 if (IS_ERR(cs53l30->reset_gpio)) {
0954 ret = PTR_ERR(cs53l30->reset_gpio);
0955 goto error_supplies;
0956 }
0957
0958 gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
0959
0960 i2c_set_clientdata(client, cs53l30);
0961
0962 cs53l30->mclk_rate = 0;
0963
0964 cs53l30->regmap = devm_regmap_init_i2c(client, &cs53l30_regmap);
0965 if (IS_ERR(cs53l30->regmap)) {
0966 ret = PTR_ERR(cs53l30->regmap);
0967 dev_err(dev, "regmap_init() failed: %d\n", ret);
0968 goto error;
0969 }
0970
0971
0972 devid = cirrus_read_device_id(cs53l30->regmap, CS53L30_DEVID_AB);
0973 if (devid < 0) {
0974 ret = devid;
0975 dev_err(dev, "Failed to read device ID: %d\n", ret);
0976 goto error;
0977 }
0978
0979 if (devid != CS53L30_DEVID) {
0980 ret = -ENODEV;
0981 dev_err(dev, "Device ID (%X). Expected %X\n",
0982 devid, CS53L30_DEVID);
0983 goto error;
0984 }
0985
0986 ret = regmap_read(cs53l30->regmap, CS53L30_REVID, ®);
0987 if (ret < 0) {
0988 dev_err(dev, "failed to get Revision ID: %d\n", ret);
0989 goto error;
0990 }
0991
0992
0993 cs53l30->mclk = devm_clk_get(dev, "mclk");
0994 if (IS_ERR(cs53l30->mclk)) {
0995 if (PTR_ERR(cs53l30->mclk) != -ENOENT) {
0996 ret = PTR_ERR(cs53l30->mclk);
0997 goto error;
0998 }
0999
1000 cs53l30->mclk = NULL;
1001 }
1002
1003
1004 cs53l30->mute_gpio = devm_gpiod_get_optional(dev, "mute",
1005 GPIOD_OUT_HIGH);
1006 if (IS_ERR(cs53l30->mute_gpio)) {
1007 ret = PTR_ERR(cs53l30->mute_gpio);
1008 goto error;
1009 }
1010
1011 if (cs53l30->mute_gpio) {
1012
1013 regmap_write(cs53l30->regmap, CS53L30_MUTEP_CTL1,
1014 CS53L30_MUTEP_CTL1_MUTEALL);
1015
1016 if (gpiod_is_active_low(cs53l30->mute_gpio))
1017 regmap_update_bits(cs53l30->regmap, CS53L30_MUTEP_CTL2,
1018 CS53L30_MUTE_PIN_POLARITY, 0);
1019 }
1020
1021 if (!of_property_read_u8(np, "cirrus,micbias-lvl", &val))
1022 regmap_update_bits(cs53l30->regmap, CS53L30_MICBIAS_CTL,
1023 CS53L30_MIC_BIAS_CTRL_MASK, val);
1024
1025 if (of_property_read_bool(np, "cirrus,use-sdout2"))
1026 cs53l30->use_sdout2 = true;
1027
1028 dev_info(dev, "Cirrus Logic CS53L30, Revision: %02X\n", reg & 0xFF);
1029
1030 ret = devm_snd_soc_register_component(dev, &cs53l30_driver, &cs53l30_dai, 1);
1031 if (ret) {
1032 dev_err(dev, "failed to register component: %d\n", ret);
1033 goto error;
1034 }
1035
1036 return 0;
1037
1038 error:
1039 gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
1040 error_supplies:
1041 regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
1042 cs53l30->supplies);
1043 return ret;
1044 }
1045
1046 static int cs53l30_i2c_remove(struct i2c_client *client)
1047 {
1048 struct cs53l30_private *cs53l30 = i2c_get_clientdata(client);
1049
1050
1051 gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
1052
1053 regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
1054 cs53l30->supplies);
1055
1056 return 0;
1057 }
1058
1059 #ifdef CONFIG_PM
1060 static int cs53l30_runtime_suspend(struct device *dev)
1061 {
1062 struct cs53l30_private *cs53l30 = dev_get_drvdata(dev);
1063
1064 regcache_cache_only(cs53l30->regmap, true);
1065
1066
1067 gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
1068
1069 regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
1070 cs53l30->supplies);
1071
1072 return 0;
1073 }
1074
1075 static int cs53l30_runtime_resume(struct device *dev)
1076 {
1077 struct cs53l30_private *cs53l30 = dev_get_drvdata(dev);
1078 int ret;
1079
1080 ret = regulator_bulk_enable(ARRAY_SIZE(cs53l30->supplies),
1081 cs53l30->supplies);
1082 if (ret) {
1083 dev_err(dev, "failed to enable supplies: %d\n", ret);
1084 return ret;
1085 }
1086
1087 gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
1088
1089 regcache_cache_only(cs53l30->regmap, false);
1090 ret = regcache_sync(cs53l30->regmap);
1091 if (ret) {
1092 dev_err(dev, "failed to synchronize regcache: %d\n", ret);
1093 return ret;
1094 }
1095
1096 return 0;
1097 }
1098 #endif
1099
1100 static const struct dev_pm_ops cs53l30_runtime_pm = {
1101 SET_RUNTIME_PM_OPS(cs53l30_runtime_suspend, cs53l30_runtime_resume,
1102 NULL)
1103 };
1104
1105 static const struct of_device_id cs53l30_of_match[] = {
1106 { .compatible = "cirrus,cs53l30", },
1107 {},
1108 };
1109
1110 MODULE_DEVICE_TABLE(of, cs53l30_of_match);
1111
1112 static const struct i2c_device_id cs53l30_id[] = {
1113 { "cs53l30", 0 },
1114 {}
1115 };
1116
1117 MODULE_DEVICE_TABLE(i2c, cs53l30_id);
1118
1119 static struct i2c_driver cs53l30_i2c_driver = {
1120 .driver = {
1121 .name = "cs53l30",
1122 .of_match_table = cs53l30_of_match,
1123 .pm = &cs53l30_runtime_pm,
1124 },
1125 .id_table = cs53l30_id,
1126 .probe_new = cs53l30_i2c_probe,
1127 .remove = cs53l30_i2c_remove,
1128 };
1129
1130 module_i2c_driver(cs53l30_i2c_driver);
1131
1132 MODULE_DESCRIPTION("ASoC CS53L30 driver");
1133 MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <Paul.Handrigan@cirrus.com>");
1134 MODULE_LICENSE("GPL");