diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig index 9775393d46b6..4258391241a7 100644 --- a/sound/soc/ti/Kconfig +++ b/sound/soc/ti/Kconfig @@ -53,6 +53,14 @@ config SND_SOC_OMAP_DMIC Say Y or M here if you want to have support for DMIC IP found in OMAP4 and OMAP5. +config SND_SOC_OMAP_MCASP + tristate "Multichannel Audio Serial Port (McASP) support" + depends on ARCH_OMAP || ARCH_OMAP1 || COMPILE_TEST + select SND_SOC_TI_SDMA_PCM + help + Say Y or M here if you want to have support for McASP IP found in + Texas Instruments OMAP1/2/3/4/5 SoCs. + config SND_SOC_OMAP_MCBSP tristate "Multichannel Buffered Serial Port (McBSP) support" depends on ARCH_OMAP || ARCH_OMAP1 || COMPILE_TEST @@ -112,6 +120,7 @@ config SND_SOC_OMAP3_TWL4030 - OMAP3EVM - SDP3430 - Zoom2 + - GTA04 config SND_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" @@ -120,6 +129,10 @@ config SND_SOC_OMAP_ABE_TWL6040 select SND_SOC_OMAP_DMIC select SND_SOC_OMAP_MCPDM select SND_SOC_TWL6040 + select SND_SOC_OMAP_MCASP + select SND_SOC_OMAP_MCBSP + select SND_DYNAMIC_MINORS + select FW_LOADER help Say Y or M if you want to add support for SoC audio on OMAP boards using ABE and twl6040 codec. This driver currently supports: diff --git a/sound/soc/ti/Makefile b/sound/soc/ti/Makefile index a21e5b0061de..22d19491d932 100644 --- a/sound/soc/ti/Makefile +++ b/sound/soc/ti/Makefile @@ -14,6 +14,7 @@ snd-soc-davinci-asp-objs := davinci-i2s.o snd-soc-davinci-mcasp-objs := davinci-mcasp.o snd-soc-davinci-vcif-objs := davinci-vcif.o snd-soc-omap-dmic-objs := omap-dmic.o +snd-soc-omap-mcasp-objs := omap-mcasp.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o omap-mcbsp-st.o snd-soc-omap-mcpdm-objs := omap-mcpdm.o @@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SOC_DAVINCI_ASP) += snd-soc-davinci-asp.o obj-$(CONFIG_SND_SOC_DAVINCI_MCASP) += snd-soc-davinci-mcasp.o obj-$(CONFIG_SND_SOC_DAVINCI_VCIF) += snd-soc-davinci-vcif.o obj-$(CONFIG_SND_SOC_OMAP_DMIC) += snd-soc-omap-dmic.o +obj-$(CONFIG_SND_SOC_OMAP_MCASP) += snd-soc-omap-mcasp.o obj-$(CONFIG_SND_SOC_OMAP_MCBSP) += snd-soc-omap-mcbsp.o obj-$(CONFIG_SND_SOC_OMAP_MCPDM) += snd-soc-omap-mcpdm.o diff --git a/sound/soc/ti/omap-mcasp.c b/sound/soc/ti/omap-mcasp.c new file mode 100644 index 000000000000..4aca3a2188db --- /dev/null +++ b/sound/soc/ti/omap-mcasp.c @@ -0,0 +1,714 @@ +/* + * ALSA SoC McASP Audio Layer for TI OMAP processor + * + * Multi-channel Audio Serial Port Driver + * + * Author: Jon Hunter , + * Dan Milea , + * + * Based upon McASP driver written for TI DaVinci + * + * Copyright: (C) 2011 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "omap-mcasp.h" +#include "sdma-pcm.h" + +/* + * McASP register definitions + */ +#define OMAP_MCASP_PID_REG 0x00 +#define OMAP_MCASP_SYSCONFIG_REG 0x04 + +#define OMAP_MCASP_PFUNC_REG 0x10 +#define OMAP_MCASP_PDIR_REG 0x14 +#define OMAP_MCASP_PDOUT_REG 0x18 +#define OMAP_MCASP_PDIN_REG 0x1c +#define OMAP_MCASP_PDSET_REG 0x1c +#define OMAP_MCASP_PDCLR_REG 0x20 + +#define OMAP_MCASP_GBLCTL_REG 0x44 +#define OMAP_MCASP_AMUTE_REG 0x48 + +#define OMAP_MCASP_TXDITCTL_REG 0x50 + +#define OMAP_MCASP_TXMASK_REG 0xa4 +#define OMAP_MCASP_TXFMT_REG 0xa8 +#define OMAP_MCASP_TXFMCTL_REG 0xac + +#define OMAP_MCASP_ACLKXCTL_REG 0xb0 +#define OMAP_MCASP_AHCLKXCTL_REG 0xb4 +#define OMAP_MCASP_TXTDM_REG 0xb8 +#define OMAP_MCASP_EVTCTLX_REG 0xbc + +#define OMAP_MCASP_TXSTAT_REG 0xc0 +#define OMAP_MCASP_TXSTAT_MASK 0x1ff + +#define OMAP_MCASP_TXTDMSLOT_REG 0xc4 +#define OMAP_MCASP_TXCLKCHK_REG 0xc8 +#define OMAP_MCASP_TXEVTCTL_REG 0xcc + +/* Left(even TDM Slot) Channel Status Register File */ +#define OMAP_MCASP_DITCSRA_REG 0x100 +/* Right(odd TDM slot) Channel Status Register File */ +#define OMAP_MCASP_DITCSRB_REG 0x118 +/* Left(even TDM slot) User Data Register File */ +#define OMAP_MCASP_DITUDRA_REG 0x130 +/* Right(odd TDM Slot) User Data Register File */ +#define OMAP_MCASP_DITUDRB_REG 0x148 + +/* Serializer n Control Register */ +#define OMAP_MCASP_XRSRCTL0_REG 0x180 + +/* Transmit Buffer for Serializer */ +#define OMAP_MCASP_TXBUF0_REG 0x200 + +/* + * OMAP_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits + */ +#define AXR0 BIT(0) +#define PFUNC_AMUTE BIT(25) +#define ACLKX BIT(26) +#define AHCLKX BIT(27) +#define AFSX BIT(28) + +/* + * OMAP_MCASP_PDIR_REG - Pin Direction Register Bits + */ +#define AXR0 BIT(0) +#define PDIR_AMUTE BIT(25) +#define ACLKX BIT(26) +#define AHCLKX BIT(27) +#define AFSX BIT(28) + +/* + * OMAP_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits + */ +#define DITEN BIT(0) /* Transmit DIT mode enable/disable */ +#define VA BIT(2) +#define VB BIT(3) + +/* + * OMAP_MCASP_TXFMT_REG - Transmit Bitstream Format Register Bits + */ +#define TXROT(val) (val) +#define TXROT_MASK TXROT(0x7) +#define TXSEL BIT(3) +#define TXSSZ(val) (val<<4) +#define TXSSZ_MASK TXSSZ(0xf<<4) +#define TXPAD(val) (val<<13) +#define TXORD BIT(15) +#define FSXDLY(val) (val<<16) + +#define ROTATE_24 0x6 +#define SLOTSIZE_32 0xf + +/* + * OMAP_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits + */ +#define FSXPOL BIT(0) +#define AFSXE BIT(1) +#define FSXDUR BIT(4) +#define FSXMOD(val) (val<<7) + +/* + * OMAP_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits + */ +#define ACLKXDIV(val) (val) +#define ACLKXE BIT(5) +#define TX_ASYNC BIT(6) + +/* + * OMAP_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control + * Register Bits + */ +#define AHCLKXDIV(val) (val) +#define AHCLKXE BIT(15) + +/* + * OMAP_MCASP_EVTCTLX_REG - Transmitter Interrupt Control Register bits + */ +#define EVTCTLX_XUNDRN BIT(0) + +/* + * OMAP_MCASP_TXSTAT_REG - Transmit Status Register Bits + */ +#define TXSTAT_XUNDRN (0x1 << 0) +#define TXSTAT_XSYNCERR (0x1 << 1) +#define TXSTAT_XCKFAIL (0x1 << 2) +#define TXSTAT_XDMSLOT (0x1 << 3) +#define TXSTAT_XLAST (0x1 << 4) +#define TXSTAT_XDATA (0x1 << 5) +#define TXSTAT_XSTAFRM (0x1 << 6) +#define TXSTAT_XDMAERR (0x1 << 7) +#define TXSTAT_XERR (0x1 << 8) + +/* + * OMAP_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits + */ +#define MODE(val) (val) +#define TXSTATE BIT(4) + +/* + * OMAP_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration + */ +#define TXTDMS(n) (1<>= 7; + + /* rounded division: fclk_rate / tgt_sample_rate + 0.5 */ + divisor = (2 * fclk_rate + tgt_sample_rate) / (2 * tgt_sample_rate); + if (!divisor) + return -EINVAL; + + sample_rate = fclk_rate / divisor; + + /* ppm calculation in two steps to avoid overflow */ + ppm = abs(tgt_sample_rate - sample_rate); + ppm = (1000000 * ppm) / tgt_sample_rate; + + if (ppm > MCASP_ALLOWED_PPM) + return -EINVAL; + + /* At this point, divisor holds the product of the two divider values we + * need to use for ACLKXCTL and AHCLKXCTL. ACLKXCTL holds a 5 bit + * divider [1, 32], while AHCLKXCTL holds a 12 bit divider [1, 4096]. + * We need to make sure that we can factor divisor into two integers + * which will fit into these divider registers. Find the largest 5-bit + * + 1 value which divides divisor and use that as our smaller divider. + * After removing this factor from divisor, if the result is <= 4096, + * then we have succeeded and will be able to produce the target sample + * rate. + */ + for (i = 32; (i > 1) && (divisor % i); --i) + ; /* no body */ + + /* Make sure to subtract one, registers hold the value of the divider + * minus one (IOW, to divide by 5, the register gets programmed with the + * value 4. */ + *out_div_lo = i - 1; + *out_div_hi = (divisor / i) - 1; + + return (*out_div_hi <= 4096) ? 0 : -EINVAL; +} + +static int omap_mcasp_start(struct omap_mcasp *mcasp) +{ + int i; + mcasp_set_ctl_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, TXHCLKRST); + mcasp_set_ctl_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, TXCLKRST); + mcasp_set_ctl_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, TXSERCLR); + + /* Wait until the DMA has loaded the first sample into TXBUF before we + * let the TX state machine and frame sync generator out of reset. */ + i = 0; + while (1) { + u32 reg = mcasp_get_reg(mcasp->base + OMAP_MCASP_TXSTAT_REG); + if (!(reg & TXSTAT_XDATA)) + break; + + if (++i > 1000) { + pr_err("Timeout waiting for DMA to load first sample of audio.\n"); + return -ETIMEDOUT; + } + + udelay(1); + } + + mcasp_set_ctl_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, TXSMRST); + mcasp_set_ctl_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, TXFSRST); + mcasp_clr_bits(mcasp->base + OMAP_MCASP_TXEVTCTL_REG, TXDATADMADIS); + + /* enable IRQ sources */ + mcasp_set_bits(mcasp->base + OMAP_MCASP_EVTCTLX_REG, EVTCTLX_XUNDRN); + + return 0; +} + +static void omap_mcasp_stop(struct omap_mcasp *mcasp) +{ + /* disable IRQ sources */ + mcasp_set_reg(mcasp->base + OMAP_MCASP_EVTCTLX_REG, 0); + + mcasp_set_reg(mcasp->base + OMAP_MCASP_GBLCTL_REG, 0); + mcasp_set_reg(mcasp->base + OMAP_MCASP_TXSTAT_REG, + OMAP_MCASP_TXSTAT_MASK); +} + +/* S/PDIF */ +static int omap_mcasp_setup(struct omap_mcasp *mcasp, unsigned int rate) +{ + u32 aclkxdiv, ahclkxdiv, ditcsr; + int res; + + /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */ + mcasp_set_reg(mcasp->base + OMAP_MCASP_TXFMCTL_REG, + AFSXE | FSXMOD(0x180)); + + /* Set the TX clock controls : div = 1 and internal */ + mcasp_set_reg(mcasp->base + OMAP_MCASP_ACLKXCTL_REG, + ACLKXE | TX_ASYNC); + + /* Set the HS TX clock controls : div = 1 and internal */ + mcasp_set_reg(mcasp->base + OMAP_MCASP_AHCLKXCTL_REG, AHCLKXE); + + /* The SPDIF bit clock is derived from the McASP functional clock. + * The McASP has two programmable clock dividers (aclkxdiv and + * ahclkxdiv) that are configured via the registers MCASP_ACLKXCTL + * and MCASP_AHCLKXCTL. For SPDIF the bit clock frequency should be + * 128 * sample rate freq. The dividers are defined as part of + * platform data as they are dependent upon the functional clock + * setting. Lookup the appropriate dividers for the sampling + * frequency that we are playing. + */ + res = mcasp_compute_clock_dividers(clk_get_rate(mcasp->fclk), + rate, + &aclkxdiv, + &ahclkxdiv); + if (res) { + dev_err(mcasp->dev, + "%s: No valid McASP config for sampling rate (%d)!\n", + __func__, rate); + return res; + } + + switch (rate) { + case 22050: + ditcsr = OMAP_MCASP_DITCSR_22050HZ; + break; + case 24000: + ditcsr = OMAP_MCASP_DITCSR_24000HZ; + break; + case 32000: + ditcsr = OMAP_MCASP_DITCSR_32000HZ; + break; + case 44100: + ditcsr = OMAP_MCASP_DITCSR_44100HZ; + break; + case 48000: + ditcsr = OMAP_MCASP_DITCSR_48000HZ; + break; + case 88200: + ditcsr = OMAP_MCASP_DITCSR_88200HZ; + break; + case 96000: + ditcsr = OMAP_MCASP_DITCSR_96000HZ; + break; + case 176400: + ditcsr = OMAP_MCASP_DITCSR_176400HZ; + break; + case 192000: + ditcsr = OMAP_MCASP_DITCSR_192000HZ; + break; + default: + dev_err(mcasp->dev, "%s: Invalid sampling rate: %d\n", + __func__, rate); + return -EINVAL; + } + mcasp_set_reg(mcasp->base + OMAP_MCASP_DITCSRA_REG, ditcsr); + mcasp_set_reg(mcasp->base + OMAP_MCASP_DITCSRB_REG, ditcsr); + mcasp_set_bits(mcasp->base + OMAP_MCASP_AHCLKXCTL_REG, + AHCLKXDIV(ahclkxdiv)); + mcasp_set_bits(mcasp->base + OMAP_MCASP_ACLKXCTL_REG, + AHCLKXDIV(aclkxdiv)); + + /* Configure McASP formatter */ + mcasp_mod_bits(mcasp->base + OMAP_MCASP_TXFMT_REG, + TXSSZ(SLOTSIZE_32), TXSSZ_MASK); + mcasp_mod_bits(mcasp->base + OMAP_MCASP_TXFMT_REG, TXROT(ROTATE_24), + TXROT_MASK); + mcasp_set_reg(mcasp->base + OMAP_MCASP_TXMASK_REG, 0xFFFF); + + /* Set the TX tdm : for all the slots */ + mcasp_set_reg(mcasp->base + OMAP_MCASP_TXTDM_REG, 0xFFFFFFFF); + + /* configure the serializer for transmit mode operation */ + mcasp_set_bits(mcasp->base + OMAP_MCASP_XRSRCTL0_REG, MODE(1)); + + /* All PINS as McASP */ + mcasp_set_reg(mcasp->base + OMAP_MCASP_PFUNC_REG, 0); + + mcasp_set_bits(mcasp->base + OMAP_MCASP_PDIR_REG, AXR0); + + /* Enable the DIT */ + mcasp_set_bits(mcasp->base + OMAP_MCASP_TXDITCTL_REG, DITEN); + + mcasp_set_reg(mcasp->base + OMAP_MCASP_TXSTAT_REG, 0xFF); + + return 0; +} + +static irqreturn_t omap_mcasp_irq_handler(int irq, void *data) +{ + struct omap_mcasp *mcasp = data; + u32 txstat; + + txstat = mcasp_get_reg(mcasp->base + OMAP_MCASP_TXSTAT_REG); + if (txstat & TXSTAT_XUNDRN) { + dev_err(mcasp->dev, "%s: Underrun (0x%08x)\n", __func__, + txstat); + + /* Try to recover from this state */ + spin_lock(&mcasp->lock); + if (likely(mcasp->stream_rate)) { + dev_err(mcasp->dev, "%s: Trying to recover\n", + __func__); + omap_mcasp_stop(mcasp); + omap_mcasp_setup(mcasp, mcasp->stream_rate); + omap_mcasp_start(mcasp); + } + spin_unlock(&mcasp->lock); + } + + mcasp_set_reg(mcasp->base + OMAP_MCASP_TXSTAT_REG, txstat); + + return IRQ_HANDLED; +} + +static int omap_mcasp_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + + pm_runtime_get_sync(mcasp->dev); + + snd_soc_dai_set_dma_data(dai, substream, + &omap_mcasp_dai_dma_params[substream->stream]); + + return 0; +} + +static void omap_mcasp_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + + pm_runtime_put_sync(mcasp->dev); + +} + +static int omap_mcasp_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + + omap_mcasp_stop(mcasp); + + if (omap_mcasp_setup(mcasp, params_rate(params)) < 0) + return -EPERM; + + return 0; +} + +static int omap_mcasp_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *cpu_dai) +{ + struct omap_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&mcasp->lock, flags); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + mcasp->stream_rate = substream->runtime->rate; + ret = omap_mcasp_start(mcasp); + break; + + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + mcasp->stream_rate = 0; + omap_mcasp_stop(mcasp); + break; + + default: + ret = -EINVAL; + } + + spin_unlock_irqrestore(&mcasp->lock, flags); + + return ret; +} + +static struct snd_soc_dai_ops omap_mcasp_dai_ops = { + .startup = omap_mcasp_startup, + .shutdown = omap_mcasp_shutdown, + .trigger = omap_mcasp_trigger, + .hw_params = omap_mcasp_hw_params, + +}; + +#define MCASP_RATES (SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_192000) + +static struct snd_soc_dai_driver omap_mcasp_dai = { + .playback = { + .channels_min = 1, + .channels_max = 384, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = MCASP_RATES, + }, + .ops = &omap_mcasp_dai_ops, +}; + +static const struct snd_soc_component_driver omap_mcasp_component = { + .name = "omap-mcasp", +}; + +static int asoc_mcasp_probe(struct platform_device *pdev) +{ + struct omap_mcasp *mcasp; + struct resource *res; + long fclk_rate; + int ret = 0; + + mcasp = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcasp), GFP_KERNEL); + if (!mcasp) { + dev_err(&pdev->dev, "cannot allocate memory\n"); + return -ENOMEM; + } + + spin_lock_init(&mcasp->lock); + + omap_mcasp_dai_dma_params[0].filter_data = "axevt"; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no resource\n"); + return -ENODEV; + } + + mcasp->base = devm_ioremap_resource(&pdev->dev, res); + if (!mcasp->base) { + dev_err(&pdev->dev, "cannot remap\n"); + return -ENOMEM; + } + + mcasp->irq = platform_get_irq(pdev, 0); + if (mcasp->irq < 0) { + dev_err(&pdev->dev, "invalid IRQ number\n"); + return mcasp->irq; + } + + ret = devm_request_threaded_irq(&pdev->dev, mcasp->irq, NULL, + omap_mcasp_irq_handler, + IRQF_ONESHOT, "McASP", mcasp); + if (ret) { + dev_err(mcasp->dev, "IRQ request failed\n"); + return ret; + } + + mcasp->fclk = clk_get(&pdev->dev, "fck"); + if (!mcasp->fclk) { + dev_err(mcasp->dev, "cant get fck\n"); + return -ENODEV; + } + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + + fclk_rate = clk_get_rate(mcasp->fclk); + + platform_set_drvdata(pdev, mcasp); + mcasp->dev = &pdev->dev; + + ret = snd_soc_register_component(&pdev->dev, &omap_mcasp_component, + &omap_mcasp_dai, 1); + if (ret < 0) + goto err_dai; + + pm_runtime_put_sync(&pdev->dev); + + return sdma_pcm_platform_register(&pdev->dev, "axevt", NULL);; + +err_dai: + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return ret; +} + +static int asoc_mcasp_remove(struct platform_device *pdev) +{ + struct omap_mcasp *mcasp = dev_get_drvdata(&pdev->dev); + + snd_soc_unregister_component(&pdev->dev); + pm_runtime_disable(&pdev->dev); + clk_put(mcasp->fclk); + + return 0; +} + +static const struct of_device_id omap_mcasp_of_match[] = { + { .compatible = "ti,omap4-mcasp", }, + { } +}; +MODULE_DEVICE_TABLE(of, omap_mcasp_of_match); + +static struct platform_driver omap_mcasp_driver = { + .driver = { + .name = "omap-mcasp", + .owner = THIS_MODULE, + .of_match_table = omap_mcasp_of_match, + }, + .probe = asoc_mcasp_probe, + .remove = asoc_mcasp_remove, +}; + +static int __init omap_mcasp_init(void) +{ + return platform_driver_register(&omap_mcasp_driver); +} +module_init(omap_mcasp_init); + +static void __exit omap_mcasp_exit(void) +{ + platform_driver_unregister(&omap_mcasp_driver); +} +module_exit(omap_mcasp_exit); + + +MODULE_AUTHOR("Jon Hunter "); +MODULE_DESCRIPTION("TI OMAP McASP SoC Interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:omap-mcasp"); diff --git a/sound/soc/ti/omap-mcasp.h b/sound/soc/ti/omap-mcasp.h new file mode 100644 index 000000000000..3fd16040b945 --- /dev/null +++ b/sound/soc/ti/omap-mcasp.h @@ -0,0 +1,35 @@ +/* + * ALSA SoC McASP Audio Layer for TI OMAP processor + * + * MCASP related definitions + * + * Author: Jon Hunter , + * Dan Milea , + * + * Based upon McASP driver written for TI DaVinci + * + * Copyright: (C) 2011 Texas Instruments + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef OMAP_MCASP_H +#define OMAP_MCASP_H + +#include + +#define OMAP44XX_MCASP_CFG_BASE 0x49028000 +#define OMAP44XX_MCASP_DAT_BASE 0x4902A000 + +struct omap_mcasp { + struct device *dev; + void __iomem *base; + spinlock_t lock; + struct clk *fclk; + int irq; + unsigned int stream_rate; +}; + +#endif /* OMAP_MCASP_H */