blob: 9d3d93a3b1670120cbe31946933f0ca8444f3a68 [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;
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -0500123 u32 *firmware;
Liam Girdwooda8d99da2011-02-03 15:28:19 +0000124 s32 *equ[ABE_MAX_EQU];
125 int equ_profile[ABE_MAX_EQU];
126 struct soc_enum equalizer_enum[ABE_MAX_EQU];
127 struct snd_kcontrol_new equalizer_control[ABE_MAX_EQU];
128 struct coeff_config *equ_texts;
129
130 /* DAPM mixer config - TODO: some of this can be replaced with HAL update */
131 u32 widget_opp[ABE_NUM_DAPM_REG + 1];
132
133 u16 router[16];
134 int loss_count;
135
136 struct snd_pcm_substream *ping_pong_substream;
137 int first_irq;
138
139 struct snd_pcm_substream *psubs;
140
141#ifdef CONFIG_DEBUG_FS
142 /* ABE runtime debug config */
143
144 /* its intended we can switch on/off individual debug items */
145 u32 dbg_format1; /* TODO: match flag names here to debug format flags */
146 u32 dbg_format2;
147 u32 dbg_format3;
148
149 u32 dbg_buffer_bytes;
150 u32 dbg_circular;
151 u32 dbg_buffer_msecs; /* size of buffer in secs */
152 u32 dbg_elem_bytes;
153 dma_addr_t dbg_buffer_addr;
154 wait_queue_head_t wait;
155 int dbg_reader_offset;
156 int dbg_dma_offset;
157 int dbg_complete;
158 struct dentry *debugfs_root;
159 struct dentry *debugfs_fmt1;
160 struct dentry *debugfs_fmt2;
161 struct dentry *debugfs_fmt3;
162 struct dentry *debugfs_size;
163 struct dentry *debugfs_data;
164 struct dentry *debugfs_circ;
165 struct dentry *debugfs_elem_bytes;
166 struct dentry *debugfs_opp_level;
167 char *dbg_buffer;
168 struct omap_pcm_dma_data *dma_data;
169 int dma_ch;
170 int dma_req;
171#endif
172};
173
174static struct abe_data *the_abe;
175
176// TODO: map to the new version of HAL
177static unsigned int abe_dsp_read(struct snd_soc_platform *platform,
178 unsigned int reg)
179{
180 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
181
182 BUG_ON(reg > ABE_NUM_DAPM_REG);
183 return abe->widget_opp[reg];
184}
185
186static int abe_dsp_write(struct snd_soc_platform *platform, unsigned int reg,
187 unsigned int val)
188{
189 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
190
191 BUG_ON(reg > ABE_NUM_DAPM_REG);
192 abe->widget_opp[reg] = val;
193 return 0;
194}
195
196static void abe_irq_pingpong_subroutine(u32 *data)
197{
Liam Girdwooda8d99da2011-02-03 15:28:19 +0000198 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
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001733
1734static int abe_set_opp_mode(struct abe_data *abe)
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001735{
1736 int i, opp = 0;
1737
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001738 /* now calculate OPP level based upon DAPM widget status */
1739 for (i = 0; i < ABE_NUM_WIDGETS; i++) {
1740 if (abe->widget_opp[ABE_WIDGET(i)]) {
1741 dev_dbg(abe->dev, "OPP: id %d = %d%%\n", i,
1742 abe->widget_opp[ABE_WIDGET(i)] * 25);
1743 opp |= abe->widget_opp[ABE_WIDGET(i)];
1744 }
1745 }
1746 opp = (1 << (fls(opp) - 1)) * 25;
1747
1748 if (abe->opp > opp) {
1749 /* Decrease OPP mode - no need of OPP100% */
1750 switch (opp) {
1751 case 25:
1752 abe_set_opp_processing(ABE_OPP25);
1753 udelay(250);
1754 omap_device_set_rate(abe->dev, abe->dev, 49150000);
1755 break;
1756 case 50:
1757 default:
1758 abe_set_opp_processing(ABE_OPP50);
1759 udelay(250);
1760 omap_device_set_rate(abe->dev, abe->dev, 98300000);
1761 break;
1762 }
1763 } else if (abe->opp < opp) {
1764 /* Increase OPP mode */
1765 switch (opp) {
1766 case 25:
1767 omap_device_set_rate(abe->dev, abe->dev, 49000000);
1768 abe_set_opp_processing(ABE_OPP25);
1769 break;
1770 case 50:
1771 omap_device_set_rate(abe->dev, abe->dev, 98300000);
1772 abe_set_opp_processing(ABE_OPP50);
1773 break;
1774 case 100:
1775 default:
1776 omap_device_set_rate(abe->dev, abe->dev, 196600000);
1777 abe_set_opp_processing(ABE_OPP100);
1778 break;
1779 }
1780 }
1781 abe->opp = opp;
1782 dev_dbg(abe->dev, "new OPP level is %d\n", opp);
1783
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001784 return 0;
1785}
1786
1787static int aess_set_runtime_opp_level(struct abe_data *abe)
1788{
1789 mutex_lock(&abe->opp_mutex);
1790
1791 pm_runtime_get_sync(abe->dev);
1792 abe_set_opp_mode(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001793 pm_runtime_put_sync(abe->dev);
1794
1795 mutex_unlock(&abe->opp_mutex);
1796
1797 return 0;
1798}
1799
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001800static int aess_save_context(struct abe_data *abe)
1801{
1802 struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata;
1803
1804 /* TODO: Find a better way to save/retore gains after OFF mode */
1805
1806 abe_mute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER);
1807 abe_mute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER);
1808 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL);
1809 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES);
1810 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK);
1811 abe_mute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL);
1812 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES);
1813 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL);
1814 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL);
1815 abe_mute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL);
1816 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_MM_DL);
1817 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_MM_UL2);
1818 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_VX_DL);
1819 abe_mute_gain(MIXDL1, MIX_DL1_INPUT_TONES);
1820 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_TONES);
1821 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_VX_DL);
1822 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_MM_DL);
1823 abe_mute_gain(MIXDL2, MIX_DL2_INPUT_MM_UL2);
1824 abe_mute_gain(MIXECHO, MIX_ECHO_DL1);
1825 abe_mute_gain(MIXECHO, MIX_ECHO_DL2);
1826 abe_mute_gain(GAINS_DMIC1, GAIN_LEFT_OFFSET);
1827 abe_mute_gain(GAINS_DMIC1, GAIN_RIGHT_OFFSET);
1828 abe_mute_gain(GAINS_DMIC2, GAIN_LEFT_OFFSET);
1829 abe_mute_gain(GAINS_DMIC2, GAIN_RIGHT_OFFSET);
1830 abe_mute_gain(GAINS_DMIC3, GAIN_LEFT_OFFSET);
1831 abe_mute_gain(GAINS_DMIC3, GAIN_RIGHT_OFFSET);
1832 abe_mute_gain(GAINS_AMIC, GAIN_LEFT_OFFSET);
1833 abe_mute_gain(GAINS_AMIC, GAIN_RIGHT_OFFSET);
1834
1835 if (pdata->get_context_loss_count)
1836 abe->loss_count = pdata->get_context_loss_count(abe->dev);
1837
1838 return 0;
1839}
1840
1841static int aess_restore_context(struct abe_data *abe)
1842{
1843 struct omap4_abe_dsp_pdata *pdata = abe->abe_pdata;
1844 int loss_count = 0;
1845
1846 omap_device_set_rate(&abe->dev, &abe->dev, 98000000);
1847
1848 if (pdata->get_context_loss_count)
1849 loss_count = pdata->get_context_loss_count(abe->dev);
1850
1851 if (loss_count != the_abe->loss_count)
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -05001852 abe_reload_fw(abe->firmware);
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001853
1854 /* TODO: Find a better way to save/retore gains after dor OFF mode */
1855 abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_UP_MIXER);
1856 abe_unmute_gain(MIXSDT, MIX_SDT_INPUT_DL1_MIXER);
1857 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_MM_DL);
1858 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_TONES);
1859 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_UPLINK);
1860 abe_unmute_gain(MIXAUDUL, MIX_AUDUL_INPUT_VX_DL);
1861 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_TONES);
1862 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_DL);
1863 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_MM_DL);
1864 abe_unmute_gain(MIXVXREC, MIX_VXREC_INPUT_VX_UL);
1865 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_MM_DL);
1866 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_MM_UL2);
1867 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_VX_DL);
1868 abe_unmute_gain(MIXDL1, MIX_DL1_INPUT_TONES);
1869 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_TONES);
1870 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_VX_DL);
1871 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_MM_DL);
1872 abe_unmute_gain(MIXDL2, MIX_DL2_INPUT_MM_UL2);
1873 abe_unmute_gain(MIXECHO, MIX_ECHO_DL1);
1874 abe_unmute_gain(MIXECHO, MIX_ECHO_DL2);
1875 abe_unmute_gain(GAINS_DMIC1, GAIN_LEFT_OFFSET);
1876 abe_unmute_gain(GAINS_DMIC1, GAIN_RIGHT_OFFSET);
1877 abe_unmute_gain(GAINS_DMIC2, GAIN_LEFT_OFFSET);
1878 abe_unmute_gain(GAINS_DMIC2, GAIN_RIGHT_OFFSET);
1879 abe_unmute_gain(GAINS_DMIC3, GAIN_LEFT_OFFSET);
1880 abe_unmute_gain(GAINS_DMIC3, GAIN_RIGHT_OFFSET);
1881 abe_unmute_gain(GAINS_AMIC, GAIN_LEFT_OFFSET);
1882 abe_unmute_gain(GAINS_AMIC, GAIN_RIGHT_OFFSET);
1883/*
1884 abe_dsp_set_equalizer(EQ1, abe->dl1_equ_profile);
1885 abe_dsp_set_equalizer(EQ2L, abe->dl20_equ_profile);
1886 abe_dsp_set_equalizer(EQ2R, abe->dl21_equ_profile);
1887 abe_dsp_set_equalizer(EQAMIC, abe->amic_equ_profile);
1888 abe_dsp_set_equalizer(EQDMIC, abe->dmic_equ_profile);
1889 abe_dsp_set_equalizer(EQSDT, abe->sdt_equ_profile);
1890*/
1891 abe_set_router_configuration(UPROUTE, 0, (u32 *)abe->router);
1892
1893 return 0;
1894}
1895
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001896static int aess_open(struct snd_pcm_substream *substream)
1897{
1898 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1899 struct snd_soc_platform *platform = rtd->platform;
1900 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
1901 struct snd_soc_dai *dai = rtd->cpu_dai;
1902 int ret = 0;
1903
1904 mutex_lock(&abe->mutex);
1905
1906 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
1907
1908 pm_runtime_get_sync(abe->dev);
1909
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001910 if (!abe->active++) {
1911 abe->opp = 0;
1912 aess_restore_context(abe);
1913 abe_set_opp_mode(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001914 abe_wakeup();
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02001915 }
Liam Girdwooda8d99da2011-02-03 15:28:19 +00001916
1917 switch (dai->id) {
1918 case ABE_FRONTEND_DAI_MODEM:
1919 break;
1920 case ABE_FRONTEND_DAI_LP_MEDIA:
1921 snd_soc_set_runtime_hwparams(substream, &omap_abe_hardware);
1922 ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
1923 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024);
1924 break;
1925 default:
1926 break;
1927 }
1928
1929 mutex_unlock(&abe->mutex);
1930 return ret;
1931}
1932
1933static int aess_hw_params(struct snd_pcm_substream *substream,
1934 struct snd_pcm_hw_params *params)
1935{
1936 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1937 struct snd_pcm_runtime *runtime = substream->runtime;
1938 struct snd_soc_platform *platform = rtd->platform;
1939 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
1940 struct snd_soc_dai *dai = rtd->cpu_dai;
1941 abe_data_format_t format;
1942 size_t period_size;
1943 u32 dst;
1944
1945 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
1946
1947 if (dai->id != ABE_FRONTEND_DAI_LP_MEDIA)
1948 return 0;
1949
1950 /*Storing substream pointer for irq*/
1951 abe->ping_pong_substream = substream;
1952
1953 format.f = params_rate(params);
1954 if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
1955 format.samp_format = STEREO_MSB;
1956 else
1957 format.samp_format = STEREO_16_16;
1958
1959 if (format.f == 44100)
1960 abe_write_event_generator(EVENT_44100);
1961
1962 period_size = params_period_bytes(params);
1963
1964 /*Adding ping pong buffer subroutine*/
1965 abe_plug_subroutine(&abe_irq_pingpong_player_id,
1966 (abe_subroutine2) abe_irq_pingpong_subroutine,
1967 SUB_1_PARAM, (u32 *)abe);
1968
1969 /* Connect a Ping-Pong cache-flush protocol to MM_DL port */
1970 abe_connect_irq_ping_pong_port(MM_DL_PORT, &format,
1971 abe_irq_pingpong_player_id,
1972 period_size, &dst,
1973 PING_PONG_WITH_MCU_IRQ);
1974
1975 /* Memory mapping for hw params */
1976 runtime->dma_area = abe->io_base[0] + dst;
1977 runtime->dma_addr = 0;
1978 runtime->dma_bytes = period_size * 2;
1979
1980 /* Need to set the first buffer in order to get interrupt */
1981 abe_set_ping_pong_buffer(MM_DL_PORT, period_size);
1982 abe->first_irq = 1;
1983
1984 return 0;
1985}
1986
1987static int aess_prepare(struct snd_pcm_substream *substream)
1988{
1989 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1990 struct snd_soc_platform *platform = rtd->platform;
1991 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
1992 struct snd_soc_dai *dai = rtd->cpu_dai;
1993
1994 mutex_lock(&abe->mutex);
1995 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
1996 aess_set_runtime_opp_level(abe);
1997 mutex_unlock(&abe->mutex);
1998 return 0;
1999}
2000
2001static int aess_close(struct snd_pcm_substream *substream)
2002{
2003 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2004 struct snd_soc_platform *platform = rtd->platform;
2005 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2006 struct snd_soc_dai *dai = rtd->cpu_dai;
2007
2008 mutex_lock(&abe->mutex);
2009 aess_set_runtime_opp_level(abe);
2010
2011 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
2012
2013 if (!--abe->active) {
2014 abe_disable_irq();
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002015 aess_save_context(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002016 abe_dsp_shutdown();
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002017 }
2018
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002019 pm_runtime_put_sync(abe->dev);
2020
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002021 mutex_unlock(&abe->mutex);
2022 return 0;
2023}
2024
2025static int aess_mmap(struct snd_pcm_substream *substream,
2026 struct vm_area_struct *vma)
2027{
2028 struct snd_soc_pcm_runtime *rtd = substream->private_data;
2029 struct snd_soc_dai *dai = rtd->cpu_dai;
2030 int offset, size, err;
2031
2032 if (dai->id != ABE_FRONTEND_DAI_LP_MEDIA)
2033 return -EINVAL;
2034
2035 vma->vm_flags |= VM_IO | VM_RESERVED;
2036 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
2037 size = vma->vm_end - vma->vm_start;
2038 offset = vma->vm_pgoff << PAGE_SHIFT;
2039
2040 err = io_remap_pfn_range(vma, vma->vm_start,
2041 (ABE_DMEM_BASE_ADDRESS_MPU +
2042 ABE_DMEM_BASE_OFFSET_PING_PONG + offset) >> PAGE_SHIFT,
2043 size, vma->vm_page_prot);
2044
2045 if (err)
2046 return -EAGAIN;
2047
2048 return 0;
2049}
2050
2051static snd_pcm_uframes_t aess_pointer(struct snd_pcm_substream *substream)
2052{
2053 snd_pcm_uframes_t offset;
2054 u32 pingpong;
2055
2056 abe_read_offset_from_ping_buffer(MM_DL_PORT, &pingpong);
2057 offset = (snd_pcm_uframes_t)pingpong;
2058
2059 return offset;
2060}
2061
2062static struct snd_pcm_ops omap_aess_pcm_ops = {
2063 .open = aess_open,
2064 .hw_params = aess_hw_params,
2065 .prepare = aess_prepare,
2066 .close = aess_close,
2067 .pointer = aess_pointer,
2068 .mmap = aess_mmap,
2069};
2070
2071#if CONFIG_PM
2072static int aess_suspend(struct device *dev)
2073{
2074 struct abe_data *abe = dev_get_drvdata(dev);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002075
2076 pm_runtime_get_sync(abe->dev);
2077
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002078 aess_save_context(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002079
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002080 pm_runtime_put_sync(abe->dev);
2081
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002082 return 0;
2083}
2084
2085static int aess_resume(struct device *dev)
2086{
2087 struct abe_data *abe = dev_get_drvdata(dev);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002088
2089 pm_runtime_get_sync(abe->dev);
2090
Sebastien Guiriecb2f30fb2011-07-04 14:36:34 +02002091 aess_restore_context(abe);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002092
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002093 pm_runtime_put_sync(abe->dev);
2094
2095 return 0;
2096}
2097
2098#else
2099#define aess_suspend NULL
2100#define aess_resume NULL
2101#endif
2102
2103static const struct dev_pm_ops aess_pm_ops = {
2104 .suspend = aess_suspend,
2105 .resume = aess_resume,
2106};
2107
2108static int aess_stream_event(struct snd_soc_dapm_context *dapm)
2109{
2110 struct snd_soc_platform *platform = dapm->platform;
2111 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2112
2113 pm_runtime_get_sync(abe->dev);
2114
2115 if (abe->active)
2116 aess_set_runtime_opp_level(abe);
2117
2118 pm_runtime_put_sync(abe->dev);
2119
2120 return 0;
2121}
2122
2123static int abe_add_widgets(struct snd_soc_platform *platform)
2124{
2125 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2126 struct fw_header *hdr = &abe->hdr;
2127 int i, j;
2128
2129#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2130 /* create equalizer controls */
2131 for (i = 0; i < hdr->num_equ; i++) {
2132 struct soc_enum *equalizer_enum = &abe->equalizer_enum[i];
2133 struct snd_kcontrol_new *equalizer_control =
2134 &abe->equalizer_control[i];
2135
2136 equalizer_enum->reg = i;
2137 equalizer_enum->max = abe->equ_texts[i].count;
2138 for (j = 0; j < abe->equ_texts[i].count; j++)
2139 equalizer_enum->dtexts[j] = abe->equ_texts[i].texts[j];
2140
2141 equalizer_control->name = abe->equ_texts[i].name;
2142 equalizer_control->private_value = (unsigned long)equalizer_enum;
2143 equalizer_control->get = abe_get_equalizer;
2144 equalizer_control->put = abe_put_equalizer;
2145 equalizer_control->info = snd_soc_info_enum_ext1;
2146 equalizer_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2147
2148 dev_dbg(platform->dev, "added EQU mixer: %s profiles %d\n",
2149 abe->equ_texts[i].name, abe->equ_texts[i].count);
2150
2151 for (j = 0; j < abe->equ_texts[i].count; j++)
2152 dev_dbg(platform->dev, " %s\n", equalizer_enum->dtexts[j]);
2153 }
2154
2155 snd_soc_add_platform_controls(platform, abe->equalizer_control,
2156 hdr->num_equ);
2157#endif
2158
2159 snd_soc_add_platform_controls(platform, abe_controls,
2160 ARRAY_SIZE(abe_controls));
2161
2162 snd_soc_dapm_new_controls(&platform->dapm, abe_dapm_widgets,
2163 ARRAY_SIZE(abe_dapm_widgets));
2164
2165 snd_soc_dapm_add_routes(&platform->dapm, intercon, ARRAY_SIZE(intercon));
2166
2167 snd_soc_dapm_new_widgets(&platform->dapm);
2168
2169 return 0;
2170}
2171
2172static int abe_probe(struct snd_soc_platform *platform)
2173{
2174 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2175 const struct firmware *fw;
2176#ifndef CONFIG_PM_RUNTIME
2177 struct omap4_abe_dsp_pdata *pdata = priv->abe_pdata;
2178#endif
2179 int ret = 0, i, offset = 0;
2180
2181 abe->platform = platform;
2182
2183 pm_runtime_enable(abe->dev);
2184
2185#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2186 /* request firmware & coefficients */
2187 ret = request_firmware(&fw, "omap4_abe", platform->dev);
2188 if (ret != 0) {
2189 dev_err(abe->dev, "Failed to load firmware: %d\n", ret);
2190 return ret;
2191 }
2192
2193 /* get firmware and coefficients header info */
2194 memcpy(&abe->hdr, fw->data, sizeof(struct fw_header));
2195 if (abe->hdr.firmware_size > ABE_MAX_FW_SIZE) {
2196 dev_err(abe->dev, "Firmware too large at %d bytes: %d\n",
2197 abe->hdr.firmware_size, ret);
2198 ret = -EINVAL;
2199 goto err_fw;
2200 }
2201 dev_dbg(abe->dev, "ABE firmware size %d bytes\n", abe->hdr.firmware_size);
2202
2203 if (abe->hdr.coeff_size > ABE_MAX_COEFF_SIZE) {
2204 dev_err(abe->dev, "Coefficients too large at %d bytes: %d\n",
2205 abe->hdr.coeff_size, ret);
2206 ret = -EINVAL;
2207 goto err_fw;
2208 }
2209 dev_dbg(abe->dev, "ABE coefficients size %d bytes\n", abe->hdr.coeff_size);
2210
2211 /* get coefficient EQU mixer strings */
2212 if (abe->hdr.num_equ >= ABE_MAX_EQU) {
2213 dev_err(abe->dev, "Too many equalizers got %d\n", abe->hdr.num_equ);
2214 ret = -EINVAL;
2215 goto err_fw;
2216 }
2217 abe->equ_texts = kzalloc(abe->hdr.num_equ * sizeof(struct coeff_config),
2218 GFP_KERNEL);
2219 if (abe->equ_texts == NULL) {
2220 ret = -ENOMEM;
2221 goto err_fw;
2222 }
2223 offset = sizeof(struct fw_header);
2224 memcpy(abe->equ_texts, fw->data + offset,
2225 abe->hdr.num_equ * sizeof(struct coeff_config));
2226
2227 /* get coefficients from firmware */
2228 abe->equ[0] = kmalloc(abe->hdr.coeff_size, GFP_KERNEL);
2229 if (abe->equ[0] == NULL) {
2230 ret = -ENOMEM;
2231 goto err_equ;
2232 }
2233 offset += abe->hdr.num_equ * sizeof(struct coeff_config);
2234 memcpy(abe->equ[0], fw->data + offset, abe->hdr.coeff_size);
2235
2236 /* allocate coefficient mixer texts */
2237 dev_dbg(abe->dev, "loaded %d equalizers\n", abe->hdr.num_equ);
2238 for (i = 0; i < abe->hdr.num_equ; i++) {
2239 dev_dbg(abe->dev, "equ %d: %s profiles %d\n", i,
2240 abe->equ_texts[i].name, abe->equ_texts[i].count);
2241 if (abe->equ_texts[i].count >= ABE_MAX_PROFILES) {
2242 dev_err(abe->dev, "Too many profiles got %d for equ %d\n",
2243 abe->equ_texts[i].count, i);
2244 ret = -EINVAL;
2245 goto err_texts;
2246 }
2247 abe->equalizer_enum[i].dtexts =
2248 kzalloc(abe->equ_texts[i].count * sizeof(char *), GFP_KERNEL);
2249 if (abe->equalizer_enum[i].dtexts == NULL) {
2250 ret = -ENOMEM;
2251 goto err_texts;
2252 }
2253 }
2254
2255 /* initialise coefficient equalizers */
2256 for (i = 1; i < abe->hdr.num_equ; i++) {
2257 abe->equ[i] = abe->equ[i - 1] +
2258 abe->equ_texts[i - 1].count * abe->equ_texts[i - 1].coeff * sizeof(s32);
2259 }
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -05002260
2261 /* store ABE firmware for later context restore */
2262 abe->firmware = kzalloc(abe->hdr.firmware_size, GFP_KERNEL);
2263 memcpy(abe->firmware,
2264 fw->data + sizeof(struct fw_header) + abe->hdr.coeff_size,
2265 abe->hdr.firmware_size);
2266#else
2267 abe->firmware = abe_get_default_fw();
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002268#endif
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -05002269
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002270 ret = request_irq(abe->irq, abe_irq_handler, 0, "ABE", (void *)abe);
2271 if (ret) {
2272 dev_err(platform->dev, "request for ABE IRQ %d failed %d\n",
2273 abe->irq, ret);
2274 goto err_texts;
2275 }
2276
2277 /* aess_clk has to be enabled to access hal register.
2278 * Disable the clk after it has been used.
2279 */
2280 pm_runtime_get_sync(abe->dev);
2281
2282 abe_init_mem(abe->io_base);
2283
2284 abe_reset_hal();
2285
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -05002286 abe_load_fw(abe->firmware);
2287
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002288 /* Config OPP 100 for now */
2289 abe_set_opp_processing(ABE_OPP100);
2290
2291 /* "tick" of the audio engine */
2292 abe_write_event_generator(EVENT_TIMER);
2293 /* Stop the engine */
2294 abe_stop_event_generator();
2295 abe_disable_irq();
2296
2297 pm_runtime_put_sync(abe->dev);
2298 abe_add_widgets(platform);
2299
2300#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2301 release_firmware(fw);
2302#endif
2303 return ret;
2304
2305err_texts:
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -05002306 kfree(abe->firmware);
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002307#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2308 for (i = 0; i < abe->hdr.num_equ; i++)
2309 kfree(abe->equalizer_enum[i].texts);
2310 kfree(abe->equ[0]);
2311err_equ:
2312 kfree(abe->equ_texts);
2313err_fw:
2314 release_firmware(fw);
2315#endif
2316 return ret;
2317}
2318
2319static int abe_remove(struct snd_soc_platform *platform)
2320{
2321 struct abe_data *abe = snd_soc_platform_get_drvdata(platform);
2322 int i;
2323
2324 free_irq(abe->irq, (void *)abe);
2325
2326#if defined(CONFIG_SND_OMAP_SOC_ABE_DSP_MODULE)
2327 for (i = 0; i < abe->hdr.num_equ; i++)
2328 kfree(abe->equalizer_enum[i].texts);
2329
2330 kfree(abe->equ[0]);
2331 kfree(abe->equ_texts);
2332#endif
Misael Lopez Cruz7c8913a2011-07-12 07:04:43 -05002333 kfree(abe->firmware);
2334
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002335 pm_runtime_disable(abe->dev);
2336
2337 return 0;
2338}
2339
2340static struct snd_soc_platform_driver omap_aess_platform = {
2341 .ops = &omap_aess_pcm_ops,
2342 .probe = abe_probe,
2343 .remove = abe_remove,
2344 .read = abe_dsp_read,
2345 .write = abe_dsp_write,
2346 .stream_event = aess_stream_event,
2347};
2348
2349static int __devinit abe_engine_probe(struct platform_device *pdev)
2350{
2351 struct resource *res;
2352 struct omap4_abe_dsp_pdata *pdata = pdev->dev.platform_data;
2353 struct abe_data *abe;
Misael Lopez Cruz5ae9cf52011-07-12 05:17:16 -05002354 int ret = -EINVAL, i;
Liam Girdwooda8d99da2011-02-03 15:28:19 +00002355
2356 abe = kzalloc(sizeof(struct abe_data), GFP_KERNEL);
2357 if (abe == NULL)
2358 return -ENOMEM;
2359 dev_set_drvdata(&pdev->dev, abe);
2360 the_abe = abe;
2361
2362 /* ZERO_labelID should really be 0 */
2363 for (i = 0; i < ABE_ROUTES_UL + 2; i++)
2364 abe->router[i] = ZERO_labelID;
2365
2366 for (i = 0; i < 5; i++) {
2367 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
2368 abe_memory_bank[i]);
2369 if (res == NULL) {
2370 dev_err(&pdev->dev, "no resource %s\n",
2371 abe_memory_bank[i]);
2372 goto err;
2373 }
2374 abe->io_base[i] = ioremap(res->start, resource_size(res));
2375 if (!abe->io_base[i]) {
2376 ret = -ENOMEM;
2377 goto err;
2378 }
2379 }
2380
2381 abe->irq = platform_get_irq(pdev, 0);
2382 if (abe->irq < 0) {
2383 ret = abe->irq;
2384 goto err;
2385 }
2386
2387 abe->abe_pdata = pdata;
2388 abe->dev = &pdev->dev;
2389 mutex_init(&abe->mutex);
2390 mutex_init(&abe->opp_mutex);
2391
2392 ret = snd_soc_register_platform(abe->dev,
2393 &omap_aess_platform);
2394 if (ret < 0)
2395 return ret;
2396
2397 abe_init_debugfs(abe);
2398 return ret;
2399
2400err:
2401 for (--i; i >= 0; i--)
2402 iounmap(abe->io_base[i]);
2403 kfree(abe);
2404 return ret;
2405}
2406
2407static int __devexit abe_engine_remove(struct platform_device *pdev)
2408{
2409 struct abe_data *abe = dev_get_drvdata(&pdev->dev);
2410 int i;
2411
2412 abe_cleanup_debugfs(abe);
2413 snd_soc_unregister_platform(&pdev->dev);
2414 for (i = 0; i < 5; i++)
2415 iounmap(abe->io_base[i]);
2416 kfree(abe);
2417 return 0;
2418}
2419
2420static struct platform_driver omap_aess_driver = {
2421 .driver = {
2422 .name = "aess",
2423 .owner = THIS_MODULE,
2424 .pm = &aess_pm_ops,
2425 },
2426 .probe = abe_engine_probe,
2427 .remove = __devexit_p(abe_engine_remove),
2428};
2429
2430static int __init abe_engine_init(void)
2431{
2432 return platform_driver_register(&omap_aess_driver);
2433}
2434module_init(abe_engine_init);
2435
2436static void __exit abe_engine_exit(void)
2437{
2438 platform_driver_unregister(&omap_aess_driver);
2439}
2440module_exit(abe_engine_exit);
2441
2442MODULE_DESCRIPTION("ASoC OMAP4 ABE");
2443MODULE_AUTHOR("Liam Girdwood <lrg@ti.com>");
2444MODULE_LICENSE("GPL");