Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2 * omap-hdmi.c
  3 *
  4 * OMAP ALSA SoC DAI driver for HDMI audio on OMAP4 processors.
  5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
  6 * Authors: Jorge Candelaria <jorge.candelaria@ti.com>
  7 *          Ricardo Neri <ricardo.neri@ti.com>
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License
 11 * version 2 as published by the Free Software Foundation.
 12 *
 13 * This program is distributed in the hope that it will be useful, but
 14 * WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 21 * 02110-1301 USA
 22 *
 23 */
 24
 25#include <linux/init.h>
 26#include <linux/module.h>
 27#include <linux/device.h>
 28#include <sound/core.h>
 29#include <sound/pcm.h>
 30#include <sound/pcm_params.h>
 31#include <sound/initval.h>
 32#include <sound/soc.h>
 33
 34#include <plat/dma.h>
 35#include "omap-pcm.h"
 36#include "omap-hdmi.h"
 37
 38#define DRV_NAME "hdmi-audio-dai"
 39
 40static struct omap_pcm_dma_data omap_hdmi_dai_dma_params = {
 41	.name = "HDMI playback",
 42	.sync_mode = OMAP_DMA_SYNC_PACKET,
 43};
 44
 45static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
 46				  struct snd_soc_dai *dai)
 47{
 48	int err;
 49	/*
 50	 * Make sure that the period bytes are multiple of the DMA packet size.
 51	 * Largest packet size we use is 32 32-bit words = 128 bytes
 52	 */
 53	err = snd_pcm_hw_constraint_step(substream->runtime, 0,
 54				 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
 55	if (err < 0)
 56		return err;
 57
 58	return 0;
 59}
 60
 61static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
 62				    struct snd_pcm_hw_params *params,
 63				    struct snd_soc_dai *dai)
 64{
 65	int err = 0;
 66
 67	switch (params_format(params)) {
 68	case SNDRV_PCM_FORMAT_S16_LE:
 69		omap_hdmi_dai_dma_params.packet_size = 16;
 70		break;
 71	case SNDRV_PCM_FORMAT_S24_LE:
 72		omap_hdmi_dai_dma_params.packet_size = 32;
 73		break;
 74	default:
 75		err = -EINVAL;
 76	}
 77
 78	omap_hdmi_dai_dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
 79
 80	snd_soc_dai_set_dma_data(dai, substream,
 81				 &omap_hdmi_dai_dma_params);
 82
 83	return err;
 84}
 85
 86static struct snd_soc_dai_ops omap_hdmi_dai_ops = {
 87	.startup	= omap_hdmi_dai_startup,
 88	.hw_params	= omap_hdmi_dai_hw_params,
 89};
 90
 91static struct snd_soc_dai_driver omap_hdmi_dai = {
 92	.playback = {
 93		.channels_min = 2,
 94		.channels_max = 2,
 95		.rates = OMAP_HDMI_RATES,
 96		.formats = OMAP_HDMI_FORMATS,
 97	},
 98	.ops = &omap_hdmi_dai_ops,
 99};
100
101static __devinit int omap_hdmi_probe(struct platform_device *pdev)
102{
103	int ret;
104	struct resource *hdmi_rsrc;
105
106	hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
107	if (!hdmi_rsrc) {
108		dev_err(&pdev->dev, "Cannot obtain IORESOURCE_MEM HDMI\n");
109		return -EINVAL;
110	}
111
112	omap_hdmi_dai_dma_params.port_addr =  hdmi_rsrc->start
113		+ OMAP_HDMI_AUDIO_DMA_PORT;
114
115	hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
116	if (!hdmi_rsrc) {
117		dev_err(&pdev->dev, "Cannot obtain IORESOURCE_DMA HDMI\n");
118		return -EINVAL;
119	}
120
121	omap_hdmi_dai_dma_params.dma_req =  hdmi_rsrc->start;
122
123	ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai);
124	return ret;
125}
126
127static int __devexit omap_hdmi_remove(struct platform_device *pdev)
128{
129	snd_soc_unregister_dai(&pdev->dev);
130	return 0;
131}
132
133static struct platform_driver hdmi_dai_driver = {
134	.driver = {
135		.name = DRV_NAME,
136		.owner = THIS_MODULE,
137	},
138	.probe = omap_hdmi_probe,
139	.remove = __devexit_p(omap_hdmi_remove),
140};
141
142static int __init hdmi_dai_init(void)
143{
144	return platform_driver_register(&hdmi_dai_driver);
145}
146module_init(hdmi_dai_init);
147
148static void __exit hdmi_dai_exit(void)
149{
150	platform_driver_unregister(&hdmi_dai_driver);
151}
152module_exit(hdmi_dai_exit);
153
154MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>");
155MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
156MODULE_DESCRIPTION("OMAP HDMI SoC Interface");
157MODULE_LICENSE("GPL");
158MODULE_ALIAS("platform:" DRV_NAME);