Commit c44ff31a authored by Mark Brown's avatar Mark Brown

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

parents bd26974f 1c0a7de2
/*
* Copyright (C) 2017, Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* 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 __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
#define __LINUX_SND_SOC_ACPI_INTEL_MATCH_H
#include <linux/stddef.h>
#include <linux/acpi.h>
/*
* these tables are not constants, some fields can be used for
* pdata or machine ops
*/
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[];
#endif
...@@ -12,10 +12,13 @@ ...@@ -12,10 +12,13 @@
* *
*/ */
#ifndef __LINUX_SND_SOC_ACPI_H
#define __LINUX_SND_SOC_ACPI_H
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/acpi.h> #include <linux/acpi.h>
struct sst_acpi_package_context { struct snd_soc_acpi_package_context {
char *name; /* package name */ char *name; /* package name */
int length; /* number of elements */ int length; /* number of elements */
struct acpi_buffer *format; struct acpi_buffer *format;
...@@ -25,58 +28,84 @@ struct sst_acpi_package_context { ...@@ -25,58 +28,84 @@ struct sst_acpi_package_context {
#if IS_ENABLED(CONFIG_ACPI) #if IS_ENABLED(CONFIG_ACPI)
/* translation fron HID to I2C name, needed for DAI codec_name */ /* translation fron HID to I2C name, needed for DAI codec_name */
const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]); const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct sst_acpi_package_context *ctx); struct snd_soc_acpi_package_context *ctx);
#else #else
static inline const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) static inline const char *
snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
{ {
return NULL; return NULL;
} }
static inline bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], static inline bool
struct sst_acpi_package_context *ctx) snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct snd_soc_acpi_package_context *ctx)
{ {
return false; return false;
} }
#endif #endif
/* acpi match */ /* acpi match */
struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines); struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines);
/* acpi check hid */ /* acpi check hid */
bool sst_acpi_check_hid(const u8 hid[ACPI_ID_LEN]); bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN]);
/**
* snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
* related to the hardware, except for the firmware and topology file names.
* A platform supported by legacy and Sound Open Firmware (SOF) would expose
* all firmware/topology related fields.
*
* @id: ACPI ID (usually the codec's) used to find a matching machine driver.
* @drv_name: machine driver name
* @fw_filename: firmware file name. Used when SOF is not enabled.
* @board: board name
* @machine_quirk: pointer to quirk, usually based on DMI information when
* ACPI ID alone is not sufficient, wrong or misleading
* @quirk_data: data used to uniquely identify a machine, usually a list of
* audio codecs whose presence if checked with ACPI
* @pdata: intended for platform data or machine specific-ops. This structure
* is not constant since this field may be updated at run-time
* @sof_fw_filename: Sound Open Firmware file name, if enabled
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
* @asoc_plat_name: ASoC platform name, used for binding machine drivers
* if non NULL
* @new_mach_data: machine driver private data fixup
*/
/* Descriptor for SST ASoC machine driver */ /* Descriptor for SST ASoC machine driver */
struct sst_acpi_mach { struct snd_soc_acpi_mach {
/* ACPI ID for the matching machine driver. Audio codec for instance */
const u8 id[ACPI_ID_LEN]; const u8 id[ACPI_ID_LEN];
/* machine driver name */
const char *drv_name; const char *drv_name;
/* firmware file name */
const char *fw_filename; const char *fw_filename;
/* board name */
const char *board; const char *board;
struct sst_acpi_mach * (*machine_quirk)(void *arg); struct snd_soc_acpi_mach * (*machine_quirk)(void *arg);
const void *quirk_data; const void *quirk_data;
void *pdata; void *pdata;
const char *sof_fw_filename;
const char *sof_tplg_filename;
const char *asoc_plat_name;
struct platform_device * (*new_mach_data)(void *pdata);
}; };
#define SST_ACPI_MAX_CODECS 3 #define SND_SOC_ACPI_MAX_CODECS 3
/** /**
* struct sst_codecs: Structure to hold secondary codec information apart from * struct snd_soc_acpi_codecs: Structure to hold secondary codec information
* the matched one, this data will be passed to the quirk function to match * apart from the matched one, this data will be passed to the quirk function
* with the ACPI detected devices * to match with the ACPI detected devices
* *
* @num_codecs: number of secondary codecs used in the platform * @num_codecs: number of secondary codecs used in the platform
* @codecs: holds the codec IDs * @codecs: holds the codec IDs
* *
*/ */
struct sst_codecs { struct snd_soc_acpi_codecs {
int num_codecs; int num_codecs;
u8 codecs[SST_ACPI_MAX_CODECS][ACPI_ID_LEN]; u8 codecs[SND_SOC_ACPI_MAX_CODECS][ACPI_ID_LEN];
}; };
/* check all codecs */ /* check all codecs */
struct sst_acpi_mach *sst_acpi_codec_list(void *arg); struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg);
#endif
...@@ -1821,6 +1821,20 @@ struct snd_soc_dai *snd_soc_find_dai( ...@@ -1821,6 +1821,20 @@ struct snd_soc_dai *snd_soc_find_dai(
#include <sound/soc-dai.h> #include <sound/soc-dai.h>
static inline
struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
const char *dai_name)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strcmp(rtd->codec_dai->name, dai_name))
return rtd->codec_dai;
}
return NULL;
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
extern struct dentry *snd_soc_debugfs_root; extern struct dentry *snd_soc_debugfs_root;
#endif #endif
......
...@@ -36,6 +36,9 @@ config SND_SOC_COMPRESS ...@@ -36,6 +36,9 @@ config SND_SOC_COMPRESS
config SND_SOC_TOPOLOGY config SND_SOC_TOPOLOGY
bool bool
config SND_SOC_ACPI
tristate
# All the supported SoCs # All the supported SoCs
source "sound/soc/adi/Kconfig" source "sound/soc/adi/Kconfig"
source "sound/soc/amd/Kconfig" source "sound/soc/amd/Kconfig"
......
...@@ -15,6 +15,12 @@ ifneq ($(CONFIG_SND_SOC_AC97_BUS),) ...@@ -15,6 +15,12 @@ ifneq ($(CONFIG_SND_SOC_AC97_BUS),)
snd-soc-core-objs += soc-ac97.o snd-soc-core-objs += soc-ac97.o
endif endif
ifneq ($(CONFIG_SND_SOC_ACPI),)
snd-soc-acpi-objs := soc-acpi.o
endif
obj-$(CONFIG_SND_SOC_ACPI) += snd-soc-acpi.o
obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o
obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += codecs/
obj-$(CONFIG_SND_SOC) += generic/ obj-$(CONFIG_SND_SOC) += generic/
......
...@@ -942,7 +942,8 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev, ...@@ -942,7 +942,8 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
if (!se) if (!se)
return -ENOMEM; return -ENOMEM;
sprintf(kc_name, "Pin %d port %d Input", pin->nid, port->id); 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->hdac.dev, kc_name, GFP_KERNEL);
if (!kc->name) if (!kc->name)
return -ENOMEM; return -ENOMEM;
...@@ -1452,6 +1453,8 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev, ...@@ -1452,6 +1453,8 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
int i, num_nodes; int i, num_nodes;
struct hdac_device *hdac = &edev->hdac; struct hdac_device *hdac = &edev->hdac;
struct hdac_hdmi_priv *hdmi = edev->private_data; struct hdac_hdmi_priv *hdmi = edev->private_data;
struct hdac_hdmi_cvt *temp_cvt, *cvt_next;
struct hdac_hdmi_pin *temp_pin, *pin_next;
int ret; int ret;
hdac_hdmi_skl_enable_all_pins(hdac); hdac_hdmi_skl_enable_all_pins(hdac);
...@@ -1481,32 +1484,54 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev, ...@@ -1481,32 +1484,54 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
case AC_WID_AUD_OUT: case AC_WID_AUD_OUT:
ret = hdac_hdmi_add_cvt(edev, nid); ret = hdac_hdmi_add_cvt(edev, nid);
if (ret < 0) if (ret < 0)
return ret; goto free_widgets;
break; break;
case AC_WID_PIN: case AC_WID_PIN:
ret = hdac_hdmi_add_pin(edev, nid); ret = hdac_hdmi_add_pin(edev, nid);
if (ret < 0) if (ret < 0)
return ret; goto free_widgets;
break; break;
} }
} }
hdac->end_nid = nid; hdac->end_nid = nid;
if (!hdmi->num_pin || !hdmi->num_cvt) if (!hdmi->num_pin || !hdmi->num_cvt) {
return -EIO; ret = -EIO;
goto free_widgets;
}
ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt); ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
if (ret) { if (ret) {
dev_err(&hdac->dev, "Failed to create dais with err: %d\n", dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
ret); ret);
return ret; goto free_widgets;
} }
*num_dais = hdmi->num_cvt; *num_dais = hdmi->num_cvt;
ret = hdac_hdmi_init_dai_map(edev);
if (ret < 0)
goto free_widgets;
return ret;
free_widgets:
list_for_each_entry_safe(temp_cvt, cvt_next, &hdmi->cvt_list, head) {
list_del(&temp_cvt->head);
kfree(temp_cvt->name);
kfree(temp_cvt);
}
list_for_each_entry_safe(temp_pin, pin_next, &hdmi->pin_list, head) {
for (i = 0; i < temp_pin->num_ports; i++)
temp_pin->ports[i].pin = NULL;
kfree(temp_pin->ports);
list_del(&temp_pin->head);
kfree(temp_pin);
}
return hdac_hdmi_init_dai_map(edev); return ret;
} }
static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
...@@ -1894,6 +1919,9 @@ static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx, ...@@ -1894,6 +1919,9 @@ static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
struct hdac_hdmi_port *port; struct hdac_hdmi_port *port;
if (!pcm)
return;
if (list_empty(&pcm->port_list)) if (list_empty(&pcm->port_list))
return; return;
...@@ -1912,6 +1940,9 @@ static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx) ...@@ -1912,6 +1940,9 @@ static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
struct hdac_hdmi_priv *hdmi = edev->private_data; struct hdac_hdmi_priv *hdmi = edev->private_data;
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
if (!pcm)
return false;
if (list_empty(&pcm->port_list)) if (list_empty(&pcm->port_list))
return false; return false;
...@@ -1925,6 +1956,9 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx) ...@@ -1925,6 +1956,9 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
struct hdac_hdmi_port *port; struct hdac_hdmi_port *port;
if (!pcm)
return 0;
if (list_empty(&pcm->port_list)) if (list_empty(&pcm->port_list))
return 0; return 0;
...@@ -1978,6 +2012,9 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) ...@@ -1978,6 +2012,9 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc; hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;
if (!hdac_id)
return -ENODEV;
if (hdac_id->driver_data) if (hdac_id->driver_data)
hdmi_priv->drv_data = hdmi_priv->drv_data =
(struct hdac_hdmi_drv_data *)hdac_id->driver_data; (struct hdac_hdmi_drv_data *)hdac_id->driver_data;
......
config SND_MFLD_MACHINE
tristate "SOC Machine Audio driver for Intel Medfield MID platform"
depends on INTEL_SCU_IPC
select SND_SOC_SN95031
select 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".
config SND_SST_ATOM_HIFI2_PLATFORM
tristate
select SND_SOC_COMPRESS
config SND_SST_IPC config SND_SST_IPC
tristate tristate
...@@ -27,10 +11,12 @@ config SND_SST_IPC_ACPI ...@@ -27,10 +11,12 @@ config SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST
select IOSF_MBI select IOSF_MBI
config SND_SOC_INTEL_COMMON
tristate
config SND_SOC_INTEL_SST config SND_SOC_INTEL_SST
tristate tristate
select SND_SOC_INTEL_SST_ACPI if ACPI select SND_SOC_INTEL_SST_ACPI if ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
config SND_SOC_INTEL_SST_FIRMWARE config SND_SOC_INTEL_SST_FIRMWARE
tristate tristate
...@@ -39,280 +25,42 @@ config SND_SOC_INTEL_SST_FIRMWARE ...@@ -39,280 +25,42 @@ config SND_SOC_INTEL_SST_FIRMWARE
config SND_SOC_INTEL_SST_ACPI config SND_SOC_INTEL_SST_ACPI
tristate tristate
config SND_SOC_INTEL_SST_MATCH config SND_SOC_ACPI_INTEL_MATCH
tristate 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
config SND_SOC_INTEL_HASWELL config SND_SOC_INTEL_HASWELL
tristate tristate "Intel ASoC SST driver for Haswell/Broadwell"
depends on SND_SOC_INTEL_SST_TOPLEVEL && SND_DMA_SGBUF
depends on DMADEVICES
select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SST_FIRMWARE select SND_SOC_INTEL_SST_FIRMWARE
config SND_SOC_INTEL_BAYTRAIL config SND_SOC_INTEL_BAYTRAIL
tristate tristate "Intel ASoC SST driver for Baytrail (legacy)"
select SND_SOC_INTEL_SST depends on SND_SOC_INTEL_SST_TOPLEVEL
select SND_SOC_INTEL_SST_FIRMWARE
config SND_SOC_INTEL_HASWELL_MACH
tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
depends on DMADEVICES
select 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.
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
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_DA7219
select SND_SOC_MAX98357A
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
select SND_HDA_DSP_LOADER
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.
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
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_RT298
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
select SND_HDA_DSP_LOADER
help
This adds support for ASoC machine driver for Broxton platforms
with RT286 I2S audio codec.
Say Y if you have such a device.
If unsure select "N".
config SND_SOC_INTEL_BYT_RT5640_MACH
tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
depends on X86_INTEL_LPSS && I2C
depends on DMADEVICES depends on DMADEVICES
depends on SND_SST_IPC_ACPI = n
select 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.
config SND_SOC_INTEL_BYT_MAX98090_MACH
tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
depends on X86_INTEL_LPSS && I2C
depends on DMADEVICES
depends on SND_SST_IPC_ACPI = n
select SND_SOC_INTEL_BAYTRAIL
select SND_SOC_MAX98090
help
This adds audio driver for Intel Baytrail platform based boards
with the MAX98090 audio codec.
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 DMADEVICES
select SND_SOC_INTEL_HASWELL
select SND_SOC_RT5677
help
This adds support for Intel Broadwell platform based boards with
the RT5677 audio codec.
config SND_SOC_INTEL_BROADWELL_MACH
tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM
depends on DMADEVICES
select 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.
If unsure select "N".
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
select SND_SOC_RT5640
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if 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".
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
select SND_SOC_RT5651
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if 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".
config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_RT5670
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
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.
If unsure select "N".
config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_RT5645
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with RT5645/5650 audio codec.
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"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_MAX98090
select SND_SOC_TS3A227E
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if 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.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_DA7213
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help
This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail
platforms with DA7212/7213 audio codec.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_ES8316_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SOC_ES8316
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help
This adds support for ASoC machine driver for Intel(R) Baytrail &
Cherrytrail platforms with ES8316 audio codec.
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)"
depends on X86_INTEL_LPSS && I2C && ACPI
select SND_SST_ATOM_HIFI2_PLATFORM
select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if 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
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 select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SKYLAKE select SND_SOC_INTEL_SST_FIRMWARE
select SND_SOC_RT5663
select SND_SOC_MAX98927
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + MAX98927.
Say Y if you have such a device.
If unsure select "N".
config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH config SND_SST_ATOM_HIFI2_PLATFORM
tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode" tristate "Intel ASoC SST driver for HiFi2 platforms (*field, *trail)"
depends on X86_INTEL_LPSS && I2C && SPI depends on SND_SOC_INTEL_SST_TOPLEVEL && X86
select SND_SOC_INTEL_SST select SND_SOC_COMPRESS
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_RT5663
select SND_SOC_RT5514
select SND_SOC_RT5514_SPI
select SND_SOC_MAX98927
select SND_SOC_HDAC_HDMI
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.
If unsure select "N".
config SND_SOC_INTEL_SKYLAKE config SND_SOC_INTEL_SKYLAKE
tristate tristate "Intel ASoC SST driver for SKL/BXT/KBL/GLK/CNL"
depends on SND_SOC_INTEL_SST_TOPLEVEL && PCI && ACPI
select SND_HDA_EXT_CORE select SND_HDA_EXT_CORE
select SND_HDA_DSP_LOADER select SND_HDA_DSP_LOADER
select SND_SOC_TOPOLOGY select SND_SOC_TOPOLOGY
select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST
config SND_SOC_INTEL_SKL_RT286_MACH # ASoC codec drivers
tristate "ASoC Audio driver for SKL with RT286 I2S mode" source "sound/soc/intel/boards/Kconfig"
depends on X86 && ACPI && I2C
select SND_SOC_INTEL_SKYLAKE
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.
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
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_NAU8825
select SND_SOC_SSM4567
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for NAU88L25 + SSM4567.
Say Y if you have such a device.
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
select SND_SOC_INTEL_SKYLAKE
select SND_SOC_NAU8825
select SND_SOC_MAX98357A
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for NAU88L25 + MAX98357A.
Say Y if you have such a device.
If unsure select "N".
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# Core support # Core support
obj-$(CONFIG_SND_SOC_INTEL_SST) += common/ obj-$(CONFIG_SND_SOC_INTEL_COMMON) += common/
# Platform Support # Platform Support
obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/ obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/
......
...@@ -259,7 +259,7 @@ static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, ...@@ -259,7 +259,7 @@ static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream,
return stream->compr_ops->set_metadata(sst->dev, stream->id, metadata); return stream->compr_ops->set_metadata(sst->dev, stream->id, metadata);
} }
struct snd_compr_ops sst_platform_compr_ops = { const struct snd_compr_ops sst_platform_compr_ops = {
.open = sst_platform_compr_open, .open = sst_platform_compr_open,
.free = sst_platform_compr_free, .free = sst_platform_compr_free,
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "sst-atom-controls.h" #include "sst-atom-controls.h"
extern struct sst_device *sst; extern struct sst_device *sst;
extern struct snd_compr_ops sst_platform_compr_ops; extern const struct snd_compr_ops sst_platform_compr_ops;
#define SST_MONO 1 #define SST_MONO 1
#define SST_STEREO 2 #define SST_STEREO 2
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -41,9 +40,10 @@ ...@@ -41,9 +40,10 @@
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/iosf_mbi.h> #include <asm/iosf_mbi.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#include "../sst-mfld-platform.h" #include "../sst-mfld-platform.h"
#include "../../common/sst-dsp.h" #include "../../common/sst-dsp.h"
#include "../../common/sst-acpi.h"
#include "sst.h" #include "sst.h"
/* LPE viewpoint addresses */ /* LPE viewpoint addresses */
...@@ -239,19 +239,26 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) ...@@ -239,19 +239,26 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
return 0; return 0;
} }
static int is_byt(void)
{
bool status = false;
static const struct x86_cpu_id cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
{}
};
if (x86_match_cpu(cpu_ids))
status = true;
return status;
}
static int is_byt_cr(struct device *dev, bool *bytcr) static int is_byt_cr(struct device *dev, bool *bytcr)
{ {
int status = 0; int status = 0;
if (IS_ENABLED(CONFIG_IOSF_MBI)) { if (IS_ENABLED(CONFIG_IOSF_MBI)) {
static const struct x86_cpu_id cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
{}
};
u32 bios_status; u32 bios_status;
if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) { if (!is_byt() || !iosf_mbi_available()) {
/* bail silently */ /* bail silently */
return status; return status;
} }
...@@ -285,7 +292,7 @@ static int sst_acpi_probe(struct platform_device *pdev) ...@@ -285,7 +292,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
int ret = 0; int ret = 0;
struct intel_sst_drv *ctx; struct intel_sst_drv *ctx;
const struct acpi_device_id *id; const struct acpi_device_id *id;
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
struct platform_device *mdev; struct platform_device *mdev;
struct platform_device *plat_dev; struct platform_device *plat_dev;
struct sst_platform_info *pdata; struct sst_platform_info *pdata;
...@@ -297,13 +304,17 @@ static int sst_acpi_probe(struct platform_device *pdev) ...@@ -297,13 +304,17 @@ static int sst_acpi_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
dev_dbg(dev, "for %s\n", id->id); dev_dbg(dev, "for %s\n", id->id);
mach = (struct sst_acpi_mach *)id->driver_data; mach = (struct snd_soc_acpi_mach *)id->driver_data;
mach = sst_acpi_find_machine(mach); mach = snd_soc_acpi_find_machine(mach);
if (mach == NULL) { if (mach == NULL) {
dev_err(dev, "No matching machine driver found\n"); dev_err(dev, "No matching machine driver found\n");
return -ENODEV; return -ENODEV;
} }
if (is_byt())
mach->pdata = &byt_rvp_platform_data;
else
mach->pdata = &chv_platform_data;
pdata = mach->pdata; pdata = mach->pdata;
ret = kstrtouint(id->id, 16, &dev_id); ret = kstrtouint(id->id, 16, &dev_id);
...@@ -381,286 +392,9 @@ static int sst_acpi_remove(struct platform_device *pdev) ...@@ -381,286 +392,9 @@ static int sst_acpi_remove(struct platform_device *pdev)
return 0; return 0;
} }
static unsigned long cht_machine_id;
#define CHT_SURFACE_MACH 1
#define BYT_THINKPAD_10 2
static int cht_surface_quirk_cb(const struct dmi_system_id *id)
{
cht_machine_id = CHT_SURFACE_MACH;
return 1;
}
static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id)
{
cht_machine_id = BYT_THINKPAD_10;
return 1;
}
static const struct dmi_system_id byt_table[] = {
{
.callback = byt_thinkpad10_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
},
},
{
.callback = byt_thinkpad10_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
},
},
{
.callback = byt_thinkpad10_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
},
},
{ }
};
static const struct dmi_system_id cht_table[] = {
{
.callback = cht_surface_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
},
},
{ }
};
static struct sst_acpi_mach cht_surface_mach = {
.id = "10EC5640",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data,
};
static struct sst_acpi_mach byt_thinkpad_10 = {
.id = "10EC5640",
.drv_name = "cht-bsw-rt5672",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.pdata = &byt_rvp_platform_data,
};
static struct sst_acpi_mach *cht_quirk(void *arg)
{
struct sst_acpi_mach *mach = arg;
dmi_check_system(cht_table);
if (cht_machine_id == CHT_SURFACE_MACH)
return &cht_surface_mach;
else
return mach;
}
static struct sst_acpi_mach *byt_quirk(void *arg)
{
struct sst_acpi_mach *mach = arg;
dmi_check_system(byt_table);
if (cht_machine_id == BYT_THINKPAD_10)
return &byt_thinkpad_10;
else
return mach;
}
static struct sst_acpi_mach sst_acpi_bytcr[] = {
{
.id = "10EC5640",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5640",
.machine_quirk = byt_quirk,
.pdata = &byt_rvp_platform_data,
},
{
.id = "10EC5642",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5640",
.pdata = &byt_rvp_platform_data
},
{
.id = "INTCCFFD",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5640",
.pdata = &byt_rvp_platform_data
},
{
.id = "10EC5651",
.drv_name = "bytcr_rt5651",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5651",
.pdata = &byt_rvp_platform_data
},
{
.id = "DLGS7212",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcht_da7213",
.pdata = &byt_rvp_platform_data
},
{
.id = "DLGS7213",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcht_da7213",
.pdata = &byt_rvp_platform_data
},
/* some Baytrail platforms rely on RT5645, use CHT machine driver */
{
.id = "10EC5645",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.pdata = &byt_rvp_platform_data
},
{
.id = "10EC5648",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.pdata = &byt_rvp_platform_data
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
.id = "80860F28",
.drv_name = "bytcht_nocodec",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcht_nocodec",
.pdata = &byt_rvp_platform_data
},
#endif
{},
};
/* Cherryview-based platforms: CherryTrail and Braswell */
static struct sst_acpi_mach sst_acpi_chv[] = {
{
.id = "10EC5670",
.drv_name = "cht-bsw-rt5672",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data
},
{
.id = "10EC5672",
.drv_name = "cht-bsw-rt5672",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data
},
{
.id = "10EC5645",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data
},
{
.id = "10EC5650",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data
},
{
.id = "10EC3270",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data
},
{
.id = "193C9890",
.drv_name = "cht-bsw-max98090",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.pdata = &chv_platform_data
},
{
.id = "DLGS7212",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_da7213",
.pdata = &chv_platform_data
},
{
.id = "DLGS7213",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_da7213",
.pdata = &chv_platform_data
},
{
.id = "ESSX8316",
.drv_name = "bytcht_es8316",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_es8316",
.pdata = &chv_platform_data
},
/* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
{
.id = "10EC5640",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcr_rt5640",
.machine_quirk = cht_quirk,
.pdata = &chv_platform_data
},
{
.id = "10EC3276",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcr_rt5640",
.pdata = &chv_platform_data
},
/* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
{
.id = "10EC5651",
.drv_name = "bytcr_rt5651",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcr_rt5651",
.pdata = &chv_platform_data
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
.id = "808622A8",
.drv_name = "bytcht_nocodec",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_nocodec",
.pdata = &chv_platform_data
},
#endif
{},
};
static const struct acpi_device_id sst_acpi_ids[] = { static const struct acpi_device_id sst_acpi_ids[] = {
{ "80860F28", (unsigned long)&sst_acpi_bytcr}, { "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
{ "808622A8", (unsigned long) &sst_acpi_chv}, { "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
{ }, { },
}; };
......
...@@ -415,7 +415,6 @@ int sst_load_fw(struct intel_sst_drv *sst_drv_ctx) ...@@ -415,7 +415,6 @@ int sst_load_fw(struct intel_sst_drv *sst_drv_ctx)
return ret_val; return ret_val;
} }
BUG_ON(!sst_drv_ctx->fw_in_mem);
block = sst_create_block(sst_drv_ctx, 0, FW_DWNL_ID); block = sst_create_block(sst_drv_ctx, 0, FW_DWNL_ID);
if (block == NULL) if (block == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -45,7 +45,6 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params) ...@@ -45,7 +45,6 @@ int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
void *data = NULL; void *data = NULL;
dev_dbg(sst_drv_ctx->dev, "Enter\n"); dev_dbg(sst_drv_ctx->dev, "Enter\n");
BUG_ON(!params);
str_params = (struct snd_sst_params *)params; str_params = (struct snd_sst_params *)params;
memset(&alloc_param, 0, sizeof(alloc_param)); memset(&alloc_param, 0, sizeof(alloc_param));
......
config SND_SOC_INTEL_MACH
tristate "Intel Audio machine drivers"
depends on SND_SOC_INTEL_SST_TOPLEVEL
select SND_SOC_ACPI_INTEL_MATCH if ACPI
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".
config SND_SOC_INTEL_HASWELL_MACH
tristate "ASoC Audio DSP support for Intel 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.
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
select SND_SOC_RT5677
help
This adds support for Intel Broadwell platform based boards with
the RT5677 audio codec.
config SND_SOC_INTEL_BROADWELL_MACH
tristate "ASoC Audio DSP support for Intel 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.
If unsure select "N".
config SND_SOC_INTEL_BYT_MAX98090_MACH
tristate "ASoC Audio driver for Intel 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.
config SND_SOC_INTEL_BYT_RT5640_MACH
tristate "ASoC Audio driver for Intel 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.
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
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".
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
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".
config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
tristate "ASoC Audio driver for Intel 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
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.
If unsure select "N".
config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec"
depends on X86_INTEL_LPSS && I2C && 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.
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"
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.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec"
depends on X86_INTEL_LPSS && I2C && 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.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_ES8316_MACH
tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec"
depends on X86_INTEL_LPSS && I2C && 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.
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)"
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
If unsure select "N".
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
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.
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
select SND_SOC_NAU8825
select SND_SOC_SSM4567
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for NAU88L25 + SSM4567.
Say Y if you have such a device.
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
select SND_SOC_NAU8825
select SND_SOC_MAX98357A
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for NAU88L25 + MAX98357A.
Say Y if you have such a device.
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
select SND_SOC_DA7219
select SND_SOC_MAX98357A
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
select SND_HDA_DSP_LOADER
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.
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
select SND_SOC_RT298
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
select SND_HDA_DSP_LOADER
help
This adds support for ASoC machine driver for Broxton platforms
with RT286 I2S audio codec.
Say Y if you have such a device.
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
select SND_SOC_RT5663
select SND_SOC_MAX98927
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + MAX98927.
Say Y if you have such a device.
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
select SND_SOC_RT5663
select SND_SOC_RT5514
select SND_SOC_RT5514_SPI
select SND_SOC_MAX98927
select SND_SOC_HDAC_HDMI
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.
If unsure select "N".
endif
...@@ -55,20 +55,6 @@ enum { ...@@ -55,20 +55,6 @@ enum {
BXT_DPCM_AUDIO_HDMI3_PB, BXT_DPCM_AUDIO_HDMI3_PB,
}; };
static inline struct snd_soc_dai *bxt_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, BXT_DIALOG_CODEC_DAI,
strlen(BXT_DIALOG_CODEC_DAI)))
return rtd->codec_dai;
}
return NULL;
}
static int platform_clock_control(struct snd_soc_dapm_widget *w, static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event) struct snd_kcontrol *k, int event)
{ {
...@@ -77,7 +63,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -77,7 +63,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_soc_card *card = dapm->card; struct snd_soc_card *card = dapm->card;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
codec_dai = bxt_get_codec_dai(card); codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI);
if (!codec_dai) { if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n");
return -EIO; return -EIO;
......
...@@ -27,9 +27,9 @@ ...@@ -27,9 +27,9 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../../codecs/da7213.h" #include "../../codecs/da7213.h"
#include "../atom/sst-atom-controls.h" #include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
static const struct snd_kcontrol_new controls[] = { static const struct snd_kcontrol_new controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headphone Jack"),
...@@ -185,19 +185,11 @@ static struct snd_soc_dai_link dailink[] = { ...@@ -185,19 +185,11 @@ static struct snd_soc_dai_link dailink[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &aif1_ops, .ops = &aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* CODEC<->CODEC link */ /* CODEC<->CODEC link */
/* back ends */ /* back ends */
{ {
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
...@@ -231,19 +223,18 @@ static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ ...@@ -231,19 +223,18 @@ static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
static int bytcht_da7213_probe(struct platform_device *pdev) static int bytcht_da7213_probe(struct platform_device *pdev)
{ {
int ret_val = 0;
int i;
struct snd_soc_card *card; struct snd_soc_card *card;
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
const char *i2c_name = NULL; const char *i2c_name = NULL;
int dai_index = 0; int dai_index = 0;
int ret_val = 0;
int i;
mach = (&pdev->dev)->platform_data; mach = (&pdev->dev)->platform_data;
card = &bytcht_da7213_card; card = &bytcht_da7213_card;
card->dev = &pdev->dev; card->dev = &pdev->dev;
/* fix index of codec dai */ /* fix index of codec dai */
dai_index = MERR_DPCM_COMPR + 1;
for (i = 0; i < ARRAY_SIZE(dailink); i++) { for (i = 0; i < ARRAY_SIZE(dailink); i++) {
if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) { if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) {
dai_index = i; dai_index = i;
...@@ -252,8 +243,8 @@ static int bytcht_da7213_probe(struct platform_device *pdev) ...@@ -252,8 +243,8 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
} }
/* fixup codec name based on HID */ /* fixup codec name based on HID */
i2c_name = sst_acpi_find_name_from_hid(mach->id); i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
if (i2c_name != NULL) { if (i2c_name) {
snprintf(codec_name, sizeof(codec_name), snprintf(codec_name, sizeof(codec_name),
"%s%s", "i2c-", i2c_name); "%s%s", "i2c-", i2c_name);
dailink[dai_index].codec_name = codec_name; dailink[dai_index].codec_name = codec_name;
......
...@@ -29,28 +29,14 @@ ...@@ -29,28 +29,14 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../atom/sst-atom-controls.h" #include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
#include "../common/sst-dsp.h" #include "../common/sst-dsp.h"
struct byt_cht_es8316_private { struct byt_cht_es8316_private {
struct clk *mclk; struct clk *mclk;
}; };
#define CODEC_DAI1 "ES8316 HiFi"
static inline struct snd_soc_dai *get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, CODEC_DAI1,
strlen(CODEC_DAI1)))
return rtd->codec_dai;
}
return NULL;
}
static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = { static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_HP("Headphone", NULL),
...@@ -208,22 +194,13 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { ...@@ -208,22 +194,13 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
.ops = &byt_cht_es8316_aif1_ops, .ops = &byt_cht_es8316_aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* back ends */ /* back ends */
{ {
/* Only SSP2 has been tested here, so BYT-CR platforms that /* Only SSP2 has been tested here, so BYT-CR platforms that
* require SSP0 will not work. * require SSP0 will not work.
*/ */
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
......
...@@ -133,19 +133,11 @@ static struct snd_soc_dai_link dais[] = { ...@@ -133,19 +133,11 @@ static struct snd_soc_dai_link dais[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &aif1_ops, .ops = &aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* CODEC<->CODEC link */ /* CODEC<->CODEC link */
/* back ends */ /* back ends */
{ {
.name = "SSP2-LowSpeed Connector", .name = "SSP2-LowSpeed Connector",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
......
...@@ -22,19 +22,19 @@ ...@@ -22,19 +22,19 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/platform_sst_audio.h> #include <asm/platform_sst_audio.h>
#include <linux/clk.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/soc-acpi.h>
#include "../../codecs/rt5640.h" #include "../../codecs/rt5640.h"
#include "../atom/sst-atom-controls.h" #include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
#include "../common/sst-dsp.h" #include "../common/sst-dsp.h"
enum { enum {
...@@ -44,13 +44,13 @@ enum { ...@@ -44,13 +44,13 @@ enum {
BYT_RT5640_IN3_MAP, BYT_RT5640_IN3_MAP,
}; };
#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) #define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(7, 0))
#define BYT_RT5640_DMIC_EN BIT(16) #define BYT_RT5640_DMIC_EN BIT(16)
#define BYT_RT5640_MONO_SPEAKER BIT(17) #define BYT_RT5640_MONO_SPEAKER BIT(17)
#define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */ #define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */
#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */ #define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */
#define BYT_RT5640_SSP0_AIF1 BIT(20) #define BYT_RT5640_SSP0_AIF1 BIT(20)
#define BYT_RT5640_SSP0_AIF2 BIT(21) #define BYT_RT5640_SSP0_AIF2 BIT(21)
#define BYT_RT5640_MCLK_EN BIT(22) #define BYT_RT5640_MCLK_EN BIT(22)
#define BYT_RT5640_MCLK_25MHZ BIT(23) #define BYT_RT5640_MCLK_25MHZ BIT(23)
...@@ -145,22 +145,6 @@ static void log_quirks(struct device *dev) ...@@ -145,22 +145,6 @@ static void log_quirks(struct device *dev)
#define BYT_CODEC_DAI1 "rt5640-aif1" #define BYT_CODEC_DAI1 "rt5640-aif1"
#define BYT_CODEC_DAI2 "rt5640-aif2" #define BYT_CODEC_DAI2 "rt5640-aif2"
static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1,
strlen(BYT_CODEC_DAI1)))
return rtd->codec_dai;
if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2,
strlen(BYT_CODEC_DAI2)))
return rtd->codec_dai;
}
return NULL;
}
static int platform_clock_control(struct snd_soc_dapm_widget *w, static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event) struct snd_kcontrol *k, int event)
{ {
...@@ -170,7 +154,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -170,7 +154,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
int ret; int ret;
codec_dai = byt_get_codec_dai(card); codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
if (!codec_dai)
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
if (!codec_dai) { if (!codec_dai) {
dev_err(card->dev, dev_err(card->dev,
"Codec dai not found; Unable to set platform clock\n"); "Codec dai not found; Unable to set platform clock\n");
...@@ -178,7 +165,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -178,7 +165,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
} }
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
ret = clk_prepare_enable(priv->mclk); ret = clk_prepare_enable(priv->mclk);
if (ret < 0) { if (ret < 0) {
dev_err(card->dev, dev_err(card->dev,
...@@ -199,7 +186,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -199,7 +186,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
48000 * 512, 48000 * 512,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
if (!ret) { if (!ret) {
if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
clk_disable_unprepare(priv->mclk); clk_disable_unprepare(priv->mclk);
} }
} }
...@@ -376,8 +363,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -376,8 +363,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | .driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ {
.callback = byt_rt5640_quirk_cb, .callback = byt_rt5640_quirk_cb,
...@@ -385,12 +372,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -385,12 +372,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | .driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_MONO_SPEAKER | BYT_RT5640_MONO_SPEAKER |
BYT_RT5640_DIFF_MIC | BYT_RT5640_DIFF_MIC |
BYT_RT5640_SSP0_AIF2 | BYT_RT5640_SSP0_AIF2 |
BYT_RT5640_MCLK_EN BYT_RT5640_MCLK_EN),
),
}, },
{ {
.callback = byt_rt5640_quirk_cb, .callback = byt_rt5640_quirk_cb,
...@@ -398,9 +384,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -398,9 +384,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | .driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
BYT_RT5640_DMIC_EN | BYT_RT5640_DMIC_EN |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ {
.callback = byt_rt5640_quirk_cb, .callback = byt_rt5640_quirk_cb,
...@@ -408,8 +394,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -408,8 +394,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | .driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ {
.callback = byt_rt5640_quirk_cb, .callback = byt_rt5640_quirk_cb,
...@@ -417,8 +403,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -417,8 +403,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP | .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
BYT_RT5640_DMIC_EN), BYT_RT5640_DMIC_EN),
}, },
{ {
.callback = byt_rt5640_quirk_cb, .callback = byt_rt5640_quirk_cb,
...@@ -426,9 +412,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -426,9 +412,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
DMI_MATCH(DMI_BOARD_NAME, "tPAD"), DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | .driver_data = (void *)(BYT_RT5640_IN3_MAP |
BYT_RT5640_MCLK_EN | BYT_RT5640_MCLK_EN |
BYT_RT5640_SSP0_AIF1), BYT_RT5640_SSP0_AIF1),
}, },
{ {
.callback = byt_rt5640_quirk_cb, .callback = byt_rt5640_quirk_cb,
...@@ -436,7 +422,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -436,7 +422,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | .driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_MCLK_EN | BYT_RT5640_MCLK_EN |
BYT_RT5640_SSP0_AIF1), BYT_RT5640_SSP0_AIF1),
...@@ -446,9 +432,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -446,9 +432,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
}, },
.driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | .driver_data = (void *)(BYT_RT5640_IN3_MAP |
BYT_RT5640_MCLK_EN | BYT_RT5640_MCLK_EN |
BYT_RT5640_SSP0_AIF1), BYT_RT5640_SSP0_AIF1),
}, },
{} {}
...@@ -456,12 +442,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -456,12 +442,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
{ {
int ret;
struct snd_soc_codec *codec = runtime->codec;
struct snd_soc_card *card = runtime->card; struct snd_soc_card *card = runtime->card;
const struct snd_soc_dapm_route *custom_map;
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
struct snd_soc_codec *codec = runtime->codec;
const struct snd_soc_dapm_route *custom_map;
int num_routes; int num_routes;
int ret;
card->dapm.idle_bias_off = true; card->dapm.idle_bias_off = true;
...@@ -549,7 +535,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) ...@@ -549,7 +535,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
/* /*
* The firmware might enable the clock at * The firmware might enable the clock at
* boot (this information may or may not * boot (this information may or may not
...@@ -692,19 +678,11 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { ...@@ -692,19 +678,11 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
.dynamic = 1, .dynamic = 1,
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &byt_rt5640_aif1_ops, .ops = &byt_rt5640_aif1_ops,
},
[MERR_DPCM_COMPR] = {
.name = "Baytrail Compressed Port",
.stream_name = "Baytrail Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
}, },
/* back ends */ /* back ends */
{ {
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */ .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
...@@ -758,12 +736,12 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ ...@@ -758,12 +736,12 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
{ {
int ret_val = 0; struct byt_rt5640_private *priv;
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
const char *i2c_name = NULL; const char *i2c_name = NULL;
int ret_val = 0;
int dai_index = 0;
int i; int i;
int dai_index;
struct byt_rt5640_private *priv;
is_bytcr = false; is_bytcr = false;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
...@@ -776,7 +754,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -776,7 +754,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(&byt_rt5640_card, priv); snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
/* fix index of codec dai */ /* fix index of codec dai */
dai_index = MERR_DPCM_COMPR + 1;
for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) { for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) { if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
dai_index = i; dai_index = i;
...@@ -785,8 +762,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -785,8 +762,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
} }
/* fixup codec name based on HID */ /* fixup codec name based on HID */
i2c_name = sst_acpi_find_name_from_hid(mach->id); i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
if (i2c_name != NULL) { if (i2c_name) {
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
"%s%s", "i2c-", i2c_name); "%s%s", "i2c-", i2c_name);
...@@ -819,7 +796,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -819,7 +796,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
/* format specified: 2 64-bit integers */ /* format specified: 2 64-bit integers */
struct acpi_buffer format = {sizeof("NN"), "NN"}; struct acpi_buffer format = {sizeof("NN"), "NN"};
struct acpi_buffer state = {0, NULL}; struct acpi_buffer state = {0, NULL};
struct sst_acpi_package_context pkg_ctx; struct snd_soc_acpi_package_context pkg_ctx;
bool pkg_found = false; bool pkg_found = false;
state.length = sizeof(chan_package); state.length = sizeof(chan_package);
...@@ -831,7 +808,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -831,7 +808,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
pkg_ctx.state = &state; pkg_ctx.state = &state;
pkg_ctx.data_valid = false; pkg_ctx.data_valid = false;
pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx); pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
&pkg_ctx);
if (pkg_found) { if (pkg_found) {
if (chan_package.aif_value == 1) { if (chan_package.aif_value == 1) {
dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n"); dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
...@@ -891,7 +869,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -891,7 +869,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
byt_rt5640_cpu_dai_name; byt_rt5640_cpu_dai_name;
} }
if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) { if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk)) { if (IS_ERR(priv->mclk)) {
ret_val = PTR_ERR(priv->mclk); ret_val = PTR_ERR(priv->mclk);
......
...@@ -21,24 +21,124 @@ ...@@ -21,24 +21,124 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/platform_sst_audio.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/soc-acpi.h>
#include "../../codecs/rt5651.h" #include "../../codecs/rt5651.h"
#include "../atom/sst-atom-controls.h" #include "../atom/sst-atom-controls.h"
enum {
BYT_RT5651_DMIC_MAP,
BYT_RT5651_IN1_MAP,
BYT_RT5651_IN2_MAP,
};
#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(7, 0))
#define BYT_RT5651_DMIC_EN BIT(16)
#define BYT_RT5651_MCLK_EN BIT(17)
#define BYT_RT5651_MCLK_25MHZ BIT(18)
struct byt_rt5651_private {
struct clk *mclk;
struct snd_soc_jack jack;
};
static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP |
BYT_RT5651_DMIC_EN |
BYT_RT5651_MCLK_EN;
static void log_quirks(struct device *dev)
{
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP)
dev_info(dev, "quirk DMIC_MAP enabled");
if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_MAP)
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_quirk & BYT_RT5651_DMIC_EN)
dev_info(dev, "quirk DMIC enabled");
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
dev_info(dev, "quirk MCLK_EN enabled");
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
dev_info(dev, "quirk MCLK_25MHZ enabled");
}
#define BYT_CODEC_DAI1 "rt5651-aif1"
static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct snd_soc_dai *codec_dai;
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
int ret;
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
if (!codec_dai) {
dev_err(card->dev,
"Codec dai not found; Unable to set platform clock\n");
return -EIO;
}
if (SND_SOC_DAPM_EVENT_ON(event)) {
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
ret = clk_prepare_enable(priv->mclk);
if (ret < 0) {
dev_err(card->dev,
"could not configure MCLK state");
return ret;
}
}
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
48000 * 512,
SND_SOC_CLOCK_IN);
} else {
/*
* Set codec clock source to internal clock before
* turning off the platform clock. Codec needs clock
* for Jack detection and button press
*/
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_RCCLK,
48000 * 512,
SND_SOC_CLOCK_IN);
if (!ret)
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
clk_disable_unprepare(priv->mclk);
}
if (ret < 0) {
dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
return ret;
}
return 0;
}
static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = { static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Internal Mic", NULL), SND_SOC_DAPM_MIC("Internal Mic", NULL),
SND_SOC_DAPM_SPK("Speaker", NULL), SND_SOC_DAPM_SPK("Speaker", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
}; };
static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
{"Headphone", NULL, "Platform Clock"},
{"Headset Mic", NULL, "Platform Clock"},
{"Internal Mic", NULL, "Platform Clock"},
{"Speaker", NULL, "Platform Clock"},
{"AIF1 Playback", NULL, "ssp2 Tx"}, {"AIF1 Playback", NULL, "ssp2 Tx"},
{"ssp2 Tx", NULL, "codec_out0"}, {"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"}, {"ssp2 Tx", NULL, "codec_out1"},
...@@ -47,38 +147,30 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { ...@@ -47,38 +147,30 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
{"ssp2 Rx", NULL, "AIF1 Capture"}, {"ssp2 Rx", NULL, "AIF1 Capture"},
{"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */ {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
{"IN2P", NULL, "Headset Mic"},
{"Headphone", NULL, "HPOL"}, {"Headphone", NULL, "HPOL"},
{"Headphone", NULL, "HPOR"}, {"Headphone", NULL, "HPOR"},
{"Speaker", NULL, "LOUTL"}, {"Speaker", NULL, "LOUTL"},
{"Speaker", NULL, "LOUTR"}, {"Speaker", NULL, "LOUTR"},
}; };
static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic1_map[] = { static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
{"DMIC1", NULL, "Internal Mic"}, {"IN2P", NULL, "Headset Mic"},
}; {"DMIC L1", NULL, "Internal Mic"},
{"DMIC R1", NULL, "Internal Mic"},
static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic2_map[] = {
{"DMIC2", NULL, "Internal Mic"},
}; };
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = { static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
{"Internal Mic", NULL, "micbias1"}, {"Internal Mic", NULL, "micbias1"},
{"IN2P", NULL, "Headset Mic"},
{"IN1P", NULL, "Internal Mic"}, {"IN1P", NULL, "Internal Mic"},
}; };
enum { static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
BYT_RT5651_DMIC1_MAP, {"Internal Mic", NULL, "micbias1"},
BYT_RT5651_DMIC2_MAP, {"IN1P", NULL, "Headset Mic"},
BYT_RT5651_IN1_MAP, {"IN2P", NULL, "Internal Mic"},
}; };
#define BYT_RT5651_MAP(quirk) ((quirk) & 0xff)
#define BYT_RT5651_DMIC_EN BIT(16)
static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC1_MAP |
BYT_RT5651_DMIC_EN;
static const struct snd_kcontrol_new byt_rt5651_controls[] = { static const struct snd_kcontrol_new byt_rt5651_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Headset Mic"),
...@@ -86,6 +178,17 @@ static const struct snd_kcontrol_new byt_rt5651_controls[] = { ...@@ -86,6 +178,17 @@ static const struct snd_kcontrol_new byt_rt5651_controls[] = {
SOC_DAPM_PIN_SWITCH("Speaker"), SOC_DAPM_PIN_SWITCH("Speaker"),
}; };
static struct snd_soc_jack_pin bytcr_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
...@@ -103,9 +206,26 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, ...@@ -103,9 +206,26 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
ret = snd_soc_dai_set_pll(codec_dai, 0, RT5651_PLL1_S_BCLK1, if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
params_rate(params) * 50, /* 2x25 bit slots on SSP2 */
params_rate(params) * 512); ret = snd_soc_dai_set_pll(codec_dai, 0,
RT5651_PLL1_S_BCLK1,
params_rate(params) * 50,
params_rate(params) * 512);
} else {
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) {
ret = snd_soc_dai_set_pll(codec_dai, 0,
RT5651_PLL1_S_MCLK,
25000000,
params_rate(params) * 512);
} else {
ret = snd_soc_dai_set_pll(codec_dai, 0,
RT5651_PLL1_S_MCLK,
19200000,
params_rate(params) * 512);
}
}
if (ret < 0) { if (ret < 0) {
dev_err(rtd->dev, "can't set codec pll: %d\n", ret); dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
return ret; return ret;
...@@ -114,33 +234,60 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, ...@@ -114,33 +234,60 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
{
byt_rt5651_quirk = (unsigned long)id->driver_data;
return 1;
}
static const struct dmi_system_id byt_rt5651_quirk_table[] = { static const struct dmi_system_id byt_rt5651_quirk_table[] = {
{
.callback = byt_rt5651_quirk_cb,
.matches = {
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),
},
{
.callback = byt_rt5651_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
},
.driver_data = (void *)(BYT_RT5651_IN2_MAP),
},
{} {}
}; };
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
{ {
int ret;
struct snd_soc_card *card = runtime->card; struct snd_soc_card *card = runtime->card;
struct snd_soc_codec *codec = runtime->codec;
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
const struct snd_soc_dapm_route *custom_map; const struct snd_soc_dapm_route *custom_map;
int num_routes; int num_routes;
int ret;
card->dapm.idle_bias_off = true; card->dapm.idle_bias_off = true;
dmi_check_system(byt_rt5651_quirk_table);
switch (BYT_RT5651_MAP(byt_rt5651_quirk)) { switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
case BYT_RT5651_IN1_MAP: case BYT_RT5651_IN1_MAP:
custom_map = byt_rt5651_intmic_in1_map; custom_map = byt_rt5651_intmic_in1_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map); num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map);
break; break;
case BYT_RT5651_DMIC2_MAP: case BYT_RT5651_IN2_MAP:
custom_map = byt_rt5651_intmic_dmic2_map; custom_map = byt_rt5651_intmic_in2_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic2_map); num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map);
break; break;
default: default:
custom_map = byt_rt5651_intmic_dmic1_map; custom_map = byt_rt5651_intmic_dmic_map;
num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic1_map); num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map);
} }
ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
if (ret)
return ret;
ret = snd_soc_add_card_controls(card, byt_rt5651_controls, ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
ARRAY_SIZE(byt_rt5651_controls)); ARRAY_SIZE(byt_rt5651_controls));
...@@ -151,6 +298,40 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) ...@@ -151,6 +298,40 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
/*
* The firmware might enable the clock at
* boot (this information may or may not
* be reflected in the enable clock register).
* To change the rate we must disable the clock
* first to cover these cases. Due to common
* clock framework restrictions that do not allow
* to disable a clock that has not been enabled,
* we need to enable the clock first.
*/
ret = clk_prepare_enable(priv->mclk);
if (!ret)
clk_disable_unprepare(priv->mclk);
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
ret = clk_set_rate(priv->mclk, 25000000);
else
ret = clk_set_rate(priv->mclk, 19200000);
if (ret)
dev_err(card->dev, "unable to set MCLK rate\n");
}
ret = snd_soc_card_jack_new(runtime->card, "Headset",
SND_JACK_HEADSET, &priv->jack,
bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins));
if (ret) {
dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
return ret;
}
rt5651_set_jack_detect(codec, &priv->jack);
return ret; return ret;
} }
...@@ -253,19 +434,11 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { ...@@ -253,19 +434,11 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &byt_rt5651_aif1_ops, .ops = &byt_rt5651_aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* CODEC<->CODEC link */ /* CODEC<->CODEC link */
/* back ends */ /* back ends */
{ {
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
...@@ -296,13 +469,65 @@ static struct snd_soc_card byt_rt5651_card = { ...@@ -296,13 +469,65 @@ static struct snd_soc_card byt_rt5651_card = {
.fully_routed = true, .fully_routed = true,
}; };
static char byt_rt5651_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
{ {
struct byt_rt5651_private *priv;
struct snd_soc_acpi_mach *mach;
const char *i2c_name = NULL;
int ret_val = 0; int ret_val = 0;
int dai_index = 0;
int i;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
if (!priv)
return -ENOMEM;
/* register the soc card */ /* register the soc card */
byt_rt5651_card.dev = &pdev->dev; byt_rt5651_card.dev = &pdev->dev;
mach = byt_rt5651_card.dev->platform_data;
snd_soc_card_set_drvdata(&byt_rt5651_card, priv);
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) {
if (!strcmp(byt_rt5651_dais[i].codec_name, "i2c-10EC5651:00")) {
dai_index = i;
break;
}
}
/* fixup codec name based on HID */
i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
if (i2c_name) {
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"%s%s", "i2c-", i2c_name);
byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
}
/* check quirks before creating card */
dmi_check_system(byt_rt5651_quirk_table);
log_quirks(&pdev->dev);
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk)) {
dev_err(&pdev->dev,
"Failed to get MCLK from pmc_plt_clk_3: %ld\n",
PTR_ERR(priv->mclk));
/*
* Fall back to bit clock usage for -ENOENT (clock not
* available likely due to missing dependencies), bail
* for all other errors, including -EPROBE_DEFER
*/
if (ret_val != -ENOENT)
return ret_val;
byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
}
}
ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card); ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card);
if (ret_val) { if (ret_val) {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/clk.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
...@@ -35,15 +36,48 @@ ...@@ -35,15 +36,48 @@
#define CHT_CODEC_DAI "HiFi" #define CHT_CODEC_DAI "HiFi"
struct cht_mc_private { struct cht_mc_private {
struct clk *mclk;
struct snd_soc_jack jack; struct snd_soc_jack jack;
bool ts3a227e_present; bool ts3a227e_present;
}; };
static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
struct snd_soc_dapm_context *dapm = w->dapm;
struct snd_soc_card *card = dapm->card;
struct snd_soc_dai *codec_dai;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret;
codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI);
if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
return -EIO;
}
if (SND_SOC_DAPM_EVENT_ON(event)) {
ret = clk_prepare_enable(ctx->mclk);
if (ret < 0) {
dev_err(card->dev,
"could not configure MCLK state");
return ret;
}
} else {
clk_disable_unprepare(ctx->mclk);
}
return 0;
}
static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL),
SND_SOC_DAPM_SPK("Ext Spk", NULL), SND_SOC_DAPM_SPK("Ext Spk", NULL),
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
SND_SOC_DAPM_POST_PMD),
}; };
static const struct snd_soc_dapm_route cht_audio_map[] = { static const struct snd_soc_dapm_route cht_audio_map[] = {
...@@ -60,6 +94,10 @@ static const struct snd_soc_dapm_route cht_audio_map[] = { ...@@ -60,6 +94,10 @@ static const struct snd_soc_dapm_route cht_audio_map[] = {
{"codec_in0", NULL, "ssp2 Rx" }, {"codec_in0", NULL, "ssp2 Rx" },
{"codec_in1", NULL, "ssp2 Rx" }, {"codec_in1", NULL, "ssp2 Rx" },
{"ssp2 Rx", NULL, "HiFi Capture"}, {"ssp2 Rx", NULL, "HiFi Capture"},
{"Headphone", NULL, "Platform Clock"},
{"Headset Mic", NULL, "Platform Clock"},
{"Int Mic", NULL, "Platform Clock"},
{"Ext Spk", NULL, "Platform Clock"},
}; };
static const struct snd_kcontrol_new cht_mc_controls[] = { static const struct snd_kcontrol_new cht_mc_controls[] = {
...@@ -109,6 +147,40 @@ static struct notifier_block cht_jack_nb = { ...@@ -109,6 +147,40 @@ static struct notifier_block cht_jack_nb = {
.notifier_call = cht_ti_jack_event, .notifier_call = cht_ti_jack_event,
}; };
static struct snd_soc_jack_pin hs_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static struct snd_soc_jack_gpio hs_jack_gpios[] = {
{
.name = "hp",
.report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
.debounce_time = 200,
},
{
.name = "mic",
.invert = 1,
.report = SND_JACK_MICROPHONE,
.debounce_time = 200,
},
};
static const struct acpi_gpio_params hp_gpios = { 0, 0, false };
static const struct acpi_gpio_params mic_gpios = { 1, 0, false };
static const struct acpi_gpio_mapping acpi_max98090_gpios[] = {
{ "hp-gpios", &hp_gpios, 1 },
{ "mic-gpios", &mic_gpios, 1 },
{},
};
static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
{ {
int ret; int ret;
...@@ -116,30 +188,55 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) ...@@ -116,30 +188,55 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
struct snd_soc_jack *jack = &ctx->jack; struct snd_soc_jack *jack = &ctx->jack;
/** if (ctx->ts3a227e_present) {
* TI supports 4 butons headset detection /*
* KEY_MEDIA * The jack has already been created in the
* KEY_VOICECOMMAND * cht_max98090_headset_init() function.
* KEY_VOLUMEUP */
* KEY_VOLUMEDOWN snd_soc_jack_notifier_register(jack, &cht_jack_nb);
*/ return 0;
if (ctx->ts3a227e_present) }
jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3;
else
jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
jack_type, jack, NULL, 0);
ret = snd_soc_card_jack_new(runtime->card, "Headset Jack",
jack_type, jack,
hs_jack_pins, ARRAY_SIZE(hs_jack_pins));
if (ret) { if (ret) {
dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret); dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret);
return ret; return ret;
} }
if (ctx->ts3a227e_present) ret = snd_soc_jack_add_gpiods(runtime->card->dev->parent, jack,
snd_soc_jack_notifier_register(jack, &cht_jack_nb); ARRAY_SIZE(hs_jack_gpios),
hs_jack_gpios);
if (ret) {
/*
* flag error but don't bail if jack detect is broken
* due to platform issues or bad BIOS/configuration
*/
dev_err(runtime->dev,
"jack detection gpios not added, error %d\n", ret);
}
/*
* The firmware might enable the clock at
* boot (this information may or may not
* be reflected in the enable clock register).
* To change the rate we must disable the clock
* first to cover these cases. Due to common
* clock framework restrictions that do not allow
* to disable a clock that has not been enabled,
* we need to enable the clock first.
*/
ret = clk_prepare_enable(ctx->mclk);
if (!ret)
clk_disable_unprepare(ctx->mclk);
ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ);
if (ret)
dev_err(runtime->dev, "unable to set MCLK rate\n");
return ret; return ret;
} }
...@@ -188,8 +285,29 @@ static int cht_max98090_headset_init(struct snd_soc_component *component) ...@@ -188,8 +285,29 @@ static int cht_max98090_headset_init(struct snd_soc_component *component)
{ {
struct snd_soc_card *card = component->card; struct snd_soc_card *card = component->card;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_jack *jack = &ctx->jack;
int jack_type;
int ret;
return ts3a227e_enable_jack_detect(component, &ctx->jack); /*
* TI supports 4 butons headset detection
* KEY_MEDIA
* KEY_VOICECOMMAND
* KEY_VOLUMEUP
* KEY_VOLUMEDOWN
*/
jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3;
ret = snd_soc_card_jack_new(card, "Headset Jack", jack_type,
jack, NULL, 0);
if (ret) {
dev_err(card->dev, "Headset Jack creation failed %d\n", ret);
return ret;
}
return ts3a227e_enable_jack_detect(component, jack);
} }
static const struct snd_soc_ops cht_aif1_ops = { static const struct snd_soc_ops cht_aif1_ops = {
...@@ -232,18 +350,10 @@ static struct snd_soc_dai_link cht_dailink[] = { ...@@ -232,18 +350,10 @@ static struct snd_soc_dai_link cht_dailink[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &cht_aif1_ops, .ops = &cht_aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* back ends */ /* back ends */
{ {
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
...@@ -277,6 +387,7 @@ static struct snd_soc_card snd_soc_card_cht = { ...@@ -277,6 +387,7 @@ static struct snd_soc_card snd_soc_card_cht = {
static int snd_cht_mc_probe(struct platform_device *pdev) static int snd_cht_mc_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev;
int ret_val = 0; int ret_val = 0;
struct cht_mc_private *drv; struct cht_mc_private *drv;
...@@ -289,11 +400,25 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -289,11 +400,25 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
/* no need probe TI jack detection chip */ /* no need probe TI jack detection chip */
snd_soc_card_cht.aux_dev = NULL; snd_soc_card_cht.aux_dev = NULL;
snd_soc_card_cht.num_aux_devs = 0; snd_soc_card_cht.num_aux_devs = 0;
ret_val = devm_acpi_dev_add_driver_gpios(dev->parent,
acpi_max98090_gpios);
if (ret_val)
dev_dbg(dev, "Unable to add GPIO mapping table\n");
} }
/* register the soc card */ /* register the soc card */
snd_soc_card_cht.dev = &pdev->dev; snd_soc_card_cht.dev = &pdev->dev;
snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
if (IS_ERR(drv->mclk)) {
dev_err(&pdev->dev,
"Failed to get MCLK from pmc_plt_clk_3: %ld\n",
PTR_ERR(drv->mclk));
return PTR_ERR(drv->mclk);
}
ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
if (ret_val) { if (ret_val) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
......
...@@ -21,20 +21,20 @@ ...@@ -21,20 +21,20 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/acpi.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/platform_sst_audio.h> #include <asm/platform_sst_audio.h>
#include <linux/clk.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/soc-acpi.h>
#include "../../codecs/rt5645.h" #include "../../codecs/rt5645.h"
#include "../atom/sst-atom-controls.h" #include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
#define CHT_PLAT_CLK_3_HZ 19200000 #define CHT_PLAT_CLK_3_HZ 19200000
#define CHT_CODEC_DAI1 "rt5645-aif1" #define CHT_CODEC_DAI1 "rt5645-aif1"
...@@ -53,7 +53,7 @@ struct cht_mc_private { ...@@ -53,7 +53,7 @@ struct cht_mc_private {
struct clk *mclk; struct clk *mclk;
}; };
#define CHT_RT5645_MAP(quirk) ((quirk) & 0xff) #define CHT_RT5645_MAP(quirk) ((quirk) & GENMASK(7, 0))
#define CHT_RT5645_SSP2_AIF2 BIT(16) /* default is using AIF1 */ #define CHT_RT5645_SSP2_AIF2 BIT(16) /* default is using AIF1 */
#define CHT_RT5645_SSP0_AIF1 BIT(17) #define CHT_RT5645_SSP0_AIF1 BIT(17)
#define CHT_RT5645_SSP0_AIF2 BIT(18) #define CHT_RT5645_SSP0_AIF2 BIT(18)
...@@ -70,21 +70,6 @@ static void log_quirks(struct device *dev) ...@@ -70,21 +70,6 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk SSP0_AIF2 enabled"); dev_info(dev, "quirk SSP0_AIF2 enabled");
} }
static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI1,
strlen(CHT_CODEC_DAI1)))
return rtd->codec_dai;
if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI2,
strlen(CHT_CODEC_DAI2)))
return rtd->codec_dai;
}
return NULL;
}
static int platform_clock_control(struct snd_soc_dapm_widget *w, static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event) struct snd_kcontrol *k, int event)
{ {
...@@ -94,20 +79,21 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -94,20 +79,21 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret; int ret;
codec_dai = cht_get_codec_dai(card); codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI1);
if (!codec_dai)
codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI2);
if (!codec_dai) { if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
return -EIO; return -EIO;
} }
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
if (ctx->mclk) { ret = clk_prepare_enable(ctx->mclk);
ret = clk_prepare_enable(ctx->mclk); if (ret < 0) {
if (ret < 0) { dev_err(card->dev,
dev_err(card->dev, "could not configure MCLK state");
"could not configure MCLK state"); return ret;
return ret;
}
} }
} else { } else {
/* Set codec sysclk source to its internal clock because codec PLL will /* Set codec sysclk source to its internal clock because codec PLL will
...@@ -122,8 +108,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -122,8 +108,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
return ret; return ret;
} }
if (ctx->mclk) clk_disable_unprepare(ctx->mclk);
clk_disable_unprepare(ctx->mclk);
} }
return 0; return 0;
...@@ -258,11 +243,11 @@ static const struct dmi_system_id cht_rt5645_quirk_table[] = { ...@@ -258,11 +243,11 @@ static const struct dmi_system_id cht_rt5645_quirk_table[] = {
static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
{ {
int ret;
int jack_type;
struct snd_soc_codec *codec = runtime->codec;
struct snd_soc_card *card = runtime->card; struct snd_soc_card *card = runtime->card;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
struct snd_soc_codec *codec = runtime->codec;
int jack_type;
int ret;
if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) || if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) ||
(cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) { (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) {
...@@ -320,26 +305,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) ...@@ -320,26 +305,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack);
if (ctx->mclk) {
/*
* The firmware might enable the clock at
* boot (this information may or may not
* be reflected in the enable clock register).
* To change the rate we must disable the clock
* first to cover these cases. Due to common
* clock framework restrictions that do not allow
* to disable a clock that has not been enabled,
* we need to enable the clock first.
*/
ret = clk_prepare_enable(ctx->mclk);
if (!ret)
clk_disable_unprepare(ctx->mclk);
ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); /*
* The firmware might enable the clock at
* boot (this information may or may not
* be reflected in the enable clock register).
* To change the rate we must disable the clock
* first to cover these cases. Due to common
* clock framework restrictions that do not allow
* to disable a clock that has not been enabled,
* we need to enable the clock first.
*/
ret = clk_prepare_enable(ctx->mclk);
if (!ret)
clk_disable_unprepare(ctx->mclk);
ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ);
if (ret)
dev_err(runtime->dev, "unable to set MCLK rate\n");
if (ret)
dev_err(runtime->dev, "unable to set MCLK rate\n");
}
return ret; return ret;
} }
...@@ -460,19 +445,11 @@ static struct snd_soc_dai_link cht_dailink[] = { ...@@ -460,19 +445,11 @@ static struct snd_soc_dai_link cht_dailink[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &cht_aif1_ops, .ops = &cht_aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* CODEC<->CODEC link */ /* CODEC<->CODEC link */
/* back ends */ /* back ends */
{ {
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
...@@ -545,15 +522,15 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ ...@@ -545,15 +522,15 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
static int snd_cht_mc_probe(struct platform_device *pdev) static int snd_cht_mc_probe(struct platform_device *pdev)
{ {
int ret_val = 0;
int i;
struct cht_mc_private *drv;
struct snd_soc_card *card = snd_soc_cards[0].soc_card; struct snd_soc_card *card = snd_soc_cards[0].soc_card;
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
struct cht_mc_private *drv;
const char *i2c_name = NULL; const char *i2c_name = NULL;
int dai_index = 0;
bool found = false; bool found = false;
bool is_bytcr = false; bool is_bytcr = false;
int dai_index = 0;
int ret_val = 0;
int i;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
if (!drv) if (!drv)
...@@ -589,8 +566,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -589,8 +566,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
} }
/* fixup codec name based on HID */ /* fixup codec name based on HID */
i2c_name = sst_acpi_find_name_from_hid(mach->id); i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
if (i2c_name != NULL) { if (i2c_name) {
snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
"%s%s", "i2c-", i2c_name); "%s%s", "i2c-", i2c_name);
cht_dailink[dai_index].codec_name = cht_rt5645_codec_name; cht_dailink[dai_index].codec_name = cht_rt5645_codec_name;
...@@ -622,7 +599,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -622,7 +599,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
/* format specified: 2 64-bit integers */ /* format specified: 2 64-bit integers */
struct acpi_buffer format = {sizeof("NN"), "NN"}; struct acpi_buffer format = {sizeof("NN"), "NN"};
struct acpi_buffer state = {0, NULL}; struct acpi_buffer state = {0, NULL};
struct sst_acpi_package_context pkg_ctx; struct snd_soc_acpi_package_context pkg_ctx;
bool pkg_found = false; bool pkg_found = false;
state.length = sizeof(chan_package); state.length = sizeof(chan_package);
...@@ -634,7 +611,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -634,7 +611,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
pkg_ctx.state = &state; pkg_ctx.state = &state;
pkg_ctx.data_valid = false; pkg_ctx.data_valid = false;
pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx); pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
&pkg_ctx);
if (pkg_found) { if (pkg_found) {
if (chan_package.aif_value == 1) { if (chan_package.aif_value == 1) {
dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n"); dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
...@@ -682,14 +660,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -682,14 +660,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
cht_rt5645_cpu_dai_name; cht_rt5645_cpu_dai_name;
} }
if (is_valleyview()) { drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); if (IS_ERR(drv->mclk)) {
if (IS_ERR(drv->mclk)) { dev_err(&pdev->dev,
dev_err(&pdev->dev, "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
"Failed to get MCLK from pmc_plt_clk_3: %ld\n", PTR_ERR(drv->mclk));
PTR_ERR(drv->mclk)); return PTR_ERR(drv->mclk);
return PTR_ERR(drv->mclk);
}
} }
snd_soc_card_set_drvdata(card, drv); snd_soc_card_set_drvdata(card, drv);
......
...@@ -20,14 +20,14 @@ ...@@ -20,14 +20,14 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <asm/cpu_device_id.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/soc-acpi.h>
#include "../../codecs/rt5670.h" #include "../../codecs/rt5670.h"
#include "../atom/sst-atom-controls.h" #include "../atom/sst-atom-controls.h"
#include "../common/sst-acpi.h"
/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ /* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */
#define CHT_PLAT_CLK_3_HZ 19200000 #define CHT_PLAT_CLK_3_HZ 19200000
...@@ -51,18 +51,6 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = { ...@@ -51,18 +51,6 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
}, },
}; };
static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
strlen(CHT_CODEC_DAI)))
return rtd->codec_dai;
}
return NULL;
}
static int platform_clock_control(struct snd_soc_dapm_widget *w, static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event) struct snd_kcontrol *k, int event)
{ {
...@@ -72,7 +60,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -72,7 +60,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret; int ret;
codec_dai = cht_get_codec_dai(card); codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI);
if (!codec_dai) { if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
return -EIO; return -EIO;
...@@ -315,20 +303,12 @@ static struct snd_soc_dai_link cht_dailink[] = { ...@@ -315,20 +303,12 @@ static struct snd_soc_dai_link cht_dailink[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &cht_aif1_ops, .ops = &cht_aif1_ops,
}, },
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
},
/* Back End DAI links */ /* Back End DAI links */
{ {
/* SSP2 - Codec */ /* SSP2 - Codec */
.name = "SSP2-Codec", .name = "SSP2-Codec",
.id = 1, .id = 0,
.cpu_dai_name = "ssp2-port", .cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform", .platform_name = "sst-mfld-platform",
.no_pcm = 1, .no_pcm = 1,
...@@ -348,9 +328,11 @@ static struct snd_soc_dai_link cht_dailink[] = { ...@@ -348,9 +328,11 @@ static struct snd_soc_dai_link cht_dailink[] = {
static int cht_suspend_pre(struct snd_soc_card *card) static int cht_suspend_pre(struct snd_soc_card *card)
{ {
struct snd_soc_component *component; struct snd_soc_component *component;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
list_for_each_entry(component, &card->component_dev_list, card_list) { list_for_each_entry(component, &card->component_dev_list, card_list) {
if (!strcmp(component->name, "i2c-10EC5670:00")) { if (!strncmp(component->name,
ctx->codec_name, sizeof(ctx->codec_name))) {
struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
...@@ -364,9 +346,11 @@ static int cht_suspend_pre(struct snd_soc_card *card) ...@@ -364,9 +346,11 @@ static int cht_suspend_pre(struct snd_soc_card *card)
static int cht_resume_post(struct snd_soc_card *card) static int cht_resume_post(struct snd_soc_card *card)
{ {
struct snd_soc_component *component; struct snd_soc_component *component;
struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);
list_for_each_entry(component, &card->component_dev_list, card_list) { list_for_each_entry(component, &card->component_dev_list, card_list) {
if (!strcmp(component->name, "i2c-10EC5670:00")) { if (!strncmp(component->name,
ctx->codec_name, sizeof(ctx->codec_name))) {
struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
dev_dbg(codec->dev, "enabling jack detect for resume.\n"); dev_dbg(codec->dev, "enabling jack detect for resume.\n");
...@@ -380,7 +364,7 @@ static int cht_resume_post(struct snd_soc_card *card) ...@@ -380,7 +364,7 @@ static int cht_resume_post(struct snd_soc_card *card)
/* SoC card */ /* SoC card */
static struct snd_soc_card snd_soc_card_cht = { static struct snd_soc_card snd_soc_card_cht = {
.name = "cherrytrailcraudio", .name = "cht-bsw-rt5672",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.dai_link = cht_dailink, .dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink), .num_links = ARRAY_SIZE(cht_dailink),
...@@ -394,25 +378,13 @@ static struct snd_soc_card snd_soc_card_cht = { ...@@ -394,25 +378,13 @@ static struct snd_soc_card snd_soc_card_cht = {
.resume_post = cht_resume_post, .resume_post = cht_resume_post,
}; };
static bool is_valleyview(void)
{
static const struct x86_cpu_id cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
{}
};
if (!x86_match_cpu(cpu_ids))
return false;
return true;
}
#define RT5672_I2C_DEFAULT "i2c-10EC5670:00" #define RT5672_I2C_DEFAULT "i2c-10EC5670:00"
static int snd_cht_mc_probe(struct platform_device *pdev) static int snd_cht_mc_probe(struct platform_device *pdev)
{ {
int ret_val = 0; int ret_val = 0;
struct cht_mc_private *drv; struct cht_mc_private *drv;
struct sst_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
const char *i2c_name; const char *i2c_name;
int i; int i;
...@@ -424,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -424,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
/* fixup codec name based on HID */ /* fixup codec name based on HID */
if (mach) { if (mach) {
i2c_name = sst_acpi_find_name_from_hid(mach->id); i2c_name = snd_soc_acpi_find_name_from_hid(mach->id);
if (i2c_name) { if (i2c_name) {
snprintf(drv->codec_name, sizeof(drv->codec_name), snprintf(drv->codec_name, sizeof(drv->codec_name),
"i2c-%s", i2c_name); "i2c-%s", i2c_name);
...@@ -439,14 +411,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev) ...@@ -439,14 +411,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
} }
} }
if (is_valleyview()) { drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); if (IS_ERR(drv->mclk)) {
if (IS_ERR(drv->mclk)) { dev_err(&pdev->dev,
dev_err(&pdev->dev, "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
"Failed to get MCLK from pmc_plt_clk_3: %ld\n", PTR_ERR(drv->mclk));
PTR_ERR(drv->mclk)); return PTR_ERR(drv->mclk);
return PTR_ERR(drv->mclk);
}
} }
snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/input.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <sound/core.h> #include <sound/core.h>
...@@ -208,6 +209,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) ...@@ -208,6 +209,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
int ret; int ret;
struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_jack *jack;
/* /*
* Headset buttons map to the google Reference headset. * Headset buttons map to the google Reference headset.
...@@ -221,6 +223,13 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) ...@@ -221,6 +223,13 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd)
dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
return ret; return ret;
} }
jack = &ctx->kabylake_headset;
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_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);
rt5663_set_jack_detect(codec, &ctx->kabylake_headset); rt5663_set_jack_detect(codec, &ctx->kabylake_headset);
return ret; return ret;
} }
...@@ -341,13 +350,28 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, ...@@ -341,13 +350,28 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_interval *channels = hw_param_interval(params, struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS); SNDRV_PCM_HW_PARAM_CHANNELS);
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
struct snd_soc_dpcm *dpcm = container_of(
params, struct snd_soc_dpcm, hw_params);
struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;
struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;
/* The ADSP will convert the FE rate to 48k, stereo */ /*
rate->min = rate->max = 48000; * The ADSP will convert the FE rate to 48k, stereo, 24 bit
channels->min = channels->max = 2; */
/* set SSP1 to 24 bit */ if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
snd_mask_none(fmt); !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
snd_mask_none(fmt);
snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE);
}
/*
* The speaker on the SSP0 supports S16_LE and not S24_LE.
* thus changing the mask here
*/
if (!strcmp(be_dai_link->name, "SSP0-Codec"))
snd_mask_set(fmt, SNDRV_PCM_FORMAT_S16_LE);
return 0; return 0;
} }
...@@ -390,6 +414,43 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, ...@@ -390,6 +414,43 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
return 0; return 0;
} }
static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
int ret = 0, j;
for (j = 0; j < rtd->num_codecs; j++) {
struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) {
/*
* Use channel 4 and 5 for the first amp
*/
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16);
if (ret < 0) {
dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
return ret;
}
}
if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) {
/*
* Use channel 6 and 7 for the second amp
*/
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16);
if (ret < 0) {
dev_err(rtd->dev, "set TDM slot err:%d\n", ret);
return ret;
}
}
}
return ret;
}
static struct snd_soc_ops kabylake_ssp0_ops = {
.hw_params = kabylake_ssp0_hw_params,
};
static unsigned int channels_dmic[] = { static unsigned int channels_dmic[] = {
2, 4, 2, 4,
}; };
...@@ -593,12 +654,13 @@ static struct snd_soc_dai_link kabylake_dais[] = { ...@@ -593,12 +654,13 @@ static struct snd_soc_dai_link kabylake_dais[] = {
.no_pcm = 1, .no_pcm = 1,
.codecs = max98927_codec_components, .codecs = max98927_codec_components,
.num_codecs = ARRAY_SIZE(max98927_codec_components), .num_codecs = ARRAY_SIZE(max98927_codec_components),
.dai_fmt = SND_SOC_DAIFMT_I2S | .dai_fmt = SND_SOC_DAIFMT_DSP_B |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
.ignore_pmdown_time = 1, .ignore_pmdown_time = 1,
.be_hw_params_fixup = kabylake_ssp_fixup, .be_hw_params_fixup = kabylake_ssp_fixup,
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &kabylake_ssp0_ops,
}, },
{ {
/* SSP1 - Codec */ /* SSP1 - Codec */
......
...@@ -302,6 +302,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, ...@@ -302,6 +302,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd,
* The ADSP will convert the FE rate to 48k, stereo, 24 bit * The ADSP will convert the FE rate to 48k, stereo, 24 bit
*/ */
if (!strcmp(fe_dai_link->name, "Kbl Audio Port") || if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||
!strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||
!strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) { !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {
rate->min = rate->max = 48000; rate->min = rate->max = 48000;
channels->min = channels->max = 2; channels->min = channels->max = 2;
......
...@@ -54,20 +54,6 @@ enum { ...@@ -54,20 +54,6 @@ enum {
SKL_DPCM_AUDIO_HDMI3_PB, SKL_DPCM_AUDIO_HDMI3_PB,
}; };
static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
strlen(SKL_NUVOTON_CODEC_DAI)))
return rtd->codec_dai;
}
return NULL;
}
static int platform_clock_control(struct snd_soc_dapm_widget *w, static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event) struct snd_kcontrol *k, int event)
{ {
...@@ -76,7 +62,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -76,7 +62,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
int ret; int ret;
codec_dai = skl_get_codec_dai(card); codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI);
if (!codec_dai) { if (!codec_dai) {
dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n");
return -EIO; return -EIO;
......
...@@ -57,20 +57,6 @@ enum { ...@@ -57,20 +57,6 @@ enum {
SKL_DPCM_AUDIO_HDMI3_PB, SKL_DPCM_AUDIO_HDMI3_PB,
}; };
static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI,
strlen(SKL_NUVOTON_CODEC_DAI)))
return rtd->codec_dai;
}
return NULL;
}
static const struct snd_kcontrol_new skylake_controls[] = { static const struct snd_kcontrol_new skylake_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Headset Mic"), SOC_DAPM_PIN_SWITCH("Headset Mic"),
...@@ -86,7 +72,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, ...@@ -86,7 +72,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
int ret; int ret;
codec_dai = skl_get_codec_dai(card); codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI);
if (!codec_dai) { if (!codec_dai) {
dev_err(card->dev, "Codec dai not found\n"); dev_err(card->dev, "Codec dai not found\n");
return -EIO; return -EIO;
......
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
snd-soc-sst-dsp-objs := sst-dsp.o snd-soc-sst-dsp-objs := sst-dsp.o
snd-soc-sst-acpi-objs := sst-acpi.o snd-soc-sst-acpi-objs := sst-acpi.o
snd-soc-sst-match-objs := sst-match-acpi.o
snd-soc-sst-ipc-objs := sst-ipc.o snd-soc-sst-ipc-objs := sst-ipc.o
snd-soc-sst-firmware-objs := sst-firmware.o snd-soc-sst-firmware-objs := sst-firmware.o
snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o soc-acpi-intel-hsw-bdw-match.o
obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
obj-$(CONFIG_SND_SOC_INTEL_SST_MATCH) += snd-soc-sst-match.o
obj-$(CONFIG_SND_SOC_INTEL_SST_FIRMWARE) += snd-soc-sst-firmware.o obj-$(CONFIG_SND_SOC_INTEL_SST_FIRMWARE) += snd-soc-sst-firmware.o
obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o
/*
* soc-apci-intel-byt-match.c - tables and support for BYT ACPI enumeration.
*
* Copyright (c) 2017, Intel Corporation.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/dmi.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
static unsigned long byt_machine_id;
#define BYT_THINKPAD_10 1
static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id)
{
byt_machine_id = BYT_THINKPAD_10;
return 1;
}
static const struct dmi_system_id byt_table[] = {
{
.callback = byt_thinkpad10_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
},
},
{
.callback = byt_thinkpad10_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
},
},
{
.callback = byt_thinkpad10_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
},
},
{ }
};
static struct snd_soc_acpi_mach byt_thinkpad_10 = {
.id = "10EC5640",
.drv_name = "cht-bsw-rt5672",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5670.tplg",
.asoc_plat_name = "sst-mfld-platform",
};
static struct snd_soc_acpi_mach *byt_quirk(void *arg)
{
struct snd_soc_acpi_mach *mach = arg;
dmi_check_system(byt_table);
if (byt_machine_id == BYT_THINKPAD_10)
return &byt_thinkpad_10;
else
return mach;
}
struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[] = {
{
.id = "10EC5640",
.drv_name = "byt-rt5640",
.fw_filename = "intel/fw_sst_0f28.bin-48kHz_i2s_master",
},
{
.id = "193C9890",
.drv_name = "byt-max98090",
.fw_filename = "intel/fw_sst_0f28.bin-48kHz_i2s_master",
},
{}
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_legacy_machines);
struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = {
{
.id = "10EC5640",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5640",
.machine_quirk = byt_quirk,
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5640.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC5642",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5640",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5640.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "INTCCFFD",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5640",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5640.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC5651",
.drv_name = "bytcr_rt5651",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcr_rt5651",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5651.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "DLGS7212",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcht_da7213",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-da7213.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "DLGS7213",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcht_da7213",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-da7213.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
/* some Baytrail platforms rely on RT5645, use CHT machine driver */
{
.id = "10EC5645",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5645.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC5648",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-rt5645.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
/* use CHT driver to Baytrail Chromebooks */
{
.id = "193C9890",
.drv_name = "cht-bsw-max98090",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-byt.ri",
.sof_tplg_filename = "intel/reef-byt-max98090.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
.id = "80860F28",
.drv_name = "bytcht_nocodec",
.fw_filename = "intel/fw_sst_0f28.bin",
.board = "bytcht_nocodec",
},
#endif
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_machines);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module");
/*
* soc-apci-intel-cht-match.c - tables and support for CHT ACPI enumeration.
*
* Copyright (c) 2017, Intel Corporation.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/dmi.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
static unsigned long cht_machine_id;
#define CHT_SURFACE_MACH 1
static int cht_surface_quirk_cb(const struct dmi_system_id *id)
{
cht_machine_id = CHT_SURFACE_MACH;
return 1;
}
static const struct dmi_system_id cht_table[] = {
{
.callback = cht_surface_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
},
},
{ }
};
static struct snd_soc_acpi_mach cht_surface_mach = {
.id = "10EC5640",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
.asoc_plat_name = "sst-mfld-platform",
};
static struct snd_soc_acpi_mach *cht_quirk(void *arg)
{
struct snd_soc_acpi_mach *mach = arg;
dmi_check_system(cht_table);
if (cht_machine_id == CHT_SURFACE_MACH)
return &cht_surface_mach;
else
return mach;
}
/* Cherryview-based platforms: CherryTrail and Braswell */
struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[] = {
{
.id = "10EC5670",
.drv_name = "cht-bsw-rt5672",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5670.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC5672",
.drv_name = "cht-bsw-rt5672",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5670.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC5645",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC5650",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC3270",
.drv_name = "cht-bsw-rt5645",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5645.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "193C9890",
.drv_name = "cht-bsw-max98090",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "cht-bsw",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-max98090.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "DLGS7212",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_da7213",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-da7213.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "DLGS7213",
.drv_name = "bytcht_da7213",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_da7213",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-da7213.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "ESSX8316",
.drv_name = "bytcht_es8316",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_es8316",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-es8316.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
/* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
{
.id = "10EC5640",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcr_rt5640",
.machine_quirk = cht_quirk,
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5640.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
{
.id = "10EC3276",
.drv_name = "bytcr_rt5640",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcr_rt5640",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5640.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
/* some CHT-T platforms rely on RT5651, use Baytrail machine driver */
{
.id = "10EC5651",
.drv_name = "bytcr_rt5651",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcr_rt5651",
.sof_fw_filename = "intel/reef-cht.ri",
.sof_tplg_filename = "intel/reef-cht-rt5651.tplg",
.asoc_plat_name = "sst-mfld-platform",
},
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH)
/*
* This is always last in the table so that it is selected only when
* enabled explicitly and there is no codec-related information in SSDT
*/
{
.id = "808622A8",
.drv_name = "bytcht_nocodec",
.fw_filename = "intel/fw_sst_22a8.bin",
.board = "bytcht_nocodec",
},
#endif
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cherrytrail_machines);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module");
/*
* soc-apci-intel-hsw-bdw-match.c - tables and support for ACPI enumeration.
*
* Copyright (c) 2017, Intel Corporation.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/dmi.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[] = {
{
.id = "INT33CA",
.drv_name = "haswell-audio",
.fw_filename = "intel/IntcSST1.bin",
.sof_fw_filename = "intel/reef-hsw.ri",
.sof_tplg_filename = "intel/reef-hsw.tplg",
.asoc_plat_name = "haswell-pcm-audio",
},
{}
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_haswell_machines);
struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = {
{
.id = "INT343A",
.drv_name = "broadwell-audio",
.fw_filename = "intel/IntcSST2.bin",
.sof_fw_filename = "intel/reef-bdw.ri",
.sof_tplg_filename = "intel/reef-bdw-rt286.tplg",
.asoc_plat_name = "haswell-pcm-audio",
},
{
.id = "RT5677CE",
.drv_name = "bdw-rt5677",
.fw_filename = "intel/IntcSST2.bin",
.sof_fw_filename = "intel/reef-bdw.ri",
.sof_tplg_filename = "intel/reef-bdw-rt286.tplg",
.asoc_plat_name = "haswell-pcm-audio",
},
{
.id = "INT33CA",
.drv_name = "haswell-audio",
.fw_filename = "intel/IntcSST2.bin",
.sof_fw_filename = "intel/reef-bdw.ri",
.sof_tplg_filename = "intel/reef-bdw-rt5640.tplg",
.asoc_plat_name = "haswell-pcm-audio",
},
{}
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_broadwell_machines);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module");
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "sst-dsp.h" #include "sst-dsp.h"
#include "sst-acpi.h" #include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000 #define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000
#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000 #define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000
...@@ -30,7 +31,7 @@ ...@@ -30,7 +31,7 @@
/* Descriptor for setting up SST platform data */ /* Descriptor for setting up SST platform data */
struct sst_acpi_desc { struct sst_acpi_desc {
const char *drv_name; const char *drv_name;
struct sst_acpi_mach *machines; struct snd_soc_acpi_mach *machines;
/* Platform resource indexes. Must set to -1 if not used */ /* Platform resource indexes. Must set to -1 if not used */
int resindex_lpe_base; int resindex_lpe_base;
int resindex_pcicfg_base; int resindex_pcicfg_base;
...@@ -49,7 +50,7 @@ struct sst_acpi_priv { ...@@ -49,7 +50,7 @@ struct sst_acpi_priv {
struct platform_device *pdev_pcm; struct platform_device *pdev_pcm;
struct sst_pdata sst_pdata; struct sst_pdata sst_pdata;
struct sst_acpi_desc *desc; struct sst_acpi_desc *desc;
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
}; };
static void sst_acpi_fw_cb(const struct firmware *fw, void *context) static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
...@@ -59,7 +60,7 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context) ...@@ -59,7 +60,7 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev); struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata; struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
struct sst_acpi_desc *desc = sst_acpi->desc; struct sst_acpi_desc *desc = sst_acpi->desc;
struct sst_acpi_mach *mach = sst_acpi->mach; struct snd_soc_acpi_mach *mach = sst_acpi->mach;
sst_pdata->fw = fw; sst_pdata->fw = fw;
if (!fw) { if (!fw) {
...@@ -85,7 +86,7 @@ static int sst_acpi_probe(struct platform_device *pdev) ...@@ -85,7 +86,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct sst_acpi_priv *sst_acpi; struct sst_acpi_priv *sst_acpi;
struct sst_pdata *sst_pdata; struct sst_pdata *sst_pdata;
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
struct sst_acpi_desc *desc; struct sst_acpi_desc *desc;
struct resource *mmio; struct resource *mmio;
int ret = 0; int ret = 0;
...@@ -99,7 +100,7 @@ static int sst_acpi_probe(struct platform_device *pdev) ...@@ -99,7 +100,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
desc = (struct sst_acpi_desc *)id->driver_data; desc = (struct sst_acpi_desc *)id->driver_data;
mach = sst_acpi_find_machine(desc->machines); mach = snd_soc_acpi_find_machine(desc->machines);
if (mach == NULL) { if (mach == NULL) {
dev_err(dev, "No matching ASoC machine driver found\n"); dev_err(dev, "No matching ASoC machine driver found\n");
return -ENODEV; return -ENODEV;
...@@ -179,14 +180,9 @@ static int sst_acpi_remove(struct platform_device *pdev) ...@@ -179,14 +180,9 @@ static int sst_acpi_remove(struct platform_device *pdev)
return 0; return 0;
} }
static struct sst_acpi_mach haswell_machines[] = {
{ "INT33CA", "haswell-audio", "intel/IntcSST1.bin", NULL, NULL, NULL },
{}
};
static struct sst_acpi_desc sst_acpi_haswell_desc = { static struct sst_acpi_desc sst_acpi_haswell_desc = {
.drv_name = "haswell-pcm-audio", .drv_name = "haswell-pcm-audio",
.machines = haswell_machines, .machines = snd_soc_acpi_intel_haswell_machines,
.resindex_lpe_base = 0, .resindex_lpe_base = 0,
.resindex_pcicfg_base = 1, .resindex_pcicfg_base = 1,
.resindex_fw_base = -1, .resindex_fw_base = -1,
...@@ -197,15 +193,9 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = { ...@@ -197,15 +193,9 @@ static struct sst_acpi_desc sst_acpi_haswell_desc = {
.dma_size = SST_LPT_DSP_DMA_SIZE, .dma_size = SST_LPT_DSP_DMA_SIZE,
}; };
static struct sst_acpi_mach broadwell_machines[] = {
{ "INT343A", "broadwell-audio", "intel/IntcSST2.bin", NULL, NULL, NULL },
{ "RT5677CE", "bdw-rt5677", "intel/IntcSST2.bin", NULL, NULL, NULL },
{}
};
static struct sst_acpi_desc sst_acpi_broadwell_desc = { static struct sst_acpi_desc sst_acpi_broadwell_desc = {
.drv_name = "haswell-pcm-audio", .drv_name = "haswell-pcm-audio",
.machines = broadwell_machines, .machines = snd_soc_acpi_intel_broadwell_machines,
.resindex_lpe_base = 0, .resindex_lpe_base = 0,
.resindex_pcicfg_base = 1, .resindex_pcicfg_base = 1,
.resindex_fw_base = -1, .resindex_fw_base = -1,
...@@ -217,15 +207,9 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = { ...@@ -217,15 +207,9 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
}; };
#if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI) #if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI)
static struct sst_acpi_mach baytrail_machines[] = {
{ "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
{ "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
{}
};
static struct sst_acpi_desc sst_acpi_baytrail_desc = { static struct sst_acpi_desc sst_acpi_baytrail_desc = {
.drv_name = "baytrail-pcm-audio", .drv_name = "baytrail-pcm-audio",
.machines = baytrail_machines, .machines = snd_soc_acpi_intel_baytrail_legacy_machines,
.resindex_lpe_base = 0, .resindex_lpe_base = 0,
.resindex_pcicfg_base = 1, .resindex_pcicfg_base = 1,
.resindex_fw_base = 2, .resindex_fw_base = 2,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dmaengine.h> #include <linux/dmaengine.h>
...@@ -274,7 +275,6 @@ int sst_dma_new(struct sst_dsp *sst) ...@@ -274,7 +275,6 @@ int sst_dma_new(struct sst_dsp *sst)
struct sst_pdata *sst_pdata = sst->pdata; struct sst_pdata *sst_pdata = sst->pdata;
struct sst_dma *dma; struct sst_dma *dma;
struct resource mem; struct resource mem;
const char *dma_dev_name;
int ret = 0; int ret = 0;
if (sst->pdata->resindex_dma_base == -1) if (sst->pdata->resindex_dma_base == -1)
...@@ -285,7 +285,6 @@ int sst_dma_new(struct sst_dsp *sst) ...@@ -285,7 +285,6 @@ int sst_dma_new(struct sst_dsp *sst)
* is attached to the ADSP IP. */ * is attached to the ADSP IP. */
switch (sst->pdata->dma_engine) { switch (sst->pdata->dma_engine) {
case SST_DMA_TYPE_DW: case SST_DMA_TYPE_DW:
dma_dev_name = "dw_dmac";
break; break;
default: default:
dev_err(sst->dev, "error: invalid DMA engine %d\n", dev_err(sst->dev, "error: invalid DMA engine %d\n",
......
...@@ -613,8 +613,10 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, ...@@ -613,8 +613,10 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
} }
#define DMA_CONTROL_ID 5 #define DMA_CONTROL_ID 5
#define DMA_I2S_BLOB_SIZE 21
int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig) int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
u32 caps_size, u32 node_id)
{ {
struct skl_dma_control *dma_ctrl; struct skl_dma_control *dma_ctrl;
struct skl_ipc_large_config_msg msg = {0}; struct skl_ipc_large_config_msg msg = {0};
...@@ -624,24 +626,27 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig) ...@@ -624,24 +626,27 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
/* /*
* if blob size zero, then return * if blob size zero, then return
*/ */
if (mconfig->formats_config.caps_size == 0) if (caps_size == 0)
return 0; return 0;
msg.large_param_id = DMA_CONTROL_ID; msg.large_param_id = DMA_CONTROL_ID;
msg.param_data_size = sizeof(struct skl_dma_control) + msg.param_data_size = sizeof(struct skl_dma_control) + caps_size;
mconfig->formats_config.caps_size;
dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL); dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
if (dma_ctrl == NULL) if (dma_ctrl == NULL)
return -ENOMEM; return -ENOMEM;
dma_ctrl->node_id = skl_get_node_id(ctx, mconfig); dma_ctrl->node_id = node_id;
/* size in dwords */ /*
dma_ctrl->config_length = mconfig->formats_config.caps_size / 4; * NHLT blob may contain additional configs along with i2s blob.
* firmware expects only the i2s blob size as the config_length.
* So fix to i2s blob size.
* size in dwords.
*/
dma_ctrl->config_length = DMA_I2S_BLOB_SIZE;
memcpy(dma_ctrl->config_data, mconfig->formats_config.caps, memcpy(dma_ctrl->config_data, caps, caps_size);
mconfig->formats_config.caps_size);
err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl); err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl);
......
...@@ -653,7 +653,7 @@ static const struct snd_soc_dai_ops skl_link_dai_ops = { ...@@ -653,7 +653,7 @@ static const struct snd_soc_dai_ops skl_link_dai_ops = {
.trigger = skl_link_pcm_trigger, .trigger = skl_link_pcm_trigger,
}; };
static struct snd_soc_dai_driver skl_platform_dai[] = { static struct snd_soc_dai_driver skl_fe_dai[] = {
{ {
.name = "System Pin", .name = "System Pin",
.ops = &skl_pcm_dai_ops, .ops = &skl_pcm_dai_ops,
...@@ -797,8 +797,10 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { ...@@ -797,8 +797,10 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.sig_bits = 32, .sig_bits = 32,
}, },
}, },
};
/* BE CPU Dais */ /* BE CPU Dais */
static struct snd_soc_dai_driver skl_platform_dai[] = {
{ {
.name = "SSP0 Pin", .name = "SSP0 Pin",
.ops = &skl_be_ssp_dai_ops, .ops = &skl_be_ssp_dai_ops,
...@@ -976,6 +978,14 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { ...@@ -976,6 +978,14 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
}, },
}; };
int skl_dai_load(struct snd_soc_component *cmp,
struct snd_soc_dai_driver *pcm_dai)
{
pcm_dai->ops = &skl_pcm_dai_ops;
return 0;
}
static int skl_platform_open(struct snd_pcm_substream *substream) static int skl_platform_open(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
...@@ -1363,6 +1373,8 @@ int skl_platform_register(struct device *dev) ...@@ -1363,6 +1373,8 @@ int skl_platform_register(struct device *dev)
int ret; int ret;
struct hdac_ext_bus *ebus = dev_get_drvdata(dev); struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
struct skl *skl = ebus_to_skl(ebus); struct skl *skl = ebus_to_skl(ebus);
struct snd_soc_dai_driver *dais;
int num_dais = ARRAY_SIZE(skl_platform_dai);
INIT_LIST_HEAD(&skl->ppl_list); INIT_LIST_HEAD(&skl->ppl_list);
INIT_LIST_HEAD(&skl->bind_list); INIT_LIST_HEAD(&skl->bind_list);
...@@ -1372,14 +1384,38 @@ int skl_platform_register(struct device *dev) ...@@ -1372,14 +1384,38 @@ int skl_platform_register(struct device *dev)
dev_err(dev, "soc platform registration failed %d\n", ret); dev_err(dev, "soc platform registration failed %d\n", ret);
return ret; return ret;
} }
skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai),
GFP_KERNEL);
if (!skl->dais) {
ret = -ENOMEM;
goto err;
}
if (!skl->use_tplg_pcm) {
dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
sizeof(skl_platform_dai), GFP_KERNEL);
if (!dais) {
ret = -ENOMEM;
goto err;
}
skl->dais = dais;
memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai,
sizeof(skl_fe_dai));
num_dais += ARRAY_SIZE(skl_fe_dai);
}
ret = snd_soc_register_component(dev, &skl_component, ret = snd_soc_register_component(dev, &skl_component,
skl_platform_dai, skl->dais, num_dais);
ARRAY_SIZE(skl_platform_dai));
if (ret) { if (ret) {
dev_err(dev, "soc component registration failed %d\n", ret); dev_err(dev, "soc component registration failed %d\n", ret);
snd_soc_unregister_platform(dev); goto err;
} }
return 0;
err:
snd_soc_unregister_platform(dev);
return ret; return ret;
} }
...@@ -1399,5 +1435,7 @@ int skl_platform_unregister(struct device *dev) ...@@ -1399,5 +1435,7 @@ int skl_platform_unregister(struct device *dev)
snd_soc_unregister_component(dev); snd_soc_unregister_component(dev);
snd_soc_unregister_platform(dev); snd_soc_unregister_platform(dev);
kfree(skl->dais);
return 0; return 0;
} }
...@@ -2036,21 +2036,45 @@ static int skl_tplg_add_pipe(struct device *dev, ...@@ -2036,21 +2036,45 @@ static int skl_tplg_add_pipe(struct device *dev,
return 0; return 0;
} }
static int skl_tplg_fill_pin(struct device *dev, u32 tkn, static int skl_tplg_get_uuid(struct device *dev, u8 *guid,
struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
{
if (uuid_tkn->token == SKL_TKN_UUID) {
memcpy(guid, &uuid_tkn->uuid, 16);
return 0;
}
dev_err(dev, "Not an UUID token %d\n", uuid_tkn->token);
return -EINVAL;
}
static int skl_tplg_fill_pin(struct device *dev,
struct snd_soc_tplg_vendor_value_elem *tkn_elem,
struct skl_module_pin *m_pin, struct skl_module_pin *m_pin,
int pin_index, u32 value) int pin_index)
{ {
switch (tkn) { int ret;
switch (tkn_elem->token) {
case SKL_TKN_U32_PIN_MOD_ID: case SKL_TKN_U32_PIN_MOD_ID:
m_pin[pin_index].id.module_id = value; m_pin[pin_index].id.module_id = tkn_elem->value;
break; break;
case SKL_TKN_U32_PIN_INST_ID: case SKL_TKN_U32_PIN_INST_ID:
m_pin[pin_index].id.instance_id = value; m_pin[pin_index].id.instance_id = tkn_elem->value;
break;
case SKL_TKN_UUID:
ret = skl_tplg_get_uuid(dev, m_pin[pin_index].id.mod_uuid.b,
(struct snd_soc_tplg_vendor_uuid_elem *)tkn_elem);
if (ret < 0)
return ret;
break; break;
default: default:
dev_err(dev, "%d Not a pin token\n", value); dev_err(dev, "%d Not a pin token\n", tkn_elem->token);
return -EINVAL; return -EINVAL;
} }
...@@ -2083,9 +2107,7 @@ static int skl_tplg_fill_pins_info(struct device *dev, ...@@ -2083,9 +2107,7 @@ static int skl_tplg_fill_pins_info(struct device *dev,
return -EINVAL; return -EINVAL;
} }
ret = skl_tplg_fill_pin(dev, tkn_elem->token, ret = skl_tplg_fill_pin(dev, tkn_elem, m_pin, pin_count);
m_pin, pin_count, tkn_elem->value);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -2170,19 +2192,6 @@ static int skl_tplg_widget_fill_fmt(struct device *dev, ...@@ -2170,19 +2192,6 @@ static int skl_tplg_widget_fill_fmt(struct device *dev,
return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val); return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val);
} }
static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig,
struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn)
{
if (uuid_tkn->token == SKL_TKN_UUID)
memcpy(&mconfig->guid, &uuid_tkn->uuid, 16);
else {
dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token);
return -EINVAL;
}
return 0;
}
static void skl_tplg_fill_pin_dynamic_val( static void skl_tplg_fill_pin_dynamic_val(
struct skl_module_pin *mpin, u32 pin_count, u32 value) struct skl_module_pin *mpin, u32 pin_count, u32 value)
{ {
...@@ -2488,6 +2497,7 @@ static int skl_tplg_get_token(struct device *dev, ...@@ -2488,6 +2497,7 @@ static int skl_tplg_get_token(struct device *dev,
case SKL_TKN_U32_PIN_MOD_ID: case SKL_TKN_U32_PIN_MOD_ID:
case SKL_TKN_U32_PIN_INST_ID: case SKL_TKN_U32_PIN_INST_ID:
case SKL_TKN_UUID:
ret = skl_tplg_fill_pins_info(dev, ret = skl_tplg_fill_pins_info(dev,
mconfig, tkn_elem, dir, mconfig, tkn_elem, dir,
pin_index); pin_index);
...@@ -2550,6 +2560,7 @@ static int skl_tplg_get_tokens(struct device *dev, ...@@ -2550,6 +2560,7 @@ static int skl_tplg_get_tokens(struct device *dev,
struct snd_soc_tplg_vendor_value_elem *tkn_elem; struct snd_soc_tplg_vendor_value_elem *tkn_elem;
int tkn_count = 0, ret; int tkn_count = 0, ret;
int off = 0, tuple_size = 0; int off = 0, tuple_size = 0;
bool is_module_guid = true;
if (block_size <= 0) if (block_size <= 0)
return -EINVAL; return -EINVAL;
...@@ -2565,7 +2576,15 @@ static int skl_tplg_get_tokens(struct device *dev, ...@@ -2565,7 +2576,15 @@ static int skl_tplg_get_tokens(struct device *dev,
continue; continue;
case SND_SOC_TPLG_TUPLE_TYPE_UUID: case SND_SOC_TPLG_TUPLE_TYPE_UUID:
ret = skl_tplg_get_uuid(dev, mconfig, array->uuid); if (is_module_guid) {
ret = skl_tplg_get_uuid(dev, mconfig->guid,
array->uuid);
is_module_guid = false;
} else {
ret = skl_tplg_get_token(dev, array->value, skl,
mconfig);
}
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -3331,6 +3350,7 @@ static struct snd_soc_tplg_ops skl_tplg_ops = { ...@@ -3331,6 +3350,7 @@ static struct snd_soc_tplg_ops skl_tplg_ops = {
.io_ops = skl_tplg_kcontrol_ops, .io_ops = skl_tplg_kcontrol_ops,
.io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops), .io_ops_count = ARRAY_SIZE(skl_tplg_kcontrol_ops),
.manifest = skl_manifest_load, .manifest = skl_manifest_load,
.dai_load = skl_dai_load,
}; };
/* /*
...@@ -3404,7 +3424,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus) ...@@ -3404,7 +3424,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
ret = request_firmware(&fw, skl->tplg_name, bus->dev); ret = request_firmware(&fw, skl->tplg_name, bus->dev);
if (ret < 0) { if (ret < 0) {
dev_err(bus->dev, "tplg fw %s load failed with %d\n", dev_info(bus->dev, "tplg fw %s load failed with %d, falling back to dfw_sst.bin",
skl->tplg_name, ret); skl->tplg_name, ret);
ret = request_firmware(&fw, "dfw_sst.bin", bus->dev); ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
if (ret < 0) { if (ret < 0) {
......
...@@ -456,8 +456,8 @@ static inline struct skl *get_skl_ctx(struct device *dev) ...@@ -456,8 +456,8 @@ static inline struct skl *get_skl_ctx(struct device *dev)
int skl_tplg_be_update_params(struct snd_soc_dai *dai, int skl_tplg_be_update_params(struct snd_soc_dai *dai,
struct skl_pipe_params *params); struct skl_pipe_params *params);
int skl_dsp_set_dma_control(struct skl_sst *ctx, int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
struct skl_module_cfg *mconfig); u32 caps_size, u32 node_id);
void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai, void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
struct skl_pipe_params *params, int stream); struct skl_pipe_params *params, int stream);
int skl_tplg_init(struct snd_soc_platform *platform, int skl_tplg_init(struct snd_soc_platform *platform,
...@@ -502,4 +502,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, ...@@ -502,4 +502,7 @@ int skl_pcm_host_dma_prepare(struct device *dev,
struct skl_pipe_params *params); struct skl_pipe_params *params);
int skl_pcm_link_dma_prepare(struct device *dev, int skl_pcm_link_dma_prepare(struct device *dev,
struct skl_pipe_params *params); struct skl_pipe_params *params);
int skl_dai_load(struct snd_soc_component *cmp,
struct snd_soc_dai_driver *pcm_dai);
#endif #endif
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include "../common/sst-acpi.h" #include <sound/soc-acpi.h>
#include <sound/hda_register.h> #include <sound/hda_register.h>
#include <sound/hdaudio.h> #include <sound/hdaudio.h>
#include <sound/hda_i915.h> #include <sound/hda_i915.h>
...@@ -439,10 +439,10 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data) ...@@ -439,10 +439,10 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data)
{ {
struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
struct platform_device *pdev; struct platform_device *pdev;
struct sst_acpi_mach *mach = driver_data; struct snd_soc_acpi_mach *mach = driver_data;
int ret; int ret;
mach = sst_acpi_find_machine(mach); mach = snd_soc_acpi_find_machine(mach);
if (mach == NULL) { if (mach == NULL) {
dev_err(bus->dev, "No matching machine driver found\n"); dev_err(bus->dev, "No matching machine driver found\n");
return -ENODEV; return -ENODEV;
...@@ -462,8 +462,11 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data) ...@@ -462,8 +462,11 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data)
return -EIO; return -EIO;
} }
if (mach->pdata) if (mach->pdata) {
skl->use_tplg_pcm =
((struct skl_machine_pdata *)mach->pdata)->use_tplg_pcm;
dev_set_drvdata(&pdev->dev, mach->pdata); dev_set_drvdata(&pdev->dev, mach->pdata);
}
skl->i2s_dev = pdev; skl->i2s_dev = pdev;
...@@ -875,33 +878,36 @@ static void skl_remove(struct pci_dev *pci) ...@@ -875,33 +878,36 @@ static void skl_remove(struct pci_dev *pci)
dev_set_drvdata(&pci->dev, NULL); dev_set_drvdata(&pci->dev, NULL);
} }
static struct sst_codecs skl_codecs = { static struct snd_soc_acpi_codecs skl_codecs = {
.num_codecs = 1, .num_codecs = 1,
.codecs = {"10508825"} .codecs = {"10508825"}
}; };
static struct sst_codecs kbl_codecs = { static struct snd_soc_acpi_codecs kbl_codecs = {
.num_codecs = 1, .num_codecs = 1,
.codecs = {"10508825"} .codecs = {"10508825"}
}; };
static struct sst_codecs bxt_codecs = { static struct snd_soc_acpi_codecs bxt_codecs = {
.num_codecs = 1, .num_codecs = 1,
.codecs = {"MX98357A"} .codecs = {"MX98357A"}
}; };
static struct sst_codecs kbl_poppy_codecs = { static struct snd_soc_acpi_codecs kbl_poppy_codecs = {
.num_codecs = 1, .num_codecs = 1,
.codecs = {"10EC5663"} .codecs = {"10EC5663"}
}; };
static struct sst_codecs kbl_5663_5514_codecs = { static struct snd_soc_acpi_codecs kbl_5663_5514_codecs = {
.num_codecs = 2, .num_codecs = 2,
.codecs = {"10EC5663", "10EC5514"} .codecs = {"10EC5663", "10EC5514"}
}; };
static struct skl_machine_pdata cnl_pdata = {
.use_tplg_pcm = true,
};
static struct sst_acpi_mach sst_skl_devdata[] = { static struct snd_soc_acpi_mach sst_skl_devdata[] = {
{ {
.id = "INT343A", .id = "INT343A",
.drv_name = "skl_alc286s_i2s", .drv_name = "skl_alc286s_i2s",
...@@ -911,7 +917,7 @@ static struct sst_acpi_mach sst_skl_devdata[] = { ...@@ -911,7 +917,7 @@ static struct sst_acpi_mach sst_skl_devdata[] = {
.id = "INT343B", .id = "INT343B",
.drv_name = "skl_n88l25_s4567", .drv_name = "skl_n88l25_s4567",
.fw_filename = "intel/dsp_fw_release.bin", .fw_filename = "intel/dsp_fw_release.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &skl_codecs, .quirk_data = &skl_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
...@@ -919,14 +925,14 @@ static struct sst_acpi_mach sst_skl_devdata[] = { ...@@ -919,14 +925,14 @@ static struct sst_acpi_mach sst_skl_devdata[] = {
.id = "MX98357A", .id = "MX98357A",
.drv_name = "skl_n88l25_m98357a", .drv_name = "skl_n88l25_m98357a",
.fw_filename = "intel/dsp_fw_release.bin", .fw_filename = "intel/dsp_fw_release.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &skl_codecs, .quirk_data = &skl_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
{} {}
}; };
static struct sst_acpi_mach sst_bxtp_devdata[] = { static struct snd_soc_acpi_mach sst_bxtp_devdata[] = {
{ {
.id = "INT343A", .id = "INT343A",
.drv_name = "bxt_alc298s_i2s", .drv_name = "bxt_alc298s_i2s",
...@@ -936,13 +942,13 @@ static struct sst_acpi_mach sst_bxtp_devdata[] = { ...@@ -936,13 +942,13 @@ static struct sst_acpi_mach sst_bxtp_devdata[] = {
.id = "DLGS7219", .id = "DLGS7219",
.drv_name = "bxt_da7219_max98357a_i2s", .drv_name = "bxt_da7219_max98357a_i2s",
.fw_filename = "intel/dsp_fw_bxtn.bin", .fw_filename = "intel/dsp_fw_bxtn.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &bxt_codecs, .quirk_data = &bxt_codecs,
}, },
{} {}
}; };
static struct sst_acpi_mach sst_kbl_devdata[] = { static struct snd_soc_acpi_mach sst_kbl_devdata[] = {
{ {
.id = "INT343A", .id = "INT343A",
.drv_name = "kbl_alc286s_i2s", .drv_name = "kbl_alc286s_i2s",
...@@ -952,7 +958,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { ...@@ -952,7 +958,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
.id = "INT343B", .id = "INT343B",
.drv_name = "kbl_n88l25_s4567", .drv_name = "kbl_n88l25_s4567",
.fw_filename = "intel/dsp_fw_kbl.bin", .fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_codecs, .quirk_data = &kbl_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
...@@ -960,7 +966,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { ...@@ -960,7 +966,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
.id = "MX98357A", .id = "MX98357A",
.drv_name = "kbl_n88l25_m98357a", .drv_name = "kbl_n88l25_m98357a",
.fw_filename = "intel/dsp_fw_kbl.bin", .fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_codecs, .quirk_data = &kbl_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
...@@ -968,7 +974,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { ...@@ -968,7 +974,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
.id = "MX98927", .id = "MX98927",
.drv_name = "kbl_r5514_5663_max", .drv_name = "kbl_r5514_5663_max",
.fw_filename = "intel/dsp_fw_kbl.bin", .fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_5663_5514_codecs, .quirk_data = &kbl_5663_5514_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
...@@ -976,7 +982,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { ...@@ -976,7 +982,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
.id = "MX98927", .id = "MX98927",
.drv_name = "kbl_rt5663_m98927", .drv_name = "kbl_rt5663_m98927",
.fw_filename = "intel/dsp_fw_kbl.bin", .fw_filename = "intel/dsp_fw_kbl.bin",
.machine_quirk = sst_acpi_codec_list, .machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &kbl_poppy_codecs, .quirk_data = &kbl_poppy_codecs,
.pdata = &skl_dmic_data .pdata = &skl_dmic_data
}, },
...@@ -989,7 +995,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { ...@@ -989,7 +995,7 @@ static struct sst_acpi_mach sst_kbl_devdata[] = {
{} {}
}; };
static struct sst_acpi_mach sst_glk_devdata[] = { static struct snd_soc_acpi_mach sst_glk_devdata[] = {
{ {
.id = "INT343A", .id = "INT343A",
.drv_name = "glk_alc298s_i2s", .drv_name = "glk_alc298s_i2s",
...@@ -998,12 +1004,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = { ...@@ -998,12 +1004,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = {
{} {}
}; };
static const struct sst_acpi_mach sst_cnl_devdata[] = { static const struct snd_soc_acpi_mach sst_cnl_devdata[] = {
{ {
.id = "INT34C2", .id = "INT34C2",
.drv_name = "cnl_rt274", .drv_name = "cnl_rt274",
.fw_filename = "intel/dsp_fw_cnl.bin", .fw_filename = "intel/dsp_fw_cnl.bin",
.pdata = &cnl_pdata,
}, },
{}
}; };
/* PCI IDs */ /* PCI IDs */
......
...@@ -53,6 +53,7 @@ struct skl { ...@@ -53,6 +53,7 @@ struct skl {
struct platform_device *dmic_dev; struct platform_device *dmic_dev;
struct platform_device *i2s_dev; struct platform_device *i2s_dev;
struct snd_soc_platform *platform; struct snd_soc_platform *platform;
struct snd_soc_dai_driver *dais;
struct nhlt_acpi_table *nhlt; /* nhlt ptr */ struct nhlt_acpi_table *nhlt; /* nhlt ptr */
struct skl_sst *skl_sst; /* sst skl ctx */ struct skl_sst *skl_sst; /* sst skl ctx */
...@@ -73,6 +74,7 @@ struct skl { ...@@ -73,6 +74,7 @@ struct skl {
struct skl_debug *debugfs; struct skl_debug *debugfs;
u8 nr_modules; u8 nr_modules;
struct skl_module **modules; struct skl_module **modules;
bool use_tplg_pcm;
}; };
#define skl_to_ebus(s) (&(s)->ebus) #define skl_to_ebus(s) (&(s)->ebus)
...@@ -85,9 +87,9 @@ struct skl_dma_params { ...@@ -85,9 +87,9 @@ struct skl_dma_params {
u8 stream_tag; u8 stream_tag;
}; };
/* to pass dmic data */
struct skl_machine_pdata { struct skl_machine_pdata {
u32 dmic_num; u32 dmic_num;
bool use_tplg_pcm; /* use dais and dai links from topology */
}; };
struct skl_dsp_ops { struct skl_dsp_ops {
......
/* /*
* sst_match_apci.c - SST (LPE) match for ACPI enumeration. * soc-apci.c - support for ACPI enumeration.
* *
* Copyright (c) 2013-15, Intel Corporation. * Copyright (c) 2013-15, Intel Corporation.
* *
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
* more details. * more details.
*/ */
#include "sst-acpi.h" #include <sound/soc-acpi.h>
static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level, static acpi_status snd_soc_acpi_find_name(acpi_handle handle, u32 level,
void *context, void **ret) void *context, void **ret)
{ {
struct acpi_device *adev; struct acpi_device *adev;
...@@ -34,12 +34,12 @@ static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level, ...@@ -34,12 +34,12 @@ static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level,
return AE_OK; return AE_OK;
} }
const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
{ {
const char *name = NULL; const char *name = NULL;
acpi_status status; acpi_status status;
status = acpi_get_devices(hid, sst_acpi_find_name, NULL, status = acpi_get_devices(hid, snd_soc_acpi_find_name, NULL,
(void **)&name); (void **)&name);
if (ACPI_FAILURE(status) || name[0] == '\0') if (ACPI_FAILURE(status) || name[0] == '\0')
...@@ -47,9 +47,9 @@ const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) ...@@ -47,9 +47,9 @@ const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
return name; return name;
} }
EXPORT_SYMBOL_GPL(sst_acpi_find_name_from_hid); EXPORT_SYMBOL_GPL(snd_soc_acpi_find_name_from_hid);
static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level, static acpi_status snd_soc_acpi_mach_match(acpi_handle handle, u32 level,
void *context, void **ret) void *context, void **ret)
{ {
unsigned long long sta; unsigned long long sta;
...@@ -63,26 +63,27 @@ static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level, ...@@ -63,26 +63,27 @@ static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
return AE_OK; return AE_OK;
} }
bool sst_acpi_check_hid(const u8 hid[ACPI_ID_LEN]) bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN])
{ {
acpi_status status; acpi_status status;
bool found = false; bool found = false;
status = acpi_get_devices(hid, sst_acpi_mach_match, &found, NULL); status = acpi_get_devices(hid, snd_soc_acpi_mach_match, &found, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return false; return false;
return found; return found;
} }
EXPORT_SYMBOL_GPL(sst_acpi_check_hid); EXPORT_SYMBOL_GPL(snd_soc_acpi_check_hid);
struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines) struct snd_soc_acpi_mach *
snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines)
{ {
struct sst_acpi_mach *mach; struct snd_soc_acpi_mach *mach;
for (mach = machines; mach->id[0]; mach++) { for (mach = machines; mach->id[0]; mach++) {
if (sst_acpi_check_hid(mach->id) == true) { if (snd_soc_acpi_check_hid(mach->id) == true) {
if (mach->machine_quirk == NULL) if (mach->machine_quirk == NULL)
return mach; return mach;
...@@ -92,14 +93,14 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines) ...@@ -92,14 +93,14 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(sst_acpi_find_machine); EXPORT_SYMBOL_GPL(snd_soc_acpi_find_machine);
static acpi_status sst_acpi_find_package(acpi_handle handle, u32 level, static acpi_status snd_soc_acpi_find_package(acpi_handle handle, u32 level,
void *context, void **ret) void *context, void **ret)
{ {
struct acpi_device *adev; struct acpi_device *adev;
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct sst_acpi_package_context *pkg_ctx = context; struct snd_soc_acpi_package_context *pkg_ctx = context;
pkg_ctx->data_valid = false; pkg_ctx->data_valid = false;
...@@ -137,37 +138,38 @@ static acpi_status sst_acpi_find_package(acpi_handle handle, u32 level, ...@@ -137,37 +138,38 @@ static acpi_status sst_acpi_find_package(acpi_handle handle, u32 level,
return AE_OK; return AE_OK;
} }
bool sst_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN],
struct sst_acpi_package_context *ctx) struct snd_soc_acpi_package_context *ctx)
{ {
acpi_status status; acpi_status status;
status = acpi_get_devices(hid, sst_acpi_find_package, ctx, NULL); status = acpi_get_devices(hid, snd_soc_acpi_find_package, ctx, NULL);
if (ACPI_FAILURE(status) || !ctx->data_valid) if (ACPI_FAILURE(status) || !ctx->data_valid)
return false; return false;
return true; return true;
} }
EXPORT_SYMBOL_GPL(sst_acpi_find_package_from_hid); EXPORT_SYMBOL_GPL(snd_soc_acpi_find_package_from_hid);
struct sst_acpi_mach *sst_acpi_codec_list(void *arg) struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
{ {
struct sst_acpi_mach *mach = arg; struct snd_soc_acpi_mach *mach = arg;
struct sst_codecs *codec_list = (struct sst_codecs *) mach->quirk_data; struct snd_soc_acpi_codecs *codec_list =
(struct snd_soc_acpi_codecs *) mach->quirk_data;
int i; int i;
if (mach->quirk_data == NULL) if (mach->quirk_data == NULL)
return mach; return mach;
for (i = 0; i < codec_list->num_codecs; i++) { for (i = 0; i < codec_list->num_codecs; i++) {
if (sst_acpi_check_hid(codec_list->codecs[i]) != true) if (snd_soc_acpi_check_hid(codec_list->codecs[i]) != true)
return NULL; return NULL;
} }
return mach; return mach;
} }
EXPORT_SYMBOL_GPL(sst_acpi_codec_list); EXPORT_SYMBOL_GPL(snd_soc_acpi_codec_list);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module"); MODULE_DESCRIPTION("ALSA SoC ACPI module");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment