summaryrefslogtreecommitdiffstats
path: root/include/sound
diff options
context:
space:
mode:
Diffstat (limited to 'include/sound')
-rw-r--r--include/sound/ac97_codec.h5
-rw-r--r--include/sound/aess.h53
-rw-r--r--include/sound/control.h10
-rw-r--r--include/sound/core.h8
-rw-r--r--include/sound/dmaengine_pcm.h5
-rw-r--r--include/sound/hda_codec.h3
-rw-r--r--include/sound/hda_register.h3
-rw-r--r--include/sound/hda_regmap.h3
-rw-r--r--include/sound/hdaudio.h111
-rw-r--r--include/sound/hdaudio_ext.h1
-rw-r--r--include/sound/hdmi-codec.h17
-rw-r--r--include/sound/info.h2
-rw-r--r--include/sound/initval.h6
-rw-r--r--include/sound/intel-dsp-config.h34
-rw-r--r--include/sound/intel-nhlt.h150
-rw-r--r--include/sound/memalloc.h2
-rw-r--r--include/sound/pcm.h99
-rw-r--r--include/sound/pxa2xx-lib.h26
-rw-r--r--include/sound/rt5682.h1
-rw-r--r--include/sound/seq_midi_emul.h3
-rw-r--r--include/sound/simple_card_utils.h9
-rw-r--r--include/sound/soc-acpi-intel-match.h11
-rw-r--r--include/sound/soc-acpi.h25
-rw-r--r--include/sound/soc-component.h421
-rw-r--r--include/sound/soc-dai.h29
-rw-r--r--include/sound/soc-dapm.h17
-rw-r--r--include/sound/soc-dpcm.h25
-rw-r--r--include/sound/soc.h417
-rw-r--r--include/sound/sof.h12
-rw-r--r--include/sound/sof/channel_map.h61
-rw-r--r--include/sound/sof/dai-imx.h54
-rw-r--r--include/sound/sof/dai-intel.h12
-rw-r--r--include/sound/sof/dai.h8
-rw-r--r--include/sound/sof/header.h2
-rw-r--r--include/sound/sof/info.h15
-rw-r--r--include/sound/sof/pm.h8
-rw-r--r--include/sound/sof/stream.h4
-rw-r--r--include/sound/sof/topology.h27
-rw-r--r--include/sound/timer.h10
-rw-r--r--include/sound/vx_core.h9
-rw-r--r--include/sound/wm8904.h2
41 files changed, 1184 insertions, 536 deletions
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index cc383991c0fe..49200ec26dc4 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -197,7 +197,7 @@ struct snd_ac97_bus_ops {
struct snd_ac97_bus {
/* -- lowlevel (hardware) driver specific -- */
- struct snd_ac97_bus_ops *ops;
+ const struct snd_ac97_bus_ops *ops;
void *private_data;
void (*private_free) (struct snd_ac97_bus *bus);
/* --- */
@@ -310,7 +310,8 @@ static inline int ac97_can_spdif(struct snd_ac97 * ac97)
/* functions */
/* create new AC97 bus */
-int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
+int snd_ac97_bus(struct snd_card *card, int num,
+ const struct snd_ac97_bus_ops *ops,
void *private_data, struct snd_ac97_bus **rbus);
/* create mixer controls */
int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
diff --git a/include/sound/aess.h b/include/sound/aess.h
deleted file mode 100644
index cee0d09fadbd..000000000000
--- a/include/sound/aess.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * AESS IP block reset
- *
- * Copyright (C) 2012 Texas Instruments, Inc.
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-#ifndef __SOUND_AESS_H__
-#define __SOUND_AESS_H__
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-
-/*
- * AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
- * block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's
- * base address
- */
-#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c
-
-/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */
-#define AESS_AUTO_GATING_ENABLE_SHIFT 0
-
-/**
- * aess_enable_autogating - enable AESS internal autogating
- * @oh: struct omap_hwmod *
- *
- * Enable internal autogating on the AESS. This allows the AESS to
- * indicate that it is idle to the OMAP PRCM. Returns 0.
- */
-static inline void aess_enable_autogating(void __iomem *base)
-{
- u32 v;
-
- /* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */
- v = 1 << AESS_AUTO_GATING_ENABLE_SHIFT;
- writel(v, base + AESS_AUTO_GATING_ENABLE_OFFSET);
-}
-
-#endif /* __SOUND_AESS_H__ */
diff --git a/include/sound/control.h b/include/sound/control.h
index 5d7c99475684..11feeee31e35 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -22,6 +22,16 @@ typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
unsigned int size,
unsigned int __user *tlv);
+/* internal flag for skipping validations */
+#ifdef CONFIG_SND_CTL_VALIDATION
+#define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK (1 << 27)
+#define snd_ctl_skip_validation(info) \
+ ((info)->access & SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK)
+#else
+#define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK 0
+#define snd_ctl_skip_validation(info) true
+#endif
+
enum {
SNDRV_CTL_TLV_OP_READ = 0,
SNDRV_CTL_TLV_OP_WRITE = 1,
diff --git a/include/sound/core.h b/include/sound/core.h
index ee238f100f73..ac8b692b69b4 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -69,7 +69,7 @@ struct snd_device {
enum snd_device_state state; /* state of the device */
enum snd_device_type type; /* device type */
void *device_data; /* device structure */
- struct snd_device_ops *ops; /* operations */
+ const struct snd_device_ops *ops; /* operations */
};
#define snd_device(n) list_entry(n, struct snd_device, list)
@@ -117,8 +117,12 @@ struct snd_card {
struct device card_dev; /* cardX object for sysfs */
const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
bool registered; /* card_dev is registered? */
+ int sync_irq; /* assigned irq, used for PCM sync */
wait_queue_head_t remove_sleep;
+ size_t total_pcm_alloc_bytes; /* total amount of allocated buffers */
+ struct mutex memory_mutex; /* protection for the above */
+
#ifdef CONFIG_PM
unsigned int power_state; /* power state */
wait_queue_head_t power_sleep;
@@ -255,7 +259,7 @@ static inline void snd_card_unref(struct snd_card *card)
/* device.c */
int snd_device_new(struct snd_card *card, enum snd_device_type type,
- void *device_data, struct snd_device_ops *ops);
+ void *device_data, const struct snd_device_ops *ops);
int snd_device_register(struct snd_card *card, void *device_data);
int snd_device_register_all(struct snd_card *card);
void snd_device_disconnect(struct snd_card *card, void *device_data);
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index c679f6116580..b65220685920 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -83,6 +83,11 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
const struct snd_dmaengine_dai_dma_data *dma_data,
struct dma_slave_config *config);
+int snd_dmaengine_pcm_refine_runtime_hwparams(
+ struct snd_pcm_substream *substream,
+ struct snd_dmaengine_dai_dma_data *dma_data,
+ struct snd_pcm_hardware *hw,
+ struct dma_chan *chan);
/*
* Try to request the DMA channel using compat_request_channel or
diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index 871993696c5f..3ee8036f5436 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -51,7 +51,6 @@ struct hda_bus {
DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
/* misc op flags */
- unsigned int needs_damn_long_delay :1;
unsigned int allow_bus_reset:1; /* allow bus reset at fatal error */
/* status for codec/controller */
unsigned int shutdown :1; /* being unloaded */
@@ -59,6 +58,7 @@ struct hda_bus {
unsigned int in_reset:1; /* during reset operation */
unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
unsigned int bus_probing :1; /* during probing process */
+ unsigned int keep_power:1; /* keep power up for notification */
int primary_dig_out_type; /* primary digital out PCM type */
unsigned int mixer_assigned; /* codec addr for mixer name */
@@ -253,6 +253,7 @@ struct hda_codec {
unsigned int force_pin_prefix:1; /* Add location prefix */
unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
+ unsigned int mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */
#ifdef CONFIG_PM
unsigned long power_on_acct;
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
index 0fd39295b426..057d2a2d0bd0 100644
--- a/include/sound/hda_register.h
+++ b/include/sound/hda_register.h
@@ -264,6 +264,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_REG_ML_LOUTPAY 0x20
#define AZX_REG_ML_LINPAY 0x30
+/* bit0 is reserved, with BIT(1) mapping to stream1 */
+#define ML_LOSIDV_STREAM_MASK 0xFFFE
+
#define ML_LCTL_SCF_MASK 0xF
#define AZX_MLCTL_SPA (0x1 << 16)
#define AZX_MLCTL_CPA (0x1 << 23)
diff --git a/include/sound/hda_regmap.h b/include/sound/hda_regmap.h
index 5141f8ffbb12..4c1b9bebbd60 100644
--- a/include/sound/hda_regmap.h
+++ b/include/sound/hda_regmap.h
@@ -24,6 +24,9 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
unsigned int val);
int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
unsigned int mask, unsigned int val);
+int snd_hdac_regmap_update_raw_once(struct hdac_device *codec, unsigned int reg,
+ unsigned int mask, unsigned int val);
+void snd_hdac_regmap_sync(struct hdac_device *codec);
/**
* snd_hdac_regmap_encode_verb - encode the verb to a pseudo register
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 612a17e375d0..d4299e146d95 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -8,6 +8,7 @@
#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/timecounter.h>
#include <sound/core.h>
@@ -86,6 +87,7 @@ struct hdac_device {
/* regmap */
struct regmap *regmap;
+ struct mutex regmap_lock;
struct snd_array vendor_verbs;
bool lazy_cache:1; /* don't wake up for writes */
bool caps_overwriting:1; /* caps overwrite being in process */
@@ -122,10 +124,6 @@ int snd_hdac_codec_modalias(struct hdac_device *hdac, char *buf, size_t size);
int snd_hdac_refresh_widgets(struct hdac_device *codec);
-unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
- unsigned int verb, unsigned int parm);
-int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd,
- unsigned int flags, unsigned int *res);
int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
unsigned int verb, unsigned int parm, unsigned int *res);
int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
@@ -253,24 +251,6 @@ struct hdac_ext_bus_ops {
int (*hdev_detach)(struct hdac_device *hdev);
};
-/*
- * Lowlevel I/O operators
- */
-struct hdac_io_ops {
- /* mapped register accesses */
- void (*reg_writel)(u32 value, u32 __iomem *addr);
- u32 (*reg_readl)(u32 __iomem *addr);
- void (*reg_writew)(u16 value, u16 __iomem *addr);
- u16 (*reg_readw)(u16 __iomem *addr);
- void (*reg_writeb)(u8 value, u8 __iomem *addr);
- u8 (*reg_readb)(u8 __iomem *addr);
- /* Allocation ops */
- int (*dma_alloc_pages)(struct hdac_bus *bus, int type, size_t size,
- struct snd_dma_buffer *buf);
- void (*dma_free_pages)(struct hdac_bus *bus,
- struct snd_dma_buffer *buf);
-};
-
#define HDA_UNSOL_QUEUE_SIZE 64
#define HDA_MAX_CODECS 8 /* limit by controller side */
@@ -304,7 +284,6 @@ struct hdac_rb {
struct hdac_bus {
struct device *dev;
const struct hdac_bus_ops *ops;
- const struct hdac_io_ops *io_ops;
const struct hdac_ext_bus_ops *ext_ops;
/* h/w resources */
@@ -340,10 +319,12 @@ struct hdac_bus {
struct hdac_rb corb;
struct hdac_rb rirb;
unsigned int last_cmd[HDA_MAX_CODECS]; /* last sent command */
+ wait_queue_head_t rirb_wq;
/* CORB/RIRB and position buffers */
struct snd_dma_buffer rb;
struct snd_dma_buffer posbuf;
+ int dma_type; /* SNDRV_DMA_TYPE_XXX for CORB/RIRB */
/* hdac_stream linked list */
struct list_head stream_list;
@@ -352,6 +333,7 @@ struct hdac_bus {
bool chip_init:1; /* h/w initialized */
/* behavior flags */
+ bool aligned_mmio:1; /* aligned MMIO access */
bool sync_write:1; /* sync after verb write */
bool use_posbuf:1; /* use position buffer */
bool snoop:1; /* enable snooping */
@@ -359,6 +341,7 @@ struct hdac_bus {
bool reverse_assign:1; /* assign devices in reverse order */
bool corbrp_self_clear:1; /* CORBRP clears itself after reset */
bool polling_mode:1;
+ bool needs_damn_long_delay:1;
int poll_count;
@@ -384,8 +367,7 @@ struct hdac_bus {
};
int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
- const struct hdac_bus_ops *ops,
- const struct hdac_io_ops *io_ops);
+ const struct hdac_bus_ops *ops);
void snd_hdac_bus_exit(struct hdac_bus *bus);
int snd_hdac_bus_exec_verb(struct hdac_bus *bus, unsigned int addr,
unsigned int cmd, unsigned int *res);
@@ -393,11 +375,6 @@ int snd_hdac_bus_exec_verb_unlocked(struct hdac_bus *bus, unsigned int addr,
unsigned int cmd, unsigned int *res);
void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
-int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
-void snd_hdac_bus_remove_device(struct hdac_bus *bus,
- struct hdac_device *codec);
-void snd_hdac_bus_process_unsol_events(struct work_struct *work);
-
static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
{
set_bit(codec->addr, &codec->bus->codec_powered);
@@ -429,21 +406,65 @@ int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
int snd_hdac_bus_alloc_stream_pages(struct hdac_bus *bus);
void snd_hdac_bus_free_stream_pages(struct hdac_bus *bus);
+#ifdef CONFIG_SND_HDA_ALIGNED_MMIO
+unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask);
+void snd_hdac_aligned_write(unsigned int val, void __iomem *addr,
+ unsigned int mask);
+#define snd_hdac_aligned_mmio(bus) (bus)->aligned_mmio
+#else
+#define snd_hdac_aligned_mmio(bus) false
+#define snd_hdac_aligned_read(addr, mask) 0
+#define snd_hdac_aligned_write(val, addr, mask) do {} while (0)
+#endif
+
+static inline void snd_hdac_reg_writeb(struct hdac_bus *bus, void __iomem *addr,
+ u8 val)
+{
+ if (snd_hdac_aligned_mmio(bus))
+ snd_hdac_aligned_write(val, addr, 0xff);
+ else
+ writeb(val, addr);
+}
+
+static inline void snd_hdac_reg_writew(struct hdac_bus *bus, void __iomem *addr,
+ u16 val)
+{
+ if (snd_hdac_aligned_mmio(bus))
+ snd_hdac_aligned_write(val, addr, 0xffff);
+ else
+ writew(val, addr);
+}
+
+static inline u8 snd_hdac_reg_readb(struct hdac_bus *bus, void __iomem *addr)
+{
+ return snd_hdac_aligned_mmio(bus) ?
+ snd_hdac_aligned_read(addr, 0xff) : readb(addr);
+}
+
+static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr)
+{
+ return snd_hdac_aligned_mmio(bus) ?
+ snd_hdac_aligned_read(addr, 0xffff) : readw(addr);
+}
+
+#define snd_hdac_reg_writel(bus, addr, val) writel(val, addr)
+#define snd_hdac_reg_readl(bus, addr) readl(addr)
+
/*
* macros for easy use
*/
#define _snd_hdac_chip_writeb(chip, reg, value) \
- ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + (reg)))
+ snd_hdac_reg_writeb(chip, (chip)->remap_addr + (reg), value)
#define _snd_hdac_chip_readb(chip, reg) \
- ((chip)->io_ops->reg_readb((chip)->remap_addr + (reg)))
+ snd_hdac_reg_readb(chip, (chip)->remap_addr + (reg))
#define _snd_hdac_chip_writew(chip, reg, value) \
- ((chip)->io_ops->reg_writew(value, (chip)->remap_addr + (reg)))
+ snd_hdac_reg_writew(chip, (chip)->remap_addr + (reg), value)
#define _snd_hdac_chip_readw(chip, reg) \
- ((chip)->io_ops->reg_readw((chip)->remap_addr + (reg)))
+ snd_hdac_reg_readw(chip, (chip)->remap_addr + (reg))
#define _snd_hdac_chip_writel(chip, reg, value) \
- ((chip)->io_ops->reg_writel(value, (chip)->remap_addr + (reg)))
+ snd_hdac_reg_writel(chip, (chip)->remap_addr + (reg), value)
#define _snd_hdac_chip_readl(chip, reg) \
- ((chip)->io_ops->reg_readl((chip)->remap_addr + (reg)))
+ snd_hdac_reg_readl(chip, (chip)->remap_addr + (reg))
/* read/write a register, pass without AZX_REG_ prefix */
#define snd_hdac_chip_writel(chip, reg, value) \
@@ -504,6 +525,7 @@ struct hdac_stream {
bool prepared:1;
bool no_period_wakeup:1;
bool locked:1;
+ bool stripe:1; /* apply stripe control */
/* timestamp */
unsigned long start_wallclk; /* start + minimum wallclk */
@@ -548,24 +570,19 @@ int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus,
/*
* macros for easy use
*/
-#define _snd_hdac_stream_write(type, dev, reg, value) \
- ((dev)->bus->io_ops->reg_write ## type(value, (dev)->sd_addr + (reg)))
-#define _snd_hdac_stream_read(type, dev, reg) \
- ((dev)->bus->io_ops->reg_read ## type((dev)->sd_addr + (reg)))
-
/* read/write a register, pass without AZX_REG_ prefix */
#define snd_hdac_stream_writel(dev, reg, value) \
- _snd_hdac_stream_write(l, dev, AZX_REG_ ## reg, value)
+ snd_hdac_reg_writel((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
#define snd_hdac_stream_writew(dev, reg, value) \
- _snd_hdac_stream_write(w, dev, AZX_REG_ ## reg, value)
+ snd_hdac_reg_writew((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
#define snd_hdac_stream_writeb(dev, reg, value) \
- _snd_hdac_stream_write(b, dev, AZX_REG_ ## reg, value)
+ snd_hdac_reg_writeb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg, value)
#define snd_hdac_stream_readl(dev, reg) \
- _snd_hdac_stream_read(l, dev, AZX_REG_ ## reg)
+ snd_hdac_reg_readl((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
#define snd_hdac_stream_readw(dev, reg) \
- _snd_hdac_stream_read(w, dev, AZX_REG_ ## reg)
+ snd_hdac_reg_readw((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
#define snd_hdac_stream_readb(dev, reg) \
- _snd_hdac_stream_read(b, dev, AZX_REG_ ## reg)
+ snd_hdac_reg_readb((dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
/* update a register, pass without AZX_REG_ prefix */
#define snd_hdac_stream_updatel(dev, reg, mask, val) \
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
index f34aced69ca8..ef88b20c7b0a 100644
--- a/include/sound/hdaudio_ext.h
+++ b/include/sound/hdaudio_ext.h
@@ -6,7 +6,6 @@
int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
const struct hdac_bus_ops *ops,
- const struct hdac_io_ops *io_ops,
const struct hdac_ext_bus_ops *ext_ops);
void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h
index 7fea496f1f34..83b17682e01c 100644
--- a/include/sound/hdmi-codec.h
+++ b/include/sound/hdmi-codec.h
@@ -47,6 +47,9 @@ struct hdmi_codec_params {
int channels;
};
+typedef void (*hdmi_codec_plugged_cb)(struct device *dev,
+ bool plugged);
+
struct hdmi_codec_pdata;
struct hdmi_codec_ops {
/*
@@ -88,6 +91,14 @@ struct hdmi_codec_ops {
*/
int (*get_dai_id)(struct snd_soc_component *comment,
struct device_node *endpoint);
+
+ /*
+ * Hook callback function to handle connector plug event.
+ * Optional
+ */
+ int (*hook_plugged_cb)(struct device *dev, void *data,
+ hdmi_codec_plugged_cb fn,
+ struct device *codec_dev);
};
/* HDMI codec initalization data */
@@ -99,6 +110,12 @@ struct hdmi_codec_pdata {
void *data;
};
+struct snd_soc_component;
+struct snd_soc_jack;
+
+int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
+ struct snd_soc_jack *jack);
+
#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
#endif /* __HDMI_CODEC_H__ */
diff --git a/include/sound/info.h b/include/sound/info.h
index b01a22913400..7c13bf52cc81 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -64,7 +64,7 @@ struct snd_info_entry {
unsigned short content;
union {
struct snd_info_entry_text text;
- struct snd_info_entry_ops *ops;
+ const struct snd_info_entry_ops *ops;
} c;
struct snd_info_entry *parent;
struct module *module;
diff --git a/include/sound/initval.h b/include/sound/initval.h
index 3ddae2b4177e..a1ff3b4865b4 100644
--- a/include/sound/initval.h
+++ b/include/sound/initval.h
@@ -37,7 +37,7 @@
#define SNDRV_DEFAULT_PTR SNDRV_DEFAULT_STR
#ifdef SNDRV_LEGACY_FIND_FREE_IOPORT
-static long snd_legacy_find_free_ioport(long *port_table, long size)
+static long snd_legacy_find_free_ioport(const long *port_table, long size)
{
while (*port_table != -1) {
if (request_region(*port_table, size, "ALSA test")) {
@@ -58,7 +58,7 @@ static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int snd_legacy_find_free_irq(int *irq_table)
+static int snd_legacy_find_free_irq(const int *irq_table)
{
while (*irq_table != -1) {
if (!request_irq(*irq_table, snd_legacy_empty_irq_handler,
@@ -74,7 +74,7 @@ static int snd_legacy_find_free_irq(int *irq_table)
#endif
#ifdef SNDRV_LEGACY_FIND_FREE_DMA
-static int snd_legacy_find_free_dma(int *dma_table)
+static int snd_legacy_find_free_dma(const int *dma_table)
{
while (*dma_table != -1) {
if (!request_dma(*dma_table, "ALSA Test DMA")) {
diff --git a/include/sound/intel-dsp-config.h b/include/sound/intel-dsp-config.h
new file mode 100644
index 000000000000..c36622bee3f8
--- /dev/null
+++ b/include/sound/intel-dsp-config.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * intel-dsp-config.h - Intel DSP config
+ *
+ * Copyright (c) 2019 Jaroslav Kysela <perex@perex.cz>
+ */
+
+#ifndef __INTEL_DSP_CONFIG_H__
+#define __INTEL_DSP_CONFIG_H__
+
+struct pci_dev;
+
+enum {
+ SND_INTEL_DSP_DRIVER_ANY = 0,
+ SND_INTEL_DSP_DRIVER_LEGACY,
+ SND_INTEL_DSP_DRIVER_SST,
+ SND_INTEL_DSP_DRIVER_SOF,
+ SND_INTEL_DSP_DRIVER_LAST = SND_INTEL_DSP_DRIVER_SOF
+};
+
+#if IS_ENABLED(CONFIG_SND_INTEL_DSP_CONFIG)
+
+int snd_intel_dsp_driver_probe(struct pci_dev *pci);
+
+#else
+
+static inline int snd_intel_dsp_driver_probe(struct pci_dev *pci)
+{
+ return SND_INTEL_DSP_DRIVER_ANY;
+}
+
+#endif
+
+#endif
diff --git a/include/sound/intel-nhlt.h b/include/sound/intel-nhlt.h
new file mode 100644
index 000000000000..f657fd8fc0ad
--- /dev/null
+++ b/include/sound/intel-nhlt.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * intel-nhlt.h - Intel HDA Platform NHLT header
+ *
+ * Copyright (c) 2015-2019 Intel Corporation
+ */
+
+#ifndef __INTEL_NHLT_H__
+#define __INTEL_NHLT_H__
+
+#include <linux/acpi.h>
+
+#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
+
+struct wav_fmt {
+ u16 fmt_tag;
+ u16 channels;
+ u32 samples_per_sec;
+ u32 avg_bytes_per_sec;
+ u16 block_align;
+ u16 bits_per_sample;
+ u16 cb_size;
+} __packed;
+
+struct wav_fmt_ext {
+ struct wav_fmt fmt;
+ union samples {
+ u16 valid_bits_per_sample;
+ u16 samples_per_block;
+ u16 reserved;
+ } sample;
+ u32 channel_mask;
+ u8 sub_fmt[16];
+} __packed;
+
+enum nhlt_link_type {
+ NHLT_LINK_HDA = 0,
+ NHLT_LINK_DSP = 1,
+ NHLT_LINK_DMIC = 2,
+ NHLT_LINK_SSP = 3,
+ NHLT_LINK_INVALID
+};
+
+enum nhlt_device_type {
+ NHLT_DEVICE_BT = 0,
+ NHLT_DEVICE_DMIC = 1,
+ NHLT_DEVICE_I2S = 4,
+ NHLT_DEVICE_INVALID
+};
+
+struct nhlt_specific_cfg {
+ u32 size;
+ u8 caps[0];
+} __packed;
+
+struct nhlt_fmt_cfg {
+ struct wav_fmt_ext fmt_ext;
+ struct nhlt_specific_cfg config;
+} __packed;
+
+struct nhlt_fmt {
+ u8 fmt_count;
+ struct nhlt_fmt_cfg fmt_config[0];
+} __packed;
+
+struct nhlt_endpoint {
+ u32 length;
+ u8 linktype;
+ u8 instance_id;
+ u16 vendor_id;
+ u16 device_id;
+ u16 revision_id;
+ u32 subsystem_id;
+ u8 device_type;
+ u8 direction;
+ u8 virtual_bus_id;
+ struct nhlt_specific_cfg config;
+} __packed;
+
+struct nhlt_acpi_table {
+ struct acpi_table_header header;
+ u8 endpoint_count;
+ struct nhlt_endpoint desc[0];
+} __packed;
+
+struct nhlt_resource_desc {
+ u32 extra;
+ u16 flags;
+ u64 addr_spc_gra;
+ u64 min_addr;
+ u64 max_addr;
+ u64 addr_trans_offset;
+ u64 length;
+} __packed;
+
+#define MIC_ARRAY_2CH 2
+#define MIC_ARRAY_4CH 4
+
+struct nhlt_device_specific_config {
+ u8 virtual_slot;
+ u8 config_type;
+} __packed;
+
+struct nhlt_dmic_array_config {
+ struct nhlt_device_specific_config device_config;
+ u8 array_type;
+} __packed;
+
+struct nhlt_vendor_dmic_array_config {
+ struct nhlt_dmic_array_config dmic_config;
+ u8 nb_mics;
+ /* TODO add vendor mic config */
+} __packed;
+
+enum {
+ NHLT_MIC_ARRAY_2CH_SMALL = 0xa,
+ NHLT_MIC_ARRAY_2CH_BIG = 0xb,
+ NHLT_MIC_ARRAY_4CH_1ST_GEOM = 0xc,
+ NHLT_MIC_ARRAY_4CH_L_SHAPED = 0xd,
+ NHLT_MIC_ARRAY_4CH_2ND_GEOM = 0xe,
+ NHLT_MIC_ARRAY_VENDOR_DEFINED = 0xf,
+};
+
+struct nhlt_acpi_table *intel_nhlt_init(struct device *dev);
+
+void intel_nhlt_free(struct nhlt_acpi_table *addr);
+
+int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt);
+
+#else
+
+struct nhlt_acpi_table;
+
+static inline struct nhlt_acpi_table *intel_nhlt_init(struct device *dev)
+{
+ return NULL;
+}
+
+static inline void intel_nhlt_free(struct nhlt_acpi_table *addr)
+{
+}
+
+static inline int intel_nhlt_get_dmic_geo(struct device *dev,
+ struct nhlt_acpi_table *nhlt)
+{
+ return 0;
+}
+#endif
+
+#endif
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index 240622d89c0b..3b47832b1c1f 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -21,7 +21,6 @@ struct snd_dma_device {
struct device *dev; /* generic device */
};
-#define snd_dma_pci_data(pci) (&(pci)->dev)
#define snd_dma_continuous_data(x) ((struct device *)(__force unsigned long)(x))
@@ -44,6 +43,7 @@ struct snd_dma_device {
#else
#define SNDRV_DMA_TYPE_DEV_IRAM SNDRV_DMA_TYPE_DEV
#endif
+#define SNDRV_DMA_TYPE_VMALLOC 7 /* vmalloc'ed buffer */
/*
* info for buffer allocation
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 1e9bb1c91770..f657ff08f317 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -44,6 +44,7 @@ struct snd_pcm_hardware {
size_t fifo_size; /* fifo size in bytes */
};
+struct snd_pcm_status64;
struct snd_pcm_substream;
struct snd_pcm_audio_tstamp_config; /* definitions further down */
@@ -59,9 +60,10 @@ struct snd_pcm_ops {
int (*hw_free)(struct snd_pcm_substream *substream);
int (*prepare)(struct snd_pcm_substream *substream);
int (*trigger)(struct snd_pcm_substream *substream, int cmd);
+ int (*sync_stop)(struct snd_pcm_substream *substream);
snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
int (*get_time_info)(struct snd_pcm_substream *substream,
- struct timespec *system_ts, struct timespec *audio_ts,
+ struct timespec64 *system_ts, struct timespec64 *audio_ts,
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
int (*fill_silence)(struct snd_pcm_substream *substream, int channel,
@@ -117,6 +119,8 @@ struct snd_pcm_ops {
#define SNDRV_PCM_RATE_96000 (1<<10) /* 96000Hz */
#define SNDRV_PCM_RATE_176400 (1<<11) /* 176400Hz */
#define SNDRV_PCM_RATE_192000 (1<<12) /* 192000Hz */
+#define SNDRV_PCM_RATE_352800 (1<<13) /* 352800Hz */
+#define SNDRV_PCM_RATE_384000 (1<<14) /* 384000Hz */
#define SNDRV_PCM_RATE_CONTINUOUS (1<<30) /* continuous range */
#define SNDRV_PCM_RATE_KNOT (1<<31) /* supports more non-continuos rates */
@@ -129,6 +133,9 @@ struct snd_pcm_ops {
SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
#define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\
SNDRV_PCM_RATE_192000)
+#define SNDRV_PCM_RATE_8000_384000 (SNDRV_PCM_RATE_8000_192000|\
+ SNDRV_PCM_RATE_352800|\
+ SNDRV_PCM_RATE_384000)
#define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt)
#define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8)
#define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8)
@@ -337,7 +344,7 @@ static inline void snd_pcm_pack_audio_tstamp_report(__u32 *data, __u32 *accuracy
struct snd_pcm_runtime {
/* -- Status -- */
struct snd_pcm_substream *trigger_master;
- struct timespec trigger_tstamp; /* trigger timestamp */
+ struct timespec64 trigger_tstamp; /* trigger timestamp */
bool trigger_tstamp_latched; /* trigger timestamp latched in low-level driver/hardware */
int overrange;
snd_pcm_uframes_t avail_max;
@@ -390,6 +397,7 @@ struct snd_pcm_runtime {
wait_queue_head_t sleep; /* poll sleep */
wait_queue_head_t tsleep; /* transfer sleep */
struct fasync_struct *fasync;
+ bool stop_operating; /* sync_stop will be called */
/* -- private section -- */
void *private_data;
@@ -409,11 +417,12 @@ struct snd_pcm_runtime {
size_t dma_bytes; /* size of DMA area */
struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */
+ unsigned int buffer_changed:1; /* buffer allocation changed; set only in managed mode */
/* -- audio timestamp config -- */
struct snd_pcm_audio_tstamp_config audio_tstamp_config;
struct snd_pcm_audio_tstamp_report audio_tstamp_report;
- struct timespec driver_tstamp;
+ struct timespec64 driver_tstamp;
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
/* -- OSS things -- */
@@ -470,6 +479,7 @@ struct snd_pcm_substream {
#endif /* CONFIG_SND_VERBOSE_PROCFS */
/* misc flags */
unsigned int hw_opened: 1;
+ unsigned int managed_buffer_alloc:1;
};
#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
@@ -549,8 +559,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info);
int snd_pcm_info_user(struct snd_pcm_substream *substream,
struct snd_pcm_info __user *info);
-int snd_pcm_status(struct snd_pcm_substream *substream,
- struct snd_pcm_status *status);
+int snd_pcm_status64(struct snd_pcm_substream *substream,
+ struct snd_pcm_status64 *status);
int snd_pcm_start(struct snd_pcm_substream *substream);
int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status);
int snd_pcm_drain_done(struct snd_pcm_substream *substream);
@@ -1146,22 +1156,22 @@ static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substrea
}
/**
- * snd_pcm_gettime - Fill the timespec depending on the timestamp mode
+ * snd_pcm_gettime - Fill the timespec64 depending on the timestamp mode
* @runtime: PCM runtime instance
- * @tv: timespec to fill
+ * @tv: timespec64 to fill
*/
static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime,
- struct timespec *tv)
+ struct timespec64 *tv)
{
switch (runtime->tstamp_type) {
case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
- ktime_get_ts(tv);
+ ktime_get_ts64(tv);
break;
case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
- getrawmonotonic(tv);
+ ktime_get_raw_ts64(tv);
break;
default:
- getnstimeofday(tv);
+ ktime_get_real_ts64(tv);
break;
}
}
@@ -1181,6 +1191,12 @@ void snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
+void snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
+ struct device *data, size_t size, size_t max);
+void snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
+ struct device *data,
+ size_t size, size_t max);
+
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
size_t size, gfp_t gfp_flags);
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream);
@@ -1231,14 +1247,6 @@ static inline int snd_pcm_lib_alloc_vmalloc_32_buffer
*/
#define snd_pcm_substream_sgbuf(substream) \
snd_pcm_get_dma_buf(substream)->private_data
-
-struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
- unsigned long offset);
-#else /* !SND_DMA_SGBUF */
-/*
- * fake using a continuous buffer
- */
-#define snd_pcm_sgbuf_ops_page NULL
#endif /* SND_DMA_SGBUF */
/**
@@ -1331,8 +1339,6 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
(IEC958_AES1_CON_PCM_CODER<<8)|\
(IEC958_AES3_CON_FS_48000<<24))
-#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
-
const char *snd_pcm_format_name(snd_pcm_format_t format);
/**
@@ -1417,4 +1423,55 @@ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
#define pcm_dbg(pcm, fmt, args...) \
dev_dbg((pcm)->card->dev, fmt, ##args)
+struct snd_pcm_status64 {
+ snd_pcm_state_t state; /* stream state */
+ u8 rsvd[4];
+ s64 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
+ s64 trigger_tstamp_nsec;
+ s64 tstamp_sec; /* reference timestamp */
+ s64 tstamp_nsec;
+ snd_pcm_uframes_t appl_ptr; /* appl ptr */
+ snd_pcm_uframes_t hw_ptr; /* hw ptr */
+ snd_pcm_sframes_t delay; /* current delay in frames */
+ snd_pcm_uframes_t avail; /* number of frames available */
+ snd_pcm_uframes_t avail_max; /* max frames available on hw since last status */
+ snd_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */
+ snd_pcm_state_t suspended_state; /* suspended stream state */
+ __u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
+ s64 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
+ s64 audio_tstamp_nsec;
+ s64 driver_tstamp_sec; /* useful in case reference system tstamp is reported with delay */
+ s64 driver_tstamp_nsec;
+ __u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */
+ unsigned char reserved[52-4*sizeof(s64)]; /* must be filled with zero */
+};
+
+#define SNDRV_PCM_IOCTL_STATUS64 _IOR('A', 0x20, struct snd_pcm_status64)
+#define SNDRV_PCM_IOCTL_STATUS_EXT64 _IOWR('A', 0x24, struct snd_pcm_status64)
+
+struct snd_pcm_status32 {
+ snd_pcm_state_t state; /* stream state */
+ s32 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
+ s32 trigger_tstamp_nsec;
+ s32 tstamp_sec; /* reference timestamp */
+ s32 tstamp_nsec;
+ u32 appl_ptr; /* appl ptr */
+ u32 hw_ptr; /* hw ptr */
+ s32 delay; /* current delay in frames */
+ u32 avail; /* number of frames available */
+ u32 avail_max; /* max frames available on hw since last status */
+ u32 overrange; /* count of ADC (capture) overrange detections from last status */
+ snd_pcm_state_t suspended_state; /* suspended stream state */
+ u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
+ s32 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
+ s32 audio_tstamp_nsec;
+ s32 driver_tstamp_sec; /* useful in case reference system tstamp is reported with delay */
+ s32 driver_tstamp_nsec;
+ u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */
+ unsigned char reserved[52-4*sizeof(s32)]; /* must be filled with zero */
+};
+
+#define SNDRV_PCM_IOCTL_STATUS32 _IOR('A', 0x20, struct snd_pcm_status32)
+#define SNDRV_PCM_IOCTL_STATUS_EXT32 _IOWR('A', 0x24, struct snd_pcm_status32)
+
#endif /* __SOUND_PCM_H */
diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h
index 6758fc12fa84..0feaf16e6ac0 100644
--- a/include/sound/pxa2xx-lib.h
+++ b/include/sound/pxa2xx-lib.h
@@ -10,6 +10,7 @@ struct snd_pcm_substream;
struct snd_pcm_hw_params;
struct snd_soc_pcm_runtime;
struct snd_pcm;
+struct snd_soc_component;
extern int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
@@ -23,8 +24,29 @@ extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma);
extern int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream);
extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
-extern int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd);
-extern const struct snd_pcm_ops pxa2xx_pcm_ops;
+extern void pxa2xx_soc_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm);
+extern int pxa2xx_soc_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd);
+extern int pxa2xx_soc_pcm_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+extern int pxa2xx_soc_pcm_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+extern int pxa2xx_soc_pcm_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+extern int pxa2xx_soc_pcm_hw_free(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+extern int pxa2xx_soc_pcm_prepare(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+extern int pxa2xx_soc_pcm_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd);
+extern snd_pcm_uframes_t
+pxa2xx_soc_pcm_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+extern int pxa2xx_soc_pcm_mmap(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma);
/* AC97 */
diff --git a/include/sound/rt5682.h b/include/sound/rt5682.h
index bf2ee75aabb1..bc2c31734df1 100644
--- a/include/sound/rt5682.h
+++ b/include/sound/rt5682.h
@@ -31,6 +31,7 @@ struct rt5682_platform_data {
enum rt5682_dmic1_data_pin dmic1_data_pin;
enum rt5682_dmic1_clk_pin dmic1_clk_pin;
enum rt5682_jd_src jd_src;
+ unsigned int btndet_delay;
};
#endif
diff --git a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
index d6b74059b4b1..88799d1e1f53 100644
--- a/include/sound/seq_midi_emul.h
+++ b/include/sound/seq_midi_emul.h
@@ -174,7 +174,8 @@ enum {
};
/* Prototypes for midi_process.c */
-void snd_midi_process_event(struct snd_midi_op *ops, struct snd_seq_event *ev,
+void snd_midi_process_event(const struct snd_midi_op *ops,
+ struct snd_seq_event *ev,
struct snd_midi_channel_set *chanset);
void snd_midi_channel_set_clear(struct snd_midi_channel_set *chset);
struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n);
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 985a5f583de4..bbdd1542d6f1 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -8,6 +8,7 @@
#ifndef __SIMPLE_CARD_UTILS_H
#define __SIMPLE_CARD_UTILS_H
+#include <linux/clk.h>
#include <sound/soc.h>
#define asoc_simple_init_hp(card, sjack, prefix) \
@@ -135,9 +136,9 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
struct link_info *li);
#ifdef DEBUG
-inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
- char *name,
- struct asoc_simple_dai *dai)
+static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
+ char *name,
+ struct asoc_simple_dai *dai)
{
struct device *dev = simple_priv_to_dev(priv);
@@ -167,7 +168,7 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
}
-inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
+static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
{
struct snd_soc_card *card = simple_priv_to_card(priv);
struct device *dev = simple_priv_to_dev(priv);
diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
index bb5e1e4ce8bf..ab6f75a86611 100644
--- a/include/sound/soc-acpi-intel-match.h
+++ b/include/sound/soc-acpi-intel-match.h
@@ -24,7 +24,18 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[];
+
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[];
/*
* generic table used for HDA codec-based platforms, possibly with
diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h
index 35b38e41e5b2..a217a87cae86 100644
--- a/include/sound/soc-acpi.h
+++ b/include/sound/soc-acpi.h
@@ -60,12 +60,33 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
* @acpi_ipc_irq_index: used for BYT-CR detection
* @platform: string used for HDaudio codec support
* @codec_mask: used for HDAudio support
+ * @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
+ * @link_mask: links enabled on the board
+ * @links: array of link _ADR descriptors, null terminated
*/
struct snd_soc_acpi_mach_params {
u32 acpi_ipc_irq_index;
const char *platform;
u32 codec_mask;
u32 dmic_num;
+ bool common_hdmi_codec_drv;
+ u32 link_mask;
+ const struct snd_soc_acpi_link_adr *links;
+};
+
+/**
+ * snd_soc_acpi_link_adr: ACPI-based list of _ADR, with a variable
+ * number of devices per link
+ *
+ * @mask: one bit set indicates the link this list applies to
+ * @num_adr: ARRAY_SIZE of adr
+ * @adr: array of _ADR (represented as u64).
+ */
+
+struct snd_soc_acpi_link_adr {
+ const u32 mask;
+ const u32 num_adr;
+ const u64 *adr;
};
/**
@@ -75,6 +96,8 @@ struct snd_soc_acpi_mach_params {
* all firmware/topology related fields.
*
* @id: ACPI ID (usually the codec's) used to find a matching machine driver.
+ * @link_mask: describes required board layout, e.g. for SoundWire.
+ * @links: array of link _ADR descriptors, null terminated.
* @drv_name: machine driver name
* @fw_filename: firmware file name. Used when SOF is not enabled.
* @board: board name
@@ -90,6 +113,8 @@ struct snd_soc_acpi_mach_params {
/* Descriptor for SST ASoC machine driver */
struct snd_soc_acpi_mach {
const u8 id[ACPI_ID_LEN];
+ const u32 link_mask;
+ const struct snd_soc_acpi_link_adr *links;
const char *drv_name;
const char *fw_filename;
const char *board;
diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h
new file mode 100644
index 000000000000..154d02fbbfed
--- /dev/null
+++ b/include/sound/soc-component.h
@@ -0,0 +1,421 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * soc-component.h
+ *
+ * Copyright (c) 2019 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ */
+#ifndef __SOC_COMPONENT_H
+#define __SOC_COMPONENT_H
+
+#include <sound/soc.h>
+
+/*
+ * Component probe and remove ordering levels for components with runtime
+ * dependencies.
+ */
+#define SND_SOC_COMP_ORDER_FIRST -2
+#define SND_SOC_COMP_ORDER_EARLY -1
+#define SND_SOC_COMP_ORDER_NORMAL 0
+#define SND_SOC_COMP_ORDER_LATE 1
+#define SND_SOC_COMP_ORDER_LAST 2
+
+#define for_each_comp_order(order) \
+ for (order = SND_SOC_COMP_ORDER_FIRST; \
+ order <= SND_SOC_COMP_ORDER_LAST; \
+ order++)
+
+/* component interface */
+struct snd_soc_component_driver {
+ const char *name;
+
+ /* Default control and setup, added after probe() is run */
+ const struct snd_kcontrol_new *controls;
+ unsigned int num_controls;
+ const struct snd_soc_dapm_widget *dapm_widgets;
+ unsigned int num_dapm_widgets;
+ const struct snd_soc_dapm_route *dapm_routes;
+ unsigned int num_dapm_routes;
+
+ int (*probe)(struct snd_soc_component *component);
+ void (*remove)(struct snd_soc_component *component);
+ int (*suspend)(struct snd_soc_component *component);
+ int (*resume)(struct snd_soc_component *component);
+
+ unsigned int (*read)(struct snd_soc_component *component,
+ unsigned int reg);
+ int (*write)(struct snd_soc_component *component,
+ unsigned int reg, unsigned int val);
+
+ /* pcm creation and destruction */
+ int (*pcm_construct)(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd);
+ void (*pcm_destruct)(struct snd_soc_component *component,
+ struct snd_pcm *pcm);
+
+ /* component wide operations */
+ int (*set_sysclk)(struct snd_soc_component *component,
+ int clk_id, int source, unsigned int freq, int dir);
+ int (*set_pll)(struct snd_soc_component *component, int pll_id,
+ int source, unsigned int freq_in, unsigned int freq_out);
+ int (*set_jack)(struct snd_soc_component *component,
+ struct snd_soc_jack *jack, void *data);
+
+ /* DT */
+ int (*of_xlate_dai_name)(struct snd_soc_component *component,
+ struct of_phandle_args *args,
+ const char **dai_name);
+ int (*of_xlate_dai_id)(struct snd_soc_component *comment,
+ struct device_node *endpoint);
+ void (*seq_notifier)(struct snd_soc_component *component,
+ enum snd_soc_dapm_type type, int subseq);
+ int (*stream_event)(struct snd_soc_component *component, int event);
+ int (*set_bias_level)(struct snd_soc_component *component,
+ enum snd_soc_bias_level level);
+
+ int (*open)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+ int (*close)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+ int (*ioctl)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg);
+ int (*hw_params)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+ int (*hw_free)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+ int (*prepare)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+ int (*trigger)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd);
+ int (*sync_stop)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+ snd_pcm_uframes_t (*pointer)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+ int (*get_time_info)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, struct timespec64 *system_ts,
+ struct timespec64 *audio_ts,
+ struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+ struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
+ int (*copy_user)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int channel,
+ unsigned long pos, void __user *buf,
+ unsigned long bytes);
+ struct page *(*page)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ unsigned long offset);
+ int (*mmap)(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma);
+
+ const struct snd_compr_ops *compr_ops;
+
+ /* probe ordering - for components with runtime dependencies */
+ int probe_order;
+ int remove_order;
+
+ /*
+ * signal if the module handling the component should not be removed
+ * if a pcm is open. Setting this would prevent the module
+ * refcount being incremented in probe() but allow it be incremented
+ * when a pcm is opened and decremented when it is closed.
+ */
+ unsigned int module_get_upon_open:1;
+
+ /* bits */
+ unsigned int idle_bias_on:1;
+ unsigned int suspend_bias_off:1;
+ unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
+ unsigned int endianness:1;
+ unsigned int non_legacy_dai_naming:1;
+
+ /* this component uses topology and ignore machine driver FEs */
+ const char *ignore_machine;
+ const char *topology_name_prefix;
+ int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params);
+ bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */
+ int be_pcm_base; /* base device ID for all BE PCMs */
+};
+
+struct snd_soc_component {
+ const char *name;
+ int id;
+ const char *name_prefix;
+ struct device *dev;
+ struct snd_soc_card *card;
+
+ unsigned int active;
+
+ unsigned int suspended:1; /* is in suspend PM state */
+
+ struct list_head list;
+ struct list_head card_aux_list; /* for auxiliary bound components */
+ struct list_head card_list;
+
+ const struct snd_soc_component_driver *driver;
+
+ struct list_head dai_list;
+ int num_dai;
+
+ struct regmap *regmap;
+ int val_bytes;
+
+ struct mutex io_mutex;
+
+ /* attached dynamic objects */
+ struct list_head dobj_list;
+
+ /*
+ * DO NOT use any of the fields below in drivers, they are temporary and
+ * are going to be removed again soon. If you use them in driver code
+ * the driver will be marked as BROKEN when these fields are removed.
+ */
+
+ /* Don't use these, use snd_soc_component_get_dapm() */
+ struct snd_soc_dapm_context dapm;
+
+ /* machine specific init */
+ int (*init)(struct snd_soc_component *component);
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_root;
+ const char *debugfs_prefix;
+#endif
+};
+
+#define for_each_component_dais(component, dai)\
+ list_for_each_entry(dai, &(component)->dai_list, list)
+#define for_each_component_dais_safe(component, dai, _dai)\
+ list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
+
+/**
+ * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
+ * embedded in
+ * @dapm: The DAPM context to cast to the component
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a component (e.g. in a component driver). Otherwise the behavior is
+ * undefined.
+ */
+static inline struct snd_soc_component *snd_soc_dapm_to_component(
+ struct snd_soc_dapm_context *dapm)
+{
+ return container_of(dapm, struct snd_soc_component, dapm);
+}
+
+/**
+ * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
+ * component
+ * @component: The component for which to get the DAPM context
+ */
+static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
+ struct snd_soc_component *component)
+{
+ return &component->dapm;
+}
+
+/**
+ * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
+ * @component: The COMPONENT for which to initialize the DAPM bias level
+ * @level: The DAPM level to initialize to
+ *
+ * Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level()
+ */
+static inline void
+snd_soc_component_init_bias_level(struct snd_soc_component *component,
+ enum snd_soc_bias_level level)
+{
+ snd_soc_dapm_init_bias_level(
+ snd_soc_component_get_dapm(component), level);
+}
+
+/**
+ * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
+ * @component: The COMPONENT for which to get the DAPM bias level
+ *
+ * Returns: The current DAPM bias level of the COMPONENT.
+ */
+static inline enum snd_soc_bias_level
+snd_soc_component_get_bias_level(struct snd_soc_component *component)
+{
+ return snd_soc_dapm_get_bias_level(
+ snd_soc_component_get_dapm(component));
+}
+
+/**
+ * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
+ * @component: The COMPONENT for which to set the level
+ * @level: The level to set to
+ *
+ * Forces the COMPONENT bias level to a specific state. See
+ * snd_soc_dapm_force_bias_level().
+ */
+static inline int
+snd_soc_component_force_bias_level(struct snd_soc_component *component,
+ enum snd_soc_bias_level level)
+{
+ return snd_soc_dapm_force_bias_level(
+ snd_soc_component_get_dapm(component),
+ level);
+}
+
+/**
+ * snd_soc_dapm_kcontrol_component() - Returns the component associated to a
+ * kcontrol
+ * @kcontrol: The kcontrol
+ *
+ * This function must only be used on DAPM contexts that are known to be part of
+ * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined
+ */
+static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
+ struct snd_kcontrol *kcontrol)
+{
+ return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
+}
+
+/**
+ * snd_soc_component_cache_sync() - Sync the register cache with the hardware
+ * @component: COMPONENT to sync
+ *
+ * Note: This function will call regcache_sync()
+ */
+static inline int snd_soc_component_cache_sync(
+ struct snd_soc_component *component)
+{
+ return regcache_sync(component->regmap);
+}
+
+/* component IO */
+int snd_soc_component_read(struct snd_soc_component *component,
+ unsigned int reg, unsigned int *val);
+unsigned int snd_soc_component_read32(struct snd_soc_component *component,
+ unsigned int reg);
+int snd_soc_component_write(struct snd_soc_component *component,
+ unsigned int reg, unsigned int val);
+int snd_soc_component_update_bits(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask,
+ unsigned int val);
+int snd_soc_component_update_bits_async(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask,
+ unsigned int val);
+void snd_soc_component_async_complete(struct snd_soc_component *component);
+int snd_soc_component_test_bits(struct snd_soc_component *component,
+ unsigned int reg, unsigned int mask,
+ unsigned int value);
+
+/* component wide operations */
+int snd_soc_component_set_sysclk(struct snd_soc_component *component,
+ int clk_id, int source,
+ unsigned int freq, int dir);
+int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
+ int source, unsigned int freq_in,
+ unsigned int freq_out);
+int snd_soc_component_set_jack(struct snd_soc_component *component,
+ struct snd_soc_jack *jack, void *data);
+
+void snd_soc_component_seq_notifier(struct snd_soc_component *component,
+ enum snd_soc_dapm_type type, int subseq);
+int snd_soc_component_stream_event(struct snd_soc_component *component,
+ int event);
+int snd_soc_component_set_bias_level(struct snd_soc_component *component,
+ enum snd_soc_bias_level level);
+
+#ifdef CONFIG_REGMAP
+void snd_soc_component_init_regmap(struct snd_soc_component *component,
+ struct regmap *regmap);
+void snd_soc_component_exit_regmap(struct snd_soc_component *component);
+#endif
+
+#define snd_soc_component_module_get_when_probe(component)\
+ snd_soc_component_module_get(component, 0)
+#define snd_soc_component_module_get_when_open(component) \
+ snd_soc_component_module_get(component, 1)
+int snd_soc_component_module_get(struct snd_soc_component *component,
+ int upon_open);
+#define snd_soc_component_module_put_when_remove(component) \
+ snd_soc_component_module_put(component, 0)
+#define snd_soc_component_module_put_when_close(component) \
+ snd_soc_component_module_put(component, 1)
+void snd_soc_component_module_put(struct snd_soc_component *component,
+ int upon_open);
+
+static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
+ void *data)
+{
+ dev_set_drvdata(c->dev, data);
+}
+
+static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
+{
+ return dev_get_drvdata(c->dev);
+}
+
+static inline bool snd_soc_component_is_active(
+ struct snd_soc_component *component)
+{
+ return component->active != 0;
+}
+
+/* component pin */
+int snd_soc_component_enable_pin(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_disable_pin(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_nc_pin(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_get_pin_status(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
+ const char *pin);
+int snd_soc_component_force_enable_pin_unlocked(
+ struct snd_soc_component *component,
+ const char *pin);
+
+/* component driver ops */
+int snd_soc_component_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+int snd_soc_component_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+int snd_soc_component_prepare(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+int snd_soc_component_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+int snd_soc_component_hw_free(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream);
+int snd_soc_component_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ int cmd);
+void snd_soc_component_suspend(struct snd_soc_component *component);
+void snd_soc_component_resume(struct snd_soc_component *component);
+int snd_soc_component_is_suspended(struct snd_soc_component *component);
+int snd_soc_component_probe(struct snd_soc_component *component);
+void snd_soc_component_remove(struct snd_soc_component *component);
+int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
+ struct device_node *ep);
+int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
+ struct of_phandle_args *args,
+ const char **dai_name);
+
+int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream);
+int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg);
+int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream);
+int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
+ int channel, unsigned long pos,
+ void __user *buf, unsigned long bytes);
+struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
+ unsigned long offset);
+int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma);
+int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd);
+void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd);
+
+#endif /* __SOC_COMPONENT_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index f5d70041108f..eaaeb00e9e84 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -145,6 +145,31 @@ int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
+int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
+int snd_soc_dai_startup(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
+void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
+int snd_soc_dai_prepare(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
+int snd_soc_dai_trigger(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream, int cmd);
+int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream, int cmd);
+snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
+void snd_soc_dai_suspend(struct snd_soc_dai *dai);
+void snd_soc_dai_resume(struct snd_soc_dai *dai);
+int snd_soc_dai_probe(struct snd_soc_dai *dai);
+int snd_soc_dai_remove(struct snd_soc_dai *dai);
+int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
+ struct snd_soc_pcm_runtime *rtd, int num);
+bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
+
struct snd_soc_dai_ops {
/*
* DAI clocking configuration, all optional.
@@ -261,15 +286,11 @@ struct snd_soc_dai_driver {
/* DAI driver callbacks */
int (*probe)(struct snd_soc_dai *dai);
int (*remove)(struct snd_soc_dai *dai);
- int (*suspend)(struct snd_soc_dai *dai);
- int (*resume)(struct snd_soc_dai *dai);
/* compress dai */
int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
/* Optional Callback used at pcm creation*/
int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
- /* DAI is also used for the control bus */
- bool bus_control;
/* ops */
const struct snd_soc_dai_ops *ops;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c00a0b8ade08..2a306c6f3fbc 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -353,6 +353,8 @@ struct device;
#define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */
#define SND_SOC_DAPM_PRE_POST_PMD \
(SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
+#define SND_SOC_DAPM_PRE_POST_PMU \
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)
/* convenience event type detection */
#define SND_SOC_DAPM_EVENT_ON(e) \
@@ -390,6 +392,8 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
+int snd_soc_dapm_put_enum_double_locked(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
@@ -402,6 +406,9 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *snd_soc_dapm_new_control(
struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
+struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(
+ struct snd_soc_dapm_context *dapm,
+ const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
@@ -414,6 +421,9 @@ int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
+void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
+ struct snd_soc_card *card,
+ struct snd_soc_component *component);
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_route *route, int num);
int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
@@ -426,6 +436,7 @@ void snd_soc_dapm_reset_cache(struct snd_soc_dapm_context *dapm);
/* dapm events */
void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
int event);
+void snd_soc_dapm_stream_stop(struct snd_soc_pcm_runtime *rtd, int stream);
void snd_soc_dapm_shutdown(struct snd_soc_card *card);
/* external DAPM widget events */
@@ -659,8 +670,6 @@ struct snd_soc_dapm_context {
unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
/* Go to BIAS_OFF in suspend if the DAPM context is idle */
unsigned int suspend_bias_off:1;
- void (*seq_notifier)(struct snd_soc_dapm_context *,
- enum snd_soc_dapm_type, int);
struct device *dev; /* from parent - for debug */
struct snd_soc_component *component; /* parent component */
@@ -670,10 +679,6 @@ struct snd_soc_dapm_context {
enum snd_soc_bias_level target_bias_level;
struct list_head list;
- int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
- int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
- enum snd_soc_bias_level level);
-
struct snd_soc_dapm_wcache path_sink_cache;
struct snd_soc_dapm_wcache path_source_cache;
diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h
index 4be3a2b7c106..b654ebfc8766 100644
--- a/include/sound/soc-dpcm.h
+++ b/include/sound/soc-dpcm.h
@@ -103,15 +103,15 @@ struct snd_soc_dpcm_runtime {
int trigger_pending; /* trigger cmd + 1 if pending, 0 if not */
};
-#define for_each_dpcm_fe(be, stream, dpcm) \
- list_for_each_entry(dpcm, &(be)->dpcm[stream].fe_clients, list_fe)
+#define for_each_dpcm_fe(be, stream, _dpcm) \
+ list_for_each_entry(_dpcm, &(be)->dpcm[stream].fe_clients, list_fe)
-#define for_each_dpcm_be(fe, stream, dpcm) \
- list_for_each_entry(dpcm, &(fe)->dpcm[stream].be_clients, list_be)
-#define for_each_dpcm_be_safe(fe, stream, dpcm, _dpcm) \
- list_for_each_entry_safe(dpcm, _dpcm, &(fe)->dpcm[stream].be_clients, list_be)
-#define for_each_dpcm_be_rollback(fe, stream, dpcm) \
- list_for_each_entry_continue_reverse(dpcm, &(fe)->dpcm[stream].be_clients, list_be)
+#define for_each_dpcm_be(fe, stream, _dpcm) \
+ list_for_each_entry(_dpcm, &(fe)->dpcm[stream].be_clients, list_be)
+#define for_each_dpcm_be_safe(fe, stream, _dpcm, __dpcm) \
+ list_for_each_entry_safe(_dpcm, __dpcm, &(fe)->dpcm[stream].be_clients, list_be)
+#define for_each_dpcm_be_rollback(fe, stream, _dpcm) \
+ list_for_each_entry_continue_reverse(_dpcm, &(fe)->dpcm[stream].be_clients, list_be)
/* can this BE stop and free */
int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
@@ -142,9 +142,16 @@ void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be, int stream,
/* internal use only */
int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
-void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
int soc_dpcm_runtime_update(struct snd_soc_card *);
+#ifdef CONFIG_DEBUG_FS
+void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
+#else
+static inline void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
+{
+}
+#endif
+
int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
int stream, struct snd_soc_dapm_widget_list **list_);
int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 4e8071269639..f0e4f36f83bf 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -299,6 +299,12 @@
.put = snd_soc_bytes_put, .private_value = \
((unsigned long)&(struct soc_bytes) \
{.base = xbase, .num_regs = xregs }) }
+#define SND_SOC_BYTES_E(xname, xbase, xregs, xhandler_get, xhandler_put) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_soc_bytes_info, .get = xhandler_get, \
+ .put = xhandler_put, .private_value = \
+ ((unsigned long)&(struct soc_bytes) \
+ {.base = xbase, .num_regs = xregs }) }
#define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -363,21 +369,6 @@
const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
/*
- * Component probe and remove ordering levels for components with runtime
- * dependencies.
- */
-#define SND_SOC_COMP_ORDER_FIRST -2
-#define SND_SOC_COMP_ORDER_EARLY -1
-#define SND_SOC_COMP_ORDER_NORMAL 0
-#define SND_SOC_COMP_ORDER_LATE 1
-#define SND_SOC_COMP_ORDER_LAST 2
-
-#define for_each_comp_order(order) \
- for (order = SND_SOC_COMP_ORDER_FIRST; \
- order <= SND_SOC_COMP_ORDER_LAST; \
- order++)
-
-/*
* Bias levels
*
* @ON: Bias is fully on for audio playback and capture operations.
@@ -473,10 +464,8 @@ static inline int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
void snd_soc_disconnect_sync(struct device *dev);
-struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
- const char *dai_link, int stream);
struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
- const char *dai_link);
+ struct snd_soc_dai_link *dai_link);
bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
@@ -505,10 +494,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw);
-int soc_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai);
-
/* Jack reporting */
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
@@ -751,143 +736,9 @@ struct snd_soc_compr_ops {
int (*trigger)(struct snd_compr_stream *);
};
-/* component interface */
-struct snd_soc_component_driver {
- const char *name;
-
- /* Default control and setup, added after probe() is run */
- const struct snd_kcontrol_new *controls;
- unsigned int num_controls;
- const struct snd_soc_dapm_widget *dapm_widgets;
- unsigned int num_dapm_widgets;
- const struct snd_soc_dapm_route *dapm_routes;
- unsigned int num_dapm_routes;
-
- int (*probe)(struct snd_soc_component *);
- void (*remove)(struct snd_soc_component *);
- int (*suspend)(struct snd_soc_component *);
- int (*resume)(struct snd_soc_component *);
-
- unsigned int (*read)(struct snd_soc_component *, unsigned int);
- int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
-
- /* pcm creation and destruction */
- int (*pcm_new)(struct snd_soc_pcm_runtime *);
- void (*pcm_free)(struct snd_pcm *);
-
- /* component wide operations */
- int (*set_sysclk)(struct snd_soc_component *component,
- int clk_id, int source, unsigned int freq, int dir);
- int (*set_pll)(struct snd_soc_component *component, int pll_id,
- int source, unsigned int freq_in, unsigned int freq_out);
- int (*set_jack)(struct snd_soc_component *component,
- struct snd_soc_jack *jack, void *data);
-
- /* DT */
- int (*of_xlate_dai_name)(struct snd_soc_component *component,
- struct of_phandle_args *args,
- const char **dai_name);
- int (*of_xlate_dai_id)(struct snd_soc_component *comment,
- struct device_node *endpoint);
- void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
- int subseq);
- int (*stream_event)(struct snd_soc_component *, int event);
- int (*set_bias_level)(struct snd_soc_component *component,
- enum snd_soc_bias_level level);
-
- const struct snd_pcm_ops *ops;
- const struct snd_compr_ops *compr_ops;
-
- /* probe ordering - for components with runtime dependencies */
- int probe_order;
- int remove_order;
-
- /*
- * signal if the module handling the component should not be removed
- * if a pcm is open. Setting this would prevent the module
- * refcount being incremented in probe() but allow it be incremented
- * when a pcm is opened and decremented when it is closed.
- */
- unsigned int module_get_upon_open:1;
-
- /* bits */
- unsigned int idle_bias_on:1;
- unsigned int suspend_bias_off:1;
- unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
- unsigned int endianness:1;
- unsigned int non_legacy_dai_naming:1;
-
- /* this component uses topology and ignore machine driver FEs */
- const char *ignore_machine;
- const char *topology_name_prefix;
- int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params);
- bool use_dai_pcm_id; /* use the DAI link PCM ID as PCM device number */
- int be_pcm_base; /* base device ID for all BE PCMs */
-};
-
-struct snd_soc_component {
- const char *name;
- int id;
- const char *name_prefix;
- struct device *dev;
- struct snd_soc_card *card;
-
- unsigned int active;
-
- unsigned int suspended:1; /* is in suspend PM state */
-
- struct list_head list;
- struct list_head card_aux_list; /* for auxiliary bound components */
- struct list_head card_list;
-
- const struct snd_soc_component_driver *driver;
-
- struct list_head dai_list;
- int num_dai;
-
- struct regmap *regmap;
- int val_bytes;
-
- struct mutex io_mutex;
-
- /* attached dynamic objects */
- struct list_head dobj_list;
-
- /*
- * DO NOT use any of the fields below in drivers, they are temporary and
- * are going to be removed again soon. If you use them in driver code the
- * driver will be marked as BROKEN when these fields are removed.
- */
-
- /* Don't use these, use snd_soc_component_get_dapm() */
- struct snd_soc_dapm_context dapm;
-
- /* machine specific init */
- int (*init)(struct snd_soc_component *component);
-
-#ifdef CONFIG_DEBUG_FS
- struct dentry *debugfs_root;
- const char *debugfs_prefix;
-#endif
-};
-
-#define for_each_component_dais(component, dai)\
- list_for_each_entry(dai, &(component)->dai_list, list)
-#define for_each_component_dais_safe(component, dai, _dai)\
- list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
-
-struct snd_soc_rtdcom_list {
- struct snd_soc_component *component;
- struct list_head list; /* rtd::component_list */
-};
struct snd_soc_component*
snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
const char *driver_name);
-#define for_each_rtdcom(rtd, rtdcom) \
- list_for_each_entry(rtdcom, &(rtd)->component_list, list)
-#define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \
- list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list)
struct snd_soc_dai_link_component {
const char *name;
@@ -989,8 +840,9 @@ struct snd_soc_dai_link {
/* Do not create a PCM for this DAI link (Backend link) */
unsigned int ignore:1;
- struct list_head list; /* DAI link list of the soc card */
+#ifdef CONFIG_SND_SOC_TOPOLOGY
struct snd_soc_dobj dobj; /* For topology */
+#endif
};
#define for_each_link_codecs(link, i, codec) \
for ((i) = 0; \
@@ -1086,6 +938,8 @@ struct snd_soc_dai_link {
#define COMP_CPU(_dai) { .dai_name = _dai, }
#define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, }
#define COMP_PLATFORM(_name) { .name = _name }
+#define COMP_AUX(_name) { .name = _name }
+#define COMP_CODEC_CONF(_name) { .name = _name }
#define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }
extern struct snd_soc_dai_link_component null_dailink_component[0];
@@ -1096,8 +950,7 @@ struct snd_soc_codec_conf {
* specify device either by device name, or by
* DT/OF node, but not both.
*/
- const char *dev_name;
- struct device_node *of_node;
+ struct snd_soc_dai_link_component dlc;
/*
* optional map of kcontrol, widget and path name prefixes that are
@@ -1107,14 +960,11 @@ struct snd_soc_codec_conf {
};
struct snd_soc_aux_dev {
- const char *name; /* Codec name */
-
/*
* specify multi-codec either by device name, or by
* DT/OF node, but not both.
*/
- const char *codec_name;
- struct device_node *codec_of_node;
+ struct snd_soc_dai_link_component dlc;
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_component *component);
@@ -1125,7 +975,10 @@ struct snd_soc_card {
const char *name;
const char *long_name;
const char *driver_name;
+ const char *components;
+#ifdef CONFIG_DMI
char dmi_longname[80];
+#endif /* CONFIG_DMI */
char topology_shortname[32];
struct device *dev;
@@ -1135,6 +988,10 @@ struct snd_soc_card {
struct mutex mutex;
struct mutex dapm_mutex;
+ /* Mutex for PCM operations */
+ struct mutex pcm_mutex;
+ enum snd_soc_pcm_subclass pcm_subclass;
+
spinlock_t dpcm_lock;
bool instantiated;
@@ -1169,7 +1026,6 @@ struct snd_soc_card {
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link; /* predefined links only */
int num_links; /* predefined links only */
- struct list_head dai_link_list; /* all links */
struct list_head rtd_list;
int num_rtd;
@@ -1203,8 +1059,6 @@ struct snd_soc_card {
int num_of_dapm_routes;
bool fully_routed;
- struct work_struct deferred_resume_work;
-
/* lists of probed devices belonging to this card */
struct list_head component_dev_list;
struct list_head list;
@@ -1224,7 +1078,9 @@ struct snd_soc_card {
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_card_root;
- struct dentry *debugfs_pop_time;
+#endif
+#ifdef CONFIG_PM_SLEEP
+ struct work_struct deferred_resume_work;
#endif
u32 pop_time;
@@ -1234,17 +1090,22 @@ struct snd_soc_card {
for ((i) = 0; \
((i) < (card)->num_links) && ((link) = &(card)->dai_link[i]); \
(i)++)
-
-#define for_each_card_links(card, link) \
- list_for_each_entry(link, &(card)->dai_link_list, list)
-#define for_each_card_links_safe(card, link, _link) \
- list_for_each_entry_safe(link, _link, &(card)->dai_link_list, list)
+#define for_each_card_pre_auxs(card, i, aux) \
+ for ((i) = 0; \
+ ((i) < (card)->num_aux_devs) && ((aux) = &(card)->aux_dev[i]); \
+ (i)++)
#define for_each_card_rtds(card, rtd) \
list_for_each_entry(rtd, &(card)->rtd_list, list)
#define for_each_card_rtds_safe(card, rtd, _rtd) \
list_for_each_entry_safe(rtd, _rtd, &(card)->rtd_list, list)
+#define for_each_card_auxs(card, component) \
+ list_for_each_entry(component, &card->aux_comp_list, card_aux_list)
+#define for_each_card_auxs_safe(card, component, _comp) \
+ list_for_each_entry_safe(component, _comp, \
+ &card->aux_comp_list, card_aux_list)
+
#define for_each_card_components(card, component) \
list_for_each_entry(component, &(card)->component_dev_list, card_list)
@@ -1253,8 +1114,6 @@ struct snd_soc_pcm_runtime {
struct device *dev;
struct snd_soc_card *card;
struct snd_soc_dai_link *dai_link;
- struct mutex pcm_mutex;
- enum snd_soc_pcm_subclass pcm_subclass;
struct snd_pcm_ops ops;
unsigned int params_select; /* currently selected param for dai link */
@@ -1274,19 +1133,25 @@ struct snd_soc_pcm_runtime {
unsigned int num_codecs;
struct delayed_work delayed_work;
+ void (*close_delayed_work_func)(struct snd_soc_pcm_runtime *rtd);
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_dpcm_root;
#endif
unsigned int num; /* 0-based and monotonic increasing */
struct list_head list; /* rtd list of the soc card */
- struct list_head component_list; /* list of connected components */
/* bit field */
- unsigned int dev_registered:1;
unsigned int pop_wait:1;
unsigned int fe_compr:1; /* for Dynamic PCM */
+
+ int num_components;
+ struct snd_soc_component *components[0]; /* CPU/Codec/Platform */
};
+#define for_each_rtd_components(rtd, i, component) \
+ for ((i) = 0; \
+ ((i) < rtd->num_components) && ((component) = rtd->components[i]);\
+ (i)++)
#define for_each_rtd_codec_dai(rtd, i, dai)\
for ((i) = 0; \
((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \
@@ -1294,6 +1159,7 @@ struct snd_soc_pcm_runtime {
#define for_each_rtd_codec_dai_rollback(rtd, i, dai) \
for (; ((--i) >= 0) && ((dai) = rtd->codec_dais[i]);)
+void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd);
/* mixer control */
struct soc_mixer_control {
@@ -1303,7 +1169,9 @@ struct soc_mixer_control {
unsigned int sign_bit;
unsigned int invert:1;
unsigned int autodisable:1;
+#ifdef CONFIG_SND_SOC_TOPOLOGY
struct snd_soc_dobj dobj;
+#endif
};
struct soc_bytes {
@@ -1314,8 +1182,9 @@ struct soc_bytes {
struct soc_bytes_ext {
int max;
+#ifdef CONFIG_SND_SOC_TOPOLOGY
struct snd_soc_dobj dobj;
-
+#endif
/* used for TLV byte control */
int (*get)(struct snd_kcontrol *kcontrol, unsigned int __user *bytes,
unsigned int size);
@@ -1339,136 +1208,10 @@ struct soc_enum {
const char * const *texts;
const unsigned int *values;
unsigned int autodisable:1;
+#ifdef CONFIG_SND_SOC_TOPOLOGY
struct snd_soc_dobj dobj;
-};
-
-/**
- * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
- * embedded in
- * @dapm: The DAPM context to cast to the component
- *
- * This function must only be used on DAPM contexts that are known to be part of
- * a component (e.g. in a component driver). Otherwise the behavior is
- * undefined.
- */
-static inline struct snd_soc_component *snd_soc_dapm_to_component(
- struct snd_soc_dapm_context *dapm)
-{
- return container_of(dapm, struct snd_soc_component, dapm);
-}
-
-/**
- * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
- * component
- * @component: The component for which to get the DAPM context
- */
-static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
- struct snd_soc_component *component)
-{
- return &component->dapm;
-}
-
-/**
- * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
- * @component: The COMPONENT for which to initialize the DAPM bias level
- * @level: The DAPM level to initialize to
- *
- * Initializes the COMPONENT DAPM bias level. See snd_soc_dapm_init_bias_level().
- */
-static inline void
-snd_soc_component_init_bias_level(struct snd_soc_component *component,
- enum snd_soc_bias_level level)
-{
- snd_soc_dapm_init_bias_level(
- snd_soc_component_get_dapm(component), level);
-}
-
-/**
- * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
- * @component: The COMPONENT for which to get the DAPM bias level
- *
- * Returns: The current DAPM bias level of the COMPONENT.
- */
-static inline enum snd_soc_bias_level
-snd_soc_component_get_bias_level(struct snd_soc_component *component)
-{
- return snd_soc_dapm_get_bias_level(
- snd_soc_component_get_dapm(component));
-}
-
-/**
- * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
- * @component: The COMPONENT for which to set the level
- * @level: The level to set to
- *
- * Forces the COMPONENT bias level to a specific state. See
- * snd_soc_dapm_force_bias_level().
- */
-static inline int
-snd_soc_component_force_bias_level(struct snd_soc_component *component,
- enum snd_soc_bias_level level)
-{
- return snd_soc_dapm_force_bias_level(
- snd_soc_component_get_dapm(component),
- level);
-}
-
-/**
- * snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
- * @kcontrol: The kcontrol
- *
- * This function must only be used on DAPM contexts that are known to be part of
- * a COMPONENT (e.g. in a COMPONENT driver). Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
- struct snd_kcontrol *kcontrol)
-{
- return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
-}
-
-/**
- * snd_soc_component_cache_sync() - Sync the register cache with the hardware
- * @component: COMPONENT to sync
- *
- * Note: This function will call regcache_sync()
- */
-static inline int snd_soc_component_cache_sync(
- struct snd_soc_component *component)
-{
- return regcache_sync(component->regmap);
-}
-
-/* component IO */
-int snd_soc_component_read(struct snd_soc_component *component,
- unsigned int reg, unsigned int *val);
-unsigned int snd_soc_component_read32(struct snd_soc_component *component,
- unsigned int reg);
-int snd_soc_component_write(struct snd_soc_component *component,
- unsigned int reg, unsigned int val);
-int snd_soc_component_update_bits(struct snd_soc_component *component,
- unsigned int reg, unsigned int mask, unsigned int val);
-int snd_soc_component_update_bits_async(struct snd_soc_component *component,
- unsigned int reg, unsigned int mask, unsigned int val);
-void snd_soc_component_async_complete(struct snd_soc_component *component);
-int snd_soc_component_test_bits(struct snd_soc_component *component,
- unsigned int reg, unsigned int mask, unsigned int value);
-
-/* component wide operations */
-int snd_soc_component_set_sysclk(struct snd_soc_component *component,
- int clk_id, int source, unsigned int freq, int dir);
-int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
- int source, unsigned int freq_in,
- unsigned int freq_out);
-int snd_soc_component_set_jack(struct snd_soc_component *component,
- struct snd_soc_jack *jack, void *data);
-
-#ifdef CONFIG_REGMAP
-
-void snd_soc_component_init_regmap(struct snd_soc_component *component,
- struct regmap *regmap);
-void snd_soc_component_exit_regmap(struct snd_soc_component *component);
-
#endif
+};
/* device driver data */
@@ -1483,27 +1226,6 @@ static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
return card->drvdata;
}
-static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
- void *data)
-{
- dev_set_drvdata(c->dev, data);
-}
-
-static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
-{
- return dev_get_drvdata(c->dev);
-}
-
-static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
-{
- INIT_LIST_HEAD(&card->widgets);
- INIT_LIST_HEAD(&card->paths);
- INIT_LIST_HEAD(&card->dapm_list);
- INIT_LIST_HEAD(&card->aux_comp_list);
- INIT_LIST_HEAD(&card->component_dev_list);
- INIT_LIST_HEAD(&card->list);
-}
-
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
{
if (mc->reg == mc->rreg && mc->shift == mc->rshift)
@@ -1540,12 +1262,6 @@ static inline unsigned int snd_soc_enum_item_to_val(struct soc_enum *e,
return e->values[item];
}
-static inline bool snd_soc_component_is_active(
- struct snd_soc_component *component)
-{
- return component->active != 0;
-}
-
/**
* snd_soc_kcontrol_component() - Returns the component that registered the
* control
@@ -1607,16 +1323,15 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
struct snd_soc_dai_link *dai_link);
void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link);
-int snd_soc_add_dai_link(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_link);
-void snd_soc_remove_dai_link(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_link);
-struct snd_soc_dai_link *snd_soc_find_dai_link(struct snd_soc_card *card,
- int id, const char *name,
- const char *stream_name);
+int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_link);
+void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
+ struct snd_soc_pcm_runtime *rtd);
-int snd_soc_register_dai(struct snd_soc_component *component,
- struct snd_soc_dai_driver *dai_drv);
+struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
+ struct snd_soc_dai_driver *dai_drv,
+ bool legacy_dai_naming);
+void snd_soc_unregister_dai(struct snd_soc_dai *dai);
struct snd_soc_dai *snd_soc_find_dai(
const struct snd_soc_dai_link_component *dlc);
@@ -1681,24 +1396,6 @@ static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
mutex_unlock(&dapm->card->dapm_mutex);
}
-int snd_soc_component_enable_pin(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_disable_pin(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_nc_pin(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_get_pin_status(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
- const char *pin);
-int snd_soc_component_force_enable_pin_unlocked(
- struct snd_soc_component *component,
- const char *pin);
+#include <sound/soc-component.h>
#endif
diff --git a/include/sound/sof.h b/include/sound/sof.h
index 4640566b54fe..a0cbca021230 100644
--- a/include/sound/sof.h
+++ b/include/sound/sof.h
@@ -22,7 +22,6 @@ struct snd_sof_dsp_ops;
*/
struct snd_sof_pdata {
const struct firmware *fw;
- const char *drv_name;
const char *name;
const char *platform;
@@ -61,6 +60,9 @@ struct sof_dev_desc {
/* list of machines using this configuration */
struct snd_soc_acpi_mach *machines;
+ /* alternate list of machines using this configuration */
+ struct snd_soc_acpi_mach *alt_machines;
+
/* Platform resource indexes in BAR / ACPI resources. */
/* Must set to -1 if not used - add new items to end */
int resindex_lpe_base;
@@ -81,20 +83,18 @@ struct sof_dev_desc {
const void *chip_info;
/* defaults for no codec mode */
- const char *nocodec_fw_filename;
const char *nocodec_tplg_filename;
/* defaults paths for firmware and topology files */
const char *default_fw_path;
const char *default_tplg_path;
+ /* default firmware name */
+ const char *default_fw_filename;
+
const struct snd_sof_dsp_ops *ops;
- const struct sof_arch_ops *arch_ops;
};
int sof_nocodec_setup(struct device *dev,
- struct snd_sof_pdata *sof_pdata,
- struct snd_soc_acpi_mach *mach,
- const struct sof_dev_desc *desc,
const struct snd_sof_dsp_ops *ops);
#endif
diff --git a/include/sound/sof/channel_map.h b/include/sound/sof/channel_map.h
new file mode 100644
index 000000000000..21044eb5f377
--- /dev/null
+++ b/include/sound/sof/channel_map.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2019 Intel Corporation. All rights reserved.
+ */
+
+#ifndef __IPC_CHANNEL_MAP_H__
+#define __IPC_CHANNEL_MAP_H__
+
+#include <uapi/sound/sof/header.h>
+#include <sound/sof/header.h>
+
+/**
+ * \brief Channel map, specifies transformation of one-to-many or many-to-one.
+ *
+ * In case of one-to-many specifies how the output channels are computed out of
+ * a single source channel,
+ * in case of many-to-one specifies how a single target channel is computed
+ * from a multichannel input stream.
+ *
+ * Channel index specifies position of the channel in the stream on the 'one'
+ * side.
+ *
+ * Ext ID is the identifier of external part of the transformation. Depending
+ * on the context, it may be pipeline ID, dai ID, ...
+ *
+ * Channel mask describes which channels are taken into account on the "many"
+ * side. Bit[i] set to 1 means that i-th channel is used for computation
+ * (either as source or as a target).
+ *
+ * Channel mask is followed by array of coefficients in Q2.30 format,
+ * one per each channel set in the mask (left to right, LS bit set in the
+ * mask corresponds to ch_coeffs[0]).
+ */
+struct sof_ipc_channel_map {
+ uint32_t ch_index;
+ uint32_t ext_id;
+ uint32_t ch_mask;
+ uint32_t reserved;
+ int32_t ch_coeffs[0];
+} __packed;
+
+/**
+ * \brief Complete map for each channel of a multichannel stream.
+ *
+ * num_ch_map Specifies number of items in the ch_map.
+ * More than one transformation per a single channel is allowed (in case
+ * multiple external entities are transformed).
+ * A channel may be skipped in the transformation list, then it is filled
+ * with 0's by the transformation function.
+ */
+struct sof_ipc_stream_map {
+ struct sof_ipc_cmd_hdr hdr;
+ uint32_t num_ch_map;
+ uint32_t reserved[3];
+ struct sof_ipc_channel_map ch_map[0];
+} __packed;
+
+#endif /* __IPC_CHANNEL_MAP_H__ */
diff --git a/include/sound/sof/dai-imx.h b/include/sound/sof/dai-imx.h
new file mode 100644
index 000000000000..ff9088dcc6f2
--- /dev/null
+++ b/include/sound/sof/dai-imx.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/*
+ * Copyright 2019 NXP
+ *
+ * Author: Daniel Baluta <daniel.baluta@nxp.com>
+ */
+
+#ifndef __INCLUDE_SOUND_SOF_DAI_IMX_H__
+#define __INCLUDE_SOUND_SOF_DAI_IMX_H__
+
+#include <sound/sof/header.h>
+
+/* ESAI Configuration Request - SOF_IPC_DAI_ESAI_CONFIG */
+struct sof_ipc_dai_esai_params {
+ struct sof_ipc_hdr hdr;
+
+ /* MCLK */
+ uint16_t reserved1;
+ uint16_t mclk_id;
+ uint32_t mclk_direction;
+
+ uint32_t mclk_rate; /* MCLK frequency in Hz */
+ uint32_t fsync_rate; /* FSYNC frequency in Hz */
+ uint32_t bclk_rate; /* BCLK frequency in Hz */
+
+ /* TDM */
+ uint32_t tdm_slots;
+ uint32_t rx_slots;
+ uint32_t tx_slots;
+ uint16_t tdm_slot_width;
+ uint16_t reserved2; /* alignment */
+} __packed;
+
+/* SAI Configuration Request - SOF_IPC_DAI_SAI_CONFIG */
+struct sof_ipc_dai_sai_params {
+ struct sof_ipc_hdr hdr;
+
+ /* MCLK */
+ uint16_t reserved1;
+ uint16_t mclk_id;
+ uint32_t mclk_direction;
+
+ uint32_t mclk_rate; /* MCLK frequency in Hz */
+ uint32_t fsync_rate; /* FSYNC frequency in Hz */
+ uint32_t bclk_rate; /* BCLK frequency in Hz */
+
+ /* TDM */
+ uint32_t tdm_slots;
+ uint32_t rx_slots;
+ uint32_t tx_slots;
+ uint16_t tdm_slot_width;
+ uint16_t reserved2; /* alignment */
+} __packed;
+#endif
diff --git a/include/sound/sof/dai-intel.h b/include/sound/sof/dai-intel.h
index 65e4c20e567c..5f1ef5565be6 100644
--- a/include/sound/sof/dai-intel.h
+++ b/include/sound/sof/dai-intel.h
@@ -76,6 +76,9 @@ struct sof_ipc_dai_ssp_params {
uint16_t tdm_per_slot_padding_flag;
uint32_t clks_control;
uint32_t quirks;
+ uint32_t bclk_delay; /* guaranteed time (ms) for which BCLK
+ * will be driven, before sending data
+ */
} __packed;
/* HDA Configuration Request - SOF_IPC_DAI_HDA_CONFIG */
@@ -176,4 +179,13 @@ struct sof_ipc_dai_dmic_params {
struct sof_ipc_dai_dmic_pdm_ctrl pdm[0];
} __packed;
+/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */
+struct sof_ipc_dai_alh_params {
+ struct sof_ipc_hdr hdr;
+ uint32_t stream_id;
+
+ /* reserved for future use */
+ uint32_t reserved[15];
+} __packed;
+
#endif
diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h
index 5b8de1b1983c..2565edd336f1 100644
--- a/include/sound/sof/dai.h
+++ b/include/sound/sof/dai.h
@@ -11,6 +11,7 @@
#include <sound/sof/header.h>
#include <sound/sof/dai-intel.h>
+#include <sound/sof/dai-imx.h>
/*
* DAI Configuration.
@@ -49,7 +50,9 @@ enum sof_ipc_dai_type {
SOF_DAI_INTEL_SSP, /**< Intel SSP */
SOF_DAI_INTEL_DMIC, /**< Intel DMIC */
SOF_DAI_INTEL_HDA, /**< Intel HD/A */
- SOF_DAI_INTEL_SOUNDWIRE, /**< Intel SoundWire */
+ SOF_DAI_INTEL_ALH, /**< Intel ALH */
+ SOF_DAI_IMX_SAI, /**< i.MX SAI */
+ SOF_DAI_IMX_ESAI, /**< i.MX ESAI */
};
/* general purpose DAI configuration */
@@ -70,6 +73,9 @@ struct sof_ipc_dai_config {
struct sof_ipc_dai_ssp_params ssp;
struct sof_ipc_dai_dmic_params dmic;
struct sof_ipc_dai_hda_params hda;
+ struct sof_ipc_dai_alh_params alh;
+ struct sof_ipc_dai_esai_params esai;
+ struct sof_ipc_dai_sai_params sai;
};
} __packed;
diff --git a/include/sound/sof/header.h b/include/sound/sof/header.h
index 10f00c08dbb7..bf3edd9c08b4 100644
--- a/include/sound/sof/header.h
+++ b/include/sound/sof/header.h
@@ -9,6 +9,7 @@
#ifndef __INCLUDE_SOUND_SOF_HEADER_H__
#define __INCLUDE_SOUND_SOF_HEADER_H__
+#include <linux/types.h>
#include <uapi/sound/sof/abi.h>
/** \addtogroup sof_uapi uAPI
@@ -74,6 +75,7 @@
#define SOF_IPC_PM_CLK_GET SOF_CMD_TYPE(0x005)
#define SOF_IPC_PM_CLK_REQ SOF_CMD_TYPE(0x006)
#define SOF_IPC_PM_CORE_ENABLE SOF_CMD_TYPE(0x007)
+#define SOF_IPC_PM_GATE SOF_CMD_TYPE(0x008)
/* component runtime config - multiple different types */
#define SOF_IPC_COMP_SET_VALUE SOF_CMD_TYPE(0x001)
diff --git a/include/sound/sof/info.h b/include/sound/sof/info.h
index a9156b4a062c..1c560144996c 100644
--- a/include/sound/sof/info.h
+++ b/include/sound/sof/info.h
@@ -30,6 +30,7 @@
enum sof_ipc_ext_data {
SOF_IPC_EXT_DMA_BUFFER = 0,
SOF_IPC_EXT_WINDOW,
+ SOF_IPC_EXT_CC_INFO,
};
/* FW version - SOF_IPC_GLB_VERSION */
@@ -115,4 +116,18 @@ struct sof_ipc_window {
struct sof_ipc_window_elem window[];
} __packed;
+struct sof_ipc_cc_version {
+ struct sof_ipc_ext_data_hdr ext_hdr;
+ uint32_t major;
+ uint32_t minor;
+ uint32_t micro;
+
+ /* reserved for future use */
+ uint32_t reserved[4];
+
+ char name[16]; /* null terminated compiler name */
+ char optim[4]; /* null terminated compiler -O flag value */
+ char desc[]; /* null terminated compiler description */
+} __packed;
+
#endif
diff --git a/include/sound/sof/pm.h b/include/sound/sof/pm.h
index 003879401d63..3cf2e0f39d94 100644
--- a/include/sound/sof/pm.h
+++ b/include/sound/sof/pm.h
@@ -45,4 +45,12 @@ struct sof_ipc_pm_core_config {
uint32_t enable_mask;
} __packed;
+struct sof_ipc_pm_gate {
+ struct sof_ipc_cmd_hdr hdr;
+ uint32_t flags; /* platform specific */
+
+ /* reserved for future use */
+ uint32_t reserved[5];
+} __packed;
+
#endif
diff --git a/include/sound/sof/stream.h b/include/sound/sof/stream.h
index 0b71b381b952..7facefb541b3 100644
--- a/include/sound/sof/stream.h
+++ b/include/sound/sof/stream.h
@@ -83,10 +83,10 @@ struct sof_ipc_stream_params {
uint16_t sample_valid_bytes;
uint16_t sample_container_bytes;
- /* for notifying host period has completed - 0 means no period IRQ */
uint32_t host_period_bytes;
+ uint16_t no_stream_position; /**< 1 means don't send stream position */
- uint32_t reserved[2];
+ uint16_t reserved[3];
uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */
} __packed;
diff --git a/include/sound/sof/topology.h b/include/sound/sof/topology.h
index c47b36240920..8e76178fedf0 100644
--- a/include/sound/sof/topology.h
+++ b/include/sound/sof/topology.h
@@ -36,6 +36,7 @@ enum sof_comp_type {
SOF_COMP_KPB, /* A key phrase buffer component */
SOF_COMP_SELECTOR, /**< channel selector component */
SOF_COMP_DEMUX,
+ SOF_COMP_ASRC, /**< Asynchronous sample rate converter */
/* keep FILEREAD/FILEWRITE as the last ones */
SOF_COMP_FILEREAD = 10000, /**< host test based file IO */
SOF_COMP_FILEWRITE = 10001, /**< host test based file IO */
@@ -147,6 +148,32 @@ struct sof_ipc_comp_src {
uint32_t rate_mask; /**< SOF_RATE_ supported rates */
} __packed;
+/* generic ASRC component */
+struct sof_ipc_comp_asrc {
+ struct sof_ipc_comp comp;
+ struct sof_ipc_comp_config config;
+ /* either source or sink rate must be non zero */
+ uint32_t source_rate; /**< Define fixed source rate or */
+ /**< use 0 to indicate need to get */
+ /**< the rate from stream */
+ uint32_t sink_rate; /**< Define fixed sink rate or */
+ /**< use 0 to indicate need to get */
+ /**< the rate from stream */
+ uint32_t asynchronous_mode; /**< synchronous 0, asynchronous 1 */
+ /**< When 1 the ASRC tracks and */
+ /**< compensates for drift. */
+ uint32_t operation_mode; /**< push 0, pull 1, In push mode the */
+ /**< ASRC consumes a defined number */
+ /**< of frames at input, with varying */
+ /**< number of frames at output. */
+ /**< In pull mode the ASRC outputs */
+ /**< a defined number of frames while */
+ /**< number of input frames varies. */
+
+ /* reserved for future use */
+ uint32_t reserved[4];
+} __attribute__((packed));
+
/* generic MUX component */
struct sof_ipc_comp_mux {
struct sof_ipc_comp comp;
diff --git a/include/sound/timer.h b/include/sound/timer.h
index 199c36295a0d..23e885d31525 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -89,7 +89,7 @@ struct snd_timer_instance {
unsigned long ticks, unsigned long resolution);
void (*ccallback) (struct snd_timer_instance * timeri,
int event,
- struct timespec * tstamp,
+ struct timespec64 * tstamp,
unsigned long resolution);
void (*disconnect)(struct snd_timer_instance *timeri);
void *callback_data;
@@ -113,13 +113,15 @@ struct snd_timer_instance {
*/
int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, struct snd_timer **rtimer);
-void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp);
+void snd_timer_notify(struct snd_timer *timer, int event, struct timespec64 *tstamp);
int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer);
int snd_timer_global_free(struct snd_timer *timer);
int snd_timer_global_register(struct snd_timer *timer);
-int snd_timer_open(struct snd_timer_instance **ti, char *owner, struct snd_timer_id *tid, unsigned int slave_id);
-int snd_timer_close(struct snd_timer_instance *timeri);
+struct snd_timer_instance *snd_timer_instance_new(const char *owner);
+void snd_timer_instance_free(struct snd_timer_instance *timeri);
+int snd_timer_open(struct snd_timer_instance *timeri, struct snd_timer_id *tid, unsigned int slave_id);
+void snd_timer_close(struct snd_timer_instance *timeri);
unsigned long snd_timer_resolution(struct snd_timer_instance *timeri);
int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks);
int snd_timer_stop(struct snd_timer_instance *timeri);
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h
index 84569ddf85e1..1ddd3036bdfc 100644
--- a/include/sound/vx_core.h
+++ b/include/sound/vx_core.h
@@ -147,8 +147,8 @@ struct vx_core {
/* ports are defined externally */
/* low-level functions */
- struct snd_vx_hardware *hw;
- struct snd_vx_ops *ops;
+ const struct snd_vx_hardware *hw;
+ const struct snd_vx_ops *ops;
struct mutex lock;
@@ -193,8 +193,9 @@ struct vx_core {
/*
* constructor
*/
-struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
- struct snd_vx_ops *ops, int extra_size);
+struct vx_core *snd_vx_create(struct snd_card *card,
+ const struct snd_vx_hardware *hw,
+ const struct snd_vx_ops *ops, int extra_size);
int snd_vx_setup_firmware(struct vx_core *chip);
int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *dsp);
int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *dsp);
diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h
index 14074405f501..88ac1870510e 100644
--- a/include/sound/wm8904.h
+++ b/include/sound/wm8904.h
@@ -120,7 +120,7 @@
* DRC configurations are specified with a label and a set of register
* values to write (the enable bits will be ignored). At runtime an
* enumerated control will be presented for each DRC block allowing
- * the user to choose the configration to use.
+ * the user to choose the configuration to use.
*
* Configurations may be generated by hand or by using the DRC control
* panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/
OpenPOWER on IntegriCloud