[alsa-devel] [PATCH 10/19] ALSA: ymu831: add device control packet packing driver
Yoichi Yuasa
yuasa at linux-mips.org
Wed Jan 16 09:36:01 CET 2013
Signed-off-by: Yoichi Yuasa <yuasa at 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 */
--
1.7.9.5
More information about the Alsa-devel
mailing list