On Wed, Apr 9, 2014 at 12:43 AM, Takashi Iwai <tiwai@xxxxxxx> wrote: > 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"? Thanks Takashi, Yes I think it should depend on OF and ARCH_TEGRA. > >> + 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. Yes it does, thanks for checking, I'll fix that up. > > 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 linux-tegra" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html