blob: b5e0d6abe5625e29d71f24f64df1bf9bc0cbd6e4 [file] [log] [blame]
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001/*
2 * omap-abe-dsp.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16 * 02110-1301 USA
17 *
18 * Copyright (C) 2010 Texas Instruments Inc.
19 *
20 * Authors: Liam Girdwood <lrg@ti.com>
21 * Misael Lopez Cruz <misael.lopez@ti.com>
22 * Sebastien Guiriec <s-guiriec@ti.com>
23 *
24 */
25
26#define DEBUG
27
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/pm.h>
33#include <linux/i2c.h>
34#include <linux/gpio.h>
35#include <linux/platform_device.h>
36#include <linux/workqueue.h>
37#include <linux/i2c/twl.h>
38#include <linux/clk.h>
39#include <linux/err.h>
40#include <linux/slab.h>
41#include <linux/pm_runtime.h>
42#include <linux/dma-mapping.h>
43#include <linux/wait.h>
44#include <linux/firmware.h>
45#include <linux/debugfs.h>
46
47#include <plat/omap_hwmod.h>
48#include <plat/omap_device.h>
49#include <plat/dma.h>
50
51#include <sound/core.h>
52#include <sound/pcm.h>
53#include <sound/pcm_params.h>
54#include <sound/soc.h>
55#include <sound/soc-dapm.h>
56#include <sound/initval.h>
57#include <sound/tlv.h>
58#include <sound/omap-abe-dsp.h>
59
60#include "omap-abe-dsp.h"
61#include "omap-abe.h"
62#include "abe/abe_main.h"
63#include "abe/port_mgr.h"
64
65#warning need omap_device_set_rate
66#define omap_device_set_rate(x, y, z)
67
68static const char *abe_memory_bank[5] = {
69 "dmem",
70 "cmem",
71 "smem",
72 "pmem",
73 "mpu"
74};
75
76
77/*
78 * ABE loadable coefficients.
79 * The coefficient and their mixer configurations are loaded with the firmware
80 * blob duing probe().
81 */
82
83struct coeff_config {
84 char name[ABE_COEFF_NAME_SIZE];
85 u32 count;
86 u32 coeff;
87 char texts[ABE_COEFF_NUM_TEXTS][ABE_COEFF_TEXT_SIZE];
88};
89
90/*
91 * ABE Firmware Header.
92 * The ABE firmware blob has a header that describes each data section. This
93 * way we can store coefficients etc in the firmware.
94 */
95struct fw_header {
96 u32 magic; /* magic number */
97 u32 crc; /* optional crc */
98 u32 firmware_size; /* payload size */
99 u32 coeff_size; /* payload size */
100 u32 coeff_version; /* coefficent version */
101 u32 firmware_version; /* min version of ABE firmware required */
102 u32 num_equ; /* number of equalizers */
103};
104
105/*
106 * ABE private data.
107 */
108struct abe_data {
109 struct omap4_abe_dsp_pdata *abe_pdata;
110 struct device *dev;
111 struct snd_soc_platform *platform;
112 struct delayed_work delayed_work;
113 struct mutex mutex;
114 struct mutex opp_mutex;
115 struct clk *clk;
116 void __iomem *io_base[5];
117 int irq;
118 int opp;
119 int active;
120
121 /* coefficients */
122 struct fw_header hdr;
123 s32 *equ[ABE_MAX_EQU];
124 int equ_profile[ABE_MAX_EQU];
125 struct soc_enum equalizer_enum[ABE_MAX_EQU];
126 struct snd_kcontrol_new equalizer_control[ABE_MAX_EQU];
127 struct coeff_config *equ_texts;
128
129 /* DAPM mixer config - TODO: some of this can be replaced with HAL update */
130 u32 widget_opp[ABE_NUM_DAPM_REG + 1];
131
132 u16 router[16];
133 int loss_count;
134
135 struct snd_pcm_substream *ping_pong_substream;
136 int first_irq;
137
138 struct snd_pcm_substream *psubs;
139
140#ifdef CONFIG_DEBUG_FS
141 /* ABE runtime debug config */
142
143 /* its intended we can switch on/off individual debug items */
144 u32 dbg_format1; /* TODO: match flag names here to debug format flags */
145 u32 dbg_format2;
146 u32 dbg_format3;
147
148 u32 dbg_buffer_bytes;
149 u32 dbg_circular;
150 u32 dbg_buffer_msecs; /* size of buffer in secs */
151 u32 dbg_elem_bytes;
152 dma_addr_t dbg_buffer_addr;
153 wait_queue_head_t wait;
154 int dbg_reader_offset;
155 int dbg_dma_offset;
156 int dbg_complete;
157 struct dentry *debugfs_root;
158 struct dentry *debugfs_fmt1;
159 struct dentry *debugfs_fmt2;
160 struct dentry *debugfs_fmt3;
161 struct dentry *debugfs_size;
162 struct dentry *debugfs_data;
163 struct dentry *debugfs_circ;
164 struct dentry *debugfs_elem_bytes;
165 struct dentry *debugfs_opp_level;
166 char *dbg_buffer;
167 struct omap_pcm_dma_data *dma_data;
168 int dma_ch;
169 int dma_req;
170#endif
171};
172
173static struct abe_data *the_abe;
174
175// TODO: map to the new version of HAL
176static unsigned int abe_dsp_read(struct snd_soc_platform *platform,
177 unsigned int reg)
178{
179 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
180
181 BUG_ON(reg > ABE_NUM_DAPM_REG);
182 return abe->widget_opp[reg];
183}
184
185static int abe_dsp_write(struct snd_soc_platform *platform, unsigned int reg,
186 unsigned int val)
187{
188 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
189
190 BUG_ON(reg > ABE_NUM_DAPM_REG);
191 abe->widget_opp[reg] = val;
192 return 0;
193}
194
195static void abe_irq_pingpong_subroutine(u32 *data)
196{
Liam Girdwooda8d99da2011-02-03 15:28:19 +0000197 u32 dst, n_bytes;
198
199 abe_read_next_ping_pong_buffer(MM_DL_PORT, &dst, &n_bytes);
200 abe_set_ping_pong_buffer(MM_DL_PORT, n_bytes);
201
202 /* Do not call ALSA function for first IRQ */
203 if (the_abe->first_irq) {
204 the_abe->first_irq = 0;
205 } else {
206 if (the_abe->ping_pong_substream)
207 snd_pcm_period_elapsed(the_abe->ping_pong_substream);
208 }
209}
210
211static irqreturn_t abe_irq_handler(int irq, void *dev_id)
212{
213 struct abe_data *abe = dev_id;
214
215 /* TODO: handle underruns/overruns/errors */
216 pm_runtime_get_sync(abe->dev);
217 abe_clear_irq(); // TODO: why is IRQ not cleared after processing ?
218 abe_irq_processing();
219 pm_runtime_put_sync(abe->dev);
220 return IRQ_HANDLED;
221}
222
223// TODO: these should really be called internally since we will know the McPDM state
224void abe_dsp_pm_get(void)
225{
226 pm_runtime_get_sync(the_abe->dev);
227}
228EXPORT_SYMBOL_GPL(abe_dsp_pm_get);
229
230void abe_dsp_pm_put(void)
231{
232 pm_runtime_put_sync(the_abe->dev);
233}
234EXPORT_SYMBOL_GPL(abe_dsp_pm_put);
235
236void abe_dsp_shutdown(void)
237{
238 if (!the_abe->active && !abe_check_activity()) {
239 abe_set_opp_processing(ABE_OPP25);
240 the_abe->opp = 25;
241 abe_stop_event_generator();
242 udelay(250);
243 omap_device_set_rate(the_abe->dev, the_abe->dev, 0);
244 }
245}
246EXPORT_SYMBOL_GPL(abe_dsp_shutdown);
247
248/*
249 * These TLV settings will need fine tuned for each individual control
250 */
251
252/* Media DL1 volume control from -120 to 30 dB in 1 dB steps */
253static DECLARE_TLV_DB_SCALE(mm_dl1_tlv, -12000, 100, 3000);
254
255/* Media DL1 volume control from -120 to 30 dB in 1 dB steps */
256static DECLARE_TLV_DB_SCALE(tones_dl1_tlv, -12000, 100, 3000);
257
258/* Media DL1 volume control from -120 to 30 dB in 1 dB steps */
259static DECLARE_TLV_DB_SCALE(voice_dl1_tlv, -12000, 100, 3000);
260
261/* Media DL1 volume control from -120 to 30 dB in 1 dB steps */
262static DECLARE_TLV_DB_SCALE(capture_dl1_tlv, -12000, 100, 3000);
263
264/* Media DL2 volume control from -120 to 30 dB in 1 dB steps */
265static DECLARE_TLV_DB_SCALE(mm_dl2_tlv, -12000, 100, 3000);
266
267/* Media DL2 volume control from -120 to 30 dB in 1 dB steps */
268static DECLARE_TLV_DB_SCALE(tones_dl2_tlv, -12000, 100, 3000);
269
270/* Media DL2 volume control from -120 to 30 dB in 1 dB steps */
271static DECLARE_TLV_DB_SCALE(voice_dl2_tlv, -12000, 100, 3000);
272
273/* Media DL2 volume control from -120 to 30 dB in 1 dB steps */
274static DECLARE_TLV_DB_SCALE(capture_dl2_tlv, -12000, 100, 3000);
275
276/* SDT volume control from -120 to 30 dB in 1 dB steps */
277static DECLARE_TLV_DB_SCALE(sdt_ul_tlv, -12000, 100, 3000);
278
279/* SDT volume control from -120 to 30 dB in 1 dB steps */
280static DECLARE_TLV_DB_SCALE(sdt_dl_tlv, -12000, 100, 3000);
281
282/* AUDUL volume control from -120 to 30 dB in 1 dB steps */
283static DECLARE_TLV_DB_SCALE(audul_mm_tlv, -12000, 100, 3000);
284
285/* AUDUL volume control from -120 to 30 dB in 1 dB steps */
286static DECLARE_TLV_DB_SCALE(audul_tones_tlv, -12000, 100, 3000);
287
288/* AUDUL volume control from -120 to 30 dB in 1 dB steps */
289static DECLARE_TLV_DB_SCALE(audul_vx_ul_tlv, -12000, 100, 3000);
290
291/* AUDUL volume control from -120 to 30 dB in 1 dB steps */
292static DECLARE_TLV_DB_SCALE(audul_vx_dl_tlv, -12000, 100, 3000);
293
294/* VXREC volume control from -120 to 30 dB in 1 dB steps */
295static DECLARE_TLV_DB_SCALE(vxrec_mm_dl_tlv, -12000, 100, 3000);
296
297/* VXREC volume control from -120 to 30 dB in 1 dB steps */
298static DECLARE_TLV_DB_SCALE(vxrec_tones_tlv, -12000, 100, 3000);
299
300/* VXREC volume control from -120 to 30 dB in 1 dB steps */
301static DECLARE_TLV_DB_SCALE(vxrec_vx_dl_tlv, -12000, 100, 3000);
302
303/* VXREC volume control from -120 to 30 dB in 1 dB steps */
304static DECLARE_TLV_DB_SCALE(vxrec_vx_ul_tlv, -12000, 100, 3000);
305
306/* DMIC volume control from -120 to 30 dB in 1 dB steps */
307static DECLARE_TLV_DB_SCALE(dmic_tlv, -12000, 100, 3000);
308
309/* BT UL volume control from -120 to 30 dB in 1 dB steps */
310static DECLARE_TLV_DB_SCALE(btul_tlv, -12000, 100, 3000);
311
312/* AMIC volume control from -120 to 30 dB in 1 dB steps */
313static DECLARE_TLV_DB_SCALE(amic_tlv, -12000, 100, 3000);
314
315//TODO: we have to use the shift value atm to represent register id due to current HAL
316static int dl1_put_mixer(struct snd_kcontrol *kcontrol,
317 struct snd_ctl_elem_value *ucontrol)
318{
319 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
320 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
321 struct soc_mixer_control *mc =
322 (struct soc_mixer_control *)kcontrol->private_value;
323
324 pm_runtime_get_sync(the_abe->dev);
325
326 // TODO: optimise all of these to call HAL abe_enable_gain(mixer, enable)
327 if (ucontrol->value.integer.value[0]) {
328 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
329 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
330 abe_enable_gain(MIXDL1, mc->reg);
331 } else {
332 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
333 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
334 abe_disable_gain(MIXDL1, mc->reg);
335 }
336 pm_runtime_put_sync(the_abe->dev);
337
338 return 1;
339}
340
341static int dl2_put_mixer(struct snd_kcontrol *kcontrol,
342 struct snd_ctl_elem_value *ucontrol)
343{
344 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
345 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
346 struct soc_mixer_control *mc =
347 (struct soc_mixer_control *)kcontrol->private_value;
348
349 pm_runtime_get_sync(the_abe->dev);
350
351 if (ucontrol->value.integer.value[0]) {
352 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
353 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
354 abe_enable_gain(MIXDL2, mc->reg);
355 } else {
356 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
357 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
358 abe_disable_gain(MIXDL2, mc->reg);
359 }
360
361 pm_runtime_put_sync(the_abe->dev);
362 return 1;
363}
364
365static int audio_ul_put_mixer(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
367{
368 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
369 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
370 struct soc_mixer_control *mc =
371 (struct soc_mixer_control *)kcontrol->private_value;
372
373 pm_runtime_get_sync(the_abe->dev);
374
375 if (ucontrol->value.integer.value[0]) {
376 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
377 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
378 abe_enable_gain(MIXAUDUL, mc->reg);
379 } else {
380 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
381 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
382 abe_disable_gain(MIXAUDUL, mc->reg);
383 }
384 pm_runtime_put_sync(the_abe->dev);
385
386 return 1;
387}
388
389static int vxrec_put_mixer(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_value *ucontrol)
391{
392 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
393 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
394 struct soc_mixer_control *mc =
395 (struct soc_mixer_control *)kcontrol->private_value;
396
397 pm_runtime_get_sync(the_abe->dev);
398
399 if (ucontrol->value.integer.value[0]) {
400 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
401 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
402 abe_enable_gain(MIXVXREC, mc->reg);
403 } else {
404 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
405 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
406 abe_disable_gain(MIXVXREC, mc->reg);
407 }
408 pm_runtime_put_sync(the_abe->dev);
409
410 return 1;
411}
412
413static int sdt_put_mixer(struct snd_kcontrol *kcontrol,
414 struct snd_ctl_elem_value *ucontrol)
415{
416 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
417 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
418 struct soc_mixer_control *mc =
419 (struct soc_mixer_control *)kcontrol->private_value;
420
421 pm_runtime_get_sync(the_abe->dev);
422
423 if (ucontrol->value.integer.value[0]) {
424 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
425 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
426 abe_enable_gain(MIXSDT, mc->reg);
427 } else {
428 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
429 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
430 abe_disable_gain(MIXSDT, mc->reg);
431 }
432 pm_runtime_put_sync(the_abe->dev);
433
434 return 1;
435}
436
437static int abe_get_mixer(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
439{
440 struct soc_mixer_control *mc =
441 (struct soc_mixer_control *)kcontrol->private_value;
442
443 ucontrol->value.integer.value[0] = the_abe->widget_opp[mc->shift];
444 return 0;
445}
446
447/* router IDs that match our mixer strings */
448static const abe_router_t router[] = {
449 ZERO_labelID, /* strangely this is not 0 */
450 DMIC1_L_labelID, DMIC1_R_labelID,
451 DMIC2_L_labelID, DMIC2_R_labelID,
452 DMIC3_L_labelID, DMIC3_R_labelID,
453 BT_UL_L_labelID, BT_UL_R_labelID,
454 MM_EXT_IN_L_labelID, MM_EXT_IN_R_labelID,
455 AMIC_L_labelID, AMIC_R_labelID,
456 VX_REC_L_labelID, VX_REC_R_labelID,
457};
458
459static int ul_mux_put_route(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
461{
462 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
463 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
464 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
465 int mux = ucontrol->value.enumerated.item[0];
466 int reg = e->reg - ABE_MUX(0);
467
468 pm_runtime_get_sync(the_abe->dev);
469
470 if (mux > ABE_ROUTES_UL)
471 return 0;
472
473 // TODO: get all this via firmware
474 if (reg < 8) {
475 /* 0 .. 9 = MM_UL */
476 the_abe->router[reg] = router[mux];
477 } else if (reg < 12) {
478 /* 10 .. 11 = MM_UL2 */
479 /* 12 .. 13 = VX_UL */
480 the_abe->router[reg + 2] = router[mux];
481 }
482
483 /* 2nd arg here is unused */
484 abe_set_router_configuration(UPROUTE, 0, (u32 *)the_abe->router);
485
486 if (router[mux] != ZERO_labelID)
487 the_abe->widget_opp[e->reg] = e->shift_l;
488 else
489 the_abe->widget_opp[e->reg] = 0;
490
491 snd_soc_dapm_mux_update_power(widget, kcontrol, 1, mux, e);
492 pm_runtime_put_sync(the_abe->dev);
493
494 return 1;
495}
496
497static int ul_mux_get_route(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
499{
500 struct soc_enum *e =
501 (struct soc_enum *)kcontrol->private_value;
502 int reg = e->reg - ABE_MUX(0), i, rval = 0;
503
504 // TODO: get all this via firmware
505 if (reg < 8) {
506 /* 0 .. 9 = MM_UL */
507 rval = the_abe->router[reg];
508 } else if (reg < 12) {
509 /* 10 .. 11 = MM_UL2 */
510 /* 12 .. 13 = VX_UL */
511 rval = the_abe->router[reg + 2];
512 }
513
514 for (i = 0; i < ARRAY_SIZE(router); i++) {
515 if (router[i] == rval) {
516 ucontrol->value.integer.value[0] = i;
517 return 0;
518 }
519 }
520
521 return 1;
522}
523
524
525static int abe_put_switch(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
527{
528 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
529 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
530 struct soc_mixer_control *mc =
531 (struct soc_mixer_control *)kcontrol->private_value;
532
533 pm_runtime_get_sync(the_abe->dev);
534
535 if (ucontrol->value.integer.value[0]) {
536 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
537 snd_soc_dapm_mixer_update_power(widget, kcontrol, 1);
538 } else {
539 the_abe->widget_opp[mc->shift] = ucontrol->value.integer.value[0];
540 snd_soc_dapm_mixer_update_power(widget, kcontrol, 0);
541 }
542 pm_runtime_put_sync(the_abe->dev);
543
544 return 1;
545}
546
547
548static int volume_put_sdt_mixer(struct snd_kcontrol *kcontrol,
549 struct snd_ctl_elem_value *ucontrol)
550{
551 struct soc_mixer_control *mc =
552 (struct soc_mixer_control *)kcontrol->private_value;
553
554 pm_runtime_get_sync(the_abe->dev);
555
556 abe_write_mixer(MIXSDT, abe_val_to_gain(ucontrol->value.integer.value[0]),
557 RAMP_0MS, mc->reg);
558 pm_runtime_put_sync(the_abe->dev);
559
560 return 1;
561}
562
563static int volume_put_audul_mixer(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
565{
566 struct soc_mixer_control *mc =
567 (struct soc_mixer_control *)kcontrol->private_value;
568
569 pm_runtime_get_sync(the_abe->dev);
570 abe_write_mixer(MIXAUDUL, abe_val_to_gain(ucontrol->value.integer.value[0]),
571 RAMP_0MS, mc->reg);
572 pm_runtime_put_sync(the_abe->dev);
573
574 return 1;
575}
576
577static int volume_put_vxrec_mixer(struct snd_kcontrol *kcontrol,
578 struct snd_ctl_elem_value *ucontrol)
579{
580 struct soc_mixer_control *mc =
581 (struct soc_mixer_control *)kcontrol->private_value;
582
583 pm_runtime_get_sync(the_abe->dev);
584 abe_write_mixer(MIXVXREC, abe_val_to_gain(ucontrol->value.integer.value[0]),
585 RAMP_0MS, mc->reg);
586 pm_runtime_put_sync(the_abe->dev);
587
588 return 1;
589}
590
591static int volume_put_dl1_mixer(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
593{
594 struct soc_mixer_control *mc =
595 (struct soc_mixer_control *)kcontrol->private_value;
596
597 pm_runtime_get_sync(the_abe->dev);
598 abe_write_mixer(MIXDL1, abe_val_to_gain(ucontrol->value.integer.value[0]),
599 RAMP_0MS, mc->reg);
600 pm_runtime_put_sync(the_abe->dev);
601
602 return 1;
603}
604
605static int volume_put_dl2_mixer(struct snd_kcontrol *kcontrol,
606 struct snd_ctl_elem_value *ucontrol)
607{
608 struct soc_mixer_control *mc =
609 (struct soc_mixer_control *)kcontrol->private_value;
610
611 pm_runtime_get_sync(the_abe->dev);
612 abe_write_mixer(MIXDL2, abe_val_to_gain(ucontrol->value.integer.value[0]),
613 RAMP_0MS, mc->reg);
614 pm_runtime_put_sync(the_abe->dev);
615
616 return 1;
617}
618
619static int volume_put_gain(struct snd_kcontrol *kcontrol,
620 struct snd_ctl_elem_value *ucontrol)
621{
622 struct soc_mixer_control *mc =
623 (struct soc_mixer_control *)kcontrol->private_value;
624
625 pm_runtime_get_sync(the_abe->dev);
626 abe_write_gain(mc->reg,
627 abe_val_to_gain(ucontrol->value.integer.value[0]),
628 RAMP_20MS, mc->shift);
629 abe_write_gain(mc->reg,
630 -12000 + (ucontrol->value.integer.value[1] * 100),
631 RAMP_20MS, mc->rshift);
632 pm_runtime_put_sync(the_abe->dev);
633
634 return 1;
635}
636
637static int volume_get_dl1_mixer(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 struct soc_mixer_control *mc =
641 (struct soc_mixer_control *)kcontrol->private_value;
642 u32 val;
643
644 pm_runtime_get_sync(the_abe->dev);
645 abe_read_mixer(MIXDL1, &val, mc->reg);
646 ucontrol->value.integer.value[0] = abe_gain_to_val(val);
647 pm_runtime_put_sync(the_abe->dev);
648
649 return 0;
650}
651
652static int volume_get_dl2_mixer(struct snd_kcontrol *kcontrol,
653 struct snd_ctl_elem_value *ucontrol)
654{
655 struct soc_mixer_control *mc =
656 (struct soc_mixer_control *)kcontrol->private_value;
657 u32 val;
658
659 pm_runtime_get_sync(the_abe->dev);
660 abe_read_mixer(MIXDL2, &val, mc->reg);
661 ucontrol->value.integer.value[0] = abe_gain_to_val(val);
662 pm_runtime_put_sync(the_abe->dev);
663
664 return 0;
665}
666
667static int volume_get_audul_mixer(struct snd_kcontrol *kcontrol,
668 struct snd_ctl_elem_value *ucontrol)
669{
670 struct soc_mixer_control *mc =
671 (struct soc_mixer_control *)kcontrol->private_value;
672 u32 val;
673
674 pm_runtime_get_sync(the_abe->dev);
675 abe_read_mixer(MIXAUDUL, &val, mc->reg);
676 ucontrol->value.integer.value[0] = abe_gain_to_val(val);
677 pm_runtime_put_sync(the_abe->dev);
678
679 return 0;
680}
681
682static int volume_get_vxrec_mixer(struct snd_kcontrol *kcontrol,
683 struct snd_ctl_elem_value *ucontrol)
684{
685 struct soc_mixer_control *mc =
686 (struct soc_mixer_control *)kcontrol->private_value;
687 u32 val;
688
689 pm_runtime_get_sync(the_abe->dev);
690 abe_read_mixer(MIXVXREC, &val, mc->reg);
691 ucontrol->value.integer.value[0] = abe_gain_to_val(val);
692 pm_runtime_put_sync(the_abe->dev);
693
694 return 0;
695}
696
697static int volume_get_sdt_mixer(struct snd_kcontrol *kcontrol,
698 struct snd_ctl_elem_value *ucontrol)
699{
700 struct soc_mixer_control *mc =
701 (struct soc_mixer_control *)kcontrol->private_value;
702 u32 val;
703
704 pm_runtime_get_sync(the_abe->dev);
705 abe_read_mixer(MIXSDT, &val, mc->reg);
706 ucontrol->value.integer.value[0] = abe_gain_to_val(val);
707 pm_runtime_put_sync(the_abe->dev);
708
709 return 0;
710}
711
712static int volume_get_gain(struct snd_kcontrol *kcontrol,
713 struct snd_ctl_elem_value *ucontrol)
714{
715 struct soc_mixer_control *mc =
716 (struct soc_mixer_control *)kcontrol->private_value;
717 u32 val;
718
719 pm_runtime_get_sync(the_abe->dev);
720 abe_read_gain(mc->reg, &val, mc->shift);
721 ucontrol->value.integer.value[0] = abe_gain_to_val(val);
722 abe_read_gain(mc->reg, &val, mc->rshift);
723 ucontrol->value.integer.value[1] = abe_gain_to_val(val);
724 pm_runtime_put_sync(the_abe->dev);
725
726 return 0;
727}
728
729static int abe_get_equalizer(struct snd_kcontrol *kcontrol,
730 struct snd_ctl_elem_value *ucontrol)
731{
732#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
733 struct soc_enum *eqc = (struct soc_enum *)kcontrol->private_value;
734
735 ucontrol->value.integer.value[0] = the_abe->equ_profile[eqc->reg];
736#endif
737 return 0;
738}
739
740static int abe_put_equalizer(struct snd_kcontrol *kcontrol,
741 struct snd_ctl_elem_value *ucontrol)
742{
743#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
744 struct soc_enum *eqc = (struct soc_enum *)kcontrol->private_value;
745 u16 val = ucontrol->value.enumerated.item[0];
746 abe_equ_t equ_params;
747 int size;
748
749 if (val >= the_abe->hdr.num_equ)
750 return -EINVAL;
751
752 equ_params.equ_length = the_abe->equ_texts[eqc->reg].coeff;
753 size = the_abe->equ_texts[eqc->reg].coeff * sizeof(s32);
754 memcpy(equ_params.coef.type1, the_abe->equ[eqc->reg] + val * size, size);
755 the_abe->equ_profile[eqc->reg] = val;
756
757 pm_runtime_get_sync(the_abe->dev);
758 abe_write_equalizer(eqc->reg, &equ_params);
759 pm_runtime_put_sync(the_abe->dev);
760#endif
761 return 1;
762}
763
764int snd_soc_info_enum_ext1(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_info *uinfo)
766{
767 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
768
769 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
770 uinfo->count = 1;
771 uinfo->value.enumerated.items = e->max;
772
773 if (uinfo->value.enumerated.item > e->max - 1)
774 uinfo->value.enumerated.item = e->max - 1;
775 strcpy(uinfo->value.enumerated.name,
776 snd_soc_get_enum_text(e, uinfo->value.enumerated.item));
777
778 return 0;
779}
780
781static const char *route_ul_texts[] = {
782 "None", "DMic0L", "DMic0R", "DMic1L", "DMic1R", "DMic2L", "DMic2R",
783 "BT Left", "BT Right", "MMExt Left", "MMExt Right", "AMic0", "AMic1",
784 "VX Left", "VX Right"
785};
786
787/* ROUTE_UL Mux table */
788static const struct soc_enum abe_enum[] = {
789 SOC_ENUM_SINGLE(MUX_MM_UL10, 0, 15, route_ul_texts),
790 SOC_ENUM_SINGLE(MUX_MM_UL11, 0, 15, route_ul_texts),
791 SOC_ENUM_SINGLE(MUX_MM_UL12, 0, 15, route_ul_texts),
792 SOC_ENUM_SINGLE(MUX_MM_UL13, 0, 15, route_ul_texts),
793 SOC_ENUM_SINGLE(MUX_MM_UL14, 0, 15, route_ul_texts),
794 SOC_ENUM_SINGLE(MUX_MM_UL15, 0, 15, route_ul_texts),
795 SOC_ENUM_SINGLE(MUX_MM_UL16, 0, 15, route_ul_texts),
796 SOC_ENUM_SINGLE(MUX_MM_UL17, 0, 15, route_ul_texts),
797 SOC_ENUM_SINGLE(MUX_MM_UL20, 0, 15, route_ul_texts),
798 SOC_ENUM_SINGLE(MUX_MM_UL21, 0, 15, route_ul_texts),
799 SOC_ENUM_SINGLE(MUX_VX_UL0, 0, 15, route_ul_texts),
800 SOC_ENUM_SINGLE(MUX_VX_UL1, 0, 15, route_ul_texts),
801};
802
803static const struct snd_kcontrol_new mm_ul00_control =
804 SOC_DAPM_ENUM_EXT("Route", abe_enum[0],
805 ul_mux_get_route, ul_mux_put_route);
806
807static const struct snd_kcontrol_new mm_ul01_control =
808 SOC_DAPM_ENUM_EXT("Route", abe_enum[1],
809 ul_mux_get_route, ul_mux_put_route);
810
811static const struct snd_kcontrol_new mm_ul02_control =
812 SOC_DAPM_ENUM_EXT("Route", abe_enum[2],
813 ul_mux_get_route, ul_mux_put_route);
814
815static const struct snd_kcontrol_new mm_ul03_control =
816 SOC_DAPM_ENUM_EXT("Route", abe_enum[3],
817 ul_mux_get_route, ul_mux_put_route);
818
819static const struct snd_kcontrol_new mm_ul04_control =
820 SOC_DAPM_ENUM_EXT("Route", abe_enum[4],
821 ul_mux_get_route, ul_mux_put_route);
822
823static const struct snd_kcontrol_new mm_ul05_control =
824 SOC_DAPM_ENUM_EXT("Route", abe_enum[5],
825 ul_mux_get_route, ul_mux_put_route);
826
827static const struct snd_kcontrol_new mm_ul06_control =
828 SOC_DAPM_ENUM_EXT("Route", abe_enum[6],
829 ul_mux_get_route, ul_mux_put_route);
830
831static const struct snd_kcontrol_new mm_ul07_control =
832 SOC_DAPM_ENUM_EXT("Route", abe_enum[7],
833 ul_mux_get_route, ul_mux_put_route);
834
835static const struct snd_kcontrol_new mm_ul10_control =
836 SOC_DAPM_ENUM_EXT("Route", abe_enum[8],
837 ul_mux_get_route, ul_mux_put_route);
838
839static const struct snd_kcontrol_new mm_ul11_control =
840 SOC_DAPM_ENUM_EXT("Route", abe_enum[9],
841 ul_mux_get_route, ul_mux_put_route);
842
843static const struct snd_kcontrol_new mm_vx0_control =
844 SOC_DAPM_ENUM_EXT("Route", abe_enum[10],
845 ul_mux_get_route, ul_mux_put_route);
846
847static const struct snd_kcontrol_new mm_vx1_control =
848 SOC_DAPM_ENUM_EXT("Route", abe_enum[11],
849 ul_mux_get_route, ul_mux_put_route);
850
851/* DL1 mixer paths */
852static const struct snd_kcontrol_new dl1_mixer_controls[] = {
853 SOC_SINGLE_EXT("Tones", MIX_DL1_INPUT_TONES, MIX_DL1_TONES, 1, 0,
854 abe_get_mixer, dl1_put_mixer),
855 SOC_SINGLE_EXT("Voice", MIX_DL1_INPUT_VX_DL, MIX_DL1_VOICE, 1, 0,
856 abe_get_mixer, dl1_put_mixer),
857 SOC_SINGLE_EXT("Capture", MIX_DL1_INPUT_MM_UL2, MIX_DL1_CAPTURE, 1, 0,
858 abe_get_mixer, dl1_put_mixer),
859 SOC_SINGLE_EXT("Multimedia", MIX_DL1_INPUT_MM_DL, MIX_DL1_MEDIA, 1, 0,
860 abe_get_mixer, dl1_put_mixer),
861};
862
863/* DL2 mixer paths */
864static const struct snd_kcontrol_new dl2_mixer_controls[] = {
865 SOC_SINGLE_EXT("Tones", MIX_DL2_INPUT_TONES, MIX_DL2_TONES, 1, 0,
866 abe_get_mixer, dl2_put_mixer),
867 SOC_SINGLE_EXT("Voice", MIX_DL2_INPUT_VX_DL, MIX_DL2_VOICE, 1, 0,
868 abe_get_mixer, dl2_put_mixer),
869 SOC_SINGLE_EXT("Capture", MIX_DL2_INPUT_MM_UL2, MIX_DL2_CAPTURE, 1, 0,
870 abe_get_mixer, dl2_put_mixer),
871 SOC_SINGLE_EXT("Multimedia", MIX_DL2_INPUT_MM_DL, MIX_DL2_MEDIA, 1, 0,
872 abe_get_mixer, dl2_put_mixer),
873};
874
875/* AUDUL ("Voice Capture Mixer") mixer paths */
876static const struct snd_kcontrol_new audio_ul_mixer_controls[] = {
877 SOC_SINGLE_EXT("Tones Playback", MIX_AUDUL_INPUT_TONES, MIX_AUDUL_TONES, 1, 0,
878 abe_get_mixer, audio_ul_put_mixer),
879 SOC_SINGLE_EXT("Media Playback", MIX_AUDUL_INPUT_MM_DL, MIX_AUDUL_MEDIA, 1, 0,
880 abe_get_mixer, audio_ul_put_mixer),
881 SOC_SINGLE_EXT("Capture", MIX_AUDUL_INPUT_UPLINK, MIX_AUDUL_CAPTURE, 1, 0,
882 abe_get_mixer, audio_ul_put_mixer),
883};
884
885/* VXREC ("Capture Mixer") mixer paths */
886static const struct snd_kcontrol_new vx_rec_mixer_controls[] = {
887 SOC_SINGLE_EXT("Tones", MIX_VXREC_INPUT_TONES, MIX_VXREC_TONES, 1, 0,
888 abe_get_mixer, vxrec_put_mixer),
889 SOC_SINGLE_EXT("Voice Playback", MIX_VXREC_INPUT_VX_DL,
890 MIX_VXREC_VOICE_PLAYBACK, 1, 0, abe_get_mixer, vxrec_put_mixer),
891 SOC_SINGLE_EXT("Voice Capture", MIX_VXREC_INPUT_VX_UL,
892 MIX_VXREC_VOICE_CAPTURE, 1, 0, abe_get_mixer, vxrec_put_mixer),
893 SOC_SINGLE_EXT("Media Playback", MIX_VXREC_INPUT_MM_DL,
894 MIX_VXREC_MEDIA, 1, 0, abe_get_mixer, vxrec_put_mixer),
895};
896
897/* SDT ("Sidetone Mixer") mixer paths */
898static const struct snd_kcontrol_new sdt_mixer_controls[] = {
899 SOC_SINGLE_EXT("Capture", MIX_SDT_INPUT_UP_MIXER, MIX_SDT_CAPTURE, 1, 0,
900 abe_get_mixer, sdt_put_mixer),
901 SOC_SINGLE_EXT("Playback", MIX_SDT_INPUT_DL1_MIXER, MIX_SDT_PLAYBACK, 1, 0,
902 abe_get_mixer, sdt_put_mixer),
903};
904
905/* Virtual PDM_DL Switch */
906static const struct snd_kcontrol_new pdm_dl1_switch_controls =
907 SOC_SINGLE_EXT("Switch", ABE_VIRTUAL_SWITCH, MIX_SWITCH_PDM_DL, 1, 0,
908 abe_get_mixer, abe_put_switch);
909
910/* Virtual BT_VX_DL Switch */
911static const struct snd_kcontrol_new bt_vx_dl_switch_controls =
912 SOC_SINGLE_EXT("Switch", ABE_VIRTUAL_SWITCH, MIX_SWITCH_BT_VX_DL, 1, 0,
913 abe_get_mixer, abe_put_switch);
914
915/* Virtual MM_EXT_DL Switch */
916static const struct snd_kcontrol_new mm_ext_dl_switch_controls =
917 SOC_SINGLE_EXT("Switch", ABE_VIRTUAL_SWITCH, MIX_SWITCH_MM_EXT_DL, 1, 0,
918 abe_get_mixer, abe_put_switch);
919
920static const struct snd_kcontrol_new abe_controls[] = {
921 /* DL1 mixer gains */
922 SOC_SINGLE_EXT_TLV("DL1 Media Playback Volume",
923 MIX_DL1_INPUT_MM_DL, 0, 149, 0,
924 volume_get_dl1_mixer, volume_put_dl1_mixer, mm_dl1_tlv),
925 SOC_SINGLE_EXT_TLV("DL1 Tones Playback Volume",
926 MIX_DL1_INPUT_TONES, 0, 149, 0,
927 volume_get_dl1_mixer, volume_put_dl1_mixer, tones_dl1_tlv),
928 SOC_SINGLE_EXT_TLV("DL1 Voice Playback Volume",
929 MIX_DL1_INPUT_VX_DL, 0, 149, 0,
930 volume_get_dl1_mixer, volume_put_dl1_mixer, voice_dl1_tlv),
931 SOC_SINGLE_EXT_TLV("DL1 Capture Playback Volume",
932 MIX_DL1_INPUT_MM_UL2, 0, 149, 0,
933 volume_get_dl1_mixer, volume_put_dl1_mixer, capture_dl1_tlv),
934
935 /* DL2 mixer gains */
936 SOC_SINGLE_EXT_TLV("DL2 Media Playback Volume",
937 MIX_DL2_INPUT_MM_DL, 0, 149, 0,
938 volume_get_dl2_mixer, volume_put_dl2_mixer, mm_dl2_tlv),
939 SOC_SINGLE_EXT_TLV("DL2 Tones Playback Volume",
940 MIX_DL2_INPUT_TONES, 0, 149, 0,
941 volume_get_dl2_mixer, volume_put_dl2_mixer, tones_dl2_tlv),
942 SOC_SINGLE_EXT_TLV("DL2 Voice Playback Volume",
943 MIX_DL2_INPUT_VX_DL, 0, 149, 0,
944 volume_get_dl2_mixer, volume_put_dl2_mixer, voice_dl2_tlv),
945 SOC_SINGLE_EXT_TLV("DL2 Capture Playback Volume",
946 MIX_DL2_INPUT_MM_UL2, 0, 149, 0,
947 volume_get_dl2_mixer, volume_put_dl2_mixer, capture_dl2_tlv),
948
949 /* VXREC mixer gains */
950 SOC_SINGLE_EXT_TLV("VXREC Media Volume",
951 MIX_VXREC_INPUT_MM_DL, 0, 149, 0,
952 volume_get_vxrec_mixer, volume_put_vxrec_mixer, vxrec_mm_dl_tlv),
953 SOC_SINGLE_EXT_TLV("VXREC Tones Volume",
954 MIX_VXREC_INPUT_TONES, 0, 149, 0,
955 volume_get_vxrec_mixer, volume_put_vxrec_mixer, vxrec_tones_tlv),
956 SOC_SINGLE_EXT_TLV("VXREC Voice DL Volume",
957 MIX_VXREC_INPUT_VX_UL, 0, 149, 0,
958 volume_get_vxrec_mixer, volume_put_vxrec_mixer, vxrec_vx_dl_tlv),
959 SOC_SINGLE_EXT_TLV("VXREC Voice UL Volume",
960 MIX_VXREC_INPUT_VX_DL, 0, 149, 0,
961 volume_get_vxrec_mixer, volume_put_vxrec_mixer, vxrec_vx_ul_tlv),
962
963 /* AUDUL mixer gains */
964 SOC_SINGLE_EXT_TLV("AUDUL Media Volume",
965 MIX_AUDUL_INPUT_MM_DL, 0, 149, 0,
966 volume_get_audul_mixer, volume_put_audul_mixer, audul_mm_tlv),
967 SOC_SINGLE_EXT_TLV("AUDUL Tones Volume",
968 MIX_AUDUL_INPUT_TONES, 0, 149, 0,
969 volume_get_audul_mixer, volume_put_audul_mixer, audul_tones_tlv),
970 SOC_SINGLE_EXT_TLV("AUDUL Voice UL Volume",
971 MIX_AUDUL_INPUT_UPLINK, 0, 149, 0,
972 volume_get_audul_mixer, volume_put_audul_mixer, audul_vx_ul_tlv),
973 SOC_SINGLE_EXT_TLV("AUDUL Voice DL Volume",
974 MIX_AUDUL_INPUT_VX_DL, 0, 149, 0,
975 volume_get_audul_mixer, volume_put_audul_mixer, audul_vx_dl_tlv),
976
977 /* SDT mixer gains */
978 SOC_SINGLE_EXT_TLV("SDT UL Volume",
979 MIX_SDT_INPUT_UP_MIXER, 0, 149, 0,
980 volume_get_sdt_mixer, volume_put_sdt_mixer, sdt_ul_tlv),
981 SOC_SINGLE_EXT_TLV("SDT DL Volume",
982 MIX_SDT_INPUT_DL1_MIXER, 0, 149, 0,
983 volume_get_sdt_mixer, volume_put_sdt_mixer, sdt_dl_tlv),
984
985 /* DMIC gains */
986 SOC_DOUBLE_EXT_TLV("DMIC1 UL Volume",
987 GAINS_DMIC1, GAIN_LEFT_OFFSET, GAIN_RIGHT_OFFSET, 149, 0,
988 volume_get_gain, volume_put_gain, dmic_tlv),
989
990 SOC_DOUBLE_EXT_TLV("DMIC2 UL Volume",
991 GAINS_DMIC2, GAIN_LEFT_OFFSET, GAIN_RIGHT_OFFSET, 149, 0,
992 volume_get_gain, volume_put_gain, dmic_tlv),
993
994 SOC_DOUBLE_EXT_TLV("DMIC3 UL Volume",
995 GAINS_DMIC3, GAIN_LEFT_OFFSET, GAIN_RIGHT_OFFSET, 149, 0,
996 volume_get_gain, volume_put_gain, dmic_tlv),
997
998 SOC_DOUBLE_EXT_TLV("AMIC UL Volume",
999 GAINS_AMIC, GAIN_LEFT_OFFSET, GAIN_RIGHT_OFFSET, 149, 0,
1000 volume_get_gain, volume_put_gain, amic_tlv),
1001
1002 SOC_DOUBLE_EXT_TLV("BT UL Volume",
1003 GAINS_BTUL, GAIN_LEFT_OFFSET, GAIN_RIGHT_OFFSET, 149, 0,
1004 volume_get_gain, volume_put_gain, btul_tlv),
1005};
1006
1007static const struct snd_soc_dapm_widget abe_dapm_widgets[] = {
1008
1009 /* Frontend AIFs */
1010 SND_SOC_DAPM_AIF_IN("TONES_DL", "Tones Playback", 0,
1011 W_AIF_TONES_DL, ABE_OPP_25, 0),
1012 SND_SOC_DAPM_AIF_IN("VX_DL", "Voice Playback", 0,
1013 W_AIF_VX_DL, ABE_OPP_50, 0),
1014 SND_SOC_DAPM_AIF_OUT("VX_UL", "Voice Capture", 0,
1015 W_AIF_VX_UL, ABE_OPP_50, 0),
1016 /* the MM_UL mapping is intentional */
1017 SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0,
1018 W_AIF_MM_UL1, ABE_OPP_100, 0),
1019 SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0,
1020 W_AIF_MM_UL2, ABE_OPP_50, 0),
1021 SND_SOC_DAPM_AIF_IN("MM_DL", " MultiMedia1 Playback", 0,
1022 W_AIF_MM_DL, ABE_OPP_25, 0),
1023 SND_SOC_DAPM_AIF_IN("MM_DL_LP", " MultiMedia1 LP Playback", 0,
1024 W_AIF_MM_DL_LP, ABE_OPP_25, 0),
1025 SND_SOC_DAPM_AIF_IN("VIB_DL", "Vibra Playback", 0,
1026 W_AIF_VIB_DL, ABE_OPP_100, 0),
1027 SND_SOC_DAPM_AIF_IN("MODEM_DL", "MODEM Playback", 0,
1028 W_AIF_MODEM_DL, ABE_OPP_50, 0),
1029 SND_SOC_DAPM_AIF_OUT("MODEM_UL", "MODEM Capture", 0,
1030 W_AIF_MODEM_UL, ABE_OPP_50, 0),
1031
1032 /* Backend DAIs */
1033 SND_SOC_DAPM_AIF_IN("PDM_UL1", "Analog Capture", 0,
1034 W_AIF_PDM_UL1, ABE_OPP_50, 0),
1035 SND_SOC_DAPM_AIF_OUT("PDM_DL1", "HS Playback", 0,
1036 W_AIF_PDM_DL1, ABE_OPP_25, 0),
1037 SND_SOC_DAPM_AIF_OUT("PDM_DL2", "HF Playback", 0,
1038 W_AIF_PDM_DL2, ABE_OPP_100, 0),
1039 SND_SOC_DAPM_AIF_OUT("PDM_VIB", "Vibra Playback", 0,
1040 W_AIF_PDM_VIB, ABE_OPP_100, 0),
1041 SND_SOC_DAPM_AIF_IN("BT_VX_UL", "BT Capture", 0,
1042 W_AIF_BT_VX_UL, ABE_OPP_50, 0),
1043 SND_SOC_DAPM_AIF_OUT("BT_VX_DL", "BT Playback", 0,
1044 W_AIF_BT_VX_DL, ABE_OPP_50, 0),
1045 SND_SOC_DAPM_AIF_IN("MM_EXT_UL", "FM Capture", 0,
1046 W_AIF_MM_EXT_UL, ABE_OPP_50, 0),
1047 SND_SOC_DAPM_AIF_OUT("MM_EXT_DL", "FM Playback", 0,
1048 W_AIF_MM_EXT_DL, ABE_OPP_25, 0),
1049 SND_SOC_DAPM_AIF_IN("DMIC0", "DMIC0 Capture", 0,
1050 W_AIF_DMIC0, ABE_OPP_50, 0),
1051 SND_SOC_DAPM_AIF_IN("DMIC1", "DMIC1 Capture", 0,
1052 W_AIF_DMIC1, ABE_OPP_50, 0),
1053 SND_SOC_DAPM_AIF_IN("DMIC2", "DMIC2 Capture", 0,
1054 W_AIF_DMIC2, ABE_OPP_50, 0),
1055
1056 /* ROUTE_UL Capture Muxes */
1057 SND_SOC_DAPM_MUX("MUX_UL00",
1058 W_MUX_UL00, ABE_OPP_50, 0, &mm_ul00_control),
1059 SND_SOC_DAPM_MUX("MUX_UL01",
1060 W_MUX_UL01, ABE_OPP_50, 0, &mm_ul01_control),
1061 SND_SOC_DAPM_MUX("MUX_UL02",
1062 W_MUX_UL02, ABE_OPP_50, 0, &mm_ul02_control),
1063 SND_SOC_DAPM_MUX("MUX_UL03",
1064 W_MUX_UL03, ABE_OPP_50, 0, &mm_ul03_control),
1065 SND_SOC_DAPM_MUX("MUX_UL04",
1066 W_MUX_UL04, ABE_OPP_50, 0, &mm_ul04_control),
1067 SND_SOC_DAPM_MUX("MUX_UL05",
1068 W_MUX_UL05, ABE_OPP_50, 0, &mm_ul05_control),
1069 SND_SOC_DAPM_MUX("MUX_UL06",
1070 W_MUX_UL06, ABE_OPP_50, 0, &mm_ul06_control),
1071 SND_SOC_DAPM_MUX("MUX_UL07",
1072 W_MUX_UL07, ABE_OPP_50, 0, &mm_ul07_control),
1073 SND_SOC_DAPM_MUX("MUX_UL10",
1074 W_MUX_UL10, ABE_OPP_50, 0, &mm_ul10_control),
1075 SND_SOC_DAPM_MUX("MUX_UL11",
1076 W_MUX_UL11, ABE_OPP_50, 0, &mm_ul11_control),
1077 SND_SOC_DAPM_MUX("MUX_VX0",
1078 W_MUX_VX00, ABE_OPP_50, 0, &mm_vx0_control),
1079 SND_SOC_DAPM_MUX("MUX_VX1",
1080 W_MUX_VX01, ABE_OPP_50, 0, &mm_vx1_control),
1081
1082 /* DL1 & DL2 Playback Mixers */
1083 SND_SOC_DAPM_MIXER("DL1 Mixer",
1084 W_MIXER_DL1, ABE_OPP_25, 0, dl1_mixer_controls,
1085 ARRAY_SIZE(dl1_mixer_controls)),
1086 SND_SOC_DAPM_MIXER("DL2 Mixer",
1087 W_MIXER_DL2, ABE_OPP_100, 0, dl2_mixer_controls,
1088 ARRAY_SIZE(dl2_mixer_controls)),
1089
1090 /* DL1 Mixer Input volumes ?????*/
1091 SND_SOC_DAPM_PGA("DL1 Media Volume",
1092 W_VOLUME_DL1, 0, 0, NULL, 0),
1093
1094 /* AUDIO_UL_MIXER */
1095 SND_SOC_DAPM_MIXER("Voice Capture Mixer",
1096 W_MIXER_AUDIO_UL, ABE_OPP_50, 0, audio_ul_mixer_controls,
1097 ARRAY_SIZE(audio_ul_mixer_controls)),
1098
1099 /* VX_REC_MIXER */
1100 SND_SOC_DAPM_MIXER("Capture Mixer",
1101 W_MIXER_VX_REC, ABE_OPP_50, 0, vx_rec_mixer_controls,
1102 ARRAY_SIZE(vx_rec_mixer_controls)),
1103
1104 /* SDT_MIXER - TODO: shoult this not be OPP25 ??? */
1105 SND_SOC_DAPM_MIXER("Sidetone Mixer",
1106 W_MIXER_SDT, ABE_OPP_25, 0, sdt_mixer_controls,
1107 ARRAY_SIZE(sdt_mixer_controls)),
1108
1109 /*
1110 * The Following three are virtual switches to select the output port
1111 * after DL1 Gain.
1112 */
1113
1114 /* Virtual PDM_DL1 Switch */
1115 SND_SOC_DAPM_MIXER("DL1 PDM",
1116 W_VSWITCH_DL1_PDM, ABE_OPP_25, 0, &pdm_dl1_switch_controls, 1),
1117
1118 /* Virtual BT_VX_DL Switch */
1119 SND_SOC_DAPM_MIXER("DL1 BT_VX",
1120 W_VSWITCH_DL1_BT_VX, ABE_OPP_50, 0, &bt_vx_dl_switch_controls, 1),
1121
1122 /* Virtual MM_EXT_DL Switch TODO: confrm OPP level here */
1123 SND_SOC_DAPM_MIXER("DL1 MM_EXT",
1124 W_VSWITCH_DL1_MM_EXT, ABE_OPP_50, 0, &mm_ext_dl_switch_controls, 1),
1125
1126 /* Virtuals to join our capture sources */
1127 SND_SOC_DAPM_MIXER("Sidetone Capture VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1128 SND_SOC_DAPM_MIXER("Voice Capture VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1129 SND_SOC_DAPM_MIXER("DL1 Capture VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1130 SND_SOC_DAPM_MIXER("DL2 Capture VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1131
1132 /* Join our MM_DL and MM_DL_LP playback */
1133 SND_SOC_DAPM_MIXER("MM_DL VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1134
1135 /* Virtual MODEM and VX_UL mixer */
1136 SND_SOC_DAPM_MIXER("VX UL VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1137 SND_SOC_DAPM_MIXER("VX DL VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
1138
1139 /* Virtual Pins to force backends ON atm */
1140 SND_SOC_DAPM_OUTPUT("BE_OUT"),
1141 SND_SOC_DAPM_INPUT("BE_IN"),
1142};
1143
1144static const struct snd_soc_dapm_route intercon[] = {
1145
1146 /* MUX_UL00 - ROUTE_UL - Chan 0 */
1147 {"MUX_UL00", "DMic0L", "DMIC0"},
1148 {"MUX_UL00", "DMic0R", "DMIC0"},
1149 {"MUX_UL00", "DMic1L", "DMIC1"},
1150 {"MUX_UL00", "DMic1R", "DMIC1"},
1151 {"MUX_UL00", "DMic2L", "DMIC2"},
1152 {"MUX_UL00", "DMic2R", "DMIC2"},
1153 {"MUX_UL00", "BT Left", "BT_VX_UL"},
1154 {"MUX_UL00", "BT Right", "BT_VX_UL"},
1155 {"MUX_UL00", "MMExt Left", "MM_EXT_UL"},
1156 {"MUX_UL00", "MMExt Right", "MM_EXT_UL"},
1157 {"MUX_UL00", "AMic0", "PDM_UL1"},
1158 {"MUX_UL00", "AMic1", "PDM_UL1"},
1159 {"MUX_UL00", "VX Left", "Capture Mixer"},
1160 {"MUX_UL00", "VX Right", "Capture Mixer"},
1161 {"MM_UL1", NULL, "MUX_UL00"},
1162
1163 /* MUX_UL01 - ROUTE_UL - Chan 1 */
1164 {"MUX_UL01", "DMic0L", "DMIC0"},
1165 {"MUX_UL01", "DMic0R", "DMIC0"},
1166 {"MUX_UL01", "DMic1L", "DMIC1"},
1167 {"MUX_UL01", "DMic1R", "DMIC1"},
1168 {"MUX_UL01", "DMic2L", "DMIC2"},
1169 {"MUX_UL01", "DMic2R", "DMIC2"},
1170 {"MUX_UL01", "BT Left", "BT_VX_UL"},
1171 {"MUX_UL01", "BT Right", "BT_VX_UL"},
1172 {"MUX_UL01", "MMExt Left", "MM_EXT_UL"},
1173 {"MUX_UL01", "MMExt Right", "MM_EXT_UL"},
1174 {"MUX_UL01", "AMic0", "PDM_UL1"},
1175 {"MUX_UL01", "AMic1", "PDM_UL1"},
1176 {"MUX_UL01", "VX Left", "Capture Mixer"},
1177 {"MUX_UL01", "VX Right", "Capture Mixer"},
1178 {"MM_UL1", NULL, "MUX_UL01"},
1179
1180 /* MUX_UL02 - ROUTE_UL - Chan 2 */
1181 {"MUX_UL02", "DMic0L", "DMIC0"},
1182 {"MUX_UL02", "DMic0R", "DMIC0"},
1183 {"MUX_UL02", "DMic1L", "DMIC1"},
1184 {"MUX_UL02", "DMic1R", "DMIC1"},
1185 {"MUX_UL02", "DMic2L", "DMIC2"},
1186 {"MUX_UL02", "DMic2R", "DMIC2"},
1187 {"MUX_UL02", "BT Left", "BT_VX_UL"},
1188 {"MUX_UL02", "BT Right", "BT_VX_UL"},
1189 {"MUX_UL02", "MMExt Left", "MM_EXT_UL"},
1190 {"MUX_UL02", "MMExt Right", "MM_EXT_UL"},
1191 {"MUX_UL02", "AMic0", "PDM_UL1"},
1192 {"MUX_UL02", "AMic1", "PDM_UL1"},
1193 {"MUX_UL02", "VX Left", "Capture Mixer"},
1194 {"MUX_UL02", "VX Right", "Capture Mixer"},
1195 {"MM_UL1", NULL, "MUX_UL02"},
1196
1197 /* MUX_UL03 - ROUTE_UL - Chan 3 */
1198 {"MUX_UL03", "DMic0L", "DMIC0"},
1199 {"MUX_UL03", "DMic0R", "DMIC0"},
1200 {"MUX_UL03", "DMic1L", "DMIC1"},
1201 {"MUX_UL03", "DMic1R", "DMIC1"},
1202 {"MUX_UL03", "DMic2L", "DMIC2"},
1203 {"MUX_UL03", "DMic2R", "DMIC2"},
1204 {"MUX_UL03", "BT Left", "BT_VX_UL"},
1205 {"MUX_UL03", "BT Right", "BT_VX_UL"},
1206 {"MUX_UL03", "MMExt Left", "MM_EXT_UL"},
1207 {"MUX_UL03", "MMExt Right", "MM_EXT_UL"},
1208 {"MUX_UL03", "AMic0", "PDM_UL1"},
1209 {"MUX_UL03", "AMic1", "PDM_UL1"},
1210 {"MUX_UL03", "VX Left", "Capture Mixer"},
1211 {"MUX_UL03", "VX Right", "Capture Mixer"},
1212 {"MM_UL1", NULL, "MUX_UL03"},
1213
1214 /* MUX_UL04 - ROUTE_UL - Chan 4 */
1215 {"MUX_UL04", "DMic0L", "DMIC0"},
1216 {"MUX_UL04", "DMic0R", "DMIC0"},
1217 {"MUX_UL04", "DMic1L", "DMIC1"},
1218 {"MUX_UL04", "DMic1R", "DMIC1"},
1219 {"MUX_UL04", "DMic2L", "DMIC2"},
1220 {"MUX_UL04", "DMic2R", "DMIC2"},
1221 {"MUX_UL04", "BT Left", "BT_VX_UL"},
1222 {"MUX_UL04", "BT Right", "BT_VX_UL"},
1223 {"MUX_UL04", "MMExt Left", "MM_EXT_UL"},
1224 {"MUX_UL04", "MMExt Right", "MM_EXT_UL"},
1225 {"MUX_UL04", "AMic0", "PDM_UL1"},
1226 {"MUX_UL04", "AMic1", "PDM_UL1"},
1227 {"MUX_UL04", "VX Left", "Capture Mixer"},
1228 {"MUX_UL04", "VX Right", "Capture Mixer"},
1229 {"MM_UL1", NULL, "MUX_UL04"},
1230
1231 /* MUX_UL05 - ROUTE_UL - Chan 5 */
1232 {"MUX_UL05", "DMic0L", "DMIC0"},
1233 {"MUX_UL05", "DMic0R", "DMIC0"},
1234 {"MUX_UL05", "DMic1L", "DMIC1"},
1235 {"MUX_UL05", "DMic1R", "DMIC1"},
1236 {"MUX_UL05", "DMic2L", "DMIC2"},
1237 {"MUX_UL05", "DMic2R", "DMIC2"},
1238 {"MUX_UL05", "BT Left", "BT_VX_UL"},
1239 {"MUX_UL05", "BT Right", "BT_VX_UL"},
1240 {"MUX_UL05", "MMExt Left", "MM_EXT_UL"},
1241 {"MUX_UL05", "MMExt Right", "MM_EXT_UL"},
1242 {"MUX_UL05", "AMic0", "PDM_UL1"},
1243 {"MUX_UL05", "AMic1", "PDM_UL1"},
1244 {"MUX_UL05", "VX Left", "Capture Mixer"},
1245 {"MUX_UL05", "VX Right", "Capture Mixer"},
1246 {"MM_UL1", NULL, "MUX_UL05"},
1247
1248 /* MUX_UL06 - ROUTE_UL - Chan 6 */
1249 {"MUX_UL06", "DMic0L", "DMIC0"},
1250 {"MUX_UL06", "DMic0R", "DMIC0"},
1251 {"MUX_UL06", "DMic1L", "DMIC1"},
1252 {"MUX_UL06", "DMic1R", "DMIC1"},
1253 {"MUX_UL06", "DMic2L", "DMIC2"},
1254 {"MUX_UL06", "DMic2R", "DMIC2"},
1255 {"MUX_UL06", "BT Left", "BT_VX_UL"},
1256 {"MUX_UL06", "BT Right", "BT_VX_UL"},
1257 {"MUX_UL06", "MMExt Left", "MM_EXT_UL"},
1258 {"MUX_UL06", "MMExt Right", "MM_EXT_UL"},
1259 {"MUX_UL06", "AMic0", "PDM_UL1"},
1260 {"MUX_UL06", "AMic1", "PDM_UL1"},
1261 {"MUX_UL06", "VX Left", "Capture Mixer"},
1262 {"MUX_UL06", "VX Right", "Capture Mixer"},
1263 {"MM_UL1", NULL, "MUX_UL06"},
1264
1265 /* MUX_UL07 - ROUTE_UL - Chan 7 */
1266 {"MUX_UL07", "DMic0L", "DMIC0"},
1267 {"MUX_UL07", "DMic0R", "DMIC0"},
1268 {"MUX_UL07", "DMic1L", "DMIC1"},
1269 {"MUX_UL07", "DMic1R", "DMIC1"},
1270 {"MUX_UL07", "DMic2L", "DMIC2"},
1271 {"MUX_UL07", "DMic2R", "DMIC2"},
1272 {"MUX_UL07", "BT Left", "BT_VX_UL"},
1273 {"MUX_UL07", "BT Right", "BT_VX_UL"},
1274 {"MUX_UL07", "MMExt Left", "MM_EXT_UL"},
1275 {"MUX_UL07", "MMExt Right", "MM_EXT_UL"},
1276 {"MUX_UL07", "AMic0", "PDM_UL1"},
1277 {"MUX_UL07", "AMic1", "PDM_UL1"},
1278 {"MUX_UL07", "VX Left", "Capture Mixer"},
1279 {"MUX_UL07", "VX Right", "Capture Mixer"},
1280 {"MM_UL1", NULL, "MUX_UL07"},
1281
1282 /* MUX_UL10 - ROUTE_UL - Chan 10 */
1283 {"MUX_UL10", "DMic0L", "DMIC0"},
1284 {"MUX_UL10", "DMic0R", "DMIC0"},
1285 {"MUX_UL10", "DMic1L", "DMIC1"},
1286 {"MUX_UL10", "DMic1R", "DMIC1"},
1287 {"MUX_UL10", "DMic2L", "DMIC2"},
1288 {"MUX_UL10", "DMic2R", "DMIC2"},
1289 {"MUX_UL10", "BT Left", "BT_VX_UL"},
1290 {"MUX_UL10", "BT Right", "BT_VX_UL"},
1291 {"MUX_UL10", "MMExt Left", "MM_EXT_UL"},
1292 {"MUX_UL10", "MMExt Right", "MM_EXT_UL"},
1293 {"MUX_UL10", "AMic0", "PDM_UL1"},
1294 {"MUX_UL10", "AMic1", "PDM_UL1"},
1295 {"MUX_UL10", "VX Left", "Capture Mixer"},
1296 {"MUX_UL10", "VX Right", "Capture Mixer"},
1297 {"MM_UL2", NULL, "MUX_UL10"},
1298
1299 /* MUX_UL11 - ROUTE_UL - Chan 11 */
1300 {"MUX_UL11", "DMic0L", "DMIC0"},
1301 {"MUX_UL11", "DMic0R", "DMIC0"},
1302 {"MUX_UL11", "DMic1L", "DMIC1"},
1303 {"MUX_UL11", "DMic1R", "DMIC1"},
1304 {"MUX_UL11", "DMic2L", "DMIC2"},
1305 {"MUX_UL11", "DMic2R", "DMIC2"},
1306 {"MUX_UL11", "BT Left", "BT_VX_UL"},
1307 {"MUX_UL11", "BT Right", "BT_VX_UL"},
1308 {"MUX_UL11", "MMExt Left", "MM_EXT_UL"},
1309 {"MUX_UL11", "MMExt Right", "MM_EXT_UL"},
1310 {"MUX_UL11", "AMic0", "PDM_UL1"},
1311 {"MUX_UL11", "AMic1", "PDM_UL1"},
1312 {"MUX_UL11", "VX Left", "Capture Mixer"},
1313 {"MUX_UL11", "VX Right", "Capture Mixer"},
1314 {"MM_UL2", NULL, "MUX_UL11"},
1315
1316 /* MUX_VX0 - ROUTE_UL - Chan 20 */
1317 {"MUX_VX0", "DMic0L", "DMIC0"},
1318 {"MUX_VX0", "DMic0R", "DMIC0"},
1319 {"MUX_VX0", "DMic1L", "DMIC1"},
1320 {"MUX_VX0", "DMic1R", "DMIC1"},
1321 {"MUX_VX0", "DMic2L", "DMIC2"},
1322 {"MUX_VX0", "DMic2R", "DMIC2"},
1323 {"MUX_VX0", "BT Left", "BT_VX_UL"},
1324 {"MUX_VX0", "BT Right", "BT_VX_UL"},
1325 {"MUX_VX0", "MMExt Left", "MM_EXT_UL"},
1326 {"MUX_VX0", "MMExt Right", "MM_EXT_UL"},
1327 {"MUX_VX0", "AMic0", "PDM_UL1"},
1328 {"MUX_VX0", "AMic1", "PDM_UL1"},
1329 {"MUX_VX0", "VX Left", "Capture Mixer"},
1330 {"MUX_VX0", "VX Right", "Capture Mixer"},
1331
1332 /* MUX_VX1 - ROUTE_UL - Chan 20 */
1333 {"MUX_VX1", "DMic0L", "DMIC0"},
1334 {"MUX_VX1", "DMic0R", "DMIC0"},
1335 {"MUX_VX1", "DMic1L", "DMIC1"},
1336 {"MUX_VX1", "DMic1R", "DMIC1"},
1337 {"MUX_VX1", "DMic2L", "DMIC2"},
1338 {"MUX_VX1", "DMic2R", "DMIC2"},
1339 {"MUX_VX1", "BT Left", "BT_VX_UL"},
1340 {"MUX_VX1", "BT Right", "BT_VX_UL"},
1341 {"MUX_VX1", "MMExt Left", "MM_EXT_UL"},
1342 {"MUX_VX1", "MMExt Right", "MM_EXT_UL"},
1343 {"MUX_VX1", "AMic0", "PDM_UL1"},
1344 {"MUX_VX1", "AMic1", "PDM_UL1"},
1345 {"MUX_VX1", "VX Left", "Capture Mixer"},
1346 {"MUX_VX1", "VX Right", "Capture Mixer"},
1347
1348 /* Headset (DL1) playback path */
1349 {"DL1 Mixer", "Tones", "TONES_DL"},
1350 {"DL1 Mixer", "Voice", "VX DL VMixer"},
1351 {"DL1 Mixer", "Capture", "DL1 Capture VMixer"},
1352 {"DL1 Capture VMixer", NULL, "MUX_UL10"},
1353 {"DL1 Capture VMixer", NULL, "MUX_UL11"},
1354 {"DL1 Mixer", "Multimedia", "MM_DL VMixer"},
1355 {"MM_DL VMixer", NULL, "MM_DL"},
1356 {"MM_DL VMixer", NULL, "MM_DL_LP"},
1357
1358 /* Sidetone Mixer */
1359 {"Sidetone Mixer", "Playback", "DL1 Mixer"},
1360 {"Sidetone Mixer", "Capture", "Sidetone Capture VMixer"},
1361 {"Sidetone Capture VMixer", NULL, "MUX_VX0"},
1362 {"Sidetone Capture VMixer", NULL, "MUX_VX1"},
1363
1364 /* Playback Output selection after DL1 Gain */
1365 {"DL1 BT_VX", "Switch", "Sidetone Mixer"},
1366 {"DL1 MM_EXT", "Switch", "Sidetone Mixer"},
1367 {"DL1 PDM", "Switch", "Sidetone Mixer"},
1368 {"PDM_DL1", NULL, "DL1 PDM"},
1369 {"BT_VX_DL", NULL, "DL1 BT_VX"},
1370 {"MM_EXT_DL", NULL, "DL1 MM_EXT"},
1371
1372 /* Handsfree (DL2) playback path */
1373 {"DL2 Mixer", "Tones", "TONES_DL"},
1374 {"DL2 Mixer", "Voice", "VX DL VMixer"},
1375 {"DL2 Mixer", "Capture", "DL2 Capture VMixer"},
1376 {"DL2 Capture VMixer", NULL, "MUX_UL10"},
1377 {"DL2 Capture VMixer", NULL, "MUX_UL11"},
1378 {"DL2 Mixer", "Multimedia", "MM_DL VMixer"},
1379 {"MM_DL VMixer", NULL, "MM_DL"},
1380 {"MM_DL VMixer", NULL, "MM_DL_LP"},
1381 {"PDM_DL2", NULL, "DL2 Mixer"},
1382
1383 /* VxREC Mixer */
1384 {"Capture Mixer", "Tones", "TONES_DL"},
1385 {"Capture Mixer", "Voice Playback", "VX DL VMixer"},
1386 {"Capture Mixer", "Voice Capture", "VX UL VMixer"},
1387 {"Capture Mixer", "Media Playback", "MM_DL VMixer"},
1388 {"MM_DL VMixer", NULL, "MM_DL"},
1389 {"MM_DL VMixer", NULL, "MM_DL_LP"},
1390
1391 /* Audio UL mixer */
1392 {"Voice Capture Mixer", "Tones Playback", "TONES_DL"},
1393 {"Voice Capture Mixer", "Media Playback", "MM_DL VMixer"},
1394 {"MM_DL VMixer", NULL, "MM_DL"},
1395 {"MM_DL VMixer", NULL, "MM_DL_LP"},
1396 {"Voice Capture Mixer", "Capture", "Voice Capture VMixer"},
1397 {"Voice Capture VMixer", NULL, "MUX_VX0"},
1398 {"Voice Capture VMixer", NULL, "MUX_VX1"},
1399
1400 /* BT */
1401 {"VX UL VMixer", NULL, "Voice Capture Mixer"},
1402
1403 /* Vibra */
1404 {"PDM_VIB", NULL, "VIB_DL"},
1405
1406 /* VX and MODEM */
1407 {"VX_UL", NULL, "VX UL VMixer"},
1408 {"MODEM_UL", NULL, "VX UL VMixer"},
1409 {"VX DL VMixer", NULL, "VX_DL"},
1410 {"VX DL VMixer", NULL, "MODEM_DL"},
1411
1412 /* Backend Enablement - TODO: maybe re-work*/
1413 {"BE_OUT", NULL, "PDM_DL1"},
1414 {"BE_OUT", NULL, "PDM_DL2"},
1415 {"BE_OUT", NULL, "PDM_VIB"},
1416 {"BE_OUT", NULL, "MM_EXT_DL"},
1417 {"BE_OUT", NULL, "BT_VX_DL"},
1418 {"PDM_UL1", NULL, "BE_IN"},
1419 {"BT_VX_UL", NULL, "BE_IN"},
1420 {"MM_EXT_UL", NULL, "BE_IN"},
1421 {"DMIC0", NULL, "BE_IN"},
1422 {"DMIC1", NULL, "BE_IN"},
1423 {"DMIC2", NULL, "BE_IN"},
1424};
1425
1426#ifdef CONFIG_DEBUG_FS
1427
1428static int abe_dbg_get_dma_pos(struct abe_data *abe)
1429{
1430 return omap_get_dma_dst_pos(abe->dma_ch) - abe->dbg_buffer_addr;
1431}
1432
1433static void abe_dbg_dma_irq(int ch, u16 stat, void *data)
1434{
1435}
1436
1437static int abe_dbg_start_dma(struct abe_data *abe, int circular)
1438{
1439 struct omap_dma_channel_params dma_params;
1440 int err;
1441
1442 /* TODO: start the DMA in either :-
1443 *
1444 * 1) circular buffer mode where the DMA will restart when it get to
1445 * the end of the buffer.
1446 * 2) default mode, where DMA stops at the end of the buffer.
1447 */
1448
1449 abe->dma_req = OMAP44XX_DMA_ABE_REQ_7;
1450 err = omap_request_dma(abe->dma_req, "ABE debug",
1451 abe_dbg_dma_irq, abe, &abe->dma_ch);
1452 if (abe->dbg_circular) {
1453 /*
1454 * Link channel with itself so DMA doesn't need any
1455 * reprogramming while looping the buffer
1456 */
1457 omap_dma_link_lch(abe->dma_ch, abe->dma_ch);
1458 }
1459
1460 memset(&dma_params, 0, sizeof(dma_params));
1461 dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
1462 dma_params.trigger = abe->dma_req;
1463 dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
1464 dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
1465 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
1466 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
1467 dma_params.src_start = D_DEBUG_FIFO_ADDR + ABE_DMEM_BASE_ADDRESS_L3;
1468 dma_params.dst_start = abe->dbg_buffer_addr;
1469 dma_params.src_port = OMAP_DMA_PORT_MPUI;
1470 dma_params.src_ei = 1;
1471 dma_params.src_fi = 1 - abe->dbg_elem_bytes;
1472
1473 dma_params.elem_count = abe->dbg_elem_bytes >> 2; /* 128 bytes shifted into words */
1474 dma_params.frame_count = abe->dbg_buffer_bytes / abe->dbg_elem_bytes;
1475 omap_set_dma_params(abe->dma_ch, &dma_params);
1476
1477 omap_enable_dma_irq(abe->dma_ch, OMAP_DMA_FRAME_IRQ);
1478 omap_set_dma_src_burst_mode(abe->dma_ch, OMAP_DMA_DATA_BURST_16);
1479 omap_set_dma_dest_burst_mode(abe->dma_ch, OMAP_DMA_DATA_BURST_16);
1480
1481 abe->dbg_reader_offset = 0;
1482
1483 pm_runtime_get_sync(abe->dev);
1484 omap_start_dma(abe->dma_ch);
1485 return 0;
1486}
1487
1488static void abe_dbg_stop_dma(struct abe_data *abe)
1489{
1490 while (omap_get_dma_active_status(abe->dma_ch))
1491 omap_stop_dma(abe->dma_ch);
1492
1493 if (abe->dbg_circular)
1494 omap_dma_unlink_lch(abe->dma_ch, abe->dma_ch);
1495 omap_free_dma(abe->dma_ch);
1496 pm_runtime_put_sync(abe->dev);
1497}
1498
1499static int abe_open_data(struct inode *inode, struct file *file)
1500{
1501 struct abe_data *abe = inode->i_private;
1502
1503 abe->dbg_elem_bytes = 128; /* size of debug data per tick */
1504
1505 if (abe->dbg_format1)
1506 abe->dbg_elem_bytes += ABE_DBG_FLAG1_SIZE;
1507 if (abe->dbg_format2)
1508 abe->dbg_elem_bytes += ABE_DBG_FLAG2_SIZE;
1509 if (abe->dbg_format3)
1510 abe->dbg_elem_bytes += ABE_DBG_FLAG3_SIZE;
1511
1512 abe->dbg_buffer_bytes = abe->dbg_elem_bytes * 4 *
1513 abe->dbg_buffer_msecs;
1514
1515 abe->dbg_buffer = dma_alloc_writecombine(abe->dev,
1516 abe->dbg_buffer_bytes, &abe->dbg_buffer_addr, GFP_KERNEL);
1517 if (abe->dbg_buffer == NULL)
1518 return -ENOMEM;
1519
1520 file->private_data = inode->i_private;
1521 abe->dbg_complete = 0;
1522 abe_dbg_start_dma(abe, abe->dbg_circular);
1523
1524 return 0;
1525}
1526
1527static int abe_release_data(struct inode *inode, struct file *file)
1528{
1529 struct abe_data *abe = inode->i_private;
1530
1531 abe_dbg_stop_dma(abe);
1532
1533 dma_free_writecombine(abe->dev, abe->dbg_buffer_bytes,
1534 abe->dbg_buffer, abe->dbg_buffer_addr);
1535 return 0;
1536}
1537
1538static ssize_t abe_copy_to_user(struct abe_data *abe, char __user *user_buf,
1539 size_t count)
1540{
1541 /* check for reader buffer wrap */
1542 if (abe->dbg_reader_offset + count > abe->dbg_buffer_bytes) {
1543 int size = abe->dbg_buffer_bytes - abe->dbg_reader_offset;
1544
1545 /* wrap */
1546 if (copy_to_user(user_buf,
1547 abe->dbg_buffer + abe->dbg_reader_offset, size))
1548 return -EFAULT;
1549
1550 /* need to just return if non circular */
1551 if (!abe->dbg_circular) {
1552 abe->dbg_complete = 1;
1553 return count;
1554 }
1555
1556 if (copy_to_user(user_buf,
1557 abe->dbg_buffer, count - size))
1558 return -EFAULT;
1559 abe->dbg_reader_offset = count - size;
1560 return count;
1561 } else {
1562 /* no wrap */
1563 if (copy_to_user(user_buf,
1564 abe->dbg_buffer + abe->dbg_reader_offset, count))
1565 return -EFAULT;
1566 abe->dbg_reader_offset += count;
1567
1568 if (!abe->dbg_circular &&
1569 abe->dbg_reader_offset == abe->dbg_buffer_bytes)
1570 abe->dbg_complete = 1;
1571
1572 return count;
1573 }
1574}
1575
1576static ssize_t abe_read_data(struct file *file, char __user *user_buf,
1577 size_t count, loff_t *ppos)
1578{
1579 ssize_t ret = 0;
1580 struct abe_data *abe = file->private_data;
1581 DECLARE_WAITQUEUE(wait, current);
1582 int dma_offset, bytes;
1583
1584 add_wait_queue(&abe->wait, &wait);
1585 do {
1586 set_current_state(TASK_INTERRUPTIBLE);
1587 /* TODO: Check if really needed. Or adjust sleep delay
1588 * If not delay trace is not working */
1589 msleep_interruptible(1);
1590 dma_offset = abe_dbg_get_dma_pos(abe);
1591
1592 /* is DMA finished ? */
1593 if (abe->dbg_complete)
1594 break;
1595
1596 /* get maximum amount of debug bytes we can read */
1597 if (dma_offset >= abe->dbg_reader_offset) {
1598 /* dma ptr is ahead of reader */
1599 bytes = dma_offset - abe->dbg_reader_offset;
1600 } else {
1601 /* dma ptr is behind reader */
1602 bytes = dma_offset + abe->dbg_buffer_bytes -
1603 abe->dbg_reader_offset;
1604 }
1605
1606 if (count > bytes)
1607 count = bytes;
1608
1609 if (count > 0) {
1610 ret = abe_copy_to_user(abe, user_buf, count);
1611 break;
1612 }
1613
1614 if (file->f_flags & O_NONBLOCK) {
1615 ret = -EAGAIN;
1616 break;
1617 }
1618
1619 if (signal_pending(current)) {
1620 ret = -ERESTARTSYS;
1621 break;
1622 }
1623
1624 schedule();
1625
1626 } while (1);
1627
1628 __set_current_state(TASK_RUNNING);
1629 remove_wait_queue(&abe->wait, &wait);
1630
1631 return ret;
1632}
1633
1634static const struct file_operations abe_data_fops = {
1635 .open = abe_open_data,
1636 .read = abe_read_data,
1637 .release = abe_release_data,
1638};
1639
1640static void abe_init_debugfs(struct abe_data *abe)
1641{
1642 abe->debugfs_root = debugfs_create_dir("omap4-abe", NULL);
1643 if (!abe->debugfs_root) {
1644 printk(KERN_WARNING "ABE: Failed to create debugfs directory\n");
1645 return;
1646 }
1647
1648 abe->debugfs_fmt1 = debugfs_create_bool("format1", 0644,
1649 abe->debugfs_root,
1650 &abe->dbg_format1);
1651 if (!abe->debugfs_fmt1)
1652 printk(KERN_WARNING "ABE: Failed to create format1 debugfs file\n");
1653
1654 abe->debugfs_fmt2 = debugfs_create_bool("format2", 0644,
1655 abe->debugfs_root,
1656 &abe->dbg_format2);
1657 if (!abe->debugfs_fmt2)
1658 printk(KERN_WARNING "ABE: Failed to create format2 debugfs file\n");
1659
1660 abe->debugfs_fmt3 = debugfs_create_bool("format3", 0644,
1661 abe->debugfs_root,
1662 &abe->dbg_format3);
1663 if (!abe->debugfs_fmt3)
1664 printk(KERN_WARNING "ABE: Failed to create format3 debugfs file\n");
1665
1666 abe->debugfs_elem_bytes = debugfs_create_u32("element_bytes", 0604,
1667 abe->debugfs_root,
1668 &abe->dbg_elem_bytes);
1669 if (!abe->debugfs_elem_bytes)
1670 printk(KERN_WARNING "ABE: Failed to create element size debugfs file\n");
1671
1672 abe->debugfs_size = debugfs_create_u32("msecs", 0644,
1673 abe->debugfs_root,
1674 &abe->dbg_buffer_msecs);
1675 if (!abe->debugfs_size)
1676 printk(KERN_WARNING "ABE: Failed to create buffer size debugfs file\n");
1677
1678 abe->debugfs_circ = debugfs_create_bool("circular", 0644,
1679 abe->debugfs_root,
1680 &abe->dbg_circular);
1681 if (!abe->debugfs_size)
1682 printk(KERN_WARNING "ABE: Failed to create circular mode debugfs file\n");
1683
1684 abe->debugfs_data = debugfs_create_file("debug", 0644,
1685 abe->debugfs_root,
1686 abe, &abe_data_fops);
1687 if (!abe->debugfs_data)
1688 printk(KERN_WARNING "ABE: Failed to create data debugfs file\n");
1689
1690 abe->debugfs_opp_level = debugfs_create_u32("opp_level", 0604,
1691 abe->debugfs_root,
1692 &abe->opp);
1693 if (!abe->debugfs_opp_level)
1694 printk(KERN_WARNING "ABE: Failed to create OPP level debugfs file\n");
1695
1696 abe->dbg_buffer_msecs = 500;
1697 init_waitqueue_head(&abe->wait);
1698}
1699
1700static void abe_cleanup_debugfs(struct abe_data *abe)
1701{
1702 debugfs_remove_recursive(abe->debugfs_root);
1703}
1704
1705#else
1706
1707static inline void abe_init_debugfs(struct abe_data *abe)
1708{
1709}
1710
1711static inline void abe_cleanup_debugfs(struct abe_data *abe)
1712{
1713}
1714#endif
1715
1716static const struct snd_pcm_hardware omap_abe_hardware = {
1717 .info = SNDRV_PCM_INFO_MMAP |
1718 SNDRV_PCM_INFO_MMAP_VALID |
1719 SNDRV_PCM_INFO_INTERLEAVED |
1720 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1721 SNDRV_PCM_INFO_PAUSE |
1722 SNDRV_PCM_INFO_RESUME,
1723 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1724 SNDRV_PCM_FMTBIT_S32_LE,
1725 .period_bytes_min = 4 * 1024,
1726 .period_bytes_max = 24 * 1024,
1727 .periods_min = 2,
1728 .periods_max = 2,
1729 .buffer_bytes_max = 24 * 1024 * 2,
1730};
1731
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001732
1733static int abe_set_opp_mode(struct abe_data *abe)
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001734{
1735 int i, opp = 0;
1736
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001737 /* now calculate OPP level based upon DAPM widget status */
1738 for (i = 0; i < ABE_NUM_WIDGETS; i++) {
1739 if (abe->widget_opp[ABE_WIDGET(i)]) {
1740 dev_dbg(abe->dev, "OPP: id %d = %d%%\n", i,
1741 abe->widget_opp[ABE_WIDGET(i)] * 25);
1742 opp |= abe->widget_opp[ABE_WIDGET(i)];
1743 }
1744 }
1745 opp = (1 << (fls(opp) - 1)) * 25;
1746
1747 if (abe->opp > opp) {
1748 /* Decrease OPP mode - no need of OPP100% */
1749 switch (opp) {
1750 case 25:
1751 abe_set_opp_processing(ABE_OPP25);
1752 udelay(250);
1753 omap_device_set_rate(abe->dev, abe->dev, 49150000);
1754 break;
1755 case 50:
1756 default:
1757 abe_set_opp_processing(ABE_OPP50);
1758 udelay(250);
1759 omap_device_set_rate(abe->dev, abe->dev, 98300000);
1760 break;
1761 }
1762 } else if (abe->opp < opp) {
1763 /* Increase OPP mode */
1764 switch (opp) {
1765 case 25:
1766 omap_device_set_rate(abe->dev, abe->dev, 49000000);
1767 abe_set_opp_processing(ABE_OPP25);
1768 break;
1769 case 50:
1770 omap_device_set_rate(abe->dev, abe->dev, 98300000);
1771 abe_set_opp_processing(ABE_OPP50);
1772 break;
1773 case 100:
1774 default:
1775 omap_device_set_rate(abe->dev, abe->dev, 196600000);
1776 abe_set_opp_processing(ABE_OPP100);
1777 break;
1778 }
1779 }
1780 abe->opp = opp;
1781 dev_dbg(abe->dev, "new OPP level is %d\n", opp);
1782
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001783 return 0;
1784}
1785
1786static int aess_set_runtime_opp_level(struct abe_data *abe)
1787{
1788 mutex_lock(&abe->opp_mutex);
1789
1790 pm_runtime_get_sync(abe->dev);
1791 abe_set_opp_mode(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001792 pm_runtime_put_sync(abe->dev);
1793
1794 mutex_unlock(&abe->opp_mutex);
1795
1796 return 0;
1797}
1798
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001799static int aess_save_context(struct abe_data *abe)
1800{
1801 struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata;
1802
1803 /* TODO: Find a better way to save/retore gains after OFF mode */
1804
1805 abe_mute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER);
1806 abe_mute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER);
1807 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL);
1808 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES);
1809 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK);
1810 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL);
1811 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES);
1812 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL);
1813 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL);
1814 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL);
1815 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_MM_DL);
1816 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_MM_UL2);
1817 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_VX_DL);
1818 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_TONES);
1819 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_TONES);
1820 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_VX_DL);
1821 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_MM_DL);
1822 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_MM_UL2);
1823 abe_mute_gain(MIXECHO, MIX_ECHO_DL1);
1824 abe_mute_gain(MIXECHO, MIX_ECHO_DL2);
1825 abe_mute_gain(GAINS_DMIC1, GAIN_LEFT_OFFSET);
1826 abe_mute_gain(GAINS_DMIC1, GAIN_RIGHT_OFFSET);
1827 abe_mute_gain(GAINS_DMIC2, GAIN_LEFT_OFFSET);
1828 abe_mute_gain(GAINS_DMIC2, GAIN_RIGHT_OFFSET);
1829 abe_mute_gain(GAINS_DMIC3, GAIN_LEFT_OFFSET);
1830 abe_mute_gain(GAINS_DMIC3, GAIN_RIGHT_OFFSET);
1831 abe_mute_gain(GAINS_AMIC, GAIN_LEFT_OFFSET);
1832 abe_mute_gain(GAINS_AMIC, GAIN_RIGHT_OFFSET);
1833
1834 if (pdata->get_context_loss_count)
1835 abe->loss_count = pdata->get_context_loss_count(abe->dev);
1836
1837 return 0;
1838}
1839
1840static int aess_restore_context(struct abe_data *abe)
1841{
1842 struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata;
1843 int loss_count = 0;
1844
1845 omap_device_set_rate(&abe->dev, &abe->dev, 98000000);
1846
1847 if (pdata->get_context_loss_count)
1848 loss_count = pdata->get_context_loss_count(abe->dev);
1849
1850 if (loss_count != the_abe->loss_count)
1851 abe_reload_fw();
1852
1853 /* TODO: Find a better way to save/retore gains after dor OFF mode */
1854 abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER);
1855 abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER);
1856 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL);
1857 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES);
1858 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK);
1859 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL);
1860 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES);
1861 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL);
1862 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL);
1863 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL);
1864 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_MM_DL);
1865 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_MM_UL2);
1866 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_VX_DL);
1867 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_TONES);
1868 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_TONES);
1869 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_VX_DL);
1870 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_MM_DL);
1871 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_MM_UL2);
1872 abe_unmute_gain(MIXECHO, MIX_ECHO_DL1);
1873 abe_unmute_gain(MIXECHO, MIX_ECHO_DL2);
1874 abe_unmute_gain(GAINS_DMIC1, GAIN_LEFT_OFFSET);
1875 abe_unmute_gain(GAINS_DMIC1, GAIN_RIGHT_OFFSET);
1876 abe_unmute_gain(GAINS_DMIC2, GAIN_LEFT_OFFSET);
1877 abe_unmute_gain(GAINS_DMIC2, GAIN_RIGHT_OFFSET);
1878 abe_unmute_gain(GAINS_DMIC3, GAIN_LEFT_OFFSET);
1879 abe_unmute_gain(GAINS_DMIC3, GAIN_RIGHT_OFFSET);
1880 abe_unmute_gain(GAINS_AMIC, GAIN_LEFT_OFFSET);
1881 abe_unmute_gain(GAINS_AMIC, GAIN_RIGHT_OFFSET);
1882/*
1883 abe_dsp_set_equalizer(EQ1, abe->dl1_equ_profile);
1884 abe_dsp_set_equalizer(EQ2L, abe->dl20_equ_profile);
1885 abe_dsp_set_equalizer(EQ2R, abe->dl21_equ_profile);
1886 abe_dsp_set_equalizer(EQAMIC, abe->amic_equ_profile);
1887 abe_dsp_set_equalizer(EQDMIC, abe->dmic_equ_profile);
1888 abe_dsp_set_equalizer(EQSDT, abe->sdt_equ_profile);
1889*/
1890 abe_set_router_configuration(UPROUTE, 0, (u32 *)abe->router);
1891
1892 return 0;
1893}
1894
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001895static int aess_open(struct snd_pcm_substream *substream)
1896{
1897 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1898 struct snd_soc_platform *platform = rtd->platform;
1899 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
1900 struct snd_soc_dai *dai = rtd->cpu_dai;
1901 int ret = 0;
1902
1903 mutex_lock(&abe->mutex);
1904
1905 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
1906
1907 pm_runtime_get_sync(abe->dev);
1908
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001909 if (!abe->active++) {
1910 abe->opp = 0;
1911 aess_restore_context(abe);
1912 abe_set_opp_mode(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001913 abe_wakeup();
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001914 }
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001915
1916 switch (dai->id) {
1917 case ABE_FRONTEND_DAI_MODEM:
1918 break;
1919 case ABE_FRONTEND_DAI_LP_MEDIA:
1920 snd_soc_set_runtime_hwparams(substream, &omap_abe_hardware);
1921 ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
1922 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024);
1923 break;
1924 default:
1925 break;
1926 }
1927
1928 mutex_unlock(&abe->mutex);
1929 return ret;
1930}
1931
1932static int aess_hw_params(struct snd_pcm_substream *substream,
1933 struct snd_pcm_hw_params *params)
1934{
1935 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1936 struct snd_pcm_runtime *runtime = substream->runtime;
1937 struct snd_soc_platform *platform = rtd->platform;
1938 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
1939 struct snd_soc_dai *dai = rtd->cpu_dai;
1940 abe_data_format_t format;
1941 size_t period_size;
1942 u32 dst;
1943
1944 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
1945
1946 if (dai->id != ABE_FRONTEND_DAI_LP_MEDIA)
1947 return 0;
1948
1949 /*Storing substream pointer for irq*/
1950 abe->ping_pong_substream = substream;
1951
1952 format.f = params_rate(params);
1953 if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
1954 format.samp_format = STEREO_MSB;
1955 else
1956 format.samp_format = STEREO_16_16;
1957
1958 if (format.f == 44100)
1959 abe_write_event_generator(EVENT_44100);
1960
1961 period_size = params_period_bytes(params);
1962
1963 /*Adding ping pong buffer subroutine*/
1964 abe_plug_subroutine(&abe_irq_pingpong_player_id,
1965 (abe_subroutine2) abe_irq_pingpong_subroutine,
1966 SUB_1_PARAM, (u32 *)abe);
1967
1968 /* Connect a Ping-Pong cache-flush protocol to MM_DL port */
1969 abe_connect_irq_ping_pong_port(MM_DL_PORT, &format,
1970 abe_irq_pingpong_player_id,
1971 period_size, &dst,
1972 PING_PONG_WITH_MCU_IRQ);
1973
1974 /* Memory mapping for hw params */
1975 runtime->dma_area = abe->io_base[0] + dst;
1976 runtime->dma_addr = 0;
1977 runtime->dma_bytes = period_size * 2;
1978
1979 /* Need to set the first buffer in order to get interrupt */
1980 abe_set_ping_pong_buffer(MM_DL_PORT, period_size);
1981 abe->first_irq = 1;
1982
1983 return 0;
1984}
1985
1986static int aess_prepare(struct snd_pcm_substream *substream)
1987{
1988 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1989 struct snd_soc_platform *platform = rtd->platform;
1990 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
1991 struct snd_soc_dai *dai = rtd->cpu_dai;
1992
1993 mutex_lock(&abe->mutex);
1994 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
1995 aess_set_runtime_opp_level(abe);
1996 mutex_unlock(&abe->mutex);
1997 return 0;
1998}
1999
2000static int aess_close(struct snd_pcm_substream *substream)
2001{
2002 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2003 struct snd_soc_platform *platform = rtd->platform;
2004 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2005 struct snd_soc_dai *dai = rtd->cpu_dai;
2006
2007 mutex_lock(&abe->mutex);
2008 aess_set_runtime_opp_level(abe);
2009
2010 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
2011
2012 if (!--abe->active) {
2013 abe_disable_irq();
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002014 aess_save_context(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002015 abe_dsp_shutdown();
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002016 }
2017
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002018 pm_runtime_put_sync(abe->dev);
2019
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002020 mutex_unlock(&abe->mutex);
2021 return 0;
2022}
2023
2024static int aess_mmap(struct snd_pcm_substream *substream,
2025 struct vm_area_struct *vma)
2026{
2027 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2028 struct snd_soc_dai *dai = rtd->cpu_dai;
2029 int offset, size, err;
2030
2031 if (dai->id != ABE_FRONTEND_DAI_LP_MEDIA)
2032 return -EINVAL;
2033
2034 vma->vm_flags |= VM_IO | VM_RESERVED;
2035 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
2036 size = vma->vm_end - vma->vm_start;
2037 offset = vma->vm_pgoff << PAGE_SHIFT;
2038
2039 err = io_remap_pfn_range(vma, vma->vm_start,
2040 (ABE_DMEM_BASE_ADDRESS_MPU +
2041 ABE_DMEM_BASE_OFFSET_PING_PONG + offset) >> PAGE_SHIFT,
2042 size, vma->vm_page_prot);
2043
2044 if (err)
2045 return -EAGAIN;
2046
2047 return 0;
2048}
2049
2050static snd_pcm_uframes_t aess_pointer(struct snd_pcm_substream *substream)
2051{
2052 snd_pcm_uframes_t offset;
2053 u32 pingpong;
2054
2055 abe_read_offset_from_ping_buffer(MM_DL_PORT, &pingpong);
2056 offset = (snd_pcm_uframes_t)pingpong;
2057
2058 return offset;
2059}
2060
2061static struct snd_pcm_ops omap_aess_pcm_ops = {
2062 .open = aess_open,
2063 .hw_params = aess_hw_params,
2064 .prepare = aess_prepare,
2065 .close = aess_close,
2066 .pointer = aess_pointer,
2067 .mmap = aess_mmap,
2068};
2069
2070#if CONFIG_PM
2071static int aess_suspend(struct device *dev)
2072{
2073 struct abe_data *abe = dev_get_drvdata(dev);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002074
2075 pm_runtime_get_sync(abe->dev);
2076
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002077 aess_save_context(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002078
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002079 pm_runtime_put_sync(abe->dev);
2080
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002081 return 0;
2082}
2083
2084static int aess_resume(struct device *dev)
2085{
2086 struct abe_data *abe = dev_get_drvdata(dev);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002087
2088 pm_runtime_get_sync(abe->dev);
2089
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002090 aess_restore_context(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002091
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002092 pm_runtime_put_sync(abe->dev);
2093
2094 return 0;
2095}
2096
2097#else
2098#define aess_suspend NULL
2099#define aess_resume NULL
2100#endif
2101
2102static const struct dev_pm_ops aess_pm_ops = {
2103 .suspend = aess_suspend,
2104 .resume = aess_resume,
2105};
2106
2107static int aess_stream_event(struct snd_soc_dapm_context *dapm)
2108{
2109 struct snd_soc_platform *platform = dapm->platform;
2110 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2111
2112 pm_runtime_get_sync(abe->dev);
2113
2114 if (abe->active)
2115 aess_set_runtime_opp_level(abe);
2116
2117 pm_runtime_put_sync(abe->dev);
2118
2119 return 0;
2120}
2121
2122static int abe_add_widgets(struct snd_soc_platform *platform)
2123{
2124 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2125 struct fw_header *hdr = &abe->hdr;
2126 int i, j;
2127
2128#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2129 /* create equalizer controls */
2130 for (i = 0; i < hdr->num_equ; i++) {
2131 struct soc_enum *equalizer_enum = &abe->equalizer_enum[i];
2132 struct snd_kcontrol_new *equalizer_control =
2133 &abe->equalizer_control[i];
2134
2135 equalizer_enum->reg = i;
2136 equalizer_enum->max = abe->equ_texts[i].count;
2137 for (j = 0; j < abe->equ_texts[i].count; j++)
2138 equalizer_enum->dtexts[j] = abe->equ_texts[i].texts[j];
2139
2140 equalizer_control->name = abe->equ_texts[i].name;
2141 equalizer_control->private_value = (unsigned long)equalizer_enum;
2142 equalizer_control->get = abe_get_equalizer;
2143 equalizer_control->put = abe_put_equalizer;
2144 equalizer_control->info = snd_soc_info_enum_ext1;
2145 equalizer_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2146
2147 dev_dbg(platform->dev, "added EQU mixer: %s profiles %d\n",
2148 abe->equ_texts[i].name, abe->equ_texts[i].count);
2149
2150 for (j = 0; j < abe->equ_texts[i].count; j++)
2151 dev_dbg(platform->dev, " %s\n", equalizer_enum->dtexts[j]);
2152 }
2153
2154 snd_soc_add_platform_controls(platform, abe->equalizer_control,
2155 hdr->num_equ);
2156#endif
2157
2158 snd_soc_add_platform_controls(platform, abe_controls,
2159 ARRAY_SIZE(abe_controls));
2160
2161 snd_soc_dapm_new_controls(&platform->dapm, abe_dapm_widgets,
2162 ARRAY_SIZE(abe_dapm_widgets));
2163
2164 snd_soc_dapm_add_routes(&platform->dapm, intercon, ARRAY_SIZE(intercon));
2165
2166 snd_soc_dapm_new_widgets(&platform->dapm);
2167
2168 return 0;
2169}
2170
2171static int abe_probe(struct snd_soc_platform *platform)
2172{
2173 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2174 const struct firmware *fw;
2175#ifndef CONFIG_PM_RUNTIME
2176 struct omap4_abe_dsp_pdata *pdata = priv->abe_pdata;
2177#endif
2178 int ret = 0, i, offset = 0;
2179
2180 abe->platform = platform;
2181
2182 pm_runtime_enable(abe->dev);
2183
2184#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2185 /* request firmware & coefficients */
2186 ret = request_firmware(&fw, "omap4_abe", platform->dev);
2187 if (ret != 0) {
2188 dev_err(abe->dev, "Failed to load firmware: %d\n", ret);
2189 return ret;
2190 }
2191
2192 /* get firmware and coefficients header info */
2193 memcpy(&abe->hdr, fw->data, sizeof(struct fw_header));
2194 if (abe->hdr.firmware_size > ABE_MAX_FW_SIZE) {
2195 dev_err(abe->dev, "Firmware too large at %d bytes: %d\n",
2196 abe->hdr.firmware_size, ret);
2197 ret = -EINVAL;
2198 goto err_fw;
2199 }
2200 dev_dbg(abe->dev, "ABE firmware size %d bytes\n", abe->hdr.firmware_size);
2201
2202 if (abe->hdr.coeff_size > ABE_MAX_COEFF_SIZE) {
2203 dev_err(abe->dev, "Coefficients too large at %d bytes: %d\n",
2204 abe->hdr.coeff_size, ret);
2205 ret = -EINVAL;
2206 goto err_fw;
2207 }
2208 dev_dbg(abe->dev, "ABE coefficients size %d bytes\n", abe->hdr.coeff_size);
2209
2210 /* get coefficient EQU mixer strings */
2211 if (abe->hdr.num_equ >= ABE_MAX_EQU) {
2212 dev_err(abe->dev, "Too many equalizers got %d\n", abe->hdr.num_equ);
2213 ret = -EINVAL;
2214 goto err_fw;
2215 }
2216 abe->equ_texts = kzalloc(abe->hdr.num_equ * sizeof(struct coeff_config),
2217 GFP_KERNEL);
2218 if (abe->equ_texts == NULL) {
2219 ret = -ENOMEM;
2220 goto err_fw;
2221 }
2222 offset = sizeof(struct fw_header);
2223 memcpy(abe->equ_texts, fw->data + offset,
2224 abe->hdr.num_equ * sizeof(struct coeff_config));
2225
2226 /* get coefficients from firmware */
2227 abe->equ[0] = kmalloc(abe->hdr.coeff_size, GFP_KERNEL);
2228 if (abe->equ[0] == NULL) {
2229 ret = -ENOMEM;
2230 goto err_equ;
2231 }
2232 offset += abe->hdr.num_equ * sizeof(struct coeff_config);
2233 memcpy(abe->equ[0], fw->data + offset, abe->hdr.coeff_size);
2234
2235 /* allocate coefficient mixer texts */
2236 dev_dbg(abe->dev, "loaded %d equalizers\n", abe->hdr.num_equ);
2237 for (i = 0; i < abe->hdr.num_equ; i++) {
2238 dev_dbg(abe->dev, "equ %d: %s profiles %d\n", i,
2239 abe->equ_texts[i].name, abe->equ_texts[i].count);
2240 if (abe->equ_texts[i].count >= ABE_MAX_PROFILES) {
2241 dev_err(abe->dev, "Too many profiles got %d for equ %d\n",
2242 abe->equ_texts[i].count, i);
2243 ret = -EINVAL;
2244 goto err_texts;
2245 }
2246 abe->equalizer_enum[i].dtexts =
2247 kzalloc(abe->equ_texts[i].count * sizeof(char *), GFP_KERNEL);
2248 if (abe->equalizer_enum[i].dtexts == NULL) {
2249 ret = -ENOMEM;
2250 goto err_texts;
2251 }
2252 }
2253
2254 /* initialise coefficient equalizers */
2255 for (i = 1; i < abe->hdr.num_equ; i++) {
2256 abe->equ[i] = abe->equ[i - 1] +
2257 abe->equ_texts[i - 1].count * abe->equ_texts[i - 1].coeff * sizeof(s32);
2258 }
2259#endif
2260 ret = request_irq(abe->irq, abe_irq_handler, 0, "ABE", (void *)abe);
2261 if (ret) {
2262 dev_err(platform->dev, "request for ABE IRQ %d failed %d\n",
2263 abe->irq, ret);
2264 goto err_texts;
2265 }
2266
2267 /* aess_clk has to be enabled to access hal register.
2268 * Disable the clk after it has been used.
2269 */
2270 pm_runtime_get_sync(abe->dev);
2271
2272 abe_init_mem(abe->io_base);
2273
2274 abe_reset_hal();
2275
2276#if 0
2277#warning fixup load fw args
2278 //abe_load_fw(fw->data + sizeof(struct fw_header) + abe->hdr.coeff_size);
2279#else
2280 abe_load_fw();
2281#endif
2282 /* Config OPP 100 for now */
2283 abe_set_opp_processing(ABE_OPP100);
2284
2285 /* "tick" of the audio engine */
2286 abe_write_event_generator(EVENT_TIMER);
2287 /* Stop the engine */
2288 abe_stop_event_generator();
2289 abe_disable_irq();
2290
2291 pm_runtime_put_sync(abe->dev);
2292 abe_add_widgets(platform);
2293
2294#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2295 release_firmware(fw);
2296#endif
2297 return ret;
2298
2299err_texts:
2300#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2301 for (i = 0; i < abe->hdr.num_equ; i++)
2302 kfree(abe->equalizer_enum[i].texts);
2303 kfree(abe->equ[0]);
2304err_equ:
2305 kfree(abe->equ_texts);
2306err_fw:
2307 release_firmware(fw);
2308#endif
2309 return ret;
2310}
2311
2312static int abe_remove(struct snd_soc_platform *platform)
2313{
2314 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2315 int i;
2316
2317 free_irq(abe->irq, (void *)abe);
2318
2319#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2320 for (i = 0; i < abe->hdr.num_equ; i++)
2321 kfree(abe->equalizer_enum[i].texts);
2322
2323 kfree(abe->equ[0]);
2324 kfree(abe->equ_texts);
2325#endif
2326 pm_runtime_disable(abe->dev);
2327
2328 return 0;
2329}
2330
2331static struct snd_soc_platform_driver omap_aess_platform = {
2332 .ops = &omap_aess_pcm_ops,
2333 .probe = abe_probe,
2334 .remove = abe_remove,
2335 .read = abe_dsp_read,
2336 .write = abe_dsp_write,
2337 .stream_event = aess_stream_event,
2338};
2339
2340static int __devinit abe_engine_probe(struct platform_device *pdev)
2341{
2342 struct resource *res;
2343 struct omap4_abe_dsp_pdata *pdata = pdev->dev.platform_data;
2344 struct abe_data *abe;
Misael Lopez Cruz5ae9cf52011-07-12 05:17:16 -05002345 int ret = -EINVAL, i;
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002346
2347 abe = kzalloc(sizeof(struct abe_data), GFP_KERNEL);
2348 if (abe == NULL)
2349 return -ENOMEM;
2350 dev_set_drvdata(&pdev->dev, abe);
2351 the_abe = abe;
2352
2353 /* ZERO_labelID should really be 0 */
2354 for (i = 0; i < ABE_ROUTES_UL + 2; i++)
2355 abe->router[i] = ZERO_labelID;
2356
2357 for (i = 0; i < 5; i++) {
2358 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2359 abe_memory_bank[i]);
2360 if (res == NULL) {
2361 dev_err(&pdev->dev, "no resource %s\n",
2362 abe_memory_bank[i]);
2363 goto err;
2364 }
2365 abe->io_base[i] = ioremap(res->start, resource_size(res));
2366 if (!abe->io_base[i]) {
2367 ret = -ENOMEM;
2368 goto err;
2369 }
2370 }
2371
2372 abe->irq = platform_get_irq(pdev, 0);
2373 if (abe->irq < 0) {
2374 ret = abe->irq;
2375 goto err;
2376 }
2377
2378 abe->abe_pdata = pdata;
2379 abe->dev = &pdev->dev;
2380 mutex_init(&abe->mutex);
2381 mutex_init(&abe->opp_mutex);
2382
2383 ret = snd_soc_register_platform(abe->dev,
2384 &omap_aess_platform);
2385 if (ret < 0)
2386 return ret;
2387
2388 abe_init_debugfs(abe);
2389 return ret;
2390
2391err:
2392 for (--i; i >= 0; i--)
2393 iounmap(abe->io_base[i]);
2394 kfree(abe);
2395 return ret;
2396}
2397
2398static int __devexit abe_engine_remove(struct platform_device *pdev)
2399{
2400 struct abe_data *abe = dev_get_drvdata(&pdev->dev);
2401 int i;
2402
2403 abe_cleanup_debugfs(abe);
2404 snd_soc_unregister_platform(&pdev->dev);
2405 for (i = 0; i < 5; i++)
2406 iounmap(abe->io_base[i]);
2407 kfree(abe);
2408 return 0;
2409}
2410
2411static struct platform_driver omap_aess_driver = {
2412 .driver = {
2413 .name = "aess",
2414 .owner = THIS_MODULE,
2415 .pm = &aess_pm_ops,
2416 },
2417 .probe = abe_engine_probe,
2418 .remove = __devexit_p(abe_engine_remove),
2419};
2420
2421static int __init abe_engine_init(void)
2422{
2423 return platform_driver_register(&omap_aess_driver);
2424}
2425module_init(abe_engine_init);
2426
2427static void __exit abe_engine_exit(void)
2428{
2429 platform_driver_unregister(&omap_aess_driver);
2430}
2431module_exit(abe_engine_exit);
2432
2433MODULE_DESCRIPTION("ASoC OMAP4 ABE");
2434MODULE_AUTHOR("Liam Girdwood <lrg@ti.com>");
2435MODULE_LICENSE("GPL");