Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * CS4271 ASoC codec driver
0004  *
0005  * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru>
0006  *
0007  * This driver support CS4271 codec being master or slave, working
0008  * in control port mode, connected either via SPI or I2C.
0009  * The data format accepted is I2S or left-justified.
0010  * DAPM support not implemented.
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  * CS4271 registers
0034  */
0035 #define CS4271_MODE1    0x01    /* Mode Control 1 */
0036 #define CS4271_DACCTL   0x02    /* DAC Control */
0037 #define CS4271_DACVOL   0x03    /* DAC Volume & Mixing Control */
0038 #define CS4271_VOLA 0x04    /* DAC Channel A Volume Control */
0039 #define CS4271_VOLB 0x05    /* DAC Channel B Volume Control */
0040 #define CS4271_ADCCTL   0x06    /* ADC Control */
0041 #define CS4271_MODE2    0x07    /* Mode Control 2 */
0042 #define CS4271_CHIPID   0x08    /* Chip ID */
0043 
0044 #define CS4271_FIRSTREG CS4271_MODE1
0045 #define CS4271_LASTREG  CS4271_MODE2
0046 #define CS4271_NR_REGS  ((CS4271_LASTREG & 0xFF) + 1)
0047 
0048 /* Bit masks for the CS4271 registers */
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  * Default CS4271 power-up configuration
0133  * Array contains non-existing in hw register at address 0
0134  * Array do not include Chip ID, as codec driver does not use
0135  * registers read operations at all
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     /* Current sample rate for de-emphasis control */
0162     int             rate;
0163     /* GPIO driving Reset pin, if any */
0164     int             gpio_nreset;
0165     /* GPIO that disable serial bus, if any */
0166     int             gpio_disable;
0167     /* enable soft reset workaround */
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  * @freq is the desired MCLK rate
0194  * MCLK rate should (c) be the sample rate, multiplied by one of the
0195  * ratios listed in cs4271_mclk_fs_ratios table
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         /* Find closest de-emphasis freq */
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;     /* codec mode */
0302     u8      speed_mode; /* codec speed mode: 1x, 2x, 4x */
0303     unsigned short  ratio;      /* MCLK / sample rate */
0304     u8      ratio_mask; /* ratio bit mask for Master mode */
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          * Put the codec in soft reset and back again in case it's not
0351          * currently streaming data. This way of bringing the codec in
0352          * sync to the current clocks is not explicitly documented in
0353          * the data sheet, but it seems to work fine, and in contrast
0354          * to a read hardware reset, we don't have to sync back all
0355          * registers every time.
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     /* Configure DAC */
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 /* CS4271 controls */
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     /* Set power-down bit */
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     /* Do a proper reset after power up */
0532     cs4271_reset(component);
0533 
0534     /* Restore codec state */
0535     ret = regcache_sync(cs4271->regmap);
0536     if (ret < 0)
0537         return ret;
0538 
0539     /* then disable the power-down bit */
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 /* CONFIG_PM */
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     /* Reset codec */
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     /* Power-up sequence requires 85 uS */
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         /* Set codec to the reset state */
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");