Merge remote-tracking branch 'asoc/topic/intel' into asoc-next

This commit is contained in:
Mark Brown 2018-03-28 10:26:09 +08:00
commit 5b6d7104f6
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
52 changed files with 3050 additions and 1488 deletions

View File

@ -16,6 +16,23 @@ Optional properties:
- realtek,dmic-en
Boolean. true if dmic is used.
- realtek,jack-detect-source
u32. Valid values:
1: Use JD1_1 pin for jack-dectect
2: Use JD1_2 pin for jack-dectect
3: Use JD2 pin for jack-dectect
- realtek,over-current-threshold-microamp
u32, micbias over-current detection threshold in µA, valid values are
600, 1500 and 2000µA.
- realtek,over-current-scale-factor
u32, micbias over-current detection scale-factor, valid values are:
0: Scale current by 0.5
1: Scale current by 0.75
2: Scale current by 1.0
3: Scale current by 1.5
Pins on the device (for linking into audio routes) for RT5651:
* DMIC L1

View File

@ -135,6 +135,7 @@ struct sst_platform_info {
const struct sst_res_info *res_info;
const struct sst_lib_dnld_info *lib_info;
const char *platform;
bool streams_lost_on_suspend;
};
int add_sst_platform_device(void);
#endif

View File

@ -146,6 +146,8 @@ int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
int flags, unsigned int verb, unsigned int parm);
bool snd_hdac_check_power_state(struct hdac_device *hdac,
hda_nid_t nid, unsigned int target_state);
unsigned int snd_hdac_sync_power_state(struct hdac_device *hdac,
hda_nid_t nid, unsigned int target_state);
/**
* snd_hdac_read_parm - read a codec parameter
* @codec: the codec object

View File

@ -11,6 +11,10 @@
#ifndef __LINUX_SND_RT5651_H
#define __LINUX_SND_RT5651_H
/*
* Note these MUST match the values from the DT binding:
* Documentation/devicetree/bindings/sound/rt5651.txt
*/
enum rt5651_jd_src {
RT5651_JD_NULL,
RT5651_JD1_1,
@ -18,12 +22,15 @@ enum rt5651_jd_src {
RT5651_JD2,
};
struct rt5651_platform_data {
/* IN2 can optionally be differential */
bool in2_diff;
bool dmic_en;
enum rt5651_jd_src jd_src;
/*
* Note these MUST match the values from the DT binding:
* Documentation/devicetree/bindings/sound/rt5651.txt
*/
enum rt5651_ovcd_sf {
RT5651_OVCD_SF_0P5,
RT5651_OVCD_SF_0P75,
RT5651_OVCD_SF_1P0,
RT5651_OVCD_SF_1P5,
};
#endif

View File

@ -3,6 +3,7 @@
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/module.h>
@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac,
return (state == target_state);
}
EXPORT_SYMBOL_GPL(snd_hdac_check_power_state);
/**
* snd_hdac_sync_power_state - wait until actual power state matches
* with the target state
*
* @hdac: the HDAC device
* @nid: NID to send the command
* @target_state: target state to check for
*
* Return power state or PS_ERROR if codec rejects GET verb.
*/
unsigned int snd_hdac_sync_power_state(struct hdac_device *codec,
hda_nid_t nid, unsigned int power_state)
{
unsigned long end_time = jiffies + msecs_to_jiffies(500);
unsigned int state, actual_state, count;
for (count = 0; count < 500; count++) {
state = snd_hdac_codec_read(codec, nid, 0,
AC_VERB_GET_POWER_STATE, 0);
if (state & AC_PWRST_ERROR) {
msleep(20);
break;
}
actual_state = (state >> 4) & 0x0f;
if (actual_state == power_state)
break;
if (time_after_eq(jiffies, end_time))
break;
/* wait until the codec reachs to the target state */
msleep(1);
}
return state;
}
EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state);

View File

@ -2702,32 +2702,6 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
}
EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all);
/*
* wait until the state is reached, returns the current state
*/
static unsigned int hda_sync_power_state(struct hda_codec *codec,
hda_nid_t fg,
unsigned int power_state)
{
unsigned long end_time = jiffies + msecs_to_jiffies(500);
unsigned int state, actual_state;
for (;;) {
state = snd_hda_codec_read(codec, fg, 0,
AC_VERB_GET_POWER_STATE, 0);
if (state & AC_PWRST_ERROR)
break;
actual_state = (state >> 4) & 0x0f;
if (actual_state == power_state)
break;
if (time_after_eq(jiffies, end_time))
break;
/* wait until the codec reachs to the target state */
msleep(1);
}
return state;
}
/**
* snd_hda_codec_eapd_power_filter - A power filter callback for EAPD
* @codec: the HDA codec
@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
state);
snd_hda_codec_set_power_to_all(codec, fg, power_state);
}
state = hda_sync_power_state(codec, fg, power_state);
state = snd_hda_sync_power_state(codec, fg, power_state);
if (!(state & AC_PWRST_ERROR))
break;
}

View File

@ -622,7 +622,11 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
{
return snd_hdac_check_power_state(&codec->core, nid, target_state);
}
static inline bool snd_hda_sync_power_state(struct hda_codec *codec,
hda_nid_t nid, unsigned int target_state)
{
return snd_hdac_sync_power_state(&codec->core, nid, target_state);
}
unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
hda_nid_t nid,
unsigned int power_state);

View File

@ -32,9 +32,9 @@
* Detection control
*/
void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
da7219->aad->jack = jack;
da7219->aad->jack_inserted = false;
@ -43,7 +43,7 @@ void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
/* Enable/Disable jack detection */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
DA7219_ACCDET_EN_MASK,
(jack ? DA7219_ACCDET_EN_MASK : 0));
}
@ -57,17 +57,17 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
{
struct da7219_aad_priv *da7219_aad =
container_of(work, struct da7219_aad_priv, btn_det_work);
struct snd_soc_codec *codec = da7219_aad->codec;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_component *component = da7219_aad->component;
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
u8 statusa, micbias_ctrl;
bool micbias_up = false;
int retries = 0;
/* Drive headphones/lineout */
snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_OE_MASK,
DA7219_HP_L_AMP_OE_MASK);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_OE_MASK,
DA7219_HP_R_AMP_OE_MASK);
@ -76,7 +76,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
snd_soc_dapm_sync(dapm);
do {
statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
statusa = snd_soc_component_read32(component, DA7219_ACCDET_STATUS_A);
if (statusa & DA7219_MICBIAS_UP_STS_MASK)
micbias_up = true;
else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
@ -84,7 +84,7 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
} while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
dev_warn(codec->dev, "Mic bias status check timed out");
dev_warn(component->dev, "Mic bias status check timed out");
/*
* Mic bias pulse required to enable mic, must be done before enabling
@ -92,16 +92,16 @@ static void da7219_aad_btn_det_work(struct work_struct *work)
*/
if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
/* Pulse higher level voltage */
micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
snd_soc_update_bits(codec, DA7219_MICBIAS_CTRL,
micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
DA7219_MICBIAS1_LEVEL_MASK,
da7219_aad->micbias_pulse_lvl);
msleep(da7219_aad->micbias_pulse_time);
snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_ctrl);
snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl);
}
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
DA7219_BUTTON_CONFIG_MASK,
da7219_aad->btn_cfg);
}
@ -110,9 +110,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
{
struct da7219_aad_priv *da7219_aad =
container_of(work, struct da7219_aad_priv, hptest_work);
struct snd_soc_codec *codec = da7219_aad->codec;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = da7219_aad->component;
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u16 tonegen_freq_hptest;
u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
@ -127,7 +127,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
if (da7219->mclk) {
ret = clk_prepare_enable(da7219->mclk);
if (ret) {
dev_err(codec->dev, "Failed to enable mclk - %d\n", ret);
dev_err(component->dev, "Failed to enable mclk - %d\n", ret);
mutex_unlock(&da7219->pll_lock);
mutex_unlock(&da7219->ctrl_lock);
snd_soc_dapm_mutex_unlock(dapm);
@ -142,90 +142,90 @@ static void da7219_aad_hptest_work(struct work_struct *work)
* If MCLK is present, but PLL is not enabled then we enable it here to
* ensure a consistent detection procedure.
*/
pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS);
pll_srm_sts = snd_soc_component_read32(component, DA7219_PLL_SRM_STS);
if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL);
if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)
da7219_set_pll(codec, DA7219_SYSCLK_PLL,
da7219_set_pll(component, DA7219_SYSCLK_PLL,
DA7219_PLL_FREQ_OUT_98304);
} else {
tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
}
/* Ensure gain ramping at fastest rate */
gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
gain_ramp_ctrl = snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
/* Bypass cache so it saves current settings */
regcache_cache_bypass(da7219->regmap, true);
/* Make sure Tone Generator is disabled */
snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
/* Enable HPTest block, 1KOhms check */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
DA7219_HPTEST_EN_MASK |
DA7219_HPTEST_RES_SEL_1KOHMS);
/* Set gains to 0db */
snd_soc_write(codec, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
snd_soc_write(codec, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
snd_soc_write(codec, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
snd_soc_write(codec, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
/* Disable DAC filters, EQs and soft mute */
snd_soc_update_bits(codec, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
0);
snd_soc_update_bits(codec, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
0);
snd_soc_update_bits(codec, DA7219_DAC_FILTERS5,
snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
DA7219_DAC_SOFTMUTE_EN_MASK, 0);
/* Enable HP left & right paths */
snd_soc_update_bits(codec, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
DA7219_CP_EN_MASK);
snd_soc_update_bits(codec, DA7219_DIG_ROUTING_DAC,
snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC,
DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
DA7219_DAC_L_SRC_TONEGEN |
DA7219_DAC_R_SRC_TONEGEN);
snd_soc_update_bits(codec, DA7219_DAC_L_CTRL,
snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL,
DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
DA7219_DAC_L_EN_MASK);
snd_soc_update_bits(codec, DA7219_DAC_R_CTRL,
snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL,
DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
DA7219_DAC_R_EN_MASK);
snd_soc_update_bits(codec, DA7219_MIXOUT_L_SELECT,
snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT,
DA7219_MIXOUT_L_MIX_SELECT_MASK,
DA7219_MIXOUT_L_MIX_SELECT_MASK);
snd_soc_update_bits(codec, DA7219_MIXOUT_R_SELECT,
snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT,
DA7219_MIXOUT_R_MIX_SELECT_MASK,
DA7219_MIXOUT_R_MIX_SELECT_MASK);
snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1L,
snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L,
DA7219_OUTFILT_ST_1L_SRC_MASK,
DA7219_DMIX_ST_SRC_OUTFILT1L);
snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1R,
snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R,
DA7219_OUTFILT_ST_1R_SRC_MASK,
DA7219_DMIX_ST_SRC_OUTFILT1R);
snd_soc_update_bits(codec, DA7219_MIXOUT_L_CTRL,
snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL,
DA7219_MIXOUT_L_AMP_EN_MASK,
DA7219_MIXOUT_L_AMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_MIXOUT_R_CTRL,
snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL,
DA7219_MIXOUT_R_AMP_EN_MASK,
DA7219_MIXOUT_R_AMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
msleep(DA7219_SETTLING_DELAY);
snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_MUTE_EN_MASK |
DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_MUTE_EN_MASK |
DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
@ -237,26 +237,26 @@ static void da7219_aad_hptest_work(struct work_struct *work)
msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
/* Configure & start Tone Generator */
snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
&tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2,
DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
DA7219_SWG_SEL_SRAMP |
DA7219_TONE_GEN_GAIN_MINUS_15DB);
snd_soc_write(codec, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
msleep(DA7219_AAD_HPTEST_PERIOD);
/* Grab comparator reading */
accdet_cfg8 = snd_soc_read(codec, DA7219_ACCDET_CONFIG_8);
accdet_cfg8 = snd_soc_component_read32(component, DA7219_ACCDET_CONFIG_8);
if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
report |= SND_JACK_HEADPHONE;
else
report |= SND_JACK_LINEOUT;
/* Stop tone generator */
snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
msleep(DA7219_AAD_HPTEST_PERIOD);
@ -294,7 +294,7 @@ static void da7219_aad_hptest_work(struct work_struct *work)
regcache_cache_bypass(da7219->regmap, false);
/* Disable HPTest block */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
DA7219_HPTEST_EN_MASK, 0);
/*
@ -305,18 +305,18 @@ static void da7219_aad_hptest_work(struct work_struct *work)
msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
/* Restore gain ramping rate */
snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
/* Drive Headphones/lineout */
snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
DA7219_HP_L_AMP_OE_MASK);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
DA7219_HP_R_AMP_OE_MASK);
/* Restore PLL to previous configuration, if re-configured */
if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
da7219_set_pll(codec, DA7219_SYSCLK_MCLK, 0);
da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0);
/* Remove MCLK, if previously enabled */
if (da7219->mclk)
@ -343,9 +343,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
{
struct da7219_aad_priv *da7219_aad = data;
struct snd_soc_codec *codec = da7219_aad->codec;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = da7219_aad->component;
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u8 events[DA7219_AAD_IRQ_REG_MAX];
u8 statusa;
int i, report = 0, mask = 0;
@ -358,13 +358,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
return IRQ_NONE;
/* Read status register for jack insertion & type status */
statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
statusa = snd_soc_component_read32(component, DA7219_ACCDET_STATUS_A);
/* Clear events */
regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
events, DA7219_AAD_IRQ_REG_MAX);
dev_dbg(codec->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
statusa);
@ -430,13 +430,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
da7219_aad->jack_inserted = false;
/* Un-drive headphones/lineout */
snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_OE_MASK, 0);
snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_OE_MASK, 0);
/* Ensure button detection disabled */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
DA7219_BUTTON_CONFIG_MASK, 0);
/* Disable mic bias */
@ -459,7 +459,7 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
*/
static enum da7219_aad_micbias_pulse_lvl
da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_micbias_pulse_lvl(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 2800:
@ -467,13 +467,13 @@ static enum da7219_aad_micbias_pulse_lvl
case 2900:
return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
default:
dev_warn(codec->dev, "Invalid micbias pulse level");
dev_warn(component->dev, "Invalid micbias pulse level");
return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
}
}
static enum da7219_aad_btn_cfg
da7219_aad_fw_btn_cfg(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_btn_cfg(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 2:
@ -491,13 +491,13 @@ static enum da7219_aad_btn_cfg
case 500:
return DA7219_AAD_BTN_CFG_500MS;
default:
dev_warn(codec->dev, "Invalid button config");
dev_warn(component->dev, "Invalid button config");
return DA7219_AAD_BTN_CFG_10MS;
}
}
static enum da7219_aad_mic_det_thr
da7219_aad_fw_mic_det_thr(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_mic_det_thr(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 200:
@ -509,13 +509,13 @@ static enum da7219_aad_mic_det_thr
case 1000:
return DA7219_AAD_MIC_DET_THR_1000_OHMS;
default:
dev_warn(codec->dev, "Invalid mic detect threshold");
dev_warn(component->dev, "Invalid mic detect threshold");
return DA7219_AAD_MIC_DET_THR_500_OHMS;
}
}
static enum da7219_aad_jack_ins_deb
da7219_aad_fw_jack_ins_deb(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_jack_ins_deb(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 5:
@ -535,13 +535,13 @@ static enum da7219_aad_jack_ins_deb
case 1000:
return DA7219_AAD_JACK_INS_DEB_1S;
default:
dev_warn(codec->dev, "Invalid jack insert debounce");
dev_warn(component->dev, "Invalid jack insert debounce");
return DA7219_AAD_JACK_INS_DEB_20MS;
}
}
static enum da7219_aad_jack_det_rate
da7219_aad_fw_jack_det_rate(struct snd_soc_codec *codec, const char *str)
da7219_aad_fw_jack_det_rate(struct snd_soc_component *component, const char *str)
{
if (!strcmp(str, "32ms_64ms")) {
return DA7219_AAD_JACK_DET_RATE_32_64MS;
@ -552,13 +552,13 @@ static enum da7219_aad_jack_det_rate
} else if (!strcmp(str, "256ms_512ms")) {
return DA7219_AAD_JACK_DET_RATE_256_512MS;
} else {
dev_warn(codec->dev, "Invalid jack detect rate");
dev_warn(component->dev, "Invalid jack detect rate");
return DA7219_AAD_JACK_DET_RATE_256_512MS;
}
}
static enum da7219_aad_jack_rem_deb
da7219_aad_fw_jack_rem_deb(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_jack_rem_deb(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 1:
@ -570,13 +570,13 @@ static enum da7219_aad_jack_rem_deb
case 20:
return DA7219_AAD_JACK_REM_DEB_20MS;
default:
dev_warn(codec->dev, "Invalid jack removal debounce");
dev_warn(component->dev, "Invalid jack removal debounce");
return DA7219_AAD_JACK_REM_DEB_1MS;
}
}
static enum da7219_aad_btn_avg
da7219_aad_fw_btn_avg(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_btn_avg(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 1:
@ -588,13 +588,13 @@ static enum da7219_aad_btn_avg
case 8:
return DA7219_AAD_BTN_AVG_8;
default:
dev_warn(codec->dev, "Invalid button average value");
dev_warn(component->dev, "Invalid button average value");
return DA7219_AAD_BTN_AVG_2;
}
}
static enum da7219_aad_adc_1bit_rpt
da7219_aad_fw_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val)
da7219_aad_fw_adc_1bit_rpt(struct snd_soc_component *component, u32 val)
{
switch (val) {
case 1:
@ -606,14 +606,14 @@ static enum da7219_aad_adc_1bit_rpt
case 8:
return DA7219_AAD_ADC_1BIT_RPT_8;
default:
dev_warn(codec->dev, "Invalid ADC 1-bit repeat value");
dev_warn(component->dev, "Invalid ADC 1-bit repeat value");
return DA7219_AAD_ADC_1BIT_RPT_1;
}
}
static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *codec)
static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_component *component)
{
struct device *dev = codec->dev;
struct device *dev = component->dev;
struct i2c_client *i2c = to_i2c_client(dev);
struct fwnode_handle *aad_np;
struct da7219_aad_pdata *aad_pdata;
@ -624,7 +624,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
if (!aad_np)
return NULL;
aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL);
aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
if (!aad_pdata)
return NULL;
@ -633,7 +633,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
&fw_val32) >= 0)
aad_pdata->micbias_pulse_lvl =
da7219_aad_fw_micbias_pulse_lvl(codec, fw_val32);
da7219_aad_fw_micbias_pulse_lvl(component, fw_val32);
else
aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
@ -642,31 +642,31 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
aad_pdata->micbias_pulse_time = fw_val32;
if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(codec, fw_val32);
aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(component, fw_val32);
else
aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
aad_pdata->mic_det_thr =
da7219_aad_fw_mic_det_thr(codec, fw_val32);
da7219_aad_fw_mic_det_thr(component, fw_val32);
else
aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
aad_pdata->jack_ins_deb =
da7219_aad_fw_jack_ins_deb(codec, fw_val32);
da7219_aad_fw_jack_ins_deb(component, fw_val32);
else
aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
aad_pdata->jack_det_rate =
da7219_aad_fw_jack_det_rate(codec, fw_str);
da7219_aad_fw_jack_det_rate(component, fw_str);
else
aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
aad_pdata->jack_rem_deb =
da7219_aad_fw_jack_rem_deb(codec, fw_val32);
da7219_aad_fw_jack_rem_deb(component, fw_val32);
else
aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
@ -691,22 +691,22 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct snd_soc_codec *cod
aad_pdata->c_mic_btn_thr = 0x3E;
if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
aad_pdata->btn_avg = da7219_aad_fw_btn_avg(codec, fw_val32);
aad_pdata->btn_avg = da7219_aad_fw_btn_avg(component, fw_val32);
else
aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
aad_pdata->adc_1bit_rpt =
da7219_aad_fw_adc_1bit_rpt(codec, fw_val32);
da7219_aad_fw_adc_1bit_rpt(component, fw_val32);
else
aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
return aad_pdata;
}
static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
static void da7219_aad_handle_pdata(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct da7219_aad_priv *da7219_aad = da7219->aad;
struct da7219_pdata *pdata = da7219->pdata;
@ -752,7 +752,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
DA7219_MIC_DET_THRESH_SHIFT);
mask |= DA7219_MIC_DET_THRESH_MASK;
}
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, mask, cfg);
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg);
cfg = 0;
mask = 0;
@ -787,15 +787,15 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
DA7219_JACKDET_REM_DEB_SHIFT);
mask |= DA7219_JACKDET_REM_DEB_MASK;
}
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_2, mask, cfg);
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg);
snd_soc_write(codec, DA7219_ACCDET_CONFIG_3,
snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3,
aad_pdata->a_d_btn_thr);
snd_soc_write(codec, DA7219_ACCDET_CONFIG_4,
snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4,
aad_pdata->d_b_btn_thr);
snd_soc_write(codec, DA7219_ACCDET_CONFIG_5,
snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5,
aad_pdata->b_c_btn_thr);
snd_soc_write(codec, DA7219_ACCDET_CONFIG_6,
snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6,
aad_pdata->c_mic_btn_thr);
cfg = 0;
@ -818,7 +818,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
DA7219_ADC_1_BIT_REPEAT_SHIFT);
mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
}
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_7, mask, cfg);
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg);
}
}
@ -827,16 +827,16 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
* Suspend/Resume
*/
void da7219_aad_suspend(struct snd_soc_codec *codec)
void da7219_aad_suspend(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct da7219_aad_priv *da7219_aad = da7219->aad;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
u8 micbias_ctrl;
if (da7219_aad->jack) {
/* Disable jack detection during suspend */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
DA7219_ACCDET_EN_MASK, 0);
/*
@ -846,7 +846,7 @@ void da7219_aad_suspend(struct snd_soc_codec *codec)
* suspend then this will be dealt with through the IRQ handler.
*/
if (da7219_aad->jack_inserted) {
micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
snd_soc_dapm_disable_pin(dapm, "Mic Bias");
snd_soc_dapm_sync(dapm);
@ -856,11 +856,11 @@ void da7219_aad_suspend(struct snd_soc_codec *codec)
}
}
void da7219_aad_resume(struct snd_soc_codec *codec)
void da7219_aad_resume(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct da7219_aad_priv *da7219_aad = da7219->aad;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
if (da7219_aad->jack) {
/* Re-enable micbias if previously enabled for 4-pole jack */
@ -872,7 +872,7 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
}
/* Re-enable jack detection */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
DA7219_ACCDET_EN_MASK,
DA7219_ACCDET_EN_MASK);
}
@ -883,28 +883,28 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
* Init/Exit
*/
int da7219_aad_init(struct snd_soc_codec *codec)
int da7219_aad_init(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct da7219_aad_priv *da7219_aad;
u8 mask[DA7219_AAD_IRQ_REG_MAX];
int ret;
da7219_aad = devm_kzalloc(codec->dev, sizeof(*da7219_aad), GFP_KERNEL);
da7219_aad = devm_kzalloc(component->dev, sizeof(*da7219_aad), GFP_KERNEL);
if (!da7219_aad)
return -ENOMEM;
da7219->aad = da7219_aad;
da7219_aad->codec = codec;
da7219_aad->component = component;
/* Handle any DT/ACPI/platform data */
if (da7219->pdata && !da7219->pdata->aad_pdata)
da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(codec);
da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(component);
da7219_aad_handle_pdata(codec);
da7219_aad_handle_pdata(component);
/* Disable button detection */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
DA7219_BUTTON_CONFIG_MASK, 0);
INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
@ -915,7 +915,7 @@ int da7219_aad_init(struct snd_soc_codec *codec)
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"da7219-aad", da7219_aad);
if (ret) {
dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
return ret;
}
@ -928,9 +928,9 @@ int da7219_aad_init(struct snd_soc_codec *codec)
}
EXPORT_SYMBOL_GPL(da7219_aad_init);
void da7219_aad_exit(struct snd_soc_codec *codec)
void da7219_aad_exit(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct da7219_aad_priv *da7219_aad = da7219->aad;
u8 mask[DA7219_AAD_IRQ_REG_MAX];

View File

@ -189,7 +189,7 @@ enum da7219_aad_event_regs {
/* Private data */
struct da7219_aad_priv {
struct snd_soc_codec *codec;
struct snd_soc_component *component;
int irq;
u8 micbias_pulse_lvl;
@ -206,14 +206,14 @@ struct da7219_aad_priv {
};
/* AAD control */
void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack);
/* Suspend/Resume */
void da7219_aad_suspend(struct snd_soc_codec *codec);
void da7219_aad_resume(struct snd_soc_codec *codec);
void da7219_aad_suspend(struct snd_soc_component *component);
void da7219_aad_resume(struct snd_soc_component *component);
/* Init/Exit */
int da7219_aad_init(struct snd_soc_codec *codec);
void da7219_aad_exit(struct snd_soc_codec *codec);
int da7219_aad_init(struct snd_soc_component *component);
void da7219_aad_exit(struct snd_soc_component *component);
#endif /* __DA7219_AAD_H */

View File

@ -256,8 +256,8 @@ static const struct soc_enum da7219_cp_track_mode =
static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
mutex_lock(&da7219->ctrl_lock);
@ -270,8 +270,8 @@ static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
mutex_lock(&da7219->ctrl_lock);
@ -284,8 +284,8 @@ static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
mutex_lock(&da7219->ctrl_lock);
@ -298,8 +298,8 @@ static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
mutex_lock(&da7219->ctrl_lock);
@ -310,55 +310,55 @@ static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
}
/* ALC */
static void da7219_alc_calib(struct snd_soc_codec *codec)
static void da7219_alc_calib(struct snd_soc_component *component)
{
u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl;
/* Save current state of mic control register */
mic_ctrl = snd_soc_read(codec, DA7219_MIC_1_CTRL);
mic_ctrl = snd_soc_component_read32(component, DA7219_MIC_1_CTRL);
/* Save current state of input mixer control register */
mixin_ctrl = snd_soc_read(codec, DA7219_MIXIN_L_CTRL);
mixin_ctrl = snd_soc_component_read32(component, DA7219_MIXIN_L_CTRL);
/* Save current state of input ADC control register */
adc_ctrl = snd_soc_read(codec, DA7219_ADC_L_CTRL);
adc_ctrl = snd_soc_component_read32(component, DA7219_ADC_L_CTRL);
/* Enable then Mute MIC PGAs */
snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
DA7219_MIC_1_AMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_MIC_1_CTRL,
snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL,
DA7219_MIC_1_AMP_MUTE_EN_MASK,
DA7219_MIC_1_AMP_MUTE_EN_MASK);
/* Enable input mixers unmuted */
snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL,
DA7219_MIXIN_L_AMP_EN_MASK |
DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
DA7219_MIXIN_L_AMP_EN_MASK);
/* Enable input filters unmuted */
snd_soc_update_bits(codec, DA7219_ADC_L_CTRL,
snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL,
DA7219_ADC_L_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK,
DA7219_ADC_L_EN_MASK);
/* Perform auto calibration */
snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
DA7219_ALC_AUTO_CALIB_EN_MASK,
DA7219_ALC_AUTO_CALIB_EN_MASK);
do {
calib_ctrl = snd_soc_read(codec, DA7219_ALC_CTRL1);
calib_ctrl = snd_soc_component_read32(component, DA7219_ALC_CTRL1);
} while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK);
/* If auto calibration fails, disable DC offset, hybrid ALC */
if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
dev_warn(codec->dev,
dev_warn(component->dev,
"ALC auto calibration failed with overflow\n");
snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
DA7219_ALC_OFFSET_EN_MASK |
DA7219_ALC_SYNC_MODE_MASK, 0);
} else {
/* Enable DC offset cancellation, hybrid mode */
snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
snd_soc_component_update_bits(component, DA7219_ALC_CTRL1,
DA7219_ALC_OFFSET_EN_MASK |
DA7219_ALC_SYNC_MODE_MASK,
DA7219_ALC_OFFSET_EN_MASK |
@ -366,20 +366,20 @@ static void da7219_alc_calib(struct snd_soc_codec *codec)
}
/* Restore input filter control register to original state */
snd_soc_write(codec, DA7219_ADC_L_CTRL, adc_ctrl);
snd_soc_component_write(component, DA7219_ADC_L_CTRL, adc_ctrl);
/* Restore input mixer control registers to original state */
snd_soc_write(codec, DA7219_MIXIN_L_CTRL, mixin_ctrl);
snd_soc_component_write(component, DA7219_MIXIN_L_CTRL, mixin_ctrl);
/* Restore MIC control registers to original states */
snd_soc_write(codec, DA7219_MIC_1_CTRL, mic_ctrl);
snd_soc_component_write(component, DA7219_MIC_1_CTRL, mic_ctrl);
}
static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
ret = snd_soc_put_volsw(kcontrol, ucontrol);
@ -389,7 +389,7 @@ static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
* make sure calibrated offsets are updated.
*/
if ((ret == 1) && (da7219->alc_en))
da7219_alc_calib(codec);
da7219_alc_calib(component);
return ret;
}
@ -397,13 +397,13 @@ static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
/* Force ALC offset calibration if enabling ALC */
if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
da7219_alc_calib(codec);
da7219_alc_calib(component);
da7219->alc_en = true;
} else {
da7219->alc_en = false;
@ -416,8 +416,8 @@ static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct soc_mixer_control *mixer_ctrl =
(struct soc_mixer_control *) kcontrol->private_value;
unsigned int reg = mixer_ctrl->reg;
@ -443,8 +443,8 @@ static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct soc_mixer_control *mixer_ctrl =
(struct soc_mixer_control *) kcontrol->private_value;
unsigned int reg = mixer_ctrl->reg;
@ -769,8 +769,8 @@ static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls[] = {
static int da7219_dai_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u8 pll_ctrl, pll_status;
int i = 0;
bool srm_lock = false;
@ -779,22 +779,22 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMU:
if (da7219->master)
/* Enable DAI clks for master mode */
snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
DA7219_DAI_CLK_EN_MASK,
DA7219_DAI_CLK_EN_MASK);
/* PC synchronised to DAI */
snd_soc_update_bits(codec, DA7219_PC_COUNT,
snd_soc_component_update_bits(component, DA7219_PC_COUNT,
DA7219_PC_FREERUN_MASK, 0);
/* Slave mode, if SRM not enabled no need for status checks */
pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL);
if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM)
return 0;
/* Check SRM has locked */
do {
pll_status = snd_soc_read(codec, DA7219_PLL_SRM_STS);
pll_status = snd_soc_component_read32(component, DA7219_PLL_SRM_STS);
if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) {
srm_lock = true;
} else {
@ -804,18 +804,18 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
} while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
if (!srm_lock)
dev_warn(codec->dev, "SRM failed to lock\n");
dev_warn(component->dev, "SRM failed to lock\n");
return 0;
case SND_SOC_DAPM_POST_PMD:
/* PC free-running */
snd_soc_update_bits(codec, DA7219_PC_COUNT,
snd_soc_component_update_bits(component, DA7219_PC_COUNT,
DA7219_PC_FREERUN_MASK,
DA7219_PC_FREERUN_MASK);
/* Disable DAI clks if in master mode */
if (da7219->master)
snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
DA7219_DAI_CLK_EN_MASK, 0);
return 0;
default:
@ -841,7 +841,7 @@ static int da7219_settling_event(struct snd_soc_dapm_widget *w,
static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
u8 hp_ctrl, min_gain_mask;
switch (w->reg) {
@ -860,7 +860,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMD:
/* Enable minimum gain on HP to avoid pops */
snd_soc_update_bits(codec, hp_ctrl, min_gain_mask,
snd_soc_component_update_bits(component, hp_ctrl, min_gain_mask,
min_gain_mask);
msleep(DA7219_MIN_GAIN_DELAY);
@ -868,7 +868,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMU:
/* Remove minimum gain on HP */
snd_soc_update_bits(codec, hp_ctrl, min_gain_mask, 0);
snd_soc_component_update_bits(component, hp_ctrl, min_gain_mask, 0);
break;
}
@ -879,22 +879,22 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
static int da7219_gain_ramp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
case SND_SOC_DAPM_PRE_PMD:
/* Ensure nominal gain ramping for DAPM sequence */
da7219->gain_ramp_ctrl =
snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
DA7219_GAIN_RAMP_RATE_NOMINAL);
break;
case SND_SOC_DAPM_POST_PMU:
case SND_SOC_DAPM_POST_PMD:
/* Restore previous gain ramp settings */
snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
da7219->gain_ramp_ctrl);
break;
}
@ -1116,8 +1116,8 @@ static const struct snd_soc_dapm_route da7219_audio_map[] = {
static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = codec_dai->codec;
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = codec_dai->component;
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret = 0;
if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
@ -1133,12 +1133,12 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
switch (clk_id) {
case DA7219_CLKSRC_MCLK_SQR:
snd_soc_update_bits(codec, DA7219_PLL_CTRL,
snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
DA7219_PLL_MCLK_SQR_EN_MASK,
DA7219_PLL_MCLK_SQR_EN_MASK);
break;
case DA7219_CLKSRC_MCLK:
snd_soc_update_bits(codec, DA7219_PLL_CTRL,
snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
DA7219_PLL_MCLK_SQR_EN_MASK, 0);
break;
default:
@ -1167,9 +1167,9 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return 0;
}
int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
int da7219_set_pll(struct snd_soc_component *component, int source, unsigned int fout)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u8 pll_ctrl, indiv_bits, indiv;
u8 pll_frac_top, pll_frac_bot, pll_integer;
@ -1178,7 +1178,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
/* Verify 2MHz - 54MHz MCLK provided, and set input divider */
if (da7219->mclk_rate < 2000000) {
dev_err(codec->dev, "PLL input clock %d below valid range\n",
dev_err(component->dev, "PLL input clock %d below valid range\n",
da7219->mclk_rate);
return -EINVAL;
} else if (da7219->mclk_rate <= 4500000) {
@ -1197,7 +1197,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
indiv_bits = DA7219_PLL_INDIV_36_TO_54_MHZ;
indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL;
} else {
dev_err(codec->dev, "PLL input clock %d above valid range\n",
dev_err(component->dev, "PLL input clock %d above valid range\n",
da7219->mclk_rate);
return -EINVAL;
}
@ -1208,7 +1208,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
switch (source) {
case DA7219_SYSCLK_MCLK:
pll_ctrl |= DA7219_PLL_MODE_BYPASS;
snd_soc_update_bits(codec, DA7219_PLL_CTRL,
snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
DA7219_PLL_INDIV_MASK |
DA7219_PLL_MODE_MASK, pll_ctrl);
return 0;
@ -1219,7 +1219,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
pll_ctrl |= DA7219_PLL_MODE_SRM;
break;
default:
dev_err(codec->dev, "Invalid PLL config\n");
dev_err(component->dev, "Invalid PLL config\n");
return -EINVAL;
}
@ -1231,10 +1231,10 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
pll_frac_bot = (frac_div) & DA7219_BYTE_MASK;
/* Write PLL config & dividers */
snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top);
snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot);
snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer);
snd_soc_update_bits(codec, DA7219_PLL_CTRL,
snd_soc_component_write(component, DA7219_PLL_FRAC_TOP, pll_frac_top);
snd_soc_component_write(component, DA7219_PLL_FRAC_BOT, pll_frac_bot);
snd_soc_component_write(component, DA7219_PLL_INTEGER, pll_integer);
snd_soc_component_update_bits(component, DA7219_PLL_CTRL,
DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK,
pll_ctrl);
@ -1244,12 +1244,12 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int source, unsigned int fref, unsigned int fout)
{
struct snd_soc_codec *codec = codec_dai->codec;
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = codec_dai->component;
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
mutex_lock(&da7219->pll_lock);
ret = da7219_set_pll(codec, source, fout);
ret = da7219_set_pll(component, source, fout);
mutex_unlock(&da7219->pll_lock);
return ret;
@ -1257,8 +1257,8 @@ static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = codec_dai->component;
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u8 dai_clk_mode = 0, dai_ctrl = 0;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@ -1335,11 +1335,11 @@ static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
/* By default 64 BCLKs per WCLK is supported */
dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64;
snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
DA7219_DAI_BCLKS_PER_WCLK_MASK |
DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
dai_clk_mode);
snd_soc_update_bits(codec, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
snd_soc_component_update_bits(component, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
dai_ctrl);
return 0;
@ -1349,18 +1349,18 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width)
{
struct snd_soc_codec *codec = dai->codec;
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
u8 dai_bclks_per_wclk;
u16 offset;
u32 frame_size;
/* No channels enabled so disable TDM, revert to 64-bit frames */
if (!tx_mask) {
snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
DA7219_DAI_TDM_CH_EN_MASK |
DA7219_DAI_TDM_MODE_EN_MASK, 0);
snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
DA7219_DAI_BCLKS_PER_WCLK_MASK,
DA7219_DAI_BCLKS_PER_WCLK_64);
return 0;
@ -1368,14 +1368,14 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
/* Check we have valid slots */
if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
dev_err(codec->dev, "Invalid number of slots, max = %d\n",
dev_err(component->dev, "Invalid number of slots, max = %d\n",
DA7219_DAI_TDM_MAX_SLOTS);
return -EINVAL;
}
/* Check we have a valid offset given */
if (rx_mask > DA7219_DAI_OFFSET_MAX) {
dev_err(codec->dev, "Invalid slot offset, max = %d\n",
dev_err(component->dev, "Invalid slot offset, max = %d\n",
DA7219_DAI_OFFSET_MAX);
return -EINVAL;
}
@ -1396,11 +1396,11 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
break;
default:
dev_err(codec->dev, "Invalid frame size %d\n", frame_size);
dev_err(component->dev, "Invalid frame size %d\n", frame_size);
return -EINVAL;
}
snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE,
DA7219_DAI_BCLKS_PER_WCLK_MASK,
dai_bclks_per_wclk);
@ -1408,7 +1408,7 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
&offset, sizeof(offset));
snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL,
DA7219_DAI_TDM_CH_EN_MASK |
DA7219_DAI_TDM_MODE_EN_MASK,
(tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
@ -1421,7 +1421,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct snd_soc_component *component = dai->component;
u8 dai_ctrl = 0, fs;
unsigned int channels;
@ -1444,7 +1444,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
channels = params_channels(params);
if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
dev_err(codec->dev,
dev_err(component->dev,
"Invalid number of channels, only 1 to %d supported\n",
DA7219_DAI_CH_NUM_MAX);
return -EINVAL;
@ -1489,11 +1489,11 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
snd_soc_update_bits(codec, DA7219_DAI_CTRL,
snd_soc_component_update_bits(component, DA7219_DAI_CTRL,
DA7219_DAI_WORD_LENGTH_MASK |
DA7219_DAI_CH_NUM_MASK,
dai_ctrl);
snd_soc_write(codec, DA7219_SR, fs);
snd_soc_component_write(component, DA7219_SR, fs);
return 0;
}
@ -1585,9 +1585,9 @@ static enum da7219_mic_amp_in_sel
}
}
static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_component *component)
{
struct device *dev = codec->dev;
struct device *dev = component->dev;
struct da7219_pdata *pdata;
const char *of_str;
u32 of_val32;
@ -1616,10 +1616,10 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
* Codec driver functions
*/
static int da7219_set_bias_level(struct snd_soc_codec *codec,
static int da7219_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
int ret;
switch (level) {
@ -1627,11 +1627,11 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_PREPARE:
/* Enable MCLK for transition to ON state */
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {
if (da7219->mclk) {
ret = clk_prepare_enable(da7219->mclk);
if (ret) {
dev_err(codec->dev,
dev_err(component->dev,
"Failed to enable mclk\n");
return ret;
}
@ -1640,13 +1640,13 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
/* Master bias */
snd_soc_update_bits(codec, DA7219_REFERENCES,
snd_soc_component_update_bits(component, DA7219_REFERENCES,
DA7219_BIAS_EN_MASK,
DA7219_BIAS_EN_MASK);
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_PREPARE) {
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) {
/* Remove MCLK */
if (da7219->mclk)
clk_disable_unprepare(da7219->mclk);
@ -1655,7 +1655,7 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_OFF:
/* Only disable master bias if we're not a wake-up source */
if (!da7219->wakeup_source)
snd_soc_update_bits(codec, DA7219_REFERENCES,
snd_soc_component_update_bits(component, DA7219_REFERENCES,
DA7219_BIAS_EN_MASK, 0);
break;
@ -1670,9 +1670,9 @@ static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = {
[DA7219_SUPPLY_VDDIO] = "VDDIO",
};
static int da7219_handle_supplies(struct snd_soc_codec *codec)
static int da7219_handle_supplies(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct regulator *vddio;
u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
int i, ret;
@ -1681,10 +1681,10 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
for (i = 0; i < DA7219_NUM_SUPPLIES; ++i)
da7219->supplies[i].supply = da7219_supply_names[i];
ret = devm_regulator_bulk_get(codec->dev, DA7219_NUM_SUPPLIES,
ret = devm_regulator_bulk_get(component->dev, DA7219_NUM_SUPPLIES,
da7219->supplies);
if (ret) {
dev_err(codec->dev, "Failed to get supplies");
dev_err(component->dev, "Failed to get supplies");
return ret;
}
@ -1692,29 +1692,29 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
ret = regulator_get_voltage(vddio);
if (ret < 1200000)
dev_warn(codec->dev, "Invalid VDDIO voltage\n");
dev_warn(component->dev, "Invalid VDDIO voltage\n");
else if (ret < 2800000)
io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
/* Enable main supplies */
ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
if (ret) {
dev_err(codec->dev, "Failed to enable supplies");
dev_err(component->dev, "Failed to enable supplies");
return ret;
}
/* Ensure device in active mode */
snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
snd_soc_component_write(component, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
/* Update IO voltage level range */
snd_soc_write(codec, DA7219_IO_CTRL, io_voltage_lvl);
snd_soc_component_write(component, DA7219_IO_CTRL, io_voltage_lvl);
return 0;
}
static void da7219_handle_pdata(struct snd_soc_codec *codec)
static void da7219_handle_pdata(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
struct da7219_pdata *pdata = da7219->pdata;
if (pdata) {
@ -1735,14 +1735,14 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
break;
}
snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl);
snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_lvl);
/* Mic */
switch (pdata->mic_amp_in_sel) {
case DA7219_MIC_AMP_IN_SEL_DIFF:
case DA7219_MIC_AMP_IN_SEL_SE_P:
case DA7219_MIC_AMP_IN_SEL_SE_N:
snd_soc_write(codec, DA7219_MIC_1_SELECT,
snd_soc_component_write(component, DA7219_MIC_1_SELECT,
pdata->mic_amp_in_sel);
break;
}
@ -1753,9 +1753,9 @@ static struct reg_sequence da7219_rev_aa_patch[] = {
{ DA7219_REFERENCES, 0x08 },
};
static int da7219_probe(struct snd_soc_codec *codec)
static int da7219_probe(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
unsigned int rev;
int ret;
@ -1763,13 +1763,13 @@ static int da7219_probe(struct snd_soc_codec *codec)
mutex_init(&da7219->pll_lock);
/* Regulator configuration */
ret = da7219_handle_supplies(codec);
ret = da7219_handle_supplies(component);
if (ret)
return ret;
ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev);
if (ret) {
dev_err(codec->dev, "Failed to read chip revision: %d\n", ret);
dev_err(component->dev, "Failed to read chip revision: %d\n", ret);
goto err_disable_reg;
}
@ -1778,7 +1778,7 @@ static int da7219_probe(struct snd_soc_codec *codec)
ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch,
ARRAY_SIZE(da7219_rev_aa_patch));
if (ret) {
dev_err(codec->dev, "Failed to register AA patch: %d\n",
dev_err(component->dev, "Failed to register AA patch: %d\n",
ret);
goto err_disable_reg;
}
@ -1788,14 +1788,14 @@ static int da7219_probe(struct snd_soc_codec *codec)
}
/* Handle DT/ACPI/Platform data */
da7219->pdata = dev_get_platdata(codec->dev);
da7219->pdata = dev_get_platdata(component->dev);
if (!da7219->pdata)
da7219->pdata = da7219_fw_to_pdata(codec);
da7219->pdata = da7219_fw_to_pdata(component);
da7219_handle_pdata(codec);
da7219_handle_pdata(component);
/* Check if MCLK provided */
da7219->mclk = devm_clk_get(codec->dev, "mclk");
da7219->mclk = devm_clk_get(component->dev, "mclk");
if (IS_ERR(da7219->mclk)) {
if (PTR_ERR(da7219->mclk) != -ENOENT) {
ret = PTR_ERR(da7219->mclk);
@ -1806,39 +1806,39 @@ static int da7219_probe(struct snd_soc_codec *codec)
}
/* Default PC counter to free-running */
snd_soc_update_bits(codec, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
snd_soc_component_update_bits(component, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
DA7219_PC_FREERUN_MASK);
/* Default gain ramping */
snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL,
DA7219_MIXIN_L_AMP_RAMP_EN_MASK,
DA7219_MIXIN_L_AMP_RAMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
DA7219_ADC_L_RAMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
DA7219_DAC_L_RAMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
DA7219_DAC_R_RAMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_RAMP_EN_MASK,
DA7219_HP_L_AMP_RAMP_EN_MASK);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_RAMP_EN_MASK,
DA7219_HP_R_AMP_RAMP_EN_MASK);
/* Default minimum gain on HP to avoid pops during DAPM sequencing */
snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
DA7219_HP_L_AMP_MIN_GAIN_EN_MASK,
DA7219_HP_L_AMP_MIN_GAIN_EN_MASK);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_MIN_GAIN_EN_MASK,
DA7219_HP_R_AMP_MIN_GAIN_EN_MASK);
/* Default infinite tone gen, start/stop by Kcontrol */
snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
snd_soc_component_write(component, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
/* Initialise AAD block */
ret = da7219_aad_init(codec);
ret = da7219_aad_init(component);
if (ret)
goto err_disable_reg;
@ -1850,39 +1850,39 @@ err_disable_reg:
return ret;
}
static int da7219_remove(struct snd_soc_codec *codec)
static void da7219_remove(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
da7219_aad_exit(codec);
da7219_aad_exit(component);
/* Supplies */
return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
}
#ifdef CONFIG_PM
static int da7219_suspend(struct snd_soc_codec *codec)
static int da7219_suspend(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
/* Suspend AAD if we're not a wake-up source */
if (!da7219->wakeup_source)
da7219_aad_suspend(codec);
da7219_aad_suspend(component);
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
return 0;
}
static int da7219_resume(struct snd_soc_codec *codec)
static int da7219_resume(struct snd_soc_component *component)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
/* Resume AAD if previously suspended */
if (!da7219->wakeup_source)
da7219_aad_resume(codec);
da7219_aad_resume(component);
return 0;
}
@ -1891,21 +1891,22 @@ static int da7219_resume(struct snd_soc_codec *codec)
#define da7219_resume NULL
#endif
static const struct snd_soc_codec_driver soc_codec_dev_da7219 = {
static const struct snd_soc_component_driver soc_component_dev_da7219 = {
.probe = da7219_probe,
.remove = da7219_remove,
.suspend = da7219_suspend,
.resume = da7219_resume,
.set_bias_level = da7219_set_bias_level,
.component_driver = {
.controls = da7219_snd_controls,
.num_controls = ARRAY_SIZE(da7219_snd_controls),
.dapm_widgets = da7219_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
.dapm_routes = da7219_audio_map,
.num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
},
.controls = da7219_snd_controls,
.num_controls = ARRAY_SIZE(da7219_snd_controls),
.dapm_widgets = da7219_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
.dapm_routes = da7219_audio_map,
.num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
@ -2090,7 +2091,7 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
}
}
/* Soft reset codec */
/* Soft reset component */
regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
DA7219_ACCDET_EN_MASK, 0);
regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
@ -2101,10 +2102,11 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
regcache_cache_bypass(da7219->regmap, false);
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
ret = devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_da7219,
&da7219_dai, 1);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to register da7219 codec: %d\n",
dev_err(&i2c->dev, "Failed to register da7219 component: %d\n",
ret);
}
return ret;
@ -2112,7 +2114,6 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
static int da7219_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
return 0;
}

View File

@ -822,6 +822,6 @@ struct da7219_priv {
u8 gain_ramp_ctrl;
};
int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout);
int da7219_set_pll(struct snd_soc_component *component, int source, unsigned int fout);
#endif /* __DA7219_H */

View File

@ -718,10 +718,22 @@ static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
hda_nid_t nid, unsigned int pwr_state)
{
int count;
unsigned int state;
if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) {
if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state))
snd_hdac_codec_write(&edev->hdev, nid, 0,
AC_VERB_SET_POWER_STATE, pwr_state);
if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state)) {
for (count = 0; count < 10; count++) {
snd_hdac_codec_read(&edev->hdev, nid, 0,
AC_VERB_SET_POWER_STATE,
pwr_state);
state = snd_hdac_sync_power_state(&edev->hdev,
nid, pwr_state);
if (!(state & AC_PWRST_ERROR))
break;
}
}
}
}
@ -1536,7 +1548,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin = NULL;
struct hdac_hdmi_port *hport = NULL;
struct snd_soc_codec *codec = edev->scodec;
struct snd_soc_component *component = edev->scodec;
int i;
/* Don't know how this mapping is derived */
@ -1551,7 +1563,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
* connection states are updated in anyway at the end of the resume,
* we can skip it when received during PM process.
*/
if (snd_power_get_state(codec->component.card->snd_card) !=
if (snd_power_get_state(component->card->snd_card) !=
SNDRV_CTL_POWER_D0)
return;
@ -1609,10 +1621,10 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
char kc_name[NAME_SIZE], xname[NAME_SIZE];
char *name;
int i = 0, j;
struct snd_soc_codec *codec = edev->scodec;
struct snd_soc_component *component = edev->scodec;
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
kc = devm_kcalloc(codec->dev, hdmi->num_ports,
kc = devm_kcalloc(component->dev, hdmi->num_ports,
sizeof(*kc), GFP_KERNEL);
if (!kc)
@ -1622,11 +1634,11 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
for (j = 0; j < pin->num_ports; j++) {
snprintf(xname, sizeof(xname), "hif%d-%d Jack",
pin->nid, pin->ports[j].id);
name = devm_kstrdup(codec->dev, xname, GFP_KERNEL);
name = devm_kstrdup(component->dev, xname, GFP_KERNEL);
if (!name)
return -ENOMEM;
snprintf(kc_name, sizeof(kc_name), "%s Switch", xname);
kc[i].name = devm_kstrdup(codec->dev, kc_name,
kc[i].name = devm_kstrdup(component->dev, kc_name,
GFP_KERNEL);
if (!kc[i].name)
return -ENOMEM;
@ -1644,10 +1656,10 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
return snd_soc_add_card_controls(card, kc, i);
}
int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
struct snd_soc_dapm_context *dapm)
{
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin;
struct snd_soc_dapm_widget *widgets;
@ -1722,8 +1734,8 @@ EXPORT_SYMBOL_GPL(hdac_hdmi_jack_port_init);
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
struct snd_soc_jack *jack)
{
struct snd_soc_codec *codec = dai->codec;
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pcm *pcm;
struct snd_pcm *snd_pcm;
@ -1784,16 +1796,16 @@ static void hdac_hdmi_present_sense_all_pins(struct hdac_ext_device *edev,
}
}
static int hdmi_codec_probe(struct snd_soc_codec *codec)
static int hdmi_codec_probe(struct snd_soc_component *component)
{
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(&codec->component);
snd_soc_component_get_dapm(component);
struct hdac_ext_link *hlink = NULL;
int ret;
edev->scodec = codec;
edev->scodec = component;
/*
* hold the ref while we probe, also no need to drop the ref on
@ -1834,12 +1846,11 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
return 0;
}
static int hdmi_codec_remove(struct snd_soc_codec *codec)
static void hdmi_codec_remove(struct snd_soc_component *component)
{
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
struct hdac_ext_device *edev = snd_soc_component_get_drvdata(component);
pm_runtime_disable(&edev->hdev.dev);
return 0;
}
#ifdef CONFIG_PM
@ -1891,10 +1902,12 @@ static void hdmi_codec_complete(struct device *dev)
#define hdmi_codec_complete NULL
#endif
static const struct snd_soc_codec_driver hdmi_hda_codec = {
.probe = hdmi_codec_probe,
.remove = hdmi_codec_remove,
.idle_bias_off = true,
static const struct snd_soc_component_driver hdmi_hda_codec = {
.probe = hdmi_codec_probe,
.remove = hdmi_codec_remove,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,
@ -2042,7 +2055,7 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
snd_hdac_refresh_widgets(hdev, true);
/* ASoC specific initialization */
ret = snd_soc_register_codec(&hdev->dev, &hdmi_hda_codec,
ret = devm_snd_soc_register_component(&hdev->dev, &hdmi_hda_codec,
hdmi_dais, num_dais);
snd_hdac_ext_bus_link_put(edev->ebus, hlink);
@ -2059,8 +2072,6 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
struct hdac_hdmi_port *port, *port_next;
int i;
snd_soc_unregister_codec(&edev->hdev.dev);
list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
pcm->cvt = NULL;
if (list_empty(&pcm->port_list))

View File

@ -5,6 +5,6 @@
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
struct snd_soc_jack *jack);
int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
struct snd_soc_dapm_context *dapm);
#endif /* __HDAC_HDMI_H__ */

View File

@ -914,8 +914,8 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@ -938,8 +938,8 @@ static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@ -962,8 +962,8 @@ static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@ -1244,8 +1244,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
nau8825_sema_acquire(nau8825, 3 * HZ);
@ -1329,8 +1329,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = codec_dai->component;
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
unsigned int ctrl1_val = 0, ctrl2_val = 0;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@ -1427,10 +1427,10 @@ static struct snd_soc_dai_driver nau8825_dai = {
* events will be routed to the given jack. Jack can be null to stop
* reporting.
*/
int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
int nau8825_enable_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *jack)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
struct regmap *regmap = nau8825->regmap;
nau8825->jack = jack;
@ -1952,24 +1952,22 @@ static const struct regmap_config nau8825_regmap_config = {
.num_reg_defaults = ARRAY_SIZE(nau8825_reg_defaults),
};
static int nau8825_codec_probe(struct snd_soc_codec *codec)
static int nau8825_component_probe(struct snd_soc_component *component)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
nau8825->dapm = dapm;
return 0;
}
static int nau8825_codec_remove(struct snd_soc_codec *codec)
static void nau8825_component_remove(struct snd_soc_component *component)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
/* Cancel and reset cross tak suppresstion detection funciton */
nau8825_xtalk_cancel(nau8825);
return 0;
}
/**
@ -2084,20 +2082,20 @@ static void nau8825_fll_apply(struct nau8825 *nau8825,
}
/* freq_out must be 256*Fs in order to achieve the best performance */
static int nau8825_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
static int nau8825_set_pll(struct snd_soc_component *component, int pll_id, int source,
unsigned int freq_in, unsigned int freq_out)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
struct nau8825_fll fll_param;
int ret, fs;
fs = freq_out / 256;
ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
if (ret < 0) {
dev_err(codec->dev, "Unsupported input clock %d\n", freq_in);
dev_err(component->dev, "Unsupported input clock %d\n", freq_in);
return ret;
}
dev_dbg(codec->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
dev_dbg(component->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
fll_param.fll_int, fll_param.clk_ref_div);
@ -2298,10 +2296,10 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
return 0;
}
static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
static int nau8825_set_sysclk(struct snd_soc_component *component, int clk_id,
int source, unsigned int freq, int dir)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
return nau8825_configure_sysclk(nau8825, clk_id, freq);
}
@ -2331,10 +2329,10 @@ static int nau8825_resume_setup(struct nau8825 *nau8825)
return 0;
}
static int nau8825_set_bias_level(struct snd_soc_codec *codec,
static int nau8825_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
int ret;
switch (level) {
@ -2345,11 +2343,11 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_STANDBY:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
if (nau8825->mclk_freq) {
ret = clk_prepare_enable(nau8825->mclk);
if (ret) {
dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
dev_err(nau8825->dev, "Unable to prepare component mclk\n");
return ret;
}
}
@ -2383,12 +2381,12 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
static int __maybe_unused nau8825_suspend(struct snd_soc_component *component)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
disable_irq(nau8825->irq);
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
/* Power down codec power; don't suppoet button wakeup */
snd_soc_dapm_disable_pin(nau8825->dapm, "SAR");
snd_soc_dapm_disable_pin(nau8825->dapm, "MICBIAS");
@ -2399,9 +2397,9 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
return 0;
}
static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
static int __maybe_unused nau8825_resume(struct snd_soc_component *component)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
int ret;
regcache_cache_only(nau8825->regmap, false);
@ -2415,24 +2413,25 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
return 0;
}
static const struct snd_soc_codec_driver nau8825_codec_driver = {
.probe = nau8825_codec_probe,
.remove = nau8825_codec_remove,
.set_sysclk = nau8825_set_sysclk,
.set_pll = nau8825_set_pll,
.set_bias_level = nau8825_set_bias_level,
.suspend_bias_off = true,
.suspend = nau8825_suspend,
.resume = nau8825_resume,
.component_driver = {
.controls = nau8825_controls,
.num_controls = ARRAY_SIZE(nau8825_controls),
.dapm_widgets = nau8825_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
.dapm_routes = nau8825_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
},
static const struct snd_soc_component_driver nau8825_component_driver = {
.probe = nau8825_component_probe,
.remove = nau8825_component_remove,
.set_sysclk = nau8825_set_sysclk,
.set_pll = nau8825_set_pll,
.set_bias_level = nau8825_set_bias_level,
.suspend = nau8825_suspend,
.resume = nau8825_resume,
.controls = nau8825_controls,
.num_controls = ARRAY_SIZE(nau8825_controls),
.dapm_widgets = nau8825_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
.dapm_routes = nau8825_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
.suspend_bias_off = 1,
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static void nau8825_reset_chip(struct regmap *regmap)
@ -2619,13 +2618,13 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
if (i2c->irq)
nau8825_setup_irq(nau8825);
return snd_soc_register_codec(&i2c->dev, &nau8825_codec_driver,
return devm_snd_soc_register_component(&i2c->dev,
&nau8825_component_driver,
&nau8825_dai, 1);
}
static int nau8825_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
return 0;
}

View File

@ -480,7 +480,7 @@ struct nau8825 {
bool xtalk_baktab_initialized; /* True if initialized. */
};
int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
int nau8825_enable_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *jack);

View File

@ -40,7 +40,7 @@ struct rt286_priv {
struct reg_default *index_cache;
int index_cache_size;
struct regmap *regmap;
struct snd_soc_codec *codec;
struct snd_soc_component *component;
struct rt286_platform_data pdata;
struct i2c_client *i2c;
struct snd_soc_jack *jack;
@ -187,13 +187,13 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
}
#ifdef CONFIG_PM
static void rt286_index_sync(struct snd_soc_codec *codec)
static void rt286_index_sync(struct snd_soc_component *component)
{
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
int i;
for (i = 0; i < INDEX_CACHE_SIZE; i++) {
snd_soc_write(codec, rt286->index_cache[i].reg,
snd_soc_component_write(component, rt286->index_cache[i].reg,
rt286->index_cache[i].def);
}
}
@ -220,10 +220,10 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
*hp = false;
*mic = false;
if (!rt286->codec)
if (!rt286->component)
return -EINVAL;
dapm = snd_soc_codec_get_dapm(rt286->codec);
dapm = snd_soc_component_get_dapm(rt286->component);
if (rt286->pdata.cbj_en) {
regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
@ -305,10 +305,10 @@ static void rt286_jack_detect_work(struct work_struct *work)
SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
}
int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
{
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
rt286->jack = jack;
@ -334,8 +334,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect);
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
if (rt286->clk_id == RT286_SCLK_S_MCLK)
return 1;
@ -434,15 +434,15 @@ SOC_DAPM_ENUM("SPO source", rt286_spo_enum);
static int rt286_spk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_write(codec,
snd_soc_component_write(component,
RT286_SPK_EAPD, RT286_SET_EAPD_HIGH);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_write(codec,
snd_soc_component_write(component,
RT286_SPK_EAPD, RT286_SET_EAPD_LOW);
break;
@ -456,14 +456,14 @@ static int rt286_spk_event(struct snd_soc_dapm_widget *w,
static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0x20);
snd_soc_component_write(component, RT286_SET_PIN_DMIC1, 0x20);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_write(codec, RT286_SET_PIN_DMIC1, 0);
snd_soc_component_write(component, RT286_SET_PIN_DMIC1, 0);
break;
default:
return 0;
@ -475,14 +475,14 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08);
snd_soc_component_update_bits(component, RT286_POWER_CTRL2, 0x38, 0x08);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30);
snd_soc_component_update_bits(component, RT286_POWER_CTRL2, 0x38, 0x30);
break;
default:
return 0;
@ -494,19 +494,19 @@ static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
break;
default:
@ -674,8 +674,8 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
unsigned int val = 0;
int d_len_code;
@ -687,7 +687,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
case 48000:
break;
default:
dev_err(codec->dev, "Unsupported sample rate %d\n",
dev_err(component->dev, "Unsupported sample rate %d\n",
params_rate(params));
return -EINVAL;
}
@ -695,7 +695,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
case 12288000:
case 24576000:
if (params_rate(params) != 48000) {
dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
params_rate(params), rt286->sys_clk);
return -EINVAL;
}
@ -703,7 +703,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
case 11289600:
case 22579200:
if (params_rate(params) != 44100) {
dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
params_rate(params), rt286->sys_clk);
return -EINVAL;
}
@ -714,7 +714,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
/* bit 3:0 Number of Channel */
val |= (params_channels(params) - 1);
} else {
dev_err(codec->dev, "Unsupported channels %d\n",
dev_err(component->dev, "Unsupported channels %d\n",
params_channels(params));
return -EINVAL;
}
@ -745,27 +745,27 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x0018, d_len_code << 3);
dev_dbg(codec->dev, "format val = 0x%x\n", val);
dev_dbg(component->dev, "format val = 0x%x\n", val);
snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x407f, val);
snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val);
snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x407f, val);
snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x407f, val);
return 0;
}
static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_codec *codec = dai->codec;
struct snd_soc_component *component = dai->component;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x800, 0x800);
break;
case SND_SOC_DAIFMT_CBS_CFS:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x800, 0x0);
break;
default:
@ -774,27 +774,27 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x300, 0x0);
break;
case SND_SOC_DAIFMT_LEFT_J:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x300, 0x1 << 8);
break;
case SND_SOC_DAIFMT_DSP_A:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x300, 0x2 << 8);
break;
case SND_SOC_DAIFMT_DSP_B:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x300, 0x3 << 8);
break;
default:
return -EINVAL;
}
/* bit 15 Stream Type 0:PCM 1:Non-PCM */
snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x8000, 0);
snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x8000, 0);
snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x8000, 0);
snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x8000, 0);
return 0;
}
@ -802,58 +802,58 @@ static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = dai->codec;
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
if (RT286_SCLK_S_MCLK == clk_id) {
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL2, 0x0100, 0x0);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_PLL_CTRL1, 0x20, 0x20);
} else {
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL2, 0x0100, 0x0100);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_PLL_CTRL, 0x4, 0x4);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_PLL_CTRL1, 0x20, 0x0);
}
switch (freq) {
case 19200000:
if (RT286_SCLK_S_MCLK == clk_id) {
dev_err(codec->dev, "Should not use MCLK\n");
dev_err(component->dev, "Should not use MCLK\n");
return -EINVAL;
}
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL2, 0x40, 0x40);
break;
case 24000000:
if (RT286_SCLK_S_MCLK == clk_id) {
dev_err(codec->dev, "Should not use MCLK\n");
dev_err(component->dev, "Should not use MCLK\n");
return -EINVAL;
}
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL2, 0x40, 0x0);
break;
case 12288000:
case 11289600:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL2, 0x8, 0x0);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_CLK_DIV, 0xfc1e, 0x0004);
break;
case 24576000:
case 22579200:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL2, 0x8, 0x8);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_CLK_DIV, 0xfc1e, 0x5406);
break;
default:
dev_err(codec->dev, "Unsupported system clock\n");
dev_err(component->dev, "Unsupported system clock\n");
return -EINVAL;
}
@ -865,42 +865,42 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
static int rt286_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
{
struct snd_soc_codec *codec = dai->codec;
struct snd_soc_component *component = dai->component;
dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
if (50 == ratio)
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x1000, 0x1000);
else
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_I2S_CTRL1, 0x1000, 0x0);
return 0;
}
static int rt286_set_bias_level(struct snd_soc_codec *codec,
static int rt286_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
snd_soc_write(codec,
if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
snd_soc_component_write(component,
RT286_SET_AUDIO_POWER, AC_PWRST_D0);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_DC_GAIN, 0x200, 0x200);
}
break;
case SND_SOC_BIAS_ON:
mdelay(10);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT286_DC_GAIN, 0x200, 0x0);
break;
case SND_SOC_BIAS_STANDBY:
snd_soc_write(codec,
snd_soc_component_write(component,
RT286_SET_AUDIO_POWER, AC_PWRST_D3);
break;
@ -937,11 +937,11 @@ static irqreturn_t rt286_irq(int irq, void *data)
return IRQ_HANDLED;
}
static int rt286_probe(struct snd_soc_codec *codec)
static int rt286_probe(struct snd_soc_component *component)
{
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
rt286->codec = codec;
rt286->component = component;
if (rt286->i2c->irq) {
regmap_update_bits(rt286->regmap,
@ -956,19 +956,17 @@ static int rt286_probe(struct snd_soc_codec *codec)
return 0;
}
static int rt286_remove(struct snd_soc_codec *codec)
static void rt286_remove(struct snd_soc_component *component)
{
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
cancel_delayed_work_sync(&rt286->jack_detect_work);
return 0;
}
#ifdef CONFIG_PM
static int rt286_suspend(struct snd_soc_codec *codec)
static int rt286_suspend(struct snd_soc_component *component)
{
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt286->regmap, true);
regcache_mark_dirty(rt286->regmap);
@ -976,12 +974,12 @@ static int rt286_suspend(struct snd_soc_codec *codec)
return 0;
}
static int rt286_resume(struct snd_soc_codec *codec)
static int rt286_resume(struct snd_soc_component *component)
{
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt286->regmap, false);
rt286_index_sync(codec);
rt286_index_sync(component);
regcache_sync(rt286->regmap);
return 0;
@ -1046,21 +1044,21 @@ static struct snd_soc_dai_driver rt286_dai[] = {
};
static const struct snd_soc_codec_driver soc_codec_dev_rt286 = {
.probe = rt286_probe,
.remove = rt286_remove,
.suspend = rt286_suspend,
.resume = rt286_resume,
.set_bias_level = rt286_set_bias_level,
.idle_bias_off = true,
.component_driver = {
.controls = rt286_snd_controls,
.num_controls = ARRAY_SIZE(rt286_snd_controls),
.dapm_widgets = rt286_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
.dapm_routes = rt286_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
},
static const struct snd_soc_component_driver soc_component_dev_rt286 = {
.probe = rt286_probe,
.remove = rt286_remove,
.suspend = rt286_suspend,
.resume = rt286_resume,
.set_bias_level = rt286_set_bias_level,
.controls = rt286_snd_controls,
.num_controls = ARRAY_SIZE(rt286_snd_controls),
.dapm_widgets = rt286_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
.dapm_routes = rt286_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static const struct regmap_config rt286_regmap = {
@ -1243,7 +1241,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
}
}
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt286,
ret = devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt286,
rt286_dai, ARRAY_SIZE(rt286_dai));
return ret;
@ -1255,7 +1254,6 @@ static int rt286_i2c_remove(struct i2c_client *i2c)
if (i2c->irq)
free_irq(i2c->irq, rt286);
snd_soc_unregister_codec(&i2c->dev);
return 0;
}

View File

@ -199,7 +199,7 @@ enum {
RT286_AIFS,
};
int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
#endif /* __RT286_H__ */

View File

@ -39,7 +39,7 @@ struct rt298_priv {
struct reg_default *index_cache;
int index_cache_size;
struct regmap *regmap;
struct snd_soc_codec *codec;
struct snd_soc_component *component;
struct rt298_platform_data pdata;
struct i2c_client *i2c;
struct snd_soc_jack *jack;
@ -194,13 +194,13 @@ static bool rt298_readable_register(struct device *dev, unsigned int reg)
}
#ifdef CONFIG_PM
static void rt298_index_sync(struct snd_soc_codec *codec)
static void rt298_index_sync(struct snd_soc_component *component)
{
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
int i;
for (i = 0; i < INDEX_CACHE_SIZE; i++) {
snd_soc_write(codec, rt298->index_cache[i].reg,
snd_soc_component_write(component, rt298->index_cache[i].reg,
rt298->index_cache[i].def);
}
}
@ -227,10 +227,10 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
*hp = false;
*mic = false;
if (!rt298->codec)
if (!rt298->component)
return -EINVAL;
dapm = snd_soc_codec_get_dapm(rt298->codec);
dapm = snd_soc_component_get_dapm(rt298->component);
if (rt298->pdata.cbj_en) {
regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf);
@ -323,9 +323,9 @@ static void rt298_jack_detect_work(struct work_struct *work)
SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
}
int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack)
{
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
struct snd_soc_dapm_context *dapm;
bool hp = false;
bool mic = false;
@ -334,7 +334,7 @@ int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
/* If jack in NULL, disable HS jack */
if (!jack) {
regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0);
dapm = snd_soc_codec_get_dapm(codec);
dapm = snd_soc_component_get_dapm(component);
snd_soc_dapm_disable_pin(dapm, "LDO1");
snd_soc_dapm_sync(dapm);
return 0;
@ -360,8 +360,8 @@ EXPORT_SYMBOL_GPL(rt298_mic_detect);
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
if (rt298->clk_id == RT298_SCLK_S_MCLK)
return 1;
@ -458,15 +458,15 @@ SOC_DAPM_ENUM("SPO source", rt298_spo_enum);
static int rt298_spk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_write(codec,
snd_soc_component_write(component,
RT298_SPK_EAPD, RT298_SET_EAPD_HIGH);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_write(codec,
snd_soc_component_write(component,
RT298_SPK_EAPD, RT298_SET_EAPD_LOW);
break;
@ -480,14 +480,14 @@ static int rt298_spk_event(struct snd_soc_dapm_widget *w,
static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0x20);
snd_soc_component_write(component, RT298_SET_PIN_DMIC1, 0x20);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0);
snd_soc_component_write(component, RT298_SET_PIN_DMIC1, 0);
break;
default:
return 0;
@ -499,39 +499,39 @@ static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
static int rt298_adc_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
unsigned int nid;
nid = (w->reg >> 20) & 0xff;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
0x7080, 0x7000);
/* If MCLK doesn't exist, reset AD filter */
if (!(snd_soc_read(codec, RT298_VAD_CTRL) & 0x200)) {
if (!(snd_soc_component_read32(component, RT298_VAD_CTRL) & 0x200)) {
pr_info("NO MCLK\n");
switch (nid) {
case RT298_ADC_IN1:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_D_FILTER_CTRL, 0x2, 0x2);
mdelay(10);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_D_FILTER_CTRL, 0x2, 0x0);
break;
case RT298_ADC_IN2:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_D_FILTER_CTRL, 0x4, 0x4);
mdelay(10);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_D_FILTER_CTRL, 0x4, 0x0);
break;
}
}
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
0x7080, 0x7080);
break;
@ -545,19 +545,19 @@ static int rt298_adc_event(struct snd_soc_dapm_widget *w,
static int rt298_mic1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_A_BIAS_CTRL3, 0xc000, 0x8000);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_A_BIAS_CTRL2, 0xc000, 0x8000);
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_A_BIAS_CTRL3, 0xc000, 0x0000);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_A_BIAS_CTRL2, 0xc000, 0x0000);
break;
default:
@ -745,8 +745,8 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
unsigned int val = 0;
int d_len_code;
@ -756,7 +756,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
case 48000:
break;
default:
dev_err(codec->dev, "Unsupported sample rate %d\n",
dev_err(component->dev, "Unsupported sample rate %d\n",
params_rate(params));
return -EINVAL;
}
@ -764,7 +764,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
case 12288000:
case 24576000:
if (params_rate(params) != 48000) {
dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
params_rate(params), rt298->sys_clk);
return -EINVAL;
}
@ -772,7 +772,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
case 11289600:
case 22579200:
if (params_rate(params) != 44100) {
dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
dev_err(component->dev, "Sys_clk is not matched (%d %d)\n",
params_rate(params), rt298->sys_clk);
return -EINVAL;
}
@ -783,7 +783,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
/* bit 3:0 Number of Channel */
val |= (params_channels(params) - 1);
} else {
dev_err(codec->dev, "Unsupported channels %d\n",
dev_err(component->dev, "Unsupported channels %d\n",
params_channels(params));
return -EINVAL;
}
@ -814,27 +814,27 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x0018, d_len_code << 3);
dev_dbg(codec->dev, "format val = 0x%x\n", val);
dev_dbg(component->dev, "format val = 0x%x\n", val);
snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x407f, val);
snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x407f, val);
snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x407f, val);
snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x407f, val);
return 0;
}
static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_codec *codec = dai->codec;
struct snd_soc_component *component = dai->component;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x800, 0x800);
break;
case SND_SOC_DAIFMT_CBS_CFS:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x800, 0x0);
break;
default:
@ -843,27 +843,27 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x300, 0x0);
break;
case SND_SOC_DAIFMT_LEFT_J:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x300, 0x1 << 8);
break;
case SND_SOC_DAIFMT_DSP_A:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x300, 0x2 << 8);
break;
case SND_SOC_DAIFMT_DSP_B:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x300, 0x3 << 8);
break;
default:
return -EINVAL;
}
/* bit 15 Stream Type 0:PCM 1:Non-PCM */
snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x8000, 0);
snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x8000, 0);
snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x8000, 0);
snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x8000, 0);
return 0;
}
@ -871,56 +871,56 @@ static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = dai->codec;
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_component *component = dai->component;
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
dev_dbg(component->dev, "%s freq=%d\n", __func__, freq);
if (RT298_SCLK_S_MCLK == clk_id) {
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL2, 0x0100, 0x0);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_PLL_CTRL1, 0x20, 0x20);
} else {
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL2, 0x0100, 0x0100);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_PLL_CTRL1, 0x20, 0x0);
}
switch (freq) {
case 19200000:
if (RT298_SCLK_S_MCLK == clk_id) {
dev_err(codec->dev, "Should not use MCLK\n");
dev_err(component->dev, "Should not use MCLK\n");
return -EINVAL;
}
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL2, 0x40, 0x40);
break;
case 24000000:
if (RT298_SCLK_S_MCLK == clk_id) {
dev_err(codec->dev, "Should not use MCLK\n");
dev_err(component->dev, "Should not use MCLK\n");
return -EINVAL;
}
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL2, 0x40, 0x0);
break;
case 12288000:
case 11289600:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL2, 0x8, 0x0);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_CLK_DIV, 0xfc1e, 0x0004);
break;
case 24576000:
case 22579200:
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL2, 0x8, 0x8);
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_CLK_DIV, 0xfc1e, 0x5406);
break;
default:
dev_err(codec->dev, "Unsupported system clock\n");
dev_err(component->dev, "Unsupported system clock\n");
return -EINVAL;
}
@ -932,39 +932,39 @@ static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
static int rt298_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
{
struct snd_soc_codec *codec = dai->codec;
struct snd_soc_component *component = dai->component;
dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
if (50 == ratio)
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x1000, 0x1000);
else
snd_soc_update_bits(codec,
snd_soc_component_update_bits(component,
RT298_I2S_CTRL1, 0x1000, 0x0);
return 0;
}
static int rt298_set_bias_level(struct snd_soc_codec *codec,
static int rt298_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY ==
snd_soc_codec_get_bias_level(codec)) {
snd_soc_write(codec,
snd_soc_component_get_bias_level(component)) {
snd_soc_component_write(component,
RT298_SET_AUDIO_POWER, AC_PWRST_D0);
snd_soc_update_bits(codec, 0x0d, 0x200, 0x200);
snd_soc_update_bits(codec, 0x52, 0x80, 0x0);
snd_soc_component_update_bits(component, 0x0d, 0x200, 0x200);
snd_soc_component_update_bits(component, 0x52, 0x80, 0x0);
mdelay(20);
snd_soc_update_bits(codec, 0x0d, 0x200, 0x0);
snd_soc_update_bits(codec, 0x52, 0x80, 0x80);
snd_soc_component_update_bits(component, 0x0d, 0x200, 0x0);
snd_soc_component_update_bits(component, 0x52, 0x80, 0x80);
}
break;
case SND_SOC_BIAS_STANDBY:
snd_soc_write(codec,
snd_soc_component_write(component,
RT298_SET_AUDIO_POWER, AC_PWRST_D3);
break;
@ -1003,11 +1003,11 @@ static irqreturn_t rt298_irq(int irq, void *data)
return IRQ_HANDLED;
}
static int rt298_probe(struct snd_soc_codec *codec)
static int rt298_probe(struct snd_soc_component *component)
{
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
rt298->codec = codec;
rt298->component = component;
if (rt298->i2c->irq) {
regmap_update_bits(rt298->regmap,
@ -1022,19 +1022,17 @@ static int rt298_probe(struct snd_soc_codec *codec)
return 0;
}
static int rt298_remove(struct snd_soc_codec *codec)
static void rt298_remove(struct snd_soc_component *component)
{
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
cancel_delayed_work_sync(&rt298->jack_detect_work);
return 0;
}
#ifdef CONFIG_PM
static int rt298_suspend(struct snd_soc_codec *codec)
static int rt298_suspend(struct snd_soc_component *component)
{
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
rt298->is_hp_in = -1;
regcache_cache_only(rt298->regmap, true);
@ -1043,12 +1041,12 @@ static int rt298_suspend(struct snd_soc_codec *codec)
return 0;
}
static int rt298_resume(struct snd_soc_codec *codec)
static int rt298_resume(struct snd_soc_component *component)
{
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt298->regmap, false);
rt298_index_sync(codec);
rt298_index_sync(component);
regcache_sync(rt298->regmap);
return 0;
@ -1113,21 +1111,21 @@ static struct snd_soc_dai_driver rt298_dai[] = {
};
static const struct snd_soc_codec_driver soc_codec_dev_rt298 = {
.probe = rt298_probe,
.remove = rt298_remove,
.suspend = rt298_suspend,
.resume = rt298_resume,
.set_bias_level = rt298_set_bias_level,
.idle_bias_off = true,
.component_driver = {
.controls = rt298_snd_controls,
.num_controls = ARRAY_SIZE(rt298_snd_controls),
.dapm_widgets = rt298_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets),
.dapm_routes = rt298_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes),
},
static const struct snd_soc_component_driver soc_component_dev_rt298 = {
.probe = rt298_probe,
.remove = rt298_remove,
.suspend = rt298_suspend,
.resume = rt298_resume,
.set_bias_level = rt298_set_bias_level,
.controls = rt298_snd_controls,
.num_controls = ARRAY_SIZE(rt298_snd_controls),
.dapm_widgets = rt298_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets),
.dapm_routes = rt298_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes),
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static const struct regmap_config rt298_regmap = {
@ -1288,7 +1286,8 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
}
}
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt298,
ret = devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt298,
rt298_dai, ARRAY_SIZE(rt298_dai));
return ret;
@ -1300,7 +1299,6 @@ static int rt298_i2c_remove(struct i2c_client *i2c)
if (i2c->irq)
free_irq(i2c->irq, rt298);
snd_soc_unregister_codec(&i2c->dev);
return 0;
}

View File

@ -210,7 +210,7 @@ enum {
RT298_AIFS,
};
int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack);
#endif /* __RT298_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -138,6 +138,7 @@
/* Index of Codec Private Register definition */
#define RT5651_BIAS_CUR1 0x12
#define RT5651_BIAS_CUR3 0x14
#define RT5651_BIAS_CUR4 0x15
#define RT5651_CLSD_INT_REG1 0x1c
#define RT5651_CHPUMP_INT_REG1 0x24
#define RT5651_MAMP_INT_REG2 0x37
@ -1966,6 +1967,15 @@
#define RT5651_D_GATE_EN_SFT 0
/* Codec Private Register definition */
/* MIC Over current threshold scale factor (0x15) */
#define RT5651_MIC_OVCD_SF_MASK (0x3 << 8)
#define RT5651_MIC_OVCD_SF_SFT 8
#define RT5651_MIC_OVCD_SF_0P5 (0x0 << 8)
#define RT5651_MIC_OVCD_SF_0P75 (0x1 << 8)
#define RT5651_MIC_OVCD_SF_1P0 (0x2 << 8)
#define RT5651_MIC_OVCD_SF_1P5 (0x3 << 8)
/* 3D Speaker Control (0x63) */
#define RT5651_3D_SPK_MASK (0x1 << 15)
#define RT5651_3D_SPK_SFT 15
@ -2059,12 +2069,15 @@ struct rt5651_pll_code {
};
struct rt5651_priv {
struct snd_soc_codec *codec;
struct rt5651_platform_data pdata;
struct snd_soc_component *component;
struct regmap *regmap;
struct snd_soc_jack *hp_jack;
struct delayed_work jack_detect_work;
struct work_struct jack_detect_work;
enum rt5651_jd_src jd_src;
unsigned int ovcd_th;
unsigned int ovcd_sf;
int irq;
int sysclk;
int sysclk_src;
int lrck[RT5651_AIFS];
@ -2079,6 +2092,4 @@ struct rt5651_priv {
bool hp_mute;
};
int rt5651_set_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *hp_jack);
#endif /* __RT5651_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1125,9 +1125,9 @@ enum {
RT5663_AD_STEREO_FILTER = 0x2,
};
int rt5663_set_jack_detect(struct snd_soc_codec *codec,
int rt5663_set_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *hs_jack);
int rt5663_sel_asrc_clk_src(struct snd_soc_codec *codec,
int rt5663_sel_asrc_clk_src(struct snd_soc_component *component,
unsigned int filter_mask, unsigned int clk_src);
#endif /* __RT5663_H__ */

View File

@ -449,6 +449,13 @@ static int intel_sst_suspend(struct device *dev)
dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
return -EBUSY;
}
if (ctx->pdata->streams_lost_on_suspend) {
stream->resume_status = stream->status;
stream->resume_prev = stream->prev;
if (stream->status != STREAM_UN_INIT)
sst_free_stream(ctx, i);
}
}
synchronize_irq(ctx->irq_num);
flush_workqueue(ctx->post_msg_wq);
@ -509,8 +516,8 @@ static int intel_sst_resume(struct device *dev)
{
struct intel_sst_drv *ctx = dev_get_drvdata(dev);
struct sst_fw_save *fw_save = ctx->fw_save;
int ret = 0;
struct sst_block *block;
int i, ret = 0;
if (!fw_save)
return 0;
@ -550,6 +557,21 @@ static int intel_sst_resume(struct device *dev)
sst_set_fw_state_locked(ctx, SST_FW_RUNNING);
}
if (ctx->pdata->streams_lost_on_suspend) {
for (i = 1; i <= ctx->info.max_streams; i++) {
struct stream_info *stream = &ctx->streams[i];
if (stream->resume_status != STREAM_UN_INIT) {
dev_dbg(ctx->dev, "Re-allocing stream %d status %d prev %d\n",
i, stream->resume_status,
stream->resume_prev);
sst_realloc_stream(ctx, i);
stream->status = stream->resume_status;
stream->prev = stream->resume_prev;
}
}
}
sst_free_block(ctx, block);
return ret;
}

View File

@ -65,9 +65,7 @@ enum sst_stream_states {
STREAM_UN_INIT = 0, /* Freed/Not used stream */
STREAM_RUNNING = 1, /* Running */
STREAM_PAUSED = 2, /* Paused stream */
STREAM_DECODE = 3, /* stream is in decoding only state */
STREAM_INIT = 4, /* stream init, waiting for data */
STREAM_RESET = 5, /* force reset on recovery */
STREAM_INIT = 3, /* stream init, waiting for data */
};
enum sst_ram_type {
@ -181,22 +179,22 @@ struct sst_block {
*
* @status : stream current state
* @prev : stream prev state
* @ops : stream operation pb/cp/drm...
* @bufs: stream buffer list
* @resume_status : stream current state to restore on resume
* @resume_prev : stream prev state to restore on resume
* @lock : stream mutex for protecting state
* @alloc_param : parameters used for stream (re-)allocation
* @pcm_substream : PCM substream
* @period_elapsed : PCM period elapsed callback
* @sfreq : stream sampling freq
* @str_type : stream type
* @cumm_bytes : cummulative bytes decoded
* @str_type : stream type
* @src : stream source
*/
struct stream_info {
unsigned int status;
unsigned int prev;
unsigned int ops;
unsigned int resume_status;
unsigned int resume_prev;
struct mutex lock;
struct snd_sst_alloc_mrfld alloc_param;
void *pcm_substream;
void (*period_elapsed)(void *pcm_substream);
@ -212,7 +210,6 @@ struct stream_info {
unsigned int num_ch;
unsigned int pipe_id;
unsigned int str_id;
unsigned int task_id;
};
@ -438,6 +435,7 @@ struct intel_sst_ops {
void (*post_download)(struct intel_sst_drv *sst);
};
int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);
int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int id);
int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int id);
int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int id);
@ -501,8 +499,6 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
void sst_process_pending_msg(struct work_struct *work);
int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx);
void sst_init_stream(struct stream_info *stream,
int codec, int sst_id, int ops, u8 slot);
int sst_validate_strid(struct intel_sst_drv *sst_drv_ctx, int str_id);
struct stream_info *get_stream_info(struct intel_sst_drv *sst_drv_ctx,
int str_id);

View File

@ -143,10 +143,11 @@ static struct sst_platform_info byt_rvp_platform_data = {
.lib_info = &byt_lib_dnld_info,
.res_info = &byt_rvp_res_info,
.platform = "sst-mfld-platform",
.streams_lost_on_suspend = true,
};
/* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail,
* so pdata is same as Baytrail.
* so pdata is same as Baytrail, minus the streams_lost_on_suspend quirk.
*/
static struct sst_platform_info chv_platform_data = {
.probe_data = &byt_fwparse_info,

View File

@ -238,16 +238,7 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id)
return -EINVAL;
}
if (stream->status == STREAM_RESET) {
dev_dbg(dev, "stream in reset state...\n");
stream->status = STREAM_UN_INIT;
retval = 0;
goto put;
}
retval = sst_free_stream(ctx, str_id);
put:
stream->compr_cb_param = NULL;
stream->compr_cb = NULL;
@ -256,7 +247,6 @@ put:
dev_dbg(dev, "End\n");
return retval;
}
static int sst_cdev_ack(struct device *dev, unsigned int str_id,
@ -486,16 +476,7 @@ static int sst_close_pcm_stream(struct device *dev, unsigned int str_id)
return -EINVAL;
}
if (stream->status == STREAM_RESET) {
/* silently fail here as we have cleaned the stream earlier */
dev_dbg(ctx->dev, "stream in reset state...\n");
retval = 0;
goto put;
}
retval = free_stream_context(ctx, str_id);
put:
stream->pcm_substream = NULL;
stream->status = STREAM_UN_INIT;
stream->period_elapsed = NULL;

View File

@ -360,14 +360,6 @@ int sst_assign_pvt_id(struct intel_sst_drv *drv)
return local;
}
void sst_init_stream(struct stream_info *stream,
int codec, int sst_id, int ops, u8 slot)
{
stream->status = STREAM_INIT;
stream->prev = STREAM_UN_INIT;
stream->ops = ops;
}
int sst_validate_strid(
struct intel_sst_drv *sst_drv_ctx, int str_id)
{

View File

@ -35,29 +35,31 @@
int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
{
struct snd_sst_alloc_mrfld alloc_param;
struct snd_pcm_params *pcm_params;
struct snd_sst_params *str_params;
struct snd_sst_tstamp fw_tstamp;
struct stream_info *str_info;
struct snd_sst_alloc_response *response;
unsigned int str_id, pipe_id, task_id;
int i, num_ch, ret = 0;
void *data = NULL;
int i, num_ch, str_id;
dev_dbg(sst_drv_ctx->dev, "Enter\n");
str_params = (struct snd_sst_params *)params;
memset(&alloc_param, 0, sizeof(alloc_param));
alloc_param.operation = str_params->ops;
alloc_param.codec_type = str_params->codec;
alloc_param.sg_count = str_params->aparams.sg_count;
alloc_param.ring_buf_info[0].addr =
str_params->aparams.ring_buf_info[0].addr;
alloc_param.ring_buf_info[0].size =
str_params->aparams.ring_buf_info[0].size;
alloc_param.frag_size = str_params->aparams.frag_size;
str_id = str_params->stream_id;
str_info = get_stream_info(sst_drv_ctx, str_id);
if (!str_info)
return -EINVAL;
memcpy(&alloc_param.codec_params, &str_params->sparams,
memset(&str_info->alloc_param, 0, sizeof(str_info->alloc_param));
str_info->alloc_param.operation = str_params->ops;
str_info->alloc_param.codec_type = str_params->codec;
str_info->alloc_param.sg_count = str_params->aparams.sg_count;
str_info->alloc_param.ring_buf_info[0].addr =
str_params->aparams.ring_buf_info[0].addr;
str_info->alloc_param.ring_buf_info[0].size =
str_params->aparams.ring_buf_info[0].size;
str_info->alloc_param.frag_size = str_params->aparams.frag_size;
memcpy(&str_info->alloc_param.codec_params, &str_params->sparams,
sizeof(struct snd_sst_stream_params));
/*
@ -67,47 +69,62 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
* Currently hardcoding as per FW reqm.
*/
num_ch = sst_get_num_channel(str_params);
pcm_params = &str_info->alloc_param.codec_params.uc.pcm_params;
for (i = 0; i < 8; i++) {
if (i < num_ch)
alloc_param.codec_params.uc.pcm_params.channel_map[i] = i;
pcm_params->channel_map[i] = i;
else
alloc_param.codec_params.uc.pcm_params.channel_map[i] = 0xFF;
pcm_params->channel_map[i] = 0xff;
}
str_id = str_params->stream_id;
str_info = get_stream_info(sst_drv_ctx, str_id);
if (str_info == NULL) {
dev_err(sst_drv_ctx->dev, "get stream info returned null\n");
return -EINVAL;
}
pipe_id = str_params->device_type;
task_id = str_params->task;
sst_drv_ctx->streams[str_id].pipe_id = pipe_id;
sst_drv_ctx->streams[str_id].task_id = task_id;
sst_drv_ctx->streams[str_id].status = STREAM_INIT;
sst_drv_ctx->streams[str_id].prev = STREAM_UN_INIT;
sst_drv_ctx->streams[str_id].pipe_id = str_params->device_type;
sst_drv_ctx->streams[str_id].task_id = str_params->task;
sst_drv_ctx->streams[str_id].num_ch = num_ch;
if (sst_drv_ctx->info.lpe_viewpt_rqd)
alloc_param.ts = sst_drv_ctx->info.mailbox_start +
str_info->alloc_param.ts = sst_drv_ctx->info.mailbox_start +
sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
else
alloc_param.ts = sst_drv_ctx->mailbox_add +
str_info->alloc_param.ts = sst_drv_ctx->mailbox_add +
sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
dev_dbg(sst_drv_ctx->dev, "alloc tstamp location = 0x%x\n",
alloc_param.ts);
str_info->alloc_param.ts);
dev_dbg(sst_drv_ctx->dev, "assigned pipe id 0x%x to task %d\n",
pipe_id, task_id);
str_info->pipe_id, str_info->task_id);
/* allocate device type context */
sst_init_stream(&sst_drv_ctx->streams[str_id], alloc_param.codec_type,
str_id, alloc_param.operation, 0);
return sst_realloc_stream(sst_drv_ctx, str_id);
}
/**
* sst_realloc_stream - Send msg for (re-)allocating a stream using the
* @sst_drv_ctx intel_sst_drv context pointer
* @str_id: stream ID
*
* Send a msg for (re-)allocating a stream using the parameters previously
* passed to sst_alloc_stream_mrfld() for the same stream ID.
* Return: 0 or negative errno value.
*/
int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
{
struct snd_sst_alloc_response *response;
struct stream_info *str_info;
void *data = NULL;
int ret;
str_info = get_stream_info(sst_drv_ctx, str_id);
if (!str_info)
return -EINVAL;
dev_dbg(sst_drv_ctx->dev, "Alloc for str %d pipe %#x\n",
str_id, pipe_id);
ret = sst_prepare_and_post_msg(sst_drv_ctx, task_id, IPC_CMD,
IPC_IA_ALLOC_STREAM_MRFLD, pipe_id, sizeof(alloc_param),
&alloc_param, &data, true, true, false, true);
str_id, str_info->pipe_id);
ret = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD,
IPC_IA_ALLOC_STREAM_MRFLD, str_info->pipe_id,
sizeof(str_info->alloc_param), &str_info->alloc_param,
&data, true, true, false, true);
if (ret < 0) {
dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
@ -253,7 +270,7 @@ int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
if (retval == 0) {
str_info->prev = str_info->status;
str_info->status = STREAM_PAUSED;
} else if (retval == SST_ERR_INVALID_STREAM_ID) {
} else if (retval == -SST_ERR_INVALID_STREAM_ID) {
retval = -EINVAL;
mutex_lock(&sst_drv_ctx->sst_lock);
sst_clean_stream(str_info);
@ -285,7 +302,29 @@ int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
return -EINVAL;
if (str_info->status == STREAM_RUNNING)
return 0;
if (str_info->status == STREAM_PAUSED) {
if (str_info->resume_status == STREAM_PAUSED &&
str_info->resume_prev == STREAM_RUNNING) {
/*
* Stream was running before suspend and re-created on resume,
* start it to get back to running state.
*/
dev_dbg(sst_drv_ctx->dev, "restart recreated stream after resume\n");
str_info->status = STREAM_RUNNING;
str_info->prev = STREAM_PAUSED;
retval = sst_start_stream(sst_drv_ctx, str_id);
str_info->resume_status = STREAM_UN_INIT;
} else if (str_info->resume_status == STREAM_PAUSED &&
str_info->resume_prev == STREAM_INIT) {
/*
* Stream was idle before suspend and re-created on resume,
* keep it as is.
*/
dev_dbg(sst_drv_ctx->dev, "leaving recreated stream idle after resume\n");
str_info->status = STREAM_INIT;
str_info->prev = STREAM_PAUSED;
str_info->resume_status = STREAM_UN_INIT;
} else if (str_info->status == STREAM_PAUSED) {
retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id,
IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD,
str_info->pipe_id, 0, NULL, NULL,

View File

@ -125,6 +125,17 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_CHT_BSW_NAU8824_MACH
tristate "Cherrytrail & Braswell with NAU88L24 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_ACPI
select SND_SOC_NAU8824
help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with NAU88L24 audio codec.
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
@ -256,6 +267,20 @@ config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
create an alsa sound card for RT5663 + RT5514 + MAX98927.
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH
tristate "KBL with DA7219 and MAX98357A in I2S Mode"
depends on MFD_INTEL_LPSS && I2C && ACPI
select SND_SOC_DA7219
select SND_SOC_MAX98357A
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for DA7219 + MAX98357A I2S audio codec.
Say Y if you have such a device.
If unsure select "N".
endif ## SND_SOC_INTEL_SKYLAKE
endif ## SND_SOC_INTEL_MACH

View File

@ -11,9 +11,11 @@ snd-soc-sst-bytcr-rt5651-objs := bytcr_rt5651.o
snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
snd-soc-sst-cht-bsw-nau8824-objs := cht_bsw_nau8824.o
snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o
snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
snd-soc-skl_rt286-objs := skl_rt286.o
@ -32,9 +34,11 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH) += snd-soc-sst-bytcr-rt5651.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH) += snd-soc-sst-cht-bsw-nau8824.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) += snd-soc-sst-byt-cht-es8316.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH) += snd-soc-kbl_da7219_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o
obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH) += snd-soc-kbl_rt5663_rt5514_max98927.o
obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o

View File

@ -78,7 +78,7 @@ static const struct snd_soc_dapm_route broadwell_rt286_map[] = {
static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
int ret = 0;
ret = snd_soc_card_jack_new(rtd->card, "Headset",
SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset,
@ -86,7 +86,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
if (ret)
return ret;
rt286_mic_detect(codec, &broadwell_headset);
rt286_mic_detect(component, &broadwell_headset);
return 0;
}
@ -225,10 +225,9 @@ static int broadwell_suspend(struct snd_soc_card *card){
list_for_each_entry(component, &card->component_dev_list, card_list) {
if (!strcmp(component->name, "i2c-INT343A:00")) {
struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
rt286_mic_detect(codec, NULL);
dev_dbg(component->dev, "disabling jack detect before going to suspend.\n");
rt286_mic_detect(component, NULL);
break;
}
}
@ -240,10 +239,9 @@ static int broadwell_resume(struct snd_soc_card *card){
list_for_each_entry(component, &card->component_dev_list, card_list) {
if (!strcmp(component->name, "i2c-INT343A:00")) {
struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
dev_dbg(codec->dev, "enabling jack detect for resume.\n");
rt286_mic_detect(codec, &broadwell_headset);
dev_dbg(component->dev, "enabling jack detect for resume.\n");
rt286_mic_detect(component, &broadwell_headset);
break;
}
}

View File

@ -169,7 +169,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
/* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000,
@ -192,7 +192,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
da7219_aad_jack_det(codec, &broxton_headset);
da7219_aad_jack_det(component, &broxton_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
@ -522,12 +522,12 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
{
struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
struct bxt_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -545,10 +545,10 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/* broxton audio machine driver for SPT + da7219 */

View File

@ -146,6 +146,9 @@ static const struct snd_soc_dapm_route geminilake_rt298_map[] = {
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
{ "DMIC01 Rx", NULL, "Capture" },
{ "dmic_voice", NULL, "DMIC16k Rx" },
{ "DMIC16k Rx", NULL, "Capture" },
{ "hifi3", NULL, "iDisp3 Tx"},
{ "iDisp3 Tx", NULL, "iDisp3_out"},
{ "hifi2", NULL, "iDisp2 Tx"},
@ -167,7 +170,7 @@ static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd)
static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
int ret = 0;
ret = snd_soc_card_jack_new(rtd->card, "Headset",
@ -178,7 +181,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd)
if (ret)
return ret;
rt298_mic_detect(codec, &broxton_headset);
rt298_mic_detect(component, &broxton_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
@ -456,6 +459,18 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
.dpcm_capture = 1,
.no_pcm = 1,
},
{
.name = "dmic16k",
.id = 2,
.cpu_dai_name = "DMIC16k Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
.platform_name = "0000:00:0e.0",
.be_hw_params_fixup = broxton_dmic_fixup,
.ignore_suspend = 1,
.dpcm_capture = 1,
.no_pcm = 1,
},
{
.name = "iDisp1",
.id = 3,
@ -496,12 +511,12 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
{
struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
struct bxt_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -519,10 +534,10 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}

View File

@ -18,13 +18,16 @@
*/
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/slab.h>
#include <asm/cpu_device_id.h>
#include <asm/platform_sst_audio.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@ -39,22 +42,55 @@ enum {
BYT_RT5651_IN1_MAP,
BYT_RT5651_IN2_MAP,
BYT_RT5651_IN1_IN2_MAP,
BYT_RT5651_IN3_MAP,
BYT_RT5651_IN1_HS_IN3_MAP,
BYT_RT5651_IN2_HS_IN3_MAP,
};
#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(7, 0))
#define BYT_RT5651_DMIC_EN BIT(16)
#define BYT_RT5651_MCLK_EN BIT(17)
#define BYT_RT5651_MCLK_25MHZ BIT(18)
enum {
BYT_RT5651_JD_NULL = (RT5651_JD_NULL << 4),
BYT_RT5651_JD1_1 = (RT5651_JD1_1 << 4),
BYT_RT5651_JD1_2 = (RT5651_JD1_2 << 4),
BYT_RT5651_JD2 = (RT5651_JD2 << 4),
};
enum {
BYT_RT5651_OVCD_TH_600UA = (6 << 8),
BYT_RT5651_OVCD_TH_1500UA = (15 << 8),
BYT_RT5651_OVCD_TH_2000UA = (20 << 8),
};
enum {
BYT_RT5651_OVCD_SF_0P5 = (RT5651_OVCD_SF_0P5 << 13),
BYT_RT5651_OVCD_SF_0P75 = (RT5651_OVCD_SF_0P75 << 13),
BYT_RT5651_OVCD_SF_1P0 = (RT5651_OVCD_SF_1P0 << 13),
BYT_RT5651_OVCD_SF_1P5 = (RT5651_OVCD_SF_1P5 << 13),
};
#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(3, 0))
#define BYT_RT5651_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
#define BYT_RT5651_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
#define BYT_RT5651_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
#define BYT_RT5651_DMIC_EN BIT(16)
#define BYT_RT5651_MCLK_EN BIT(17)
#define BYT_RT5651_MCLK_25MHZ BIT(18)
#define BYT_RT5651_SSP2_AIF2 BIT(19) /* default is using AIF1 */
#define BYT_RT5651_SSP0_AIF1 BIT(20)
#define BYT_RT5651_SSP0_AIF2 BIT(21)
/* jack-detect-source + dmic-en + ovcd-th + -sf + terminating empty entry */
#define MAX_NO_PROPS 5
struct byt_rt5651_private {
struct clk *mclk;
struct snd_soc_jack jack;
};
static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP |
BYT_RT5651_DMIC_EN |
BYT_RT5651_MCLK_EN;
/* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
static unsigned long byt_rt5651_quirk = BYT_RT5651_MCLK_EN |
BYT_RT5651_JD1_1 |
BYT_RT5651_OVCD_TH_2000UA |
BYT_RT5651_OVCD_SF_0P75 |
BYT_RT5651_IN2_HS_IN3_MAP;
static void log_quirks(struct device *dev)
{
@ -64,17 +100,66 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk IN1_MAP enabled");
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
dev_info(dev, "quirk IN2_MAP enabled");
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN3_MAP)
dev_info(dev, "quirk IN3_MAP enabled");
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_HS_IN3_MAP)
dev_info(dev, "quirk IN1_HS_IN3_MAP enabled");
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_HS_IN3_MAP)
dev_info(dev, "quirk IN2_HS_IN3_MAP enabled");
if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
BYT_RT5651_JDSRC(byt_rt5651_quirk));
dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
}
if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
dev_info(dev, "quirk DMIC enabled");
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
dev_info(dev, "quirk MCLK_EN enabled");
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
dev_info(dev, "quirk MCLK_25MHZ enabled");
if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2)
dev_info(dev, "quirk SSP2_AIF2 enabled\n");
if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1)
dev_info(dev, "quirk SSP0_AIF1 enabled\n");
if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)
dev_info(dev, "quirk SSP0_AIF2 enabled\n");
}
#define BYT_CODEC_DAI1 "rt5651-aif1"
#define BYT_CODEC_DAI2 "rt5651-aif2"
static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
int rate, int bclk_ratio)
{
int clk_id, clk_freq, ret;
/* Configure the PLL before selecting it */
if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
clk_id = RT5651_PLL1_S_BCLK1,
clk_freq = rate * bclk_ratio;
} else {
clk_id = RT5651_PLL1_S_MCLK;
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
clk_freq = 25000000;
else
clk_freq = 19200000;
}
ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, rate * 512);
if (ret < 0) {
dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
return ret;
}
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
rate * 512, SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
return ret;
}
return 0;
}
static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
@ -86,6 +171,8 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
int ret;
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
if (!codec_dai)
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
if (!codec_dai) {
dev_err(card->dev,
"Codec dai not found; Unable to set platform clock\n");
@ -101,9 +188,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
return ret;
}
}
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
48000 * 512,
SND_SOC_CLOCK_IN);
ret = byt_rt5651_prepare_and_enable_pll1(codec_dai, 48000, 50);
} else {
/*
* Set codec clock source to internal clock before
@ -145,13 +230,6 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
{"Speaker", NULL, "Platform Clock"},
{"Line In", NULL, "Platform Clock"},
{"AIF1 Playback", NULL, "ssp2 Tx"},
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
{"codec_in0", NULL, "ssp2 Rx"},
{"codec_in1", NULL, "ssp2 Rx"},
{"ssp2 Rx", NULL, "AIF1 Capture"},
{"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
{"Headphone", NULL, "HPOL"},
{"Headphone", NULL, "HPOR"},
@ -170,8 +248,8 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
{"Internal Mic", NULL, "micbias1"},
{"IN2P", NULL, "Headset Mic"},
{"IN1P", NULL, "Internal Mic"},
{"IN2P", NULL, "Headset Mic"},
};
static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
@ -187,10 +265,52 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map[] = {
{"IN3P", NULL, "Headset Mic"},
};
static const struct snd_soc_dapm_route byt_rt5651_intmic_in3_map[] = {
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_hs_in3_map[] = {
{"Internal Mic", NULL, "micbias1"},
{"IN3P", NULL, "Headset Mic"},
{"IN1P", NULL, "Internal Mic"},
{"IN3P", NULL, "Headset Mic"},
};
static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_hs_in3_map[] = {
{"Internal Mic", NULL, "micbias1"},
{"IN2P", NULL, "Internal Mic"},
{"IN3P", NULL, "Headset Mic"},
};
static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif1_map[] = {
{"ssp0 Tx", NULL, "modem_out"},
{"modem_in", NULL, "ssp0 Rx"},
{"AIF1 Playback", NULL, "ssp0 Tx"},
{"ssp0 Rx", NULL, "AIF1 Capture"},
};
static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif2_map[] = {
{"ssp0 Tx", NULL, "modem_out"},
{"modem_in", NULL, "ssp0 Rx"},
{"AIF2 Playback", NULL, "ssp0 Tx"},
{"ssp0 Rx", NULL, "AIF2 Capture"},
};
static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif1_map[] = {
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
{"codec_in0", NULL, "ssp2 Rx"},
{"codec_in1", NULL, "ssp2 Rx"},
{"AIF1 Playback", NULL, "ssp2 Tx"},
{"ssp2 Rx", NULL, "AIF1 Capture"},
};
static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif2_map[] = {
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
{"codec_in0", NULL, "ssp2 Rx"},
{"codec_in1", NULL, "ssp2 Rx"},
{"AIF2 Playback", NULL, "ssp2 Tx"},
{"ssp2 Rx", NULL, "AIF2 Capture"},
};
static const struct snd_kcontrol_new byt_rt5651_controls[] = {
@ -217,44 +337,16 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
snd_pcm_format_t format = params_format(params);
int rate = params_rate(params);
int bclk_ratio;
snd_soc_dai_set_bclk_ratio(codec_dai, 50);
if (format == SNDRV_PCM_FORMAT_S16_LE)
bclk_ratio = 32;
else
bclk_ratio = 50;
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
params_rate(params) * 512,
SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(rtd->dev, "can't set codec clock %d\n", ret);
return ret;
}
if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
/* 2x25 bit slots on SSP2 */
ret = snd_soc_dai_set_pll(codec_dai, 0,
RT5651_PLL1_S_BCLK1,
params_rate(params) * 50,
params_rate(params) * 512);
} else {
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) {
ret = snd_soc_dai_set_pll(codec_dai, 0,
RT5651_PLL1_S_MCLK,
25000000,
params_rate(params) * 512);
} else {
ret = snd_soc_dai_set_pll(codec_dai, 0,
RT5651_PLL1_S_MCLK,
19200000,
params_rate(params) * 512);
}
}
if (ret < 0) {
dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
return ret;
}
return 0;
return byt_rt5651_prepare_and_enable_pll1(codec_dai, rate, bclk_ratio);
}
static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
@ -270,7 +362,7 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
},
.driver_data = (void *)(BYT_RT5651_IN3_MAP),
.driver_data = (void *)(BYT_RT5651_IN1_HS_IN3_MAP),
},
{
.callback = byt_rt5651_quirk_cb,
@ -279,7 +371,7 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"),
},
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
BYT_RT5651_IN3_MAP),
BYT_RT5651_IN1_HS_IN3_MAP),
},
{
.callback = byt_rt5651_quirk_cb,
@ -288,15 +380,76 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
},
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
BYT_RT5651_JD1_1 |
BYT_RT5651_OVCD_TH_2000UA |
BYT_RT5651_OVCD_SF_0P75 |
BYT_RT5651_IN1_IN2_MAP),
},
{
/* Chuwi Vi8 Plus (CWI519) */
.callback = byt_rt5651_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
DMI_MATCH(DMI_PRODUCT_NAME, "D2D3_Vi8A1"),
},
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
BYT_RT5651_JD1_1 |
BYT_RT5651_OVCD_TH_2000UA |
BYT_RT5651_OVCD_SF_0P75 |
BYT_RT5651_IN2_HS_IN3_MAP),
},
{
/* VIOS LTH17 */
.callback = byt_rt5651_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "VIOS"),
DMI_MATCH(DMI_PRODUCT_NAME, "LTH17"),
},
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
BYT_RT5651_JD1_1 |
BYT_RT5651_OVCD_TH_2000UA |
BYT_RT5651_OVCD_SF_1P0 |
BYT_RT5651_IN1_IN2_MAP),
},
{}
};
/*
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
static int byt_rt5651_add_codec_device_props(const char *i2c_dev_name)
{
struct property_entry props[MAX_NO_PROPS] = {};
struct device *i2c_dev;
int ret, cnt = 0;
i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
if (!i2c_dev)
return -EPROBE_DEFER;
props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
BYT_RT5651_JDSRC(byt_rt5651_quirk));
props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-threshold-microamp",
BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-scale-factor",
BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en");
ret = device_add_properties(i2c_dev, props);
put_device(i2c_dev);
return ret;
}
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
{
struct snd_soc_card *card = runtime->card;
struct snd_soc_codec *codec = runtime->codec;
struct snd_soc_component *codec = runtime->codec_dai->component;
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
const struct snd_soc_dapm_route *custom_map;
int num_routes;
@ -304,6 +457,11 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
card->dapm.idle_bias_off = true;
/* Start with RC clk for jack-detect (we disable MCLK below) */
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
snd_soc_component_update_bits(codec, RT5651_GLB_CLK,
RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_RCCLK);
switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
case BYT_RT5651_IN1_MAP:
custom_map = byt_rt5651_intmic_in1_map;
@ -317,9 +475,13 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
custom_map = byt_rt5651_intmic_in1_in2_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
break;
case BYT_RT5651_IN3_MAP:
custom_map = byt_rt5651_intmic_in3_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in3_map);
case BYT_RT5651_IN1_HS_IN3_MAP:
custom_map = byt_rt5651_intmic_in1_hs_in3_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_hs_in3_map);
break;
case BYT_RT5651_IN2_HS_IN3_MAP:
custom_map = byt_rt5651_intmic_in2_hs_in3_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_hs_in3_map);
break;
default:
custom_map = byt_rt5651_intmic_dmic_map;
@ -329,6 +491,26 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
if (ret)
return ret;
if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) {
ret = snd_soc_dapm_add_routes(&card->dapm,
byt_rt5651_ssp2_aif2_map,
ARRAY_SIZE(byt_rt5651_ssp2_aif2_map));
} else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) {
ret = snd_soc_dapm_add_routes(&card->dapm,
byt_rt5651_ssp0_aif1_map,
ARRAY_SIZE(byt_rt5651_ssp0_aif1_map));
} else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) {
ret = snd_soc_dapm_add_routes(&card->dapm,
byt_rt5651_ssp0_aif2_map,
ARRAY_SIZE(byt_rt5651_ssp0_aif2_map));
} else {
ret = snd_soc_dapm_add_routes(&card->dapm,
byt_rt5651_ssp2_aif1_map,
ARRAY_SIZE(byt_rt5651_ssp2_aif1_map));
}
if (ret)
return ret;
ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
ARRAY_SIZE(byt_rt5651_controls));
if (ret) {
@ -362,17 +544,21 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
dev_err(card->dev, "unable to set MCLK rate\n");
}
ret = snd_soc_card_jack_new(runtime->card, "Headset",
if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
ret = snd_soc_card_jack_new(runtime->card, "Headset",
SND_JACK_HEADSET, &priv->jack,
bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
if (ret) {
dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
return ret;
if (ret) {
dev_err(runtime->dev, "jack creation failed %d\n", ret);
return ret;
}
ret = snd_soc_component_set_jack(codec, &priv->jack, NULL);
if (ret)
return ret;
}
rt5651_set_jack_detect(codec, &priv->jack);
return ret;
return 0;
}
static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
@ -390,18 +576,26 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
int ret;
int ret, bits;
/* The DSP will covert the FE rate to 48k, stereo, 24bits */
/* The DSP will covert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
/* set SSP2 to 24-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
/* set SSP0 to 16-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
bits = 16;
} else {
/* set SSP2 to 24-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
bits = 24;
}
/*
* Default mode for SSP configuration is TDM 4 slot, override config
* with explicit setting to I2S 2ch 24-bit. The word length is set with
* with explicit setting to I2S 2ch. The word length is set with
* dai_set_tdm_slot() since there is no other API exposed
*/
ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
@ -415,7 +609,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
return ret;
}
ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, bits);
if (ret < 0) {
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
return ret;
@ -510,12 +704,32 @@ static struct snd_soc_card byt_rt5651_card = {
};
static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
static char byt_rt5651_codec_aif_name[12]; /* = "rt5651-aif[1|2]" */
static char byt_rt5651_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
static bool is_valleyview(void)
{
static const struct x86_cpu_id cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
{}
};
if (!x86_match_cpu(cpu_ids))
return false;
return true;
}
struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
u64 aif_value; /* 1: AIF1, 2: AIF2 */
u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */
};
static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
{
struct byt_rt5651_private *priv;
struct snd_soc_acpi_mach *mach;
const char *i2c_name = NULL;
bool is_bytcr = false;
int ret_val = 0;
int dai_index = 0;
int i;
@ -540,17 +754,105 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
/* fixup codec name based on HID */
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
if (i2c_name) {
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"%s%s", "i2c-", i2c_name);
if (!i2c_name) {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENODEV;
}
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"%s%s", "i2c-", i2c_name);
byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
/*
* swap SSP0 if bytcr is detected
* (will be overridden if DMI quirk is detected)
*/
if (is_valleyview()) {
struct sst_platform_info *p_info = mach->pdata;
const struct sst_res_info *res_info = p_info->res_info;
if (res_info->acpi_ipc_irq_index == 0)
is_bytcr = true;
}
if (is_bytcr) {
/*
* Baytrail CR platforms may have CHAN package in BIOS, try
* to find relevant routing quirk based as done on Windows
* platforms. We have to read the information directly from the
* BIOS, at this stage the card is not created and the links
* with the codec driver/pdata are non-existent
*/
struct acpi_chan_package chan_package;
/* format specified: 2 64-bit integers */
struct acpi_buffer format = {sizeof("NN"), "NN"};
struct acpi_buffer state = {0, NULL};
struct snd_soc_acpi_package_context pkg_ctx;
bool pkg_found = false;
state.length = sizeof(chan_package);
state.pointer = &chan_package;
pkg_ctx.name = "CHAN";
pkg_ctx.length = 2;
pkg_ctx.format = &format;
pkg_ctx.state = &state;
pkg_ctx.data_valid = false;
pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
&pkg_ctx);
if (pkg_found) {
if (chan_package.aif_value == 1) {
dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF1;
} else if (chan_package.aif_value == 2) {
dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
} else {
dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
pkg_found = false;
}
}
if (!pkg_found) {
/* no BIOS indications, assume SSP0-AIF2 connection */
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
}
}
/* check quirks before creating card */
dmi_check_system(byt_rt5651_quirk_table);
/* Must be called before register_card, also see declaration comment. */
ret_val = byt_rt5651_add_codec_device_props(byt_rt5651_codec_name);
if (ret_val)
return ret_val;
log_quirks(&pdev->dev);
if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
/* fixup codec aif name */
snprintf(byt_rt5651_codec_aif_name,
sizeof(byt_rt5651_codec_aif_name),
"%s", "rt5651-aif2");
byt_rt5651_dais[dai_index].codec_dai_name =
byt_rt5651_codec_aif_name;
}
if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
/* fixup cpu dai name name */
snprintf(byt_rt5651_cpu_dai_name,
sizeof(byt_rt5651_cpu_dai_name),
"%s", "ssp0-port");
byt_rt5651_dais[dai_index].cpu_dai_name =
byt_rt5651_cpu_dai_name;
}
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk)) {

View File

@ -0,0 +1,282 @@
/*
* cht-bsw-nau8824.c - ASoc Machine driver for Intel Cherryview-based
* platforms Cherrytrail and Braswell, with nau8824 codec.
*
* Copyright (C) 2018 Intel Corp
* Copyright (C) 2018 Nuvoton Technology Corp
*
* Author: Wang, Joseph C <joequant@gmail.com>
* Co-author: John Hsu <KCHSU0@nuvoton.com>
* This file is based on cht_bsw_rt5672.c and cht-bsw-max98090.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include <linux/input.h>
#include "../atom/sst-atom-controls.h"
#include "../../codecs/nau8824.h"
struct cht_mc_private {
struct snd_soc_jack jack;
};
static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Int Mic", NULL),
SND_SOC_DAPM_SPK("Ext Spk", NULL),
};
static const struct snd_soc_dapm_route cht_audio_map[] = {
{"Ext Spk", NULL, "SPKOUTL"},
{"Ext Spk", NULL, "SPKOUTR"},
{"Headphone", NULL, "HPOL"},
{"Headphone", NULL, "HPOR"},
{"MIC1", NULL, "Int Mic"},
{"MIC2", NULL, "Int Mic"},
{"HSMIC1", NULL, "Headset Mic"},
{"HSMIC2", NULL, "Headset Mic"},
{"Playback", NULL, "ssp2 Tx"},
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
{"codec_in0", NULL, "ssp2 Rx" },
{"codec_in1", NULL, "ssp2 Rx" },
{"ssp2 Rx", NULL, "Capture"},
};
static const struct snd_kcontrol_new cht_mc_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Int Mic"),
SOC_DAPM_PIN_SWITCH("Ext Spk"),
};
static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8824_CLK_FLL_FS, 0,
SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
return ret;
}
ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
params_rate(params) * 256);
if (ret < 0) {
dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
return ret;
}
return 0;
}
static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
{
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
struct snd_soc_jack *jack = &ctx->jack;
struct snd_soc_dai *codec_dai = runtime->codec_dai;
struct snd_soc_component *component = codec_dai->component;
int ret, jack_type;
/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xf, 0x1, 4, 24);
if (ret < 0) {
dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret);
return ret;
}
/* NAU88L24 supports 4 butons headset detection
* KEY_MEDIA
* KEY_VOICECOMMAND
* KEY_VOLUMEUP
* KEY_VOLUMEDOWN
*/
jack_type = SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3;
ret = snd_soc_card_jack_new(runtime->card, "Headset", jack_type, jack,
cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
if (ret) {
dev_err(runtime->dev,
"Headset Jack creation failed %d\n", ret);
return ret;
}
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
nau8824_enable_jack_detect(component, jack);
return ret;
}
static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt =
hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The DSP will covert the FE rate to 48k, stereo, 24bits */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
/* set SSP2 to 24-bit */
snd_mask_none(fmt);
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
return 0;
}
static int cht_aif1_startup(struct snd_pcm_substream *substream)
{
return snd_pcm_hw_constraint_single(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE, 48000);
}
static const struct snd_soc_ops cht_aif1_ops = {
.startup = cht_aif1_startup,
};
static const struct snd_soc_ops cht_be_ssp2_ops = {
.hw_params = cht_aif1_hw_params,
};
static struct snd_soc_dai_link cht_dailink[] = {
/* Front End DAI links */
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_aif1_ops,
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &cht_aif1_ops,
},
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* Back End DAI links */
{
/* SSP2 - Codec */
.name = "SSP2-Codec",
.id = 1,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = NAU8824_CODEC_DAI,
.codec_name = "i2c-10508824:00",
.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.init = cht_codec_init,
.be_hw_params_fixup = cht_codec_fixup,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_be_ssp2_ops,
},
};
/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
.name = "chtnau8824",
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
.dapm_widgets = cht_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
.dapm_routes = cht_audio_map,
.num_dapm_routes = ARRAY_SIZE(cht_audio_map),
.controls = cht_mc_controls,
.num_controls = ARRAY_SIZE(cht_mc_controls),
};
static int snd_cht_mc_probe(struct platform_device *pdev)
{
struct cht_mc_private *drv;
int ret_val;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
if (!drv)
return -ENOMEM;
snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
/* register the soc card */
snd_soc_card_cht.dev = &pdev->dev;
ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
if (ret_val) {
dev_err(&pdev->dev,
"snd_soc_register_card failed %d\n", ret_val);
return ret_val;
}
platform_set_drvdata(pdev, &snd_soc_card_cht);
return ret_val;
}
static struct platform_driver snd_cht_mc_driver = {
.driver = {
.name = "cht-bsw-nau8824",
},
.probe = snd_cht_mc_probe,
};
module_platform_driver(snd_cht_mc_driver);
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
MODULE_AUTHOR("Wang, Joseph C <joequant@gmail.com>");
MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:cht-bsw-nau8824");

View File

@ -0,0 +1,613 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright(c) 2017-18 Intel Corporation.
/*
* Intel Kabylake I2S Machine Driver with MAX98357A & DA7219 Codecs
*
* Modified from:
* Intel Kabylake I2S Machine driver supporting MAXIM98927 and
* RT5663 codecs
*/
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../../codecs/da7219.h"
#include "../../codecs/hdac_hdmi.h"
#include "../skylake/skl.h"
#include "../../codecs/da7219-aad.h"
#define KBL_DIALOG_CODEC_DAI "da7219-hifi"
#define KBL_MAXIM_CODEC_DAI "HiFi"
#define MAXIM_DEV0_NAME "MX98357A:00"
#define DUAL_CHANNEL 2
#define QUAD_CHANNEL 4
static struct snd_soc_card *kabylake_audio_card;
static struct snd_soc_jack skylake_hdmi[3];
struct kbl_hdmi_pcm {
struct list_head head;
struct snd_soc_dai *codec_dai;
int device;
};
struct kbl_codec_private {
struct snd_soc_jack kabylake_headset;
struct list_head hdmi_pcm_list;
};
enum {
KBL_DPCM_AUDIO_PB = 0,
KBL_DPCM_AUDIO_CP,
KBL_DPCM_AUDIO_DMIC_CP,
KBL_DPCM_AUDIO_HDMI1_PB,
KBL_DPCM_AUDIO_HDMI2_PB,
KBL_DPCM_AUDIO_HDMI3_PB,
};
static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct snd_soc_dai *codec_dai;
int ret = 0;
codec_dai = snd_soc_card_get_codec_dai(card, KBL_DIALOG_CODEC_DAI);
if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
return -EIO;
}
/* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24576000,
SND_SOC_CLOCK_IN);
if (ret) {
dev_err(card->dev, "can't set codec sysclk configuration\n");
return ret;
}
if (SND_SOC_DAPM_EVENT_OFF(event)) {
ret = snd_soc_dai_set_pll(codec_dai, 0,
DA7219_SYSCLK_MCLK, 0, 0);
if (ret)
dev_err(card->dev, "failed to stop PLL: %d\n", ret);
} else if (SND_SOC_DAPM_EVENT_ON(event)) {
ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM,
0, DA7219_PLL_FREQ_OUT_98304);
if (ret)
dev_err(card->dev, "failed to start PLL: %d\n", ret);
}
return ret;
}
static const struct snd_kcontrol_new kabylake_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Spk"),
};
static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_SPK("Spk", NULL),
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
SND_SOC_DAPM_SPK("DP", NULL),
SND_SOC_DAPM_SPK("HDMI", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route kabylake_map[] = {
{ "Headphone Jack", NULL, "HPL" },
{ "Headphone Jack", NULL, "HPR" },
/* speaker */
{ "Spk", NULL, "Speaker" },
/* other jacks */
{ "MIC", NULL, "Headset Mic" },
{ "DMic", NULL, "SoC DMIC" },
{ "HDMI", NULL, "hif5 Output" },
{ "DP", NULL, "hif6 Output" },
/* CODEC BE connections */
{ "HiFi Playback", NULL, "ssp0 Tx" },
{ "ssp0 Tx", NULL, "codec0_out" },
{ "Playback", NULL, "ssp1 Tx" },
{ "ssp1 Tx", NULL, "codec1_out" },
{ "codec0_in", NULL, "ssp1 Rx" },
{ "ssp1 Rx", NULL, "Capture" },
/* DMIC */
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
{ "DMIC01 Rx", NULL, "DMIC AIF" },
{ "hifi1", NULL, "iDisp1 Tx" },
{ "iDisp1 Tx", NULL, "iDisp1_out" },
{ "hifi2", NULL, "iDisp2 Tx" },
{ "iDisp2 Tx", NULL, "iDisp2_out" },
{ "hifi3", NULL, "iDisp3 Tx"},
{ "iDisp3 Tx", NULL, "iDisp3_out"},
{ "Headphone Jack", NULL, "Platform Clock" },
{ "Headset Mic", NULL, "Platform Clock" },
};
static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
/* The ADSP will convert the FE rate to 48k, stereo */
rate->min = rate->max = 48000;
channels->min = channels->max = DUAL_CHANNEL;
/* set SSP to 24 bit */
snd_mask_none(fmt);
snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
return 0;
}
static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_component *component = rtd->codec_dai->component;
struct snd_soc_jack *jack;
int ret;
/*
* Headset buttons map to the google Reference headset.
* These can be configured by userspace.
*/
ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack",
SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT,
&ctx->kabylake_headset, NULL, 0);
if (ret) {
dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
return ret;
}
jack = &ctx->kabylake_headset;
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
da7219_aad_jack_det(component, &ctx->kabylake_headset);
ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
if (ret)
dev_err(rtd->dev, "SoC DMIC - Ignore suspend failed %d\n", ret);
return ret;
}
static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
{
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *dai = rtd->codec_dai;
struct kbl_hdmi_pcm *pcm;
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
if (!pcm)
return -ENOMEM;
pcm->device = device;
pcm->codec_dai = dai;
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
return 0;
}
static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
{
return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB);
}
static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
{
return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB);
}
static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
{
return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB);
}
static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dapm_context *dapm;
struct snd_soc_component *component = rtd->cpu_dai->component;
dapm = snd_soc_component_get_dapm(component);
snd_soc_dapm_ignore_suspend(dapm, "Reference Capture");
return 0;
}
static const unsigned int rates[] = {
48000,
};
static const struct snd_pcm_hw_constraint_list constraints_rates = {
.count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
static const unsigned int channels[] = {
DUAL_CHANNEL,
};
static const struct snd_pcm_hw_constraint_list constraints_channels = {
.count = ARRAY_SIZE(channels),
.list = channels,
.mask = 0,
};
static unsigned int channels_quad[] = {
QUAD_CHANNEL,
};
static struct snd_pcm_hw_constraint_list constraints_channels_quad = {
.count = ARRAY_SIZE(channels_quad),
.list = channels_quad,
.mask = 0,
};
static int kbl_fe_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
/*
* On this platform for PCM device we support,
* 48Khz
* stereo
* 16 bit audio
*/
runtime->hw.channels_max = DUAL_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels);
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
return 0;
}
static const struct snd_soc_ops kabylake_da7219_fe_ops = {
.startup = kbl_fe_startup,
};
static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
/*
* set BE channel constraint as user FE channels
*/
if (params_channels(params) == 2)
channels->min = channels->max = 2;
else
channels->min = channels->max = 4;
return 0;
}
static int kabylake_dmic_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
runtime->hw.channels_min = runtime->hw.channels_max = QUAD_CHANNEL;
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels_quad);
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
}
static struct snd_soc_ops kabylake_dmic_ops = {
.startup = kabylake_dmic_startup,
};
static const unsigned int rates_16000[] = {
16000,
};
static const struct snd_pcm_hw_constraint_list constraints_16000 = {
.count = ARRAY_SIZE(rates_16000),
.list = rates_16000,
};
static const unsigned int ch_mono[] = {
1,
};
/* kabylake digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link kabylake_dais[] = {
/* Front End DAI links */
[KBL_DPCM_AUDIO_PB] = {
.name = "Kbl Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "System Pin",
.platform_name = "0000:00:1f.3",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.nonatomic = 1,
.init = kabylake_da7219_fe_init,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.ops = &kabylake_da7219_fe_ops,
},
[KBL_DPCM_AUDIO_CP] = {
.name = "Kbl Audio Capture Port",
.stream_name = "Audio Record",
.cpu_dai_name = "System Pin",
.platform_name = "0000:00:1f.3",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.nonatomic = 1,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_capture = 1,
},
[KBL_DPCM_AUDIO_DMIC_CP] = {
.name = "Kbl Audio DMIC cap",
.stream_name = "dmiccap",
.cpu_dai_name = "DMIC Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.init = NULL,
.dpcm_capture = 1,
.nonatomic = 1,
.dynamic = 1,
.ops = &kabylake_dmic_ops,
},
[KBL_DPCM_AUDIO_HDMI1_PB] = {
.name = "Kbl HDMI Port1",
.stream_name = "Hdmi1",
.cpu_dai_name = "HDMI1 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
.init = NULL,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.nonatomic = 1,
.dynamic = 1,
},
[KBL_DPCM_AUDIO_HDMI2_PB] = {
.name = "Kbl HDMI Port2",
.stream_name = "Hdmi2",
.cpu_dai_name = "HDMI2 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
.init = NULL,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.nonatomic = 1,
.dynamic = 1,
},
[KBL_DPCM_AUDIO_HDMI3_PB] = {
.name = "Kbl HDMI Port3",
.stream_name = "Hdmi3",
.cpu_dai_name = "HDMI3 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:1f.3",
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
},
/* Back End DAI links */
{
/* SSP0 - Codec */
.name = "SSP0-Codec",
.id = 0,
.cpu_dai_name = "SSP0 Pin",
.platform_name = "0000:00:1f.3",
.no_pcm = 1,
.codec_name = MAXIM_DEV0_NAME,
.codec_dai_name = KBL_MAXIM_CODEC_DAI,
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ignore_pmdown_time = 1,
.be_hw_params_fixup = kabylake_ssp_fixup,
.dpcm_playback = 1,
},
{
/* SSP1 - Codec */
.name = "SSP1-Codec",
.id = 1,
.cpu_dai_name = "SSP1 Pin",
.platform_name = "0000:00:1f.3",
.no_pcm = 1,
.codec_name = "i2c-DLGS7219:00",
.codec_dai_name = KBL_DIALOG_CODEC_DAI,
.init = kabylake_da7219_codec_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ignore_pmdown_time = 1,
.be_hw_params_fixup = kabylake_ssp_fixup,
.dpcm_playback = 1,
.dpcm_capture = 1,
},
{
.name = "dmic01",
.id = 2,
.cpu_dai_name = "DMIC01 Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
.platform_name = "0000:00:1f.3",
.be_hw_params_fixup = kabylake_dmic_fixup,
.ignore_suspend = 1,
.dpcm_capture = 1,
.no_pcm = 1,
},
{
.name = "iDisp1",
.id = 3,
.cpu_dai_name = "iDisp1 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi1",
.platform_name = "0000:00:1f.3",
.dpcm_playback = 1,
.init = kabylake_hdmi1_init,
.no_pcm = 1,
},
{
.name = "iDisp2",
.id = 4,
.cpu_dai_name = "iDisp2 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi2",
.platform_name = "0000:00:1f.3",
.init = kabylake_hdmi2_init,
.dpcm_playback = 1,
.no_pcm = 1,
},
{
.name = "iDisp3",
.id = 5,
.cpu_dai_name = "iDisp3 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi3",
.platform_name = "0000:00:1f.3",
.init = kabylake_hdmi3_init,
.dpcm_playback = 1,
.no_pcm = 1,
},
};
#define NAME_SIZE 32
static int kabylake_card_late_probe(struct snd_soc_card *card)
{
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
struct kbl_hdmi_pcm *pcm;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
SND_JACK_AVOUT, &skylake_hdmi[i],
NULL, 0);
if (err)
return err;
err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
&skylake_hdmi[i]);
if (err < 0)
return err;
i++;
}
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/* kabylake audio machine driver for SPT + DA7219 */
static struct snd_soc_card kabylake_audio_card_da7219_m98357a = {
.name = "kblda7219max",
.owner = THIS_MODULE,
.dai_link = kabylake_dais,
.num_links = ARRAY_SIZE(kabylake_dais),
.controls = kabylake_controls,
.num_controls = ARRAY_SIZE(kabylake_controls),
.dapm_widgets = kabylake_widgets,
.num_dapm_widgets = ARRAY_SIZE(kabylake_widgets),
.dapm_routes = kabylake_map,
.num_dapm_routes = ARRAY_SIZE(kabylake_map),
.fully_routed = true,
.late_probe = kabylake_card_late_probe,
};
static int kabylake_audio_probe(struct platform_device *pdev)
{
struct kbl_codec_private *ctx;
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
if (!ctx)
return -ENOMEM;
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
kabylake_audio_card =
(struct snd_soc_card *)pdev->id_entry->driver_data;
kabylake_audio_card->dev = &pdev->dev;
snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
}
static const struct platform_device_id kbl_board_ids[] = {
{
.name = "kbl_da7219_max98357a",
.driver_data =
(kernel_ulong_t)&kabylake_audio_card_da7219_m98357a,
},
{ }
};
static struct platform_driver kabylake_audio = {
.probe = kabylake_audio_probe,
.driver = {
.name = "kbl_da7219_max98357a",
.pm = &snd_soc_pm_ops,
},
.id_table = kbl_board_ids,
};
module_platform_driver(kabylake_audio)
/* Module information */
MODULE_DESCRIPTION("Audio Machine driver-DA7219 & MAX98357A in I2S mode");
MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:kbl_da7219_max98357a");

View File

@ -204,13 +204,18 @@ static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = {
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_SPK("DP", NULL),
SND_SOC_DAPM_SPK("HDMI", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route kabylake_5663_map[] = {
{ "Headphone Jack", NULL, "Platform Clock" },
{ "Headphone Jack", NULL, "HPOL" },
{ "Headphone Jack", NULL, "HPOR" },
/* other jacks */
{ "Headset Mic", NULL, "Platform Clock" },
{ "IN1P", NULL, "Headset Mic" },
{ "IN1N", NULL, "Headset Mic" },
@ -272,7 +277,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
struct snd_soc_jack *jack;
/*
@ -294,7 +299,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
rt5663_set_jack_detect(component, &ctx->kabylake_headset);
return ret;
}
@ -448,7 +453,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
int ret;
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
rt5663_sel_asrc_clk_src(codec_dai->codec,
rt5663_sel_asrc_clk_src(codec_dai->component,
RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
RT5663_CLK_SEL_I2S1_ASRC);
@ -898,12 +903,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
{
struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
struct kbl_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -921,10 +926,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/* kabylake audio machine driver for SPT + RT5663 */

View File

@ -178,7 +178,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
struct snd_soc_jack *jack;
/*
@ -200,7 +200,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
rt5663_set_jack_detect(component, &ctx->kabylake_headset);
ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC");
if (ret)
@ -333,7 +333,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
int ret;
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
rt5663_sel_asrc_clk_src(codec_dai->codec,
rt5663_sel_asrc_clk_src(codec_dai->component,
RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
RT5663_CLK_SEL_I2S1_ASRC);
@ -599,12 +599,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
{
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
struct kbl_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP,pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -620,10 +620,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/*

View File

@ -165,7 +165,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
/*
* Headset buttons map to the google Reference headset.
@ -180,7 +180,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
nau8825_enable_jack_detect(codec, &skylake_headset);
nau8825_enable_jack_detect(component, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
@ -592,12 +592,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
{
struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
struct skl_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -616,10 +616,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/* skylake audio machine driver for SPT + NAU88L25 */

View File

@ -195,7 +195,7 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd)
static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
/*
* 4 buttons here map to the google Reference headset
@ -210,7 +210,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
nau8825_enable_jack_detect(codec, &skylake_headset);
nau8825_enable_jack_detect(component, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
@ -643,12 +643,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
{
struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
struct skl_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -667,10 +667,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/* skylake audio machine driver for SPT + NAU88L25 */

View File

@ -130,7 +130,7 @@ static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd)
static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_component *component = rtd->codec_dai->component;
int ret;
ret = snd_soc_card_jack_new(rtd->card, "Headset",
@ -141,7 +141,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
if (ret)
return ret;
rt286_mic_detect(codec, &skylake_headset);
rt286_mic_detect(component, &skylake_headset);
snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
@ -478,12 +478,12 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
{
struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
struct skl_hdmi_pcm *pcm;
struct snd_soc_codec *codec = NULL;
struct snd_soc_component *component = NULL;
int err, i = 0;
char jack_name[NAME_SIZE];
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
component = pcm->codec_dai->component;
snprintf(jack_name, sizeof(jack_name),
"HDMI/DP, pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
@ -501,10 +501,10 @@ static int skylake_card_late_probe(struct snd_soc_card *card)
i++;
}
if (!codec)
if (!component)
return -EINVAL;
return hdac_hdmi_jack_port_init(codec, &card->dapm);
return hdac_hdmi_jack_port_init(component, &card->dapm);
}
/* skylake audio machine driver for SPT + RT286S */

View File

@ -117,6 +117,15 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = {
.sof_tplg_filename = "intel/reef-cht-max98090.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10508824",
.drv_name = "cht-bsw-nau8824",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-nau8824.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "DLGS7212",
.drv_name = "bytcht_da7213",

View File

@ -417,11 +417,16 @@ int skl_resume_dsp(struct skl *skl)
if (skl->skl_sst->is_first_boot == true)
return 0;
/* disable dynamic clock gating during fw and lib download */
/*
* Disable dynamic clock and power gating during firmware
* and library download
*/
ctx->enable_miscbdcge(ctx->dev, false);
ctx->clock_power_gating(ctx->dev, false);
ret = skl_dsp_wake(ctx->dsp);
ctx->enable_miscbdcge(ctx->dev, true);
ctx->clock_power_gating(ctx->dev, true);
if (ret < 0)
return ret;
@ -1210,7 +1215,7 @@ out:
static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
enum skl_ipc_pipeline_state state)
{
dev_dbg(ctx->dev, "%s: pipe_satate = %d\n", __func__, state);
dev_dbg(ctx->dev, "%s: pipe_state = %d\n", __func__, state);
return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state);
}

View File

@ -958,6 +958,17 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
},
},
{
.name = "DMIC16k Pin",
.ops = &skl_dmic_dai_ops,
.capture = {
.stream_name = "DMIC16k Rx",
.channels_min = HDA_MONO,
.channels_max = HDA_QUAD,
.rates = SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
},
{
.name = "HD-Codec Pin",
.ops = &skl_link_dai_ops,
@ -1307,6 +1318,8 @@ static int skl_populate_modules(struct skl *skl)
"query module info failed\n");
return ret;
}
skl_tplg_add_moduleid_in_bind_params(skl, w);
}
}
@ -1343,11 +1356,16 @@ static int skl_platform_soc_probe(struct snd_soc_component *component)
return -EIO;
}
/* disable dynamic clock gating during fw and lib download */
/*
* Disable dynamic clock and power gating during firmware
* and library download
*/
skl->skl_sst->enable_miscbdcge(component->dev, false);
skl->skl_sst->clock_power_gating(component->dev, false);
ret = ops->init_fw(component->dev, skl->skl_sst);
skl->skl_sst->enable_miscbdcge(component->dev, true);
skl->skl_sst->clock_power_gating(component->dev, true);
if (ret < 0) {
dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
return ret;

View File

@ -247,8 +247,8 @@ static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
}
/* Not supported by clk driver. Implemented to satisfy clk fw */
long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
static long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
return rate;
}

View File

@ -118,6 +118,9 @@ struct skl_sst {
struct skl_d0i3_data d0i3;
const struct skl_dsp_ops *dsp_ops;
/* Callback to update dynamic clock and power gating registers */
void (*clock_power_gating)(struct device *dev, bool enable);
};
struct skl_ipc_init_instance_msg {

View File

@ -94,8 +94,12 @@ void skl_tplg_d0i3_put(struct skl *skl, enum d0i3_capability caps)
* SKL DSP driver modelling uses only few DAPM widgets so for rest we will
* ignore. This helpers checks if the SKL driver handles this widget type
*/
static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w,
struct device *dev)
{
if (w->dapm->dev != dev)
return false;
switch (w->id) {
case snd_soc_dapm_dai_link:
case snd_soc_dapm_dai_in:
@ -826,7 +830,7 @@ static int skl_fill_sink_instance_id(struct skl_sst *ctx, u32 *params,
if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
struct skl_kpb_params *kpb_params =
(struct skl_kpb_params *)params;
struct skl_mod_inst_map *inst = kpb_params->map;
struct skl_mod_inst_map *inst = kpb_params->u.map;
for (i = 0; i < kpb_params->num_modules; i++) {
pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
@ -911,6 +915,87 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
return 0;
}
static int skl_get_module_id(struct skl_sst *ctx, uuid_le *uuid)
{
struct uuid_module *module;
list_for_each_entry(module, &ctx->uuid_list, list) {
if (uuid_le_cmp(*uuid, module->uuid) == 0)
return module->id;
}
return -EINVAL;
}
static int skl_tplg_find_moduleid_from_uuid(struct skl *skl,
const struct snd_kcontrol_new *k)
{
struct soc_bytes_ext *sb = (void *) k->private_value;
struct skl_algo_data *bc = (struct skl_algo_data *)sb->dobj.private;
struct skl_kpb_params *uuid_params, *params;
struct hdac_bus *bus = ebus_to_hbus(skl_to_ebus(skl));
int i, size, module_id;
if (bc->set_params == SKL_PARAM_BIND && bc->max) {
uuid_params = (struct skl_kpb_params *)bc->params;
size = uuid_params->num_modules *
sizeof(struct skl_mod_inst_map) +
sizeof(uuid_params->num_modules);
params = devm_kzalloc(bus->dev, size, GFP_KERNEL);
if (!params)
return -ENOMEM;
params->num_modules = uuid_params->num_modules;
for (i = 0; i < uuid_params->num_modules; i++) {
module_id = skl_get_module_id(skl->skl_sst,
&uuid_params->u.map_uuid[i].mod_uuid);
if (module_id < 0) {
devm_kfree(bus->dev, params);
return -EINVAL;
}
params->u.map[i].mod_id = module_id;
params->u.map[i].inst_id =
uuid_params->u.map_uuid[i].inst_id;
}
devm_kfree(bus->dev, bc->params);
bc->params = (char *)params;
bc->max = size;
}
return 0;
}
/*
* Retrieve the module id from UUID mentioned in the
* post bind params
*/
void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
struct snd_soc_dapm_widget *w)
{
struct skl_module_cfg *mconfig = w->priv;
int i;
/*
* Post bind params are used for only for KPB
* to set copier instances to drain the data
* in fast mode
*/
if (mconfig->m_type != SKL_MODULE_TYPE_KPB)
return;
for (i = 0; i < w->num_kcontrols; i++)
if ((w->kcontrol_news[i].access &
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
(skl_tplg_find_moduleid_from_uuid(skl,
&w->kcontrol_news[i]) < 0))
dev_err(skl->skl_sst->dev,
"%s: invalid kpb post bind params\n",
__func__);
}
static int skl_tplg_module_add_deferred_bind(struct skl *skl,
struct skl_module_cfg *src, struct skl_module_cfg *dst)
@ -969,7 +1054,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
next_sink = p->sink;
if (!is_skl_dsp_widget_type(p->sink))
if (!is_skl_dsp_widget_type(p->sink, ctx->dev))
return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
/*
@ -978,7 +1063,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
* they are ones used for SKL so check that first
*/
if ((p->sink->priv != NULL) &&
is_skl_dsp_widget_type(p->sink)) {
is_skl_dsp_widget_type(p->sink, ctx->dev)) {
sink = p->sink;
sink_mconfig = sink->priv;
@ -1092,7 +1177,7 @@ static struct snd_soc_dapm_widget *skl_get_src_dsp_widget(
* ones used for SKL so check that first
*/
if ((p->source->priv != NULL) &&
is_skl_dsp_widget_type(p->source)) {
is_skl_dsp_widget_type(p->source, ctx->dev)) {
return p->source;
}
}
@ -1654,7 +1739,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
w = dai->playback_widget;
snd_soc_dapm_widget_for_each_sink_path(w, p) {
if (p->connect && p->sink->power &&
!is_skl_dsp_widget_type(p->sink))
!is_skl_dsp_widget_type(p->sink, dai->dev))
continue;
if (p->sink->priv) {
@ -1667,7 +1752,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
w = dai->capture_widget;
snd_soc_dapm_widget_for_each_source_path(w, p) {
if (p->connect && p->source->power &&
!is_skl_dsp_widget_type(p->source))
!is_skl_dsp_widget_type(p->source, dai->dev))
continue;
if (p->source->priv) {
@ -1819,7 +1904,7 @@ static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
int ret = -EIO;
snd_soc_dapm_widget_for_each_source_path(w, p) {
if (p->connect && is_skl_dsp_widget_type(p->source) &&
if (p->connect && is_skl_dsp_widget_type(p->source, dai->dev) &&
p->source->priv) {
ret = skl_tplg_be_fill_pipe_params(dai,
@ -1844,7 +1929,7 @@ static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
int ret = -EIO;
snd_soc_dapm_widget_for_each_sink_path(w, p) {
if (p->connect && is_skl_dsp_widget_type(p->sink) &&
if (p->connect && is_skl_dsp_widget_type(p->sink, dai->dev) &&
p->sink->priv) {
ret = skl_tplg_be_fill_pipe_params(dai,
@ -2752,7 +2837,7 @@ void skl_cleanup_resources(struct skl *skl)
skl->resource.mcps = 0;
list_for_each_entry(w, &card->widgets, list) {
if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
if (is_skl_dsp_widget_type(w, ctx->dev) && w->priv != NULL)
skl_clear_pin_config(soc_component, w);
}
@ -3408,7 +3493,7 @@ static int skl_tplg_create_pipe_widget_list(struct snd_soc_component *component)
struct skl_pipe *pipe;
list_for_each_entry(w, &component->card->widgets, list) {
if (is_skl_dsp_widget_type(w) && w->priv != NULL) {
if (is_skl_dsp_widget_type(w, component->dev) && w->priv) {
mcfg = w->priv;
pipe = mcfg->pipe;

View File

@ -221,9 +221,18 @@ struct skl_mod_inst_map {
u16 inst_id;
};
struct skl_uuid_inst_map {
u16 inst_id;
u16 reserved;
uuid_le mod_uuid;
} __packed;
struct skl_kpb_params {
u32 num_modules;
struct skl_mod_inst_map map[0];
union {
struct skl_mod_inst_map map[0];
struct skl_uuid_inst_map map_uuid[0];
} u;
};
struct skl_module_inst_id {
@ -505,4 +514,6 @@ int skl_pcm_link_dma_prepare(struct device *dev,
int skl_dai_load(struct snd_soc_component *cmp,
struct snd_soc_dai_driver *pcm_dai);
void skl_tplg_add_moduleid_in_bind_params(struct skl *skl,
struct snd_soc_dapm_widget *w);
#endif

View File

@ -94,6 +94,32 @@ static void skl_enable_miscbdcge(struct device *dev, bool enable)
update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, val);
}
/**
* skl_clock_power_gating: Enable/Disable clock and power gating
*
* @dev: Device pointer
* @enable: Enable/Disable flag
*/
static void skl_clock_power_gating(struct device *dev, bool enable)
{
struct pci_dev *pci = to_pci_dev(dev);
struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
struct hdac_bus *bus = ebus_to_hbus(ebus);
u32 val;
/* Update PDCGE bit of CGCTL register */
val = enable ? AZX_CGCTL_ADSPDCGE : 0;
update_pci_dword(pci, AZX_PCIREG_CGCTL, AZX_CGCTL_ADSPDCGE, val);
/* Update L1SEN bit of EM2 register */
val = enable ? AZX_REG_VS_EM2_L1SEN : 0;
snd_hdac_chip_updatel(bus, VS_EM2, AZX_REG_VS_EM2_L1SEN, val);
/* Update ADSPPGD bit of PGCTL register */
val = enable ? 0 : AZX_PGCTL_ADSPPGD;
update_pci_dword(pci, AZX_PCIREG_PGCTL, AZX_PGCTL_ADSPPGD, val);
}
/*
* While performing reset, controller may not come back properly causing
* issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
@ -916,6 +942,7 @@ static int skl_probe(struct pci_dev *pci,
goto out_nhlt_free;
}
skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
skl->skl_sst->clock_power_gating = skl_clock_power_gating;
}
if (bus->mlcap)
snd_hdac_ext_bus_get_ml_capabilities(ebus);
@ -1017,6 +1044,11 @@ static struct snd_soc_acpi_codecs kbl_5663_5514_codecs = {
.codecs = {"10EC5663", "10EC5514"}
};
static struct snd_soc_acpi_codecs kbl_7219_98357_codecs = {
.num_codecs = 1,
.codecs = {"MX98357A"}
};
static struct skl_machine_pdata cnl_pdata = {
.use_tplg_pcm = true,
};
@ -1105,6 +1137,14 @@ static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
.drv_name = "kbl_rt5663",
.fw_filename = "intel/dsp_fw_kbl.bin",
},
{
.id = "DLGS7219",
.drv_name = "kbl_da7219_max98357a",
.fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_7219_98357_codecs,
.pdata = &skl_dmic_data
},
{}
};

View File

@ -33,8 +33,10 @@
#define AZX_PCIREG_PGCTL 0x44
#define AZX_PGCTL_LSRMD_MASK (1 << 4)
#define AZX_PGCTL_ADSPPGD BIT(2)
#define AZX_PCIREG_CGCTL 0x48
#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
#define AZX_CGCTL_ADSPDCGE BIT(1)
/* D0I3C Register fields */
#define AZX_REG_VS_D0I3C_CIP 0x1 /* Command in progress */
#define AZX_REG_VS_D0I3C_I3 0x4 /* D0i3 enable */
@ -43,6 +45,8 @@
#define DMA_TRANSMITION_START 2
#define DMA_TRANSMITION_STOP 3
#define AZX_REG_VS_EM2_L1SEN BIT(13)
struct skl_dsp_resource {
u32 max_mcps;
u32 max_mem;

View File

@ -176,7 +176,7 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec_dais[0]->codec;
struct snd_soc_component *component = rtd->codec_dais[0]->component;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret;
@ -215,7 +215,7 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
snd_jack_set_key(
rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
da7219_aad_jack_det(codec, &rockchip_sound_jack);
da7219_aad_jack_det(component, &rockchip_sound_jack);
return 0;
}