mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
ASoC: codecs: Add driver support for rk730
This patch add support for RK730 audio codec. Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com> Change-Id: Ia3d883d10cb8a0418f5f4313154f593cc90a1700
This commit is contained in:
@@ -161,6 +161,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_RK3228
|
||||
imply SND_SOC_RK3308
|
||||
imply SND_SOC_RK3328
|
||||
imply SND_SOC_RK730
|
||||
imply SND_SOC_RK817
|
||||
imply SND_SOC_RT274
|
||||
imply SND_SOC_RT286
|
||||
@@ -1101,6 +1102,10 @@ config SND_SOC_RK3328
|
||||
tristate "Rockchip RK3328 audio CODEC"
|
||||
select REGMAP_MMIO
|
||||
|
||||
config SND_SOC_RK730
|
||||
tristate "Rockchip RK730 CODEC"
|
||||
select REGMAP_I2C
|
||||
|
||||
config SND_SOC_RK817
|
||||
tristate "Rockchip RK817 CODEC"
|
||||
depends on MFD_RK808
|
||||
|
||||
@@ -168,6 +168,7 @@ snd-soc-rk312x-objs := rk312x_codec.o
|
||||
snd-soc-rk3228-objs := rk3228_codec.o
|
||||
snd-soc-rk3308-objs := rk3308_codec.o
|
||||
snd-soc-rk3328-objs := rk3328_codec.o
|
||||
snd-soc-rk730-objs := rk730.o
|
||||
snd-soc-rk817-objs := rk817_codec.o
|
||||
snd-soc-rk-codec-digital-objs := rk_codec_digital.o
|
||||
snd-soc-rl6231-objs := rl6231.o
|
||||
@@ -492,6 +493,7 @@ obj-$(CONFIG_SND_SOC_RK312X) += snd-soc-rk312x.o
|
||||
obj-$(CONFIG_SND_SOC_RK3228) += snd-soc-rk3228.o
|
||||
obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o
|
||||
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
|
||||
obj-$(CONFIG_SND_SOC_RK730) += snd-soc-rk730.o
|
||||
obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o
|
||||
obj-$(CONFIG_SND_SOC_RK_CODEC_DIGITAL) += snd-soc-rk-codec-digital.o
|
||||
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
|
||||
|
||||
971
sound/soc/codecs/rk730.c
Normal file
971
sound/soc/codecs/rk730.c
Normal file
@@ -0,0 +1,971 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* rk730.c -- RK730 ALSA SoC Audio driver
|
||||
*
|
||||
* Copyright (C) 2022 Rockchip Electronics Co.,Ltd
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/clk.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#include "rk730.h"
|
||||
|
||||
enum rk730_mix_mode {
|
||||
RK730_MIX_MODE_1_PATH,
|
||||
RK730_MIX_MODE_2_PATHS,
|
||||
RK730_MIX_MODE_3_PATHS,
|
||||
};
|
||||
|
||||
enum rk730_chop_freq {
|
||||
RK730_CHOP_FREQ_NONE,
|
||||
RK730_CHOP_FREQ_200KHZ,
|
||||
RK730_CHOP_FREQ_400KHZ,
|
||||
RK730_CHOP_FREQ_800KHZ,
|
||||
};
|
||||
|
||||
struct rk730_priv {
|
||||
struct regmap *regmap;
|
||||
struct clk *mclk;
|
||||
atomic_t mix_mode;
|
||||
};
|
||||
|
||||
/* ADC Digital Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(adc_dig_tlv, -95625, 375, 0);
|
||||
/* DAC Digital Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -95625, 375, 0);
|
||||
/* D2S Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(d2s_tlv, -1800, 300, 0);
|
||||
/* ADC Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 300, 0);
|
||||
/* MUX Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(mux_tlv, -600, 600, 0);
|
||||
/* MIX Buf Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(mix_buf_tlv, -1800, 300, 0);
|
||||
/* HP Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(hp_tlv, 0, 300, 0);
|
||||
/* LINEOUT Volume */
|
||||
static const DECLARE_TLV_DB_SCALE(lineout_tlv, 0, 300, 0);
|
||||
/* MIC Boost Volume */
|
||||
static const DECLARE_TLV_DB_RANGE(micboost_tlv,
|
||||
0, 2, TLV_DB_SCALE_ITEM(0, 600, 0),
|
||||
3, 4, TLV_DB_SCALE_ITEM(2400, 1200, 0),
|
||||
5, 7, TLV_DB_SCALE_ITEM(4200, 600, 0),
|
||||
8, 8, TLV_DB_SCALE_ITEM(-300, 0, 0),
|
||||
16, 16, TLV_DB_SCALE_ITEM(-600, 0, 0),
|
||||
24, 24, TLV_DB_SCALE_ITEM(-900, 0, 0)
|
||||
);
|
||||
|
||||
static const char * const mux_out_l_text[] = { "DIFF", "MIC1N", "MIC2N" };
|
||||
static const char * const mux_out_r_text[] = { "DIFF", "MIC2P", "MIC1P" };
|
||||
static const char * const mux_input_l_text[] = { "DIFF", "VINP1", "VINN1" };
|
||||
static const char * const mux_input_r_text[] = { "DIFF", "VINP2", "VINN2" };
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(mux_out_l_enum, RK730_MUXER_0, 2, mux_out_l_text);
|
||||
static SOC_ENUM_SINGLE_DECL(mux_out_r_enum, RK730_MUXER_0, 6, mux_out_r_text);
|
||||
static SOC_ENUM_SINGLE_DECL(mux_input_l_enum, RK730_ADC_PGA_BLOCK_0,
|
||||
4, mux_input_l_text);
|
||||
static SOC_ENUM_SINGLE_DECL(mux_input_r_enum, RK730_ADC_PGA_BLOCK_1,
|
||||
4, mux_input_r_text);
|
||||
|
||||
static const struct snd_kcontrol_new mux_out_l =
|
||||
SOC_DAPM_ENUM("Left Out Mux", mux_out_l_enum);
|
||||
static const struct snd_kcontrol_new mux_out_r =
|
||||
SOC_DAPM_ENUM("Right Out Mux", mux_out_r_enum);
|
||||
static const struct snd_kcontrol_new mux_input_l =
|
||||
SOC_DAPM_ENUM("Left Input Mux", mux_input_l_enum);
|
||||
static const struct snd_kcontrol_new mux_input_r =
|
||||
SOC_DAPM_ENUM("Right Input Mux", mux_input_r_enum);
|
||||
|
||||
static const struct snd_kcontrol_new mix_ctls[] = {
|
||||
SOC_DAPM_SINGLE("Left Out Mux Switch", RK730_MUXER_0, 0, 1, 1),
|
||||
SOC_DAPM_SINGLE("Right Out Mux Switch", RK730_MUXER_0, 4, 1, 1),
|
||||
};
|
||||
|
||||
static const char * const adc_hpf_cutoff_text[] = {
|
||||
"3.79Hz", "60Hz", "243Hz", "493Hz",
|
||||
};
|
||||
|
||||
static const char * const dac_hpf_cutoff_text[] = {
|
||||
"80Hz", "100Hz", "120Hz", "140Hz",
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(adc_hpf_cutoff_enum, RK730_DADC_HPF,
|
||||
4, adc_hpf_cutoff_text);
|
||||
static SOC_ENUM_SINGLE_DECL(dac_hpf_cutoff_enum, RK730_DDAC_MUTE_MIXCTL,
|
||||
5, dac_hpf_cutoff_text);
|
||||
|
||||
static const char * const chop_freq_text[] = {
|
||||
"Disabled", "200kHz", "400kHz", "800kHz",
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(dac_ref_buf_chop_freq_enum, RK730_HK_TOP_1,
|
||||
6, chop_freq_text);
|
||||
static SOC_ENUM_SINGLE_DECL(mic_chop_freq_enum, RK730_MIC_BOOST_3,
|
||||
6, chop_freq_text);
|
||||
static SOC_ENUM_SINGLE_DECL(adc_pga_chop_freq_enum, RK730_ADC_PGA_BLOCK_1,
|
||||
6, chop_freq_text);
|
||||
static SOC_ENUM_SINGLE_DECL(mux_out_chop_freq_enum, RK730_MUXER_1,
|
||||
0, chop_freq_text);
|
||||
static SOC_ENUM_SINGLE_DECL(mix_chop_freq_enum, RK730_MIXER_2,
|
||||
6, chop_freq_text);
|
||||
static SOC_ENUM_SINGLE_DECL(hp_lo_chop_freq_enum, RK730_HP_1,
|
||||
5, chop_freq_text);
|
||||
|
||||
static const char * const micbias_volt_text[] = {
|
||||
"2.0v", "2.2v", "2.5v", "2.8v",
|
||||
};
|
||||
|
||||
static const char * const charge_pump_volt_text[] = {
|
||||
"2.1v", "2.3v", "2.5v", "2.7v",
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(micbias_volt_enum, RK730_MIC_BIAS,
|
||||
2, micbias_volt_text);
|
||||
static SOC_ENUM_SINGLE_DECL(charge_pump_volt_enum, RK730_CHARGE_PUMP,
|
||||
1, charge_pump_volt_text);
|
||||
|
||||
static int rk730_adc_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
unsigned int val = snd_soc_component_read(component, mc->reg);
|
||||
unsigned int sign = snd_soc_component_read(component, RK730_DADC_SR_ACL);
|
||||
unsigned int mask = (1 << fls(mc->max)) - 1;
|
||||
unsigned int shift = mc->shift;
|
||||
int mid = mc->max / 2;
|
||||
int uv;
|
||||
|
||||
uv = (val >> shift) & mask;
|
||||
sign &= RK730_DADC_SR_ACL_VOLL_POL_MASK;
|
||||
if (sign)
|
||||
uv = mid + uv;
|
||||
else
|
||||
uv = mid - uv;
|
||||
|
||||
ucontrol->value.integer.value[0] = uv;
|
||||
ucontrol->value.integer.value[1] = uv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_adc_vol_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
unsigned int reg = mc->reg;
|
||||
unsigned int rreg = mc->rreg;
|
||||
unsigned int shift = mc->shift;
|
||||
unsigned int mask = (1 << fls(mc->max)) - 1;
|
||||
unsigned int val, val_mask, sign, sign_mask;
|
||||
int uv = ucontrol->value.integer.value[0];
|
||||
int min = mc->min;
|
||||
int mid = mc->max / 2;
|
||||
|
||||
sign_mask = RK730_DADC_SR_ACL_VOLL_POL_MASK | RK730_DADC_SR_ACL_VOLR_POL_MASK;
|
||||
|
||||
if (uv > mid) {
|
||||
sign = RK730_DADC_SR_ACL_VOLL_POS | RK730_DADC_SR_ACL_VOLR_POS;
|
||||
uv = uv - mid;
|
||||
} else {
|
||||
sign = RK730_DADC_SR_ACL_VOLL_NEG | RK730_DADC_SR_ACL_VOLR_NEG;
|
||||
uv = mid - uv;
|
||||
}
|
||||
|
||||
val = ((uv + min) & mask);
|
||||
val_mask = mask << shift;
|
||||
val = val << shift;
|
||||
|
||||
snd_soc_component_update_bits(component, reg, val_mask, val);
|
||||
snd_soc_component_update_bits(component, rreg, val_mask, val);
|
||||
snd_soc_component_update_bits(component, RK730_DADC_SR_ACL, sign_mask, sign);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rk730_dac_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
unsigned int val = snd_soc_component_read(component, mc->reg);
|
||||
unsigned int sign = snd_soc_component_read(component, RK730_DDAC_SR_LMT);
|
||||
unsigned int mask = (1 << fls(mc->max)) - 1;
|
||||
unsigned int shift = mc->shift;
|
||||
int mid = mc->max / 2;
|
||||
int uv;
|
||||
|
||||
uv = (val >> shift) & mask;
|
||||
sign &= RK730_DDAC_SR_LMT_VOLL_POL_MASK;
|
||||
if (sign)
|
||||
uv = mid + uv;
|
||||
else
|
||||
uv = mid - uv;
|
||||
|
||||
ucontrol->value.integer.value[0] = uv;
|
||||
ucontrol->value.integer.value[1] = uv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_dac_vol_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
unsigned int reg = mc->reg;
|
||||
unsigned int rreg = mc->rreg;
|
||||
unsigned int shift = mc->shift;
|
||||
unsigned int mask = (1 << fls(mc->max)) - 1;
|
||||
unsigned int val, val_mask, sign, sign_mask;
|
||||
int uv = ucontrol->value.integer.value[0];
|
||||
int min = mc->min;
|
||||
int mid = mc->max / 2;
|
||||
|
||||
sign_mask = RK730_DDAC_SR_LMT_VOLL_POL_MASK | RK730_DDAC_SR_LMT_VOLR_POL_MASK;
|
||||
|
||||
if (uv > mid) {
|
||||
sign = RK730_DDAC_SR_LMT_VOLL_POS | RK730_DDAC_SR_LMT_VOLR_POS;
|
||||
uv = uv - mid;
|
||||
} else {
|
||||
sign = RK730_DDAC_SR_LMT_VOLL_NEG | RK730_DDAC_SR_LMT_VOLR_NEG;
|
||||
uv = mid - uv;
|
||||
}
|
||||
|
||||
val = ((uv + min) & mask);
|
||||
val_mask = mask << shift;
|
||||
val = val << shift;
|
||||
|
||||
snd_soc_component_update_bits(component, reg, val_mask, val);
|
||||
snd_soc_component_update_bits(component, rreg, val_mask, val);
|
||||
snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT, sign_mask, sign);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rk730_cp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||
usleep_range(5000, 5100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_pll_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||
snd_soc_component_write(component, RK730_SYSPLL_0, 0x00);
|
||||
else
|
||||
snd_soc_component_write(component, RK730_SYSPLL_0, 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_adc_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
snd_soc_component_update_bits(component, RK730_ADC_0,
|
||||
RK730_ADC_0_DEM_EN_MASK,
|
||||
RK730_ADC_0_DEM_EN);
|
||||
snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK,
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN |
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_EN |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_EN);
|
||||
usleep_range(20000, 21000);
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD,
|
||||
RK730_DI2S_TXCR_3_TXCMD_TXS_MASK,
|
||||
RK730_DI2S_TXCR_3_TXCMD_TXS_EN);
|
||||
} else {
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD,
|
||||
RK730_DI2S_TXCR_3_TXCMD_TXS_MASK,
|
||||
RK730_DI2S_TXCR_3_TXCMD_TXS_DIS);
|
||||
snd_soc_component_update_bits(component, RK730_ADC_0,
|
||||
RK730_ADC_0_DEM_EN_MASK,
|
||||
RK730_ADC_0_DEM_DIS);
|
||||
snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK,
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS |
|
||||
RK730_DTOP_DIGEN_CLKE_ADC_DIS |
|
||||
RK730_DTOP_DIGEN_CLKE_I2STX_DIS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_dac_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK,
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN |
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_EN |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_EN);
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD,
|
||||
RK730_DI2S_RXCMD_TSD_RXS_MASK,
|
||||
RK730_DI2S_RXCMD_TSD_RXS_EN);
|
||||
} else {
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD,
|
||||
RK730_DI2S_RXCMD_TSD_RXS_MASK,
|
||||
RK730_DI2S_RXCMD_TSD_RXS_DIS);
|
||||
snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE,
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK,
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS |
|
||||
RK730_DTOP_DIGEN_CLKE_DAC_DIS |
|
||||
RK730_DTOP_DIGEN_CLKE_I2SRX_DIS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_mux_out_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
|
||||
unsigned int val;
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||
val = atomic_inc_return(&rk730->mix_mode);
|
||||
else
|
||||
val = atomic_dec_return(&rk730->mix_mode);
|
||||
|
||||
snd_soc_component_update_bits(component, RK730_MIXER_2,
|
||||
RK730_MIXER_2_MIX_R_MODE_MASK |
|
||||
RK730_MIXER_2_MIX_L_MODE_MASK,
|
||||
RK730_MIXER_2_MIX_R_MODE(val) |
|
||||
RK730_MIXER_2_MIX_L_MODE(val));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new rk730_snd_controls[] = {
|
||||
SOC_DOUBLE_R_TLV("ADC Volume", RK730_ADC_PGA_BLOCK_0, RK730_ADC_PGA_BLOCK_1,
|
||||
1, 0x7, 1, adc_tlv),
|
||||
SOC_DOUBLE_R_TLV("D2S Volume", RK730_DAC_1, RK730_DAC_2,
|
||||
1, 0x6, 1, d2s_tlv),
|
||||
|
||||
SOC_DOUBLE_R_TLV("MIC1 Boost Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1,
|
||||
1, 0x18, 0, micboost_tlv),
|
||||
SOC_DOUBLE_R_TLV("MIC2 Boost Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3,
|
||||
1, 0x18, 0, micboost_tlv),
|
||||
|
||||
SOC_DOUBLE_TLV("Out Mux Volume", RK730_MUXER_0, 1, 5, 0x1, 0, mux_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Left Out Mux -> Left Out Mixer Volume",
|
||||
RK730_MIXER_0, 1, 0x6, 1, mix_buf_tlv),
|
||||
SOC_SINGLE_TLV("Left Out Mux -> Right Out Mixer Volume",
|
||||
RK730_MIXER_0, 5, 0x6, 1, mix_buf_tlv),
|
||||
SOC_SINGLE_TLV("Right Out Mux -> Left Out Mixer Volume",
|
||||
RK730_MIXER_1, 1, 0x6, 1, mix_buf_tlv),
|
||||
SOC_SINGLE_TLV("Right Out Mux -> Right Out Mixer Volume",
|
||||
RK730_MIXER_1, 5, 0x6, 1, mix_buf_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("HP Volume", RK730_HP_0, 6, 0x3, 0, hp_tlv),
|
||||
SOC_SINGLE_TLV("Line Out Volume", RK730_LINEOUT_1, 2, 0x3, 0, lineout_tlv),
|
||||
|
||||
SOC_DOUBLE_R_EXT_TLV("ADC Digital Volume",
|
||||
RK730_DADC_VOLL, RK730_DADC_VOLR, 0, 0x1fe, 0,
|
||||
rk730_adc_vol_get,
|
||||
rk730_adc_vol_put,
|
||||
adc_dig_tlv),
|
||||
SOC_DOUBLE_R_EXT_TLV("DAC Digital Volume",
|
||||
RK730_DDAC_VOLL, RK730_DDAC_VOLR, 0, 0x1fe, 0,
|
||||
rk730_dac_vol_get,
|
||||
rk730_dac_vol_put,
|
||||
dac_dig_tlv),
|
||||
|
||||
SOC_ENUM("ADC HPF Cutoff", adc_hpf_cutoff_enum),
|
||||
SOC_ENUM("DAC HPF Cutoff", dac_hpf_cutoff_enum),
|
||||
SOC_ENUM("DAC Ref Buf Chop Freq", dac_ref_buf_chop_freq_enum),
|
||||
SOC_ENUM("MIC Chop Freq", mic_chop_freq_enum),
|
||||
SOC_ENUM("ADC PGA Chop Freq", adc_pga_chop_freq_enum),
|
||||
SOC_ENUM("Out Mux Chop Freq", mux_out_chop_freq_enum),
|
||||
SOC_ENUM("Mixer Chop Freq", mix_chop_freq_enum),
|
||||
SOC_ENUM("HP / Lineout Chop Freq", hp_lo_chop_freq_enum),
|
||||
SOC_ENUM("Mic Bias Volt", micbias_volt_enum),
|
||||
SOC_ENUM("Charge Pump Volt", charge_pump_volt_enum),
|
||||
|
||||
SOC_SINGLE("ADCL HPF Switch", RK730_DADC_HPF, 7, 1, 0),
|
||||
SOC_SINGLE("ADCR HPF Switch", RK730_DADC_HPF, 6, 1, 0),
|
||||
SOC_SINGLE("DAC HPF Switch", RK730_DDAC_MUTE_MIXCTL, 7, 1, 0),
|
||||
SOC_SINGLE("ADC Volume Bypass Switch", RK730_DTOP_VUCTL, 7, 1, 0),
|
||||
SOC_SINGLE("DAC Volume Bypass Switch", RK730_DTOP_VUCTL, 6, 1, 0),
|
||||
SOC_SINGLE("ADC Fade Switch", RK730_DTOP_VUCTL, 5, 1, 0),
|
||||
SOC_SINGLE("DAC Fade Switch", RK730_DTOP_VUCTL, 4, 1, 0),
|
||||
SOC_SINGLE("ADC Zero Crossing Switch", RK730_DTOP_VUCTL, 1, 1, 0),
|
||||
SOC_SINGLE("DAC Zero Crossing Switch", RK730_DTOP_VUCTL, 0, 1, 0),
|
||||
SOC_SINGLE("MIC1N / MIC2P Exchanged Switch", RK730_MIC_BOOST_2, 7, 1, 0),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget rk730_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SUPPLY_S("ANA LDO", 0, RK730_LDO, 7, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("OSC CLK", 1, RK730_HK_TOP_2, 4, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("VAG BUF", 1, RK730_HK_TOP_2, 2, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("ADC BUF", 1, RK730_HK_TOP_2, 1, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC BUF", 1, RK730_HK_TOP_2, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("MICBIAS", 1, RK730_MIC_BIAS, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RK730_CHARGE_PUMP, 0, 0,
|
||||
rk730_cp_event, SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_SUPPLY_S("PLL", 2, SND_SOC_NOPM, 0, 0, rk730_pll_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC Bias", 2, RK730_DAC_0, 2, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("HP Bias", 2, RK730_HP_0, 5, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("Line Out Bias", 2, RK730_LINEOUT_1, 7, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_ADC_E("ADCL", "HiFi Capture", RK730_ADC_0, 0, 1,
|
||||
rk730_adc_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_ADC_E("ADCR", "HiFi Capture", RK730_ADC_0, 1, 1,
|
||||
rk730_adc_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_DAC_E("DACL", "HiFi Playback", RK730_DAC_0, 0, 1,
|
||||
rk730_dac_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_DAC_E("DACR", "HiFi Playback", RK730_DAC_0, 1, 1,
|
||||
rk730_dac_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_PGA("ADCL PGA", RK730_ADC_PGA_BLOCK_0, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("ADCR PGA", RK730_ADC_PGA_BLOCK_1, 0, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("D2SL", RK730_DAC_1, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("D2SR", RK730_DAC_2, 0, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("MIC1P", RK730_MIC_BOOST_0, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("MIC1N", RK730_MIC_BOOST_1, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("MIC2P", RK730_MIC_BOOST_2, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("MIC2N", RK730_MIC_BOOST_3, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("DIFFL", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("DIFFR", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("HP Out", RK730_HP_0, 2, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("HP Out Stage", RK730_HP_0, 3, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Line Out", RK730_LINEOUT_0, 2, 1, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Line Out Stage", RK730_LINEOUT_0, 3, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_MUX_E("Left Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_l,
|
||||
rk730_mux_out_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_MUX_E("Right Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_r,
|
||||
rk730_mux_out_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_l),
|
||||
SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_r),
|
||||
|
||||
SND_SOC_DAPM_MIXER("Left Out Mixer", RK730_MIXER_2, 0, 1,
|
||||
mix_ctls, ARRAY_SIZE(mix_ctls)),
|
||||
SND_SOC_DAPM_MIXER("Right Out Mixer", RK730_MIXER_2, 3, 1,
|
||||
mix_ctls, ARRAY_SIZE(mix_ctls)),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("HPL"),
|
||||
SND_SOC_DAPM_OUTPUT("HPR"),
|
||||
SND_SOC_DAPM_OUTPUT("LINEOUTL"),
|
||||
SND_SOC_DAPM_OUTPUT("LINEOUTR"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("MIC1"),
|
||||
SND_SOC_DAPM_INPUT("MIC2"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rk730_dapm_routes[] = {
|
||||
{ "DACL", NULL, "ANA LDO" },
|
||||
{ "DACR", NULL, "ANA LDO" },
|
||||
{ "DACL", NULL, "OSC CLK" },
|
||||
{ "DACR", NULL, "OSC CLK" },
|
||||
{ "DACL", NULL, "VAG BUF" },
|
||||
{ "DACR", NULL, "VAG BUF" },
|
||||
{ "DACL", NULL, "DAC BUF" },
|
||||
{ "DACR", NULL, "DAC BUF" },
|
||||
{ "DACL", NULL, "PLL" },
|
||||
{ "DACR", NULL, "PLL" },
|
||||
{ "DACL", NULL, "DAC Bias" },
|
||||
{ "DACR", NULL, "DAC Bias" },
|
||||
|
||||
{ "D2SL", NULL, "DACL" },
|
||||
{ "D2SR", NULL, "DACR" },
|
||||
|
||||
{ "Left Out Mixer", NULL, "D2SL" },
|
||||
{ "Left Out Mixer", "Left Out Mux Switch", "Left Out Mux" },
|
||||
{ "Left Out Mixer", "Right Out Mux Switch", "Right Out Mux" },
|
||||
{ "Right Out Mixer", NULL, "D2SR" },
|
||||
{ "Right Out Mixer", "Left Out Mux Switch", "Left Out Mux" },
|
||||
{ "Right Out Mixer", "Right Out Mux Switch", "Right Out Mux" },
|
||||
|
||||
{ "Left Out Mux", "DIFF", "DIFFL" },
|
||||
{ "Left Out Mux", "MIC1N", "MIC1N" },
|
||||
{ "Left Out Mux", "MIC2N", "MIC2N" },
|
||||
|
||||
{ "Right Out Mux", "DIFF", "DIFFR" },
|
||||
{ "Right Out Mux", "MIC1P", "MIC1P" },
|
||||
{ "Right Out Mux", "MIC2P", "MIC2P" },
|
||||
|
||||
{ "HP Out", NULL, "HP Bias" },
|
||||
{ "HP Out", NULL, "HP Bias" },
|
||||
{ "Line Out", NULL, "Line Out Bias" },
|
||||
|
||||
{ "HP Out", NULL, "Left Out Mixer" },
|
||||
{ "HP Out", NULL, "Right Out Mixer" },
|
||||
{ "Line Out", NULL, "Left Out Mixer" },
|
||||
{ "Line Out", NULL, "Right Out Mixer" },
|
||||
|
||||
{ "HP Out Stage", NULL, "HP Out" },
|
||||
{ "Line Out Stage", NULL, "Line Out" },
|
||||
|
||||
{ "HPL", NULL, "HP Out Stage" },
|
||||
{ "HPR", NULL, "HP Out Stage" },
|
||||
{ "HPL", NULL, "Charge Pump" },
|
||||
{ "HPR", NULL, "Charge Pump" },
|
||||
|
||||
{ "LINEOUTL", NULL, "Line Out Stage" },
|
||||
{ "LINEOUTR", NULL, "Line Out Stage" },
|
||||
{ "LINEOUTL", NULL, "Charge Pump" },
|
||||
{ "LINEOUTR", NULL, "Charge Pump" },
|
||||
|
||||
{ "ADCL", NULL, "ANA LDO" },
|
||||
{ "ADCR", NULL, "ANA LDO" },
|
||||
{ "ADCL", NULL, "OSC CLK" },
|
||||
{ "ADCR", NULL, "OSC CLK" },
|
||||
{ "ADCL", NULL, "ADC BUF" },
|
||||
{ "ADCR", NULL, "ADC BUF" },
|
||||
{ "ADCL", NULL, "VAG BUF" },
|
||||
{ "ADCR", NULL, "VAG BUF" },
|
||||
{ "ADCL", NULL, "PLL" },
|
||||
{ "ADCR", NULL, "PLL" },
|
||||
|
||||
{ "ADCL", NULL, "ADCL PGA" },
|
||||
{ "ADCR", NULL, "ADCR PGA" },
|
||||
{ "ADCL PGA", NULL, "Left Input Mux" },
|
||||
{ "ADCR PGA", NULL, "Right Input Mux" },
|
||||
|
||||
{ "Left Input Mux", "DIFF", "DIFFL" },
|
||||
{ "Left Input Mux", "VINP1", "MIC1P" },
|
||||
{ "Left Input Mux", "VINN1", "MIC1N" },
|
||||
{ "Right Input Mux", "DIFF", "DIFFR" },
|
||||
{ "Right Input Mux", "VINP2", "MIC2P" },
|
||||
{ "Right Input Mux", "VINN2", "MIC2N" },
|
||||
|
||||
{ "DIFFL", NULL, "MIC1P" },
|
||||
{ "DIFFL", NULL, "MIC1N" },
|
||||
{ "DIFFR", NULL, "MIC2P" },
|
||||
{ "DIFFR", NULL, "MIC2N" },
|
||||
|
||||
{ "MIC1P", NULL, "MIC1" },
|
||||
{ "MIC1N", NULL, "MIC1" },
|
||||
{ "MIC2P", NULL, "MIC2" },
|
||||
{ "MIC2N", NULL, "MIC2" },
|
||||
|
||||
{ "MIC1", NULL, "MICBIAS" },
|
||||
{ "MIC2", NULL, "MICBIAS" },
|
||||
};
|
||||
|
||||
static unsigned int samplerate_to_bit(unsigned int samplerate)
|
||||
{
|
||||
switch (samplerate) {
|
||||
case 8000:
|
||||
case 11025:
|
||||
case 12000:
|
||||
return 0;
|
||||
case 16000:
|
||||
case 22050:
|
||||
case 24000:
|
||||
return 1;
|
||||
case 32000:
|
||||
case 44100:
|
||||
case 48000:
|
||||
return 2;
|
||||
case 64000:
|
||||
case 88200:
|
||||
case 96000:
|
||||
return 3;
|
||||
case 128000:
|
||||
case 176400:
|
||||
case 192000:
|
||||
return 4;
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int rk730_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
unsigned int width, rate;
|
||||
|
||||
width = min(params_width(params), 24);
|
||||
rate = samplerate_to_bit(params_rate(params));
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_RXCR_2,
|
||||
RK730_DI2S_XCR2_VDW_MASK,
|
||||
RK730_DI2S_XCR2_VDW(width));
|
||||
snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT,
|
||||
RK730_DDAC_SR_LMT_SRT_MASK,
|
||||
RK730_DDAC_SR_LMT_SRT(rate));
|
||||
} else {
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_TXCR_2,
|
||||
RK730_DI2S_XCR2_VDW_MASK,
|
||||
RK730_DI2S_XCR2_VDW(width));
|
||||
snd_soc_component_update_bits(component, RK730_DADC_SR_ACL,
|
||||
RK730_DADC_SR_ACL_SRT_MASK,
|
||||
RK730_DADC_SR_ACL_SRT(rate));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_CKM,
|
||||
RK730_DI2S_CKM_MST_MASK,
|
||||
RK730_DI2S_CKM_MST_SLAVE);
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
snd_soc_component_update_bits(component, RK730_DI2S_CKM,
|
||||
RK730_DI2S_CKM_MST_MASK,
|
||||
RK730_DI2S_CKM_MST_MASTER);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_dai_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
|
||||
{
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
|
||||
if (mute)
|
||||
snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL,
|
||||
RK730_DDAC_MUTE_MIXCTL_MUTE_MASK,
|
||||
RK730_DDAC_MUTE_MIXCTL_MUTE);
|
||||
else
|
||||
snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL,
|
||||
RK730_DDAC_MUTE_MIXCTL_MUTE_MASK,
|
||||
RK730_DDAC_MUTE_MIXCTL_UNMUTE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_set_bias_level(struct snd_soc_component *component,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/*
|
||||
* SND_SOC_BIAS_PREPARE is called while preparing for a
|
||||
* transition to ON or away from ON. If current bias_level
|
||||
* is SND_SOC_BIAS_ON, then it is preparing for a transition
|
||||
* away from ON. Disable the clock in that case, otherwise
|
||||
* enable it.
|
||||
*/
|
||||
if (!IS_ERR(rk730->mclk)) {
|
||||
if (snd_soc_component_get_bias_level(component) ==
|
||||
SND_SOC_BIAS_ON)
|
||||
clk_disable_unprepare(rk730->mclk);
|
||||
else
|
||||
clk_prepare_enable(rk730->mclk);
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
|
||||
regcache_sync(rk730->regmap);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_OFF:
|
||||
regcache_mark_dirty(rk730->regmap);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RK730_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define RK730_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
static const struct snd_soc_dai_ops rk730_dai_ops = {
|
||||
.set_fmt = rk730_dai_set_fmt,
|
||||
.hw_params = rk730_dai_hw_params,
|
||||
.mute_stream = rk730_dai_mute,
|
||||
.no_capture_mute = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver rk730_dai = {
|
||||
.name = "HiFi",
|
||||
.playback = {
|
||||
.stream_name = "HiFi Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = RK730_RATES,
|
||||
.formats = RK730_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "HiFi Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = RK730_RATES,
|
||||
.formats = RK730_FORMATS,
|
||||
},
|
||||
.ops = &rk730_dai_ops,
|
||||
};
|
||||
|
||||
static int rk730_reset(struct snd_soc_component *component)
|
||||
{
|
||||
struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
clk_prepare_enable(rk730->mclk);
|
||||
snd_soc_component_write(component, RK730_DTOP_LPT_SRST, 0x40);
|
||||
udelay(10);
|
||||
/* WA: Initial micbias default, ADC stopped with micbias(>2.5v) */
|
||||
snd_soc_component_update_bits(component, RK730_MIC_BIAS,
|
||||
RK730_MIC_BIAS_VOLT_MASK,
|
||||
RK730_MIC_BIAS_VOLT_2_2V);
|
||||
/* PF: Use the maximum bias current for better performance */
|
||||
snd_soc_component_update_bits(component, RK730_HK_TOP_1,
|
||||
RK730_HK_TOP_1_IBIAS_STD_SEL_MASK |
|
||||
RK730_HK_TOP_1_IBIAS_GAIN_SEL_MASK,
|
||||
RK730_HK_TOP_1_IBIAS_STD_SEL_27_5UA |
|
||||
RK730_HK_TOP_1_IBIAS_GAIN_SEL_200);
|
||||
/* PF: Use the chop 400kHz for better ADC noise performance */
|
||||
snd_soc_component_update_bits(component, RK730_MIC_BOOST_3,
|
||||
RK730_MIC_BOOST_3_MIC_CHOP_MASK,
|
||||
RK730_MIC_BOOST_3_MIC_CHOP(RK730_CHOP_FREQ_400KHZ));
|
||||
snd_soc_component_update_bits(component, RK730_ADC_PGA_BLOCK_1,
|
||||
RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK,
|
||||
RK730_ADC_PGA_BLOCK_1_PGA_CHOP(RK730_CHOP_FREQ_400KHZ));
|
||||
|
||||
clk_disable_unprepare(rk730->mclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk730_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component);
|
||||
int ret = 0;
|
||||
|
||||
regcache_mark_dirty(rk730->regmap);
|
||||
|
||||
/* initialize private data */
|
||||
atomic_set(&rk730->mix_mode, RK730_MIX_MODE_1_PATH);
|
||||
|
||||
ret = snd_soc_component_read(component, RK730_HK_TOP_0);
|
||||
if (ret < 0) {
|
||||
dev_err(component->dev, "Failed to read register: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rk730_reset(component);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver rk730_component_driver = {
|
||||
.probe = rk730_probe,
|
||||
.set_bias_level = rk730_set_bias_level,
|
||||
.controls = rk730_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(rk730_snd_controls),
|
||||
.dapm_widgets = rk730_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(rk730_dapm_widgets),
|
||||
.dapm_routes = rk730_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(rk730_dapm_routes),
|
||||
.suspend_bias_off = 1,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct reg_default rk730_reg_defaults[] = {
|
||||
{ 0x00, 0x40 },
|
||||
{ 0x02, 0x17 },
|
||||
{ 0x05, 0x03 },
|
||||
{ 0x06, 0x22 },
|
||||
{ 0x07, 0x02 },
|
||||
{ 0x08, 0x07 },
|
||||
{ 0x09, 0x01 },
|
||||
{ 0x0a, 0x01 },
|
||||
{ 0x0b, 0x01 },
|
||||
{ 0x0c, 0x01 },
|
||||
{ 0x0d, 0x01 },
|
||||
{ 0x0e, 0x01 },
|
||||
{ 0x0f, 0x07 },
|
||||
{ 0x10, 0x07 },
|
||||
{ 0x11, 0xff },
|
||||
{ 0x12, 0x07 },
|
||||
{ 0x13, 0x54 },
|
||||
{ 0x14, 0x04 },
|
||||
{ 0x15, 0x23 },
|
||||
{ 0x16, 0x35 },
|
||||
{ 0x17, 0x67 },
|
||||
{ 0x18, 0x1e },
|
||||
{ 0x19, 0xc0 },
|
||||
{ 0x1a, 0x13 },
|
||||
{ 0x1b, 0x04 },
|
||||
{ 0x1c, 0x20 },
|
||||
{ 0x1f, 0x90 },
|
||||
{ 0x20, 0x11 },
|
||||
{ 0x21, 0x09 },
|
||||
{ 0x22, 0x33 },
|
||||
{ 0x24, 0x11 },
|
||||
{ 0x25, 0x11 },
|
||||
{ 0x26, 0x09 },
|
||||
{ 0x27, 0x02 },
|
||||
{ 0x28, 0x2c },
|
||||
{ 0x2a, 0x0c },
|
||||
{ 0x2b, 0x80 },
|
||||
{ 0x40, 0x03 },
|
||||
{ 0x42, 0x20 },
|
||||
{ 0x47, 0xe6 },
|
||||
{ 0x48, 0xd0 },
|
||||
{ 0x49, 0x17 },
|
||||
{ 0x4a, 0x26 },
|
||||
{ 0x4b, 0x01 },
|
||||
{ 0x4c, 0x05 },
|
||||
{ 0x4d, 0x0e },
|
||||
{ 0x4e, 0x09 },
|
||||
{ 0x4f, 0x02 },
|
||||
{ 0x5b, 0xe6 },
|
||||
{ 0x5c, 0xd0 },
|
||||
{ 0x5d, 0x17 },
|
||||
{ 0x5e, 0x26 },
|
||||
{ 0x5f, 0x01 },
|
||||
{ 0x60, 0x05 },
|
||||
{ 0x61, 0x0e },
|
||||
{ 0x62, 0x09 },
|
||||
{ 0x63, 0x20 },
|
||||
{ 0x66, 0x01 },
|
||||
{ 0x69, 0x17 },
|
||||
{ 0x6c, 0x17 },
|
||||
};
|
||||
|
||||
static bool rk730_volatile_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case RK730_DTOP_LPT_SRST:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config rk730_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.volatile_reg = rk730_volatile_register,
|
||||
.max_register = RK730_DAC_ATTN,
|
||||
.reg_defaults = rk730_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(rk730_reg_defaults),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int rk730_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct rk730_priv *rk730;
|
||||
int ret;
|
||||
|
||||
rk730 = devm_kzalloc(&i2c->dev, sizeof(struct rk730_priv), GFP_KERNEL);
|
||||
if (!rk730)
|
||||
return -ENOMEM;
|
||||
|
||||
rk730->regmap = devm_regmap_init_i2c(i2c, &rk730_regmap);
|
||||
if (IS_ERR(rk730->regmap))
|
||||
return PTR_ERR(rk730->regmap);
|
||||
|
||||
rk730->mclk = devm_clk_get(&i2c->dev, "mclk");
|
||||
if (IS_ERR(rk730->mclk))
|
||||
return PTR_ERR(rk730->mclk);
|
||||
|
||||
i2c_set_clientdata(i2c, rk730);
|
||||
|
||||
ret = devm_snd_soc_register_component(&i2c->dev,
|
||||
&rk730_component_driver, &rk730_dai, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rk730_i2c_id[] = {
|
||||
{ "rk730", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rk730_i2c_id);
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static const struct of_device_id rk730_of_match[] = {
|
||||
{ .compatible = "rockchip,rk730" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rk730_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver rk730_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rk730",
|
||||
.of_match_table = of_match_ptr(rk730_of_match),
|
||||
},
|
||||
.probe = rk730_i2c_probe,
|
||||
.id_table = rk730_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(rk730_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC RK730 driver");
|
||||
MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
239
sound/soc/codecs/rk730.h
Normal file
239
sound/soc/codecs/rk730.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* rk730.h -- RK730 ALSA SoC Audio driver
|
||||
*
|
||||
* Copyright (C) 2022 Rockchip Electronics Co.,Ltd
|
||||
*/
|
||||
|
||||
#ifndef _RK730_H
|
||||
#define _RK730_H
|
||||
|
||||
/* RK730 Analog Registers Definition */
|
||||
#define RK730_HK_TOP_0 0x00
|
||||
#define RK730_HK_TOP_1 0x01
|
||||
#define RK730_HK_TOP_2 0x02
|
||||
#define RK730_HK_TRIM_0 0x03
|
||||
#define RK730_HK_TRIM_1 0x04
|
||||
#define RK730_ADC_0 0x05
|
||||
#define RK730_ADC_1 0x06
|
||||
#define RK730_ADC_2 0x07
|
||||
#define RK730_DAC_0 0x08
|
||||
#define RK730_DAC_1 0x09
|
||||
#define RK730_DAC_2 0x0a
|
||||
#define RK730_MIC_BOOST_0 0x0b
|
||||
#define RK730_MIC_BOOST_1 0x0c
|
||||
#define RK730_MIC_BOOST_2 0x0d
|
||||
#define RK730_MIC_BOOST_3 0x0e
|
||||
#define RK730_ADC_PGA_BLOCK_0 0x0f
|
||||
#define RK730_ADC_PGA_BLOCK_1 0x10
|
||||
#define RK730_SYSPLL_0 0x11
|
||||
#define RK730_SYSPLL_1 0x12
|
||||
#define RK730_SYSPLL_2 0x13
|
||||
#define RK730_SYSPLL_3 0x14
|
||||
#define RK730_SYSPLL_LOOP_0 0x15
|
||||
#define RK730_SYSPLL_LOOP_1 0x16
|
||||
#define RK730_SYSPLL_LOOP_2 0x17
|
||||
#define RK730_SYSPLL_LOOP_3 0x18
|
||||
#define RK730_SYSPLL_RVCO_0 0x19
|
||||
#define RK730_SYSPLL_RVCO_1 0x1a
|
||||
#define RK730_SYSPLL_RVCO_2 0x1b
|
||||
#define RK730_SYSPLL_RVCO_3 0x1c
|
||||
#define RK730_SYSPLL_FRACT_0 0x1d
|
||||
#define RK730_SYSPLL_FRACT_1 0x1e
|
||||
#define RK730_SYSPLL_FRACT_2 0x1f
|
||||
#define RK730_LDO 0x20
|
||||
#define RK730_MIC_BIAS 0x21
|
||||
#define RK730_MUXER_0 0x22
|
||||
#define RK730_MUXER_1 0x23
|
||||
#define RK730_MIXER_0 0x24
|
||||
#define RK730_MIXER_1 0x25
|
||||
#define RK730_MIXER_2 0x26
|
||||
#define RK730_CHARGE_PUMP 0x27
|
||||
#define RK730_HP_0 0x28
|
||||
#define RK730_HP_1 0x29
|
||||
#define RK730_LINEOUT_0 0x2a
|
||||
#define RK730_LINEOUT_1 0x2b
|
||||
|
||||
/* RK730 Digital Registers Definition */
|
||||
#define RK730_DTOP_VUCTL 0x40
|
||||
#define RK730_DTOP_VUCTIME 0x41
|
||||
#define RK730_DTOP_LPT_SRST 0x42
|
||||
#define RK730_DTOP_DIGEN_CLKE 0x43
|
||||
#define RK730_DADC_VOLL 0x44
|
||||
#define RK730_DADC_VOLR 0x45
|
||||
#define RK730_DADC_SR_ACL 0x46
|
||||
#define RK730_DADC_PR_0 0x47
|
||||
#define RK730_DADC_PR_1 0x48
|
||||
#define RK730_DADC_PR_2 0x49
|
||||
#define RK730_DADC_PR_3 0x4a
|
||||
#define RK730_DADC_NG_0 0x4b
|
||||
#define RK730_DADC_NG_1 0x4c
|
||||
#define RK730_DADC_NG_2 0x4d
|
||||
#define RK730_DADC_NG_3 0x4e
|
||||
#define RK730_DADC_CICCOMP 0x4f
|
||||
#define RK730_DADC_HPF 0x50
|
||||
#define RK730_DADC_RVOLL 0x51
|
||||
#define RK730_DADC_RVOLR 0x52
|
||||
#define RK730_DMIC_LMT_1 0x53
|
||||
#define RK730_DMIC_LMT_2 0x54
|
||||
#define RK730_DMIC_NG_1 0x55
|
||||
#define RK730_DMIC_NG_2 0x56
|
||||
#define RK730_DDAC_POPD_DACST 0x57
|
||||
#define RK730_DDAC_VOLL 0x58
|
||||
#define RK730_DDAC_VOLR 0x59
|
||||
#define RK730_DDAC_SR_LMT 0x5a
|
||||
#define RK730_DDAC_PR_0 0x5b
|
||||
#define RK730_DDAC_PR_1 0x5c
|
||||
#define RK730_DDAC_PR_2 0x5d
|
||||
#define RK730_DDAC_PR_3 0x5e
|
||||
#define RK730_DDAC_NG_0 0x5f
|
||||
#define RK730_DDAC_NG_1 0x60
|
||||
#define RK730_DDAC_NG_2 0x61
|
||||
#define RK730_DDAC_NG_3 0x62
|
||||
#define RK730_DDAC_MUTE_MIXCTL 0x63
|
||||
#define RK730_DDAC_RVOLL 0x64
|
||||
#define RK730_DDAC_RVOLR 0x65
|
||||
#define RK730_DI2S_CKM 0x66
|
||||
#define RK730_DI2S_RSD 0x67
|
||||
#define RK730_DI2S_RXCR_1 0x68
|
||||
#define RK730_DI2S_RXCR_2 0x69
|
||||
#define RK730_DI2S_RXCMD_TSD 0x6a
|
||||
#define RK730_DI2S_TXCR_1 0x6b
|
||||
#define RK730_DI2S_TXCR_2 0x6c
|
||||
#define RK730_DI2S_TXCR_3_TXCMD 0x6d
|
||||
#define RK730_DAC_ATTN 0x6e
|
||||
|
||||
/* RK730_HK_TOP_1 */
|
||||
#define RK730_HK_TOP_1_DAC_REF_BUF_CHOP_MASK GENMASK(7, 6)
|
||||
#define RK730_HK_TOP_1_DAC_REF_BUF_CHOP(x) ((x) << 6)
|
||||
#define RK730_HK_TOP_1_IBIAS_STD_SEL_MASK GENMASK(5, 4)
|
||||
#define RK730_HK_TOP_1_IBIAS_STD_SEL_27_5UA (3 << 4)
|
||||
#define RK730_HK_TOP_1_IBIAS_STD_SEL_23_5UA (2 << 4)
|
||||
#define RK730_HK_TOP_1_IBIAS_STD_SEL_20UA (1 << 4)
|
||||
#define RK730_HK_TOP_1_IBIAS_STD_SEL_16_5UA (0 << 4)
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_MASK GENMASK(3, 0)
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_200 8
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_143 9
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_120 10
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_100 0
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_71_5 1
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_62_5 2
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_50 3
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_38_2 6
|
||||
#define RK730_HK_TOP_1_IBIAS_GAIN_SEL_32 7
|
||||
|
||||
/* RK730_ADC_0 */
|
||||
#define RK730_ADC_0_DEM_EN_MASK BIT(3)
|
||||
#define RK730_ADC_0_DEM_EN BIT(3)
|
||||
#define RK730_ADC_0_DEM_DIS 0
|
||||
|
||||
/* RK730_MIC_BOOST_3 */
|
||||
#define RK730_MIC_BOOST_3_MIC_CHOP_MASK GENMASK(7, 6)
|
||||
#define RK730_MIC_BOOST_3_MIC_CHOP(x) ((x) << 6)
|
||||
|
||||
/* RK730_ADC_PGA_BLOCK_1 */
|
||||
#define RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK GENMASK(7, 6)
|
||||
#define RK730_ADC_PGA_BLOCK_1_PGA_CHOP(x) ((x) << 6)
|
||||
|
||||
/* RK730_MIC_BIAS */
|
||||
#define RK730_MIC_BIAS_VOLT_MASK GENMASK(3, 2)
|
||||
#define RK730_MIC_BIAS_VOLT_2_8V (3 << 2)
|
||||
#define RK730_MIC_BIAS_VOLT_2_5V (2 << 2)
|
||||
#define RK730_MIC_BIAS_VOLT_2_2V (1 << 2)
|
||||
#define RK730_MIC_BIAS_VOLT_2_0V (0 << 2)
|
||||
|
||||
/* RK730_MUXER_1 */
|
||||
#define RK730_MUXER_1_MUX_OUT_CHOP_MASK GENMASK(1, 0)
|
||||
#define RK730_MUXER_1_MUX_OUT_CHOP(x) ((x) << 0)
|
||||
|
||||
/* RK730_MIXER_2 */
|
||||
#define RK730_MIXER_2_MIX_CHOP_MASK GENMASK(7, 6)
|
||||
#define RK730_MIXER_2_MIX_CHOP(x) ((x) << 6)
|
||||
#define RK730_MIXER_2_MIX_R_MODE_MASK GENMASK(5, 4)
|
||||
#define RK730_MIXER_2_MIX_R_MODE(x) ((x) << 4)
|
||||
#define RK730_MIXER_2_MIX_L_MODE_MASK GENMASK(2, 1)
|
||||
#define RK730_MIXER_2_MIX_L_MODE(x) ((x) << 1)
|
||||
|
||||
/* RK730_HP_1 */
|
||||
#define RK730_HP_1_HP_LO_CHOP_MASK GENMASK(6, 5)
|
||||
#define RK730_HP_1_HP_LO_CHOP(x) ((x) << 5)
|
||||
|
||||
/* RK730_DTOP_DIGEN_CLKE */
|
||||
#define RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK BIT(7)
|
||||
#define RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN BIT(7)
|
||||
#define RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK BIT(6)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN BIT(6)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK BIT(5)
|
||||
#define RK730_DTOP_DIGEN_CLKE_ADC_EN BIT(5)
|
||||
#define RK730_DTOP_DIGEN_CLKE_ADC_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK BIT(4)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2STX_EN BIT(4)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2STX_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK BIT(3)
|
||||
#define RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN BIT(3)
|
||||
#define RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK BIT(2)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN BIT(2)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK BIT(1)
|
||||
#define RK730_DTOP_DIGEN_CLKE_DAC_EN BIT(1)
|
||||
#define RK730_DTOP_DIGEN_CLKE_DAC_DIS 0
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK BIT(0)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2SRX_EN BIT(0)
|
||||
#define RK730_DTOP_DIGEN_CLKE_I2SRX_DIS 0
|
||||
|
||||
/* RK730_DADC_SR_ACL */
|
||||
#define RK730_DADC_SR_ACL_VOLL_POL_MASK BIT(5)
|
||||
#define RK730_DADC_SR_ACL_VOLL_POS BIT(5)
|
||||
#define RK730_DADC_SR_ACL_VOLL_NEG 0
|
||||
#define RK730_DADC_SR_ACL_VOLR_POL_MASK BIT(4)
|
||||
#define RK730_DADC_SR_ACL_VOLR_POS BIT(4)
|
||||
#define RK730_DADC_SR_ACL_VOLR_NEG 0
|
||||
#define RK730_DADC_SR_ACL_SRT_MASK GENMASK(2, 0)
|
||||
#define RK730_DADC_SR_ACL_SRT(x) (x)
|
||||
|
||||
/* RK730_DDAC_SR_LMT */
|
||||
#define RK730_DDAC_SR_LMT_VOLL_POL_MASK BIT(5)
|
||||
#define RK730_DDAC_SR_LMT_VOLL_POS BIT(5)
|
||||
#define RK730_DDAC_SR_LMT_VOLL_NEG 0
|
||||
#define RK730_DDAC_SR_LMT_VOLR_POL_MASK BIT(4)
|
||||
#define RK730_DDAC_SR_LMT_VOLR_POS BIT(4)
|
||||
#define RK730_DDAC_SR_LMT_VOLR_NEG 0
|
||||
#define RK730_DDAC_SR_LMT_SRT_MASK GENMASK(2, 0)
|
||||
#define RK730_DDAC_SR_LMT_SRT(x) (x)
|
||||
|
||||
/* RK730_DDAC_MUTE_MIXCTL */
|
||||
#define RK730_DDAC_MUTE_MIXCTL_MUTE_MASK BIT(0)
|
||||
#define RK730_DDAC_MUTE_MIXCTL_MUTE BIT(0)
|
||||
#define RK730_DDAC_MUTE_MIXCTL_UNMUTE 0
|
||||
|
||||
/* RK730_DI2S_CKM */
|
||||
#define RK730_DI2S_CKM_SCLK_DIV_MASK GENMASK(7, 4)
|
||||
#define RK730_DI2S_CKM_SCLK_DIV(x) ((x - 1) << 4)
|
||||
#define RK730_DI2S_CKM_SCLK_EN_MASK BIT(2)
|
||||
#define RK730_DI2S_CKM_SCLK_EN BIT(2)
|
||||
#define RK730_DI2S_CKM_SCLK_DIS 0
|
||||
#define RK730_DI2S_CKM_SCLK_POL_MASK BIT(1)
|
||||
#define RK730_DI2S_CKM_SCLK_INVERTED BIT(1)
|
||||
#define RK730_DI2S_CKM_SCLK_NORMAL 0
|
||||
#define RK730_DI2S_CKM_MST_MASK BIT(0)
|
||||
#define RK730_DI2S_CKM_MST_MASTER BIT(0)
|
||||
#define RK730_DI2S_CKM_MST_SLAVE 0
|
||||
|
||||
/* RK730_DI2S_XCR2 */
|
||||
#define RK730_DI2S_XCR2_VDW_MASK GENMASK(4, 0)
|
||||
#define RK730_DI2S_XCR2_VDW(x) (x - 1)
|
||||
|
||||
/* RK730_DI2S_RXCMD_TSD */
|
||||
#define RK730_DI2S_RXCMD_TSD_RXS_MASK BIT(5)
|
||||
#define RK730_DI2S_RXCMD_TSD_RXS_EN BIT(5)
|
||||
#define RK730_DI2S_RXCMD_TSD_RXS_DIS 0
|
||||
|
||||
/* RK730_DI2S_TXCR_3_TXCMD */
|
||||
#define RK730_DI2S_TXCR_3_TXCMD_TXS_MASK BIT(7)
|
||||
#define RK730_DI2S_TXCR_3_TXCMD_TXS_EN BIT(7)
|
||||
#define RK730_DI2S_TXCR_3_TXCMD_TXS_DIS 0
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user