blob: b2adf5de822c78be819602add92583ff85068b48 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/platform_device.h>
17#include <linux/mfd/wcd9310/core.h>
18#include <linux/bitops.h>
19#include <linux/slab.h>
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -070020#include <linux/clk.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/apr_audio.h>
25#include <sound/q6afe.h>
26#include <sound/q6adm.h>
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -070027#include <sound/msm-dai-q6.h>
28#include <mach/clk.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029
30enum {
31 STATUS_PORT_STARTED, /* track if AFE port has started */
32 STATUS_MAX
33};
34
35struct msm_dai_q6_dai_data {
36 DECLARE_BITMAP(status_mask, STATUS_MAX);
37 u32 rate;
38 u32 channels;
39 union afe_port_config port_config;
40};
41
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -070042static struct clk *pcm_clk;
43
Kuirong Wang274f21a2011-12-15 21:29:08 -080044static u8 num_of_bits_set(u8 sd_line_mask)
45{
46 u8 num_bits_set = 0;
47
48 while (sd_line_mask) {
49 num_bits_set++;
50 sd_line_mask = sd_line_mask & (sd_line_mask - 1);
51 }
52 return num_bits_set;
53}
54
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070055static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params,
56 struct snd_soc_dai *dai, int stream)
57{
58 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
59
60 dai_data->channels = params_channels(params);
61 switch (dai_data->channels) {
62 case 2:
63 dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
64 break;
65 case 1:
66 dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
67 break;
68 default:
69 return -EINVAL;
70 break;
71 }
72 dai_data->rate = params_rate(params);
73
74 dev_dbg(dai->dev, " channel %d sample rate %d entered\n",
75 dai_data->channels, dai_data->rate);
76
77 /* Q6 only supports 16 as now */
78 dai_data->port_config.mi2s.bitwidth = 16;
79 dai_data->port_config.mi2s.line = 1;
Kuirong Wang274f21a2011-12-15 21:29:08 -080080 return 0;
81}
82
83static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_hw_params *params,
84 struct snd_soc_dai *dai, int stream)
85{
86 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
87 struct msm_mi2s_data *mi2s_pdata =
88 (struct msm_mi2s_data *) dai->dev->platform_data;
89
90 dai_data->channels = params_channels(params);
91 if (num_of_bits_set(mi2s_pdata->sd_lines) == 1) {
92 switch (dai_data->channels) {
93 case 2:
94 dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
95 break;
96 case 1:
97 dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
98 break;
99 default:
100 pr_warn("greater than stereo has not been validated");
101 break;
102 }
103 }
104 /* Q6 only supports 16 as now */
105 dai_data->port_config.mi2s.bitwidth = 16;
Lei Zhou157c1842011-08-19 13:05:04 -0400106
107 return 0;
108}
109
Kuirong Wang274f21a2011-12-15 21:29:08 -0800110static int msm_dai_q6_mi2s_platform_data_validation(
111 struct snd_soc_dai *dai)
112{
113 u8 num_of_sd_lines;
114 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
115 struct msm_mi2s_data *mi2s_pdata =
116 (struct msm_mi2s_data *)dai->dev->platform_data;
117 struct snd_soc_dai_driver *dai_driver =
118 (struct snd_soc_dai_driver *)dai->driver;
119
120 num_of_sd_lines = num_of_bits_set(mi2s_pdata->sd_lines);
121
122 switch (num_of_sd_lines) {
123 case 1:
124 switch (mi2s_pdata->sd_lines) {
125 case MSM_MI2S_SD0:
126 dai_data->port_config.mi2s.line = AFE_I2S_SD0;
127 break;
128 case MSM_MI2S_SD1:
129 dai_data->port_config.mi2s.line = AFE_I2S_SD1;
130 break;
131 case MSM_MI2S_SD2:
132 dai_data->port_config.mi2s.line = AFE_I2S_SD2;
133 break;
134 case MSM_MI2S_SD3:
135 dai_data->port_config.mi2s.line = AFE_I2S_SD3;
136 break;
137 default:
138 pr_err("%s: invalid SD line\n",
139 __func__);
140 goto error_invalid_data;
141 }
142 break;
143 case 2:
144 switch (mi2s_pdata->sd_lines) {
145 case MSM_MI2S_SD0 | MSM_MI2S_SD1:
146 dai_data->port_config.mi2s.line = AFE_I2S_QUAD01;
147 break;
148 case MSM_MI2S_SD2 | MSM_MI2S_SD3:
149 dai_data->port_config.mi2s.line = AFE_I2S_QUAD23;
150 break;
151 default:
152 pr_err("%s: invalid SD line\n",
153 __func__);
154 goto error_invalid_data;
155 }
156 break;
157 case 3:
158 switch (mi2s_pdata->sd_lines) {
159 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2:
160 dai_data->port_config.mi2s.line = AFE_I2S_6CHS;
161 break;
162 default:
163 pr_err("%s: invalid SD lines\n",
164 __func__);
165 goto error_invalid_data;
166 }
167 break;
168 case 4:
169 switch (mi2s_pdata->sd_lines) {
170 case MSM_MI2S_SD0 | MSM_MI2S_SD1 | MSM_MI2S_SD2 | MSM_MI2S_SD3:
171 dai_data->port_config.mi2s.line = AFE_I2S_8CHS;
172 break;
173 default:
174 pr_err("%s: invalid SD lines\n",
175 __func__);
176 goto error_invalid_data;
177 }
178 break;
179 default:
180 pr_err("%s: invalid SD lines\n", __func__);
181 goto error_invalid_data;
182 }
183 if (mi2s_pdata->capability == MSM_MI2S_CAP_RX)
184 dai_driver->playback.channels_max = num_of_sd_lines << 1;
185
186 return 0;
187
188error_invalid_data:
189 return -EINVAL;
190}
191
Lei Zhou157c1842011-08-19 13:05:04 -0400192static int msm_dai_q6_cdc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
193{
194 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
195
196 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
197 case SND_SOC_DAIFMT_CBS_CFS:
198 dai_data->port_config.mi2s.ws = 1; /* CPU is master */
199 break;
200 case SND_SOC_DAIFMT_CBM_CFM:
201 dai_data->port_config.mi2s.ws = 0; /* CPU is slave */
202 break;
203 default:
204 return -EINVAL;
205 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700206
207 return 0;
208}
209
210static int msm_dai_q6_hdmi_hw_params(struct snd_pcm_hw_params *params,
211 struct snd_soc_dai *dai)
212{
213 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
214
215 dev_dbg(dai->dev, "%s start HDMI port\n", __func__);
216
217 dai_data->channels = params_channels(params);
218 switch (dai_data->channels) {
219 case 2:
220 dai_data->port_config.hdmi.channel_mode = 0; /* Put in macro */
221 break;
222 default:
223 return -EINVAL;
224 break;
225 }
226
227 /* Q6 only supports 16 as now */
228 dai_data->port_config.hdmi.bitwidth = 16;
229 dai_data->port_config.hdmi.data_type = 0;
230 dai_data->rate = params_rate(params);
231
232 return 0;
233}
234
235static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params,
236 struct snd_soc_dai *dai, int stream)
237{
238 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
239 u8 pgd_la, inf_la;
240
241 memset(dai_data->port_config.slimbus.slave_port_mapping, 0,
242 sizeof(dai_data->port_config.slimbus.slave_port_mapping));
243
244 dai_data->channels = params_channels(params);
245 switch (dai_data->channels) {
246 case 2:
247 if (dai->id == SLIMBUS_0_RX) {
248 dai_data->port_config.slimbus.slave_port_mapping[0] = 1;
249 dai_data->port_config.slimbus.slave_port_mapping[1] = 2;
250 } else {
251 dai_data->port_config.slimbus.slave_port_mapping[0] = 7;
252 dai_data->port_config.slimbus.slave_port_mapping[1] = 8;
253 }
254 break;
255 case 1:
256 if (dai->id == SLIMBUS_0_RX)
257 dai_data->port_config.slimbus.slave_port_mapping[0] = 1;
258 else
259 dai_data->port_config.slimbus.slave_port_mapping[0] = 7;
260 break;
261 default:
262 return -EINVAL;
263 break;
264 }
265 dai_data->rate = params_rate(params);
266 tabla_get_logical_addresses(&pgd_la, &inf_la);
267
268 dai_data->port_config.slimbus.slimbus_dev_id = AFE_SLIMBUS_DEVICE_1;
269 dai_data->port_config.slimbus.slave_dev_pgd_la = pgd_la;
270 dai_data->port_config.slimbus.slave_dev_intfdev_la = inf_la;
271 /* Q6 only supports 16 as now */
272 dai_data->port_config.slimbus.bit_width = 16;
273 dai_data->port_config.slimbus.data_format = 0;
274 dai_data->port_config.slimbus.num_channels = dai_data->channels;
275 dai_data->port_config.slimbus.reserved = 0;
276
277 dev_dbg(dai->dev, "slimbus_dev_id %hu slave_dev_pgd_la 0x%hx\n"
278 "slave_dev_intfdev_la 0x%hx bit_width %hu data_format %hu\n"
279 "num_channel %hu slave_port_mapping[0] %hu\n"
280 "slave_port_mapping[1] %hu slave_port_mapping[2] %hu\n"
281 "sample_rate %d\n",
282 dai_data->port_config.slimbus.slimbus_dev_id,
283 dai_data->port_config.slimbus.slave_dev_pgd_la,
284 dai_data->port_config.slimbus.slave_dev_intfdev_la,
285 dai_data->port_config.slimbus.bit_width,
286 dai_data->port_config.slimbus.data_format,
287 dai_data->port_config.slimbus.num_channels,
288 dai_data->port_config.slimbus.slave_port_mapping[0],
289 dai_data->port_config.slimbus.slave_port_mapping[1],
290 dai_data->port_config.slimbus.slave_port_mapping[2],
291 dai_data->rate);
292
293 return 0;
294}
295
296static int msm_dai_q6_bt_fm_hw_params(struct snd_pcm_hw_params *params,
297 struct snd_soc_dai *dai, int stream)
298{
299 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
300
301 dai_data->channels = params_channels(params);
302 dai_data->rate = params_rate(params);
303
304 dev_dbg(dai->dev, "channels %d sample rate %d entered\n",
305 dai_data->channels, dai_data->rate);
306
307 memset(&dai_data->port_config, 0, sizeof(dai_data->port_config));
308
309 return 0;
310}
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700311static int msm_dai_q6_auxpcm_hw_params(
312 struct snd_pcm_substream *substream,
313 struct snd_pcm_hw_params *params,
314 struct snd_soc_dai *dai)
315{
316 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
317 struct msm_dai_auxpcm_pdata *auxpcm_pdata =
318 (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
319
320 if (params_channels(params) != 1) {
321 dev_err(dai->dev, "AUX PCM supports only mono stream\n");
322 return -EINVAL;
323 }
324 dai_data->channels = params_channels(params);
325
326 if (params_rate(params) != 8000) {
327 dev_err(dai->dev, "AUX PCM supports only 8KHz sampling rate\n");
328 return -EINVAL;
329 }
330 dai_data->rate = params_rate(params);
331 dai_data->port_config.pcm.mode = auxpcm_pdata->mode;
332 dai_data->port_config.pcm.sync = auxpcm_pdata->sync;
333 dai_data->port_config.pcm.frame = auxpcm_pdata->frame;
334 dai_data->port_config.pcm.quant = auxpcm_pdata->quant;
335 dai_data->port_config.pcm.slot = auxpcm_pdata->slot;
336 dai_data->port_config.pcm.data = auxpcm_pdata->data;
337
338 return 0;
339}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530341static int get_frame_size(u16 rate, u16 ch)
342{
343 if (rate == 8000) {
344 if (ch == 1)
345 return 128 * 2;
346 else
347 return 128 * 2 * 2;
348 } else if (rate == 16000) {
349 if (ch == 1)
350 return 128 * 2 * 2;
351 else
352 return 128 * 2 * 4;
353 } else if (rate == 48000) {
354 if (ch == 1)
355 return 128 * 2 * 6;
356 else
357 return 128 * 2 * 12;
358 } else
359 return 128 * 2 * 12;
360}
361
362static int msm_dai_q6_afe_rtproxy_hw_params(struct snd_pcm_hw_params *params,
363 struct snd_soc_dai *dai)
364{
365 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
366
367 dai_data->rate = params_rate(params);
368 dai_data->port_config.rtproxy.num_ch =
369 params_channels(params);
370
371 pr_debug("channel %d entered,dai_id: %d,rate: %d\n",
372 dai_data->port_config.rtproxy.num_ch, dai->id, dai_data->rate);
373
374 dai_data->port_config.rtproxy.bitwidth = 16; /* Q6 only supports 16 */
375 dai_data->port_config.rtproxy.interleaved = 1;
376 dai_data->port_config.rtproxy.frame_sz = get_frame_size(dai_data->rate,
377 dai_data->port_config.rtproxy.num_ch);
378 dai_data->port_config.rtproxy.jitter =
379 dai_data->port_config.rtproxy.frame_sz/2;
380 dai_data->port_config.rtproxy.lw_mark = 0;
381 dai_data->port_config.rtproxy.hw_mark = 0;
382 dai_data->port_config.rtproxy.rsvd = 0;
383
384 return 0;
385}
386
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700387/* Current implementation assumes hw_param is called once
388 * This may not be the case but what to do when ADM and AFE
389 * port are already opened and parameter changes
390 */
391static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream,
392 struct snd_pcm_hw_params *params,
393 struct snd_soc_dai *dai)
394{
395 int rc = 0;
396
397 switch (dai->id) {
398 case PRIMARY_I2S_TX:
399 case PRIMARY_I2S_RX:
400 rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
401 break;
Kuirong Wang274f21a2011-12-15 21:29:08 -0800402 case MI2S_RX:
403 rc = msm_dai_q6_mi2s_hw_params(params, dai, substream->stream);
404 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700405 case HDMI_RX:
406 rc = msm_dai_q6_hdmi_hw_params(params, dai);
407 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700408 case SLIMBUS_0_RX:
409 case SLIMBUS_0_TX:
410 rc = msm_dai_q6_slim_bus_hw_params(params, dai,
411 substream->stream);
412 break;
413 case INT_BT_SCO_RX:
414 case INT_BT_SCO_TX:
415 case INT_FM_RX:
416 case INT_FM_TX:
417 rc = msm_dai_q6_bt_fm_hw_params(params, dai, substream->stream);
418 break;
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530419 case RT_PROXY_DAI_001_TX:
420 case RT_PROXY_DAI_001_RX:
421 case RT_PROXY_DAI_002_TX:
422 case RT_PROXY_DAI_002_RX:
423 rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai);
424 break;
Helen Zeng0705a5f2011-10-14 15:29:52 -0700425 case VOICE_PLAYBACK_TX:
Helen Zenge3d716a2011-10-14 16:32:16 -0700426 case VOICE_RECORD_RX:
427 case VOICE_RECORD_TX:
Helen Zeng0705a5f2011-10-14 15:29:52 -0700428 rc = 0;
429 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700430 default:
431 dev_err(dai->dev, "invalid AFE port ID\n");
432 rc = -EINVAL;
433 break;
434 }
435
436 return rc;
437}
438
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700439static void msm_dai_q6_auxpcm_shutdown(struct snd_pcm_substream *substream,
440 struct snd_soc_dai *dai)
441{
442 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
443 int rc = 0;
444
445 rc = adm_close(dai->id);
446 if (IS_ERR_VALUE(rc))
447 dev_err(dai->dev, "fail to close ADM COPP\n");
448
449 pr_debug("%s: dai->id = %d", __func__, dai->id);
450
451 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
452 clk_disable(pcm_clk);
453 rc = afe_close(dai->id); /* can block */
454 if (IS_ERR_VALUE(rc))
455 dev_err(dai->dev, "fail to close AFE port\n");
456 pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
457 *dai_data->status_mask);
458 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
459
460 rc = afe_close(PCM_TX);
461 if (IS_ERR_VALUE(rc))
462 dev_err(dai->dev, "fail to close AUX PCM TX port\n");
463 }
464}
465
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700466static void msm_dai_q6_shutdown(struct snd_pcm_substream *substream,
467 struct snd_soc_dai *dai)
468{
469 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530470 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700472 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700473 switch (dai->id) {
474 case VOICE_PLAYBACK_TX:
Helen Zenge3d716a2011-10-14 16:32:16 -0700475 case VOICE_RECORD_TX:
476 case VOICE_RECORD_RX:
Helen Zeng0705a5f2011-10-14 15:29:52 -0700477 pr_debug("%s, stop pseudo port:%d\n",
478 __func__, dai->id);
479 rc = afe_stop_pseudo_port(dai->id);
480 break;
481 default:
482 rc = afe_close(dai->id); /* can block */
483 break;
484 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700485 if (IS_ERR_VALUE(rc))
486 dev_err(dai->dev, "fail to close AFE port\n");
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530487 pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
488 *dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700489 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
490 }
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700491}
492
493static int msm_dai_q6_auxpcm_prepare(struct snd_pcm_substream *substream,
494 struct snd_soc_dai *dai)
495{
496 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
497 int rc = 0;
498
499 struct msm_dai_auxpcm_pdata *auxpcm_pdata =
500 (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
501
502 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Patrick Laicf999112011-08-23 11:27:20 -0700503 rc = afe_q6_interface_prepare();
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700504 if (IS_ERR_VALUE(rc))
Patrick Laicf999112011-08-23 11:27:20 -0700505 dev_err(dai->dev, "fail to open AFE APR\n");
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700506
Patrick Laicf999112011-08-23 11:27:20 -0700507 rc = afe_q6_interface_prepare();
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700508 if (IS_ERR_VALUE(rc))
Patrick Laicf999112011-08-23 11:27:20 -0700509 dev_err(dai->dev, "fail to open AFE APR\n");
510
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700511 pr_debug("%s:dai->id:%d dai_data->status_mask = %ld\n",
512 __func__, dai->id, *dai_data->status_mask);
513
514 /*
515 * For AUX PCM Interface the below sequence of clk
516 * settings and afe_open is a strict requirement.
517 *
518 * Also using afe_open instead of afe_port_start_nowait
519 * to make sure the port is open before deasserting the
520 * clock line. This is required because pcm register is
521 * not written before clock deassert. Hence the hw does
522 * not get updated with new setting if the below clock
523 * assert/deasset and afe_open sequence is not followed.
524 */
525
526 clk_reset(pcm_clk, CLK_RESET_ASSERT);
527
528 afe_open(dai->id, &dai_data->port_config,
529 dai_data->rate);
530 set_bit(STATUS_PORT_STARTED,
531 dai_data->status_mask);
532
533 afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
534
535 rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate);
536 if (rc < 0) {
537 pr_err("%s: clk_set_rate failed\n", __func__);
538 return rc;
539 }
540
541 clk_enable(pcm_clk);
542 clk_reset(pcm_clk, CLK_RESET_DEASSERT);
543
544 }
545 return rc;
546}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700547
548static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
549 struct snd_soc_dai *dai)
550{
551 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
552 int rc = 0;
553
Patrick Lai831561e2011-07-26 22:51:27 -0700554 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Patrick Laicf999112011-08-23 11:27:20 -0700555 /* PORT START should be set if prepare called in active state */
556 rc = afe_q6_interface_prepare();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700557 if (IS_ERR_VALUE(rc))
Patrick Laicf999112011-08-23 11:27:20 -0700558 dev_err(dai->dev, "fail to open AFE APR\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700560 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700561}
562
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700563static int msm_dai_q6_auxpcm_trigger(struct snd_pcm_substream *substream,
564 int cmd, struct snd_soc_dai *dai)
565{
566 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
567 int rc = 0;
568
569 pr_debug("%s:port:%d cmd:%d dai_data->status_mask = %ld",
570 __func__, dai->id, cmd, *dai_data->status_mask);
571
572 switch (cmd) {
573
574 case SNDRV_PCM_TRIGGER_START:
575 case SNDRV_PCM_TRIGGER_RESUME:
576 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
577 /* afe_open will be called from prepare */
578 return 0;
579
580 case SNDRV_PCM_TRIGGER_STOP:
581 case SNDRV_PCM_TRIGGER_SUSPEND:
582 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
583 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
584
585 clk_disable(pcm_clk);
586 afe_port_stop_nowait(dai->id);
587 clear_bit(STATUS_PORT_STARTED,
588 dai_data->status_mask);
589
590 afe_port_stop_nowait(PCM_TX);
591 }
592 break;
593
594 default:
595 rc = -EINVAL;
596 }
597
598 return rc;
599
600}
601
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700602static int msm_dai_q6_trigger(struct snd_pcm_substream *substream, int cmd,
603 struct snd_soc_dai *dai)
604{
605 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
606 int rc = 0;
607
608 /* Start/stop port without waiting for Q6 AFE response. Need to have
609 * native q6 AFE driver propagates AFE response in order to handle
610 * port start/stop command error properly if error does arise.
611 */
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530612 pr_debug("%s:port:%d cmd:%d dai_data->status_mask = %ld",
613 __func__, dai->id, cmd, *dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700614 switch (cmd) {
615 case SNDRV_PCM_TRIGGER_START:
616 case SNDRV_PCM_TRIGGER_RESUME:
617 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
618 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700619 switch (dai->id) {
620 case VOICE_PLAYBACK_TX:
Helen Zenge3d716a2011-10-14 16:32:16 -0700621 case VOICE_RECORD_TX:
622 case VOICE_RECORD_RX:
Helen Zeng0705a5f2011-10-14 15:29:52 -0700623 afe_pseudo_port_start_nowait(dai->id);
624 break;
625 default:
626 afe_port_start_nowait(dai->id,
627 &dai_data->port_config, dai_data->rate);
628 break;
629 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700630 set_bit(STATUS_PORT_STARTED,
631 dai_data->status_mask);
632 }
633 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700634 case SNDRV_PCM_TRIGGER_STOP:
635 case SNDRV_PCM_TRIGGER_SUSPEND:
636 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
637 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700638 switch (dai->id) {
639 case VOICE_PLAYBACK_TX:
Helen Zenge3d716a2011-10-14 16:32:16 -0700640 case VOICE_RECORD_TX:
641 case VOICE_RECORD_RX:
Helen Zeng0705a5f2011-10-14 15:29:52 -0700642 afe_pseudo_port_stop_nowait(dai->id);
643 break;
644 default:
645 afe_port_stop_nowait(dai->id);
646 break;
647 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700648 clear_bit(STATUS_PORT_STARTED,
649 dai_data->status_mask);
650 }
651 break;
652
653 default:
654 rc = -EINVAL;
655 }
656
657 return rc;
658}
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700659static int msm_dai_q6_dai_auxpcm_probe(struct snd_soc_dai *dai)
660{
661 struct msm_dai_q6_dai_data *dai_data;
662 int rc = 0;
663
664 struct msm_dai_auxpcm_pdata *auxpcm_pdata =
665 (struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
666
667 dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data),
668 GFP_KERNEL);
669
670 if (!dai_data) {
671 dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
672 dai->id);
673 rc = -ENOMEM;
674 } else
675 dev_set_drvdata(dai->dev, dai_data);
676
677 /*
678 * The clk name for AUX PCM operation is passed as platform
679 * data to the cpu driver, since cpu drive is unaware of any
680 * boarc specific configuration.
681 */
682 pcm_clk = clk_get(NULL, auxpcm_pdata->clk);
683 if (IS_ERR(pcm_clk)) {
684 pr_err("%s: could not get pcm_clk\n", __func__);
685 return PTR_ERR(pcm_clk);
686 kfree(dai_data);
687 }
688
689 return rc;
690}
691
692static int msm_dai_q6_dai_auxpcm_remove(struct snd_soc_dai *dai)
693{
694 struct msm_dai_q6_dai_data *dai_data;
695 int rc;
696
697 dai_data = dev_get_drvdata(dai->dev);
698
699 /* If AFE port is still up, close it */
700 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
701 rc = afe_close(dai->id); /* can block */
702 if (IS_ERR_VALUE(rc))
703 dev_err(dai->dev, "fail to close AFE port\n");
704 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
705
706 rc = afe_close(PCM_TX);
707 if (IS_ERR_VALUE(rc))
708 dev_err(dai->dev, "fail to close AUX PCM TX port\n");
709 }
710
711
712 kfree(dai_data);
713 snd_soc_unregister_dai(dai->dev);
714
715 return 0;
716}
Kuirong Wang274f21a2011-12-15 21:29:08 -0800717static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
718{
719 struct msm_dai_q6_dai_data *dai_data;
720 int rc = 0;
721
722 dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data),
723 GFP_KERNEL);
724
725 if (!dai_data) {
726 dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
727 dai->id);
728 rc = -ENOMEM;
729 goto rtn;
730 } else
731 dev_set_drvdata(dai->dev, dai_data);
732
733 rc = msm_dai_q6_mi2s_platform_data_validation(dai);
734 if (rc != 0) {
735 pr_err("%s: The msm_dai_q6_mi2s_platform_data_validation failed\n",
736 __func__);
737 kfree(dai_data);
738 }
739rtn:
740 return rc;
741}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700742
743static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
744{
745 struct msm_dai_q6_dai_data *dai_data;
746 int rc = 0;
747
748 dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data),
749 GFP_KERNEL);
750
751 if (!dai_data) {
752 dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
753 dai->id);
754 rc = -ENOMEM;
755 } else
756 dev_set_drvdata(dai->dev, dai_data);
757
758 return rc;
759}
760
761static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai)
762{
763 struct msm_dai_q6_dai_data *dai_data;
764 int rc;
765
766 dai_data = dev_get_drvdata(dai->dev);
767
768 /* If AFE port is still up, close it */
769 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Helen Zeng0705a5f2011-10-14 15:29:52 -0700770 switch (dai->id) {
771 case VOICE_PLAYBACK_TX:
Helen Zenge3d716a2011-10-14 16:32:16 -0700772 case VOICE_RECORD_TX:
773 case VOICE_RECORD_RX:
Helen Zeng0705a5f2011-10-14 15:29:52 -0700774 pr_debug("%s, stop pseudo port:%d\n",
775 __func__, dai->id);
776 rc = afe_stop_pseudo_port(dai->id);
777 break;
778 default:
779 rc = afe_close(dai->id); /* can block */
780 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781 if (IS_ERR_VALUE(rc))
782 dev_err(dai->dev, "fail to close AFE port\n");
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530783 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700784 }
785 kfree(dai_data);
786 snd_soc_unregister_dai(dai->dev);
787
788 return 0;
789}
790
Lei Zhou157c1842011-08-19 13:05:04 -0400791static int msm_dai_q6_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
792{
793 int rc = 0;
794
795 dev_dbg(dai->dev, "enter %s, id = %d\n", __func__, dai->id);
796 switch (dai->id) {
797 case PRIMARY_I2S_TX:
798 case PRIMARY_I2S_RX:
Kuirong Wang274f21a2011-12-15 21:29:08 -0800799 case MI2S_RX:
Lei Zhou157c1842011-08-19 13:05:04 -0400800 rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
801 break;
802 default:
803 dev_err(dai->dev, "invalid cpu_dai set_fmt\n");
804 rc = -EINVAL;
805 break;
806 }
807
808 return rc;
809}
810
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700811static struct snd_soc_dai_ops msm_dai_q6_ops = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700812 .prepare = msm_dai_q6_prepare,
813 .trigger = msm_dai_q6_trigger,
814 .hw_params = msm_dai_q6_hw_params,
815 .shutdown = msm_dai_q6_shutdown,
Lei Zhou157c1842011-08-19 13:05:04 -0400816 .set_fmt = msm_dai_q6_set_fmt,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700817};
818
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -0700819static struct snd_soc_dai_ops msm_dai_q6_auxpcm_ops = {
820 .prepare = msm_dai_q6_auxpcm_prepare,
821 .trigger = msm_dai_q6_auxpcm_trigger,
822 .hw_params = msm_dai_q6_auxpcm_hw_params,
823 .shutdown = msm_dai_q6_auxpcm_shutdown,
824};
825
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700826static struct snd_soc_dai_driver msm_dai_q6_i2s_rx_dai = {
827 .playback = {
828 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
829 SNDRV_PCM_RATE_16000,
830 .formats = SNDRV_PCM_FMTBIT_S16_LE,
831 .channels_min = 1,
832 .channels_max = 2,
833 .rate_min = 8000,
834 .rate_max = 48000,
835 },
836 .ops = &msm_dai_q6_ops,
837 .probe = msm_dai_q6_dai_probe,
838 .remove = msm_dai_q6_dai_remove,
839};
840
841static struct snd_soc_dai_driver msm_dai_q6_i2s_tx_dai = {
842 .capture = {
843 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
844 SNDRV_PCM_RATE_16000,
845 .formats = SNDRV_PCM_FMTBIT_S16_LE,
846 .channels_min = 1,
847 .channels_max = 2,
848 .rate_min = 8000,
849 .rate_max = 48000,
850 },
851 .ops = &msm_dai_q6_ops,
852 .probe = msm_dai_q6_dai_probe,
853 .remove = msm_dai_q6_dai_remove,
854};
855
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530856static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai = {
857 .playback = {
858 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
859 SNDRV_PCM_RATE_16000,
860 .formats = SNDRV_PCM_FMTBIT_S16_LE,
861 .channels_min = 1,
862 .channels_max = 2,
863 .rate_min = 8000,
864 .rate_max = 48000,
865 },
866 .ops = &msm_dai_q6_ops,
867 .probe = msm_dai_q6_dai_probe,
868 .remove = msm_dai_q6_dai_remove,
869};
870
871static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai = {
872 .capture = {
873 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
874 SNDRV_PCM_RATE_16000,
875 .formats = SNDRV_PCM_FMTBIT_S16_LE,
876 .channels_min = 1,
877 .channels_max = 2,
878 .rate_min = 8000,
879 .rate_max = 48000,
880 },
881 .ops = &msm_dai_q6_ops,
882 .probe = msm_dai_q6_dai_probe,
883 .remove = msm_dai_q6_dai_remove,
884};
885
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700886static struct snd_soc_dai_driver msm_dai_q6_hdmi_rx_dai = {
887 .playback = {
888 .rates = SNDRV_PCM_RATE_48000,
889 .formats = SNDRV_PCM_FMTBIT_S16_LE,
890 .channels_min = 2,
891 .channels_max = 2,
892 .rate_max = 48000,
893 .rate_min = 48000,
894 },
895 .ops = &msm_dai_q6_ops,
896 .probe = msm_dai_q6_dai_probe,
897 .remove = msm_dai_q6_dai_remove,
898};
899
Helen Zeng0705a5f2011-10-14 15:29:52 -0700900static struct snd_soc_dai_driver msm_dai_q6_voice_playback_tx_dai = {
901 .playback = {
902 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
903 SNDRV_PCM_RATE_16000,
904 .formats = SNDRV_PCM_FMTBIT_S16_LE,
905 .channels_min = 1,
906 .channels_max = 2,
907 .rate_max = 48000,
908 .rate_min = 8000,
909 },
910 .ops = &msm_dai_q6_ops,
911 .probe = msm_dai_q6_dai_probe,
912 .remove = msm_dai_q6_dai_remove,
913};
914
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700915static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai = {
916 .playback = {
917 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
918 SNDRV_PCM_RATE_16000,
919 .formats = SNDRV_PCM_FMTBIT_S16_LE,
920 .channels_min = 1,
921 .channels_max = 2,
922 .rate_min = 8000,
923 .rate_max = 48000,
924 },
925 .ops = &msm_dai_q6_ops,
926 .probe = msm_dai_q6_dai_probe,
927 .remove = msm_dai_q6_dai_remove,
928};
929
930static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai = {
931 .capture = {
932 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
933 SNDRV_PCM_RATE_16000,
934 .formats = SNDRV_PCM_FMTBIT_S16_LE,
935 .channels_min = 1,
936 .channels_max = 2,
937 .rate_min = 8000,
938 .rate_max = 48000,
939 },
940 .ops = &msm_dai_q6_ops,
941 .probe = msm_dai_q6_dai_probe,
942 .remove = msm_dai_q6_dai_remove,
943};
944
Helen Zenge3d716a2011-10-14 16:32:16 -0700945static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai = {
946 .capture = {
947 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
948 SNDRV_PCM_RATE_16000,
949 .formats = SNDRV_PCM_FMTBIT_S16_LE,
950 .channels_min = 1,
951 .channels_max = 2,
952 .rate_min = 8000,
953 .rate_max = 48000,
954 },
955 .ops = &msm_dai_q6_ops,
956 .probe = msm_dai_q6_dai_probe,
957 .remove = msm_dai_q6_dai_remove,
958};
959
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700960static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = {
961 .playback = {
962 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
963 .formats = SNDRV_PCM_FMTBIT_S16_LE,
964 .channels_min = 1,
965 .channels_max = 1,
966 .rate_max = 16000,
967 .rate_min = 8000,
968 },
969 .ops = &msm_dai_q6_ops,
970 .probe = msm_dai_q6_dai_probe,
971 .remove = msm_dai_q6_dai_remove,
972};
973
974static struct snd_soc_dai_driver msm_dai_q6_bt_sco_tx_dai = {
975 .playback = {
976 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
977 .formats = SNDRV_PCM_FMTBIT_S16_LE,
978 .channels_min = 1,
979 .channels_max = 1,
980 .rate_max = 16000,
981 .rate_min = 8000,
982 },
983 .ops = &msm_dai_q6_ops,
984 .probe = msm_dai_q6_dai_probe,
985 .remove = msm_dai_q6_dai_remove,
986};
987
988static struct snd_soc_dai_driver msm_dai_q6_fm_rx_dai = {
989 .playback = {
990 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
991 SNDRV_PCM_RATE_16000,
992 .formats = SNDRV_PCM_FMTBIT_S16_LE,
993 .channels_min = 2,
994 .channels_max = 2,
995 .rate_max = 48000,
996 .rate_min = 8000,
997 },
998 .ops = &msm_dai_q6_ops,
999 .probe = msm_dai_q6_dai_probe,
1000 .remove = msm_dai_q6_dai_remove,
1001};
1002
1003static struct snd_soc_dai_driver msm_dai_q6_fm_tx_dai = {
1004 .playback = {
1005 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1006 SNDRV_PCM_RATE_16000,
1007 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1008 .channels_min = 2,
1009 .channels_max = 2,
1010 .rate_max = 48000,
1011 .rate_min = 8000,
1012 },
1013 .ops = &msm_dai_q6_ops,
1014 .probe = msm_dai_q6_dai_probe,
1015 .remove = msm_dai_q6_dai_remove,
1016};
1017
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001018static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_rx_dai = {
1019 .playback = {
1020 .rates = SNDRV_PCM_RATE_8000,
1021 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1022 .channels_min = 1,
1023 .channels_max = 1,
1024 .rate_max = 8000,
1025 .rate_min = 8000,
1026 },
1027 .ops = &msm_dai_q6_auxpcm_ops,
1028 .probe = msm_dai_q6_dai_auxpcm_probe,
1029 .remove = msm_dai_q6_dai_auxpcm_remove,
1030};
1031
1032static struct snd_soc_dai_driver msm_dai_q6_aux_pcm_tx_dai = {
1033 .capture = {
1034 .rates = SNDRV_PCM_RATE_8000,
1035 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1036 .channels_min = 1,
1037 .channels_max = 1,
1038 .rate_max = 8000,
1039 .rate_min = 8000,
1040 },
1041};
1042
Kuirong Wang274f21a2011-12-15 21:29:08 -08001043static struct snd_soc_dai_driver msm_dai_q6_mi2s_rx_dai = {
1044 .playback = {
1045 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1046 SNDRV_PCM_RATE_16000,
1047 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1048 .channels_min = 1,
1049 .rate_min = 8000,
1050 .rate_max = 48000,
1051 },
1052 .ops = &msm_dai_q6_ops,
1053 .probe = msm_dai_q6_dai_mi2s_probe,
1054 .remove = msm_dai_q6_dai_probe,
1055};
1056
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001057/* To do: change to register DAIs as batch */
1058static __devinit int msm_dai_q6_dev_probe(struct platform_device *pdev)
1059{
1060 int rc = 0;
1061
1062 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
1063
1064 switch (pdev->id) {
1065 case PRIMARY_I2S_RX:
1066 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
1067 break;
1068 case PRIMARY_I2S_TX:
1069 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_tx_dai);
1070 break;
Bhalchandra Gajare0e795c42011-08-15 18:10:30 -07001071 case PCM_RX:
1072 rc = snd_soc_register_dai(&pdev->dev,
1073 &msm_dai_q6_aux_pcm_rx_dai);
1074 break;
1075 case PCM_TX:
1076 rc = snd_soc_register_dai(&pdev->dev,
1077 &msm_dai_q6_aux_pcm_tx_dai);
1078 break;
Kuirong Wang274f21a2011-12-15 21:29:08 -08001079 case MI2S_RX:
1080 rc = snd_soc_register_dai(&pdev->dev,
1081 &msm_dai_q6_mi2s_rx_dai);
1082 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001083 case HDMI_RX:
1084 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_hdmi_rx_dai);
1085 break;
1086 case SLIMBUS_0_RX:
1087 rc = snd_soc_register_dai(&pdev->dev,
1088 &msm_dai_q6_slimbus_rx_dai);
1089 break;
1090 case SLIMBUS_0_TX:
1091 rc = snd_soc_register_dai(&pdev->dev,
1092 &msm_dai_q6_slimbus_tx_dai);
1093 case INT_BT_SCO_RX:
1094 rc = snd_soc_register_dai(&pdev->dev,
1095 &msm_dai_q6_bt_sco_rx_dai);
1096 break;
1097 case INT_BT_SCO_TX:
1098 rc = snd_soc_register_dai(&pdev->dev,
1099 &msm_dai_q6_bt_sco_tx_dai);
1100 break;
1101 case INT_FM_RX:
1102 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_fm_rx_dai);
1103 break;
1104 case INT_FM_TX:
1105 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_fm_tx_dai);
1106 break;
Laxminath Kasam32657ec2011-08-01 19:26:57 +05301107 case RT_PROXY_DAI_001_RX:
1108 case RT_PROXY_DAI_002_RX:
1109 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_rx_dai);
1110 break;
1111 case RT_PROXY_DAI_001_TX:
1112 case RT_PROXY_DAI_002_TX:
1113 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_tx_dai);
1114 break;
Helen Zeng0705a5f2011-10-14 15:29:52 -07001115 case VOICE_PLAYBACK_TX:
1116 rc = snd_soc_register_dai(&pdev->dev,
1117 &msm_dai_q6_voice_playback_tx_dai);
1118 break;
Helen Zenge3d716a2011-10-14 16:32:16 -07001119 case VOICE_RECORD_RX:
1120 case VOICE_RECORD_TX:
1121 rc = snd_soc_register_dai(&pdev->dev,
1122 &msm_dai_q6_incall_record_dai);
1123 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001124 default:
1125 rc = -ENODEV;
1126 break;
1127 }
1128 return rc;
1129}
1130
1131static __devexit int msm_dai_q6_dev_remove(struct platform_device *pdev)
1132{
1133 snd_soc_unregister_dai(&pdev->dev);
1134 return 0;
1135}
1136
1137static struct platform_driver msm_dai_q6_driver = {
1138 .probe = msm_dai_q6_dev_probe,
1139 .remove = msm_dai_q6_dev_remove,
1140 .driver = {
1141 .name = "msm-dai-q6",
1142 .owner = THIS_MODULE,
1143 },
1144};
1145
1146static int __init msm_dai_q6_init(void)
1147{
1148 return platform_driver_register(&msm_dai_q6_driver);
1149}
1150module_init(msm_dai_q6_init);
1151
1152static void __exit msm_dai_q6_exit(void)
1153{
1154 platform_driver_unregister(&msm_dai_q6_driver);
1155}
1156module_exit(msm_dai_q6_exit);
1157
1158/* Module information */
1159MODULE_DESCRIPTION("MSM DSP DAI driver");
1160MODULE_LICENSE("GPL v2");