cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpcap.c (51892B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ALSA SoC CPCAP codec driver
      4 *
      5 * Copyright (C) 2017 - 2018 Sebastian Reichel <sre@kernel.org>
      6 *
      7 * Very loosely based on original driver from Motorola:
      8 * Copyright (C) 2007 - 2009 Motorola, Inc.
      9 */
     10
     11#include <linux/module.h>
     12#include <linux/regmap.h>
     13#include <linux/platform_device.h>
     14#include <linux/mfd/motorola-cpcap.h>
     15#include <sound/core.h>
     16#include <sound/soc.h>
     17#include <sound/tlv.h>
     18
     19/* Register 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */
     20#define CPCAP_BIT_AUDIO_LOW_PWR           6
     21#define CPCAP_BIT_AUD_LOWPWR_SPEED        5
     22#define CPCAP_BIT_VAUDIOPRISTBY           4
     23#define CPCAP_BIT_VAUDIO_MODE1            2
     24#define CPCAP_BIT_VAUDIO_MODE0            1
     25#define CPCAP_BIT_V_AUDIO_EN              0
     26
     27/* Register 513 CPCAP_REG_CC     --- CODEC */
     28#define CPCAP_BIT_CDC_CLK2                15
     29#define CPCAP_BIT_CDC_CLK1                14
     30#define CPCAP_BIT_CDC_CLK0                13
     31#define CPCAP_BIT_CDC_SR3                 12
     32#define CPCAP_BIT_CDC_SR2                 11
     33#define CPCAP_BIT_CDC_SR1                 10
     34#define CPCAP_BIT_CDC_SR0                 9
     35#define CPCAP_BIT_CDC_CLOCK_TREE_RESET    8
     36#define CPCAP_BIT_MIC2_CDC_EN             7
     37#define CPCAP_BIT_CDC_EN_RX               6
     38#define CPCAP_BIT_DF_RESET                5
     39#define CPCAP_BIT_MIC1_CDC_EN             4
     40#define CPCAP_BIT_AUDOHPF_1		  3
     41#define CPCAP_BIT_AUDOHPF_0		  2
     42#define CPCAP_BIT_AUDIHPF_1		  1
     43#define CPCAP_BIT_AUDIHPF_0		  0
     44
     45/* Register 514 CPCAP_REG_CDI    --- CODEC Digital Audio Interface */
     46#define CPCAP_BIT_CDC_PLL_SEL             15
     47#define CPCAP_BIT_CLK_IN_SEL              13
     48#define CPCAP_BIT_DIG_AUD_IN              12
     49#define CPCAP_BIT_CDC_CLK_EN              11
     50#define CPCAP_BIT_CDC_DIG_AUD_FS1         10
     51#define CPCAP_BIT_CDC_DIG_AUD_FS0         9
     52#define CPCAP_BIT_MIC2_TIMESLOT2          8
     53#define CPCAP_BIT_MIC2_TIMESLOT1          7
     54#define CPCAP_BIT_MIC2_TIMESLOT0          6
     55#define CPCAP_BIT_MIC1_RX_TIMESLOT2       5
     56#define CPCAP_BIT_MIC1_RX_TIMESLOT1       4
     57#define CPCAP_BIT_MIC1_RX_TIMESLOT0       3
     58#define CPCAP_BIT_FS_INV                  2
     59#define CPCAP_BIT_CLK_INV                 1
     60#define CPCAP_BIT_SMB_CDC                 0
     61
     62/* Register 515 CPCAP_REG_SDAC   --- Stereo DAC */
     63#define CPCAP_BIT_FSYNC_CLK_IN_COMMON     11
     64#define CPCAP_BIT_SLAVE_PLL_CLK_INPUT     10
     65#define CPCAP_BIT_ST_CLOCK_TREE_RESET     9
     66#define CPCAP_BIT_DF_RESET_ST_DAC         8
     67#define CPCAP_BIT_ST_SR3                  7
     68#define CPCAP_BIT_ST_SR2                  6
     69#define CPCAP_BIT_ST_SR1                  5
     70#define CPCAP_BIT_ST_SR0                  4
     71#define CPCAP_BIT_ST_DAC_CLK2             3
     72#define CPCAP_BIT_ST_DAC_CLK1             2
     73#define CPCAP_BIT_ST_DAC_CLK0             1
     74#define CPCAP_BIT_ST_DAC_EN               0
     75
     76/* Register 516 CPCAP_REG_SDACDI --- Stereo DAC Digital Audio Interface */
     77#define CPCAP_BIT_ST_L_TIMESLOT2          13
     78#define CPCAP_BIT_ST_L_TIMESLOT1          12
     79#define CPCAP_BIT_ST_L_TIMESLOT0          11
     80#define CPCAP_BIT_ST_R_TIMESLOT2          10
     81#define CPCAP_BIT_ST_R_TIMESLOT1          9
     82#define CPCAP_BIT_ST_R_TIMESLOT0          8
     83#define CPCAP_BIT_ST_DAC_CLK_IN_SEL       7
     84#define CPCAP_BIT_ST_FS_INV               6
     85#define CPCAP_BIT_ST_CLK_INV              5
     86#define CPCAP_BIT_ST_DIG_AUD_FS1          4
     87#define CPCAP_BIT_ST_DIG_AUD_FS0          3
     88#define CPCAP_BIT_DIG_AUD_IN_ST_DAC       2
     89#define CPCAP_BIT_ST_CLK_EN               1
     90#define CPCAP_BIT_SMB_ST_DAC              0
     91
     92/* Register 517 CPCAP_REG_TXI    --- TX Interface */
     93#define CPCAP_BIT_PTT_TH		15
     94#define CPCAP_BIT_PTT_CMP_EN		14
     95#define CPCAP_BIT_HS_ID_TX		13
     96#define CPCAP_BIT_MB_ON2		12
     97#define CPCAP_BIT_MB_ON1L		11
     98#define CPCAP_BIT_MB_ON1R		10
     99#define CPCAP_BIT_RX_L_ENCODE		9
    100#define CPCAP_BIT_RX_R_ENCODE		8
    101#define CPCAP_BIT_MIC2_MUX		7
    102#define CPCAP_BIT_MIC2_PGA_EN		6
    103#define CPCAP_BIT_CDET_DIS		5
    104#define CPCAP_BIT_EMU_MIC_MUX		4
    105#define CPCAP_BIT_HS_MIC_MUX		3
    106#define CPCAP_BIT_MIC1_MUX		2
    107#define CPCAP_BIT_MIC1_PGA_EN		1
    108#define CPCAP_BIT_DLM			0
    109
    110/* Register 518 CPCAP_REG_TXMP   --- Mic Gain */
    111#define CPCAP_BIT_MB_BIAS_R1              11
    112#define CPCAP_BIT_MB_BIAS_R0              10
    113#define CPCAP_BIT_MIC2_GAIN_4             9
    114#define CPCAP_BIT_MIC2_GAIN_3             8
    115#define CPCAP_BIT_MIC2_GAIN_2             7
    116#define CPCAP_BIT_MIC2_GAIN_1             6
    117#define CPCAP_BIT_MIC2_GAIN_0             5
    118#define CPCAP_BIT_MIC1_GAIN_4             4
    119#define CPCAP_BIT_MIC1_GAIN_3             3
    120#define CPCAP_BIT_MIC1_GAIN_2             2
    121#define CPCAP_BIT_MIC1_GAIN_1             1
    122#define CPCAP_BIT_MIC1_GAIN_0             0
    123
    124/* Register 519 CPCAP_REG_RXOA   --- RX Output Amplifier */
    125#define CPCAP_BIT_UNUSED_519_15		15
    126#define CPCAP_BIT_UNUSED_519_14		14
    127#define CPCAP_BIT_UNUSED_519_13		13
    128#define CPCAP_BIT_STDAC_LOW_PWR_DISABLE	12
    129#define CPCAP_BIT_HS_LOW_PWR		11
    130#define CPCAP_BIT_HS_ID_RX		10
    131#define CPCAP_BIT_ST_HS_CP_EN		9
    132#define CPCAP_BIT_EMU_SPKR_R_EN		8
    133#define CPCAP_BIT_EMU_SPKR_L_EN		7
    134#define CPCAP_BIT_HS_L_EN		6
    135#define CPCAP_BIT_HS_R_EN		5
    136#define CPCAP_BIT_A4_LINEOUT_L_EN	4
    137#define CPCAP_BIT_A4_LINEOUT_R_EN	3
    138#define CPCAP_BIT_A2_LDSP_L_EN		2
    139#define CPCAP_BIT_A2_LDSP_R_EN		1
    140#define CPCAP_BIT_A1_EAR_EN		0
    141
    142/* Register 520 CPCAP_REG_RXVC   --- RX Volume Control */
    143#define CPCAP_BIT_VOL_EXT3                15
    144#define CPCAP_BIT_VOL_EXT2                14
    145#define CPCAP_BIT_VOL_EXT1                13
    146#define CPCAP_BIT_VOL_EXT0                12
    147#define CPCAP_BIT_VOL_DAC3                11
    148#define CPCAP_BIT_VOL_DAC2                10
    149#define CPCAP_BIT_VOL_DAC1                9
    150#define CPCAP_BIT_VOL_DAC0                8
    151#define CPCAP_BIT_VOL_DAC_LSB_1dB1        7
    152#define CPCAP_BIT_VOL_DAC_LSB_1dB0        6
    153#define CPCAP_BIT_VOL_CDC3                5
    154#define CPCAP_BIT_VOL_CDC2                4
    155#define CPCAP_BIT_VOL_CDC1                3
    156#define CPCAP_BIT_VOL_CDC0                2
    157#define CPCAP_BIT_VOL_CDC_LSB_1dB1        1
    158#define CPCAP_BIT_VOL_CDC_LSB_1dB0        0
    159
    160/* Register 521 CPCAP_REG_RXCOA  --- Codec to Output Amp Switches */
    161#define CPCAP_BIT_PGA_CDC_EN              10
    162#define CPCAP_BIT_CDC_SW                  9
    163#define CPCAP_BIT_PGA_OUTR_USBDP_CDC_SW   8
    164#define CPCAP_BIT_PGA_OUTL_USBDN_CDC_SW   7
    165#define CPCAP_BIT_ALEFT_HS_CDC_SW         6
    166#define CPCAP_BIT_ARIGHT_HS_CDC_SW        5
    167#define CPCAP_BIT_A4_LINEOUT_L_CDC_SW     4
    168#define CPCAP_BIT_A4_LINEOUT_R_CDC_SW     3
    169#define CPCAP_BIT_A2_LDSP_L_CDC_SW        2
    170#define CPCAP_BIT_A2_LDSP_R_CDC_SW        1
    171#define CPCAP_BIT_A1_EAR_CDC_SW           0
    172
    173/* Register 522 CPCAP_REG_RXSDOA --- RX Stereo DAC to Output Amp Switches */
    174#define CPCAP_BIT_PGA_DAC_EN              12
    175#define CPCAP_BIT_ST_DAC_SW               11
    176#define CPCAP_BIT_MONO_DAC1               10
    177#define CPCAP_BIT_MONO_DAC0               9
    178#define CPCAP_BIT_PGA_OUTR_USBDP_DAC_SW   8
    179#define CPCAP_BIT_PGA_OUTL_USBDN_DAC_SW   7
    180#define CPCAP_BIT_ALEFT_HS_DAC_SW         6
    181#define CPCAP_BIT_ARIGHT_HS_DAC_SW        5
    182#define CPCAP_BIT_A4_LINEOUT_L_DAC_SW     4
    183#define CPCAP_BIT_A4_LINEOUT_R_DAC_SW     3
    184#define CPCAP_BIT_A2_LDSP_L_DAC_SW        2
    185#define CPCAP_BIT_A2_LDSP_R_DAC_SW        1
    186#define CPCAP_BIT_A1_EAR_DAC_SW           0
    187
    188/* Register 523 CPCAP_REG_RXEPOA --- RX External PGA to Output Amp Switches */
    189#define CPCAP_BIT_PGA_EXT_L_EN            14
    190#define CPCAP_BIT_PGA_EXT_R_EN            13
    191#define CPCAP_BIT_PGA_IN_L_SW             12
    192#define CPCAP_BIT_PGA_IN_R_SW             11
    193#define CPCAP_BIT_MONO_EXT1               10
    194#define CPCAP_BIT_MONO_EXT0               9
    195#define CPCAP_BIT_PGA_OUTR_USBDP_EXT_SW   8
    196#define CPCAP_BIT_PGA_OUTL_USBDN_EXT_SW   7
    197#define CPCAP_BIT_ALEFT_HS_EXT_SW         6
    198#define CPCAP_BIT_ARIGHT_HS_EXT_SW        5
    199#define CPCAP_BIT_A4_LINEOUT_L_EXT_SW     4
    200#define CPCAP_BIT_A4_LINEOUT_R_EXT_SW     3
    201#define CPCAP_BIT_A2_LDSP_L_EXT_SW        2
    202#define CPCAP_BIT_A2_LDSP_R_EXT_SW        1
    203#define CPCAP_BIT_A1_EAR_EXT_SW           0
    204
    205/* Register 525 CPCAP_REG_A2LA --- SPK Amplifier and Clock Config for Headset */
    206#define CPCAP_BIT_NCP_CLK_SYNC            7
    207#define CPCAP_BIT_A2_CLK_SYNC             6
    208#define CPCAP_BIT_A2_FREE_RUN             5
    209#define CPCAP_BIT_A2_CLK2                 4
    210#define CPCAP_BIT_A2_CLK1                 3
    211#define CPCAP_BIT_A2_CLK0                 2
    212#define CPCAP_BIT_A2_CLK_IN               1
    213#define CPCAP_BIT_A2_CONFIG               0
    214
    215#define SLEEP_ACTIVATE_POWER 2
    216#define CLOCK_TREE_RESET_TIME 1
    217
    218/* constants for ST delay workaround */
    219#define STM_STDAC_ACTIVATE_RAMP_TIME   1
    220#define STM_STDAC_EN_TEST_PRE          0x090C
    221#define STM_STDAC_EN_TEST_POST         0x0000
    222#define STM_STDAC_EN_ST_TEST1_PRE      0x2400
    223#define STM_STDAC_EN_ST_TEST1_POST     0x0400
    224
    225struct cpcap_reg_info {
    226	u16 reg;
    227	u16 mask;
    228	u16 val;
    229};
    230
    231static const struct cpcap_reg_info cpcap_default_regs[] = {
    232	{ CPCAP_REG_VAUDIOC, 0x003F, 0x0000 },
    233	{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
    234	{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
    235	{ CPCAP_REG_CDI, 0xBFFF, 0x0000 },
    236	{ CPCAP_REG_SDAC, 0x0FFF, 0x0000 },
    237	{ CPCAP_REG_SDACDI, 0x3FFF, 0x0000 },
    238	{ CPCAP_REG_TXI, 0x0FDF, 0x0000 },
    239	{ CPCAP_REG_TXMP, 0x0FFF, 0x0400 },
    240	{ CPCAP_REG_RXOA, 0x01FF, 0x0000 },
    241	{ CPCAP_REG_RXVC, 0xFF3C, 0x0000 },
    242	{ CPCAP_REG_RXCOA, 0x07FF, 0x0000 },
    243	{ CPCAP_REG_RXSDOA, 0x1FFF, 0x0000 },
    244	{ CPCAP_REG_RXEPOA, 0x7FFF, 0x0000 },
    245	{ CPCAP_REG_A2LA, BIT(CPCAP_BIT_A2_FREE_RUN),
    246	  BIT(CPCAP_BIT_A2_FREE_RUN) },
    247};
    248
    249enum cpcap_dai {
    250	CPCAP_DAI_HIFI,
    251	CPCAP_DAI_VOICE,
    252};
    253
    254struct cpcap_audio {
    255	struct snd_soc_component *component;
    256	struct regmap *regmap;
    257
    258	u16 vendor;
    259
    260	int codec_clk_id;
    261	int codec_freq;
    262	int codec_format;
    263};
    264
    265static int cpcap_st_workaround(struct snd_soc_dapm_widget *w,
    266			       struct snd_kcontrol *kcontrol, int event)
    267{
    268	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
    269	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    270	int err = 0;
    271
    272	/* Only CPCAP from ST requires workaround */
    273	if (cpcap->vendor != CPCAP_VENDOR_ST)
    274		return 0;
    275
    276	switch (event) {
    277	case SND_SOC_DAPM_PRE_PMU:
    278		err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
    279				   STM_STDAC_EN_TEST_PRE);
    280		if (err)
    281			return err;
    282		err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
    283				   STM_STDAC_EN_ST_TEST1_PRE);
    284		break;
    285	case SND_SOC_DAPM_POST_PMU:
    286		msleep(STM_STDAC_ACTIVATE_RAMP_TIME);
    287
    288		err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1,
    289				   STM_STDAC_EN_ST_TEST1_POST);
    290		if (err)
    291			return err;
    292		err = regmap_write(cpcap->regmap, CPCAP_REG_TEST,
    293				   STM_STDAC_EN_TEST_POST);
    294		break;
    295	default:
    296		break;
    297	}
    298
    299	return err;
    300}
    301
    302/* Capture Gain Control: 0dB to 31dB in 1dB steps */
    303static const DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
    304
    305/* Playback Gain Control: -33dB to 12dB in 3dB steps */
    306static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
    307
    308static const struct snd_kcontrol_new cpcap_snd_controls[] = {
    309	/* Playback Gain */
    310	SOC_SINGLE_TLV("HiFi Playback Volume",
    311		CPCAP_REG_RXVC, CPCAP_BIT_VOL_DAC0, 0xF, 0, vol_tlv),
    312	SOC_SINGLE_TLV("Voice Playback Volume",
    313		CPCAP_REG_RXVC, CPCAP_BIT_VOL_CDC0, 0xF, 0, vol_tlv),
    314	SOC_SINGLE_TLV("Ext Playback Volume",
    315		CPCAP_REG_RXVC, CPCAP_BIT_VOL_EXT0, 0xF, 0, vol_tlv),
    316
    317	/* Capture Gain */
    318	SOC_SINGLE_TLV("Mic1 Capture Volume",
    319		CPCAP_REG_TXMP, CPCAP_BIT_MIC1_GAIN_0, 0x1F, 0, mic_gain_tlv),
    320	SOC_SINGLE_TLV("Mic2 Capture Volume",
    321		CPCAP_REG_TXMP, CPCAP_BIT_MIC2_GAIN_0, 0x1F, 0, mic_gain_tlv),
    322
    323	/* Phase Invert */
    324	SOC_SINGLE("Hifi Left Phase Invert Switch",
    325		CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC0, 1, 0),
    326	SOC_SINGLE("Ext Left Phase Invert Switch",
    327		CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
    328};
    329
    330static const char * const cpcap_out_mux_texts[] = {
    331	"Off", "Voice", "HiFi", "Ext"
    332};
    333
    334static const char * const cpcap_in_right_mux_texts[] = {
    335	"Off", "Mic 1", "Headset Mic", "EMU Mic", "Ext Right"
    336};
    337
    338static const char * const cpcap_in_left_mux_texts[] = {
    339	"Off", "Mic 2", "Ext Left"
    340};
    341
    342/*
    343 * input muxes use unusual register layout, so that we need to use custom
    344 * getter/setter methods
    345 */
    346static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_left_mux_enum,
    347				cpcap_in_left_mux_texts);
    348static SOC_ENUM_SINGLE_EXT_DECL(cpcap_input_right_mux_enum,
    349				cpcap_in_right_mux_texts);
    350
    351/*
    352 * mux uses same bit in CPCAP_REG_RXCOA, CPCAP_REG_RXSDOA & CPCAP_REG_RXEPOA;
    353 * even though the register layout makes it look like a mixer, this is a mux.
    354 * Enabling multiple inputs will result in no audio being forwarded.
    355 */
    356static SOC_ENUM_SINGLE_DECL(cpcap_earpiece_mux_enum, 0, 0, cpcap_out_mux_texts);
    357static SOC_ENUM_SINGLE_DECL(cpcap_spkr_r_mux_enum, 0, 1, cpcap_out_mux_texts);
    358static SOC_ENUM_SINGLE_DECL(cpcap_spkr_l_mux_enum, 0, 2, cpcap_out_mux_texts);
    359static SOC_ENUM_SINGLE_DECL(cpcap_line_r_mux_enum, 0, 3, cpcap_out_mux_texts);
    360static SOC_ENUM_SINGLE_DECL(cpcap_line_l_mux_enum, 0, 4, cpcap_out_mux_texts);
    361static SOC_ENUM_SINGLE_DECL(cpcap_hs_r_mux_enum, 0, 5, cpcap_out_mux_texts);
    362static SOC_ENUM_SINGLE_DECL(cpcap_hs_l_mux_enum, 0, 6, cpcap_out_mux_texts);
    363static SOC_ENUM_SINGLE_DECL(cpcap_emu_l_mux_enum, 0, 7, cpcap_out_mux_texts);
    364static SOC_ENUM_SINGLE_DECL(cpcap_emu_r_mux_enum, 0, 8, cpcap_out_mux_texts);
    365
    366static int cpcap_output_mux_get_enum(struct snd_kcontrol *kcontrol,
    367				     struct snd_ctl_elem_value *ucontrol)
    368{
    369	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
    370	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    371	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
    372	unsigned int shift = e->shift_l;
    373	int reg_voice, reg_hifi, reg_ext, status;
    374	int err;
    375
    376	err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, &reg_voice);
    377	if (err)
    378		return err;
    379	err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, &reg_hifi);
    380	if (err)
    381		return err;
    382	err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, &reg_ext);
    383	if (err)
    384		return err;
    385
    386	reg_voice = (reg_voice >> shift) & 1;
    387	reg_hifi = (reg_hifi >> shift) & 1;
    388	reg_ext = (reg_ext >> shift) & 1;
    389	status = reg_ext << 2 | reg_hifi << 1 | reg_voice;
    390
    391	switch (status) {
    392	case 0x04:
    393		ucontrol->value.enumerated.item[0] = 3;
    394		break;
    395	case 0x02:
    396		ucontrol->value.enumerated.item[0] = 2;
    397		break;
    398	case 0x01:
    399		ucontrol->value.enumerated.item[0] = 1;
    400		break;
    401	default:
    402		ucontrol->value.enumerated.item[0] = 0;
    403		break;
    404	}
    405
    406	return 0;
    407}
    408
    409static int cpcap_output_mux_put_enum(struct snd_kcontrol *kcontrol,
    410				     struct snd_ctl_elem_value *ucontrol)
    411{
    412	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
    413	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    414	struct snd_soc_dapm_context *dapm =
    415		snd_soc_dapm_kcontrol_dapm(kcontrol);
    416	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
    417	unsigned int muxval = ucontrol->value.enumerated.item[0];
    418	unsigned int mask = BIT(e->shift_l);
    419	u16 reg_voice = 0x00, reg_hifi = 0x00, reg_ext = 0x00;
    420	int err;
    421
    422	switch (muxval) {
    423	case 1:
    424		reg_voice = mask;
    425		break;
    426	case 2:
    427		reg_hifi = mask;
    428		break;
    429	case 3:
    430		reg_ext = mask;
    431		break;
    432	default:
    433		break;
    434	}
    435
    436	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
    437				 mask, reg_voice);
    438	if (err)
    439		return err;
    440	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA,
    441				 mask, reg_hifi);
    442	if (err)
    443		return err;
    444	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA,
    445				 mask, reg_ext);
    446	if (err)
    447		return err;
    448
    449	snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
    450
    451	return 0;
    452}
    453
    454static int cpcap_input_right_mux_get_enum(struct snd_kcontrol *kcontrol,
    455					  struct snd_ctl_elem_value *ucontrol)
    456{
    457	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
    458	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    459	int regval, mask;
    460	int err;
    461
    462	err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval);
    463	if (err)
    464		return err;
    465
    466	mask = 0;
    467	mask |= BIT(CPCAP_BIT_MIC1_MUX);
    468	mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
    469	mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
    470	mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
    471
    472	switch (regval & mask) {
    473	case BIT(CPCAP_BIT_RX_R_ENCODE):
    474		ucontrol->value.enumerated.item[0] = 4;
    475		break;
    476	case BIT(CPCAP_BIT_EMU_MIC_MUX):
    477		ucontrol->value.enumerated.item[0] = 3;
    478		break;
    479	case BIT(CPCAP_BIT_HS_MIC_MUX):
    480		ucontrol->value.enumerated.item[0] = 2;
    481		break;
    482	case BIT(CPCAP_BIT_MIC1_MUX):
    483		ucontrol->value.enumerated.item[0] = 1;
    484		break;
    485	default:
    486		ucontrol->value.enumerated.item[0] = 0;
    487		break;
    488	}
    489
    490	return 0;
    491}
    492
    493static int cpcap_input_right_mux_put_enum(struct snd_kcontrol *kcontrol,
    494					  struct snd_ctl_elem_value *ucontrol)
    495{
    496	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
    497	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    498	struct snd_soc_dapm_context *dapm =
    499		snd_soc_dapm_kcontrol_dapm(kcontrol);
    500	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
    501	unsigned int muxval = ucontrol->value.enumerated.item[0];
    502	int regval = 0, mask;
    503	int err;
    504
    505	mask = 0;
    506	mask |= BIT(CPCAP_BIT_MIC1_MUX);
    507	mask |= BIT(CPCAP_BIT_HS_MIC_MUX);
    508	mask |= BIT(CPCAP_BIT_EMU_MIC_MUX);
    509	mask |= BIT(CPCAP_BIT_RX_R_ENCODE);
    510
    511	switch (muxval) {
    512	case 1:
    513		regval = BIT(CPCAP_BIT_MIC1_MUX);
    514		break;
    515	case 2:
    516		regval = BIT(CPCAP_BIT_HS_MIC_MUX);
    517		break;
    518	case 3:
    519		regval = BIT(CPCAP_BIT_EMU_MIC_MUX);
    520		break;
    521	case 4:
    522		regval = BIT(CPCAP_BIT_RX_R_ENCODE);
    523		break;
    524	default:
    525		break;
    526	}
    527
    528	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
    529				 mask, regval);
    530	if (err)
    531		return err;
    532
    533	snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
    534
    535	return 0;
    536}
    537
    538static int cpcap_input_left_mux_get_enum(struct snd_kcontrol *kcontrol,
    539					 struct snd_ctl_elem_value *ucontrol)
    540{
    541	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
    542	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    543	int regval, mask;
    544	int err;
    545
    546	err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval);
    547	if (err)
    548		return err;
    549
    550	mask = 0;
    551	mask |= BIT(CPCAP_BIT_MIC2_MUX);
    552	mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
    553
    554	switch (regval & mask) {
    555	case BIT(CPCAP_BIT_RX_L_ENCODE):
    556		ucontrol->value.enumerated.item[0] = 2;
    557		break;
    558	case BIT(CPCAP_BIT_MIC2_MUX):
    559		ucontrol->value.enumerated.item[0] = 1;
    560		break;
    561	default:
    562		ucontrol->value.enumerated.item[0] = 0;
    563		break;
    564	}
    565
    566	return 0;
    567}
    568
    569static int cpcap_input_left_mux_put_enum(struct snd_kcontrol *kcontrol,
    570					 struct snd_ctl_elem_value *ucontrol)
    571{
    572	struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
    573	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
    574	struct snd_soc_dapm_context *dapm =
    575		snd_soc_dapm_kcontrol_dapm(kcontrol);
    576	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
    577	unsigned int muxval = ucontrol->value.enumerated.item[0];
    578	int regval = 0, mask;
    579	int err;
    580
    581	mask = 0;
    582	mask |= BIT(CPCAP_BIT_MIC2_MUX);
    583	mask |= BIT(CPCAP_BIT_RX_L_ENCODE);
    584
    585	switch (muxval) {
    586	case 1:
    587		regval = BIT(CPCAP_BIT_MIC2_MUX);
    588		break;
    589	case 2:
    590		regval = BIT(CPCAP_BIT_RX_L_ENCODE);
    591		break;
    592	default:
    593		break;
    594	}
    595
    596	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
    597				 mask, regval);
    598	if (err)
    599		return err;
    600
    601	snd_soc_dapm_mux_update_power(dapm, kcontrol, muxval, e, NULL);
    602
    603	return 0;
    604}
    605
    606static const struct snd_kcontrol_new cpcap_input_left_mux =
    607	SOC_DAPM_ENUM_EXT("Input Left", cpcap_input_left_mux_enum,
    608			  cpcap_input_left_mux_get_enum,
    609			  cpcap_input_left_mux_put_enum);
    610static const struct snd_kcontrol_new cpcap_input_right_mux =
    611	SOC_DAPM_ENUM_EXT("Input Right", cpcap_input_right_mux_enum,
    612			  cpcap_input_right_mux_get_enum,
    613			  cpcap_input_right_mux_put_enum);
    614static const struct snd_kcontrol_new cpcap_emu_left_mux =
    615	SOC_DAPM_ENUM_EXT("EMU Left", cpcap_emu_l_mux_enum,
    616			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    617static const struct snd_kcontrol_new cpcap_emu_right_mux =
    618	SOC_DAPM_ENUM_EXT("EMU Right", cpcap_emu_r_mux_enum,
    619			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    620static const struct snd_kcontrol_new cpcap_hs_left_mux =
    621	SOC_DAPM_ENUM_EXT("Headset Left", cpcap_hs_l_mux_enum,
    622			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    623static const struct snd_kcontrol_new cpcap_hs_right_mux =
    624	SOC_DAPM_ENUM_EXT("Headset Right", cpcap_hs_r_mux_enum,
    625			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    626static const struct snd_kcontrol_new cpcap_line_left_mux =
    627	SOC_DAPM_ENUM_EXT("Line Left", cpcap_line_l_mux_enum,
    628			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    629static const struct snd_kcontrol_new cpcap_line_right_mux =
    630	SOC_DAPM_ENUM_EXT("Line Right", cpcap_line_r_mux_enum,
    631			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    632static const struct snd_kcontrol_new cpcap_speaker_left_mux =
    633	SOC_DAPM_ENUM_EXT("Speaker Left", cpcap_spkr_l_mux_enum,
    634			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    635static const struct snd_kcontrol_new cpcap_speaker_right_mux =
    636	SOC_DAPM_ENUM_EXT("Speaker Right", cpcap_spkr_r_mux_enum,
    637			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    638static const struct snd_kcontrol_new cpcap_earpiece_mux =
    639	SOC_DAPM_ENUM_EXT("Earpiece", cpcap_earpiece_mux_enum,
    640			  cpcap_output_mux_get_enum, cpcap_output_mux_put_enum);
    641
    642static const struct snd_kcontrol_new cpcap_hifi_mono_mixer_controls[] = {
    643	SOC_DAPM_SINGLE("HiFi Mono Playback Switch",
    644		CPCAP_REG_RXSDOA, CPCAP_BIT_MONO_DAC1, 1, 0),
    645};
    646static const struct snd_kcontrol_new cpcap_ext_mono_mixer_controls[] = {
    647	SOC_DAPM_SINGLE("Ext Mono Playback Switch",
    648		CPCAP_REG_RXEPOA, CPCAP_BIT_MONO_EXT0, 1, 0),
    649};
    650
    651static const struct snd_kcontrol_new cpcap_extr_mute_control =
    652	SOC_DAPM_SINGLE("Switch",
    653		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_R_SW, 1, 0);
    654static const struct snd_kcontrol_new cpcap_extl_mute_control =
    655	SOC_DAPM_SINGLE("Switch",
    656		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_IN_L_SW, 1, 0);
    657
    658static const struct snd_kcontrol_new cpcap_voice_loopback =
    659	SOC_DAPM_SINGLE("Switch",
    660		CPCAP_REG_TXI, CPCAP_BIT_DLM, 1, 0);
    661
    662static const struct snd_soc_dapm_widget cpcap_dapm_widgets[] = {
    663	/* DAIs */
    664	SND_SOC_DAPM_AIF_IN("HiFi RX", NULL, 0, SND_SOC_NOPM, 0, 0),
    665	SND_SOC_DAPM_AIF_IN("Voice RX", NULL, 0, SND_SOC_NOPM, 0, 0),
    666	SND_SOC_DAPM_AIF_OUT("Voice TX", NULL, 0, SND_SOC_NOPM, 0, 0),
    667
    668	/* Power Supply */
    669	SND_SOC_DAPM_REGULATOR_SUPPLY("VAUDIO", SLEEP_ACTIVATE_POWER, 0),
    670
    671	/* Highpass Filters */
    672	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter RX",
    673		CPCAP_REG_CC, CPCAP_BIT_AUDIHPF_0, 0x3, 0x3, 0x0),
    674	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Highpass Filter TX",
    675		CPCAP_REG_CC, CPCAP_BIT_AUDOHPF_0, 0x3, 0x3, 0x0),
    676
    677	/* Clocks */
    678	SND_SOC_DAPM_SUPPLY("HiFi DAI Clock",
    679		CPCAP_REG_SDACDI, CPCAP_BIT_ST_CLK_EN, 0, NULL, 0),
    680	SND_SOC_DAPM_SUPPLY("Voice DAI Clock",
    681		CPCAP_REG_CDI, CPCAP_BIT_CDC_CLK_EN, 0, NULL, 0),
    682
    683	/* Microphone Bias */
    684	SND_SOC_DAPM_SUPPLY("MIC1R Bias",
    685		CPCAP_REG_TXI, CPCAP_BIT_MB_ON1R, 0, NULL, 0),
    686	SND_SOC_DAPM_SUPPLY("MIC1L Bias",
    687		CPCAP_REG_TXI, CPCAP_BIT_MB_ON1L, 0, NULL, 0),
    688	SND_SOC_DAPM_SUPPLY("MIC2 Bias",
    689		CPCAP_REG_TXI, CPCAP_BIT_MB_ON2, 0, NULL, 0),
    690
    691	/* Inputs */
    692	SND_SOC_DAPM_INPUT("MICR"),
    693	SND_SOC_DAPM_INPUT("HSMIC"),
    694	SND_SOC_DAPM_INPUT("EMUMIC"),
    695	SND_SOC_DAPM_INPUT("MICL"),
    696	SND_SOC_DAPM_INPUT("EXTR"),
    697	SND_SOC_DAPM_INPUT("EXTL"),
    698
    699	/* Capture Route */
    700	SND_SOC_DAPM_MUX("Right Capture Route",
    701		SND_SOC_NOPM, 0, 0, &cpcap_input_right_mux),
    702	SND_SOC_DAPM_MUX("Left Capture Route",
    703		SND_SOC_NOPM, 0, 0, &cpcap_input_left_mux),
    704
    705	/* Capture PGAs */
    706	SND_SOC_DAPM_PGA("Microphone 1 PGA",
    707		CPCAP_REG_TXI, CPCAP_BIT_MIC1_PGA_EN, 0, NULL, 0),
    708	SND_SOC_DAPM_PGA("Microphone 2 PGA",
    709		CPCAP_REG_TXI, CPCAP_BIT_MIC2_PGA_EN, 0, NULL, 0),
    710
    711	/* ADC */
    712	SND_SOC_DAPM_ADC("ADC Right", NULL,
    713		CPCAP_REG_CC, CPCAP_BIT_MIC1_CDC_EN, 0),
    714	SND_SOC_DAPM_ADC("ADC Left", NULL,
    715		CPCAP_REG_CC, CPCAP_BIT_MIC2_CDC_EN, 0),
    716
    717	/* DAC */
    718	SND_SOC_DAPM_DAC_E("DAC HiFi", NULL,
    719		CPCAP_REG_SDAC, CPCAP_BIT_ST_DAC_EN, 0,
    720		cpcap_st_workaround,
    721		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
    722	SND_SOC_DAPM_DAC_E("DAC Voice", NULL,
    723		CPCAP_REG_CC, CPCAP_BIT_CDC_EN_RX, 0,
    724		cpcap_st_workaround,
    725		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
    726
    727	/* Playback PGA */
    728	SND_SOC_DAPM_PGA("HiFi PGA",
    729		CPCAP_REG_RXSDOA, CPCAP_BIT_PGA_DAC_EN, 0, NULL, 0),
    730	SND_SOC_DAPM_PGA("Voice PGA",
    731		CPCAP_REG_RXCOA, CPCAP_BIT_PGA_CDC_EN, 0, NULL, 0),
    732	SND_SOC_DAPM_PGA_E("Ext Right PGA",
    733		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_R_EN, 0,
    734		NULL, 0,
    735		cpcap_st_workaround,
    736		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
    737	SND_SOC_DAPM_PGA_E("Ext Left PGA",
    738		CPCAP_REG_RXEPOA, CPCAP_BIT_PGA_EXT_L_EN, 0,
    739		NULL, 0,
    740		cpcap_st_workaround,
    741		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
    742
    743	/* Playback Switch */
    744	SND_SOC_DAPM_SWITCH("Ext Right Enable", SND_SOC_NOPM, 0, 0,
    745		&cpcap_extr_mute_control),
    746	SND_SOC_DAPM_SWITCH("Ext Left Enable", SND_SOC_NOPM, 0, 0,
    747		&cpcap_extl_mute_control),
    748
    749	/* Loopback Switch */
    750	SND_SOC_DAPM_SWITCH("Voice Loopback", SND_SOC_NOPM, 0, 0,
    751		&cpcap_voice_loopback),
    752
    753	/* Mono Mixer */
    754	SOC_MIXER_ARRAY("HiFi Mono Left Mixer", SND_SOC_NOPM, 0, 0,
    755		cpcap_hifi_mono_mixer_controls),
    756	SOC_MIXER_ARRAY("HiFi Mono Right Mixer", SND_SOC_NOPM, 0, 0,
    757		cpcap_hifi_mono_mixer_controls),
    758	SOC_MIXER_ARRAY("Ext Mono Left Mixer", SND_SOC_NOPM, 0, 0,
    759		cpcap_ext_mono_mixer_controls),
    760	SOC_MIXER_ARRAY("Ext Mono Right Mixer", SND_SOC_NOPM, 0, 0,
    761		cpcap_ext_mono_mixer_controls),
    762
    763	/* Output Routes */
    764	SND_SOC_DAPM_MUX("Earpiece Playback Route", SND_SOC_NOPM, 0, 0,
    765		&cpcap_earpiece_mux),
    766	SND_SOC_DAPM_MUX("Speaker Right Playback Route", SND_SOC_NOPM, 0, 0,
    767		&cpcap_speaker_right_mux),
    768	SND_SOC_DAPM_MUX("Speaker Left Playback Route", SND_SOC_NOPM, 0, 0,
    769		&cpcap_speaker_left_mux),
    770	SND_SOC_DAPM_MUX("Lineout Right Playback Route", SND_SOC_NOPM, 0, 0,
    771		&cpcap_line_right_mux),
    772	SND_SOC_DAPM_MUX("Lineout Left Playback Route", SND_SOC_NOPM, 0, 0,
    773		&cpcap_line_left_mux),
    774	SND_SOC_DAPM_MUX("Headset Right Playback Route", SND_SOC_NOPM, 0, 0,
    775		&cpcap_hs_right_mux),
    776	SND_SOC_DAPM_MUX("Headset Left Playback Route", SND_SOC_NOPM, 0, 0,
    777		&cpcap_hs_left_mux),
    778	SND_SOC_DAPM_MUX("EMU Right Playback Route", SND_SOC_NOPM, 0, 0,
    779		&cpcap_emu_right_mux),
    780	SND_SOC_DAPM_MUX("EMU Left Playback Route", SND_SOC_NOPM, 0, 0,
    781		&cpcap_emu_left_mux),
    782
    783	/* Output Amplifier */
    784	SND_SOC_DAPM_PGA("Earpiece PGA",
    785		CPCAP_REG_RXOA, CPCAP_BIT_A1_EAR_EN, 0, NULL, 0),
    786	SND_SOC_DAPM_PGA("Speaker Right PGA",
    787		CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_R_EN, 0, NULL, 0),
    788	SND_SOC_DAPM_PGA("Speaker Left PGA",
    789		CPCAP_REG_RXOA, CPCAP_BIT_A2_LDSP_L_EN, 0, NULL, 0),
    790	SND_SOC_DAPM_PGA("Lineout Right PGA",
    791		CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_R_EN, 0, NULL, 0),
    792	SND_SOC_DAPM_PGA("Lineout Left PGA",
    793		CPCAP_REG_RXOA, CPCAP_BIT_A4_LINEOUT_L_EN, 0, NULL, 0),
    794	SND_SOC_DAPM_PGA("Headset Right PGA",
    795		CPCAP_REG_RXOA, CPCAP_BIT_HS_R_EN, 0, NULL, 0),
    796	SND_SOC_DAPM_PGA("Headset Left PGA",
    797		CPCAP_REG_RXOA, CPCAP_BIT_HS_L_EN, 0, NULL, 0),
    798	SND_SOC_DAPM_PGA("EMU Right PGA",
    799		CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_R_EN, 0, NULL, 0),
    800	SND_SOC_DAPM_PGA("EMU Left PGA",
    801		CPCAP_REG_RXOA, CPCAP_BIT_EMU_SPKR_L_EN, 0, NULL, 0),
    802
    803	/* Headet Charge Pump */
    804	SND_SOC_DAPM_SUPPLY("Headset Charge Pump",
    805		CPCAP_REG_RXOA, CPCAP_BIT_ST_HS_CP_EN, 0, NULL, 0),
    806
    807	/* Outputs */
    808	SND_SOC_DAPM_OUTPUT("EP"),
    809	SND_SOC_DAPM_OUTPUT("SPKR"),
    810	SND_SOC_DAPM_OUTPUT("SPKL"),
    811	SND_SOC_DAPM_OUTPUT("LINER"),
    812	SND_SOC_DAPM_OUTPUT("LINEL"),
    813	SND_SOC_DAPM_OUTPUT("HSR"),
    814	SND_SOC_DAPM_OUTPUT("HSL"),
    815	SND_SOC_DAPM_OUTPUT("EMUR"),
    816	SND_SOC_DAPM_OUTPUT("EMUL"),
    817};
    818
    819static const struct snd_soc_dapm_route intercon[] = {
    820	/* Power Supply */
    821	{"HiFi PGA", NULL, "VAUDIO"},
    822	{"Voice PGA", NULL, "VAUDIO"},
    823	{"Ext Right PGA", NULL, "VAUDIO"},
    824	{"Ext Left PGA", NULL, "VAUDIO"},
    825	{"Microphone 1 PGA", NULL, "VAUDIO"},
    826	{"Microphone 2 PGA", NULL, "VAUDIO"},
    827
    828	/* Stream -> AIF */
    829	{"HiFi RX", NULL, "HiFi Playback"},
    830	{"Voice RX", NULL, "Voice Playback"},
    831	{"Voice Capture", NULL, "Voice TX"},
    832
    833	/* AIF clocks */
    834	{"HiFi RX", NULL, "HiFi DAI Clock"},
    835	{"Voice RX", NULL, "Voice DAI Clock"},
    836	{"Voice TX", NULL, "Voice DAI Clock"},
    837
    838	/* Digital Loopback */
    839	{"Voice Loopback", "Switch", "Voice TX"},
    840	{"Voice RX", NULL, "Voice Loopback"},
    841
    842	/* Highpass Filters */
    843	{"Highpass Filter RX", NULL, "Voice RX"},
    844	{"Voice TX", NULL, "Highpass Filter TX"},
    845
    846	/* AIF -> DAC mapping */
    847	{"DAC HiFi", NULL, "HiFi RX"},
    848	{"DAC Voice", NULL, "Highpass Filter RX"},
    849
    850	/* DAC -> PGA */
    851	{"HiFi PGA", NULL, "DAC HiFi"},
    852	{"Voice PGA", NULL, "DAC Voice"},
    853
    854	/* Ext Input -> PGA */
    855	{"Ext Right PGA", NULL, "EXTR"},
    856	{"Ext Left PGA", NULL, "EXTL"},
    857
    858	/* Ext PGA -> Ext Playback Switch */
    859	{"Ext Right Enable", "Switch", "Ext Right PGA"},
    860	{"Ext Left Enable", "Switch", "Ext Left PGA"},
    861
    862	/* HiFi PGA -> Mono Mixer */
    863	{"HiFi Mono Left Mixer", NULL, "HiFi PGA"},
    864	{"HiFi Mono Left Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
    865	{"HiFi Mono Right Mixer", NULL, "HiFi PGA"},
    866	{"HiFi Mono Right Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
    867
    868	/* Ext Playback Switch -> Ext Mono Mixer */
    869	{"Ext Mono Right Mixer", NULL, "Ext Right Enable"},
    870	{"Ext Mono Right Mixer", "Ext Mono Playback Switch", "Ext Left Enable"},
    871	{"Ext Mono Left Mixer", NULL, "Ext Left Enable"},
    872	{"Ext Mono Left Mixer", "Ext Mono Playback Switch", "Ext Right Enable"},
    873
    874	/* HiFi Mono Mixer -> Output Route */
    875	{"Earpiece Playback Route", "HiFi", "HiFi Mono Right Mixer"},
    876	{"Speaker Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
    877	{"Speaker Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
    878	{"Lineout Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
    879	{"Lineout Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
    880	{"Headset Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
    881	{"Headset Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
    882	{"EMU Right Playback Route", "HiFi", "HiFi Mono Right Mixer"},
    883	{"EMU Left Playback Route", "HiFi", "HiFi Mono Left Mixer"},
    884
    885	/* Voice PGA -> Output Route */
    886	{"Earpiece Playback Route", "Voice", "Voice PGA"},
    887	{"Speaker Right Playback Route", "Voice", "Voice PGA"},
    888	{"Speaker Left Playback Route", "Voice", "Voice PGA"},
    889	{"Lineout Right Playback Route", "Voice", "Voice PGA"},
    890	{"Lineout Left Playback Route", "Voice", "Voice PGA"},
    891	{"Headset Right Playback Route", "Voice", "Voice PGA"},
    892	{"Headset Left Playback Route", "Voice", "Voice PGA"},
    893	{"EMU Right Playback Route", "Voice", "Voice PGA"},
    894	{"EMU Left Playback Route", "Voice", "Voice PGA"},
    895
    896	/* Ext Mono Mixer -> Output Route */
    897	{"Earpiece Playback Route", "Ext", "Ext Mono Right Mixer"},
    898	{"Speaker Right Playback Route", "Ext", "Ext Mono Right Mixer"},
    899	{"Speaker Left Playback Route", "Ext", "Ext Mono Left Mixer"},
    900	{"Lineout Right Playback Route", "Ext", "Ext Mono Right Mixer"},
    901	{"Lineout Left Playback Route", "Ext", "Ext Mono Left Mixer"},
    902	{"Headset Right Playback Route", "Ext", "Ext Mono Right Mixer"},
    903	{"Headset Left Playback Route", "Ext", "Ext Mono Left Mixer"},
    904	{"EMU Right Playback Route", "Ext", "Ext Mono Right Mixer"},
    905	{"EMU Left Playback Route", "Ext", "Ext Mono Left Mixer"},
    906
    907	/* Output Route -> Output Amplifier */
    908	{"Earpiece PGA", NULL, "Earpiece Playback Route"},
    909	{"Speaker Right PGA", NULL, "Speaker Right Playback Route"},
    910	{"Speaker Left PGA", NULL, "Speaker Left Playback Route"},
    911	{"Lineout Right PGA", NULL, "Lineout Right Playback Route"},
    912	{"Lineout Left PGA", NULL, "Lineout Left Playback Route"},
    913	{"Headset Right PGA", NULL, "Headset Right Playback Route"},
    914	{"Headset Left PGA", NULL, "Headset Left Playback Route"},
    915	{"EMU Right PGA", NULL, "EMU Right Playback Route"},
    916	{"EMU Left PGA", NULL, "EMU Left Playback Route"},
    917
    918	/* Output Amplifier -> Output */
    919	{"EP", NULL, "Earpiece PGA"},
    920	{"SPKR", NULL, "Speaker Right PGA"},
    921	{"SPKL", NULL, "Speaker Left PGA"},
    922	{"LINER", NULL, "Lineout Right PGA"},
    923	{"LINEL", NULL, "Lineout Left PGA"},
    924	{"HSR", NULL, "Headset Right PGA"},
    925	{"HSL", NULL, "Headset Left PGA"},
    926	{"EMUR", NULL, "EMU Right PGA"},
    927	{"EMUL", NULL, "EMU Left PGA"},
    928
    929	/* Headset Charge Pump -> Headset */
    930	{"HSR", NULL, "Headset Charge Pump"},
    931	{"HSL", NULL, "Headset Charge Pump"},
    932
    933	/* Mic -> Mic Route */
    934	{"Right Capture Route", "Mic 1", "MICR"},
    935	{"Right Capture Route", "Headset Mic", "HSMIC"},
    936	{"Right Capture Route", "EMU Mic", "EMUMIC"},
    937	{"Right Capture Route", "Ext Right", "EXTR"},
    938	{"Left Capture Route", "Mic 2", "MICL"},
    939	{"Left Capture Route", "Ext Left", "EXTL"},
    940
    941	/* Input Route -> Microphone PGA */
    942	{"Microphone 1 PGA", NULL, "Right Capture Route"},
    943	{"Microphone 2 PGA", NULL, "Left Capture Route"},
    944
    945	/* Microphone PGA -> ADC */
    946	{"ADC Right", NULL, "Microphone 1 PGA"},
    947	{"ADC Left", NULL, "Microphone 2 PGA"},
    948
    949	/* ADC -> Stream */
    950	{"Highpass Filter TX", NULL, "ADC Right"},
    951	{"Highpass Filter TX", NULL, "ADC Left"},
    952
    953	/* Mic Bias */
    954	{"MICL", NULL, "MIC1L Bias"},
    955	{"MICR", NULL, "MIC1R Bias"},
    956};
    957
    958static int cpcap_set_sysclk(struct cpcap_audio *cpcap, enum cpcap_dai dai,
    959			    int clk_id, int freq)
    960{
    961	u16 clkfreqreg, clkfreqshift;
    962	u16 clkfreqmask, clkfreqval;
    963	u16 clkidreg, clkidshift;
    964	u16 mask, val;
    965	int err;
    966
    967	switch (dai) {
    968	case CPCAP_DAI_HIFI:
    969		clkfreqreg = CPCAP_REG_SDAC;
    970		clkfreqshift = CPCAP_BIT_ST_DAC_CLK0;
    971		clkidreg = CPCAP_REG_SDACDI;
    972		clkidshift = CPCAP_BIT_ST_DAC_CLK_IN_SEL;
    973		break;
    974	case CPCAP_DAI_VOICE:
    975		clkfreqreg = CPCAP_REG_CC;
    976		clkfreqshift = CPCAP_BIT_CDC_CLK0;
    977		clkidreg = CPCAP_REG_CDI;
    978		clkidshift = CPCAP_BIT_CLK_IN_SEL;
    979		break;
    980	default:
    981		dev_err(cpcap->component->dev, "invalid DAI: %d", dai);
    982		return -EINVAL;
    983	}
    984
    985	/* setup clk id */
    986	if (clk_id < 0 || clk_id > 1) {
    987		dev_err(cpcap->component->dev, "invalid clk id %d", clk_id);
    988		return -EINVAL;
    989	}
    990	err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift),
    991				 clk_id ? BIT(clkidshift) : 0);
    992	if (err)
    993		return err;
    994
    995	/* enable PLL for Voice DAI */
    996	if (dai == CPCAP_DAI_VOICE) {
    997		mask = BIT(CPCAP_BIT_CDC_PLL_SEL);
    998		val = BIT(CPCAP_BIT_CDC_PLL_SEL);
    999		err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
   1000					 mask, val);
   1001		if (err)
   1002			return err;
   1003	}
   1004
   1005	/* setup frequency */
   1006	clkfreqmask = 0x7 << clkfreqshift;
   1007	switch (freq) {
   1008	case 15360000:
   1009		clkfreqval = 0x01 << clkfreqshift;
   1010		break;
   1011	case 16800000:
   1012		clkfreqval = 0x02 << clkfreqshift;
   1013		break;
   1014	case 19200000:
   1015		clkfreqval = 0x03 << clkfreqshift;
   1016		break;
   1017	case 26000000:
   1018		clkfreqval = 0x04 << clkfreqshift;
   1019		break;
   1020	case 33600000:
   1021		clkfreqval = 0x05 << clkfreqshift;
   1022		break;
   1023	case 38400000:
   1024		clkfreqval = 0x06 << clkfreqshift;
   1025		break;
   1026	default:
   1027		dev_err(cpcap->component->dev, "unsupported freq %u", freq);
   1028		return -EINVAL;
   1029	}
   1030
   1031	err = regmap_update_bits(cpcap->regmap, clkfreqreg,
   1032				 clkfreqmask, clkfreqval);
   1033	if (err)
   1034		return err;
   1035
   1036	if (dai == CPCAP_DAI_VOICE) {
   1037		cpcap->codec_clk_id = clk_id;
   1038		cpcap->codec_freq = freq;
   1039	}
   1040
   1041	return 0;
   1042}
   1043
   1044static int cpcap_set_samprate(struct cpcap_audio *cpcap, enum cpcap_dai dai,
   1045			      int samplerate)
   1046{
   1047	struct snd_soc_component *component = cpcap->component;
   1048	u16 sampreg, sampmask, sampshift, sampval, sampreset;
   1049	int err, sampreadval;
   1050
   1051	switch (dai) {
   1052	case CPCAP_DAI_HIFI:
   1053		sampreg = CPCAP_REG_SDAC;
   1054		sampshift = CPCAP_BIT_ST_SR0;
   1055		sampreset = BIT(CPCAP_BIT_DF_RESET_ST_DAC) |
   1056			    BIT(CPCAP_BIT_ST_CLOCK_TREE_RESET);
   1057		break;
   1058	case CPCAP_DAI_VOICE:
   1059		sampreg = CPCAP_REG_CC;
   1060		sampshift = CPCAP_BIT_CDC_SR0;
   1061		sampreset = BIT(CPCAP_BIT_DF_RESET) |
   1062			    BIT(CPCAP_BIT_CDC_CLOCK_TREE_RESET);
   1063		break;
   1064	default:
   1065		dev_err(component->dev, "invalid DAI: %d", dai);
   1066		return -EINVAL;
   1067	}
   1068
   1069	sampmask = 0xF << sampshift | sampreset;
   1070	switch (samplerate) {
   1071	case 48000:
   1072		sampval = 0x8 << sampshift;
   1073		break;
   1074	case 44100:
   1075		sampval = 0x7 << sampshift;
   1076		break;
   1077	case 32000:
   1078		sampval = 0x6 << sampshift;
   1079		break;
   1080	case 24000:
   1081		sampval = 0x5 << sampshift;
   1082		break;
   1083	case 22050:
   1084		sampval = 0x4 << sampshift;
   1085		break;
   1086	case 16000:
   1087		sampval = 0x3 << sampshift;
   1088		break;
   1089	case 12000:
   1090		sampval = 0x2 << sampshift;
   1091		break;
   1092	case 11025:
   1093		sampval = 0x1 << sampshift;
   1094		break;
   1095	case 8000:
   1096		sampval = 0x0 << sampshift;
   1097		break;
   1098	default:
   1099		dev_err(component->dev, "unsupported samplerate %d", samplerate);
   1100		return -EINVAL;
   1101	}
   1102	err = regmap_update_bits(cpcap->regmap, sampreg,
   1103				 sampmask, sampval | sampreset);
   1104	if (err)
   1105		return err;
   1106
   1107	/* Wait for clock tree reset to complete */
   1108	mdelay(CLOCK_TREE_RESET_TIME);
   1109
   1110	err = regmap_read(cpcap->regmap, sampreg, &sampreadval);
   1111	if (err)
   1112		return err;
   1113
   1114	if (sampreadval & sampreset) {
   1115		dev_err(component->dev, "reset self-clear failed: %04x",
   1116			sampreadval);
   1117		return -EIO;
   1118	}
   1119
   1120	return 0;
   1121}
   1122
   1123static int cpcap_hifi_hw_params(struct snd_pcm_substream *substream,
   1124				struct snd_pcm_hw_params *params,
   1125				struct snd_soc_dai *dai)
   1126{
   1127	struct snd_soc_component *component = dai->component;
   1128	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1129	int rate = params_rate(params);
   1130
   1131	dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate);
   1132	return cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, rate);
   1133}
   1134
   1135static int cpcap_hifi_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
   1136				     unsigned int freq, int dir)
   1137{
   1138	struct snd_soc_component *component = codec_dai->component;
   1139	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1140	struct device *dev = component->dev;
   1141
   1142	dev_dbg(dev, "HiFi setup sysclk: clk_id=%u, freq=%u", clk_id, freq);
   1143	return cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, clk_id, freq);
   1144}
   1145
   1146static int cpcap_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
   1147				  unsigned int fmt)
   1148{
   1149	struct snd_soc_component *component = codec_dai->component;
   1150	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1151	struct device *dev = component->dev;
   1152	static const u16 reg = CPCAP_REG_SDACDI;
   1153	static const u16 mask =
   1154		BIT(CPCAP_BIT_SMB_ST_DAC) |
   1155		BIT(CPCAP_BIT_ST_CLK_INV) |
   1156		BIT(CPCAP_BIT_ST_FS_INV) |
   1157		BIT(CPCAP_BIT_ST_DIG_AUD_FS0) |
   1158		BIT(CPCAP_BIT_ST_DIG_AUD_FS1) |
   1159		BIT(CPCAP_BIT_ST_L_TIMESLOT0) |
   1160		BIT(CPCAP_BIT_ST_L_TIMESLOT1) |
   1161		BIT(CPCAP_BIT_ST_L_TIMESLOT2) |
   1162		BIT(CPCAP_BIT_ST_R_TIMESLOT0) |
   1163		BIT(CPCAP_BIT_ST_R_TIMESLOT1) |
   1164		BIT(CPCAP_BIT_ST_R_TIMESLOT2);
   1165	u16 val = 0x0000;
   1166
   1167	dev_dbg(dev, "HiFi setup dai format (%08x)", fmt);
   1168
   1169	/*
   1170	 * "HiFi Playback" should always be configured as
   1171	 * SND_SOC_DAIFMT_CBP_CFP - codec clk & frm provider
   1172	 * SND_SOC_DAIFMT_I2S - I2S mode
   1173	 */
   1174	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
   1175	case SND_SOC_DAIFMT_CBP_CFP:
   1176		val &= ~BIT(CPCAP_BIT_SMB_ST_DAC);
   1177		break;
   1178	default:
   1179		dev_err(dev, "HiFi dai fmt failed: CPCAP should be provider");
   1180		return -EINVAL;
   1181	}
   1182
   1183	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
   1184	case SND_SOC_DAIFMT_IB_IF:
   1185		val |= BIT(CPCAP_BIT_ST_FS_INV);
   1186		val |= BIT(CPCAP_BIT_ST_CLK_INV);
   1187		break;
   1188	case SND_SOC_DAIFMT_IB_NF:
   1189		val &= ~BIT(CPCAP_BIT_ST_FS_INV);
   1190		val |= BIT(CPCAP_BIT_ST_CLK_INV);
   1191		break;
   1192	case SND_SOC_DAIFMT_NB_IF:
   1193		val |= BIT(CPCAP_BIT_ST_FS_INV);
   1194		val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
   1195		break;
   1196	case SND_SOC_DAIFMT_NB_NF:
   1197		val &= ~BIT(CPCAP_BIT_ST_FS_INV);
   1198		val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
   1199		break;
   1200	default:
   1201		dev_err(dev, "HiFi dai fmt failed: unsupported clock invert mode");
   1202		return -EINVAL;
   1203	}
   1204
   1205	if (val & BIT(CPCAP_BIT_ST_CLK_INV))
   1206		val &= ~BIT(CPCAP_BIT_ST_CLK_INV);
   1207	else
   1208		val |= BIT(CPCAP_BIT_ST_CLK_INV);
   1209
   1210	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
   1211	case SND_SOC_DAIFMT_I2S:
   1212		val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
   1213		val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
   1214		break;
   1215	default:
   1216		/* 01 - 4 slots network mode */
   1217		val |= BIT(CPCAP_BIT_ST_DIG_AUD_FS0);
   1218		val &= ~BIT(CPCAP_BIT_ST_DIG_AUD_FS1);
   1219		/* L on slot 1 */
   1220		val |= BIT(CPCAP_BIT_ST_L_TIMESLOT0);
   1221		break;
   1222	}
   1223
   1224	dev_dbg(dev, "HiFi dai format: val=%04x", val);
   1225	return regmap_update_bits(cpcap->regmap, reg, mask, val);
   1226}
   1227
   1228static int cpcap_hifi_set_mute(struct snd_soc_dai *dai, int mute, int direction)
   1229{
   1230	struct snd_soc_component *component = dai->component;
   1231	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1232	static const u16 reg = CPCAP_REG_RXSDOA;
   1233	static const u16 mask = BIT(CPCAP_BIT_ST_DAC_SW);
   1234	u16 val;
   1235
   1236	if (mute)
   1237		val = 0;
   1238	else
   1239		val = BIT(CPCAP_BIT_ST_DAC_SW);
   1240
   1241	dev_dbg(component->dev, "HiFi mute: %d", mute);
   1242	return regmap_update_bits(cpcap->regmap, reg, mask, val);
   1243}
   1244
   1245static const struct snd_soc_dai_ops cpcap_dai_hifi_ops = {
   1246	.hw_params	= cpcap_hifi_hw_params,
   1247	.set_sysclk	= cpcap_hifi_set_dai_sysclk,
   1248	.set_fmt	= cpcap_hifi_set_dai_fmt,
   1249	.mute_stream	= cpcap_hifi_set_mute,
   1250	.no_capture_mute = 1,
   1251};
   1252
   1253static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
   1254				 struct snd_pcm_hw_params *params,
   1255				 struct snd_soc_dai *dai)
   1256{
   1257	struct snd_soc_component *component = dai->component;
   1258	struct device *dev = component->dev;
   1259	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1260	static const u16 reg_cdi = CPCAP_REG_CDI;
   1261	int rate = params_rate(params);
   1262	int channels = params_channels(params);
   1263	int direction = substream->stream;
   1264	u16 val, mask;
   1265	int err;
   1266
   1267	dev_dbg(dev, "Voice setup HW params: rate=%d, direction=%d, chan=%d",
   1268		rate, direction, channels);
   1269
   1270	err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate);
   1271	if (err)
   1272		return err;
   1273
   1274	if (direction == SNDRV_PCM_STREAM_CAPTURE) {
   1275		mask = 0x0000;
   1276		mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
   1277		mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1);
   1278		mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2);
   1279		mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0);
   1280		mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1);
   1281		mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2);
   1282		val = 0x0000;
   1283		if (channels >= 2)
   1284			val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
   1285		err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val);
   1286		if (err)
   1287			return err;
   1288	}
   1289
   1290	return 0;
   1291}
   1292
   1293static int cpcap_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
   1294				      unsigned int freq, int dir)
   1295{
   1296	struct snd_soc_component *component = codec_dai->component;
   1297	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1298
   1299	dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u",
   1300		clk_id, freq);
   1301	return cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, clk_id, freq);
   1302}
   1303
   1304static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
   1305				   unsigned int fmt)
   1306{
   1307	struct snd_soc_component *component = codec_dai->component;
   1308	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1309	static const u16 mask = BIT(CPCAP_BIT_SMB_CDC) |
   1310				BIT(CPCAP_BIT_CLK_INV) |
   1311				BIT(CPCAP_BIT_FS_INV) |
   1312				BIT(CPCAP_BIT_CDC_DIG_AUD_FS0) |
   1313				BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
   1314	u16 val = 0x0000;
   1315	int err;
   1316
   1317	dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt);
   1318
   1319	/*
   1320	 * "Voice Playback" and "Voice Capture" should always be
   1321	 * configured as SND_SOC_DAIFMT_CBP_CFP - codec clk & frm
   1322	 * provider
   1323	 */
   1324	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
   1325	case SND_SOC_DAIFMT_CBP_CFP:
   1326		val &= ~BIT(CPCAP_BIT_SMB_CDC);
   1327		break;
   1328	default:
   1329		dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the provider");
   1330		val &= ~BIT(CPCAP_BIT_SMB_CDC);
   1331		break;
   1332	}
   1333
   1334	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
   1335	case SND_SOC_DAIFMT_IB_IF:
   1336		val |= BIT(CPCAP_BIT_CLK_INV);
   1337		val |= BIT(CPCAP_BIT_FS_INV);
   1338		break;
   1339	case SND_SOC_DAIFMT_IB_NF:
   1340		val |= BIT(CPCAP_BIT_CLK_INV);
   1341		val &= ~BIT(CPCAP_BIT_FS_INV);
   1342		break;
   1343	case SND_SOC_DAIFMT_NB_IF:
   1344		val &= ~BIT(CPCAP_BIT_CLK_INV);
   1345		val |= BIT(CPCAP_BIT_FS_INV);
   1346		break;
   1347	case SND_SOC_DAIFMT_NB_NF:
   1348		val &= ~BIT(CPCAP_BIT_CLK_INV);
   1349		val &= ~BIT(CPCAP_BIT_FS_INV);
   1350		break;
   1351	default:
   1352		dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode");
   1353		break;
   1354	}
   1355
   1356	if (val & BIT(CPCAP_BIT_CLK_INV))
   1357		val &= ~BIT(CPCAP_BIT_CLK_INV);
   1358	else
   1359		val |= BIT(CPCAP_BIT_CLK_INV);
   1360
   1361	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
   1362	case SND_SOC_DAIFMT_I2S:
   1363		/* 11 - true I2S mode */
   1364		val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
   1365		val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
   1366		break;
   1367	default:
   1368		/* 4 timeslots network mode */
   1369		val |= BIT(CPCAP_BIT_CDC_DIG_AUD_FS0);
   1370		val &= ~BIT(CPCAP_BIT_CDC_DIG_AUD_FS1);
   1371		break;
   1372	}
   1373
   1374	dev_dbg(component->dev, "Voice dai format: val=%04x", val);
   1375	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val);
   1376	if (err)
   1377		return err;
   1378
   1379	cpcap->codec_format = val;
   1380	return 0;
   1381}
   1382
   1383
   1384/*
   1385 * Configure codec for voice call if requested.
   1386 *
   1387 * We can configure most with snd_soc_dai_set_sysclk(), snd_soc_dai_set_fmt()
   1388 * and snd_soc_dai_set_tdm_slot(). This function configures the rest of the
   1389 * cpcap related hardware as CPU is not involved in the voice call.
   1390 */
   1391static int cpcap_voice_call(struct cpcap_audio *cpcap, struct snd_soc_dai *dai,
   1392			    bool voice_call)
   1393{
   1394	int mask, err;
   1395
   1396	/* Modem to codec VAUDIO_MODE1 */
   1397	mask = BIT(CPCAP_BIT_VAUDIO_MODE1);
   1398	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC,
   1399				 mask, voice_call ? mask : 0);
   1400	if (err)
   1401		return err;
   1402
   1403	/* Clear MIC1_MUX for call */
   1404	mask = BIT(CPCAP_BIT_MIC1_MUX);
   1405	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
   1406				 mask, voice_call ? 0 : mask);
   1407	if (err)
   1408		return err;
   1409
   1410	/* Set MIC2_MUX for call */
   1411	mask = BIT(CPCAP_BIT_MB_ON1L) | BIT(CPCAP_BIT_MB_ON1R) |
   1412		BIT(CPCAP_BIT_MIC2_MUX) | BIT(CPCAP_BIT_MIC2_PGA_EN);
   1413	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
   1414				 mask, voice_call ? mask : 0);
   1415	if (err)
   1416		return err;
   1417
   1418	/* Enable LDSP for call */
   1419	mask = BIT(CPCAP_BIT_A2_LDSP_L_EN) | BIT(CPCAP_BIT_A2_LDSP_R_EN);
   1420	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA,
   1421				 mask, voice_call ? mask : 0);
   1422	if (err)
   1423		return err;
   1424
   1425	/* Enable CPCAP_BIT_PGA_CDC_EN for call */
   1426	mask = BIT(CPCAP_BIT_PGA_CDC_EN);
   1427	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
   1428				 mask, voice_call ? mask : 0);
   1429	if (err)
   1430		return err;
   1431
   1432	/* Unmute voice for call */
   1433	if (dai) {
   1434		err = snd_soc_dai_digital_mute(dai, !voice_call,
   1435					       SNDRV_PCM_STREAM_PLAYBACK);
   1436		if (err)
   1437			return err;
   1438	}
   1439
   1440	/* Set modem to codec mic CDC and HPF for call */
   1441	mask = BIT(CPCAP_BIT_MIC2_CDC_EN) | BIT(CPCAP_BIT_CDC_EN_RX) |
   1442	       BIT(CPCAP_BIT_AUDOHPF_1) | BIT(CPCAP_BIT_AUDOHPF_0) |
   1443	       BIT(CPCAP_BIT_AUDIHPF_1) | BIT(CPCAP_BIT_AUDIHPF_0);
   1444	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC,
   1445				 mask, voice_call ? mask : 0);
   1446	if (err)
   1447		return err;
   1448
   1449	/* Enable modem to codec CDC for call*/
   1450	mask = BIT(CPCAP_BIT_CDC_CLK_EN);
   1451	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
   1452				 mask, voice_call ? mask : 0);
   1453
   1454	return err;
   1455}
   1456
   1457static int cpcap_voice_set_tdm_slot(struct snd_soc_dai *dai,
   1458				    unsigned int tx_mask, unsigned int rx_mask,
   1459				    int slots, int slot_width)
   1460{
   1461	struct snd_soc_component *component = dai->component;
   1462	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1463	int err, ts_mask, mask;
   1464	bool voice_call;
   1465
   1466	/*
   1467	 * Primitive test for voice call, probably needs more checks
   1468	 * later on for 16-bit calls detected, Bluetooth headset etc.
   1469	 */
   1470	if (tx_mask == 0 && rx_mask == 1 && slot_width == 8)
   1471		voice_call = true;
   1472	else
   1473		voice_call = false;
   1474
   1475	ts_mask = 0x7 << CPCAP_BIT_MIC2_TIMESLOT0;
   1476	ts_mask |= 0x7 << CPCAP_BIT_MIC1_RX_TIMESLOT0;
   1477
   1478	mask = (tx_mask & 0x7) << CPCAP_BIT_MIC2_TIMESLOT0;
   1479	mask |= (rx_mask & 0x7) << CPCAP_BIT_MIC1_RX_TIMESLOT0;
   1480
   1481	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
   1482				 ts_mask, mask);
   1483	if (err)
   1484		return err;
   1485
   1486	err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, slot_width * 1000);
   1487	if (err)
   1488		return err;
   1489
   1490	err = cpcap_voice_call(cpcap, dai, voice_call);
   1491	if (err)
   1492		return err;
   1493
   1494	return 0;
   1495}
   1496
   1497static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute, int direction)
   1498{
   1499	struct snd_soc_component *component = dai->component;
   1500	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1501	static const u16 reg = CPCAP_REG_RXCOA;
   1502	static const u16 mask = BIT(CPCAP_BIT_CDC_SW);
   1503	u16 val;
   1504
   1505	if (mute)
   1506		val = 0;
   1507	else
   1508		val = BIT(CPCAP_BIT_CDC_SW);
   1509
   1510	dev_dbg(component->dev, "Voice mute: %d", mute);
   1511	return regmap_update_bits(cpcap->regmap, reg, mask, val);
   1512};
   1513
   1514static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
   1515	.hw_params	= cpcap_voice_hw_params,
   1516	.set_sysclk	= cpcap_voice_set_dai_sysclk,
   1517	.set_fmt	= cpcap_voice_set_dai_fmt,
   1518	.set_tdm_slot	= cpcap_voice_set_tdm_slot,
   1519	.mute_stream	= cpcap_voice_set_mute,
   1520	.no_capture_mute = 1,
   1521};
   1522
   1523static struct snd_soc_dai_driver cpcap_dai[] = {
   1524{
   1525	.id = 0,
   1526	.name = "cpcap-hifi",
   1527	.playback = {
   1528		.stream_name = "HiFi Playback",
   1529		.channels_min = 2,
   1530		.channels_max = 2,
   1531		.rates = SNDRV_PCM_RATE_8000_48000,
   1532		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE,
   1533	},
   1534	.ops = &cpcap_dai_hifi_ops,
   1535},
   1536{
   1537	.id = 1,
   1538	.name = "cpcap-voice",
   1539	.playback = {
   1540		.stream_name = "Voice Playback",
   1541		.channels_min = 1,
   1542		.channels_max = 1,
   1543		.rates = SNDRV_PCM_RATE_8000_48000,
   1544		.formats = SNDRV_PCM_FMTBIT_S16_LE,
   1545	},
   1546	.capture = {
   1547		.stream_name = "Voice Capture",
   1548		.channels_min = 1,
   1549		.channels_max = 2,
   1550		.rates = SNDRV_PCM_RATE_8000_48000,
   1551		.formats = SNDRV_PCM_FMTBIT_S16_LE,
   1552	},
   1553	.ops = &cpcap_dai_voice_ops,
   1554},
   1555};
   1556
   1557static int cpcap_dai_mux(struct cpcap_audio *cpcap, bool swap_dai_configuration)
   1558{
   1559	u16 hifi_val, voice_val;
   1560	u16 hifi_mask = BIT(CPCAP_BIT_DIG_AUD_IN_ST_DAC);
   1561	u16 voice_mask = BIT(CPCAP_BIT_DIG_AUD_IN);
   1562	int err;
   1563
   1564
   1565
   1566	if (!swap_dai_configuration) {
   1567		/* Codec on DAI0, HiFi on DAI1 */
   1568		voice_val = 0;
   1569		hifi_val = hifi_mask;
   1570	} else {
   1571		/* Codec on DAI1, HiFi on DAI0 */
   1572		voice_val = voice_mask;
   1573		hifi_val = 0;
   1574	}
   1575
   1576	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
   1577				 voice_mask, voice_val);
   1578	if (err)
   1579		return err;
   1580
   1581	err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI,
   1582				 hifi_mask, hifi_val);
   1583	if (err)
   1584		return err;
   1585
   1586	return 0;
   1587}
   1588
   1589static int cpcap_audio_reset(struct snd_soc_component *component,
   1590			     bool swap_dai_configuration)
   1591{
   1592	struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
   1593	int i, err = 0;
   1594
   1595	dev_dbg(component->dev, "init audio codec");
   1596
   1597	for (i = 0; i < ARRAY_SIZE(cpcap_default_regs); i++) {
   1598		err = regmap_update_bits(cpcap->regmap,
   1599					 cpcap_default_regs[i].reg,
   1600					 cpcap_default_regs[i].mask,
   1601					 cpcap_default_regs[i].val);
   1602		if (err)
   1603			return err;
   1604	}
   1605
   1606	/* setup default settings */
   1607	err = cpcap_dai_mux(cpcap, swap_dai_configuration);
   1608	if (err)
   1609		return err;
   1610
   1611	err = cpcap_set_sysclk(cpcap, CPCAP_DAI_HIFI, 0, 26000000);
   1612	if (err)
   1613		return err;
   1614	err = cpcap_set_sysclk(cpcap, CPCAP_DAI_VOICE, 0, 26000000);
   1615	if (err)
   1616		return err;
   1617
   1618	err = cpcap_set_samprate(cpcap, CPCAP_DAI_HIFI, 48000);
   1619	if (err)
   1620		return err;
   1621
   1622	err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, 48000);
   1623	if (err)
   1624		return err;
   1625
   1626	return 0;
   1627}
   1628
   1629static int cpcap_soc_probe(struct snd_soc_component *component)
   1630{
   1631	struct cpcap_audio *cpcap;
   1632	int err;
   1633
   1634	cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL);
   1635	if (!cpcap)
   1636		return -ENOMEM;
   1637	snd_soc_component_set_drvdata(component, cpcap);
   1638	cpcap->component = component;
   1639
   1640	cpcap->regmap = dev_get_regmap(component->dev->parent, NULL);
   1641	if (!cpcap->regmap)
   1642		return -ENODEV;
   1643	snd_soc_component_init_regmap(component, cpcap->regmap);
   1644
   1645	err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor);
   1646	if (err)
   1647		return err;
   1648
   1649	return cpcap_audio_reset(component, false);
   1650}
   1651
   1652static struct snd_soc_component_driver soc_codec_dev_cpcap = {
   1653	.probe			= cpcap_soc_probe,
   1654	.controls		= cpcap_snd_controls,
   1655	.num_controls		= ARRAY_SIZE(cpcap_snd_controls),
   1656	.dapm_widgets		= cpcap_dapm_widgets,
   1657	.num_dapm_widgets	= ARRAY_SIZE(cpcap_dapm_widgets),
   1658	.dapm_routes		= intercon,
   1659	.num_dapm_routes	= ARRAY_SIZE(intercon),
   1660	.idle_bias_on		= 1,
   1661	.use_pmdown_time	= 1,
   1662	.endianness		= 1,
   1663	.non_legacy_dai_naming	= 1,
   1664};
   1665
   1666static int cpcap_codec_probe(struct platform_device *pdev)
   1667{
   1668	struct device_node *codec_node =
   1669		of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec");
   1670	if (!codec_node)
   1671		return -ENODEV;
   1672
   1673	pdev->dev.of_node = codec_node;
   1674
   1675	return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap,
   1676				      cpcap_dai, ARRAY_SIZE(cpcap_dai));
   1677}
   1678
   1679static struct platform_driver cpcap_codec_driver = {
   1680	.probe		= cpcap_codec_probe,
   1681	.driver		= {
   1682		.name	= "cpcap-codec",
   1683	},
   1684};
   1685module_platform_driver(cpcap_codec_driver);
   1686
   1687MODULE_ALIAS("platform:cpcap-codec");
   1688MODULE_DESCRIPTION("ASoC CPCAP codec driver");
   1689MODULE_AUTHOR("Sebastian Reichel");
   1690MODULE_LICENSE("GPL v2");