Merge branch 'mic' into combined
# Conflicts: # arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
This commit is contained in:
commit
2931c83762
7 changed files with 2242 additions and 1 deletions
|
|
@ -209,13 +209,34 @@
|
|||
sound {
|
||||
compatible = "qcom,milos-sndcard", "qcom,sm8450-sndcard";
|
||||
model = "Fairphone (Gen. 6)";
|
||||
// audio-routing = ...
|
||||
audio-routing = "AMIC1", "MIC BIAS1",
|
||||
"AMIC2", "MIC BIAS2",
|
||||
"AMIC3", "MIC BIAS3",
|
||||
"TX SWR_INPUT0", "ADC1_OUTPUT",
|
||||
"TX SWR_INPUT1", "ADC2_OUTPUT",
|
||||
"TX SWR_INPUT2", "ADC3_OUTPUT";
|
||||
|
||||
pinctrl-0 = <&lpi_i2s2_active>;
|
||||
pinctrl-1 = <&lpi_i2s2_sleep>;
|
||||
pinctrl-names = "default",
|
||||
"sleep";
|
||||
|
||||
wcd-capture-dai-link {
|
||||
link-name = "WCD Capture";
|
||||
|
||||
codec {
|
||||
sound-dai = <&wcd9378 1>, <&swr2 0>, <&lpass_txmacro 0>;
|
||||
};
|
||||
|
||||
cpu {
|
||||
sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
|
||||
};
|
||||
|
||||
platform {
|
||||
sound-dai = <&q6apm>;
|
||||
};
|
||||
};
|
||||
|
||||
i2s-dai-link {
|
||||
link-name = "Senary MI2S Playback";
|
||||
|
||||
|
|
@ -233,6 +254,29 @@
|
|||
};
|
||||
};
|
||||
|
||||
wcd9378: audio-codec {
|
||||
compatible = "qcom,wcd9378-codec";
|
||||
|
||||
pinctrl-0 = <&wcd_reset_n_active>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
reset-gpios = <&tlmm 162 GPIO_ACTIVE_LOW>;
|
||||
|
||||
vdd-buck-supply = <&vreg_l8b>;
|
||||
vdd-rxtx-supply = <&vreg_l7b>;
|
||||
vdd-io-supply = <&vreg_l7b>;
|
||||
vdd-mic-bias-supply = <&vreg_bob>;
|
||||
|
||||
qcom,micbias1-microvolt = <1800000>;
|
||||
qcom,micbias2-microvolt = <1800000>;
|
||||
qcom,micbias3-microvolt = <1800000>;
|
||||
|
||||
qcom,rx-device = <&wcd9378_rx>;
|
||||
qcom,tx-device = <&wcd9378_tx>;
|
||||
|
||||
#sound-dai-cells = <1>;
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
pm8008-thermal {
|
||||
polling-delay-passive = <100>;
|
||||
|
|
@ -1103,6 +1147,36 @@
|
|||
};
|
||||
};
|
||||
|
||||
&swr1 {
|
||||
status = "okay";
|
||||
|
||||
/* WCD9378 RX */
|
||||
wcd9378_rx: codec@0,4 {
|
||||
compatible = "sdw20217011000";
|
||||
reg = <0 4>;
|
||||
qcom,rx-port-mapping = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
||||
&swr2 {
|
||||
status = "okay";
|
||||
|
||||
/* WCD9378 TX */
|
||||
wcd9378_tx: codec@0,3 {
|
||||
compatible = "sdw20217011000";
|
||||
reg = <0 3>;
|
||||
|
||||
/*
|
||||
* WCD9378 TX port 1 (ADC1) <=> SWR2 port 1 (SWRM_TX1)
|
||||
* WCD9378 TX port 2 (ADC2) <=> SWR2 port 1
|
||||
* WCD9378 TX port 3 (ADC3) <=> SWR2 port 1
|
||||
* WCD9378 TX port 4 (DMIC0,1, MBHC) <=> SWR2 port 2
|
||||
* WCD9378 TX port 5 (DMIC2..5) <=> SWR2 port 3
|
||||
*/
|
||||
qcom,tx-port-mapping = <1 1 1 2 3>;
|
||||
};
|
||||
};
|
||||
|
||||
&tlmm {
|
||||
gpio-reserved-ranges = <8 4>, /* Fingerprint SPI */
|
||||
<13 1>, /* NC */
|
||||
|
|
@ -1255,6 +1329,13 @@
|
|||
drive-strength = <2>;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
wcd_reset_n_active: wcd-reset-n-active-state {
|
||||
pins = "gpio162";
|
||||
function = "gpio";
|
||||
drive-strength = <16>;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
|
||||
&uart5 {
|
||||
|
|
|
|||
|
|
@ -976,6 +976,20 @@ static enum sdw_command_response qcom_swrm_xfer_msg(struct sdw_bus *bus,
|
|||
struct qcom_swrm_ctrl *ctrl = to_qcom_sdw(bus);
|
||||
int ret, i, len;
|
||||
|
||||
if (msg->page) {
|
||||
ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page1,
|
||||
msg->dev_num,
|
||||
SDW_SCP_ADDRPAGE1);
|
||||
if (ret)
|
||||
return SDW_CMD_IGNORED;
|
||||
|
||||
ret = qcom_swrm_cmd_fifo_wr_cmd(ctrl, msg->addr_page2,
|
||||
msg->dev_num,
|
||||
SDW_SCP_ADDRPAGE2);
|
||||
if (ret)
|
||||
return SDW_CMD_IGNORED;
|
||||
}
|
||||
|
||||
if (msg->flags == SDW_MSG_FLAG_READ) {
|
||||
for (i = 0; i < msg->len;) {
|
||||
len = min(msg->len - i, QCOM_SWRM_MAX_RD_LEN);
|
||||
|
|
|
|||
|
|
@ -2431,6 +2431,22 @@ config SND_SOC_WCD937X_SDW
|
|||
via soundwire.
|
||||
To compile this codec driver say Y or m.
|
||||
|
||||
config SND_SOC_WCD9378
|
||||
depends on SND_SOC_WCD9378_SDW
|
||||
tristate
|
||||
depends on SOUNDWIRE || !SOUNDWIRE
|
||||
select SND_SOC_WCD_COMMON
|
||||
|
||||
config SND_SOC_WCD9378_SDW
|
||||
tristate "WCD9378 Codec - SDW"
|
||||
select SND_SOC_WCD9378
|
||||
depends on SOUNDWIRE
|
||||
select REGMAP_SOUNDWIRE
|
||||
help
|
||||
Driver for the Qualcomm WCD9378 audio codec connected via
|
||||
SoundWire, as found on SM7635 phones.
|
||||
To compile this codec driver say Y or m.
|
||||
|
||||
config SND_SOC_WCD938X
|
||||
depends on SND_SOC_WCD938X_SDW
|
||||
tristate
|
||||
|
|
|
|||
|
|
@ -356,6 +356,8 @@ snd-soc-wcd9335-y := wcd9335.o
|
|||
snd-soc-wcd934x-y := wcd934x.o
|
||||
snd-soc-wcd937x-y := wcd937x.o
|
||||
snd-soc-wcd937x-sdw-y := wcd937x-sdw.o
|
||||
snd-soc-wcd9378-y := wcd9378.o
|
||||
snd-soc-wcd9378-sdw-y := wcd9378-sdw.o
|
||||
snd-soc-wcd938x-y := wcd938x.o
|
||||
snd-soc-wcd938x-sdw-y := wcd938x-sdw.o
|
||||
snd-soc-wcd939x-y := wcd939x.o
|
||||
|
|
@ -796,6 +798,11 @@ ifdef CONFIG_SND_SOC_WCD937X_SDW
|
|||
# avoid link failure by forcing sdw code built-in when needed
|
||||
obj-$(CONFIG_SND_SOC_WCD937X) += snd-soc-wcd937x-sdw.o
|
||||
endif
|
||||
obj-$(CONFIG_SND_SOC_WCD9378) += snd-soc-wcd9378.o
|
||||
ifdef CONFIG_SND_SOC_WCD9378_SDW
|
||||
# avoid link failure by forcing sdw code built-in when needed
|
||||
obj-$(CONFIG_SND_SOC_WCD9378) += snd-soc-wcd9378-sdw.o
|
||||
endif
|
||||
obj-$(CONFIG_SND_SOC_WCD938X) += snd-soc-wcd938x.o
|
||||
ifdef CONFIG_SND_SOC_WCD938X_SDW
|
||||
# avoid link failure by forcing sdw code built-in when needed
|
||||
|
|
|
|||
487
sound/soc/codecs/wcd9378-sdw.c
Normal file
487
sound/soc/codecs/wcd9378-sdw.c
Normal file
|
|
@ -0,0 +1,487 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2026, Jorijn van der Graaf
|
||||
*
|
||||
* SoundWire slave driver for the Qualcomm WCD9378 audio codec.
|
||||
*
|
||||
* The codec presents two SoundWire slaves (RX and TX, mfg 0x0217 part
|
||||
* 0x0110); the SDCA control space is a 32-bit paged register map accessed
|
||||
* through the TX slave.
|
||||
*/
|
||||
|
||||
#include <linux/component.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_registers.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
||||
#include "wcd-common.h"
|
||||
#include "wcd9378.h"
|
||||
|
||||
#define WCD9378_SDW_CH(id, pn, cmask, mmask) \
|
||||
[id] = { \
|
||||
.port_num = pn, \
|
||||
.ch_mask = cmask, \
|
||||
.master_ch_mask = mmask, \
|
||||
}
|
||||
|
||||
/*
|
||||
* Each ADC sits alone on its own TX device port (channel 1); by default
|
||||
* they land on channels 1/2/3 of the same master port (SWRM_TX1 on the
|
||||
* FP6). DMIC/MBHC masks per the downstream qcom,tx_swr_ch_map.
|
||||
*/
|
||||
static struct wcd_sdw_ch_info wcd9378_sdw_tx_ch_info[] = {
|
||||
WCD9378_SDW_CH(WCD9378_ADC1, WCD9378_ADC_1_PORT, BIT(0), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_ADC2, WCD9378_ADC_2_PORT, BIT(0), BIT(1)),
|
||||
WCD9378_SDW_CH(WCD9378_ADC3, WCD9378_ADC_3_PORT, BIT(0), BIT(2)),
|
||||
WCD9378_SDW_CH(WCD9378_DMIC0, WCD9378_DMIC_0_1_MBHC_PORT, BIT(2), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_DMIC1, WCD9378_DMIC_0_1_MBHC_PORT, BIT(3), BIT(1)),
|
||||
WCD9378_SDW_CH(WCD9378_MBHC, WCD9378_DMIC_0_1_MBHC_PORT, BIT(2), BIT(2)),
|
||||
WCD9378_SDW_CH(WCD9378_DMIC2, WCD9378_DMIC_2_5_PORT, BIT(0), BIT(2)),
|
||||
WCD9378_SDW_CH(WCD9378_DMIC3, WCD9378_DMIC_2_5_PORT, BIT(1), BIT(3)),
|
||||
WCD9378_SDW_CH(WCD9378_DMIC4, WCD9378_DMIC_2_5_PORT, BIT(2), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_DMIC5, WCD9378_DMIC_2_5_PORT, BIT(3), BIT(1)),
|
||||
};
|
||||
|
||||
static struct wcd_sdw_ch_info wcd9378_sdw_rx_ch_info[] = {
|
||||
WCD9378_SDW_CH(WCD9378_HPH_L, WCD9378_HPH_PORT, BIT(0), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_HPH_R, WCD9378_HPH_PORT, BIT(1), BIT(1)),
|
||||
WCD9378_SDW_CH(WCD9378_CLSH, WCD9378_CLSH_PORT, BIT(0), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_COMP_L, WCD9378_COMP_PORT, BIT(0), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_COMP_R, WCD9378_COMP_PORT, BIT(1), BIT(1)),
|
||||
WCD9378_SDW_CH(WCD9378_LO, WCD9378_LO_PORT, BIT(0), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_DSD_L, WCD9378_DSD_PORT, BIT(0), BIT(0)),
|
||||
WCD9378_SDW_CH(WCD9378_DSD_R, WCD9378_DSD_PORT, BIT(1), BIT(1)),
|
||||
};
|
||||
|
||||
static struct sdw_dpn_prop wcd9378_dpn_prop[WCD9378_MAX_SWR_PORTS] = {
|
||||
{
|
||||
.num = 1,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 8,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 2,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 3,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 4,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 5,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}
|
||||
};
|
||||
|
||||
int wcd9378_sdw_hw_params(struct wcd9378_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct sdw_port_config port_config[WCD9378_MAX_SWR_PORTS];
|
||||
unsigned long ch_mask;
|
||||
int i, j;
|
||||
|
||||
wcd->sconfig.ch_count = 1;
|
||||
wcd->active_ports = 0;
|
||||
for (i = 0; i < WCD9378_MAX_SWR_PORTS; i++) {
|
||||
ch_mask = wcd->port_config[i].ch_mask;
|
||||
if (!ch_mask)
|
||||
continue;
|
||||
|
||||
for_each_set_bit(j, &ch_mask, 4)
|
||||
wcd->sconfig.ch_count++;
|
||||
|
||||
port_config[wcd->active_ports] = wcd->port_config[i];
|
||||
wcd->active_ports++;
|
||||
}
|
||||
|
||||
wcd->sconfig.bps = 1;
|
||||
wcd->sconfig.frame_rate = params_rate(params);
|
||||
wcd->sconfig.direction = wcd->is_tx ? SDW_DATA_DIR_TX : SDW_DATA_DIR_RX;
|
||||
wcd->sconfig.type = SDW_STREAM_PCM;
|
||||
|
||||
return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig,
|
||||
&port_config[0], wcd->active_ports,
|
||||
wcd->sruntime);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd9378_sdw_hw_params);
|
||||
|
||||
/*
|
||||
* Tell the codec the bus clock: base 19.2 MHz plus a scale (div) per bank.
|
||||
* The downstream driver writes these raw SCP registers on every capture
|
||||
* start; here the bus_config callback covers bank switches.
|
||||
*/
|
||||
static int wcd9378_bus_config(struct sdw_slave *slave,
|
||||
struct sdw_bus_params *params)
|
||||
{
|
||||
u8 scale;
|
||||
|
||||
switch (params->curr_dr_freq) {
|
||||
case 4800000:
|
||||
scale = WCD9378_SWRS_CLK_SCALE_DIV4;
|
||||
break;
|
||||
case 9600000:
|
||||
default:
|
||||
scale = WCD9378_SWRS_CLK_SCALE_DIV2;
|
||||
break;
|
||||
}
|
||||
|
||||
sdw_write(slave, WCD9378_SWRS_SCP_HOST_CLK_DIV2_CTL(params->next_bank),
|
||||
0x01);
|
||||
sdw_write(slave, WCD9378_SWRS_SCP_BASE_CLK,
|
||||
WCD9378_SWRS_BASE_CLK_19P2MHZ);
|
||||
sdw_write(slave, WCD9378_SWRS_SCP_BUSCLK_SCALE_BANK0, scale);
|
||||
sdw_write(slave, WCD9378_SWRS_SCP_BUSCLK_SCALE_BANK1, scale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sdw_slave_ops wcd9378_slave_ops = {
|
||||
.update_status = wcd_update_status,
|
||||
.bus_config = wcd9378_bus_config,
|
||||
};
|
||||
|
||||
static const struct reg_default wcd9378_defaults[] = {
|
||||
{ WCD9378_ANA_BIAS, 0x00 },
|
||||
{ WCD9378_ANA_TX_CH1, 0x20 },
|
||||
{ WCD9378_ANA_TX_CH2, 0x00 },
|
||||
{ WCD9378_ANA_TX_CH3, 0x20 },
|
||||
{ WCD9378_ANA_TX_CH3_HPF, 0x00 },
|
||||
{ WCD9378_ANA_MICB2_RAMP, 0x00 },
|
||||
{ WCD9378_BIAS_VBG_FINE_ADJ, 0x55 },
|
||||
{ WCD9378_MBHC_CTL_SPARE_1, 0x02 },
|
||||
{ WCD9378_MICB1_TEST_CTL_2, 0x00 },
|
||||
{ WCD9378_MICB2_TEST_CTL_2, 0x00 },
|
||||
{ WCD9378_MICB3_TEST_CTL_2, 0x80 },
|
||||
{ WCD9378_TX_COM_TXFE_DIV_CTL, 0x22 },
|
||||
{ WCD9378_SLEEP_CTL, 0x16 },
|
||||
{ WCD9378_TX_NEW_CH12_MUX, 0x11 },
|
||||
{ WCD9378_TX_NEW_CH34_MUX, 0x23 },
|
||||
{ WCD9378_TOP_CLK_CFG, 0x00 },
|
||||
{ WCD9378_CDC_ANA_TX_CLK_CTL, 0x0e },
|
||||
{ WCD9378_CDC_AMIC_CTL, 0x07 },
|
||||
{ WCD9378_PDM_WD_CTL0, 0x0f },
|
||||
{ WCD9378_PDM_WD_CTL1, 0x0f },
|
||||
{ WCD9378_PLATFORM_CTL, 0x01 },
|
||||
{ WCD9378_SYS_USAGE_CTRL, 0x00 },
|
||||
{ WCD9378_HPH_UP_T0, 0x02 },
|
||||
{ WCD9378_HPH_UP_T9, 0x02 },
|
||||
{ WCD9378_HPH_DN_T0, 0x05 },
|
||||
{ WCD9378_MICB_REMAP_TABLE_VAL_3, 0x00 },
|
||||
{ WCD9378_MICB_REMAP_TABLE_VAL_4, 0x00 },
|
||||
{ WCD9378_MICB_REMAP_TABLE_VAL_5, 0x00 },
|
||||
{ WCD9378_SM0_MB_SEL, 0x00 },
|
||||
{ WCD9378_SM1_MB_SEL, 0x00 },
|
||||
{ WCD9378_SM2_MB_SEL, 0x00 },
|
||||
{ WCD9378_MB_PULLUP_EN, 0x00 },
|
||||
{ WCD9378_SMP_AMP_FUNC_ACT, 0x00 },
|
||||
{ WCD9378_CMT_GRP_MASK, 0x00 },
|
||||
{ WCD9378_SMP_JACK_IT31_MICB, 0x00 },
|
||||
{ WCD9378_SMP_JACK_IT31_USAGE, 0x03 },
|
||||
{ WCD9378_SMP_JACK_PDE34_REQ_PS, 0x03 },
|
||||
{ WCD9378_SMP_JACK_FUNC_ACT, 0x00 },
|
||||
{ WCD9378_SMP_MIC_IT11_MICB(0), 0x00 },
|
||||
{ WCD9378_SMP_MIC_IT11_USAGE(0), 0x03 },
|
||||
{ WCD9378_SMP_MIC_PDE11_REQ_PS(0), 0x03 },
|
||||
{ WCD9378_SMP_MIC_FUNC_ACT(0), 0x00 },
|
||||
{ WCD9378_SMP_MIC_IT11_MICB(1), 0x00 },
|
||||
{ WCD9378_SMP_MIC_IT11_USAGE(1), 0x03 },
|
||||
{ WCD9378_SMP_MIC_PDE11_REQ_PS(1), 0x03 },
|
||||
{ WCD9378_SMP_MIC_FUNC_ACT(1), 0x00 },
|
||||
{ WCD9378_SMP_MIC_IT11_MICB(2), 0x00 },
|
||||
{ WCD9378_SMP_MIC_IT11_USAGE(2), 0x03 },
|
||||
{ WCD9378_SMP_MIC_PDE11_REQ_PS(2), 0x03 },
|
||||
{ WCD9378_SMP_MIC_FUNC_ACT(2), 0x00 },
|
||||
};
|
||||
|
||||
static bool wcd9378_rdwr_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case WCD9378_ANA_BIAS:
|
||||
case WCD9378_ANA_TX_CH1:
|
||||
case WCD9378_ANA_TX_CH2:
|
||||
case WCD9378_ANA_TX_CH3:
|
||||
case WCD9378_ANA_TX_CH3_HPF:
|
||||
case WCD9378_ANA_MICB2_RAMP:
|
||||
case WCD9378_BIAS_VBG_FINE_ADJ:
|
||||
case WCD9378_MBHC_CTL_SPARE_1:
|
||||
case WCD9378_MICB1_TEST_CTL_2:
|
||||
case WCD9378_MICB2_TEST_CTL_2:
|
||||
case WCD9378_MICB3_TEST_CTL_2:
|
||||
case WCD9378_TX_COM_TXFE_DIV_CTL:
|
||||
case WCD9378_SLEEP_CTL:
|
||||
case WCD9378_TX_NEW_CH12_MUX:
|
||||
case WCD9378_TX_NEW_CH34_MUX:
|
||||
case WCD9378_HPH_RDAC_GAIN_CTL:
|
||||
case WCD9378_HPH_RDAC_HD2_CTL_L:
|
||||
case WCD9378_HPH_RDAC_HD2_CTL_R:
|
||||
case WCD9378_TOP_CLK_CFG:
|
||||
case WCD9378_CDC_ANA_TX_CLK_CTL:
|
||||
case WCD9378_CDC_AMIC_CTL:
|
||||
case WCD9378_PDM_WD_CTL0:
|
||||
case WCD9378_PDM_WD_CTL1:
|
||||
case WCD9378_PLATFORM_CTL:
|
||||
case WCD9378_SYS_USAGE_CTRL:
|
||||
case WCD9378_HPH_UP_T0:
|
||||
case WCD9378_HPH_UP_T9:
|
||||
case WCD9378_HPH_DN_T0:
|
||||
case WCD9378_MICB_REMAP_TABLE_VAL_3:
|
||||
case WCD9378_MICB_REMAP_TABLE_VAL_4:
|
||||
case WCD9378_MICB_REMAP_TABLE_VAL_5:
|
||||
case WCD9378_SM0_MB_SEL:
|
||||
case WCD9378_SM1_MB_SEL:
|
||||
case WCD9378_SM2_MB_SEL:
|
||||
case WCD9378_MB_PULLUP_EN:
|
||||
case WCD9378_SMP_AMP_FUNC_STAT:
|
||||
case WCD9378_SMP_AMP_FUNC_ACT:
|
||||
case WCD9378_CMT_GRP_MASK:
|
||||
case WCD9378_SMP_JACK_IT31_MICB:
|
||||
case WCD9378_SMP_JACK_IT31_USAGE:
|
||||
case WCD9378_SMP_JACK_PDE34_REQ_PS:
|
||||
case WCD9378_SMP_JACK_FUNC_STAT:
|
||||
case WCD9378_SMP_JACK_FUNC_ACT:
|
||||
case WCD9378_SMP_MIC_IT11_MICB(0):
|
||||
case WCD9378_SMP_MIC_IT11_USAGE(0):
|
||||
case WCD9378_SMP_MIC_PDE11_REQ_PS(0):
|
||||
case WCD9378_SMP_MIC_FUNC_STAT(0):
|
||||
case WCD9378_SMP_MIC_FUNC_ACT(0):
|
||||
case WCD9378_SMP_MIC_IT11_MICB(1):
|
||||
case WCD9378_SMP_MIC_IT11_USAGE(1):
|
||||
case WCD9378_SMP_MIC_PDE11_REQ_PS(1):
|
||||
case WCD9378_SMP_MIC_FUNC_STAT(1):
|
||||
case WCD9378_SMP_MIC_FUNC_ACT(1):
|
||||
case WCD9378_SMP_MIC_IT11_MICB(2):
|
||||
case WCD9378_SMP_MIC_IT11_USAGE(2):
|
||||
case WCD9378_SMP_MIC_PDE11_REQ_PS(2):
|
||||
case WCD9378_SMP_MIC_FUNC_STAT(2):
|
||||
case WCD9378_SMP_MIC_FUNC_ACT(2):
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool wcd9378_volatile_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case WCD9378_FUNC_EXT_ID_0:
|
||||
case WCD9378_FUNC_EXT_ID_1:
|
||||
case WCD9378_FUNC_EXT_VER:
|
||||
case WCD9378_FUNC_STAT:
|
||||
case WCD9378_DEV_MANU_ID_0:
|
||||
case WCD9378_DEV_MANU_ID_1:
|
||||
case WCD9378_DEV_PART_ID_0:
|
||||
case WCD9378_DEV_PART_ID_1:
|
||||
case WCD9378_DEV_VER:
|
||||
case WCD9378_EFUSE_REG_16:
|
||||
case WCD9378_EFUSE_REG_29:
|
||||
case WCD9378_SEQ_TX0_STAT:
|
||||
case WCD9378_SEQ_TX1_STAT:
|
||||
case WCD9378_SEQ_TX2_STAT:
|
||||
case WCD9378_SMP_JACK_PDE34_ACT_PS:
|
||||
case WCD9378_SMP_MIC_OT10_USAGE(0):
|
||||
case WCD9378_SMP_MIC_PDE11_ACT_PS(0):
|
||||
case WCD9378_SMP_MIC_OT10_USAGE(1):
|
||||
case WCD9378_SMP_MIC_PDE11_ACT_PS(1):
|
||||
case WCD9378_SMP_MIC_OT10_USAGE(2):
|
||||
case WCD9378_SMP_MIC_PDE11_ACT_PS(2):
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool wcd9378_readable_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if (wcd9378_volatile_register(dev, reg))
|
||||
return true;
|
||||
|
||||
return wcd9378_rdwr_register(dev, reg);
|
||||
}
|
||||
|
||||
static const struct regmap_config wcd9378_regmap_config = {
|
||||
.name = "wcd9378_csr",
|
||||
.reg_bits = 32,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
.reg_defaults = wcd9378_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(wcd9378_defaults),
|
||||
.max_register = WCD9378_MAX_REGISTER,
|
||||
.readable_reg = wcd9378_readable_register,
|
||||
.writeable_reg = wcd9378_rdwr_register,
|
||||
.volatile_reg = wcd9378_volatile_register,
|
||||
};
|
||||
|
||||
static int wcd9378_sdw_probe(struct sdw_slave *pdev,
|
||||
const struct sdw_device_id *id)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct wcd9378_sdw_priv *wcd;
|
||||
u8 master_ch_mask[WCD9378_MAX_SWR_CH_IDS];
|
||||
int master_ch_mask_size = 0;
|
||||
int ret, i;
|
||||
|
||||
wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
|
||||
if (!wcd)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Port map index starts at 0, however the data ports start at index 1 */
|
||||
if (of_property_present(dev->of_node, "qcom,tx-port-mapping")) {
|
||||
wcd->is_tx = true;
|
||||
ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping",
|
||||
&pdev->m_port_map[1],
|
||||
WCD9378_MAX_TX_SWR_PORTS);
|
||||
} else {
|
||||
ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping",
|
||||
&pdev->m_port_map[1],
|
||||
WCD9378_MAX_SWR_PORTS);
|
||||
}
|
||||
if (ret < 0)
|
||||
dev_info(dev, "Error getting static port mapping for %s (%d)\n",
|
||||
wcd->is_tx ? "TX" : "RX", ret);
|
||||
|
||||
wcd->sdev = pdev;
|
||||
dev_set_drvdata(dev, wcd);
|
||||
|
||||
pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |
|
||||
SDW_SCP_INT1_BUS_CLASH |
|
||||
SDW_SCP_INT1_PARITY;
|
||||
pdev->prop.lane_control_support = true;
|
||||
pdev->prop.simple_clk_stop_capable = true;
|
||||
/* The SDCA control space sits above the 16-bit address range */
|
||||
pdev->prop.paging_support = true;
|
||||
|
||||
memset(master_ch_mask, 0, WCD9378_MAX_SWR_CH_IDS);
|
||||
|
||||
if (wcd->is_tx) {
|
||||
master_ch_mask_size = of_property_count_u8_elems(dev->of_node,
|
||||
"qcom,tx-channel-mapping");
|
||||
|
||||
if (master_ch_mask_size > 0)
|
||||
ret = of_property_read_u8_array(dev->of_node,
|
||||
"qcom,tx-channel-mapping",
|
||||
master_ch_mask,
|
||||
master_ch_mask_size);
|
||||
} else {
|
||||
master_ch_mask_size = of_property_count_u8_elems(dev->of_node,
|
||||
"qcom,rx-channel-mapping");
|
||||
|
||||
if (master_ch_mask_size > 0)
|
||||
ret = of_property_read_u8_array(dev->of_node,
|
||||
"qcom,rx-channel-mapping",
|
||||
master_ch_mask,
|
||||
master_ch_mask_size);
|
||||
}
|
||||
|
||||
if (wcd->is_tx) {
|
||||
pdev->prop.source_ports = GENMASK(WCD9378_MAX_TX_SWR_PORTS, 1);
|
||||
pdev->prop.src_dpn_prop = wcd9378_dpn_prop;
|
||||
wcd->ch_info = &wcd9378_sdw_tx_ch_info[0];
|
||||
|
||||
for (i = 0; i < master_ch_mask_size; i++)
|
||||
wcd->ch_info[i].master_ch_mask = WCD9378_SWRM_CH_MASK(master_ch_mask[i]);
|
||||
|
||||
pdev->prop.wake_capable = true;
|
||||
|
||||
wcd->regmap = devm_regmap_init_sdw(pdev, &wcd9378_regmap_config);
|
||||
if (IS_ERR(wcd->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(wcd->regmap),
|
||||
"Regmap init failed\n");
|
||||
|
||||
/* Start in cache-only until device is enumerated */
|
||||
regcache_cache_only(wcd->regmap, true);
|
||||
} else {
|
||||
pdev->prop.sink_ports = GENMASK(WCD9378_MAX_SWR_PORTS, 1);
|
||||
pdev->prop.sink_dpn_prop = wcd9378_dpn_prop;
|
||||
wcd->ch_info = &wcd9378_sdw_rx_ch_info[0];
|
||||
|
||||
for (i = 0; i < master_ch_mask_size; i++)
|
||||
wcd->ch_info[i].master_ch_mask = WCD9378_SWRM_CH_MASK(master_ch_mask[i]);
|
||||
}
|
||||
|
||||
ret = component_add(dev, &wcd_sdw_component_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set suspended until aggregate device is bind */
|
||||
pm_runtime_set_suspended(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wcd9378_sdw_remove(struct sdw_slave *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
component_del(dev, &wcd_sdw_component_ops);
|
||||
}
|
||||
|
||||
static const struct sdw_device_id wcd9378_sdw_id[] = {
|
||||
SDW_SLAVE_ENTRY(0x0217, 0x0110, 0),
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdw, wcd9378_sdw_id);
|
||||
|
||||
static int wcd9378_sdw_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct wcd9378_sdw_priv *wcd = dev_get_drvdata(dev);
|
||||
|
||||
if (wcd->regmap) {
|
||||
regcache_cache_only(wcd->regmap, true);
|
||||
regcache_mark_dirty(wcd->regmap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9378_sdw_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct wcd9378_sdw_priv *wcd = dev_get_drvdata(dev);
|
||||
|
||||
if (wcd->regmap) {
|
||||
regcache_cache_only(wcd->regmap, false);
|
||||
regcache_sync(wcd->regmap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops wcd9378_sdw_pm_ops = {
|
||||
RUNTIME_PM_OPS(wcd9378_sdw_runtime_suspend, wcd9378_sdw_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static struct sdw_driver wcd9378_sdw_driver = {
|
||||
.probe = wcd9378_sdw_probe,
|
||||
.remove = wcd9378_sdw_remove,
|
||||
.ops = &wcd9378_slave_ops,
|
||||
.id_table = wcd9378_sdw_id,
|
||||
.driver = {
|
||||
.name = "wcd9378-sdw",
|
||||
.pm = pm_ptr(&wcd9378_sdw_pm_ops),
|
||||
}
|
||||
};
|
||||
module_sdw_driver(wcd9378_sdw_driver);
|
||||
|
||||
MODULE_DESCRIPTION("WCD9378 SDW codec driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
1394
sound/soc/codecs/wcd9378.c
Normal file
1394
sound/soc/codecs/wcd9378.c
Normal file
File diff suppressed because it is too large
Load diff
242
sound/soc/codecs/wcd9378.h
Normal file
242
sound/soc/codecs/wcd9378.h
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2026, Jorijn van der Graaf
|
||||
*
|
||||
* Register map for the Qualcomm WCD9378 audio codec.
|
||||
*
|
||||
* The codec exposes its control registers in the SoundWire SDCA control
|
||||
* address space (bit 30 set, SDCA function number in bits 25:22), accessed
|
||||
* through the TX SoundWire slave. The analog core registers (function 0,
|
||||
* implementation-defined region at +0x180000) are layout-compatible with
|
||||
* the WCD937x family; on top of that the chip adds SDCA-style functions
|
||||
* (SmartMIC0/1/2, SmartJACK, SmartAMP) whose sequencers drive the analog
|
||||
* power-up autonomously.
|
||||
*/
|
||||
|
||||
#ifndef __WCD9378_H__
|
||||
#define __WCD9378_H__
|
||||
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
/* SDCA function 0 (extension unit): device identity */
|
||||
#define WCD9378_FUNC_EXT_ID_0 0x40000048
|
||||
#define WCD9378_FUNC_EXT_ID_1 0x40000049
|
||||
#define WCD9378_FUNC_EXT_VER 0x40000050
|
||||
#define WCD9378_FUNC_STAT 0x40080000
|
||||
#define WCD9378_DEV_MANU_ID_0 0x40100060
|
||||
#define WCD9378_DEV_MANU_ID_1 0x40100061
|
||||
#define WCD9378_DEV_PART_ID_0 0x40100068
|
||||
#define WCD9378_DEV_PART_ID_1 0x40100069
|
||||
#define WCD9378_DEV_VER 0x40100070
|
||||
|
||||
/* Analog core (WCD937x-compatible layout), function 0 + 0x180000 */
|
||||
#define WCD9378_ANA_PAGE 0x40180000
|
||||
#define WCD9378_ANA_BIAS 0x40180001
|
||||
#define WCD9378_ANA_BIAS_ANALOG_BIAS_EN BIT(7)
|
||||
#define WCD9378_ANA_BIAS_PRECHRG_EN BIT(6)
|
||||
#define WCD9378_ANA_RX_SUPPLIES 0x40180008
|
||||
#define WCD9378_ANA_TX_CH1 0x4018000e
|
||||
#define WCD9378_ANA_TX_CH2 0x4018000f
|
||||
#define WCD9378_ANA_TX_CH2_HPF1_INIT BIT(6)
|
||||
#define WCD9378_ANA_TX_CH2_HPF2_INIT BIT(5)
|
||||
#define WCD9378_ANA_TX_CH3 0x40180010
|
||||
#define WCD9378_ANA_TX_CH3_HPF 0x40180011
|
||||
#define WCD9378_ANA_TX_CH3_HPF3_INIT BIT(6)
|
||||
#define WCD9378_ANA_TX_GAIN_MASK GENMASK(4, 0)
|
||||
#define WCD9378_ANA_MICB1 0x40180022
|
||||
#define WCD9378_ANA_MICB2 0x40180023
|
||||
#define WCD9378_ANA_MICB2_RAMP 0x40180024
|
||||
#define WCD9378_ANA_MICB2_RAMP_SHIFT_CTL_MASK GENMASK(4, 2)
|
||||
#define WCD9378_ANA_MICB2_RAMP_EN BIT(7)
|
||||
#define WCD9378_ANA_MICB3 0x40180025
|
||||
#define WCD9378_BIAS_VBG_FINE_ADJ 0x40180029
|
||||
#define WCD9378_MBHC_CTL_SPARE_1 0x40180058
|
||||
#define WCD9378_MICB1_TEST_CTL_2 0x4018006c
|
||||
#define WCD9378_MICB2_TEST_CTL_2 0x4018006f
|
||||
#define WCD9378_MICB3_TEST_CTL_2 0x40180072
|
||||
#define WCD9378_TX_COM_TXFE_DIV_CTL 0x4018007b
|
||||
#define WCD9378_TX_COM_TXFE_DIV_SEQ_BYPASS BIT(7)
|
||||
#define WCD9378_SLEEP_CTL 0x40180103
|
||||
#define WCD9378_SLEEP_CTL_BG_CTL_MASK GENMASK(3, 1)
|
||||
#define WCD9378_SLEEP_CTL_BG_EN BIT(7)
|
||||
#define WCD9378_SLEEP_CTL_LDOL_BG_SEL BIT(6)
|
||||
#define WCD9378_TX_NEW_CH12_MUX 0x4018012e
|
||||
#define WCD9378_TX_NEW_CH12_MUX_CH1_SEL_MASK GENMASK(2, 0)
|
||||
#define WCD9378_TX_NEW_CH12_MUX_CH2_SEL_MASK GENMASK(5, 3)
|
||||
#define WCD9378_TX_NEW_CH34_MUX 0x4018012f
|
||||
#define WCD9378_TX_NEW_CH34_MUX_CH3_SEL_MASK GENMASK(2, 0)
|
||||
#define WCD9378_HPH_RDAC_GAIN_CTL 0x40180132
|
||||
#define WCD9378_HPH_RDAC_HD2_CTL_L 0x40180133
|
||||
#define WCD9378_HPH_RDAC_HD2_CTL_R 0x40180136
|
||||
|
||||
/* Digital page */
|
||||
#define WCD9378_TOP_CLK_CFG 0x40180407
|
||||
#define WCD9378_CDC_ANA_TX_CLK_CTL 0x40180417
|
||||
#define WCD9378_CDC_ANA_TXSCBIAS_CLK_EN BIT(0)
|
||||
#define WCD9378_CDC_AMIC_CTL 0x4018045a
|
||||
#define WCD9378_PDM_WD_CTL0 0x40180465
|
||||
#define WCD9378_PDM_WD_CTL1 0x40180466
|
||||
#define WCD9378_EFUSE_REG_16 0x401804c0
|
||||
#define WCD9378_EFUSE_REG_29 0x401804cd
|
||||
#define WCD9378_PLATFORM_CTL 0x401804f0
|
||||
|
||||
/* Sequencer block (SEQR) */
|
||||
#define WCD9378_SYS_USAGE_CTRL 0x40180501
|
||||
#define WCD9378_SYS_USAGE_CTRL_MASK GENMASK(3, 0)
|
||||
#define WCD9378_HPH_UP_T0 0x40180510
|
||||
#define WCD9378_HPH_UP_T9 0x40180519
|
||||
#define WCD9378_HPH_DN_T0 0x4018051b
|
||||
#define WCD9378_SEQ_TX0_STAT 0x40180592
|
||||
#define WCD9378_SEQ_TX1_STAT 0x40180593
|
||||
#define WCD9378_SEQ_TX2_STAT 0x40180594
|
||||
#define WCD9378_MICB_REMAP_TABLE_VAL_3 0x401805a3
|
||||
#define WCD9378_MICB_REMAP_TABLE_VAL_4 0x401805a4
|
||||
#define WCD9378_MICB_REMAP_TABLE_VAL_5 0x401805a5
|
||||
#define WCD9378_SM0_MB_SEL 0x401805b0
|
||||
#define WCD9378_SM1_MB_SEL 0x401805b1
|
||||
#define WCD9378_SM2_MB_SEL 0x401805b2
|
||||
#define WCD9378_SM_MB_SEL_MASK GENMASK(1, 0)
|
||||
#define WCD9378_MB_PULLUP_EN 0x401805b3
|
||||
|
||||
/* SmartAMP SDCA function */
|
||||
#define WCD9378_SMP_AMP_FUNC_STAT 0x40880000
|
||||
#define WCD9378_SMP_AMP_FUNC_ACT 0x40880008
|
||||
|
||||
/* SmartJACK SDCA function (hosts ADC2 when fed from AMIC2) */
|
||||
#define WCD9378_CMT_GRP_MASK 0x40c00008
|
||||
#define WCD9378_SMP_JACK_IT31_MICB 0x40c00798
|
||||
#define WCD9378_SMP_JACK_IT31_USAGE 0x40c007a0
|
||||
#define WCD9378_SMP_JACK_PDE34_REQ_PS 0x40c00808
|
||||
#define WCD9378_SMP_JACK_FUNC_STAT 0x40c80000
|
||||
#define WCD9378_SMP_JACK_FUNC_ACT 0x40c80008
|
||||
#define WCD9378_SMP_JACK_PDE34_ACT_PS 0x40c80800
|
||||
|
||||
/* SmartMIC0/1/2 SDCA functions (ADC1/ADC2/ADC3 sequencers) */
|
||||
#define WCD9378_SMP_MIC_BASE(n) (0x41000000 + (n) * 0x400000)
|
||||
#define WCD9378_SMP_MIC_IT11_MICB(n) (WCD9378_SMP_MIC_BASE(n) + 0x98)
|
||||
#define WCD9378_SMP_MIC_IT11_USAGE(n) (WCD9378_SMP_MIC_BASE(n) + 0xa0)
|
||||
#define WCD9378_SMP_MIC_PDE11_REQ_PS(n) (WCD9378_SMP_MIC_BASE(n) + 0x108)
|
||||
#define WCD9378_SMP_MIC_OT10_USAGE(n) (WCD9378_SMP_MIC_BASE(n) + 0x3a0)
|
||||
#define WCD9378_SMP_MIC_FUNC_STAT(n) (WCD9378_SMP_MIC_BASE(n) + 0x80000)
|
||||
#define WCD9378_SMP_MIC_FUNC_ACT(n) (WCD9378_SMP_MIC_BASE(n) + 0x80008)
|
||||
#define WCD9378_SMP_MIC_PDE11_ACT_PS(n) (WCD9378_SMP_MIC_BASE(n) + 0x80100)
|
||||
|
||||
#define WCD9378_MAX_REGISTER 0x41900070
|
||||
|
||||
/*
|
||||
* Raw (16-bit, non-paged) Qualcomm slave SCP registers, written with
|
||||
* sdw_write() directly. Bus clock indication towards the codec.
|
||||
*/
|
||||
#define WCD9378_SWRS_SCP_BASE_CLK 0x4d
|
||||
#define WCD9378_SWRS_SCP_BUSCLK_SCALE_BANK0 0x62
|
||||
#define WCD9378_SWRS_SCP_BUSCLK_SCALE_BANK1 0x72
|
||||
#define WCD9378_SWRS_SCP_HOST_CLK_DIV2_CTL(m) (0xe0 + 0x10 * (m))
|
||||
#define WCD9378_SWRS_BASE_CLK_19P2MHZ 0x01
|
||||
#define WCD9378_SWRS_CLK_SCALE_DIV2 0x02 /* 9.6 MHz */
|
||||
#define WCD9378_SWRS_CLK_SCALE_DIV4 0x03 /* 4.8 MHz */
|
||||
|
||||
/* ITxx_USAGE ADC mode values */
|
||||
#define WCD9378_ADC_USAGE_HIFI 0x01
|
||||
#define WCD9378_ADC_USAGE_LO_HIF 0x02
|
||||
#define WCD9378_ADC_USAGE_NORMAL 0x03
|
||||
#define WCD9378_ADC_USAGE_LP 0x05
|
||||
#define WCD9378_ADC_USAGE_OFF 0x00
|
||||
|
||||
/* ITxx_MICB usage values */
|
||||
#define WCD9378_MICB_USAGE_OFF 0x00
|
||||
#define WCD9378_MICB_USAGE_PULL_DOWN 0x01
|
||||
#define WCD9378_MICB_USAGE_1P2V 0x02
|
||||
#define WCD9378_MICB_USAGE_1P8V_OR_PULLUP 0x03
|
||||
#define WCD9378_MICB_USAGE_2P5V 0x04
|
||||
#define WCD9378_MICB_USAGE_2P75V 0x05
|
||||
#define WCD9378_MICB_USAGE_2P2V 0xf0
|
||||
#define WCD9378_MICB_USAGE_2P7V 0xf1
|
||||
#define WCD9378_MICB_USAGE_2P8V 0xf2
|
||||
#define WCD9378_MICB_USAGE_REMAP_TABLE_3 0xf3
|
||||
#define WCD9378_MICB_USAGE_REMAP_TABLE_4 0xf4
|
||||
#define WCD9378_MICB_USAGE_REMAP_TABLE_5 0xf5
|
||||
|
||||
/* PDExx_REQ_PS power states */
|
||||
#define WCD9378_PDE_PS0_ON 0x00
|
||||
#define WCD9378_PDE_PS3_OFF 0x03
|
||||
|
||||
#define WCD9378_MAX_MICBIAS 3
|
||||
#define WCD9378_MAX_SWR_CH_IDS 15
|
||||
#define WCD9378_SWRM_CH_MASK(ch_idx) BIT((ch_idx) - 1)
|
||||
|
||||
enum wcd9378_tx_sdw_ports {
|
||||
WCD9378_ADC_1_PORT = 1,
|
||||
WCD9378_ADC_2_PORT,
|
||||
WCD9378_ADC_3_PORT,
|
||||
WCD9378_DMIC_0_1_MBHC_PORT,
|
||||
WCD9378_DMIC_2_5_PORT,
|
||||
WCD9378_MAX_TX_SWR_PORTS = WCD9378_DMIC_2_5_PORT,
|
||||
};
|
||||
|
||||
enum wcd9378_rx_sdw_ports {
|
||||
WCD9378_HPH_PORT = 1,
|
||||
WCD9378_CLSH_PORT,
|
||||
WCD9378_COMP_PORT,
|
||||
WCD9378_LO_PORT,
|
||||
WCD9378_DSD_PORT,
|
||||
WCD9378_MAX_SWR_PORTS = WCD9378_DSD_PORT,
|
||||
};
|
||||
|
||||
enum wcd9378_tx_sdw_channels {
|
||||
WCD9378_ADC1,
|
||||
WCD9378_ADC2,
|
||||
WCD9378_ADC3,
|
||||
WCD9378_DMIC0,
|
||||
WCD9378_DMIC1,
|
||||
WCD9378_MBHC,
|
||||
WCD9378_DMIC2,
|
||||
WCD9378_DMIC3,
|
||||
WCD9378_DMIC4,
|
||||
WCD9378_DMIC5,
|
||||
};
|
||||
|
||||
enum wcd9378_rx_sdw_channels {
|
||||
WCD9378_HPH_L,
|
||||
WCD9378_HPH_R,
|
||||
WCD9378_CLSH,
|
||||
WCD9378_COMP_L,
|
||||
WCD9378_COMP_R,
|
||||
WCD9378_LO,
|
||||
WCD9378_DSD_L,
|
||||
WCD9378_DSD_R,
|
||||
};
|
||||
|
||||
struct wcd9378_priv;
|
||||
struct wcd9378_sdw_priv {
|
||||
struct sdw_slave *sdev;
|
||||
struct sdw_stream_config sconfig;
|
||||
struct sdw_stream_runtime *sruntime;
|
||||
struct sdw_port_config port_config[WCD9378_MAX_SWR_PORTS];
|
||||
struct wcd_sdw_ch_info *ch_info;
|
||||
bool port_enable[WCD9378_MAX_SWR_CH_IDS];
|
||||
unsigned int master_channel_map[SDW_MAX_PORTS];
|
||||
int active_ports;
|
||||
bool is_tx;
|
||||
struct wcd9378_priv *wcd9378;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_WCD9378_SDW)
|
||||
int wcd9378_sdw_hw_params(struct wcd9378_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai);
|
||||
#else
|
||||
static inline int wcd9378_sdw_hw_params(struct wcd9378_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WCD9378_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue