Commit 5b6d7104 authored by Mark Brown's avatar Mark Brown

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

parents 342fd472 2759ba9b
...@@ -16,6 +16,23 @@ Optional properties: ...@@ -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 { ...@@ -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, ...@@ -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 @@ ...@@ -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 { ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
......
This diff is collapsed.
...@@ -189,7 +189,7 @@ enum da7219_aad_event_regs { ...@@ -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 { ...@@ -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 */
This diff is collapsed.
...@@ -822,6 +822,6 @@ struct da7219_priv { ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 = { ...@@ -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 = { ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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,
.component_driver = {
.controls = nau8825_controls, .controls = nau8825_controls,
.num_controls = ARRAY_SIZE(nau8825_controls), .num_controls = ARRAY_SIZE(nau8825_controls),
.dapm_widgets = nau8825_dapm_widgets, .dapm_widgets = nau8825_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
.dapm_routes = nau8825_dapm_routes, .dapm_routes = nau8825_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes), .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
}, .suspend_bias_off = 1,
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
}; };
static void nau8825_reset_chip(struct regmap *regmap) static void nau8825_reset_chip(struct regmap *regmap)
...@@ -2619,13 +2618,13 @@ static int nau8825_i2c_probe(struct i2c_client *i2c, ...@@ -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 { ...@@ -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);
......
This diff is collapsed.
...@@ -199,7 +199,7 @@ enum { ...@@ -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__ */
This diff is collapsed.
...@@ -210,7 +210,7 @@ enum { ...@@ -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__ */
This diff is collapsed.
...@@ -138,6 +138,7 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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__ */
This diff is collapsed.
...@@ -1125,9 +1125,9 @@ enum { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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, ...@@ -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 = { ...@@ -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) ...@@ -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 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id) ...@@ -256,7 +247,6 @@ static int sst_cdev_close(struct device *dev, unsigned int str_id)
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) ...@@ -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) ...@@ -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 @@ ...@@ -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 =
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_params->aparams.ring_buf_info[0].addr;
alloc_param.ring_buf_info[0].size = str_info->alloc_param.ring_buf_info[0].size =
str_params->aparams.ring_buf_info[0].size; str_params->aparams.ring_buf_info[0].size;
alloc_param.frag_size = str_params->aparams.frag_size; str_info->alloc_param.frag_size = str_params->aparams.frag_size;
memcpy(&alloc_param.codec_params, &str_params->sparams, 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) ...@@ -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);
return sst_realloc_stream(sst_drv_ctx, str_id);
}
/**
* sst_realloc_stream - Send msg for (re-)allocating a stream using the
* @sst_drv_ctx intel_sst_drv context pointer
* @str_id: stream ID
*
* Send a msg for (re-)allocating a stream using the parameters previously
* passed to sst_alloc_stream_mrfld() for the same stream ID.
* Return: 0 or negative errno value.
*/
int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
{
struct snd_sst_alloc_response *response;
struct stream_info *str_info;
void *data = NULL;
int ret;
/* allocate device type context */ str_info = get_stream_info(sst_drv_ctx, str_id);
sst_init_stream(&sst_drv_ctx->streams[str_id], alloc_param.codec_type, if (!str_info)
str_id, alloc_param.operation, 0); 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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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[] = { ...@@ -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) ...@@ -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){ ...@@ -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){ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
This diff is collapsed.
/*
* 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");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment