1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * PCM1681 ASoC codec driver 4 * 5 * Copyright (c) StreamUnlimited GmbH 2013 6 * Marek Belisko <marek.belisko@streamunlimited.com> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/slab.h> 11 #include <linux/delay.h> 12 #include <linux/i2c.h> 13 #include <linux/regmap.h> 14 #include <linux/of.h> 15 #include <sound/pcm.h> 16 #include <sound/pcm_params.h> 17 #include <sound/soc.h> 18 #include <sound/tlv.h> 19 20 #define PCM1681_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 21 SNDRV_PCM_FMTBIT_S24_LE) 22 23 #define PCM1681_PCM_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \ 24 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 25 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \ 26 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) 27 28 #define PCM1681_SOFT_MUTE_ALL 0xff 29 #define PCM1681_DEEMPH_RATE_MASK 0x18 30 #define PCM1681_DEEMPH_MASK 0x01 31 32 #define PCM1681_ATT_CONTROL(X) (X <= 6 ? X : X + 9) /* Attenuation level */ 33 #define PCM1681_SOFT_MUTE 0x07 /* Soft mute control register */ 34 #define PCM1681_DAC_CONTROL 0x08 /* DAC operation control */ 35 #define PCM1681_FMT_CONTROL 0x09 /* Audio interface data format */ 36 #define PCM1681_DEEMPH_CONTROL 0x0a /* De-emphasis control */ 37 #define PCM1681_ZERO_DETECT_STATUS 0x0e /* Zero detect status reg */ 38 39 static const struct reg_default pcm1681_reg_defaults[] = { 40 { 0x01, 0xff }, 41 { 0x02, 0xff }, 42 { 0x03, 0xff }, 43 { 0x04, 0xff }, 44 { 0x05, 0xff }, 45 { 0x06, 0xff }, 46 { 0x07, 0x00 }, 47 { 0x08, 0x00 }, 48 { 0x09, 0x06 }, 49 { 0x0A, 0x00 }, 50 { 0x0B, 0xff }, 51 { 0x0C, 0x0f }, 52 { 0x0D, 0x00 }, 53 { 0x10, 0xff }, 54 { 0x11, 0xff }, 55 { 0x12, 0x00 }, 56 { 0x13, 0x00 }, 57 }; 58 59 static bool pcm1681_accessible_reg(struct device *dev, unsigned int reg) 60 { 61 return !((reg == 0x00) || (reg == 0x0f)); 62 } 63 64 static bool pcm1681_writeable_reg(struct device *dev, unsigned int reg) 65 { 66 return pcm1681_accessible_reg(dev, reg) && 67 (reg != PCM1681_ZERO_DETECT_STATUS); 68 } 69 70 struct pcm1681_private { 71 struct regmap *regmap; 72 unsigned int format; 73 /* Current deemphasis status */ 74 unsigned int deemph; 75 /* Current rate for deemphasis control */ 76 unsigned int rate; 77 }; 78 79 static const int pcm1681_deemph[] = { 44100, 48000, 32000 }; 80 81 static int pcm1681_set_deemph(struct snd_soc_component *component) 82 { 83 struct pcm1681_private *priv = snd_soc_component_get_drvdata(component); 84 int i, val = -1, enable = 0; 85 86 if (priv->deemph) { 87 for (i = 0; i < ARRAY_SIZE(pcm1681_deemph); i++) { 88 if (pcm1681_deemph[i] == priv->rate) { 89 val = i; 90 break; 91 } 92 } 93 } 94 95 if (val != -1) { 96 regmap_update_bits(priv->regmap, PCM1681_DEEMPH_CONTROL, 97 PCM1681_DEEMPH_RATE_MASK, val << 3); 98 enable = 1; 99 } else { 100 enable = 0; 101 } 102 103 /* enable/disable deemphasis functionality */ 104 return regmap_update_bits(priv->regmap, PCM1681_DEEMPH_CONTROL, 105 PCM1681_DEEMPH_MASK, enable); 106 } 107 108 static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, 109 struct snd_ctl_elem_value *ucontrol) 110 { 111 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 112 struct pcm1681_private *priv = snd_soc_component_get_drvdata(component); 113 114 ucontrol->value.integer.value[0] = priv->deemph; 115 116 return 0; 117 } 118 119 static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, 120 struct snd_ctl_elem_value *ucontrol) 121 { 122 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 123 struct pcm1681_private *priv = snd_soc_component_get_drvdata(component); 124 125 priv->deemph = ucontrol->value.integer.value[0]; 126 127 return pcm1681_set_deemph(component); 128 } 129 130 static int pcm1681_set_dai_fmt(struct snd_soc_dai *codec_dai, 131 unsigned int format) 132 { 133 struct snd_soc_component *component = codec_dai->component; 134 struct pcm1681_private *priv = snd_soc_component_get_drvdata(component); 135 136 /* The PCM1681 can only be consumer to all clocks */ 137 if ((format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { 138 dev_err(component->dev, "Invalid clocking mode\n"); 139 return -EINVAL; 140 } 141 142 priv->format = format; 143 144 return 0; 145 } 146 147 static int pcm1681_mute(struct snd_soc_dai *dai, int mute, int direction) 148 { 149 struct snd_soc_component *component = dai->component; 150 struct pcm1681_private *priv = snd_soc_component_get_drvdata(component); 151 int val; 152 153 if (mute) 154 val = PCM1681_SOFT_MUTE_ALL; 155 else 156 val = 0; 157 158 return regmap_write(priv->regmap, PCM1681_SOFT_MUTE, val); 159 } 160 161 static int pcm1681_hw_params(struct snd_pcm_substream *substream, 162 struct snd_pcm_hw_params *params, 163 struct snd_soc_dai *dai) 164 { 165 struct snd_soc_component *component = dai->component; 166 struct pcm1681_private *priv = snd_soc_component_get_drvdata(component); 167 int val = 0, ret; 168 169 priv->rate = params_rate(params); 170 171 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { 172 case SND_SOC_DAIFMT_RIGHT_J: 173 switch (params_width(params)) { 174 case 24: 175 val = 0; 176 break; 177 case 16: 178 val = 3; 179 break; 180 default: 181 return -EINVAL; 182 } 183 break; 184 case SND_SOC_DAIFMT_I2S: 185 val = 0x04; 186 break; 187 case SND_SOC_DAIFMT_LEFT_J: 188 val = 0x05; 189 break; 190 default: 191 dev_err(component->dev, "Invalid DAI format\n"); 192 return -EINVAL; 193 } 194 195 ret = regmap_update_bits(priv->regmap, PCM1681_FMT_CONTROL, 0x0f, val); 196 if (ret < 0) 197 return ret; 198 199 return pcm1681_set_deemph(component); 200 } 201 202 static const struct snd_soc_dai_ops pcm1681_dai_ops = { 203 .set_fmt = pcm1681_set_dai_fmt, 204 .hw_params = pcm1681_hw_params, 205 .mute_stream = pcm1681_mute, 206 .no_capture_mute = 1, 207 }; 208 209 static const struct snd_soc_dapm_widget pcm1681_dapm_widgets[] = { 210 SND_SOC_DAPM_OUTPUT("VOUT1"), 211 SND_SOC_DAPM_OUTPUT("VOUT2"), 212 SND_SOC_DAPM_OUTPUT("VOUT3"), 213 SND_SOC_DAPM_OUTPUT("VOUT4"), 214 SND_SOC_DAPM_OUTPUT("VOUT5"), 215 SND_SOC_DAPM_OUTPUT("VOUT6"), 216 SND_SOC_DAPM_OUTPUT("VOUT7"), 217 SND_SOC_DAPM_OUTPUT("VOUT8"), 218 }; 219 220 static const struct snd_soc_dapm_route pcm1681_dapm_routes[] = { 221 { "VOUT1", NULL, "Playback" }, 222 { "VOUT2", NULL, "Playback" }, 223 { "VOUT3", NULL, "Playback" }, 224 { "VOUT4", NULL, "Playback" }, 225 { "VOUT5", NULL, "Playback" }, 226 { "VOUT6", NULL, "Playback" }, 227 { "VOUT7", NULL, "Playback" }, 228 { "VOUT8", NULL, "Playback" }, 229 }; 230 231 static const DECLARE_TLV_DB_SCALE(pcm1681_dac_tlv, -6350, 50, 1); 232 233 static const struct snd_kcontrol_new pcm1681_controls[] = { 234 SOC_DOUBLE_R_TLV("Channel 1/2 Playback Volume", 235 PCM1681_ATT_CONTROL(1), PCM1681_ATT_CONTROL(2), 0, 236 0x7f, 0, pcm1681_dac_tlv), 237 SOC_DOUBLE_R_TLV("Channel 3/4 Playback Volume", 238 PCM1681_ATT_CONTROL(3), PCM1681_ATT_CONTROL(4), 0, 239 0x7f, 0, pcm1681_dac_tlv), 240 SOC_DOUBLE_R_TLV("Channel 5/6 Playback Volume", 241 PCM1681_ATT_CONTROL(5), PCM1681_ATT_CONTROL(6), 0, 242 0x7f, 0, pcm1681_dac_tlv), 243 SOC_DOUBLE_R_TLV("Channel 7/8 Playback Volume", 244 PCM1681_ATT_CONTROL(7), PCM1681_ATT_CONTROL(8), 0, 245 0x7f, 0, pcm1681_dac_tlv), 246 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0, 247 pcm1681_get_deemph, pcm1681_put_deemph), 248 }; 249 250 static struct snd_soc_dai_driver pcm1681_dai = { 251 .name = "pcm1681-hifi", 252 .playback = { 253 .stream_name = "Playback", 254 .channels_min = 2, 255 .channels_max = 8, 256 .rates = PCM1681_PCM_RATES, 257 .formats = PCM1681_PCM_FORMATS, 258 }, 259 .ops = &pcm1681_dai_ops, 260 }; 261 262 #ifdef CONFIG_OF 263 static const struct of_device_id pcm1681_dt_ids[] = { 264 { .compatible = "ti,pcm1681", }, 265 { } 266 }; 267 MODULE_DEVICE_TABLE(of, pcm1681_dt_ids); 268 #endif 269 270 static const struct regmap_config pcm1681_regmap = { 271 .reg_bits = 8, 272 .val_bits = 8, 273 .max_register = 0x13, 274 .reg_defaults = pcm1681_reg_defaults, 275 .num_reg_defaults = ARRAY_SIZE(pcm1681_reg_defaults), 276 .writeable_reg = pcm1681_writeable_reg, 277 .readable_reg = pcm1681_accessible_reg, 278 }; 279 280 static const struct snd_soc_component_driver soc_component_dev_pcm1681 = { 281 .controls = pcm1681_controls, 282 .num_controls = ARRAY_SIZE(pcm1681_controls), 283 .dapm_widgets = pcm1681_dapm_widgets, 284 .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets), 285 .dapm_routes = pcm1681_dapm_routes, 286 .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes), 287 .idle_bias_on = 1, 288 .use_pmdown_time = 1, 289 .endianness = 1, 290 }; 291 292 static const struct i2c_device_id pcm1681_i2c_id[] = { 293 {"pcm1681"}, 294 {} 295 }; 296 MODULE_DEVICE_TABLE(i2c, pcm1681_i2c_id); 297 298 static int pcm1681_i2c_probe(struct i2c_client *client) 299 { 300 int ret; 301 struct pcm1681_private *priv; 302 303 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); 304 if (!priv) 305 return -ENOMEM; 306 307 priv->regmap = devm_regmap_init_i2c(client, &pcm1681_regmap); 308 if (IS_ERR(priv->regmap)) { 309 ret = PTR_ERR(priv->regmap); 310 dev_err(&client->dev, "Failed to create regmap: %d\n", ret); 311 return ret; 312 } 313 314 i2c_set_clientdata(client, priv); 315 316 return devm_snd_soc_register_component(&client->dev, 317 &soc_component_dev_pcm1681, 318 &pcm1681_dai, 1); 319 } 320 321 static struct i2c_driver pcm1681_i2c_driver = { 322 .driver = { 323 .name = "pcm1681", 324 .of_match_table = of_match_ptr(pcm1681_dt_ids), 325 }, 326 .id_table = pcm1681_i2c_id, 327 .probe = pcm1681_i2c_probe, 328 }; 329 330 module_i2c_driver(pcm1681_i2c_driver); 331 332 MODULE_DESCRIPTION("Texas Instruments PCM1681 ALSA SoC Codec Driver"); 333 MODULE_AUTHOR("Marek Belisko <marek.belisko@streamunlimited.com>"); 334 MODULE_LICENSE("GPL"); 335