Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
This commit is contained in:
commit
5b6d7104f6
@ -16,6 +16,23 @@ Optional properties:
|
|||||||
- realtek,dmic-en
|
- realtek,dmic-en
|
||||||
Boolean. true if dmic is used.
|
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:
|
Pins on the device (for linking into audio routes) for RT5651:
|
||||||
|
|
||||||
* DMIC L1
|
* DMIC L1
|
||||||
|
@ -135,6 +135,7 @@ struct sst_platform_info {
|
|||||||
const struct sst_res_info *res_info;
|
const struct sst_res_info *res_info;
|
||||||
const struct sst_lib_dnld_info *lib_info;
|
const struct sst_lib_dnld_info *lib_info;
|
||||||
const char *platform;
|
const char *platform;
|
||||||
|
bool streams_lost_on_suspend;
|
||||||
};
|
};
|
||||||
int add_sst_platform_device(void);
|
int add_sst_platform_device(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -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);
|
int flags, unsigned int verb, unsigned int parm);
|
||||||
bool snd_hdac_check_power_state(struct hdac_device *hdac,
|
bool snd_hdac_check_power_state(struct hdac_device *hdac,
|
||||||
hda_nid_t nid, unsigned int target_state);
|
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
|
* snd_hdac_read_parm - read a codec parameter
|
||||||
* @codec: the codec object
|
* @codec: the codec object
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
#ifndef __LINUX_SND_RT5651_H
|
#ifndef __LINUX_SND_RT5651_H
|
||||||
#define __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 {
|
enum rt5651_jd_src {
|
||||||
RT5651_JD_NULL,
|
RT5651_JD_NULL,
|
||||||
RT5651_JD1_1,
|
RT5651_JD1_1,
|
||||||
@ -18,12 +22,15 @@ enum rt5651_jd_src {
|
|||||||
RT5651_JD2,
|
RT5651_JD2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rt5651_platform_data {
|
/*
|
||||||
/* IN2 can optionally be differential */
|
* Note these MUST match the values from the DT binding:
|
||||||
bool in2_diff;
|
* Documentation/devicetree/bindings/sound/rt5651.txt
|
||||||
|
*/
|
||||||
bool dmic_en;
|
enum rt5651_ovcd_sf {
|
||||||
enum rt5651_jd_src jd_src;
|
RT5651_OVCD_SF_0P5,
|
||||||
|
RT5651_OVCD_SF_0P75,
|
||||||
|
RT5651_OVCD_SF_1P0,
|
||||||
|
RT5651_OVCD_SF_1P5,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -1064,3 +1065,37 @@ bool snd_hdac_check_power_state(struct hdac_device *hdac,
|
|||||||
return (state == target_state);
|
return (state == target_state);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_check_power_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);
|
||||||
|
@ -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);
|
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
|
* snd_hda_codec_eapd_power_filter - A power filter callback for EAPD
|
||||||
* @codec: the HDA codec
|
* @codec: the HDA codec
|
||||||
@ -2790,7 +2764,7 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
|
|||||||
state);
|
state);
|
||||||
snd_hda_codec_set_power_to_all(codec, fg, power_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))
|
if (!(state & AC_PWRST_ERROR))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
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,
|
unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
|
||||||
hda_nid_t nid,
|
hda_nid_t nid,
|
||||||
unsigned int power_state);
|
unsigned int power_state);
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
* Detection control
|
* 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 = jack;
|
||||||
da7219->aad->jack_inserted = false;
|
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);
|
snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
|
||||||
|
|
||||||
/* Enable/Disable jack detection */
|
/* 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,
|
DA7219_ACCDET_EN_MASK,
|
||||||
(jack ? DA7219_ACCDET_EN_MASK : 0));
|
(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 =
|
struct da7219_aad_priv *da7219_aad =
|
||||||
container_of(work, struct da7219_aad_priv, btn_det_work);
|
container_of(work, struct da7219_aad_priv, btn_det_work);
|
||||||
struct snd_soc_codec *codec = da7219_aad->codec;
|
struct snd_soc_component *component = da7219_aad->component;
|
||||||
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 statusa, micbias_ctrl;
|
u8 statusa, micbias_ctrl;
|
||||||
bool micbias_up = false;
|
bool micbias_up = false;
|
||||||
int retries = 0;
|
int retries = 0;
|
||||||
|
|
||||||
/* Drive headphones/lineout */
|
/* 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,
|
||||||
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,
|
||||||
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);
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
do {
|
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)
|
if (statusa & DA7219_MICBIAS_UP_STS_MASK)
|
||||||
micbias_up = true;
|
micbias_up = true;
|
||||||
else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
|
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));
|
} while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
|
||||||
|
|
||||||
if (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
|
* 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) {
|
if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
|
||||||
/* Pulse higher level voltage */
|
/* Pulse higher level voltage */
|
||||||
micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
|
micbias_ctrl = snd_soc_component_read32(component, DA7219_MICBIAS_CTRL);
|
||||||
snd_soc_update_bits(codec, DA7219_MICBIAS_CTRL,
|
snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
|
||||||
DA7219_MICBIAS1_LEVEL_MASK,
|
DA7219_MICBIAS1_LEVEL_MASK,
|
||||||
da7219_aad->micbias_pulse_lvl);
|
da7219_aad->micbias_pulse_lvl);
|
||||||
msleep(da7219_aad->micbias_pulse_time);
|
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_BUTTON_CONFIG_MASK,
|
||||||
da7219_aad->btn_cfg);
|
da7219_aad->btn_cfg);
|
||||||
}
|
}
|
||||||
@ -110,9 +110,9 @@ static void da7219_aad_hptest_work(struct work_struct *work)
|
|||||||
{
|
{
|
||||||
struct da7219_aad_priv *da7219_aad =
|
struct da7219_aad_priv *da7219_aad =
|
||||||
container_of(work, struct da7219_aad_priv, hptest_work);
|
container_of(work, struct da7219_aad_priv, hptest_work);
|
||||||
struct snd_soc_codec *codec = da7219_aad->codec;
|
struct snd_soc_component *component = da7219_aad->component;
|
||||||
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
u16 tonegen_freq_hptest;
|
u16 tonegen_freq_hptest;
|
||||||
u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
|
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) {
|
if (da7219->mclk) {
|
||||||
ret = clk_prepare_enable(da7219->mclk);
|
ret = clk_prepare_enable(da7219->mclk);
|
||||||
if (ret) {
|
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->pll_lock);
|
||||||
mutex_unlock(&da7219->ctrl_lock);
|
mutex_unlock(&da7219->ctrl_lock);
|
||||||
snd_soc_dapm_mutex_unlock(dapm);
|
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
|
* If MCLK is present, but PLL is not enabled then we enable it here to
|
||||||
* ensure a consistent detection procedure.
|
* 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) {
|
if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
|
||||||
tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
|
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)
|
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);
|
DA7219_PLL_FREQ_OUT_98304);
|
||||||
} else {
|
} else {
|
||||||
tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
|
tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure gain ramping at fastest rate */
|
/* Ensure gain ramping at fastest rate */
|
||||||
gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
|
gain_ramp_ctrl = snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
|
||||||
snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
|
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
|
||||||
|
|
||||||
/* Bypass cache so it saves current settings */
|
/* Bypass cache so it saves current settings */
|
||||||
regcache_cache_bypass(da7219->regmap, true);
|
regcache_cache_bypass(da7219->regmap, true);
|
||||||
|
|
||||||
/* Make sure Tone Generator is disabled */
|
/* 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 */
|
/* 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_MASK,
|
||||||
DA7219_HPTEST_EN_MASK |
|
DA7219_HPTEST_EN_MASK |
|
||||||
DA7219_HPTEST_RES_SEL_1KOHMS);
|
DA7219_HPTEST_RES_SEL_1KOHMS);
|
||||||
|
|
||||||
/* Set gains to 0db */
|
/* Set gains to 0db */
|
||||||
snd_soc_write(codec, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
|
snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
|
||||||
snd_soc_write(codec, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
|
snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
|
||||||
snd_soc_write(codec, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
|
snd_soc_component_write(component, 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_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
|
||||||
|
|
||||||
/* Disable DAC filters, EQs and soft mute */
|
/* 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);
|
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);
|
0);
|
||||||
snd_soc_update_bits(codec, DA7219_DAC_FILTERS5,
|
snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
|
||||||
DA7219_DAC_SOFTMUTE_EN_MASK, 0);
|
DA7219_DAC_SOFTMUTE_EN_MASK, 0);
|
||||||
|
|
||||||
/* Enable HP left & right paths */
|
/* 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);
|
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_MASK | DA7219_DAC_R_SRC_MASK,
|
||||||
DA7219_DAC_L_SRC_TONEGEN |
|
DA7219_DAC_L_SRC_TONEGEN |
|
||||||
DA7219_DAC_R_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 | DA7219_DAC_L_MUTE_EN_MASK,
|
||||||
DA7219_DAC_L_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 | DA7219_DAC_R_MUTE_EN_MASK,
|
||||||
DA7219_DAC_R_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,
|
||||||
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,
|
||||||
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_OUTFILT_ST_1L_SRC_MASK,
|
||||||
DA7219_DMIX_ST_SRC_OUTFILT1L);
|
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_OUTFILT_ST_1R_SRC_MASK,
|
||||||
DA7219_DMIX_ST_SRC_OUTFILT1R);
|
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
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_MUTE_EN_MASK |
|
||||||
DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
|
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_MUTE_EN_MASK |
|
||||||
DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
|
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);
|
msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
|
||||||
|
|
||||||
/* Configure & start Tone Generator */
|
/* 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,
|
regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
|
||||||
&tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
|
&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_MASK | DA7219_TONE_GEN_GAIN_MASK,
|
||||||
DA7219_SWG_SEL_SRAMP |
|
DA7219_SWG_SEL_SRAMP |
|
||||||
DA7219_TONE_GEN_GAIN_MINUS_15DB);
|
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);
|
msleep(DA7219_AAD_HPTEST_PERIOD);
|
||||||
|
|
||||||
/* Grab comparator reading */
|
/* 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)
|
if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
|
||||||
report |= SND_JACK_HEADPHONE;
|
report |= SND_JACK_HEADPHONE;
|
||||||
else
|
else
|
||||||
report |= SND_JACK_LINEOUT;
|
report |= SND_JACK_LINEOUT;
|
||||||
|
|
||||||
/* Stop tone generator */
|
/* 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);
|
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);
|
regcache_cache_bypass(da7219->regmap, false);
|
||||||
|
|
||||||
/* Disable HPTest block */
|
/* 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);
|
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);
|
msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
|
||||||
|
|
||||||
/* Restore gain ramping rate */
|
/* 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 */
|
/* 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);
|
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);
|
DA7219_HP_R_AMP_OE_MASK);
|
||||||
|
|
||||||
/* Restore PLL to previous configuration, if re-configured */
|
/* Restore PLL to previous configuration, if re-configured */
|
||||||
if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
|
if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
|
||||||
((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
|
((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 */
|
/* Remove MCLK, if previously enabled */
|
||||||
if (da7219->mclk)
|
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)
|
static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct da7219_aad_priv *da7219_aad = data;
|
struct da7219_aad_priv *da7219_aad = data;
|
||||||
struct snd_soc_codec *codec = da7219_aad->codec;
|
struct snd_soc_component *component = da7219_aad->component;
|
||||||
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
u8 events[DA7219_AAD_IRQ_REG_MAX];
|
u8 events[DA7219_AAD_IRQ_REG_MAX];
|
||||||
u8 statusa;
|
u8 statusa;
|
||||||
int i, report = 0, mask = 0;
|
int i, report = 0, mask = 0;
|
||||||
@ -358,13 +358,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
|
|||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
/* Read status register for jack insertion & type status */
|
/* 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 */
|
/* Clear events */
|
||||||
regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
|
regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
|
||||||
events, DA7219_AAD_IRQ_REG_MAX);
|
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],
|
events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
|
||||||
statusa);
|
statusa);
|
||||||
|
|
||||||
@ -430,13 +430,13 @@ static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
|
|||||||
da7219_aad->jack_inserted = false;
|
da7219_aad->jack_inserted = false;
|
||||||
|
|
||||||
/* Un-drive headphones/lineout */
|
/* 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);
|
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);
|
DA7219_HP_L_AMP_OE_MASK, 0);
|
||||||
|
|
||||||
/* Ensure button detection disabled */
|
/* 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);
|
DA7219_BUTTON_CONFIG_MASK, 0);
|
||||||
|
|
||||||
/* Disable mic bias */
|
/* 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
|
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) {
|
switch (val) {
|
||||||
case 2800:
|
case 2800:
|
||||||
@ -467,13 +467,13 @@ static enum da7219_aad_micbias_pulse_lvl
|
|||||||
case 2900:
|
case 2900:
|
||||||
return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
|
return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
|
||||||
default:
|
default:
|
||||||
dev_warn(codec->dev, "Invalid micbias pulse level");
|
dev_warn(component->dev, "Invalid micbias pulse level");
|
||||||
return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
|
return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_btn_cfg
|
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) {
|
switch (val) {
|
||||||
case 2:
|
case 2:
|
||||||
@ -491,13 +491,13 @@ static enum da7219_aad_btn_cfg
|
|||||||
case 500:
|
case 500:
|
||||||
return DA7219_AAD_BTN_CFG_500MS;
|
return DA7219_AAD_BTN_CFG_500MS;
|
||||||
default:
|
default:
|
||||||
dev_warn(codec->dev, "Invalid button config");
|
dev_warn(component->dev, "Invalid button config");
|
||||||
return DA7219_AAD_BTN_CFG_10MS;
|
return DA7219_AAD_BTN_CFG_10MS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_mic_det_thr
|
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) {
|
switch (val) {
|
||||||
case 200:
|
case 200:
|
||||||
@ -509,13 +509,13 @@ static enum da7219_aad_mic_det_thr
|
|||||||
case 1000:
|
case 1000:
|
||||||
return DA7219_AAD_MIC_DET_THR_1000_OHMS;
|
return DA7219_AAD_MIC_DET_THR_1000_OHMS;
|
||||||
default:
|
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;
|
return DA7219_AAD_MIC_DET_THR_500_OHMS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_jack_ins_deb
|
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) {
|
switch (val) {
|
||||||
case 5:
|
case 5:
|
||||||
@ -535,13 +535,13 @@ static enum da7219_aad_jack_ins_deb
|
|||||||
case 1000:
|
case 1000:
|
||||||
return DA7219_AAD_JACK_INS_DEB_1S;
|
return DA7219_AAD_JACK_INS_DEB_1S;
|
||||||
default:
|
default:
|
||||||
dev_warn(codec->dev, "Invalid jack insert debounce");
|
dev_warn(component->dev, "Invalid jack insert debounce");
|
||||||
return DA7219_AAD_JACK_INS_DEB_20MS;
|
return DA7219_AAD_JACK_INS_DEB_20MS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_jack_det_rate
|
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")) {
|
if (!strcmp(str, "32ms_64ms")) {
|
||||||
return DA7219_AAD_JACK_DET_RATE_32_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")) {
|
} else if (!strcmp(str, "256ms_512ms")) {
|
||||||
return DA7219_AAD_JACK_DET_RATE_256_512MS;
|
return DA7219_AAD_JACK_DET_RATE_256_512MS;
|
||||||
} else {
|
} 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;
|
return DA7219_AAD_JACK_DET_RATE_256_512MS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_jack_rem_deb
|
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) {
|
switch (val) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -570,13 +570,13 @@ static enum da7219_aad_jack_rem_deb
|
|||||||
case 20:
|
case 20:
|
||||||
return DA7219_AAD_JACK_REM_DEB_20MS;
|
return DA7219_AAD_JACK_REM_DEB_20MS;
|
||||||
default:
|
default:
|
||||||
dev_warn(codec->dev, "Invalid jack removal debounce");
|
dev_warn(component->dev, "Invalid jack removal debounce");
|
||||||
return DA7219_AAD_JACK_REM_DEB_1MS;
|
return DA7219_AAD_JACK_REM_DEB_1MS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_btn_avg
|
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) {
|
switch (val) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -588,13 +588,13 @@ static enum da7219_aad_btn_avg
|
|||||||
case 8:
|
case 8:
|
||||||
return DA7219_AAD_BTN_AVG_8;
|
return DA7219_AAD_BTN_AVG_8;
|
||||||
default:
|
default:
|
||||||
dev_warn(codec->dev, "Invalid button average value");
|
dev_warn(component->dev, "Invalid button average value");
|
||||||
return DA7219_AAD_BTN_AVG_2;
|
return DA7219_AAD_BTN_AVG_2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum da7219_aad_adc_1bit_rpt
|
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) {
|
switch (val) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -606,14 +606,14 @@ static enum da7219_aad_adc_1bit_rpt
|
|||||||
case 8:
|
case 8:
|
||||||
return DA7219_AAD_ADC_1BIT_RPT_8;
|
return DA7219_AAD_ADC_1BIT_RPT_8;
|
||||||
default:
|
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;
|
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 i2c_client *i2c = to_i2c_client(dev);
|
||||||
struct fwnode_handle *aad_np;
|
struct fwnode_handle *aad_np;
|
||||||
struct da7219_aad_pdata *aad_pdata;
|
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)
|
if (!aad_np)
|
||||||
return NULL;
|
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)
|
if (!aad_pdata)
|
||||||
return NULL;
|
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",
|
if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
|
||||||
&fw_val32) >= 0)
|
&fw_val32) >= 0)
|
||||||
aad_pdata->micbias_pulse_lvl =
|
aad_pdata->micbias_pulse_lvl =
|
||||||
da7219_aad_fw_micbias_pulse_lvl(codec, fw_val32);
|
da7219_aad_fw_micbias_pulse_lvl(component, fw_val32);
|
||||||
else
|
else
|
||||||
aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
|
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;
|
aad_pdata->micbias_pulse_time = fw_val32;
|
||||||
|
|
||||||
if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
|
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
|
else
|
||||||
aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
|
aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
|
||||||
|
|
||||||
if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
|
if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
|
||||||
aad_pdata->mic_det_thr =
|
aad_pdata->mic_det_thr =
|
||||||
da7219_aad_fw_mic_det_thr(codec, fw_val32);
|
da7219_aad_fw_mic_det_thr(component, fw_val32);
|
||||||
else
|
else
|
||||||
aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
|
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)
|
if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
|
||||||
aad_pdata->jack_ins_deb =
|
aad_pdata->jack_ins_deb =
|
||||||
da7219_aad_fw_jack_ins_deb(codec, fw_val32);
|
da7219_aad_fw_jack_ins_deb(component, fw_val32);
|
||||||
else
|
else
|
||||||
aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
|
aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
|
||||||
|
|
||||||
if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
|
if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
|
||||||
aad_pdata->jack_det_rate =
|
aad_pdata->jack_det_rate =
|
||||||
da7219_aad_fw_jack_det_rate(codec, fw_str);
|
da7219_aad_fw_jack_det_rate(component, fw_str);
|
||||||
else
|
else
|
||||||
aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
|
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)
|
if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
|
||||||
aad_pdata->jack_rem_deb =
|
aad_pdata->jack_rem_deb =
|
||||||
da7219_aad_fw_jack_rem_deb(codec, fw_val32);
|
da7219_aad_fw_jack_rem_deb(component, fw_val32);
|
||||||
else
|
else
|
||||||
aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
|
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;
|
aad_pdata->c_mic_btn_thr = 0x3E;
|
||||||
|
|
||||||
if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
|
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
|
else
|
||||||
aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
|
aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
|
||||||
|
|
||||||
if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
|
if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
|
||||||
aad_pdata->adc_1bit_rpt =
|
aad_pdata->adc_1bit_rpt =
|
||||||
da7219_aad_fw_adc_1bit_rpt(codec, fw_val32);
|
da7219_aad_fw_adc_1bit_rpt(component, fw_val32);
|
||||||
else
|
else
|
||||||
aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
|
aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
|
||||||
|
|
||||||
return aad_pdata;
|
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_aad_priv *da7219_aad = da7219->aad;
|
||||||
struct da7219_pdata *pdata = da7219->pdata;
|
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);
|
DA7219_MIC_DET_THRESH_SHIFT);
|
||||||
mask |= DA7219_MIC_DET_THRESH_MASK;
|
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;
|
cfg = 0;
|
||||||
mask = 0;
|
mask = 0;
|
||||||
@ -787,15 +787,15 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
|
|||||||
DA7219_JACKDET_REM_DEB_SHIFT);
|
DA7219_JACKDET_REM_DEB_SHIFT);
|
||||||
mask |= DA7219_JACKDET_REM_DEB_MASK;
|
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);
|
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);
|
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);
|
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);
|
aad_pdata->c_mic_btn_thr);
|
||||||
|
|
||||||
cfg = 0;
|
cfg = 0;
|
||||||
@ -818,7 +818,7 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
|
|||||||
DA7219_ADC_1_BIT_REPEAT_SHIFT);
|
DA7219_ADC_1_BIT_REPEAT_SHIFT);
|
||||||
mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
|
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
|
* 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 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;
|
u8 micbias_ctrl;
|
||||||
|
|
||||||
if (da7219_aad->jack) {
|
if (da7219_aad->jack) {
|
||||||
/* Disable jack detection during suspend */
|
/* 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);
|
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.
|
* suspend then this will be dealt with through the IRQ handler.
|
||||||
*/
|
*/
|
||||||
if (da7219_aad->jack_inserted) {
|
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) {
|
if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
|
||||||
snd_soc_dapm_disable_pin(dapm, "Mic Bias");
|
snd_soc_dapm_disable_pin(dapm, "Mic Bias");
|
||||||
snd_soc_dapm_sync(dapm);
|
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 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) {
|
if (da7219_aad->jack) {
|
||||||
/* Re-enable micbias if previously enabled for 4-pole 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 */
|
/* 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,
|
||||||
DA7219_ACCDET_EN_MASK);
|
DA7219_ACCDET_EN_MASK);
|
||||||
}
|
}
|
||||||
@ -883,28 +883,28 @@ void da7219_aad_resume(struct snd_soc_codec *codec)
|
|||||||
* Init/Exit
|
* 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;
|
struct da7219_aad_priv *da7219_aad;
|
||||||
u8 mask[DA7219_AAD_IRQ_REG_MAX];
|
u8 mask[DA7219_AAD_IRQ_REG_MAX];
|
||||||
int ret;
|
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)
|
if (!da7219_aad)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
da7219->aad = da7219_aad;
|
da7219->aad = da7219_aad;
|
||||||
da7219_aad->codec = codec;
|
da7219_aad->component = component;
|
||||||
|
|
||||||
/* Handle any DT/ACPI/platform data */
|
/* Handle any DT/ACPI/platform data */
|
||||||
if (da7219->pdata && !da7219->pdata->aad_pdata)
|
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 */
|
/* 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);
|
DA7219_BUTTON_CONFIG_MASK, 0);
|
||||||
|
|
||||||
INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
|
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,
|
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||||
"da7219-aad", da7219_aad);
|
"da7219-aad", da7219_aad);
|
||||||
if (ret) {
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,9 +928,9 @@ int da7219_aad_init(struct snd_soc_codec *codec)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(da7219_aad_init);
|
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;
|
struct da7219_aad_priv *da7219_aad = da7219->aad;
|
||||||
u8 mask[DA7219_AAD_IRQ_REG_MAX];
|
u8 mask[DA7219_AAD_IRQ_REG_MAX];
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ enum da7219_aad_event_regs {
|
|||||||
|
|
||||||
/* Private data */
|
/* Private data */
|
||||||
struct da7219_aad_priv {
|
struct da7219_aad_priv {
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_component *component;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
u8 micbias_pulse_lvl;
|
u8 micbias_pulse_lvl;
|
||||||
@ -206,14 +206,14 @@ struct da7219_aad_priv {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* AAD control */
|
/* 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 */
|
/* Suspend/Resume */
|
||||||
void da7219_aad_suspend(struct snd_soc_codec *codec);
|
void da7219_aad_suspend(struct snd_soc_component *component);
|
||||||
void da7219_aad_resume(struct snd_soc_codec *codec);
|
void da7219_aad_resume(struct snd_soc_component *component);
|
||||||
|
|
||||||
/* Init/Exit */
|
/* Init/Exit */
|
||||||
int da7219_aad_init(struct snd_soc_codec *codec);
|
int da7219_aad_init(struct snd_soc_component *component);
|
||||||
void da7219_aad_exit(struct snd_soc_codec *codec);
|
void da7219_aad_exit(struct snd_soc_component *component);
|
||||||
|
|
||||||
#endif /* __DA7219_AAD_H */
|
#endif /* __DA7219_AAD_H */
|
||||||
|
@ -256,8 +256,8 @@ static const struct soc_enum da7219_cp_track_mode =
|
|||||||
static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
|
static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&da7219->ctrl_lock);
|
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,
|
static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&da7219->ctrl_lock);
|
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,
|
static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&da7219->ctrl_lock);
|
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,
|
static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&da7219->ctrl_lock);
|
mutex_lock(&da7219->ctrl_lock);
|
||||||
@ -310,55 +310,55 @@ static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ALC */
|
/* 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;
|
u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl;
|
||||||
|
|
||||||
/* Save current state of mic control register */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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);
|
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,
|
||||||
DA7219_MIC_1_AMP_MUTE_EN_MASK);
|
DA7219_MIC_1_AMP_MUTE_EN_MASK);
|
||||||
|
|
||||||
/* Enable input mixers unmuted */
|
/* 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_EN_MASK |
|
||||||
DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
|
DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
|
||||||
DA7219_MIXIN_L_AMP_EN_MASK);
|
DA7219_MIXIN_L_AMP_EN_MASK);
|
||||||
|
|
||||||
/* Enable input filters unmuted */
|
/* 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_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK,
|
||||||
DA7219_ADC_L_EN_MASK);
|
DA7219_ADC_L_EN_MASK);
|
||||||
|
|
||||||
/* Perform auto calibration */
|
/* 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,
|
||||||
DA7219_ALC_AUTO_CALIB_EN_MASK);
|
DA7219_ALC_AUTO_CALIB_EN_MASK);
|
||||||
do {
|
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);
|
} while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK);
|
||||||
|
|
||||||
/* If auto calibration fails, disable DC offset, hybrid ALC */
|
/* If auto calibration fails, disable DC offset, hybrid ALC */
|
||||||
if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
|
if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
|
||||||
dev_warn(codec->dev,
|
dev_warn(component->dev,
|
||||||
"ALC auto calibration failed with overflow\n");
|
"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_OFFSET_EN_MASK |
|
||||||
DA7219_ALC_SYNC_MODE_MASK, 0);
|
DA7219_ALC_SYNC_MODE_MASK, 0);
|
||||||
} else {
|
} else {
|
||||||
/* Enable DC offset cancellation, hybrid mode */
|
/* 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_OFFSET_EN_MASK |
|
||||||
DA7219_ALC_SYNC_MODE_MASK,
|
DA7219_ALC_SYNC_MODE_MASK,
|
||||||
DA7219_ALC_OFFSET_EN_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 */
|
/* 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 */
|
/* 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 */
|
/* 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,
|
static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = snd_soc_put_volsw(kcontrol, ucontrol);
|
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.
|
* make sure calibrated offsets are updated.
|
||||||
*/
|
*/
|
||||||
if ((ret == 1) && (da7219->alc_en))
|
if ((ret == 1) && (da7219->alc_en))
|
||||||
da7219_alc_calib(codec);
|
da7219_alc_calib(component);
|
||||||
|
|
||||||
return ret;
|
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,
|
static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
|
||||||
/* Force ALC offset calibration if enabling ALC */
|
/* Force ALC offset calibration if enabling ALC */
|
||||||
if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
|
if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
|
||||||
da7219_alc_calib(codec);
|
da7219_alc_calib(component);
|
||||||
da7219->alc_en = true;
|
da7219->alc_en = true;
|
||||||
} else {
|
} else {
|
||||||
da7219->alc_en = false;
|
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,
|
static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
struct soc_mixer_control *mixer_ctrl =
|
struct soc_mixer_control *mixer_ctrl =
|
||||||
(struct soc_mixer_control *) kcontrol->private_value;
|
(struct soc_mixer_control *) kcontrol->private_value;
|
||||||
unsigned int reg = mixer_ctrl->reg;
|
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,
|
static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
struct soc_mixer_control *mixer_ctrl =
|
struct soc_mixer_control *mixer_ctrl =
|
||||||
(struct soc_mixer_control *) kcontrol->private_value;
|
(struct soc_mixer_control *) kcontrol->private_value;
|
||||||
unsigned int reg = mixer_ctrl->reg;
|
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,
|
static int da7219_dai_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
u8 pll_ctrl, pll_status;
|
u8 pll_ctrl, pll_status;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
bool srm_lock = false;
|
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:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
if (da7219->master)
|
if (da7219->master)
|
||||||
/* Enable DAI clks for master mode */
|
/* 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,
|
||||||
DA7219_DAI_CLK_EN_MASK);
|
DA7219_DAI_CLK_EN_MASK);
|
||||||
|
|
||||||
/* PC synchronised to DAI */
|
/* 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);
|
DA7219_PC_FREERUN_MASK, 0);
|
||||||
|
|
||||||
/* Slave mode, if SRM not enabled no need for status checks */
|
/* 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)
|
if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Check SRM has locked */
|
/* Check SRM has locked */
|
||||||
do {
|
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) {
|
if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) {
|
||||||
srm_lock = true;
|
srm_lock = true;
|
||||||
} else {
|
} else {
|
||||||
@ -804,18 +804,18 @@ static int da7219_dai_event(struct snd_soc_dapm_widget *w,
|
|||||||
} while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
|
} while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
|
||||||
|
|
||||||
if (!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;
|
return 0;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
/* PC free-running */
|
/* 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,
|
||||||
DA7219_PC_FREERUN_MASK);
|
DA7219_PC_FREERUN_MASK);
|
||||||
|
|
||||||
/* Disable DAI clks if in master mode */
|
/* Disable DAI clks if in master mode */
|
||||||
if (da7219->master)
|
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);
|
DA7219_DAI_CLK_EN_MASK, 0);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
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,
|
static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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;
|
u8 hp_ctrl, min_gain_mask;
|
||||||
|
|
||||||
switch (w->reg) {
|
switch (w->reg) {
|
||||||
@ -860,7 +860,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
/* Enable minimum gain on HP to avoid pops */
|
/* 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);
|
min_gain_mask);
|
||||||
|
|
||||||
msleep(DA7219_MIN_GAIN_DELAY);
|
msleep(DA7219_MIN_GAIN_DELAY);
|
||||||
@ -868,7 +868,7 @@ static int da7219_mixout_event(struct snd_soc_dapm_widget *w,
|
|||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/* Remove minimum gain on HP */
|
/* 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;
|
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,
|
static int da7219_gain_ramp_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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);
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
/* Ensure nominal gain ramping for DAPM sequence */
|
/* Ensure nominal gain ramping for DAPM sequence */
|
||||||
da7219->gain_ramp_ctrl =
|
da7219->gain_ramp_ctrl =
|
||||||
snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
|
snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL);
|
||||||
snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL,
|
snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL,
|
||||||
DA7219_GAIN_RAMP_RATE_NOMINAL);
|
DA7219_GAIN_RAMP_RATE_NOMINAL);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
/* Restore previous gain ramp settings */
|
/* 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);
|
da7219->gain_ramp_ctrl);
|
||||||
break;
|
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,
|
static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||||
int clk_id, unsigned int freq, int dir)
|
int clk_id, unsigned int freq, int dir)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
|
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) {
|
switch (clk_id) {
|
||||||
case DA7219_CLKSRC_MCLK_SQR:
|
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,
|
||||||
DA7219_PLL_MCLK_SQR_EN_MASK);
|
DA7219_PLL_MCLK_SQR_EN_MASK);
|
||||||
break;
|
break;
|
||||||
case DA7219_CLKSRC_MCLK:
|
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);
|
DA7219_PLL_MCLK_SQR_EN_MASK, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1167,9 +1167,9 @@ static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
|||||||
return 0;
|
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_ctrl, indiv_bits, indiv;
|
||||||
u8 pll_frac_top, pll_frac_bot, pll_integer;
|
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 */
|
/* Verify 2MHz - 54MHz MCLK provided, and set input divider */
|
||||||
if (da7219->mclk_rate < 2000000) {
|
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);
|
da7219->mclk_rate);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else if (da7219->mclk_rate <= 4500000) {
|
} 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_bits = DA7219_PLL_INDIV_36_TO_54_MHZ;
|
||||||
indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL;
|
indiv = DA7219_PLL_INDIV_36_TO_54_MHZ_VAL;
|
||||||
} else {
|
} 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);
|
da7219->mclk_rate);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -1208,7 +1208,7 @@ int da7219_set_pll(struct snd_soc_codec *codec, int source, unsigned int fout)
|
|||||||
switch (source) {
|
switch (source) {
|
||||||
case DA7219_SYSCLK_MCLK:
|
case DA7219_SYSCLK_MCLK:
|
||||||
pll_ctrl |= DA7219_PLL_MODE_BYPASS;
|
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_INDIV_MASK |
|
||||||
DA7219_PLL_MODE_MASK, pll_ctrl);
|
DA7219_PLL_MODE_MASK, pll_ctrl);
|
||||||
return 0;
|
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;
|
pll_ctrl |= DA7219_PLL_MODE_SRM;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(codec->dev, "Invalid PLL config\n");
|
dev_err(component->dev, "Invalid PLL config\n");
|
||||||
return -EINVAL;
|
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;
|
pll_frac_bot = (frac_div) & DA7219_BYTE_MASK;
|
||||||
|
|
||||||
/* Write PLL config & dividers */
|
/* Write PLL config & dividers */
|
||||||
snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top);
|
snd_soc_component_write(component, DA7219_PLL_FRAC_TOP, pll_frac_top);
|
||||||
snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot);
|
snd_soc_component_write(component, DA7219_PLL_FRAC_BOT, pll_frac_bot);
|
||||||
snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer);
|
snd_soc_component_write(component, DA7219_PLL_INTEGER, pll_integer);
|
||||||
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,
|
DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK,
|
||||||
pll_ctrl);
|
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,
|
static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
|
||||||
int source, unsigned int fref, unsigned int fout)
|
int source, unsigned int fref, unsigned int fout)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&da7219->pll_lock);
|
mutex_lock(&da7219->pll_lock);
|
||||||
ret = da7219_set_pll(codec, source, fout);
|
ret = da7219_set_pll(component, source, fout);
|
||||||
mutex_unlock(&da7219->pll_lock);
|
mutex_unlock(&da7219->pll_lock);
|
||||||
|
|
||||||
return ret;
|
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)
|
static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
u8 dai_clk_mode = 0, dai_ctrl = 0;
|
u8 dai_clk_mode = 0, dai_ctrl = 0;
|
||||||
|
|
||||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
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 */
|
/* By default 64 BCLKs per WCLK is supported */
|
||||||
dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64;
|
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_BCLKS_PER_WCLK_MASK |
|
||||||
DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
|
DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
|
||||||
dai_clk_mode);
|
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);
|
dai_ctrl);
|
||||||
|
|
||||||
return 0;
|
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,
|
unsigned int tx_mask, unsigned int rx_mask,
|
||||||
int slots, int slot_width)
|
int slots, int slot_width)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
|
struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
|
||||||
u8 dai_bclks_per_wclk;
|
u8 dai_bclks_per_wclk;
|
||||||
u16 offset;
|
u16 offset;
|
||||||
u32 frame_size;
|
u32 frame_size;
|
||||||
|
|
||||||
/* No channels enabled so disable TDM, revert to 64-bit frames */
|
/* No channels enabled so disable TDM, revert to 64-bit frames */
|
||||||
if (!tx_mask) {
|
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_CH_EN_MASK |
|
||||||
DA7219_DAI_TDM_MODE_EN_MASK, 0);
|
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_MASK,
|
||||||
DA7219_DAI_BCLKS_PER_WCLK_64);
|
DA7219_DAI_BCLKS_PER_WCLK_64);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1368,14 +1368,14 @@ static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
|
|||||||
|
|
||||||
/* Check we have valid slots */
|
/* Check we have valid slots */
|
||||||
if (fls(tx_mask) > DA7219_DAI_TDM_MAX_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);
|
DA7219_DAI_TDM_MAX_SLOTS);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check we have a valid offset given */
|
/* Check we have a valid offset given */
|
||||||
if (rx_mask > DA7219_DAI_OFFSET_MAX) {
|
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);
|
DA7219_DAI_OFFSET_MAX);
|
||||||
return -EINVAL;
|
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;
|
dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
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,
|
DA7219_DAI_BCLKS_PER_WCLK_MASK,
|
||||||
dai_bclks_per_wclk);
|
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,
|
regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
|
||||||
&offset, sizeof(offset));
|
&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_CH_EN_MASK |
|
||||||
DA7219_DAI_TDM_MODE_EN_MASK,
|
DA7219_DAI_TDM_MODE_EN_MASK,
|
||||||
(tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
|
(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_pcm_hw_params *params,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
u8 dai_ctrl = 0, fs;
|
u8 dai_ctrl = 0, fs;
|
||||||
unsigned int channels;
|
unsigned int channels;
|
||||||
|
|
||||||
@ -1444,7 +1444,7 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
|
|||||||
|
|
||||||
channels = params_channels(params);
|
channels = params_channels(params);
|
||||||
if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) {
|
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",
|
"Invalid number of channels, only 1 to %d supported\n",
|
||||||
DA7219_DAI_CH_NUM_MAX);
|
DA7219_DAI_CH_NUM_MAX);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1489,11 +1489,11 @@ static int da7219_hw_params(struct snd_pcm_substream *substream,
|
|||||||
return -EINVAL;
|
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_WORD_LENGTH_MASK |
|
||||||
DA7219_DAI_CH_NUM_MASK,
|
DA7219_DAI_CH_NUM_MASK,
|
||||||
dai_ctrl);
|
dai_ctrl);
|
||||||
snd_soc_write(codec, DA7219_SR, fs);
|
snd_soc_component_write(component, DA7219_SR, fs);
|
||||||
|
|
||||||
return 0;
|
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;
|
struct da7219_pdata *pdata;
|
||||||
const char *of_str;
|
const char *of_str;
|
||||||
u32 of_val32;
|
u32 of_val32;
|
||||||
@ -1616,10 +1616,10 @@ static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_codec *codec)
|
|||||||
* Codec driver functions
|
* 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)
|
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;
|
int ret;
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -1627,11 +1627,11 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
break;
|
break;
|
||||||
case SND_SOC_BIAS_PREPARE:
|
case SND_SOC_BIAS_PREPARE:
|
||||||
/* Enable MCLK for transition to ON state */
|
/* 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) {
|
if (da7219->mclk) {
|
||||||
ret = clk_prepare_enable(da7219->mclk);
|
ret = clk_prepare_enable(da7219->mclk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(codec->dev,
|
dev_err(component->dev,
|
||||||
"Failed to enable mclk\n");
|
"Failed to enable mclk\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1640,13 +1640,13 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case SND_SOC_BIAS_STANDBY:
|
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 */
|
/* 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,
|
||||||
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 */
|
/* Remove MCLK */
|
||||||
if (da7219->mclk)
|
if (da7219->mclk)
|
||||||
clk_disable_unprepare(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:
|
case SND_SOC_BIAS_OFF:
|
||||||
/* Only disable master bias if we're not a wake-up source */
|
/* Only disable master bias if we're not a wake-up source */
|
||||||
if (!da7219->wakeup_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);
|
DA7219_BIAS_EN_MASK, 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1670,9 +1670,9 @@ static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = {
|
|||||||
[DA7219_SUPPLY_VDDIO] = "VDDIO",
|
[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;
|
struct regulator *vddio;
|
||||||
u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
|
u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
|
||||||
int i, ret;
|
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)
|
for (i = 0; i < DA7219_NUM_SUPPLIES; ++i)
|
||||||
da7219->supplies[i].supply = da7219_supply_names[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);
|
da7219->supplies);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(codec->dev, "Failed to get supplies");
|
dev_err(component->dev, "Failed to get supplies");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1692,29 +1692,29 @@ static int da7219_handle_supplies(struct snd_soc_codec *codec)
|
|||||||
vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
|
vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
|
||||||
ret = regulator_get_voltage(vddio);
|
ret = regulator_get_voltage(vddio);
|
||||||
if (ret < 1200000)
|
if (ret < 1200000)
|
||||||
dev_warn(codec->dev, "Invalid VDDIO voltage\n");
|
dev_warn(component->dev, "Invalid VDDIO voltage\n");
|
||||||
else if (ret < 2800000)
|
else if (ret < 2800000)
|
||||||
io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
|
io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
|
||||||
|
|
||||||
/* Enable main supplies */
|
/* Enable main supplies */
|
||||||
ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
|
ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(codec->dev, "Failed to enable supplies");
|
dev_err(component->dev, "Failed to enable supplies");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure device in active mode */
|
/* 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 */
|
/* 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;
|
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;
|
struct da7219_pdata *pdata = da7219->pdata;
|
||||||
|
|
||||||
if (pdata) {
|
if (pdata) {
|
||||||
@ -1735,14 +1735,14 @@ static void da7219_handle_pdata(struct snd_soc_codec *codec)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl);
|
snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_lvl);
|
||||||
|
|
||||||
/* Mic */
|
/* Mic */
|
||||||
switch (pdata->mic_amp_in_sel) {
|
switch (pdata->mic_amp_in_sel) {
|
||||||
case DA7219_MIC_AMP_IN_SEL_DIFF:
|
case DA7219_MIC_AMP_IN_SEL_DIFF:
|
||||||
case DA7219_MIC_AMP_IN_SEL_SE_P:
|
case DA7219_MIC_AMP_IN_SEL_SE_P:
|
||||||
case DA7219_MIC_AMP_IN_SEL_SE_N:
|
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);
|
pdata->mic_amp_in_sel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1753,9 +1753,9 @@ static struct reg_sequence da7219_rev_aa_patch[] = {
|
|||||||
{ DA7219_REFERENCES, 0x08 },
|
{ 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;
|
unsigned int rev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1763,13 +1763,13 @@ static int da7219_probe(struct snd_soc_codec *codec)
|
|||||||
mutex_init(&da7219->pll_lock);
|
mutex_init(&da7219->pll_lock);
|
||||||
|
|
||||||
/* Regulator configuration */
|
/* Regulator configuration */
|
||||||
ret = da7219_handle_supplies(codec);
|
ret = da7219_handle_supplies(component);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev);
|
ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev);
|
||||||
if (ret) {
|
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;
|
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,
|
ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch,
|
||||||
ARRAY_SIZE(da7219_rev_aa_patch));
|
ARRAY_SIZE(da7219_rev_aa_patch));
|
||||||
if (ret) {
|
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);
|
ret);
|
||||||
goto err_disable_reg;
|
goto err_disable_reg;
|
||||||
}
|
}
|
||||||
@ -1788,14 +1788,14 @@ static int da7219_probe(struct snd_soc_codec *codec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle DT/ACPI/Platform data */
|
/* Handle DT/ACPI/Platform data */
|
||||||
da7219->pdata = dev_get_platdata(codec->dev);
|
da7219->pdata = dev_get_platdata(component->dev);
|
||||||
if (!da7219->pdata)
|
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 */
|
/* 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 (IS_ERR(da7219->mclk)) {
|
||||||
if (PTR_ERR(da7219->mclk) != -ENOENT) {
|
if (PTR_ERR(da7219->mclk) != -ENOENT) {
|
||||||
ret = PTR_ERR(da7219->mclk);
|
ret = PTR_ERR(da7219->mclk);
|
||||||
@ -1806,39 +1806,39 @@ static int da7219_probe(struct snd_soc_codec *codec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Default PC counter to free-running */
|
/* 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);
|
DA7219_PC_FREERUN_MASK);
|
||||||
|
|
||||||
/* Default gain ramping */
|
/* 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,
|
||||||
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);
|
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);
|
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);
|
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,
|
||||||
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,
|
||||||
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 */
|
/* 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,
|
||||||
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,
|
||||||
DA7219_HP_R_AMP_MIN_GAIN_EN_MASK);
|
DA7219_HP_R_AMP_MIN_GAIN_EN_MASK);
|
||||||
|
|
||||||
/* Default infinite tone gen, start/stop by Kcontrol */
|
/* 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 */
|
/* Initialise AAD block */
|
||||||
ret = da7219_aad_init(codec);
|
ret = da7219_aad_init(component);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_disable_reg;
|
goto err_disable_reg;
|
||||||
|
|
||||||
@ -1850,39 +1850,39 @@ err_disable_reg:
|
|||||||
return ret;
|
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 */
|
/* Supplies */
|
||||||
return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
|
regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#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 */
|
/* Suspend AAD if we're not a wake-up source */
|
||||||
if (!da7219->wakeup_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;
|
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 */
|
/* Resume AAD if previously suspended */
|
||||||
if (!da7219->wakeup_source)
|
if (!da7219->wakeup_source)
|
||||||
da7219_aad_resume(codec);
|
da7219_aad_resume(component);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1891,21 +1891,22 @@ static int da7219_resume(struct snd_soc_codec *codec)
|
|||||||
#define da7219_resume NULL
|
#define da7219_resume NULL
|
||||||
#endif
|
#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,
|
.probe = da7219_probe,
|
||||||
.remove = da7219_remove,
|
.remove = da7219_remove,
|
||||||
.suspend = da7219_suspend,
|
.suspend = da7219_suspend,
|
||||||
.resume = da7219_resume,
|
.resume = da7219_resume,
|
||||||
.set_bias_level = da7219_set_bias_level,
|
.set_bias_level = da7219_set_bias_level,
|
||||||
|
.controls = da7219_snd_controls,
|
||||||
.component_driver = {
|
.num_controls = ARRAY_SIZE(da7219_snd_controls),
|
||||||
.controls = da7219_snd_controls,
|
.dapm_widgets = da7219_dapm_widgets,
|
||||||
.num_controls = ARRAY_SIZE(da7219_snd_controls),
|
.num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
|
||||||
.dapm_widgets = da7219_dapm_widgets,
|
.dapm_routes = da7219_audio_map,
|
||||||
.num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
|
.num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
|
||||||
.dapm_routes = da7219_audio_map,
|
.idle_bias_on = 1,
|
||||||
.num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
|
.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,
|
regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
|
||||||
DA7219_ACCDET_EN_MASK, 0);
|
DA7219_ACCDET_EN_MASK, 0);
|
||||||
regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
|
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);
|
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);
|
&da7219_dai, 1);
|
||||||
if (ret < 0) {
|
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);
|
ret);
|
||||||
}
|
}
|
||||||
return 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)
|
static int da7219_i2c_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
snd_soc_unregister_codec(&client->dev);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,6 +822,6 @@ struct da7219_priv {
|
|||||||
u8 gain_ramp_ctrl;
|
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 */
|
#endif /* __DA7219_H */
|
||||||
|
@ -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,
|
static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
|
||||||
hda_nid_t nid, unsigned int pwr_state)
|
hda_nid_t nid, unsigned int pwr_state)
|
||||||
{
|
{
|
||||||
|
int count;
|
||||||
|
unsigned int state;
|
||||||
|
|
||||||
if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) {
|
if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) {
|
||||||
if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state))
|
if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state)) {
|
||||||
snd_hdac_codec_write(&edev->hdev, nid, 0,
|
for (count = 0; count < 10; count++) {
|
||||||
AC_VERB_SET_POWER_STATE, pwr_state);
|
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_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
|
||||||
struct hdac_hdmi_pin *pin = NULL;
|
struct hdac_hdmi_pin *pin = NULL;
|
||||||
struct hdac_hdmi_port *hport = NULL;
|
struct hdac_hdmi_port *hport = NULL;
|
||||||
struct snd_soc_codec *codec = edev->scodec;
|
struct snd_soc_component *component = edev->scodec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Don't know how this mapping is derived */
|
/* 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,
|
* connection states are updated in anyway at the end of the resume,
|
||||||
* we can skip it when received during PM process.
|
* 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)
|
SNDRV_CTL_POWER_D0)
|
||||||
return;
|
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 kc_name[NAME_SIZE], xname[NAME_SIZE];
|
||||||
char *name;
|
char *name;
|
||||||
int i = 0, j;
|
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);
|
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);
|
sizeof(*kc), GFP_KERNEL);
|
||||||
|
|
||||||
if (!kc)
|
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++) {
|
for (j = 0; j < pin->num_ports; j++) {
|
||||||
snprintf(xname, sizeof(xname), "hif%d-%d Jack",
|
snprintf(xname, sizeof(xname), "hif%d-%d Jack",
|
||||||
pin->nid, pin->ports[j].id);
|
pin->nid, pin->ports[j].id);
|
||||||
name = devm_kstrdup(codec->dev, xname, GFP_KERNEL);
|
name = devm_kstrdup(component->dev, xname, GFP_KERNEL);
|
||||||
if (!name)
|
if (!name)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
snprintf(kc_name, sizeof(kc_name), "%s Switch", xname);
|
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);
|
GFP_KERNEL);
|
||||||
if (!kc[i].name)
|
if (!kc[i].name)
|
||||||
return -ENOMEM;
|
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);
|
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 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_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
|
||||||
struct hdac_hdmi_pin *pin;
|
struct hdac_hdmi_pin *pin;
|
||||||
struct snd_soc_dapm_widget *widgets;
|
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,
|
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
|
||||||
struct snd_soc_jack *jack)
|
struct snd_soc_jack *jack)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->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 hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
|
||||||
struct hdac_hdmi_pcm *pcm;
|
struct hdac_hdmi_pcm *pcm;
|
||||||
struct snd_pcm *snd_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 hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
|
||||||
struct snd_soc_dapm_context *dapm =
|
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;
|
struct hdac_ext_link *hlink = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
edev->scodec = codec;
|
edev->scodec = component;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hold the ref while we probe, also no need to drop the ref on
|
* 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;
|
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);
|
pm_runtime_disable(&edev->hdev.dev);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
@ -1891,10 +1902,12 @@ static void hdmi_codec_complete(struct device *dev)
|
|||||||
#define hdmi_codec_complete NULL
|
#define hdmi_codec_complete NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct snd_soc_codec_driver hdmi_hda_codec = {
|
static const struct snd_soc_component_driver hdmi_hda_codec = {
|
||||||
.probe = hdmi_codec_probe,
|
.probe = hdmi_codec_probe,
|
||||||
.remove = hdmi_codec_remove,
|
.remove = hdmi_codec_remove,
|
||||||
.idle_bias_off = true,
|
.use_pmdown_time = 1,
|
||||||
|
.endianness = 1,
|
||||||
|
.non_legacy_dai_naming = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,
|
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);
|
snd_hdac_refresh_widgets(hdev, true);
|
||||||
|
|
||||||
/* ASoC specific initialization */
|
/* 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);
|
hdmi_dais, num_dais);
|
||||||
|
|
||||||
snd_hdac_ext_bus_link_put(edev->ebus, hlink);
|
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;
|
struct hdac_hdmi_port *port, *port_next;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
snd_soc_unregister_codec(&edev->hdev.dev);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
|
list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
|
||||||
pcm->cvt = NULL;
|
pcm->cvt = NULL;
|
||||||
if (list_empty(&pcm->port_list))
|
if (list_empty(&pcm->port_list))
|
||||||
|
@ -5,6 +5,6 @@
|
|||||||
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
|
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
|
||||||
struct snd_soc_jack *jack);
|
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);
|
struct snd_soc_dapm_context *dapm);
|
||||||
#endif /* __HDAC_HDMI_H__ */
|
#endif /* __HDAC_HDMI_H__ */
|
||||||
|
@ -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,
|
static int nau8825_adc_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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);
|
||||||
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
|
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
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,
|
static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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);
|
||||||
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
|
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
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,
|
static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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);
|
||||||
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
|
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
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_pcm_hw_params *params,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
|
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
|
||||||
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
|
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
|
||||||
|
|
||||||
nau8825_sema_acquire(nau8825, 3 * HZ);
|
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)
|
static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
|
struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
|
||||||
unsigned int ctrl1_val = 0, ctrl2_val = 0;
|
unsigned int ctrl1_val = 0, ctrl2_val = 0;
|
||||||
|
|
||||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
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
|
* events will be routed to the given jack. Jack can be null to stop
|
||||||
* reporting.
|
* 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 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;
|
struct regmap *regmap = nau8825->regmap;
|
||||||
|
|
||||||
nau8825->jack = jack;
|
nau8825->jack = jack;
|
||||||
@ -1952,24 +1952,22 @@ static const struct regmap_config nau8825_regmap_config = {
|
|||||||
.num_reg_defaults = ARRAY_SIZE(nau8825_reg_defaults),
|
.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 nau8825 *nau8825 = snd_soc_component_get_drvdata(component);
|
||||||
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||||
|
|
||||||
nau8825->dapm = dapm;
|
nau8825->dapm = dapm;
|
||||||
|
|
||||||
return 0;
|
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 */
|
/* Cancel and reset cross tak suppresstion detection funciton */
|
||||||
nau8825_xtalk_cancel(nau8825);
|
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 */
|
/* 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)
|
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;
|
struct nau8825_fll fll_param;
|
||||||
int ret, fs;
|
int ret, fs;
|
||||||
|
|
||||||
fs = freq_out / 256;
|
fs = freq_out / 256;
|
||||||
ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
|
ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
|
||||||
if (ret < 0) {
|
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;
|
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.mclk_src, fll_param.ratio, fll_param.fll_frac,
|
||||||
fll_param.fll_int, fll_param.clk_ref_div);
|
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;
|
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)
|
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);
|
return nau8825_configure_sysclk(nau8825, clk_id, freq);
|
||||||
}
|
}
|
||||||
@ -2331,10 +2329,10 @@ static int nau8825_resume_setup(struct nau8825 *nau8825)
|
|||||||
return 0;
|
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)
|
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;
|
int ret;
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@ -2345,11 +2343,11 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_SOC_BIAS_STANDBY:
|
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) {
|
if (nau8825->mclk_freq) {
|
||||||
ret = clk_prepare_enable(nau8825->mclk);
|
ret = clk_prepare_enable(nau8825->mclk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
|
dev_err(nau8825->dev, "Unable to prepare component mclk\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2383,12 +2381,12 @@ static int nau8825_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
return 0;
|
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);
|
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 */
|
/* Power down codec power; don't suppoet button wakeup */
|
||||||
snd_soc_dapm_disable_pin(nau8825->dapm, "SAR");
|
snd_soc_dapm_disable_pin(nau8825->dapm, "SAR");
|
||||||
snd_soc_dapm_disable_pin(nau8825->dapm, "MICBIAS");
|
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;
|
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;
|
int ret;
|
||||||
|
|
||||||
regcache_cache_only(nau8825->regmap, false);
|
regcache_cache_only(nau8825->regmap, false);
|
||||||
@ -2415,24 +2413,25 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct snd_soc_codec_driver nau8825_codec_driver = {
|
static const struct snd_soc_component_driver nau8825_component_driver = {
|
||||||
.probe = nau8825_codec_probe,
|
.probe = nau8825_component_probe,
|
||||||
.remove = nau8825_codec_remove,
|
.remove = nau8825_component_remove,
|
||||||
.set_sysclk = nau8825_set_sysclk,
|
.set_sysclk = nau8825_set_sysclk,
|
||||||
.set_pll = nau8825_set_pll,
|
.set_pll = nau8825_set_pll,
|
||||||
.set_bias_level = nau8825_set_bias_level,
|
.set_bias_level = nau8825_set_bias_level,
|
||||||
.suspend_bias_off = true,
|
.suspend = nau8825_suspend,
|
||||||
.suspend = nau8825_suspend,
|
.resume = nau8825_resume,
|
||||||
.resume = nau8825_resume,
|
.controls = nau8825_controls,
|
||||||
|
.num_controls = ARRAY_SIZE(nau8825_controls),
|
||||||
.component_driver = {
|
.dapm_widgets = nau8825_dapm_widgets,
|
||||||
.controls = nau8825_controls,
|
.num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
|
||||||
.num_controls = ARRAY_SIZE(nau8825_controls),
|
.dapm_routes = nau8825_dapm_routes,
|
||||||
.dapm_widgets = nau8825_dapm_widgets,
|
.num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
|
||||||
.num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
|
.suspend_bias_off = 1,
|
||||||
.dapm_routes = nau8825_dapm_routes,
|
.idle_bias_on = 1,
|
||||||
.num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
|
.use_pmdown_time = 1,
|
||||||
},
|
.endianness = 1,
|
||||||
|
.non_legacy_dai_naming = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nau8825_reset_chip(struct regmap *regmap)
|
static void nau8825_reset_chip(struct regmap *regmap)
|
||||||
@ -2619,13 +2618,13 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
|
|||||||
if (i2c->irq)
|
if (i2c->irq)
|
||||||
nau8825_setup_irq(nau8825);
|
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);
|
&nau8825_dai, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nau8825_i2c_remove(struct i2c_client *client)
|
static int nau8825_i2c_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
snd_soc_unregister_codec(&client->dev);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ struct nau8825 {
|
|||||||
bool xtalk_baktab_initialized; /* True if initialized. */
|
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);
|
struct snd_soc_jack *jack);
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ struct rt286_priv {
|
|||||||
struct reg_default *index_cache;
|
struct reg_default *index_cache;
|
||||||
int index_cache_size;
|
int index_cache_size;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_component *component;
|
||||||
struct rt286_platform_data pdata;
|
struct rt286_platform_data pdata;
|
||||||
struct i2c_client *i2c;
|
struct i2c_client *i2c;
|
||||||
struct snd_soc_jack *jack;
|
struct snd_soc_jack *jack;
|
||||||
@ -187,13 +187,13 @@ static bool rt286_readable_register(struct device *dev, unsigned int reg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < INDEX_CACHE_SIZE; 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);
|
rt286->index_cache[i].def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,10 +220,10 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
|
|||||||
*hp = false;
|
*hp = false;
|
||||||
*mic = false;
|
*mic = false;
|
||||||
|
|
||||||
if (!rt286->codec)
|
if (!rt286->component)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dapm = snd_soc_codec_get_dapm(rt286->codec);
|
dapm = snd_soc_component_get_dapm(rt286->component);
|
||||||
|
|
||||||
if (rt286->pdata.cbj_en) {
|
if (rt286->pdata.cbj_en) {
|
||||||
regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
|
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);
|
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 snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||||
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
|
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
rt286->jack = jack;
|
rt286->jack = jack;
|
||||||
|
|
||||||
@ -334,8 +334,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect);
|
|||||||
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
|
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
|
||||||
struct snd_soc_dapm_widget *sink)
|
struct snd_soc_dapm_widget *sink)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
|
||||||
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
|
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
if (rt286->clk_id == RT286_SCLK_S_MCLK)
|
if (rt286->clk_id == RT286_SCLK_S_MCLK)
|
||||||
return 1;
|
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,
|
static int rt286_spk_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT286_SPK_EAPD, RT286_SET_EAPD_HIGH);
|
RT286_SPK_EAPD, RT286_SET_EAPD_HIGH);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT286_SPK_EAPD, RT286_SET_EAPD_LOW);
|
RT286_SPK_EAPD, RT286_SET_EAPD_LOW);
|
||||||
break;
|
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,
|
static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
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;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
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,
|
static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
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;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
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,
|
static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
|
RT286_A_BIAS_CTRL3, 0xc000, 0x8000);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
|
RT286_A_BIAS_CTRL2, 0xc000, 0x8000);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
|
RT286_A_BIAS_CTRL3, 0xc000, 0x0000);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
|
RT286_A_BIAS_CTRL2, 0xc000, 0x0000);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -674,8 +674,8 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
|||||||
struct snd_pcm_hw_params *params,
|
struct snd_pcm_hw_params *params,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
|
struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component);
|
||||||
unsigned int val = 0;
|
unsigned int val = 0;
|
||||||
int d_len_code;
|
int d_len_code;
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
|||||||
case 48000:
|
case 48000:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(codec->dev, "Unsupported sample rate %d\n",
|
dev_err(component->dev, "Unsupported sample rate %d\n",
|
||||||
params_rate(params));
|
params_rate(params));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -695,7 +695,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
|||||||
case 12288000:
|
case 12288000:
|
||||||
case 24576000:
|
case 24576000:
|
||||||
if (params_rate(params) != 48000) {
|
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);
|
params_rate(params), rt286->sys_clk);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -703,7 +703,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
|||||||
case 11289600:
|
case 11289600:
|
||||||
case 22579200:
|
case 22579200:
|
||||||
if (params_rate(params) != 44100) {
|
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);
|
params_rate(params), rt286->sys_clk);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -714,7 +714,7 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
|||||||
/* bit 3:0 Number of Channel */
|
/* bit 3:0 Number of Channel */
|
||||||
val |= (params_channels(params) - 1);
|
val |= (params_channels(params) - 1);
|
||||||
} else {
|
} else {
|
||||||
dev_err(codec->dev, "Unsupported channels %d\n",
|
dev_err(component->dev, "Unsupported channels %d\n",
|
||||||
params_channels(params));
|
params_channels(params));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -745,27 +745,27 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x0018, d_len_code << 3);
|
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_component_update_bits(component, RT286_DAC_FORMAT, 0x407f, val);
|
||||||
snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x407f, val);
|
snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x407f, val);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt286_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
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) {
|
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||||
case SND_SOC_DAIFMT_CBM_CFM:
|
case SND_SOC_DAIFMT_CBM_CFM:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x800, 0x800);
|
RT286_I2S_CTRL1, 0x800, 0x800);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_CBS_CFS:
|
case SND_SOC_DAIFMT_CBS_CFS:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x800, 0x0);
|
RT286_I2S_CTRL1, 0x800, 0x0);
|
||||||
break;
|
break;
|
||||||
default:
|
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) {
|
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||||
case SND_SOC_DAIFMT_I2S:
|
case SND_SOC_DAIFMT_I2S:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x300, 0x0);
|
RT286_I2S_CTRL1, 0x300, 0x0);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_LEFT_J:
|
case SND_SOC_DAIFMT_LEFT_J:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x300, 0x1 << 8);
|
RT286_I2S_CTRL1, 0x300, 0x1 << 8);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_DSP_A:
|
case SND_SOC_DAIFMT_DSP_A:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x300, 0x2 << 8);
|
RT286_I2S_CTRL1, 0x300, 0x2 << 8);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_DSP_B:
|
case SND_SOC_DAIFMT_DSP_B:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x300, 0x3 << 8);
|
RT286_I2S_CTRL1, 0x300, 0x3 << 8);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
/* bit 15 Stream Type 0:PCM 1:Non-PCM */
|
/* bit 15 Stream Type 0:PCM 1:Non-PCM */
|
||||||
snd_soc_update_bits(codec, RT286_DAC_FORMAT, 0x8000, 0);
|
snd_soc_component_update_bits(component, RT286_DAC_FORMAT, 0x8000, 0);
|
||||||
snd_soc_update_bits(codec, RT286_ADC_FORMAT, 0x8000, 0);
|
snd_soc_component_update_bits(component, RT286_ADC_FORMAT, 0x8000, 0);
|
||||||
|
|
||||||
return 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,
|
static int rt286_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||||
int clk_id, unsigned int freq, int dir)
|
int clk_id, unsigned int freq, int dir)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
|
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) {
|
if (RT286_SCLK_S_MCLK == clk_id) {
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL2, 0x0100, 0x0);
|
RT286_I2S_CTRL2, 0x0100, 0x0);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_PLL_CTRL1, 0x20, 0x20);
|
RT286_PLL_CTRL1, 0x20, 0x20);
|
||||||
} else {
|
} else {
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL2, 0x0100, 0x0100);
|
RT286_I2S_CTRL2, 0x0100, 0x0100);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_PLL_CTRL, 0x4, 0x4);
|
RT286_PLL_CTRL, 0x4, 0x4);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_PLL_CTRL1, 0x20, 0x0);
|
RT286_PLL_CTRL1, 0x20, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (freq) {
|
switch (freq) {
|
||||||
case 19200000:
|
case 19200000:
|
||||||
if (RT286_SCLK_S_MCLK == clk_id) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL2, 0x40, 0x40);
|
RT286_I2S_CTRL2, 0x40, 0x40);
|
||||||
break;
|
break;
|
||||||
case 24000000:
|
case 24000000:
|
||||||
if (RT286_SCLK_S_MCLK == clk_id) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL2, 0x40, 0x0);
|
RT286_I2S_CTRL2, 0x40, 0x0);
|
||||||
break;
|
break;
|
||||||
case 12288000:
|
case 12288000:
|
||||||
case 11289600:
|
case 11289600:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL2, 0x8, 0x0);
|
RT286_I2S_CTRL2, 0x8, 0x0);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_CLK_DIV, 0xfc1e, 0x0004);
|
RT286_CLK_DIV, 0xfc1e, 0x0004);
|
||||||
break;
|
break;
|
||||||
case 24576000:
|
case 24576000:
|
||||||
case 22579200:
|
case 22579200:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL2, 0x8, 0x8);
|
RT286_I2S_CTRL2, 0x8, 0x8);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_CLK_DIV, 0xfc1e, 0x5406);
|
RT286_CLK_DIV, 0xfc1e, 0x5406);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(codec->dev, "Unsupported system clock\n");
|
dev_err(component->dev, "Unsupported system clock\n");
|
||||||
return -EINVAL;
|
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)
|
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)
|
if (50 == ratio)
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x1000, 0x1000);
|
RT286_I2S_CTRL1, 0x1000, 0x1000);
|
||||||
else
|
else
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_I2S_CTRL1, 0x1000, 0x0);
|
RT286_I2S_CTRL1, 0x1000, 0x0);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
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)
|
enum snd_soc_bias_level level)
|
||||||
{
|
{
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case SND_SOC_BIAS_PREPARE:
|
case SND_SOC_BIAS_PREPARE:
|
||||||
if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
|
if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT286_SET_AUDIO_POWER, AC_PWRST_D0);
|
RT286_SET_AUDIO_POWER, AC_PWRST_D0);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_DC_GAIN, 0x200, 0x200);
|
RT286_DC_GAIN, 0x200, 0x200);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_SOC_BIAS_ON:
|
case SND_SOC_BIAS_ON:
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT286_DC_GAIN, 0x200, 0x0);
|
RT286_DC_GAIN, 0x200, 0x0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_SOC_BIAS_STANDBY:
|
case SND_SOC_BIAS_STANDBY:
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT286_SET_AUDIO_POWER, AC_PWRST_D3);
|
RT286_SET_AUDIO_POWER, AC_PWRST_D3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -937,11 +937,11 @@ static irqreturn_t rt286_irq(int irq, void *data)
|
|||||||
return IRQ_HANDLED;
|
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) {
|
if (rt286->i2c->irq) {
|
||||||
regmap_update_bits(rt286->regmap,
|
regmap_update_bits(rt286->regmap,
|
||||||
@ -956,19 +956,17 @@ static int rt286_probe(struct snd_soc_codec *codec)
|
|||||||
return 0;
|
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);
|
cancel_delayed_work_sync(&rt286->jack_detect_work);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#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_cache_only(rt286->regmap, true);
|
||||||
regcache_mark_dirty(rt286->regmap);
|
regcache_mark_dirty(rt286->regmap);
|
||||||
@ -976,12 +974,12 @@ static int rt286_suspend(struct snd_soc_codec *codec)
|
|||||||
return 0;
|
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);
|
regcache_cache_only(rt286->regmap, false);
|
||||||
rt286_index_sync(codec);
|
rt286_index_sync(component);
|
||||||
regcache_sync(rt286->regmap);
|
regcache_sync(rt286->regmap);
|
||||||
|
|
||||||
return 0;
|
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 = {
|
static const struct snd_soc_component_driver soc_component_dev_rt286 = {
|
||||||
.probe = rt286_probe,
|
.probe = rt286_probe,
|
||||||
.remove = rt286_remove,
|
.remove = rt286_remove,
|
||||||
.suspend = rt286_suspend,
|
.suspend = rt286_suspend,
|
||||||
.resume = rt286_resume,
|
.resume = rt286_resume,
|
||||||
.set_bias_level = rt286_set_bias_level,
|
.set_bias_level = rt286_set_bias_level,
|
||||||
.idle_bias_off = true,
|
.controls = rt286_snd_controls,
|
||||||
.component_driver = {
|
.num_controls = ARRAY_SIZE(rt286_snd_controls),
|
||||||
.controls = rt286_snd_controls,
|
.dapm_widgets = rt286_dapm_widgets,
|
||||||
.num_controls = ARRAY_SIZE(rt286_snd_controls),
|
.num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
|
||||||
.dapm_widgets = rt286_dapm_widgets,
|
.dapm_routes = rt286_dapm_routes,
|
||||||
.num_dapm_widgets = ARRAY_SIZE(rt286_dapm_widgets),
|
.num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
|
||||||
.dapm_routes = rt286_dapm_routes,
|
.use_pmdown_time = 1,
|
||||||
.num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes),
|
.endianness = 1,
|
||||||
},
|
.non_legacy_dai_naming = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct regmap_config rt286_regmap = {
|
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));
|
rt286_dai, ARRAY_SIZE(rt286_dai));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1255,7 +1254,6 @@ static int rt286_i2c_remove(struct i2c_client *i2c)
|
|||||||
|
|
||||||
if (i2c->irq)
|
if (i2c->irq)
|
||||||
free_irq(i2c->irq, rt286);
|
free_irq(i2c->irq, rt286);
|
||||||
snd_soc_unregister_codec(&i2c->dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ enum {
|
|||||||
RT286_AIFS,
|
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__ */
|
#endif /* __RT286_H__ */
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ struct rt298_priv {
|
|||||||
struct reg_default *index_cache;
|
struct reg_default *index_cache;
|
||||||
int index_cache_size;
|
int index_cache_size;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_component *component;
|
||||||
struct rt298_platform_data pdata;
|
struct rt298_platform_data pdata;
|
||||||
struct i2c_client *i2c;
|
struct i2c_client *i2c;
|
||||||
struct snd_soc_jack *jack;
|
struct snd_soc_jack *jack;
|
||||||
@ -194,13 +194,13 @@ static bool rt298_readable_register(struct device *dev, unsigned int reg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < INDEX_CACHE_SIZE; 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);
|
rt298->index_cache[i].def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,10 +227,10 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
|
|||||||
*hp = false;
|
*hp = false;
|
||||||
*mic = false;
|
*mic = false;
|
||||||
|
|
||||||
if (!rt298->codec)
|
if (!rt298->component)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dapm = snd_soc_codec_get_dapm(rt298->codec);
|
dapm = snd_soc_component_get_dapm(rt298->component);
|
||||||
|
|
||||||
if (rt298->pdata.cbj_en) {
|
if (rt298->pdata.cbj_en) {
|
||||||
regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf);
|
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);
|
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;
|
struct snd_soc_dapm_context *dapm;
|
||||||
bool hp = false;
|
bool hp = false;
|
||||||
bool mic = 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 in NULL, disable HS jack */
|
||||||
if (!jack) {
|
if (!jack) {
|
||||||
regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0);
|
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_disable_pin(dapm, "LDO1");
|
||||||
snd_soc_dapm_sync(dapm);
|
snd_soc_dapm_sync(dapm);
|
||||||
return 0;
|
return 0;
|
||||||
@ -360,8 +360,8 @@ EXPORT_SYMBOL_GPL(rt298_mic_detect);
|
|||||||
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
|
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
|
||||||
struct snd_soc_dapm_widget *sink)
|
struct snd_soc_dapm_widget *sink)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
|
||||||
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
|
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
if (rt298->clk_id == RT298_SCLK_S_MCLK)
|
if (rt298->clk_id == RT298_SCLK_S_MCLK)
|
||||||
return 1;
|
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,
|
static int rt298_spk_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT298_SPK_EAPD, RT298_SET_EAPD_HIGH);
|
RT298_SPK_EAPD, RT298_SET_EAPD_HIGH);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT298_SPK_EAPD, RT298_SET_EAPD_LOW);
|
RT298_SPK_EAPD, RT298_SET_EAPD_LOW);
|
||||||
break;
|
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,
|
static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
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;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
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,
|
static int rt298_adc_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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;
|
unsigned int nid;
|
||||||
|
|
||||||
nid = (w->reg >> 20) & 0xff;
|
nid = (w->reg >> 20) & 0xff;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
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),
|
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
|
||||||
0x7080, 0x7000);
|
0x7080, 0x7000);
|
||||||
/* If MCLK doesn't exist, reset AD filter */
|
/* 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");
|
pr_info("NO MCLK\n");
|
||||||
switch (nid) {
|
switch (nid) {
|
||||||
case RT298_ADC_IN1:
|
case RT298_ADC_IN1:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_D_FILTER_CTRL, 0x2, 0x2);
|
RT298_D_FILTER_CTRL, 0x2, 0x2);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_D_FILTER_CTRL, 0x2, 0x0);
|
RT298_D_FILTER_CTRL, 0x2, 0x0);
|
||||||
break;
|
break;
|
||||||
case RT298_ADC_IN2:
|
case RT298_ADC_IN2:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_D_FILTER_CTRL, 0x4, 0x4);
|
RT298_D_FILTER_CTRL, 0x4, 0x4);
|
||||||
mdelay(10);
|
mdelay(10);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_D_FILTER_CTRL, 0x4, 0x0);
|
RT298_D_FILTER_CTRL, 0x4, 0x0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
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),
|
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
|
||||||
0x7080, 0x7080);
|
0x7080, 0x7080);
|
||||||
break;
|
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,
|
static int rt298_mic1_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
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) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_A_BIAS_CTRL3, 0xc000, 0x8000);
|
RT298_A_BIAS_CTRL3, 0xc000, 0x8000);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_A_BIAS_CTRL2, 0xc000, 0x8000);
|
RT298_A_BIAS_CTRL2, 0xc000, 0x8000);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_A_BIAS_CTRL3, 0xc000, 0x0000);
|
RT298_A_BIAS_CTRL3, 0xc000, 0x0000);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_A_BIAS_CTRL2, 0xc000, 0x0000);
|
RT298_A_BIAS_CTRL2, 0xc000, 0x0000);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -745,8 +745,8 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
|
|||||||
struct snd_pcm_hw_params *params,
|
struct snd_pcm_hw_params *params,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
|
struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component);
|
||||||
unsigned int val = 0;
|
unsigned int val = 0;
|
||||||
int d_len_code;
|
int d_len_code;
|
||||||
|
|
||||||
@ -756,7 +756,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
|
|||||||
case 48000:
|
case 48000:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(codec->dev, "Unsupported sample rate %d\n",
|
dev_err(component->dev, "Unsupported sample rate %d\n",
|
||||||
params_rate(params));
|
params_rate(params));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -764,7 +764,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
|
|||||||
case 12288000:
|
case 12288000:
|
||||||
case 24576000:
|
case 24576000:
|
||||||
if (params_rate(params) != 48000) {
|
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);
|
params_rate(params), rt298->sys_clk);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -772,7 +772,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
|
|||||||
case 11289600:
|
case 11289600:
|
||||||
case 22579200:
|
case 22579200:
|
||||||
if (params_rate(params) != 44100) {
|
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);
|
params_rate(params), rt298->sys_clk);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -783,7 +783,7 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
|
|||||||
/* bit 3:0 Number of Channel */
|
/* bit 3:0 Number of Channel */
|
||||||
val |= (params_channels(params) - 1);
|
val |= (params_channels(params) - 1);
|
||||||
} else {
|
} else {
|
||||||
dev_err(codec->dev, "Unsupported channels %d\n",
|
dev_err(component->dev, "Unsupported channels %d\n",
|
||||||
params_channels(params));
|
params_channels(params));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -814,27 +814,27 @@ static int rt298_hw_params(struct snd_pcm_substream *substream,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x0018, d_len_code << 3);
|
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_component_update_bits(component, RT298_DAC_FORMAT, 0x407f, val);
|
||||||
snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x407f, val);
|
snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x407f, val);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
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) {
|
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||||
case SND_SOC_DAIFMT_CBM_CFM:
|
case SND_SOC_DAIFMT_CBM_CFM:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x800, 0x800);
|
RT298_I2S_CTRL1, 0x800, 0x800);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_CBS_CFS:
|
case SND_SOC_DAIFMT_CBS_CFS:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x800, 0x0);
|
RT298_I2S_CTRL1, 0x800, 0x0);
|
||||||
break;
|
break;
|
||||||
default:
|
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) {
|
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||||
case SND_SOC_DAIFMT_I2S:
|
case SND_SOC_DAIFMT_I2S:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x300, 0x0);
|
RT298_I2S_CTRL1, 0x300, 0x0);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_LEFT_J:
|
case SND_SOC_DAIFMT_LEFT_J:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x300, 0x1 << 8);
|
RT298_I2S_CTRL1, 0x300, 0x1 << 8);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_DSP_A:
|
case SND_SOC_DAIFMT_DSP_A:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x300, 0x2 << 8);
|
RT298_I2S_CTRL1, 0x300, 0x2 << 8);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_DSP_B:
|
case SND_SOC_DAIFMT_DSP_B:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x300, 0x3 << 8);
|
RT298_I2S_CTRL1, 0x300, 0x3 << 8);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
/* bit 15 Stream Type 0:PCM 1:Non-PCM */
|
/* bit 15 Stream Type 0:PCM 1:Non-PCM */
|
||||||
snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x8000, 0);
|
snd_soc_component_update_bits(component, RT298_DAC_FORMAT, 0x8000, 0);
|
||||||
snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x8000, 0);
|
snd_soc_component_update_bits(component, RT298_ADC_FORMAT, 0x8000, 0);
|
||||||
|
|
||||||
return 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,
|
static int rt298_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||||
int clk_id, unsigned int freq, int dir)
|
int clk_id, unsigned int freq, int dir)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = dai->codec;
|
struct snd_soc_component *component = dai->component;
|
||||||
struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec);
|
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) {
|
if (RT298_SCLK_S_MCLK == clk_id) {
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL2, 0x0100, 0x0);
|
RT298_I2S_CTRL2, 0x0100, 0x0);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_PLL_CTRL1, 0x20, 0x20);
|
RT298_PLL_CTRL1, 0x20, 0x20);
|
||||||
} else {
|
} else {
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL2, 0x0100, 0x0100);
|
RT298_I2S_CTRL2, 0x0100, 0x0100);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_PLL_CTRL1, 0x20, 0x0);
|
RT298_PLL_CTRL1, 0x20, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (freq) {
|
switch (freq) {
|
||||||
case 19200000:
|
case 19200000:
|
||||||
if (RT298_SCLK_S_MCLK == clk_id) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL2, 0x40, 0x40);
|
RT298_I2S_CTRL2, 0x40, 0x40);
|
||||||
break;
|
break;
|
||||||
case 24000000:
|
case 24000000:
|
||||||
if (RT298_SCLK_S_MCLK == clk_id) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL2, 0x40, 0x0);
|
RT298_I2S_CTRL2, 0x40, 0x0);
|
||||||
break;
|
break;
|
||||||
case 12288000:
|
case 12288000:
|
||||||
case 11289600:
|
case 11289600:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL2, 0x8, 0x0);
|
RT298_I2S_CTRL2, 0x8, 0x0);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_CLK_DIV, 0xfc1e, 0x0004);
|
RT298_CLK_DIV, 0xfc1e, 0x0004);
|
||||||
break;
|
break;
|
||||||
case 24576000:
|
case 24576000:
|
||||||
case 22579200:
|
case 22579200:
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL2, 0x8, 0x8);
|
RT298_I2S_CTRL2, 0x8, 0x8);
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_CLK_DIV, 0xfc1e, 0x5406);
|
RT298_CLK_DIV, 0xfc1e, 0x5406);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(codec->dev, "Unsupported system clock\n");
|
dev_err(component->dev, "Unsupported system clock\n");
|
||||||
return -EINVAL;
|
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)
|
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)
|
if (50 == ratio)
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x1000, 0x1000);
|
RT298_I2S_CTRL1, 0x1000, 0x1000);
|
||||||
else
|
else
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_component_update_bits(component,
|
||||||
RT298_I2S_CTRL1, 0x1000, 0x0);
|
RT298_I2S_CTRL1, 0x1000, 0x0);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
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)
|
enum snd_soc_bias_level level)
|
||||||
{
|
{
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case SND_SOC_BIAS_PREPARE:
|
case SND_SOC_BIAS_PREPARE:
|
||||||
if (SND_SOC_BIAS_STANDBY ==
|
if (SND_SOC_BIAS_STANDBY ==
|
||||||
snd_soc_codec_get_bias_level(codec)) {
|
snd_soc_component_get_bias_level(component)) {
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT298_SET_AUDIO_POWER, AC_PWRST_D0);
|
RT298_SET_AUDIO_POWER, AC_PWRST_D0);
|
||||||
snd_soc_update_bits(codec, 0x0d, 0x200, 0x200);
|
snd_soc_component_update_bits(component, 0x0d, 0x200, 0x200);
|
||||||
snd_soc_update_bits(codec, 0x52, 0x80, 0x0);
|
snd_soc_component_update_bits(component, 0x52, 0x80, 0x0);
|
||||||
mdelay(20);
|
mdelay(20);
|
||||||
snd_soc_update_bits(codec, 0x0d, 0x200, 0x0);
|
snd_soc_component_update_bits(component, 0x0d, 0x200, 0x0);
|
||||||
snd_soc_update_bits(codec, 0x52, 0x80, 0x80);
|
snd_soc_component_update_bits(component, 0x52, 0x80, 0x80);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_SOC_BIAS_STANDBY:
|
case SND_SOC_BIAS_STANDBY:
|
||||||
snd_soc_write(codec,
|
snd_soc_component_write(component,
|
||||||
RT298_SET_AUDIO_POWER, AC_PWRST_D3);
|
RT298_SET_AUDIO_POWER, AC_PWRST_D3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1003,11 +1003,11 @@ static irqreturn_t rt298_irq(int irq, void *data)
|
|||||||
return IRQ_HANDLED;
|
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) {
|
if (rt298->i2c->irq) {
|
||||||
regmap_update_bits(rt298->regmap,
|
regmap_update_bits(rt298->regmap,
|
||||||
@ -1022,19 +1022,17 @@ static int rt298_probe(struct snd_soc_codec *codec)
|
|||||||
return 0;
|
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);
|
cancel_delayed_work_sync(&rt298->jack_detect_work);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#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;
|
rt298->is_hp_in = -1;
|
||||||
regcache_cache_only(rt298->regmap, true);
|
regcache_cache_only(rt298->regmap, true);
|
||||||
@ -1043,12 +1041,12 @@ static int rt298_suspend(struct snd_soc_codec *codec)
|
|||||||
return 0;
|
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);
|
regcache_cache_only(rt298->regmap, false);
|
||||||
rt298_index_sync(codec);
|
rt298_index_sync(component);
|
||||||
regcache_sync(rt298->regmap);
|
regcache_sync(rt298->regmap);
|
||||||
|
|
||||||
return 0;
|
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 = {
|
static const struct snd_soc_component_driver soc_component_dev_rt298 = {
|
||||||
.probe = rt298_probe,
|
.probe = rt298_probe,
|
||||||
.remove = rt298_remove,
|
.remove = rt298_remove,
|
||||||
.suspend = rt298_suspend,
|
.suspend = rt298_suspend,
|
||||||
.resume = rt298_resume,
|
.resume = rt298_resume,
|
||||||
.set_bias_level = rt298_set_bias_level,
|
.set_bias_level = rt298_set_bias_level,
|
||||||
.idle_bias_off = true,
|
.controls = rt298_snd_controls,
|
||||||
.component_driver = {
|
.num_controls = ARRAY_SIZE(rt298_snd_controls),
|
||||||
.controls = rt298_snd_controls,
|
.dapm_widgets = rt298_dapm_widgets,
|
||||||
.num_controls = ARRAY_SIZE(rt298_snd_controls),
|
.num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets),
|
||||||
.dapm_widgets = rt298_dapm_widgets,
|
.dapm_routes = rt298_dapm_routes,
|
||||||
.num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets),
|
.num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes),
|
||||||
.dapm_routes = rt298_dapm_routes,
|
.use_pmdown_time = 1,
|
||||||
.num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes),
|
.endianness = 1,
|
||||||
},
|
.non_legacy_dai_naming = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct regmap_config rt298_regmap = {
|
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));
|
rt298_dai, ARRAY_SIZE(rt298_dai));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1300,7 +1299,6 @@ static int rt298_i2c_remove(struct i2c_client *i2c)
|
|||||||
|
|
||||||
if (i2c->irq)
|
if (i2c->irq)
|
||||||
free_irq(i2c->irq, rt298);
|
free_irq(i2c->irq, rt298);
|
||||||
snd_soc_unregister_codec(&i2c->dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ enum {
|
|||||||
RT298_AIFS,
|
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__ */
|
#endif /* __RT298_H__ */
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -138,6 +138,7 @@
|
|||||||
/* Index of Codec Private Register definition */
|
/* Index of Codec Private Register definition */
|
||||||
#define RT5651_BIAS_CUR1 0x12
|
#define RT5651_BIAS_CUR1 0x12
|
||||||
#define RT5651_BIAS_CUR3 0x14
|
#define RT5651_BIAS_CUR3 0x14
|
||||||
|
#define RT5651_BIAS_CUR4 0x15
|
||||||
#define RT5651_CLSD_INT_REG1 0x1c
|
#define RT5651_CLSD_INT_REG1 0x1c
|
||||||
#define RT5651_CHPUMP_INT_REG1 0x24
|
#define RT5651_CHPUMP_INT_REG1 0x24
|
||||||
#define RT5651_MAMP_INT_REG2 0x37
|
#define RT5651_MAMP_INT_REG2 0x37
|
||||||
@ -1966,6 +1967,15 @@
|
|||||||
#define RT5651_D_GATE_EN_SFT 0
|
#define RT5651_D_GATE_EN_SFT 0
|
||||||
|
|
||||||
/* Codec Private Register definition */
|
/* 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) */
|
/* 3D Speaker Control (0x63) */
|
||||||
#define RT5651_3D_SPK_MASK (0x1 << 15)
|
#define RT5651_3D_SPK_MASK (0x1 << 15)
|
||||||
#define RT5651_3D_SPK_SFT 15
|
#define RT5651_3D_SPK_SFT 15
|
||||||
@ -2059,12 +2069,15 @@ struct rt5651_pll_code {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rt5651_priv {
|
struct rt5651_priv {
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_component *component;
|
||||||
struct rt5651_platform_data pdata;
|
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct snd_soc_jack *hp_jack;
|
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;
|
||||||
int sysclk_src;
|
int sysclk_src;
|
||||||
int lrck[RT5651_AIFS];
|
int lrck[RT5651_AIFS];
|
||||||
@ -2079,6 +2092,4 @@ struct rt5651_priv {
|
|||||||
bool hp_mute;
|
bool hp_mute;
|
||||||
};
|
};
|
||||||
|
|
||||||
int rt5651_set_jack_detect(struct snd_soc_codec *codec,
|
|
||||||
struct snd_soc_jack *hp_jack);
|
|
||||||
#endif /* __RT5651_H__ */
|
#endif /* __RT5651_H__ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1125,9 +1125,9 @@ enum {
|
|||||||
RT5663_AD_STEREO_FILTER = 0x2,
|
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);
|
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);
|
unsigned int filter_mask, unsigned int clk_src);
|
||||||
|
|
||||||
#endif /* __RT5663_H__ */
|
#endif /* __RT5663_H__ */
|
||||||
|
@ -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);
|
dev_err(dev, "stream %d is running, can't suspend, abort\n", i);
|
||||||
return -EBUSY;
|
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);
|
synchronize_irq(ctx->irq_num);
|
||||||
flush_workqueue(ctx->post_msg_wq);
|
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 intel_sst_drv *ctx = dev_get_drvdata(dev);
|
||||||
struct sst_fw_save *fw_save = ctx->fw_save;
|
struct sst_fw_save *fw_save = ctx->fw_save;
|
||||||
int ret = 0;
|
|
||||||
struct sst_block *block;
|
struct sst_block *block;
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
if (!fw_save)
|
if (!fw_save)
|
||||||
return 0;
|
return 0;
|
||||||
@ -550,6 +557,21 @@ static int intel_sst_resume(struct device *dev)
|
|||||||
sst_set_fw_state_locked(ctx, SST_FW_RUNNING);
|
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);
|
sst_free_block(ctx, block);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,7 @@ enum sst_stream_states {
|
|||||||
STREAM_UN_INIT = 0, /* Freed/Not used stream */
|
STREAM_UN_INIT = 0, /* Freed/Not used stream */
|
||||||
STREAM_RUNNING = 1, /* Running */
|
STREAM_RUNNING = 1, /* Running */
|
||||||
STREAM_PAUSED = 2, /* Paused stream */
|
STREAM_PAUSED = 2, /* Paused stream */
|
||||||
STREAM_DECODE = 3, /* stream is in decoding only state */
|
STREAM_INIT = 3, /* stream init, waiting for data */
|
||||||
STREAM_INIT = 4, /* stream init, waiting for data */
|
|
||||||
STREAM_RESET = 5, /* force reset on recovery */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sst_ram_type {
|
enum sst_ram_type {
|
||||||
@ -181,22 +179,22 @@ struct sst_block {
|
|||||||
*
|
*
|
||||||
* @status : stream current state
|
* @status : stream current state
|
||||||
* @prev : stream prev state
|
* @prev : stream prev state
|
||||||
* @ops : stream operation pb/cp/drm...
|
* @resume_status : stream current state to restore on resume
|
||||||
* @bufs: stream buffer list
|
* @resume_prev : stream prev state to restore on resume
|
||||||
* @lock : stream mutex for protecting state
|
* @lock : stream mutex for protecting state
|
||||||
|
* @alloc_param : parameters used for stream (re-)allocation
|
||||||
* @pcm_substream : PCM substream
|
* @pcm_substream : PCM substream
|
||||||
* @period_elapsed : PCM period elapsed callback
|
* @period_elapsed : PCM period elapsed callback
|
||||||
* @sfreq : stream sampling freq
|
* @sfreq : stream sampling freq
|
||||||
* @str_type : stream type
|
|
||||||
* @cumm_bytes : cummulative bytes decoded
|
* @cumm_bytes : cummulative bytes decoded
|
||||||
* @str_type : stream type
|
|
||||||
* @src : stream source
|
|
||||||
*/
|
*/
|
||||||
struct stream_info {
|
struct stream_info {
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
unsigned int prev;
|
unsigned int prev;
|
||||||
unsigned int ops;
|
unsigned int resume_status;
|
||||||
|
unsigned int resume_prev;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
|
struct snd_sst_alloc_mrfld alloc_param;
|
||||||
|
|
||||||
void *pcm_substream;
|
void *pcm_substream;
|
||||||
void (*period_elapsed)(void *pcm_substream);
|
void (*period_elapsed)(void *pcm_substream);
|
||||||
@ -212,7 +210,6 @@ struct stream_info {
|
|||||||
|
|
||||||
unsigned int num_ch;
|
unsigned int num_ch;
|
||||||
unsigned int pipe_id;
|
unsigned int pipe_id;
|
||||||
unsigned int str_id;
|
|
||||||
unsigned int task_id;
|
unsigned int task_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -438,6 +435,7 @@ struct intel_sst_ops {
|
|||||||
void (*post_download)(struct intel_sst_drv *sst);
|
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_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_resume_stream(struct intel_sst_drv *sst_drv_ctx, int id);
|
||||||
int sst_drop_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);
|
void sst_process_pending_msg(struct work_struct *work);
|
||||||
int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx);
|
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);
|
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,
|
struct stream_info *get_stream_info(struct intel_sst_drv *sst_drv_ctx,
|
||||||
int str_id);
|
int str_id);
|
||||||
|
@ -143,10 +143,11 @@ static struct sst_platform_info byt_rvp_platform_data = {
|
|||||||
.lib_info = &byt_lib_dnld_info,
|
.lib_info = &byt_lib_dnld_info,
|
||||||
.res_info = &byt_rvp_res_info,
|
.res_info = &byt_rvp_res_info,
|
||||||
.platform = "sst-mfld-platform",
|
.platform = "sst-mfld-platform",
|
||||||
|
.streams_lost_on_suspend = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Cherryview (Cherrytrail and Braswell) uses same mrfld dpcm fw as Baytrail,
|
/* 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 = {
|
static struct sst_platform_info chv_platform_data = {
|
||||||
.probe_data = &byt_fwparse_info,
|
.probe_data = &byt_fwparse_info,
|
||||||
|
@ -238,16 +238,7 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id)
|
|||||||
return -EINVAL;
|
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);
|
retval = sst_free_stream(ctx, str_id);
|
||||||
put:
|
|
||||||
stream->compr_cb_param = NULL;
|
stream->compr_cb_param = NULL;
|
||||||
stream->compr_cb = NULL;
|
stream->compr_cb = NULL;
|
||||||
|
|
||||||
@ -256,7 +247,6 @@ put:
|
|||||||
|
|
||||||
dev_dbg(dev, "End\n");
|
dev_dbg(dev, "End\n");
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sst_cdev_ack(struct device *dev, unsigned int str_id,
|
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;
|
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);
|
retval = free_stream_context(ctx, str_id);
|
||||||
put:
|
|
||||||
stream->pcm_substream = NULL;
|
stream->pcm_substream = NULL;
|
||||||
stream->status = STREAM_UN_INIT;
|
stream->status = STREAM_UN_INIT;
|
||||||
stream->period_elapsed = NULL;
|
stream->period_elapsed = NULL;
|
||||||
|
@ -360,14 +360,6 @@ int sst_assign_pvt_id(struct intel_sst_drv *drv)
|
|||||||
return local;
|
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(
|
int sst_validate_strid(
|
||||||
struct intel_sst_drv *sst_drv_ctx, int str_id)
|
struct intel_sst_drv *sst_drv_ctx, int str_id)
|
||||||
{
|
{
|
||||||
|
@ -35,29 +35,31 @@
|
|||||||
|
|
||||||
int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
|
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_params *str_params;
|
||||||
struct snd_sst_tstamp fw_tstamp;
|
struct snd_sst_tstamp fw_tstamp;
|
||||||
struct stream_info *str_info;
|
struct stream_info *str_info;
|
||||||
struct snd_sst_alloc_response *response;
|
int i, num_ch, str_id;
|
||||||
unsigned int str_id, pipe_id, task_id;
|
|
||||||
int i, num_ch, ret = 0;
|
|
||||||
void *data = NULL;
|
|
||||||
|
|
||||||
dev_dbg(sst_drv_ctx->dev, "Enter\n");
|
dev_dbg(sst_drv_ctx->dev, "Enter\n");
|
||||||
|
|
||||||
str_params = (struct snd_sst_params *)params;
|
str_params = (struct snd_sst_params *)params;
|
||||||
memset(&alloc_param, 0, sizeof(alloc_param));
|
str_id = str_params->stream_id;
|
||||||
alloc_param.operation = str_params->ops;
|
str_info = get_stream_info(sst_drv_ctx, str_id);
|
||||||
alloc_param.codec_type = str_params->codec;
|
if (!str_info)
|
||||||
alloc_param.sg_count = str_params->aparams.sg_count;
|
return -EINVAL;
|
||||||
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;
|
|
||||||
|
|
||||||
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));
|
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.
|
* Currently hardcoding as per FW reqm.
|
||||||
*/
|
*/
|
||||||
num_ch = sst_get_num_channel(str_params);
|
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++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (i < num_ch)
|
if (i < num_ch)
|
||||||
alloc_param.codec_params.uc.pcm_params.channel_map[i] = i;
|
pcm_params->channel_map[i] = i;
|
||||||
else
|
else
|
||||||
alloc_param.codec_params.uc.pcm_params.channel_map[i] = 0xFF;
|
pcm_params->channel_map[i] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
str_id = str_params->stream_id;
|
sst_drv_ctx->streams[str_id].status = STREAM_INIT;
|
||||||
str_info = get_stream_info(sst_drv_ctx, str_id);
|
sst_drv_ctx->streams[str_id].prev = STREAM_UN_INIT;
|
||||||
if (str_info == NULL) {
|
sst_drv_ctx->streams[str_id].pipe_id = str_params->device_type;
|
||||||
dev_err(sst_drv_ctx->dev, "get stream info returned null\n");
|
sst_drv_ctx->streams[str_id].task_id = str_params->task;
|
||||||
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].num_ch = num_ch;
|
sst_drv_ctx->streams[str_id].num_ch = num_ch;
|
||||||
|
|
||||||
if (sst_drv_ctx->info.lpe_viewpt_rqd)
|
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));
|
sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
|
||||||
else
|
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));
|
sst_drv_ctx->tstamp + (str_id * sizeof(fw_tstamp));
|
||||||
|
|
||||||
dev_dbg(sst_drv_ctx->dev, "alloc tstamp location = 0x%x\n",
|
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",
|
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 */
|
return sst_realloc_stream(sst_drv_ctx, str_id);
|
||||||
sst_init_stream(&sst_drv_ctx->streams[str_id], alloc_param.codec_type,
|
}
|
||||||
str_id, alloc_param.operation, 0);
|
|
||||||
|
/**
|
||||||
|
* 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",
|
dev_dbg(sst_drv_ctx->dev, "Alloc for str %d pipe %#x\n",
|
||||||
str_id, pipe_id);
|
str_id, str_info->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),
|
ret = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, IPC_CMD,
|
||||||
&alloc_param, &data, true, true, false, true);
|
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) {
|
if (ret < 0) {
|
||||||
dev_err(sst_drv_ctx->dev, "FW alloc failed ret %d\n", ret);
|
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) {
|
if (retval == 0) {
|
||||||
str_info->prev = str_info->status;
|
str_info->prev = str_info->status;
|
||||||
str_info->status = STREAM_PAUSED;
|
str_info->status = STREAM_PAUSED;
|
||||||
} else if (retval == SST_ERR_INVALID_STREAM_ID) {
|
} else if (retval == -SST_ERR_INVALID_STREAM_ID) {
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
mutex_lock(&sst_drv_ctx->sst_lock);
|
mutex_lock(&sst_drv_ctx->sst_lock);
|
||||||
sst_clean_stream(str_info);
|
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;
|
return -EINVAL;
|
||||||
if (str_info->status == STREAM_RUNNING)
|
if (str_info->status == STREAM_RUNNING)
|
||||||
return 0;
|
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,
|
retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id,
|
||||||
IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD,
|
IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD,
|
||||||
str_info->pipe_id, 0, NULL, NULL,
|
str_info->pipe_id, 0, NULL, NULL,
|
||||||
|
@ -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.
|
Say Y or m if you have such a device. This is a recommended option.
|
||||||
If unsure select "N".
|
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
|
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
|
||||||
tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
|
tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
|
||||||
depends on X86_INTEL_LPSS && I2C && ACPI
|
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.
|
create an alsa sound card for RT5663 + RT5514 + MAX98927.
|
||||||
Say Y or m if you have such a device. This is a recommended option.
|
Say Y or m if you have such a device. This is a recommended option.
|
||||||
If unsure select "N".
|
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_SKYLAKE
|
||||||
|
|
||||||
endif ## SND_SOC_INTEL_MACH
|
endif ## SND_SOC_INTEL_MACH
|
||||||
|
@ -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-rt5672-objs := cht_bsw_rt5672.o
|
||||||
snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.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-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-da7213-objs := bytcht_da7213.o
|
||||||
snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
|
snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
|
||||||
snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.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_max98927-objs := kbl_rt5663_max98927.o
|
||||||
snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
|
snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
|
||||||
snd-soc-skl_rt286-objs := skl_rt286.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_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_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_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_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_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_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_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_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
|
obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
|
||||||
|
@ -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)
|
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;
|
int ret = 0;
|
||||||
ret = snd_soc_card_jack_new(rtd->card, "Headset",
|
ret = snd_soc_card_jack_new(rtd->card, "Headset",
|
||||||
SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_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)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
rt286_mic_detect(codec, &broadwell_headset);
|
rt286_mic_detect(component, &broadwell_headset);
|
||||||
return 0;
|
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) {
|
list_for_each_entry(component, &card->component_dev_list, card_list) {
|
||||||
if (!strcmp(component->name, "i2c-INT343A:00")) {
|
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");
|
dev_dbg(component->dev, "disabling jack detect before going to suspend.\n");
|
||||||
rt286_mic_detect(codec, NULL);
|
rt286_mic_detect(component, NULL);
|
||||||
break;
|
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) {
|
list_for_each_entry(component, &card->component_dev_list, card_list) {
|
||||||
if (!strcmp(component->name, "i2c-INT343A:00")) {
|
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");
|
dev_dbg(component->dev, "enabling jack detect for resume.\n");
|
||||||
rt286_mic_detect(codec, &broadwell_headset);
|
rt286_mic_detect(component, &broadwell_headset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
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 */
|
/* Configure sysclk for codec */
|
||||||
ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000,
|
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;
|
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");
|
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_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct bxt_hdmi_pcm *pcm;
|
struct bxt_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
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 */
|
/* broxton audio machine driver for SPT + da7219 */
|
||||||
|
@ -146,6 +146,9 @@ static const struct snd_soc_dapm_route geminilake_rt298_map[] = {
|
|||||||
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
|
{ "dmic01_hifi", NULL, "DMIC01 Rx" },
|
||||||
{ "DMIC01 Rx", NULL, "Capture" },
|
{ "DMIC01 Rx", NULL, "Capture" },
|
||||||
|
|
||||||
|
{ "dmic_voice", NULL, "DMIC16k Rx" },
|
||||||
|
{ "DMIC16k Rx", NULL, "Capture" },
|
||||||
|
|
||||||
{ "hifi3", NULL, "iDisp3 Tx"},
|
{ "hifi3", NULL, "iDisp3 Tx"},
|
||||||
{ "iDisp3 Tx", NULL, "iDisp3_out"},
|
{ "iDisp3 Tx", NULL, "iDisp3_out"},
|
||||||
{ "hifi2", NULL, "iDisp2 Tx"},
|
{ "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)
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
ret = snd_soc_card_jack_new(rtd->card, "Headset",
|
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)
|
if (ret)
|
||||||
return 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");
|
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,
|
.dpcm_capture = 1,
|
||||||
.no_pcm = 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",
|
.name = "iDisp1",
|
||||||
.id = 3,
|
.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_rt286_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct bxt_hdmi_pcm *pcm;
|
struct bxt_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return hdac_hdmi_jack_port_init(codec, &card->dapm);
|
return hdac_hdmi_jack_port_init(component, &card->dapm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,13 +18,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/property.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <asm/cpu_device_id.h>
|
||||||
#include <asm/platform_sst_audio.h>
|
#include <asm/platform_sst_audio.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
@ -39,22 +42,55 @@ enum {
|
|||||||
BYT_RT5651_IN1_MAP,
|
BYT_RT5651_IN1_MAP,
|
||||||
BYT_RT5651_IN2_MAP,
|
BYT_RT5651_IN2_MAP,
|
||||||
BYT_RT5651_IN1_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))
|
enum {
|
||||||
#define BYT_RT5651_DMIC_EN BIT(16)
|
BYT_RT5651_JD_NULL = (RT5651_JD_NULL << 4),
|
||||||
#define BYT_RT5651_MCLK_EN BIT(17)
|
BYT_RT5651_JD1_1 = (RT5651_JD1_1 << 4),
|
||||||
#define BYT_RT5651_MCLK_25MHZ BIT(18)
|
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 byt_rt5651_private {
|
||||||
struct clk *mclk;
|
struct clk *mclk;
|
||||||
struct snd_soc_jack jack;
|
struct snd_soc_jack jack;
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP |
|
/* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
|
||||||
BYT_RT5651_DMIC_EN |
|
static unsigned long byt_rt5651_quirk = BYT_RT5651_MCLK_EN |
|
||||||
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)
|
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");
|
dev_info(dev, "quirk IN1_MAP enabled");
|
||||||
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
|
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
|
||||||
dev_info(dev, "quirk IN2_MAP enabled");
|
dev_info(dev, "quirk IN2_MAP enabled");
|
||||||
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN3_MAP)
|
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_HS_IN3_MAP)
|
||||||
dev_info(dev, "quirk IN3_MAP enabled");
|
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)
|
if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
|
||||||
dev_info(dev, "quirk DMIC enabled");
|
dev_info(dev, "quirk DMIC enabled");
|
||||||
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
|
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
|
||||||
dev_info(dev, "quirk MCLK_EN enabled");
|
dev_info(dev, "quirk MCLK_EN enabled");
|
||||||
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
|
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
|
||||||
dev_info(dev, "quirk MCLK_25MHZ enabled");
|
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_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,
|
static int platform_clock_control(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *k, int event)
|
struct snd_kcontrol *k, int event)
|
||||||
@ -86,6 +171,8 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
|
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) {
|
if (!codec_dai) {
|
||||||
dev_err(card->dev,
|
dev_err(card->dev,
|
||||||
"Codec dai not found; Unable to set platform clock\n");
|
"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;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
|
ret = byt_rt5651_prepare_and_enable_pll1(codec_dai, 48000, 50);
|
||||||
48000 * 512,
|
|
||||||
SND_SOC_CLOCK_IN);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Set codec clock source to internal clock before
|
* 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"},
|
{"Speaker", NULL, "Platform Clock"},
|
||||||
{"Line In", 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 */
|
{"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
|
||||||
{"Headphone", NULL, "HPOL"},
|
{"Headphone", NULL, "HPOL"},
|
||||||
{"Headphone", NULL, "HPOR"},
|
{"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[] = {
|
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
|
||||||
{"Internal Mic", NULL, "micbias1"},
|
{"Internal Mic", NULL, "micbias1"},
|
||||||
{"IN2P", NULL, "Headset Mic"},
|
|
||||||
{"IN1P", NULL, "Internal Mic"},
|
{"IN1P", NULL, "Internal Mic"},
|
||||||
|
{"IN2P", NULL, "Headset Mic"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
|
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"},
|
{"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"},
|
{"Internal Mic", NULL, "micbias1"},
|
||||||
{"IN3P", NULL, "Headset Mic"},
|
|
||||||
{"IN1P", NULL, "Internal 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[] = {
|
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_pcm_runtime *rtd = substream->private_data;
|
||||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
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,
|
return byt_rt5651_prepare_and_enable_pll1(codec_dai, rate, bclk_ratio);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
|
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_SYS_VENDOR, "Circuitco"),
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
|
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,
|
.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"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"),
|
||||||
},
|
},
|
||||||
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
|
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
|
||||||
BYT_RT5651_IN3_MAP),
|
BYT_RT5651_IN1_HS_IN3_MAP),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.callback = byt_rt5651_quirk_cb,
|
.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"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
|
||||||
},
|
},
|
||||||
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
|
.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),
|
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)
|
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = runtime->card;
|
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);
|
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
|
||||||
const struct snd_soc_dapm_route *custom_map;
|
const struct snd_soc_dapm_route *custom_map;
|
||||||
int num_routes;
|
int num_routes;
|
||||||
@ -304,6 +457,11 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
|
|||||||
|
|
||||||
card->dapm.idle_bias_off = true;
|
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)) {
|
switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
|
||||||
case BYT_RT5651_IN1_MAP:
|
case BYT_RT5651_IN1_MAP:
|
||||||
custom_map = byt_rt5651_intmic_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;
|
custom_map = byt_rt5651_intmic_in1_in2_map;
|
||||||
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
|
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
|
||||||
break;
|
break;
|
||||||
case BYT_RT5651_IN3_MAP:
|
case BYT_RT5651_IN1_HS_IN3_MAP:
|
||||||
custom_map = byt_rt5651_intmic_in3_map;
|
custom_map = byt_rt5651_intmic_in1_hs_in3_map;
|
||||||
num_routes = ARRAY_SIZE(byt_rt5651_intmic_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;
|
break;
|
||||||
default:
|
default:
|
||||||
custom_map = byt_rt5651_intmic_dmic_map;
|
custom_map = byt_rt5651_intmic_dmic_map;
|
||||||
@ -329,6 +491,26 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return 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,
|
ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
|
||||||
ARRAY_SIZE(byt_rt5651_controls));
|
ARRAY_SIZE(byt_rt5651_controls));
|
||||||
if (ret) {
|
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");
|
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,
|
SND_JACK_HEADSET, &priv->jack,
|
||||||
bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
|
bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
|
dev_err(runtime->dev, "jack creation failed %d\n", ret);
|
||||||
return 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 0;
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct snd_soc_pcm_stream byt_rt5651_dai_params = {
|
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);
|
SNDRV_PCM_HW_PARAM_RATE);
|
||||||
struct snd_interval *channels = hw_param_interval(params,
|
struct snd_interval *channels = hw_param_interval(params,
|
||||||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
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;
|
rate->min = rate->max = 48000;
|
||||||
channels->min = channels->max = 2;
|
channels->min = channels->max = 2;
|
||||||
|
|
||||||
/* set SSP2 to 24-bit */
|
if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
|
||||||
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
|
(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
|
* 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
|
* dai_set_tdm_slot() since there is no other API exposed
|
||||||
*/
|
*/
|
||||||
ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
|
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;
|
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) {
|
if (ret < 0) {
|
||||||
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
|
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
|
||||||
return 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_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)
|
static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct byt_rt5651_private *priv;
|
struct byt_rt5651_private *priv;
|
||||||
struct snd_soc_acpi_mach *mach;
|
struct snd_soc_acpi_mach *mach;
|
||||||
const char *i2c_name = NULL;
|
const char *i2c_name = NULL;
|
||||||
|
bool is_bytcr = false;
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
int dai_index = 0;
|
int dai_index = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -540,17 +754,105 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
/* fixup codec name based on HID */
|
/* fixup codec name based on HID */
|
||||||
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
||||||
if (i2c_name) {
|
if (!i2c_name) {
|
||||||
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
|
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
|
||||||
"%s%s", "i2c-", i2c_name);
|
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 */
|
/* check quirks before creating card */
|
||||||
dmi_check_system(byt_rt5651_quirk_table);
|
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);
|
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) {
|
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
|
||||||
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
|
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
|
||||||
if (IS_ERR(priv->mclk)) {
|
if (IS_ERR(priv->mclk)) {
|
||||||
|
282
sound/soc/intel/boards/cht_bsw_nau8824.c
Normal file
282
sound/soc/intel/boards/cht_bsw_nau8824.c
Normal 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");
|
613
sound/soc/intel/boards/kbl_da7219_max98357a.c
Normal file
613
sound/soc/intel/boards/kbl_da7219_max98357a.c
Normal 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");
|
@ -204,13 +204,18 @@ static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = {
|
|||||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||||
SND_SOC_DAPM_SPK("DP", NULL),
|
SND_SOC_DAPM_SPK("DP", NULL),
|
||||||
SND_SOC_DAPM_SPK("HDMI", 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[] = {
|
static const struct snd_soc_dapm_route kabylake_5663_map[] = {
|
||||||
|
{ "Headphone Jack", NULL, "Platform Clock" },
|
||||||
{ "Headphone Jack", NULL, "HPOL" },
|
{ "Headphone Jack", NULL, "HPOL" },
|
||||||
{ "Headphone Jack", NULL, "HPOR" },
|
{ "Headphone Jack", NULL, "HPOR" },
|
||||||
|
|
||||||
/* other jacks */
|
/* other jacks */
|
||||||
|
{ "Headset Mic", NULL, "Platform Clock" },
|
||||||
{ "IN1P", NULL, "Headset Mic" },
|
{ "IN1P", NULL, "Headset Mic" },
|
||||||
{ "IN1N", 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;
|
int ret;
|
||||||
struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
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;
|
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_2, KEY_VOLUMEUP);
|
||||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,7 +453,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
|
/* 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_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
|
||||||
RT5663_CLK_SEL_I2S1_ASRC);
|
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_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct kbl_hdmi_pcm *pcm;
|
struct kbl_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
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 */
|
/* kabylake audio machine driver for SPT + RT5663 */
|
||||||
|
@ -178,7 +178,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
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;
|
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_2, KEY_VOLUMEUP);
|
||||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
|
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");
|
ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC");
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -333,7 +333,7 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */
|
/* 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_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
|
||||||
RT5663_CLK_SEL_I2S1_ASRC);
|
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_codec_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct kbl_hdmi_pcm *pcm;
|
struct kbl_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP,pcm=%d Jack", pcm->device);
|
"HDMI/DP,pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return hdac_hdmi_jack_port_init(codec, &card->dapm);
|
return hdac_hdmi_jack_port_init(component, &card->dapm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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)
|
static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
int ret;
|
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.
|
* 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;
|
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");
|
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_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct skl_hdmi_pcm *pcm;
|
struct skl_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
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 */
|
/* skylake audio machine driver for SPT + NAU88L25 */
|
||||||
|
@ -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)
|
static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
int ret;
|
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
|
* 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;
|
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");
|
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_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct skl_hdmi_pcm *pcm;
|
struct skl_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
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 */
|
/* skylake audio machine driver for SPT + NAU88L25 */
|
||||||
|
@ -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)
|
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;
|
int ret;
|
||||||
|
|
||||||
ret = snd_soc_card_jack_new(rtd->card, "Headset",
|
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)
|
if (ret)
|
||||||
return 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");
|
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_rt286_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct skl_hdmi_pcm *pcm;
|
struct skl_hdmi_pcm *pcm;
|
||||||
struct snd_soc_codec *codec = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
int err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
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),
|
snprintf(jack_name, sizeof(jack_name),
|
||||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||||
err = snd_soc_card_jack_new(card, jack_name,
|
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++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!codec)
|
if (!component)
|
||||||
return -EINVAL;
|
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 */
|
/* skylake audio machine driver for SPT + RT286S */
|
||||||
|
@ -117,6 +117,15 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = {
|
|||||||
.sof_tplg_filename = "intel/reef-cht-max98090.tplg",
|
.sof_tplg_filename = "intel/reef-cht-max98090.tplg",
|
||||||
.asoc_plat_name = "sst-mfld-platform",
|
.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",
|
.id = "DLGS7212",
|
||||||
.drv_name = "bytcht_da7213",
|
.drv_name = "bytcht_da7213",
|
||||||
|
@ -417,11 +417,16 @@ int skl_resume_dsp(struct skl *skl)
|
|||||||
if (skl->skl_sst->is_first_boot == true)
|
if (skl->skl_sst->is_first_boot == true)
|
||||||
return 0;
|
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->enable_miscbdcge(ctx->dev, false);
|
||||||
|
ctx->clock_power_gating(ctx->dev, false);
|
||||||
|
|
||||||
ret = skl_dsp_wake(ctx->dsp);
|
ret = skl_dsp_wake(ctx->dsp);
|
||||||
ctx->enable_miscbdcge(ctx->dev, true);
|
ctx->enable_miscbdcge(ctx->dev, true);
|
||||||
|
ctx->clock_power_gating(ctx->dev, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -1210,7 +1215,7 @@ out:
|
|||||||
static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
|
static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe,
|
||||||
enum skl_ipc_pipeline_state state)
|
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);
|
return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state);
|
||||||
}
|
}
|
||||||
|
@ -958,6 +958,17 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
|
|||||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
|
.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",
|
.name = "HD-Codec Pin",
|
||||||
.ops = &skl_link_dai_ops,
|
.ops = &skl_link_dai_ops,
|
||||||
@ -1307,6 +1318,8 @@ static int skl_populate_modules(struct skl *skl)
|
|||||||
"query module info failed\n");
|
"query module info failed\n");
|
||||||
return ret;
|
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;
|
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->enable_miscbdcge(component->dev, false);
|
||||||
|
skl->skl_sst->clock_power_gating(component->dev, false);
|
||||||
|
|
||||||
ret = ops->init_fw(component->dev, skl->skl_sst);
|
ret = ops->init_fw(component->dev, skl->skl_sst);
|
||||||
skl->skl_sst->enable_miscbdcge(component->dev, true);
|
skl->skl_sst->enable_miscbdcge(component->dev, true);
|
||||||
|
skl->skl_sst->clock_power_gating(component->dev, true);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
|
dev_err(component->dev, "Failed to boot first fw: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -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 */
|
/* Not supported by clk driver. Implemented to satisfy clk fw */
|
||||||
long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
static long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long *parent_rate)
|
unsigned long *parent_rate)
|
||||||
{
|
{
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,9 @@ struct skl_sst {
|
|||||||
struct skl_d0i3_data d0i3;
|
struct skl_d0i3_data d0i3;
|
||||||
|
|
||||||
const struct skl_dsp_ops *dsp_ops;
|
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 {
|
struct skl_ipc_init_instance_msg {
|
||||||
|
@ -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
|
* 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
|
* 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) {
|
switch (w->id) {
|
||||||
case snd_soc_dapm_dai_link:
|
case snd_soc_dapm_dai_link:
|
||||||
case snd_soc_dapm_dai_in:
|
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) {
|
if (mcfg->m_type == SKL_MODULE_TYPE_KPB) {
|
||||||
struct skl_kpb_params *kpb_params =
|
struct skl_kpb_params *kpb_params =
|
||||||
(struct skl_kpb_params *)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++) {
|
for (i = 0; i < kpb_params->num_modules; i++) {
|
||||||
pvt_id = skl_get_pvt_instance_id_map(ctx, inst->mod_id,
|
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;
|
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,
|
static int skl_tplg_module_add_deferred_bind(struct skl *skl,
|
||||||
struct skl_module_cfg *src, struct skl_module_cfg *dst)
|
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;
|
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);
|
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
|
* they are ones used for SKL so check that first
|
||||||
*/
|
*/
|
||||||
if ((p->sink->priv != NULL) &&
|
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 = p->sink;
|
||||||
sink_mconfig = sink->priv;
|
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
|
* ones used for SKL so check that first
|
||||||
*/
|
*/
|
||||||
if ((p->source->priv != NULL) &&
|
if ((p->source->priv != NULL) &&
|
||||||
is_skl_dsp_widget_type(p->source)) {
|
is_skl_dsp_widget_type(p->source, ctx->dev)) {
|
||||||
return p->source;
|
return p->source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1654,7 +1739,7 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
|
|||||||
w = dai->playback_widget;
|
w = dai->playback_widget;
|
||||||
snd_soc_dapm_widget_for_each_sink_path(w, p) {
|
snd_soc_dapm_widget_for_each_sink_path(w, p) {
|
||||||
if (p->connect && p->sink->power &&
|
if (p->connect && p->sink->power &&
|
||||||
!is_skl_dsp_widget_type(p->sink))
|
!is_skl_dsp_widget_type(p->sink, dai->dev))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (p->sink->priv) {
|
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;
|
w = dai->capture_widget;
|
||||||
snd_soc_dapm_widget_for_each_source_path(w, p) {
|
snd_soc_dapm_widget_for_each_source_path(w, p) {
|
||||||
if (p->connect && p->source->power &&
|
if (p->connect && p->source->power &&
|
||||||
!is_skl_dsp_widget_type(p->source))
|
!is_skl_dsp_widget_type(p->source, dai->dev))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (p->source->priv) {
|
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;
|
int ret = -EIO;
|
||||||
|
|
||||||
snd_soc_dapm_widget_for_each_source_path(w, p) {
|
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) {
|
p->source->priv) {
|
||||||
|
|
||||||
ret = skl_tplg_be_fill_pipe_params(dai,
|
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;
|
int ret = -EIO;
|
||||||
|
|
||||||
snd_soc_dapm_widget_for_each_sink_path(w, p) {
|
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) {
|
p->sink->priv) {
|
||||||
|
|
||||||
ret = skl_tplg_be_fill_pipe_params(dai,
|
ret = skl_tplg_be_fill_pipe_params(dai,
|
||||||
@ -2752,7 +2837,7 @@ void skl_cleanup_resources(struct skl *skl)
|
|||||||
skl->resource.mcps = 0;
|
skl->resource.mcps = 0;
|
||||||
|
|
||||||
list_for_each_entry(w, &card->widgets, list) {
|
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);
|
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;
|
struct skl_pipe *pipe;
|
||||||
|
|
||||||
list_for_each_entry(w, &component->card->widgets, list) {
|
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;
|
mcfg = w->priv;
|
||||||
pipe = mcfg->pipe;
|
pipe = mcfg->pipe;
|
||||||
|
|
||||||
|
@ -221,9 +221,18 @@ struct skl_mod_inst_map {
|
|||||||
u16 inst_id;
|
u16 inst_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct skl_uuid_inst_map {
|
||||||
|
u16 inst_id;
|
||||||
|
u16 reserved;
|
||||||
|
uuid_le mod_uuid;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct skl_kpb_params {
|
struct skl_kpb_params {
|
||||||
u32 num_modules;
|
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 {
|
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,
|
int skl_dai_load(struct snd_soc_component *cmp,
|
||||||
struct snd_soc_dai_driver *pcm_dai);
|
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
|
#endif
|
||||||
|
@ -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);
|
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
|
* While performing reset, controller may not come back properly causing
|
||||||
* issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
|
* 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;
|
goto out_nhlt_free;
|
||||||
}
|
}
|
||||||
skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
|
skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
|
||||||
|
skl->skl_sst->clock_power_gating = skl_clock_power_gating;
|
||||||
}
|
}
|
||||||
if (bus->mlcap)
|
if (bus->mlcap)
|
||||||
snd_hdac_ext_bus_get_ml_capabilities(ebus);
|
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"}
|
.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 = {
|
static struct skl_machine_pdata cnl_pdata = {
|
||||||
.use_tplg_pcm = true,
|
.use_tplg_pcm = true,
|
||||||
};
|
};
|
||||||
@ -1105,6 +1137,14 @@ static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
|
|||||||
.drv_name = "kbl_rt5663",
|
.drv_name = "kbl_rt5663",
|
||||||
.fw_filename = "intel/dsp_fw_kbl.bin",
|
.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
|
||||||
|
},
|
||||||
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -33,8 +33,10 @@
|
|||||||
|
|
||||||
#define AZX_PCIREG_PGCTL 0x44
|
#define AZX_PCIREG_PGCTL 0x44
|
||||||
#define AZX_PGCTL_LSRMD_MASK (1 << 4)
|
#define AZX_PGCTL_LSRMD_MASK (1 << 4)
|
||||||
|
#define AZX_PGCTL_ADSPPGD BIT(2)
|
||||||
#define AZX_PCIREG_CGCTL 0x48
|
#define AZX_PCIREG_CGCTL 0x48
|
||||||
#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
|
#define AZX_CGCTL_MISCBDCGE_MASK (1 << 6)
|
||||||
|
#define AZX_CGCTL_ADSPDCGE BIT(1)
|
||||||
/* D0I3C Register fields */
|
/* D0I3C Register fields */
|
||||||
#define AZX_REG_VS_D0I3C_CIP 0x1 /* Command in progress */
|
#define AZX_REG_VS_D0I3C_CIP 0x1 /* Command in progress */
|
||||||
#define AZX_REG_VS_D0I3C_I3 0x4 /* D0i3 enable */
|
#define AZX_REG_VS_D0I3C_I3 0x4 /* D0i3 enable */
|
||||||
@ -43,6 +45,8 @@
|
|||||||
#define DMA_TRANSMITION_START 2
|
#define DMA_TRANSMITION_START 2
|
||||||
#define DMA_TRANSMITION_STOP 3
|
#define DMA_TRANSMITION_STOP 3
|
||||||
|
|
||||||
|
#define AZX_REG_VS_EM2_L1SEN BIT(13)
|
||||||
|
|
||||||
struct skl_dsp_resource {
|
struct skl_dsp_resource {
|
||||||
u32 max_mcps;
|
u32 max_mcps;
|
||||||
u32 max_mem;
|
u32 max_mem;
|
||||||
|
@ -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)
|
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;
|
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
snd_jack_set_key(
|
snd_jack_set_key(
|
||||||
rockchip_sound_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user