ASoC: msm8916-wcd-analog: Update correct register setting for MIC BIAS Internal1
[sfrench/cifs-2.6.git] / sound / soc / qcom / lpass-platform.c
1 /*
2  * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 and
6  * only version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * lpass-platform.c -- ALSA SoC platform driver for QTi LPASS
14  */
15
16 #include <linux/dma-mapping.h>
17 #include <linux/export.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <sound/pcm_params.h>
22 #include <linux/regmap.h>
23 #include <sound/soc.h>
24 #include "lpass-lpaif-reg.h"
25 #include "lpass.h"
26
27 struct lpass_pcm_data {
28         int dma_ch;
29         int i2s_port;
30 };
31
32 #define LPASS_PLATFORM_BUFFER_SIZE      (16 * 1024)
33 #define LPASS_PLATFORM_PERIODS          2
34
35 static struct snd_pcm_hardware lpass_platform_pcm_hardware = {
36         .info                   =       SNDRV_PCM_INFO_MMAP |
37                                         SNDRV_PCM_INFO_MMAP_VALID |
38                                         SNDRV_PCM_INFO_INTERLEAVED |
39                                         SNDRV_PCM_INFO_PAUSE |
40                                         SNDRV_PCM_INFO_RESUME,
41         .formats                =       SNDRV_PCM_FMTBIT_S16 |
42                                         SNDRV_PCM_FMTBIT_S24 |
43                                         SNDRV_PCM_FMTBIT_S32,
44         .rates                  =       SNDRV_PCM_RATE_8000_192000,
45         .rate_min               =       8000,
46         .rate_max               =       192000,
47         .channels_min           =       1,
48         .channels_max           =       8,
49         .buffer_bytes_max       =       LPASS_PLATFORM_BUFFER_SIZE,
50         .period_bytes_max       =       LPASS_PLATFORM_BUFFER_SIZE /
51                                                 LPASS_PLATFORM_PERIODS,
52         .period_bytes_min       =       LPASS_PLATFORM_BUFFER_SIZE /
53                                                 LPASS_PLATFORM_PERIODS,
54         .periods_min            =       LPASS_PLATFORM_PERIODS,
55         .periods_max            =       LPASS_PLATFORM_PERIODS,
56         .fifo_size              =       0,
57 };
58
59 static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
60 {
61         struct snd_pcm_runtime *runtime = substream->runtime;
62         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
63         struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
64         struct lpass_data *drvdata =
65                 snd_soc_platform_get_drvdata(soc_runtime->platform);
66         struct lpass_variant *v = drvdata->variant;
67         int ret, dma_ch, dir = substream->stream;
68         struct lpass_pcm_data *data;
69
70         data = devm_kzalloc(soc_runtime->dev, sizeof(*data), GFP_KERNEL);
71         if (!data)
72                 return -ENOMEM;
73
74         data->i2s_port = cpu_dai->driver->id;
75         runtime->private_data = data;
76
77         if (v->alloc_dma_channel)
78                 dma_ch = v->alloc_dma_channel(drvdata, dir);
79         if (dma_ch < 0)
80                 return dma_ch;
81
82         drvdata->substream[dma_ch] = substream;
83
84         ret = regmap_write(drvdata->lpaif_map,
85                         LPAIF_DMACTL_REG(v, dma_ch, dir), 0);
86         if (ret) {
87                 dev_err(soc_runtime->dev,
88                         "%s() error writing to rdmactl reg: %d\n",
89                         __func__, ret);
90                         return ret;
91         }
92
93         data->dma_ch = dma_ch;
94
95         snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);
96
97         runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max;
98
99         ret = snd_pcm_hw_constraint_integer(runtime,
100                         SNDRV_PCM_HW_PARAM_PERIODS);
101         if (ret < 0) {
102                 dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n",
103                                 __func__, ret);
104                 return -EINVAL;
105         }
106
107         snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
108
109         return 0;
110 }
111
112 static int lpass_platform_pcmops_close(struct snd_pcm_substream *substream)
113 {
114         struct snd_pcm_runtime *runtime = substream->runtime;
115         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
116         struct lpass_data *drvdata =
117                 snd_soc_platform_get_drvdata(soc_runtime->platform);
118         struct lpass_variant *v = drvdata->variant;
119         struct lpass_pcm_data *data;
120
121         data = runtime->private_data;
122         v = drvdata->variant;
123         drvdata->substream[data->dma_ch] = NULL;
124         if (v->free_dma_channel)
125                 v->free_dma_channel(drvdata, data->dma_ch);
126
127         return 0;
128 }
129
130 static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
131                 struct snd_pcm_hw_params *params)
132 {
133         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
134         struct lpass_data *drvdata =
135                 snd_soc_platform_get_drvdata(soc_runtime->platform);
136         struct snd_pcm_runtime *rt = substream->runtime;
137         struct lpass_pcm_data *pcm_data = rt->private_data;
138         struct lpass_variant *v = drvdata->variant;
139         snd_pcm_format_t format = params_format(params);
140         unsigned int channels = params_channels(params);
141         unsigned int regval;
142         int ch, dir = substream->stream;
143         int bitwidth;
144         int ret, dma_port = pcm_data->i2s_port + v->dmactl_audif_start;
145
146         ch = pcm_data->dma_ch;
147
148         bitwidth = snd_pcm_format_width(format);
149         if (bitwidth < 0) {
150                 dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n",
151                                 __func__, bitwidth);
152                 return bitwidth;
153         }
154
155         regval = LPAIF_DMACTL_BURSTEN_INCR4 |
156                         LPAIF_DMACTL_AUDINTF(dma_port) |
157                         LPAIF_DMACTL_FIFOWM_8;
158
159         switch (bitwidth) {
160         case 16:
161                 switch (channels) {
162                 case 1:
163                 case 2:
164                         regval |= LPAIF_DMACTL_WPSCNT_ONE;
165                         break;
166                 case 4:
167                         regval |= LPAIF_DMACTL_WPSCNT_TWO;
168                         break;
169                 case 6:
170                         regval |= LPAIF_DMACTL_WPSCNT_THREE;
171                         break;
172                 case 8:
173                         regval |= LPAIF_DMACTL_WPSCNT_FOUR;
174                         break;
175                 default:
176                         dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
177                                         __func__, bitwidth, channels);
178                         return -EINVAL;
179                 }
180                 break;
181         case 24:
182         case 32:
183                 switch (channels) {
184                 case 1:
185                         regval |= LPAIF_DMACTL_WPSCNT_ONE;
186                         break;
187                 case 2:
188                         regval |= LPAIF_DMACTL_WPSCNT_TWO;
189                         break;
190                 case 4:
191                         regval |= LPAIF_DMACTL_WPSCNT_FOUR;
192                         break;
193                 case 6:
194                         regval |= LPAIF_DMACTL_WPSCNT_SIX;
195                         break;
196                 case 8:
197                         regval |= LPAIF_DMACTL_WPSCNT_EIGHT;
198                         break;
199                 default:
200                         dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
201                                         __func__, bitwidth, channels);
202                         return -EINVAL;
203                 }
204                 break;
205         default:
206                 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
207                                 __func__, bitwidth, channels);
208                 return -EINVAL;
209         }
210
211         ret = regmap_write(drvdata->lpaif_map,
212                         LPAIF_DMACTL_REG(v, ch, dir), regval);
213         if (ret) {
214                 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
215                                 __func__, ret);
216                 return ret;
217         }
218
219         return 0;
220 }
221
222 static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
223 {
224         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
225         struct lpass_data *drvdata =
226                 snd_soc_platform_get_drvdata(soc_runtime->platform);
227         struct snd_pcm_runtime *rt = substream->runtime;
228         struct lpass_pcm_data *pcm_data = rt->private_data;
229         struct lpass_variant *v = drvdata->variant;
230         unsigned int reg;
231         int ret;
232
233         reg = LPAIF_DMACTL_REG(v, pcm_data->dma_ch, substream->stream);
234         ret = regmap_write(drvdata->lpaif_map, reg, 0);
235         if (ret)
236                 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
237                                 __func__, ret);
238
239         return ret;
240 }
241
242 static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
243 {
244         struct snd_pcm_runtime *runtime = substream->runtime;
245         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
246         struct lpass_data *drvdata =
247                 snd_soc_platform_get_drvdata(soc_runtime->platform);
248         struct snd_pcm_runtime *rt = substream->runtime;
249         struct lpass_pcm_data *pcm_data = rt->private_data;
250         struct lpass_variant *v = drvdata->variant;
251         int ret, ch, dir = substream->stream;
252
253         ch = pcm_data->dma_ch;
254
255         ret = regmap_write(drvdata->lpaif_map,
256                         LPAIF_DMABASE_REG(v, ch, dir),
257                         runtime->dma_addr);
258         if (ret) {
259                 dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n",
260                                 __func__, ret);
261                 return ret;
262         }
263
264         ret = regmap_write(drvdata->lpaif_map,
265                         LPAIF_DMABUFF_REG(v, ch, dir),
266                         (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1);
267         if (ret) {
268                 dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n",
269                                 __func__, ret);
270                 return ret;
271         }
272
273         ret = regmap_write(drvdata->lpaif_map,
274                         LPAIF_DMAPER_REG(v, ch, dir),
275                         (snd_pcm_lib_period_bytes(substream) >> 2) - 1);
276         if (ret) {
277                 dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n",
278                                 __func__, ret);
279                 return ret;
280         }
281
282         ret = regmap_update_bits(drvdata->lpaif_map,
283                         LPAIF_DMACTL_REG(v, ch, dir),
284                         LPAIF_DMACTL_ENABLE_MASK, LPAIF_DMACTL_ENABLE_ON);
285         if (ret) {
286                 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
287                                 __func__, ret);
288                 return ret;
289         }
290
291         return 0;
292 }
293
294 static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
295                 int cmd)
296 {
297         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
298         struct lpass_data *drvdata =
299                 snd_soc_platform_get_drvdata(soc_runtime->platform);
300         struct snd_pcm_runtime *rt = substream->runtime;
301         struct lpass_pcm_data *pcm_data = rt->private_data;
302         struct lpass_variant *v = drvdata->variant;
303         int ret, ch, dir = substream->stream;
304
305         ch = pcm_data->dma_ch;
306
307         switch (cmd) {
308         case SNDRV_PCM_TRIGGER_START:
309         case SNDRV_PCM_TRIGGER_RESUME:
310         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
311                 /* clear status before enabling interrupts */
312                 ret = regmap_write(drvdata->lpaif_map,
313                                 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST),
314                                 LPAIF_IRQ_ALL(ch));
315                 if (ret) {
316                         dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
317                                         __func__, ret);
318                         return ret;
319                 }
320
321                 ret = regmap_update_bits(drvdata->lpaif_map,
322                                 LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST),
323                                 LPAIF_IRQ_ALL(ch),
324                                 LPAIF_IRQ_ALL(ch));
325                 if (ret) {
326                         dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
327                                         __func__, ret);
328                         return ret;
329                 }
330
331                 ret = regmap_update_bits(drvdata->lpaif_map,
332                                 LPAIF_DMACTL_REG(v, ch, dir),
333                                 LPAIF_DMACTL_ENABLE_MASK,
334                                 LPAIF_DMACTL_ENABLE_ON);
335                 if (ret) {
336                         dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
337                                         __func__, ret);
338                         return ret;
339                 }
340                 break;
341         case SNDRV_PCM_TRIGGER_STOP:
342         case SNDRV_PCM_TRIGGER_SUSPEND:
343         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
344                 ret = regmap_update_bits(drvdata->lpaif_map,
345                                 LPAIF_DMACTL_REG(v, ch, dir),
346                                 LPAIF_DMACTL_ENABLE_MASK,
347                                 LPAIF_DMACTL_ENABLE_OFF);
348                 if (ret) {
349                         dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
350                                         __func__, ret);
351                         return ret;
352                 }
353
354                 ret = regmap_update_bits(drvdata->lpaif_map,
355                                 LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST),
356                                 LPAIF_IRQ_ALL(ch), 0);
357                 if (ret) {
358                         dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
359                                         __func__, ret);
360                         return ret;
361                 }
362                 break;
363         }
364
365         return 0;
366 }
367
368 static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
369                 struct snd_pcm_substream *substream)
370 {
371         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
372         struct lpass_data *drvdata =
373                         snd_soc_platform_get_drvdata(soc_runtime->platform);
374         struct snd_pcm_runtime *rt = substream->runtime;
375         struct lpass_pcm_data *pcm_data = rt->private_data;
376         struct lpass_variant *v = drvdata->variant;
377         unsigned int base_addr, curr_addr;
378         int ret, ch, dir = substream->stream;
379
380         ch = pcm_data->dma_ch;
381
382         ret = regmap_read(drvdata->lpaif_map,
383                         LPAIF_DMABASE_REG(v, ch, dir), &base_addr);
384         if (ret) {
385                 dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n",
386                                 __func__, ret);
387                 return ret;
388         }
389
390         ret = regmap_read(drvdata->lpaif_map,
391                         LPAIF_DMACURR_REG(v, ch, dir), &curr_addr);
392         if (ret) {
393                 dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n",
394                                 __func__, ret);
395                 return ret;
396         }
397
398         return bytes_to_frames(substream->runtime, curr_addr - base_addr);
399 }
400
401 static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
402                 struct vm_area_struct *vma)
403 {
404         struct snd_pcm_runtime *runtime = substream->runtime;
405
406         return dma_mmap_coherent(substream->pcm->card->dev, vma,
407                         runtime->dma_area, runtime->dma_addr,
408                         runtime->dma_bytes);
409 }
410
411 static const struct snd_pcm_ops lpass_platform_pcm_ops = {
412         .open           = lpass_platform_pcmops_open,
413         .close          = lpass_platform_pcmops_close,
414         .ioctl          = snd_pcm_lib_ioctl,
415         .hw_params      = lpass_platform_pcmops_hw_params,
416         .hw_free        = lpass_platform_pcmops_hw_free,
417         .prepare        = lpass_platform_pcmops_prepare,
418         .trigger        = lpass_platform_pcmops_trigger,
419         .pointer        = lpass_platform_pcmops_pointer,
420         .mmap           = lpass_platform_pcmops_mmap,
421 };
422
423 static irqreturn_t lpass_dma_interrupt_handler(
424                         struct snd_pcm_substream *substream,
425                         struct lpass_data *drvdata,
426                         int chan, u32 interrupts)
427 {
428         struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
429         struct lpass_variant *v = drvdata->variant;
430         irqreturn_t ret = IRQ_NONE;
431         int rv;
432
433         if (interrupts & LPAIF_IRQ_PER(chan)) {
434                 rv = regmap_write(drvdata->lpaif_map,
435                                 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST),
436                                 LPAIF_IRQ_PER(chan));
437                 if (rv) {
438                         dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
439                                         __func__, rv);
440                         return IRQ_NONE;
441                 }
442                 snd_pcm_period_elapsed(substream);
443                 ret = IRQ_HANDLED;
444         }
445
446         if (interrupts & LPAIF_IRQ_XRUN(chan)) {
447                 rv = regmap_write(drvdata->lpaif_map,
448                                 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST),
449                                 LPAIF_IRQ_XRUN(chan));
450                 if (rv) {
451                         dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
452                                         __func__, rv);
453                         return IRQ_NONE;
454                 }
455                 dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__);
456                 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
457                 ret = IRQ_HANDLED;
458         }
459
460         if (interrupts & LPAIF_IRQ_ERR(chan)) {
461                 rv = regmap_write(drvdata->lpaif_map,
462                                 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST),
463                                 LPAIF_IRQ_ERR(chan));
464                 if (rv) {
465                         dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
466                                         __func__, rv);
467                         return IRQ_NONE;
468                 }
469                 dev_err(soc_runtime->dev, "%s() bus access error\n", __func__);
470                 snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
471                 ret = IRQ_HANDLED;
472         }
473
474         return ret;
475 }
476
477 static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
478 {
479         struct lpass_data *drvdata = data;
480         struct lpass_variant *v = drvdata->variant;
481         unsigned int irqs;
482         int rv, chan;
483
484         rv = regmap_read(drvdata->lpaif_map,
485                         LPAIF_IRQSTAT_REG(v, LPAIF_IRQ_PORT_HOST), &irqs);
486         if (rv) {
487                 pr_err("%s() error reading from irqstat reg: %d\n",
488                                 __func__, rv);
489                 return IRQ_NONE;
490         }
491
492         /* Handle per channel interrupts */
493         for (chan = 0; chan < LPASS_MAX_DMA_CHANNELS; chan++) {
494                 if (irqs & LPAIF_IRQ_ALL(chan) && drvdata->substream[chan]) {
495                         rv = lpass_dma_interrupt_handler(
496                                                 drvdata->substream[chan],
497                                                 drvdata, chan, irqs);
498                         if (rv != IRQ_HANDLED)
499                                 return rv;
500                 }
501         }
502
503         return IRQ_HANDLED;
504 }
505
506 static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
507 {
508         struct snd_pcm *pcm = soc_runtime->pcm;
509         struct snd_pcm_substream *psubstream, *csubstream;
510         int ret = -EINVAL;
511         size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
512
513         psubstream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
514         if (psubstream) {
515                 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
516                                         soc_runtime->platform->dev,
517                                         size, &psubstream->dma_buffer);
518                 if (ret) {
519                         dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
520                         return ret;
521                 }
522         }
523
524         csubstream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
525         if (csubstream) {
526                 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
527                                         soc_runtime->platform->dev,
528                                         size, &csubstream->dma_buffer);
529                 if (ret) {
530                         dev_err(soc_runtime->dev, "Cannot allocate buffer(s)\n");
531                         if (psubstream)
532                                 snd_dma_free_pages(&psubstream->dma_buffer);
533                         return ret;
534                 }
535
536         }
537
538         return 0;
539 }
540
541 static void lpass_platform_pcm_free(struct snd_pcm *pcm)
542 {
543         struct snd_pcm_substream *substream;
544         int i;
545
546         for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
547                 substream = pcm->streams[i].substream;
548                 if (substream) {
549                         snd_dma_free_pages(&substream->dma_buffer);
550                         substream->dma_buffer.area = NULL;
551                         substream->dma_buffer.addr = 0;
552                 }
553         }
554 }
555
556 static struct snd_soc_platform_driver lpass_platform_driver = {
557         .pcm_new        = lpass_platform_pcm_new,
558         .pcm_free       = lpass_platform_pcm_free,
559         .ops            = &lpass_platform_pcm_ops,
560 };
561
562 int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
563 {
564         struct lpass_data *drvdata = platform_get_drvdata(pdev);
565         struct lpass_variant *v = drvdata->variant;
566         int ret;
567
568         drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif");
569         if (drvdata->lpaif_irq < 0) {
570                 dev_err(&pdev->dev, "%s() error getting irq handle: %d\n",
571                                 __func__, drvdata->lpaif_irq);
572                 return -ENODEV;
573         }
574
575         /* ensure audio hardware is disabled */
576         ret = regmap_write(drvdata->lpaif_map,
577                         LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 0);
578         if (ret) {
579                 dev_err(&pdev->dev, "%s() error writing to irqen reg: %d\n",
580                                 __func__, ret);
581                 return ret;
582         }
583
584         ret = devm_request_irq(&pdev->dev, drvdata->lpaif_irq,
585                         lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING,
586                         "lpass-irq-lpaif", drvdata);
587         if (ret) {
588                 dev_err(&pdev->dev, "%s() irq request failed: %d\n",
589                                 __func__, ret);
590                 return ret;
591         }
592
593
594         return devm_snd_soc_register_platform(&pdev->dev,
595                         &lpass_platform_driver);
596 }
597 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
598
599 MODULE_DESCRIPTION("QTi LPASS Platform Driver");
600 MODULE_LICENSE("GPL v2");