blob: 400c82f8eed297a6fa22f5dc8bc9c02083b9a201 [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>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/soc.h>
23#include <sound/apr_audio.h>
24#include <sound/q6afe.h>
25#include <sound/q6adm.h>
26
27enum {
28 STATUS_PORT_STARTED, /* track if AFE port has started */
29 STATUS_MAX
30};
31
32struct msm_dai_q6_dai_data {
33 DECLARE_BITMAP(status_mask, STATUS_MAX);
34 u32 rate;
35 u32 channels;
36 union afe_port_config port_config;
37};
38
39static int msm_dai_q6_cdc_hw_params(struct snd_pcm_hw_params *params,
40 struct snd_soc_dai *dai, int stream)
41{
42 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
43
44 dai_data->channels = params_channels(params);
45 switch (dai_data->channels) {
46 case 2:
47 dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
48 break;
49 case 1:
50 dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
51 break;
52 default:
53 return -EINVAL;
54 break;
55 }
56 dai_data->rate = params_rate(params);
57
58 dev_dbg(dai->dev, " channel %d sample rate %d entered\n",
59 dai_data->channels, dai_data->rate);
60
61 /* Q6 only supports 16 as now */
62 dai_data->port_config.mi2s.bitwidth = 16;
63 dai_data->port_config.mi2s.line = 1;
64 dai_data->port_config.mi2s.ws = 1; /* I2S master mode for now */
65
66 return 0;
67}
68
69static int msm_dai_q6_hdmi_hw_params(struct snd_pcm_hw_params *params,
70 struct snd_soc_dai *dai)
71{
72 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
73
74 dev_dbg(dai->dev, "%s start HDMI port\n", __func__);
75
76 dai_data->channels = params_channels(params);
77 switch (dai_data->channels) {
78 case 2:
79 dai_data->port_config.hdmi.channel_mode = 0; /* Put in macro */
80 break;
81 default:
82 return -EINVAL;
83 break;
84 }
85
86 /* Q6 only supports 16 as now */
87 dai_data->port_config.hdmi.bitwidth = 16;
88 dai_data->port_config.hdmi.data_type = 0;
89 dai_data->rate = params_rate(params);
90
91 return 0;
92}
93
94static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params,
95 struct snd_soc_dai *dai, int stream)
96{
97 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
98 u8 pgd_la, inf_la;
99
100 memset(dai_data->port_config.slimbus.slave_port_mapping, 0,
101 sizeof(dai_data->port_config.slimbus.slave_port_mapping));
102
103 dai_data->channels = params_channels(params);
104 switch (dai_data->channels) {
105 case 2:
106 if (dai->id == SLIMBUS_0_RX) {
107 dai_data->port_config.slimbus.slave_port_mapping[0] = 1;
108 dai_data->port_config.slimbus.slave_port_mapping[1] = 2;
109 } else {
110 dai_data->port_config.slimbus.slave_port_mapping[0] = 7;
111 dai_data->port_config.slimbus.slave_port_mapping[1] = 8;
112 }
113 break;
114 case 1:
115 if (dai->id == SLIMBUS_0_RX)
116 dai_data->port_config.slimbus.slave_port_mapping[0] = 1;
117 else
118 dai_data->port_config.slimbus.slave_port_mapping[0] = 7;
119 break;
120 default:
121 return -EINVAL;
122 break;
123 }
124 dai_data->rate = params_rate(params);
125 tabla_get_logical_addresses(&pgd_la, &inf_la);
126
127 dai_data->port_config.slimbus.slimbus_dev_id = AFE_SLIMBUS_DEVICE_1;
128 dai_data->port_config.slimbus.slave_dev_pgd_la = pgd_la;
129 dai_data->port_config.slimbus.slave_dev_intfdev_la = inf_la;
130 /* Q6 only supports 16 as now */
131 dai_data->port_config.slimbus.bit_width = 16;
132 dai_data->port_config.slimbus.data_format = 0;
133 dai_data->port_config.slimbus.num_channels = dai_data->channels;
134 dai_data->port_config.slimbus.reserved = 0;
135
136 dev_dbg(dai->dev, "slimbus_dev_id %hu slave_dev_pgd_la 0x%hx\n"
137 "slave_dev_intfdev_la 0x%hx bit_width %hu data_format %hu\n"
138 "num_channel %hu slave_port_mapping[0] %hu\n"
139 "slave_port_mapping[1] %hu slave_port_mapping[2] %hu\n"
140 "sample_rate %d\n",
141 dai_data->port_config.slimbus.slimbus_dev_id,
142 dai_data->port_config.slimbus.slave_dev_pgd_la,
143 dai_data->port_config.slimbus.slave_dev_intfdev_la,
144 dai_data->port_config.slimbus.bit_width,
145 dai_data->port_config.slimbus.data_format,
146 dai_data->port_config.slimbus.num_channels,
147 dai_data->port_config.slimbus.slave_port_mapping[0],
148 dai_data->port_config.slimbus.slave_port_mapping[1],
149 dai_data->port_config.slimbus.slave_port_mapping[2],
150 dai_data->rate);
151
152 return 0;
153}
154
155static int msm_dai_q6_bt_fm_hw_params(struct snd_pcm_hw_params *params,
156 struct snd_soc_dai *dai, int stream)
157{
158 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
159
160 dai_data->channels = params_channels(params);
161 dai_data->rate = params_rate(params);
162
163 dev_dbg(dai->dev, "channels %d sample rate %d entered\n",
164 dai_data->channels, dai_data->rate);
165
166 memset(&dai_data->port_config, 0, sizeof(dai_data->port_config));
167
168 return 0;
169}
170
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530171static int get_frame_size(u16 rate, u16 ch)
172{
173 if (rate == 8000) {
174 if (ch == 1)
175 return 128 * 2;
176 else
177 return 128 * 2 * 2;
178 } else if (rate == 16000) {
179 if (ch == 1)
180 return 128 * 2 * 2;
181 else
182 return 128 * 2 * 4;
183 } else if (rate == 48000) {
184 if (ch == 1)
185 return 128 * 2 * 6;
186 else
187 return 128 * 2 * 12;
188 } else
189 return 128 * 2 * 12;
190}
191
192static int msm_dai_q6_afe_rtproxy_hw_params(struct snd_pcm_hw_params *params,
193 struct snd_soc_dai *dai)
194{
195 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
196
197 dai_data->rate = params_rate(params);
198 dai_data->port_config.rtproxy.num_ch =
199 params_channels(params);
200
201 pr_debug("channel %d entered,dai_id: %d,rate: %d\n",
202 dai_data->port_config.rtproxy.num_ch, dai->id, dai_data->rate);
203
204 dai_data->port_config.rtproxy.bitwidth = 16; /* Q6 only supports 16 */
205 dai_data->port_config.rtproxy.interleaved = 1;
206 dai_data->port_config.rtproxy.frame_sz = get_frame_size(dai_data->rate,
207 dai_data->port_config.rtproxy.num_ch);
208 dai_data->port_config.rtproxy.jitter =
209 dai_data->port_config.rtproxy.frame_sz/2;
210 dai_data->port_config.rtproxy.lw_mark = 0;
211 dai_data->port_config.rtproxy.hw_mark = 0;
212 dai_data->port_config.rtproxy.rsvd = 0;
213
214 return 0;
215}
216
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700217/* Current implementation assumes hw_param is called once
218 * This may not be the case but what to do when ADM and AFE
219 * port are already opened and parameter changes
220 */
221static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai)
224{
225 int rc = 0;
226
227 switch (dai->id) {
228 case PRIMARY_I2S_TX:
229 case PRIMARY_I2S_RX:
230 rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
231 break;
232 case HDMI_RX:
233 rc = msm_dai_q6_hdmi_hw_params(params, dai);
234 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700235 case SLIMBUS_0_RX:
236 case SLIMBUS_0_TX:
237 rc = msm_dai_q6_slim_bus_hw_params(params, dai,
238 substream->stream);
239 break;
240 case INT_BT_SCO_RX:
241 case INT_BT_SCO_TX:
242 case INT_FM_RX:
243 case INT_FM_TX:
244 rc = msm_dai_q6_bt_fm_hw_params(params, dai, substream->stream);
245 break;
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530246 case RT_PROXY_DAI_001_TX:
247 case RT_PROXY_DAI_001_RX:
248 case RT_PROXY_DAI_002_TX:
249 case RT_PROXY_DAI_002_RX:
250 rc = msm_dai_q6_afe_rtproxy_hw_params(params, dai);
251 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252 default:
253 dev_err(dai->dev, "invalid AFE port ID\n");
254 rc = -EINVAL;
255 break;
256 }
257
258 return rc;
259}
260
261static void msm_dai_q6_shutdown(struct snd_pcm_substream *substream,
262 struct snd_soc_dai *dai)
263{
264 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530265 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700266
267 rc = adm_close(dai->id);
268
269 if (IS_ERR_VALUE(rc))
270 dev_err(dai->dev, "fail to close ADM COPP\n");
271
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530272 pr_debug("%s: dai->id = %d", __func__, dai->id);
273
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700274 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
275 rc = afe_close(dai->id); /* can block */
276 if (IS_ERR_VALUE(rc))
277 dev_err(dai->dev, "fail to close AFE port\n");
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530278 pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
279 *dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
281 }
282};
283
284static int msm_dai_q6_prepare(struct snd_pcm_substream *substream,
285 struct snd_soc_dai *dai)
286{
287 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
288 int rc = 0;
289
Patrick Lai831561e2011-07-26 22:51:27 -0700290 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
292 rc = adm_open_mixer(dai->id, 1, dai_data->rate,
293 dai_data->channels, DEFAULT_COPP_TOPOLOGY);
294 else
295 rc = adm_open_mixer(dai->id, 2, dai_data->rate,
296 dai_data->channels, DEFAULT_COPP_TOPOLOGY);
297 if (IS_ERR_VALUE(rc))
298 dev_err(dai->dev, "fail to open ADM\n");
Jay Wang6a305432011-08-05 16:01:54 -0700299 else {
300 rc = afe_q6_interface_prepare();
301 if (IS_ERR_VALUE(rc))
302 dev_err(dai->dev, "fail to open AFE APR\n");
303 }
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530304 pr_debug("%s:dai->id:%d dai_data->status_mask = %ld\n",
305 __func__, dai->id, *dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700306 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700308}
309
310static int msm_dai_q6_trigger(struct snd_pcm_substream *substream, int cmd,
311 struct snd_soc_dai *dai)
312{
313 struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
314 int rc = 0;
315
316 /* Start/stop port without waiting for Q6 AFE response. Need to have
317 * native q6 AFE driver propagates AFE response in order to handle
318 * port start/stop command error properly if error does arise.
319 */
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530320 pr_debug("%s:port:%d cmd:%d dai_data->status_mask = %ld",
321 __func__, dai->id, cmd, *dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700322 switch (cmd) {
323 case SNDRV_PCM_TRIGGER_START:
324 case SNDRV_PCM_TRIGGER_RESUME:
325 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
326 if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
327 afe_port_start_nowait(dai->id, &dai_data->port_config,
328 dai_data->rate);
329 set_bit(STATUS_PORT_STARTED,
330 dai_data->status_mask);
331 }
332 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333 case SNDRV_PCM_TRIGGER_STOP:
334 case SNDRV_PCM_TRIGGER_SUSPEND:
335 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
336 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
337 afe_port_stop_nowait(dai->id);
338 clear_bit(STATUS_PORT_STARTED,
339 dai_data->status_mask);
340 }
341 break;
342
343 default:
344 rc = -EINVAL;
345 }
346
347 return rc;
348}
349
350static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
351{
352 struct msm_dai_q6_dai_data *dai_data;
353 int rc = 0;
354
355 dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data),
356 GFP_KERNEL);
357
358 if (!dai_data) {
359 dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
360 dai->id);
361 rc = -ENOMEM;
362 } else
363 dev_set_drvdata(dai->dev, dai_data);
364
365 return rc;
366}
367
368static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai)
369{
370 struct msm_dai_q6_dai_data *dai_data;
371 int rc;
372
373 dai_data = dev_get_drvdata(dai->dev);
374
375 /* If AFE port is still up, close it */
376 if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
377 rc = afe_close(dai->id); /* can block */
378 if (IS_ERR_VALUE(rc))
379 dev_err(dai->dev, "fail to close AFE port\n");
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530380 clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381 }
382 kfree(dai_data);
383 snd_soc_unregister_dai(dai->dev);
384
385 return 0;
386}
387
388static struct snd_soc_dai_ops msm_dai_q6_ops = {
389 /*
390 * DSP only handles 16-bit and support only I2S
391 * master mode for now. leave set_fmt function
392 * unimplemented for now.
393 */
394 .prepare = msm_dai_q6_prepare,
395 .trigger = msm_dai_q6_trigger,
396 .hw_params = msm_dai_q6_hw_params,
397 .shutdown = msm_dai_q6_shutdown,
398};
399
400static struct snd_soc_dai_driver msm_dai_q6_i2s_rx_dai = {
401 .playback = {
402 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
403 SNDRV_PCM_RATE_16000,
404 .formats = SNDRV_PCM_FMTBIT_S16_LE,
405 .channels_min = 1,
406 .channels_max = 2,
407 .rate_min = 8000,
408 .rate_max = 48000,
409 },
410 .ops = &msm_dai_q6_ops,
411 .probe = msm_dai_q6_dai_probe,
412 .remove = msm_dai_q6_dai_remove,
413};
414
415static struct snd_soc_dai_driver msm_dai_q6_i2s_tx_dai = {
416 .capture = {
417 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
418 SNDRV_PCM_RATE_16000,
419 .formats = SNDRV_PCM_FMTBIT_S16_LE,
420 .channels_min = 1,
421 .channels_max = 2,
422 .rate_min = 8000,
423 .rate_max = 48000,
424 },
425 .ops = &msm_dai_q6_ops,
426 .probe = msm_dai_q6_dai_probe,
427 .remove = msm_dai_q6_dai_remove,
428};
429
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530430static struct snd_soc_dai_driver msm_dai_q6_afe_rx_dai = {
431 .playback = {
432 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
433 SNDRV_PCM_RATE_16000,
434 .formats = SNDRV_PCM_FMTBIT_S16_LE,
435 .channels_min = 1,
436 .channels_max = 2,
437 .rate_min = 8000,
438 .rate_max = 48000,
439 },
440 .ops = &msm_dai_q6_ops,
441 .probe = msm_dai_q6_dai_probe,
442 .remove = msm_dai_q6_dai_remove,
443};
444
445static struct snd_soc_dai_driver msm_dai_q6_afe_tx_dai = {
446 .capture = {
447 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
448 SNDRV_PCM_RATE_16000,
449 .formats = SNDRV_PCM_FMTBIT_S16_LE,
450 .channels_min = 1,
451 .channels_max = 2,
452 .rate_min = 8000,
453 .rate_max = 48000,
454 },
455 .ops = &msm_dai_q6_ops,
456 .probe = msm_dai_q6_dai_probe,
457 .remove = msm_dai_q6_dai_remove,
458};
459
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700460static struct snd_soc_dai_driver msm_dai_q6_hdmi_rx_dai = {
461 .playback = {
462 .rates = SNDRV_PCM_RATE_48000,
463 .formats = SNDRV_PCM_FMTBIT_S16_LE,
464 .channels_min = 2,
465 .channels_max = 2,
466 .rate_max = 48000,
467 .rate_min = 48000,
468 },
469 .ops = &msm_dai_q6_ops,
470 .probe = msm_dai_q6_dai_probe,
471 .remove = msm_dai_q6_dai_remove,
472};
473
474static struct snd_soc_dai_driver msm_dai_q6_slimbus_rx_dai = {
475 .playback = {
476 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
477 SNDRV_PCM_RATE_16000,
478 .formats = SNDRV_PCM_FMTBIT_S16_LE,
479 .channels_min = 1,
480 .channels_max = 2,
481 .rate_min = 8000,
482 .rate_max = 48000,
483 },
484 .ops = &msm_dai_q6_ops,
485 .probe = msm_dai_q6_dai_probe,
486 .remove = msm_dai_q6_dai_remove,
487};
488
489static struct snd_soc_dai_driver msm_dai_q6_slimbus_tx_dai = {
490 .capture = {
491 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
492 SNDRV_PCM_RATE_16000,
493 .formats = SNDRV_PCM_FMTBIT_S16_LE,
494 .channels_min = 1,
495 .channels_max = 2,
496 .rate_min = 8000,
497 .rate_max = 48000,
498 },
499 .ops = &msm_dai_q6_ops,
500 .probe = msm_dai_q6_dai_probe,
501 .remove = msm_dai_q6_dai_remove,
502};
503
504static struct snd_soc_dai_driver msm_dai_q6_bt_sco_rx_dai = {
505 .playback = {
506 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
507 .formats = SNDRV_PCM_FMTBIT_S16_LE,
508 .channels_min = 1,
509 .channels_max = 1,
510 .rate_max = 16000,
511 .rate_min = 8000,
512 },
513 .ops = &msm_dai_q6_ops,
514 .probe = msm_dai_q6_dai_probe,
515 .remove = msm_dai_q6_dai_remove,
516};
517
518static struct snd_soc_dai_driver msm_dai_q6_bt_sco_tx_dai = {
519 .playback = {
520 .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
521 .formats = SNDRV_PCM_FMTBIT_S16_LE,
522 .channels_min = 1,
523 .channels_max = 1,
524 .rate_max = 16000,
525 .rate_min = 8000,
526 },
527 .ops = &msm_dai_q6_ops,
528 .probe = msm_dai_q6_dai_probe,
529 .remove = msm_dai_q6_dai_remove,
530};
531
532static struct snd_soc_dai_driver msm_dai_q6_fm_rx_dai = {
533 .playback = {
534 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
535 SNDRV_PCM_RATE_16000,
536 .formats = SNDRV_PCM_FMTBIT_S16_LE,
537 .channels_min = 2,
538 .channels_max = 2,
539 .rate_max = 48000,
540 .rate_min = 8000,
541 },
542 .ops = &msm_dai_q6_ops,
543 .probe = msm_dai_q6_dai_probe,
544 .remove = msm_dai_q6_dai_remove,
545};
546
547static struct snd_soc_dai_driver msm_dai_q6_fm_tx_dai = {
548 .playback = {
549 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
550 SNDRV_PCM_RATE_16000,
551 .formats = SNDRV_PCM_FMTBIT_S16_LE,
552 .channels_min = 2,
553 .channels_max = 2,
554 .rate_max = 48000,
555 .rate_min = 8000,
556 },
557 .ops = &msm_dai_q6_ops,
558 .probe = msm_dai_q6_dai_probe,
559 .remove = msm_dai_q6_dai_remove,
560};
561
562/* To do: change to register DAIs as batch */
563static __devinit int msm_dai_q6_dev_probe(struct platform_device *pdev)
564{
565 int rc = 0;
566
567 dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
568
569 switch (pdev->id) {
570 case PRIMARY_I2S_RX:
571 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
572 break;
573 case PRIMARY_I2S_TX:
574 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_tx_dai);
575 break;
576 case HDMI_RX:
577 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_hdmi_rx_dai);
578 break;
579 case SLIMBUS_0_RX:
580 rc = snd_soc_register_dai(&pdev->dev,
581 &msm_dai_q6_slimbus_rx_dai);
582 break;
583 case SLIMBUS_0_TX:
584 rc = snd_soc_register_dai(&pdev->dev,
585 &msm_dai_q6_slimbus_tx_dai);
586 case INT_BT_SCO_RX:
587 rc = snd_soc_register_dai(&pdev->dev,
588 &msm_dai_q6_bt_sco_rx_dai);
589 break;
590 case INT_BT_SCO_TX:
591 rc = snd_soc_register_dai(&pdev->dev,
592 &msm_dai_q6_bt_sco_tx_dai);
593 break;
594 case INT_FM_RX:
595 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_fm_rx_dai);
596 break;
597 case INT_FM_TX:
598 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_fm_tx_dai);
599 break;
Laxminath Kasam32657ec2011-08-01 19:26:57 +0530600 case RT_PROXY_DAI_001_RX:
601 case RT_PROXY_DAI_002_RX:
602 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_rx_dai);
603 break;
604 case RT_PROXY_DAI_001_TX:
605 case RT_PROXY_DAI_002_TX:
606 rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_afe_tx_dai);
607 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700608 default:
609 rc = -ENODEV;
610 break;
611 }
612 return rc;
613}
614
615static __devexit int msm_dai_q6_dev_remove(struct platform_device *pdev)
616{
617 snd_soc_unregister_dai(&pdev->dev);
618 return 0;
619}
620
621static struct platform_driver msm_dai_q6_driver = {
622 .probe = msm_dai_q6_dev_probe,
623 .remove = msm_dai_q6_dev_remove,
624 .driver = {
625 .name = "msm-dai-q6",
626 .owner = THIS_MODULE,
627 },
628};
629
630static int __init msm_dai_q6_init(void)
631{
632 return platform_driver_register(&msm_dai_q6_driver);
633}
634module_init(msm_dai_q6_init);
635
636static void __exit msm_dai_q6_exit(void)
637{
638 platform_driver_unregister(&msm_dai_q6_driver);
639}
640module_exit(msm_dai_q6_exit);
641
642/* Module information */
643MODULE_DESCRIPTION("MSM DSP DAI driver");
644MODULE_LICENSE("GPL v2");