xref: /linux/sound/soc/codecs/uda1342.c (revision cdd30ebb1b9f36159d66f088b61aee264e649d7a)
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