0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <sound/pcm_params.h>
0009 #include <sound/soc.h>
0010 #include <sound/tlv.h>
0011
0012 #include "pcm3060.h"
0013
0014
0015
0016 static int pcm3060_set_sysclk(struct snd_soc_dai *dai, int clk_id,
0017 unsigned int freq, int dir)
0018 {
0019 struct snd_soc_component *comp = dai->component;
0020 struct pcm3060_priv *priv = snd_soc_component_get_drvdata(comp);
0021 unsigned int reg;
0022 unsigned int val;
0023
0024 if (dir != SND_SOC_CLOCK_IN) {
0025 dev_err(comp->dev, "unsupported sysclock dir: %d\n", dir);
0026 return -EINVAL;
0027 }
0028
0029 switch (clk_id) {
0030 case PCM3060_CLK_DEF:
0031 val = 0;
0032 break;
0033
0034 case PCM3060_CLK1:
0035 val = (dai->id == PCM3060_DAI_ID_DAC ? PCM3060_REG_CSEL : 0);
0036 break;
0037
0038 case PCM3060_CLK2:
0039 val = (dai->id == PCM3060_DAI_ID_DAC ? 0 : PCM3060_REG_CSEL);
0040 break;
0041
0042 default:
0043 dev_err(comp->dev, "unsupported sysclock id: %d\n", clk_id);
0044 return -EINVAL;
0045 }
0046
0047 if (dai->id == PCM3060_DAI_ID_DAC)
0048 reg = PCM3060_REG67;
0049 else
0050 reg = PCM3060_REG72;
0051
0052 regmap_update_bits(priv->regmap, reg, PCM3060_REG_CSEL, val);
0053
0054 priv->dai[dai->id].sclk_freq = freq;
0055
0056 return 0;
0057 }
0058
0059 static int pcm3060_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0060 {
0061 struct snd_soc_component *comp = dai->component;
0062 struct pcm3060_priv *priv = snd_soc_component_get_drvdata(comp);
0063 unsigned int reg;
0064 unsigned int val;
0065
0066 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
0067 dev_err(comp->dev, "unsupported DAI polarity: 0x%x\n", fmt);
0068 return -EINVAL;
0069 }
0070
0071 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0072 case SND_SOC_DAIFMT_CBP_CFP:
0073 priv->dai[dai->id].is_provider = true;
0074 break;
0075 case SND_SOC_DAIFMT_CBC_CFC:
0076 priv->dai[dai->id].is_provider = false;
0077 break;
0078 default:
0079 dev_err(comp->dev, "unsupported DAI mode: 0x%x\n", fmt);
0080 return -EINVAL;
0081 }
0082
0083 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0084 case SND_SOC_DAIFMT_I2S:
0085 val = PCM3060_REG_FMT_I2S;
0086 break;
0087 case SND_SOC_DAIFMT_RIGHT_J:
0088 val = PCM3060_REG_FMT_RJ;
0089 break;
0090 case SND_SOC_DAIFMT_LEFT_J:
0091 val = PCM3060_REG_FMT_LJ;
0092 break;
0093 default:
0094 dev_err(comp->dev, "unsupported DAI format: 0x%x\n", fmt);
0095 return -EINVAL;
0096 }
0097
0098 if (dai->id == PCM3060_DAI_ID_DAC)
0099 reg = PCM3060_REG67;
0100 else
0101 reg = PCM3060_REG72;
0102
0103 regmap_update_bits(priv->regmap, reg, PCM3060_REG_MASK_FMT, val);
0104
0105 return 0;
0106 }
0107
0108 static int pcm3060_hw_params(struct snd_pcm_substream *substream,
0109 struct snd_pcm_hw_params *params,
0110 struct snd_soc_dai *dai)
0111 {
0112 struct snd_soc_component *comp = dai->component;
0113 struct pcm3060_priv *priv = snd_soc_component_get_drvdata(comp);
0114 unsigned int rate;
0115 unsigned int ratio;
0116 unsigned int reg;
0117 unsigned int val;
0118
0119 if (!priv->dai[dai->id].is_provider) {
0120 val = PCM3060_REG_MS_S;
0121 goto val_ready;
0122 }
0123
0124 rate = params_rate(params);
0125 if (!rate) {
0126 dev_err(comp->dev, "rate is not configured\n");
0127 return -EINVAL;
0128 }
0129
0130 ratio = priv->dai[dai->id].sclk_freq / rate;
0131
0132 switch (ratio) {
0133 case 768:
0134 val = PCM3060_REG_MS_M768;
0135 break;
0136 case 512:
0137 val = PCM3060_REG_MS_M512;
0138 break;
0139 case 384:
0140 val = PCM3060_REG_MS_M384;
0141 break;
0142 case 256:
0143 val = PCM3060_REG_MS_M256;
0144 break;
0145 case 192:
0146 val = PCM3060_REG_MS_M192;
0147 break;
0148 case 128:
0149 val = PCM3060_REG_MS_M128;
0150 break;
0151 default:
0152 dev_err(comp->dev, "unsupported ratio: %d\n", ratio);
0153 return -EINVAL;
0154 }
0155
0156 val_ready:
0157 if (dai->id == PCM3060_DAI_ID_DAC)
0158 reg = PCM3060_REG67;
0159 else
0160 reg = PCM3060_REG72;
0161
0162 regmap_update_bits(priv->regmap, reg, PCM3060_REG_MASK_MS, val);
0163
0164 return 0;
0165 }
0166
0167 static const struct snd_soc_dai_ops pcm3060_dai_ops = {
0168 .set_sysclk = pcm3060_set_sysclk,
0169 .set_fmt = pcm3060_set_fmt,
0170 .hw_params = pcm3060_hw_params,
0171 };
0172
0173 #define PCM3060_DAI_RATES_ADC (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 | \
0174 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
0175 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
0176
0177 #define PCM3060_DAI_RATES_DAC (PCM3060_DAI_RATES_ADC | \
0178 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
0179
0180 static struct snd_soc_dai_driver pcm3060_dai[] = {
0181 {
0182 .name = "pcm3060-dac",
0183 .id = PCM3060_DAI_ID_DAC,
0184 .playback = {
0185 .stream_name = "Playback",
0186 .channels_min = 2,
0187 .channels_max = 2,
0188 .rates = PCM3060_DAI_RATES_DAC,
0189 .formats = SNDRV_PCM_FMTBIT_S24_LE,
0190 },
0191 .ops = &pcm3060_dai_ops,
0192 },
0193 {
0194 .name = "pcm3060-adc",
0195 .id = PCM3060_DAI_ID_ADC,
0196 .capture = {
0197 .stream_name = "Capture",
0198 .channels_min = 2,
0199 .channels_max = 2,
0200 .rates = PCM3060_DAI_RATES_ADC,
0201 .formats = SNDRV_PCM_FMTBIT_S24_LE,
0202 },
0203 .ops = &pcm3060_dai_ops,
0204 },
0205 };
0206
0207
0208
0209 static DECLARE_TLV_DB_SCALE(pcm3060_dapm_tlv, -10050, 50, 1);
0210
0211 static const struct snd_kcontrol_new pcm3060_dapm_controls[] = {
0212 SOC_DOUBLE_R_RANGE_TLV("Master Playback Volume",
0213 PCM3060_REG65, PCM3060_REG66, 0,
0214 PCM3060_REG_AT2_MIN, PCM3060_REG_AT2_MAX,
0215 0, pcm3060_dapm_tlv),
0216 SOC_DOUBLE("Master Playback Switch", PCM3060_REG68,
0217 PCM3060_REG_SHIFT_MUT21, PCM3060_REG_SHIFT_MUT22, 1, 1),
0218
0219 SOC_DOUBLE_R_RANGE_TLV("Master Capture Volume",
0220 PCM3060_REG70, PCM3060_REG71, 0,
0221 PCM3060_REG_AT1_MIN, PCM3060_REG_AT1_MAX,
0222 0, pcm3060_dapm_tlv),
0223 SOC_DOUBLE("Master Capture Switch", PCM3060_REG73,
0224 PCM3060_REG_SHIFT_MUT11, PCM3060_REG_SHIFT_MUT12, 1, 1),
0225 };
0226
0227 static const struct snd_soc_dapm_widget pcm3060_dapm_widgets[] = {
0228 SND_SOC_DAPM_DAC("DAC", "Playback", PCM3060_REG64,
0229 PCM3060_REG_SHIFT_DAPSV, 1),
0230
0231 SND_SOC_DAPM_OUTPUT("OUTL"),
0232 SND_SOC_DAPM_OUTPUT("OUTR"),
0233
0234 SND_SOC_DAPM_INPUT("INL"),
0235 SND_SOC_DAPM_INPUT("INR"),
0236
0237 SND_SOC_DAPM_ADC("ADC", "Capture", PCM3060_REG64,
0238 PCM3060_REG_SHIFT_ADPSV, 1),
0239 };
0240
0241 static const struct snd_soc_dapm_route pcm3060_dapm_map[] = {
0242 { "OUTL", NULL, "DAC" },
0243 { "OUTR", NULL, "DAC" },
0244
0245 { "ADC", NULL, "INL" },
0246 { "ADC", NULL, "INR" },
0247 };
0248
0249
0250
0251 static const struct snd_soc_component_driver pcm3060_soc_comp_driver = {
0252 .controls = pcm3060_dapm_controls,
0253 .num_controls = ARRAY_SIZE(pcm3060_dapm_controls),
0254 .dapm_widgets = pcm3060_dapm_widgets,
0255 .num_dapm_widgets = ARRAY_SIZE(pcm3060_dapm_widgets),
0256 .dapm_routes = pcm3060_dapm_map,
0257 .num_dapm_routes = ARRAY_SIZE(pcm3060_dapm_map),
0258 .endianness = 1,
0259 };
0260
0261
0262
0263 static bool pcm3060_reg_writeable(struct device *dev, unsigned int reg)
0264 {
0265 return (reg >= PCM3060_REG64);
0266 }
0267
0268 static bool pcm3060_reg_readable(struct device *dev, unsigned int reg)
0269 {
0270 return (reg >= PCM3060_REG64);
0271 }
0272
0273 static bool pcm3060_reg_volatile(struct device *dev, unsigned int reg)
0274 {
0275
0276 return (reg == PCM3060_REG64);
0277 }
0278
0279 static const struct reg_default pcm3060_reg_defaults[] = {
0280 { PCM3060_REG64, 0xF0 },
0281 { PCM3060_REG65, 0xFF },
0282 { PCM3060_REG66, 0xFF },
0283 { PCM3060_REG67, 0x00 },
0284 { PCM3060_REG68, 0x00 },
0285 { PCM3060_REG69, 0x00 },
0286 { PCM3060_REG70, 0xD7 },
0287 { PCM3060_REG71, 0xD7 },
0288 { PCM3060_REG72, 0x00 },
0289 { PCM3060_REG73, 0x00 },
0290 };
0291
0292 const struct regmap_config pcm3060_regmap = {
0293 .reg_bits = 8,
0294 .val_bits = 8,
0295 .writeable_reg = pcm3060_reg_writeable,
0296 .readable_reg = pcm3060_reg_readable,
0297 .volatile_reg = pcm3060_reg_volatile,
0298 .max_register = PCM3060_REG73,
0299 .reg_defaults = pcm3060_reg_defaults,
0300 .num_reg_defaults = ARRAY_SIZE(pcm3060_reg_defaults),
0301 .cache_type = REGCACHE_RBTREE,
0302 };
0303 EXPORT_SYMBOL(pcm3060_regmap);
0304
0305
0306
0307 static void pcm3060_parse_dt(const struct device_node *np,
0308 struct pcm3060_priv *priv)
0309 {
0310 priv->out_se = of_property_read_bool(np, "ti,out-single-ended");
0311 }
0312
0313 int pcm3060_probe(struct device *dev)
0314 {
0315 int rc;
0316 struct pcm3060_priv *priv = dev_get_drvdata(dev);
0317
0318
0319 rc = regmap_update_bits(priv->regmap, PCM3060_REG64,
0320 PCM3060_REG_MRST, 0);
0321 if (rc) {
0322 dev_err(dev, "failed to reset component, rc=%d\n", rc);
0323 return rc;
0324 }
0325
0326 if (dev->of_node)
0327 pcm3060_parse_dt(dev->of_node, priv);
0328
0329 if (priv->out_se)
0330 regmap_update_bits(priv->regmap, PCM3060_REG64,
0331 PCM3060_REG_SE, PCM3060_REG_SE);
0332
0333 rc = devm_snd_soc_register_component(dev, &pcm3060_soc_comp_driver,
0334 pcm3060_dai,
0335 ARRAY_SIZE(pcm3060_dai));
0336 if (rc) {
0337 dev_err(dev, "failed to register component, rc=%d\n", rc);
0338 return rc;
0339 }
0340
0341 return 0;
0342 }
0343 EXPORT_SYMBOL(pcm3060_probe);
0344
0345 MODULE_DESCRIPTION("PCM3060 codec driver");
0346 MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
0347 MODULE_LICENSE("GPL v2");