summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-01-18 12:55:32 +0100
committerMark Brown <broonie@kernel.org>2018-01-18 12:55:32 +0100
commitb68cbc1d1d5c153dffa877fa612f70b2338a1d5a (patch)
treefd13e0196d6e6f7558e6dddf2a707425e392b0f1 /sound
parentMerge remote-tracking branch 'asoc/topic/core' into asoc-next (diff)
parentASoC: Intel: remove select on non-existing SND_SOC_INTEL_COMMON (diff)
downloadlinux-b68cbc1d1d5c153dffa877fa612f70b2338a1d5a.tar.xz
linux-b68cbc1d1d5c153dffa877fa612f70b2338a1d5a.zip
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
Diffstat (limited to 'sound')
-rw-r--r--sound/hda/ext/hdac_ext_bus.c2
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile1
-rw-r--r--sound/soc/codecs/hdac_hdmi.c356
-rw-r--r--sound/soc/codecs/sn95031.c936
-rw-r--r--sound/soc/codecs/sn95031.h133
-rw-r--r--sound/soc/intel/Kconfig115
-rw-r--r--sound/soc/intel/Makefile2
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c3
-rw-r--r--sound/soc/intel/atom/sst/sst_stream.c8
-rw-r--r--sound/soc/intel/boards/Kconfig195
-rw-r--r--sound/soc/intel/boards/bytcht_da7213.c4
-rw-r--r--sound/soc/intel/boards/bytcht_es8316.c26
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c4
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c50
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c6
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c4
-rw-r--r--sound/soc/intel/boards/haswell.c2
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c2
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c2
-rw-r--r--sound/soc/intel/boards/mfld_machine.c428
-rw-r--r--sound/soc/intel/common/sst-dsp.c4
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c2
-rw-r--r--sound/soc/intel/skylake/cnl-sst.c2
-rw-r--r--sound/soc/intel/skylake/skl-i2s.h64
-rw-r--r--sound/soc/intel/skylake/skl-messages.c22
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c155
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c14
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.h79
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c14
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.h4
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c6
-rw-r--r--sound/soc/intel/skylake/skl-sst.c2
-rw-r--r--sound/soc/intel/skylake/skl-topology.c45
-rw-r--r--sound/soc/intel/skylake/skl.c150
-rw-r--r--sound/soc/intel/skylake/skl.h22
-rw-r--r--sound/soc/soc-acpi.c65
37 files changed, 997 insertions, 1936 deletions
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c
index 31b510c5ca0b..0daf31383084 100644
--- a/sound/hda/ext/hdac_ext_bus.c
+++ b/sound/hda/ext/hdac_ext_bus.c
@@ -146,7 +146,7 @@ int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr)
edev = kzalloc(sizeof(*edev), GFP_KERNEL);
if (!edev)
return -ENOMEM;
- hdev = &edev->hdac;
+ hdev = &edev->hdev;
edev->ebus = ebus;
snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index a42ddbc93f3d..3ed2b985b38b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -133,7 +133,6 @@ config SND_SOC_ALL_CODECS
select SND_SOC_SGTL5000 if I2C
select SND_SOC_SI476X if MFD_SI476X_CORE
select SND_SOC_SIRF_AUDIO_CODEC
- select SND_SOC_SN95031 if INTEL_SCU_IPC
select SND_SOC_SPDIF
select SND_SOC_SSM2518 if I2C
select SND_SOC_SSM2602_SPI if SPI_MASTER
@@ -818,9 +817,6 @@ config SND_SOC_SIRF_AUDIO_CODEC
tristate "SiRF SoC internal audio codec"
select REGMAP_MMIO
-config SND_SOC_SN95031
- tristate
-
config SND_SOC_SPDIF
tristate "S/PDIF CODEC"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 0001069ce2a7..ae25cbe85d1d 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -140,7 +140,6 @@ snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
snd-soc-si476x-objs := si476x.o
snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
-snd-soc-sn95031-objs := sn95031.o
snd-soc-spdif-tx-objs := spdif_transmitter.o
snd-soc-spdif-rx-objs := spdif_receiver.o
snd-soc-ssm2518-objs := ssm2518.o
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index f3b4f4dfae6a..15c3638fe345 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -136,8 +136,11 @@ struct hdac_hdmi_priv {
struct mutex pin_mutex;
struct hdac_chmap chmap;
struct hdac_hdmi_drv_data *drv_data;
+ struct snd_soc_dai_driver *dai_drv;
};
+#define hdev_to_hdmi_priv(_hdev) ((to_ehdac_device(_hdev))->private_data)
+
static struct hdac_hdmi_pcm *
hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
struct hdac_hdmi_cvt *cvt)
@@ -169,7 +172,7 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
* ports.
*/
if (pcm->jack_event == 0) {
- dev_dbg(&edev->hdac.dev,
+ dev_dbg(&edev->hdev.dev,
"jack report for pcm=%d\n",
pcm->pcm_id);
snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
@@ -195,18 +198,18 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
/*
* Get the no devices that can be connected to a port on the Pin widget.
*/
-static int hdac_hdmi_get_port_len(struct hdac_ext_device *hdac, hda_nid_t nid)
+static int hdac_hdmi_get_port_len(struct hdac_ext_device *edev, hda_nid_t nid)
{
unsigned int caps;
unsigned int type, param;
- caps = get_wcaps(&hdac->hdac, nid);
+ caps = get_wcaps(&edev->hdev, nid);
type = get_wcaps_type(caps);
if (!(caps & AC_WCAP_DIGITAL) || (type != AC_WID_PIN))
return 0;
- param = snd_hdac_read_parm_uncached(&hdac->hdac, nid,
+ param = snd_hdac_read_parm_uncached(&edev->hdev, nid,
AC_PAR_DEVLIST_LEN);
if (param == -1)
return param;
@@ -219,10 +222,10 @@ static int hdac_hdmi_get_port_len(struct hdac_ext_device *hdac, hda_nid_t nid)
* id selected on the pin. Return 0 means the first port entry
* is selected or MST is not supported.
*/
-static int hdac_hdmi_port_select_get(struct hdac_ext_device *hdac,
+static int hdac_hdmi_port_select_get(struct hdac_ext_device *edev,
struct hdac_hdmi_port *port)
{
- return snd_hdac_codec_read(&hdac->hdac, port->pin->nid,
+ return snd_hdac_codec_read(&edev->hdev, port->pin->nid,
0, AC_VERB_GET_DEVICE_SEL, 0);
}
@@ -230,7 +233,7 @@ static int hdac_hdmi_port_select_get(struct hdac_ext_device *hdac,
* Sets the selected port entry for the configuring Pin widget verb.
* returns error if port set is not equal to port get otherwise success
*/
-static int hdac_hdmi_port_select_set(struct hdac_ext_device *hdac,
+static int hdac_hdmi_port_select_set(struct hdac_ext_device *edev,
struct hdac_hdmi_port *port)
{
int num_ports;
@@ -239,7 +242,7 @@ static int hdac_hdmi_port_select_set(struct hdac_ext_device *hdac,
return 0;
/* AC_PAR_DEVLIST_LEN is 0 based. */
- num_ports = hdac_hdmi_get_port_len(hdac, port->pin->nid);
+ num_ports = hdac_hdmi_get_port_len(edev, port->pin->nid);
if (num_ports < 0)
return -EIO;
@@ -250,13 +253,13 @@ static int hdac_hdmi_port_select_set(struct hdac_ext_device *hdac,
if (num_ports + 1 < port->id)
return 0;
- snd_hdac_codec_write(&hdac->hdac, port->pin->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0,
AC_VERB_SET_DEVICE_SEL, port->id);
- if (port->id != hdac_hdmi_port_select_get(hdac, port))
+ if (port->id != hdac_hdmi_port_select_get(edev, port))
return -EIO;
- dev_dbg(&hdac->hdac.dev, "Selected the port=%d\n", port->id);
+ dev_dbg(&edev->hdev.dev, "Selected the port=%d\n", port->id);
return 0;
}
@@ -276,9 +279,9 @@ static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi,
static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
{
- struct hdac_device *hdac = dev_to_hdac_dev(dev);
+ struct hdac_device *hdev = dev_to_hdac_dev(dev);
- return to_ehdac_device(hdac);
+ return to_ehdac_device(hdev);
}
static unsigned int sad_format(const u8 *sad)
@@ -321,14 +324,14 @@ format_constraint:
}
static void
-hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
+hdac_hdmi_set_dip_index(struct hdac_ext_device *edev, hda_nid_t pin_nid,
int packet_index, int byte_index)
{
int val;
val = (packet_index << 5) | (byte_index & 0x1f);
- snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
+ snd_hdac_codec_write(&edev->hdev, pin_nid, 0,
AC_VERB_SET_HDMI_DIP_INDEX, val);
}
@@ -344,14 +347,14 @@ struct dp_audio_infoframe {
u8 LFEPBL01_LSV36_DM_INH7;
};
-static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
+static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *edev,
struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port)
{
uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
struct hdmi_audio_infoframe frame;
struct hdac_hdmi_pin *pin = port->pin;
struct dp_audio_infoframe dp_ai;
- struct hdac_hdmi_priv *hdmi = hdac->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_cvt *cvt = pcm->cvt;
u8 *dip;
int ret;
@@ -360,11 +363,11 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
u8 conn_type;
int channels, ca;
- ca = snd_hdac_channel_allocation(&hdac->hdac, port->eld.info.spk_alloc,
+ ca = snd_hdac_channel_allocation(&edev->hdev, port->eld.info.spk_alloc,
pcm->channels, pcm->chmap_set, true, pcm->chmap);
channels = snd_hdac_get_active_channels(ca);
- hdmi->chmap.ops.set_channel_count(&hdac->hdac, cvt->nid, channels);
+ hdmi->chmap.ops.set_channel_count(&edev->hdev, cvt->nid, channels);
snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca,
pcm->channels, pcm->chmap, pcm->chmap_set);
@@ -397,32 +400,32 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
break;
default:
- dev_err(&hdac->hdac.dev, "Invalid connection type: %d\n",
+ dev_err(&edev->hdev.dev, "Invalid connection type: %d\n",
conn_type);
return -EIO;
}
/* stop infoframe transmission */
- hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0);
- snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
+ hdac_hdmi_set_dip_index(edev, pin->nid, 0x0, 0x0);
+ snd_hdac_codec_write(&edev->hdev, pin->nid, 0,
AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);
/* Fill infoframe. Index auto-incremented */
- hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0);
+ hdac_hdmi_set_dip_index(edev, pin->nid, 0x0, 0x0);
if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
for (i = 0; i < sizeof(buffer); i++)
- snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, pin->nid, 0,
AC_VERB_SET_HDMI_DIP_DATA, buffer[i]);
} else {
for (i = 0; i < sizeof(dp_ai); i++)
- snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, pin->nid, 0,
AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
}
/* Start infoframe */
- hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0);
- snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
+ hdac_hdmi_set_dip_index(edev, pin->nid, 0x0, 0x0);
+ snd_hdac_codec_write(&edev->hdev, pin->nid, 0,
AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);
return 0;
@@ -433,11 +436,11 @@ static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai,
int slots, int slot_width)
{
struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_pcm *pcm;
- dev_dbg(&edev->hdac.dev, "%s: strm_tag: %d\n", __func__, tx_mask);
+ dev_dbg(&edev->hdev.dev, "%s: strm_tag: %d\n", __func__, tx_mask);
dai_map = &hdmi->dai_map[dai->id];
@@ -452,8 +455,8 @@ static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai,
static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
{
- struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
- struct hdac_hdmi_priv *hdmi = hdac->private_data;
+ struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_port *port;
struct hdac_hdmi_pcm *pcm;
@@ -466,7 +469,7 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
return -ENODEV;
if ((!port->eld.monitor_present) || (!port->eld.eld_valid)) {
- dev_err(&hdac->hdac.dev,
+ dev_err(&edev->hdev.dev,
"device is not configured for this pin:port%d:%d\n",
port->pin->nid, port->id);
return -ENODEV;
@@ -486,28 +489,28 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int hdac_hdmi_query_port_connlist(struct hdac_ext_device *hdac,
+static int hdac_hdmi_query_port_connlist(struct hdac_ext_device *edev,
struct hdac_hdmi_pin *pin,
struct hdac_hdmi_port *port)
{
- if (!(get_wcaps(&hdac->hdac, pin->nid) & AC_WCAP_CONN_LIST)) {
- dev_warn(&hdac->hdac.dev,
+ if (!(get_wcaps(&edev->hdev, pin->nid) & AC_WCAP_CONN_LIST)) {
+ dev_warn(&edev->hdev.dev,
"HDMI: pin %d wcaps %#x does not support connection list\n",
- pin->nid, get_wcaps(&hdac->hdac, pin->nid));
+ pin->nid, get_wcaps(&edev->hdev, pin->nid));
return -EINVAL;
}
- if (hdac_hdmi_port_select_set(hdac, port) < 0)
+ if (hdac_hdmi_port_select_set(edev, port) < 0)
return -EIO;
- port->num_mux_nids = snd_hdac_get_connections(&hdac->hdac, pin->nid,
+ port->num_mux_nids = snd_hdac_get_connections(&edev->hdev, pin->nid,
port->mux_nids, HDA_MAX_CONNECTIONS);
if (port->num_mux_nids == 0)
- dev_warn(&hdac->hdac.dev,
+ dev_warn(&edev->hdev.dev,
"No connections found for pin:port %d:%d\n",
pin->nid, port->id);
- dev_dbg(&hdac->hdac.dev, "num_mux_nids %d for pin:port %d:%d\n",
+ dev_dbg(&edev->hdev.dev, "num_mux_nids %d for pin:port %d:%d\n",
port->num_mux_nids, pin->nid, port->id);
return port->num_mux_nids;
@@ -565,8 +568,8 @@ static struct hdac_hdmi_port *hdac_hdmi_get_port_from_cvt(
static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
- struct hdac_hdmi_priv *hdmi = hdac->private_data;
+ struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_cvt *cvt;
struct hdac_hdmi_port *port;
@@ -575,7 +578,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
dai_map = &hdmi->dai_map[dai->id];
cvt = dai_map->cvt;
- port = hdac_hdmi_get_port_from_cvt(hdac, hdmi, cvt);
+ port = hdac_hdmi_get_port_from_cvt(edev, hdmi, cvt);
/*
* To make PA and other userland happy.
@@ -586,7 +589,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
if ((!port->eld.monitor_present) ||
(!port->eld.eld_valid)) {
- dev_warn(&hdac->hdac.dev,
+ dev_warn(&edev->hdev.dev,
"Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n",
port->eld.monitor_present, port->eld.eld_valid,
port->pin->nid, port->id);
@@ -608,8 +611,8 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
- struct hdac_hdmi_priv *hdmi = hdac->private_data;
+ struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai);
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_pcm *pcm;
@@ -630,14 +633,13 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
}
static int
-hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
+hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt)
{
unsigned int chans;
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
int err;
- chans = get_wcaps(hdac, cvt->nid);
+ chans = get_wcaps(hdev, cvt->nid);
chans = get_wcaps_channels(chans);
cvt->params.channels_min = 2;
@@ -646,12 +648,12 @@ hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt)
if (chans > hdmi->chmap.channels_max)
hdmi->chmap.channels_max = chans;
- err = snd_hdac_query_supported_pcm(hdac, cvt->nid,
+ err = snd_hdac_query_supported_pcm(hdev, cvt->nid,
&cvt->params.rates,
&cvt->params.formats,
&cvt->params.maxbps);
if (err < 0)
- dev_err(&hdac->dev,
+ dev_err(&hdev->dev,
"Failed to query pcm params for nid %d: %d\n",
cvt->nid, err);
@@ -696,7 +698,7 @@ static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
struct hdac_hdmi_port *port)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pcm *pcm = NULL;
struct hdac_hdmi_port *p;
@@ -716,9 +718,9 @@ static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
hda_nid_t nid, unsigned int pwr_state)
{
- if (get_wcaps(&edev->hdac, nid) & AC_WCAP_POWER) {
- if (!snd_hdac_check_power_state(&edev->hdac, nid, pwr_state))
- snd_hdac_codec_write(&edev->hdac, nid, 0,
+ if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) {
+ if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state))
+ snd_hdac_codec_write(&edev->hdev, nid, 0,
AC_VERB_SET_POWER_STATE, pwr_state);
}
}
@@ -726,8 +728,8 @@ static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev,
static void hdac_hdmi_set_amp(struct hdac_ext_device *edev,
hda_nid_t nid, int val)
{
- if (get_wcaps(&edev->hdac, nid) & AC_WCAP_OUT_AMP)
- snd_hdac_codec_write(&edev->hdac, nid, 0,
+ if (get_wcaps(&edev->hdev, nid) & AC_WCAP_OUT_AMP)
+ snd_hdac_codec_write(&edev->hdev, nid, 0,
AC_VERB_SET_AMP_GAIN_MUTE, val);
}
@@ -739,7 +741,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev);
struct hdac_hdmi_pcm *pcm;
- dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n",
+ dev_dbg(&edev->hdev.dev, "%s: widget: %s event: %x\n",
__func__, w->name, event);
pcm = hdac_hdmi_get_pcm(edev, port);
@@ -755,7 +757,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D0);
/* Enable out path for this pin widget */
- snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_UNMUTE);
@@ -766,7 +768,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_MUTE);
/* Disable out path for this pin widget */
- snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D3);
@@ -782,10 +784,10 @@ static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,
{
struct hdac_hdmi_cvt *cvt = w->priv;
struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pcm *pcm;
- dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n",
+ dev_dbg(&edev->hdev.dev, "%s: widget: %s event: %x\n",
__func__, w->name, event);
pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt);
@@ -797,23 +799,23 @@ static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,
hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D0);
/* Enable transmission */
- snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, cvt->nid, 0,
AC_VERB_SET_DIGI_CONVERT_1, 1);
/* Category Code (CC) to zero */
- snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, cvt->nid, 0,
AC_VERB_SET_DIGI_CONVERT_2, 0);
- snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, cvt->nid, 0,
AC_VERB_SET_CHANNEL_STREAMID, pcm->stream_tag);
- snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, cvt->nid, 0,
AC_VERB_SET_STREAM_FORMAT, pcm->format);
break;
case SND_SOC_DAPM_POST_PMD:
- snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, cvt->nid, 0,
AC_VERB_SET_CHANNEL_STREAMID, 0);
- snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, cvt->nid, 0,
AC_VERB_SET_STREAM_FORMAT, 0);
hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D3);
@@ -831,7 +833,7 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev);
int mux_idx;
- dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n",
+ dev_dbg(&edev->hdev.dev, "%s: widget: %s event: %x\n",
__func__, w->name, event);
if (!kc)
@@ -844,7 +846,7 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
return -EIO;
if (mux_idx > 0) {
- snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0,
+ snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0,
AC_VERB_SET_CONNECT_SEL, (mux_idx - 1));
}
@@ -864,7 +866,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_context *dapm = w->dapm;
struct hdac_hdmi_port *port = w->priv;
struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pcm *pcm = NULL;
const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]];
@@ -922,7 +924,7 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
struct snd_soc_dapm_widget *widget,
const char *widget_name)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin = port->pin;
struct snd_kcontrol_new *kc;
struct hdac_hdmi_cvt *cvt;
@@ -934,17 +936,17 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
int i = 0;
int num_items = hdmi->num_cvt + 1;
- kc = devm_kzalloc(&edev->hdac.dev, sizeof(*kc), GFP_KERNEL);
+ kc = devm_kzalloc(&edev->hdev.dev, sizeof(*kc), GFP_KERNEL);
if (!kc)
return -ENOMEM;
- se = devm_kzalloc(&edev->hdac.dev, sizeof(*se), GFP_KERNEL);
+ se = devm_kzalloc(&edev->hdev.dev, sizeof(*se), GFP_KERNEL);
if (!se)
return -ENOMEM;
snprintf(kc_name, NAME_SIZE, "Pin %d port %d Input",
pin->nid, port->id);
- kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL);
+ kc->name = devm_kstrdup(&edev->hdev.dev, kc_name, GFP_KERNEL);
if (!kc->name)
return -ENOMEM;
@@ -962,24 +964,24 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
se->mask = roundup_pow_of_two(se->items) - 1;
sprintf(mux_items, "NONE");
- items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
+ items[i] = devm_kstrdup(&edev->hdev.dev, mux_items, GFP_KERNEL);
if (!items[i])
return -ENOMEM;
list_for_each_entry(cvt, &hdmi->cvt_list, head) {
i++;
sprintf(mux_items, "cvt %d", cvt->nid);
- items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
+ items[i] = devm_kstrdup(&edev->hdev.dev, mux_items, GFP_KERNEL);
if (!items[i])
return -ENOMEM;
}
- se->texts = devm_kmemdup(&edev->hdac.dev, items,
+ se->texts = devm_kmemdup(&edev->hdev.dev, items,
(num_items * sizeof(char *)), GFP_KERNEL);
if (!se->texts)
return -ENOMEM;
- return hdac_hdmi_fill_widget_info(&edev->hdac.dev, widget,
+ return hdac_hdmi_fill_widget_info(&edev->hdev.dev, widget,
snd_soc_dapm_mux, port, widget_name, NULL, kc, 1,
hdac_hdmi_pin_mux_widget_event,
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_REG);
@@ -990,7 +992,7 @@ static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_ext_device *edev,
struct snd_soc_dapm_widget *widgets,
struct snd_soc_dapm_route *route, int rindex)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
const struct snd_kcontrol_new *kc;
struct soc_enum *se;
int mux_index = hdmi->num_cvt + hdmi->num_ports;
@@ -1033,8 +1035,8 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)
struct snd_soc_dapm_widget *widgets;
struct snd_soc_dapm_route *route;
struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
- struct snd_soc_dai_driver *dai_drv = dapm->component->dai_drv;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
+ struct snd_soc_dai_driver *dai_drv = hdmi->dai_drv;
char widget_name[NAME_SIZE];
struct hdac_hdmi_cvt *cvt;
struct hdac_hdmi_pin *pin;
@@ -1134,7 +1136,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)
static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_dai_port_map *dai_map;
struct hdac_hdmi_cvt *cvt;
int dai_id = 0;
@@ -1150,7 +1152,7 @@ static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
dai_id++;
if (dai_id == HDA_MAX_CVTS) {
- dev_warn(&edev->hdac.dev,
+ dev_warn(&edev->hdev.dev,
"Max dais supported: %d\n", dai_id);
break;
}
@@ -1161,7 +1163,7 @@ static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_cvt *cvt;
char name[NAME_SIZE];
@@ -1176,7 +1178,7 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
list_add_tail(&cvt->head, &hdmi->cvt_list);
hdmi->num_cvt++;
- return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
+ return hdac_hdmi_query_cvt_params(&edev->hdev, cvt);
}
static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev,
@@ -1188,7 +1190,7 @@ static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev,
>> DRM_ELD_VER_SHIFT;
if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) {
- dev_err(&edev->hdac.dev, "HDMI: Unknown ELD version %d\n", ver);
+ dev_err(&edev->hdev.dev, "HDMI: Unknown ELD version %d\n", ver);
return -EINVAL;
}
@@ -1196,7 +1198,7 @@ static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev,
DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;
if (mnl > ELD_MAX_MNL) {
- dev_err(&edev->hdac.dev, "HDMI: MNL Invalid %d\n", mnl);
+ dev_err(&edev->hdev.dev, "HDMI: MNL Invalid %d\n", mnl);
return -EINVAL;
}
@@ -1209,7 +1211,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
struct hdac_hdmi_port *port)
{
struct hdac_ext_device *edev = pin->edev;
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pcm *pcm;
int size = 0;
int port_id = -1;
@@ -1227,7 +1229,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
if (pin->mst_capable)
port_id = port->id;
- size = snd_hdac_acomp_get_eld(&edev->hdac, pin->nid, port_id,
+ size = snd_hdac_acomp_get_eld(&edev->hdev, pin->nid, port_id,
&port->eld.monitor_present,
port->eld.eld_buffer,
ELD_MAX_SIZE);
@@ -1250,7 +1252,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
if (!port->eld.monitor_present || !port->eld.eld_valid) {
- dev_err(&edev->hdac.dev, "%s: disconnect for pin:port %d:%d\n",
+ dev_err(&edev->hdev.dev, "%s: disconnect for pin:port %d:%d\n",
__func__, pin->nid, port->id);
/*
@@ -1304,7 +1306,7 @@ static int hdac_hdmi_add_ports(struct hdac_hdmi_priv *hdmi,
static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin;
int ret;
@@ -1333,40 +1335,38 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
-static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
+static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdev)
{
unsigned int vendor_param;
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
unsigned int vendor_nid = hdmi->drv_data->vendor_nid;
- vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
+ vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,
INTEL_GET_VENDOR_VERB, 0);
if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
return;
vendor_param |= INTEL_EN_ALL_PIN_CVTS;
- vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
+ vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,
INTEL_SET_VENDOR_VERB, vendor_param);
if (vendor_param == -1)
return;
}
-static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
+static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdev)
{
unsigned int vendor_param;
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
unsigned int vendor_nid = hdmi->drv_data->vendor_nid;
- vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
+ vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,
INTEL_GET_VENDOR_VERB, 0);
if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
return;
/* enable DP1.2 mode */
vendor_param |= INTEL_EN_DP12;
- vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
+ vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,
INTEL_SET_VENDOR_VERB, vendor_param);
if (vendor_param == -1)
return;
@@ -1384,7 +1384,7 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
* Each converter can support a stream independently. So a dai is created
* based on the number of converter queried.
*/
-static int hdac_hdmi_create_dais(struct hdac_device *hdac,
+static int hdac_hdmi_create_dais(struct hdac_device *hdev,
struct snd_soc_dai_driver **dais,
struct hdac_hdmi_priv *hdmi, int num_dais)
{
@@ -1397,20 +1397,20 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac,
u64 formats;
int ret;
- hdmi_dais = devm_kzalloc(&hdac->dev,
+ hdmi_dais = devm_kzalloc(&hdev->dev,
(sizeof(*hdmi_dais) * num_dais),
GFP_KERNEL);
if (!hdmi_dais)
return -ENOMEM;
list_for_each_entry(cvt, &hdmi->cvt_list, head) {
- ret = snd_hdac_query_supported_pcm(hdac, cvt->nid,
+ ret = snd_hdac_query_supported_pcm(hdev, cvt->nid,
&rates, &formats, &bps);
if (ret)
return ret;
sprintf(dai_name, "intel-hdmi-hifi%d", i+1);
- hdmi_dais[i].name = devm_kstrdup(&hdac->dev,
+ hdmi_dais[i].name = devm_kstrdup(&hdev->dev,
dai_name, GFP_KERNEL);
if (!hdmi_dais[i].name)
@@ -1418,7 +1418,7 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac,
snprintf(name, sizeof(name), "hifi%d", i+1);
hdmi_dais[i].playback.stream_name =
- devm_kstrdup(&hdac->dev, name, GFP_KERNEL);
+ devm_kstrdup(&hdev->dev, name, GFP_KERNEL);
if (!hdmi_dais[i].playback.stream_name)
return -ENOMEM;
@@ -1438,6 +1438,7 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac,
}
*dais = hdmi_dais;
+ hdmi->dai_drv = hdmi_dais;
return 0;
}
@@ -1451,29 +1452,26 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
{
hda_nid_t nid;
int i, num_nodes;
- struct hdac_device *hdac = &edev->hdac;
- struct hdac_hdmi_priv *hdmi = edev->private_data;
struct hdac_hdmi_cvt *temp_cvt, *cvt_next;
struct hdac_hdmi_pin *temp_pin, *pin_next;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
+ struct hdac_device *hdev = &edev->hdev;
int ret;
- hdac_hdmi_skl_enable_all_pins(hdac);
- hdac_hdmi_skl_enable_dp12(hdac);
+ hdac_hdmi_skl_enable_all_pins(hdev);
+ hdac_hdmi_skl_enable_dp12(hdev);
- num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
+ num_nodes = snd_hdac_get_sub_nodes(hdev, hdev->afg, &nid);
if (!nid || num_nodes <= 0) {
- dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
+ dev_warn(&hdev->dev, "HDMI: failed to get afg sub nodes\n");
return -EINVAL;
}
- hdac->num_nodes = num_nodes;
- hdac->start_nid = nid;
-
- for (i = 0; i < hdac->num_nodes; i++, nid++) {
+ for (i = 0; i < num_nodes; i++, nid++) {
unsigned int caps;
unsigned int type;
- caps = get_wcaps(hdac, nid);
+ caps = get_wcaps(hdev, nid);
type = get_wcaps_type(caps);
if (!(caps & AC_WCAP_DIGITAL))
@@ -1495,16 +1493,14 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
}
}
- hdac->end_nid = nid;
-
if (!hdmi->num_pin || !hdmi->num_cvt) {
ret = -EIO;
goto free_widgets;
}
- ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
+ ret = hdac_hdmi_create_dais(hdev, dais, hdmi, hdmi->num_cvt);
if (ret) {
- dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
+ dev_err(&hdev->dev, "Failed to create dais with err: %d\n",
ret);
goto free_widgets;
}
@@ -1537,7 +1533,7 @@ free_widgets:
static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
{
struct hdac_ext_device *edev = aptr;
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin = NULL;
struct hdac_hdmi_port *hport = NULL;
struct snd_soc_codec *codec = edev->scodec;
@@ -1546,7 +1542,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
/* Don't know how this mapping is derived */
hda_nid_t pin_nid = port + 0x04;
- dev_dbg(&edev->hdac.dev, "%s: for pin:%d port=%d\n", __func__,
+ dev_dbg(&edev->hdev.dev, "%s: for pin:%d port=%d\n", __func__,
pin_nid, pipe);
/*
@@ -1559,7 +1555,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
SNDRV_CTL_POWER_D0)
return;
- if (atomic_read(&edev->hdac.in_pm))
+ if (atomic_read(&edev->hdev.in_pm))
return;
list_for_each_entry(pin, &hdmi->pin_list, head) {
@@ -1614,7 +1610,7 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
char *name;
int i = 0, j;
struct snd_soc_codec *codec = edev->scodec;
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
kc = devm_kcalloc(codec->dev, hdmi->num_ports,
sizeof(*kc), GFP_KERNEL);
@@ -1652,7 +1648,7 @@ int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
struct snd_soc_dapm_context *dapm)
{
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin;
struct snd_soc_dapm_widget *widgets;
struct snd_soc_dapm_route *route;
@@ -1728,7 +1724,7 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
{
struct snd_soc_codec *codec = dai->codec;
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pcm *pcm;
struct snd_pcm *snd_pcm;
int err;
@@ -1750,7 +1746,7 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
if (snd_pcm) {
err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap);
if (err < 0) {
- dev_err(&edev->hdac.dev,
+ dev_err(&edev->hdev.dev,
"chmap control add failed with err: %d for pcm: %d\n",
err, device);
kfree(pcm);
@@ -1791,7 +1787,7 @@ static void hdac_hdmi_present_sense_all_pins(struct hdac_ext_device *edev,
static int hdmi_codec_probe(struct snd_soc_codec *codec)
{
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(&codec->component);
struct hdac_ext_link *hlink = NULL;
@@ -1803,9 +1799,9 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
* hold the ref while we probe, also no need to drop the ref on
* exit, we call pm_runtime_suspend() so that will do for us
*/
- hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev));
+ hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdev.dev));
if (!hlink) {
- dev_err(&edev->hdac.dev, "hdac link not found\n");
+ dev_err(&edev->hdev.dev, "hdac link not found\n");
return -EIO;
}
@@ -1818,7 +1814,7 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
aops.audio_ptr = edev;
ret = snd_hdac_i915_register_notifier(&aops);
if (ret < 0) {
- dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n",
+ dev_err(&edev->hdev.dev, "notifier register failed: err: %d\n",
ret);
return ret;
}
@@ -1831,9 +1827,9 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
* hdac_device core already sets the state to active and calls
* get_noresume. So enable runtime and set the device to suspend.
*/
- pm_runtime_enable(&edev->hdac.dev);
- pm_runtime_put(&edev->hdac.dev);
- pm_runtime_suspend(&edev->hdac.dev);
+ pm_runtime_enable(&edev->hdev.dev);
+ pm_runtime_put(&edev->hdev.dev);
+ pm_runtime_suspend(&edev->hdev.dev);
return 0;
}
@@ -1842,7 +1838,7 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec)
{
struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
- pm_runtime_disable(&edev->hdac.dev);
+ pm_runtime_disable(&edev->hdev.dev);
return 0;
}
@@ -1850,9 +1846,9 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec)
static int hdmi_codec_prepare(struct device *dev)
{
struct hdac_ext_device *edev = to_hda_ext_device(dev);
- struct hdac_device *hdac = &edev->hdac;
+ struct hdac_device *hdev = &edev->hdev;
- pm_runtime_get_sync(&edev->hdac.dev);
+ pm_runtime_get_sync(&edev->hdev.dev);
/*
* Power down afg.
@@ -1861,7 +1857,7 @@ static int hdmi_codec_prepare(struct device *dev)
* is received. So setting power state is ensured without using loop
* to read the state.
*/
- snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
+ snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,
AC_PWRST_D3);
return 0;
@@ -1870,15 +1866,15 @@ static int hdmi_codec_prepare(struct device *dev)
static void hdmi_codec_complete(struct device *dev)
{
struct hdac_ext_device *edev = to_hda_ext_device(dev);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
- struct hdac_device *hdac = &edev->hdac;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
+ struct hdac_device *hdev = &edev->hdev;
/* Power up afg */
- snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
+ snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,
AC_PWRST_D0);
- hdac_hdmi_skl_enable_all_pins(&edev->hdac);
- hdac_hdmi_skl_enable_dp12(&edev->hdac);
+ hdac_hdmi_skl_enable_all_pins(&edev->hdev);
+ hdac_hdmi_skl_enable_dp12(&edev->hdev);
/*
* As the ELD notify callback request is not entertained while the
@@ -1888,7 +1884,7 @@ static void hdmi_codec_complete(struct device *dev)
*/
hdac_hdmi_present_sense_all_pins(edev, hdmi, false);
- pm_runtime_put_sync(&edev->hdac.dev);
+ pm_runtime_put_sync(&edev->hdev.dev);
}
#else
#define hdmi_codec_prepare NULL
@@ -1901,21 +1897,20 @@ static const struct snd_soc_codec_driver hdmi_hda_codec = {
.idle_bias_off = true,
};
-static void hdac_hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
+static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,
unsigned char *chmap)
{
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
memcpy(chmap, pcm->chmap, ARRAY_SIZE(pcm->chmap));
}
-static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
+static void hdac_hdmi_set_chmap(struct hdac_device *hdev, int pcm_idx,
unsigned char *chmap, int prepared)
{
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_ext_device *edev = to_ehdac_device(hdev);
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
struct hdac_hdmi_port *port;
@@ -1934,10 +1929,9 @@ static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
mutex_unlock(&pcm->lock);
}
-static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
+static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdev, int pcm_idx)
{
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
if (!pcm)
@@ -1949,10 +1943,9 @@ static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
return true;
}
-static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
+static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdev, int pcm_idx)
{
- struct hdac_ext_device *edev = to_ehdac_device(hdac);
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
struct hdac_hdmi_port *port;
@@ -1983,30 +1976,30 @@ static struct hdac_hdmi_drv_data intel_drv_data = {
static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
{
- struct hdac_device *codec = &edev->hdac;
+ struct hdac_device *hdev = &edev->hdev;
struct hdac_hdmi_priv *hdmi_priv;
struct snd_soc_dai_driver *hdmi_dais = NULL;
struct hdac_ext_link *hlink = NULL;
int num_dais = 0;
int ret = 0;
- struct hdac_driver *hdrv = drv_to_hdac_driver(codec->dev.driver);
- const struct hda_device_id *hdac_id = hdac_get_device_id(codec, hdrv);
+ struct hdac_driver *hdrv = drv_to_hdac_driver(hdev->dev.driver);
+ const struct hda_device_id *hdac_id = hdac_get_device_id(hdev, hdrv);
/* hold the ref while we probe */
- hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev));
+ hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdev.dev));
if (!hlink) {
- dev_err(&edev->hdac.dev, "hdac link not found\n");
+ dev_err(&edev->hdev.dev, "hdac link not found\n");
return -EIO;
}
snd_hdac_ext_bus_link_get(edev->ebus, hlink);
- hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
+ hdmi_priv = devm_kzalloc(&hdev->dev, sizeof(*hdmi_priv), GFP_KERNEL);
if (hdmi_priv == NULL)
return -ENOMEM;
edev->private_data = hdmi_priv;
- snd_hdac_register_chmap_ops(codec, &hdmi_priv->chmap);
+ snd_hdac_register_chmap_ops(hdev, &hdmi_priv->chmap);
hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap;
hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap;
hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
@@ -2021,7 +2014,7 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
else
hdmi_priv->drv_data = &intel_drv_data;
- dev_set_drvdata(&codec->dev, edev);
+ dev_set_drvdata(&hdev->dev, edev);
INIT_LIST_HEAD(&hdmi_priv->pin_list);
INIT_LIST_HEAD(&hdmi_priv->cvt_list);
@@ -2032,9 +2025,9 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
* Turned off in the runtime_suspend during the first explicit
* pm_runtime_suspend call.
*/
- ret = snd_hdac_display_power(edev->hdac.bus, true);
+ ret = snd_hdac_display_power(edev->hdev.bus, true);
if (ret < 0) {
- dev_err(&edev->hdac.dev,
+ dev_err(&edev->hdev.dev,
"Cannot turn on display power on i915 err: %d\n",
ret);
return ret;
@@ -2042,13 +2035,14 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais);
if (ret < 0) {
- dev_err(&codec->dev,
+ dev_err(&hdev->dev,
"Failed in parse and map nid with err: %d\n", ret);
return ret;
}
+ snd_hdac_refresh_widgets(hdev, true);
/* ASoC specific initialization */
- ret = snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
+ ret = snd_soc_register_codec(&hdev->dev, &hdmi_hda_codec,
hdmi_dais, num_dais);
snd_hdac_ext_bus_link_put(edev->ebus, hlink);
@@ -2058,14 +2052,14 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
{
- struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev);
struct hdac_hdmi_pin *pin, *pin_next;
struct hdac_hdmi_cvt *cvt, *cvt_next;
struct hdac_hdmi_pcm *pcm, *pcm_next;
struct hdac_hdmi_port *port, *port_next;
int i;
- snd_soc_unregister_codec(&edev->hdac.dev);
+ snd_soc_unregister_codec(&edev->hdev.dev);
list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
pcm->cvt = NULL;
@@ -2101,8 +2095,8 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
static int hdac_hdmi_runtime_suspend(struct device *dev)
{
struct hdac_ext_device *edev = to_hda_ext_device(dev);
- struct hdac_device *hdac = &edev->hdac;
- struct hdac_bus *bus = hdac->bus;
+ struct hdac_device *hdev = &edev->hdev;
+ struct hdac_bus *bus = hdev->bus;
struct hdac_ext_bus *ebus = hbus_to_ebus(bus);
struct hdac_ext_link *hlink = NULL;
int err;
@@ -2120,7 +2114,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
* is received. So setting power state is ensured without using loop
* to read the state.
*/
- snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
+ snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,
AC_PWRST_D3);
err = snd_hdac_display_power(bus, false);
if (err < 0) {
@@ -2142,8 +2136,8 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
static int hdac_hdmi_runtime_resume(struct device *dev)
{
struct hdac_ext_device *edev = to_hda_ext_device(dev);
- struct hdac_device *hdac = &edev->hdac;
- struct hdac_bus *bus = hdac->bus;
+ struct hdac_device *hdev = &edev->hdev;
+ struct hdac_bus *bus = hdev->bus;
struct hdac_ext_bus *ebus = hbus_to_ebus(bus);
struct hdac_ext_link *hlink = NULL;
int err;
@@ -2168,11 +2162,11 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
return err;
}
- hdac_hdmi_skl_enable_all_pins(&edev->hdac);
- hdac_hdmi_skl_enable_dp12(&edev->hdac);
+ hdac_hdmi_skl_enable_all_pins(&edev->hdev);
+ hdac_hdmi_skl_enable_dp12(&edev->hdev);
/* Power up afg */
- snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE,
+ snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,
AC_PWRST_D0);
return 0;
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
deleted file mode 100644
index 887923e68849..000000000000
--- a/sound/soc/codecs/sn95031.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * sn95031.c - TI sn95031 Codec driver
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <asm/intel_scu_ipc.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <sound/initval.h>
-#include <sound/tlv.h>
-#include <sound/jack.h>
-#include "sn95031.h"
-
-#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
-#define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
-
-/* adc helper functions */
-
-/* enables mic bias voltage */
-static void sn95031_enable_mic_bias(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0));
- snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2));
-}
-
-/* Enable/Disable the ADC depending on the argument */
-static void configure_adc(struct snd_soc_codec *sn95031_codec, int val)
-{
- int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
-
- if (val) {
- /* Enable and start the ADC */
- value |= (SN95031_ADC_ENBL | SN95031_ADC_START);
- value &= (~SN95031_ADC_NO_LOOP);
- } else {
- /* Just stop the ADC */
- value &= (~SN95031_ADC_START);
- }
- snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value);
-}
-
-/*
- * finds an empty channel for conversion
- * If the ADC is not enabled then start using 0th channel
- * itself. Otherwise find an empty channel by looking for a
- * channel in which the stopbit is set to 1. returns the index
- * of the first free channel if succeeds or an error code.
- *
- * Context: can sleep
- *
- */
-static int find_free_channel(struct snd_soc_codec *sn95031_codec)
-{
- int i, value;
-
- /* check whether ADC is enabled */
- value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1);
-
- if ((value & SN95031_ADC_ENBL) == 0)
- return 0;
-
- /* ADC is already enabled; Looking for an empty channel */
- for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) {
- value = snd_soc_read(sn95031_codec,
- SN95031_ADC_CHNL_START_ADDR + i);
- if (value & SN95031_STOPBIT_MASK)
- break;
- }
- return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i;
-}
-
-/* Initialize the ADC for reading micbias values. Can sleep. */
-static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec)
-{
- int base_addr, chnl_addr;
- int value;
- int channel_index;
-
- /* Index of the first channel in which the stop bit is set */
- channel_index = find_free_channel(sn95031_codec);
- if (channel_index < 0) {
- pr_err("No free ADC channels");
- return channel_index;
- }
-
- base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index;
-
- if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) {
- /* Reset stop bit for channels other than 0 and 12 */
- value = snd_soc_read(sn95031_codec, base_addr);
- /* Set the stop bit to zero */
- snd_soc_write(sn95031_codec, base_addr, value & 0xEF);
- /* Index of the first free channel */
- base_addr++;
- channel_index++;
- }
-
- /* Since this is the last channel, set the stop bit
- to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
- snd_soc_write(sn95031_codec, base_addr,
- SN95031_AUDIO_DETECT_CODE | 0x10);
-
- chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index;
- pr_debug("mid_initialize : %x", chnl_addr);
- configure_adc(sn95031_codec, 1);
- return chnl_addr;
-}
-
-
-/* reads the ADC registers and gets the mic bias value in mV. */
-static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec)
-{
- u16 adc_adr = sn95031_initialize_adc(codec);
- u16 adc_val1, adc_val2;
- unsigned int mic_bias;
-
- sn95031_enable_mic_bias(codec);
-
- /* Enable the sound card for conversion before reading */
- snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05);
- /* Re-toggle the RRDATARD bit */
- snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04);
-
- /* Read the higher bits of data */
- msleep(1000);
- adc_val1 = snd_soc_read(codec, adc_adr);
- adc_adr++;
- adc_val2 = snd_soc_read(codec, adc_adr);
-
- /* Adding lower two bits to the higher bits */
- mic_bias = (adc_val1 << 2) + (adc_val2 & 3);
- mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000;
- pr_debug("mic bias = %dmV\n", mic_bias);
- return mic_bias;
-}
-/*end - adc helper functions */
-
-static int sn95031_read(void *ctx, unsigned int reg, unsigned int *val)
-{
- u8 value = 0;
- int ret;
-
- ret = intel_scu_ipc_ioread8(reg, &value);
- if (ret == 0)
- *val = value;
-
- return ret;
-}
-
-static int sn95031_write(void *ctx, unsigned int reg, unsigned int value)
-{
- return intel_scu_ipc_iowrite8(reg, value);
-}
-
-static const struct regmap_config sn95031_regmap = {
- .reg_read = sn95031_read,
- .reg_write = sn95031_write,
-};
-
-static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
- enum snd_soc_bias_level level)
-{
- switch (level) {
- case SND_SOC_BIAS_ON:
- break;
-
- case SND_SOC_BIAS_PREPARE:
- if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
- pr_debug("vaud_bias powering up pll\n");
- /* power up the pll */
- snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
- /* enable pcm 2 */
- snd_soc_update_bits(codec, SN95031_PCM2C2,
- BIT(0), BIT(0));
- }
- break;
-
- case SND_SOC_BIAS_STANDBY:
- switch (snd_soc_codec_get_bias_level(codec)) {
- case SND_SOC_BIAS_OFF:
- pr_debug("vaud_bias power up rail\n");
- /* power up the rail */
- snd_soc_write(codec, SN95031_VAUD,
- BIT(2)|BIT(1)|BIT(0));
- msleep(1);
- break;
- case SND_SOC_BIAS_PREPARE:
- /* turn off pcm */
- pr_debug("vaud_bias power dn pcm\n");
- snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
- snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
- break;
- default:
- break;
- }
- break;
-
-
- case SND_SOC_BIAS_OFF:
- pr_debug("vaud_bias _OFF doing rail shutdown\n");
- snd_soc_write(codec, SN95031_VAUD, BIT(3));
- break;
- }
-
- return 0;
-}
-
-static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
- /* power up the rail */
- snd_soc_write(codec, SN95031_VHSP, 0x3D);
- snd_soc_write(codec, SN95031_VHSN, 0x3F);
- msleep(1);
- } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
- pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
- snd_soc_write(codec, SN95031_VHSP, 0xC4);
- snd_soc_write(codec, SN95031_VHSN, 0x04);
- }
- return 0;
-}
-
-static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
- /* power up the rail */
- snd_soc_write(codec, SN95031_VIHF, 0x27);
- msleep(1);
- } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
- pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
- snd_soc_write(codec, SN95031_VIHF, 0x24);
- }
- return 0;
-}
-
-static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
- unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- ldo = BIT(5)|BIT(4);
- clk_dir = BIT(0);
- data_dir = BIT(7);
- }
- /* program DMIC LDO, clock and set clock */
- snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
- snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
- snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(7), data_dir);
- return 0;
-}
-
-static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
- unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- ldo = BIT(5)|BIT(4);
- clk_dir = BIT(2);
- data_dir = BIT(1);
- }
- /* program DMIC LDO, clock and set clock */
- snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
- snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
- snd_soc_update_bits(codec, SN95031_DMICBUF45, BIT(1), data_dir);
- return 0;
-}
-
-static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
- unsigned int ldo = 0;
-
- if (SND_SOC_DAPM_EVENT_ON(event))
- ldo = BIT(7)|BIT(6);
-
- /* program DMIC LDO */
- snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
- return 0;
-}
-
-/* mux controls */
-static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" };
-
-static SOC_ENUM_SINGLE_DECL(sn95031_micl_enum,
- SN95031_ADCCONFIG, 1, sn95031_mic_texts);
-
-static const struct snd_kcontrol_new sn95031_micl_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_micl_enum);
-
-static SOC_ENUM_SINGLE_DECL(sn95031_micr_enum,
- SN95031_ADCCONFIG, 3, sn95031_mic_texts);
-
-static const struct snd_kcontrol_new sn95031_micr_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_micr_enum);
-
-static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3",
- "DMIC4", "DMIC5", "DMIC6",
- "ADC Left", "ADC Right" };
-
-static SOC_ENUM_SINGLE_DECL(sn95031_input1_enum,
- SN95031_AUDIOMUX12, 0, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input1_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input1_enum);
-
-static SOC_ENUM_SINGLE_DECL(sn95031_input2_enum,
- SN95031_AUDIOMUX12, 4, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input2_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input2_enum);
-
-static SOC_ENUM_SINGLE_DECL(sn95031_input3_enum,
- SN95031_AUDIOMUX34, 0, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input3_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input3_enum);
-
-static SOC_ENUM_SINGLE_DECL(sn95031_input4_enum,
- SN95031_AUDIOMUX34, 4, sn95031_input_texts);
-
-static const struct snd_kcontrol_new sn95031_input4_mux_control =
- SOC_DAPM_ENUM("Route", sn95031_input4_enum);
-
-/* capture path controls */
-
-static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"};
-
-/* 0dB to 30dB in 10dB steps */
-static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0);
-
-static SOC_ENUM_SINGLE_DECL(sn95031_micmode1_enum,
- SN95031_MICAMP1, 1, sn95031_micmode_text);
-static SOC_ENUM_SINGLE_DECL(sn95031_micmode2_enum,
- SN95031_MICAMP2, 1, sn95031_micmode_text);
-
-static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"};
-
-static SOC_ENUM_SINGLE_DECL(sn95031_dmic12_cfg_enum,
- SN95031_DMICMUX, 0, sn95031_dmic_cfg_text);
-static SOC_ENUM_SINGLE_DECL(sn95031_dmic34_cfg_enum,
- SN95031_DMICMUX, 1, sn95031_dmic_cfg_text);
-static SOC_ENUM_SINGLE_DECL(sn95031_dmic56_cfg_enum,
- SN95031_DMICMUX, 2, sn95031_dmic_cfg_text);
-
-static const struct snd_kcontrol_new sn95031_snd_controls[] = {
- SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum),
- SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum),
- SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum),
- SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum),
- SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum),
- SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1,
- 2, 4, 0, mic_tlv),
- SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2,
- 2, 4, 0, mic_tlv),
-};
-
-/* DAPM widgets */
-static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = {
-
- /* all end points mic, hs etc */
- SND_SOC_DAPM_OUTPUT("HPOUTL"),
- SND_SOC_DAPM_OUTPUT("HPOUTR"),
- SND_SOC_DAPM_OUTPUT("EPOUT"),
- SND_SOC_DAPM_OUTPUT("IHFOUTL"),
- SND_SOC_DAPM_OUTPUT("IHFOUTR"),
- SND_SOC_DAPM_OUTPUT("LINEOUTL"),
- SND_SOC_DAPM_OUTPUT("LINEOUTR"),
- SND_SOC_DAPM_OUTPUT("VIB1OUT"),
- SND_SOC_DAPM_OUTPUT("VIB2OUT"),
-
- SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */
- SND_SOC_DAPM_INPUT("AMIC2"),
- SND_SOC_DAPM_INPUT("DMIC1"),
- SND_SOC_DAPM_INPUT("DMIC2"),
- SND_SOC_DAPM_INPUT("DMIC3"),
- SND_SOC_DAPM_INPUT("DMIC4"),
- SND_SOC_DAPM_INPUT("DMIC5"),
- SND_SOC_DAPM_INPUT("DMIC6"),
- SND_SOC_DAPM_INPUT("LINEINL"),
- SND_SOC_DAPM_INPUT("LINEINR"),
-
- SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0),
- SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0),
- SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0),
- SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0),
- SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0),
-
- SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0,
- sn95031_dmic12_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0,
- sn95031_dmic34_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0,
- sn95031_dmic56_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0,
- SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0,
- sn95031_vhs_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0,
- sn95031_vihf_event,
- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
- /* playback path driver enables */
- SND_SOC_DAPM_PGA("Headset Left Playback",
- SN95031_DRIVEREN, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Headset Right Playback",
- SN95031_DRIVEREN, 1, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Left Playback",
- SN95031_DRIVEREN, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Right Playback",
- SN95031_DRIVEREN, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Vibra1 Playback",
- SN95031_DRIVEREN, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Vibra2 Playback",
- SN95031_DRIVEREN, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Earpiece Playback",
- SN95031_DRIVEREN, 6, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Lineout Left Playback",
- SN95031_LOCTL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Lineout Right Playback",
- SN95031_LOCTL, 4, 0, NULL, 0),
-
- /* playback path filter enable */
- SND_SOC_DAPM_PGA("Headset Left Filter",
- SN95031_HSEPRXCTRL, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Headset Right Filter",
- SN95031_HSEPRXCTRL, 5, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Left Filter",
- SN95031_IHFRXCTRL, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("Speaker Right Filter",
- SN95031_IHFRXCTRL, 1, 0, NULL, 0),
-
- /* DACs */
- SND_SOC_DAPM_DAC("HSDAC Left", "Headset",
- SN95031_DACCONFIG, 0, 0),
- SND_SOC_DAPM_DAC("HSDAC Right", "Headset",
- SN95031_DACCONFIG, 1, 0),
- SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker",
- SN95031_DACCONFIG, 2, 0),
- SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker",
- SN95031_DACCONFIG, 3, 0),
- SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1",
- SN95031_VIB1C5, 1, 0),
- SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2",
- SN95031_VIB2C5, 1, 0),
-
- /* capture widgets */
- SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1,
- 7, 0, NULL, 0),
- SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2,
- 7, 0, NULL, 0),
-
- SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0),
-
- /* ADC have null stream as they will be turned ON by TX path */
- SND_SOC_DAPM_ADC("ADC Left", NULL,
- SN95031_ADCCONFIG, 0, 0),
- SND_SOC_DAPM_ADC("ADC Right", NULL,
- SN95031_ADCCONFIG, 2, 0),
-
- SND_SOC_DAPM_MUX("Mic_InputL Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control),
- SND_SOC_DAPM_MUX("Mic_InputR Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control),
-
- SND_SOC_DAPM_MUX("Txpath1 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control),
- SND_SOC_DAPM_MUX("Txpath2 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control),
- SND_SOC_DAPM_MUX("Txpath3 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control),
- SND_SOC_DAPM_MUX("Txpath4 Capture Route",
- SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control),
-
-};
-
-static const struct snd_soc_dapm_route sn95031_audio_map[] = {
- /* headset and earpiece map */
- { "HPOUTL", NULL, "Headset Rail"},
- { "HPOUTR", NULL, "Headset Rail"},
- { "HPOUTL", NULL, "Headset Left Playback" },
- { "HPOUTR", NULL, "Headset Right Playback" },
- { "EPOUT", NULL, "Earpiece Playback" },
- { "Headset Left Playback", NULL, "Headset Left Filter"},
- { "Headset Right Playback", NULL, "Headset Right Filter"},
- { "Earpiece Playback", NULL, "Headset Left Filter"},
- { "Headset Left Filter", NULL, "HSDAC Left"},
- { "Headset Right Filter", NULL, "HSDAC Right"},
-
- /* speaker map */
- { "IHFOUTL", NULL, "Speaker Rail"},
- { "IHFOUTR", NULL, "Speaker Rail"},
- { "IHFOUTL", NULL, "Speaker Left Playback"},
- { "IHFOUTR", NULL, "Speaker Right Playback"},
- { "Speaker Left Playback", NULL, "Speaker Left Filter"},
- { "Speaker Right Playback", NULL, "Speaker Right Filter"},
- { "Speaker Left Filter", NULL, "IHFDAC Left"},
- { "Speaker Right Filter", NULL, "IHFDAC Right"},
-
- /* vibra map */
- { "VIB1OUT", NULL, "Vibra1 Playback"},
- { "Vibra1 Playback", NULL, "Vibra1 DAC"},
-
- { "VIB2OUT", NULL, "Vibra2 Playback"},
- { "Vibra2 Playback", NULL, "Vibra2 DAC"},
-
- /* lineout */
- { "LINEOUTL", NULL, "Lineout Left Playback"},
- { "LINEOUTR", NULL, "Lineout Right Playback"},
- { "Lineout Left Playback", NULL, "Headset Left Filter"},
- { "Lineout Left Playback", NULL, "Speaker Left Filter"},
- { "Lineout Left Playback", NULL, "Vibra1 DAC"},
- { "Lineout Right Playback", NULL, "Headset Right Filter"},
- { "Lineout Right Playback", NULL, "Speaker Right Filter"},
- { "Lineout Right Playback", NULL, "Vibra2 DAC"},
-
- /* Headset (AMIC1) mic */
- { "AMIC1Bias", NULL, "AMIC1"},
- { "MIC1 Enable", NULL, "AMIC1Bias"},
- { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"},
-
- /* AMIC2 */
- { "AMIC2Bias", NULL, "AMIC2"},
- { "MIC2 Enable", NULL, "AMIC2Bias"},
- { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"},
-
-
- /* Linein */
- { "LineIn Enable Left", NULL, "LINEINL"},
- { "LineIn Enable Right", NULL, "LINEINR"},
- { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"},
- { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"},
-
- /* ADC connection */
- { "ADC Left", NULL, "Mic_InputL Capture Route"},
- { "ADC Right", NULL, "Mic_InputR Capture Route"},
-
- /*DMIC connections */
- { "DMIC1", NULL, "DMIC12supply"},
- { "DMIC2", NULL, "DMIC12supply"},
- { "DMIC3", NULL, "DMIC34supply"},
- { "DMIC4", NULL, "DMIC34supply"},
- { "DMIC5", NULL, "DMIC56supply"},
- { "DMIC6", NULL, "DMIC56supply"},
-
- { "DMIC12Bias", NULL, "DMIC1"},
- { "DMIC12Bias", NULL, "DMIC2"},
- { "DMIC34Bias", NULL, "DMIC3"},
- { "DMIC34Bias", NULL, "DMIC4"},
- { "DMIC56Bias", NULL, "DMIC5"},
- { "DMIC56Bias", NULL, "DMIC6"},
-
- /*TX path inputs*/
- { "Txpath1 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath2 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath3 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath4 Capture Route", "ADC Left", "ADC Left"},
- { "Txpath1 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath2 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath3 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath4 Capture Route", "ADC Right", "ADC Right"},
- { "Txpath1 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath2 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath3 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath4 Capture Route", "DMIC1", "DMIC1"},
- { "Txpath1 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath2 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath3 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath4 Capture Route", "DMIC2", "DMIC2"},
- { "Txpath1 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath2 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath3 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath4 Capture Route", "DMIC3", "DMIC3"},
- { "Txpath1 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath2 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath3 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath4 Capture Route", "DMIC4", "DMIC4"},
- { "Txpath1 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath2 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath3 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath4 Capture Route", "DMIC5", "DMIC5"},
- { "Txpath1 Capture Route", "DMIC6", "DMIC6"},
- { "Txpath2 Capture Route", "DMIC6", "DMIC6"},
- { "Txpath3 Capture Route", "DMIC6", "DMIC6"},
- { "Txpath4 Capture Route", "DMIC6", "DMIC6"},
-
- /* tx path */
- { "TX1 Enable", NULL, "Txpath1 Capture Route"},
- { "TX2 Enable", NULL, "Txpath2 Capture Route"},
- { "TX3 Enable", NULL, "Txpath3 Capture Route"},
- { "TX4 Enable", NULL, "Txpath4 Capture Route"},
- { "PCM_Out", NULL, "TX1 Enable"},
- { "PCM_Out", NULL, "TX2 Enable"},
- { "PCM_Out", NULL, "TX3 Enable"},
- { "PCM_Out", NULL, "TX4 Enable"},
-
-};
-
-/* speaker and headset mutes, for audio pops and clicks */
-static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute)
-{
- snd_soc_update_bits(dai->codec,
- SN95031_HSLVOLCTRL, BIT(7), (!mute << 7));
- snd_soc_update_bits(dai->codec,
- SN95031_HSRVOLCTRL, BIT(7), (!mute << 7));
- return 0;
-}
-
-static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute)
-{
- snd_soc_update_bits(dai->codec,
- SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7));
- snd_soc_update_bits(dai->codec,
- SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7));
- return 0;
-}
-
-static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
-{
- unsigned int format, rate;
-
- switch (params_width(params)) {
- case 16:
- format = BIT(4)|BIT(5);
- break;
-
- case 24:
- format = 0;
- break;
- default:
- return -EINVAL;
- }
- snd_soc_update_bits(dai->codec, SN95031_PCM2C2,
- BIT(4)|BIT(5), format);
-
- switch (params_rate(params)) {
- case 48000:
- pr_debug("RATE_48000\n");
- rate = 0;
- break;
-
- case 44100:
- pr_debug("RATE_44100\n");
- rate = BIT(7);
- break;
-
- default:
- pr_err("ERR rate %d\n", params_rate(params));
- return -EINVAL;
- }
- snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate);
-
- return 0;
-}
-
-/* Codec DAI section */
-static const struct snd_soc_dai_ops sn95031_headset_dai_ops = {
- .digital_mute = sn95031_pcm_hs_mute,
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static const struct snd_soc_dai_ops sn95031_speaker_dai_ops = {
- .digital_mute = sn95031_pcm_spkr_mute,
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static const struct snd_soc_dai_ops sn95031_vib1_dai_ops = {
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static const struct snd_soc_dai_ops sn95031_vib2_dai_ops = {
- .hw_params = sn95031_pcm_hw_params,
-};
-
-static struct snd_soc_dai_driver sn95031_dais[] = {
-{
- .name = "SN95031 Headset",
- .playback = {
- .stream_name = "Headset",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 5,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_headset_dai_ops,
-},
-{ .name = "SN95031 Speaker",
- .playback = {
- .stream_name = "Speaker",
- .channels_min = 2,
- .channels_max = 2,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_speaker_dai_ops,
-},
-{ .name = "SN95031 Vibra1",
- .playback = {
- .stream_name = "Vibra1",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_vib1_dai_ops,
-},
-{ .name = "SN95031 Vibra2",
- .playback = {
- .stream_name = "Vibra2",
- .channels_min = 1,
- .channels_max = 1,
- .rates = SN95031_RATES,
- .formats = SN95031_FORMATS,
- },
- .ops = &sn95031_vib2_dai_ops,
-},
-};
-
-static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
-}
-
-static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
-{
- snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
- snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
-}
-
-static int sn95031_get_headset_state(struct snd_soc_codec *codec,
- struct snd_soc_jack *mfld_jack)
-{
- int micbias = sn95031_get_mic_bias(codec);
-
- int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
-
- pr_debug("jack type detected = %d\n", jack_type);
- if (jack_type == SND_JACK_HEADSET)
- sn95031_enable_jack_btn(codec);
- return jack_type;
-}
-
-void sn95031_jack_detection(struct snd_soc_codec *codec,
- struct mfld_jack_data *jack_data)
-{
- unsigned int status;
- unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
-
- pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
- if (jack_data->intr_id & 0x1) {
- pr_debug("short_push detected\n");
- status = SND_JACK_HEADSET | SND_JACK_BTN_0;
- } else if (jack_data->intr_id & 0x2) {
- pr_debug("long_push detected\n");
- status = SND_JACK_HEADSET | SND_JACK_BTN_1;
- } else if (jack_data->intr_id & 0x4) {
- pr_debug("headset or headphones inserted\n");
- status = sn95031_get_headset_state(codec, jack_data->mfld_jack);
- } else if (jack_data->intr_id & 0x8) {
- pr_debug("headset or headphones removed\n");
- status = 0;
- sn95031_disable_jack_btn(codec);
- } else {
- pr_err("unidentified interrupt\n");
- return;
- }
-
- snd_soc_jack_report(jack_data->mfld_jack, status, mask);
- /*button pressed and released so we send explicit button release */
- if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
- snd_soc_jack_report(jack_data->mfld_jack,
- SND_JACK_HEADSET, mask);
-}
-EXPORT_SYMBOL_GPL(sn95031_jack_detection);
-
-/* codec registration */
-static int sn95031_codec_probe(struct snd_soc_codec *codec)
-{
- pr_debug("codec_probe called\n");
-
- /* PCM interface config
- * This sets the pcm rx slot conguration to max 6 slots
- * for max 4 dais (2 stereo and 2 mono)
- */
- snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10);
- snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32);
- snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54);
- snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10);
- snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32);
- /* pcm port setting
- * This sets the pcm port to slave and clock at 19.2Mhz which
- * can support 6slots, sampling rate set per stream in hw-params
- */
- snd_soc_write(codec, SN95031_PCM1C1, 0x00);
- snd_soc_write(codec, SN95031_PCM2C1, 0x01);
- snd_soc_write(codec, SN95031_PCM2C2, 0x0A);
- snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4));
- /* vendor vibra workround, the vibras are muted by
- * custom register so unmute them
- */
- snd_soc_write(codec, SN95031_SSR5, 0x80);
- snd_soc_write(codec, SN95031_SSR6, 0x80);
- snd_soc_write(codec, SN95031_VIB1C5, 0x00);
- snd_soc_write(codec, SN95031_VIB2C5, 0x00);
- /* configure vibras for pcm port */
- snd_soc_write(codec, SN95031_VIB1C3, 0x00);
- snd_soc_write(codec, SN95031_VIB2C3, 0x00);
-
- /* soft mute ramp time */
- snd_soc_write(codec, SN95031_SOFTMUTE, 0x3);
- /* fix the initial volume at 1dB,
- * default in +9dB,
- * 1dB give optimal swing on DAC, amps
- */
- snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08);
- snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08);
- snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08);
- snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08);
- /* dac mode and lineout workaround */
- snd_soc_write(codec, SN95031_SSR2, 0x10);
- snd_soc_write(codec, SN95031_SSR3, 0x40);
-
- return 0;
-}
-
-static const struct snd_soc_codec_driver sn95031_codec = {
- .probe = sn95031_codec_probe,
- .set_bias_level = sn95031_set_vaud_bias,
- .idle_bias_off = true,
-
- .component_driver = {
- .controls = sn95031_snd_controls,
- .num_controls = ARRAY_SIZE(sn95031_snd_controls),
- .dapm_widgets = sn95031_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets),
- .dapm_routes = sn95031_audio_map,
- .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map),
- },
-};
-
-static int sn95031_device_probe(struct platform_device *pdev)
-{
- struct regmap *regmap;
-
- pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev));
-
- regmap = devm_regmap_init(&pdev->dev, NULL, NULL, &sn95031_regmap);
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- return snd_soc_register_codec(&pdev->dev, &sn95031_codec,
- sn95031_dais, ARRAY_SIZE(sn95031_dais));
-}
-
-static int sn95031_device_remove(struct platform_device *pdev)
-{
- pr_debug("codec device remove called\n");
- snd_soc_unregister_codec(&pdev->dev);
- return 0;
-}
-
-static struct platform_driver sn95031_codec_driver = {
- .driver = {
- .name = "sn95031",
- },
- .probe = sn95031_device_probe,
- .remove = sn95031_device_remove,
-};
-
-module_platform_driver(sn95031_codec_driver);
-
-MODULE_DESCRIPTION("ASoC TI SN95031 codec driver");
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:sn95031");
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
deleted file mode 100644
index 7651fe4e6a45..000000000000
--- a/sound/soc/codecs/sn95031.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * sn95031.h - TI sn95031 Codec driver
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *
- */
-#ifndef _SN95031_H
-#define _SN95031_H
-
-/*register map*/
-#define SN95031_VAUD 0xDB
-#define SN95031_VHSP 0xDC
-#define SN95031_VHSN 0xDD
-#define SN95031_VIHF 0xC9
-
-#define SN95031_AUDPLLCTRL 0x240
-#define SN95031_DMICBUF0123 0x241
-#define SN95031_DMICBUF45 0x242
-#define SN95031_DMICGPO 0x244
-#define SN95031_DMICMUX 0x245
-#define SN95031_DMICLK 0x246
-#define SN95031_MICBIAS 0x247
-#define SN95031_ADCCONFIG 0x248
-#define SN95031_MICAMP1 0x249
-#define SN95031_MICAMP2 0x24A
-#define SN95031_NOISEMUX 0x24B
-#define SN95031_AUDIOMUX12 0x24C
-#define SN95031_AUDIOMUX34 0x24D
-#define SN95031_AUDIOSINC 0x24E
-#define SN95031_AUDIOTXEN 0x24F
-#define SN95031_HSEPRXCTRL 0x250
-#define SN95031_IHFRXCTRL 0x251
-#define SN95031_HSMIXER 0x256
-#define SN95031_DACCONFIG 0x257
-#define SN95031_SOFTMUTE 0x258
-#define SN95031_HSLVOLCTRL 0x259
-#define SN95031_HSRVOLCTRL 0x25A
-#define SN95031_IHFLVOLCTRL 0x25B
-#define SN95031_IHFRVOLCTRL 0x25C
-#define SN95031_DRIVEREN 0x25D
-#define SN95031_LOCTL 0x25E
-#define SN95031_VIB1C1 0x25F
-#define SN95031_VIB1C2 0x260
-#define SN95031_VIB1C3 0x261
-#define SN95031_VIB1SPIPCM1 0x262
-#define SN95031_VIB1SPIPCM2 0x263
-#define SN95031_VIB1C5 0x264
-#define SN95031_VIB2C1 0x265
-#define SN95031_VIB2C2 0x266
-#define SN95031_VIB2C3 0x267
-#define SN95031_VIB2SPIPCM1 0x268
-#define SN95031_VIB2SPIPCM2 0x269
-#define SN95031_VIB2C5 0x26A
-#define SN95031_BTNCTRL1 0x26B
-#define SN95031_BTNCTRL2 0x26C
-#define SN95031_PCM1TXSLOT01 0x26D
-#define SN95031_PCM1TXSLOT23 0x26E
-#define SN95031_PCM1TXSLOT45 0x26F
-#define SN95031_PCM1RXSLOT0_3 0x270
-#define SN95031_PCM1RXSLOT45 0x271
-#define SN95031_PCM2TXSLOT01 0x272
-#define SN95031_PCM2TXSLOT23 0x273
-#define SN95031_PCM2TXSLOT45 0x274
-#define SN95031_PCM2RXSLOT01 0x275
-#define SN95031_PCM2RXSLOT23 0x276
-#define SN95031_PCM2RXSLOT45 0x277
-#define SN95031_PCM1C1 0x278
-#define SN95031_PCM1C2 0x279
-#define SN95031_PCM1C3 0x27A
-#define SN95031_PCM2C1 0x27B
-#define SN95031_PCM2C2 0x27C
-/*end codec register defn*/
-
-/*vendor defn these are not part of avp*/
-#define SN95031_SSR2 0x381
-#define SN95031_SSR3 0x382
-#define SN95031_SSR5 0x384
-#define SN95031_SSR6 0x385
-
-/* ADC registers */
-
-#define SN95031_ADC1CNTL1 0x1C0
-#define SN95031_ADC_ENBL 0x10
-#define SN95031_ADC_START 0x08
-#define SN95031_ADC1CNTL3 0x1C2
-#define SN95031_ADCTHERM_ENBL 0x04
-#define SN95031_ADCRRDATA_ENBL 0x05
-#define SN95031_STOPBIT_MASK 16
-#define SN95031_ADCTHERM_MASK 4
-#define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */
-#define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1)
-#define SN95031_ADC_NO_LOOP 0x07
-#define SN95031_AUDIO_GPIO_CTRL 0x070
-
-/* ADC channel code values */
-#define SN95031_AUDIO_DETECT_CODE 0x06
-
-/* ADC base addresses */
-#define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
-#define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
-/* multipier to convert to mV */
-#define SN95031_ADC_ONE_LSB_MULTIPLIER 2346
-
-
-struct mfld_jack_data {
- int intr_id;
- int micbias_vol;
- struct snd_soc_jack *mfld_jack;
-};
-
-extern void sn95031_jack_detection(struct snd_soc_codec *codec,
- struct mfld_jack_data *jack_data);
-
-#endif
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 7b49d04e3c60..f2c9e8c5970a 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -1,71 +1,122 @@
+config SND_SOC_INTEL_SST_TOPLEVEL
+ bool "Intel ASoC SST drivers"
+ default y
+ depends on X86 || COMPILE_TEST
+ select SND_SOC_INTEL_MACH
+ help
+ Intel ASoC SST Platform Drivers. If you have a Intel machine that
+ has an audio controller with a DSP and I2S or DMIC port, then
+ enable this option by saying Y
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Intel SST drivers.
+
+if SND_SOC_INTEL_SST_TOPLEVEL
+
config SND_SST_IPC
tristate
+ # This option controls the IPC core for HiFi2 platforms
config SND_SST_IPC_PCI
tristate
select SND_SST_IPC
+ # This option controls the PCI-based IPC for HiFi2 platforms
+ # (Medfield, Merrifield).
config SND_SST_IPC_ACPI
tristate
select SND_SST_IPC
- select SND_SOC_INTEL_SST
- select IOSF_MBI
+ # This option controls the ACPI-based IPC for HiFi2 platforms
+ # (Baytrail, Cherrytrail)
-config SND_SOC_INTEL_COMMON
+config SND_SOC_INTEL_SST_ACPI
tristate
+ # This option controls ACPI-based probing on
+ # Haswell/Broadwell/Baytrail legacy and will be set
+ # when these platforms are enabled
config SND_SOC_INTEL_SST
tristate
- select SND_SOC_INTEL_SST_ACPI if ACPI
config SND_SOC_INTEL_SST_FIRMWARE
tristate
select DW_DMAC_CORE
-
-config SND_SOC_INTEL_SST_ACPI
- tristate
-
-config SND_SOC_ACPI_INTEL_MATCH
- tristate
- select SND_SOC_ACPI if ACPI
-
-config SND_SOC_INTEL_SST_TOPLEVEL
- tristate "Intel ASoC SST drivers"
- depends on X86 || COMPILE_TEST
- select SND_SOC_INTEL_MACH
- select SND_SOC_INTEL_COMMON
- help
- Intel ASoC Audio Drivers. If you have a Intel machine that
- has audio controller with a DSP and I2S or DMIC port, then
- enable this option by saying Y or M
- If unsure select "N".
+ # This option controls firmware download on
+ # Haswell/Broadwell/Baytrail legacy and will be set
+ # when these platforms are enabled
config SND_SOC_INTEL_HASWELL
- tristate "Intel ASoC SST driver for Haswell/Broadwell"
- depends on SND_SOC_INTEL_SST_TOPLEVEL && SND_DMA_SGBUF
- depends on DMADEVICES
+ tristate "Haswell/Broadwell Platforms"
+ depends on SND_DMA_SGBUF
+ depends on DMADEVICES && ACPI
select SND_SOC_INTEL_SST
+ select SND_SOC_INTEL_SST_ACPI
select SND_SOC_INTEL_SST_FIRMWARE
+ select SND_SOC_ACPI_INTEL_MATCH
+ help
+ If you have a Intel Haswell or Broadwell platform connected to
+ an I2S codec, then enable this option by saying Y or m. This is
+ typically used for Chromebooks. This is a recommended option.
config SND_SOC_INTEL_BAYTRAIL
- tristate "Intel ASoC SST driver for Baytrail (legacy)"
- depends on SND_SOC_INTEL_SST_TOPLEVEL
- depends on DMADEVICES
+ tristate "Baytrail (legacy) Platforms"
+ depends on DMADEVICES && ACPI
select SND_SOC_INTEL_SST
+ select SND_SOC_INTEL_SST_ACPI
select SND_SOC_INTEL_SST_FIRMWARE
+ select SND_SOC_ACPI_INTEL_MATCH
+ help
+ If you have a Intel Baytrail platform connected to an I2S codec,
+ then enable this option by saying Y or m. This was typically used
+ for Baytrail Chromebooks but this option is now deprecated and is
+ not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead.
+
+config SND_SST_ATOM_HIFI2_PLATFORM_PCI
+ tristate "PCI HiFi2 (Medfield, Merrifield) Platforms"
+ depends on X86 && PCI
+ select SND_SST_IPC_PCI
+ select SND_SOC_COMPRESS
+ help
+ If you have a Intel Medfield or Merrifield/Edison platform, then
+ enable this option by saying Y or m. Distros will typically not
+ enable this option: Medfield devices are not available to
+ developers and while Merrifield/Edison can run a mainline kernel with
+ limited functionality it will require a firmware file which
+ is not in the standard firmware tree
config SND_SST_ATOM_HIFI2_PLATFORM
- tristate "Intel ASoC SST driver for HiFi2 platforms (*field, *trail)"
- depends on SND_SOC_INTEL_SST_TOPLEVEL && X86
+ tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
+ depends on X86 && ACPI
+ select SND_SST_IPC_ACPI
select SND_SOC_COMPRESS
+ select SND_SOC_ACPI_INTEL_MATCH
+ select IOSF_MBI
+ help
+ If you have a Intel Baytrail or Cherrytrail platform with an I2S
+ codec, then enable this option by saying Y or m. This is a
+ recommended option
config SND_SOC_INTEL_SKYLAKE
- tristate "Intel ASoC SST driver for SKL/BXT/KBL/GLK/CNL"
- depends on SND_SOC_INTEL_SST_TOPLEVEL && PCI && ACPI
+ tristate "SKL/BXT/KBL/GLK/CNL... Platforms"
+ depends on PCI && ACPI
select SND_HDA_EXT_CORE
select SND_HDA_DSP_LOADER
select SND_SOC_TOPOLOGY
select SND_SOC_INTEL_SST
+ select SND_SOC_ACPI_INTEL_MATCH
+ help
+ If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/
+ GeminiLake or CannonLake platform with the DSP enabled in the BIOS
+ then enable this option by saying Y or m.
+
+config SND_SOC_ACPI_INTEL_MATCH
+ tristate
+ select SND_SOC_ACPI if ACPI
+ # this option controls the compilation of ACPI matching tables and
+ # helpers and is not meant to be selected by the user.
+
+endif ## SND_SOC_INTEL_SST_TOPLEVEL
# ASoC codec drivers
source "sound/soc/intel/boards/Kconfig"
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index b973d457e834..8160520fd74c 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# Core support
-obj-$(CONFIG_SND_SOC_INTEL_COMMON) += common/
+obj-$(CONFIG_SND_SOC) += common/
# Platform Support
obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index 32d6e02e2104..6cd481bec275 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -236,6 +236,9 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
/* Find the IRQ */
ctx->irq_num = platform_get_irq(pdev,
ctx->pdata->res_info->acpi_ipc_irq_index);
+ if (ctx->irq_num <= 0)
+ return ctx->irq_num < 0 ? ctx->irq_num : -EIO;
+
return 0;
}
diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
index 65e257b17a7e..7ee6aeb7e0af 100644
--- a/sound/soc/intel/atom/sst/sst_stream.c
+++ b/sound/soc/intel/atom/sst/sst_stream.c
@@ -220,10 +220,10 @@ int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx,
sst_free_block(sst_drv_ctx, block);
out:
test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id);
- return 0;
+ return ret;
}
-/*
+/**
* sst_pause_stream - Send msg for a pausing stream
* @str_id: stream ID
*
@@ -261,7 +261,7 @@ int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
}
} else {
retval = -EBADRQC;
- dev_dbg(sst_drv_ctx->dev, "SST DBG:BADRQC for stream\n ");
+ dev_dbg(sst_drv_ctx->dev, "SST DBG:BADRQC for stream\n");
}
return retval;
@@ -284,7 +284,7 @@ int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id)
if (!str_info)
return -EINVAL;
if (str_info->status == STREAM_RUNNING)
- return 0;
+ return 0;
if (str_info->status == STREAM_PAUSED) {
retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id,
IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD,
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index 6f754708a48c..d4e103615f51 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -1,183 +1,183 @@
-config SND_SOC_INTEL_MACH
- tristate "Intel Audio machine drivers"
+menuconfig SND_SOC_INTEL_MACH
+ bool "Intel Machine drivers"
depends on SND_SOC_INTEL_SST_TOPLEVEL
- select SND_SOC_ACPI_INTEL_MATCH if ACPI
+ help
+ Intel ASoC Machine Drivers. If you have a Intel machine that
+ has an audio controller with a DSP and I2S or DMIC port, then
+ enable this option by saying Y
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Intel ASoC machine drivers.
if SND_SOC_INTEL_MACH
-config SND_MFLD_MACHINE
- tristate "SOC Machine Audio driver for Intel Medfield MID platform"
- depends on INTEL_SCU_IPC
- select SND_SOC_SN95031
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_PCI
- help
- This adds support for ASoC machine driver for Intel(R) MID Medfield platform
- used as alsa device in audio substem in Intel(R) MID devices
- Say Y if you have such a device.
- If unsure select "N".
+if SND_SOC_INTEL_HASWELL
config SND_SOC_INTEL_HASWELL_MACH
- tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
+ tristate "Haswell Lynxpoint"
depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
- depends on SND_SOC_INTEL_HASWELL
select SND_SOC_RT5640
help
This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell
- Ultrabook platforms.
- Say Y if you have such a device.
+ Ultrabook platforms. This is a recommended option.
+ Say Y or m if you have such a device.
If unsure select "N".
config SND_SOC_INTEL_BDW_RT5677_MACH
- tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec"
- depends on X86_INTEL_LPSS && GPIOLIB && I2C
- depends on SND_SOC_INTEL_HASWELL
+ tristate "Broadwell with RT5677 codec"
+ depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM && GPIOLIB
select SND_SOC_RT5677
help
This adds support for Intel Broadwell platform based boards with
- the RT5677 audio codec.
+ the RT5677 audio codec. This is a recommended option.
+ Say Y or m if you have such a device.
+ If unsure select "N".
config SND_SOC_INTEL_BROADWELL_MACH
- tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
+ tristate "Broadwell Wildcatpoint"
depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
- depends on SND_SOC_INTEL_HASWELL
select SND_SOC_RT286
help
This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell
Ultrabook platforms.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
+endif ## SND_SOC_INTEL_HASWELL
+
+if SND_SOC_INTEL_BAYTRAIL
config SND_SOC_INTEL_BYT_MAX98090_MACH
- tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
+ tristate "Baytrail with MAX98090 codec"
depends on X86_INTEL_LPSS && I2C
- depends on SND_SST_IPC_ACPI = n
- depends on SND_SOC_INTEL_BAYTRAIL
select SND_SOC_MAX98090
help
This adds audio driver for Intel Baytrail platform based boards
- with the MAX98090 audio codec.
+ with the MAX98090 audio codec. This driver is deprecated, use
+ SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH instead for better
+ functionality.
config SND_SOC_INTEL_BYT_RT5640_MACH
- tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
+ tristate "Baytrail with RT5640 codec"
depends on X86_INTEL_LPSS && I2C
- depends on SND_SST_IPC_ACPI = n
- depends on SND_SOC_INTEL_BAYTRAIL
select SND_SOC_RT5640
help
This adds audio driver for Intel Baytrail platform based boards
with the RT5640 audio codec. This driver is deprecated, use
SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality.
+endif ## SND_SOC_INTEL_BAYTRAIL
+
+if SND_SST_ATOM_HIFI2_PLATFORM
+
config SND_SOC_INTEL_BYTCR_RT5640_MACH
- tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec"
- depends on X86 && I2C && ACPI
+ tristate "Baytrail and Baytrail-CR with RT5640 codec"
+ depends on X86_INTEL_LPSS && I2C && ACPI
+ select SND_SOC_ACPI
select SND_SOC_RT5640
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
- This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
- platforms with RT5640 audio codec.
- Say Y if you have such a device.
- If unsure select "N".
+ This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
+ platforms with RT5640 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_BYTCR_RT5651_MACH
- tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec"
- depends on X86 && I2C && ACPI
+ tristate "Baytrail and Baytrail-CR with RT5651 codec"
+ depends on X86_INTEL_LPSS && I2C && ACPI
+ select SND_SOC_ACPI
select SND_SOC_RT5651
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
- This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
- platforms with RT5651 audio codec.
- Say Y if you have such a device.
- If unsure select "N".
+ This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
+ platforms with RT5651 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_CHT_BSW_RT5672_MACH
- tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec"
+ tristate "Cherrytrail & Braswell with RT5672 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
- select SND_SOC_RT5670
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
+ select SND_SOC_ACPI
+ select SND_SOC_RT5670
help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with RT5672 audio codec.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
- tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
+ tristate "Cherrytrail & Braswell with RT5645/5650 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
+ select SND_SOC_ACPI
select SND_SOC_RT5645
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with RT5645/5650 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_CHT_BSW_MAX98090_TI_MACH
- tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec"
+ tristate "Cherrytrail & Braswell with MAX98090 & TI codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_MAX98090
select SND_SOC_TS3A227E
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
- tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
+ tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
+ select SND_SOC_ACPI
select SND_SOC_DA7213
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
platforms with DA7212/7213 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_ES8316_MACH
- tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec"
+ tristate "Baytrail & Cherrytrail with ES8316 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
+ select SND_SOC_ACPI
select SND_SOC_ES8316
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
This adds support for ASoC machine driver for Intel(R) Baytrail &
Cherrytrail platforms with ES8316 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_NOCODEC_MACH
- tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)"
+ tristate "Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)"
depends on X86_INTEL_LPSS && I2C && ACPI
- depends on SND_SST_ATOM_HIFI2_PLATFORM
- select SND_SST_IPC_ACPI
help
This adds support for ASoC machine driver for the MinnowBoard Max or
Up boards and provides access to I2S signals on the Low-Speed
- connector
+ connector. This is not a recommended option outside of these cases.
+ It is not intended to be enabled by distros by default.
+ Say Y or m if you have such a device.
+
If unsure select "N".
+endif ## SND_SST_ATOM_HIFI2_PLATFORM
+
+if SND_SOC_INTEL_SKYLAKE
+
config SND_SOC_INTEL_SKL_RT286_MACH
- tristate "ASoC Audio driver for SKL with RT286 I2S mode"
- depends on X86 && ACPI && I2C
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "SKL with RT286 I2S mode"
+ depends on MFD_INTEL_LPSS && I2C && ACPI
select SND_SOC_RT286
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC machine driver for Skylake platforms
with RT286 I2S audio codec.
- Say Y if you have such a device.
+ Say Y or m if you have such a device.
If unsure select "N".
config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
- tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode"
- depends on X86_INTEL_LPSS && I2C
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "SKL with NAU88L25 and SSM4567 in I2S Mode"
+ depends on MFD_INTEL_LPSS && I2C && ACPI
select SND_SOC_NAU8825
select SND_SOC_SSM4567
select SND_SOC_DMIC
@@ -185,13 +185,12 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for NAU88L25 + SSM4567.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
- tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode"
- depends on X86_INTEL_LPSS && I2C
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "SKL with NAU88L25 and MAX98357A in I2S Mode"
+ depends on MFD_INTEL_LPSS && I2C && ACPI
select SND_SOC_NAU8825
select SND_SOC_MAX98357A
select SND_SOC_DMIC
@@ -199,13 +198,12 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for NAU88L25 + MAX98357A.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
- tristate "ASoC Audio driver for Broxton with DA7219 and MAX98357A in I2S Mode"
- depends on X86 && ACPI && I2C
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "Broxton 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
@@ -214,13 +212,12 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
help
This adds support for ASoC machine driver for Broxton-P platforms
with DA7219 + MAX98357A I2S audio codec.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_BXT_RT298_MACH
- tristate "ASoC Audio driver for Broxton with RT298 I2S mode"
- depends on X86 && ACPI && I2C
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "Broxton with RT298 I2S mode"
+ depends on MFD_INTEL_LPSS && I2C && ACPI
select SND_SOC_RT298
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
@@ -228,14 +225,12 @@ config SND_SOC_INTEL_BXT_RT298_MACH
help
This adds support for ASoC machine driver for Broxton platforms
with RT286 I2S audio codec.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
- tristate "ASoC Audio driver for KBL with RT5663 and MAX98927 in I2S Mode"
- depends on X86_INTEL_LPSS && I2C
- select SND_SOC_INTEL_SST
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "KBL with RT5663 and MAX98927 in I2S Mode"
+ depends on MFD_INTEL_LPSS && I2C && ACPI
select SND_SOC_RT5663
select SND_SOC_MAX98927
select SND_SOC_DMIC
@@ -243,14 +238,13 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + MAX98927.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
- tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
- depends on X86_INTEL_LPSS && I2C && SPI
- select SND_SOC_INTEL_SST
- depends on SND_SOC_INTEL_SKYLAKE
+ tristate "KBL with RT5663, RT5514 and MAX98927 in I2S Mode"
+ depends on MFD_INTEL_LPSS && I2C && ACPI
+ depends on SPI
select SND_SOC_RT5663
select SND_SOC_RT5514
select SND_SOC_RT5514_SPI
@@ -259,7 +253,8 @@ config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + RT5514 + MAX98927.
- Say Y if you have such a device.
+ Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
+endif ## SND_SOC_INTEL_SKYLAKE
-endif
+endif ## SND_SOC_INTEL_MACH
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c
index c4d82ad41bd7..2179dedb28ad 100644
--- a/sound/soc/intel/boards/bytcht_da7213.c
+++ b/sound/soc/intel/boards/bytcht_da7213.c
@@ -219,7 +219,7 @@ static struct snd_soc_card bytcht_da7213_card = {
.num_dapm_routes = ARRAY_SIZE(audio_map),
};
-static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+static char codec_name[SND_ACPI_I2C_ID_LEN];
static int bytcht_da7213_probe(struct platform_device *pdev)
{
@@ -243,7 +243,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
}
/* fixup codec name based on HID */
- i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
if (i2c_name) {
snprintf(codec_name, sizeof(codec_name),
"%s%s", "i2c-", i2c_name);
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
index 8088396717e3..305e7f4fe55a 100644
--- a/sound/soc/intel/boards/bytcht_es8316.c
+++ b/sound/soc/intel/boards/bytcht_es8316.c
@@ -232,15 +232,39 @@ static struct snd_soc_card byt_cht_es8316_card = {
.fully_routed = true,
};
+static char codec_name[SND_ACPI_I2C_ID_LEN];
+
static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
{
- int ret = 0;
struct byt_cht_es8316_private *priv;
+ struct snd_soc_acpi_mach *mach;
+ const char *i2c_name = NULL;
+ int dai_index = 0;
+ int i;
+ int ret = 0;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
if (!priv)
return -ENOMEM;
+ mach = (&pdev->dev)->platform_data;
+ /* fix index of codec dai */
+ for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
+ if (!strcmp(byt_cht_es8316_dais[i].codec_name,
+ "i2c-ESSX8316:00")) {
+ dai_index = i;
+ break;
+ }
+ }
+
+ /* fixup codec name based on HID */
+ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
+ if (i2c_name) {
+ snprintf(codec_name, sizeof(codec_name),
+ "%s%s", "i2c-", i2c_name);
+ byt_cht_es8316_dais[dai_index].codec_name = codec_name;
+ }
+
/* register the soc card */
byt_cht_es8316_card.dev = &pdev->dev;
snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv);
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index f2c0fc415e52..b6a1cfeec830 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -713,7 +713,7 @@ static struct snd_soc_card byt_rt5640_card = {
.fully_routed = true,
};
-static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
@@ -762,7 +762,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
}
/* fixup codec name based on HID */
- i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
if (i2c_name) {
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
"%s%s", "i2c-", i2c_name);
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index d955836c6870..456526a93dd5 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -38,6 +38,8 @@ enum {
BYT_RT5651_DMIC_MAP,
BYT_RT5651_IN1_MAP,
BYT_RT5651_IN2_MAP,
+ BYT_RT5651_IN1_IN2_MAP,
+ BYT_RT5651_IN3_MAP,
};
#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(7, 0))
@@ -62,6 +64,8 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk IN1_MAP enabled");
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP)
dev_info(dev, "quirk IN2_MAP enabled");
+ if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN3_MAP)
+ dev_info(dev, "quirk IN3_MAP enabled");
if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
dev_info(dev, "quirk DMIC enabled");
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
@@ -127,6 +131,7 @@ static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = {
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Internal Mic", NULL),
SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_LINE("Line In", 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),
@@ -138,6 +143,7 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
{"Headset Mic", NULL, "Platform Clock"},
{"Internal Mic", NULL, "Platform Clock"},
{"Speaker", NULL, "Platform Clock"},
+ {"Line In", NULL, "Platform Clock"},
{"AIF1 Playback", NULL, "ssp2 Tx"},
{"ssp2 Tx", NULL, "codec_out0"},
@@ -151,6 +157,9 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
{"Headphone", NULL, "HPOR"},
{"Speaker", NULL, "LOUTL"},
{"Speaker", NULL, "LOUTR"},
+ {"IN2P", NULL, "Line In"},
+ {"IN2N", NULL, "Line In"},
+
};
static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
@@ -171,11 +180,25 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
{"IN2P", NULL, "Internal Mic"},
};
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map[] = {
+ {"Internal Mic", NULL, "micbias1"},
+ {"IN1P", NULL, "Internal Mic"},
+ {"IN2P", NULL, "Internal Mic"},
+ {"IN3P", NULL, "Headset Mic"},
+};
+
+static const struct snd_soc_dapm_route byt_rt5651_intmic_in3_map[] = {
+ {"Internal Mic", NULL, "micbias1"},
+ {"IN3P", NULL, "Headset Mic"},
+ {"IN1P", NULL, "Internal Mic"},
+};
+
static const struct snd_kcontrol_new byt_rt5651_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Internal Mic"),
SOC_DAPM_PIN_SWITCH("Speaker"),
+ SOC_DAPM_PIN_SWITCH("Line In"),
};
static struct snd_soc_jack_pin bytcr_jack_pins[] = {
@@ -247,8 +270,16 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
},
- .driver_data = (void *)(BYT_RT5651_DMIC_MAP |
- BYT_RT5651_DMIC_EN),
+ .driver_data = (void *)(BYT_RT5651_IN3_MAP),
+ },
+ {
+ .callback = byt_rt5651_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ADI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"),
+ },
+ .driver_data = (void *)(BYT_RT5651_MCLK_EN |
+ BYT_RT5651_IN3_MAP),
},
{
.callback = byt_rt5651_quirk_cb,
@@ -256,7 +287,8 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
},
- .driver_data = (void *)(BYT_RT5651_IN2_MAP),
+ .driver_data = (void *)(BYT_RT5651_MCLK_EN |
+ BYT_RT5651_IN1_IN2_MAP),
},
{}
};
@@ -281,6 +313,14 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
custom_map = byt_rt5651_intmic_in2_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map);
break;
+ case BYT_RT5651_IN1_IN2_MAP:
+ custom_map = byt_rt5651_intmic_in1_in2_map;
+ num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
+ break;
+ case BYT_RT5651_IN3_MAP:
+ custom_map = byt_rt5651_intmic_in3_map;
+ num_routes = ARRAY_SIZE(byt_rt5651_intmic_in3_map);
+ break;
default:
custom_map = byt_rt5651_intmic_dmic_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map);
@@ -469,7 +509,7 @@ static struct snd_soc_card byt_rt5651_card = {
.fully_routed = true,
};
-static char byt_rt5651_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
{
@@ -499,7 +539,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
}
/* fixup codec name based on HID */
- i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
if (i2c_name) {
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"%s%s", "i2c-", i2c_name);
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 18d129caa974..976ea6bf9539 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -49,7 +49,7 @@ struct cht_acpi_card {
struct cht_mc_private {
struct snd_soc_jack jack;
struct cht_acpi_card *acpi_card;
- char codec_name[16];
+ char codec_name[SND_ACPI_I2C_ID_LEN];
struct clk *mclk;
};
@@ -499,7 +499,7 @@ static struct cht_acpi_card snd_soc_cards[] = {
{"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},
};
-static char cht_rt5645_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
+static char cht_rt5645_codec_name[SND_ACPI_I2C_ID_LEN];
static char cht_rt5645_codec_aif_name[12]; /* = "rt5645-aif[1|2]" */
static char cht_rt5645_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
@@ -566,7 +566,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
}
/* fixup codec name based on HID */
- i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
if (i2c_name) {
snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
"%s%s", "i2c-", i2c_name);
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index f8f21eee9b2d..c14a52d2f714 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -35,7 +35,7 @@
struct cht_mc_private {
struct snd_soc_jack headset;
- char codec_name[16];
+ char codec_name[SND_ACPI_I2C_ID_LEN];
struct clk *mclk;
};
@@ -396,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
/* fixup codec name based on HID */
if (mach) {
- i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
+ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
if (i2c_name) {
snprintf(drv->codec_name, sizeof(drv->codec_name),
"i2c-%s", i2c_name);
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c
index 5e1ea0371c90..3c5160779204 100644
--- a/sound/soc/intel/boards/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -76,7 +76,7 @@ static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream,
}
/* set correct codec filter for DAI format and clock config */
- snd_soc_update_bits(rtd->codec, 0x83, 0xffff, 0x8000);
+ snd_soc_component_update_bits(codec_dai->component, 0x83, 0xffff, 0x8000);
return ret;
}
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index 6dcad0a8a0d0..bf7014ca486f 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -225,7 +225,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
}
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_0, KEY_PLAYPAUSE);
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);
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 271ae3c2c535..90ea98f01c4c 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -195,7 +195,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
}
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_0, KEY_PLAYPAUSE);
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);
diff --git a/sound/soc/intel/boards/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c
deleted file mode 100644
index 6f44acfb4aae..000000000000
--- a/sound/soc/intel/boards/mfld_machine.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * mfld_machine.c - ASoc Machine driver for Intel Medfield MID platform
- *
- * Copyright (C) 2010 Intel Corp
- * Author: Vinod Koul <vinod.koul@intel.com>
- * Author: Harsha Priya <priya.harsha@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-#include "../codecs/sn95031.h"
-
-#define MID_MONO 1
-#define MID_STEREO 2
-#define MID_MAX_CAP 5
-#define MFLD_JACK_INSERT 0x04
-
-enum soc_mic_bias_zones {
- MFLD_MV_START = 0,
- /* mic bias volutage range for Headphones*/
- MFLD_MV_HP = 400,
- /* mic bias volutage range for American Headset*/
- MFLD_MV_AM_HS = 650,
- /* mic bias volutage range for Headset*/
- MFLD_MV_HS = 2000,
- MFLD_MV_UNDEFINED,
-};
-
-static unsigned int hs_switch;
-static unsigned int lo_dac;
-static struct snd_soc_codec *mfld_codec;
-
-struct mfld_mc_private {
- void __iomem *int_base;
- u8 interrupt_status;
-};
-
-struct snd_soc_jack mfld_jack;
-
-/*Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin mfld_jack_pins[] = {
- {
- .pin = "Headphones",
- .mask = SND_JACK_HEADPHONE,
- },
- {
- .pin = "AMIC1",
- .mask = SND_JACK_MICROPHONE,
- },
-};
-
-/* jack detection voltage zones */
-static struct snd_soc_jack_zone mfld_zones[] = {
- {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE},
- {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET},
-};
-
-/* sound card controls */
-static const char * const headset_switch_text[] = {"Earpiece", "Headset"};
-
-static const char * const lo_text[] = {"Vibra", "Headset", "IHF", "None"};
-
-static const struct soc_enum headset_enum =
- SOC_ENUM_SINGLE_EXT(2, headset_switch_text);
-
-static const struct soc_enum lo_enum =
- SOC_ENUM_SINGLE_EXT(4, lo_text);
-
-static int headset_get_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.enumerated.item[0] = hs_switch;
- return 0;
-}
-
-static int headset_set_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_context *dapm = &card->dapm;
-
- if (ucontrol->value.enumerated.item[0] == hs_switch)
- return 0;
-
- snd_soc_dapm_mutex_lock(dapm);
-
- if (ucontrol->value.enumerated.item[0]) {
- pr_debug("hs_set HS path\n");
- snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
- snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
- } else {
- pr_debug("hs_set EP path\n");
- snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
- snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
- }
-
- snd_soc_dapm_sync_unlocked(dapm);
-
- snd_soc_dapm_mutex_unlock(dapm);
-
- hs_switch = ucontrol->value.enumerated.item[0];
-
- return 0;
-}
-
-static void lo_enable_out_pins(struct snd_soc_dapm_context *dapm)
-{
- snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL");
- snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR");
- snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL");
- snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTR");
- snd_soc_dapm_enable_pin_unlocked(dapm, "VIB1OUT");
- snd_soc_dapm_enable_pin_unlocked(dapm, "VIB2OUT");
- if (hs_switch) {
- snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones");
- snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
- } else {
- snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
- snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT");
- }
-}
-
-static int lo_get_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- ucontrol->value.enumerated.item[0] = lo_dac;
- return 0;
-}
-
-static int lo_set_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
- struct snd_soc_dapm_context *dapm = &card->dapm;
-
- if (ucontrol->value.enumerated.item[0] == lo_dac)
- return 0;
-
- snd_soc_dapm_mutex_lock(dapm);
-
- /* we dont want to work with last state of lineout so just enable all
- * pins and then disable pins not required
- */
- lo_enable_out_pins(dapm);
-
- switch (ucontrol->value.enumerated.item[0]) {
- case 0:
- pr_debug("set vibra path\n");
- snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT");
- snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT");
- snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0);
- break;
-
- case 1:
- pr_debug("set hs path\n");
- snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones");
- snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT");
- snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x22);
- break;
-
- case 2:
- pr_debug("set spkr path\n");
- snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL");
- snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR");
- snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x44);
- break;
-
- case 3:
- pr_debug("set null path\n");
- snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL");
- snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR");
- snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x66);
- break;
- }
-
- snd_soc_dapm_sync_unlocked(dapm);
-
- snd_soc_dapm_mutex_unlock(dapm);
-
- lo_dac = ucontrol->value.enumerated.item[0];
- return 0;
-}
-
-static const struct snd_kcontrol_new mfld_snd_controls[] = {
- SOC_ENUM_EXT("Playback Switch", headset_enum,
- headset_get_switch, headset_set_switch),
- SOC_ENUM_EXT("Lineout Mux", lo_enum,
- lo_get_switch, lo_set_switch),
-};
-
-static const struct snd_soc_dapm_widget mfld_widgets[] = {
- SND_SOC_DAPM_HP("Headphones", NULL),
- SND_SOC_DAPM_MIC("Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route mfld_map[] = {
- {"Headphones", NULL, "HPOUTR"},
- {"Headphones", NULL, "HPOUTL"},
- {"Mic", NULL, "AMIC1"},
-};
-
-static void mfld_jack_check(unsigned int intr_status)
-{
- struct mfld_jack_data jack_data;
-
- if (!mfld_codec)
- return;
-
- jack_data.mfld_jack = &mfld_jack;
- jack_data.intr_id = intr_status;
-
- sn95031_jack_detection(mfld_codec, &jack_data);
- /* TODO: add american headset detection post gpiolib support */
-}
-
-static int mfld_init(struct snd_soc_pcm_runtime *runtime)
-{
- struct snd_soc_dapm_context *dapm = &runtime->card->dapm;
- int ret_val;
-
- /* default is earpiece pin, userspace sets it explcitly */
- snd_soc_dapm_disable_pin(dapm, "Headphones");
- /* default is lineout NC, userspace sets it explcitly */
- snd_soc_dapm_disable_pin(dapm, "LINEOUTL");
- snd_soc_dapm_disable_pin(dapm, "LINEOUTR");
- lo_dac = 3;
- hs_switch = 0;
- /* we dont use linein in this so set to NC */
- snd_soc_dapm_disable_pin(dapm, "LINEINL");
- snd_soc_dapm_disable_pin(dapm, "LINEINR");
-
- /* Headset and button jack detection */
- ret_val = snd_soc_card_jack_new(runtime->card,
- "Intel(R) MID Audio Jack", SND_JACK_HEADSET |
- SND_JACK_BTN_0 | SND_JACK_BTN_1, &mfld_jack,
- mfld_jack_pins, ARRAY_SIZE(mfld_jack_pins));
- if (ret_val) {
- pr_err("jack creation failed\n");
- return ret_val;
- }
-
- ret_val = snd_soc_jack_add_zones(&mfld_jack,
- ARRAY_SIZE(mfld_zones), mfld_zones);
- if (ret_val) {
- pr_err("adding jack zones failed\n");
- return ret_val;
- }
-
- mfld_codec = runtime->codec;
-
- /* we want to check if anything is inserted at boot,
- * so send a fake event to codec and it will read adc
- * to find if anything is there or not */
- mfld_jack_check(MFLD_JACK_INSERT);
- return ret_val;
-}
-
-static struct snd_soc_dai_link mfld_msic_dailink[] = {
- {
- .name = "Medfield Headset",
- .stream_name = "Headset",
- .cpu_dai_name = "Headset-cpu-dai",
- .codec_dai_name = "SN95031 Headset",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = mfld_init,
- },
- {
- .name = "Medfield Speaker",
- .stream_name = "Speaker",
- .cpu_dai_name = "Speaker-cpu-dai",
- .codec_dai_name = "SN95031 Speaker",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
- {
- .name = "Medfield Vibra",
- .stream_name = "Vibra1",
- .cpu_dai_name = "Vibra1-cpu-dai",
- .codec_dai_name = "SN95031 Vibra1",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
- {
- .name = "Medfield Haptics",
- .stream_name = "Vibra2",
- .cpu_dai_name = "Vibra2-cpu-dai",
- .codec_dai_name = "SN95031 Vibra2",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
- {
- .name = "Medfield Compress",
- .stream_name = "Speaker",
- .cpu_dai_name = "Compress-cpu-dai",
- .codec_dai_name = "SN95031 Speaker",
- .codec_name = "sn95031",
- .platform_name = "sst-platform",
- .init = NULL,
- },
-};
-
-/* SoC card */
-static struct snd_soc_card snd_soc_card_mfld = {
- .name = "medfield_audio",
- .owner = THIS_MODULE,
- .dai_link = mfld_msic_dailink,
- .num_links = ARRAY_SIZE(mfld_msic_dailink),
-
- .controls = mfld_snd_controls,
- .num_controls = ARRAY_SIZE(mfld_snd_controls),
- .dapm_widgets = mfld_widgets,
- .num_dapm_widgets = ARRAY_SIZE(mfld_widgets),
- .dapm_routes = mfld_map,
- .num_dapm_routes = ARRAY_SIZE(mfld_map),
-};
-
-static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev)
-{
- struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev;
-
- memcpy_fromio(&mc_private->interrupt_status,
- ((void *)(mc_private->int_base)),
- sizeof(u8));
- return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t snd_mfld_jack_detection(int irq, void *data)
-{
- struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data;
-
- mfld_jack_check(mc_drv_ctx->interrupt_status);
-
- return IRQ_HANDLED;
-}
-
-static int snd_mfld_mc_probe(struct platform_device *pdev)
-{
- int ret_val = 0, irq;
- struct mfld_mc_private *mc_drv_ctx;
- struct resource *irq_mem;
-
- pr_debug("snd_mfld_mc_probe called\n");
-
- /* retrive the irq number */
- irq = platform_get_irq(pdev, 0);
-
- /* audio interrupt base of SRAM location where
- * interrupts are stored by System FW */
- mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC);
- if (!mc_drv_ctx)
- return -ENOMEM;
-
- irq_mem = platform_get_resource_byname(
- pdev, IORESOURCE_MEM, "IRQ_BASE");
- if (!irq_mem) {
- pr_err("no mem resource given\n");
- return -ENODEV;
- }
- mc_drv_ctx->int_base = devm_ioremap_nocache(&pdev->dev, irq_mem->start,
- resource_size(irq_mem));
- if (!mc_drv_ctx->int_base) {
- pr_err("Mapping of cache failed\n");
- return -ENOMEM;
- }
- /* register for interrupt */
- ret_val = devm_request_threaded_irq(&pdev->dev, irq,
- snd_mfld_jack_intr_handler,
- snd_mfld_jack_detection,
- IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx);
- if (ret_val) {
- pr_err("cannot register IRQ\n");
- return ret_val;
- }
- /* register the soc card */
- snd_soc_card_mfld.dev = &pdev->dev;
- ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_mfld);
- if (ret_val) {
- pr_debug("snd_soc_register_card failed %d\n", ret_val);
- return ret_val;
- }
- platform_set_drvdata(pdev, mc_drv_ctx);
- pr_debug("successfully exited probe\n");
- return 0;
-}
-
-static struct platform_driver snd_mfld_mc_driver = {
- .driver = {
- .name = "msic_audio",
- },
- .probe = snd_mfld_mc_probe,
-};
-
-module_platform_driver(snd_mfld_mc_driver);
-
-MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver");
-MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
-MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:msic-audio");
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index 11c0805393ff..fd82f4b1d4a0 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -269,7 +269,7 @@ int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
*/
timeout = jiffies + msecs_to_jiffies(time);
- while (((sst_dsp_shim_read_unlocked(ctx, offset) & mask) != target)
+ while ((((reg = sst_dsp_shim_read_unlocked(ctx, offset)) & mask) != target)
&& time_before(jiffies, timeout)) {
k++;
if (k > 10)
@@ -278,8 +278,6 @@ int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
usleep_range(s, 2*s);
}
- reg = sst_dsp_shim_read_unlocked(ctx, offset);
-
if ((reg & mask) == target) {
dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n",
reg, operation);
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
index 4524211960e4..440bca7afbf1 100644
--- a/sound/soc/intel/skylake/bxt-sst.c
+++ b/sound/soc/intel/skylake/bxt-sst.c
@@ -595,7 +595,7 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3);
skl->d0i3.state = SKL_DSP_D0I3_NONE;
- return 0;
+ return skl_dsp_acquire_irq(sst);
}
EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c
index 387de388ce29..245df1067ba8 100644
--- a/sound/soc/intel/skylake/cnl-sst.c
+++ b/sound/soc/intel/skylake/cnl-sst.c
@@ -458,7 +458,7 @@ int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
cnl->boot_complete = false;
init_waitqueue_head(&cnl->boot_wait);
- return 0;
+ return skl_dsp_acquire_irq(sst);
}
EXPORT_SYMBOL_GPL(cnl_sst_dsp_init);
diff --git a/sound/soc/intel/skylake/skl-i2s.h b/sound/soc/intel/skylake/skl-i2s.h
new file mode 100644
index 000000000000..dcf819bc688f
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-i2s.h
@@ -0,0 +1,64 @@
+/*
+ * skl-i2s.h - i2s blob mapping
+ *
+ * Copyright (C) 2017 Intel Corp
+ * Author: Subhransu S. Prusty < subhransu.s.prusty@intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+#ifndef __SOUND_SOC_SKL_I2S_H
+#define __SOUND_SOC_SKL_I2S_H
+
+#define SKL_I2S_MAX_TIME_SLOTS 8
+#define SKL_MCLK_DIV_CLK_SRC_MASK GENMASK(17, 16)
+
+#define SKL_MNDSS_DIV_CLK_SRC_MASK GENMASK(21, 20)
+#define SKL_SHIFT(x) (ffs(x) - 1)
+#define SKL_MCLK_DIV_RATIO_MASK GENMASK(11, 0)
+
+struct skl_i2s_config {
+ u32 ssc0;
+ u32 ssc1;
+ u32 sscto;
+ u32 sspsp;
+ u32 sstsa;
+ u32 ssrsa;
+ u32 ssc2;
+ u32 sspsp2;
+ u32 ssc3;
+ u32 ssioc;
+} __packed;
+
+struct skl_i2s_config_mclk {
+ u32 mdivctrl;
+ u32 mdivr;
+};
+
+/**
+ * struct skl_i2s_config_blob_legacy - Structure defines I2S Gateway
+ * configuration legacy blob
+ *
+ * @gtw_attr: Gateway attribute for the I2S Gateway
+ * @tdm_ts_group: TDM slot mapping against channels in the Gateway.
+ * @i2s_cfg: I2S HW registers
+ * @mclk: MCLK clock source and divider values
+ */
+struct skl_i2s_config_blob_legacy {
+ u32 gtw_attr;
+ u32 tdm_ts_group[SKL_I2S_MAX_TIME_SLOTS];
+ struct skl_i2s_config i2s_cfg;
+ struct skl_i2s_config_mclk mclk;
+};
+
+#endif /* __SOUND_SOC_SKL_I2S_H */
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 61b5bfa79d13..8cbf080c38b3 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -55,6 +55,19 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
return 0;
}
+#define SKL_ASTATE_PARAM_ID 4
+
+void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data)
+{
+ struct skl_ipc_large_config_msg msg = {0};
+
+ msg.large_param_id = SKL_ASTATE_PARAM_ID;
+ msg.param_data_size = (cnt * sizeof(struct skl_astate_param) +
+ sizeof(cnt));
+
+ skl_ipc_set_large_config(&ctx->ipc, &msg, data);
+}
+
#define NOTIFICATION_PARAM_ID 3
#define NOTIFICATION_MASK 0xf
@@ -404,11 +417,20 @@ int skl_resume_dsp(struct skl *skl)
if (skl->skl_sst->is_first_boot == true)
return 0;
+ /* disable dynamic clock gating during fw and lib download */
+ ctx->enable_miscbdcge(ctx->dev, false);
+
ret = skl_dsp_wake(ctx->dsp);
+ ctx->enable_miscbdcge(ctx->dev, true);
if (ret < 0)
return ret;
skl_dsp_enable_notification(skl->skl_sst, false);
+
+ if (skl->cfg.astate_cfg != NULL) {
+ skl_dsp_set_astate_cfg(skl->skl_sst, skl->cfg.astate_cfg->count,
+ skl->cfg.astate_cfg);
+ }
return ret;
}
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 26b0a5caea5a..3b1d2b828c1b 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -19,6 +19,7 @@
*/
#include <linux/pci.h>
#include "skl.h"
+#include "skl-i2s.h"
#define NHLT_ACPI_HEADER_SIG "NHLT"
@@ -277,3 +278,157 @@ void skl_nhlt_remove_sysfs(struct skl *skl)
sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr);
}
+
+/*
+ * Queries NHLT for all the fmt configuration for a particular endpoint and
+ * stores all possible rates supported in a rate table for the corresponding
+ * sclk/sclkfs.
+ */
+static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
+ struct nhlt_fmt *fmt, u8 id)
+{
+ struct skl_i2s_config_blob_legacy *i2s_config;
+ struct skl_clk_parent_src *parent;
+ struct skl_ssp_clk *sclk, *sclkfs;
+ struct nhlt_fmt_cfg *fmt_cfg;
+ struct wav_fmt_ext *wav_fmt;
+ unsigned long rate = 0;
+ bool present = false;
+ int rate_index = 0;
+ u16 channels, bps;
+ u8 clk_src;
+ int i, j;
+ u32 fs;
+
+ sclk = &ssp_clks[SKL_SCLK_OFS];
+ sclkfs = &ssp_clks[SKL_SCLKFS_OFS];
+
+ if (fmt->fmt_count == 0)
+ return;
+
+ for (i = 0; i < fmt->fmt_count; i++) {
+ fmt_cfg = &fmt->fmt_config[i];
+ wav_fmt = &fmt_cfg->fmt_ext;
+
+ channels = wav_fmt->fmt.channels;
+ bps = wav_fmt->fmt.bits_per_sample;
+ fs = wav_fmt->fmt.samples_per_sec;
+
+ /*
+ * In case of TDM configuration on a ssp, there can
+ * be more than one blob in which channel masks are
+ * different for each usecase for a specific rate and bps.
+ * But the sclk rate will be generated for the total
+ * number of channels used for that endpoint.
+ *
+ * So for the given fs and bps, choose blob which has
+ * the superset of all channels for that endpoint and
+ * derive the rate.
+ */
+ for (j = i; j < fmt->fmt_count; j++) {
+ fmt_cfg = &fmt->fmt_config[j];
+ wav_fmt = &fmt_cfg->fmt_ext;
+ if ((fs == wav_fmt->fmt.samples_per_sec) &&
+ (bps == wav_fmt->fmt.bits_per_sample))
+ channels = max_t(u16, channels,
+ wav_fmt->fmt.channels);
+ }
+
+ rate = channels * bps * fs;
+
+ /* check if the rate is added already to the given SSP's sclk */
+ for (j = 0; (j < SKL_MAX_CLK_RATES) &&
+ (sclk[id].rate_cfg[j].rate != 0); j++) {
+ if (sclk[id].rate_cfg[j].rate == rate) {
+ present = true;
+ break;
+ }
+ }
+
+ /* Fill rate and parent for sclk/sclkfs */
+ if (!present) {
+ /* MCLK Divider Source Select */
+ i2s_config = (struct skl_i2s_config_blob_legacy *)
+ fmt->fmt_config[0].config.caps;
+ clk_src = ((i2s_config->mclk.mdivctrl)
+ & SKL_MNDSS_DIV_CLK_SRC_MASK) >>
+ SKL_SHIFT(SKL_MNDSS_DIV_CLK_SRC_MASK);
+
+ parent = skl_get_parent_clk(clk_src);
+
+ /*
+ * Do not copy the config data if there is no parent
+ * clock available for this clock source select
+ */
+ if (!parent)
+ continue;
+
+ sclk[id].rate_cfg[rate_index].rate = rate;
+ sclk[id].rate_cfg[rate_index].config = fmt_cfg;
+ sclkfs[id].rate_cfg[rate_index].rate = rate;
+ sclkfs[id].rate_cfg[rate_index].config = fmt_cfg;
+ sclk[id].parent_name = parent->name;
+ sclkfs[id].parent_name = parent->name;
+
+ rate_index++;
+ }
+ }
+}
+
+static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
+ struct nhlt_fmt *fmt, u8 id)
+{
+ struct skl_i2s_config_blob_legacy *i2s_config;
+ struct nhlt_specific_cfg *fmt_cfg;
+ struct skl_clk_parent_src *parent;
+ u32 clkdiv, div_ratio;
+ u8 clk_src;
+
+ fmt_cfg = &fmt->fmt_config[0].config;
+ i2s_config = (struct skl_i2s_config_blob_legacy *)fmt_cfg->caps;
+
+ /* MCLK Divider Source Select */
+ clk_src = ((i2s_config->mclk.mdivctrl) & SKL_MCLK_DIV_CLK_SRC_MASK) >>
+ SKL_SHIFT(SKL_MCLK_DIV_CLK_SRC_MASK);
+
+ clkdiv = i2s_config->mclk.mdivr & SKL_MCLK_DIV_RATIO_MASK;
+
+ /* bypass divider */
+ div_ratio = 1;
+
+ if (clkdiv != SKL_MCLK_DIV_RATIO_MASK)
+ /* Divider is 2 + clkdiv */
+ div_ratio = clkdiv + 2;
+
+ /* Calculate MCLK rate from source using div value */
+ parent = skl_get_parent_clk(clk_src);
+ if (!parent)
+ return;
+
+ mclk[id].rate_cfg[0].rate = parent->rate/div_ratio;
+ mclk[id].rate_cfg[0].config = &fmt->fmt_config[0];
+ mclk[id].parent_name = parent->name;
+}
+
+void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks)
+{
+ struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
+ struct nhlt_endpoint *epnt;
+ struct nhlt_fmt *fmt;
+ int i;
+ u8 id;
+
+ epnt = (struct nhlt_endpoint *)nhlt->desc;
+ for (i = 0; i < nhlt->endpoint_count; i++) {
+ if (epnt->linktype == NHLT_LINK_SSP) {
+ id = epnt->virtual_bus_id;
+
+ fmt = (struct nhlt_fmt *)(epnt->config.caps
+ + epnt->config.size);
+
+ skl_get_ssp_clks(skl, ssp_clks, fmt, id);
+ skl_get_mclk(skl, ssp_clks, fmt, id);
+ }
+ epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
+ }
+}
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 1dd97479e0c0..e46828533826 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -537,7 +537,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
- link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name);
+ link = snd_hdac_ext_bus_get_link(ebus, codec_dai->component->name);
if (!link)
return -EINVAL;
@@ -620,7 +620,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
link_dev->link_prepared = 0;
- link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name);
+ link = snd_hdac_ext_bus_get_link(ebus, rtd->codec_dai->component->name);
if (!link)
return -EINVAL;
@@ -1343,7 +1343,11 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
return -EIO;
}
+ /* disable dynamic clock gating during fw and lib download */
+ skl->skl_sst->enable_miscbdcge(platform->dev, false);
+
ret = ops->init_fw(platform->dev, skl->skl_sst);
+ skl->skl_sst->enable_miscbdcge(platform->dev, true);
if (ret < 0) {
dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
return ret;
@@ -1351,6 +1355,12 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform)
skl_populate_modules(skl);
skl->skl_sst->update_d0i3c = skl_update_d0i3c;
skl_dsp_enable_notification(skl->skl_sst, false);
+
+ if (skl->cfg.astate_cfg != NULL) {
+ skl_dsp_set_astate_cfg(skl->skl_sst,
+ skl->cfg.astate_cfg->count,
+ skl->cfg.astate_cfg);
+ }
}
pm_runtime_mark_last_busy(platform->dev);
pm_runtime_put_autosuspend(platform->dev);
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.h b/sound/soc/intel/skylake/skl-ssp-clk.h
new file mode 100644
index 000000000000..c9ea84004260
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-ssp-clk.h
@@ -0,0 +1,79 @@
+/*
+ * skl-ssp-clk.h - Skylake ssp clock information and ipc structure
+ *
+ * Copyright (C) 2017 Intel Corp
+ * Author: Jaikrishna Nemallapudi <jaikrishnax.nemallapudi@intel.com>
+ * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+#ifndef SOUND_SOC_SKL_SSP_CLK_H
+#define SOUND_SOC_SKL_SSP_CLK_H
+
+#define SKL_MAX_SSP 6
+/* xtal/cardinal/pll, parent of ssp clocks and mclk */
+#define SKL_MAX_CLK_SRC 3
+#define SKL_MAX_SSP_CLK_TYPES 3 /* mclk, sclk, sclkfs */
+
+#define SKL_MAX_CLK_CNT (SKL_MAX_SSP * SKL_MAX_SSP_CLK_TYPES)
+
+/* Max number of configurations supported for each clock */
+#define SKL_MAX_CLK_RATES 10
+
+#define SKL_SCLK_OFS SKL_MAX_SSP
+#define SKL_SCLKFS_OFS (SKL_SCLK_OFS + SKL_MAX_SSP)
+
+enum skl_clk_type {
+ SKL_MCLK,
+ SKL_SCLK,
+ SKL_SCLK_FS,
+};
+
+enum skl_clk_src_type {
+ SKL_XTAL,
+ SKL_CARDINAL,
+ SKL_PLL,
+};
+
+struct skl_clk_parent_src {
+ u8 clk_id;
+ const char *name;
+ unsigned long rate;
+ const char *parent_name;
+};
+
+struct skl_clk_rate_cfg_table {
+ unsigned long rate;
+ void *config;
+};
+
+/*
+ * rate for mclk will be in rates[0]. For sclk and sclkfs, rates[] store
+ * all possible clocks ssp can generate for that platform.
+ */
+struct skl_ssp_clk {
+ const char *name;
+ const char *parent_name;
+ struct skl_clk_rate_cfg_table rate_cfg[SKL_MAX_CLK_RATES];
+};
+
+struct skl_clk_pdata {
+ struct skl_clk_parent_src *parent_clks;
+ int num_clks;
+ struct skl_ssp_clk *ssp_clks;
+ void *pvt_data;
+};
+
+#endif /* SOUND_SOC_SKL_SSP_CLK_H */
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index 19ee1d4f3bdf..71e31ad0bb3f 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -435,16 +435,22 @@ struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
return NULL;
}
+ return sst;
+}
+
+int skl_dsp_acquire_irq(struct sst_dsp *sst)
+{
+ struct sst_dsp_device *sst_dev = sst->sst_dev;
+ int ret;
+
/* Register the ISR */
ret = request_threaded_irq(sst->irq, sst->ops->irq_handler,
sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
- if (ret) {
+ if (ret)
dev_err(sst->dev, "unable to grab threaded IRQ %d, disabling device\n",
sst->irq);
- return NULL;
- }
- return sst;
+ return ret;
}
void skl_dsp_free(struct sst_dsp *dsp)
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
index eba20d37ba8c..12fc9a73dc8a 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
@@ -206,6 +206,7 @@ int skl_cldma_wait_interruptible(struct sst_dsp *ctx);
void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
struct sst_dsp_device *sst_dev, int irq);
+int skl_dsp_acquire_irq(struct sst_dsp *sst);
bool is_skl_dsp_running(struct sst_dsp *ctx);
unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx);
@@ -251,6 +252,9 @@ void skl_freeup_uuid_list(struct skl_sst *ctx);
int skl_dsp_strip_extended_manifest(struct firmware *fw);
void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable);
+
+void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data);
+
int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp,
struct sst_dsp_device *skl_dev);
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index 8ff89280d9fd..2ae405617876 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -178,7 +178,8 @@ static inline int skl_pvtid_128(struct uuid_module *module)
* skl_get_pvt_id: generate a private id for use as module id
*
* @ctx: driver context
- * @mconfig: module configuration data
+ * @uuid_mod: module's uuid
+ * @instance_id: module's instance id
*
* This generates a 128 bit private unique id for a module TYPE so that
* module instance is unique
@@ -208,7 +209,8 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id);
* skl_put_pvt_id: free up the private id allocated
*
* @ctx: driver context
- * @mconfig: module configuration data
+ * @uuid_mod: module's uuid
+ * @pvt_id: module pvt id
*
* This frees a 128 bit private unique id previously generated
*/
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index a436abf2fe3f..5a7e41b65ef3 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -569,7 +569,7 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
sst->fw_ops = skl_fw_ops;
- return 0;
+ return skl_dsp_acquire_irq(sst);
}
EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index 81923da18ac2..73af6e19ebbd 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -190,7 +190,6 @@ skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig)
u8 res_idx = mconfig->res_idx;
struct skl_module_res *res = &mconfig->module->resources[res_idx];
- res = &mconfig->module->resources[res_idx];
skl->resource.mcps -= res->cps;
}
@@ -3056,11 +3055,13 @@ static int skl_tplg_get_int_tkn(struct device *dev,
struct snd_soc_tplg_vendor_value_elem *tkn_elem,
struct skl *skl)
{
- int tkn_count = 0, ret;
+ int tkn_count = 0, ret, size;
static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx;
struct skl_module_res *res = NULL;
struct skl_module_iface *fmt = NULL;
struct skl_module *mod = NULL;
+ static struct skl_astate_param *astate_table;
+ static int astate_cfg_idx, count;
int i;
if (skl->modules) {
@@ -3093,6 +3094,46 @@ static int skl_tplg_get_int_tkn(struct device *dev,
mod_idx = tkn_elem->value;
break;
+ case SKL_TKN_U32_ASTATE_COUNT:
+ if (astate_table != NULL) {
+ dev_err(dev, "More than one entry for A-State count");
+ return -EINVAL;
+ }
+
+ if (tkn_elem->value > SKL_MAX_ASTATE_CFG) {
+ dev_err(dev, "Invalid A-State count %d\n",
+ tkn_elem->value);
+ return -EINVAL;
+ }
+
+ size = tkn_elem->value * sizeof(struct skl_astate_param) +
+ sizeof(count);
+ skl->cfg.astate_cfg = devm_kzalloc(dev, size, GFP_KERNEL);
+ if (!skl->cfg.astate_cfg)
+ return -ENOMEM;
+
+ astate_table = skl->cfg.astate_cfg->astate_table;
+ count = skl->cfg.astate_cfg->count = tkn_elem->value;
+ break;
+
+ case SKL_TKN_U32_ASTATE_IDX:
+ if (tkn_elem->value >= count) {
+ dev_err(dev, "Invalid A-State index %d\n",
+ tkn_elem->value);
+ return -EINVAL;
+ }
+
+ astate_cfg_idx = tkn_elem->value;
+ break;
+
+ case SKL_TKN_U32_ASTATE_KCPS:
+ astate_table[astate_cfg_idx].kcps = tkn_elem->value;
+ break;
+
+ case SKL_TKN_U32_ASTATE_CLK_SRC:
+ astate_table[astate_cfg_idx].clk_src = tkn_elem->value;
+ break;
+
case SKL_TKN_U8_IN_PIN_TYPE:
case SKL_TKN_U8_OUT_PIN_TYPE:
case SKL_TKN_U8_IN_QUEUE_COUNT:
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 31d8634e8aa1..32ce64c6b2dc 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -355,6 +355,7 @@ static int skl_resume(struct device *dev)
if (ebus->cmd_dma_state)
snd_hdac_bus_init_cmd_io(&ebus->bus);
+ ret = 0;
} else {
ret = _skl_resume(ebus);
@@ -435,19 +436,51 @@ static int skl_free(struct hdac_ext_bus *ebus)
return 0;
}
-static int skl_machine_device_register(struct skl *skl, void *driver_data)
+/*
+ * For each ssp there are 3 clocks (mclk/sclk/sclkfs).
+ * e.g. for ssp0, clocks will be named as
+ * "ssp0_mclk", "ssp0_sclk", "ssp0_sclkfs"
+ * So for skl+, there are 6 ssps, so 18 clocks will be created.
+ */
+static struct skl_ssp_clk skl_ssp_clks[] = {
+ {.name = "ssp0_mclk"}, {.name = "ssp1_mclk"}, {.name = "ssp2_mclk"},
+ {.name = "ssp3_mclk"}, {.name = "ssp4_mclk"}, {.name = "ssp5_mclk"},
+ {.name = "ssp0_sclk"}, {.name = "ssp1_sclk"}, {.name = "ssp2_sclk"},
+ {.name = "ssp3_sclk"}, {.name = "ssp4_sclk"}, {.name = "ssp5_sclk"},
+ {.name = "ssp0_sclkfs"}, {.name = "ssp1_sclkfs"},
+ {.name = "ssp2_sclkfs"},
+ {.name = "ssp3_sclkfs"}, {.name = "ssp4_sclkfs"},
+ {.name = "ssp5_sclkfs"},
+};
+
+static int skl_find_machine(struct skl *skl, void *driver_data)
{
- struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
- struct platform_device *pdev;
struct snd_soc_acpi_mach *mach = driver_data;
- int ret;
+ struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
+ struct skl_machine_pdata *pdata;
mach = snd_soc_acpi_find_machine(mach);
if (mach == NULL) {
dev_err(bus->dev, "No matching machine driver found\n");
return -ENODEV;
}
+
+ skl->mach = mach;
skl->fw_name = mach->fw_filename;
+ pdata = skl->mach->pdata;
+
+ if (mach->pdata)
+ skl->use_tplg_pcm = pdata->use_tplg_pcm;
+
+ return 0;
+}
+
+static int skl_machine_device_register(struct skl *skl)
+{
+ struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
+ struct snd_soc_acpi_mach *mach = skl->mach;
+ struct platform_device *pdev;
+ int ret;
pdev = platform_device_alloc(mach->drv_name, -1);
if (pdev == NULL) {
@@ -462,11 +495,8 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data)
return -EIO;
}
- if (mach->pdata) {
- skl->use_tplg_pcm =
- ((struct skl_machine_pdata *)mach->pdata)->use_tplg_pcm;
+ if (mach->pdata)
dev_set_drvdata(&pdev->dev, mach->pdata);
- }
skl->i2s_dev = pdev;
@@ -509,6 +539,74 @@ static void skl_dmic_device_unregister(struct skl *skl)
platform_device_unregister(skl->dmic_dev);
}
+static struct skl_clk_parent_src skl_clk_src[] = {
+ { .clk_id = SKL_XTAL, .name = "xtal" },
+ { .clk_id = SKL_CARDINAL, .name = "cardinal", .rate = 24576000 },
+ { .clk_id = SKL_PLL, .name = "pll", .rate = 96000000 },
+};
+
+struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(skl_clk_src); i++) {
+ if (skl_clk_src[i].clk_id == clk_id)
+ return &skl_clk_src[i];
+ }
+
+ return NULL;
+}
+
+static void init_skl_xtal_rate(int pci_id)
+{
+ switch (pci_id) {
+ case 0x9d70:
+ case 0x9d71:
+ skl_clk_src[0].rate = 24000000;
+ return;
+
+ default:
+ skl_clk_src[0].rate = 19200000;
+ return;
+ }
+}
+
+static int skl_clock_device_register(struct skl *skl)
+{
+ struct platform_device_info pdevinfo = {NULL};
+ struct skl_clk_pdata *clk_pdata;
+
+ clk_pdata = devm_kzalloc(&skl->pci->dev, sizeof(*clk_pdata),
+ GFP_KERNEL);
+ if (!clk_pdata)
+ return -ENOMEM;
+
+ init_skl_xtal_rate(skl->pci->device);
+
+ clk_pdata->parent_clks = skl_clk_src;
+ clk_pdata->ssp_clks = skl_ssp_clks;
+ clk_pdata->num_clks = ARRAY_SIZE(skl_ssp_clks);
+
+ /* Query NHLT to fill the rates and parent */
+ skl_get_clks(skl, clk_pdata->ssp_clks);
+ clk_pdata->pvt_data = skl;
+
+ /* Register Platform device */
+ pdevinfo.parent = &skl->pci->dev;
+ pdevinfo.id = -1;
+ pdevinfo.name = "skl-ssp-clk";
+ pdevinfo.data = clk_pdata;
+ pdevinfo.size_data = sizeof(*clk_pdata);
+ skl->clk_dev = platform_device_register_full(&pdevinfo);
+ return PTR_ERR_OR_ZERO(skl->clk_dev);
+}
+
+static void skl_clock_device_unregister(struct skl *skl)
+{
+ if (skl->clk_dev)
+ platform_device_unregister(skl->clk_dev);
+}
+
/*
* Probe the given codec address
*/
@@ -615,18 +713,30 @@ static void skl_probe_work(struct work_struct *work)
/* create codec instances */
skl_codec_create(ebus);
+ /* register platform dai and controls */
+ err = skl_platform_register(bus->dev);
+ if (err < 0) {
+ dev_err(bus->dev, "platform register failed: %d\n", err);
+ return;
+ }
+
+ if (bus->ppcap) {
+ err = skl_machine_device_register(skl);
+ if (err < 0) {
+ dev_err(bus->dev, "machine register failed: %d\n", err);
+ goto out_err;
+ }
+ }
+
if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
err = snd_hdac_display_power(bus, false);
if (err < 0) {
dev_err(bus->dev, "Cannot turn off display power on i915\n");
+ skl_machine_device_unregister(skl);
return;
}
}
- /* register platform dai and controls */
- err = skl_platform_register(bus->dev);
- if (err < 0)
- return;
/*
* we are done probing so decrement link counts
*/
@@ -791,18 +901,21 @@ static int skl_probe(struct pci_dev *pci,
/* check if dsp is there */
if (bus->ppcap) {
- err = skl_machine_device_register(skl,
- (void *)pci_id->driver_data);
+ /* create device for dsp clk */
+ err = skl_clock_device_register(skl);
+ if (err < 0)
+ goto out_clk_free;
+
+ err = skl_find_machine(skl, (void *)pci_id->driver_data);
if (err < 0)
goto out_nhlt_free;
err = skl_init_dsp(skl);
if (err < 0) {
dev_dbg(bus->dev, "error failed to register dsp\n");
- goto out_mach_free;
+ goto out_nhlt_free;
}
skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
-
}
if (bus->mlcap)
snd_hdac_ext_bus_get_ml_capabilities(ebus);
@@ -820,8 +933,8 @@ static int skl_probe(struct pci_dev *pci,
out_dsp_free:
skl_free_dsp(skl);
-out_mach_free:
- skl_machine_device_unregister(skl);
+out_clk_free:
+ skl_clock_device_unregister(skl);
out_nhlt_free:
skl_nhlt_free(skl->nhlt);
out_free:
@@ -872,6 +985,7 @@ static void skl_remove(struct pci_dev *pci)
skl_free_dsp(skl);
skl_machine_device_unregister(skl);
skl_dmic_device_unregister(skl);
+ skl_clock_device_unregister(skl);
skl_nhlt_remove_sysfs(skl);
skl_nhlt_free(skl->nhlt);
skl_free(ebus);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index e00cde8200dd..f411579bc713 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -25,9 +25,12 @@
#include <sound/hdaudio_ext.h>
#include <sound/soc.h>
#include "skl-nhlt.h"
+#include "skl-ssp-clk.h"
#define SKL_SUSPEND_DELAY 2000
+#define SKL_MAX_ASTATE_CFG 3
+
#define AZX_PCIREG_PGCTL 0x44
#define AZX_PGCTL_LSRMD_MASK (1 << 4)
#define AZX_PCIREG_CGCTL 0x48
@@ -45,6 +48,20 @@ struct skl_dsp_resource {
struct skl_debug;
+struct skl_astate_param {
+ u32 kcps;
+ u32 clk_src;
+};
+
+struct skl_astate_config {
+ u32 count;
+ struct skl_astate_param astate_table[0];
+};
+
+struct skl_fw_config {
+ struct skl_astate_config *astate_cfg;
+};
+
struct skl {
struct hdac_ext_bus ebus;
struct pci_dev *pci;
@@ -52,6 +69,7 @@ struct skl {
unsigned int init_done:1; /* delayed init status */
struct platform_device *dmic_dev;
struct platform_device *i2s_dev;
+ struct platform_device *clk_dev;
struct snd_soc_platform *platform;
struct snd_soc_dai_driver *dais;
@@ -75,6 +93,8 @@ struct skl {
u8 nr_modules;
struct skl_module **modules;
bool use_tplg_pcm;
+ struct skl_fw_config cfg;
+ struct snd_soc_acpi_mach *mach;
};
#define skl_to_ebus(s) (&(s)->ebus)
@@ -125,6 +145,8 @@ const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
void skl_update_d0i3c(struct device *dev, bool enable);
int skl_nhlt_create_sysfs(struct skl *skl);
void skl_nhlt_remove_sysfs(struct skl *skl);
+void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks);
+struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id);
struct skl_module_cfg;
diff --git a/sound/soc/soc-acpi.c b/sound/soc/soc-acpi.c
index d4dd2efea45e..3d7e1ff79139 100644
--- a/sound/soc/soc-acpi.c
+++ b/sound/soc/soc-acpi.c
@@ -16,74 +16,13 @@
#include <sound/soc-acpi.h>
-static acpi_status snd_soc_acpi_find_name(acpi_handle handle, u32 level,
- void *context, void **ret)
-{
- struct acpi_device *adev;
- const char *name = NULL;
-
- if (acpi_bus_get_device(handle, &adev))
- return AE_OK;
-
- if (adev->status.present && adev->status.functional) {
- name = acpi_dev_name(adev);
- *(const char **)ret = name;
- return AE_CTRL_TERMINATE;
- }
-
- return AE_OK;
-}
-
-const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
-{
- const char *name = NULL;
- acpi_status status;
-
- status = acpi_get_devices(hid, snd_soc_acpi_find_name, NULL,
- (void **)&name);
-
- if (ACPI_FAILURE(status) || name[0] == '\0')
- return NULL;
-
- return name;
-}
-EXPORT_SYMBOL_GPL(snd_soc_acpi_find_name_from_hid);
-
-static acpi_status snd_soc_acpi_mach_match(acpi_handle handle, u32 level,
- void *context, void **ret)
-{
- unsigned long long sta;
- acpi_status status;
-
- *(bool *)context = true;
- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
- if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
- *(bool *)context = false;
-
- return AE_OK;
-}
-
-bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN])
-{
- acpi_status status;
- bool found = false;
-
- status = acpi_get_devices(hid, snd_soc_acpi_mach_match, &found, NULL);
-
- if (ACPI_FAILURE(status))
- return false;
-
- return found;
-}
-EXPORT_SYMBOL_GPL(snd_soc_acpi_check_hid);
-
struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
{
struct snd_soc_acpi_mach *mach;
for (mach = machines; mach->id[0]; mach++) {
- if (snd_soc_acpi_check_hid(mach->id) == true) {
+ if (acpi_dev_present(mach->id, NULL, -1)) {
if (mach->machine_quirk)
mach = mach->machine_quirk(mach);
return mach;
@@ -161,7 +100,7 @@ struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
return mach;
for (i = 0; i < codec_list->num_codecs; i++) {
- if (snd_soc_acpi_check_hid(codec_list->codecs[i]) != true)
+ if (!acpi_dev_present(codec_list->codecs[i], NULL, -1))
return NULL;
}