*/
int snd_hda_bus_new(struct snd_card *card,
const struct hdac_bus_ops *ops,
+ const struct hdac_io_ops *io_ops,
struct hda_bus **busp)
{
struct hda_bus *bus;
if (!bus)
return -ENOMEM;
- err = snd_hdac_bus_init(&bus->core, card->dev, ops, NULL);
+ err = snd_hdac_bus_init(&bus->core, card->dev, ops, io_ops);
if (err < 0) {
kfree(bus);
return err;
*/
int snd_hda_bus_new(struct snd_card *card,
const struct hdac_bus_ops *ops,
+ const struct hdac_io_ops *io_ops,
struct hda_bus **busp);
int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
unsigned int codec_addr, struct hda_codec **codecp);
static int azx_alloc_cmd_io(struct azx *chip)
{
/* single page (at least 4096 bytes) must suffice for both ringbuffes */
- return chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
- PAGE_SIZE, &chip->rb);
+ return chip->io_ops->dma_alloc_pages(azx_bus(chip), SNDRV_DMA_TYPE_DEV,
+ PAGE_SIZE, &chip->rb);
}
static void azx_init_cmd_io(struct azx *chip)
azx_dev->locked = 1;
spin_unlock_irq(&chip->reg_lock);
- err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV_SG,
- byte_size, bufp);
+ err = chip->io_ops->dma_alloc_pages(&bus->core, SNDRV_DMA_TYPE_DEV_SG,
+ byte_size, bufp);
if (err < 0)
goto err_alloc;
return azx_dev->stream_tag;
error:
- chip->ops->dma_free_pages(chip, bufp);
+ chip->io_ops->dma_free_pages(&bus->core, bufp);
err_alloc:
spin_lock_irq(&chip->reg_lock);
if (azx_dev->opened)
azx_dev->period_bytes = 0;
azx_dev->format_val = 0;
- chip->ops->dma_free_pages(chip, dmab);
+ chip->io_ops->dma_free_pages(&bus->core, dmab);
dmab->area = NULL;
spin_lock_irq(&chip->reg_lock);
for (i = 0; i < chip->num_streams; i++) {
dsp_lock_init(&chip->azx_dev[i]);
/* allocate memory for the BDL for each stream */
- err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
+ err = chip->io_ops->dma_alloc_pages(azx_bus(chip), SNDRV_DMA_TYPE_DEV,
BDL_SIZE,
&chip->azx_dev[i].bdl);
if (err < 0)
return -ENOMEM;
}
/* allocate memory for the position buffer */
- err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
+ err = chip->io_ops->dma_alloc_pages(azx_bus(chip), SNDRV_DMA_TYPE_DEV,
chip->num_streams * 8, &chip->posbuf);
if (err < 0)
return -ENOMEM;
if (chip->azx_dev) {
for (i = 0; i < chip->num_streams; i++)
if (chip->azx_dev[i].bdl.area)
- chip->ops->dma_free_pages(
- chip, &chip->azx_dev[i].bdl);
+ chip->io_ops->dma_free_pages(azx_bus(chip),
+ &chip->azx_dev[i].bdl);
}
if (chip->rb.area)
- chip->ops->dma_free_pages(chip, &chip->rb);
+ chip->io_ops->dma_free_pages(azx_bus(chip), &chip->rb);
if (chip->posbuf.area)
- chip->ops->dma_free_pages(chip, &chip->posbuf);
+ chip->io_ops->dma_free_pages(azx_bus(chip), &chip->posbuf);
}
EXPORT_SYMBOL_GPL(azx_free_stream_pages);
struct hda_bus *bus;
int err;
- err = snd_hda_bus_new(chip->card, &bus_core_ops, &bus);
+ err = snd_hda_bus_new(chip->card, &bus_core_ops, chip->io_ops, &bus);
if (err < 0)
return err;
/* Functions to read/write to hda registers. */
struct hda_controller_ops {
- /* Register Access */
- 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);
/* Disable msi if supported, PCI only */
int (*disable_msi_reset_irq)(struct azx *);
- /* Allocation ops */
- int (*dma_alloc_pages)(struct azx *chip,
- int type,
- size_t size,
- struct snd_dma_buffer *buf);
- void (*dma_free_pages)(struct azx *chip, struct snd_dma_buffer *buf);
int (*substream_alloc_pages)(struct azx *chip,
struct snd_pcm_substream *substream,
size_t size);
/* Register interaction. */
const struct hda_controller_ops *ops;
+ const struct hdac_io_ops *io_ops;
/* position adjustment callbacks */
azx_get_pos_callback_t get_position[2];
#endif
};
+#define azx_bus(chip) (&(chip)->bus->core)
+
#ifdef CONFIG_X86
#define azx_snoop(chip) ((chip)->snoop)
#else
*/
#define azx_writel(chip, reg, value) \
- ((chip)->ops->reg_writel(value, (chip)->remap_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_writel(value, (chip)->remap_addr + AZX_REG_##reg))
#define azx_readl(chip, reg) \
- ((chip)->ops->reg_readl((chip)->remap_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_readl((chip)->remap_addr + AZX_REG_##reg))
#define azx_writew(chip, reg, value) \
- ((chip)->ops->reg_writew(value, (chip)->remap_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_writew(value, (chip)->remap_addr + AZX_REG_##reg))
#define azx_readw(chip, reg) \
- ((chip)->ops->reg_readw((chip)->remap_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_readw((chip)->remap_addr + AZX_REG_##reg))
#define azx_writeb(chip, reg, value) \
- ((chip)->ops->reg_writeb(value, (chip)->remap_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + AZX_REG_##reg))
#define azx_readb(chip, reg) \
- ((chip)->ops->reg_readb((chip)->remap_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_readb((chip)->remap_addr + AZX_REG_##reg))
#define azx_sd_writel(chip, dev, reg, value) \
- ((chip)->ops->reg_writel(value, (dev)->sd_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_writel(value, (dev)->sd_addr + AZX_REG_##reg))
#define azx_sd_readl(chip, dev, reg) \
- ((chip)->ops->reg_readl((dev)->sd_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_readl((dev)->sd_addr + AZX_REG_##reg))
#define azx_sd_writew(chip, dev, reg, value) \
- ((chip)->ops->reg_writew(value, (dev)->sd_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_writew(value, (dev)->sd_addr + AZX_REG_##reg))
#define azx_sd_readw(chip, dev, reg) \
- ((chip)->ops->reg_readw((dev)->sd_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_readw((dev)->sd_addr + AZX_REG_##reg))
#define azx_sd_writeb(chip, dev, reg, value) \
- ((chip)->ops->reg_writeb(value, (dev)->sd_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_writeb(value, (dev)->sd_addr + AZX_REG_##reg))
#define azx_sd_readb(chip, dev, reg) \
- ((chip)->ops->reg_readb((dev)->sd_addr + AZX_REG_##reg))
+ ((chip)->io_ops->reg_readb((dev)->sd_addr + AZX_REG_##reg))
#define azx_has_pm_runtime(chip) \
(!AZX_DCAPS_PM_RUNTIME || ((chip)->driver_caps & AZX_DCAPS_PM_RUNTIME))
/*
* constructor
*/
+static const struct hdac_io_ops pci_hda_io_ops;
+static const struct hda_controller_ops pci_hda_ops;
+
static int azx_create(struct snd_card *card, struct pci_dev *pci,
int dev, unsigned int driver_caps,
- const struct hda_controller_ops *hda_ops,
struct azx **rchip)
{
static struct snd_device_ops ops = {
mutex_init(&chip->open_mutex);
chip->card = card;
chip->pci = pci;
- chip->ops = hda_ops;
+ chip->ops = &pci_hda_ops;
+ chip->io_ops = &pci_hda_io_ops;
chip->irq = -1;
chip->driver_caps = driver_caps;
chip->driver_type = driver_caps & 0xff;
}
/* DMA page allocation helpers. */
-static int dma_alloc_pages(struct azx *chip,
+static int dma_alloc_pages(struct hdac_bus *bus,
int type,
size_t size,
struct snd_dma_buffer *buf)
{
+ struct azx *chip = to_hda_bus(bus)->private_data;
int err;
err = snd_dma_alloc_pages(type,
- chip->card->dev,
+ bus->dev,
size, buf);
if (err < 0)
return err;
return 0;
}
-static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
+static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
{
+ struct azx *chip = to_hda_bus(bus)->private_data;
+
mark_pages_wc(chip, buf, false);
snd_dma_free_pages(buf);
}
#endif
}
-static const struct hda_controller_ops pci_hda_ops = {
+static const struct hdac_io_ops pci_hda_io_ops = {
.reg_writel = pci_azx_writel,
.reg_readl = pci_azx_readl,
.reg_writew = pci_azx_writew,
.reg_readw = pci_azx_readw,
.reg_writeb = pci_azx_writeb,
.reg_readb = pci_azx_readb,
- .disable_msi_reset_irq = disable_msi_reset_irq,
.dma_alloc_pages = dma_alloc_pages,
.dma_free_pages = dma_free_pages,
+};
+
+static const struct hda_controller_ops pci_hda_ops = {
+ .disable_msi_reset_irq = disable_msi_reset_irq,
.substream_alloc_pages = substream_alloc_pages,
.substream_free_pages = substream_free_pages,
.pcm_mmap_prepare = pcm_mmap_prepare,
return err;
}
- err = azx_create(card, pci, dev, pci_id->driver_data,
- &pci_hda_ops, &chip);
+ err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
if (err < 0)
goto out_free;
card->private_data = chip;
#endif
}
+ err = azx_bus_create(chip, model[dev]);
+ if (err < 0)
+ goto out_free;
+
err = azx_first_init(chip);
if (err < 0)
goto out_free;
#endif
/* create codec instances */
- err = azx_bus_create(chip, model[dev]);
- if (err < 0)
- goto out_free;
-
err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
if (err < 0)
goto out_free;
/*
* DMA page allocation ops.
*/
-static int dma_alloc_pages(struct azx *chip, int type, size_t size,
+static int dma_alloc_pages(struct hdac_bus *bus, int type, size_t size,
struct snd_dma_buffer *buf)
{
- return snd_dma_alloc_pages(type, chip->card->dev, size, buf);
+ return snd_dma_alloc_pages(type, bus->dev, size, buf);
}
-static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
+static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
{
snd_dma_free_pages(buf);
}
return (v >> shift) & 0xff;
}
-static const struct hda_controller_ops hda_tegra_ops = {
+static const struct hdac_io_ops hda_tegra_io_ops = {
.reg_writel = hda_tegra_writel,
.reg_readl = hda_tegra_readl,
.reg_writew = hda_tegra_writew,
.reg_readb = hda_tegra_readb,
.dma_alloc_pages = dma_alloc_pages,
.dma_free_pages = dma_free_pages,
+};
+
+static const struct hda_controller_ops hda_tegra_ops = {
.substream_alloc_pages = substream_alloc_pages,
.substream_free_pages = substream_free_pages,
};
*/
static int hda_tegra_create(struct snd_card *card,
unsigned int driver_caps,
- const struct hda_controller_ops *hda_ops,
struct hda_tegra *hda)
{
static struct snd_device_ops ops = {
spin_lock_init(&chip->reg_lock);
mutex_init(&chip->open_mutex);
chip->card = card;
- chip->ops = hda_ops;
+ chip->ops = &hda_tegra_ops;
+ chip->io_ops = &hda_tegra_io_ops;
chip->irq = -1;
chip->driver_caps = driver_caps;
chip->driver_type = driver_caps & 0xff;
return err;
}
- err = hda_tegra_create(card, driver_flags, &hda_tegra_ops, hda);
+ err = azx_bus_create(chip, NULL);
+ if (err < 0)
+ goto out_free;
+
+ err = hda_tegra_create(card, driver_flags, hda);
if (err < 0)
goto out_free;
card->private_data = chip;
goto out_free;
/* create codec instances */
- err = azx_bus_create(chip, NULL);
- if (err < 0)
- goto out_free;
-
err = azx_probe_codecs(chip, 0);
if (err < 0)
goto out_free;