diff options
Diffstat (limited to 'sound/soc/omap')
-rw-r--r-- | sound/soc/omap/Kconfig | 11 | ||||
-rw-r--r-- | sound/soc/omap/Makefile | 4 | ||||
-rw-r--r-- | sound/soc/omap/omap-hdmi.c | 158 | ||||
-rw-r--r-- | sound/soc/omap/omap-hdmi.h | 36 | ||||
-rw-r--r-- | sound/soc/omap/omap4-hdmi-card.c | 129 |
5 files changed, 338 insertions, 0 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 99054cf1f68f..fe83d0d176be 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -9,6 +9,9 @@ config SND_OMAP_SOC_MCBSP config SND_OMAP_SOC_MCPDM tristate +config SND_OMAP_SOC_HDMI + tristate + config SND_OMAP_SOC_N810 tristate "SoC Audio support for Nokia N810" depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C @@ -100,6 +103,14 @@ config SND_OMAP_SOC_SDP4430 Say Y if you want to add support for SoC audio on Texas Instruments SDP4430. +config SND_OMAP_SOC_OMAP4_HDMI + tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" + depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS && ARCH_OMAP4 + select SND_OMAP_SOC_HDMI + help + Say Y if you want to add support for SoC HDMI audio on Texas Instruments + OMAP4 chips + config SND_OMAP_SOC_OMAP3_PANDORA tristate "SoC Audio support for OMAP3 Pandora" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 6c2c87eed5bb..59e2c8d1e38d 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -2,10 +2,12 @@ snd-soc-omap-objs := omap-pcm.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o +snd-soc-omap-hdmi-objs := omap-hdmi.o obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o +obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o # OMAP Machine Support snd-soc-n810-objs := n810.o @@ -21,6 +23,7 @@ snd-soc-omap3pandora-objs := omap3pandora.o snd-soc-omap3beagle-objs := omap3beagle.o snd-soc-zoom2-objs := zoom2.o snd-soc-igep0020-objs := igep0020.o +snd-soc-omap4-hdmi-objs := omap4-hdmi-card.o obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o @@ -36,3 +39,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o +obj-$(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) += snd-soc-omap4-hdmi.o diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c new file mode 100644 index 000000000000..36c6eaeffb02 --- /dev/null +++ b/sound/soc/omap/omap-hdmi.c @@ -0,0 +1,158 @@ +/* + * omap-hdmi.c + * + * OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors. + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * Authors: Jorge Candelaria <jorge.candelaria@ti.com> + * Ricardo Neri <ricardo.neri@ti.com> + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/initval.h> +#include <sound/soc.h> + +#include <plat/dma.h> +#include "omap-pcm.h" +#include "omap-hdmi.h" + +#define DRV_NAME "hdmi-audio-dai" + +static struct omap_pcm_dma_data omap_hdmi_dai_dma_params = { + .name = "HDMI playback", + .sync_mode = OMAP_DMA_SYNC_PACKET, +}; + +static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int err; + /* + * Make sure that the period bytes are multiple of the DMA packet size. + * Largest packet size we use is 32 32-bit words = 128 bytes + */ + err = snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128); + if (err < 0) + return err; + + return 0; +} + +static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + int err = 0; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + omap_hdmi_dai_dma_params.packet_size = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + omap_hdmi_dai_dma_params.packet_size = 32; + break; + default: + err = -EINVAL; + } + + omap_hdmi_dai_dma_params.data_type = OMAP_DMA_DATA_TYPE_S32; + + snd_soc_dai_set_dma_data(dai, substream, + &omap_hdmi_dai_dma_params); + + return err; +} + +static struct snd_soc_dai_ops omap_hdmi_dai_ops = { + .startup = omap_hdmi_dai_startup, + .hw_params = omap_hdmi_dai_hw_params, +}; + +static struct snd_soc_dai_driver omap_hdmi_dai = { + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = OMAP_HDMI_RATES, + .formats = OMAP_HDMI_FORMATS, + }, + .ops = &omap_hdmi_dai_ops, +}; + +static __devinit int omap_hdmi_probe(struct platform_device *pdev) +{ + int ret; + struct resource *hdmi_rsrc; + + hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!hdmi_rsrc) { + dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n"); + return -EINVAL; + } + + omap_hdmi_dai_dma_params.port_addr = hdmi_rsrc->start + + OMAP_HDMI_AUDIO_DMA_PORT; + + hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!hdmi_rsrc) { + dev_err(&pdev->dev, "Cannot obtain IORESOURCE_DMA HDMI\n"); + return -EINVAL; + } + + omap_hdmi_dai_dma_params.dma_req = hdmi_rsrc->start; + + ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai); + return ret; +} + +static int __devexit omap_hdmi_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + return 0; +} + +static struct platform_driver hdmi_dai_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = omap_hdmi_probe, + .remove = __devexit_p(omap_hdmi_remove), +}; + +static int __init hdmi_dai_init(void) +{ + return platform_driver_register(&hdmi_dai_driver); +} +module_init(hdmi_dai_init); + +static void __exit hdmi_dai_exit(void) +{ + platform_driver_unregister(&hdmi_dai_driver); +} +module_exit(hdmi_dai_exit); + +MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>"); +MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>"); +MODULE_DESCRIPTION("OMAP HDMI SoC Interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/omap/omap-hdmi.h b/sound/soc/omap/omap-hdmi.h new file mode 100644 index 000000000000..34c298d5057e --- /dev/null +++ b/sound/soc/omap/omap-hdmi.h @@ -0,0 +1,36 @@ +/* + * omap-hdmi.h + * + * Definitions for OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors. + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * Authors: Jorge Candelaria <jorge.candelaria@ti.com> + * Ricardo Neri <ricardo.neri@ti.com> + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __OMAP_HDMI_H__ +#define __OMAP_HDMI_H__ + +#define OMAP_HDMI_AUDIO_DMA_PORT 0x8c + +#define OMAP_HDMI_RATES (SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) + +#define OMAP_HDMI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +#endif diff --git a/sound/soc/omap/omap4-hdmi-card.c b/sound/soc/omap/omap4-hdmi-card.c new file mode 100644 index 000000000000..9f32615b81f7 --- /dev/null +++ b/sound/soc/omap/omap4-hdmi-card.c @@ -0,0 +1,129 @@ +/* + * omap4-hdmi-card.c + * + * OMAP ALSA SoC machine driver for TI OMAP4 HDMI + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * Author: Ricardo Neri <ricardo.neri@ti.com> + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <sound/pcm.h> +#include <sound/soc.h> +#include <asm/mach-types.h> +#include <video/omapdss.h> + +#define DRV_NAME "omap4-hdmi-audio" + +static int omap4_hdmi_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + int i; + struct omap_overlay_manager *mgr = NULL; + struct device *dev = substream->pcm->card->dev; + + /* Find DSS HDMI device */ + for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { + mgr = omap_dss_get_overlay_manager(i); + if (mgr && mgr->device + && mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) + break; + } + + if (i == omap_dss_get_num_overlay_managers()) { + dev_err(dev, "HDMI display device not found!\n"); + return -ENODEV; + } + + /* Make sure HDMI is power-on to avoid L3 interconnect errors */ + if (mgr->device->state != OMAP_DSS_DISPLAY_ACTIVE) { + dev_err(dev, "HDMI display is not active!\n"); + return -EIO; + } + + return 0; +} + +static struct snd_soc_ops omap4_hdmi_dai_ops = { + .hw_params = omap4_hdmi_dai_hw_params, +}; + +static struct snd_soc_dai_link omap4_hdmi_dai = { + .name = "HDMI", + .stream_name = "HDMI", + .cpu_dai_name = "hdmi-audio-dai", + .platform_name = "omap-pcm-audio", + .codec_name = "omapdss_hdmi", + .codec_dai_name = "hdmi-audio-codec", + .ops = &omap4_hdmi_dai_ops, +}; + +static struct snd_soc_card snd_soc_omap4_hdmi = { + .name = "OMAP4HDMI", + .dai_link = &omap4_hdmi_dai, + .num_links = 1, +}; + +static __devinit int omap4_hdmi_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &snd_soc_omap4_hdmi; + int ret; + + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + card->dev = NULL; + return ret; + } + return 0; +} + +static int __devexit omap4_hdmi_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + card->dev = NULL; + return 0; +} + +static struct platform_driver omap4_hdmi_driver = { + .driver = { + .name = "omap4-hdmi-audio", + .owner = THIS_MODULE, + }, + .probe = omap4_hdmi_probe, + .remove = __devexit_p(omap4_hdmi_remove), +}; + +static int __init omap4_hdmi_init(void) +{ + return platform_driver_register(&omap4_hdmi_driver); +} +module_init(omap4_hdmi_init); + +static void __exit omap4_hdmi_exit(void) +{ + platform_driver_unregister(&omap4_hdmi_driver); +} +module_exit(omap4_hdmi_exit); + +MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>"); +MODULE_DESCRIPTION("OMAP4 HDMI machine ASoC driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); |