[alsa-devel] [PATCH 07/19] ALSA: ymu831: add base driver
Yoichi Yuasa
yuasa at linux-mips.org
Wed Jan 16 09:33:03 CET 2013
Signed-off-by: Yoichi Yuasa <yuasa at linux-mips.org>
---
sound/soc/codecs/ymu831/Makefile | 3 +-
sound/soc/codecs/ymu831/mcdriver.c | 2934 ++++++++++++++++++++++++++++++++++++
sound/soc/codecs/ymu831/mcdriver.h | 1017 +++++++++++++
3 files changed, 3953 insertions(+), 1 deletion(-)
create mode 100644 sound/soc/codecs/ymu831/mcdriver.c
create mode 100644 sound/soc/codecs/ymu831/mcdriver.h
diff --git a/sound/soc/codecs/ymu831/Makefile b/sound/soc/codecs/ymu831/Makefile
index 949640e..e908b6d 100644
--- a/sound/soc/codecs/ymu831/Makefile
+++ b/sound/soc/codecs/ymu831/Makefile
@@ -1,6 +1,7 @@
snd-soc-ymu831-objs := \
mcbdspdrv.o \
mccdspdrv.o \
- mcdevif.o
+ mcdevif.o \
+ mcdriver.o
obj-$(CONFIG_SND_SOC_YMU831) += snd-soc-ymu831.o
diff --git a/sound/soc/codecs/ymu831/mcdriver.c b/sound/soc/codecs/ymu831/mcdriver.c
new file mode 100644
index 0000000..dbdce57
--- /dev/null
+++ b/sound/soc/codecs/ymu831/mcdriver.c
@@ -0,0 +1,2934 @@
+/****************************************************************************
+ *
+ * Copyright(c) 2012 Yamaha Corporation. All rights reserved.
+ *
+ * Module : mcdriver.c
+ * Description : MC base driver
+ * Version : 1.0.1 Dec 20 2012
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ****************************************************************************/
+/*
+ * changelog:
+ * - change in the Linux coding style
+ * - remove unnecessary comments
+ * - remove unused codes
+ */
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "mcbdspdrv.h"
+#include "mccdspdrv.h"
+#include "mcdefs.h"
+#include "mcdevif.h"
+#include "mcdriver.h"
+#include "mcedspdrv.h"
+#include "mcfdspdrv.h"
+#include "mcparser.h"
+#include "mcresctrl.h"
+
+#define LDO_WAIT_TIME 1 /* msec */
+#define VREF_WAIT_TIME_ES1 2 /* msec */
+#define VREF_WAIT_TIME 30 /* msec */
+#define MCDRV_DAC_MUTE_WAIT_TIME 20000
+#define MCDRV_MB4_WAIT_TIME 8000
+
+#define T_CPMODE_IMPSENSE_BEFORE 0
+#define T_CPMODE_IMPSENSE_AFTER 2
+
+static struct mcdrv_path_info path_alloff = {
+ .music_out = {0x00AAAAAA, 0x00AAAAAA},
+ .ext_out = {0x00AAAAAA, 0x00AAAAAA},
+ .hifi_out = {0x00AAAAAA},
+ .vbox_mix_in = {0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA},
+ .ae0 = {0x00AAAAAA, 0x00AAAAAA},
+ .ae1 = {0x00AAAAAA, 0x00AAAAAA},
+ .ae2 = {0x00AAAAAA, 0x00AAAAAA},
+ .ae3 = {0x00AAAAAA, 0x00AAAAAA},
+ .dac0 = {0x00AAAAAA, 0x00AAAAAA},
+ .dac1 = {0x00AAAAAA, 0x00AAAAAA},
+ .voice_out = {0x00AAAAAA},
+ .vbox_io_in = {0x00AAAAAA},
+ .vbox_host_in = {0x00AAAAAA},
+ .host_out = {0x00AAAAAA},
+ .adif0 = {0x00AAAAAA, 0x00AAAAAA},
+ .adif1 = {0x00AAAAAA, 0x00AAAAAA},
+ .adif2 = {0x00AAAAAA, 0x00AAAAAA},
+ .adc0 = {0x002AAAAA, 0x002AAAAA},
+ .adc1 = {0x002AAAAA},
+ .sp = {0x002AAAAA, 0x002AAAAA},
+ .hp = {0x002AAAAA, 0x002AAAAA},
+ .rc = {0x002AAAAA},
+ .lout1 = {0x002AAAAA, 0x002AAAAA},
+ .lout2 = {0x002AAAAA, 0x002AAAAA},
+ .bias = {0x002AAAAA, 0x002AAAAA, 0x002AAAAA, 0x002AAAAA},
+};
+
+static DEFINE_MUTEX(mcdrv_mutex);
+
+#ifndef MCDRV_SKIP_IMPSENSE
+static inline int imp_sense_start(u8 *op_dac)
+{
+ struct mcdrv_power_info power_info;
+ struct mcdrv_power_update power_update;
+ struct mcdrv_hsdet_info hsdet_info;
+ struct mcdrv_dev_info info;
+ enum mcdrv_dev_id id;
+ u8 val, data[2];
+ int ret = 0;
+
+ id = mc_dev_id_get();
+ mc_power_info_get_current(&power_info);
+ power_info.digital &= ~(MCDRV_POWINFO_D_PM_CLK_PD |
+ MCDRV_POWINFO_D_PE_CLK_PD |
+ MCDRV_POWINFO_D_PLL_PD);
+ power_info.analog[0] &= ~(MCB_AP_LDOA | MCB_AP_BGR | MCB_AP_VR);
+
+ /* power up */
+ power_update.digital = MCDRV_POWUPDATE_D_ALL;
+ power_update.analog[0] = (u8) MCDRV_POWUPDATE_AP;
+ power_update.analog[1] = 0;
+ power_update.analog[2] = 0;
+ power_update.analog[3] = 0;
+ power_update.analog[4] = 0;
+ ret = mc_packet_add_powerup(&power_info, &power_update);
+ if (ret < 0)
+ goto exit;
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ mc_packet_add_force_write_if(MCI_IRQ, 0);
+ mc_packet_add_force_write_cd(MCI_IRQHS, 0);
+
+ mc_packet_add_write_e(MCI_E1DSP_CTRL, 0);
+
+ mc_packet_add_dac0_mute();
+
+ val = mc_e_register_get_value(MCI_LPF_THR);
+ val |= (MCB_OSF0_ENB | MCB_LPF0_PST_THR | MCB_LPF0_PRE_THR);
+ mc_packet_add_write_e(MCI_LPF_THR, val);
+
+ val = mc_cd_register_get_value(MCI_DP);
+ if (id == MCDRV_DEV_ID_80_90H) {
+ val &= ~(MCB_DP_ADC | MCB_DP_DAC0 | MCB_DP_PDMCK |
+ MCB_DP_PDMADC | MCB_DP_PDMDAC);
+ } else {
+ val &= ~(MCB_DP_ADC | MCB_DP_DAC1 | MCB_DP_DAC0 |
+ MCB_DP_PDMCK | MCB_DP_PDMADC | MCB_DP_PDMDAC);
+ }
+ mc_packet_add_write_cd(MCI_DP, val);
+
+ val = mc_e_register_get_value(MCI_DCL_GAIN);
+ val |= MCB_DCL0_OFF;
+ mc_packet_add_write_e(MCI_DCL_GAIN, val);
+
+ if (id == MCDRV_DEV_ID_80_90H) {
+ val = mc_e_register_get_value(MCI_DSF0_FLT_TYPE);
+ val |= MCB_DSF0ENB;
+ mc_packet_add_write_e(MCI_DSF0_FLT_TYPE, val);
+ } else {
+ val = mc_e_register_get_value(MCI_DSF2_FLT_TYPE);
+ val |= MCB_DSF2ENB;
+ mc_packet_add_write_e(MCI_DSF2_FLT_TYPE, val);
+ }
+
+ mc_hsdet_info_get(&hsdet_info);
+ val = hsdet_info.sgnl_peak << 4 | hsdet_info.sgnl_num << 2 |
+ hsdet_info.sgnl_period;
+ mc_packet_add_write_e(MCI_IMPSEL, val);
+
+ mc_packet_add_write_if(MCI_IRQR, MCB_EIRQR);
+
+ mc_packet_add_write_cd(MCI_EIRQSENSE, MCB_EIRQSENSE);
+
+ if (id == MCDRV_DEV_ID_80_90H) {
+ *op_dac = mc_ana_register_get_value(19);
+ mc_packet_add_write_ana(19, 0);
+ }
+
+ mc_dev_info_get(&info);
+ if (id == MCDRV_DEV_ID_80_90H)
+ mc_packet_add_write_ana(MCI_HPDETVOL, 0x70);
+ else
+ mc_packet_add_write_ana(MCI_HPDETVOL, info.options[9]);
+
+ if (id == MCDRV_DEV_ID_80_90H) {
+ mc_packet_add_force_write_ana(78, T_CPMODE_IMPSENSE_BEFORE);
+ mc_packet_add_force_write_ana(87, 0x11);
+ } else {
+ mc_packet_add_force_write_if(31, 0xb5);
+ mc_packet_add_force_write_if(30, 0xd6);
+ mc_packet_add_force_write_ana(87, info.options[10]);
+ }
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ if (id == MCDRV_DEV_ID_80_90H) {
+ data[0] = MCI_ANA_REG_A << 1;
+ data[1] = 78;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_ANA_REG_D, &val, 1);
+ if (val != T_CPMODE_IMPSENSE_BEFORE) {
+ ret = -EIO;
+ goto exit;
+ }
+ }
+
+ val = E1COMMAND_IMP_SENSE;
+ if (info.gnd_det == MCDRV_GNDDET_ON)
+ val |= E1COMMAND_GND_DET;
+ if (mc_a_source_is_used(MCDRV_ASRC_DAC1_L_ON) ||
+ mc_a_source_is_used(MCDRV_ASRC_DAC1_R_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_ADC0_L_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_ADC0_R_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_ADC1_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_PDM0_L_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_PDM0_R_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_PDM1_L_ON) ||
+ mc_d2_source_is_used(MCDRV_D2SRC_PDM1_R_ON))
+ val |= E1COMMAND_ADDITIONAL;
+ else if (mc_a_source_is_used(MCDRV_ASRC_DAC0_L_ON) ||
+ mc_a_source_is_used(MCDRV_ASRC_DAC0_R_ON))
+ val |= E1COMMAND_ADDITIONAL | E1COMMAND_PD;
+
+ if (id == MCDRV_DEV_ID_80_90H)
+ mc_packet_add_wait(MCDRV_DAC_MUTE_WAIT_TIME);
+ else
+ val |= E1COMMAND_WAIT;
+ mc_packet_add_force_write_e(MCI_E1COMMAND, val);
+
+ ret = mc_packet_execute();
+
+exit:
+ return ret;
+}
+#endif
+
+static inline bool is_ldoa_on(void)
+{
+ if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH0))
+ return true;
+
+ if (mc_source_is_used(MCDRV_DST_ADC0, MCDRV_DST_CH1))
+ return true;
+
+ if (mc_source_is_used(MCDRV_DST_ADC1, MCDRV_DST_CH0))
+ return true;
+
+ if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH0))
+ return true;
+
+ if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH1))
+ return true;
+
+ if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH2))
+ return true;
+
+ if (mc_source_is_used(MCDRV_DST_BIAS, MCDRV_DST_CH3))
+ return true;
+
+ if (mc_a_source_is_used(MCDRV_ASRC_DAC0_L_ON))
+ return true;
+
+ if (mc_a_source_is_used(MCDRV_ASRC_DAC0_R_ON))
+ return true;
+
+ if (mc_a_source_is_used(MCDRV_ASRC_DAC1_L_ON))
+ return true;
+
+ if (mc_a_source_is_used(MCDRV_ASRC_DAC1_R_ON))
+ return true;
+
+ return false;
+}
+
+static inline void mask_irregular_path_info(struct mcdrv_path_info *path_info)
+{
+ u8 ch;
+
+ for (ch = 0; ch < MUSICOUT_PATH_CHANNELS; ch++)
+ path_info->music_out[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+
+ for (ch = 0; ch < EXTOUT_PATH_CHANNELS; ch++)
+ path_info->ext_out[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+
+ for (ch = 0; ch < HIFIOUT_PATH_CHANNELS; ch++)
+ path_info->hifi_out[ch] &=
+ MCDRV_D1SRC_ADIF0_ON | MCDRV_D1SRC_ADIF0_OFF;
+
+ for (ch = 0; ch < VBOXMIXIN_PATH_CHANNELS; ch++)
+ path_info->vbox_mix_in[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+
+ for (ch = 0; ch < AE_PATH_CHANNELS; ch++) {
+ path_info->ae0[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+ path_info->ae1[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+ path_info->ae2[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+ path_info->ae3[ch] &= ~MCDRV_D1SRC_HIFIIN_ON;
+ }
+
+ for (ch = 0; ch < VOICEOUT_PATH_CHANNELS; ch++)
+ path_info->voice_out[ch] &=
+ MCDRV_D2SRC_VBOXIOOUT_ON | MCDRV_D2SRC_VBOXIOOUT_OFF;
+
+ for (ch = 0; ch < VBOXIOIN_PATH_CHANNELS; ch++)
+ path_info->vbox_io_in[ch] &=
+ MCDRV_D2SRC_VOICEIN_ON | MCDRV_D2SRC_VOICEIN_OFF;
+
+ for (ch = 0; ch < VBOXHOSTIN_PATH_CHANNELS; ch++)
+ path_info->vbox_host_in[ch] &=
+ MCDRV_D2SRC_VOICEIN_ON | MCDRV_D2SRC_VOICEIN_OFF;
+
+ for (ch = 0; ch < HOSTOUT_PATH_CHANNELS; ch++)
+ path_info->host_out[ch] &=
+ MCDRV_D2SRC_VBOXHOSTOUT_ON | MCDRV_D2SRC_VBOXHOSTOUT_OFF;
+
+ for (ch = 0; ch < ADIF0_PATH_CHANNELS; ch++)
+ path_info->adif0[ch] &= MCDRV_D2SRC_ADC0_L_ON
+ | MCDRV_D2SRC_ADC0_L_OFF
+ | MCDRV_D2SRC_ADC0_R_ON
+ | MCDRV_D2SRC_ADC0_R_OFF
+ | MCDRV_D2SRC_ADC1_ON
+ | MCDRV_D2SRC_ADC1_OFF
+ | MCDRV_D2SRC_PDM0_L_ON
+ | MCDRV_D2SRC_PDM0_L_OFF
+ | MCDRV_D2SRC_PDM0_R_ON
+ | MCDRV_D2SRC_PDM0_R_OFF
+ | MCDRV_D2SRC_PDM1_L_ON
+ | MCDRV_D2SRC_PDM1_L_OFF
+ | MCDRV_D2SRC_PDM1_R_ON | MCDRV_D2SRC_PDM1_R_OFF;
+
+ for (ch = 0; ch < ADIF1_PATH_CHANNELS; ch++)
+ path_info->adif1[ch] &= MCDRV_D2SRC_ADC0_L_ON
+ | MCDRV_D2SRC_ADC0_L_OFF
+ | MCDRV_D2SRC_ADC0_R_ON
+ | MCDRV_D2SRC_ADC0_R_OFF
+ | MCDRV_D2SRC_ADC1_ON
+ | MCDRV_D2SRC_ADC1_OFF
+ | MCDRV_D2SRC_PDM0_L_ON
+ | MCDRV_D2SRC_PDM0_L_OFF
+ | MCDRV_D2SRC_PDM0_R_ON
+ | MCDRV_D2SRC_PDM0_R_OFF
+ | MCDRV_D2SRC_PDM1_L_ON
+ | MCDRV_D2SRC_PDM1_L_OFF
+ | MCDRV_D2SRC_PDM1_R_ON | MCDRV_D2SRC_PDM1_R_OFF;
+
+ for (ch = 0; ch < ADIF2_PATH_CHANNELS; ch++)
+ path_info->adif2[ch] &= MCDRV_D2SRC_ADC0_L_ON
+ | MCDRV_D2SRC_ADC0_L_OFF
+ | MCDRV_D2SRC_ADC0_R_ON
+ | MCDRV_D2SRC_ADC0_R_OFF
+ | MCDRV_D2SRC_ADC1_ON
+ | MCDRV_D2SRC_ADC1_OFF
+ | MCDRV_D2SRC_PDM0_L_ON
+ | MCDRV_D2SRC_PDM0_L_OFF
+ | MCDRV_D2SRC_PDM0_R_ON
+ | MCDRV_D2SRC_PDM0_R_OFF
+ | MCDRV_D2SRC_PDM1_L_ON
+ | MCDRV_D2SRC_PDM1_L_OFF
+ | MCDRV_D2SRC_PDM1_R_ON
+ | MCDRV_D2SRC_PDM1_R_OFF
+ | MCDRV_D2SRC_DAC0REF_ON
+ | MCDRV_D2SRC_DAC0REF_OFF
+ | MCDRV_D2SRC_DAC1REF_ON | MCDRV_D2SRC_DAC1REF_OFF;
+
+ path_info->adc0[0] &= ~(MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON |
+ MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_R_ON |
+ MCDRV_ASRC_LINEIN1_R_ON);
+ path_info->adc0[1] &= ~(MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_R_ON |
+ MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_R_ON |
+ MCDRV_ASRC_LINEIN1_L_ON);
+
+ for (ch = 0; ch < ADC1_PATH_CHANNELS; ch++)
+ path_info->adc1[ch] &= ~(MCDRV_ASRC_DAC0_L_ON |
+ MCDRV_ASRC_DAC0_R_ON |
+ MCDRV_ASRC_DAC1_L_ON |
+ MCDRV_ASRC_DAC1_R_ON |
+ MCDRV_ASRC_LINEIN1_L_ON |
+ MCDRV_ASRC_LINEIN1_R_ON);
+
+ path_info->sp[0] &= MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_L_OFF;
+ path_info->sp[1] &= MCDRV_ASRC_DAC1_R_ON | MCDRV_ASRC_DAC1_R_OFF;
+
+ path_info->hp[0] &= MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_L_OFF;
+ path_info->hp[1] &= MCDRV_ASRC_DAC0_R_ON | MCDRV_ASRC_DAC0_R_OFF;
+
+ path_info->rc[0] &= MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_L_OFF;
+
+ path_info->lout1[0] &= MCDRV_ASRC_DAC0_L_ON | MCDRV_ASRC_DAC0_L_OFF;
+ path_info->lout1[1] &= MCDRV_ASRC_DAC0_R_ON | MCDRV_ASRC_DAC0_R_OFF;
+
+ path_info->lout2[0] &= MCDRV_ASRC_DAC1_L_ON | MCDRV_ASRC_DAC1_L_OFF;
+ path_info->lout2[1] &= MCDRV_ASRC_DAC1_R_ON | MCDRV_ASRC_DAC1_R_OFF;
+
+ path_info->bias[0] &= MCDRV_ASRC_MIC1_ON | MCDRV_ASRC_MIC1_OFF;
+ path_info->bias[1] &= MCDRV_ASRC_MIC2_ON | MCDRV_ASRC_MIC2_OFF;
+ path_info->bias[2] &= MCDRV_ASRC_MIC3_ON | MCDRV_ASRC_MIC3_OFF;
+ path_info->bias[3] &= MCDRV_ASRC_MIC4_ON | MCDRV_ASRC_MIC4_OFF;
+}
+
+static inline bool is_valid_dio_path_info(struct mcdrv_dio_path_info
+ *dio_path_info, unsigned int update)
+{
+ struct mcdrv_dio_path_info curr_dio_path_info;
+ u8 val;
+ bool LP0_start = false, LP1_start = false;
+ bool LP2_start = false, LP3_start = false;
+ bool ret = true;
+
+ val = mc_mb_register_get_value(MCI_LP0_START);
+ if (val & (MCB_LPR0_START | MCB_LPT0_START))
+ LP0_start = true;
+
+ val = mc_mb_register_get_value(MCI_LP1_START);
+ if (val & (MCB_LPR1_START | MCB_LPT1_START))
+ LP1_start = true;
+
+ val = mc_mb_register_get_value(MCI_LP2_START);
+ if (val & (MCB_LPR2_START | MCB_LPT2_START))
+ LP2_start = true;
+
+ val = mc_mb_register_get_value(MCI_LP3_START);
+ if (val & (MCB_LPR3_START | MCB_LPT3_START))
+ LP3_start = true;
+
+ mc_dio_path_info_get(&curr_dio_path_info);
+
+ if (update & MCDRV_MUSICNUM_UPDATE_FLAG) {
+ if (dio_path_info->music_ch > MCDRV_MUSIC_LAST) {
+ ret = false;
+ goto exit;
+ } else if (dio_path_info->music_ch !=
+ curr_dio_path_info.music_ch) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_PHYS0_UPDATE_FLAG) {
+ if (dio_path_info->phys_port[0] > MCDRV_PHYSPORT_LAST) {
+ ret = false;
+ goto exit;
+ } else if (dio_path_info->phys_port[0] !=
+ curr_dio_path_info.phys_port[0]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_PHYS1_UPDATE_FLAG) {
+ if (dio_path_info->phys_port[1] > MCDRV_PHYSPORT_LAST) {
+ ret = false;
+ goto exit;
+ } else if (dio_path_info->phys_port[1] !=
+ curr_dio_path_info.phys_port[1]) {
+ if (LP1_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_PHYS2_UPDATE_FLAG) {
+ if (dio_path_info->phys_port[2] > MCDRV_PHYSPORT_LAST) {
+ ret = false;
+ goto exit;
+ } else if (dio_path_info->phys_port[2] !=
+ curr_dio_path_info.phys_port[2]) {
+ if (LP2_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_PHYS3_UPDATE_FLAG) {
+ if (dio_path_info->phys_port[3] > MCDRV_PHYSPORT_LAST) {
+ ret = false;
+ goto exit;
+ } else if (dio_path_info->phys_port[3] !=
+ curr_dio_path_info.phys_port[3]) {
+ if (LP3_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_DIR0SLOT_UPDATE_FLAG) {
+ if (dio_path_info->music_rslot[0] > 3) {
+ ret = false;
+ goto exit;
+ } else if (dio_path_info->music_rslot[0] !=
+ curr_dio_path_info.music_rslot[0]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_DIR1SLOT_UPDATE_FLAG) {
+ if (dio_path_info->music_rslot[1] > 3) {
+ ret = false;
+ } else if (dio_path_info->music_rslot[1] !=
+ curr_dio_path_info.music_rslot[1]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_DIR2SLOT_UPDATE_FLAG) {
+ if (dio_path_info->music_rslot[2] > 3) {
+ ret = false;
+ } else if (dio_path_info->music_rslot[2] !=
+ curr_dio_path_info.music_rslot[2]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_DIT0SLOT_UPDATE_FLAG) {
+ if (dio_path_info->music_tslot[0] > 3) {
+ ret = false;
+ } else if (dio_path_info->music_tslot[0] !=
+ curr_dio_path_info.music_tslot[0]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_DIT1SLOT_UPDATE_FLAG) {
+ if (dio_path_info->music_tslot[1] > 3) {
+ ret = false;
+ } else if (dio_path_info->music_tslot[1] !=
+ curr_dio_path_info.music_tslot[1]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+ if (update & MCDRV_DIT2SLOT_UPDATE_FLAG) {
+ if (dio_path_info->music_tslot[2] > 3) {
+ ret = false;
+ } else if (dio_path_info->music_tslot[2] !=
+ curr_dio_path_info.music_tslot[2]) {
+ if (LP0_start) {
+ ret = false;
+ goto exit;
+ }
+ }
+ }
+
+exit:
+ return ret;
+}
+
+static inline bool is_valid_swap_info(struct mcdrv_swap_info *info,
+ unsigned int update)
+{
+ bool ret = true;
+
+ if (update & MCDRV_SWAP_ADIF0_UPDATE_FLAG)
+ if (info->adif0 > MCDRV_SWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_ADIF1_UPDATE_FLAG)
+ if (info->adif1 > MCDRV_SWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_ADIF2_UPDATE_FLAG)
+ if (info->adif2 > MCDRV_SWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_DAC0_UPDATE_FLAG)
+ if (info->dac0 > MCDRV_SWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_DAC1_UPDATE_FLAG)
+ if (info->dac1 > MCDRV_SWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_MUSICIN0_UPDATE_FLAG)
+ if (info->music_in0 > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_MUSICIN1_UPDATE_FLAG)
+ if (info->music_in1 > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_MUSICIN2_UPDATE_FLAG)
+ if (info->music_in2 > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_EXTIN_UPDATE_FLAG)
+ if (info->ext_in > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_VOICEIN_UPDATE_FLAG)
+ if (info->voice_in > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_HIFIIN_UPDATE_FLAG)
+ if (info->hifi_in > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG)
+ if (info->music_out0 > MCDRV_SWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG)
+ if (info->music_out1 > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG)
+ if (info->music_out2 > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_EXTOUT_UPDATE_FLAG)
+ if (info->ext_out > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_VOICEOUT_UPDATE_FLAG)
+ if (info->voice_out > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ if (update & MCDRV_SWAP_HIFIOUT_UPDATE_FLAG)
+ if (info->hifi_out > MCDRV_SWSWAP_LAST)
+ ret = false;
+
+ return ret;
+}
+
+static inline bool is_valid_aec_info(struct mcdrv_aec_info *info)
+{
+ struct mcdrv_aec_info curr_info;
+ bool bdsp_used = false, cdsp_used = false, fdsp_used = false;
+ bool ret = true;
+
+ mc_aec_info_get(&curr_info);
+
+ if (mc_d1_source_is_used(MCDRV_D1SRC_AE0_ON | MCDRV_D1SRC_AE1_ON |
+ MCDRV_D1SRC_AE2_ON | MCDRV_D1SRC_AE3_ON)) {
+ bdsp_used = true;
+ if (!curr_info.fdsp_locate)
+ fdsp_used = true;
+ }
+
+ if (mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0) ||
+ mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1) ||
+ mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2) ||
+ mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3) ||
+ mc_source_is_used(MCDRV_DST_VBOXHOSTIN, MCDRV_DST_CH0)) {
+ cdsp_used = true;
+ if (curr_info.fdsp_locate)
+ fdsp_used = true;
+ }
+
+ if (bdsp_used || cdsp_used || fdsp_used)
+ if (info->fdsp_locate != 0xFF)
+ if (info->fdsp_locate != curr_info.fdsp_locate) {
+ ret = false;
+ goto exit;
+ }
+
+ if (bdsp_used || fdsp_used)
+ if (info->audio_engine.enable) {
+ if (info->audio_engine.bdsp_ae0_src != 2 &&
+ info->audio_engine.bdsp_ae0_src !=
+ curr_info.audio_engine.bdsp_ae0_src) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->audio_engine.bdsp_ae1_src != 2 &&
+ info->audio_engine.bdsp_ae1_src !=
+ curr_info.audio_engine.bdsp_ae1_src) {
+ ret = false;
+ goto exit;
+ }
+ if (info->audio_engine.mixer_in0_src != 2 &&
+ info->audio_engine.mixer_in0_src !=
+ curr_info.audio_engine.mixer_in0_src) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->audio_engine.mixer_in1_src != 2 &&
+ info->audio_engine.mixer_in1_src !=
+ curr_info.audio_engine.mixer_in1_src) {
+ ret = false;
+ goto exit;
+ }
+ if (info->audio_engine.mixer_in2_src != 2 &&
+ info->audio_engine.mixer_in2_src !=
+ curr_info.audio_engine.mixer_in2_src) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->audio_engine.mixer_in3_src != 2 &&
+ info->audio_engine.mixer_in3_src !=
+ curr_info.audio_engine.mixer_in3_src) {
+ ret = false;
+ goto exit;
+ }
+ }
+
+ if (cdsp_used || fdsp_used)
+ if (info->vbox.enable) {
+ if (info->vbox.fdsp_po_source != 0xFF &&
+ info->vbox.fdsp_po_source !=
+ curr_info.vbox.fdsp_po_source) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.isrc2_vsource != 0xFF &&
+ info->vbox.isrc2_vsource !=
+ curr_info.vbox.isrc2_vsource) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.isrc2_ch1_vsource != 0xFF &&
+ info->vbox.isrc2_ch1_vsource !=
+ curr_info.vbox.isrc2_ch1_vsource) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.isrc3_vsource != 0xFF &&
+ info->vbox.isrc3_vsource !=
+ curr_info.vbox.isrc3_vsource) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.lpt2_vsource != 0xFF &&
+ info->vbox.lpt2_vsource !=
+ curr_info.vbox.lpt2_vsource) {
+ ret = false;
+ goto exit;
+ }
+ }
+
+ if (cdsp_used)
+ if (info->vbox.enable) {
+ if (info->vbox.src3_ctrl != 0xFF &&
+ info->vbox.src3_ctrl != curr_info.vbox.src3_ctrl) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.src2_fs != 0xFF &&
+ info->vbox.src2_fs != curr_info.vbox.src2_fs) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.src2_thru != 0xFF &&
+ info->vbox.src2_thru != curr_info.vbox.src2_thru) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.src3_fs != 0xFF &&
+ info->vbox.src3_fs != curr_info.vbox.src3_fs) {
+ ret = false;
+ goto exit;
+ }
+
+ if (info->vbox.src3_thru != 0xFF &&
+ info->vbox.src3_thru != curr_info.vbox.src3_thru) {
+ ret = false;
+ goto exit;
+ }
+ }
+
+exit:
+ return ret;
+}
+
+static bool is_valid_hsdet_info(struct mcdrv_hsdet_info *info,
+ unsigned int update)
+{
+ struct mcdrv_hsdet_info hsdet_info;
+
+ mc_hsdet_info_get(&hsdet_info);
+
+ if (update & MCDRV_ENPLUGDET_UPDATE_FLAG)
+ if (info->en_plug_det_db > MCDRV_PLUGDETDB_LAST)
+ return false;
+
+ if (update & MCDRV_ENDLYKEYOFF_UPDATE_FLAG)
+ if (info->en_dly_key_off > MCDRV_KEYEN_LAST)
+ return false;
+
+ if (update & MCDRV_ENDLYKEYON_UPDATE_FLAG)
+ if (info->en_dly_key_on > MCDRV_KEYEN_LAST)
+ return false;
+
+ if (update & MCDRV_ENKEYOFF_UPDATE_FLAG)
+ if (info->en_key_off > MCDRV_KEYEN_LAST)
+ return false;
+
+ if (update & MCDRV_ENKEYON_UPDATE_FLAG)
+ if (info->en_key_on > MCDRV_KEYEN_LAST)
+ return false;
+
+ if (update & MCDRV_HSDETDBNC_UPDATE_FLAG)
+ if (info->hs_det_dbnc > MCDRV_DETDBNC_LAST)
+ return false;
+
+ if (update & MCDRV_KEYOFFMTIM_UPDATE_FLAG)
+ hsdet_info.key_off_mtim = info->key_off_mtim;
+
+ if (update & MCDRV_KEYONMTIM_UPDATE_FLAG)
+ hsdet_info.key_on_mtim = info->key_on_mtim;
+
+ if (update & MCDRV_KEY0OFFDLYTIM_UPDATE_FLAG) {
+ if (info->key0_off_dly_tim > MC_DRV_KEYOFFDLYTIM_MAX)
+ return false;
+ else if (hsdet_info.key_off_mtim == MCDRV_KEYOFF_MTIM_63 &&
+ info->key0_off_dly_tim == 1)
+ return false;
+ }
+
+ if (update & MCDRV_KEY1OFFDLYTIM_UPDATE_FLAG) {
+ if (info->key1_off_dly_tim > MC_DRV_KEYOFFDLYTIM_MAX)
+ return false;
+ else if (hsdet_info.key_off_mtim == MCDRV_KEYOFF_MTIM_63 &&
+ info->key1_off_dly_tim == 1)
+ return false;
+ }
+
+ if (update & MCDRV_KEY2OFFDLYTIM_UPDATE_FLAG) {
+ if (info->key2_off_dly_tim > MC_DRV_KEYOFFDLYTIM_MAX)
+ return false;
+ else if (hsdet_info.key_off_mtim == MCDRV_KEYOFF_MTIM_63 &&
+ info->key2_off_dly_tim == 1)
+ return false;
+ }
+
+ if (update & MCDRV_KEY0ONDLYTIM_UPDATE_FLAG) {
+ if (info->key0_on_dly_tim > MC_DRV_KEYONDLYTIM_MAX)
+ return false;
+ else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 &&
+ (info->key0_on_dly_tim == 1 ||
+ info->key0_on_dly_tim == 2 ||
+ info->key0_on_dly_tim == 3))
+ return false;
+ }
+
+ if (update & MCDRV_KEY1ONDLYTIM_UPDATE_FLAG) {
+ if (info->key1_on_dly_tim > MC_DRV_KEYONDLYTIM_MAX)
+ return false;
+ else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 &&
+ (info->key1_on_dly_tim == 1 ||
+ info->key1_on_dly_tim == 2 ||
+ info->key1_on_dly_tim == 3))
+ return false;
+ }
+
+ if (update & MCDRV_KEY2ONDLYTIM_UPDATE_FLAG) {
+ if (info->key2_on_dly_tim > MC_DRV_KEYONDLYTIM_MAX)
+ return false;
+ else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 &&
+ (info->key2_on_dly_tim == 1 ||
+ info->key2_on_dly_tim == 2 ||
+ info->key2_on_dly_tim == 3))
+ return false;
+ }
+
+ if (update & MCDRV_KEY0ONDLYTIM2_UPDATE_FLAG) {
+ if (info->key0_on_dly_tim2 > MC_DRV_KEYONDLYTIM2_MAX)
+ return false;
+ else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 &&
+ (info->key0_on_dly_tim2 == 1 ||
+ info->key0_on_dly_tim2 == 2 ||
+ info->key0_on_dly_tim2 == 3))
+ return false;
+ }
+
+ if (update & MCDRV_KEY1ONDLYTIM2_UPDATE_FLAG) {
+ if (info->key1_on_dly_tim2 > MC_DRV_KEYONDLYTIM2_MAX)
+ return false;
+ else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 &&
+ (info->key1_on_dly_tim2 == 1 ||
+ info->key1_on_dly_tim2 == 2 ||
+ info->key1_on_dly_tim2 == 3))
+ return false;
+ }
+
+ if (update & MCDRV_KEY2ONDLYTIM2_UPDATE_FLAG) {
+ if (info->key2_on_dly_tim2 > MC_DRV_KEYONDLYTIM2_MAX)
+ return false;
+ else if (hsdet_info.key_on_mtim == MCDRV_KEYON_MTIM_250 &&
+ (info->key2_on_dly_tim2 == 1 ||
+ info->key2_on_dly_tim2 == 2 ||
+ info->key2_on_dly_tim2 == 3))
+ return false;
+ }
+
+ if (update & MCDRV_IRQTYPE_UPDATE_FLAG) {
+ if (info->irq_type == MCDRV_IRQTYPE_EX) {
+ if (info->plug_det_db_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->plug_undet_db_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->mic_det_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->plug_det_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->key0_on_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->key1_on_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->key2_on_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->key0_off_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->key1_off_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ if (info->key2_off_irq_type > MCDRV_IRQTYPE_REF)
+ return false;
+ } else if (info->irq_type > MCDRV_IRQTYPE_LAST)
+ return false;
+ }
+
+ if (update & MCDRV_DETINV_UPDATE_FLAG)
+ if (info->det_in_inv > MCDRV_DET_IN_LAST)
+ return false;
+
+ if (update & MCDRV_HSDETMODE_UPDATE_FLAG)
+ if (info->hs_det_mode != MCDRV_HSDET_MODE_DETIN_A &&
+ info->hs_det_mode != MCDRV_HSDET_MODE_DETIN_B)
+ return false;
+
+ if (update & MCDRV_SPERIOD_UPDATE_FLAG)
+ if (info->speriod > MCDRV_SPERIOD_LAST)
+ return false;
+
+ if (update & MCDRV_LPERIOD_UPDATE_FLAG)
+ if (info->lperiod > MCDRV_LPERIOD_LAST)
+ return false;
+
+ if (update & MCDRV_DBNCNUMPLUG_UPDATE_FLAG)
+ if (info->dbnc_num_plug > MCDRV_DBNC_NUM_LAST)
+ return false;
+
+ if (update & MCDRV_DBNCNUMMIC_UPDATE_FLAG)
+ if (info->dbnc_num_mic > MCDRV_DBNC_NUM_LAST)
+ return false;
+
+ if (update & MCDRV_DBNCNUMKEY_UPDATE_FLAG)
+ if (info->dbnc_num_key > MCDRV_DBNC_NUM_LAST)
+ return false;
+
+ if (update & MCDRV_SGNL_UPDATE_FLAG) {
+ if (info->sgnl_period > MCDRV_SGNLPERIOD_LAST)
+ return false;
+
+ if (info->sgnl_num != MCDRV_SGNLNUM_NONE
+ && info->sgnl_num > MCDRV_SGNLNUM_LAST)
+ return false;
+
+ if (info->sgnl_peak > MCDRV_SGNLPEAK_LAST)
+ return false;
+ }
+
+ return true;
+}
+
+static bool check_dio_common(struct mcdrv_dio_info *dio_info, u8 port)
+{
+ struct mcdrv_dio_common *dio_common;
+ bool ret = true;
+
+ dio_common = &dio_info->port[port].dio_common;
+
+ if (port == 3) {
+ if (dio_common->fs != MCDRV_FS_48000 &&
+ dio_common->fs != MCDRV_FS_192000 &&
+ dio_common->fs != MCDRV_FS_96000) {
+ ret = false;
+ goto exit;
+ }
+
+ if (dio_common->bck_fs != MCDRV_BCKFS_64 &&
+ dio_common->bck_fs != MCDRV_BCKFS_48 &&
+ dio_common->bck_fs != MCDRV_BCKFS_32)
+ ret = false;
+ goto exit;
+ }
+
+ if (dio_common->fs > MCDRV_FS_LAST ||
+ dio_common->fs == MCDRV_FS_NONE1 ||
+ dio_common->fs == MCDRV_FS_NONE2 ||
+ dio_common->fs == MCDRV_FS_NONE3)
+ ret = false;
+ else if (dio_common->bck_fs > MCDRV_BCKFS_LAST ||
+ dio_common->bck_fs == MCDRV_BCKFS_NONE1 ||
+ dio_common->bck_fs == MCDRV_BCKFS_NONE2 ||
+ dio_common->bck_fs == MCDRV_BCKFS_NONE3 ||
+ dio_common->bck_fs == MCDRV_BCKFS_NONE4)
+ ret = false;
+ else if (dio_common->interface == MCDRV_DIO_PCM &&
+ dio_common->pcm_high_period > 31)
+ ret = false;
+
+ if (dio_common->interface == MCDRV_DIO_PCM) {
+ if (dio_common->fs != MCDRV_FS_8000 &&
+ dio_common->fs != MCDRV_FS_16000)
+ ret = false;
+
+ if (dio_common->bck_fs == MCDRV_BCKFS_512 &&
+ dio_common->fs != MCDRV_FS_8000)
+ ret = false;
+
+ if (dio_common->bck_fs == MCDRV_BCKFS_256 &&
+ (dio_common->fs != MCDRV_FS_8000 &&
+ dio_common->fs != MCDRV_FS_16000))
+ ret = false;
+
+ if (dio_common->master_slave == MCDRV_DIO_MASTER &&
+ dio_common->bck_fs == MCDRV_BCKFS_SLAVE)
+ ret = false;
+ } else {
+ if (port == 0 || port == 1) {
+ if (dio_common->fs == MCDRV_FS_192000 ||
+ dio_common->fs == MCDRV_FS_96000)
+ ret = false;
+ }
+
+ if (dio_common->bck_fs != MCDRV_BCKFS_64 &&
+ dio_common->bck_fs != MCDRV_BCKFS_48 &&
+ dio_common->bck_fs != MCDRV_BCKFS_32)
+ ret = false;
+ }
+
+exit:
+ return ret;
+}
+
+static bool check_da_format(struct mcdrv_da_format *da_format)
+{
+ bool ret = true;
+
+ if (da_format->bit_sel > MCDRV_BITSEL_LAST)
+ ret = false;
+ else if (da_format->mode > MCDRV_DAMODE_LAST)
+ ret = false;
+
+ return ret;
+}
+
+static bool check_pcm_format(struct mcdrv_pcm_format *pcm_format)
+{
+ bool ret = true;
+
+ if (pcm_format->law > MCDRV_PCM_LAST)
+ ret = false;
+ else if (pcm_format->bit_sel > MCDRV_PCM_BITSEL_LAST)
+ ret = false;
+ else if ((pcm_format->law == MCDRV_PCM_ALAW ||
+ pcm_format->law == MCDRV_PCM_MULAW) &&
+ pcm_format->bit_sel != MCDRV_PCM_BITSEL_8)
+ ret = false;
+
+ return ret;
+}
+
+static bool check_dio_dir(struct mcdrv_dio_info *dio_info,
+ u8 port, u8 interface)
+{
+ bool ret = true;
+
+ if (interface == MCDRV_DIO_PCM)
+ ret = check_pcm_format(&dio_info->port[port].dir.pcm_format);
+ else {
+ ret = check_da_format(&dio_info->port[port].dir.da_format);
+ if (dio_info->port[port].dir.da_format.bit_sel ==
+ MCDRV_BITSEL_32)
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool check_dio_dit(struct mcdrv_dio_info *dio_info,
+ u8 port, u8 interface)
+{
+ bool ret = true;
+
+ if (interface == MCDRV_DIO_PCM)
+ ret = check_pcm_format(&dio_info->port[port].dit.pcm_format);
+ else {
+ ret = check_da_format(&dio_info->port[port].dit.da_format);
+ if (dio_info->port[port].dit.da_format.bit_sel ==
+ MCDRV_BITSEL_32 && port != 2)
+ ret = false;
+ }
+
+ return ret;
+}
+
+static inline bool is_valid_dio_info(struct mcdrv_dio_info *dio_info,
+ unsigned int update)
+{
+ struct mcdrv_dio_info curr_dio_info;
+ u8 val;
+ bool LPR0_start = 0, LPT0_start = 0;
+ bool LPR1_start = 0, LPT1_start = 0;
+ bool LPR2_start = 0, LPT2_start = 0;
+ bool LPR3_start = 0, LPT3_start = 0;
+ bool ret = true;
+
+ mc_dio_info_get(&curr_dio_info);
+
+ val = mc_mb_register_get_value(MCI_LP0_START);
+ if (val & MCB_LPR0_START)
+ LPR0_start = true;
+ if (val & MCB_LPT0_START)
+ LPT0_start = true;
+
+ val = mc_mb_register_get_value(MCI_LP1_START);
+ if (val & MCB_LPR1_START)
+ LPR1_start = true;
+ if (val & MCB_LPT1_START)
+ LPT1_start = true;
+
+ val = mc_mb_register_get_value(MCI_LP2_START);
+ if (val & MCB_LPR2_START)
+ LPR2_start = true;
+ if (val & MCB_LPT2_START)
+ LPT2_start = true;
+
+ val = mc_mb_register_get_value(MCI_LP3_START);
+ if (val & MCB_LPR3_START)
+ LPR3_start = true;
+ if (val & MCB_LPT3_START)
+ LPT3_start = true;
+
+ if ((update & MCDRV_MUSIC_COM_UPDATE_FLAG) ||
+ (update & MCDRV_MUSIC_DIR_UPDATE_FLAG)) {
+ if (LPR0_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_MUSIC_COM_UPDATE_FLAG) ||
+ (update & MCDRV_MUSIC_DIT_UPDATE_FLAG)) {
+ if (LPT0_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_EXT_COM_UPDATE_FLAG) ||
+ (update & MCDRV_EXT_DIR_UPDATE_FLAG)) {
+ if (LPR1_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_EXT_COM_UPDATE_FLAG) ||
+ (update & MCDRV_EXT_DIT_UPDATE_FLAG)) {
+ if (LPT1_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_VOICE_COM_UPDATE_FLAG) ||
+ (update & MCDRV_VOICE_DIR_UPDATE_FLAG)) {
+ if (LPR2_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_VOICE_COM_UPDATE_FLAG) ||
+ (update & MCDRV_VOICE_DIT_UPDATE_FLAG)) {
+ if (LPT2_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_HIFI_COM_UPDATE_FLAG) ||
+ (update & MCDRV_HIFI_DIR_UPDATE_FLAG)) {
+ if (LPR3_start)
+ ret = false;
+ }
+
+ if ((update & MCDRV_HIFI_COM_UPDATE_FLAG) ||
+ (update & MCDRV_HIFI_DIT_UPDATE_FLAG)) {
+ if (LPT3_start)
+ ret = false;
+ }
+
+ if (ret && (update & MCDRV_MUSIC_COM_UPDATE_FLAG)) {
+ ret = check_dio_common(dio_info, 0);
+ if (ret)
+ curr_dio_info.port[0].dio_common.interface
+ = dio_info->port[0].dio_common.interface;
+ }
+
+ if (ret && (update & MCDRV_EXT_COM_UPDATE_FLAG)) {
+ ret = check_dio_common(dio_info, 1);
+ if (ret)
+ curr_dio_info.port[1].dio_common.interface
+ = dio_info->port[1].dio_common.interface;
+ }
+
+ if (ret && (update & MCDRV_VOICE_COM_UPDATE_FLAG)) {
+ ret = check_dio_common(dio_info, 2);
+ if (ret)
+ curr_dio_info.port[2].dio_common.interface
+ = dio_info->port[2].dio_common.interface;
+ }
+
+ if (ret && (update & MCDRV_HIFI_COM_UPDATE_FLAG)) {
+ ret = check_dio_common(dio_info, 3);
+ if (ret)
+ curr_dio_info.port[3].dio_common.interface
+ = dio_info->port[3].dio_common.interface;
+ }
+
+ if (ret && (update & MCDRV_MUSIC_DIR_UPDATE_FLAG)) {
+ ret = check_dio_dir(dio_info, 0,
+ curr_dio_info.port[0].dio_common.interface);
+ }
+
+ if (ret && (update & MCDRV_EXT_DIR_UPDATE_FLAG)) {
+ ret = check_dio_dir(dio_info, 1,
+ curr_dio_info.port[1].dio_common.interface);
+ }
+
+ if (ret && (update & MCDRV_VOICE_DIR_UPDATE_FLAG)) {
+ ret = check_dio_dir(dio_info, 2,
+ curr_dio_info.port[2].dio_common.interface);
+ }
+
+ if (ret && (update & MCDRV_MUSIC_DIT_UPDATE_FLAG)) {
+ ret = check_dio_dit(dio_info, 0,
+ curr_dio_info.port[0].dio_common.interface);
+ }
+
+ if (ret && (update & MCDRV_EXT_DIT_UPDATE_FLAG))
+ ret = check_dio_dit(dio_info, 1,
+ curr_dio_info.port[1].dio_common.interface);
+
+ if (ret && (update & MCDRV_VOICE_DIT_UPDATE_FLAG))
+ ret = check_dio_dit(dio_info, 2,
+ curr_dio_info.port[2].dio_common.interface);
+
+ return ret;
+}
+
+static inline int set_vol(u32 update, enum mcdrv_volume_mode mode, u32 *status)
+{
+ mc_packet_add_volume(update, mode, status);
+
+ return mc_packet_execute();
+}
+
+static inline void get_mute(u8 *dir_mute, u8 *adc_mute,
+ u8 *dit_mute, u8 *dac_mute)
+{
+ u8 vol;
+
+ *dir_mute = 0;
+ *adc_mute = 0;
+ *dit_mute = 0;
+ *dac_mute = 0;
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_MUSICIN_ON)) {
+ vol = mc_ma_register_get_value(MCI_DIFI0_VOL0);
+ if (vol & ~MCB_DIFI0_VSEP)
+ *dir_mute |= MCB_DIFI0_VFLAG0;
+
+ vol = mc_ma_register_get_value(MCI_DIFI0_VOL1);
+ if (vol)
+ *dir_mute |= MCB_DIFI0_VFLAG1;
+ }
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_EXTIN_ON)) {
+ vol = mc_ma_register_get_value(MCI_DIFI1_VOL0);
+ if (vol & ~MCB_DIFI1_VSEP)
+ *dir_mute |= MCB_DIFI1_VFLAG0;
+
+ vol = mc_ma_register_get_value(MCI_DIFI1_VOL1);
+ if (vol)
+ *dir_mute |= MCB_DIFI1_VFLAG1;
+ }
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXOUT_ON)) {
+ vol = mc_ma_register_get_value(MCI_DIFI2_VOL0);
+ if (vol & ~MCB_DIFI2_VSEP)
+ *dir_mute |= MCB_DIFI2_VFLAG0;
+
+ vol = mc_ma_register_get_value(MCI_DIFI2_VOL1);
+ if (vol)
+ *dir_mute |= MCB_DIFI2_VFLAG1;
+ }
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_VBOXREFOUT_ON)) {
+ vol = mc_ma_register_get_value(MCI_DIFI3_VOL0);
+ if (vol & ~MCB_DIFI3_VSEP)
+ *dir_mute |= MCB_DIFI3_VFLAG0;
+
+ vol = mc_ma_register_get_value(MCI_DIFI3_VOL1);
+ if (vol)
+ *dir_mute |= MCB_DIFI3_VFLAG1;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH0)) {
+ vol = mc_ma_register_get_value(MCI_DAO0_VOL0);
+ if (vol & ~MCB_DAO0_VSEP)
+ *dac_mute |= MCB_DAO0_VFLAG0;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_DAC0, MCDRV_DST_CH1)) {
+ vol = mc_ma_register_get_value(MCI_DAO0_VOL1);
+ if (vol)
+ *dac_mute |= MCB_DAO0_VFLAG1;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH0)) {
+ vol = mc_ma_register_get_value(MCI_DAO1_VOL0);
+ if (vol & ~MCB_DAO1_VSEP)
+ *dac_mute |= MCB_DAO1_VFLAG0;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_DAC1, MCDRV_DST_CH1)) {
+ vol = mc_ma_register_get_value(MCI_DAO1_VOL1);
+ if (vol)
+ *dac_mute |= MCB_DAO1_VFLAG1;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH0)) {
+ vol = mc_ma_register_get_value(MCI_DIFO0_VOL0);
+ if (vol & ~MCB_DIFO0_VSEP)
+ *dit_mute |= MCB_DIFO0_VFLAG0;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_MUSICOUT, MCDRV_DST_CH1)) {
+ vol = mc_ma_register_get_value(MCI_DIFO0_VOL1);
+ if (vol)
+ *dit_mute |= MCB_DIFO0_VFLAG1;
+
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH0)) {
+ vol = mc_ma_register_get_value(MCI_DIFO1_VOL0);
+ if (vol & ~MCB_DIFO1_VSEP)
+ *dit_mute |= MCB_DIFO1_VFLAG0;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_EXTOUT, MCDRV_DST_CH1)) {
+ vol = mc_ma_register_get_value(MCI_DIFO1_VOL1);
+ if (vol)
+ *dit_mute |= MCB_DIFO1_VFLAG1;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH0)) {
+ vol = mc_ma_register_get_value(MCI_DIFO2_VOL0);
+ if (vol & ~MCB_DIFO2_VSEP)
+ *dit_mute |= MCB_DIFO2_VFLAG0;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH1)) {
+ vol = mc_ma_register_get_value(MCI_DIFO2_VOL1);
+ if (vol)
+ *dit_mute |= MCB_DIFO2_VFLAG1;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH2)) {
+ vol = mc_ma_register_get_value(MCI_DIFO3_VOL0);
+ if (vol & ~MCB_DIFO2_VSEP)
+ *dit_mute |= MCB_DIFO3_VFLAG0;
+ }
+
+ if (!mc_source_is_used(MCDRV_DST_VBOXMIXIN, MCDRV_DST_CH3)) {
+ vol = mc_ma_register_get_value(MCI_DIFO3_VOL1);
+ if (vol)
+ *dit_mute |= MCB_DIFO3_VFLAG1;
+ }
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF0_ON)) {
+ vol = mc_ma_register_get_value(MCI_ADI0_VOL0);
+ if (vol & ~MCB_ADI0_VSEP)
+ *adc_mute |= MCB_ADI0_VFLAG0;
+ vol = mc_ma_register_get_value(MCI_ADI0_VOL1);
+ if (vol)
+ *adc_mute |= MCB_ADI0_VFLAG1;
+ }
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF1_ON)) {
+ vol = mc_ma_register_get_value(MCI_ADI1_VOL1);
+ if (vol & ~MCB_ADI1_VSEP)
+ *adc_mute |= MCB_ADI1_VFLAG0;
+ vol = mc_ma_register_get_value(MCI_ADI1_VOL1);
+ if (vol)
+ *adc_mute |= MCB_ADI1_VFLAG1;
+ }
+
+ if (!mc_d1_source_is_used(MCDRV_D1SRC_ADIF2_ON)) {
+ vol = mc_ma_register_get_value(MCI_ADI2_VOL1);
+ if (vol & ~MCB_ADI2_VSEP)
+ *adc_mute |= MCB_ADI2_VFLAG0;
+
+ vol = mc_ma_register_get_value(MCI_ADI2_VOL1);
+ if (vol)
+ *adc_mute |= MCB_ADI2_VFLAG1;
+ }
+}
+
+static int save_power(void)
+{
+ struct mcdrv_power_info power;
+ struct mcdrv_power_update update;
+ int ret;
+
+ /* unused path power down */
+ mc_power_info_get(&power);
+
+ update.digital = MCDRV_POWUPDATE_D_ALL;
+ update.analog[0] = MCDRV_POWUPDATE_AP;
+ update.analog[1] = MCDRV_POWUPDATE_AP_OUT0;
+ update.analog[2] = MCDRV_POWUPDATE_AP_OUT1;
+ update.analog[3] = MCDRV_POWUPDATE_AP_MC;
+ update.analog[4] = MCDRV_POWUPDATE_AP_IN;
+
+ ret = mc_packet_add_powerdown(&power, &update);
+ if (!ret)
+ ret = mc_packet_execute();
+
+ return ret;
+}
+
+static inline bool is_valid_clock(u8 clock)
+{
+ if (clock != MCDRV_CLKSW_CLKA && clock != MCDRV_CLKSW_CLKB)
+ return false;
+
+ return true;
+}
+
+static inline int get_clock(u8 *clock)
+{
+
+ mc_clock_get(clock);
+
+ return 0;
+}
+
+static inline int set_clock(u8 *clock)
+{
+ u8 old_clock;
+
+ if (!is_valid_clock(*clock))
+ return -EINVAL;
+
+ mc_clock_get(&old_clock);
+ if (*clock == old_clock)
+ return 0;
+
+ return mc_clock_set(*clock);
+}
+
+static inline int get_path(struct mcdrv_path_info *path_info)
+{
+ if (!path_info)
+ return -EINVAL;
+
+ mc_path_info_get_virtual(path_info);
+
+ return 0;
+}
+
+static int set_path(struct mcdrv_path_info *path_info)
+{
+ struct mcdrv_power_info power;
+ struct mcdrv_power_update update;
+ u32 status;
+ u8 val, dir_mute, adc_mute, dit_mute, dac_mute, hp_vol_l, hp_vol_r;
+ u8 dsp_started = mc_dsp_get_running();
+ int ret;
+
+ if (!path_info)
+ return -EINVAL;
+
+ mask_irregular_path_info(path_info);
+
+ ret = mc_path_info_set(path_info);
+ if (ret < 0)
+ return ret;
+
+ hp_vol_l = mc_ana_register_get_value(MCI_HPVOL_L);
+ hp_vol_l &= ~MCB_ALAT_HP;
+ hp_vol_r = mc_ana_register_get_value(MCI_HPVOL_R);
+
+ /* unused analog out volume mute */
+ ret = set_vol(MCDRV_VOLUPDATE_ANA_OUT, MCDRV_VOLUME_MUTE, &status);
+ if (ret < 0)
+ return ret;
+
+ if (status)
+ mc_packet_add_wait_event(MCDRV_EVT_SVOL_DONE | status);
+
+ get_mute(&dir_mute, &adc_mute, &dit_mute, &dac_mute);
+
+ /* unused volume mute */
+ ret = set_vol(MCDRV_VOLUPDATE_DIG, MCDRV_VOLUME_MUTE, NULL);
+ if (ret < 0)
+ return ret;
+
+ /* set volume */
+ ret = set_vol(MCDRV_VOLUPDATE_ANA_IN, MCDRV_VOLUME_SET, NULL);
+ if (ret < 0)
+ return ret;
+
+ if (dir_mute)
+ mc_packet_add_wait_event(MCDRV_EVT_DIRMUTE | dir_mute);
+
+ if (adc_mute)
+ mc_packet_add_wait_event(MCDRV_EVT_ADCMUTE | adc_mute);
+
+ if (dit_mute)
+ mc_packet_add_wait_event(MCDRV_EVT_DITMUTE | dit_mute);
+
+ if (dac_mute)
+ mc_packet_add_wait_event(MCDRV_EVT_DACMUTE | dac_mute);
+
+ mc_packet_add_fdsp_stop(dsp_started);
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ /* stop unused path */
+ mc_packet_add_stop();
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ mc_power_info_get(&power);
+
+ /* unused analog out path power down */
+ update.digital = 0;
+ update.analog[0] = 0;
+ update.analog[1] = MCDRV_POWUPDATE_AP_OUT0;
+ update.analog[2] = MCDRV_POWUPDATE_AP_OUT1;
+ update.analog[3] = 0;
+ update.analog[4] = 0;
+ ret = mc_packet_add_powerdown(&power, &update);
+ if (ret < 0)
+ return ret;
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ /* used path power up */
+ update.digital = MCDRV_POWUPDATE_D_ALL;
+ update.analog[0] = MCDRV_POWUPDATE_AP;
+ update.analog[1] = MCDRV_POWUPDATE_AP_OUT0;
+ update.analog[2] = MCDRV_POWUPDATE_AP_OUT1;
+ update.analog[3] = MCDRV_POWUPDATE_AP_MC;
+ update.analog[4] = MCDRV_POWUPDATE_AP_IN;
+ ret = mc_packet_add_powerup(&power, &update);
+ if (ret < 0)
+ return ret;
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ /* set mixer */
+ mc_packet_add_path_set();
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ /* DSP start */
+ mc_packet_add_dsp_start_and_stop(dsp_started);
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ if ((hp_vol_l || hp_vol_r)
+ && (!hp_vol_l || (status & (MCB_HPL_BUSY << 8)))
+ && (!hp_vol_r || (status & (MCB_HPR_BUSY << 8)))
+ && (power.analog[3] & MCB_MB4)) {
+ val = mc_ana_register_get_value(MCI_AP_MIC);
+ if (!(val & MCB_MB4))
+ mc_packet_add_wait(MCDRV_MB4_WAIT_TIME);
+ }
+
+ /* unused path power down */
+ update.digital = MCDRV_POWUPDATE_D_ALL;
+ update.analog[0] = MCDRV_POWUPDATE_AP;
+ update.analog[1] = MCDRV_POWUPDATE_AP_OUT0;
+ update.analog[2] = MCDRV_POWUPDATE_AP_OUT1;
+ update.analog[3] = MCDRV_POWUPDATE_AP_MC;
+ update.analog[4] = MCDRV_POWUPDATE_AP_IN;
+ ret = mc_packet_add_powerdown(&power, &update);
+ if (ret < 0)
+ return ret;
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ mc_packet_add_start();
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ /* set volume */
+ ret = set_vol(MCDRV_VOLUPDATE_DIG, MCDRV_VOLUME_SET, NULL);
+ if (ret < 0)
+ return ret;
+
+ return set_vol(MCDRV_VOLUPDATE_ANA_OUT, MCDRV_VOLUME_SET, &status);
+}
+
+static inline int get_volume(struct mcdrv_vol_info *vol_info)
+{
+ if (!vol_info)
+ return -EINVAL;
+
+ mc_vol_info_get(vol_info);
+
+ return 0;
+}
+
+static inline int set_volume(struct mcdrv_vol_info *vol_info)
+{
+ struct mcdrv_path_info path_info;
+
+ if (!vol_info)
+ return -EINVAL;
+
+ mc_vol_info_set(vol_info);
+
+ mc_path_info_get_virtual(&path_info);
+
+ return set_path(&path_info);
+}
+
+static inline int get_digitalio(struct mcdrv_dio_info *dio_info)
+{
+ if (!dio_info)
+ return -EINVAL;
+
+ mc_dio_info_get(dio_info);
+
+ return 0;
+}
+
+static inline int set_digitalio(struct mcdrv_dio_info *dio_info,
+ unsigned int update)
+{
+ if (!dio_info)
+ return -EINVAL;
+
+ if (!is_valid_dio_info(dio_info, update))
+ return -EINVAL;
+
+ mc_dio_info_set(dio_info, update);
+
+ mc_packet_add_digital_io(update);
+
+ return mc_packet_execute();
+}
+
+static inline int get_digitalio_path(struct mcdrv_dio_path_info *dio_path_info)
+{
+ if (!dio_path_info)
+ return -EINVAL;
+
+ mc_dio_path_info_get(dio_path_info);
+
+ return 0;
+}
+
+static inline int set_digitalio_path(struct mcdrv_dio_path_info *dio_path_info,
+ unsigned int update)
+{
+ if (!dio_path_info)
+ return -EINVAL;
+
+ if (!is_valid_dio_path_info(dio_path_info, update))
+ return -EINVAL;
+
+ mc_dio_path_info_set(dio_path_info, update);
+
+ mc_packet_add_digital_io_path();
+
+ return mc_packet_execute();
+}
+
+static inline int get_swap(struct mcdrv_swap_info *info)
+{
+ if (!info)
+ return -EINVAL;
+
+ mc_swap_info_get(info);
+
+ return 0;
+}
+
+static inline int set_swap(struct mcdrv_swap_info *info, unsigned int update)
+{
+ if (!info)
+ return -EINVAL;
+
+ if (!is_valid_swap_info(info, update))
+ return -EINVAL;
+
+ mc_swap_info_set(info, update);
+
+ mc_packet_add_swap(update);
+
+ return mc_packet_execute();
+}
+
+static inline bool is_path_alloff(void)
+{
+ struct mcdrv_path_info info;
+
+ mc_path_info_get_virtual(&info);
+ if (memcmp(&info, &path_alloff, sizeof(struct mcdrv_path_info)))
+ return false;
+
+ return true;
+}
+
+static int set_dsp(u8 *data, unsigned int size)
+{
+ struct mcdrv_aec_info info, curr_info;
+ struct mcdrv_power_info power;
+ struct mcdrv_power_update update;
+ static struct mcdrv_path_info path_info;
+ enum mcdrv_dev_id id;
+ static u8 g_lp2_start, g_src3_start;
+ u32 mute_flag;
+ int ret = 0;
+
+ if (!data || !size)
+ return -EINVAL;
+
+ id = mc_dev_id_get();
+
+ mc_aec_info_get(&info);
+ curr_info = info;
+
+ ret = mc_parser_d7_data_analyze(data, size, &info);
+ if (ret < 0)
+ return ret;
+
+ if (!is_valid_aec_info(&info))
+ return -EINVAL;
+
+ mc_aec_info_set(&info);
+ mc_aec_info_get(&info);
+
+ info.vbox.cdsp_func_a_on &= 0x01;
+ info.vbox.cdsp_func_b_on &= 0x01;
+
+ if (info.control.command == 1) {
+ if (!info.control.param[0] && !is_path_alloff()) {
+ mc_path_info_get_virtual(&path_info);
+
+ ret = set_path(&path_alloff);
+ if (ret < 0)
+ goto exit;
+ }
+ } else if (info.control.command == 2) {
+ if (!info.control.param[0]) {
+ g_lp2_start = mc_mb_register_get_value(MCI_LP2_START);
+ mc_packet_add_write_mb(MCI_LP2_START, 0);
+ g_src3_start = mc_mb_register_get_value(MCI_SRC3_START);
+ mc_packet_add_write_mb(MCI_SRC3_START, 0);
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+ }
+ } else if (info.control.command == 3) {
+ if (id == MCDRV_DEV_ID_81_91H) {
+ mc_packet_add_dout_mute();
+ mute_flag = MCB_DIFO3_VFLAG1 | MCB_DIFO3_VFLAG0 |
+ MCB_DIFO2_VFLAG1 | MCB_DIFO2_VFLAG0 |
+ MCB_DIFO1_VFLAG1 | MCB_DIFO1_VFLAG0 |
+ MCB_DIFO0_VFLAG1 | MCB_DIFO0_VFLAG0;
+ mc_packet_add_wait_event(MCDRV_EVT_DITMUTE | mute_flag);
+ mute_flag = MCB_DAO1_VFLAG1 | MCB_DAO1_VFLAG0 |
+ MCB_DAO0_VFLAG1 | MCB_DAO0_VFLAG0;
+ mc_packet_add_wait_event(MCDRV_EVT_DACMUTE | mute_flag);
+ mc_packet_add_write_ma(MCI_CLK_SEL,
+ info.control.param[0]);
+ mc_clock_select_set(info.control.param[0]);
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ ret = set_vol(MCDRV_VOLUPDATE_DOUT,
+ MCDRV_VOLUME_SET, NULL);
+ if (ret < 0)
+ goto exit;
+ }
+ } else if (info.control.command == 4) {
+ if (id == MCDRV_DEV_ID_81_91H) {
+ u32 status = 0;
+
+ mc_packet_add_dac0_mute();
+ mc_packet_add_dac1_mute();
+ mc_packet_add_adif_mute();
+ mc_packet_add_dpath_da_mute();
+ mute_flag = MCB_ADI2_VFLAG1 | MCB_ADI2_VFLAG0 |
+ MCB_ADI1_VFLAG1 | MCB_ADI1_VFLAG0 |
+ MCB_ADI0_VFLAG1 | MCB_ADI0_VFLAG0;
+ mc_packet_add_wait_event(MCDRV_EVT_ADCMUTE | mute_flag);
+
+ mute_flag = MCB_SPR_BUSY << 8 | MCB_SPL_BUSY << 8 |
+ MCB_HPR_BUSY << 8 | MCB_HPL_BUSY << 8 |
+ MCB_LO2R_BUSY | MCB_LO2L_BUSY |
+ MCB_LO1R_BUSY | MCB_LO1L_BUSY | MCB_RC_BUSY;
+ mc_packet_add_wait_event(MCDRV_EVT_SVOL_DONE |
+ mute_flag);
+ mc_packet_add_write_e(MCI_ECLK_SEL,
+ info.control.param[0]);
+ mc_e_clock_select_set(info.control.param[0]);
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ ret = set_vol(MCDRV_VOLUPDATE_ANA_OUT |
+ MCDRV_VOLUPDATE_ADIF0 |
+ MCDRV_VOLUPDATE_ADIF1 |
+ MCDRV_VOLUPDATE_ADIF2 |
+ MCDRV_VOLUPDATE_DPATHDA,
+ MCDRV_VOLUME_SET, &status);
+ if (ret < 0)
+ goto exit;
+ }
+
+ }
+
+ mc_power_info_get(&power);
+ update.digital = MCDRV_POWUPDATE_D_ALL;
+ update.analog[0] = MCDRV_POWUPDATE_AP;
+ update.analog[1] = MCDRV_POWUPDATE_AP_OUT0;
+ update.analog[2] = MCDRV_POWUPDATE_AP_OUT1;
+ update.analog[3] = MCDRV_POWUPDATE_AP_MC;
+ update.analog[4] = MCDRV_POWUPDATE_AP_IN;
+ ret = mc_packet_add_powerup(&power, &update);
+ if (ret < 0)
+ goto exit;
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ mc_packet_add_aec();
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ ret = mc_bdsp_set_dsp(&info);
+ if (ret < 0)
+ goto exit;
+
+ ret = mc_cdsp_set_dsp(&info);
+ if (ret < 0)
+ goto exit;
+
+ ret = mc_edsp_set_dsp(&info);
+ if (ret < 0)
+ goto exit;
+
+ ret = mc_fdsp_set_dsp(&info);
+ if (ret < 0)
+ goto exit;
+
+ if (info.control.command == 1) {
+ if (info.control.param[0] == 1) {
+ ret = set_path(&path_info);
+ if (ret < 0)
+ goto exit;
+ }
+ } else if (info.control.command == 2) {
+ if (info.control.param[0] == 1) {
+ mc_packet_add_write_mb(MCI_LP2_START, g_lp2_start);
+ mc_packet_add_write_mb(MCI_SRC3_START, g_src3_start);
+ }
+ }
+
+ mc_power_info_get(&power);
+
+ ret = mc_packet_add_powerdown(&power, &update);
+ if (ret < 0)
+ goto exit;
+
+ return mc_packet_execute();
+
+exit:
+ mc_aec_info_replace(&curr_info);
+ save_power();
+
+ return ret;
+}
+
+static inline int get_hsdet(struct mcdrv_hsdet_info *info)
+{
+ if (!info)
+ return -EINVAL;
+
+ mc_hsdet_info_get(info);
+
+ info->dly_irq_stop = 0;
+
+ return 0;
+}
+
+static int set_hsdet(struct mcdrv_hsdet_info *hsdet, unsigned int update)
+{
+ struct mcdrv_hsdet_info curr_hsdet;
+ struct mcdrv_path_info path_info, tmp_path_info;
+ struct mcdrv_hsdet_res hsdet_res;
+ enum mcdrv_dev_id id;
+ u8 val, data[2], plug_det_db;
+ int ret = 0;
+
+ if (!hsdet)
+ return -EINVAL;
+
+ curr_hsdet = *hsdet;
+ if (!is_valid_hsdet_info(&curr_hsdet, update))
+ return -EINVAL;
+
+ id = mc_dev_id_get();
+ if (id == MCDRV_DEV_ID_80_90H)
+ curr_hsdet.det_in_inv &= 1;
+
+ mc_hsdet_info_set(&curr_hsdet, update);
+ mc_packet_add_hsdet();
+ ret = mc_packet_execute();
+ if (ret < 0)
+ return ret;
+
+ mc_hsdet_info_get(&curr_hsdet);
+ if (curr_hsdet.en_plug_det_db != MCDRV_PLUGDETDB_DISABLE ||
+ curr_hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_mic_det != MCDRV_MICDET_DISABLE ||
+ curr_hsdet.en_key_off != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_key_on != MCDRV_KEYEN_D_D_D) {
+ val = mc_cd_register_get_value(MCI_HSDETEN);
+ if (!(val & MCB_MKDETEN)) {
+ val = MCB_HSDETEN | curr_hsdet.hs_det_dbnc;
+ mc_packet_add_write_cd(MCI_HSDETEN, val);
+
+ if (curr_hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_mic_det != MCDRV_MICDET_DISABLE ||
+ curr_hsdet.en_key_off != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_key_on != MCDRV_KEYEN_D_D_D) {
+ bool do_set_path = false;
+
+ if (is_ldoa_on()) {
+ mc_path_info_get_virtual(&path_info);
+ tmp_path_info = path_info;
+ tmp_path_info.adc0[0] = 0x00aaaaaa;
+ tmp_path_info.adc0[1] = 0x00aaaaaa;
+
+ tmp_path_info.adc1[0] = 0x00aaaaaa;
+
+ tmp_path_info.dac0[0] = 0x00aaaaaa;
+ tmp_path_info.dac0[1] = 0x00aaaaaa;
+ tmp_path_info.dac1[0] = 0x00aaaaaa;
+ tmp_path_info.dac1[1] = 0x00aaaaaa;
+
+ tmp_path_info.bias[0] = 0x002aaaaa;
+ tmp_path_info.bias[1] = 0x002aaaaa;
+ tmp_path_info.bias[2] = 0x002aaaaa;
+ tmp_path_info.bias[3] = 0x002aaaaa;
+ ret = set_path(&tmp_path_info);
+ if (ret < 0)
+ return ret;
+
+ do_set_path = true;
+ }
+
+ mc_packet_add_mic_key_detect_enable(true);
+
+ if (do_set_path)
+ ret = set_path(&path_info);
+ }
+ } else {
+ val = MCB_HSDETEN | curr_hsdet.hs_det_dbnc;
+ if (curr_hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_mic_det != MCDRV_MICDET_DISABLE ||
+ curr_hsdet.en_key_off != MCDRV_KEYEN_D_D_D ||
+ curr_hsdet.en_key_on != MCDRV_KEYEN_D_D_D) {
+ plug_det_db = mc_plug_detect_db_get();
+ if (plug_det_db & MCB_RPLUGDET_DB)
+ val |= MCB_MKDETEN;
+ }
+
+ mc_packet_add_write_cd(MCI_HSDETEN, val);
+
+ if (!(val & MCB_MKDETEN)) {
+ val = mc_ana_register_get_value(MCI_KDSET);
+ val &= ~(MCB_KDSET2 | MCB_KDSET1);
+ mc_packet_add_force_write_ana(MCI_KDSET, val);
+ }
+ }
+ }
+
+ if (!ret)
+ ret = mc_packet_execute();
+
+ if (!ret) {
+ if ((update & MCDRV_ENPLUGDETDB_UPDATE_FLAG) &&
+ (curr_hsdet.en_plug_det_db &
+ MCDRV_PLUGDETDB_UNDET_ENABLE) && curr_hsdet.cbfunc) {
+ data[0] = MCI_CD_REG_A << 1;
+ data[1] = MCI_PLUGDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ if (!(val & MCB_PLUGDET)) {
+ hsdet_res.key_cnt0 = 0;
+ hsdet_res.key_cnt1 = 0;
+ hsdet_res.key_cnt2 = 0;
+ mutex_unlock(&mcdrv_mutex);
+ (*curr_hsdet.
+ cbfunc) (MCDRV_HSDET_EVT_PLUGUNDET_DB_FLAG,
+ &hsdet_res);
+ mutex_lock(&mcdrv_mutex);
+ }
+ }
+
+ ret = save_power();
+ }
+
+ return ret;
+}
+
+static inline void enable_irqhs(u8 *data)
+{
+ data[1] = MCI_IRQHS;
+ data[3] = MCB_EIRQHS;
+ mc_write_analog(data, 4);
+
+ mc_cd_register_set_value(MCI_IRQHS, MCB_EIRQHS);
+}
+
+int mc_do_irq(void)
+{
+ struct mcdrv_aec_info aec;
+ struct mcdrv_path_info path;
+ struct mcdrv_hsdet_info hsdet;
+ struct mcdrv_hsdet_res hsdet_res;
+ enum mcdrv_dev_id id;
+ u32 flag_det = 0;
+ u8 val, splug_det, plug_det, sensefin, eirq, data[4];
+ u8 flag_dlykey = 0, flag_key = 0;
+ static u8 s_op_dac, s_hp_det;
+ unsigned long interval;
+ int cycles, timeout, ret = 0;
+
+ mutex_lock(&mcdrv_mutex);
+
+ id = mc_dev_id_get();
+ mc_hsdet_info_get(&hsdet);
+
+ eirq = mc_if_register_get_value(MCI_IRQ);
+ val = mc_cd_register_get_value(MCI_EIRQSENSE);
+ if (val & MCB_EIRQSENSE) {
+ /* IRQ Disable */
+ data[0] = MCI_IRQR << 1;
+ data[1] = 0;
+ mc_write_digital(data, 2);
+
+ data[0] = MCI_CD_REG_A << 1;
+ data[1] = MCI_SSENSEFIN;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &sensefin, 1);
+ if (sensefin & MCB_SSENSEFIN) {
+ data[1] = MCI_EIRQSENSE;
+ data[2] = MCI_CD_REG_D << 1;
+ data[3] = 0;
+ mc_write_analog(data, 4);
+
+ mc_cd_register_set_value(MCI_EIRQSENSE, 0);
+ data[1] = MCI_SSENSEFIN;
+ data[3] = val;
+ mc_write_analog(data, 4);
+ } else {
+ /* IRQ Enable */
+ data[0] = MCI_IRQR << 1;
+ data[1] = MCB_EIRQR;
+ mc_write_digital(data, 2);
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return 0;
+ }
+
+ /* PLUGDET, PLUGUNDETDB, PLUGDETDB */
+ data[0] = MCI_CD_REG_A << 1;
+ data[1] = MCI_PLUGDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+
+ /* clear */
+ flag_det = val;
+ data[2] = MCI_CD_REG_D << 1;
+ data[3] = val;
+ mc_write_analog(data, 4);
+
+ /* set reference */
+ data[1] = MCI_PLUGDET_DB;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ mc_plug_detect_db_set(val);
+
+ data[1] = MCI_RPLUGDET;
+ data[3] = (flag_det & MCB_PLUGDET) | val;
+ mc_write_analog(data, 4);
+ flag_det = data[3];
+
+ data[1] = MCI_MICDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+
+ data[1] = MCI_RMICDET;
+ data[3] = val;
+ mc_write_analog(data, 4);
+ flag_key = val & MCB_MICDET;
+
+ data[1] = MCI_SMICDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+
+ data[3] = val;
+ mc_write_analog(data, 4);
+
+ hsdet_res.key_cnt0 = 0;
+ hsdet_res.key_cnt1 = 0;
+ hsdet_res.key_cnt2 = 0;
+
+ data[0] = MCI_E_REG_A << 1;
+ data[1] = MCI_PLUG_REV;
+ mc_write_digital(data, 2);
+ mc_read_digital(MCI_E_REG_D, &val, 1);
+ hsdet_res.plug_rev = val >> 7;
+ hsdet_res.hp_imp_class = val & 0x07;
+ data[1] = MCI_HPIMP_15_8;
+ mc_write_digital(data, 2);
+ mc_read_digital(MCI_E_REG_D, &val, 1);
+ hsdet_res.hp_imp = val << 8;
+ data[1] = MCI_HPIMP_7_0;
+ mc_write_digital(data, 2);
+ mc_read_digital(MCI_E_REG_D, &val, 1);
+ hsdet_res.hp_imp |= val;
+
+ val = mc_e_register_get_value(MCI_LPF_THR);
+ val &=
+ (MCB_OSF1_MN | MCB_OSF0_MN | MCB_OSF1_ENB | MCB_OSF0_ENB);
+ mc_aec_info_get(&aec);
+ val |= aec.output.lpf_post_thru[1] << 7
+ | aec.output.lpf_post_thru[0] << 6
+ | aec.output.lpf_pre_thru[1] << 5
+ | aec.output.lpf_pre_thru[0] << 4;
+ mc_packet_add_write_e(MCI_LPF_THR, val);
+
+ val = aec.output.dcl_on[1] << 7 | aec.output.dcl_gain[1] << 4
+ | aec.output.dcl_on[0] << 3 | aec.output.dcl_gain[0];
+ mc_packet_add_write_e(MCI_DCL_GAIN, val);
+
+ if (id == MCDRV_DEV_ID_80_90H)
+ mc_packet_add_write_ana(19, s_op_dac);
+
+ mc_packet_add_write_ana(MCI_HPDETVOL, s_hp_det);
+ if (id == MCDRV_DEV_ID_80_90H) {
+ mc_packet_add_force_write_ana(78,
+ T_CPMODE_IMPSENSE_AFTER);
+ mc_packet_add_force_write_ana(87, 0);
+ data[0] = MCI_ANA_REG_A << 1;
+ data[1] = 78;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_ANA_REG_D, &val, 1);
+ } else {
+ mc_packet_add_force_write_ana(87, 0);
+ mc_packet_add_force_write_if(31, 0);
+ mc_packet_add_force_write_if(30, 0);
+ }
+
+ mc_path_info_get_virtual(&path);
+ ret = set_path(&path);
+
+ if (hsdet.cbfunc) {
+ if (flag_det & MCB_SPLUGUNDET_DB)
+ flag_det = MCB_PLUGUNDET_DB;
+ else
+ flag_det |= MCDRV_HSDET_EVT_SENSEFIN_FLAG;
+
+ mutex_unlock(&mcdrv_mutex);
+
+ (*hsdet.cbfunc) (flag_det | (flag_key << 16),
+ &hsdet_res);
+ mutex_lock(&mcdrv_mutex);
+ }
+
+ /* Enable IRQ */
+ data[0] = MCI_CD_REG_A << 1;
+ data[2] = MCI_CD_REG_D << 1;
+ enable_irqhs(data);
+
+ data[0] = MCI_IRQR << 1;
+ data[1] = MCB_EIRQR;
+ mc_write_digital(data, 2);
+
+ val = mc_if_register_get_value(MCI_RST_A);
+ if (!val) {
+ data[0] = MCI_IRQ << 1;
+ data[1] = MCB_EIRQ;
+ mc_write_digital(data, 2);
+ mc_if_register_set_value(MCI_IRQ, MCB_EIRQ);
+ }
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return 0;
+ }
+
+ if (mc_state_get() != MCDRV_STATE_READY) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ if (eirq & MCB_EIRQ) {
+ mc_read_digital(MCI_EDSP, &val, 1);
+ if (val) {
+ /* Disable IRQ */
+ mc_packet_add_force_write_if(MCI_EEDSP, 0);
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ if (val & MCB_E2DSP_STA)
+ mc_edsp_irq();
+
+ /* Clear IRQ */
+ mc_packet_add_force_write_if(MCI_EDSP, val);
+
+ /* Enable IRQ */
+ mc_packet_add_force_write_if(MCI_EEDSP, MCB_EE2DSP);
+ }
+
+ mc_read_digital(MCI_CDSP, &val, 1);
+ if (val) {
+ /* Disable IRQ */
+ mc_packet_add_force_write_if(MCI_ECDSP, 0);
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ mc_cdsp_irq();
+
+ /* Clear IRQ */
+ mc_packet_add_force_write_if(MCI_CDSP, val);
+
+ /* Enable IRQ */
+ val = MCB_ECDSP | MCB_EFFIFO | MCB_ERFIFO | MCB_EEFIFO |
+ MCB_EOFIFO | MCB_EDFIFO | MCB_EENC | MCB_EDEC;
+ mc_packet_add_force_write_if(MCI_ECDSP, val);
+ }
+
+ mc_read_digital(MCI_IRSERR, &val, 1);
+ if (val) {
+ /* Disable IRQ */
+ mc_packet_add_force_write_if(MCI_IESERR, 0);
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+
+ mc_fdsp_irq();
+
+ /* Clear IRQ */
+ mc_packet_add_force_write_if(MCI_IRSERR, val);
+ /* Enable IRQ */
+ val =
+ MCB_IESERR | MCB_IEAMTBEG | MCB_IEAMTEND | MCB_IEFW;
+ mc_packet_add_force_write_if(MCI_IESERR, val);
+ }
+
+ ret = mc_packet_execute();
+ if (ret < 0)
+ goto exit;
+ }
+
+ data[0] = MCI_CD_REG_A << 1;
+ data[1] = MCI_IRQHS;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ if (val == (MCB_EIRQHS | MCB_IRQHS)) {
+ /* Disable EIRQHS */
+ data[2] = MCI_CD_REG_D << 1;
+ data[3] = 0;
+ mc_write_analog(data, 4);
+ mc_cd_register_set_value(MCI_IRQHS, 0);
+
+ /* PLUGDET, SPLUGUNDETDB, SPLUGDETDB */
+ data[1] = MCI_PLUGDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &splug_det, 1);
+ flag_det = splug_det & MCB_PLUGDET;
+
+ data[1] = MCI_PLUGDET_DB;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &plug_det, 1);
+ flag_det |= plug_det;
+ if (flag_det & MCB_PLUGUNDET_DB)
+ mc_plug_detect_db_set(0);
+
+ if (hsdet.en_plug_det_db & MCDRV_PLUGDETDB_DET_ENABLE) {
+ if (id == MCDRV_DEV_ID_81_91H) {
+ data[1] = MCI_RPLUGDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ val = ~val & plug_det;
+ } else
+ val = splug_det;
+
+ if (val & MCB_SPLUGDET_DB) {
+ mc_plug_detect_db_set(val);
+
+ if (id != MCDRV_DEV_ID_81_92H) {
+ val = mc_ana_register_get_value(MCI_AP);
+ val &= ~MCB_AP_BGR;
+ mc_packet_add_write_ana(MCI_AP, val);
+ }
+
+ val = mc_ana_register_get_value(MCI_HIZ);
+ val |= MCB_HPR_HIZ | MCB_HPL_HIZ;
+ mc_packet_add_write_ana(MCI_HIZ, val);
+
+ mc_path_info_get_virtual(&path);
+ path.bias[3] |= MCDRV_ASRC_MIC4_ON;
+ ret = set_path(&path);
+ if (ret < 0) {
+ enable_irqhs(data);
+ goto exit;
+ }
+
+ if (hsdet.en_dly_key_off != MCDRV_KEYEN_D_D_D
+ || hsdet.en_dly_key_on != MCDRV_KEYEN_D_D_D
+ || hsdet.en_mic_det != MCDRV_MICDET_DISABLE
+ || hsdet.en_key_off != MCDRV_KEYEN_D_D_D
+ || hsdet.en_key_on != MCDRV_KEYEN_D_D_D)
+ mc_packet_add_mic_key_detect_enable
+ (false);
+
+ ret = mc_packet_execute();
+ if (ret < 0) {
+ enable_irqhs(data);
+ goto exit;
+ }
+
+ if (hsdet.sgnl_num != MCDRV_SGNLNUM_NONE) {
+ s_hp_det =
+ mc_ana_register_get_value
+ (MCI_HPDETVOL);
+ ret = imp_sense_start(&s_op_dac);
+ if (ret == 0) {
+ mutex_unlock(&mcdrv_mutex);
+ return ret;
+ }
+
+ enable_irqhs(data);
+ goto exit;
+ }
+ }
+ }
+
+ /* clear */
+ data[1] = MCI_PLUGDET;
+ data[3] = splug_det;
+ mc_write_analog(data, 4);
+
+ /* set reference */
+ data[1] = MCI_RPLUGDET;
+ data[3] = flag_det;
+ mc_write_analog(data, 4);
+
+ /* DLYKEYON, DLYKEYOFF */
+ data[1] = MCI_SDLYKEY;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ flag_dlykey = val;
+ /* clear */
+ data[1] = MCI_SDLYKEY;
+ data[3] = val;
+ mc_write_analog(data, 4);
+
+ /* MICDET, KEYON, KEYOFF */
+ data[1] = MCI_SMICDET;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ flag_key = val & ~MCB_SMICDET;
+ /* clear */
+ data[1] = MCI_SMICDET;
+ data[3] = val;
+ mc_write_analog(data, 4);
+
+ /* set reference */
+ data[1] = MCI_MICDET;
+ mc_write_analog(data, 2);
+ if (hsdet.sgnl_num == MCDRV_SGNLNUM_NONE) {
+ if (flag_det & MCB_PLUGDET_DB) {
+ switch (hsdet.speriod) {
+ case MCDRV_SPERIOD_488:
+ interval = 488;
+ break;
+ case MCDRV_SPERIOD_977:
+ interval = 977;
+ break;
+ case MCDRV_SPERIOD_1953:
+ interval = 1953;
+ break;
+ case MCDRV_SPERIOD_3906:
+ interval = 3906;
+ break;
+ case MCDRV_SPERIOD_7813:
+ interval = 7813;
+ break;
+ case MCDRV_SPERIOD_15625:
+ interval = 15625;
+ break;
+ case MCDRV_SPERIOD_31250:
+ interval = 31250;
+ break;
+ default:
+ interval = 244;
+ break;
+ }
+
+ timeout = 1;
+ switch (hsdet.dbnc_num_mic) {
+ case MCDRV_DBNC_NUM_3:
+ timeout += 3;
+ break;
+ case MCDRV_DBNC_NUM_4:
+ timeout += 4;
+ break;
+ case MCDRV_DBNC_NUM_7:
+ timeout += 7;
+ break;
+ default:
+ break;
+ }
+
+ cycles = 0;
+ while (cycles < timeout) {
+ mc_read_analog(MCI_CD_REG_D,
+ &val, 1);
+ if (val & (MCB_MICDET | 0x07))
+ break;
+
+ udelay(interval);
+ cycles++;
+ }
+ }
+ } else
+ mc_read_analog(MCI_CD_REG_D, &val, 1);
+ flag_key |= val & MCB_MICDET;
+ data[1] = MCI_RMICDET;
+ data[3] = val;
+ mc_write_analog(data, 4);
+
+ if (hsdet.cbfunc) {
+ /* KeyCnt0 */
+ data[1] = MCI_KEYCNTCLR0;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D,
+ &hsdet_res.key_cnt0, 1);
+ data[1] = MCI_KEYCNTCLR0;
+ data[3] = MCB_KEYCNTCLR0;
+ mc_write_analog(data, 4);
+
+ /* KeyCnt1 */
+ data[1] = MCI_KEYCNTCLR1;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D,
+ &hsdet_res.key_cnt1, 1);
+ data[1] = MCI_KEYCNTCLR1;
+ data[3] = MCB_KEYCNTCLR1;
+ mc_write_analog(data, 4);
+
+ /* KeyCnt2 */
+ data[1] = MCI_KEYCNTCLR2;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_CD_REG_D,
+ &hsdet_res.key_cnt2, 1);
+ data[1] = MCI_KEYCNTCLR2;
+ data[3] = MCB_KEYCNTCLR2;
+ mc_write_analog(data, 4);
+
+ data[0] = MCI_IRQ << 1;
+ data[1] = 0;
+ mc_write_analog(data, 2);
+ mc_if_register_set_value(MCI_IRQ, 0);
+
+ data[0] = MCI_IRQR << 1;
+ data[1] = 0;
+ mc_write_analog(data, 2);
+
+ mutex_unlock(&mcdrv_mutex);
+
+ (*hsdet.cbfunc) (flag_det | (u32) flag_dlykey << 8 |
+ (u32) flag_key << 16, &hsdet_res);
+
+ mutex_lock(&mcdrv_mutex);
+
+ data[0] = MCI_IRQR << 1;
+ data[1] = MCB_EIRQR;
+ mc_write_analog(data, 2);
+ }
+ /* Enable IRQ */
+ data[0] = MCI_CD_REG_A << 1;
+ data[2] = MCI_CD_REG_D << 1;
+ enable_irqhs(data);
+ }
+
+exit:
+ val = mc_if_register_get_value(MCI_RST_A);
+ if (!val) {
+ val = mc_if_register_get_value(MCI_IRQ);
+ if (val != MCB_EIRQ) {
+ data[0] = MCI_IRQ << 1;
+ data[1] = MCB_EIRQ;
+ mc_write_analog(data, 2);
+ mc_if_register_set_value(MCI_IRQ, MCB_EIRQ);
+ }
+ }
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return ret;
+}
+
+static inline bool is_valid_mcdrv_dev_info(struct mcdrv_dev_info *info)
+{
+ enum mcdrv_dev_id id;
+
+ id = mc_dev_id_get();
+
+ if (info->clk_sel > MCDRV_CKSEL_LAST)
+ return false;
+
+ if (info->clk_input > MCDRV_CKINPUT_LAST ||
+ info->clk_input == MCDRV_CKINPUT_NONE0 ||
+ info->clk_input == MCDRV_CKINPUT_NONE1 ||
+ info->clk_input == MCDRV_CKINPUT_NONE2)
+ return false;
+
+ if (info->pll_mode_a > MCDRV_PLLMODE_MAX)
+ return false;
+
+ if (info->pll_prev_div_a > MCDRV_PLLPREV_DIV_MAX)
+ return false;
+
+ if (info->pll_fb_div_a > MCDRV_PLLFB_DIV_MAX)
+ return false;
+
+ if (info->pll_mode_b > MCDRV_PLLMODE_MAX)
+ return false;
+
+ if (info->pll_prev_div_b > MCDRV_PLLPREV_DIV_MAX)
+ return false;
+
+ if (info->pll_fb_div_b > MCDRV_PLLFB_DIV_MAX)
+ return false;
+
+ if (info->power_mode != MCDRV_POWMODE_FULL &&
+ info->power_mode != MCDRV_POWMODE_CDSPDEBUG)
+ return false;
+
+ if (info->mb_sel1 > MCDRV_MBSEL_LAST)
+ return false;
+
+ if (info->mb_sel2 > MCDRV_MBSEL_LAST)
+ return false;
+
+ if (info->mb_sel3 > MCDRV_MBSEL_LAST)
+ return false;
+
+ if (info->mb_sel4 > MCDRV_MBSEL_LAST)
+ return false;
+
+ if (info->mbs_disch > MCDRV_MBSDISCH_LAST)
+ return false;
+
+ if (info->sp_hiz > MCDRV_WL_LAST)
+ return false;
+
+ if (info->hp_hiz > MCDRV_IMP_LAST)
+ return false;
+
+ if (info->line_out1_hiz > MCDRV_IMP_LAST)
+ return false;
+
+ if (info->line_out2_hiz > MCDRV_IMP_LAST)
+ return false;
+
+ if (info->wait_time.wait[0] > MCDRV_WAIT_MAX ||
+ info->wait_time.wait[1] > MCDRV_WAIT_MAX ||
+ info->wait_time.wait[2] > MCDRV_WAIT_MAX ||
+ info->wait_time.wait[3] > MCDRV_WAIT_MAX ||
+ info->wait_time.wait[4] > MCDRV_WAIT_MAX)
+ return false;
+
+ if (id == MCDRV_DEV_ID_81_91H) {
+ if (info->options[0] > MCDRV_DOA_DRV_LAST)
+ return false;
+ if (info->options[1] > MCDRV_SCKMSK_LAST)
+ return false;
+ if (info->options[2] > MCDRV_SPMN_LAST)
+ return false;
+ if (info->options[3] > 0x0f)
+ return false;
+ if (info->options[4] > 0xf8)
+ return false;
+ if (info->options[5] > 0xf8)
+ return false;
+ if (info->options[6] > 0x31)
+ return false;
+ if (info->options[7] > 0x7f)
+ return false;
+ if (info->options[9] > 0x7f)
+ return false;
+ if (info->options[10] > 0x11)
+ return false;
+ if (info->options[11] > 0xf3)
+ return false;
+ if (info->options[12] > 0x07)
+ return false;
+ }
+
+ return true;
+}
+
+int mc_init(struct mcdrv_dev_info *info)
+{
+ struct mcdrv_power_info power_info;
+ struct mcdrv_power_update power_update;
+ enum mcdrv_state state;
+ u8 analog_id, digital_id, ap = MCI_AP_DEF, data[4];
+ int ret;
+
+ if (!info)
+ return -EINVAL;
+
+ state = mc_state_get();
+ if (state == MCDRV_STATE_READY)
+ return -EBUSY;
+
+ mutex_lock(&mcdrv_mutex);
+
+ mc_resource_init();
+
+ data[0] = MCI_ANA_REG_A << 1;
+ data[1] = MCI_ANA_ID;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_ANA_REG_D, &analog_id, 1);
+
+ if ((analog_id & MCDRV_DEVID_MASK) == MCDRV_DEVID_ANA) {
+ /* reset */
+ data[0] = MCI_ANA_REG_A << 1;
+ data[1] = MCI_ANA_RST;
+ data[2] = MCI_ANA_REG_D << 1;
+ data[3] = MCI_ANA_RST_DEF;
+ mc_write_analog(data, 4);
+
+ data[3] = 0;
+ mc_write_analog(data, 4);
+
+ if (!(analog_id & MCDRV_VERID_MASK)) {
+ data[1] = MCI_AP;
+ data[3] = MCI_AP_DEF & ~(MCB_AP_LDOD | MCB_AP_BGR);
+ mc_write_analog(data, 4);
+
+ data[3] &= ~MCB_AP_VR;
+ mc_write_analog(data, 4);
+
+ msleep(VREF_WAIT_TIME_ES1);
+
+ data[3] &= ~MCB_AP_LDOA;
+ mc_write_analog(data, 4);
+
+ msleep(LDO_WAIT_TIME);
+
+ ap = data[3];
+ } else {
+ data[1] = MCI_HIZ;
+ data[3] = 0;
+ mc_write_analog(data, 4);
+
+ data[1] = MCI_LO_HIZ;
+ data[3] = 0;
+ mc_write_analog(data, 4);
+
+ data[1] = MCI_AP;
+ ap &= ~(MCB_AP_LDOD | MCB_AP_BGR);
+ data[3] = ap;
+ mc_write_analog(data, 4);
+
+ ap &= ~MCB_AP_LDOA;
+ data[3] = ap;
+ mc_write_analog(data, 4);
+
+ msleep(LDO_WAIT_TIME);
+
+ data[1] = 62;
+ data[3] = 0x20;
+ mc_write_analog(data, 4);
+
+ data[1] = MCI_AP;
+ ap &= ~MCB_AP_VR;
+ data[3] = ap;
+ mc_write_analog(data, 4);
+
+ msleep(VREF_WAIT_TIME);
+
+ data[1] = 62;
+ data[3] = 0;
+ mc_write_analog(data, 4);
+ }
+
+ data[0] = MCI_RST_A << 1;
+ data[1] = MCI_RST_A_DEF & ~MCB_RST_A;
+ mc_write_digital(data, 2);
+
+ data[0] = MCI_A_REG_A << 1;
+ data[1] = MCI_A_DEV_ID;
+ mc_write_digital(data, 2);
+ mc_read_digital(MCI_A_REG_D, &digital_id, 1);
+ ret = mc_id_set(digital_id, analog_id);
+ if (!ret) {
+ if (is_valid_mcdrv_dev_info(info)) {
+ mc_ana_register_set_value(MCI_AP, ap);
+ mc_dev_info_set(info);
+ mc_packet_clear();
+ ret = mc_packet_init();
+ if (ret == 0)
+ ret = mc_packet_execute();
+ } else
+ ret = -EINVAL;
+ }
+
+ if (!ret && info->power_mode == MCDRV_POWMODE_CDSPDEBUG) {
+ mc_power_info_get(&power_info);
+
+ /* used path power up */
+ power_update.digital = MCDRV_POWUPDATE_D_ALL;
+ power_update.analog[0] = 0;
+ power_update.analog[1] = 0;
+ power_update.analog[2] = 0;
+ power_update.analog[3] = 0;
+ power_update.analog[4] = 0;
+ ret = mc_packet_add_powerup(&power_info, &power_update);
+ }
+
+ if (!ret) {
+ mc_state_update(MCDRV_STATE_READY);
+ save_power();
+ }
+ } else
+ ret = -EIO;
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return ret;
+}
+
+int mc_term(void)
+{
+ struct mcdrv_dev_info info;
+ struct mcdrv_power_info power_info;
+ struct mcdrv_power_update power_update;
+ struct mcdrv_hsdet_info hsdet_info;
+ enum mcdrv_state state;
+ u32 flags;
+ int ret = 0;
+
+ state = mc_state_get();
+ if (state != MCDRV_STATE_READY)
+ return -EBUSY;
+
+ mutex_lock(&mcdrv_mutex);
+
+ mc_dev_info_get(&info);
+ info.power_mode = MCDRV_POWMODE_FULL;
+ mc_dev_info_set(&info);
+
+ ret = set_path(&path_alloff);
+ if (!ret) {
+ power_info.digital = 0xff;
+ power_info.analog[0] = 0xff;
+ power_info.analog[1] = 0xff;
+ power_info.analog[2] = 0xff;
+ power_info.analog[3] = 0xff;
+ power_info.analog[4] = 0xff;
+
+ power_update.digital = MCDRV_POWUPDATE_D_ALL;
+ power_update.analog[0] = MCDRV_POWUPDATE_AP;
+ power_update.analog[1] = MCDRV_POWUPDATE_AP_OUT0;
+ power_update.analog[2] = (u8) MCDRV_POWUPDATE_AP_OUT1;
+ power_update.analog[3] = (u8) MCDRV_POWUPDATE_AP_MC;
+ power_update.analog[4] = (u8) MCDRV_POWUPDATE_AP_IN;
+
+ ret = mc_packet_add_powerdown(&power_info,
+ &power_update);
+ if (!ret)
+ ret = mc_packet_execute();
+ }
+
+ hsdet_info.en_plug_det = MCDRV_PLUGDET_DISABLE;
+ hsdet_info.en_plug_det_db = MCDRV_PLUGDETDB_DISABLE;
+ hsdet_info.en_dly_key_off = MCDRV_KEYEN_D_D_D;
+ hsdet_info.en_dly_key_on = MCDRV_KEYEN_D_D_D;
+ hsdet_info.en_mic_det = MCDRV_MICDET_DISABLE;
+ hsdet_info.en_key_off = MCDRV_KEYEN_D_D_D;
+ hsdet_info.en_key_on = MCDRV_KEYEN_D_D_D;
+ flags = MCDRV_ENPLUGDET_UPDATE_FLAG | MCDRV_ENPLUGDETDB_UPDATE_FLAG |
+ MCDRV_ENDLYKEYOFF_UPDATE_FLAG | MCDRV_ENDLYKEYON_UPDATE_FLAG |
+ MCDRV_ENMICDET_UPDATE_FLAG | MCDRV_ENKEYOFF_UPDATE_FLAG |
+ MCDRV_ENKEYON_UPDATE_FLAG;
+
+ ret = set_hsdet(&hsdet_info, flags);
+
+ mc_state_update(MCDRV_STATE_NOTINIT);
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return ret;
+}
+
+int mc_control(unsigned int cmd, unsigned long arg, unsigned int flags)
+{
+ int ret;
+
+ if (mc_state_get() != MCDRV_STATE_READY)
+ return -EBUSY;
+
+ mutex_lock(&mcdrv_mutex);
+
+ switch (cmd) {
+ case MCDRV_GET_CLOCKSW:
+ ret = get_clock((u8 *) arg);
+ break;
+ case MCDRV_SET_CLOCKSW:
+ ret = set_clock((u8 *) arg);
+ break;
+ case MCDRV_GET_PATH:
+ ret = get_path((struct mcdrv_path_info *)arg);
+ break;
+ case MCDRV_SET_PATH:
+ ret = set_path((struct mcdrv_path_info *)arg);
+ break;
+ case MCDRV_GET_VOLUME:
+ ret = get_volume((struct mcdrv_vol_info *)arg);
+ break;
+ case MCDRV_SET_VOLUME:
+ ret = set_volume((struct mcdrv_vol_info *)arg);
+ break;
+ case MCDRV_GET_DIGITALIO:
+ ret = get_digitalio((struct mcdrv_dio_info *)arg);
+ break;
+ case MCDRV_SET_DIGITALIO:
+ ret = set_digitalio((struct mcdrv_dio_info *)arg, flags);
+ break;
+ case MCDRV_GET_DIGITALIO_PATH:
+ ret = get_digitalio_path((struct mcdrv_dio_path_info *)arg);
+ break;
+ case MCDRV_SET_DIGITALIO_PATH:
+ ret =
+ set_digitalio_path((struct mcdrv_dio_path_info *)arg,
+ flags);
+ break;
+ case MCDRV_GET_SWAP:
+ ret = get_swap((struct mcdrv_swap_info *)arg);
+ break;
+ case MCDRV_SET_SWAP:
+ ret = set_swap((struct mcdrv_swap_info *)arg, flags);
+ break;
+ case MCDRV_SET_DSP:
+ ret = set_dsp((u8 *) arg, flags);
+ break;
+ case MCDRV_GET_HSDET:
+ ret = get_hsdet((struct mcdrv_hsdet_info *)arg);
+ break;
+ case MCDRV_SET_HSDET:
+ ret = set_hsdet((struct mcdrv_hsdet_info *)arg, flags);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return ret;
+}
+
+int mc_version_id_get(void)
+{
+ u8 data[2], val;
+
+ mutex_lock(&mcdrv_mutex);
+
+ data[0] = MCI_ANA_REG_A << 1;
+ data[1] = MCI_ANA_ID;
+ mc_write_analog(data, 2);
+ mc_read_analog(MCI_ANA_REG_D, &val, 1);
+
+ mutex_unlock(&mcdrv_mutex);
+
+ return val & 0x7;
+}
diff --git a/sound/soc/codecs/ymu831/mcdriver.h b/sound/soc/codecs/ymu831/mcdriver.h
new file mode 100644
index 0000000..d583e87
--- /dev/null
+++ b/sound/soc/codecs/ymu831/mcdriver.h
@@ -0,0 +1,1017 @@
+/****************************************************************************
+ *
+ * Copyright(c) 2012 Yamaha Corporation. All rights reserved.
+ *
+ * Module : mcdriver.h
+ * Description : MC driver header
+ * Version : 1.0.0 Dec 13 2012
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ****************************************************************************/
+/*
+ * changelog:
+ * - change in the Linux coding style
+ * - remove unnecessary comments
+ * - remove unused codes
+ */
+#ifndef _MCDRIVER_H
+#define _MCDRIVER_H
+
+#include <linux/types.h>
+
+/* mc_control command */
+enum mc_command {
+ MCDRV_GET_CLOCKSW,
+ MCDRV_SET_CLOCKSW,
+ MCDRV_GET_PATH,
+ MCDRV_SET_PATH,
+ MCDRV_GET_VOLUME,
+ MCDRV_SET_VOLUME,
+ MCDRV_GET_DIGITALIO,
+ MCDRV_SET_DIGITALIO,
+ MCDRV_GET_DIGITALIO_PATH,
+ MCDRV_SET_DIGITALIO_PATH,
+ MCDRV_GET_SWAP,
+ MCDRV_SET_SWAP,
+ MCDRV_SET_DSP,
+ MCDRV_GET_HSDET,
+ MCDRV_SET_HSDET,
+};
+
+#define MCDRV_WAIT_MAX 268435455U
+
+struct mcdrv_wait_time {
+ u32 wait[7];
+ u32 poll_interval[6];
+ u32 poll_timeout[6];
+};
+
+/* mcdrv_dev_info clk_sel setting */
+#define MCDRV_CKSEL_CMOS_CMOS 0x00
+#define MCDRV_CKSEL_TCXO_CMOS 0x01
+#define MCDRV_CKSEL_CMOS_TCXO 0x02
+#define MCDRV_CKSEL_TCXO_TCXO 0x03
+#define MCDRV_CKSEL_LAST MCDRV_CKSEL_TCXO_TCXO
+
+/* mcdrv_dev_info clk_input setting */
+#define MCDRV_CKINPUT_NONE0 0x00
+#define MCDRV_CKINPUT_CLKI1_CLKI0 0x01
+#define MCDRV_CKINPUT_RTC_CLKI0 0x02
+#define MCDRV_CKINPUT_SBCK_CLKI0 0x03
+#define MCDRV_CKINPUT_CLKI0_CLKI1 0x04
+#define MCDRV_CKINPUT_NONE1 0x05
+#define MCDRV_CKINPUT_RTC_CLKI1 0x06
+#define MCDRV_CKINPUT_SBCK_CLKI1 0x07
+#define MCDRV_CKINPUT_CLKI0_RTCK 0x08
+#define MCDRV_CKINPUT_CLKI1_RTCK 0x09
+#define MCDRV_CKINPUT_NONE2 0x0A
+#define MCDRV_CKINPUT_SBCK_RTC 0x0B
+#define MCDRV_CKINPUT_CLKI0_SBCK 0x0C
+#define MCDRV_CKINPUT_CLKI1_SBCK 0x0D
+#define MCDRV_CKINPUT_RTC_SBCK 0x0E
+#define MCDRV_CKINPUT_LAST MCDRV_CKINPUT_RTC_SBCK
+
+#define MCDRV_PLLMODE_MAX 7
+
+#define MCDRV_PLLPREV_DIV_MAX 0x3f
+
+#define MCDRV_PLLFB_DIV_MAX 0x3fff
+
+/* mcdrv_dev_info pll_freq_* setting */
+#define MCDRV_PLLFREQ_73 0
+#define MCDRV_PLLFREQ_147 1
+
+/* mcdrv_dev_info hsdet_clk setting */
+#define MCDRV_HSDETCLK_RTC false
+#define MCDRV_HSDETCLK_OSC true
+
+/* mcdrv_dev_info XXX_hiz setting */
+#define MCDRV_DAHIZ_LOW 0
+#define MCDRV_DAHIZ_HIZ 1
+
+/* mcdrv_dev_info pcm_hiz setting */
+#define MCDRV_PCMHIZ_LOW 0
+#define MCDRV_PCMHIZ_HIZ 1
+
+/* mcdrv_dev_info paX_func setting */
+#define MCDRV_PA_GPIO false
+#define MCDRV_PA_PDMCK true
+#define MCDRV_PA_PDMDI true
+
+/* mcdrv_dev_info power_mode setting */
+#define MCDRV_POWMODE_FULL 0
+#define MCDRV_POWMODE_CDSPDEBUG 255
+
+/* mcdrv_dev_info mb_sel setting */
+#define MCDRV_MBSEL_20 0
+#define MCDRV_MBSEL_21 1
+#define MCDRV_MBSEL_22 2
+#define MCDRV_MBSEL_23 3
+#define MCDRV_MBSEL_LAST MCDRV_MBSEL_23
+
+/* mcdrv_dev_info mbs_disch setting */
+#define MCDRV_MBSDISCH_0000 0
+#define MCDRV_MBSDISCH_0001 1
+#define MCDRV_MBSDISCH_0010 2
+#define MCDRV_MBSDISCH_0011 3
+#define MCDRV_MBSDISCH_0100 4
+#define MCDRV_MBSDISCH_0101 5
+#define MCDRV_MBSDISCH_0110 6
+#define MCDRV_MBSDISCH_0111 7
+#define MCDRV_MBSDISCH_1000 8
+#define MCDRV_MBSDISCH_1001 9
+#define MCDRV_MBSDISCH_1010 10
+#define MCDRV_MBSDISCH_1011 11
+#define MCDRV_MBSDISCH_1100 12
+#define MCDRV_MBSDISCH_1101 13
+#define MCDRV_MBSDISCH_1110 14
+#define MCDRV_MBSDISCH_1111 15
+#define MCDRV_MBSDISCH_LAST MCDRV_MBSDISCH_1111
+
+/* mcdrv_dev_info nonclip setting */
+#define MCDRV_NONCLIP_OFF false
+#define MCDRV_NONCLIP_ON true
+
+/* mcdrv_dev_info line_*_dif setting */
+#define MCDRV_LINE_STEREO false
+#define MCDRV_LINE_DIF true
+
+/* mcdrv_dev_info micX_single setting */
+#define MCDRV_MIC_DIF false
+#define MCDRV_MIC_SINGLE true
+
+/* mcdrv_dev_info zc_line_outX/zc_rc/zc_sp/zc_hp setting */
+#define MCDRV_ZC_ON false
+#define MCDRV_ZC_OFF true
+
+/* mcdrv_dev_info svol_line_outX/svol_rc/svol_sp/svol_hp setting */
+#define MCDRV_SVOL_OFF false
+#define MCDRV_SVOL_ON true
+
+/* mcdrv_dev_info rc_hiz setting */
+#define MCDRV_RCIMP_FIXLOW 0
+#define MCDRV_RCIMP_WL 1
+
+/* mcdrv_dev_info sp_hiz setting */
+#define MCDRV_WL_LOFF_ROFF 0
+#define MCDRV_WL_LON_ROFF 1
+#define MCDRV_WL_LOFF_RON 2
+#define MCDRV_WL_LON_RON 3
+#define MCDRV_WL_LAST MCDRV_WL_LON_RON
+
+/* mcdrv_dev_info hp_hiz/line_outX_hiz setting */
+#define MCDRV_IMP_LFIXLOW_RFIXLOW 0
+#define MCDRV_IMP_LWL_RFIXLOW 1
+#define MCDRV_IMP_LFIXLOW_RWL 2
+#define MCDRV_IMP_LWL_RWL 3
+#define MCDRV_IMP_LAST MCDRV_IMP_LWL_RWL
+
+/* mcdrv_dev_info cp_mod setting */
+#define MCDRV_CPMOD_HI 0
+#define MCDRV_CPMOD_MID 1
+
+/* mcdrv_dev_info rb_sel setting */
+#define MCDRV_RBSEL_2_2K 0
+#define MCDRV_RBSEL_50 1
+
+/* mcdrv_dev_info plug_sel setting */
+#define MCDRV_PLUG_LRGM 0
+#define MCDRV_PLUG_LRMG 1
+
+/* mcdrv_dev_info gnd_det setting */
+#define MCDRV_GNDDET_OFF 0
+#define MCDRV_GNDDET_ON 1
+
+/* mcdrv_dev_info ppd_* setting */
+#define MCDRV_PPD_OFF 0
+#define MCDRV_PPD_ON 1
+
+/* mcdrv_dev_info option[0] setting */
+#define MCDRV_DOA_DRV_LOW 0
+#define MCDRV_DOA_DRV_HIGH 1
+#define MCDRV_DOA_DRV_LAST MCDRV_DOA_DRV_HIGH
+
+/* mcdrv_dev_info option[1] setting */
+#define MCDRV_SCKMSK_OFF 0
+#define MCDRV_SCKMSK_ON 1
+#define MCDRV_SCKMSK_LAST MCDRV_SCKMSK_ON
+
+/* mcdrv_dev_info option[2] setting */
+#define MCDRV_SPMN_8_9_10 0
+#define MCDRV_SPMN_5_6_7 1
+#define MCDRV_SPMN_4_5_6 2
+#define MCDRV_SPMN_OFF_9 3
+#define MCDRV_SPMN_OFF_6 4
+#define MCDRV_SPMN_LAST MCDRV_SPMN_OFF_6
+
+struct mcdrv_dev_info {
+ u8 clk_sel;
+ u8 clk_input;
+ u8 pll_mode_a;
+ u8 pll_prev_div_a;
+ u16 pll_fb_div_a;
+ u16 pll_frac_a;
+ bool pll_freq_a;
+ u8 pll_mode_b;
+ u8 pll_prev_div_b;
+ u16 pll_fb_div_b;
+ u16 pll_frac_b;
+ bool pll_freq_b;
+ bool hsdet_clk;
+ bool dio0_sdo_hiz;
+ bool dio1_sdo_hiz;
+ bool dio2_sdo_hiz;
+ bool dio0_clk_hiz;
+ bool dio1_clk_hiz;
+ bool dio2_clk_hiz;
+ bool dio0_pcm_hiz;
+ bool dio1_pcm_hiz;
+ bool dio2_pcm_hiz;
+ bool pa0_func;
+ bool pa1_func;
+ bool pa2_func;
+ u8 power_mode;
+ u8 mb_sel1;
+ u8 mb_sel2;
+ u8 mb_sel3;
+ u8 mb_sel4;
+ u8 mbs_disch;
+ bool nonclip;
+ bool line_in1_dif;
+ bool line_out1_dif;
+ bool line_out2_dif;
+ bool mic1_single;
+ bool mic2_single;
+ bool mic3_single;
+ bool mic4_single;
+ bool zc_line_out1;
+ bool zc_line_out2;
+ bool zc_rc;
+ bool zc_sp;
+ bool zc_hp;
+ bool svol_line_out1;
+ bool svol_line_out2;
+ bool svol_rc;
+ bool svol_sp;
+ bool svol_hp;
+ bool rc_hiz;
+ u8 sp_hiz;
+ u8 hp_hiz;
+ u8 line_out1_hiz;
+ u8 line_out2_hiz;
+ bool cp_mod;
+ bool rb_sel;
+ bool plug_sel;
+ bool gnd_det;
+ bool ppd_rc;
+ bool ppd_sp;
+ bool ppd_hp;
+ bool ppd_line_out1;
+ bool ppd_line_out2;
+ u8 options[20];
+ struct mcdrv_wait_time wait_time;
+};
+
+/* set/get clock switch */
+#define MCDRV_CLKSW_CLKA 0
+#define MCDRV_CLKSW_CLKB 1
+
+/* set/get path */
+#define MCDRV_D1SRC_MUSICIN_ON 0x00000001
+#define MCDRV_D1SRC_MUSICIN_OFF 0x00000002
+#define MCDRV_D1SRC_EXTIN_ON 0x00000004
+#define MCDRV_D1SRC_EXTIN_OFF 0x00000008
+#define MCDRV_D1SRC_VBOXOUT_ON 0x00000010
+#define MCDRV_D1SRC_VBOXOUT_OFF 0x00000020
+#define MCDRV_D1SRC_VBOXREFOUT_ON 0x00000040
+#define MCDRV_D1SRC_VBOXREFOUT_OFF 0x00000080
+#define MCDRV_D1SRC_AE0_ON 0x00000100
+#define MCDRV_D1SRC_AE0_OFF 0x00000200
+#define MCDRV_D1SRC_AE1_ON 0x00000400
+#define MCDRV_D1SRC_AE1_OFF 0x00000800
+#define MCDRV_D1SRC_AE2_ON 0x00001000
+#define MCDRV_D1SRC_AE2_OFF 0x00002000
+#define MCDRV_D1SRC_AE3_ON 0x00004000
+#define MCDRV_D1SRC_AE3_OFF 0x00008000
+#define MCDRV_D1SRC_AE_ALL_ON \
+ (MCDRV_D1SRC_AE0_ON | MCDRV_D1SRC_AE1_ON | \
+ MCDRV_D1SRC_AE2_ON | MCDRV_D1SRC_AE3_ON)
+#define MCDRV_D1SRC_ADIF0_ON 0x00010000
+#define MCDRV_D1SRC_ADIF0_OFF 0x00020000
+#define MCDRV_D1SRC_ADIF1_ON 0x00040000
+#define MCDRV_D1SRC_ADIF1_OFF 0x00080000
+#define MCDRV_D1SRC_ADIF2_ON 0x00100000
+#define MCDRV_D1SRC_ADIF2_OFF 0x00200000
+#define MCDRV_D1SRC_HIFIIN_ON 0x00400000
+#define MCDRV_D1SRC_HIFIIN_OFF 0x00800000
+#define MCDRV_D1SRC_ALL_ON 0x00555555
+
+#define MCDRV_D2SRC_VOICEIN_ON 0x00000001
+#define MCDRV_D2SRC_VOICEIN_OFF 0x00000002
+#define MCDRV_D2SRC_VBOXIOOUT_ON 0x00000004
+#define MCDRV_D2SRC_VBOXIOOUT_OFF 0x00000008
+#define MCDRV_D2SRC_VBOXHOSTOUT_ON 0x00000010
+#define MCDRV_D2SRC_VBOXHOSTOUT_OFF 0x00000020
+#define MCDRV_D2SRC_ADC0_L_ON 0x00000040
+#define MCDRV_D2SRC_ADC0_L_OFF 0x00000080
+#define MCDRV_D2SRC_ADC0_R_ON 0x00000100
+#define MCDRV_D2SRC_ADC0_R_OFF 0x00000200
+#define MCDRV_D2SRC_ADC0_ON \
+ (MCDRV_D2SRC_ADC0_L_ON | MCDRV_D2SRC_ADC0_R_ON)
+#define MCDRV_D2SRC_ADC0_OFF \
+ (MCDRV_D2SRC_ADC0_L_OFF | MCDRV_D2SRC_ADC0_R_OFF)
+#define MCDRV_D2SRC_ADC1_ON 0x00000400
+#define MCDRV_D2SRC_ADC1_OFF 0x00000800
+#define MCDRV_D2SRC_PDM0_L_ON 0x00001000
+#define MCDRV_D2SRC_PDM0_L_OFF 0x00002000
+#define MCDRV_D2SRC_PDM0_R_ON 0x00004000
+#define MCDRV_D2SRC_PDM0_R_OFF 0x00008000
+#define MCDRV_D2SRC_PDM0_ON \
+ (MCDRV_D2SRC_PDM0_L_ON | MCDRV_D2SRC_PDM0_R_ON)
+#define MCDRV_D2SRC_PDM1_L_ON 0x00010000
+#define MCDRV_D2SRC_PDM1_L_OFF 0x00020000
+#define MCDRV_D2SRC_PDM1_R_ON 0x00040000
+#define MCDRV_D2SRC_PDM1_R_OFF 0x00080000
+#define MCDRV_D2SRC_PDM1_ON \
+ (MCDRV_D2SRC_PDM1_L_ON | MCDRV_D2SRC_PDM1_R_ON)
+#define MCDRV_D2SRC_DAC0REF_ON 0x00100000
+#define MCDRV_D2SRC_DAC0REF_OFF 0x00200000
+#define MCDRV_D2SRC_DAC1REF_ON 0x00400000
+#define MCDRV_D2SRC_DAC1REF_OFF 0x00800000
+
+#define MCDRV_ASRC_DAC0_L_ON 0x00000001
+#define MCDRV_ASRC_DAC0_L_OFF 0x00000002
+#define MCDRV_ASRC_DAC0_R_ON 0x00000004
+#define MCDRV_ASRC_DAC0_R_OFF 0x00000008
+#define MCDRV_ASRC_DAC1_L_ON 0x00000010
+#define MCDRV_ASRC_DAC1_L_OFF 0x00000020
+#define MCDRV_ASRC_DAC1_R_ON 0x00000040
+#define MCDRV_ASRC_DAC1_R_OFF 0x00000080
+#define MCDRV_ASRC_MIC1_ON 0x00000100
+#define MCDRV_ASRC_MIC1_OFF 0x00000200
+#define MCDRV_ASRC_MIC2_ON 0x00000400
+#define MCDRV_ASRC_MIC2_OFF 0x00000800
+#define MCDRV_ASRC_MIC3_ON 0x00001000
+#define MCDRV_ASRC_MIC3_OFF 0x00002000
+#define MCDRV_ASRC_MIC4_ON 0x00004000
+#define MCDRV_ASRC_MIC4_OFF 0x00008000
+#define MCDRV_ASRC_MIC_ALL_ON \
+ (MCDRV_ASRC_MIC1_ON | MCDRV_ASRC_MIC2_ON | \
+ MCDRV_ASRC_MIC3_ON | MCDRV_ASRC_MIC4_ON)
+#define MCDRV_ASRC_LINEIN1_L_ON 0x00010000
+#define MCDRV_ASRC_LINEIN1_L_OFF 0x00020000
+#define MCDRV_ASRC_LINEIN1_R_ON 0x00040000
+#define MCDRV_ASRC_LINEIN1_R_OFF 0x00080000
+#define MCDRV_ASRC_LINEIN1_M_ON 0x00100000
+#define MCDRV_ASRC_LINEIN1_M_OFF 0x00200000
+#define MCDRV_ASRC_LINEIN1_ALL_ON \
+ (MCDRV_ASRC_LINEIN1_L_ON | MCDRV_ASRC_LINEIN1_R_ON | \
+ MCDRV_ASRC_LINEIN1_M_ON)
+
+#define MUSICOUT_PATH_CHANNELS 2
+#define EXTOUT_PATH_CHANNELS 2
+#define HIFIOUT_PATH_CHANNELS 1
+#define VBOXMIXIN_PATH_CHANNELS 4
+#define AE_PATH_CHANNELS 2
+#define DAC0_PATH_CHANNELS 2
+#define DAC1_PATH_CHANNELS 2
+#define VOICEOUT_PATH_CHANNELS 1
+#define VBOXIOIN_PATH_CHANNELS 1
+#define VBOXHOSTIN_PATH_CHANNELS 1
+#define HOSTOUT_PATH_CHANNELS 1
+#define ADIF0_PATH_CHANNELS 2
+#define ADIF1_PATH_CHANNELS 2
+#define ADIF2_PATH_CHANNELS 2
+#define ADC0_PATH_CHANNELS 2
+#define ADC1_PATH_CHANNELS 1
+#define SP_PATH_CHANNELS 2
+#define HP_PATH_CHANNELS 2
+#define RC_PATH_CHANNELS 1
+#define LOUT1_PATH_CHANNELS 2
+#define LOUT2_PATH_CHANNELS 2
+#define BIAS_PATH_CHANNELS 4
+
+struct mcdrv_path_info {
+ u32 music_out[MUSICOUT_PATH_CHANNELS];
+ u32 ext_out[EXTOUT_PATH_CHANNELS];
+ u32 hifi_out[HIFIOUT_PATH_CHANNELS];
+ u32 vbox_mix_in[VBOXMIXIN_PATH_CHANNELS];
+ u32 ae0[AE_PATH_CHANNELS];
+ u32 ae1[AE_PATH_CHANNELS];
+ u32 ae2[AE_PATH_CHANNELS];
+ u32 ae3[AE_PATH_CHANNELS];
+ u32 dac0[DAC0_PATH_CHANNELS];
+ u32 dac1[DAC1_PATH_CHANNELS];
+ u32 voice_out[VOICEOUT_PATH_CHANNELS];
+ u32 vbox_io_in[VBOXIOIN_PATH_CHANNELS];
+ u32 vbox_host_in[VBOXHOSTIN_PATH_CHANNELS];
+ u32 host_out[HOSTOUT_PATH_CHANNELS];
+ u32 adif0[ADIF0_PATH_CHANNELS];
+ u32 adif1[ADIF1_PATH_CHANNELS];
+ u32 adif2[ADIF2_PATH_CHANNELS];
+ u32 adc0[ADC0_PATH_CHANNELS];
+ u32 adc1[ADC1_PATH_CHANNELS];
+ u32 sp[SP_PATH_CHANNELS];
+ u32 hp[HP_PATH_CHANNELS];
+ u32 rc[RC_PATH_CHANNELS];
+ u32 lout1[LOUT1_PATH_CHANNELS];
+ u32 lout2[LOUT2_PATH_CHANNELS];
+ u32 bias[BIAS_PATH_CHANNELS];
+};
+
+/* set/get vol */
+#define MCDRV_VOL_UPDATE 0x0001
+
+#define MUSICIN_VOL_CHANNELS 2
+#define EXTIN_VOL_CHANNELS 2
+#define VOICEIN_VOL_CHANNELS 2
+#define REFIN_VOL_CHANNELS 2
+#define ADIF0IN_VOL_CHANNELS 2
+#define ADIF1IN_VOL_CHANNELS 2
+#define ADIF2IN_VOL_CHANNELS 2
+#define MUSICOUT_VOL_CHANNELS 2
+#define EXTOUT_VOL_CHANNELS 2
+#define VOICEOUT_VOL_CHANNELS 2
+#define REFOUT_VOL_CHANNELS 2
+#define DAC0OUT_VOL_CHANNELS 2
+#define DAC1OUT_VOL_CHANNELS 2
+#define DPATH_VOL_CHANNELS 2
+#define LINEIN1_VOL_CHANNELS 2
+#define MIC1_VOL_CHANNELS 1
+#define MIC2_VOL_CHANNELS 1
+#define MIC3_VOL_CHANNELS 1
+#define MIC4_VOL_CHANNELS 1
+#define HP_VOL_CHANNELS 2
+#define SP_VOL_CHANNELS 2
+#define RC_VOL_CHANNELS 1
+#define LINEOUT1_VOL_CHANNELS 2
+#define LINEOUT2_VOL_CHANNELS 2
+#define HPDET_VOL_CHANNELS 1
+
+struct mcdrv_vol_info {
+ s16 d_music_in[MUSICIN_VOL_CHANNELS];
+ s16 d_ext_in[EXTIN_VOL_CHANNELS];
+ s16 d_voice_in[VOICEIN_VOL_CHANNELS];
+ s16 d_ref_in[REFIN_VOL_CHANNELS];
+ s16 d_adif0_in[ADIF0IN_VOL_CHANNELS];
+ s16 d_adif1_in[ADIF1IN_VOL_CHANNELS];
+ s16 d_adif2_in[ADIF2IN_VOL_CHANNELS];
+ s16 d_music_out[MUSICOUT_VOL_CHANNELS];
+ s16 d_ext_out[EXTOUT_VOL_CHANNELS];
+ s16 d_voice_out[VOICEOUT_VOL_CHANNELS];
+ s16 d_ref_out[REFOUT_VOL_CHANNELS];
+ s16 d_dac0_out[DAC0OUT_VOL_CHANNELS];
+ s16 d_dac1_out[DAC1OUT_VOL_CHANNELS];
+ s16 d_dpath_da[DPATH_VOL_CHANNELS];
+ s16 d_dpath_ad[DPATH_VOL_CHANNELS];
+ s16 a_line_in1[LINEIN1_VOL_CHANNELS];
+ s16 a_mic1[MIC1_VOL_CHANNELS];
+ s16 a_mic2[MIC2_VOL_CHANNELS];
+ s16 a_mic3[MIC3_VOL_CHANNELS];
+ s16 a_mic4[MIC4_VOL_CHANNELS];
+ s16 a_hp[HP_VOL_CHANNELS];
+ s16 a_sp[SP_VOL_CHANNELS];
+ s16 a_rc[RC_VOL_CHANNELS];
+ s16 a_line_out1[LINEOUT1_VOL_CHANNELS];
+ s16 a_line_out2[LINEOUT2_VOL_CHANNELS];
+ s16 a_hp_det[HPDET_VOL_CHANNELS];
+};
+
+/* set/get digitalio */
+#define MCDRV_MUSIC_COM_UPDATE_FLAG 0x00000001U
+#define MCDRV_MUSIC_DIR_UPDATE_FLAG 0x00000002U
+#define MCDRV_MUSIC_DIT_UPDATE_FLAG 0x00000004U
+#define MCDRV_EXT_COM_UPDATE_FLAG 0x00000008U
+#define MCDRV_EXT_DIR_UPDATE_FLAG 0x00000010U
+#define MCDRV_EXT_DIT_UPDATE_FLAG 0x00000020U
+#define MCDRV_VOICE_COM_UPDATE_FLAG 0x00000040U
+#define MCDRV_VOICE_DIR_UPDATE_FLAG 0x00000080U
+#define MCDRV_VOICE_DIT_UPDATE_FLAG 0x00000100U
+#define MCDRV_HIFI_COM_UPDATE_FLAG 0x00000200U
+#define MCDRV_HIFI_DIR_UPDATE_FLAG 0x00000400U
+#define MCDRV_HIFI_DIT_UPDATE_FLAG 0x00000800U
+#define MCDRV_ALL_DIO_UPDATE_FLAG 0x00000fffU
+
+/* mcdrv_dio_common master_slave setting */
+#define MCDRV_DIO_SLAVE 0
+#define MCDRV_DIO_MASTER 1
+
+/* mcdrv_dio_common bDigitalAutoFs setting */
+#define MCDRV_AUTOFS_OFF 0
+#define MCDRV_AUTOFS_ON 1
+
+/* mcdrv_dio_common fs setting */
+#define MCDRV_FS_48000 0
+#define MCDRV_FS_44100 1
+#define MCDRV_FS_32000 2
+#define MCDRV_FS_NONE1 3
+#define MCDRV_FS_24000 4
+#define MCDRV_FS_22050 5
+#define MCDRV_FS_16000 6
+#define MCDRV_FS_NONE2 7
+#define MCDRV_FS_12000 8
+#define MCDRV_FS_11025 9
+#define MCDRV_FS_8000 10
+#define MCDRV_FS_NONE3 11
+#define MCDRV_FS_192000 12
+#define MCDRV_FS_96000 13
+#define MCDRV_FS_LAST MCDRV_FS_96000
+
+/* mcdrv_dio_common bck_fs setting */
+#define MCDRV_BCKFS_64 0
+#define MCDRV_BCKFS_48 1
+#define MCDRV_BCKFS_32 2
+#define MCDRV_BCKFS_NONE1 3
+#define MCDRV_BCKFS_512 4
+#define MCDRV_BCKFS_256 5
+#define MCDRV_BCKFS_192 6
+#define MCDRV_BCKFS_128 7
+#define MCDRV_BCKFS_96 8
+#define MCDRV_BCKFS_24 9
+#define MCDRV_BCKFS_16 10
+#define MCDRV_BCKFS_8 11
+#define MCDRV_BCKFS_NONE2 12
+#define MCDRV_BCKFS_NONE3 13
+#define MCDRV_BCKFS_NONE4 14
+#define MCDRV_BCKFS_SLAVE 15
+#define MCDRV_BCKFS_LAST MCDRV_BCKFS_SLAVE
+
+/* mcdrv_dio_common interface setting */
+#define MCDRV_DIO_DA 0
+#define MCDRV_DIO_PCM 1
+
+/* mcdrv_dio_common bck_invert setting */
+#define MCDRV_BCLK_NORMAL 0
+#define MCDRV_BCLK_INVERT 1
+
+/* mcdrv_dio_common src_thru setting */
+#define MCDRV_SRC_NOT_THRU 0
+#define MCDRV_SRC_THRU 1
+
+/* mcdrv_dio_common pcm_hiz_transition setting */
+#define MCDRV_PCMHIZTRANS_FALLING 0
+#define MCDRV_PCMHIZTRANS_RISING 1
+
+/* mcdrv_dio_common pcm_frame setting */
+#define MCDRV_PCM_SHORTFRAME 0
+#define MCDRV_PCM_LONGFRAME 1
+
+struct mcdrv_dio_common {
+ bool master_slave;
+ bool auto_fs;
+ u8 fs;
+ u8 bck_fs;
+ bool interface;
+ bool bck_invert;
+ bool src_thru;
+ bool pcm_hiz_transition;
+ bool pcm_frame;
+ u8 pcm_high_period;
+};
+
+/* mcdrv_da_format bit_sel setting */
+#define MCDRV_BITSEL_16 0
+#define MCDRV_BITSEL_20 1
+#define MCDRV_BITSEL_24 2
+#define MCDRV_BITSEL_32 3
+#define MCDRV_BITSEL_LAST MCDRV_BITSEL_32
+
+/* mcdrv_da_format mode setting */
+#define MCDRV_DAMODE_HEADALIGN 0
+#define MCDRV_DAMODE_I2S 1
+#define MCDRV_DAMODE_TAILALIGN 2
+#define MCDRV_DAMODE_LAST MCDRV_DAMODE_TAILALIGN
+
+struct mcdrv_da_format {
+ u8 bit_sel;
+ u8 mode;
+};
+
+/* mcdrv_pcm_format mono setting */
+#define MCDRV_PCM_STEREO 0
+#define MCDRV_PCM_MONO 1
+
+/* mcdrv_pcm_format order setting */
+#define MCDRV_PCM_MSB_FIRST 0
+#define MCDRV_PCM_LSB_FIRST 1
+
+/* mcdrv_pcm_format law setting */
+#define MCDRV_PCM_LINEAR 0
+#define MCDRV_PCM_ALAW 1
+#define MCDRV_PCM_MULAW 2
+#define MCDRV_PCM_LAST MCDRV_PCM_MULAW
+
+/* mcdrv_pcm_format bit_sel setting */
+#define MCDRV_PCM_BITSEL_8 0
+#define MCDRV_PCM_BITSEL_16 1
+#define MCDRV_PCM_BITSEL_24 2
+#define MCDRV_PCM_BITSEL_LAST MCDRV_PCM_BITSEL_24
+
+struct mcdrv_pcm_format {
+ bool mono;
+ bool order;
+ u8 law;
+ u8 bit_sel;
+};
+
+struct mcdrv_dio_dir {
+ struct mcdrv_da_format da_format;
+ struct mcdrv_pcm_format pcm_format;
+};
+
+/* mcdrv_dio_dit st_mode setting */
+#define MCDRV_STMODE_ZERO 0
+#define MCDRV_STMODE_HOLD 1
+
+/* mcdrv_dio_dit edge setting */
+#define MCDRV_SDOUT_NORMAL 0
+#define MCDRV_SDOUT_AHEAD 1
+
+struct mcdrv_dio_dit {
+ bool st_mode;
+ bool edge;
+ struct mcdrv_da_format da_format;
+ struct mcdrv_pcm_format pcm_format;
+};
+
+struct mcdrv_dio_port {
+ struct mcdrv_dio_common dio_common;
+ struct mcdrv_dio_dir dir;
+ struct mcdrv_dio_dit dit;
+};
+
+struct mcdrv_dio_info {
+ struct mcdrv_dio_port port[4];
+};
+
+/* set/get digitalio_path */
+#define MCDRV_PHYS0_UPDATE_FLAG 0x00000001U
+#define MCDRV_PHYS1_UPDATE_FLAG 0x00000002U
+#define MCDRV_PHYS2_UPDATE_FLAG 0x00000004U
+#define MCDRV_PHYS3_UPDATE_FLAG 0x00000008U
+#define MCDRV_MUSICNUM_UPDATE_FLAG 0x00000010U
+#define MCDRV_DIR0SLOT_UPDATE_FLAG 0x00000020U
+#define MCDRV_DIR1SLOT_UPDATE_FLAG 0x00000040U
+#define MCDRV_DIR2SLOT_UPDATE_FLAG 0x00000080U
+#define MCDRV_DIT0SLOT_UPDATE_FLAG 0x00000100U
+#define MCDRV_DIT1SLOT_UPDATE_FLAG 0x00000200U
+#define MCDRV_DIT2SLOT_UPDATE_FLAG 0x00000400U
+
+/* mcdrv_dio_path_info phys_port setting */
+#define MCDRV_PHYSPORT_DIO0 0
+#define MCDRV_PHYSPORT_DIO1 1
+#define MCDRV_PHYSPORT_DIO2 2
+#define MCDRV_PHYSPORT_NONE 3
+#define MCDRV_PHYSPORT_SLIM0 4
+#define MCDRV_PHYSPORT_SLIM1 5
+#define MCDRV_PHYSPORT_SLIM2 6
+#define MCDRV_PHYSPORT_LAST MCDRV_PHYSPORT_SLIM2
+
+/* mcdrv_dio_path_info music_ch setting */
+#define MCDRV_MUSIC_2CH 0
+#define MCDRV_MUSIC_4CH 1
+#define MCDRV_MUSIC_6CH 2
+#define MCDRV_MUSIC_LAST MCDRV_MUSIC_6CH
+
+struct mcdrv_dio_path_info {
+ u8 phys_port[4];
+ u8 music_ch;
+ u8 music_rslot[3];
+ u8 music_tslot[3];
+};
+
+/* set/get swap */
+#define MCDRV_SWAP_ADIF0_UPDATE_FLAG 0x00000001U
+#define MCDRV_SWAP_ADIF1_UPDATE_FLAG 0x00000002U
+#define MCDRV_SWAP_ADIF2_UPDATE_FLAG 0x00000004U
+#define MCDRV_SWAP_DAC0_UPDATE_FLAG 0x00000008U
+#define MCDRV_SWAP_DAC1_UPDATE_FLAG 0x00000010U
+#define MCDRV_SWAP_MUSICIN0_UPDATE_FLAG 0x00000020U
+#define MCDRV_SWAP_MUSICIN1_UPDATE_FLAG 0x00000040U
+#define MCDRV_SWAP_MUSICIN2_UPDATE_FLAG 0x00000080U
+#define MCDRV_SWAP_EXTIN_UPDATE_FLAG 0x00000100U
+#define MCDRV_SWAP_VOICEIN_UPDATE_FLAG 0x00000200U
+#define MCDRV_SWAP_HIFIIN_UPDATE_FLAG 0x00000400U
+#define MCDRV_SWAP_MUSICOUT0_UPDATE_FLAG 0x00000800U
+#define MCDRV_SWAP_MUSICOUT1_UPDATE_FLAG 0x00001000U
+#define MCDRV_SWAP_MUSICOUT2_UPDATE_FLAG 0x00002000U
+#define MCDRV_SWAP_EXTOUT_UPDATE_FLAG 0x00004000U
+#define MCDRV_SWAP_VOICEOUT_UPDATE_FLAG 0x00008000U
+#define MCDRV_SWAP_HIFIOUT_UPDATE_FLAG 0x00010000U
+#define MCDRV_SWAP_ALL_UPDATE_FLAG 0x0001ffffU
+
+/* mcdrv_swap_info adif/dac setting */
+#define MCDRV_SWAP_NORMAL 0
+#define MCDRV_SWAP_SWAP 1
+#define MCDRV_SWAP_MUTE 2
+#define MCDRV_SWAP_CENTER 3
+#define MCDRV_SWAP_MIX 4
+#define MCDRV_SWAP_MONOMIX 5
+#define MCDRV_SWAP_BOTHL 6
+#define MCDRV_SWAP_BOTHR 7
+#define MCDRV_SWAP_LAST MCDRV_SWAP_BOTHR
+
+/* mcdrv_swap_info
+ music_in/ext_in/voice_in/hifi_in/music_out/ext_out/voice_out/hifi_out
+ setting */
+#define MCDRV_SWSWAP_NORMAL 0
+#define MCDRV_SWSWAP_BOTH1 1
+#define MCDRV_SWSWAP_BOTH0 2
+#define MCDRV_SWSWAP_SWAP 3
+#define MCDRV_SWSWAP_LAST MCDRV_SWSWAP_SWAP
+
+struct mcdrv_swap_info {
+ u8 adif0;
+ u8 adif1;
+ u8 adif2;
+ u8 dac0;
+ u8 dac1;
+ u8 music_in0;
+ u8 music_in1;
+ u8 music_in2;
+ u8 ext_in;
+ u8 voice_in;
+ u8 hifi_in;
+ u8 music_out0;
+ u8 music_out1;
+ u8 music_out2;
+ u8 ext_out;
+ u8 voice_out;
+ u8 hifi_out;
+};
+
+/* get transition */
+#define MCDRV_DSPTYPE_FDSP 0
+#define MCDRV_DSPTYPE_BDSP 1
+
+/* register dsp cb */
+#define MCDRV_AE_EVT_STOP 1
+#define MCDRV_AE_EVT_APPSTOP 2
+#define MCDRV_AE_EVT_APPREQ 3
+#define MCDRV_AE_EVT_COEFDONE 4
+#define MCDRV_AE_EVT_ERROR 5
+#define MCDRV_CDSP_EVT_ERROR 11
+#define MCDRV_CDSP_EVT_PARAM 12
+#define MCDRV_CDSP_ENV_END 13
+#define MCDRV_CDSP_EVT_FIFO 14
+#define MCDRV_EDSP_EVT_E2PARAM 21
+
+/* set/get hsdet */
+#define MCDRV_ENPLUGDET_UPDATE_FLAG 0x00000001U
+#define MCDRV_ENPLUGDETDB_UPDATE_FLAG 0x00000002U
+#define MCDRV_ENDLYKEYOFF_UPDATE_FLAG 0x00000004U
+#define MCDRV_ENDLYKEYON_UPDATE_FLAG 0x00000008U
+#define MCDRV_ENMICDET_UPDATE_FLAG 0x00000010U
+#define MCDRV_ENKEYOFF_UPDATE_FLAG 0x00000020U
+#define MCDRV_ENKEYON_UPDATE_FLAG 0x00000040U
+#define MCDRV_HSDETDBNC_UPDATE_FLAG 0x00000080U
+#define MCDRV_KEYOFFMTIM_UPDATE_FLAG 0x00000100U
+#define MCDRV_KEYONMTIM_UPDATE_FLAG 0x00000200U
+#define MCDRV_KEY0OFFDLYTIM_UPDATE_FLAG 0x00000400U
+#define MCDRV_KEY1OFFDLYTIM_UPDATE_FLAG 0x00000800U
+#define MCDRV_KEY2OFFDLYTIM_UPDATE_FLAG 0x00001000U
+#define MCDRV_KEY0ONDLYTIM_UPDATE_FLAG 0x00002000U
+#define MCDRV_KEY1ONDLYTIM_UPDATE_FLAG 0x00004000U
+#define MCDRV_KEY2ONDLYTIM_UPDATE_FLAG 0x00008000U
+#define MCDRV_KEY0ONDLYTIM2_UPDATE_FLAG 0x00010000U
+#define MCDRV_KEY1ONDLYTIM2_UPDATE_FLAG 0x00020000U
+#define MCDRV_KEY2ONDLYTIM2_UPDATE_FLAG 0x00040000U
+#define MCDRV_IRQTYPE_UPDATE_FLAG 0x00080000U
+#define MCDRV_DETINV_UPDATE_FLAG 0x00100000U
+#define MCDRV_HSDETMODE_UPDATE_FLAG 0x00200000U
+#define MCDRV_SPERIOD_UPDATE_FLAG 0x00400000U
+#define MCDRV_LPERIOD_UPDATE_FLAG 0x00800000U
+#define MCDRV_DBNCNUMPLUG_UPDATE_FLAG 0x01000000U
+#define MCDRV_DBNCNUMMIC_UPDATE_FLAG 0x02000000U
+#define MCDRV_DBNCNUMKEY_UPDATE_FLAG 0x04000000U
+#define MCDRV_SGNL_UPDATE_FLAG 0x08000000U
+#define MCDRV_IMPSEL_UPDATE_FLAG 0x10000000U
+#define MCDRV_DLYIRQSTOP_UPDATE_FLAG 0x20000000U
+#define MCDRV_CBFUNC_UPDATE_FLAG 0x40000000U
+
+/* mcdrv_hsdet_info en_plug_det setting */
+#define MCDRV_PLUGDET_DISABLE 0
+#define MCDRV_PLUGDET_ENABLE 1
+
+/* mcdrv_hsdet_info en_plug_det_db setting */
+#define MCDRV_PLUGDETDB_DISABLE 0
+#define MCDRV_PLUGDETDB_DET_ENABLE 1
+#define MCDRV_PLUGDETDB_UNDET_ENABLE 2
+#define MCDRV_PLUGDETDB_BOTH_ENABLE 3
+#define MCDRV_PLUGDETDB_LAST MCDRV_PLUGDETDB_BOTH_ENABLE
+
+/* mcdrv_hsdet_info
+ en_dly_key_off/en_dly_key_on/en_key_off/en_key_on setting */
+#define MCDRV_KEYEN_D_D_D 0
+#define MCDRV_KEYEN_D_D_E 1
+#define MCDRV_KEYEN_D_E_D 2
+#define MCDRV_KEYEN_D_E_E 3
+#define MCDRV_KEYEN_E_D_D 4
+#define MCDRV_KEYEN_E_D_E 5
+#define MCDRV_KEYEN_E_E_D 6
+#define MCDRV_KEYEN_E_E_E 7
+#define MCDRV_KEYEN_LAST MCDRV_KEYEN_E_E_E
+
+/* mcdrv_hsdet_info en_mic_det setting */
+#define MCDRV_MICDET_DISABLE 0
+#define MCDRV_MICDET_ENABLE 1
+
+/* mcdrv_hsdet_info hs_det_dbnc setting */
+#define MCDRV_DETDBNC_27 0
+#define MCDRV_DETDBNC_55 1
+#define MCDRV_DETDBNC_109 2
+#define MCDRV_DETDBNC_219 3
+#define MCDRV_DETDBNC_438 4
+#define MCDRV_DETDBNC_875 5
+#define MCDRV_DETDBNC_1313 6
+#define MCDRV_DETDBNC_1750 7
+#define MCDRV_DETDBNC_LAST MCDRV_DETDBNC_1750
+
+/* mcdrv_hsdet_info key_off_mtim setting */
+#define MCDRV_KEYOFF_MTIM_63 0
+#define MCDRV_KEYOFF_MTIM_16 1
+
+/* mcdrv_hsdet_info key_on_mtim setting */
+#define MCDRV_KEYON_MTIM_63 0
+#define MCDRV_KEYON_MTIM_250 1
+
+/* mcdrv_hsdet_info key_off_dly_tim setting */
+#define MC_DRV_KEYOFFDLYTIM_MAX 15
+
+/* mcdrv_hsdet_info key_on_dly_tim setting */
+#define MC_DRV_KEYONDLYTIM_MAX 15
+
+/* mcdrv_hsdet_info key_on_dly_tim2 setting */
+#define MC_DRV_KEYONDLYTIM2_MAX 15
+
+/* mcdrv_hsdet_info irq_type setting */
+#define MCDRV_IRQTYPE_NORMAL 0
+#define MCDRV_IRQTYPE_REF 1
+#define MCDRV_IRQTYPE_EX 2
+#define MCDRV_IRQTYPE_LAST MCDRV_IRQTYPE_EX
+
+/* mcdrv_hsdet_info det_in_inv setting */
+#define MCDRV_DET_IN_NORMAL 0
+#define MCDRV_DET_IN_INV 1
+#define MCDRV_DET_IN_NORMAL_NORMAL 4
+#define MCDRV_DET_IN_INV_NORMAL 5
+#define MCDRV_DET_IN_NORMAL_INV 6
+#define MCDRV_DET_IN_INV_INV 7
+#define MCDRV_DET_IN_LAST MCDRV_DET_IN_INV_INV
+
+/* mcdrv_hsdet_info hs_det_mode setting */
+#define MCDRV_HSDET_MODE_DETIN_A 4
+#define MCDRV_HSDET_MODE_DETIN_B 6
+
+/* mcdrv_hsdet_info speriod setting */
+#define MCDRV_SPERIOD_244 0
+#define MCDRV_SPERIOD_488 1
+#define MCDRV_SPERIOD_977 2
+#define MCDRV_SPERIOD_1953 3
+#define MCDRV_SPERIOD_3906 4
+#define MCDRV_SPERIOD_7813 5
+#define MCDRV_SPERIOD_15625 6
+#define MCDRV_SPERIOD_31250 7
+#define MCDRV_SPERIOD_LAST MCDRV_SPERIOD_31250
+
+/* mcdrv_hsdet_info lperiod setting */
+#define MCDRV_LPERIOD_3906 0
+#define MCDRV_LPERIOD_62500 1
+#define MCDRV_LPERIOD_125000 2
+#define MCDRV_LPERIOD_250000 3
+#define MCDRV_LPERIOD_LAST MCDRV_LPERIOD_250000
+
+/* mcdrv_hsdet_info dbnc_num setting */
+#define MCDRV_DBNC_NUM_2 0
+#define MCDRV_DBNC_NUM_3 1
+#define MCDRV_DBNC_NUM_4 2
+#define MCDRV_DBNC_NUM_7 3
+#define MCDRV_DBNC_NUM_LAST MCDRV_DBNC_NUM_7
+
+/* mcdrv_hsdet_info sgnl_period setting */
+#define MCDRV_SGNLPERIOD_61 0
+#define MCDRV_SGNLPERIOD_79 1
+#define MCDRV_SGNLPERIOD_97 2
+#define MCDRV_SGNLPERIOD_151 3
+#define MCDRV_SGNLPERIOD_LAST MCDRV_SGNLPERIOD_151
+
+/* mcdrv_hsdet_info sgnl_num setting */
+#define MCDRV_SGNLNUM_1 0
+#define MCDRV_SGNLNUM_4 1
+#define MCDRV_SGNLNUM_6 2
+#define MCDRV_SGNLNUM_8 3
+#define MCDRV_SGNLNUM_LAST MCDRV_SGNLNUM_8
+#define MCDRV_SGNLNUM_NONE 0xff
+
+/* mcdrv_hsdet_info sgnl_peak setting */
+#define MCDRV_SGNLPEAK_500 0
+#define MCDRV_SGNLPEAK_730 1
+#define MCDRV_SGNLPEAK_960 2
+#define MCDRV_SGNLPEAK_1182 3
+#define MCDRV_SGNLPEAK_LAST MCDRV_SGNLPEAK_1182
+
+/* mcdrv_hsdet_info imp_sel setting */
+#define MCDRV_IMPSEL_MOSTFREQ 0
+#define MCDRV_IMPSEL_MIN 1
+
+/* mcdrv_hsdet_info dly_irq_stop setting */
+#define MCDRV_DLYIRQ_DONTCARE 0
+#define MCDRV_DLYIRQ_STOP 1
+
+#define MCDRV_HSDET_EVT_PLUGDET_DB_FLAG 0x00000001
+#define MCDRV_HSDET_EVT_PLUGUNDET_DB_FLAG 0x00000002
+#define MCDRV_HSDET_EVT_PLUGDET_FLAG 0x00000080
+#define MCDRV_HSDET_EVT_DLYKEYON0_FLAG 0x00000100
+#define MCDRV_HSDET_EVT_DLYKEYON1_FLAG 0x00000200
+#define MCDRV_HSDET_EVT_DLYKEYON2_FLAG 0x00000400
+#define MCDRV_HSDET_EVT_DLYKEYOFF0_FLAG 0x00000800
+#define MCDRV_HSDET_EVT_DLYKEYOFF1_FLAG 0x00001000
+#define MCDRV_HSDET_EVT_DLYKEYOFF2_FLAG 0x00002000
+#define MCDRV_HSDET_EVT_KEYON0_FLAG 0x00010000
+#define MCDRV_HSDET_EVT_KEYON1_FLAG 0x00020000
+#define MCDRV_HSDET_EVT_KEYON2_FLAG 0x00040000
+#define MCDRV_HSDET_EVT_KEYOFF0_FLAG 0x00080000
+#define MCDRV_HSDET_EVT_KEYOFF1_FLAG 0x00100000
+#define MCDRV_HSDET_EVT_KEYOFF2_FLAG 0x00200000
+#define MCDRV_HSDET_EVT_MICDET_FLAG 0x00400000
+#define MCDRV_HSDET_EVT_SENSEFIN_FLAG 0x80000000
+
+struct mcdrv_hsdet_res {
+ u8 key_cnt0;
+ u8 key_cnt1;
+ u8 key_cnt2;
+ u8 plug_rev;
+ u8 hp_imp_class;
+ u16 hp_imp;
+};
+
+typedef void (*callback_function) (u32 flags, struct mcdrv_hsdet_res *res);
+
+struct mcdrv_hsdet_info {
+ bool en_plug_det;
+ u8 en_plug_det_db;
+ u8 en_dly_key_off;
+ u8 en_dly_key_on;
+ bool en_mic_det;
+ u8 en_key_off;
+ u8 en_key_on;
+ u8 hs_det_dbnc;
+ bool key_off_mtim;
+ bool key_on_mtim;
+ u8 key0_off_dly_tim;
+ u8 key1_off_dly_tim;
+ u8 key2_off_dly_tim;
+ u8 key0_on_dly_tim;
+ u8 key1_on_dly_tim;
+ u8 key2_on_dly_tim;
+ u8 key0_on_dly_tim2;
+ u8 key1_on_dly_tim2;
+ u8 key2_on_dly_tim2;
+ u8 irq_type;
+ u8 plug_det_db_irq_type;
+ u8 plug_undet_db_irq_type;
+ u8 mic_det_irq_type;
+ u8 plug_det_irq_type;
+ u8 key0_on_irq_type;
+ u8 key1_on_irq_type;
+ u8 key2_on_irq_type;
+ u8 key0_off_irq_type;
+ u8 key1_off_irq_type;
+ u8 key2_off_irq_type;
+ u8 det_in_inv;
+ u8 hs_det_mode;
+ u8 speriod;
+ u8 lperiod;
+ u8 dbnc_num_plug;
+ u8 dbnc_num_mic;
+ u8 dbnc_num_key;
+ u8 sgnl_period;
+ u8 sgnl_num;
+ u8 sgnl_peak;
+ bool imp_sel;
+ bool dly_irq_stop;
+ callback_function cbfunc;
+};
+
+int mc_init(struct mcdrv_dev_info *info);
+int mc_term(void);
+int mc_do_irq(void);
+int mc_control(unsigned int cmd, unsigned long arg, unsigned int flags);
+int mc_version_id_get(void);
+
+#endif /* _MCDRIVER_H */
--
1.7.9.5
More information about the Alsa-devel
mailing list