At Tue, 8 Apr 2014 12:15:33 -0700, Dylan Reid wrote: > > diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig > index ac17c3f..4f6ee6b 100644 > --- a/sound/pci/hda/Kconfig > +++ b/sound/pci/hda/Kconfig > @@ -20,6 +20,20 @@ config SND_HDA_INTEL > To compile this driver as a module, choose M here: the module > will be called snd-hda-intel. > > +config SND_HDA_TEGRA > + tristate "Tegra HD Audio" > + select SND_HDA Does (or should) this be build generically? Or any arch-specific dependency, or maybe at least "depends on OF"? > + help > + Say Y here to support the HDA controller present in Nvidia > + Tegra SoCs > + > + This options enables support for the HD Audio controller > + present in some Nvidia Tegra SoCs, used to communicate audio > + to the HDMI output. > + > + To compile this driver as a module, choose M here: the module > + will be called snd-hda-tegra. > + > if SND_HDA > > config SND_HDA_DSP_LOADER > diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile > index d0d0c19..194f3093 100644 > --- a/sound/pci/hda/Makefile > +++ b/sound/pci/hda/Makefile > @@ -1,5 +1,6 @@ > snd-hda-intel-objs := hda_intel.o > snd-hda-controller-objs := hda_controller.o > +snd-hda-tegra-objs := hda_tegra.o > # for haswell power well > snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o > > @@ -47,3 +48,4 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o > # otherwise the codec patches won't be hooked before the PCI probe > # when built in kernel > obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o > +obj-$(CONFIG_SND_HDA_TEGRA) += snd-hda-tegra.o > diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c > new file mode 100644 > index 0000000..c36bbca > --- /dev/null > +++ b/sound/pci/hda/hda_tegra.c > @@ -0,0 +1,695 @@ > +/* > + * > + * Implementation of primary alsa driver code base for Tegra HDA. > + * > + * 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; either version 2 of the License, or (at your option) > + * any later version. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + */ > + > +#include <linux/clk.h> > +#include <linux/clocksource.h> > +#include <linux/delay.h> > +#include <linux/interrupt.h> > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/dma-mapping.h> > +#include <linux/moduleparam.h> > +#include <linux/init.h> > +#include <linux/slab.h> > +#include <linux/mutex.h> > +#include <linux/reboot.h> > +#include <linux/io.h> > +#include <linux/pm_runtime.h> > +#include <linux/of_device.h> > +#include <linux/time.h> > +#include <linux/completion.h> > + > +#include <sound/core.h> > +#include <sound/initval.h> > +#include <linux/firmware.h> > +#include "hda_codec.h" > +#include "hda_controller.h" > +#include "hda_priv.h" > + > +#define DRV_NAME "tegra-hda" > + > +/* Defines for Nvidia Tegra HDA support */ > +#define NVIDIA_TEGRA_HDA_BAR0_OFFSET 0x8000 > + > +#define NVIDIA_TEGRA_HDA_CFG_CMD_OFFSET 0x1004 > +#define NVIDIA_TEGRA_HDA_CFG_BAR0_OFFSET 0x1010 > + > +#define NVIDIA_TEGRA_HDA_ENABLE_IO_SPACE (1 << 0) > +#define NVIDIA_TEGRA_HDA_ENABLE_MEM_SPACE (1 << 1) > +#define NVIDIA_TEGRA_HDA_ENABLE_BUS_MASTER (1 << 2) > +#define NVIDIA_TEGRA_HDA_ENABLE_SERR (1 << 8) > +#define NVIDIA_TEGRA_HDA_DISABLE_INTR (1 << 10) > +#define NVIDIA_TEGRA_HDA_BAR0_INIT_PROGRAM 0xFFFFFFFF > +#define NVIDIA_TEGRA_HDA_BAR0_FINAL_PROGRAM (1 << 14) > + > +/* IPFS */ > +#define NVIDIA_TEGRA_HDA_IPFS_CONFIG 0x180 > +#define NVIDIA_TEGRA_HDA_IPFS_EN_FPCI 0x1 > + > +#define NVIDIA_TEGRA_HDA_IPFS_FPCI_BAR0 0x80 > +#define NVIDIA_TEGRA_HDA_FPCI_BAR0_START 0x40 > + > +#define NVIDIA_TEGRA_HDA_IPFS_INTR_MASK 0x188 > +#define NVIDIA_TEGRA_HDA_IPFS_EN_INTR (1 << 16) > + > +struct hda_tegra_data { > + struct azx chip; > + struct platform_device *pdev; > + struct clk **platform_clks; > + int platform_clk_count; > + void __iomem *remap_config_addr; > +}; > + > +static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; > +module_param_array(probe_mask, int, NULL, 0444); > +MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); > + > +static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; > +static int *power_save_addr = &power_save; > +module_param(power_save, bint, 0644); > +MODULE_PARM_DESC(power_save, > + "Automatic power-saving timeout (in seconds, 0 = disable)."); > + > +/* > + * DMA page allocation ops. > + */ > +static int dma_alloc_pages(struct azx *chip, > + int type, > + size_t size, > + struct snd_dma_buffer *buf) > +{ > + return snd_dma_alloc_pages(type, > + chip->card->dev, > + size, buf); > +} > + > +static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf) > +{ > + snd_dma_free_pages(buf); > +} > + > +static int substream_alloc_pages(struct azx *chip, > + struct snd_pcm_substream *substream, > + size_t size) > +{ > + struct azx_dev *azx_dev = get_azx_dev(substream); > + > + azx_dev->bufsize = 0; > + azx_dev->period_bytes = 0; > + azx_dev->format_val = 0; > + return snd_pcm_lib_malloc_pages(substream, size); > +} > + > +static int substream_free_pages(struct azx *chip, > + struct snd_pcm_substream *substream) > +{ > + return snd_pcm_lib_free_pages(substream); > +} > + > +/* > + * Register access ops. Tegra HDA register access is DWORD only. > + */ > +#define MASK_LONG_ALIGN 0x3UL > +#define SHIFT_BYTE 3 > +#define SHIFT_BITS(addr) \ > + (((unsigned int)(addr) & MASK_LONG_ALIGN) << SHIFT_BYTE) > +#define ADDR_ALIGN_L(addr) \ > + (void *)((unsigned int)(addr) & ~MASK_LONG_ALIGN) > +#define MASK(bits) (BIT(bits) - 1) > +#define MASK_REG(addr, bits) (MASK(bits) << SHIFT_BITS(addr)) This results in lots of compile warnings on 64bit machines. sound/pci/hda/hda_tegra.c: In function ‘tegra_hda_writew’: sound/pci/hda/hda_tegra.c:128:4: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] (((unsigned int)(addr) & MASK_LONG_ALIGN) << SHIFT_BYTE) thanks, Takashi -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html