1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // uda1342.c -- UDA1342 ALSA SoC Codec driver 4 // Based on the WM87xx drivers by Liam Girdwood and Richard Purdie 5 // 6 // Copyright 2007 Dension Audio Systems Ltd. 7 // Copyright 2024 Loongson Technology Co.,Ltd. 8 // 9 // Modifications by Christian Pellegrin <chripell@evolware.org> 10 // Further cleanup and restructuring by: 11 // Binbin Zhou <zhoubinbin@loongson.cn> 12 13 #include <linux/module.h> 14 #include <linux/i2c.h> 15 #include <sound/core.h> 16 #include <sound/pcm.h> 17 #include <sound/pcm_params.h> 18 #include <linux/pm_runtime.h> 19 #include <sound/soc.h> 20 #include <sound/tlv.h> 21 22 #include "uda1342.h" 23 24 #define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ 25 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE) 26 27 struct uda1342_priv { 28 int sysclk; 29 int dai_fmt; 30 31 struct snd_pcm_substream *provider_substream; 32 struct snd_pcm_substream *consumer_substream; 33 34 struct regmap *regmap; 35 struct i2c_client *i2c; 36 }; 37 38 static const struct reg_default uda1342_reg_defaults[] = { 39 { 0x00, 0x1042 }, 40 { 0x01, 0x0000 }, 41 { 0x10, 0x0088 }, 42 { 0x11, 0x0000 }, 43 { 0x12, 0x0000 }, 44 { 0x20, 0x0080 }, 45 { 0x21, 0x0080 }, 46 }; 47 48 static int uda1342_mute(struct snd_soc_dai *dai, int mute, int direction) 49 { 50 struct snd_soc_component *component = dai->component; 51 struct uda1342_priv *uda1342 = snd_soc_component_get_drvdata(component); 52 unsigned int mask; 53 unsigned int val = 0; 54 55 /* Master mute */ 56 mask = BIT(5); 57 if (mute) 58 val = mask; 59 60 return regmap_update_bits(uda1342->regmap, 0x10, mask, val); 61 } 62 63 static int uda1342_startup(struct snd_pcm_substream *substream, 64 struct snd_soc_dai *dai) 65 { 66 struct snd_soc_component *component = dai->component; 67 struct uda1342_priv *uda1342 = snd_soc_component_get_drvdata(component); 68 struct snd_pcm_runtime *provider_runtime; 69 70 if (uda1342->provider_substream) { 71 provider_runtime = uda1342->provider_substream->runtime; 72 73 snd_pcm_hw_constraint_single(substream->runtime, 74 SNDRV_PCM_HW_PARAM_RATE, provider_runtime->rate); 75 snd_pcm_hw_constraint_single(substream->runtime, 76 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 77 provider_runtime->sample_bits); 78 79 uda1342->consumer_substream = substream; 80 } else { 81 uda1342->provider_substream = substream; 82 } 83 84 return 0; 85 } 86 87 static void uda1342_shutdown(struct snd_pcm_substream *substream, 88 struct snd_soc_dai *dai) 89 { 90 struct snd_soc_component *component = dai->component; 91 struct uda1342_priv *uda1342 = snd_soc_component_get_drvdata(component); 92 93 if (uda1342->provider_substream == substream) 94 uda1342->provider_substream = uda1342->consumer_substream; 95 96 uda1342->consumer_substream = NULL; 97 } 98 99 static int uda1342_hw_params(struct snd_pcm_substream *substream, 100 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 101 { 102 struct snd_soc_component *component = dai->component; 103 struct uda1342_priv *uda1342 = snd_soc_component_get_drvdata(component); 104 struct device *dev = &uda1342->i2c->dev; 105 unsigned int hw_params = 0; 106 107 if (substream == uda1342->consumer_substream) 108 return 0; 109 110 /* set SYSCLK / fs ratio */ 111 switch (uda1342->sysclk / params_rate(params)) { 112 case 512: 113 break; 114 case 384: 115 hw_params |= BIT(4); 116 break; 117 case 256: 118 hw_params |= BIT(5); 119 break; 120 default: 121 dev_err(dev, "unsupported frequency\n"); 122 return -EINVAL; 123 } 124 125 /* set DAI format and word length */ 126 switch (uda1342->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 127 case SND_SOC_DAIFMT_I2S: 128 break; 129 case SND_SOC_DAIFMT_RIGHT_J: 130 switch (params_width(params)) { 131 case 16: 132 hw_params |= BIT(1); 133 break; 134 case 18: 135 hw_params |= BIT(2); 136 break; 137 case 20: 138 hw_params |= BIT(2) | BIT(1); 139 break; 140 default: 141 dev_err(dev, "unsupported format (right)\n"); 142 return -EINVAL; 143 } 144 break; 145 case SND_SOC_DAIFMT_LEFT_J: 146 hw_params |= BIT(3); 147 break; 148 default: 149 dev_err(dev, "unsupported format\n"); 150 return -EINVAL; 151 } 152 153 return regmap_update_bits(uda1342->regmap, 0x0, 154 STATUS0_DAIFMT_MASK | STATUS0_SYSCLK_MASK, hw_params); 155 } 156 157 static int uda1342_set_dai_sysclk(struct snd_soc_dai *codec_dai, 158 int clk_id, unsigned int freq, int dir) 159 { 160 struct snd_soc_component *component = codec_dai->component; 161 struct uda1342_priv *uda1342 = snd_soc_component_get_drvdata(component); 162 struct device *dev = &uda1342->i2c->dev; 163 164 /* 165 * Anything between 256fs*8Khz and 512fs*48Khz should be acceptable 166 * because the codec is slave. Of course limitations of the clock 167 * master (the IIS controller) apply. 168 * We'll error out on set_hw_params if it's not OK 169 */ 170 if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) { 171 uda1342->sysclk = freq; 172 return 0; 173 } 174 175 dev_err(dev, "unsupported sysclk\n"); 176 177 return -EINVAL; 178 } 179 180 static int uda1342_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 181 { 182 struct snd_soc_component *component = codec_dai->component; 183 struct uda1342_priv *uda1342 = snd_soc_component_get_drvdata(component); 184 185 /* codec supports only full consumer mode */ 186 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_BC_FC) { 187 dev_err(&uda1342->i2c->dev, "unsupported consumer mode.\n"); 188 return -EINVAL; 189 } 190 191 /* We can't setup DAI format here as it depends on the word bit num */ 192 /* so let's just store the value for later */ 193 uda1342->dai_fmt = fmt; 194 195 return 0; 196 } 197 198 static const struct snd_kcontrol_new uda1342_snd_controls[] = { 199 SOC_SINGLE("Master Playback Volume", 0x11, 0, 0x3F, 1), 200 SOC_SINGLE("Analog1 Volume", 0x12, 0, 0x1F, 1), 201 }; 202 203 /* Common DAPM widgets */ 204 static const struct snd_soc_dapm_widget uda1342_dapm_widgets[] = { 205 SND_SOC_DAPM_INPUT("VINL1"), 206 SND_SOC_DAPM_INPUT("VINR1"), 207 SND_SOC_DAPM_INPUT("VINL2"), 208 SND_SOC_DAPM_INPUT("VINR2"), 209 210 SND_SOC_DAPM_DAC("DAC", "Playback", 0, 1, 0), 211 SND_SOC_DAPM_ADC("ADC", "Capture", 0, 9, 0), 212 213 SND_SOC_DAPM_OUTPUT("VOUTL"), 214 SND_SOC_DAPM_OUTPUT("VOUTR"), 215 }; 216 217 static const struct snd_soc_dapm_route uda1342_dapm_routes[] = { 218 { "ADC", NULL, "VINL1" }, 219 { "ADC", NULL, "VINR1" }, 220 { "ADC", NULL, "VINL2" }, 221 { "ADC", NULL, "VINR2" }, 222 { "VOUTL", NULL, "DAC" }, 223 { "VOUTR", NULL, "DAC" }, 224 }; 225 226 static const struct snd_soc_dai_ops uda1342_dai_ops = { 227 .startup = uda1342_startup, 228 .shutdown = uda1342_shutdown, 229 .hw_params = uda1342_hw_params, 230 .mute_stream = uda1342_mute, 231 .set_sysclk = uda1342_set_dai_sysclk, 232 .set_fmt = uda1342_set_dai_fmt, 233 }; 234 235 static struct snd_soc_dai_driver uda1342_dai = { 236 .name = "uda1342-hifi", 237 /* playback capabilities */ 238 .playback = { 239 .stream_name = "Playback", 240 .channels_min = 1, 241 .channels_max = 2, 242 .rates = SNDRV_PCM_RATE_8000_48000, 243 .formats = UDA134X_FORMATS, 244 }, 245 /* capture capabilities */ 246 .capture = { 247 .stream_name = "Capture", 248 .channels_min = 1, 249 .channels_max = 2, 250 .rates = SNDRV_PCM_RATE_8000_48000, 251 .formats = UDA134X_FORMATS, 252 }, 253 /* pcm operations */ 254 .ops = &uda1342_dai_ops, 255 }; 256 257 static const struct snd_soc_component_driver soc_component_dev_uda1342 = { 258 .controls = uda1342_snd_controls, 259 .num_controls = ARRAY_SIZE(uda1342_snd_controls), 260 .dapm_widgets = uda1342_dapm_widgets, 261 .num_dapm_widgets = ARRAY_SIZE(uda1342_dapm_widgets), 262 .dapm_routes = uda1342_dapm_routes, 263 .num_dapm_routes = ARRAY_SIZE(uda1342_dapm_routes), 264 .suspend_bias_off = 1, 265 .idle_bias_on = 1, 266 .use_pmdown_time = 1, 267 .endianness = 1, 268 }; 269 270 static const struct regmap_config uda1342_regmap = { 271 .reg_bits = 8, 272 .val_bits = 16, 273 .max_register = 0x21, 274 .reg_defaults = uda1342_reg_defaults, 275 .num_reg_defaults = ARRAY_SIZE(uda1342_reg_defaults), 276 .cache_type = REGCACHE_MAPLE, 277 }; 278 279 static int uda1342_i2c_probe(struct i2c_client *i2c) 280 { 281 struct uda1342_priv *uda1342; 282 283 uda1342 = devm_kzalloc(&i2c->dev, sizeof(*uda1342), GFP_KERNEL); 284 if (!uda1342) 285 return -ENOMEM; 286 287 uda1342->regmap = devm_regmap_init_i2c(i2c, &uda1342_regmap); 288 if (IS_ERR(uda1342->regmap)) 289 return PTR_ERR(uda1342->regmap); 290 291 i2c_set_clientdata(i2c, uda1342); 292 uda1342->i2c = i2c; 293 294 return devm_snd_soc_register_component(&i2c->dev, 295 &soc_component_dev_uda1342, 296 &uda1342_dai, 1); 297 } 298 299 static int uda1342_suspend(struct device *dev) 300 { 301 struct uda1342_priv *uda1342 = dev_get_drvdata(dev); 302 303 regcache_cache_only(uda1342->regmap, true); 304 305 return 0; 306 } 307 308 static int uda1342_resume(struct device *dev) 309 { 310 struct uda1342_priv *uda1342 = dev_get_drvdata(dev); 311 312 regcache_mark_dirty(uda1342->regmap); 313 regcache_sync(uda1342->regmap); 314 315 return 0; 316 } 317 318 static DEFINE_RUNTIME_DEV_PM_OPS(uda1342_pm_ops, 319 uda1342_suspend, uda1342_resume, NULL); 320 321 static const struct i2c_device_id uda1342_i2c_id[] = { 322 { "uda1342", 0 }, 323 { } 324 }; 325 MODULE_DEVICE_TABLE(i2c, uda1342_i2c_id); 326 327 static const struct of_device_id uda1342_of_match[] = { 328 { .compatible = "nxp,uda1342" }, 329 { } 330 }; 331 MODULE_DEVICE_TABLE(of, uda1342_of_match); 332 333 static struct i2c_driver uda1342_i2c_driver = { 334 .driver = { 335 .name = "uda1342", 336 .of_match_table = uda1342_of_match, 337 .pm = pm_sleep_ptr(&uda1342_pm_ops), 338 }, 339 .probe = uda1342_i2c_probe, 340 .id_table = uda1342_i2c_id, 341 }; 342 module_i2c_driver(uda1342_i2c_driver); 343 344 MODULE_DESCRIPTION("UDA1342 ALSA soc codec driver"); 345 MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); 346 MODULE_AUTHOR("Binbin Zhou <zhoubinbin@loongson.cn>"); 347 MODULE_LICENSE("GPL"); 348