xref: /openbmc/linux/sound/soc/ux500/mop500_ab8500.c (revision a130243b)
1 /*
2  * Copyright (C) ST-Ericsson SA 2012
3  *
4  * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5  *         Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>
6  *         for ST-Ericsson.
7  *
8  * License terms:
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as published
12  * by the Free Software Foundation.
13  */
14 
15 #include <linux/module.h>
16 #include <linux/device.h>
17 #include <linux/io.h>
18 #include <linux/clk.h>
19 #include <linux/mutex.h>
20 
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 
26 #include "ux500_pcm.h"
27 #include "ux500_msp_dai.h"
28 #include "mop500_ab8500.h"
29 #include "../codecs/ab8500-codec.h"
30 
31 #define TX_SLOT_MONO	0x0008
32 #define TX_SLOT_STEREO	0x000a
33 #define RX_SLOT_MONO	0x0001
34 #define RX_SLOT_STEREO	0x0003
35 #define TX_SLOT_8CH	0x00FF
36 #define RX_SLOT_8CH	0x00FF
37 
38 #define DEF_TX_SLOTS	TX_SLOT_STEREO
39 #define DEF_RX_SLOTS	RX_SLOT_MONO
40 
41 #define DRIVERMODE_NORMAL	0
42 #define DRIVERMODE_CODEC_ONLY	1
43 
44 /* Slot configuration */
45 static unsigned int tx_slots = DEF_TX_SLOTS;
46 static unsigned int rx_slots = DEF_RX_SLOTS;
47 
48 /* Configuration consistency parameters */
49 static DEFINE_MUTEX(mop500_ab8500_params_lock);
50 static unsigned long mop500_ab8500_usage;
51 static int mop500_ab8500_rate;
52 static int mop500_ab8500_channels;
53 
54 /* Clocks */
55 static const char * const enum_mclk[] = {
56 	"SYSCLK",
57 	"ULPCLK"
58 };
59 enum mclk {
60 	MCLK_SYSCLK,
61 	MCLK_ULPCLK,
62 };
63 
64 static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk);
65 
66 /* Private data for machine-part MOP500<->AB8500 */
67 struct mop500_ab8500_drvdata {
68 	/* Clocks */
69 	enum mclk mclk_sel;
70 	struct clk *clk_ptr_intclk;
71 	struct clk *clk_ptr_sysclk;
72 	struct clk *clk_ptr_ulpclk;
73 };
74 
75 static inline const char *get_mclk_str(enum mclk mclk_sel)
76 {
77 	switch (mclk_sel) {
78 	case MCLK_SYSCLK:
79 		return "SYSCLK";
80 	case MCLK_ULPCLK:
81 		return "ULPCLK";
82 	default:
83 		return "Unknown";
84 	}
85 }
86 
87 static int mop500_ab8500_set_mclk(struct device *dev,
88 				struct mop500_ab8500_drvdata *drvdata)
89 {
90 	int status;
91 	struct clk *clk_ptr;
92 
93 	if (IS_ERR(drvdata->clk_ptr_intclk)) {
94 		dev_err(dev,
95 			"%s: ERROR: intclk not initialized!\n", __func__);
96 		return -EIO;
97 	}
98 
99 	switch (drvdata->mclk_sel) {
100 	case MCLK_SYSCLK:
101 		clk_ptr = drvdata->clk_ptr_sysclk;
102 		break;
103 	case MCLK_ULPCLK:
104 		clk_ptr = drvdata->clk_ptr_ulpclk;
105 		break;
106 	default:
107 		return -EINVAL;
108 	}
109 
110 	if (IS_ERR(clk_ptr)) {
111 		dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__,
112 			get_mclk_str(drvdata->mclk_sel));
113 		return -EIO;
114 	}
115 
116 	status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr);
117 	if (status)
118 		dev_err(dev,
119 			"%s: ERROR: Setting intclk parent to %s failed (ret = %d)!",
120 			__func__, get_mclk_str(drvdata->mclk_sel), status);
121 	else
122 		dev_dbg(dev,
123 			"%s: intclk parent changed to %s.\n",
124 			__func__, get_mclk_str(drvdata->mclk_sel));
125 
126 	return status;
127 }
128 
129 /*
130  * Control-events
131  */
132 
133 static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
134 				struct snd_ctl_elem_value *ucontrol)
135 {
136 	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
137 	struct mop500_ab8500_drvdata *drvdata =
138 				snd_soc_card_get_drvdata(card);
139 
140 	ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
141 
142 	return 0;
143 }
144 
145 static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
146 				struct snd_ctl_elem_value *ucontrol)
147 {
148 	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
149 	struct mop500_ab8500_drvdata *drvdata =
150 				snd_soc_card_get_drvdata(card);
151 	unsigned int val = ucontrol->value.enumerated.item[0];
152 
153 	if (val > (unsigned int)MCLK_ULPCLK)
154 		return -EINVAL;
155 	if (drvdata->mclk_sel == val)
156 		return 0;
157 
158 	drvdata->mclk_sel = val;
159 
160 	return 1;
161 }
162 
163 /*
164  * Controls
165  */
166 
167 static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
168 	SOC_ENUM_EXT("Master Clock Select",
169 		soc_enum_mclk,
170 		mclk_input_control_get, mclk_input_control_put),
171 	SOC_DAPM_PIN_SWITCH("Headset Left"),
172 	SOC_DAPM_PIN_SWITCH("Headset Right"),
173 	SOC_DAPM_PIN_SWITCH("Earpiece"),
174 	SOC_DAPM_PIN_SWITCH("Speaker Left"),
175 	SOC_DAPM_PIN_SWITCH("Speaker Right"),
176 	SOC_DAPM_PIN_SWITCH("LineOut Left"),
177 	SOC_DAPM_PIN_SWITCH("LineOut Right"),
178 	SOC_DAPM_PIN_SWITCH("Vibra 1"),
179 	SOC_DAPM_PIN_SWITCH("Vibra 2"),
180 	SOC_DAPM_PIN_SWITCH("Mic 1"),
181 	SOC_DAPM_PIN_SWITCH("Mic 2"),
182 	SOC_DAPM_PIN_SWITCH("LineIn Left"),
183 	SOC_DAPM_PIN_SWITCH("LineIn Right"),
184 	SOC_DAPM_PIN_SWITCH("DMic 1"),
185 	SOC_DAPM_PIN_SWITCH("DMic 2"),
186 	SOC_DAPM_PIN_SWITCH("DMic 3"),
187 	SOC_DAPM_PIN_SWITCH("DMic 4"),
188 	SOC_DAPM_PIN_SWITCH("DMic 5"),
189 	SOC_DAPM_PIN_SWITCH("DMic 6"),
190 };
191 
192 /* ASoC */
193 
194 static int mop500_ab8500_startup(struct snd_pcm_substream *substream)
195 {
196 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
197 
198 	/* Set audio-clock source */
199 	return mop500_ab8500_set_mclk(rtd->card->dev,
200 				snd_soc_card_get_drvdata(rtd->card));
201 }
202 
203 static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
204 {
205 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
206 	struct device *dev = rtd->card->dev;
207 
208 	dev_dbg(dev, "%s: Enter\n", __func__);
209 
210 	/* Reset slots configuration to default(s) */
211 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
212 		tx_slots = DEF_TX_SLOTS;
213 	else
214 		rx_slots = DEF_RX_SLOTS;
215 }
216 
217 static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
218 			struct snd_pcm_hw_params *params)
219 {
220 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
221 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
222 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
223 	struct device *dev = rtd->card->dev;
224 	unsigned int fmt;
225 	int channels, ret = 0, driver_mode, slots;
226 	unsigned int sw_codec, sw_cpu;
227 	bool is_playback;
228 
229 	dev_dbg(dev, "%s: Enter\n", __func__);
230 
231 	dev_dbg(dev, "%s: substream->pcm->name = %s\n"
232 		"substream->pcm->id = %s.\n"
233 		"substream->name = %s.\n"
234 		"substream->number = %d.\n",
235 		__func__,
236 		substream->pcm->name,
237 		substream->pcm->id,
238 		substream->name,
239 		substream->number);
240 
241 	/* Ensure configuration consistency between DAIs */
242 	mutex_lock(&mop500_ab8500_params_lock);
243 	if (mop500_ab8500_usage) {
244 		if (mop500_ab8500_rate != params_rate(params) ||
245 		    mop500_ab8500_channels != params_channels(params)) {
246 			mutex_unlock(&mop500_ab8500_params_lock);
247 			return -EBUSY;
248 		}
249 	} else {
250 		mop500_ab8500_rate = params_rate(params);
251 		mop500_ab8500_channels = params_channels(params);
252 	}
253 	__set_bit(cpu_dai->id, &mop500_ab8500_usage);
254 	mutex_unlock(&mop500_ab8500_params_lock);
255 
256 	channels = params_channels(params);
257 
258 	switch (params_format(params)) {
259 	case SNDRV_PCM_FORMAT_S32_LE:
260 		sw_cpu = 32;
261 		break;
262 
263 	case SNDRV_PCM_FORMAT_S16_LE:
264 		sw_cpu = 16;
265 		break;
266 
267 	default:
268 		return -EINVAL;
269 	}
270 
271 	/* Setup codec depending on driver-mode */
272 	if (channels == 8)
273 		driver_mode = DRIVERMODE_CODEC_ONLY;
274 	else
275 		driver_mode = DRIVERMODE_NORMAL;
276 	dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__,
277 		(driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
278 
279 	/* Setup format */
280 
281 	if (driver_mode == DRIVERMODE_NORMAL) {
282 		fmt = SND_SOC_DAIFMT_DSP_A |
283 			SND_SOC_DAIFMT_CBM_CFM |
284 			SND_SOC_DAIFMT_NB_NF |
285 			SND_SOC_DAIFMT_CONT;
286 	} else {
287 		fmt = SND_SOC_DAIFMT_DSP_A |
288 			SND_SOC_DAIFMT_CBM_CFM |
289 			SND_SOC_DAIFMT_NB_NF |
290 			SND_SOC_DAIFMT_GATED;
291 	}
292 
293 	ret = snd_soc_dai_set_fmt(codec_dai, fmt);
294 	if (ret < 0) {
295 		dev_err(dev,
296 			"%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n",
297 			__func__, ret);
298 		return ret;
299 	}
300 
301 	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
302 	if (ret < 0) {
303 		dev_err(dev,
304 			"%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n",
305 			__func__, ret);
306 		return ret;
307 	}
308 
309 	/* Setup TDM-slots */
310 
311 	is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
312 	switch (channels) {
313 	case 1:
314 		slots = 16;
315 		tx_slots = (is_playback) ? TX_SLOT_MONO : 0;
316 		rx_slots = (is_playback) ? 0 : RX_SLOT_MONO;
317 		break;
318 	case 2:
319 		slots = 16;
320 		tx_slots = (is_playback) ? TX_SLOT_STEREO : 0;
321 		rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO;
322 		break;
323 	case 8:
324 		slots = 16;
325 		tx_slots = (is_playback) ? TX_SLOT_8CH : 0;
326 		rx_slots = (is_playback) ? 0 : RX_SLOT_8CH;
327 		break;
328 	default:
329 		return -EINVAL;
330 	}
331 
332 	if (driver_mode == DRIVERMODE_NORMAL)
333 		sw_codec = sw_cpu;
334 	else
335 		sw_codec = 20;
336 
337 	dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
338 		tx_slots, rx_slots);
339 	ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots,
340 				sw_cpu);
341 	if (ret)
342 		return ret;
343 
344 	dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
345 		tx_slots, rx_slots);
346 	ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots,
347 				sw_codec);
348 	if (ret)
349 		return ret;
350 
351 	return 0;
352 }
353 
354 static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
355 {
356 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
357 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
358 
359 	mutex_lock(&mop500_ab8500_params_lock);
360 	__clear_bit(cpu_dai->id, &mop500_ab8500_usage);
361 	mutex_unlock(&mop500_ab8500_params_lock);
362 
363 	return 0;
364 }
365 
366 struct snd_soc_ops mop500_ab8500_ops[] = {
367 	{
368 		.hw_params = mop500_ab8500_hw_params,
369 		.hw_free = mop500_ab8500_hw_free,
370 		.startup = mop500_ab8500_startup,
371 		.shutdown = mop500_ab8500_shutdown,
372 	}
373 };
374 
375 int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
376 {
377 	struct snd_soc_codec *codec = rtd->codec;
378 	struct device *dev = rtd->card->dev;
379 	struct mop500_ab8500_drvdata *drvdata;
380 	int ret;
381 
382 	dev_dbg(dev, "%s Enter.\n", __func__);
383 
384 	/* Create driver private-data struct */
385 	drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata),
386 			GFP_KERNEL);
387 	snd_soc_card_set_drvdata(rtd->card, drvdata);
388 
389 	/* Setup clocks */
390 
391 	drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk");
392 	if (IS_ERR(drvdata->clk_ptr_sysclk))
393 		dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n",
394 			__func__);
395 	drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk");
396 	if (IS_ERR(drvdata->clk_ptr_ulpclk))
397 		dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n",
398 			__func__);
399 	drvdata->clk_ptr_intclk = clk_get(dev, "intclk");
400 	if (IS_ERR(drvdata->clk_ptr_intclk))
401 		dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n",
402 			__func__);
403 
404 	/* Set intclk default parent to ulpclk */
405 	drvdata->mclk_sel = MCLK_ULPCLK;
406 	ret = mop500_ab8500_set_mclk(dev, drvdata);
407 	if (ret < 0)
408 		dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n",
409 			__func__);
410 
411 	drvdata->mclk_sel = MCLK_ULPCLK;
412 
413 	/* Add controls */
414 	ret = snd_soc_add_card_controls(codec->card, mop500_ab8500_ctrls,
415 			ARRAY_SIZE(mop500_ab8500_ctrls));
416 	if (ret < 0) {
417 		pr_err("%s: Failed to add machine-controls (%d)!\n",
418 				__func__, ret);
419 		return ret;
420 	}
421 
422 	ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece");
423 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left");
424 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right");
425 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left");
426 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right");
427 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1");
428 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2");
429 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1");
430 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2");
431 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left");
432 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right");
433 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1");
434 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2");
435 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3");
436 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4");
437 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5");
438 	ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6");
439 
440 	return ret;
441 }
442 
443 void mop500_ab8500_remove(struct snd_soc_card *card)
444 {
445 	struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card);
446 
447 	if (drvdata->clk_ptr_sysclk != NULL)
448 		clk_put(drvdata->clk_ptr_sysclk);
449 	if (drvdata->clk_ptr_ulpclk != NULL)
450 		clk_put(drvdata->clk_ptr_ulpclk);
451 	if (drvdata->clk_ptr_intclk != NULL)
452 		clk_put(drvdata->clk_ptr_intclk);
453 
454 	snd_soc_card_set_drvdata(card, drvdata);
455 }
456