[alsa-devel] [PATCH 01/19] ALSA: add Yamaha YMU831 codec support
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/Kconfig | 6 ++++++ sound/soc/codecs/Makefile | 1 + sound/soc/codecs/ymu831/Makefile | 3 +++ 3 files changed, 10 insertions(+) create mode 100644 sound/soc/codecs/ymu831/Makefile
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 3a84782..bb405b87 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -122,6 +122,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM9705 if SND_SOC_AC97_BUS select SND_SOC_WM9712 if SND_SOC_AC97_BUS select SND_SOC_WM9713 if SND_SOC_AC97_BUS + select SND_SOC_YMU831 if SPI_MASTER help Normally ASoC codec drivers are only built if a machine driver which uses them is also built since they are only usable with a machine @@ -494,6 +495,11 @@ config SND_SOC_WM9712 config SND_SOC_WM9713 tristate
+config SND_SOC_YMU831 + tristate + select SND_HWDEP + + # Amp config SND_SOC_LM4857 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index f6e8e36..1d31783 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -236,6 +236,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o +obj-$(CONFIG_SND_SOC_YMU831) += ymu831/
# Amp obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile new file mode 100644 index 0000000..5b3f66d --- /dev/null +++ b/sound/soc/codecs/ymu831/Makefile @@ -0,0 +1,3 @@ +snd-soc-ymu831-objs := \ + +obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/mcdefs.h | 4303 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 4303 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mcdefs.h
diff --git a/sound/soc/codecs/ymu831/mcdefs.h b/sound/soc/codecs/ymu831/mcdefs.h new file mode 100644 index 0000000..fbd2008 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdefs.h @@ -0,0 +1,4303 @@ +/**************************************************************************** + * + * Copyrightc 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcdefs.h + * Description : MC device definitions + * Version : 1.0.1 Dec 18 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +#ifndef _MCDEFS_H +#define _MCDEFS_H + +/* Register Definition + + [Naming Rules] + + MCI_xxx : Registers + MCI_xxx_DEF : Default setting of registers + MCB_xxx : Miscelleneous bit definition +*/ + +/* Registers */ +/* IF_REG */ +#define MCI_A_REG_A 0 +#define MCB_A_REG_AINC 0x80 + +#define MCI_A_REG_D 1 + +#define MCI_RST_A 2 +#define MCB_RST_A 0x01 +#define MCI_RST_A_DEF MCB_RST_A + +#define MCI_RST 3 +#define MCB_PSW_S 0x80 +#define MCB_PSW_M 0x40 +#define MCB_PSW_F 0x20 +#define MCB_PSW_C 0x10 +#define MCB_RST_S 0x08 +#define MCB_RST_M 0x04 +#define MCB_RST_F 0x02 +#define MCB_RST_C 0x01 +#define MCI_RST_DEF (MCB_PSW_S | MCB_RST_S | \ + MCB_PSW_M | MCB_RST_M | \ + MCB_PSW_F | MCB_RST_F | \ + MCB_PSW_C | MCB_RST_C) + +#define MCI_IRQ 4 +#define MCB_IRQ 0x02 +#define MCB_EIRQ 0x01 + +#define MCI_ANA_REG_A 6 +#define MCB_ANA_REG_AINC 0x80 + +#define MCI_ANA_REG_D 7 + +#define MCI_CD_REG_A 8 +#define MCB_CD_REG_AINC 0x80 + +#define MCI_CD_REG_D 9 + +#define MCI_IRQR 10 +#define MCB_IRQR 0x02 +#define MCB_EIRQR 0x01 + +#define MCI_MA_REG_A 12 +#define MCB_MA_REG_AINC 0x80 + +#define MCI_MA_REG_D 13 + +#define MCI_MB_REG_A 14 +#define MCB_MB_REG_AINC 0x80 + +#define MCI_MB_REG_D 15 + +/* IF_REG = #16: B_REG_A + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | B_REG | B_REG_A | + | _AINC | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_B_REG_A 16 +#define MCI_B_REG_A_DEF 0x00 +#define MCB_B_REG_AINC 0x80 +#define MCB_B_REG_A 0x7f + +/* IF_REG = #17: B_REG_D + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | B_REG_D[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_B_REG_D 17 +#define MCI_B_REG_D_DEF 0x00 +#define MCB_B_REG_D 0xff + +/* IF_REG = #18: BMAA0 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | "0" | "0" | BMAA | + | | | | | | | | [16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_BMAA0 18 +#define MCI_BMAA0_DEF 0x00 +#define MCB_BMAA0 0x01 + +/* IF_REG = #19: BMAA1 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | BMAA[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BMAA1 19 +#define MCI_BMAA1_DEF 0x00 +#define MCB_BMAA1 0xff + +/* IF_REG = #20: BMAA2 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | BMAA[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BMAA2 20 +#define MCI_BMAA2_DEF 0x00 +#define MCB_BMAA2 0xff + +/* IF_REG = #21: BMACtl + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | BDSPT | "0" | "0" | "0" | BMAMOD| BMADIR| BMABUS[1:0] | + | INI | | | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BMACTL 21 +#define MCI_BMACTL_DEF 0x00 +#define MCB_BDSPTINI 0x80 +#define MCB_BMAMOD 0x08 +#define MCB_BMAMOD_DMA 0x00 +#define MCB_BMAMOD_DSP 0x08 +#define MCB_BMADIR 0x04 +#define MCB_BMADIR_DL 0x00 +#define MCB_BMADIR_UL 0x04 +#define MCB_BMABUS 0x03 +#define MCB_BMABUS_I 0x02 +#define MCB_BMABUS_Y 0x01 +#define MCB_BMABUS_X 0x00 + +/* IF_REG = #22: BMADat + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | BMAD[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BMAD 22 +#define MCI_BMAD_DEF 0x00 +#define MCB_BMAD 0xff + +/* IF_REG = #23: BDSPTReq + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | BDSP | "0" | "0" | "0" | "0" | "0" | "0" | "0" | + | TREQ | | | | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BDSPTREQ 23 +#define MCI_BDSPTREQ_DEF 0x00 +#define MCB_BDSPTREQ 0x80 + +/* IF_REG = #24: BDSPTCNT + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | "0" | "0" | "0" | "0" | BDSPTCNT[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BDSP_TCNT 24 +#define MCI_BDSP_TCNT_DEF 0x00 +#define MCB_BDSP_TCNT 0x0f + +/* IF_REG = #32: E_REG_A + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | E_REG | E_REG_A[6:0] | + | _AINC | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E_REG_A 32 +#define MCI_E_REG_A_DEF 0x00 +#define MCB_E_REG_AINC 0x80 +#define MCB_E_REG_A 0x7f + +/* IF_REG = #33: E_REG_D + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | E_REG_D[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E_REG_D 33 +#define MCI_E_REG_D_DEF 0x00 +#define MCB_E_REG_D 0xff + +/* IF_REG = #34: EDSP_FW_PAGE + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EDSP_FW_PAGE[2:0] | "0" | "0" | "0" |EDSP_FW| + | | | | | _A[8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EDSP_FW_PAGE 34 +#define MCI_EDSP_FW_PAGE_DEF 0x00 +#define MCB_EDSP_FW_PAGE 0x70 +#define MCB_EDSP_FW_PAGE_E2IMEM 0x10 +#define MCB_EDSP_FW_PAGE_SYSEQ0 0x20 +#define MCB_EDSP_FW_PAGE_SYSEQ1 0x30 +#define MCB_EDSP_FW_PAGE_E2YMEM 0x40 +#define MCB_EDSP_FW_PAGE_E2XMEM 0x60 +#define MCB_EDSP_FW_PAGE_SYSEQ0_B0 0x20 +#define MCB_EDSP_FW_PAGE_SYSEQ1_B0 0x30 +#define MCB_EDSP_FW_PAGE_SYSEQ0_B1 0x80 +#define MCB_EDSP_FW_PAGE_SYSEQ1_B1 0x90 +#define MCB_EDSP_FW_PAGE_SYSEQ0_B2 0xa0 +#define MCB_EDSP_FW_PAGE_SYSEQ1_B2 0xb0 +#define MCB_EDSP_FW_A_8 0x01 + +/* IF_REG = #35: EDSP_FW_A + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EDSP_FW_A[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EDSP_FW_A 35 +#define MCI_EDSP_FW_A_DEF 0x00 +#define MCB_EDSP_FW_A 0xff + +/* IF_REG = #36: EDSP_FW_D + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EDSP_FW_D[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EDSP_FW_D 36 +#define MCI_EDSP_FW_D_DEF 0x00 +#define MCB_EDSP_FW_D 0xff + +/* IF_REG = #37: EDSP_IRQ_CTRL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | EE2DSP| EE2DSP| "0" | "0" | EE1DSP| EE1DSP| + | | | _OV | _STA | | | _OV | _STA | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EEDSP 37 +#define MCI_EEDSP_DEF 0x00 +#define MCB_EE2DSP_OV 0x20 +#define MCB_EE2DSP 0x10 +#define MCB_EE1DSP_OV 0x02 +#define MCB_EE1DSP 0x01 + +/* IF_REG = #38: EDSP_IRQ_FLAG + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | E2DSP | E2DSP | "0" | "0" | E1DSP | E1DSP | + | | | _OV | _STA | | | _OV | _STA | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EDSP 38 +#define MCI_EDSP_DEF 0x00 +#define MCB_E2DSP_OV 0x20 +#define MCB_E2DSP_STA 0x10 +#define MCB_E1DSP_OV 0x02 +#define MCB_E1DSP_STA 0x01 + +#define MCI_C_REG_A 40 + +#define MCI_C_REG_D 41 + +#define MCI_DEC_FIFO 42 + +/* IF_ADR = #43: decoder IRQ control register + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ECDSP | EFFIFO| ERFIFO| EEFIFO| EOFIFO| EDFIFO| EENC | EDEC | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_ECDSP 43 +#define MCB_ECDSP 0x80 +#define MCB_EFFIFO 0x40 +#define MCB_ERFIFO 0x20 +#define MCB_EEFIFO 0x10 +#define MCB_EOFIFO 0x08 +#define MCB_EDFIFO 0x04 +#define MCB_EENC 0x02 +#define MCB_EDEC 0x01 + +/* IF_ADR = #44: decoder IRQ Flag register + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | CDSP | FFIFO | RFIFO | EFIFO | OFIFO | DFIFO | ENC | DEC | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_CDSP 44 +#define MCB_IRQFLAG_CDSP 0x80 +#define MCB_IRQFLAG_FFIFO 0x40 +#define MCB_IRQFLAG_RFIFO 0x20 +#define MCB_IRQFLAG_EFIFO 0x10 +#define MCB_IRQFLAG_OFIFO 0x08 +#define MCB_IRQFLAG_DFIFO 0x04 +#define MCB_IRQFLAG_ENC 0x02 +#define MCB_IRQFLAG_DEC 0x01 +#define MCB_IRQFLAG_CDSP_ALL 0xff + +/* IF_ADR = #45: FFIFO register + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | FSQ_FIFO[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FSQ_FFIFO 45 + +/* IF_ADR = #48: F_REG_A register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | F_REG | F_REG_A[6:0] | + | AINC | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_F_REG_A 48 +#define MCI_F_REG_A_DEF 0x00 +#define MCB_F_REG_AINC 0x80 +#define MCB_F_REG_A 0x7f + +/* IF_ADR = #49: F_REG_D register + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | F_REG_D[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_F_REG_D 49 +#define MCI_F_REG_D_DEF 0x00 +#define MCB_F_REG_D 0xff + +/* IF_ADR = #50: FMAA + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | FMAA[19:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FMAA_19_16 50 +#define MCI_FMAA_19_16_DEF 0x00 +#define MCB_FMAA_19_16 0x0f + +/* IF_ADR = #51: FMAA + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FMAA[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FMAA_15_8 51 +#define MCI_FMAA_15_8_DEF 0x00 +#define MCB_FMAA_15_8 0xff + +/* IF_ADR = #52: FMAA + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FMAA[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FMAA_7_0 52 +#define MCI_FMAA_7_0_DEF 0x00 +#define MCB_FMAA_7_0 0xff + +/* IF_ADR = #53: FDSPTINI + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R |DSPTINI| "0" | "0" | "0" | FMAMOD| FMADIR| FMABUS[1:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FDSPTINI 53 +#define MCI_FDSPTINI_DEF 0x00 +#define MCB_DSPTINI 0x80 +#define MCB_FMAMOD 0x08 +#define MCB_FMAMOD_DMA 0x00 +#define MCB_FMAMOD_DSP 0x08 +#define MCB_FMADIR 0x04 +#define MCB_FMADIR_DL 0x00 +#define MCB_FMADIR_UL 0x04 +#define MCB_FMABUS 0x03 +#define MCB_FMABUS_I 0x02 +#define MCB_FMABUS_Y 0x01 +#define MCB_FMABUS_X 0x00 + +/* IF_ADR = #54: FMAD + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FMAD[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FMAD 54 +#define MCI_FMAD_DEF 0x00 +#define MCB_FMAD 0xff + +/* IF_ADR = #55: DSPTReq + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R |DSPTREQ| "0" | "0" | "0" | "0" | "0" | "0" | "0" | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FDSPTREQ 55 +#define MCI_FDSPTREQ_DEF 0x00 +#define MCB_FDSPTREQ 0x80 + +/* IF_ADR = #57: IENB + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | IESERR| "0" | IEAMT | IEAMT | IEFW[3:0] | + | | | BEG | END | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_IESERR 57 +#define MCI_IESERR_DEF 0x00 +#define MCB_IESERR 0x80 +#define MCB_IEAMTBEG 0x20 +#define MCB_IEAMTEND 0x10 +#define MCB_IEFW 0x0f +#define MCB_IEFW_STRT 0x08 +#define MCB_IEFW_TOP 0x04 +#define MCB_IEFW_APP 0x02 +#define MCB_IEFW_DSP 0x01 + +/* A_ADR = #58: IReq + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | IRSERR| "0" | IRAMT | IRAMT | IRFW[3:0] | + | | | BEG | END | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_IRSERR 58 +#define MCI_IRSERR_DEF 0x00 +#define MCB_IRSERR 0x80 +#define MCB_IRMTBEG 0x20 +#define MCB_IRMTEND 0x10 +#define MCB_IRFW 0x0f +#define MCB_IRFW_STRT 0x08 +#define MCB_IRFW_TOP 0x04 +#define MCB_IRFW_APP 0x02 +#define MCB_IRFW_DSP 0x01 + +/* A_REG */ +#define MCI_A_DEV_ID 0 + +#define MCI_CLK_MSK 1 +#define MCB_RTCI_MSK 0x04 +#define MCB_CLKI1_MSK 0x02 +#define MCB_CLKI0_MSK 0x01 +#define MCI_CLK_MSK_DEF (MCB_RTCI_MSK | MCB_CLKI1_MSK | \ + MCB_CLKI0_MSK) + +#define MCI_PD 2 +#define MCB_PLL_PD 0x80 +#define MCB_ANACLK_PD 0x40 +#define MCB_PE_CLK_PD 0x20 +#define MCB_PB_CLK_PD 0x10 +#define MCB_PM_CLK_PD 0x08 +#define MCB_PF_CLK_PD 0x04 +#define MCB_PC_CLK_PD 0x02 +#define MCB_VCOOUT_PD 0x01 +#define MCI_PD_DEF (MCB_PLL_PD | MCB_ANACLK_PD | \ + MCB_PE_CLK_PD | MCB_PB_CLK_PD |\ + MCB_PM_CLK_PD | MCB_PF_CLK_PD |\ + MCB_PC_CLK_PD | MCB_VCOOUT_PD) + +#define MCI_JTAGSEL 3 +#define MCB_JTAGSEL 0x01 + +#define MCI_DO0_DRV 4 +#define MCB_DO0_DRV 0x80 +#define MCB_BCLK0_INV 0x40 +#define MCB_BCLK0_MSK 0x20 +#define MCB_BCLK0_DDR 0x10 +#define MCB_LRCK0_MSK 0x08 +#define MCB_LRCK0_DDR 0x04 +#define MCB_SDIN0_MSK 0x02 +#define MCB_SDO0_DDR 0x01 +#define MCI_DO0_DRV_DEF (MCB_BCLK0_MSK | \ + MCB_LRCK0_MSK | MCB_SDIN0_MSK) + +#define MCI_DO1_DRV 5 +#define MCB_DO1_DRV 0x80 +#define MCB_BCLK1_INV 0x40 +#define MCB_BCLK1_MSK 0x20 +#define MCB_BCLK1_DDR 0x10 +#define MCB_LRCK1_MSK 0x08 +#define MCB_LRCK1_DDR 0x04 +#define MCB_SDIN1_MSK 0x02 +#define MCB_SDO1_DDR 0x01 +#define MCI_DO1_DRV_DEF (MCB_BCLK1_MSK | \ + MCB_LRCK1_MSK | MCB_SDIN1_MSK) + +#define MCI_DO2_DRV 6 +#define MCB_DO2_DRV 0x80 +#define MCB_BCLK2_INV 0x40 +#define MCB_BCLK2_MSK 0x20 +#define MCB_BCLK2_DDR 0x10 +#define MCB_LRCK2_MSK 0x08 +#define MCB_LRCK2_DDR 0x04 +#define MCB_SDIN2_MSK 0x02 +#define MCB_SDO2_DDR 0x01 +#define MCI_DO2_DRV_DEF (MCB_BCLK2_MSK | \ + MCB_LRCK2_MSK | MCB_SDIN2_MSK) + +#define MCI_PCMOUT_HIZ 8 +#define MCB_PDM2_DATA_DELAY 0x40 +#define MCB_PDM1_DATA_DELAY 0x20 +#define MCB_PDM0_DATA_DELAY 0x10 +#define MCB_PCMOUT2_HIZ 0x04 +#define MCB_PCMOUT1_HIZ 0x02 +#define MCB_PCMOUT0_HIZ 0x01 + +#define MCI_PA0 9 +#define MCB_PA0_OUT 0x80 +#define MCB_PA0_DDR 0x20 +#define MCB_PA0_DATA 0x10 +#define MCB_PA0_OUTSEL 0x04 +#define MCB_PA0_MSK 0x02 +#define MCB_PA0_INV 0x01 +#define MCI_PA0_DEF MCB_PA0_MSK + +#define MCI_PA1 10 +#define MCB_PA1_DDR 0x20 +#define MCB_PA1_DATA 0x10 +#define MCB_PA1_OUTSEL 0x04 +#define MCB_PA1_MSK 0x02 +#define MCB_PA1_INV 0x01 +#define MCI_PA1_DEF MCB_PA1_MSK + +#define MCI_PA2 11 +#define MCB_PA2_DDR 0x20 +#define MCB_PA2_DATA 0x10 +#define MCB_PA2_OUTSEL 0x04 +#define MCB_PA2_MSK 0x02 +#define MCB_PA2_INV 0x01 +#define MCI_PA2_DEF MCB_PA2_MSK + +#define MCI_DOA_DRV 12 +#define MCI_DOA_DRV_DEF 0x80 + +#define MCI_LP0_FP 13 +#define MCI_LP0_FP_DEF 0x00 + +#define MCI_LP1_FP 14 +#define MCI_LP1_FP_DEF 0x01 + +#define MCI_LP2_FP 15 +#define MCI_LP2_FP_DEF 0x02 + +#define MCI_LP3_FP 16 +#define MCI_LP3_FP_DEF 0x03 + +#define MCI_CK_TCX0 17 + +#define MCI_CLKSRC 18 +#define MCB_CLKBUSY 0x80 +#define MCB_CLKSRC 0x20 +#define MCB_CLK_INPUT 0x10 +#define MCI_CLKSRC_DEF 0x04 + +#define MCI_FREQ73M 19 +#define MCI_FREQ73M_DEF 0x00 + +#define MCI_PLL_MODE_A 24 +#define MCI_PLL_MODE_A_DEF 0x04 + +#define MCI_PLL_PREDIV_A 25 + +#define MCI_PLL_FBDIV_A_12_8 26 +#define MCI_PLL_FBDIV_A_7_0 27 + +#define MCI_PLL_FRAC_A_15_8 28 +#define MCI_PLL_FRAC_A_7_0 29 + +#define MCI_PLL_FOUT_A 30 +#define MCB_PLL_FOUT_A 0x02 + +#define MCI_PLL_MODE_B 40 +#define MCI_PLL_MODE_B_DEF 0x04 + +#define MCI_PLL_PREDIV_B 41 + +#define MCI_PLL_FBDIV_B_12_8 42 +#define MCI_PLL_FBDIV_B_7_0 43 + +#define MCI_PLL_FRAC_B_15_8 44 +#define MCI_PLL_FRAC_B_7_0 45 + +#define MCI_PLL_FOUT_B 46 +#define MCB_PLL_FOUT_B 0x02 + +#define MCI_SCKMSKON_B 67 + +/* MA_REG */ +#define MCI_DIFI_VFLAG 0 +#define MCB_DIFI3_VFLAG1 0x80 +#define MCB_DIFI3_VFLAG0 0x40 +#define MCB_DIFI2_VFLAG1 0x20 +#define MCB_DIFI2_VFLAG0 0x10 +#define MCB_DIFI1_VFLAG1 0x08 +#define MCB_DIFI1_VFLAG0 0x04 +#define MCB_DIFI0_VFLAG1 0x02 +#define MCB_DIFI0_VFLAG0 0x01 + +#define MCI_ADI_VFLAG 1 +#define MCB_ADI2_VFLAG1 0x20 +#define MCB_ADI2_VFLAG0 0x10 +#define MCB_ADI1_VFLAG1 0x08 +#define MCB_ADI1_VFLAG0 0x04 +#define MCB_ADI0_VFLAG1 0x02 +#define MCB_ADI0_VFLAG0 0x01 + +#define MCI_DIFO_VFLAG 2 +#define MCB_DIFO3_VFLAG1 0x80 +#define MCB_DIFO3_VFLAG0 0x40 +#define MCB_DIFO2_VFLAG1 0x20 +#define MCB_DIFO2_VFLAG0 0x10 +#define MCB_DIFO1_VFLAG1 0x08 +#define MCB_DIFO1_VFLAG0 0x04 +#define MCB_DIFO0_VFLAG1 0x02 +#define MCB_DIFO0_VFLAG0 0x01 + +#define MCI_DAO_VFLAG 3 +#define MCB_DAO1_VFLAG1 0x08 +#define MCB_DAO1_VFLAG0 0x04 +#define MCB_DAO0_VFLAG1 0x02 +#define MCB_DAO0_VFLAG0 0x01 + +#define MCI_I_VINTP 4 +#define MCB_ADI2_VINTP 0x40 +#define MCB_ADI1_VINTP 0x20 +#define MCB_ADI0_VINTP 0x10 +#define MCB_DIFI3_VINTP 0x08 +#define MCB_DIFI2_VINTP 0x04 +#define MCB_DIFI1_VINTP 0x02 +#define MCB_DIFI0_VINTP 0x01 +#define MCI_I_VINTP_DEF (MCB_ADI2_VINTP | \ + MCB_ADI1_VINTP | \ + MCB_ADI0_VINTP | \ + MCB_DIFI3_VINTP | \ + MCB_DIFI2_VINTP | \ + MCB_DIFI1_VINTP | \ + MCB_DIFI0_VINTP) + +#define MCI_O_VINTP 5 +#define MCB_DAO1_VINTP 0x20 +#define MCB_DAOO_VINTP 0x10 +#define MCB_DIFO3_VINTP 0x08 +#define MCB_DIFO2_VINTP 0x04 +#define MCB_DIFO1_VINTP 0x02 +#define MCB_DIFO0_VINTP 0x01 +#define MCI_O_VINTP_DEF (MCB_DAO1_VINTP | \ + MCB_DAOO_VINTP | \ + MCB_DIFO3_VINTP | \ + MCB_DIFO2_VINTP | \ + MCB_DIFO1_VINTP | \ + MCB_DIFO0_VINTP) + +#define MCI_DIFI0_VOL0 6 +#define MCB_DIFI0_VSEP 0x80 + +#define MCI_DIFI0_VOL1 7 + +#define MCI_DIFI1_VOL0 8 +#define MCB_DIFI1_VSEP 0x80 + +#define MCI_DIFI1_VOL1 9 + +#define MCI_DIFI2_VOL0 10 +#define MCB_DIFI2_VSEP 0x80 + +#define MCI_DIFI2_VOL1 11 + +#define MCI_DIFI3_VOL0 12 +#define MCB_DIFI3_VSEP 0x80 + +#define MCI_DIFI3_VOL1 13 + +#define MCI_ADI0_VOL0 14 +#define MCB_ADI0_VSEP 0x80 + +#define MCI_ADI0_VOL1 15 + +#define MCI_ADI1_VOL0 16 +#define MCB_ADI1_VSEP 0x80 + +#define MCI_ADI1_VOL1 17 + +#define MCI_ADI2_VOL0 18 +#define MCB_ADI2_VSEP 0x80 + +#define MCI_ADI2_VOL1 19 + +#define MCI_DIFO0_VOL0 20 +#define MCB_DIFO0_VSEP 0x80 + +#define MCI_DIFO0_VOL1 21 + +#define MCI_DIFO1_VOL0 22 +#define MCB_DIFO1_VSEP 0x80 + +#define MCI_DIFO1_VOL1 23 + +#define MCI_DIFO2_VOL0 24 +#define MCB_DIFO2_VSEP 0x80 + +#define MCI_DIFO2_VOL1 25 + +#define MCI_DIFO3_VOL0 26 +#define MCB_DIFO3_VSEP 0x80 + +#define MCI_DIFO3_VOL1 27 + +#define MCI_DAO0_VOL0 28 +#define MCB_DAO0_VSEP 0x80 + +#define MCI_DAO0_VOL1 29 + +#define MCI_DAO1_VOL0 30 +#define MCB_DAO1_VSEP 0x80 + +#define MCI_DAO1_VOL1 31 + +#define MCI_ADI_SWAP 32 + +#define MCI_ADI2_SWAP 33 + +#define MCI_DAO_SWAP 34 + +#define MCI_IN0_MIX0 35 +#define MCB_IN_MIX_DIFI_0 0x01 +#define MCB_IN_MIX_DIFI_1 0x02 +#define MCB_IN_MIX_DIFI_2 0x04 +#define MCB_IN_MIX_DIFI_3 0x08 +#define MCB_IN_MIX_ADI_0 0x10 +#define MCB_IN_MIX_ADI_1 0x20 +#define MCB_IN_MIX_ADI_2 0x40 +#define MCB_IN0_MSEP 0x80 + +#define MCI_IN0_MIX1 36 + +#define MCI_IN1_MIX0 37 +#define MCB_IN1_MSEP 0x80 + +#define MCI_IN1_MIX1 38 + +#define MCI_IN2_MIX0 39 +#define MCB_IN2_MSEP 0x80 + +#define MCI_IN2_MIX1 40 + +#define MCI_IN3_MIX0 41 +#define MCB_IN3_MSEP 0x80 + +#define MCI_IN3_MIX1 42 + +#define MCI_OUT0_MIX0_10_8 43 +#define MCB_OUT_MIX_DIFI_0 0x001 +#define MCB_OUT_MIX_DIFI_1 0x002 +#define MCB_OUT_MIX_DIFI_2 0x004 +#define MCB_OUT_MIX_DIFI_3 0x008 +#define MCB_OUT_MIX_ADI_0 0x010 +#define MCB_OUT_MIX_ADI_1 0x020 +#define MCB_OUT_MIX_ADI_2 0x040 +#define MCB_OUT_MIX_AEO_0 0x080 +#define MCB_OUT_MIX_AEO_1 0x100 +#define MCB_OUT_MIX_AEO_2 0x200 +#define MCB_OUT_MIX_AEO_3 0x400 +#define MCB_OUT0_MSEP 0x80 + +#define MCI_OUT0_MIX0_7_0 44 + +#define MCI_OUT0_MIX1_10_8 45 + +#define MCI_OUT0_MIX1_7_0 46 + +#define MCI_OUT1_MIX0_10_8 47 +#define MCB_OUT1_MSEP 0x80 + +#define MCI_OUT1_MIX0_7_0 48 + +#define MCI_OUT1_MIX1_10_8 49 + +#define MCI_OUT1_MIX1_7_0 50 + +#define MCI_OUT2_MIX0_10_8 51 +#define MCB_OUT2_MSEP 0x80 + +#define MCI_OUT2_MIX0_7_0 52 + +#define MCI_OUT2_MIX1_10_8 53 + +#define MCI_OUT2_MIX1_7_0 54 + +#define MCI_OUT3_MIX0_10_8 55 +#define MCB_OUT3_MSEP 0x80 + +#define MCI_OUT3_MIX0_7_0 56 + +#define MCI_OUT3_MIX1_10_8 57 + +#define MCI_OUT3_MIX1_7_0 58 + +#define MCI_OUT4_MIX0_10_8 59 +#define MCB_OUT4_MSEP 0x80 + +#define MCI_OUT4_MIX0_7_0 60 + +#define MCI_OUT4_MIX1_10_8 61 + +#define MCI_OUT4_MIX1_7_0 62 + +#define MCI_OUT5_MIX0_10_8 63 +#define MCB_OUT5_MSEP 0x80 + +#define MCI_OUT5_MIX0_7_0 64 + +#define MCI_OUT5_MIX1_10_8 65 + +#define MCI_OUT5_MIX1_7_0 66 + +#define MCI_DSP_START 67 +#define MCB_DSP_START 0x01 + +#define MCI_SPATH_ON 68 +#define MCB_SPATH_ON 0x80 +#define MCB_IN_MIX_ON 0x40 +#define MCB_OUT_MIX_ON_5 (1 << 5) +#define MCB_OUT_MIX_ON_4 (1 << 4) +#define MCB_OUT_MIX_ON_3 (1 << 3) +#define MCB_OUT_MIX_ON_2 (1 << 2) +#define MCB_OUT_MIX_ON_1 (1 << 1) +#define MCB_OUT_MIX_ON_0 (1 << 0) +#define MCB_OUT_MIX_ON_5321 0x2e + +#define MCI_CLK_SEL 70 + +#define MCI_LINK_LOCK 71 +#define MCB_LINK_LOCK 0x80 + +#define MCI_FDSP_PI_SOURCE 80 +#define MCB_FDSP_PI_SOURCE_AE 0x00 +#define MCB_FDSP_PI_SOURCE_VDSP 0x07 +#define MCB_FDSP_PI_SOURCE_VDSP_EX 0x0f +#define MCB_FDSP_EX_SYNC 0x80 + +#define MCI_FDSP_PO_SOURCE 81 +#define MCB_FDSP_PO_SOURCE_AE 0x00 +#define MCB_FDSP_PO_SOURCE_VDSP 0x07 +#define MCB_FDSP_PO_SOURCE_VDSP_EX 0x3f +#define MCB_FDSP_PO_SOURCE_MASK 0x3f + +#define MCI_BDSP_SOURCE 82 + +#define MCI_SRC_VSOURCE 83 + +#define MCI_LPT2_MIX_VOL 84 + +/* MB_REG */ +#define MCI_LP0_MODE 0 +#define MCB_LP0_STMODE 0x80 +#define MCB_LP0_AUTO_FS 0x40 +#define MCB_LP0_SRC_THRU 0x20 +#define MCB_LPT0_EDGE 0x10 +#define MCB_LP0_MODE 0x01 +#define MCI_LP0_MODE_DEF MCB_LP0_AUTO_FS + +#define MCI_LP0_BCK 1 + +#define MCI_LPR0_SLOT 2 +#define MCI_LPR0_SLOT_DEF 0x24 + +#define MCI_LPR0_SWAP 3 + +#define MCI_LPT0_SLOT 4 +#define MCI_LPT0_SLOT_DEF 0x24 + +#define MCI_LPT0_SWAP 5 + +#define MCI_LP0_FMT 6 + +#define MCI_LP0_PCM 7 + +#define MCI_LPR0_PCM 8 +#define MCB_LPR0_PCM_MONO 0x80 +#define MCI_LPR0_PCM_DEF MCB_LPR0_PCM_MONO + +#define MCI_LPT0_PCM 9 +#define MCB_LPT0_PCM_MONO 0x80 +#define MCI_LPT0_PCM_DEF MCB_LPT0_PCM_MONO + +#define MCI_LP0_START 10 +#define MCB_LP0_TIM_START 0x80 +#define MCB_LPR0_START_SRC 0x08 +#define MCB_LPR0_START 0x04 +#define MCB_LPT0_START_SRC 0x02 +#define MCB_LPT0_START 0x01 + +#define MCI_LP1_MODE 16 +#define MCB_LP1_STMODE 0x80 +#define MCB_LP1_AUTO_FS 0x40 +#define MCB_LP1_SRC_THRU 0x20 +#define MCB_LP1_MODE 0x01 +#define MCI_LP1_MODE_DEF MCB_LP1_AUTO_FS + +#define MCI_LP1_BCK 17 + +#define MCI_LPR1_SWAP 19 + +#define MCI_LPT1_SWAP 21 + +#define MCI_LP1_FMT 22 + +#define MCI_LP1_PCM 23 + +#define MCI_LPR1_PCM 24 +#define MCB_LPR1_PCM_MONO 0x80 +#define MCI_LPR1_PCM_DEF MCB_LPR1_PCM_MONO + +#define MCI_LPT1_PCM 25 +#define MCB_LPT1_PCM_MONO 0x80 +#define MCI_LPT1_PCM_DEF MCB_LPT1_PCM_MONO + +#define MCI_LP1_START 26 +#define MCB_LP1_TIM_START 0x80 +#define MCB_LPR1_START_SRC 0x08 +#define MCB_LPR1_START 0x04 +#define MCB_LPT1_START_SRC 0x02 +#define MCB_LPT1_START 0x01 + +#define MCI_LP2_MODE 32 +#define MCB_LP2_STMODE 0x80 +#define MCB_LP2_AUTO_FS 0x40 +#define MCB_LP2_SRC_THRU 0x20 +#define MCB_LP2_MODE 0x01 +#define MCI_LP2_MODE_DEF MCB_LP2_AUTO_FS + +#define MCI_LP2_BCK 33 + +#define MCI_LPR2_SWAP 35 + +#define MCI_LPT2_SWAP 37 + +#define MCI_LP2_FMT 38 + +#define MCI_LP2_PCM 39 + +#define MCI_LPR2_PCM 40 +#define MCB_LPR2_PCM_MONO 0x80 +#define MCI_LPR2_PCM_DEF MCB_LPR2_PCM_MONO + +#define MCI_LPT2_PCM 41 +#define MCB_LPT2_PCM_MONO 0x80 +#define MCI_LPT2_PCM_DEF MCB_LPT2_PCM_MONO + +#define MCI_LP2_START 42 +#define MCB_LP2_TIM_START 0x80 +#define MCB_LPR2_START_SRC 0x08 +#define MCB_LPR2_START 0x04 +#define MCB_LPT2_START_SRC 0x02 +#define MCB_LPT2_START 0x01 + +#define MCI_SRC3 43 + +#define MCI_SRC3_START 44 +#define MCB_SRC3_TIM_START 0x80 +#define MCB_ISRC3_START 0x08 +#define MCB_OSRC3_START 0x02 + +#define MCI_LPT3_STMODE 48 + +#define MCI_LP3_BCK 49 + +#define MCI_LPR3_SWAP 51 + +#define MCI_LPT3_SWAP 53 + +#define MCI_LP3_FMT 54 + +#define MCI_LP3_START 58 +#define MCB_LP3_TIM_START 0x80 +#define MCB_LPR3_START 0x04 +#define MCB_LPT3_START 0x01 + +#define MCI_T_DPLL_FAST 85 +#define MCB_T_DPLL_FAST 0x80 +#define MCB_VOLREL_TIME 0x20 + +/* B_REG */ +/* B_REG = #0: DSPCtl + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DSP | "0" | "0" | "0" | "0" | "0" | "0" | DSP | + | BYPASS| | | | | | | START | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_BDSPCTRL 0x00 +#define MCI_BDSPCTRL_DEF 0x00 +#define MCB_BDSPBYPASS 0x80 +#define MCB_BDSPSTART 0x01 + +/* B_REG = #1: State0 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | OVER | "0" | "0" | "0" | "0" | LOAD[10:8] | + | LOAD | | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_STATE0 0x01 +#define MCI_STATE0_DEF 0x00 +#define MCB_OVERLOAD 0x80 +#define MCB_LOAD0 0x07 + +/* B_REG = #2: State1 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | LOAD[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_STATE1 0x02 +#define MCI_STATE1_DEF 0x00 +#define MCB_LOAD1 0xff + +/* B_REG = #64: FWCTRL0 AEExec0 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | GEN | "0" | EQ3_0B| DRC_0 | DRC3 | EQ3_0A| HEX | WIDE | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL0 64 +#define MCI_AEEXEC0 MCI_FWCTL0 +#define MCI_AEEXEC0_DEF 0x00 +#define MCB_AEEXEC0_GEN 0x80 +#define MCB_AEEXEC0_EQ3_0B 0x20 +#define MCB_AEEXEC0_DRC_0 0x10 +#define MCB_AEEXEC0_DRC3 0x08 +#define MCB_AEEXEC0_EQ3_0A 0x04 +#define MCB_AEEXEC0_HEX 0x02 +#define MCB_AEEXEC0_WIDE 0x01 + +/* B_REG = #65: FWCTRL1 AEExec1 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | EQ3_1B| DRC_1 | AGC | EQ3_1A| "0" | "0" | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL1 65 +#define MCI_AEEXEC1 MCI_FWCTL1 +#define MCI_AEEXEC1_DEF 0x00 +#define MCB_AEEXEC1_EQ3_1B 0x20 +#define MCB_AEEXEC1_DRC_1 0x10 +#define MCB_AEEXEC1_AGC 0x08 +#define MCB_AEEXEC1_EQ3_1A 0x04 + +/* B_REG = #66: FWCTRL2 AEBypass + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | "0" | AE1 | AE0 | + | | | | | | | BYPASS| BYPASS| + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL2 66 +#define MCI_AEBYPASS MCI_FWCTL2 +#define MCI_AEBYPASS_DEF 0x00 +#define MCB_AEBYPASS_AE1 0x02 +#define MCB_AEBYPASS_AE0 0x01 + +/* B_REG = #67: FWCTRL3 AEFade + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ + R | "0" | "0" | "0" | "0" | "0" | "0" | AE1 | AE0 | + | | | | | | | FADE | FADE | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL3 67 +#define MCI_AEFADE MCI_FWCTL3 +#define MCI_AEFADE_DEF 0x00 +#define MCB_AEFADE_AE1 0x02 +#define MCB_AEFADE_AE0 0x01 + +/* B_REG = #68: FWCTRL4 F0/1SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | F1SEL[1:0] | "0" | "0" | F0SEL[1:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL4 68 +#define MCI_F01SEL MCI_FWCTL4 +#define MCI_F01SEL_DEF 0x00 +#define MCB_F1SEL 0x30 +#define MCB_F0SEL 0x03 + +/* B_REG = #69: FWCTRL5 SinOut + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | "0" | "0" | SIN | + | | | | | | | | OUT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL5 69 +#define MCI_SINOUT MCI_FWCTL5 +#define MCI_SINOUT_DEF 0x00 +#define MCB_SINOUT 0x01 + +/* B_REG = #70: FWCTRL6 SinOutFlg + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | "0" | "0" | "0" | "0" | "0" | "0" | "0" | SIN | + | | | | | | | | OFLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL6 70 +#define MCI_SINOUTFLG MCI_FWCTL6 +#define MCI_SINOUTFLG_DEF 0x00 +#define MCB_SINOFLG 0x01 + +/* B_REG = #71: FWCTRL7 No Used + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | "0" | "0" | "0" | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_FWCTL7 71 + +/* E_REG */ +/* E_REG = #0: E1DSP_CTRL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | E1DSP | "0" | "0" | "0" | "0" | "0" | "0" | E1DSP | + | _HALT | | | | | | | _RST | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E1DSP_CTRL 0 +#define MCB_E1DSP_HALT 0x80 +#define MCB_E1DSP_RST 0x01 +#define MCI_E1DSP_CTRL_DEF MCB_E1DSP_RST + +/* E_REG = #1: E1COMMAND/E1STATUS + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E1COMMAND | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E1STATUS | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E1COMMAND 1 +#define MCI_E1STATUS 1 +#define MCI_E1COMMAND_DEF 0x00 +#define MCI_E1STATUS_DEF 0x00 +#define MCB_E1COMMAND 0xff +#define MCB_E1STATUS 0xff +#define E1COMMAND_RUN_MODE 0x40 +#define E1COMMAND_OFFSET_CANCEL 0x02 +#define E1COMMAND_IMP_SENSE 0x04 +#define E1COMMAND_WAIT 0x08 +#define E1COMMAND_PD 0x10 +#define E1COMMAND_GND_DET 0x20 +#define E1COMMAND_ADDITIONAL 0x80 +#define E1COMMAND_SLEEP_MODE 0x00 + +#define MCI_LPF_THR 2 +#define MCB_LPF1_PST_THR 0x80 +#define MCB_LPF0_PST_THR 0x40 +#define MCB_LPF1_PRE_THR 0x20 +#define MCB_LPF0_PRE_THR 0x10 +#define MCB_LPF_ALL_THR 0xf0 +#define MCB_OSF1_MN 0x08 +#define MCB_OSF0_MN 0x04 +#define MCB_OSF1_ENB 0x02 +#define MCB_OSF0_ENB 0x01 +#define MCI_LPF_THR_DEF (MCB_LPF0_PST_THR | MCB_LPF0_PRE_THR) + +#define MCI_DAC_DCC_SEL 3 +#define MCI_DAC_DCC_SEL_DEF 0x0a + +#define MCI_DET_LVL 4 + +#define MCI_ECLK_SEL 6 + +#define MCI_OSF_SEL 8 +#define MCI_OSF_SEL_DEF 0x0f + +#define MCI_SYSEQ 9 +#define MCB_SYSEQ_SYSEQ1_ENB 0x02 +#define MCB_SYSEQ_SYSEQ0_ENB 0x01 +#define MCB_SYSEQ_SYSEQ1_B2_ENB 0x40 +#define MCB_SYSEQ_SYSEQ1_B1_ENB 0x20 +#define MCB_SYSEQ_SYSEQ1_B0_ENB 0x10 +#define MCB_SYSEQ_SYSEQ0_B2_ENB 0x04 +#define MCB_SYSEQ_SYSEQ0_B1_ENB 0x02 +#define MCB_SYSEQ_SYSEQ0_B0_ENB 0x01 +#define MCI_SYSEQ_DEF 0x00 + +#define MCI_CLIP_MD 10 + +#define MCI_CLIP_ATT 11 + +#define MCI_CLIP_REL 12 + +#define MCI_CLIP_G 13 + +#define MCI_OSF_GAIN0_15_8 14 +#define MCI_OSF_GAIN0_15_8_DEF 0x40 +#define MCI_OSF_GAIN0_7_0 15 +#define MCI_OSF_GAIN0_7_0_DEF 0x00 + +#define MCI_OSF_GAIN1_15_8 16 +#define MCI_OSF_GAIN1_15_8_DEF 0x40 +#define MCI_OSF_GAIN1_7_0 17 +#define MCI_OSF_GAIN1_7_0_DEF 0x00 + +#define MCI_DCL_GAIN 18 +#define MCB_DCL1_OFF 0x80 +#define MCB_DCL0_OFF 0x08 + +#define MCI_DCL0_LMT_14_8 19 +#define MCI_DCL0_LMT_14_8_DEF 0x7f +#define MCI_DCL0_LMT_7_0 20 +#define MCI_DCL0_LMT_7_0_DEF 0xff + +#define MCI_DCL1_LMT_14_8 21 +#define MCI_DCL1_LMT_14_8_DEF 0x7f +#define MCI_DCL1_LMT_7_0 22 +#define MCI_DCL1_LMT_7_0_DEF 0xff + +#define MCI_DITHER0 23 +#define MCI_DITHER0_DEF 0x50 + +#define MCI_DITHER1 24 +#define MCI_DITHER1_DEF 0x50 + +#define MCI_DNG0_ES1 25 +#define MCI_DNG0_DEF_ES1 0xc9 + +#define MCI_DNG1_ES1 26 +#define MCI_DNG1_DEF_ES1 0xc9 + +#define MCI_DNG_ON_ES1 27 + +#define MCI_DIRECTPATH_ENB 28 +#define MCB_DIRECTPATH_ENB 0x01 +#define MCB_DIRECT_ENB_ADC 0x04 +#define MCB_DIRECT_ENB_DAC1 0x02 +#define MCB_DIRECT_ENB_DAC0 0x01 + +#define MCI_DPATH_DA_V 29 +#define MCB_DPATH_DA_VFLAG 0x02 +#define MCB_DPATH_DA_VINTP 0x01 +#define MCI_DPATH_DA_V_DEF (MCB_DPATH_DA_VFLAG | \ + MCB_DPATH_DA_VINTP) + +#define MCI_DPATH_DA_VOL_L 30 +#define MCB_DPATH_DA_VSEP 0x80 + +#define MCI_DPATH_DA_VOL_R 31 + +#define MCI_DPATH_AD_V 32 +#define MCB_DPATH_AD_VFLAG 0x02 +#define MCB_DPATH_AD_VINTP 0x01 +#define MCI_DPATH_AD_V_DEF (MCB_DPATH_AD_VFLAG | \ + MCB_DPATH_AD_VINTP) + +#define MCI_DPATH_AD_VOL_L 33 +#define MCB_DPATH_AD_VSEP 0x80 + +#define MCI_DPATH_AD_VOL_R 34 + +#define MCI_ADJ_HOLD 35 + +#define MCI_ADJ_CNT 36 + +#define MCI_ADJ_MAX_15_8 37 +#define MCI_ADJ_MAX_7_0 38 + +#define MCI_DSF0_FLT_TYPE 41 +#define MCB_DSF0R_PRE_FLT_TYPE 0x20 +#define MCB_DSF0L_PRE_FLT_TYPE 0x10 +#define MCB_DSF0_MN 0x02 +#define MCB_DSF0ENB 0x01 + +#define MCI_DSF0_PRE_INPUT 42 +#define MCB_DSF_PRE_INPUT_ADC_L 0 +#define MCB_DSF_PRE_INPUT_ADC_R 1 +#define MCB_DSF_PRE_INPUT_ADC_M 2 +#define MCB_DSF_PRE_INPUT_PDM0_L 3 +#define MCB_DSF_PRE_INPUT_PDM0_R 4 +#define MCB_DSF_PRE_INPUT_PDM1_L 5 +#define MCB_DSF_PRE_INPUT_PDM1_R 6 +#define MCI_DSF0_PRE_INPUT_DEF 0x10 + +#define MCI_DSF1_FLT_TYPE 43 +#define MCB_DSF1R_PRE_FLT_TYPE 0x20 +#define MCB_DSF1L_PRE_FLT_TYPE 0x10 +#define MCB_DSF1_MN 0x02 +#define MCB_DSF1ENB 0x01 +#define MCI_DSF1_FLT_TYPE_DEF MCB_DSF1_MN + +#define MCI_DSF1_PRE_INPUT 44 +#define MCI_DSF1_PRE_INPUT_DEF 0x22 + +#define MCI_DSF2_FLT_TYPE 45 +#define MCB_DSF2R_PRE_FLT_TYPE 0x40 +#define MCB_DSF2L_PRE_FLT_TYPE 0x10 +#define MCB_DSF2REFSEL 0x08 +#define MCB_DSF2REFBACK 0x04 +#define MCB_DSF2_MN 0x02 +#define MCB_DSF2ENB 0x01 + +#define MCI_DSF2_PRE_INPUT 46 +#define MCI_DSF2_PRE_INPUT_DEF 0x43 + +#define MCI_DSF_SEL 47 + +#define MCI_ADC_DCC_SEL 48 +#define MCI_ADC_DCC_SEL_DEF_ES1 0x2a +#define MCI_ADC_DCC_SEL_DEF 0x15 + +#define MCI_ADC_DNG_ON 49 + +#define MCI_ADC_DNG0_FW 50 +#define MCI_ADC_DNG0_FW_DEF 0x0b + +#define MCI_ADC_DNG0_TIM 51 + +#define MCI_ADC_DNG0_ZERO_15_8 52 +#define MCI_ADC_DNG0_ZERO_7_0 53 + +#define MCI_ADC_DNG0_TGT_15_8 54 +#define MCI_ADC_DNG0_TGT_7_0 55 + +#define MCI_ADC_DNG1_FW 56 +#define MCI_ADC_DNG1_FW_DEF 0x0b + +#define MCI_ADC_DNG1_TIM 57 + +#define MCI_ADC_DNG1_ZERO_15_8 58 +#define MCI_ADC_DNG1_ZERO_7_0 59 + +#define MCI_ADC_DNG1_TGT_15_8 60 +#define MCI_ADC_DNG1_TGT_7_0 61 + +#define MCI_ADC_DNG2_FW 62 +#define MCI_ADC_DNG2_FW_DEF 0x0b + +#define MCI_ADC_DNG2_TIM 63 + +#define MCI_ADC_DNG2_ZERO_15_8 64 +#define MCI_ADC_DNG2_ZERO_7_0 65 + +#define MCI_ADC_DNG2_TGT_15_8 66 +#define MCI_ADC_DNG2_TGT_7_0 67 + +#define MCI_DEPOP0 68 +#define MCI_DEPOP0_DEF 0x0a + +#define MCI_DEPOP1 69 +#define MCI_DEPOP1_DEF 0x0a + +#define MCI_DEPOP2 70 +#define MCI_DEPOP2_DEF 0x0a + +#define MCI_PDM_MODE 71 +#define MCI_PDM_MODE_DEF 0x08 + +#define MCI_PDM_LOAD_TIM 72 +#define MCB_PDM1_START 0x80 +#define MCB_PDM0_START 0x08 + +#define MCI_PDM0L_FINE_DLY 73 +#define MCI_PDM0R_FINE_DLY 74 +#define MCI_PDM1L_FINE_DLY 75 +#define MCI_PDM1R_FINE_DLY 76 + +/* E_REG = #77: E2DSP_CTRL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | E2DSP | "0" | "0" | "0" | "0" | "0" | "0" | E2DSP | + | _HALT | | | | | | | _RST | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2DSP 77 +#define MCB_E2DSP_HALT 0x80 +#define MCB_E2DSP_RST 0x01 +#define MCI_E2DSP_DEF MCB_E2DSP_RST + +/* E_REG = #78: E2REQ_0/E2RES_0 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_0 78 +#define MCI_E2RES_0 MCI_E2REQ_0 +#define MCI_E2REQ_0_DEF 0x00 +#define MCI_E2RES_0_DEF MCI_E2REQ_0_DEF +#define MCB_E2REQ_0 0xff +#define MCB_E2RES_0 MCB_E2REQ_0 + +/* E_REG = #79: E2REQ_1/E2RES_1 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_1 79 +#define MCI_E2RES_1 MCI_E2REQ_1 +#define MCI_E2REQ_1_DEF 0x00 +#define MCI_E2RES_1_DEF MCI_E2REQ_1_DEF +#define MCB_E2REQ_1 0xff +#define MCB_E2RES_1 MCB_E2REQ_1 + +/* E_REG = #80: E2REQ_2/E2RES_2 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_2 80 +#define MCI_E2RES_2 MCI_E2REQ_2 +#define MCI_E2REQ_2_DEF 0x00 +#define MCI_E2RES_2_DEF MCI_E2REQ_2_DEF +#define MCB_E2REQ_2 0xff +#define MCB_E2RES_2 MCB_E2REQ_2 + +/* E_REG = #81: E2REQ_3/E2RES_3 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_3 81 +#define MCI_E2RES_3 MCI_E2REQ_3 +#define MCI_E2REQ_3_DEF 0x00 +#define MCI_E2RES_3_DEF MCI_E2REQ_3_DEF +#define MCB_E2REQ_3 0xff +#define MCB_E2RES_3 MCB_E2REQ_3 + +/* E_REG = #82: E2REQ_4/E2RES_4 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_4 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_4 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_4 82 +#define MCI_E2RES_4 MCI_E2REQ_4 +#define MCI_E2REQ_4_DEF 0x00 +#define MCI_E2RES_4_DEF MCI_E2REQ_4_DEF +#define MCB_E2REQ_4 0xff +#define MCB_E2RES_4 MCB_E2REQ_4 + +/* E_REG = #83: E2REQ_5/E2RES_5 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_5 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_5 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_5 83 +#define MCI_E2RES_5 MCI_E2REQ_5 +#define MCI_E2REQ_5_DEF 0x00 +#define MCI_E2RES_5_DEF MCI_E2REQ_5_DEF +#define MCB_E2REQ_5 0xff +#define MCB_E2RES_5 MCB_E2REQ_5 + +/* E_REG = #84: E2REQ_6/E2RES_6 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_6 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_6 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_6 84 +#define MCI_E2RES_6 MCI_E2REQ_6 +#define MCI_E2REQ_6_DEF 0x00 +#define MCI_E2RES_6_DEF MCI_E2REQ_6_DEF +#define MCB_E2REQ_6 0xff +#define MCB_E2RES_6 MCB_E2REQ_6 + +/* E_REG = #85: E2REQ_7/E2RES_7 + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2REQ_7 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2RES_7 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2REQ_7 85 +#define MCI_E2RES_7 MCI_E2REQ_7 +#define MCI_E2REQ_7_DEF 0x00 +#define MCI_E2RES_7_DEF MCI_E2REQ_7_DEF +#define MCB_E2REQ_7 0xff +#define MCB_E2RES_7 MCB_E2REQ_7 + +/* E_REG = #86: E2COMMAND/E2STATUS + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | E2COMMAND | + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | E2STATUS | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_E2COMMAND 86 +#define MCI_E2STATUS MCI_E2COMMAND +#define MCI_E2COMMAND_DEF 0x00 +#define MCI_E2STATUS_DEF MCI_E2COMMAND_DEF +#define MCB_E2COMMAND 0xff +#define MCB_E2STATUS MCB_E2COMMAND + +#define MCI_CH_SEL 87 +#define MCB_I2SOUT_ENB 0x20 + +#define MCI_IMPSEL 90 + +#define MCI_HPIMP_15_8 91 +#define MCI_HPIMP_7_0 92 + +#define MCI_PLUG_REV 93 + +#define MCI_E2_SEL 94 + +#define MCI_DNG0 96 +#define MCI_DNG0_DEF 0xc9 + +#define MCI_DNG1 97 +#define MCI_DNG1_DEF 0xc9 + +#define MCI_DNG_ON 98 + +/* C_REG */ +/* C_REG = #0: power management digital CDSP register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | CDSP_ | "0" | "0" | "0" | "0" | "0" | "0" | "0" | + |SAVEOFF| | | | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_PWM_CDSP_SAVEOFF 0x80 +#define MCI_PWM_DIGITAL_CDSP 0 + +/* C_REG = #1: CDSP input/output FIFO level 1 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | OFIFO_LVL | DFIFO_LVL | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_OFIFO_LVL 0xf0 +#define MCB_DEC_DFIFO_LVL 0x0f +#define MCI_DEC_FIFOLEVEL_1 1 + +/* C_REG = #2: CDSP input/output FIFO level 2 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | RFIFO_LVL | EFIFO_LVL | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_RFIFO_LVL 0xf0 +#define MCB_DEC_EFIFO_LVL 0x0f +#define MCI_DEC_FIFOLEVEL_2 2 + +/* C_REG = #3: CDSP input/output FIFO level 3 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | "0" | "0" | "0" | "0" | FFIFO_LVL | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_FFIFO_LVL 0x0f +#define MCI_DEC_FIFOLEVEL_3 3 + +/* C_REG = #4: decoder play position1 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_POS[31:24] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_POS1 0xff +#define MCI_DEC_POS1 4 + +/* C_REG = #5: decoder play position2 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_POS[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_POS2 0xff +#define MCI_DEC_POS2 5 + +/* C_REG = #6: decoder play position3 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_POS[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_POS3 0xff +#define MCI_DEC_POS3 6 + +/* C_REG = #7: decoder play position4 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_POS[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_POS4 0xff +#define MCI_DEC_POS4 7 + +/* C_REG = #8: encoder play position1 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_POS[31:24] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_POS1 0xff +#define MCI_ENC_POS1 8 + +/* C_REG = #9: encoder play position2 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_POS[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_POS2 0xff +#define MCI_ENC_POS2 9 + +/* C_REG = #10: encoder play position3 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_POS[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_POS3 0xff +#define MCI_ENC_POS3 10 + +/* C_REG = #11: encoder play position4 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_POS[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_POS4 0xff +#define MCI_ENC_POS4 11 + +/* C_REG = #12: decoder error flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_ERR | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_ERROR 0xff +#define MCI_DEC_ERROR 12 + +/* C_REG = #13: encoder error flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_ERR | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_ERROR 0xff +#define MCI_ENC_ERROR 13 + +/* C_REG = #14: decoder FIFO reset register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | FFIFO | EFIFO | RFIFO | OFIFO | DFIFO | + | | | | _RST | _RST | _RST | _RST | _RST | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_FFIFO_RST 0x10 +#define MCB_DEC_EFIFO_RST 0x08 +#define MCB_DEC_RFIFO_RST 0x04 +#define MCB_DEC_OFIFO_RST 0x02 +#define MCB_DEC_DFIFO_RST 0x01 +#define MCI_DEC_FIFO_RST 14 + +/* C_REG = #15: decoder start register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R |OUT_STA| "0" | "0" | FSQ_ | ENC_ |CDSP_OU| OUT_ | DEC_ | + | RT_SEL| | | START | START |T_START| START | START | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_OUT_START_SEL 0x80 +#define MCB_DEC_FSQ_START 0x10 +#define MCB_DEC_ENC_START 0x08 +#define MCB_DEC_CDSP_OUT_START 0x04 +#define MCB_DEC_OUT_START 0x02 +#define MCB_DEC_DEC_START 0x01 +#define MCI_DEC_START 15 + +/* C_REG = #16: decoder FIFO ch setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EFIFO | EFIFO | EFIFO_CH | CDSP | "0" | OFIFO_CH | + | _START| _START| | _EFIFO| | | + | _SEL | | | _START| | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EFIFO_START_SEL 0x80 +#define MCB_DEC_EFIFO_START 0x40 +#define MCB_DEC_EFIFO_CH 0x30 +#define MCB_DEC_EFIFO_CH_2_16 0x00 +#define MCB_DEC_EFIFO_CH_4_16 0x10 +#define MCB_DEC_EFIFO_CH_2_32 0x20 +#define MCB_DEC_EFIFO_CH_4_32 0x30 +#define MCB_DEC_CDSP_EFIFO_START 0x08 +#define MCB_DEC_OFIFO_CH 0x03 +#define MCB_DEC_OFIFO_CH_2_16 0x00 +#define MCB_DEC_OFIFO_CH_4_16 0x01 +#define MCB_DEC_OFIFO_CH_2_32 0x02 +#define MCB_DEC_OFIFO_CH_4_32 0x03 +#define MCI_DEC_FIFO_CH 16 + +/* C_REG = #17: decoder start register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R |RFIFO | "0" | "0" | "0" | "0" |CDSP |RFIFO | "0" | + | _START| | | | | _RFIFO| _START| | + | _SEL | | | | | _START| | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_RFIFO_START_SEL 0X80 +#define MCB_DEC_CDSP_RFIFO_START 0X04 +#define MCB_RFIFO_START 0X02 +#define MCI_DEC_START2 17 + +/* C_REG = #19: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL15 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL15 0xff +#define MCI_DEC_CTL15 19 + +/* C_REG = #20: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL14 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL14 0xff +#define MCI_DEC_CTL14 20 + +/* C_REG = #21: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL13 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL13 0xff +#define MCI_DEC_CTL13 21 + +/* C_REG = #22: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL12 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL12 0xff +#define MCI_DEC_CTL12 22 + +/* C_REG = #23: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL11 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL11 0xff +#define MCI_DEC_CTL11 23 + +/* C_REG = #24: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL10 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL10 0xff +#define MCI_DEC_CTL10 24 + +/* C_REG = #25: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL9 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL9 0xff +#define MCI_DEC_CTL9 25 + +/* C_REG = #26: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL8 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL8 0xff +#define MCI_DEC_CTL8 26 + +/* C_REG = #27: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL7 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL7 0xff +#define MCI_DEC_CTL7 27 + +/* C_REG = #28: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL6 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL6 0xff +#define MCI_DEC_CTL6 28 + +/* C_REG = #29: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL5 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL5 0xff +#define MCI_DEC_CTL5 29 + +/* C_REG = #30: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL4 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL4 0xff +#define MCI_DEC_CTL4 30 + +/* C_REG = #31: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL3 0xff +#define MCI_DEC_CTL3 31 + +/* C_REG = #32: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL2 0xff +#define MCI_DEC_CTL2 32 + +/* C_REG = #33: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL1 0xff +#define MCI_DEC_CTL1 33 + +/* C_REG = #34: decoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_CTL0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_CTL0 0xff +#define MCI_DEC_CTL0 34 + +/* C_REG = #35: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR15 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR15 0xff +#define MCI_DEC_GPR15 35 + +/* C_REG = #36: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR14 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR14 0xff +#define MCI_DEC_GPR14 36 + +/* C_REG = #37: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR13 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR13 0xff +#define MCI_DEC_GPR13 37 + +/* C_REG = #38: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR12 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR12 0xff +#define MCI_DEC_GPR12 38 + +/* C_REG = #39: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR11 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR11 0xff +#define MCI_DEC_GPR11 39 + +/* C_REG = #40: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR10 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR10 0xff +#define MCI_DEC_GPR10 40 + +/* C_REG = #41: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR9 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR9 0xff +#define MCI_DEC_GPR9 41 + +/* C_REG = #42: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR8 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR8 0xff +#define MCI_DEC_GPR8 42 + +/* C_REG = #43: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR7 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR7 0xff +#define MCI_DEC_GPR7 43 + +/* C_REG = #44: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR6 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR6 0xff +#define MCI_DEC_GPR6 44 + +/* C_REG = #45: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR5 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR5 0xff +#define MCI_DEC_GPR5 45 + +/* C_REG = #46: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR4 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR4 0xff +#define MCI_DEC_GPR4 46 + +/* C_REG = #47: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR3 0xff +#define MCI_DEC_GPR3 47 + +/* C_REG = #48: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR2 0xff +#define MCI_DEC_GPR2 48 + +/* C_REG = #49: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR1 0xff +#define MCI_DEC_GPR1 49 + +/* C_REG = #50: decoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR0 0xff +#define MCI_DEC_GPR0 50 + +/* C_REG = #51: decoder special function register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_SFR1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_SFR1 0xff +#define MCI_DEC_SFR1 51 + +/* C_REG = #52: decoder special function register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_SFR0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_SFR0 0xff +#define MCI_DEC_SFR0 52 + +/* C_REG = #53: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL15 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL15 0xff +#define MCI_ENC_CTL15 53 + +/* C_REG = #54: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL14 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL14 0xff +#define MCI_ENC_CTL14 54 + +/* C_REG = #55: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL13 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL13 0xff +#define MCI_ENC_CTL13 55 + +/* C_REG = #56: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL12 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL12 0xff +#define MCI_ENC_CTL12 56 + +/* C_REG = #57: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL11 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL11 0xff +#define MCI_ENC_CTL11 57 + +/* C_REG = #58: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL10 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL10 0xff +#define MCI_ENC_CTL10 58 + +/* C_REG = #59: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL9 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL9 0xff +#define MCI_ENC_CTL9 59 + +/* C_REG = #60: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL8 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL8 0xff +#define MCI_ENC_CTL8 60 + +/* C_REG = #61: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL7 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL7 0xff +#define MCI_ENC_CTL7 61 + +/* C_REG = #62: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL6 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL6 0xff +#define MCI_ENC_CTL6 62 + +/* C_REG = #63: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL5 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL5 0xff +#define MCI_ENC_CTL5 63 + +/* C_REG = #64: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL4 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL4 0xff +#define MCI_ENC_CTL4 64 + +/* C_REG = #65: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL3 0xff +#define MCI_ENC_CTL3 65 + +/* C_REG = #66: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL2 0xff +#define MCI_ENC_CTL2 66 + +/* C_REG = #67: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL1 0xff +#define MCI_ENC_CTL1 67 + +/* C_REG = #68: encoder control setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_CTL0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_CTL0 0xff +#define MCI_ENC_CTL0 68 + +/* C_REG = #69: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR15 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR15 0xff +#define MCI_ENC_GPR15 69 + +/* C_REG = #70: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR14 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR14 0xff +#define MCI_ENC_GPR14 70 + +/* C_REG = #71: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR13 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR13 0xff +#define MCI_ENC_GPR13 71 + +/* C_REG = #72: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR12 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR12 0xff +#define MCI_ENC_GPR12 72 + +/* C_REG = #73: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR11 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR11 0xff +#define MCI_ENC_GPR11 73 + +/* C_REG = #74: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR10 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR10 0xff +#define MCI_ENC_GPR10 74 + +/* C_REG = #75: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR9 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR9 0xff +#define MCI_ENC_GPR9 75 + +/* C_REG = #76: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR8 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR8 0xff +#define MCI_ENC_GPR8 76 + +/* C_REG = #77: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR7 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR7 0xff +#define MCI_ENC_GPR7 77 + +/* C_REG = #78: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR6 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR6 0xff +#define MCI_ENC_GPR6 78 + +/* C_REG = #79: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR5 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR5 0xff +#define MCI_ENC_GPR5 79 + +/* C_REG = #80: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR4 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR4 0xff +#define MCI_ENC_GPR4 80 + +/* C_REG = #81: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR3 0xff +#define MCI_ENC_GPR3 81 + +/* C_REG = #82: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR2 0xff +#define MCI_ENC_GPR2 82 + +/* C_REG = #83: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR1 0xff +#define MCI_ENC_GPR1 83 + +/* C_REG = #84: encoder general purpose register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR0 0xff +#define MCI_ENC_GPR0 84 + +/* C_REG = #85: encoder special function register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_SFR1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_SFR1 0xff +#define MCI_ENC_SFR1 85 + +/* C_REG = #86: encoder special function register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_SFR0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_SFR0 0xff +#define MCI_ENC_SFR0 86 + +/* C_REG = #87: CDSP DFIFO pointer H register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | "0" | "0" | "0" | DFIFO_POINTER[12:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DFIFO_POINTER_H 0x1f +#define MCI_DFIFO_POINTER_H 87 + +/* C_REG = #88: CDSP DFIFO pointer L register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DFIFO_POINTER[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DFIFO_POINTER_L 0xff +#define MCI_DFIFO_POINTER_L 88 + +/* C_REG = #89: CDSP FFIFO pointer H register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | "0" | "0" | "0" | "0" | "0" | FFIFO_POINTER[10:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_FFIFO_POINTER_H 0x07 +#define MCI_FFIFO_POINTER_H 89 + +/* C_REG = #90: CDSP FFIFO pointer L register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | FFIFO_POINTER[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_FFIFO_POINTER_L 0xff +#define MCI_FFIFO_POINTER_L 90 + +/* C_REG = #91: CDSP DFIFO flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | JDEMP | JDPNT | "0" | "0" | DOVF | DUDF | DEMP | DPNT | + | | | | | _FLG | _FLG | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DFIFO_FLG_JDEMP 0x80 +#define MCB_DFIFO_FLG_JDPNT 0x40 +#define MCB_DFIFO_FLG_DOVF 0x08 +#define MCB_DFIFO_FLG_DUDF 0x04 +#define MCB_DFIFO_FLG_DEMP 0x02 +#define MCB_DFIFO_FLG_DPNT 0x01 +#define MCB_DFIFO_FLG_ALL 0x0f +#define MCI_DFIFO_FLG 91 + +/* C_REG = #92: CDSP OFIFO flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | JOEMP | JOPNT | "0" | "0" | OOVF | OUDF | OEMP | OPNT | + | | | | | _FLG | _FLG | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_OFIFO_FLG_JOEMP 0x80 +#define MCB_OFIFO_FLG_JOPNT 0x40 +#define MCB_OFIFO_FLG_OOVF 0x08 +#define MCB_OFIFO_FLG_OUDF 0x04 +#define MCB_OFIFO_FLG_OEMP 0x02 +#define MCB_OFIFO_FLG_OPNT 0x01 +#define MCB_OFIFO_FLG_ALL 0x0f +#define MCI_OFIFO_FLG 92 + +/* C_REG = #93: CDSP EFIFO flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | JEEMP | JEPNT | "0" | "0" | EOVF | EUDF | EEMP | EPNT | + | | | | | _FLG | _FLG | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EFIFO_FLG_JEEMP 0x80 +#define MCB_EFIFO_FLG_JEPNT 0x40 +#define MCB_EFIFO_FLG_EOVF 0x08 +#define MCB_EFIFO_FLG_EUDF 0x04 +#define MCB_EFIFO_FLG_EEMP 0x02 +#define MCB_EFIFO_FLG_EPNT 0x01 +#define MCB_EFIFO_FLG_ALL 0x0f +#define MCI_EFIFO_FLG 93 + +/* C_REG = #94: CDSP RFIFO flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | JREMP | JRPNT | "0" | "0" | ROVF | RUDF | REMP | RPNT | + | | | | | _FLG | _FLG | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_RFIFO_FLG_JREMP 0x80 +#define MCB_RFIFO_FLG_JRPNT 0x40 +#define MCB_RFIFO_FLG_ROVF 0x08 +#define MCB_RFIFO_FLG_RUDF 0x04 +#define MCB_RFIFO_FLG_REMP 0x02 +#define MCB_RFIFO_FLG_RPNT 0x01 +#define MCB_RFIFO_FLG_ALL 0x0f +#define MCI_RFIFO_FLG 94 + +/* C_REG = #95: CDSP FFIFO flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | JFEMP | JFPNT |FSQ_END| "0" | FOVF | "0" | FEMP | FPNT | + | | | _FLG | | _FLG | | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_FFIFO_FLG_JFEMP 0x80 +#define MCB_FFIFO_FLG_JFPNT 0x40 +#define MCB_FFIFO_FLG_FSQ_END 0x20 +#define MCB_FFIFO_FLG_FOVF 0x08 +#define MCB_FFIFO_FLG_FEMP 0x02 +#define MCB_FFIFO_FLG_FPNT 0x01 +#define MCB_FFIFO_FLG_ALL 0x2b +#define MCI_FFIFO_FLG 95 + +/* C_REG = #96: CDSP decoder flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R |DEC_EPARAM_FLG | "0" |DEC_EVT| "0" |DEC_END|DEC_ERR|DEC_SFR| + | | | _FLG | | _FLG | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EPARAM_FLG 0xc0 +#define MCB_DEC_EVT_FLG 0x10 +#define MCB_DEC_FLG_END 0x04 +#define MCB_DEC_FLG_ERR 0x02 +#define MCB_DEC_FLG_SFR 0x01 +#define MCB_DEC_FLG_ALL 0xd7 +#define MCI_DEC_FLG 96 + +/* C_REG = #97: CDSP encoder flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R |ENC_EPARAM_FLG | "0" |ENC_EVT| "0" |ENC_END|ENC_ERR|ENC_SFR| + | | | _FLG | | _FLG | _FLG | _FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_EPARAM_FLG 0xc0 +#define MCB_ENC_EVT_FLG 0x10 +#define MCB_ENC_FLG_END 0x04 +#define MCB_ENC_FLG_ERR 0x02 +#define MCB_ENC_FLG_SFR 0x01 +#define MCB_ENC_FLG_ALL 0xd7 +#define MCI_ENC_FLG 97 + +/* C_REG = #98: CDSP decoder general purpose flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_GPR_FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_GPR_FLG 0xff +#define MCI_DEC_GPR_FLG 98 + +/* C_REG = #99: CDSP encoder general purpose flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_GPR_FLG | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_GPR_FLG 0xff +#define MCI_ENC_GPR_FLG 99 + +/* C_REG = #100: CDSP DFIFO enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | EDOVF | EDUDF | EDEMP | EDPNT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DFIFO_EDOVF 0x08 +#define MCB_DFIFO_EDUDF 0x04 +#define MCB_DFIFO_EDEMP 0x02 +#define MCB_DFIFO_EDPNT 0x01 +#define MCI_DFIFO_ENABLE 100 + +/* C_REG = #101: CDSP OFIFO enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | EOOVF | EOUDF | EOEMP | EOPNT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_OFIFO_EOOVF 0x08 +#define MCB_OFIFO_EOUDF 0x04 +#define MCB_OFIFO_EOEMP 0x02 +#define MCB_OFIFO_EOPNT 0x01 +#define MCI_OFIFO_ENABLE 101 + +/* C_REG = #102: CDSP EFIFO enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | EEOVF | EEUDF | EEEMP | EEPNT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EFIFO_EEOVF 0x08 +#define MCB_EFIFO_EEUDF 0x04 +#define MCB_EFIFO_EEEMP 0x02 +#define MCB_EFIFO_EEPNT 0x01 +#define MCI_EFIFO_ENABLE 102 + +/* C_REG = #103: CDSP RFIFO enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | EROVF | ERUDF | EREMP | ERPNT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_RFIFO_EROVF 0x08 +#define MCB_RFIFO_ERUDF 0x04 +#define MCB_RFIFO_EREMP 0x02 +#define MCB_RFIFO_ERPNT 0x01 +#define MCI_RFIFO_ENABLE 103 + +/* C_REG = #104: CDSP FFIFO enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | EFSQ | "0" | EFOVF | "0" | EFEMP | EFPNT | + | | | _END | | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_FFIFO_EFSQ_END 0x20 +#define MCB_FFIFO_EFOVF 0x08 +#define MCB_FFIFO_EFEMP 0x02 +#define MCB_FFIFO_EFPNT 0x01 +#define MCI_FFIFO_ENABLE 104 + +/* C_REG = #105: CDSP decoder enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EDEC_EPARAM | "0" | EDEC | "0" | EDEC | EDEC | EDEC | + | | | _EVT | | _END | _ERR | _SFR | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EDEC_EPARAM 0xc0 +#define MCB_EDEC_EVT 0x10 +#define MCB_EDEC_END 0x04 +#define MCB_EDEC_ERR 0x02 +#define MCB_EDEC_SFR 0x01 +#define MCI_DEC_ENABLE 105 + +/* C_REG = #106: CDSP encoder enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EENC_EPARAM | "0" | EENC | "0" | EENC | EENC | EENC | + | | | _EVT | | _END | _ERR | _SFR | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EENC_EPARAM 0xc0 +#define MCB_EENC_EVT 0x10 +#define MCB_EENC_END 0x04 +#define MCB_EENC_ERR 0x02 +#define MCB_EENC_SFR 0x01 +#define MCI_ENC_ENABLE 106 + +/* C_REG = #107: CDSP decoder general purpose enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | EDEC_GPR | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EDEC_GPR 0xff +#define MCI_DEC_GPR_ENABLE 107 + +/* C_REG = #108: CDSP encoder general purpose enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | EENC_GPR | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EENC_GPR 0xff +#define MCI_ENC_GPR_ENABLE 108 + +/* C_REG = #110: CDSP reset register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | CDSP_MSEL | CDSP_ | CDSP_ | "0" | FSQ_ | "0" | CDSP_ | + | | DMODE | FMODE | | SRST | | SRST | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_MSEL 0xc0 +#define MCB_CDSP_MSEL_PROG 0x00 +#define MCB_CDSP_MSEL_DATA 0x40 +#define MCB_CDSP_DMODE 0x20 +#define MCB_CDSP_FMODE 0x10 +#define MCB_CDSP_FSQ_SRST 0x04 +#define MCB_CDSP_SRST 0x01 +#define MCI_CDSP_RESET 110 + +/* C_REG = #112: CDSP power mode register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | SLEEP | "0" | CDSP_HLT_MODE | "0" | "0" | "0" | "0" | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_SLEEP 0x80 +#define MCB_CDSP_HLT_MODE 0x30 +#define MCB_CDSP_HLT_MODE_IDLE 0x10 +#define MCB_CDSP_HLT_MODE_SLEEP_HALT 0x20 +#define MCI_CDSP_POWER_MODE 112 + +/* C_REG = #113: CDSP error register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | CDSP_ERR[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_ERR 0xff +#define MCI_CDSP_ERR 113 + +/* C_REG = #114: CDSP memory address H setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | CDSP_MAR[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_MAR_H 0xff +#define MCI_CDSP_MAR_H 114 + +/* C_REG = #115: CDSP memory address L setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | CDSP_MAR[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_MAR_L 0xff +#define MCI_CDSP_MAR_L 115 + +/* C_REG = #116: OFIFO irq point H setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | OFIFO_IRQ_PNT[11:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_OFIFO_IRQ_PNT_H 0x1f +#define MCI_OFIFO_IRQ_PNT_H 116 + +/* C_REG = #117: OFIFO irq point L setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | OFIFO_IRQ_PNT[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_OFIFO_IRQ_PNT_L 0xff +#define MCI_OFIFO_IRQ_PNT_L 117 + +/* C_REG = #118: DFIFO irq point H setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | DFIFO_IRQ_PNT[14:7] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DFIFO_IRQ_PNT_H 0x0f +#define MCI_DFIFO_IRQ_PNT_H 118 + +/* C_REG = #119: dfifo irq point L setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DFIFO_IRQ_PNT[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DFIFO_IRQ_PNT_L 0xff +#define MCI_DFIFO_IRQ_PNT_L 119 + +/* C_REG = #120: RFIFO irq point H setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | RFIFO_IRQ_PNT[12:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_RFIFO_IRQ_PNT_H 0x1f +#define MCI_RFIFO_IRQ_PNT_H 120 + +/* C_REG = #121: RFIFO irq point L setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | RFIFO_IRQ_PNT[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_RFIFO_IRQ_PNT_L 0xff +#define MCI_RFIFO_IRQ_PNT_L 121 + +/* C_REG = #122: EFIFO irq point H setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | EFIFO_IRQ_PNT[11:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EFIFO_IRQ_PNT_H 0x0f +#define MCI_EFIFO_IRQ_PNT_H 122 + +/* C_REG = #123: EFIFO irq point L setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | EFIFO_IRQ_PNT[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_EFIFO_IRQ_PNT_L 0xff +#define MCI_EFIFO_IRQ_PNT_L 123 + +/* C_REG = #124: FFIFO irq point H setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | "0" | FFIFO_IRQ_PNT | + | | | | | | | [9:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_FFIFO_IRQ_PNT_H 0x03 +#define MCI_FFIFO_IRQ_PNT_H 124 + +/* C_REG = #125: FFIFO irq point L setting register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FFIFO_IRQ_PNT[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_FFIFO_IRQ_PNT_L 0xff +#define MCI_FFIFO_IRQ_PNT_L 125 + +/* C_REG = #128: CDSP flag register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" |CDSP_ | "0" |CDSP_ | + | | | | | |ERR_FLG| |WDT_FLG| + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_FLG_ERR 0x04 +#define MCB_CDSP_FLG_WDT 0x01 +#define MCB_CDSP_FLG_ALL 0x05 +#define MCI_CDSP_FLG 128 + +/* C_REG = #129: CDSP enable register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | ECDSP | "0" | ECDSP | + | | | | | | _ERR | | _WDT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_CDSP_EERR 0x04 +#define MCB_CDSP_EWDT 0x01 +#define MCB_CDSP_ENABLE_ALL 0x05 +#define MCI_CDSP_ENABLE 129 + +/* C_REG = #130: CDSP RFIFO pointer H register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | "0" | "0" | "0" | RFIFO_POINTER[12:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_RFIFO_POINTER_H 0x1f +#define MCI_RFIFO_POINTER_H 130 + +/* C_REG = #131: CDSP RFIFO pointer L register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | RFIFO_POINTER[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_RFIFO_POINTER_L 0xff +#define MCI_RFIFO_POINTER_L 131 + +/* C_REG = #144: Decoder event register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DEC_EVT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EVT 0xff +#define MCI_DEC_EVT 144 + +/* C_REG = #145: Decoder event parameter3 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_EPARAM3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EPARAM3 0xff +#define MCI_DEC_EPARAM3 145 + +/* C_REG = #146: Decoder event parameter2 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_EPARAM2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EPARAM2 0xff +#define MCI_DEC_EPARAM2 146 + +/* C_REG = #147: Decoder event parameter1 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_EPARAM1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EPARAM1 0xff +#define MCI_DEC_EPARAM1 147 + +/* C_REG = #148: Decoder event parameter0 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | DEC_EPARAM0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_DEC_EPARAM0 0xff +#define MCI_DEC_EPARAM0 148 + +/* C_REG = #149: OUT0LR_SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | OUT0R_SEL[2:0] | "0" | OUT0L_SEL[2:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_OUT0_SEL_DEF 0x10 +#define MCB_OUT0R_SEL 0x70 +#define MCB_OUT0L_SEL 0x07 +#define MCI_OUT0_SEL 149 + +/* C_REG = #150: OUT1LR_SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | OUT1R_SEL[2:0] | "0" | OUT1L_SEL[2:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_OUT1_SEL_DEF 0x10 +#define MCB_OUT1R_SEL 0x70 +#define MCB_OUT1L_SEL 0x07 +#define MCI_OUT1_SEL 150 + +/* C_REG = #151: OUT2LR_SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | OUT2R_SEL[2:0] | "0" | OUT2L_SEL[2:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_OUT2_SEL_DEF 0x32 +#define MCB_OUT2R_SEL 0x70 +#define MCB_OUT2L_SEL 0x07 +#define MCI_OUT2_SEL 151 + +/* C_REG = #152: Encoder event register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ENC_EVT | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_EVT 0xff +#define MCI_ENC_EVT 152 + +/* C_REG = #153: Encoder event parameter3 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_EPARAM3 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_EPARAM3 0xff +#define MCI_ENC_EPARAM3 153 + +/* C_REG = #154: Encoder event parameter2 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_EPARAM2 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_EPARAM2 0xff +#define MCI_ENC_EPARAM2 154 + +/* C_REG = #155: Encoder event parameter1 register + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_EPARAM1 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_EPARAM1 0xff +#define MCI_ENC_EPARAM1 155 + +/* C_REG = #156: Encoder event parameter0 register + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ENC_EPARAM0 | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCB_ENC_EPARAM0 0xff +#define MCI_ENC_EPARAM0 156 + +/* C_REG = #157: RDFIFO_BIT_SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DFIFO | DFIFO | CDSP | "0" | RFIFO_| RFIFO_| DFIFO_| DFIFO_| + | _START| _START| _DFIFO| | BIT | SEL | BIT | SEL | + | _SEL | | _START| | | | | | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_RDFIFO_BIT_SEL_DEF 0x00 +#define MCB_RDFIFO_DFIFO_START_SEL 0x80 +#define MCB_RDFIFO_DFIFO_START 0x40 +#define MCB_RDFIFO_CDSP_DFIFO_START 0x20 +#define MCB_RFIFO_BIT 0x08 +#define MCB_RFIFO_BIT_16 0x00 +#define MCB_RFIFO_BIT_32 0x08 +#define MCB_RFIFO_SEL 0x04 +#define MCB_RFIFO_SEL_SRC 0x00 +#define MCB_RFIFO_SEL_HOST 0x04 +#define MCB_DFIFO_BIT 0x02 +#define MCB_DFIFO_BIT_16 0x00 +#define MCB_DFIFO_BIT_32 0x02 +#define MCB_DFIFO_SEL 0x01 +#define MCB_DFIFO_SEL_SRC 0x00 +#define MCB_DFIFO_SEL_HOST 0x01 +#define MCI_RDFIFO_BIT_SEL 157 + +/* C_REG = #158: EFIFO01_SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | EFIFO01_SEL[2:0] | "0" | EFIFO00_SEL[2:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EFIFO01_SEL_DEF 0x32 +#define MCB_EFIFO1_SEL 0x70 +#define MCB_EFIFO0_SEL 0x07 +#define MCI_EFIFO01_SEL 158 + +/* C_REG = #159: EFIFO23_SEL + + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | EFIFO03_SEL[2:0] | "0" | EFIFO02_SEL[2:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_EFIFO23_SEL_DEF 0x54 +#define MCB_EFIFO3_SEL 0x70 +#define MCB_EFIFO2_SEL 0x07 +#define MCI_EFIFO23_SEL 159 + +/* F_REG */ + +/* FDSP_ADR = #3: ADIDFmt0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI3DFMT[1:0] | ADI2DFMT[1:0] | ADI1DFMT[1:0] | ADI0DFMT[1:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIDFMT0 0x03 +#define MCI_ADIDFMT0_DEF 0x00 +#define MCB_ADI3DFMT 0xc0 +#define MCB_ADI2DFMT 0x30 +#define MCB_ADI1DFMT 0x0c +#define MCB_ADI0DFMT 0x03 + +/* FDSP_ADR = #4: ADIDFmt1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI7DFMT[1:0] | ADI6DFMT[1:0] | ADI5DFMT[1:0] | ADI4DFMT[1:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIDFMT1 0x04 +#define MCI_ADIDFMT1_DEF 0x00 +#define MCB_ADI7DFMT 0xc0 +#define MCB_ADI6DFMT 0x30 +#define MCB_ADI5DFMT 0x0c +#define MCB_ADI4DFMT 0x03 + +/* FDSP_ADR = #5: ADIMute0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI07 | ADI06 | ADI05 | ADI04 | ADI03 | ADI02 | ADI01 | ADI00 | + | MTN | MTN | MTN | MTN | MTN | MTN | MTN | MTN | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIMUTE0 0x05 +#define MCI_ADIMUTE0_DEF 0x00 +#define MCB_ADI07MTN 0x80 +#define MCB_ADI06MTN 0x40 +#define MCB_ADI05MTN 0x20 +#define MCB_ADI04MTN 0x10 +#define MCB_ADI03MTN 0x08 +#define MCB_ADI02MTN 0x04 +#define MCB_ADI01MTN 0x02 +#define MCB_ADI00MTN 0x01 + +/* FDSP_ADR = #6: ADIMute1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI15 | ADI14 | ADI13 | ADI12 | ADI11 | ADI10 | ADI09 | ADI08 | + | MTN | MTN | MTN | MTN | MTN | MTN | MTN | MTN | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIMUTE1 0x06 +#define MCI_ADIMUTE1_DEF 0x00 +#define MCB_ADI15MTN 0x80 +#define MCB_ADI14MTN 0x40 +#define MCB_ADI13MTN 0x20 +#define MCB_ADI12MTN 0x10 +#define MCB_ADI11MTN 0x08 +#define MCB_ADI10MTN 0x04 +#define MCB_ADI09MTN 0x02 +#define MCB_ADI08MTN 0x01 + +/* FDSP_ADR = #7: ADIMute2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | "0" | "0" | "0" | "0" | "0" | "0" | "0" | ADIMT | + | | | | | | | | SET | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIMUTE2 0x07 +#define MCI_ADIMUTE2_DEF 0x00 +#define MCB_ADIMTSET 0x01 + +/* FDSP_ADR = #8: ADICSel0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI01CSEL[3:0] | ADI00CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL0 0x08 +#define MCI_ADICSEL0_DEF 0x10 +#define MCB_ADI01CSEL 0xf0 +#define MCB_ADI00CSEL 0x0f + +/* FDSP_ADR = #9: ADICSel1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI03CSEL[3:0] | ADI02CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_ADICSEL1 0x09 +#define MCI_ADICSEL1_DEF 0x32 +#define MCB_ADI03CSEL 0xf0 +#define MCB_ADI02CSEL 0x0f + +/* FDSP_ADR = #10: ADICSel2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI05CSEL[3:0] | ADI04CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL2 0x0a +#define MCI_ADICSEL2_DEF 0x54 +#define MCB_ADI05CSEL 0xf0 +#define MCB_ADI04CSEL 0x0f + +/* FDSP_ADR = #11: ADICSel3 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI07CSEL[3:0] | ADI06CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL3 0x0b +#define MCI_ADICSEL3_DEF 0x76 +#define MCB_ADI07CSEL 0xf0 +#define MCB_ADI06CSEL 0x0f + +/* FDSP_ADR = #12: ADICSel4 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI09CSEL[3:0] | ADI08CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL4 0x0c +#define MCI_ADICSEL4_DEF 0x98 +#define MCB_ADI09CSEL 0xf0 +#define MCB_ADI08CSEL 0x0f + +/* FDSP_ADR = #13: ADICSel5 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI11CSEL[3:0] | ADI10CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL5 0x0d +#define MCI_ADICSEL5_DEF 0xba +#define MCB_ADI11CSEL 0xf0 +#define MCB_ADI10CSEL 0x0f + +/* FDSP_ADR = #14: ADICSel6 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI13CSEL[3:0] | ADI12CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL6 0x0e +#define MCI_ADICSEL6_DEF 0xdc +#define MCB_ADI13CSEL 0xf0 +#define MCB_ADI12CSEL 0x0f + +/* FDSP_ADR = #15: ADICSel7 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADI15CSEL[3:0] | ADI14CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADICSEL7 0x0f +#define MCI_ADICSEL7_DEF 0xfe +#define MCB_ADI15CSEL 0xf0 +#define MCB_ADI14CSEL 0x0f + +/* FDSP_ADR = #19: ADODFmt0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO3DFMT[1:0] | ADO2DFMT[1:0] | ADO1DFMT[1:0] | ADO0DFMT[1:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADODFMT0 0x13 +#define MCI_ADODFMT0_DEF 0x00 +#define MCB_ADO3DFMT 0xc0 +#define MCB_ADO2DFMT 0x30 +#define MCB_ADO1DFMT 0x0c +#define MCB_ADO0DFMT 0x03 + +/* FDSP_ADR = #20: ADODFmt1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO7DFMT[1:0] | ADO6DFMT[1:0] | ADO5DFMT[1:0] | ADO4DFMT[1:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADODFMT1 0x14 +#define MCI_ADODFMT1_DEF 0x00 +#define MCB_ADO7DFMT 0xc0 +#define MCB_ADO6DFMT 0x30 +#define MCB_ADO5DFMT 0x0c +#define MCB_ADO4DFMT 0x03 + +/* FDSP_ADR = #21: ADOMute0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO07 | ADO06 | ADO05 | ADO04 | ADO03 | ADO02 | ADO01 | ADO00 | + | MTN | MTN | MTN | MTN | MTN | MTN | MTN | MTN | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOMUTE0 0x15 +#define MCI_ADOMUTE0_DEF 0x00 +#define MCB_ADO07MTN 0x80 +#define MCB_ADO06MTN 0x40 +#define MCB_ADO05MTN 0x20 +#define MCB_ADO04MTN 0x10 +#define MCB_ADO03MTN 0x08 +#define MCB_ADO02MTN 0x04 +#define MCB_ADO01MTN 0x02 +#define MCB_ADO00MTN 0x01 + +/* FDSP_ADR = #22: ADOMute1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO15 | ADO14 | ADO13 | ADO12 | ADO11 | ADO10 | ADO09 | ADO08 | + | MTN | MTN | MTN | MTN | MTN | MTN | MTN | MTN | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOMUTE1 0x16 +#define MCI_ADOMUTE1_DEF 0x00 +#define MCB_ADO15MTN 0x80 +#define MCB_ADO14MTN 0x40 +#define MCB_ADO13MTN 0x20 +#define MCB_ADO12MTN 0x10 +#define MCB_ADO11MTN 0x08 +#define MCB_ADO10MTN 0x04 +#define MCB_ADO09MTN 0x02 +#define MCB_ADO08MTN 0x01 + +/* FDSP_ADR = #23: ADOMute2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W | "0" | "0" | "0" | "0" | "0" | "0" | "0" | ADOMT | + | | | | | | | | SET | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOMUTE2 0x17 +#define MCI_ADOMUTE2_DEF 0x00 +#define MCB_ADOMTSET 0x01 + +/* FDSP_ADR = #24: ADOCSel0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO01CSEL[3:0] | ADO00CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL0 0x18 +#define MCI_ADOCSEL0_DEF 0x10 +#define MCB_ADO01CSEL 0xf0 +#define MCB_ADO00CSEL 0x0f + +/* FDSP_ADR = #25: ADOCSel1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO03CSEL[3:0] | ADO02CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL1 0x19 +#define MCI_ADOCSEL1_DEF 0x32 +#define MCB_ADO03CSEL 0xf0 +#define MCB_ADO02CSEL 0x0f + +/* FDSP_ADR = #26: ADOCSel2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO05CSEL[3:0] | ADO04CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL2 0x1a +#define MCI_ADOCSEL2_DEF 0x54 +#define MCB_ADO05CSEL 0xf0 +#define MCB_ADO04CSEL 0x0f + +/* FDSP_ADR = #27: ADOCSel3 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO07CSEL[3:0] | ADO06CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL3 0x1b +#define MCI_ADOCSEL3_DEF 0x76 +#define MCB_ADO07CSEL 0xf0 +#define MCB_ADO06CSEL 0x0f + +/* FDSP_ADR = #28: ADOCSel4 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO09CSEL[3:0] | ADO08CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL4 0x1c +#define MCI_ADOCSEL4_DEF 0x98 +#define MCB_ADO09CSEL 0xf0 +#define MCB_ADO08CSEL 0x0f + +/* FDSP_ADR = #29: ADOCSel5 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO11CSEL[3:0] | ADO10CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL5 0x1d +#define MCI_ADOCSEL5_DEF 0xba +#define MCB_ADO11CSEL 0xf0 +#define MCB_ADO10CSEL 0x0f + +/* FDSP_ADR = #30: ADOCSel6 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO13CSEL[3:0] | ADO12CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL6 0x1e +#define MCI_ADOCSEL6_DEF 0xdc +#define MCB_ADO13CSEL 0xf0 +#define MCB_ADO12CSEL 0x0f + +/* FDSP_ADR = #31: ADOCSel7 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | ADO15CSEL[3:0] | ADO14CSEL[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOCSEL7 0x1f +#define MCI_ADOCSEL7_DEF 0xfe +#define MCB_ADO15CSEL 0xf0 +#define MCB_ADO14CSEL 0x0f + +/* FDSP_ADR = #32: DSPCtl + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | DSP | "0" | "0" | "0" | "0" | "0" | "0" | DSP | + | BYPASS| | | | | | | START | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_DSPCTRL 0x20 +#define MCI_DSPCTRL_DEF 0x00 +#define MCB_DSPBYPASS 0x80 +#define MCB_DSPSTART 0x01 + +/* FDSP_ADR = #33: DSPState + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R |AUTOMTN| "0" | "0" | "0" | "0" | "0" | "0" | DSPACT| + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_DSPSTATE 0x21 +#define MCI_DSPSTATE_DEF 0x00 +#define MCB_AUTOMTN 0x80 +#define MCB_DSPACT 0x01 + +/* FDSP_ADR = #34: ADIFs0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ADIFS[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIFS0 0x22 +#define MCI_ADIFS0_DEF 0x00 +#define MCB_ADIFS0 0xff + +/* FDSP_ADR = #35: ADIFs1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ADIFS[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADIFS1 0x23 +#define MCI_ADIFS1_DEF 0x00 +#define MCB_ADIFS1 0xff + +/* FDSP_ADR = #36: ADOFs0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ADOFS[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_ADOFS0 0x24 +#define MCI_ADOFS0_DEF 0x00 +#define MCB_ADOFS0 0xff + +/* FDSP_ADR = #37: ADOFs1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +R | ADOFS[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_ADOFS1 0x25 +#define MCI_ADOFS1_DEF 0x00 +#define MCB_ADOFS1 0xff + +/* FDSP_ADR = #38: IReqApp0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | IRAPP[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_IREQAPP0 0x26 +#define MCI_IREQAPP0_DEF 0x00 +#define MCB_IREQAPP0 0xff +#define MCB_IRAPP23 0x80 +#define MCB_IRAPP22 0x40 +#define MCB_IRAPP21 0x20 +#define MCB_IRAPP20 0x10 +#define MCB_IRAPP19 0x08 +#define MCB_IRAPP18 0x04 +#define MCB_IRAPP17 0x02 +#define MCB_IRAPP16 0x01 + +/* FDSP_ADR = #39: IReqApp1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | IRAPP[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_IREQAPP1 0x27 +#define MCI_IREQAPP1_DEF 0x00 +#define MCB_IREQAPP1 0xff +#define MCB_IRAPP15 0x80 +#define MCB_IRAPP14 0x40 +#define MCB_IRAPP13 0x20 +#define MCB_IRAPP12 0x10 +#define MCB_IRAPP11 0x08 +#define MCB_IRAPP10 0x04 +#define MCB_IRAPP09 0x02 +#define MCB_IRAPP08 0x01 + +/* FDSP_ADR = #40: IReqApp2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | IRAPP[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_IREQAPP2 0x28 +#define MCI_IREQAPP2_DEF 0x00 +#define MCB_IREQAPP2 0xff +#define MCB_IRAPP07 0x80 +#define MCB_IRAPP06 0x40 +#define MCB_IRAPP05 0x20 +#define MCB_IRAPP04 0x10 +#define MCB_IRAPP03 0x08 +#define MCB_IRAPP02 0x04 +#define MCB_IRAPP01 0x02 +#define MCB_IRAPP00 0x01 + +/* FDSP_ADR = #41: IReqTop + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | IRTOP[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_IREQTOP 0x29 +#define MCI_IREQTOP_DEF 0x00 +#define MCB_IREQTOP 0x0f +#define MCB_IREQTOP3 0x08 +#define MCB_IREQTOP2 0x04 +#define MCB_IREQTOP1 0x02 +#define MCB_IREQTOP0 0x01 + +/* FDSP_ADR = #64: FWMod + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWMOD[3:0] | FS[3:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWMOD 0x40 +#define MCI_FWMOD_DEF 0x00 +#define MCB_FWMOD 0xf0 +#define MCB_FS 0x0f + +/* FDSP_ADR = #65: AppExec0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPEXEC[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPEXEC0 0x41 +#define MCI_APPEXEC0_DEF 0x00 +#define MCB_APPEXEC0 0xff +#define MCB_APPEXEC23 0x80 +#define MCB_APPEXEC22 0x40 +#define MCB_APPEXEC21 0x20 +#define MCB_APPEXEC20 0x10 +#define MCB_APPEXEC19 0x08 +#define MCB_APPEXEC18 0x04 +#define MCB_APPEXEC17 0x02 +#define MCB_APPEXEC16 0x01 + +/* FDSP_ADR = #66: AppExec1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPEXEC[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPEXEC1 0x42 +#define MCI_APPEXEC1_DEF 0x00 +#define MCB_APPEXEC1 0xff +#define MCB_APPEXEC15 0x80 +#define MCB_APPEXEC14 0x40 +#define MCB_APPEXEC13 0x20 +#define MCB_APPEXEC12 0x10 +#define MCB_APPEXEC11 0x08 +#define MCB_APPEXEC10 0x04 +#define MCB_APPEXEC09 0x02 +#define MCB_APPEXEC08 0x01 + +/* FDSP_ADR = #67: AppExec2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPEXEC[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPEXEC2 0x43 +#define MCI_APPEXEC2_DEF 0x00 +#define MCB_APPEXEC2 0xff +#define MCB_APPEXEC07 0x80 +#define MCB_APPEXEC06 0x40 +#define MCB_APPEXEC05 0x20 +#define MCB_APPEXEC04 0x10 +#define MCB_APPEXEC03 0x08 +#define MCB_APPEXEC02 0x04 +#define MCB_APPEXEC01 0x02 +#define MCB_APPEXEC00 0x01 + +/* FDSP_ADR = #68: AppAct0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPACT[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPACT0 0x44 +#define MCI_APPACT0_DEF 0x00 +#define MCB_APPACT23 0x80 +#define MCB_APPACT22 0x40 +#define MCB_APPACT21 0x20 +#define MCB_APPACT20 0x10 +#define MCB_APPACT19 0x08 +#define MCB_APPACT18 0x04 +#define MCB_APPACT17 0x02 +#define MCB_APPACT16 0x01 + +/* FDSP_ADR = #69: AppAct1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPACT[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPACT1 0x45 +#define MCI_APPACT1_DEF 0x00 +#define MCB_APPACT15 0x80 +#define MCB_APPACT14 0x40 +#define MCB_APPACT13 0x20 +#define MCB_APPACT12 0x10 +#define MCB_APPACT11 0x08 +#define MCB_APPACT10 0x04 +#define MCB_APPACT09 0x02 +#define MCB_APPACT08 0x01 + +/* FDSP_ADR = #70: AppAct2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPACT[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPACT2 0x46 +#define MCI_APPACT2_DEF 0x00 +#define MCB_APPACT07 0x80 +#define MCB_APPACT06 0x40 +#define MCB_APPACT05 0x20 +#define MCB_APPACT04 0x10 +#define MCB_APPACT03 0x08 +#define MCB_APPACT02 0x04 +#define MCB_APPACT01 0x02 +#define MCB_APPACT00 0x01 + +/* FDSP_ADR = #71: AppIEnb0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPIE[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPIENB0 0x47 +#define MCI_APPIENB0_DEF 0x00 +#define MCB_APPIE23 0x80 +#define MCB_APPIE22 0x40 +#define MCB_APPIE21 0x20 +#define MCB_APPIE20 0x10 +#define MCB_APPIE19 0x08 +#define MCB_APPIE18 0x04 +#define MCB_APPIE17 0x02 +#define MCB_APPIE16 0x01 + +/* FDSP_ADR = #72: AppIEnb1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPIE[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPIENB1 0x48 +#define MCI_APPIENB1_DEF 0x00 +#define MCB_APPIE15 0x80 +#define MCB_APPIE14 0x40 +#define MCB_APPIE13 0x20 +#define MCB_APPIE12 0x10 +#define MCB_APPIE11 0x08 +#define MCB_APPIE10 0x04 +#define MCB_APPIE09 0x02 +#define MCB_APPIE08 0x01 + +/* FDSP_ADR = #73: AppIEnb2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPIE[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_APPIENB2 0x49 +#define MCI_APPIENB2_DEF 0x00 +#define MCB_APPIE07 0x80 +#define MCB_APPIE06 0x40 +#define MCB_APPIE05 0x20 +#define MCB_APPIE04 0x10 +#define MCB_APPIE03 0x08 +#define MCB_APPIE02 0x04 +#define MCB_APPIE01 0x02 +#define MCB_APPIE00 0x01 + +/* FDSP_ADR = #74: AppFade0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPFADE[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ + +#define MCI_APPFADE0 0x4a +#define MCI_APPFADE0_DEF 0x00 +#define MCB_APPFADE23 0x80 +#define MCB_APPFADE22 0x40 +#define MCB_APPFADE21 0x20 +#define MCB_APPFADE20 0x10 +#define MCB_APPFADE19 0x08 +#define MCB_APPFADE18 0x04 +#define MCB_APPFADE17 0x02 +#define MCB_APPFADE16 0x01 + +/* FDSP_ADR = #75: AppFade1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPFADE[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPFADE1 0x4b +#define MCI_APPFADE1_DEF 0x00 +#define MCB_APPFADE15 0x80 +#define MCB_APPFADE14 0x40 +#define MCB_APPFADE13 0x20 +#define MCB_APPFADE12 0x10 +#define MCB_APPFADE11 0x08 +#define MCB_APPFADE10 0x04 +#define MCB_APPFADE09 0x02 +#define MCB_APPFADE08 0x01 + +/* FDSP_ADR = #76: AppFade2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | APPFADE[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_APPFADE2 0x4c +#define MCI_APPFADE2_DEF 0x00 +#define MCB_APPFADE07 0x80 +#define MCB_APPFADE06 0x40 +#define MCB_APPFADE05 0x20 +#define MCB_APPFADE04 0x10 +#define MCB_APPFADE03 0x08 +#define MCB_APPFADE02 0x04 +#define MCB_APPFADE01 0x02 +#define MCB_APPFADE00 0x01 + +/* FDSP_ADR = #77: FadeCode + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | "0" | FADECODE[1:0]| + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FADECODE 0x4d +#define MCI_FADECODE_DEF 0x00 +#define MCB_FADECODE 0x03 + +/* FDSP_ADR = #78: TopIEnb + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | TOPIE[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_TOPIENB 0x4e +#define MCI_TOPIENB_DEF 0x00 +#define MCB_TOPIENB 0xff +#define MCB_TOPIE7 0x80 +#define MCB_TOPIE6 0x40 +#define MCB_TOPIE5 0x20 +#define MCB_TOPIE4 0x10 +#define MCB_TOPIE3 0x08 +#define MCB_TOPIE2 0x04 +#define MCB_TOPIE1 0x02 +#define MCB_TOPIE0 0x01 + +/* FDSP_ADR = #119: FWSel + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | FWSEL[5:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWSEL 0x77 +#define MCI_FWSEL_DEF 0x00 +#define MCB_FWSEL 0x3f + +/* FDSP_ADR = #120: FWID + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWID[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWID 0x78 +#define MCI_FWID_DEF 0x00 +#define MCB_FWID 0xff + +/* FDSP_ADR = #121: FWVer0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWVER[23:16] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWVER0 0x79 +#define MCI_FWVER0_DEF 0x00 +#define MCB_FWVER0 0xff + +/* FDSP_ADR = #122: FWVer1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWVER[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWVER1 0x7a +#define MCI_FWVER1_DEF 0x00 +#define MCB_FWVER1 0xff + +/* FDSP_ADR = #123: FWVer2 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWVER[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWVER2 0x7B +#define MCI_FWVER2_DEF 0x00 +#define MCB_FWVER2 0xff + +/* FDSP_ADR = #124: FWState + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | "0" | "0" | "0" | "0" | "0" | FWSTATE[2:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWSTATE 0x7c +#define MCI_FWSTATE_DEF 0x00 +#define MCB_FWSTATE 0x07 + +/* FDSP_ADR = #125: FWRetVal + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWRETVAL[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWRETVAL 0x7d +#define MCI_FWRETVAL_DEF 0x00 +#define MCB_FWRETVAL 0xff + +/* FDSP_ADR = #126: FWLoad0 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWLOAD[15:8] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWLOAD0 0x7e +#define MCI_FWLOAD0_DEF 0x00 +#define MCB_FWLOAD0 0xff + +/* FDSP_ADR = #127: FWLoad1 + 7 6 5 4 3 2 1 0 + +-------+-------+-------+-------+-------+-------+-------+-------+ +W/R | FWLOAD[7:0] | + +-------+-------+-------+-------+-------+-------+-------+-------+ +*/ +#define MCI_FWLOAD1 0x7f +#define MCI_FWLOAD1_DEF 0x00 +#define MCI_FWLOAD1 0x7f + +/* ANA_REG */ +#define MCI_ANA_ID 0 +#define MCI_ANA_ID_DEF 0x90 + +#define MCI_ANA_RST 1 +#define MCB_ANA_RST 0x01 +#define MCI_ANA_RST_DEF MCB_ANA_RST + +#define MCI_AP 2 +#define MCB_AP_HPDET 0x20 +#define MCB_AP_LDOA 0x10 +#define MCB_AP_LDOD 0x08 +#define MCB_AP_BGR 0x04 +#define MCB_AP_CP 0x02 +#define MCB_AP_VR 0x01 +#define MCI_AP_DEF (MCB_AP_VR | MCB_AP_CP | \ + MCB_AP_BGR | MCB_AP_LDOA | \ + MCB_AP_LDOD | MCB_AP_HPDET) + +#define MCI_AP_DA0 3 +#define MCB_AP_RC 0x40 +#define MCB_AP_HPR 0x20 +#define MCB_AP_HPL 0x10 +#define MCB_AP_LO1R 0x08 +#define MCB_AP_LO1L 0x04 +#define MCB_AP_DA0R 0x02 +#define MCB_AP_DA0L 0x01 +#define MCI_AP_DA0_DEF (MCB_AP_DA0L | MCB_AP_DA0R | \ + MCB_AP_LO1L | MCB_AP_LO1R | \ + MCB_AP_HPL | MCB_AP_HPR | MCB_AP_RC) + +#define MCI_AP_DA1 4 +#define MCB_AP_SPR2 0x80 +#define MCB_AP_SPR1 0x40 +#define MCB_AP_SPL2 0x20 +#define MCB_AP_SPL1 0x10 +#define MCB_AP_LO2R 0x08 +#define MCB_AP_LO2L 0x04 +#define MCB_AP_DA1R 0x02 +#define MCB_AP_DA1L 0x01 +#define MCI_AP_DA1_DEF (MCB_AP_DA1L | MCB_AP_DA1R | \ + MCB_AP_LO2L | MCB_AP_LO2R | \ + MCB_AP_SPL1 | MCB_AP_SPL2 | \ + MCB_AP_SPR1 | MCB_AP_SPR2) + +#define MCI_PN_DA 5 +#define MCB_PN_DA1 0x02 +#define MCB_PN_DA0 0x01 + +#define MCI_AP_MIC 6 +#define MCB_MC4 0x80 +#define MCB_MC3 0x40 +#define MCB_MC2 0x20 +#define MCB_MC1 0x10 +#define MCB_MB4 0x08 +#define MCB_MB3 0x04 +#define MCB_MB2 0x02 +#define MCB_MB1 0x01 +#define MCI_AP_MIC_DEF (MCB_MB1 | MCB_MB2 | MCB_MB3 | \ + MCB_MB4 | MCB_MC1 | MCB_MC2 | \ + MCB_MC3 | MCB_MC4) + +#define MCI_AP_AD 7 +#define MCB_AP_LI 0x80 +#define MCB_AP_ADM 0x04 +#define MCB_AP_ADR 0x02 +#define MCB_AP_ADL 0x01 +#define MCI_AP_AD_DEF (MCB_AP_LI | MCB_AP_ADM | \ + MCB_AP_ADR | MCB_AP_ADL) + +#define MCI_PPD 8 +#define MCB_PPD_RC 0x10 +#define MCB_PPD_HP 0x08 +#define MCB_PPD_SP 0x04 +#define MCB_PPD_LO2 0x02 +#define MCB_PPD_LO1 0x01 + +#define MCI_APM 9 +#define MCB_APMOFF 0x01 + +#define MCI_BUSY1 11 +#define MCB_SPR_BUSY 0x20 +#define MCB_SPL_BUSY 0x10 +#define MCB_HPR_BUSY 0x08 +#define MCB_HPL_BUSY 0x04 + +#define MCI_BUSY2 12 +#define MCB_LO2R_BUSY 0x80 +#define MCB_LO2L_BUSY 0x40 +#define MCB_LO1R_BUSY 0x20 +#define MCB_LO1L_BUSY 0x10 +#define MCB_RC_BUSY 0x08 + +#define MCI_MBSEL 13 + +#define MCI_KDSET 14 +#define MCB_MBS4_DISCH 0x80 +#define MCB_MBS3_DISCH 0x40 +#define MCB_MBS2_DISCH 0x20 +#define MCB_MBS1_DISCH 0x10 +#define MCB_KDSET2 0x02 +#define MCB_KDSET1 0x01 + +#define MCI_NONCLIP 21 +#define MCI_NONCLIP_DEF 0x03 + +#define MCI_DIF 24 + +#define MCI_LIVOL_L 25 +#define MCB_ALAT_LI 0x80 + +#define MCI_LIVOL_R 26 + +#define MCI_MC1VOL 27 +#define MCI_MC2VOL 28 +#define MCI_MC3VOL 29 +#define MCI_MC4VOL 30 + +#define MCI_HPVOL_L 31 +#define MCB_ALAT_HP 0x80 + +#define MCI_HPVOL_R 32 + +#define MCI_SPVOL_L 33 +#define MCB_ALAT_SP 0x80 + +#define MCI_SPVOL_R 34 + +#define MCI_RCVOL 35 + +#define MCI_LO1VOL_L 36 +#define MCB_ALAT_LO1 0x80 + +#define MCI_LO1VOL_R 37 + +#define MCI_LO2VOL_L 38 +#define MCB_ALAT_LO2 0x80 + +#define MCI_LO2VOL_R 39 + +#define MCI_HPDETVOL 40 + +#define MCI_SVOL 41 +#define MCB_SVOL_HP 0x80 +#define MCB_SVOL_SP 0x40 +#define MCB_SVOL_RC 0x20 +#define MCB_SVOL_LO2 0x10 +#define MCB_SVOL_LO1 0x08 +#define MCB_SVOL_HPDET 0x04 +#define MCI_SVOL_DEF (MCB_SVOL_HP | MCB_SVOL_SP | \ + MCB_SVOL_RC | MCB_SVOL_LO2 | \ + MCB_SVOL_LO1 | MCB_SVOL_HPDET) + +#define MCI_HIZ 42 +#define MCB_HPR_HIZ 0x80 +#define MCB_HPL_HIZ 0x40 +#define MCB_SPR_HIZ 0x20 +#define MCB_SPL_HIZ 0x10 +#define MCB_RC_HIZ 0x08 +#define MCI_HIZ_DEF 0xf8 + +#define MCI_LO_HIZ 43 +#define MCB_LO2R_HIZ 0x80 +#define MCB_LO2L_HIZ 0x40 +#define MCB_LO1R_HIZ 0x20 +#define MCB_LO1L_HIZ 0x10 +#define MCI_LO_HIZ_DEF 0xf0 + +#define MCI_MCSNG 44 +#define MCB_MC4SNG 0x80 +#define MCB_MC3SNG 0x40 +#define MCB_MC2SNG 0x20 +#define MCB_MC1SNG 0x10 + +#define MCI_RDY1 45 +#define MCB_VREF_RDY 0x40 +#define MCB_SPDY_R 0x20 +#define MCB_SPDY_L 0x10 +#define MCB_HPDY_R 0x08 +#define MCB_HPDY_L 0x04 +#define MCB_CPPDRDY 0x02 +#define MCB_HPDET_RDY 0x01 + +#define MCI_RDY2 46 +#define MCB_LO2RDY_R 0x80 +#define MCB_LO2RDY_L 0x40 +#define MCB_LO1RDY_R 0x20 +#define MCB_LO1RDY_L 0x10 +#define MCB_RCRDY 0x08 + +#define MCI_ZCOFF 47 +#define MCB_ZCOFF_HP 0x80 +#define MCB_ZCOFF_SP 0x40 +#define MCB_ZCOFF_RC 0x20 +#define MCB_ZCOFF_LO2 0x10 +#define MCB_ZCOFF_LO1 0x08 +#define MCI_ZCOFF_DEF_ES1 (MCB_ZCOFF_HP | MCB_ZCOFF_LO2 | \ + MCB_ZCOFF_LO1) + +#define MCI_ADL_MIX 48 +#define MCI_ADR_MIX 49 +#define MCI_ADM_MIX 50 + +#define MCB_AD_M4MIX 0x80 +#define MCB_AD_M3MIX 0x40 +#define MCB_AD_M2MIX 0x20 +#define MCB_AD_M1MIX 0x10 +#define MCB_MONO_AD_LI 0x02 +#define MCB_AD_LIMIX 0x01 + +#define MCI_DCERR 51 +#define MCB_DCERR 0x10 +#define MCB_L_OCPR 0x04 +#define MCB_L_OCPL 0x02 +#define MCB_OTP 0x01 + +#define MCI_CPMOD 53 +#define MCB_HIP_DISABLE 0x08 +#define MCB_CPMOD 0x01 +#define MCI_CPMOD_DEF_ES1 MCB_CPMOD +#define MCI_CPMOD_DEF (MCB_HIP_DISABLE | MCB_CPMOD) + +#define MCI_DNG_ES1 55 +#define MCI_DNG_DEF_ES1 0x14 + +#define MCI_DNG_HP_ES1 56 +#define MCI_DNG_HP_DEF_ES1 0x05 + +#define MCI_DNG_SP_ES1 57 +#define MCI_DNG_SP_DEF_ES1 0x05 + +#define MCI_DNG_RC_ES1 58 +#define MCI_DNG_RC_DEF_ES1 0x05 + +#define MCI_DNG_LO1_ES1 59 +#define MCI_DNG_LO1_DEF_ES1 0x05 + +#define MCI_DNG_LO2_ES1 60 +#define MCI_DNG_LO2_DEF_ES1 0x05 + +#define MCI_RBSEL 61 +#define MCB_RBSEL 0x80 +#define MCB_OFC_MAN 0x01 + +#define MCI_DNG 108 +#define MCI_DNG_DEF 0x31 + +#define MCI_DNG_HP 109 +#define MCI_DNG_HP_DEF 0x0f + +#define MCI_DNG_SP 110 +#define MCI_DNG_SP_DEF 0x0f + +#define MCI_DNG_RC 111 +#define MCI_DNG_RC_DEF 0x0f + +#define MCI_DNG_LO1 112 +#define MCI_DNG_LO1_DEF 0x0f + +#define MCI_DNG_LO2 113 +#define MCI_DNG_LO2_DEF 0x0f + +/* CD_REG */ +#define MCI_HW_ID 0 +#define MCI_HW_ID_DEF 0x90 + +#define MCI_CD_RST 1 +#define MCI_CD_RST_DEF 0x01 + +#define MCI_DP 2 +#define MCB_DP_ADC 0x40 +#define MCB_DP_DAC1 0x20 +#define MCB_DP_DAC0 0x10 +#define MCB_DP_PDMCK 0x04 +#define MCB_DP_PDMADC 0x02 +#define MCB_DP_PDMDAC 0x01 +#define MCI_DP_DEF (MCB_DP_ADC | MCB_DP_DAC1 | \ + MCB_DP_DAC0 | MCB_DP_PDMCK | \ + MCB_DP_PDMADC | MCB_DP_PDMDAC) + +#define MCI_DP_OSC 3 +#define MCB_DP_OSC 0x01 +#define MCI_DP_OSC_DEF MCB_DP_OSC + +#define MCI_CKSEL 4 +#define MCB_CKSEL0 0x10 +#define MCB_CRTC 0x02 +#define MCB_HSDET 0x01 +#define MCI_CKSEL_DEF_ES1 MCB_HSDET +#define MCI_CKSEL_DEF (MCB_CRTC | MCB_HSDET) + +#define MCI_SCKMSKON_R 5 + +#define MCI_IRQHS 8 +#define MCB_EIRQHS 0x80 +#define MCB_IRQHS 0x40 + +#define MCI_EPLUGDET 9 +#define MCB_EPLUGDET 0x80 +#define MCB_EPLUGUNDET_DB 0x02 +#define MCB_EPLUGDET_DB 0x01 + +#define MCI_PLUGDET 10 +#define MCB_PLUGDET 0x80 +#define MCB_SPLUGUNDET_DB 0x02 +#define MCB_SPLUGDET_DB 0x01 + +#define MCI_PLUGDET_DB 11 +#define MCB_PLUGUNDET_DB 0x02 +#define MCB_PLUGDET_DB 0x01 + +#define MCI_RPLUGDET 12 +#define MCB_RPLUGDET 0x80 +#define MCB_RPLUGUNDET_DB 0x02 +#define MCB_RPLUGDET_DB 0x01 + +#define MCI_EDLYKEY 13 + +#define MCI_SDLYKEY 14 + +#define MCI_EMICDET 15 + +#define MCI_SMICDET 16 +#define MCB_SMICDET 0x40 + +#define MCI_MICDET 17 +#define MCB_MICDET 0x40 +#define MCI_MICDET_DEF 0x38 + +#define MCI_RMICDET 18 + +#define MCI_KEYCNTCLR0 19 +#define MCB_KEYCNTCLR0 0x80 + +#define MCI_KEYCNTCLR1 20 +#define MCB_KEYCNTCLR1 0x80 + +#define MCI_KEYCNTCLR2 21 +#define MCB_KEYCNTCLR2 0x80 + +#define MCI_HSDETEN 22 +#define MCB_HSDETEN 0x80 +#define MCB_MKDETEN 0x40 +#define MCI_HSDETEN_DEF 0x05 + +#define MCI_IRQTYPE 23 +#define MCI_IRQTYPE_DEF 0xc3 + +#define MCI_DLYIRQSTOP 24 + +#define MCI_DETIN_INV 25 +#define MCI_DETIN_INV_DEF_ES1 0x01 +#define MCI_DETIN_INV_DEF 0xe3 + +#define MCI_IRQM_KEYOFF 26 + +#define MCI_HSDETMODE 28 +#define MCI_HSDETMODE_DEF 0x04 + +#define MCI_DBNC_PERIOD 29 +#define MCB_DBNC_LPERIOD 0x02 +#define MCI_DBNC_PERIOD_DEF 0x22 + +#define MCI_DBNC_NUM 30 +#define MCI_DBNC_NUM_DEF_ES1 0x3f +#define MCI_DBNC_NUM_DEF 0xbf + +#define MCI_KEY_MTIM 31 +#define MCI_KEY_MTIM_DEF 0x80 + +#define MCI_KEYONDLYTIM_K0 32 +#define MCI_KEYOFFDLYTIM_K0 33 + +#define MCI_KEYONDLYTIM_K1 34 +#define MCI_KEYOFFDLYTIM_K1 35 + +#define MCI_KEYONDLYTIM_K2 36 +#define MCI_KEYOFFDLYTIM_K2 37 + +#define MCI_EIRQSENSE 48 +#define MCB_EIRQSENSE 0x80 +#define MCB_EIRQOFC 0x08 + +#define MCI_SSENSEFIN 49 +#define MCB_SSENSEFIN 0x80 +#define MCB_SENSE_BSY 0x40 +#define MCB_SOFFCANFIN 0x08 +#define MCB_OFFCAN_BSY 0x04 + +#define MCI_STDPLUGSEL 52 +#define MCB_STDPLUGSEL 0x80 + +#endif /* _MCDEFS_H */
At Wed, 16 Jan 2013 17:27:04 +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/mcdefs.h | 4303 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 4303 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mcdefs.h
diff --git a/sound/soc/codecs/ymu831/mcdefs.h b/sound/soc/codecs/ymu831/mcdefs.h new file mode 100644 index 0000000..fbd2008 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdefs.h @@ -0,0 +1,4303 @@ +/****************************************************************************
- Copyrightc 2012 Yamaha Corporation. All rights reserved.
- Module : mcdefs.h
- Description : MC device definitions
- Version : 1.0.1 Dec 18 2012
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
So you need to keep zlib license instead of the standard GPLv2?
Takashi
On Wed, 16 Jan 2013 12:45:56 +0100 Takashi Iwai tiwai@suse.de wrote:
At Wed, 16 Jan 2013 17:27:04 +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/mcdefs.h | 4303 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 4303 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mcdefs.h
diff --git a/sound/soc/codecs/ymu831/mcdefs.h b/sound/soc/codecs/ymu831/mcdefs.h new file mode 100644 index 0000000..fbd2008 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdefs.h @@ -0,0 +1,4303 @@ +/****************************************************************************
- Copyrightc 2012 Yamaha Corporation. All rights reserved.
- Module : mcdefs.h
- Description : MC device definitions
- Version : 1.0.1 Dec 18 2012
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
So you need to keep zlib license instead of the standard GPLv2?
The base codes license is zlib license. It is not so easy to change.
Yoichi
At Thu, 17 Jan 2013 14:59:37 +0900, Yoichi Yuasa wrote:
On Wed, 16 Jan 2013 12:45:56 +0100 Takashi Iwai tiwai@suse.de wrote:
At Wed, 16 Jan 2013 17:27:04 +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/mcdefs.h | 4303 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 4303 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mcdefs.h
diff --git a/sound/soc/codecs/ymu831/mcdefs.h b/sound/soc/codecs/ymu831/mcdefs.h new file mode 100644 index 0000000..fbd2008 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdefs.h @@ -0,0 +1,4303 @@ +/****************************************************************************
- Copyrightc 2012 Yamaha Corporation. All rights reserved.
- Module : mcdefs.h
- Description : MC device definitions
- Version : 1.0.1 Dec 18 2012
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
So you need to keep zlib license instead of the standard GPLv2?
The base codes license is zlib license. It is not so easy to change.
Then it's another good reason to rewrite the driver from scratch.
The code with zlib license in kernel is taken from zlib itself. Keeping it as is had merit from maintenance POV, as well.
But in your case, 99% of the whole code would have to be either rewritten or strip as a binary blob. Why sticking with it at all?
As Mark already suggested, consider to start writing from scratch. Then you'll get much more maintainable driver code.
thanks,
Takashi
On Thu, 17 Jan 2013 07:45:40 +0100 Takashi Iwai tiwai@suse.de wrote:
At Thu, 17 Jan 2013 14:59:37 +0900, Yoichi Yuasa wrote:
On Wed, 16 Jan 2013 12:45:56 +0100 Takashi Iwai tiwai@suse.de wrote:
At Wed, 16 Jan 2013 17:27:04 +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/mcdefs.h | 4303 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 4303 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mcdefs.h
diff --git a/sound/soc/codecs/ymu831/mcdefs.h b/sound/soc/codecs/ymu831/mcdefs.h new file mode 100644 index 0000000..fbd2008 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdefs.h @@ -0,0 +1,4303 @@ +/****************************************************************************
- Copyrightc 2012 Yamaha Corporation. All rights reserved.
- Module : mcdefs.h
- Description : MC device definitions
- Version : 1.0.1 Dec 18 2012
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
So you need to keep zlib license instead of the standard GPLv2?
The base codes license is zlib license. It is not so easy to change.
Then it's another good reason to rewrite the driver from scratch.
The code with zlib license in kernel is taken from zlib itself. Keeping it as is had merit from maintenance POV, as well.
But in your case, 99% of the whole code would have to be either rewritten or strip as a binary blob. Why sticking with it at all?
As Mark already suggested, consider to start writing from scratch. Then you'll get much more maintainable driver code.
I don't have the sufficient information for rewriting the driver. I'll try to get more information.
Thanks,
Yoichi
Yoichi
On Wed, Jan 16, 2013 at 05:27:04PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
Please follow the patch submission process in SubmittingPatches.
- Module : mcdefs.h
- Description : MC device definitions
- Version : 1.0.1 Dec 18 2012
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
It's not entirely clear to me that this is GPL compatible...
+#define MCI_A_REG_A 0 +#define MCB_A_REG_AINC 0x80
All these definitions need to be namespaced.
On Wed, 16 Jan 2013 13:18:09 +0000 Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Wed, Jan 16, 2013 at 05:27:04PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
Please follow the patch submission process in SubmittingPatches.
- Module : mcdefs.h
- Description : MC device definitions
- Version : 1.0.1 Dec 18 2012
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
It's not entirely clear to me that this is GPL compatible...
Some file of kernel lib/zlib_deflate and lib/zlib_inflate are same license.
also see:
http://www.gnu.org/licenses/license-list.en.html#ZLib
+#define MCI_A_REG_A 0 +#define MCB_A_REG_AINC 0x80
All these definitions need to be namespaced.
How should these change concretely?
Thanks,
Yoichi
On Thu, Jan 17, 2013 at 03:00:06PM +0900, Yoichi Yuasa wrote:
Mark Brown broonie@opensource.wolfsonmicro.com wrote:
+#define MCI_A_REG_A 0 +#define MCB_A_REG_AINC 0x80
All these definitions need to be namespaced.
How should these change concretely?
Put a prefix in front of them.
On Thu, 17 Jan 2013 15:02:48 +0900 Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Thu, Jan 17, 2013 at 03:00:06PM +0900, Yoichi Yuasa wrote:
Mark Brown broonie@opensource.wolfsonmicro.com wrote:
+#define MCI_A_REG_A 0 +#define MCB_A_REG_AINC 0x80
All these definitions need to be namespaced.
How should these change concretely?
Put a prefix in front of them.
OK, I'll update them.
Thanks,
Yoichi
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 1 + sound/soc/codecs/ymu831/mcbdspdrv.c | 1193 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcbdspdrv.h | 43 ++ 3 files changed, 1237 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mcbdspdrv.c create mode 100644 sound/soc/codecs/ymu831/mcbdspdrv.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index 5b3f66d..e74a60f 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -1,3 +1,4 @@ snd-soc-ymu831-objs := \ + mcbdspdrv.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcbdspdrv.c b/sound/soc/codecs/ymu831/mcbdspdrv.c new file mode 100644 index 0000000..c43604c --- /dev/null +++ b/sound/soc/codecs/ymu831/mcbdspdrv.c @@ -0,0 +1,1193 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcbdspdrv.c + * Description : MC B-DSP driver + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/types.h> + +#include <asm/byteorder.h> + +#include "mcbdspdrv.h" +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcresctrl.h" + +#define BDSP_STATUS_IDLE 0 +#define BDSP_STATUS_INITIALIZED 1 + +#define DATA_SIZE 8 + +#define AEC_BDSP_TAG_FWCTRL_B 0x00000c00 +#define FWCTRL_B_SIZE 14 +#define AEC_BDSP_TAG_APP_COEF 0x00000700 +#define APP_COEF_FIX_SIZE 9 +#define AEC_BDSP_TAG_APP_REG 0x00000a00 +#define APP_REG_FIX_SIZE 8 +#define AEC_BDSP_TAG_APP_MASK 0xffffff00 +#define AEC_BDSP_TAG_APPNO_MASK 0x000000ff + +#define FWCTRL_B_BYPASS 0 +#define FWCTRL_B_AE0_BYP 1 +#define FWCTRL_B_AE1_BYP 2 +#define FWCTRL_B_WIDE 3 +#define FWCTRL_B_HEX 4 +#define FWCTRL_B_EQ3_0A 5 +#define FWCTRL_B_DRC3 6 +#define FWCTRL_B_DRC_0 7 +#define FWCTRL_B_EQ3_0B 8 +#define FWCTRL_B_GEN 9 +#define FWCTRL_B_EQ3_1A 10 +#define FWCTRL_B_AGC 11 +#define FWCTRL_B_DRC_1 12 +#define FWCTRL_B_EQ3_1B 13 + +#define APP_NO_GEN 0 +#define APP_NO_SWAP_0 1 +#define APP_NO_WIDE 2 +#define APP_NO_HEX 3 +#define APP_NO_EQ3_0A 4 +#define APP_NO_DRC3 5 +#define APP_NO_DRC_0 6 +#define APP_NO_EQ3_0B 7 +#define APP_NO_MIX_0 8 +#define APP_NO_SWAP_1 9 +#define APP_NO_EQ3_1A 10 +#define APP_NO_AGC 11 +#define APP_NO_DRC_1 12 +#define APP_NO_EQ3_1B 13 +#define APP_NO_MIX_1 14 +#define APP_NO_LAST APP_NO_MIX_1 + +#define APP_COEF_ADR 0 +#define APP_COEF_SIZE 5 +#define APP_COEF_DATA 9 + +#define APP_REG_FLG 0 +#define APP_REG_FLG_FWCTL0 0x01 +#define APP_REG_FLG_FWCTL1 0x02 +#define APP_REG_FLG_FWCTL2 0x04 +#define APP_REG_FLG_FWCTL3 0x08 +#define APP_REG_FLG_FWCTL4 0x10 +#define APP_REG_FLG_FWCTL5 0x20 +#define APP_REG_FLG_FWCTL6 0x40 +#define APP_REG_FWCTL0 1 +#define APP_REG_FWCTL1 2 +#define APP_REG_FWCTL2 3 +#define APP_REG_FWCTL3 4 +#define APP_REG_FWCTL4 5 +#define APP_REG_FWCTL5 6 +#define APP_REG_FWCTL6 7 + +#define COEF_DMA_TRANS 0 +#define COEF_DSP_TRANS 1 +#define COEF_DSP_TRANS_MAX 40 + +#define TARGET_NONE 0x00000000 +#define TARGET_AE0_MASK 0x00003f00 +#define TARGET_AE0_EQ3_0B 0x00002000 +#define TARGET_AE0_DRC_0 0x00001000 +#define TARGET_AE0_DRC3 0x00000800 +#define TARGET_AE0_EQ3_0A 0x00000400 +#define TARGET_AE0_HEX 0x00000200 +#define TARGET_AE0_WIDE 0x00000100 +#define TARGET_AE1_MASK 0x0000003c +#define TARGET_AE1_EQ3_1B 0x00000020 +#define TARGET_AE1_DRC_1 0x00000010 +#define TARGET_AE1_AGC 0x00000008 +#define TARGET_AE1_EQ3_1A 0x00000004 +#define TARGET_GEN_MASK 0x00008000 +#define TARGET_GEN_GEN 0x00008000 +#define TARGET_BASE_MASK 0xf0000000 +#define TARGET_BASE_SWAP_0 0x10000000 +#define TARGET_BASE_SWAP_1 0x20000000 +#define TARGET_BASE_MIX_0 0x40000000 +#define TARGET_BASE_MIX_1 0x80000000 + +#define REG_APP_NO_STOP 0 +#define REG_APP_STOP 1 + +#define MULTI_DATA_APP_COEF 1 +#define MULTI_DATA_APP_REG 2 + +#define RAM_UNIT_SIZE_32 4UL +#define RAM_UNIT_SIZE_64 8UL +#define DXRAM_RANGE_MIN 0x0UL +#define DXRAM_RANGE_MAX 0x017fUL +#define DYRAM_RANGE_MIN 0x0UL +#define DYRAM_RANGE_MAX 0x01ffUL + +#define NO_WAIT 0x00 +#define CROSS_FADE_WAIT 0x01 +#define SIN_OUT_WAIT 0x02 + +#define BDSP_PATH_NORMAL 0 +#define BDSP_PATH_BYPASS 1 +#define BDSP_PATH_DONTCARE 2 + +#define BDSP_BYPASS_FADE_TIME 10 /* msec */ + +#define BDSP_SIN_CTRL_REG 0 +#define BDSP_SIN_CTRL_GPIO 1 + +#define GEN_SIN_CTL_SEL_ADD 0x001d9 + +#define BDSP_APP_EXEC_STOP 0 +#define BDSP_APP_EXEC_START 1 + +#define BDSP_OFF 0 +#define BDSP_ON 1 + +#define BDSP_PRC_FADE_AE0 0x01 +#define BDSP_PRC_FADE_AE1 0x02 +#define BDSP_PRC_SINOUT 0x04 +#define BDSP_PRC_COEF_TRS 0x08 + +#define BDSP_AE_FW_DXRAM 1 +#define BDSP_AE_FW_DYRAM 2 + +struct aec_bdsp_info { + u8 on; + u8 *data; + u32 data_size; + u8 *fwctrl_b; + u8 ae0_app_onoff; + u8 ae1_app_onoff; + u8 app_gen; + u32 app_coef_count; + u8 coef_trans; + u32 coef_target; + u8 sin_ctrl_sel; + u32 app_reg_count; + u32 app_stop_target; + u8 stopped_app_exec0; + u8 stopped_app_exec1; + u8 stopped_sin_out; + u8 stopped_bypass; +}; + +struct bdsp_info { + u32 status; + u8 dsp_bypass; + u8 sin_ctrl_sel; + u8 dsp_ctrl; + u8 app_exec0; + u8 app_exec1; + u8 aebypass; +}; + +static struct bdsp_info mc_bdsp_info = { + .status = BDSP_STATUS_IDLE, +}; + +static void bdsp_get_data(struct mcdrv_aec_info *aec, + struct aec_bdsp_info *bdsp) +{ + bdsp->on = BDSP_OFF; + bdsp->data = NULL; + bdsp->data_size = 0; + + if (aec->audio_engine.enable) { + bdsp->on = aec->audio_engine.on; + if (bdsp->on == BDSP_OFF) + return; + + bdsp->data = aec->audio_engine.bdsp.data; + bdsp->data_size = aec->audio_engine.bdsp.data_size; + } + + if (bdsp->data) + bdsp->data = &bdsp->data[DATA_SIZE]; +} + +static u8 bdsp_app_exec(u8 onoff, u8 app, u8 exec) +{ + switch (onoff) { + case BDSP_APP_EXEC_STOP: + if ((app & exec) == 0) + app = 0x00; + break; + case BDSP_APP_EXEC_START: + if ((app & exec) != 0) + app = 0x00; + break; + default: + app = 0x00; + break; + } + + return app; +} + +static inline void bdsp_app_check(struct aec_bdsp_info *bdsp) +{ + u8 *data; + u8 onoff, exec; + + data = bdsp->fwctrl_b; + + onoff = bdsp->ae0_app_onoff; + exec = mc_bdsp_info.app_exec0; + + onoff |= bdsp_app_exec(data[FWCTRL_B_WIDE], MCB_AEEXEC0_WIDE, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_HEX], MCB_AEEXEC0_HEX, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_EQ3_0A], MCB_AEEXEC0_EQ3_0A, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_DRC3], MCB_AEEXEC0_DRC3, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_DRC_0], MCB_AEEXEC0_DRC_0, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_EQ3_0B], MCB_AEEXEC0_EQ3_0B, exec); + + bdsp->ae0_app_onoff = onoff; + + onoff = bdsp->ae1_app_onoff; + exec = mc_bdsp_info.app_exec1; + + onoff |= bdsp_app_exec(data[FWCTRL_B_EQ3_1A], MCB_AEEXEC1_EQ3_1A, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_AGC], MCB_AEEXEC1_AGC, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_DRC_1], MCB_AEEXEC1_DRC_1, exec); + onoff |= bdsp_app_exec(data[FWCTRL_B_EQ3_1B], MCB_AEEXEC1_EQ3_1B, exec); + + bdsp->ae1_app_onoff = onoff; + + if ((data[FWCTRL_B_GEN] == BDSP_APP_EXEC_STOP) && + (mc_bdsp_info.app_exec0 & MCB_AEEXEC0_GEN) != 0) + bdsp->app_gen |= MCB_AEEXEC0_GEN; +} + +static u32 bdsp_app_to_target(u32 app_no) +{ + switch (app_no) { + case APP_NO_GEN: + return TARGET_GEN_GEN; + case APP_NO_SWAP_0: + return TARGET_BASE_SWAP_0; + case APP_NO_WIDE: + return TARGET_AE0_WIDE; + case APP_NO_HEX: + return TARGET_AE0_HEX; + case APP_NO_EQ3_0A: + return TARGET_AE0_EQ3_0A; + case APP_NO_DRC3: + return TARGET_AE0_DRC3; + case APP_NO_DRC_0: + return TARGET_AE0_DRC_0; + case APP_NO_EQ3_0B: + return TARGET_AE0_EQ3_0B; + case APP_NO_MIX_0: + return TARGET_BASE_MIX_0; + case APP_NO_SWAP_1: + return TARGET_BASE_SWAP_1; + case APP_NO_EQ3_1A: + return TARGET_AE1_EQ3_1A; + case APP_NO_AGC: + return TARGET_AE1_AGC; + case APP_NO_DRC_1: + return TARGET_AE1_DRC_1; + case APP_NO_EQ3_1B: + return TARGET_AE1_EQ3_1B; + case APP_NO_MIX_1: + return TARGET_BASE_MIX_1; + default: + break; + } + + return TARGET_NONE; +} + +static void bdsp_check_sin_control_sel(struct aec_bdsp_info *bdsp, u8 *data) +{ + u32 addr; + u32 size; + + addr = htonl(*(u32 *) data); + size = htonl(*(u32 *) (data + 5)); + data = &data[9]; + + if (addr > GEN_SIN_CTL_SEL_ADD) + return; + + if ((addr + (size / 4)) < GEN_SIN_CTL_SEL_ADD) + return; + + addr = GEN_SIN_CTL_SEL_ADD - addr; + + if ((data[(addr * 4) + 3] & BDSP_SIN_CTRL_GPIO) != 0) + bdsp->sin_ctrl_sel = BDSP_SIN_CTRL_GPIO; + else + bdsp->sin_ctrl_sel = BDSP_SIN_CTRL_REG; +} + +static int bdsp_app_data_analyze(struct aec_bdsp_info *bdsp, + u32 id, u32 size, u32 top, u8 *data) +{ + u32 tag, target; + u32 val; + + tag = id & AEC_BDSP_TAG_APP_MASK; + if ((tag != AEC_BDSP_TAG_APP_COEF) && (tag != AEC_BDSP_TAG_APP_REG)) + return 0; + + target = bdsp_app_to_target(id & AEC_BDSP_TAG_APPNO_MASK); + + if (tag == AEC_BDSP_TAG_APP_COEF) { + if (size < APP_COEF_FIX_SIZE) + return -EINVAL; + + val = htonl(*(u32 *) (data + top + 5)); + if (!val) + return 0; + + if (val & 0x03) + return -EINVAL; + + if (size < (val + APP_COEF_FIX_SIZE)) + return -EINVAL; + + bdsp->app_coef_count++; + + if ((data[top + 4] != COEF_DSP_TRANS) || + (val > COEF_DSP_TRANS_MAX) || (bdsp->app_coef_count > 1)) + bdsp->coef_trans = COEF_DMA_TRANS; + + bdsp->coef_target |= target; + + if (target == TARGET_GEN_GEN) + bdsp_check_sin_control_sel(bdsp, &data[top]); + } else { + if (size < APP_REG_FIX_SIZE) + return -EINVAL; + + if (target != TARGET_GEN_GEN) + return 0; + + bdsp->app_reg_count++; + + if (data[top + APP_REG_FLG] & APP_REG_FLG_FWCTL4) + bdsp->app_stop_target |= TARGET_GEN_GEN; + } + + return 0; +} + +static int bdsp_data_analyze(struct aec_bdsp_info *bdsp) +{ + u32 top, id, size; + u8 *data; + u32 data_size; + + bdsp->fwctrl_b = NULL; + bdsp->app_coef_count = 0UL; + bdsp->coef_trans = COEF_DSP_TRANS; + bdsp->ae0_app_onoff = 0; + bdsp->ae1_app_onoff = 0; + bdsp->app_gen = 0; + bdsp->coef_target = TARGET_NONE; + bdsp->sin_ctrl_sel = mc_bdsp_info.sin_ctrl_sel; + bdsp->app_reg_count = 0UL; + bdsp->app_stop_target = TARGET_NONE; + bdsp->stopped_app_exec0 = 0; + bdsp->stopped_app_exec1 = 0; + bdsp->stopped_sin_out = 0; + bdsp->stopped_bypass = 0; + + if (!bdsp->data || !bdsp->data_size) + return 0; + + data = bdsp->data; + data_size = bdsp->data_size; + top = 0; + while (top < data_size) { + if (data_size < (top + DATA_SIZE)) + return -EINVAL; + + id = htonl(*(u32 *) (data + top)); + size = htonl(*(u32 *) (data + top + 4)); + if (data_size < (top + DATA_SIZE + size)) + return -EINVAL; + + top += DATA_SIZE; + switch (id) { + case AEC_BDSP_TAG_FWCTRL_B: + if (size < FWCTRL_B_SIZE) + return -EINVAL; + if (bdsp->fwctrl_b != NULL) + return -EINVAL; + + bdsp->fwctrl_b = &data[top]; + + bdsp_app_check(bdsp); + break; + default: + if (bdsp_app_data_analyze(bdsp, id, size, top, data)) + return -EINVAL; + } + + top += size; + } + + return 0; +} + +static inline int bdsp_trans_wait(void) +{ + mc_packet_add_wait_event(MCDRV_EVT_IF_REG_FLAG_RESET | + (MCI_BDSPTREQ << 8) | MCB_BDSPTREQ); + + return mc_packet_execute(); +} + +static inline int bdsp_cross_fade_wait(void) +{ + msleep(BDSP_BYPASS_FADE_TIME); + + mc_packet_add_wait_event(MCDRV_EVT_B_REG_FLAG_RESET | + (MCI_AEFADE << 8) | MCB_AEFADE_AE1 | + MCB_AEFADE_AE0); + + return mc_packet_execute(); +} + +static inline int bdsp_sin_out_wait(void) +{ + mc_packet_add_wait_event(MCDRV_EVT_B_REG_FLAG_RESET | + (MCI_SINOUTFLG << 8) | MCB_SINOFLG); + + return mc_packet_execute(); +} + +static inline u32 bdsp_path_bypass(struct aec_bdsp_info *bdsp) +{ + u8 bypass, stopped = 0; + u32 wait = NO_WAIT; + + bypass = mc_bdsp_info.aebypass; + + if (bdsp->ae0_app_onoff) { + bypass |= MCB_AEBYPASS_AE0; + stopped |= MCB_AEBYPASS_AE0; + } + + if (bdsp->ae1_app_onoff) { + bypass |= MCB_AEBYPASS_AE1; + stopped |= MCB_AEBYPASS_AE1; + } + + if (bdsp->coef_trans == COEF_DMA_TRANS) { + if (bdsp->coef_target & TARGET_AE0_MASK) { + bypass |= MCB_AEBYPASS_AE0; + stopped |= MCB_AEBYPASS_AE0; + } + + if (bdsp->coef_target & TARGET_AE1_MASK) { + bypass |= MCB_AEBYPASS_AE1; + stopped |= MCB_AEBYPASS_AE1; + } + } + + if (bypass != mc_bdsp_info.aebypass) { + mc_packet_add_write_b(MCI_AEBYPASS, bypass); + mc_packet_execute(); + + wait = CROSS_FADE_WAIT; + bdsp->stopped_bypass = stopped; + mc_bdsp_info.aebypass = bypass; + } + + return wait; +} + +static inline u32 bdsp_sin_stop(struct aec_bdsp_info *bdsp) +{ + u8 data; + u32 wait = NO_WAIT; + + if (mc_bdsp_info.sin_ctrl_sel == BDSP_SIN_CTRL_GPIO) + return NO_WAIT; + + if (!(mc_bdsp_info.app_exec0 & MCB_AEEXEC0_GEN)) + return NO_WAIT; + + if ((bdsp->app_gen || (bdsp->app_stop_target & TARGET_GEN_MASK)) || + ((bdsp->coef_trans == COEF_DMA_TRANS) && + (bdsp->coef_target & TARGET_GEN_MASK))) { + wait = SIN_OUT_WAIT; + + mc_read_b(MCI_SINOUT, &data, 1); + if (data & MCB_SINOUT) { + mc_packet_add_write_b(MCI_SINOUT, MCI_SINOUT_DEF); + mc_packet_execute(); + + bdsp->stopped_sin_out = MCB_SINOUT; + } + } + + return wait; +} + +static inline void bdsp_app_stop(struct aec_bdsp_info *bdsp) +{ + u8 app_exec0, app_exec1; + u8 stopped_app_exec0 = 0, stopped_app_exec1 = 0; + + app_exec0 = mc_bdsp_info.app_exec0; + app_exec1 = mc_bdsp_info.app_exec1; + + if (bdsp->coef_trans == COEF_DMA_TRANS) { + if ((bdsp->coef_target & TARGET_AE0_EQ3_0B) && + (app_exec0 & MCB_AEEXEC0_EQ3_0B)) { + app_exec0 &= ~MCB_AEEXEC0_EQ3_0B; + stopped_app_exec0 |= MCB_AEEXEC0_EQ3_0B; + } + if ((bdsp->coef_target & TARGET_AE0_DRC_0) && + (app_exec0 & MCB_AEEXEC0_DRC_0)) { + app_exec0 &= ~MCB_AEEXEC0_DRC_0; + stopped_app_exec0 |= MCB_AEEXEC0_DRC_0; + } + if ((bdsp->coef_target & TARGET_AE0_DRC3) && + (app_exec0 & MCB_AEEXEC0_DRC3)) { + app_exec0 &= ~MCB_AEEXEC0_DRC3; + stopped_app_exec0 |= MCB_AEEXEC0_DRC3; + } + if ((bdsp->coef_target & TARGET_AE0_EQ3_0A) && + (app_exec0 & MCB_AEEXEC0_EQ3_0A)) { + app_exec0 &= ~MCB_AEEXEC0_EQ3_0A; + stopped_app_exec0 |= MCB_AEEXEC0_EQ3_0A; + } + if ((bdsp->coef_target & TARGET_AE0_HEX) && + (app_exec0 & MCB_AEEXEC0_HEX)) { + app_exec0 &= ~MCB_AEEXEC0_HEX; + stopped_app_exec0 |= MCB_AEEXEC0_HEX; + } + if ((bdsp->coef_target & TARGET_AE0_WIDE) && + (app_exec0 & MCB_AEEXEC0_WIDE)) { + app_exec0 &= ~MCB_AEEXEC0_WIDE; + stopped_app_exec0 |= MCB_AEEXEC0_WIDE; + } + + if ((bdsp->coef_target & TARGET_AE1_EQ3_1B) && + (app_exec1 & MCB_AEEXEC1_EQ3_1B)) { + app_exec1 &= ~MCB_AEEXEC1_EQ3_1B; + stopped_app_exec1 |= MCB_AEEXEC1_EQ3_1B; + } + if ((bdsp->coef_target & TARGET_AE1_DRC_1) && + (app_exec1 & MCB_AEEXEC1_DRC_1)) { + app_exec1 &= ~MCB_AEEXEC1_DRC_1; + stopped_app_exec1 |= MCB_AEEXEC1_DRC_1; + } + if ((bdsp->coef_target & TARGET_AE1_AGC) && + (app_exec1 & MCB_AEEXEC1_AGC)) { + app_exec1 &= ~MCB_AEEXEC1_AGC; + stopped_app_exec1 |= MCB_AEEXEC1_AGC; + } + if ((bdsp->coef_target & TARGET_AE1_EQ3_1A) && + (app_exec1 & MCB_AEEXEC1_EQ3_1A)) { + app_exec1 &= ~MCB_AEEXEC1_EQ3_1A; + stopped_app_exec1 |= MCB_AEEXEC1_EQ3_1A; + } + + if ((bdsp->coef_target & TARGET_GEN_GEN) && + (app_exec0 & MCB_AEEXEC0_GEN)) { + app_exec0 &= ~MCB_AEEXEC0_GEN; + stopped_app_exec0 |= MCB_AEEXEC0_GEN; + } + } + + if ((bdsp->app_stop_target & TARGET_GEN_GEN) && + (app_exec0 & MCB_AEEXEC0_GEN)) { + app_exec0 &= ~MCB_AEEXEC0_GEN; + stopped_app_exec0 |= MCB_AEEXEC0_GEN; + } + + mc_packet_add_write_b(MCI_AEEXEC0, app_exec0); + + mc_packet_add_write_b(MCI_AEEXEC1, app_exec1); + + bdsp->stopped_app_exec0 = stopped_app_exec0; + bdsp->stopped_app_exec1 = stopped_app_exec1; + + mc_bdsp_info.app_exec0 = app_exec0; + mc_bdsp_info.app_exec1 = app_exec1; +} + +static int bdsp_stop_all(struct aec_bdsp_info *bdsp) +{ + int ret; + u32 wait = NO_WAIT; + + ret = bdsp_trans_wait(); + if (ret < 0) + return ret; + + wait |= bdsp_path_bypass(bdsp); + wait |= bdsp_sin_stop(bdsp); + if (wait & CROSS_FADE_WAIT) { + ret = bdsp_cross_fade_wait(); + if (ret < 0) + return ret; + } + if (wait & SIN_OUT_WAIT) { + ret = bdsp_sin_out_wait(); + if (ret < 0) + return ret; + } + + bdsp_app_stop(bdsp); + + return 0; +} + +static void bdsp_app_coef_download(u8 *app_coef, u8 coef_trans) +{ + u32 size; + int i; + + mc_packet_add_force_write_if(MCI_BMAA0, + app_coef[APP_COEF_ADR + 1] & MCB_BMAA0); + mc_packet_add_force_write_if(MCI_BMAA1, + app_coef[APP_COEF_ADR + 2] & MCB_BMAA1); + mc_packet_add_force_write_if(MCI_BMAA2, + app_coef[APP_COEF_ADR + 3] & MCB_BMAA2); + + if (coef_trans == COEF_DSP_TRANS) + mc_packet_add_force_write_if(MCI_BMACTL, + MCB_BDSPTINI | MCB_BMAMOD_DSP | + MCB_BMABUS_Y); + else + mc_packet_add_force_write_if(MCI_BMACTL, MCB_BMABUS_Y); + + mc_packet_execute(); + + size = htonl(*(u32 *) (app_coef + APP_COEF_SIZE)); + for (i = 0; i < size; i++) + mc_packet_add_force_write_if(MCI_BMAD, + app_coef[APP_COEF_DATA + i]); + + mc_packet_execute(); +} + +static inline void bdsp_app_reg_download(struct aec_bdsp_info *bdsp, + u32 target, u8 *reg) +{ + if (target != TARGET_GEN_GEN) + return; + + if (reg[APP_REG_FLG] & APP_REG_FLG_FWCTL4) + mc_packet_add_force_write_b(MCI_F01SEL, reg[APP_REG_FWCTL4]); + + if (reg[APP_REG_FLG] & APP_REG_FLG_FWCTL5) { + mc_packet_add_force_write_b(MCI_SINOUT, reg[APP_REG_FWCTL5]); + if (!(reg[APP_REG_FWCTL5] & MCB_SINOUT)) + bdsp->stopped_sin_out = 0; + } + + mc_packet_execute(); +} + +static void bdsp_multi_data_download(struct aec_bdsp_info *bdsp, u32 target) +{ + u32 top, id, size; + u32 app_no; + u8 *data; + u32 data_size; + + data = bdsp->data; + data_size = bdsp->data_size; + + top = 0; + while (top < data_size) { + id = htonl(*(u32 *) (data + top)); + size = htonl(*(u32 *) (data + top + 4)); + + top += DATA_SIZE; + app_no = id & AEC_BDSP_TAG_APPNO_MASK; + + switch (id & AEC_BDSP_TAG_APP_MASK) { + case AEC_BDSP_TAG_APP_COEF: + if (target != MULTI_DATA_APP_COEF) + break; + + if (app_no <= APP_NO_LAST) + bdsp_app_coef_download(&data[top], + bdsp->coef_trans); + + if (app_no == APP_NO_GEN) + mc_bdsp_info.sin_ctrl_sel = bdsp->sin_ctrl_sel; + break; + case AEC_BDSP_TAG_APP_REG: + if (target == MULTI_DATA_APP_REG) + bdsp_app_reg_download(bdsp, + bdsp_app_to_target + (app_no), &data[top]); + break; + default: + break; + } + + top += size; + } +} + +static inline void bdsp_download(struct aec_bdsp_info *bdsp) +{ + if (bdsp->app_coef_count) { + bdsp_multi_data_download(bdsp, MULTI_DATA_APP_COEF); + + if (bdsp->coef_trans == COEF_DSP_TRANS) { + mc_packet_add_force_write_if(MCI_BDSPTREQ, + MCB_BDSPTREQ); + mc_packet_execute(); + } + } + + if (bdsp->app_reg_count) + bdsp_multi_data_download(bdsp, MULTI_DATA_APP_REG); +} + +static u8 bdsp_app_create_exec(u8 onoff, u8 app, u8 exec) +{ + switch (onoff) { + case BDSP_APP_EXEC_STOP: + exec &= ~app; + break; + case BDSP_APP_EXEC_START: + exec |= app; + break; + default: + break; + } + + return exec; +} + +static inline void bdsp_app_new(struct aec_bdsp_info *bdsp) +{ + u8 app_exec0; + u8 app_exec1; + u8 *data; + + data = bdsp->fwctrl_b; + + app_exec0 = mc_bdsp_info.app_exec0; + app_exec1 = mc_bdsp_info.app_exec1; + + app_exec0 |= bdsp->stopped_app_exec0; + app_exec1 |= bdsp->stopped_app_exec1; + + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_WIDE], + MCB_AEEXEC0_WIDE, app_exec0); + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_HEX], + MCB_AEEXEC0_HEX, app_exec0); + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_EQ3_0A], + MCB_AEEXEC0_EQ3_0A, app_exec0); + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_DRC3], + MCB_AEEXEC0_DRC3, app_exec0); + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_DRC_0], + MCB_AEEXEC0_DRC_0, app_exec0); + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_EQ3_0B], + MCB_AEEXEC0_EQ3_0B, app_exec0); + + app_exec0 = bdsp_app_create_exec(data[FWCTRL_B_GEN], + MCB_AEEXEC0_GEN, app_exec0); + + app_exec1 = bdsp_app_create_exec(data[FWCTRL_B_EQ3_1A], + MCB_AEEXEC1_EQ3_1A, app_exec1); + app_exec1 = bdsp_app_create_exec(data[FWCTRL_B_AGC], + MCB_AEEXEC1_AGC, app_exec1); + app_exec1 = bdsp_app_create_exec(data[FWCTRL_B_DRC_1], + MCB_AEEXEC1_DRC_1, app_exec1); + app_exec1 = bdsp_app_create_exec(data[FWCTRL_B_EQ3_1B], + MCB_AEEXEC1_EQ3_1B, app_exec1); + + mc_packet_add_write_b(MCI_AEEXEC0, app_exec0); + + mc_packet_add_write_b(MCI_AEEXEC1, app_exec1); + + mc_packet_execute(); + + mc_bdsp_info.app_exec0 = app_exec0; + mc_bdsp_info.app_exec1 = app_exec1; +} + +static inline void bdsp_sin_start(struct aec_bdsp_info *bdsp) +{ + if (bdsp->stopped_sin_out == MCB_SINOUT) { + mc_packet_add_write_b(MCI_SINOUT, MCB_SINOUT); + mc_packet_execute(); + } +} + +static inline void bdsp_path_new(struct aec_bdsp_info *bdsp) +{ + u8 aebypass; + u8 *data; + + data = bdsp->fwctrl_b; + if (!data) + return; + + aebypass = mc_bdsp_info.aebypass; + + switch (data[FWCTRL_B_AE0_BYP]) { + case BDSP_PATH_NORMAL: + aebypass &= ~MCB_AEBYPASS_AE0; + break; + case BDSP_PATH_BYPASS: + aebypass |= MCB_AEBYPASS_AE0; + break; + default: + break; + } + + switch (data[FWCTRL_B_AE1_BYP]) { + case BDSP_PATH_NORMAL: + aebypass &= ~MCB_AEBYPASS_AE1; + break; + case BDSP_PATH_BYPASS: + aebypass |= MCB_AEBYPASS_AE1; + break; + default: + break; + } + + mc_packet_add_write_b(MCI_AEBYPASS, aebypass); + + mc_packet_execute(); + + mc_bdsp_info.aebypass = aebypass; +} + +static inline void bdsp_path_set_audio_if(struct aec_bdsp_info *bdsp) +{ + u8 dsp_ctrl; + + switch (bdsp->fwctrl_b[FWCTRL_B_BYPASS]) { + case BDSP_PATH_NORMAL: + case BDSP_PATH_BYPASS: + mc_bdsp_info.dsp_bypass = + ((bdsp->fwctrl_b[FWCTRL_B_BYPASS] << 7) & MCB_BDSPBYPASS); + break; + default: + break; + }; + + dsp_ctrl = mc_bdsp_info.dsp_ctrl; + switch (mc_bdsp_info.dsp_bypass & MCB_BDSPBYPASS) { + case MCB_BDSPBYPASS: + if (dsp_ctrl & MCB_BDSPSTART) + dsp_ctrl = MCB_BDSPBYPASS; + break; + default: + if (dsp_ctrl & MCB_BDSPBYPASS) + dsp_ctrl = MCB_BDSPSTART; + break; + } + + mc_packet_add_write_b(MCI_BDSPCTRL, dsp_ctrl); + + mc_packet_execute(); + + mc_bdsp_info.dsp_ctrl = dsp_ctrl; +} + +static inline void bdsp_app_resume(struct aec_bdsp_info *bdsp) +{ + u8 app_exec0; + u8 app_exec1; + + app_exec0 = mc_bdsp_info.app_exec0; + app_exec1 = mc_bdsp_info.app_exec1; + + app_exec0 |= bdsp->stopped_app_exec0; + app_exec1 |= bdsp->stopped_app_exec1; + + mc_packet_add_write_b(MCI_AEEXEC0, app_exec0); + + mc_packet_add_write_b(MCI_AEEXEC1, app_exec1); + + mc_packet_execute(); + + mc_bdsp_info.app_exec0 = app_exec0; + mc_bdsp_info.app_exec1 = app_exec1; +} + +static void bdsp_path_resume(struct aec_bdsp_info *bdsp) +{ + u8 aebypass; + + aebypass = mc_bdsp_info.aebypass; + aebypass &= ~bdsp->stopped_bypass; + + mc_packet_add_write_b(MCI_AEBYPASS, aebypass); + + mc_packet_execute(); + + mc_bdsp_info.aebypass = aebypass; +} + +static inline void bdsp_restart(struct aec_bdsp_info *bdsp) +{ + if (bdsp->fwctrl_b) { + bdsp_app_new(bdsp); + bdsp_sin_start(bdsp); + bdsp_path_new(bdsp); + bdsp_path_set_audio_if(bdsp); + } else { + bdsp_app_resume(bdsp); + bdsp_sin_start(bdsp); + bdsp_path_resume(bdsp); + } +} + +static inline int bdsp_audio_engine_set(struct aec_bdsp_info *bdsp) +{ + int ret; + + if (!(mc_bdsp_info.dsp_ctrl & MCB_BDSPSTART)) { + bdsp->ae0_app_onoff = 0; + bdsp->ae1_app_onoff = 0; + bdsp->app_gen = 0; + bdsp->coef_target = TARGET_NONE; + bdsp->coef_trans = COEF_DMA_TRANS; + bdsp->app_stop_target = TARGET_NONE; + } + + ret = bdsp_stop_all(bdsp); + if (ret < 0) + return ret; + + bdsp_download(bdsp); + + bdsp_restart(bdsp); + + return 0; +} + +static void bdsp_upload(u8 addr0, u32 address, u8 bma_ctrl, + u32 size, u32 unit_size, u8 *data) +{ + u8 addr1, addr2; + int i; + + addr1 = (address >> 8) & MCB_BMAA1; + addr2 = address & MCB_BMAA2; + + mc_packet_add_force_write_if(MCI_BMAA0, addr0); + mc_packet_add_force_write_if(MCI_BMAA1, addr1); + mc_packet_add_force_write_if(MCI_BMAA2, addr2); + + mc_packet_add_force_write_if(MCI_BMACTL, bma_ctrl); + + mc_packet_execute(); + + for (i = 0; i < size; i++) { + mc_read_digital(MCI_BMAD, &data[(i * unit_size) + 0], 1); + mc_read_digital(MCI_BMAD, &data[(i * unit_size) + 1], 1); + mc_read_digital(MCI_BMAD, &data[(i * unit_size) + 2], 1); + mc_read_digital(MCI_BMAD, &data[(i * unit_size) + 3], 1); + } + + mc_packet_add_force_write_if(MCI_BMAA0, MCI_BMAA0_DEF); + mc_packet_execute(); +} + +int mc_bdsp_init(void) +{ + static u8 fader_coef[17] = { + 0x00, 0x00, 0x00, 0x00, /* address */ + 0x00, + 0x00, 0x00, 0x00, 0x08, /* size 8 (4 * 2) */ + 0xF8, 0x44, 0x41, 0x78, /* CFADE_0 10ms */ + 0xF8, 0x44, 0x41, 0x78 /* CFADE_1 10ms */ + }; + + if (mc_bdsp_info.status != BDSP_STATUS_IDLE) + return -EBUSY; + + mc_bdsp_info.dsp_bypass = MCB_BDSPBYPASS; + mc_bdsp_info.sin_ctrl_sel = BDSP_SIN_CTRL_REG; + + mc_bdsp_info.dsp_ctrl = MCI_BDSPCTRL_DEF; + mc_bdsp_info.app_exec0 = MCI_AEEXEC0_DEF; + mc_bdsp_info.app_exec1 = MCI_AEEXEC1_DEF; + mc_bdsp_info.aebypass = MCI_AEBYPASS_DEF; + + mc_packet_add_write_b(MCI_BDSPCTRL, mc_bdsp_info.dsp_ctrl); + + mc_packet_add_write_b(MCI_AEEXEC0, mc_bdsp_info.app_exec0); + mc_packet_add_write_b(MCI_AEEXEC1, mc_bdsp_info.app_exec1); + + mc_packet_add_write_b(MCI_AEBYPASS, mc_bdsp_info.aebypass); + + mc_packet_add_write_b(MCI_AEFADE, MCI_AEFADE_DEF); + + mc_packet_add_write_b(MCI_F01SEL, MCI_F01SEL_DEF); + + mc_packet_add_write_b(MCI_SINOUT, MCI_SINOUT_DEF); + + mc_packet_execute(); + + mc_bdsp_info.status = BDSP_STATUS_INITIALIZED; + + bdsp_app_coef_download(fader_coef, COEF_DMA_TRANS); + + return 0; +} + +int mc_bdsp_term(void) +{ + if (mc_bdsp_info.status == BDSP_STATUS_IDLE) + return 0; + + mc_packet_add_force_write_b(MCI_BDSPCTRL, MCI_BDSPCTRL_DEF); + + mc_packet_execute(); + + mc_bdsp_info.status = BDSP_STATUS_IDLE; + + return 0; +} + +int mc_bdsp_get_dsp(u32 target, u32 address, u8 *data, u32 size) +{ + u8 bma_ctrl; + u32 unit_size = 0; + + if (!data) + return -EINVAL; + + bma_ctrl = MCB_BMADIR_UL; + + switch (target) { + case BDSP_AE_FW_DXRAM: + if (address > DXRAM_RANGE_MAX) + return -EINVAL; + + unit_size = RAM_UNIT_SIZE_64; + size = size / unit_size; + + if (size > DXRAM_RANGE_MAX + 1) + size = DXRAM_RANGE_MAX + 1; + + if (address + size > DXRAM_RANGE_MAX + 1) + size -= (address + size - (DXRAM_RANGE_MAX + 1)); + + bma_ctrl |= MCB_BMABUS_X; + break; + case BDSP_AE_FW_DYRAM: + if (address > DYRAM_RANGE_MAX) + return -EINVAL; + + unit_size = RAM_UNIT_SIZE_32; + size = size / unit_size; + + if (size > DYRAM_RANGE_MAX + 1) + size = DYRAM_RANGE_MAX + 1; + + if (address + size > DYRAM_RANGE_MAX + 1) + size -= (address + size - (DYRAM_RANGE_MAX + 1)); + + bma_ctrl |= MCB_BMABUS_Y; + break; + default: + return -EINVAL; + } + + if (!size) + return 0; + + if (mc_bdsp_info.status == BDSP_STATUS_IDLE) + return 0; + + if (target == BDSP_AE_FW_DXRAM) { + bdsp_upload(MCB_BMAA0, address, bma_ctrl, size, unit_size, + data); + + bdsp_upload(MCI_BMAA0_DEF, address, bma_ctrl, size, + unit_size, &data[4]); + } else + bdsp_upload(MCI_BMAA0_DEF, address, bma_ctrl, size, + unit_size, data); + + return size * unit_size; +} + +int mc_bdsp_set_dsp(struct mcdrv_aec_info *aec) +{ + struct aec_bdsp_info bdsp; + int ret; + + if (!aec) + return -EINVAL; + + bdsp_get_data(aec, &bdsp); + + ret = bdsp_data_analyze(&bdsp); + if (ret < 0) + return ret; + + if (!bdsp.data || !bdsp.data_size) + return 0; + + if (mc_bdsp_info.status == BDSP_STATUS_IDLE) + return -EBUSY; + + return bdsp_audio_engine_set(&bdsp); +} + +int mc_bdsp_start(void) +{ + if (mc_bdsp_info.status == BDSP_STATUS_IDLE) + return -EBUSY; + + if (mc_bdsp_info.dsp_bypass & MCB_BDSPBYPASS) + mc_bdsp_info.dsp_ctrl = MCB_BDSPBYPASS; + else + mc_bdsp_info.dsp_ctrl = MCB_BDSPSTART; + + mc_packet_add_write_b(MCI_BDSPCTRL, mc_bdsp_info.dsp_ctrl); + + mc_packet_execute(); + + return 0; +} + +int mc_bdsp_stop(void) +{ + if (mc_bdsp_info.status == BDSP_STATUS_IDLE) + return 0; + + mc_packet_add_write_if(MCI_BDSPTREQ, MCI_BDSPTREQ_DEF); + + mc_bdsp_info.dsp_ctrl = MCI_BDSPCTRL_DEF; + mc_packet_add_write_b(MCI_BDSPCTRL, MCI_BDSPCTRL_DEF); + + mc_packet_execute(); + + return 0; +} diff --git a/sound/soc/codecs/ymu831/mcbdspdrv.h b/sound/soc/codecs/ymu831/mcbdspdrv.h new file mode 100644 index 0000000..78971a8 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcbdspdrv.h @@ -0,0 +1,43 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcbdspdrv.h + * Description : MC B-DSP driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _MCBDSPDRV_H +#define _MCBDSPDRV_H + +#include "mcresctrl.h" + +int mc_bdsp_init(void); +int mc_bdsp_term(void); +int mc_bdsp_set_dsp(struct mcdrv_aec_info *aec); +int mc_bdsp_start(void); +int mc_bdsp_stop(void); + +#endif /* _MCBDSPDRV_H */
At Wed, 16 Jan 2013 17:28:32 +0900, Yoichi Yuasa wrote:
+static void bdsp_check_sin_control_sel(struct aec_bdsp_info *bdsp, u8 *data) +{
- u32 addr;
- u32 size;
- addr = htonl(*(u32 *) data);
- size = htonl(*(u32 *) (data + 5));
It's an unaligned access. And normally we use cpu_to_xxx() or xxx_to_cpu() macros for endian conversions.
Takashi
On Wed, 16 Jan 2013 12:49:37 +0100 Takashi Iwai tiwai@suse.de wrote:
At Wed, 16 Jan 2013 17:28:32 +0900, Yoichi Yuasa wrote:
+static void bdsp_check_sin_control_sel(struct aec_bdsp_info *bdsp, u8 *data) +{
- u32 addr;
- u32 size;
- addr = htonl(*(u32 *) data);
- size = htonl(*(u32 *) (data + 5));
It's an unaligned access.
The size is unaligned. I'll add a comment.
And normally we use cpu_to_xxx() or xxx_to_cpu() macros for endian conversions.
I'll update them.
Thank you for your comment.
Yoichi
On Wed, Jan 16, 2013 at 05:28:32PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/Makefile | 1 + sound/soc/codecs/ymu831/mcbdspdrv.c | 1193 +++++++++++++++++++++++++++++++++++
Why the subdirectory? Also this file is over 1000 lines of code with basically no comments or relationship with standard kernel code. This is a substandial barrier to review; at the very least it would be helpful to split this up into multiple patches, one per algorithm for example.
+/*
- changelog:
- change in the Linux coding style
- remove unnecessary comments
- remove unused codes
- */
No changelogs in kernel code.
On Wed, 16 Jan 2013 13:22:45 +0000 Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Wed, Jan 16, 2013 at 05:28:32PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/Makefile | 1 + sound/soc/codecs/ymu831/mcbdspdrv.c | 1193 +++++++++++++++++++++++++++++++++++
Why the subdirectory?
ymu831 driver has 27 files. It is the reason that I made the subdirectory. Is it better to put them on sound/soc/codes ?
Also this file is over 1000 lines of code with basically no comments or relationship with standard kernel code. This is a substandial barrier to review; at the very least it would be helpful to split this up into multiple patches, one per algorithm for example.
OK, I'll split it.
+/*
- changelog:
- change in the Linux coding style
- remove unnecessary comments
- remove unused codes
- */
No changelogs in kernel code.
OK, I'll remove them.
Thank you for your comments.
Yoichi
On Thu, Jan 17, 2013 at 02:59:12PM +0900, Yoichi Yuasa wrote:
Mark Brown broonie@opensource.wolfsonmicro.com wrote:
Why the subdirectory?
ymu831 driver has 27 files. It is the reason that I made the subdirectory. Is it better to put them on sound/soc/codes ?
It would be better to rewrite the driver to be a standard Linux driver using the standard Linux frameworks - looking at the code this seems very likely to substantially reduce the amount of code involved.
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/mccdspos.h | 3436 ++++++++++++++++++++++++++++++++++++ 1 file changed, 3436 insertions(+) create mode 100644 sound/soc/codecs/ymu831/mccdspos.h
diff --git a/sound/soc/codecs/ymu831/mccdspos.h b/sound/soc/codecs/ymu831/mccdspos.h new file mode 100644 index 0000000..31a2e72 --- /dev/null +++ b/sound/soc/codecs/ymu831/mccdspos.h @@ -0,0 +1,3436 @@ +/**************************************************************************** + * + * Copyright (c) 2012 Yamaha Corporation + * + * Module : mccdspos.h + * Description : MC C-DSP operating system + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change the array name + */ +#ifndef _MCCDSPOS_H +#define _MCCDSPOS_H + +static const unsigned char mc_cdsp_os[] = { + 0xe3, 0x33, /* program size */ + 0x2c, 0x01, /* data size */ + /* program */ + 0x2d, 0x61, 0xaa, 0xae, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf3, 0xaf, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xa7, 0xae, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x20, 0x83, 0x2d, 0x93, 0xb4, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x21, 0x83, 0x2d, 0x93, 0xbc, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x26, 0x83, 0x2d, 0x93, 0xa4, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x27, 0x83, 0x2d, 0x93, 0xac, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x24, 0x83, 0x2d, 0x93, 0x54, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x25, 0x83, 0x2d, 0x93, 0x5c, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x2a, 0x83, 0x2d, 0x93, 0x44, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x2b, 0x83, 0x2d, 0x93, 0x4c, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x28, 0x83, 0x2d, 0x93, 0x74, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x29, 0x83, 0x2d, 0x93, 0x7c, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x2e, 0x83, 0x2d, 0x93, 0x64, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x2f, 0x83, 0x2d, 0x93, 0x6c, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x2c, 0x83, 0x2d, 0x93, 0x14, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xf1, 0xc9, 0x2d, 0x83, 0x2d, 0x93, 0x1c, 0xac, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xd2, 0x82, 0x22, 0x92, 0x7d, 0x8a, 0x25, 0x9a, + 0x01, 0x8b, 0x2c, 0x9b, 0x68, 0x28, 0x2b, 0xee, + 0x62, 0x0e, 0x79, 0x14, 0xcd, 0x08, 0xc8, 0xc7, + 0xd2, 0xe0, 0x53, 0x83, 0x2e, 0x93, 0x20, 0x15, + 0xd0, 0x03, 0xd2, 0xa1, 0xdd, 0x15, 0xad, 0x16, + 0xcd, 0x15, 0xad, 0x02, 0xac, 0x03, 0xad, 0x01, + 0xd2, 0xee, 0xac, 0x02, 0xad, 0x02, 0x3d, 0x17, + 0xcd, 0x15, 0xdc, 0x15, 0xad, 0x02, 0xac, 0x03, + 0xad, 0x01, 0xd2, 0xee, 0xac, 0x02, 0xad, 0x02, + 0xf3, 0x8e, 0x2c, 0x9e, 0xdf, 0x15, 0xce, 0x15, + 0xba, 0xbe, 0xd9, 0x15, 0xc8, 0x15, 0x2d, 0x61, + 0xb8, 0xbe, 0xdb, 0x15, 0xca, 0x15, 0x2d, 0x61, + 0xbe, 0xbe, 0xd5, 0x15, 0xc4, 0x15, 0x2d, 0x61, + 0xbc, 0xbe, 0xd7, 0x15, 0xc6, 0x15, 0x2d, 0x61, + 0xa2, 0xbe, 0xd1, 0x15, 0xc0, 0x15, 0x2d, 0x61, + 0xa0, 0xbe, 0xd3, 0x15, 0xc2, 0x15, 0x2d, 0x61, + 0xa6, 0xbe, 0x2f, 0x16, 0x3c, 0x16, 0xdf, 0x15, + 0xcc, 0x15, 0x2d, 0x61, 0xa5, 0xbe, 0xcf, 0x16, + 0xdf, 0x15, 0x2d, 0x61, 0xab, 0xbe, 0x0f, 0x16, + 0xbc, 0x16, 0xdf, 0x15, 0xcc, 0x15, 0x2d, 0x61, + 0xae, 0xbe, 0x1f, 0x16, 0x6c, 0x16, 0xdf, 0x15, + 0xcc, 0x15, 0x2d, 0x61, 0xad, 0xbe, 0x7f, 0x16, + 0x4c, 0x16, 0xdf, 0x15, 0xcc, 0x15, 0x2d, 0x61, + 0x50, 0xbe, 0xbf, 0x17, 0x8c, 0x17, 0xdf, 0x15, + 0xcc, 0x15, 0x2d, 0x61, 0x57, 0xbe, 0x5f, 0x16, + 0xec, 0x16, 0xdf, 0x15, 0xcc, 0x15, 0x2d, 0x61, + 0x5a, 0xbe, 0xdf, 0x16, 0x0c, 0x17, 0xdf, 0x15, + 0xcc, 0x15, 0x2d, 0x61, 0x59, 0xbe, 0x1f, 0x17, + 0x6c, 0x17, 0xdf, 0x15, 0xcc, 0x15, 0x2d, 0x61, + 0x5c, 0xbe, 0x7f, 0x17, 0x4c, 0x17, 0xdf, 0x15, + 0xcc, 0x15, 0x2d, 0x61, 0x43, 0xbe, 0x5f, 0x17, + 0xac, 0x17, 0xdf, 0x15, 0xcc, 0x15, 0x2d, 0x61, + 0x46, 0xbe, 0xc8, 0x17, 0x38, 0x12, 0x71, 0x0d, + 0x7d, 0x0f, 0x1e, 0xee, 0x79, 0x0f, 0x20, 0xee, + 0x25, 0x83, 0x2d, 0x93, 0x70, 0x2f, 0x38, 0xee, + 0x27, 0x83, 0x2d, 0x93, 0x70, 0x2f, 0x32, 0xee, + 0x00, 0xae, 0x2d, 0x61, 0x4f, 0xbe, 0xc3, 0xa1, + 0xd5, 0x17, 0x7c, 0x12, 0x22, 0x9d, 0xd2, 0x8d, + 0x7e, 0x26, 0x05, 0xd7, 0xdf, 0x15, 0x72, 0x0e, + 0xd8, 0xee, 0x2d, 0x61, 0x71, 0xbe, 0xd7, 0xa1, + 0xd5, 0x17, 0x7c, 0x12, 0x22, 0x9c, 0xd2, 0x8c, + 0x7f, 0x26, 0x2d, 0x61, 0x75, 0xbe, 0xde, 0x17, + 0x15, 0xc7, 0x72, 0x0e, 0xca, 0xee, 0x2d, 0x61, + 0x78, 0xbe, 0xd7, 0xa1, 0x7c, 0x12, 0x2d, 0x9c, + 0x32, 0x8c, 0x7f, 0x26, 0x22, 0x8c, 0x7f, 0x2f, + 0xf0, 0xef, 0xdf, 0x17, 0xdf, 0x14, 0xf7, 0xa1, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0xd1, 0xa1, 0xd2, 0x17, 0x61, 0xbe, 0xd3, 0x17, + 0x66, 0xbe, 0xd0, 0x17, 0x67, 0xbe, 0xd1, 0x17, + 0x64, 0xbe, 0xd6, 0x17, 0x65, 0xbe, 0xd7, 0x17, + 0x6a, 0xbe, 0xd4, 0x17, 0x6b, 0xbe, 0xd5, 0x17, + 0x68, 0xbe, 0xda, 0x17, 0x69, 0xbe, 0xdb, 0x17, + 0x6e, 0xbe, 0xd8, 0x17, 0x6f, 0xbe, 0xd9, 0x17, + 0x6c, 0xbe, 0xde, 0x17, 0x6d, 0xbe, 0xdf, 0x17, + 0x12, 0xbe, 0xdc, 0x17, 0x13, 0xbe, 0xdd, 0x17, + 0x2d, 0x14, 0x2d, 0x61, 0x11, 0xbe, 0xdd, 0x17, + 0x3d, 0x14, 0x2d, 0x61, 0x17, 0xbe, 0xdd, 0x17, + 0xcd, 0x14, 0x2d, 0x61, 0x15, 0xbe, 0xdd, 0x17, + 0x0d, 0x14, 0x2d, 0x61, 0x1b, 0xbe, 0xdd, 0x17, + 0x1d, 0x14, 0x2d, 0x61, 0x19, 0xbe, 0xdd, 0x17, + 0x6d, 0x14, 0x2d, 0x61, 0x1f, 0xbe, 0xdd, 0x17, + 0x7d, 0x14, 0x2d, 0x61, 0x1d, 0xbe, 0xdd, 0x17, + 0x4d, 0x14, 0x2d, 0x61, 0x03, 0xbe, 0xdd, 0x17, + 0xbd, 0x15, 0x2d, 0x61, 0x01, 0xbe, 0xdd, 0x17, + 0x8d, 0x15, 0x2d, 0x61, 0x07, 0xbe, 0xdd, 0x17, + 0x5d, 0x14, 0x2d, 0x61, 0x05, 0xbe, 0xdd, 0x17, + 0xed, 0x14, 0x2d, 0x61, 0x0b, 0xbe, 0xdd, 0x17, + 0xdd, 0x14, 0x2d, 0x61, 0x09, 0xbe, 0xdd, 0x17, + 0x0d, 0x15, 0x2d, 0x61, 0x0f, 0xbe, 0xdd, 0x17, + 0x1d, 0x15, 0x2d, 0x61, 0x0d, 0xbe, 0xdd, 0x17, + 0x6d, 0x15, 0x2d, 0x61, 0x33, 0xbe, 0xdd, 0x17, + 0x7d, 0x15, 0x2d, 0x61, 0x31, 0xbe, 0xdd, 0x17, + 0x4d, 0x15, 0x2d, 0x61, 0x37, 0xbe, 0x2d, 0x61, + 0x34, 0xbe, 0x2d, 0x61, 0x35, 0xbe, 0xdd, 0x17, + 0x3d, 0x15, 0xad, 0x02, 0xac, 0x03, 0xad, 0x01, + 0xd2, 0xee, 0xac, 0x02, 0xad, 0x02, 0xd4, 0x00, + 0xcd, 0x17, 0x2d, 0x06, 0x2c, 0x06, 0xad, 0x14, + 0xdd, 0x17, 0x0d, 0xae, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2f, 0x11, 0xad, 0x02, 0xac, 0x03, + 0xad, 0x01, 0xd2, 0xee, 0xac, 0x02, 0xad, 0x02, + 0x2c, 0x11, 0xe2, 0x61, 0xb0, 0x03, 0x2f, 0x11, + 0x7d, 0x0f, 0x3e, 0xee, 0x2d, 0x98, 0x74, 0x88, + 0x49, 0xce, 0x2d, 0x98, 0x6c, 0x88, 0x49, 0xce, + 0x2d, 0x98, 0x60, 0x88, 0x49, 0xce, 0x2d, 0x98, + 0x6c, 0x88, 0x49, 0xce, 0x2d, 0x98, 0x65, 0x88, + 0x49, 0xce, 0x2d, 0x98, 0x6c, 0x88, 0x49, 0xce, + 0x2c, 0x11, 0x2d, 0x61, 0x21, 0xc5, 0x01, 0xc5, + 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, 0xc1, 0xc5, + 0x5c, 0x16, 0x3d, 0x17, 0x21, 0xc5, 0xd2, 0x8a, + 0xd2, 0x9a, 0x79, 0xde, 0x71, 0xc1, 0x2d, 0x61, + 0xc3, 0xb1, 0x69, 0x8c, 0x25, 0x9c, 0x2f, 0xde, + 0x2d, 0x9f, 0x2a, 0x8f, 0xed, 0xc2, 0x35, 0x8c, + 0x2f, 0x9c, 0x25, 0x8f, 0x0d, 0xc2, 0x01, 0xae, + 0xf1, 0x12, 0xfc, 0x0e, 0x20, 0xd7, 0xd2, 0x8f, + 0xd2, 0x9f, 0x2c, 0xce, 0x20, 0xd6, 0x3d, 0x15, + 0x5c, 0x14, 0xc0, 0xd6, 0x80, 0xd6, 0xa0, 0xd6, + 0x50, 0xd7, 0x00, 0xd6, 0x20, 0xd6, 0xf2, 0x0e, + 0xe0, 0x12, 0x69, 0x8a, 0x25, 0x9a, 0x69, 0xde, + 0x2d, 0x9b, 0x29, 0x8b, 0x49, 0xd2, 0x4f, 0x05, + 0x25, 0xee, 0x28, 0x8b, 0x49, 0xd2, 0x4d, 0x0f, + 0x29, 0xee, 0x13, 0x83, 0x28, 0x93, 0x20, 0x15, + 0x2c, 0x11, 0x2d, 0x61, 0x0c, 0x8e, 0x25, 0x9e, + 0x3d, 0x08, 0x3d, 0xce, 0xd2, 0x8a, 0xd2, 0x9a, + 0x79, 0xde, 0x2d, 0x61, 0xfe, 0xb1, 0x69, 0x8e, + 0x25, 0x9e, 0x0f, 0x8f, 0x25, 0x9f, 0x0c, 0xde, + 0x0d, 0xce, 0x0d, 0x0f, 0x27, 0xee, 0x95, 0x8f, + 0x2e, 0x9f, 0x3d, 0x09, 0x1d, 0x08, 0x2a, 0x8d, + 0xef, 0xd2, 0x25, 0x8d, 0xff, 0xd2, 0x20, 0x15, + 0xd2, 0x82, 0x22, 0x92, 0x0c, 0x8f, 0x25, 0x9f, + 0x0c, 0x08, 0x0c, 0xce, 0x95, 0x8f, 0x2e, 0x9f, + 0x3d, 0x09, 0x4f, 0x8f, 0x2f, 0x9f, 0x02, 0x03, + 0x0c, 0x15, 0xd3, 0x03, 0x2c, 0xae, 0x24, 0xae, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, 0x2d, 0x61, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x6b, 0x8c, 0x25, 0x9c, 0x1f, 0xde, + 0x1d, 0x0f, 0xcc, 0xee, 0x1d, 0x08, 0x1f, 0xce, + 0x0c, 0x8f, 0x25, 0x9f, 0x1c, 0xce, 0xe9, 0xa1, + 0xf1, 0xd7, 0x61, 0xd7, 0x39, 0x15, 0x61, 0xde, + 0x02, 0x03, 0x20, 0x15, 0x6b, 0x8f, 0x25, 0x9f, + 0x0d, 0x08, 0x0c, 0xce, 0x68, 0x8e, 0x25, 0x9e, + 0x3d, 0xde, 0x3d, 0x0f, 0x39, 0xee, 0x69, 0x8e, + 0x25, 0x9e, 0x3d, 0xde, 0x0f, 0x8c, 0x25, 0x9c, + 0x1f, 0xde, 0x3e, 0x2f, 0x21, 0xee, 0x69, 0x8c, + 0x25, 0x9c, 0x2f, 0xde, 0x2d, 0x9f, 0x2a, 0x8f, + 0xed, 0xc2, 0x8f, 0x8d, 0x2f, 0x9d, 0x25, 0x8f, + 0x1d, 0xc2, 0x8f, 0xa1, 0x69, 0x8a, 0x25, 0x9a, + 0x69, 0xde, 0x2d, 0x9b, 0x29, 0x8b, 0x49, 0xd2, + 0x4f, 0x05, 0x5d, 0xee, 0x28, 0x8b, 0x49, 0xd2, + 0x4d, 0x0f, 0x41, 0xee, 0x13, 0x83, 0x28, 0x93, + 0xfd, 0x09, 0x70, 0xae, 0x2c, 0x11, 0x2c, 0x11, + 0x01, 0xca, 0x2f, 0x16, 0x21, 0xc8, 0x31, 0xcb, + 0x2d, 0x7e, 0x2d, 0x76, 0xad, 0x16, 0xcc, 0x16, + 0xe7, 0x0e, 0x11, 0xcf, 0x1e, 0x24, 0xce, 0x14, + 0x01, 0xc1, 0x0e, 0x16, 0x21, 0xc5, 0x61, 0xc5, + 0x3d, 0x17, 0x0c, 0x17, 0x21, 0xc5, 0x1f, 0x16, + 0x01, 0xc5, 0x7d, 0x17, 0x4c, 0x17, 0xc1, 0xc5, + 0x81, 0xc5, 0x1f, 0x17, 0x6e, 0x17, 0xa1, 0xc5, + 0x41, 0xc5, 0x86, 0x17, 0xb7, 0x17, 0x21, 0xc5, + 0x01, 0xc5, 0x4e, 0x16, 0x7f, 0x16, 0x81, 0xc5, + 0x01, 0xc5, 0xec, 0x16, 0x5d, 0x16, 0x21, 0xc5, + 0xdf, 0x16, 0x01, 0xc1, 0xdf, 0x02, 0xde, 0x02, + 0x0c, 0x8f, 0x25, 0x9f, 0x2c, 0xde, 0x2d, 0x0f, + 0x26, 0xea, 0xd2, 0x8a, 0xd2, 0x9a, 0x79, 0xde, + 0x71, 0xc1, 0x2d, 0x61, 0x52, 0xb1, 0xd2, 0x8c, + 0x22, 0x9c, 0xef, 0xc1, 0xef, 0x12, 0x2c, 0x0e, + 0x2c, 0xce, 0x2c, 0x08, 0x20, 0x2c, 0x21, 0xc1, + 0x2d, 0x25, 0x0c, 0x16, 0x3d, 0x26, 0x32, 0x07, + 0x0c, 0x14, 0x3e, 0x8e, 0x25, 0x9e, 0x30, 0x12, + 0xfd, 0xd2, 0xfd, 0x09, 0x02, 0x02, 0x21, 0xdf, + 0xec, 0x0e, 0x0c, 0x16, 0x3d, 0x27, 0x32, 0x06, + 0x0c, 0x14, 0x0c, 0x8f, 0x25, 0x9f, 0x2c, 0xde, + 0x22, 0x0e, 0x2c, 0xce, 0x2d, 0x0f, 0x2e, 0xea, + 0xf1, 0xdf, 0xe0, 0x12, 0x0c, 0x8f, 0x25, 0x9f, + 0x2c, 0xde, 0x2d, 0x0f, 0x2a, 0xef, 0x6b, 0x8f, + 0x25, 0x9f, 0x2c, 0xde, 0x2d, 0x0f, 0x2f, 0xee, + 0x43, 0xa1, 0x21, 0x8e, 0x2d, 0x9e, 0x0c, 0x8f, + 0x25, 0x9f, 0x0c, 0xde, 0x0d, 0x0f, 0x2a, 0xea, + 0xec, 0x0e, 0x41, 0xd6, 0xd2, 0x8f, 0xd2, 0x9f, + 0x4c, 0xce, 0x2f, 0xae, 0x41, 0xd6, 0xa1, 0xd6, + 0x5d, 0x26, 0x7d, 0x25, 0xdd, 0x16, 0x81, 0xd6, + 0x55, 0x14, 0x28, 0x26, 0xc1, 0xd6, 0xe4, 0x14, + 0x5d, 0x27, 0x01, 0xd6, 0xda, 0x14, 0x61, 0xd6, + 0x41, 0xd6, 0xa1, 0xd6, 0x77, 0x14, 0x46, 0x14, + 0x81, 0xd6, 0xb3, 0x15, 0x82, 0x15, 0xc1, 0xd6, + 0x21, 0xd6, 0x79, 0x15, 0x2d, 0x8a, 0xdd, 0x9a, + 0x48, 0x15, 0x1f, 0x15, 0x6e, 0x15, 0x29, 0x26, + 0x79, 0x25, 0x1f, 0x16, 0x0e, 0x16, 0x08, 0x26, + 0xed, 0x9a, 0x79, 0x25, 0x39, 0x26, 0x0d, 0x27, + 0x18, 0x26, 0x1c, 0x27, 0x21, 0xd6, 0x12, 0x06, + 0x1f, 0x14, 0x0e, 0x14, 0x61, 0xd6, 0x3d, 0x15, + 0x0c, 0x15, 0x21, 0xd6, 0x01, 0xd6, 0xe9, 0x0e, + 0xad, 0x14, 0xcc, 0x14, 0x2f, 0x14, 0x01, 0xda, + 0x31, 0xdb, 0x21, 0xd8, 0xf1, 0xd9, 0x2f, 0x11, + 0x39, 0x17, 0x61, 0xc0, 0x09, 0x16, 0x6d, 0x0f, + 0x2f, 0xec, 0x02, 0x02, 0x3f, 0x8b, 0xe1, 0x83, + 0x25, 0x9b, 0x1e, 0x93, 0x6d, 0x08, 0x68, 0xce, + 0xfd, 0x09, 0x7d, 0x08, 0x71, 0xcf, 0x71, 0xdf, + 0x7d, 0x0f, 0x2e, 0xee, 0x71, 0xdf, 0x7d, 0x09, + 0xed, 0x83, 0x2e, 0x93, 0x08, 0xbe, 0x99, 0x83, + 0x2e, 0x93, 0xfd, 0x09, 0x61, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x39, 0x17, 0x93, 0x83, + 0x2e, 0x93, 0x61, 0xc1, 0x33, 0xbe, 0xb3, 0x83, + 0x2e, 0x93, 0xfd, 0x09, 0xb1, 0x83, 0x2e, 0x93, + 0x27, 0xbe, 0x7d, 0x83, 0x2b, 0x93, 0xfd, 0x09, + 0x97, 0x83, 0x1e, 0x93, 0xfd, 0x09, 0xfb, 0x83, + 0x1e, 0x93, 0xfd, 0x09, 0x3f, 0x8b, 0x17, 0x83, + 0x25, 0x9b, 0x2f, 0x93, 0x6c, 0x08, 0x68, 0xce, + 0x7c, 0xb1, 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, + 0x2c, 0x11, 0xe2, 0x61, 0xda, 0x03, 0x21, 0x8a, + 0x00, 0x03, 0xd5, 0x9a, 0x79, 0xde, 0x73, 0x05, + 0x25, 0xee, 0xdf, 0x8b, 0x2d, 0x9b, 0x79, 0xca, + 0x2d, 0x8b, 0x6d, 0x9b, 0x79, 0xce, 0xd2, 0x03, + 0xd4, 0x8b, 0xaa, 0x9b, 0x79, 0xce, 0x39, 0x8a, + 0x7c, 0x08, 0x79, 0xce, 0x2c, 0x11, 0x2d, 0x61, + 0x2c, 0x11, 0x2d, 0x61, 0x2c, 0x11, 0x2d, 0x61, + 0x21, 0x8b, 0xd5, 0x9b, 0x68, 0xde, 0x68, 0xce, + 0x2c, 0x11, 0xe2, 0x61, 0x2c, 0x11, 0x2d, 0x61, + 0x2c, 0x11, 0x2d, 0x61, 0x20, 0x88, 0x2d, 0x98, + 0x49, 0x2f, 0x29, 0xe6, 0xc2, 0x8a, 0xd2, 0x9a, + 0x25, 0xae, 0x08, 0x16, 0x2c, 0x88, 0x49, 0x2c, + 0x6b, 0x25, 0x79, 0x26, 0x08, 0x14, 0x6d, 0x08, + 0x2c, 0x11, 0x2d, 0x61, 0x20, 0x88, 0x2d, 0x98, + 0x49, 0x2f, 0x29, 0xe6, 0xc2, 0x8a, 0xd2, 0x9a, + 0x2a, 0xae, 0x08, 0x16, 0x2c, 0x88, 0x49, 0x2c, + 0x7b, 0x27, 0x6d, 0x08, 0x08, 0x14, 0x2c, 0x11, + 0x22, 0x7b, 0x0f, 0x8b, 0x51, 0xc1, 0x2d, 0x73, + 0x25, 0x9b, 0xa1, 0xc5, 0x39, 0x17, 0x61, 0xc1, + 0x6d, 0x08, 0x68, 0xce, 0x69, 0x8b, 0x25, 0x9b, + 0x68, 0xce, 0x6b, 0x8b, 0x25, 0x9b, 0x68, 0xce, + 0x2c, 0x8a, 0x68, 0x8b, 0x25, 0x9b, 0x68, 0xce, + 0x09, 0x8a, 0x25, 0x9a, 0x69, 0xce, 0x69, 0xcf, + 0x6f, 0x0e, 0xd0, 0xe0, 0x6d, 0x08, 0x0e, 0x8b, + 0x25, 0x9b, 0x68, 0xce, 0xa5, 0x8a, 0x2d, 0x9a, + 0xb9, 0xde, 0xbd, 0x0f, 0x25, 0xef, 0x61, 0xdf, + 0xa1, 0xdc, 0xb1, 0xdd, 0xee, 0x0e, 0x51, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0xf4, 0x86, 0xb2, 0x0e, + 0x2d, 0x96, 0x75, 0xd7, 0xe9, 0x83, 0x72, 0x0e, + 0x29, 0x93, 0x68, 0x12, 0x6e, 0x0c, 0x49, 0x12, + 0x48, 0x2e, 0x49, 0x0e, 0xa4, 0x8b, 0x2d, 0x9b, + 0x68, 0x2e, 0xa5, 0x8b, 0x2a, 0x9b, 0x48, 0x2e, + 0x7b, 0xde, 0x41, 0x0e, 0x7d, 0x06, 0x6b, 0xcc, + 0x6b, 0x12, 0x49, 0x0e, 0x59, 0x12, 0x7b, 0xce, + 0x7d, 0xbe, 0x6a, 0xdc, 0x69, 0xde, 0x6c, 0x05, + 0x28, 0xee, 0xf9, 0x83, 0x6a, 0x12, 0x29, 0x93, + 0x79, 0xbe, 0xb2, 0x0e, 0xf8, 0xed, 0xf3, 0xa1, + 0x0e, 0x8a, 0x22, 0x83, 0x25, 0x9a, 0x2d, 0x93, + 0x69, 0xde, 0x6d, 0x0f, 0x2f, 0xef, 0xd2, 0x03, + 0xd2, 0x8b, 0x4d, 0x08, 0x2d, 0x9b, 0x79, 0x26, + 0x2f, 0xee, 0x29, 0xae, 0x25, 0x88, 0x65, 0x0d, + 0x2d, 0x98, 0x70, 0x12, 0x79, 0x26, 0x28, 0xef, + 0x79, 0x12, 0x49, 0x0e, 0x79, 0x0d, 0x70, 0x26, + 0xd2, 0x8a, 0xd2, 0x9a, 0x79, 0x2e, 0x68, 0xde, + 0x49, 0x2e, 0x4c, 0x0c, 0x09, 0x8a, 0x25, 0x9a, + 0x49, 0x2e, 0x6b, 0xde, 0x2c, 0x11, 0xe2, 0x61, + 0x2d, 0x88, 0x51, 0xc1, 0xd2, 0x98, 0xa1, 0xc5, + 0x79, 0xdd, 0x09, 0x86, 0x25, 0x96, 0x58, 0x12, + 0x7b, 0x26, 0x55, 0x0d, 0x7d, 0x07, 0x4a, 0x12, + 0x4c, 0x0c, 0x79, 0xcd, 0x45, 0x2e, 0x7c, 0x08, + 0x7a, 0x2c, 0x0e, 0x86, 0x25, 0x96, 0xb5, 0xde, + 0x74, 0x27, 0xbb, 0xdf, 0xb9, 0xcf, 0x49, 0xce, + 0x75, 0xce, 0x7b, 0xdf, 0x6b, 0xcf, 0x0f, 0x88, + 0x68, 0xce, 0x25, 0x98, 0x7b, 0xde, 0x7d, 0x0f, + 0x2a, 0xee, 0x78, 0xdd, 0x75, 0x0d, 0x58, 0x2f, + 0x2e, 0xe7, 0x6d, 0x08, 0x28, 0xae, 0x6b, 0xce, + 0x68, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0xa1, 0xdf, + 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, 0x2c, 0x11, + 0x38, 0x17, 0x51, 0xc1, 0xa1, 0xc5, 0x71, 0xc1, + 0x79, 0xdf, 0x49, 0xdd, 0x59, 0xde, 0x45, 0x0d, + 0xbb, 0x12, 0x58, 0xce, 0x59, 0xde, 0xbc, 0x0c, + 0x7a, 0xcf, 0x09, 0x8b, 0x0f, 0x89, 0x25, 0x9b, + 0x25, 0x99, 0xb8, 0x2e, 0xa4, 0xde, 0xb5, 0x2f, + 0x31, 0xef, 0x74, 0xdf, 0xb8, 0x2f, 0x2f, 0xee, + 0xd2, 0x03, 0x0e, 0x86, 0x7c, 0x08, 0x7b, 0x2c, + 0x25, 0x96, 0x4a, 0xde, 0x78, 0x25, 0xb5, 0xde, + 0x74, 0x26, 0x49, 0x2f, 0x75, 0xce, 0x38, 0xef, + 0x7d, 0x0f, 0x6d, 0x08, 0x2f, 0xef, 0x29, 0xae, + 0x1d, 0x83, 0x29, 0x93, 0xec, 0xb1, 0x6a, 0xce, + 0x68, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x27, 0xae, + 0x7a, 0xde, 0x79, 0x2f, 0x2b, 0xef, 0x68, 0x8a, + 0xaa, 0xce, 0x25, 0x9a, 0x69, 0xde, 0x2f, 0xae, + 0x6d, 0x08, 0x71, 0xdf, 0xa1, 0xdc, 0xb1, 0xdd, + 0xee, 0x0e, 0x51, 0xdf, 0xec, 0x0e, 0x28, 0x15, + 0x69, 0x0e, 0x74, 0x08, 0x49, 0xde, 0x61, 0x0e, + 0x48, 0x26, 0x79, 0xdc, 0x78, 0xdd, 0x69, 0x0e, + 0x75, 0x0c, 0x49, 0xc7, 0x4d, 0x08, 0x49, 0xce, + 0x66, 0x0e, 0x79, 0xcd, 0x2c, 0x11, 0xe2, 0x61, + 0x38, 0x17, 0x51, 0xc1, 0x79, 0x83, 0xb1, 0xc1, + 0x29, 0x93, 0x71, 0xc1, 0x49, 0xdc, 0x48, 0x0e, + 0x6a, 0x0e, 0x7b, 0xd1, 0x5b, 0xde, 0x72, 0x0e, + 0x41, 0x0e, 0x7a, 0x2e, 0x5b, 0xdf, 0x58, 0xc1, + 0x63, 0x89, 0x25, 0x99, 0x58, 0xc1, 0x4b, 0xdc, + 0x48, 0xce, 0x79, 0xc0, 0xad, 0x8b, 0x2f, 0x9b, + 0x79, 0xcd, 0x66, 0x0e, 0x9e, 0xb1, 0x71, 0xdf, + 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, 0x28, 0x15, + 0x39, 0x17, 0x51, 0xc1, 0x69, 0x89, 0x61, 0xc1, + 0x25, 0x99, 0xa9, 0x83, 0x6a, 0xde, 0x29, 0x93, + 0xe9, 0xb1, 0x6a, 0xde, 0xe9, 0x83, 0x29, 0x93, + 0xcf, 0xb1, 0x4a, 0xde, 0x49, 0x0e, 0x7b, 0xde, + 0x41, 0x0e, 0x7d, 0x05, 0x25, 0xee, 0x7d, 0x06, + 0x6b, 0x12, 0x49, 0x0e, 0xf9, 0x83, 0x29, 0x93, + 0x7b, 0xce, 0xfd, 0x09, 0x17, 0x83, 0x2f, 0x93, + 0xb8, 0xb0, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0xe2, 0x61, 0x6c, 0x0c, 0x51, 0xc1, + 0x09, 0x8b, 0x25, 0x9b, 0x68, 0x2e, 0x79, 0xde, + 0x68, 0x2f, 0x2b, 0xef, 0x79, 0xdf, 0x68, 0x2f, + 0x37, 0xee, 0xd2, 0x03, 0x35, 0xae, 0x48, 0xde, + 0x49, 0x2f, 0x38, 0xee, 0x49, 0xce, 0x48, 0xde, + 0x6b, 0xcf, 0x68, 0xce, 0x49, 0xdf, 0x48, 0xcf, + 0x49, 0xdf, 0x7b, 0xce, 0x0f, 0x88, 0x79, 0xcf, + 0x25, 0x98, 0x5b, 0xde, 0x58, 0x2f, 0x2a, 0xef, + 0x69, 0xde, 0x6b, 0xce, 0x68, 0x8a, 0x25, 0x9a, + 0x69, 0xde, 0x2f, 0xae, 0x6d, 0x08, 0x51, 0xdf, + 0xec, 0x0e, 0x2c, 0x11, 0x39, 0x17, 0x51, 0xc1, + 0x69, 0x89, 0xb1, 0xc1, 0xbd, 0x08, 0x61, 0xc1, + 0x25, 0x99, 0xfa, 0xde, 0xf9, 0x0e, 0x70, 0xd7, + 0x60, 0xde, 0x7f, 0x06, 0xb0, 0xc1, 0x70, 0xce, + 0x02, 0x03, 0xf1, 0x0e, 0x40, 0xdc, 0x7b, 0xdf, + 0x4a, 0x0e, 0x4b, 0xde, 0x4d, 0x09, 0x09, 0x16, + 0x6d, 0x0f, 0x2f, 0xec, 0x02, 0x02, 0x7a, 0xde, + 0x78, 0x0e, 0x68, 0xde, 0x76, 0x0e, 0x6d, 0x0f, + 0xc4, 0xef, 0x79, 0x0e, 0x68, 0xde, 0x6f, 0x07, + 0x68, 0xce, 0x61, 0xdf, 0xb1, 0xdc, 0x51, 0xdd, + 0xee, 0x0e, 0x29, 0x15, 0xa9, 0x83, 0x51, 0xc1, + 0x3a, 0x17, 0xa1, 0xc5, 0x29, 0x93, 0x81, 0xc5, + 0x69, 0x85, 0xc1, 0xc5, 0x89, 0x12, 0x51, 0xc1, + 0xe3, 0x0e, 0xab, 0x12, 0x25, 0x95, 0x58, 0x12, + 0x66, 0xde, 0xfd, 0x09, 0x66, 0xde, 0x6b, 0x0e, + 0xad, 0x0f, 0x89, 0xce, 0x3e, 0xeb, 0x63, 0x88, + 0x57, 0xce, 0x25, 0x98, 0x2f, 0x83, 0x6b, 0xd6, + 0x2a, 0x93, 0xbd, 0x08, 0xa9, 0x3e, 0x66, 0xde, + 0x6a, 0xcc, 0xe9, 0x8a, 0xa1, 0xcf, 0x28, 0x9a, + 0xb1, 0xcc, 0x6a, 0xcf, 0x6a, 0x12, 0xfd, 0x09, + 0x2b, 0xae, 0xa2, 0x0f, 0x2f, 0xee, 0xd2, 0x03, + 0x6d, 0x08, 0x67, 0xce, 0x7e, 0x08, 0x71, 0x2e, + 0x68, 0xd7, 0xc8, 0xd6, 0x88, 0xd6, 0xa8, 0xd6, + 0x58, 0xde, 0xe8, 0x12, 0x29, 0x15, 0xe2, 0x61, + 0x38, 0x17, 0x51, 0xc1, 0x59, 0x12, 0x71, 0xc1, + 0x6b, 0x0e, 0x79, 0xde, 0x68, 0xde, 0x6d, 0x0f, + 0x2a, 0xee, 0x05, 0x83, 0x2a, 0x93, 0xfd, 0x09, + 0x5b, 0x0e, 0x7a, 0xde, 0x57, 0x0e, 0x6d, 0x08, + 0x68, 0xce, 0x7a, 0xdd, 0xd2, 0x8a, 0x68, 0x26, + 0x7c, 0x05, 0x2f, 0xef, 0xd2, 0x03, 0x6f, 0x05, + 0x2b, 0xef, 0x79, 0x83, 0x6a, 0x12, 0x29, 0x93, + 0x63, 0xb1, 0x2a, 0xae, 0x2d, 0x8a, 0xd2, 0x9a, + 0x79, 0x26, 0x7f, 0x07, 0x2d, 0x9a, 0x7a, 0xcd, + 0x71, 0xdf, 0x51, 0xdc, 0xef, 0x0e, 0x28, 0x15, + 0x38, 0x17, 0x51, 0xc1, 0xd2, 0x89, 0x71, 0xc1, + 0x79, 0xdd, 0x2d, 0x99, 0xfa, 0x12, 0xf8, 0x26, + 0x79, 0x05, 0x25, 0xee, 0x79, 0xdf, 0x49, 0xde, + 0x48, 0xce, 0x49, 0xde, 0x7b, 0xcf, 0xf9, 0xdd, + 0xfa, 0x26, 0xe3, 0x8b, 0x6b, 0x0e, 0x49, 0xde, + 0xd2, 0x9b, 0x67, 0x0e, 0x7b, 0xce, 0xfc, 0x05, + 0x2f, 0xef, 0xd2, 0x03, 0xff, 0x05, 0x2a, 0xef, + 0x79, 0x83, 0x29, 0x93, 0x14, 0xb1, 0x6d, 0x0f, + 0x24, 0xef, 0x21, 0xae, 0x79, 0xdd, 0x2d, 0x88, + 0xd2, 0x98, 0x7b, 0x26, 0x7f, 0x07, 0x79, 0xcd, + 0x28, 0xae, 0x6b, 0x8b, 0x6c, 0x08, 0x25, 0x9b, + 0x68, 0xce, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0xe2, 0x61, 0x38, 0x17, 0x51, 0xc1, + 0x59, 0x12, 0x71, 0xc1, 0x6b, 0x0e, 0x69, 0xde, + 0x69, 0xde, 0x6d, 0x0f, 0x29, 0xee, 0x05, 0x83, + 0x2a, 0x93, 0xfd, 0x09, 0x6a, 0xdd, 0x69, 0x05, + 0x2b, 0xee, 0x6a, 0xdf, 0x7a, 0xde, 0x79, 0xce, + 0x7a, 0xde, 0x68, 0xcf, 0x61, 0xdf, 0x51, 0xdc, + 0xef, 0x0e, 0x29, 0x15, 0x3b, 0x17, 0x51, 0xc1, + 0x2d, 0x89, 0xa1, 0xc5, 0x69, 0x87, 0x81, 0xc5, + 0x25, 0x97, 0x41, 0xc1, 0x44, 0xde, 0xd2, 0x99, + 0x8b, 0xdd, 0xa8, 0x12, 0x8a, 0x26, 0xa9, 0x83, + 0x29, 0x93, 0x59, 0x12, 0x1f, 0x8a, 0x2d, 0x9a, + 0x89, 0x27, 0x6b, 0x12, 0x8b, 0xcd, 0xfd, 0x09, + 0xb4, 0xde, 0x6d, 0x08, 0xbb, 0x0e, 0xa4, 0xce, + 0xb7, 0x0e, 0x65, 0xce, 0x6a, 0xdc, 0x69, 0xde, + 0x6d, 0x05, 0x39, 0xee, 0x44, 0xdd, 0x6a, 0xde, + 0x45, 0x0d, 0x59, 0x2f, 0x25, 0xee, 0x79, 0xdd, + 0x75, 0x0d, 0x48, 0x2f, 0x28, 0xe7, 0x69, 0xde, + 0x59, 0x2f, 0xd7, 0xef, 0x6a, 0x12, 0x79, 0xdf, + 0x74, 0xcf, 0x64, 0xce, 0x79, 0xdf, 0xb9, 0xcf, + 0x2b, 0xae, 0x6a, 0xdf, 0x64, 0xcf, 0x54, 0xce, + 0x7a, 0xdf, 0xba, 0xcf, 0xb8, 0xce, 0x7c, 0x08, + 0x55, 0xcf, 0x71, 0x2e, 0x68, 0xd7, 0x88, 0xd6, + 0xa8, 0xd6, 0x58, 0xde, 0xeb, 0x0e, 0x29, 0x15, + 0x69, 0x24, 0x51, 0xc1, 0x67, 0x8b, 0x4c, 0x08, + 0x25, 0x9b, 0x68, 0xce, 0x68, 0xcf, 0x65, 0x8b, + 0x25, 0x9b, 0x68, 0xce, 0x68, 0xcf, 0x63, 0x8b, + 0x25, 0x9b, 0x48, 0xce, 0x68, 0xcf, 0x61, 0x8b, + 0x25, 0x9b, 0x68, 0xce, 0x51, 0xdf, 0xec, 0x0e, + 0x2c, 0x11, 0xe2, 0x61, 0x6f, 0x0f, 0x21, 0xc5, + 0x01, 0xc5, 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, + 0xc1, 0xc5, 0x07, 0xe7, 0x65, 0x8e, 0x21, 0x88, + 0x25, 0x9e, 0x2d, 0x98, 0x0d, 0xd6, 0x41, 0x2e, + 0x5b, 0xdf, 0x29, 0x12, 0x4b, 0xde, 0x4f, 0x38, + 0x6f, 0x86, 0x39, 0x12, 0x32, 0x0e, 0x2a, 0x96, + 0x7c, 0x12, 0x2c, 0x0d, 0x7c, 0x0c, 0xbd, 0x12, + 0xb2, 0x0e, 0x7c, 0x2e, 0x34, 0x12, 0x75, 0x2e, + 0x3c, 0x0c, 0x34, 0x2e, 0x35, 0x2e, 0xdc, 0x12, + 0xac, 0xd6, 0xaf, 0x38, 0x45, 0x3f, 0x21, 0xe6, + 0x32, 0xd7, 0x2f, 0x0f, 0x38, 0xc7, 0x32, 0xd7, + 0x38, 0xc7, 0x32, 0xde, 0x38, 0xce, 0x38, 0xde, + 0x6c, 0xce, 0x6d, 0x12, 0xcf, 0xe6, 0x7c, 0x08, + 0x71, 0x2e, 0xc8, 0xd6, 0x88, 0xd6, 0xa8, 0xd6, + 0x58, 0xd7, 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, + 0xe8, 0x12, 0x2c, 0x11, 0x6f, 0x8b, 0x21, 0xc5, + 0x61, 0x8e, 0x01, 0xc5, 0x25, 0x9e, 0x51, 0xc1, + 0x59, 0x12, 0xa1, 0xc5, 0x5c, 0x0c, 0x81, 0xc5, + 0x2a, 0x9b, 0xc1, 0xc5, 0x3d, 0xde, 0x3a, 0x2f, + 0x6b, 0xe7, 0x65, 0x8e, 0x21, 0x84, 0x25, 0x9e, + 0x2d, 0x94, 0xad, 0xd6, 0x81, 0x2e, 0x97, 0xdf, + 0x87, 0xde, 0x85, 0x38, 0xfa, 0x12, 0x0a, 0x12, + 0x0c, 0x0c, 0xf2, 0x0e, 0x2a, 0x12, 0x10, 0x12, + 0x2c, 0x0e, 0x1c, 0x0c, 0x0a, 0x2e, 0x3d, 0x2f, + 0x27, 0xe6, 0x10, 0x12, 0x22, 0x0e, 0x1c, 0x0c, + 0x10, 0x2e, 0x18, 0x2e, 0x0e, 0xde, 0x1e, 0xdf, + 0x05, 0x38, 0x3d, 0xae, 0x10, 0x2e, 0x08, 0x2e, + 0x4f, 0xd6, 0x18, 0x2e, 0x0e, 0xde, 0x1e, 0xdf, + 0x45, 0x38, 0x05, 0x38, 0x4f, 0x3f, 0x2e, 0xe7, + 0x22, 0x0e, 0x29, 0xae, 0xfc, 0x0e, 0x0b, 0x12, + 0x1a, 0x12, 0xc9, 0x12, 0xd0, 0x12, 0xdc, 0x0c, + 0xc2, 0x0e, 0x5d, 0x12, 0x43, 0x12, 0x5c, 0x0c, + 0x4c, 0x0c, 0xd0, 0x2e, 0x07, 0x3f, 0x22, 0xe6, + 0x43, 0x2e, 0xd8, 0x2e, 0x02, 0xd7, 0x48, 0x2e, + 0x3a, 0x2f, 0x0b, 0xc7, 0x02, 0xd7, 0x0b, 0xc7, + 0x02, 0xde, 0x0b, 0xce, 0x0b, 0xde, 0x6f, 0xce, + 0x6d, 0x12, 0xe8, 0xe6, 0x7c, 0x08, 0x71, 0x2e, + 0xc8, 0xd6, 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, + 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, + 0x2c, 0x11, 0xe2, 0x61, 0x38, 0x17, 0x51, 0xc1, + 0x59, 0x12, 0xa1, 0xc5, 0x61, 0x88, 0x71, 0xc1, + 0xe3, 0x0e, 0x25, 0x98, 0x7b, 0xde, 0x4b, 0x83, + 0x7c, 0x0e, 0x2b, 0x93, 0x68, 0x12, 0xaa, 0x08, + 0xa1, 0x2e, 0xb5, 0xdf, 0xa5, 0xde, 0x7b, 0xce, + 0xa1, 0xcf, 0xb1, 0xcc, 0x85, 0xb1, 0x6a, 0xce, + 0x62, 0x0e, 0x79, 0x12, 0x7c, 0x0c, 0x79, 0x2e, + 0x6f, 0x8a, 0x2a, 0x9a, 0x79, 0x2e, 0xa8, 0xc6, + 0x58, 0xce, 0x7e, 0x08, 0x71, 0x2e, 0x68, 0xd7, + 0xa8, 0xd6, 0x58, 0xde, 0xeb, 0x0e, 0x29, 0x15, + 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, 0xa1, 0xc5, + 0x81, 0xc5, 0xc1, 0xc5, 0x6f, 0x80, 0x21, 0xc1, + 0xe3, 0x0e, 0x61, 0x8e, 0x39, 0xde, 0x25, 0x9e, + 0x4d, 0xde, 0x12, 0x8a, 0xab, 0x12, 0x7b, 0x12, + 0xac, 0x0c, 0x72, 0x0e, 0xab, 0x2e, 0x7d, 0xce, + 0x2a, 0x9a, 0x2a, 0x90, 0xa9, 0x2e, 0x45, 0xd6, + 0x7d, 0x0f, 0x68, 0xee, 0x3f, 0x0f, 0x04, 0xe7, + 0x65, 0x8a, 0xfc, 0x12, 0x25, 0x9a, 0xfc, 0x0d, + 0x89, 0xd6, 0xa0, 0x12, 0xa2, 0x0e, 0x6b, 0x12, + 0xd5, 0x12, 0x7a, 0x12, 0xdc, 0x0c, 0xd5, 0x2e, + 0xd3, 0x2e, 0xa2, 0xd6, 0x67, 0x38, 0xa7, 0x38, + 0xd3, 0x0e, 0x65, 0x3f, 0x3b, 0xe6, 0x60, 0x12, + 0xac, 0x12, 0xa2, 0x0e, 0x4b, 0x83, 0x75, 0x12, + 0x2b, 0x93, 0x7c, 0x0c, 0x75, 0x2e, 0xa2, 0xd7, + 0x73, 0x2e, 0xa8, 0xc7, 0xa2, 0xd7, 0xa8, 0xc7, + 0xa2, 0xde, 0xa8, 0xce, 0x78, 0xde, 0x38, 0xce, + 0x41, 0xcf, 0x51, 0xcc, 0x53, 0xb1, 0x2a, 0xae, + 0x8f, 0x83, 0x41, 0xcf, 0x2b, 0x93, 0x51, 0xcc, + 0x6c, 0x12, 0xfd, 0x09, 0x7d, 0xde, 0x39, 0x12, + 0x32, 0x0e, 0xd8, 0x12, 0xdc, 0x0c, 0x29, 0x12, + 0x62, 0x0e, 0xd8, 0x2e, 0x6c, 0x0c, 0xd3, 0x2e, + 0x6c, 0x2e, 0x32, 0xd7, 0x63, 0x2e, 0x39, 0xc7, + 0x32, 0xd7, 0x39, 0xc7, 0x32, 0xde, 0x39, 0xce, + 0x39, 0xde, 0x2c, 0xce, 0x6e, 0x08, 0x61, 0x2e, + 0x29, 0xd7, 0xc9, 0xd6, 0x3d, 0x15, 0x89, 0xd6, + 0xa9, 0xd6, 0x59, 0xd7, 0x29, 0xd6, 0x62, 0x0e, + 0xe9, 0x12, 0x2c, 0x11, 0x21, 0xc5, 0x3d, 0x17, + 0x01, 0xc5, 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, + 0xc1, 0xc5, 0x21, 0xc1, 0x0c, 0x8e, 0xe3, 0x0e, + 0x25, 0x9e, 0x2d, 0xde, 0x2d, 0x0f, 0x7a, 0xee, + 0x0d, 0x16, 0x2d, 0x0f, 0x79, 0xec, 0x61, 0x87, + 0x63, 0x86, 0x65, 0x80, 0x6f, 0x8f, 0x02, 0x02, + 0x25, 0x97, 0x64, 0xde, 0x2a, 0x9f, 0x6d, 0x0f, + 0x25, 0x96, 0x25, 0x90, 0x2c, 0x12, 0x17, 0xee, + 0x0a, 0xae, 0x8d, 0x0f, 0x84, 0xce, 0x02, 0xd6, + 0x5d, 0xdc, 0x37, 0xee, 0x8f, 0x83, 0x01, 0xcf, + 0x2b, 0x93, 0x11, 0xcc, 0x6c, 0x08, 0xfd, 0x09, + 0x74, 0xde, 0x19, 0x12, 0x12, 0x0e, 0xd8, 0x12, + 0xdc, 0x0c, 0x0e, 0x12, 0x0c, 0x0c, 0xd8, 0x2e, + 0x0e, 0x2e, 0xdd, 0x2e, 0x12, 0xd7, 0x0d, 0x2e, + 0x1f, 0xc7, 0x12, 0xd7, 0x1f, 0xc7, 0x12, 0xde, + 0x1f, 0xce, 0x4f, 0xde, 0x6b, 0xce, 0x7a, 0xdf, + 0x6a, 0xdc, 0x7d, 0x09, 0x02, 0x03, 0x02, 0x02, + 0x64, 0xde, 0x6d, 0x0f, 0x3e, 0xee, 0x03, 0xd6, + 0x4c, 0xd6, 0xd9, 0x12, 0xdc, 0x0c, 0x89, 0x12, + 0x4f, 0x38, 0x12, 0x8f, 0xd9, 0x2e, 0x65, 0xd6, + 0x2a, 0x9f, 0x6f, 0x38, 0xdc, 0x2e, 0x82, 0x0e, + 0xc3, 0x0e, 0xa3, 0x0e, 0x6b, 0x3f, 0x3d, 0x12, + 0xe4, 0xe6, 0x25, 0xd6, 0xa3, 0x0e, 0x23, 0xce, + 0x2c, 0x0e, 0x33, 0xcf, 0x2e, 0xea, 0x2f, 0xed, + 0x3c, 0x0e, 0x6d, 0x08, 0x25, 0xce, 0x35, 0xcf, + 0x02, 0x03, 0x2e, 0xae, 0xca, 0x8a, 0xd2, 0x9a, + 0x7e, 0x08, 0x71, 0x2e, 0x28, 0xd7, 0xc8, 0xd6, + 0x3d, 0x15, 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, + 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, + 0x2c, 0x11, 0xe2, 0x61, 0x38, 0x17, 0x71, 0xc1, + 0x0c, 0x8b, 0x25, 0x9b, 0x78, 0xde, 0x7d, 0x0f, + 0x2b, 0xee, 0xca, 0x8a, 0xd2, 0x9a, 0x71, 0xdf, + 0xec, 0x0e, 0x28, 0x15, 0x08, 0x16, 0x7d, 0x0f, + 0x2f, 0xed, 0xd5, 0xa1, 0x6d, 0x0f, 0x2b, 0xeb, + 0xa5, 0x8b, 0x2d, 0x9b, 0x78, 0xde, 0x68, 0x2f, + 0x2b, 0xeb, 0x6d, 0x0f, 0x29, 0xee, 0xc3, 0x8a, + 0xd2, 0x9a, 0xc3, 0xa1, 0x6d, 0x0f, 0x24, 0xee, + 0x62, 0x0e, 0x79, 0x12, 0x7e, 0x0c, 0x79, 0x2e, + 0xa5, 0x8a, 0x2a, 0x9a, 0x79, 0x2e, 0x29, 0xae, + 0x69, 0x8a, 0x25, 0x9a, 0x79, 0xde, 0xd2, 0x88, + 0x02, 0x02, 0x68, 0xdd, 0x2d, 0x98, 0x6b, 0x26, + 0x21, 0xef, 0x68, 0x12, 0xf9, 0x83, 0x29, 0x93, + 0x63, 0xb0, 0x6d, 0x0f, 0x29, 0xee, 0xd3, 0x83, + 0x2c, 0x93, 0xfd, 0x09, 0x6d, 0x08, 0x20, 0xae, + 0x79, 0x0e, 0x68, 0xde, 0x71, 0x0e, 0x6d, 0x05, + 0x29, 0xee, 0xf8, 0x8a, 0xd2, 0x9a, 0x28, 0xae, + 0x6d, 0x07, 0x79, 0x0e, 0x68, 0xce, 0x6d, 0x08, + 0x02, 0x03, 0xef, 0xa1, 0x39, 0x17, 0x61, 0xc1, + 0x09, 0x16, 0x6d, 0x0f, 0x2f, 0xec, 0x02, 0x02, + 0x68, 0x8b, 0x25, 0x9b, 0x68, 0xde, 0x6d, 0x0f, + 0x2e, 0xef, 0x6c, 0x08, 0x68, 0xce, 0xd9, 0x83, + 0x29, 0x93, 0xfd, 0x09, 0x61, 0xdf, 0xec, 0x0e, + 0x29, 0x15, 0xe2, 0x61, 0x38, 0x17, 0x51, 0xc1, + 0x71, 0xc1, 0x0c, 0x8b, 0x25, 0x9b, 0x78, 0xde, + 0x7d, 0x0f, 0x29, 0xee, 0xca, 0x8a, 0xd2, 0x9a, + 0x24, 0xae, 0x08, 0x16, 0x7d, 0x0f, 0x2f, 0xed, + 0xd7, 0xa1, 0x6d, 0x0f, 0x2a, 0xea, 0xc3, 0x8a, + 0xd2, 0x9a, 0x71, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x28, 0x15, 0xa5, 0x8b, 0x2d, 0x9b, 0x78, 0xde, + 0x68, 0x2f, 0x2f, 0xeb, 0xd8, 0xa1, 0x62, 0x0e, + 0x59, 0x12, 0x5e, 0x0c, 0x59, 0x2e, 0xa5, 0x8a, + 0x2a, 0x9a, 0x59, 0x2e, 0x69, 0x8a, 0x25, 0x9a, + 0x69, 0xde, 0x59, 0x2f, 0xc9, 0x8a, 0xd2, 0x9a, + 0x2f, 0xef, 0xc5, 0xa1, 0xd2, 0x8b, 0x02, 0x02, + 0x6a, 0xdd, 0x2d, 0x9b, 0x79, 0x26, 0x29, 0xef, + 0xfa, 0x8a, 0xd2, 0x9a, 0x0b, 0xae, 0x6d, 0x05, + 0x2b, 0xee, 0xa9, 0x83, 0x6a, 0x12, 0x29, 0x93, + 0xd9, 0xb3, 0x2a, 0xae, 0x6c, 0x05, 0x28, 0xee, + 0xdb, 0x83, 0x6a, 0x12, 0x28, 0x93, 0xfd, 0x09, + 0x6a, 0x12, 0xe9, 0x83, 0x29, 0x93, 0xfd, 0x09, + 0x59, 0x0e, 0x7a, 0xde, 0x51, 0x0e, 0x7d, 0x05, + 0x22, 0xee, 0x7d, 0x06, 0x6a, 0x12, 0x59, 0x0e, + 0xf9, 0x83, 0x29, 0x93, 0x7a, 0xce, 0xfd, 0x09, + 0x6d, 0x0f, 0x2b, 0xee, 0xd3, 0x83, 0x2c, 0x93, + 0x8e, 0xb2, 0x6d, 0x08, 0x2f, 0xae, 0x6d, 0x08, + 0x02, 0x03, 0x95, 0xa1, 0x38, 0x17, 0x51, 0xc1, + 0x49, 0x12, 0xa1, 0xc5, 0x0c, 0x8a, 0x71, 0xc1, + 0x25, 0x9a, 0xe1, 0x0e, 0x69, 0xde, 0x6d, 0x0f, + 0x27, 0xee, 0xca, 0x8a, 0xd2, 0x9a, 0x48, 0x08, + 0x41, 0x2e, 0x7b, 0xd7, 0xab, 0xd6, 0x5b, 0xde, + 0xeb, 0x12, 0x28, 0x15, 0x09, 0x16, 0x6d, 0x0f, + 0x2f, 0xed, 0xd9, 0xa1, 0x68, 0x8a, 0x25, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0x2f, 0xef, 0xc3, 0xa1, + 0xc2, 0x8a, 0x42, 0x0f, 0xd2, 0x9a, 0x2f, 0xec, + 0xc6, 0xa1, 0x02, 0x02, 0x69, 0x8a, 0x25, 0x9a, + 0x59, 0xde, 0x59, 0x0e, 0x6a, 0xde, 0x51, 0x0e, + 0x6c, 0x05, 0x2b, 0xee, 0x6c, 0x06, 0x59, 0x0e, + 0x6a, 0xce, 0x6d, 0x08, 0x34, 0xae, 0xe3, 0x8a, + 0x4d, 0x0f, 0xd2, 0x9a, 0x2f, 0xef, 0x39, 0xae, + 0xaa, 0xdd, 0x2d, 0x8a, 0xd2, 0x9a, 0x27, 0x87, + 0xa9, 0x26, 0x4b, 0x83, 0x28, 0x93, 0x61, 0x12, + 0x6c, 0x0e, 0x71, 0x12, 0x7f, 0x0e, 0x2d, 0x97, + 0xa4, 0x27, 0xaa, 0xcd, 0x1f, 0xb0, 0xd3, 0x83, + 0x2c, 0x93, 0xfd, 0x09, 0x61, 0xdf, 0x02, 0x03, + 0xee, 0xa1, 0xe2, 0x61, 0x0c, 0x88, 0x51, 0xc1, + 0x25, 0x98, 0x4b, 0xde, 0x4d, 0x0f, 0x29, 0xef, + 0xca, 0x8a, 0xd2, 0x9a, 0x24, 0xae, 0x0b, 0x16, + 0x4d, 0x0f, 0x2f, 0xed, 0xd7, 0xa1, 0x6d, 0x0f, + 0x2b, 0xea, 0xc3, 0x8a, 0xd2, 0x9a, 0x51, 0xdf, + 0xec, 0x0e, 0x2c, 0x11, 0xa5, 0x88, 0x2d, 0x98, + 0x4b, 0xde, 0x6b, 0x2f, 0x2f, 0xeb, 0xdb, 0xa1, + 0x7d, 0x0f, 0x29, 0xef, 0xc2, 0x8a, 0xd2, 0x9a, + 0xde, 0xa1, 0x62, 0x0e, 0xd2, 0x89, 0x49, 0x12, + 0x02, 0x02, 0x4e, 0x0c, 0x2d, 0x99, 0x49, 0x2e, + 0xa5, 0x8a, 0x2a, 0x9a, 0x49, 0x2e, 0x6b, 0xdd, + 0x6a, 0x26, 0x29, 0xef, 0xfa, 0x8a, 0xd2, 0x9a, + 0x3f, 0xae, 0x6b, 0xdc, 0x6a, 0x0e, 0x69, 0xde, + 0x6d, 0x0f, 0x2f, 0xef, 0xd5, 0xa1, 0x48, 0x0e, + 0x6b, 0xde, 0x68, 0x27, 0x6b, 0xce, 0x69, 0x8a, + 0x46, 0x0e, 0x25, 0x9a, 0x69, 0xde, 0x49, 0x2f, + 0x29, 0xee, 0x6d, 0x08, 0x02, 0x03, 0xfd, 0xa1, + 0x49, 0x0e, 0x6b, 0xde, 0x6f, 0x05, 0xd7, 0xee, + 0x6c, 0x08, 0x6b, 0x8b, 0x25, 0x9b, 0x68, 0xce, + 0x2d, 0x8a, 0xd8, 0xa1, 0x39, 0x17, 0x61, 0xc1, + 0x0c, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0x30, 0xef, 0x09, 0x16, 0x6d, 0x0f, 0x37, 0xec, + 0x02, 0x02, 0x69, 0x8a, 0x25, 0x9a, 0x49, 0xde, + 0x6b, 0xdc, 0x6a, 0x0e, 0x69, 0xde, 0x6d, 0x0f, + 0xfa, 0x8a, 0xd2, 0x9a, 0x2f, 0xef, 0x21, 0xae, + 0x49, 0x0e, 0x7b, 0xd7, 0x6b, 0xd1, 0x7f, 0x07, + 0x6d, 0x0f, 0x7b, 0xce, 0x29, 0xee, 0x13, 0x83, + 0x28, 0x93, 0xfd, 0x09, 0x6d, 0x08, 0x02, 0x03, + 0x2e, 0xae, 0xca, 0x8a, 0xd2, 0x9a, 0x71, 0xdf, + 0xec, 0x0e, 0x28, 0x15, 0xc9, 0x8a, 0x2d, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0x22, 0xee, 0xcf, 0x88, + 0xc8, 0x8b, 0x62, 0x0e, 0x2a, 0x98, 0x79, 0x14, + 0x2d, 0x9b, 0x7b, 0xcc, 0x68, 0xdf, 0x7f, 0x0e, + 0x6b, 0xcd, 0x4b, 0xce, 0x4b, 0xcf, 0x49, 0x0e, + 0xd4, 0xe0, 0x2c, 0x11, 0x4d, 0x05, 0x51, 0xc1, + 0x59, 0xdd, 0x3d, 0xee, 0x7a, 0x26, 0x3c, 0xee, + 0x79, 0xdd, 0x41, 0xdc, 0x7b, 0xce, 0x79, 0xdc, + 0x78, 0xde, 0x7f, 0x05, 0x2e, 0xee, 0x7d, 0x08, + 0x79, 0xcd, 0x6c, 0x08, 0x51, 0xdf, 0xec, 0x0e, + 0x2c, 0x11, 0x58, 0x26, 0x58, 0x2f, 0xdc, 0xee, + 0x6d, 0x08, 0xd4, 0xa1, 0x3b, 0x17, 0x51, 0xc1, + 0xb1, 0xc1, 0x41, 0xc0, 0x0c, 0x88, 0x25, 0x98, + 0x4b, 0xde, 0x4d, 0x0f, 0x15, 0xef, 0x0b, 0x16, + 0x4d, 0x0f, 0x18, 0xec, 0x6d, 0x0f, 0x1b, 0xeb, + 0xc9, 0x88, 0x2d, 0x98, 0x4b, 0xde, 0x49, 0x2f, + 0x1c, 0xed, 0x6f, 0x0c, 0xf3, 0x88, 0x2a, 0x98, + 0x02, 0x02, 0x6b, 0x2e, 0x49, 0xdd, 0x48, 0x27, + 0x49, 0xcd, 0x59, 0xde, 0x6a, 0x2f, 0x2b, 0xef, + 0x79, 0xdf, 0x68, 0x2f, 0x30, 0xee, 0xd2, 0x03, + 0x36, 0xae, 0x5b, 0x0e, 0xbf, 0x83, 0xba, 0xde, + 0x24, 0x93, 0x74, 0xdc, 0x57, 0x0e, 0x44, 0xdd, + 0xb9, 0x0e, 0xb1, 0xcf, 0xf3, 0xb1, 0x6d, 0x0f, + 0x22, 0xee, 0x6a, 0xdf, 0xb1, 0x83, 0x7a, 0xde, + 0x28, 0x93, 0x79, 0xce, 0x7a, 0xde, 0x68, 0xcf, + 0x6a, 0x12, 0xfd, 0x09, 0x6d, 0x0f, 0x29, 0xee, + 0xd3, 0x83, 0x2c, 0x93, 0x21, 0xb2, 0x02, 0x03, + 0x6d, 0x08, 0x2b, 0xae, 0xca, 0x8a, 0xd2, 0x9a, + 0x2e, 0xae, 0xc3, 0x8a, 0xd2, 0x9a, 0x4f, 0x08, + 0x41, 0x2e, 0x7b, 0xd7, 0xbb, 0xd7, 0x5b, 0xde, + 0xe9, 0x0e, 0x28, 0x15, 0x3b, 0x17, 0x51, 0xc1, + 0xb1, 0xc1, 0x41, 0xc0, 0x0c, 0x88, 0x25, 0x98, + 0x4b, 0xde, 0x4d, 0x0f, 0x14, 0xee, 0x0b, 0x16, + 0x4d, 0x0f, 0x1b, 0xec, 0x6d, 0x0f, 0x1a, 0xeb, + 0xc9, 0x88, 0x2d, 0x98, 0x4b, 0xde, 0x49, 0x2f, + 0x1f, 0xed, 0x6f, 0x0c, 0xf3, 0x88, 0x2a, 0x98, + 0x02, 0x02, 0x6b, 0x2e, 0x49, 0xdd, 0x48, 0x27, + 0x49, 0xcd, 0x59, 0xde, 0x6a, 0x2f, 0x2b, 0xef, + 0x79, 0xdf, 0x68, 0x2f, 0x33, 0xee, 0xd2, 0x03, + 0x31, 0xae, 0x5b, 0x0e, 0xbf, 0x83, 0xba, 0xde, + 0x24, 0x93, 0x74, 0xdc, 0x57, 0x0e, 0x44, 0xdd, + 0xb9, 0x0e, 0xb1, 0xcf, 0x95, 0xb1, 0x6d, 0x0f, + 0x3d, 0xee, 0x6a, 0xdf, 0xb1, 0x83, 0x7a, 0xde, + 0x28, 0x93, 0x79, 0xce, 0x7a, 0xde, 0x68, 0xcf, + 0x6a, 0x12, 0xfd, 0x09, 0x6d, 0x0f, 0x28, 0xee, + 0x6b, 0x8b, 0x6c, 0x08, 0x25, 0x9b, 0x68, 0xce, + 0x02, 0x03, 0x6d, 0x08, 0x2b, 0xae, 0xca, 0x8a, + 0xd2, 0x9a, 0x2e, 0xae, 0xc3, 0x8a, 0xd2, 0x9a, + 0x4f, 0x08, 0x41, 0x2e, 0x7b, 0xd7, 0xbb, 0xd7, + 0x5b, 0xde, 0xe9, 0x0e, 0x28, 0x15, 0xe2, 0x61, + 0x0c, 0x88, 0x51, 0xc1, 0x25, 0x98, 0x4b, 0xde, + 0x4d, 0x0f, 0x3b, 0xef, 0x0b, 0x16, 0x4d, 0x0f, + 0x3e, 0xec, 0x6d, 0x0f, 0x39, 0xeb, 0xc9, 0x88, + 0x2d, 0x98, 0x4b, 0xde, 0x49, 0x2f, 0x22, 0xed, + 0x02, 0x02, 0x6f, 0x0c, 0xf3, 0x88, 0x2a, 0x98, + 0x6b, 0x2e, 0x49, 0xdd, 0x48, 0x26, 0x49, 0xcd, + 0x02, 0x03, 0x6d, 0x08, 0x2b, 0xae, 0xca, 0x8a, + 0xd2, 0x9a, 0x2e, 0xae, 0xc3, 0x8a, 0xd2, 0x9a, + 0x51, 0xdf, 0xec, 0x0e, 0x2c, 0x11, 0xe2, 0x61, + 0x51, 0xc1, 0x3a, 0x17, 0xa1, 0xc5, 0xa8, 0x12, + 0x51, 0xc1, 0x0c, 0x8b, 0xe7, 0x0e, 0x25, 0x9b, + 0xbb, 0x12, 0x78, 0xde, 0x7d, 0x0f, 0x65, 0xef, + 0x08, 0x16, 0x7d, 0x0f, 0x68, 0xec, 0x68, 0x8b, + 0x25, 0x9b, 0x78, 0xde, 0x7d, 0x0f, 0x6d, 0xee, + 0x6d, 0x0f, 0x6c, 0xeb, 0xc9, 0x8b, 0x2d, 0x9b, + 0x78, 0xde, 0x79, 0x2f, 0x11, 0xed, 0xad, 0x0f, + 0x10, 0xee, 0x4d, 0x06, 0x16, 0xef, 0x59, 0x12, + 0x02, 0x02, 0x5f, 0x0c, 0xf3, 0x8a, 0x2a, 0x9a, + 0x59, 0x2e, 0x6a, 0xde, 0x59, 0x2f, 0xc9, 0x8a, + 0xd2, 0x9a, 0x05, 0xef, 0x6a, 0xdf, 0x59, 0x2f, + 0x2e, 0xee, 0xd2, 0x03, 0x2c, 0xae, 0x26, 0x83, + 0x44, 0x12, 0x2d, 0x93, 0x75, 0x12, 0x61, 0xd2, + 0xbf, 0x83, 0x61, 0xcf, 0x24, 0x93, 0x6a, 0x12, + 0x54, 0xb1, 0x6d, 0x0f, 0x6d, 0x08, 0x2f, 0xee, + 0x38, 0xae, 0x23, 0x83, 0x71, 0x12, 0x7f, 0x0e, + 0x2b, 0x93, 0x6a, 0x12, 0xa8, 0xcc, 0xb8, 0xcd, + 0x9c, 0xb3, 0xd3, 0x83, 0x2c, 0x93, 0xfd, 0x09, + 0x61, 0xdc, 0x6d, 0x0f, 0x2a, 0xef, 0x26, 0x83, + 0x2d, 0x93, 0x41, 0xd2, 0x2b, 0x83, 0x71, 0xd2, + 0x7b, 0xce, 0x02, 0x03, 0x24, 0xae, 0xca, 0x8a, + 0xd2, 0x9a, 0x2b, 0xae, 0xc3, 0x8a, 0xd2, 0x9a, + 0x2e, 0xae, 0xc2, 0x8a, 0xd2, 0x9a, 0x4a, 0x08, + 0x41, 0x2e, 0x7b, 0xd7, 0xab, 0xd6, 0x5b, 0xde, + 0xeb, 0x12, 0x28, 0x15, 0x39, 0x17, 0x51, 0xc1, + 0xa1, 0xc5, 0x81, 0xc5, 0x61, 0xc1, 0x2d, 0x8a, + 0xe3, 0x0e, 0x2c, 0x9a, 0xb9, 0xde, 0xbd, 0x0f, + 0x24, 0xef, 0x7e, 0x08, 0x71, 0x2e, 0x68, 0xd7, + 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xde, 0xe8, 0x12, + 0x29, 0x15, 0x41, 0x89, 0x2c, 0x86, 0xb2, 0x0e, + 0x2a, 0x99, 0x2c, 0x96, 0xaa, 0xce, 0x65, 0xde, + 0x6c, 0x05, 0x23, 0xee, 0xd1, 0x83, 0xa9, 0x0e, + 0x65, 0xde, 0x27, 0x93, 0x7c, 0x08, 0xa1, 0x0e, + 0x7a, 0xcf, 0x61, 0xcf, 0x6d, 0x08, 0x61, 0xcc, + 0x6a, 0x12, 0xfd, 0x09, 0x2e, 0xae, 0x6d, 0x08, + 0x6a, 0xcf, 0xa8, 0x0e, 0xb2, 0x0e, 0x2f, 0xec, + 0xf0, 0xa1, 0x5a, 0x0e, 0xc5, 0xa1, 0xe2, 0x61, + 0x38, 0x17, 0x51, 0xc1, 0x2f, 0x83, 0xa1, 0xc5, + 0xa9, 0x12, 0x71, 0xc1, 0xe3, 0x0e, 0x69, 0x0e, + 0xa1, 0x8b, 0x2a, 0x93, 0x26, 0x9b, 0x79, 0xcf, + 0x7a, 0x08, 0xa9, 0xcc, 0x71, 0x2e, 0x58, 0xdf, + 0xb8, 0xde, 0xb1, 0xcf, 0x51, 0xcc, 0xfd, 0x09, + 0x7e, 0x08, 0xb5, 0xcc, 0x71, 0x2e, 0x55, 0xcd, + 0x68, 0xd7, 0xa8, 0xd6, 0x58, 0xde, 0xeb, 0x0e, + 0x29, 0x15, 0xe2, 0x61, 0x38, 0x17, 0x51, 0xc1, + 0xa1, 0xc5, 0x71, 0xc1, 0x0c, 0x8b, 0xe3, 0x0e, + 0x25, 0x9b, 0x78, 0xde, 0x7d, 0x0f, 0x03, 0xef, + 0x08, 0x16, 0x7d, 0x0f, 0x06, 0xec, 0x6d, 0x0f, + 0x01, 0xeb, 0x2d, 0x8b, 0x2c, 0x9b, 0x78, 0xde, + 0x79, 0x2f, 0x0a, 0xed, 0x62, 0x0e, 0x02, 0x02, + 0x59, 0x12, 0x5e, 0x0c, 0x59, 0x28, 0x41, 0x8a, + 0x2a, 0x9a, 0x59, 0x2e, 0x6a, 0xdf, 0x6d, 0x0f, + 0x2a, 0xee, 0x05, 0x83, 0x6a, 0x12, 0x69, 0x0e, + 0x2a, 0x93, 0xfd, 0x09, 0x2e, 0xae, 0x6c, 0x08, + 0x6a, 0xcf, 0x6a, 0xde, 0x63, 0x8b, 0xa9, 0xdd, + 0x25, 0x9b, 0x6a, 0x12, 0xd1, 0x83, 0x48, 0xd6, + 0x27, 0x93, 0xbd, 0x08, 0xab, 0x3e, 0xa1, 0xcf, + 0xb1, 0xcc, 0xfd, 0x09, 0x02, 0x03, 0x6d, 0x08, + 0x2b, 0xae, 0xca, 0x8a, 0xd2, 0x9a, 0x2e, 0xae, + 0xc3, 0x8a, 0xd2, 0x9a, 0x4e, 0x08, 0x41, 0x2e, + 0x7b, 0xd7, 0xab, 0xd6, 0x5b, 0xde, 0xeb, 0x0e, + 0x28, 0x15, 0xe2, 0x61, 0x38, 0x17, 0x71, 0xc1, + 0x0c, 0x8b, 0x25, 0x9b, 0x78, 0xde, 0x7d, 0x0f, + 0x0d, 0xef, 0x08, 0x16, 0x7d, 0x0f, 0x30, 0xec, + 0x6d, 0x0f, 0x33, 0xeb, 0x2d, 0x8b, 0x2c, 0x9b, + 0x78, 0xde, 0x79, 0x2f, 0x34, 0xed, 0x62, 0x0e, + 0x02, 0x02, 0x79, 0x12, 0x7e, 0x0c, 0x79, 0x28, + 0x41, 0x8a, 0x2a, 0x9a, 0x79, 0x2e, 0x68, 0xdf, + 0x6d, 0x0f, 0x25, 0xee, 0x68, 0x12, 0x05, 0x83, + 0x69, 0x0e, 0x2a, 0x93, 0x7d, 0x08, 0x79, 0xcb, + 0xf9, 0xb3, 0x02, 0x03, 0x6d, 0x08, 0x2b, 0xae, + 0xca, 0x8a, 0xd2, 0x9a, 0x2e, 0xae, 0xc3, 0x8a, + 0xd2, 0x9a, 0x71, 0xdf, 0xec, 0x0e, 0x28, 0x15, + 0x38, 0x17, 0x51, 0xc1, 0xd1, 0x83, 0xa1, 0xc5, + 0x27, 0x93, 0x81, 0xc5, 0x5d, 0x08, 0x71, 0xc1, + 0xe3, 0x0e, 0x79, 0xde, 0x48, 0xdd, 0xa9, 0xdc, + 0xb9, 0xdd, 0x45, 0x3e, 0x41, 0xcf, 0x51, 0xcc, + 0x59, 0x12, 0xfd, 0x09, 0x02, 0x03, 0x5a, 0xde, + 0x6a, 0xdf, 0xba, 0xdc, 0xbd, 0x09, 0x02, 0x02, + 0x7e, 0x08, 0x71, 0x2e, 0x68, 0xd7, 0x88, 0xd6, + 0xa8, 0xd6, 0x58, 0xde, 0xe8, 0x12, 0x29, 0x15, + 0x38, 0x17, 0x71, 0xc1, 0x0c, 0x8b, 0x25, 0x9b, + 0x78, 0xde, 0x7d, 0x0f, 0x0d, 0xef, 0x08, 0x16, + 0x7d, 0x0f, 0x30, 0xec, 0x3d, 0x8b, 0x2d, 0x9b, + 0x79, 0x2f, 0x29, 0xe6, 0xc2, 0x8a, 0xd2, 0x9a, + 0x35, 0xae, 0x02, 0x02, 0x6d, 0x0f, 0x2a, 0xef, + 0x69, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x69, 0xdd, + 0x65, 0x0d, 0x2f, 0xae, 0x62, 0x0e, 0x3b, 0x83, + 0x28, 0x93, 0xfd, 0x09, 0x6d, 0x0f, 0x29, 0xee, + 0xd3, 0x83, 0x2c, 0x93, 0x35, 0xb5, 0x02, 0x03, + 0x6d, 0x08, 0x2e, 0xae, 0xca, 0x8a, 0xd2, 0x9a, + 0x71, 0xdf, 0xec, 0x0e, 0x28, 0x15, 0xe2, 0x61, + 0x31, 0xc1, 0x0c, 0x8f, 0x51, 0xc1, 0x25, 0x9f, + 0x3c, 0xde, 0x3d, 0x0f, 0x37, 0xee, 0x0c, 0x16, + 0x3d, 0x0f, 0x3a, 0xec, 0x69, 0x8f, 0x02, 0x02, + 0x25, 0x9f, 0x4c, 0xde, 0x4d, 0x0f, 0x3d, 0x08, + 0x2f, 0xef, 0x26, 0xae, 0xa5, 0x8f, 0x7d, 0x12, + 0x2a, 0x9f, 0x14, 0x8e, 0xa3, 0x9e, 0x4c, 0x28, + 0x4d, 0x4a, 0x3d, 0x12, 0x28, 0x12, 0x3c, 0x0e, + 0x39, 0xce, 0x02, 0x03, 0x6d, 0x08, 0x2e, 0xae, + 0xca, 0x8a, 0xd2, 0x9a, 0x51, 0xdf, 0x31, 0xdc, + 0xef, 0x0e, 0x2c, 0x11, 0x0c, 0x8a, 0x25, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0xca, 0x8a, 0xd2, 0x9a, + 0x2f, 0xee, 0x2b, 0xae, 0x09, 0x16, 0x6d, 0x0f, + 0x2f, 0xec, 0x02, 0x02, 0x6d, 0x08, 0x2c, 0x11, + 0x0c, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0xca, 0x8a, 0xd2, 0x9a, 0x2f, 0xef, 0x2b, 0xae, + 0x09, 0x16, 0x6d, 0x0f, 0x2f, 0xec, 0x02, 0x02, + 0x6d, 0x08, 0x2c, 0x11, 0x0c, 0x8a, 0x25, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0xca, 0x8a, 0xd2, 0x9a, + 0x2f, 0xee, 0x2b, 0xae, 0x09, 0x16, 0x6d, 0x0f, + 0x2f, 0xed, 0x02, 0x03, 0x6d, 0x08, 0x2c, 0x11, + 0x0c, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0x26, 0xef, 0x09, 0x16, 0x6d, 0x0f, 0x25, 0xec, + 0x02, 0x02, 0x68, 0x8b, 0x6d, 0x08, 0x25, 0x9b, + 0x68, 0xce, 0x02, 0x03, 0x2e, 0xae, 0xca, 0x8a, + 0xd2, 0x9a, 0x2c, 0x11, 0x39, 0x17, 0x61, 0xc1, + 0x0c, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0x3a, 0xef, 0x09, 0x16, 0x6d, 0x0f, 0x39, 0xec, + 0x6c, 0x08, 0x68, 0x8b, 0x25, 0x9b, 0x02, 0x02, + 0x68, 0xce, 0x69, 0x8a, 0x0f, 0x8b, 0x25, 0x9a, + 0x25, 0x9b, 0x69, 0xde, 0x78, 0xde, 0x68, 0x2f, + 0x29, 0xee, 0xd3, 0x83, 0x2c, 0x93, 0xfd, 0x09, + 0x02, 0x03, 0x6d, 0x08, 0x2e, 0xae, 0xca, 0x8a, + 0xd2, 0x9a, 0x71, 0xdf, 0xec, 0x0e, 0x28, 0x15, + 0x68, 0x8a, 0x25, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0x6d, 0x08, 0x2f, 0xef, 0x2c, 0x8a, 0x2c, 0x11, + 0x38, 0x8a, 0x3e, 0x8b, 0x2c, 0x9a, 0x25, 0x9b, + 0x69, 0xde, 0x6d, 0x0f, 0x26, 0xee, 0x3b, 0x83, + 0x62, 0x0e, 0x79, 0x14, 0x2c, 0x93, 0x40, 0xde, + 0x60, 0xdc, 0x48, 0x2e, 0xfe, 0x0e, 0x6b, 0xce, + 0xd6, 0xe0, 0x2c, 0x11, 0x30, 0x17, 0xf1, 0xc1, + 0x21, 0xc5, 0x61, 0xc5, 0x41, 0xc1, 0xfa, 0x08, + 0x21, 0xd2, 0xf1, 0xdc, 0x39, 0x08, 0x4d, 0xd2, + 0x42, 0x0e, 0x01, 0x8b, 0x2c, 0x9b, 0xe8, 0xce, + 0x61, 0xdd, 0x71, 0xdf, 0xeb, 0x12, 0xfd, 0x09, + 0x01, 0x88, 0x2c, 0x98, 0xeb, 0xde, 0x71, 0x12, + 0x79, 0x0e, 0x28, 0xd6, 0xf8, 0xde, 0x30, 0x15, + 0xe8, 0x12, 0x2c, 0x11, 0x30, 0x17, 0xf1, 0xc1, + 0x21, 0xc5, 0x61, 0xc5, 0x41, 0xc1, 0xfa, 0x08, + 0x21, 0xd2, 0xf1, 0xdc, 0x39, 0x08, 0x4d, 0xd2, + 0x42, 0x0e, 0x03, 0x8b, 0x2c, 0x9b, 0xe8, 0xce, + 0x61, 0xdd, 0x71, 0xdf, 0xeb, 0x12, 0xfd, 0x09, + 0x03, 0x88, 0x2c, 0x98, 0xeb, 0xde, 0x71, 0x12, + 0x79, 0x0e, 0x28, 0xd6, 0xf8, 0xde, 0x30, 0x15, + 0xe8, 0x12, 0x2c, 0x11, 0x30, 0x17, 0xf1, 0xc1, + 0x21, 0xc5, 0x61, 0xc5, 0x41, 0xc1, 0xfa, 0x08, + 0x21, 0xd2, 0xf1, 0xdc, 0x39, 0x08, 0x4d, 0xd2, + 0x42, 0x0e, 0x00, 0x8b, 0x2c, 0x9b, 0xe8, 0xce, + 0x61, 0xdd, 0x71, 0xdf, 0xeb, 0x12, 0xfd, 0x09, + 0x00, 0x88, 0x2c, 0x98, 0xeb, 0xde, 0x71, 0x12, + 0x79, 0x0e, 0x28, 0xd6, 0xf8, 0xde, 0x30, 0x15, + 0xe8, 0x12, 0x2c, 0x11, 0x30, 0x17, 0xf1, 0xc1, + 0x21, 0xc5, 0x61, 0xc5, 0x41, 0xc1, 0xfa, 0x08, + 0x21, 0xd2, 0xf1, 0xdc, 0x39, 0x08, 0x4d, 0xd2, + 0x42, 0x0e, 0x02, 0x8b, 0x2c, 0x9b, 0xe8, 0xce, + 0x61, 0xdd, 0x71, 0xdf, 0xeb, 0x12, 0xfd, 0x09, + 0x02, 0x88, 0x2c, 0x98, 0xeb, 0xde, 0x71, 0x12, + 0x79, 0x0e, 0x28, 0xd6, 0xf8, 0xde, 0x30, 0x15, + 0xe8, 0x12, 0x2c, 0x11, 0x39, 0x17, 0x2d, 0x8b, + 0xd4, 0x9b, 0x61, 0xc1, 0x6f, 0x08, 0x2b, 0x83, + 0x25, 0x93, 0x68, 0xce, 0xd7, 0x9b, 0x68, 0xce, + 0xad, 0x8a, 0x1d, 0x8b, 0xd4, 0x9b, 0x68, 0xce, + 0xd7, 0x9b, 0x68, 0xce, 0x2d, 0x8a, 0x02, 0x8b, + 0xd3, 0x9b, 0x68, 0xce, 0x12, 0x8b, 0x68, 0xce, + 0x3c, 0x8b, 0x68, 0xce, 0x34, 0x8b, 0x68, 0xce, + 0x2f, 0x8a, 0xfd, 0x09, 0x2b, 0x83, 0x6e, 0x08, + 0x25, 0x93, 0xfd, 0x09, 0x2c, 0x8b, 0xd5, 0x9b, + 0x68, 0xde, 0x6f, 0x07, 0x68, 0xce, 0x61, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0x2a, 0x7b, 0x2c, 0x8b, + 0x51, 0xc1, 0x2d, 0x73, 0xd5, 0x9b, 0xb1, 0xc1, + 0x98, 0x88, 0x39, 0x17, 0x2b, 0x98, 0x61, 0xc1, + 0x6d, 0x08, 0x68, 0xce, 0x1d, 0x8b, 0xd4, 0x9b, + 0x68, 0xce, 0xd7, 0x9b, 0x68, 0xce, 0x4e, 0x8b, + 0x2b, 0x9b, 0x68, 0xcd, 0xa1, 0x8b, 0x2b, 0x9b, + 0x68, 0xce, 0x52, 0x8a, 0xfb, 0x8b, 0x28, 0x9b, + 0x68, 0xce, 0x2d, 0x8a, 0xf9, 0x8b, 0x28, 0x9b, + 0x22, 0x9a, 0x68, 0xce, 0x62, 0x08, 0x9c, 0x8b, + 0x2b, 0x9b, 0x68, 0xce, 0x82, 0x8b, 0x2b, 0x9b, + 0x68, 0xce, 0x10, 0x8b, 0x6d, 0x08, 0x2a, 0x9b, + 0x68, 0xce, 0xc0, 0x8b, 0x2b, 0x9b, 0x4b, 0x0e, + 0x7b, 0xce, 0x47, 0x0e, 0x7a, 0x0e, 0x7e, 0x0e, + 0x6b, 0xce, 0x6b, 0xcf, 0x4a, 0x0e, 0xd5, 0xe0, + 0xbd, 0x89, 0xb8, 0x08, 0x28, 0x99, 0x6a, 0x12, + 0x65, 0x83, 0x1f, 0x93, 0xfd, 0x09, 0x6a, 0x12, + 0x01, 0x83, 0x1f, 0x93, 0x5a, 0x0e, 0x59, 0x0e, + 0x4d, 0x08, 0x7d, 0x08, 0xfd, 0x09, 0xb2, 0x0e, + 0xde, 0xec, 0x6d, 0x08, 0x25, 0x8b, 0xd5, 0x9b, + 0x22, 0x88, 0x2d, 0x98, 0x68, 0xce, 0x7d, 0x8b, + 0xd4, 0x9b, 0x68, 0xce, 0xd7, 0x9b, 0x68, 0xce, + 0x2f, 0x8b, 0xd4, 0x9b, 0x68, 0xce, 0xd7, 0x9b, + 0x68, 0xce, 0x2d, 0x8b, 0xd4, 0x9b, 0x68, 0xce, + 0xd7, 0x9b, 0x68, 0xce, 0x2e, 0x8a, 0x2c, 0x8b, + 0xd2, 0x9a, 0xd4, 0x9b, 0x68, 0xce, 0x2e, 0x8a, + 0xd7, 0x9b, 0x68, 0xce, 0x7d, 0x08, 0x3b, 0x8a, + 0xd5, 0x9a, 0x79, 0xce, 0xd2, 0x8b, 0x79, 0xcf, + 0x35, 0x8a, 0x2d, 0x8b, 0x79, 0xce, 0xd2, 0x8b, + 0x2e, 0x9b, 0x79, 0xcf, 0x3d, 0x8a, 0x7d, 0x08, + 0x79, 0xce, 0x79, 0xcf, 0x3f, 0x8a, 0x72, 0x0e, + 0x79, 0xce, 0xd2, 0x8b, 0x79, 0xcf, 0x5d, 0x8a, + 0x7b, 0x08, 0x79, 0xce, 0x09, 0x16, 0x2d, 0x8b, + 0x6b, 0x27, 0x09, 0x14, 0x68, 0x14, 0x18, 0x14, + 0x61, 0xdf, 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, + 0x29, 0x15, 0xe2, 0x61, 0xd2, 0x83, 0x21, 0xc5, + 0x2d, 0x8f, 0x01, 0xc5, 0x6a, 0x0e, 0x51, 0xc1, + 0x2d, 0x93, 0xa1, 0xc5, 0xd0, 0x9f, 0x81, 0xc5, + 0xc1, 0xc5, 0x29, 0xdd, 0x2d, 0x0f, 0x23, 0xef, + 0x1d, 0x08, 0x7c, 0x08, 0x6e, 0x12, 0x71, 0x2e, + 0xc8, 0xd6, 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, + 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, + 0x2c, 0x11, 0x2b, 0x0e, 0x6c, 0x12, 0x2d, 0xde, + 0xcd, 0x08, 0x2a, 0x0e, 0x0d, 0xde, 0x24, 0x0e, + 0x0c, 0x0f, 0x2f, 0xee, 0x28, 0xae, 0x2c, 0x8a, + 0x25, 0x80, 0xd0, 0x9a, 0x2d, 0x90, 0x0d, 0xdf, + 0x5d, 0x08, 0x9f, 0x12, 0x2b, 0x0e, 0xad, 0xdd, + 0x92, 0x0b, 0x8f, 0x12, 0x27, 0x0e, 0x7d, 0xde, + 0x0c, 0x8c, 0x8c, 0x1c, 0xd5, 0x9c, 0x15, 0x12, + 0x4f, 0xde, 0x12, 0x0b, 0x4c, 0x1c, 0x05, 0x12, + 0x8f, 0x38, 0x8b, 0x33, 0x8c, 0x1b, 0x8d, 0x1f, + 0x2f, 0xef, 0xe2, 0xa1, 0x0c, 0x0b, 0x08, 0x2e, + 0xad, 0x05, 0x24, 0xef, 0x8d, 0x1f, 0x05, 0xea, + 0x2d, 0x9f, 0x1d, 0x08, 0xac, 0x2e, 0x2b, 0x0e, + 0xad, 0xcd, 0xe9, 0xa1, 0x8d, 0x1f, 0xd4, 0xeb, + 0x6f, 0xde, 0x1d, 0x08, 0xac, 0xde, 0x7d, 0x08, + 0x4f, 0xdf, 0x5d, 0x08, 0x63, 0x3c, 0x68, 0x27, + 0x43, 0x3c, 0x60, 0x26, 0x4a, 0x27, 0x45, 0x12, + 0x7d, 0x08, 0x45, 0x0c, 0xa5, 0x0d, 0x6b, 0x27, + 0x63, 0x3c, 0x68, 0x27, 0x7d, 0x08, 0x6f, 0xc7, + 0x65, 0x12, 0x63, 0x3c, 0x68, 0x27, 0x82, 0x0e, + 0x2f, 0xe6, 0x92, 0x0e, 0x1c, 0x0e, 0x6f, 0xce, + 0x8d, 0x1f, 0xc8, 0xea, 0x27, 0xae, 0x1d, 0x08, + 0x82, 0x0e, 0x2f, 0xe6, 0x92, 0x0e, 0x39, 0xde, + 0x1c, 0x0e, 0x8d, 0x1f, 0x3f, 0xc7, 0xd4, 0xea, + 0x3e, 0x12, 0x2b, 0x0e, 0xad, 0xdd, 0x3c, 0x0c, + 0x27, 0x0e, 0xe0, 0xa1, 0x78, 0x14, 0x21, 0xc5, + 0x01, 0xc5, 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, + 0xc1, 0xc5, 0x3d, 0x80, 0xe7, 0x0e, 0x4d, 0x0f, + 0xd0, 0x90, 0x2f, 0xea, 0x02, 0xaf, 0x6a, 0x0e, + 0x29, 0xdd, 0x2d, 0x0f, 0x2f, 0xef, 0x07, 0xaf, + 0x2b, 0x0e, 0x9b, 0x12, 0x0d, 0xde, 0x92, 0x0b, + 0x0a, 0x0e, 0x8b, 0x12, 0x2f, 0xde, 0xbd, 0x08, + 0x8f, 0x1c, 0x04, 0x0e, 0x2d, 0x22, 0x3f, 0xdf, + 0x2d, 0x21, 0x22, 0x0d, 0x0b, 0x0e, 0x1f, 0xdd, + 0x7c, 0x12, 0x72, 0x0b, 0x6c, 0x12, 0x6c, 0x1c, + 0x08, 0x8f, 0x07, 0x0e, 0xd5, 0x9f, 0x70, 0x16, + 0xac, 0xde, 0xf3, 0x0e, 0xaf, 0x1c, 0x5e, 0x12, + 0x3e, 0x12, 0x52, 0x0b, 0x3c, 0x0b, 0x4e, 0x12, + 0x2e, 0x0c, 0x6b, 0x38, 0x4f, 0xde, 0x52, 0x89, + 0x3b, 0x2e, 0x09, 0x0e, 0x4f, 0xde, 0x2d, 0x99, + 0x85, 0x33, 0x01, 0x0e, 0x4a, 0x26, 0xff, 0x0f, + 0x2f, 0xe7, 0xb5, 0xae, 0x4c, 0x0f, 0x25, 0xee, + 0x8e, 0x1b, 0x6e, 0x1b, 0x89, 0x33, 0xad, 0x08, + 0x6d, 0x08, 0x70, 0xea, 0xaa, 0xae, 0x7b, 0x16, + 0x4f, 0x0f, 0x2f, 0xee, 0xdb, 0xa1, 0x2d, 0x7b, + 0x8e, 0x1b, 0x2d, 0x73, 0x6f, 0x1b, 0x89, 0x33, + 0x6d, 0x08, 0x2f, 0xea, 0x67, 0xae, 0x11, 0x12, + 0x1c, 0x0e, 0x4e, 0x14, 0x13, 0x12, 0x6e, 0xde, + 0xf9, 0x08, 0x7e, 0xdf, 0xdd, 0x08, 0x5d, 0x08, + 0x71, 0xcf, 0x61, 0xcc, 0x7e, 0xde, 0x6e, 0xdf, + 0x61, 0xcd, 0x49, 0x16, 0x79, 0xcd, 0x61, 0xdc, + 0x7d, 0x08, 0xc1, 0xdf, 0xd9, 0x27, 0xa1, 0xd2, + 0x6c, 0x08, 0x63, 0x26, 0x28, 0x83, 0xf1, 0x2e, + 0x60, 0xc6, 0x41, 0xdd, 0x3f, 0x83, 0x2d, 0x93, + 0x61, 0xd2, 0x6c, 0x0f, 0x3e, 0xee, 0xcc, 0x1b, + 0x55, 0x27, 0x6f, 0x0f, 0x29, 0xef, 0xcb, 0x12, + 0xda, 0x12, 0x21, 0xae, 0x6c, 0x08, 0xa8, 0x08, + 0x6b, 0x26, 0xa1, 0x2e, 0xb5, 0xdf, 0xa5, 0xde, + 0x65, 0x3e, 0x4c, 0x1b, 0xcb, 0x3e, 0x6c, 0x1b, + 0xc9, 0x3e, 0x43, 0x12, 0x5d, 0x08, 0x4d, 0x3c, + 0x4a, 0x27, 0x62, 0x12, 0x7d, 0x08, 0x4c, 0xce, + 0x6d, 0x3c, 0x68, 0x27, 0x82, 0x0e, 0x2f, 0xe6, + 0x92, 0x0e, 0x6c, 0xcf, 0x79, 0x16, 0x6c, 0x0e, + 0x8d, 0x1f, 0x79, 0x14, 0x2e, 0xeb, 0x3f, 0x0e, + 0x92, 0xa1, 0x0b, 0x0e, 0x1f, 0xdd, 0x07, 0x0e, + 0x7d, 0x16, 0x0b, 0x0e, 0x2f, 0x0c, 0x2e, 0x2e, + 0x2f, 0xcd, 0xb4, 0xae, 0x3d, 0x81, 0xc1, 0x12, + 0xcc, 0x0e, 0xd0, 0x91, 0x12, 0xde, 0x7d, 0x08, + 0x62, 0xdf, 0x5d, 0x08, 0x61, 0xcf, 0x11, 0xcc, + 0x62, 0xdf, 0x12, 0xde, 0x61, 0xcd, 0x13, 0xcd, + 0x61, 0xdf, 0x6d, 0x3c, 0x68, 0x27, 0x7d, 0x08, + 0x6c, 0xce, 0x61, 0xdc, 0x6d, 0x3c, 0x68, 0x27, + 0x7d, 0x08, 0x6c, 0xcf, 0x61, 0xdd, 0x6d, 0x3c, + 0x68, 0x27, 0x6c, 0xcc, 0x43, 0xdd, 0x4d, 0x3c, + 0x4a, 0x27, 0x82, 0x0e, 0x2f, 0xe6, 0x92, 0x0e, + 0xac, 0x0e, 0x4c, 0xcd, 0x39, 0x0e, 0x8d, 0x1f, + 0xf3, 0xea, 0x0b, 0x0e, 0x65, 0x12, 0x1f, 0xdd, + 0x07, 0x0e, 0xae, 0x0c, 0x0b, 0x0e, 0xae, 0x2e, + 0x7d, 0x16, 0x2e, 0x0f, 0xaf, 0xcd, 0x49, 0xee, + 0x4b, 0xae, 0x4c, 0x0f, 0x17, 0xef, 0x7b, 0x16, + 0x4d, 0x0f, 0x1a, 0xef, 0x8f, 0x1b, 0x6c, 0x1b, + 0x89, 0x33, 0xad, 0x08, 0x6d, 0x08, 0x2f, 0xea, + 0x06, 0xae, 0x63, 0xde, 0x3f, 0x83, 0x13, 0xdf, + 0x2d, 0x93, 0x61, 0xcf, 0x11, 0xcc, 0x11, 0xdc, + 0x61, 0xd2, 0x7e, 0x12, 0x41, 0xdf, 0x72, 0x0b, + 0x5b, 0x12, 0x52, 0x0b, 0x6c, 0x0f, 0x6e, 0x12, + 0x2e, 0xef, 0x1b, 0x12, 0x2a, 0xae, 0x6b, 0x3e, + 0x41, 0xd2, 0x4f, 0x0f, 0x2e, 0xee, 0x6c, 0x1b, + 0x19, 0x12, 0x6e, 0x12, 0x11, 0xcd, 0x7d, 0x08, + 0x6d, 0x3c, 0x68, 0x27, 0x82, 0x0e, 0x2f, 0xe6, + 0x92, 0x0e, 0xac, 0x0e, 0x6c, 0xce, 0x8d, 0x1f, + 0x2e, 0xeb, 0x3c, 0x0e, 0xf6, 0xa1, 0x0b, 0x0e, + 0x65, 0x12, 0x1f, 0xdd, 0x07, 0x0e, 0xac, 0x0c, + 0x0b, 0x0e, 0xae, 0x2e, 0xaf, 0xcd, 0x06, 0xae, + 0x8f, 0x1b, 0x6f, 0x1b, 0x89, 0x33, 0x7d, 0x08, + 0x6d, 0x08, 0x2f, 0xea, 0x37, 0xae, 0x63, 0xde, + 0xbd, 0x08, 0x13, 0xdf, 0x5d, 0x08, 0x61, 0xcf, + 0x11, 0xcc, 0xa1, 0xdf, 0xad, 0x3c, 0xa4, 0x27, + 0xac, 0xce, 0x41, 0xdc, 0x4d, 0x3c, 0x4a, 0x27, + 0x82, 0x0e, 0x2f, 0xe6, 0x92, 0x0e, 0x7c, 0x0e, + 0x4c, 0xcf, 0x3f, 0x0e, 0x8d, 0x1f, 0xc1, 0xea, + 0x0b, 0x0e, 0x68, 0x12, 0x1f, 0xdd, 0x07, 0x0e, + 0x7f, 0x0c, 0x0b, 0x0e, 0x7e, 0x2e, 0x7d, 0x16, + 0x2c, 0x0f, 0x7f, 0xcd, 0x29, 0xef, 0x6c, 0x0d, + 0x2f, 0xae, 0x6d, 0x08, 0x7a, 0x08, 0x71, 0x2e, + 0xc8, 0xd6, 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, + 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, + 0x2c, 0x11, 0x2d, 0x61, 0x21, 0xc5, 0x01, 0xc5, + 0x51, 0xc1, 0x59, 0x12, 0xa1, 0xc5, 0x6a, 0x0e, + 0x81, 0xc5, 0xab, 0x12, 0xc1, 0xc5, 0x35, 0xde, + 0x4b, 0x0e, 0x89, 0xde, 0xb8, 0x12, 0x4b, 0xdd, + 0x78, 0x0e, 0x28, 0xde, 0x69, 0x08, 0x67, 0x28, + 0x7d, 0x12, 0x7c, 0x0d, 0x6b, 0x23, 0x7c, 0x2e, + 0xd2, 0x8f, 0x6f, 0x0f, 0x2d, 0x9f, 0x3d, 0xef, + 0x8e, 0x0c, 0x1d, 0x08, 0x2d, 0x05, 0x05, 0xee, + 0x08, 0xdf, 0x2d, 0x8e, 0x78, 0xde, 0x3d, 0x08, + 0x05, 0x1c, 0x75, 0x0d, 0xd2, 0x9e, 0x0d, 0x36, + 0x08, 0x27, 0x07, 0x3c, 0x08, 0xae, 0x6e, 0x0f, + 0x21, 0xef, 0x8e, 0x0c, 0x2d, 0x05, 0x28, 0xde, + 0x37, 0xee, 0x08, 0xdf, 0x1d, 0x08, 0x05, 0x1c, + 0x25, 0x0d, 0x0d, 0x27, 0x07, 0x3c, 0x35, 0xae, + 0x6c, 0x0f, 0x2e, 0xee, 0x0f, 0x34, 0x39, 0xae, + 0x08, 0xde, 0x8e, 0x0c, 0x2d, 0x05, 0x1d, 0x08, + 0x29, 0xee, 0x05, 0x1d, 0x07, 0x3c, 0x21, 0xae, + 0x0c, 0x26, 0x07, 0x3c, 0x24, 0xae, 0x08, 0xde, + 0x07, 0x3c, 0x2b, 0xae, 0x18, 0xdf, 0x0d, 0x08, + 0x1c, 0x26, 0x0d, 0x27, 0x07, 0x3c, 0xb8, 0x0e, + 0x25, 0x8e, 0x2d, 0x9e, 0xab, 0x0e, 0x2a, 0x2e, + 0x49, 0x28, 0x3d, 0xdf, 0x5a, 0x0e, 0x2d, 0xde, + 0x2f, 0x37, 0x25, 0x8d, 0x45, 0xcd, 0x74, 0xde, + 0x2d, 0x9d, 0x79, 0x2e, 0x74, 0xce, 0x0a, 0xde, + 0x7c, 0x08, 0x71, 0x2e, 0x54, 0x0e, 0x1a, 0x2e, + 0x09, 0x2e, 0x2e, 0xc6, 0x0e, 0xcb, 0xc8, 0xd6, + 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, 0x08, 0xd6, + 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, + 0xf9, 0x08, 0x21, 0xc5, 0x3d, 0x17, 0x01, 0xc5, + 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, 0xc1, 0xc5, + 0x25, 0x81, 0x21, 0xc1, 0xe1, 0x0e, 0x1d, 0x80, + 0x2d, 0x91, 0x71, 0xc2, 0xd0, 0x90, 0x61, 0xcd, + 0x6a, 0x0e, 0x29, 0xdd, 0x64, 0x0e, 0x21, 0xcc, + 0x2d, 0x0f, 0x2f, 0xef, 0x84, 0xaf, 0x0a, 0x8e, + 0x3d, 0x08, 0xd5, 0x9e, 0x5d, 0x08, 0x4d, 0xde, + 0x21, 0xdc, 0x2b, 0x0e, 0x0d, 0xde, 0x1f, 0xdd, + 0x2d, 0x8e, 0x29, 0x9e, 0x2b, 0x38, 0x2d, 0x1f, + 0x2f, 0xef, 0xb7, 0xaf, 0x33, 0x8b, 0x4e, 0x12, + 0x42, 0x0e, 0x2d, 0x9b, 0x7b, 0x2f, 0x2f, 0xe6, + 0xcb, 0xae, 0x69, 0x0e, 0x69, 0xde, 0x6d, 0x0f, + 0x28, 0xee, 0x6c, 0x0f, 0x51, 0xcf, 0x09, 0xee, + 0x98, 0xae, 0x0b, 0x0e, 0xaf, 0xdd, 0x07, 0x0e, + 0xad, 0x0f, 0x2f, 0xef, 0xa8, 0xaf, 0x2e, 0x1f, + 0x2f, 0xea, 0xaf, 0xaf, 0x7a, 0x12, 0x6a, 0x12, + 0x43, 0x12, 0xae, 0x0c, 0xbe, 0x12, 0x6b, 0xc6, + 0x43, 0x12, 0x13, 0x12, 0x21, 0x0e, 0x6b, 0xc6, + 0x32, 0x8a, 0x5f, 0x8b, 0x43, 0x12, 0x63, 0x9a, + 0xd5, 0x9b, 0x6b, 0xc6, 0xae, 0xc6, 0x2f, 0xe6, + 0x32, 0x0e, 0x61, 0xdd, 0x1c, 0x08, 0x69, 0x0e, + 0x19, 0xce, 0x25, 0x8d, 0x11, 0xcf, 0x61, 0xdd, + 0x6a, 0x0e, 0x19, 0xde, 0x64, 0x0e, 0x1d, 0x0f, + 0x0c, 0xeb, 0x71, 0xdc, 0x4f, 0x12, 0x2d, 0x61, + 0xb4, 0xb1, 0x61, 0xdd, 0x6a, 0x0e, 0x19, 0xde, + 0x64, 0x0e, 0x19, 0x0f, 0x3a, 0xef, 0x2d, 0x1f, + 0x38, 0xeb, 0x4b, 0x34, 0x12, 0x12, 0x19, 0x2e, + 0x6e, 0xdf, 0x1e, 0xde, 0x7e, 0x12, 0x13, 0x12, + 0x6e, 0xc6, 0x11, 0xdd, 0x62, 0x12, 0x6e, 0x2e, + 0x49, 0xc6, 0x61, 0xdf, 0x6f, 0x0e, 0x22, 0x0e, + 0x61, 0xcf, 0x2f, 0xe6, 0x32, 0x0e, 0x1a, 0x0e, + 0x5e, 0xce, 0x0b, 0x0e, 0x1f, 0xdd, 0x7e, 0x12, + 0x6e, 0x12, 0x11, 0xdc, 0x72, 0x0b, 0x6f, 0x1b, + 0x18, 0x0e, 0x07, 0x0e, 0x1e, 0xde, 0x5f, 0xde, + 0x4e, 0x12, 0x4c, 0x0d, 0x4a, 0x2e, 0x6d, 0x33, + 0x1d, 0x05, 0x30, 0xef, 0x6d, 0x1f, 0x15, 0xea, + 0x6d, 0x08, 0x2d, 0x08, 0x31, 0xdf, 0x19, 0x2e, + 0x3d, 0x2e, 0x0b, 0x0e, 0x31, 0xcf, 0x21, 0xdc, + 0x28, 0x0e, 0x1d, 0xce, 0x1f, 0xdd, 0x19, 0x28, + 0x1f, 0xcd, 0x07, 0x0e, 0x1d, 0x0f, 0x14, 0xea, + 0x31, 0xdd, 0x3a, 0x0e, 0x2c, 0xde, 0x34, 0x0e, + 0x2d, 0x0f, 0x1e, 0xef, 0x39, 0x0e, 0x2d, 0x08, + 0x2c, 0xce, 0xf7, 0xae, 0x6d, 0x1f, 0xc8, 0xeb, + 0x3b, 0xde, 0x2d, 0x08, 0x8b, 0xdf, 0x5c, 0x12, + 0x55, 0x0d, 0xb7, 0x12, 0xb5, 0x0c, 0x4f, 0x0e, + 0x3b, 0xde, 0x54, 0x27, 0x85, 0x0d, 0xac, 0x12, + 0xa5, 0x0c, 0xba, 0x12, 0xa7, 0x27, 0x53, 0x12, + 0x62, 0x0e, 0xaa, 0xc6, 0x2f, 0xe6, 0x72, 0x0e, + 0x2c, 0x0e, 0x6d, 0x1f, 0xc1, 0xea, 0x6d, 0x12, + 0x6f, 0x0c, 0x2c, 0x0c, 0xe1, 0xa1, 0x2d, 0x08, + 0x3b, 0xde, 0x62, 0x0e, 0xab, 0xdf, 0xbc, 0x12, + 0x33, 0x12, 0xac, 0xc6, 0x2f, 0xe6, 0x72, 0x0e, + 0x4f, 0x0e, 0x2c, 0x0e, 0x6d, 0x1f, 0xd8, 0xea, + 0x6d, 0x12, 0x6f, 0x0c, 0x2c, 0x0c, 0x96, 0xa1, + 0x12, 0x0e, 0x1e, 0x0f, 0x28, 0xe7, 0x21, 0xdd, + 0x29, 0x0e, 0x6d, 0xde, 0x26, 0xae, 0x61, 0xdd, + 0x4f, 0x12, 0x71, 0xdc, 0x2f, 0x08, 0x2d, 0x61, + 0x7a, 0xb1, 0x31, 0xdd, 0x39, 0x0e, 0x2c, 0xce, + 0x29, 0xae, 0x6f, 0x0f, 0x2f, 0xee, 0xb5, 0xae, + 0x0a, 0x8e, 0xd5, 0x9e, 0x3d, 0xde, 0xd2, 0x8e, + 0x2e, 0x9e, 0x2c, 0x2f, 0x2f, 0xe6, 0xbd, 0xae, + 0x21, 0xdd, 0x2a, 0x0e, 0x2d, 0xde, 0x2d, 0x0f, + 0x2f, 0xea, 0xa7, 0xae, 0x21, 0xdd, 0x12, 0x12, + 0x1d, 0x2e, 0x0b, 0x0e, 0x2e, 0xdf, 0x1e, 0xde, + 0x3e, 0x12, 0x23, 0xc6, 0x21, 0xdd, 0x3d, 0x08, + 0x29, 0x0e, 0x3d, 0xce, 0x2e, 0x0e, 0x3d, 0xce, + 0x24, 0x0e, 0xdd, 0x2e, 0x2d, 0x34, 0x22, 0xc6, + 0x21, 0xdf, 0x2f, 0x0e, 0x21, 0xcf, 0x1f, 0xdd, + 0x07, 0x0e, 0x58, 0xae, 0x11, 0xdd, 0x1a, 0x0e, + 0x1e, 0xde, 0x1d, 0x0f, 0x0d, 0xeb, 0x71, 0xdc, + 0x4f, 0x12, 0x2d, 0x61, 0x11, 0xb1, 0x61, 0xdd, + 0x6a, 0x0e, 0x19, 0xde, 0x64, 0x0e, 0x19, 0x0f, + 0x3b, 0xef, 0x12, 0x12, 0x19, 0x2e, 0x6e, 0xdf, + 0x1e, 0xde, 0x7e, 0x12, 0x13, 0x12, 0x6e, 0xc6, + 0x41, 0xdd, 0x6d, 0x08, 0x4a, 0x0e, 0x12, 0x12, + 0x78, 0x24, 0x6b, 0xce, 0x44, 0x0e, 0x1b, 0x2e, + 0x22, 0x0e, 0x6e, 0xc6, 0x2f, 0xe6, 0x32, 0x0e, + 0x2f, 0x89, 0x2c, 0xae, 0x0b, 0x0e, 0x1f, 0xdd, + 0x7e, 0x12, 0x6e, 0x12, 0x11, 0xdc, 0x72, 0x0b, + 0x6f, 0x1b, 0x18, 0x0e, 0x07, 0x0e, 0x1e, 0xde, + 0xaf, 0xde, 0x4e, 0x12, 0x4c, 0x0d, 0x45, 0x2e, + 0x6d, 0x33, 0x1d, 0x05, 0x64, 0xef, 0x6d, 0x1f, + 0x48, 0xea, 0x3d, 0x08, 0x2d, 0x08, 0x1c, 0x2e, + 0x5d, 0x2e, 0x0b, 0x0e, 0x51, 0xcf, 0x21, 0xdc, + 0x28, 0x0e, 0x1d, 0xce, 0x1f, 0xdd, 0x1c, 0x28, + 0x2e, 0x12, 0x1f, 0xcd, 0x22, 0x0e, 0x07, 0x0e, + 0x2e, 0x0f, 0x24, 0xe6, 0x61, 0xdd, 0x4f, 0x12, + 0x71, 0xdc, 0x2d, 0x61, 0x37, 0xb1, 0x0b, 0x0e, + 0x1f, 0xdd, 0x07, 0x0e, 0x1d, 0x0f, 0x0e, 0xea, + 0xf9, 0x08, 0x21, 0xd2, 0x2d, 0x0f, 0x32, 0xee, + 0x0a, 0x8e, 0xd5, 0x9e, 0x3d, 0xde, 0xd2, 0x8e, + 0x2e, 0x9e, 0x2c, 0x2f, 0x35, 0xe7, 0x21, 0xdd, + 0x2a, 0x0e, 0x3d, 0xde, 0x24, 0x0e, 0x3d, 0x0f, + 0x3f, 0xeb, 0x12, 0x12, 0x1d, 0x2e, 0x2e, 0xdf, + 0x1e, 0xde, 0x69, 0x34, 0x3e, 0x12, 0x23, 0xc6, + 0x21, 0xdd, 0xdd, 0x2e, 0x62, 0xc6, 0x21, 0xdf, + 0x2f, 0x0e, 0x21, 0xcf, 0x72, 0xcb, 0x0b, 0x0e, + 0x1f, 0xdd, 0x07, 0x0e, 0x1d, 0x0f, 0x17, 0xea, + 0x2d, 0x08, 0x0b, 0x0e, 0x2f, 0xcd, 0x31, 0xdc, + 0x38, 0x0e, 0x2c, 0xce, 0x1e, 0xae, 0x6d, 0x1f, + 0x94, 0xeb, 0xfb, 0xde, 0x93, 0x12, 0x2d, 0x08, + 0x8b, 0xdf, 0x30, 0x12, 0x35, 0x0d, 0xb7, 0x12, + 0xb5, 0x0c, 0x4f, 0x0e, 0xfb, 0xde, 0x34, 0x27, + 0x85, 0x0d, 0xa0, 0x12, 0xa5, 0x0c, 0xbc, 0x12, + 0xa7, 0x27, 0x36, 0x12, 0x62, 0x0e, 0xac, 0xc6, + 0x2f, 0xe6, 0x72, 0x0e, 0x2c, 0x0e, 0x6d, 0x1f, + 0xc1, 0xea, 0x3d, 0x12, 0x3f, 0x0c, 0x2c, 0x0c, + 0xb2, 0xa1, 0x33, 0x12, 0x2d, 0x08, 0x8b, 0xde, + 0x62, 0x0e, 0xab, 0xdf, 0xb7, 0x12, 0x8c, 0x12, + 0xa7, 0xc6, 0x2f, 0xe6, 0x72, 0x0e, 0x4f, 0x0e, + 0x2c, 0x0e, 0x6d, 0x1f, 0xd8, 0xea, 0x3d, 0x12, + 0x3f, 0x0c, 0x2c, 0x0c, 0xa0, 0xa1, 0x2d, 0x08, + 0x21, 0xcf, 0x61, 0xdf, 0x78, 0x08, 0x71, 0x2e, + 0x28, 0xd7, 0xc8, 0xd6, 0x3d, 0x15, 0x88, 0xd6, + 0xa8, 0xd6, 0x58, 0xd7, 0x08, 0xd6, 0x28, 0xd6, + 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, 0x2d, 0x61, + 0x6a, 0x0e, 0x21, 0xc5, 0xf8, 0x08, 0x01, 0xc5, + 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, 0x0d, 0x84, + 0xc1, 0xc5, 0xe6, 0x0e, 0xd0, 0x94, 0x41, 0xc2, + 0x99, 0xdd, 0x9d, 0x0f, 0x2f, 0xef, 0x3d, 0xaf, + 0x0e, 0x8e, 0x3d, 0x08, 0xd5, 0x9e, 0x7d, 0x08, + 0x6d, 0xde, 0x26, 0x12, 0x2b, 0x0e, 0x0d, 0xde, + 0x2d, 0x8e, 0xcf, 0x12, 0x25, 0x9e, 0x09, 0x0e, + 0x4f, 0xde, 0x29, 0x38, 0x2d, 0x1f, 0x2f, 0xea, + 0xd2, 0xae, 0x06, 0x12, 0x08, 0x0e, 0xdf, 0xde, + 0x03, 0xde, 0xdc, 0x0d, 0xdf, 0x2e, 0x03, 0x12, + 0x0b, 0x0e, 0x7f, 0xdd, 0xaf, 0x8c, 0x68, 0x12, + 0x2f, 0x1c, 0x78, 0x14, 0x2d, 0x9c, 0x72, 0x0b, + 0x4f, 0x2f, 0x3a, 0xef, 0x01, 0xd2, 0x0d, 0x0f, + 0x3c, 0xef, 0x3c, 0x83, 0x01, 0xd2, 0x0c, 0x0f, + 0x29, 0xef, 0x11, 0x12, 0x1c, 0x0e, 0x2b, 0xae, + 0x01, 0xd2, 0x0f, 0x0f, 0x27, 0xef, 0x11, 0x12, + 0x1f, 0x0e, 0xa1, 0x12, 0x0e, 0x12, 0xae, 0x0e, + 0x27, 0xae, 0x01, 0xd2, 0x0f, 0x0f, 0x3d, 0xee, + 0xa1, 0x12, 0x11, 0x12, 0x01, 0x12, 0xae, 0x0e, + 0x1f, 0x0e, 0x0c, 0x0e, 0x52, 0x89, 0x28, 0x83, + 0xb1, 0xd2, 0x2d, 0x99, 0xb3, 0x0e, 0x5b, 0x26, + 0xbf, 0x0f, 0x38, 0xe7, 0x5c, 0xae, 0x3c, 0x83, + 0x01, 0xd2, 0x0c, 0x0f, 0x2a, 0xef, 0x11, 0x12, + 0xa1, 0x12, 0xac, 0x0e, 0x1f, 0x0e, 0x05, 0x12, + 0xc3, 0xa1, 0x01, 0xd2, 0x0f, 0x0f, 0xc8, 0xef, + 0x11, 0x12, 0xa1, 0x12, 0xae, 0x0e, 0x19, 0x0e, + 0x05, 0x12, 0xc8, 0xa1, 0x5c, 0x0f, 0x05, 0xef, + 0x41, 0xd2, 0x4f, 0x0f, 0x08, 0xef, 0x2e, 0x1b, + 0x6f, 0x1b, 0x29, 0x33, 0x4d, 0x08, 0x2f, 0xea, + 0x3c, 0xae, 0x02, 0xde, 0xa7, 0x12, 0x52, 0xdf, + 0x6f, 0x12, 0x7a, 0x12, 0x1a, 0x12, 0x22, 0x0e, + 0x65, 0xc6, 0x67, 0x12, 0x09, 0xc6, 0x2f, 0xe6, + 0x32, 0x0e, 0xdf, 0x0e, 0x4c, 0x0e, 0x2d, 0x1f, + 0xdc, 0xea, 0x7d, 0x16, 0x33, 0x12, 0x3b, 0x0e, + 0xbb, 0x12, 0x4f, 0x0c, 0x2b, 0x28, 0x2c, 0xcd, + 0x36, 0x12, 0x38, 0x0e, 0x2c, 0xde, 0x2b, 0x2e, + 0x2c, 0xce, 0x39, 0x08, 0xaf, 0xae, 0x2e, 0x1b, + 0x6e, 0x1b, 0x29, 0x33, 0xbd, 0x08, 0x2f, 0xea, + 0x36, 0xae, 0x29, 0x83, 0x62, 0xde, 0x61, 0xcf, + 0x62, 0xdf, 0x61, 0xcc, 0x62, 0xdc, 0x61, 0xcd, + 0x62, 0xdd, 0xd9, 0x0e, 0x61, 0xc2, 0x6f, 0xde, + 0x22, 0x0e, 0x4e, 0xde, 0x7b, 0x12, 0x47, 0x12, + 0x6b, 0xc6, 0x45, 0xdf, 0x65, 0xde, 0x7b, 0x12, + 0x47, 0x12, 0x6b, 0xc6, 0x2f, 0xe6, 0x32, 0x0e, + 0xbc, 0x0e, 0x2d, 0x1f, 0xc5, 0xea, 0x04, 0x12, + 0x7d, 0x16, 0x0e, 0x0c, 0x33, 0x12, 0x2f, 0x28, + 0x3b, 0x0e, 0x28, 0x83, 0x2c, 0xcd, 0x36, 0x12, + 0x38, 0x0e, 0x2c, 0xde, 0x2f, 0x2e, 0x2c, 0xce, + 0x21, 0xd2, 0x2e, 0x0f, 0x2f, 0xef, 0xbc, 0x0d, + 0x25, 0x8f, 0x2d, 0x9f, 0x63, 0xae, 0x5c, 0x0f, + 0x0e, 0xef, 0x41, 0xd2, 0x4d, 0x0f, 0x0d, 0xef, + 0x2f, 0x1b, 0x6c, 0x1b, 0x29, 0x33, 0x6d, 0x08, + 0x2f, 0xea, 0x21, 0xae, 0x72, 0xd7, 0x22, 0x0e, + 0x18, 0x12, 0x08, 0x12, 0x77, 0x12, 0x08, 0xc6, + 0x2f, 0xe6, 0x32, 0x0e, 0x6c, 0x0e, 0x2d, 0x1f, + 0xdb, 0xea, 0x7d, 0x16, 0x33, 0x12, 0x3b, 0x0e, + 0xb9, 0x12, 0x6c, 0x0c, 0x29, 0x28, 0x2c, 0xcd, + 0x36, 0x12, 0x38, 0x0e, 0x2c, 0xde, 0x29, 0x2e, + 0x2c, 0xce, 0x3f, 0x08, 0x07, 0xae, 0x6f, 0x1b, + 0x4d, 0x12, 0x5c, 0x12, 0x4f, 0x1b, 0x49, 0x33, + 0xbd, 0x08, 0x2f, 0xea, 0x3c, 0xae, 0x22, 0xde, + 0x21, 0xcf, 0x22, 0xdf, 0xdf, 0x0e, 0x21, 0xcc, + 0x6f, 0xde, 0x42, 0x0e, 0x2e, 0xde, 0x39, 0x12, + 0x67, 0x12, 0x29, 0xc6, 0x2f, 0xe6, 0x52, 0x0e, + 0xbc, 0x0e, 0x4d, 0x1f, 0xdc, 0xea, 0x04, 0x12, + 0x7d, 0x16, 0x0f, 0x0c, 0x33, 0x12, 0x2f, 0x28, + 0x3b, 0x0e, 0x2c, 0xcd, 0x36, 0x12, 0x38, 0x0e, + 0x2c, 0xde, 0x2f, 0x2e, 0x2c, 0xce, 0x21, 0xd2, + 0x2c, 0x0f, 0x2f, 0xef, 0xbc, 0x0d, 0x39, 0x08, + 0x23, 0x12, 0x2b, 0x0e, 0x2d, 0xdd, 0x3d, 0x2f, + 0x25, 0xeb, 0x2d, 0x08, 0xcb, 0x0e, 0x98, 0x0e, + 0x23, 0xcd, 0x26, 0xce, 0x2f, 0xae, 0xbd, 0x08, + 0x7b, 0x08, 0x64, 0x12, 0x71, 0x2e, 0xc8, 0xd6, + 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, 0x08, 0xd6, + 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, + 0x6a, 0x0e, 0x21, 0xc5, 0x01, 0xc5, 0x51, 0xc1, + 0xa1, 0xc5, 0x81, 0xc5, 0xd2, 0x84, 0xc1, 0xc5, + 0xe3, 0x0e, 0x2d, 0x94, 0xf9, 0xdd, 0xfd, 0x0f, + 0x2f, 0xef, 0x95, 0xae, 0x7a, 0x0e, 0x28, 0xdd, + 0x2d, 0x0f, 0x2f, 0xef, 0x9e, 0xae, 0x2b, 0x0e, + 0x3c, 0x08, 0x2d, 0xde, 0x0d, 0xdf, 0x7d, 0x14, + 0x0c, 0x0c, 0x2a, 0x0e, 0x2d, 0xde, 0x2c, 0x24, + 0xcd, 0x22, 0x7c, 0x16, 0x3b, 0x0e, 0xc2, 0x0e, + 0x7c, 0xdd, 0xc2, 0x0d, 0x08, 0x28, 0x20, 0x12, + 0x2b, 0x0e, 0x30, 0x12, 0x2d, 0xde, 0x38, 0x0e, + 0x4c, 0xde, 0x9d, 0x12, 0x16, 0xde, 0x2b, 0x0e, + 0x2d, 0xdd, 0x3b, 0x12, 0x3c, 0x0d, 0x0d, 0x23, + 0x28, 0x12, 0x6f, 0x12, 0x2c, 0x0b, 0x6c, 0x0b, + 0x3e, 0x2e, 0x7d, 0x6e, 0x7e, 0x16, 0xce, 0x0c, + 0x1e, 0xde, 0x2e, 0x2e, 0x1b, 0x12, 0x1d, 0x6e, + 0x6d, 0x0f, 0x11, 0xcc, 0x1d, 0x08, 0x71, 0xcf, + 0x2e, 0xea, 0x6d, 0x08, 0x17, 0xae, 0xdd, 0x12, + 0x62, 0x0e, 0x49, 0x14, 0xdc, 0x0e, 0xad, 0x12, + 0x61, 0xdc, 0x6d, 0x0f, 0x2a, 0xee, 0x6c, 0xdf, + 0x7c, 0xde, 0x65, 0x0c, 0x75, 0x0d, 0x68, 0x27, + 0x2f, 0xae, 0x6c, 0xde, 0x7d, 0x08, 0x3c, 0x0e, + 0x63, 0x3c, 0x68, 0x27, 0xb9, 0x12, 0x61, 0xdf, + 0x6d, 0x0f, 0x34, 0xee, 0x4d, 0xde, 0x5d, 0x08, + 0x65, 0xdf, 0x24, 0x12, 0x43, 0x3c, 0x4a, 0x27, + 0x25, 0x0c, 0x47, 0x26, 0x7d, 0x08, 0x63, 0x3c, + 0x4d, 0x27, 0x68, 0x27, 0x5d, 0x08, 0x7d, 0x08, + 0x43, 0x3c, 0x4a, 0x27, 0xb5, 0x0d, 0x64, 0x12, + 0x45, 0xce, 0x63, 0x3c, 0x68, 0x27, 0x22, 0x12, + 0x65, 0xcf, 0x2e, 0xae, 0xbd, 0xce, 0x2c, 0x0e, + 0x1c, 0x0e, 0xdc, 0x0e, 0xad, 0x12, 0xfc, 0xe1, + 0x60, 0x12, 0x68, 0x0e, 0x49, 0xde, 0x6e, 0x12, + 0x59, 0x12, 0x70, 0x12, 0x5c, 0x0c, 0x78, 0x0e, + 0x4a, 0x2e, 0x0a, 0x28, 0x48, 0xce, 0x46, 0x12, + 0x4b, 0x0e, 0x7b, 0xdd, 0x7a, 0x28, 0x7b, 0xcd, + 0x7b, 0x16, 0x4b, 0x0e, 0x7b, 0xdd, 0x7a, 0x2e, + 0x0d, 0x0f, 0x7b, 0xcd, 0x01, 0xeb, 0x01, 0xdc, + 0x4c, 0xde, 0x0d, 0x0f, 0x2e, 0xee, 0x45, 0x0d, + 0x2f, 0xae, 0x47, 0x26, 0x31, 0xdf, 0x5d, 0x08, + 0x43, 0x3c, 0x4a, 0x27, 0x3d, 0x0f, 0x23, 0xee, + 0xad, 0xde, 0xbd, 0x08, 0xa3, 0x3c, 0xa4, 0x27, + 0x45, 0x0c, 0xa7, 0x26, 0xbd, 0x08, 0xab, 0x27, + 0x6e, 0x12, 0xa3, 0x3c, 0xa4, 0x27, 0xad, 0xce, + 0x2f, 0xae, 0x4d, 0xce, 0x36, 0x12, 0x6c, 0x0e, + 0x3b, 0x0e, 0x2c, 0xdd, 0x22, 0x0e, 0x2c, 0xcd, + 0x30, 0x12, 0x38, 0x0e, 0x2c, 0xde, 0x2c, 0x0e, + 0x2c, 0xce, 0x7d, 0x16, 0x2b, 0x0e, 0x3d, 0xdd, + 0x3c, 0x0e, 0x3d, 0xcd, 0x26, 0x12, 0x2b, 0x0e, + 0x2d, 0xdd, 0x2d, 0x0f, 0x25, 0xea, 0x2d, 0x08, + 0x9b, 0x0e, 0xf8, 0x0e, 0x26, 0xcd, 0x20, 0xce, + 0x2f, 0xae, 0x6d, 0x08, 0x7e, 0x08, 0x71, 0x2e, + 0xc8, 0xd6, 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, + 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, + 0x2c, 0x11, 0xe2, 0x61, 0x7f, 0x0f, 0x69, 0x08, + 0x3d, 0xee, 0x7e, 0x0f, 0x25, 0xe6, 0x7d, 0x0f, + 0x6c, 0x08, 0x26, 0xee, 0x7c, 0x0f, 0x6f, 0x08, + 0x33, 0xef, 0x2a, 0xae, 0x7e, 0x0f, 0x6d, 0x08, + 0x29, 0xee, 0x79, 0x0f, 0x35, 0xef, 0x6e, 0x08, + 0x4f, 0x0f, 0x3e, 0xee, 0x4e, 0x0f, 0x2a, 0xe6, + 0x4d, 0x0f, 0x20, 0xee, 0x4c, 0x0f, 0x22, 0xef, + 0x68, 0x07, 0x23, 0xae, 0x4e, 0x0f, 0x21, 0xee, + 0x49, 0x0f, 0x24, 0xef, 0x1d, 0x8b, 0x2d, 0x9b, + 0x68, 0x27, 0x2b, 0xae, 0x69, 0x07, 0x29, 0xae, + 0x6b, 0x07, 0x2f, 0xae, 0x62, 0x08, 0x2c, 0x11, + 0x7d, 0x05, 0x2e, 0xef, 0x6d, 0x08, 0x25, 0xae, + 0x6d, 0x0f, 0x2d, 0x8a, 0x2f, 0x9a, 0x2f, 0xee, + 0x2e, 0xae, 0x2d, 0x8a, 0x2c, 0x9a, 0x7c, 0x05, + 0x2f, 0xee, 0x67, 0x07, 0x7f, 0x05, 0x2f, 0xee, + 0x66, 0x07, 0x2c, 0x11, 0x51, 0xc1, 0xb1, 0xc1, + 0x59, 0xde, 0xbb, 0x12, 0x58, 0x27, 0xba, 0x26, + 0xbb, 0x2f, 0x2e, 0xee, 0x62, 0x08, 0x27, 0xae, + 0x71, 0xdd, 0x7d, 0x0f, 0x2e, 0xee, 0x6d, 0x08, + 0x28, 0xae, 0x74, 0x25, 0x7a, 0x26, 0x79, 0xce, + 0x6d, 0x08, 0xb1, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x49, 0xde, 0x48, 0x27, + 0x49, 0xce, 0x2c, 0x11, 0x7d, 0x05, 0x29, 0xee, + 0xbd, 0x88, 0x28, 0x98, 0x6b, 0xce, 0x7c, 0x05, + 0x29, 0xee, 0xb6, 0x88, 0x28, 0x98, 0x6b, 0xce, + 0x79, 0x05, 0x29, 0xee, 0x9c, 0x88, 0x28, 0x98, + 0x6b, 0xce, 0x78, 0x05, 0x29, 0xee, 0x91, 0x88, + 0x28, 0x98, 0x6b, 0xce, 0x7f, 0x05, 0x29, 0xee, + 0xea, 0x88, 0x28, 0x98, 0x6b, 0xce, 0x7b, 0x05, + 0x29, 0xee, 0x8b, 0x8b, 0x28, 0x9b, 0x68, 0xce, + 0x2c, 0x11, 0x2d, 0x61, 0x4d, 0x0f, 0x51, 0xc1, + 0xa1, 0xc5, 0x22, 0x87, 0x81, 0xc5, 0x2d, 0x97, + 0xc1, 0xc5, 0xab, 0x12, 0x08, 0xee, 0xd2, 0x89, + 0xda, 0x99, 0x58, 0x2f, 0x0c, 0xe7, 0x9d, 0x08, + 0x88, 0x12, 0x5d, 0x08, 0x47, 0x3e, 0x2d, 0x84, + 0xd5, 0x94, 0x8b, 0x3f, 0x33, 0x85, 0x2f, 0xe6, + 0x28, 0xae, 0x98, 0x12, 0x92, 0x0e, 0x95, 0x2e, + 0x96, 0x0d, 0x76, 0x0d, 0x98, 0x2f, 0x3d, 0xe7, + 0x8c, 0x08, 0x58, 0x12, 0xa4, 0x12, 0xa8, 0x26, + 0x59, 0x0d, 0x59, 0x2e, 0x7c, 0x0e, 0x47, 0x12, + 0x45, 0x2c, 0xaa, 0xde, 0x4b, 0x25, 0x45, 0x26, + 0x98, 0x2f, 0x4a, 0xce, 0xde, 0xe6, 0x6c, 0x08, + 0x61, 0x2e, 0xc9, 0xd6, 0x89, 0xd6, 0xa9, 0xd6, + 0x59, 0xde, 0xea, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x4d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x2d, 0x9e, + 0x6d, 0x4a, 0x3d, 0x12, 0x4e, 0x8a, 0x2b, 0x9a, + 0x2b, 0x12, 0x39, 0x2e, 0x4c, 0xdd, 0x6b, 0x08, + 0x6b, 0x2d, 0x6d, 0x05, 0xda, 0x8a, 0x2d, 0x9a, + 0x2f, 0xef, 0x34, 0xae, 0x78, 0xdf, 0xd2, 0x8a, + 0x2d, 0x9a, 0x27, 0x88, 0x68, 0x26, 0x2d, 0x98, + 0x49, 0x2f, 0x22, 0xe7, 0x6e, 0x0f, 0x20, 0xee, + 0x6a, 0x0f, 0x26, 0xee, 0x75, 0x0d, 0x7e, 0x0f, + 0x25, 0xe6, 0x3b, 0x0e, 0x7c, 0xcd, 0x32, 0x0e, + 0x6c, 0xcd, 0xad, 0x8a, 0x2d, 0x9a, 0x2e, 0xae, + 0xdb, 0x8a, 0x2d, 0x9a, 0x31, 0xdf, 0xec, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x4e, 0x8b, 0x21, 0xc5, + 0x2b, 0x9b, 0x0b, 0x8e, 0x2d, 0x9e, 0x6d, 0x4a, + 0x28, 0x2e, 0x4d, 0xdd, 0x23, 0x8b, 0x2d, 0x9b, + 0x7b, 0x2d, 0x7d, 0x05, 0x29, 0xef, 0xda, 0x8a, + 0x2d, 0x9a, 0x3f, 0xae, 0x7d, 0x12, 0x3f, 0x8e, + 0x2d, 0x9e, 0x6d, 0x4a, 0x68, 0xde, 0x3c, 0x8b, + 0x2d, 0x9b, 0x28, 0x2e, 0x3d, 0xde, 0x29, 0xdf, + 0x3b, 0x0e, 0x2c, 0xce, 0x29, 0xdc, 0x3c, 0x0e, + 0xad, 0x8a, 0x2c, 0xce, 0x2d, 0x9a, 0x21, 0xdf, + 0x31, 0xdc, 0xef, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x4e, 0x8b, 0x31, 0xc1, 0xfd, 0x12, 0x2b, 0x9b, + 0x0b, 0x8e, 0x2d, 0x9e, 0x6d, 0x4a, 0x28, 0x2e, + 0x3d, 0xdd, 0x22, 0x8e, 0x2d, 0x9e, 0x2c, 0x2d, + 0x2d, 0x05, 0x20, 0x12, 0x29, 0xef, 0xda, 0x8a, + 0x2d, 0x9a, 0x3f, 0xae, 0x3f, 0x8e, 0x2d, 0x9e, + 0x6d, 0x4a, 0x3d, 0x12, 0x3c, 0x8a, 0x2d, 0x9a, + 0x20, 0x12, 0x39, 0x2e, 0x6c, 0xde, 0x6b, 0x0e, + 0x3c, 0x08, 0x39, 0xce, 0x6c, 0x0e, 0x2f, 0x8f, + 0x39, 0xce, 0xad, 0x8a, 0x2d, 0x9a, 0x31, 0xdf, + 0xec, 0x0e, 0x2c, 0x11, 0x4e, 0x8b, 0x21, 0xc5, + 0x2b, 0x9b, 0x0b, 0x8e, 0x2d, 0x9e, 0x0f, 0x83, + 0x6d, 0x4a, 0x2d, 0x93, 0x28, 0x2e, 0x4d, 0xdd, + 0x35, 0x8b, 0x2d, 0x9b, 0x7b, 0x2d, 0xad, 0x88, + 0x7d, 0x05, 0x2d, 0x98, 0x29, 0xef, 0xda, 0x8a, + 0x2d, 0x9a, 0x34, 0xae, 0x70, 0x12, 0x3c, 0x08, + 0x7d, 0x2e, 0x38, 0xce, 0x3d, 0xdd, 0x39, 0x0f, + 0x2e, 0xef, 0x6b, 0x12, 0x3d, 0xae, 0x7d, 0x12, + 0x3f, 0x8e, 0xf8, 0x2e, 0x2d, 0x9e, 0x6d, 0x4a, + 0x22, 0x8a, 0x2d, 0x9a, 0x29, 0x2e, 0x3d, 0xde, + 0x6b, 0x12, 0x89, 0x8e, 0x2d, 0x9e, 0x2c, 0xce, + 0x2d, 0x8e, 0x20, 0xce, 0x21, 0xdf, 0x31, 0xdc, + 0xef, 0x0e, 0x2c, 0x11, 0x0b, 0x88, 0x31, 0xc1, + 0x2d, 0x98, 0x51, 0xc1, 0x59, 0x12, 0xb1, 0xc1, + 0x6d, 0x12, 0x5b, 0x4a, 0x3d, 0x12, 0x4e, 0x8e, + 0x2b, 0x9e, 0x3d, 0x2e, 0x7c, 0xdd, 0x33, 0x8e, + 0x2d, 0x9e, 0x28, 0x2d, 0x2d, 0x05, 0x29, 0x12, + 0x29, 0xef, 0xda, 0x8a, 0x2d, 0x9a, 0x01, 0xae, + 0x3a, 0x0e, 0x2c, 0xdd, 0x2d, 0x0f, 0x39, 0xee, + 0x2c, 0x0f, 0x2b, 0xef, 0xb1, 0x8e, 0x28, 0x9e, + 0x4d, 0xdf, 0x7d, 0xde, 0x3c, 0xae, 0x2f, 0x0f, + 0x2b, 0xef, 0xe5, 0x8e, 0x28, 0x9e, 0x4d, 0xdf, + 0x7d, 0xde, 0x27, 0xae, 0x29, 0x0f, 0x2d, 0x88, + 0x7d, 0x08, 0x2f, 0xee, 0x28, 0xae, 0xbd, 0x8e, + 0x28, 0x9e, 0x7d, 0xdf, 0x4d, 0xdc, 0x3f, 0x8e, + 0x2d, 0x9e, 0x5d, 0x4a, 0x3d, 0x12, 0x29, 0x12, + 0x3c, 0x8a, 0x2d, 0x9a, 0x39, 0x2e, 0x6c, 0xde, + 0x6b, 0x0e, 0x79, 0xce, 0x3c, 0xde, 0xad, 0x8a, + 0x3a, 0x0e, 0x2d, 0x9a, 0x4c, 0xce, 0xb1, 0xdf, + 0x51, 0xdc, 0x31, 0xdd, 0xee, 0x0e, 0x2c, 0x11, + 0x7d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x51, 0xc1, + 0x2d, 0x9e, 0xb1, 0x83, 0x6d, 0x4a, 0xbd, 0x88, + 0x28, 0x93, 0x6d, 0x12, 0x4e, 0x8f, 0x2b, 0x9f, + 0x28, 0x12, 0x6c, 0x2e, 0x28, 0x98, 0x79, 0xdd, + 0x33, 0x8f, 0x2d, 0x9f, 0x38, 0x2d, 0x3d, 0x05, + 0xad, 0x8f, 0x2d, 0x9f, 0x29, 0xef, 0xda, 0x8a, + 0x2d, 0x9a, 0x32, 0xae, 0x6a, 0x0e, 0x69, 0xdd, + 0x6d, 0x0f, 0x2b, 0xef, 0x69, 0x24, 0x6b, 0xcf, + 0x6b, 0xcc, 0x6c, 0x12, 0x3b, 0xae, 0x6c, 0x0f, + 0x28, 0xef, 0x69, 0x34, 0x60, 0xc6, 0xad, 0x8a, + 0x3d, 0xae, 0x6f, 0x0f, 0x2a, 0xef, 0x69, 0x34, + 0xe5, 0x8f, 0x28, 0x9f, 0x6c, 0xc6, 0xad, 0x8a, + 0x25, 0xae, 0x69, 0x0f, 0x28, 0xef, 0x69, 0x34, + 0x7b, 0xcf, 0x7b, 0xcc, 0x60, 0xc6, 0x6c, 0x12, + 0x51, 0xdf, 0x31, 0xdc, 0xef, 0x0e, 0x2c, 0x11, + 0x4d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x2d, 0x9e, + 0x6d, 0x4a, 0x3d, 0x12, 0x4e, 0x8a, 0x2b, 0x9a, + 0x2b, 0x12, 0x39, 0x2e, 0x4c, 0xdd, 0x33, 0x8a, + 0x2d, 0x9a, 0x6b, 0x2d, 0x6d, 0x05, 0xda, 0x8a, + 0x2d, 0x9a, 0x2f, 0xef, 0x23, 0xae, 0x78, 0xdf, + 0xd2, 0x8a, 0x2d, 0x9a, 0x79, 0x26, 0x7e, 0x0f, + 0x2e, 0xe7, 0xdb, 0x8a, 0x2b, 0xae, 0x23, 0x8a, + 0x6c, 0x2e, 0x79, 0xce, 0xad, 0x8a, 0x2d, 0x9a, + 0x31, 0xdf, 0xec, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x3d, 0x17, 0x31, 0xc1, 0xd3, 0x83, 0x21, 0xc1, + 0x29, 0x12, 0x26, 0x93, 0x3f, 0x8f, 0xfd, 0x09, + 0x2d, 0x9f, 0x0d, 0x08, 0x2c, 0x4a, 0x21, 0x8d, + 0xd5, 0x9d, 0x0e, 0xce, 0x22, 0x8c, 0x39, 0x8d, + 0x2d, 0x9c, 0x2f, 0x2e, 0x0d, 0x08, 0x0e, 0xce, + 0x3d, 0xde, 0x80, 0x8e, 0x2d, 0x9e, 0x2c, 0xce, + 0xd2, 0x03, 0xd2, 0xa1, 0x39, 0x17, 0x51, 0xc1, + 0xb1, 0xc1, 0x61, 0xc1, 0xb8, 0xdf, 0xd2, 0x8a, + 0x2d, 0x9a, 0xb9, 0x26, 0xbf, 0x0f, 0xdb, 0x8a, + 0x2f, 0xe7, 0x03, 0xae, 0x10, 0x89, 0x2a, 0x99, + 0x6a, 0xde, 0x64, 0x2f, 0x0a, 0xee, 0xd3, 0x83, + 0x26, 0x93, 0xfd, 0x09, 0x6d, 0x08, 0x21, 0x8b, + 0xd5, 0x9b, 0xb8, 0x88, 0xbd, 0x0f, 0x68, 0xce, + 0x39, 0x8b, 0xa8, 0x98, 0x68, 0xce, 0x2c, 0x8a, + 0x38, 0x8b, 0x68, 0xce, 0x20, 0x8b, 0x2d, 0x8a, + 0x68, 0xce, 0x2b, 0x8b, 0xac, 0x9b, 0x2f, 0xee, + 0x28, 0xae, 0x2e, 0x8b, 0xd4, 0x88, 0xa9, 0x9b, + 0xaa, 0x98, 0x20, 0x8a, 0x37, 0x83, 0xd5, 0x9a, + 0x21, 0x93, 0x79, 0xce, 0x39, 0x8b, 0x49, 0xc9, + 0xd5, 0x9b, 0x6c, 0x08, 0x68, 0xce, 0xba, 0xce, + 0x36, 0xb5, 0xad, 0x8a, 0x2d, 0x9a, 0x71, 0xdf, + 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, 0x28, 0x15, + 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, 0xda, 0x89, + 0xa1, 0xc5, 0xb8, 0x12, 0x21, 0xc0, 0x0b, 0x8e, + 0xa9, 0x12, 0x2d, 0x9e, 0x2d, 0x99, 0x6d, 0x4a, + 0x4e, 0x8a, 0x2b, 0x9a, 0x29, 0x2e, 0x7d, 0xdd, + 0x33, 0x8a, 0x2d, 0x9a, 0x68, 0x2d, 0x6d, 0x05, + 0x2f, 0xef, 0x09, 0xae, 0x7d, 0x12, 0xb9, 0x83, + 0x2a, 0x0e, 0x78, 0x0e, 0x6d, 0xde, 0x02, 0x93, + 0x24, 0x0e, 0xfd, 0x09, 0x3d, 0xde, 0x74, 0x12, + 0x38, 0x0e, 0x4d, 0x08, 0x6c, 0xdd, 0x21, 0xcf, + 0x5d, 0xdf, 0x3f, 0x8e, 0x5d, 0x09, 0x43, 0x83, + 0x2d, 0x9e, 0xad, 0x4a, 0x02, 0x93, 0x59, 0x12, + 0xfd, 0x09, 0x3c, 0x8a, 0xba, 0x0e, 0x2d, 0x9a, + 0x29, 0x2e, 0x7d, 0xde, 0x64, 0xd0, 0x7b, 0x0e, + 0x68, 0xce, 0x3d, 0xde, 0x24, 0xdd, 0x3a, 0x0e, + 0x2c, 0xce, 0x7f, 0x08, 0x6a, 0x12, 0x71, 0x2e, + 0x28, 0xd7, 0xa8, 0xd6, 0x3d, 0x15, 0x58, 0xd7, + 0x28, 0xd6, 0xea, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x4d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x51, 0xc1, + 0x2d, 0x9e, 0x3c, 0x17, 0x31, 0xc1, 0x6d, 0x4a, + 0x3d, 0x12, 0x2b, 0x12, 0x4e, 0x88, 0x2b, 0x98, + 0x3b, 0x2e, 0x4c, 0xdd, 0x33, 0x8f, 0x2d, 0x9f, + 0x3b, 0x2d, 0x3d, 0x05, 0x29, 0xef, 0xda, 0x8a, + 0x2d, 0x9a, 0x22, 0xae, 0x78, 0xdf, 0xd2, 0x8f, + 0x2d, 0x9f, 0x7c, 0x26, 0x7f, 0x0f, 0x29, 0xe7, + 0xdb, 0x8a, 0x2d, 0x9a, 0x2b, 0xae, 0xcb, 0x83, + 0x1d, 0x93, 0xfd, 0x09, 0xad, 0x8a, 0x2d, 0x9a, + 0x31, 0xdf, 0x51, 0xdc, 0x3c, 0x15, 0x31, 0xdd, + 0xee, 0x0e, 0x2c, 0x11, 0x4d, 0x12, 0x31, 0xc1, + 0x0b, 0x8e, 0x51, 0xc1, 0x2d, 0x9e, 0xb1, 0xc1, + 0x3c, 0x17, 0x31, 0xc1, 0x6d, 0x4a, 0xe3, 0x0e, + 0x3d, 0x12, 0x2b, 0x12, 0x4e, 0x88, 0x2b, 0x98, + 0x3b, 0x2e, 0x4c, 0xdd, 0x23, 0x8f, 0x2d, 0x9f, + 0x3b, 0x2d, 0x3d, 0x05, 0x38, 0x12, 0x29, 0xef, + 0xda, 0x8a, 0x2d, 0x9a, 0x26, 0xae, 0x48, 0xdc, + 0x6d, 0x83, 0x7d, 0x08, 0x1c, 0x93, 0x71, 0xcf, + 0x71, 0xcc, 0x7c, 0xdf, 0xfd, 0x09, 0xad, 0x8a, + 0x2d, 0x9a, 0x7e, 0x08, 0x71, 0x2e, 0x38, 0xd7, + 0xb8, 0xd7, 0x3c, 0x15, 0x58, 0xd7, 0x38, 0xde, + 0xeb, 0x0e, 0x2c, 0x11, 0x7d, 0x12, 0x31, 0xc1, + 0x0b, 0x8e, 0x51, 0xc1, 0x2d, 0x9e, 0xb1, 0xc1, + 0x3c, 0x17, 0x31, 0xc1, 0x6d, 0x4a, 0x3d, 0x12, + 0x4e, 0x8a, 0x2b, 0x9a, 0x28, 0x12, 0x39, 0x2e, + 0x7c, 0xdd, 0x6f, 0x08, 0x68, 0x2d, 0x6d, 0x05, + 0xda, 0x8a, 0x2d, 0x9a, 0x2f, 0xef, 0x15, 0xae, + 0x20, 0x8b, 0x5d, 0x08, 0x2d, 0x9b, 0x7c, 0x2e, + 0x68, 0xde, 0x65, 0x05, 0x2f, 0xef, 0x2a, 0xae, + 0x02, 0x89, 0x4d, 0x08, 0xd3, 0x99, 0x4a, 0xce, + 0x2d, 0x89, 0x2c, 0x99, 0x64, 0x05, 0x2b, 0xee, + 0x12, 0x87, 0x4d, 0x08, 0xd3, 0x97, 0x54, 0x07, + 0x44, 0xce, 0x5d, 0x0f, 0x39, 0xee, 0xef, 0x83, + 0x6e, 0x08, 0x2e, 0x93, 0xfd, 0x09, 0x35, 0x8a, + 0xff, 0x83, 0xd5, 0x9a, 0x2e, 0x93, 0x49, 0xde, + 0x7a, 0x25, 0x7b, 0x26, 0x79, 0xce, 0x59, 0xcf, + 0x6e, 0x08, 0xfd, 0x09, 0x20, 0x8b, 0x2d, 0x9b, + 0x7c, 0x2e, 0x68, 0xde, 0xf9, 0x88, 0x28, 0x98, + 0x5b, 0xde, 0x6a, 0x27, 0x5d, 0x08, 0x5c, 0xce, + 0x6b, 0xce, 0x6d, 0x08, 0x6c, 0xcd, 0x3a, 0x0e, + 0x6c, 0xce, 0x68, 0xce, 0xad, 0x8a, 0x31, 0xdf, + 0xb1, 0xdc, 0x3c, 0x15, 0x51, 0xdd, 0xee, 0x0e, + 0x31, 0xdf, 0xec, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x21, 0xc5, 0x3d, 0x17, 0x01, 0xc5, 0x4e, 0x8c, + 0x51, 0xc1, 0x2b, 0x9c, 0xa1, 0xc5, 0xa9, 0x12, + 0x81, 0xc5, 0xc1, 0xc5, 0xc7, 0x81, 0x21, 0xc1, + 0x07, 0x8e, 0x98, 0x80, 0x2d, 0x9e, 0x1c, 0x91, + 0xed, 0x28, 0x2b, 0x90, 0x0b, 0x8e, 0x6d, 0x4a, + 0x2f, 0x2e, 0x1d, 0xdd, 0x09, 0x08, 0x0e, 0x2d, + 0xda, 0x8d, 0x0d, 0x05, 0x2d, 0x9d, 0x2f, 0xef, + 0x51, 0xae, 0xfd, 0x12, 0x22, 0x8c, 0x3f, 0x8e, + 0x10, 0x12, 0x2d, 0x9e, 0x2d, 0x9c, 0x6d, 0x4a, + 0x2f, 0x83, 0x04, 0x88, 0x2f, 0x2e, 0x1f, 0x93, + 0x0d, 0xdd, 0x2d, 0x98, 0x51, 0x12, 0x7d, 0x08, + 0x5f, 0x0e, 0x6a, 0x12, 0xfd, 0x09, 0x7e, 0x12, + 0x0e, 0x83, 0x78, 0x0e, 0x2d, 0x93, 0x18, 0xdd, + 0x38, 0x12, 0x36, 0x0e, 0x11, 0xc2, 0x22, 0x83, + 0x1a, 0xcd, 0x11, 0xc2, 0x34, 0x83, 0x11, 0xc2, + 0x68, 0xdc, 0xb9, 0x83, 0x02, 0x93, 0xfd, 0x09, + 0x1c, 0xde, 0x7a, 0x12, 0x1b, 0x0e, 0x4d, 0x08, + 0x6e, 0xde, 0x31, 0xcf, 0x5c, 0xdf, 0x5d, 0x09, + 0x43, 0x83, 0x19, 0x12, 0x02, 0x93, 0xfd, 0x09, + 0xad, 0x8a, 0x2d, 0x9a, 0x19, 0x2f, 0x64, 0xef, + 0x61, 0xdc, 0x2a, 0x0e, 0x22, 0x8b, 0x2d, 0x9b, + 0x7c, 0x2e, 0x68, 0xce, 0x4d, 0xdd, 0x26, 0x8b, + 0x24, 0x0e, 0x6b, 0x12, 0x6e, 0x0c, 0x2d, 0x9b, + 0x7d, 0x2e, 0x6b, 0x28, 0x98, 0xd7, 0x63, 0x2e, + 0x88, 0xd7, 0x6b, 0x0e, 0x48, 0xde, 0xb6, 0x12, + 0x69, 0xde, 0xbe, 0x0c, 0x2b, 0x12, 0x57, 0x12, + 0x5e, 0x0c, 0x2e, 0x0c, 0x2b, 0x28, 0x71, 0x12, + 0x7e, 0x0e, 0x27, 0x88, 0x2d, 0x98, 0xb6, 0x28, + 0x57, 0x28, 0xdd, 0x09, 0x71, 0x12, 0x27, 0x88, + 0x7a, 0x0e, 0x2d, 0x98, 0x7b, 0x0e, 0xb3, 0x2e, + 0xbb, 0x0e, 0x64, 0xde, 0xdd, 0x09, 0x3a, 0x8b, + 0x27, 0x88, 0x2d, 0x9b, 0x2d, 0x98, 0x71, 0x2e, + 0x53, 0x2e, 0x5b, 0x0e, 0x6a, 0xde, 0xdd, 0x09, + 0x23, 0x2e, 0x0c, 0x8b, 0x2b, 0x0e, 0x2d, 0x9b, + 0x6d, 0xde, 0x71, 0x2e, 0x27, 0x88, 0x21, 0x8e, + 0x2d, 0x98, 0x2d, 0x9e, 0xdd, 0x09, 0x2c, 0x2e, + 0x65, 0x12, 0x7d, 0xde, 0x6d, 0xb0, 0x2f, 0xde, + 0x2d, 0x07, 0x2f, 0xce, 0x2e, 0x08, 0x2c, 0xcd, + 0x06, 0x8b, 0x6e, 0x12, 0x2d, 0x9b, 0x71, 0x2e, + 0x28, 0xd7, 0xc8, 0xd6, 0x3d, 0x15, 0x88, 0xd6, + 0xa8, 0xd6, 0x58, 0xd7, 0x08, 0xd6, 0x28, 0xd6, + 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, 0x2d, 0x61, + 0xff, 0x12, 0x21, 0xc5, 0x3d, 0x17, 0x11, 0xc1, + 0x79, 0x12, 0x21, 0xc1, 0x0b, 0x8e, 0x7c, 0x0c, + 0x2d, 0x9e, 0x4e, 0x8d, 0x6d, 0x4a, 0x2b, 0x9d, + 0x69, 0x8c, 0x2e, 0x2e, 0x2d, 0x9c, 0x13, 0x8d, + 0x08, 0x88, 0x2a, 0x9d, 0x2d, 0x98, 0x4d, 0x2e, + 0x7e, 0x2e, 0x6f, 0x42, 0x28, 0x0e, 0x39, 0x12, + 0x6d, 0x08, 0x1f, 0x12, 0x00, 0x12, 0x6b, 0xce, + 0xd2, 0x88, 0x6d, 0xcd, 0x2c, 0x0e, 0x2d, 0x98, + 0x26, 0x83, 0x6d, 0xcd, 0x2c, 0x0e, 0x2d, 0x93, + 0x4d, 0xcd, 0x24, 0x0e, 0xfd, 0x2e, 0x40, 0xc7, + 0x0f, 0x88, 0x60, 0xc4, 0x4d, 0x2e, 0x2c, 0x8a, + 0x3f, 0x8e, 0x60, 0xc7, 0x2d, 0x8a, 0x2d, 0x9e, + 0x3d, 0x4a, 0x60, 0xce, 0x7d, 0x83, 0x6b, 0xc7, + 0x1f, 0x93, 0x6b, 0xc7, 0x6b, 0xce, 0x68, 0xc7, + 0x68, 0xce, 0xfa, 0x8a, 0x28, 0x9a, 0x6e, 0x2e, + 0x22, 0x8d, 0xfd, 0x09, 0x2a, 0x0e, 0x2d, 0x9d, + 0x2e, 0x2e, 0x09, 0x83, 0x1d, 0xdd, 0x1f, 0x93, + 0x24, 0x0e, 0x6e, 0x12, 0x6e, 0x0c, 0x6e, 0x28, + 0x98, 0x8d, 0x2b, 0x9d, 0x6e, 0x2e, 0x26, 0x8d, + 0xfd, 0x09, 0x2d, 0x9d, 0x09, 0x83, 0x1d, 0x2e, + 0x1f, 0x93, 0x1e, 0xde, 0x6e, 0x12, 0x6e, 0x0c, + 0x6e, 0x28, 0x98, 0x8d, 0x2b, 0x9d, 0x6e, 0x2e, + 0x21, 0x8d, 0xfd, 0x09, 0x2d, 0x9d, 0x09, 0x83, + 0x1d, 0x2e, 0x1f, 0x93, 0x1e, 0xde, 0x6e, 0x12, + 0x6e, 0x0c, 0x6e, 0x28, 0x98, 0x8d, 0x2b, 0x9d, + 0x6e, 0x2e, 0x20, 0x8d, 0xfd, 0x09, 0x2d, 0x9d, + 0x09, 0x83, 0x1d, 0x2e, 0x1f, 0x93, 0x2e, 0xde, + 0x6d, 0x12, 0x6e, 0x0c, 0x6d, 0x28, 0x98, 0x8e, + 0x2b, 0x9e, 0x6d, 0x2e, 0xfd, 0x09, 0x21, 0xdf, + 0x11, 0xdc, 0x3d, 0x15, 0x21, 0xdd, 0xee, 0x0e, + 0x31, 0xdf, 0xec, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x21, 0xc5, 0x3d, 0x17, 0x01, 0xc5, 0x4e, 0x8f, + 0x51, 0xc1, 0x2b, 0x9f, 0xa1, 0xc5, 0x81, 0xc5, + 0xc1, 0xc5, 0x20, 0x81, 0x21, 0xc0, 0x0b, 0x8e, + 0x2d, 0x91, 0x2d, 0x9e, 0x6d, 0x42, 0x0c, 0x2e, + 0x28, 0x12, 0x7f, 0xdd, 0x3c, 0x08, 0x38, 0x2d, + 0x19, 0x12, 0x3d, 0x05, 0x29, 0xef, 0xda, 0x8a, + 0x2d, 0x9a, 0xbd, 0xae, 0x2b, 0x0e, 0x08, 0x0e, + 0x31, 0x08, 0x3f, 0xc7, 0xd2, 0x8f, 0x52, 0x9f, + 0x3f, 0xce, 0x7d, 0xde, 0x2d, 0x9f, 0x27, 0x0e, + 0x7c, 0x26, 0x8d, 0xdf, 0x07, 0x0e, 0x9d, 0xdc, + 0x2e, 0x8f, 0xad, 0xdd, 0xd5, 0x9f, 0xbc, 0xde, + 0x29, 0x0e, 0x5d, 0xd7, 0x2d, 0xde, 0x2d, 0x61, + 0xe5, 0xb3, 0x39, 0x12, 0x62, 0x12, 0x4c, 0x12, + 0x6f, 0x2e, 0x79, 0xde, 0x6c, 0x08, 0x61, 0xcf, + 0xf9, 0x8a, 0x28, 0x9a, 0xe1, 0xb3, 0x6d, 0x0f, + 0xdb, 0x8a, 0x2d, 0x9a, 0x2f, 0xec, 0x47, 0xae, + 0xcf, 0x12, 0x77, 0x12, 0xc8, 0x0e, 0x46, 0x12, + 0x63, 0x12, 0x2d, 0x61, 0xc9, 0xb3, 0x4d, 0x12, + 0x7a, 0x12, 0x2a, 0x2e, 0x63, 0x12, 0x2d, 0x61, + 0xcc, 0xb3, 0xbf, 0x8a, 0x5b, 0x8b, 0x09, 0x0e, + 0x21, 0x9a, 0x21, 0x9b, 0x2f, 0xce, 0xad, 0x8e, + 0x01, 0x0e, 0x1d, 0x0f, 0x2d, 0x9e, 0x2f, 0xef, + 0x28, 0xae, 0xe7, 0x8a, 0x83, 0x8b, 0x21, 0x9a, + 0x21, 0x9b, 0xb9, 0x83, 0x7f, 0xcf, 0x02, 0x93, + 0x6f, 0xcc, 0x73, 0x12, 0x6d, 0x08, 0xfd, 0x09, + 0x65, 0x12, 0x01, 0xcf, 0x5f, 0xdf, 0x74, 0x12, + 0x4d, 0x08, 0x5d, 0x09, 0x43, 0x83, 0x59, 0x12, + 0x02, 0x93, 0xfd, 0x09, 0xdd, 0x8a, 0x5d, 0x0f, + 0x2d, 0x9a, 0x2f, 0xef, 0x1a, 0xae, 0x62, 0x12, + 0x4c, 0x12, 0x6f, 0x2e, 0xad, 0x08, 0x79, 0xde, + 0x6d, 0x08, 0x61, 0xcf, 0xf9, 0x8a, 0x28, 0x9a, + 0x86, 0xb3, 0xdf, 0x2e, 0x35, 0x05, 0x32, 0xce, + 0x2f, 0xef, 0x2b, 0xae, 0x02, 0x8a, 0x2d, 0x86, + 0xd3, 0x9a, 0x2c, 0x96, 0x29, 0xce, 0x34, 0x05, + 0x28, 0xee, 0x12, 0x8f, 0xa4, 0x07, 0xd3, 0x9f, + 0x2c, 0xce, 0xad, 0x0f, 0x3d, 0xee, 0xef, 0x83, + 0x35, 0x8f, 0x2e, 0x93, 0xd5, 0x9f, 0x6e, 0x08, + 0xfd, 0x09, 0x7c, 0xde, 0xff, 0x83, 0x2e, 0x93, + 0x65, 0x12, 0x68, 0x27, 0x6c, 0xce, 0x6e, 0x08, + 0xac, 0xcf, 0xfd, 0x09, 0x3a, 0xdd, 0x0a, 0x0e, + 0x6e, 0x12, 0x3f, 0xce, 0x04, 0x0e, 0x3c, 0x08, + 0x5f, 0xce, 0x2d, 0x61, 0x42, 0xb1, 0x6d, 0x12, + 0x3f, 0xcd, 0x7f, 0x08, 0x71, 0x2e, 0x28, 0xd7, + 0xc8, 0xd6, 0x3d, 0x15, 0x88, 0xd6, 0xa8, 0xd6, + 0x58, 0xd7, 0x08, 0xd6, 0x28, 0xd6, 0x72, 0x0e, + 0xe8, 0x12, 0x2c, 0x11, 0x4e, 0x8b, 0x21, 0xc5, + 0x2b, 0x9b, 0x3d, 0x17, 0x8c, 0x88, 0x21, 0xc1, + 0x0b, 0x8e, 0x28, 0x98, 0x2d, 0x9e, 0x6d, 0x4a, + 0x28, 0x2e, 0xbd, 0x8b, 0x2a, 0x0e, 0xfd, 0xdd, + 0x28, 0x9b, 0x24, 0x0e, 0xfc, 0x0f, 0x4a, 0xee, + 0xfc, 0x0f, 0x4f, 0xe7, 0xff, 0x0f, 0x47, 0xee, + 0xf9, 0x0f, 0x25, 0xef, 0x3d, 0x08, 0x38, 0xcd, + 0x25, 0x9f, 0x3b, 0xce, 0x40, 0x0e, 0x2d, 0x9f, + 0x3b, 0xce, 0x7d, 0x12, 0x0d, 0x88, 0x3f, 0x8e, + 0x2d, 0x98, 0x48, 0x2e, 0x2d, 0x9e, 0x6d, 0x4a, + 0x7d, 0x08, 0xfd, 0x12, 0x7b, 0xc0, 0xfa, 0x0e, + 0x7b, 0xc7, 0x22, 0x8e, 0x7b, 0xc4, 0x2d, 0x9e, + 0x7b, 0xce, 0xfd, 0x2e, 0x40, 0xdd, 0x69, 0x8e, + 0xf4, 0x0e, 0x7b, 0x12, 0x7e, 0x0c, 0x2d, 0x9e, + 0x6d, 0x4a, 0x7b, 0x28, 0xfa, 0x8a, 0x28, 0x9a, + 0x29, 0x2e, 0x94, 0x8a, 0x2b, 0x9a, 0x79, 0x2e, + 0x6d, 0x08, 0x68, 0xce, 0x26, 0x8a, 0x60, 0x2e, + 0x79, 0xd7, 0x48, 0x12, 0x4e, 0x0c, 0x48, 0x28, + 0x94, 0x8b, 0x2b, 0x9b, 0x48, 0x2e, 0x7d, 0x08, + 0x7b, 0xce, 0x79, 0xd7, 0x48, 0x12, 0x4e, 0x0c, + 0x48, 0x28, 0x94, 0x8b, 0x2b, 0x9b, 0x48, 0x2e, + 0x7d, 0x08, 0x7b, 0xce, 0x69, 0xde, 0x79, 0x12, + 0x7e, 0x0c, 0x79, 0x28, 0x94, 0x8a, 0x2b, 0x9a, + 0x79, 0x2e, 0x6d, 0x08, 0x68, 0xce, 0x04, 0x8b, + 0x2d, 0x9b, 0x7d, 0x2e, 0x3d, 0x8e, 0x68, 0xc1, + 0x2d, 0x9e, 0x68, 0xce, 0x20, 0x2e, 0xf2, 0x8b, + 0x6d, 0xde, 0xd2, 0x9b, 0x20, 0x12, 0x69, 0x83, + 0x27, 0x93, 0xfd, 0x09, 0x3d, 0xdd, 0x2d, 0x08, + 0x2c, 0xcc, 0x21, 0xdf, 0x31, 0xdd, 0x3d, 0x15, + 0x21, 0xdc, 0xee, 0x0e, 0x2c, 0x11, 0x3d, 0x08, + 0x38, 0xcd, 0x85, 0xa1, 0x2d, 0x8f, 0x25, 0x9f, + 0x3b, 0xce, 0x40, 0x0e, 0x2d, 0x9f, 0x3b, 0xce, + 0x8c, 0xa1, 0xe7, 0x8b, 0x3d, 0x08, 0x28, 0x9b, + 0x38, 0xce, 0xb1, 0xa1, 0x7d, 0x12, 0x31, 0xc1, + 0x0b, 0x8e, 0x3c, 0x17, 0x2d, 0x9e, 0x31, 0xc1, + 0x6d, 0x4a, 0x3d, 0x12, 0x28, 0x12, 0x4e, 0x8b, + 0x2b, 0x9b, 0x38, 0x2e, 0x7c, 0xdd, 0x35, 0x8f, + 0x2d, 0x9f, 0x38, 0x2d, 0x3d, 0x05, 0x29, 0xef, + 0xda, 0x8a, 0x2d, 0x9a, 0x28, 0xae, 0x2d, 0x61, + 0x9e, 0xb1, 0xad, 0x8a, 0x2d, 0x9a, 0x31, 0xdf, + 0x3c, 0x15, 0x31, 0xdc, 0xef, 0x0e, 0x2c, 0x11, + 0x38, 0x17, 0x51, 0xc1, 0x6d, 0x05, 0x71, 0xc1, + 0x59, 0x12, 0x20, 0xee, 0x01, 0x83, 0xbd, 0x8a, + 0x1f, 0x93, 0x28, 0x9a, 0x4d, 0x08, 0x7c, 0x08, + 0xfd, 0x09, 0x69, 0x83, 0x7d, 0x08, 0x27, 0x93, + 0x6b, 0x08, 0xfd, 0x09, 0x5c, 0x05, 0x23, 0xee, + 0x01, 0x83, 0x2d, 0x88, 0x1f, 0x93, 0x25, 0x98, + 0xb6, 0x8a, 0x7c, 0x08, 0x28, 0x9a, 0xfd, 0x09, + 0x69, 0x83, 0x7d, 0x08, 0x27, 0x93, 0x6a, 0x08, + 0x4b, 0xb6, 0x59, 0x05, 0x22, 0xee, 0x01, 0x83, + 0x2d, 0x8b, 0x1f, 0x93, 0x2c, 0x9b, 0x9c, 0x8a, + 0x4d, 0x08, 0x28, 0x9a, 0xfd, 0x09, 0x69, 0x83, + 0x24, 0x8a, 0x27, 0x93, 0x2d, 0x9a, 0x7d, 0x08, + 0x73, 0xb6, 0x58, 0x05, 0x22, 0xee, 0x01, 0x83, + 0x2d, 0x8b, 0x1f, 0x93, 0x2c, 0x9b, 0x91, 0x8a, + 0x4d, 0x08, 0x28, 0x9a, 0xfd, 0x09, 0x69, 0x83, + 0x27, 0x8a, 0x27, 0x93, 0x2d, 0x9a, 0x7d, 0x08, + 0x7b, 0xb6, 0x5f, 0x05, 0x3e, 0xee, 0x01, 0x83, + 0xea, 0x8a, 0x1f, 0x93, 0x28, 0x9a, 0x4d, 0x08, + 0x7d, 0x08, 0xfd, 0x09, 0x4c, 0x8a, 0x2b, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0x2a, 0xef, 0x69, 0x83, + 0x25, 0x8a, 0x27, 0x93, 0x2d, 0x9a, 0x7d, 0x08, + 0x61, 0xb6, 0x5b, 0x05, 0x3e, 0xee, 0x01, 0x83, + 0x8b, 0x8a, 0x1f, 0x93, 0x28, 0x9a, 0x4d, 0x08, + 0x7d, 0x08, 0xfd, 0x09, 0x4c, 0x8a, 0x2b, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0x2a, 0xef, 0x69, 0x83, + 0x25, 0x8a, 0x27, 0x93, 0x2d, 0x9a, 0x7d, 0x08, + 0x6f, 0xb6, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x31, 0xc1, 0x3c, 0x17, + 0x51, 0xc1, 0xb1, 0xc1, 0xb9, 0x12, 0x31, 0xc0, + 0x6d, 0x12, 0x0b, 0x8e, 0x2d, 0x9e, 0xbd, 0x4a, + 0x3d, 0x12, 0x29, 0x12, 0x4e, 0x8a, 0x2b, 0x9a, + 0x39, 0x2e, 0x7c, 0xdd, 0x23, 0x8a, 0x2d, 0x9a, + 0x68, 0x2d, 0x6d, 0x05, 0xda, 0x8a, 0x2d, 0x9a, + 0x2f, 0xef, 0xac, 0xae, 0x7c, 0x12, 0xb9, 0x83, + 0x3a, 0x0e, 0x78, 0x0e, 0x6c, 0xde, 0x02, 0x93, + 0x34, 0x0e, 0xfd, 0x09, 0x6c, 0xde, 0x7d, 0x08, + 0x68, 0x0e, 0x4d, 0x08, 0x69, 0xde, 0x31, 0xcf, + 0x5c, 0xdf, 0x5d, 0x09, 0x43, 0x83, 0x5d, 0x12, + 0x02, 0x93, 0x69, 0x8e, 0x2d, 0x9e, 0xfd, 0x09, + 0x64, 0x12, 0x2d, 0x61, 0x4d, 0xb1, 0xcb, 0x83, + 0x7d, 0x08, 0x1d, 0x93, 0x64, 0x12, 0xfd, 0x09, + 0x6d, 0x08, 0x0c, 0x88, 0x2d, 0x98, 0x74, 0x12, + 0x4c, 0x2e, 0x7c, 0x0c, 0x6b, 0xc7, 0x6b, 0xc7, + 0x13, 0x8a, 0x2a, 0x9a, 0x79, 0x2e, 0x6d, 0x08, + 0x6b, 0xc7, 0x6b, 0xc7, 0x6b, 0xce, 0x68, 0xc7, + 0x68, 0xce, 0x21, 0x8a, 0x6c, 0x2e, 0xbd, 0x4a, + 0x69, 0xde, 0x2d, 0x61, 0x8e, 0xb1, 0xfa, 0x8a, + 0x7d, 0x83, 0x28, 0x9a, 0x1f, 0x93, 0x6d, 0x2e, + 0x3f, 0x8e, 0xfd, 0x09, 0x2d, 0x9e, 0x22, 0x8a, + 0xbd, 0x4a, 0x2d, 0x9a, 0x09, 0x83, 0x3d, 0x12, + 0x1f, 0x93, 0x39, 0x2e, 0x2a, 0x12, 0x3a, 0x0e, + 0x7c, 0xdd, 0x34, 0x0e, 0x68, 0x12, 0x6e, 0x0c, + 0x68, 0x28, 0x98, 0x8b, 0x2b, 0x9b, 0x68, 0x2e, + 0xfd, 0x09, 0x26, 0x8a, 0x09, 0x83, 0x2d, 0x9a, + 0x1f, 0x93, 0x6c, 0x2e, 0x79, 0xde, 0x68, 0x12, + 0x6e, 0x0c, 0x68, 0x28, 0x98, 0x8b, 0x2b, 0x9b, + 0x68, 0x2e, 0xfd, 0x09, 0x21, 0x8a, 0x09, 0x83, + 0x2d, 0x9a, 0x1f, 0x93, 0x6c, 0x2e, 0x79, 0xde, + 0x68, 0x12, 0x6e, 0x0c, 0x68, 0x28, 0x98, 0x8b, + 0x2b, 0x9b, 0x68, 0x2e, 0xfd, 0x09, 0x20, 0x8a, + 0x09, 0x83, 0x2d, 0x9a, 0x1f, 0x93, 0x6c, 0x2e, + 0x79, 0xde, 0x68, 0x12, 0x6e, 0x0c, 0x68, 0x28, + 0x98, 0x8b, 0x2b, 0x9b, 0x68, 0x2e, 0xfd, 0x09, + 0x3c, 0x8a, 0x69, 0x83, 0x2d, 0x9a, 0x27, 0x93, + 0x6c, 0x2e, 0x7d, 0x08, 0x69, 0xde, 0xfd, 0x09, + 0xad, 0x8a, 0x2d, 0x9a, 0x7f, 0x08, 0x71, 0x2e, + 0x38, 0xd7, 0xb8, 0xd7, 0x3c, 0x15, 0x58, 0xd7, + 0x38, 0xde, 0xe8, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x6d, 0x0f, 0x31, 0xc1, 0x3c, 0x17, 0x51, 0xc1, + 0x58, 0x12, 0xb1, 0xc1, 0xb9, 0x12, 0x31, 0xc1, + 0xfe, 0x8a, 0x3d, 0x08, 0x28, 0x9a, 0x2f, 0xef, + 0x2e, 0xae, 0xf8, 0x8a, 0x28, 0x9a, 0x5d, 0x05, + 0x39, 0xce, 0x24, 0xee, 0x65, 0x83, 0xbd, 0x8a, + 0x1f, 0x93, 0x28, 0x9a, 0xfd, 0x09, 0x9f, 0x8a, + 0x2b, 0x9a, 0x39, 0xce, 0x5c, 0x05, 0x24, 0xee, + 0x65, 0x83, 0xb6, 0x8a, 0x1f, 0x93, 0x28, 0x9a, + 0xfd, 0x09, 0x9d, 0x8a, 0x2b, 0x9a, 0x39, 0xce, + 0x5f, 0x05, 0x2b, 0xee, 0x65, 0x83, 0xea, 0x8a, + 0x1f, 0x93, 0x28, 0x9a, 0xfd, 0x09, 0x6d, 0x12, + 0x35, 0x83, 0x3f, 0x8e, 0x1f, 0x93, 0x2d, 0x9e, + 0xbd, 0x4a, 0x2a, 0x0e, 0x39, 0x12, 0x22, 0x8a, + 0x2d, 0x9a, 0x29, 0x2e, 0x7d, 0xdd, 0x24, 0x0e, + 0x68, 0x12, 0x6e, 0x0c, 0x68, 0x28, 0x98, 0x8b, + 0x2b, 0x9b, 0x68, 0x2e, 0xfd, 0x09, 0x26, 0x8a, + 0x35, 0x83, 0x2d, 0x9a, 0x1f, 0x93, 0x6d, 0x2e, + 0x29, 0xde, 0x6d, 0x12, 0x6e, 0x0c, 0x6d, 0x28, + 0x98, 0x8e, 0x2b, 0x9e, 0x6d, 0x2e, 0xfd, 0x09, + 0x59, 0x05, 0x27, 0xee, 0x65, 0x83, 0x9c, 0x8a, + 0x1f, 0x93, 0x28, 0x9a, 0x2d, 0x08, 0xfd, 0x09, + 0xff, 0x8a, 0x28, 0x9a, 0x29, 0xce, 0x58, 0x05, + 0x27, 0xee, 0x65, 0x83, 0x91, 0x8a, 0x1f, 0x93, + 0x28, 0x9a, 0x2d, 0x08, 0xfd, 0x09, 0x4f, 0x8a, + 0x2b, 0x9a, 0x29, 0xce, 0x5b, 0x05, 0x2b, 0xee, + 0x65, 0x83, 0x8b, 0x8a, 0x1f, 0x93, 0x28, 0x9a, + 0xfd, 0x09, 0x6c, 0x12, 0x3f, 0x8e, 0x2d, 0x9e, + 0x35, 0x83, 0xbd, 0x4a, 0x1f, 0x93, 0x3d, 0x12, + 0x29, 0x12, 0x22, 0x8a, 0x2d, 0x9a, 0x39, 0x2e, + 0x21, 0x8a, 0x2d, 0x9a, 0x6c, 0x2e, 0x79, 0xde, + 0x68, 0x12, 0x6e, 0x0c, 0x68, 0x28, 0x98, 0x8b, + 0x2b, 0x9b, 0x68, 0x2e, 0xfd, 0x09, 0x20, 0x8a, + 0x35, 0x83, 0x2d, 0x9a, 0x1f, 0x93, 0x6c, 0x2e, + 0x39, 0xde, 0x6c, 0x12, 0x6e, 0x0c, 0x6c, 0x28, + 0x98, 0x8f, 0x2b, 0x9f, 0x6c, 0x2e, 0xfd, 0x09, + 0x31, 0xdf, 0xb1, 0xdc, 0x3c, 0x15, 0x51, 0xdd, + 0xee, 0x0e, 0x31, 0xdf, 0xec, 0x0e, 0x2c, 0x11, + 0x4e, 0x8b, 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, + 0x2b, 0x9b, 0xa1, 0xc5, 0x21, 0x86, 0x21, 0xc0, + 0x0b, 0x8e, 0xb9, 0x12, 0x2d, 0x9e, 0x2d, 0x96, + 0x6d, 0x4a, 0x28, 0x2e, 0x23, 0x8a, 0x7d, 0xdd, + 0x2d, 0x9a, 0x68, 0x2d, 0x6d, 0x05, 0xda, 0x8a, + 0x2d, 0x9a, 0x2f, 0xef, 0x7f, 0xae, 0x4d, 0x0f, + 0x0d, 0xef, 0x7d, 0x12, 0xb9, 0x83, 0x2a, 0x0e, + 0x78, 0x0e, 0x6d, 0xde, 0x02, 0x93, 0x24, 0x0e, + 0xfd, 0x09, 0x3d, 0xde, 0x4d, 0x08, 0x39, 0x0e, + 0x7d, 0x08, 0x6c, 0xde, 0x21, 0xcf, 0x5d, 0xdf, + 0x5d, 0x09, 0x43, 0x83, 0x02, 0x93, 0xfd, 0x09, + 0x6d, 0x12, 0x3f, 0x8e, 0x2d, 0x9e, 0xbd, 0x4a, + 0x3d, 0x12, 0x29, 0x12, 0x3e, 0x8a, 0x2d, 0x9a, + 0x39, 0x2e, 0x6c, 0xde, 0x3d, 0x08, 0x39, 0xce, + 0xcb, 0x83, 0x35, 0x12, 0x1d, 0x93, 0x64, 0x12, + 0x7c, 0x08, 0x5d, 0x12, 0xfd, 0x09, 0x64, 0x12, + 0x90, 0xb0, 0x3d, 0x2e, 0x6c, 0xde, 0x35, 0x12, + 0x21, 0xb1, 0x3d, 0x2e, 0x64, 0x12, 0x7c, 0xde, + 0xbf, 0xb1, 0xfb, 0x8a, 0xad, 0x2e, 0x75, 0xde, + 0x28, 0x9a, 0x39, 0xde, 0x3f, 0x8e, 0x38, 0x27, + 0x2d, 0x9e, 0x39, 0xce, 0xbd, 0x4a, 0x64, 0x12, + 0x37, 0xb0, 0x22, 0x8a, 0x69, 0x83, 0x2d, 0x9a, + 0x27, 0x93, 0x29, 0x2e, 0x7d, 0x08, 0x3c, 0x8a, + 0x2d, 0x9a, 0x6d, 0x2e, 0x69, 0xde, 0xfd, 0x09, + 0x3d, 0xdd, 0xad, 0x8a, 0x2c, 0xde, 0x2d, 0x9a, + 0x2d, 0x06, 0x2c, 0xce, 0x2c, 0x08, 0x2a, 0xcd, + 0x7f, 0x08, 0x71, 0x2e, 0x28, 0xd7, 0xa8, 0xd6, + 0x3d, 0x15, 0x58, 0xd7, 0x28, 0xd6, 0xea, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x6d, 0x0f, 0x21, 0xc5, + 0x3d, 0x17, 0x51, 0xc1, 0xf8, 0x89, 0xa1, 0xc5, + 0xab, 0x12, 0x81, 0xc5, 0x6f, 0x85, 0xc1, 0xc5, + 0x2d, 0x80, 0x21, 0xc1, 0x89, 0x12, 0x1f, 0x95, + 0xbd, 0x8a, 0x3d, 0x90, 0x28, 0x9a, 0x28, 0x99, + 0x2f, 0xee, 0x2e, 0xae, 0xfe, 0x89, 0x28, 0x99, + 0x3f, 0x8e, 0x22, 0x88, 0x2d, 0x98, 0x2d, 0x9e, + 0x8d, 0x4a, 0x2b, 0x2e, 0x2a, 0x0e, 0x26, 0x88, + 0xfd, 0xdd, 0x2d, 0x98, 0x24, 0x0e, 0xb0, 0x12, + 0xbe, 0x0c, 0x4d, 0x2e, 0x3b, 0xde, 0xb0, 0x28, + 0x2c, 0x12, 0x2e, 0x0c, 0x2c, 0x28, 0x98, 0x8f, + 0x2b, 0x9f, 0xbc, 0x2e, 0x2c, 0x2e, 0x33, 0x12, + 0xc4, 0xcc, 0x2c, 0x9f, 0x7f, 0x0f, 0x34, 0xcd, + 0x2d, 0x9f, 0x34, 0xce, 0x34, 0xcf, 0x3d, 0xcc, + 0x3d, 0xcd, 0x3d, 0xce, 0x3d, 0xcf, 0x3a, 0xce, + 0x01, 0xee, 0x7e, 0x0f, 0x2a, 0xe6, 0x7d, 0x0f, + 0x26, 0xee, 0x7c, 0x0f, 0x74, 0x12, 0x3b, 0xee, + 0x77, 0xae, 0x7e, 0x0f, 0x02, 0xee, 0x79, 0x0f, + 0x74, 0x12, 0x19, 0xee, 0x79, 0xae, 0x4b, 0x0e, + 0x9f, 0x8f, 0x2b, 0x08, 0x74, 0x12, 0x2b, 0x9f, + 0x24, 0xce, 0x2b, 0xde, 0x24, 0xcf, 0x9d, 0x09, + 0x24, 0xdc, 0x2c, 0xce, 0x24, 0xdd, 0x2a, 0xce, + 0x6b, 0xae, 0x4b, 0x0e, 0xb6, 0x8a, 0x28, 0x9a, + 0x9d, 0x8f, 0x2a, 0x08, 0x2b, 0x9f, 0x24, 0xce, + 0x2b, 0xde, 0x24, 0xcf, 0x9d, 0x09, 0x24, 0xdc, + 0x2c, 0xce, 0x24, 0xdd, 0x2a, 0xce, 0x1a, 0xae, + 0x4b, 0x0e, 0x25, 0x8e, 0x2d, 0x9e, 0xea, 0x8a, + 0x28, 0x9a, 0x24, 0xce, 0x2b, 0xde, 0x74, 0x12, + 0x24, 0xcf, 0x9d, 0x09, 0x24, 0xdd, 0x2a, 0xce, + 0x07, 0xae, 0x2d, 0x8e, 0x34, 0xcd, 0x2c, 0x9e, + 0x34, 0xce, 0x34, 0xcf, 0x34, 0xcc, 0x2a, 0xce, + 0x0f, 0xae, 0x4b, 0x0e, 0x2b, 0x8f, 0x34, 0xce, + 0x3b, 0xde, 0x43, 0x12, 0xc4, 0xcc, 0x2c, 0x98, + 0x34, 0xcf, 0x44, 0xcd, 0x3d, 0xcf, 0x3a, 0x08, + 0x3d, 0xce, 0x33, 0x12, 0xcd, 0xcc, 0x2f, 0x9f, + 0x3d, 0xcd, 0x9d, 0x09, 0x7d, 0x12, 0xb6, 0x8a, + 0x28, 0x9a, 0x9d, 0x09, 0x34, 0xdc, 0x9f, 0x8a, + 0x2b, 0x9a, 0x39, 0xce, 0x3d, 0xdc, 0x9d, 0x8a, + 0x2b, 0x9a, 0x39, 0xce, 0x2d, 0xdd, 0x34, 0xdd, + 0x2c, 0x27, 0x2a, 0xce, 0x3f, 0x8e, 0x22, 0x8a, + 0x2d, 0x9e, 0x2d, 0x9a, 0x8d, 0x4a, 0x21, 0x87, + 0x27, 0x88, 0x29, 0x2e, 0x2d, 0x97, 0xbd, 0x2e, + 0x2d, 0x98, 0x74, 0xd7, 0x64, 0xde, 0x28, 0x12, + 0x2e, 0x0c, 0x39, 0x12, 0x3e, 0x0c, 0x28, 0x28, + 0x39, 0x28, 0x24, 0x8b, 0x98, 0x8a, 0x2d, 0x9b, + 0x2b, 0x9a, 0x29, 0x2e, 0x39, 0x2e, 0x63, 0x12, + 0xcd, 0xcc, 0x2c, 0x9a, 0xaf, 0x0f, 0x6d, 0xcd, + 0x2d, 0x9a, 0x6d, 0xce, 0x6d, 0xcf, 0x6c, 0xcc, + 0x6c, 0xcd, 0x6c, 0xce, 0x6c, 0xcf, 0x04, 0xee, + 0xae, 0x0f, 0x2b, 0xe6, 0xad, 0x0f, 0x24, 0xee, + 0xac, 0x0f, 0x3f, 0xee, 0x70, 0xae, 0xae, 0x0f, + 0x02, 0xee, 0xa9, 0x0f, 0x18, 0xee, 0x75, 0xae, + 0x9c, 0x8a, 0xb9, 0x0e, 0x34, 0xde, 0x28, 0x9a, + 0x3d, 0xce, 0x7d, 0xcf, 0x7d, 0x12, 0x9d, 0x09, + 0xff, 0x8a, 0x28, 0x9a, 0x26, 0xae, 0x91, 0x8a, + 0xb9, 0x0e, 0x34, 0xde, 0x28, 0x9a, 0x7d, 0x12, + 0x3d, 0xce, 0x4d, 0xcf, 0x9d, 0x09, 0x4f, 0x8a, + 0x2b, 0x9a, 0x3d, 0xdd, 0x39, 0xce, 0x3a, 0xde, + 0x2d, 0xdc, 0x3d, 0x27, 0x3a, 0xce, 0x11, 0xae, + 0x7d, 0x12, 0x8b, 0x8a, 0x28, 0x9a, 0xb9, 0x0e, + 0x34, 0xde, 0x3d, 0xce, 0x25, 0x8f, 0x2d, 0x9f, + 0x3d, 0xcf, 0x9d, 0x09, 0x3a, 0xde, 0x2d, 0xdc, + 0x3d, 0x27, 0x3a, 0xce, 0x00, 0xae, 0x6d, 0xcd, + 0x6d, 0xce, 0x6d, 0xcf, 0x6d, 0xcc, 0x2a, 0xde, + 0x21, 0x07, 0x2a, 0xce, 0x08, 0xae, 0xb9, 0x0e, + 0x64, 0xde, 0x7d, 0xcf, 0x7d, 0x12, 0x6d, 0xce, + 0xcd, 0xcc, 0x2c, 0x90, 0xcd, 0xcd, 0x6c, 0xce, + 0x2d, 0x8a, 0x4c, 0xcf, 0x0d, 0x9a, 0x6c, 0xcc, + 0x2c, 0x9a, 0x6c, 0xcd, 0x9c, 0x8a, 0x28, 0x9a, + 0x9d, 0x09, 0x7c, 0x12, 0x91, 0x8a, 0x28, 0x9a, + 0x9d, 0x09, 0x6d, 0xdd, 0xff, 0x8b, 0x28, 0x9b, + 0x68, 0xce, 0x6c, 0xdd, 0x4f, 0x8b, 0x2b, 0x9b, + 0x68, 0xce, 0x3c, 0xdc, 0x2d, 0xdc, 0x3d, 0x27, + 0x2a, 0xde, 0x3d, 0x27, 0x3a, 0xce, 0x6c, 0x08, + 0x61, 0x2e, 0x29, 0xd7, 0xc9, 0xd6, 0x3d, 0x15, + 0x89, 0xd6, 0xa9, 0xd6, 0x59, 0xd7, 0x29, 0xd6, + 0x62, 0x0e, 0xe9, 0x12, 0x6d, 0x08, 0x2c, 0x11, + 0x4e, 0x88, 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, + 0x2b, 0x98, 0xa1, 0xc5, 0xb9, 0x12, 0x81, 0xc5, + 0xfb, 0x85, 0x21, 0xc0, 0x0b, 0x8e, 0x21, 0x84, + 0x2d, 0x9e, 0x28, 0x95, 0x6d, 0x4a, 0x2d, 0x94, + 0x2b, 0x2e, 0x5d, 0xdd, 0x4b, 0x08, 0x4a, 0x2d, + 0x4d, 0x05, 0x29, 0xef, 0xda, 0x8a, 0x2d, 0x9a, + 0x15, 0xae, 0x38, 0xdf, 0xd2, 0x86, 0x5c, 0x12, + 0x2d, 0x96, 0xac, 0x26, 0x55, 0x0d, 0x75, 0x12, + 0x4a, 0x12, 0x2d, 0x61, 0x47, 0xb5, 0x62, 0x0f, + 0x39, 0x12, 0x04, 0xee, 0x67, 0x12, 0x4c, 0x12, + 0x6d, 0x2e, 0x79, 0xde, 0x6c, 0x08, 0x61, 0xcf, + 0x66, 0x12, 0x2d, 0x61, 0xaf, 0xb5, 0x6d, 0x0f, + 0x33, 0xed, 0x67, 0x12, 0x6d, 0x2e, 0x79, 0xde, + 0x64, 0x12, 0x2d, 0x61, 0xe4, 0xb0, 0x64, 0x12, + 0x4a, 0x12, 0x75, 0x12, 0x67, 0xb1, 0x67, 0x12, + 0x4c, 0x12, 0x6d, 0x2e, 0x79, 0xde, 0x6d, 0x08, + 0x61, 0xcf, 0x66, 0x12, 0x55, 0xb5, 0x8d, 0x2e, + 0xad, 0x8a, 0x2a, 0x0e, 0x37, 0xc1, 0x3f, 0x08, + 0x57, 0xce, 0x2d, 0x9a, 0xad, 0xcd, 0x24, 0x0e, + 0x3d, 0xcd, 0x2e, 0xae, 0xdb, 0x8a, 0x2d, 0x9a, + 0x7f, 0x08, 0x71, 0x2e, 0x28, 0xd7, 0x88, 0xd6, + 0x3d, 0x15, 0xa8, 0xd6, 0x58, 0xd7, 0x28, 0xd6, + 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, 0x2d, 0x61, + 0x4d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x3c, 0x17, + 0x2d, 0x9e, 0x31, 0xc1, 0x6d, 0x4a, 0x3d, 0x12, + 0x2b, 0x12, 0x4e, 0x88, 0x2b, 0x98, 0x3b, 0x2e, + 0x0d, 0x88, 0x2d, 0x98, 0x4c, 0x2e, 0x3a, 0x0e, + 0x7b, 0xce, 0x3c, 0xdd, 0x3f, 0x0f, 0x14, 0xee, + 0x3e, 0x0f, 0x3d, 0xe6, 0x3d, 0x0f, 0x07, 0xee, + 0x3c, 0x0f, 0x0e, 0xef, 0xb3, 0x8a, 0x87, 0x83, + 0x28, 0x9a, 0x24, 0x93, 0x2d, 0x8b, 0x3c, 0x08, + 0x3d, 0x9b, 0x39, 0xce, 0x6a, 0x08, 0xfd, 0x09, + 0x35, 0xae, 0x3e, 0x0f, 0x1f, 0xee, 0x39, 0x0f, + 0x39, 0xef, 0xbd, 0x8a, 0x87, 0x83, 0x28, 0x9a, + 0x24, 0x93, 0x2d, 0x8b, 0x3c, 0x08, 0x3d, 0x9b, + 0x39, 0xcd, 0xb3, 0x8a, 0x28, 0x9a, 0x39, 0xce, + 0x6b, 0x08, 0xfd, 0x09, 0x87, 0x83, 0x2d, 0x8b, + 0x24, 0x93, 0x3d, 0x9b, 0x6a, 0x08, 0xfd, 0x09, + 0x31, 0xdf, 0x3c, 0x15, 0x31, 0xdc, 0xef, 0x0e, + 0x2c, 0x11, 0xbd, 0x8a, 0x87, 0x83, 0x28, 0x9a, + 0x24, 0x93, 0x2d, 0x8b, 0x3c, 0x08, 0x3d, 0x9b, + 0x39, 0xcd, 0x6b, 0x08, 0xfd, 0x09, 0xdc, 0xa1, + 0xe7, 0x8a, 0x87, 0x83, 0x28, 0x9a, 0x24, 0x93, + 0x2d, 0x8b, 0x3c, 0x08, 0x3d, 0x9b, 0x39, 0xce, + 0x25, 0x8a, 0x2d, 0x9a, 0xfd, 0x09, 0xc8, 0xa1, + 0x7d, 0x12, 0x3f, 0x8e, 0x2d, 0x9e, 0x6d, 0x4a, + 0x3d, 0x12, 0x22, 0x8a, 0x3a, 0x0e, 0x2d, 0x9a, + 0x39, 0x2e, 0x28, 0x12, 0x6c, 0xdd, 0x94, 0x8b, + 0x34, 0x0e, 0x49, 0x12, 0x4e, 0x0c, 0x2b, 0x9b, + 0x49, 0x28, 0x48, 0x2e, 0x6c, 0x08, 0x6b, 0xce, + 0x26, 0x88, 0x2d, 0x98, 0x4c, 0x2e, 0x4b, 0xde, + 0x3b, 0x12, 0x3e, 0x0c, 0x3b, 0x28, 0x38, 0x2e, + 0x6c, 0xce, 0xea, 0xa1, 0x4d, 0x12, 0x31, 0xc1, + 0x0b, 0x8e, 0x51, 0xc1, 0x2d, 0x9e, 0x3c, 0x17, + 0x31, 0xc1, 0x6d, 0x4a, 0x3d, 0x12, 0x2b, 0x12, + 0x4e, 0x88, 0x2b, 0x98, 0x3b, 0x2e, 0x4c, 0xdd, + 0x35, 0x8f, 0x2d, 0x9f, 0x3b, 0x2d, 0x3d, 0x05, + 0x29, 0xef, 0xda, 0x8a, 0x2d, 0x9a, 0x23, 0xae, + 0x78, 0xdf, 0xd2, 0x8f, 0x2d, 0x9f, 0x7c, 0x26, + 0x7f, 0x0f, 0x29, 0xe7, 0xdb, 0x8a, 0x2d, 0x9a, + 0x28, 0xae, 0x2d, 0x61, 0x98, 0xb1, 0xad, 0x8a, + 0x2d, 0x9a, 0x31, 0xdf, 0x51, 0xdc, 0x3c, 0x15, + 0x31, 0xdd, 0xee, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, 0xad, 0x8f, + 0xa1, 0xc5, 0xd2, 0x9f, 0xc1, 0xc5, 0x38, 0x2e, + 0x21, 0xc0, 0x52, 0x8e, 0xe5, 0x0e, 0x2d, 0x9e, + 0x58, 0x12, 0x2c, 0x2f, 0x2f, 0xe7, 0x4d, 0xae, + 0x71, 0x12, 0x3f, 0x8e, 0x6d, 0x4a, 0x7c, 0x0e, + 0x22, 0x88, 0xf8, 0x08, 0x2d, 0x98, 0x2b, 0x2e, + 0xdd, 0xdf, 0xad, 0xde, 0x51, 0xcf, 0x22, 0xd7, + 0x21, 0xcc, 0x22, 0xd7, 0x21, 0xcd, 0x22, 0xd7, + 0x28, 0xcd, 0x22, 0xd7, 0x7a, 0x0e, 0x21, 0xc2, + 0x22, 0xd7, 0x2b, 0x83, 0x21, 0xc2, 0x22, 0xde, + 0x2a, 0x83, 0x21, 0xc2, 0x2d, 0x08, 0x28, 0xc0, + 0x28, 0xcd, 0x76, 0x0e, 0x03, 0x8e, 0x2a, 0x2f, + 0x27, 0xe6, 0xed, 0x8e, 0x02, 0x8f, 0xd2, 0x9e, + 0x2d, 0x9f, 0x2a, 0x2e, 0x3d, 0x2f, 0x02, 0xe7, + 0x21, 0xb2, 0x68, 0xae, 0x1e, 0x8e, 0x2d, 0x9e, + 0x2a, 0x2e, 0x2d, 0xde, 0x2d, 0x15, 0x4d, 0x08, + 0xbd, 0xb0, 0x10, 0xae, 0xd9, 0xb3, 0x16, 0xae, + 0x53, 0xb2, 0x14, 0xae, 0x65, 0xb5, 0x1a, 0xae, + 0x77, 0xb5, 0x18, 0xae, 0x20, 0xb3, 0x1e, 0xae, + 0x03, 0xb5, 0x1c, 0xae, 0x76, 0xb1, 0x02, 0xae, + 0x44, 0xb5, 0x00, 0xae, 0xef, 0xb1, 0x06, 0xae, + 0x88, 0xb3, 0x04, 0xae, 0x19, 0xb2, 0x0a, 0xae, + 0x33, 0xb2, 0x08, 0xae, 0x65, 0xb2, 0x0e, 0xae, + 0x91, 0xb5, 0x0c, 0xae, 0x57, 0xb5, 0x32, 0xae, + 0xb1, 0xb5, 0x30, 0xae, 0xe6, 0xb5, 0x36, 0xae, + 0xfa, 0xb5, 0x34, 0xae, 0xbd, 0x8e, 0xde, 0x8a, + 0xd2, 0x9e, 0x22, 0x8f, 0x5d, 0x2e, 0x2d, 0x9a, + 0x3a, 0x2f, 0x23, 0xe6, 0x65, 0xce, 0x27, 0x8a, + 0x2d, 0x9a, 0x61, 0x2e, 0x29, 0xd7, 0xc9, 0xd6, + 0x3d, 0x15, 0xa9, 0xd6, 0x59, 0xd7, 0x29, 0xd6, + 0x62, 0x0e, 0xe9, 0x12, 0x2c, 0x11, 0xd8, 0x8a, + 0x2d, 0x9a, 0xdc, 0xa1, 0xad, 0x8e, 0x2d, 0x9e, + 0x6d, 0x2f, 0xc0, 0xef, 0x09, 0x8e, 0x5d, 0x2f, + 0xc6, 0xee, 0x00, 0x8e, 0x5d, 0x2f, 0xc5, 0xee, + 0x5a, 0x07, 0x55, 0xce, 0xc8, 0xa1, 0xe2, 0x61, + 0x08, 0x88, 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, + 0x2d, 0x98, 0xa1, 0xc5, 0xa9, 0x12, 0xc1, 0xc5, + 0x3f, 0x80, 0x21, 0xc1, 0x12, 0x8e, 0xe5, 0x0e, + 0xe3, 0x0e, 0x2d, 0x9e, 0x28, 0x2f, 0x2d, 0x90, + 0xb8, 0x12, 0x2f, 0xe6, 0xbc, 0xae, 0x0b, 0x8e, + 0x6d, 0x4a, 0x4e, 0x8a, 0x2b, 0x9a, 0x29, 0x2e, + 0x6b, 0x12, 0x6d, 0x2e, 0x69, 0xde, 0x6d, 0x0f, + 0x3e, 0xef, 0xbb, 0x07, 0x35, 0x8b, 0x2d, 0x9b, + 0x6d, 0x12, 0xa3, 0x4a, 0x49, 0x2e, 0x28, 0x2e, + 0x2d, 0xde, 0x2d, 0x8b, 0x2a, 0x0e, 0xd2, 0x9b, + 0x3d, 0xde, 0x38, 0x26, 0xbc, 0x27, 0xbd, 0xce, + 0x2c, 0x08, 0x2b, 0xce, 0x58, 0xae, 0x6c, 0x0f, + 0x2f, 0xee, 0x5f, 0xae, 0x7d, 0x12, 0x3b, 0x8a, + 0xa3, 0x4a, 0x2d, 0x9a, 0xdd, 0x89, 0x3d, 0x12, + 0x2d, 0x99, 0x39, 0x2e, 0x21, 0x12, 0xdc, 0xde, + 0x2a, 0x0e, 0x68, 0xde, 0x7d, 0x8f, 0x6b, 0x0e, + 0xd5, 0x9f, 0x69, 0xdd, 0xb1, 0xcc, 0x3c, 0xde, + 0x31, 0xcd, 0x32, 0xd7, 0x3d, 0xcb, 0x32, 0xd7, + 0x3d, 0xc8, 0x32, 0xd7, 0x3d, 0xc9, 0x32, 0xd7, + 0x3d, 0xce, 0x32, 0xd7, 0x3d, 0xcf, 0x32, 0xde, + 0x3d, 0xcc, 0x3d, 0x08, 0x3d, 0xcd, 0x26, 0x0e, + 0x38, 0x12, 0x6d, 0x0f, 0x2f, 0xef, 0x39, 0xae, + 0x3a, 0x0e, 0x78, 0x0e, 0x6c, 0xde, 0xb9, 0x83, + 0x34, 0x0e, 0x02, 0x93, 0xfd, 0x09, 0x7d, 0x12, + 0x4d, 0x08, 0x2c, 0xde, 0x2b, 0x0e, 0x6d, 0xdd, + 0x31, 0xcf, 0x5c, 0xdf, 0x5d, 0x09, 0x43, 0x83, + 0x59, 0x12, 0x02, 0x93, 0xfd, 0x09, 0xfc, 0x12, + 0x35, 0x8b, 0xa3, 0x4a, 0x2d, 0x9b, 0x60, 0x12, + 0x28, 0x2e, 0x27, 0x83, 0x4d, 0xde, 0x2d, 0x93, + 0x71, 0xd2, 0x4b, 0x0e, 0x7b, 0xce, 0x2d, 0xde, + 0x2d, 0x8b, 0xd2, 0x9b, 0x2a, 0x0e, 0x3d, 0xde, + 0x38, 0x26, 0xad, 0x8b, 0x2d, 0x9b, 0x58, 0x2f, + 0x28, 0xef, 0xba, 0x07, 0xbc, 0x27, 0xbd, 0xce, + 0x2e, 0xae, 0x5c, 0x27, 0x5d, 0xce, 0x2d, 0x8b, + 0x08, 0x8e, 0x2d, 0x9e, 0x29, 0x2e, 0x7d, 0xce, + 0x22, 0x8b, 0x79, 0x2e, 0x28, 0xde, 0x22, 0x0f, + 0x3e, 0xef, 0x29, 0xdd, 0x29, 0x0f, 0x3d, 0xef, + 0x87, 0x83, 0xad, 0x0f, 0x24, 0x93, 0x2a, 0xef, + 0xfe, 0x8e, 0x69, 0x08, 0x28, 0x9e, 0x7d, 0xde, + 0xfd, 0x09, 0x2b, 0xae, 0xf8, 0x8e, 0x68, 0x08, + 0x28, 0x9e, 0x7d, 0xde, 0xfd, 0x09, 0x26, 0x8a, + 0x2d, 0x9a, 0x61, 0x2e, 0x29, 0xd7, 0xc9, 0xd6, + 0x3d, 0x15, 0xa9, 0xd6, 0x59, 0xd7, 0x29, 0xd6, + 0x62, 0x0e, 0xe9, 0x12, 0x2c, 0x11, 0xe2, 0x61, + 0x7d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x51, 0xc1, + 0x2d, 0x9e, 0x3c, 0x17, 0x31, 0xc1, 0x6d, 0x4a, + 0xe0, 0x0e, 0x3d, 0x12, 0x97, 0x8a, 0xd5, 0x9a, + 0x28, 0x12, 0x59, 0xde, 0x4e, 0x8a, 0x2b, 0x9a, + 0x39, 0x2e, 0x7c, 0xde, 0x94, 0x8a, 0xd5, 0x9a, + 0x49, 0xde, 0x26, 0x8a, 0x2d, 0x9a, 0x68, 0x2e, + 0x69, 0xde, 0x6d, 0x0f, 0x34, 0xee, 0x7c, 0x12, + 0xb9, 0x83, 0x3a, 0x0e, 0x78, 0x0e, 0x6c, 0xde, + 0x02, 0x93, 0x34, 0x0e, 0x41, 0xcc, 0x51, 0xcd, + 0xfd, 0x09, 0x4c, 0xde, 0x26, 0x8a, 0x2d, 0x9a, + 0x71, 0x12, 0x6b, 0x2e, 0x7f, 0x0e, 0x69, 0xde, + 0x4d, 0x08, 0x31, 0xcf, 0x5c, 0xdf, 0x5d, 0x09, + 0x43, 0x83, 0x02, 0x93, 0xfd, 0x09, 0x69, 0x08, + 0x61, 0x2e, 0x39, 0xd7, 0x59, 0xd7, 0x3c, 0x15, + 0x39, 0xde, 0xeb, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x7d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x51, 0xc1, + 0x2d, 0x9e, 0x3c, 0x17, 0x31, 0xc1, 0x6d, 0x4a, + 0xe0, 0x0e, 0x3d, 0x12, 0x87, 0x8a, 0xd5, 0x9a, + 0x28, 0x12, 0x59, 0xde, 0x4e, 0x8a, 0x2b, 0x9a, + 0x39, 0x2e, 0x86, 0x8a, 0xd5, 0x9a, 0x49, 0xde, + 0x6c, 0xde, 0x6a, 0x0e, 0x69, 0xdd, 0x6d, 0x0f, + 0x3a, 0xee, 0x7c, 0x12, 0xb9, 0x83, 0x3a, 0x0e, + 0x78, 0x0e, 0x6c, 0xde, 0x02, 0x93, 0x34, 0x0e, + 0x41, 0xcc, 0x51, 0xcd, 0xfd, 0x09, 0x6c, 0xde, + 0x71, 0x12, 0x7f, 0x0e, 0x6a, 0x0e, 0x69, 0xdd, + 0x4d, 0x08, 0x31, 0xcf, 0x5c, 0xdf, 0x5d, 0x09, + 0x43, 0x83, 0x02, 0x93, 0xfd, 0x09, 0x69, 0x08, + 0x61, 0x2e, 0x39, 0xd7, 0x59, 0xd7, 0x3c, 0x15, + 0x39, 0xde, 0xeb, 0x0e, 0x2c, 0x11, 0x2d, 0x61, + 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, 0x58, 0x12, + 0xa1, 0xc5, 0xb9, 0x12, 0x81, 0xc5, 0x99, 0x84, + 0xc1, 0xc5, 0x69, 0x80, 0x21, 0xc1, 0x3f, 0x8e, + 0x00, 0x94, 0x2d, 0x9e, 0x27, 0x90, 0x6d, 0x4a, + 0x22, 0x8a, 0x2d, 0x9a, 0x29, 0x2e, 0x9d, 0xde, + 0x3d, 0x8a, 0x2d, 0x9a, 0x6d, 0x2e, 0xa9, 0xde, + 0x7c, 0x05, 0x26, 0xee, 0x65, 0x12, 0x70, 0x08, + 0xcd, 0x09, 0x2b, 0x0e, 0x05, 0x83, 0x2d, 0xde, + 0x33, 0x93, 0x7d, 0xde, 0x64, 0x12, 0xfd, 0x09, + 0x5d, 0x05, 0x23, 0xee, 0x09, 0x8f, 0x73, 0x08, + 0x65, 0x12, 0x2d, 0x9f, 0xcd, 0x09, 0x26, 0xde, + 0x2c, 0x2f, 0x2a, 0xee, 0xb1, 0x83, 0x7d, 0x12, + 0x30, 0x93, 0x64, 0x12, 0x22, 0xb1, 0x2d, 0x08, + 0x59, 0x05, 0x08, 0xee, 0xbd, 0x0f, 0x34, 0x12, + 0x2f, 0xee, 0x3c, 0x08, 0xef, 0x83, 0x6c, 0x12, + 0x2e, 0x93, 0xfd, 0x09, 0x72, 0x88, 0x9e, 0x8b, + 0x2b, 0x98, 0x2b, 0x9b, 0x74, 0x2e, 0x44, 0x2e, + 0x8b, 0xde, 0x6d, 0x08, 0x6b, 0xce, 0x98, 0xde, + 0x68, 0xce, 0xc2, 0x8b, 0x65, 0x12, 0xd2, 0x9b, + 0xcd, 0x09, 0xff, 0x83, 0x6c, 0x12, 0x2e, 0x93, + 0xfd, 0x09, 0x86, 0x2f, 0x2f, 0xea, 0x20, 0xae, + 0xcd, 0x83, 0x64, 0x12, 0x06, 0x93, 0x3d, 0x08, + 0x33, 0xb8, 0x3b, 0xae, 0x5a, 0x05, 0x21, 0xee, + 0x52, 0x8b, 0x65, 0x12, 0xd2, 0x9b, 0xcd, 0x09, + 0x27, 0x83, 0x7d, 0x08, 0x03, 0x93, 0x64, 0x12, + 0x3d, 0x08, 0xfd, 0x09, 0x24, 0xae, 0x58, 0x05, + 0x01, 0xee, 0x7d, 0x08, 0x64, 0x12, 0x8d, 0x09, + 0x6d, 0x0f, 0x03, 0xef, 0x3c, 0x08, 0x5f, 0x05, + 0x2a, 0xee, 0x65, 0x12, 0x76, 0x08, 0xcd, 0x09, + 0x64, 0x12, 0x2d, 0x61, 0x84, 0xb1, 0x5e, 0x05, + 0x2a, 0xee, 0xda, 0x8b, 0x65, 0x12, 0xd2, 0x9b, + 0xcd, 0x09, 0x64, 0x12, 0xaa, 0xb1, 0x09, 0x8b, + 0x2d, 0x9b, 0x28, 0x2f, 0x28, 0xef, 0xb1, 0x83, + 0x64, 0x12, 0x30, 0x93, 0xc8, 0xb0, 0x7c, 0x08, + 0x6c, 0x12, 0x71, 0x2e, 0x28, 0xd7, 0xc8, 0xd6, + 0x3d, 0x15, 0x88, 0xd6, 0xa8, 0xd6, 0x58, 0xd7, + 0x28, 0xd6, 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, + 0x5b, 0x05, 0x27, 0xee, 0x7c, 0x08, 0x64, 0x12, + 0xc5, 0xb8, 0x6d, 0x0f, 0xf9, 0xee, 0xb2, 0x8b, + 0x65, 0x12, 0xd2, 0x9b, 0xcd, 0x09, 0x3d, 0x08, + 0xe2, 0xa1, 0x2d, 0x61, 0x3d, 0x17, 0x51, 0xc1, + 0x7b, 0x83, 0xb1, 0xc1, 0x24, 0x93, 0x21, 0xc1, + 0xe3, 0x0e, 0x2d, 0x08, 0x31, 0x12, 0x3f, 0x0e, + 0xfd, 0x09, 0x21, 0xcc, 0x45, 0x83, 0x31, 0xcf, + 0x27, 0x93, 0xd2, 0x8b, 0x2d, 0x9b, 0x6e, 0x08, + 0x4c, 0x08, 0xfd, 0x09, 0x6d, 0x0f, 0x2a, 0xee, + 0x69, 0x83, 0x6e, 0x08, 0x27, 0x93, 0x7d, 0x08, + 0xfd, 0x09, 0xdc, 0xa1, 0x05, 0x83, 0x21, 0x93, + 0xfd, 0x09, 0x71, 0xdc, 0x6c, 0x08, 0x2d, 0x61, + 0xb3, 0xb1, 0x17, 0x83, 0x29, 0x12, 0x21, 0x93, + 0xfd, 0x09, 0x81, 0x83, 0x6d, 0x08, 0x26, 0x93, + 0xfd, 0x09, 0x2c, 0x0f, 0xcd, 0xef, 0x93, 0x83, + 0x6c, 0x08, 0x25, 0x93, 0xfd, 0x09, 0xf6, 0xa1, + 0x3d, 0x17, 0x51, 0xc1, 0x7b, 0x83, 0xb1, 0xc1, + 0x24, 0x93, 0x21, 0xc1, 0xe3, 0x0e, 0x2d, 0x08, + 0x31, 0x12, 0x3f, 0x0e, 0xfd, 0x09, 0x21, 0xcc, + 0x45, 0x83, 0x31, 0xcf, 0x27, 0x93, 0xd2, 0x8b, + 0x2d, 0x9b, 0x6f, 0x08, 0x4c, 0x08, 0xfd, 0x09, + 0x6d, 0x0f, 0x2a, 0xee, 0x69, 0x83, 0x6f, 0x08, + 0x27, 0x93, 0x7d, 0x08, 0xfd, 0x09, 0xdc, 0xa1, + 0x05, 0x83, 0x21, 0x93, 0xfd, 0x09, 0x71, 0xdc, + 0x6d, 0x08, 0x2d, 0x61, 0xa8, 0xb1, 0x17, 0x83, + 0x29, 0x12, 0x21, 0x93, 0xfd, 0x09, 0x81, 0x83, + 0x6d, 0x08, 0x26, 0x93, 0xfd, 0x09, 0x2c, 0x0f, + 0xcd, 0xef, 0x93, 0x83, 0x6c, 0x08, 0x25, 0x93, + 0xfd, 0x09, 0xf6, 0xa1, 0x7b, 0x83, 0x21, 0xc5, + 0x24, 0x93, 0x01, 0xc5, 0x35, 0x8f, 0x51, 0xc1, + 0x4f, 0x89, 0xa1, 0xc5, 0x69, 0x87, 0x81, 0xc5, + 0x3d, 0x17, 0xc1, 0xc5, 0x87, 0x81, 0x21, 0xc1, + 0xe3, 0x0e, 0x27, 0x80, 0xa1, 0x12, 0x27, 0x97, + 0xaf, 0x0e, 0x24, 0x91, 0x2d, 0x90, 0xfd, 0x09, + 0xd5, 0x9f, 0x2b, 0x99, 0x26, 0x8c, 0x0d, 0x8e, + 0x2d, 0x9e, 0xf2, 0x8d, 0x7d, 0x12, 0x2d, 0x9c, + 0x6f, 0x12, 0xd2, 0x9d, 0xdd, 0x09, 0x7d, 0x12, + 0x21, 0x8e, 0x2d, 0x9e, 0x6d, 0x12, 0xdd, 0x09, + 0x45, 0x83, 0xa1, 0xcf, 0x7a, 0xde, 0x27, 0x93, + 0x63, 0x12, 0x4d, 0x08, 0xfd, 0x09, 0x89, 0x12, + 0x7e, 0x12, 0x6f, 0x12, 0xbd, 0x09, 0x7e, 0x12, + 0x6d, 0x12, 0xbd, 0x09, 0x8d, 0x0f, 0x28, 0xee, + 0x63, 0x12, 0x7d, 0x08, 0xbd, 0x09, 0xf2, 0xa1, + 0x05, 0x83, 0x91, 0x8e, 0x28, 0x9e, 0x21, 0x93, + 0xfd, 0x09, 0x1d, 0xde, 0xeb, 0x8e, 0x28, 0x9e, + 0x2d, 0xde, 0x2d, 0x0f, 0x63, 0xee, 0x1f, 0x0f, + 0x61, 0xe6, 0x29, 0x0e, 0xe5, 0x83, 0x7d, 0xde, + 0x22, 0x93, 0x91, 0x8a, 0x0a, 0x8c, 0x28, 0x9a, + 0xd5, 0x9c, 0x90, 0x84, 0x21, 0x0e, 0x28, 0x94, + 0xfd, 0x09, 0x97, 0xdf, 0x90, 0x88, 0x0f, 0xde, + 0x28, 0x98, 0x87, 0xde, 0x7d, 0x08, 0x67, 0x3e, + 0x6b, 0xc6, 0x7d, 0x08, 0x63, 0x12, 0xbd, 0x09, + 0x0d, 0x0f, 0x2a, 0xee, 0x2d, 0x8a, 0x7f, 0x12, + 0x72, 0x0e, 0xd2, 0x9a, 0x79, 0x26, 0x2e, 0xae, + 0x2d, 0x8b, 0x2c, 0x9b, 0xec, 0x8a, 0x0d, 0x0f, + 0x28, 0x9a, 0x79, 0xce, 0x69, 0xde, 0x0b, 0x8b, + 0xd5, 0x9b, 0x68, 0xce, 0x0f, 0x8b, 0x2d, 0x9b, + 0x7c, 0xcf, 0x24, 0xee, 0x6f, 0x2f, 0x0c, 0xde, + 0x29, 0xe6, 0x08, 0x27, 0x0c, 0xce, 0x2e, 0xae, + 0x0c, 0x07, 0x0c, 0xce, 0x0b, 0x8c, 0x4e, 0x8a, + 0x2d, 0x9c, 0x22, 0x8b, 0x1f, 0x42, 0x2b, 0x9a, + 0x09, 0x2e, 0x7f, 0x2e, 0x08, 0xde, 0x0d, 0x0f, + 0x22, 0xef, 0x6d, 0xde, 0xeb, 0x83, 0x1f, 0x93, + 0x7d, 0x12, 0xfd, 0x09, 0x6d, 0x0f, 0x79, 0x12, + 0x2a, 0xee, 0x6d, 0xde, 0xdd, 0x09, 0x29, 0xae, + 0x7d, 0x08, 0x63, 0x12, 0xbd, 0x09, 0x17, 0x83, + 0x21, 0x93, 0xfd, 0x09, 0x81, 0x83, 0x6d, 0x08, + 0x26, 0x93, 0xfd, 0x09, 0x51, 0xa1, 0x2d, 0x61, + 0x7b, 0x83, 0x21, 0xc5, 0x24, 0x93, 0x01, 0xc5, + 0x3d, 0x17, 0x51, 0xc1, 0xa1, 0xc5, 0xff, 0x87, + 0x81, 0xc5, 0x69, 0x85, 0xc1, 0xc5, 0x87, 0x81, + 0x21, 0xc1, 0xe3, 0x0e, 0x24, 0x80, 0x81, 0x12, + 0x27, 0x95, 0x8f, 0x0e, 0x24, 0x91, 0x2d, 0x90, + 0xfd, 0x09, 0x28, 0x97, 0x3d, 0x8d, 0x26, 0x8c, + 0x21, 0x8f, 0xc2, 0x8e, 0x2d, 0x9d, 0x2d, 0x9c, + 0x6f, 0x12, 0x7e, 0x12, 0x2d, 0x9f, 0xdd, 0x09, + 0x7e, 0x12, 0x6c, 0x12, 0xd2, 0x9e, 0xdd, 0x09, + 0x45, 0x83, 0x81, 0xcf, 0x74, 0xde, 0x27, 0x93, + 0x63, 0x12, 0x4d, 0x08, 0xfd, 0x09, 0x59, 0x12, + 0x7d, 0x12, 0x6f, 0x12, 0x9d, 0x09, 0x7d, 0x12, + 0x6c, 0x12, 0x9d, 0x09, 0x5d, 0x0f, 0x28, 0xee, + 0x63, 0x12, 0x7d, 0x08, 0x9d, 0x09, 0xf2, 0xa1, + 0x05, 0x83, 0x9c, 0x8e, 0x28, 0x9e, 0x21, 0x93, + 0xfd, 0x09, 0x3d, 0xde, 0x96, 0x8e, 0x28, 0x9e, + 0xad, 0xde, 0xad, 0x0f, 0x21, 0xef, 0x7d, 0x08, + 0x63, 0x12, 0x9d, 0x09, 0x17, 0x83, 0x21, 0x93, + 0xfd, 0x09, 0x81, 0x83, 0x6d, 0x08, 0x26, 0x93, + 0xfd, 0x09, 0xe4, 0xa1, 0x3f, 0x0f, 0x2f, 0xe7, + 0xde, 0xa1, 0x0b, 0x8e, 0xa9, 0x0e, 0x75, 0xde, + 0x2d, 0x9e, 0x3d, 0x42, 0xb5, 0x83, 0x9c, 0x8a, + 0x0f, 0x8e, 0x3c, 0x93, 0xd0, 0x9e, 0x28, 0x9a, + 0x1d, 0xde, 0xa1, 0x0e, 0x4e, 0x8e, 0x4e, 0x12, + 0x2b, 0x9e, 0x3d, 0x08, 0x0d, 0x2e, 0x23, 0x8e, + 0x2d, 0x9e, 0x2f, 0x2e, 0x2d, 0xde, 0x21, 0xcf, + 0x0d, 0xb6, 0x29, 0x12, 0x0e, 0x8a, 0xd5, 0x9a, + 0x59, 0xde, 0x9f, 0x8a, 0x28, 0x9a, 0x79, 0xdf, + 0x69, 0xde, 0x29, 0x3e, 0x9f, 0x8a, 0x7d, 0x08, + 0x28, 0x9a, 0x29, 0xc6, 0x63, 0x12, 0x9d, 0x09, + 0x5d, 0x0f, 0x0f, 0xee, 0x1c, 0x0f, 0x37, 0xe7, + 0x1e, 0x0f, 0x3f, 0xe7, 0x1e, 0x0f, 0x1a, 0x12, + 0x38, 0xef, 0x12, 0x0e, 0x86, 0x8b, 0x6e, 0x12, + 0x87, 0x9b, 0x18, 0x4a, 0x62, 0x0b, 0x2d, 0x8e, + 0x68, 0x26, 0x39, 0x2e, 0x2e, 0x9e, 0x1c, 0x2e, + 0x14, 0x0d, 0x1d, 0x4a, 0x22, 0xae, 0x2d, 0x8f, + 0x2a, 0x12, 0x22, 0x0e, 0xd3, 0x9f, 0x2c, 0x26, + 0x24, 0xae, 0x2d, 0x8f, 0x2a, 0x12, 0x22, 0x0e, + 0xd2, 0x9f, 0x2c, 0x26, 0x2e, 0xae, 0x2d, 0x8e, + 0x2c, 0x9e, 0x9b, 0x8f, 0x3c, 0x8d, 0x28, 0x9f, + 0x2d, 0x9d, 0x5d, 0x0f, 0x2c, 0xce, 0x2c, 0xde, + 0x0f, 0x8f, 0xd5, 0x9f, 0x2c, 0xce, 0x34, 0x8f, + 0x1c, 0xce, 0x24, 0xee, 0x2a, 0x2f, 0x2c, 0xd9, + 0x29, 0xe6, 0x2e, 0x27, 0x2c, 0xc9, 0x2e, 0xae, + 0x2d, 0x07, 0x2c, 0xc9, 0x22, 0x8e, 0x2d, 0x9e, + 0x2f, 0x2e, 0x2d, 0xde, 0x2d, 0x0f, 0xa2, 0xef, + 0x65, 0xde, 0xeb, 0x83, 0x1f, 0x93, 0x75, 0x12, + 0xfd, 0x09, 0x6d, 0x0f, 0x79, 0x12, 0xaa, 0xee, + 0x65, 0xde, 0xdd, 0x09, 0xa9, 0xa1, 0x2d, 0x61, + 0x7b, 0x83, 0x21, 0xc5, 0x24, 0x93, 0x01, 0xc5, + 0x0b, 0x8c, 0x51, 0xc1, 0x3d, 0x17, 0xa1, 0xc5, + 0x2d, 0x9c, 0x81, 0xc5, 0xc1, 0xc5, 0x25, 0x81, + 0x21, 0xc1, 0xe3, 0x0e, 0x2d, 0x91, 0x11, 0x12, + 0x1f, 0x0e, 0xfd, 0x09, 0x87, 0x8e, 0x26, 0x8f, + 0x24, 0x9e, 0x21, 0x89, 0x69, 0x87, 0x2d, 0x9f, + 0x6c, 0x12, 0x72, 0x12, 0x2d, 0x99, 0x2d, 0x09, + 0x6a, 0x12, 0x72, 0x12, 0x27, 0x97, 0x2d, 0x09, + 0x45, 0x83, 0x11, 0xcf, 0x27, 0x93, 0x2d, 0x8b, + 0x3c, 0x9b, 0xda, 0x8e, 0x62, 0x12, 0x4c, 0x08, + 0xd2, 0x9e, 0xfd, 0x09, 0xa9, 0x12, 0x7d, 0x12, + 0x6c, 0x12, 0xbd, 0x09, 0x7d, 0x12, 0x6a, 0x12, + 0xbd, 0x09, 0xad, 0x0f, 0x28, 0xee, 0x62, 0x12, + 0x7d, 0x08, 0xbd, 0x09, 0xf1, 0xa1, 0x8b, 0x8e, + 0x05, 0x83, 0x28, 0x9e, 0x21, 0x93, 0x3d, 0xde, + 0xea, 0x8e, 0x28, 0x9e, 0xcd, 0xde, 0x9d, 0x8e, + 0xfd, 0x09, 0x28, 0x9e, 0x9d, 0xde, 0xfc, 0x8e, + 0x9d, 0x0f, 0x28, 0x9e, 0x8d, 0xde, 0x21, 0xef, + 0x7d, 0x08, 0x62, 0x12, 0xbd, 0x09, 0x17, 0x83, + 0x21, 0x93, 0xfd, 0x09, 0x81, 0x83, 0x6d, 0x08, + 0x26, 0x93, 0xfd, 0x09, 0xed, 0xa1, 0x8d, 0x0f, + 0x2f, 0xef, 0xde, 0xa1, 0x3f, 0x0f, 0x2f, 0xe7, + 0xdd, 0xa1, 0xcf, 0x0f, 0x2f, 0xe7, 0xc0, 0xa1, + 0xe9, 0x83, 0xea, 0x8b, 0x3f, 0x93, 0x28, 0x9b, + 0x8b, 0x8a, 0x8a, 0x86, 0x28, 0x96, 0x28, 0x9a, + 0x5d, 0x08, 0xfd, 0x09, 0xb5, 0xdf, 0x49, 0x12, + 0xa5, 0xde, 0x8a, 0x8e, 0xab, 0x3e, 0x28, 0x9e, + 0xad, 0xc6, 0xe5, 0x86, 0xe5, 0x8e, 0x28, 0x96, + 0x28, 0x9e, 0xb5, 0xdf, 0xa5, 0xde, 0x45, 0x3e, + 0x87, 0x87, 0x4d, 0xc6, 0x22, 0x86, 0x6d, 0x0f, + 0x24, 0x97, 0x2d, 0x96, 0x2b, 0xef, 0x69, 0x83, + 0x7d, 0x08, 0x27, 0x93, 0x62, 0x12, 0xfd, 0x09, + 0x3f, 0x4a, 0x4e, 0x89, 0x65, 0x12, 0x2b, 0x99, + 0x2a, 0x2e, 0x6d, 0x2e, 0x29, 0xde, 0x2d, 0x0f, + 0x26, 0xef, 0x66, 0xde, 0xeb, 0x83, 0x1f, 0x93, + 0x76, 0x12, 0xfd, 0x09, 0x6d, 0x0f, 0x29, 0xee, + 0x79, 0x12, 0x66, 0xde, 0xbd, 0x09, 0xe7, 0x8e, + 0x28, 0x9e, 0x2d, 0xde, 0x2d, 0x0f, 0x26, 0xee, + 0x9b, 0x0e, 0x26, 0xde, 0x2b, 0x0e, 0x2d, 0xdd, + 0x2d, 0x0f, 0x28, 0xef, 0x89, 0x0e, 0x2c, 0x08, + 0x27, 0xce, 0x81, 0x0e, 0xcf, 0x4a, 0x2a, 0x2e, + 0xad, 0x2e, 0x25, 0xde, 0x2d, 0x0f, 0x89, 0xef, + 0x67, 0xdf, 0x77, 0x12, 0x89, 0x0e, 0x51, 0x83, + 0x47, 0xde, 0x1f, 0x93, 0x28, 0x12, 0xfd, 0x09, + 0x6d, 0x0f, 0x79, 0x12, 0xb4, 0xee, 0x6d, 0xdf, + 0xbd, 0x09, 0xbb, 0xa1, 0x7b, 0x83, 0x21, 0xc5, + 0x24, 0x93, 0x01, 0xc5, 0x3b, 0x8c, 0x51, 0xc1, + 0x3d, 0x17, 0xa1, 0xc5, 0xd5, 0x9c, 0x81, 0xc5, + 0x9d, 0x85, 0xc1, 0xc5, 0x2b, 0x95, 0x21, 0xc1, + 0xe6, 0x0e, 0x11, 0x12, 0x1f, 0x0e, 0xfd, 0x09, + 0x87, 0x8e, 0x26, 0x86, 0x24, 0x9e, 0x69, 0x8f, + 0x2d, 0x96, 0x79, 0x08, 0x65, 0x12, 0x27, 0x9f, + 0x2d, 0x09, 0xfd, 0x12, 0x79, 0x08, 0x21, 0x8e, + 0x2d, 0x9e, 0x6d, 0x12, 0xfd, 0x09, 0x45, 0x83, + 0x11, 0xcf, 0x76, 0xde, 0x27, 0x93, 0x6a, 0x08, + 0x4d, 0x08, 0xfd, 0x09, 0x59, 0x12, 0x76, 0x08, + 0x65, 0x12, 0x3d, 0x09, 0x6d, 0x12, 0x76, 0x08, + 0x3d, 0x09, 0x5d, 0x0f, 0x28, 0xee, 0x6a, 0x08, + 0x7d, 0x08, 0x3d, 0x09, 0xf3, 0xa1, 0x05, 0x83, + 0xb6, 0x8e, 0x21, 0x93, 0x28, 0x9e, 0x88, 0x89, + 0xfd, 0x09, 0x2d, 0xde, 0x28, 0x99, 0xba, 0xde, + 0xbd, 0x0f, 0x2f, 0xef, 0xba, 0xae, 0x2f, 0x0f, + 0x2f, 0xe7, 0xb9, 0xae, 0x3f, 0x8a, 0x4e, 0x88, + 0xd0, 0x9a, 0x2d, 0x84, 0x79, 0xde, 0x54, 0x0e, + 0x6a, 0xde, 0x0b, 0x86, 0x25, 0x4a, 0x2b, 0x98, + 0x25, 0x94, 0x2b, 0x2e, 0x6d, 0x0f, 0x2f, 0xef, + 0x2e, 0xae, 0x5e, 0x0e, 0x8a, 0xde, 0x2b, 0x0e, + 0x3f, 0x83, 0x3d, 0xdd, 0x23, 0x93, 0xb6, 0x8a, + 0x31, 0xcf, 0x28, 0x9a, 0x27, 0x0e, 0x47, 0x12, + 0x3e, 0x08, 0xfd, 0x09, 0x31, 0x2e, 0x6e, 0xcd, + 0x7d, 0x08, 0x08, 0x88, 0xd5, 0x98, 0x6c, 0xc6, + 0xdc, 0xd9, 0x69, 0x83, 0xcc, 0xd8, 0x27, 0x93, + 0xab, 0xde, 0xb1, 0x8f, 0xb1, 0x88, 0x28, 0x9f, + 0x28, 0x98, 0x6a, 0x08, 0x5b, 0xdf, 0x4b, 0xde, + 0xcb, 0x3e, 0x8d, 0x89, 0xcc, 0xc6, 0x32, 0x8f, + 0xfd, 0x09, 0xb3, 0x88, 0xad, 0x0f, 0x28, 0x98, + 0x2d, 0x9f, 0x28, 0x99, 0x29, 0xef, 0x6c, 0x08, + 0x6a, 0xce, 0x27, 0xae, 0x4d, 0x8b, 0x2d, 0x8a, + 0x2d, 0x9b, 0x25, 0x9a, 0x75, 0x2e, 0x68, 0x2f, + 0x7a, 0xce, 0x2f, 0xe6, 0x6a, 0xce, 0x6c, 0x12, + 0x6d, 0x2e, 0x69, 0xde, 0x6d, 0x0f, 0x2a, 0xee, + 0x2c, 0x8f, 0xb9, 0x0e, 0x34, 0xce, 0xb1, 0x0e, + 0x3b, 0xce, 0x34, 0xae, 0x6b, 0xde, 0x6d, 0x0f, + 0x3b, 0xee, 0xb9, 0x0e, 0x64, 0xde, 0xb1, 0x0e, + 0x6d, 0x0f, 0x3c, 0xef, 0x6e, 0xdd, 0x89, 0x28, + 0x8d, 0x0f, 0x2e, 0xeb, 0xad, 0x0f, 0x25, 0xef, + 0x6c, 0x08, 0xb9, 0x0e, 0x3d, 0x2e, 0x64, 0xce, + 0xb1, 0x0e, 0x6c, 0xce, 0x8d, 0x08, 0x8c, 0x8f, + 0x28, 0x9f, 0x8c, 0xce, 0x8d, 0x8f, 0x09, 0x8a, + 0xd5, 0x9a, 0x28, 0x9f, 0x3c, 0xde, 0xd2, 0x8b, + 0x2a, 0x9b, 0x39, 0xce, 0x0f, 0x8a, 0x75, 0x2f, + 0x2d, 0x9a, 0x6f, 0xcf, 0x24, 0xe7, 0xac, 0x2f, + 0x3f, 0xde, 0x29, 0xe6, 0x39, 0x27, 0x3f, 0xce, + 0x2e, 0xae, 0x3c, 0x07, 0x3f, 0xce, 0x22, 0x8f, + 0x2d, 0x9f, 0x3d, 0x2e, 0x2c, 0xde, 0x2d, 0x0f, + 0x39, 0xef, 0x64, 0xdf, 0x74, 0x12, 0xb9, 0x0e, + 0x51, 0x83, 0x44, 0xde, 0x1f, 0x93, 0x28, 0x12, + 0x8f, 0xb9, 0x6d, 0x0f, 0x79, 0x12, 0x24, 0xee, + 0x6d, 0xdf, 0x87, 0x83, 0x24, 0x93, 0xfd, 0x09, + 0x29, 0xae, 0x7d, 0x08, 0x6a, 0x08, 0x3d, 0x09, + 0x17, 0x83, 0x21, 0x93, 0xfd, 0x09, 0x81, 0x83, + 0x6d, 0x08, 0x26, 0x93, 0xfd, 0x09, 0x1c, 0xa1, + 0x7b, 0x83, 0x21, 0xc5, 0x3d, 0x17, 0x01, 0xc5, + 0x24, 0x93, 0x51, 0xc1, 0xa1, 0xc5, 0x81, 0xc5, + 0xbd, 0x85, 0xc1, 0xc5, 0x9f, 0x84, 0x21, 0xc1, + 0xe3, 0x0e, 0x3b, 0x8e, 0xd1, 0x12, 0x28, 0x95, + 0xdf, 0x0e, 0xd5, 0x9e, 0xc6, 0x12, 0xfd, 0x09, + 0x2b, 0x94, 0x87, 0x8f, 0x26, 0x89, 0x24, 0x9f, + 0x21, 0x8d, 0x69, 0x8c, 0x2d, 0x99, 0x6a, 0x12, + 0x7f, 0x08, 0x2d, 0x9d, 0x3d, 0x09, 0x6e, 0x12, + 0x7f, 0x08, 0x27, 0x9c, 0x3d, 0x09, 0x45, 0x83, + 0xd1, 0xcf, 0x77, 0xde, 0x27, 0x93, 0x6b, 0x08, + 0x4d, 0x08, 0xfd, 0x09, 0x39, 0x12, 0x70, 0x08, + 0x6a, 0x12, 0x0d, 0x09, 0x70, 0x08, 0x6e, 0x12, + 0x0d, 0x09, 0x3d, 0x0f, 0x28, 0xee, 0x6b, 0x08, + 0x7d, 0x08, 0x0d, 0x09, 0xf2, 0xa1, 0x05, 0x83, + 0x21, 0x93, 0xfd, 0x09, 0x36, 0xde, 0x9a, 0x0e, + 0xb6, 0xdd, 0xbd, 0x0f, 0x93, 0x12, 0x21, 0xef, + 0x7d, 0x08, 0x6b, 0x08, 0x0d, 0x09, 0x17, 0x83, + 0x21, 0x93, 0xfd, 0x09, 0x81, 0x83, 0x6d, 0x08, + 0x26, 0x93, 0xfd, 0x09, 0xe6, 0xa1, 0x3f, 0x0f, + 0x2f, 0xe7, 0xde, 0xa1, 0x0b, 0x8d, 0xbb, 0x83, + 0x3e, 0x42, 0x20, 0x93, 0xbd, 0x8a, 0x3f, 0x12, + 0x28, 0x9a, 0x0c, 0x8c, 0xfd, 0x09, 0x13, 0xdc, + 0xd5, 0x9c, 0xaf, 0xde, 0x2d, 0x89, 0x4e, 0x8c, + 0x49, 0x12, 0x2b, 0x9c, 0x3f, 0x2e, 0x03, 0xdf, + 0x4f, 0x3e, 0x6d, 0x0f, 0x43, 0xcf, 0x53, 0xcc, + 0x2b, 0xef, 0x69, 0x83, 0x7d, 0x08, 0x27, 0x93, + 0x6b, 0x08, 0xfd, 0x09, 0x98, 0x0e, 0x03, 0x12, + 0xad, 0x0f, 0x29, 0xef, 0x1c, 0x08, 0x16, 0xce, + 0x26, 0xae, 0x2d, 0x8d, 0x65, 0x12, 0x6c, 0x0e, + 0x25, 0x9d, 0x19, 0x2f, 0x66, 0xce, 0x29, 0xe6, + 0xc8, 0x0e, 0x13, 0xce, 0xcf, 0x12, 0x32, 0x8a, + 0x2d, 0x9a, 0x6c, 0x2e, 0x19, 0xde, 0x1d, 0x0f, + 0x2a, 0xee, 0x1c, 0x08, 0xb9, 0x0e, 0x14, 0xce, + 0xb1, 0x0e, 0x1f, 0xcd, 0x26, 0xae, 0x1f, 0xdd, + 0x1d, 0x0f, 0x25, 0xee, 0xad, 0x0f, 0x2b, 0xef, + 0x1c, 0x08, 0xb9, 0x0e, 0x14, 0xce, 0xb1, 0x0e, + 0x19, 0xce, 0x08, 0x0e, 0x0d, 0x8d, 0x0f, 0xde, + 0xd5, 0x9d, 0xd2, 0x8a, 0x0e, 0xce, 0x3c, 0x8d, + 0x2a, 0x9a, 0x2d, 0x9d, 0x65, 0x2f, 0x93, 0x12, + 0x1d, 0xcf, 0x24, 0xe7, 0xaf, 0x2f, 0x0d, 0xde, + 0x29, 0xe6, 0x0e, 0x27, 0x0d, 0xce, 0x2e, 0xae, + 0x0d, 0x07, 0x0d, 0xce, 0x22, 0x8c, 0x2d, 0x9c, + 0x0c, 0x2e, 0x3f, 0xde, 0x3d, 0x0f, 0xb5, 0xef, + 0x64, 0xdf, 0x74, 0x12, 0xb9, 0x0e, 0x51, 0x83, + 0x44, 0xde, 0x1f, 0x93, 0x38, 0x12, 0xfd, 0x09, + 0x6d, 0x0f, 0x79, 0x12, 0xa0, 0xee, 0x6c, 0xdf, + 0x87, 0x83, 0x24, 0x93, 0xfd, 0x09, 0xa5, 0xa1, + 0x3e, 0x8b, 0x51, 0xc1, 0x3c, 0x88, 0xa1, 0xc5, + 0x39, 0x17, 0xd5, 0x9b, 0xd5, 0x98, 0x61, 0xc0, + 0x68, 0xd8, 0x58, 0xde, 0x6a, 0x26, 0x2e, 0xef, + 0x5d, 0x08, 0x28, 0xae, 0x6d, 0x08, 0x6b, 0xce, + 0x5b, 0xcc, 0x5c, 0x08, 0x3f, 0x8a, 0x3d, 0x88, + 0xd5, 0x9a, 0xa9, 0xd8, 0xb9, 0xde, 0xa4, 0x26, + 0x28, 0xee, 0xad, 0x08, 0x2c, 0x89, 0xab, 0xce, + 0xbb, 0xcc, 0xab, 0xdd, 0xad, 0x0f, 0x28, 0xec, + 0x2d, 0x86, 0x2f, 0x89, 0xad, 0x96, 0xa8, 0xce, + 0x38, 0x88, 0x21, 0x8a, 0xb9, 0xde, 0xab, 0xd9, + 0xb3, 0x07, 0x7b, 0xde, 0xad, 0x05, 0xb9, 0xce, + 0x7b, 0xce, 0x38, 0xef, 0xdc, 0x86, 0x2d, 0x96, + 0xf5, 0x83, 0x61, 0x12, 0x6c, 0x0e, 0x26, 0x93, + 0x7d, 0x08, 0x71, 0xcf, 0xfd, 0x09, 0x61, 0xdf, + 0x69, 0x0f, 0x3a, 0xee, 0x69, 0x0f, 0x20, 0xea, + 0x6f, 0x0f, 0x0b, 0xee, 0x6e, 0x0f, 0x38, 0xef, + 0x5e, 0x0c, 0x0f, 0xae, 0x7d, 0x05, 0xc6, 0xee, + 0xdf, 0x86, 0x5f, 0x07, 0x2d, 0x96, 0xc4, 0xa1, + 0x68, 0x0f, 0x24, 0xee, 0x27, 0x8b, 0x2d, 0x9b, + 0x79, 0x2f, 0x2a, 0xed, 0x51, 0x0c, 0x39, 0xae, + 0x5b, 0x0c, 0x3f, 0xae, 0x54, 0x0c, 0x3d, 0xae, + 0xb0, 0x02, 0x2d, 0x08, 0x21, 0x83, 0x21, 0x8f, + 0xd5, 0x9f, 0x21, 0x93, 0xfd, 0x09, 0x2c, 0xce, + 0x39, 0x8f, 0x2c, 0xce, 0x25, 0x8e, 0xd5, 0x9e, + 0xad, 0xce, 0xd2, 0x03, 0xd2, 0xa1, 0x5d, 0x0f, + 0x28, 0xee, 0x27, 0x83, 0x7a, 0x12, 0x24, 0x93, + 0xfd, 0x09, 0xb0, 0x02, 0x7f, 0x08, 0x71, 0x2e, + 0x68, 0xd7, 0xa8, 0xd6, 0x58, 0xde, 0xe8, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x39, 0x17, 0x51, 0xc1, + 0x2d, 0x89, 0xa1, 0xc5, 0x2c, 0x99, 0x81, 0xc5, + 0xdb, 0x85, 0x61, 0xc1, 0x34, 0x8a, 0x24, 0x95, + 0xd5, 0x9a, 0x49, 0xde, 0x69, 0xd9, 0x69, 0x05, + 0x28, 0xef, 0x7d, 0x08, 0x6d, 0x05, 0x2a, 0xef, + 0x27, 0xae, 0x49, 0x05, 0xd6, 0xee, 0x69, 0x06, + 0x7a, 0x12, 0xd4, 0xa1, 0x4d, 0x05, 0x2e, 0xee, + 0x6d, 0x06, 0x75, 0x07, 0x68, 0x05, 0x28, 0xef, + 0x2d, 0x99, 0x6c, 0x05, 0x2b, 0xef, 0x24, 0xae, + 0x48, 0x05, 0xd6, 0xee, 0x68, 0x06, 0xd7, 0xa1, + 0x4c, 0x05, 0x2e, 0xee, 0x6c, 0x06, 0x55, 0x07, + 0x65, 0x05, 0x25, 0xef, 0xad, 0x08, 0x64, 0x05, + 0x24, 0xef, 0xbd, 0x08, 0x6b, 0x05, 0x27, 0xef, + 0x3b, 0xae, 0x45, 0x05, 0xaf, 0x08, 0xda, 0xee, + 0xda, 0xa1, 0x44, 0x05, 0xbf, 0x08, 0xdb, 0xee, + 0xdb, 0xa1, 0x4b, 0x05, 0x21, 0xee, 0x9c, 0x84, + 0x2b, 0x94, 0x87, 0xde, 0x8d, 0x0f, 0x2e, 0xef, + 0xaf, 0x07, 0x29, 0xae, 0x8c, 0x0f, 0x2f, 0xef, + 0xbf, 0x07, 0x6b, 0x06, 0x6a, 0x05, 0x2f, 0xef, + 0x23, 0xae, 0x4a, 0x05, 0x21, 0xee, 0x82, 0x84, + 0x2b, 0x94, 0x87, 0xde, 0x8d, 0x0f, 0x2e, 0xef, + 0xae, 0x07, 0x29, 0xae, 0x8c, 0x0f, 0x2f, 0xef, + 0xbe, 0x07, 0x6a, 0x06, 0x35, 0x84, 0xd5, 0x94, + 0x67, 0xce, 0x6d, 0x08, 0x47, 0xcf, 0x34, 0x88, + 0xbe, 0x02, 0xd5, 0x98, 0x7d, 0x0f, 0x6b, 0xce, + 0x2e, 0xee, 0x24, 0x8a, 0x9d, 0x09, 0x5d, 0x0f, + 0x28, 0xee, 0x27, 0x8a, 0x7a, 0x12, 0x2d, 0x9a, + 0x9d, 0x09, 0xad, 0x0f, 0x29, 0xee, 0x75, 0x12, + 0x6f, 0x08, 0x9d, 0x09, 0xbd, 0x0f, 0x29, 0xee, + 0x74, 0x12, 0x6e, 0x08, 0x9d, 0x09, 0x7c, 0x08, + 0x71, 0x2e, 0x68, 0xd7, 0x88, 0xd6, 0xa8, 0xd6, + 0x58, 0xde, 0xeb, 0x0e, 0x29, 0x15, 0x2d, 0x61, + 0x39, 0x17, 0x51, 0xc1, 0x2d, 0x89, 0xb1, 0xc1, + 0x3d, 0x99, 0x61, 0xc1, 0x3a, 0x8a, 0xd5, 0x9a, + 0x49, 0xd9, 0xb9, 0xde, 0x49, 0x05, 0x28, 0xef, + 0x7d, 0x08, 0x4d, 0x05, 0x2a, 0xef, 0x27, 0xae, + 0xb9, 0x05, 0xd6, 0xee, 0x49, 0x06, 0x7a, 0x12, + 0xd4, 0xa1, 0xbd, 0x05, 0x2e, 0xee, 0x4d, 0x06, + 0x71, 0x07, 0x48, 0x05, 0x28, 0xef, 0x2d, 0x99, + 0x4c, 0x05, 0x2b, 0xef, 0x24, 0xae, 0xb8, 0x05, + 0xd6, 0xee, 0x48, 0x06, 0xd7, 0xa1, 0xbc, 0x05, + 0x2e, 0xee, 0x4c, 0x06, 0x51, 0x07, 0x3b, 0x8a, + 0x49, 0xce, 0x3a, 0x88, 0xb9, 0xcf, 0xdb, 0x87, + 0xbf, 0x02, 0x6d, 0x08, 0xd5, 0x98, 0x7d, 0x0f, + 0x6b, 0xce, 0x24, 0x97, 0x2e, 0xee, 0x2b, 0x8a, + 0xbd, 0x09, 0x5d, 0x0f, 0x29, 0xee, 0x7a, 0x12, + 0x6a, 0x08, 0xbd, 0x09, 0x61, 0xdf, 0xb1, 0xdc, + 0x51, 0xdd, 0xee, 0x0e, 0x29, 0x15, 0x2d, 0x61, + 0x39, 0x17, 0x51, 0xc1, 0x7d, 0x08, 0xb1, 0xc1, + 0x61, 0xc1, 0x2d, 0x8a, 0xd5, 0x9a, 0x59, 0xde, + 0x2c, 0x8a, 0xd7, 0x9a, 0x49, 0xde, 0x49, 0xce, + 0xbc, 0x02, 0x79, 0xce, 0x69, 0xd9, 0x6c, 0x05, + 0x2f, 0xef, 0x29, 0xae, 0x7b, 0x12, 0x7c, 0x0d, + 0x7d, 0x6e, 0x6d, 0x05, 0x2f, 0xef, 0x3f, 0xae, + 0x4d, 0x05, 0x2f, 0xef, 0x22, 0xae, 0x79, 0x07, + 0x5c, 0x05, 0x2a, 0xee, 0x72, 0x88, 0x2b, 0x98, + 0x6b, 0xdf, 0x6c, 0x0e, 0x6b, 0xcf, 0x2b, 0xae, + 0x9e, 0x88, 0x2b, 0x98, 0x6b, 0xdf, 0x6c, 0x0e, + 0x6b, 0xcf, 0x7d, 0x0f, 0x28, 0xee, 0xdb, 0x83, + 0x6e, 0x08, 0x24, 0x93, 0xfd, 0x09, 0x61, 0xdf, + 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, 0x29, 0x15, + 0x39, 0x17, 0x51, 0xc1, 0x7d, 0x08, 0xb1, 0xc1, + 0x61, 0xc1, 0x2d, 0x8a, 0xd5, 0x9a, 0x59, 0xde, + 0x2c, 0x8a, 0xd4, 0x9a, 0x49, 0xde, 0x49, 0xce, + 0xbd, 0x02, 0x79, 0xce, 0x69, 0xd9, 0x6c, 0x05, + 0x2f, 0xef, 0x29, 0xae, 0x7b, 0x12, 0x7c, 0x0d, + 0x7d, 0x6e, 0x6d, 0x05, 0x2f, 0xef, 0x3f, 0xae, + 0x4d, 0x05, 0x2f, 0xef, 0x22, 0xae, 0x79, 0x07, + 0x5d, 0x05, 0x2a, 0xee, 0x72, 0x88, 0x2b, 0x98, + 0x6b, 0xde, 0x6c, 0x0e, 0x6b, 0xce, 0x2b, 0xae, + 0x9e, 0x88, 0x2b, 0x98, 0x6b, 0xde, 0x6c, 0x0e, + 0x6b, 0xce, 0x7d, 0x0f, 0x28, 0xee, 0xdb, 0x83, + 0x6f, 0x08, 0x24, 0x93, 0xfd, 0x09, 0x61, 0xdf, + 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, 0x29, 0x15, + 0x7e, 0x0f, 0x51, 0xc1, 0x2b, 0xef, 0x49, 0x0e, + 0x6c, 0x08, 0x4b, 0xde, 0x4d, 0x6e, 0x3e, 0xae, + 0x7b, 0xdf, 0x79, 0x2f, 0x2e, 0xee, 0x4c, 0x08, + 0x29, 0xae, 0x49, 0x0e, 0x4b, 0xde, 0x4d, 0x6e, + 0x71, 0xdc, 0x78, 0xdf, 0x79, 0x2f, 0x6c, 0x08, + 0x2f, 0xee, 0x28, 0xae, 0x61, 0xdc, 0x69, 0x0e, + 0x69, 0xde, 0x6d, 0x6e, 0x51, 0xdf, 0x6b, 0x26, + 0xec, 0x0e, 0x2c, 0x11, 0x79, 0x12, 0x65, 0x0e, + 0x65, 0x0e, 0x69, 0x0f, 0x3d, 0xe7, 0xcd, 0x8a, + 0x22, 0x88, 0xd2, 0x9a, 0x2d, 0x98, 0x68, 0x2e, + 0x49, 0x2f, 0x24, 0xe6, 0xfd, 0x8a, 0x27, 0x88, + 0xd2, 0x9a, 0x68, 0x2e, 0x49, 0x2f, 0x62, 0x08, + 0x2f, 0xe6, 0x29, 0xae, 0xad, 0x8a, 0xd5, 0x9a, + 0x68, 0x2e, 0x2c, 0x11, 0x38, 0x17, 0x51, 0xc1, + 0x71, 0xc1, 0x20, 0x8b, 0x2d, 0x9b, 0x79, 0x2e, + 0x68, 0xde, 0x6d, 0x8b, 0x59, 0x12, 0x59, 0x0d, + 0x2d, 0x9b, 0x58, 0x26, 0x66, 0x05, 0x2f, 0xee, + 0x5a, 0x07, 0x5d, 0x0f, 0x22, 0xee, 0xef, 0x83, + 0x6e, 0x08, 0x2e, 0x93, 0xfd, 0x09, 0x35, 0x8a, + 0xff, 0x83, 0xd5, 0x9a, 0x2e, 0x93, 0x59, 0xcf, + 0x79, 0xde, 0x58, 0x27, 0x59, 0xce, 0x6e, 0x08, + 0xfd, 0x09, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x3b, 0x17, 0x51, 0xc1, + 0xa1, 0xc5, 0xb9, 0x12, 0x81, 0xc5, 0xd2, 0x85, + 0xc1, 0xc5, 0x88, 0x12, 0x41, 0xc0, 0x11, 0x88, + 0x2d, 0x95, 0x2d, 0x98, 0x48, 0x2e, 0x6b, 0xde, + 0x6d, 0x0f, 0x2f, 0xef, 0x40, 0xae, 0x4c, 0x0e, + 0x6b, 0xde, 0x6f, 0x0f, 0x2f, 0xe6, 0x45, 0xae, + 0x4c, 0x0e, 0x5b, 0xde, 0xaa, 0x12, 0xa9, 0x2e, + 0x55, 0x2f, 0x13, 0xe6, 0x5f, 0x0e, 0x55, 0x2f, + 0x16, 0xe6, 0xca, 0xd8, 0x66, 0x12, 0x63, 0x26, + 0xfc, 0xb1, 0x7a, 0xd9, 0x62, 0x0f, 0x2e, 0xee, + 0x7d, 0x0f, 0x28, 0xef, 0x7c, 0x0e, 0x7c, 0x0d, + 0x58, 0x2e, 0x06, 0xae, 0xc2, 0x0d, 0x3f, 0xef, + 0x72, 0x0e, 0xfd, 0x08, 0x78, 0x14, 0x7a, 0xde, + 0x40, 0x12, 0x4d, 0x6e, 0x2e, 0xee, 0x75, 0x0d, + 0x2f, 0xae, 0x76, 0x26, 0x5b, 0x2e, 0x79, 0xce, + 0xfc, 0x0e, 0xdb, 0xe0, 0xfd, 0x6e, 0x50, 0x2e, + 0x35, 0xae, 0xcc, 0x0f, 0x3b, 0xef, 0x72, 0x0e, + 0xdd, 0x08, 0x78, 0x14, 0x76, 0x12, 0xc2, 0x12, + 0xcd, 0x6e, 0x2a, 0xee, 0xf9, 0xde, 0x4a, 0xde, + 0xf5, 0x0c, 0x48, 0x26, 0x40, 0x27, 0x2e, 0xae, + 0x49, 0xde, 0x46, 0x26, 0xdc, 0x0e, 0x4a, 0xce, + 0x53, 0x2e, 0xdf, 0xe0, 0xdd, 0x6e, 0x52, 0x2e, + 0x55, 0x2f, 0x2f, 0xe6, 0xe9, 0xa1, 0x6e, 0x86, + 0x2d, 0x96, 0xa7, 0x2e, 0x65, 0xde, 0xa4, 0x0e, + 0x6d, 0x0f, 0x2f, 0xef, 0x39, 0xae, 0x74, 0x12, + 0xb9, 0x83, 0x78, 0x0e, 0xba, 0x0e, 0x64, 0xde, + 0x02, 0x93, 0xb4, 0x0e, 0xb4, 0xba, 0x65, 0x12, + 0xb1, 0xcf, 0x54, 0xdc, 0x6a, 0x0e, 0x69, 0xde, + 0x4d, 0x08, 0x75, 0x12, 0x5d, 0x09, 0x43, 0x83, + 0x02, 0x93, 0xfd, 0x09, 0x2f, 0x83, 0x65, 0x12, + 0x1f, 0x93, 0x4e, 0x08, 0x7d, 0x08, 0xfd, 0x09, + 0xaa, 0x0e, 0x6d, 0x08, 0x65, 0xce, 0x7f, 0x08, + 0x71, 0x2e, 0x68, 0xd7, 0xc8, 0xd6, 0x88, 0xd6, + 0xa8, 0xd6, 0x58, 0xde, 0xe8, 0x12, 0x29, 0x15, + 0x38, 0x17, 0x51, 0xc1, 0x12, 0x89, 0xb1, 0xc1, + 0x2d, 0x99, 0x71, 0xc1, 0x59, 0x2e, 0x4e, 0x08, + 0x79, 0x12, 0x6a, 0xde, 0x49, 0x26, 0x2f, 0xef, + 0x0e, 0xae, 0x7c, 0x88, 0x6d, 0x05, 0xd5, 0x98, + 0x4b, 0xde, 0x25, 0xee, 0x5c, 0x0e, 0xb5, 0x08, + 0xbb, 0x26, 0x4a, 0xde, 0x5a, 0x08, 0x4a, 0x26, + 0x44, 0x27, 0x6c, 0x05, 0x27, 0xee, 0x49, 0x06, + 0x6d, 0x8a, 0x2d, 0x9a, 0x3d, 0x89, 0x68, 0x2e, + 0x2d, 0x99, 0x69, 0xde, 0x6a, 0x26, 0x49, 0x27, + 0x12, 0x8a, 0x2f, 0x83, 0x2d, 0x9a, 0x1f, 0x93, + 0x68, 0x2e, 0x7c, 0x8b, 0xd5, 0x9b, 0x48, 0xce, + 0x4f, 0x08, 0x7d, 0x08, 0x87, 0xbb, 0x61, 0xdf, + 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, 0x29, 0x15, + 0x09, 0x83, 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, + 0x1e, 0x89, 0xa1, 0xc5, 0xbb, 0x12, 0x81, 0xc5, + 0x22, 0x84, 0x21, 0xc0, 0x3f, 0x88, 0x2d, 0x93, + 0x20, 0x12, 0x99, 0x12, 0x28, 0x2e, 0x2d, 0x99, + 0x2d, 0xde, 0x2d, 0x94, 0x2d, 0x0f, 0x2d, 0x98, + 0xa8, 0x12, 0x36, 0xef, 0x13, 0x8e, 0x3a, 0x12, + 0x34, 0x2e, 0x2d, 0x9e, 0x6c, 0xde, 0x62, 0x0e, + 0x29, 0x2f, 0x29, 0xe6, 0x2d, 0x8e, 0x2c, 0xce, + 0x8c, 0xae, 0x3f, 0x8e, 0x35, 0x8a, 0x9d, 0x4a, + 0x2d, 0x9a, 0x29, 0x2e, 0x3d, 0xde, 0x3a, 0x0e, + 0x2c, 0xde, 0x25, 0x07, 0x2c, 0xce, 0x30, 0x12, + 0x2c, 0x08, 0x38, 0x2e, 0x2c, 0xce, 0x25, 0xae, + 0x2c, 0x0f, 0x2b, 0xee, 0x2f, 0x0f, 0x34, 0xee, + 0x2e, 0x0f, 0x16, 0xee, 0xa6, 0xae, 0x9b, 0x4a, + 0x27, 0x2e, 0x2a, 0x0e, 0x6d, 0xde, 0x6a, 0x0e, + 0x24, 0x0e, 0x69, 0xde, 0x6a, 0x05, 0x2f, 0xef, + 0xac, 0xae, 0x28, 0x0e, 0x3d, 0xdd, 0x2a, 0x12, + 0x24, 0x2e, 0x2d, 0xde, 0x2c, 0xce, 0x30, 0x12, + 0x2f, 0x08, 0x35, 0x2e, 0x2c, 0xce, 0x2c, 0xae, + 0x9b, 0x4a, 0x27, 0x2e, 0x2a, 0x0e, 0x6d, 0xde, + 0x6a, 0x0e, 0x24, 0x0e, 0x69, 0xde, 0x6b, 0x05, + 0x2f, 0xef, 0x41, 0xae, 0x2b, 0x0e, 0x18, 0x8a, + 0x7d, 0xdd, 0x2d, 0x9a, 0x22, 0x0e, 0x64, 0x2e, + 0x39, 0xd7, 0xf5, 0x2e, 0x38, 0xc7, 0x39, 0xd7, + 0x38, 0xc7, 0x39, 0xd7, 0x38, 0xc7, 0x39, 0xd7, + 0x38, 0xc7, 0x39, 0xd7, 0x38, 0xc7, 0x39, 0xde, + 0x64, 0x0e, 0x38, 0xce, 0x3d, 0xdd, 0x29, 0xde, + 0x2c, 0xce, 0x2e, 0x08, 0x20, 0xce, 0x2c, 0xae, + 0x9b, 0x4a, 0x3b, 0x8a, 0x2d, 0x9a, 0x29, 0x2e, + 0x6d, 0xde, 0x29, 0x12, 0x2a, 0x0e, 0x2d, 0xde, + 0x2a, 0x05, 0x65, 0xee, 0x6b, 0x0e, 0x16, 0x8f, + 0x29, 0xde, 0x2d, 0x9f, 0x34, 0x2e, 0x8a, 0x12, + 0x84, 0x2e, 0x2c, 0xce, 0x29, 0xdf, 0x35, 0x0e, + 0x2c, 0xce, 0x6f, 0x8e, 0x2d, 0x9e, 0x24, 0x2e, + 0x2d, 0xde, 0x2d, 0x0f, 0x2f, 0xef, 0x38, 0xae, + 0x75, 0x12, 0xb9, 0x83, 0x78, 0x0e, 0xaa, 0x0e, + 0x65, 0xde, 0x02, 0x93, 0xa4, 0x0e, 0x6f, 0x8e, + 0x2d, 0x9e, 0xfd, 0x09, 0x24, 0x2e, 0xa1, 0xcf, + 0x6d, 0xde, 0x4d, 0x08, 0x55, 0xdc, 0x77, 0x12, + 0x5d, 0x09, 0x43, 0x83, 0x02, 0x93, 0xfd, 0x09, + 0x3f, 0x8e, 0x22, 0x8b, 0x2d, 0x9e, 0x2d, 0x9b, + 0x9d, 0x4a, 0x2f, 0x83, 0x67, 0x12, 0x28, 0x2e, + 0x1f, 0x93, 0x28, 0x0e, 0x7d, 0x08, 0x4d, 0xdd, + 0x2c, 0x0e, 0x7b, 0xce, 0x09, 0x88, 0x2d, 0x98, + 0x45, 0x2e, 0x7b, 0xce, 0x24, 0x88, 0x2d, 0x98, + 0x60, 0xbb, 0x3d, 0xdd, 0x6f, 0x8a, 0x2d, 0x9a, + 0x3a, 0x0e, 0x64, 0x2e, 0x2d, 0x08, 0x29, 0xce, + 0x2c, 0xde, 0xd2, 0x8a, 0x2d, 0x9a, 0x29, 0x26, + 0x2c, 0xce, 0x6f, 0x08, 0x61, 0x2e, 0x29, 0xd7, + 0x89, 0xd6, 0x3d, 0x15, 0xa9, 0xd6, 0x59, 0xd7, + 0x29, 0xd6, 0x62, 0x0e, 0xe9, 0x12, 0x2c, 0x11, + 0x0e, 0x83, 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, + 0x3f, 0x89, 0xa1, 0xc5, 0x2d, 0x93, 0x21, 0xc0, + 0x20, 0x12, 0xa8, 0x12, 0x28, 0x2e, 0x2d, 0x99, + 0x2d, 0xde, 0xbb, 0x12, 0x2d, 0x0f, 0x3f, 0xef, + 0x07, 0x8e, 0x53, 0x8f, 0x2d, 0x9e, 0x2d, 0x9f, + 0x2b, 0x2e, 0x7d, 0xde, 0x72, 0x0e, 0x38, 0x2f, + 0x29, 0xe6, 0x2d, 0x8f, 0x3d, 0xce, 0x5c, 0xae, + 0x20, 0x12, 0x2c, 0x8f, 0x25, 0x2e, 0x3d, 0xce, + 0x2b, 0xae, 0x2c, 0x0f, 0x29, 0xee, 0x2f, 0x0f, + 0x0e, 0xee, 0x4a, 0xae, 0x6a, 0x4a, 0x22, 0x8b, + 0x2d, 0x9b, 0x28, 0x2e, 0x7d, 0xde, 0x78, 0xdf, + 0x7a, 0x05, 0x2f, 0xef, 0x73, 0xae, 0x4d, 0xdc, + 0x06, 0x8b, 0x2d, 0x9b, 0xf5, 0x2e, 0x74, 0x2e, + 0x38, 0xd7, 0x3b, 0xc7, 0x38, 0xd7, 0x3b, 0xc7, + 0x38, 0xd7, 0x3b, 0xc7, 0x38, 0xd7, 0x3b, 0xc7, + 0x38, 0xd7, 0x3b, 0xc7, 0x38, 0xde, 0x77, 0x0e, + 0x3b, 0xce, 0x3d, 0xde, 0x28, 0xde, 0x2c, 0xcf, + 0x2f, 0x08, 0x20, 0xce, 0x2c, 0xae, 0x6a, 0x4a, + 0x22, 0x8a, 0x2d, 0x9a, 0x29, 0x2e, 0x6d, 0xde, + 0x69, 0xdf, 0x6a, 0x05, 0x13, 0xee, 0x6d, 0xdf, + 0x1c, 0x8f, 0x6b, 0x0e, 0x2d, 0x9f, 0x79, 0xde, + 0x34, 0x2e, 0x6c, 0x0e, 0x7c, 0xc7, 0x69, 0xde, + 0x6c, 0xce, 0x2d, 0xde, 0x35, 0x0e, 0x2d, 0xdf, + 0x2c, 0xce, 0x6c, 0x8e, 0x2d, 0x9e, 0x24, 0x2e, + 0x2d, 0xde, 0x2d, 0x0f, 0x07, 0x8e, 0x2d, 0x9e, + 0x2e, 0xef, 0x24, 0x2e, 0x3b, 0xae, 0x75, 0x12, + 0xb9, 0x83, 0x78, 0x0e, 0xaa, 0x0e, 0x65, 0xde, + 0x02, 0x93, 0xa4, 0x0e, 0x6c, 0x8f, 0x2d, 0x9f, + 0x24, 0x2e, 0xfd, 0x09, 0x34, 0x2e, 0xa1, 0xcf, + 0x6c, 0xde, 0x4d, 0x08, 0x55, 0xdc, 0x7d, 0x12, + 0x5d, 0x09, 0x43, 0x83, 0x02, 0x93, 0xfd, 0x09, + 0x0e, 0x8a, 0x3d, 0x08, 0x2d, 0x9a, 0x2f, 0x83, + 0x65, 0x2e, 0x1f, 0x93, 0x24, 0x88, 0x39, 0xce, + 0x6d, 0x12, 0x2d, 0x98, 0x6c, 0x8f, 0x7d, 0x08, + 0x2d, 0x08, 0xfd, 0x09, 0x34, 0x2e, 0x2c, 0xce, + 0x6f, 0x08, 0x61, 0x2e, 0x29, 0xd7, 0xa9, 0xd6, + 0x3d, 0x15, 0x59, 0xd7, 0x29, 0xd6, 0xea, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x38, 0x17, 0x51, 0xc1, + 0xb1, 0xc1, 0xb9, 0x12, 0x71, 0xc1, 0x6b, 0x0e, + 0x79, 0xde, 0x78, 0x0e, 0x68, 0xdd, 0x76, 0x0e, + 0x6d, 0x0f, 0x30, 0xee, 0xb8, 0x0e, 0x44, 0xde, + 0xb6, 0x0e, 0x4d, 0x0f, 0x35, 0xee, 0x5b, 0x12, + 0x5c, 0x0d, 0x38, 0xee, 0x4c, 0x0e, 0x7b, 0x0e, + 0x68, 0xdd, 0x49, 0x2e, 0x77, 0x0e, 0x4c, 0x0b, + 0x4a, 0x28, 0x4d, 0x0f, 0x21, 0xee, 0x68, 0xde, + 0xc7, 0x83, 0x79, 0x12, 0x1c, 0x93, 0x7a, 0x2e, + 0x5c, 0x0c, 0xfd, 0x09, 0xb8, 0x0e, 0x64, 0xde, + 0x6a, 0x28, 0x64, 0xce, 0x61, 0xdf, 0xb1, 0xdc, + 0x51, 0xdd, 0xee, 0x0e, 0x29, 0x15, 0x2d, 0x61, + 0x51, 0xc1, 0x3a, 0x17, 0x51, 0xc1, 0x5b, 0x12, + 0x5c, 0x0b, 0x5d, 0x0f, 0x22, 0xee, 0x48, 0x12, + 0x4c, 0x0e, 0x4c, 0x0b, 0x4a, 0x28, 0x4d, 0x0f, + 0x24, 0xee, 0x6b, 0x0e, 0xc7, 0x83, 0x69, 0xde, + 0x1c, 0x93, 0x69, 0xde, 0x79, 0x12, 0x7a, 0x2e, + 0xe4, 0xba, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0xc7, 0x83, 0x21, 0xc5, + 0x3d, 0x17, 0x01, 0xc5, 0x22, 0x8c, 0x51, 0xc1, + 0x2d, 0x9c, 0xa1, 0xc5, 0xb8, 0x12, 0x21, 0xc1, + 0x3f, 0x8e, 0x27, 0x89, 0x2d, 0x99, 0x2d, 0x9e, + 0x6d, 0x4a, 0x1c, 0x93, 0x27, 0x88, 0x2f, 0x2e, + 0xc0, 0x8a, 0x2a, 0x0e, 0x2b, 0x9a, 0x3d, 0xdd, + 0x2d, 0x98, 0x3a, 0x42, 0x24, 0x0e, 0x6f, 0x2e, + 0x3c, 0x0e, 0x3a, 0x42, 0x95, 0xba, 0x74, 0x12, + 0xc0, 0x8a, 0x7a, 0x0e, 0x2b, 0x9a, 0x6f, 0x2e, + 0x7e, 0x0e, 0xc7, 0x83, 0x27, 0x88, 0x1c, 0x93, + 0x2d, 0x98, 0x21, 0x8c, 0x9f, 0xba, 0x2d, 0x9c, + 0x39, 0x8b, 0x0d, 0x2e, 0x2d, 0x9b, 0x2f, 0xde, + 0x74, 0x2e, 0x2a, 0x42, 0xc0, 0x8a, 0xc7, 0x83, + 0x2c, 0x0e, 0x2b, 0x9a, 0x2a, 0x4a, 0x6f, 0x2e, + 0x1c, 0x93, 0x27, 0x88, 0x2d, 0x98, 0xfd, 0x09, + 0x33, 0x8b, 0xc0, 0x8a, 0x2d, 0x9b, 0x2b, 0x9a, + 0x74, 0x2e, 0x6d, 0x2e, 0xc7, 0x83, 0x27, 0x88, + 0x1c, 0x93, 0x2d, 0x98, 0x89, 0xba, 0x6c, 0x08, + 0x61, 0x2e, 0x29, 0xd7, 0xa9, 0xd6, 0x3d, 0x15, + 0x59, 0xd7, 0x09, 0xd6, 0x29, 0xd6, 0x62, 0x0e, + 0xe9, 0x12, 0x2c, 0x11, 0xc7, 0x83, 0x21, 0xc5, + 0x3d, 0x17, 0x01, 0xc5, 0x22, 0x8c, 0x51, 0xc1, + 0x2d, 0x9c, 0xa1, 0xc5, 0xb8, 0x12, 0x21, 0xc1, + 0x3f, 0x8e, 0x27, 0x89, 0x2d, 0x99, 0x2d, 0x9e, + 0x6d, 0x4a, 0xc0, 0x8b, 0x1c, 0x93, 0x2f, 0x2e, + 0x2b, 0x9b, 0x2a, 0x0e, 0x27, 0x88, 0x3d, 0xdd, + 0x2d, 0x98, 0x3a, 0x42, 0x24, 0x0e, 0x64, 0x12, + 0x7f, 0x2e, 0x3c, 0x0e, 0x3a, 0x42, 0xfd, 0x09, + 0x64, 0x12, 0xc0, 0x8b, 0x6a, 0x0e, 0x2b, 0x9b, + 0x7f, 0x2e, 0x6e, 0x0e, 0xc7, 0x83, 0x27, 0x88, + 0x1c, 0x93, 0x2d, 0x98, 0x21, 0x8c, 0xfd, 0x09, + 0x2d, 0x9c, 0x39, 0x8a, 0x0d, 0x2e, 0x2d, 0x9a, + 0x2f, 0xde, 0x64, 0x2e, 0x2a, 0x42, 0xc0, 0x8b, + 0xc7, 0x83, 0x2c, 0x0e, 0x2b, 0x9b, 0x2a, 0x4a, + 0x7f, 0x2e, 0x1c, 0x93, 0x27, 0x88, 0x2d, 0x98, + 0xac, 0xba, 0x33, 0x8a, 0xc0, 0x8b, 0x2d, 0x9a, + 0x2b, 0x9b, 0x64, 0x2e, 0x7d, 0x2e, 0xc7, 0x83, + 0x27, 0x88, 0x1c, 0x93, 0x2d, 0x98, 0xfd, 0x09, + 0x6c, 0x08, 0x61, 0x2e, 0x29, 0xd7, 0xa9, 0xd6, + 0x3d, 0x15, 0x59, 0xd7, 0x09, 0xd6, 0x29, 0xd6, + 0x62, 0x0e, 0xe9, 0x12, 0x2c, 0x11, 0x2d, 0x61, + 0x3a, 0x83, 0x21, 0xc5, 0x3d, 0x17, 0x01, 0xc5, + 0x2d, 0x93, 0x51, 0xc1, 0xa1, 0xc5, 0xa9, 0x12, + 0x81, 0xc5, 0xc1, 0xc5, 0x21, 0xc1, 0xe0, 0x28, + 0x69, 0x8e, 0x2d, 0x9e, 0x81, 0x12, 0x6d, 0x42, + 0x38, 0x83, 0x51, 0x12, 0xbf, 0x12, 0x3f, 0x8e, + 0x6d, 0x4a, 0xfa, 0x8c, 0x28, 0x9c, 0xbf, 0x2e, + 0x01, 0x12, 0x74, 0x12, 0x0f, 0x0e, 0x01, 0xc2, + 0x22, 0x8c, 0x2d, 0x9c, 0x2f, 0x2e, 0xfd, 0x12, + 0x00, 0x12, 0x0b, 0x8e, 0x2d, 0x9e, 0x3c, 0x83, + 0x6d, 0x4a, 0x2d, 0x93, 0xff, 0x2e, 0x31, 0x12, + 0x10, 0xde, 0x3a, 0x83, 0x2d, 0x93, 0x11, 0xc2, + 0x3d, 0x83, 0xff, 0x2e, 0x10, 0xde, 0x3b, 0x83, + 0x2d, 0x93, 0x11, 0xc2, 0x93, 0xb1, 0x41, 0x12, + 0x21, 0x83, 0x2d, 0x93, 0x71, 0x12, 0xff, 0x2e, + 0x79, 0x0e, 0x60, 0xde, 0x0a, 0x0e, 0x0f, 0xdd, + 0xc9, 0x12, 0xce, 0x0c, 0x1f, 0x12, 0x1e, 0x0c, + 0x3f, 0x83, 0x2d, 0x93, 0xc9, 0x28, 0x4e, 0x8a, + 0x71, 0xc2, 0x38, 0x83, 0x2b, 0x9a, 0x71, 0x12, + 0x1f, 0x28, 0x01, 0xd2, 0x29, 0x2e, 0x3f, 0x83, + 0x0f, 0x25, 0x98, 0x8a, 0x7e, 0x0e, 0x2b, 0x9a, + 0x4a, 0x0e, 0x19, 0x2e, 0xc9, 0x2e, 0x61, 0xd2, + 0x48, 0x0e, 0x09, 0x2e, 0x39, 0x83, 0x3d, 0x8a, + 0x7f, 0x14, 0x2d, 0x9a, 0x3a, 0x0e, 0x61, 0x2e, + 0x5b, 0x0e, 0x8a, 0x0e, 0x61, 0xc2, 0x38, 0x83, + 0x8c, 0x0e, 0x01, 0xd2, 0x7a, 0x0e, 0x3a, 0x0e, + 0x09, 0xcd, 0x09, 0xdc, 0x3e, 0x83, 0x1b, 0x0e, + 0x9e, 0xde, 0x9b, 0x0e, 0x17, 0x0e, 0xd6, 0xdd, + 0x97, 0x0e, 0xd8, 0xc7, 0x9a, 0xc7, 0x91, 0xd2, + 0x16, 0xc7, 0x1a, 0x0e, 0x91, 0xc2, 0xcf, 0xc7, + 0xcb, 0x0e, 0xd3, 0xd7, 0xdb, 0x0e, 0x92, 0xdd, + 0xd7, 0x0e, 0x9c, 0xc7, 0xd7, 0xc7, 0x9b, 0xc7, + 0x9d, 0x08, 0x99, 0xc7, 0xc4, 0xe0, 0x33, 0x83, + 0x05, 0x8d, 0xfd, 0x2e, 0x3a, 0x80, 0x30, 0xde, + 0x2a, 0x0e, 0x69, 0x81, 0x2d, 0x9d, 0xfe, 0x12, + 0x2d, 0x90, 0xf4, 0x2e, 0x27, 0x91, 0x30, 0xce, + 0x7d, 0xdd, 0xf3, 0x12, 0x81, 0xdc, 0x24, 0x0e, + 0x91, 0xdd, 0x47, 0x12, 0x91, 0xcf, 0x61, 0xd2, + 0x2b, 0xb0, 0x6d, 0x0f, 0x27, 0xee, 0x3d, 0x0f, + 0x25, 0xef, 0x33, 0x8c, 0x3c, 0x08, 0x2d, 0x9c, + 0x14, 0x2e, 0x0d, 0x2e, 0x3f, 0xce, 0x3e, 0xce, + 0x0c, 0x8f, 0x2d, 0x9f, 0x3d, 0x2e, 0x3c, 0xde, + 0x3d, 0x0f, 0x3d, 0x08, 0x2f, 0xef, 0x2c, 0x8f, + 0x22, 0x8c, 0x2d, 0x9c, 0x0d, 0x2e, 0x0f, 0xde, + 0x0d, 0x0f, 0x26, 0xef, 0x21, 0x83, 0x2d, 0x93, + 0x01, 0xd2, 0x0d, 0x0f, 0x28, 0xea, 0x20, 0x83, + 0x01, 0xd2, 0x0d, 0x0f, 0x2f, 0xeb, 0x2d, 0x8f, + 0x0e, 0x8c, 0x2d, 0x9c, 0x0d, 0x2e, 0x1f, 0xde, + 0x1d, 0x0f, 0x27, 0xef, 0x0c, 0x0e, 0x0f, 0xde, + 0x0d, 0x0f, 0x2b, 0xef, 0x3d, 0x0f, 0x0d, 0x08, + 0x3d, 0x08, 0x3d, 0xef, 0x2e, 0xae, 0x3c, 0x08, + 0x0c, 0x08, 0x25, 0x83, 0x2d, 0x93, 0x91, 0xd2, + 0x24, 0x83, 0x9b, 0x0e, 0x51, 0xd2, 0x16, 0xdd, + 0x5b, 0x0e, 0x8a, 0xdd, 0x97, 0x0e, 0x57, 0x0e, + 0xa5, 0xae, 0xf9, 0x08, 0x61, 0xd2, 0x2d, 0x61, + 0x32, 0xb1, 0xf8, 0x08, 0x61, 0xd2, 0x2d, 0x61, + 0x30, 0xb1, 0x7d, 0x12, 0xb9, 0x83, 0x2a, 0x0e, + 0x78, 0x0e, 0x6d, 0xde, 0x02, 0x93, 0x24, 0x0e, + 0xf5, 0xbc, 0x1d, 0xde, 0x4d, 0x08, 0x1a, 0x0e, + 0x74, 0x12, 0x6e, 0xde, 0x21, 0xcf, 0x5d, 0xdc, + 0x5d, 0x09, 0x43, 0x83, 0x19, 0x12, 0x02, 0x93, + 0x92, 0xbc, 0x04, 0x8a, 0x0c, 0x8b, 0x2d, 0x9a, + 0x2d, 0x9b, 0x64, 0x2e, 0x7d, 0x2e, 0x69, 0xde, + 0x1d, 0x0f, 0x68, 0xce, 0x3b, 0xee, 0x3f, 0x8e, + 0x3e, 0x8b, 0x2d, 0x9e, 0x2d, 0x9b, 0xad, 0x4a, + 0xf3, 0x12, 0x61, 0xd2, 0x28, 0x2e, 0x2d, 0xde, + 0x7d, 0x08, 0x1d, 0xce, 0xdd, 0x09, 0x3b, 0x83, + 0xad, 0x8b, 0x2d, 0x93, 0x2d, 0x9b, 0x61, 0xd2, + 0x87, 0x83, 0x24, 0x93, 0xfd, 0x09, 0x60, 0xaf, + 0x65, 0x12, 0x74, 0x12, 0x0b, 0xb1, 0x27, 0x83, + 0x2d, 0x93, 0x71, 0xd2, 0x2a, 0x83, 0x48, 0x12, + 0x11, 0xd2, 0x1b, 0x0e, 0x2b, 0x83, 0x6e, 0xdd, + 0x11, 0xd2, 0x1b, 0x0e, 0x26, 0x83, 0x1e, 0xdd, + 0x51, 0xd2, 0x4e, 0x28, 0x3d, 0x83, 0x1a, 0x12, + 0x19, 0x28, 0x41, 0xc2, 0x3c, 0x83, 0x67, 0x12, + 0x11, 0xc2, 0x2d, 0x61, 0x20, 0xb1, 0x4e, 0x12, + 0x66, 0x12, 0x26, 0x8d, 0x7a, 0x12, 0x2d, 0x9d, + 0x27, 0xb1, 0x1d, 0x2e, 0x25, 0x83, 0x1e, 0xde, + 0x2d, 0x93, 0x71, 0xd2, 0x1e, 0x0f, 0x24, 0x83, + 0x61, 0xd2, 0x2f, 0xee, 0x24, 0xae, 0x7b, 0x0e, + 0x08, 0xcd, 0x61, 0xd2, 0x77, 0x0e, 0x6b, 0x0e, + 0x09, 0xcd, 0x67, 0x0e, 0x2c, 0x8c, 0x2a, 0x0e, + 0x98, 0x12, 0x1d, 0xdd, 0x7b, 0x0e, 0x24, 0x0e, + 0x59, 0x12, 0x1e, 0x0f, 0x18, 0xdd, 0x29, 0xee, + 0x6b, 0x0e, 0x89, 0xdd, 0x23, 0xae, 0x6b, 0x0e, + 0x89, 0xdd, 0x1d, 0x0f, 0x2f, 0xee, 0x24, 0xae, + 0x19, 0xdd, 0x1d, 0x0f, 0x29, 0xee, 0x8e, 0x12, + 0x1d, 0x08, 0x2e, 0xae, 0x2c, 0x8c, 0x8d, 0x08, + 0x23, 0x83, 0x44, 0x12, 0x7d, 0x12, 0x11, 0xc2, + 0x22, 0x83, 0x65, 0x12, 0x81, 0xc2, 0x2d, 0x61, + 0x05, 0xb0, 0x44, 0x12, 0x7d, 0x12, 0x65, 0x12, + 0xa1, 0xb0, 0x74, 0x12, 0x6d, 0x12, 0x2d, 0x61, + 0xea, 0xb3, 0x6d, 0x12, 0x99, 0xb3, 0x64, 0x12, + 0x3a, 0x87, 0x2d, 0x61, 0x2a, 0xb0, 0x0e, 0x83, + 0x23, 0x88, 0x2d, 0x93, 0x13, 0x8b, 0xfd, 0x2e, + 0x2d, 0x97, 0x60, 0xde, 0x2d, 0x98, 0x6d, 0x0f, + 0x2a, 0x9b, 0x3a, 0xef, 0xfc, 0x0e, 0x60, 0xde, + 0x6d, 0x0f, 0x3e, 0xef, 0x69, 0x84, 0x3d, 0x0f, + 0x27, 0x94, 0x1d, 0xee, 0xac, 0x0c, 0xfb, 0x12, + 0xa8, 0x2e, 0x9b, 0x0e, 0x05, 0xd7, 0x5b, 0x0e, + 0x35, 0xde, 0x01, 0xc2, 0x22, 0x83, 0x31, 0xc2, + 0x06, 0xcd, 0x0d, 0x08, 0x3a, 0xcd, 0x0f, 0xae, + 0x3d, 0x0f, 0x3f, 0xef, 0x2d, 0x8f, 0xac, 0x0c, + 0x38, 0x83, 0x20, 0x8c, 0xa8, 0x2e, 0x2d, 0x93, + 0x61, 0xd2, 0x9b, 0x0e, 0x09, 0x2e, 0x5b, 0x0e, + 0x3f, 0xc1, 0x3f, 0xce, 0x0c, 0x08, 0x15, 0xc7, + 0x85, 0xce, 0x36, 0xcd, 0x3a, 0xcd, 0x22, 0x8f, + 0x3d, 0x2e, 0x3c, 0xde, 0x20, 0x08, 0x32, 0x0e, + 0x2c, 0x2f, 0x2f, 0xe6, 0x83, 0xae, 0xf3, 0x12, + 0x7d, 0x08, 0x61, 0xd2, 0x2d, 0x8c, 0xdd, 0x09, + 0x85, 0xae, 0x22, 0x8f, 0x38, 0x85, 0x2d, 0x9f, + 0x87, 0x86, 0x3d, 0x2e, 0x2d, 0x95, 0x3c, 0xde, + 0x24, 0x96, 0x3d, 0x0f, 0x6e, 0xef, 0xfb, 0x12, + 0x5d, 0x08, 0x11, 0xd2, 0x22, 0x83, 0x31, 0xd2, + 0x3d, 0x0f, 0x2f, 0xef, 0x2c, 0x89, 0x39, 0x83, + 0x31, 0x12, 0x61, 0xd2, 0x3f, 0x83, 0x39, 0x28, + 0xd1, 0xd2, 0x3c, 0x8a, 0x38, 0x83, 0x2d, 0x9a, + 0xc1, 0xd2, 0x39, 0x2e, 0x39, 0x83, 0x2d, 0x93, + 0x61, 0xd2, 0x69, 0xde, 0x6d, 0x0f, 0x28, 0xea, + 0x1d, 0x0f, 0x4a, 0x12, 0x2f, 0xef, 0x2f, 0xae, + 0x4d, 0x08, 0x61, 0xd2, 0x6c, 0x0e, 0x61, 0xc2, + 0x63, 0xd7, 0x69, 0x0e, 0x79, 0xde, 0x61, 0x0e, + 0x7d, 0x0f, 0x20, 0xef, 0x3a, 0x83, 0x79, 0x12, + 0x61, 0xd2, 0x8d, 0x83, 0x1f, 0x93, 0xfd, 0x09, + 0x62, 0x0f, 0x28, 0xee, 0x79, 0x12, 0xf4, 0x12, + 0x61, 0xd2, 0x8d, 0x09, 0x72, 0xd7, 0xf4, 0x12, + 0x61, 0xd2, 0xf7, 0x83, 0x1f, 0x93, 0xfd, 0x09, + 0x62, 0x0f, 0x28, 0xee, 0x79, 0x12, 0xf4, 0x12, + 0x61, 0xd2, 0x8d, 0x09, 0x32, 0x0e, 0xfe, 0xec, + 0x2b, 0xae, 0xf3, 0x12, 0x7d, 0x08, 0x61, 0xd2, + 0x2d, 0x8c, 0xdd, 0x09, 0x0c, 0x8f, 0x3b, 0x8d, + 0x2d, 0x9f, 0x3f, 0x89, 0x3d, 0x2e, 0x2d, 0x9d, + 0x6c, 0xde, 0x37, 0x8e, 0xc3, 0x8f, 0x6c, 0x0f, + 0x1e, 0x9e, 0x2d, 0x99, 0x1f, 0x9f, 0x30, 0xef, + 0xf9, 0x08, 0x2c, 0x87, 0x61, 0xd2, 0x69, 0x0e, + 0x28, 0x83, 0xb9, 0xce, 0x61, 0xd2, 0x69, 0x0e, + 0x23, 0x83, 0xb9, 0xce, 0x61, 0xd2, 0x6d, 0x0f, + 0x31, 0xef, 0x22, 0x83, 0x61, 0xd2, 0x6d, 0x0f, + 0x35, 0xef, 0x3a, 0x83, 0x7d, 0x08, 0x61, 0xd2, + 0x2d, 0x8c, 0x8d, 0x09, 0x0d, 0x8b, 0xfe, 0x12, + 0x61, 0xd2, 0x2d, 0x9b, 0xad, 0x09, 0x20, 0xae, + 0x6f, 0x0f, 0x26, 0xef, 0xf4, 0x12, 0x7d, 0x08, + 0x61, 0xd2, 0x2d, 0x8c, 0x8d, 0x09, 0x6d, 0x8b, + 0xfe, 0x12, 0x61, 0xd2, 0x2d, 0x9b, 0xad, 0x09, + 0xf6, 0x12, 0x11, 0xd2, 0xbe, 0x25, 0x3e, 0x83, + 0x11, 0xd2, 0xbe, 0x2e, 0xf6, 0x12, 0xc1, 0xd2, + 0x13, 0xd7, 0x7e, 0x12, 0xc1, 0xc2, 0x6e, 0xde, + 0xfe, 0xbd, 0x6d, 0x0f, 0x29, 0xee, 0x79, 0x12, + 0x6e, 0xde, 0xad, 0x09, 0xfa, 0x12, 0xc1, 0xd2, + 0x13, 0xd7, 0x7e, 0x12, 0xc1, 0xc2, 0x6e, 0xdf, + 0xce, 0xbd, 0x6d, 0x0f, 0x79, 0x12, 0x2e, 0xee, + 0x6e, 0xdf, 0xad, 0x09, 0xb2, 0x0e, 0xca, 0xec, + 0x35, 0x8b, 0x6f, 0x12, 0x2d, 0x9b, 0x71, 0x2e, + 0x28, 0xd7, 0xc8, 0xd6, 0x3d, 0x15, 0x88, 0xd6, + 0xa8, 0xd6, 0x58, 0xd7, 0x08, 0xd6, 0x28, 0xd6, + 0x72, 0x0e, 0xe8, 0x12, 0x2c, 0x11, 0x2d, 0x61, + 0x3d, 0x17, 0x51, 0xc1, 0x7b, 0x83, 0xa1, 0xc5, + 0x24, 0x93, 0x21, 0xc1, 0xe3, 0x0e, 0x69, 0x8e, + 0x21, 0x8f, 0xf8, 0x89, 0x11, 0x12, 0x27, 0x9e, + 0x1f, 0x0e, 0x2d, 0x9f, 0x28, 0x99, 0xfd, 0x09, + 0x87, 0x83, 0x6c, 0x12, 0x24, 0x93, 0x7c, 0x08, + 0xfd, 0x09, 0x45, 0x83, 0x11, 0xcf, 0x7a, 0xde, + 0x27, 0x93, 0x68, 0x08, 0x4d, 0x08, 0xfd, 0x09, + 0x09, 0x12, 0x73, 0x08, 0x6c, 0x12, 0x2d, 0x09, + 0x0d, 0x0f, 0x28, 0xee, 0x68, 0x08, 0x7d, 0x08, + 0x2d, 0x09, 0xc6, 0xa1, 0x05, 0x83, 0x21, 0x93, + 0xfd, 0x09, 0x6c, 0x08, 0x98, 0xb0, 0x17, 0x83, + 0x09, 0x12, 0x21, 0x93, 0xfd, 0x09, 0x81, 0x83, + 0x6d, 0x08, 0x26, 0x93, 0xfd, 0x09, 0x0c, 0x0f, + 0xf1, 0xef, 0x93, 0x83, 0x6c, 0x08, 0x25, 0x93, + 0xfd, 0x09, 0xfa, 0xa1, 0x3d, 0x17, 0x51, 0xc1, + 0x7b, 0x83, 0xa1, 0xc5, 0x24, 0x93, 0x21, 0xc1, + 0xe3, 0x0e, 0x69, 0x8e, 0x26, 0x8f, 0xfe, 0x89, + 0x11, 0x12, 0x27, 0x9e, 0x1f, 0x0e, 0x2d, 0x9f, + 0x28, 0x99, 0xfd, 0x09, 0x87, 0x83, 0x6c, 0x12, + 0x24, 0x93, 0x7c, 0x08, 0xfd, 0x09, 0x45, 0x83, + 0x11, 0xcf, 0x7a, 0xde, 0x27, 0x93, 0x69, 0x08, + 0x4d, 0x08, 0xfd, 0x09, 0x09, 0x12, 0x73, 0x08, + 0x6c, 0x12, 0x2d, 0x09, 0x0d, 0x0f, 0x28, 0xee, + 0x69, 0x08, 0x7d, 0x08, 0x2d, 0x09, 0xc6, 0xa1, + 0x05, 0x83, 0x21, 0x93, 0xfd, 0x09, 0x6d, 0x08, + 0xb5, 0xb0, 0x17, 0x83, 0x09, 0x12, 0x21, 0x93, + 0xfd, 0x09, 0x81, 0x83, 0x6d, 0x08, 0x26, 0x93, + 0xfd, 0x09, 0x0c, 0x0f, 0xf1, 0xef, 0x93, 0x83, + 0x6c, 0x08, 0x25, 0x93, 0xfd, 0x09, 0xfa, 0xa1, + 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, 0x59, 0x12, + 0xa1, 0xc5, 0x69, 0x86, 0x81, 0xc5, 0x27, 0x96, + 0xc1, 0xc5, 0x98, 0x80, 0x21, 0xc1, 0x0b, 0x8e, + 0x21, 0x81, 0x2d, 0x9e, 0xe3, 0x0e, 0x6d, 0x4a, + 0x2b, 0x90, 0x2d, 0x91, 0x4e, 0x8a, 0x2b, 0x9a, + 0x29, 0x2e, 0x7d, 0xdd, 0x25, 0x8a, 0x2d, 0x9a, + 0x68, 0x2d, 0x6d, 0x05, 0x2f, 0xef, 0x66, 0xaf, + 0x26, 0x8a, 0x5d, 0x0f, 0x7d, 0x08, 0xf5, 0x12, + 0x2d, 0x9a, 0x2f, 0xef, 0x2f, 0xae, 0x62, 0x12, + 0x9d, 0x12, 0xfd, 0x09, 0x3f, 0x8e, 0x22, 0x8a, + 0x2d, 0x9a, 0x2d, 0x9e, 0x5d, 0x4a, 0x7d, 0x08, + 0x29, 0x2e, 0x3c, 0x8a, 0x2d, 0x9a, 0x6d, 0x2e, + 0x39, 0xde, 0x6c, 0x12, 0xad, 0x09, 0x22, 0x8a, + 0x2d, 0x9a, 0x66, 0x2e, 0x69, 0xde, 0x6d, 0x0f, + 0x62, 0xef, 0x2a, 0x0e, 0x51, 0x83, 0x6d, 0xdd, + 0x1f, 0x93, 0x24, 0x0e, 0x79, 0x12, 0x7e, 0x0c, + 0x79, 0x28, 0x73, 0x2e, 0x6c, 0x12, 0x79, 0x0e, + 0x48, 0xde, 0x71, 0x0e, 0x06, 0xbd, 0x51, 0x83, + 0xa9, 0x12, 0x26, 0x8a, 0x1f, 0x93, 0x2d, 0x9a, + 0x6d, 0x2e, 0x69, 0xde, 0x79, 0x12, 0x7e, 0x0c, + 0x79, 0x28, 0x73, 0x2e, 0x6c, 0x12, 0x79, 0x0e, + 0x48, 0xde, 0x71, 0x0e, 0x0e, 0xbd, 0x89, 0x12, + 0xeb, 0x83, 0x85, 0x27, 0x1f, 0x93, 0x62, 0x12, + 0x6d, 0x2e, 0x69, 0xde, 0x79, 0x12, 0x7e, 0x0c, + 0x79, 0x28, 0x73, 0x2e, 0x6c, 0x12, 0xfd, 0x09, + 0xeb, 0x83, 0xb9, 0x12, 0x84, 0x27, 0x20, 0x8a, + 0x2d, 0x9a, 0x1f, 0x93, 0x6d, 0x2e, 0x29, 0xde, + 0x7d, 0x12, 0x6c, 0x12, 0x7e, 0x0c, 0x7d, 0x28, + 0x73, 0x2e, 0xfd, 0x09, 0x9a, 0x0e, 0x89, 0x27, + 0x26, 0xdd, 0x94, 0x0e, 0x2e, 0x0f, 0x2f, 0xef, + 0x85, 0x07, 0x26, 0x8e, 0x2d, 0x9e, 0x26, 0x2e, + 0x2d, 0xde, 0x2e, 0x0f, 0x2f, 0xef, 0x81, 0x07, + 0x8d, 0x0f, 0x2b, 0xee, 0x87, 0x83, 0x6c, 0x12, + 0x24, 0x93, 0x77, 0x12, 0xfd, 0x09, 0x9c, 0x87, + 0x82, 0x84, 0x22, 0x12, 0x2b, 0x97, 0x34, 0xde, + 0x26, 0x2e, 0x6d, 0xde, 0x2b, 0x94, 0xa7, 0xde, + 0x6d, 0x05, 0x2d, 0x08, 0x2f, 0xef, 0x3c, 0xae, + 0x2c, 0x08, 0xb8, 0x8a, 0x28, 0x9a, 0x2b, 0x83, + 0x25, 0x93, 0x29, 0xce, 0x0d, 0x8a, 0xd5, 0x9a, + 0x29, 0xce, 0x21, 0x8e, 0x6b, 0x08, 0xfd, 0x09, + 0x26, 0x2e, 0x6d, 0xde, 0x3c, 0x8e, 0x2d, 0x9e, + 0x6c, 0x05, 0x3f, 0xee, 0x0f, 0x8a, 0x8d, 0x8b, + 0x2d, 0x9a, 0x28, 0x9b, 0x2b, 0x83, 0x29, 0x27, + 0x2c, 0x8a, 0x25, 0x93, 0x68, 0xce, 0x09, 0x8b, + 0xd5, 0x9b, 0x68, 0xce, 0x2a, 0x8a, 0xfd, 0x09, + 0x62, 0x12, 0x66, 0x2e, 0x69, 0xde, 0x6f, 0x05, + 0x34, 0xee, 0x87, 0x83, 0x2d, 0x8b, 0x24, 0x93, + 0x3d, 0x9b, 0x25, 0x8a, 0x4c, 0x80, 0x2d, 0x9a, + 0x2b, 0x90, 0xfd, 0x09, 0x63, 0xde, 0x6d, 0x0f, + 0x2b, 0xef, 0x2b, 0x83, 0x25, 0x8a, 0x25, 0x93, + 0x2d, 0x9a, 0xfd, 0x09, 0x73, 0xde, 0x6c, 0x08, + 0x6a, 0x2c, 0xd6, 0x2e, 0x68, 0x27, 0x63, 0xce, + 0x62, 0xde, 0x0f, 0x80, 0x69, 0x05, 0x2d, 0x90, + 0xdd, 0x08, 0x2f, 0xef, 0x3c, 0xae, 0x9b, 0x8b, + 0x2d, 0x8a, 0x2c, 0x9a, 0x28, 0x9b, 0x2b, 0x83, + 0x68, 0xce, 0x25, 0x93, 0x24, 0x8a, 0x2d, 0x9a, + 0x3c, 0x81, 0x2d, 0x91, 0xfd, 0x09, 0x21, 0x8a, + 0x2d, 0x9a, 0x66, 0x2e, 0x69, 0xde, 0x68, 0x05, + 0x38, 0xee, 0xec, 0x8a, 0x2d, 0x8b, 0x28, 0x9a, + 0x2c, 0x9b, 0x2b, 0x83, 0x79, 0xce, 0x0b, 0x8a, + 0x25, 0x93, 0xd5, 0x9a, 0xd3, 0x27, 0x79, 0xce, + 0x34, 0x8a, 0xc9, 0xce, 0x63, 0x12, 0x27, 0x8a, + 0xfd, 0x09, 0x21, 0x8a, 0x2d, 0x9a, 0x66, 0x2e, + 0x69, 0xde, 0x6b, 0x05, 0x3a, 0xee, 0x87, 0x83, + 0x2d, 0x8b, 0x24, 0x93, 0x2c, 0x9b, 0x25, 0x8a, + 0x4c, 0x80, 0x2d, 0x9a, 0x2b, 0x90, 0xfd, 0x09, + 0x63, 0xde, 0x6d, 0x0f, 0x2b, 0xef, 0x2b, 0x83, + 0x25, 0x8a, 0x25, 0x93, 0x2d, 0x9a, 0xfd, 0x09, + 0x73, 0xde, 0x6c, 0x08, 0x6a, 0x2c, 0x68, 0x27, + 0x63, 0xce, 0x20, 0x8a, 0xef, 0x80, 0x2d, 0x9a, + 0x2e, 0x90, 0x66, 0x2e, 0x69, 0xde, 0x67, 0x05, + 0x2e, 0xee, 0xdb, 0x07, 0x3a, 0x12, 0x66, 0x05, + 0x2e, 0xee, 0xda, 0x07, 0xaa, 0x12, 0x2d, 0x0f, + 0x20, 0xee, 0x6f, 0x08, 0xcd, 0x09, 0x3b, 0x8a, + 0xff, 0x83, 0xd5, 0x9a, 0x2e, 0x93, 0x29, 0xcf, + 0x79, 0xde, 0x28, 0x27, 0x29, 0xce, 0x6f, 0x08, + 0xfd, 0x09, 0xdd, 0x0f, 0x22, 0xee, 0x35, 0x8e, + 0x6e, 0x08, 0xd5, 0x9e, 0xcd, 0x09, 0xff, 0x83, + 0x34, 0xce, 0x2e, 0x93, 0xa7, 0xce, 0x6e, 0x08, + 0xdd, 0xcf, 0x3d, 0xde, 0xdc, 0x27, 0xdd, 0xce, + 0xfd, 0x09, 0x3f, 0x8e, 0x22, 0x8a, 0x2d, 0x9e, + 0x2d, 0x9a, 0x5d, 0x4a, 0x2b, 0x83, 0x29, 0x2e, + 0x25, 0x93, 0x7d, 0xdd, 0x6d, 0x08, 0x29, 0x0e, + 0x68, 0xcc, 0x7d, 0xde, 0x21, 0x0e, 0x68, 0xce, + 0x22, 0x8a, 0x6d, 0x2e, 0x69, 0xde, 0x2c, 0x08, + 0xfd, 0x09, 0x6d, 0x83, 0x21, 0xcf, 0x1c, 0x93, + 0x21, 0xcc, 0x22, 0x8e, 0x6a, 0x12, 0x4d, 0x08, + 0x7d, 0x08, 0xfd, 0x09, 0x26, 0x2e, 0x97, 0x83, + 0x7d, 0xde, 0x1d, 0x93, 0x6a, 0x12, 0x29, 0x08, + 0x96, 0xbf, 0x26, 0xcd, 0x6e, 0x08, 0x61, 0x2e, + 0x29, 0xd7, 0xc9, 0xd6, 0x3d, 0x15, 0x89, 0xd6, + 0xa9, 0xd6, 0x59, 0xd7, 0x29, 0xd6, 0x62, 0x0e, + 0xe9, 0x12, 0x2c, 0x11, 0x21, 0x83, 0x31, 0xc1, + 0x0c, 0x8f, 0x51, 0xc1, 0x2d, 0x9f, 0x2d, 0x93, + 0x39, 0x2e, 0x59, 0x12, 0x3c, 0xde, 0x3d, 0x0f, + 0x2f, 0xef, 0x7f, 0xae, 0x4d, 0x0f, 0x6c, 0x08, + 0x2f, 0xee, 0x62, 0xae, 0x6d, 0x12, 0x3f, 0x8e, + 0x2d, 0x9e, 0x7d, 0x4a, 0x3d, 0x12, 0x29, 0x12, + 0x22, 0x8a, 0x2d, 0x9a, 0x39, 0x2e, 0x60, 0x12, + 0x6c, 0x2e, 0x79, 0xd7, 0x69, 0xde, 0x38, 0x12, + 0x3e, 0x0c, 0x38, 0x28, 0x3b, 0x0e, 0x98, 0x8b, + 0x2b, 0x9b, 0x38, 0x2e, 0x3c, 0xde, 0x3b, 0x0e, + 0x3c, 0xdd, 0x3d, 0x0f, 0x2e, 0xeb, 0x6d, 0x08, + 0x22, 0xae, 0x39, 0x12, 0x3e, 0x0c, 0x39, 0x28, + 0x38, 0x2e, 0x3b, 0x0e, 0x3c, 0xde, 0x3b, 0x0e, + 0x3c, 0xdd, 0x3d, 0x0f, 0x3d, 0x08, 0x2f, 0xeb, + 0x2c, 0x8f, 0x6c, 0x08, 0x6c, 0x24, 0x0d, 0x8f, + 0x2d, 0x9f, 0x3a, 0x2e, 0x3c, 0xde, 0x3d, 0x0f, + 0x2f, 0xee, 0x32, 0xae, 0xfa, 0x2e, 0x70, 0xde, + 0x79, 0x05, 0x20, 0xee, 0x95, 0x8f, 0x28, 0x9f, + 0x3c, 0xde, 0x3d, 0x0f, 0x2f, 0xeb, 0x6d, 0x08, + 0x0e, 0x8f, 0xd5, 0x9f, 0x3c, 0xde, 0x3d, 0x0f, + 0x2f, 0xee, 0x6d, 0x08, 0x78, 0x05, 0x20, 0xee, + 0xee, 0x8f, 0x28, 0x9f, 0x3c, 0xde, 0x3d, 0x0f, + 0x2f, 0xeb, 0x6d, 0x08, 0x0a, 0x8f, 0xd5, 0x9f, + 0x3c, 0xde, 0x3d, 0x0f, 0x2f, 0xee, 0x6d, 0x08, + 0x51, 0xdf, 0x31, 0xdc, 0xef, 0x0e, 0x2c, 0x11, + 0x4d, 0x12, 0x31, 0xc1, 0x0b, 0x8e, 0x51, 0xc1, + 0x2d, 0x9e, 0xb1, 0xc1, 0x3c, 0x17, 0x59, 0x12, + 0x31, 0xc1, 0x6d, 0x4a, 0xe3, 0x0e, 0x6d, 0x12, + 0x4e, 0x8f, 0x2b, 0x9f, 0x2b, 0x12, 0x6c, 0x2e, + 0x49, 0xdd, 0x3d, 0x8f, 0x2d, 0x9f, 0x3b, 0x2d, + 0x3d, 0x05, 0x2e, 0xef, 0x6c, 0x08, 0x0c, 0xae, + 0x48, 0x12, 0x7a, 0x12, 0xef, 0xb1, 0x6d, 0x0f, + 0x6d, 0x08, 0x2f, 0xef, 0x37, 0xae, 0x7d, 0x08, + 0x6d, 0x83, 0x1c, 0x93, 0x71, 0xcf, 0xbc, 0x08, + 0x6a, 0x12, 0x4d, 0x08, 0xb1, 0xcc, 0xfd, 0x09, + 0xb3, 0x83, 0x6a, 0x12, 0x1d, 0x93, 0xfd, 0x09, + 0x6d, 0x12, 0x3f, 0x8e, 0x2d, 0x9e, 0x5d, 0x4a, + 0x3d, 0x12, 0x29, 0x12, 0x3f, 0x8a, 0x2d, 0x9a, + 0x39, 0x2e, 0x3c, 0xde, 0x6c, 0x08, 0xbc, 0xcc, + 0x7e, 0x08, 0x71, 0x2e, 0x38, 0xd7, 0xb8, 0xd7, + 0x3c, 0x15, 0x58, 0xd7, 0x38, 0xde, 0xeb, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x38, 0x17, 0x6d, 0x0f, + 0x71, 0xc1, 0x29, 0xee, 0x05, 0x83, 0x21, 0x93, + 0xfd, 0x09, 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, + 0x38, 0x17, 0x6d, 0x0f, 0x71, 0xc1, 0x29, 0xee, + 0x17, 0x83, 0x21, 0x93, 0xfd, 0x09, 0x61, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0x21, 0xc5, 0x3d, 0x17, + 0x01, 0xc5, 0x4e, 0x8c, 0x51, 0xc1, 0x2b, 0x9c, + 0xa1, 0xc5, 0xb8, 0x12, 0x81, 0xc5, 0x89, 0x12, + 0xc1, 0xc5, 0x45, 0x81, 0x21, 0xc1, 0x0b, 0x8e, + 0xe0, 0x0e, 0x2d, 0x9e, 0x27, 0x91, 0x6d, 0x4a, + 0x2f, 0x2e, 0x1d, 0xdd, 0x3d, 0x8c, 0x2d, 0x9c, + 0x0e, 0x2d, 0x0d, 0x05, 0x2f, 0xef, 0x10, 0xaf, + 0x7d, 0x08, 0x6d, 0x83, 0x1c, 0x93, 0x71, 0xcf, + 0x21, 0x86, 0x3c, 0x08, 0x2d, 0x96, 0x31, 0xcc, + 0x37, 0x22, 0x4d, 0x08, 0xa4, 0xbf, 0xb3, 0x83, + 0x67, 0x12, 0x1d, 0x93, 0x1b, 0xbf, 0x32, 0x0e, + 0x71, 0x83, 0x21, 0x93, 0x32, 0x0d, 0xac, 0x28, + 0xfd, 0x09, 0xbd, 0x0f, 0x59, 0x12, 0x21, 0xef, + 0x31, 0x12, 0x2d, 0x61, 0xcc, 0xb1, 0x3e, 0x0e, + 0x65, 0x12, 0x4d, 0x08, 0x31, 0xcf, 0x7c, 0x08, + 0xdd, 0x09, 0x6a, 0x12, 0xf5, 0xb1, 0x3f, 0x8f, + 0x4f, 0x83, 0x2d, 0x9f, 0x25, 0x93, 0x8c, 0x42, + 0x82, 0x85, 0x33, 0x8f, 0x2b, 0x95, 0x2d, 0x9f, + 0x1d, 0x08, 0x0c, 0x2e, 0x6f, 0xde, 0x9c, 0x8f, + 0x2b, 0x9f, 0xfd, 0x09, 0xcc, 0xde, 0x21, 0x8c, + 0x36, 0xde, 0x2d, 0x9c, 0x0d, 0x2e, 0x6f, 0xde, + 0x6d, 0x05, 0x2f, 0xef, 0x34, 0xae, 0xbd, 0x0f, + 0x20, 0xef, 0x6a, 0x12, 0x01, 0x12, 0x2d, 0x61, + 0xe3, 0xb1, 0x0e, 0x0e, 0x65, 0x12, 0x4d, 0x08, + 0x01, 0xcf, 0x7f, 0x08, 0xdd, 0x09, 0x6a, 0x12, + 0xe8, 0xb1, 0x4f, 0x83, 0x21, 0x8c, 0x25, 0x93, + 0x2d, 0x9c, 0x3c, 0x8d, 0x6b, 0x08, 0x2d, 0x9d, + 0xfd, 0x09, 0x0d, 0x2e, 0x6f, 0xde, 0x6c, 0x05, + 0x34, 0xee, 0xbd, 0x0f, 0x20, 0xef, 0x6a, 0x12, + 0x01, 0x12, 0x2d, 0x61, 0xec, 0xb1, 0x0e, 0x0e, + 0x65, 0x12, 0x4d, 0x08, 0x01, 0xcf, 0x79, 0x08, + 0xdd, 0x09, 0x6a, 0x12, 0x95, 0xb1, 0x0f, 0x8c, + 0x4f, 0x83, 0x2d, 0x9c, 0x25, 0x93, 0x6a, 0x08, + 0x1f, 0x27, 0x21, 0x8c, 0xfd, 0x09, 0x0d, 0x2e, + 0x6f, 0xde, 0x6f, 0x05, 0x0b, 0xee, 0x4c, 0x88, + 0xfc, 0x08, 0xf7, 0x2c, 0x2b, 0x98, 0x7b, 0xde, + 0x00, 0x25, 0x08, 0x26, 0x7d, 0x0f, 0x0b, 0xce, + 0x31, 0xee, 0x0d, 0x0f, 0x37, 0xef, 0xbd, 0x0f, + 0x22, 0xef, 0x6a, 0x12, 0x01, 0x12, 0x2d, 0x61, + 0x83, 0xb1, 0x25, 0x8b, 0x0e, 0x0e, 0x2d, 0x9b, + 0x01, 0xcf, 0x65, 0x12, 0x4d, 0x08, 0xdd, 0x09, + 0x6a, 0x12, 0x2d, 0x61, 0x89, 0xb1, 0x4f, 0x83, + 0x25, 0x8a, 0x25, 0x93, 0x2d, 0x9a, 0x21, 0x8c, + 0xfd, 0x09, 0x2d, 0x9c, 0x0d, 0x2e, 0x6f, 0xde, + 0x69, 0x05, 0x0d, 0x08, 0x2f, 0xef, 0x36, 0xae, + 0xbd, 0x0f, 0x23, 0xef, 0x6a, 0x12, 0x01, 0x12, + 0x8d, 0xb1, 0x3d, 0x8b, 0x0e, 0x0e, 0x2d, 0x9b, + 0x01, 0xcf, 0x65, 0x12, 0x4d, 0x08, 0xdd, 0x09, + 0x6a, 0x12, 0x2d, 0x61, 0xbb, 0xb1, 0x4f, 0x83, + 0x24, 0x8a, 0x25, 0x93, 0x2d, 0x9a, 0x21, 0x8c, + 0xfd, 0x09, 0x2d, 0x9c, 0x0d, 0x2e, 0x6f, 0xde, + 0x3c, 0x8c, 0x2d, 0x9c, 0x68, 0x05, 0x36, 0xee, + 0xbd, 0x0f, 0x23, 0xef, 0x6a, 0x12, 0x2d, 0x61, + 0xbf, 0xb1, 0x0d, 0x8b, 0x61, 0x12, 0x6e, 0x0e, + 0x2d, 0x9b, 0x4d, 0x08, 0x61, 0xcf, 0x65, 0x12, + 0xdd, 0x09, 0x6a, 0x12, 0xa5, 0xb1, 0x0f, 0x8a, + 0x4f, 0x83, 0x2d, 0x9a, 0x25, 0x93, 0x09, 0x27, + 0x27, 0x8a, 0xfd, 0x09, 0x21, 0x8a, 0x2d, 0x9a, + 0x6d, 0x2e, 0x69, 0xde, 0x6b, 0x05, 0x0f, 0xee, + 0x4c, 0x88, 0xfc, 0x08, 0xf7, 0x2c, 0x2b, 0x98, + 0x7b, 0xde, 0x60, 0x25, 0x68, 0x26, 0x7d, 0x0f, + 0x6b, 0xce, 0x35, 0xee, 0x6d, 0x0f, 0x3b, 0xef, + 0xbd, 0x0f, 0x25, 0x87, 0x2d, 0x97, 0x23, 0xef, + 0x6a, 0x12, 0x2d, 0x61, 0x50, 0xb1, 0x61, 0x12, + 0x74, 0x12, 0x6e, 0x0e, 0x4d, 0x08, 0x61, 0xcf, + 0x65, 0x12, 0xdd, 0x09, 0x6a, 0x12, 0x2d, 0x61, + 0x5e, 0xb1, 0x4f, 0x83, 0x64, 0x12, 0x25, 0x93, + 0xfd, 0x09, 0x20, 0x8a, 0xff, 0x89, 0x2d, 0x9a, + 0xef, 0x86, 0x6d, 0x2e, 0x2e, 0x99, 0x69, 0xde, + 0x2e, 0x96, 0x67, 0x05, 0x2e, 0xee, 0x0b, 0x07, + 0xc2, 0x08, 0x66, 0x05, 0x2e, 0xee, 0x0a, 0x07, + 0x32, 0x08, 0x1d, 0x0f, 0x21, 0xee, 0x6f, 0x08, + 0xad, 0x09, 0x3b, 0x8a, 0x7e, 0x25, 0xd5, 0x9a, + 0x49, 0xde, 0x7b, 0x26, 0x79, 0xce, 0x19, 0xcf, + 0x6f, 0x08, 0x5d, 0x09, 0x0d, 0x0f, 0x3d, 0xee, + 0x6e, 0x08, 0x1f, 0x25, 0xad, 0x09, 0x9c, 0x8a, + 0x2b, 0x9a, 0xc9, 0xce, 0x36, 0xce, 0x35, 0x8f, + 0xd5, 0x9f, 0x6c, 0xde, 0x19, 0x26, 0x6e, 0x08, + 0x1c, 0xce, 0x0c, 0xcf, 0x5d, 0x09, 0x3f, 0x8f, + 0x69, 0x83, 0x2d, 0x9f, 0x27, 0x93, 0x8c, 0x42, + 0x72, 0x8b, 0x22, 0x8f, 0xd2, 0x9b, 0x2d, 0x9f, + 0x0c, 0x2e, 0x3d, 0x8f, 0x2d, 0x9f, 0x3f, 0x2e, + 0x6c, 0xde, 0x3e, 0x08, 0xfd, 0x09, 0x0f, 0x8a, + 0x3d, 0xcd, 0x2d, 0x9a, 0x6d, 0x2e, 0x29, 0xde, + 0x2d, 0x0f, 0x2a, 0xee, 0x3f, 0xde, 0x89, 0x8e, + 0x2d, 0x9e, 0x2c, 0xce, 0x2d, 0x8e, 0x29, 0xce, + 0x69, 0x08, 0x61, 0x2e, 0x29, 0xd7, 0xc9, 0xd6, + 0x3d, 0x15, 0x89, 0xd6, 0xa9, 0xd6, 0x59, 0xd7, + 0x09, 0xd6, 0x29, 0xd6, 0x62, 0x0e, 0xe9, 0x12, + 0x2c, 0x11, 0xe2, 0x61, 0x39, 0x17, 0xd3, 0x83, + 0x26, 0x93, 0x61, 0xc1, 0xfd, 0x09, 0x72, 0x08, + 0x68, 0xde, 0x6d, 0x05, 0x23, 0xee, 0x74, 0x8a, + 0x2d, 0x9a, 0x68, 0xce, 0x6c, 0x8a, 0x68, 0xce, + 0x60, 0x8a, 0x68, 0xce, 0x6c, 0x8a, 0x68, 0xce, + 0x65, 0x8a, 0x68, 0xce, 0x6c, 0x8a, 0x68, 0xce, + 0x37, 0x83, 0x21, 0x93, 0xfd, 0x09, 0x6d, 0x08, + 0x3d, 0x8b, 0xd5, 0x9b, 0x68, 0xce, 0x3c, 0x8b, + 0x68, 0xce, 0x2c, 0x8a, 0x73, 0x08, 0x68, 0xce, + 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, 0x2d, 0x61, + 0x6d, 0x6e, 0x3b, 0x17, 0xd3, 0x83, 0x41, 0xc1, + 0x43, 0x08, 0x26, 0x93, 0x6b, 0xce, 0x68, 0xde, + 0x3d, 0x88, 0xd5, 0x98, 0x6b, 0xce, 0x68, 0xdf, + 0x3c, 0x8b, 0xd5, 0x9b, 0x68, 0xce, 0xfd, 0x09, + 0x72, 0x08, 0x68, 0xde, 0x6d, 0x05, 0x2e, 0xef, + 0x6c, 0x08, 0x68, 0xce, 0x37, 0x83, 0x21, 0x93, + 0xfd, 0x09, 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, + 0x38, 0x17, 0x51, 0xc1, 0x27, 0x89, 0xa1, 0xc5, + 0xa9, 0x12, 0x71, 0xc1, 0xbf, 0x8b, 0x03, 0x99, + 0x09, 0x9b, 0x79, 0x26, 0x25, 0xef, 0x64, 0x8a, + 0xdf, 0x87, 0x3f, 0x9a, 0x2d, 0x97, 0x65, 0x26, + 0x2f, 0xef, 0x2e, 0xae, 0xdc, 0x87, 0x2d, 0x97, + 0x09, 0x8a, 0x64, 0x9a, 0x65, 0x26, 0x2f, 0xee, + 0xdf, 0x87, 0xed, 0x8a, 0x2c, 0x9a, 0x65, 0x26, + 0x2a, 0xee, 0x7c, 0x08, 0x6d, 0x08, 0x5d, 0x09, + 0x7d, 0x8a, 0xd4, 0x9a, 0xb9, 0xce, 0x2d, 0x8a, + 0x23, 0x9a, 0x65, 0x26, 0x2a, 0xee, 0x7c, 0x08, + 0x6c, 0x08, 0x5d, 0x09, 0x7d, 0x8a, 0xd7, 0x9a, + 0xb9, 0xce, 0x6a, 0x08, 0x65, 0x26, 0x32, 0xee, + 0x69, 0x83, 0x6f, 0x08, 0x27, 0x93, 0x7d, 0x08, + 0xfd, 0x09, 0x7c, 0x08, 0x6d, 0x08, 0x5d, 0x09, + 0x1d, 0x8a, 0x52, 0x8b, 0xd4, 0x9a, 0x2d, 0x9b, + 0x49, 0xde, 0x7b, 0x2f, 0x2f, 0xe7, 0xb9, 0xce, + 0xa5, 0x8b, 0x2b, 0x9b, 0x68, 0xde, 0x6d, 0x0f, + 0x2b, 0xee, 0x02, 0x8a, 0xd3, 0x9a, 0xb9, 0xce, + 0x6d, 0x08, 0x68, 0xce, 0x2b, 0x83, 0x6f, 0x08, + 0x25, 0x93, 0xfd, 0x09, 0x15, 0x8a, 0x2d, 0x9a, + 0x65, 0x26, 0x32, 0xee, 0x69, 0x83, 0x6e, 0x08, + 0x27, 0x93, 0x7d, 0x08, 0xfd, 0x09, 0x7c, 0x08, + 0x6c, 0x08, 0x5d, 0x09, 0x1d, 0x8a, 0x52, 0x8b, + 0xd7, 0x9a, 0x2d, 0x9b, 0x49, 0xde, 0x7b, 0x2f, + 0x2f, 0xe7, 0xb9, 0xce, 0x83, 0x8b, 0x2b, 0x9b, + 0x68, 0xde, 0x6d, 0x0f, 0x2b, 0xee, 0x12, 0x8a, + 0xd3, 0x9a, 0xb9, 0xce, 0x6d, 0x08, 0x68, 0xce, + 0x2b, 0x83, 0x6e, 0x08, 0x25, 0x93, 0xfd, 0x09, + 0x2d, 0x8a, 0x5d, 0x9a, 0xa9, 0x26, 0x21, 0xee, + 0x2d, 0x9a, 0x25, 0x8e, 0x7c, 0x08, 0xd5, 0x9e, + 0xdc, 0xb0, 0x7c, 0x08, 0x6c, 0x08, 0x5d, 0x09, + 0xbd, 0xce, 0xd2, 0x03, 0xd2, 0xa1, 0x61, 0xdf, + 0xa1, 0xdc, 0xb1, 0xdd, 0xee, 0x0e, 0x51, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0x3d, 0x17, 0x51, 0xc1, + 0xcb, 0x83, 0x21, 0xc1, 0xe3, 0x0e, 0x21, 0x93, + 0x21, 0x12, 0x2f, 0x0e, 0xfd, 0x09, 0x45, 0x83, + 0x21, 0xcf, 0x27, 0x93, 0xd2, 0x8b, 0x52, 0x9b, + 0x6c, 0x08, 0x4c, 0x08, 0xfd, 0x09, 0x6d, 0x0f, + 0xda, 0xef, 0x61, 0xdc, 0x9e, 0xb1, 0xd9, 0xa1, + 0x49, 0x12, 0x51, 0xc1, 0xa1, 0xc5, 0x59, 0xdf, + 0x5d, 0x0f, 0x02, 0xee, 0x5e, 0x0f, 0x00, 0xee, + 0x5c, 0x0f, 0x25, 0xef, 0x59, 0xdd, 0xa9, 0xdc, + 0x5a, 0x22, 0x52, 0x0e, 0x52, 0x0d, 0x5f, 0x0e, + 0x25, 0xae, 0x5f, 0x0f, 0xac, 0x08, 0x5d, 0x08, + 0x2f, 0xee, 0x2e, 0xae, 0xa9, 0xdd, 0x5f, 0x08, + 0x49, 0x0e, 0x6b, 0xde, 0x6c, 0x0e, 0x6b, 0xce, + 0x41, 0x0e, 0x65, 0x2f, 0x3b, 0xe7, 0x6b, 0x12, + 0x68, 0x0e, 0x49, 0x0e, 0xa9, 0xde, 0xb9, 0xdf, + 0x6d, 0x08, 0x6b, 0xce, 0x41, 0x0e, 0xac, 0x0e, + 0x2e, 0xea, 0x2f, 0xed, 0xbc, 0x0e, 0x6b, 0x12, + 0xa8, 0xcf, 0x68, 0x0e, 0xb8, 0xcc, 0xa9, 0xc6, + 0x68, 0xde, 0x6d, 0x07, 0x68, 0xce, 0x5b, 0xcf, + 0xa1, 0xdf, 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x39, 0x17, 0x61, 0xc1, + 0x39, 0x8a, 0x2d, 0x9a, 0x79, 0xde, 0x5e, 0x8a, + 0x2b, 0x9a, 0x2d, 0x61, 0xf2, 0xb1, 0x61, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0x39, 0x17, 0x61, 0xc1, + 0x0b, 0x8a, 0x2d, 0x9a, 0x79, 0xde, 0xb4, 0x8a, + 0x2b, 0x9a, 0x2d, 0x61, 0xf4, 0xb1, 0x61, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0x79, 0x22, 0x31, 0xc1, + 0x72, 0x0e, 0x3c, 0x17, 0x72, 0x0d, 0x31, 0xc1, + 0x39, 0x12, 0x73, 0x83, 0x26, 0x93, 0x69, 0x08, + 0x68, 0x28, 0xfd, 0x09, 0x6d, 0x12, 0x0b, 0x8e, + 0x2d, 0x9e, 0x3d, 0x4a, 0x3d, 0x12, 0x29, 0x12, + 0x50, 0x8a, 0x2b, 0x9a, 0x39, 0x2e, 0x6d, 0x08, + 0x6c, 0xce, 0x31, 0xdf, 0x3c, 0x15, 0x31, 0xdc, + 0xef, 0x0e, 0x2c, 0x11, 0x48, 0x12, 0x21, 0xc5, + 0x3d, 0x17, 0x51, 0xc1, 0x72, 0x0e, 0xa1, 0xc5, + 0x21, 0xc1, 0x20, 0x08, 0x28, 0x2f, 0x37, 0xe7, + 0x0b, 0x8e, 0x79, 0x22, 0x72, 0x0e, 0x2d, 0x9e, + 0x6d, 0x4a, 0x72, 0x0d, 0x37, 0x83, 0x4e, 0x8a, + 0x26, 0x93, 0x2b, 0x9a, 0x3c, 0x24, 0x29, 0x2e, + 0x37, 0x8a, 0x2d, 0x9a, 0x6d, 0x2e, 0x2d, 0x08, + 0x29, 0xcf, 0x39, 0xcc, 0x39, 0xcd, 0x49, 0xce, + 0x29, 0xc8, 0x29, 0xc9, 0x69, 0x08, 0x68, 0x28, + 0xfd, 0x09, 0x6c, 0x08, 0x61, 0x2e, 0x29, 0xd7, + 0xa9, 0xd6, 0x3d, 0x15, 0x59, 0xd7, 0x29, 0xd6, + 0xeb, 0x0e, 0x2c, 0x11, 0x49, 0x22, 0x21, 0xc5, + 0x42, 0x0e, 0x51, 0xc1, 0x3d, 0x17, 0xa1, 0xc5, + 0x42, 0x0d, 0x81, 0xc5, 0x0b, 0x84, 0x21, 0xc1, + 0x4e, 0x85, 0xbf, 0x08, 0x2d, 0x94, 0x59, 0x12, + 0x67, 0x4a, 0xbb, 0x28, 0xa8, 0x12, 0x5e, 0x8a, + 0x2b, 0x95, 0x2b, 0x9a, 0x29, 0x2e, 0x6d, 0xde, + 0x6d, 0x0f, 0x6d, 0x08, 0x2f, 0xef, 0x25, 0xae, + 0x73, 0x83, 0x64, 0x12, 0x26, 0x93, 0x3d, 0x08, + 0xfd, 0x09, 0x6c, 0x08, 0x3d, 0xce, 0x57, 0x4a, + 0x39, 0x8b, 0x26, 0x2e, 0x2d, 0x9b, 0x7d, 0x2e, + 0x2d, 0x34, 0xad, 0x0f, 0x28, 0xcf, 0x28, 0xcc, + 0x28, 0xce, 0x28, 0xee, 0x38, 0xcb, 0x38, 0xc8, + 0x38, 0xc9, 0x0d, 0xae, 0x28, 0xd9, 0x48, 0x12, + 0x40, 0x0e, 0x2d, 0x0f, 0x3b, 0xce, 0x2e, 0xee, + 0x2f, 0x08, 0x2b, 0xce, 0x57, 0x4a, 0x3f, 0x8b, + 0x26, 0x2e, 0x2d, 0x9b, 0x7d, 0x2e, 0x28, 0xde, + 0x2d, 0x0f, 0x29, 0xee, 0x72, 0x0e, 0x2c, 0x08, + 0x28, 0xce, 0x6d, 0x0f, 0x26, 0xee, 0x57, 0x4a, + 0x37, 0x83, 0x64, 0x12, 0x26, 0x93, 0xfd, 0x09, + 0x5e, 0x8a, 0x2b, 0x9a, 0x29, 0x2e, 0x6c, 0x08, + 0x6d, 0xce, 0x2c, 0x8a, 0x61, 0x2e, 0x29, 0xd7, + 0x89, 0xd6, 0x3d, 0x15, 0xa9, 0xd6, 0x59, 0xd7, + 0x29, 0xd6, 0x62, 0x0e, 0xe9, 0x12, 0x2c, 0x11, + 0x21, 0xc5, 0x3d, 0x17, 0x51, 0xc1, 0x5f, 0x08, + 0xa1, 0xc5, 0xb9, 0x12, 0x81, 0xc5, 0x69, 0x22, + 0x21, 0xc1, 0x62, 0x0e, 0x0b, 0x84, 0x62, 0x0d, + 0x2d, 0x94, 0xb7, 0x4a, 0x59, 0x28, 0x98, 0x12, + 0x5e, 0x8b, 0xab, 0x12, 0x2b, 0x9b, 0x28, 0x2e, + 0x6d, 0xde, 0x6d, 0x0f, 0x2a, 0xee, 0x73, 0x83, + 0x6a, 0x12, 0x26, 0x93, 0x3d, 0x08, 0xfd, 0x09, + 0x3d, 0xce, 0x24, 0x8e, 0x4e, 0x88, 0x2d, 0x9e, + 0x2b, 0x98, 0x21, 0x2e, 0x2d, 0xdf, 0x2d, 0x0f, + 0x25, 0xef, 0xb7, 0x4a, 0x3e, 0x8a, 0x2d, 0x9a, + 0x2b, 0x2e, 0x6d, 0x2e, 0xa9, 0xc1, 0x99, 0xce, + 0xb7, 0x4a, 0x39, 0x8a, 0x2b, 0x2e, 0x2d, 0x9a, + 0x6d, 0x2e, 0x79, 0xd8, 0xf9, 0x12, 0x2d, 0x34, + 0xf3, 0x0e, 0x39, 0xcf, 0x7d, 0x0f, 0x39, 0xcc, + 0x29, 0xce, 0x25, 0xef, 0x29, 0xd9, 0xfc, 0x0e, + 0x2d, 0x0f, 0x29, 0xef, 0xf3, 0x0e, 0x30, 0xce, + 0x0b, 0xae, 0x24, 0x83, 0x2d, 0x93, 0x21, 0xd2, + 0x2d, 0x0f, 0x0c, 0xee, 0xb7, 0x4a, 0x3e, 0x8a, + 0x2b, 0x2e, 0x2d, 0x9a, 0x6d, 0x2e, 0x29, 0xde, + 0x2d, 0x0f, 0x29, 0xee, 0x63, 0x0e, 0x2f, 0x08, + 0x29, 0xce, 0xb7, 0x4a, 0x3f, 0x8a, 0x2b, 0x2e, + 0x2d, 0x9a, 0x6d, 0x2e, 0x29, 0xde, 0x2d, 0x0f, + 0x29, 0xee, 0x62, 0x0e, 0x2c, 0x08, 0x29, 0xce, + 0xb7, 0x4a, 0x37, 0x83, 0x6a, 0x12, 0x26, 0x93, + 0xfd, 0x09, 0x5e, 0x8a, 0x2b, 0x9a, 0x29, 0x2e, + 0x6c, 0x08, 0x6d, 0xce, 0x6c, 0x08, 0x61, 0x2e, + 0x29, 0xd7, 0x89, 0xd6, 0x3d, 0x15, 0xa9, 0xd6, + 0x59, 0xd7, 0x29, 0xd6, 0x62, 0x0e, 0xe9, 0x12, + 0x2c, 0x11, 0x2d, 0x61, 0x51, 0xc1, 0x3a, 0x17, + 0xb1, 0xc1, 0x51, 0xc1, 0x59, 0x12, 0x69, 0x0e, + 0x59, 0x0e, 0x69, 0xde, 0x6c, 0x0e, 0x6a, 0xce, + 0x51, 0x0e, 0xba, 0xdd, 0x64, 0x2f, 0x24, 0xe7, + 0xdb, 0x83, 0x59, 0x0e, 0x24, 0x93, 0x6d, 0x08, + 0x6a, 0xce, 0x68, 0x12, 0x7b, 0x12, 0xfd, 0x09, + 0x61, 0xdf, 0xb1, 0xdc, 0x51, 0xdd, 0xee, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x39, 0x17, 0x61, 0xc1, + 0x1f, 0x8a, 0x2d, 0x9a, 0x79, 0xde, 0xf8, 0x8a, + 0x28, 0x9a, 0x49, 0xde, 0x8d, 0x8a, 0x2b, 0x9a, + 0xc0, 0xb1, 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, + 0x39, 0x17, 0x61, 0xc1, 0x0d, 0x8a, 0x2d, 0x9a, + 0x79, 0xde, 0xfe, 0x8a, 0x28, 0x9a, 0x49, 0xde, + 0x57, 0x8a, 0x2b, 0x9a, 0xcb, 0xb1, 0x61, 0xdf, + 0xec, 0x0e, 0x29, 0x15, 0x4d, 0x0f, 0xd1, 0xc1, + 0x3e, 0xeb, 0x42, 0x0e, 0xd8, 0x12, 0xfb, 0x12, + 0x7c, 0x12, 0xfc, 0x0e, 0x4d, 0x12, 0xfd, 0x05, + 0x2e, 0xee, 0x22, 0xd7, 0x29, 0xc7, 0xfc, 0x0d, + 0x70, 0x14, 0x2e, 0xae, 0x22, 0xd6, 0x29, 0xc6, + 0xd3, 0xe0, 0x38, 0x12, 0x2b, 0x12, 0xd1, 0xdf, + 0xec, 0x0e, 0x2c, 0x11, 0x4d, 0x0f, 0x3e, 0xeb, + 0x42, 0x0e, 0xfc, 0x12, 0x7b, 0x14, 0x4d, 0x12, + 0x7d, 0x16, 0x2c, 0x0e, 0x2d, 0x05, 0x2f, 0xee, + 0x79, 0xc7, 0x2c, 0x0d, 0x38, 0x12, 0x7d, 0x14, + 0x28, 0x12, 0x2f, 0xae, 0x29, 0xc6, 0xd2, 0xe0, + 0x30, 0x12, 0x2b, 0x12, 0x2c, 0x11, 0x2d, 0x61, + 0x69, 0x0e, 0x7d, 0x08, 0x79, 0xce, 0x61, 0x0e, + 0x79, 0xce, 0x79, 0xcf, 0x79, 0xcc, 0x79, 0xcd, + 0x68, 0x0e, 0x79, 0xce, 0x2c, 0x11, 0x2d, 0x61, + 0x68, 0x0e, 0x7d, 0x08, 0x79, 0xc7, 0x69, 0xde, + 0x6b, 0x0e, 0x79, 0xcd, 0x2c, 0x11, 0x2d, 0x61, + 0x25, 0x83, 0xa1, 0xc5, 0xa5, 0x34, 0x2d, 0x93, + 0xf9, 0x2e, 0xa0, 0xc6, 0xb9, 0xcf, 0xb9, 0xcc, + 0x68, 0x0e, 0x79, 0xc7, 0x49, 0xce, 0x67, 0x0e, + 0xa9, 0xcd, 0x69, 0x0e, 0xa9, 0xce, 0x6e, 0x0e, + 0xa9, 0xce, 0xa1, 0xdf, 0xb1, 0xdc, 0xef, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x6a, 0x0e, 0x79, 0xcd, + 0x64, 0x0e, 0x72, 0x08, 0x79, 0xce, 0x2c, 0x11, + 0x7d, 0x08, 0x6a, 0x0e, 0x79, 0xcd, 0x64, 0x0e, + 0x72, 0x0e, 0x79, 0xce, 0x2c, 0x11, 0x2d, 0x61, + 0x38, 0x17, 0x51, 0xc1, 0x59, 0x12, 0x71, 0xc1, + 0x7d, 0x08, 0x07, 0x8a, 0x2d, 0x9a, 0x24, 0x88, + 0x6a, 0x2e, 0x2d, 0x98, 0x79, 0xc8, 0x79, 0xc9, + 0xfe, 0xb1, 0x1e, 0x8a, 0x24, 0x88, 0x2d, 0x9a, + 0x2d, 0x98, 0x6a, 0x2e, 0x7d, 0x08, 0x2d, 0x61, + 0xe2, 0xb1, 0x11, 0x8a, 0x4e, 0x08, 0x2d, 0x9a, + 0x7d, 0x08, 0x6a, 0x2e, 0xe1, 0xb1, 0x12, 0x8a, + 0x4f, 0x08, 0x2d, 0x9a, 0x7d, 0x08, 0x6a, 0x2e, + 0xe4, 0xb1, 0x6d, 0x08, 0x6e, 0x8b, 0x2d, 0x9b, + 0x7a, 0x2e, 0x68, 0xc0, 0x68, 0xc7, 0x68, 0xce, + 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, 0x29, 0x15, + 0x6d, 0x0f, 0x51, 0xc1, 0x58, 0x12, 0x30, 0xee, + 0x7d, 0x0f, 0x36, 0xee, 0x78, 0xdf, 0x79, 0x2f, + 0x35, 0xef, 0x4d, 0x0f, 0x39, 0xef, 0x5b, 0x0e, + 0x6a, 0xde, 0x6b, 0x0e, 0x57, 0x0e, 0x79, 0xde, + 0x67, 0x0e, 0x7d, 0x0f, 0x2b, 0xeb, 0x6b, 0x0e, + 0x69, 0xdd, 0x68, 0x2f, 0x27, 0xed, 0x2a, 0xae, + 0x7d, 0x0f, 0x28, 0xef, 0x6b, 0x0e, 0x69, 0xdd, + 0x6d, 0x0f, 0x2e, 0xeb, 0x6a, 0xdd, 0x2f, 0xae, + 0x6d, 0x08, 0x51, 0xdf, 0xec, 0x0e, 0x2c, 0x11, + 0x6d, 0x0f, 0x51, 0xc1, 0x58, 0x12, 0x33, 0xee, + 0x7d, 0x0f, 0x31, 0xee, 0x78, 0xdf, 0x79, 0x2f, + 0x34, 0xef, 0x5b, 0x0e, 0x6a, 0xde, 0x57, 0x0e, + 0x4d, 0x0f, 0x3c, 0xef, 0x6b, 0x0e, 0x79, 0xde, + 0x67, 0x0e, 0x7d, 0x0f, 0x2b, 0xeb, 0x6b, 0x0e, + 0x69, 0xdd, 0x79, 0x2f, 0x26, 0xeb, 0x2a, 0xae, + 0x7d, 0x0f, 0x25, 0xef, 0x6b, 0x0e, 0x69, 0xdd, + 0x6d, 0x0f, 0x29, 0xef, 0x6a, 0xdd, 0x69, 0x25, + 0x2f, 0xae, 0x62, 0x08, 0x51, 0xdf, 0xec, 0x0e, + 0x2c, 0x11, 0x2d, 0x61, 0x6d, 0x0f, 0x48, 0x12, + 0x22, 0xee, 0x7d, 0x0f, 0x20, 0xee, 0x78, 0xde, + 0x79, 0x2f, 0x27, 0xef, 0x4b, 0x0e, 0x6b, 0xde, + 0x6b, 0x0e, 0x47, 0x0e, 0x69, 0xdd, 0x6d, 0x0f, + 0x6b, 0xdc, 0x2f, 0xef, 0x2f, 0xae, 0x6d, 0x08, + 0x2c, 0x11, 0x2d, 0x61, 0x6d, 0x0f, 0x48, 0x12, + 0x3d, 0xee, 0x7d, 0x0f, 0x23, 0xee, 0x78, 0xde, + 0x79, 0x2f, 0x26, 0xef, 0x4b, 0x0e, 0x6b, 0xde, + 0x6b, 0x0e, 0x47, 0x0e, 0x69, 0xdd, 0x6d, 0x0f, + 0x29, 0xeb, 0x6b, 0xdc, 0x69, 0x25, 0x2f, 0xae, + 0x62, 0x08, 0x2c, 0x11, 0x6d, 0x0f, 0x48, 0x12, + 0x0a, 0xee, 0x7d, 0x0f, 0x08, 0xee, 0x78, 0xde, + 0x79, 0x2f, 0x0f, 0xef, 0x7b, 0x0f, 0x2a, 0xef, + 0x0c, 0x8a, 0xd5, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0x36, 0xee, 0x35, 0xae, 0x7a, 0x0f, 0x2a, 0xef, + 0x08, 0x8a, 0xd5, 0x9a, 0x69, 0xde, 0x6d, 0x0f, + 0x3e, 0xee, 0x3d, 0xae, 0x25, 0x8a, 0x2d, 0x9a, + 0x79, 0x2f, 0x23, 0xef, 0x9d, 0x8a, 0x28, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0x24, 0xee, 0x6b, 0x0e, + 0x69, 0xde, 0x6b, 0x0e, 0x69, 0xdd, 0x6d, 0x0f, + 0x2e, 0xeb, 0x6b, 0xdc, 0x2f, 0xae, 0x6d, 0x08, + 0x2c, 0x11, 0x2d, 0x61, 0x6d, 0x0f, 0x51, 0xc1, + 0x48, 0x12, 0x31, 0xee, 0x7d, 0x0f, 0x37, 0xee, + 0x58, 0xdf, 0x59, 0x2f, 0x3a, 0xef, 0x7b, 0x0e, + 0x68, 0xde, 0x6b, 0x0e, 0x69, 0xdd, 0x6d, 0x0f, + 0x22, 0xea, 0x49, 0x0e, 0x6b, 0xde, 0x41, 0x0e, + 0x6d, 0x0f, 0x21, 0xee, 0x27, 0x8a, 0x2d, 0x9a, + 0x59, 0x2f, 0x25, 0xef, 0xee, 0x8a, 0x28, 0x9a, + 0x69, 0xde, 0x6d, 0x0f, 0x2e, 0xeb, 0x6b, 0xdd, + 0x2f, 0xae, 0x6d, 0x08, 0x51, 0xdf, 0xec, 0x0e, + 0x2c, 0x11, 0xe2, 0x61, 0xd9, 0x16, 0xad, 0x8b, + 0xcd, 0x9b, 0x68, 0x26, 0xd9, 0x14, 0x6d, 0x08, + 0x29, 0x14, 0xc9, 0x14, 0x2c, 0x11, 0x2d, 0x61, + 0x05, 0x83, 0x51, 0xc1, 0x38, 0x17, 0x59, 0x12, + 0x21, 0x93, 0x71, 0xc1, 0xfd, 0x09, 0x2d, 0x61, + 0xda, 0xb1, 0x7a, 0x12, 0x87, 0x83, 0x24, 0x93, + 0x6c, 0x08, 0xfd, 0x09, 0x63, 0x83, 0x25, 0x93, + 0xfd, 0x09, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x38, 0x17, 0x51, 0xc1, + 0x59, 0x12, 0x71, 0xc1, 0x05, 0x83, 0x21, 0x93, + 0xfd, 0x09, 0x2d, 0x61, 0xc1, 0xb1, 0x7a, 0x12, + 0x87, 0x83, 0x24, 0x93, 0x6c, 0x08, 0xfd, 0x09, + 0x63, 0x83, 0x25, 0x93, 0xfd, 0x09, 0x61, 0xdf, + 0x51, 0xdc, 0xef, 0x0e, 0x29, 0x15, 0x2d, 0x61, + 0x38, 0x17, 0x51, 0xc1, 0x59, 0x12, 0x71, 0xc1, + 0x05, 0x83, 0x21, 0x93, 0xfd, 0x09, 0x2d, 0x61, + 0xcc, 0xb1, 0x7a, 0x12, 0x87, 0x83, 0x24, 0x93, + 0x6c, 0x08, 0xfd, 0x09, 0x63, 0x83, 0x25, 0x93, + 0xfd, 0x09, 0x61, 0xdf, 0x51, 0xdc, 0xef, 0x0e, + 0x29, 0x15, 0xe2, 0x61, 0x2e, 0x8a, 0x20, 0x8b, + 0xa9, 0x9a, 0xd5, 0x9b, 0x68, 0xce, 0xb9, 0x02, + 0x09, 0x03, 0x2c, 0x11, 0x20, 0x8b, 0x6d, 0x08, + 0xd5, 0x9b, 0x68, 0xce, 0x09, 0x02, 0xb9, 0x02, + 0x2c, 0x11, 0x2d, 0x61, 0x39, 0x17, 0x20, 0x8b, + 0xd5, 0x9b, 0x61, 0xc1, 0xe3, 0x0e, 0xbf, 0x83, + 0x68, 0xde, 0x2a, 0x93, 0x68, 0xce, 0xb9, 0x02, + 0x09, 0x03, 0xfd, 0x09, 0x6d, 0x0f, 0x23, 0xec, + 0x95, 0x83, 0x61, 0xcc, 0x51, 0x8a, 0x1e, 0x93, + 0x2d, 0x9a, 0x12, 0x88, 0x2d, 0x98, 0x61, 0xcf, + 0x4f, 0x8b, 0x6d, 0x08, 0x2d, 0x9b, 0xfd, 0x09, + 0xd2, 0x03, 0x61, 0xdd, 0xee, 0x0e, 0x29, 0x15, + 0x2c, 0x11, 0xe2, 0x61, 0x39, 0x17, 0xcd, 0x83, + 0x2e, 0x93, 0x61, 0xc1, 0xfd, 0x09, 0x53, 0x83, + 0x24, 0x93, 0xfd, 0x09, 0xe7, 0x83, 0x27, 0x93, + 0xfd, 0x09, 0x49, 0x83, 0x21, 0x93, 0xfd, 0x09, + 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, 0x2d, 0x61, + 0x39, 0x17, 0xbf, 0x83, 0x1e, 0x93, 0x61, 0xc1, + 0x6d, 0x08, 0xfd, 0x09, 0x61, 0xdf, 0xec, 0x0e, + 0x29, 0x15, 0x2d, 0x61, 0x39, 0x17, 0xa7, 0x83, + 0x1e, 0x93, 0x61, 0xc1, 0x6d, 0x08, 0xfd, 0x09, + 0x23, 0x83, 0x6d, 0x08, 0x20, 0x93, 0xfd, 0x09, + 0x61, 0xdf, 0xec, 0x0e, 0x29, 0x15, + /* data */ + 0x2d, 0xae, 0x2c, 0xae, 0x2d, 0xae, 0x2f, 0xae, + 0x2d, 0xae, 0x2c, 0xae, 0x2d, 0xae, 0x2e, 0xae, + 0x2d, 0xae, 0x2c, 0xae, 0x2d, 0xae, 0x2f, 0xae, + 0x2d, 0xae, 0x2c, 0xae, 0x2d, 0xae, 0x1d, 0x57, + 0x3d, 0x57, 0x0d, 0x57, 0x2d, 0x57, 0x7d, 0x57, + 0x2d, 0x52, 0x3d, 0x50, 0x0d, 0x50, 0x3c, 0x50, + 0x05, 0x50, 0x2d, 0xae, 0x2c, 0xae, 0x2f, 0xae, + 0x2e, 0xae, 0x2f, 0xae, 0x29, 0xae, 0x2f, 0xae, + 0x29, 0xae, 0x1d, 0x54, 0x3d, 0x54, 0x0d, 0x54, + 0x2d, 0x54, 0x7d, 0x54, 0x2e, 0x52, 0x35, 0x50, + 0x1d, 0x50, 0x34, 0x50, 0x15, 0x50, 0x29, 0xae, + 0x28, 0xae, 0x2b, 0xae, 0x2a, 0xae, 0x2e, 0xae, + 0x28, 0xae, 0x2e, 0xae, 0x28, 0xae, 0x3a, 0xb0, + 0xf6, 0xb3, 0xf3, 0xb3, 0xcd, 0xb3, 0xcf, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, + 0xe0, 0xb3, 0xe0, 0xb3, 0xe0, 0xb3, 0xc9, 0xb3, + 0xcb, 0xb3, 0xc5, 0xb3, 0xc7, 0xb3, 0xc1, 0xb3, + 0xc3, 0xb3, 0xdd, 0xb3, 0xdf, 0xb3, 0xd9, 0xb3, + 0xdb, 0xb3, 0xd5, 0xb3, 0xd7, 0xb3, 0xd1, 0xb3, + 0xd3, 0xb3, 0x2d, 0xb0, 0x03, 0xae, 0x03, 0xae, + 0x02, 0xae, 0x46, 0xae, 0x48, 0xae, 0x5f, 0xae, + 0x43, 0xae, 0x48, 0xae, 0x41, 0xae, 0x02, 0xae, + 0x5e, 0xae, 0x54, 0xae, 0x5e, 0xae, 0x59, 0xae, + 0x4c, 0xae, 0x5e, 0xae, 0x46, 0xae, 0x02, 0xae, + 0x59, 0xae, 0x44, 0xae, 0x40, 0xae, 0x48, 0xae, + 0x5f, 0xae, 0x03, 0xae, 0x4e, 0xae, 0x2d, 0xae, + 0x44, 0xae, 0x5e, 0xae, 0x44, 0xae, 0x4a, 0xae, + 0x72, 0xae, 0x59, 0xae, 0x44, 0xae, 0x40, 0xae, + 0x05, 0xae, 0x04, 0xae, 0x2d, 0xae, 0xe2, 0x61, + 0x27, 0xae, 0x2f, 0xae, 0x2d, 0xae, 0x1b, 0x9e, + 0x2d, 0xae, 0x49, 0xae, 0x1d, 0xaf, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x0d, 0x8e, + 0x2c, 0xae, 0xa1, 0xae, 0xb9, 0xaf, 0x2d, 0xae, + 0x59, 0x9d, 0x2d, 0xae, 0x2c, 0xae, 0xc3, 0xb1, + 0x2c, 0xae, 0xa1, 0xae, 0x0d, 0xac, 0x2d, 0xae, + 0x59, 0x9d, 0x2d, 0xae, 0x2d, 0xae, 0x8b, 0x85, + 0x2f, 0xae, 0x55, 0xae, 0x81, 0xac, 0x2d, 0xae, + 0x73, 0x9d, 0x2d, 0xae, 0x2c, 0xae, 0x41, 0x85, + 0x2f, 0xae, 0x55, 0xae, 0x09, 0xad, 0x2d, 0xae, + 0x73, 0x9d, 0x2d, 0xae, 0x2d, 0xae, 0x61, 0x8d, + 0x2e, 0xae, 0x49, 0xae, 0xb1, 0xad, 0x2d, 0xae, + 0x65, 0x9d, 0x2d, 0xae, 0x2c, 0xae, 0x47, 0x8c, + 0x2e, 0xae, 0x49, 0xae, 0x2d, 0xaa, 0x2d, 0xae, + 0x65, 0x9d, 0x2d, 0xae, 0x2f, 0xae, 0x99, 0x8f, + 0x2e, 0xae, 0x49, 0xae, 0x49, 0xaa, 0x2d, 0xae, + 0x65, 0x9d, 0x2d, 0xae, 0x2e, 0xae, 0xdd, 0x8e, + 0x2e, 0xae, 0x49, 0xae, 0xe5, 0xaa, 0x2d, 0xae, + 0x65, 0x9d, 0x2d, 0xae, 0x29, 0xae, 0x7f, 0x8e, + 0x2e, 0xae, 0x49, 0xae, 0x01, 0xab, 0x2d, 0xae, + 0x65, 0x9d, 0x2c, 0xae, 0x2f, 0xae, 0x2e, 0xae, + 0x29, 0xae, 0x28, 0xae, 0x2b, 0xae, 0x2a, 0xae, + 0x25, 0xae, 0x24, 0xae, 0x27, 0xae, 0x2d, 0xae, + 0x21, 0xae, 0x29, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x29, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0xab, 0x9e, + 0x2c, 0xae, 0x2d, 0xae, 0x2d, 0xae, 0x2c, 0xae, + 0xbf, 0x9e, 0x2c, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0xf1, 0x9f, 0x2c, 0xae, 0x2d, 0xae, + 0x2d, 0xae, 0x2c, 0xae, 0xe3, 0x9f, 0x2c, 0xae, + 0x2d, 0xae, 0x2b, 0xae, 0x2d, 0xae, 0x2d, 0xae, + 0x41, 0x8b, 0x2c, 0xae, 0x2d, 0xae, 0x15, 0x8b, + 0x20, 0xae, 0x2d, 0xae, 0x25, 0x8a, 0x2f, 0xae, + 0x2d, 0xae, 0xd5, 0x8a, 0x2e, 0xae, 0x2d, 0xae, + 0x57, 0x8a, 0x29, 0xae, 0x2d, 0xae, 0xb7, 0x9d, + 0x2d, 0xae, 0x2d, 0x61, 0x4a, 0xeb, 0x0e, 0xaf, +}; + +#endif /* _MCCDSPOS_H */
On Wed, Jan 16, 2013 at 05:29:48PM +0900, Yoichi Yuasa wrote:
+static const unsigned char mc_cdsp_os[] = {
- 0xe3, 0x33, /* program size */
- 0x2c, 0x01, /* data size */
- /* program */
- 0x2d, 0x61, 0xaa, 0xae, 0x2d, 0x61, 0x2d, 0x61,
This is a firmware blob, it is totally unsuitable for inclusion in the kernel. You should load it with request_firmware().
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mccdspdrv.c | 5119 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mccdspdrv.h | 57 + 3 files changed, 5178 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mccdspdrv.c create mode 100644 sound/soc/codecs/ymu831/mccdspdrv.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index e74a60f..b42881e 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -1,4 +1,5 @@ snd-soc-ymu831-objs := \ - mcbdspdrv.o + mcbdspdrv.o \ + mccdspdrv.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mccdspdrv.c b/sound/soc/codecs/ymu831/mccdspdrv.c new file mode 100644 index 0000000..c1c9e83 --- /dev/null +++ b/sound/soc/codecs/ymu831/mccdspdrv.c @@ -0,0 +1,5119 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mccdspdrv.c + * Description : MC C-DSP driver + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/types.h> + +#include <asm/byteorder.h> + +#include "mccdspdrv.h" +#include "mccdspos.h" +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcresctrl.h" + +#undef LOW_BYTE +#define LOW_BYTE(w) ((u8)((u16)(w) & 0xff)) + +#undef HIGH_BYTE +#define HIGH_BYTE(w) ((u8)((u16)(w) >> 8)) + +#undef MAKE_HALFWORD +#define MAKE_HALFWORD(l, h) (((u16)(l) & 0xff) | (((u16)(h) & 0xff) << 8)) + +#define CODER_DEC 0 /* FuncA */ +#define CODER_ENC 1 /* FuncB */ + +/* state */ +#define STATE_NOTINIT 0 +#define STATE_INIT 1 +#define STATE_READY_SETUP 2 +#define STATE_READY 3 +#define STATE_PLAYING 4 + +/* call back */ + +#define CALLBACK_HOSTCOMMAND 0 /* Host command */ +#define CALLBACK_END_OF_SEQUENCE 1 /* End */ +#define CALLBACK_DFIFOPOINT 2 /* DEC_FIFO IRQ point */ +#define CALLBACK_RFIFOPOINT 3 /* REC_FIFO IRQ point */ +#define CALLBACK_DFIFOEMPTY 4 /* DEC_FIFO empty */ +#define CALLBACK_RECBUF_OVF 5 /* Record buffer over flow */ +#define CALLBACK_TIMER 6 /* Timer */ +#define CALLBACK_PLAY_ERROR1 7 /* Play error */ +#define CALLBACK_PLAY_ERROR2 8 /* Play error */ +#define CALLBACK_HW_ERROR 9 /* Hardware error */ +#define CALLBACK_COUNT 10 + +/* callback position */ +#define CBPOS_DFIFO_NONE -1 +#define CBPOS_DFIFO_DEF 2048 +#define CBPOS_DFIFO_MIN 0 +#define CBPOS_DFIFO_MAX 4096 + +#define CBPOS_RFIFO_NONE -1 +#define CBPOS_RFIFO_DEF 2048 +#define CBPOS_RFIFO_MIN 0 +#define CBPOS_RFIFO_MAX 4096 + +/* Program parameter */ +#define PRG_DESC_VENDER_ID 0 +#define PRG_DESC_FUNCTION_ID 2 +#define PRG_DESC_PRG_TYPE 4 +#define PRG_DESC_OUTPUT_TYPE 6 +#define PRG_DESC_PRG_SCRAMBLE 8 +#define PRG_DESC_DATA_SCRAMBLE 10 +#define PRG_DESC_ENTRY_ADR 12 +#define PRG_DESC_PRG_LOAD_ADR 14 +#define PRG_DESC_PRG_SIZE 16 +#define PRG_DESC_DATA_LOAD_ADR 18 +#define PRG_DESC_DATA_SIZE 20 +#define PRG_DESC_WORK_BEGIN_ADR 22 +#define PRG_DESC_WORK_SIZE 24 +#define PRG_DESC_STACK_BEGIN_ADR 26 +#define PRG_DESC_STACK_SIZE 28 +#define PRG_DESC_OUTSTARTMODE 30 +#define PRG_DESC_RESOURCE_FLAG 32 +#define PRG_DESC_MAX_LOAD 34 +#define PRG_DESC_PROGRAM 36 + +/* Program data parameter */ +#define PRG_PRM_TYPE_TASK0 0x0001 +#define PRG_PRM_TYPE_TASK1 0x0002 +#define PRG_PRM_SCRMBL_DISABLE 0x0000 +#define PRG_PRM_SCRMBL_ENABLE 0x0001 +#define PRG_PRM_IOTYPE_IN_MASK 0xff00 +#define PRG_PRM_IOTYPE_IN_PCM 0x0000 +#define PRG_PRM_IOTYPE_IN_NOPCM 0x0100 +#define PRG_PRM_IOTYPE_OUT_MASK 0x00ff +#define PRG_PRM_IOTYPE_OUT_PCM 0x0000 +#define PRG_PRM_IOTYPE_OUT_NOPCM 0x0001 + +/* OS parameter */ +#define ADR_OS_PROG_L 0x00 +#define ADR_OS_PROG_H 0x00 +#define ADR_OS_DATA_L 0x00 +#define ADR_OS_DATA_H 0x00 + +/* CDSP MSEL */ +#define MSEL_PROG 0x00 +#define MSEL_DATA 0x01 + +/* FIFO size */ +#define FIFOSIZE_DFIFO 4096 +#define FIFOSIZE_OFIFO 8192 +#define FIFOSIZE_EFIFO 8192 +#define FIFOSIZE_RFIFO 4096 +#define FIFOSIZE_FFIFO 1024 + +#define DFIFO_DUMMY_SPACE 2 + +/* FIFO ID */ +#define FIFO_NONE 0x00000000L +#define FIFO_DFIFO_MASK 0x000000ffL +#define FIFO_DFIFO 0x00000001L +#define FIFO_EFIFO_MASK 0x0000ff00L +#define FIFO_EFIFO 0x00000100L +#define FIFO_OFIFO_MASK 0x00ff0000L +#define FIFO_OFIFO 0x00010000L +#define FIFO_RFIFO_MASK 0xff000000L +#define FIFO_RFIFO 0x01000000L + +#define PORT_SEL_NONE 0 +#define PORT_SEL_NORMAL 1 +#define PORT_SEL_REF 2 + +#define RFIFO_CH_NUM 2 +#define RFIFO_BIT_WIDTH 16 + +/* format */ +#define CODER_FMT_FS_48000 0 +#define CODER_FMT_FS_44100 1 +#define CODER_FMT_FS_32000 2 +#define CODER_FMT_FS_24000 4 +#define CODER_FMT_FS_22050 5 +#define CODER_FMT_FS_16000 6 +#define CODER_FMT_FS_12000 8 +#define CODER_FMT_FS_11025 9 +#define CODER_FMT_FS_8000 10 + +#define CODER_FMT_ETOBUF_LRMIX 0 +#define CODER_FMT_ETOBUF_LCH 1 +#define CODER_FMT_ETOBUF_RCH 2 + +#define CODER_FMT_BUFTOO_NONE 0 +#define CODER_FMT_BUFTOO_CONV 1 + +/* InputDataEnd Command */ +#define INPUTDATAEND_EMPTY 0 +#define INPUTDATAEND_WRITE 1 + +/* TimerReste Command */ +#define TIMERRESET_RESET 0 +#define TIMERRESET_OFF 1 + +/* dual mono */ +#define CODER_DUALMONO_LR 0 +#define CODER_DUALMONO_L 1 +#define CODER_DUALMONO_R 2 + +/* Fs */ +#define OUTPUT_FS_8000 8000 +#define OUTPUT_FS_11025 11025 +#define OUTPUT_FS_12000 12000 +#define OUTPUT_FS_16000 16000 +#define OUTPUT_FS_22050 22050 +#define OUTPUT_FS_24000 24000 +#define OUTPUT_FS_32000 32000 +#define OUTPUT_FS_44100 44100 +#define OUTPUT_FS_48000 48000 +#define OUTPUT_FS_MIN OUTPUT_FS_8000 +#define OUTPUT_FS_MAX OUTPUT_FS_48000 +#define OUTPUT_FS_DEF OUTPUT_FS_48000 + +/* Start Sample */ +#define OFIFO_BUF_SAMPLE_MIN 0 +#define OFIFO_BUF_SAMPLE_MAX 1024 +#define OFIFO_BUF_SAMPLE_DEF 500 + +#define RFIFO_BUF_SAMPLE_MIN 0 +#define RFIFO_BUF_SAMPLE_MAX 512 +#define RFIFO_BUF_SAMPLE_DEF 500 + +/* Stop: verify stop completion */ +#define MADEVCDSP_VERIFY_COMP_OFF 0 +#define MADEVCDSP_VERIFY_COMP_ON 1 + +/* EVT */ +#define EVENT_TIMER 0x01 +#define EVENT_CLEAR 0x00 + +/* Error code: CDSP */ +#define CDSP_ERR_NO_ERROR 0x0000 +#define CDSP_ERR_MEM_PROTECTION 0xfff1 +#define CDSP_ERR_WDT 0xfff2 +#define CDSP_ERR_PROG_DOWNLOAD 0xffff + +/* Error code: DEC/ENC */ +#define DEC_ERR_NO_ERROR 0x00 +#define DEC_ERR_PROG_SPECIFIC_MIN 0x01 +#define DEC_ERR_PROG_SPECIFIC_MAX 0xef +#define DEC_ERR_NOT_READY 0xf0 +#define DEC_ERR_MEM_PROTECTION 0xf1 +#define DEC_ERR_WDT 0xf2 + +/* c-dsp chunk */ +#define CHUNK_SIZE 8 + +#define CDSP_FUNC_NUMBER 0 + +#define AEC_CDSP_TAG_PROG 0x00001000 +#define PROG_FIX_SIZE 4 +#define AEC_CDSP_TAG_PRM 0x00001100 +#define PRM_FIX_SIZE 4 +#define PRM_UNIT_SIZE 17 +#define AEC_CDSP_TAG_FIFO 0x00001200 +#define FIFO_FIX_SIZE 26 +#define AEC_CDSP_TAG_EXT 0x00001300 +#define EXT_FIX_SIZE 5 + +#define ROUTE_OUT0L_SEL 0 +#define ROUTE_OUT0R_SEL 1 +#define ROUTE_OUT1L_SEL 2 +#define ROUTE_OUT1R_SEL 3 +#define ROUTE_OUT2L_SEL 4 +#define ROUTE_OUT2R_SEL 5 +#define ROUTE_EFIFO0_SEL 6 +#define ROUTE_EFIFO1_SEL 7 +#define ROUTE_EFIFO2_SEL 8 +#define ROUTE_EFIFO3_SEL 9 +#define CDSP_EFIFO_CH 10 +#define CDSP_EFIFO_BIT_WIDTH 11 +#define CDSP_EFIFO_E2BUF_MODE 12 +#define CDSP_OFIFO_CH 13 +#define CDSP_OFIFO_BIT_WIDTH 14 +#define CDSP_DFIFO_BIT_WIDTH 15 +#define CDSP_RFIFO_BIT_WIDTH 16 +#define CDSP_USE_FIFO 17 +#define CDSP_DFIFO_CB_POINT 18 /* 2Byte */ +#define CDSP_RFIFO_CB_POINT 20 /* 2Byte */ +#define CDSP_OFIFO_BUFFERING 22 /* 2Byte */ +#define CDSP_RFIFO_BUFFERING 24 /* 2Byte */ + +#define OUT_LOOPBACK_L 4 +#define OUT_LOOPBACK_R 5 + +#define CDSP_FIFO_MASK 0x0f +#define CDSP_FIFO_EFIFO_BIT 0x01 +#define CDSP_FIFO_OFIFO_BIT 0x02 +#define CDSP_FIFO_DFIFO_BIT 0x04 +#define CDSP_FIFO_RFIFO_BIT 0x08 +#define CDSP_FIFO_OTHER_MASK 0xf0 +#define CDSP_FIFO_OTHER_OUTBUF_BIT 0x10 +#define CDSP_FIFO_OTHER_INBUF_BIT 0x20 + +#define CDSP_FIFO_DONTCARE 0xff +#define CDSP_FIFO_DONTCARE_W 0xffff +#define CDSP_FIFO_DONTCARE_CB 0xfffe +#define CDSP_FIFO_NOT_CB 0xffff + +#define CDSP_PRM_CMD 0 +#define CDSP_PRM_PRM0 1 + +#define AEC_FUNC_INFO_A 0 +#define AEC_FUNC_INFO_B 1 +#define AEC_FUNC_INFO_NUM 2 + +#define EXT_COMMAND 0 +#define EXT_COMMAND_CLEAR 1 + +/* Command (Host -> OS) */ +#define CDSP_CMD_HOST2OS_CMN_NONE 0x00 +#define CDSP_CMD_HOST2OS_CMN_RESET 0x01 +#define CDSP_CMD_HOST2OS_CMN_CLEAR 0x02 +#define CDSP_CMD_HOST2OS_CMN_STANDBY 0x03 +#define CDSP_CMD_HOST2OS_CMN_GET_PRG_VER 0x04 +#define CDSP_CMD_HOST2OS_SYS_GET_OS_VER 0x20 +#define CDSP_CMD_HOST2OS_SYS_SET_PRG_INFO 0x21 +#define CDSP_CMD_HOST2OS_SYS_SET_FORMAT 0x22 +#define CDSP_CMD_HOST2OS_SYS_SET_CONNECTION 0x23 +#define CDSP_CMD_HOST2OS_SYS_VERIFY_STOP_COMP 0x24 +#define CDSP_CMD_HOST2OS_SYS_INPUT_DATA_END 0x25 +#define CDSP_CMD_HOST2OS_SYS_CLEAR_INPUT_DATA_END 0x26 +#define CDSP_CMD_HOST2OS_SYS_SET_TIMER 0x27 +#define CDSP_CMD_HOST2OS_SYS_TIMER_RESET 0x28 +#define CDSP_CMD_HOST2OS_SYS_TERMINATE 0x29 +#define CDSP_CMD_HOST2OS_SYS_SET_DUAL_MONO 0x2a +#define CDSP_CMD_HOST2OS_SYS_GET_INPUT_POS 0x2b +#define CDSP_CMD_HOST2OS_SYS_RESET_INPUT_POS 0x2c +#define CDSP_CMD_HOST2OS_SYS_HALT 0x2d +#define CDSP_CMD_HOST2OS_SYS_SET_CLOCK_SOURCE 0x2e +#define CDSP_CMD_DRV_SYS_SET_CONNECTION_EX 0x3e +#define CDSP_CMD_DRV_SYS_SET_BIT_WIDTH 0x3f +#define CDSP_CMD_HOST2OS_PRG_MIN 0x40 +#define CDSP_CMD_HOST2OS_PRG_MAX 0x6f + +/* Command (OS -> Host) */ +#define CDSP_CMD_OS2HOST_CMN_NONE 0x00 +#define CDSP_CMD_OS2HOST_CMN_MIN 0x01 +#define CDSP_CMD_OS2HOST_CMN_MAX 0x3f +#define CDSP_CMD_OS2HOST_PRG_MIN 0x40 +#define CDSP_CMD_OS2HOST_PRG_MAX 0x6f +#define CDSP_CMD_OS2HOST_DISABLE_MIN 0x70 +#define CDSP_CMD_OS2HOST_DISABLE_MAX 0x7f +#define CDSP_CMD_OS2HOST_READY_MIN 0x80 +#define CDSP_CMD_OS2HOST_READY_MAX 0xff +#define CDSP_CMD_OS2HOST_CMN_NOTIFY_OUT_FORMAT 0x01 + +/* Command parameter */ +#define CDSP_CMD_PARAM_ARGUMENT_00 0 +#define CDSP_CMD_PARAM_ARGUMENT_01 1 +#define CDSP_CMD_PARAM_ARGUMENT_02 2 +#define CDSP_CMD_PARAM_ARGUMENT_03 3 +#define CDSP_CMD_PARAM_ARGUMENT_04 4 +#define CDSP_CMD_PARAM_ARGUMENT_05 5 +#define CDSP_CMD_PARAM_ARGUMENT_06 6 +#define CDSP_CMD_PARAM_ARGUMENT_07 7 +#define CDSP_CMD_PARAM_ARGUMENT_08 8 +#define CDSP_CMD_PARAM_ARGUMENT_09 9 +#define CDSP_CMD_PARAM_ARGUMENT_10 10 +#define CDSP_CMD_PARAM_ARGUMENT_11 11 +#define CDSP_CMD_PARAM_ARGUMENT_NUM 12 +#define CDSP_CMD_PARAM_RESULT_00 12 +#define CDSP_CMD_PARAM_RESULT_01 13 +#define CDSP_CMD_PARAM_RESULT_02 14 +#define CDSP_CMD_PARAM_RESULT_03 15 +#define CDSP_CMD_PARAM_RESULT_NUM 4 +#define CDSP_CMD_PARAM_NUM \ + (CDSP_CMD_PARAM_ARGUMENT_NUM + CDSP_CMD_PARAM_RESULT_NUM) + +/* Command Completion */ +#define CDSP_CMD_COMPLETION 0x80 + +/* Connect FIFO */ +#define CDSP_IN_SOURCE_DFIFO 0 +#define CDSP_IN_SOURCE_EFIFO 1 +#define CDSP_IN_SOURCE_OTHER_OUTBUF 2 +#define CDSP_IN_SOURCE_NONE 3 +#define CDSP_IN_SOURCE_DFIFO_EFIFO 4 + +#define CDSP_OUT_DEST_OFIFO 0 +#define CDSP_OUT_DEST_RFIFO 1 +#define CDSP_OUT_DEST_OTHER_INBUF 2 +#define CDSP_OUT_DEST_NONE 3 +#define CDSP_OUT_DEST_OFIFO_RFIFO 4 + +struct coder_firmware { + u8 *firmware; + u32 size; +}; + +struct coder_version { + u32 id; + u16 prog_ver_h; + u16 prog_ver_m; + u16 prog_ver_l; + u16 os_ver_h; + u16 os_ver_m; + u16 os_ver_l; +}; + +struct fsq_data_info { + u8 *data; + u16 size; + u16 load_addr; + u16 scramble; + u8 msel; +}; + +struct fifo_info { + int dfifo_cb_pos; + int rfifo_cb_pos; + u32 ofifo_buf_sample; + bool ofifo_output_start; + u32 dfifo_write_size; + u32 rfifo_buf_sample; + bool rfifo_output_start; + + u8 out0_sel; + u8 out1_sel; + u8 out2_sel; + u8 rdfifo_bit_sel; + u8 efifo01_sel; + u8 efifo23_sel; +}; + +struct version_info { + u16 version_h; + u16 version_l; +}; + +struct callback_info { + bool on[CALLBACK_COUNT]; + u32 ex_info[CALLBACK_COUNT]; +}; + +struct program_info { + u16 vendor_id; + u16 function_id; + u16 prog_type; + u16 inout_type; + u16 prog_scramble; + u16 data_scramble; + u16 entry_addr; + u16 prog_loadaddr; + u16 prog_size; + u16 data_loadaddr; + u16 data_size; + u16 work_begin; + u16 work_size; + u16 stack_begin; + u16 stack_size; + u16 output_start_mode; + u16 resource_flag; + u16 max_load; +}; + +struct format_info { + u8 fs; + u8 etobuf; +}; + +struct connection_info { + u8 src; + u8 dest; +}; + +struct connection_ex_info { + u8 efifo_ch; + u8 ofifo_ch; +}; + +struct bit_width_info { + u8 efifo; + u8 ofifo; +}; + +struct coder_params { + u8 command; + u8 params[16]; +}; + +struct coder_info { + u8 state; + bool preinput_dataend_set; + bool input_dataend_set; + bool change_output_fs; + bool format_propagate; + u32 input_pos; + u8 error_code; + struct callback_info callback; + struct version_info program; + struct program_info prog_info; + struct format_info format; + struct connection_info conn_info; + struct connection_ex_info conn_ex_info; + struct bit_width_info bit_width; + struct coder_params coder; +}; + +struct cdsp_info { + u16 hw_error_code; + struct version_info os; +}; + +struct aec_cdsp_func_info { + enum mc_cdsp_id id; + bool func_on; + u8 *data; + u32 data_size; + u8 *fifo_data; + u8 *prog_data; + u32 prog_size; + u8 *param_data; + u32 param_num; + u8 *ext; + + struct format_info format; + struct connection_info conn_info; + struct connection_ex_info conn_ex_info; + struct bit_width_info bit_width; +}; + +struct aec_cdsp_info { + struct aec_cdsp_func_info func_info[AEC_FUNC_INFO_NUM]; + + int dfifo_cb_pos; + int rfifo_cb_pos; + u32 ofifo_buf_sample; + u32 rfifo_buf_sample; + u8 out0_sel; + u8 out1_sel; + u8 out2_sel; + u8 rdfifo_bit_sel; + u8 efifo01_sel; + u8 efifo23_sel; +}; + +static struct cdsp_info mc_cdsp_info = { + .hw_error_code = CDSP_ERR_NO_ERROR, +}; + +static struct fifo_info mc_fifo_info; + +static struct coder_info mc_dec_info = { + .state = STATE_NOTINIT, + .format = { + .fs = CODER_FMT_FS_48000, + .etobuf = CODER_FMT_ETOBUF_LRMIX, + }, + .conn_info = { + .src = CDSP_IN_SOURCE_NONE, + .dest = CDSP_OUT_DEST_NONE, + }, + .conn_ex_info = { + .efifo_ch = 2, + .ofifo_ch = 2, + }, + .bit_width = { + .efifo = 16, + .ofifo = 16, + }, +}; + +static struct coder_info mc_enc_info = { + .state = STATE_NOTINIT, + .format = { + .fs = CODER_FMT_FS_48000, + .etobuf = CODER_FMT_ETOBUF_LRMIX, + }, + .conn_info = { + .src = CDSP_IN_SOURCE_NONE, + .dest = CDSP_OUT_DEST_NONE, + }, + .conn_ex_info = { + .efifo_ch = 2, + .ofifo_ch = 2, + }, + .bit_width = { + .efifo = 16, + .ofifo = 16, + }, +}; + +static int cdsp_coder_start(enum mc_cdsp_id id); + +static void cdsp_registers_init(void) +{ + int i; + + mc_packet_add_force_write_c(MCI_CDSP_RESET, + MCB_CDSP_DMODE | MCB_CDSP_FSQ_SRST | + MCB_CDSP_SRST); + + /* Disable interrupt */ + mc_packet_add_force_write_c(MCI_DEC_ENABLE, 0); + mc_packet_add_force_write_c(MCI_ENC_ENABLE, 0); + mc_packet_add_force_write_c(MCI_DFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_OFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_EFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_FFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_CDSP_ENABLE, 0); + mc_packet_add_force_write_if(MCI_ECDSP, 0); + + /* Clear interrupt flag */ + mc_packet_add_force_write_c(MCI_DEC_FLG, MCB_DEC_FLG_ALL); + mc_packet_add_force_write_c(MCI_ENC_FLG, MCB_ENC_FLG_ALL); + mc_packet_add_force_write_c(MCI_DFIFO_FLG, MCB_DFIFO_FLG_ALL); + mc_packet_add_force_write_c(MCI_OFIFO_FLG, MCB_OFIFO_FLG_ALL); + mc_packet_add_force_write_c(MCI_EFIFO_FLG, MCB_EFIFO_FLG_ALL); + mc_packet_add_force_write_c(MCI_RFIFO_FLG, MCB_RFIFO_FLG_ALL); + mc_packet_add_force_write_c(MCI_FFIFO_FLG, MCB_FFIFO_FLG_ALL); + mc_packet_add_force_write_c(MCI_CDSP_FLG, MCB_CDSP_FLG_ALL); + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_CDSP_ALL); + + /* Other registers */ + mc_packet_add_force_write_c(MCI_DEC_START, 0); + mc_packet_add_force_write_c(MCI_DEC_START2, 0); + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, 0); + + mc_packet_add_force_write_c(MCI_PWM_DIGITAL_CDSP, 0); + + mc_packet_add_force_write_c(MCI_DEC_POS4, 0); + mc_packet_add_force_write_c(MCI_ENC_POS4, 0); + mc_packet_add_force_write_c(MCI_DFIFO_IRQ_PNT_H, 0); + mc_packet_add_force_write_c(MCI_DFIFO_IRQ_PNT_L, 0); + mc_packet_add_force_write_c(MCI_OFIFO_IRQ_PNT_H, 0); + mc_packet_add_force_write_c(MCI_OFIFO_IRQ_PNT_L, 0); + mc_packet_add_force_write_c(MCI_EFIFO_IRQ_PNT_H, 0); + mc_packet_add_force_write_c(MCI_EFIFO_IRQ_PNT_L, 0); + mc_packet_add_force_write_c(MCI_RFIFO_IRQ_PNT_H, 0); + mc_packet_add_force_write_c(MCI_RFIFO_IRQ_PNT_L, 0); + mc_packet_add_force_write_c(MCI_FFIFO_IRQ_PNT_H, 0); + mc_packet_add_force_write_c(MCI_FFIFO_IRQ_PNT_L, 0); + mc_packet_add_force_write_c(MCI_CDSP_MAR_H, 0); + mc_packet_add_force_write_c(MCI_CDSP_MAR_L, 0); + mc_packet_add_force_write_c(MCI_DEC_GPR_ENABLE, 0); + mc_packet_add_force_write_c(MCI_DEC_SFR1, 0); + mc_packet_add_force_write_c(MCI_DEC_SFR0, 0); + mc_packet_add_force_write_c(MCI_ENC_GPR_ENABLE, 0); + mc_packet_add_force_write_c(MCI_ENC_SFR1, 0); + mc_packet_add_force_write_c(MCI_ENC_SFR0, 0); + mc_packet_add_force_write_c(MCI_DEC_EVT, 0); + mc_packet_add_force_write_c(MCI_ENC_EVT, 0); + mc_packet_add_force_write_c(MCI_DEC_FIFO_CH, 0); + mc_packet_add_force_write_c(MCI_RDFIFO_BIT_SEL, 0); + mc_packet_add_force_write_c(MCI_OUT0_SEL, MCI_OUT0_SEL_DEF); + mc_packet_add_force_write_c(MCI_OUT1_SEL, MCI_OUT1_SEL_DEF); + mc_packet_add_force_write_c(MCI_OUT2_SEL, MCI_OUT2_SEL_DEF); + mc_packet_add_force_write_c(MCI_EFIFO01_SEL, MCI_EFIFO01_SEL_DEF); + mc_packet_add_force_write_c(MCI_EFIFO23_SEL, MCI_EFIFO23_SEL_DEF); + + for (i = 0; i < CDSP_CMD_PARAM_NUM; i++) { + mc_packet_add_force_write_c((MCI_DEC_GPR15 + i), 0); + mc_packet_add_force_write_c((MCI_ENC_GPR15 + i), 0); + mc_packet_add_force_write_c((MCI_DEC_CTL15 + i), 0); + mc_packet_add_force_write_c((MCI_ENC_CTL15 + i), 0); + } + + mc_packet_execute(); +} + +static inline void cdsp_os_download(const u8 *firmware) +{ + u8 data, msel[2]; + u8 addr_h[2], addr_l[2]; + u32 os_size[2], i, j; + const u8 *os_prog[2]; + + msel[0] = MCB_CDSP_MSEL_PROG; + addr_h[0] = ADR_OS_PROG_H; + addr_l[0] = ADR_OS_PROG_L; + os_size[0] = MAKE_HALFWORD(firmware[0], firmware[1]) * 2; + os_prog[0] = &firmware[4]; + + msel[1] = MCB_CDSP_MSEL_DATA; + addr_h[1] = ADR_OS_DATA_H; + addr_l[1] = ADR_OS_DATA_L; + os_size[1] = MAKE_HALFWORD(firmware[2], firmware[3]) * 2; + os_prog[1] = &os_prog[0][os_size[0]]; + + mc_read_c(MCI_CDSP_RESET, &data, 1); + + /* CDSP_SRST Set : CDSP OS stop */ + data &= ~MCB_CDSP_FMODE; + data |= MCB_CDSP_SRST; + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + + /* Program & Data Write */ + for (i = 0; i < 2; i++) { + /* CDSP_MSEL Set */ + data &= ~MCB_CDSP_MSEL; + data |= msel[i]; + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + + /* CDSP_MAR Set */ + mc_packet_add_force_write_c(MCI_CDSP_MAR_H, addr_h[i]); + mc_packet_add_force_write_c(MCI_CDSP_MAR_L, addr_l[i]); + + mc_packet_execute(); + + /* FSQ_FIFO Write */ + for (j = 0; j < os_size[i]; ++j) + mc_packet_add_force_write_if(MCI_FSQ_FFIFO, + os_prog[i][j]); + + mc_packet_execute(); + + } + + /* CDSP_SRST Release : CDSP OS start */ + data &= ~MCB_CDSP_SRST; + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + /* 100 ns wait */ + mc_packet_add_wait(1); + + mc_packet_execute(); +} + +static void cdsp_command_write_complete(enum mc_cdsp_id id, + struct coder_params *coder) +{ + u32 sfr, ctl, base, i; + + if (id == CDSP_DECODER) { + sfr = MCI_DEC_SFR1; + ctl = MCI_DEC_CTL0; + } else { + sfr = MCI_ENC_SFR1; + ctl = MCI_ENC_CTL0; + } + + /* Write result */ + base = CDSP_CMD_PARAM_RESULT_00; + for (i = base; i < base + CDSP_CMD_PARAM_RESULT_NUM; i++) + mc_packet_add_write_c(ctl - i, coder->params[i]); + + /* Write complete command */ + mc_packet_add_force_write_c(sfr, coder->command | CDSP_CMD_COMPLETION); + + mc_packet_execute(); +} + +static int cdsp_command_wait_complete(enum mc_cdsp_id id) +{ + u32 sfr; + int ret; + + if (id == CDSP_DECODER) + sfr = MCI_DEC_SFR0; + else + sfr = MCI_ENC_SFR0; + + /* Polling */ + mc_packet_add_wait_event(MCDRV_EVT_C_REG_FLAG_SET | (sfr << 8) | + CDSP_CMD_COMPLETION); + + ret = mc_packet_execute(); + if (ret < 0) { + /* Time out */ + mc_packet_add_force_write_c(sfr, CDSP_CMD_COMPLETION); + + mc_packet_execute(); + } + + return ret; +} + +static int cdsp_command_init(enum mc_cdsp_id id) +{ + struct coder_params coder; + + coder.command = CDSP_CMD_OS2HOST_CMN_NONE; + coder.params[CDSP_CMD_PARAM_RESULT_00] = 0; + coder.params[CDSP_CMD_PARAM_RESULT_01] = 0; + coder.params[CDSP_CMD_PARAM_RESULT_02] = 0; + coder.params[CDSP_CMD_PARAM_RESULT_03] = 0; + + cdsp_command_write_complete(id, &coder); + + return cdsp_command_wait_complete(id); +} + +static int cdsp_command_write_host2os(enum mc_cdsp_id id, + struct coder_params *coder) +{ + u32 sfr, ctl, gpr; + u8 data; + int count, i, ret; + + if (id == CDSP_DECODER) { + sfr = MCI_DEC_SFR0; + ctl = MCI_DEC_CTL0; + gpr = MCI_DEC_GPR0; + } else { + sfr = MCI_ENC_SFR0; + ctl = MCI_ENC_CTL0; + gpr = MCI_ENC_GPR0; + } + + /* Polling */ + ret = cdsp_command_wait_complete(id); + if (ret < 0) + return ret; + + /* Write parameter */ + switch (coder->command) { + case CDSP_CMD_HOST2OS_CMN_NONE: + case CDSP_CMD_HOST2OS_CMN_RESET: + case CDSP_CMD_HOST2OS_CMN_CLEAR: + case CDSP_CMD_HOST2OS_CMN_STANDBY: + case CDSP_CMD_HOST2OS_CMN_GET_PRG_VER: + case CDSP_CMD_HOST2OS_SYS_GET_OS_VER: + case CDSP_CMD_HOST2OS_SYS_VERIFY_STOP_COMP: + case CDSP_CMD_HOST2OS_SYS_CLEAR_INPUT_DATA_END: + case CDSP_CMD_HOST2OS_SYS_TERMINATE: + case CDSP_CMD_HOST2OS_SYS_GET_INPUT_POS: + case CDSP_CMD_HOST2OS_SYS_RESET_INPUT_POS: + case CDSP_CMD_HOST2OS_SYS_HALT: + count = 0; + break; + case CDSP_CMD_HOST2OS_SYS_INPUT_DATA_END: + case CDSP_CMD_HOST2OS_SYS_TIMER_RESET: + case CDSP_CMD_HOST2OS_SYS_SET_DUAL_MONO: + case CDSP_CMD_HOST2OS_SYS_SET_CLOCK_SOURCE: + count = 1; + break; + case CDSP_CMD_HOST2OS_SYS_SET_PRG_INFO: + count = 11; + break; + case CDSP_CMD_HOST2OS_SYS_SET_FORMAT: + count = 2; + break; + case CDSP_CMD_HOST2OS_SYS_SET_CONNECTION: + count = 2; + break; + case CDSP_CMD_HOST2OS_SYS_SET_TIMER: + count = 4; + break; + default: + /* Program dependence command */ + count = CDSP_CMD_PARAM_ARGUMENT_NUM; + break; + } + + for (i = 0; i < count; i++) + mc_packet_add_write_c(ctl - i, coder->params[i]); + + /* Write command */ + mc_packet_add_force_write_c(sfr, coder->command); + + mc_packet_execute(); + + /* Polling */ + ret = cdsp_command_wait_complete(id); + if (ret < 0) + return ret; + + /* Error check */ + mc_read_c(sfr, &data, 1); + if (data >= 0xF0) { + if (data == 0xF7) + return -EBUSY; + if (data >= 0xF3 && data <= 0xF6) + return -EINVAL; + return -EIO; + } + + /* Get result */ + count = CDSP_CMD_PARAM_RESULT_00; + for (i = count; i < count + CDSP_CMD_PARAM_RESULT_NUM; i++) { + mc_read_c((gpr - i), &data, 1); + coder->params[i] = data; + } + + return data; +} + +static int cdsp_os_init(void) +{ + struct coder_params coder; + int ret; + + /* CDSP_ERR/WDT_FLG Flag clear */ + mc_packet_add_force_write_c(MCI_CDSP_FLG, MCB_CDSP_FLG_ALL); + + /* IRQ Flag clear */ + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_CDSP_ALL); + + /* ECDSP_ERR/WDT Enable */ + mc_packet_add_force_write_c(MCI_CDSP_ENABLE, MCB_CDSP_ENABLE_ALL); + + /* IRQ: ECDSP=Enable, other=Disable */ + mc_packet_add_force_write_if(MCI_ECDSP, MCB_ECDSP); + + mc_packet_execute(); + + /* Command register Initialize */ + ret = cdsp_command_init(CODER_DEC); + if (ret < 0) + return ret; + + ret = cdsp_command_init(CODER_ENC); + if (ret < 0) + return ret; + + /* READY Polling */ + mc_packet_add_wait_event(MCDRV_EVT_C_REG_FLAG_SET | + (MCI_CDSP_POWER_MODE << 8) | MCB_CDSP_SLEEP); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* GetOsVersion command */ + coder.command = CDSP_CMD_HOST2OS_SYS_GET_OS_VER; + ret = cdsp_command_write_host2os(CODER_DEC, &coder); + if (ret < 0) + return ret; + + mc_cdsp_info.os.version_h = + MAKE_HALFWORD(coder.params[CDSP_CMD_PARAM_RESULT_00], + coder.params[CDSP_CMD_PARAM_RESULT_01]); + mc_cdsp_info.os.version_l = + MAKE_HALFWORD(coder.params[CDSP_CMD_PARAM_RESULT_02], + coder.params[CDSP_CMD_PARAM_RESULT_03]); + + return 0; +} + +static void cdsp_coder_info_init(struct coder_info *info) +{ + memset(info, 0, sizeof(struct coder_info)); + + info->state = STATE_INIT; + + info->prog_info.inout_type = + PRG_PRM_IOTYPE_IN_PCM | PRG_PRM_IOTYPE_OUT_PCM; + + info->format.fs = CODER_FMT_FS_48000; + info->format.etobuf = CODER_FMT_ETOBUF_LRMIX; + + info->conn_info.src = CDSP_IN_SOURCE_NONE; + info->conn_info.dest = CDSP_OUT_DEST_NONE; + + info->conn_ex_info.efifo_ch = 2; + info->conn_ex_info.ofifo_ch = 2; + + info->bit_width.efifo = 16; + info->bit_width.ofifo = 16; +} + +static inline struct coder_info *cdsp_coder_info_get(enum mc_cdsp_id id) +{ + if (id == CDSP_DECODER) + return &mc_dec_info; + + return &mc_enc_info; +} + +static inline enum mc_cdsp_id cdsp_another_id_get(enum mc_cdsp_id id) +{ + if (id == CDSP_DECODER) + return CDSP_ENCODER; + + return CDSP_DECODER; +} + +static void cdsp_command_read_os2host(enum mc_cdsp_id id, + struct coder_params *coder) +{ + u32 sfr, gpr, count, i; + u8 data; + + if (id == CDSP_DECODER) { + sfr = MCI_DEC_SFR1; + gpr = MCI_DEC_GPR0; + } else { + sfr = MCI_ENC_SFR1; + gpr = MCI_ENC_GPR0; + } + + mc_read_c(sfr, &data, 1); + + coder->command = data; + switch (coder->command) { + case CDSP_CMD_OS2HOST_CMN_NONE: + count = 0; + break; + case CDSP_CMD_OS2HOST_CMN_NOTIFY_OUT_FORMAT: + count = 4; + break; + default: + /* Program dependence command */ + count = CDSP_CMD_PARAM_ARGUMENT_NUM; + break; + } + + for (i = 0; i < count; i++) { + mc_read_c((gpr - i), &data, 1); + coder->params[i] = data; + } +} + +static int cdsp_command_inputdataend(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + u8 src, dest; + + info = cdsp_coder_info_get(id); + + src = info->conn_info.src; + if (src == CDSP_IN_SOURCE_DFIFO || src == CDSP_IN_SOURCE_DFIFO_EFIFO) { + if (mc_fifo_info.dfifo_write_size & 0x01) { + mc_packet_add_force_write_if(MCI_DEC_FIFO, 0); + + mc_fifo_info.dfifo_write_size = 0; + } + } + + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = INPUTDATAEND_EMPTY; + + dest = info->conn_info.dest; + if ((mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST) && + (dest == CDSP_OUT_DEST_RFIFO || dest == CDSP_OUT_DEST_OFIFO_RFIFO)) + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = INPUTDATAEND_WRITE; + + /* InputDataEnd command */ + coder.command = CDSP_CMD_HOST2OS_SYS_INPUT_DATA_END; + + return cdsp_command_write_host2os(id, &coder); +} + +static void cdsp_ofifo_start_real(void) +{ + u8 data; + + mc_read_c(MCI_DEC_START, &data, 1); + data |= MCB_DEC_OUT_START; + mc_packet_add_write_c(MCI_DEC_START, data); + + mc_packet_execute(); +} + +static void cdsp_rfifo_start_real(void) +{ + u8 data; + + mc_read_c(MCI_DEC_START2, &data, 1); + data |= MCB_RFIFO_START; + mc_packet_add_write_c(MCI_DEC_START2, data); + + mc_packet_execute(); +} + +static u32 cdsp_fifoid_get(struct connection_info *conn_info) +{ + u32 id = 0; + + switch (conn_info->src) { + case CDSP_IN_SOURCE_DFIFO: + id |= FIFO_DFIFO; + break; + case CDSP_IN_SOURCE_EFIFO: + id |= FIFO_EFIFO; + break; + case CDSP_IN_SOURCE_DFIFO_EFIFO: + id |= FIFO_DFIFO | FIFO_EFIFO; + break; + default: + break; + } + + switch (conn_info->dest) { + case CDSP_OUT_DEST_OFIFO: + id |= FIFO_OFIFO; + break; + case CDSP_OUT_DEST_RFIFO: + id |= FIFO_RFIFO; + break; + case CDSP_OUT_DEST_OFIFO_RFIFO: + id |= FIFO_OFIFO | FIFO_RFIFO; + break; + default: + break; + } + + return id; +} + +static u32 cdsp_fifoid_get_from_coderid(enum mc_cdsp_id id) +{ + struct coder_info *info; + + info = cdsp_coder_info_get(id); + + return cdsp_fifoid_get(&info->conn_info); +} + +static inline void cdsp_output_format_notify_os2host(enum mc_cdsp_id id) +{ + struct coder_info *info, *another_info; + enum mc_cdsp_id another_id; + u32 fifo_id, another_fifo_id; + + info = cdsp_coder_info_get(id); + + another_id = cdsp_another_id_get(id); + another_info = cdsp_coder_info_get(another_id); + + info->format.fs = info->coder.params[CDSP_CMD_PARAM_ARGUMENT_00]; + + another_fifo_id = 0; + if (info->conn_info.dest == CDSP_OUT_DEST_OTHER_INBUF) { + fifo_id = cdsp_fifoid_get(&another_info->conn_info); + if (fifo_id & FIFO_OFIFO_MASK) + another_fifo_id |= FIFO_OFIFO; + if ((fifo_id & FIFO_RFIFO_MASK) && + !(mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST)) + another_fifo_id |= FIFO_RFIFO; + } else { + fifo_id = cdsp_fifoid_get(&info->conn_info); + fifo_id &= ~(FIFO_DFIFO_MASK | FIFO_EFIFO_MASK); + if (mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST) + fifo_id &= ~FIFO_RFIFO_MASK; + if (fifo_id != FIFO_NONE) { + if (fifo_id & FIFO_OFIFO_MASK) + /* Wait OFIFO_EMPTY */ + mc_packet_add_force_write_c(MCI_OFIFO_FLG, + MCB_OFIFO_FLG_OEMP); + if (fifo_id & FIFO_RFIFO_MASK) + /* Wait RFIFO_EMPTY */ + mc_packet_add_force_write_c(MCI_RFIFO_FLG, + MCB_RFIFO_FLG_REMP); + if (fifo_id & FIFO_OFIFO_MASK) + mc_packet_add_wait_event + (MCDRV_EVT_C_REG_FLAG_SET | + (MCI_OFIFO_FLG << 8) | MCB_OFIFO_FLG_OEMP); + + if (fifo_id & FIFO_RFIFO_MASK) + mc_packet_add_wait_event + (MCDRV_EVT_C_REG_FLAG_SET | + (MCI_RFIFO_FLG << 8) | MCB_RFIFO_FLG_REMP); + + mc_packet_execute(); + + if (fifo_id & FIFO_OFIFO_MASK) + /* Clear OFIFO_EMPTY */ + mc_packet_add_force_write_c(MCI_OFIFO_FLG, + MCB_OFIFO_FLG_ALL); + + if (fifo_id & FIFO_RFIFO_MASK) + /* Clear RFIFO_EMPTY */ + mc_packet_add_force_write_c(MCI_RFIFO_FLG, + MCB_RFIFO_FLG_ALL); + + mc_packet_execute(); + } + } + + if (another_fifo_id && !another_info->input_dataend_set) { + another_info->preinput_dataend_set = false; + + cdsp_command_inputdataend(another_id); + + another_info->format_propagate = true; + + if (another_fifo_id & FIFO_OFIFO_MASK) + cdsp_ofifo_start_real(); + if (another_fifo_id & FIFO_RFIFO_MASK) + cdsp_rfifo_start_real(); + + } else + info->callback.on[CALLBACK_HOSTCOMMAND] = true; +} + +static void cdsp_interrupt_proc_coder_sfr(enum mc_cdsp_id id) +{ + struct coder_info *info; + u8 command; + + info = cdsp_coder_info_get(id); + + /* Read SFR data */ + cdsp_command_read_os2host(id, &info->coder); + command = info->coder.command; + + if (command >= CDSP_CMD_OS2HOST_READY_MIN) + return; /* ready */ + + if (command <= CDSP_CMD_OS2HOST_CMN_MAX) + /* Common Command */ + switch (command) { + case CDSP_CMD_OS2HOST_CMN_NOTIFY_OUT_FORMAT: + cdsp_output_format_notify_os2host(id); + break; + default: + /* DEC/ENC_SFR1 Write complete */ + info->coder.params[CDSP_CMD_PARAM_RESULT_00] = 0; + info->coder.params[CDSP_CMD_PARAM_RESULT_01] = 0; + info->coder.params[CDSP_CMD_PARAM_RESULT_02] = 0; + info->coder.params[CDSP_CMD_PARAM_RESULT_03] = 0; + cdsp_command_write_complete(id, &info->coder); + break; + } else if (command <= CDSP_CMD_OS2HOST_PRG_MAX) + /* Callback (HOST COMMAND) */ + info->callback.on[CALLBACK_HOSTCOMMAND] = true; +} + +static void cdsp_interrupt_proc_coder_event(enum mc_cdsp_id id) +{ + u8 add, event; + + /* Read EVT data */ + if (id == CDSP_DECODER) + add = MCI_DEC_EVT; + else + add = MCI_ENC_EVT; + + mc_read_c(add, &event, 1); + mc_packet_add_force_write_c(add, 0); + + mc_packet_execute(); + + /* Timer Event */ + if (event & EVENT_TIMER) { + /* Callback (TIMER) */ + struct coder_info *info; + info = cdsp_coder_info_get(id); + info->callback.on[CALLBACK_TIMER] = true; + } +} + +static int cdsp_coder_stop(enum mc_cdsp_id id, u8 verify) +{ + struct coder_info *info; + struct coder_params coder; + u32 fifo_id; + u8 data, addint; + int ret = 0; + + info = cdsp_coder_info_get(id); + + /* State check */ + if (info->state != STATE_PLAYING) + return -EBUSY; + + fifo_id = cdsp_fifoid_get(&info->conn_info); + if (fifo_id & FIFO_EFIFO) { + mc_read_c(MCI_DEC_FIFO_CH, &data, 1); + data &= ~MCB_DEC_EFIFO_START; + mc_packet_add_force_write_c(MCI_DEC_FIFO_CH, data); + + mc_packet_execute(); + } + if ((fifo_id & FIFO_DFIFO) && + !(mc_fifo_info.rdfifo_bit_sel & MCB_DFIFO_SEL_HOST)) { + mc_read_c(MCI_RDFIFO_BIT_SEL, &data, 1); + data &= ~MCB_RDFIFO_DFIFO_START; + mc_packet_add_force_write_c(MCI_RDFIFO_BIT_SEL, data); + + mc_packet_execute(); + } + + /* DEC/ENC Stop */ + mc_read_c(MCI_DEC_START, &data, 1); + if (id == CDSP_DECODER) { + data &= ~MCB_DEC_DEC_START; + addint = MCI_DEC_ENABLE; + } else { + data &= ~MCB_DEC_ENC_START; + addint = MCI_ENC_ENABLE; + } + mc_packet_add_force_write_c(MCI_DEC_START, data); + + mc_packet_execute(); + + /* VerifyStopCompletion command */ + if (verify == MADEVCDSP_VERIFY_COMP_ON) { + coder.command = CDSP_CMD_HOST2OS_SYS_VERIFY_STOP_COMP; + ret = cdsp_command_write_host2os(id, &coder); + } + + /* DEC/ENC END,ERR Interrupt Disable */ + mc_read_c(addint, &data, 1); + data &= ~(MCB_EDEC_END | MCB_EDEC_ERR); + mc_packet_add_force_write_c(addint, data); + + mc_packet_execute(); + + return ret; +} + +static void cdsp_fifo_stop(enum mc_cdsp_id id) +{ + u32 fifo_id; + u8 data; + + fifo_id = cdsp_fifoid_get_from_coderid(id); + + if (fifo_id & FIFO_DFIFO_MASK) { + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt Disable */ + mc_packet_add_force_write_c(MCI_DFIFO_ENABLE, 0); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data &= ~MCB_EDFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + } + + if (fifo_id & FIFO_EFIFO_MASK) { + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt Disable */ + mc_packet_add_force_write_c(MCI_EFIFO_ENABLE, 0); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data &= ~MCB_EEFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + } + + if (fifo_id & FIFO_OFIFO_MASK) { + /* OUT Stop */ + mc_read_c(MCI_DEC_START, &data, 1); + + data &= ~MCB_DEC_OUT_START; + mc_packet_add_force_write_c(MCI_DEC_START, data); + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt Disable */ + mc_packet_add_force_write_c(MCI_OFIFO_ENABLE, 0); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data &= ~MCB_EOFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + } + + if (fifo_id & FIFO_RFIFO_MASK) { + if (!(mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST)) { + /* OUT Stop */ + mc_read_c(MCI_DEC_START2, &data, 1); + + data &= ~MCB_RFIFO_START; + mc_packet_add_force_write_c(MCI_DEC_START2, data); + } + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt Disable */ + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, 0); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data &= ~MCB_ERFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + } +} + +static u32 cdsp_convert_sample_to_msec(u8 fs, u32 sample) +{ + u32 base, msec; + + if (!sample) + return 0; + + switch (fs) { + case CODER_FMT_FS_48000: + base = OUTPUT_FS_48000; + break; + case CODER_FMT_FS_44100: + base = OUTPUT_FS_44100; + break; + case CODER_FMT_FS_32000: + base = OUTPUT_FS_32000; + break; + case CODER_FMT_FS_24000: + base = OUTPUT_FS_24000; + break; + case CODER_FMT_FS_22050: + base = OUTPUT_FS_22050; + break; + case CODER_FMT_FS_16000: + base = OUTPUT_FS_16000; + break; + case CODER_FMT_FS_12000: + base = OUTPUT_FS_12000; + break; + case CODER_FMT_FS_11025: + base = OUTPUT_FS_11025; + break; + case CODER_FMT_FS_8000: + base = OUTPUT_FS_8000; + break; + default: + base = OUTPUT_FS_DEF; + break; + } + + msec = (sample / base) * 1000; + msec += (((sample % base) * 1000) + (base - 1)) / base; + + return msec; +} + +static int cdsp_output_get_position(enum mc_cdsp_id id, u32 *pos) +{ + struct coder_info *info; + u32 output_pos; + u8 data[4]; + + info = cdsp_coder_info_get(id); + + /* Path check */ + switch (info->conn_info.dest) { + case CDSP_OUT_DEST_RFIFO: + case CDSP_OUT_DEST_OTHER_INBUF: + case CDSP_OUT_DEST_NONE: + return -EIO; + default: + break; + } + + /* DEC_POS Read */ + mc_read_c(MCI_DEC_POS1, &data[3], 1); + mc_read_c(MCI_DEC_POS2, &data[2], 1); + mc_read_c(MCI_DEC_POS3, &data[1], 1); + mc_read_c(MCI_DEC_POS4, &data[0], 1); + + output_pos = (u32) data[3] << 24 | (u32) data[2] << 16 | + (u32) data[1] << 8 | (u32) data[0]; + + *pos = cdsp_convert_sample_to_msec(info->format.fs, output_pos); + + return 0; +} + +static void cdsp_interrupt_proc_coder_error(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + u8 addr, data, error; + u32 pos = 0; + int ret; + + info = cdsp_coder_info_get(id); + + /* Read ERR data */ + if (id == CDSP_DECODER) + addr = MCI_DEC_ERROR; + else + addr = MCI_ENC_ERROR; + + mc_read_c(addr, &error, 1); + + info->error_code = error; + + ret = cdsp_output_get_position(id, &pos); + if (ret) + return; + + if (error > DEC_ERR_PROG_SPECIFIC_MAX) { + /* Stop */ + cdsp_fifo_stop(id); + ret = cdsp_coder_stop(id, MADEVCDSP_VERIFY_COMP_OFF); + + /* Reset command */ + coder.command = CDSP_CMD_HOST2OS_CMN_RESET; + ret = cdsp_command_write_host2os(id, &coder); + + /* Command register Initialize */ + cdsp_command_init(id); + + /* EDEC/EENC_SFR Disable */ + if (id == CDSP_DECODER) { + mc_read_c(MCI_DEC_ENABLE, &data, 1); + data &= ~MCB_EDEC_SFR; + mc_packet_add_force_write_c(MCI_DEC_ENABLE, data); + } else { + mc_read_c(MCI_ENC_ENABLE, &data, 1); + data &= ~MCB_EENC_SFR; + mc_packet_add_force_write_c(MCI_ENC_ENABLE, data); + } + mc_packet_execute(); + + /* EDEC/EENC Disable */ + mc_read_digital(MCI_ECDSP, &data, 1); + if (id == CDSP_DECODER) + data &= ~MCB_EDEC; + else + data &= ~MCB_EENC; + + mc_packet_add_force_write_if(MCI_ECDSP, data); + mc_packet_execute(); + + /* Parameter Initialize */ + info->prog_info.vendor_id = 0; + info->prog_info.function_id = 0; + + info->state = STATE_READY_SETUP; + + /* Callback (ERROR) */ + info->callback.on[CALLBACK_PLAY_ERROR2] = true; + info->callback.ex_info[CALLBACK_PLAY_ERROR2] = + (pos << 8) | (error & 0xFF); + } else { + cdsp_fifo_stop(id); + cdsp_coder_stop(id, MADEVCDSP_VERIFY_COMP_OFF); + + info->state = STATE_READY; + + /* Callback (ERROR) */ + info->callback.on[CALLBACK_PLAY_ERROR1] = true; + info->callback.ex_info[CALLBACK_PLAY_ERROR1] = + (pos << 8) | (error & 0xFF); + } +} + +static void cdsp_output_start(struct coder_info *info) +{ + u8 dest; + + dest = info->conn_info.dest; + switch (dest) { + case CDSP_OUT_DEST_OFIFO: + break; + case CDSP_OUT_DEST_OFIFO_RFIFO: + if (mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST) + dest = CDSP_OUT_DEST_OFIFO; + break; + case CDSP_OUT_DEST_RFIFO: + if (mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST) + return; + break; + default: + return; + } + + if (info->prog_info.output_start_mode && !info->change_output_fs) + return; + + switch (dest) { + case CDSP_OUT_DEST_OFIFO: + if (!mc_fifo_info.ofifo_output_start) + return; + + cdsp_ofifo_start_real(); + break; + case CDSP_OUT_DEST_OFIFO_RFIFO: + if (!mc_fifo_info.ofifo_output_start || + !mc_fifo_info.rfifo_output_start) + return; + + cdsp_ofifo_start_real(); + cdsp_rfifo_start_real(); + break; + case CDSP_OUT_DEST_RFIFO: + if (!mc_fifo_info.rfifo_output_start) + return; + + cdsp_rfifo_start_real(); + break; + default: + break; + } +} + +static void cdsp_interrupt_proc_coder_end(enum mc_cdsp_id id) +{ + struct coder_info *info, *another_info; + struct coder_params coder; + enum mc_cdsp_id another_id; + u8 data; + + info = cdsp_coder_info_get(id); + + another_id = cdsp_another_id_get(id); + another_info = cdsp_coder_info_get(another_id); + + if (info->format_propagate) { + info->format.fs = another_info->format.fs; + + /* DEC/ENC Stop */ + mc_read_c(MCI_DEC_START, &data, 1); + if (id == CDSP_DECODER) + data &= ~MCB_DEC_DEC_START; + else + data &= ~MCB_DEC_ENC_START; + + mc_packet_add_force_write_c(MCI_DEC_START, data); + mc_packet_execute(); + + /* VerifyStopCompletion command */ + coder.command = CDSP_CMD_HOST2OS_SYS_VERIFY_STOP_COMP; + cdsp_command_write_host2os(id, &coder); + + /* GetInputPos command */ + coder.command = CDSP_CMD_HOST2OS_SYS_GET_INPUT_POS; + cdsp_command_write_host2os(id, &coder); + + /* InputPos */ + info->input_pos += + *(u32 *) (coder.params + CDSP_CMD_PARAM_RESULT_00); + + /* Clear command */ + coder.command = CDSP_CMD_HOST2OS_CMN_CLEAR; + cdsp_command_write_host2os(id, &coder); + + /* DEC/ENC Start */ + mc_read_c(MCI_DEC_START, &data, 1); + if (id == CDSP_DECODER) + data |= MCB_DEC_DEC_START; + else + data |= MCB_DEC_ENC_START; + + mc_packet_add_force_write_c(MCI_DEC_START, data); + + mc_packet_execute(); + + info->format_propagate = false; + + /* Callback (HOST Command) */ + another_info->callback.on[CALLBACK_HOSTCOMMAND] = true; + } else { + switch (another_info->state) { + case STATE_READY_SETUP: + another_info->preinput_dataend_set = true; + break; + case STATE_READY: + case STATE_PLAYING: + if (another_info->conn_info.src == + CDSP_IN_SOURCE_OTHER_OUTBUF) { + /* InputDataEnd command */ + cdsp_command_inputdataend(another_id); + /* Input data end flag - set */ + another_info->input_dataend_set = true; + cdsp_output_start(another_info); + } + break; + default: + break; + } + + /* ClearInputDataEnd command */ + coder.command = CDSP_CMD_HOST2OS_SYS_CLEAR_INPUT_DATA_END; + cdsp_command_write_host2os(id, &coder); + + /* Input data end flag - release */ + info->input_dataend_set = false; + + cdsp_fifo_stop(id); + cdsp_coder_stop(id, MADEVCDSP_VERIFY_COMP_ON); + + info->state = STATE_READY; + + /* Callback (DEC/ENC END) */ + info->callback.on[CALLBACK_END_OF_SEQUENCE] = true; + } +} + +static void cdsp_interrupt_proc_coder(enum mc_cdsp_id id) +{ + struct coder_info *info; + u8 addr, data, clear = 0; + + info = cdsp_coder_info_get(id); + + /* Read interrupt flag */ + if (id == CDSP_DECODER) + addr = MCI_DEC_FLG; + else + addr = MCI_ENC_FLG; + mc_read_c(addr, &data, 1); + + if (id == CODER_DEC) { + if (data & MCB_DEC_FLG_SFR) { + cdsp_interrupt_proc_coder_sfr(id); + clear |= MCB_DEC_FLG_SFR; + } + if (data & MCB_DEC_FLG_ERR) { + cdsp_interrupt_proc_coder_error(id); + clear |= MCB_DEC_FLG_ERR; + } + if ((data & MCB_DEC_FLG_END) && info->state == STATE_PLAYING) { + cdsp_interrupt_proc_coder_end(id); + clear |= MCB_DEC_FLG_END; + } + if (data & MCB_DEC_EVT_FLG) { + cdsp_interrupt_proc_coder_event(id); + clear |= MCB_DEC_EVT_FLG; + } + } else { + if (data & MCB_ENC_FLG_SFR) { + cdsp_interrupt_proc_coder_sfr(id); + clear |= MCB_ENC_FLG_SFR; + } + if (data & MCB_ENC_FLG_ERR) { + cdsp_interrupt_proc_coder_error(id); + clear |= MCB_ENC_FLG_ERR; + } + if ((data & MCB_ENC_FLG_END) && info->state == STATE_PLAYING) { + cdsp_interrupt_proc_coder_end(id); + clear |= MCB_ENC_FLG_END; + } + if (data & MCB_ENC_EVT_FLG) { + cdsp_interrupt_proc_coder_event(id); + clear |= MCB_ENC_EVT_FLG; + } + } + + mc_packet_add_force_write_c(addr, clear); + + mc_packet_execute(); +} + +static void cdsp_interrupt_proc_dfifo(void) +{ + struct coder_info *info; + u8 flag, ctrl; + + /* Read interrupt flag */ + mc_read_c(MCI_DFIFO_FLG, &flag, 1); + + /* Interrupt process */ + /* EDPNT, EDEMP Read */ + mc_read_c(MCI_DFIFO_ENABLE, &ctrl, 1); + + info = cdsp_coder_info_get(CODER_DEC); + if (!((info->conn_info.src == CDSP_IN_SOURCE_DFIFO || + info->conn_info.src == CDSP_IN_SOURCE_DFIFO_EFIFO) && + info->state > STATE_INIT)) { + info = cdsp_coder_info_get(CODER_ENC); + if (!((info->conn_info.src == CDSP_IN_SOURCE_DFIFO || + info->conn_info.src == CDSP_IN_SOURCE_DFIFO_EFIFO) && + info->state > STATE_INIT)) + info = NULL; + } + + /* DPNT */ + if ((flag & MCB_DFIFO_FLG_DPNT) && (ctrl & MCB_DFIFO_EDPNT)) { + /* EDPNT Disable */ + ctrl &= ~MCB_DFIFO_EDPNT; + + /* Callback (DFIFO POINT) */ + if (info) + info->callback.on[CALLBACK_DFIFOPOINT] = true; + } + + /* DEMP */ + if ((flag & MCB_DFIFO_FLG_DEMP) && (ctrl & MCB_DFIFO_EDEMP)) { + /* EDEMP Disable */ + ctrl &= ~MCB_DFIFO_EDEMP; + + /* Callback (DFIFO EMPTY) */ + if (info) + info->callback.on[CALLBACK_DFIFOEMPTY] = true; + } + + mc_packet_add_force_write_c(MCI_DFIFO_ENABLE, ctrl); + + /* Clear interrupt flag */ + mc_packet_add_force_write_c(MCI_DFIFO_FLG, flag); + + mc_packet_execute(); +} + +static void cdsp_interrupt_proc_ofifo_core(void) +{ + struct coder_info *info; + u8 data; + + /* EOPNT Disable */ + mc_read_c(MCI_OFIFO_ENABLE, &data, 1); + data &= ~MCB_OFIFO_EOPNT; + mc_packet_add_force_write_c(MCI_OFIFO_ENABLE, data); + + /* EOFIFO Disable */ + mc_read_digital(MCI_ECDSP, &data, 1); + data &= ~MCB_EOFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + + /* OUT START */ + mc_fifo_info.ofifo_output_start = true; + + info = cdsp_coder_info_get(CODER_DEC); + if (!((info->conn_info.dest == CDSP_OUT_DEST_OFIFO || + info->conn_info.dest == CDSP_OUT_DEST_OFIFO_RFIFO) && + info->state > STATE_INIT)) { + info = cdsp_coder_info_get(CODER_ENC); + if (!((info->conn_info.dest == CDSP_OUT_DEST_OFIFO || + info->conn_info.dest == CDSP_OUT_DEST_OFIFO_RFIFO) && + info->state > STATE_INIT)) + info = NULL; + } + + /* OUT_START Set */ + if (info) + cdsp_output_start(info); +} + +static inline void cdsp_interrupt_proc_ofifo(void) +{ + u8 flag; + + /* Read interrupt flag */ + mc_read_c(MCI_OFIFO_FLG, &flag, 1); + + /* Interrupt process */ + if (flag & MCB_OFIFO_FLG_OPNT) + cdsp_interrupt_proc_ofifo_core(); + + /* Clear interrupt flag */ + mc_packet_add_force_write_c(MCI_OFIFO_FLG, flag); + + mc_packet_execute(); +} + +static void cdsp_interrupt_proc_rfifo_core(void) +{ + struct coder_info *info; + u8 data; + + /* ERPNT Disable */ + mc_read_c(MCI_RFIFO_ENABLE, &data, 1); + data &= ~MCB_RFIFO_ERPNT; + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, data); + + /* ERFIFO Disable */ + mc_read_digital(MCI_ECDSP, &data, 1); + data &= ~MCB_ERFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + + /* OUT START */ + mc_fifo_info.rfifo_output_start = true; + + info = cdsp_coder_info_get(CODER_DEC); + if (!((info->conn_info.dest == CDSP_OUT_DEST_RFIFO || + info->conn_info.dest == CDSP_OUT_DEST_OFIFO_RFIFO) && + info->state > STATE_INIT)) { + info = cdsp_coder_info_get(CODER_ENC); + if (!((info->conn_info.dest == CDSP_OUT_DEST_RFIFO || + info->conn_info.dest == CDSP_OUT_DEST_OFIFO_RFIFO) && + info->state > STATE_INIT)) + info = NULL; + } + + /* OUT_START Set */ + if (info) + cdsp_output_start(info); +} + +static inline void cdsp_interrupt_proc_rfifo_port(void) +{ + u8 flag; + + /* Read interrupt flag */ + mc_read_c(MCI_RFIFO_FLG, &flag, 1); + + /* Interrupt process */ + if (flag & MCB_OFIFO_FLG_OPNT) + cdsp_interrupt_proc_rfifo_core(); + + /* Clear interrupt flag */ + mc_packet_add_force_write_c(MCI_RFIFO_FLG, flag); + + mc_packet_execute(); +} + +static inline void cdsp_interrupt_proc_rfifo_host(void) +{ + struct coder_info *info; + u8 flag, ctrl; + + /* Read interrupt flag */ + mc_read_c(MCI_RFIFO_FLG, &flag, 1); + + /* ERxxx Read */ + mc_read_c(MCI_RFIFO_ENABLE, &ctrl, 1); + + if (flag & MCB_RFIFO_FLG_RPNT) { + info = cdsp_coder_info_get(CODER_DEC); + if (!((info->conn_info.dest == CDSP_OUT_DEST_RFIFO || + info->conn_info.dest == CDSP_OUT_DEST_OFIFO_RFIFO) && + info->state > STATE_INIT)) { + info = cdsp_coder_info_get(CODER_ENC); + if (!((info->conn_info.dest == CDSP_OUT_DEST_RFIFO || + info->conn_info.dest == + CDSP_OUT_DEST_OFIFO_RFIFO) + && info->state > STATE_INIT)) + info = NULL; + } + + if (ctrl & MCB_RFIFO_ERPNT) { + /* ERPNT Disable */ + ctrl &= ~MCB_RFIFO_ERPNT; + + /* Callback (RFIFO POINT) */ + if (info) + info->callback.on[CALLBACK_RFIFOPOINT] = true; + } + + if ((flag & MCB_RFIFO_FLG_ROVF) && (ctrl & MCB_RFIFO_EROVF)) { + /* EROVF Disable */ + ctrl &= ~MCB_RFIFO_EROVF; + + /* Callback (RecBuf Overflow) */ + if (info) + info->callback.on[CALLBACK_RECBUF_OVF] = true; + } + + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, ctrl); + } + + /* Clear interrupt flag */ + mc_packet_add_force_write_c(MCI_RFIFO_FLG, flag); + + mc_packet_execute(); +} + +static inline void cdsp_interrupt_proc_rfifo(void) +{ + if (mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST) + cdsp_interrupt_proc_rfifo_host(); + else + cdsp_interrupt_proc_rfifo_port(); +} + +static inline void cdsp_interrupt_proc(void) +{ + u8 data, error; + + /* Read interrupt flag */ + mc_read_c(MCI_CDSP_FLG, &data, 1); + + /* Interrupt process */ + if (data & MCB_CDSP_FLG_ERR) { + mc_read_c(MCI_CDSP_ERR, &error, 1); + + mc_cdsp_info.hw_error_code = error; + } else if (data & MCB_CDSP_FLG_WDT) + mc_cdsp_info.hw_error_code = CDSP_ERR_WDT; + + /* Interrupt ALL disable */ + mc_packet_add_force_write_c(MCI_DEC_ENABLE, 0); + mc_packet_add_force_write_c(MCI_ENC_ENABLE, 0); + mc_packet_add_force_write_c(MCI_DFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_OFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_EFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_FFIFO_ENABLE, 0); + mc_packet_add_force_write_c(MCI_CDSP_ENABLE, 0); + mc_packet_add_force_write_if(MCI_ECDSP, 0); + + /* State update */ + mc_dec_info.state = STATE_NOTINIT; + mc_enc_info.state = STATE_NOTINIT; + + /* Callback (HW ERROR) */ + mc_dec_info.callback.on[CALLBACK_HW_ERROR] = true; + mc_dec_info.callback.ex_info[CALLBACK_HW_ERROR] = + mc_cdsp_info.hw_error_code & 0xFF; + mc_enc_info.callback.on[CALLBACK_HW_ERROR] = true; + mc_enc_info.callback.ex_info[CALLBACK_HW_ERROR] = + mc_cdsp_info.hw_error_code & 0xFF; + + /* Clear interrupt flag */ + mc_packet_add_force_write_c(MCI_CDSP_FLG, data); + + mc_packet_execute(); +} + +static inline void cdsp_callback_proc_core(struct callback_info *callback, + int handle) +{ + callback->on[CALLBACK_HOSTCOMMAND] = false; + callback->on[CALLBACK_END_OF_SEQUENCE] = false; + callback->on[CALLBACK_DFIFOPOINT] = false; + callback->on[CALLBACK_RFIFOPOINT] = false; + callback->on[CALLBACK_DFIFOEMPTY] = false; + callback->on[CALLBACK_RECBUF_OVF] = false; + callback->on[CALLBACK_TIMER] = false; + callback->on[CALLBACK_PLAY_ERROR1] = false; + callback->ex_info[CALLBACK_PLAY_ERROR1] = 0; + callback->on[CALLBACK_PLAY_ERROR2] = false; + callback->ex_info[CALLBACK_PLAY_ERROR2] = 0; + callback->on[CALLBACK_HW_ERROR] = false; + callback->ex_info[CALLBACK_HW_ERROR] = 0; +} + +static inline void cdsp_callback_proc(void) +{ + cdsp_callback_proc_core(&mc_dec_info.callback, 0); + cdsp_callback_proc_core(&mc_enc_info.callback, 1); +} + +static void cdsp_get_data(struct mcdrv_aec_info *aec_info, + struct aec_cdsp_info *cdsp_info) +{ + struct aec_cdsp_func_info *finfo_a; + struct aec_cdsp_func_info *finfo_b; + + finfo_a = &cdsp_info->func_info[AEC_FUNC_INFO_A]; + finfo_b = &cdsp_info->func_info[AEC_FUNC_INFO_B]; + + finfo_a->id = CDSP_DECODER; + finfo_a->func_on = false; + finfo_a->data = NULL; + finfo_a->data_size = 0; + + finfo_b->id = CDSP_ENCODER; + finfo_b->func_on = false; + finfo_b->data = NULL; + finfo_b->data_size = 0; + + if (aec_info->vbox.enable) { + finfo_a->func_on = aec_info->vbox.cdsp_func_a_on; + finfo_b->func_on = aec_info->vbox.cdsp_func_b_on; + + if (!finfo_a->func_on && !finfo_b->func_on) + return; + + if (finfo_a->func_on) { + finfo_a->data = aec_info->vbox.cdsp_a.data; + finfo_a->data_size = aec_info->vbox.cdsp_a.data_size; + } + + if (finfo_b->func_on) { + finfo_b->data = aec_info->vbox.cdsp_b.data; + finfo_b->data_size = aec_info->vbox.cdsp_b.data_size; + } + } + + if (finfo_a->data) + finfo_a->data = &finfo_a->data[CHUNK_SIZE]; + + if (finfo_b->data) + finfo_b->data = &finfo_b->data[CHUNK_SIZE]; +} + +static inline int cdsp_fifo_check(enum mc_cdsp_id id, + struct aec_cdsp_info *cdsp_info) +{ + struct aec_cdsp_func_info *finfo; + u32 pos, sample, fifo_id; + u8 sel, fifo, src, dest, bit, ch, etobuf, tmp; + u8 *data; + + if (id == CDSP_DECODER) + finfo = &cdsp_info->func_info[AEC_FUNC_INFO_A]; + else + finfo = &cdsp_info->func_info[AEC_FUNC_INFO_B]; + + data = finfo->fifo_data; + + fifo = data[CDSP_USE_FIFO]; + if (fifo != CDSP_FIFO_DONTCARE) { + if ((fifo & CDSP_FIFO_OTHER_OUTBUF_BIT) && + ((fifo & CDSP_FIFO_EFIFO_BIT) || + (fifo & CDSP_FIFO_DFIFO_BIT))) + return -EINVAL; + + if ((fifo & CDSP_FIFO_OTHER_INBUF_BIT) && + ((fifo & CDSP_FIFO_OFIFO_BIT) || + (fifo & CDSP_FIFO_RFIFO_BIT))) + return -EINVAL; + + if (fifo & CDSP_FIFO_OTHER_OUTBUF_BIT) + src = CDSP_IN_SOURCE_OTHER_OUTBUF; + else if ((fifo & CDSP_FIFO_EFIFO_BIT) && + (fifo & CDSP_FIFO_DFIFO_BIT)) + src = CDSP_IN_SOURCE_DFIFO_EFIFO; + else if (fifo & CDSP_FIFO_DFIFO_BIT) + src = CDSP_IN_SOURCE_DFIFO; + else if (fifo & CDSP_FIFO_EFIFO_BIT) + src = CDSP_IN_SOURCE_EFIFO; + else + src = CDSP_IN_SOURCE_NONE; + + finfo->conn_info.src = src; + + if (fifo & CDSP_FIFO_OTHER_INBUF_BIT) + dest = CDSP_OUT_DEST_OTHER_INBUF; + else if ((fifo & CDSP_FIFO_OFIFO_BIT) && + (fifo & CDSP_FIFO_RFIFO_BIT)) + dest = CDSP_OUT_DEST_OFIFO_RFIFO; + else if (fifo & CDSP_FIFO_OFIFO_BIT) + dest = CDSP_OUT_DEST_OFIFO; + else if (fifo & CDSP_FIFO_RFIFO_BIT) + dest = CDSP_OUT_DEST_RFIFO; + else + dest = CDSP_OUT_DEST_NONE; + + finfo->conn_info.dest = dest; + } + + fifo_id = cdsp_fifoid_get(&finfo->conn_info); + + /* EFIFO */ + if (fifo_id & FIFO_EFIFO) { + tmp = data[ROUTE_EFIFO0_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + sel = cdsp_info->efifo01_sel & ~MCB_EFIFO0_SEL; + sel |= tmp & MCB_EFIFO0_SEL; + cdsp_info->efifo01_sel = sel; + } + + tmp = data[ROUTE_EFIFO1_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + sel = cdsp_info->efifo01_sel & ~MCB_EFIFO1_SEL; + sel |= (tmp << 4) & MCB_EFIFO1_SEL; + cdsp_info->efifo01_sel = sel; + } + + tmp = data[ROUTE_EFIFO2_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + sel = cdsp_info->efifo23_sel & ~MCB_EFIFO2_SEL; + sel |= tmp & MCB_EFIFO2_SEL; + cdsp_info->efifo23_sel = sel; + } + + tmp = data[ROUTE_EFIFO3_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + sel = cdsp_info->efifo23_sel & ~MCB_EFIFO3_SEL; + sel |= (tmp << 4) & MCB_EFIFO3_SEL; + cdsp_info->efifo23_sel = sel; + } + + /* 0: 2ch 16bit */ + /* 1: 4ch 16bit */ + /* 2: 2ch 32bit */ + /* 3: 4ch 32bit */ + ch = finfo->conn_ex_info.efifo_ch; + bit = finfo->bit_width.efifo; + etobuf = finfo->format.etobuf; + + tmp = data[CDSP_EFIFO_CH]; + switch (tmp) { + case 2: + case 4: + ch = tmp; + break; + case CDSP_FIFO_DONTCARE: + break; + default: + return -EINVAL; + } + + tmp = data[CDSP_EFIFO_BIT_WIDTH]; + switch (tmp) { + case 16: + case 32: + bit = tmp; + break; + case CDSP_FIFO_DONTCARE: + break; + default: + return -EINVAL; + } + + tmp = data[CDSP_EFIFO_E2BUF_MODE]; + switch (tmp) { + case CODER_FMT_ETOBUF_LRMIX: + case CODER_FMT_ETOBUF_LCH: + case CODER_FMT_ETOBUF_RCH: + etobuf = tmp; + break; + case CDSP_FIFO_DONTCARE: + break; + default: + return -EINVAL; + } + + finfo->conn_ex_info.efifo_ch = ch; + finfo->bit_width.efifo = bit; + finfo->format.etobuf = etobuf; + } + + /* OFIFO */ + tmp = data[ROUTE_OUT0L_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + if ((fifo_id & FIFO_OFIFO) || + (tmp == OUT_LOOPBACK_L) || (tmp == OUT_LOOPBACK_R)) { + sel = cdsp_info->out0_sel & ~MCB_OUT0L_SEL; + sel |= tmp & MCB_OUT0L_SEL; + cdsp_info->out0_sel = sel; + } + } + + tmp = data[ROUTE_OUT0R_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + if ((fifo_id & FIFO_OFIFO) || + (tmp == OUT_LOOPBACK_L) || (tmp == OUT_LOOPBACK_R)) { + sel = cdsp_info->out0_sel & ~MCB_OUT0R_SEL; + sel |= (tmp << 4) & MCB_OUT0R_SEL; + cdsp_info->out0_sel = sel; + } + } + + tmp = data[ROUTE_OUT1L_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + if ((fifo_id & FIFO_OFIFO) || + (tmp == OUT_LOOPBACK_L) || (tmp == OUT_LOOPBACK_R)) { + sel = cdsp_info->out1_sel & ~MCB_OUT1L_SEL; + sel |= tmp & MCB_OUT1L_SEL; + cdsp_info->out1_sel = sel; + } + } + + tmp = data[ROUTE_OUT1R_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + if ((fifo_id & FIFO_OFIFO) || + (tmp == OUT_LOOPBACK_L) || (tmp == OUT_LOOPBACK_R)) { + sel = cdsp_info->out1_sel & ~MCB_OUT1R_SEL; + sel |= (tmp << 4) & MCB_OUT1R_SEL; + cdsp_info->out1_sel = sel; + } + } + + tmp = data[ROUTE_OUT2L_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + if ((fifo_id & FIFO_OFIFO) || + (tmp == OUT_LOOPBACK_L) || (tmp == OUT_LOOPBACK_R)) { + sel = cdsp_info->out2_sel & ~MCB_OUT2L_SEL; + sel |= tmp & MCB_OUT2L_SEL; + cdsp_info->out2_sel = sel; + } + } + + tmp = data[ROUTE_OUT2R_SEL]; + if (tmp != CDSP_FIFO_DONTCARE) { + if ((fifo_id & FIFO_OFIFO) || + (tmp == OUT_LOOPBACK_L) || (tmp == OUT_LOOPBACK_R)) { + sel = cdsp_info->out2_sel & ~MCB_OUT2R_SEL; + sel |= (tmp << 4) & MCB_OUT2R_SEL; + cdsp_info->out2_sel = sel; + } + } + + if (fifo_id & FIFO_OFIFO) { + /* 0: 2ch 16bit) */ + /* 1: 4ch 16bit */ + /* 2: 2ch 32bit */ + /* 3: 4ch 32bit */ + ch = finfo->conn_ex_info.ofifo_ch; + bit = finfo->bit_width.ofifo; + + tmp = data[CDSP_OFIFO_CH]; + switch (tmp) { + case 2: + case 4: + ch = tmp; + break; + case CDSP_FIFO_DONTCARE: + break; + default: + return -EINVAL; + } + + tmp = data[CDSP_OFIFO_BIT_WIDTH]; + switch (tmp) { + case 16: + case 32: + bit = tmp; + break; + case CDSP_FIFO_DONTCARE: + break; + default: + return -EINVAL; + } + + finfo->conn_ex_info.ofifo_ch = ch; + finfo->bit_width.ofifo = bit; + + sample = ((u32) data[CDSP_OFIFO_BUFFERING + 0] << 8) | + (u32) data[CDSP_OFIFO_BUFFERING + 1]; + if (sample != CDSP_FIFO_DONTCARE_W) { + if (sample > OFIFO_BUF_SAMPLE_MAX) + return -EINVAL; + cdsp_info->ofifo_buf_sample = sample; + } + } + + /* DFIFO */ + if (fifo_id & FIFO_DFIFO) { + tmp = data[CDSP_DFIFO_BIT_WIDTH]; + if (tmp != CDSP_FIFO_DONTCARE) { + sel = cdsp_info->rdfifo_bit_sel & ~MCB_DFIFO_BIT; + if (tmp == 32) + sel |= MCB_DFIFO_BIT; + cdsp_info->rdfifo_bit_sel = sel; + } + + pos = ((u32) data[CDSP_DFIFO_CB_POINT + 0] << 8) | + (u32) data[CDSP_DFIFO_CB_POINT + 1]; + switch (pos) { + case CDSP_FIFO_DONTCARE_CB: + break; + case CDSP_FIFO_NOT_CB: + cdsp_info->dfifo_cb_pos = CBPOS_DFIFO_NONE; + break; + default: + if (pos > CBPOS_DFIFO_MAX) + return -EINVAL; + + cdsp_info->dfifo_cb_pos = pos; + break; + } + } + + /* RFIFO */ + if (fifo_id & FIFO_RFIFO) { + tmp = data[CDSP_RFIFO_BIT_WIDTH]; + if (tmp != CDSP_FIFO_DONTCARE) { + sel = cdsp_info->rdfifo_bit_sel & ~MCB_RFIFO_BIT; + if (tmp == 32) + sel |= MCB_RFIFO_BIT; + cdsp_info->rdfifo_bit_sel = sel; + } + + pos = ((u32) data[CDSP_RFIFO_CB_POINT + 0] << 8) | + (u32) data[CDSP_RFIFO_CB_POINT + 1]; + switch (pos) { + case CDSP_FIFO_DONTCARE_CB: + break; + case CDSP_FIFO_NOT_CB: + cdsp_info->rfifo_cb_pos = CBPOS_RFIFO_NONE; + break; + default: + if (pos > CBPOS_RFIFO_MAX) + return -EINVAL; + + cdsp_info->rfifo_cb_pos = pos; + break; + } + + sample = ((u32) data[CDSP_RFIFO_BUFFERING + 0] << 8) | + (u32) data[CDSP_RFIFO_BUFFERING + 1]; + if (sample != CDSP_FIFO_DONTCARE_W) { + if (sample > RFIFO_BUF_SAMPLE_MAX) + return -EINVAL; + + cdsp_info->rfifo_buf_sample = sample; + } + } + + return 0; +} + +static int cdsp_memoryrange_check(u16 start1, u16 size1, u16 start2, u16 size2) +{ + u16 end1, end2; + + end1 = start1 + size1 - 1; + end2 = start2 + size2 - 1; + + if (start2 >= start1 && start2 <= end1) + return -EINVAL; + + if (end2 >= start1 && end2 <= end1) + return -EINVAL; + + if (start1 >= start2 && start1 <= end2) + return -EINVAL; + + if (end1 >= start2 && end1 <= end2) + return -EINVAL; + + return 0; +} + +static inline int cdsp_program_check(enum mc_cdsp_id id, + struct coder_firmware *coder) +{ + struct coder_info *info; + struct coder_info *another_info; + struct program_info *another_pinfo; + u16 prog_loadaddr, prog_size; + u16 data_loadaddr, data_size; + u16 work_begin, work_size; + u16 stack_begin, stack_size; + u16 prog_type; + u32 total_size; + int ret; + + info = cdsp_coder_info_get(id); + another_info = cdsp_coder_info_get(cdsp_another_id_get(id)); + + /* Size Check */ + if (coder->size < PRG_DESC_PROGRAM) + return -EINVAL; + + total_size = MAKE_HALFWORD(coder->firmware[PRG_DESC_PRG_SIZE], + coder->firmware[PRG_DESC_PRG_SIZE + 1]); + total_size += MAKE_HALFWORD(coder->firmware[PRG_DESC_DATA_SIZE], + coder->firmware[PRG_DESC_DATA_SIZE + 1]); + total_size += PRG_DESC_PROGRAM / 2; + if (coder->size != (total_size * 2)) + return -EINVAL; + + /* Program Type Check */ + prog_type = MAKE_HALFWORD(coder->firmware[PRG_DESC_PRG_TYPE], + coder->firmware[PRG_DESC_PRG_TYPE + 1]); + if (id == CDSP_DECODER && prog_type != PRG_PRM_TYPE_TASK0) + return -EINVAL; + + if (id == CDSP_ENCODER && prog_type != PRG_PRM_TYPE_TASK1) + return -EINVAL; + + if (another_info->state == STATE_NOTINIT || + another_info->state == STATE_INIT) + return 0; + + /* RAM Check */ + prog_loadaddr = MAKE_HALFWORD(coder->firmware[PRG_DESC_PRG_LOAD_ADR], + coder->firmware[PRG_DESC_PRG_LOAD_ADR + + 1]); + prog_size = + MAKE_HALFWORD(coder->firmware[PRG_DESC_PRG_SIZE], + coder->firmware[PRG_DESC_PRG_SIZE + 1]); + data_loadaddr = + MAKE_HALFWORD(coder->firmware[PRG_DESC_DATA_LOAD_ADR], + coder->firmware[PRG_DESC_DATA_LOAD_ADR + 1]); + data_size = + MAKE_HALFWORD(coder->firmware[PRG_DESC_DATA_SIZE], + coder->firmware[PRG_DESC_DATA_SIZE + 1]); + work_begin = + MAKE_HALFWORD(coder->firmware[PRG_DESC_WORK_BEGIN_ADR], + coder->firmware[PRG_DESC_WORK_BEGIN_ADR + 1]); + work_size = + MAKE_HALFWORD(coder->firmware[PRG_DESC_WORK_SIZE], + coder->firmware[PRG_DESC_WORK_SIZE + 1]); + stack_begin = + MAKE_HALFWORD(coder->firmware[PRG_DESC_STACK_BEGIN_ADR], + coder->firmware[PRG_DESC_STACK_BEGIN_ADR + 1]); + stack_size = + MAKE_HALFWORD(coder->firmware[PRG_DESC_STACK_SIZE], + coder->firmware[PRG_DESC_STACK_SIZE + 1]); + another_pinfo = &another_info->prog_info; + + /* Program & Program */ + ret = cdsp_memoryrange_check(prog_loadaddr, prog_size, + another_pinfo->prog_loadaddr, + another_pinfo->prog_size); + if (ret < 0) + return ret; + + /* Data & Data */ + ret = cdsp_memoryrange_check(data_loadaddr, data_size, + another_pinfo->data_loadaddr, + another_pinfo->data_size); + if (ret < 0) + return ret; + + /* Data & Stack */ + ret = cdsp_memoryrange_check(data_loadaddr, data_size, + another_pinfo->stack_begin, + another_pinfo->stack_size); + if (ret < 0) + return ret; + + ret = cdsp_memoryrange_check(stack_begin, stack_size, + another_pinfo->data_loadaddr, + another_pinfo->data_size); + if (ret < 0) + return ret; + + /* Work & Work */ + ret = cdsp_memoryrange_check(work_begin, work_size, + another_pinfo->work_begin, + another_pinfo->work_size); + if (ret < 0) + return ret; + + /* Work & Stack */ + ret = cdsp_memoryrange_check(work_begin, work_size, + another_pinfo->stack_begin, + another_pinfo->stack_size); + if (ret < 0) + return ret; + + return cdsp_memoryrange_check(stack_begin, stack_size, + another_pinfo->work_begin, + another_pinfo->work_size); +} + +static inline int cdsp_aec_program_check(struct coder_firmware *coder_a, + struct coder_firmware *coder_b) +{ + u16 prog_loadaddr_a, prog_size_a; + u16 data_loadaddr_a, data_size_a; + u16 work_begin_a, work_size_a; + u16 stack_begin_a, stack_size_a; + u32 total_size_a; + u16 prog_loadaddr_b, prog_size_b; + u16 data_loadaddr_b, data_size_b; + u16 work_begin_b, work_size_b; + u16 stack_begin_b, stack_size_b; + u32 total_size_b; + int ret; + + total_size_a = MAKE_HALFWORD(coder_a->firmware[PRG_DESC_PRG_SIZE], + coder_a->firmware[PRG_DESC_PRG_SIZE + 1]); + total_size_a += MAKE_HALFWORD(coder_a->firmware[PRG_DESC_DATA_SIZE], + coder_a->firmware[PRG_DESC_DATA_SIZE + + 1]); + total_size_a += PRG_DESC_PROGRAM / 2; + + total_size_b = MAKE_HALFWORD(coder_b->firmware[PRG_DESC_PRG_SIZE], + coder_b->firmware[PRG_DESC_PRG_SIZE + 1]); + total_size_b += MAKE_HALFWORD(coder_b->firmware[PRG_DESC_DATA_SIZE], + coder_b->firmware[PRG_DESC_DATA_SIZE + + 1]); + total_size_b += PRG_DESC_PROGRAM / 2; + + /* RAM Check */ + prog_loadaddr_a = + MAKE_HALFWORD(coder_a->firmware[PRG_DESC_PRG_LOAD_ADR], + coder_a->firmware[PRG_DESC_PRG_LOAD_ADR + 1]); + prog_loadaddr_b = + MAKE_HALFWORD(coder_b->firmware[PRG_DESC_PRG_LOAD_ADR], + coder_b->firmware[PRG_DESC_PRG_LOAD_ADR + 1]); + + prog_size_a = MAKE_HALFWORD(coder_a->firmware[PRG_DESC_PRG_SIZE], + coder_a->firmware[PRG_DESC_PRG_SIZE + 1]); + prog_size_b = MAKE_HALFWORD(coder_b->firmware[PRG_DESC_PRG_SIZE], + coder_b->firmware[PRG_DESC_PRG_SIZE + 1]); + + data_loadaddr_a = + MAKE_HALFWORD(coder_a->firmware[PRG_DESC_DATA_LOAD_ADR], + coder_a->firmware[PRG_DESC_DATA_LOAD_ADR + 1]); + data_loadaddr_b = + MAKE_HALFWORD(coder_b->firmware[PRG_DESC_DATA_LOAD_ADR], + coder_b->firmware[PRG_DESC_DATA_LOAD_ADR + 1]); + + data_size_a = MAKE_HALFWORD(coder_a->firmware[PRG_DESC_DATA_SIZE], + coder_a->firmware[PRG_DESC_DATA_SIZE + 1]); + data_size_b = MAKE_HALFWORD(coder_b->firmware[PRG_DESC_DATA_SIZE], + coder_b->firmware[PRG_DESC_DATA_SIZE + 1]); + + work_begin_a = MAKE_HALFWORD(coder_a->firmware[PRG_DESC_WORK_BEGIN_ADR], + coder_a->firmware[PRG_DESC_WORK_BEGIN_ADR + + 1]); + work_begin_b = + MAKE_HALFWORD(coder_b->firmware[PRG_DESC_WORK_BEGIN_ADR], + coder_b->firmware[PRG_DESC_WORK_BEGIN_ADR + 1]); + + work_size_a = MAKE_HALFWORD(coder_a->firmware[PRG_DESC_WORK_SIZE], + coder_a->firmware[PRG_DESC_WORK_SIZE + 1]); + work_size_b = MAKE_HALFWORD(coder_b->firmware[PRG_DESC_WORK_SIZE], + coder_b->firmware[PRG_DESC_WORK_SIZE + 1]); + + stack_begin_a = + MAKE_HALFWORD(coder_a->firmware[PRG_DESC_STACK_BEGIN_ADR], + coder_a->firmware[PRG_DESC_STACK_BEGIN_ADR + 1]); + stack_begin_b = + MAKE_HALFWORD(coder_b->firmware[PRG_DESC_STACK_BEGIN_ADR], + coder_b->firmware[PRG_DESC_STACK_BEGIN_ADR + 1]); + + stack_size_a = MAKE_HALFWORD(coder_a->firmware[PRG_DESC_STACK_SIZE], + coder_a->firmware[PRG_DESC_STACK_SIZE + + 1]); + stack_size_b = + MAKE_HALFWORD(coder_b->firmware[PRG_DESC_STACK_SIZE], + coder_b->firmware[PRG_DESC_STACK_SIZE + 1]); + + /* Program & Program */ + ret = cdsp_memoryrange_check(prog_loadaddr_a, prog_size_a, + prog_loadaddr_b, prog_size_b); + if (ret < 0) + return ret; + + /* Data & Data */ + ret = cdsp_memoryrange_check(data_loadaddr_a, data_size_a, + data_loadaddr_b, data_size_b); + if (ret < 0) + return ret; + + /* Data & Stack */ + ret = cdsp_memoryrange_check(data_loadaddr_a, data_size_a, + stack_begin_b, stack_size_b); + if (ret < 0) + return ret; + + ret = cdsp_memoryrange_check(stack_begin_a, stack_size_a, + data_loadaddr_b, data_size_b); + if (ret < 0) + return ret; + + /* Work & Work */ + ret = cdsp_memoryrange_check(work_begin_a, work_size_a, + work_begin_b, work_size_b); + if (ret < 0) + return ret; + + /* Work & Stack */ + ret = cdsp_memoryrange_check(work_begin_a, work_size_a, + stack_begin_b, stack_size_b); + if (ret < 0) + return ret; + + return cdsp_memoryrange_check(stack_begin_a, stack_size_a, + work_begin_b, work_size_b); +} + +static int cdsp_inout_path_check(struct connection_info *conn, + struct connection_info *another_conn) +{ + /* Input */ + switch (conn->src) { + case CDSP_IN_SOURCE_OTHER_OUTBUF: + case CDSP_IN_SOURCE_NONE: + break; + /* DFIFO */ + case CDSP_IN_SOURCE_DFIFO: + switch (another_conn->src) { + case CDSP_IN_SOURCE_EFIFO: + case CDSP_IN_SOURCE_OTHER_OUTBUF: + case CDSP_IN_SOURCE_NONE: + break; + default: + return -EINVAL; + } + break; + /* EFIFO */ + case CDSP_IN_SOURCE_EFIFO: + switch (another_conn->src) { + case CDSP_IN_SOURCE_DFIFO: + case CDSP_IN_SOURCE_OTHER_OUTBUF: + case CDSP_IN_SOURCE_NONE: + break; + default: + return -EINVAL; + } + break; + /* DFIFO & EFIFO */ + case CDSP_IN_SOURCE_DFIFO_EFIFO: + switch (another_conn->src) { + case CDSP_IN_SOURCE_OTHER_OUTBUF: + case CDSP_IN_SOURCE_NONE: + break; + default: + return -EINVAL; + } + default: + return -EIO; + } + + /* output */ + switch (conn->dest) { + case CDSP_OUT_DEST_OTHER_INBUF: + case CDSP_OUT_DEST_NONE: + break; + /* RFIFO */ + case CDSP_OUT_DEST_RFIFO: + switch (another_conn->dest) { + case CDSP_OUT_DEST_OFIFO: + case CDSP_OUT_DEST_OTHER_INBUF: + case CDSP_OUT_DEST_NONE: + break; + default: + return -EINVAL; + } + break; + /* OFIFO */ + case CDSP_OUT_DEST_OFIFO: + switch (another_conn->dest) { + case CDSP_OUT_DEST_RFIFO: + case CDSP_OUT_DEST_OTHER_INBUF: + case CDSP_OUT_DEST_NONE: + break; + default: + return -EINVAL; + } + break; + /* RFIFO & OFIFO */ + case CDSP_OUT_DEST_OFIFO_RFIFO: + switch (another_conn->dest) { + case CDSP_OUT_DEST_OTHER_INBUF: + case CDSP_OUT_DEST_NONE: + break; + default: + return -EINVAL; + } + break; + default: + break; + } + + return 0; +} + +static inline int cdsp_inout_type_check(struct connection_info *conn_info, + u16 inout_type) +{ + u16 in_type, out_type; + + in_type = inout_type & PRG_PRM_IOTYPE_IN_MASK; + out_type = inout_type & PRG_PRM_IOTYPE_OUT_MASK; + + /* Input type check */ + if (in_type == PRG_PRM_IOTYPE_IN_NOPCM) { + switch (conn_info->src) { + case CDSP_IN_SOURCE_NONE: + case CDSP_IN_SOURCE_DFIFO: + break; + default: + return -EIO; + } + } + + /* Output type check */ + if (out_type == PRG_PRM_IOTYPE_OUT_NOPCM) { + switch (conn_info->dest) { + case CDSP_OUT_DEST_NONE: + case CDSP_OUT_DEST_RFIFO: + break; + default: + return -EIO; + } + } + + return 0; +} + +static inline int cdsp_path_check(enum mc_cdsp_id id, u16 inout_type, + struct connection_info *conn_info) +{ + struct coder_info *another_info; + u8 state; + int ret; + + another_info = cdsp_coder_info_get(cdsp_another_id_get(id)); + + state = another_info->state; + if (state == STATE_READY_SETUP || state == STATE_READY || + state == STATE_PLAYING) { + /* Check Input/Output path */ + ret = + cdsp_inout_path_check(conn_info, &another_info->conn_info); + if (ret < 0) + return ret; + } + + /* Check Input/Output Type */ + return cdsp_inout_type_check(conn_info, inout_type); +} + +static int cdsp_data_analyze_coder(enum mc_cdsp_id id, + struct aec_cdsp_info *cdsp_info) +{ + struct aec_cdsp_func_info *finfo; + struct coder_info *cinfo; + struct coder_firmware coder; + u8 *data; + u32 data_size; + u32 top, tag, size, tmp; + int ret; + + if (id == CDSP_DECODER) + finfo = &cdsp_info->func_info[AEC_FUNC_INFO_A]; + else + finfo = &cdsp_info->func_info[AEC_FUNC_INFO_B]; + + data = finfo->data; + data_size = finfo->data_size; + finfo->fifo_data = NULL; + finfo->prog_data = NULL; + finfo->prog_size = 0; + finfo->param_data = NULL; + finfo->param_num = 0; + finfo->ext = NULL; + + cinfo = cdsp_coder_info_get(id); + finfo->conn_info.src = cinfo->conn_info.src; + finfo->conn_info.dest = cinfo->conn_info.dest; + finfo->conn_ex_info.efifo_ch = cinfo->conn_ex_info.efifo_ch; + finfo->conn_ex_info.ofifo_ch = cinfo->conn_ex_info.ofifo_ch; + finfo->bit_width.efifo = cinfo->bit_width.efifo; + finfo->bit_width.ofifo = cinfo->bit_width.ofifo; + finfo->format.fs = cinfo->format.fs; + finfo->format.etobuf = cinfo->format.etobuf; + + if (!data || !data_size) + return 0; + + top = 0; + while (top < data_size) { + if (top + CHUNK_SIZE > data_size) + return -EINVAL; + + tag = htonl(*(u32 *) (data + top)); + size = htonl(*(u32 *) (data + top + 4)); + if (top + CHUNK_SIZE + size > data_size) + return -EINVAL; + + top += CHUNK_SIZE; + switch (tag) { + case AEC_CDSP_TAG_PROG: + if (size < PROG_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top)); + if (!tmp) + return 0; + if (tmp + PROG_FIX_SIZE > size) + return -EINVAL; + if (finfo->prog_data) + return -EINVAL; + + finfo->prog_data = &data[top + PROG_FIX_SIZE]; + finfo->prog_size = tmp; + break; + case AEC_CDSP_TAG_PRM: + if (size < PRM_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top)); + if (!tmp) + return 0; + if (tmp % PRM_UNIT_SIZE) + return -EINVAL; + if (tmp + PRM_FIX_SIZE > size) + return -EINVAL; + if (finfo->param_data) + return -EINVAL; + + finfo->param_data = &data[top + PRM_FIX_SIZE]; + finfo->param_num = tmp / PRM_UNIT_SIZE; + break; + case AEC_CDSP_TAG_FIFO: + if (size < FIFO_FIX_SIZE) + return -EINVAL; + if (finfo->fifo_data) + return -EINVAL; + + finfo->fifo_data = &data[top]; + break; + case AEC_CDSP_TAG_EXT: + if (size < EXT_FIX_SIZE) + return -EINVAL; + + if (finfo->ext) + return -EINVAL; + + finfo->ext = &data[top]; + break; + default: + break; + } + + top += size; + } + + /* FIFO Check */ + if (finfo->fifo_data) { + ret = cdsp_fifo_check(id, cdsp_info); + if (ret < 0) + return ret; + } + + /* Program Check */ + if (finfo->prog_size && finfo->prog_data) { + coder.firmware = finfo->prog_data; + coder.size = finfo->prog_size; + + ret = cdsp_program_check(id, &coder); + if (ret < 0) + return ret; + + cinfo->prog_info.inout_type = + MAKE_HALFWORD(coder.firmware[PRG_DESC_OUTPUT_TYPE], + coder.firmware[PRG_DESC_OUTPUT_TYPE + 1]); + } + + return cdsp_path_check(id, cinfo->prog_info.inout_type, + &finfo->conn_info); +} + +static int cdsp_data_analyze(struct aec_cdsp_info *cdsp_info) +{ + struct aec_cdsp_func_info *finfo_a; + struct aec_cdsp_func_info *finfo_b; + struct coder_firmware coder_a; + struct coder_firmware coder_b; + int ret; + + finfo_a = &cdsp_info->func_info[AEC_FUNC_INFO_A]; + finfo_b = &cdsp_info->func_info[AEC_FUNC_INFO_B]; + cdsp_info->dfifo_cb_pos = mc_fifo_info.dfifo_cb_pos; + cdsp_info->rfifo_cb_pos = mc_fifo_info.rfifo_cb_pos; + cdsp_info->ofifo_buf_sample = mc_fifo_info.ofifo_buf_sample; + cdsp_info->rfifo_buf_sample = mc_fifo_info.rfifo_buf_sample; + cdsp_info->out0_sel = mc_fifo_info.out0_sel; + cdsp_info->out1_sel = mc_fifo_info.out1_sel; + cdsp_info->out2_sel = mc_fifo_info.out2_sel; + cdsp_info->rdfifo_bit_sel = mc_fifo_info.rdfifo_bit_sel; + cdsp_info->efifo01_sel = mc_fifo_info.efifo01_sel; + cdsp_info->efifo23_sel = mc_fifo_info.efifo23_sel; + + ret = cdsp_data_analyze_coder(CODER_DEC, cdsp_info); + if (ret < 0) + return ret; + + ret = cdsp_data_analyze_coder(CODER_ENC, cdsp_info); + if (ret < 0) + return ret; + + if (finfo_a->fifo_data && finfo_b->fifo_data) { + ret = cdsp_inout_path_check(&finfo_a->conn_info, + &finfo_b->conn_info); + if (ret < 0) + return ret; + } + + if (finfo_a->prog_size && finfo_a->prog_data && + finfo_b->prog_size && finfo_b->prog_data) { + coder_a.firmware = finfo_a->prog_data; + coder_a.size = finfo_a->prog_size; + coder_b.firmware = finfo_b->prog_data; + coder_b.size = finfo_b->prog_size; + ret = cdsp_aec_program_check(&coder_a, &coder_b); + } + + return ret; +} + +static inline void cdsp_output_format_notify_complete(enum mc_cdsp_id id) +{ + struct coder_info *another_info; + struct coder_params coder; + + another_info = cdsp_coder_info_get(cdsp_another_id_get(id)); + + /* Complete NotifyOutFormat */ + if (another_info->format_propagate) { + coder.command = CDSP_CMD_OS2HOST_CMN_NOTIFY_OUT_FORMAT; + coder.params[CDSP_CMD_PARAM_RESULT_00] = 0; + coder.params[CDSP_CMD_PARAM_RESULT_01] = 0; + coder.params[CDSP_CMD_PARAM_RESULT_02] = 0; + coder.params[CDSP_CMD_PARAM_RESULT_03] = 0; + cdsp_command_write_complete(id, &coder); + + another_info->format_propagate = false; + } +} + +static void cdsp_coder_close(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + u32 int_reg; + u8 ctl, int_data, ctl_data; + int ret; + + info = cdsp_coder_info_get(id); + + cdsp_output_format_notify_complete(id); + + /* Reset command */ + coder.command = CDSP_CMD_HOST2OS_CMN_RESET; + ret = cdsp_command_write_host2os(id, &coder); + + /* Command register Initialize */ + cdsp_command_init(id); + + /* DEC/ENC SFR,EVT Disable */ + if (id == CDSP_DECODER) { + int_reg = MCI_DEC_ENABLE; + ctl = MCB_EDEC; + } else { + int_reg = MCI_ENC_ENABLE; + ctl = MCB_EENC; + } + + mc_read_c(int_reg, &int_data, 1); + + int_data &= ~(MCB_EDEC_EVT | MCB_EDEC_SFR); + + mc_read_digital(MCI_ECDSP, &ctl_data, 1); + ctl_data &= ~ctl; + mc_packet_add_force_write_if(MCI_ECDSP, ctl_data); + + mc_packet_add_force_write_c(int_reg, int_data); + + mc_packet_execute(); + + info->format.fs = CODER_FMT_FS_48000; + +} + +static void cdsp_program_terminate(enum mc_cdsp_id id) +{ + struct coder_params coder; + struct coder_info *info; + + coder.command = CDSP_CMD_HOST2OS_SYS_TERMINATE; + cdsp_command_write_host2os(id, &coder); + + info = cdsp_coder_info_get(id); + info->prog_info.vendor_id = 0; + info->prog_info.function_id = 0; +} + +static int cdsp_program_write(struct fsq_data_info *fsq) +{ + u8 data; + u16 load_addr, remain; + u32 current, writes, i; + int ret = 0; + + load_addr = fsq->load_addr; + current = 0; + remain = fsq->size; + + /* CDSP_MSEL Set */ + mc_read_c(MCI_CDSP_RESET, &data, 1); + + if (fsq->scramble == PRG_PRM_SCRMBL_DISABLE) + data |= MCB_CDSP_FMODE; + else + data &= ~MCB_CDSP_FMODE; + + data &= ~MCB_CDSP_MSEL; + + if (fsq->msel == MSEL_PROG) + data |= MCB_CDSP_MSEL_PROG; + else + data |= MCB_CDSP_MSEL_DATA; + + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + + mc_packet_execute(); + + while (remain > 0 && !ret) { + /* CDSP_MAR Set */ + mc_packet_add_force_write_c(MCI_CDSP_MAR_H, + HIGH_BYTE(load_addr)); + mc_packet_add_force_write_c(MCI_CDSP_MAR_L, + LOW_BYTE(load_addr)); + + mc_packet_execute(); + + /* fill FFIFO */ + writes = FIFOSIZE_FFIFO / sizeof(u16); + if (writes > remain) + writes = remain; + + for (i = 0; i < writes * 2; ++i) + mc_packet_add_force_write_if(MCI_FSQ_FFIFO, + fsq->data[current * 2 + + i]); + + mc_packet_execute(); + + load_addr += writes; + current += writes; + remain -= writes; + + /* FFIFO_FLG Clear */ + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_FFIFO); + + /* FSQ_END_FLG Clear */ + mc_packet_add_force_write_c(MCI_FFIFO_FLG, + MCB_FFIFO_FLG_FSQ_END); + + mc_packet_execute(); + + /* FSQ_START Set */ + mc_read_c(MCI_DEC_START, &data, 1); + data |= MCB_DEC_FSQ_START; + mc_packet_add_force_write_c(MCI_DEC_START, data); + + mc_packet_execute(); + + /* FSQ_END_FLG Polling */ + mc_packet_add_wait_event(MCDRV_EVT_C_REG_FLAG_SET | + (MCI_FFIFO_FLG << 8) | + MCB_FFIFO_FLG_FSQ_END); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* FSQ_START Clear */ + mc_read_c(MCI_DEC_START, &data, 1); + data &= ~MCB_DEC_FSQ_START; + mc_packet_add_force_write_c(MCI_DEC_START, data); + + mc_packet_execute(); + } + + /* FFIFO_FLG Clear */ + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_FFIFO); + + /* FSQ_END_FLG Clear */ + mc_packet_add_force_write_c(MCI_FFIFO_FLG, MCB_FFIFO_FLG_FSQ_END); + + mc_packet_execute(); + + return ret; +} + +static inline int cdsp_program_download(u8 *firmware) +{ + struct fsq_data_info fsq[2]; + u8 data; + int ret; + + /* CDSP_SAVEOFF Set */ + mc_packet_add_force_write_c(MCI_PWM_DIGITAL_CDSP, MCB_PWM_CDSP_SAVEOFF); + + mc_packet_execute(); + + /* CDSP_HALT_MODE Check */ + mc_packet_add_wait_event(MCDRV_EVT_C_REG_FLAG_RESET | + (MCI_CDSP_POWER_MODE << 8) | + MCB_CDSP_HLT_MODE_SLEEP_HALT); + + ret = mc_packet_execute(); + if (ret < 0) { + mc_packet_add_force_write_c(MCI_PWM_DIGITAL_CDSP, 0); + + mc_packet_execute(); + + return ret; + } + + /* FSQ_SRST */ + mc_read_c(MCI_CDSP_RESET, &data, 1); + data |= MCB_CDSP_FSQ_SRST; + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + data &= ~MCB_CDSP_FSQ_SRST; + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + + /* 150ns wait */ + mc_packet_add_wait(1); + + mc_packet_execute(); + + /* FFIFO_RST */ + mc_read_c(MCI_DEC_FIFO_RST, &data, 1); + data |= MCB_DEC_FFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + data &= ~MCB_DEC_FFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + + mc_packet_execute(); + + /* Transfer Program & Data */ + fsq[0].data = &firmware[PRG_DESC_PROGRAM]; + fsq[0].size = MAKE_HALFWORD(firmware[PRG_DESC_PRG_SIZE], + firmware[PRG_DESC_PRG_SIZE + 1]); + fsq[0].load_addr = MAKE_HALFWORD(firmware[PRG_DESC_PRG_LOAD_ADR], + firmware[PRG_DESC_PRG_LOAD_ADR + 1]); + fsq[0].scramble = MAKE_HALFWORD(firmware[PRG_DESC_PRG_SCRAMBLE], + firmware[PRG_DESC_PRG_SCRAMBLE + 1]); + fsq[0].msel = MSEL_PROG; + + fsq[1].data = &fsq[0].data[(u32) fsq[0].size * 2]; + fsq[1].size = MAKE_HALFWORD(firmware[PRG_DESC_DATA_SIZE], + firmware[PRG_DESC_DATA_SIZE + 1]); + fsq[1].load_addr = MAKE_HALFWORD(firmware[PRG_DESC_DATA_LOAD_ADR], + firmware[PRG_DESC_DATA_LOAD_ADR + 1]); + fsq[1].scramble = MAKE_HALFWORD(firmware[PRG_DESC_DATA_SCRAMBLE], + firmware[PRG_DESC_DATA_SCRAMBLE + 1]); + fsq[1].msel = MSEL_DATA; + + ret = cdsp_program_write(&fsq[0]); + if (!ret) + ret = cdsp_program_write(&fsq[1]); + + /* CDSP_SAVEOFF Clear */ + mc_packet_add_force_write_c(MCI_PWM_DIGITAL_CDSP, 0); + + mc_packet_execute(); + + return ret; +} + +static inline int cdsp_program_init(enum mc_cdsp_id id, + struct coder_firmware *coderf) +{ + struct coder_info *info; + struct coder_params coderp; + u16 data_loadaddr; + u16 work_begin; + u16 data_addr; + u16 data_size; + u8 *firmware; + int ret; + + firmware = coderf->firmware; + data_loadaddr = MAKE_HALFWORD(firmware[PRG_DESC_DATA_LOAD_ADR], + firmware[PRG_DESC_DATA_LOAD_ADR + 1]); + work_begin = MAKE_HALFWORD(firmware[PRG_DESC_WORK_BEGIN_ADR], + firmware[PRG_DESC_WORK_BEGIN_ADR + 1]); + if (data_loadaddr < work_begin) + data_addr = data_loadaddr; + else + data_addr = work_begin; + data_size = MAKE_HALFWORD(firmware[PRG_DESC_DATA_SIZE], + firmware[PRG_DESC_DATA_SIZE + 1]); + data_size = data_size + MAKE_HALFWORD(firmware[PRG_DESC_WORK_SIZE], + firmware[PRG_DESC_WORK_SIZE + 1]); + + /* SetProgramInfo command */ + coderp.command = CDSP_CMD_HOST2OS_SYS_SET_PRG_INFO; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_00] = LOW_BYTE(data_addr); + coderp.params[CDSP_CMD_PARAM_ARGUMENT_01] = HIGH_BYTE(data_addr); + coderp.params[CDSP_CMD_PARAM_ARGUMENT_02] = LOW_BYTE(data_size); + coderp.params[CDSP_CMD_PARAM_ARGUMENT_03] = HIGH_BYTE(data_size); + coderp.params[CDSP_CMD_PARAM_ARGUMENT_04] = + firmware[PRG_DESC_ENTRY_ADR]; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_05] = + firmware[PRG_DESC_ENTRY_ADR + 1]; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_06] = + firmware[PRG_DESC_STACK_BEGIN_ADR]; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_07] = + firmware[PRG_DESC_STACK_BEGIN_ADR + 1]; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_08] = + firmware[PRG_DESC_STACK_SIZE]; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_09] = + firmware[PRG_DESC_STACK_SIZE + 1]; + coderp.params[CDSP_CMD_PARAM_ARGUMENT_10] = + firmware[PRG_DESC_RESOURCE_FLAG]; + ret = cdsp_command_write_host2os(id, &coderp); + if (ret < 0) + return ret; + + /* Reset command */ + coderp.command = CDSP_CMD_HOST2OS_CMN_RESET; + ret = cdsp_command_write_host2os(id, &coderp); + if (ret < 0) + return ret; + + /* GetProgramVersion command */ + coderp.command = CDSP_CMD_HOST2OS_CMN_GET_PRG_VER; + ret = cdsp_command_write_host2os(id, &coderp); + if (ret < 0) + return ret; + + info = cdsp_coder_info_get(id); + info->program.version_h = + MAKE_HALFWORD(coderp.params[CDSP_CMD_PARAM_RESULT_00], + coderp.params[CDSP_CMD_PARAM_RESULT_01]); + info->program.version_l = + MAKE_HALFWORD(coderp.params[CDSP_CMD_PARAM_RESULT_02], + coderp.params[CDSP_CMD_PARAM_RESULT_03]); + + info->prog_info.vendor_id = MAKE_HALFWORD(firmware[PRG_DESC_VENDER_ID], + firmware[PRG_DESC_VENDER_ID + + 1]); + info->prog_info.function_id = + MAKE_HALFWORD(firmware[PRG_DESC_FUNCTION_ID], + firmware[PRG_DESC_FUNCTION_ID + 1]); + info->prog_info.prog_type = + MAKE_HALFWORD(firmware[PRG_DESC_PRG_TYPE], + firmware[PRG_DESC_PRG_TYPE + 1]); + info->prog_info.inout_type = + MAKE_HALFWORD(firmware[PRG_DESC_OUTPUT_TYPE], + firmware[PRG_DESC_OUTPUT_TYPE + 1]); + info->prog_info.prog_scramble = + MAKE_HALFWORD(firmware[PRG_DESC_PRG_SCRAMBLE], + firmware[PRG_DESC_PRG_SCRAMBLE + 1]); + info->prog_info.data_scramble = + MAKE_HALFWORD(firmware[PRG_DESC_DATA_SCRAMBLE], + firmware[PRG_DESC_DATA_SCRAMBLE + 1]); + info->prog_info.entry_addr = + MAKE_HALFWORD(firmware[PRG_DESC_ENTRY_ADR], + firmware[PRG_DESC_ENTRY_ADR + 1]); + info->prog_info.prog_loadaddr = + MAKE_HALFWORD(firmware[PRG_DESC_PRG_LOAD_ADR], + firmware[PRG_DESC_PRG_LOAD_ADR + 1]); + info->prog_info.prog_size = + MAKE_HALFWORD(firmware[PRG_DESC_PRG_SIZE], + firmware[PRG_DESC_PRG_SIZE + 1]); + info->prog_info.data_loadaddr = + MAKE_HALFWORD(firmware[PRG_DESC_DATA_LOAD_ADR], + firmware[PRG_DESC_DATA_LOAD_ADR + 1]); + info->prog_info.data_size = + MAKE_HALFWORD(firmware[PRG_DESC_DATA_SIZE], + firmware[PRG_DESC_DATA_SIZE + 1]); + info->prog_info.work_begin = + MAKE_HALFWORD(firmware[PRG_DESC_WORK_BEGIN_ADR], + firmware[PRG_DESC_WORK_BEGIN_ADR + 1]); + info->prog_info.work_size = + MAKE_HALFWORD(firmware[PRG_DESC_WORK_SIZE], + firmware[PRG_DESC_WORK_SIZE + 1]); + info->prog_info.stack_begin = + MAKE_HALFWORD(firmware[PRG_DESC_STACK_BEGIN_ADR], + firmware[PRG_DESC_STACK_BEGIN_ADR + 1]); + info->prog_info.stack_size = + MAKE_HALFWORD(firmware[PRG_DESC_STACK_SIZE], + firmware[PRG_DESC_STACK_SIZE + 1]); + info->prog_info.output_start_mode = + MAKE_HALFWORD(firmware[PRG_DESC_OUTSTARTMODE], + firmware[PRG_DESC_OUTSTARTMODE + 1]); + info->prog_info.resource_flag = + MAKE_HALFWORD(firmware[PRG_DESC_RESOURCE_FLAG], + firmware[PRG_DESC_RESOURCE_FLAG + 1]); + info->prog_info.max_load = + MAKE_HALFWORD(firmware[PRG_DESC_MAX_LOAD], + firmware[PRG_DESC_MAX_LOAD + 1]); + + return 0; +} + +static void cdsp_fifo_reset(enum mc_cdsp_id id, u32 fifo) +{ + u32 fifo_id; + u8 data; + + fifo_id = cdsp_fifoid_get_from_coderid(id); + mc_read_c(MCI_DEC_FIFO_RST, &data, 1); + + if ((fifo & FIFO_DFIFO_MASK) && (fifo_id & FIFO_DFIFO_MASK)) { + /* DFIFO Reset */ + data |= MCB_DEC_DFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + data &= ~MCB_DEC_DFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + + mc_fifo_info.dfifo_write_size = 0; + } + + if ((fifo & FIFO_EFIFO_MASK) && (fifo_id & FIFO_EFIFO_MASK)) { + /* EFIFO Reset */ + data |= MCB_DEC_EFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + data &= ~MCB_DEC_EFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + } + + if ((fifo & FIFO_OFIFO_MASK) && (fifo_id & FIFO_OFIFO_MASK)) { + /* OFIFO Reset */ + data |= MCB_DEC_OFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + data &= ~MCB_DEC_OFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + } + + if ((fifo & FIFO_RFIFO_MASK) && (fifo_id & FIFO_RFIFO_MASK)) { + /* RFIFO Reset */ + data |= MCB_DEC_RFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + data &= ~MCB_DEC_RFIFO_RST; + mc_packet_add_force_write_c(MCI_DEC_FIFO_RST, data); + } + + mc_packet_execute(); +} + +static void cdsp_fifo_init(enum mc_cdsp_id id, u32 fifo) +{ + u32 fifo_id; + + fifo_id = cdsp_fifoid_get_from_coderid(id); + + if ((fifo & FIFO_DFIFO_MASK) && (fifo_id & FIFO_DFIFO_MASK)) { + mc_fifo_info.dfifo_cb_pos = CBPOS_DFIFO_DEF; + mc_fifo_info.dfifo_write_size = 0; + } + + if ((fifo & FIFO_OFIFO_MASK) && (fifo_id & FIFO_OFIFO_MASK)) + mc_fifo_info.ofifo_buf_sample = OFIFO_BUF_SAMPLE_DEF; + + if ((fifo & FIFO_RFIFO_MASK) && (fifo_id & FIFO_RFIFO_MASK)) { + mc_fifo_info.rfifo_cb_pos = CBPOS_RFIFO_DEF; + mc_fifo_info.rfifo_buf_sample = RFIFO_BUF_SAMPLE_DEF; + } + + cdsp_fifo_reset(id, fifo); +} + +static u8 cdsp_fifo_set_ch(u32 fifo, u8 ch) +{ + u8 data, old_ch = 0; + + mc_read_c(MCI_DEC_FIFO_CH, &data, 1); + + if (fifo & FIFO_EFIFO_MASK) { + old_ch |= data & MCB_DEC_EFIFO_CH; + data &= ~MCB_DEC_EFIFO_CH; + data |= ch & MCB_DEC_EFIFO_CH; + } + + if (fifo & FIFO_OFIFO_MASK) { + old_ch |= data & MCB_DEC_OFIFO_CH; + data &= ~MCB_DEC_OFIFO_CH; + data |= ch & MCB_DEC_OFIFO_CH; + } + + mc_packet_add_write_c(MCI_DEC_FIFO_CH, data); + + mc_packet_execute(); + + return old_ch; +} + +static u8 cdsp_fifo_get_ch_bit(u32 fifo, + struct connection_ex_info *conn_ex_info, + struct bit_width_info *bit_width) +{ + u8 data = 0; + + if (fifo & FIFO_EFIFO_MASK) { + if (conn_ex_info->efifo_ch == 4) { + if (bit_width->efifo == 32) + data |= MCB_DEC_EFIFO_CH_4_32; + else + data |= MCB_DEC_EFIFO_CH_4_16; + } else { + if (bit_width->efifo == 32) + data |= MCB_DEC_EFIFO_CH_2_32; + else + data |= MCB_DEC_EFIFO_CH_2_16; + } + } + + if (fifo & FIFO_OFIFO_MASK) { + if (conn_ex_info->ofifo_ch == 4) { + if (bit_width->ofifo == 32) + data |= MCB_DEC_OFIFO_CH_4_32; + else + data |= MCB_DEC_OFIFO_CH_4_16; + } else { + if (bit_width->ofifo == 32) + data |= MCB_DEC_OFIFO_CH_2_32; + else + data |= MCB_DEC_OFIFO_CH_2_16; + } + } + + return data; +} + +static inline u8 cdsp_fifo_reset_ch(enum mc_cdsp_id id) +{ + struct coder_info *info; + u32 fifo_id; + u8 data; + + info = cdsp_coder_info_get(id); + + fifo_id = cdsp_fifoid_get_from_coderid(id); + data = + cdsp_fifo_get_ch_bit(fifo_id, &info->conn_ex_info, + &info->bit_width); + + data = cdsp_fifo_set_ch(fifo_id, data); + + return data; +} + +static int cdsp_connection_reset(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + int ret; + + info = cdsp_coder_info_get(id); + + coder.command = CDSP_CMD_HOST2OS_SYS_SET_CONNECTION; + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = info->conn_info.src; + coder.params[CDSP_CMD_PARAM_ARGUMENT_01] = info->conn_info.dest; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + cdsp_fifo_reset_ch(id); + + return ret; +} + +static int cdsp_coder_open(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + u8 data; + int ret; + + info = cdsp_coder_info_get(id); + + /* Command register Initialize */ + cdsp_command_init(id); + + /* TimerReset command (Off) */ + coder.command = CDSP_CMD_HOST2OS_SYS_TIMER_RESET; + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = TIMERRESET_OFF; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + /* DEC/ENC SFR,EVT Interrupt flag clear */ + if (id == CDSP_DECODER) { + mc_read_c(MCI_DEC_FLG, &data, 1); + data |= MCB_ENC_FLG_SFR | MCB_DEC_EVT_FLG; + mc_packet_add_force_write_c(MCI_DEC_FLG, data); + } else { + mc_read_c(MCI_ENC_FLG, &data, 1); + data |= MCB_ENC_FLG_SFR | MCB_ENC_EVT_FLG; + mc_packet_add_force_write_c(MCI_ENC_FLG, data); + } + + mc_packet_execute(); + + mc_read_digital(MCI_CDSP, &data, 1); + if (id == CDSP_DECODER) + data |= MCB_IRQFLAG_DEC; + else + data |= MCB_IRQFLAG_ENC; + mc_packet_add_force_write_if(MCI_CDSP, data); + + mc_packet_execute(); + + /* DEC/ENC SFR,EVT Interrupt Enable */ + if (id == CDSP_DECODER) { + mc_read_c(MCI_DEC_ENABLE, &data, 1); + data |= MCB_EDEC_SFR | MCB_EDEC_EVT; + mc_packet_add_force_write_c(MCI_DEC_ENABLE, data); + } else { + mc_read_c(MCI_ENC_ENABLE, &data, 1); + data |= MCB_EENC_SFR | MCB_EENC_EVT; + mc_packet_add_force_write_c(MCI_ENC_ENABLE, data); + } + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + if (id == CDSP_DECODER) + data |= MCB_EDEC; + else + data |= MCB_EENC; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + + /* Initialize */ + memset(info, 0, sizeof(struct coder_info)); + info->format.fs = CODER_FMT_FS_48000; + info->format.etobuf = CODER_FMT_ETOBUF_LRMIX; + info->conn_info.src = CDSP_IN_SOURCE_NONE; + info->conn_info.dest = CDSP_OUT_DEST_NONE; + info->conn_ex_info.efifo_ch = 2; + info->conn_ex_info.ofifo_ch = 2; + info->bit_width.efifo = 16; + info->bit_width.ofifo = 16; + + cdsp_fifo_init(id, FIFO_DFIFO | FIFO_EFIFO | FIFO_OFIFO | FIFO_RFIFO); + + return cdsp_connection_reset(id); +} + +static int cdsp_coder_reset(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + int ret; + + info = cdsp_coder_info_get(id); + + /* Reset command */ + coder.command = CDSP_CMD_HOST2OS_CMN_RESET; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + cdsp_output_format_notify_complete(id); + + /* Command register Initialize */ + cdsp_command_init(id); + + /* Input data end flag - release */ + info->preinput_dataend_set = false; + info->input_dataend_set = false; + + info->format.fs = CODER_FMT_FS_48000; + info->format.etobuf = CODER_FMT_ETOBUF_LRMIX; + + return 0; +} + +static void cdsp_input_position_clear(enum mc_cdsp_id id) +{ + struct coder_info *info; + + info = cdsp_coder_info_get(id); + + if (info->conn_info.src != CDSP_IN_SOURCE_EFIFO && + info->conn_info.src != CDSP_IN_SOURCE_DFIFO_EFIFO) + return; + + /* ENC_POS Write (Suitable value) */ + mc_packet_add_force_write_c(MCI_ENC_POS4, 0); + + mc_packet_execute(); + + info->input_pos = 0; +} + +static void cdsp_input_position_reset(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + + info = cdsp_coder_info_get(id); + + if (info->conn_info.src != CDSP_IN_SOURCE_OTHER_OUTBUF) + return; + + coder.command = CDSP_CMD_HOST2OS_SYS_RESET_INPUT_POS; + cdsp_command_write_host2os(id, &coder); + + info->input_pos = 0; +} + +static void cdsp_output_position_clear(enum mc_cdsp_id id) +{ + struct coder_info *info; + + info = cdsp_coder_info_get(id); + + if (info->conn_info.dest != CDSP_OUT_DEST_OFIFO && + info->conn_info.dest != CDSP_OUT_DEST_OFIFO_RFIFO) + return; + + /* DEC_POS Write (Suitable value) */ + mc_packet_add_force_write_c(MCI_DEC_POS4, 0); + + mc_packet_execute(); +} + +static int cdsp_coder_clear(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + int ret; + + info = cdsp_coder_info_get(id); + + /* State check */ + if (info->state != STATE_READY_SETUP && info->state != STATE_READY) + return -EBUSY; + + /* Clear command */ + coder.command = CDSP_CMD_HOST2OS_CMN_CLEAR; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + cdsp_output_format_notify_complete(id); + + /* TimerReset command (Reset) */ + coder.command = CDSP_CMD_HOST2OS_SYS_TIMER_RESET; + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = TIMERRESET_RESET; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + /* ChangeOutSamplingRate - Not complete */ + info->change_output_fs = false; + + /* Input data end state - release */ + info->preinput_dataend_set = false; + info->input_dataend_set = false; + + /* Output Start - clear */ + switch (info->conn_info.dest) { + case CDSP_OUT_DEST_OFIFO: + mc_fifo_info.ofifo_output_start = false; + break; + case CDSP_OUT_DEST_OFIFO_RFIFO: + mc_fifo_info.ofifo_output_start = false; + mc_fifo_info.rfifo_output_start = false; + break; + case CDSP_OUT_DEST_RFIFO: + mc_fifo_info.rfifo_output_start = false; + break; + default: + break; + } + + return 0; +} + +static inline int cdsp_format_set(enum mc_cdsp_id id, + struct coder_params *coder) +{ + struct coder_info *info; + struct coder_params tmp; + int ret; + + info = cdsp_coder_info_get(id); + + /* State check */ + if (info->state != STATE_READY_SETUP) + return -EBUSY; + + /* Argument check */ + switch (coder->params[CDSP_CMD_PARAM_ARGUMENT_00]) { + case CODER_FMT_FS_48000: + case CODER_FMT_FS_44100: + case CODER_FMT_FS_32000: + case CODER_FMT_FS_24000: + case CODER_FMT_FS_22050: + case CODER_FMT_FS_16000: + case CODER_FMT_FS_12000: + case CODER_FMT_FS_11025: + case CODER_FMT_FS_8000: + break; + default: + return -EINVAL; + } + + switch (coder->params[CDSP_CMD_PARAM_ARGUMENT_01]) { + case CODER_FMT_ETOBUF_LRMIX: + case CODER_FMT_ETOBUF_LCH: + case CODER_FMT_ETOBUF_RCH: + break; + default: + return -EINVAL; + } + + tmp.command = coder->command; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_00] = + coder->params[CDSP_CMD_PARAM_ARGUMENT_00]; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_01] = + coder->params[CDSP_CMD_PARAM_ARGUMENT_01]; + ret = cdsp_command_write_host2os(id, &tmp); + if (ret < 0) + return ret; + + info->format.fs = tmp.params[CDSP_CMD_PARAM_ARGUMENT_00]; + info->format.etobuf = tmp.params[CDSP_CMD_PARAM_ARGUMENT_01]; + + return 0; +} + +static int cdsp_input_dataend_set(enum mc_cdsp_id id) +{ + struct coder_info *info; + u8 state, src; + int ret; + + info = cdsp_coder_info_get(id); + state = info->state; + + /* State check */ + switch (state) { + case STATE_READY_SETUP: + case STATE_READY: + case STATE_PLAYING: + break; + default: + return -EBUSY; + } + + /* Path check */ + src = info->conn_info.src; + if (src != CDSP_IN_SOURCE_DFIFO && src != CDSP_IN_SOURCE_DFIFO_EFIFO) + return -EIO; + + if (state == STATE_READY_SETUP) { + info->preinput_dataend_set = true; + return 0; + } + + info->preinput_dataend_set = false; + + /* FormatPropagate flag clear */ + info->format_propagate = false; + + /* InputDataEnd command */ + ret = cdsp_command_inputdataend(id); + if (ret < 0) + return ret; + + /* Input data end state - set */ + info->input_dataend_set = true; + + /* Output Start */ + cdsp_output_start(info); + + return 0; +} + +static int cdsp_timer_set(enum mc_cdsp_id id, struct coder_params *coder) +{ + struct coder_info *info; + struct coder_params tmp; + + info = cdsp_coder_info_get(id); + + /* State check */ + if (info->state != STATE_READY_SETUP && info->state != STATE_READY) + return -EBUSY; + + /* SetTimer command */ + tmp.command = coder->command; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_00] = + coder->params[CDSP_CMD_PARAM_ARGUMENT_00]; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_01] = + coder->params[CDSP_CMD_PARAM_ARGUMENT_01]; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_02] = + coder->params[CDSP_CMD_PARAM_ARGUMENT_02]; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_03] = + coder->params[CDSP_CMD_PARAM_ARGUMENT_03]; + return cdsp_command_write_host2os(id, &tmp); +} + +static inline int cdsp_output_set_dualmono(enum mc_cdsp_id id, + struct coder_params *coder) +{ + struct coder_info *info; + struct coder_params tmp; + + info = cdsp_coder_info_get(id); + + /* State check */ + switch (info->state) { + case STATE_READY_SETUP: + case STATE_READY: + case STATE_PLAYING: + break; + default: + return -EBUSY; + } + + /* Argument check */ + switch (coder->params[CDSP_CMD_PARAM_ARGUMENT_00]) { + case CODER_DUALMONO_LR: + case CODER_DUALMONO_L: + case CODER_DUALMONO_R: + break; + default: + return -EINVAL; + } + + /* Path check */ + switch (info->conn_info.dest) { + case CDSP_OUT_DEST_OFIFO: + case CDSP_OUT_DEST_OFIFO_RFIFO: + break; + default: + return -EIO; + } + + /* SetDualMono command */ + tmp.command = coder->command; + tmp.params[CDSP_CMD_PARAM_ARGUMENT_00] + = coder->params[CDSP_CMD_PARAM_ARGUMENT_00]; + return cdsp_command_write_host2os(id, &tmp); +} + +static int cdsp_input_get_position_sample(enum mc_cdsp_id id, + struct coder_params *coder) +{ + struct coder_info *info; + struct coder_params tmp; + u32 pos; + int ret; + + info = cdsp_coder_info_get(id); + + /* State check */ + switch (info->state) { + case STATE_READY_SETUP: + case STATE_READY: + case STATE_PLAYING: + break; + default: + return -EBUSY; + } + + /* Path check */ + if (info->conn_info.src != CDSP_IN_SOURCE_OTHER_OUTBUF) + return -EIO; + + /* pcm input ? */ + if ((info->prog_info.inout_type & PRG_PRM_IOTYPE_IN_MASK) != + PRG_PRM_IOTYPE_IN_PCM) + return -EIO; + + /* GetInputPos command */ + tmp.command = coder->command; + ret = cdsp_command_write_host2os(id, &tmp); + if (ret < 0) + return ret; + + /* InputPos */ + pos = (u32) tmp.params[CDSP_CMD_PARAM_RESULT_03] << 24 | + (u32) tmp.params[CDSP_CMD_PARAM_RESULT_02] << 16 | + (u32) tmp.params[CDSP_CMD_PARAM_RESULT_01] << 8 | + (u32) tmp.params[CDSP_CMD_PARAM_RESULT_00]; + + pos += info->input_pos; + + return pos; +} + +static inline int cdsp_coder_standby(enum mc_cdsp_id id) +{ + struct coder_info *info; + struct coder_params coder; + u32 fifo_id; + int ret; + + info = cdsp_coder_info_get(id); + + /* TimerReset command (Reset) */ + coder.command = CDSP_CMD_HOST2OS_SYS_TIMER_RESET; + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = TIMERRESET_RESET; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + /* Standby command */ + coder.command = CDSP_CMD_HOST2OS_CMN_STANDBY; + ret = cdsp_command_write_host2os(id, &coder); + if (ret < 0) + return ret; + + /* ChangeOutSamplingRate - Not complete */ + info->change_output_fs = false; + + fifo_id = cdsp_fifoid_get_from_coderid(id); + if (fifo_id & FIFO_OFIFO_MASK) + mc_fifo_info.ofifo_output_start = false; + + if (fifo_id & FIFO_RFIFO_MASK) + mc_fifo_info.rfifo_output_start = false; + + return 0; +} + +static void cdsp_coder_term(enum mc_cdsp_id id) +{ + struct coder_info *info; + u32 fifo; + + info = cdsp_coder_info_get(id); + + /* State check */ + switch (info->state) { + case STATE_PLAYING: + cdsp_coder_stop(id, MADEVCDSP_VERIFY_COMP_ON); + cdsp_fifo_stop(id); + case STATE_READY_SETUP: + case STATE_READY: + cdsp_coder_close(id); + + /* Terminate current program */ + cdsp_program_terminate(id); + break; + default: + return; + } + + fifo = cdsp_fifoid_get_from_coderid(id); + if (fifo & FIFO_DFIFO_MASK) + mc_fifo_info.dfifo_cb_pos = CBPOS_DFIFO_DEF; + + if (fifo & FIFO_OFIFO_MASK) { + mc_fifo_info.ofifo_buf_sample = OFIFO_BUF_SAMPLE_DEF; + mc_fifo_info.ofifo_output_start = false; + } + + if (fifo & FIFO_RFIFO_MASK) { + mc_fifo_info.rfifo_cb_pos = CBPOS_RFIFO_DEF; + mc_fifo_info.rfifo_buf_sample = RFIFO_BUF_SAMPLE_DEF; + mc_fifo_info.rfifo_output_start = false; + } + + cdsp_coder_info_init(info); +} + +static int cdsp_firmware_setup(struct aec_cdsp_func_info *finfo) +{ + struct coder_info *info; + struct coder_firmware coder; + bool download = false; + int ret; + + if (!finfo->prog_size || !finfo->prog_data) + return 0; + + if (mc_cdsp_info.hw_error_code != CDSP_ERR_NO_ERROR) + return -EBUSY; + + coder.firmware = finfo->prog_data; + coder.size = finfo->prog_size; + info = cdsp_coder_info_get(finfo->id); + + /* State check */ + switch (info->state) { + case STATE_INIT: + download = true; + break; + case STATE_READY_SETUP: + case STATE_READY: + /* Check Program ID */ + if (info->prog_info.vendor_id != + MAKE_HALFWORD(coder.firmware[PRG_DESC_VENDER_ID], + coder.firmware[PRG_DESC_VENDER_ID + 1])) + download = true; + else if (info->prog_info.function_id != + MAKE_HALFWORD(coder.firmware[PRG_DESC_FUNCTION_ID], + coder.firmware[PRG_DESC_FUNCTION_ID + + 1])) + download = true; + break; + default: + return -EBUSY; + } + + switch (info->state) { + case STATE_READY_SETUP: + case STATE_READY: + cdsp_coder_close(finfo->id); + + /* Terminate current program */ + cdsp_program_terminate(finfo->id); + + info->state = STATE_INIT; + break; + default: + break; + } + + if (download) { + /* Download */ + ret = cdsp_program_download(coder.firmware); + if (ret < 0) + return ret; + } + + /* Initialize */ + ret = cdsp_program_init(finfo->id, &coder); + if (ret < 0) + return ret; + + ret = cdsp_coder_open(finfo->id); + if (ret < 0) { + /* Terminate current program */ + cdsp_program_terminate(finfo->id); + + return ret; + } + + info->state = STATE_READY_SETUP; + + return 0; +} + +static int cdsp_connection_setup(struct aec_cdsp_func_info *finfo) +{ + struct coder_info *info; + struct coder_params coder; + struct connection_info conn_info; + struct connection_ex_info conn_ex_info; + struct bit_width_info bit_width; + u32 prev, fifo; + u8 data; + int ret; + + info = cdsp_coder_info_get(finfo->id); + + conn_info.src = finfo->conn_info.src; + conn_info.dest = finfo->conn_info.dest; + + conn_ex_info.efifo_ch = finfo->conn_ex_info.efifo_ch; + conn_ex_info.ofifo_ch = finfo->conn_ex_info.ofifo_ch; + bit_width.efifo = finfo->bit_width.efifo; + bit_width.ofifo = finfo->bit_width.ofifo; + + if (info->conn_info.src == conn_info.src && + info->conn_info.dest == conn_info.dest && + info->bit_width.efifo == bit_width.efifo && + info->conn_ex_info.efifo_ch == conn_ex_info.efifo_ch && + info->bit_width.ofifo == bit_width.ofifo && + info->conn_ex_info.ofifo_ch == conn_ex_info.ofifo_ch) + return 0; + + /* State check */ + switch (info->state) { + case STATE_READY_SETUP: + case STATE_READY: + break; + default: + return -EBUSY; + } + + prev = FIFO_NONE; + if (info->conn_info.src != conn_info.src || + info->conn_info.dest != conn_info.dest) { + switch (info->state) { + case STATE_READY: + ret = cdsp_coder_reset(finfo->id); + if (ret < 0) + return ret; + + cdsp_input_position_clear(finfo->id); + cdsp_input_position_reset(finfo->id); + cdsp_output_position_clear(finfo->id); + + info->state = STATE_READY_SETUP; + break; + default: + break; + } + + coder.command = CDSP_CMD_HOST2OS_SYS_SET_CONNECTION; + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = conn_info.src; + coder.params[CDSP_CMD_PARAM_ARGUMENT_01] = conn_info.dest; + ret = cdsp_command_write_host2os(finfo->id, &coder); + if (ret < 0) + return ret; + + fifo = FIFO_NONE; + if (conn_info.src != info->conn_info.src) { + switch (conn_info.src) { + case CDSP_IN_SOURCE_DFIFO: + if (info->conn_info.src != + CDSP_IN_SOURCE_DFIFO_EFIFO) + fifo |= FIFO_DFIFO; + break; + case CDSP_IN_SOURCE_EFIFO: + if (info->conn_info.src != + CDSP_IN_SOURCE_DFIFO_EFIFO) + fifo |= FIFO_EFIFO; + break; + case CDSP_IN_SOURCE_DFIFO_EFIFO: + if (info->conn_info.src != CDSP_IN_SOURCE_DFIFO) + fifo |= FIFO_DFIFO; + + if (info->conn_info.src != CDSP_IN_SOURCE_EFIFO) + fifo |= FIFO_EFIFO; + break; + default: + break; + } + + info->conn_info.src = conn_info.src; + } + + if (conn_info.dest != info->conn_info.dest) { + switch (conn_info.dest) { + case CDSP_OUT_DEST_OFIFO: + if (info->conn_info.dest != + CDSP_OUT_DEST_OFIFO_RFIFO) + fifo |= FIFO_OFIFO; + break; + case CDSP_OUT_DEST_RFIFO: + if (info->conn_info.dest != + CDSP_OUT_DEST_OFIFO_RFIFO) + fifo |= FIFO_RFIFO; + break; + case CDSP_OUT_DEST_OFIFO_RFIFO: + if (info->conn_info.dest != CDSP_OUT_DEST_OFIFO) + fifo |= FIFO_OFIFO; + + if (info->conn_info.dest != CDSP_OUT_DEST_RFIFO) + fifo |= FIFO_RFIFO; + break; + default: + break; + } + + info->conn_info.dest = conn_info.dest; + } + + if (fifo != FIFO_NONE) { + cdsp_fifo_init(finfo->id, fifo); + prev = fifo; + } + } + + fifo = cdsp_fifoid_get_from_coderid(finfo->id); + if (info->bit_width.efifo == bit_width.efifo && + info->conn_ex_info.efifo_ch == conn_ex_info.efifo_ch) + fifo &= ~FIFO_EFIFO_MASK; + + if (info->bit_width.ofifo == bit_width.ofifo && + info->conn_ex_info.ofifo_ch == conn_ex_info.ofifo_ch) + fifo &= ~FIFO_OFIFO_MASK; + + if (fifo & (FIFO_EFIFO_MASK | FIFO_OFIFO_MASK)) { + data = cdsp_fifo_get_ch_bit(fifo, &conn_ex_info, &bit_width); + if (fifo & FIFO_EFIFO_MASK) { + /* Clear position */ + cdsp_input_position_clear(finfo->id); + + info->conn_ex_info.efifo_ch = conn_ex_info.efifo_ch; + info->bit_width.efifo = bit_width.efifo; + } + + if (fifo & FIFO_OFIFO_MASK) { + /* Clear position */ + cdsp_output_position_clear(finfo->id); + + info->conn_ex_info.ofifo_ch = conn_ex_info.ofifo_ch; + info->bit_width.ofifo = bit_width.ofifo; + } + + /* Clear FIFO */ + prev = fifo & ~prev; + if (prev) + cdsp_fifo_reset(finfo->id, prev); + + cdsp_fifo_set_ch(fifo, data); + } + + return 0; +} + +static int cdsp_params_set_one(enum mc_cdsp_id id, + struct coder_params *coder) +{ + struct coder_info *info; + int ret; + + info = cdsp_coder_info_get(id); + + /* State check */ + switch (info->state) { + case STATE_INIT: + if (coder->command != CDSP_CMD_HOST2OS_SYS_SET_CLOCK_SOURCE) + return -EBUSY; + break; + case STATE_READY_SETUP: + case STATE_READY: + case STATE_PLAYING: + break; + default: + return -EBUSY; + } + + if (!(coder->command & CDSP_CMD_COMPLETION)) { + /* Command check */ + switch (coder->command) { + case CDSP_CMD_HOST2OS_CMN_RESET: + /* reset */ + ret = cdsp_coder_reset(id); + if (!ret) { + /* Clear position */ + cdsp_input_position_clear(id); + cdsp_input_position_reset(id); + cdsp_output_position_clear(id); + + /* Clear FIFO */ + cdsp_fifo_reset(id, + (FIFO_DFIFO | FIFO_EFIFO | + FIFO_OFIFO | FIFO_RFIFO)); + + cdsp_connection_reset(id); + + info->state = STATE_READY_SETUP; + } + break; + case CDSP_CMD_HOST2OS_CMN_CLEAR: + ret = cdsp_coder_clear(id); + if (!ret) { + /* Clear position */ + cdsp_input_position_clear(id); + cdsp_input_position_reset(id); + cdsp_output_position_clear(id); + + /* Clear FIFO */ + cdsp_fifo_reset(id, + (FIFO_DFIFO | FIFO_EFIFO | + FIFO_OFIFO | FIFO_RFIFO)); + } + break; + case CDSP_CMD_HOST2OS_SYS_INPUT_DATA_END: + ret = cdsp_input_dataend_set(id); + break; + case CDSP_CMD_HOST2OS_SYS_SET_TIMER: + ret = cdsp_timer_set(id, coder); + break; + + case CDSP_CMD_HOST2OS_SYS_SET_DUAL_MONO: + ret = cdsp_output_set_dualmono(id, coder); + break; + case CDSP_CMD_HOST2OS_SYS_GET_INPUT_POS: + ret = cdsp_input_get_position_sample(id, coder); + break; + default: + if ((coder->command < CDSP_CMD_HOST2OS_PRG_MIN) || + (coder->command > CDSP_CMD_HOST2OS_PRG_MAX)) + return -EINVAL; + + /* Program dependence command */ + ret = cdsp_command_write_host2os(id, coder); + break; + } + } else { + /* Host command notify completion */ + switch (info->coder.command) { + case CDSP_CMD_OS2HOST_CMN_NONE: + return -EIO; + case CDSP_CMD_OS2HOST_CMN_NOTIFY_OUT_FORMAT: + info->change_output_fs = true; + cdsp_output_start(info); + break; + default: + break; + } + + /* Write complete command */ + cdsp_command_write_complete(id, coder); + + /* clear */ + info->coder.command = CDSP_CMD_OS2HOST_CMN_NONE; + memset(info->coder.params, 0, CDSP_CMD_PARAM_ARGUMENT_NUM); + + ret = 0; + } + + return ret; +} + +static inline int cdsp_params_get_one(enum mc_cdsp_id id, + struct coder_params *coder) +{ + struct coder_info *info; + int count, i; + + info = cdsp_coder_info_get(id); + + /* State check */ + switch (info->state) { + case STATE_READY_SETUP: + case STATE_READY: + case STATE_PLAYING: + break; + default: + return -EBUSY; + } + + /* Command */ + coder->command = info->coder.command; + + /* Argument */ + count = CDSP_CMD_PARAM_ARGUMENT_00; + for (i = count; i < count + CDSP_CMD_PARAM_ARGUMENT_NUM; i++) + coder->params[i] = info->coder.params[i]; + + /* Result */ + count = CDSP_CMD_PARAM_RESULT_00; + for (i = count; i < count + CDSP_CMD_PARAM_RESULT_NUM; i++) + coder->params[i] = 0; + + return 0; +} + +static int cdsp_params_set(struct aec_cdsp_func_info *finfo) +{ + struct coder_params coder; + u8 *data; + int i, j, count, ret; + + if (!finfo->param_data || !finfo->param_num) + return 0; + + data = finfo->param_data; + count = CDSP_CMD_PARAM_ARGUMENT_00; + + for (i = 0; i < finfo->param_num; i++) { + coder.command = data[CDSP_PRM_CMD]; + + for (j = count; j < count + CDSP_CMD_PARAM_ARGUMENT_NUM; j++) + coder.params[j] = data[CDSP_PRM_PRM0 + j]; + + ret = cdsp_params_set_one(finfo->id, &coder); + if (ret < 0) + return ret; + + data += PRM_UNIT_SIZE; + } + + return 0; +} + +static void cdsp_callback_set_position(enum mc_cdsp_id id, + struct aec_cdsp_info *cdsp_info) +{ + struct coder_info *info; + u32 fifo_id; + + if (mc_fifo_info.dfifo_cb_pos == cdsp_info->dfifo_cb_pos && + mc_fifo_info.rfifo_cb_pos == cdsp_info->rfifo_cb_pos) + return; + + info = cdsp_coder_info_get(id); + + fifo_id = cdsp_fifoid_get(&info->conn_info); + if (fifo_id & FIFO_DFIFO_MASK) + mc_fifo_info.dfifo_cb_pos = cdsp_info->dfifo_cb_pos; + + if (fifo_id & FIFO_RFIFO_MASK) + mc_fifo_info.rfifo_cb_pos = cdsp_info->rfifo_cb_pos; +} + +static void cdsp_callback_set_buffering(enum mc_cdsp_id id, + struct aec_cdsp_info *cdsp_info) +{ + struct coder_info *info; + u32 fifo_id; + + if ((mc_fifo_info.ofifo_buf_sample == cdsp_info->ofifo_buf_sample) && + (mc_fifo_info.rfifo_buf_sample == cdsp_info->rfifo_buf_sample)) + return; + + info = cdsp_coder_info_get(id); + fifo_id = cdsp_fifoid_get(&info->conn_info); + + if (fifo_id & FIFO_OFIFO_MASK) + mc_fifo_info.ofifo_buf_sample = cdsp_info->ofifo_buf_sample; + + if (fifo_id & FIFO_RFIFO_MASK) + mc_fifo_info.rfifo_buf_sample = cdsp_info->rfifo_buf_sample; +} + +static inline void cdsp_route_set(struct aec_cdsp_info *cdsp_info) +{ + if (!cdsp_info->func_info[AEC_FUNC_INFO_A].fifo_data && + !cdsp_info->func_info[AEC_FUNC_INFO_B].fifo_data) + return; + + /* OUT*R/L_SEL */ + if (cdsp_info->out0_sel != mc_fifo_info.out0_sel) { + mc_packet_add_force_write_c(MCI_OUT0_SEL, cdsp_info->out0_sel); + mc_fifo_info.out0_sel = cdsp_info->out0_sel; + } + + if (cdsp_info->out1_sel != mc_fifo_info.out1_sel) { + mc_packet_add_force_write_c(MCI_OUT1_SEL, cdsp_info->out1_sel); + mc_fifo_info.out1_sel = cdsp_info->out1_sel; + } + + if (cdsp_info->out2_sel != mc_fifo_info.out2_sel) { + mc_packet_add_force_write_c(MCI_OUT2_SEL, cdsp_info->out2_sel); + mc_fifo_info.out2_sel = cdsp_info->out2_sel; + } + + /* RFIFO_BIT/RFIFO_SEL/DFIFO_BIT/DFIFO_SEL */ + if (cdsp_info->rdfifo_bit_sel != mc_fifo_info.rdfifo_bit_sel) { + mc_packet_add_force_write_c(MCI_RDFIFO_BIT_SEL, + cdsp_info->rdfifo_bit_sel); + mc_fifo_info.rdfifo_bit_sel = cdsp_info->rdfifo_bit_sel; + } + + /* EFIFO0*_SEL */ + if (cdsp_info->efifo01_sel != mc_fifo_info.efifo01_sel) { + mc_packet_add_force_write_c(MCI_EFIFO01_SEL, + cdsp_info->efifo01_sel); + mc_fifo_info.efifo01_sel = cdsp_info->efifo01_sel; + } + + if (cdsp_info->efifo23_sel != mc_fifo_info.efifo23_sel) { + mc_packet_add_force_write_c(MCI_EFIFO23_SEL, + cdsp_info->efifo23_sel); + mc_fifo_info.efifo23_sel = cdsp_info->efifo23_sel; + } + + mc_packet_execute(); +} + +static inline void cdsp_etobuf_set_mode(enum mc_cdsp_id coder_id, + struct aec_cdsp_func_info *finfo) +{ + struct coder_info *info; + + info = cdsp_coder_info_get(coder_id); + info->format.etobuf = finfo->format.etobuf; +} + +static int cdsp_ext_set(enum mc_cdsp_id coder_id, + struct aec_cdsp_func_info *finfo) +{ + struct coder_info *info; + struct coder_params coder; + int ret = 0; + + if (!finfo->ext) + return ret; + + if (finfo->ext[EXT_COMMAND] == EXT_COMMAND_CLEAR) { + coder.command = CDSP_CMD_HOST2OS_CMN_CLEAR; + + info = cdsp_coder_info_get(coder_id); + switch (info->state) { + case STATE_PLAYING: + ret = + cdsp_coder_stop(coder_id, MADEVCDSP_VERIFY_COMP_ON); + if (ret < 0) + return ret; + + cdsp_fifo_stop(coder_id); + info->state = STATE_READY; + + ret = cdsp_params_set_one(coder_id, &coder); + if (ret < 0) + return ret; + + ret = cdsp_coder_start(coder_id); + if (!ret) + info->state = STATE_PLAYING; + break; + case STATE_READY_SETUP: + case STATE_READY: + ret = cdsp_params_set_one(coder_id, &coder); + break; + default: + break; + } + } + + return ret; +} + +static int cdsp_set_dsp(struct aec_cdsp_info *cdsp_info) +{ + struct aec_cdsp_func_info *finfo_a; + struct aec_cdsp_func_info *finfo_b; + int ret; + + finfo_a = &cdsp_info->func_info[AEC_FUNC_INFO_A]; + finfo_b = &cdsp_info->func_info[AEC_FUNC_INFO_B]; + + if (finfo_a->func_on) { + ret = cdsp_firmware_setup(finfo_a); + if (ret < 0) + return ret; + + ret = cdsp_connection_setup(finfo_a); + if (ret < 0) + return ret; + + ret = cdsp_params_set(finfo_a); + if (ret < 0) + return ret; + + cdsp_etobuf_set_mode(CODER_DEC, finfo_a); + cdsp_callback_set_position(CODER_DEC, cdsp_info); + cdsp_callback_set_buffering(CODER_DEC, cdsp_info); + + ret = cdsp_ext_set(CODER_DEC, finfo_a); + if (ret < 0) + return ret; + } + + if (finfo_b->func_on) { + ret = cdsp_firmware_setup(finfo_b); + if (ret < 0) + return ret; + + ret = cdsp_connection_setup(finfo_b); + if (ret < 0) + return ret; + + ret = cdsp_params_set(finfo_b); + if (ret < 0) + return ret; + + cdsp_etobuf_set_mode(CODER_ENC, finfo_b); + cdsp_callback_set_position(CODER_ENC, cdsp_info); + cdsp_callback_set_buffering(CODER_ENC, cdsp_info); + + ret = cdsp_ext_set(CODER_ENC, finfo_b); + if (ret < 0) + return ret; + } + + cdsp_route_set(cdsp_info); + + return 0; +} + +static inline void cdsp_dfifo_start(void) +{ + u8 ptr_h, ptr_l, data; + + mc_read_c(MCI_DFIFO_ENABLE, &data, 1); + mc_read_c(MCI_DFIFO_IRQ_PNT_H, &ptr_h, 1); + mc_read_c(MCI_DFIFO_IRQ_PNT_L, &ptr_l, 1); + + if (!(mc_fifo_info.rdfifo_bit_sel & MCB_DFIFO_SEL_HOST) || + mc_fifo_info.dfifo_cb_pos == CBPOS_DFIFO_NONE) { + ptr_h = ptr_l = 0; + data &= ~MCB_DFIFO_EDPNT; + } else { + ptr_h = (mc_fifo_info.dfifo_cb_pos >> 8) & MCB_DFIFO_IRQ_PNT_H; + ptr_l = mc_fifo_info.dfifo_cb_pos & MCB_DFIFO_IRQ_PNT_L; + data |= MCB_DFIFO_EDPNT; + } + + data |= MCB_DFIFO_EDEMP; + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt flag clear */ + mc_packet_add_force_write_c(MCI_DFIFO_FLG, MCB_DFIFO_FLG_ALL); + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_DFIFO); + + /* xFIFO_IRQ_PNT Set */ + mc_packet_add_force_write_c(MCI_DFIFO_IRQ_PNT_H, ptr_h); + mc_packet_add_force_write_c(MCI_DFIFO_IRQ_PNT_L, ptr_l); + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt Enable */ + mc_packet_add_force_write_c(MCI_DFIFO_ENABLE, data); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data |= MCB_EDFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); +} + +static inline void cdsp_efifo_start(void) +{ + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt flag clear */ + mc_packet_add_force_write_c(MCI_EFIFO_FLG, MCB_EFIFO_FLG_ALL); + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_EFIFO); + + mc_packet_execute(); +} + +static inline void cdsp_ofifo_start(enum mc_cdsp_id id) +{ + struct coder_info *info; + u32 sample; + u8 ptr_h, ptr_l, data; + + info = cdsp_coder_info_get(id); + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt flag clear */ + mc_packet_add_force_write_c(MCI_OFIFO_FLG, MCB_OFIFO_FLG_ALL); + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_OFIFO); + + /* xFIFO_IRQ_PNT Set */ + sample = (mc_fifo_info.ofifo_buf_sample * info->conn_ex_info.ofifo_ch * + (info->bit_width.ofifo / 8)) / 4; + ptr_h = (sample >> 8) & MCB_OFIFO_IRQ_PNT_H; + ptr_l = sample & MCB_OFIFO_IRQ_PNT_L; + + mc_packet_add_force_write_c(MCI_OFIFO_IRQ_PNT_H, ptr_h); + mc_packet_add_force_write_c(MCI_OFIFO_IRQ_PNT_L, ptr_l); + + /* xFIFO/xPNT Interrupt Enable */ + mc_packet_add_force_write_c(MCI_OFIFO_ENABLE, MCB_OFIFO_EOPNT); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data |= MCB_EOFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + + cdsp_output_start(info); +} + +static inline void cdsp_rfifo_start_port(enum mc_cdsp_id id) +{ + struct coder_info *info; + u32 sample; + u8 ptr_h, ptr_l, data; + + info = cdsp_coder_info_get(id); + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt flag clear */ + mc_packet_add_force_write_c(MCI_RFIFO_FLG, MCB_RFIFO_FLG_ALL); + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_RFIFO); + + /* xFIFO_IRQ_PNT Set */ + sample = (mc_fifo_info.rfifo_buf_sample * RFIFO_CH_NUM * + RFIFO_BIT_WIDTH / 8) / 4; + ptr_h = (sample >> 8) & MCB_RFIFO_IRQ_PNT_H; + ptr_l = sample & MCB_RFIFO_IRQ_PNT_L; + + mc_packet_add_force_write_c(MCI_RFIFO_IRQ_PNT_H, ptr_h); + mc_packet_add_force_write_c(MCI_RFIFO_IRQ_PNT_L, ptr_l); + + /* xFIFO/xPNT/xOVF Interrupt Enable */ + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, MCB_RFIFO_ERPNT); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data |= MCB_ERFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); + + cdsp_output_start(info); +} + +static inline void cdsp_rfifo_start_host(void) +{ + u8 ptr_h, ptr_l, data, ctrl; + + mc_read_c(MCI_RFIFO_ENABLE, &ctrl, 1); + ctrl |= MCB_RFIFO_EROVF; + + if (mc_fifo_info.rfifo_cb_pos != CBPOS_RFIFO_NONE) { + ptr_h = (mc_fifo_info.rfifo_cb_pos >> 8) & MCB_RFIFO_IRQ_PNT_H; + ptr_l = mc_fifo_info.rfifo_cb_pos & MCB_RFIFO_IRQ_PNT_L; + ctrl |= MCB_RFIFO_ERPNT; + } else { + ptr_h = 0; + ptr_l = 0; + ctrl &= ~MCB_RFIFO_ERPNT; + } + + /* xFIFO/xPNT/xEMP/xUDF/xOVF Interrupt flag clear */ + mc_packet_add_force_write_c(MCI_RFIFO_FLG, MCB_RFIFO_FLG_ALL); + mc_packet_add_force_write_if(MCI_CDSP, MCB_IRQFLAG_RFIFO); + + /* xFIFO_IRQ_PNT Set */ + mc_packet_add_force_write_c(MCI_RFIFO_IRQ_PNT_H, ptr_h); + mc_packet_add_force_write_c(MCI_RFIFO_IRQ_PNT_L, ptr_l); + + /* xFIFO/xPNT/xOVF Interrupt Enable */ + mc_packet_add_force_write_c(MCI_RFIFO_ENABLE, ctrl); + + mc_packet_execute(); + + mc_read_digital(MCI_ECDSP, &data, 1); + data |= MCB_ERFIFO; + mc_packet_add_force_write_if(MCI_ECDSP, data); + + mc_packet_execute(); +} + +static inline void cdsp_rfifo_start(enum mc_cdsp_id id) +{ + if (mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST) + cdsp_rfifo_start_host(); + else + cdsp_rfifo_start_port(id); +} + +static inline void cdsp_fifo_start(enum mc_cdsp_id id) +{ + u32 fifo_id; + + fifo_id = cdsp_fifoid_get_from_coderid(id); + if (fifo_id & FIFO_DFIFO_MASK) + cdsp_dfifo_start(); + + if (fifo_id & FIFO_EFIFO_MASK) + cdsp_efifo_start(); + + if (fifo_id & FIFO_OFIFO_MASK) + cdsp_ofifo_start(id); + + if (fifo_id & FIFO_RFIFO_MASK) + cdsp_rfifo_start(id); +} + +static inline int cdsp_coder_start(enum mc_cdsp_id id) +{ + struct coder_info *info; + u32 fifo_id; + u8 data; + + info = cdsp_coder_info_get(id); + + /* Mutual output ? */ + if (info->conn_info.dest == CDSP_OUT_DEST_OTHER_INBUF) { + struct coder_info *another_info; + another_info = cdsp_coder_info_get(cdsp_another_id_get(id)); + switch (another_info->state) { + case STATE_READY_SETUP: + case STATE_READY: + case STATE_PLAYING: + break; + default: + return -EIO; + } + } + + cdsp_fifo_start(id); + + /* DEC/ENC ERR,END Interrupt flag clear */ + if (id == CDSP_DECODER) { + mc_read_c(MCI_DEC_FLG, &data, 1); + data |= MCB_DEC_FLG_ERR | MCB_DEC_FLG_END; + mc_packet_add_force_write_c(MCI_DEC_FLG, data); + } else { + mc_read_c(MCI_ENC_FLG, &data, 1); + data |= MCB_ENC_FLG_ERR | MCB_ENC_FLG_END; + mc_packet_add_force_write_c(MCI_ENC_FLG, data); + } + + mc_packet_execute(); + + mc_read_digital(MCI_CDSP, &data, 1); + if (id == CDSP_DECODER) + data |= MCB_IRQFLAG_DEC; + else + data |= MCB_IRQFLAG_ENC; + mc_packet_add_force_write_if(MCI_CDSP, data); + + mc_packet_execute(); + + /* DEC/ENC END,ERR Interrupt Enable */ + if (id == CDSP_DECODER) { + mc_read_c(MCI_DEC_ENABLE, &data, 1); + data |= MCB_EDEC_ERR | MCB_EDEC_END; + mc_packet_add_force_write_c(MCI_DEC_ENABLE, data); + } else { + mc_read_c(MCI_ENC_ENABLE, &data, 1); + data |= MCB_EENC_ERR | MCB_EENC_END; + mc_packet_add_force_write_c(MCI_ENC_ENABLE, data); + } + + mc_packet_execute(); + + /* DEC/ENC Start */ + mc_read_c(MCI_DEC_START, &data, 1); + if (id == CDSP_DECODER) + data |= MCB_DEC_DEC_START; + else + data |= MCB_DEC_ENC_START; + mc_packet_add_force_write_c(MCI_DEC_START, data); + + mc_packet_execute(); + + fifo_id = cdsp_fifoid_get(&info->conn_info); + if (fifo_id & FIFO_EFIFO) { + mc_read_c(MCI_DEC_FIFO_CH, &data, 1); + data |= MCB_DEC_EFIFO_START; + mc_packet_add_force_write_c(MCI_DEC_FIFO_CH, data); + + mc_packet_execute(); + } + + if ((fifo_id & FIFO_DFIFO) && + !(mc_fifo_info.rdfifo_bit_sel & MCB_DFIFO_SEL_HOST)) { + mc_read_c(MCI_RDFIFO_BIT_SEL, &data, 1); + data |= MCB_RDFIFO_DFIFO_START; + mc_packet_add_force_write_c(MCI_RDFIFO_BIT_SEL, data); + + mc_packet_execute(); + } + + if (!mc_fifo_info.ofifo_buf_sample && (fifo_id & FIFO_OFIFO)) + cdsp_interrupt_proc_ofifo_core(); + + if (!mc_fifo_info.rfifo_buf_sample && + (fifo_id & FIFO_RFIFO) && + !(mc_fifo_info.rdfifo_bit_sel & MCB_RFIFO_SEL_HOST)) + cdsp_interrupt_proc_rfifo_core(); + + return 0; +} + +int mc_cdsp_init(void) +{ + if (mc_dec_info.state == STATE_PLAYING || + mc_enc_info.state == STATE_PLAYING) + return -EBUSY; + + /* Global Initialize */ + mc_cdsp_info.hw_error_code = CDSP_ERR_NO_ERROR; + mc_cdsp_info.os.version_h = 0; + mc_cdsp_info.os.version_l = 0; + + mc_fifo_info.dfifo_cb_pos = CBPOS_DFIFO_DEF; + mc_fifo_info.rfifo_cb_pos = CBPOS_RFIFO_DEF; + mc_fifo_info.ofifo_buf_sample = OFIFO_BUF_SAMPLE_DEF; + mc_fifo_info.ofifo_output_start = false; + mc_fifo_info.dfifo_write_size = 0; + mc_fifo_info.rfifo_buf_sample = RFIFO_BUF_SAMPLE_DEF; + mc_fifo_info.rfifo_output_start = false; + mc_fifo_info.out0_sel = MCI_OUT0_SEL_DEF; + mc_fifo_info.out1_sel = MCI_OUT1_SEL_DEF; + mc_fifo_info.out2_sel = MCI_OUT2_SEL_DEF; + mc_fifo_info.rdfifo_bit_sel = 0; + mc_fifo_info.efifo01_sel = MCI_EFIFO01_SEL_DEF; + mc_fifo_info.efifo23_sel = MCI_EFIFO23_SEL_DEF; + + cdsp_coder_info_init(&mc_dec_info); + cdsp_coder_info_init(&mc_enc_info); + + cdsp_registers_init(); + + /* CDSP OS Download */ + cdsp_os_download(mc_cdsp_os); + + /* CDSP OS initialize */ + return cdsp_os_init(); +} + +void mc_cdsp_term(void) +{ + u8 data; + + /* CDSP stop */ + if (mc_dec_info.state != STATE_NOTINIT || + mc_enc_info.state != STATE_NOTINIT) { + mc_read_c(MCI_CDSP_RESET, &data, 1); + data |= MCB_CDSP_SRST; + mc_packet_add_force_write_c(MCI_CDSP_RESET, data); + + mc_packet_execute(); + } + + mc_dec_info.state = STATE_NOTINIT; + mc_enc_info.state = STATE_NOTINIT; +} + +void mc_cdsp_irq(void) +{ + u8 flag; + + if (mc_dec_info.state == STATE_NOTINIT || + mc_enc_info.state == STATE_NOTINIT) + return; + + /* Get interrupt flag */ + mc_read_digital(MCI_CDSP, &flag, 1); + + if (flag & MCB_IRQFLAG_DEC) + cdsp_interrupt_proc_coder(CODER_DEC); + + if (flag & MCB_IRQFLAG_ENC) + cdsp_interrupt_proc_coder(CODER_ENC); + + if (flag & MCB_IRQFLAG_DFIFO) + cdsp_interrupt_proc_dfifo(); + + if (flag & MCB_IRQFLAG_OFIFO) + cdsp_interrupt_proc_ofifo(); + + if (flag & MCB_IRQFLAG_RFIFO) + cdsp_interrupt_proc_rfifo(); + + if (flag & MCB_IRQFLAG_CDSP) + cdsp_interrupt_proc(); + + /* Clear interrupt flag */ + mc_packet_add_force_write_if(MCI_CDSP, flag); + + mc_packet_execute(); + + cdsp_callback_proc(); +} + +int mc_cdsp_set_dsp(struct mcdrv_aec_info *aec) +{ + struct aec_cdsp_info cdsp_info; + struct aec_cdsp_func_info *finfo_a; + struct aec_cdsp_func_info *finfo_b; + int ret; + + finfo_a = &cdsp_info.func_info[AEC_FUNC_INFO_A]; + finfo_b = &cdsp_info.func_info[AEC_FUNC_INFO_B]; + + if (!aec) + return -EINVAL; + + cdsp_get_data(aec, &cdsp_info); + + ret = cdsp_data_analyze(&cdsp_info); + if (ret < 0) + return ret; + + if (aec->vbox.enable) { + if (!finfo_a->func_on) + cdsp_coder_term(CODER_DEC); + + if (!finfo_b->func_on) + cdsp_coder_term(CODER_ENC); + } + + if ((!finfo_a->data || !finfo_a->data_size) && + (!finfo_b->data || !finfo_b->data_size)) + return 0; + + if (mc_dec_info.state == STATE_NOTINIT || + mc_enc_info.state == STATE_NOTINIT) + return -EBUSY; + + return cdsp_set_dsp(&cdsp_info); +} + +int mc_cdsp_set_fs(enum mc_cdsp_id id, u8 fs) +{ + struct coder_info *info; + struct coder_params coder; + + if (mc_dec_info.state == STATE_NOTINIT || + mc_enc_info.state == STATE_NOTINIT) + return -EBUSY; + + info = cdsp_coder_info_get(id); + + coder.command = CDSP_CMD_HOST2OS_SYS_SET_FORMAT; + coder.params[CDSP_CMD_PARAM_ARGUMENT_00] = fs; + coder.params[CDSP_CMD_PARAM_ARGUMENT_01] = info->format.etobuf; + + return cdsp_format_set(id, &coder); +} + +int mc_cdsp_set_dfifo_sel(enum mc_cdsp_fifo_sel sel) +{ + u8 rdfifo_bit_sel; + + if (sel != CDSP_FIFO_SEL_PORT && sel != CDSP_FIFO_SEL_HOST) + return -EINVAL; + + if (mc_dec_info.state == STATE_NOTINIT || + mc_enc_info.state == STATE_NOTINIT) + return -EBUSY; + + rdfifo_bit_sel = mc_fifo_info.rdfifo_bit_sel; + rdfifo_bit_sel &= ~MCB_DFIFO_SEL; + if (sel == CDSP_FIFO_SEL_HOST) + rdfifo_bit_sel |= MCB_DFIFO_SEL_HOST; + + if (rdfifo_bit_sel != mc_fifo_info.rdfifo_bit_sel) { + mc_packet_add_force_write_c(MCI_RDFIFO_BIT_SEL, rdfifo_bit_sel); + + mc_packet_execute(); + + mc_fifo_info.rdfifo_bit_sel = rdfifo_bit_sel; + } + + return 0; +} + +int mc_cdsp_set_rfifo_sel(enum mc_cdsp_fifo_sel sel) +{ + u8 rdfifo_bit_sel; + + if (sel != CDSP_FIFO_SEL_PORT && sel != CDSP_FIFO_SEL_HOST) + return -EINVAL; + + if (mc_dec_info.state == STATE_NOTINIT || + mc_enc_info.state == STATE_NOTINIT) + return -EBUSY; + + rdfifo_bit_sel = mc_fifo_info.rdfifo_bit_sel; + rdfifo_bit_sel &= ~MCB_RFIFO_SEL; + if (sel == CDSP_FIFO_SEL_HOST) + rdfifo_bit_sel |= MCB_RFIFO_SEL_HOST; + + if (rdfifo_bit_sel != mc_fifo_info.rdfifo_bit_sel) { + mc_packet_add_force_write_c(MCI_RDFIFO_BIT_SEL, rdfifo_bit_sel); + + mc_packet_execute(); + + mc_fifo_info.rdfifo_bit_sel = rdfifo_bit_sel; + } + + return 0; +} + +int mc_cdsp_start(enum mc_cdsp_id id) +{ + struct coder_info *info; + int ret; + + info = cdsp_coder_info_get(id); + switch (info->state) { + case STATE_READY_SETUP: + ret = cdsp_coder_standby(id); + if (ret < 0) + return ret; + + cdsp_fifo_reset(id, + (FIFO_DFIFO | FIFO_EFIFO | FIFO_OFIFO | + FIFO_RFIFO)); + info->state = STATE_READY; + + if (info->preinput_dataend_set) { + ret = cdsp_input_dataend_set(id); + if (ret < 0) + return ret; + } + break; + case STATE_READY: + cdsp_fifo_reset(id, (FIFO_DFIFO | FIFO_EFIFO)); + break; + default: + return -EBUSY; + } + + ret = cdsp_coder_start(id); + if (!ret) + info->state = STATE_PLAYING; + + return ret; +} + +int mc_cdsp_stop(enum mc_cdsp_id id) +{ + struct coder_info *info; + int ret; + + info = cdsp_coder_info_get(id); + if (info->state != STATE_PLAYING) + return -EBUSY; + + ret = cdsp_coder_stop(id, MADEVCDSP_VERIFY_COMP_ON); + if (ret < 0) + return ret; + + cdsp_fifo_stop(id); + + info->state = STATE_READY; + + return ret; +} diff --git a/sound/soc/codecs/ymu831/mccdspdrv.h b/sound/soc/codecs/ymu831/mccdspdrv.h new file mode 100644 index 0000000..11e669c --- /dev/null +++ b/sound/soc/codecs/ymu831/mccdspdrv.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mccdspdrv.h + * Description : MC C-DSP driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _MCCDSPDRV_H +#define _MCCDSPDRV_H + +#include "mcresctrl.h" + +enum mc_cdsp_fifo_sel { + CDSP_FIFO_SEL_PORT, + CDSP_FIFO_SEL_HOST +}; + +enum mc_cdsp_id { + CDSP_DECODER, + CDSP_ENCODER, +}; + +int mc_cdsp_init(void); +void mc_cdsp_term(void); +void mc_cdsp_irq(void); +int mc_cdsp_set_dsp(struct mcdrv_aec_info *aec); +int mc_cdsp_set_fs(enum mc_cdsp_id id, u8 fs); +int mc_cdsp_set_dfifo_sel(enum mc_cdsp_fifo_sel sel); +int mc_cdsp_set_rfifo_sel(enum mc_cdsp_fifo_sel sel); +int mc_cdsp_start(enum mc_cdsp_id id); +int mc_cdsp_stop(enum mc_cdsp_id id); + +#endif /* _MCCDSPDRV_H */
On Wed, Jan 16, 2013 at 05:31:03PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mccdspdrv.c | 5119 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mccdspdrv.h | 57 +
Again, this is an *extremely* large source file which appears to have no relationship with standard Linux code. It needs to be broken down into smaller commits for review, I strongly expect that it needs to be better integrated into Linux also.
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcdevif.c | 100 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcdevif.h | 69 +++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcdevif.c create mode 100644 sound/soc/codecs/ymu831/mcdevif.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index b42881e..949640e 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -1,5 +1,6 @@ snd-soc-ymu831-objs := \ mcbdspdrv.o \ - mccdspdrv.o + mccdspdrv.o \ + mcdevif.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcdevif.c b/sound/soc/codecs/ymu831/mcdevif.c new file mode 100644 index 0000000..6909dc5 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdevif.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcdevif.c + * Description : MC device interface driver + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + * - mc_packet_*() functions move to mcpacking.c + */ +#include <linux/types.h> + +#include "mcdefs.h" +#include "mcdevif.h" + +static struct mcdrv_bus_ops *mc_bus_ops; + +void mc_bus_register(struct mcdrv_bus_ops *ops) +{ + mc_bus_ops = ops; +} + +void mc_read(enum mcdrv_slave_addr slave_addr, u8 addr, u8 *data, u32 size) +{ + if (mc_bus_ops && mc_bus_ops->read) + mc_bus_ops->read(mc_bus_ops->priv, slave_addr, addr, data, + size); +} + +void mc_read_b(u8 addr, u8 *data, u32 size) +{ + u8 addr_cmd[2]; + + addr_cmd[0] = MCI_B_REG_A << 1; + addr_cmd[1] = addr; + + mc_write_digital(addr_cmd, 2); + mc_read_digital(MCI_B_REG_D, data, size); +} + +void mc_read_c(u8 addr, u8 *data, u32 size) +{ + u8 addr_cmd[2]; + + addr_cmd[0] = MCI_C_REG_A << 1; + addr_cmd[1] = addr; + + mc_write_digital(addr_cmd, 2); + mc_read_digital(MCI_C_REG_D, data, size); +} + +void mc_read_e(u8 addr, u8 *data, u32 size) +{ + u8 addr_cmd[2]; + + addr_cmd[0] = MCI_E_REG_A << 1; + addr_cmd[1] = addr; + + mc_write_digital(addr_cmd, 2); + mc_read_digital(MCI_E_REG_D, data, size); +} + +void mc_read_f(u8 addr, u8 *data, u32 size) +{ + u8 addr_cmd[2]; + + addr_cmd[0] = MCI_F_REG_A << 1; + addr_cmd[1] = addr; + + mc_write_digital(addr_cmd, 2); + mc_read_digital(MCI_F_REG_D, data, size); +} + +void mc_write(enum mcdrv_slave_addr slave_addr, u8 *data, u32 size) +{ + if (mc_bus_ops && mc_bus_ops->write) + mc_bus_ops->write(mc_bus_ops->priv, slave_addr, data, size); +} diff --git a/sound/soc/codecs/ymu831/mcdevif.h b/sound/soc/codecs/ymu831/mcdevif.h new file mode 100644 index 0000000..af9f8c8 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdevif.h @@ -0,0 +1,69 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcdevif.h + * Description : MC device interface driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + * - mc_packet_*() functions move to mcpacking.h + */ +#ifndef _MCDEVIF_H +#define _MCDEVIF_H + +#include <linux/types.h> + +enum mcdrv_slave_addr { + MCDRV_SLAVE_ADDR_ANALOG, + MCDRV_SLAVE_ADDR_DIGITAL, +}; + +struct mcdrv_bus_ops { + int (*read) (void *bus_priv, enum mcdrv_slave_addr slave_addr, + u8 addr, u8 *data, u32 size); + int (*write) (void *bus_priv, enum mcdrv_slave_addr slave_addr, + u8 *data, u32 size); + void *priv; +}; + +void mc_bus_register(struct mcdrv_bus_ops *ops); +void mc_read(enum mcdrv_slave_addr slave_addr, u8 addr, u8 *data, u32 size); +void mc_read_b(u8 addr, u8 *data, u32 size); +void mc_read_c(u8 addr, u8 *data, u32 size); +void mc_read_e(u8 addr, u8 *data, u32 size); +void mc_read_f(u8 addr, u8 *data, u32 size); +void mc_write(enum mcdrv_slave_addr slave_addr, u8 *data, u32 size); + +#define mc_read_analog(address, data, size) \ + mc_read(MCDRV_SLAVE_ADDR_ANALOG, (address), (data), (size)) +#define mc_read_digital(address, data, size) \ + mc_read(MCDRV_SLAVE_ADDR_DIGITAL, (address), (data), (size)) + +#define mc_write_analog(data, size) \ + mc_write(MCDRV_SLAVE_ADDR_ANALOG, (data), (size)) +#define mc_write_digital(data, size) \ + mc_write(MCDRV_SLAVE_ADDR_DIGITAL, (data), (size)) + +#endif /* _MCDEVIF_H */
On Wed, Jan 16, 2013 at 05:32:04PM +0900, Yoichi Yuasa wrote:
+static struct mcdrv_bus_ops *mc_bus_ops;
+void mc_bus_register(struct mcdrv_bus_ops *ops) +{
- mc_bus_ops = ops;
+}
Again this just doesn't look like a serious effort has been made to integrate whatever thise code does into Linux. Without some description of what this is trying to abstract it's hard to comment about what you're doing here.
The use of a static variable is also a big warning sign here.
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcdriver.c | 2934 ++++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcdriver.h | 1017 +++++++++++++ 3 files changed, 3953 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcdriver.c create mode 100644 sound/soc/codecs/ymu831/mcdriver.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index 949640e..e908b6d 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -1,6 +1,7 @@ snd-soc-ymu831-objs := \ mcbdspdrv.o \ mccdspdrv.o \ - mcdevif.o + mcdevif.o \ + mcdriver.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcdriver.c b/sound/soc/codecs/ymu831/mcdriver.c new file mode 100644 index 0000000..dbdce57 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdriver.c @@ -0,0 +1,2934 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcdriver.c + * Description : MC base driver + * Version : 1.0.1 Dec 20 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/string.h> +#include <linux/types.h> + +#include "mcbdspdrv.h" +#include "mccdspdrv.h" +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcdriver.h" +#include "mcedspdrv.h" +#include "mcfdspdrv.h" +#include "mcparser.h" +#include "mcresctrl.h" + +#define LDO_WAIT_TIME 1 /* msec */ +#define VREF_WAIT_TIME_ES1 2 /* msec */ +#define VREF_WAIT_TIME 30 /* msec */ +#define MCDRV_DAC_MUTE_WAIT_TIME 20000 +#define MCDRV_MB4_WAIT_TIME 8000 + +#define T_CPMODE_IMPSENSE_BEFORE 0 +#define T_CPMODE_IMPSENSE_AFTER 2 + +static struct mcdrv_path_info path_alloff = { + .music_out = {0x00AAAAAA, 0x00AAAAAA}, + .ext_out = {0x00AAAAAA, 0x00AAAAAA}, + .hifi_out = {0x00AAAAAA}, + .vbox_mix_in = {0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA}, + .ae0 = {0x00AAAAAA, 0x00AAAAAA}, + .ae1 = {0x00AAAAAA, 0x00AAAAAA}, + .ae2 = {0x00AAAAAA, 0x00AAAAAA}, + .ae3 = {0x00AAAAAA, 0x00AAAAAA}, + .dac0 = {0x00AAAAAA, 0x00AAAAAA}, + .dac1 = {0x00AAAAAA, 0x00AAAAAA}, + .voice_out = {0x00AAAAAA}, + .vbox_io_in = {0x00AAAAAA}, + .vbox_host_in = {0x00AAAAAA}, + .host_out = {0x00AAAAAA}, + .adif0 = {0x00AAAAAA, 0x00AAAAAA}, + .adif1 = {0x00AAAAAA, 0x00AAAAAA}, + .adif2 = {0x00AAAAAA, 0x00AAAAAA}, + .adc0 = {0x002AAAAA, 0x002AAAAA}, + .adc1 = {0x002AAAAA}, + .sp = {0x002AAAAA, 0x002AAAAA}, + .hp = {0x002AAAAA, 0x002AAAAA}, + .rc = {0x002AAAAA}, + .lout1 = {0x002AAAAA, 0x002AAAAA}, + .lout2 = {0x002AAAAA, 0x002AAAAA}, + .bias = {0x002AAAAA, 0x002AAAAA, 0x002AAAAA, 0x002AAAAA}, +}; + +static DEFINE_MUTEX(mcdrv_mutex); + +#ifndef MCDRV_SKIP_IMPSENSE +static inline int imp_sense_start(u8 *op_dac) +{ + struct mcdrv_power_info power_info; + struct mcdrv_power_update power_update; + struct mcdrv_hsdet_info hsdet_info; + struct mcdrv_dev_info info; + enum mcdrv_dev_id id; + u8 val, data[2]; + int ret = 0; + + id = mc_dev_id_get(); + mc_power_info_get_current(&power_info); + power_info.digital &= ~(MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + power_info.analog[0] &= ~(MCB_AP_LDOA | MCB_AP_BGR | MCB_AP_VR); + + /* power up */ + power_update.digital = MCDRV_POWUPDATE_D_ALL; + power_update.analog[0] = (u8) MCDRV_POWUPDATE_AP; + power_update.analog[1] = 0; + power_update.analog[2] = 0; + power_update.analog[3] = 0; + power_update.analog[4] = 0; + ret = mc_packet_add_powerup(&power_info, &power_update); + if (ret < 0) + goto exit; + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + mc_packet_add_force_write_if(MCI_IRQ, 0); + mc_packet_add_force_write_cd(MCI_IRQHS, 0); + + mc_packet_add_write_e(MCI_E1DSP_CTRL, 0); + + mc_packet_add_dac0_mute(); + + val = mc_e_register_get_value(MCI_LPF_THR); + val |= (MCB_OSF0_ENB | MCB_LPF0_PST_THR | MCB_LPF0_PRE_THR); + mc_packet_add_write_e(MCI_LPF_THR, val); + + val = mc_cd_register_get_value(MCI_DP); + if (id == MCDRV_DEV_ID_80_90H) { + val &= ~(MCB_DP_ADC | MCB_DP_DAC0 | MCB_DP_PDMCK | + MCB_DP_PDMADC | MCB_DP_PDMDAC); + } else { + val &= ~(MCB_DP_ADC | MCB_DP_DAC1 | MCB_DP_DAC0 | + MCB_DP_PDMCK | MCB_DP_PDMADC | MCB_DP_PDMDAC); + } + mc_packet_add_write_cd(MCI_DP, val); + + val = mc_e_register_get_value(MCI_DCL_GAIN); + val |= MCB_DCL0_OFF; + mc_packet_add_write_e(MCI_DCL_GAIN, val); + + if (id == MCDRV_DEV_ID_80_90H) { + val = mc_e_register_get_value(MCI_DSF0_FLT_TYPE); + val |= MCB_DSF0ENB; + mc_packet_add_write_e(MCI_DSF0_FLT_TYPE, val); + } else { + val = mc_e_register_get_value(MCI_DSF2_FLT_TYPE); + val |= MCB_DSF2ENB; + mc_packet_add_write_e(MCI_DSF2_FLT_TYPE, val); + } + + mc_hsdet_info_get(&hsdet_info); + val = hsdet_info.sgnl_peak << 4 | hsdet_info.sgnl_num << 2 | + hsdet_info.sgnl_period; + mc_packet_add_write_e(MCI_IMPSEL, val); + + mc_packet_add_write_if(MCI_IRQR, MCB_EIRQR); + + mc_packet_add_write_cd(MCI_EIRQSENSE, MCB_EIRQSENSE); + + if (id == MCDRV_DEV_ID_80_90H) { + *op_dac = mc_ana_register_get_value(19); + mc_packet_add_write_ana(19, 0); + } + + mc_dev_info_get(&info); + if (id == MCDRV_DEV_ID_80_90H) + mc_packet_add_write_ana(MCI_HPDETVOL, 0x70); + else + mc_packet_add_write_ana(MCI_HPDETVOL, info.options[9]); + + if (id == MCDRV_DEV_ID_80_90H) { + mc_packet_add_force_write_ana(78, T_CPMODE_IMPSENSE_BEFORE); + mc_packet_add_force_write_ana(87, 0x11); + } else { + mc_packet_add_force_write_if(31, 0xb5); + mc_packet_add_force_write_if(30, 0xd6); + mc_packet_add_force_write_ana(87, info.options[10]); + } + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + if (id == MCDRV_DEV_ID_80_90H) { + data[0] = MCI_ANA_REG_A << 1; + data[1] = 78; + mc_write_analog(data, 2); + mc_read_analog(MCI_ANA_REG_D, &val, 1); + if (val != T_CPMODE_IMPSENSE_BEFORE) { + ret = -EIO; + goto exit; + } + } + + val = E1COMMAND_IMP_SENSE; + if (info.gnd_det == MCDRV_GNDDET_ON) + val |= E1COMMAND_GND_DET; + if (mc_a_source_is_used(MCDRV_ASRC_DAC1_L_ON) || + mc_a_source_is_used(MCDRV_ASRC_DAC1_R_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_ADC0_L_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_ADC0_R_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_ADC1_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_PDM0_L_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_PDM0_R_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_PDM1_L_ON) || + mc_d2_source_is_used(MCDRV_D2SRC_PDM1_R_ON)) + val |= E1COMMAND_ADDITIONAL; + else if (mc_a_source_is_used(MCDRV_ASRC_DAC0_L_ON) || + mc_a_source_is_used(MCDRV_ASRC_DAC0_R_ON)) + val |= E1COMMAND_ADDITIONAL | E1COMMAND_PD; + + if (id == MCDRV_DEV_ID_80_90H) + mc_packet_add_wait(MCDRV_DAC_MUTE_WAIT_TIME); + else + val |= E1COMMAND_WAIT; + mc_packet_add_force_write_e(MCI_E1COMMAND, val); + + ret = mc_packet_execute(); + +exit: + return ret; +} +#endif + +static inline bool is_ldoa_on(void) +{ + if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH0)) + return true; + + if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH1)) + return true; + + if (mc_source_is_used(MCDRV_DST_ADC1, MCDRV_DST_CH0)) + return true; + + if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH0)) + return true; + + if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH1)) + return true; + + if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH2)) + return true; + + if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH3)) + return true; + + if (mc_a_source_is_used(MCDRV_ASRC_DAC0_L_ON)) + return true; + + if (mc_a_source_is_used(MCDRV_ASRC_DAC0_R_ON)) + return true; + + if (mc_a_source_is_used(MCDRV_ASRC_DAC1_L_ON)) + return true; + + if (mc_a_source_is_used(MCDRV_ASRC_DAC1_R_ON)) + return true; + + return false; +} + +static inline void mask_irregular_path_info(struct mcdrv_path_info *path_info) +{ + u8 ch; + + for (ch = 0; ch < MUSICOUT_PATH_CHANNELS; ch++) + path_info->music_out[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + + for (ch = 0; ch < EXTOUT_PATH_CHANNELS; ch++) + path_info->ext_out[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + + for (ch = 0; ch < HIFIOUT_PATH_CHANNELS; ch++) + path_info->hifi_out[ch] &= + MCDRV_D1SRC_ADIF0_ON | MCDRV_D1SRC_ADIF0_OFF; + + for (ch = 0; ch < VBOXMIXIN_PATH_CHANNELS; ch++) + path_info->vbox_mix_in[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + + for (ch = 0; ch < AE_PATH_CHANNELS; ch++) { + path_info->ae0[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + path_info->ae1[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + path_info->ae2[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + path_info->ae3[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + } + + for (ch = 0; ch < VOICEOUT_PATH_CHANNELS; ch++) + path_info->voice_out[ch] &= + MCDRV_D2SRC_VBOXIOOUT_ON | MCDRV_D2SRC_VBOXIOOUT_OFF; + + for (ch = 0; ch < VBOXIOIN_PATH_CHANNELS; ch++) + path_info->vbox_io_in[ch] &= + MCDRV_D2SRC_VOICEIN_ON | MCDRV_D2SRC_VOICEIN_OFF; + + for (ch = 0; ch < VBOXHOSTIN_PATH_CHANNELS; ch++) + path_info->vbox_host_in[ch] &= + MCDRV_D2SRC_VOICEIN_ON | MCDRV_D2SRC_VOICEIN_OFF; + + for (ch = 0; ch < HOSTOUT_PATH_CHANNELS; ch++) + path_info->host_out[ch] &= + MCDRV_D2SRC_VBOXHOSTOUT_ON | MCDRV_D2SRC_VBOXHOSTOUT_OFF; + + for (ch = 0; ch < ADIF0_PATH_CHANNELS; ch++) + path_info->adif0[ch] &= MCDRV_D2SRC_ADC0_L_ON + | MCDRV_D2SRC_ADC0_L_OFF + | MCDRV_D2SRC_ADC0_R_ON + | MCDRV_D2SRC_ADC0_R_OFF + | MCDRV_D2SRC_ADC1_ON + | MCDRV_D2SRC_ADC1_OFF + | MCDRV_D2SRC_PDM0_L_ON + | MCDRV_D2SRC_PDM0_L_OFF + | MCDRV_D2SRC_PDM0_R_ON + | MCDRV_D2SRC_PDM0_R_OFF + | MCDRV_D2SRC_PDM1_L_ON + | MCDRV_D2SRC_PDM1_L_OFF + | MCDRV_D2SRC_PDM1_R_ON | MCDRV_D2SRC_PDM1_R_OFF; + + for (ch = 0; ch < ADIF1_PATH_CHANNELS; ch++) + path_info->adif1[ch] &= MCDRV_D2SRC_ADC0_L_ON + | MCDRV_D2SRC_ADC0_L_OFF + | MCDRV_D2SRC_ADC0_R_ON + | MCDRV_D2SRC_ADC0_R_OFF + | MCDRV_D2SRC_ADC1_ON + | MCDRV_D2SRC_ADC1_OFF + | MCDRV_D2SRC_PDM0_L_ON + | MCDRV_D2SRC_PDM0_L_OFF + | MCDRV_D2SRC_PDM0_R_ON + | MCDRV_D2SRC_PDM0_R_OFF + | MCDRV_D2SRC_PDM1_L_ON + | MCDRV_D2SRC_PDM1_L_OFF + | MCDRV_D2SRC_PDM1_R_ON | MCDRV_D2SRC_PDM1_R_OFF; + + for (ch = 0; ch < ADIF2_PATH_CHANNELS; ch++) + path_info->adif2[ch] &= MCDRV_D2SRC_ADC0_L_ON + | MCDRV_D2SRC_ADC0_L_OFF + | MCDRV_D2SRC_ADC0_R_ON + | MCDRV_D2SRC_ADC0_R_OFF + | MCDRV_D2SRC_ADC1_ON + | MCDRV_D2SRC_ADC1_OFF + | MCDRV_D2SRC_PDM0_L_ON + | MCDRV_D2SRC_PDM0_L_OFF + | MCDRV_D2SRC_PDM0_R_ON + | MCDRV_D2SRC_PDM0_R_OFF + | MCDRV_D2SRC_PDM1_L_ON + | MCDRV_D2SRC_PDM1_L_OFF + | MCDRV_D2SRC_PDM1_R_ON + | MCDRV_D2SRC_PDM1_R_OFF + | MCDRV_D2SRC_DAC0REF_ON + | MCDRV_D2SRC_DAC0REF_OFF + | MCDRV_D2SRC_DAC1REF_ON | MCDRV_D2SRC_DAC1REF_OFF; + + path_info->adc0[0] &= ~(MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON | + MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_R_ON | + MCDRV_ASRC_LINEIN1_R_ON); + path_info->adc0[1] &= ~(MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON | + MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_R_ON | + MCDRV_ASRC_LINEIN1_L_ON); + + for (ch = 0; ch < ADC1_PATH_CHANNELS; ch++) + path_info->adc1[ch] &= ~(MCDRV_ASRC_DAC0_L_ON | + MCDRV_ASRC_DAC0_R_ON | + MCDRV_ASRC_DAC1_L_ON | + MCDRV_ASRC_DAC1_R_ON | + MCDRV_ASRC_LINEIN1_L_ON | + MCDRV_ASRC_LINEIN1_R_ON); + + path_info->sp[0] &= MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_L_OFF; + path_info->sp[1] &= MCDRV_ASRC_DAC1_R_ON | MCDRV_ASRC_DAC1_R_OFF; + + path_info->hp[0] &= MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_L_OFF; + path_info->hp[1] &= MCDRV_ASRC_DAC0_R_ON | MCDRV_ASRC_DAC0_R_OFF; + + path_info->rc[0] &= MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_L_OFF; + + path_info->lout1[0] &= MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_L_OFF; + path_info->lout1[1] &= MCDRV_ASRC_DAC0_R_ON | MCDRV_ASRC_DAC0_R_OFF; + + path_info->lout2[0] &= MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_L_OFF; + path_info->lout2[1] &= MCDRV_ASRC_DAC1_R_ON | MCDRV_ASRC_DAC1_R_OFF; + + path_info->bias[0] &= MCDRV_ASRC_MIC1_ON | MCDRV_ASRC_MIC1_OFF; + path_info->bias[1] &= MCDRV_ASRC_MIC2_ON | MCDRV_ASRC_MIC2_OFF; + path_info->bias[2] &= MCDRV_ASRC_MIC3_ON | MCDRV_ASRC_MIC3_OFF; + path_info->bias[3] &= MCDRV_ASRC_MIC4_ON | MCDRV_ASRC_MIC4_OFF; +} + +static inline bool is_valid_dio_path_info(struct mcdrv_dio_path_info + *dio_path_info, unsigned int update) +{ + struct mcdrv_dio_path_info curr_dio_path_info; + u8 val; + bool LP0_start = false, LP1_start = false; + bool LP2_start = false, LP3_start = false; + bool ret = true; + + val = mc_mb_register_get_value(MCI_LP0_START); + if (val & (MCB_LPR0_START | MCB_LPT0_START)) + LP0_start = true; + + val = mc_mb_register_get_value(MCI_LP1_START); + if (val & (MCB_LPR1_START | MCB_LPT1_START)) + LP1_start = true; + + val = mc_mb_register_get_value(MCI_LP2_START); + if (val & (MCB_LPR2_START | MCB_LPT2_START)) + LP2_start = true; + + val = mc_mb_register_get_value(MCI_LP3_START); + if (val & (MCB_LPR3_START | MCB_LPT3_START)) + LP3_start = true; + + mc_dio_path_info_get(&curr_dio_path_info); + + if (update & MCDRV_MUSICNUM_UPDATE_FLAG) { + if (dio_path_info->music_ch > MCDRV_MUSIC_LAST) { + ret = false; + goto exit; + } else if (dio_path_info->music_ch != + curr_dio_path_info.music_ch) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_PHYS0_UPDATE_FLAG) { + if (dio_path_info->phys_port[0] > MCDRV_PHYSPORT_LAST) { + ret = false; + goto exit; + } else if (dio_path_info->phys_port[0] != + curr_dio_path_info.phys_port[0]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_PHYS1_UPDATE_FLAG) { + if (dio_path_info->phys_port[1] > MCDRV_PHYSPORT_LAST) { + ret = false; + goto exit; + } else if (dio_path_info->phys_port[1] != + curr_dio_path_info.phys_port[1]) { + if (LP1_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_PHYS2_UPDATE_FLAG) { + if (dio_path_info->phys_port[2] > MCDRV_PHYSPORT_LAST) { + ret = false; + goto exit; + } else if (dio_path_info->phys_port[2] != + curr_dio_path_info.phys_port[2]) { + if (LP2_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_PHYS3_UPDATE_FLAG) { + if (dio_path_info->phys_port[3] > MCDRV_PHYSPORT_LAST) { + ret = false; + goto exit; + } else if (dio_path_info->phys_port[3] != + curr_dio_path_info.phys_port[3]) { + if (LP3_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_DIR0SLOT_UPDATE_FLAG) { + if (dio_path_info->music_rslot[0] > 3) { + ret = false; + goto exit; + } else if (dio_path_info->music_rslot[0] != + curr_dio_path_info.music_rslot[0]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_DIR1SLOT_UPDATE_FLAG) { + if (dio_path_info->music_rslot[1] > 3) { + ret = false; + } else if (dio_path_info->music_rslot[1] != + curr_dio_path_info.music_rslot[1]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_DIR2SLOT_UPDATE_FLAG) { + if (dio_path_info->music_rslot[2] > 3) { + ret = false; + } else if (dio_path_info->music_rslot[2] != + curr_dio_path_info.music_rslot[2]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_DIT0SLOT_UPDATE_FLAG) { + if (dio_path_info->music_tslot[0] > 3) { + ret = false; + } else if (dio_path_info->music_tslot[0] != + curr_dio_path_info.music_tslot[0]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_DIT1SLOT_UPDATE_FLAG) { + if (dio_path_info->music_tslot[1] > 3) { + ret = false; + } else if (dio_path_info->music_tslot[1] != + curr_dio_path_info.music_tslot[1]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + + if (update & MCDRV_DIT2SLOT_UPDATE_FLAG) { + if (dio_path_info->music_tslot[2] > 3) { + ret = false; + } else if (dio_path_info->music_tslot[2] != + curr_dio_path_info.music_tslot[2]) { + if (LP0_start) { + ret = false; + goto exit; + } + } + } + +exit: + return ret; +} + +static inline bool is_valid_swap_info(struct mcdrv_swap_info *info, + unsigned int update) +{ + bool ret = true; + + if (update & MCDRV_SWAP_ADIF0_UPDATE_FLAG) + if (info->adif0 > MCDRV_SWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_ADIF1_UPDATE_FLAG) + if (info->adif1 > MCDRV_SWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_ADIF2_UPDATE_FLAG) + if (info->adif2 > MCDRV_SWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_DAC0_UPDATE_FLAG) + if (info->dac0 > MCDRV_SWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_DAC1_UPDATE_FLAG) + if (info->dac1 > MCDRV_SWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_MUSICIN0_UPDATE_FLAG) + if (info->music_in0 > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_MUSICIN1_UPDATE_FLAG) + if (info->music_in1 > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_MUSICIN2_UPDATE_FLAG) + if (info->music_in2 > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_EXTIN_UPDATE_FLAG) + if (info->ext_in > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_VOICEIN_UPDATE_FLAG) + if (info->voice_in > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_HIFIIN_UPDATE_FLAG) + if (info->hifi_in > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG) + if (info->music_out0 > MCDRV_SWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG) + if (info->music_out1 > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG) + if (info->music_out2 > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_EXTOUT_UPDATE_FLAG) + if (info->ext_out > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_VOICEOUT_UPDATE_FLAG) + if (info->voice_out > MCDRV_SWSWAP_LAST) + ret = false; + + if (update & MCDRV_SWAP_HIFIOUT_UPDATE_FLAG) + if (info->hifi_out > MCDRV_SWSWAP_LAST) + ret = false; + + return ret; +} + +static inline bool is_valid_aec_info(struct mcdrv_aec_info *info) +{ + struct mcdrv_aec_info curr_info; + bool bdsp_used = false, cdsp_used = false, fdsp_used = false; + bool ret = true; + + mc_aec_info_get(&curr_info); + + if (mc_d1_source_is_used(MCDRV_D1SRC_AE0_ON | MCDRV_D1SRC_AE1_ON | + MCDRV_D1SRC_AE2_ON | MCDRV_D1SRC_AE3_ON)) { + bdsp_used = true; + if (!curr_info.fdsp_locate) + fdsp_used = true; + } + + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3) || + mc_source_is_used(MCDRV_DST_VBOXHOSTIN, MCDRV_DST_CH0)) { + cdsp_used = true; + if (curr_info.fdsp_locate) + fdsp_used = true; + } + + if (bdsp_used || cdsp_used || fdsp_used) + if (info->fdsp_locate != 0xFF) + if (info->fdsp_locate != curr_info.fdsp_locate) { + ret = false; + goto exit; + } + + if (bdsp_used || fdsp_used) + if (info->audio_engine.enable) { + if (info->audio_engine.bdsp_ae0_src != 2 && + info->audio_engine.bdsp_ae0_src != + curr_info.audio_engine.bdsp_ae0_src) { + ret = false; + goto exit; + } + + if (info->audio_engine.bdsp_ae1_src != 2 && + info->audio_engine.bdsp_ae1_src != + curr_info.audio_engine.bdsp_ae1_src) { + ret = false; + goto exit; + } + if (info->audio_engine.mixer_in0_src != 2 && + info->audio_engine.mixer_in0_src != + curr_info.audio_engine.mixer_in0_src) { + ret = false; + goto exit; + } + + if (info->audio_engine.mixer_in1_src != 2 && + info->audio_engine.mixer_in1_src != + curr_info.audio_engine.mixer_in1_src) { + ret = false; + goto exit; + } + if (info->audio_engine.mixer_in2_src != 2 && + info->audio_engine.mixer_in2_src != + curr_info.audio_engine.mixer_in2_src) { + ret = false; + goto exit; + } + + if (info->audio_engine.mixer_in3_src != 2 && + info->audio_engine.mixer_in3_src != + curr_info.audio_engine.mixer_in3_src) { + ret = false; + goto exit; + } + } + + if (cdsp_used || fdsp_used) + if (info->vbox.enable) { + if (info->vbox.fdsp_po_source != 0xFF && + info->vbox.fdsp_po_source != + curr_info.vbox.fdsp_po_source) { + ret = false; + goto exit; + } + + if (info->vbox.isrc2_vsource != 0xFF && + info->vbox.isrc2_vsource != + curr_info.vbox.isrc2_vsource) { + ret = false; + goto exit; + } + + if (info->vbox.isrc2_ch1_vsource != 0xFF && + info->vbox.isrc2_ch1_vsource != + curr_info.vbox.isrc2_ch1_vsource) { + ret = false; + goto exit; + } + + if (info->vbox.isrc3_vsource != 0xFF && + info->vbox.isrc3_vsource != + curr_info.vbox.isrc3_vsource) { + ret = false; + goto exit; + } + + if (info->vbox.lpt2_vsource != 0xFF && + info->vbox.lpt2_vsource != + curr_info.vbox.lpt2_vsource) { + ret = false; + goto exit; + } + } + + if (cdsp_used) + if (info->vbox.enable) { + if (info->vbox.src3_ctrl != 0xFF && + info->vbox.src3_ctrl != curr_info.vbox.src3_ctrl) { + ret = false; + goto exit; + } + + if (info->vbox.src2_fs != 0xFF && + info->vbox.src2_fs != curr_info.vbox.src2_fs) { + ret = false; + goto exit; + } + + if (info->vbox.src2_thru != 0xFF && + info->vbox.src2_thru != curr_info.vbox.src2_thru) { + ret = false; + goto exit; + } + + if (info->vbox.src3_fs != 0xFF && + info->vbox.src3_fs != curr_info.vbox.src3_fs) { + ret = false; + goto exit; + } + + if (info->vbox.src3_thru != 0xFF && + info->vbox.src3_thru != curr_info.vbox.src3_thru) { + ret = false; + goto exit; + } + } + +exit: + return ret; +} + +static bool is_valid_hsdet_info(struct mcdrv_hsdet_info *info, + unsigned int update) +{ + struct mcdrv_hsdet_info hsdet_info; + + mc_hsdet_info_get(&hsdet_info); + + if (update & MCDRV_ENPLUGDET_UPDATE_FLAG) + if (info->en_plug_det_db > MCDRV_PLUGDETDB_LAST) + return false; + + if (update & MCDRV_ENDLYKEYOFF_UPDATE_FLAG) + if (info->en_dly_key_off > MCDRV_KEYEN_LAST) + return false; + + if (update & MCDRV_ENDLYKEYON_UPDATE_FLAG) + if (info->en_dly_key_on > MCDRV_KEYEN_LAST) + return false; + + if (update & MCDRV_ENKEYOFF_UPDATE_FLAG) + if (info->en_key_off > MCDRV_KEYEN_LAST) + return false; + + if (update & MCDRV_ENKEYON_UPDATE_FLAG) + if (info->en_key_on > MCDRV_KEYEN_LAST) + return false; + + if (update & MCDRV_HSDETDBNC_UPDATE_FLAG) + if (info->hs_det_dbnc > MCDRV_DETDBNC_LAST) + return false; + + if (update & MCDRV_KEYOFFMTIM_UPDATE_FLAG) + hsdet_info.key_off_mtim = info->key_off_mtim; + + if (update & MCDRV_KEYONMTIM_UPDATE_FLAG) + hsdet_info.key_on_mtim = info->key_on_mtim; + + if (update & MCDRV_KEY0OFFDLYTIM_UPDATE_FLAG) { + if (info->key0_off_dly_tim > MC_DRV_KEYOFFDLYTIM_MAX) + return false; + else if (hsdet_info.key_off_mtim == MCDRV_KEYOFF_MTIM_63 && + info->key0_off_dly_tim == 1) + return false; + } + + if (update & MCDRV_KEY1OFFDLYTIM_UPDATE_FLAG) { + if (info->key1_off_dly_tim > MC_DRV_KEYOFFDLYTIM_MAX) + return false; + else if (hsdet_info.key_off_mtim == MCDRV_KEYOFF_MTIM_63 && + info->key1_off_dly_tim == 1) + return false; + } + + if (update & MCDRV_KEY2OFFDLYTIM_UPDATE_FLAG) { + if (info->key2_off_dly_tim > MC_DRV_KEYOFFDLYTIM_MAX) + return false; + else if (hsdet_info.key_off_mtim == MCDRV_KEYOFF_MTIM_63 && + info->key2_off_dly_tim == 1) + return false; + } + + if (update & MCDRV_KEY0ONDLYTIM_UPDATE_FLAG) { + if (info->key0_on_dly_tim > MC_DRV_KEYONDLYTIM_MAX) + return false; + else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 && + (info->key0_on_dly_tim == 1 || + info->key0_on_dly_tim == 2 || + info->key0_on_dly_tim == 3)) + return false; + } + + if (update & MCDRV_KEY1ONDLYTIM_UPDATE_FLAG) { + if (info->key1_on_dly_tim > MC_DRV_KEYONDLYTIM_MAX) + return false; + else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 && + (info->key1_on_dly_tim == 1 || + info->key1_on_dly_tim == 2 || + info->key1_on_dly_tim == 3)) + return false; + } + + if (update & MCDRV_KEY2ONDLYTIM_UPDATE_FLAG) { + if (info->key2_on_dly_tim > MC_DRV_KEYONDLYTIM_MAX) + return false; + else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 && + (info->key2_on_dly_tim == 1 || + info->key2_on_dly_tim == 2 || + info->key2_on_dly_tim == 3)) + return false; + } + + if (update & MCDRV_KEY0ONDLYTIM2_UPDATE_FLAG) { + if (info->key0_on_dly_tim2 > MC_DRV_KEYONDLYTIM2_MAX) + return false; + else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 && + (info->key0_on_dly_tim2 == 1 || + info->key0_on_dly_tim2 == 2 || + info->key0_on_dly_tim2 == 3)) + return false; + } + + if (update & MCDRV_KEY1ONDLYTIM2_UPDATE_FLAG) { + if (info->key1_on_dly_tim2 > MC_DRV_KEYONDLYTIM2_MAX) + return false; + else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 && + (info->key1_on_dly_tim2 == 1 || + info->key1_on_dly_tim2 == 2 || + info->key1_on_dly_tim2 == 3)) + return false; + } + + if (update & MCDRV_KEY2ONDLYTIM2_UPDATE_FLAG) { + if (info->key2_on_dly_tim2 > MC_DRV_KEYONDLYTIM2_MAX) + return false; + else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 && + (info->key2_on_dly_tim2 == 1 || + info->key2_on_dly_tim2 == 2 || + info->key2_on_dly_tim2 == 3)) + return false; + } + + if (update & MCDRV_IRQTYPE_UPDATE_FLAG) { + if (info->irq_type == MCDRV_IRQTYPE_EX) { + if (info->plug_det_db_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->plug_undet_db_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->mic_det_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->plug_det_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->key0_on_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->key1_on_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->key2_on_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->key0_off_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->key1_off_irq_type > MCDRV_IRQTYPE_REF) + return false; + if (info->key2_off_irq_type > MCDRV_IRQTYPE_REF) + return false; + } else if (info->irq_type > MCDRV_IRQTYPE_LAST) + return false; + } + + if (update & MCDRV_DETINV_UPDATE_FLAG) + if (info->det_in_inv > MCDRV_DET_IN_LAST) + return false; + + if (update & MCDRV_HSDETMODE_UPDATE_FLAG) + if (info->hs_det_mode != MCDRV_HSDET_MODE_DETIN_A && + info->hs_det_mode != MCDRV_HSDET_MODE_DETIN_B) + return false; + + if (update & MCDRV_SPERIOD_UPDATE_FLAG) + if (info->speriod > MCDRV_SPERIOD_LAST) + return false; + + if (update & MCDRV_LPERIOD_UPDATE_FLAG) + if (info->lperiod > MCDRV_LPERIOD_LAST) + return false; + + if (update & MCDRV_DBNCNUMPLUG_UPDATE_FLAG) + if (info->dbnc_num_plug > MCDRV_DBNC_NUM_LAST) + return false; + + if (update & MCDRV_DBNCNUMMIC_UPDATE_FLAG) + if (info->dbnc_num_mic > MCDRV_DBNC_NUM_LAST) + return false; + + if (update & MCDRV_DBNCNUMKEY_UPDATE_FLAG) + if (info->dbnc_num_key > MCDRV_DBNC_NUM_LAST) + return false; + + if (update & MCDRV_SGNL_UPDATE_FLAG) { + if (info->sgnl_period > MCDRV_SGNLPERIOD_LAST) + return false; + + if (info->sgnl_num != MCDRV_SGNLNUM_NONE + && info->sgnl_num > MCDRV_SGNLNUM_LAST) + return false; + + if (info->sgnl_peak > MCDRV_SGNLPEAK_LAST) + return false; + } + + return true; +} + +static bool check_dio_common(struct mcdrv_dio_info *dio_info, u8 port) +{ + struct mcdrv_dio_common *dio_common; + bool ret = true; + + dio_common = &dio_info->port[port].dio_common; + + if (port == 3) { + if (dio_common->fs != MCDRV_FS_48000 && + dio_common->fs != MCDRV_FS_192000 && + dio_common->fs != MCDRV_FS_96000) { + ret = false; + goto exit; + } + + if (dio_common->bck_fs != MCDRV_BCKFS_64 && + dio_common->bck_fs != MCDRV_BCKFS_48 && + dio_common->bck_fs != MCDRV_BCKFS_32) + ret = false; + goto exit; + } + + if (dio_common->fs > MCDRV_FS_LAST || + dio_common->fs == MCDRV_FS_NONE1 || + dio_common->fs == MCDRV_FS_NONE2 || + dio_common->fs == MCDRV_FS_NONE3) + ret = false; + else if (dio_common->bck_fs > MCDRV_BCKFS_LAST || + dio_common->bck_fs == MCDRV_BCKFS_NONE1 || + dio_common->bck_fs == MCDRV_BCKFS_NONE2 || + dio_common->bck_fs == MCDRV_BCKFS_NONE3 || + dio_common->bck_fs == MCDRV_BCKFS_NONE4) + ret = false; + else if (dio_common->interface == MCDRV_DIO_PCM && + dio_common->pcm_high_period > 31) + ret = false; + + if (dio_common->interface == MCDRV_DIO_PCM) { + if (dio_common->fs != MCDRV_FS_8000 && + dio_common->fs != MCDRV_FS_16000) + ret = false; + + if (dio_common->bck_fs == MCDRV_BCKFS_512 && + dio_common->fs != MCDRV_FS_8000) + ret = false; + + if (dio_common->bck_fs == MCDRV_BCKFS_256 && + (dio_common->fs != MCDRV_FS_8000 && + dio_common->fs != MCDRV_FS_16000)) + ret = false; + + if (dio_common->master_slave == MCDRV_DIO_MASTER && + dio_common->bck_fs == MCDRV_BCKFS_SLAVE) + ret = false; + } else { + if (port == 0 || port == 1) { + if (dio_common->fs == MCDRV_FS_192000 || + dio_common->fs == MCDRV_FS_96000) + ret = false; + } + + if (dio_common->bck_fs != MCDRV_BCKFS_64 && + dio_common->bck_fs != MCDRV_BCKFS_48 && + dio_common->bck_fs != MCDRV_BCKFS_32) + ret = false; + } + +exit: + return ret; +} + +static bool check_da_format(struct mcdrv_da_format *da_format) +{ + bool ret = true; + + if (da_format->bit_sel > MCDRV_BITSEL_LAST) + ret = false; + else if (da_format->mode > MCDRV_DAMODE_LAST) + ret = false; + + return ret; +} + +static bool check_pcm_format(struct mcdrv_pcm_format *pcm_format) +{ + bool ret = true; + + if (pcm_format->law > MCDRV_PCM_LAST) + ret = false; + else if (pcm_format->bit_sel > MCDRV_PCM_BITSEL_LAST) + ret = false; + else if ((pcm_format->law == MCDRV_PCM_ALAW || + pcm_format->law == MCDRV_PCM_MULAW) && + pcm_format->bit_sel != MCDRV_PCM_BITSEL_8) + ret = false; + + return ret; +} + +static bool check_dio_dir(struct mcdrv_dio_info *dio_info, + u8 port, u8 interface) +{ + bool ret = true; + + if (interface == MCDRV_DIO_PCM) + ret = check_pcm_format(&dio_info->port[port].dir.pcm_format); + else { + ret = check_da_format(&dio_info->port[port].dir.da_format); + if (dio_info->port[port].dir.da_format.bit_sel == + MCDRV_BITSEL_32) + ret = false; + } + + return ret; +} + +static bool check_dio_dit(struct mcdrv_dio_info *dio_info, + u8 port, u8 interface) +{ + bool ret = true; + + if (interface == MCDRV_DIO_PCM) + ret = check_pcm_format(&dio_info->port[port].dit.pcm_format); + else { + ret = check_da_format(&dio_info->port[port].dit.da_format); + if (dio_info->port[port].dit.da_format.bit_sel == + MCDRV_BITSEL_32 && port != 2) + ret = false; + } + + return ret; +} + +static inline bool is_valid_dio_info(struct mcdrv_dio_info *dio_info, + unsigned int update) +{ + struct mcdrv_dio_info curr_dio_info; + u8 val; + bool LPR0_start = 0, LPT0_start = 0; + bool LPR1_start = 0, LPT1_start = 0; + bool LPR2_start = 0, LPT2_start = 0; + bool LPR3_start = 0, LPT3_start = 0; + bool ret = true; + + mc_dio_info_get(&curr_dio_info); + + val = mc_mb_register_get_value(MCI_LP0_START); + if (val & MCB_LPR0_START) + LPR0_start = true; + if (val & MCB_LPT0_START) + LPT0_start = true; + + val = mc_mb_register_get_value(MCI_LP1_START); + if (val & MCB_LPR1_START) + LPR1_start = true; + if (val & MCB_LPT1_START) + LPT1_start = true; + + val = mc_mb_register_get_value(MCI_LP2_START); + if (val & MCB_LPR2_START) + LPR2_start = true; + if (val & MCB_LPT2_START) + LPT2_start = true; + + val = mc_mb_register_get_value(MCI_LP3_START); + if (val & MCB_LPR3_START) + LPR3_start = true; + if (val & MCB_LPT3_START) + LPT3_start = true; + + if ((update & MCDRV_MUSIC_COM_UPDATE_FLAG) || + (update & MCDRV_MUSIC_DIR_UPDATE_FLAG)) { + if (LPR0_start) + ret = false; + } + + if ((update & MCDRV_MUSIC_COM_UPDATE_FLAG) || + (update & MCDRV_MUSIC_DIT_UPDATE_FLAG)) { + if (LPT0_start) + ret = false; + } + + if ((update & MCDRV_EXT_COM_UPDATE_FLAG) || + (update & MCDRV_EXT_DIR_UPDATE_FLAG)) { + if (LPR1_start) + ret = false; + } + + if ((update & MCDRV_EXT_COM_UPDATE_FLAG) || + (update & MCDRV_EXT_DIT_UPDATE_FLAG)) { + if (LPT1_start) + ret = false; + } + + if ((update & MCDRV_VOICE_COM_UPDATE_FLAG) || + (update & MCDRV_VOICE_DIR_UPDATE_FLAG)) { + if (LPR2_start) + ret = false; + } + + if ((update & MCDRV_VOICE_COM_UPDATE_FLAG) || + (update & MCDRV_VOICE_DIT_UPDATE_FLAG)) { + if (LPT2_start) + ret = false; + } + + if ((update & MCDRV_HIFI_COM_UPDATE_FLAG) || + (update & MCDRV_HIFI_DIR_UPDATE_FLAG)) { + if (LPR3_start) + ret = false; + } + + if ((update & MCDRV_HIFI_COM_UPDATE_FLAG) || + (update & MCDRV_HIFI_DIT_UPDATE_FLAG)) { + if (LPT3_start) + ret = false; + } + + if (ret && (update & MCDRV_MUSIC_COM_UPDATE_FLAG)) { + ret = check_dio_common(dio_info, 0); + if (ret) + curr_dio_info.port[0].dio_common.interface + = dio_info->port[0].dio_common.interface; + } + + if (ret && (update & MCDRV_EXT_COM_UPDATE_FLAG)) { + ret = check_dio_common(dio_info, 1); + if (ret) + curr_dio_info.port[1].dio_common.interface + = dio_info->port[1].dio_common.interface; + } + + if (ret && (update & MCDRV_VOICE_COM_UPDATE_FLAG)) { + ret = check_dio_common(dio_info, 2); + if (ret) + curr_dio_info.port[2].dio_common.interface + = dio_info->port[2].dio_common.interface; + } + + if (ret && (update & MCDRV_HIFI_COM_UPDATE_FLAG)) { + ret = check_dio_common(dio_info, 3); + if (ret) + curr_dio_info.port[3].dio_common.interface + = dio_info->port[3].dio_common.interface; + } + + if (ret && (update & MCDRV_MUSIC_DIR_UPDATE_FLAG)) { + ret = check_dio_dir(dio_info, 0, + curr_dio_info.port[0].dio_common.interface); + } + + if (ret && (update & MCDRV_EXT_DIR_UPDATE_FLAG)) { + ret = check_dio_dir(dio_info, 1, + curr_dio_info.port[1].dio_common.interface); + } + + if (ret && (update & MCDRV_VOICE_DIR_UPDATE_FLAG)) { + ret = check_dio_dir(dio_info, 2, + curr_dio_info.port[2].dio_common.interface); + } + + if (ret && (update & MCDRV_MUSIC_DIT_UPDATE_FLAG)) { + ret = check_dio_dit(dio_info, 0, + curr_dio_info.port[0].dio_common.interface); + } + + if (ret && (update & MCDRV_EXT_DIT_UPDATE_FLAG)) + ret = check_dio_dit(dio_info, 1, + curr_dio_info.port[1].dio_common.interface); + + if (ret && (update & MCDRV_VOICE_DIT_UPDATE_FLAG)) + ret = check_dio_dit(dio_info, 2, + curr_dio_info.port[2].dio_common.interface); + + return ret; +} + +static inline int set_vol(u32 update, enum mcdrv_volume_mode mode, u32 *status) +{ + mc_packet_add_volume(update, mode, status); + + return mc_packet_execute(); +} + +static inline void get_mute(u8 *dir_mute, u8 *adc_mute, + u8 *dit_mute, u8 *dac_mute) +{ + u8 vol; + + *dir_mute = 0; + *adc_mute = 0; + *dit_mute = 0; + *dac_mute = 0; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) { + vol = mc_ma_register_get_value(MCI_DIFI0_VOL0); + if (vol & ~MCB_DIFI0_VSEP) + *dir_mute |= MCB_DIFI0_VFLAG0; + + vol = mc_ma_register_get_value(MCI_DIFI0_VOL1); + if (vol) + *dir_mute |= MCB_DIFI0_VFLAG1; + } + + if (!mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) { + vol = mc_ma_register_get_value(MCI_DIFI1_VOL0); + if (vol & ~MCB_DIFI1_VSEP) + *dir_mute |= MCB_DIFI1_VFLAG0; + + vol = mc_ma_register_get_value(MCI_DIFI1_VOL1); + if (vol) + *dir_mute |= MCB_DIFI1_VFLAG1; + } + + if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) { + vol = mc_ma_register_get_value(MCI_DIFI2_VOL0); + if (vol & ~MCB_DIFI2_VSEP) + *dir_mute |= MCB_DIFI2_VFLAG0; + + vol = mc_ma_register_get_value(MCI_DIFI2_VOL1); + if (vol) + *dir_mute |= MCB_DIFI2_VFLAG1; + } + + if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) { + vol = mc_ma_register_get_value(MCI_DIFI3_VOL0); + if (vol & ~MCB_DIFI3_VSEP) + *dir_mute |= MCB_DIFI3_VFLAG0; + + vol = mc_ma_register_get_value(MCI_DIFI3_VOL1); + if (vol) + *dir_mute |= MCB_DIFI3_VFLAG1; + } + + if (!mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0)) { + vol = mc_ma_register_get_value(MCI_DAO0_VOL0); + if (vol & ~MCB_DAO0_VSEP) + *dac_mute |= MCB_DAO0_VFLAG0; + } + + if (!mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1)) { + vol = mc_ma_register_get_value(MCI_DAO0_VOL1); + if (vol) + *dac_mute |= MCB_DAO0_VFLAG1; + } + + if (!mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0)) { + vol = mc_ma_register_get_value(MCI_DAO1_VOL0); + if (vol & ~MCB_DAO1_VSEP) + *dac_mute |= MCB_DAO1_VFLAG0; + } + + if (!mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) { + vol = mc_ma_register_get_value(MCI_DAO1_VOL1); + if (vol) + *dac_mute |= MCB_DAO1_VFLAG1; + } + + if (!mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0)) { + vol = mc_ma_register_get_value(MCI_DIFO0_VOL0); + if (vol & ~MCB_DIFO0_VSEP) + *dit_mute |= MCB_DIFO0_VFLAG0; + } + + if (!mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1)) { + vol = mc_ma_register_get_value(MCI_DIFO0_VOL1); + if (vol) + *dit_mute |= MCB_DIFO0_VFLAG1; + + } + + if (!mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0)) { + vol = mc_ma_register_get_value(MCI_DIFO1_VOL0); + if (vol & ~MCB_DIFO1_VSEP) + *dit_mute |= MCB_DIFO1_VFLAG0; + } + + if (!mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) { + vol = mc_ma_register_get_value(MCI_DIFO1_VOL1); + if (vol) + *dit_mute |= MCB_DIFO1_VFLAG1; + } + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0)) { + vol = mc_ma_register_get_value(MCI_DIFO2_VOL0); + if (vol & ~MCB_DIFO2_VSEP) + *dit_mute |= MCB_DIFO2_VFLAG0; + } + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) { + vol = mc_ma_register_get_value(MCI_DIFO2_VOL1); + if (vol) + *dit_mute |= MCB_DIFO2_VFLAG1; + } + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2)) { + vol = mc_ma_register_get_value(MCI_DIFO3_VOL0); + if (vol & ~MCB_DIFO2_VSEP) + *dit_mute |= MCB_DIFO3_VFLAG0; + } + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) { + vol = mc_ma_register_get_value(MCI_DIFO3_VOL1); + if (vol) + *dit_mute |= MCB_DIFO3_VFLAG1; + } + + if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF0_ON)) { + vol = mc_ma_register_get_value(MCI_ADI0_VOL0); + if (vol & ~MCB_ADI0_VSEP) + *adc_mute |= MCB_ADI0_VFLAG0; + vol = mc_ma_register_get_value(MCI_ADI0_VOL1); + if (vol) + *adc_mute |= MCB_ADI0_VFLAG1; + } + + if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF1_ON)) { + vol = mc_ma_register_get_value(MCI_ADI1_VOL1); + if (vol & ~MCB_ADI1_VSEP) + *adc_mute |= MCB_ADI1_VFLAG0; + vol = mc_ma_register_get_value(MCI_ADI1_VOL1); + if (vol) + *adc_mute |= MCB_ADI1_VFLAG1; + } + + if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF2_ON)) { + vol = mc_ma_register_get_value(MCI_ADI2_VOL1); + if (vol & ~MCB_ADI2_VSEP) + *adc_mute |= MCB_ADI2_VFLAG0; + + vol = mc_ma_register_get_value(MCI_ADI2_VOL1); + if (vol) + *adc_mute |= MCB_ADI2_VFLAG1; + } +} + +static int save_power(void) +{ + struct mcdrv_power_info power; + struct mcdrv_power_update update; + int ret; + + /* unused path power down */ + mc_power_info_get(&power); + + update.digital = MCDRV_POWUPDATE_D_ALL; + update.analog[0] = MCDRV_POWUPDATE_AP; + update.analog[1] = MCDRV_POWUPDATE_AP_OUT0; + update.analog[2] = MCDRV_POWUPDATE_AP_OUT1; + update.analog[3] = MCDRV_POWUPDATE_AP_MC; + update.analog[4] = MCDRV_POWUPDATE_AP_IN; + + ret = mc_packet_add_powerdown(&power, &update); + if (!ret) + ret = mc_packet_execute(); + + return ret; +} + +static inline bool is_valid_clock(u8 clock) +{ + if (clock != MCDRV_CLKSW_CLKA && clock != MCDRV_CLKSW_CLKB) + return false; + + return true; +} + +static inline int get_clock(u8 *clock) +{ + + mc_clock_get(clock); + + return 0; +} + +static inline int set_clock(u8 *clock) +{ + u8 old_clock; + + if (!is_valid_clock(*clock)) + return -EINVAL; + + mc_clock_get(&old_clock); + if (*clock == old_clock) + return 0; + + return mc_clock_set(*clock); +} + +static inline int get_path(struct mcdrv_path_info *path_info) +{ + if (!path_info) + return -EINVAL; + + mc_path_info_get_virtual(path_info); + + return 0; +} + +static int set_path(struct mcdrv_path_info *path_info) +{ + struct mcdrv_power_info power; + struct mcdrv_power_update update; + u32 status; + u8 val, dir_mute, adc_mute, dit_mute, dac_mute, hp_vol_l, hp_vol_r; + u8 dsp_started = mc_dsp_get_running(); + int ret; + + if (!path_info) + return -EINVAL; + + mask_irregular_path_info(path_info); + + ret = mc_path_info_set(path_info); + if (ret < 0) + return ret; + + hp_vol_l = mc_ana_register_get_value(MCI_HPVOL_L); + hp_vol_l &= ~MCB_ALAT_HP; + hp_vol_r = mc_ana_register_get_value(MCI_HPVOL_R); + + /* unused analog out volume mute */ + ret = set_vol(MCDRV_VOLUPDATE_ANA_OUT, MCDRV_VOLUME_MUTE, &status); + if (ret < 0) + return ret; + + if (status) + mc_packet_add_wait_event(MCDRV_EVT_SVOL_DONE | status); + + get_mute(&dir_mute, &adc_mute, &dit_mute, &dac_mute); + + /* unused volume mute */ + ret = set_vol(MCDRV_VOLUPDATE_DIG, MCDRV_VOLUME_MUTE, NULL); + if (ret < 0) + return ret; + + /* set volume */ + ret = set_vol(MCDRV_VOLUPDATE_ANA_IN, MCDRV_VOLUME_SET, NULL); + if (ret < 0) + return ret; + + if (dir_mute) + mc_packet_add_wait_event(MCDRV_EVT_DIRMUTE | dir_mute); + + if (adc_mute) + mc_packet_add_wait_event(MCDRV_EVT_ADCMUTE | adc_mute); + + if (dit_mute) + mc_packet_add_wait_event(MCDRV_EVT_DITMUTE | dit_mute); + + if (dac_mute) + mc_packet_add_wait_event(MCDRV_EVT_DACMUTE | dac_mute); + + mc_packet_add_fdsp_stop(dsp_started); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* stop unused path */ + mc_packet_add_stop(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_power_info_get(&power); + + /* unused analog out path power down */ + update.digital = 0; + update.analog[0] = 0; + update.analog[1] = MCDRV_POWUPDATE_AP_OUT0; + update.analog[2] = MCDRV_POWUPDATE_AP_OUT1; + update.analog[3] = 0; + update.analog[4] = 0; + ret = mc_packet_add_powerdown(&power, &update); + if (ret < 0) + return ret; + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* used path power up */ + update.digital = MCDRV_POWUPDATE_D_ALL; + update.analog[0] = MCDRV_POWUPDATE_AP; + update.analog[1] = MCDRV_POWUPDATE_AP_OUT0; + update.analog[2] = MCDRV_POWUPDATE_AP_OUT1; + update.analog[3] = MCDRV_POWUPDATE_AP_MC; + update.analog[4] = MCDRV_POWUPDATE_AP_IN; + ret = mc_packet_add_powerup(&power, &update); + if (ret < 0) + return ret; + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* set mixer */ + mc_packet_add_path_set(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* DSP start */ + mc_packet_add_dsp_start_and_stop(dsp_started); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + if ((hp_vol_l || hp_vol_r) + && (!hp_vol_l || (status & (MCB_HPL_BUSY << 8))) + && (!hp_vol_r || (status & (MCB_HPR_BUSY << 8))) + && (power.analog[3] & MCB_MB4)) { + val = mc_ana_register_get_value(MCI_AP_MIC); + if (!(val & MCB_MB4)) + mc_packet_add_wait(MCDRV_MB4_WAIT_TIME); + } + + /* unused path power down */ + update.digital = MCDRV_POWUPDATE_D_ALL; + update.analog[0] = MCDRV_POWUPDATE_AP; + update.analog[1] = MCDRV_POWUPDATE_AP_OUT0; + update.analog[2] = MCDRV_POWUPDATE_AP_OUT1; + update.analog[3] = MCDRV_POWUPDATE_AP_MC; + update.analog[4] = MCDRV_POWUPDATE_AP_IN; + ret = mc_packet_add_powerdown(&power, &update); + if (ret < 0) + return ret; + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_packet_add_start(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + /* set volume */ + ret = set_vol(MCDRV_VOLUPDATE_DIG, MCDRV_VOLUME_SET, NULL); + if (ret < 0) + return ret; + + return set_vol(MCDRV_VOLUPDATE_ANA_OUT, MCDRV_VOLUME_SET, &status); +} + +static inline int get_volume(struct mcdrv_vol_info *vol_info) +{ + if (!vol_info) + return -EINVAL; + + mc_vol_info_get(vol_info); + + return 0; +} + +static inline int set_volume(struct mcdrv_vol_info *vol_info) +{ + struct mcdrv_path_info path_info; + + if (!vol_info) + return -EINVAL; + + mc_vol_info_set(vol_info); + + mc_path_info_get_virtual(&path_info); + + return set_path(&path_info); +} + +static inline int get_digitalio(struct mcdrv_dio_info *dio_info) +{ + if (!dio_info) + return -EINVAL; + + mc_dio_info_get(dio_info); + + return 0; +} + +static inline int set_digitalio(struct mcdrv_dio_info *dio_info, + unsigned int update) +{ + if (!dio_info) + return -EINVAL; + + if (!is_valid_dio_info(dio_info, update)) + return -EINVAL; + + mc_dio_info_set(dio_info, update); + + mc_packet_add_digital_io(update); + + return mc_packet_execute(); +} + +static inline int get_digitalio_path(struct mcdrv_dio_path_info *dio_path_info) +{ + if (!dio_path_info) + return -EINVAL; + + mc_dio_path_info_get(dio_path_info); + + return 0; +} + +static inline int set_digitalio_path(struct mcdrv_dio_path_info *dio_path_info, + unsigned int update) +{ + if (!dio_path_info) + return -EINVAL; + + if (!is_valid_dio_path_info(dio_path_info, update)) + return -EINVAL; + + mc_dio_path_info_set(dio_path_info, update); + + mc_packet_add_digital_io_path(); + + return mc_packet_execute(); +} + +static inline int get_swap(struct mcdrv_swap_info *info) +{ + if (!info) + return -EINVAL; + + mc_swap_info_get(info); + + return 0; +} + +static inline int set_swap(struct mcdrv_swap_info *info, unsigned int update) +{ + if (!info) + return -EINVAL; + + if (!is_valid_swap_info(info, update)) + return -EINVAL; + + mc_swap_info_set(info, update); + + mc_packet_add_swap(update); + + return mc_packet_execute(); +} + +static inline bool is_path_alloff(void) +{ + struct mcdrv_path_info info; + + mc_path_info_get_virtual(&info); + if (memcmp(&info, &path_alloff, sizeof(struct mcdrv_path_info))) + return false; + + return true; +} + +static int set_dsp(u8 *data, unsigned int size) +{ + struct mcdrv_aec_info info, curr_info; + struct mcdrv_power_info power; + struct mcdrv_power_update update; + static struct mcdrv_path_info path_info; + enum mcdrv_dev_id id; + static u8 g_lp2_start, g_src3_start; + u32 mute_flag; + int ret = 0; + + if (!data || !size) + return -EINVAL; + + id = mc_dev_id_get(); + + mc_aec_info_get(&info); + curr_info = info; + + ret = mc_parser_d7_data_analyze(data, size, &info); + if (ret < 0) + return ret; + + if (!is_valid_aec_info(&info)) + return -EINVAL; + + mc_aec_info_set(&info); + mc_aec_info_get(&info); + + info.vbox.cdsp_func_a_on &= 0x01; + info.vbox.cdsp_func_b_on &= 0x01; + + if (info.control.command == 1) { + if (!info.control.param[0] && !is_path_alloff()) { + mc_path_info_get_virtual(&path_info); + + ret = set_path(&path_alloff); + if (ret < 0) + goto exit; + } + } else if (info.control.command == 2) { + if (!info.control.param[0]) { + g_lp2_start = mc_mb_register_get_value(MCI_LP2_START); + mc_packet_add_write_mb(MCI_LP2_START, 0); + g_src3_start = mc_mb_register_get_value(MCI_SRC3_START); + mc_packet_add_write_mb(MCI_SRC3_START, 0); + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + } + } else if (info.control.command == 3) { + if (id == MCDRV_DEV_ID_81_91H) { + mc_packet_add_dout_mute(); + mute_flag = MCB_DIFO3_VFLAG1 | MCB_DIFO3_VFLAG0 | + MCB_DIFO2_VFLAG1 | MCB_DIFO2_VFLAG0 | + MCB_DIFO1_VFLAG1 | MCB_DIFO1_VFLAG0 | + MCB_DIFO0_VFLAG1 | MCB_DIFO0_VFLAG0; + mc_packet_add_wait_event(MCDRV_EVT_DITMUTE | mute_flag); + mute_flag = MCB_DAO1_VFLAG1 | MCB_DAO1_VFLAG0 | + MCB_DAO0_VFLAG1 | MCB_DAO0_VFLAG0; + mc_packet_add_wait_event(MCDRV_EVT_DACMUTE | mute_flag); + mc_packet_add_write_ma(MCI_CLK_SEL, + info.control.param[0]); + mc_clock_select_set(info.control.param[0]); + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + ret = set_vol(MCDRV_VOLUPDATE_DOUT, + MCDRV_VOLUME_SET, NULL); + if (ret < 0) + goto exit; + } + } else if (info.control.command == 4) { + if (id == MCDRV_DEV_ID_81_91H) { + u32 status = 0; + + mc_packet_add_dac0_mute(); + mc_packet_add_dac1_mute(); + mc_packet_add_adif_mute(); + mc_packet_add_dpath_da_mute(); + mute_flag = MCB_ADI2_VFLAG1 | MCB_ADI2_VFLAG0 | + MCB_ADI1_VFLAG1 | MCB_ADI1_VFLAG0 | + MCB_ADI0_VFLAG1 | MCB_ADI0_VFLAG0; + mc_packet_add_wait_event(MCDRV_EVT_ADCMUTE | mute_flag); + + mute_flag = MCB_SPR_BUSY << 8 | MCB_SPL_BUSY << 8 | + MCB_HPR_BUSY << 8 | MCB_HPL_BUSY << 8 | + MCB_LO2R_BUSY | MCB_LO2L_BUSY | + MCB_LO1R_BUSY | MCB_LO1L_BUSY | MCB_RC_BUSY; + mc_packet_add_wait_event(MCDRV_EVT_SVOL_DONE | + mute_flag); + mc_packet_add_write_e(MCI_ECLK_SEL, + info.control.param[0]); + mc_e_clock_select_set(info.control.param[0]); + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + ret = set_vol(MCDRV_VOLUPDATE_ANA_OUT | + MCDRV_VOLUPDATE_ADIF0 | + MCDRV_VOLUPDATE_ADIF1 | + MCDRV_VOLUPDATE_ADIF2 | + MCDRV_VOLUPDATE_DPATHDA, + MCDRV_VOLUME_SET, &status); + if (ret < 0) + goto exit; + } + + } + + mc_power_info_get(&power); + update.digital = MCDRV_POWUPDATE_D_ALL; + update.analog[0] = MCDRV_POWUPDATE_AP; + update.analog[1] = MCDRV_POWUPDATE_AP_OUT0; + update.analog[2] = MCDRV_POWUPDATE_AP_OUT1; + update.analog[3] = MCDRV_POWUPDATE_AP_MC; + update.analog[4] = MCDRV_POWUPDATE_AP_IN; + ret = mc_packet_add_powerup(&power, &update); + if (ret < 0) + goto exit; + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + mc_packet_add_aec(); + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + ret = mc_bdsp_set_dsp(&info); + if (ret < 0) + goto exit; + + ret = mc_cdsp_set_dsp(&info); + if (ret < 0) + goto exit; + + ret = mc_edsp_set_dsp(&info); + if (ret < 0) + goto exit; + + ret = mc_fdsp_set_dsp(&info); + if (ret < 0) + goto exit; + + if (info.control.command == 1) { + if (info.control.param[0] == 1) { + ret = set_path(&path_info); + if (ret < 0) + goto exit; + } + } else if (info.control.command == 2) { + if (info.control.param[0] == 1) { + mc_packet_add_write_mb(MCI_LP2_START, g_lp2_start); + mc_packet_add_write_mb(MCI_SRC3_START, g_src3_start); + } + } + + mc_power_info_get(&power); + + ret = mc_packet_add_powerdown(&power, &update); + if (ret < 0) + goto exit; + + return mc_packet_execute(); + +exit: + mc_aec_info_replace(&curr_info); + save_power(); + + return ret; +} + +static inline int get_hsdet(struct mcdrv_hsdet_info *info) +{ + if (!info) + return -EINVAL; + + mc_hsdet_info_get(info); + + info->dly_irq_stop = 0; + + return 0; +} + +static int set_hsdet(struct mcdrv_hsdet_info *hsdet, unsigned int update) +{ + struct mcdrv_hsdet_info curr_hsdet; + struct mcdrv_path_info path_info, tmp_path_info; + struct mcdrv_hsdet_res hsdet_res; + enum mcdrv_dev_id id; + u8 val, data[2], plug_det_db; + int ret = 0; + + if (!hsdet) + return -EINVAL; + + curr_hsdet = *hsdet; + if (!is_valid_hsdet_info(&curr_hsdet, update)) + return -EINVAL; + + id = mc_dev_id_get(); + if (id == MCDRV_DEV_ID_80_90H) + curr_hsdet.det_in_inv &= 1; + + mc_hsdet_info_set(&curr_hsdet, update); + mc_packet_add_hsdet(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_hsdet_info_get(&curr_hsdet); + if (curr_hsdet.en_plug_det_db != MCDRV_PLUGDETDB_DISABLE || + curr_hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_mic_det != MCDRV_MICDET_DISABLE || + curr_hsdet.en_key_off != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_key_on != MCDRV_KEYEN_D_D_D) { + val = mc_cd_register_get_value(MCI_HSDETEN); + if (!(val & MCB_MKDETEN)) { + val = MCB_HSDETEN | curr_hsdet.hs_det_dbnc; + mc_packet_add_write_cd(MCI_HSDETEN, val); + + if (curr_hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_mic_det != MCDRV_MICDET_DISABLE || + curr_hsdet.en_key_off != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_key_on != MCDRV_KEYEN_D_D_D) { + bool do_set_path = false; + + if (is_ldoa_on()) { + mc_path_info_get_virtual(&path_info); + tmp_path_info = path_info; + tmp_path_info.adc0[0] = 0x00aaaaaa; + tmp_path_info.adc0[1] = 0x00aaaaaa; + + tmp_path_info.adc1[0] = 0x00aaaaaa; + + tmp_path_info.dac0[0] = 0x00aaaaaa; + tmp_path_info.dac0[1] = 0x00aaaaaa; + tmp_path_info.dac1[0] = 0x00aaaaaa; + tmp_path_info.dac1[1] = 0x00aaaaaa; + + tmp_path_info.bias[0] = 0x002aaaaa; + tmp_path_info.bias[1] = 0x002aaaaa; + tmp_path_info.bias[2] = 0x002aaaaa; + tmp_path_info.bias[3] = 0x002aaaaa; + ret = set_path(&tmp_path_info); + if (ret < 0) + return ret; + + do_set_path = true; + } + + mc_packet_add_mic_key_detect_enable(true); + + if (do_set_path) + ret = set_path(&path_info); + } + } else { + val = MCB_HSDETEN | curr_hsdet.hs_det_dbnc; + if (curr_hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_mic_det != MCDRV_MICDET_DISABLE || + curr_hsdet.en_key_off != MCDRV_KEYEN_D_D_D || + curr_hsdet.en_key_on != MCDRV_KEYEN_D_D_D) { + plug_det_db = mc_plug_detect_db_get(); + if (plug_det_db & MCB_RPLUGDET_DB) + val |= MCB_MKDETEN; + } + + mc_packet_add_write_cd(MCI_HSDETEN, val); + + if (!(val & MCB_MKDETEN)) { + val = mc_ana_register_get_value(MCI_KDSET); + val &= ~(MCB_KDSET2 | MCB_KDSET1); + mc_packet_add_force_write_ana(MCI_KDSET, val); + } + } + } + + if (!ret) + ret = mc_packet_execute(); + + if (!ret) { + if ((update & MCDRV_ENPLUGDETDB_UPDATE_FLAG) && + (curr_hsdet.en_plug_det_db & + MCDRV_PLUGDETDB_UNDET_ENABLE) && curr_hsdet.cbfunc) { + data[0] = MCI_CD_REG_A << 1; + data[1] = MCI_PLUGDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + if (!(val & MCB_PLUGDET)) { + hsdet_res.key_cnt0 = 0; + hsdet_res.key_cnt1 = 0; + hsdet_res.key_cnt2 = 0; + mutex_unlock(&mcdrv_mutex); + (*curr_hsdet. + cbfunc) (MCDRV_HSDET_EVT_PLUGUNDET_DB_FLAG, + &hsdet_res); + mutex_lock(&mcdrv_mutex); + } + } + + ret = save_power(); + } + + return ret; +} + +static inline void enable_irqhs(u8 *data) +{ + data[1] = MCI_IRQHS; + data[3] = MCB_EIRQHS; + mc_write_analog(data, 4); + + mc_cd_register_set_value(MCI_IRQHS, MCB_EIRQHS); +} + +int mc_do_irq(void) +{ + struct mcdrv_aec_info aec; + struct mcdrv_path_info path; + struct mcdrv_hsdet_info hsdet; + struct mcdrv_hsdet_res hsdet_res; + enum mcdrv_dev_id id; + u32 flag_det = 0; + u8 val, splug_det, plug_det, sensefin, eirq, data[4]; + u8 flag_dlykey = 0, flag_key = 0; + static u8 s_op_dac, s_hp_det; + unsigned long interval; + int cycles, timeout, ret = 0; + + mutex_lock(&mcdrv_mutex); + + id = mc_dev_id_get(); + mc_hsdet_info_get(&hsdet); + + eirq = mc_if_register_get_value(MCI_IRQ); + val = mc_cd_register_get_value(MCI_EIRQSENSE); + if (val & MCB_EIRQSENSE) { + /* IRQ Disable */ + data[0] = MCI_IRQR << 1; + data[1] = 0; + mc_write_digital(data, 2); + + data[0] = MCI_CD_REG_A << 1; + data[1] = MCI_SSENSEFIN; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &sensefin, 1); + if (sensefin & MCB_SSENSEFIN) { + data[1] = MCI_EIRQSENSE; + data[2] = MCI_CD_REG_D << 1; + data[3] = 0; + mc_write_analog(data, 4); + + mc_cd_register_set_value(MCI_EIRQSENSE, 0); + data[1] = MCI_SSENSEFIN; + data[3] = val; + mc_write_analog(data, 4); + } else { + /* IRQ Enable */ + data[0] = MCI_IRQR << 1; + data[1] = MCB_EIRQR; + mc_write_digital(data, 2); + + mutex_unlock(&mcdrv_mutex); + + return 0; + } + + /* PLUGDET, PLUGUNDETDB, PLUGDETDB */ + data[0] = MCI_CD_REG_A << 1; + data[1] = MCI_PLUGDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + + /* clear */ + flag_det = val; + data[2] = MCI_CD_REG_D << 1; + data[3] = val; + mc_write_analog(data, 4); + + /* set reference */ + data[1] = MCI_PLUGDET_DB; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + mc_plug_detect_db_set(val); + + data[1] = MCI_RPLUGDET; + data[3] = (flag_det & MCB_PLUGDET) | val; + mc_write_analog(data, 4); + flag_det = data[3]; + + data[1] = MCI_MICDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + + data[1] = MCI_RMICDET; + data[3] = val; + mc_write_analog(data, 4); + flag_key = val & MCB_MICDET; + + data[1] = MCI_SMICDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + + data[3] = val; + mc_write_analog(data, 4); + + hsdet_res.key_cnt0 = 0; + hsdet_res.key_cnt1 = 0; + hsdet_res.key_cnt2 = 0; + + data[0] = MCI_E_REG_A << 1; + data[1] = MCI_PLUG_REV; + mc_write_digital(data, 2); + mc_read_digital(MCI_E_REG_D, &val, 1); + hsdet_res.plug_rev = val >> 7; + hsdet_res.hp_imp_class = val & 0x07; + data[1] = MCI_HPIMP_15_8; + mc_write_digital(data, 2); + mc_read_digital(MCI_E_REG_D, &val, 1); + hsdet_res.hp_imp = val << 8; + data[1] = MCI_HPIMP_7_0; + mc_write_digital(data, 2); + mc_read_digital(MCI_E_REG_D, &val, 1); + hsdet_res.hp_imp |= val; + + val = mc_e_register_get_value(MCI_LPF_THR); + val &= + (MCB_OSF1_MN | MCB_OSF0_MN | MCB_OSF1_ENB | MCB_OSF0_ENB); + mc_aec_info_get(&aec); + val |= aec.output.lpf_post_thru[1] << 7 + | aec.output.lpf_post_thru[0] << 6 + | aec.output.lpf_pre_thru[1] << 5 + | aec.output.lpf_pre_thru[0] << 4; + mc_packet_add_write_e(MCI_LPF_THR, val); + + val = aec.output.dcl_on[1] << 7 | aec.output.dcl_gain[1] << 4 + | aec.output.dcl_on[0] << 3 | aec.output.dcl_gain[0]; + mc_packet_add_write_e(MCI_DCL_GAIN, val); + + if (id == MCDRV_DEV_ID_80_90H) + mc_packet_add_write_ana(19, s_op_dac); + + mc_packet_add_write_ana(MCI_HPDETVOL, s_hp_det); + if (id == MCDRV_DEV_ID_80_90H) { + mc_packet_add_force_write_ana(78, + T_CPMODE_IMPSENSE_AFTER); + mc_packet_add_force_write_ana(87, 0); + data[0] = MCI_ANA_REG_A << 1; + data[1] = 78; + mc_write_analog(data, 2); + mc_read_analog(MCI_ANA_REG_D, &val, 1); + } else { + mc_packet_add_force_write_ana(87, 0); + mc_packet_add_force_write_if(31, 0); + mc_packet_add_force_write_if(30, 0); + } + + mc_path_info_get_virtual(&path); + ret = set_path(&path); + + if (hsdet.cbfunc) { + if (flag_det & MCB_SPLUGUNDET_DB) + flag_det = MCB_PLUGUNDET_DB; + else + flag_det |= MCDRV_HSDET_EVT_SENSEFIN_FLAG; + + mutex_unlock(&mcdrv_mutex); + + (*hsdet.cbfunc) (flag_det | (flag_key << 16), + &hsdet_res); + mutex_lock(&mcdrv_mutex); + } + + /* Enable IRQ */ + data[0] = MCI_CD_REG_A << 1; + data[2] = MCI_CD_REG_D << 1; + enable_irqhs(data); + + data[0] = MCI_IRQR << 1; + data[1] = MCB_EIRQR; + mc_write_digital(data, 2); + + val = mc_if_register_get_value(MCI_RST_A); + if (!val) { + data[0] = MCI_IRQ << 1; + data[1] = MCB_EIRQ; + mc_write_digital(data, 2); + mc_if_register_set_value(MCI_IRQ, MCB_EIRQ); + } + + mutex_unlock(&mcdrv_mutex); + + return 0; + } + + if (mc_state_get() != MCDRV_STATE_READY) { + ret = -EBUSY; + goto exit; + } + + if (eirq & MCB_EIRQ) { + mc_read_digital(MCI_EDSP, &val, 1); + if (val) { + /* Disable IRQ */ + mc_packet_add_force_write_if(MCI_EEDSP, 0); + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + if (val & MCB_E2DSP_STA) + mc_edsp_irq(); + + /* Clear IRQ */ + mc_packet_add_force_write_if(MCI_EDSP, val); + + /* Enable IRQ */ + mc_packet_add_force_write_if(MCI_EEDSP, MCB_EE2DSP); + } + + mc_read_digital(MCI_CDSP, &val, 1); + if (val) { + /* Disable IRQ */ + mc_packet_add_force_write_if(MCI_ECDSP, 0); + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + mc_cdsp_irq(); + + /* Clear IRQ */ + mc_packet_add_force_write_if(MCI_CDSP, val); + + /* Enable IRQ */ + val = MCB_ECDSP | MCB_EFFIFO | MCB_ERFIFO | MCB_EEFIFO | + MCB_EOFIFO | MCB_EDFIFO | MCB_EENC | MCB_EDEC; + mc_packet_add_force_write_if(MCI_ECDSP, val); + } + + mc_read_digital(MCI_IRSERR, &val, 1); + if (val) { + /* Disable IRQ */ + mc_packet_add_force_write_if(MCI_IESERR, 0); + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + + mc_fdsp_irq(); + + /* Clear IRQ */ + mc_packet_add_force_write_if(MCI_IRSERR, val); + /* Enable IRQ */ + val = + MCB_IESERR | MCB_IEAMTBEG | MCB_IEAMTEND | MCB_IEFW; + mc_packet_add_force_write_if(MCI_IESERR, val); + } + + ret = mc_packet_execute(); + if (ret < 0) + goto exit; + } + + data[0] = MCI_CD_REG_A << 1; + data[1] = MCI_IRQHS; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + if (val == (MCB_EIRQHS | MCB_IRQHS)) { + /* Disable EIRQHS */ + data[2] = MCI_CD_REG_D << 1; + data[3] = 0; + mc_write_analog(data, 4); + mc_cd_register_set_value(MCI_IRQHS, 0); + + /* PLUGDET, SPLUGUNDETDB, SPLUGDETDB */ + data[1] = MCI_PLUGDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &splug_det, 1); + flag_det = splug_det & MCB_PLUGDET; + + data[1] = MCI_PLUGDET_DB; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &plug_det, 1); + flag_det |= plug_det; + if (flag_det & MCB_PLUGUNDET_DB) + mc_plug_detect_db_set(0); + + if (hsdet.en_plug_det_db & MCDRV_PLUGDETDB_DET_ENABLE) { + if (id == MCDRV_DEV_ID_81_91H) { + data[1] = MCI_RPLUGDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + val = ~val & plug_det; + } else + val = splug_det; + + if (val & MCB_SPLUGDET_DB) { + mc_plug_detect_db_set(val); + + if (id != MCDRV_DEV_ID_81_92H) { + val = mc_ana_register_get_value(MCI_AP); + val &= ~MCB_AP_BGR; + mc_packet_add_write_ana(MCI_AP, val); + } + + val = mc_ana_register_get_value(MCI_HIZ); + val |= MCB_HPR_HIZ | MCB_HPL_HIZ; + mc_packet_add_write_ana(MCI_HIZ, val); + + mc_path_info_get_virtual(&path); + path.bias[3] |= MCDRV_ASRC_MIC4_ON; + ret = set_path(&path); + if (ret < 0) { + enable_irqhs(data); + goto exit; + } + + if (hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D + || hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D + || hsdet.en_mic_det != MCDRV_MICDET_DISABLE + || hsdet.en_key_off != MCDRV_KEYEN_D_D_D + || hsdet.en_key_on != MCDRV_KEYEN_D_D_D) + mc_packet_add_mic_key_detect_enable + (false); + + ret = mc_packet_execute(); + if (ret < 0) { + enable_irqhs(data); + goto exit; + } + + if (hsdet.sgnl_num != MCDRV_SGNLNUM_NONE) { + s_hp_det = + mc_ana_register_get_value + (MCI_HPDETVOL); + ret = imp_sense_start(&s_op_dac); + if (ret == 0) { + mutex_unlock(&mcdrv_mutex); + return ret; + } + + enable_irqhs(data); + goto exit; + } + } + } + + /* clear */ + data[1] = MCI_PLUGDET; + data[3] = splug_det; + mc_write_analog(data, 4); + + /* set reference */ + data[1] = MCI_RPLUGDET; + data[3] = flag_det; + mc_write_analog(data, 4); + + /* DLYKEYON, DLYKEYOFF */ + data[1] = MCI_SDLYKEY; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + flag_dlykey = val; + /* clear */ + data[1] = MCI_SDLYKEY; + data[3] = val; + mc_write_analog(data, 4); + + /* MICDET, KEYON, KEYOFF */ + data[1] = MCI_SMICDET; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + flag_key = val & ~MCB_SMICDET; + /* clear */ + data[1] = MCI_SMICDET; + data[3] = val; + mc_write_analog(data, 4); + + /* set reference */ + data[1] = MCI_MICDET; + mc_write_analog(data, 2); + if (hsdet.sgnl_num == MCDRV_SGNLNUM_NONE) { + if (flag_det & MCB_PLUGDET_DB) { + switch (hsdet.speriod) { + case MCDRV_SPERIOD_488: + interval = 488; + break; + case MCDRV_SPERIOD_977: + interval = 977; + break; + case MCDRV_SPERIOD_1953: + interval = 1953; + break; + case MCDRV_SPERIOD_3906: + interval = 3906; + break; + case MCDRV_SPERIOD_7813: + interval = 7813; + break; + case MCDRV_SPERIOD_15625: + interval = 15625; + break; + case MCDRV_SPERIOD_31250: + interval = 31250; + break; + default: + interval = 244; + break; + } + + timeout = 1; + switch (hsdet.dbnc_num_mic) { + case MCDRV_DBNC_NUM_3: + timeout += 3; + break; + case MCDRV_DBNC_NUM_4: + timeout += 4; + break; + case MCDRV_DBNC_NUM_7: + timeout += 7; + break; + default: + break; + } + + cycles = 0; + while (cycles < timeout) { + mc_read_analog(MCI_CD_REG_D, + &val, 1); + if (val & (MCB_MICDET | 0x07)) + break; + + udelay(interval); + cycles++; + } + } + } else + mc_read_analog(MCI_CD_REG_D, &val, 1); + flag_key |= val & MCB_MICDET; + data[1] = MCI_RMICDET; + data[3] = val; + mc_write_analog(data, 4); + + if (hsdet.cbfunc) { + /* KeyCnt0 */ + data[1] = MCI_KEYCNTCLR0; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, + &hsdet_res.key_cnt0, 1); + data[1] = MCI_KEYCNTCLR0; + data[3] = MCB_KEYCNTCLR0; + mc_write_analog(data, 4); + + /* KeyCnt1 */ + data[1] = MCI_KEYCNTCLR1; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, + &hsdet_res.key_cnt1, 1); + data[1] = MCI_KEYCNTCLR1; + data[3] = MCB_KEYCNTCLR1; + mc_write_analog(data, 4); + + /* KeyCnt2 */ + data[1] = MCI_KEYCNTCLR2; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, + &hsdet_res.key_cnt2, 1); + data[1] = MCI_KEYCNTCLR2; + data[3] = MCB_KEYCNTCLR2; + mc_write_analog(data, 4); + + data[0] = MCI_IRQ << 1; + data[1] = 0; + mc_write_analog(data, 2); + mc_if_register_set_value(MCI_IRQ, 0); + + data[0] = MCI_IRQR << 1; + data[1] = 0; + mc_write_analog(data, 2); + + mutex_unlock(&mcdrv_mutex); + + (*hsdet.cbfunc) (flag_det | (u32) flag_dlykey << 8 | + (u32) flag_key << 16, &hsdet_res); + + mutex_lock(&mcdrv_mutex); + + data[0] = MCI_IRQR << 1; + data[1] = MCB_EIRQR; + mc_write_analog(data, 2); + } + /* Enable IRQ */ + data[0] = MCI_CD_REG_A << 1; + data[2] = MCI_CD_REG_D << 1; + enable_irqhs(data); + } + +exit: + val = mc_if_register_get_value(MCI_RST_A); + if (!val) { + val = mc_if_register_get_value(MCI_IRQ); + if (val != MCB_EIRQ) { + data[0] = MCI_IRQ << 1; + data[1] = MCB_EIRQ; + mc_write_analog(data, 2); + mc_if_register_set_value(MCI_IRQ, MCB_EIRQ); + } + } + + mutex_unlock(&mcdrv_mutex); + + return ret; +} + +static inline bool is_valid_mcdrv_dev_info(struct mcdrv_dev_info *info) +{ + enum mcdrv_dev_id id; + + id = mc_dev_id_get(); + + if (info->clk_sel > MCDRV_CKSEL_LAST) + return false; + + if (info->clk_input > MCDRV_CKINPUT_LAST || + info->clk_input == MCDRV_CKINPUT_NONE0 || + info->clk_input == MCDRV_CKINPUT_NONE1 || + info->clk_input == MCDRV_CKINPUT_NONE2) + return false; + + if (info->pll_mode_a > MCDRV_PLLMODE_MAX) + return false; + + if (info->pll_prev_div_a > MCDRV_PLLPREV_DIV_MAX) + return false; + + if (info->pll_fb_div_a > MCDRV_PLLFB_DIV_MAX) + return false; + + if (info->pll_mode_b > MCDRV_PLLMODE_MAX) + return false; + + if (info->pll_prev_div_b > MCDRV_PLLPREV_DIV_MAX) + return false; + + if (info->pll_fb_div_b > MCDRV_PLLFB_DIV_MAX) + return false; + + if (info->power_mode != MCDRV_POWMODE_FULL && + info->power_mode != MCDRV_POWMODE_CDSPDEBUG) + return false; + + if (info->mb_sel1 > MCDRV_MBSEL_LAST) + return false; + + if (info->mb_sel2 > MCDRV_MBSEL_LAST) + return false; + + if (info->mb_sel3 > MCDRV_MBSEL_LAST) + return false; + + if (info->mb_sel4 > MCDRV_MBSEL_LAST) + return false; + + if (info->mbs_disch > MCDRV_MBSDISCH_LAST) + return false; + + if (info->sp_hiz > MCDRV_WL_LAST) + return false; + + if (info->hp_hiz > MCDRV_IMP_LAST) + return false; + + if (info->line_out1_hiz > MCDRV_IMP_LAST) + return false; + + if (info->line_out2_hiz > MCDRV_IMP_LAST) + return false; + + if (info->wait_time.wait[0] > MCDRV_WAIT_MAX || + info->wait_time.wait[1] > MCDRV_WAIT_MAX || + info->wait_time.wait[2] > MCDRV_WAIT_MAX || + info->wait_time.wait[3] > MCDRV_WAIT_MAX || + info->wait_time.wait[4] > MCDRV_WAIT_MAX) + return false; + + if (id == MCDRV_DEV_ID_81_91H) { + if (info->options[0] > MCDRV_DOA_DRV_LAST) + return false; + if (info->options[1] > MCDRV_SCKMSK_LAST) + return false; + if (info->options[2] > MCDRV_SPMN_LAST) + return false; + if (info->options[3] > 0x0f) + return false; + if (info->options[4] > 0xf8) + return false; + if (info->options[5] > 0xf8) + return false; + if (info->options[6] > 0x31) + return false; + if (info->options[7] > 0x7f) + return false; + if (info->options[9] > 0x7f) + return false; + if (info->options[10] > 0x11) + return false; + if (info->options[11] > 0xf3) + return false; + if (info->options[12] > 0x07) + return false; + } + + return true; +} + +int mc_init(struct mcdrv_dev_info *info) +{ + struct mcdrv_power_info power_info; + struct mcdrv_power_update power_update; + enum mcdrv_state state; + u8 analog_id, digital_id, ap = MCI_AP_DEF, data[4]; + int ret; + + if (!info) + return -EINVAL; + + state = mc_state_get(); + if (state == MCDRV_STATE_READY) + return -EBUSY; + + mutex_lock(&mcdrv_mutex); + + mc_resource_init(); + + data[0] = MCI_ANA_REG_A << 1; + data[1] = MCI_ANA_ID; + mc_write_analog(data, 2); + mc_read_analog(MCI_ANA_REG_D, &analog_id, 1); + + if ((analog_id & MCDRV_DEVID_MASK) == MCDRV_DEVID_ANA) { + /* reset */ + data[0] = MCI_ANA_REG_A << 1; + data[1] = MCI_ANA_RST; + data[2] = MCI_ANA_REG_D << 1; + data[3] = MCI_ANA_RST_DEF; + mc_write_analog(data, 4); + + data[3] = 0; + mc_write_analog(data, 4); + + if (!(analog_id & MCDRV_VERID_MASK)) { + data[1] = MCI_AP; + data[3] = MCI_AP_DEF & ~(MCB_AP_LDOD | MCB_AP_BGR); + mc_write_analog(data, 4); + + data[3] &= ~MCB_AP_VR; + mc_write_analog(data, 4); + + msleep(VREF_WAIT_TIME_ES1); + + data[3] &= ~MCB_AP_LDOA; + mc_write_analog(data, 4); + + msleep(LDO_WAIT_TIME); + + ap = data[3]; + } else { + data[1] = MCI_HIZ; + data[3] = 0; + mc_write_analog(data, 4); + + data[1] = MCI_LO_HIZ; + data[3] = 0; + mc_write_analog(data, 4); + + data[1] = MCI_AP; + ap &= ~(MCB_AP_LDOD | MCB_AP_BGR); + data[3] = ap; + mc_write_analog(data, 4); + + ap &= ~MCB_AP_LDOA; + data[3] = ap; + mc_write_analog(data, 4); + + msleep(LDO_WAIT_TIME); + + data[1] = 62; + data[3] = 0x20; + mc_write_analog(data, 4); + + data[1] = MCI_AP; + ap &= ~MCB_AP_VR; + data[3] = ap; + mc_write_analog(data, 4); + + msleep(VREF_WAIT_TIME); + + data[1] = 62; + data[3] = 0; + mc_write_analog(data, 4); + } + + data[0] = MCI_RST_A << 1; + data[1] = MCI_RST_A_DEF & ~MCB_RST_A; + mc_write_digital(data, 2); + + data[0] = MCI_A_REG_A << 1; + data[1] = MCI_A_DEV_ID; + mc_write_digital(data, 2); + mc_read_digital(MCI_A_REG_D, &digital_id, 1); + ret = mc_id_set(digital_id, analog_id); + if (!ret) { + if (is_valid_mcdrv_dev_info(info)) { + mc_ana_register_set_value(MCI_AP, ap); + mc_dev_info_set(info); + mc_packet_clear(); + ret = mc_packet_init(); + if (ret == 0) + ret = mc_packet_execute(); + } else + ret = -EINVAL; + } + + if (!ret && info->power_mode == MCDRV_POWMODE_CDSPDEBUG) { + mc_power_info_get(&power_info); + + /* used path power up */ + power_update.digital = MCDRV_POWUPDATE_D_ALL; + power_update.analog[0] = 0; + power_update.analog[1] = 0; + power_update.analog[2] = 0; + power_update.analog[3] = 0; + power_update.analog[4] = 0; + ret = mc_packet_add_powerup(&power_info, &power_update); + } + + if (!ret) { + mc_state_update(MCDRV_STATE_READY); + save_power(); + } + } else + ret = -EIO; + + mutex_unlock(&mcdrv_mutex); + + return ret; +} + +int mc_term(void) +{ + struct mcdrv_dev_info info; + struct mcdrv_power_info power_info; + struct mcdrv_power_update power_update; + struct mcdrv_hsdet_info hsdet_info; + enum mcdrv_state state; + u32 flags; + int ret = 0; + + state = mc_state_get(); + if (state != MCDRV_STATE_READY) + return -EBUSY; + + mutex_lock(&mcdrv_mutex); + + mc_dev_info_get(&info); + info.power_mode = MCDRV_POWMODE_FULL; + mc_dev_info_set(&info); + + ret = set_path(&path_alloff); + if (!ret) { + power_info.digital = 0xff; + power_info.analog[0] = 0xff; + power_info.analog[1] = 0xff; + power_info.analog[2] = 0xff; + power_info.analog[3] = 0xff; + power_info.analog[4] = 0xff; + + power_update.digital = MCDRV_POWUPDATE_D_ALL; + power_update.analog[0] = MCDRV_POWUPDATE_AP; + power_update.analog[1] = MCDRV_POWUPDATE_AP_OUT0; + power_update.analog[2] = (u8) MCDRV_POWUPDATE_AP_OUT1; + power_update.analog[3] = (u8) MCDRV_POWUPDATE_AP_MC; + power_update.analog[4] = (u8) MCDRV_POWUPDATE_AP_IN; + + ret = mc_packet_add_powerdown(&power_info, + &power_update); + if (!ret) + ret = mc_packet_execute(); + } + + hsdet_info.en_plug_det = MCDRV_PLUGDET_DISABLE; + hsdet_info.en_plug_det_db = MCDRV_PLUGDETDB_DISABLE; + hsdet_info.en_dly_key_off = MCDRV_KEYEN_D_D_D; + hsdet_info.en_dly_key_on = MCDRV_KEYEN_D_D_D; + hsdet_info.en_mic_det = MCDRV_MICDET_DISABLE; + hsdet_info.en_key_off = MCDRV_KEYEN_D_D_D; + hsdet_info.en_key_on = MCDRV_KEYEN_D_D_D; + flags = MCDRV_ENPLUGDET_UPDATE_FLAG | MCDRV_ENPLUGDETDB_UPDATE_FLAG | + MCDRV_ENDLYKEYOFF_UPDATE_FLAG | MCDRV_ENDLYKEYON_UPDATE_FLAG | + MCDRV_ENMICDET_UPDATE_FLAG | MCDRV_ENKEYOFF_UPDATE_FLAG | + MCDRV_ENKEYON_UPDATE_FLAG; + + ret = set_hsdet(&hsdet_info, flags); + + mc_state_update(MCDRV_STATE_NOTINIT); + + mutex_unlock(&mcdrv_mutex); + + return ret; +} + +int mc_control(unsigned int cmd, unsigned long arg, unsigned int flags) +{ + int ret; + + if (mc_state_get() != MCDRV_STATE_READY) + return -EBUSY; + + mutex_lock(&mcdrv_mutex); + + switch (cmd) { + case MCDRV_GET_CLOCKSW: + ret = get_clock((u8 *) arg); + break; + case MCDRV_SET_CLOCKSW: + ret = set_clock((u8 *) arg); + break; + case MCDRV_GET_PATH: + ret = get_path((struct mcdrv_path_info *)arg); + break; + case MCDRV_SET_PATH: + ret = set_path((struct mcdrv_path_info *)arg); + break; + case MCDRV_GET_VOLUME: + ret = get_volume((struct mcdrv_vol_info *)arg); + break; + case MCDRV_SET_VOLUME: + ret = set_volume((struct mcdrv_vol_info *)arg); + break; + case MCDRV_GET_DIGITALIO: + ret = get_digitalio((struct mcdrv_dio_info *)arg); + break; + case MCDRV_SET_DIGITALIO: + ret = set_digitalio((struct mcdrv_dio_info *)arg, flags); + break; + case MCDRV_GET_DIGITALIO_PATH: + ret = get_digitalio_path((struct mcdrv_dio_path_info *)arg); + break; + case MCDRV_SET_DIGITALIO_PATH: + ret = + set_digitalio_path((struct mcdrv_dio_path_info *)arg, + flags); + break; + case MCDRV_GET_SWAP: + ret = get_swap((struct mcdrv_swap_info *)arg); + break; + case MCDRV_SET_SWAP: + ret = set_swap((struct mcdrv_swap_info *)arg, flags); + break; + case MCDRV_SET_DSP: + ret = set_dsp((u8 *) arg, flags); + break; + case MCDRV_GET_HSDET: + ret = get_hsdet((struct mcdrv_hsdet_info *)arg); + break; + case MCDRV_SET_HSDET: + ret = set_hsdet((struct mcdrv_hsdet_info *)arg, flags); + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&mcdrv_mutex); + + return ret; +} + +int mc_version_id_get(void) +{ + u8 data[2], val; + + mutex_lock(&mcdrv_mutex); + + data[0] = MCI_ANA_REG_A << 1; + data[1] = MCI_ANA_ID; + mc_write_analog(data, 2); + mc_read_analog(MCI_ANA_REG_D, &val, 1); + + mutex_unlock(&mcdrv_mutex); + + return val & 0x7; +} diff --git a/sound/soc/codecs/ymu831/mcdriver.h b/sound/soc/codecs/ymu831/mcdriver.h new file mode 100644 index 0000000..d583e87 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcdriver.h @@ -0,0 +1,1017 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcdriver.h + * Description : MC driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _MCDRIVER_H +#define _MCDRIVER_H + +#include <linux/types.h> + +/* mc_control command */ +enum mc_command { + MCDRV_GET_CLOCKSW, + MCDRV_SET_CLOCKSW, + MCDRV_GET_PATH, + MCDRV_SET_PATH, + MCDRV_GET_VOLUME, + MCDRV_SET_VOLUME, + MCDRV_GET_DIGITALIO, + MCDRV_SET_DIGITALIO, + MCDRV_GET_DIGITALIO_PATH, + MCDRV_SET_DIGITALIO_PATH, + MCDRV_GET_SWAP, + MCDRV_SET_SWAP, + MCDRV_SET_DSP, + MCDRV_GET_HSDET, + MCDRV_SET_HSDET, +}; + +#define MCDRV_WAIT_MAX 268435455U + +struct mcdrv_wait_time { + u32 wait[7]; + u32 poll_interval[6]; + u32 poll_timeout[6]; +}; + +/* mcdrv_dev_info clk_sel setting */ +#define MCDRV_CKSEL_CMOS_CMOS 0x00 +#define MCDRV_CKSEL_TCXO_CMOS 0x01 +#define MCDRV_CKSEL_CMOS_TCXO 0x02 +#define MCDRV_CKSEL_TCXO_TCXO 0x03 +#define MCDRV_CKSEL_LAST MCDRV_CKSEL_TCXO_TCXO + +/* mcdrv_dev_info clk_input setting */ +#define MCDRV_CKINPUT_NONE0 0x00 +#define MCDRV_CKINPUT_CLKI1_CLKI0 0x01 +#define MCDRV_CKINPUT_RTC_CLKI0 0x02 +#define MCDRV_CKINPUT_SBCK_CLKI0 0x03 +#define MCDRV_CKINPUT_CLKI0_CLKI1 0x04 +#define MCDRV_CKINPUT_NONE1 0x05 +#define MCDRV_CKINPUT_RTC_CLKI1 0x06 +#define MCDRV_CKINPUT_SBCK_CLKI1 0x07 +#define MCDRV_CKINPUT_CLKI0_RTCK 0x08 +#define MCDRV_CKINPUT_CLKI1_RTCK 0x09 +#define MCDRV_CKINPUT_NONE2 0x0A +#define MCDRV_CKINPUT_SBCK_RTC 0x0B +#define MCDRV_CKINPUT_CLKI0_SBCK 0x0C +#define MCDRV_CKINPUT_CLKI1_SBCK 0x0D +#define MCDRV_CKINPUT_RTC_SBCK 0x0E +#define MCDRV_CKINPUT_LAST MCDRV_CKINPUT_RTC_SBCK + +#define MCDRV_PLLMODE_MAX 7 + +#define MCDRV_PLLPREV_DIV_MAX 0x3f + +#define MCDRV_PLLFB_DIV_MAX 0x3fff + +/* mcdrv_dev_info pll_freq_* setting */ +#define MCDRV_PLLFREQ_73 0 +#define MCDRV_PLLFREQ_147 1 + +/* mcdrv_dev_info hsdet_clk setting */ +#define MCDRV_HSDETCLK_RTC false +#define MCDRV_HSDETCLK_OSC true + +/* mcdrv_dev_info XXX_hiz setting */ +#define MCDRV_DAHIZ_LOW 0 +#define MCDRV_DAHIZ_HIZ 1 + +/* mcdrv_dev_info pcm_hiz setting */ +#define MCDRV_PCMHIZ_LOW 0 +#define MCDRV_PCMHIZ_HIZ 1 + +/* mcdrv_dev_info paX_func setting */ +#define MCDRV_PA_GPIO false +#define MCDRV_PA_PDMCK true +#define MCDRV_PA_PDMDI true + +/* mcdrv_dev_info power_mode setting */ +#define MCDRV_POWMODE_FULL 0 +#define MCDRV_POWMODE_CDSPDEBUG 255 + +/* mcdrv_dev_info mb_sel setting */ +#define MCDRV_MBSEL_20 0 +#define MCDRV_MBSEL_21 1 +#define MCDRV_MBSEL_22 2 +#define MCDRV_MBSEL_23 3 +#define MCDRV_MBSEL_LAST MCDRV_MBSEL_23 + +/* mcdrv_dev_info mbs_disch setting */ +#define MCDRV_MBSDISCH_0000 0 +#define MCDRV_MBSDISCH_0001 1 +#define MCDRV_MBSDISCH_0010 2 +#define MCDRV_MBSDISCH_0011 3 +#define MCDRV_MBSDISCH_0100 4 +#define MCDRV_MBSDISCH_0101 5 +#define MCDRV_MBSDISCH_0110 6 +#define MCDRV_MBSDISCH_0111 7 +#define MCDRV_MBSDISCH_1000 8 +#define MCDRV_MBSDISCH_1001 9 +#define MCDRV_MBSDISCH_1010 10 +#define MCDRV_MBSDISCH_1011 11 +#define MCDRV_MBSDISCH_1100 12 +#define MCDRV_MBSDISCH_1101 13 +#define MCDRV_MBSDISCH_1110 14 +#define MCDRV_MBSDISCH_1111 15 +#define MCDRV_MBSDISCH_LAST MCDRV_MBSDISCH_1111 + +/* mcdrv_dev_info nonclip setting */ +#define MCDRV_NONCLIP_OFF false +#define MCDRV_NONCLIP_ON true + +/* mcdrv_dev_info line_*_dif setting */ +#define MCDRV_LINE_STEREO false +#define MCDRV_LINE_DIF true + +/* mcdrv_dev_info micX_single setting */ +#define MCDRV_MIC_DIF false +#define MCDRV_MIC_SINGLE true + +/* mcdrv_dev_info zc_line_outX/zc_rc/zc_sp/zc_hp setting */ +#define MCDRV_ZC_ON false +#define MCDRV_ZC_OFF true + +/* mcdrv_dev_info svol_line_outX/svol_rc/svol_sp/svol_hp setting */ +#define MCDRV_SVOL_OFF false +#define MCDRV_SVOL_ON true + +/* mcdrv_dev_info rc_hiz setting */ +#define MCDRV_RCIMP_FIXLOW 0 +#define MCDRV_RCIMP_WL 1 + +/* mcdrv_dev_info sp_hiz setting */ +#define MCDRV_WL_LOFF_ROFF 0 +#define MCDRV_WL_LON_ROFF 1 +#define MCDRV_WL_LOFF_RON 2 +#define MCDRV_WL_LON_RON 3 +#define MCDRV_WL_LAST MCDRV_WL_LON_RON + +/* mcdrv_dev_info hp_hiz/line_outX_hiz setting */ +#define MCDRV_IMP_LFIXLOW_RFIXLOW 0 +#define MCDRV_IMP_LWL_RFIXLOW 1 +#define MCDRV_IMP_LFIXLOW_RWL 2 +#define MCDRV_IMP_LWL_RWL 3 +#define MCDRV_IMP_LAST MCDRV_IMP_LWL_RWL + +/* mcdrv_dev_info cp_mod setting */ +#define MCDRV_CPMOD_HI 0 +#define MCDRV_CPMOD_MID 1 + +/* mcdrv_dev_info rb_sel setting */ +#define MCDRV_RBSEL_2_2K 0 +#define MCDRV_RBSEL_50 1 + +/* mcdrv_dev_info plug_sel setting */ +#define MCDRV_PLUG_LRGM 0 +#define MCDRV_PLUG_LRMG 1 + +/* mcdrv_dev_info gnd_det setting */ +#define MCDRV_GNDDET_OFF 0 +#define MCDRV_GNDDET_ON 1 + +/* mcdrv_dev_info ppd_* setting */ +#define MCDRV_PPD_OFF 0 +#define MCDRV_PPD_ON 1 + +/* mcdrv_dev_info option[0] setting */ +#define MCDRV_DOA_DRV_LOW 0 +#define MCDRV_DOA_DRV_HIGH 1 +#define MCDRV_DOA_DRV_LAST MCDRV_DOA_DRV_HIGH + +/* mcdrv_dev_info option[1] setting */ +#define MCDRV_SCKMSK_OFF 0 +#define MCDRV_SCKMSK_ON 1 +#define MCDRV_SCKMSK_LAST MCDRV_SCKMSK_ON + +/* mcdrv_dev_info option[2] setting */ +#define MCDRV_SPMN_8_9_10 0 +#define MCDRV_SPMN_5_6_7 1 +#define MCDRV_SPMN_4_5_6 2 +#define MCDRV_SPMN_OFF_9 3 +#define MCDRV_SPMN_OFF_6 4 +#define MCDRV_SPMN_LAST MCDRV_SPMN_OFF_6 + +struct mcdrv_dev_info { + u8 clk_sel; + u8 clk_input; + u8 pll_mode_a; + u8 pll_prev_div_a; + u16 pll_fb_div_a; + u16 pll_frac_a; + bool pll_freq_a; + u8 pll_mode_b; + u8 pll_prev_div_b; + u16 pll_fb_div_b; + u16 pll_frac_b; + bool pll_freq_b; + bool hsdet_clk; + bool dio0_sdo_hiz; + bool dio1_sdo_hiz; + bool dio2_sdo_hiz; + bool dio0_clk_hiz; + bool dio1_clk_hiz; + bool dio2_clk_hiz; + bool dio0_pcm_hiz; + bool dio1_pcm_hiz; + bool dio2_pcm_hiz; + bool pa0_func; + bool pa1_func; + bool pa2_func; + u8 power_mode; + u8 mb_sel1; + u8 mb_sel2; + u8 mb_sel3; + u8 mb_sel4; + u8 mbs_disch; + bool nonclip; + bool line_in1_dif; + bool line_out1_dif; + bool line_out2_dif; + bool mic1_single; + bool mic2_single; + bool mic3_single; + bool mic4_single; + bool zc_line_out1; + bool zc_line_out2; + bool zc_rc; + bool zc_sp; + bool zc_hp; + bool svol_line_out1; + bool svol_line_out2; + bool svol_rc; + bool svol_sp; + bool svol_hp; + bool rc_hiz; + u8 sp_hiz; + u8 hp_hiz; + u8 line_out1_hiz; + u8 line_out2_hiz; + bool cp_mod; + bool rb_sel; + bool plug_sel; + bool gnd_det; + bool ppd_rc; + bool ppd_sp; + bool ppd_hp; + bool ppd_line_out1; + bool ppd_line_out2; + u8 options[20]; + struct mcdrv_wait_time wait_time; +}; + +/* set/get clock switch */ +#define MCDRV_CLKSW_CLKA 0 +#define MCDRV_CLKSW_CLKB 1 + +/* set/get path */ +#define MCDRV_D1SRC_MUSICIN_ON 0x00000001 +#define MCDRV_D1SRC_MUSICIN_OFF 0x00000002 +#define MCDRV_D1SRC_EXTIN_ON 0x00000004 +#define MCDRV_D1SRC_EXTIN_OFF 0x00000008 +#define MCDRV_D1SRC_VBOXOUT_ON 0x00000010 +#define MCDRV_D1SRC_VBOXOUT_OFF 0x00000020 +#define MCDRV_D1SRC_VBOXREFOUT_ON 0x00000040 +#define MCDRV_D1SRC_VBOXREFOUT_OFF 0x00000080 +#define MCDRV_D1SRC_AE0_ON 0x00000100 +#define MCDRV_D1SRC_AE0_OFF 0x00000200 +#define MCDRV_D1SRC_AE1_ON 0x00000400 +#define MCDRV_D1SRC_AE1_OFF 0x00000800 +#define MCDRV_D1SRC_AE2_ON 0x00001000 +#define MCDRV_D1SRC_AE2_OFF 0x00002000 +#define MCDRV_D1SRC_AE3_ON 0x00004000 +#define MCDRV_D1SRC_AE3_OFF 0x00008000 +#define MCDRV_D1SRC_AE_ALL_ON \ + (MCDRV_D1SRC_AE0_ON | MCDRV_D1SRC_AE1_ON | \ + MCDRV_D1SRC_AE2_ON | MCDRV_D1SRC_AE3_ON) +#define MCDRV_D1SRC_ADIF0_ON 0x00010000 +#define MCDRV_D1SRC_ADIF0_OFF 0x00020000 +#define MCDRV_D1SRC_ADIF1_ON 0x00040000 +#define MCDRV_D1SRC_ADIF1_OFF 0x00080000 +#define MCDRV_D1SRC_ADIF2_ON 0x00100000 +#define MCDRV_D1SRC_ADIF2_OFF 0x00200000 +#define MCDRV_D1SRC_HIFIIN_ON 0x00400000 +#define MCDRV_D1SRC_HIFIIN_OFF 0x00800000 +#define MCDRV_D1SRC_ALL_ON 0x00555555 + +#define MCDRV_D2SRC_VOICEIN_ON 0x00000001 +#define MCDRV_D2SRC_VOICEIN_OFF 0x00000002 +#define MCDRV_D2SRC_VBOXIOOUT_ON 0x00000004 +#define MCDRV_D2SRC_VBOXIOOUT_OFF 0x00000008 +#define MCDRV_D2SRC_VBOXHOSTOUT_ON 0x00000010 +#define MCDRV_D2SRC_VBOXHOSTOUT_OFF 0x00000020 +#define MCDRV_D2SRC_ADC0_L_ON 0x00000040 +#define MCDRV_D2SRC_ADC0_L_OFF 0x00000080 +#define MCDRV_D2SRC_ADC0_R_ON 0x00000100 +#define MCDRV_D2SRC_ADC0_R_OFF 0x00000200 +#define MCDRV_D2SRC_ADC0_ON \ + (MCDRV_D2SRC_ADC0_L_ON | MCDRV_D2SRC_ADC0_R_ON) +#define MCDRV_D2SRC_ADC0_OFF \ + (MCDRV_D2SRC_ADC0_L_OFF | MCDRV_D2SRC_ADC0_R_OFF) +#define MCDRV_D2SRC_ADC1_ON 0x00000400 +#define MCDRV_D2SRC_ADC1_OFF 0x00000800 +#define MCDRV_D2SRC_PDM0_L_ON 0x00001000 +#define MCDRV_D2SRC_PDM0_L_OFF 0x00002000 +#define MCDRV_D2SRC_PDM0_R_ON 0x00004000 +#define MCDRV_D2SRC_PDM0_R_OFF 0x00008000 +#define MCDRV_D2SRC_PDM0_ON \ + (MCDRV_D2SRC_PDM0_L_ON | MCDRV_D2SRC_PDM0_R_ON) +#define MCDRV_D2SRC_PDM1_L_ON 0x00010000 +#define MCDRV_D2SRC_PDM1_L_OFF 0x00020000 +#define MCDRV_D2SRC_PDM1_R_ON 0x00040000 +#define MCDRV_D2SRC_PDM1_R_OFF 0x00080000 +#define MCDRV_D2SRC_PDM1_ON \ + (MCDRV_D2SRC_PDM1_L_ON | MCDRV_D2SRC_PDM1_R_ON) +#define MCDRV_D2SRC_DAC0REF_ON 0x00100000 +#define MCDRV_D2SRC_DAC0REF_OFF 0x00200000 +#define MCDRV_D2SRC_DAC1REF_ON 0x00400000 +#define MCDRV_D2SRC_DAC1REF_OFF 0x00800000 + +#define MCDRV_ASRC_DAC0_L_ON 0x00000001 +#define MCDRV_ASRC_DAC0_L_OFF 0x00000002 +#define MCDRV_ASRC_DAC0_R_ON 0x00000004 +#define MCDRV_ASRC_DAC0_R_OFF 0x00000008 +#define MCDRV_ASRC_DAC1_L_ON 0x00000010 +#define MCDRV_ASRC_DAC1_L_OFF 0x00000020 +#define MCDRV_ASRC_DAC1_R_ON 0x00000040 +#define MCDRV_ASRC_DAC1_R_OFF 0x00000080 +#define MCDRV_ASRC_MIC1_ON 0x00000100 +#define MCDRV_ASRC_MIC1_OFF 0x00000200 +#define MCDRV_ASRC_MIC2_ON 0x00000400 +#define MCDRV_ASRC_MIC2_OFF 0x00000800 +#define MCDRV_ASRC_MIC3_ON 0x00001000 +#define MCDRV_ASRC_MIC3_OFF 0x00002000 +#define MCDRV_ASRC_MIC4_ON 0x00004000 +#define MCDRV_ASRC_MIC4_OFF 0x00008000 +#define MCDRV_ASRC_MIC_ALL_ON \ + (MCDRV_ASRC_MIC1_ON | MCDRV_ASRC_MIC2_ON | \ + MCDRV_ASRC_MIC3_ON | MCDRV_ASRC_MIC4_ON) +#define MCDRV_ASRC_LINEIN1_L_ON 0x00010000 +#define MCDRV_ASRC_LINEIN1_L_OFF 0x00020000 +#define MCDRV_ASRC_LINEIN1_R_ON 0x00040000 +#define MCDRV_ASRC_LINEIN1_R_OFF 0x00080000 +#define MCDRV_ASRC_LINEIN1_M_ON 0x00100000 +#define MCDRV_ASRC_LINEIN1_M_OFF 0x00200000 +#define MCDRV_ASRC_LINEIN1_ALL_ON \ + (MCDRV_ASRC_LINEIN1_L_ON | MCDRV_ASRC_LINEIN1_R_ON | \ + MCDRV_ASRC_LINEIN1_M_ON) + +#define MUSICOUT_PATH_CHANNELS 2 +#define EXTOUT_PATH_CHANNELS 2 +#define HIFIOUT_PATH_CHANNELS 1 +#define VBOXMIXIN_PATH_CHANNELS 4 +#define AE_PATH_CHANNELS 2 +#define DAC0_PATH_CHANNELS 2 +#define DAC1_PATH_CHANNELS 2 +#define VOICEOUT_PATH_CHANNELS 1 +#define VBOXIOIN_PATH_CHANNELS 1 +#define VBOXHOSTIN_PATH_CHANNELS 1 +#define HOSTOUT_PATH_CHANNELS 1 +#define ADIF0_PATH_CHANNELS 2 +#define ADIF1_PATH_CHANNELS 2 +#define ADIF2_PATH_CHANNELS 2 +#define ADC0_PATH_CHANNELS 2 +#define ADC1_PATH_CHANNELS 1 +#define SP_PATH_CHANNELS 2 +#define HP_PATH_CHANNELS 2 +#define RC_PATH_CHANNELS 1 +#define LOUT1_PATH_CHANNELS 2 +#define LOUT2_PATH_CHANNELS 2 +#define BIAS_PATH_CHANNELS 4 + +struct mcdrv_path_info { + u32 music_out[MUSICOUT_PATH_CHANNELS]; + u32 ext_out[EXTOUT_PATH_CHANNELS]; + u32 hifi_out[HIFIOUT_PATH_CHANNELS]; + u32 vbox_mix_in[VBOXMIXIN_PATH_CHANNELS]; + u32 ae0[AE_PATH_CHANNELS]; + u32 ae1[AE_PATH_CHANNELS]; + u32 ae2[AE_PATH_CHANNELS]; + u32 ae3[AE_PATH_CHANNELS]; + u32 dac0[DAC0_PATH_CHANNELS]; + u32 dac1[DAC1_PATH_CHANNELS]; + u32 voice_out[VOICEOUT_PATH_CHANNELS]; + u32 vbox_io_in[VBOXIOIN_PATH_CHANNELS]; + u32 vbox_host_in[VBOXHOSTIN_PATH_CHANNELS]; + u32 host_out[HOSTOUT_PATH_CHANNELS]; + u32 adif0[ADIF0_PATH_CHANNELS]; + u32 adif1[ADIF1_PATH_CHANNELS]; + u32 adif2[ADIF2_PATH_CHANNELS]; + u32 adc0[ADC0_PATH_CHANNELS]; + u32 adc1[ADC1_PATH_CHANNELS]; + u32 sp[SP_PATH_CHANNELS]; + u32 hp[HP_PATH_CHANNELS]; + u32 rc[RC_PATH_CHANNELS]; + u32 lout1[LOUT1_PATH_CHANNELS]; + u32 lout2[LOUT2_PATH_CHANNELS]; + u32 bias[BIAS_PATH_CHANNELS]; +}; + +/* set/get vol */ +#define MCDRV_VOL_UPDATE 0x0001 + +#define MUSICIN_VOL_CHANNELS 2 +#define EXTIN_VOL_CHANNELS 2 +#define VOICEIN_VOL_CHANNELS 2 +#define REFIN_VOL_CHANNELS 2 +#define ADIF0IN_VOL_CHANNELS 2 +#define ADIF1IN_VOL_CHANNELS 2 +#define ADIF2IN_VOL_CHANNELS 2 +#define MUSICOUT_VOL_CHANNELS 2 +#define EXTOUT_VOL_CHANNELS 2 +#define VOICEOUT_VOL_CHANNELS 2 +#define REFOUT_VOL_CHANNELS 2 +#define DAC0OUT_VOL_CHANNELS 2 +#define DAC1OUT_VOL_CHANNELS 2 +#define DPATH_VOL_CHANNELS 2 +#define LINEIN1_VOL_CHANNELS 2 +#define MIC1_VOL_CHANNELS 1 +#define MIC2_VOL_CHANNELS 1 +#define MIC3_VOL_CHANNELS 1 +#define MIC4_VOL_CHANNELS 1 +#define HP_VOL_CHANNELS 2 +#define SP_VOL_CHANNELS 2 +#define RC_VOL_CHANNELS 1 +#define LINEOUT1_VOL_CHANNELS 2 +#define LINEOUT2_VOL_CHANNELS 2 +#define HPDET_VOL_CHANNELS 1 + +struct mcdrv_vol_info { + s16 d_music_in[MUSICIN_VOL_CHANNELS]; + s16 d_ext_in[EXTIN_VOL_CHANNELS]; + s16 d_voice_in[VOICEIN_VOL_CHANNELS]; + s16 d_ref_in[REFIN_VOL_CHANNELS]; + s16 d_adif0_in[ADIF0IN_VOL_CHANNELS]; + s16 d_adif1_in[ADIF1IN_VOL_CHANNELS]; + s16 d_adif2_in[ADIF2IN_VOL_CHANNELS]; + s16 d_music_out[MUSICOUT_VOL_CHANNELS]; + s16 d_ext_out[EXTOUT_VOL_CHANNELS]; + s16 d_voice_out[VOICEOUT_VOL_CHANNELS]; + s16 d_ref_out[REFOUT_VOL_CHANNELS]; + s16 d_dac0_out[DAC0OUT_VOL_CHANNELS]; + s16 d_dac1_out[DAC1OUT_VOL_CHANNELS]; + s16 d_dpath_da[DPATH_VOL_CHANNELS]; + s16 d_dpath_ad[DPATH_VOL_CHANNELS]; + s16 a_line_in1[LINEIN1_VOL_CHANNELS]; + s16 a_mic1[MIC1_VOL_CHANNELS]; + s16 a_mic2[MIC2_VOL_CHANNELS]; + s16 a_mic3[MIC3_VOL_CHANNELS]; + s16 a_mic4[MIC4_VOL_CHANNELS]; + s16 a_hp[HP_VOL_CHANNELS]; + s16 a_sp[SP_VOL_CHANNELS]; + s16 a_rc[RC_VOL_CHANNELS]; + s16 a_line_out1[LINEOUT1_VOL_CHANNELS]; + s16 a_line_out2[LINEOUT2_VOL_CHANNELS]; + s16 a_hp_det[HPDET_VOL_CHANNELS]; +}; + +/* set/get digitalio */ +#define MCDRV_MUSIC_COM_UPDATE_FLAG 0x00000001U +#define MCDRV_MUSIC_DIR_UPDATE_FLAG 0x00000002U +#define MCDRV_MUSIC_DIT_UPDATE_FLAG 0x00000004U +#define MCDRV_EXT_COM_UPDATE_FLAG 0x00000008U +#define MCDRV_EXT_DIR_UPDATE_FLAG 0x00000010U +#define MCDRV_EXT_DIT_UPDATE_FLAG 0x00000020U +#define MCDRV_VOICE_COM_UPDATE_FLAG 0x00000040U +#define MCDRV_VOICE_DIR_UPDATE_FLAG 0x00000080U +#define MCDRV_VOICE_DIT_UPDATE_FLAG 0x00000100U +#define MCDRV_HIFI_COM_UPDATE_FLAG 0x00000200U +#define MCDRV_HIFI_DIR_UPDATE_FLAG 0x00000400U +#define MCDRV_HIFI_DIT_UPDATE_FLAG 0x00000800U +#define MCDRV_ALL_DIO_UPDATE_FLAG 0x00000fffU + +/* mcdrv_dio_common master_slave setting */ +#define MCDRV_DIO_SLAVE 0 +#define MCDRV_DIO_MASTER 1 + +/* mcdrv_dio_common bDigitalAutoFs setting */ +#define MCDRV_AUTOFS_OFF 0 +#define MCDRV_AUTOFS_ON 1 + +/* mcdrv_dio_common fs setting */ +#define MCDRV_FS_48000 0 +#define MCDRV_FS_44100 1 +#define MCDRV_FS_32000 2 +#define MCDRV_FS_NONE1 3 +#define MCDRV_FS_24000 4 +#define MCDRV_FS_22050 5 +#define MCDRV_FS_16000 6 +#define MCDRV_FS_NONE2 7 +#define MCDRV_FS_12000 8 +#define MCDRV_FS_11025 9 +#define MCDRV_FS_8000 10 +#define MCDRV_FS_NONE3 11 +#define MCDRV_FS_192000 12 +#define MCDRV_FS_96000 13 +#define MCDRV_FS_LAST MCDRV_FS_96000 + +/* mcdrv_dio_common bck_fs setting */ +#define MCDRV_BCKFS_64 0 +#define MCDRV_BCKFS_48 1 +#define MCDRV_BCKFS_32 2 +#define MCDRV_BCKFS_NONE1 3 +#define MCDRV_BCKFS_512 4 +#define MCDRV_BCKFS_256 5 +#define MCDRV_BCKFS_192 6 +#define MCDRV_BCKFS_128 7 +#define MCDRV_BCKFS_96 8 +#define MCDRV_BCKFS_24 9 +#define MCDRV_BCKFS_16 10 +#define MCDRV_BCKFS_8 11 +#define MCDRV_BCKFS_NONE2 12 +#define MCDRV_BCKFS_NONE3 13 +#define MCDRV_BCKFS_NONE4 14 +#define MCDRV_BCKFS_SLAVE 15 +#define MCDRV_BCKFS_LAST MCDRV_BCKFS_SLAVE + +/* mcdrv_dio_common interface setting */ +#define MCDRV_DIO_DA 0 +#define MCDRV_DIO_PCM 1 + +/* mcdrv_dio_common bck_invert setting */ +#define MCDRV_BCLK_NORMAL 0 +#define MCDRV_BCLK_INVERT 1 + +/* mcdrv_dio_common src_thru setting */ +#define MCDRV_SRC_NOT_THRU 0 +#define MCDRV_SRC_THRU 1 + +/* mcdrv_dio_common pcm_hiz_transition setting */ +#define MCDRV_PCMHIZTRANS_FALLING 0 +#define MCDRV_PCMHIZTRANS_RISING 1 + +/* mcdrv_dio_common pcm_frame setting */ +#define MCDRV_PCM_SHORTFRAME 0 +#define MCDRV_PCM_LONGFRAME 1 + +struct mcdrv_dio_common { + bool master_slave; + bool auto_fs; + u8 fs; + u8 bck_fs; + bool interface; + bool bck_invert; + bool src_thru; + bool pcm_hiz_transition; + bool pcm_frame; + u8 pcm_high_period; +}; + +/* mcdrv_da_format bit_sel setting */ +#define MCDRV_BITSEL_16 0 +#define MCDRV_BITSEL_20 1 +#define MCDRV_BITSEL_24 2 +#define MCDRV_BITSEL_32 3 +#define MCDRV_BITSEL_LAST MCDRV_BITSEL_32 + +/* mcdrv_da_format mode setting */ +#define MCDRV_DAMODE_HEADALIGN 0 +#define MCDRV_DAMODE_I2S 1 +#define MCDRV_DAMODE_TAILALIGN 2 +#define MCDRV_DAMODE_LAST MCDRV_DAMODE_TAILALIGN + +struct mcdrv_da_format { + u8 bit_sel; + u8 mode; +}; + +/* mcdrv_pcm_format mono setting */ +#define MCDRV_PCM_STEREO 0 +#define MCDRV_PCM_MONO 1 + +/* mcdrv_pcm_format order setting */ +#define MCDRV_PCM_MSB_FIRST 0 +#define MCDRV_PCM_LSB_FIRST 1 + +/* mcdrv_pcm_format law setting */ +#define MCDRV_PCM_LINEAR 0 +#define MCDRV_PCM_ALAW 1 +#define MCDRV_PCM_MULAW 2 +#define MCDRV_PCM_LAST MCDRV_PCM_MULAW + +/* mcdrv_pcm_format bit_sel setting */ +#define MCDRV_PCM_BITSEL_8 0 +#define MCDRV_PCM_BITSEL_16 1 +#define MCDRV_PCM_BITSEL_24 2 +#define MCDRV_PCM_BITSEL_LAST MCDRV_PCM_BITSEL_24 + +struct mcdrv_pcm_format { + bool mono; + bool order; + u8 law; + u8 bit_sel; +}; + +struct mcdrv_dio_dir { + struct mcdrv_da_format da_format; + struct mcdrv_pcm_format pcm_format; +}; + +/* mcdrv_dio_dit st_mode setting */ +#define MCDRV_STMODE_ZERO 0 +#define MCDRV_STMODE_HOLD 1 + +/* mcdrv_dio_dit edge setting */ +#define MCDRV_SDOUT_NORMAL 0 +#define MCDRV_SDOUT_AHEAD 1 + +struct mcdrv_dio_dit { + bool st_mode; + bool edge; + struct mcdrv_da_format da_format; + struct mcdrv_pcm_format pcm_format; +}; + +struct mcdrv_dio_port { + struct mcdrv_dio_common dio_common; + struct mcdrv_dio_dir dir; + struct mcdrv_dio_dit dit; +}; + +struct mcdrv_dio_info { + struct mcdrv_dio_port port[4]; +}; + +/* set/get digitalio_path */ +#define MCDRV_PHYS0_UPDATE_FLAG 0x00000001U +#define MCDRV_PHYS1_UPDATE_FLAG 0x00000002U +#define MCDRV_PHYS2_UPDATE_FLAG 0x00000004U +#define MCDRV_PHYS3_UPDATE_FLAG 0x00000008U +#define MCDRV_MUSICNUM_UPDATE_FLAG 0x00000010U +#define MCDRV_DIR0SLOT_UPDATE_FLAG 0x00000020U +#define MCDRV_DIR1SLOT_UPDATE_FLAG 0x00000040U +#define MCDRV_DIR2SLOT_UPDATE_FLAG 0x00000080U +#define MCDRV_DIT0SLOT_UPDATE_FLAG 0x00000100U +#define MCDRV_DIT1SLOT_UPDATE_FLAG 0x00000200U +#define MCDRV_DIT2SLOT_UPDATE_FLAG 0x00000400U + +/* mcdrv_dio_path_info phys_port setting */ +#define MCDRV_PHYSPORT_DIO0 0 +#define MCDRV_PHYSPORT_DIO1 1 +#define MCDRV_PHYSPORT_DIO2 2 +#define MCDRV_PHYSPORT_NONE 3 +#define MCDRV_PHYSPORT_SLIM0 4 +#define MCDRV_PHYSPORT_SLIM1 5 +#define MCDRV_PHYSPORT_SLIM2 6 +#define MCDRV_PHYSPORT_LAST MCDRV_PHYSPORT_SLIM2 + +/* mcdrv_dio_path_info music_ch setting */ +#define MCDRV_MUSIC_2CH 0 +#define MCDRV_MUSIC_4CH 1 +#define MCDRV_MUSIC_6CH 2 +#define MCDRV_MUSIC_LAST MCDRV_MUSIC_6CH + +struct mcdrv_dio_path_info { + u8 phys_port[4]; + u8 music_ch; + u8 music_rslot[3]; + u8 music_tslot[3]; +}; + +/* set/get swap */ +#define MCDRV_SWAP_ADIF0_UPDATE_FLAG 0x00000001U +#define MCDRV_SWAP_ADIF1_UPDATE_FLAG 0x00000002U +#define MCDRV_SWAP_ADIF2_UPDATE_FLAG 0x00000004U +#define MCDRV_SWAP_DAC0_UPDATE_FLAG 0x00000008U +#define MCDRV_SWAP_DAC1_UPDATE_FLAG 0x00000010U +#define MCDRV_SWAP_MUSICIN0_UPDATE_FLAG 0x00000020U +#define MCDRV_SWAP_MUSICIN1_UPDATE_FLAG 0x00000040U +#define MCDRV_SWAP_MUSICIN2_UPDATE_FLAG 0x00000080U +#define MCDRV_SWAP_EXTIN_UPDATE_FLAG 0x00000100U +#define MCDRV_SWAP_VOICEIN_UPDATE_FLAG 0x00000200U +#define MCDRV_SWAP_HIFIIN_UPDATE_FLAG 0x00000400U +#define MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG 0x00000800U +#define MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG 0x00001000U +#define MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG 0x00002000U +#define MCDRV_SWAP_EXTOUT_UPDATE_FLAG 0x00004000U +#define MCDRV_SWAP_VOICEOUT_UPDATE_FLAG 0x00008000U +#define MCDRV_SWAP_HIFIOUT_UPDATE_FLAG 0x00010000U +#define MCDRV_SWAP_ALL_UPDATE_FLAG 0x0001ffffU + +/* mcdrv_swap_info adif/dac setting */ +#define MCDRV_SWAP_NORMAL 0 +#define MCDRV_SWAP_SWAP 1 +#define MCDRV_SWAP_MUTE 2 +#define MCDRV_SWAP_CENTER 3 +#define MCDRV_SWAP_MIX 4 +#define MCDRV_SWAP_MONOMIX 5 +#define MCDRV_SWAP_BOTHL 6 +#define MCDRV_SWAP_BOTHR 7 +#define MCDRV_SWAP_LAST MCDRV_SWAP_BOTHR + +/* mcdrv_swap_info + music_in/ext_in/voice_in/hifi_in/music_out/ext_out/voice_out/hifi_out + setting */ +#define MCDRV_SWSWAP_NORMAL 0 +#define MCDRV_SWSWAP_BOTH1 1 +#define MCDRV_SWSWAP_BOTH0 2 +#define MCDRV_SWSWAP_SWAP 3 +#define MCDRV_SWSWAP_LAST MCDRV_SWSWAP_SWAP + +struct mcdrv_swap_info { + u8 adif0; + u8 adif1; + u8 adif2; + u8 dac0; + u8 dac1; + u8 music_in0; + u8 music_in1; + u8 music_in2; + u8 ext_in; + u8 voice_in; + u8 hifi_in; + u8 music_out0; + u8 music_out1; + u8 music_out2; + u8 ext_out; + u8 voice_out; + u8 hifi_out; +}; + +/* get transition */ +#define MCDRV_DSPTYPE_FDSP 0 +#define MCDRV_DSPTYPE_BDSP 1 + +/* register dsp cb */ +#define MCDRV_AE_EVT_STOP 1 +#define MCDRV_AE_EVT_APPSTOP 2 +#define MCDRV_AE_EVT_APPREQ 3 +#define MCDRV_AE_EVT_COEFDONE 4 +#define MCDRV_AE_EVT_ERROR 5 +#define MCDRV_CDSP_EVT_ERROR 11 +#define MCDRV_CDSP_EVT_PARAM 12 +#define MCDRV_CDSP_ENV_END 13 +#define MCDRV_CDSP_EVT_FIFO 14 +#define MCDRV_EDSP_EVT_E2PARAM 21 + +/* set/get hsdet */ +#define MCDRV_ENPLUGDET_UPDATE_FLAG 0x00000001U +#define MCDRV_ENPLUGDETDB_UPDATE_FLAG 0x00000002U +#define MCDRV_ENDLYKEYOFF_UPDATE_FLAG 0x00000004U +#define MCDRV_ENDLYKEYON_UPDATE_FLAG 0x00000008U +#define MCDRV_ENMICDET_UPDATE_FLAG 0x00000010U +#define MCDRV_ENKEYOFF_UPDATE_FLAG 0x00000020U +#define MCDRV_ENKEYON_UPDATE_FLAG 0x00000040U +#define MCDRV_HSDETDBNC_UPDATE_FLAG 0x00000080U +#define MCDRV_KEYOFFMTIM_UPDATE_FLAG 0x00000100U +#define MCDRV_KEYONMTIM_UPDATE_FLAG 0x00000200U +#define MCDRV_KEY0OFFDLYTIM_UPDATE_FLAG 0x00000400U +#define MCDRV_KEY1OFFDLYTIM_UPDATE_FLAG 0x00000800U +#define MCDRV_KEY2OFFDLYTIM_UPDATE_FLAG 0x00001000U +#define MCDRV_KEY0ONDLYTIM_UPDATE_FLAG 0x00002000U +#define MCDRV_KEY1ONDLYTIM_UPDATE_FLAG 0x00004000U +#define MCDRV_KEY2ONDLYTIM_UPDATE_FLAG 0x00008000U +#define MCDRV_KEY0ONDLYTIM2_UPDATE_FLAG 0x00010000U +#define MCDRV_KEY1ONDLYTIM2_UPDATE_FLAG 0x00020000U +#define MCDRV_KEY2ONDLYTIM2_UPDATE_FLAG 0x00040000U +#define MCDRV_IRQTYPE_UPDATE_FLAG 0x00080000U +#define MCDRV_DETINV_UPDATE_FLAG 0x00100000U +#define MCDRV_HSDETMODE_UPDATE_FLAG 0x00200000U +#define MCDRV_SPERIOD_UPDATE_FLAG 0x00400000U +#define MCDRV_LPERIOD_UPDATE_FLAG 0x00800000U +#define MCDRV_DBNCNUMPLUG_UPDATE_FLAG 0x01000000U +#define MCDRV_DBNCNUMMIC_UPDATE_FLAG 0x02000000U +#define MCDRV_DBNCNUMKEY_UPDATE_FLAG 0x04000000U +#define MCDRV_SGNL_UPDATE_FLAG 0x08000000U +#define MCDRV_IMPSEL_UPDATE_FLAG 0x10000000U +#define MCDRV_DLYIRQSTOP_UPDATE_FLAG 0x20000000U +#define MCDRV_CBFUNC_UPDATE_FLAG 0x40000000U + +/* mcdrv_hsdet_info en_plug_det setting */ +#define MCDRV_PLUGDET_DISABLE 0 +#define MCDRV_PLUGDET_ENABLE 1 + +/* mcdrv_hsdet_info en_plug_det_db setting */ +#define MCDRV_PLUGDETDB_DISABLE 0 +#define MCDRV_PLUGDETDB_DET_ENABLE 1 +#define MCDRV_PLUGDETDB_UNDET_ENABLE 2 +#define MCDRV_PLUGDETDB_BOTH_ENABLE 3 +#define MCDRV_PLUGDETDB_LAST MCDRV_PLUGDETDB_BOTH_ENABLE + +/* mcdrv_hsdet_info + en_dly_key_off/en_dly_key_on/en_key_off/en_key_on setting */ +#define MCDRV_KEYEN_D_D_D 0 +#define MCDRV_KEYEN_D_D_E 1 +#define MCDRV_KEYEN_D_E_D 2 +#define MCDRV_KEYEN_D_E_E 3 +#define MCDRV_KEYEN_E_D_D 4 +#define MCDRV_KEYEN_E_D_E 5 +#define MCDRV_KEYEN_E_E_D 6 +#define MCDRV_KEYEN_E_E_E 7 +#define MCDRV_KEYEN_LAST MCDRV_KEYEN_E_E_E + +/* mcdrv_hsdet_info en_mic_det setting */ +#define MCDRV_MICDET_DISABLE 0 +#define MCDRV_MICDET_ENABLE 1 + +/* mcdrv_hsdet_info hs_det_dbnc setting */ +#define MCDRV_DETDBNC_27 0 +#define MCDRV_DETDBNC_55 1 +#define MCDRV_DETDBNC_109 2 +#define MCDRV_DETDBNC_219 3 +#define MCDRV_DETDBNC_438 4 +#define MCDRV_DETDBNC_875 5 +#define MCDRV_DETDBNC_1313 6 +#define MCDRV_DETDBNC_1750 7 +#define MCDRV_DETDBNC_LAST MCDRV_DETDBNC_1750 + +/* mcdrv_hsdet_info key_off_mtim setting */ +#define MCDRV_KEYOFF_MTIM_63 0 +#define MCDRV_KEYOFF_MTIM_16 1 + +/* mcdrv_hsdet_info key_on_mtim setting */ +#define MCDRV_KEYON_MTIM_63 0 +#define MCDRV_KEYON_MTIM_250 1 + +/* mcdrv_hsdet_info key_off_dly_tim setting */ +#define MC_DRV_KEYOFFDLYTIM_MAX 15 + +/* mcdrv_hsdet_info key_on_dly_tim setting */ +#define MC_DRV_KEYONDLYTIM_MAX 15 + +/* mcdrv_hsdet_info key_on_dly_tim2 setting */ +#define MC_DRV_KEYONDLYTIM2_MAX 15 + +/* mcdrv_hsdet_info irq_type setting */ +#define MCDRV_IRQTYPE_NORMAL 0 +#define MCDRV_IRQTYPE_REF 1 +#define MCDRV_IRQTYPE_EX 2 +#define MCDRV_IRQTYPE_LAST MCDRV_IRQTYPE_EX + +/* mcdrv_hsdet_info det_in_inv setting */ +#define MCDRV_DET_IN_NORMAL 0 +#define MCDRV_DET_IN_INV 1 +#define MCDRV_DET_IN_NORMAL_NORMAL 4 +#define MCDRV_DET_IN_INV_NORMAL 5 +#define MCDRV_DET_IN_NORMAL_INV 6 +#define MCDRV_DET_IN_INV_INV 7 +#define MCDRV_DET_IN_LAST MCDRV_DET_IN_INV_INV + +/* mcdrv_hsdet_info hs_det_mode setting */ +#define MCDRV_HSDET_MODE_DETIN_A 4 +#define MCDRV_HSDET_MODE_DETIN_B 6 + +/* mcdrv_hsdet_info speriod setting */ +#define MCDRV_SPERIOD_244 0 +#define MCDRV_SPERIOD_488 1 +#define MCDRV_SPERIOD_977 2 +#define MCDRV_SPERIOD_1953 3 +#define MCDRV_SPERIOD_3906 4 +#define MCDRV_SPERIOD_7813 5 +#define MCDRV_SPERIOD_15625 6 +#define MCDRV_SPERIOD_31250 7 +#define MCDRV_SPERIOD_LAST MCDRV_SPERIOD_31250 + +/* mcdrv_hsdet_info lperiod setting */ +#define MCDRV_LPERIOD_3906 0 +#define MCDRV_LPERIOD_62500 1 +#define MCDRV_LPERIOD_125000 2 +#define MCDRV_LPERIOD_250000 3 +#define MCDRV_LPERIOD_LAST MCDRV_LPERIOD_250000 + +/* mcdrv_hsdet_info dbnc_num setting */ +#define MCDRV_DBNC_NUM_2 0 +#define MCDRV_DBNC_NUM_3 1 +#define MCDRV_DBNC_NUM_4 2 +#define MCDRV_DBNC_NUM_7 3 +#define MCDRV_DBNC_NUM_LAST MCDRV_DBNC_NUM_7 + +/* mcdrv_hsdet_info sgnl_period setting */ +#define MCDRV_SGNLPERIOD_61 0 +#define MCDRV_SGNLPERIOD_79 1 +#define MCDRV_SGNLPERIOD_97 2 +#define MCDRV_SGNLPERIOD_151 3 +#define MCDRV_SGNLPERIOD_LAST MCDRV_SGNLPERIOD_151 + +/* mcdrv_hsdet_info sgnl_num setting */ +#define MCDRV_SGNLNUM_1 0 +#define MCDRV_SGNLNUM_4 1 +#define MCDRV_SGNLNUM_6 2 +#define MCDRV_SGNLNUM_8 3 +#define MCDRV_SGNLNUM_LAST MCDRV_SGNLNUM_8 +#define MCDRV_SGNLNUM_NONE 0xff + +/* mcdrv_hsdet_info sgnl_peak setting */ +#define MCDRV_SGNLPEAK_500 0 +#define MCDRV_SGNLPEAK_730 1 +#define MCDRV_SGNLPEAK_960 2 +#define MCDRV_SGNLPEAK_1182 3 +#define MCDRV_SGNLPEAK_LAST MCDRV_SGNLPEAK_1182 + +/* mcdrv_hsdet_info imp_sel setting */ +#define MCDRV_IMPSEL_MOSTFREQ 0 +#define MCDRV_IMPSEL_MIN 1 + +/* mcdrv_hsdet_info dly_irq_stop setting */ +#define MCDRV_DLYIRQ_DONTCARE 0 +#define MCDRV_DLYIRQ_STOP 1 + +#define MCDRV_HSDET_EVT_PLUGDET_DB_FLAG 0x00000001 +#define MCDRV_HSDET_EVT_PLUGUNDET_DB_FLAG 0x00000002 +#define MCDRV_HSDET_EVT_PLUGDET_FLAG 0x00000080 +#define MCDRV_HSDET_EVT_DLYKEYON0_FLAG 0x00000100 +#define MCDRV_HSDET_EVT_DLYKEYON1_FLAG 0x00000200 +#define MCDRV_HSDET_EVT_DLYKEYON2_FLAG 0x00000400 +#define MCDRV_HSDET_EVT_DLYKEYOFF0_FLAG 0x00000800 +#define MCDRV_HSDET_EVT_DLYKEYOFF1_FLAG 0x00001000 +#define MCDRV_HSDET_EVT_DLYKEYOFF2_FLAG 0x00002000 +#define MCDRV_HSDET_EVT_KEYON0_FLAG 0x00010000 +#define MCDRV_HSDET_EVT_KEYON1_FLAG 0x00020000 +#define MCDRV_HSDET_EVT_KEYON2_FLAG 0x00040000 +#define MCDRV_HSDET_EVT_KEYOFF0_FLAG 0x00080000 +#define MCDRV_HSDET_EVT_KEYOFF1_FLAG 0x00100000 +#define MCDRV_HSDET_EVT_KEYOFF2_FLAG 0x00200000 +#define MCDRV_HSDET_EVT_MICDET_FLAG 0x00400000 +#define MCDRV_HSDET_EVT_SENSEFIN_FLAG 0x80000000 + +struct mcdrv_hsdet_res { + u8 key_cnt0; + u8 key_cnt1; + u8 key_cnt2; + u8 plug_rev; + u8 hp_imp_class; + u16 hp_imp; +}; + +typedef void (*callback_function) (u32 flags, struct mcdrv_hsdet_res *res); + +struct mcdrv_hsdet_info { + bool en_plug_det; + u8 en_plug_det_db; + u8 en_dly_key_off; + u8 en_dly_key_on; + bool en_mic_det; + u8 en_key_off; + u8 en_key_on; + u8 hs_det_dbnc; + bool key_off_mtim; + bool key_on_mtim; + u8 key0_off_dly_tim; + u8 key1_off_dly_tim; + u8 key2_off_dly_tim; + u8 key0_on_dly_tim; + u8 key1_on_dly_tim; + u8 key2_on_dly_tim; + u8 key0_on_dly_tim2; + u8 key1_on_dly_tim2; + u8 key2_on_dly_tim2; + u8 irq_type; + u8 plug_det_db_irq_type; + u8 plug_undet_db_irq_type; + u8 mic_det_irq_type; + u8 plug_det_irq_type; + u8 key0_on_irq_type; + u8 key1_on_irq_type; + u8 key2_on_irq_type; + u8 key0_off_irq_type; + u8 key1_off_irq_type; + u8 key2_off_irq_type; + u8 det_in_inv; + u8 hs_det_mode; + u8 speriod; + u8 lperiod; + u8 dbnc_num_plug; + u8 dbnc_num_mic; + u8 dbnc_num_key; + u8 sgnl_period; + u8 sgnl_num; + u8 sgnl_peak; + bool imp_sel; + bool dly_irq_stop; + callback_function cbfunc; +}; + +int mc_init(struct mcdrv_dev_info *info); +int mc_term(void); +int mc_do_irq(void); +int mc_control(unsigned int cmd, unsigned long arg, unsigned int flags); +int mc_version_id_get(void); + +#endif /* _MCDRIVER_H */
On Wed, Jan 16, 2013 at 05:33:03PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcdriver.c | 2934 ++++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcdriver.h | 1017 +++++++++++++
Same comments as previous patches, really... this is a very big block of code with no visible relationship with Linux. Looking at the code it seems fairly clear that at least some this stuff ought to be integrated with the ASoC framework but it doesn't even reference the framework.
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcedspdrv.c | 636 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcedspdrv.h | 45 +++ 3 files changed, 683 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcedspdrv.c create mode 100644 sound/soc/codecs/ymu831/mcedspdrv.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index e908b6d..d0586ca 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -2,6 +2,7 @@ snd-soc-ymu831-objs := \ mcbdspdrv.o \ mccdspdrv.o \ mcdevif.o \ - mcdriver.o + mcdriver.o \ + mcedspdrv.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcedspdrv.c b/sound/soc/codecs/ymu831/mcedspdrv.c new file mode 100644 index 0000000..ad143e8 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcedspdrv.c @@ -0,0 +1,636 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcedspdrv.c + * Description : MC E-DSP driver + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/types.h> + +#include <asm/byteorder.h> + +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcresctrl.h" + +#define CHUNK_SIZE 8 + +#define AEC_EDSP_TAG_IMEM 0x00002000 +#define AEC_EDSP_TAG_XMEM 0x00002100 +#define AEC_EDSP_TAG_YMEM 0x00002200 +#define AEC_EDSP_TAG_REG 0x00002300 + +#define MEM_FIX_SIZE 4 + +#define REG_UNIT_NUM 9 +#define REG_FIX_SIZE 4 +#define REG_COMMAND 0 +#define REG_REQ_0 1 +#define REG_REQ_NUM 8 +#define REG_RES_NUM 8 + +#define E1_COMMAND_RUN_MODE 0x40 +#define E1_COMMAND_SLEEP_MODE 0x00 +#define E1_COMMAND_OFFSET_START 0x02 +#define E1_COMMAND_OFFSET_STOP 0x00 +#define E1_COMMAND_IMPEDANCE_START 0x81 +#define E1_COMMAND_IMPEDANCE_STOP 0x80 +#define OFFSET_START 1 +#define OFFSET_STOP 0 +#define IMPEDANCE_START 1 +#define IMPEDANCE_STOP 0 + +#define SYSEQ_NUM 15 +#define BAND_NUM 3 +#define SYSEQ_NO_MODIFY 0 +#define SYSEQ_MODIFY_0 1 +#define SYSEQ_MODIFY_0 1 +#define SYSEQ_MODIFY_1 2 +#define SYSEQ_MODIFY_2 4 + +struct aec_edsp_info { + bool on; + u8 *data; + u32 data_size; + + u8 *i_mem; + u32 i_mem_size; + u8 *x_mem; + u32 x_mem_size; + u8 *y_mem; + u32 y_mem_size; + u8 *reg; + u32 cmd_count; +}; + +struct edsp_info { + bool initialized; + u8 sys_eq0_modify; + u8 sys_eq0[SYSEQ_NUM * BAND_NUM]; + u8 sys_eq1_modify; + u8 sys_eq1[SYSEQ_NUM * BAND_NUM]; +}; + +static struct edsp_info mc_edsp_info = { + .sys_eq0_modify = SYSEQ_MODIFY_0 | SYSEQ_MODIFY_1 | SYSEQ_MODIFY_2, + .sys_eq1_modify = SYSEQ_MODIFY_0 | SYSEQ_MODIFY_1 | SYSEQ_MODIFY_2, +}; + +static inline void edsp_get_data(struct mcdrv_aec_info *aec, + struct aec_edsp_info *edsp) +{ + if (aec->e2.enable) { + edsp->on = aec->e2.on; + + if (!edsp->on) + return; + + edsp->data = &aec->e2.config.data[CHUNK_SIZE]; + edsp->data_size = aec->e2.config.data_size; + } +} + +static inline int edsp_data_analyze(struct aec_edsp_info *edsp) +{ + u32 top, tag, size, tmp; + u8 *data; + u32 data_size; + + if (!edsp->on) + return 0; + + if (!edsp->data || !edsp->data_size) + return 0; + + data = edsp->data; + data_size = edsp->data_size; + + top = 0; + while (top < data_size) { + if (top + CHUNK_SIZE > data_size) + return -EINVAL; + + tag = htonl(*(u32 *) (data + top)); + size = htonl(*(u32 *) (data + top + 4)); + + if (top + CHUNK_SIZE + size > data_size) + return -EINVAL; + + top += CHUNK_SIZE; + + switch (tag) { + case AEC_EDSP_TAG_IMEM: + if (data_size < MEM_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top)); + if (!tmp) + break; + if (tmp % 3) + return -EINVAL; + if (tmp + MEM_FIX_SIZE > size) + return -EINVAL; + if (edsp->i_mem) + return -EINVAL; + + edsp->i_mem = &data[top + MEM_FIX_SIZE]; + edsp->i_mem_size = tmp; + break; + case AEC_EDSP_TAG_XMEM: + if (data_size < MEM_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top)); + if (!tmp) + break; + if (tmp & 0x07) + return -EINVAL; + if (tmp + MEM_FIX_SIZE > size) + return -EINVAL; + if (edsp->x_mem) + return -EINVAL; + + edsp->x_mem = &data[top + MEM_FIX_SIZE]; + edsp->x_mem_size = tmp; + break; + case AEC_EDSP_TAG_YMEM: + if (data_size < MEM_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top)); + if (!tmp) + break; + if (tmp % 3) + return -EINVAL; + if (tmp + MEM_FIX_SIZE > size) + return -EINVAL; + if (edsp->y_mem) + return -EINVAL; + + edsp->y_mem = &data[top + MEM_FIX_SIZE]; + edsp->y_mem_size = tmp; + break; + case AEC_EDSP_TAG_REG: + if (data_size < REG_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top)); + if (!tmp) + break; + if (tmp != REG_UNIT_NUM) + return -EINVAL; + if (tmp + REG_FIX_SIZE > size) + return -EINVAL; + if (edsp->reg) + return -EINVAL; + + edsp->reg = &data[top + MEM_FIX_SIZE]; + edsp->cmd_count = 1; + break; + default: + break; + } + + top += size; + } + + return 0; +} + +static inline void edsp_firmware_set(struct aec_edsp_info *edsp) +{ + u32 i; + + if (!edsp->on) + return; + + if (!edsp->i_mem && !edsp->x_mem && !edsp->y_mem) + return; + + mc_packet_add_force_write_e(MCI_E2DSP, MCB_E2DSP_RST); + + /* E2IMEM */ + if (edsp->i_mem) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_E2IMEM); + mc_packet_add_force_write_if(MCI_EDSP_FW_A, 0); + + for (i = 0; i < edsp->i_mem_size; ++i) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + edsp->i_mem[i]); + + mc_packet_execute(); + } + + /* E2YMEM */ + if (edsp->y_mem) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_E2YMEM); + mc_packet_add_force_write_if(MCI_EDSP_FW_A, 0); + + for (i = 0; i < edsp->y_mem_size; ++i) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + edsp->y_mem[i]); + + mc_packet_execute(); + } + + /* E2XMEM */ + if (edsp->x_mem) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_E2XMEM); + + mc_packet_add_force_write_if(MCI_EDSP_FW_A, 0); + + for (i = 0; i < edsp->x_mem_size; ++i) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + edsp->x_mem[i]); + + mc_packet_execute(); + } + + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, MCI_EDSP_FW_PAGE_DEF); + mc_packet_add_force_write_e(MCI_E2DSP, 0); + mc_packet_execute(); +} + +static inline void edsp_e2_command_write(struct aec_edsp_info *edsp) +{ + int i; + + if (edsp->on && edsp->reg && edsp->cmd_count) { + for (i = 0; i < REG_REQ_NUM; ++i) + mc_packet_add_force_write_e((MCI_E2REQ_0 + i), + edsp->reg[REG_REQ_0 + i]); + + mc_packet_add_force_write_e(MCI_E2COMMAND, + edsp->reg[REG_COMMAND]); + mc_packet_execute(); + } +} + +static inline void edsp_irq_enable(void) +{ + u8 data; + + mc_read_digital(MCI_EEDSP, &data, 1); + data |= MCB_EE2DSP; + mc_packet_add_write_if(MCI_EEDSP, data); +} + +static inline void edsp_irq_disable(void) +{ + u8 data; + + mc_read_digital(MCI_EEDSP, &data, 1); + data &= ~MCB_EE2DSP; + mc_packet_add_write_if(MCI_EEDSP, data); +} + +int mc_edsp_init(void) +{ + int i; + + if (mc_edsp_info.initialized) + return -EBUSY; + + mc_edsp_info.initialized = true; + + mc_edsp_info.sys_eq0_modify = SYSEQ_MODIFY_0 | SYSEQ_MODIFY_1 | + SYSEQ_MODIFY_2; + mc_edsp_info.sys_eq1_modify = SYSEQ_MODIFY_0 | SYSEQ_MODIFY_1 | + SYSEQ_MODIFY_2; + for (i = 0; i < SYSEQ_NUM * BAND_NUM; ++i) + mc_edsp_info.sys_eq0[i] = 0; + for (i = 0; i < SYSEQ_NUM * BAND_NUM; ++i) + mc_edsp_info.sys_eq1[i] = 0; + + return 0; +} + +void mc_edsp_term(void) +{ + u8 data; + + if (!mc_edsp_info.initialized) + return; + + mc_read_digital(MCI_EEDSP, &data, 1); + data &= ~(MCB_EE2DSP_OV | MCB_EE2DSP); + mc_packet_add_force_write_if(MCI_EEDSP, data); + mc_packet_add_force_write_if(MCI_EDSP, MCB_E2DSP_STA); + mc_packet_add_force_write_e(MCI_E2DSP, MCI_E2DSP_DEF); + mc_packet_execute(); + + mc_edsp_info.initialized = false; +} + +void mc_edsp_irq(void) +{ + u8 status, data; + + mc_read_digital(MCI_EDSP, &status, 1); + status &= MCB_E2DSP_STA; + mc_packet_add_force_write_if(MCI_EDSP, status); + mc_packet_execute(); + + if (status & MCB_E2DSP_STA) + mc_read_e(MCI_E2STATUS, &data, 1); +} + +int mc_edsp_set_dsp(struct mcdrv_aec_info *aec) +{ + struct aec_edsp_info edsp; + int ret; + + if (!aec) + return -EINVAL; + + memset(&edsp, 0, sizeof(edsp)); + + edsp_get_data(aec, &edsp); + + ret = edsp_data_analyze(&edsp); + if (ret < 0) + return ret; + + if (aec->e2.enable && !edsp.on) { + mc_packet_add_force_write_e(MCI_E2DSP, MCB_E2DSP_RST); + mc_packet_execute(); + } + + if (!edsp.data || !edsp.data_size) + return 0; + + if (!mc_edsp_info.initialized) + return -EBUSY; + + edsp_firmware_set(&edsp); + + edsp_e2_command_write(&edsp); + + return 0; +} + +int mc_edsp_start(void) +{ + if (!mc_edsp_info.initialized) + return -EBUSY; + + edsp_irq_enable(); + + return 0; +} + +int mc_edsp_stop(void) +{ + if (!mc_edsp_info.initialized) + return -EBUSY; + + edsp_irq_disable(); + + return 0; +} + +static int edsp_e1_download_1band(u8 *sys_eq0, u8 *sys_eq1, u8 enable) +{ + u8 tmp; + bool sys_eq0_skip = false, sys_eq1_skip = false; + int i; + + tmp = enable; + if (sys_eq0) { + for (i = 0; i < SYSEQ_NUM; ++i) + if (mc_edsp_info.sys_eq0[i] != sys_eq0[i]) { + mc_edsp_info.sys_eq0[i] = sys_eq0[i]; + mc_edsp_info.sys_eq0_modify = true; + } + + if (mc_edsp_info.sys_eq0_modify) + tmp &= ~MCB_SYSEQ_SYSEQ0_ENB; + else + sys_eq0_skip = true; + mc_edsp_info.sys_eq0_modify = false; + } + if (sys_eq1) { + for (i = 0; i < SYSEQ_NUM; ++i) + if (mc_edsp_info.sys_eq1[i] != sys_eq1[i]) { + mc_edsp_info.sys_eq1[i] = sys_eq1[i]; + mc_edsp_info.sys_eq1_modify = true; + } + + if (mc_edsp_info.sys_eq1_modify) + tmp &= ~MCB_SYSEQ_SYSEQ1_ENB; + else + sys_eq1_skip = true; + mc_edsp_info.sys_eq1_modify = false; + } + + if (sys_eq0_skip && sys_eq1_skip) + return 0; + + mc_packet_add_force_write_e(MCI_SYSEQ, tmp); + + if (!sys_eq0_skip) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ0); + + for (i = 0; i < SYSEQ_NUM; ++i) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, sys_eq0[i]); + + mc_packet_execute(); + } + + if (!sys_eq1_skip) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ1); + + for (i = 0; i < SYSEQ_NUM; ++i) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, sys_eq1[i]); + + mc_packet_execute(); + } + + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, MCI_EDSP_FW_PAGE_DEF); + mc_packet_add_force_write_e(MCI_SYSEQ, enable); + mc_packet_execute(); + + return 0; +} + +int edsp_e1_download_3band(u8 *sys_eq0, u8 *sys_eq1, u8 enable) +{ + u8 sys_eq0_modify = SYSEQ_NO_MODIFY, sys_eq1_modify = SYSEQ_NO_MODIFY; + u8 tmp; + bool sys_eq0_skip = false, sys_eq1_skip = false; + int i, j, k; + + tmp = enable; + if (sys_eq0) { + sys_eq0_modify = mc_edsp_info.sys_eq0_modify; + for (i = 0, j = SYSEQ_NUM, k = SYSEQ_NUM * 2; i < SYSEQ_NUM; + i++, j++, k++) { + if (mc_edsp_info.sys_eq0[i] != sys_eq0[i]) { + mc_edsp_info.sys_eq0[i] = sys_eq0[i]; + sys_eq0_modify |= SYSEQ_MODIFY_0; + } + + if (mc_edsp_info.sys_eq0[j] != sys_eq0[j]) { + mc_edsp_info.sys_eq0[j] = sys_eq0[j]; + sys_eq0_modify |= SYSEQ_MODIFY_1; + } + + if (mc_edsp_info.sys_eq0[k] != sys_eq0[k]) { + mc_edsp_info.sys_eq0[k] = sys_eq0[k]; + sys_eq0_modify |= SYSEQ_MODIFY_2; + } + } + + if (sys_eq0_modify != SYSEQ_NO_MODIFY) { + if (sys_eq0_modify & SYSEQ_MODIFY_0) + tmp &= ~MCB_SYSEQ_SYSEQ0_B0_ENB; + if (sys_eq0_modify & SYSEQ_MODIFY_1) + tmp &= ~MCB_SYSEQ_SYSEQ0_B1_ENB; + if (sys_eq0_modify & SYSEQ_MODIFY_2) + tmp &= ~MCB_SYSEQ_SYSEQ0_B2_ENB; + } else + sys_eq0_skip = true; + mc_edsp_info.sys_eq0_modify = SYSEQ_NO_MODIFY; + } + + if (sys_eq1) { + sys_eq1_modify = mc_edsp_info.sys_eq1_modify; + for (i = 0, j = SYSEQ_NUM, k = SYSEQ_NUM * 2; i < SYSEQ_NUM; + ++i, ++j, ++k) { + if (mc_edsp_info.sys_eq1[i] != sys_eq1[i]) { + mc_edsp_info.sys_eq1[i] = sys_eq1[i]; + sys_eq1_modify |= SYSEQ_MODIFY_0; + } + + if (mc_edsp_info.sys_eq1[j] != sys_eq1[j]) { + mc_edsp_info.sys_eq1[j] = sys_eq1[j]; + sys_eq1_modify |= SYSEQ_MODIFY_1; + } + + if (mc_edsp_info.sys_eq1[k] != sys_eq1[k]) { + mc_edsp_info.sys_eq1[k] = sys_eq1[k]; + sys_eq1_modify |= SYSEQ_MODIFY_2; + } + } + + if (sys_eq1_modify != SYSEQ_NO_MODIFY) { + if (sys_eq1_modify & SYSEQ_MODIFY_0) + tmp &= ~MCB_SYSEQ_SYSEQ1_B0_ENB; + if (sys_eq1_modify & SYSEQ_MODIFY_1) + tmp &= ~MCB_SYSEQ_SYSEQ1_B1_ENB; + if (sys_eq1_modify & SYSEQ_MODIFY_2) + tmp &= ~MCB_SYSEQ_SYSEQ1_B2_ENB; + } else + sys_eq1_skip = true; + mc_edsp_info.sys_eq1_modify = SYSEQ_NO_MODIFY; + } + + if (sys_eq0_skip && sys_eq1_skip) + return 0; + + mc_packet_add_force_write_e(MCI_SYSEQ, tmp); + + if (!sys_eq0_skip) { + if (sys_eq0_modify & SYSEQ_MODIFY_0) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ0_B0); + for (i = 0; i < SYSEQ_NUM; i++) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + sys_eq0[i]); + } + + if (sys_eq0_modify & SYSEQ_MODIFY_1) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ0_B1); + for (i = SYSEQ_NUM; i < SYSEQ_NUM * 2; i++) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + sys_eq0[i]); + } + + if (sys_eq0_modify & SYSEQ_MODIFY_2) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ0_B2); + for (i = SYSEQ_NUM * 2; i < SYSEQ_NUM * 3; i++) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + sys_eq0[i]); + } + + mc_packet_execute(); + } + + if (!sys_eq1_skip) { + if (sys_eq1_modify & SYSEQ_MODIFY_0) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ1_B0); + for (i = 0; i < SYSEQ_NUM; i++) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + sys_eq1[i]); + } + + if (sys_eq1_modify & SYSEQ_MODIFY_1) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ1_B1); + for (i = SYSEQ_NUM; i < SYSEQ_NUM * 2; i++) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + sys_eq1[i]); + } + + if (sys_eq1_modify & SYSEQ_MODIFY_2) { + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, + MCB_EDSP_FW_PAGE_SYSEQ1_B2); + for (i = SYSEQ_NUM * 2; i < SYSEQ_NUM * 3; i++) + mc_packet_add_force_write_if(MCI_EDSP_FW_D, + sys_eq1[i]); + } + + mc_packet_execute(); + } + + mc_packet_add_force_write_if(MCI_EDSP_FW_PAGE, MCI_EDSP_FW_PAGE_DEF); + mc_packet_add_force_write_e(MCI_SYSEQ, enable); + mc_packet_execute(); + + return 0; +} + +int mc_edsp_e1_download(u8 *sys_eq0, u8 *sys_eq1, u8 enable) +{ + u8 dev_id; + + dev_id = mc_a_register_get_value(MCI_A_DEV_ID); + if (dev_id & 0x7) + return edsp_e1_download_3band(sys_eq0, sys_eq1, enable); + + return edsp_e1_download_1band(sys_eq0, sys_eq1, enable); +} diff --git a/sound/soc/codecs/ymu831/mcedspdrv.h b/sound/soc/codecs/ymu831/mcedspdrv.h new file mode 100644 index 0000000..60697ac --- /dev/null +++ b/sound/soc/codecs/ymu831/mcedspdrv.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcedspdrv.h + * Description : MC E-DSP driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _MCEDSPDRV_H +#define _MCEDSPDRV_H + +#include "mcresctrl.h" + +int mc_edsp_init(void); +void mc_edsp_term(void); +void mc_edsp_irq(void); +int mc_edsp_set_dsp(struct mcdrv_aec_info *aec); +int mc_edsp_start(void); +int mc_edsp_stop(void); +int mc_edsp_e1_download(u8 *sys_eq0, u8 *sys_eq1, u8 enable); + +#endif /* _MCEDSPDRV_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcfdspdrv.c | 1666 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcfdspdrv.h | 55 ++ 3 files changed, 1723 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcfdspdrv.c create mode 100644 sound/soc/codecs/ymu831/mcfdspdrv.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index d0586ca..c6809c0 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -3,6 +3,7 @@ snd-soc-ymu831-objs := \ mccdspdrv.o \ mcdevif.o \ mcdriver.o \ - mcedspdrv.o + mcedspdrv.o \ + mcfdspdrv.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcfdspdrv.c b/sound/soc/codecs/ymu831/mcfdspdrv.c new file mode 100644 index 0000000..9312b70 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcfdspdrv.c @@ -0,0 +1,1666 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcfdspdrv.c + * Description : MC F-DSP driver + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/errno.h> +#include <linux/types.h> + +#include <asm/byteorder.h> + +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcfdspdrv.h" +#include "mcresctrl.h" + +#define CHUNK_SIZE 8 + +#define COEF_DMA_TRANS 0 +#define COEF_DSP_TRANS 1 +#define COEF_DSP_TRANS_MAX 512 + +#define AEC_FDSP_TAG_FWCTRL 0x00000100 +#define FWCTRL_SIZE 27 +#define AEC_FDSP_TAG_CHSEL 0x00000200 +#define CHSEL_SIZE 33 +#define AEC_FDSP_TAG_TOP_ENV 0x00000300 +#define TOP_ENV_SIZE 29 +#define AEC_FDSP_TAG_TOP_COEF 0x00000400 +#define TOP_COEF_FIX_SIZE 8 +#define AEC_FDSP_TAG_TOP_INS 0x00000500 +#define TOP_INS_FIX_SIZE 8 +#define AEC_FDSP_TAG_APP_MASK 0xffffff00 +#define AEC_FDSP_TAG_APPNO_MASK 0xff +#define AEC_FDSP_TAG_APP_ENV 0x00000600 +#define APP_ENV_FIX_SIZE 38 +#define AEC_FDSP_TAG_APP_COEF 0x00000700 +#define APP_COEF_FIX_SIZE 9 +#define AEC_FDSP_TAG_APP_CONST 0x00000800 +#define AEC_FDSP_TAG_APP_INS 0x00000900 +#define APP_INS_FIX_SIZE 8 +#define AEC_FDSP_TAG_APP_REG 0x00000a00 +#define APP_REG_FIX_SIZE 8 +#define AEC_FDSP_TAG_EX_INFO_1 0x00000b00 +#define EX_INFO_1_SIZE 4 + +#define FWCTL_FWMOD 0 +#define FWCTL_FS 1 +#define FWCTL_APPEXEC 2 +#define FWCTL_FADECODE 26 + +#define CHSEL_BYPASS 0 +#define CHSEL_INFDSPSRC 1 +#define CHSEL_OUTAUDIOSRC 17 + +#define TOP_ENV_ID 0 +#define TOP_ENV_INSTBASE 1 +#define TOP_ENV_MBLKSIZE 5 +#define TOP_ENV_MBUFSIZE 6 +#define TOP_ENV_MOCHCNFG 7 +#define TOP_ENV_MICHCNFG 8 +#define TOP_ENV_SSTARTCH 9 +#define TOP_ENV_SNUMOFOCH 10 +#define TOP_ENV_SNUMOFICH 11 +#define TOP_ENV_SAVEBUFSIZE1 12 +#define TOP_ENV_SAVEBUFSIZE0 16 +#define TOP_ENV_LIMITWORKSIZE 20 +#define TOP_ENV_WORKBASE 24 +#define TOP_ENV_TOPBASE0 28 + +#define TOP_COEF_ADR 0 +#define TOP_COEF_SIZE 4 +#define TOP_COEF_DATA 8 + +#define TOP_INST_ADR 0 +#define TOP_INST_SIZE 4 +#define TOP_INST_DATA 8 + +#define APP_ENV_ID 0 +#define APP_ENV_EXCECPROCESS 1 +#define APP_ENV_INSTBASE 2 +#define APP_ENV_REGBASE 6 +#define APP_ENV_EXECFS 10 +#define APP_ENV_EXECCH 14 +#define APP_ENV_WORKBASE 18 +#define APP_ENV_APPBASE0 22 +#define APP_ENV_APPBASE1 26 +#define APP_ENV_APPBASE2 30 +#define APP_ENV_APPBASE3 34 +#define APP_ENV_APPFADE 38 +#define APP_ENV_APPIRQ 39 + +#define APP_COEF_ADR 0 +#define APP_COEF_SIZE 5 +#define APP_COEF_DATA 9 + +#define APP_INST_ADR 0 +#define APP_INST_SIZE 4 +#define APP_INST_DATA 8 + +#define APP_REG_ADR 0 +#define APP_REG_SIZE 4 +#define APP_REG_DATA 8 + +#define APP_PARAM_ON 1 + +#define MULTI_CHUNK_TOP_COEF 1 +#define MULTI_CHUNK_APP_COEF 2 +#define MULTI_CHUNK_APP_REG 3 + +#define STOP_KIND_NONE 0x00 +#define STOP_KIND_FDSP 0x01 +#define STOP_KIND_APP_EXEC 0x02 +#define STOP_KIND_APP 0x04 +#define STOP_KIND_WAIT 0x08 + +#define RESTART_OFF 0 +#define RESTART_ON 1 +#define RESTART_BYPASS 2 + +#define APP_VOL_ID 0x07 +#define FIX_APP_VOL_FREE 0 +#define FIX_APP_VOL_EXIST 1 +#define FIX_APP_VOL_NO 22 +#define FIX_APP_VOL_ACT MCI_APPACT0 +#define FIX_APP_VOL_BIT MCB_APPACT22 +#define FIX_APP_VOL_APPEXEC 0x400000 +#define FIX_APP_VOL_REG_BASE 0x4F +#define FIX_APP_VOL_REG_FADE_CTRL (FIX_APP_VOL_REG_BASE + 1) +#define FIX_APP_VOL_REG_FADE_CTRL_BIT 0x01 +#define FIX_APP_VOL_REG_FADE_STE (FIX_APP_VOL_REG_BASE + 2) +#define FIX_APP_VOL_REG_FADE_STE_BIT 0x01 +#define FIX_APP_FADE_WAIT_TIME_US 10000 + +#define DEF_FDSP_STOP_WAIT_TIME_US 15000 + +#define FDSP_APP_NUM 24 +#define FDSP_APP_EXEC_STOP 0 +#define FDSP_APP_EXEC_START 1 +#define FDSP_APP_EXEC_DONTCARE 2 + +struct fdsp_info { + bool initialized; + u16 input_add_format; + u16 output_add_format; + u32 wait; + u32 app_stop; + u32 app_irq_enable; + u32 app_fade; + u8 dsp_bypass; + u8 fix_app_vol; + + /* registers */ + u8 adi_mute0; + u8 adi_mute1; + u8 ado_mute0; + u8 ado_mute1; + u8 dsp_ctrl; + u8 app_exec0; + u8 app_exec1; + u8 app_exec2; + u8 app_irq_enable0; + u8 app_irq_enable1; + u8 app_irq_enable2; +}; + +struct fdsp_data { + u8 *data; + u32 data_size; + u8 must_stop; + u8 *fw_ctrl; + u8 *ch_sel; + u8 *top_env; + u32 top_coef_count; + u8 *top_inst; + u32 target_app; + u32 app_env_count; + u8 *app_env[FDSP_APP_NUM]; + u8 coef_trans; + u32 app_coef_count; + u32 app_const_count; + u32 app_coef_trans_max; + u32 app_inst_count; + u8 *app_inst[FDSP_APP_NUM]; + u32 app_reg_count; + u8 *ext_info1; + u32 app_exec; +}; + +struct fdsp_exec { + u32 app_exec; + u8 restart; +}; + +static struct fdsp_info mc_fdsp_info = { + .wait = DEF_FDSP_STOP_WAIT_TIME_US +}; + +static inline u8 create_mute_value(u8 mute, u8 onoff, u8 mask) +{ + switch (onoff) { + case FDSP_MUTE_ON: + mute &= ~mask; + break; + case FDSP_MUTE_OFF: + mute |= mask; + break; + default: + break; + } + + return mute; +} + +static u32 fdsp_app_act_get(void) +{ + u32 app_act; + u8 data; + + mc_read_f(MCI_APPACT0, &data, 1); + app_act = (u32) data << 16; + + mc_read_f(MCI_APPACT1, &data, 1); + app_act |= (u32) data << 8; + + mc_read_f(MCI_APPACT2, &data, 1); + app_act |= data; + + return app_act; +} + +static inline void fdsp_audioif_set(u16 input_add_format, u16 output_add_format) +{ + mc_packet_add_force_write_f(MCI_ADIDFMT0, input_add_format & 0xff); + mc_packet_add_force_write_f(MCI_ADIDFMT1, + (input_add_format >> 8) & 0xff); + + mc_packet_add_force_write_f(MCI_ADODFMT0, output_add_format & 0xff); + mc_packet_add_force_write_f(MCI_ADODFMT1, + (output_add_format >> 8) & 0xff); + + mc_packet_execute(); +} + +static void fdsp_core_init(void) +{ + mc_fdsp_info.app_stop = 0; + mc_fdsp_info.app_irq_enable = 0; + mc_fdsp_info.app_fade = 0; + mc_fdsp_info.dsp_bypass = 0; + mc_fdsp_info.fix_app_vol = FIX_APP_VOL_FREE; + + mc_fdsp_info.dsp_ctrl = MCI_DSPCTRL_DEF; + mc_fdsp_info.app_exec0 = MCI_APPEXEC0_DEF; + mc_fdsp_info.app_exec1 = MCI_APPEXEC1_DEF; + mc_fdsp_info.app_exec2 = MCI_APPEXEC2_DEF; + mc_fdsp_info.app_irq_enable0 = MCI_APPIENB0_DEF; + mc_fdsp_info.app_irq_enable1 = MCI_APPIENB1_DEF; + mc_fdsp_info.app_irq_enable2 = MCI_APPIENB2_DEF; + + mc_packet_add_force_write_f(MCI_DSPCTRL, mc_fdsp_info.dsp_ctrl); + + mc_packet_add_force_write_f(MCI_APPEXEC0, mc_fdsp_info.app_exec0); + + mc_packet_add_force_write_f(MCI_APPEXEC1, mc_fdsp_info.app_exec1); + + mc_packet_add_force_write_f(MCI_APPEXEC2, mc_fdsp_info.app_exec2); + + mc_packet_add_force_write_f(MCI_APPIENB0, mc_fdsp_info.app_irq_enable0); + + mc_packet_add_force_write_f(MCI_APPIENB1, mc_fdsp_info.app_irq_enable1); + + mc_packet_add_force_write_f(MCI_APPIENB2, mc_fdsp_info.app_irq_enable2); + + mc_packet_add_force_write_f(MCI_ADIMUTE0, mc_fdsp_info.adi_mute0); + + mc_packet_add_force_write_f(MCI_ADIMUTE1, mc_fdsp_info.adi_mute1); + + mc_packet_add_force_write_f(MCI_ADIMUTE2, MCB_ADIMTSET); + + mc_packet_add_force_write_f(MCI_ADOMUTE0, mc_fdsp_info.ado_mute0); + + mc_packet_add_force_write_f(MCI_ADOMUTE1, mc_fdsp_info.ado_mute1); + + mc_packet_add_force_write_f(MCI_ADOMUTE2, MCB_ADOMTSET); + + mc_packet_add_force_write_f(MCI_APPFADE0, 0); + + mc_packet_add_force_write_f(MCI_APPFADE1, 0); + + mc_packet_add_force_write_f(MCI_APPFADE2, 0); + + mc_packet_execute(); + + fdsp_audioif_set(mc_fdsp_info.input_add_format, + mc_fdsp_info.output_add_format); +} + +static int fdsp_get_data(struct mcdrv_aec_info *aec, struct fdsp_data *fdsp) +{ + fdsp->data = NULL; + fdsp->data_size = 0; + + switch (aec->fdsp_locate) { + case FDSP_LOCATE_AUDIOENGINE: + if (aec->audio_engine.enable) { + if (!aec->audio_engine.fdsp_on) + return 0; + + fdsp->data = &aec->audio_engine.fdsp.data[CHUNK_SIZE]; + fdsp->data_size = aec->audio_engine.fdsp.data_size; + } + break; + case FDSP_LOCATE_V_BOX: + if (aec->vbox.enable) { + if (!aec->vbox.fdsp_on) + return 0; + + fdsp->data = &aec->vbox.fdsp.data[CHUNK_SIZE]; + fdsp->data_size = aec->vbox.fdsp.data_size; + } + break; + default: + return -EINVAL; + } + + return 0; +} + +static inline int fdsp_firmware_control_analyze(struct fdsp_data *fdsp, + u8 *data) +{ + int i; + + if (data[FWCTL_FWMOD]) + return -EINVAL; + + if (data[FWCTL_FS] != 0xff || data[FWCTL_FADECODE] != 0xff) + fdsp->must_stop |= STOP_KIND_FDSP; + + for (i = 0; i < FDSP_APP_NUM; ++i) + if (data[FWCTL_APPEXEC + i] != FDSP_APP_EXEC_DONTCARE && + i != FIX_APP_VOL_NO) { + fdsp->must_stop |= STOP_KIND_APP_EXEC; + break; + } + + return 0; +} + +static inline int fdsp_app_environment_check(u32 app_no, u8 *app_env) +{ + if (app_no != FIX_APP_VOL_NO) + return 0; + + if (!app_env[APP_ENV_ID]) + return 0; + + if (app_env[APP_ENV_ID] != APP_VOL_ID) + return -EINVAL; + + if ((app_env[APP_ENV_REGBASE + 3] & 0x7F) != FIX_APP_VOL_REG_BASE) + return -EINVAL; + + return 0; +} + +static inline int fdsp_app_data_analyze(struct fdsp_data *fdsp, + u32 tag, u32 size, u32 top, u8 *data) +{ + u32 app_no, tmp; + + app_no = tag & AEC_FDSP_TAG_APPNO_MASK; + if (app_no >= FDSP_APP_NUM) + return -EINVAL; + + switch (tag & AEC_FDSP_TAG_APP_MASK) { + case AEC_FDSP_TAG_APP_ENV: + if (size < APP_ENV_FIX_SIZE) + return -EINVAL; + if (fdsp->app_env[app_no]) + return -EINVAL; + if (fdsp_app_environment_check(app_no, &data[top]) < 0) + return -EINVAL; + + fdsp->app_env[app_no] = &data[top]; + fdsp->app_env_count++; + fdsp->target_app |= 1 << app_no; + fdsp->coef_trans = COEF_DMA_TRANS; + fdsp->must_stop |= STOP_KIND_APP; + break; + case AEC_FDSP_TAG_APP_COEF: + case AEC_FDSP_TAG_APP_CONST: + if (size < APP_COEF_FIX_SIZE) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top + 5)); + if (!tmp) + break; + if (tmp & 3) + return -EINVAL; + if (tmp + APP_COEF_FIX_SIZE > size) + return -EINVAL; + + if (data[top + 4] != COEF_DSP_TRANS) { + fdsp->coef_trans = COEF_DMA_TRANS; + fdsp->must_stop |= STOP_KIND_APP; + } + + if ((tag & AEC_FDSP_TAG_APP_MASK) == AEC_FDSP_TAG_APP_COEF) + fdsp->app_coef_count++; + else + fdsp->app_const_count++; + + fdsp->target_app |= 1 << app_no; + + if (tmp > fdsp->app_coef_trans_max) + fdsp->app_coef_trans_max = tmp; + + fdsp->must_stop |= STOP_KIND_WAIT; + break; + case AEC_FDSP_TAG_APP_INS: + if (size < APP_INS_FIX_SIZE) + return -EINVAL; + if (fdsp->app_inst[app_no]) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top + 4)); + if (!tmp) + break; + if (tmp & 3) + return -EINVAL; + if (tmp + APP_INS_FIX_SIZE > size) + return -EINVAL; + + fdsp->app_inst[app_no] = &data[top]; + fdsp->app_inst_count++; + fdsp->target_app |= 1 << app_no; + fdsp->coef_trans = COEF_DMA_TRANS; + fdsp->must_stop |= STOP_KIND_APP; + break; + case AEC_FDSP_TAG_APP_REG: + if (size < APP_REG_FIX_SIZE) + return -EINVAL; + tmp = htonl(*(u32 *) (data + top + 4)); + if (!tmp) + break; + if (tmp + APP_REG_FIX_SIZE > size) + return -EINVAL; + + fdsp->app_reg_count++; + fdsp->must_stop |= STOP_KIND_WAIT; + break; + + default: + break; + } + + return 0; +} + +static inline void fdsp_coef_trans_check(struct fdsp_data *fdsp) +{ + if (fdsp->coef_trans != COEF_DSP_TRANS) + return; + + if (!fdsp->app_coef_count && !fdsp->app_const_count) + return; + + if (fdsp->app_coef_trans_max > COEF_DSP_TRANS_MAX || + (fdsp->app_coef_count + fdsp->app_const_count) > 1) + fdsp->coef_trans = COEF_DMA_TRANS; + + if (fdsp->coef_trans == COEF_DMA_TRANS) + fdsp->must_stop |= STOP_KIND_APP; +} + +static int fdsp_data_analyze(struct fdsp_data *fdsp) +{ + u32 top, tag, size, tmp; + u8 *data; + u32 data_size; + int ret, i; + + fdsp->must_stop = STOP_KIND_NONE; + fdsp->fw_ctrl = NULL; + fdsp->ch_sel = NULL; + fdsp->top_env = NULL; + fdsp->top_coef_count = 0; + fdsp->top_inst = NULL; + fdsp->target_app = 0; + fdsp->app_env_count = 0; + fdsp->coef_trans = COEF_DSP_TRANS; + fdsp->app_coef_count = 0; + fdsp->app_const_count = 0; + fdsp->app_coef_trans_max = 0; + fdsp->app_inst_count = 0; + fdsp->app_reg_count = 0; + fdsp->ext_info1 = NULL; + for (i = 0; i < FDSP_APP_NUM; ++i) { + fdsp->app_env[i] = NULL; + fdsp->app_inst[i] = NULL; + } + + if (!fdsp->data || !fdsp->data_size) + return 0; + + data = fdsp->data; + data_size = fdsp->data_size; + + top = 0; + while (top < data_size) { + if (top + CHUNK_SIZE > data_size) + return -EINVAL; + + tag = htonl(*(u32 *) (data + top)); + size = htonl(*(u32 *) (data + top + 4)); + if (top + CHUNK_SIZE + size > data_size) + return -EINVAL; + + top += CHUNK_SIZE; + switch (tag) { + case AEC_FDSP_TAG_FWCTRL: + if (size < FWCTRL_SIZE) + return -EINVAL; + if (fdsp->fw_ctrl) + return -EINVAL; + + ret = fdsp_firmware_control_analyze(fdsp, &data[top]); + if (ret < 0) + return ret; + + fdsp->fw_ctrl = &data[top]; + break; + case AEC_FDSP_TAG_CHSEL: + if (size < CHSEL_SIZE) + return -EINVAL; + if (fdsp->ch_sel) + return -EINVAL; + + fdsp->ch_sel = &data[top]; + fdsp->must_stop |= STOP_KIND_FDSP; + break; + case AEC_FDSP_TAG_TOP_ENV: + if (size < TOP_ENV_SIZE) + return -EINVAL; + if (fdsp->top_env) + return -EINVAL; + + fdsp->top_env = &data[top]; + fdsp->must_stop |= STOP_KIND_FDSP; + break; + case AEC_FDSP_TAG_TOP_COEF: + if (size < TOP_COEF_FIX_SIZE) + return -EINVAL; + tmp = htonl(*(u32 *) (data + top + 4)); + if (tmp & 3) + return -EINVAL; + if (tmp + TOP_COEF_FIX_SIZE > size) + return -EINVAL; + + fdsp->top_coef_count++; + fdsp->must_stop |= STOP_KIND_FDSP; + break; + case AEC_FDSP_TAG_TOP_INS: + if (size < TOP_INS_FIX_SIZE) + return -EINVAL; + if (fdsp->top_inst) + return -EINVAL; + + tmp = htonl(*(u32 *) (data + top + 4)); + if (!tmp) + break; + if (tmp & 3) + return -EINVAL; + if (tmp + TOP_INS_FIX_SIZE > size) + return -EINVAL; + + fdsp->top_inst = &data[top]; + fdsp->must_stop |= STOP_KIND_FDSP; + break; + default: + ret = fdsp_app_data_analyze(fdsp, tag, size, top, data); + if (ret < 0) + return ret; + } + + top += size; + } + + fdsp_coef_trans_check(fdsp); + + return 0; +} + +static void fdsp_app_irq_set(u32 app_irq_enable) +{ + u8 app_irq_enable0; + u8 app_irq_enable1; + u8 app_irq_enable2; + u8 data; + + app_irq_enable0 = (app_irq_enable >> 16) & 0xff; + app_irq_enable1 = (app_irq_enable >> 8) & 0xff; + app_irq_enable2 = app_irq_enable & 0xff; + + if (mc_fdsp_info.app_irq_enable0 != app_irq_enable0) { + data = app_irq_enable0 & ~mc_fdsp_info.app_irq_enable0; + if (data) + mc_packet_add_force_write_f(MCI_IREQAPP0, data); + + mc_fdsp_info.app_irq_enable0 = app_irq_enable0; + mc_packet_add_force_write_f(MCI_APPIENB0, app_irq_enable0); + + mc_packet_execute(); + } + + if (mc_fdsp_info.app_irq_enable1 != app_irq_enable1) { + data = app_irq_enable1 & ~mc_fdsp_info.app_irq_enable1; + if (data) + mc_packet_add_force_write_f(MCI_IREQAPP1, data); + + mc_fdsp_info.app_irq_enable1 = app_irq_enable1; + mc_packet_add_force_write_f(MCI_APPIENB1, app_irq_enable1); + + mc_packet_execute(); + } + + if (mc_fdsp_info.app_irq_enable2 != app_irq_enable2) { + data = app_irq_enable2 & ~mc_fdsp_info.app_irq_enable2; + if (data) + mc_packet_add_force_write_f(MCI_IREQAPP2, data); + + mc_fdsp_info.app_irq_enable2 = app_irq_enable2; + mc_packet_add_force_write_f(MCI_APPIENB2, app_irq_enable2); + + mc_packet_execute(); + } +} + +static inline void fdsp_irq_disable(struct fdsp_data *fdsp) +{ + if (fdsp->must_stop & STOP_KIND_FDSP) { + mc_packet_add_force_write_if(MCI_IESERR, MCI_IESERR_DEF); + + mc_packet_add_force_write_f(MCI_TOPIENB, MCI_TOPIENB_DEF); + + mc_packet_execute(); + + fdsp_app_irq_set(0); + } else if (fdsp->must_stop & STOP_KIND_APP) + fdsp_app_irq_set(mc_fdsp_info.app_irq_enable & ~fdsp-> + target_app); +} + +static int fdsp_fade_out_set(void) +{ + u8 act; + + if (mc_fdsp_info.fix_app_vol != FIX_APP_VOL_EXIST) + return 0; + + mc_read_f(FIX_APP_VOL_ACT, &act, 1); + + mc_packet_add_force_write_f(MCI_IREQAPP0, MCB_IRAPP22); + + mc_packet_add_force_write_f(FIX_APP_VOL_REG_FADE_CTRL, 0); + + mc_packet_execute(); + + if (!(act & FIX_APP_VOL_BIT)) + return 0; + + mc_packet_add_wait(FIX_APP_FADE_WAIT_TIME_US); + + mc_packet_execute(); + + return 0; +} + +static inline int fdsp_forwarding_wait(void) +{ + mc_packet_add_wait_event(MCDRV_EVT_IF_REG_FLAG_RESET | + (MCI_FDSPTREQ << 8) | MCB_FDSPTREQ); + + return mc_packet_execute(); +} + +static void fdsp_control_set(u8 dsp_ctrl) +{ + if ((dsp_ctrl & MCB_DSPSTART) != MCB_DSPSTART) + mc_packet_add_force_write_if(MCI_FDSPTREQ, MCI_FDSPTREQ_DEF); + + mc_packet_add_force_write_f(MCI_DSPCTRL, dsp_ctrl); + mc_packet_execute(); + + mc_fdsp_info.dsp_ctrl = dsp_ctrl; +} + +static void fdsp_app_fade_set(void) +{ + u8 fade0, fade1, fade2; + + fade0 = mc_fdsp_info.app_fade >> 16; + fade1 = mc_fdsp_info.app_fade >> 8; + fade2 = mc_fdsp_info.app_fade; + + mc_packet_add_write_f(MCI_APPFADE0, fade0); + mc_packet_add_write_f(MCI_APPFADE1, fade1); + mc_packet_add_write_f(MCI_APPFADE2, fade2); + + mc_packet_execute(); +} + +static void fdsp_app_exec_set(u8 app_exec0, u8 app_exec1, u8 app_exec2) +{ + mc_packet_add_write_f(MCI_APPEXEC0, app_exec0); + mc_packet_add_write_f(MCI_APPEXEC1, app_exec1); + mc_packet_add_write_f(MCI_APPEXEC2, app_exec2); + mc_packet_execute(); + + mc_fdsp_info.app_exec0 = app_exec0; + mc_fdsp_info.app_exec1 = app_exec1; + mc_fdsp_info.app_exec2 = app_exec2; +} + +static inline int fdsp_app_stop(u32 app_stop) +{ + u8 app_stop0, app_stop1, app_stop2; + u8 app_stop0_org, app_stop1_org, app_stop2_org; + u8 app_exec0, app_exec1, app_exec2; + int ret = 0; + + if (!app_stop) + return 0; + + app_stop0 = (app_stop >> 16) & MCB_APPEXEC0; + app_stop1 = (app_stop >> 8) & MCB_APPEXEC1; + app_stop2 = app_stop & MCB_APPEXEC2; + app_stop0_org = app_stop0; + app_stop1_org = app_stop1; + app_stop2_org = app_stop2; + + app_stop0 = mc_fdsp_info.app_exec0 & app_stop0; + app_stop1 = mc_fdsp_info.app_exec1 & app_stop1; + app_stop2 = mc_fdsp_info.app_exec2 & app_stop2; + + app_exec0 = mc_fdsp_info.app_exec0 & ~app_stop0; + app_exec1 = mc_fdsp_info.app_exec1 & ~app_stop1; + app_exec2 = mc_fdsp_info.app_exec2 & ~app_stop2; + fdsp_app_exec_set(app_exec0, app_exec1, app_exec2); + + if (app_stop0_org) { + mc_packet_add_wait_event(MCDRV_EVT_F_REG_FLAG_RESET | + (MCI_APPACT0 << 8) | app_stop0_org); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + } + + if (app_stop1_org) { + mc_packet_add_wait_event(MCDRV_EVT_F_REG_FLAG_RESET | + (MCI_APPACT1 << 8) | app_stop1_org); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + } + + if (app_stop2_org) { + mc_packet_add_wait_event(MCDRV_EVT_F_REG_FLAG_RESET | + (MCI_APPACT2 << 8) | app_stop2_org); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + } + + mc_packet_add_force_write_f(MCI_IREQAPP0, app_stop0_org); + mc_packet_add_force_write_f(MCI_IREQAPP1, app_stop1_org); + mc_packet_add_force_write_f(MCI_IREQAPP2, app_stop2_org); + mc_packet_execute(); + + return ret; +} + +static int fdsp_stop(struct fdsp_data *fdsp) +{ + u8 val; + int ret = 0; + + if (fdsp->must_stop & STOP_KIND_FDSP) { + if (mc_fdsp_info.dsp_ctrl & MCB_DSPSTART) { + ret = fdsp_fade_out_set(); + if (ret < 0) + return ret; + + ret = fdsp_forwarding_wait(); + if (ret < 0) + return ret; + } + + mc_read_f(MCI_DSPSTATE, &val, 1); + + fdsp_control_set(MCI_DSPCTRL_DEF); + + if (val & MCB_DSPACT) { + mc_packet_add_wait(mc_fdsp_info.wait); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + val = mc_if_register_get_value(MCI_RST); + if (val & MCB_PSW_F) { + mc_packet_add_force_write_if(MCI_RST, + val | MCB_RST_F); + mc_packet_add_force_write_if(MCI_RST, val); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + } + + fdsp_core_init(); + } + } else if (fdsp->must_stop & STOP_KIND_APP) { + ret = fdsp_forwarding_wait(); + if (ret < 0) + return ret; + + fdsp_app_fade_set(); + + ret = fdsp_app_stop(fdsp->target_app); + } else if (fdsp->must_stop & STOP_KIND_WAIT) + ret = fdsp_forwarding_wait(); + + return ret; +} + +static inline void fdsp_firmware_control_set(struct fdsp_data *fdsp) +{ + u8 *fw_ctrl; + u8 data; + int i; + + fw_ctrl = fdsp->fw_ctrl; + + for (i = 0; i < FDSP_APP_NUM; ++i) { + if (i != FIX_APP_VOL_NO) { + switch (fw_ctrl[FWCTL_APPEXEC + i]) { + case FDSP_APP_EXEC_STOP: + fdsp->app_exec &= ~(0x01U << i); + break; + case FDSP_APP_EXEC_START: + fdsp->app_exec |= (0x01U << i); + break; + default: + break; + } + } + } + + if (!(fdsp->must_stop & STOP_KIND_FDSP)) + return; + + data = (fw_ctrl[FWCTL_FWMOD] << 4) & MCB_FWMOD; + if (fw_ctrl[FWCTL_FS] != 0xff) { + data |= fw_ctrl[FWCTL_FS] & MCB_FS; + mc_packet_add_force_write_f(MCI_FWMOD, data); + } + + if (fw_ctrl[FWCTL_FADECODE] != 0xff) { + data = fw_ctrl[FWCTL_FADECODE] & MCB_FADECODE; + mc_packet_add_force_write_f(MCI_FADECODE, data); + } + + mc_packet_execute(); +} + +static inline void fdsp_channel_select(u8 *ch_sel) +{ + u8 data; + + mc_fdsp_info.dsp_bypass = (ch_sel[CHSEL_BYPASS] << 7) & MCB_DSPBYPASS; + + data = (ch_sel[CHSEL_INFDSPSRC + 1] << 4) & MCB_ADI01CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 0] & MCB_ADI00CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL0, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 3] << 4) & MCB_ADI03CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 2] & MCB_ADI02CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL1, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 5] << 4) & MCB_ADI05CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 4] & MCB_ADI04CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL2, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 7] << 4) & MCB_ADI07CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 6] & MCB_ADI06CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL3, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 9] << 4) & MCB_ADI09CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 8] & MCB_ADI08CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL4, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 11] << 4) & MCB_ADI11CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 10] & MCB_ADI10CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL5, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 13] << 4) & MCB_ADI13CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 12] & MCB_ADI12CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL6, data); + + data = (ch_sel[CHSEL_INFDSPSRC + 15] << 4) & MCB_ADI15CSEL; + data |= ch_sel[CHSEL_INFDSPSRC + 14] & MCB_ADI14CSEL; + mc_packet_add_force_write_f(MCI_ADICSEL7, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 1] << 4) & MCB_ADO01CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 0] & MCB_ADO00CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL0, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 3] << 4) & MCB_ADO03CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 2] & MCB_ADO02CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL1, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 5] << 4) & MCB_ADO05CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 4] & MCB_ADO04CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL2, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 7] << 4) & MCB_ADO07CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 6] & MCB_ADO06CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL3, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 9] << 4) & MCB_ADO09CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 8] & MCB_ADO08CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL4, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 11] << 4) & MCB_ADO11CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 10] & MCB_ADO10CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL5, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 13] << 4) & MCB_ADO13CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 12] & MCB_ADO12CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL6, data); + + data = (ch_sel[CHSEL_OUTAUDIOSRC + 15] << 4) & MCB_ADO15CSEL; + data |= ch_sel[CHSEL_OUTAUDIOSRC + 14] & MCB_ADO14CSEL; + mc_packet_add_force_write_f(MCI_ADOCSEL7, data); + + mc_packet_execute(); +} + +static void fdsp_top_environment_set(u8 *top_env) +{ + u8 data; + + mc_packet_add_force_write_if(MCI_FMAA_19_16, 0); + mc_packet_add_force_write_if(MCI_FMAA_15_8, 0); + mc_packet_add_force_write_if(MCI_FMAA_7_0, 8); + + mc_packet_add_force_write_if(MCI_FDSPTINI, MCI_FDSPTINI_DEF); + mc_packet_execute(); + + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_ID]); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_INSTBASE + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_INSTBASE + 2]); + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_INSTBASE + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_MBLKSIZE] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_MBUFSIZE] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, 0); + data = (top_env[TOP_ENV_MOCHCNFG] << 4) & 0xf0; + data |= top_env[TOP_ENV_MICHCNFG] & 0x0f; + mc_packet_add_force_write_if(MCI_FMAD, data); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_SSTARTCH] & 0x0f); + data = (top_env[TOP_ENV_SNUMOFOCH] << 4) & 0xf0; + data |= top_env[TOP_ENV_SNUMOFICH] & 0x0f; + mc_packet_add_force_write_if(MCI_FMAD, data); + + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_SAVEBUFSIZE1 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_SAVEBUFSIZE1 + 3]); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_SAVEBUFSIZE0 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_SAVEBUFSIZE0 + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_LIMITWORKSIZE + 1] & 0x0f); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_LIMITWORKSIZE + 2]); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_LIMITWORKSIZE + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_WORKBASE + 1] & 0x0f); + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_WORKBASE + 2]); + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_WORKBASE + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + top_env[TOP_ENV_TOPBASE0 + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_TOPBASE0 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, top_env[TOP_ENV_TOPBASE0 + 3]); + + mc_packet_execute(); +} + +static inline void fdsp_top_coef_set(u8 *coef) +{ + u32 size, i; + + mc_packet_add_force_write_if(MCI_FMAA_19_16, + coef[TOP_COEF_ADR + 1] & MCB_FMAA_19_16); + mc_packet_add_force_write_if(MCI_FMAA_15_8, + coef[TOP_COEF_ADR + 2] & MCB_FMAA_15_8); + mc_packet_add_force_write_if(MCI_FMAA_7_0, + coef[TOP_COEF_ADR + 3] & MCB_FMAA_7_0); + mc_packet_add_force_write_if(MCI_FDSPTINI, MCI_FDSPTINI_DEF); + mc_packet_execute(); + + size = htonl(*(u32 *) (coef + TOP_COEF_SIZE)); + for (i = 0; i < size; i++) + mc_packet_add_force_write_if(MCI_FMAD, coef[TOP_COEF_DATA + i]); + + mc_packet_execute(); +} + +static inline void fdsp_app_coef_set(u8 *coef, u8 coef_trans) +{ + u32 size, i; + + mc_packet_add_force_write_if(MCI_FMAA_19_16, + coef[APP_COEF_ADR + 1] & MCB_FMAA_19_16); + mc_packet_add_force_write_if(MCI_FMAA_15_8, + coef[APP_COEF_ADR + 2] & MCB_FMAA_15_8); + mc_packet_add_force_write_if(MCI_FMAA_7_0, + coef[APP_COEF_ADR + 3] & MCB_FMAA_7_0); + + if (coef_trans == COEF_DSP_TRANS) + mc_packet_add_force_write_if(MCI_FDSPTINI, + MCB_DSPTINI | MCB_FMAMOD_DSP); + else + mc_packet_add_force_write_if(MCI_FDSPTINI, MCI_FDSPTINI_DEF); + mc_packet_execute(); + + size = htonl(*(u32 *) (coef + APP_COEF_SIZE)); + for (i = 0; i < size; i++) + mc_packet_add_force_write_if(MCI_FMAD, coef[APP_COEF_DATA + i]); + mc_packet_execute(); +} + +static inline void fdsp_app_reg_set(u8 *reg) +{ + u32 size, i; + + mc_packet_add_force_write_if(MCI_F_REG_A, + reg[APP_REG_ADR + 3] | MCB_F_REG_AINC); + mc_packet_execute(); + + size = htonl(*(u32 *) (reg + APP_REG_SIZE)); + for (i = 0; i < size; i++) + mc_packet_add_force_write_if(MCI_F_REG_D, + reg[APP_REG_DATA + i]); + mc_packet_execute(); +} + +static void fdsp_multi_data_set(struct fdsp_data *fdsp, u32 target) +{ + u32 top, tag, size, app_no, data_size; + u8 *data; + + data = fdsp->data; + data_size = fdsp->data_size; + top = 0; + + while (top < data_size) { + tag = htonl(*(u32 *) (data + top)); + size = htonl(*(u32 *) (data + top + 4)); + + top += CHUNK_SIZE; + app_no = tag & AEC_FDSP_TAG_APPNO_MASK; + + switch (tag & AEC_FDSP_TAG_APP_MASK) { + case AEC_FDSP_TAG_APP_COEF: + case AEC_FDSP_TAG_APP_CONST: + if (target == MULTI_CHUNK_APP_COEF && + app_no < FDSP_APP_NUM) + fdsp_app_coef_set(&data[top], fdsp->coef_trans); + break; + case AEC_FDSP_TAG_APP_REG: + if (target == MULTI_CHUNK_APP_REG && + app_no < FDSP_APP_NUM) + fdsp_app_reg_set(&data[top]); + break; + default: + if (tag == AEC_FDSP_TAG_TOP_COEF && + target == MULTI_CHUNK_TOP_COEF) + fdsp_top_coef_set(&data[top]); + break; + } + + top += size; + } +} + +static inline void fdsp_top_instruction_set(u8 *inst) +{ + u32 size, i; + + mc_packet_add_force_write_if(MCI_FMAA_19_16, + inst[TOP_INST_ADR + 1] & MCB_FMAA_19_16); + mc_packet_add_force_write_if(MCI_FMAA_15_8, + inst[TOP_INST_ADR + 2] & MCB_FMAA_15_8); + mc_packet_add_force_write_if(MCI_FMAA_7_0, + inst[TOP_INST_ADR + 3] & MCB_FMAA_7_0); + mc_packet_add_force_write_if(MCI_FDSPTINI, MCB_FMABUS_I); + mc_packet_execute(); + + size = htonl(*(u32 *) (inst + TOP_INST_SIZE)); + for (i = 0; i < size; i++) + mc_packet_add_force_write_if(MCI_FMAD, inst[TOP_INST_DATA + i]); + mc_packet_execute(); +} + +static inline void fdsp_app_environment_fix(u32 app_no, u8 *app_env) +{ + if (app_no != FIX_APP_VOL_NO) + return; + + if (app_env[APP_ENV_ID] == APP_VOL_ID) + mc_fdsp_info.fix_app_vol = FIX_APP_VOL_EXIST; + else + mc_fdsp_info.fix_app_vol = FIX_APP_VOL_FREE; +} + +static inline void fdsp_app_environment_set(u32 app_no, u8 *app_env) +{ + u32 base; + u8 data; + + base = 0x10 + (app_no * 8); + + mc_packet_add_force_write_if(MCI_FMAA_19_16, + (base >> 16) & MCB_FMAA_19_16); + mc_packet_add_force_write_if(MCI_FMAA_15_8, + (base >> 8) & MCB_FMAA_15_8); + mc_packet_add_force_write_if(MCI_FMAA_7_0, base & MCB_FMAA_7_0); + + mc_packet_add_force_write_if(MCI_FDSPTINI, MCI_FDSPTINI_DEF); + + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_ID]); + data = (app_env[APP_ENV_EXCECPROCESS] << 7) & 0x80; + data |= app_env[APP_ENV_INSTBASE + 1] & 0x1f; + mc_packet_add_force_write_if(MCI_FMAD, data); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_INSTBASE + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_INSTBASE + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_REGBASE + 3] & 0x7f); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_EXECFS + 2] & 0x7f); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_EXECFS + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_EXECCH + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_EXECCH + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_WORKBASE + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_WORKBASE + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_WORKBASE + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_APPBASE0 + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE0 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE0 + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_APPBASE1 + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE1 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE1 + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_APPBASE2 + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE2 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE2 + 3]); + + mc_packet_add_force_write_if(MCI_FMAD, 0); + mc_packet_add_force_write_if(MCI_FMAD, + app_env[APP_ENV_APPBASE3 + 1] & 0x1f); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE3 + 2]); + mc_packet_add_force_write_if(MCI_FMAD, app_env[APP_ENV_APPBASE3 + 3]); + + mc_packet_execute(); + + if ((app_env[APP_ENV_APPFADE] & APP_PARAM_ON) == APP_PARAM_ON) + mc_fdsp_info.app_fade |= 0x01U << app_no; + else + mc_fdsp_info.app_fade &= ~(0x01U << app_no); + + if ((app_env[APP_ENV_APPIRQ] & APP_PARAM_ON) == APP_PARAM_ON) + mc_fdsp_info.app_irq_enable |= 0x01U << app_no; + else + mc_fdsp_info.app_irq_enable &= ~(0x01UL << app_no); +} + +static void fdsp_app_instruction_set(u8 *inst) +{ + u32 size, i; + + mc_packet_add_force_write_if(MCI_FMAA_19_16, + inst[APP_INST_ADR + 1] & MCB_FMAA_19_16); + mc_packet_add_force_write_if(MCI_FMAA_15_8, + inst[APP_INST_ADR + 2] & MCB_FMAA_15_8); + mc_packet_add_force_write_if(MCI_FMAA_7_0, + inst[APP_INST_ADR + 3] & MCB_FMAA_7_0); + + mc_packet_add_force_write_if(MCI_FDSPTINI, MCB_FMABUS_I); + mc_packet_execute(); + + size = htonl(*(u32 *) (inst + APP_INST_SIZE)); + for (i = 0; i < size; i++) + mc_packet_add_force_write_if(MCI_FMAD, inst[APP_INST_DATA + i]); + mc_packet_execute(); +} + +static void fdsp_download(struct fdsp_data *fdsp) +{ + int i; + + if (fdsp->fw_ctrl) + fdsp_firmware_control_set(fdsp); + + if (fdsp->ch_sel) + fdsp_channel_select(fdsp->ch_sel); + + if (fdsp->top_env) + fdsp_top_environment_set(fdsp->top_env); + + if (fdsp->top_coef_count) + fdsp_multi_data_set(fdsp, MULTI_CHUNK_TOP_COEF); + + if (fdsp->top_inst) + fdsp_top_instruction_set(fdsp->top_inst); + + if (fdsp->target_app) + for (i = 0; i < FDSP_APP_NUM; i++) + if (fdsp->app_env[i]) { + fdsp_app_environment_fix(i, fdsp->app_env[i]); + fdsp_app_environment_set(i, fdsp->app_env[i]); + } + + if (fdsp->app_coef_count || fdsp->app_const_count) { + fdsp_multi_data_set(fdsp, MULTI_CHUNK_APP_COEF); + + if (fdsp->coef_trans == COEF_DSP_TRANS) { + mc_packet_add_force_write_if(MCI_FDSPTREQ, + MCB_FDSPTREQ); + mc_packet_execute(); + } + } + + if (fdsp->app_inst_count) + for (i = 0; i < FDSP_APP_NUM; i++) + if (fdsp->app_inst[i]) + fdsp_app_instruction_set(fdsp->app_inst[i]); + + if (fdsp->app_reg_count) + fdsp_multi_data_set(fdsp, MULTI_CHUNK_APP_REG); +} + +static void fdsp_irq_enable(struct fdsp_data *fdsp, struct fdsp_exec *exec) +{ + if (fdsp->must_stop & STOP_KIND_FDSP) { + mc_packet_add_force_write_f(MCI_IREQTOP, MCB_IREQTOP); + mc_packet_add_force_write_if(MCI_IRSERR, MCB_IRSERR | MCB_IRFW); + mc_packet_execute(); + + fdsp_app_irq_set(mc_fdsp_info.app_irq_enable & exec->app_exec); + + mc_packet_add_force_write_f(MCI_TOPIENB, MCB_TOPIENB); + mc_packet_add_force_write_if(MCI_IESERR, MCB_IESERR | MCB_IEFW); + mc_packet_execute(); + } else if (fdsp->must_stop & STOP_KIND_APP_EXEC) { + mc_packet_add_force_write_if(MCI_IRSERR, MCB_IRFW_DSP); + mc_packet_execute(); + + fdsp_app_irq_set(mc_fdsp_info.app_irq_enable & exec->app_exec); + } else if (fdsp->must_stop & STOP_KIND_APP) { + mc_packet_add_force_write_if(MCI_IRSERR, MCB_IRFW_DSP); + mc_packet_execute(); + + fdsp_app_irq_set(mc_fdsp_info.app_irq_enable & exec->app_exec); + } else if (fdsp->must_stop & STOP_KIND_WAIT) { + mc_packet_add_force_write_if(MCI_IRSERR, MCB_IRFW_DSP); + mc_packet_execute(); + } +} + +static void fdsp_face_in_set(void) +{ + if (mc_fdsp_info.fix_app_vol != FIX_APP_VOL_EXIST) + return; + + mc_packet_add_force_write_f(FIX_APP_VOL_REG_FADE_CTRL, + FIX_APP_VOL_REG_FADE_CTRL_BIT); + mc_packet_execute(); +} + +static inline void fdsp_restart(struct fdsp_data *fdsp, struct fdsp_exec *exec) +{ + u8 app_exec0; + u8 app_exec1; + u8 app_exec2; + u32 app_stop; + u32 app_act; + + app_exec0 = (exec->app_exec >> 16) & MCB_APPEXEC0; + app_exec1 = (exec->app_exec >> 8) & MCB_APPEXEC1; + app_exec2 = exec->app_exec & MCB_APPEXEC2; + + if (fdsp->must_stop & STOP_KIND_FDSP) { + fdsp_app_exec_set(app_exec0, app_exec1, app_exec2); + if (exec->restart == RESTART_ON) { + mc_fdsp_info.app_stop = 0; + if (mc_fdsp_info.dsp_bypass & MCB_DSPBYPASS) + fdsp_control_set(MCB_DSPBYPASS); + else { + fdsp_control_set(MCB_DSPSTART); + fdsp_face_in_set(); + } + } + } else if (fdsp->must_stop & STOP_KIND_APP_EXEC) { + app_stop = (u32) (mc_fdsp_info.app_exec0 & ~app_exec0) << 16; + app_stop |= (u32) (mc_fdsp_info.app_exec1 & ~app_exec1) << 8; + app_stop |= mc_fdsp_info.app_exec2 & ~app_exec2; + + fdsp_app_fade_set(); + fdsp_app_exec_set(app_exec0, app_exec1, app_exec2); + fdsp_face_in_set(); + + app_act = fdsp_app_act_get(); + if ((app_stop & app_act) != app_stop) + app_stop &= app_act; + + mc_fdsp_info.app_stop |= app_stop; + } else if (fdsp->must_stop & STOP_KIND_APP) { + fdsp_app_fade_set(); + fdsp_app_exec_set(app_exec0, app_exec1, app_exec2); + fdsp_face_in_set(); + } +} + +static inline int fdsp_audio_engine_set(struct fdsp_data *fdsp) +{ + struct fdsp_exec exec; + u8 data; + int ret; + + fdsp->app_exec = (u32) mc_fdsp_info.app_exec0 << 16 | + (u32) mc_fdsp_info.app_exec1 << 8 | (u32) mc_fdsp_info.app_exec2; + + if (mc_fdsp_info.dsp_ctrl != MCI_DSPCTRL_DEF) + exec.restart = RESTART_ON; + else + exec.restart = RESTART_OFF; + + if (mc_fdsp_info.dsp_ctrl & MCB_DSPBYPASS) + fdsp->must_stop |= STOP_KIND_FDSP; + else if (mc_fdsp_info.dsp_ctrl & MCB_DSPSTART) { + fdsp->must_stop |= STOP_KIND_FDSP; + fdsp->coef_trans = COEF_DMA_TRANS; + } else { + mc_read_f(MCI_DSPSTATE, &data, 1); + if ((data & MCB_DSPACT) != MCB_DSPACT) + fdsp->coef_trans = COEF_DMA_TRANS; + } + + fdsp_irq_disable(fdsp); + + ret = fdsp_stop(fdsp); + if (ret < 0) + return ret; + + if (fdsp->must_stop & STOP_KIND_FDSP) { + mc_packet_add_write_f(MCI_APPFADE0, 0); + mc_packet_add_write_f(MCI_APPFADE1, 0); + mc_packet_add_write_f(MCI_APPFADE2, 0); + } + + fdsp_download(fdsp); + + exec.app_exec = fdsp->app_exec; + if (mc_fdsp_info.fix_app_vol == FIX_APP_VOL_EXIST) + exec.app_exec |= FIX_APP_VOL_APPEXEC; + else + exec.app_exec &= ~FIX_APP_VOL_APPEXEC; + + fdsp_irq_enable(fdsp, &exec); + fdsp_restart(fdsp, &exec); + + return 0; +} + +int mc_fdsp_init(u8 locate, u32 wait) +{ + if (mc_fdsp_info.initialized) + return -EBUSY; + + if (!locate) { + mc_fdsp_info.input_add_format = 0xf0ff; + mc_fdsp_info.output_add_format = 0xf0ff; + } else { + mc_fdsp_info.input_add_format = 0xf000; + mc_fdsp_info.output_add_format = 0xf000; + } + + if (wait) + mc_fdsp_info.wait = wait; + else + mc_fdsp_info.wait = DEF_FDSP_STOP_WAIT_TIME_US; + + mc_fdsp_info.adi_mute0 = MCI_ADIMUTE0_DEF; + mc_fdsp_info.adi_mute1 = MCI_ADIMUTE1_DEF; + mc_fdsp_info.ado_mute0 = MCI_ADOMUTE0_DEF; + mc_fdsp_info.ado_mute1 = MCI_ADOMUTE1_DEF; + + fdsp_core_init(); + + mc_fdsp_info.initialized = true; + + return 0; +} + +void mc_fdsp_term(void) +{ + if (!mc_fdsp_info.initialized) + return; + + mc_packet_add_force_write_if(MCI_IESERR, MCI_IESERR_DEF); + mc_packet_add_force_write_if(MCI_IRSERR, MCB_IRSERR | MCB_IRFW); + mc_packet_add_force_write_f(MCI_DSPCTRL, MCI_DSPCTRL_DEF); + mc_packet_execute(); + + mc_fdsp_info.initialized = false; +} + +void mc_fdsp_irq(void) +{ + u32 app_stop; + u8 ireq, ireq_top = 0, ireq_app0 = 0, ireq_app1 = 0, ireq_app2 = 0; + + mc_read_f(MCI_IRSERR, &ireq, 1); + + mc_packet_add_force_write_if(MCI_IRSERR, ireq); + mc_packet_execute(); + + if (ireq & MCB_IRFW_TOP) { + mc_read_f(MCI_IREQTOP, &ireq_top, 1); + + mc_packet_add_force_write_f(MCI_IREQTOP, ireq_top); + mc_packet_execute(); + } + + if (ireq & MCB_IRFW_APP) { + if (mc_fdsp_info.app_irq_enable0) { + mc_read_f(MCI_IREQAPP0, &ireq_app0, 1); + + mc_packet_add_force_write_f(MCI_IREQAPP0, ireq_app0); + mc_packet_execute(); + + ireq_app0 = ireq_app0 & mc_fdsp_info.app_irq_enable0; + } + + if (mc_fdsp_info.app_irq_enable1) { + mc_read_f(MCI_IREQAPP1, &ireq_app1, 1); + + mc_packet_add_force_write_f(MCI_IREQAPP1, ireq_app1); + mc_packet_execute(); + + ireq_app2 = ireq_app1 & mc_fdsp_info.app_irq_enable1; + } + + if (mc_fdsp_info.app_irq_enable2) { + mc_read_f(MCI_IREQAPP2, &ireq_app2, 1); + + mc_packet_add_force_write_f(MCI_IREQAPP2, ireq_app2); + mc_packet_execute(); + + ireq_app2 = ireq_app2 & mc_fdsp_info.app_irq_enable2; + } + } + + if (ireq_top & MCB_IREQTOP0) { + app_stop = mc_fdsp_info.app_stop & ~fdsp_app_act_get(); + mc_fdsp_info.app_stop &= ~app_stop; + } +} + +int mc_fdsp_set_dsp(struct mcdrv_aec_info *aec) +{ + struct fdsp_data fdsp; + int ret; + + if (!aec) + return -EINVAL; + + ret = fdsp_get_data(aec, &fdsp); + if (ret < 0) + return ret; + + ret = fdsp_data_analyze(&fdsp); + if (ret < 0) + return ret; + + if (!fdsp.data || !fdsp.data_size) + return 0; + + if (!mc_fdsp_info.initialized) + return -EBUSY; + + return fdsp_audio_engine_set(&fdsp); +} + +int mc_fdsp_start(void) +{ + if (!mc_fdsp_info.initialized) + return -EBUSY; + + if (mc_fdsp_info.dsp_bypass & MCB_DSPBYPASS) { + mc_fdsp_info.app_stop = 0; + fdsp_control_set(MCB_DSPBYPASS); + } else if (!(mc_fdsp_info.dsp_ctrl & MCB_DSPSTART)) { + mc_fdsp_info.app_stop = 0; + fdsp_control_set(MCB_DSPSTART); + fdsp_face_in_set(); + } + + return 0; +} + +int mc_fdsp_stop(void) +{ + if (!mc_fdsp_info.initialized) + return 0; + + if (mc_fdsp_info.dsp_ctrl & MCB_DSPSTART) + fdsp_fade_out_set(); + + fdsp_control_set(MCI_DSPCTRL_DEF); + + return 0; +} + +int mc_fdsp_set_mute(struct mcdrv_fdsp_mute *mute) +{ + u8 adi_mute0, adi_mute1; + u8 ado_mute0, ado_mute1; + int i; + + if (!mute) + return -EINVAL; + + for (i = 0; i < FDSP_MUTE_NUM; i++) + if (mute->in_mute[i] > FDSP_MUTE_OFF || + mute->out_mute[i] > FDSP_MUTE_OFF) + return -EINVAL; + + if (!mc_fdsp_info.initialized) + return -EBUSY; + + adi_mute0 = mc_fdsp_info.adi_mute0; + adi_mute0 = create_mute_value(adi_mute0, mute->in_mute[0], + MCB_ADI01MTN | MCB_ADI00MTN); + adi_mute0 = create_mute_value(adi_mute0, mute->in_mute[1], + MCB_ADI03MTN | MCB_ADI02MTN); + adi_mute0 = create_mute_value(adi_mute0, mute->in_mute[2], + MCB_ADI05MTN | MCB_ADI04MTN); + adi_mute0 = create_mute_value(adi_mute0, mute->in_mute[3], + MCB_ADI07MTN | MCB_ADI06MTN); + adi_mute1 = mc_fdsp_info.adi_mute1; + adi_mute1 = create_mute_value(adi_mute1, mute->in_mute[4], + MCB_ADI09MTN | MCB_ADI08MTN); + adi_mute1 = create_mute_value(adi_mute1, mute->in_mute[5], + MCB_ADI11MTN | MCB_ADI10MTN); + adi_mute1 = create_mute_value(adi_mute1, mute->in_mute[6], + MCB_ADI13MTN | MCB_ADI12MTN); + adi_mute1 = create_mute_value(adi_mute1, mute->in_mute[7], + MCB_ADI15MTN | MCB_ADI14MTN); + + ado_mute0 = mc_fdsp_info.ado_mute0; + ado_mute0 = create_mute_value(ado_mute0, mute->out_mute[0], + MCB_ADO01MTN | MCB_ADO00MTN); + ado_mute0 = create_mute_value(ado_mute0, mute->out_mute[1], + MCB_ADO03MTN | MCB_ADO02MTN); + ado_mute0 = create_mute_value(ado_mute0, mute->out_mute[2], + MCB_ADO05MTN | MCB_ADO04MTN); + ado_mute0 = create_mute_value(ado_mute0, mute->out_mute[3], + MCB_ADO07MTN | MCB_ADO06MTN); + ado_mute1 = mc_fdsp_info.ado_mute1; + ado_mute1 = create_mute_value(ado_mute1, mute->out_mute[4], + MCB_ADO09MTN | MCB_ADO08MTN); + ado_mute1 = create_mute_value(ado_mute1, mute->out_mute[5], + MCB_ADO11MTN | MCB_ADO10MTN); + ado_mute1 = create_mute_value(ado_mute1, mute->out_mute[6], + MCB_ADO13MTN | MCB_ADO12MTN); + ado_mute1 = create_mute_value(ado_mute1, mute->out_mute[7], + MCB_ADO15MTN | MCB_ADO14MTN); + + mc_packet_add_force_write_f(MCI_ADIMUTE0, adi_mute0); + mc_packet_add_force_write_f(MCI_ADIMUTE1, adi_mute1); + mc_packet_add_force_write_f(MCI_ADIMUTE2, MCB_ADIMTSET); + + mc_packet_add_force_write_f(MCI_ADOMUTE0, ado_mute0); + mc_packet_add_force_write_f(MCI_ADOMUTE1, ado_mute1); + mc_packet_add_force_write_f(MCI_ADOMUTE2, MCB_ADOMTSET); + + mc_packet_execute(); + + mc_fdsp_info.adi_mute0 = adi_mute0; + mc_fdsp_info.adi_mute1 = adi_mute1; + mc_fdsp_info.ado_mute0 = ado_mute0; + mc_fdsp_info.ado_mute1 = ado_mute1; + + return 0; +} diff --git a/sound/soc/codecs/ymu831/mcfdspdrv.h b/sound/soc/codecs/ymu831/mcfdspdrv.h new file mode 100644 index 0000000..72c6076 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcfdspdrv.h @@ -0,0 +1,55 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcfdspdrv.h + * Description : MC F-DSP driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _MCFDSPDRV_H +#define _MCFDSPDRV_H + +#include "mcresctrl.h" + +#define FDSP_MUTE_NUM 8 +#define FDSP_MUTE_NOTCHANGE 0 +#define FDSP_MUTE_ON 1 +#define FDSP_MUTE_OFF 2 + +struct mcdrv_fdsp_mute { + u8 in_mute[FDSP_MUTE_NUM]; + u8 out_mute[FDSP_MUTE_NUM]; +}; + +int mc_fdsp_init(u8 locate, u32 wait); +void mc_fdsp_term(void); +void mc_fdsp_irq(void); +int mc_fdsp_set_dsp(struct mcdrv_aec_info *aec); +int mc_fdsp_start(void); +int mc_fdsp_stop(void); +int mc_fdsp_set_mute(struct mcdrv_fdsp_mute *mute); + +#endif /* _MCFDSPDRV_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcpacking.c | 4064 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcpacking.h | 217 ++ 3 files changed, 4283 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcpacking.c create mode 100644 sound/soc/codecs/ymu831/mcpacking.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index c6809c0..01f5910 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -4,6 +4,7 @@ snd-soc-ymu831-objs := \ mcdevif.o \ mcdriver.o \ mcedspdrv.o \ - mcfdspdrv.o + mcfdspdrv.o \ + mcpacking.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcpacking.c b/sound/soc/codecs/ymu831/mcpacking.c new file mode 100644 index 0000000..4563afd --- /dev/null +++ b/sound/soc/codecs/ymu831/mcpacking.c @@ -0,0 +1,4064 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcpacking.c + * Description : MC device control packet packing driver + * Version : 1.0.1 Dec 19 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + * - some mc_packet_*() functions move from mcdevif.c + */ +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/types.h> + +#include "mcbdspdrv.h" +#include "mccdspdrv.h" +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcedspdrv.h" +#include "mcfdspdrv.h" +#include "mcpacking.h" +#include "mcresctrl.h" + +#define MCDRV_TCXO_WAIT_TIME 2000 +#define MCDRV_PLL_WAIT_TIME 2000 +#define MCDRV_LDO_WAIT_TIME 1000 +#define MCDRV_VREF_WAIT_TIME_ES1 2000 +#define MCDRV_OSC_WAIT_TIME 10 +#define MCDRV_CP_WAIT_TIME 2000 +#define MCDRV_WAIT_TIME_500US 500 +#define MCDRV_WAIT_TIME_350US 350 +#define MCDRV_OFC_WAIT_TIME 3000 +#define MCDRV_DP_DAC_WAIT_TIME 21 + +#define DTH 3 +#define EN_CP_ILMT_N 1 +#define HP_IDLE 0 +#define HP_IBST 3 +#define HP_MIDBST 1 +#define OP_DAC_HP 0x40 +#define OP_DAC 0x30 +#define CP_88OFF 1 +#define CD_39 0x21 +#define T_CPMODE_OFFCAN_BEFORE 0 +#define T_CPMODE_OFFCAN_AFTER 2 +#define E_99 0x9f +#define E_100 0x01 +#define ANA_114 0x31 +#define ANA_115 0x8a + +enum dio_port { + DIO_0 = 0, + DIO_1, + DIO_2, + DIO_3 +}; + +struct mc_packet { + u32 desc; + u8 data; +}; + +static struct mc_packet packet_queue[MCDRV_MAX_PACKETS + 1]; +static int packet_terminate; + +int mc_packet_init(void) +{ + struct mcdrv_dev_info info; + struct mcdrv_aec_info aec; + enum mcdrv_dev_id id; + u8 val; + + mc_packet_add_force_write_cd(MCI_CD_RST, MCI_CD_RST_DEF); + mc_packet_add_force_write_cd(MCI_CD_RST, 0); + + id = mc_dev_id_get(); + mc_dev_info_get(&info); + + if (id == MCDRV_DEV_ID_80_90H) + val = info.ppd_rc << 4 | info.ppd_hp << 3 | + info.ppd_sp << 2 | + info.ppd_line_out2 << 1 | info.ppd_line_out1; + else + val = info.ppd_sp << 2; + + mc_packet_add_write_ana(MCI_PPD, val); + + switch (id) { + case MCDRV_DEV_ID_81_91H: + val = info.options[12] << 4 | 0x06; + mc_packet_add_write_ana(10, val); + break; + case MCDRV_DEV_ID_81_92H: + val = info.options[12] << 4 | (info.options[13] & 0x0f); + mc_packet_add_write_ana(10, val); + break; + default: + break; + } + + val = info.mb_sel4 << 6 | info.mb_sel3 << 4 | + info.mb_sel2 << 2 | info.mb_sel1; + mc_packet_add_write_ana(MCI_MBSEL, val); + mc_packet_add_write_ana(MCI_KDSET, info.mbs_disch << 4); + + if (id != MCDRV_DEV_ID_80_90H) + mc_packet_add_write_ana(15, info.options[11]); + + val = info.nonclip << 7; + if (id == MCDRV_DEV_ID_80_90H) + val |= DTH; + else + val |= info.options[3]; + mc_packet_add_write_ana(MCI_NONCLIP, val); + + val = info.line_out2_dif << 5 | info.line_out1_dif << 4 | + info.line_in1_dif; + mc_packet_add_write_ana(MCI_DIF, val); + + val = info.svol_hp << 7 | info.svol_sp << 6 + | info.svol_rc << 5 | info.svol_line_out2 << 4 + | info.svol_line_out1 << 3 | MCB_SVOL_HPDET; + mc_packet_add_write_ana(MCI_SVOL, val); + + val = info.hp_hiz << 6 | info.sp_hiz << 4 | info.rc_hiz << 3; + if (id != MCDRV_DEV_ID_80_90H) + val |= info.options[2]; + mc_packet_add_force_write_ana(MCI_HIZ, val); + + val = info.line_out2_hiz << 6 | info.line_out1_hiz << 4; + mc_packet_add_write_ana(MCI_LO_HIZ, val); + + val = info.mic4_single << 7 | info.mic3_single << 6 | + info.mic2_single << 5 | info.mic1_single << 4; + mc_packet_add_write_ana(MCI_MCSNG, val); + + val = info.zc_hp << 7 | info.zc_sp << 6 | + info.zc_rc << 5 | info.zc_line_out2 << 4 | info.zc_line_out1 << 3; + mc_packet_add_write_ana(MCI_ZCOFF, val); + + val = info.cp_mod; + if (id == MCDRV_DEV_ID_80_90H) + val |= EN_CP_ILMT_N << 2; + else + val |= MCB_HIP_DISABLE; + + mc_packet_add_write_ana(MCI_CPMOD, val); + + mc_aec_info_get(&aec); + + val = aec.output.dng_release << 4 | aec.output.dng_attack; + if (id == MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_ana(MCI_DNG_ES1, val); + mc_packet_add_write_ana(MCI_DNG_HP_ES1, + aec.output.dng_target[0]); + val = info.rb_sel << 7; + } else { + mc_packet_add_write_ana(MCI_DNG, val); + mc_packet_add_write_ana(MCI_DNG_HP, aec.output.dng_target[0]); + val = 0; + } + + mc_packet_add_write_ana(MCI_RBSEL, val); + + if (id == MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_cd(MCI_STDPLUGSEL, info.plug_sel << 7); + mc_packet_add_write_ana(18, 0x20); + } else { + mc_packet_add_write_ana(114, ANA_114); + mc_packet_add_write_ana(115, ANA_115); + mc_packet_add_write_cd(MCI_SCKMSKON_R, info.options[1]); + mc_packet_add_write_cd(39, info.options[6]); + } + + mc_packet_add_hsdet(); + + return 0; +} + +void mc_packet_clear(void) +{ + packet_queue[0].desc = MCDRV_PACKET_TYPE_TERMINATE; + packet_terminate = 0; +} + +void mc_packet_add(u32 desc, u8 data) +{ + if (packet_terminate >= MCDRV_MAX_PACKETS) + mc_packet_execute(); + + packet_queue[packet_terminate].desc = desc; + packet_queue[packet_terminate++].data = data; + packet_queue[packet_terminate].desc = MCDRV_PACKET_TYPE_TERMINATE; +} + +int mc_packet_execute(void) +{ + enum mcdrv_update_mode mode; + u32 desc, delay; + int index; + int ret = 0; + + mc_resource_clear(); + + index = 0; + desc = packet_queue[index].desc; + + while (desc != MCDRV_PACKET_TYPE_TERMINATE) { + mode = MCDRV_UPDATE_FORCE; + + switch (desc & MCDRV_PACKET_TYPE_MASK) { + case MCDRV_PACKET_TYPE_WRITE: + mode = MCDRV_UPDATE_NORMAL; + case MCDRV_PACKET_TYPE_FORCE_WRITE: + mc_bus_queue_add(desc & MCDRV_PACKET_REGTYPE_MASK, + desc & MCDRV_PACKET_ADR_MASK, + packet_queue[index].data, mode); + break; + case MCDRV_PACKET_TYPE_TIMWAIT: + mc_bus_queue_flush(); + mc_resource_clear(); + + delay = desc & MCDRV_PACKET_TIME_MASK; + if (delay < 1000) + udelay(delay); + else + msleep(delay / 1000); + break; + case MCDRV_PACKET_TYPE_EVTWAIT: + mc_bus_queue_flush(); + mc_resource_clear(); + ret = mc_wait_event(desc & MCDRV_PACKET_EVT_MASK, + desc & MCDRV_PACKET_EVTPRM_MASK); + break; + default: + ret = -EINVAL; + break; + } + + if (ret) + break; + + desc = packet_queue[++index].desc; + } + + if (!ret) + mc_bus_queue_flush(); + + mc_packet_clear(); + + return ret; +} + +static inline void digital_io_init(void) +{ + struct mcdrv_dev_info info; + struct mcdrv_aec_info aec; + u8 val; + + mc_dev_info_get(&info); + mc_aec_info_get(&aec); + + /* DIO0 */ + if (info.power_mode == MCDRV_POWMODE_CDSPDEBUG + || aec.vbox.cdsp_jtag_on == 1) + val = 0x01; + else { + val = MCI_DO0_DRV_DEF; + if (!info.dio0_sdo_hiz) + val |= MCB_SDO0_DDR; + if (!info.dio0_clk_hiz) + val |= MCB_BCLK0_DDR | MCB_LRCK0_DDR; + } + mc_packet_add_write_a(MCI_DO0_DRV, val); + + /* DIO1 */ + if (info.power_mode == MCDRV_POWMODE_CDSPDEBUG + || aec.vbox.cdsp_jtag_on == 1) + val = 0x22; + else { + val = MCI_DO1_DRV_DEF; + if (!info.dio1_sdo_hiz) + val |= MCB_SDO1_DDR; + if (!info.dio1_clk_hiz) + val |= MCB_BCLK1_DDR | MCB_LRCK1_DDR; + } + mc_packet_add_write_a(MCI_DO1_DRV, val); + + /* DIO2 */ + val = MCI_DO2_DRV_DEF; + if (!info.dio2_sdo_hiz) + val |= MCB_SDO2_DDR; + if (!info.dio2_clk_hiz) + val |= MCB_BCLK2_DDR | MCB_LRCK2_DDR; + mc_packet_add_write_a(MCI_DO2_DRV, val); + + val = aec.pdm.pdm1_data_delay << 5; + val |= aec.pdm.pdm0_data_delay << 4; + if (info.dio0_pcm_hiz) + val |= MCB_PCMOUT0_HIZ; + if (info.dio1_pcm_hiz) + val |= MCB_PCMOUT1_HIZ; + if (info.dio2_pcm_hiz) + val |= MCB_PCMOUT2_HIZ; + mc_packet_add_write_a(MCI_PCMOUT_HIZ, val); +} + +static inline void gpio_init(void) +{ + struct mcdrv_dev_info info; + struct mcdrv_gp_mode gp_mode; + u8 val; + + mc_dev_info_get(&info); + mc_gp_mode_get(&gp_mode); + + val = MCI_PA0_DEF; + if (info.pa0_func == MCDRV_PA_PDMCK) + val |= MCB_PA0_OUT | MCB_PA0_DDR; + else if (info.pa0_func == MCDRV_PA_GPIO) { + if (gp_mode.gp_ddr[MCDRV_GP_PAD0] == MCDRV_GPDDR_IN) + val &= ~MCB_PA0_DDR; + else + val |= MCB_PA0_DDR; + if (gp_mode.gp_host[MCDRV_GP_PAD0] == MCDRV_GPHOST_CPU) + val &= ~MCB_PA0_OUTSEL; + else + val |= MCB_PA0_OUTSEL; + if (gp_mode.gp_invert[MCDRV_GP_PAD0] == MCDRV_GPINV_NORMAL) + val &= ~MCB_PA0_INV; + else + val |= MCB_PA0_INV; + } + if (info.pa0_func == MCDRV_PA_GPIO + && gp_mode.gp_ddr[MCDRV_GP_PAD0] == MCDRV_GPDDR_OUT + && gp_mode.gp_host[MCDRV_GP_PAD0] == MCDRV_GPHOST_CPU) + val |= mc_gp_pad_get(MCDRV_GP_PAD0) << 4; + mc_packet_add_write_a(MCI_PA0, val); + + val = mc_a_register_get_value(MCI_PA1); + if (info.pa1_func == MCDRV_PA_GPIO) { + if (gp_mode.gp_ddr[MCDRV_GP_PAD1] == MCDRV_GPDDR_IN) + val &= ~MCB_PA1_DDR; + else + val |= MCB_PA1_DDR; + if (gp_mode.gp_host[MCDRV_GP_PAD1] == MCDRV_GPHOST_CPU) + val &= ~MCB_PA1_OUTSEL; + else + val |= MCB_PA1_OUTSEL; + if (gp_mode.gp_invert[MCDRV_GP_PAD1] == MCDRV_GPINV_NORMAL) + val &= ~MCB_PA1_INV; + else + val |= MCB_PA1_INV; + } + val |= MCB_PA1_MSK; + if (info.pa1_func == MCDRV_PA_GPIO + && gp_mode.gp_ddr[MCDRV_GP_PAD1] == MCDRV_GPDDR_OUT + && gp_mode.gp_host[MCDRV_GP_PAD1] == MCDRV_GPHOST_CPU) + val |= mc_gp_pad_get(MCDRV_GP_PAD1) << 4; + mc_packet_add_write_a(MCI_PA1, val); + + val = mc_a_register_get_value(MCI_PA2); + if (info.pa2_func == MCDRV_PA_GPIO) { + if (gp_mode.gp_ddr[MCDRV_GP_PAD2] == MCDRV_GPDDR_IN) + val &= ~MCB_PA2_DDR; + else + val |= MCB_PA2_DDR; + if (gp_mode.gp_host[MCDRV_GP_PAD2] == MCDRV_GPHOST_CPU) + val &= ~MCB_PA2_OUTSEL; + else + val |= MCB_PA2_OUTSEL; + if (gp_mode.gp_invert[MCDRV_GP_PAD2] == MCDRV_GPINV_NORMAL) + val &= ~MCB_PA2_INV; + else + val |= MCB_PA2_INV; + } + val |= MCB_PA2_MSK; + if (info.pa2_func == MCDRV_PA_GPIO + && gp_mode.gp_ddr[MCDRV_GP_PAD2] == MCDRV_GPDDR_OUT + && gp_mode.gp_host[MCDRV_GP_PAD2] == MCDRV_GPHOST_CPU) + val |= mc_gp_pad_get(MCDRV_GP_PAD2) << 4; + mc_packet_add_write_a(MCI_PA2, val); +} + +static inline int mblock_init(void) +{ + u32 flags; + int ret; + + if (mc_dev_id_get() != MCDRV_DEV_ID_80_90H) + mc_packet_add_write_ma(MCI_CLK_SEL, mc_clock_select_get()); + + mc_packet_add_digital_io(MCDRV_ALL_DIO_UPDATE_FLAG); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_packet_add_write_a(MCI_LP0_FP, MCDRV_PHYSPORT_NONE); + mc_packet_add_write_a(MCI_LP1_FP, MCDRV_PHYSPORT_NONE); + mc_packet_add_write_a(MCI_LP2_FP, MCDRV_PHYSPORT_NONE); + mc_packet_add_write_a(MCI_LP0_FP, MCDRV_PHYSPORT_NONE); + mc_packet_add_digital_io_path(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + flags = MCDRV_SWAP_ALL_UPDATE_FLAG & ~MCDRV_SWAP_HIFIOUT_UPDATE_FLAG; + mc_packet_add_swap(flags); + return mc_packet_execute(); +} + +static void e_registers_setup(void) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dev_info info; + enum mcdrv_dev_id id; + u8 val, val1, val2; + u8 sys_eq[2][45]; + int i; + + mc_dev_info_get(&info); + + val = mc_if_register_get_value(MCI_RST); + if (val & (MCB_PSW_M | MCB_RST_M)) + return; + + val = mc_a_register_get_value(MCI_PD); + if (val & MCB_PE_CLK_PD) + return; + + mc_aec_info_get(&aec); + + id = mc_dev_id_get(); + if (id != MCDRV_DEV_ID_80_90H) + mc_packet_add_write_e(MCI_ECLK_SEL, mc_e_clock_select_get()); + + val = mc_e_register_get_value(MCI_LPF_THR); + val &= (MCB_OSF1_MN | MCB_OSF0_MN | MCB_OSF1_ENB | MCB_OSF0_ENB); + val |= aec.output.lpf_post_thru[1] << 7 + | aec.output.lpf_post_thru[0] << 6 + | aec.output.lpf_pre_thru[1] << 5 | aec.output.lpf_pre_thru[0] << 4; + mc_packet_add_write_e(MCI_LPF_THR, val); + + val = aec.output.dcc_sel[1] << 2 | aec.output.dcc_sel[0]; + mc_packet_add_write_e(MCI_DAC_DCC_SEL, val); + + val = aec.output.power_detect_level[1] << 6 + | aec.output.power_detect_level[0] << 4 + | aec.output.signal_detect_level; + mc_packet_add_write_e(MCI_DET_LVL, val); + + val = aec.output.osf_sel[1] << 2 | aec.output.osf_sel[0]; + mc_packet_add_write_e(MCI_OSF_SEL, val); + + for (i = 0; i < MCDRV_AEC_OUTPUT_N; i++) { + memcpy(&sys_eq[i][0], aec.output.syseq_coef_a0[i], 3); + memcpy(&sys_eq[i][3], aec.output.syseq_coef_a1[i], 3); + memcpy(&sys_eq[i][6], aec.output.syseq_coef_a2[i], 3); + memcpy(&sys_eq[i][9], aec.output.syseq_coef_b1[i], 3); + memcpy(&sys_eq[i][12], aec.output.syseq_coef_b2[i], 3); + memcpy(aec.output.syseq_ex[i].band[0].coef_a0, &sys_eq[i][15], + 3); + memcpy(aec.output.syseq_ex[i].band[0].coef_a1, &sys_eq[i][18], + 3); + memcpy(aec.output.syseq_ex[i].band[0].coef_a2, &sys_eq[i][21], + 3); + memcpy(aec.output.syseq_ex[i].band[0].coef_b1, &sys_eq[i][24], + 3); + memcpy(aec.output.syseq_ex[i].band[0].coef_b2, &sys_eq[i][27], + 3); + memcpy(aec.output.syseq_ex[i].band[1].coef_a0, &sys_eq[i][30], + 3); + memcpy(aec.output.syseq_ex[i].band[1].coef_a1, &sys_eq[i][33], + 3); + memcpy(aec.output.syseq_ex[i].band[1].coef_a2, &sys_eq[i][36], + 3); + memcpy(aec.output.syseq_ex[i].band[1].coef_b1, &sys_eq[i][39], + 3); + memcpy(aec.output.syseq_ex[i].band[1].coef_b2, &sys_eq[i][42], + 3); + } + + if (id == MCDRV_DEV_ID_80_90H) + val = aec.output.syseq_enb[1] << 1; + else + val = aec.output.syseq_enb[1] << 4; + val |= aec.output.syseq_enb[0]; + mc_edsp_e1_download(sys_eq[0], sys_eq[1], val); + mc_packet_add_write_e(MCI_SYSEQ, val); + + val = mc_ana_register_get_value(MCI_NONCLIP); + if (aec.output.clip_md[1] & 0x6) + val |= 1 << 7; + else + val &= 0x7f; + mc_packet_add_write_ana(MCI_NONCLIP, val); + mc_packet_add_write_e(MCI_CLIP_MD, aec.output.clip_md[1]); + mc_packet_add_write_e(MCI_CLIP_ATT, aec.output.clip_att[1]); + mc_packet_add_write_e(MCI_CLIP_REL, aec.output.clip_rel[1]); + mc_packet_add_write_e(MCI_CLIP_G, aec.output.clip_g[1]); + + val1 = mc_e_register_get_value(MCI_OSF_GAIN0_15_8); + val2 = mc_e_register_get_value(MCI_OSF_GAIN0_7_0); + if (val1 != aec.output.osf_gain[0][0] || + val2 != aec.output.osf_gain[0][1]) { + mc_packet_add_force_write_e(MCI_OSF_GAIN0_15_8, + aec.output.osf_gain[0][0]); + mc_packet_add_force_write_e(MCI_OSF_GAIN0_7_0, + aec.output.osf_gain[0][1]); + } + + val1 = mc_e_register_get_value(MCI_OSF_GAIN1_15_8); + val2 = mc_e_register_get_value(MCI_OSF_GAIN1_7_0); + if (val1 != aec.output.osf_gain[1][0] || + val2 != aec.output.osf_gain[1][1]) { + mc_packet_add_force_write_e(MCI_OSF_GAIN1_15_8, + aec.output.osf_gain[1][0]); + mc_packet_add_force_write_e(MCI_OSF_GAIN1_7_0, + aec.output.osf_gain[1][1]); + } + + val = aec.output.dcl_on[1] << 7 | aec.output.dcl_gain[1] << 4 + | aec.output.dcl_on[0] << 3 | aec.output.dcl_gain[0]; + mc_packet_add_write_e(MCI_DCL_GAIN, val); + + val1 = mc_e_register_get_value(MCI_DCL0_LMT_14_8); + val2 = mc_e_register_get_value(MCI_DCL0_LMT_7_0); + if (val1 != aec.output.dcl_limit[0][0] || + val2 != aec.output.dcl_limit[0][1]) { + mc_packet_add_force_write_e(MCI_DCL0_LMT_14_8, + aec.output.dcl_limit[0][0]); + mc_packet_add_force_write_e(MCI_DCL0_LMT_7_0, + aec.output.dcl_limit[0][1]); + } + + val1 = mc_e_register_get_value(MCI_DCL0_LMT_14_8); + val2 = mc_e_register_get_value(MCI_DCL0_LMT_7_0); + if (val1 != aec.output.dcl_limit[1][0] || + val2 != aec.output.dcl_limit[1][1]) { + mc_packet_add_force_write_e(MCI_DCL1_LMT_14_8, + aec.output.dcl_limit[1][0]); + mc_packet_add_force_write_e(MCI_DCL1_LMT_7_0, + aec.output.dcl_limit[1][1]); + } + + if (id == MCDRV_DEV_ID_80_90H) { + val = aec.output.dc_dither_level[0] << 4 + | aec.output.random_dither_on[0] << 3 + | aec.output.random_dither_pos[0] << 2 + | aec.output.random_dither_level[0]; + mc_packet_add_write_e(MCI_DITHER0, val); + + val = aec.output.dc_dither_level[1] << 4 + | aec.output.random_dither_on[1] << 3 + | aec.output.random_dither_pos[1] << 2 + | aec.output.random_dither_level[1]; + mc_packet_add_write_e(MCI_DITHER1, val); + } else { + mc_packet_add_write_e(MCI_DITHER0, info.options[4]); + mc_packet_add_write_e(MCI_DITHER1, info.options[5]); + } + + val = aec.output.dng_fw[0] << 7 | aec.output.dng_time[0] << 5 + | aec.output.dng_zero[0]; + val1 = aec.output.dng_fw[1] << 7 | aec.output.dng_time[1] << 5 + | aec.output.dng_zero[1]; + val2 = aec.output.dng_on[1] << 1 | aec.output.dng_on[0]; + if (id == MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_e(MCI_DNG0_ES1, val); + mc_packet_add_write_e(MCI_DNG1_ES1, val1); + mc_packet_add_write_e(MCI_DNG_ON_ES1, val2); + } else { + mc_packet_add_write_e(MCI_DNG0, val); + mc_packet_add_write_e(MCI_DNG1, val1); + mc_packet_add_write_e(MCI_DNG_ON, val2); + } + + mc_packet_add_write_e(MCI_ADJ_HOLD, aec.adj.hold); + mc_packet_add_write_e(MCI_ADJ_CNT, aec.adj.cnt); + + val1 = mc_e_register_get_value(MCI_ADJ_MAX_15_8); + val2 = mc_e_register_get_value(MCI_ADJ_MAX_7_0); + if (val1 != aec.adj.max[0] || val2 != aec.adj.max[1]) { + mc_packet_add_force_write_e(MCI_ADJ_MAX_15_8, aec.adj.max[0]); + mc_packet_add_force_write_e(MCI_ADJ_MAX_7_0, aec.adj.max[1]); + } + + val = aec.output.dither_type[1] << 5 | aec.output.dither_type[0] << 4; + mc_packet_add_write_e(40, val); + + val = mc_e_register_get_value(MCI_DSF0_FLT_TYPE); + val &= MCB_DSF0_MN | MCB_DSF0ENB; + val |= aec.input.dsf32_r_type[0] << 6 | aec.input.dsf32_l_type[0] << 4; + mc_packet_add_write_e(MCI_DSF0_FLT_TYPE, val); + + val = mc_e_register_get_value(MCI_DSF1_FLT_TYPE); + val &= MCB_DSF1_MN | MCB_DSF1ENB; + val |= aec.input.dsf32_r_type[1] << 6 | aec.input.dsf32_l_type[1] << 4; + mc_packet_add_write_e(MCI_DSF1_FLT_TYPE, val); + + val = mc_e_register_get_value(MCI_DSF2_FLT_TYPE); + val &= MCB_DSF2REFSEL | MCB_DSF2REFBACK | MCB_DSF2_MN | MCB_DSF2ENB; + val |= aec.input.dsf32_r_type[2] << 6 | aec.input.dsf32_l_type[2] << 4; + mc_packet_add_write_e(MCI_DSF2_FLT_TYPE, val); + + val = aec.input.dsf4_sel[2] << 2 | aec.input.dsf4_sel[1] << 1 + | aec.input.dsf4_sel[0]; + mc_packet_add_write_e(MCI_DSF_SEL, val); + + val = aec.input.dcc_sel[2] << 4 | aec.input.dcc_sel[1] << 2 + | aec.input.dcc_sel[0]; + mc_packet_add_write_e(MCI_ADC_DCC_SEL, val); + + val = aec.input.dng_on[2] << 2 | aec.input.dng_on[1] << 1 + | aec.input.dng_on[0]; + mc_packet_add_write_e(MCI_ADC_DNG_ON, val); + + val = aec.input.dng_fw[0] << 4 | aec.input.dng_rel[0] << 2 + | aec.input.dng_att[0]; + mc_packet_add_write_e(MCI_ADC_DNG0_FW, val); + mc_packet_add_write_e(MCI_ADC_DNG0_TIM, aec.input.dng_time[0]); + + val1 = mc_e_register_get_value(MCI_ADC_DNG0_ZERO_15_8); + val2 = mc_e_register_get_value(MCI_ADC_DNG0_ZERO_7_0); + if (val1 != aec.input.dng_zero[0][0] || + val2 != aec.input.dng_zero[0][1]) { + mc_packet_add_force_write_e(MCI_ADC_DNG0_ZERO_15_8, + aec.input.dng_zero[0][0]); + mc_packet_add_force_write_e(MCI_ADC_DNG0_ZERO_7_0, + aec.input.dng_zero[0][1]); + } + + val1 = mc_e_register_get_value(MCI_ADC_DNG0_ZERO_15_8); + val2 = mc_e_register_get_value(MCI_ADC_DNG0_ZERO_7_0); + if (val1 != aec.input.dng_target[0][0] || + val2 != aec.input.dng_target[0][1]) { + mc_packet_add_force_write_e(MCI_ADC_DNG0_TGT_15_8, + aec.input.dng_target[0][0]); + mc_packet_add_force_write_e(MCI_ADC_DNG0_TGT_7_0, + aec.input.dng_target[0][1]); + } + + val = aec.input.dng_fw[1] << 4 | aec.input.dng_rel[1] << 2 + | aec.input.dng_att[1]; + mc_packet_add_write_e(MCI_ADC_DNG1_FW, val); + mc_packet_add_write_e(MCI_ADC_DNG1_TIM, aec.input.dng_time[1]); + + val1 = mc_e_register_get_value(MCI_ADC_DNG1_ZERO_15_8); + val2 = mc_e_register_get_value(MCI_ADC_DNG1_ZERO_7_0); + if (val1 != aec.input.dng_zero[1][0] || + val2 != aec.input.dng_zero[1][1]) { + mc_packet_add_force_write_e(MCI_ADC_DNG1_ZERO_15_8, + aec.input.dng_zero[1][0]); + mc_packet_add_force_write_e(MCI_ADC_DNG1_ZERO_7_0, + aec.input.dng_zero[1][1]); + } + + val1 = mc_e_register_get_value(MCI_ADC_DNG1_ZERO_15_8); + val2 = mc_e_register_get_value(MCI_ADC_DNG1_ZERO_7_0); + if (val1 != aec.input.dng_target[1][0] || + val2 != aec.input.dng_target[1][1]) { + mc_packet_add_force_write_e(MCI_ADC_DNG1_TGT_15_8, + aec.input.dng_target[1][0]); + mc_packet_add_force_write_e(MCI_ADC_DNG1_TGT_7_0, + aec.input.dng_target[1][1]); + } + + val = aec.input.dng_fw[2] << 4 | aec.input.dng_rel[2] << 2 + | aec.input.dng_att[2]; + mc_packet_add_write_e(MCI_ADC_DNG2_FW, val); + mc_packet_add_write_e(MCI_ADC_DNG2_TIM, aec.input.dng_time[2]); + + val1 = mc_e_register_get_value(MCI_ADC_DNG2_ZERO_15_8); + val2 = mc_e_register_get_value(MCI_ADC_DNG2_ZERO_7_0); + if (val1 != aec.input.dng_zero[2][0] || + val2 != aec.input.dng_zero[2][1]) { + + mc_packet_add_force_write_e(MCI_ADC_DNG2_ZERO_15_8, + aec.input.dng_zero[2][0]); + mc_packet_add_force_write_e(MCI_ADC_DNG2_ZERO_7_0, + aec.input.dng_zero[2][1]); + } + + val1 = mc_e_register_get_value(MCI_ADC_DNG2_TGT_15_8); + val2 = mc_e_register_get_value(MCI_ADC_DNG2_TGT_7_0); + if (val1 != aec.input.dng_target[2][0] || + val2 != aec.input.dng_target[2][1]) { + mc_packet_add_force_write_e(MCI_ADC_DNG2_TGT_15_8, + aec.input.dng_target[2][0]); + mc_packet_add_force_write_e(MCI_ADC_DNG2_TGT_7_0, + aec.input.dng_target[2][1]); + } + + val = aec.input.depop_wait[0] << 2 | aec.input.depop_att[0]; + mc_packet_add_write_e(MCI_DEPOP0, val); + + val = aec.input.depop_wait[1] << 2 | aec.input.depop_att[1]; + mc_packet_add_write_e(MCI_DEPOP1, val); + + val = aec.input.depop_wait[2] << 2 | aec.input.depop_att[2]; + mc_packet_add_write_e(MCI_DEPOP2, val); + + val = aec.pdm.st_wait << 2 | aec.pdm.mode; + mc_packet_add_write_e(MCI_PDM_MODE, val); + + val = mc_e_register_get_value(MCI_PDM_LOAD_TIM); + val &= MCB_PDM1_START | MCB_PDM0_START; + val |= aec.pdm.pdm1_loadtime << 4 | aec.pdm.pdm0_loadtime; + mc_packet_add_write_e(MCI_PDM_LOAD_TIM, val); + mc_packet_add_write_e(MCI_PDM0L_FINE_DLY, aec.pdm.pdm0_l_finedelay); + mc_packet_add_write_e(MCI_PDM0R_FINE_DLY, aec.pdm.pdm0_r_finedelay); + mc_packet_add_write_e(MCI_PDM1L_FINE_DLY, aec.pdm.pdm1_l_finedelay); + mc_packet_add_write_e(MCI_PDM1R_FINE_DLY, aec.pdm.pdm1_r_finedelay); + + val = aec.edsp_misc.ch_sel << 6 | aec.edsp_misc.i2s_out_enable << 5 + | aec.edsp_misc.loopback; + mc_packet_add_write_e(MCI_CH_SEL, val); + + val = aec.e2.da_sel << 3 | aec.e2.ad_sel; + mc_packet_add_write_e(MCI_E2_SEL, val); + + if (id != MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_e(99, E_99); + mc_packet_add_write_e(100, E_100); + } +} + +static int offset_cancel(void) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dev_info info; + enum mcdrv_dev_id id; + u8 val, val1, val2, e_irq_hs; + u8 data[2]; + int ret = 0; + + id = mc_dev_id_get(); + mc_dev_info_get(&info); + mc_aec_info_get(&aec); + + mc_packet_add_force_write_e(MCI_E1DSP_CTRL, 0); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_packet_add_force_write_e(MCI_LPF_THR, + MCI_LPF_THR_DEF | MCB_OSF1_ENB | + MCB_OSF0_ENB); + + mc_packet_add_wait(MCDRV_DP_DAC_WAIT_TIME); + + mc_packet_add_write_cd(MCI_DP, 0); + mc_packet_add_force_write_e(MCI_DSF0_FLT_TYPE, MCB_DSF0ENB); + + e_irq_hs = mc_cd_register_get_value(MCI_IRQHS); + mc_packet_add_write_cd(MCI_IRQHS, 0); + + if (id == MCDRV_DEV_ID_80_90H) { + val = aec.output.dc_dither_level[0] << 4 + | aec.output.random_dither_on[0] << 3 + | aec.output.random_dither_pos[0] << 2 + | aec.output.random_dither_level[0]; + mc_packet_add_write_e(MCI_DITHER0, val); + + val = aec.output.dc_dither_level[1] << 4 + | aec.output.random_dither_on[1] << 3 + | aec.output.random_dither_pos[1] << 2 + | aec.output.random_dither_level[1]; + mc_packet_add_write_e(MCI_DITHER1, val); + } + + val = aec.output.dither_type[1] << 5 | aec.output.dither_type[0] << 4; + mc_packet_add_write_e(40, val); + + mc_packet_add_write_e(MCI_ADJ_HOLD, aec.adj.hold); + mc_packet_add_write_e(MCI_ADJ_CNT, aec.adj.cnt); + + val1 = mc_e_register_get_value(MCI_ADJ_MAX_15_8); + val2 = mc_e_register_get_value(MCI_ADJ_MAX_7_0); + if (val1 != aec.adj.max[0] || val2 != aec.adj.max[1]) { + mc_packet_add_force_write_e(MCI_ADJ_MAX_15_8, aec.adj.max[0]); + mc_packet_add_force_write_e(MCI_ADJ_MAX_7_0, aec.adj.max[1]); + } + + if (id == MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_ana(22, CP_88OFF << 1); + + if (mc_source_is_used(MCDRV_DST_HP, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_HP, MCDRV_DST_CH1)) + mc_packet_add_write_ana(19, OP_DAC_HP); + else + mc_packet_add_write_ana(19, OP_DAC); + + mc_packet_add_write_ana(17, (HP_IBST << 1) | HP_MIDBST); + mc_packet_add_force_write_ana(15, HP_IDLE << 5); + mc_packet_add_write_cd(39, CD_39); + + mc_packet_add_force_write_if(31, 0xb5); + mc_packet_add_force_write_if(30, 0xd6); + mc_packet_add_force_write_ana(78, T_CPMODE_OFFCAN_BEFORE); + } else { + mc_packet_add_write_ana(22, CP_88OFF << 1); + mc_packet_add_write_ana(19, info.options[7]); + mc_packet_add_write_ana(62, info.options[8]); + } + + mc_packet_add_force_write_e(MCI_E1COMMAND, E1COMMAND_OFFSET_CANCEL); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + if (id == MCDRV_DEV_ID_80_90H) { + data[0] = MCI_ANA_REG_A << 1; + data[1] = 78; + mc_write_analog(data, 2); + mc_read_analog(MCI_ANA_REG_D, &val, 1); + if (val != T_CPMODE_OFFCAN_BEFORE) + return -EIO; + } + + mc_packet_add_wait_event(MCDRV_EVT_OFFCAN_BSY_RESET); + mc_packet_add_force_write_cd(MCI_SSENSEFIN, MCB_SOFFCANFIN); + + mc_packet_add_force_write_e(MCI_DSF0_FLT_TYPE, 0); + mc_packet_add_write_cd(MCI_IRQHS, e_irq_hs); + + if (id == MCDRV_DEV_ID_80_90H) + mc_packet_add_force_write_ana(78, T_CPMODE_OFFCAN_AFTER); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + if (id == MCDRV_DEV_ID_80_90H) { + data[0] = MCI_ANA_REG_A << 1; + data[1] = 78; + mc_write_analog(data, 2); + mc_read_analog(MCI_ANA_REG_D, &val, 1); + if (val != T_CPMODE_OFFCAN_AFTER) + ret = -EIO; + } + + return ret; +} + +static inline void add_dac_start(void) +{ + u8 val, osf0 = 0, osf1 = 0; + + val = mc_e_register_get_value(MCI_LPF_THR); + osf0 = val & (MCB_OSF0_MN | MCB_OSF0_ENB); + if (mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0)) + osf0 = MCB_OSF0_ENB | MCB_OSF0_MN; + if (mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1)) + osf0 = MCB_OSF0_ENB; + + osf1 = val & (MCB_OSF1_MN | MCB_OSF1_ENB); + if (mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0)) + osf1 = MCB_OSF1_ENB | MCB_OSF1_MN; + if (mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) + osf1 = MCB_OSF1_ENB; + + val &= MCB_LPF_ALL_THR; + val |= osf1 | osf0; + mc_packet_add_write_e(MCI_LPF_THR, val); +} + +static inline u32 get_max_wait(u8 reg_change) +{ + struct mcdrv_dev_info info; + u32 wait_time_max = 0; + + mc_dev_info_get(&info); + + if ((reg_change & MCB_MC1) || (reg_change & MCB_MB1)) + if (info.wait_time.wait[0] > wait_time_max) + wait_time_max = info.wait_time.wait[0]; + + if ((reg_change & MCB_MC2) || (reg_change & MCB_MB2)) + if (info.wait_time.wait[1] > wait_time_max) + wait_time_max = info.wait_time.wait[1]; + + if ((reg_change & MCB_MC3) || (reg_change & MCB_MB3)) + if (info.wait_time.wait[2] > wait_time_max) + wait_time_max = info.wait_time.wait[2]; + + if ((reg_change & MCB_MC4) || (reg_change & MCB_MB4)) + if (info.wait_time.wait[3] > wait_time_max) + wait_time_max = info.wait_time.wait[3]; + + return wait_time_max; +} + +int mc_packet_add_powerup(struct mcdrv_power_info *power_info, + struct mcdrv_power_update *power_update) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dev_info info; + enum mcdrv_dev_id id; + u32 wait_time; + u8 val, ap, rst_reg, psw, rst, d_update, clock, reg_change; + u8 new_pd, org_pd, new_da0, new_da1, org_da0, org_da1; + u8 ofc = 0; + int ret = 0; + + id = mc_dev_id_get(); + mc_aec_info_get(&aec); + mc_dev_info_get(&info); + mc_clock_get(&clock); + + rst_reg = mc_if_register_get_value(MCI_RST); + psw = rst_reg & (MCB_PSW_M | MCB_PSW_F | MCB_PSW_C); + rst = rst_reg & (MCB_RST_M | MCB_RST_F | MCB_RST_C); + + org_pd = mc_a_register_get_value(MCI_PD); + new_pd = org_pd; + + d_update = ~power_info->digital & power_update->digital; + + ap = mc_ana_register_get_value(MCI_AP); + + org_da0 = mc_ana_register_get_value(MCI_AP_DA0); + org_da1 = mc_ana_register_get_value(MCI_AP_DA1); + + new_da0 = ~(org_da0 & power_update->analog[1]); + new_da0 |= power_info->analog[1]; + new_da0 &= org_da0; + + new_da1 = ~(org_da1 & power_update->analog[2]); + new_da1 |= power_info->analog[2]; + new_da1 &= org_da1; + + if ((d_update & MCDRV_POWINFO_D_PLL_PD) && (org_pd & MCB_PLL_PD)) { + if (ap & MCB_AP_LDOD) { + ap &= ~(MCB_AP_LDOD | MCB_AP_BGR); + mc_packet_add_write_ana(MCI_AP, ap); + mc_packet_add_wait(MCDRV_LDO_WAIT_TIME); + } + + mc_packet_add_force_write_if(MCI_RST_A, MCI_RST_A_DEF); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_packet_add_force_write_if(MCI_RST_A, + MCI_RST_A_DEF & ~MCB_RST_A); + + mc_a_registers_init(); + + if (info.power_mode == MCDRV_POWMODE_CDSPDEBUG + || aec.vbox.cdsp_jtag_on == 1) + mc_packet_add_write_a(MCI_JTAGSEL, MCB_JTAGSEL); + + digital_io_init(); + gpio_init(); + + mc_packet_add_write_a(MCI_CK_TCX0, info.clk_sel); + + mc_packet_add_write_a(MCI_PLL_MODE_A, info.pll_mode_a); + mc_packet_add_write_a(MCI_PLL_PREDIV_A, info.pll_prev_div_a); + mc_packet_add_write_a(MCI_PLL_FBDIV_A_12_8, + info.pll_fb_div_a >> 8); + mc_packet_add_write_a(MCI_PLL_FBDIV_A_7_0, + info.pll_fb_div_a & 0xff); + mc_packet_add_write_a(MCI_PLL_FRAC_A_15_8, + info.pll_frac_a >> 8); + mc_packet_add_write_a(MCI_PLL_FRAC_A_7_0, + info.pll_frac_a & 0xff); + mc_packet_add_write_a(MCI_PLL_FOUT_A, info.pll_freq_a << 1); + + mc_packet_add_write_a(MCI_PLL_MODE_B, info.pll_mode_b); + mc_packet_add_write_a(MCI_PLL_PREDIV_B, info.pll_prev_div_b); + mc_packet_add_write_a(MCI_PLL_FBDIV_B_12_8, + info.pll_fb_div_b >> 8); + mc_packet_add_write_a(MCI_PLL_FBDIV_B_7_0, + info.pll_fb_div_b & 0xff); + mc_packet_add_write_a(MCI_PLL_FRAC_B_15_8, + info.pll_frac_b >> 8); + mc_packet_add_write_a(MCI_PLL_FRAC_B_7_0, + info.pll_frac_b & 0xff); + mc_packet_add_write_a(MCI_PLL_FOUT_B, info.pll_freq_b << 1); + + val = mc_a_register_get_value(MCI_FREQ73M); + val &= 0xcf; + if (clock == MCDRV_CLKSW_CLKA) + val |= info.pll_freq_a << 4; + else + val |= info.pll_freq_b << 4; + mc_packet_add_write_a(MCI_FREQ73M, val); + + val = info.clk_input; + if (clock == MCDRV_CLKSW_CLKB) + val |= MCB_CLK_INPUT; + mc_packet_add_write_a(MCI_CLKSRC, val); + + if (id != MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_a(MCI_DOA_DRV, + info.options[0] << 7); + mc_packet_add_write_a(MCI_SCKMSKON_B, info.options[1]); + } + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + val = MCI_CLK_MSK_DEF; + if (clock == MCDRV_CLKSW_CLKA) { + if (info.clk_input == MCDRV_CKINPUT_CLKI0_CLKI1 + || info.clk_input == MCDRV_CKINPUT_CLKI0_RTCK + || info.clk_input == MCDRV_CKINPUT_CLKI0_SBCK) + val &= ~MCB_CLKI0_MSK; + else if (info.clk_input == MCDRV_CKINPUT_CLKI1_CLKI0 + || info.clk_input == MCDRV_CKINPUT_CLKI1_RTCK + || info.clk_input == MCDRV_CKINPUT_CLKI1_SBCK) + val &= ~MCB_CLKI1_MSK; + else + val &= ~MCB_RTCI_MSK; + } else { + if (info.clk_input == MCDRV_CKINPUT_CLKI1_CLKI0 + || info.clk_input == MCDRV_CKINPUT_RTC_CLKI0 + || info.clk_input == MCDRV_CKINPUT_SBCK_CLKI0) + val &= ~MCB_CLKI0_MSK; + else if (info.clk_input == MCDRV_CKINPUT_CLKI0_CLKI1 + || info.clk_input == MCDRV_CKINPUT_RTC_CLKI1 + || info.clk_input == MCDRV_CKINPUT_SBCK_CLKI1) + val &= ~MCB_CLKI1_MSK; + else + val &= ~MCB_RTCI_MSK; + } + mc_packet_add_write_a(MCI_CLK_MSK, val); + + if (!(val & MCB_CLKI0_MSK)) { + if (info.clk_sel == MCDRV_CKSEL_TCXO_TCXO + || info.clk_sel == MCDRV_CKSEL_TCXO_CMOS) + mc_packet_add_wait(MCDRV_TCXO_WAIT_TIME); + } else if ((val & MCB_CLKI1_MSK) == 0) { + if (info.clk_sel == MCDRV_CKSEL_TCXO_TCXO + || info.clk_sel == MCDRV_CKSEL_CMOS_TCXO) + mc_packet_add_wait(MCDRV_TCXO_WAIT_TIME); + } + + if (!(val & MCB_RTCI_MSK)) { + val = mc_cd_register_get_value(MCI_CKSEL); + if (id == MCDRV_DEV_ID_80_90H) + val &= ~MCB_HSDET; + else + val &= ~MCB_CRTC; + mc_packet_add_write_cd(MCI_CKSEL, val); + } + + new_pd &= ~MCB_PLL_PD; + mc_packet_add_write_a(MCI_PD, new_pd); + + mc_packet_add_wait(MCDRV_PLL_WAIT_TIME); + + new_pd &= ~MCB_VCOOUT_PD; + mc_packet_add_write_a(MCI_PD, new_pd); + + mc_packet_add_force_write_if(MCI_IRQ, MCB_EIRQ); + + ofc = 1; + } + + if (((power_update->analog[0] & MCB_AP_LDOA) + && !(power_info->analog[0] & MCB_AP_LDOA)) || ofc == 1) { + new_pd &= ~MCB_ANACLK_PD; + mc_packet_add_write_a(MCI_PD, new_pd); + } + + if (ofc) { + if (id == MCDRV_DEV_ID_80_90H) { + if (mc_source_is_used(MCDRV_DST_HP, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_HP, MCDRV_DST_CH1)) + mc_packet_add_write_ana(19, OP_DAC_HP); + else + mc_packet_add_write_ana(19, OP_DAC); + } + } + + if (ap & MCB_AP_VR) { + if (((power_update->analog[0] & MCB_AP_LDOA) + && !(power_info->analog[0] & MCB_AP_LDOA)) || ofc) { + if (id == MCDRV_DEV_ID_80_90H) { + ap &= ~MCB_AP_VR; + mc_packet_add_write_ana(MCI_AP, ap); + + mc_packet_add_wait(MCDRV_VREF_WAIT_TIME_ES1); + + ap &= ~(MCB_AP_LDOA | MCB_AP_BGR); + mc_packet_add_write_ana(MCI_AP, ap); + + mc_packet_add_wait(MCDRV_LDO_WAIT_TIME); + } else { + ap &= ~MCB_AP_BGR; + mc_packet_add_write_ana(MCI_AP, ap); + + ap &= ~MCB_AP_LDOA; + mc_packet_add_write_ana(MCI_AP, ap); + + mc_packet_add_wait(MCDRV_LDO_WAIT_TIME); + + mc_packet_add_write_ana(62, 0x20); + + ap &= ~MCB_AP_VR; + mc_packet_add_write_ana(MCI_AP, ap); + + mc_packet_add_wait(info.wait_time.wait[6]); + + mc_packet_add_write_ana(62, 0); + } + } + } + + if (((d_update & MCDRV_POWINFO_D_PM_CLK_PD) && (new_pd & MCB_PM_CLK_PD)) + || ofc) { + psw &= ~MCB_PSW_M; + rst &= ~MCB_RST_M; + new_pd &= ~MCB_PM_CLK_PD; + mc_mblock_registers_init(); + } + + if ((d_update & MCDRV_POWINFO_D_PB_CLK_PD) && (new_pd & MCB_PB_CLK_PD)) + new_pd &= ~MCB_PB_CLK_PD; + + if (((d_update & MCDRV_POWINFO_D_PE_CLK_PD) && (new_pd & MCB_PE_CLK_PD)) + || ofc) { + new_pd &= ~MCB_PE_CLK_PD; + mc_e_registers_init(); + } + + if ((d_update & MCDRV_POWINFO_D_PF_CLK_PD) + && (new_pd & MCB_PF_CLK_PD)) { + psw &= ~MCB_PSW_F; + rst &= ~MCB_RST_F; + new_pd &= ~MCB_PF_CLK_PD; + } + + if ((d_update & MCDRV_POWINFO_D_PC_CLK_PD) + && (new_pd & MCB_PC_CLK_PD)) { + psw &= ~MCB_PSW_C; + rst &= ~MCB_RST_C; + new_pd &= ~MCB_PC_CLK_PD; + } + + rst_reg &= ~(MCB_PSW_M | MCB_PSW_F | MCB_PSW_C); + rst_reg |= psw; + mc_packet_add_write_if(MCI_RST, rst_reg); + + if (!(ap & MCB_AP_LDOD)) + mc_packet_add_wait_event(MCDRV_EVT_PSW_RESET | (MCI_RST << 8) | + (~psw & + (MCB_PSW_M | MCB_PSW_F | MCB_PSW_C))); + + rst_reg &= ~(MCB_RST_M | MCB_RST_F | MCB_RST_C); + rst_reg |= rst; + mc_packet_add_write_if(MCI_RST, rst_reg); + mc_packet_add_write_a(MCI_PD, new_pd); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + if ((d_update & MCDRV_POWINFO_D_PM_CLK_PD) + && (org_pd & MCB_PM_CLK_PD) && !(new_pd & MCB_PM_CLK_PD)) + mblock_init(); + + if ((d_update & MCDRV_POWINFO_D_PB_CLK_PD) + && (org_pd & MCB_PB_CLK_PD) && !(new_pd & MCB_PB_CLK_PD)) { + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_bdsp_init(); + } + + if (ofc || ((d_update & MCDRV_POWINFO_D_PE_CLK_PD) + && (org_pd & MCB_PE_CLK_PD) && !(new_pd & MCB_PE_CLK_PD))) { + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_edsp_init(); + e_registers_setup(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + if (ofc) { + ret = offset_cancel(); + if (ret < 0) + return ret; + + e_registers_setup(); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + } + } + + if ((d_update & MCDRV_POWINFO_D_PF_CLK_PD) + && (org_pd & MCB_PF_CLK_PD) && !(new_pd & MCB_PF_CLK_PD)) { + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_fdsp_init(aec.fdsp_locate, info.wait_time.wait[5]); + + val = MCB_IESERR | MCB_IEAMTBEG | MCB_IEAMTEND | MCB_IEFW; + mc_packet_add_force_write_if(MCI_IESERR, val); + } + + if ((d_update & MCDRV_POWINFO_D_PC_CLK_PD) + && (org_pd & MCB_PC_CLK_PD) && !(new_pd & MCB_PC_CLK_PD)) { + if (aec.vbox.cdsp_jtag_on == 1) + mc_packet_add_write_a(MCI_JTAGSEL, MCB_JTAGSEL); + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_cdsp_init(); + + val = MCB_ECDSP | MCB_EFFIFO | MCB_ERFIFO | MCB_EEFIFO + | MCB_EOFIFO | MCB_EDFIFO | MCB_EENC | MCB_EDEC; + mc_packet_add_force_write_if(MCI_ECDSP, val); + } + + add_dac_start(); + + if (!ofc) { + val = mc_cd_register_get_value(MCI_DP); + if (power_update->analog[1] & (MCB_AP_DA0R | MCB_AP_DA0L)) { + if (!(power_info->analog[1] & MCB_AP_DA0R) + || !(power_info->analog[1] & MCB_AP_DA0L)) { + val &= ~(MCB_DP_DAC1 | MCB_DP_DAC0 | + MCB_DP_PDMCK | MCB_DP_PDMDAC); + if (id == MCDRV_DEV_ID_80_90H) + val |= MCB_DP_DAC1; + } + } + + if (power_update->analog[1] & (MCB_AP_DA1R | MCB_AP_DA1L)) + if (!(power_info->analog[2] & MCB_AP_DA1R) + || !(power_info->analog[2] & MCB_AP_DA1L)) + val &= ~(MCB_DP_DAC1 | MCB_DP_PDMCK | + MCB_DP_PDMDAC); + if (power_update->analog[4] & + (MCB_AP_ADM | MCB_AP_ADR | MCB_AP_ADL)) + if (!(power_info->analog[4] & MCB_AP_ADM) + || !(power_info->analog[4] & MCB_AP_ADR) + || !(power_info->analog[4] & MCB_AP_ADL)) + val &= ~(MCB_DP_ADC | MCB_DP_PDMCK | + MCB_DP_PDMADC); + if ((new_da1 & + (MCB_AP_SPR2 | MCB_AP_SPR1 | MCB_AP_SPL2 | MCB_AP_SPL1)) + != (MCB_AP_SPR2 | MCB_AP_SPR1 | MCB_AP_SPL2 | MCB_AP_SPL1)) + val &= ~(MCB_DP_ADC | MCB_DP_PDMADC); + mc_packet_add_write_cd(MCI_DP, val); + } + + val = mc_ana_register_get_value(MCI_AP_MIC); + reg_change = ~(val & power_update->analog[3]); + reg_change |= power_info->analog[3]; + reg_change &= val; + mc_packet_add_write_ana(MCI_AP_MIC, reg_change); + reg_change = ~reg_change & val; + wait_time = get_max_wait(reg_change); + + val = mc_ana_register_get_value(MCI_AP_AD); + reg_change = ~(val & power_update->analog[4]); + reg_change |= power_info->analog[4]; + reg_change &= val; + mc_packet_add_write_ana(MCI_AP_AD, reg_change); + + if ((val & MCB_AP_LI) && !(reg_change & MCB_AP_LI)) + wait_time = info.wait_time.wait[4]; + + mc_ana_register_set_value(MCI_AP_DA0, new_da0); + mc_ana_register_set_value(MCI_AP_DA1, new_da1); + + if (wait_time > 0) + mc_packet_add_wait(wait_time); + + return ret; +} + +static inline void dac_stop(void) +{ + u8 val; + + val = mc_e_register_get_value(MCI_LPF_THR); + if (!mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1)) + val &= ~MCB_OSF0_ENB; + if (!mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) + val &= ~MCB_OSF1_ENB; + mc_packet_add_write_e(MCI_LPF_THR, val); +} + +int mc_packet_add_powerdown(struct mcdrv_power_info *power_info, + struct mcdrv_power_update *power_update) +{ + struct mcdrv_dev_info info; + enum mcdrv_dev_id id; + u8 val, d_update, pd, rst_reg, ap, da0, da1; + u8 psw = 0, rst = 0, mk_det_en = 0, add_mk_det_en = 0, plug_det_db = 0; + int ret = 0; + + id = mc_dev_id_get(); + mc_dev_info_get(&info); + + d_update = power_info->digital & power_update->digital; + rst_reg = mc_if_register_get_value(MCI_RST); + pd = mc_a_register_get_value(MCI_PD); + plug_det_db = mc_plug_detect_db_get(); + + if (info.power_mode == MCDRV_POWMODE_FULL) + if ((d_update & MCDRV_POWINFO_D_PLL_PD) + && !(pd & (MCB_PLL_PD | MCB_PM_CLK_PD))) + mc_packet_add_wait_event(MCDRV_EVT_ALLMUTE); + + da0 = mc_ana_register_get_value(MCI_AP_DA0); + da0 |= (power_info->analog[1] & power_update->analog[1]); + da1 = mc_ana_register_get_value(MCI_AP_DA1); + da1 |= (power_info->analog[2] & power_update->analog[2]); + mc_ana_register_set_value(MCI_AP_DA0, da0); + mc_ana_register_set_value(MCI_AP_DA1, da1); + + val = mc_ana_register_get_value(MCI_AP_MIC); + val |= (power_info->analog[3] & power_update->analog[3]); + mc_packet_add_write_ana(MCI_AP_MIC, val); + + val = mc_ana_register_get_value(MCI_AP_AD); + val |= (power_info->analog[4] & power_update->analog[4]); + mc_packet_add_write_ana(MCI_AP_AD, val); + + if (d_update & MCDRV_POWINFO_D_PC_CLK_PD) { + if (!(pd & MCB_PC_CLK_PD)) { + mc_packet_add_force_write_if(MCI_ECDSP, 0); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_cdsp_term(); + pd |= MCB_PC_CLK_PD; + } + rst |= MCB_RST_C; + psw |= MCB_PSW_C; + } + + if (d_update & MCDRV_POWINFO_D_PF_CLK_PD) { + if (!(pd & MCB_PF_CLK_PD)) { + mc_packet_add_force_write_if(MCI_IESERR, 0); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_fdsp_term(); + pd |= MCB_PF_CLK_PD; + } + rst |= MCB_RST_F; + psw |= MCB_PSW_F; + } + + if ((d_update & MCDRV_POWINFO_D_PE_CLK_PD) && !(pd & MCB_PE_CLK_PD)) { + mc_packet_add_force_write_if(MCI_EEDSP, 0); + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_edsp_term(); + pd |= MCB_PE_CLK_PD; + } + + if ((d_update & MCDRV_POWINFO_D_PB_CLK_PD) && !(pd & MCB_PB_CLK_PD)) { + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_bdsp_term(); + pd |= MCB_PB_CLK_PD; + } + + if (d_update & MCDRV_POWINFO_D_PM_CLK_PD) { + if (!(pd & MCB_PM_CLK_PD)) { + mc_packet_add_write_ma(MCI_DSP_START, 0); + pd |= MCB_PM_CLK_PD; + } + rst |= MCB_RST_M; + psw |= MCB_PSW_M; + } + + mc_packet_add_write_a(MCI_PD, pd); + + rst_reg |= rst; + mc_packet_add_write_if(MCI_RST, rst_reg); + + rst_reg |= psw; + mc_packet_add_write_if(MCI_RST, rst_reg); + + ap = mc_ana_register_get_value(MCI_AP); + + val = mc_cd_register_get_value(MCI_HSDETEN); + if (info.power_mode == MCDRV_POWMODE_FULL) { + if ((d_update & MCDRV_POWINFO_D_PLL_PD) + && !(pd & MCB_PLL_PD) + && (power_update->analog[0] & MCB_AP_LDOA) + && (power_info->analog[0] & MCB_AP_LDOA)) { + if (val & MCB_MKDETEN) { + mk_det_en = val & MCB_MKDETEN; + val &= ~MCB_MKDETEN; + mc_packet_add_write_cd(MCI_HSDETEN, val); + } + + if (id != MCDRV_DEV_ID_80_90H) + mc_packet_add_wait_event(MCDRV_EVT_AP_CP_A_SET | + (91U << 8) | 0x2U); + + pd |= MCB_ANACLK_PD; + mc_packet_add_write_a(MCI_PD, pd); + } + } + + val = mc_cd_register_get_value(MCI_DP); + if ((power_update->analog[1] & (MCB_AP_DA0R | MCB_AP_DA0L)) + && (power_info->analog[1] & MCB_AP_DA0R) + && (power_info->analog[1] & MCB_AP_DA0L)) + val |= MCB_DP_DAC0; + if ((power_update->analog[1] & (MCB_AP_DA1R | MCB_AP_DA1L)) + && (power_info->analog[2] & MCB_AP_DA1R) + && (power_info->analog[2] & MCB_AP_DA1L)) { + if (id == MCDRV_DEV_ID_80_90H) + val |= MCB_DP_DAC1; + else if (val & MCB_DP_DAC0) + val |= MCB_DP_DAC1; + + } + + if ((power_update->analog[4] & (MCB_AP_ADM | MCB_AP_ADR | MCB_AP_ADL)) + && (power_info->analog[4] & MCB_AP_ADM) + && (power_info->analog[4] & MCB_AP_ADR) + && (power_info->analog[4] & MCB_AP_ADL) + && (da1 & (MCB_AP_SPR2 | MCB_AP_SPR1 | MCB_AP_SPL2 | MCB_AP_SPL1)) + == (MCB_AP_SPR2 | MCB_AP_SPR1 | MCB_AP_SPL2 | MCB_AP_SPL1)) + val |= MCB_DP_ADC | MCB_DP_PDMADC; + if ((val & (MCB_DP_DAC0 | MCB_DP_DAC1)) + == (MCB_DP_DAC0 | MCB_DP_DAC1)) { + val |= MCB_DP_PDMDAC; + if (val & MCB_DP_PDMADC) + val = MCI_DP_DEF; + } + mc_packet_add_write_cd(MCI_DP, val); + dac_stop(); + + if (info.power_mode == MCDRV_POWMODE_FULL) { + if ((d_update & MCDRV_POWINFO_D_PLL_PD) + && !(pd & MCB_PLL_PD)) { + mc_packet_add_force_write_if(MCI_IRQ, 0); + pd |= MCB_VCOOUT_PD; + pd |= MCB_PLL_PD; + mc_packet_add_write_a(MCI_PD, pd); + + val = mc_a_register_get_value(MCI_CLK_MSK); + if (!(val & MCB_RTCI_MSK)) { + val = mc_cd_register_get_value(MCI_CKSEL); + if (id == MCDRV_DEV_ID_80_90H) + val |= MCB_HSDET; + else + val |= MCB_CRTC; + mc_packet_add_write_cd(MCI_CKSEL, val); + } + + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_packet_add_write_if(MCI_RST_A, MCI_RST_A_DEF); + mc_a_registers_init(); + } + + if (pd & MCB_PLL_PD) + ap |= MCB_AP_LDOD; + } + + if ((power_update->analog[0] & MCB_AP_LDOA) + && (power_info->analog[0] & MCB_AP_LDOA) + && !(ap & MCB_AP_LDOA) + && (ap & MCB_AP_LDOD)) { + add_mk_det_en = mk_det_en; + ap |= (MCB_AP_LDOA | MCB_AP_VR); + } else + add_mk_det_en = 0; + + if ((power_update->analog[0] & MCB_AP_HPDET) + && (power_info->analog[0] & MCB_AP_HPDET)) + ap |= MCB_AP_HPDET; + + if (id != MCDRV_DEV_ID_81_92H) { + if ((ap & (MCB_AP_LDOA | MCB_AP_LDOD)) == + (MCB_AP_LDOA | MCB_AP_LDOD) + && !(ap & MCB_AP_BGR) + && !(plug_det_db & MCB_RPLUGDET_DB)) { + if (id != MCDRV_DEV_ID_80_90H) { + val = info.hp_hiz << 6 | info.sp_hiz << 4 + | info.rc_hiz << 3 | info.options[2]; + mc_packet_add_write_ana(MCI_HIZ, val); + val = info.line_out2_hiz << 6 + | info.line_out1_hiz << 4; + mc_packet_add_write_ana(MCI_LO_HIZ, val); + } + + ap |= MCB_AP_BGR; + } + } else { + if ((ap & (MCB_AP_LDOA | MCB_AP_LDOD)) == + (MCB_AP_LDOA | MCB_AP_LDOD)) { + ap |= MCB_AP_BGR; + if (!(plug_det_db & MCB_RPLUGDET_DB)) { + val = info.hp_hiz << 6 | info.sp_hiz << 4 + | info.rc_hiz << 3 | info.options[2]; + mc_packet_add_write_ana(MCI_HIZ, val); + } + } + } + + val = mc_ana_register_get_value(MCI_AP); + if ((ap & MCB_AP_HPDET) && !(val & MCB_AP_HPDET)) { + val |= MCB_AP_HPDET; + mc_packet_add_write_ana(MCI_AP, val); + } + if ((ap & MCB_AP_LDOA) && !(val & MCB_AP_LDOA)) { + val |= MCB_AP_LDOA; + if (id == MCDRV_DEV_ID_80_90H) + mc_packet_add_write_ana(MCI_AP, val); + val |= MCB_AP_VR; + mc_packet_add_write_ana(MCI_AP, val); + } + if ((ap & MCB_AP_LDOD) && !(val & MCB_AP_LDOD)) { + val |= MCB_AP_LDOD; + if ((ap & MCB_AP_BGR) && !(val & MCB_AP_BGR) && !mk_det_en) + val |= MCB_AP_BGR; + mc_packet_add_write_ana(MCI_AP, val); + } + + if ((val & (MCB_AP_LDOA | MCB_AP_LDOD | MCB_AP_BGR)) == + (MCB_AP_LDOA | MCB_AP_LDOD) + && (ap & MCB_AP_BGR) && !(plug_det_db & MCB_RPLUGDET_DB)) + val |= MCB_AP_BGR; + mc_packet_add_write_ana(MCI_AP, val); + + if (add_mk_det_en) { + ret = mc_packet_execute(); + if (ret < 0) + return ret; + + mc_packet_add_mic_key_detect_enable(false); + } + + return ret; +} + +static void get_di_state(u8 phys_port, u8 *is_used_dir, u8 *is_used_dit, + u8 *lport) +{ + struct mcdrv_dio_path_info dio; + + mc_dio_path_info_get(&dio); + + if (!is_used_dir || !is_used_dit || !lport) + return; + + *is_used_dir = 0; + *is_used_dit = 0; + *lport = 0xff; + + if (dio.phys_port[0] == phys_port) { + if (mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) { + *is_used_dir = 1; + *lport = 0; + } + + if (mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1)) { + *is_used_dit = 1; + *lport = 0; + } + } + + if (dio.phys_port[1] == phys_port) { + if (mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) { + *is_used_dir = 1; + *lport = 1; + } + + if (mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) { + *is_used_dit = 1; + *lport = 1; + } + } + + if (dio.phys_port[2] == phys_port) { + if (mc_source_is_used(MCDRV_DST_VBOXIOIN, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_VBOXHOSTIN, MCDRV_DST_CH0)) { + *is_used_dir = 1; + *lport = 2; + } + + if (mc_source_is_used(MCDRV_DST_VOICEOUT, MCDRV_DST_CH0)) { + *is_used_dit = 1; + *lport = 2; + } + } + + if (dio.phys_port[3] == phys_port) { + if (mc_d1_source_is_used(MCDRV_D1SRC_HIFIIN_ON)) { + *is_used_dir = 1; + *lport = 3; + } + + if (mc_source_is_used(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0)) { + *is_used_dit = 1; + *lport = 3; + } + } +} + +static inline u8 get_logical_port(u8 phys_port) +{ + u8 is_used_dir, is_used_dit, lport = 0xff; + + get_di_state(phys_port, &is_used_dir, &is_used_dit, &lport); + + return lport; +} + +static inline void add_di_pad(void) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dev_info info; + struct mcdrv_path_info path; + struct mcdrv_dio_info dio; + u8 val, lport, is_used_dir, is_used_dit; + + mc_aec_info_get(&aec); + mc_dev_info_get(&info); + mc_path_info_get(&path); + mc_dio_info_get(&dio); + + is_used_dir = 0; + is_used_dit = 0; + lport = 0xff; + get_di_state(MCDRV_PHYSPORT_DIO0, &is_used_dir, &is_used_dit, &lport); + + val = 0; + if (!is_used_dir) + val |= MCB_SDIN0_MSK; + if (!is_used_dit) { + if (!info.dio0_sdo_hiz) + val |= MCB_SDO0_DDR; + } else + val |= MCB_SDO0_DDR; + + if (!is_used_dir && !is_used_dit) { + val |= MCB_BCLK0_MSK | MCB_LRCK0_MSK; + if (!info.dio0_clk_hiz) + val |= MCB_BCLK0_DDR | MCB_LRCK0_DDR; + } else { + if (lport == 3 + || (lport <= 2 && + dio.port[lport].dio_common.master_slave == + MCDRV_DIO_MASTER)) + val |= MCB_BCLK0_DDR | MCB_LRCK0_DDR; + } + if (lport <= 3 + && dio.port[lport].dio_common.bck_invert == MCDRV_BCLK_INVERT) + val |= MCB_BCLK0_INV; + if (info.power_mode != MCDRV_POWMODE_CDSPDEBUG + && aec.vbox.cdsp_jtag_on != 1) + mc_packet_add_write_a(MCI_DO0_DRV, val); + + is_used_dir = 0; + is_used_dit = 0; + lport = 0xff; + get_di_state(MCDRV_PHYSPORT_DIO1, &is_used_dir, &is_used_dit, &lport); + + val = 0; + if (!is_used_dir) + val |= MCB_SDIN1_MSK; + if (!is_used_dit) { + if (!info.dio1_sdo_hiz) + val |= MCB_SDO1_DDR; + } else + val |= MCB_SDO1_DDR; + + if (!is_used_dir && !is_used_dit) { + val |= MCB_BCLK1_MSK | MCB_LRCK1_MSK; + if (!info.dio1_clk_hiz) + val |= MCB_BCLK1_DDR | MCB_LRCK1_DDR; + } else { + if (lport == 3 + || (lport <= 2 && + dio.port[lport].dio_common.master_slave == + MCDRV_DIO_MASTER)) + val |= MCB_BCLK1_DDR | MCB_LRCK1_DDR; + } + if (lport <= 3 + && dio.port[lport].dio_common.bck_invert == MCDRV_BCLK_INVERT) + val |= MCB_BCLK1_INV; + if (info.power_mode != MCDRV_POWMODE_CDSPDEBUG + && aec.vbox.cdsp_jtag_on != 1) + mc_packet_add_write_a(MCI_DO1_DRV, val); + + is_used_dir = 0; + is_used_dit = 0; + lport = 0xff; + get_di_state(MCDRV_PHYSPORT_DIO2, &is_used_dir, &is_used_dit, &lport); + + val = 0; + if (!is_used_dir) + val |= MCB_SDIN2_MSK; + if (!is_used_dit) { + if (!info.dio2_sdo_hiz) + val |= MCB_SDO2_DDR; + } else + val |= MCB_SDO2_DDR; + + if (!is_used_dir && !is_used_dit + && !mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON) + && !mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) { + val |= MCB_BCLK2_MSK | MCB_LRCK2_MSK; + if (!info.dio2_clk_hiz) + val |= MCB_BCLK2_DDR | MCB_LRCK2_DDR; + } else { + if (lport == 3 + || (lport <= 2 && + dio.port[lport].dio_common.master_slave == + MCDRV_DIO_MASTER)) + val |= MCB_BCLK2_DDR | MCB_LRCK2_DDR; + } + if (lport <= 3 + && dio.port[lport].dio_common.bck_invert == MCDRV_BCLK_INVERT) + val |= MCB_BCLK2_INV; + mc_packet_add_write_a(MCI_DO2_DRV, val); +} + +static inline void add_pad(void) +{ + struct mcdrv_dev_info info; + u32 hifi_src; + u8 val; + + mc_dev_info_get(&info); + + hifi_src = mc_source_get(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0); + + if (!mc_d2_source_is_used(MCDRV_D2SRC_PDM0_L_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM0_R_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM1_L_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM1_R_ON) + && !(hifi_src & (MCDRV_D2SRC_PDM0_L_ON | MCDRV_D2SRC_PDM0_R_ON)) + && !(hifi_src & (MCDRV_D2SRC_PDM1_L_ON | MCDRV_D2SRC_PDM1_R_ON)) + && info.pa0_func == MCDRV_PA_PDMCK) { + val = mc_a_register_get_value(MCI_PA0); + val |= MCB_PA0_MSK; + mc_packet_add_write_a(MCI_PA0, val); + } + + if (info.pa1_func == MCDRV_PA_PDMDI) { + val = mc_a_register_get_value(MCI_PA1); + if (!mc_d2_source_is_used(MCDRV_D2SRC_PDM0_L_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM0_R_ON) + && !(hifi_src & + (MCDRV_D2SRC_PDM0_L_ON | MCDRV_D2SRC_PDM0_R_ON))) + val |= MCB_PA1_MSK; + else + val &= ~MCB_PA1_MSK; + mc_packet_add_write_a(MCI_PA1, val); + } + + if (info.pa2_func == MCDRV_PA_PDMDI) { + val = mc_a_register_get_value(MCI_PA2); + if (!mc_d2_source_is_used(MCDRV_D2SRC_PDM1_L_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM1_R_ON) + && !(hifi_src & + (MCDRV_D2SRC_PDM1_L_ON | MCDRV_D2SRC_PDM1_R_ON))) + val |= MCB_PA2_MSK; + else + val &= ~MCB_PA2_MSK; + mc_packet_add_write_a(MCI_PA2, val); + } +} + +static u8 get_preinput(u32 src_on) +{ + u8 val = 0; + + switch (src_on) { + case MCDRV_D2SRC_ADC0_L_ON: + val = MCB_DSF_PRE_INPUT_ADC_L; + break; + case MCDRV_D2SRC_ADC0_R_ON: + val = MCB_DSF_PRE_INPUT_ADC_R; + break; + case MCDRV_D2SRC_ADC1_ON: + val = MCB_DSF_PRE_INPUT_ADC_M; + break; + case MCDRV_D2SRC_PDM0_L_ON: + val = MCB_DSF_PRE_INPUT_PDM0_L; + break; + case MCDRV_D2SRC_PDM0_R_ON: + val = MCB_DSF_PRE_INPUT_PDM0_R; + break; + case MCDRV_D2SRC_PDM1_L_ON: + val = MCB_DSF_PRE_INPUT_PDM1_L; + break; + case MCDRV_D2SRC_PDM1_R_ON: + val = MCB_DSF_PRE_INPUT_PDM1_R; + break; + default: + break; + } + + return val; +} + +static u8 get_in_mix_value(u32 src_on) +{ + u8 val = 0; + + if (src_on & MCDRV_D1SRC_MUSICIN_ON) + val |= MCB_IN_MIX_DIFI_0; + if (src_on & MCDRV_D1SRC_EXTIN_ON) + val |= MCB_IN_MIX_DIFI_1; + if (src_on & MCDRV_D1SRC_VBOXOUT_ON) + val |= MCB_IN_MIX_DIFI_2; + if (src_on & MCDRV_D1SRC_VBOXREFOUT_ON) + val |= MCB_IN_MIX_DIFI_3; + if (src_on & MCDRV_D1SRC_ADIF0_ON) + val |= MCB_IN_MIX_ADI_0; + if (src_on & MCDRV_D1SRC_ADIF1_ON) + val |= MCB_IN_MIX_ADI_1; + if (src_on & MCDRV_D1SRC_ADIF2_ON) + val |= MCB_IN_MIX_ADI_2; + + return val; +} + +static void add_in_mix_src(enum mcdrv_dst_type dst_type, + u8 addr0, u8 addr1, u8 sep) +{ + u32 src; + u8 val0, val1, cur_val0, cur_val1; + + cur_val0 = mc_ma_register_get_value(addr0); + cur_val0 &= ~sep; + + cur_val1 = mc_ma_register_get_value(addr1); + + src = mc_source_get(dst_type, MCDRV_DST_CH0); + val0 = get_in_mix_value(src); + + src = mc_source_get(dst_type, MCDRV_DST_CH1); + val1 = get_in_mix_value(src); + + if (val0 != cur_val0 || val1 != cur_val1) { + if (val0 == val1) { + mc_packet_add_force_write_ma(addr0, val0); + mc_ma_register_set_value(addr1, val1); + } else { + mc_packet_add_force_write_ma(addr0, val0 | sep); + mc_packet_add_force_write_ma(addr1, val1); + } + } +} + +static u16 get_out_mix_value(u32 src_on) +{ + u16 val = 0; + + if (src_on & MCDRV_D1SRC_MUSICIN_ON) + val |= MCB_OUT_MIX_DIFI_0; + if (src_on & MCDRV_D1SRC_EXTIN_ON) + val |= MCB_OUT_MIX_DIFI_1; + if (src_on & MCDRV_D1SRC_VBOXOUT_ON) + val |= MCB_OUT_MIX_DIFI_2; + if (src_on & MCDRV_D1SRC_VBOXREFOUT_ON) + val |= MCB_OUT_MIX_DIFI_3; + if (src_on & MCDRV_D1SRC_AE0_ON) + val |= MCB_OUT_MIX_AEO_0; + if (src_on & MCDRV_D1SRC_AE1_ON) + val |= MCB_OUT_MIX_AEO_1; + if (src_on & MCDRV_D1SRC_AE2_ON) + val |= MCB_OUT_MIX_AEO_2; + if (src_on & MCDRV_D1SRC_AE3_ON) + val |= MCB_OUT_MIX_AEO_3; + if (src_on & MCDRV_D1SRC_ADIF0_ON) + val |= MCB_OUT_MIX_ADI_0; + if (src_on & MCDRV_D1SRC_ADIF1_ON) + val |= MCB_OUT_MIX_ADI_1; + if (src_on & MCDRV_D1SRC_ADIF2_ON) + val |= MCB_OUT_MIX_ADI_2; + + return val; +} + +static void add_out_mix_src(enum mcdrv_dst_type dst_type, + u8 addr0, u8 addr1, u8 sep) +{ + u32 src; + u16 val0, val1, cur_val0, cur_val1; + + cur_val0 = (u16) mc_ma_register_get_value(addr0) << 8 + | mc_ma_register_get_value(addr0 + 1); + cur_val0 &= ~(sep << 8); + + cur_val1 = (u16) mc_ma_register_get_value(addr1) << 8 + | mc_ma_register_get_value(addr1 + 1); + + src = mc_source_get(dst_type, MCDRV_DST_CH0); + val0 = get_out_mix_value(src); + + src = mc_source_get(dst_type, MCDRV_DST_CH1); + val1 = get_out_mix_value(src); + + if (val0 != cur_val0 || val1 != cur_val1) { + if (val0 == val1) { + mc_packet_add_force_write_ma(addr0, val0 >> 8); + mc_packet_add_force_write_ma(addr0 + 1, val0); + mc_ma_register_set_value(addr1, val1 >> 8); + mc_ma_register_set_value(addr1 + 1, val1); + } else { + mc_packet_add_force_write_ma(addr0, (val0 >> 8) | sep); + mc_packet_add_force_write_ma(addr0 + 1, val0); + mc_packet_add_force_write_ma(addr1, val1 >> 8); + mc_packet_add_force_write_ma(addr1 + 1, val1); + } + } +} + +static inline void add_out2_mix_src(void) +{ + u32 src; + u16 val0, val1, cur_val0, cur_val1; + + cur_val0 = (u16) mc_ma_register_get_value(MCI_OUT2_MIX0_10_8) << 8 + | mc_ma_register_get_value(MCI_OUT2_MIX0_7_0); + cur_val0 &= ~(MCB_OUT2_MSEP << 8); + + cur_val1 = (u16) mc_ma_register_get_value(MCI_OUT2_MIX1_10_8) << 8 + | mc_ma_register_get_value(MCI_OUT2_MIX1_7_0); + src = mc_source_get(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0); + val0 = get_out_mix_value(src); + + src = mc_source_get(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1); + val1 = get_out_mix_value(src); + + if (val0 != cur_val0 || val1 != cur_val1) { + if (val0 == val1) { + mc_packet_add_force_write_ma(MCI_OUT2_MIX0_10_8, + val0 >> 8); + mc_packet_add_force_write_ma(MCI_OUT2_MIX0_7_0, val0); + mc_ma_register_set_value(MCI_OUT2_MIX1_10_8, val1 >> 8); + mc_ma_register_set_value(MCI_OUT2_MIX1_7_0, val1); + } else { + mc_packet_add_force_write_ma(MCI_OUT2_MIX0_10_8, + (val0 >> 8) | + MCB_OUT2_MSEP); + mc_packet_add_force_write_ma(MCI_OUT2_MIX0_7_0, val0); + mc_packet_add_force_write_ma(MCI_OUT2_MIX1_10_8, + val1 >> 8); + mc_packet_add_force_write_ma(MCI_OUT2_MIX1_7_0, val1); + } + } + + cur_val0 = (u16) mc_ma_register_get_value(MCI_OUT3_MIX0_10_8) << 8 + | mc_ma_register_get_value(MCI_OUT3_MIX0_7_0); + cur_val0 &= ~(MCB_OUT3_MSEP << 8); + + cur_val1 = (u16) mc_ma_register_get_value(MCI_OUT3_MIX1_10_8) << 8 + | mc_ma_register_get_value(MCI_OUT3_MIX1_7_0); + + src = mc_source_get(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2); + val0 = get_out_mix_value(src); + + src = mc_source_get(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3); + val1 = get_out_mix_value(src); + + if (val0 != cur_val0 || val1 != cur_val1) { + if (val0 == val1) { + mc_packet_add_force_write_ma(MCI_OUT3_MIX0_10_8, + val0 >> 8); + mc_packet_add_force_write_ma(MCI_OUT3_MIX0_7_0, val0); + mc_ma_register_set_value(MCI_OUT3_MIX1_10_8, val1 >> 8); + mc_ma_register_set_value(MCI_OUT3_MIX1_7_0, val1); + } else { + mc_packet_add_force_write_ma(MCI_OUT3_MIX0_10_8, + (val0 >> 8) | + MCB_OUT3_MSEP); + mc_packet_add_force_write_ma(MCI_OUT3_MIX0_7_0, val0); + mc_packet_add_force_write_ma(MCI_OUT3_MIX1_10_8, + val1 >> 8); + mc_packet_add_force_write_ma(MCI_OUT3_MIX1_7_0, val1); + } + } +} + +static inline void add_source(void) +{ + struct mcdrv_aec_info aec; + u32 hifi_src, src; + u8 val, dsf0_preinput, dsf1_preinput, dsf2_preinput; + + add_in_mix_src(MCDRV_DST_AE0, MCI_IN0_MIX0, MCI_IN0_MIX1, MCB_IN0_MSEP); + add_in_mix_src(MCDRV_DST_AE1, MCI_IN1_MIX0, MCI_IN1_MIX1, MCB_IN1_MSEP); + add_in_mix_src(MCDRV_DST_AE2, MCI_IN2_MIX0, MCI_IN2_MIX1, MCB_IN2_MSEP); + add_in_mix_src(MCDRV_DST_AE3, MCI_IN3_MIX0, MCI_IN3_MIX1, MCB_IN3_MSEP); + + add_out_mix_src(MCDRV_DST_MUSICOUT, MCI_OUT0_MIX0_10_8, + MCI_OUT0_MIX1_10_8, MCB_OUT0_MSEP); + add_out_mix_src(MCDRV_DST_EXTOUT, MCI_OUT1_MIX0_10_8, + MCI_OUT1_MIX1_10_8, MCB_OUT1_MSEP); + add_out2_mix_src(); + add_out_mix_src(MCDRV_DST_DAC0, MCI_OUT4_MIX0_10_8, MCI_OUT4_MIX1_10_8, + MCB_OUT4_MSEP); + add_out_mix_src(MCDRV_DST_DAC1, MCI_OUT5_MIX0_10_8, MCI_OUT5_MIX1_10_8, + MCB_OUT5_MSEP); + + mc_aec_info_get(&aec); + + dsf0_preinput = mc_e_register_get_value(MCI_DSF0_PRE_INPUT); + dsf1_preinput = mc_e_register_get_value(MCI_DSF1_PRE_INPUT); + dsf2_preinput = mc_e_register_get_value(MCI_DSF2_PRE_INPUT); + + hifi_src = mc_source_get(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0); + + if (mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH1)) { + val = dsf0_preinput; + src = mc_source_get(MCDRV_DST_ADIF0, MCDRV_DST_CH0); + if (src) { + val &= ~0x0f; + val |= get_preinput(src); + } + + src = mc_source_get(MCDRV_DST_ADIF0, MCDRV_DST_CH1); + if (src) { + val &= ~0xf0; + val |= get_preinput(src) << 4; + } + + if (val != dsf0_preinput) + mc_packet_add_write_e(MCI_DSF0_PRE_INPUT, val); + } + + if (mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH1)) { + val = dsf1_preinput; + src = mc_source_get(MCDRV_DST_ADIF1, MCDRV_DST_CH0); + if (src) { + val &= ~0x0f; + val |= get_preinput(src); + } + + src = mc_source_get(MCDRV_DST_ADIF1, MCDRV_DST_CH1); + if (src) { + val &= ~0xf0; + val |= get_preinput(src) << 4; + } + + if (val != dsf1_preinput) + mc_packet_add_write_e(MCI_DSF1_PRE_INPUT, val); + } + + if (mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH1)) { + src = mc_source_get(MCDRV_DST_ADIF2, MCDRV_DST_CH0); + if (src != MCDRV_D2SRC_DAC0REF_ON + && src != MCDRV_D2SRC_DAC1REF_ON) { + val = dsf2_preinput; + if (src) { + val &= ~0x0f; + val |= get_preinput(src); + } + + src = mc_source_get(MCDRV_DST_ADIF2, MCDRV_DST_CH1); + if (src) { + val &= ~0xf0; + val |= get_preinput(src) << 4; + } + + if (val != dsf2_preinput) + mc_packet_add_write_e(MCI_DSF2_PRE_INPUT, val); + } + } +} + +static u8 get_mic_mixer_value(u32 src_on) +{ + u8 val = 0; + + if (src_on & MCDRV_ASRC_MIC1_ON) + val |= MCB_AD_M1MIX; + if (src_on & MCDRV_ASRC_MIC2_ON) + val |= MCB_AD_M2MIX; + if (src_on & MCDRV_ASRC_MIC3_ON) + val |= MCB_AD_M3MIX; + if (src_on & MCDRV_ASRC_MIC4_ON) + val |= MCB_AD_M4MIX; + + return val; +} + +static inline void add_mixer(void) +{ + struct mcdrv_path_info path; + u8 val; + + mc_path_info_get(&path); + + val = get_mic_mixer_value(path.adc0[0]); + if (path.adc0[0] & MCDRV_ASRC_LINEIN1_L_ON) + val |= MCB_AD_LIMIX; + if (path.adc0[0] & MCDRV_ASRC_LINEIN1_M_ON) + val |= (MCB_MONO_AD_LI | MCB_AD_LIMIX); + mc_packet_add_write_ana(MCI_ADL_MIX, val); + + val = get_mic_mixer_value(path.adc0[1]); + if (path.adc0[1] & MCDRV_ASRC_LINEIN1_R_ON) + val |= MCB_AD_LIMIX; + if (path.adc0[1] & MCDRV_ASRC_LINEIN1_M_ON) + val |= (MCB_MONO_AD_LI | MCB_AD_LIMIX); + mc_packet_add_write_ana(MCI_ADR_MIX, val); + + val = get_mic_mixer_value(path.adc1[0]); + if (path.adc1[0] & MCDRV_ASRC_LINEIN1_M_ON) + val |= MCB_AD_LIMIX; + mc_packet_add_write_ana(MCI_ADM_MIX, val); +} + +void mc_packet_add_path_set(void) +{ + u8 val; + + val = mc_if_register_get_value(MCI_RST_A); + if (!(val & MCB_RST_A)) { + add_di_pad(); + add_pad(); + add_source(); + add_mixer(); + } +} + +static u8 get_lp2_start(void) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dio_info dio; + u8 start = 0; + + mc_dio_info_get(&dio); + mc_aec_info_get(&aec); + + if (mc_source_is_used(MCDRV_DST_VOICEOUT, MCDRV_DST_CH0)) { + if (dio.port[2].dio_common.master_slave == MCDRV_DIO_MASTER) + start |= MCB_LP2_TIM_START; + start |= MCB_LPT2_START_SRC | MCB_LPT2_START; + } + + if (mc_source_is_used(MCDRV_DST_VBOXIOIN, MCDRV_DST_CH0)) { + if (dio.port[2].dio_common.master_slave == MCDRV_DIO_MASTER) + start |= MCB_LP2_TIM_START; + start |= MCB_LPR2_START_SRC | MCB_LPR2_START; + } + + if (!start) { + /* LP2 not running */ + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) + start |= MCB_LP2_TIM_START | MCB_LPT2_START_SRC | + MCB_LPT2_START; + + if (mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) + start |= MCB_LP2_TIM_START | MCB_LPR2_START_SRC | + MCB_LPR2_START; + + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3) || + mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) + if (aec.vbox.src3_ctrl == 1 || aec.vbox.src3_ctrl == 2) + start |= MCB_LP2_TIM_START; + + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3) || + mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON) || + mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON) || + mc_source_is_used(MCDRV_DST_VBOXHOSTIN, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_HOSTOUT, MCDRV_DST_CH0)) + if (aec.fdsp_locate && aec.vbox.fdsp_on) + start |= MCB_LP2_TIM_START; + } else { + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) + start |= MCB_LPT2_START_SRC | MCB_LPT2_START; + + if (mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) + start |= MCB_LPR2_START_SRC | MCB_LPR2_START; + + } + + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3) || + mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) + if (aec.vbox.src3_ctrl == 1 || aec.vbox.src3_ctrl == 2) + start |= MCB_LPT2_START_SRC | MCB_LPT2_START | + MCB_LPR2_START_SRC | MCB_LPR2_START; + + return start; +} + +static u8 get_lp2_fs(u8 *thru) +{ + struct mcdrv_dio_info dio; + struct mcdrv_aec_info aec; + u8 fs = 0xff; + + mc_dio_info_get(&dio); + mc_aec_info_get(&aec); + + *thru = 0xff; + + if (mc_source_is_used(MCDRV_DST_VOICEOUT, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_VBOXIOIN, MCDRV_DST_CH0)) { + /* LP2 running */ + *thru = dio.port[2].dio_common.src_thru << 5; + fs = dio.port[2].dio_common.fs; + } else { + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1) || + mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) { + *thru = aec.vbox.src2_thru << 5; + fs = aec.vbox.src2_fs; + } + } + + if (aec.vbox.src3_ctrl == 1) { + if (*thru == 0xff) { + *thru = aec.vbox.src2_thru << 5; + fs = aec.vbox.src2_fs; + } + } + + return fs; +} + +void mc_packet_add_stop(void) +{ + u32 hifi_src, src; + u8 val, old, enable; + + val = mc_mb_register_get_value(MCI_LP0_START); + old = val; + if (!mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1)) + val &= ~(MCB_LPT0_START_SRC | MCB_LPT0_START); + if (!mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) + val &= ~(MCB_LPR0_START_SRC | MCB_LPR0_START); + if (!(val & 0x0f)) + val = 0; + mc_packet_add_write_mb(MCI_LP0_START, val); + + if (val == 0 && val != old) + mc_packet_add_write_a(MCI_LP0_FP, MCDRV_PHYSPORT_NONE); + + val = mc_mb_register_get_value(MCI_LP1_START); + old = val; + if (!mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) + val &= ~(MCB_LPT1_START_SRC | MCB_LPT1_START); + if (!mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) + val &= ~(MCB_LPR1_START_SRC | MCB_LPR1_START); + if (!(val & 0x0f)) + val = 0; + mc_packet_add_write_mb(MCI_LP1_START, val); + + if (val == 0 && val != old) + mc_packet_add_write_a(MCI_LP1_FP, MCDRV_PHYSPORT_NONE); + + old = mc_mb_register_get_value(MCI_LP2_START); + val = old & get_lp2_start(); + mc_packet_add_write_mb(MCI_LP2_START, val); + + if (val == 0 && val != old) + mc_packet_add_write_a(MCI_LP2_FP, MCDRV_PHYSPORT_NONE); + + val = mc_mb_register_get_value(MCI_SRC3_START); + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) + && !mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) + val &= ~MCB_OSRC3_START; + if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) + val &= ~MCB_ISRC3_START; + if (!(val & 0x0f)) + val = 0; + mc_packet_add_write_mb(MCI_SRC3_START, val); + + enable = mc_e_register_get_value(MCI_DIRECTPATH_ENB); + + val = mc_mb_register_get_value(MCI_LP3_START); + if (!mc_source_is_used(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0)) { + val &= ~MCB_LPT3_START; + enable &= ~MCB_DIRECT_ENB_ADC; + } + if (!mc_d1_source_is_used(MCDRV_D1SRC_HIFIIN_ON)) { + val &= ~MCB_LPR3_START; + enable &= ~(MCB_DIRECT_ENB_DAC1 | MCB_DIRECT_ENB_DAC0); + } else { + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH0); + src |= mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH1); + if (!(src & MCDRV_D1SRC_HIFIIN_ON)) + enable &= ~MCB_DIRECT_ENB_DAC0; + + src = mc_source_get(MCDRV_DST_DAC1, MCDRV_DST_CH0); + src |= mc_source_get(MCDRV_DST_DAC1, MCDRV_DST_CH1); + if (!(src & MCDRV_D1SRC_HIFIIN_ON)) + enable &= ~MCB_DIRECT_ENB_DAC1; + } + + if (!(val & 0x0f)) + val = 0; + mc_packet_add_write_mb(MCI_LP3_START, val); + + if (val == 0) { + mc_packet_add_write_e(MCI_DIRECTPATH_ENB, 0); + mc_packet_add_write_a(MCI_LP3_FP, MCDRV_PHYSPORT_NONE); + } else { + if (mc_dev_id_get() != MCDRV_DEV_ID_80_90H) + mc_packet_add_write_e(MCI_DIRECTPATH_ENB, enable); + } + + /* ADC stop */ + hifi_src = mc_source_get(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0); + if (!mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH1)) { + val = mc_e_register_get_value(MCI_DSF0_FLT_TYPE); + val &= ~MCB_DSF0ENB; + mc_packet_add_write_e(MCI_DSF0_FLT_TYPE, val); + } + + if (!mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH1)) { + val = mc_e_register_get_value(MCI_DSF1_FLT_TYPE); + val &= ~MCB_DSF1ENB; + mc_packet_add_write_e(MCI_DSF1_FLT_TYPE, val); + } + + if (!mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH1)) { + val = mc_e_register_get_value(MCI_DSF2_FLT_TYPE); + val &= ~MCB_DSF2ENB; + mc_packet_add_write_e(MCI_DSF2_FLT_TYPE, val); + } + + /* PDM Stop */ + val = mc_e_register_get_value(MCI_PDM_LOAD_TIM); + if (!mc_d2_source_is_used(MCDRV_D2SRC_PDM0_L_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM0_R_ON) + && !(hifi_src & (MCDRV_D2SRC_PDM0_L_ON | MCDRV_D2SRC_PDM0_R_ON))) + val &= ~MCB_PDM0_START; + if (!mc_d2_source_is_used(MCDRV_D2SRC_PDM1_L_ON) + && !mc_d2_source_is_used(MCDRV_D2SRC_PDM1_R_ON) + && !(hifi_src & (MCDRV_D2SRC_PDM1_L_ON | MCDRV_D2SRC_PDM1_R_ON))) + val &= ~MCB_PDM1_START; + mc_packet_add_write_e(MCI_PDM_LOAD_TIM, val); +} + +static inline u8 get_spath(void) +{ + u32 src; + u8 val = 0x7f; + + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH0); + if (src & MCDRV_D1SRC_MUSICIN_ON) + val |= MCB_SPATH_ON; + + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH1); + if (src & MCDRV_D1SRC_MUSICIN_ON) + val |= MCB_SPATH_ON; + + src = mc_source_get(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0); + if (src & MCDRV_D1SRC_ADIF0_ON) + val |= MCB_SPATH_ON; + + src = mc_source_get(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1); + if (src & MCDRV_D1SRC_ADIF0_ON) + val |= MCB_SPATH_ON; + + if (mc_source_is_used(MCDRV_DST_AE0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_AE0, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_AE1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_AE1, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_AE2, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_AE2, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_AE3, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_AE3, MCDRV_DST_CH1)) + val &= ~MCB_SPATH_ON; + else + val &= ~MCB_IN_MIX_ON; + + if (!mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1)) + val &= ~MCB_OUT_MIX_ON_0; + + if (!mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) + val &= ~MCB_OUT_MIX_ON_1; + else + val &= ~MCB_SPATH_ON; + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) + val &= ~MCB_OUT_MIX_ON_2; + else + val &= ~MCB_SPATH_ON; + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) + && !mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) + val &= ~MCB_OUT_MIX_ON_3; + else + val &= ~MCB_SPATH_ON; + + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH0); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) { + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH1); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) + val &= ~MCB_OUT_MIX_ON_4; + } + + src = mc_source_get(MCDRV_DST_DAC1, MCDRV_DST_CH0); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) { + src = mc_source_get(MCDRV_DST_DAC1, MCDRV_DST_CH1); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) + val &= ~MCB_OUT_MIX_ON_5; + } + + if (!(val & (MCB_OUT_MIX_ON_4 | MCB_OUT_MIX_ON_0)) + || (val & (MCB_IN_MIX_ON | MCB_OUT_MIX_ON_5321))) + val &= ~MCB_SPATH_ON; + + if ((val & (MCB_SPATH_ON | MCB_OUT_MIX_ON_0)) + == (MCB_SPATH_ON | MCB_OUT_MIX_ON_0)) { + src = mc_source_get(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0); + src |= mc_source_get(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1); + if (src != MCDRV_D1SRC_ADIF0_ON) + val &= ~MCB_SPATH_ON; + } + if ((val & (MCB_SPATH_ON | MCB_OUT_MIX_ON_4)) + == (MCB_SPATH_ON | MCB_OUT_MIX_ON_4)) { + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH0); + src |= mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH1); + if (src != MCDRV_D1SRC_MUSICIN_ON) + val &= ~MCB_SPATH_ON; + } + + return val; +} + +void mc_packet_add_dsp_start_and_stop(u8 started) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dio_info dio; + struct mcdrv_fdsp_mute mute; + enum mc_cdsp_fifo_sel fifo_sel; + u8 val, start, e1_cmd, lp2_fs, thru; + int i; + + mc_aec_info_get(&aec); + + start = mc_dsp_get_running(); + if (start & MCDRV_DSP_START_E) { + e1_cmd = 0; + val = mc_e_register_get_value(MCI_E1COMMAND); + if (!mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1) + && !mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH1) + && !mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH1) + && !mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH0) + && !mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH1)) + e1_cmd = E1COMMAND_PD; + + if (!(started & MCDRV_DSP_START_E)) { + mc_packet_add_write_e(MCI_E1DSP_CTRL, 0); + e1_cmd |= E1COMMAND_RUN_MODE; + mc_packet_add_write_e(MCI_E1COMMAND, e1_cmd); + + mc_edsp_start(); + } else if ((val & E1COMMAND_PD) != (e1_cmd & E1COMMAND_PD)) { + e1_cmd |= E1COMMAND_ADDITIONAL; + mc_packet_add_write_e(MCI_E1COMMAND, e1_cmd); + } + } else if (started & MCDRV_DSP_START_E) { + mc_packet_add_force_write_e(MCI_E1COMMAND, + E1COMMAND_SLEEP_MODE); + mc_edsp_stop(); + } + + if (start & MCDRV_DSP_START_B) { + if (!(started & MCDRV_DSP_START_B)) + mc_bdsp_start(); + } else if (started & MCDRV_DSP_START_B) + mc_bdsp_stop(); + + if (start & MCDRV_DSP_START_F) { + if (!(started & MCDRV_DSP_START_F)) { + for (i = 0; i < FDSP_MUTE_NUM; i++) { + mute.in_mute[i] = FDSP_MUTE_OFF; + mute.out_mute[i] = FDSP_MUTE_OFF; + } + + mc_fdsp_start(); + mc_fdsp_set_mute(&mute); + } + } + + if (start & MCDRV_DSP_START_C) { + if (!mc_source_is_used(MCDRV_DST_VBOXHOSTIN, MCDRV_DST_CH0)) + fifo_sel = CDSP_FIFO_SEL_PORT; + else + fifo_sel = CDSP_FIFO_SEL_HOST; + mc_cdsp_set_dfifo_sel(fifo_sel); + + if (!mc_source_is_used(MCDRV_DST_HOSTOUT, MCDRV_DST_CH0)) + fifo_sel = CDSP_FIFO_SEL_PORT; + else + fifo_sel = CDSP_FIFO_SEL_HOST; + mc_cdsp_set_rfifo_sel(fifo_sel); + + if (!(started & MCDRV_DSP_START_C)) { + mc_dio_info_get(&dio); + lp2_fs = get_lp2_fs(&thru); + if (aec.vbox.cdsp_func_a_on) { + if (aec.vbox.src3_ctrl == 3 + && aec.vbox.cdsp_func_a_on == 0x11) + val = + mc_mb_register_get_value(MCI_SRC3); + else + val = lp2_fs; + mc_cdsp_set_fs(CDSP_DECODER, val & 0x0f); + mc_cdsp_start(CDSP_DECODER); + } + + if (aec.vbox.cdsp_func_b_on) { + if (aec.vbox.src3_ctrl == 3 + && aec.vbox.cdsp_func_b_on == 0x11) + val = + mc_mb_register_get_value(MCI_SRC3); + else + val = lp2_fs; + mc_cdsp_set_fs(CDSP_ENCODER, val & 0x0f); + mc_cdsp_start(CDSP_ENCODER); + } + } + } else if (started & MCDRV_DSP_START_C) { + if (aec.vbox.cdsp_func_a_on) + mc_cdsp_stop(CDSP_DECODER); + if (aec.vbox.cdsp_func_b_on) + mc_cdsp_stop(CDSP_ENCODER); + } + + if (start & MCDRV_DSP_START_M) { + mc_packet_add_write_ma(MCI_SPATH_ON, get_spath()); + if (!(started & MCDRV_DSP_START_M)) + mc_packet_add_write_ma(MCI_DSP_START, MCB_DSP_START); + } else if (started & MCDRV_DSP_START_M) + mc_packet_add_write_ma(MCI_SPATH_ON, 0); +} + +void mc_packet_add_fdsp_stop(u8 started) +{ + u8 start = mc_dsp_get_running(); + + if (!(start & MCDRV_DSP_START_F) && (started & MCDRV_DSP_START_F)) + mc_fdsp_stop(); +} + +static inline void add_di_start(void) +{ + struct mcdrv_dio_info dio; + struct mcdrv_dio_path_info path_info; + struct mcdrv_aec_info aec; + enum mcdrv_dev_id id; + u8 start, val = 0; + u8 thru = 0xff, fs = 0xff; + + id = mc_dev_id_get(); + mc_dio_info_get(&dio); + mc_aec_info_get(&aec); + mc_dio_path_info_get(&path_info); + + start = 0; + if (mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1)) { + if (dio.port[0].dio_common.master_slave == MCDRV_DIO_MASTER) + start |= MCB_LP0_TIM_START; + start |= MCB_LPT0_START_SRC | MCB_LPT0_START; + } + + if (mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) { + if (dio.port[0].dio_common.master_slave == MCDRV_DIO_MASTER) + start |= MCB_LP0_TIM_START; + start |= MCB_LPR0_START_SRC | MCB_LPR0_START; + } + + if (start) { + mc_packet_add_write_a(MCI_LP0_FP, path_info.phys_port[0]); + if (id != MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_ma(MCI_LINK_LOCK, MCB_LINK_LOCK); + mc_packet_add_write_mb(MCI_T_DPLL_FAST, + MCB_T_DPLL_FAST | + MCB_VOLREL_TIME); + } + mc_packet_add_write_mb(MCI_LP0_START, start); + } + + start = 0; + if (mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) { + if (dio.port[1].dio_common.master_slave == MCDRV_DIO_MASTER) + start |= MCB_LP1_TIM_START; + start |= MCB_LPT1_START_SRC | MCB_LPT1_START; + } + + if (mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) { + if (dio.port[1].dio_common.master_slave == MCDRV_DIO_MASTER) + start |= MCB_LP1_TIM_START; + start |= MCB_LPR1_START_SRC | MCB_LPR1_START; + } + + if (start) { + mc_packet_add_write_a(MCI_LP1_FP, path_info.phys_port[1]); + if (id != MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_ma(MCI_LINK_LOCK, MCB_LINK_LOCK); + mc_packet_add_write_mb(MCI_T_DPLL_FAST, + MCB_T_DPLL_FAST | + MCB_VOLREL_TIME); + } + mc_packet_add_write_mb(MCI_LP1_START, start); + } + + start = get_lp2_start(); + if (start) { + fs = get_lp2_fs(&thru); + if (thru != 0xff) { + if (id == MCDRV_DEV_ID_80_90H) { + val = mc_mb_register_get_value(MCI_LP2_MODE); + if ((val & MCB_LP2_SRC_THRU) != thru) { + mc_packet_add_write_mb(MCI_LP2_START, + 0); + val = (val & ~MCB_LP2_SRC_THRU) | thru; + mc_packet_add_write_mb(MCI_LP2_MODE, + val); + } + } + + val = mc_mb_register_get_value(MCI_LP2_BCK); + if ((val & 0x0f) != fs) { + mc_packet_add_write_mb(MCI_LP2_START, 0); + val = (val & 0xf0) | fs; + mc_packet_add_write_mb(MCI_LP2_BCK, val); + } + } + if (mc_source_is_used(MCDRV_DST_VOICEOUT, MCDRV_DST_CH0) || + mc_source_is_used(MCDRV_DST_VBOXIOIN, MCDRV_DST_CH0)) + mc_packet_add_write_a(MCI_LP2_FP, + path_info.phys_port[2]); + else { + /* LP2 not running */ + val = mc_mb_register_get_value(MCI_LP2_START); + if (val) + mc_packet_add_write_a(MCI_LP2_FP, + MCDRV_PHYSPORT_NONE); + } + + if (id != MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_mb(MCI_LP2_START, 0); + val = (val & 0xf0) | fs; + mc_packet_add_write_mb(MCI_LP2_BCK, val); + } + + mc_packet_add_write_mb(MCI_LP2_START, start); + } + + start = 0; + thru = 0xff; + fs = 0xff; + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) { + start |= MCB_SRC3_TIM_START | MCB_OSRC3_START; + thru = aec.vbox.src3_thru << 5; + fs = aec.vbox.src3_fs; + } + + if (mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) { + start |= MCB_SRC3_TIM_START | MCB_ISRC3_START; + thru = aec.vbox.src3_thru << 5; + fs = aec.vbox.src3_fs; + } + + if (start && aec.vbox.src3_ctrl == 3) + mc_packet_add_write_mb(MCI_SRC3, (thru << 4) | fs); + mc_packet_add_write_mb(MCI_SRC3_START, start); + + start = 0; + if (mc_source_is_used(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0)) + start |= MCB_LP3_TIM_START | MCB_LPT3_START; + if (mc_d1_source_is_used(MCDRV_D1SRC_HIFIIN_ON)) + start |= MCB_LP3_TIM_START | MCB_LPR3_START; + if (start) { + mc_packet_add_write_a(MCI_LP3_FP, path_info.phys_port[3]); + if (id != MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_ma(MCI_LINK_LOCK, MCB_LINK_LOCK); + mc_packet_add_write_mb(MCI_T_DPLL_FAST, + MCB_T_DPLL_FAST | + MCB_VOLREL_TIME); + } + mc_packet_add_write_mb(MCI_LP3_START, start); + } +} + +void mc_packet_add_start(void) +{ + u32 src, hifi_src; + u8 val, dsf0, dsf1, dsf2; + + /* DIR*_START, DIT*_START */ + add_di_start(); + + /* ADC Start */ + dsf0 = mc_e_register_get_value(MCI_DSF0_FLT_TYPE); + dsf1 = mc_e_register_get_value(MCI_DSF1_FLT_TYPE); + dsf2 = mc_e_register_get_value(MCI_DSF2_FLT_TYPE); + hifi_src = mc_source_get(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0); + + if (mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH1)) { + dsf0 |= MCB_DSF0ENB; + val = mc_e_register_get_value(MCI_DSF0_PRE_INPUT); + if (val >> 4 == (val & 0x0f) + || !mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH1)) + dsf0 |= MCB_DSF0_MN; + else + dsf0 &= ~MCB_DSF0_MN; + } + mc_packet_add_write_e(MCI_DSF0_FLT_TYPE, dsf0); + + if (mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH1)) { + dsf1 |= MCB_DSF1ENB; + val = mc_e_register_get_value(MCI_DSF1_PRE_INPUT); + if (val >> 4 == (val & 0x0f) + || !mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH1)) + dsf1 |= MCB_DSF1_MN; + else + dsf1 &= ~MCB_DSF1_MN; + } + mc_packet_add_write_e(MCI_DSF1_FLT_TYPE, dsf1); + + if (mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH1)) { + dsf2 |= MCB_DSF2ENB; + src = mc_source_get(MCDRV_DST_ADIF2, MCDRV_DST_CH0); + if (src == MCDRV_D2SRC_DAC0REF_ON) { + dsf2 |= MCB_DSF2REFBACK; + dsf2 &= ~(MCB_DSF2REFSEL | MCB_DSF2_MN); + } else if (src == MCDRV_D2SRC_DAC1REF_ON) { + dsf2 |= MCB_DSF2REFBACK | MCB_DSF2REFSEL; + dsf2 &= ~MCB_DSF2_MN; + } else { + dsf2 &= ~MCB_DSF2REFBACK; + val = mc_e_register_get_value(MCI_DSF2_PRE_INPUT); + if (val >> 4 == (val & 0x0f) + || !mc_source_is_used(MCDRV_DST_ADIF2, + MCDRV_DST_CH1)) + dsf2 |= MCB_DSF2_MN; + else + dsf2 &= ~MCB_DSF2_MN; + } + } + mc_packet_add_write_e(MCI_DSF2_FLT_TYPE, dsf2); + + if (mc_dev_id_get() == MCDRV_DEV_ID_80_90H) { + if (mc_d1_source_is_used(MCDRV_D1SRC_HIFIIN_ON) || + mc_source_is_used(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0)) + mc_packet_add_write_e(MCI_DIRECTPATH_ENB, + MCB_DIRECTPATH_ENB); + } else { + val = 0; + if (mc_source_is_used(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0)) + val |= MCB_DIRECT_ENB_ADC; + + src = mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH0); + src |= mc_source_get(MCDRV_DST_DAC0, MCDRV_DST_CH1); + if (src & MCDRV_D1SRC_HIFIIN_ON) + val |= MCB_DIRECT_ENB_DAC0; + + src = mc_source_get(MCDRV_DST_DAC1, MCDRV_DST_CH0); + src |= mc_source_get(MCDRV_DST_DAC1, MCDRV_DST_CH1); + if (src & MCDRV_D1SRC_HIFIIN_ON) + val |= MCB_DIRECT_ENB_DAC1; + mc_packet_add_write_e(MCI_DIRECTPATH_ENB, val); + } + + /* PDM Start */ + val = mc_e_register_get_value(MCI_PDM_LOAD_TIM); + if (mc_d2_source_is_used(MCDRV_D2SRC_PDM0_L_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_PDM0_R_ON) + || (hifi_src & (MCDRV_D2SRC_PDM0_L_ON | MCDRV_D2SRC_PDM0_R_ON))) + val |= MCB_PDM0_START; + if (mc_d2_source_is_used(MCDRV_D2SRC_PDM1_L_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_PDM1_R_ON) + || (hifi_src & (MCDRV_D2SRC_PDM1_L_ON | MCDRV_D2SRC_PDM1_R_ON))) + val |= MCB_PDM1_START; + mc_packet_add_write_e(MCI_PDM_LOAD_TIM, val); +} + +static void add_digital_volume(u8 vol_l, u8 vol_r, u32 reg_type, u8 vol_l_addr, + u8 vsep, u8 vol_r_addr, + enum mcdrv_volume_mode mode) +{ + u8 val_l, val_r; + + val_l = mc_register_get_value(reg_type, vol_l_addr); + val_l &= ~vsep; + val_r = mc_register_get_value(reg_type, vol_r_addr); + + if (mode == MCDRV_VOLUME_MUTE) { + if (vol_l != MCDRV_REG_MUTE) + vol_l = val_l; + if (vol_r != MCDRV_REG_MUTE) + vol_r = val_r; + } + + if (vol_l == vol_r) { + if ((vol_l != val_l || vol_r != val_r) + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + mc_packet_add_force_write(reg_type | vol_l_addr, vol_l); + mc_register_set_value(reg_type, vol_r_addr, vol_r); + } + return; + } + + if (mode == MCDRV_VOLUME_MUTE) { + if (vol_l == MCDRV_REG_MUTE && vol_l != val_l) { + vol_l |= vsep; + mc_packet_add_force_write(reg_type | vol_l_addr, vol_l); + mc_packet_add_force_write(reg_type | vol_r_addr, val_r); + } else if (vol_r == MCDRV_REG_MUTE && vol_r != val_r) { + val_l |= vsep; + mc_packet_add_force_write(reg_type | vol_l_addr, val_l); + mc_packet_add_write(reg_type | vol_r_addr, vol_r); + } + return; + } + + if (vol_l == val_l) { + if (vol_r != val_r) { + val_l |= vsep; + mc_packet_add_force_write(reg_type | vol_l_addr, val_l); + mc_packet_add_write(reg_type | vol_r_addr, vol_r); + } + } else { + vol_l |= vsep; + mc_packet_add_write(reg_type | vol_l_addr, vol_l); + mc_packet_add_force_write(reg_type | vol_r_addr, vol_r); + } +} + +void mc_packet_add_volume(u32 update, enum mcdrv_volume_mode mode, u32 *status) +{ + struct mcdrv_dev_info info; + struct mcdrv_vol_info vol_info; + u8 val_l, val_r; + u8 vol_l, vol_r; + + mc_dev_info_get(&info); + mc_volume_info_get(&vol_info); + + if (update & MCDRV_VOLUPDATE_ANA_IN) { + vol_l = vol_info.a_line_in1[0]; + vol_r = vol_info.a_line_in1[1]; + + val_l = mc_ana_register_get_value(MCI_LIVOL_L); + val_l &= ~MCB_ALAT_LI; + val_r = mc_ana_register_get_value(MCI_LIVOL_R); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE + || vol_r == MCDRV_REG_MUTE)) + vol_l |= MCB_ALAT_LI; + mc_packet_add_write_ana(MCI_LIVOL_L, vol_l); + } + + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE || vol_r == MCDRV_REG_MUTE)) + mc_packet_add_write_ana(MCI_LIVOL_R, vol_r); + + vol_l = vol_info.a_mic1[0]; + val_l = mc_ana_register_get_value(MCI_MC1VOL); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) + mc_packet_add_write_ana(MCI_MC1VOL, vol_l); + + vol_l = vol_info.a_mic2[0]; + val_l = mc_ana_register_get_value(MCI_MC2VOL); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) + mc_packet_add_write_ana(MCI_MC2VOL, vol_l); + + vol_l = vol_info.a_mic3[0]; + val_l = mc_ana_register_get_value(MCI_MC3VOL); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) + mc_packet_add_write_ana(MCI_MC3VOL, vol_l); + + vol_l = vol_info.a_mic4[0]; + val_l = mc_ana_register_get_value(MCI_MC4VOL); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) + mc_packet_add_write_ana(MCI_MC4VOL, vol_l); + } + + if (update & MCDRV_VOLUPDATE_DIN0) + add_digital_volume(vol_info.d_music_in[0] & ~MCB_DIFI0_VSEP, + vol_info.d_music_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFI0_VOL0, + MCB_DIFI0_VSEP, MCI_DIFI0_VOL1, mode); + + if (update & MCDRV_VOLUPDATE_DIN1) + add_digital_volume(vol_info.d_ext_in[0] & ~MCB_DIFI1_VSEP, + vol_info.d_ext_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFI1_VOL0, + MCB_DIFI1_VSEP, MCI_DIFI1_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DIN2) + add_digital_volume(vol_info.d_voice_in[0] & ~MCB_DIFI2_VSEP, + vol_info.d_voice_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFI2_VOL0, + MCB_DIFI2_VSEP, MCI_DIFI2_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DIN3) + add_digital_volume(vol_info.d_ref_in[0] & ~MCB_DIFI3_VSEP, + vol_info.d_ref_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFI3_VOL0, + MCB_DIFI3_VSEP, MCI_DIFI3_VOL1, mode); + if (update & MCDRV_VOLUPDATE_ADIF0) + add_digital_volume(vol_info.d_adif0_in[0] & ~MCB_ADI0_VSEP, + vol_info.d_adif0_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_ADI0_VOL0, + MCB_ADI0_VSEP, MCI_ADI0_VOL1, mode); + if (update & MCDRV_VOLUPDATE_ADIF1) + add_digital_volume(vol_info.d_adif1_in[0] & ~MCB_ADI1_VSEP, + vol_info.d_adif1_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_ADI1_VOL0, + MCB_ADI1_VSEP, MCI_ADI1_VOL1, mode); + if (update & MCDRV_VOLUPDATE_ADIF2) + add_digital_volume(vol_info.d_adif2_in[0] & ~MCB_ADI2_VSEP, + vol_info.d_adif2_in[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_ADI2_VOL0, + MCB_ADI2_VSEP, MCI_ADI2_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DOUT0) + add_digital_volume(vol_info.d_music_out[0] & ~MCB_DIFO0_VSEP, + vol_info.d_music_out[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFO0_VOL0, + MCB_DIFO0_VSEP, MCI_DIFO0_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DOUT1) + add_digital_volume(vol_info.d_ext_out[0] & ~MCB_DIFO1_VSEP, + vol_info.d_ext_out[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFO1_VOL0, + MCB_DIFO1_VSEP, MCI_DIFO1_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DOUT2) + add_digital_volume(vol_info.d_voice_out[0] & ~MCB_DIFO2_VSEP, + vol_info.d_voice_out[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFO2_VOL0, + MCB_DIFO2_VSEP, MCI_DIFO2_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DOUT3) + add_digital_volume(vol_info.d_ref_out[0] & ~MCB_DIFO3_VSEP, + vol_info.d_ref_out[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DIFO3_VOL0, + MCB_DIFO3_VSEP, MCI_DIFO3_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DAC0) + add_digital_volume(vol_info.d_dac0_out[0] & ~MCB_DAO0_VSEP, + vol_info.d_dac0_out[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DAO0_VOL0, + MCB_DAO0_VSEP, MCI_DAO0_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DAC1) + add_digital_volume(vol_info.d_dac1_out[0] & ~MCB_DAO1_VSEP, + vol_info.d_dac1_out[1], + MCDRV_PACKET_REGTYPE_MA, + MCI_DAO1_VOL0, + MCB_DAO1_VSEP, MCI_DAO1_VOL1, mode); + if (update & MCDRV_VOLUPDATE_DPATHDA) + add_digital_volume(vol_info.d_dpath_da[0] & ~MCB_DPATH_DA_VSEP, + vol_info.d_dpath_da[1], + MCDRV_PACKET_REGTYPE_E, + MCI_DPATH_DA_VOL_L, + MCB_DPATH_DA_VSEP, MCI_DPATH_DA_VOL_R, mode); + if (update & MCDRV_VOLUPDATE_DIN) + add_digital_volume(vol_info.d_dpath_ad[0] & ~MCB_DPATH_AD_VSEP, + vol_info.d_dpath_ad[1], + MCDRV_PACKET_REGTYPE_E, + MCI_DPATH_AD_VOL_L, + MCB_DPATH_AD_VSEP, MCI_DPATH_AD_VOL_R, mode); + + if ((update & MCDRV_VOLUPDATE_ANA_OUT) && status != NULL) { + *status = 0; + + vol_l = vol_info.a_hp[0]; + vol_r = vol_info.a_hp[1]; + + val_l = mc_ana_register_get_value(MCI_HPVOL_L); + val_l &= ~MCB_ALAT_HP; + val_r = mc_ana_register_get_value(MCI_HPVOL_R); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE + || vol_r == MCDRV_REG_MUTE)) + vol_l |= MCB_ALAT_HP; + + mc_packet_add_write_ana(MCI_HPVOL_L, vol_l); + + if (vol_l == MCDRV_REG_MUTE) + *status |= MCB_HPL_BUSY << 8; + } + + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE || vol_r == MCDRV_REG_MUTE)) { + mc_packet_add_write_ana(MCI_HPVOL_R, vol_r); + if (vol_r == MCDRV_REG_MUTE) + *status |= MCB_HPR_BUSY << 8; + } + + vol_l = vol_info.a_sp[0]; + vol_r = vol_info.a_sp[1]; + + val_l = mc_ana_register_get_value(MCI_SPVOL_L); + val_l &= ~MCB_ALAT_SP; + val_r = mc_ana_register_get_value(MCI_SPVOL_R); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE + || vol_r == MCDRV_REG_MUTE)) + vol_l |= MCB_ALAT_SP; + + mc_packet_add_write_ana(MCI_SPVOL_L, vol_l); + + if (vol_l == MCDRV_REG_MUTE) + *status |= MCB_SPL_BUSY << 8; + } + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE || vol_r == MCDRV_REG_MUTE)) { + mc_packet_add_write_ana(MCI_SPVOL_R, vol_r); + if (vol_r == MCDRV_REG_MUTE) + *status |= MCB_SPR_BUSY << 8; + } + + vol_l = vol_info.a_rc[0]; + val_l = mc_ana_register_get_value(MCI_RCVOL); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + mc_packet_add_write_ana(MCI_RCVOL, vol_l); + if (vol_l == MCDRV_REG_MUTE) + *status |= MCB_RC_BUSY; + } + + vol_l = vol_info.a_line_out1[0]; + vol_r = vol_info.a_line_out1[1]; + val_l = mc_ana_register_get_value(MCI_LO1VOL_L); + val_l &= ~MCB_ALAT_LO1; + val_r = mc_ana_register_get_value(MCI_LO1VOL_R); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE + || vol_r == MCDRV_REG_MUTE)) + vol_l |= MCB_ALAT_LO1; + + mc_packet_add_write_ana(MCI_LO1VOL_L, vol_l); + + if (vol_l == MCDRV_REG_MUTE) + *status |= MCB_LO1L_BUSY; + } + + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE || vol_r == MCDRV_REG_MUTE)) { + mc_packet_add_write_ana(MCI_LO1VOL_R, vol_r); + if (vol_r == MCDRV_REG_MUTE) + *status |= MCB_LO1R_BUSY; + } + + vol_l = vol_info.a_line_out2[0]; + vol_r = vol_info.a_line_out2[1]; + val_l = mc_ana_register_get_value(MCI_LO2VOL_L); + val_l &= ~MCB_ALAT_LO2; + val_r = mc_ana_register_get_value(MCI_LO2VOL_R); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE || vol_l == MCDRV_REG_MUTE)) { + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE + || vol_r == MCDRV_REG_MUTE)) + vol_l |= MCB_ALAT_LO2; + + mc_packet_add_write_ana(MCI_LO2VOL_L, vol_l); + + if (vol_l == MCDRV_REG_MUTE) + *status |= MCB_LO2L_BUSY; + } + + if (vol_r != val_r + && (mode != MCDRV_VOLUME_MUTE || vol_r == MCDRV_REG_MUTE)) { + mc_packet_add_write_ana(MCI_LO2VOL_R, vol_r); + if (vol_r == MCDRV_REG_MUTE) + *status |= MCB_LO2R_BUSY; + } + + if (mc_dev_id_get() == MCDRV_DEV_ID_80_90H) { + vol_l = vol_info.a_hp_det[0]; + val_l = mc_ana_register_get_value(MCI_HPDETVOL); + if (vol_l != val_l + && (mode != MCDRV_VOLUME_MUTE + || vol_l == MCDRV_REG_MUTE)) + mc_packet_add_write_ana(MCI_HPDETVOL, vol_l); + } + } +} + +void mc_packet_add_dac0_mute(void) +{ + mc_packet_add_write_ana(MCI_HPVOL_L, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_HPVOL_R, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_RCVOL, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_LO1VOL_L, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_LO1VOL_R, MCDRV_REG_MUTE); +} + +void mc_packet_add_dac1_mute(void) +{ + mc_packet_add_write_ana(MCI_SPVOL_L, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_SPVOL_R, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_LO2VOL_L, MCDRV_REG_MUTE); + mc_packet_add_write_ana(MCI_LO2VOL_R, MCDRV_REG_MUTE); +} + +void mc_packet_add_dout_mute(void) +{ + mc_packet_add_write_ma(MCI_DIFO0_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO0_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO1_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO1_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO2_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO2_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO3_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DIFO3_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DAO0_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DAO0_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DAO1_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_DAO1_VOL1, MCDRV_REG_MUTE); +} + +void mc_packet_add_adif_mute(void) +{ + mc_packet_add_write_ma(MCI_ADI0_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_ADI0_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_ADI1_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_ADI1_VOL1, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_ADI2_VOL0, MCDRV_REG_MUTE); + mc_packet_add_write_ma(MCI_ADI2_VOL1, MCDRV_REG_MUTE); +} + +void mc_packet_add_dpath_da_mute(void) +{ + mc_packet_add_write_e(MCI_DPATH_DA_VOL_L, MCDRV_REG_MUTE); + mc_packet_add_write_e(MCI_DPATH_DA_VOL_R, MCDRV_REG_MUTE); +} + +static void add_dio_common(enum dio_port port) +{ + struct mcdrv_dio_info dio; + u8 val, offset; + + mc_dio_info_get(&dio); + + if (port == DIO_0) + offset = 0; + else if (port == DIO_1) + offset = MCI_LP1_MODE - MCI_LP0_MODE; + else if (port == DIO_2) + offset = MCI_LP2_MODE - MCI_LP0_MODE; + else + return; + + val = mc_mb_register_get_value(MCI_LP0_MODE + offset); + val = (val & 0x0c) + | dio.port[port].dit.st_mode << 7 + | dio.port[port].dio_common.auto_fs << 6 + | dio.port[port].dit.edge << 4; + if (dio.port[port].dio_common.master_slave == MCDRV_DIO_MASTER + && dio.port[port].dio_common.fs == MCDRV_FS_48000) { + if (mc_dev_id_get() == MCDRV_DEV_ID_80_90H) + val |= dio.port[port].dio_common.src_thru << 5; + } + + val |= dio.port[port].dio_common.interface; + mc_packet_add_write_mb(MCI_LP0_MODE + offset, val); + + val = dio.port[port].dio_common.bck_fs << 4 + | dio.port[port].dio_common.fs; + mc_packet_add_write_mb(MCI_LP0_BCK + offset, val); + + if (dio.port[port].dio_common.interface == MCDRV_DIO_PCM) { + val = dio.port[port].dio_common.pcm_hiz_transition << 7 + | dio.port[port].dio_common.pcm_frame << 5 + | dio.port[port].dio_common.pcm_high_period; + mc_packet_add_write_mb(MCI_LP0_PCM + offset, val); + } +} + +static void add_dio_dir(enum dio_port port) +{ + struct mcdrv_dio_info dio; + u8 val, offset; + + mc_dio_info_get(&dio); + + if (port == DIO_0) + offset = 0; + else if (port == DIO_1) + offset = MCI_LP1_MODE - MCI_LP0_MODE; + else if (port == DIO_2) + offset = MCI_LP2_MODE - MCI_LP0_MODE; + else + return; + + if (dio.port[port].dio_common.interface == MCDRV_DIO_DA) { + val = dio.port[port].dit.da_format.mode << 6 + | dio.port[port].dit.da_format.bit_sel << 4 + | dio.port[port].dir.da_format.mode << 2 + | dio.port[port].dir.da_format.bit_sel; + mc_packet_add_write_mb(MCI_LP0_FMT + offset, val); + } else { + val = dio.port[port].dir.pcm_format.mono << 7 + | dio.port[port].dir.pcm_format.order << 4 + | dio.port[port].dir.pcm_format.law << 2 + | dio.port[port].dir.pcm_format.bit_sel; + mc_packet_add_write_mb(MCI_LPR0_PCM + offset, val); + } +} + +static void add_dio_dit(enum dio_port port) +{ + struct mcdrv_dio_info dio; + u8 val, offset; + + mc_dio_info_get(&dio); + + if (port == DIO_0) + offset = 0; + else if (port == DIO_1) + offset = MCI_LP1_MODE - MCI_LP0_MODE; + else if (port == DIO_2) + offset = MCI_LP2_MODE - MCI_LP0_MODE; + else + return; + + if (dio.port[port].dio_common.interface == MCDRV_DIO_DA) { + val = dio.port[port].dit.da_format.mode << 6 + | dio.port[port].dit.da_format.bit_sel << 4 + | dio.port[port].dir.da_format.mode << 2 + | dio.port[port].dir.da_format.bit_sel; + mc_packet_add_write_mb(MCI_LP0_FMT + offset, val); + } else { + val = dio.port[port].dit.pcm_format.mono << 7 + | dio.port[port].dit.pcm_format.order << 4 + | dio.port[port].dit.pcm_format.law << 2 + | dio.port[port].dit.pcm_format.bit_sel; + mc_packet_add_write_mb(MCI_LPT0_PCM + offset, val); + } +} + +void mc_packet_add_digital_io(u32 update) +{ + struct mcdrv_aec_info aec; + struct mcdrv_dev_info dev; + struct mcdrv_dio_info dio; + u8 val, lport; + + mc_dev_info_get(&dev); + mc_aec_info_get(&aec); + + val = mc_if_register_get_value(MCI_RST); + if (val & (MCB_PSW_M | MCB_RST_M)) + return; + + val = mc_a_register_get_value(MCI_PD); + if (val & MCB_PM_CLK_PD) + return; + + mc_dio_info_get(&dio); + val = mc_a_register_get_value(MCI_DO0_DRV); + lport = get_logical_port(MCDRV_PHYSPORT_DIO0); + if (lport <= 3) { + if (dio.port[lport].dio_common.bck_invert == MCDRV_BCLK_INVERT) + val |= MCB_BCLK0_INV; + else + val &= ~MCB_BCLK0_INV; + } + if (dev.power_mode != MCDRV_POWMODE_CDSPDEBUG + && aec.vbox.cdsp_jtag_on != 1) + mc_packet_add_write_a(MCI_DO0_DRV, val); + + val = mc_a_register_get_value(MCI_DO1_DRV); + lport = get_logical_port(MCDRV_PHYSPORT_DIO1); + if (lport <= 3) { + if (dio.port[lport].dio_common.bck_invert == MCDRV_BCLK_INVERT) + val |= MCB_BCLK1_INV; + else + val &= ~MCB_BCLK1_INV; + } + if (dev.power_mode != MCDRV_POWMODE_CDSPDEBUG + && aec.vbox.cdsp_jtag_on != 1) + mc_packet_add_write_a(MCI_DO1_DRV, val); + + lport = get_logical_port(MCDRV_PHYSPORT_DIO2); + if (lport <= 3) { + if (dio.port[lport].dio_common.bck_invert == MCDRV_BCLK_INVERT) + val |= MCB_BCLK2_INV; + else + val &= ~MCB_BCLK2_INV; + } + mc_packet_add_write_a(MCI_DO2_DRV, val); + + if (update & MCDRV_MUSIC_COM_UPDATE_FLAG) + add_dio_common(DIO_0); + + if (update & MCDRV_MUSIC_DIR_UPDATE_FLAG) + add_dio_dir(DIO_0); + + if (update & MCDRV_MUSIC_DIT_UPDATE_FLAG) + add_dio_dit(DIO_0); + + if (update & MCDRV_EXT_COM_UPDATE_FLAG) + add_dio_common(DIO_1); + + if (update & MCDRV_EXT_DIR_UPDATE_FLAG) + add_dio_dir(DIO_1); + + if (update & MCDRV_EXT_DIT_UPDATE_FLAG) + add_dio_dit(DIO_1); + + if (update & MCDRV_VOICE_COM_UPDATE_FLAG) + add_dio_common(DIO_2); + + if (update & MCDRV_VOICE_DIR_UPDATE_FLAG) + add_dio_dir(DIO_2); + + if (update & MCDRV_VOICE_DIT_UPDATE_FLAG) + add_dio_dit(DIO_2); + + if ((update & MCDRV_HIFI_DIR_UPDATE_FLAG) + || (update & MCDRV_HIFI_DIT_UPDATE_FLAG)) { + val = dio.port[DIO_3].dit.st_mode << 7 + | dio.port[DIO_3].dit.edge << 4; + mc_packet_add_write_mb(MCI_LPT3_STMODE, val); + } + + if (update & MCDRV_HIFI_COM_UPDATE_FLAG) { + val = dio.port[DIO_3].dio_common.bck_fs << 4 + | dio.port[DIO_3].dio_common.fs; + mc_packet_add_write_mb(MCI_LP3_BCK, val); + } + + if ((update & MCDRV_HIFI_DIR_UPDATE_FLAG) + || (update & MCDRV_HIFI_DIT_UPDATE_FLAG)) { + if (dio.port[DIO_3].dio_common.interface == MCDRV_DIO_DA) { + val = dio.port[DIO_3].dit.da_format.mode << 6 + | dio.port[DIO_3].dit.da_format.bit_sel << 4 + | dio.port[DIO_3].dir.da_format.mode << 2 + | dio.port[DIO_3].dir.da_format.bit_sel; + mc_packet_add_write_mb(MCI_LP3_FMT, val); + } + } +} + +void mc_packet_add_digital_io_path(void) +{ + struct mcdrv_dio_path_info path_info; + u8 val; + + val = mc_if_register_get_value(MCI_RST); + if (val & (MCB_PSW_M | MCB_RST_M)) + return; + + val = mc_a_register_get_value(MCI_PD); + if (val & MCB_PM_CLK_PD) + return; + + mc_dio_path_info_get(&path_info); + + val = mc_if_register_get_value(MCI_RST); + if (path_info.phys_port[0] >= 4 || path_info.phys_port[1] >= 4 + || path_info.phys_port[2] >= 4 || path_info.phys_port[3] >= 4) { + if (val & MCB_PSW_S) { + val &= MCB_PSW_S; + mc_packet_add_write_if(MCI_RST, val); + + mc_packet_add_wait_event(MCDRV_EVT_PSW_RESET | + (MCI_RST << 8) | MCB_PSW_S); + + val &= ~MCB_RST_S; + mc_packet_add_write_if(MCI_RST, val); + } + } else { + if (!(val & MCB_PSW_S)) { + val |= MCB_RST_S; + mc_packet_add_write_if(MCI_RST, val); + val |= MCB_PSW_S; + mc_packet_add_write_if(MCI_RST, val); + } + } + + val = mc_mb_register_get_value(MCI_LP0_MODE); + val &= MCB_LP0_STMODE | MCB_LP0_AUTO_FS | MCB_LP0_SRC_THRU + | MCB_LPT0_EDGE | MCB_LP0_MODE; + val |= path_info.music_ch << 2; + mc_packet_add_write_mb(MCI_LP0_MODE, val); + + val = path_info.music_rslot[0] + | path_info.music_rslot[1] << 2 | path_info.music_rslot[2] << 4; + mc_packet_add_write_mb(MCI_LPR0_SLOT, val); + + val = path_info.music_tslot[0] + | path_info.music_tslot[1] << 2 | path_info.music_tslot[2] << 4; + mc_packet_add_write_mb(MCI_LPT0_SLOT, val); +} + +void mc_packet_add_switch_clock(u8 clock) +{ + struct mcdrv_dev_info info; + struct mcdrv_hsdet_info hsdet; + u8 val, mask; + + mc_dev_info_get(&info); + mc_hsdet_info_get(&hsdet); + + val = mc_a_register_get_value(MCI_PD); + if ((val & MCB_PLL_PD) != MCB_PLL_PD) { + val = mc_a_register_get_value(MCI_CLK_MSK); + if (clock == MCDRV_CLKSW_CLKA) { + /* CLKB->CLKA */ + if (info.clk_input == MCDRV_CKINPUT_CLKI0_CLKI1 + || info.clk_input == MCDRV_CKINPUT_CLKI0_RTCK + || info.clk_input == MCDRV_CKINPUT_CLKI0_SBCK) + val &= ~MCB_CLKI0_MSK; + else if (info.clk_input == MCDRV_CKINPUT_CLKI1_CLKI0 + || info.clk_input == MCDRV_CKINPUT_CLKI1_RTCK + || info.clk_input == MCDRV_CKINPUT_CLKI1_SBCK) + val &= ~MCB_CLKI1_MSK; + else + val &= ~MCB_RTCI_MSK; + mc_packet_add_write_a(MCI_CLK_MSK, val); + + val = mc_a_register_get_value(MCI_CLKSRC); + if (val & MCB_CLK_INPUT) + val |= MCB_CLKSRC; + else + val &= ~MCB_CLKSRC; + mc_packet_add_write_a(MCI_CLKSRC, val); + + mc_packet_add_wait_event(MCDRV_EVT_CLKBUSY_RESET); + + val = MCI_CLK_MSK_DEF; + if (info.clk_input == MCDRV_CKINPUT_CLKI0_CLKI1 + || info.clk_input == MCDRV_CKINPUT_CLKI0_RTCK + || info.clk_input == MCDRV_CKINPUT_CLKI0_SBCK) + val &= ~MCB_CLKI0_MSK; + else if (info.clk_input == MCDRV_CKINPUT_CLKI1_CLKI0 + || info.clk_input == MCDRV_CKINPUT_CLKI1_RTCK + || info.clk_input == MCDRV_CKINPUT_CLKI1_SBCK) + val &= ~MCB_CLKI1_MSK; + else + val &= ~MCB_RTCI_MSK; + mc_packet_add_write_a(MCI_CLK_MSK, val); + mask = val; + } else { + /* CLKA->CLKB */ + if (info.clk_input == MCDRV_CKINPUT_CLKI1_CLKI0 + || info.clk_input == MCDRV_CKINPUT_RTC_CLKI0 + || info.clk_input == MCDRV_CKINPUT_SBCK_CLKI0) + val &= ~MCB_CLKI0_MSK; + else if (info.clk_input == MCDRV_CKINPUT_CLKI0_CLKI1 + || info.clk_input == MCDRV_CKINPUT_RTC_CLKI1 + || info.clk_input == MCDRV_CKINPUT_SBCK_CLKI1) + val &= ~MCB_CLKI1_MSK; + else + val &= ~MCB_RTCI_MSK; + mc_packet_add_write_a(MCI_CLK_MSK, val); + + val = mc_a_register_get_value(MCI_CLKSRC); + if (!(val & MCB_CLK_INPUT)) + val |= MCB_CLKSRC; + else + val &= ~MCB_CLKSRC; + mc_packet_add_write_a(MCI_CLKSRC, val); + + mc_packet_add_wait_event(MCDRV_EVT_CLKBUSY_RESET); + + val = MCI_CLK_MSK_DEF; + if (info.clk_input == MCDRV_CKINPUT_CLKI1_CLKI0 + || info.clk_input == MCDRV_CKINPUT_RTC_CLKI0 + || info.clk_input == MCDRV_CKINPUT_SBCK_CLKI0) + val &= ~MCB_CLKI0_MSK; + else if (info.clk_input == MCDRV_CKINPUT_CLKI0_CLKI1 + || info.clk_input == MCDRV_CKINPUT_RTC_CLKI1 + || info.clk_input == MCDRV_CKINPUT_SBCK_CLKI1) + val &= ~MCB_CLKI1_MSK; + else + val &= ~MCB_RTCI_MSK; + mc_packet_add_write_a(MCI_CLK_MSK, val); + mask = val; + } + + val = mc_cd_register_get_value(MCI_CKSEL); + if (mc_dev_id_get() == MCDRV_DEV_ID_80_90H) { + if (!(mask & MCB_RTCI_MSK)) + val &= ~MCB_HSDET; + else if (hsdet.en_plug_det_db == MCDRV_PLUGDETDB_DISABLE + && hsdet.en_dly_key_off == MCDRV_KEYEN_D_D_D + && hsdet.en_dly_key_on == MCDRV_KEYEN_D_D_D + && hsdet.en_mic_det == MCDRV_MICDET_DISABLE + && hsdet.en_key_off == MCDRV_KEYEN_D_D_D + && hsdet.en_key_on == MCDRV_KEYEN_D_D_D) + val |= MCB_HSDET; + } else { + if (!(mask & MCB_RTCI_MSK)) + val &= ~MCB_CRTC; + else + val |= MCB_CRTC; + } + mc_packet_add_write_cd(MCI_CKSEL, val); + } else { + val = mc_a_register_get_value(MCI_CLKSRC); + if (clock == MCDRV_CLKSW_CLKA) { + if (val & MCB_CLKSRC) + val |= MCB_CLK_INPUT; + else + val &= ~MCB_CLK_INPUT; + } else { + if (!(val & MCB_CLKSRC)) + val |= MCB_CLK_INPUT; + else + val &= ~MCB_CLK_INPUT; + } + mc_packet_add_write_a(MCI_CLKSRC, val); + } +} + +void mc_packet_add_swap(u32 update) +{ + struct mcdrv_swap_info info; + u8 val; + + val = mc_if_register_get_value(MCI_RST); + if (val & (MCB_PSW_M | MCB_RST_M)) + return; + + val = mc_a_register_get_value(MCI_PD); + if (val & MCB_PM_CLK_PD) + return; + + mc_swap_info_get(&info); + + val = mc_ma_register_get_value(MCI_ADI_SWAP); + if (update & MCDRV_SWAP_ADIF0_UPDATE_FLAG) + val = (val & 0xf0) | info.adif0; + if (update & MCDRV_SWAP_ADIF1_UPDATE_FLAG) + val = (val & 0x0f) | info.adif1 << 4; + mc_packet_add_write_ma(MCI_ADI_SWAP, val); + + if (update & MCDRV_SWAP_ADIF2_UPDATE_FLAG) + mc_packet_add_write_ma(MCI_ADI2_SWAP, info.adif2); + + val = mc_ma_register_get_value(MCI_DAO_SWAP); + if (update & MCDRV_SWAP_DAC0_UPDATE_FLAG) + val = (val & 0xf0) | info.dac0; + if (update & MCDRV_SWAP_DAC1_UPDATE_FLAG) + val = (val & 0x0f) | info.dac1 << 4; + mc_packet_add_write_ma(MCI_DAO_SWAP, val); + + val = mc_mb_register_get_value(MCI_LPR0_SWAP); + if (update & MCDRV_SWAP_MUSICIN0_UPDATE_FLAG) + val = (val & ~0x03) | info.music_in0; + if (update & MCDRV_SWAP_MUSICIN1_UPDATE_FLAG) + val = (val & ~0x0c) | info.music_in1 << 2; + if (update & MCDRV_SWAP_MUSICIN2_UPDATE_FLAG) + val = (val & ~0x30) | info.music_in2 << 4; + mc_packet_add_write_mb(MCI_LPR0_SWAP, val); + + val = mc_mb_register_get_value(MCI_LPT0_SWAP); + if (update & MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG) + val = (val & ~0x07) | info.music_out0; + if (update & MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG) + val = (val & ~0x18) | info.music_out1 << 3; + if (update & MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG) + val = (val & ~0x60) | info.music_out2 << 5; + mc_packet_add_write_mb(MCI_LPT0_SWAP, val); + + if (update & MCDRV_SWAP_EXTIN_UPDATE_FLAG) + mc_packet_add_write_mb(MCI_LPR1_SWAP, info.ext_in); + + if (update & MCDRV_SWAP_EXTOUT_UPDATE_FLAG) + mc_packet_add_write_mb(MCI_LPT1_SWAP, info.ext_out); + + if (update & MCDRV_SWAP_VOICEIN_UPDATE_FLAG) + mc_packet_add_write_mb(MCI_LPR2_SWAP, info.voice_in); + + if (update & MCDRV_SWAP_VOICEOUT_UPDATE_FLAG) + mc_packet_add_write_mb(MCI_LPT2_SWAP, info.voice_out); + + if (update & MCDRV_SWAP_HIFIIN_UPDATE_FLAG) + mc_packet_add_write_mb(MCI_LPR3_SWAP, info.hifi_in); + + if (update & MCDRV_SWAP_HIFIOUT_UPDATE_FLAG) + mc_packet_add_write_mb(MCI_LPT3_SWAP, info.hifi_out); +} + +void mc_packet_add_hsdet(void) +{ + struct mcdrv_dev_info info; + struct mcdrv_hsdet_info hsdet; + enum mcdrv_dev_id id; + u8 val, mask, data[2]; + + id = mc_dev_id_get(); + mc_dev_info_get(&info); + mc_hsdet_info_get(&hsdet); + + if (hsdet.en_plug_det_db == MCDRV_PLUGDETDB_DISABLE + && hsdet.en_dly_key_off == MCDRV_KEYEN_D_D_D + && hsdet.en_dly_key_on == MCDRV_KEYEN_D_D_D + && hsdet.en_mic_det == MCDRV_MICDET_DISABLE + && hsdet.en_key_off == MCDRV_KEYEN_D_D_D + && hsdet.en_key_on == MCDRV_KEYEN_D_D_D) { + mc_packet_add_write_cd(MCI_IRQHS, 0); + mc_packet_add_write_cd(MCI_EPLUGDET, hsdet.en_plug_det << 7); + mc_packet_add_write_cd(MCI_EDLYKEY, 0); + mc_packet_add_write_cd(MCI_EMICDET, 0); + mc_packet_add_write_cd(MCI_HSDETEN, hsdet.hs_det_dbnc); + mc_packet_add_write_ana(MCI_KDSET, info.mbs_disch << 4); + val = mc_cd_register_get_value(MCI_CKSEL); + val &= ~MCB_CKSEL0; + if (id == MCDRV_DEV_ID_80_90H) { + mask = mc_a_register_get_value(MCI_CLK_MSK); + if (mask & MCB_RTCI_MSK) + val |= MCB_HSDET; + } else + val |= MCB_HSDET; + mc_packet_add_write_cd(MCI_CKSEL, val); + mc_packet_add_write_cd(MCI_DP_OSC, MCB_DP_OSC); + } else { + if (hsdet.en_plug_det_db != MCDRV_PLUGDETDB_DISABLE + || hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D + || hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D + || hsdet.en_mic_det != MCDRV_MICDET_DISABLE + || hsdet.en_key_off != MCDRV_KEYEN_D_D_D + || hsdet.en_key_on != MCDRV_KEYEN_D_D_D) { + val = mc_cd_register_get_value(MCI_HSDETEN); + if (!(val & MCB_HSDETEN)) { + if (info.hsdet_clk == MCDRV_HSDETCLK_OSC) { + mc_packet_add_write_cd(MCI_DP_OSC, 0); + mc_packet_add_wait(MCDRV_OSC_WAIT_TIME); + } + mc_packet_add_write_cd(MCI_HSDETEN, + hsdet.hs_det_dbnc); + mc_packet_add_write_cd(MCI_HSDETMODE, + hsdet.hs_det_mode); + val = hsdet.speriod << 3 | MCB_DBNC_LPERIOD; + mc_packet_add_write_cd(MCI_DBNC_PERIOD, val); + + val = hsdet.dbnc_num_plug << 4 + | hsdet.dbnc_num_mic << 2 + | hsdet.dbnc_num_key; + mc_packet_add_write_cd(MCI_DBNC_NUM, val); + + val = hsdet.key_off_mtim << 1 + | hsdet.key_on_mtim; + if (id != MCDRV_DEV_ID_80_90H) + val |= MCI_KEY_MTIM_DEF; + mc_packet_add_write_cd(MCI_KEY_MTIM, val); + + val = hsdet.key0_on_dly_tim2 << 4 + | hsdet.key0_on_dly_tim; + mc_packet_add_write_cd(MCI_KEYONDLYTIM_K0, val); + mc_packet_add_write_cd(MCI_KEYOFFDLYTIM_K0, + hsdet.key0_off_dly_tim); + val = + hsdet.key1_on_dly_tim2 << 4 | + hsdet.key1_on_dly_tim; + mc_packet_add_write_cd(MCI_KEYONDLYTIM_K1, val); + mc_packet_add_write_cd(MCI_KEYOFFDLYTIM_K1, + hsdet.key1_off_dly_tim); + val = + hsdet.key2_on_dly_tim2 << 4 | + hsdet.key2_on_dly_tim; + mc_packet_add_write_cd(MCI_KEYONDLYTIM_K2, val); + mc_packet_add_write_cd(MCI_KEYOFFDLYTIM_K2, + hsdet.key2_off_dly_tim); + + val = mc_cd_register_get_value(MCI_CKSEL); + val &= ~MCB_HSDET; + if (info.hsdet_clk == MCDRV_HSDETCLK_OSC) + val |= MCB_CKSEL0; + mc_packet_add_write_cd(MCI_CKSEL, val); + } + } + mc_packet_add_write_cd(MCI_IRQHS, MCB_EIRQHS); + + val = hsdet.en_plug_det << 7 | hsdet.en_plug_det_db; + mc_packet_add_write_cd(MCI_EPLUGDET, val); + + val = hsdet.en_dly_key_off << 3 | hsdet.en_dly_key_on; + mc_packet_add_write_cd(MCI_EDLYKEY, val); + + val = hsdet.en_mic_det << 6 | hsdet.en_key_off << 3 + | hsdet.en_key_on; + mc_packet_add_write_cd(MCI_EMICDET, val); + mc_packet_add_write_if(MCI_IRQR, MCB_EIRQR); + } + + if (id == MCDRV_DEV_ID_80_90H) + mc_packet_add_write_cd(MCI_IRQTYPE, hsdet.irq_type); + else { + if (hsdet.irq_type == MCDRV_IRQTYPE_NORMAL) + val = 0; + else if (hsdet.irq_type == MCDRV_IRQTYPE_REF) + val = MCI_IRQTYPE_DEF; + else + val = hsdet.plug_det_irq_type << 7 + | hsdet.mic_det_irq_type << 6 + | hsdet.plug_undet_db_irq_type << 1 + | hsdet.plug_det_db_irq_type; + mc_packet_add_write_cd(MCI_IRQTYPE, val); + } + mc_packet_add_write_cd(MCI_DLYIRQSTOP, hsdet.dly_irq_stop); + + val = hsdet.det_in_inv; + if (id != MCDRV_DEV_ID_80_90H) { + if (hsdet.irq_type == MCDRV_IRQTYPE_EX) + val |= hsdet.key2_on_irq_type << 7 + | hsdet.key1_on_irq_type << 6 + | hsdet.key0_on_irq_type << 5; + else + val |= hsdet.irq_type << 7 + | hsdet.irq_type << 6 | hsdet.irq_type << 5; + } + mc_packet_add_write_cd(MCI_DETIN_INV, val); + + if (id != MCDRV_DEV_ID_80_90H) { + data[0] = MCI_CD_REG_A << 1; + data[1] = MCI_IRQM_KEYOFF; + mc_write_analog(data, 2); + mc_read_analog(MCI_CD_REG_D, &val, 1); + val &= 0x1; + if (hsdet.irq_type == MCDRV_IRQTYPE_EX) + val |= hsdet.key2_off_irq_type << 7 + | hsdet.key1_off_irq_type << 6 + | hsdet.key0_off_irq_type << 5; + else + val |= hsdet.irq_type << 7 | hsdet.irq_type << 6 + | hsdet.irq_type << 5; + mc_packet_add_write_cd(MCI_IRQM_KEYOFF, val); + } + + mc_packet_add_write_cd(MCI_HSDETMODE, hsdet.hs_det_mode); + + val = hsdet.speriod << 3 | MCB_DBNC_LPERIOD; + mc_packet_add_write_cd(MCI_DBNC_PERIOD, val); + + val = hsdet.dbnc_num_plug << 4 | hsdet.dbnc_num_mic << 2 + | hsdet.dbnc_num_key; + mc_packet_add_write_cd(MCI_DBNC_NUM, val); + + val = hsdet.key_off_mtim << 1 | hsdet.key_on_mtim; + if (id != MCDRV_DEV_ID_80_90H) + val |= MCI_KEY_MTIM_DEF; + mc_packet_add_write_cd(MCI_KEY_MTIM, val); + + val = hsdet.key0_on_dly_tim2 << 4 | hsdet.key0_on_dly_tim; + mc_packet_add_write_cd(MCI_KEYONDLYTIM_K0, val); + mc_packet_add_write_cd(MCI_KEYOFFDLYTIM_K0, hsdet.key0_off_dly_tim); + + val = hsdet.key1_on_dly_tim2 << 4 | hsdet.key1_on_dly_tim; + mc_packet_add_write_cd(MCI_KEYONDLYTIM_K1, val); + mc_packet_add_write_cd(MCI_KEYOFFDLYTIM_K1, hsdet.key1_off_dly_tim); + + val = hsdet.key2_on_dly_tim2 << 4 | hsdet.key2_on_dly_tim; + mc_packet_add_write_cd(MCI_KEYONDLYTIM_K2, val); + mc_packet_add_write_cd(MCI_KEYOFFDLYTIM_K2, hsdet.key2_off_dly_tim); +} + +void mc_packet_add_mic_key_detect_enable(bool check_plug_det_db) +{ + struct mcdrv_hsdet_info hsdet; + u8 val; + + if (check_plug_det_db) { + val = mc_plug_detect_db_get(); + if (!(val & MCB_RPLUGDET_DB)) + return; + } + + mc_hsdet_info_get(&hsdet); + + val = mc_ana_register_get_value(MCI_AP); + val &= ~MCB_AP_BGR; + mc_packet_add_write_ana(MCI_AP, val); + + val = mc_ana_register_get_value(MCI_KDSET); + val = (val & ~MCB_KDSET2) | MCB_KDSET1; + mc_packet_add_force_write_ana(MCI_KDSET, val); + + mc_packet_add_wait(2000); + + val &= ~MCB_KDSET1; + mc_packet_add_force_write_ana(MCI_KDSET, val); + + val |= MCB_KDSET2; + mc_packet_add_force_write_ana(MCI_KDSET, val); + + mc_packet_add_wait(4000); + + val = MCB_HSDETEN | MCB_MKDETEN | hsdet.hs_det_dbnc; + mc_packet_add_write_cd(MCI_HSDETEN, val); +} + +void mc_packet_add_aec(void) +{ + struct mcdrv_aec_info aec; + u8 val; + + mc_aec_info_get(&aec); + + if (aec.vbox.cdsp_jtag_on == 1) { + mc_packet_add_write_a(MCI_DO0_DRV, 0x01); + mc_packet_add_write_a(MCI_DO1_DRV, 0x22); + } + + if (!aec.fdsp_locate) + val = MCB_FDSP_PI_SOURCE_AE; + else + val = MCB_FDSP_EX_SYNC | MCB_FDSP_PI_SOURCE_VDSP_EX; + mc_packet_add_write_ma(MCI_FDSP_PI_SOURCE, val); + mc_packet_add_write_ma(MCI_FDSP_PO_SOURCE, aec.vbox.fdsp_po_source); + + val = aec.audio_engine.mixer_in3_src << 7 + | aec.audio_engine.mixer_in2_src << 6 + | aec.audio_engine.mixer_in1_src << 5 + | aec.audio_engine.mixer_in0_src << 4 + | aec.audio_engine.bdsp_ae1_src << 1 + | aec.audio_engine.bdsp_ae0_src; + mc_packet_add_write_ma(MCI_BDSP_SOURCE, val); + + val = aec.vbox.lpt2_vsource << 5 + | aec.vbox.isrc3_vsource << 4 + | aec.vbox.isrc2_ch1_vsource << 3 + | aec.vbox.isrc2_vsource << 2 | aec.vbox.src3_ctrl; + mc_packet_add_write_ma(MCI_SRC_VSOURCE, val); + + val = aec.vbox.lpt2_mix_vol_o << 4 | aec.vbox.lpt2_mix_vol_i; + mc_packet_add_write_ma(MCI_LPT2_MIX_VOL, val); + + val = mc_a_register_get_value(MCI_PCMOUT_HIZ); + val = (val & (MCB_PCMOUT2_HIZ | MCB_PCMOUT1_HIZ | MCB_PCMOUT0_HIZ)) + | aec.pdm.pdm1_data_delay << 5 | aec.pdm.pdm0_data_delay << 4; + mc_packet_add_write_a(MCI_PCMOUT_HIZ, val); + + e_registers_setup(); + + val = aec.output.dng_release << 4 | aec.output.dng_attack; + if (mc_dev_id_get() == MCDRV_DEV_ID_80_90H) { + mc_packet_add_write_ana(MCI_DNG_ES1, val); + mc_packet_add_write_ana(MCI_DNG_HP_ES1, + aec.output.dng_target[0]); + mc_packet_add_write_ana(MCI_DNG_SP_ES1, + aec.output.dng_target[1]); + mc_packet_add_write_ana(MCI_DNG_RC_ES1, + aec.output.dng_target_rc); + mc_packet_add_write_ana(MCI_DNG_LO1_ES1, + aec.output.dng_target_lineout[0]); + mc_packet_add_write_ana(MCI_DNG_LO2_ES1, + aec.output.dng_target_lineout[1]); + } else { + mc_packet_add_write_ana(MCI_DNG, val); + mc_packet_add_write_ana(MCI_DNG_HP, aec.output.dng_target[0]); + mc_packet_add_write_ana(MCI_DNG_SP, aec.output.dng_target[1]); + mc_packet_add_write_ana(MCI_DNG_RC, aec.output.dng_target_rc); + mc_packet_add_write_ana(MCI_DNG_LO1, + aec.output.dng_target_lineout[0]); + mc_packet_add_write_ana(MCI_DNG_LO2, + aec.output.dng_target_lineout[1]); + } +} + +void mc_packet_add_gp_mode(void) +{ + struct mcdrv_dev_info info; + struct mcdrv_gp_mode gp_mode; + u8 val; + + mc_dev_info_get(&info); + mc_gp_mode_get(&gp_mode); + + if (info.pa0_func == MCDRV_PA_GPIO) { + val = mc_a_register_get_value(MCI_PA0); + if (gp_mode.gp_ddr[0] == MCDRV_GPDDR_IN) + val &= ~MCB_PA0_DDR; + else + val |= MCB_PA0_DDR; + + if (gp_mode.gp_host[0] == MCDRV_GPHOST_CPU) + val &= ~MCB_PA0_OUTSEL; + else + val |= MCB_PA0_OUTSEL; + + if (gp_mode.gp_invert[0] == MCDRV_GPINV_NORMAL) + val &= ~MCB_PA0_INV; + else + val |= MCB_PA0_INV; + mc_packet_add_write_a(MCI_PA0, val); + } + + if (info.pa1_func == MCDRV_PA_GPIO) { + val = mc_a_register_get_value(MCI_PA1); + if (gp_mode.gp_ddr[1] == MCDRV_GPDDR_IN) + val &= ~MCB_PA1_DDR; + else + val |= MCB_PA1_DDR; + + if (gp_mode.gp_host[1] == MCDRV_GPHOST_CPU) + val &= ~MCB_PA1_OUTSEL; + else + val |= MCB_PA1_OUTSEL; + + if (gp_mode.gp_invert[1] == MCDRV_GPINV_NORMAL) + val &= ~MCB_PA1_INV; + else + val |= MCB_PA1_INV; + mc_packet_add_write_a(MCI_PA1, val); + } + + if (info.pa2_func == MCDRV_PA_GPIO) { + val = mc_a_register_get_value(MCI_PA2); + if (gp_mode.gp_ddr[2] == MCDRV_GPDDR_IN) + val &= ~MCB_PA2_DDR; + else + val |= MCB_PA2_DDR; + + if (gp_mode.gp_host[2] == MCDRV_GPHOST_CPU) + val &= ~MCB_PA2_OUTSEL; + else + val |= MCB_PA2_OUTSEL; + + if (gp_mode.gp_invert[2] == MCDRV_GPINV_NORMAL) + val &= ~MCB_PA2_INV; + else + val |= MCB_PA2_INV; + mc_packet_add_write_a(MCI_PA2, val); + } +} + +void mc_packet_add_gp_set(u32 pad_no) +{ + struct mcdrv_dev_info info; + struct mcdrv_gp_mode gp_mode; + u8 val; + + mc_dev_info_get(&info); + mc_gp_mode_get(&gp_mode); + + switch (pad_no) { + case 0: + if (info.pa0_func == MCDRV_PA_GPIO + && gp_mode.gp_ddr[0] == MCDRV_GPDDR_OUT + && gp_mode.gp_host[0] == MCDRV_GPHOST_CPU) { + val = mc_a_register_get_value(MCI_PA0); + val = val & ~MCB_PA0_DATA; + val |= mc_gp_pad_get(pad_no) << 4; + mc_packet_add_write_a(MCI_PA0, val); + } + break; + case 1: + if (info.pa1_func == MCDRV_PA_GPIO + && gp_mode.gp_ddr[1] == MCDRV_GPDDR_OUT + && gp_mode.gp_host[1] == MCDRV_GPHOST_CPU) { + val = mc_a_register_get_value(MCI_PA1); + val &= ~MCB_PA1_DATA; + val |= mc_gp_pad_get(pad_no) << 4; + mc_packet_add_write_a(MCI_PA1, val); + } + break; + case 2: + if (info.pa2_func == MCDRV_PA_GPIO + && gp_mode.gp_ddr[2] == MCDRV_GPDDR_OUT + && gp_mode.gp_host[2] == MCDRV_GPHOST_CPU) { + val = mc_a_register_get_value(MCI_PA2); + val &= ~MCB_PA2_DATA; + val |= mc_gp_pad_get(pad_no) << 4; + mc_packet_add_write_a(MCI_PA2, val); + } + break; + default: + break; + } +} diff --git a/sound/soc/codecs/ymu831/mcpacking.h b/sound/soc/codecs/ymu831/mcpacking.h new file mode 100644 index 0000000..e5a2e62 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcpacking.h @@ -0,0 +1,217 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcpacking.h + * Description : MC device control packet packing driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + * - some definitions move from mcdevif.h + */ +#ifndef _MCPACKING_H +#define _MCPACKING_H + +#include <linux/types.h> + +/* packet type */ +#define MCDRV_PACKET_TYPE_WRITE 0x10000000U +#define MCDRV_PACKET_TYPE_FORCE_WRITE 0x20000000U +#define MCDRV_PACKET_TYPE_TIMWAIT 0x30000000U +#define MCDRV_PACKET_TYPE_EVTWAIT 0x40000000U +#define MCDRV_PACKET_TYPE_TERMINATE 0xF0000000U +#define MCDRV_PACKET_TYPE_MASK 0xF0000000U + +/* register type */ +#define MCDRV_PACKET_REGTYPE_IF 0x0000U +#define MCDRV_PACKET_REGTYPE_A 0x1000U +#define MCDRV_PACKET_REGTYPE_MA 0x2000U +#define MCDRV_PACKET_REGTYPE_MB 0x3000U +#define MCDRV_PACKET_REGTYPE_B 0x4000U +#define MCDRV_PACKET_REGTYPE_E 0x5000U +#define MCDRV_PACKET_REGTYPE_C 0x6000U +#define MCDRV_PACKET_REGTYPE_F 0x7000U +#define MCDRV_PACKET_REGTYPE_ANA 0x8000U +#define MCDRV_PACKET_REGTYPE_CD 0x9000U +#define MCDRV_PACKET_REGTYPE_MASK 0xF000U +#define MCDRV_PACKET_ADR_MASK 0x0FFFU + +/* event */ +#define MCDRV_EVT_SVOL_DONE 0x00010000U +#define MCDRV_EVT_ALLMUTE 0x00020000U +#define MCDRV_EVT_DIRMUTE 0x00030000U +#define MCDRV_EVT_ADCMUTE 0x00040000U +#define MCDRV_EVT_DITMUTE 0x00050000U +#define MCDRV_EVT_DACMUTE 0x00060000U +#define MCDRV_EVT_PSW_RESET 0x00070000U +#define MCDRV_EVT_CLKBUSY_RESET 0x00080000U +#define MCDRV_EVT_OFFCAN_BSY_RESET 0x00090000U +#define MCDRV_EVT_ANA_RDY 0x000A0000U +#define MCDRV_EVT_AP_CP_A_SET 0x000b0000U + +#define MCDRV_EVT_IF_REG_FLAG_SET 0x01000000U +#define MCDRV_EVT_IF_REG_FLAG_RESET 0x02000000U +#define MCDRV_EVT_B_REG_FLAG_SET 0x03000000U +#define MCDRV_EVT_B_REG_FLAG_RESET 0x04000000U +#define MCDRV_EVT_E_REG_FLAG_SET 0x05000000U +#define MCDRV_EVT_E_REG_FLAG_RESET 0x06000000U +#define MCDRV_EVT_C_REG_FLAG_SET 0x07000000U +#define MCDRV_EVT_C_REG_FLAG_RESET 0x08000000U +#define MCDRV_EVT_F_REG_FLAG_SET 0x09000000U +#define MCDRV_EVT_F_REG_FLAG_RESET 0x0A000000U + +#define MCDRV_PACKET_EVT_MASK 0x0FFF0000U +#define MCDRV_PACKET_EVTPRM_MASK 0x0000FFFFU + +/* timer */ +#define MCDRV_PACKET_TIME_MASK 0x0FFFFFFFU + +#define MCDRV_MAX_PACKETS 255 + +enum mcdrv_volume_mode { + MCDRV_VOLUME_MUTE, + MCDRV_VOLUME_SET, +}; + +#define MCDRV_VOLUPDATE_ALL 0xffffffffU +#define MCDRV_VOLUPDATE_ANA_OUT 0x00000001U +#define MCDRV_VOLUPDATE_ANA_IN 0x00000100U +#define MCDRV_VOLUPDATE_DIN0 0x00010000U +#define MCDRV_VOLUPDATE_DIN1 0x00020000U +#define MCDRV_VOLUPDATE_DIN2 0x00040000U +#define MCDRV_VOLUPDATE_DIN3 0x00080000U +#define MCDRV_VOLUPDATE_ADIF0 0x00100000U +#define MCDRV_VOLUPDATE_ADIF1 0x00200000U +#define MCDRV_VOLUPDATE_ADIF2 0x00400000U +#define MCDRV_VOLUPDATE_DIN 0x00ff0000U +#define MCDRV_VOLUPDATE_DOUT0 0x01000000U +#define MCDRV_VOLUPDATE_DOUT1 0x02000000U +#define MCDRV_VOLUPDATE_DOUT2 0x04000000U +#define MCDRV_VOLUPDATE_DOUT3 0x08000000U +#define MCDRV_VOLUPDATE_DAC0 0x10000000U +#define MCDRV_VOLUPDATE_DAC1 0x20000000U +#define MCDRV_VOLUPDATE_DPATHDA 0x80000000U +#define MCDRV_VOLUPDATE_DOUT 0xff000000U +#define MCDRV_VOLUPDATE_DIG 0xffff0000U + +struct mcdrv_power_info { + u8 digital; + u8 analog[5]; +}; + +#define MCDRV_POWINFO_D_PLL_PD 0x80 +#define MCDRV_POWINFO_D_PE_CLK_PD 0x20 +#define MCDRV_POWINFO_D_PB_CLK_PD 0x10 +#define MCDRV_POWINFO_D_PM_CLK_PD 0x08 +#define MCDRV_POWINFO_D_PF_CLK_PD 0x04 +#define MCDRV_POWINFO_D_PC_CLK_PD 0x02 + +struct mcdrv_power_update { + u8 digital; + u8 analog[5]; +}; + +#define MCDRV_POWUPDATE_D_ALL 0xff +#define MCDRV_POWUPDATE_AP 0x3f +#define MCDRV_POWUPDATE_AP_OUT0 0x7f +#define MCDRV_POWUPDATE_AP_OUT1 0xff +#define MCDRV_POWUPDATE_AP_MC 0xff +#define MCDRV_POWUPDATE_AP_IN 0x87 + +int mc_packet_init(void); +void mc_packet_clear(void); +void mc_packet_add(u32 desc, u8 data); +int mc_packet_execute(void); + +#define mc_packet_add_wait(time) \ + mc_packet_add((time) | MCDRV_PACKET_TYPE_TIMWAIT, 0) +#define mc_packet_add_wait_event(event) \ + mc_packet_add((event) | MCDRV_PACKET_TYPE_EVTWAIT, 0) +#define mc_packet_add_write(reg, data) \ + mc_packet_add((reg) | MCDRV_PACKET_TYPE_WRITE, (data)) +#define mc_packet_add_write_if(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_IF, (data)) +#define mc_packet_add_write_a(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_A, (data)) +#define mc_packet_add_write_ma(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_MA, (data)) +#define mc_packet_add_write_mb(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_MB, (data)) +#define mc_packet_add_write_b(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_B, (data)) +#define mc_packet_add_write_e(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_E, (data)) +#define mc_packet_add_write_c(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_C, (data)) +#define mc_packet_add_write_f(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_F, (data)) +#define mc_packet_add_write_ana(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_ANA, (data)) +#define mc_packet_add_write_cd(reg, data) \ + mc_packet_add_write((reg) | MCDRV_PACKET_REGTYPE_CD, (data)) +#define mc_packet_add_force_write(reg, data) \ + mc_packet_add((reg) | MCDRV_PACKET_TYPE_FORCE_WRITE, (data)) +#define mc_packet_add_force_write_if(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_IF, (data)) +#define mc_packet_add_force_write_ma(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_MA, (data)) +#define mc_packet_add_force_write_b(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_B, (data)) +#define mc_packet_add_force_write_e(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_E, (data)) +#define mc_packet_add_force_write_c(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_C, (data)) +#define mc_packet_add_force_write_f(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_F, (data)) +#define mc_packet_add_force_write_ana(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_ANA, (data)) +#define mc_packet_add_force_write_cd(reg, data) \ + mc_packet_add_force_write((reg) | MCDRV_PACKET_REGTYPE_CD, (data)) + +void mc_packet_add_switch_clock(u8 clk_switch); +int mc_packet_add_powerup(struct mcdrv_power_info *power_info, + struct mcdrv_power_update *power_update); +int mc_packet_add_powerdown(struct mcdrv_power_info *power_info, + struct mcdrv_power_update *power_update); +void mc_packet_add_path_set(void); +void mc_packet_add_start(void); +void mc_packet_add_stop(void); +void mc_packet_add_dsp_start_and_stop(u8 started); +void mc_packet_add_fdsp_stop(u8 started); +void mc_packet_add_volume(u32 update, enum mcdrv_volume_mode mode, u32 *status); +void mc_packet_add_dac0_mute(void); +void mc_packet_add_dac1_mute(void); +void mc_packet_add_dout_mute(void); +void mc_packet_add_adif_mute(void); +void mc_packet_add_dpath_da_mute(void); +void mc_packet_add_digital_io(u32 update); +void mc_packet_add_digital_io_path(void); +void mc_packet_add_swap(u32 update); +void mc_packet_add_hsdet(void); +void mc_packet_add_mic_key_detect_enable(bool check_plug_det_db); +void mc_packet_add_aec(void); +void mc_packet_add_gp_mode(void); +void mc_packet_add_gp_set(u32 pad_no); + +#endif /* _MCPACKING_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcparser.c | 1132 ++++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcparser.h | 40 ++ 3 files changed, 1174 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcparser.c create mode 100644 sound/soc/codecs/ymu831/mcparser.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index 01f5910..820dec7 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -5,6 +5,7 @@ snd-soc-ymu831-objs := \ mcdriver.o \ mcedspdrv.o \ mcfdspdrv.o \ - mcpacking.o + mcpacking.o \ + mcparser.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcparser.c b/sound/soc/codecs/ymu831/mcparser.c new file mode 100644 index 0000000..b2ba4bc --- /dev/null +++ b/sound/soc/codecs/ymu831/mcparser.c @@ -0,0 +1,1132 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcparser.c + * Description : MC data parser + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/errno.h> +#include <linux/types.h> + +#include <asm/byteorder.h> + +#include "mcbdspdrv.h" +#include "mccdspdrv.h" +#include "mcdriver.h" +#include "mcedspdrv.h" +#include "mcfdspdrv.h" +#include "mcparser.h" + +#define AEC_MIN_BYTES 12 +#define AEC_REVISION 5 +#define AEC_TARGET 253 + +#define AEC_D7_MIN_BYTES 6 +#define AEC_D7_CHUNK_CONFIG 0x01000000 +#define AEC_D7_CHUNK_AE 0x02000000 +#define AEC_D7_CHUNK_BDSP_ES1 0x00010000 +#define AEC_D7_CHUNK_BDSP 0x00010001 +#define AEC_D7_CHUNK_FDSP_ES1 0x00020000 +#define AEC_D7_CHUNK_FDSP 0x00020001 +#define AEC_D7_CHUNK_VBOX 0x03000000 +#define AEC_D7_CHUNK_CDSPA 0x00030000 +#define AEC_D7_CHUNK_CDSPB 0x00030001 +#define AEC_D7_CHUNK_CDSP_DEBUG 0x00050000 +#define AEC_D7_CHUNK_OUTPUT0_ES1 0x04000000 +#define AEC_D7_CHUNK_OUTPUT1_ES1 0x04000001 +#define AEC_D7_CHUNK_OUTPUT0 0x04000002 +#define AEC_D7_CHUNK_OUTPUT1 0x04000003 +#define AEC_D7_CHUNK_SYSEQ_EX 0x00060000 +#define AEC_D7_CHUNK_INPUT0 0x05000000 +#define AEC_D7_CHUNK_INPUT1 0x05000001 +#define AEC_D7_CHUNK_INPUT2 0x05000002 +#define AEC_D7_CHUNK_PDM 0x06000000 +#define AEC_D7_CHUNK_E2 0x07000000 +#define AEC_D7_CHUNK_E2_CONFIG 0x00040000 +#define AEC_D7_CHUNK_ADJ 0x08000000 +#define AEC_D7_CHUNK_EDSP_MISC 0x09000000 +#define AEC_D7_CHUNK_CONTROL 0x0A000000 + +struct mcdrv_aec_d7_info { + u8 *top; + u32 size; +}; + +static int analyze_audioengine_sub_data(u8 *data, u32 *offset, u32 *data_size, + struct mcdrv_aec_info *aec) +{ + enum mcdrv_dev_id dev_id; + u32 id, size; + + dev_id = mc_dev_id_get(); + + while (*data_size > 0) { + if (*data_size < 8) + return -EINVAL; + + id = htonl(*(u32 *) (data + *offset)); + size = htonl(*(u32 *) (data + *offset + 4)); + + *data_size -= 8; + if (*data_size < size) + return -EINVAL; + + if ((id == AEC_D7_CHUNK_BDSP_ES1 && + dev_id == MCDRV_DEV_ID_80_90H) || + (id == AEC_D7_CHUNK_BDSP && + dev_id != MCDRV_DEV_ID_80_90H)) { + if (aec->audio_engine.bdsp.data) + return -EINVAL; + + aec->audio_engine.bdsp.data = data + *offset; + aec->audio_engine.bdsp.data_size = size; + } else if ((id == AEC_D7_CHUNK_FDSP_ES1 && + dev_id == MCDRV_DEV_ID_80_90H) || + (id == AEC_D7_CHUNK_FDSP && + dev_id != MCDRV_DEV_ID_80_90H)) { + if (aec->audio_engine.fdsp.data) + return -EINVAL; + + aec->audio_engine.fdsp.data = data + *offset; + aec->audio_engine.fdsp.data_size = size; + } else + return -EINVAL; + + *offset += size + 8; + *data_size -= size; + } + + return 0; +} + +static int analyze_vbox_sub_data(u8 *data, u32 *offset, u32 *data_size, + struct mcdrv_aec_info *aec) +{ + enum mcdrv_dev_id dev_id; + u32 id, size; + + dev_id = mc_dev_id_get(); + + while (*data_size > 0) { + if (*data_size < 8) + return -EINVAL; + + id = htonl(*(u32 *) (data + *offset)); + size = htonl(*(u32 *) (data + *offset + 4)); + + *data_size -= 8; + if (*data_size < size) + return -EINVAL; + + if (id == AEC_D7_CHUNK_CDSPA) { + if (aec->vbox.cdsp_a.data) + return -EINVAL; + + aec->vbox.cdsp_a.data = data + *offset; + aec->vbox.cdsp_a.data_size = size; + } else if (id == AEC_D7_CHUNK_CDSPB) { + if (aec->vbox.cdsp_b.data) + return -EINVAL; + + aec->vbox.cdsp_b.data = data + *offset; + aec->vbox.cdsp_b.data_size = size; + } else if ((id == AEC_D7_CHUNK_FDSP_ES1 && + dev_id == MCDRV_DEV_ID_80_90H) || + (id == AEC_D7_CHUNK_FDSP && + dev_id != MCDRV_DEV_ID_80_90H)) { + if (aec->vbox.fdsp.data) + return -EINVAL; + + aec->vbox.fdsp.data = data + *offset; + aec->vbox.fdsp.data_size = size; + } else if (id == AEC_D7_CHUNK_CDSP_DEBUG) { + if (size != 1) + return -EINVAL; + + if (aec->vbox.cdsp_jtag_on != 0xff) + return -EINVAL; + if (data[*offset + 8] > 1) + return -EINVAL; + aec->vbox.cdsp_jtag_on = data[*offset + 8]; + } else + return -EINVAL; + + *offset += size + 8; + *data_size -= size; + } + + return 0; +} + +static int analyze_edsp_sub_data(u8 *data, u32 *offset, u32 *data_size, + struct mcdrv_aec_info *aec) +{ + u32 id, size; + + while (*data_size > 0) { + if (*data_size < 8) + return -EINVAL; + + id = htonl(*(u32 *) (data + *offset)); + size = htonl(*(u32 *) (data + *offset + 4)); + + *data_size -= 8; + if (*data_size < size) + return -EINVAL; + + if (id == AEC_D7_CHUNK_E2_CONFIG) { + if (aec->e2.config.data) + return -EINVAL; + + aec->e2.config.data = data + *offset; + aec->e2.config.data_size = size; + + *offset += size + 8; + *data_size -= size; + } else + return -EINVAL; + } + + return 0; +} + +static int get_d7_info(u8 *data, u32 size, struct mcdrv_aec_d7_info *d7_info) +{ + u32 data_size, offset, chunk_size; + + if (size < AEC_MIN_BYTES) + return -EINVAL; + + /* header */ + if (data[0] != 0x41 || data[1] != 0x45 || data[2] != 0x43) + return -EINVAL; + + /* revision */ + if (data[3] != AEC_REVISION) + return -EINVAL; + + /* size */ + data_size = htonl(*(u32 *) (data + 4)); + if (size != data_size + 8) + return -EINVAL; + + /* target */ + if (data[9] != AEC_TARGET) + return -EINVAL; + + /* Reserved */ + if (data[11] != 0x00) + return -EINVAL; + + /* D7 Chunk Search */ + d7_info->top = NULL; + d7_info->size = 0; + offset = AEC_MIN_BYTES; + + while ((offset + AEC_D7_MIN_BYTES) < size) { + if (data[offset] == 0x44 && data[offset + 1] == 0x37) { + if (d7_info->top) + return -EINVAL; + + chunk_size = htonl(*(u32 *) (data + offset + 2)); + if ((offset + AEC_D7_MIN_BYTES + chunk_size) > size) + return -EINVAL; + + d7_info->top = data + offset + AEC_D7_MIN_BYTES; + d7_info->size = chunk_size; + } else + return -EINVAL; + + /* Next Chunk */ + offset += chunk_size + AEC_D7_MIN_BYTES; + } + + if (!d7_info->top) + return -EINVAL; + + return 0; +} + +static int analyze_syseq_ex_sub_data(u8 *data, u32 *offset, u32 *sub_size, + struct mcdrv_aec_syseq_ex *syseq_ex) +{ + u32 id, size; + + while (*sub_size > 0) { + if (*sub_size < 8) + return -EINVAL; + + id = htonl(*(u32 *) (data + *offset)); + size = htonl(*(u32 *) (data + *offset + 4)); + + *offset += 8; + *sub_size -= 8; + if (*sub_size < size) + return -EINVAL; + + if (id == AEC_D7_CHUNK_SYSEQ_EX) { + if (size != 30) + return -EINVAL; + + if (syseq_ex->enable) + return -EINVAL; + + syseq_ex->enable = true; + syseq_ex->band[0].coef_a0[0] = data[*offset++]; + syseq_ex->band[0].coef_a0[1] = data[*offset++]; + syseq_ex->band[0].coef_a0[2] = data[*offset++]; + syseq_ex->band[0].coef_a1[0] = data[*offset++]; + syseq_ex->band[0].coef_a1[1] = data[*offset++]; + syseq_ex->band[0].coef_a1[2] = data[*offset++]; + syseq_ex->band[0].coef_a2[0] = data[*offset++]; + syseq_ex->band[0].coef_a2[1] = data[*offset++]; + syseq_ex->band[0].coef_a2[2] = data[*offset++]; + syseq_ex->band[0].coef_b1[0] = data[*offset++]; + syseq_ex->band[0].coef_b1[1] = data[*offset++]; + syseq_ex->band[0].coef_b1[2] = data[*offset++]; + syseq_ex->band[0].coef_b2[0] = data[*offset++]; + syseq_ex->band[0].coef_b2[1] = data[*offset++]; + syseq_ex->band[0].coef_b2[2] = data[*offset++]; + syseq_ex->band[1].coef_a0[0] = data[*offset++]; + syseq_ex->band[1].coef_a0[1] = data[*offset++]; + syseq_ex->band[1].coef_a0[2] = data[*offset++]; + syseq_ex->band[1].coef_a1[0] = data[*offset++]; + syseq_ex->band[1].coef_a1[1] = data[*offset++]; + syseq_ex->band[1].coef_a1[2] = data[*offset++]; + syseq_ex->band[1].coef_a2[0] = data[*offset++]; + syseq_ex->band[1].coef_a2[1] = data[*offset++]; + syseq_ex->band[1].coef_a2[2] = data[*offset++]; + syseq_ex->band[1].coef_b1[0] = data[*offset++]; + syseq_ex->band[1].coef_b1[1] = data[*offset++]; + syseq_ex->band[1].coef_b1[2] = data[*offset++]; + syseq_ex->band[1].coef_b2[0] = data[*offset++]; + syseq_ex->band[1].coef_b2[1] = data[*offset++]; + syseq_ex->band[1].coef_b2[2] = data[*offset++]; + *sub_size -= size; + } else + return -EINVAL; + } + + return 0; +} + +int mc_parser_d7_data_analyze(u8 *data, u32 size, struct mcdrv_aec_info *aec) +{ + struct mcdrv_aec_d7_info d7_info; + enum mcdrv_dev_id dev_id; + u8 *d7_data; + u32 offset, d7_data_end; + u32 id, sub_size; + int n, ret; + + ret = get_d7_info(data, size, &d7_info); + if (ret < 0) + return ret; + + dev_id = mc_dev_id_get(); + + d7_data = d7_info.top; + d7_data_end = d7_info.size - 1; + + aec->fdsp_locate = 0xFF; + aec->audio_engine.enable = false; + aec->audio_engine.bdsp.data = NULL; + aec->audio_engine.bdsp.data_size = 0; + aec->audio_engine.fdsp.data = NULL; + aec->audio_engine.fdsp.data_size = 0; + aec->vbox.enable = false; + aec->vbox.cdsp_a.data = NULL; + aec->vbox.cdsp_a.data_size = 0; + aec->vbox.cdsp_b.data = NULL; + aec->vbox.cdsp_b.data_size = 0; + aec->vbox.fdsp.data = NULL; + aec->vbox.fdsp.data_size = 0; + aec->vbox.cdsp_jtag_on = 0xff; + aec->output.lpf_pre_thru[0] = 0xFF; + aec->output.lpf_pre_thru[1] = 0xFF; + aec->input.dsf32_l_type[0] = 0xFF; + aec->input.dsf32_l_type[1] = 0xFF; + aec->input.dsf32_l_type[2] = 0xFF; + aec->pdm.mode = 0xFF; + aec->e2.enable = false; + aec->e2.config.data = NULL; + aec->e2.config.data_size = 0; + aec->adj.hold = 0xFF; + aec->edsp_misc.i2s_out_enable = 0xFF; + aec->control.command = 0xFF; + + offset = 0; + while (offset <= d7_data_end && !ret) { + if ((offset + 8 - 1) > d7_data_end) { + ret = -EINVAL; + break; + } + + id = htonl(*(u32 *) (d7_data + offset)); + sub_size = htonl(*(u32 *) (d7_data + offset + 4)); + + offset += 8; + if ((offset + sub_size - 1) > d7_data_end) { + ret = -EINVAL; + break; + } + + switch (id) { + case AEC_D7_CHUNK_CONFIG: + if (sub_size != 1 || aec->fdsp_locate != 0xFF || + d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->fdsp_locate = d7_data[offset++]; + sub_size = 0; + break; + case AEC_D7_CHUNK_AE: + if (sub_size < 8 || aec->audio_engine.enable || + d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.enable = true; + aec->audio_engine.on = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.fdsp_on = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.bdsp_ae0_src = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.bdsp_ae1_src = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.mixer_in0_src = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.mixer_in1_src = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.mixer_in2_src = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->audio_engine.mixer_in3_src = d7_data[offset++]; + sub_size--; + + if (sub_size > 0) { + ret = analyze_audioengine_sub_data(d7_data, + &offset, + &sub_size, + aec); + } + break; + case AEC_D7_CHUNK_VBOX: + if (sub_size < 15 || aec->vbox.enable) { + ret = -EINVAL; + break; + } + + aec->vbox.enable = true; + + if (d7_data[offset] > 2 && d7_data[offset] != 0x11) { + ret = -EINVAL; + break; + } + + aec->vbox.cdsp_func_a_on = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2 && d7_data[offset] != 0x11) { + ret = -EINVAL; + break; + } + + aec->vbox.cdsp_func_b_on = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->vbox.fdsp_on = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 0x3F && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.fdsp_po_source = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 1 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.isrc2_vsource = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 1 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.isrc2_ch1_vsource = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 1 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.isrc3_vsource = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 1 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.lpt2_vsource = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 3 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.lpt2_mix_vol_o = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 3 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.lpt2_mix_vol_i = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 3 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.src3_ctrl = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] == 3 || d7_data[offset] == 7 || + d7_data[offset] == 11 || + (d7_data[offset] > 13 && d7_data[offset] < 0xFF)) { + ret = -EINVAL; + break; + } + + aec->vbox.src2_fs = d7_data[offset++]; + sub_size--; + + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] > 1 && + d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + aec->vbox.src2_thru = d7_data[offset++]; + } else + offset++; + sub_size--; + + if (d7_data[offset] == 3 || d7_data[offset] == 7 || + d7_data[offset] == 11 || + (d7_data[offset] > 13 && d7_data[offset] < 0xFF)) { + ret = -EINVAL; + break; + } + + aec->vbox.src3_fs = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 1 && d7_data[offset] < 0xFF) { + ret = -EINVAL; + break; + } + + aec->vbox.src3_thru = d7_data[offset++]; + sub_size--; + + if (sub_size > 0) { + ret = analyze_vbox_sub_data(d7_data, + &offset, + &sub_size, aec); + } + break; + case AEC_D7_CHUNK_OUTPUT0_ES1: + case AEC_D7_CHUNK_OUTPUT1_ES1: + case AEC_D7_CHUNK_OUTPUT0: + case AEC_D7_CHUNK_OUTPUT1: + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (id != AEC_D7_CHUNK_OUTPUT0_ES1 && + id != AEC_D7_CHUNK_OUTPUT1_ES1) + break; + n = id - AEC_D7_CHUNK_OUTPUT0_ES1; + } else { + if (id != AEC_D7_CHUNK_OUTPUT0 && + id != AEC_D7_CHUNK_OUTPUT1) + break; + n = id - AEC_D7_CHUNK_OUTPUT0; + } + if (sub_size < 47 || + aec->output.lpf_pre_thru[n] != 0xFF || + d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.lpf_pre_thru[n] = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.lpf_post_thru[n] = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->output.dcc_sel[n] = d7_data[offset++]; + + if (d7_data[offset] > 5) { + ret = -EINVAL; + break; + } + + aec->output.signal_detect_level = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->output.power_detect_level[n] = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->output.osf_sel[n] = d7_data[offset++]; + + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + } else { + if (d7_data[offset] > 7) { + ret = -EINVAL; + break; + } + } + aec->output.syseq_enb[n] = d7_data[offset++]; + aec->output.syseq_coef_a0[n][0] = d7_data[offset++]; + aec->output.syseq_coef_a0[n][1] = d7_data[offset++]; + aec->output.syseq_coef_a0[n][2] = d7_data[offset++]; + aec->output.syseq_coef_a1[n][0] = d7_data[offset++]; + aec->output.syseq_coef_a1[n][1] = d7_data[offset++]; + aec->output.syseq_coef_a1[n][2] = d7_data[offset++]; + aec->output.syseq_coef_a2[n][0] = d7_data[offset++]; + aec->output.syseq_coef_a2[n][1] = d7_data[offset++]; + aec->output.syseq_coef_a2[n][2] = d7_data[offset++]; + aec->output.syseq_coef_b1[n][0] = d7_data[offset++]; + aec->output.syseq_coef_b1[n][1] = d7_data[offset++]; + aec->output.syseq_coef_b1[n][2] = d7_data[offset++]; + aec->output.syseq_coef_b2[n][0] = d7_data[offset++]; + aec->output.syseq_coef_b2[n][1] = d7_data[offset++]; + aec->output.syseq_coef_b2[n][2] = d7_data[offset++]; + + if (d7_data[offset] > 7) { + ret = -EINVAL; + break; + } + + aec->output.clip_md[n] = d7_data[offset++]; + aec->output.clip_att[n] = d7_data[offset++]; + aec->output.clip_rel[n] = d7_data[offset++]; + aec->output.clip_g[n] = d7_data[offset++]; + aec->output.osf_gain[n][0] = d7_data[offset++]; + aec->output.osf_gain[n][1] = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.dcl_on[n] = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->output.dcl_gain[n] = d7_data[offset++]; + + if (d7_data[offset] > 0x7F) { + ret = -EINVAL; + break; + } + + aec->output.dcl_limit[n][0] = d7_data[offset++]; + aec->output.dcl_limit[n][1] = d7_data[offset++]; + + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + aec->output.random_dither_on[n] = + d7_data[offset++]; + } else + offset++; + + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + aec->output.random_dither_level[n] = + d7_data[offset++]; + } else + offset++; + + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + aec->output.random_dither_pos[n] = + d7_data[offset++]; + } else + offset++; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.dc_dither_on[n] = d7_data[offset++]; + + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] > 15) { + ret = -EINVAL; + break; + } + aec->output.dc_dither_level[n] = + d7_data[offset++]; + } else + offset++; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.dither_type[n] = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.dng_on[n] = d7_data[offset++]; + + if (d7_data[offset] > 31) { + ret = -EINVAL; + break; + } + + aec->output.dng_zero[n] = d7_data[offset++]; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->output.dng_time[n] = d7_data[offset++]; + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->output.dng_fw[n] = d7_data[offset++]; + aec->output.dng_attack = d7_data[offset++]; + aec->output.dng_release = d7_data[offset++]; + aec->output.dng_target[n] = d7_data[offset++]; + aec->output.dng_target_lineout[n] = d7_data[offset++]; + if (n == 0) + aec->output.dng_target_rc = d7_data[offset++]; + else + offset++; + + sub_size -= 47; + if (sub_size > 0) + ret = analyze_syseq_ex_sub_data(data, &offset, + &sub_size, + &aec->output. + syseq_ex[n]); + break; + case AEC_D7_CHUNK_INPUT0: + case AEC_D7_CHUNK_INPUT1: + case AEC_D7_CHUNK_INPUT2: + n = id - AEC_D7_CHUNK_INPUT0; + if (sub_size < 16 || + aec->input.dsf32_l_type[n] != 0xFF || + (n == 0 && d7_data[offset] > 2) || + (n != 0 && d7_data[offset] > 1)) { + ret = -EINVAL; + break; + } + + aec->input.dsf32_l_type[n] = d7_data[offset++]; + + if ((n == 0 && d7_data[offset] > 2) || + (n != 0 && d7_data[offset] > 1)) { + ret = -EINVAL; + break; + } + + aec->input.dsf32_r_type[n] = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->input.dsf4_sel[n] = d7_data[offset++]; + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->input.dcc_sel[n] = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->input.dng_on[n] = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->input.dng_att[n] = d7_data[offset++]; + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->input.dng_rel[n] = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->input.dng_fw[n] = d7_data[offset++]; + + if (d7_data[offset] > 0x3F) { + ret = -EINVAL; + break; + } + + aec->input.dng_time[n] = d7_data[offset++]; + aec->input.dng_zero[n][0] = d7_data[offset++]; + aec->input.dng_zero[n][1] = d7_data[offset++]; + aec->input.dng_target[n][0] = d7_data[offset++]; + aec->input.dng_target[n][1] = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->input.depop_att[n] = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->input.depop_wait[n] = d7_data[offset++]; + if (n == 2) { + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->input.ref_sel = d7_data[offset++]; + } else + offset++; + + sub_size = 0; + break; + case AEC_D7_CHUNK_PDM: + if (sub_size != 10 || aec->pdm.mode != 0xFF || + d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->pdm.mode = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->pdm.st_wait = d7_data[offset++]; + + if (d7_data[offset] > 7) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm0_loadtime = d7_data[offset++]; + + if (d7_data[offset] > 63) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm0_l_finedelay = d7_data[offset++]; + + if (d7_data[offset] > 63) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm0_r_finedelay = d7_data[offset++]; + + if (d7_data[offset] > 7) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm1_loadtime = d7_data[offset++]; + + if (d7_data[offset] > 63) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm1_l_finedelay = d7_data[offset++]; + + if (d7_data[offset] > 63) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm1_r_finedelay = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm0_data_delay = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->pdm.pdm1_data_delay = d7_data[offset++]; + + sub_size = 0; + break; + case AEC_D7_CHUNK_E2: + if (sub_size < 3 || aec->e2.enable) { + ret = -EINVAL; + break; + } + + aec->e2.enable = true; + + if (d7_data[offset] > 4) { + ret = -EINVAL; + break; + } + + aec->e2.da_sel = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 8) { + ret = -EINVAL; + break; + } + + aec->e2.ad_sel = d7_data[offset++]; + sub_size--; + + if (d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + + aec->e2.on = d7_data[offset++]; + sub_size--; + + if (sub_size > 0) { + ret = analyze_edsp_sub_data(d7_data, + &offset, + &sub_size, aec); + } + break; + case AEC_D7_CHUNK_ADJ: + if (sub_size != 4 || aec->adj.hold != 0xFF || + d7_data[offset] > 0x3F) { + ret = -EINVAL; + break; + } + + aec->adj.hold = d7_data[offset++]; + + if (d7_data[offset] > 0x0F) { + ret = -EINVAL; + break; + } + + aec->adj.cnt = d7_data[offset++]; + aec->adj.max[0] = d7_data[offset++]; + aec->adj.max[1] = d7_data[offset++]; + + sub_size = 0; + break; + case AEC_D7_CHUNK_EDSP_MISC: + if (sub_size != 3 || + aec->edsp_misc.i2s_out_enable != 0xFF || + d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->edsp_misc.i2s_out_enable = d7_data[offset++]; + + if (d7_data[offset] > 1) { + ret = -EINVAL; + break; + } + + aec->edsp_misc.ch_sel = d7_data[offset++]; + + if (d7_data[offset] > 3) { + ret = -EINVAL; + break; + } + + aec->edsp_misc.loopback = d7_data[offset++]; + + sub_size = 0; + break; + case AEC_D7_CHUNK_CONTROL: + if (sub_size != 5 || aec->control.command != 0xFF) { + ret = -EINVAL; + break; + } + if (dev_id == MCDRV_DEV_ID_80_90H) { + if (d7_data[offset] < 1 + || d7_data[offset] > 2) { + ret = -EINVAL; + break; + } + } else { + if (d7_data[offset] < 1 + || d7_data[offset] > 4) { + ret = -EINVAL; + break; + } + } + + aec->control.command = d7_data[offset++]; + aec->control.param[0] = d7_data[offset++]; + aec->control.param[1] = d7_data[offset++]; + aec->control.param[2] = d7_data[offset++]; + aec->control.param[3] = d7_data[offset++]; + + sub_size = 0; + break; + default: + ret = -EINVAL; + } + + offset += sub_size; + } + + return ret; +} diff --git a/sound/soc/codecs/ymu831/mcparser.h b/sound/soc/codecs/ymu831/mcparser.h new file mode 100644 index 0000000..996c8ab --- /dev/null +++ b/sound/soc/codecs/ymu831/mcparser.h @@ -0,0 +1,40 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcparser.h + * Description : MC data parser header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unused codes + */ +#ifndef _MCPARSER_H +#define _MCPARSER_H + +#include <linux/types.h> + +#include "mcresctrl.h" + +int mc_parser_d7_data_analyze(u8 *data, u32 size, struct mcdrv_aec_info *aec); + +#endif /* _MCPARSER_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 3 +- sound/soc/codecs/ymu831/mcresctrl.c | 4062 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/mcresctrl.h | 394 ++++ 3 files changed, 4458 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/mcresctrl.c create mode 100644 sound/soc/codecs/ymu831/mcresctrl.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index 820dec7..3fd53fe 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -6,6 +6,7 @@ snd-soc-ymu831-objs := \ mcedspdrv.o \ mcfdspdrv.o \ mcpacking.o \ - mcparser.o + mcparser.o \ + mcresctrl.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o diff --git a/sound/soc/codecs/ymu831/mcresctrl.c b/sound/soc/codecs/ymu831/mcresctrl.c new file mode 100644 index 0000000..9a7787e --- /dev/null +++ b/sound/soc/codecs/ymu831/mcresctrl.c @@ -0,0 +1,4062 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcresctrl.c + * Description : MC resource control driver + * Version : 1.0.1 Dec 18 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/bug.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/types.h> + +#include "mcdefs.h" +#include "mcdevif.h" +#include "mcdriver.h" +#include "mcresctrl.h" + +#define BURST_WRITE_ENABLE 0x01 + +#define D1SRC_ALL_OFF (MCDRV_D1SRC_MUSICIN_OFF \ + | MCDRV_D1SRC_EXTIN_OFF \ + | MCDRV_D1SRC_VBOXOUT_OFF \ + | MCDRV_D1SRC_VBOXREFOUT_OFF \ + | MCDRV_D1SRC_AE0_OFF \ + | MCDRV_D1SRC_AE1_OFF \ + | MCDRV_D1SRC_AE2_OFF \ + | MCDRV_D1SRC_AE3_OFF \ + | MCDRV_D1SRC_ADIF0_OFF \ + | MCDRV_D1SRC_ADIF1_OFF \ + | MCDRV_D1SRC_ADIF2_OFF \ + | MCDRV_D1SRC_HIFIIN_OFF) +#define D2SRC_ALL_OFF (MCDRV_D2SRC_VOICEIN_OFF \ + | MCDRV_D2SRC_VBOXIOOUT_OFF \ + | MCDRV_D2SRC_VBOXHOSTOUT_OFF \ + | MCDRV_D2SRC_ADC0_L_OFF \ + | MCDRV_D2SRC_ADC0_R_OFF \ + | MCDRV_D2SRC_ADC1_OFF \ + | MCDRV_D2SRC_PDM0_L_OFF \ + | MCDRV_D2SRC_PDM0_R_OFF \ + | MCDRV_D2SRC_PDM1_L_OFF \ + | MCDRV_D2SRC_PDM1_R_OFF \ + | MCDRV_D2SRC_DAC0REF_OFF \ + | MCDRV_D2SRC_DAC1REF_OFF) + +#define ASRC_ALL_OFF (MCDRV_ASRC_DAC0_L_OFF \ + | MCDRV_ASRC_DAC0_R_OFF \ + | MCDRV_ASRC_DAC1_L_OFF \ + | MCDRV_ASRC_DAC1_R_OFF \ + | MCDRV_ASRC_MIC1_OFF \ + | MCDRV_ASRC_MIC2_OFF \ + | MCDRV_ASRC_MIC3_OFF \ + | MCDRV_ASRC_MIC4_OFF \ + | MCDRV_ASRC_LINEIN1_L_OFF \ + | MCDRV_ASRC_LINEIN1_R_OFF \ + | MCDRV_ASRC_LINEIN1_M_OFF) + +/* control packet for serial host interface */ +#define MCDRV_MAX_CTRL_DATA_NUM (MCDRV_MAX_PACKETS * 4) + +struct mcdrv_packet { + u8 data[MCDRV_MAX_CTRL_DATA_NUM]; + u16 data_size; +}; + +/* Register available num */ +#define MCDRV_REG_NUM_IF 59 +#define MCDRV_REG_NUM_A 68 +#define MCDRV_REG_NUM_MA 85 +#define MCDRV_REG_NUM_MB 86 +#define MCDRV_REG_NUM_B 72 +#define MCDRV_REG_NUM_E 101 +#define MCDRV_REG_NUM_C 160 +#define MCDRV_REG_NUM_F 128 +#define MCDRV_REG_NUM_ANA 116 +#define MCDRV_REG_NUM_CD 53 + +struct mcdrv_info { + u8 id; + enum mcdrv_dev_id device_id; + enum mcdrv_state state; + + u8 if_registers[MCDRV_REG_NUM_IF]; + u8 a_registers[MCDRV_REG_NUM_A]; + u8 ma_registers[MCDRV_REG_NUM_MA]; + u8 mb_registers[MCDRV_REG_NUM_MB]; + u8 b_registers[MCDRV_REG_NUM_B]; + u8 e_registers[MCDRV_REG_NUM_E]; + u8 c_registers[MCDRV_REG_NUM_C]; + u8 f_registers[MCDRV_REG_NUM_F]; + u8 ana_registers[MCDRV_REG_NUM_ANA]; + u8 cd_registers[MCDRV_REG_NUM_CD]; + + struct mcdrv_dev_info dev_info; + struct mcdrv_path_info path_info; + struct mcdrv_path_info path_info_virtual; + struct mcdrv_vol_info vol_info; + struct mcdrv_dio_info dio_info; + struct mcdrv_dio_path_info dio_path_info; + struct mcdrv_swap_info swap_info; + struct mcdrv_hsdet_info hsdet_info; + struct mcdrv_aec_info aec_info; + struct mcdrv_gp_mode gp_mode; + + u8 clk; + u8 clk_sel; + u8 eclk_sel; + u8 plug_det_db; + + struct mcdrv_packet packet; + u16 slave_addr; + u16 type; + u16 addr; + u16 data_count; + u16 prev_addr_index; +}; + +static struct mcdrv_info mc_info = { + .device_id = MCDRV_DEV_ID_UNKNOWN, + .state = MCDRV_STATE_NOTINIT, +}; + +/* register next address */ +static const u16 mc_next_addr_list[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; + +static const u16 mc_next_addr_list_inc[256] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 0xffff +}; + +static inline void registers_set_default(enum mcdrv_dev_id id) +{ + memset(mc_info.if_registers, 0, MCDRV_REG_NUM_IF); + + mc_info.if_registers[MCI_RST_A] = MCI_RST_A_DEF; + mc_info.if_registers[MCI_RST] = MCI_RST_DEF; + + mc_a_registers_init(); + mc_mblock_registers_init(); + + memset(mc_info.c_registers, 0, MCDRV_REG_NUM_C); + memset(mc_info.f_registers, 0, MCDRV_REG_NUM_F); + memset(mc_info.ana_registers, 0, MCDRV_REG_NUM_ANA); + + mc_info.ana_registers[MCI_ANA_ID] = MCI_ANA_ID_DEF; + mc_info.ana_registers[MCI_ANA_RST] = MCI_ANA_RST_DEF; + mc_info.ana_registers[MCI_AP] = MCI_AP_DEF; + mc_info.ana_registers[MCI_AP_DA0] = MCI_AP_DA0_DEF; + mc_info.ana_registers[MCI_AP_DA1] = MCI_AP_DA1_DEF; + mc_info.ana_registers[MCI_AP_MIC] = MCI_AP_MIC_DEF; + mc_info.ana_registers[MCI_AP_AD] = MCI_AP_AD_DEF; + + if (id == MCDRV_DEV_ID_81_91H) + mc_info.ana_registers[10] = 0x06; + mc_info.ana_registers[MCI_NONCLIP] = MCI_NONCLIP_DEF; + + mc_info.ana_registers[MCI_SVOL] = MCI_SVOL_DEF; + + if (id == MCDRV_DEV_ID_81_91H) { + mc_info.ana_registers[MCI_HIZ] = MCI_HIZ_DEF; + mc_info.ana_registers[MCI_LO_HIZ] = MCI_LO_HIZ_DEF; + } + + if (id == MCDRV_DEV_ID_80_90H) + mc_info.ana_registers[MCI_ZCOFF] = MCI_ZCOFF_DEF_ES1; + + switch (id) { + case MCDRV_DEV_ID_80_90H: + mc_info.ana_registers[MCI_CPMOD] = MCI_CPMOD_DEF_ES1; + mc_info.ana_registers[MCI_DNG_ES1] = MCI_DNG_DEF_ES1; + mc_info.ana_registers[MCI_DNG_HP_ES1] = MCI_DNG_HP_DEF_ES1; + mc_info.ana_registers[MCI_DNG_SP_ES1] = MCI_DNG_SP_DEF_ES1; + mc_info.ana_registers[MCI_DNG_RC_ES1] = MCI_DNG_RC_DEF_ES1; + mc_info.ana_registers[MCI_DNG_LO1_ES1] = MCI_DNG_LO1_DEF_ES1; + mc_info.ana_registers[MCI_DNG_LO2_ES1] = MCI_DNG_LO2_DEF_ES1; + break; + case MCDRV_DEV_ID_81_91H: + mc_info.ana_registers[MCI_CPMOD] = MCI_CPMOD_DEF; + mc_info.ana_registers[MCI_DNG] = MCI_DNG_DEF; + mc_info.ana_registers[MCI_DNG_HP] = MCI_DNG_HP_DEF; + mc_info.ana_registers[MCI_DNG_SP] = MCI_DNG_SP_DEF; + mc_info.ana_registers[MCI_DNG_RC] = MCI_DNG_RC_DEF; + mc_info.ana_registers[MCI_DNG_LO1] = MCI_DNG_LO1_DEF; + mc_info.ana_registers[MCI_DNG_LO2] = MCI_DNG_LO2_DEF; + mc_info.ana_registers[114] = 0x31; + mc_info.ana_registers[115] = 0x8B; + break; + default: + break; + } + + memset(mc_info.cd_registers, 0, MCDRV_REG_NUM_CD); + + mc_info.cd_registers[MCI_HW_ID] = MCI_HW_ID_DEF; + mc_info.cd_registers[MCI_CD_RST] = MCI_CD_RST_DEF; + mc_info.cd_registers[MCI_DP] = MCI_DP_DEF; + mc_info.cd_registers[MCI_DP_OSC] = MCI_DP_OSC_DEF; + + switch (id) { + case MCDRV_DEV_ID_80_90H: + mc_info.cd_registers[MCI_CKSEL] = MCI_CKSEL_DEF_ES1; + break; + case MCDRV_DEV_ID_81_91H: + mc_info.cd_registers[MCI_CKSEL] = MCI_CKSEL_DEF; + break; + default: + break; + } + + mc_info.cd_registers[MCI_MICDET] = MCI_MICDET_DEF; + mc_info.cd_registers[MCI_HSDETEN] = MCI_HSDETEN_DEF; + + switch (id) { + case MCDRV_DEV_ID_80_90H: + mc_info.cd_registers[MCI_DETIN_INV] = MCI_DETIN_INV_DEF_ES1; + break; + case MCDRV_DEV_ID_81_91H: + mc_info.cd_registers[MCI_IRQTYPE] = MCI_IRQTYPE_DEF; + mc_info.cd_registers[MCI_DETIN_INV] = MCI_DETIN_INV_DEF; + break; + default: + break; + } + + mc_info.cd_registers[MCI_HSDETMODE] = MCI_HSDETMODE_DEF; + mc_info.cd_registers[MCI_DBNC_PERIOD] = MCI_DBNC_PERIOD_DEF; + + switch (id) { + case MCDRV_DEV_ID_80_90H: + mc_info.cd_registers[MCI_DBNC_NUM] = MCI_DBNC_NUM_DEF_ES1; + break; + case MCDRV_DEV_ID_UNKNOWN: + break; + default: + mc_info.cd_registers[MCI_DBNC_NUM] = MCI_DBNC_NUM_DEF; + mc_info.cd_registers[MCI_KEY_MTIM] = MCI_KEY_MTIM_DEF; + mc_info.cd_registers[39] = 0x21; + break; + } +} + +int mc_id_set(u8 digital_id, u8 analog_id) +{ + if ((digital_id & MCDRV_DEVID_MASK) == MCDRV_DEVID_DIG + && (analog_id & MCDRV_DEVID_MASK) == MCDRV_DEVID_ANA) { + if ((digital_id & MCDRV_VERID_MASK) == 1) { + if ((analog_id & MCDRV_VERID_MASK) == 2) + mc_info.device_id = MCDRV_DEV_ID_81_92H; + else + mc_info.device_id = MCDRV_DEV_ID_81_91H; + } else + mc_info.device_id = MCDRV_DEV_ID_80_90H; + + mc_info.id = digital_id; + registers_set_default(mc_info.device_id); + mc_info.a_registers[MCI_A_DEV_ID] = mc_info.id; + + return 0; + } + + return -EINVAL; +} + +enum mcdrv_dev_id mc_dev_id_get(void) +{ + return mc_info.device_id; +} + +static inline void path_info_init(void) +{ + struct mcdrv_path_info *path_info; + + path_info = &mc_info.path_info; + + memset(path_info->music_out, D1SRC_ALL_OFF, MUSICOUT_PATH_CHANNELS); + memset(path_info->ext_out, D1SRC_ALL_OFF, EXTOUT_PATH_CHANNELS); + memset(path_info->hifi_out, D1SRC_ALL_OFF, HIFIOUT_PATH_CHANNELS); + memset(path_info->vbox_mix_in, D1SRC_ALL_OFF, VBOXMIXIN_PATH_CHANNELS); + memset(path_info->ae0, D1SRC_ALL_OFF, AE_PATH_CHANNELS); + memset(path_info->ae1, D1SRC_ALL_OFF, AE_PATH_CHANNELS); + memset(path_info->ae2, D1SRC_ALL_OFF, AE_PATH_CHANNELS); + memset(path_info->ae3, D1SRC_ALL_OFF, AE_PATH_CHANNELS); + memset(path_info->dac0, D1SRC_ALL_OFF, DAC0_PATH_CHANNELS); + memset(path_info->dac1, D1SRC_ALL_OFF, DAC1_PATH_CHANNELS); + + memset(path_info->voice_out, D2SRC_ALL_OFF, VOICEOUT_PATH_CHANNELS); + memset(path_info->vbox_io_in, D2SRC_ALL_OFF, VBOXIOIN_PATH_CHANNELS); + memset(path_info->vbox_host_in, D2SRC_ALL_OFF, + VBOXHOSTIN_PATH_CHANNELS); + memset(path_info->host_out, D2SRC_ALL_OFF, HOSTOUT_PATH_CHANNELS); + memset(path_info->adif0, D2SRC_ALL_OFF, ADIF0_PATH_CHANNELS); + memset(path_info->adif1, D2SRC_ALL_OFF, ADIF1_PATH_CHANNELS); + memset(path_info->adif2, D2SRC_ALL_OFF, ADIF2_PATH_CHANNELS); + + memset(path_info->adc0, ASRC_ALL_OFF, ADC0_PATH_CHANNELS); + memset(path_info->adc1, ASRC_ALL_OFF, ADC1_PATH_CHANNELS); + memset(path_info->sp, ASRC_ALL_OFF, SP_PATH_CHANNELS); + memset(path_info->hp, ASRC_ALL_OFF, HP_PATH_CHANNELS); + memset(path_info->rc, ASRC_ALL_OFF, RC_PATH_CHANNELS); + memset(path_info->lout1, ASRC_ALL_OFF, LOUT1_PATH_CHANNELS); + memset(path_info->lout2, ASRC_ALL_OFF, LOUT2_PATH_CHANNELS); + memset(path_info->bias, ASRC_ALL_OFF, BIAS_PATH_CHANNELS); + + mc_info.path_info_virtual = mc_info.path_info; +} + +static inline void vol_info_init(void) +{ + struct mcdrv_vol_info *vol_info; + + vol_info = &mc_info.vol_info; + + memset(vol_info, MCDRV_LOGICAL_VOL_MUTE, sizeof(struct mcdrv_vol_info)); +} + +static inline void dio_info_init(void) +{ + struct mcdrv_dio_port *port; + int i; + + for (i = 0; i < ARRAY_SIZE(mc_info.dio_info.port); i++) { + port = &mc_info.dio_info.port[i]; + port->dio_common.master_slave = MCDRV_DIO_SLAVE; + port->dio_common.auto_fs = MCDRV_AUTOFS_ON; + port->dio_common.fs = MCDRV_FS_48000; + port->dio_common.bck_fs = MCDRV_BCKFS_64; + port->dio_common.interface = MCDRV_DIO_DA; + port->dio_common.bck_invert = MCDRV_BCLK_NORMAL; + port->dio_common.src_thru = MCDRV_SRC_NOT_THRU; + port->dio_common.pcm_hiz_transition = MCDRV_PCMHIZTRANS_FALLING; + port->dio_common.pcm_frame = MCDRV_PCM_SHORTFRAME; + port->dio_common.pcm_high_period = 0; + + port->dir.da_format.bit_sel = MCDRV_BITSEL_16; + port->dir.da_format.mode = MCDRV_DAMODE_HEADALIGN; + port->dir.pcm_format.mono = MCDRV_PCM_MONO; + port->dir.pcm_format.order = MCDRV_PCM_MSB_FIRST; + port->dir.pcm_format.law = MCDRV_PCM_LINEAR; + port->dir.pcm_format.bit_sel = MCDRV_PCM_BITSEL_8; + + port->dit.st_mode = MCDRV_STMODE_ZERO; + port->dit.edge = MCDRV_SDOUT_NORMAL; + port->dit.da_format.bit_sel = MCDRV_BITSEL_16; + port->dit.da_format.mode = MCDRV_DAMODE_HEADALIGN; + port->dit.pcm_format.mono = MCDRV_PCM_MONO; + port->dit.pcm_format.order = MCDRV_PCM_MSB_FIRST; + port->dit.pcm_format.law = MCDRV_PCM_LINEAR; + port->dit.pcm_format.bit_sel = MCDRV_PCM_BITSEL_8; + } +} + +static inline void dio_path_info_init(void) +{ + mc_info.dio_path_info.phys_port[0] = MCDRV_PHYSPORT_DIO0; + mc_info.dio_path_info.phys_port[1] = MCDRV_PHYSPORT_DIO1; + mc_info.dio_path_info.phys_port[2] = MCDRV_PHYSPORT_DIO2; + mc_info.dio_path_info.phys_port[3] = MCDRV_PHYSPORT_NONE; + mc_info.dio_path_info.music_ch = MCDRV_MUSIC_2CH; + mc_info.dio_path_info.music_rslot[0] = 0; + mc_info.dio_path_info.music_rslot[1] = 1; + mc_info.dio_path_info.music_rslot[2] = 2; + mc_info.dio_path_info.music_tslot[0] = 0; + mc_info.dio_path_info.music_tslot[1] = 1; + mc_info.dio_path_info.music_tslot[2] = 2; +} + +static inline void swap_info_init(void) +{ + mc_info.swap_info.adif0 = MCDRV_SWAP_NORMAL; + mc_info.swap_info.adif1 = MCDRV_SWAP_NORMAL; + mc_info.swap_info.adif2 = MCDRV_SWAP_NORMAL; + mc_info.swap_info.dac0 = MCDRV_SWAP_NORMAL; + mc_info.swap_info.dac1 = MCDRV_SWAP_NORMAL; + + mc_info.swap_info.music_in0 = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.music_in1 = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.music_in2 = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.ext_in = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.voice_in = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.hifi_in = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.music_out0 = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.music_out1 = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.music_out2 = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.ext_out = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.voice_out = MCDRV_SWSWAP_NORMAL; + mc_info.swap_info.hifi_out = MCDRV_SWSWAP_NORMAL; +} + +static inline void hsdet_info_init(void) +{ + struct mcdrv_hsdet_info *hsdet; + + hsdet = &mc_info.hsdet_info; + hsdet->en_plug_det = MCDRV_PLUGDET_DISABLE; + hsdet->en_plug_det_db = MCDRV_PLUGDETDB_DISABLE; + hsdet->en_dly_key_off = MCDRV_KEYEN_D_D_D; + hsdet->en_dly_key_on = MCDRV_KEYEN_D_D_D; + hsdet->en_mic_det = MCDRV_MICDET_DISABLE; + hsdet->en_key_off = MCDRV_KEYEN_D_D_D; + hsdet->en_key_on = MCDRV_KEYEN_D_D_D; + hsdet->hs_det_dbnc = MCDRV_DETDBNC_875; + hsdet->key_off_mtim = MCDRV_KEYOFF_MTIM_63; + hsdet->key_on_mtim = MCDRV_KEYON_MTIM_63; + hsdet->key0_off_dly_tim = 0; + hsdet->key1_off_dly_tim = 0; + hsdet->key2_off_dly_tim = 0; + hsdet->key0_on_dly_tim = 0; + hsdet->key1_on_dly_tim = 0; + hsdet->key2_on_dly_tim = 0; + hsdet->key0_on_dly_tim2 = 0; + hsdet->key1_on_dly_tim2 = 0; + hsdet->key2_on_dly_tim2 = 0; + if (mc_info.device_id == MCDRV_DEV_ID_81_91H) + hsdet->irq_type = MCDRV_IRQTYPE_REF; + else + hsdet->irq_type = MCDRV_IRQTYPE_NORMAL; + hsdet->plug_det_db_irq_type = MCDRV_IRQTYPE_REF; + hsdet->plug_undet_db_irq_type = MCDRV_IRQTYPE_REF; + hsdet->mic_det_irq_type = MCDRV_IRQTYPE_REF; + hsdet->plug_det_irq_type = MCDRV_IRQTYPE_REF; + hsdet->key0_on_irq_type = MCDRV_IRQTYPE_REF; + hsdet->key1_on_irq_type = MCDRV_IRQTYPE_REF; + hsdet->key2_on_irq_type = MCDRV_IRQTYPE_REF; + hsdet->key0_off_irq_type = MCDRV_IRQTYPE_REF; + hsdet->key1_off_irq_type = MCDRV_IRQTYPE_REF; + hsdet->key2_off_irq_type = MCDRV_IRQTYPE_REF; + hsdet->det_in_inv = MCDRV_DET_IN_INV; + hsdet->hs_det_mode = MCDRV_HSDET_MODE_DETIN_A; + hsdet->speriod = MCDRV_SPERIOD_3906; + hsdet->lperiod = MCDRV_LPERIOD_125000; + hsdet->dbnc_num_plug = MCDRV_DBNC_NUM_7; + hsdet->dbnc_num_mic = MCDRV_DBNC_NUM_7; + hsdet->dbnc_num_key = MCDRV_DBNC_NUM_7; + hsdet->sgnl_period = MCDRV_SGNLPERIOD_97; + hsdet->sgnl_num = MCDRV_SGNLNUM_8; + hsdet->sgnl_peak = MCDRV_SGNLPEAK_1182; + hsdet->imp_sel = MCDRV_IMPSEL_MOSTFREQ; + hsdet->dly_irq_stop = MCDRV_DLYIRQ_DONTCARE; + hsdet->cbfunc = NULL; +} + +static inline void aec_info_init(void) +{ + struct mcdrv_aec_info *aec_info; + int i; + + aec_info = &mc_info.aec_info; + memset(aec_info, 0, sizeof(struct mcdrv_aec_info)); + + aec_info->output.lpf_pre_thru[0] = 1; + aec_info->output.lpf_post_thru[0] = 1; + + for (i = 0; i < MCDRV_AEC_OUTPUT_N; i++) { + aec_info->output.dcc_sel[i] = 2; + aec_info->output.osf_sel[i] = 3; + aec_info->output.dcl_limit[i][0] = 0x7f; + aec_info->output.dcl_limit[i][1] = 0xff; + aec_info->output.dc_dither_level[i] = 3; + aec_info->output.dng_fw[i] = 1; + } + aec_info->output.dng_zero[0] = 31; + aec_info->output.dng_zero[1] = 9; + aec_info->output.dng_time[1] = 2; + aec_info->output.osf_gain[0][0] = MCI_OSF_GAIN0_15_8_DEF; + aec_info->output.osf_gain[0][1] = MCI_OSF_GAIN0_7_0_DEF; + aec_info->output.osf_gain[1][0] = MCI_OSF_GAIN1_15_8_DEF; + aec_info->output.osf_gain[1][1] = MCI_OSF_GAIN1_7_0_DEF; + aec_info->output.dng_attack = 1; + aec_info->output.dng_release = 3; + aec_info->output.dng_target[0] = 0x84; + if (mc_info.device_id == MCDRV_DEV_ID_80_90H) { + aec_info->output.dng_target[1] = MCI_DNG_SP_DEF_ES1; + aec_info->output.dng_target_lineout[0] = MCI_DNG_LO1_DEF_ES1; + aec_info->output.dng_target_lineout[1] = MCI_DNG_LO2_DEF_ES1; + aec_info->output.dng_target_rc = MCI_DNG_RC_DEF_ES1; + } else { + aec_info->output.dng_target[1] = MCI_DNG_SP_DEF; + aec_info->output.dng_target_lineout[0] = MCI_DNG_LO1_DEF; + aec_info->output.dng_target_lineout[1] = MCI_DNG_LO2_DEF; + aec_info->output.dng_target_rc = MCI_DNG_RC_DEF; + } + + for (i = 0; i < MCDRV_AEC_INPUT_N; i++) { + aec_info->input.dsf32_l_type[i] = 1; + aec_info->input.dsf32_r_type[i] = 1; + aec_info->input.dsf4_sel[i] = 1; + if (mc_info.device_id == MCDRV_DEV_ID_80_90H) + aec_info->input.dcc_sel[i] = 2; + else + aec_info->input.dcc_sel[i] = 1; + aec_info->input.dng_att[i] = 3; + aec_info->input.dng_rel[i] = 2; + aec_info->input.depop_att[i] = 2; + aec_info->input.depop_wait[i] = 2; + } + + aec_info->pdm.st_wait = 2; + + aec_info->adj.hold = 24; + aec_info->adj.cnt = 10; + aec_info->adj.max[0] = 2; +} + +void mc_resource_init(void) +{ + path_info_init(); + vol_info_init(); + dio_info_init(); + dio_path_info_init(); + swap_info_init(); + hsdet_info_init(); + aec_info_init(); + + mc_info.clk = MCDRV_CLKSW_CLKA; + mc_info.clk_sel = 0; + mc_info.eclk_sel = 0; + mc_info.plug_det_db = 0; + + mc_resource_clear(); +} + +void mc_a_registers_init(void) +{ + memset(mc_info.a_registers, 0, MCDRV_REG_NUM_A); + + mc_info.a_registers[MCI_A_DEV_ID] = mc_info.id; + mc_info.a_registers[MCI_CLK_MSK] = MCI_CLK_MSK_DEF; + mc_info.a_registers[MCI_PD] = MCI_PD_DEF; + mc_info.a_registers[MCI_DO0_DRV] = MCI_DO0_DRV_DEF; + mc_info.a_registers[MCI_DO1_DRV] = MCI_DO1_DRV_DEF; + mc_info.a_registers[MCI_DO2_DRV] = MCI_DO2_DRV_DEF; + mc_info.a_registers[MCI_PA0] = MCI_PA0_DEF; + mc_info.a_registers[MCI_PA1] = MCI_PA1_DEF; + mc_info.a_registers[MCI_PA2] = MCI_PA2_DEF; + if (mc_info.device_id != MCDRV_DEV_ID_80_90H) + mc_info.a_registers[MCI_DOA_DRV] = MCI_DOA_DRV_DEF; + mc_info.a_registers[MCI_LP1_FP] = MCI_LP1_FP_DEF; + mc_info.a_registers[MCI_LP2_FP] = MCI_LP2_FP_DEF; + mc_info.a_registers[MCI_LP3_FP] = MCI_LP3_FP_DEF; + mc_info.a_registers[MCI_CLKSRC] = MCI_CLKSRC_DEF; + mc_info.a_registers[MCI_FREQ73M] = MCI_FREQ73M_DEF; + mc_info.a_registers[MCI_PLL_MODE_A] = MCI_PLL_MODE_A_DEF; + mc_info.a_registers[MCI_PLL_MODE_B] = MCI_PLL_MODE_B_DEF; +} + +void mc_mblock_registers_init(void) +{ + memset(mc_info.ma_registers, 0, MCDRV_REG_NUM_MA); + + mc_info.ma_registers[MCI_I_VINTP] = MCI_I_VINTP_DEF; + mc_info.ma_registers[MCI_O_VINTP] = MCI_O_VINTP_DEF; + + memset(mc_info.mb_registers, 0, MCDRV_REG_NUM_MB); + + mc_info.mb_registers[MCI_LP0_MODE] = MCI_LP0_MODE_DEF; + mc_info.mb_registers[MCI_LPR0_SLOT] = MCI_LPR0_SLOT_DEF; + mc_info.mb_registers[MCI_LPT0_SLOT] = MCI_LPT0_SLOT_DEF; + mc_info.mb_registers[MCI_LPR0_PCM] = MCI_LPR0_PCM_DEF; + mc_info.mb_registers[MCI_LPT0_PCM] = MCI_LPT0_PCM_DEF; + mc_info.mb_registers[MCI_LP1_MODE] = MCI_LP1_MODE_DEF; + mc_info.mb_registers[MCI_LPR1_PCM] = MCI_LPR1_PCM_DEF; + mc_info.mb_registers[MCI_LPT1_PCM] = MCI_LPT1_PCM_DEF; + mc_info.mb_registers[MCI_LP2_MODE] = MCI_LP2_MODE_DEF; + mc_info.mb_registers[MCI_LPR2_PCM] = MCI_LPR2_PCM_DEF; + mc_info.mb_registers[MCI_LPT2_PCM] = MCI_LPT2_PCM_DEF; + + memset(mc_info.b_registers, 0, MCDRV_REG_NUM_B); + + mc_e_registers_init(); +} + +void mc_e_registers_init(void) +{ + memset(mc_info.e_registers, 0, MCDRV_REG_NUM_E); + + mc_info.e_registers[MCI_E1DSP_CTRL] = MCI_E1DSP_CTRL_DEF; + mc_info.e_registers[MCI_LPF_THR] = MCI_LPF_THR_DEF; + mc_info.e_registers[MCI_DAC_DCC_SEL] = MCI_DAC_DCC_SEL_DEF; + if (mc_info.device_id == MCDRV_DEV_ID_81_91H) + mc_info.e_registers[MCI_OSF_SEL] = MCI_OSF_SEL_DEF; + mc_info.e_registers[MCI_OSF_GAIN0_15_8] = MCI_OSF_GAIN0_15_8_DEF; + mc_info.e_registers[MCI_OSF_GAIN0_7_0] = MCI_OSF_GAIN0_7_0_DEF; + mc_info.e_registers[MCI_OSF_GAIN1_15_8] = MCI_OSF_GAIN1_15_8_DEF; + mc_info.e_registers[MCI_OSF_GAIN1_7_0] = MCI_OSF_GAIN1_7_0_DEF; + mc_info.e_registers[MCI_DCL0_LMT_14_8] = MCI_DCL0_LMT_14_8_DEF; + mc_info.e_registers[MCI_DCL0_LMT_7_0] = MCI_DCL0_LMT_7_0_DEF; + mc_info.e_registers[MCI_DCL1_LMT_14_8] = MCI_DCL1_LMT_14_8_DEF; + mc_info.e_registers[MCI_DCL1_LMT_7_0] = MCI_DCL1_LMT_7_0_DEF; + switch (mc_info.device_id) { + case MCDRV_DEV_ID_80_90H: + mc_info.e_registers[MCI_DITHER0] = MCI_DITHER0_DEF; + mc_info.e_registers[MCI_DITHER1] = MCI_DITHER1_DEF; + mc_info.e_registers[MCI_DNG0_ES1] = MCI_DNG0_DEF_ES1; + mc_info.e_registers[MCI_DNG1_ES1] = MCI_DNG1_DEF_ES1; + break; + case MCDRV_DEV_ID_81_91H: + mc_info.e_registers[MCI_DITHER0] = 0x30; + mc_info.e_registers[MCI_DITHER1] = 0x30; + mc_info.e_registers[MCI_DNG0] = MCI_DNG0_DEF; + mc_info.e_registers[MCI_DNG1] = MCI_DNG1_DEF; + break; + default: + break; + } + mc_info.e_registers[MCI_DPATH_DA_V] = MCI_DPATH_DA_V_DEF; + mc_info.e_registers[MCI_DPATH_AD_V] = MCI_DPATH_AD_V_DEF; + if (mc_info.device_id == MCDRV_DEV_ID_81_91H) + mc_info.e_registers[39] = 0xf4; + mc_info.e_registers[MCI_DSF0_PRE_INPUT] = MCI_DSF0_PRE_INPUT_DEF; + mc_info.e_registers[MCI_DSF1_FLT_TYPE] = MCI_DSF1_FLT_TYPE_DEF; + mc_info.e_registers[MCI_DSF1_PRE_INPUT] = MCI_DSF1_PRE_INPUT_DEF; + mc_info.e_registers[MCI_DSF2_PRE_INPUT] = MCI_DSF2_PRE_INPUT_DEF; + switch (mc_info.device_id) { + case MCDRV_DEV_ID_80_90H: + mc_info.e_registers[MCI_ADC_DCC_SEL] = MCI_ADC_DCC_SEL_DEF_ES1; + break; + case MCDRV_DEV_ID_81_91H: + mc_info.e_registers[MCI_ADC_DCC_SEL] = MCI_ADC_DCC_SEL_DEF; + break; + default: + break; + } + mc_info.e_registers[MCI_ADC_DNG0_FW] = MCI_ADC_DNG0_FW_DEF; + mc_info.e_registers[MCI_ADC_DNG1_FW] = MCI_ADC_DNG1_FW_DEF; + mc_info.e_registers[MCI_ADC_DNG2_FW] = MCI_ADC_DNG2_FW_DEF; + mc_info.e_registers[MCI_DEPOP0] = MCI_DEPOP0_DEF; + mc_info.e_registers[MCI_DEPOP1] = MCI_DEPOP1_DEF; + mc_info.e_registers[MCI_DEPOP2] = MCI_DEPOP2_DEF; + mc_info.e_registers[MCI_PDM_MODE] = MCI_PDM_MODE_DEF; + mc_info.e_registers[MCI_E2DSP] = MCI_E2DSP_DEF; + if (mc_info.device_id == MCDRV_DEV_ID_81_91H) { + mc_info.e_registers[99] = 0xc9; + mc_info.e_registers[100] = 0x01; + } +} + +void mc_state_update(enum mcdrv_state state) +{ + mc_info.state = state; +} + +enum mcdrv_state mc_state_get(void) +{ + return mc_info.state; +} + +u8 mc_register_get_value(u16 type, u16 addr) +{ + u8 val = 0; + + switch (type) { + case MCDRV_PACKET_REGTYPE_IF: + val = mc_info.if_registers[addr]; + break; + case MCDRV_PACKET_REGTYPE_A: + val = mc_info.a_registers[addr]; + break; + case MCDRV_PACKET_REGTYPE_MA: + val = mc_info.ma_registers[addr]; + break; + case MCDRV_PACKET_REGTYPE_MB: + val = mc_info.mb_registers[addr]; + break; + case MCDRV_PACKET_REGTYPE_E: + val = mc_info.e_registers[addr]; + break; + case MCDRV_PACKET_REGTYPE_ANA: + val = mc_info.ana_registers[addr]; + break; + case MCDRV_PACKET_REGTYPE_CD: + val = mc_info.cd_registers[addr]; + break; + + default: + break; + } + + return val; +} + +void mc_register_set_value(u16 type, u16 addr, u8 val) +{ + switch (type) { + case MCDRV_PACKET_REGTYPE_IF: + mc_info.if_registers[addr] = val; + break; + case MCDRV_PACKET_REGTYPE_A: + mc_info.a_registers[addr] = val; + break; + case MCDRV_PACKET_REGTYPE_MA: + mc_info.ma_registers[addr] = val; + break; + case MCDRV_PACKET_REGTYPE_MB: + mc_info.mb_registers[addr] = val; + break; + case MCDRV_PACKET_REGTYPE_E: + mc_info.e_registers[addr] = val; + break; + case MCDRV_PACKET_REGTYPE_ANA: + mc_info.ana_registers[addr] = val; + break; + case MCDRV_PACKET_REGTYPE_CD: + mc_info.cd_registers[addr] = val; + break; + default: + break; + } +} + +void mc_dev_info_set(struct mcdrv_dev_info *dev_info) +{ + mc_info.dev_info = *dev_info; +} + +void mc_dev_info_get(struct mcdrv_dev_info *dev_info) +{ + *dev_info = mc_info.dev_info; +} + +int mc_clock_set(u8 clock) +{ + mc_info.clk = clock; + + mc_packet_add_switch_clock(clock); + + return mc_packet_execute(); +} + +void mc_clock_get(u8 *clock) +{ + *clock = mc_info.clk; +} + +static void source_set_onoff(u32 src, u32 *dst, u32 on, u32 off) +{ + if (dst) { + if (src & on) { + *dst &= ~off; + *dst |= on; + } else if ((src & (on | off)) == off) { + *dst &= ~on; + *dst |= off; + } + } +} + +static void d1_source_set_onoff(u32 *src, u32 *dst, u8 channels) +{ + int i, j; + + struct { + u32 on; + u32 off; + } d1_src[] = { + { MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_OFF }, + { MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_OFF }, + { MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_OFF }, + { MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_OFF }, + { MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_OFF }, + { MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_OFF }, + { MCDRV_D1SRC_AE2_ON, MCDRV_D1SRC_AE2_OFF }, + { MCDRV_D1SRC_AE3_ON, MCDRV_D1SRC_AE3_OFF }, + { MCDRV_D1SRC_ADIF0_ON, MCDRV_D1SRC_ADIF0_OFF }, + { MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_OFF }, + { MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_ADIF2_OFF }, + { MCDRV_D1SRC_HIFIIN_ON, MCDRV_D1SRC_HIFIIN_OFF } + }; + + for (i = 0; i < channels; i++) { + for (j = 0; j < ARRAY_SIZE(d1_src); j++) + source_set_onoff(src[i], &dst[i], + d1_src[j].on, d1_src[j].off); + } +} + +static void d2_source_set_onoff(u32 *src, u32 *dst, u8 channels) +{ + u32 on, off; + int i, j; + + struct { + u32 on; + u32 off; + } d2_src[] = { + { MCDRV_D2SRC_VOICEIN_ON, MCDRV_D2SRC_VOICEIN_OFF }, + { MCDRV_D2SRC_VBOXIOOUT_ON, MCDRV_D2SRC_VBOXIOOUT_OFF }, + { MCDRV_D2SRC_VBOXHOSTOUT_ON, MCDRV_D2SRC_VBOXHOSTOUT_OFF }, + { MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_L_OFF }, + { MCDRV_D2SRC_ADC0_R_ON, MCDRV_D2SRC_ADC0_R_OFF }, + { MCDRV_D2SRC_ADC1_ON, MCDRV_D2SRC_ADC1_OFF }, + { MCDRV_D2SRC_PDM0_L_ON, MCDRV_D2SRC_PDM0_L_OFF }, + { MCDRV_D2SRC_PDM0_R_ON, MCDRV_D2SRC_PDM0_R_OFF }, + { MCDRV_D2SRC_PDM1_L_ON, MCDRV_D2SRC_PDM1_L_OFF }, + { MCDRV_D2SRC_PDM1_R_ON, MCDRV_D2SRC_PDM1_R_OFF }, + { MCDRV_D2SRC_DAC0REF_ON, MCDRV_D2SRC_DAC0REF_OFF }, + { MCDRV_D2SRC_DAC1REF_ON, MCDRV_D2SRC_DAC1REF_OFF } + }; + + for (i = 0; i < channels; i++) { + for (j = 0; j < ARRAY_SIZE(d2_src); j++) { + on = d2_src[j].on; + off = d2_src[j].off; + if ((src[i] & on) + && (on == MCDRV_D2SRC_PDM0_L_ON || + on == MCDRV_D2SRC_PDM0_R_ON || + on == MCDRV_D2SRC_PDM1_L_ON || + on == MCDRV_D2SRC_PDM1_R_ON) + && mc_info.dev_info.pa0_func != MCDRV_PA_PDMCK) + break; + + source_set_onoff(src[i], &dst[i], on, off); + } + } +} + +static void a_source_set_onoff(u32 *src, u32 *dst, u8 channels) +{ + int i, j; + + struct { + u32 on; + u32 off; + } a_src[] = { + { MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_L_OFF }, + { MCDRV_ASRC_DAC0_R_ON, MCDRV_ASRC_DAC0_R_OFF }, + { MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_L_OFF }, + { MCDRV_ASRC_DAC1_R_ON, MCDRV_ASRC_DAC1_R_OFF }, + { MCDRV_ASRC_MIC1_ON, MCDRV_ASRC_MIC1_OFF }, + { MCDRV_ASRC_MIC2_ON, MCDRV_ASRC_MIC2_OFF }, + { MCDRV_ASRC_MIC3_ON, MCDRV_ASRC_MIC3_OFF }, + { MCDRV_ASRC_MIC4_ON, MCDRV_ASRC_MIC4_OFF }, + { MCDRV_ASRC_LINEIN1_L_ON, MCDRV_ASRC_LINEIN1_L_OFF }, + { MCDRV_ASRC_LINEIN1_R_ON, MCDRV_ASRC_LINEIN1_R_OFF }, + { MCDRV_ASRC_LINEIN1_M_ON, MCDRV_ASRC_LINEIN1_M_OFF } + }; + + for (i = 0; i < channels; i++) { + for (j = 0; j < ARRAY_SIZE(a_src); j++) + source_set_onoff(src[i], &dst[i], + a_src[j].on, a_src[j].off); + } +} + +static inline void bias_source_set_onoff(struct mcdrv_path_info *path_info) +{ + int i, j; + + struct { + u32 on; + u32 off; + } bias[] = { + { MCDRV_ASRC_MIC1_ON, MCDRV_ASRC_MIC1_OFF }, + { MCDRV_ASRC_MIC2_ON, MCDRV_ASRC_MIC2_OFF }, + { MCDRV_ASRC_MIC3_ON, MCDRV_ASRC_MIC3_OFF }, + { MCDRV_ASRC_MIC4_ON, MCDRV_ASRC_MIC4_OFF } + }; + + for (i = 0; i < BIAS_PATH_CHANNELS; i++) { + for (j = 0; j < ARRAY_SIZE(bias); j++) { + source_set_onoff(path_info->bias[i], + &mc_info.path_info.bias[i], + bias[j].on, bias[j].off); + } + } +} + +static inline int is_valid_path(void) +{ + u32 dac[2], adif[2], src; + int used, i; + + dac[0] = mc_info.path_info.dac0[0]; + dac[1] = mc_info.path_info.dac0[1]; + + if ((dac[0] & MCDRV_D1SRC_HIFIIN_ON) + || (dac[1] & MCDRV_D1SRC_HIFIIN_ON)) { + if ((dac[0] & (MCDRV_D1SRC_ALL_ON & ~MCDRV_D1SRC_HIFIIN_ON)) + || (dac[1] & (MCDRV_D1SRC_ALL_ON & ~MCDRV_D1SRC_HIFIIN_ON))) + return -EINVAL; + + if (mc_info.device_id == MCDRV_DEV_ID_80_90H) { + for (i = 0; i < MUSICOUT_PATH_CHANNELS; i++) { + src = mc_info.path_info.music_out[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + } + + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) { + src = mc_info.path_info.ext_out[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + } + + for (i = 0; i < VBOXMIXIN_PATH_CHANNELS; i++) { + src = mc_info.path_info.vbox_mix_in[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + } + + for (i = 0; i < AE_PATH_CHANNELS; i++) { + src = mc_info.path_info.ae0[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + + src = mc_info.path_info.ae1[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + + src = mc_info.path_info.ae2[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + + src = mc_info.path_info.ae3[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + } + + for (i = 0; i < DAC1_PATH_CHANNELS; i++) { + src = mc_info.path_info.dac1[i]; + if (src & MCDRV_D1SRC_ADIF0_ON) + return -EINVAL; + } + } + } + + dac[0] = mc_info.path_info.dac1[0]; + dac[1] = mc_info.path_info.dac1[1]; + + if ((dac[0] & MCDRV_D1SRC_HIFIIN_ON) + || (dac[1] & MCDRV_D1SRC_HIFIIN_ON)) { + if ((dac[0] & (MCDRV_D1SRC_ALL_ON & ~MCDRV_D1SRC_HIFIIN_ON)) + || (dac[1] & (MCDRV_D1SRC_ALL_ON & ~MCDRV_D1SRC_HIFIIN_ON))) + return -EINVAL; + } + + for (i = 0; i < ADIF0_PATH_CHANNELS; i++) { + adif[i] = mc_info.path_info.adif0[i]; + + used = 0; + if (adif[i] & MCDRV_D2SRC_ADC0_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_ADC0_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_ADC1_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM0_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM0_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM1_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM1_R_ON) + used++; + if (used > 1) + return -EINVAL; + } + + if (adif[0] == D2SRC_ALL_OFF && adif[1] != D2SRC_ALL_OFF) + return -EINVAL; + + for (i = 0; i < ADIF1_PATH_CHANNELS; i++) { + adif[i] = mc_info.path_info.adif1[i]; + + used = 0; + if (adif[i] & MCDRV_D2SRC_ADC0_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_ADC0_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_ADC1_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM0_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM0_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM1_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM1_R_ON) + used++; + if (used > 1) + return -EINVAL; + } + + if (adif[0] == D2SRC_ALL_OFF && adif[1] != D2SRC_ALL_OFF) + return -EINVAL; + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + if (!i) + adif[i] = mc_source_get(MCDRV_DST_ADIF2, MCDRV_DST_CH0); + else + adif[i] = mc_source_get(MCDRV_DST_ADIF2, MCDRV_DST_CH1); + + used = 0; + if (adif[i] & MCDRV_D2SRC_ADC0_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_ADC0_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_ADC1_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM0_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM0_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM1_L_ON) + used++; + if (adif[i] & MCDRV_D2SRC_PDM1_R_ON) + used++; + if (adif[i] & MCDRV_D2SRC_DAC0REF_ON) + used++; + if (adif[i] & MCDRV_D2SRC_DAC1REF_ON) + used++; + if (used > 1) + return -EINVAL; + } + + if (!(adif[0] & ~D2SRC_ALL_OFF) + && (adif[1] & ~D2SRC_ALL_OFF)) + return -EINVAL; + + if ((adif[0] & MCDRV_D2SRC_DAC0REF_ON) + && (adif[1] & ~MCDRV_D2SRC_DAC0REF_ON)) + return -EINVAL; + + if ((adif[1] & MCDRV_D2SRC_DAC0REF_ON) + && (adif[0] & ~MCDRV_D2SRC_DAC0REF_ON)) + return -EINVAL; + + if ((adif[0] & MCDRV_D2SRC_DAC1REF_ON) + && (adif[1] & ~MCDRV_D2SRC_DAC1REF_ON)) + return -EINVAL; + + if ((adif[1] & MCDRV_D2SRC_DAC1REF_ON) + && (adif[0] & ~MCDRV_D2SRC_DAC1REF_ON)) + return -EINVAL; + + for (i = 0; i < ADC0_PATH_CHANNELS; i++) { + used = 0; + src = mc_info.path_info.adc0[i]; + if (src & MCDRV_ASRC_LINEIN1_L_ON) + used++; + if (src & MCDRV_ASRC_LINEIN1_R_ON) + used++; + if (src & MCDRV_ASRC_LINEIN1_M_ON) + used++; + if (used > 1) + return -EINVAL; + } + + return 0; +} + +static inline int phys_port_check(void) +{ + u32 port[4] = { MCDRV_PHYSPORT_NONE, MCDRV_PHYSPORT_NONE, + MCDRV_PHYSPORT_NONE, MCDRV_PHYSPORT_NONE + }; + int i, j; + + if (mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1) + || mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) { + port[0] = mc_info.dio_path_info.phys_port[0]; + if (port[0] == MCDRV_PHYSPORT_NONE) + return -EINVAL; + } + + if (mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1) + || mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) { + port[1] = mc_info.dio_path_info.phys_port[1]; + if (port[1] == MCDRV_PHYSPORT_NONE) + return -EINVAL; + } + + if (mc_source_is_used(MCDRV_DST_VOICEOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_VBOXIOIN, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_VBOXIOIN, MCDRV_DST_CH0)) { + port[2] = mc_info.dio_path_info.phys_port[2]; + if (port[2] == MCDRV_PHYSPORT_NONE) + return -EINVAL; + } + + if (mc_source_is_used(MCDRV_DST_HIFIOUT, MCDRV_DST_CH0) + || mc_d1_source_is_used(MCDRV_D1SRC_HIFIIN_ON)) { + port[3] = mc_info.dio_path_info.phys_port[3]; + if (port[3] == MCDRV_PHYSPORT_NONE) + return -EINVAL; + } + + for (i = 0; i < 4; i++) { + if (port[i] == MCDRV_PHYSPORT_NONE) + continue; + + for (j = i + 1; j < 4; j++) { + if (port[i] == port[j]) + return -EINVAL; + } + } + + return 0; +} + +static inline int adc_validate(void) +{ + struct mcdrv_path_info *path_info; + u32 hifi_out; + int has_src, i, ret = 0; + + path_info = &mc_info.path_info; + + has_src = 0; + if (mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF0, MCDRV_DST_CH1)) + has_src = 1; + + hifi_out = path_info->hifi_out[0]; + + if ((mc_d1_source_is_used(MCDRV_D1SRC_ADIF0_ON) + || (hifi_out & MCDRV_D1SRC_ADIF0_ON)) && !has_src) { + for (i = 0; i < MUSICOUT_PATH_CHANNELS; i++) { + path_info->music_out[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->music_out[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) { + path_info->ext_out[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->ext_out[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + for (i = 0; i < HIFIOUT_PATH_CHANNELS; i++) { + path_info->hifi_out[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->hifi_out[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + for (i = 0; i < VBOXMIXIN_PATH_CHANNELS; i++) { + path_info->vbox_mix_in[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->vbox_mix_in[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + for (i = 0; i < AE_PATH_CHANNELS; i++) { + path_info->ae0[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->ae0[i] |= MCDRV_D1SRC_ADIF0_OFF; + path_info->ae1[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->ae1[i] |= MCDRV_D1SRC_ADIF0_OFF; + path_info->ae2[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->ae2[i] |= MCDRV_D1SRC_ADIF0_OFF; + path_info->ae3[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->ae3[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + for (i = 0; i < DAC0_PATH_CHANNELS; i++) { + path_info->dac0[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->dac0[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + for (i = 0; i < DAC1_PATH_CHANNELS; i++) { + path_info->dac1[i] &= ~MCDRV_D1SRC_ADIF0_ON; + path_info->dac1[i] |= MCDRV_D1SRC_ADIF0_OFF; + } + + ret = 1; + } + + has_src = 0; + if (mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF1, MCDRV_DST_CH1)) + has_src = 1; + if (mc_d1_source_is_used(MCDRV_D1SRC_ADIF1_ON) && !has_src) { + for (i = 0; i < MUSICOUT_PATH_CHANNELS; i++) { + path_info->music_out[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->music_out[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) { + path_info->ext_out[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->ext_out[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + for (i = 0; i < HIFIOUT_PATH_CHANNELS; i++) { + path_info->hifi_out[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->hifi_out[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + for (i = 0; i < VBOXMIXIN_PATH_CHANNELS; i++) { + path_info->vbox_mix_in[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->vbox_mix_in[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + for (i = 0; i < AE_PATH_CHANNELS; i++) { + path_info->ae0[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->ae0[i] |= MCDRV_D1SRC_ADIF1_OFF; + path_info->ae1[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->ae1[i] |= MCDRV_D1SRC_ADIF1_OFF; + path_info->ae2[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->ae2[i] |= MCDRV_D1SRC_ADIF1_OFF; + path_info->ae3[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->ae3[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + for (i = 0; i < DAC0_PATH_CHANNELS; i++) { + path_info->dac0[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->dac0[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + for (i = 0; i < DAC1_PATH_CHANNELS; i++) { + path_info->dac1[i] &= ~MCDRV_D1SRC_ADIF1_ON; + path_info->dac1[i] |= MCDRV_D1SRC_ADIF1_OFF; + } + + ret = 1; + } + + has_src = 0; + if (mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_ADIF2, MCDRV_DST_CH1)) + has_src = 1; + if (mc_d1_source_is_used(MCDRV_D1SRC_ADIF2_ON) && !has_src) { + for (i = 0; i < MUSICOUT_PATH_CHANNELS; i++) { + path_info->music_out[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->music_out[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) { + path_info->ext_out[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->ext_out[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + for (i = 0; i < HIFIOUT_PATH_CHANNELS; i++) { + path_info->hifi_out[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->hifi_out[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + for (i = 0; i < VBOXMIXIN_PATH_CHANNELS; i++) { + path_info->vbox_mix_in[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->vbox_mix_in[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + for (i = 0; i < AE_PATH_CHANNELS; i++) { + path_info->ae0[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->ae0[i] |= MCDRV_D1SRC_ADIF2_OFF; + path_info->ae1[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->ae1[i] |= MCDRV_D1SRC_ADIF2_OFF; + path_info->ae2[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->ae2[i] |= MCDRV_D1SRC_ADIF2_OFF; + path_info->ae3[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->ae3[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + for (i = 0; i < DAC0_PATH_CHANNELS; i++) { + path_info->dac0[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->dac0[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + for (i = 0; i < DAC1_PATH_CHANNELS; i++) { + path_info->dac1[i] &= ~MCDRV_D1SRC_ADIF2_ON; + path_info->dac1[i] |= MCDRV_D1SRC_ADIF2_OFF; + } + + ret = 1; + } + + has_src = 0; + if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH0)) + has_src = 1; + if (!mc_d2_source_is_used(MCDRV_D2SRC_ADC0_L_ON)) { + if (has_src) { + path_info->adc0[0] = D2SRC_ALL_OFF; + ret = 1; + } + } else if (!has_src) { + for (i = 0; i < ADIF0_PATH_CHANNELS; i++) { + path_info->adif0[i] &= ~MCDRV_D2SRC_ADC0_L_ON; + path_info->adif0[i] |= MCDRV_D2SRC_ADC0_L_OFF; + } + + for (i = 0; i < ADIF1_PATH_CHANNELS; i++) { + path_info->adif1[i] &= ~MCDRV_D2SRC_ADC0_L_ON; + path_info->adif1[i] |= MCDRV_D2SRC_ADC0_L_OFF; + } + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + path_info->adif2[i] &= ~MCDRV_D2SRC_ADC0_L_ON; + path_info->adif2[i] |= MCDRV_D2SRC_ADC0_L_OFF; + } + + ret = 1; + } + + has_src = 0; + if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH1)) + has_src = 1; + if (!mc_d2_source_is_used(MCDRV_D2SRC_ADC0_R_ON)) { + if (has_src) { + path_info->adc0[1] = D2SRC_ALL_OFF; + ret = 1; + } + } else if (!has_src) { + for (i = 0; i < ADIF0_PATH_CHANNELS; i++) { + path_info->adif0[i] &= ~MCDRV_D2SRC_ADC0_R_ON; + path_info->adif0[i] |= MCDRV_D2SRC_ADC0_R_OFF; + } + + for (i = 0; i < ADIF1_PATH_CHANNELS; i++) { + path_info->adif1[i] &= ~MCDRV_D2SRC_ADC0_R_ON; + path_info->adif1[i] |= MCDRV_D2SRC_ADC0_R_OFF; + } + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + path_info->adif2[i] &= ~MCDRV_D2SRC_ADC0_R_ON; + path_info->adif2[i] |= MCDRV_D2SRC_ADC0_R_OFF; + } + + ret = 1; + } + + has_src = 0; + if (mc_source_is_used(MCDRV_DST_ADC1, MCDRV_DST_CH0)) + has_src = 1; + if (!mc_d2_source_is_used(MCDRV_D2SRC_ADC1_ON)) { + if (has_src) { + for (i = 0; i < ADC1_PATH_CHANNELS; i++) + path_info->adc1[i] = D2SRC_ALL_OFF; + ret = 1; + } + } else if (!has_src) { + for (i = 0; i < ADIF0_PATH_CHANNELS; i++) { + path_info->adif0[i] &= ~MCDRV_D2SRC_ADC1_ON; + path_info->adif0[i] |= MCDRV_D2SRC_ADC1_OFF; + } + + for (i = 0; i < ADIF1_PATH_CHANNELS; i++) { + path_info->adif1[i] &= ~MCDRV_D2SRC_ADC1_ON; + path_info->adif1[i] |= MCDRV_D2SRC_ADC1_OFF; + } + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + path_info->adif2[i] &= ~MCDRV_D2SRC_ADC1_ON; + path_info->adif2[i] |= MCDRV_D2SRC_ADC1_OFF; + } + + ret = 1; + } + + return ret; +} + +static inline int dac_validate(void) +{ + struct mcdrv_path_info *path_info; + int has_src, used, i, ret = 0; + + path_info = &mc_info.path_info; + + has_src = 0; + used = 0; + if (mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1)) + has_src = 1; + + if (mc_a_source_is_used(MCDRV_ASRC_DAC0_L_ON) + || mc_a_source_is_used(MCDRV_ASRC_DAC0_R_ON)) + used = 1; + else { + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + if (path_info->adif2[i] & MCDRV_D2SRC_DAC0REF_ON) + used = 1; + } + } + if (!has_src) { + if (used) { + for (i = 0; i < HP_PATH_CHANNELS; i++) { + path_info->hp[i] &= ~MCDRV_ASRC_DAC0_L_ON; + path_info->hp[i] |= MCDRV_ASRC_DAC0_L_OFF; + path_info->hp[i] &= ~MCDRV_ASRC_DAC0_R_ON; + path_info->hp[i] |= MCDRV_ASRC_DAC0_R_OFF; + } + + for (i = 0; i < RC_PATH_CHANNELS; i++) { + path_info->rc[i] &= ~MCDRV_ASRC_DAC0_L_ON; + path_info->rc[i] |= MCDRV_ASRC_DAC0_L_OFF; + path_info->rc[i] &= ~MCDRV_ASRC_DAC0_R_ON; + path_info->rc[i] |= MCDRV_ASRC_DAC0_R_OFF; + } + + for (i = 0; i < LOUT1_PATH_CHANNELS; i++) { + path_info->lout1[i] &= ~MCDRV_ASRC_DAC0_L_ON; + path_info->lout1[i] |= MCDRV_ASRC_DAC0_L_OFF; + path_info->lout1[i] &= ~MCDRV_ASRC_DAC0_R_ON; + path_info->lout1[i] |= MCDRV_ASRC_DAC0_R_OFF; + } + + ret = 1; + } + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + if (path_info->adif2[i] & MCDRV_D2SRC_DAC0REF_ON) { + path_info->adif2[i] &= ~MCDRV_D2SRC_DAC0REF_ON; + ret = 1; + } + } + } + + has_src = 0; + used = 0; + if (mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) + has_src = 1; + if (mc_a_source_is_used(MCDRV_ASRC_DAC1_L_ON) + || mc_a_source_is_used(MCDRV_ASRC_DAC1_R_ON)) + used = 1; + else { + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + if (path_info->adif2[i] & MCDRV_D2SRC_DAC1REF_ON) + used = 1; + } + } + if (!has_src) { + if (used) { + ret = 1; + for (i = 0; i < SP_PATH_CHANNELS; i++) { + path_info->sp[i] &= ~MCDRV_ASRC_DAC1_L_ON; + path_info->sp[i] |= MCDRV_ASRC_DAC1_L_OFF; + path_info->sp[i] &= ~MCDRV_ASRC_DAC1_R_ON; + path_info->sp[i] |= MCDRV_ASRC_DAC1_R_OFF; + } + + for (i = 0; i < LOUT2_PATH_CHANNELS; i++) { + path_info->lout2[i] &= ~MCDRV_ASRC_DAC1_L_ON; + path_info->lout2[i] |= MCDRV_ASRC_DAC1_L_OFF; + path_info->lout2[i] &= ~MCDRV_ASRC_DAC1_R_ON; + path_info->lout2[i] |= MCDRV_ASRC_DAC1_R_OFF; + } + } + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + if (path_info->adif2[i] & MCDRV_D2SRC_DAC1REF_ON) { + path_info->adif2[i] &= ~MCDRV_D2SRC_DAC1REF_ON; + ret = 1; + } + } + } + + return ret; +} + +int mc_path_info_set(struct mcdrv_path_info *path_info) +{ + struct mcdrv_path_info old_path_info; + int cont, i, ret; + + old_path_info = mc_info.path_info; + mc_info.path_info = mc_info.path_info_virtual; + + d1_source_set_onoff(path_info->music_out, + mc_info.path_info.music_out, + MUSICOUT_PATH_CHANNELS); + d1_source_set_onoff(path_info->ext_out, + mc_info.path_info.ext_out, EXTOUT_PATH_CHANNELS); + d1_source_set_onoff(path_info->hifi_out, + mc_info.path_info.hifi_out, HIFIOUT_PATH_CHANNELS); + d1_source_set_onoff(path_info->vbox_mix_in, + mc_info.path_info.vbox_mix_in, + VBOXMIXIN_PATH_CHANNELS); + d1_source_set_onoff(path_info->ae0, + mc_info.path_info.ae0, AE_PATH_CHANNELS); + d1_source_set_onoff(path_info->ae1, + mc_info.path_info.ae1, AE_PATH_CHANNELS); + d1_source_set_onoff(path_info->ae2, + mc_info.path_info.ae2, AE_PATH_CHANNELS); + d1_source_set_onoff(path_info->ae3, + mc_info.path_info.ae3, AE_PATH_CHANNELS); + d1_source_set_onoff(path_info->dac0, + mc_info.path_info.dac0, DAC0_PATH_CHANNELS); + d1_source_set_onoff(path_info->dac1, + mc_info.path_info.dac1, DAC1_PATH_CHANNELS); + + d2_source_set_onoff(path_info->voice_out, + mc_info.path_info.voice_out, + VOICEOUT_PATH_CHANNELS); + d2_source_set_onoff(path_info->vbox_io_in, + mc_info.path_info.vbox_io_in, + VBOXIOIN_PATH_CHANNELS); + d2_source_set_onoff(path_info->vbox_host_in, + mc_info.path_info.vbox_host_in, + VBOXHOSTIN_PATH_CHANNELS); + d2_source_set_onoff(path_info->host_out, + mc_info.path_info.host_out, HOSTOUT_PATH_CHANNELS); + d2_source_set_onoff(path_info->adif0, + mc_info.path_info.adif0, ADIF0_PATH_CHANNELS); + d2_source_set_onoff(path_info->adif1, + mc_info.path_info.adif1, ADIF1_PATH_CHANNELS); + d2_source_set_onoff(path_info->adif2, + mc_info.path_info.adif2, ADIF2_PATH_CHANNELS); + + a_source_set_onoff(path_info->adc0, + mc_info.path_info.adc0, ADC0_PATH_CHANNELS); + a_source_set_onoff(path_info->adc1, + mc_info.path_info.adc1, ADC1_PATH_CHANNELS); + a_source_set_onoff(path_info->sp, + mc_info.path_info.sp, SP_PATH_CHANNELS); + a_source_set_onoff(path_info->hp, + mc_info.path_info.hp, HP_PATH_CHANNELS); + a_source_set_onoff(path_info->rc, + mc_info.path_info.rc, RC_PATH_CHANNELS); + a_source_set_onoff(path_info->lout1, + mc_info.path_info.lout1, LOUT1_PATH_CHANNELS); + a_source_set_onoff(path_info->lout2, + mc_info.path_info.lout2, LOUT2_PATH_CHANNELS); + + bias_source_set_onoff(path_info); + + ret = is_valid_path(); + if (ret < 0) { + mc_info.path_info = old_path_info; + return ret; + } + + ret = phys_port_check(); + if (ret < 0) { + mc_info.path_info = old_path_info; + return ret; + } + + mc_info.path_info_virtual = mc_info.path_info; + + for (i = 0, cont = 1; i < 3 && cont; i++) { + cont = adc_validate(); + cont |= dac_validate(); + } + + return 0; +} + +void mc_path_info_get(struct mcdrv_path_info *path_info) +{ + *path_info = mc_info.path_info; +} + +void mc_path_info_get_virtual(struct mcdrv_path_info *path_info) +{ + *path_info = mc_info.path_info_virtual; +} + +void mc_vol_info_set(struct mcdrv_vol_info *vol_info) +{ + int i; + + for (i = 0; i < MUSICIN_VOL_CHANNELS; i++) { + if (vol_info->d_music_in[i] & 1) + mc_info.vol_info.d_music_in[i] = + vol_info->d_music_in[i] & ~1; + } + + for (i = 0; i < EXTIN_VOL_CHANNELS; i++) { + if (vol_info->d_ext_in[i] & 1) + mc_info.vol_info.d_ext_in[i] = + vol_info->d_ext_in[i] & ~1; + } + + for (i = 0; i < VOICEIN_VOL_CHANNELS; i++) { + if (vol_info->d_voice_in[i] & 1) + mc_info.vol_info.d_voice_in[i] = + vol_info->d_voice_in[i] & ~1; + } + + for (i = 0; i < REFIN_VOL_CHANNELS; i++) { + if (vol_info->d_ref_in[i] & 1) + mc_info.vol_info.d_ref_in[i] = + vol_info->d_ref_in[i] & ~1; + } + + for (i = 0; i < ADIF0IN_VOL_CHANNELS; i++) { + if (vol_info->d_adif0_in[i] & 1) + mc_info.vol_info.d_adif0_in[i] = + vol_info->d_adif0_in[i] & ~1; + } + + for (i = 0; i < ADIF1IN_VOL_CHANNELS; i++) { + if (vol_info->d_adif1_in[i] & 1) + mc_info.vol_info.d_adif1_in[i] = + vol_info->d_adif1_in[i] & ~1; + } + + for (i = 0; i < ADIF2IN_VOL_CHANNELS; i++) { + if (vol_info->d_adif2_in[i] & 1) + mc_info.vol_info.d_adif2_in[i] = + vol_info->d_adif2_in[i] & ~1; + } + + for (i = 0; i < MUSICOUT_VOL_CHANNELS; i++) { + if (vol_info->d_music_out[i] & 1) + mc_info.vol_info.d_music_out[i] = + vol_info->d_music_out[i] & ~1; + } + + for (i = 0; i < EXTOUT_VOL_CHANNELS; i++) { + if (vol_info->d_ext_out[i] & 1) + mc_info.vol_info.d_ext_out[i] = + vol_info->d_ext_out[i] & ~1; + } + + for (i = 0; i < VOICEOUT_VOL_CHANNELS; i++) { + if (vol_info->d_voice_out[i] & 1) + mc_info.vol_info.d_voice_out[i] = + vol_info->d_voice_out[i] & ~1; + } + + for (i = 0; i < REFOUT_VOL_CHANNELS; i++) { + if (vol_info->d_ref_out[i] & 1) + mc_info.vol_info.d_ref_out[i] = + vol_info->d_ref_out[i] & ~1; + } + + for (i = 0; i < DAC0OUT_VOL_CHANNELS; i++) { + if (vol_info->d_dac0_out[i] & 1) + mc_info.vol_info.d_dac0_out[i] = + vol_info->d_dac0_out[i] & ~1; + } + + for (i = 0; i < DAC1OUT_VOL_CHANNELS; i++) { + if (vol_info->d_dac1_out[i] & 1) + mc_info.vol_info.d_dac1_out[i] = + vol_info->d_dac1_out[i] & ~1; + } + + for (i = 0; i < DPATH_VOL_CHANNELS; i++) { + if (vol_info->d_dpath_da[i] & 1) + mc_info.vol_info.d_dpath_da[i] = + vol_info->d_dpath_da[i] & ~1; + + if (vol_info->d_dpath_ad[i] & 1) + mc_info.vol_info.d_dpath_ad[i] = + vol_info->d_dpath_ad[i] & ~1; + } + + for (i = 0; i < LINEIN1_VOL_CHANNELS; i++) { + if (vol_info->a_line_in1[i] & 1) + mc_info.vol_info.a_line_in1[i] = + vol_info->a_line_in1[i] & ~1; + } + + for (i = 0; i < MIC1_VOL_CHANNELS; i++) { + if (vol_info->a_mic1[i] & 1) + mc_info.vol_info.a_mic1[i] = vol_info->a_mic1[i] & ~1; + } + + for (i = 0; i < MIC2_VOL_CHANNELS; i++) { + if (vol_info->a_mic2[i] & 1) + mc_info.vol_info.a_mic2[i] = vol_info->a_mic2[i] & ~1; + } + + for (i = 0; i < MIC3_VOL_CHANNELS; i++) { + if (vol_info->a_mic3[i] & 1) + mc_info.vol_info.a_mic3[i] = vol_info->a_mic3[i] & ~1; + } + + for (i = 0; i < MIC4_VOL_CHANNELS; i++) { + if (vol_info->a_mic4[i] & 1) + mc_info.vol_info.a_mic4[i] = vol_info->a_mic4[i] & ~1; + } + + for (i = 0; i < HP_VOL_CHANNELS; i++) { + if (vol_info->a_hp[i] & 1) + mc_info.vol_info.a_hp[i] = vol_info->a_hp[i] & ~1; + } + + for (i = 0; i < SP_VOL_CHANNELS; i++) { + if (vol_info->a_sp[i] & 1) + mc_info.vol_info.a_sp[i] = vol_info->a_sp[i] & ~1; + } + + for (i = 0; i < RC_VOL_CHANNELS; i++) { + if (vol_info->a_rc[i] & 1) + mc_info.vol_info.a_rc[i] = vol_info->a_rc[i] & ~1; + } + + for (i = 0; i < LINEOUT1_VOL_CHANNELS; i++) { + if (vol_info->a_line_out1[i] & 1) + mc_info.vol_info.a_line_out1[i] = + vol_info->a_line_out1[i] & ~1; + } + + for (i = 0; i < LINEOUT2_VOL_CHANNELS; i++) { + if (vol_info->a_line_out2[i] & 1) + mc_info.vol_info.a_line_out2[i] = + vol_info->a_line_out2[i] & ~1; + } + + for (i = 0; i < HPDET_VOL_CHANNELS; i++) { + if (vol_info->a_hp_det[i] & 1) + mc_info.vol_info.a_hp_det[i] = + vol_info->a_hp_det[i] & ~1; + } +} + +void mc_vol_info_get(struct mcdrv_vol_info *vol_info) +{ + *vol_info = mc_info.vol_info; +} + +static void dio_common_set(struct mcdrv_dio_common *dio_common, u8 port) +{ + struct mcdrv_dio_common *common; + + common = &mc_info.dio_info.port[port].dio_common; + + common->master_slave = dio_common->master_slave; + common->auto_fs = dio_common->auto_fs; + common->fs = dio_common->fs; + common->bck_fs = dio_common->bck_fs; + common->interface = dio_common->interface; + common->bck_invert = dio_common->bck_invert; + common->src_thru = dio_common->src_thru; + + if (dio_common->interface == MCDRV_DIO_PCM) { + common->pcm_hiz_transition = dio_common->pcm_hiz_transition; + common->pcm_frame = dio_common->pcm_frame; + common->pcm_high_period = dio_common->pcm_high_period; + } +} + +static void dio_dir_set(struct mcdrv_dio_dir *dio_dir, u8 port) +{ + struct mcdrv_dio_dir *dir; + + dir = &mc_info.dio_info.port[port].dir; + + if (mc_info.dio_info.port[port].dio_common.interface == MCDRV_DIO_DA) { + dir->da_format.bit_sel = dio_dir->da_format.bit_sel; + dir->da_format.mode = dio_dir->da_format.mode; + } else { + dir->pcm_format.mono = dio_dir->pcm_format.mono; + dir->pcm_format.order = dio_dir->pcm_format.order; + dir->pcm_format.law = dio_dir->pcm_format.law; + dir->pcm_format.bit_sel = dio_dir->pcm_format.bit_sel; + } +} + +static void dio_dit_set(struct mcdrv_dio_dit *dio_dit, u8 port) +{ + struct mcdrv_dio_dit *dit; + + dit = &mc_info.dio_info.port[port].dit; + + dit->st_mode = dio_dit->st_mode; + dit->edge = dio_dit->edge; + if (mc_info.dio_info.port[port].dio_common.interface == MCDRV_DIO_DA) { + dit->da_format.bit_sel = dio_dit->da_format.bit_sel; + dit->da_format.mode = dio_dit->da_format.mode; + } else { + dit->pcm_format.mono = dio_dit->pcm_format.mono; + dit->pcm_format.order = dio_dit->pcm_format.order; + dit->pcm_format.law = dio_dit->pcm_format.law; + dit->pcm_format.bit_sel = dio_dit->pcm_format.bit_sel; + } +} + +void mc_dio_info_set(struct mcdrv_dio_info *dio_info, u32 update) +{ + if (update & MCDRV_MUSIC_COM_UPDATE_FLAG) + dio_common_set(&dio_info->port[0].dio_common, 0); + + if (update & MCDRV_EXT_COM_UPDATE_FLAG) + dio_common_set(&dio_info->port[1].dio_common, 1); + + if (update & MCDRV_VOICE_COM_UPDATE_FLAG) + dio_common_set(&dio_info->port[2].dio_common, 2); + + if (update & MCDRV_HIFI_COM_UPDATE_FLAG) + dio_common_set(&dio_info->port[3].dio_common, 3); + + if (update & MCDRV_MUSIC_DIR_UPDATE_FLAG) + dio_dir_set(&dio_info->port[0].dir, 0); + + if (update & MCDRV_EXT_DIR_UPDATE_FLAG) + dio_dir_set(&dio_info->port[1].dir, 1); + + if (update & MCDRV_VOICE_DIR_UPDATE_FLAG) + dio_dir_set(&dio_info->port[2].dir, 2); + + if (update & MCDRV_HIFI_DIR_UPDATE_FLAG) + dio_dir_set(&dio_info->port[3].dir, 3); + + if (update & MCDRV_MUSIC_DIT_UPDATE_FLAG) + dio_dit_set(&dio_info->port[0].dit, 0); + + if (update & MCDRV_EXT_DIT_UPDATE_FLAG) + dio_dit_set(&dio_info->port[1].dit, 1); + + if (update & MCDRV_VOICE_DIT_UPDATE_FLAG) + dio_dit_set(&dio_info->port[2].dit, 2); + + if (update & MCDRV_HIFI_DIT_UPDATE_FLAG) + dio_dit_set(&dio_info->port[3].dit, 3); +} + +void mc_dio_info_get(struct mcdrv_dio_info *dio_info) +{ + *dio_info = mc_info.dio_info; +} + +void mc_dio_path_info_set(struct mcdrv_dio_path_info *dio_path_info, u32 update) +{ + if (update & MCDRV_MUSICNUM_UPDATE_FLAG) + mc_info.dio_path_info.music_ch = dio_path_info->music_ch; + + if (update & MCDRV_PHYS0_UPDATE_FLAG) + mc_info.dio_path_info.phys_port[0] + = dio_path_info->phys_port[0]; + + if (update & MCDRV_PHYS1_UPDATE_FLAG) + mc_info.dio_path_info.phys_port[1] + = dio_path_info->phys_port[1]; + + if (update & MCDRV_PHYS2_UPDATE_FLAG) + mc_info.dio_path_info.phys_port[2] + = dio_path_info->phys_port[2]; + + if (update & MCDRV_PHYS3_UPDATE_FLAG) + mc_info.dio_path_info.phys_port[3] + = dio_path_info->phys_port[3]; + + if (update & MCDRV_DIR0SLOT_UPDATE_FLAG) + mc_info.dio_path_info.music_rslot[0] + = dio_path_info->music_rslot[0]; + + if (update & MCDRV_DIR1SLOT_UPDATE_FLAG) + mc_info.dio_path_info.music_rslot[1] + = dio_path_info->music_rslot[1]; + + if (update & MCDRV_DIR2SLOT_UPDATE_FLAG) + mc_info.dio_path_info.music_rslot[2] + = dio_path_info->music_rslot[2]; + + if (update & MCDRV_DIT0SLOT_UPDATE_FLAG) + mc_info.dio_path_info.music_tslot[0] + = dio_path_info->music_tslot[0]; + + if (update & MCDRV_DIT1SLOT_UPDATE_FLAG) + mc_info.dio_path_info.music_tslot[1] + = dio_path_info->music_tslot[1]; + + if (update & MCDRV_DIT2SLOT_UPDATE_FLAG) + mc_info.dio_path_info.music_tslot[2] + = dio_path_info->music_tslot[2]; +} + +void mc_dio_path_info_get(struct mcdrv_dio_path_info *dio_path_info) +{ + *dio_path_info = mc_info.dio_path_info; +} + +void mc_swap_info_set(struct mcdrv_swap_info *swap_info, u32 update) +{ + if (update & MCDRV_SWAP_ADIF0_UPDATE_FLAG) + mc_info.swap_info.adif0 = swap_info->adif0; + + if (update & MCDRV_SWAP_ADIF1_UPDATE_FLAG) + mc_info.swap_info.adif1 = swap_info->adif1; + + if (update & MCDRV_SWAP_ADIF2_UPDATE_FLAG) + mc_info.swap_info.adif2 = swap_info->adif2; + + if (update & MCDRV_SWAP_DAC0_UPDATE_FLAG) + mc_info.swap_info.dac0 = swap_info->dac0; + + if (update & MCDRV_SWAP_DAC1_UPDATE_FLAG) + mc_info.swap_info.dac1 = swap_info->dac1; + + if (update & MCDRV_SWAP_MUSICIN0_UPDATE_FLAG) + mc_info.swap_info.music_in0 = swap_info->music_in0; + + if (update & MCDRV_SWAP_MUSICIN1_UPDATE_FLAG) + mc_info.swap_info.music_in1 = swap_info->music_in1; + + if (update & MCDRV_SWAP_MUSICIN2_UPDATE_FLAG) + mc_info.swap_info.music_in2 = swap_info->music_in2; + + if (update & MCDRV_SWAP_EXTIN_UPDATE_FLAG) + mc_info.swap_info.ext_in = swap_info->ext_in; + + if (update & MCDRV_SWAP_VOICEIN_UPDATE_FLAG) + mc_info.swap_info.voice_in = swap_info->voice_in; + + if (update & MCDRV_SWAP_HIFIIN_UPDATE_FLAG) + mc_info.swap_info.hifi_in = swap_info->hifi_in; + + if (update & MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG) + mc_info.swap_info.music_out0 = swap_info->music_out0; + + if (update & MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG) + mc_info.swap_info.music_out1 = swap_info->music_out1; + + if (update & MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG) + mc_info.swap_info.music_out2 = swap_info->music_out2; + + if (update & MCDRV_SWAP_EXTOUT_UPDATE_FLAG) + mc_info.swap_info.ext_out = swap_info->ext_out; + + if (update & MCDRV_SWAP_VOICEOUT_UPDATE_FLAG) + mc_info.swap_info.voice_out = swap_info->voice_out; + + if (update & MCDRV_SWAP_HIFIOUT_UPDATE_FLAG) + mc_info.swap_info.hifi_out = swap_info->hifi_out; +} + +void mc_swap_info_get(struct mcdrv_swap_info *swap_info) +{ + *swap_info = mc_info.swap_info; +} + +void mc_hsdet_info_set(struct mcdrv_hsdet_info *hsdet_info, u32 update) +{ + struct mcdrv_hsdet_info *hsdet; + + hsdet = &mc_info.hsdet_info; + + if (update & MCDRV_ENPLUGDET_UPDATE_FLAG) + hsdet->en_plug_det = hsdet_info->en_plug_det; + + if (update & MCDRV_ENPLUGDETDB_UPDATE_FLAG) + hsdet->en_plug_det_db = hsdet_info->en_plug_det_db; + + if (update & MCDRV_ENDLYKEYOFF_UPDATE_FLAG) + hsdet->en_dly_key_off = hsdet_info->en_dly_key_off; + + if (update & MCDRV_ENDLYKEYON_UPDATE_FLAG) + hsdet->en_dly_key_on = hsdet_info->en_dly_key_on; + + if (update & MCDRV_ENMICDET_UPDATE_FLAG) + hsdet->en_mic_det = hsdet_info->en_mic_det; + + if (update & MCDRV_ENKEYOFF_UPDATE_FLAG) + hsdet->en_key_off = hsdet_info->en_key_off; + + if (update & MCDRV_ENKEYON_UPDATE_FLAG) + hsdet->en_key_on = hsdet_info->en_key_on; + + if (update & MCDRV_HSDETDBNC_UPDATE_FLAG) + hsdet->hs_det_dbnc = hsdet_info->hs_det_dbnc; + + if (update & MCDRV_KEYOFFMTIM_UPDATE_FLAG) + hsdet->key_off_mtim = hsdet_info->key_off_mtim; + + if (update & MCDRV_KEYONMTIM_UPDATE_FLAG) + hsdet->key_on_mtim = hsdet_info->key_on_mtim; + + if (update & MCDRV_KEY0OFFDLYTIM_UPDATE_FLAG) + hsdet->key0_off_dly_tim = hsdet_info->key0_off_dly_tim; + + if (update & MCDRV_KEY1OFFDLYTIM_UPDATE_FLAG) + hsdet->key1_off_dly_tim = hsdet_info->key1_off_dly_tim; + + if (update & MCDRV_KEY2OFFDLYTIM_UPDATE_FLAG) + hsdet->key2_off_dly_tim = hsdet_info->key2_off_dly_tim; + + if (update & MCDRV_KEY0ONDLYTIM_UPDATE_FLAG) + hsdet->key0_on_dly_tim = hsdet_info->key0_on_dly_tim; + + if (update & MCDRV_KEY1ONDLYTIM_UPDATE_FLAG) + hsdet->key1_on_dly_tim = hsdet_info->key1_on_dly_tim; + + if (update & MCDRV_KEY2ONDLYTIM_UPDATE_FLAG) + hsdet->key2_on_dly_tim = hsdet_info->key2_on_dly_tim; + + if (update & MCDRV_KEY0ONDLYTIM2_UPDATE_FLAG) + hsdet->key0_on_dly_tim2 = hsdet_info->key0_on_dly_tim2; + + if (update & MCDRV_KEY1ONDLYTIM2_UPDATE_FLAG) + hsdet->key1_on_dly_tim2 = hsdet_info->key1_on_dly_tim2; + + if (update & MCDRV_KEY2ONDLYTIM2_UPDATE_FLAG) + hsdet->key2_on_dly_tim2 = hsdet_info->key2_on_dly_tim2; + + if (update & MCDRV_IRQTYPE_UPDATE_FLAG) { + hsdet->irq_type = hsdet_info->irq_type; + hsdet->plug_det_db_irq_type = hsdet_info->plug_det_db_irq_type; + hsdet->plug_undet_db_irq_type + = hsdet_info->plug_undet_db_irq_type; + hsdet->mic_det_irq_type = hsdet_info->mic_det_irq_type; + hsdet->plug_det_irq_type = hsdet_info->plug_det_irq_type; + hsdet->key0_on_irq_type = hsdet_info->key0_on_irq_type; + hsdet->key1_on_irq_type = hsdet_info->key1_on_irq_type; + hsdet->key2_on_irq_type = hsdet_info->key2_on_irq_type; + hsdet->key0_off_irq_type = hsdet_info->key0_off_irq_type; + hsdet->key1_off_irq_type = hsdet_info->key1_off_irq_type; + hsdet->key2_off_irq_type = hsdet_info->key2_off_irq_type; + } + + if (update & MCDRV_DETINV_UPDATE_FLAG) + hsdet->det_in_inv = hsdet_info->det_in_inv; + + if (update & MCDRV_HSDETMODE_UPDATE_FLAG) + hsdet->hs_det_mode = hsdet_info->hs_det_mode; + + if (update & MCDRV_SPERIOD_UPDATE_FLAG) + hsdet->speriod = hsdet_info->speriod; + + if (update & MCDRV_LPERIOD_UPDATE_FLAG) + hsdet->lperiod = hsdet_info->lperiod; + + if (update & MCDRV_DBNCNUMPLUG_UPDATE_FLAG) + hsdet->dbnc_num_plug = hsdet_info->dbnc_num_plug; + + if (update & MCDRV_DBNCNUMMIC_UPDATE_FLAG) + hsdet->dbnc_num_mic = hsdet_info->dbnc_num_mic; + + if (update & MCDRV_DBNCNUMKEY_UPDATE_FLAG) + hsdet->dbnc_num_key = hsdet_info->dbnc_num_key; + + if (update & MCDRV_SGNL_UPDATE_FLAG) { + hsdet->sgnl_period = hsdet_info->sgnl_period; + hsdet->sgnl_num = hsdet_info->sgnl_num; + hsdet->sgnl_peak = hsdet_info->sgnl_peak; + } + + if (update & MCDRV_IMPSEL_UPDATE_FLAG) + hsdet->imp_sel = hsdet_info->imp_sel; + + if (update & MCDRV_DLYIRQSTOP_UPDATE_FLAG) + hsdet->dly_irq_stop = hsdet_info->dly_irq_stop; + + if (update & MCDRV_CBFUNC_UPDATE_FLAG) + hsdet->cbfunc = hsdet_info->cbfunc; +} + +void mc_hsdet_info_get(struct mcdrv_hsdet_info *hsdet_info) +{ + *hsdet_info = mc_info.hsdet_info; +} + +void mc_aec_info_set(struct mcdrv_aec_info *aec_info) +{ + struct mcdrv_aec_info *aec; + struct mcdrv_aec_output *out; + struct mcdrv_aec_input *in; + int i; + + aec = &mc_info.aec_info; + + if (aec_info->fdsp_locate != 0xff) + aec->fdsp_locate = aec_info->fdsp_locate; + + aec->audio_engine.enable = aec_info->audio_engine.enable; + if (aec_info->audio_engine.enable) { + struct mcdrv_aec_audio_engine *ae = &aec->audio_engine; + + if (aec_info->audio_engine.on != 2) + ae->on = aec_info->audio_engine.on; + if (aec_info->audio_engine.fdsp_on != 2) + ae->fdsp_on = aec_info->audio_engine.fdsp_on; + if (aec_info->audio_engine.bdsp_ae0_src != 2) + ae->bdsp_ae0_src = aec_info->audio_engine.bdsp_ae0_src; + if (aec_info->audio_engine.bdsp_ae1_src != 2) + ae->bdsp_ae1_src = aec_info->audio_engine.bdsp_ae1_src; + if (aec_info->audio_engine.mixer_in0_src != 2) + ae->mixer_in0_src = + aec_info->audio_engine.mixer_in0_src; + if (aec_info->audio_engine.mixer_in1_src != 2) + ae->mixer_in1_src = + aec_info->audio_engine.mixer_in1_src; + if (aec_info->audio_engine.mixer_in2_src != 2) + ae->mixer_in2_src = + aec_info->audio_engine.mixer_in2_src; + if (aec_info->audio_engine.mixer_in3_src != 2) + ae->mixer_in3_src = + aec_info->audio_engine.mixer_in3_src; + } + + aec->audio_engine.bdsp = aec_info->audio_engine.bdsp; + aec->audio_engine.fdsp = aec_info->audio_engine.fdsp; + + aec->vbox.enable = aec_info->vbox.enable; + if (aec_info->vbox.enable) { + struct mcdrv_aec_vbox *vb = &mc_info.aec_info.vbox; + + if (aec_info->vbox.cdsp_func_a_on != 2) + vb->cdsp_func_a_on = aec_info->vbox.cdsp_func_a_on; + + if (aec_info->vbox.cdsp_func_b_on != 2) + vb->cdsp_func_b_on = aec_info->vbox.cdsp_func_b_on; + + if (aec_info->vbox.fdsp_on != 2) + vb->fdsp_on = aec_info->vbox.fdsp_on; + + if (aec_info->vbox.fdsp_po_source != 0xff) + vb->fdsp_po_source = aec_info->vbox.fdsp_po_source; + + if (aec_info->vbox.isrc2_vsource != 0xff) + vb->isrc2_vsource = aec_info->vbox.isrc2_vsource; + + if (aec_info->vbox.isrc2_ch1_vsource != 0xff) + vb->isrc2_ch1_vsource = + aec_info->vbox.isrc2_ch1_vsource; + if (aec_info->vbox.isrc3_vsource != 0xff) + vb->isrc3_vsource = aec_info->vbox.isrc3_vsource; + + if (aec_info->vbox.lpt2_vsource != 0xff) + vb->lpt2_vsource = aec_info->vbox.lpt2_vsource; + + if (aec_info->vbox.lpt2_mix_vol_o != 0xff) + vb->lpt2_mix_vol_o = aec_info->vbox.lpt2_mix_vol_o; + + if (aec_info->vbox.lpt2_mix_vol_i != 0xff) + vb->lpt2_mix_vol_i = aec_info->vbox.lpt2_mix_vol_i; + + if (aec_info->vbox.src3_ctrl != 0xff) + vb->src3_ctrl = aec_info->vbox.src3_ctrl; + + if (aec_info->vbox.src2_fs != 0xff) + vb->src2_fs = aec_info->vbox.src2_fs; + + if (aec_info->vbox.src2_thru != 0xff) + vb->src2_thru = aec_info->vbox.src2_thru; + + if (aec_info->vbox.src3_fs != 0xff) + vb->src3_fs = aec_info->vbox.src3_fs; + + if (aec_info->vbox.src3_thru != 0xff) + vb->src3_thru = aec_info->vbox.src3_thru; + + if (aec_info->vbox.cdsp_jtag_on != 0xff) + vb->cdsp_jtag_on = aec_info->vbox.cdsp_jtag_on; + } + + aec->vbox.cdsp_a = aec_info->vbox.cdsp_a; + aec->vbox.cdsp_b = aec_info->vbox.cdsp_b; + aec->vbox.fdsp = aec_info->vbox.fdsp; + + out = &aec->output; + + for (i = 0; i < MCDRV_AEC_OUTPUT_N; i++) { + + if (aec_info->output.lpf_pre_thru[i] != 0xff) { + out->lpf_pre_thru[i] = aec_info->output.lpf_pre_thru[i]; + out->lpf_post_thru[i] + = aec_info->output.lpf_post_thru[i]; + out->dcc_sel[i] = aec_info->output.dcc_sel[i]; + out->power_detect_level[i] + = aec_info->output.power_detect_level[i]; + out->osf_sel[i] = aec_info->output.osf_sel[i]; + out->syseq_enb[i] = aec_info->output.syseq_enb[i]; + out->syseq_coef_a0[i][0] + = aec_info->output.syseq_coef_a0[i][0]; + out->syseq_coef_a0[i][1] + = aec_info->output.syseq_coef_a0[i][1]; + out->syseq_coef_a0[i][2] + = aec_info->output.syseq_coef_a0[i][2]; + out->syseq_coef_a1[i][0] + = aec_info->output.syseq_coef_a1[i][0]; + out->syseq_coef_a1[i][1] + = aec_info->output.syseq_coef_a1[i][1]; + out->syseq_coef_a1[i][2] + = aec_info->output.syseq_coef_a1[i][2]; + out->syseq_coef_a2[i][0] + = aec_info->output.syseq_coef_a2[i][0]; + out->syseq_coef_a2[i][1] + = aec_info->output.syseq_coef_a2[i][1]; + out->syseq_coef_a2[i][2] + = aec_info->output.syseq_coef_a2[i][2]; + out->syseq_coef_b1[i][0] + = aec_info->output.syseq_coef_b1[i][0]; + out->syseq_coef_b1[i][1] + = aec_info->output.syseq_coef_b1[i][1]; + out->syseq_coef_b1[i][2] + = aec_info->output.syseq_coef_b1[i][2]; + out->syseq_coef_b2[i][0] + = aec_info->output.syseq_coef_b2[i][0]; + out->syseq_coef_b2[i][1] + = aec_info->output.syseq_coef_b2[i][1]; + out->syseq_coef_b2[i][2] + = aec_info->output.syseq_coef_b2[i][2]; + out->clip_md[i] = aec_info->output.clip_md[i]; + out->clip_att[i] = aec_info->output.clip_att[i]; + out->clip_rel[i] = aec_info->output.clip_rel[i]; + out->clip_g[i] = aec_info->output.clip_g[i]; + out->osf_gain[i][0] = aec_info->output.osf_gain[i][0]; + out->osf_gain[i][1] = aec_info->output.osf_gain[i][1]; + out->dcl_on[i] = aec_info->output.dcl_on[i]; + out->dcl_gain[i] = aec_info->output.dcl_gain[i]; + out->dcl_limit[i][0] = aec_info->output.dcl_limit[i][0]; + out->dcl_limit[i][1] = aec_info->output.dcl_limit[i][1]; + out->random_dither_on[i] + = aec_info->output.random_dither_on[i]; + out->random_dither_level[i] + = aec_info->output.random_dither_level[i]; + out->random_dither_pos[i] + = aec_info->output.random_dither_pos[i]; + out->dc_dither_on[i] = aec_info->output.dc_dither_on[i]; + out->dc_dither_level[i] + = aec_info->output.dc_dither_level[i]; + out->dither_type[i] = aec_info->output.dither_type[i]; + out->dng_on[i] = aec_info->output.dng_on[i]; + out->dng_zero[i] = aec_info->output.dng_zero[i]; + out->dng_time[i] = aec_info->output.dng_time[i]; + out->dng_fw[i] = aec_info->output.dng_fw[i]; + out->dng_target[i] = aec_info->output.dng_target[i]; + out->dng_target_lineout[i] + = aec_info->output.dng_target_lineout[i]; + } + if (aec_info->output.syseq_ex[i].enable) + memcpy(&out->syseq_ex[i], &aec_info->output.syseq_ex[i], + sizeof(struct mcdrv_aec_syseq_ex)); + } + + out->signal_detect_level = aec_info->output.signal_detect_level; + out->dng_attack = aec_info->output.dng_attack; + out->dng_release = aec_info->output.dng_release; + out->dng_target_rc = aec_info->output.dng_target_rc; + + in = &aec->input; + + for (i = 0; i < MCDRV_AEC_INPUT_N; i++) { + if (aec_info->input.dsf32_l_type[i] != 0xff) { + in->dsf32_l_type[i] = aec_info->input.dsf32_l_type[i]; + in->dsf32_r_type[i] = aec_info->input.dsf32_r_type[i]; + in->dsf4_sel[i] = aec_info->input.dsf4_sel[i]; + in->dcc_sel[i] = aec_info->input.dcc_sel[i]; + in->dng_on[i] = aec_info->input.dng_on[i]; + in->dng_att[i] = aec_info->input.dng_att[i]; + in->dng_rel[i] = aec_info->input.dng_rel[i]; + in->dng_fw[i] = aec_info->input.dng_fw[i]; + in->dng_time[i] = aec_info->input.dng_time[i]; + in->dng_zero[i][0] = aec_info->input.dng_zero[i][0]; + in->dng_zero[i][1] = aec_info->input.dng_zero[i][1]; + in->dng_target[i][0] = aec_info->input.dng_target[i][0]; + in->dng_target[i][1] = aec_info->input.dng_target[i][1]; + in->depop_att[i] = aec_info->input.depop_att[i]; + in->depop_wait[i] = aec_info->input.depop_wait[i]; + } + } + + in->ref_sel = aec_info->input.ref_sel; + + if (aec_info->pdm.mode != 0xff) + aec->pdm = aec_info->pdm; + + aec->e2.enable = aec_info->e2.enable; + if (aec_info->e2.enable) { + if (aec_info->e2.da_sel != 4) + aec->e2.da_sel = aec_info->e2.da_sel; + if (aec_info->e2.ad_sel != 8) + aec->e2.ad_sel = aec_info->e2.ad_sel; + aec->e2.on = aec_info->e2.on; + } + aec->e2.config = aec_info->e2.config; + + if (aec_info->adj.hold != 0xff) + aec->adj = aec_info->adj; + + if (aec_info->edsp_misc.i2s_out_enable != 0xff) + aec->edsp_misc = aec_info->edsp_misc; + + if (aec_info->control.command == 0xff) + memset(&aec->control, 0, sizeof(struct mcdrv_aec_control)); + else + aec->control = aec_info->control; + + if (!aec->fdsp_locate) + aec->vbox.fdsp_on = 0; + else + aec->audio_engine.fdsp_on = 0; +} + +void mc_aec_info_replace(struct mcdrv_aec_info *aec_info) +{ + mc_info.aec_info = *aec_info; +} + +void mc_aec_info_get(struct mcdrv_aec_info *aec_info) +{ + *aec_info = mc_info.aec_info; +} + +void mc_gp_mode_set(struct mcdrv_gp_mode *mode) +{ + mc_info.gp_mode = *mode; +} + +void mc_gp_mode_get(struct mcdrv_gp_mode *mode) +{ + *mode = mc_info.gp_mode; +} + +bool mc_gp_pad_get(u32 pad_no) +{ + if (pad_no > 2) + return 0; + + return mc_info.gp_mode.gp_ddr[pad_no]; +} + +void mc_clock_select_set(u8 clk_sel) +{ + mc_info.clk_sel = clk_sel; +} + +u8 mc_clock_select_get(void) +{ + return mc_info.clk_sel; +} + +void mc_e_clock_select_set(u8 eclk_sel) +{ + mc_info.eclk_sel = eclk_sel; +} + +u8 mc_e_clock_select_get(void) +{ + return mc_info.eclk_sel; +} + +void mc_plug_detect_db_set(u8 plug_det_db) +{ + mc_info.plug_det_db = plug_det_db; +} + +u8 mc_plug_detect_db_get(void) +{ + return mc_info.plug_det_db; +} + +static s16 digital_volume(int vol) +{ + int ret; + + if (vol < (-95 * 256)) + ret = 0; + else if (vol < 0) + ret = 96 + (vol - 128) / 256; + else + ret = 96 + (vol + 128) / 256; + + if (ret > 114) + ret = 114; + + return (s16) ret; +} + +static s16 analog_in_volume(s16 vol) +{ + s16 ret; + + if (vol < (-30 * 256)) + ret = 0; + else if (vol < 0) + ret = 0x21 + (vol - 128) / 256; + else if (vol <= (21 * 256)) + ret = 0x21 + (vol + 128) / 256; + else if (vol < 6080) /* 6080 = 23.75 * 256 */ + ret = 0x36 + ((vol + 64) / 128 - (21 * 2)); + else + ret = 0x3c + (vol / 256 - 23) / 2; + + if (ret < 0) + ret = 0; + else if (ret > 0x3f) + ret = 0x3f; + + return ret; +} + +static s16 analog_out_volume(s16 vol) +{ + s16 ret; + + if (vol < (-36 * 256)) + ret = 0; + else if (vol < -4032) /* -4032:-15.75*256 */ + ret = 0x42 + (vol - 128) / 256 + 17; + else if (vol < -1504) /* -1504:-5.875*256 */ + ret = 0x57 + ((vol - 64) / 128 + 6 * 2); + else + ret = 0x6f + ((vol - 32) / 64); + + if (ret < 0) + ret = 0; + else if (ret > 0x6f) + ret = 0x6f; + + return ret; +} + +static inline s16 sp_volume(s16 vol) +{ + s16 ret; + + if (vol < (-36 * 256)) + ret = 0; + else if (vol < -4032) /* -4032:-15.75*256 */ + ret = 0x42 + (vol - 128) / 256 + 17; + else if (vol < -1504) /* -1504:-5.875*256 */ + ret = 0x57 + ((vol - 64) / 128 + 6 * 2); + else if (vol < 32) + ret = 0x6f + ((vol - 32) / 64); + else + ret = 0x70 + ((vol - 32) / 64); + + if (ret < 0) + ret = 0; + else if (ret > 0x7f) + ret = 0x7f; + + return ret; +} + +static s16 lineout_volume(s16 vol) +{ + s16 ret; + + if (vol < (-38 * 256)) + ret = 0; + else if (vol < -9344) /* -9344:-15.75 * 256 */ + ret = 0x2e; + else if (vol < -4032) /* -4032:-15.75 * 256 */ + ret = 0x42 + (vol - 128) / 256 + 17; + else if (vol < -1504) /* -1504:-5.875 * 256 */ + ret = 0x57 + ((vol - 64) / 128 + 6 * 2); + else if (vol < 32) + ret = 0x6f + ((vol - 32) / 64); + else + ret = 0x70 + ((vol - 32) / 64); + + if (ret < 0) + ret = 0; + else if (ret > 0x77) + ret = 0x77; + + return ret; +} + +static inline s16 hp_volume(s16 vol) +{ + s16 ret; + + if (vol < (-36 * 256)) + ret = 0; + else if (vol < -4032) /* -4032:-15.75 * 256 */ + ret = 0x43 + (vol - 128) / 256 + 16; + else if (vol < -1504) /* -1504:-5.875 * 256 */ + ret = 0x43 + ((vol - 64) / 128 + 16 * 2); + else if (vol < 0) + ret = 0x57 + ((vol - 32) / 64 + 6 * 4); + else + ret = 0x6f + ((vol + 32) / 64); + + if (ret < 0) + ret = 0; + else if (ret > 0x7f) + ret = 0x7f; + + return ret; +} + +static u32 d1_get_source(u32 *d1, enum mcdrv_dst_ch ch) +{ + u32 src = 0; + + if (d1) { + if (d1[ch] & MCDRV_D1SRC_MUSICIN_ON) + src |= MCDRV_D1SRC_MUSICIN_ON; + if (d1[ch] & MCDRV_D1SRC_EXTIN_ON) + src |= MCDRV_D1SRC_EXTIN_ON; + if (d1[ch] & MCDRV_D1SRC_VBOXOUT_ON) + src |= MCDRV_D1SRC_VBOXOUT_ON; + if (d1[ch] & MCDRV_D1SRC_VBOXREFOUT_ON) + src |= MCDRV_D1SRC_VBOXREFOUT_ON; + if (d1[ch] & MCDRV_D1SRC_AE0_ON) + src |= MCDRV_D1SRC_AE0_ON; + if (d1[ch] & MCDRV_D1SRC_AE1_ON) + src |= MCDRV_D1SRC_AE1_ON; + if (d1[ch] & MCDRV_D1SRC_AE2_ON) + src |= MCDRV_D1SRC_AE2_ON; + if (d1[ch] & MCDRV_D1SRC_AE3_ON) + src |= MCDRV_D1SRC_AE3_ON; + if (d1[ch] & MCDRV_D1SRC_ADIF0_ON) + src |= MCDRV_D1SRC_ADIF0_ON; + if (d1[ch] & MCDRV_D1SRC_ADIF1_ON) + src |= MCDRV_D1SRC_ADIF1_ON; + if (d1[ch] & MCDRV_D1SRC_ADIF2_ON) + src |= MCDRV_D1SRC_ADIF2_ON; + if (d1[ch] & MCDRV_D1SRC_HIFIIN_ON) + src |= MCDRV_D1SRC_HIFIIN_ON; + } + + return src; +} + +void mc_volume_info_get(struct mcdrv_vol_info *vol_info) +{ + enum mcdrv_dst_ch ch, dst_ch[] = { MCDRV_DST_CH0, MCDRV_DST_CH1 }; + s16 val1, val2; + int i, src; + + *vol_info = mc_info.vol_info; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_music_in[0]); + val2 = digital_volume(vol_info->d_music_in[1]); + } + vol_info->d_music_in[0] = val1; + vol_info->d_music_in[1] = val2; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_ext_in[0]); + val2 = digital_volume(vol_info->d_ext_in[1]); + } + vol_info->d_ext_in[0] = val1; + vol_info->d_ext_in[1] = val2; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_voice_in[0]); + val2 = digital_volume(vol_info->d_voice_in[1]); + } + vol_info->d_voice_in[0] = val1; + vol_info->d_voice_in[1] = val2; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_ref_in[0]); + val2 = digital_volume(vol_info->d_ref_in[1]); + } + vol_info->d_ref_in[0] = val1; + vol_info->d_ref_in[1] = val2; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF0_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_adif0_in[0]); + val2 = digital_volume(vol_info->d_adif0_in[1]); + } + vol_info->d_adif0_in[0] = val1; + vol_info->d_adif0_in[1] = val2; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF1_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_adif1_in[0]); + val2 = digital_volume(vol_info->d_adif1_in[1]); + } + vol_info->d_adif1_in[0] = val1; + vol_info->d_adif1_in[1] = val2; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF2_ON)) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + val1 = digital_volume(vol_info->d_adif2_in[0]); + val2 = digital_volume(vol_info->d_adif2_in[1]); + } + vol_info->d_adif2_in[0] = val1; + vol_info->d_adif2_in[1] = val2; + + for (i = 0; i < ARRAY_SIZE(dst_ch); i++) { + ch = dst_ch[i]; + if (!mc_source_is_used(MCDRV_DST_MUSICOUT, ch)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_music_out[i]); + + if (!mc_source_is_used(MCDRV_DST_EXTOUT, ch)) + val2 = MCDRV_REG_MUTE; + else + val2 = digital_volume(vol_info->d_ext_out[i]); + vol_info->d_music_out[i] = val1; + vol_info->d_ext_out[i] = val2; + } + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_voice_out[0]); + vol_info->d_voice_out[0] = val1; + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_voice_out[1]); + vol_info->d_voice_out[1] = val1; + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_ref_out[0]); + vol_info->d_ref_out[0] = val1; + + if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_ref_out[1]); + vol_info->d_ref_out[1] = val1; + + if (!mc_d1_source_is_used(MCDRV_D1SRC_HIFIIN_ON)) { + vol_info->d_dpath_da[0] = MCDRV_REG_MUTE; + vol_info->d_dpath_da[1] = MCDRV_REG_MUTE; + } + + src = d1_get_source(mc_info.path_info.dac0, MCDRV_DST_CH0); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_dac0_out[0]); + vol_info->d_dac0_out[0] = val1; + + if (src & MCDRV_D1SRC_HIFIIN_ON) + vol_info->d_dpath_da[0] + = digital_volume(vol_info->d_dpath_da[0]); + + src = d1_get_source(mc_info.path_info.dac0, MCDRV_DST_CH1); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_dac0_out[1]); + vol_info->d_dac0_out[1] = val1; + + if (src & MCDRV_D1SRC_HIFIIN_ON) + vol_info->d_dpath_da[1] + = digital_volume(vol_info->d_dpath_da[1]); + + src = d1_get_source(mc_info.path_info.dac1, MCDRV_DST_CH0); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_dac1_out[0]); + vol_info->d_dac1_out[0] = val1; + + if (src & MCDRV_D1SRC_HIFIIN_ON) + vol_info->d_dpath_da[0] + = digital_volume(vol_info->d_dpath_da[0]); + + src = d1_get_source(mc_info.path_info.dac1, MCDRV_DST_CH1); + if (!(src & ~MCDRV_D1SRC_HIFIIN_ON)) + val1 = MCDRV_REG_MUTE; + else + val1 = digital_volume(vol_info->d_dac1_out[1]); + vol_info->d_dac1_out[1] = val1; + + if (src & MCDRV_D1SRC_HIFIIN_ON) + vol_info->d_dpath_da[1] + = digital_volume(vol_info->d_dpath_da[1]); + + src = d1_get_source(mc_info.path_info.hifi_out, MCDRV_DST_CH0); + if (!src) { + val1 = MCDRV_REG_MUTE; + val2 = MCDRV_REG_MUTE; + } else { + if ((src & MCDRV_D2SRC_PDM0_ON) + || (src & MCDRV_D2SRC_PDM1_ON)) { + val1 = digital_volume(vol_info->d_dpath_ad[0]); + val2 = digital_volume(vol_info->d_dpath_ad[1]); + } else { + if ((src & MCDRV_D2SRC_ADC1_ON) + || mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH0)) + val1 = digital_volume(vol_info->d_dpath_ad[0]); + else + val1 = MCDRV_REG_MUTE; + + if ((src & MCDRV_D2SRC_ADC0_ON) + && mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH1)) + val2 = digital_volume(vol_info->d_dpath_ad[1]); + else + val2 = MCDRV_REG_MUTE; + } + } + vol_info->d_dpath_ad[0] = val1; + vol_info->d_dpath_ad[1] = val2; + + if (mc_a_source_is_used(MCDRV_ASRC_LINEIN1_L_ON) + || mc_a_source_is_used(MCDRV_ASRC_LINEIN1_M_ON)) + val1 = analog_in_volume(mc_info.vol_info.a_line_in1[0]); + else + val1 = MCDRV_REG_MUTE; + vol_info->a_line_in1[0] = val1; + + if (mc_a_source_is_used(MCDRV_ASRC_LINEIN1_R_ON) + || mc_a_source_is_used(MCDRV_ASRC_LINEIN1_M_ON)) + val1 = analog_in_volume(mc_info.vol_info.a_line_in1[1]); + else + val1 = MCDRV_REG_MUTE; + vol_info->a_line_in1[1] = val1; + + if (mc_a_source_is_used(MCDRV_ASRC_MIC1_ON) != 0) + val1 = analog_in_volume(mc_info.vol_info.a_mic1[0]); + else + val1 = MCDRV_REG_MUTE; + vol_info->a_mic1[0] = val1; + + if (mc_a_source_is_used(MCDRV_ASRC_MIC2_ON) != 0) + val1 = analog_in_volume(mc_info.vol_info.a_mic2[0]); + else + val1 = MCDRV_REG_MUTE; + vol_info->a_mic2[0] = val1; + + if (mc_a_source_is_used(MCDRV_ASRC_MIC3_ON) != 0) + val1 = analog_in_volume(mc_info.vol_info.a_mic3[0]); + else + val1 = MCDRV_REG_MUTE; + vol_info->a_mic3[0] = val1; + + if (mc_a_source_is_used(MCDRV_ASRC_MIC4_ON) != 0) + val1 = analog_in_volume(mc_info.vol_info.a_mic4[0]); + else + val1 = MCDRV_REG_MUTE; + vol_info->a_mic4[0] = val1; + + for (i = 0; i < ARRAY_SIZE(dst_ch); i++) { + ch = dst_ch[i]; + if (!mc_source_is_used(MCDRV_DST_HP, ch)) + val1 = MCDRV_REG_MUTE; + else + val1 = hp_volume(mc_info.vol_info.a_hp[i]); + vol_info->a_hp[i] = val1; + + if (!mc_source_is_used(MCDRV_DST_SP, ch)) + val1 = MCDRV_REG_MUTE; + else + val1 = sp_volume(mc_info.vol_info.a_sp[i]); + vol_info->a_sp[i] = val1; + + if (!mc_source_is_used(MCDRV_DST_LOUT1, dst_ch[i])) + val1 = MCDRV_REG_MUTE; + else + val1 = lineout_volume(mc_info.vol_info.a_line_out1[i]); + vol_info->a_line_out1[i] = val1; + + if (!mc_source_is_used(MCDRV_DST_LOUT2, dst_ch[i])) + val1 = MCDRV_REG_MUTE; + else + val1 = lineout_volume(mc_info.vol_info.a_line_out2[i]); + vol_info->a_line_out2[i] = val1; + } + + if (!mc_source_is_used(MCDRV_DST_RCV, MCDRV_DST_CH0)) + val1 = MCDRV_REG_MUTE; + else + val1 = analog_out_volume(mc_info.vol_info.a_rc[0]); + vol_info->a_rc[0] = val1; + + val1 = analog_out_volume(mc_info.vol_info.a_hp_det[0]); + vol_info->a_hp_det[0] = val1; +} + +void mc_power_info_get(struct mcdrv_power_info *info) +{ + struct mcdrv_aec_info *aec; + u32 hifi_out; + + info->digital = MCDRV_POWINFO_D_PLL_PD | MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PB_CLK_PD | MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PF_CLK_PD | MCDRV_POWINFO_D_PC_CLK_PD; + + aec = &mc_info.aec_info; + hifi_out = mc_info.path_info.hifi_out[0]; + + if (aec->e2.on || (hifi_out & MCDRV_D1SRC_ADIF0_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_ADC0_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_ADC1_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_PDM0_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_PDM1_ON) + || mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) + info->digital &= ~(MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + + if (aec->audio_engine.on == 1 + || mc_d1_source_is_used(MCDRV_D1SRC_AE_ALL_ON)) + info->digital &= ~(MCDRV_POWINFO_D_PB_CLK_PD | + MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + + if (mc_info.dev_info.power_mode == MCDRV_POWMODE_CDSPDEBUG + || aec->vbox.cdsp_jtag_on + || aec->vbox.cdsp_func_a_on || aec->vbox.cdsp_func_b_on) + info->digital &= ~(MCDRV_POWINFO_D_PC_CLK_PD | + MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + + if (!aec->fdsp_locate && aec->audio_engine.fdsp_on) + info->digital &= ~(MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PF_CLK_PD | + MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + + if (aec->fdsp_locate && aec->vbox.fdsp_on) + info->digital &= ~(MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PF_CLK_PD | + MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + + if (info->digital & MCDRV_POWINFO_D_PM_CLK_PD) { + if (mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON) + || mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON) + || mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON) + || mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_VOICEIN_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_VBOXIOOUT_ON) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) + info->digital &= ~(MCDRV_POWINFO_D_PE_CLK_PD | + MCDRV_POWINFO_D_PM_CLK_PD | + MCDRV_POWINFO_D_PLL_PD); + } + + info->analog[0] = MCI_AP_DEF; + info->analog[1] = MCI_AP_DA0_DEF; + info->analog[2] = MCI_AP_DA1_DEF; + info->analog[3] = MCI_AP_MIC_DEF; + info->analog[4] = MCI_AP_AD_DEF; + + if (mc_a_source_is_used(MCDRV_ASRC_DAC0_L_ON)) + info->analog[1] &= ~MCB_AP_DA0L; + if (mc_a_source_is_used(MCDRV_ASRC_DAC0_R_ON)) + info->analog[1] &= ~MCB_AP_DA0R; + if (mc_source_is_used(MCDRV_DST_HP, MCDRV_DST_CH0)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[1] &= ~MCB_AP_HPL; + } + if (mc_source_is_used(MCDRV_DST_HP, MCDRV_DST_CH1)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[1] &= ~MCB_AP_HPR; + } + if (mc_source_is_used(MCDRV_DST_RCV, MCDRV_DST_CH0)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[1] &= ~MCB_AP_RC; + } + if (mc_source_is_used(MCDRV_DST_LOUT1, MCDRV_DST_CH0)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[1] &= ~MCB_AP_LO1L; + } + if (mc_source_is_used(MCDRV_DST_LOUT1, MCDRV_DST_CH1)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[1] &= ~MCB_AP_LO1R; + } + if (mc_a_source_is_used(MCDRV_ASRC_DAC1_L_ON)) + info->analog[2] &= ~MCB_AP_DA1L; + if (mc_a_source_is_used(MCDRV_ASRC_DAC1_R_ON)) + info->analog[2] &= ~MCB_AP_DA1R; + if (mc_source_is_used(MCDRV_DST_SP, MCDRV_DST_CH0)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[2] &= ~(MCB_AP_SPL2 | MCB_AP_SPL1); + } + if (mc_source_is_used(MCDRV_DST_SP, MCDRV_DST_CH1)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[2] &= ~(MCB_AP_SPR2 | MCB_AP_SPR1); + } + if (mc_source_is_used(MCDRV_DST_LOUT2, MCDRV_DST_CH0)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[2] &= ~MCB_AP_LO2L; + } + if (mc_source_is_used(MCDRV_DST_LOUT2, MCDRV_DST_CH1)) { + info->analog[0] &= ~MCB_AP_CP; + info->analog[2] &= ~MCB_AP_LO2R; + } + if (mc_a_source_is_used(MCDRV_ASRC_MIC1_ON)) + info->analog[3] &= ~MCB_MC1; + if (mc_a_source_is_used(MCDRV_ASRC_MIC2_ON)) + info->analog[3] &= ~MCB_MC2; + if (mc_a_source_is_used(MCDRV_ASRC_MIC3_ON)) + info->analog[3] &= ~MCB_MC3; + if (mc_a_source_is_used(MCDRV_ASRC_MIC4_ON)) + info->analog[3] &= ~MCB_MC4; + if ((mc_info.path_info.bias[0] & MCDRV_ASRC_MIC1_ON)) + info->analog[3] &= ~MCB_MB1; + if ((mc_info.path_info.bias[1] & MCDRV_ASRC_MIC2_ON)) + info->analog[3] &= ~MCB_MB2; + if ((mc_info.path_info.bias[2] & MCDRV_ASRC_MIC3_ON)) + info->analog[3] &= ~MCB_MB3; + if ((mc_info.path_info.bias[3] & MCDRV_ASRC_MIC4_ON)) + info->analog[3] &= ~MCB_MB4; + if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH0)) + info->analog[4] &= ~MCB_AP_ADL; + if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH1)) + info->analog[4] &= ~MCB_AP_ADR; + if (mc_source_is_used(MCDRV_DST_ADC1, MCDRV_DST_CH0)) + info->analog[4] &= ~MCB_AP_ADM; + if (mc_a_source_is_used(MCDRV_ASRC_LINEIN1_L_ON) + || mc_a_source_is_used(MCDRV_ASRC_LINEIN1_M_ON) + || mc_a_source_is_used(MCDRV_ASRC_LINEIN1_R_ON)) + info->analog[4] &= ~MCB_AP_LI; + if (info->analog[1] != MCI_AP_DA0_DEF + || info->analog[2] != MCI_AP_DA1_DEF + || info->analog[3] != MCI_AP_MIC_DEF + || info->analog[4] != MCI_AP_AD_DEF) + info->analog[0] &= ~(MCB_AP_LDOA | MCB_AP_BGR | MCB_AP_VR); +} + +void mc_power_info_get_current(struct mcdrv_power_info *info) +{ + u8 val; + + info->digital = 0; + + val = mc_info.a_registers[MCI_PD]; + if (val & MCB_PLL_PD) + info->digital |= MCDRV_POWINFO_D_PLL_PD; + if (val & MCB_PE_CLK_PD) + info->digital |= MCDRV_POWINFO_D_PE_CLK_PD; + if (val & MCB_PB_CLK_PD) + info->digital |= MCDRV_POWINFO_D_PB_CLK_PD; + if (val & MCB_PM_CLK_PD) + info->digital |= MCDRV_POWINFO_D_PM_CLK_PD; + if (val & MCB_PF_CLK_PD) + info->digital |= MCDRV_POWINFO_D_PF_CLK_PD; + if (val & MCB_PC_CLK_PD) + info->digital |= MCDRV_POWINFO_D_PC_CLK_PD; + + info->analog[0] = mc_info.ana_registers[MCI_AP]; + info->analog[1] = mc_info.ana_registers[MCI_AP_DA0]; + info->analog[2] = mc_info.ana_registers[MCI_AP_DA1]; + info->analog[3] = mc_info.ana_registers[MCI_AP_MIC]; + info->analog[4] = mc_info.ana_registers[MCI_AP_AD]; +} + +static u32 d2_get_source(u32 *d2, enum mcdrv_dst_ch ch) +{ + u32 src = 0; + + if (d2) { + if (d2[ch] & MCDRV_D2SRC_VOICEIN_ON) + src |= MCDRV_D2SRC_VOICEIN_ON; + if (d2[ch] & MCDRV_D2SRC_VBOXIOOUT_ON) + src |= MCDRV_D2SRC_VBOXIOOUT_ON; + if (d2[ch] & MCDRV_D2SRC_VBOXHOSTOUT_ON) + src |= MCDRV_D2SRC_VBOXHOSTOUT_ON; + if (d2[ch] & MCDRV_D2SRC_ADC0_L_ON) + src |= MCDRV_D2SRC_ADC0_L_ON; + if (d2[ch] & MCDRV_D2SRC_ADC0_R_ON) + src |= MCDRV_D2SRC_ADC0_R_ON; + if (d2[ch] & MCDRV_D2SRC_ADC1_ON) + src |= MCDRV_D2SRC_ADC1_ON; + if (d2[ch] & MCDRV_D2SRC_PDM0_L_ON) + src |= MCDRV_D2SRC_PDM0_L_ON; + if (d2[ch] & MCDRV_D2SRC_PDM0_R_ON) + src |= MCDRV_D2SRC_PDM0_R_ON; + if (d2[ch] & MCDRV_D2SRC_PDM1_L_ON) + src |= MCDRV_D2SRC_PDM1_L_ON; + if (d2[ch] & MCDRV_D2SRC_PDM1_R_ON) + src |= MCDRV_D2SRC_PDM1_R_ON; + if (d2[ch] & MCDRV_D2SRC_DAC0REF_ON) + src |= MCDRV_D2SRC_DAC0REF_ON; + if (d2[ch] & MCDRV_D2SRC_DAC1REF_ON) + src |= MCDRV_D2SRC_DAC1REF_ON; + } + + return src; +} + +bool mc_d1_source_is_used(u32 mask) +{ + struct mcdrv_path_info *path; + int i; + + path = &mc_info.path_info; + + for (i = 0; i < MUSICOUT_PATH_CHANNELS; i++) { + if (path->music_out[i] & mask) + return true; + } + + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) { + if (path->ext_out[i] & mask) + return true; + } + + for (i = 0; i < VBOXMIXIN_PATH_CHANNELS; i++) { + if (path->vbox_mix_in[i] & mask) + return true; + } + + for (i = 0; i < AE_PATH_CHANNELS; i++) { + if (path->ae0[i] & mask) + return true; + if (path->ae1[i] & mask) + return true; + if (path->ae2[i] & mask) + return true; + if (path->ae3[i] & mask) + return true; + } + + for (i = 0; i < DAC0_PATH_CHANNELS; i++) { + if (path->dac0[i] & mask) + return true; + } + + for (i = 0; i < DAC1_PATH_CHANNELS; i++) { + if (path->dac1[i] & mask) + return true; + } + + return false; +} + +bool mc_d2_source_is_used(u32 mask) +{ + struct mcdrv_path_info *path; + int i; + + path = &mc_info.path_info; + + for (i = 0; i < VOICEOUT_PATH_CHANNELS; i++) { + if (path->voice_out[i] & mask) + return true; + } + + for (i = 0; i < VBOXIOIN_PATH_CHANNELS; i++) { + if (path->vbox_io_in[i] & mask) + return true; + } + + for (i = 0; i < VBOXHOSTIN_PATH_CHANNELS; i++) { + if (path->vbox_host_in[i] & mask) + return true; + } + + for (i = 0; i < HOSTOUT_PATH_CHANNELS; i++) { + if (path->host_out[i] & mask) + return true; + } + + for (i = 0; i < ADIF0_PATH_CHANNELS; i++) { + if (path->adif0[i] & mask) + return true; + } + + for (i = 0; i < ADIF1_PATH_CHANNELS; i++) { + if (path->adif1[i] & mask) + return true; + } + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) { + if (path->adif2[i] & mask) + return true; + } + + return false; +} + +bool mc_a_source_is_used(u32 mask) +{ + struct mcdrv_path_info *path; + int i; + + path = &mc_info.path_info; + + for (i = 0; i < ADC0_PATH_CHANNELS; i++) { + if (path->adc0[i] & mask) + return true; + } + + for (i = 0; i < ADC1_PATH_CHANNELS; i++) { + if (path->adc1[i] & mask) + return true; + } + + for (i = 0; i < SP_PATH_CHANNELS; i++) { + if (path->sp[i] & mask) + return true; + } + + for (i = 0; i < HP_PATH_CHANNELS; i++) { + if (path->hp[i] & mask) + return true; + } + + for (i = 0; i < RC_PATH_CHANNELS; i++) { + if (path->rc[i] & mask) + return true; + } + + for (i = 0; i < LOUT1_PATH_CHANNELS; i++) { + if (path->lout1[i] & mask) + return true; + } + + for (i = 0; i < LOUT2_PATH_CHANNELS; i++) { + if (path->lout2[i] & mask) + return true; + } + + return false; +} + +bool mc_source_is_used(enum mcdrv_dst_type type, enum mcdrv_dst_ch ch) +{ + struct mcdrv_path_info *path; + u32 src; + + path = &mc_info.path_info; + + switch (type) { + case MCDRV_DST_MUSICOUT: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->music_out, ch)) + return true; + break; + case MCDRV_DST_EXTOUT: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->ext_out, ch)) + return true; + break; + case MCDRV_DST_HIFIOUT: + if (ch > MCDRV_DST_CH0) + break; + if (d1_get_source(path->hifi_out, ch)) + return true; + break; + case MCDRV_DST_VBOXMIXIN: + if (d1_get_source(path->vbox_mix_in, ch)) + return true; + break; + case MCDRV_DST_AE0: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->ae0, ch)) + return true; + break; + case MCDRV_DST_AE1: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->ae1, ch)) + return true; + break; + case MCDRV_DST_AE2: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->ae2, ch)) + return true; + break; + case MCDRV_DST_AE3: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->ae3, ch)) + return true; + break; + case MCDRV_DST_DAC0: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->dac0, ch)) + return true; + break; + case MCDRV_DST_DAC1: + if (ch > MCDRV_DST_CH1) + break; + if (d1_get_source(path->dac1, ch)) + return true; + break; + case MCDRV_DST_VOICEOUT: + if (ch > MCDRV_DST_CH0) + break; + if (d2_get_source(path->voice_out, ch)) + return true; + break; + case MCDRV_DST_VBOXIOIN: + if (ch > MCDRV_DST_CH0) + break; + if (d2_get_source(path->vbox_io_in, ch)) + return true; + break; + case MCDRV_DST_VBOXHOSTIN: + if (ch > MCDRV_DST_CH0) + break; + if (d2_get_source(path->vbox_host_in, ch)) + return true; + break; + case MCDRV_DST_HOSTOUT: + if (ch > MCDRV_DST_CH0) + break; + if (d2_get_source(path->host_out, ch)) + return true; + break; + + case MCDRV_DST_ADIF0: + if (ch > MCDRV_DST_CH1) + break; + if (d2_get_source(path->adif0, ch)) + return true; + break; + case MCDRV_DST_ADIF1: + if (ch > MCDRV_DST_CH1) + break; + if (d2_get_source(path->adif1, ch)) + return true; + break; + case MCDRV_DST_ADIF2: + if (ch > MCDRV_DST_CH1) + break; + if (d2_get_source(path->adif2, ch)) + return true; + break; + case MCDRV_DST_ADC0: + if (ch > MCDRV_DST_CH1) + break; + src = path->adc0[ch]; + if (src & (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_ALL_ON)) + return true; + break; + case MCDRV_DST_ADC1: + if (ch > MCDRV_DST_CH0) + break; + src = path->adc1[ch]; + if (src & (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_ALL_ON)) + return true; + break; + case MCDRV_DST_SP: + if (ch > MCDRV_DST_CH1) + break; + src = path->sp[ch]; + if (src & (MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_R_ON)) + return true; + break; + case MCDRV_DST_HP: + if (ch > MCDRV_DST_CH1) + break; + src = path->hp[ch]; + if (src & (MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON)) + return true; + break; + case MCDRV_DST_RCV: + if (ch > MCDRV_DST_CH0) + break; + src = path->rc[ch]; + if (src & (MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON)) + return true; + break; + case MCDRV_DST_LOUT1: + if (ch > MCDRV_DST_CH1) + break; + src = path->lout1[ch]; + if (src & (MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON)) + return true; + break; + case MCDRV_DST_LOUT2: + if (ch > MCDRV_DST_CH1) + break; + src = path->lout2[ch]; + if (src & (MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_R_ON)) + return true; + break; + case MCDRV_DST_BIAS: + if (ch > MCDRV_DST_CH3) + break; + src = path->bias[ch]; + if (src & MCDRV_ASRC_MIC_ALL_ON) + return true; + break; + default: + break; + } + + return false; +} + +u32 mc_source_get(enum mcdrv_dst_type type, enum mcdrv_dst_ch ch) +{ + struct mcdrv_path_info *path; + + path = &mc_info.path_info; + + switch (type) { + case MCDRV_DST_MUSICOUT: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->music_out, ch); + case MCDRV_DST_EXTOUT: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->ext_out, ch); + case MCDRV_DST_HIFIOUT: + if (ch > MCDRV_DST_CH0) + break; + return d1_get_source(path->hifi_out, ch); + case MCDRV_DST_VBOXMIXIN: + return d1_get_source(path->vbox_mix_in, ch); + case MCDRV_DST_AE0: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->ae0, ch); + case MCDRV_DST_AE1: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->ae1, ch); + case MCDRV_DST_AE2: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->ae2, ch); + case MCDRV_DST_AE3: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->ae3, ch); + case MCDRV_DST_DAC0: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->dac0, ch); + case MCDRV_DST_DAC1: + if (ch > MCDRV_DST_CH1) + break; + return d1_get_source(path->dac1, ch); + case MCDRV_DST_VOICEOUT: + if (ch > MCDRV_DST_CH0) + break; + return d2_get_source(path->voice_out, ch); + case MCDRV_DST_VBOXIOIN: + if (ch > MCDRV_DST_CH0) + break; + return d2_get_source(path->vbox_io_in, ch); + case MCDRV_DST_VBOXHOSTIN: + if (ch > MCDRV_DST_CH0) + break; + return d2_get_source(path->vbox_host_in, ch); + case MCDRV_DST_HOSTOUT: + if (ch > MCDRV_DST_CH0) + break; + return d2_get_source(path->host_out, ch); + case MCDRV_DST_ADIF0: + if (ch > MCDRV_DST_CH1) + break; + return d2_get_source(path->adif0, ch); + case MCDRV_DST_ADIF1: + if (ch > MCDRV_DST_CH1) + break; + return d2_get_source(path->adif1, ch); + case MCDRV_DST_ADIF2: + if (ch > MCDRV_DST_CH1) + break; + return d2_get_source(path->adif2, ch); + default: + break; + } + + return 0; +} + +u8 mc_dsp_get_running(void) +{ + struct mcdrv_aec_info *aec; + u32 hifi_out; + u8 start = 0; + + aec = &mc_info.aec_info; + hifi_out = mc_info.path_info.hifi_out[0]; + + if ((hifi_out & MCDRV_D1SRC_ADIF0_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_ADC0_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_ADC1_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_PDM0_ON) + || mc_d2_source_is_used(MCDRV_D2SRC_PDM1_ON) + || mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) + start |= MCDRV_DSP_START_E | MCDRV_DSP_START_M; + + if (mc_d1_source_is_used(MCDRV_D1SRC_AE_ALL_ON)) { + start |= MCDRV_DSP_START_B | MCDRV_DSP_START_M; + if (!aec->fdsp_locate && aec->audio_engine.fdsp_on == 1) + start |= MCDRV_DSP_START_E | MCDRV_DSP_START_F; + } + + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3) + || mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) { + start |= MCDRV_DSP_START_M; + if (aec->vbox.cdsp_func_a_on || aec->vbox.cdsp_func_b_on) + start |= MCDRV_DSP_START_C; + if (aec->fdsp_locate && aec->vbox.fdsp_on == 1) + start |= MCDRV_DSP_START_F; + } else { + if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) { + start |= MCDRV_DSP_START_M; + if (aec->vbox.lpt2_vsource == 1) { + if (aec->vbox.cdsp_func_a_on + || aec->vbox.cdsp_func_b_on) + start |= MCDRV_DSP_START_C; + if (aec->fdsp_locate && aec->vbox.fdsp_on == 1) + start |= MCDRV_DSP_START_F; + } + } + + if (mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) { + start |= MCDRV_DSP_START_M; + if (aec->vbox.isrc2_vsource == 1) { + if (aec->vbox.cdsp_func_a_on + || aec->vbox.cdsp_func_b_on) + start |= MCDRV_DSP_START_C; + if (aec->fdsp_locate && aec->vbox.fdsp_on == 1) + start |= MCDRV_DSP_START_F; + } + } + + if (mc_source_is_used(MCDRV_DST_VBOXHOSTIN, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_HOSTOUT, MCDRV_DST_CH0)) { + if (aec->vbox.cdsp_func_a_on + || aec->vbox.cdsp_func_b_on) + start |= MCDRV_DSP_START_C; + if (aec->fdsp_locate && aec->vbox.fdsp_on == 1) + start |= MCDRV_DSP_START_F; + } + + if (mc_source_is_used(MCDRV_DST_VOICEOUT, MCDRV_DST_CH0) + && aec->vbox.lpt2_vsource == 1) { + if (aec->vbox.cdsp_func_a_on + || aec->vbox.cdsp_func_b_on) + start |= MCDRV_DSP_START_C; + if (aec->fdsp_locate && aec->vbox.fdsp_on == 1) + start |= MCDRV_DSP_START_F; + } + } + + if (mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON) + || mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0) + || mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) + start |= MCDRV_DSP_START_M; + + return start; +} + +void mc_resource_clear(void) +{ + mc_info.packet.data_size = 0; + mc_info.slave_addr = 0xffff; + mc_info.type = 0xffff; + mc_info.addr = 0xffff; + mc_info.data_count = 0; + mc_info.prev_addr_index = 0; +} + +void mc_bus_queue_add(u16 type, u16 addr, u8 data, enum mcdrv_update_mode mode) +{ + const u16 *next_list; + u16 size, next_addr, after_next_addr; + u16 index, prev_type, prev_addr, prev_slave_addr, slave_addr; + u8 *regs, *packet; + u8 packet_addr, packet_window, addr_inc_reg; + bool addr_inc; + + prev_type = mc_info.type; + prev_slave_addr = mc_info.slave_addr; + + slave_addr = MCDRV_SLAVE_ADDR_DIGITAL; + + switch (type) { + case MCDRV_PACKET_REGTYPE_IF: + regs = mc_info.if_registers; + next_list = mc_next_addr_list; + addr_inc = false; + addr_inc_reg = 0; + packet_addr = addr; + packet_window = packet_addr; + break; + case MCDRV_PACKET_REGTYPE_A: + regs = mc_info.a_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_A_REG_AINC; + packet_addr = MCI_A_REG_A; + packet_window = MCI_A_REG_D; + break; + case MCDRV_PACKET_REGTYPE_MA: + regs = mc_info.ma_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_MA_REG_AINC; + packet_addr = MCI_MA_REG_A; + packet_window = MCI_MA_REG_D; + break; + case MCDRV_PACKET_REGTYPE_MB: + regs = mc_info.mb_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_MB_REG_AINC; + packet_addr = MCI_MB_REG_A; + packet_window = MCI_MB_REG_D; + break; + case MCDRV_PACKET_REGTYPE_B: + regs = mc_info.b_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_B_REG_AINC; + packet_addr = MCI_B_REG_A; + packet_window = MCI_B_REG_D; + break; + case MCDRV_PACKET_REGTYPE_E: + regs = mc_info.e_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_E_REG_AINC; + packet_addr = MCI_E_REG_A; + packet_window = MCI_E_REG_D; + break; + case MCDRV_PACKET_REGTYPE_C: + regs = mc_info.c_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = 0; + packet_addr = MCI_C_REG_A; + packet_window = MCI_C_REG_D; + break; + case MCDRV_PACKET_REGTYPE_F: + regs = mc_info.f_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_F_REG_AINC; + packet_addr = MCI_F_REG_A; + packet_window = MCI_F_REG_D; + break; + case MCDRV_PACKET_REGTYPE_ANA: + slave_addr = MCDRV_SLAVE_ADDR_ANALOG; + regs = mc_info.ana_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_ANA_REG_AINC; + packet_addr = MCI_ANA_REG_A; + packet_window = MCI_ANA_REG_D; + break; + case MCDRV_PACKET_REGTYPE_CD: + slave_addr = MCDRV_SLAVE_ADDR_ANALOG; + regs = mc_info.cd_registers; + next_list = mc_next_addr_list_inc; + addr_inc = true; + addr_inc_reg = MCB_CD_REG_AINC; + packet_addr = MCI_CD_REG_A; + packet_window = MCI_CD_REG_D; + break; + default: + return; + } + + if ((prev_type != 0xffff && prev_type != type) + || (prev_slave_addr != 0xffff && prev_slave_addr != slave_addr)) { + mc_bus_queue_flush(); + mc_resource_clear(); + } + + if (mode != MCDRV_UPDATE_FORCE && data == regs[addr]) + return; + + if (mc_info.addr == 0xffff) + mc_info.addr = addr; + + prev_addr = mc_info.addr; + + if (mode != MCDRV_UPDATE_DUMMY) { + packet = mc_info.packet.data; + size = mc_info.packet.data_size; + index = mc_info.prev_addr_index; + next_addr = next_list[prev_addr]; + + if (size > MCDRV_MAX_CTRL_DATA_NUM - 8) + pr_warn("ymu831: remaining packet buffer too small\n"); + + if (slave_addr == prev_slave_addr && type == prev_type + && next_addr != 0xffff && addr != next_addr && addr_inc) { + after_next_addr = next_list[next_addr]; + if (after_next_addr == addr) { + if (!mc_info.data_count) + packet[index] |= BURST_WRITE_ENABLE; + + packet[size++] = regs[next_addr]; + mc_info.data_count++; + next_addr = after_next_addr; + } else if (after_next_addr != 0xffff + && next_list[after_next_addr] == addr) { + if (!mc_info.data_count) + packet[index] |= BURST_WRITE_ENABLE; + + packet[size++] = regs[next_addr]; + packet[size++] = regs[after_next_addr]; + mc_info.data_count += 2; + next_addr = next_list[after_next_addr]; + } + } + + if (!size || addr != next_addr) { + if (mc_info.data_count) { + mc_bus_queue_flush(); + mc_resource_clear(); + size = mc_info.packet.data_size; + } + + if (MCDRV_PACKET_REGTYPE_IF == type) { + packet[size] = packet_addr << 1; + index = size++; + } else { + packet[size++] = packet_addr << 1; + packet[size++] = addr | addr_inc_reg; + packet[size] = packet_window << 1; + index = size++; + } + + mc_info.prev_addr_index = index; + } else { + if (!mc_info.data_count) + packet[index] |= BURST_WRITE_ENABLE; + + mc_info.data_count++; + } + + packet[size++] = data; + + mc_info.slave_addr = slave_addr; + mc_info.type = type; + mc_info.addr = addr; + mc_info.packet.data_size = size; + } + + /* save register value */ + regs[addr] = data; +} + +void mc_bus_queue_flush(void) +{ + if (mc_info.packet.data_size) { + mc_write(mc_info.slave_addr, + mc_info.packet.data, + mc_info.packet.data_size); + } +} + +static int wait_set_bit(u8 slave_addr, u16 addr, u8 mask, + u32 interval, u32 timeout) +{ + u8 val; + + while (timeout > 0) { + mc_read(slave_addr, addr, &val, 1); + if ((val & mask) == mask) + return 0; + + msleep(interval); + timeout--; + } + + return -EAGAIN; +} + +static int wait_release_bit(u8 slave_addr, u16 addr, u8 mask, + u32 interval, u32 timeout) +{ + u8 val; + + while (timeout > 0) { + mc_read(slave_addr, addr, &val, 1); + if (!(val & mask)) + return 0; + + msleep(interval); + timeout--; + } + + return -EAGAIN; +} + +static int wait_set_dspbit(u8 slave_addr, u8 addr_a, u8 addr_d, u8 addr, + u8 mask, u32 interval, u32 timeout) +{ + u8 val, data[2]; + + data[0] = addr_a << 1; + data[1] = addr; + + while (timeout > 0) { + mc_write(slave_addr, data, 2); + mc_read(slave_addr, addr_d, &val, 1); + if ((val & mask) == mask) + return 0; + + msleep(interval); + timeout--; + } + + return -EAGAIN; +} + +static int wait_release_dspbit(u8 slave_addr, u8 addr_a, u8 addr_d, u8 addr, + u8 mask, u32 interval, u32 timeout) +{ + u8 val, data[2]; + + data[0] = addr_a << 1; + data[1] = addr; + + while (timeout > 0) { + mc_write(slave_addr, data, 2); + mc_read(slave_addr, addr_d, &val, 1); + if (!(val & mask)) + return 0; + + msleep(interval); + timeout--; + } + + return -EAGAIN; +} + +int mc_wait_event(u32 event, u32 param) +{ + u32 interval, timeout; + u8 data[2]; + int ret = 0; + + switch (event) { + case MCDRV_EVT_SVOL_DONE: + interval = mc_info.dev_info.wait_time.poll_interval[0]; + timeout = mc_info.dev_info.wait_time.poll_timeout[0]; + + if (param >> 8) { + data[0] = MCI_ANA_REG_A << 1; + data[1] = MCI_BUSY1; + mc_write_analog(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_ANALOG, + MCI_ANA_REG_D, param >> 8, + interval, timeout); + if (ret < 0) + break; + } + + if (param & 0xffU) { + data[0] = MCI_ANA_REG_A << 1; + data[1] = MCI_BUSY2; + mc_write_analog(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_ANALOG, + MCI_ANA_REG_D, param & 0xff, + interval, timeout); + } + break; + case MCDRV_EVT_ALLMUTE: + interval = mc_info.dev_info.wait_time.poll_interval[1]; + timeout = mc_info.dev_info.wait_time.poll_timeout[1]; + + data[0] = MCI_MA_REG_A << 1; + data[1] = MCI_DIFI_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, + (MCB_DIFI3_VFLAG1 | MCB_DIFI3_VFLAG0 | + MCB_DIFI2_VFLAG1 | MCB_DIFI2_VFLAG0 | + MCB_DIFI1_VFLAG1 | MCB_DIFI1_VFLAG0 | + MCB_DIFI1_VFLAG0 | MCB_DIFI0_VFLAG0), + interval, timeout); + if (ret < 0) + break; + + data[1] = MCI_ADI_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, + (MCB_ADI2_VFLAG1 | MCB_ADI2_VFLAG0 | + MCB_ADI1_VFLAG1 | MCB_ADI1_VFLAG0 | + MCB_ADI0_VFLAG1 | MCB_ADI0_VFLAG0), + interval, timeout); + if (ret < 0) + break; + + data[1] = MCI_DIFO_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, + (MCB_DIFO3_VFLAG1 | MCB_DIFO3_VFLAG0 | + MCB_DIFO2_VFLAG1 | MCB_DIFO2_VFLAG0 | + MCB_DIFO1_VFLAG1 | MCB_DIFO1_VFLAG0 | + MCB_DIFO1_VFLAG0 | MCB_DIFO0_VFLAG0), + interval, timeout); + if (ret < 0) + break; + + data[1] = MCI_DAO_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, + (MCB_DAO1_VFLAG1 | MCB_DAO1_VFLAG0 | + MCB_DAO0_VFLAG1 | MCB_DAO0_VFLAG0), + interval, timeout); + break; + case MCDRV_EVT_DIRMUTE: + interval = mc_info.dev_info.wait_time.poll_interval[1]; + timeout = mc_info.dev_info.wait_time.poll_timeout[1]; + + data[0] = MCI_MA_REG_A << 1; + data[1] = MCI_DIFI_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, param, interval, timeout); + break; + case MCDRV_EVT_ADCMUTE: + interval = mc_info.dev_info.wait_time.poll_interval[1]; + timeout = mc_info.dev_info.wait_time.poll_timeout[1]; + + data[0] = MCI_MA_REG_A << 1; + data[1] = MCI_ADI_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, param, interval, timeout); + break; + case MCDRV_EVT_DITMUTE: + interval = mc_info.dev_info.wait_time.poll_interval[1]; + timeout = mc_info.dev_info.wait_time.poll_timeout[1]; + + data[0] = MCI_MA_REG_A << 1; + data[1] = MCI_DIFO_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, param, interval, timeout); + break; + case MCDRV_EVT_DACMUTE: + interval = mc_info.dev_info.wait_time.poll_interval[1]; + timeout = mc_info.dev_info.wait_time.poll_timeout[1]; + + data[0] = MCI_MA_REG_A << 1; + data[1] = MCI_DAO_VFLAG; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_MA_REG_D, param, interval, timeout); + break; + case MCDRV_EVT_CLKBUSY_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[2]; + timeout = mc_info.dev_info.wait_time.poll_timeout[2]; + + data[0] = MCI_A_REG_A << 1; + data[1] = MCI_CLKSRC; + mc_write_digital(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + MCI_A_REG_D, MCB_CLKBUSY, interval, + timeout); + break; + case MCDRV_EVT_PSW_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[4]; + timeout = mc_info.dev_info.wait_time.poll_timeout[4]; + + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, + param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_OFFCAN_BSY_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + data[0] = MCI_CD_REG_A << 1; + data[1] = MCI_SSENSEFIN; + mc_write_analog(data, 2); + ret = wait_release_bit(MCDRV_SLAVE_ADDR_ANALOG, MCI_CD_REG_D, + MCB_OFFCAN_BSY, interval, timeout); + break; + case MCDRV_EVT_ANA_RDY: + interval = mc_info.dev_info.wait_time.poll_interval[5]; + timeout = mc_info.dev_info.wait_time.poll_timeout[5]; + + data[0] = MCI_ANA_REG_A << 1; + data[1] = param >> 8; + mc_write_analog(data, 2); + ret = wait_set_bit(MCDRV_SLAVE_ADDR_ANALOG, MCI_ANA_REG_D, + param & 0xff, interval, timeout); + break; + case MCDRV_EVT_AP_CP_A_SET: + interval = mc_info.dev_info.wait_time.poll_interval[5]; + timeout = mc_info.dev_info.wait_time.poll_timeout[5]; + + data[0] = MCI_ANA_REG_A << 1; + data[1] = param >> 8; + mc_write_analog(data, 2); + ret = wait_set_bit(MCDRV_SLAVE_ADDR_ANALOG, MCI_ANA_REG_D, + param & 0xff, interval, timeout); + break; + case MCDRV_EVT_IF_REG_FLAG_SET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_set_bit(MCDRV_SLAVE_ADDR_DIGITAL, param >> 8, + param & 0xff, interval, timeout); + break; + case MCDRV_EVT_IF_REG_FLAG_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_release_bit(MCDRV_SLAVE_ADDR_DIGITAL, param >> 8, + param & 0xff, interval, timeout); + break; + case MCDRV_EVT_B_REG_FLAG_SET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_set_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_B_REG_A, + MCI_B_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_B_REG_FLAG_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_release_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_B_REG_A, + MCI_B_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_E_REG_FLAG_SET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_set_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_E_REG_A, + MCI_E_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_E_REG_FLAG_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_release_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_E_REG_A, + MCI_E_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_C_REG_FLAG_SET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_set_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_C_REG_A, + MCI_C_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_C_REG_FLAG_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + ret = wait_release_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_C_REG_A, + MCI_C_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_F_REG_FLAG_SET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + ret = wait_set_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_F_REG_A, + MCI_F_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + case MCDRV_EVT_F_REG_FLAG_RESET: + interval = mc_info.dev_info.wait_time.poll_interval[3]; + timeout = mc_info.dev_info.wait_time.poll_timeout[3]; + + ret = wait_release_dspbit(MCDRV_SLAVE_ADDR_DIGITAL, MCI_F_REG_A, + MCI_F_REG_D, param >> 8, param & 0xff, + interval, timeout); + break; + default: + ret = -EINVAL; + } + + return ret; +} diff --git a/sound/soc/codecs/ymu831/mcresctrl.h b/sound/soc/codecs/ymu831/mcresctrl.h new file mode 100644 index 0000000..4494779 --- /dev/null +++ b/sound/soc/codecs/ymu831/mcresctrl.h @@ -0,0 +1,394 @@ +/**************************************************************************** + * + * Copyright(c) 2012 Yamaha Corporation. All rights reserved. + * + * Module : mcresctrl.h + * Description : MC resource control driver header + * Version : 1.0.0 Dec 13 2012 + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ****************************************************************************/ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _MCRESCTRL_H +#define _MCRESCTRL_H + +#include "mcdriver.h" +#include "mcpacking.h" + +#define MCDRV_DEVID_ANA 0x90 +#define MCDRV_DEVID_DIG 0x80 +#define MCDRV_DEVID_MASK 0xf8 +#define MCDRV_VERID_MASK 0x07 + +enum mcdrv_state { + MCDRV_STATE_NOTINIT, + MCDRV_STATE_READY, +}; + +/* volume setting */ +#define MCDRV_LOGICAL_VOL_MUTE -24576 /* -96dB */ + +#define MCDRV_REG_MUTE 0x00 + +/* Path destination channel */ +enum mcdrv_dst_ch { + MCDRV_DST_CH0 = 0, + MCDRV_DST_CH1, + MCDRV_DST_CH2, + MCDRV_DST_CH3 +}; + +/* Path destination type */ +enum mcdrv_dst_type { + MCDRV_DST_MUSICOUT = 0, + MCDRV_DST_EXTOUT, + MCDRV_DST_HIFIOUT, + MCDRV_DST_VBOXMIXIN, + MCDRV_DST_AE0, + MCDRV_DST_AE1, + MCDRV_DST_AE2, + MCDRV_DST_AE3, + MCDRV_DST_DAC0, + MCDRV_DST_DAC1, + MCDRV_DST_VOICEOUT, + MCDRV_DST_VBOXIOIN, + MCDRV_DST_VBOXHOSTIN, + MCDRV_DST_HOSTOUT, + MCDRV_DST_ADIF0, + MCDRV_DST_ADIF1, + MCDRV_DST_ADIF2, + MCDRV_DST_ADC0, + MCDRV_DST_ADC1, + MCDRV_DST_SP, + MCDRV_DST_HP, + MCDRV_DST_RCV, + MCDRV_DST_LOUT1, + MCDRV_DST_LOUT2, + MCDRV_DST_BIAS +}; + +/* Register update parameter */ +enum mcdrv_update_mode { + MCDRV_UPDATE_NORMAL, + MCDRV_UPDATE_FORCE, + MCDRV_UPDATE_DUMMY +}; + +/* DSP Start */ +#define MCDRV_DSP_START_E 0x01 +#define MCDRV_DSP_START_B 0x02 +#define MCDRV_DSP_START_M 0x04 +#define MCDRV_DSP_START_F 0x08 +#define MCDRV_DSP_START_C 0x10 + +struct mcdrv_aec_bdsp { + u8 *data; + u32 data_size; +}; + +struct mcdrv_aec_fdsp { + u8 *data; + u32 data_size; +}; + +struct mcdrv_aec_cdsp { + u8 *data; + u32 data_size; +}; + +struct mcdrv_aec_syseq_ex { + bool enable; + struct { + u8 coef_a0[3]; + u8 coef_a1[3]; + u8 coef_a2[3]; + u8 coef_b1[3]; + u8 coef_b2[3]; + } band[2]; +}; + +struct mcdrv_aec_e2_config { + u8 *data; + u32 data_size; +}; + +struct mcdrv_aec_audio_engine { + bool enable; + u8 on; + bool fdsp_on; + u8 bdsp_ae0_src; + u8 bdsp_ae1_src; + u8 mixer_in0_src; + u8 mixer_in1_src; + u8 mixer_in2_src; + u8 mixer_in3_src; + struct mcdrv_aec_bdsp bdsp; + struct mcdrv_aec_fdsp fdsp; +}; + +struct mcdrv_aec_vbox { + bool enable; + u8 cdsp_func_a_on; + u8 cdsp_func_b_on; + u8 cdsp_jtag_on; + bool fdsp_on; + u8 fdsp_po_source; + u8 isrc2_vsource; + u8 isrc2_ch1_vsource; + u8 isrc3_vsource; + u8 lpt2_vsource; + u8 lpt2_mix_vol_o; + u8 lpt2_mix_vol_i; + u8 src3_ctrl; + u8 src2_fs; + u8 src2_thru; + u8 src3_fs; + u8 src3_thru; + struct mcdrv_aec_cdsp cdsp_a; + struct mcdrv_aec_cdsp cdsp_b; + struct mcdrv_aec_fdsp fdsp; +}; + +#define MCDRV_AEC_OUTPUT_N 2 + +struct mcdrv_aec_output { + u8 lpf_pre_thru[MCDRV_AEC_OUTPUT_N]; + u8 lpf_post_thru[MCDRV_AEC_OUTPUT_N]; + u8 dcc_sel[MCDRV_AEC_OUTPUT_N]; + u8 signal_detect_level; + u8 power_detect_level[MCDRV_AEC_OUTPUT_N]; + u8 osf_sel[MCDRV_AEC_OUTPUT_N]; + u8 syseq_enb[MCDRV_AEC_OUTPUT_N]; + u8 syseq_coef_a0[MCDRV_AEC_OUTPUT_N][3]; + u8 syseq_coef_a1[MCDRV_AEC_OUTPUT_N][3]; + u8 syseq_coef_a2[MCDRV_AEC_OUTPUT_N][3]; + u8 syseq_coef_b1[MCDRV_AEC_OUTPUT_N][3]; + u8 syseq_coef_b2[MCDRV_AEC_OUTPUT_N][3]; + u8 clip_md[MCDRV_AEC_OUTPUT_N]; + u8 clip_att[MCDRV_AEC_OUTPUT_N]; + u8 clip_rel[MCDRV_AEC_OUTPUT_N]; + u8 clip_g[MCDRV_AEC_OUTPUT_N]; + u8 osf_gain[MCDRV_AEC_OUTPUT_N][2]; + u8 dcl_on[MCDRV_AEC_OUTPUT_N]; + u8 dcl_gain[MCDRV_AEC_OUTPUT_N]; + u8 dcl_limit[MCDRV_AEC_OUTPUT_N][2]; + u8 random_dither_on[MCDRV_AEC_OUTPUT_N]; + u8 random_dither_level[MCDRV_AEC_OUTPUT_N]; + u8 random_dither_pos[MCDRV_AEC_OUTPUT_N]; + u8 dc_dither_on[MCDRV_AEC_OUTPUT_N]; + u8 dc_dither_level[MCDRV_AEC_OUTPUT_N]; + u8 dither_type[MCDRV_AEC_OUTPUT_N]; + u8 dng_on[MCDRV_AEC_OUTPUT_N]; + u8 dng_zero[MCDRV_AEC_OUTPUT_N]; + u8 dng_time[MCDRV_AEC_OUTPUT_N]; + u8 dng_fw[MCDRV_AEC_OUTPUT_N]; + u8 dng_attack; + u8 dng_release; + u8 dng_target[MCDRV_AEC_OUTPUT_N]; + u8 dng_target_lineout[MCDRV_AEC_OUTPUT_N]; + u8 dng_target_rc; + struct mcdrv_aec_syseq_ex syseq_ex[MCDRV_AEC_OUTPUT_N]; +}; + +#define MCDRV_AEC_INPUT_N 3 + +struct mcdrv_aec_input { + u8 dsf32_l_type[MCDRV_AEC_INPUT_N]; + u8 dsf32_r_type[MCDRV_AEC_INPUT_N]; + u8 dsf4_sel[MCDRV_AEC_INPUT_N]; + u8 dcc_sel[MCDRV_AEC_INPUT_N]; + u8 dng_on[MCDRV_AEC_INPUT_N]; + u8 dng_att[MCDRV_AEC_INPUT_N]; + u8 dng_rel[MCDRV_AEC_INPUT_N]; + u8 dng_fw[MCDRV_AEC_INPUT_N]; + u8 dng_time[MCDRV_AEC_INPUT_N]; + u8 dng_zero[MCDRV_AEC_INPUT_N][2]; + u8 dng_target[MCDRV_AEC_INPUT_N][2]; + u8 depop_att[MCDRV_AEC_INPUT_N]; + u8 depop_wait[MCDRV_AEC_INPUT_N]; + u8 ref_sel; +}; + +struct mcdrv_aec_pdm { + u8 mode; + u8 st_wait; + u8 pdm0_loadtime; + u8 pdm0_l_finedelay; + u8 pdm0_r_finedelay; + u8 pdm1_loadtime; + u8 pdm1_l_finedelay; + u8 pdm1_r_finedelay; + u8 pdm0_data_delay; + u8 pdm1_data_delay; +}; + +struct mcdrv_aec_e2 { + bool enable; + u8 da_sel; + u8 ad_sel; + bool on; + struct mcdrv_aec_e2_config config; +}; +struct mcdrv_aec_adj { + u8 hold; + u8 cnt; + u8 max[2]; +}; + +struct mcdrv_aec_edsp_misc { + u8 i2s_out_enable; + u8 ch_sel; + u8 loopback; +}; + +struct mcdrv_aec_control { + u8 command; + u8 param[4]; +}; + +/* fdsp_locate */ +#define FDSP_LOCATE_AUDIOENGINE 0 +#define FDSP_LOCATE_V_BOX 1 + +struct mcdrv_aec_info { + u8 fdsp_locate; + struct mcdrv_aec_audio_engine audio_engine; + struct mcdrv_aec_vbox vbox; + struct mcdrv_aec_output output; + struct mcdrv_aec_input input; + struct mcdrv_aec_pdm pdm; + struct mcdrv_aec_e2 e2; + struct mcdrv_aec_adj adj; + struct mcdrv_aec_edsp_misc edsp_misc; + struct mcdrv_aec_control control; +}; + +/* mcdrv_gp_mode gp_ddr setting */ +#define MCDRV_GPDDR_IN 0 +#define MCDRV_GPDDR_OUT 1 + +/* mcdrv_gp_mode gp_host setting */ +#define MCDRV_GPHOST_CPU 0 +#define MCDRV_GPHOST_CDSP 1 + +/* mcdrv_gp_mode gp_invert setting */ +#define MCDRV_GPINV_NORMAL 0 +#define MCDRV_GPINV_INVERT 1 + +#define MCDRV_GP_PAD0 0 +#define MCDRV_GP_PAD1 1 +#define MCDRV_GP_PAD2 2 +#define MCDRV_GP_NUM 3 + +struct mcdrv_gp_mode { + bool gp_ddr[MCDRV_GP_NUM]; + bool gp_host[MCDRV_GP_NUM]; + bool gp_invert[MCDRV_GP_NUM]; +}; + +enum mcdrv_dev_id { + MCDRV_DEV_ID_UNKNOWN = 0, + MCDRV_DEV_ID_80_90H, + MCDRV_DEV_ID_81_91H, + MCDRV_DEV_ID_81_92H, +}; + +int mc_id_set(u8 digital_id, u8 analog_id); +enum mcdrv_dev_id mc_dev_id_get(void); +void mc_resource_init(void); +void mc_a_registers_init(void); +void mc_mblock_registers_init(void); +void mc_e_registers_init(void); +void mc_state_update(enum mcdrv_state state); +enum mcdrv_state mc_state_get(void); +u8 mc_register_get_value(u16 type, u16 addr); +void mc_register_set_value(u16 type, u16 addr, u8 val); + +#define mc_if_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_IF, (addr)) +#define mc_ma_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_MA, (addr)) +#define mc_mb_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_MB, (addr)) +#define mc_a_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_A, (addr)) +#define mc_e_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_E, (addr)) +#define mc_ana_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_ANA, (addr)) +#define mc_cd_register_get_value(addr) \ + mc_register_get_value(MCDRV_PACKET_REGTYPE_CD, (addr)) +#define mc_if_register_set_value(addr, val) \ + mc_register_set_value(MCDRV_PACKET_REGTYPE_IF, (addr), (val)) +#define mc_ma_register_set_value(addr, val) \ + mc_register_set_value(MCDRV_PACKET_REGTYPE_MA, (addr), (val)) +#define mc_ana_register_set_value(addr, val) \ + mc_register_set_value(MCDRV_PACKET_REGTYPE_ANA, (addr), (val)) +#define mc_cd_register_set_value(addr, val) \ + mc_register_set_value(MCDRV_PACKET_REGTYPE_CD, (addr), (val)) + +void mc_dev_info_set(struct mcdrv_dev_info *dev_info); +void mc_dev_info_get(struct mcdrv_dev_info *dev_info); +int mc_clock_set(u8 clock); +void mc_clock_get(u8 *clock); +int mc_path_info_set(struct mcdrv_path_info *path_info); +void mc_path_info_get(struct mcdrv_path_info *path_info); +void mc_path_info_get_virtual(struct mcdrv_path_info *path_info); +void mc_vol_info_set(struct mcdrv_vol_info *vol_info); +void mc_vol_info_get(struct mcdrv_vol_info *vol_info); +void mc_dio_info_set(struct mcdrv_dio_info *dio_info, u32 update); +void mc_dio_info_get(struct mcdrv_dio_info *dio_info); +void mc_dio_path_info_set(struct mcdrv_dio_path_info *dio_path_info, + u32 update); +void mc_dio_path_info_get(struct mcdrv_dio_path_info *dio_path_info); +void mc_swap_info_set(struct mcdrv_swap_info *swap_info, u32 update); +void mc_swap_info_get(struct mcdrv_swap_info *swap_info); +void mc_hsdet_info_set(struct mcdrv_hsdet_info *hsdet_info, u32 update); +void mc_hsdet_info_get(struct mcdrv_hsdet_info *hsdet_info); +void mc_aec_info_set(struct mcdrv_aec_info *aec_info); +void mc_aec_info_replace(struct mcdrv_aec_info *aec_info); +void mc_aec_info_get(struct mcdrv_aec_info *aec_info); +void mc_gp_mode_set(struct mcdrv_gp_mode *mode); +void mc_gp_mode_get(struct mcdrv_gp_mode *mode); +bool mc_gp_pad_get(u32 pad_no); +void mc_clock_select_set(u8 clk_sel); +u8 mc_clock_select_get(void); +void mc_e_clock_select_set(u8 eclk_sel); +u8 mc_e_clock_select_get(void); +void mc_plug_detect_db_set(u8 plug_det_db); +u8 mc_plug_detect_db_get(void); +void mc_volume_info_get(struct mcdrv_vol_info *vol_info); +void mc_power_info_get(struct mcdrv_power_info *info); +void mc_power_info_get_current(struct mcdrv_power_info *info); +bool mc_d1_source_is_used(u32 mask); +bool mc_d2_source_is_used(u32 mask); +bool mc_a_source_is_used(u32 mask); +bool mc_source_is_used(enum mcdrv_dst_type type, enum mcdrv_dst_ch ch); +u32 mc_source_get(enum mcdrv_dst_type type, enum mcdrv_dst_ch ch); +u8 mc_dsp_get_running(void); +void mc_resource_clear(void); +void mc_bus_queue_add(u16 type, u16 addr, u8 data, enum mcdrv_update_mode mode); +void mc_bus_queue_flush(void); +int mc_wait_event(u32 event, u32 param); + +#endif /* _MCRESCTRL_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/ymu831_cfg.h | 539 ++++++++++++++++++++++++++++++++++ 1 file changed, 539 insertions(+) create mode 100644 sound/soc/codecs/ymu831/ymu831_cfg.h
diff --git a/sound/soc/codecs/ymu831/ymu831_cfg.h b/sound/soc/codecs/ymu831/ymu831_cfg.h new file mode 100644 index 0000000..61b8cbd --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831_cfg.h @@ -0,0 +1,539 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _YMU831_CFG_H +#define _YMU831_CFG_H + +#include <linux/input.h> +#include <linux/types.h> + +#include "mcdriver.h" +#include "ymu831_priv.h" + +#define MAX_YMS_CTRL_PARAM_SIZE 524288UL + +#define CAPTURE_PORT_MUSIC 0 +#define CAPTURE_PORT_EXT 1 +#define CAPTURE_PORT CAPTURE_PORT_MUSIC + +#define MC_ASOC_PHYS_DIO0 MCDRV_PHYSPORT_DIO0 +#define MC_ASOC_PHYS_DIO1 MCDRV_PHYSPORT_DIO1 +#define MC_ASOC_PHYS_DIO2 MCDRV_PHYSPORT_DIO2 +#define MC_ASOC_PHYS_NONE MCDRV_PHYSPORT_NONE +#define MC_ASOC_PHYS_SLIM0 MCDRV_PHYSPORT_SLIM0 +#define MC_ASOC_PHYS_SLIM1 MCDRV_PHYSPORT_SLIM1 +#define MC_ASOC_PHYS_SLIM2 MCDRV_PHYSPORT_SLIM2 +#define MUSIC_PHYSICAL_PORT MC_ASOC_PHYS_DIO0 +#define EXT_PHYSICAL_PORT MC_ASOC_PHYS_DIO2 +#define VOICE_PHYSICAL_PORT MC_ASOC_PHYS_DIO1 +#define HIFI_PHYSICAL_PORT MC_ASOC_PHYS_DIO0 + +#define VOICE_RECORDING_UNMUTE 1 + +#define INCALL_MIC_SP MC_ASOC_INCALL_MIC_MAINMIC +#define INCALL_MIC_RC MC_ASOC_INCALL_MIC_MAINMIC +#define INCALL_MIC_HP MC_ASOC_INCALL_MIC_MAINMIC +#define INCALL_MIC_LO1 MC_ASOC_INCALL_MIC_MAINMIC +#define INCALL_MIC_LO2 MC_ASOC_INCALL_MIC_MAINMIC + +#define MIC_NONE 0 +#define MIC_1 1 +#define MIC_2 2 +#define MIC_3 3 +#define MIC_4 4 +#define MIC_PDM0 5 +#define MIC_PDM1 6 + +#define MAIN_MIC MIC_1 +#define SUB_MIC MIC_2 +#define HEADSET_MIC MIC_4 + +#define BIAS_OFF 0 +#define BIAS_ON_ALWAYS 1 +#define BIAS_SYNC_MIC 2 +#define MIC1_BIAS BIAS_SYNC_MIC +#define MIC2_BIAS BIAS_SYNC_MIC +#define MIC3_BIAS BIAS_SYNC_MIC +#define MIC4_BIAS BIAS_SYNC_MIC + +#define IRQ_TYPE IRQ_TYPE_EDGE_FALLING + +#define AUTO_POWEROFF_OFF 0 +#define AUTO_POWEROFF_ON 1 +#define AUTO_POWEROFF AUTO_POWEROFF_ON + +static const struct mc_asoc_setup mc_asoc_cfg_setup = { + .info = { + .clk_sel = MCDRV_CKSEL_CMOS_CMOS, + .clk_input = MCDRV_CKINPUT_CLKI0_CLKI1, + .pll_mode_a = 4, + .pll_prev_div_a = 10, + .pll_fb_div_a = 130, + .pll_frac_a = 40124, + .pll_freq_a = 1, + .pll_mode_b = 4, + .hsdet_clk = MCDRV_HSDETCLK_RTC, + .dio0_sdo_hiz = MCDRV_DAHIZ_HIZ, + .dio1_sdo_hiz = MCDRV_DAHIZ_HIZ, + .dio2_sdo_hiz = MCDRV_DAHIZ_HIZ, + .dio0_clk_hiz = MCDRV_DAHIZ_HIZ, + .dio1_clk_hiz = MCDRV_DAHIZ_HIZ, + .dio2_clk_hiz = MCDRV_DAHIZ_HIZ, + .dio0_pcm_hiz = MCDRV_PCMHIZ_LOW, + .dio1_pcm_hiz = MCDRV_PCMHIZ_LOW, + .dio2_pcm_hiz = MCDRV_PCMHIZ_LOW, + .pa0_func = MCDRV_PA_GPIO, + .pa1_func = MCDRV_PA_GPIO, + .pa2_func = MCDRV_PA_GPIO, + .power_mode = MCDRV_POWMODE_FULL, + .mb_sel1 = MCDRV_MBSEL_22, + .mb_sel2 = MCDRV_MBSEL_22, + .mb_sel3 = MCDRV_MBSEL_22, + .mb_sel4 = MCDRV_MBSEL_22, + .mbs_disch = MCDRV_MBSDISCH_1000, + .nonclip = MCDRV_NONCLIP_OFF, + .line_in1_dif = MCDRV_LINE_STEREO, + .line_out1_dif = MCDRV_LINE_STEREO, + .line_out2_dif = MCDRV_LINE_STEREO, + .mic1_single = MCDRV_MIC_DIF, + .mic2_single = MCDRV_MIC_DIF, + .mic3_single = MCDRV_MIC_DIF, + .mic4_single = MCDRV_MIC_DIF, + .zc_line_out1 = MCDRV_ZC_OFF, + .zc_line_out2 = MCDRV_ZC_OFF, + .zc_rc = MCDRV_ZC_ON, + .zc_sp = MCDRV_ZC_ON, + .zc_hp = MCDRV_ZC_OFF, + .svol_line_out1 = MCDRV_SVOL_ON, + .svol_line_out2 = MCDRV_SVOL_ON, + .svol_rc = MCDRV_SVOL_ON, + .svol_sp = MCDRV_SVOL_ON, + .svol_hp = MCDRV_SVOL_ON, + .rc_hiz = MCDRV_RCIMP_FIXLOW, + .sp_hiz = MCDRV_WL_LOFF_ROFF, + .hp_hiz = MCDRV_IMP_LFIXLOW_RFIXLOW, + .line_out1_hiz = MCDRV_IMP_LFIXLOW_RFIXLOW, + .line_out2_hiz = MCDRV_IMP_LFIXLOW_RFIXLOW, + .cp_mod = MCDRV_CPMOD_MID, + .rb_sel = MCDRV_RBSEL_2_2K, + .plug_sel = MCDRV_PLUG_LRGM, + .gnd_det = MCDRV_GNDDET_OFF, + .ppd_rc = MCDRV_PPD_OFF, + .ppd_sp = MCDRV_PPD_OFF, + .ppd_hp = MCDRV_PPD_OFF, + .ppd_line_out1 = MCDRV_PPD_OFF, + .ppd_line_out2 = MCDRV_PPD_OFF, + .options = { + MCDRV_DOA_DRV_HIGH, MCDRV_SCKMSK_OFF, + MCDRV_SPMN_OFF_9, 0x03, 0x30, 0x30, + 0x21, 0x03, 0xc0, 0x6a, 0x10, 0xc0, 0x01, 0x0f, + }, + .wait_time = { + .wait = { + 5000, 5000, 5000, 5000, + 25000, 15000, 2000, + /* usec */ + }, + .poll_interval = { + 1, 1, 1, 1, 1, 1, + /* msec */ + }, + .poll_timeout = { + 1000, 1000, 1000, + 1000, 1000, 1000, + /* times */ + }, + }, + }, + .rslot = {0, 1, 2}, + .tslot = {0, 1, 2}, +}; + +static const struct mcdrv_dio_port music_port_def = { + .dio_common = { + .master_slave = MCDRV_DIO_MASTER, + + /* auto_fs : Sampling frequency automatic measurement + ON/OFF Setting in slave mode */ + /* MCDRV_AUTOFS_OFF (0): OFF */ + /* MCDRV_AUTOFS_ON (1): ON */ + .auto_fs = MCDRV_AUTOFS_ON, + + /* fs : Sampling Rate Setting */ + /* MCDRV_FS_48000 (0): 48kHz */ + /* MCDRV_FS_44100 (1): 44.1kHz */ + /* MCDRV_FS_32000 (2): 32kHz */ + /* MCDRV_FS_24000 (4): 24kHz */ + /* MCDRV_FS_22050 (5): 22.05kHz */ + /* MCDRV_FS_16000 (6): 16kHz */ + /* MCDRV_FS_12000 (8): 12kHz */ + /* MCDRV_FS_11025 (9): 11.025kHz */ + /* MCDRV_FS_8000 (10): 8kHz */ + .fs = MCDRV_FS_48000, + + /* bck_fs : Bit Clock Frequency Setting */ + /* MCDRV_BCKFS_64 (0): LRCK x 64 */ + /* MCDRV_BCKFS_48 (1): LRCK x 48 */ + /* MCDRV_BCKFS_32 (2): LRCK x 32 */ + /* MCDRV_BCKFS_512 (4): LRCK x 512 */ + /* MCDRV_BCKFS_256 (5): LRCK x 256 */ + /* MCDRV_BCKFS_128 (6): LRCK x 128 */ + /* MCDRV_BCKFS_16 (7): LRCK x 16 */ + .bck_fs = MCDRV_BCKFS_32, + + /* interface : Interface Selection */ + /* MCDRV_DIO_DA (0): Digital Audio */ + /* MCDRV_DIO_PCM (1): PCM */ + .interface = MCDRV_DIO_DA, + + /* bck_invert : Bit Clock Inversion Setting */ + /* MCDRV_BCLK_NORMAL (0): Normal Operation */ + /* MCDRV_BCLK_INVERT (1): Clock Inverted */ + .bck_invert = MCDRV_BCLK_NORMAL, + + /* MCDRV_SRC_NOT_THRU (0) */ + /* MCDRV_SRC_THRU (1) */ + .src_thru = MCDRV_SRC_NOT_THRU, + + /* pcm_transition_edge : High Impedance transition timing + after transmitting the last PCM I/F data */ + /* MCDRV_PCMHIZTIM_FALLING (0): BCLK#* Falling Edge */ + /* MCDRV_PCMHIZTIM_RISING (1): BCLK#* Rising Edge */ + .pcm_hiz_transition = MCDRV_PCMHIZTRANS_FALLING, + + /* pcm_frame : Frame Mode Setting with PCM interface */ + /* MCDRV_PCM_SHORTFRAME (0): Short Frame */ + /* MCDRV_PCM_LONGFRAME (1): Long Frame */ + .pcm_frame = MCDRV_PCM_SHORTFRAME, + + /* pcm_high_period : LR clock High time setting + with PCM selected and Master selected */ + /* 0 to 31: High level keeps during the period of time. + setting value + 1 is the bit clock. */ + .pcm_high_period = 0, + }, + .dir = { + /* da_format : Digital Audio Format Information */ + .da_format = { + /* bit_sel : Bit Width Setting */ + /* MCDRV_BITSEL_16 (0): 16bit */ + /* MCDRV_BITSEL_20 (1): 20bit */ + /* MCDRV_BITSEL_24 (2): 24bit */ + /* MCDRV_BITSEL_32 (3): 32bit */ + .bit_sel = MCDRV_BITSEL_16, + + /* mode : Data Format Setting */ + /* MCDRV_DAMODE_HEADALIGN (0): + Left-justified Format */ + /* MCDRV_DAMODE_I2S (1): I2S */ + /* MCDRV_DAMODE_TAILALIGN (2): + Right-justified Format */ + .mode = MCDRV_DAMODE_I2S}, + /* pcm_format : PCM Format Information */ + .pcm_format = { + /* mono : Mono / Stereo Setting */ + /* MCDRV_PCM_STEREO (0): Stereo */ + /* MCDRV_PCM_MONO (1): Mono */ + .mono = MCDRV_PCM_MONO, + /* order : Bit Order Setting */ + /* MCDRV_PCM_MSB_FIRST (0): MSB First */ + /* MCDRV_PCM_LSB_FIRST (1): LSB First */ + .order = MCDRV_PCM_MSB_FIRST, + /* law : Data Format Setting */ + /* MCDRV_PCM_LINEAR (0): Linear */ + /* MCDRV_PCM_ALAW (1): A-Law */ + /* MCDRV_PCM_MULAW (2): u-Law */ + .law = MCDRV_PCM_LINEAR, + /* bit_sel : Bit Width Setting */ + /* MCDRV_PCM_BITSEL_8 (0): 8 bits */ + /* MCDRV_PCM_BITSEL_16 (1): 16 bits */ + /* MCDRV_PCM_BITSEL_24 (2): 24 bits */ + .bit_sel = MCDRV_PCM_BITSEL_8} + }, + .dit = { + .st_mode = MCDRV_STMODE_ZERO, + .edge = MCDRV_SDOUT_NORMAL, + /* da_format : Digital Audio Format Information */ + .da_format = { + /* bit_sel : Bit Width Setting */ + /* MCDRV_BITSEL_16 (0): 16bit */ + /* MCDRV_BITSEL_20 (1): 20bit */ + /* MCDRV_BITSEL_24 (2): 24bit */ + /* MCDRV_BITSEL_32 (3): 32bit */ + .bit_sel = MCDRV_BITSEL_16, + + /* mode : Data Format Setting */ + /* MCDRV_DAMODE_HEADALIGN (0): + Left-justified Format */ + /* MCDRV_DAMODE_I2S (1): I2S */ + /* MCDRV_DAMODE_TAILALIGN (2): + Right-justified Format */ + .mode = MCDRV_DAMODE_I2S}, + /* pcm_format : PCM Format Information */ + .pcm_format = { + /* mono : Mono / Stereo Setting */ + /* MCDRV_PCM_STEREO (0): Stereo */ + /* MCDRV_PCM_MONO (1): Mono */ + .mono = MCDRV_PCM_MONO, + /* order : Bit Order Setting */ + /* MCDRV_PCM_MSB_FIRST (0): MSB First */ + /* MCDRV_PCM_LSB_FIRST (1): LSB First */ + .order = MCDRV_PCM_MSB_FIRST, + /* law : Data Format Setting */ + /* MCDRV_PCM_LINEAR (0): Linear */ + /* MCDRV_PCM_ALAW (1): A-Law */ + /* MCDRV_PCM_MULAW (2): u-Law */ + .law = MCDRV_PCM_LINEAR, + /* bit_sel : Bit Width Setting */ + /* MCDRV_PCM_BITSEL_8 (0): 8 bits */ + /* MCDRV_PCM_BITSEL_16 (1): 16 bits */ + /* MCDRV_PCM_BITSEL_24 (2): 24 bits */ + .bit_sel = MCDRV_PCM_BITSEL_16} + } +}; + +static const struct mcdrv_dio_port ext_port_def = { + .dio_common = { + .master_slave = MCDRV_DIO_SLAVE, + .auto_fs = MCDRV_AUTOFS_ON, + .fs = MCDRV_FS_8000, + .bck_fs = MCDRV_BCKFS_32, + .interface = MCDRV_DIO_PCM, + .bck_invert = MCDRV_BCLK_NORMAL, + .src_thru = MCDRV_SRC_NOT_THRU, + .pcm_hiz_transition = MCDRV_PCMHIZTRANS_FALLING, + .pcm_frame = MCDRV_PCM_SHORTFRAME, + .pcm_high_period = 0, + }, + .dir = { + .da_format = { + .bit_sel = MCDRV_BITSEL_16, + .mode = MCDRV_DAMODE_HEADALIGN}, + .pcm_format = { + .mono = MCDRV_PCM_MONO, + .order = MCDRV_PCM_LSB_FIRST, + .law = MCDRV_PCM_LINEAR, + .bit_sel = MCDRV_PCM_BITSEL_16} + }, + .dit = { + .st_mode = MCDRV_STMODE_ZERO, + .edge = MCDRV_SDOUT_NORMAL, + .da_format = { + .bit_sel = MCDRV_BITSEL_16, + .mode = MCDRV_DAMODE_HEADALIGN}, + .pcm_format = { + .mono = MCDRV_PCM_MONO, + .order = MCDRV_PCM_LSB_FIRST, + .law = MCDRV_PCM_LINEAR, + .bit_sel = MCDRV_PCM_BITSEL_16} + } +}; + +static const struct mcdrv_dio_port voice_port_def = { + .dio_common = { + .master_slave = MCDRV_DIO_SLAVE, + .auto_fs = MCDRV_AUTOFS_ON, + .fs = MCDRV_FS_8000, + .bck_fs = MCDRV_BCKFS_32, + .interface = MCDRV_DIO_DA, + .bck_invert = MCDRV_BCLK_NORMAL, + .src_thru = MCDRV_SRC_NOT_THRU, + .pcm_hiz_transition = MCDRV_PCMHIZTRANS_FALLING, + .pcm_frame = MCDRV_PCM_SHORTFRAME, + .pcm_high_period = 0, + }, + .dir = { + .da_format = { + .bit_sel = MCDRV_BITSEL_16, + .mode = MCDRV_DAMODE_I2S}, + .pcm_format = { + .mono = MCDRV_PCM_MONO, + .order = MCDRV_PCM_LSB_FIRST, + .law = MCDRV_PCM_LINEAR, + .bit_sel = MCDRV_PCM_BITSEL_16}, + }, + .dit = { + .st_mode = MCDRV_STMODE_ZERO, + .edge = MCDRV_SDOUT_NORMAL, + .da_format = { + .bit_sel = MCDRV_BITSEL_16, + .mode = MCDRV_DAMODE_I2S}, + .pcm_format = { + .mono = MCDRV_PCM_MONO, + .order = MCDRV_PCM_LSB_FIRST, + .law = MCDRV_PCM_LINEAR, + .bit_sel = MCDRV_PCM_BITSEL_16} + } +}; + +static const struct mcdrv_dio_port hifi_port_def = { + .dio_common = { + .master_slave = MCDRV_DIO_MASTER, + .auto_fs = MCDRV_AUTOFS_ON, + .fs = MCDRV_FS_48000, + .bck_fs = MCDRV_BCKFS_32, + .interface = MCDRV_DIO_DA, + .bck_invert = MCDRV_BCLK_NORMAL, + .src_thru = MCDRV_SRC_NOT_THRU, + .pcm_hiz_transition = MCDRV_PCMHIZTRANS_FALLING, + .pcm_frame = MCDRV_PCM_SHORTFRAME, + .pcm_high_period = 0, + }, + .dir = { + .da_format = { + .bit_sel = MCDRV_BITSEL_16, + .mode = MCDRV_DAMODE_I2S}, + .pcm_format = { + .mono = MCDRV_PCM_MONO, + .order = MCDRV_PCM_MSB_FIRST, + .law = MCDRV_PCM_LINEAR, + .bit_sel = MCDRV_PCM_BITSEL_8} + }, + .dit = { + .st_mode = MCDRV_STMODE_ZERO, + .edge = MCDRV_SDOUT_NORMAL, + .da_format = { + .bit_sel = MCDRV_BITSEL_16, + .mode = MCDRV_DAMODE_I2S}, + .pcm_format = { + .mono = MCDRV_PCM_MONO, + .order = MCDRV_PCM_MSB_FIRST, + .law = MCDRV_PCM_LINEAR, + .bit_sel = MCDRV_PCM_BITSEL_16} + } +}; + +static const struct mcdrv_hsdet_info hsdet_info_def = { + .en_plug_det = MCDRV_PLUGDET_DISABLE, + .en_plug_det_db = MCDRV_PLUGDETDB_BOTH_ENABLE, + .en_dly_key_off = MCDRV_KEYEN_D_D_D, + .en_dly_key_on = MCDRV_KEYEN_D_D_D, + .en_mic_det = MCDRV_MICDET_ENABLE, + .en_key_off = MCDRV_KEYEN_E_E_E, + .en_key_on = MCDRV_KEYEN_E_E_E, + .hs_det_dbnc = MCDRV_DETDBNC_219, + .key_off_mtim = MCDRV_KEYOFF_MTIM_63, + .key_on_mtim = MCDRV_KEYON_MTIM_63, + .key0_off_dly_tim = 8, + .key1_off_dly_tim = 8, + .key2_off_dly_tim = 8, + .key0_on_dly_tim = 8, + .key1_on_dly_tim = 8, + .key2_on_dly_tim = 8, + .irq_type = MCDRV_IRQTYPE_REF, + .plug_det_db_irq_type = MCDRV_IRQTYPE_REF, + .plug_undet_db_irq_type = MCDRV_IRQTYPE_REF, + .mic_det_irq_type = MCDRV_IRQTYPE_REF, + .plug_det_irq_type = MCDRV_IRQTYPE_REF, + .key0_on_irq_type = MCDRV_IRQTYPE_REF, + .key1_on_irq_type = MCDRV_IRQTYPE_REF, + .key2_on_irq_type = MCDRV_IRQTYPE_REF, + .key0_off_irq_type = MCDRV_IRQTYPE_REF, + .key1_off_irq_type = MCDRV_IRQTYPE_REF, + .key2_off_irq_type = MCDRV_IRQTYPE_REF, + .det_in_inv = MCDRV_DET_IN_INV, + .hs_det_mode = MCDRV_HSDET_MODE_DETIN_A, + .speriod = MCDRV_SPERIOD_3906, + .dbnc_num_plug = MCDRV_DBNC_NUM_7, + .dbnc_num_mic = MCDRV_DBNC_NUM_7, + .dbnc_num_key = MCDRV_DBNC_NUM_7, + .sgnl_period = MCDRV_SGNLPERIOD_79, + .sgnl_num = MCDRV_SGNLNUM_4, + .sgnl_peak = MCDRV_SGNLPEAK_1182, +}; + +#define HSUNDETDBNC MCDRV_DETDBNC_55 +#define HSUNDETDBNCNUM MCDRV_DBNC_NUM_7 +#define MSDETMB4OFF 5000 + +static const struct mcdrv_hsdet_info hsdet_info_suspend = { + .en_plug_det = MCDRV_PLUGDET_DISABLE, + .en_plug_det_db = MCDRV_PLUGDETDB_BOTH_ENABLE, + .en_dly_key_off = MCDRV_KEYEN_D_D_D, + .en_dly_key_on = MCDRV_KEYEN_D_D_D, + .en_mic_det = MCDRV_MICDET_ENABLE, + .en_key_off = MCDRV_KEYEN_D_D_E, + .en_key_on = MCDRV_KEYEN_D_D_E, + .hs_det_dbnc = MCDRV_DETDBNC_219, + .key_off_mtim = MCDRV_KEYOFF_MTIM_63, + .key_on_mtim = MCDRV_KEYON_MTIM_63, + .key0_off_dly_tim = 8, + .key1_off_dly_tim = 8, + .key2_off_dly_tim = 8, + .key0_on_dly_tim = 8, + .key1_on_dly_tim = 8, + .key2_on_dly_tim = 8, + .irq_type = MCDRV_IRQTYPE_REF, + .plug_det_db_irq_type = MCDRV_IRQTYPE_REF, + .plug_undet_db_irq_type = MCDRV_IRQTYPE_REF, + .mic_det_irq_type = MCDRV_IRQTYPE_REF, + .plug_det_irq_type = MCDRV_IRQTYPE_REF, + .key0_on_irq_type = MCDRV_IRQTYPE_REF, + .key1_on_irq_type = MCDRV_IRQTYPE_REF, + .key2_on_irq_type = MCDRV_IRQTYPE_REF, + .key0_off_irq_type = MCDRV_IRQTYPE_REF, + .key1_off_irq_type = MCDRV_IRQTYPE_REF, + .key2_off_irq_type = MCDRV_IRQTYPE_REF, + .det_in_inv = MCDRV_DET_IN_INV, + .hs_det_mode = MCDRV_HSDET_MODE_DETIN_A, + .speriod = MCDRV_SPERIOD_3906, + .dbnc_num_plug = MCDRV_DBNC_NUM_7, + .dbnc_num_mic = MCDRV_DBNC_NUM_7, + .dbnc_num_key = MCDRV_DBNC_NUM_7, + .sgnl_period = MCDRV_SGNLPERIOD_79, + .sgnl_num = MCDRV_SGNLNUM_4, + .sgnl_peak = MCDRV_SGNLPEAK_1182, +}; + +#define MC_ASOC_EV_KEY_DELAYKEYON0 KEY_RESERVED +#define MC_ASOC_EV_KEY_DELAYKEYON1 KEY_RESERVED +#define MC_ASOC_EV_KEY_DELAYKEYON2 KEY_RESERVED + +static const unsigned int delay_key_off0[8] = { + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED +}; + +static const unsigned int delay_key_off1[8] = { + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED +}; + +static const unsigned int delay_key_off2[8] = { + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, + KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED +}; + +#define MC_ASOC_IMP_TBL_NUM 8 + +static const s16 hp_vol_imp_table[MC_ASOC_IMP_TBL_NUM]; + +static const s16 dac0_vol_imp_table[MC_ASOC_IMP_TBL_NUM] = { + 0, 0, 12, 18, 18, 24, 0, 0 +}; + +#endif /* _YMU831_CFG_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/ymu831_ctl.h | 944 ++++++++++++++++++++++++++++++++++ 1 file changed, 944 insertions(+) create mode 100644 sound/soc/codecs/ymu831/ymu831_ctl.h
diff --git a/sound/soc/codecs/ymu831/ymu831_ctl.h b/sound/soc/codecs/ymu831/ymu831_ctl.h new file mode 100644 index 0000000..edc0f21 --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831_ctl.h @@ -0,0 +1,944 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - split from ymu831.c + * - change in the Linux coding style + */ +#ifndef _YMU831_CTL_H +#define _YMU831_CTL_H + +#include <sound/soc.h> +#include <sound/tlv.h> + +static const DECLARE_TLV_DB_SCALE(mc_asoc_tlv_digital, -9600, 1800, 1); + +static unsigned int mc_asoc_tlv_ain[] = { + TLV_DB_RANGE_HEAD(4), + 0x00, 0x02, TLV_DB_SCALE_ITEM(-9600, 0, 1), + 0x03, 0x36, TLV_DB_SCALE_ITEM(-3000, 100, 0), + 0x37, 0x3B, TLV_DB_SCALE_ITEM(2150, 50, 0), + 0x3C, 0x3F, TLV_DB_SCALE_ITEM(2400, 200, 0), +}; + +static unsigned int mc_asoc_tlv_aout[] = { + TLV_DB_RANGE_HEAD(4), + 0x00, 0x2E, TLV_DB_SCALE_ITEM(-9600, 0, 1), + 0x2F, 0x43, TLV_DB_SCALE_ITEM(-3600, 100, 0), + 0x44, 0x57, TLV_DB_SCALE_ITEM(-1550, 50, 0), + 0x58, 0x6F, TLV_DB_SCALE_ITEM(-575, 25, 0), +}; + +static unsigned int mc_asoc_tlv_sp[] = { + TLV_DB_RANGE_HEAD(4), + 0x00, 0x2E, TLV_DB_SCALE_ITEM(-9600, 0, 1), + 0x2F, 0x43, TLV_DB_SCALE_ITEM(-3600, 100, 0), + 0x44, 0x57, TLV_DB_SCALE_ITEM(-1550, 50, 0), + 0x58, 0x6f, TLV_DB_SCALE_ITEM(-575, 25, 0), +}; + +static unsigned int mc_asoc_tlv_lout[] = { + TLV_DB_RANGE_HEAD(4), + 0x00, 0x2E, TLV_DB_SCALE_ITEM(-9600, 0, 1), + 0x2F, 0x43, TLV_DB_SCALE_ITEM(-3600, 100, 0), + 0x44, 0x57, TLV_DB_SCALE_ITEM(-1550, 50, 0), + 0x58, 0x77, TLV_DB_SCALE_ITEM(-575, 25, 0), +}; + +static unsigned int mc_asoc_tlv_hp[] = { + TLV_DB_RANGE_HEAD(4), + 0x00, 0x2F, TLV_DB_SCALE_ITEM(-9600, 0, 1), + 0x30, 0x43, TLV_DB_SCALE_ITEM(-3500, 100, 0), + 0x44, 0x57, TLV_DB_SCALE_ITEM(-1550, 50, 0), + 0x58, 0x7f, TLV_DB_SCALE_ITEM(-575, 25, 0), +}; + +static const DECLARE_TLV_DB_SCALE(mc_asoc_tlv_ext, -7500, 100, 1); + +/* SP Gain */ +static unsigned int mc_asoc_tlv_sp_gain[] = { + TLV_DB_RANGE_HEAD(1), + 0x00, 0x04, TLV_DB_SCALE_ITEM(1200, 100, 0) +}; + +/* Audio Mode */ +static const char * const audio_mode_play_param_text[] = { + "off", "audio", "incall", "audio+incall", "incommunication", "karaoke", + "incall2", "audio+incall2", "incommunication2" +}; + +static const struct soc_enum audio_mode_play_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_AUDIO_MODE_PLAY, 0, + ARRAY_SIZE(audio_mode_play_param_text) - 2, + audio_mode_play_param_text); + +static const char * const audio_mode_cap_param_text[] = { + "off", "audio", "incall", "audio+incall", "incommunication", "audioex", + "audiovr" +}; + +static const struct soc_enum audio_mode_cap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_AUDIO_MODE_CAP, 0, + ARRAY_SIZE(audio_mode_cap_param_text), + audio_mode_cap_param_text); + +/* Output Path */ +static const char * const output_path_param_text[] = { + "SP", "RC", "HP", "HS", "LO1", "LO2", "BT", + "SP+RC", "SP+HP", "SP+LO1", "SP+LO2", "SP+BT", + "LO1+RC", "LO1+HP", "LO1+BT", "LO2+RC", "LO2+HP", "LO2+BT", + "LO1+LO2", "LO2+LO1" +}; + +static const struct soc_enum output_path_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_OUTPUT_PATH, 0, + ARRAY_SIZE(output_path_param_text), + output_path_param_text); + +/* Input Path */ +static const char * const input_path_param_text[] = { + "MainMIC", "SubMIC", "2MIC", "Headset", "Bluetooth", + "VoiceCall", "VoiceUplink", "VoiceDownlink", "Linein1" +}; + +static const struct soc_enum input_path_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_INPUT_PATH, 0, + ARRAY_SIZE(input_path_param_text), + input_path_param_text); + +/* Incall Mic */ +static const char * const incall_mic_param_text[] = { + "MainMIC", "SubMIC", "2MIC" +}; + +static const struct soc_enum incall_mic_sp_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_INCALL_MIC_SP, 0, + ARRAY_SIZE(incall_mic_param_text), + incall_mic_param_text); + +static const struct soc_enum incall_mic_rc_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_INCALL_MIC_RC, 0, + ARRAY_SIZE(incall_mic_param_text), incall_mic_param_text); + +static const struct soc_enum incall_mic_hp_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_INCALL_MIC_HP, 0, + ARRAY_SIZE(incall_mic_param_text), incall_mic_param_text); + +static const struct soc_enum incall_mic_lo1_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_INCALL_MIC_LO1, 0, + ARRAY_SIZE(incall_mic_param_text), incall_mic_param_text); + +static const struct soc_enum incall_mic_lo2_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_INCALL_MIC_LO2, 0, + ARRAY_SIZE(incall_mic_param_text), incall_mic_param_text); + +/* Playback Path */ +static const char * const playback_path_sw_param_text[] = { + "OFF", "ON" +}; + +static const struct soc_enum mainmic_playback_path_sw_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MAINMIC_PLAYBACK_PATH, 0, + ARRAY_SIZE(playback_path_sw_param_text), + playback_path_sw_param_text); + +static const struct soc_enum submic_playback_path_sw_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_SUBMIC_PLAYBACK_PATH, 0, + ARRAY_SIZE(playback_path_sw_param_text), + playback_path_sw_param_text); + +static const struct soc_enum msmic_playback_path_sw_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_2MIC_PLAYBACK_PATH, 0, + ARRAY_SIZE(playback_path_sw_param_text), + playback_path_sw_param_text); + +static const struct soc_enum hsmic_playback_path_sw_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_HSMIC_PLAYBACK_PATH, 0, + ARRAY_SIZE(playback_path_sw_param_text), + playback_path_sw_param_text); + +static const struct soc_enum btmic_playback_path_sw_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_BTMIC_PLAYBACK_PATH, 0, + ARRAY_SIZE(playback_path_sw_param_text), + playback_path_sw_param_text); + +static const struct soc_enum lin1_playback_path_sw_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_LIN1_PLAYBACK_PATH, 0, + ARRAY_SIZE(playback_path_sw_param_text), + playback_path_sw_param_text); + +/* DTMF Control */ +static const char * const dtmf_control_param_text[] = { + "OFF", "ON" +}; + +static const struct soc_enum dtmf_control_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_DTMF_CONTROL, 0, + ARRAY_SIZE(dtmf_control_param_text), + dtmf_control_param_text); + +/* DTMF Output */ +static const char * const dtmf_output_param_text[] = { + "SP", "NORMAL" +}; + +static const struct soc_enum dtmf_output_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_DTMF_OUTPUT, 0, + ARRAY_SIZE(dtmf_output_param_text), + dtmf_output_param_text); + +/* Switch Clock */ +static const char * const switch_clock_param_text[] = { + "CLKA", "CLKB" +}; + +static const struct soc_enum switch_clock_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_SWITCH_CLOCK, 0, + ARRAY_SIZE(switch_clock_param_text), + switch_clock_param_text); + +/* Ext MasterSlave */ +static const char * const ext_masterslave_param_text[] = { + "Slave", "Master" +}; + +static const struct soc_enum ext_masterslave_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_MASTERSLAVE, 0, + ARRAY_SIZE(ext_masterslave_param_text), + ext_masterslave_param_text); + +/* Ext Rate */ +static const char * const ext_rate_param_text[] = { + "48kHz", "44.1kHz", "32kHz", "", "24kHz", "22.05kHz", "16kHz", "", + "12kHz", "11.025kHz", "8kHz" +}; + +static const struct soc_enum ext_rate_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_RATE, 0, + ARRAY_SIZE(ext_rate_param_text), + ext_rate_param_text); + +/* Ext Bitclock Rate */ +static const char * const ext_bck_rate_param_text[] = { + "64fs", "48fs", "32fs", "", "512fs", "256fs", "192fs", "128fs", + "96fs", "24fs", "16fs", "8fs", "", "", "", "Slave" +}; + +static const struct soc_enum ext_bck_rate_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_BITCLOCK_RATE, 0, + ARRAY_SIZE(ext_bck_rate_param_text), + ext_bck_rate_param_text); + +/* Ext Interface */ +static const char * const ext_interface_param_text[] = { + "DA", "PCM" +}; + +static const struct soc_enum ext_interface_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INTERFACE, 0, + ARRAY_SIZE(ext_interface_param_text), + ext_interface_param_text); + +/* Ext Bitclock Invert */ +static const char * const ext_bck_invert_param_text[] = { + "Normal", "Invert" +}; + +static const struct soc_enum ext_bck_invert_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_BITCLOCK_INVERT, 0, + ARRAY_SIZE(ext_bck_invert_param_text), + ext_bck_invert_param_text); + +/* Ext DA Bit Width */ +static const char * const ext_bit_width_param_text[] = { + "16bit", "20bit", "24bit" +}; + +static const struct soc_enum ext_input_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INPUT_DA_BIT_WIDTH, 0, + ARRAY_SIZE(ext_bit_width_param_text), + ext_bit_width_param_text); + +static const struct soc_enum ext_output_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUTPUT_DA_BIT_WIDTH, 0, + ARRAY_SIZE(ext_bit_width_param_text), + ext_bit_width_param_text); + +/* Ext DA Format */ +static const char * const ext_da_format_param_text[] = { + "HeadAlign", "I2S", "TailAlign" +}; + +static const struct soc_enum ext_input_da_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INPUT_DA_FORMAT, 0, + ARRAY_SIZE(ext_da_format_param_text), + ext_da_format_param_text); + +static const struct soc_enum ext_output_da_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUTPUT_DA_FORMAT, 0, + ARRAY_SIZE(ext_da_format_param_text), + ext_da_format_param_text); + +/* Ext Pcm MonoStereo */ +static const char * const ext_pcm_mono_param_text[] = { + "Stereo", "Mono" +}; + +static const struct soc_enum ext_input_pcm_mono_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INPUT_PCM_MONOSTEREO, 0, + ARRAY_SIZE(ext_pcm_mono_param_text), ext_pcm_mono_param_text); + +static const struct soc_enum ext_output_pcm_mono_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUTPUT_PCM_MONOSTEREO, 0, + ARRAY_SIZE(ext_pcm_mono_param_text), ext_pcm_mono_param_text); + +/* Ext Pcm Bit Order */ +static const char * const ext_pcm_bit_order_param_text[] = { + "MSB", "LSB" +}; + +static const struct soc_enum ext_input_pcm_bit_order_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INPUT_PCM_BIT_ORDER, 0, + ARRAY_SIZE(ext_pcm_bit_order_param_text), + ext_pcm_bit_order_param_text); +static const struct soc_enum ext_output_pcm_bit_order_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUTPUT_PCM_BIT_ORDER, 0, + ARRAY_SIZE(ext_pcm_bit_order_param_text), + ext_pcm_bit_order_param_text); + +/* Ext Pcm Format */ +static const char * const ext_pcm_format_param_text[] = { + "Linear", "Alaw", "Mulaw" +}; + +static const struct soc_enum ext_input_pcm_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INPUT_PCM_FORMAT, 0, + ARRAY_SIZE(ext_pcm_format_param_text), + ext_pcm_format_param_text); + +static const struct soc_enum ext_output_pcm_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUTPUT_PCM_FORMAT, 0, + ARRAY_SIZE(ext_pcm_format_param_text), + ext_pcm_format_param_text); + +/* Ext PCM Bit Width */ +static const char * const ext_pcm_bit_width_param_text[] = { + "8bit", "16bit", "24bit" +}; + +static const struct soc_enum ext_input_pcm_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_INPUT_PCM_BIT_WIDTH, 0, + ARRAY_SIZE(ext_pcm_bit_width_param_text), + ext_pcm_bit_width_param_text); + +static const struct soc_enum ext_output_pcm_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUTPUT_PCM_BIT_WIDTH, 0, + ARRAY_SIZE(ext_pcm_bit_width_param_text), + ext_pcm_bit_width_param_text); + +/* Voice MasterSlave */ +static const char * const voice_masterslave_param_text[] = { + "Slave", "Master" +}; + +static const struct soc_enum voice_masterslave_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_MASTERSLAVE, 0, + ARRAY_SIZE(voice_masterslave_param_text), + voice_masterslave_param_text); + +/* Voice Rate */ +static const char * const voice_rate_param_text[] = { + "48kHz", "44.1kHz", "32kHz", "", "24kHz", "22.05kHz", "16kHz", "", + "12kHz", "11.025kHz", "8kHz", "", "192kHz", "96kHz" +}; + +static const struct soc_enum voice_rate_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_RATE, 0, + ARRAY_SIZE(voice_rate_param_text), voice_rate_param_text); + +/* Voice Bitclock Rate */ +static const char * const voice_bck_rate_param_text[] = { + "64fs", "48fs", "32fs", "", "512fs", "256fs", "192fs", "128fs", + "96fs", "24fs", "16fs", "8fs", "", "", "", "Slave" +}; + +static const struct soc_enum voice_bck_rate_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_BITCLOCK_RATE, 0, + ARRAY_SIZE(voice_bck_rate_param_text), + voice_bck_rate_param_text); + +/* Voice Interface */ +static const char * const voice_interface_param_text[] = { + "DA", "PCM" +}; + +static const struct soc_enum voice_interface_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INTERFACE, 0, + ARRAY_SIZE(voice_interface_param_text), + voice_interface_param_text); + +/* Voice Bitclock Invert */ +static const char * const voice_bck_invert_param_text[] = { + "Normal", "Invert" +}; + +static const struct soc_enum voice_bck_invert_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_BITCLOCK_INVERT, 0, + ARRAY_SIZE(voice_bck_invert_param_text), + voice_bck_invert_param_text); + +/* Voice DA Bit Width */ +static const char * const voice_input_bit_width_param_text[] = { + "16bit", "20bit", "24bit" +}; + +static const struct soc_enum voice_input_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INPUT_DA_BIT_WIDTH, 0, + ARRAY_SIZE(voice_input_bit_width_param_text), + voice_input_bit_width_param_text); + +static const char * const voice_output_bit_width_param_text[] = { + "16bit", "20bit", "24bit", "32bit" +}; + +static const struct soc_enum voice_output_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUTPUT_DA_BIT_WIDTH, 0, + ARRAY_SIZE(voice_output_bit_width_param_text), + voice_output_bit_width_param_text); + +/* Voice DA Format */ +static const char * const voice_da_format_param_text[] = { + "HeadAlign", "I2S", "TailAlign" +}; + +static const struct soc_enum voice_input_da_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INPUT_DA_FORMAT, 0, + ARRAY_SIZE(voice_da_format_param_text), + voice_da_format_param_text); + +static const struct soc_enum voice_output_da_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUTPUT_DA_FORMAT, 0, + ARRAY_SIZE(voice_da_format_param_text), + voice_da_format_param_text); + +/* Voice Pcm MonoStereo */ +static const char * const voice_pcm_mono_param_text[] = { + "Stereo", "Mono" +}; + +static const struct soc_enum voice_input_pcm_mono_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INPUT_PCM_MONOSTEREO, 0, + ARRAY_SIZE(voice_pcm_mono_param_text), + voice_pcm_mono_param_text); + +static const struct soc_enum voice_output_pcm_mono_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUTPUT_PCM_MONOSTEREO, 0, + ARRAY_SIZE(voice_pcm_mono_param_text), + voice_pcm_mono_param_text); + +/* Voice Pcm Bit Order */ +static const char * const voice_pcm_bit_order_param_text[] = { + "MSB", "LSB" +}; + +static const struct soc_enum voice_input_pcm_bit_order_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INPUT_PCM_BIT_ORDER, 0, + ARRAY_SIZE(voice_pcm_bit_order_param_text), + voice_pcm_bit_order_param_text); + +static const struct soc_enum voice_output_pcm_bit_order_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUTPUT_PCM_BIT_ORDER, 0, + ARRAY_SIZE(voice_pcm_bit_order_param_text), + voice_pcm_bit_order_param_text); + +/* Voice Pcm Format */ +static const char * const voice_pcm_format_param_text[] = { + "Linear", "Alaw", "Mulaw" +}; + +static const struct soc_enum voice_input_pcm_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INPUT_PCM_FORMAT, 0, + ARRAY_SIZE(voice_pcm_format_param_text), + voice_pcm_format_param_text); + +static const struct soc_enum voice_output_pcm_format_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUTPUT_PCM_FORMAT, 0, + ARRAY_SIZE(voice_pcm_format_param_text), + voice_pcm_format_param_text); + +/* Voice PCM Bit Width */ +static const char * const voice_pcm_bit_width_param_text[] = { + "8bit", "16bit", "24bit" +}; + +static const struct soc_enum voice_input_pcm_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_INPUT_PCM_BIT_WIDTH, 0, + ARRAY_SIZE(voice_pcm_bit_width_param_text), + voice_pcm_bit_width_param_text); + +static const struct soc_enum voice_output_pcm_bit_width_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUTPUT_PCM_BIT_WIDTH, 0, + ARRAY_SIZE(voice_pcm_bit_width_param_text), + voice_pcm_bit_width_param_text); + +/* Music Physical Port */ +static const char * const phy_port_param_text[] = { + "DIO0", "DIO1", "DIO2", "NONE", "SLIM0", "SLIM1", "SLIM2" +}; + +static const struct soc_enum music_phy_port_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_PHYSICAL_PORT, 0, + ARRAY_SIZE(phy_port_param_text), + phy_port_param_text); + +/* Ext Physical Port */ +static const struct soc_enum ext_phy_port_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_PHYSICAL_PORT, 0, + ARRAY_SIZE(phy_port_param_text), + phy_port_param_text); + +/* Voice Physical Port */ +static const struct soc_enum voice_phy_port_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_PHYSICAL_PORT, 0, + ARRAY_SIZE(phy_port_param_text), + phy_port_param_text); + +/* Hifi Physical Port */ +static const struct soc_enum hifi_phy_port_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_HIFI_PHYSICAL_PORT, 0, + ARRAY_SIZE(phy_port_param_text), + phy_port_param_text); + +/* Adif0 Swap */ +static const char * const swap_param_text[] = { + "Normal", "Swap", "Mute", "Center", "Mix", "MonoMix", "BothL", "BothR" +}; + +static const struct soc_enum adif0_swap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_ADIF0_SWAP, 0, + ARRAY_SIZE(swap_param_text), + swap_param_text); + +/* Adif1 Swap */ +static const struct soc_enum adif1_swap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_ADIF1_SWAP, 0, + ARRAY_SIZE(swap_param_text), + swap_param_text); + +/* Adif2 Swap */ +static const struct soc_enum adif2_swap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_ADIF2_SWAP, 0, + ARRAY_SIZE(swap_param_text), + swap_param_text); + +/* Dac0 Swap */ +static const struct soc_enum dac0_swap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_DAC0_SWAP, 0, + ARRAY_SIZE(swap_param_text), + swap_param_text); + +/* Dac1 Swap */ +static const struct soc_enum dac1_swap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_DAC1_SWAP, 0, + ARRAY_SIZE(swap_param_text), + swap_param_text); + +/* Music Out0 Swap */ +static const struct soc_enum music_out0_swap_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_OUT0_SWAP, 0, + ARRAY_SIZE(swap_param_text), + swap_param_text); + +/* Music In0 Swap */ +static const char * const swap2_param_text[] = { + "Normal", "Both1", "Both0", "Swap" +}; + +static const struct soc_enum music_in0_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_IN0_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Music In1 Swap */ +static const struct soc_enum music_in1_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_IN1_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Music In2 Swap */ +static const struct soc_enum music_in2_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_IN2_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Ext In Swap */ +static const struct soc_enum ext_in_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_IN_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Voice In Swap */ +static const struct soc_enum voice_in_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_IN_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Music Out1 Swap */ +static const struct soc_enum music_out1_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_OUT1_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Music Out2 Swap */ +static const struct soc_enum music_out2_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MUSIC_OUT2_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Ext Out Swap */ +static const struct soc_enum ext_out_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_EXT_OUT_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Voice Out Swap */ +static const struct soc_enum voice_out_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_VOICE_OUT_SWAP, 0, + ARRAY_SIZE(swap2_param_text), + swap2_param_text); + +/* Adif Source */ +static const char * const adif_src_param_text[] = { + "ymu831_path_cfg.h", "ADC0L", "ADC0R", "ADC1", + "PDM0L", "PDM0R", "PDM1L", "PDM1R", "DAC0REF", "DAC1REF" +}; + +static const struct soc_enum adif_src[] = { + SOC_ENUM_DOUBLE(MC_ASOC_ADIF0_SOURCE, 0, 8, 8, adif_src_param_text), + SOC_ENUM_DOUBLE(MC_ASOC_ADIF1_SOURCE, 0, 8, 8, adif_src_param_text), + SOC_ENUM_DOUBLE(MC_ASOC_ADIF2_SOURCE, 0, 8, 10, adif_src_param_text) +}; + +/* Parameter Setting */ +static const char * const parameter_setting_param_text[] = { + "DUMMY" +}; + +static const struct soc_enum parameter_setting_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_PARAMETER_SETTING, 0, + ARRAY_SIZE(parameter_setting_param_text), + parameter_setting_param_text); + +static const char * const mic_param_text[] = { + "NONE", "MIC1", "MIC2", "MIC3", "MIC4", "PDM0", "PDM1" +}; + +/* Main Mic */ +static const struct soc_enum main_mic_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MAIN_MIC, 0, ARRAY_SIZE(mic_param_text), + mic_param_text); + +/* Sub Mic */ +static const struct soc_enum sub_mic_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_SUB_MIC, 0, ARRAY_SIZE(mic_param_text), + mic_param_text); + +/* Headset Mic */ +static const struct soc_enum hs_mic_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_HS_MIC, 0, ARRAY_SIZE(mic_param_text), + mic_param_text); + +#ifdef MC_ASOC_TEST +/* MICx_BIAS */ +static const char * const mic_bias_param_text[] = { + "OFF", "ALWAYS_ON", "SYNC_MIC" +}; + +static const struct soc_enum mic1_bias_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MIC1_BIAS, 0, ARRAY_SIZE(mic_bias_param_text), + mic_bias_param_text); + +static const struct soc_enum mic2_bias_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MIC2_BIAS, 0, ARRAY_SIZE(mic_bias_param_text), + mic_bias_param_text); + +static const struct soc_enum mic3_bias_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MIC3_BIAS, 0, ARRAY_SIZE(mic_bias_param_text), + mic_bias_param_text); + +static const struct soc_enum mic4_bias_param_enum = +SOC_ENUM_SINGLE(MC_ASOC_MIC4_BIAS, 0, ARRAY_SIZE(mic_bias_param_text), + mic_bias_param_text); +#endif /* MC_ASOC_TEST */ + +static const struct snd_kcontrol_new mc_asoc_snd_controls[] = { + SOC_DOUBLE_TLV("Music Input Volume", + MC_ASOC_DVOL_MUSICIN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Music Input Switch", + MC_ASOC_DVOL_MUSICIN, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Ext Input Volume", + MC_ASOC_DVOL_EXTIN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Ext Input Switch", + MC_ASOC_DVOL_EXTIN, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Voice Input Volume", + MC_ASOC_DVOL_VOICEIN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Voice Input Switch", + MC_ASOC_DVOL_VOICEIN, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Ref Input Volume", + MC_ASOC_DVOL_REFIN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Ref Input Switch", + MC_ASOC_DVOL_REFIN, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Adif0 Input Volume", + MC_ASOC_DVOL_ADIF0IN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Adif0 Input Switch", + MC_ASOC_DVOL_ADIF0IN, 7, 15, 1, 0), + SOC_DOUBLE_TLV("Adif1 Input Volume", + MC_ASOC_DVOL_ADIF1IN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Adif1 Input Switch", + MC_ASOC_DVOL_ADIF1IN, 7, 15, 1, 0), + SOC_DOUBLE_TLV("Adif2 Input Volume", + MC_ASOC_DVOL_ADIF2IN, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Adif2 Input Switch", + MC_ASOC_DVOL_ADIF2IN, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Music Output Volume", + MC_ASOC_DVOL_MUSICOUT, 0, 8, 114, 0, + mc_asoc_tlv_digital), + SOC_DOUBLE("Music Output Switch", + MC_ASOC_DVOL_MUSICOUT, 7, 15, 1, 0), + SOC_DOUBLE_TLV("Ext Output Volume", + MC_ASOC_DVOL_EXTOUT, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Ext Output Switch", + MC_ASOC_DVOL_EXTOUT, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Voice Output Volume", + MC_ASOC_DVOL_VOICEOUT, 0, 8, 114, 0, + mc_asoc_tlv_digital), + SOC_DOUBLE("Voice Output Switch", + MC_ASOC_DVOL_VOICEOUT, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Ref Output Volume", + MC_ASOC_DVOL_REFOUT, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Ref Output Switch", + MC_ASOC_DVOL_REFOUT, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Dac0 Output Volume", + MC_ASOC_DVOL_DAC0OUT, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Dac0 Output Switch", + MC_ASOC_DVOL_DAC0OUT, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Dac1 Output Volume", + MC_ASOC_DVOL_DAC1OUT, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Dac1 Output Switch", + MC_ASOC_DVOL_DAC1OUT, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Dpath Da Volume", + MC_ASOC_DVOL_DPATHDA, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Dpath Da Switch", + MC_ASOC_DVOL_DPATHDA, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Dpath Ad Volume", + MC_ASOC_DVOL_DPATHAD, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("Dpath Ad Switch", + MC_ASOC_DVOL_DPATHAD, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("LineIn1 Volume", + MC_ASOC_AVOL_LINEIN1, 0, 8, 63, 0, mc_asoc_tlv_ain), + SOC_DOUBLE("LineIn1 Switch", + MC_ASOC_AVOL_LINEIN1, 7, 15, 1, 0), + + SOC_SINGLE_TLV("Mic1 Volume", + MC_ASOC_AVOL_MIC1, 0, 63, 0, mc_asoc_tlv_ain), + SOC_SINGLE("Mic1 Switch", + MC_ASOC_AVOL_MIC1, 7, 1, 0), + + SOC_SINGLE_TLV("Mic2 Volume", + MC_ASOC_AVOL_MIC2, 0, 63, 0, mc_asoc_tlv_ain), + SOC_SINGLE("Mic2 Switch", + MC_ASOC_AVOL_MIC2, 7, 1, 0), + + SOC_SINGLE_TLV("Mic3 Volume", + MC_ASOC_AVOL_MIC3, 0, 63, 0, mc_asoc_tlv_ain), + SOC_SINGLE("Mic3 Switch", + MC_ASOC_AVOL_MIC3, 7, 1, 0), + + SOC_SINGLE_TLV("Mic4 Volume", + MC_ASOC_AVOL_MIC4, 0, 63, 0, mc_asoc_tlv_ain), + SOC_SINGLE("Mic4 Switch", + MC_ASOC_AVOL_MIC4, 7, 1, 0), + + SOC_DOUBLE_TLV("Headphone Volume", + MC_ASOC_AVOL_HP, 0, 8, 127, 0, mc_asoc_tlv_hp), + SOC_DOUBLE("Headphone Switch", + MC_ASOC_AVOL_HP, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Speaker Volume", + MC_ASOC_AVOL_SP, 0, 8, 127, 0, mc_asoc_tlv_sp), + SOC_DOUBLE("Speaker Switch", + MC_ASOC_AVOL_SP, 7, 15, 1, 0), + + SOC_SINGLE_TLV("Receiver Volume", + MC_ASOC_AVOL_RC, 0, 111, 0, mc_asoc_tlv_aout), + SOC_SINGLE("Receiver Switch", + MC_ASOC_AVOL_RC, 7, 1, 0), + + SOC_DOUBLE_TLV("LineOut1 Volume", + MC_ASOC_AVOL_LINEOUT1, 0, 8, 119, 0, mc_asoc_tlv_lout), + SOC_DOUBLE("LineOut1 Switch", + MC_ASOC_AVOL_LINEOUT1, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("LineOut2 Volume", + MC_ASOC_AVOL_LINEOUT2, 0, 8, 119, 0, mc_asoc_tlv_lout), + SOC_DOUBLE("LineOut2 Switch", + MC_ASOC_AVOL_LINEOUT2, 7, 15, 1, 0), + + SOC_SINGLE_TLV("SP Gain", + MC_ASOC_AVOL_SP_GAIN, 0, 4, 0, mc_asoc_tlv_sp_gain), + + SOC_DOUBLE_TLV("Master Playback Volume", + MC_ASOC_DVOL_MASTER, 0, 8, 75, 0, mc_asoc_tlv_ext), + SOC_DOUBLE("Master Playback Switch", + MC_ASOC_DVOL_MASTER, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("Voice Playback Volume", + MC_ASOC_DVOL_VOICE, 0, 8, 75, 0, mc_asoc_tlv_ext), + SOC_DOUBLE("Voice Playback Switch", + MC_ASOC_DVOL_VOICE, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("AnalogIn Playback Analog Volume", + MC_ASOC_DVOL_APLAY_A, 0, 8, 63, 0, mc_asoc_tlv_ain), + SOC_DOUBLE("AnalogIn Playback Analog Switch", + MC_ASOC_DVOL_APLAY_A, 7, 15, 1, 0), + + SOC_DOUBLE_TLV("AnalogIn Playback Digital Volume", + MC_ASOC_DVOL_APLAY_D, 0, 8, 114, 0, mc_asoc_tlv_digital), + SOC_DOUBLE("AnalogIn Playback Digital Switch", + MC_ASOC_DVOL_APLAY_D, 7, 15, 1, 0), + + SOC_SINGLE("Voice Recording Switch", + MC_ASOC_VOICE_RECORDING, 0, 1, 0), + + SOC_ENUM("Audio Mode Playback", audio_mode_play_param_enum), + SOC_ENUM("Audio Mode Capture", audio_mode_cap_param_enum), + SOC_ENUM("Output Path", output_path_param_enum), + SOC_ENUM("Input Path", input_path_param_enum), + SOC_ENUM("Incall Mic Speaker", incall_mic_sp_param_enum), + SOC_ENUM("Incall Mic Receiver", incall_mic_rc_param_enum), + SOC_ENUM("Incall Mic Headphone", incall_mic_hp_param_enum), + SOC_ENUM("Incall Mic LineOut1", incall_mic_lo1_param_enum), + SOC_ENUM("Incall Mic LineOut2", incall_mic_lo2_param_enum), + SOC_ENUM("MainMIC Playback Path", + mainmic_playback_path_sw_param_enum), + SOC_ENUM("SubMIC Playback Path", submic_playback_path_sw_param_enum), + SOC_ENUM("2MIC Playback Path", msmic_playback_path_sw_param_enum), + SOC_ENUM("HeadsetMIC Playback Path", + hsmic_playback_path_sw_param_enum), + SOC_ENUM("BluetoothMIC Playback Path", + btmic_playback_path_sw_param_enum), + SOC_ENUM("LIN 1 Playback Path", lin1_playback_path_sw_param_enum), + SOC_ENUM("DTMF Control", dtmf_control_param_enum), + SOC_ENUM("DTMF Output", dtmf_output_param_enum), + SOC_ENUM("Switch Clock", switch_clock_param_enum), + SOC_ENUM("Ext MasterSlave", ext_masterslave_param_enum), + SOC_ENUM("Ext Rate", ext_rate_param_enum), + SOC_ENUM("Ext Bitclock Rate", ext_bck_rate_param_enum), + SOC_ENUM("Ext Interface", ext_interface_param_enum), + SOC_ENUM("Ext Bitclock Invert", ext_bck_invert_param_enum), + SOC_ENUM("Ext Input DA Bit Width", ext_input_bit_width_param_enum), + SOC_ENUM("Ext Output DA Bit Width", + ext_output_bit_width_param_enum), + SOC_ENUM("Ext Input DA Format", ext_input_da_format_param_enum), + SOC_ENUM("Ext Output DA Format", ext_output_da_format_param_enum), + SOC_ENUM("Ext Input Pcm MonoStereo", ext_input_pcm_mono_param_enum), + SOC_ENUM("Ext Output Pcm MonoStereo", ext_output_pcm_mono_param_enum), + SOC_ENUM("Ext Input Pcm Bit Order", ext_input_pcm_bit_order_param_enum), + SOC_ENUM("Ext Output Pcm Bit Order", + ext_output_pcm_bit_order_param_enum), + SOC_ENUM("Ext Input Pcm Format", ext_input_pcm_format_param_enum), + SOC_ENUM("Ext Output Pcm Format", ext_output_pcm_format_param_enum), + SOC_ENUM("Ext Input PCM Bit Width", ext_input_pcm_bit_width_param_enum), + SOC_ENUM("Ext Output PCM Bit Width", + ext_output_pcm_bit_width_param_enum), + SOC_ENUM("Voice MasterSlave", voice_masterslave_param_enum), + SOC_ENUM("Voice Rate", voice_rate_param_enum), + SOC_ENUM("Voice Bitclock Rate", voice_bck_rate_param_enum), + SOC_ENUM("Voice Interface", voice_interface_param_enum), + SOC_ENUM("Voice Bitclock Invert", voice_bck_invert_param_enum), + SOC_ENUM("Voice Input DA Bit Width", + voice_input_bit_width_param_enum), + SOC_ENUM("Voice Output DA Bit Width", + voice_output_bit_width_param_enum), + SOC_ENUM("Voice Input DA Format", voice_input_da_format_param_enum), + SOC_ENUM("Voice Output DA Format", voice_output_da_format_param_enum), + SOC_ENUM("Voice Input Pcm MonoStereo", voice_input_pcm_mono_param_enum), + SOC_ENUM("Voice Output Pcm MonoStereo", + voice_output_pcm_mono_param_enum), + SOC_ENUM("Voice Input Pcm Bit Order", + voice_input_pcm_bit_order_param_enum), + SOC_ENUM("Voice Output Pcm Bit Order", + voice_output_pcm_bit_order_param_enum), + SOC_ENUM("Voice Input Pcm Format", voice_input_pcm_format_param_enum), + SOC_ENUM("Voice Output Pcm Format", voice_output_pcm_format_param_enum), + SOC_ENUM("Voice Input PCM Bit Width", + voice_input_pcm_bit_width_param_enum), + SOC_ENUM("Voice Output PCM Bit Width", + voice_output_pcm_bit_width_param_enum), + SOC_ENUM("Music Physical Port", music_phy_port_param_enum), + SOC_ENUM("Ext Physical Port", ext_phy_port_param_enum), + SOC_ENUM("Voice Physical Port", voice_phy_port_param_enum), + SOC_ENUM("Hifi Physical Port", hifi_phy_port_param_enum), + SOC_ENUM("Adif0 Swap", adif0_swap_param_enum), + SOC_ENUM("Adif1 Swap", adif1_swap_param_enum), + SOC_ENUM("Adif2 Swap", adif2_swap_param_enum), + SOC_ENUM("Dac0 Swap", dac0_swap_param_enum), + SOC_ENUM("Dac1 Swap", dac1_swap_param_enum), + SOC_ENUM("Music Out0 Swap", music_out0_swap_param_enum), + SOC_ENUM("Music In0 Swap", music_in0_param_enum), + SOC_ENUM("Music In1 Swap", music_in1_param_enum), + SOC_ENUM("Music In2 Swap", music_in2_param_enum), + SOC_ENUM("Ext In Swap", ext_in_param_enum), + SOC_ENUM("Voice In Swap", voice_in_param_enum), + SOC_ENUM("Music Out1 Swap", music_out1_param_enum), + SOC_ENUM("Music Out2 Swap", music_out2_param_enum), + SOC_ENUM("Ext Out Swap", ext_out_param_enum), + SOC_ENUM("Voice Out Swap", voice_out_param_enum), + + SOC_ENUM("ADIF0 Source", adif_src[0]), + SOC_ENUM("ADIF1 Source", adif_src[1]), + SOC_ENUM("ADIF2 Source", adif_src[2]), + SOC_ENUM("Parameter Setting", parameter_setting_param_enum), + SOC_ENUM("Main Mic", main_mic_param_enum), + SOC_ENUM("Sub Mic", sub_mic_param_enum), + SOC_ENUM("Headset Mic", hs_mic_param_enum), +#ifdef MC_ASOC_TEST + SOC_ENUM("MIC1 BIAS", mic1_bias_param_enum), + SOC_ENUM("MIC2 BIAS", mic2_bias_param_enum), + SOC_ENUM("MIC3 BIAS", mic3_bias_param_enum), + SOC_ENUM("MIC4 BIAS", mic4_bias_param_enum), +#endif /* MC_ASOC_TEST */ +}; + +#endif /* _YMU831_CTL_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/ymu831_path_cfg.h | 1024 +++++++++++++++++++++++++++++ 1 file changed, 1024 insertions(+) create mode 100644 sound/soc/codecs/ymu831/ymu831_path_cfg.h
diff --git a/sound/soc/codecs/ymu831/ymu831_path_cfg.h b/sound/soc/codecs/ymu831/ymu831_path_cfg.h new file mode 100644 index 0000000..e533ebc --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831_path_cfg.h @@ -0,0 +1,1024 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _YMU831_PATH_CFG_H +#define _YMU831_PATH_CFG_H + +#include "mcdriver.h" + +#define PRESET_PATH_N 65 + +static const struct mcdrv_path_info mc_preset_path_info[PRESET_PATH_N] = { + /* playback:off, capture:off */ + { + .music_out = {0x00aaaaaa, 0x00aaaaaa}, + .ext_out = {0x00aaaaaa, 0x00aaaaaa}, + .hifi_out = {0x00aaaaaa}, + .vbox_mix_in = {0x00aaaaaa, 0x00aaaaaa, 0x00aaaaaa, 0x00aaaaaa}, + .ae0 = {0x00aaaaaa, 0x00aaaaaa}, + .ae1 = {0x00aaaaaa, 0x00aaaaaa}, + .ae2 = {0x00aaaaaa, 0x00aaaaaa}, + .ae3 = {0x00aaaaaa, 0x00aaaaaa}, + .dac0 = {0x00aaaaaa, 0x00aaaaaa}, + .dac1 = {0x00aaaaaa, 0x00aaaaaa}, + .voice_out = {0x00aaaaaa}, + .vbox_io_in = {0x00aaaaaa}, + .vbox_host_in = {0x00aaaaaa}, + .host_out = {0x00aaaaaa}, + .adif0 = {0x00aaaaaa, 0x00aaaaaa}, + .adif1 = {0x00aaaaaa, 0x00aaaaaa}, + .adif2 = {0x00aaaaaa, 0x00aaaaaa}, + .adc0 = {0x002aaaaa, 0x002aaaaa}, + .adc1 = {0x002aaaaa}, + .sp = {0x002aaaaa, 0x002aaaaa}, + .hp = {0x002aaaaa, 0x002aaaaa}, + .rc = {0x002aaaaa}, + .lout1 = {0x002aaaaa, 0x002aaaaa}, + .lout2 = {0x002aaaaa, 0x002aaaaa}, + .bias = {0x002aaaaa, 0x002aaaaa, 0x002aaaaa, 0x002aaaaa}, + }, + /* playback:audio, capture:off (analog output) */ + { + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:off (BT output) */ + { + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + }, + /* playback:audio, capture:off (analog+BT output) */ + { + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:off, capture:audio (analog input) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {(MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON), + (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON)}, + }, + /* playback:off, capture:audio (BT input) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + }, + /* playback:audio, capture:audio (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {(MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON), + (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audio (BT input, analog output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audio (analog input, BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {(MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON), + (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON)}, + }, + /* playback:audio, capture:audio (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + }, + /* playback:audio, capture:audio (analog input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {(MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON), + (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audio (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall, capture:incall (analog input, analog output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall, capture:incall (BT input, BT output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:incall, capture:incall (BT input, analog+BT output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall, capture:incall (analog input analog output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .dac1 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall, capture:incall (BT input BT output) */ + { + .ext_out = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:audio+incall, capture:incall (BT input analog+BT output) */ + { + .ext_out = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .dac1 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall, capture:audio+incall + (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall, capture:audio+incall (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON)}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:incall, capture:audio+incall (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON)}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall, capture:audio+incall + (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .dac1 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON)}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {(MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON), + (MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON)}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall, capture:audio+incall (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:audio+incall, capture:audio+incall + (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* incommunication (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* incommunication (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, + MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* incommunication (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .dac1 = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio (HiFi), capture:off */ + { + .dac0 = {MCDRV_D1SRC_HIFIIN_ON, MCDRV_D1SRC_HIFIIN_ON}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + }, + /* playback:off, capture:audio (HiFi) */ + { + .hifi_out = {MCDRV_D1SRC_ADIF0_ON}, + .adif0 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON, + MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON}, + }, + /* playback:audio (HiFi), capture:audio (HiFi) */ + { + .hifi_out = {MCDRV_D1SRC_ADIF0_ON}, + .dac0 = {MCDRV_D1SRC_HIFIIN_ON, MCDRV_D1SRC_HIFIIN_ON}, + .adif0 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON, + MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + }, + /* playback:off, capture:audioex (analog input) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON,}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON, + MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON}, + }, + /* playback:off, capture:audioex (BT input) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON,}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:audio, capture:audioex (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON,}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON, + MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audioex (BT input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON,}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audioex (analog input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON,}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON, + MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON}, + }, + /* playback:audio, capture:audioex (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON,}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:audio, capture:audioex (analog input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON,}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON, + MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audioex (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON,}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:off, capture:audiovr (analog input) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae1 = {MCDRV_D1SRC_ADIF0_ON, MCDRV_D1SRC_ADIF0_ON}, + .adif0 = {MCDRV_D2SRC_ADC1_ON, MCDRV_D2SRC_ADC1_ON}, + .adc1 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_M_ON}, + }, + /* playback:off, capture:audiovr (BT input) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + }, + /* playback:audio, capture:audiovr (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF0_ON, MCDRV_D1SRC_ADIF0_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .adif0 = {MCDRV_D2SRC_ADC1_ON, MCDRV_D2SRC_ADC1_ON}, + .adc1 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_M_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audiovr (BT input, analog output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audiovr (analog input, BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF0_ON, MCDRV_D1SRC_ADIF0_ON}, + .adif0 = {MCDRV_D2SRC_ADC1_ON, MCDRV_D2SRC_ADC1_ON}, + .adc1 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_M_ON}, + }, + /* playback:audio, capture:audiovr (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + }, + /* playback:audio, capture:audiovr (analog input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF0_ON, MCDRV_D1SRC_ADIF0_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .adif0 = {MCDRV_D2SRC_ADC1_ON, MCDRV_D2SRC_ADC1_ON}, + .adc1 = {MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_M_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio, capture:audiovr (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:karaoke, capture:off (analog input) */ + { + .vbox_mix_in = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON, + MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .ae0 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON)}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {(MCDRV_ASRC_MIC_ALL_ON & ~MCDRV_ASRC_MIC3_ON), + (MCDRV_ASRC_MIC_ALL_ON & ~MCDRV_ASRC_MIC3_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:karaoke, capture:off (BT input) */ + { + .vbox_mix_in = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON, + MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae0 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON)}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:karaoke, capture:audio (analog input) */ + { + .music_out = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON)}, + .vbox_mix_in = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON, + MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .ae0 = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON)}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:karaoke, capture:audio (BT input) */ + { + .music_out = {(MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON), + (MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON)}, + .vbox_mix_in = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON, + MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae0 = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_VBOXREFOUT_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall2, capture:incall (analog input, analog output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall2, capture:incall (BT input, BT output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:incall2, capture:incall (BT input, analog+BT output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_VBOXOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall2, capture:incall + (analog input analog output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall2, capture:incall (BT input BT output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:audio+incall2, capture:incall + (BT input analog+BT output) */ + { + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall2, capture:audio+incall + (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:incall2, capture:audio+incall (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:incall2, capture:audio+incall + (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_MUSICIN_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall2, capture:audio+incall + (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_EXTIN_ON}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* playback:audio+incall2, capture:audio+incall + (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_VBOXOUT_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* playback:audio+incall2, capture:audio+incall + (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_VBOXOUT_ON | MCDRV_D1SRC_AE0_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, MCDRV_D1SRC_ADIF2_ON, 0}, + .ae0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON, + MCDRV_D1SRC_EXTIN_ON | MCDRV_D1SRC_AE0_ON}, + .voice_out = {MCDRV_D2SRC_VBOXIOOUT_ON}, + .vbox_io_in = {MCDRV_D2SRC_VOICEIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* incommunication2 (analog input, analog output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, MCDRV_D1SRC_AE1_ON, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .dac1 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .adc0 = {MCDRV_ASRC_MIC_ALL_ON, MCDRV_ASRC_MIC_ALL_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, + /* incommunication2 (BT input, BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, + MCDRV_D1SRC_VBOXOUT_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + }, + /* incommunication2 (BT input, analog+BT output) */ + { + .music_out = {MCDRV_D1SRC_VBOXREFOUT_ON, MCDRV_D1SRC_VBOXREFOUT_ON}, + .ext_out = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .vbox_mix_in = {MCDRV_D1SRC_AE1_ON, 0, + MCDRV_D1SRC_ADIF2_ON, MCDRV_D1SRC_MUSICIN_ON}, + .ae1 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .dac1 = {MCDRV_D1SRC_MUSICIN_ON, MCDRV_D1SRC_MUSICIN_ON}, + .host_out = {MCDRV_D2SRC_VBOXHOSTOUT_ON}, + .adif2 = {MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON, + MCDRV_D2SRC_DAC0REF_ON | MCDRV_D2SRC_DAC1REF_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, +}; + +static const struct mcdrv_path_info analog_input_path[] = { + { + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .ae0 = {MCDRV_D1SRC_ADIF1_ON, MCDRV_D1SRC_ADIF1_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .adif1 = {MCDRV_D2SRC_ADC0_L_ON, MCDRV_D2SRC_ADC0_R_ON}, + .adc0 = {(MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_L_ON), + (MCDRV_ASRC_MIC_ALL_ON | MCDRV_ASRC_LINEIN1_R_ON)}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + }, +}; + +static const int analog_path_mapping[PRESET_PATH_N]; + +static const struct mcdrv_path_info bt_input_path[] = { + { + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .ae0 = {MCDRV_D1SRC_EXTIN_ON, MCDRV_D1SRC_EXTIN_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + } +}; + +static const int bt_path_mapping[PRESET_PATH_N]; + +static const struct mcdrv_path_info dtmf_path[] = { + { + .ext_out = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac0 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .dac1 = {MCDRV_D1SRC_AE0_ON, MCDRV_D1SRC_AE0_ON}, + .sp = {MCDRV_ASRC_DAC1_L_ON,}, + .hp = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .rc = {MCDRV_ASRC_DAC0_L_ON}, + .lout1 = {MCDRV_ASRC_DAC0_L_ON, MCDRV_ASRC_DAC0_R_ON}, + .lout2 = {MCDRV_ASRC_DAC1_L_ON, MCDRV_ASRC_DAC1_R_ON}, + } +}; + +static const int dtmf_path_mapping[PRESET_PATH_N]; + +#endif /* _YMU831_PATH_CFG_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/ymu831_vol.h | 461 ++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 sound/soc/codecs/ymu831/ymu831_vol.h
diff --git a/sound/soc/codecs/ymu831/ymu831_vol.h b/sound/soc/codecs/ymu831/ymu831_vol.h new file mode 100644 index 0000000..34bdabd --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831_vol.h @@ -0,0 +1,461 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - split from ymu831.c + * - change in the Linux coding style + */ +#ifndef _YMU831_VOL_H +#define _YMU831_VOL_H + +/* volmap for Digital Volumes */ +static const s16 volmap_digital[] = { + 0xa000, 0xa100, 0xa200, 0xa300, 0xa400, 0xa500, 0xa600, 0xa700, + 0xa800, 0xa900, 0xaa00, 0xab00, 0xac00, 0xad00, 0xae00, 0xaf00, + 0xb000, 0xb100, 0xb200, 0xb300, 0xb400, 0xb500, 0xb600, 0xb700, + 0xb800, 0xb900, 0xba00, 0xbb00, 0xbc00, 0xbd00, 0xbe00, 0xbf00, + 0xc000, 0xc100, 0xc200, 0xc300, 0xc400, 0xc500, 0xc600, 0xc700, + 0xc800, 0xc900, 0xca00, 0xcb00, 0xcc00, 0xcd00, 0xce00, 0xcf00, + 0xd000, 0xd100, 0xd200, 0xd300, 0xd400, 0xd500, 0xd600, 0xd700, + 0xd800, 0xd900, 0xda00, 0xdb00, 0xdc00, 0xdd00, 0xde00, 0xdf00, + 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, 0xe700, + 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, 0xef00, + 0xf000, 0xf100, 0xf200, 0xf300, 0xf400, 0xf500, 0xf600, 0xf700, + 0xf800, 0xf900, 0xfa00, 0xfb00, 0xfc00, 0xfd00, 0xfe00, 0xff00, + 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, + 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, + 0x1000, 0x1100, 0x1200 +}; + +/* volmap for LINE/MIC Input Volumes */ +static const s16 volmap_ain[] = { + 0xa000, 0xa000, 0xa000, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, + 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, + 0xef00, 0xf000, 0xf100, 0xf200, 0xf300, 0xf400, 0xf500, 0xf600, + 0xf700, 0xf800, 0xf900, 0xfa00, 0xfb00, 0xfc00, 0xfd00, 0xfe00, + 0xff00, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, + 0x0700, 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, + 0x0f00, 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1580, + 0x1600, 0x1680, 0x1700, 0x1780, 0x1800, 0x1a00, 0x1c00, 0x1e00 +}; + +/* volmap for Analog Output Volumes */ +static const s16 volmap_aout[] = { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdc00, + 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, + 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, + 0xed00, 0xee00, 0xef00, 0xf000, 0xf080, 0xf100, 0xf180, 0xf200, + 0xf280, 0xf300, 0xf380, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, + 0xf680, 0xf700, 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, + 0xfa40, 0xfa80, 0xfac0, 0xfb00, 0xfb40, 0xfb80, 0xfbc0, 0xfc00, + 0xfc40, 0xfc80, 0xfcc0, 0xfd00, 0xfd40, 0xfd80, 0xfdc0, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000 +}; + +/* volmap for SP Volumes */ +static const s16 volmap_sp[5][128] = { + { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdc00, + 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, + 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, + 0xed00, 0xee00, 0xef00, 0xf000, 0xf080, 0xf100, 0xf180, 0xf200, + 0xf280, 0xf300, 0xf380, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, + 0xf680, 0xf700, 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, + 0xfa40, 0xfa80, 0xfac0, 0xfb00, 0xfb40, 0xfb80, 0xfbc0, 0xfc00, + 0xfc40, 0xfc80, 0xfcc0, 0xfd00, 0xfd40, 0xfd80, 0xfdc0, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000, + 0x0040, 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, + 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 0x03c0, 0x0400}, + { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdd00, + 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, 0xe500, + 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, + 0xee00, 0xef00, 0xf000, 0xf100, 0xf180, 0xf200, 0xf280, 0xf300, + 0xf380, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, 0xf680, 0xf700, + 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, 0xfa80, 0xfb00, + 0xfb40, 0xfb80, 0xfbc0, 0xfc00, 0xfc40, 0xfc80, 0xfcc0, 0xfd00, + 0xfd40, 0xfd80, 0xfdc0, 0xfe00, 0xfe40, 0xfe80, 0xfec0, 0xff00, + 0xff40, 0xff80, 0xffc0, 0x0000, 0x0040, 0x0080, 0x00c0, 0x0100, + 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, + 0x0340, 0x0380, 0x03c0, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400}, + { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xde00, + 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, + 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, + 0xef00, 0xf000, 0xf100, 0xf200, 0xf280, 0xf300, 0xf380, 0xf400, + 0xf480, 0xf500, 0xf580, 0xf600, 0xf680, 0xf700, 0xf780, 0xf800, + 0xf880, 0xf900, 0xf980, 0xfa00, 0xfa80, 0xfb00, 0xfb80, 0xfc00, + 0xfc40, 0xfc80, 0xfcc0, 0xfd00, 0xfd40, 0xfd80, 0xfdc0, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000, + 0x0040, 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, + 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 0x03c0, 0x0400, + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400}, + { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdf00, + 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, 0xe700, + 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, 0xef00, + 0xf000, 0xf100, 0xf200, 0xf300, 0xf380, 0xf400, 0xf480, 0xf500, + 0xf580, 0xf600, 0xf680, 0xf700, 0xf780, 0xf800, 0xf880, 0xf900, + 0xf980, 0xfa00, 0xfa80, 0xfb00, 0xfb80, 0xfc00, 0xfc80, 0xfd00, + 0xfd40, 0xfd80, 0xfdc0, 0xfe00, 0xfe40, 0xfe80, 0xfec0, 0xff00, + 0xff40, 0xff80, 0xffc0, 0x0000, 0x0040, 0x0080, 0x00c0, 0x0100, + 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, + 0x0340, 0x0380, 0x03c0, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400}, + { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xe000, + 0xe100, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, 0xe700, 0xe800, + 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, 0xef00, 0xf000, + 0xf100, 0xf200, 0xf300, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, + 0xf680, 0xf700, 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, + 0xfa80, 0xfb00, 0xfb80, 0xfc00, 0xfc80, 0xfd00, 0xfd80, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000, + 0x0040, 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, + 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 0x03c0, 0x0400, + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400} +}; + +/* volmap for LineOut Volumes */ +static const s16 volmap_lineout[] = { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdc00, + 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, + 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, + 0xed00, 0xee00, 0xef00, 0xf000, 0xf080, 0xf100, 0xf180, 0xf200, + 0xf280, 0xf300, 0xf380, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, + 0xf680, 0xf700, 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, + 0xfa40, 0xfa80, 0xfac0, 0xfb00, 0xfb40, 0xfb80, 0xfbc0, 0xfc00, + 0xfc40, 0xfc80, 0xfcc0, 0xfd00, 0xfd40, 0xfd80, 0xfdc0, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000, + 0x0040, 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, +}; + +/* volmap for LineOut2 Volumes */ +static const s16 volmap_lineout2[] = { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xda00, + 0xdc00, 0xdc00, 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, + 0xe300, 0xe400, 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, + 0xeb00, 0xec00, 0xed00, 0xee00, 0xee00, 0xef00, 0xef00, 0xf000, + 0xf080, 0xf100, 0xf180, 0xf200, 0xf280, 0xf300, 0xf380, 0xf400, + 0xf480, 0xf500, 0xf580, 0xf600, 0xf680, 0xf700, 0xf780, 0xf800, + 0xf800, 0xf880, 0xf880, 0xf900, 0xf900, 0xf980, 0xf980, 0xfa00, + 0xfa40, 0xfa80, 0xfac0, 0xfb00, 0xfb40, 0xfb80, 0xfbc0, 0xfc00, + 0xfc40, 0xfc80, 0xfcc0, 0xfd00, 0xfd40, 0xfd80, 0xfdc0, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000, +}; + +/* volmap for HP Output Volumes */ +static const s16 volmap_hp_es1[] = { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdd00, + 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, 0xe500, + 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, + 0xee00, 0xef00, 0xf000, 0xf100, 0xf180, 0xf200, 0xf280, 0xf300, + 0xf380, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, 0xf680, 0xf700, + 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, 0xfa80, 0xfb00, + 0xfb40, 0xfb80, 0xfbc0, 0xfc00, 0xfc40, 0xfc80, 0xfcc0, 0xfd00, + 0xfd40, 0xfd80, 0xfdc0, 0xfe00, 0xfe40, 0xfe80, 0xfec0, 0xff00, + 0xff40, 0xff80, 0xffc0, 0x0000, 0x0040, 0x0080, 0x00c0, 0x0100, + 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, + 0x0340, 0x0380, 0x03c0, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400 +}; + +static const s16 volmap_hp[] = { + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xdc00, + 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, + 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, + 0xed00, 0xee00, 0xef00, 0xf000, 0xf080, 0xf100, 0xf180, 0xf200, + 0xf280, 0xf300, 0xf380, 0xf400, 0xf480, 0xf500, 0xf580, 0xf600, + 0xf680, 0xf700, 0xf780, 0xf800, 0xf880, 0xf900, 0xf980, 0xfa00, + 0xfa40, 0xfa80, 0xfac0, 0xfb00, 0xfb40, 0xfb80, 0xfbc0, 0xfc00, + 0xfc40, 0xfc80, 0xfcc0, 0xfd00, 0xfd40, 0xfd80, 0xfdc0, 0xfe00, + 0xfe40, 0xfe80, 0xfec0, 0xff00, 0xff40, 0xff80, 0xffc0, 0x0000, + 0x0040, 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, + 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 0x03c0, 0x0400 +}; + +/* volmap for Master Volumes */ +static const s16 volmap_master[] = { + 0xb500, 0xb600, 0xb700, 0xb800, 0xb900, 0xba00, 0xbb00, 0xbc00, + 0xbd00, 0xbe00, 0xbf00, 0xc000, 0xc100, 0xc200, 0xc300, 0xc400, + 0xc500, 0xc600, 0xc700, 0xc800, 0xc900, 0xca00, 0xcb00, 0xcc00, + 0xcd00, 0xce00, 0xcf00, 0xd000, 0xd100, 0xd200, 0xd300, 0xd400, + 0xd500, 0xd600, 0xd700, 0xd800, 0xd900, 0xda00, 0xdb00, 0xdc00, + 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, + 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, + 0xed00, 0xee00, 0xdf00, 0xf000, 0xf100, 0xf200, 0xf300, 0xf400, + 0xf500, 0xf600, 0xf700, 0xf800, 0xf900, 0xfa00, 0xfb00, 0xfc00, + 0xfd00, 0xfe00, 0xff00, 0x0000 +}; + +/* volmap for Voice Volumes */ +static const s16 volmap_voice[] = { + 0xb500, 0xb600, 0xb700, 0xb800, 0xb900, 0xba00, 0xbb00, 0xbc00, + 0xbd00, 0xbe00, 0xbf00, 0xc000, 0xc100, 0xc200, 0xc300, 0xc400, + 0xc500, 0xc600, 0xc700, 0xc800, 0xc900, 0xca00, 0xcb00, 0xcc00, + 0xcd00, 0xce00, 0xcf00, 0xd000, 0xd100, 0xd200, 0xd300, 0xd400, + 0xd500, 0xd600, 0xd700, 0xd800, 0xd900, 0xda00, 0xdb00, 0xdc00, + 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, 0xe200, 0xe300, 0xe400, + 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, + 0xed00, 0xee00, 0xdf00, 0xf000, 0xf100, 0xf200, 0xf300, 0xf400, + 0xf500, 0xf600, 0xf700, 0xf800, 0xf900, 0xfa00, 0xfb00, 0xfc00, + 0xfd00, 0xfe00, 0xff00, 0x0000 +}; + +/* volmap for AnalogIn Ana Volumes */ +static const s16 volmap_aplay_a[] = { + 0xa000, 0xa000, 0xa000, 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, + 0xe700, 0xe800, 0xe900, 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, + 0xef00, 0xf000, 0xf100, 0xf200, 0xf300, 0xf400, 0xf500, 0xf600, + 0xf700, 0xf800, 0xf900, 0xfa00, 0xfb00, 0xfc00, 0xfd00, 0xfe00, + 0xff00, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, + 0x0700, 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, + 0x0f00, 0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1580, + 0x1600, 0x1680, 0x1700, 0x1780, 0x1800, 0x1a00, 0x1c00, 0x1e00 +}; + +/* volmap for Adif(ES) Volumes */ +static const s16 volmap_adif[] = { + 0xa000, 0xa300, 0xa400, 0xa500, 0xa600, 0xa700, 0xa800, 0xa900, + 0xaa00, 0xab00, 0xac00, 0xad00, 0xae00, 0xaf00, 0xb000, 0xb100, + 0xb200, 0xb300, 0xb400, 0xb500, 0xb600, 0xb700, 0xb800, 0xb900, + 0xba00, 0xbb00, 0xbc00, 0xbd00, 0xbe00, 0xbf00, 0xc000, 0xc100, + 0xc200, 0xc300, 0xc400, 0xc500, 0xc600, 0xc700, 0xc800, 0xc900, + 0xca00, 0xcb00, 0xcc00, 0xcd00, 0xce00, 0xcf00, 0xd000, 0xd100, + 0xd200, 0xd300, 0xd400, 0xd500, 0xd600, 0xd700, 0xd800, 0xd900, + 0xda00, 0xdb00, 0xdc00, 0xdd00, 0xde00, 0xdf00, 0xe000, 0xe100, + 0xe200, 0xe300, 0xe400, 0xe500, 0xe600, 0xe700, 0xe800, 0xe900, + 0xea00, 0xeb00, 0xec00, 0xed00, 0xee00, 0xef00, 0xf000, 0xf100, + 0xf200, 0xf300, 0xf400, 0xf500, 0xf600, 0xf700, 0xf800, 0xf900, + 0xfa00, 0xfb00, 0xfc00, 0xfd00, 0xfe00, 0xff00, 0x0000, 0x0100, + 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 0x0800, 0x0900, + 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, 0x1000, 0x1100, + 0x1200, 0x1200, 0x1200 +}; + +struct mc_asoc_vreg_info { + size_t offset; + const s16 *volmap; + u8 channels; +}; + +static struct mc_asoc_vreg_info vreg_map[MC_ASOC_N_VOL_REG] = { + { + .offset = offsetof(struct mcdrv_vol_info, d_music_in), + .volmap = volmap_digital, + .channels = MUSICIN_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_ext_in), + .volmap = volmap_digital, + .channels = EXTIN_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_voice_in), + .volmap = volmap_digital, + .channels = VOICEIN_VOL_CHANNELS}, + { + .offset = offsetof(struct mcdrv_vol_info, d_ref_in), + .volmap = volmap_digital, + .channels = REFIN_VOL_CHANNELS}, + { + .offset = offsetof(struct mcdrv_vol_info, d_adif0_in), + .volmap = volmap_digital, + .channels = ADIF0IN_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_adif1_in), + .volmap = volmap_digital, + .channels = ADIF1IN_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_adif2_in), + .volmap = volmap_digital, + .channels = ADIF2IN_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_music_out), + .volmap = volmap_digital, + .channels = MUSICOUT_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_ext_out), + .volmap = volmap_digital, + .channels = EXTOUT_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_voice_out), + .volmap = volmap_digital, + .channels = VOICEOUT_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_ref_out), + .volmap = volmap_digital, + .channels = REFOUT_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_dac0_out), + .volmap = volmap_digital, + .channels = DAC0OUT_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_dac1_out), + .volmap = volmap_digital, + .channels = DAC1OUT_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_dpath_da), + .volmap = volmap_digital, + .channels = DPATH_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, d_dpath_ad), + .volmap = volmap_digital, + .channels = DPATH_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_line_in1), + .volmap = volmap_ain, + .channels = LINEIN1_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_mic1), + .volmap = volmap_ain, + .channels = MIC1_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_mic2), + .volmap = volmap_ain, + .channels = MIC2_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_mic3), + .volmap = volmap_ain, + .channels = MIC3_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_mic4), + .volmap = volmap_ain, + .channels = MIC4_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_hp), + .volmap = volmap_hp, + .channels = HP_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_sp), + .volmap = volmap_sp[0], + .channels = SP_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_rc), + .volmap = volmap_aout, + .channels = RC_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_line_out1), + .volmap = volmap_lineout, + .channels = LINEOUT1_VOL_CHANNELS, + }, + { + .offset = offsetof(struct mcdrv_vol_info, a_line_out2), + .volmap = volmap_lineout2, + .channels = LINEOUT2_VOL_CHANNELS, + }, + { + .offset = (size_t) -1, + .volmap = NULL, + .channels = 0, + }, + { + .offset = (size_t) -1, + .volmap = volmap_master, + .channels = MUSICIN_VOL_CHANNELS, + }, + { + .offset = (size_t) -1, + .volmap = volmap_voice, + .channels = VOICEIN_VOL_CHANNELS, + }, + { + .offset = (size_t) -1, + .volmap = volmap_aplay_a, + .channels = LINEIN1_VOL_CHANNELS, + }, + { + .offset = (size_t) -1, + .volmap = volmap_digital, + .channels = ADIF0IN_VOL_CHANNELS, + }, +}; + +#endif /* _YMU831_VOL_H */
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/codecs/ymu831/Makefile | 2 +- sound/soc/codecs/ymu831/ymu831.c | 5235 +++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/ymu831.h | 48 + sound/soc/codecs/ymu831/ymu831_priv.h | 278 ++ 4 files changed, 5562 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/ymu831.c create mode 100644 sound/soc/codecs/ymu831/ymu831.h create mode 100644 sound/soc/codecs/ymu831/ymu831_priv.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile index 3fd53fe..ada24db 100644 --- a/sound/soc/codecs/ymu831/Makefile +++ b/sound/soc/codecs/ymu831/Makefile @@ -1,4 +1,4 @@ -snd-soc-ymu831-objs := \ +snd-soc-ymu831-objs := ymu831.o \ mcbdspdrv.o \ mccdspdrv.o \ mcdevif.o \ diff --git a/sound/soc/codecs/ymu831/ymu831.c b/sound/soc/codecs/ymu831/ymu831.c new file mode 100644 index 0000000..62c4a90 --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831.c @@ -0,0 +1,5235 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/workqueue.h> + +#include <linux/spi/spi.h> + +#include <sound/hwdep.h> +#include <sound/initval.h> +#include <sound/jack.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include "mcdevif.h" +#include "mcdriver.h" +#include "ymu831.h" +#include "ymu831_cfg.h" +#include "ymu831_ctl.h" +#include "ymu831_path_cfg.h" +#include "ymu831_priv.h" +#include "ymu831_vol.h" + +#define MC_ASOC_DRIVER_VERSION "1.0.1" + +#define MC_ASOC_RATE SNDRV_PCM_RATE_8000_192000 +#define MC_ASOC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define get_port_id(id) (id - 1) + +#define PORT_MUSIC 0 +#define PORT_EXT 1 +#define PORT_VOICE 2 +#define PORT_HIFI 3 + +#define DIO_MUSIC 0 +#define DIO_VOICE 1 +#define LOUT1 3 +#define LOUT2 4 +#define LIN1 3 +#define LIN1_LOUT1 3 +#define LIN1_LOUT2 5 + +#define DSP_PRM_OUTPUT 0 +#define DSP_PRM_INPUT 1 +#define DSP_PRM_VC_1MIC 2 +#define DSP_PRM_VC_2MIC 3 +#define DSP_PRM_BASE 0 +#define DSP_PRM_USER 1 + +struct mc_asoc_info_store { + u32 get; + u32 set; + size_t offset; + u32 flags; +}; + +static const struct mc_asoc_info_store info_store_tbl[] = { + { + .get = MCDRV_GET_CLOCKSW, + .set = MCDRV_SET_CLOCKSW, + .offset = offsetof(struct mc_asoc_data, clocksw_store), + }, + { + .get = MCDRV_GET_DIGITALIO, + .set = MCDRV_SET_DIGITALIO, + .offset = offsetof(struct mc_asoc_data, dio_store), + .flags = 0xfff, + }, + { + .get = MCDRV_GET_DIGITALIO_PATH, + .set = MCDRV_SET_DIGITALIO_PATH, + .offset = offsetof(struct mc_asoc_data, diopath_store), + .flags = 0x7ff, + }, + { + .get = MCDRV_GET_PATH, + .set = MCDRV_SET_PATH, + .offset = offsetof(struct mc_asoc_data, path_store), + }, + { + .get = MCDRV_GET_VOLUME, + .set = MCDRV_SET_VOLUME, + .offset = offsetof(struct mc_asoc_data, vol_store), + }, + { + .get = MCDRV_GET_SWAP, + .set = MCDRV_SET_SWAP, + .offset = offsetof(struct mc_asoc_data, swap_store), + .flags = 0x7fff}, +}; + +struct snd_soc_codec *mc_asoc_codec; + +static u8 mc_asoc_ver_id = 1; +static bool mc_asoc_suspended; +static u8 mc_asoc_hpimpclass = 0xff; +static u8 mc_asoc_jack_status; + +static struct mcdrv_vol_info mc_asoc_vol_info_mute; + +static u8 mc_asoc_main_mic = MAIN_MIC; +static u8 mc_asoc_sub_mic = SUB_MIC; +static u8 mc_asoc_hs_mic = HEADSET_MIC; +static u8 mc_asoc_mic1_bias = MIC1_BIAS; +static u8 mc_asoc_mic2_bias = MIC2_BIAS; +static u8 mc_asoc_mic3_bias = MIC3_BIAS; +static u8 mc_asoc_mic4_bias = MIC4_BIAS; + +static u8 mc_asoc_audio_play_port = DIO_MUSIC; +static u8 mc_asoc_audio_cap_port = DIO_MUSIC; +static u8 mc_asoc_voice_port = DIO_VOICE; +static u8 mc_asoc_rate = MCDRV_FS_48000; + +static int set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + codec->dapm.bias_level = level; + + return 0; +} + +static int read_cache(struct snd_soc_codec *codec, unsigned int reg) +{ + int ret; + unsigned int val; + + ret = snd_soc_cache_read(codec, reg, &val); + if (ret) { + dev_err(codec->dev, "Cache read to %x failed: %d\n", reg, ret); + return ret; + } + + return val; +} + +static int get_mic_block_on(u8 mic) +{ + switch (mic) { + case MIC_1: + return MCDRV_ASRC_MIC1_ON; + case MIC_2: + return MCDRV_ASRC_MIC2_ON; + case MIC_3: + return MCDRV_ASRC_MIC3_ON; + case MIC_4: + return MCDRV_ASRC_MIC4_ON; + default: + break; + } + + return -1; +} + +static int get_main_mic_block_on(void) +{ + return get_mic_block_on(mc_asoc_main_mic); +} + +static int get_sub_mic_block_on(void) +{ + return get_mic_block_on(mc_asoc_sub_mic); +} + +static int get_hs_mic_block_on(void) +{ + return get_mic_block_on(mc_asoc_hs_mic); +} + +static int get_unused_mic_block_on(void) +{ + int ret = MCDRV_ASRC_MIC1_ON | MCDRV_ASRC_MIC2_ON | + MCDRV_ASRC_MIC3_ON | MCDRV_ASRC_MIC4_ON; + if ((mc_asoc_main_mic == MIC_1) + || (mc_asoc_sub_mic == MIC_1) + || (mc_asoc_hs_mic == MIC_1)) + ret &= ~MCDRV_ASRC_MIC1_ON; + + if ((mc_asoc_main_mic == MIC_2) + || (mc_asoc_sub_mic == MIC_2) + || (mc_asoc_hs_mic == MIC_2)) + ret &= ~MCDRV_ASRC_MIC2_ON; + + if ((mc_asoc_main_mic == MIC_3) + || (mc_asoc_sub_mic == MIC_3) + || (mc_asoc_hs_mic == MIC_3)) + ret &= ~MCDRV_ASRC_MIC3_ON; + + if ((mc_asoc_main_mic == MIC_4) + || (mc_asoc_sub_mic == MIC_4) + || (mc_asoc_hs_mic == MIC_4)) + ret &= ~MCDRV_ASRC_MIC4_ON; + + return ret; +} + +static int get_incall_mic(struct snd_soc_codec *codec, int output_path) +{ + switch (output_path) { + case MC_ASOC_OUTPUT_PATH_SP: + return read_cache(codec, MC_ASOC_INCALL_MIC_SP); + case MC_ASOC_OUTPUT_PATH_RC: + case MC_ASOC_OUTPUT_PATH_SP_RC: + case MC_ASOC_OUTPUT_PATH_LO1_RC: + case MC_ASOC_OUTPUT_PATH_LO2_RC: + return read_cache(codec, MC_ASOC_INCALL_MIC_RC); + case MC_ASOC_OUTPUT_PATH_HP: + case MC_ASOC_OUTPUT_PATH_SP_HP: + case MC_ASOC_OUTPUT_PATH_LO1_HP: + case MC_ASOC_OUTPUT_PATH_LO2_HP: + return read_cache(codec, MC_ASOC_INCALL_MIC_HP); + case MC_ASOC_OUTPUT_PATH_LO1: + case MC_ASOC_OUTPUT_PATH_SP_LO1: + case MC_ASOC_OUTPUT_PATH_LO2_LO1: + return read_cache(codec, MC_ASOC_INCALL_MIC_LO1); + case MC_ASOC_OUTPUT_PATH_LO2: + case MC_ASOC_OUTPUT_PATH_SP_LO2: + case MC_ASOC_OUTPUT_PATH_LO1_LO2: + return read_cache(codec, MC_ASOC_INCALL_MIC_LO2); + case MC_ASOC_OUTPUT_PATH_HS: + case MC_ASOC_OUTPUT_PATH_BT: + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return MC_ASOC_INCALL_MIC_MAINMIC; + default: + break; + } + + return -EIO; +} + +struct mixer_path_ctl_info { + int audio_mode_play; + int audio_mode_cap; + int output_path; + int input_path; + int incall_mic; + int mainmic_play; + int submic_play; + int msmic_play; + int hsmic_play; + int btmic_play; + int lin1_play; + int dtmf_control; + int dtmf_output; +}; + +static int get_mixer_path_ctl_info(struct snd_soc_codec *codec, + struct mixer_path_ctl_info *info) +{ + info->audio_mode_play = read_cache(codec, MC_ASOC_AUDIO_MODE_PLAY); + if (info->audio_mode_play < 0) + return -EIO; + + info->audio_mode_cap = read_cache(codec, MC_ASOC_AUDIO_MODE_CAP); + if (info->audio_mode_cap < 0) + return -EIO; + + info->output_path = read_cache(codec, MC_ASOC_OUTPUT_PATH); + if (info->output_path < 0) + return -EIO; + + info->input_path = read_cache(codec, MC_ASOC_INPUT_PATH); + if (info->input_path < 0) + return -EIO; + + info->incall_mic = get_incall_mic(codec, info->output_path); + if (info->incall_mic < 0) + return -EIO; + + info->dtmf_control = read_cache(codec, MC_ASOC_DTMF_CONTROL); + if (info->dtmf_control < 0) + return -EIO; + + info->dtmf_output = read_cache(codec, MC_ASOC_DTMF_OUTPUT); + if (info->dtmf_output < 0) + return -EIO; + + info->mainmic_play = read_cache(codec, MC_ASOC_MAINMIC_PLAYBACK_PATH); + if (info->mainmic_play < 0) + return -EIO; + + info->submic_play = read_cache(codec, MC_ASOC_SUBMIC_PLAYBACK_PATH); + if (info->submic_play < 0) + return -EIO; + + info->msmic_play = read_cache(codec, MC_ASOC_2MIC_PLAYBACK_PATH); + if (info->msmic_play < 0) + return -EIO; + + info->hsmic_play = read_cache(codec, MC_ASOC_HSMIC_PLAYBACK_PATH); + if (info->hsmic_play < 0) + return -EIO; + + info->btmic_play = read_cache(codec, MC_ASOC_BTMIC_PLAYBACK_PATH); + if (info->btmic_play < 0) + return -EIO; + + info->lin1_play = read_cache(codec, MC_ASOC_LIN1_PLAYBACK_PATH); + if (info->lin1_play < 0) + return -EIO; + + return 0; +} + +static int get_path_preset_idx(struct mixer_path_ctl_info *info) +{ + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM + && info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 25; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 26; + default: + return 24; + } + } + + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM2 + && info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM) { + if (info->output_path == MC_ASOC_OUTPUT_PATH_BT) + return 63; + else if (info->output_path == MC_ASOC_OUTPUT_PATH_SP_BT + || info->output_path == MC_ASOC_OUTPUT_PATH_LO1_BT + || info->output_path == MC_ASOC_OUTPUT_PATH_LO2_BT) + return 64; + else + return 62; + } + + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL) { + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 13; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 14; + default: + return 12; + } + } + + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 19; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 20; + default: + return 18; + } + } + } + + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL2) { + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 51; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 52; + default: + return 50; + } + } + + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 57; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 58; + default: + return 56; + } + } + } + + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) { + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 16; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 17; + default: + return 15; + } + } + + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 22; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 23; + default: + return 21; + } + } + } + + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL2) { + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 54; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 55; + default: + return 53; + } + } + + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 60; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 61; + default: + return 59; + } + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_OFF || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCALL || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM)) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_OFF || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM)) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL2 && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_OFF || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM))) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + return 2; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + return 3; + default: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return 27; + return 1; + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_OFF && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL)) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL && + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL2 && + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL)) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM2 && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL))) { + switch (info->input_path) { + case MC_ASOC_INPUT_PATH_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + return 5; + case MC_ASOC_INPUT_PATH_VOICECALL: + case MC_ASOC_INPUT_PATH_VOICEUPLINK: + case MC_ASOC_INPUT_PATH_VOICEDOWNLINK: + if ((mc_asoc_rate == MCDRV_FS_96000) + || (mc_asoc_rate == MCDRV_FS_192000)) + return 28; + return 4; + default: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return 28; + return 4; + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO && + (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO || + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL)) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL && + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO) + || (info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL2 && + info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO)) { + switch (info->input_path) { + case MC_ASOC_INPUT_PATH_VOICECALL: + case MC_ASOC_INPUT_PATH_VOICEUPLINK: + case MC_ASOC_INPUT_PATH_VOICEDOWNLINK: + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + return 8; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + return 10; + default: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return 29; + return 6; + } + default: + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 9; + return 8; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 11; + return 10; + default: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) { + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return -1; + return 7; + } + + if (mc_asoc_rate == MCDRV_FS_96000 + || mc_asoc_rate == MCDRV_FS_192000) + return 29; + return 6; + } + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_OFF || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL2 || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM2) + && info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIOEX) { + switch (info->input_path) { + case MC_ASOC_INPUT_PATH_VOICECALL: + case MC_ASOC_INPUT_PATH_VOICEUPLINK: + case MC_ASOC_INPUT_PATH_VOICEDOWNLINK: + return 30; + default: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 31; + return 30; + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL2) + && info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIOEX) { + switch (info->input_path) { + case MC_ASOC_INPUT_PATH_VOICECALL: + case MC_ASOC_INPUT_PATH_VOICEUPLINK: + case MC_ASOC_INPUT_PATH_VOICEDOWNLINK: + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + return 34; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + return 36; + default: + return 32; + } + default: + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 35; + return 34; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 37; + return 36; + default: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 33; + return 32; + } + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_OFF || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCALL || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_INCOMM) + && info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIOVR) { + switch (info->input_path) { + case MC_ASOC_INPUT_PATH_VOICECALL: + case MC_ASOC_INPUT_PATH_VOICEUPLINK: + case MC_ASOC_INPUT_PATH_VOICEDOWNLINK: + return 38; + default: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 39; + return 38; + } + } + + if ((info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO || + info->audio_mode_play == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) + && info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIOVR) { + switch (info->output_path) { + case MC_ASOC_OUTPUT_PATH_BT: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 43; + return 42; + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 45; + return 44; + default: + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 41; + return 40; + } + } + + if (info->audio_mode_play == MC_ASOC_AUDIO_MODE_KARAOKE) { + if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_OFF) { + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 47; + return 46; + } else if (info->audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO) { + if (info->input_path == MC_ASOC_INPUT_PATH_BT) + return 49; + return 48; + } + } + + return 0; +} + +static inline int is_incall(int preset_idx) +{ + if ((preset_idx >= 12 && preset_idx <= 23) + || (preset_idx >= 50 && preset_idx <= 61)) + return 1; + + return 0; +} + +static inline int is_incommunication(int preset_idx) +{ + if ((preset_idx >= 24 && preset_idx <= 26) + || (preset_idx >= 62 && preset_idx <= 64)) + return 1; + + return 0; +} + +static void set_vol_mute_flag(size_t offset, u8 lr, u8 mute) +{ + s16 *vp = (void *)&mc_asoc_vol_info_mute + offset; + + if (offset == (size_t) -1) + return; + + if (mute == 1) + *(vp + lr) = 0xa000; + else + *(vp + lr) = 0; +} + +static u8 get_vol_mute_flag(size_t offset, u8 lr) +{ + s16 *vp; + + if (offset == (size_t) -1) + return 1; /* mute */ + + vp = (void *)&mc_asoc_vol_info_mute + offset; + + return (*(vp + lr) != 0); +} + +static int get_master_vol(struct snd_soc_codec *codec, s16 *db, int reg, int i) +{ + unsigned int v; + int cache, sum, sw, vol; + + cache = read_cache(codec, MC_ASOC_DVOL_MASTER); + if (cache < 0) + return -EIO; + + v = (cache >> (i * 8)) & 0xff; + sw = v & 0x80; + vol = sw ? (v & 0x7f) : 0; + if (!vol) + *db = vreg_map[reg].volmap[0]; + else { + sum = *db + vreg_map[MC_ASOC_DVOL_MASTER].volmap[vol]; + if (sum < vreg_map[reg].volmap[0]) + sum = vreg_map[reg].volmap[0]; + *db = sum; + } + + return 0; +} + +static int get_voice_vol(struct snd_soc_codec *codec, s16 *db, int reg, int i) +{ + unsigned int v; + int cache, sum, sw, vol; + + cache = read_cache(codec, MC_ASOC_DVOL_VOICE); + if (cache < 0) + return -EIO; + + v = (cache >> (i * 8)) & 0xff; + sw = v & 0x80; + vol = sw ? (v & 0x7f) : 0; + if (!vol) + *db = vreg_map[reg].volmap[0]; + else { + sum = *db + vreg_map[MC_ASOC_DVOL_VOICE].volmap[vol]; + if (sum < vreg_map[reg].volmap[0]) + sum = vreg_map[reg].volmap[0]; + *db = sum; + } + + return 0; +} + +static int get_aplay_vol(struct snd_soc_codec *codec, s16 *db, int reg, int i, + int aplay_reg, struct mixer_path_ctl_info *info, + int preset_idx) +{ + unsigned int v; + int cache, input_path, sw, vol; + s16 aplay_db; + + if (preset_idx >= 46 && preset_idx <= 49) + return 0; + + if (is_incall(preset_idx) || is_incommunication(preset_idx)) + return 0; + + if (!(preset_idx < 12 || preset_idx == 28 || preset_idx > 29)) + return 0; + + cache = read_cache(codec, aplay_reg); + if (cache < 0) + return -EIO; + + v = (cache >> (i * 8)) & 0xff; + sw = v & 0x80; + vol = sw ? (v & 0x7f) : 0; + aplay_db = vreg_map[reg].volmap[vol]; + input_path = info->input_path; + + if (reg == MC_ASOC_DVOL_ADIF1IN) { + if (info->lin1_play == 1) { + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_LIN1) { + *db = aplay_db; + return 0; + } + } + + if (info->mainmic_play == 1) { + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_MAINMIC) { + *db = aplay_db; + return 0; + } + } + + if (info->submic_play == 1) { + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_SUBMIC) { + *db = aplay_db; + return 0; + } + } + + if (info->msmic_play == 1) { + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (info->hsmic_play == 1) { + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_HS) { + *db = aplay_db; + return 0; + } + } + + return 0; + } + + if (reg == MC_ASOC_AVOL_LINEIN1) { + if (info->lin1_play == 1) { + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_LIN1) + *db = aplay_db; + } + + return 0; + } + + if (reg == MC_ASOC_AVOL_MIC1) { + if (mc_asoc_main_mic == MIC_1) { + if (info->mainmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_MAINMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_sub_mic == MIC_1) { + if (info->submic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_SUBMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_hs_mic == MIC_1 && info->hsmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_HS) + *db = aplay_db; + + return 0; + } + + if (reg == MC_ASOC_AVOL_MIC2) { + if (mc_asoc_main_mic == MIC_2) { + if (info->mainmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_MAINMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_sub_mic == MIC_2) { + if (info->submic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_SUBMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_hs_mic == MIC_2 && info->hsmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_HS) + *db = aplay_db; + + return 0; + } + + if (reg == MC_ASOC_AVOL_MIC3) { + if (mc_asoc_main_mic == MIC_3) { + if (info->mainmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_MAINMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_sub_mic == MIC_3) { + if (info->submic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_SUBMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_hs_mic == MIC_3 && info->hsmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_HS) + *db = aplay_db; + + return 0; + } + + if (reg == MC_ASOC_AVOL_MIC4) { + if (mc_asoc_main_mic == MIC_4) { + if (info->mainmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_MAINMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_sub_mic == MIC_4) { + if (info->submic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == + MC_ASOC_INPUT_PATH_SUBMIC) { + *db = aplay_db; + return 0; + } + + if (info->msmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + *db = aplay_db; + return 0; + } + } + + if (mc_asoc_hs_mic == MIC_4 && info->hsmic_play == 1) + if (preset_idx < 4 || preset_idx >= 38 + || input_path == MC_ASOC_INPUT_PATH_BT + || input_path == MC_ASOC_INPUT_PATH_HS) + *db = aplay_db; + } + + return 0; +} + +static int set_vol_info(struct snd_soc_codec *codec, + struct mcdrv_vol_info *vol_info, int reg, + struct mixer_path_ctl_info *mixer_info, int preset_idx) +{ + s16 *vp; + int i, cache; + + if (!codec) + return -EIO; + + if (reg >= MC_ASOC_AVOL_SP_GAIN) + return -EIO; + + if (vreg_map[reg].offset != (size_t) -1) { + vp = (void *)vol_info + vreg_map[reg].offset; + cache = read_cache(codec, reg); + if (cache < 0) + return -EIO; + + for (i = 0; i < vreg_map[reg].channels; i++, vp++) { + unsigned int v; + int sw, vol, size; + bool sw_overwrite; + s16 db, db_max, map; + + v = (cache >> (i * 8)) & 0xff; + sw = v & 0x80; + sw_overwrite = false; + + if (is_incall(preset_idx)) { + switch (reg) { + case MC_ASOC_DVOL_VOICEOUT: + if (mc_asoc_voice_port == DIO_VOICE + && sw) + sw_overwrite = true; + break; + case MC_ASOC_DVOL_DAC0OUT: + if (mc_asoc_voice_port == LIN1_LOUT1 + && sw) + sw_overwrite = true; + break; + case MC_ASOC_DVOL_DAC1OUT: + if (mc_asoc_voice_port == LIN1_LOUT2 + && sw) + sw_overwrite = true; + break; + default: + break; + } + } else if (is_incommunication(preset_idx)) { + if (reg == MC_ASOC_DVOL_VOICEOUT) { + if (mc_asoc_voice_port == DIO_VOICE + && sw) + sw_overwrite = true; + } + } + + if (sw_overwrite) + sw = read_cache(codec, MC_ASOC_VOICE_RECORDING); + + vol = sw ? (v & 0x7f) : 0; + + if (get_vol_mute_flag(vreg_map[reg].offset, i)) + db = vreg_map[reg].volmap[0]; + else + db = vreg_map[reg].volmap[vol]; + + if (reg == MC_ASOC_DVOL_MUSICIN) { + if (mc_asoc_audio_play_port != DIO_MUSIC + || !vol) + db = vreg_map[reg].volmap[0]; + else if (get_master_vol(codec, &db, reg, i)) + return -EIO; + } else if (reg == MC_ASOC_DVOL_VOICEIN) { + if (is_incall(preset_idx)) + db = vreg_map[reg].volmap[vol]; + else if (mc_asoc_voice_port == LIN1_LOUT1 + || mc_asoc_voice_port == LIN1_LOUT2 + || !vol) + db = vreg_map[reg].volmap[0]; + else if (get_voice_vol(codec, &db, reg, i)) + return -EIO; + } else if (reg == MC_ASOC_DVOL_ADIF1IN) { + if (get_aplay_vol(codec, &db, reg, i, + MC_ASOC_DVOL_APLAY_D, + mixer_info, preset_idx)) + return -EIO; + if (mc_asoc_audio_play_port == LIN1) + if (get_master_vol(codec, &db, reg, i)) + return -EIO; + } else if (reg == MC_ASOC_AVOL_LINEIN1) { + if (is_incall(preset_idx)) { + if ((mc_asoc_voice_port == LIN1_LOUT1 || + mc_asoc_voice_port == LIN1_LOUT2) + && get_voice_vol(codec, &db, reg, + i)) + return -EIO; + } else { + if (get_aplay_vol(codec, &db, reg, i, + MC_ASOC_DVOL_APLAY_A, + mixer_info, + preset_idx)) + return -EIO; + } + } else if ((reg == MC_ASOC_AVOL_MIC1 || + reg == MC_ASOC_AVOL_MIC2 || + reg == MC_ASOC_AVOL_MIC3 || + reg == MC_ASOC_AVOL_MIC4) + && get_aplay_vol(codec, &db, reg, i, + MC_ASOC_DVOL_APLAY_A, + mixer_info, preset_idx)) { + return -EIO; + } else if (reg == MC_ASOC_AVOL_HP + && (mc_asoc_hpimpclass != (u8) -1 && + db > vreg_map[reg].volmap[0])) { + size = ARRAY_SIZE(volmap_hp) - 1; + db_max = vreg_map[MC_ASOC_AVOL_HP].volmap[size]; + db += hp_vol_imp_table[mc_asoc_hpimpclass] << 8; + map = vreg_map[MC_ASOC_AVOL_HP].volmap[0]; + if (db < map) + db = map; + else if (db > db_max) + db = db_max; + } else if (reg == MC_ASOC_DVOL_DAC0OUT + && (mc_asoc_hpimpclass != (u8) -1 && + db > vreg_map[reg].volmap[0])) { + size = ARRAY_SIZE(volmap_digital) - 1; + db_max = volmap_digital[size]; + db += + dac0_vol_imp_table[mc_asoc_hpimpclass] << 8; + map = volmap_digital[0]; + if (db < map) + db = map; + else if (db > db_max) + db = db_max; + } + + *vp = db | MCDRV_VOL_UPDATE; + } + } + + return 0; +} + +static int set_volume(struct snd_soc_codec *codec, + struct mixer_path_ctl_info *mixer, int preset_idx) +{ + struct mcdrv_vol_info vol_info; + int err, reg; + + if (!codec) + return -EIO; + + memset(&vol_info, 0, sizeof(struct mcdrv_vol_info)); + + for (reg = MC_ASOC_DVOL_MUSICIN; reg < MC_ASOC_AVOL_SP_GAIN; reg++) { + err = set_vol_info(codec, &vol_info, reg, mixer, preset_idx); + if (err < 0) + return err; + } + + err = mc_control(MCDRV_SET_VOLUME, (unsigned long)&vol_info, 0); + if (err < 0) { + dev_err(codec->dev, "Error in MCDRV_SET_VOLUME: %d\n", err); + return -EIO; + } + + return 0; +} + +static inline void mask_source(u32 *src, int size) +{ + int i; + + for (i = 0; i < size; i++) + src[i] = 0x002aaaaa; +} + +static void mask_analog_out_source(struct mcdrv_path_info *path, + struct mixer_path_ctl_info *mixer, + int preset_idx) +{ + int output_path; + + output_path = mixer->output_path; + + if (output_path != MC_ASOC_OUTPUT_PATH_SP + && output_path != MC_ASOC_OUTPUT_PATH_SP_RC + && output_path != MC_ASOC_OUTPUT_PATH_SP_HP + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_SP_BT) + mask_source(path->sp, SP_PATH_CHANNELS); + + if (output_path != MC_ASOC_OUTPUT_PATH_RC + && output_path != MC_ASOC_OUTPUT_PATH_SP_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO1_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO2_RC) + mask_source(path->rc, RC_PATH_CHANNELS); + + if (output_path != MC_ASOC_OUTPUT_PATH_HP + && output_path != MC_ASOC_OUTPUT_PATH_HS + && output_path != MC_ASOC_OUTPUT_PATH_SP_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO1_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO2_HP) + mask_source(path->hp, HP_PATH_CHANNELS); + + if (output_path != MC_ASOC_OUTPUT_PATH_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_LO1_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO1_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO1_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO1_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_LO2_LO1) { + if (preset_idx < 12) { + if (mc_asoc_audio_cap_port == LOUT1) { + if (preset_idx <= 3 || preset_idx == 6 + || preset_idx == 7) + mask_source(path->lout1, + LOUT1_PATH_CHANNELS); + } else + mask_source(path->lout1, LOUT1_PATH_CHANNELS); + } else if (is_incall(preset_idx)) { + /* incall */ + if (mc_asoc_voice_port == LIN1_LOUT1) { + /* nothing to do */ + } else if (mc_asoc_audio_cap_port == LOUT1) { + if (preset_idx != 18 && preset_idx != 21 + && preset_idx != 56 && preset_idx != 59) + mask_source(path->lout1, + LOUT1_PATH_CHANNELS); + } else + mask_source(path->lout1, LOUT1_PATH_CHANNELS); + } else if (preset_idx == 24 || preset_idx >= 26) + mask_source(path->lout1, LOUT1_PATH_CHANNELS); + + } + + if (output_path != MC_ASOC_OUTPUT_PATH_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_LO2_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO2_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO2_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO1_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_LO2_LO1) { + if (preset_idx < 12) { + if (mc_asoc_audio_cap_port == LOUT2) { + if (preset_idx <= 3 || preset_idx == 6 + || preset_idx == 7) + mask_source(path->lout2, + LOUT2_PATH_CHANNELS); + } else + mask_source(path->lout2, LOUT2_PATH_CHANNELS); + } else if (is_incall(preset_idx)) { + if (mc_asoc_voice_port == LIN1_LOUT2) { + /* nothing to do */ + } else if (mc_asoc_audio_cap_port == LOUT2) { + if (preset_idx != 18 && preset_idx != 21 + && preset_idx != 56 && preset_idx != 59) + mask_source(path->lout2, + LOUT2_PATH_CHANNELS); + } else + mask_source(path->lout2, LOUT2_PATH_CHANNELS); + } else if (preset_idx == 24 || preset_idx >= 26) { + mask_source(path->lout2, LOUT2_PATH_CHANNELS); + } + } +} + +static void mask_bluetooth_out_source(struct mcdrv_path_info *path, + int output_path) +{ + int i; + + if (output_path != MC_ASOC_OUTPUT_PATH_BT + && output_path != MC_ASOC_OUTPUT_PATH_SP_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO1_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO2_BT) + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) + path->ext_out[i] = 0x00aaaaaa; +} + +static void mask_adc0_source(struct mcdrv_path_info *path, + struct mixer_path_ctl_info *mixer, int preset_idx) +{ + int input_path, output_path, incall_mic; + int main_mic_block_on = get_main_mic_block_on(); + int sub_mic_block_on = get_sub_mic_block_on(); + int hs_mic_block_on = get_hs_mic_block_on(); + int unused_mic_block_on = get_unused_mic_block_on(); + + if (!is_incall(preset_idx) && !is_incommunication(preset_idx)) { + /* !incall */ + if (preset_idx == 4 || preset_idx == 6 + || preset_idx == 8 || preset_idx == 10 + || preset_idx == 28 || preset_idx == 29 + || preset_idx == 30 || preset_idx == 32 + || preset_idx == 34 || preset_idx == 36 + || preset_idx == 46 || preset_idx == 48) { + /* in capture */ + input_path = mixer->input_path; + if (input_path != MC_ASOC_INPUT_PATH_MAINMIC + && input_path != MC_ASOC_INPUT_PATH_2MIC + && main_mic_block_on != -1) { + path->adc0[0] &= ~main_mic_block_on; + path->adc0[1] &= ~main_mic_block_on; + } + + if (input_path != MC_ASOC_INPUT_PATH_SUBMIC + && input_path != MC_ASOC_INPUT_PATH_2MIC + && sub_mic_block_on != -1) { + path->adc0[0] &= ~sub_mic_block_on; + path->adc0[1] &= ~sub_mic_block_on; + } + + if (input_path != MC_ASOC_INPUT_PATH_HS + && hs_mic_block_on != -1) { + path->adc0[0] &= ~hs_mic_block_on; + path->adc0[1] &= ~hs_mic_block_on; + } + + if (input_path == MC_ASOC_INPUT_PATH_2MIC) { + path->adc0[0] &= ~sub_mic_block_on; + path->adc0[1] &= ~main_mic_block_on; + } + + if (input_path != MC_ASOC_INPUT_PATH_LIN1) { + path->adc0[0] &= ~MCDRV_ASRC_LINEIN1_L_ON; + path->adc0[1] &= ~MCDRV_ASRC_LINEIN1_R_ON; + } + } else { + if (mixer->mainmic_play != 1 && mixer->msmic_play != 1 + && main_mic_block_on != -1) { + path->adc0[0] &= ~main_mic_block_on; + path->adc0[1] &= ~main_mic_block_on; + } + + if (mixer->submic_play != 1 && mixer->msmic_play != 1 + && sub_mic_block_on != -1) { + path->adc0[0] &= ~sub_mic_block_on; + path->adc0[1] &= ~sub_mic_block_on; + } + + if (mixer->hsmic_play != 1 && hs_mic_block_on != -1) { + path->adc0[0] &= ~hs_mic_block_on; + path->adc0[1] &= ~hs_mic_block_on; + } + + if (mixer->lin1_play != 1) { + path->adc0[0] &= ~MCDRV_ASRC_LINEIN1_ALL_ON; + path->adc0[1] &= ~MCDRV_ASRC_LINEIN1_ALL_ON; + } + } + } else { + /* incall or incommunication */ + output_path = mixer->output_path; + if (output_path != MC_ASOC_OUTPUT_PATH_BT + && output_path != MC_ASOC_OUTPUT_PATH_SP_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO1_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO2_BT) { + if (output_path != MC_ASOC_OUTPUT_PATH_HS) { + if (hs_mic_block_on != -1) { + path->adc0[0] &= ~hs_mic_block_on; + path->adc0[1] &= ~hs_mic_block_on; + } + + incall_mic = mixer->incall_mic; + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_2MIC + && main_mic_block_on != -1) { + path->adc0[0] &= ~main_mic_block_on; + path->adc0[1] &= ~main_mic_block_on; + } + + if (incall_mic != MC_ASOC_INCALL_MIC_SUBMIC + && incall_mic != MC_ASOC_INCALL_MIC_2MIC + && sub_mic_block_on != -1) { + path->adc0[0] &= ~sub_mic_block_on; + path->adc0[1] &= ~sub_mic_block_on; + } + + if (incall_mic == MC_ASOC_INCALL_MIC_2MIC) { + path->adc0[0] &= ~sub_mic_block_on; + path->adc0[1] &= ~main_mic_block_on; + } + } else { + if (main_mic_block_on != -1) { + path->adc0[0] &= ~main_mic_block_on; + path->adc0[1] &= ~main_mic_block_on; + } + + if (sub_mic_block_on != -1) { + path->adc0[0] &= ~sub_mic_block_on; + path->adc0[1] &= ~sub_mic_block_on; + } + } + } + } + + path->adc0[0] &= ~unused_mic_block_on; + path->adc0[1] &= ~unused_mic_block_on; +} + +static void mask_adc1_source(struct mcdrv_path_info *path, + struct mixer_path_ctl_info *mixer, int preset_idx) +{ + int input_path = mixer->input_path; + int main_mic_block_on = get_main_mic_block_on(); + int sub_mic_block_on = get_sub_mic_block_on(); + int hs_mic_block_on = get_hs_mic_block_on(); + int unused_mic_block_on = get_unused_mic_block_on(); + + /* !incall */ + if (preset_idx == 38 || preset_idx == 40 + || preset_idx == 42 || preset_idx == 44) { + /* in capture */ + if (input_path != MC_ASOC_INPUT_PATH_MAINMIC + && input_path != MC_ASOC_INPUT_PATH_2MIC + && main_mic_block_on != -1) + path->adc1[0] &= ~main_mic_block_on; + + if (input_path != MC_ASOC_INPUT_PATH_SUBMIC + && input_path != MC_ASOC_INPUT_PATH_2MIC + && sub_mic_block_on != -1) + path->adc1[0] &= ~sub_mic_block_on; + + if (input_path != MC_ASOC_INPUT_PATH_HS + && hs_mic_block_on != -1) + path->adc1[0] &= ~hs_mic_block_on; + + if (input_path != MC_ASOC_INPUT_PATH_LIN1) + path->adc1[0] &= ~MCDRV_ASRC_LINEIN1_M_ON; + } + + path->adc1[0] &= ~unused_mic_block_on; +} + +static void mask_dac_reference(struct mcdrv_path_info *path, int output_path) +{ + int i; + + switch (output_path) { + case MC_ASOC_OUTPUT_PATH_SP: + case MC_ASOC_OUTPUT_PATH_LO2: + case MC_ASOC_OUTPUT_PATH_SP_LO2: + case MC_ASOC_OUTPUT_PATH_SP_BT: + case MC_ASOC_OUTPUT_PATH_LO2_BT: + case MC_ASOC_OUTPUT_PATH_LO1_LO2: + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) + path->adif2[i] &= ~MCDRV_D2SRC_DAC0REF_ON; + break; + case MC_ASOC_OUTPUT_PATH_RC: + case MC_ASOC_OUTPUT_PATH_HP: + case MC_ASOC_OUTPUT_PATH_HS: + case MC_ASOC_OUTPUT_PATH_LO1: + case MC_ASOC_OUTPUT_PATH_LO1_RC: + case MC_ASOC_OUTPUT_PATH_LO1_HP: + case MC_ASOC_OUTPUT_PATH_LO1_BT: + case MC_ASOC_OUTPUT_PATH_SP_RC: + case MC_ASOC_OUTPUT_PATH_SP_HP: + case MC_ASOC_OUTPUT_PATH_SP_LO1: + case MC_ASOC_OUTPUT_PATH_LO2_RC: + case MC_ASOC_OUTPUT_PATH_LO2_HP: + case MC_ASOC_OUTPUT_PATH_LO2_LO1: + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) + path->adif2[i] &= ~MCDRV_D2SRC_DAC1REF_ON; + break; + default: + break; + } +} + +static void add_path_info(struct mcdrv_path_info *dst_path, + const struct mcdrv_path_info *src_path) +{ + int i; + + for (i = 0; i < MUSICOUT_PATH_CHANNELS; i++) + dst_path->music_out[i] |= src_path->music_out[i]; + + for (i = 0; i < EXTOUT_PATH_CHANNELS; i++) + dst_path->ext_out[i] |= src_path->ext_out[i]; + + for (i = 0; i < HIFIOUT_PATH_CHANNELS; i++) + dst_path->hifi_out[i] |= src_path->hifi_out[i]; + + for (i = 0; i < VBOXMIXIN_PATH_CHANNELS; i++) + dst_path->vbox_mix_in[i] |= src_path->vbox_mix_in[i]; + + for (i = 0; i < AE_PATH_CHANNELS; i++) { + dst_path->ae0[i] |= src_path->ae0[i]; + dst_path->ae1[i] |= src_path->ae1[i]; + dst_path->ae2[i] |= src_path->ae2[i]; + dst_path->ae3[i] |= src_path->ae3[i]; + } + + for (i = 0; i < DAC0_PATH_CHANNELS; i++) + dst_path->dac0[i] |= src_path->dac0[i]; + + for (i = 0; i < DAC1_PATH_CHANNELS; i++) + dst_path->dac1[i] |= src_path->dac1[i]; + + for (i = 0; i < VOICEOUT_PATH_CHANNELS; i++) + dst_path->voice_out[i] |= src_path->voice_out[i]; + + for (i = 0; i < VBOXIOIN_PATH_CHANNELS; i++) + dst_path->vbox_io_in[i] |= src_path->vbox_io_in[i]; + + for (i = 0; i < VBOXHOSTIN_PATH_CHANNELS; i++) + dst_path->vbox_host_in[i] |= src_path->vbox_host_in[i]; + + for (i = 0; i < HOSTOUT_PATH_CHANNELS; i++) + dst_path->host_out[i] |= src_path->host_out[i]; + + for (i = 0; i < ADIF0_PATH_CHANNELS; i++) + dst_path->adif0[i] |= src_path->adif0[i]; + + for (i = 0; i < ADIF1_PATH_CHANNELS; i++) + dst_path->adif1[i] |= src_path->adif1[i]; + + for (i = 0; i < ADIF2_PATH_CHANNELS; i++) + dst_path->adif2[i] |= src_path->adif2[i]; + + for (i = 0; i < ADC0_PATH_CHANNELS; i++) + dst_path->adc0[i] |= src_path->adc0[i]; + + for (i = 0; i < ADC1_PATH_CHANNELS; i++) + dst_path->adc1[i] |= src_path->adc1[i]; + + for (i = 0; i < HP_PATH_CHANNELS; i++) + dst_path->hp[i] |= src_path->hp[i]; + + for (i = 0; i < SP_PATH_CHANNELS; i++) + dst_path->sp[i] |= src_path->sp[i]; + + for (i = 0; i < RC_PATH_CHANNELS; i++) + dst_path->rc[i] |= src_path->rc[i]; + + for (i = 0; i < LOUT1_PATH_CHANNELS; i++) + dst_path->lout1[i] |= src_path->lout1[i]; + + for (i = 0; i < LOUT2_PATH_CHANNELS; i++) + dst_path->lout2[i] |= src_path->lout2[i]; + + for (i = 0; i < BIAS_PATH_CHANNELS; i++) + dst_path->bias[i] |= src_path->bias[i]; +} + +static void exchange_adc0_to_pdm(struct mcdrv_path_info *path, + u32 pdm_l_on, u32 pdm_r_on) +{ + if (pdm_l_on) { + path->adif1[0] &= ~MCDRV_D2SRC_ADC0_ON; + path->adif1[0] |= MCDRV_D2SRC_ADC0_OFF | pdm_l_on; + } + + if (pdm_r_on) { + path->adif1[1] &= ~MCDRV_D2SRC_ADC0_ON; + path->adif1[1] |= MCDRV_D2SRC_ADC0_OFF | pdm_r_on; + } +} + +static void exchange_adc1_to_pdm(struct mcdrv_path_info *path, + u32 pdm_l_on, u32 pdm_r_on) +{ + if (pdm_l_on) { + path->adif0[0] &= ~MCDRV_D2SRC_ADC1_ON; + path->adif0[0] |= MCDRV_D2SRC_ADC1_OFF | pdm_l_on; + } + + if (pdm_r_on) { + path->adif0[1] &= ~MCDRV_D2SRC_ADC1_ON; + path->adif0[1] |= MCDRV_D2SRC_ADC1_OFF | pdm_r_on; + } +} + +static void set_ain_play_path(struct mcdrv_path_info *path, + struct mixer_path_ctl_info *mixer, + int preset_idx, int ignore_input_path) +{ + int idx = analog_path_mapping[preset_idx]; + int input_path = mixer->input_path; + + if (idx >= ARRAY_SIZE(analog_input_path)) + return; + + if (mixer->mainmic_play == 1) { + if (ignore_input_path + || input_path == MC_ASOC_INPUT_PATH_MAINMIC) { + add_path_info(path, &analog_input_path[idx]); + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + mask_adc0_source(path, mixer, preset_idx); + mask_bluetooth_out_source(path, mixer->output_path); + return; + } + } + + if (mixer->submic_play == 1) { + if (ignore_input_path + || input_path == MC_ASOC_INPUT_PATH_SUBMIC) { + add_path_info(path, &analog_input_path[idx]); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + mask_adc0_source(path, mixer, preset_idx); + mask_bluetooth_out_source(path, mixer->output_path); + return; + } + } + + if (mixer->hsmic_play == 1) { + if (ignore_input_path || input_path == MC_ASOC_INPUT_PATH_HS) { + add_path_info(path, &analog_input_path[idx]); + if (mc_asoc_hs_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_hs_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + mask_adc0_source(path, mixer, preset_idx); + mask_bluetooth_out_source(path, mixer->output_path); + return; + } + } + + if (mixer->msmic_play == 1) { + if (ignore_input_path + || input_path == MC_ASOC_INPUT_PATH_2MIC) { + add_path_info(path, &analog_input_path[idx]); + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, 0); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + 0, MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + 0, MCDRV_D2SRC_PDM1_R_ON); + mask_adc0_source(path, mixer, preset_idx); + mask_bluetooth_out_source(path, mixer->output_path); + return; + } + } + + if (mixer->lin1_play == 1) { + if (ignore_input_path + || input_path == MC_ASOC_INPUT_PATH_LIN1) { + add_path_info(path, &analog_input_path[idx]); + mask_adc0_source(path, mixer, preset_idx); + mask_bluetooth_out_source(path, mixer->output_path); + return; + } + } +} + +static inline void set_bias(struct mcdrv_path_info *path) +{ + int mic_bias[BIAS_PATH_CHANNELS] = { + mc_asoc_mic1_bias, + mc_asoc_mic2_bias, + mc_asoc_mic3_bias, + mc_asoc_mic4_bias + }; + u32 on[BIAS_PATH_CHANNELS] = { + MCDRV_ASRC_MIC1_ON, + MCDRV_ASRC_MIC2_ON, + MCDRV_ASRC_MIC3_ON, + MCDRV_ASRC_MIC4_ON + }; + int i, j; + + for (i = 0; i < BIAS_PATH_CHANNELS; i++) { + switch (mic_bias[i]) { + case BIAS_ON_ALWAYS: + path->bias[i] |= on[i]; + break; + case BIAS_OFF: + path->bias[i] &= ~on[i]; + break; + case BIAS_SYNC_MIC: + path->bias[i] &= ~on[i]; + for (j = 0; j < ADC0_PATH_CHANNELS; j++) { + if (path->adc0[j] & on[i]) { + path->bias[i] |= on[i]; + break; + } + } + + for (j = 0; j < ADC1_PATH_CHANNELS; j++) { + if (path->adc1[j] & on[i]) { + path->bias[i] |= on[i]; + break; + } + } + break; + default: + break; + } + } + + if (path->hp[0] & MCDRV_ASRC_DAC0_L_ON + || path->hp[1] & MCDRV_ASRC_DAC0_R_ON) { + if (mc_asoc_jack_status) + path->bias[3] |= MCDRV_ASRC_MIC4_ON; + } +} + +static void get_path_info(struct mcdrv_path_info *path, + struct mixer_path_ctl_info *mixer, int preset_idx) +{ + const struct mcdrv_path_info *preset_path; + size_t offset; + bool mute_dit = false, ain_play = false; + int input_path, output_path, audio_mode_play, audio_mode_cap, idx; + + if (mixer->mainmic_play == 1 || mixer->submic_play == 1 + || mixer->msmic_play == 1 || mixer->hsmic_play == 1 + || mixer->lin1_play == 1) + ain_play = true; + + preset_path = &mc_preset_path_info[preset_idx]; + input_path = mixer->input_path; + output_path = mixer->output_path; + audio_mode_play = mixer->audio_mode_play; + audio_mode_cap = mixer->audio_mode_cap; + + if (mixer->dtmf_control == 1) { + if (!(mixer->dtmf_output == MC_ASOC_DTMF_OUTPUT_SP + && output_path != MC_ASOC_OUTPUT_PATH_SP)) { + idx = dtmf_path_mapping[preset_idx]; + if (idx >= ARRAY_SIZE(dtmf_path)) + return; + + add_path_info(path, &dtmf_path[idx]); + mask_analog_out_source(path, mixer, preset_idx); + mask_bluetooth_out_source(path, output_path); + } + } + + if (is_incommunication(preset_idx)) { + if (output_path == MC_ASOC_OUTPUT_PATH_BT) { + add_path_info(path, preset_path); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else if (output_path == MC_ASOC_OUTPUT_PATH_SP_BT + || output_path == MC_ASOC_OUTPUT_PATH_LO1_BT + || output_path == MC_ASOC_OUTPUT_PATH_LO2_BT) { + add_path_info(path, preset_path); + mask_analog_out_source(path, mixer, preset_idx); + path->vbox_mix_in[1] = 0x00aaaaaa; + mask_dac_reference(path, output_path); + } else { + add_path_info(path, preset_path); + + switch (mixer->incall_mic) { + case MC_ASOC_INCALL_MIC_MAINMIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + path->vbox_mix_in[1] = 0x00aaaaaa; + break; + case MC_ASOC_INCALL_MIC_SUBMIC: + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + path->vbox_mix_in[1] = 0x00aaaaaa; + break; + default: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + 0); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + 0, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + 0, + MCDRV_D2SRC_PDM1_R_ON); + break; + } + + mask_dac_reference(path, output_path); + mask_adc0_source(path, mixer, preset_idx); + mask_analog_out_source(path, mixer, preset_idx); + } + + return; + } + + if ((preset_idx >= 12 && preset_idx <= 17) + || (preset_idx >= 50 && preset_idx <= 55)) { + if (output_path == MC_ASOC_OUTPUT_PATH_BT) { + add_path_info(path, preset_path); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else if (output_path == MC_ASOC_OUTPUT_PATH_SP_BT + || output_path == MC_ASOC_OUTPUT_PATH_LO1_BT + || output_path == MC_ASOC_OUTPUT_PATH_LO2_BT) { + add_path_info(path, preset_path); + mask_analog_out_source(path, mixer, preset_idx); + path->vbox_mix_in[1] = 0x00aaaaaa; + mask_dac_reference(path, output_path); + } else { + add_path_info(path, preset_path); + if (mixer->incall_mic == MC_ASOC_INCALL_MIC_MAINMIC) { + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else if (mixer->incall_mic == + MC_ASOC_INCALL_MIC_SUBMIC) { + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else { + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + 0); + + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM1_R_ON); + + } + + mask_adc0_source(path, mixer, preset_idx); + mask_analog_out_source(path, mixer, preset_idx); + mask_dac_reference(path, output_path); + } + + return; + } + + if ((preset_idx >= 18 && preset_idx <= 23) + || (preset_idx >= 56 && preset_idx <= 61)) { + if (output_path == MC_ASOC_OUTPUT_PATH_BT) { + add_path_info(path, preset_path); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else if (output_path == MC_ASOC_OUTPUT_PATH_SP_BT + || output_path == MC_ASOC_OUTPUT_PATH_LO1_BT + || output_path == MC_ASOC_OUTPUT_PATH_LO2_BT) { + add_path_info(path, preset_path); + mask_analog_out_source(path, mixer, preset_idx); + path->vbox_mix_in[1] = 0x00aaaaaa; + mask_dac_reference(path, output_path); + } else { + add_path_info(path, preset_path); + if (mixer->incall_mic == MC_ASOC_INCALL_MIC_MAINMIC) { + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else if (mixer->incall_mic == + MC_ASOC_INCALL_MIC_SUBMIC) { + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + path->vbox_mix_in[1] = 0x00aaaaaa; + } else { + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + 0); + + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM1_R_ON); + } + + mask_adc0_source(path, mixer, preset_idx); + mask_analog_out_source(path, mixer, preset_idx); + mask_dac_reference(path, output_path); + } + + return; + } + + if (mixer->btmic_play == 1) { + idx = bt_path_mapping[preset_idx]; + if (bt_path_mapping[preset_idx] < ARRAY_SIZE(bt_input_path)) { + add_path_info(path, &bt_input_path[idx]); + mask_bluetooth_out_source(path, output_path); + } + } + + if ((preset_idx >= 1 && preset_idx <= 3) || preset_idx == 27) { + if (ain_play) + set_ain_play_path(path, mixer, preset_idx, 1); + add_path_info(path, preset_path); + } else if (preset_idx == 4 || preset_idx == 5 || preset_idx == 28 + || preset_idx == 30 || preset_idx == 31) { + if (input_path != MC_ASOC_INPUT_PATH_VOICECALL + && input_path != MC_ASOC_INPUT_PATH_VOICEUPLINK + && input_path != MC_ASOC_INPUT_PATH_VOICEDOWNLINK) { + if (ain_play == 1) { + if (input_path == MC_ASOC_INPUT_PATH_BT) + set_ain_play_path(path, mixer, + preset_idx, 1); + else + set_ain_play_path(path, mixer, + preset_idx, 0); + } + + add_path_info(path, preset_path); + switch (input_path) { + case MC_ASOC_INPUT_PATH_MAINMIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_SUBMIC: + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_2MIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + 0); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_HS: + if (mc_asoc_hs_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_hs_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + default: + break; + } + + mask_adc0_source(path, mixer, preset_idx); + if (input_path != MC_ASOC_INPUT_PATH_2MIC) + path->vbox_mix_in[1] = 0x00aaaaaa; + } else { + add_path_info(path, preset_path); + mute_dit = true; + } + } else if ((preset_idx >= 6 && preset_idx <= 11) + || preset_idx == 29 + || (preset_idx >= 32 && preset_idx <= 37)) { + if (input_path != MC_ASOC_INPUT_PATH_VOICECALL + && input_path != MC_ASOC_INPUT_PATH_VOICEUPLINK + && input_path != MC_ASOC_INPUT_PATH_VOICEDOWNLINK) { + if (ain_play == 1) { + if (input_path == MC_ASOC_INPUT_PATH_BT) + set_ain_play_path(path, mixer, + preset_idx, 1); + else + set_ain_play_path(path, mixer, + preset_idx, 0); + } + + add_path_info(path, preset_path); + switch (input_path) { + case MC_ASOC_INPUT_PATH_MAINMIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_SUBMIC: + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_2MIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + 0); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, 0, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_HS: + if (mc_asoc_hs_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_hs_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + default: + break; + } + + mask_adc0_source(path, mixer, preset_idx); + if (input_path != MC_ASOC_INPUT_PATH_2MIC) + path->vbox_mix_in[1] = 0x00aaaaaa; + } else { + add_path_info(path, preset_path); + mute_dit = true; + } + } else if (preset_idx >= 38 && preset_idx <= 45) { + if (ain_play == 1) + set_ain_play_path(path, mixer, preset_idx, 1); + if (input_path != MC_ASOC_INPUT_PATH_VOICECALL + && input_path != MC_ASOC_INPUT_PATH_VOICEUPLINK + && input_path != MC_ASOC_INPUT_PATH_VOICEDOWNLINK) { + add_path_info(path, preset_path); + switch (input_path) { + case MC_ASOC_INPUT_PATH_MAINMIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_SUBMIC: + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_2MIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + 0); + if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + 0); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc1_to_pdm(path, 0, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc1_to_pdm(path, 0, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_HS: + if (mc_asoc_hs_mic == MIC_PDM0) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_hs_mic == MIC_PDM1) + exchange_adc1_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + default: + break; + } + mask_adc1_source(path, mixer, preset_idx); + } else { + add_path_info(path, preset_path); + mute_dit = true; + } + } else if (preset_idx == 46 || preset_idx == 47 + || preset_idx == 48 || preset_idx == 49) { + add_path_info(path, preset_path); + switch (input_path) { + case MC_ASOC_INPUT_PATH_MAINMIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_SUBMIC: + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_2MIC: + if (mc_asoc_main_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, 0); + else if (mc_asoc_main_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, 0); + if (mc_asoc_sub_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + 0, MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_sub_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + 0, MCDRV_D2SRC_PDM1_R_ON); + break; + case MC_ASOC_INPUT_PATH_HS: + if (mc_asoc_hs_mic == MIC_PDM0) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM0_L_ON, + MCDRV_D2SRC_PDM0_R_ON); + else if (mc_asoc_hs_mic == MIC_PDM1) + exchange_adc0_to_pdm(path, + MCDRV_D2SRC_PDM1_L_ON, + MCDRV_D2SRC_PDM1_R_ON); + break; + default: + break; + } + + mask_adc0_source(path, mixer, preset_idx); + } else if (ain_play == 1) + set_ain_play_path(path, mixer, preset_idx, 1); + + mask_analog_out_source(path, mixer, preset_idx); + if (preset_idx < 4 || CAPTURE_PORT != CAPTURE_PORT_EXT) + mask_bluetooth_out_source(path, output_path); + + offset = vreg_map[MC_ASOC_DVOL_EXTOUT].offset; + set_vol_mute_flag(offset, 0, 0); + set_vol_mute_flag(offset, 1, 0); + + offset = vreg_map[MC_ASOC_DVOL_MUSICOUT].offset; + set_vol_mute_flag(offset, 0, 0); + set_vol_mute_flag(offset, 1, 0); + if (CAPTURE_PORT == CAPTURE_PORT_EXT) { + if (preset_idx >= 4) { + path->ext_out[0] = path->music_out[0]; + path->music_out[0] = 0x00aaaaaa; + path->ext_out[1] = path->music_out[1]; + path->music_out[1] = 0x00aaaaaa; + if (mute_dit) { + offset = vreg_map[MC_ASOC_DVOL_EXTOUT].offset; + set_vol_mute_flag(offset, 0, 1); + set_vol_mute_flag(offset, 1, 1); + } + } + } else if (mute_dit) { + offset = vreg_map[MC_ASOC_DVOL_MUSICOUT].offset; + set_vol_mute_flag(offset, 0, 1); + set_vol_mute_flag(offset, 1, 1); + } +} + +static void set_adif_source(u8 src, u32 *onoff) +{ + switch (src) { + case 1: + /* ADC0L */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_ADC0_L_ON; + break; + case 2: + /* ADC0R */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_ADC0_R_ON; + break; + case 3: + /* ADC1 */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_ADC1_ON; + break; + case 4: + /* PDM0L */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_PDM0_L_ON; + break; + case 5: + /* PDM0R */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_PDM0_R_ON; + break; + case 6: + /* PDM1L */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_PDM1_L_ON; + break; + case 7: + /* PDM1R */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_PDM1_R_ON; + break; + case 8: + /* DAC0REF */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_DAC0REF_ON; + break; + case 9: + /* DAC1REF */ + *onoff = 0x00aaaaaa | MCDRV_D2SRC_DAC1REF_ON; + break; + default: + break; + } +} + +static int connect_path(struct snd_soc_codec *codec) +{ + struct mixer_path_ctl_info mixer_info; + struct mcdrv_path_info path_info; + int preset_idx = 0; + int cache; + int err; + + if (get_mixer_path_ctl_info(codec, &mixer_info) < 0) + return -EIO; + + preset_idx = get_path_preset_idx(&mixer_info); + if (preset_idx < 0 || preset_idx > PRESET_PATH_N) + return -EIO; + + memcpy(&path_info, &mc_preset_path_info[0], + sizeof(struct mcdrv_path_info)); + get_path_info(&path_info, &mixer_info, preset_idx); + set_bias(&path_info); + + cache = read_cache(codec, MC_ASOC_ADIF0_SOURCE); + if (cache < 0) + return -EIO; + if ((cache & 0xff) && (cache & 0xff00)) { + set_adif_source(cache, &path_info.adif0[0]); + set_adif_source(cache >> 8, &path_info.adif0[1]); + } + + cache = read_cache(codec, MC_ASOC_ADIF1_SOURCE); + if (cache < 0) + return -EIO; + if ((cache & 0xff) && (cache & 0xff00)) { + set_adif_source(cache, &path_info.adif1[0]); + set_adif_source(cache >> 8, &path_info.adif1[1]); + } + + cache = read_cache(codec, MC_ASOC_ADIF2_SOURCE); + if (cache < 0) + return -EIO; + if ((cache & 0xff) && (cache & 0xff00)) { + set_adif_source(cache, &path_info.adif2[0]); + set_adif_source(cache >> 8, &path_info.adif2[1]); + } + + err = set_volume(codec, &mixer_info, preset_idx); + if (err < 0) + return err; + + err = mc_control(MCDRV_SET_PATH, (unsigned long)&path_info, 0); + if (err < 0) + return err; + + return err; +} + +/* + * DAI (PCM interface) + */ +static int is_dio_modified(struct mcdrv_dio_port *dio_port, + int id, int mode, u32 update) +{ + struct mcdrv_dio_info dio_info; + struct mcdrv_dio_common *comm1, *comm2; + struct mcdrv_dio_dir *dir1, *dir2; + struct mcdrv_dio_dit *dit1, *dit2; + int err; + + err = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio_info, 0); + if (err < 0) + return err; + + comm1 = &dio_info.port[id].dio_common; + comm2 = &dio_port->dio_common; + + if (update & (MCDRV_MUSIC_COM_UPDATE_FLAG | MCDRV_EXT_COM_UPDATE_FLAG | + MCDRV_HIFI_COM_UPDATE_FLAG)) { + if (comm1->master_slave != comm2->master_slave + || comm1->auto_fs != comm2->auto_fs + || comm1->fs != comm2->fs + || comm1->bck_fs != comm2->bck_fs + || comm1->interface != comm2->interface + || comm1->bck_invert != comm2->bck_invert + || comm1->src_thru != comm2->src_thru) + return 1; + + if (mode == MCDRV_DIO_PCM + && (comm1->pcm_hiz_transition != comm2->pcm_hiz_transition + || comm1->pcm_frame != comm2->pcm_frame + || comm1->pcm_high_period != comm2->pcm_high_period)) + return 1; + } + + dir1 = &dio_info.port[id].dir; + dir2 = &dio_port->dir; + + if (update + & (MCDRV_MUSIC_DIR_UPDATE_FLAG | MCDRV_HIFI_DIR_UPDATE_FLAG)) { + if (mode == MCDRV_DIO_DA + && (dir1->da_format.bit_sel != dir2->da_format.bit_sel + || dir1->da_format.mode != dir2->da_format.mode)) + return 1; + + if (mode != MCDRV_DIO_DA + && (dir1->pcm_format.mono != dir2->pcm_format.mono + || dir1->pcm_format.order != dir2->pcm_format.order + || dir1->pcm_format.law != dir2->pcm_format.law + || dir1->pcm_format.bit_sel != + dir2->pcm_format.bit_sel)) + return 1; + } + + dit1 = &dio_info.port[id].dit; + dit2 = &dio_port->dit; + + if (update & (MCDRV_MUSIC_DIT_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG | + MCDRV_HIFI_DIT_UPDATE_FLAG)) { + if (mode == MCDRV_DIO_DA + && (dit1->da_format.bit_sel != dit2->da_format.bit_sel + || dit1->da_format.mode != dit2->da_format.mode)) + return 1; + + if (mode != MCDRV_DIO_DA + && (dit1->pcm_format.mono != dit2->pcm_format.mono + || dit1->pcm_format.order != dit2->pcm_format.order + || dit1->pcm_format.law != dit2->pcm_format.law + || dit1->pcm_format.bit_sel != + dit2->pcm_format.bit_sel)) + return 1; + } + + return 0; +} + +static int setup_dai(struct snd_soc_codec *codec, + struct mc_asoc_data *mc_asoc, int id, int mode, int dir) +{ + struct mcdrv_dio_info dio; + struct mcdrv_dio_port *port = &dio.port[id]; + struct mc_asoc_port_params *port_params = &mc_asoc->port; + struct mcdrv_path_info path, tmp_path; + u32 update = 0; + int ch, err, modify; + + err = mc_control(MCDRV_GET_PATH, (unsigned long)&path, 0); + if (err < 0) + return err; + + memset(&dio, 0, sizeof(struct mcdrv_dio_info)); + + if (port_params->stream == 0) { + port->dio_common.master_slave = port_params->master; + port->dio_common.auto_fs = MCDRV_AUTOFS_OFF; + port->dio_common.fs = port_params->rate; + port->dio_common.bck_fs = port_params->bckfs; + port->dio_common.interface = mode; + port->dio_common.bck_invert = port_params->inv; + port->dio_common.src_thru = port_params->srcthru; + if (mode == MCDRV_DIO_PCM) + port->dio_common.pcm_frame = port_params->format; + switch (id) { + case 0: + update |= MCDRV_MUSIC_COM_UPDATE_FLAG; + break; + case 1: + update |= MCDRV_EXT_COM_UPDATE_FLAG; + break; + case 3: + update |= MCDRV_HIFI_COM_UPDATE_FLAG; + default: + break; + } + } + + if (dir == SNDRV_PCM_STREAM_PLAYBACK) { + if (mode == MCDRV_DIO_DA) { + port->dir.da_format.bit_sel = port_params->bits[dir]; + port->dir.da_format.mode = port_params->format; + } else { + port->dir.pcm_format.mono = port_params->pcm_mono[dir]; + port->dir.pcm_format.order = + port_params->pcm_order[dir]; + port->dir.pcm_format.law = port_params->pcm_law[dir]; + port->dir.pcm_format.bit_sel = port_params->bits[dir]; + } + + switch (id) { + case 0: + update |= MCDRV_MUSIC_DIR_UPDATE_FLAG; + break; + case 3: + update |= MCDRV_HIFI_DIR_UPDATE_FLAG; + break; + default: + break; + } + } + + if (dir == SNDRV_PCM_STREAM_CAPTURE) { + if (mode == MCDRV_DIO_DA) { + port->dit.da_format.bit_sel = port_params->bits[dir]; + port->dit.da_format.mode = port_params->format; + } else { + port->dit.pcm_format.mono = port_params->pcm_mono[dir]; + port->dit.pcm_format.order = + port_params->pcm_order[dir]; + port->dit.pcm_format.law = port_params->pcm_law[dir]; + port->dit.pcm_format.bit_sel = port_params->bits[dir]; + } + + switch (id) { + case 0: + update |= MCDRV_MUSIC_DIT_UPDATE_FLAG; + break; + case 1: + update |= MCDRV_EXT_DIT_UPDATE_FLAG; + break; + case 3: + update |= MCDRV_HIFI_DIT_UPDATE_FLAG; + break; + default: + break; + } + } + + modify = is_dio_modified(port, id, mode, update); + if (modify < 0) + return -EIO; + if (modify == 0) + return 0; + + memcpy(&tmp_path, &path, sizeof(struct mcdrv_path_info)); + if (dir == SNDRV_PCM_STREAM_PLAYBACK || !port_params->stream) { + switch (id) { + case 0: + for (ch = 0; ch < MUSICOUT_PATH_CHANNELS; ch++) { + tmp_path.music_out[ch] &= + ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.music_out[ch] |= + MCDRV_D1SRC_MUSICIN_OFF; + } + + for (ch = 0; ch < EXTOUT_PATH_CHANNELS; ch++) { + tmp_path.ext_out[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.ext_out[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + } + + for (ch = 0; ch < VBOXMIXIN_PATH_CHANNELS; ch++) { + tmp_path.vbox_mix_in[ch] &= + ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.vbox_mix_in[ch] |= + MCDRV_D1SRC_MUSICIN_OFF; + } + + for (ch = 0; ch < AE_PATH_CHANNELS; ch++) { + tmp_path.ae0[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.ae0[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + tmp_path.ae1[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.ae1[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + tmp_path.ae2[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.ae2[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + tmp_path.ae3[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.ae3[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + } + + for (ch = 0; ch < DAC0_PATH_CHANNELS; ch++) { + tmp_path.dac0[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.dac0[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + } + + for (ch = 0; ch < DAC1_PATH_CHANNELS; ch++) { + tmp_path.dac1[ch] &= ~MCDRV_D1SRC_MUSICIN_ON; + tmp_path.dac1[ch] |= MCDRV_D1SRC_MUSICIN_OFF; + } + break; + case 3: + for (ch = 0; ch < DAC0_PATH_CHANNELS; ch++) { + tmp_path.dac0[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + tmp_path.dac0[ch] |= MCDRV_D1SRC_HIFIIN_OFF; + } + + for (ch = 0; ch < DAC1_PATH_CHANNELS; ch++) { + tmp_path.dac1[ch] &= ~MCDRV_D1SRC_HIFIIN_ON; + tmp_path.dac1[ch] |= MCDRV_D1SRC_HIFIIN_OFF; + } + break; + default: + break; + } + } + + if (dir == SNDRV_PCM_STREAM_CAPTURE || !port_params->stream) { + switch (id) { + case 0: + for (ch = 0; ch < MUSICOUT_PATH_CHANNELS; ch++) + tmp_path.music_out[ch] = 0x00aaaaaa; + break; + case 1: + for (ch = 0; ch < EXTOUT_PATH_CHANNELS; ch++) + tmp_path.ext_out[ch] = 0x00aaaaaa; + break; + case 3: + for (ch = 0; ch < HIFIOUT_PATH_CHANNELS; ch++) + tmp_path.hifi_out[ch] = 0x00aaaaaa; + break; + default: + break; + } + } + + if (!memcmp(&tmp_path, &path, sizeof(struct mcdrv_path_info))) + modify = 0; + else { + err = mc_control(MCDRV_SET_PATH, (unsigned long)&tmp_path, 0); + if (err < 0) + return err; + } + + err = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, update); + if (err < 0) + return err; + + if (modify) + return connect_path(codec); + + return 0; +} + +static int mc_asoc_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) +{ + struct mc_asoc_data *mc_asoc; + struct mc_asoc_port_params *port; + + if (!dai || !dai->codec || get_port_id(dai->id)) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(dai->codec); + if (!mc_asoc) + return -EINVAL; + + port = &mc_asoc->port; + + if (div_id == MC_ASOC_BCLK_MULT) { + switch (div) { + case MC_ASOC_LRCK_X64: + port->bckfs = MCDRV_BCKFS_64; + break; + case MC_ASOC_LRCK_X48: + port->bckfs = MCDRV_BCKFS_48; + break; + case MC_ASOC_LRCK_X32: + port->bckfs = MCDRV_BCKFS_32; + break; + case MC_ASOC_LRCK_X512: + port->bckfs = MCDRV_BCKFS_512; + break; + case MC_ASOC_LRCK_X256: + port->bckfs = MCDRV_BCKFS_256; + break; + case MC_ASOC_LRCK_X192: + port->bckfs = MCDRV_BCKFS_192; + break; + case MC_ASOC_LRCK_X128: + port->bckfs = MCDRV_BCKFS_128; + break; + case MC_ASOC_LRCK_X96: + port->bckfs = MCDRV_BCKFS_96; + break; + case MC_ASOC_LRCK_X24: + port->bckfs = MCDRV_BCKFS_24; + break; + case MC_ASOC_LRCK_X16: + port->bckfs = MCDRV_BCKFS_16; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int mc_asoc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mc_asoc_data *mc_asoc; + struct mc_asoc_port_params *port; + + if (!dai || !dai->codec || get_port_id(dai->id)) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(dai->codec); + if (!mc_asoc) + return -EINVAL; + + port = &mc_asoc->port; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + port->format = MCDRV_DAMODE_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + port->format = MCDRV_DAMODE_TAILALIGN; + break; + case SND_SOC_DAIFMT_LEFT_J: + port->format = MCDRV_DAMODE_HEADALIGN; + break; + case SND_SOC_DAIFMT_DSP_A: + port->format = MCDRV_PCM_SHORTFRAME; + break; + case SND_SOC_DAIFMT_DSP_B: + port->format = MCDRV_PCM_LONGFRAME; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + port->master = MCDRV_DIO_MASTER; + break; + case SND_SOC_DAIFMT_CBS_CFS: + port->master = MCDRV_DIO_SLAVE; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + port->inv = MCDRV_BCLK_NORMAL; + break; + case SND_SOC_DAIFMT_IB_NF: + port->inv = MCDRV_BCLK_INVERT; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mc_asoc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec; + struct mc_asoc_data *mc_asoc; + struct mc_asoc_port_params *port; + struct mcdrv_dio_path_info dio_path; + int dir = substream->stream; + int id, rate, err = 0; + + if (!substream || !dai) + return -EINVAL; + + id = get_port_id(dai->id); + if (id) + return -EINVAL; + + codec = dai->codec; + if (!codec) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + port = &mc_asoc->port; + + switch (params_channels(params)) { + case 1: + port->pcm_mono[dir] = MCDRV_PCM_MONO; + port->channels = MCDRV_MUSIC_2CH; + break; + case 2: + port->channels = MCDRV_MUSIC_2CH; + port->pcm_mono[dir] = MCDRV_PCM_STEREO; + break; + case 4: + port->channels = MCDRV_MUSIC_4CH; + port->pcm_mono[dir] = MCDRV_PCM_STEREO; + break; + case 6: + port->channels = MCDRV_MUSIC_6CH; + port->pcm_mono[dir] = MCDRV_PCM_STEREO; + break; + default: + return -EINVAL; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + port->bits[dir] = MCDRV_BITSEL_16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + port->bits[dir] = MCDRV_BITSEL_20; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + port->bits[dir] = MCDRV_BITSEL_24; + break; + default: + return -EINVAL; + } + + if (dir == SNDRV_PCM_STREAM_PLAYBACK) { + port->pcm_order[dir] = music_port_def.dir.pcm_format.order; + port->pcm_law[dir] = music_port_def.dir.pcm_format.law; + } else { + port->pcm_order[dir] = music_port_def.dit.pcm_format.order; + port->pcm_law[dir] = music_port_def.dit.pcm_format.law; + } + + switch (params_rate(params)) { + case 8000: + rate = MCDRV_FS_8000; + break; + case 11025: + rate = MCDRV_FS_11025; + break; + case 16000: + rate = MCDRV_FS_16000; + break; + case 22050: + rate = MCDRV_FS_22050; + break; + case 32000: + rate = MCDRV_FS_32000; + break; + case 44100: + rate = MCDRV_FS_44100; + break; + case 48000: + rate = MCDRV_FS_48000; + break; + case 96000: + rate = MCDRV_FS_96000; + break; + case 192000: + rate = MCDRV_FS_192000; + break; + default: + return -EINVAL; + } + + mutex_lock(&mc_asoc->mutex); + + if (CAPTURE_PORT == CAPTURE_PORT_MUSIC) + if ((port->stream & ~(1 << dir)) && rate != port->rate) { + err = -EBUSY; + goto error; + } + + port->rate = rate; + + if (rate == MCDRV_FS_96000 || rate == MCDRV_FS_192000) { + struct mixer_path_ctl_info mixer_info; + int preset_idx; + + if (get_mixer_path_ctl_info(codec, &mixer_info) < 0) { + err = -EIO; + goto error; + } + + preset_idx = get_path_preset_idx(&mixer_info); + if (is_incall(preset_idx) || is_incommunication(preset_idx)) { + err = -EINVAL; + goto error; + } + } + + if (rate == MCDRV_FS_96000 || rate == MCDRV_FS_192000) { + id = 3; + } else { + dio_path.music_ch = port->channels; + err = mc_control(MCDRV_SET_DIGITALIO_PATH, + (unsigned long)&dio_path, + MCDRV_MUSICNUM_UPDATE_FLAG); + if (err < 0) { + dev_err(codec->dev, + "Error in MCDRV_SET_DIGITALIO_PATH: %d\n", err); + goto error; + } + + if (dir == SNDRV_PCM_STREAM_CAPTURE + && CAPTURE_PORT == CAPTURE_PORT_EXT) + id = 1; + } + + err = setup_dai(codec, mc_asoc, id, MCDRV_DIO_DA, dir); + if (err < 0) { + dev_err(codec->dev, "Error in setup_dai: %d\n", err); + goto error; + } + + port->stream |= 1 << dir; + mc_asoc_rate = rate; + +error: + mutex_unlock(&mc_asoc->mutex); + + return err; +} + +static int mc_asoc_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec; + struct mc_asoc_data *mc_asoc; + struct mc_asoc_port_params *port; + int dir = substream->stream; + + if (!substream || !dai || get_port_id(dai->id)) + return -EINVAL; + + codec = dai->codec; + if (!codec) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + port = &mc_asoc->port; + + mutex_lock(&mc_asoc->mutex); + + if (port->stream & (1 << dir)) + port->stream &= ~(1 << dir); + + mutex_unlock(&mc_asoc->mutex); + + return 0; +} + +static struct snd_soc_dai_ops mc_asoc_dai_ops[] = { + { + .set_clkdiv = mc_asoc_set_clkdiv, + .set_fmt = mc_asoc_set_fmt, + .hw_params = mc_asoc_hw_params, + .hw_free = mc_asoc_hw_free, + }, +}; + +static struct snd_soc_dai_driver mc_asoc_dai[] = { + { + .name = MC_ASOC_NAME "-da0", + .id = 1, + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 6, + .rates = MC_ASOC_RATE, + .formats = MC_ASOC_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MC_ASOC_RATE, + .formats = MC_ASOC_FORMATS, + }, + .ops = &mc_asoc_dai_ops[0] + }, +}; + +/* + * Control interface + */ +/* + * Virtual register + * + * 16bit software registers are implemented for volumes and mute + * switches (as an exception, no mute switches for MIC and HP gain). + * Register contents are stored in codec's register cache. + * + * 15 14 8 7 0 + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * |swR| volume-R |swL| volume-L | + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + */ + +static unsigned int mc_asoc_read_reg(struct snd_soc_codec *codec, + unsigned int reg) +{ + int ret; + + if (!codec) + return -EINVAL; + + ret = read_cache(codec, reg); + if (ret < 0) + return -EIO; + + return (unsigned int)ret; +} + +static int write_reg_vol(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + struct mcdrv_vol_info vol; + struct mixer_path_ctl_info mixer; + int err, preset_idx; + + err = snd_soc_cache_write(codec, reg, value); + if (err < 0) + dev_err(codec->dev, "Cache write to 0x%x failed: %d\n", reg, + err); + + if (get_mixer_path_ctl_info(codec, &mixer) < 0) + return -EIO; + + preset_idx = get_path_preset_idx(&mixer); + if (preset_idx < 0 || preset_idx > PRESET_PATH_N) + return -EIO; + + memset(&vol, 0, sizeof(struct mcdrv_vol_info)); + + switch (reg) { + case MC_ASOC_AVOL_SP_GAIN: + if (!mc_asoc_ver_id) { + vreg_map[MC_ASOC_AVOL_SP].volmap = volmap_sp[value]; + reg = MC_ASOC_AVOL_SP; + } else + return 0; + break; + case MC_ASOC_DVOL_MASTER: + if (mc_asoc_audio_play_port == LIN1) + reg = MC_ASOC_DVOL_ADIF1IN; + else + reg = MC_ASOC_DVOL_MUSICIN; + break; + case MC_ASOC_DVOL_VOICE: + if (is_incall(preset_idx)) { + reg = MC_ASOC_DVOL_VOICEIN; + if (mc_asoc_voice_port == LIN1_LOUT1 + || mc_asoc_voice_port == LIN1_LOUT2) + reg = MC_ASOC_AVOL_LINEIN1; + } else + return 0; + break; + case MC_ASOC_DVOL_APLAY_A: + reg = MC_ASOC_AVOL_MIC1; + err = set_vol_info(codec, &vol, reg, &mixer, preset_idx); + if (err < 0) + return err; + + reg = MC_ASOC_AVOL_MIC2; + err = set_vol_info(codec, &vol, reg, &mixer, preset_idx); + if (err < 0) + return err; + + reg = MC_ASOC_AVOL_MIC3; + err = set_vol_info(codec, &vol, reg, &mixer, preset_idx); + if (err < 0) + return err; + + reg = MC_ASOC_AVOL_MIC4; + err = set_vol_info(codec, &vol, reg, &mixer, preset_idx); + if (err < 0) + return err; + + reg = MC_ASOC_AVOL_LINEIN1; + break; + case MC_ASOC_DVOL_APLAY_D: + reg = MC_ASOC_DVOL_ADIF1IN; + break; + case MC_ASOC_VOICE_RECORDING: + if (is_incall(preset_idx)) { + reg = MC_ASOC_DVOL_VOICEOUT; + if (mc_asoc_voice_port == LIN1_LOUT1) + reg = MC_ASOC_DVOL_DAC0OUT; + else if (mc_asoc_voice_port == LIN1_LOUT2) + reg = MC_ASOC_DVOL_DAC1OUT; + } else if (is_incommunication(preset_idx)) + reg = MC_ASOC_DVOL_VOICEOUT; + else + return 0; + break; + default: + break; + } + + err = set_vol_info(codec, &vol, reg, &mixer, preset_idx); + if (err < 0) + return err; + + err = mc_control(MCDRV_SET_VOLUME, (unsigned long)&vol, 0); + if (err < 0) { + dev_err(codec->dev, "Error in MCDRV_SET_VOLUME: %d\n", err); + return err; + } + + return 0; +} + +static void auto_powerdown(struct snd_soc_codec *codec) +{ +#if (AUTO_POWEROFF == AUTO_POWEROFF_ON) + struct mixer_path_ctl_info mixer; + u8 aec[] = { + 0x41, 0x45, 0x43, + 0x05, + 0, 0, 0, 60, + 0x00, + 253, + 0, + 0, + /* D7: */ + 0x44, 0x37, + 0, 0, 0, 50, + /* AudioEngine:16 */ + 0x02, 0x00, 0x00, 0x00, + 0, 0, 0, 8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* V-BOX:23 */ + 0x03, 0x00, 0x00, 0x00, + 0, 0, 0, 15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* E-DSP:11 */ + 0x07, 0x00, 0x00, 0x00, + 0, 0, 0, 3, + 0, + 0, + 0, + }; + + get_mixer_path_ctl_info(codec, &mixer); + if (!mixer.audio_mode_play && !mixer.audio_mode_cap + && !mixer.mainmic_play && !mixer.submic_play + && !mixer.msmic_play && !mixer.hsmic_play + && !mixer.btmic_play && !mixer.lin1_play && !mixer.dtmf_control) + mc_control(MCDRV_SET_DSP, (unsigned long)aec, sizeof(aec)); +#endif +} + +static void del_dsp_param(struct mc_asoc_data *mc_asoc) +{ + struct mc_asoc_dsp_params *dsp_params, *next; + int i, j; + + for (i = 0; i <= DSP_PRM_VC_2MIC; i++) { + for (j = 0; j <= DSP_PRM_USER; j++) { + kfree(mc_asoc->params_store[i][j].pab_param); + + dsp_params = mc_asoc->params_store[i][j].next; + while (dsp_params) { + kfree(dsp_params->pab_param); + next = dsp_params->next; + kfree(dsp_params); + dsp_params = next; + } + + mc_asoc->params_store[i][j].pab_param = NULL; + mc_asoc->params_store[i][j].size = 0; + mc_asoc->params_store[i][j].next = NULL; + } + } +} + +static int set_audio_mode_play(struct snd_soc_codec *codec, unsigned int value) +{ + struct mc_asoc_data *mc_asoc; + struct mc_asoc_port_params *port; + int ret; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + port = &mc_asoc->port; + if (value > 1) { + u8 rate = port->rate; + if (port->stream + && (rate == MCDRV_FS_96000 || rate == MCDRV_FS_192000)) + return -EINVAL; + } + + ret = snd_soc_cache_write(codec, MC_ASOC_AUDIO_MODE_PLAY, value); + if (ret < 0) + return ret; + + if (!value) + del_dsp_param(mc_asoc); + + ret = connect_path(codec); + if (!value) + auto_powerdown(codec); + + return ret; +} + +static int set_audio_mode_cap(struct snd_soc_codec *codec, unsigned int value) +{ + struct mc_asoc_data *mc_asoc; + struct mc_asoc_port_params *port; + int ret; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + port = &mc_asoc->port; + if (value > 1) { + u8 rate = port->rate; + if (port->stream + && (rate == MCDRV_FS_96000 || rate == MCDRV_FS_192000)) + return -EINVAL; + } + + ret = snd_soc_cache_write(codec, MC_ASOC_AUDIO_MODE_CAP, value); + if (ret < 0) + return ret; + + if (!value) + del_dsp_param(mc_asoc); + + ret = connect_path(codec); + if (!value) + auto_powerdown(codec); + + return ret; +} + +static int set_incall_mic(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + struct mc_asoc_data *mc_asoc; + struct mc_asoc_dsp_params *dsp_params; + int ret; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return ret; + + if (value == MC_ASOC_INCALL_MIC_MAINMIC + || value == MC_ASOC_INCALL_MIC_SUBMIC) + dsp_params = + &mc_asoc->params_store[DSP_PRM_VC_1MIC][DSP_PRM_BASE]; + else + dsp_params = + &mc_asoc->params_store[DSP_PRM_VC_2MIC][DSP_PRM_BASE]; + + while (dsp_params) { + if (dsp_params->size > 0) { + ret = mc_control(MCDRV_SET_DSP, + (unsigned long)dsp_params->pab_param, + dsp_params->size); + if (ret < 0) + return ret; + } + + dsp_params = dsp_params->next; + } + + return connect_path(codec); +} + +static int set_ain_playback(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int audio_mode, audio_mode_cap, ret; + + audio_mode_cap = read_cache(codec, MC_ASOC_AUDIO_MODE_CAP); + if (audio_mode_cap < 0) + return -EIO; + + audio_mode = read_cache(codec, MC_ASOC_AUDIO_MODE_PLAY); + if (audio_mode < 0) + return -EIO; + + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return ret; + + if (audio_mode == MC_ASOC_AUDIO_MODE_INCALL + || audio_mode == MC_ASOC_AUDIO_MODE_INCALL2 + || audio_mode == MC_ASOC_AUDIO_MODE_AUDIO_INCALL + || audio_mode == MC_ASOC_AUDIO_MODE_AUDIO_INCALL2) { + if (audio_mode_cap == MC_ASOC_AUDIO_MODE_INCALL + || audio_mode_cap == MC_ASOC_AUDIO_MODE_AUDIO_INCALL) + return 0; + } + + if ((audio_mode == MC_ASOC_AUDIO_MODE_INCOMM + || audio_mode == MC_ASOC_AUDIO_MODE_INCOMM2) + && audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM) + return 0; + + ret = connect_path(codec); + if (!value) + auto_powerdown(codec); + + return ret; +} + +static int set_dtmf_control(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int ret; + + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return ret; + + ret = connect_path(codec); + if (!value) + auto_powerdown(codec); + + return ret; +} + +static int set_dtmf_output(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int ret; + + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return ret; + + return connect_path(codec); +} + +static int set_switch_clock(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int ret; + + ret = mc_control(MCDRV_SET_CLOCKSW, value, 0); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_master_slave(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, u8 port) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + dio.port[port].dio_common.master_slave = value; + if (port == 1) + flag = MCDRV_EXT_COM_UPDATE_FLAG; + else + flag = MCDRV_VOICE_COM_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_rate(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, u8 port) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + dio.port[port].dio_common.fs = value; + if (port == 1) + flag = MCDRV_EXT_COM_UPDATE_FLAG; + else + flag = MCDRV_VOICE_COM_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_bitclock_rate(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, u8 port) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + dio.port[port].dio_common.bck_fs = value; + if (port == 1) + flag = MCDRV_EXT_COM_UPDATE_FLAG; + else + flag = MCDRV_VOICE_COM_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_interface(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, u8 port) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + dio.port[port].dio_common.interface = value; + if (port == 1) + flag = MCDRV_EXT_COM_UPDATE_FLAG; + else + flag = MCDRV_VOICE_COM_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_bitclock_invert(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, u8 port) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + dio.port[port].dio_common.bck_invert = value; + if (port == 1) + flag = MCDRV_EXT_COM_UPDATE_FLAG; + else + flag = MCDRV_VOICE_COM_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_da_bit_width(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + u8 port, u8 in_out) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + if (!in_out) + dio.port[port].dir.da_format.bit_sel = value; + else + dio.port[port].dit.da_format.bit_sel = value; + + if (port == 1) + flag = MCDRV_EXT_DIR_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG; + else + flag = MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_da_format(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + u8 port, u8 in_out) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + if (!in_out) + dio.port[port].dir.da_format.mode = value; + else + dio.port[port].dit.da_format.mode = value; + + if (port == 1) + flag = MCDRV_EXT_DIR_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG; + else + flag = MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_pcm_mono_stereo(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + u8 port, u8 in_out) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + if (!in_out) + dio.port[port].dir.pcm_format.mono = value; + else + dio.port[port].dit.pcm_format.mono = value; + + if (port == 1) + flag = MCDRV_EXT_DIR_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG; + else + flag = MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_pcm_bit_order(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + u8 port, u8 in_out) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + if (!in_out) + dio.port[port].dir.pcm_format.order = value; + else + dio.port[port].dit.pcm_format.order = value; + + if (port == 1) + flag = MCDRV_EXT_DIR_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG; + else + flag = MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_pcm_format(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + u8 port, u8 in_out) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + if (!in_out) + dio.port[port].dir.pcm_format.law = value; + else + dio.port[port].dit.pcm_format.law = value; + + if (port == 1) + flag = MCDRV_EXT_DIR_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG; + else + flag = MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_pcm_bit_width(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + u8 port, u8 in_out) +{ + struct mcdrv_dio_info dio; + u32 flag; + int ret; + + ret = mc_control(MCDRV_GET_DIGITALIO, (unsigned long)&dio, 0); + if (ret < 0) + return ret; + + if (!in_out) + dio.port[port].dir.pcm_format.bit_sel = value; + else + dio.port[port].dit.pcm_format.bit_sel = value; + + if (port == 1) + flag = MCDRV_EXT_DIR_UPDATE_FLAG | MCDRV_EXT_DIT_UPDATE_FLAG; + else + flag = MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG; + + ret = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_phys_port(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, u8 port) +{ + struct mcdrv_dio_path_info info; + int ret; + + info.phys_port[port] = value; + ret = + mc_control(MCDRV_SET_DIGITALIO_PATH, (unsigned long)&info, + 1 << port); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int set_swap(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value, + size_t offset, u32 flag) +{ + struct mcdrv_swap_info swap; + int ret; + + *(u8 *) ((void *)&swap + offset) = value; + ret = mc_control(MCDRV_SET_SWAP, (unsigned long)&swap, flag); + if (ret < 0) + return ret; + + return snd_soc_cache_write(codec, reg, value); +} + +static int mc_asoc_write_reg(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int err = 0; + + if (!codec) + return -EINVAL; + + if (reg <= MC_ASOC_N_VOL_REG) { + switch (reg) { + case MC_ASOC_DVOL_MUSICIN: + case MC_ASOC_DVOL_EXTIN: + case MC_ASOC_DVOL_VOICEIN: + case MC_ASOC_DVOL_REFIN: + case MC_ASOC_DVOL_ADIF0IN: + case MC_ASOC_DVOL_ADIF1IN: + case MC_ASOC_DVOL_ADIF2IN: + case MC_ASOC_DVOL_MUSICOUT: + case MC_ASOC_DVOL_EXTOUT: + case MC_ASOC_DVOL_VOICEOUT: + case MC_ASOC_DVOL_REFOUT: + case MC_ASOC_DVOL_DAC0OUT: + case MC_ASOC_DVOL_DAC1OUT: + case MC_ASOC_DVOL_DPATHDA: + case MC_ASOC_DVOL_DPATHAD: + case MC_ASOC_DVOL_APLAY_D: + if (((value >> 8) & 0x7f) > 114 || (value & 0x7f) > 114) + return -EINVAL; + break; + case MC_ASOC_AVOL_LINEIN1: + case MC_ASOC_AVOL_MIC1: + case MC_ASOC_AVOL_MIC2: + case MC_ASOC_AVOL_MIC3: + case MC_ASOC_AVOL_MIC4: + case MC_ASOC_DVOL_APLAY_A: + if (((value >> 8) & 0x7f) > 63 || (value & 0x7f) > 63) + return -EINVAL; + break; + case MC_ASOC_AVOL_HP: + if (((value >> 8) & 0x7f) > 127 || (value & 0x7f) > 127) + return -EINVAL; + break; + case MC_ASOC_AVOL_SP: + if (((value >> 8) & 0x7f) > 127 || (value & 0x7f) > 127) + return -EINVAL; + break; + case MC_ASOC_AVOL_RC: + if (((value >> 8) & 0x7f) > 111 || (value & 0x7f) > 111) + return -EINVAL; + break; + case MC_ASOC_AVOL_LINEOUT1: + case MC_ASOC_AVOL_LINEOUT2: + if (((value >> 8) & 0x7f) > 119 || (value & 0x7f) > 119) + return -EINVAL; + break; + case MC_ASOC_AVOL_SP_GAIN: + if (((value >> 8) & 0x7f) > 4 || (value & 0x7f) > 4) + return -EINVAL; + break; + case MC_ASOC_DVOL_MASTER: + case MC_ASOC_DVOL_VOICE: + if (((value >> 8) & 0x7f) > 75 || (value & 0x7f) > 75) + return -EINVAL; + break; + case MC_ASOC_VOICE_RECORDING: + if ((value & 0x7f) > 1) + return -EINVAL; + break; + } + + if (!err) + err = write_reg_vol(codec, reg, value); + } else { + switch (reg) { + case MC_ASOC_AUDIO_MODE_PLAY: + err = set_audio_mode_play(codec, value); + break; + case MC_ASOC_AUDIO_MODE_CAP: + err = set_audio_mode_cap(codec, value); + break; + case MC_ASOC_OUTPUT_PATH: + err = snd_soc_cache_write(codec, reg, value); + break; + case MC_ASOC_INPUT_PATH: + err = snd_soc_cache_write(codec, reg, value); + break; + case MC_ASOC_INCALL_MIC_SP: + case MC_ASOC_INCALL_MIC_RC: + case MC_ASOC_INCALL_MIC_HP: + case MC_ASOC_INCALL_MIC_LO1: + case MC_ASOC_INCALL_MIC_LO2: + err = set_incall_mic(codec, reg, value); + break; + case MC_ASOC_MAINMIC_PLAYBACK_PATH: + case MC_ASOC_SUBMIC_PLAYBACK_PATH: + case MC_ASOC_2MIC_PLAYBACK_PATH: + case MC_ASOC_HSMIC_PLAYBACK_PATH: + case MC_ASOC_BTMIC_PLAYBACK_PATH: + case MC_ASOC_LIN1_PLAYBACK_PATH: + err = set_ain_playback(codec, reg, value); + break; + case MC_ASOC_PARAMETER_SETTING: + break; + case MC_ASOC_DTMF_CONTROL: + err = set_dtmf_control(codec, reg, value); + break; + case MC_ASOC_DTMF_OUTPUT: + err = set_dtmf_output(codec, reg, value); + break; + case MC_ASOC_SWITCH_CLOCK: + err = set_switch_clock(codec, reg, value); + break; + case MC_ASOC_EXT_MASTERSLAVE: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_master_slave(codec, reg, value, + PORT_EXT); + break; + case MC_ASOC_EXT_RATE: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_rate(codec, reg, value, PORT_EXT); + break; + case MC_ASOC_EXT_BITCLOCK_RATE: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_bitclock_rate(codec, reg, value, + PORT_EXT); + break; + case MC_ASOC_EXT_INTERFACE: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_interface(codec, reg, value, + PORT_EXT); + break; + case MC_ASOC_EXT_BITCLOCK_INVERT: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_bitclock_invert(codec, reg, value, + PORT_EXT); + break; + case MC_ASOC_EXT_INPUT_DA_BIT_WIDTH: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_da_bit_width(codec, reg, value, + PORT_EXT, 0); + break; + case MC_ASOC_EXT_INPUT_DA_FORMAT: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_da_format(codec, reg, value, + PORT_EXT, 0); + break; + case MC_ASOC_EXT_INPUT_PCM_MONOSTEREO: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_mono_stereo(codec, reg, value, + PORT_EXT, 0); + break; + case MC_ASOC_EXT_INPUT_PCM_BIT_ORDER: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_bit_order(codec, reg, value, + PORT_EXT, 0); + break; + case MC_ASOC_EXT_INPUT_PCM_FORMAT: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_format(codec, reg, value, + PORT_EXT, 0); + break; + case MC_ASOC_EXT_INPUT_PCM_BIT_WIDTH: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_bit_width(codec, reg, value, + PORT_EXT, 0); + break; + case MC_ASOC_EXT_OUTPUT_DA_BIT_WIDTH: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_da_bit_width(codec, reg, value, + PORT_EXT, 1); + break; + case MC_ASOC_EXT_OUTPUT_DA_FORMAT: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_da_format(codec, reg, value, + PORT_EXT, 1); + break; + case MC_ASOC_EXT_OUTPUT_PCM_MONOSTEREO: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_mono_stereo(codec, reg, value, + PORT_EXT, 1); + break; + case MC_ASOC_EXT_OUTPUT_PCM_BIT_ORDER: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_bit_order(codec, reg, value, + PORT_EXT, 1); + break; + case MC_ASOC_EXT_OUTPUT_PCM_FORMAT: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_format(codec, reg, value, + PORT_EXT, 1); + break; + case MC_ASOC_EXT_OUTPUT_PCM_BIT_WIDTH: + if (CAPTURE_PORT != CAPTURE_PORT_EXT) + err = set_pcm_bit_width(codec, reg, value, + PORT_EXT, 1); + break; + case MC_ASOC_VOICE_MASTERSLAVE: + err = set_master_slave(codec, reg, value, PORT_VOICE); + break; + case MC_ASOC_VOICE_RATE: + err = set_rate(codec, reg, value, PORT_VOICE); + break; + case MC_ASOC_VOICE_BITCLOCK_RATE: + err = set_bitclock_rate(codec, reg, value, PORT_VOICE); + break; + case MC_ASOC_VOICE_INTERFACE: + err = set_interface(codec, reg, value, PORT_VOICE); + break; + case MC_ASOC_VOICE_BITCLOCK_INVERT: + err = set_bitclock_invert(codec, reg, value, + PORT_VOICE); + break; + case MC_ASOC_VOICE_INPUT_DA_BIT_WIDTH: + err = set_da_bit_width(codec, reg, value, + PORT_VOICE, 0); + break; + case MC_ASOC_VOICE_INPUT_DA_FORMAT: + err = set_da_format(codec, reg, value, PORT_VOICE, 0); + break; + case MC_ASOC_VOICE_INPUT_PCM_MONOSTEREO: + err = set_pcm_mono_stereo(codec, reg, value, + PORT_VOICE, 0); + break; + case MC_ASOC_VOICE_INPUT_PCM_BIT_ORDER: + err = set_pcm_bit_order(codec, reg, value, + PORT_VOICE, 0); + break; + case MC_ASOC_VOICE_INPUT_PCM_FORMAT: + err = set_pcm_format(codec, reg, value, PORT_VOICE, 0); + break; + case MC_ASOC_VOICE_INPUT_PCM_BIT_WIDTH: + err = set_pcm_bit_width(codec, reg, value, + PORT_VOICE, 0); + break; + case MC_ASOC_VOICE_OUTPUT_DA_BIT_WIDTH: + err = set_da_bit_width(codec, reg, value, + PORT_VOICE, 1); + break; + case MC_ASOC_VOICE_OUTPUT_DA_FORMAT: + err = set_da_format(codec, reg, value, PORT_VOICE, 1); + break; + case MC_ASOC_VOICE_OUTPUT_PCM_MONOSTEREO: + err = set_pcm_mono_stereo(codec, reg, value, + PORT_VOICE, 1); + break; + case MC_ASOC_VOICE_OUTPUT_PCM_BIT_ORDER: + err = set_pcm_bit_order(codec, reg, value, + PORT_VOICE, 1); + break; + case MC_ASOC_VOICE_OUTPUT_PCM_FORMAT: + err = set_pcm_format(codec, reg, value, PORT_VOICE, 1); + break; + case MC_ASOC_VOICE_OUTPUT_PCM_BIT_WIDTH: + err = set_pcm_bit_width(codec, reg, value, + PORT_VOICE, 1); + break; + case MC_ASOC_MUSIC_PHYSICAL_PORT: + err = set_phys_port(codec, reg, value, PORT_MUSIC); + break; + case MC_ASOC_EXT_PHYSICAL_PORT: + err = set_phys_port(codec, reg, value, PORT_EXT); + break; + case MC_ASOC_VOICE_PHYSICAL_PORT: + err = set_phys_port(codec, reg, value, PORT_VOICE); + break; + case MC_ASOC_HIFI_PHYSICAL_PORT: + err = set_phys_port(codec, reg, value, PORT_HIFI); + break; + case MC_ASOC_ADIF0_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, adif0), + MCDRV_SWAP_ADIF0_UPDATE_FLAG); + break; + case MC_ASOC_ADIF1_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, adif1), + MCDRV_SWAP_ADIF1_UPDATE_FLAG); + break; + case MC_ASOC_ADIF2_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, adif2), + MCDRV_SWAP_ADIF2_UPDATE_FLAG); + break; + case MC_ASOC_DAC0_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, dac0), + MCDRV_SWAP_DAC0_UPDATE_FLAG); + break; + case MC_ASOC_DAC1_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, dac1), + MCDRV_SWAP_DAC1_UPDATE_FLAG); + break; + case MC_ASOC_MUSIC_OUT0_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + music_out0), + MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG); + break; + case MC_ASOC_MUSIC_IN0_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + music_in0), + MCDRV_SWAP_MUSICIN0_UPDATE_FLAG); + break; + case MC_ASOC_MUSIC_IN1_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + music_in1), + MCDRV_SWAP_MUSICIN1_UPDATE_FLAG); + break; + case MC_ASOC_MUSIC_IN2_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + music_in2), + MCDRV_SWAP_MUSICIN2_UPDATE_FLAG); + break; + case MC_ASOC_EXT_IN_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, ext_in), + MCDRV_SWAP_EXTIN_UPDATE_FLAG); + break; + case MC_ASOC_VOICE_IN_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + voice_in), + MCDRV_SWAP_VOICEIN_UPDATE_FLAG); + break; + case MC_ASOC_MUSIC_OUT1_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + music_out1), + MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG); + break; + case MC_ASOC_MUSIC_OUT2_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + music_out2), + MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG); + break; + case MC_ASOC_EXT_OUT_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + ext_out), + MCDRV_SWAP_EXTOUT_UPDATE_FLAG); + break; + case MC_ASOC_VOICE_OUT_SWAP: + err = set_swap(codec, reg, value, + offsetof(struct mcdrv_swap_info, + voice_out), + MCDRV_SWAP_VOICEOUT_UPDATE_FLAG); + break; + case MC_ASOC_ADIF0_SOURCE: + case MC_ASOC_ADIF1_SOURCE: + case MC_ASOC_ADIF2_SOURCE: + err = snd_soc_cache_write(codec, reg, value); + if (err < 0) + break; + + err = connect_path(codec); + break; + case MC_ASOC_MAIN_MIC: + mc_asoc_main_mic = value; + snd_soc_cache_write(codec, reg, value); + break; + case MC_ASOC_SUB_MIC: + mc_asoc_sub_mic = value; + snd_soc_cache_write(codec, reg, value); + break; + case MC_ASOC_HS_MIC: + mc_asoc_hs_mic = value; + snd_soc_cache_write(codec, reg, value); + break; +#ifdef MC_ASOC_TEST + case MC_ASOC_MIC1_BIAS: + mc_asoc_mic1_bias = value; + snd_soc_cache_write(codec, reg, value); + err = connect_path(codec); + break; + case MC_ASOC_MIC2_BIAS: + mc_asoc_mic2_bias = value; + snd_soc_cache_write(codec, reg, value); + err = connect_path(codec); + break; + case MC_ASOC_MIC3_BIAS: + mc_asoc_mic3_bias = value; + snd_soc_cache_write(codec, reg, value); + err = connect_path(codec); + break; + case MC_ASOC_MIC4_BIAS: + mc_asoc_mic4_bias = value; + snd_soc_cache_write(codec, reg, value); + err = connect_path(codec); + break; +#endif + default: + err = -EINVAL; + break; + } + } + + return err; +} + +static const struct snd_soc_dapm_widget mc_asoc_widgets[] = { + SND_SOC_DAPM_DAC("DAC DUMMY", "DAC Playback", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_ADC("ADC DUMMY", "ADC Capture", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_INPUT("INPUT DUMMY"), + SND_SOC_DAPM_OUTPUT("OUTPUT DUMMY"), +}; + +static const struct snd_soc_dapm_widget mc_asoc_widgets_headset[] = { + SND_SOC_DAPM_OUTPUT("HPOUTL"), + SND_SOC_DAPM_OUTPUT("HPOUTR"), + SND_SOC_DAPM_INPUT("AMIC1"), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), +}; + +static const struct snd_soc_dapm_route mc_asoc_intercon[] = { + {"OUTPUT DUMMY", NULL, "DAC DUMMY"}, + {"ADC DUMMY", NULL, "INPUT DUMMY"} +}; + +static const struct snd_soc_dapm_route mc_asoc_intercon_headset[] = { + {"Headphone Jack", NULL, "HPOUTL"}, + {"Headphone Jack", NULL, "HPOUTR"}, + {"Mic Jack", NULL, "AMIC1"}, +}; + +static int mc_asoc_add_widgets(struct snd_soc_codec *codec) +{ + int err; + + if (!codec) + return -EINVAL; + + err = snd_soc_dapm_new_controls(&codec->dapm, mc_asoc_widgets, + ARRAY_SIZE(mc_asoc_widgets)); + if (err < 0) + return err; + + err = snd_soc_dapm_add_routes(&codec->dapm, mc_asoc_intercon, + ARRAY_SIZE(mc_asoc_intercon)); + if (err < 0) + return err; + + err = snd_soc_dapm_new_controls(&codec->dapm, mc_asoc_widgets_headset, + ARRAY_SIZE(mc_asoc_widgets_headset)); + if (err < 0) + return err; + + err = snd_soc_dapm_add_routes(&codec->dapm, mc_asoc_intercon_headset, + ARRAY_SIZE(mc_asoc_intercon_headset)); + if (err < 0) + return err; + + return snd_soc_dapm_new_widgets(&codec->dapm); +} + +static struct input_dev *inp_dev; + +static struct snd_soc_jack hs_jack; +static struct snd_soc_jack_pin hs_jack_pins[] = { + { + .pin = "Mic Jack", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, +}; + +static struct workqueue_struct *mb4_workq; +static struct delayed_work delayed_work; + +static void mb4_work(struct work_struct *work) +{ + connect_path(mc_asoc_codec); +} + +static void headset_detect_callback(u32 flags, struct mcdrv_hsdet_res *res) +{ + struct mcdrv_hsdet_info info; + u8 hpimpclass = mc_asoc_hpimpclass; + u8 en_plug_det_db, en_mic_det, en_dly_key_off, en_dly_key_on; + u8 en_key_off, en_key_on, hs_det_dbnc, dbnc_num_plug; + u8 key0_on_dly_tim, key1_on_dly_tim, key2_on_dly_tim; + u8 key0_on_dly_tim2, key1_on_dly_tim2, key2_on_dly_tim2; + u8 current_en_plug_det_db; + int err; + + if (!mc_asoc_suspended) { + en_plug_det_db = hsdet_info_def.en_plug_det_db; + en_mic_det = hsdet_info_def.en_mic_det; + en_dly_key_off = hsdet_info_def.en_dly_key_off; + en_dly_key_on = hsdet_info_def.en_dly_key_on; + en_key_off = hsdet_info_def.en_key_off; + en_key_on = hsdet_info_def.en_key_on; + key0_on_dly_tim = hsdet_info_def.key0_on_dly_tim; + key1_on_dly_tim = hsdet_info_def.key1_on_dly_tim; + key2_on_dly_tim = hsdet_info_def.key2_on_dly_tim; + key0_on_dly_tim2 = hsdet_info_def.key0_on_dly_tim2; + key1_on_dly_tim2 = hsdet_info_def.key1_on_dly_tim2; + key2_on_dly_tim2 = hsdet_info_def.key2_on_dly_tim2; + hs_det_dbnc = hsdet_info_def.hs_det_dbnc; + dbnc_num_plug = hsdet_info_def.dbnc_num_plug; + } else { + en_plug_det_db = hsdet_info_suspend.en_plug_det_db; + en_mic_det = hsdet_info_suspend.en_mic_det; + en_dly_key_off = hsdet_info_suspend.en_dly_key_off; + en_dly_key_on = hsdet_info_suspend.en_dly_key_on; + en_key_off = hsdet_info_suspend.en_key_off; + en_key_on = hsdet_info_suspend.en_key_on; + key0_on_dly_tim = hsdet_info_suspend.key0_on_dly_tim; + key1_on_dly_tim = hsdet_info_suspend.key1_on_dly_tim; + key2_on_dly_tim = hsdet_info_suspend.key2_on_dly_tim; + key0_on_dly_tim2 = hsdet_info_suspend.key0_on_dly_tim2; + key1_on_dly_tim2 = hsdet_info_suspend.key1_on_dly_tim2; + key2_on_dly_tim2 = hsdet_info_suspend.key2_on_dly_tim2; + hs_det_dbnc = hsdet_info_suspend.hs_det_dbnc; + dbnc_num_plug = hsdet_info_suspend.dbnc_num_plug; + } + + mc_control(MCDRV_GET_HSDET, (unsigned long)&info, 0); + current_en_plug_det_db = info.en_plug_det_db; + + if (flags & MCDRV_HSDET_EVT_SENSEFIN_FLAG) + mc_asoc_hpimpclass = res->hp_imp_class; + + if (flags & MCDRV_HSDET_EVT_PLUGUNDET_DB_FLAG) { + if (current_en_plug_det_db & MCDRV_PLUGDETDB_UNDET_ENABLE) { + mc_asoc_jack_status = 0; + snd_soc_jack_report(&hs_jack, 0, SND_JACK_HEADSET); + cancel_delayed_work(&delayed_work); + info.en_plug_det_db = + en_plug_det_db & MCDRV_PLUGDETDB_DET_ENABLE; + info.en_dly_key_off = MCDRV_KEYEN_D_D_D; + info.en_dly_key_on = MCDRV_KEYEN_D_D_D; + info.en_key_off = MCDRV_KEYEN_D_D_D; + info.en_key_on = MCDRV_KEYEN_D_D_D; + + info.hs_det_dbnc = hs_det_dbnc; + info.dbnc_num_plug = dbnc_num_plug; + info.cbfunc = NULL; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x410000ee); + + info.cbfunc = headset_detect_callback; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x40000000); + mc_asoc_hpimpclass = (u8) -1; + } else + connect_path(mc_asoc_codec); + } + + if (mc_asoc_jack_status == SND_JACK_HEADSET) { + if ((flags & MCDRV_HSDET_EVT_KEYON0_FLAG) && + (en_key_on & MCDRV_KEYEN_D_D_E)) + snd_soc_jack_report(&hs_jack, SND_JACK_BTN_0, + SND_JACK_BTN_0); + if ((flags & MCDRV_HSDET_EVT_KEYON1_FLAG) + && (en_key_on & MCDRV_KEYEN_D_E_D)) + snd_soc_jack_report(&hs_jack, SND_JACK_BTN_1, + SND_JACK_BTN_1); + if ((flags & MCDRV_HSDET_EVT_KEYON2_FLAG) + && (en_key_on & MCDRV_KEYEN_E_D_D)) + snd_soc_jack_report(&hs_jack, SND_JACK_BTN_2, + SND_JACK_BTN_2); + + if (flags & MCDRV_HSDET_EVT_KEYOFF0_FLAG) { + if (en_key_off & MCDRV_KEYEN_D_D_E) + snd_soc_jack_report(&hs_jack, 0, + SND_JACK_BTN_0); + if ((en_dly_key_on & MCDRV_KEYEN_D_D_E) + && !mc_asoc_ver_id + && key0_on_dly_tim2 == 0 && (info.en_key_off & 1)) { + info.en_key_off &= ~1; + info.key0_on_dly_tim = key0_on_dly_tim; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x2020); + } + } + if (flags & MCDRV_HSDET_EVT_KEYOFF1_FLAG) { + if (en_key_off & MCDRV_KEYEN_D_E_D) + snd_soc_jack_report(&hs_jack, 0, + SND_JACK_BTN_1); + if ((en_dly_key_on & MCDRV_KEYEN_D_E_D) + && !mc_asoc_ver_id + && key1_on_dly_tim2 == 0 && (info.en_key_off & 2)) { + info.en_key_off &= ~2; + info.key1_on_dly_tim = key1_on_dly_tim; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x4020); + } + } + if (flags & MCDRV_HSDET_EVT_KEYOFF2_FLAG) { + if (en_key_off & MCDRV_KEYEN_E_D_D) + snd_soc_jack_report(&hs_jack, 0, + SND_JACK_BTN_2); + if ((en_dly_key_on & MCDRV_KEYEN_E_D_D) + && !mc_asoc_ver_id + && key2_on_dly_tim2 == 0 && (info.en_key_off & 4)) { + info.en_key_off &= ~4; + info.key2_on_dly_tim = key2_on_dly_tim; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x8020); + } + } + + if (flags & MCDRV_HSDET_EVT_DLYKEYON0_FLAG) { + if (en_dly_key_on & MCDRV_KEYEN_D_D_E) { + input_report_key(inp_dev, + MC_ASOC_EV_KEY_DELAYKEYON0, 1); + input_sync(inp_dev); + input_report_key(inp_dev, + MC_ASOC_EV_KEY_DELAYKEYON0, 0); + input_sync(inp_dev); + if (!mc_asoc_ver_id && key0_on_dly_tim2 == 0) { + info.en_key_off |= 1; + info.key0_on_dly_tim = 0; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, + 0x2020); + } + } + } else if (flags & MCDRV_HSDET_EVT_DLYKEYON1_FLAG) { + if (en_dly_key_on & MCDRV_KEYEN_D_E_D) { + input_report_key(inp_dev, + MC_ASOC_EV_KEY_DELAYKEYON1, 1); + input_sync(inp_dev); + input_report_key(inp_dev, + MC_ASOC_EV_KEY_DELAYKEYON1, 0); + input_sync(inp_dev); + + if (!mc_asoc_ver_id && key1_on_dly_tim2 == 0) { + info.en_key_off |= 2; + info.key1_on_dly_tim = 0; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, + 0x4020); + } + } + } else if (flags & MCDRV_HSDET_EVT_DLYKEYON2_FLAG) { + if (en_dly_key_on & MCDRV_KEYEN_E_D_D) { + input_report_key(inp_dev, + MC_ASOC_EV_KEY_DELAYKEYON2, 1); + input_sync(inp_dev); + input_report_key(inp_dev, + MC_ASOC_EV_KEY_DELAYKEYON2, 0); + input_sync(inp_dev); + + if (!mc_asoc_ver_id && key2_on_dly_tim2 == 0) { + info.en_key_off |= 4; + info.key2_on_dly_tim = 0; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, + 0x8020); + } + } + } + + if (flags & MCDRV_HSDET_EVT_DLYKEYOFF0_FLAG) { + if (en_dly_key_off & MCDRV_KEYEN_D_D_E) { + input_report_key(inp_dev, + delay_key_off0[res->key_cnt0], + 1); + input_sync(inp_dev); + input_report_key(inp_dev, + delay_key_off0[res->key_cnt0], + 0); + input_sync(inp_dev); + } + } else if (flags & MCDRV_HSDET_EVT_DLYKEYOFF1_FLAG) { + if (en_dly_key_off & MCDRV_KEYEN_D_E_D) { + input_report_key(inp_dev, + delay_key_off1[res->key_cnt1], + 1); + input_sync(inp_dev); + input_report_key(inp_dev, + delay_key_off1[res->key_cnt1], + 0); + input_sync(inp_dev); + } + } else if (flags & MCDRV_HSDET_EVT_DLYKEYOFF2_FLAG) { + if (en_dly_key_off & MCDRV_KEYEN_E_D_D) { + input_report_key(inp_dev, + delay_key_off2[res->key_cnt2], + 1); + input_sync(inp_dev); + input_report_key(inp_dev, + delay_key_off2[res->key_cnt2], + 0); + input_sync(inp_dev); + } + } + } + + if ((flags & MCDRV_HSDET_EVT_PLUGDET_DB_FLAG) + && (current_en_plug_det_db & MCDRV_PLUGDETDB_DET_ENABLE)) { + if ((flags & MCDRV_HSDET_EVT_MICDET_FLAG) + && (en_mic_det & MCDRV_MICDET_ENABLE)) { + mc_asoc_jack_status = SND_JACK_HEADSET; + snd_soc_jack_report(&hs_jack, + mc_asoc_jack_status, + SND_JACK_HEADSET); + } else { + mc_asoc_jack_status = SND_JACK_HEADPHONE; + snd_soc_jack_report(&hs_jack, + mc_asoc_jack_status, + SND_JACK_HEADSET); + } + + queue_delayed_work(mb4_workq, &delayed_work, + msecs_to_jiffies(MSDETMB4OFF)); + info.en_plug_det_db = + en_plug_det_db & MCDRV_PLUGDETDB_UNDET_ENABLE; + info.en_dly_key_off = en_dly_key_off; + info.en_dly_key_on = en_dly_key_on; + info.en_key_off = en_key_off; + info.en_key_on = en_key_on; + info.hs_det_dbnc = HSUNDETDBNC; + info.dbnc_num_plug = HSUNDETDBNCNUM; + info.cbfunc = NULL; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x410000ee); + info.cbfunc = headset_detect_callback; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&info, 0x40000000); + if (info.sgnl_num == MCDRV_SGNLNUM_NONE) + mc_asoc_hpimpclass = MC_ASOC_IMP_TBL_NUM - 1; + } + + if (mc_asoc_jack_status == SND_JACK_HEADPHONE + && (flags & MCDRV_HSDET_EVT_MICDET_FLAG) + && (en_mic_det & MCDRV_MICDET_ENABLE)) { + mc_asoc_jack_status = SND_JACK_HEADSET; + snd_soc_jack_report(&hs_jack, + mc_asoc_jack_status, SND_JACK_HEADSET); + } + + if (hpimpclass != mc_asoc_hpimpclass) { + if (mc_asoc_hpimpclass != (u8) -1) { + struct mixer_path_ctl_info mixer; + int preset_idx = 0; + + err = get_mixer_path_ctl_info(mc_asoc_codec, &mixer); + if (err < 0) + return; + preset_idx = get_path_preset_idx(&mixer); + if (preset_idx < 0 || preset_idx > PRESET_PATH_N) + return; + set_volume(mc_asoc_codec, &mixer, preset_idx); + } else + connect_path(mc_asoc_codec); + } +} + +static void mc_asoc_irq_work(struct work_struct *work) +{ + struct mc_asoc_data *mc_asoc = + container_of(work, struct mc_asoc_data, work); + struct spi_device *spi_dev = mc_asoc->spi; + int err; + + err = mc_do_irq(); + if (err < 0) + dev_err(&spi_dev->dev, "IRQ processing error: %d\n", err); + + if (IRQ_TYPE == IRQ_TYPE_LEVEL_LOW) + enable_irq(mc_asoc->irq); +} + +static irqreturn_t irq_handler(int irq, void *data) +{ + struct mc_asoc_data *mc_asoc; + + mc_asoc = (struct mc_asoc_data *)data; + if (mc_asoc && mc_asoc->workqueue) { + if (IRQ_TYPE == IRQ_TYPE_LEVEL_LOW) + disable_irq_nosync(mc_asoc->irq); + + queue_work(mc_asoc->workqueue, &mc_asoc->work); + } + + return IRQ_HANDLED; +} + +static int init_irq(struct snd_soc_codec *codec) +{ + struct mc_asoc_data *mc_asoc; + int err; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + INIT_WORK(&mc_asoc->work, mc_asoc_irq_work); + + mc_asoc->workqueue = create_workqueue("irq_queue"); + if (!mc_asoc->workqueue) + return -ENOMEM; + + err = irq_set_irq_type(mc_asoc->irq, IRQ_TYPE); + if (err < 0) { + dev_err(codec->dev, "Failed to set_irq_type: %d\n", err); + return -EIO; + } + + err = request_irq(mc_asoc->irq, irq_handler, + IRQF_DISABLED, "MC_YAMAHA IRQ", mc_asoc); + if (err < 0) + dev_err(codec->dev, "Failed to request_irq: %d\n", err); + + return err; +} + +static int term_irq(struct snd_soc_codec *codec) +{ + struct mc_asoc_data *mc_asoc; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (mc_asoc) { + free_irq(mc_asoc->irq, mc_asoc); + + if (mc_asoc->workqueue) + destroy_workqueue(mc_asoc->workqueue); + if (mb4_workq) + destroy_workqueue(mb4_workq); + } + + return 0; +} + +static int mc_asoc_probe(struct snd_soc_codec *codec) +{ + struct mc_asoc_data *mc_asoc; + struct device *dev; + struct mcdrv_dio_info dio; + struct mcdrv_dio_path_info dio_path; + u32 update = 0; + int i, err; + + mc_asoc_codec = codec; + mc_asoc_suspended = false; + mc_asoc_hpimpclass = (u8) -1; + mc_asoc_jack_status = 0; + + mb4_workq = create_workqueue("mb4"); + if (!mb4_workq) + return -ENOMEM; + + INIT_DELAYED_WORK(&delayed_work, mb4_work); + + if (!codec) + return -ENODEV; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + dev = codec->dev; + if (!mc_asoc || !dev) + return -ENODEV; + + mc_asoc_ver_id = mc_version_id_get(); + + mc_asoc->setup = mc_asoc_cfg_setup; + if (mc_asoc_ver_id < 2) { + mc_asoc->setup.info.mb_sel1 = MCDRV_MBSEL_20; + mc_asoc->setup.info.mb_sel2 = MCDRV_MBSEL_20; + mc_asoc->setup.info.mb_sel3 = MCDRV_MBSEL_20; + mc_asoc->setup.info.mb_sel4 = MCDRV_MBSEL_20; + } + + err = mc_init(&mc_asoc->setup.info); + if (err < 0) { + dev_err(dev, "Error in mc_init: %d\n", err); + return err; + } + + if (mc_asoc_ver_id == 0) { + vreg_map[MC_ASOC_AVOL_HP].volmap = volmap_hp_es1; + vreg_map[MC_ASOC_AVOL_LINEOUT2].volmap = volmap_lineout; + vreg_map[MC_ASOC_DVOL_ADIF0IN].volmap = volmap_adif; + vreg_map[MC_ASOC_DVOL_ADIF1IN].volmap = volmap_adif; + vreg_map[MC_ASOC_DVOL_APLAY_D].volmap = volmap_adif; + } else + vreg_map[MC_ASOC_AVOL_SP].volmap = volmap_sp[4]; + + err = snd_soc_add_codec_controls(codec, mc_asoc_snd_controls, + ARRAY_SIZE(mc_asoc_snd_controls)); + if (err < 0) { + dev_err(dev, "Error in snd_soc_add_codec_controls: %d\n", err); + goto error; + } + + err = mc_asoc_add_widgets(codec); + if (err < 0) { + dev_err(dev, "Error in mc_asoc_add_widgets: %d\n", err); + goto error; + } + + snd_soc_cache_write(codec, MC_ASOC_EXT_MASTERSLAVE, + ext_port_def.dio_common.master_slave); + snd_soc_cache_write(codec, MC_ASOC_EXT_RATE, + ext_port_def.dio_common.fs); + snd_soc_cache_write(codec, MC_ASOC_EXT_BITCLOCK_RATE, + ext_port_def.dio_common.bck_fs); + snd_soc_cache_write(codec, MC_ASOC_EXT_INTERFACE, + ext_port_def.dio_common.interface); + snd_soc_cache_write(codec, MC_ASOC_EXT_BITCLOCK_INVERT, + ext_port_def.dio_common.bck_invert); + snd_soc_cache_write(codec, MC_ASOC_EXT_INPUT_DA_BIT_WIDTH, + ext_port_def.dir.da_format.bit_sel); + snd_soc_cache_write(codec, MC_ASOC_EXT_OUTPUT_DA_BIT_WIDTH, + ext_port_def.dit.da_format.bit_sel); + snd_soc_cache_write(codec, MC_ASOC_EXT_INPUT_DA_FORMAT, + ext_port_def.dir.da_format.mode); + snd_soc_cache_write(codec, MC_ASOC_EXT_OUTPUT_DA_FORMAT, + ext_port_def.dit.da_format.mode); + snd_soc_cache_write(codec, MC_ASOC_EXT_INPUT_PCM_MONOSTEREO, + ext_port_def.dir.pcm_format.mono); + snd_soc_cache_write(codec, MC_ASOC_EXT_OUTPUT_PCM_MONOSTEREO, + ext_port_def.dit.pcm_format.mono); + snd_soc_cache_write(codec, MC_ASOC_EXT_INPUT_PCM_BIT_ORDER, + ext_port_def.dir.pcm_format.order); + snd_soc_cache_write(codec, MC_ASOC_EXT_OUTPUT_PCM_BIT_ORDER, + ext_port_def.dit.pcm_format.order); + snd_soc_cache_write(codec, MC_ASOC_EXT_INPUT_PCM_FORMAT, + ext_port_def.dir.pcm_format.law); + snd_soc_cache_write(codec, MC_ASOC_EXT_OUTPUT_PCM_FORMAT, + ext_port_def.dit.pcm_format.law); + snd_soc_cache_write(codec, MC_ASOC_EXT_INPUT_PCM_BIT_WIDTH, + ext_port_def.dir.pcm_format.bit_sel); + snd_soc_cache_write(codec, MC_ASOC_EXT_OUTPUT_PCM_BIT_WIDTH, + ext_port_def.dit.pcm_format.bit_sel); + + snd_soc_cache_write(codec, MC_ASOC_VOICE_MASTERSLAVE, + voice_port_def.dio_common.master_slave); + snd_soc_cache_write(codec, MC_ASOC_VOICE_RATE, + voice_port_def.dio_common.fs); + snd_soc_cache_write(codec, MC_ASOC_VOICE_BITCLOCK_RATE, + voice_port_def.dio_common.bck_fs); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INTERFACE, + voice_port_def.dio_common.interface); + snd_soc_cache_write(codec, MC_ASOC_VOICE_BITCLOCK_INVERT, + voice_port_def.dio_common.bck_invert); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INPUT_DA_BIT_WIDTH, + voice_port_def.dir.da_format.bit_sel); + snd_soc_cache_write(codec, MC_ASOC_VOICE_OUTPUT_DA_BIT_WIDTH, + voice_port_def.dit.da_format.bit_sel); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INPUT_DA_FORMAT, + voice_port_def.dir.da_format.mode); + snd_soc_cache_write(codec, MC_ASOC_VOICE_OUTPUT_DA_FORMAT, + voice_port_def.dit.da_format.mode); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INPUT_PCM_MONOSTEREO, + voice_port_def.dir.pcm_format.mono); + snd_soc_cache_write(codec, MC_ASOC_VOICE_OUTPUT_PCM_MONOSTEREO, + voice_port_def.dit.pcm_format.mono); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INPUT_PCM_BIT_ORDER, + voice_port_def.dir.pcm_format.order); + snd_soc_cache_write(codec, MC_ASOC_VOICE_OUTPUT_PCM_BIT_ORDER, + voice_port_def.dit.pcm_format.order); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INPUT_PCM_FORMAT, + voice_port_def.dir.pcm_format.law); + snd_soc_cache_write(codec, MC_ASOC_VOICE_OUTPUT_PCM_FORMAT, + voice_port_def.dit.pcm_format.law); + snd_soc_cache_write(codec, MC_ASOC_VOICE_INPUT_PCM_BIT_WIDTH, + voice_port_def.dir.pcm_format.bit_sel); + + snd_soc_cache_write(codec, MC_ASOC_VOICE_OUTPUT_PCM_BIT_WIDTH, + voice_port_def.dit.pcm_format.bit_sel); + + snd_soc_cache_write(codec, MC_ASOC_VOICE_RECORDING, + VOICE_RECORDING_UNMUTE); + snd_soc_cache_write(codec, MC_ASOC_INCALL_MIC_SP, INCALL_MIC_SP); + snd_soc_cache_write(codec, MC_ASOC_INCALL_MIC_RC, INCALL_MIC_RC); + snd_soc_cache_write(codec, MC_ASOC_INCALL_MIC_HP, INCALL_MIC_HP); + snd_soc_cache_write(codec, MC_ASOC_INCALL_MIC_LO1, INCALL_MIC_LO1); + snd_soc_cache_write(codec, MC_ASOC_INCALL_MIC_LO2, INCALL_MIC_LO2); + + snd_soc_cache_write(codec, MC_ASOC_MUSIC_PHYSICAL_PORT, + MUSIC_PHYSICAL_PORT); + snd_soc_cache_write(codec, MC_ASOC_EXT_PHYSICAL_PORT, + EXT_PHYSICAL_PORT); + snd_soc_cache_write(codec, MC_ASOC_VOICE_PHYSICAL_PORT, + VOICE_PHYSICAL_PORT); + snd_soc_cache_write(codec, MC_ASOC_HIFI_PHYSICAL_PORT, + HIFI_PHYSICAL_PORT); + + snd_soc_cache_write(codec, MC_ASOC_MAIN_MIC, mc_asoc_main_mic); + snd_soc_cache_write(codec, MC_ASOC_SUB_MIC, mc_asoc_sub_mic); + snd_soc_cache_write(codec, MC_ASOC_HS_MIC, mc_asoc_hs_mic); +#ifdef MC_ASOC_TEST + snd_soc_cache_write(codec, MC_ASOC_MIC1_BIAS, mc_asoc_mic1_bias); + snd_soc_cache_write(codec, MC_ASOC_MIC2_BIAS, mc_asoc_mic2_bias); + snd_soc_cache_write(codec, MC_ASOC_MIC3_BIAS, mc_asoc_mic3_bias); + snd_soc_cache_write(codec, MC_ASOC_MIC4_BIAS, mc_asoc_mic4_bias); +#endif + + /* Headset jack detection */ + snd_soc_jack_new(codec, "Headset", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2, &hs_jack); + + snd_jack_set_key(hs_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); + snd_jack_set_key(hs_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); + snd_jack_set_key(hs_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); + + snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); + + inp_dev = input_allocate_device(); + inp_dev->name = "Headset keys"; + input_set_capability(inp_dev, EV_KEY, MC_ASOC_EV_KEY_DELAYKEYON0); + input_set_capability(inp_dev, EV_KEY, MC_ASOC_EV_KEY_DELAYKEYON1); + input_set_capability(inp_dev, EV_KEY, MC_ASOC_EV_KEY_DELAYKEYON2); + for (i = 0; i < 8; i++) { + input_set_capability(inp_dev, EV_KEY, delay_key_off0[i]); + input_set_capability(inp_dev, EV_KEY, delay_key_off1[i]); + input_set_capability(inp_dev, EV_KEY, delay_key_off2[i]); + } + + err = input_register_device(inp_dev); + if (err < 0) { + dev_err(dev, "Error in input_register_device: %d\n", err); + goto error; + } + + dio.port[0] = music_port_def; + dio.port[1] = ext_port_def; + dio.port[2] = voice_port_def; + dio.port[3] = hifi_port_def; + + update = MCDRV_MUSIC_COM_UPDATE_FLAG + | MCDRV_MUSIC_DIR_UPDATE_FLAG + | MCDRV_MUSIC_DIT_UPDATE_FLAG + | MCDRV_EXT_COM_UPDATE_FLAG + | MCDRV_EXT_DIR_UPDATE_FLAG + | MCDRV_EXT_DIT_UPDATE_FLAG + | MCDRV_VOICE_COM_UPDATE_FLAG + | MCDRV_VOICE_DIR_UPDATE_FLAG + | MCDRV_VOICE_DIT_UPDATE_FLAG + | MCDRV_HIFI_COM_UPDATE_FLAG + | MCDRV_HIFI_DIR_UPDATE_FLAG | MCDRV_HIFI_DIT_UPDATE_FLAG; + err = mc_control(MCDRV_SET_DIGITALIO, (unsigned long)&dio, update); + if (err < 0) { + dev_err(dev, "Error in MCDRV_SET_DIGITALIO: %d\n", err); + goto error; + } + + update = MCDRV_PHYS0_UPDATE_FLAG + | MCDRV_PHYS1_UPDATE_FLAG + | MCDRV_PHYS2_UPDATE_FLAG + | MCDRV_PHYS3_UPDATE_FLAG + | MCDRV_DIR0SLOT_UPDATE_FLAG + | MCDRV_DIR1SLOT_UPDATE_FLAG + | MCDRV_DIR2SLOT_UPDATE_FLAG + | MCDRV_DIT0SLOT_UPDATE_FLAG + | MCDRV_DIT1SLOT_UPDATE_FLAG | MCDRV_DIT2SLOT_UPDATE_FLAG; + dio_path.phys_port[0] = MUSIC_PHYSICAL_PORT; + dio_path.phys_port[1] = EXT_PHYSICAL_PORT; + dio_path.phys_port[2] = VOICE_PHYSICAL_PORT; + dio_path.phys_port[3] = HIFI_PHYSICAL_PORT; + dio_path.music_rslot[0] = mc_asoc_cfg_setup.rslot[0]; + dio_path.music_rslot[1] = mc_asoc_cfg_setup.rslot[1]; + dio_path.music_rslot[2] = mc_asoc_cfg_setup.rslot[2]; + dio_path.music_tslot[0] = mc_asoc_cfg_setup.tslot[0]; + dio_path.music_tslot[1] = mc_asoc_cfg_setup.tslot[1]; + dio_path.music_tslot[2] = mc_asoc_cfg_setup.tslot[2]; + err = mc_control(MCDRV_SET_DIGITALIO_PATH, + (unsigned long)&dio_path, update); + if (err < 0) { + dev_err(dev, "Error in MCDRV_SET_DIGITALIO_PATH: %d\n", err); + goto error; + } + + mc_asoc->hsdet_store = hsdet_info_def; + mc_asoc->hsdet_store.en_dly_key_off = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.en_dly_key_on = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.en_key_off = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.en_key_on = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.cbfunc = headset_detect_callback; + if (mc_asoc_ver_id == 0) + mc_asoc->hsdet_store.irq_type = MCDRV_IRQTYPE_NORMAL; + + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&mc_asoc->hsdet_store, 0x7fffffff); + if (err < 0) { + dev_err(dev, "Error in MCDRV_SET_HSDET: %d\n", err); + goto error; + } + + err = connect_path(codec); + if (err < 0) { + dev_err(dev, "Error in coeenct_path: %d\n", err); + goto error; + } + + err = mc_do_irq(); + if (err < 0) + dev_err(dev, "Error in mc_do_IRQ: %d\n", err); + + if (mc_asoc_ver_id) { + mc_asoc->hsdet_store.en_plug_det_db &= + ~MCDRV_PLUGDETDB_UNDET_ENABLE; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&mc_asoc->hsdet_store, 0x2); + if (err < 0) { + dev_err(dev, "Error in MCDRV_SET_HSDET: %d\n", err); + goto error; + } + } + + err = init_irq(codec); + if (err < 0) { + dev_err(dev, "Error in init_irq: %d\n", err); + goto error; + } + + device_init_wakeup(dev, 1); + + set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + return 0; + +error: + mc_term(); + + return err; +} + +static int mc_asoc_remove(struct snd_soc_codec *codec) +{ + struct mc_asoc_data *mc_asoc; + int err; + + if (!codec) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + term_irq(codec); + + input_unregister_device(inp_dev); + + del_dsp_param(mc_asoc); + + set_bias_level(codec, SND_SOC_BIAS_OFF); + + err = mc_term(); + if (err < 0) + dev_err(codec->dev, "Error in mc_term: %d\n", err); + + return err; +} + +static int mc_asoc_suspend(struct snd_soc_codec *codec) +{ + struct mc_asoc_data *mc_asoc; + struct mixer_path_ctl_info mixer; + struct mcdrv_hsdet_info hsdet_info; + int err; + + if (!codec) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + get_mixer_path_ctl_info(codec, &mixer); + if (mixer.audio_mode_play || mixer.audio_mode_cap + || mixer.mainmic_play || mixer.submic_play || mixer.msmic_play + || mixer.hsmic_play || mixer.btmic_play || mixer.lin1_play + || mixer.dtmf_control) + return 0; + + set_bias_level(codec, SND_SOC_BIAS_OFF); + + mutex_lock(&mc_asoc->mutex); + + err = mc_control(MCDRV_GET_HSDET, + (unsigned long)&mc_asoc->hsdet_store, 0); + if (err < 0) { + dev_err(codec->dev, "Error in mc_asoc_suspend: %d\n", err); + goto error; + } + + mc_asoc->hsdet_store.dly_irq_stop = hsdet_info_def.dly_irq_stop; + + if (device_may_wakeup(codec->dev)) + enable_irq_wake(mc_asoc->irq); + + hsdet_info = hsdet_info_suspend; + if (!mc_asoc_ver_id) + hsdet_info.irq_type = MCDRV_IRQTYPE_NORMAL; + + if (mc_asoc_jack_status != SND_JACK_HEADSET) { + hsdet_info.en_dly_key_off = MCDRV_KEYEN_D_D_D; + hsdet_info.en_dly_key_on = MCDRV_KEYEN_D_D_D; + hsdet_info.en_key_off = MCDRV_KEYEN_D_D_D; + hsdet_info.en_key_on = MCDRV_KEYEN_D_D_D; + } + + hsdet_info.en_plug_det_db &= mc_asoc->hsdet_store.en_plug_det_db; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&hsdet_info, 0x7fffffff); + if (err < 0) { + dev_err(codec->dev, "Error in mc_asoc_suspend: %d\n", err); + goto error; + } + + hsdet_info.cbfunc = headset_detect_callback; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&hsdet_info, 0x40000000); + if (err < 0) { + dev_err(codec->dev, "Error in mc_asoc_suspend: %d\n", err); + goto error; + } + + mc_asoc_suspended = true; +error: + mutex_unlock(&mc_asoc->mutex); + + return err; +} + +static int mc_asoc_resume(struct snd_soc_codec *codec) +{ + struct mc_asoc_data *mc_asoc; + struct mcdrv_hsdet_info hsdet_info; + int err; + + if (!mc_asoc_suspended) + return 0; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + mutex_lock(&mc_asoc->mutex); + + set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + err = mc_control(MCDRV_GET_HSDET, (unsigned long)&hsdet_info, 0); + if (err < 0) { + dev_err(codec->dev, "Error in mc_asoc_resume: %d\n", err); + goto error; + } + + mc_asoc->hsdet_store.en_plug_det_db = + hsdet_info_def.en_plug_det_db & hsdet_info.en_plug_det_db; + if (mc_asoc_jack_status != SND_JACK_HEADSET) { + mc_asoc->hsdet_store.en_dly_key_off = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.en_dly_key_on = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.en_key_off = MCDRV_KEYEN_D_D_D; + mc_asoc->hsdet_store.en_key_on = MCDRV_KEYEN_D_D_D; + } else { + mc_asoc->hsdet_store.en_dly_key_off = + hsdet_info_def.en_dly_key_off; + mc_asoc->hsdet_store.en_dly_key_on = + hsdet_info_def.en_dly_key_on; + mc_asoc->hsdet_store.en_key_off = hsdet_info_def.en_key_off; + mc_asoc->hsdet_store.en_key_on = hsdet_info_def.en_key_on; + } + + mc_asoc->hsdet_store.cbfunc = NULL; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&mc_asoc->hsdet_store, 0x7fffffff); + if (err < 0) { + dev_err(codec->dev, "Error in mc_asoc_resume: %d\n", err); + goto error; + } + + mc_asoc->hsdet_store.cbfunc = headset_detect_callback; + err = mc_control(MCDRV_SET_HSDET, + (unsigned long)&mc_asoc->hsdet_store, 0x40000000); + if (err < 0) { + dev_err(codec->dev, "Error in mc_asoc_resume: %d\n", err); + goto error; + } + + if (device_may_wakeup(codec->dev)) + disable_irq_wake(mc_asoc->irq); + + mc_asoc_suspended = false; + +error: + mutex_unlock(&mc_asoc->mutex); + + return err; +} + +static struct snd_soc_codec_driver mc_asoc_codec_dev = { + .probe = mc_asoc_probe, + .remove = mc_asoc_remove, + .suspend = mc_asoc_suspend, + .resume = mc_asoc_resume, + .read = mc_asoc_read_reg, + .write = mc_asoc_write_reg, + .reg_cache_size = MC_ASOC_N_REG, + .reg_word_size = sizeof(u16), + .reg_cache_step = 1, + .idle_bias_off = true, + .set_bias_level = set_bias_level +}; + +static int spi_rw(struct spi_device *spi_dev, u8 *tx, u8 *rx, int len) +{ + struct spi_message spi_msg; + struct spi_transfer spi_xfer; + + spi_message_init(&spi_msg); + + memset(&spi_xfer, 0, sizeof(spi_xfer)); + spi_xfer.len = len; + spi_xfer.tx_buf = tx; + spi_xfer.rx_buf = rx; + + spi_message_add_tail(&spi_xfer, &spi_msg); + + if (spi_sync(spi_dev, &spi_msg)) { + dev_err(&spi_dev->dev, "spi_sync failure\n"); + return -EIO; + } + + return 0; +} + +static u8 spi_buf[1024]; + +static int mc_asoc_read_data(void *bus_priv, enum mcdrv_slave_addr slave_addr, + u8 addr, u8 *data, u32 size) +{ + struct spi_device *spi_dev = (struct spi_device *)bus_priv; + u8 tx[2]; + u8 *rx = NULL; + u8 *readbuf = spi_buf; + int err; + + if (size + 1 > sizeof(spi_buf)) { + rx = kzalloc(size + 1, GFP_KERNEL); + if (!rx) { + dev_err(&spi_dev->dev, "Failed to allocate memory\n"); + return -ENOMEM; + } + + readbuf = rx; + } + + tx[0] = (addr << 1) | 0x80; + tx[1] = 0; + if (size > 1) + tx[0] |= 0x01; /* burst */ + + err = spi_rw(spi_dev, tx, readbuf, size + 1); + if (!err) + memcpy(data, readbuf + 1, size); + + kfree(rx); + + return err; +} + +static int mc_asoc_write_data(void *bus_priv, enum mcdrv_slave_addr slave_addr, + u8 *data, u32 size) +{ + struct spi_device *spi_dev = (struct spi_device *)bus_priv; + + return spi_rw(spi_dev, data, NULL, size); +} + +static struct mcdrv_bus_ops mc_asoc_bus_ops = { + .read = mc_asoc_read_data, + .write = mc_asoc_write_data, +}; + +static int __devinit mc_asoc_spi_probe(struct spi_device *spi) +{ + struct mc_asoc_data *mc_asoc; + int err; + + mc_asoc = kzalloc(sizeof(struct mc_asoc_data), GFP_KERNEL); + if (!mc_asoc) { + dev_err(&spi->dev, "Failed to allocate memory\n"); + return -ENOMEM; + } + + mc_asoc->spi = spi; + mc_asoc->irq = spi->irq; + pr_info("MC ASOC IRQ1: %d\n", spi->irq); + mutex_init(&mc_asoc->mutex); + dev_set_drvdata(&spi->dev, mc_asoc); + + err = snd_soc_register_codec(&spi->dev, &mc_asoc_codec_dev, + mc_asoc_dai, ARRAY_SIZE(mc_asoc_dai)); + if (err < 0) { + dev_set_drvdata(&spi->dev, NULL); + mutex_destroy(&mc_asoc->mutex); + kfree(mc_asoc); + dev_err(&spi->dev, "Failed to register codec: error=%d\n", err); + return err; + } + + mc_asoc_bus_ops.priv = spi; + mc_bus_register(&mc_asoc_bus_ops); + + return 0; +} + +static int __devexit mc_asoc_spi_remove(struct spi_device *spi) +{ + struct mc_asoc_data *mc_asoc = dev_get_drvdata(&spi->dev); + + if (mc_asoc) { + dev_set_drvdata(&spi->dev, NULL); + mutex_destroy(&mc_asoc->mutex); + kfree(mc_asoc); + } + + mc_bus_register(NULL); + snd_soc_unregister_codec(&spi->dev); + + return 0; +} + +static struct spi_driver mc_asoc_spi_driver = { + .driver = { + .name = MC_ASOC_NAME, + .owner = THIS_MODULE, + }, + .probe = mc_asoc_spi_probe, + .remove = __devexit_p(mc_asoc_spi_remove), +}; + +static int __init ymu831_init(void) +{ + int err; + + err = spi_register_driver(&mc_asoc_spi_driver); + if (err) + pr_err("Failed to register YMU831 SPI driver: %d\n", err); + + return err; +} + +module_init(ymu831_init); + +static void __exit ymu831_exit(void) +{ + spi_unregister_driver(&mc_asoc_spi_driver); +} + +module_exit(ymu831_exit); + +MODULE_AUTHOR("Yamaha Corporation"); +MODULE_DESCRIPTION("Yamaha YMU831 ALSA SoC codec driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(MC_ASOC_DRIVER_VERSION); diff --git a/sound/soc/codecs/ymu831/ymu831.h b/sound/soc/codecs/ymu831/ymu831.h new file mode 100644 index 0000000..a38b976 --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831.h @@ -0,0 +1,48 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _YMU831_H +#define _YMU831_H + +#define MC_ASOC_NAME "ymu831" + +/* div id */ +#define MC_ASOC_BCLK_MULT 5 + +/* div for MC_ASOC_BCLK_MULT */ +#define MC_ASOC_LRCK_X64 0 +#define MC_ASOC_LRCK_X48 1 +#define MC_ASOC_LRCK_X32 2 +#define MC_ASOC_LRCK_X512 3 +#define MC_ASOC_LRCK_X256 4 +#define MC_ASOC_LRCK_X192 5 +#define MC_ASOC_LRCK_X128 6 +#define MC_ASOC_LRCK_X96 7 +#define MC_ASOC_LRCK_X24 8 +#define MC_ASOC_LRCK_X16 9 + +#endif /* _YMU831_H */ diff --git a/sound/soc/codecs/ymu831/ymu831_priv.h b/sound/soc/codecs/ymu831/ymu831_priv.h new file mode 100644 index 0000000..10bce05 --- /dev/null +++ b/sound/soc/codecs/ymu831/ymu831_priv.h @@ -0,0 +1,278 @@ +/* + * YMU831 ASoC codec driver - private header + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - change in the Linux coding style + * - remove unnecessary comments + * - remove unused codes + */ +#ifndef _YMU831_PRIV_H +#define _YMU831_PRIV_H + +#include <linux/spi/spi.h> + +#include "mcdriver.h" + +#undef MC_ASOC_TEST + +/* + * Virtual registers + */ +enum { + MC_ASOC_DVOL_MUSICIN, + MC_ASOC_DVOL_EXTIN, + MC_ASOC_DVOL_VOICEIN, + MC_ASOC_DVOL_REFIN, + MC_ASOC_DVOL_ADIF0IN, + MC_ASOC_DVOL_ADIF1IN, + MC_ASOC_DVOL_ADIF2IN, + MC_ASOC_DVOL_MUSICOUT, + MC_ASOC_DVOL_EXTOUT, + MC_ASOC_DVOL_VOICEOUT, + MC_ASOC_DVOL_REFOUT, + MC_ASOC_DVOL_DAC0OUT, + MC_ASOC_DVOL_DAC1OUT, + MC_ASOC_DVOL_DPATHDA, + MC_ASOC_DVOL_DPATHAD, + MC_ASOC_AVOL_LINEIN1, + MC_ASOC_AVOL_MIC1, + MC_ASOC_AVOL_MIC2, + MC_ASOC_AVOL_MIC3, + MC_ASOC_AVOL_MIC4, + MC_ASOC_AVOL_HP, + MC_ASOC_AVOL_SP, + MC_ASOC_AVOL_RC, + MC_ASOC_AVOL_LINEOUT1, + MC_ASOC_AVOL_LINEOUT2, + MC_ASOC_AVOL_SP_GAIN, + + MC_ASOC_DVOL_MASTER, + MC_ASOC_DVOL_VOICE, + MC_ASOC_DVOL_APLAY_A, + MC_ASOC_DVOL_APLAY_D, + + MC_ASOC_VOICE_RECORDING, + + MC_ASOC_AUDIO_MODE_PLAY, + MC_ASOC_AUDIO_MODE_CAP, + MC_ASOC_OUTPUT_PATH, + MC_ASOC_INPUT_PATH, + MC_ASOC_INCALL_MIC_SP, + MC_ASOC_INCALL_MIC_RC, + MC_ASOC_INCALL_MIC_HP, + MC_ASOC_INCALL_MIC_LO1, + MC_ASOC_INCALL_MIC_LO2, + + MC_ASOC_MAINMIC_PLAYBACK_PATH, + MC_ASOC_SUBMIC_PLAYBACK_PATH, + MC_ASOC_2MIC_PLAYBACK_PATH, + MC_ASOC_HSMIC_PLAYBACK_PATH, + MC_ASOC_BTMIC_PLAYBACK_PATH, + MC_ASOC_LIN1_PLAYBACK_PATH, + + MC_ASOC_DTMF_CONTROL, + MC_ASOC_DTMF_OUTPUT, + + MC_ASOC_SWITCH_CLOCK, + + MC_ASOC_EXT_MASTERSLAVE, + MC_ASOC_EXT_RATE, + MC_ASOC_EXT_BITCLOCK_RATE, + MC_ASOC_EXT_INTERFACE, + MC_ASOC_EXT_BITCLOCK_INVERT, + MC_ASOC_EXT_INPUT_DA_BIT_WIDTH, + MC_ASOC_EXT_INPUT_DA_FORMAT, + MC_ASOC_EXT_INPUT_PCM_MONOSTEREO, + MC_ASOC_EXT_INPUT_PCM_BIT_ORDER, + MC_ASOC_EXT_INPUT_PCM_FORMAT, + MC_ASOC_EXT_INPUT_PCM_BIT_WIDTH, + MC_ASOC_EXT_OUTPUT_DA_BIT_WIDTH, + MC_ASOC_EXT_OUTPUT_DA_FORMAT, + MC_ASOC_EXT_OUTPUT_PCM_MONOSTEREO, + MC_ASOC_EXT_OUTPUT_PCM_BIT_ORDER, + MC_ASOC_EXT_OUTPUT_PCM_FORMAT, + MC_ASOC_EXT_OUTPUT_PCM_BIT_WIDTH, + + MC_ASOC_VOICE_MASTERSLAVE, + MC_ASOC_VOICE_RATE, + MC_ASOC_VOICE_BITCLOCK_RATE, + MC_ASOC_VOICE_INTERFACE, + MC_ASOC_VOICE_BITCLOCK_INVERT, + MC_ASOC_VOICE_INPUT_DA_BIT_WIDTH, + MC_ASOC_VOICE_INPUT_DA_FORMAT, + MC_ASOC_VOICE_INPUT_PCM_MONOSTEREO, + MC_ASOC_VOICE_INPUT_PCM_BIT_ORDER, + MC_ASOC_VOICE_INPUT_PCM_FORMAT, + MC_ASOC_VOICE_INPUT_PCM_BIT_WIDTH, + MC_ASOC_VOICE_OUTPUT_DA_BIT_WIDTH, + MC_ASOC_VOICE_OUTPUT_DA_FORMAT, + MC_ASOC_VOICE_OUTPUT_PCM_MONOSTEREO, + MC_ASOC_VOICE_OUTPUT_PCM_BIT_ORDER, + MC_ASOC_VOICE_OUTPUT_PCM_FORMAT, + MC_ASOC_VOICE_OUTPUT_PCM_BIT_WIDTH, + + MC_ASOC_MUSIC_PHYSICAL_PORT, + MC_ASOC_EXT_PHYSICAL_PORT, + MC_ASOC_VOICE_PHYSICAL_PORT, + MC_ASOC_HIFI_PHYSICAL_PORT, + + MC_ASOC_ADIF0_SWAP, + MC_ASOC_ADIF1_SWAP, + MC_ASOC_ADIF2_SWAP, + + MC_ASOC_DAC0_SWAP, + MC_ASOC_DAC1_SWAP, + + MC_ASOC_MUSIC_OUT0_SWAP, + + MC_ASOC_MUSIC_IN0_SWAP, + MC_ASOC_MUSIC_IN1_SWAP, + MC_ASOC_MUSIC_IN2_SWAP, + + MC_ASOC_EXT_IN_SWAP, + + MC_ASOC_VOICE_IN_SWAP, + + MC_ASOC_MUSIC_OUT1_SWAP, + MC_ASOC_MUSIC_OUT2_SWAP, + + MC_ASOC_EXT_OUT_SWAP, + + MC_ASOC_VOICE_OUT_SWAP, + + MC_ASOC_ADIF0_SOURCE, + MC_ASOC_ADIF1_SOURCE, + MC_ASOC_ADIF2_SOURCE, + + MC_ASOC_PARAMETER_SETTING, + + MC_ASOC_MAIN_MIC, + MC_ASOC_SUB_MIC, + MC_ASOC_HS_MIC, +#ifdef MC_ASOC_TEST + MC_ASOC_MIC1_BIAS, + MC_ASOC_MIC2_BIAS, + MC_ASOC_MIC3_BIAS, + MC_ASOC_MIC4_BIAS, +#endif + + MC_ASOC_N_REG +}; + +#define MC_ASOC_N_VOL_REG (MC_ASOC_DVOL_APLAY_D + 1) + +#define MC_ASOC_AUDIO_MODE_OFF 0 +#define MC_ASOC_AUDIO_MODE_AUDIO 1 +#define MC_ASOC_AUDIO_MODE_INCALL 2 +#define MC_ASOC_AUDIO_MODE_AUDIO_INCALL 3 +#define MC_ASOC_AUDIO_MODE_INCOMM 4 +#define MC_ASOC_AUDIO_MODE_KARAOKE 5 +#define MC_ASOC_AUDIO_MODE_AUDIOEX 5 +#define MC_ASOC_AUDIO_MODE_AUDIOVR 6 +#define MC_ASOC_AUDIO_MODE_INCALL2 6 +#define MC_ASOC_AUDIO_MODE_AUDIO_INCALL2 7 +#define MC_ASOC_AUDIO_MODE_INCOMM2 8 + +#define MC_ASOC_OUTPUT_PATH_SP 0 +#define MC_ASOC_OUTPUT_PATH_RC 1 +#define MC_ASOC_OUTPUT_PATH_HP 2 +#define MC_ASOC_OUTPUT_PATH_HS 3 +#define MC_ASOC_OUTPUT_PATH_LO1 4 +#define MC_ASOC_OUTPUT_PATH_LO2 5 +#define MC_ASOC_OUTPUT_PATH_BT 6 +#define MC_ASOC_OUTPUT_PATH_SP_RC 7 +#define MC_ASOC_OUTPUT_PATH_SP_HP 8 +#define MC_ASOC_OUTPUT_PATH_SP_LO1 9 +#define MC_ASOC_OUTPUT_PATH_SP_LO2 10 +#define MC_ASOC_OUTPUT_PATH_SP_BT 11 +#define MC_ASOC_OUTPUT_PATH_LO1_RC 12 +#define MC_ASOC_OUTPUT_PATH_LO1_HP 13 +#define MC_ASOC_OUTPUT_PATH_LO1_BT 14 +#define MC_ASOC_OUTPUT_PATH_LO2_RC 15 +#define MC_ASOC_OUTPUT_PATH_LO2_HP 16 +#define MC_ASOC_OUTPUT_PATH_LO2_BT 17 +#define MC_ASOC_OUTPUT_PATH_LO1_LO2 18 +#define MC_ASOC_OUTPUT_PATH_LO2_LO1 19 + +#define MC_ASOC_INPUT_PATH_MAINMIC 0 +#define MC_ASOC_INPUT_PATH_SUBMIC 1 +#define MC_ASOC_INPUT_PATH_2MIC 2 +#define MC_ASOC_INPUT_PATH_HS 3 +#define MC_ASOC_INPUT_PATH_BT 4 +#define MC_ASOC_INPUT_PATH_VOICECALL 5 +#define MC_ASOC_INPUT_PATH_VOICEUPLINK 6 +#define MC_ASOC_INPUT_PATH_VOICEDOWNLINK 7 +#define MC_ASOC_INPUT_PATH_LIN1 8 + +#define MC_ASOC_INCALL_MIC_MAINMIC 0 +#define MC_ASOC_INCALL_MIC_SUBMIC 1 +#define MC_ASOC_INCALL_MIC_2MIC 2 + +#define MC_ASOC_DTMF_OUTPUT_SP 0 +#define MC_ASOC_DTMF_OUTPUT_NORMAL 1 + +struct mc_asoc_setup { + struct mcdrv_dev_info info; + unsigned char rslot[3]; + unsigned char tslot[3]; +}; + +struct mc_asoc_port_params { + u8 rate; + u8 bits[SNDRV_PCM_STREAM_LAST + 1]; + u8 pcm_mono[SNDRV_PCM_STREAM_LAST + 1]; + u8 pcm_order[SNDRV_PCM_STREAM_LAST + 1]; + u8 pcm_law[SNDRV_PCM_STREAM_LAST + 1]; + u8 master; + u8 inv; + u8 srcthru; + u8 format; + u8 bckfs; + u8 channels; + u8 stream; /* bit0: Playback, bit1: Capture */ +}; + +struct mc_asoc_dsp_params { + u8 *pab_param; + u32 size; + struct mc_asoc_dsp_params *next; +}; + +struct mc_asoc_data { + int irq; + struct spi_device *spi; + struct mutex mutex; + struct workqueue_struct *workqueue; + struct work_struct work; + struct mc_asoc_setup setup; + struct mc_asoc_port_params port; + u8 clocksw_store; + struct mcdrv_path_info path_store; + struct mcdrv_vol_info vol_store; + struct mcdrv_dio_info dio_store; + struct mcdrv_dio_path_info diopath_store; + struct mcdrv_swap_info swap_store; + struct mcdrv_hsdet_info hsdet_store; + struct mc_asoc_dsp_params params_store[4][2]; +}; + +#endif /* _YMU831_PRIV_H */
On Wed, Jan 16, 2013 at 05:43:28PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/ymu831/Makefile | 2 +- sound/soc/codecs/ymu831/ymu831.c | 5235 +++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/ymu831.h | 48 + sound/soc/codecs/ymu831/ymu831_priv.h | 278 ++ 4 files changed, 5562 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/ymu831/ymu831.c create mode 100644 sound/soc/codecs/ymu831/ymu831.h create mode 100644 sound/soc/codecs/ymu831/ymu831_priv.h
+#define MC_ASOC_DRIVER_VERSION "1.0.1"
The kernel verison numbers are perfectly good, don't add your own.
+static const struct mc_asoc_info_store info_store_tbl[] = {
- {
.get = MCDRV_GET_CLOCKSW,
.set = MCDRV_SET_CLOCKSW,
.offset = offsetof(struct mc_asoc_data, clocksw_store),
},
You're essentially doing ioctl() calls to the non-Linux code earlier... this looks like you've done some kind of HAL which is basically never going to fly in mainline. You need to rewrite this stuff to get rid of the HAL.
+struct mixer_path_ctl_info {
- int audio_mode_play;
- int audio_mode_cap;
- int output_path;
- int input_path;
- int incall_mic;
- int mainmic_play;
- int submic_play;
- int msmic_play;
- int hsmic_play;
- int btmic_play;
- int lin1_play;
- int dtmf_control;
- int dtmf_output;
+};
+static int get_mixer_path_ctl_info(struct snd_soc_codec *codec,
struct mixer_path_ctl_info *info)
+{
Use DAPM.
+static inline int is_incall(int preset_idx) +{
- if ((preset_idx >= 12 && preset_idx <= 23)
|| (preset_idx >= 50 && preset_idx <= 61))
return 1;
- return 0;
+}
This is really not legible. What do these numbers mean?
if (mc_asoc_sub_mic == MIC_4) {
if (info->submic_play == 1)
if (preset_idx < 4 || preset_idx >= 38
|| input_path == MC_ASOC_INPUT_PATH_BT
|| input_path ==
MC_ASOC_INPUT_PATH_SUBMIC) {
*db = aplay_db;
return 0;
}
All this open coded stuff for individual controls is really bloating the code.
I've stopped reading here. It's really hard to see this as a serious attempt to produce a Linux driver - even at a simple visual level the code doesn't look like normal ASoC code and I'd be surprised seeing it anywhere within the kernel.
I strongly recommend just throwing this code away and starting from scratch, working from the datasheet to produce something within the ASoC frameworks. Probably the simplest thing is going to be to start with a basic driver that just supports a limited subset of the functionality (eg, skip the DSPs - perhaps even just make something that supports a single audio path) and then build up from there incrementally. I suspect that if you do this your driver will get very much smaller and simpler, there's an awful lot of stuff the frameworks do for you on Linux.
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- include/uapi/sound/asound.h | 3 +- include/uapi/sound/ymu831.h | 81 +++++ sound/soc/codecs/ymu831/ymu831.c | 585 +++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/ymu831_priv.h | 5 +- 4 files changed, 672 insertions(+), 2 deletions(-) create mode 100644 include/uapi/sound/ymu831.h
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index 1774a5c..e13b05e 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -93,9 +93,10 @@ enum { SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */ SNDRV_HWDEP_IFACE_HDA, /* HD-audio */ SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */ + SNDRV_HWDEP_IFACE_YMU831, /* Yamaha YMU831 */
/* Don't forget to change the following: */ - SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM + SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_YMU831 };
struct snd_hwdep_info { diff --git a/include/uapi/sound/ymu831.h b/include/uapi/sound/ymu831.h new file mode 100644 index 0000000..d5c22b3 --- /dev/null +++ b/include/uapi/sound/ymu831.h @@ -0,0 +1,81 @@ +/* + * YMU831 ASoC codec driver + * + * Copyright (c) 2012 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +/* + * changelog: + * - split from sound/soc/codecs/ymu831/ymu831.h + */ +#ifndef _UAPI__SOUND_YMU831_H +#define _UAPI__SOUND_YMU831_H + +#define MC_ASOC_MAGIC 'N' +#define MC_ASOC_IOCTL_SET_CTRL 1 +#define MC_ASOC_IOCTL_NOTIFY_HOLD 4 + +struct ymc_ctrl_args { + void *param; + unsigned long size; + unsigned long option; +}; + +#define YMC_IOCTL_SET_CTRL \ + _IOW(MC_ASOC_MAGIC, MC_ASOC_IOCTL_SET_CTRL, struct ymc_ctrl_args) + +#define YMC_IOCTL_NOTIFY_HOLD \ + _IOWR(MC_ASOC_MAGIC, MC_ASOC_IOCTL_NOTIFY_HOLD, unsigned long) + +#define YMC_DSP_OUTPUT_BASE 0x00000000 +#define YMC_DSP_OUTPUT_SP 0x00000001 +#define YMC_DSP_OUTPUT_RC 0x00000002 +#define YMC_DSP_OUTPUT_HP 0x00000003 +#define YMC_DSP_OUTPUT_LO1 0x00000004 +#define YMC_DSP_OUTPUT_LO2 0x00000005 +#define YMC_DSP_OUTPUT_BT 0x00000006 + +#define YMC_DSP_INPUT_BASE 0x00000010 +#define YMC_DSP_INPUT_MAINMIC 0x00000020 +#define YMC_DSP_INPUT_SUBMIC 0x00000030 +#define YMC_DSP_INPUT_2MIC 0x00000040 +#define YMC_DSP_INPUT_HEADSET 0x00000050 +#define YMC_DSP_INPUT_BT 0x00000060 +#define YMC_DSP_INPUT_LINEIN1 0x00000070 +#define YMC_DSP_INPUT_LINEIN2 0x00000080 + +#define YMC_DSP_VOICECALL_BASE_1MIC 0x00000100 +#define YMC_DSP_VOICECALL_BASE_2MIC 0x00000200 +#define YMC_DSP_VOICECALL_SP_1MIC 0x00000300 +#define YMC_DSP_VOICECALL_SP_2MIC 0x00000400 +#define YMC_DSP_VOICECALL_RC_1MIC 0x00000500 +#define YMC_DSP_VOICECALL_RC_2MIC 0x00000600 +#define YMC_DSP_VOICECALL_HP_1MIC 0x00000700 +#define YMC_DSP_VOICECALL_HP_2MIC 0x00000800 +#define YMC_DSP_VOICECALL_LO1_1MIC 0x00000900 +#define YMC_DSP_VOICECALL_LO1_2MIC 0x00000a00 +#define YMC_DSP_VOICECALL_LO2_1MIC 0x00000b00 +#define YMC_DSP_VOICECALL_LO2_2MIC 0x00000c00 +#define YMC_DSP_VOICECALL_HEADSET 0x00000d00 +#define YMC_DSP_VOICECALL_BT 0x00000e00 +#define YMC_DSP_VOICECALL_BASE_COMMON 0x00000f00 + +#define YMC_NOTITY_HOLD_OFF 0 +#define YMC_NOTITY_HOLD_ON 1 + +#endif /* _UAPI__SOUND_YMU831_H */ diff --git a/sound/soc/codecs/ymu831/ymu831.c b/sound/soc/codecs/ymu831/ymu831.c index 62c4a90..f6a32ce 100644 --- a/sound/soc/codecs/ymu831/ymu831.c +++ b/sound/soc/codecs/ymu831/ymu831.c @@ -46,6 +46,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h>
+#include <uapi/sound/ymu831.h> + #include "mcdevif.h" #include "mcdriver.h" #include "ymu831.h" @@ -62,6 +64,8 @@ SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE)
+#define MC_ASOC_HWDEP_ID MC_ASOC_NAME + #define get_port_id(id) (id - 1)
#define PORT_MUSIC 0 @@ -129,6 +133,7 @@ static const struct mc_asoc_info_store info_store_tbl[] = { struct snd_soc_codec *mc_asoc_codec;
static u8 mc_asoc_ver_id = 1; +static u8 mc_asoc_hold = YMC_NOTITY_HOLD_OFF; static bool mc_asoc_suspended; static u8 mc_asoc_hpimpclass = 0xff; static u8 mc_asoc_jack_status; @@ -3238,6 +3243,33 @@ static void auto_powerdown(struct snd_soc_codec *codec) #endif }
+static int add_dsp_param(struct mc_asoc_data *mc_asoc, int i, int j, + u8 *param, u32 size) +{ + struct mc_asoc_dsp_params *dsp_params, *next; + + dsp_params = &mc_asoc->params_store[i][j]; + while (dsp_params->pab_param) { + if (!dsp_params->next) { + next = kzalloc(sizeof(struct mc_asoc_dsp_params), + GFP_KERNEL); + if (!next) + return -ENOMEM; + + dsp_params->next = next; + dsp_params = dsp_params->next; + break; + } + + dsp_params = dsp_params->next; + } + + dsp_params->pab_param = param; + dsp_params->size = size; + + return 0; +} + static void del_dsp_param(struct mc_asoc_data *mc_asoc) { struct mc_asoc_dsp_params *dsp_params, *next; @@ -3287,6 +3319,9 @@ static int set_audio_mode_play(struct snd_soc_codec *codec, unsigned int value) if (!value) del_dsp_param(mc_asoc);
+ if (mc_asoc_hold == YMC_NOTITY_HOLD_ON) + return 0; + ret = connect_path(codec); if (!value) auto_powerdown(codec); @@ -3319,6 +3354,9 @@ static int set_audio_mode_cap(struct snd_soc_codec *codec, unsigned int value) if (!value) del_dsp_param(mc_asoc);
+ if (mc_asoc_hold == YMC_NOTITY_HOLD_ON) + return 0; + ret = connect_path(codec); if (!value) auto_powerdown(codec); @@ -3361,6 +3399,9 @@ static int set_incall_mic(struct snd_soc_codec *codec, dsp_params = dsp_params->next; }
+ if (mc_asoc_hold == YMC_NOTITY_HOLD_ON) + return 0; + return connect_path(codec); }
@@ -3395,6 +3436,9 @@ static int set_ain_playback(struct snd_soc_codec *codec, && audio_mode_cap == MC_ASOC_AUDIO_MODE_INCOMM) return 0;
+ if (mc_asoc_hold == YMC_NOTITY_HOLD_ON) + return 0; + ret = connect_path(codec); if (!value) auto_powerdown(codec); @@ -3411,6 +3455,9 @@ static int set_dtmf_control(struct snd_soc_codec *codec, if (ret < 0) return ret;
+ if (mc_asoc_hold == YMC_NOTITY_HOLD_ON) + return 0; + ret = connect_path(codec); if (!value) auto_powerdown(codec); @@ -3427,6 +3474,9 @@ static int set_dtmf_output(struct snd_soc_codec *codec, if (ret < 0) return ret;
+ if (mc_asoc_hold == YMC_NOTITY_HOLD_ON) + return 0; + return connect_path(codec); }
@@ -4233,6 +4283,535 @@ static int mc_asoc_add_widgets(struct snd_soc_codec *codec) return snd_soc_dapm_new_widgets(&codec->dapm); }
+static int mc_asoc_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct snd_soc_codec *codec; + struct mc_asoc_data *mc_asoc; + struct ymc_ctrl_args ymc_ctrl_arg; + u32 hold; + u8 *param; + int output_path, input_path, incall_mic; + int err = 0; + + if (!hw) + return -EINVAL; + + codec = hw->private_data; + if (!codec) + return -EINVAL; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + output_path = read_cache(codec, MC_ASOC_OUTPUT_PATH); + if (output_path < 0) + return -EIO; + + input_path = read_cache(codec, MC_ASOC_INPUT_PATH); + if (input_path < 0) + return -EIO; + + incall_mic = get_incall_mic(codec, output_path); + if (incall_mic < 0) + return -EIO; + + switch (cmd) { + case YMC_IOCTL_SET_CTRL: + if (!access_ok(VERIFY_READ, + (struct ymc_ctrl_args *)arg, + sizeof(struct ymc_ctrl_args))) + return -EFAULT; + if (copy_from_user(&ymc_ctrl_arg, + (struct ymc_ctrl_args *)arg, + sizeof(struct ymc_ctrl_args))) { + return -EFAULT; + } + + if (ymc_ctrl_arg.size == 0) + break; + if (ymc_ctrl_arg.size > MAX_YMS_CTRL_PARAM_SIZE) + return -ENOMEM; + + param = kzalloc(ymc_ctrl_arg.size, GFP_KERNEL); + if (!param) + return -ENOMEM; + + if (copy_from_user(param, ymc_ctrl_arg.param, + ymc_ctrl_arg.size)) { + err = -EFAULT; + goto error; + } + + switch (ymc_ctrl_arg.option) { + case YMC_DSP_OUTPUT_BASE: + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_BASE, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_BASE: + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_BASE, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_VOICECALL_BASE_COMMON: + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_BASE, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + param = kzalloc(ymc_ctrl_arg.size, GFP_KERNEL); + if (!param) { + err = -ENOMEM; + goto error; + } + + if (copy_from_user(param, ymc_ctrl_arg.param, + ymc_ctrl_arg.size)) { + err = -EFAULT; + goto error; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_BASE, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_VOICECALL_BASE_1MIC: + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_BASE, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_BASE_2MIC: + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_BASE, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_2MIC) + goto exit; + break; + case YMC_DSP_OUTPUT_SP: + if (output_path != MC_ASOC_OUTPUT_PATH_SP) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_OUTPUT_RC: + if (output_path != MC_ASOC_OUTPUT_PATH_RC + && output_path != MC_ASOC_OUTPUT_PATH_SP_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO1_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO2_RC) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_OUTPUT_HP: + if (output_path != MC_ASOC_OUTPUT_PATH_HP + && output_path != MC_ASOC_OUTPUT_PATH_HS + && output_path != MC_ASOC_OUTPUT_PATH_SP_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO1_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO2_HP) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_OUTPUT_LO1: + if (output_path != MC_ASOC_OUTPUT_PATH_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_LO2_LO1) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_OUTPUT_LO2: + if (output_path != MC_ASOC_OUTPUT_PATH_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_LO1_LO2) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_OUTPUT_BT: + if (output_path != MC_ASOC_OUTPUT_PATH_BT + && output_path != MC_ASOC_OUTPUT_PATH_SP_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO1_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO2_BT) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_OUTPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_MAINMIC: + if (input_path != MC_ASOC_INPUT_PATH_MAINMIC) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_SUBMIC: + if (input_path != MC_ASOC_INPUT_PATH_SUBMIC) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_2MIC: + if (input_path != MC_ASOC_INPUT_PATH_2MIC) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_HEADSET: + if (input_path != MC_ASOC_INPUT_PATH_HS) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_BT: + if (input_path != MC_ASOC_INPUT_PATH_BT) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_INPUT_LINEIN1: + if (input_path != MC_ASOC_INPUT_PATH_LIN1) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_INPUT, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + break; + case YMC_DSP_VOICECALL_SP_1MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_SP) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_RC_1MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_RC + && output_path != MC_ASOC_OUTPUT_PATH_SP_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO1_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO2_RC) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_HP_1MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_HP + && output_path != MC_ASOC_OUTPUT_PATH_SP_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO1_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO2_HP) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_LO1_1MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_LO2_LO1) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_LO2_1MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_LO1_LO2) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_HEADSET: + if (output_path != MC_ASOC_OUTPUT_PATH_HS) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_1MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_BT: + if (output_path != MC_ASOC_OUTPUT_PATH_BT + && output_path != MC_ASOC_OUTPUT_PATH_SP_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO1_BT + && output_path != MC_ASOC_OUTPUT_PATH_LO2_BT) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_MAINMIC + && incall_mic != MC_ASOC_INCALL_MIC_SUBMIC) + goto exit; + break; + case YMC_DSP_VOICECALL_SP_2MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_SP) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_2MIC) + goto exit; + break; + case YMC_DSP_VOICECALL_RC_2MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_RC + && output_path != MC_ASOC_OUTPUT_PATH_SP_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO1_RC + && output_path != MC_ASOC_OUTPUT_PATH_LO2_RC) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_2MIC) + goto exit; + break; + case YMC_DSP_VOICECALL_HP_2MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_HP + && output_path != MC_ASOC_OUTPUT_PATH_HS + && output_path != MC_ASOC_OUTPUT_PATH_SP_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO1_HP + && output_path != MC_ASOC_OUTPUT_PATH_LO2_HP) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_2MIC) + goto exit; + break; + case YMC_DSP_VOICECALL_LO1_2MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO1 + && output_path != MC_ASOC_OUTPUT_PATH_LO2_LO1) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_2MIC) + goto exit; + break; + case YMC_DSP_VOICECALL_LO2_2MIC: + if (output_path != MC_ASOC_OUTPUT_PATH_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_SP_LO2 + && output_path != MC_ASOC_OUTPUT_PATH_LO1_LO2) { + kfree(param); + goto exit; + } + + err = add_dsp_param(mc_asoc, DSP_PRM_VC_2MIC, + DSP_PRM_USER, param, + ymc_ctrl_arg.size); + if (err) + goto error; + + if (incall_mic != MC_ASOC_INCALL_MIC_2MIC) + goto exit; + break; + default: + err = -EINVAL; + break; + } + + if (err) + goto error; + + err = + mc_control(MCDRV_SET_DSP, (unsigned long)param, + ymc_ctrl_arg.size); + break; + case YMC_IOCTL_NOTIFY_HOLD: + if (!access_ok(VERIFY_READ, (u32 *) arg, sizeof(u32))) + return -EFAULT; + if (copy_from_user(&hold, (u32 *) arg, sizeof(u32))) { + err = -EFAULT; + break; + } + + switch (hold) { + case YMC_NOTITY_HOLD_OFF: + err = connect_path(codec); + if (!err) + auto_powerdown(codec); + case YMC_NOTITY_HOLD_ON: + mc_asoc_hold = hold; + break; + default: + err = -EINVAL; + break; + } + break; + default: + err = -EINVAL; + } +exit: + return err; + +error: + kfree(param); + + return err; +} + +static int mc_asoc_add_hwdep(struct snd_soc_codec *codec) +{ + struct snd_hwdep *hw; + struct mc_asoc_data *mc_asoc; + int err; + + mc_asoc = snd_soc_codec_get_drvdata(codec); + if (!mc_asoc) + return -EINVAL; + + err = snd_hwdep_new(codec->card->snd_card, MC_ASOC_HWDEP_ID, 0, &hw); + if (err < 0) + return err; + + hw->iface = SNDRV_HWDEP_IFACE_YMU831; + hw->private_data = codec; + hw->ops.ioctl = mc_asoc_hwdep_ioctl; + hw->exclusive = 1; + strcpy(hw->name, MC_ASOC_HWDEP_ID); + mc_asoc->hwdep = hw; + + return 0; +} + static struct input_dev *inp_dev;
static struct snd_soc_jack hs_jack; @@ -4674,6 +5253,12 @@ static int mc_asoc_probe(struct snd_soc_codec *codec) goto error; }
+ err = mc_asoc_add_hwdep(codec); + if (err < 0) { + dev_err(dev, "Error in mc_asoc_add_hwdep: %d\n", err); + goto error; + } + snd_soc_cache_write(codec, MC_ASOC_EXT_MASTERSLAVE, ext_port_def.dio_common.master_slave); snd_soc_cache_write(codec, MC_ASOC_EXT_RATE, diff --git a/sound/soc/codecs/ymu831/ymu831_priv.h b/sound/soc/codecs/ymu831/ymu831_priv.h index 10bce05..36ee29b 100644 --- a/sound/soc/codecs/ymu831/ymu831_priv.h +++ b/sound/soc/codecs/ymu831/ymu831_priv.h @@ -30,6 +30,8 @@
#include <linux/spi/spi.h>
+#include <sound/hwdep.h> + #include "mcdriver.h"
#undef MC_ASOC_TEST @@ -173,7 +175,7 @@ enum { MC_ASOC_MIC2_BIAS, MC_ASOC_MIC3_BIAS, MC_ASOC_MIC4_BIAS, -#endif +#endif /* MC_ASOC_TEST */
MC_ASOC_N_REG }; @@ -273,6 +275,7 @@ struct mc_asoc_data { struct mcdrv_swap_info swap_store; struct mcdrv_hsdet_info hsdet_store; struct mc_asoc_dsp_params params_store[4][2]; + struct snd_hwdep *hwdep; };
#endif /* _YMU831_PRIV_H */
At Wed, 16 Jan 2013 17:44:29 +0900, Yoichi Yuasa wrote:
+#define MC_ASOC_MAGIC 'N' +#define MC_ASOC_IOCTL_SET_CTRL 1 +#define MC_ASOC_IOCTL_NOTIFY_HOLD 4
+struct ymc_ctrl_args {
- void *param;
- unsigned long size;
- unsigned long option;
+};
Using a pointer in an ioctl data struct is a very bad idea in general. Don't do it unless you really really need it. Otherwise you'd have to provide a 32/64 bit conversion for compat_ioctl.
Ditto for using long type there. They need conversions as well. For ioctl structs, use only types with strict size definitions.
Takashi
On Wed, Jan 16, 2013 at 05:44:29PM +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
include/uapi/sound/asound.h | 3 +- include/uapi/sound/ymu831.h | 81 +++++ sound/soc/codecs/ymu831/ymu831.c | 585 +++++++++++++++++++++++++++++++++ sound/soc/codecs/ymu831/ymu831_priv.h | 5 +-
Why are you adding ioctl() calls here? What makes it impossible to support whatever you're doing from standard APIs?
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org --- sound/soc/omap/Kconfig | 11 +++ sound/soc/omap/Makefile | 2 + sound/soc/omap/omap-ymu831.c | 169 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 sound/soc/omap/omap-ymu831.c
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 7048137..ff8975b 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -131,3 +131,14 @@ config SND_OMAP_SOC_ZOOM2 select SND_SOC_TWL4030 help Say Y if you want to add support for Soc audio on Zoom2 board. + +config SND_OMAP_SOC_OMAP_YMU831 + tristate "SoC Audio support for OMAP4 boards with Yamaha YMU831 codec" + depends on SND_OMAP_SOC && ARCH_OMAP4 && SPI_MASTER + select SND_OMAP_SOC_MCBSP + select SND_SOC_YMU831 + help + Say Y if you want to add support for SoC audio on OMAP4 boards + using Yamaha YMU831 codec. This driver currently supports: + - SDP4430 + - PandaBoard (4430) diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 19637e5..4bbff7b 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -23,6 +23,7 @@ snd-soc-omap-twl4030-objs := omap-twl4030.o snd-soc-omap3pandora-objs := omap3pandora.o snd-soc-zoom2-objs := zoom2.o snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o +snd-soc-omap-ymu831-objs := omap-ymu831.o
obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o @@ -36,3 +37,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o +obj-$(CONFIG_SND_OMAP_SOC_OMAP_YMU831) += snd-soc-omap-ymu831.o diff --git a/sound/soc/omap/omap-ymu831.c b/sound/soc/omap/omap-ymu831.c new file mode 100644 index 0000000..2f16ca2 --- /dev/null +++ b/sound/soc/omap/omap-ymu831.c @@ -0,0 +1,169 @@ +/* + * ALSA SoC for OMAP4 boards with Yamaha YMU831 codec + * + * Copyright (c) 2011 Yamaha Corporation + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ +#include <linux/io.h> +#include <linux/module.h> +#include <sound/soc.h> +#include <asm/mach-types.h> + +#include "omap-mcbsp.h" +#include "../codecs/ymu831/ymu831.h" + +#define INTERNAL_FREQ (196608000 / 2) + +static int omap_ymu831_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + void *base; + int internal_freq = INTERNAL_FREQ; + int dev, ret; + + base = ioremap(0x4a004108, 16); + if (base) { + if (params_rate(params) < 16000) { + internal_freq /= 4; + iowrite32(ioread32(base) | 0x02, base); + } else + iowrite32(ioread32(base) & ~0x02, base); + iounmap(base); + } + + /* Set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) { + pr_err("can't set cpu DAI configuration %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) { + pr_err("can't set codec DAI configuration %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(cpu_dai, + OMAP_MCBSP_SYSCLK_CLK, + internal_freq, SND_SOC_CLOCK_OUT); + if (ret < 0) { + pr_err("can't set cpu system clock %d\n", ret); + return ret; + } + + dev = internal_freq / (params_rate(params) * 32); + ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, dev); + if (ret < 0) { + pr_err("can't set cpu clkdiv %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_clkdiv(codec_dai, + MC_ASOC_BCLK_MULT, MC_ASOC_LRCK_X32); + if (ret < 0) { + pr_err("can't set codec clkdiv %d\n", ret); + return ret; + } + + return 0; +} + +static struct snd_soc_ops omap_ymu831_dai_ops = { + .hw_params = omap_ymu831_dai_hw_params, +}; + +static int omap_ymu831_init(struct snd_soc_pcm_runtime *rtd) +{ + rtd->pmdown_time = 500; + + return 0; +} + +/* Machine DAI Configuration */ +static struct snd_soc_dai_link omap_ymu831_dai[] = { + { + .name = "Application", + .stream_name = "HiFi Audio", + .codec_dai_name = MC_ASOC_NAME "-da0", + .cpu_dai_name = "omap-mcbsp.2", + .codec_name = "spi1.0", + .platform_name = "omap-pcm-audio", + .init = omap_ymu831_init, + .ops = &omap_ymu831_dai_ops, + }, +}; + +/* Audio machine driver */ +static struct snd_soc_card omap_ymu831_card = { + .name = "omap-" MC_ASOC_NAME, + .owner = THIS_MODULE, + .dai_link = omap_ymu831_dai, + .long_name = "Yamaha YMU831 ASOC for OMAP", + .num_links = ARRAY_SIZE(omap_ymu831_dai), +}; + +static __devinit int omap_ymu831_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &omap_ymu831_card; + int ret; + + if (!machine_is_omap_4430sdp() && !machine_is_omap4_panda()) { + pr_debug("Not SDP4430 or PandaBoard!\n"); + return -ENODEV; + } + + card->dev = &pdev->dev; + ret = snd_soc_register_card(card); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + + return ret; +} + +static int __devexit omap_ymu831_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + return snd_soc_unregister_card(card); +} + +static struct platform_driver omap_ymu831_driver = { + .driver = { + .name = "omap-" MC_ASOC_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = omap_ymu831_probe, + .remove = __devexit_p(omap_ymu831_remove), +}; + +module_platform_driver(omap_ymu831_driver); + +MODULE_AUTHOR("Yamaha Corporation"); +MODULE_DESCRIPTION("ALSA SoC for OMAP4 boards with Yamaha YMU831 codec"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:omap-ymu831");
On Wed, Jan 16, 2013 at 05:46:01PM +0900, Yoichi Yuasa wrote:
- base = ioremap(0x4a004108, 16);
- if (base) {
if (params_rate(params) < 16000) {
internal_freq /= 4;
iowrite32(ioread32(base) | 0x02, base);
} else
iowrite32(ioread32(base) & ~0x02, base);
iounmap(base);
- }
You can't be seriously trying to include this code in mainline... you're poking at random magic numbers in the CPU address space.
+static int omap_ymu831_init(struct snd_soc_pcm_runtime *rtd) +{
- rtd->pmdown_time = 500;
- return 0;
+}
Why?
At Wed, 16 Jan 2013 17:25:30 +0900, Yoichi Yuasa wrote:
Signed-off-by: Yoichi Yuasa yuasa@linux-mips.org
sound/soc/codecs/Kconfig | 6 ++++++ sound/soc/codecs/Makefile | 1 + sound/soc/codecs/ymu831/Makefile | 3 +++ 3 files changed, 10 insertions(+) create mode 100644 sound/soc/codecs/ymu831/Makefile
Usually this kind of patch is applied at the last of series (although this patch doesn't seem to break the build)...
And before Mark starts grumbling: please put ASoC maintainers to Cc when you post ASoC patches.
thanks,
Takashi
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 3a84782..bb405b87 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -122,6 +122,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM9705 if SND_SOC_AC97_BUS select SND_SOC_WM9712 if SND_SOC_AC97_BUS select SND_SOC_WM9713 if SND_SOC_AC97_BUS
- select SND_SOC_YMU831 if SPI_MASTER help Normally ASoC codec drivers are only built if a machine driver which uses them is also built since they are only usable with a machine
@@ -494,6 +495,11 @@ config SND_SOC_WM9712 config SND_SOC_WM9713 tristate
+config SND_SOC_YMU831
- tristate
- select SND_HWDEP
# Amp config SND_SOC_LM4857 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index f6e8e36..1d31783 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -236,6 +236,7 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o +obj-$(CONFIG_SND_SOC_YMU831) += ymu831/
# Amp obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile new file mode 100644 index 0000000..5b3f66d --- /dev/null +++ b/sound/soc/codecs/ymu831/Makefile @@ -0,0 +1,3 @@ +snd-soc-ymu831-objs := \
+obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o
1.7.9.5
On Wed, Jan 16, 2013 at 12:38:05PM +0100, Takashi Iwai wrote:
And before Mark starts grumbling: please put ASoC maintainers to Cc when you post ASoC patches.
Please also use subject lines appropriate for the subsystem you're sending patches for - between the fact that I've barely read alsa-devel for the past couple of months, the subject line being wrong and me not being CCed there's every chance I either have already or would delete your mail unread as it doesn't look relevant.
participants (3)
-
Mark Brown
-
Takashi Iwai
-
Yoichi Yuasa