0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <linux/delay.h>
0016 #include <linux/gpio.h>
0017 #include <linux/of.h>
0018 #include <linux/of_device.h>
0019 #include <linux/of_gpio.h>
0020 #include <linux/regulator/consumer.h>
0021 #include <sound/pcm.h>
0022 #include <sound/soc.h>
0023 #include <sound/tlv.h>
0024 #include <sound/cs4271.h>
0025 #include "cs4271.h"
0026
0027 #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
0028 SNDRV_PCM_FMTBIT_S24_LE | \
0029 SNDRV_PCM_FMTBIT_S32_LE)
0030 #define CS4271_PCM_RATES SNDRV_PCM_RATE_8000_192000
0031
0032
0033
0034
0035 #define CS4271_MODE1 0x01
0036 #define CS4271_DACCTL 0x02
0037 #define CS4271_DACVOL 0x03
0038 #define CS4271_VOLA 0x04
0039 #define CS4271_VOLB 0x05
0040 #define CS4271_ADCCTL 0x06
0041 #define CS4271_MODE2 0x07
0042 #define CS4271_CHIPID 0x08
0043
0044 #define CS4271_FIRSTREG CS4271_MODE1
0045 #define CS4271_LASTREG CS4271_MODE2
0046 #define CS4271_NR_REGS ((CS4271_LASTREG & 0xFF) + 1)
0047
0048
0049 #define CS4271_MODE1_MODE_MASK 0xC0
0050 #define CS4271_MODE1_MODE_1X 0x00
0051 #define CS4271_MODE1_MODE_2X 0x80
0052 #define CS4271_MODE1_MODE_4X 0xC0
0053
0054 #define CS4271_MODE1_DIV_MASK 0x30
0055 #define CS4271_MODE1_DIV_1 0x00
0056 #define CS4271_MODE1_DIV_15 0x10
0057 #define CS4271_MODE1_DIV_2 0x20
0058 #define CS4271_MODE1_DIV_3 0x30
0059
0060 #define CS4271_MODE1_MASTER 0x08
0061
0062 #define CS4271_MODE1_DAC_DIF_MASK 0x07
0063 #define CS4271_MODE1_DAC_DIF_LJ 0x00
0064 #define CS4271_MODE1_DAC_DIF_I2S 0x01
0065 #define CS4271_MODE1_DAC_DIF_RJ16 0x02
0066 #define CS4271_MODE1_DAC_DIF_RJ24 0x03
0067 #define CS4271_MODE1_DAC_DIF_RJ20 0x04
0068 #define CS4271_MODE1_DAC_DIF_RJ18 0x05
0069
0070 #define CS4271_DACCTL_AMUTE 0x80
0071 #define CS4271_DACCTL_IF_SLOW 0x40
0072
0073 #define CS4271_DACCTL_DEM_MASK 0x30
0074 #define CS4271_DACCTL_DEM_DIS 0x00
0075 #define CS4271_DACCTL_DEM_441 0x10
0076 #define CS4271_DACCTL_DEM_48 0x20
0077 #define CS4271_DACCTL_DEM_32 0x30
0078
0079 #define CS4271_DACCTL_SVRU 0x08
0080 #define CS4271_DACCTL_SRD 0x04
0081 #define CS4271_DACCTL_INVA 0x02
0082 #define CS4271_DACCTL_INVB 0x01
0083
0084 #define CS4271_DACVOL_BEQUA 0x40
0085 #define CS4271_DACVOL_SOFT 0x20
0086 #define CS4271_DACVOL_ZEROC 0x10
0087
0088 #define CS4271_DACVOL_ATAPI_MASK 0x0F
0089 #define CS4271_DACVOL_ATAPI_M_M 0x00
0090 #define CS4271_DACVOL_ATAPI_M_BR 0x01
0091 #define CS4271_DACVOL_ATAPI_M_BL 0x02
0092 #define CS4271_DACVOL_ATAPI_M_BLR2 0x03
0093 #define CS4271_DACVOL_ATAPI_AR_M 0x04
0094 #define CS4271_DACVOL_ATAPI_AR_BR 0x05
0095 #define CS4271_DACVOL_ATAPI_AR_BL 0x06
0096 #define CS4271_DACVOL_ATAPI_AR_BLR2 0x07
0097 #define CS4271_DACVOL_ATAPI_AL_M 0x08
0098 #define CS4271_DACVOL_ATAPI_AL_BR 0x09
0099 #define CS4271_DACVOL_ATAPI_AL_BL 0x0A
0100 #define CS4271_DACVOL_ATAPI_AL_BLR2 0x0B
0101 #define CS4271_DACVOL_ATAPI_ALR2_M 0x0C
0102 #define CS4271_DACVOL_ATAPI_ALR2_BR 0x0D
0103 #define CS4271_DACVOL_ATAPI_ALR2_BL 0x0E
0104 #define CS4271_DACVOL_ATAPI_ALR2_BLR2 0x0F
0105
0106 #define CS4271_VOLA_MUTE 0x80
0107 #define CS4271_VOLA_VOL_MASK 0x7F
0108 #define CS4271_VOLB_MUTE 0x80
0109 #define CS4271_VOLB_VOL_MASK 0x7F
0110
0111 #define CS4271_ADCCTL_DITHER16 0x20
0112
0113 #define CS4271_ADCCTL_ADC_DIF_MASK 0x10
0114 #define CS4271_ADCCTL_ADC_DIF_LJ 0x00
0115 #define CS4271_ADCCTL_ADC_DIF_I2S 0x10
0116
0117 #define CS4271_ADCCTL_MUTEA 0x08
0118 #define CS4271_ADCCTL_MUTEB 0x04
0119 #define CS4271_ADCCTL_HPFDA 0x02
0120 #define CS4271_ADCCTL_HPFDB 0x01
0121
0122 #define CS4271_MODE2_LOOP 0x10
0123 #define CS4271_MODE2_MUTECAEQUB 0x08
0124 #define CS4271_MODE2_FREEZE 0x04
0125 #define CS4271_MODE2_CPEN 0x02
0126 #define CS4271_MODE2_PDN 0x01
0127
0128 #define CS4271_CHIPID_PART_MASK 0xF0
0129 #define CS4271_CHIPID_REV_MASK 0x0F
0130
0131
0132
0133
0134
0135
0136
0137 static const struct reg_default cs4271_reg_defaults[] = {
0138 { CS4271_MODE1, 0, },
0139 { CS4271_DACCTL, CS4271_DACCTL_AMUTE, },
0140 { CS4271_DACVOL, CS4271_DACVOL_SOFT | CS4271_DACVOL_ATAPI_AL_BR, },
0141 { CS4271_VOLA, 0, },
0142 { CS4271_VOLB, 0, },
0143 { CS4271_ADCCTL, 0, },
0144 { CS4271_MODE2, 0, },
0145 };
0146
0147 static bool cs4271_volatile_reg(struct device *dev, unsigned int reg)
0148 {
0149 return reg == CS4271_CHIPID;
0150 }
0151
0152 static const char * const supply_names[] = {
0153 "vd", "vl", "va"
0154 };
0155
0156 struct cs4271_private {
0157 unsigned int mclk;
0158 bool master;
0159 bool deemph;
0160 struct regmap *regmap;
0161
0162 int rate;
0163
0164 int gpio_nreset;
0165
0166 int gpio_disable;
0167
0168 bool enable_soft_reset;
0169 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
0170 };
0171
0172 static const struct snd_soc_dapm_widget cs4271_dapm_widgets[] = {
0173 SND_SOC_DAPM_INPUT("AINA"),
0174 SND_SOC_DAPM_INPUT("AINB"),
0175
0176 SND_SOC_DAPM_OUTPUT("AOUTA+"),
0177 SND_SOC_DAPM_OUTPUT("AOUTA-"),
0178 SND_SOC_DAPM_OUTPUT("AOUTB+"),
0179 SND_SOC_DAPM_OUTPUT("AOUTB-"),
0180 };
0181
0182 static const struct snd_soc_dapm_route cs4271_dapm_routes[] = {
0183 { "Capture", NULL, "AINA" },
0184 { "Capture", NULL, "AINB" },
0185
0186 { "AOUTA+", NULL, "Playback" },
0187 { "AOUTA-", NULL, "Playback" },
0188 { "AOUTB+", NULL, "Playback" },
0189 { "AOUTB-", NULL, "Playback" },
0190 };
0191
0192
0193
0194
0195
0196
0197 static int cs4271_set_dai_sysclk(struct snd_soc_dai *codec_dai,
0198 int clk_id, unsigned int freq, int dir)
0199 {
0200 struct snd_soc_component *component = codec_dai->component;
0201 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0202
0203 cs4271->mclk = freq;
0204 return 0;
0205 }
0206
0207 static int cs4271_set_dai_fmt(struct snd_soc_dai *codec_dai,
0208 unsigned int format)
0209 {
0210 struct snd_soc_component *component = codec_dai->component;
0211 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0212 unsigned int val = 0;
0213 int ret;
0214
0215 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
0216 case SND_SOC_DAIFMT_CBS_CFS:
0217 cs4271->master = false;
0218 break;
0219 case SND_SOC_DAIFMT_CBM_CFM:
0220 cs4271->master = true;
0221 val |= CS4271_MODE1_MASTER;
0222 break;
0223 default:
0224 dev_err(component->dev, "Invalid DAI format\n");
0225 return -EINVAL;
0226 }
0227
0228 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
0229 case SND_SOC_DAIFMT_LEFT_J:
0230 val |= CS4271_MODE1_DAC_DIF_LJ;
0231 ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
0232 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_LJ);
0233 if (ret < 0)
0234 return ret;
0235 break;
0236 case SND_SOC_DAIFMT_I2S:
0237 val |= CS4271_MODE1_DAC_DIF_I2S;
0238 ret = regmap_update_bits(cs4271->regmap, CS4271_ADCCTL,
0239 CS4271_ADCCTL_ADC_DIF_MASK, CS4271_ADCCTL_ADC_DIF_I2S);
0240 if (ret < 0)
0241 return ret;
0242 break;
0243 default:
0244 dev_err(component->dev, "Invalid DAI format\n");
0245 return -EINVAL;
0246 }
0247
0248 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1,
0249 CS4271_MODE1_DAC_DIF_MASK | CS4271_MODE1_MASTER, val);
0250 if (ret < 0)
0251 return ret;
0252 return 0;
0253 }
0254
0255 static int cs4271_deemph[] = {0, 44100, 48000, 32000};
0256
0257 static int cs4271_set_deemph(struct snd_soc_component *component)
0258 {
0259 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0260 int i, ret;
0261 int val = CS4271_DACCTL_DEM_DIS;
0262
0263 if (cs4271->deemph) {
0264
0265 val = 1;
0266 for (i = 2; i < ARRAY_SIZE(cs4271_deemph); i++)
0267 if (abs(cs4271_deemph[i] - cs4271->rate) <
0268 abs(cs4271_deemph[val] - cs4271->rate))
0269 val = i;
0270 val <<= 4;
0271 }
0272
0273 ret = regmap_update_bits(cs4271->regmap, CS4271_DACCTL,
0274 CS4271_DACCTL_DEM_MASK, val);
0275 if (ret < 0)
0276 return ret;
0277 return 0;
0278 }
0279
0280 static int cs4271_get_deemph(struct snd_kcontrol *kcontrol,
0281 struct snd_ctl_elem_value *ucontrol)
0282 {
0283 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0284 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0285
0286 ucontrol->value.integer.value[0] = cs4271->deemph;
0287 return 0;
0288 }
0289
0290 static int cs4271_put_deemph(struct snd_kcontrol *kcontrol,
0291 struct snd_ctl_elem_value *ucontrol)
0292 {
0293 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0294 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0295
0296 cs4271->deemph = ucontrol->value.integer.value[0];
0297 return cs4271_set_deemph(component);
0298 }
0299
0300 struct cs4271_clk_cfg {
0301 bool master;
0302 u8 speed_mode;
0303 unsigned short ratio;
0304 u8 ratio_mask;
0305 };
0306
0307 static struct cs4271_clk_cfg cs4271_clk_tab[] = {
0308 {1, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
0309 {1, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_15},
0310 {1, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_2},
0311 {1, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_3},
0312 {1, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
0313 {1, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_15},
0314 {1, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_2},
0315 {1, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_3},
0316 {1, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
0317 {1, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_15},
0318 {1, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_2},
0319 {1, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_3},
0320 {0, CS4271_MODE1_MODE_1X, 256, CS4271_MODE1_DIV_1},
0321 {0, CS4271_MODE1_MODE_1X, 384, CS4271_MODE1_DIV_1},
0322 {0, CS4271_MODE1_MODE_1X, 512, CS4271_MODE1_DIV_1},
0323 {0, CS4271_MODE1_MODE_1X, 768, CS4271_MODE1_DIV_2},
0324 {0, CS4271_MODE1_MODE_1X, 1024, CS4271_MODE1_DIV_2},
0325 {0, CS4271_MODE1_MODE_2X, 128, CS4271_MODE1_DIV_1},
0326 {0, CS4271_MODE1_MODE_2X, 192, CS4271_MODE1_DIV_1},
0327 {0, CS4271_MODE1_MODE_2X, 256, CS4271_MODE1_DIV_1},
0328 {0, CS4271_MODE1_MODE_2X, 384, CS4271_MODE1_DIV_2},
0329 {0, CS4271_MODE1_MODE_2X, 512, CS4271_MODE1_DIV_2},
0330 {0, CS4271_MODE1_MODE_4X, 64, CS4271_MODE1_DIV_1},
0331 {0, CS4271_MODE1_MODE_4X, 96, CS4271_MODE1_DIV_1},
0332 {0, CS4271_MODE1_MODE_4X, 128, CS4271_MODE1_DIV_1},
0333 {0, CS4271_MODE1_MODE_4X, 192, CS4271_MODE1_DIV_2},
0334 {0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
0335 };
0336
0337 #define CS4271_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
0338
0339 static int cs4271_hw_params(struct snd_pcm_substream *substream,
0340 struct snd_pcm_hw_params *params,
0341 struct snd_soc_dai *dai)
0342 {
0343 struct snd_soc_component *component = dai->component;
0344 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0345 int i, ret;
0346 unsigned int ratio, val;
0347
0348 if (cs4271->enable_soft_reset) {
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
0359 !snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) ||
0360 (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
0361 !snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK))) {
0362 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0363 CS4271_MODE2_PDN,
0364 CS4271_MODE2_PDN);
0365 if (ret < 0)
0366 return ret;
0367
0368 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0369 CS4271_MODE2_PDN, 0);
0370 if (ret < 0)
0371 return ret;
0372 }
0373 }
0374
0375 cs4271->rate = params_rate(params);
0376
0377
0378 if (cs4271->rate < 50000)
0379 val = CS4271_MODE1_MODE_1X;
0380 else if (cs4271->rate < 100000)
0381 val = CS4271_MODE1_MODE_2X;
0382 else
0383 val = CS4271_MODE1_MODE_4X;
0384
0385 ratio = cs4271->mclk / cs4271->rate;
0386 for (i = 0; i < CS4271_NR_RATIOS; i++)
0387 if ((cs4271_clk_tab[i].master == cs4271->master) &&
0388 (cs4271_clk_tab[i].speed_mode == val) &&
0389 (cs4271_clk_tab[i].ratio == ratio))
0390 break;
0391
0392 if (i == CS4271_NR_RATIOS) {
0393 dev_err(component->dev, "Invalid sample rate\n");
0394 return -EINVAL;
0395 }
0396
0397 val |= cs4271_clk_tab[i].ratio_mask;
0398
0399 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE1,
0400 CS4271_MODE1_MODE_MASK | CS4271_MODE1_DIV_MASK, val);
0401 if (ret < 0)
0402 return ret;
0403
0404 return cs4271_set_deemph(component);
0405 }
0406
0407 static int cs4271_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
0408 {
0409 struct snd_soc_component *component = dai->component;
0410 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0411 int ret;
0412 int val_a = 0;
0413 int val_b = 0;
0414
0415 if (stream != SNDRV_PCM_STREAM_PLAYBACK)
0416 return 0;
0417
0418 if (mute) {
0419 val_a = CS4271_VOLA_MUTE;
0420 val_b = CS4271_VOLB_MUTE;
0421 }
0422
0423 ret = regmap_update_bits(cs4271->regmap, CS4271_VOLA,
0424 CS4271_VOLA_MUTE, val_a);
0425 if (ret < 0)
0426 return ret;
0427
0428 ret = regmap_update_bits(cs4271->regmap, CS4271_VOLB,
0429 CS4271_VOLB_MUTE, val_b);
0430 if (ret < 0)
0431 return ret;
0432
0433 return 0;
0434 }
0435
0436
0437 static DECLARE_TLV_DB_SCALE(cs4271_dac_tlv, -12700, 100, 0);
0438
0439 static const struct snd_kcontrol_new cs4271_snd_controls[] = {
0440 SOC_DOUBLE_R_TLV("Master Playback Volume", CS4271_VOLA, CS4271_VOLB,
0441 0, 0x7F, 1, cs4271_dac_tlv),
0442 SOC_SINGLE("Digital Loopback Switch", CS4271_MODE2, 4, 1, 0),
0443 SOC_SINGLE("Soft Ramp Switch", CS4271_DACVOL, 5, 1, 0),
0444 SOC_SINGLE("Zero Cross Switch", CS4271_DACVOL, 4, 1, 0),
0445 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
0446 cs4271_get_deemph, cs4271_put_deemph),
0447 SOC_SINGLE("Auto-Mute Switch", CS4271_DACCTL, 7, 1, 0),
0448 SOC_SINGLE("Slow Roll Off Filter Switch", CS4271_DACCTL, 6, 1, 0),
0449 SOC_SINGLE("Soft Volume Ramp-Up Switch", CS4271_DACCTL, 3, 1, 0),
0450 SOC_SINGLE("Soft Ramp-Down Switch", CS4271_DACCTL, 2, 1, 0),
0451 SOC_SINGLE("Left Channel Inversion Switch", CS4271_DACCTL, 1, 1, 0),
0452 SOC_SINGLE("Right Channel Inversion Switch", CS4271_DACCTL, 0, 1, 0),
0453 SOC_DOUBLE("Master Capture Switch", CS4271_ADCCTL, 3, 2, 1, 1),
0454 SOC_SINGLE("Dither 16-Bit Data Switch", CS4271_ADCCTL, 5, 1, 0),
0455 SOC_DOUBLE("High Pass Filter Switch", CS4271_ADCCTL, 1, 0, 1, 1),
0456 SOC_DOUBLE_R("Master Playback Switch", CS4271_VOLA, CS4271_VOLB,
0457 7, 1, 1),
0458 };
0459
0460 static const struct snd_soc_dai_ops cs4271_dai_ops = {
0461 .hw_params = cs4271_hw_params,
0462 .set_sysclk = cs4271_set_dai_sysclk,
0463 .set_fmt = cs4271_set_dai_fmt,
0464 .mute_stream = cs4271_mute_stream,
0465 };
0466
0467 static struct snd_soc_dai_driver cs4271_dai = {
0468 .name = "cs4271-hifi",
0469 .playback = {
0470 .stream_name = "Playback",
0471 .channels_min = 2,
0472 .channels_max = 2,
0473 .rates = CS4271_PCM_RATES,
0474 .formats = CS4271_PCM_FORMATS,
0475 },
0476 .capture = {
0477 .stream_name = "Capture",
0478 .channels_min = 2,
0479 .channels_max = 2,
0480 .rates = CS4271_PCM_RATES,
0481 .formats = CS4271_PCM_FORMATS,
0482 },
0483 .ops = &cs4271_dai_ops,
0484 .symmetric_rate = 1,
0485 };
0486
0487 static int cs4271_reset(struct snd_soc_component *component)
0488 {
0489 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0490
0491 if (gpio_is_valid(cs4271->gpio_nreset)) {
0492 gpio_direction_output(cs4271->gpio_nreset, 0);
0493 mdelay(1);
0494 gpio_set_value(cs4271->gpio_nreset, 1);
0495 mdelay(1);
0496 }
0497
0498 return 0;
0499 }
0500
0501 #ifdef CONFIG_PM
0502 static int cs4271_soc_suspend(struct snd_soc_component *component)
0503 {
0504 int ret;
0505 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0506
0507
0508 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0509 CS4271_MODE2_PDN, CS4271_MODE2_PDN);
0510 if (ret < 0)
0511 return ret;
0512
0513 regcache_mark_dirty(cs4271->regmap);
0514 regulator_bulk_disable(ARRAY_SIZE(cs4271->supplies), cs4271->supplies);
0515
0516 return 0;
0517 }
0518
0519 static int cs4271_soc_resume(struct snd_soc_component *component)
0520 {
0521 int ret;
0522 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0523
0524 ret = regulator_bulk_enable(ARRAY_SIZE(cs4271->supplies),
0525 cs4271->supplies);
0526 if (ret < 0) {
0527 dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
0528 return ret;
0529 }
0530
0531
0532 cs4271_reset(component);
0533
0534
0535 ret = regcache_sync(cs4271->regmap);
0536 if (ret < 0)
0537 return ret;
0538
0539
0540 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0541 CS4271_MODE2_PDN, 0);
0542 if (ret < 0)
0543 return ret;
0544
0545 return 0;
0546 }
0547 #else
0548 #define cs4271_soc_suspend NULL
0549 #define cs4271_soc_resume NULL
0550 #endif
0551
0552 #ifdef CONFIG_OF
0553 const struct of_device_id cs4271_dt_ids[] = {
0554 { .compatible = "cirrus,cs4271", },
0555 { }
0556 };
0557 MODULE_DEVICE_TABLE(of, cs4271_dt_ids);
0558 EXPORT_SYMBOL_GPL(cs4271_dt_ids);
0559 #endif
0560
0561 static int cs4271_component_probe(struct snd_soc_component *component)
0562 {
0563 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0564 struct cs4271_platform_data *cs4271plat = component->dev->platform_data;
0565 int ret;
0566 bool amutec_eq_bmutec = false;
0567
0568 #ifdef CONFIG_OF
0569 if (of_match_device(cs4271_dt_ids, component->dev)) {
0570 if (of_get_property(component->dev->of_node,
0571 "cirrus,amutec-eq-bmutec", NULL))
0572 amutec_eq_bmutec = true;
0573
0574 if (of_get_property(component->dev->of_node,
0575 "cirrus,enable-soft-reset", NULL))
0576 cs4271->enable_soft_reset = true;
0577 }
0578 #endif
0579
0580 ret = regulator_bulk_enable(ARRAY_SIZE(cs4271->supplies),
0581 cs4271->supplies);
0582 if (ret < 0) {
0583 dev_err(component->dev, "Failed to enable regulators: %d\n", ret);
0584 return ret;
0585 }
0586
0587 if (cs4271plat) {
0588 amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec;
0589 cs4271->enable_soft_reset = cs4271plat->enable_soft_reset;
0590 }
0591
0592
0593 cs4271_reset(component);
0594
0595 ret = regcache_sync(cs4271->regmap);
0596 if (ret < 0)
0597 return ret;
0598
0599 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0600 CS4271_MODE2_PDN | CS4271_MODE2_CPEN,
0601 CS4271_MODE2_PDN | CS4271_MODE2_CPEN);
0602 if (ret < 0)
0603 return ret;
0604 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0605 CS4271_MODE2_PDN, 0);
0606 if (ret < 0)
0607 return ret;
0608
0609 udelay(85);
0610
0611 if (amutec_eq_bmutec)
0612 regmap_update_bits(cs4271->regmap, CS4271_MODE2,
0613 CS4271_MODE2_MUTECAEQUB,
0614 CS4271_MODE2_MUTECAEQUB);
0615
0616 return 0;
0617 }
0618
0619 static void cs4271_component_remove(struct snd_soc_component *component)
0620 {
0621 struct cs4271_private *cs4271 = snd_soc_component_get_drvdata(component);
0622
0623 if (gpio_is_valid(cs4271->gpio_nreset))
0624
0625 gpio_set_value(cs4271->gpio_nreset, 0);
0626
0627 regcache_mark_dirty(cs4271->regmap);
0628 regulator_bulk_disable(ARRAY_SIZE(cs4271->supplies), cs4271->supplies);
0629 };
0630
0631 static const struct snd_soc_component_driver soc_component_dev_cs4271 = {
0632 .probe = cs4271_component_probe,
0633 .remove = cs4271_component_remove,
0634 .suspend = cs4271_soc_suspend,
0635 .resume = cs4271_soc_resume,
0636 .controls = cs4271_snd_controls,
0637 .num_controls = ARRAY_SIZE(cs4271_snd_controls),
0638 .dapm_widgets = cs4271_dapm_widgets,
0639 .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets),
0640 .dapm_routes = cs4271_dapm_routes,
0641 .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes),
0642 .idle_bias_on = 1,
0643 .use_pmdown_time = 1,
0644 .endianness = 1,
0645 };
0646
0647 static int cs4271_common_probe(struct device *dev,
0648 struct cs4271_private **c)
0649 {
0650 struct cs4271_platform_data *cs4271plat = dev->platform_data;
0651 struct cs4271_private *cs4271;
0652 int i, ret;
0653
0654 cs4271 = devm_kzalloc(dev, sizeof(*cs4271), GFP_KERNEL);
0655 if (!cs4271)
0656 return -ENOMEM;
0657
0658 if (of_match_device(cs4271_dt_ids, dev))
0659 cs4271->gpio_nreset =
0660 of_get_named_gpio(dev->of_node, "reset-gpio", 0);
0661
0662 if (cs4271plat)
0663 cs4271->gpio_nreset = cs4271plat->gpio_nreset;
0664
0665 if (gpio_is_valid(cs4271->gpio_nreset)) {
0666 ret = devm_gpio_request(dev, cs4271->gpio_nreset,
0667 "CS4271 Reset");
0668 if (ret < 0)
0669 return ret;
0670 }
0671
0672 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
0673 cs4271->supplies[i].supply = supply_names[i];
0674
0675 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs4271->supplies),
0676 cs4271->supplies);
0677
0678 if (ret < 0) {
0679 dev_err(dev, "Failed to get regulators: %d\n", ret);
0680 return ret;
0681 }
0682
0683 *c = cs4271;
0684 return 0;
0685 }
0686
0687 const struct regmap_config cs4271_regmap_config = {
0688 .max_register = CS4271_LASTREG,
0689
0690 .reg_defaults = cs4271_reg_defaults,
0691 .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults),
0692 .cache_type = REGCACHE_RBTREE,
0693
0694 .volatile_reg = cs4271_volatile_reg,
0695 };
0696 EXPORT_SYMBOL_GPL(cs4271_regmap_config);
0697
0698 int cs4271_probe(struct device *dev, struct regmap *regmap)
0699 {
0700 struct cs4271_private *cs4271;
0701 int ret;
0702
0703 if (IS_ERR(regmap))
0704 return PTR_ERR(regmap);
0705
0706 ret = cs4271_common_probe(dev, &cs4271);
0707 if (ret < 0)
0708 return ret;
0709
0710 dev_set_drvdata(dev, cs4271);
0711 cs4271->regmap = regmap;
0712
0713 return devm_snd_soc_register_component(dev, &soc_component_dev_cs4271,
0714 &cs4271_dai, 1);
0715 }
0716 EXPORT_SYMBOL_GPL(cs4271_probe);
0717
0718 MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>");
0719 MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
0720 MODULE_LICENSE("GPL");