diff options
Diffstat (limited to 'sound/hda/hdac_bus.c')
-rw-r--r-- | sound/hda/hdac_bus.c | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c index 14e57ffd5bc1..3fe62be1cbcc 100644 --- a/sound/hda/hdac_bus.c +++ b/sound/hda/hdac_bus.c @@ -4,12 +4,16 @@ */ #include <linux/init.h> +#include <linux/io.h> #include <linux/device.h> #include <linux/module.h> #include <linux/export.h> #include <sound/hdaudio.h> +#include "local.h" #include "trace.h" +static void snd_hdac_bus_process_unsol_events(struct work_struct *work); + static const struct hdac_bus_ops default_ops = { .command = snd_hdac_bus_send_cmd, .get_response = snd_hdac_bus_get_response, @@ -18,14 +22,13 @@ static const struct hdac_bus_ops default_ops = { /** * snd_hdac_bus_init - initialize a HD-audio bas bus * @bus: the pointer to bus object + * @dev: device pointer * @ops: bus verb operators - * @io_ops: lowlevel I/O operators * * Returns 0 if successful, or a negative error code. */ 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) { memset(bus, 0, sizeof(*bus)); bus->dev = dev; @@ -33,7 +36,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, bus->ops = ops; else bus->ops = &default_ops; - bus->io_ops = io_ops; + bus->dma_type = SNDRV_DMA_TYPE_DEV; INIT_LIST_HEAD(&bus->stream_list); INIT_LIST_HEAD(&bus->codec_list); INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events); @@ -41,6 +44,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev, mutex_init(&bus->cmd_mutex); mutex_init(&bus->lock); INIT_LIST_HEAD(&bus->hlink_list); + init_waitqueue_head(&bus->rirb_wq); bus->irq = -1; return 0; } @@ -61,6 +65,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_exit); /** * snd_hdac_bus_exec_verb - execute a HD-audio verb on the given bus * @bus: bus object + * @addr: the HDAC device address * @cmd: HD-audio encoded verb * @res: pointer to store the response, NULL if performing asynchronously * @@ -81,6 +86,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_exec_verb); /** * snd_hdac_bus_exec_verb_unlocked - unlocked version * @bus: bus object + * @addr: the HDAC device address * @cmd: HD-audio encoded verb * @res: pointer to store the response, NULL if performing asynchronously * @@ -149,7 +155,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_queue_event); /* * process queued unsolicited events */ -void snd_hdac_bus_process_unsol_events(struct work_struct *work) +static void snd_hdac_bus_process_unsol_events(struct work_struct *work) { struct hdac_bus *bus = container_of(work, struct hdac_bus, unsol_work); struct hdac_device *codec; @@ -172,7 +178,6 @@ void snd_hdac_bus_process_unsol_events(struct work_struct *work) drv->unsol_event(codec, res); } } -EXPORT_SYMBOL_GPL(snd_hdac_bus_process_unsol_events); /** * snd_hdac_bus_add_device - Add a codec to bus @@ -197,7 +202,6 @@ int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec) bus->num_codecs++; return 0; } -EXPORT_SYMBOL_GPL(snd_hdac_bus_add_device); /** * snd_hdac_bus_remove_device - Remove a codec from bus @@ -216,4 +220,33 @@ void snd_hdac_bus_remove_device(struct hdac_bus *bus, bus->num_codecs--; flush_work(&bus->unsol_work); } -EXPORT_SYMBOL_GPL(snd_hdac_bus_remove_device); + +#ifdef CONFIG_SND_HDA_ALIGNED_MMIO +/* Helpers for aligned read/write of mmio space, for Tegra */ +unsigned int snd_hdac_aligned_read(void __iomem *addr, unsigned int mask) +{ + void __iomem *aligned_addr = + (void __iomem *)((unsigned long)(addr) & ~0x3); + unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; + unsigned int v; + + v = readl(aligned_addr); + return (v >> shift) & mask; +} +EXPORT_SYMBOL_GPL(snd_hdac_aligned_read); + +void snd_hdac_aligned_write(unsigned int val, void __iomem *addr, + unsigned int mask) +{ + void __iomem *aligned_addr = + (void __iomem *)((unsigned long)(addr) & ~0x3); + unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; + unsigned int v; + + v = readl(aligned_addr); + v &= ~(mask << shift); + v |= val << shift; + writel(v, aligned_addr); +} +EXPORT_SYMBOL_GPL(snd_hdac_aligned_write); +#endif /* CONFIG_SND_HDA_ALIGNED_MMIO */ |