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