[alsa-devel] [PATCH 2/5] [RFC]intel_hdmi_audio: interface module
ramesh.babu at intel.com
ramesh.babu at intel.com
Mon Nov 22 14:39:43 CET 2010
From: Ramesh Babu K V <ramesh.babu at intel.com>
This patch creates intel_mid_hdmi_audio_if.c file. This
interface module of the driver communicates with client driver
(HDMI display module) for receiving hot plug/unplug and other
events such as Buffer complete interrupt. ALSA sound card
will be created dynamically when hot plug event received and
removed when unplug event is received.
Signed-off-by: Ramesh Babu K V <ramesh.babu at intel.com>
Signed-off-by: Sailaja Bandarupalli <sailaja.bandarupalli at intel.com>
---
.../intel_mid_hdmi/intel_mid_hdmi_audio_if.c | 224 ++++++++++++++++++++
1 files changed, 224 insertions(+), 0 deletions(-)
create mode 100644 sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c
diff --git a/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c
new file mode 100644
index 0000000..aac9335
--- /dev/null
+++ b/sound/drivers/intel_mid_hdmi/intel_mid_hdmi_audio_if.c
@@ -0,0 +1,224 @@
+/*
+ * intel_mid_hdmi_audio_if.h - Intel HDMI audio driver for MID
+ *
+ * Copyright (C) 2010 Intel Corp
+ * Authors: Sailaja Bandarupalli <sailaja.bandarupalli at intel.com>
+ * Ramesh Babu K V <ramesh.babu at intel.com>
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * ALSA driver for Intel MID HDMI audio controller. This file contains
+ * interface functions exposed to HDMI Display driver and code to register
+ * with ALSA framework..
+ */
+
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/core.h>
+#include "intel_mid_hdmi_audio.h"
+#include "../../../drivers/staging/mrst/drv/psb_intel_hdmi.h"
+
+#define PCM_INDEX 0
+#define MAX_PB_STREAMS 1
+#define MAX_CAP_STREAMS 0
+
+/**
+ * snd_intelhad_dev_free - to free alsa card instance
+ *
+ * @device: pointer to device
+ *
+ * This function is called when the hdmi cable is un plugged
+ */
+static int snd_intelhad_dev_free(struct snd_device *device)
+{
+ struct snd_intelhad *intelhaddata;
+
+ BUG_ON(!device);
+ pr_debug("had: snd_intelhad_dev_free called\n");
+ intelhaddata = device->device_data;
+ return 0;
+}
+
+/**
+ * snd_intelhad_create - to crete alsa card instance
+ *
+ * @intelhaddata: pointer to internal context
+ * @card: pointer to card
+ *
+ * This function is called when the hdmi cable is plugged in
+ */
+static int __devinit snd_intelhad_create(
+ struct snd_intelhad *intelhaddata,
+ struct snd_card *card)
+{
+ int retval;
+ static struct snd_device_ops ops = {
+ .dev_free = snd_intelhad_dev_free,
+ };
+
+ BUG_ON(!intelhaddata);
+ BUG_ON(!card);
+ /* ALSA api to register the device */
+ retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, intelhaddata, &ops);
+ return retval;
+}
+/**
+ * snd_intelhad_pcm_free - to free the memory allocated
+ *
+ * @pcm: pointer to pcm instance
+ * This function is called when the device is removed
+ */
+static void snd_intelhad_pcm_free(struct snd_pcm *pcm)
+{
+ pr_debug("had:Freeing PCM preallocated pages\n");
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+/**
+ * had_hot_plug - to create sound card instance for HDMI audio playabck
+ *
+ *
+ * This function is called when the hdmi cable is plugged in. This function
+ * creates and registers the sound card with ALSA
+ */
+static int had_hot_plug(void)
+{
+ int retval;
+ struct snd_pcm *pcm;
+ struct snd_card *card;
+
+ pr_debug("had: Hot plug event received\n");
+ /* create a card instance with ALSA framework */
+ retval = snd_card_create(hdmi_card_index, hdmi_card_id,
+ THIS_MODULE, 0, &card);
+ if (retval) {
+ pr_err("had:Error while creating snd card\n");
+ return retval;
+ }
+
+ intelhaddata->card = card;
+ intelhaddata->card_id = hdmi_card_id;
+ intelhaddata->card_index = card->number;
+ intelhaddata->playback_cnt = 0;
+ strncpy(card->driver, INTEL_HAD, strlen(INTEL_HAD));
+ strncpy(card->shortname, INTEL_HAD, strlen(INTEL_HAD));
+
+ retval = snd_pcm_new(card, INTEL_HAD, PCM_INDEX, MAX_PB_STREAMS,
+ MAX_CAP_STREAMS, &pcm);
+ if (retval) {
+ pr_err("had:_pcm_new failed\n");
+ goto err;
+ }
+ /* setup private data which can be retrieved when required */
+ pcm->private_data = intelhaddata;
+ pcm->private_free = snd_intelhad_pcm_free;
+ pcm->info_flags = 0;
+ strncpy(pcm->name, card->shortname, strlen(card->shortname));
+ /* setup the ops for palyabck */
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_intelhad_playback_ops);
+ /* allocate dma pages for ALSA stream operations */
+ retval = snd_pcm_lib_preallocate_pages_for_all(pcm,
+ SNDRV_DMA_TYPE_CONTINUOUS,
+ snd_dma_continuous_data(GFP_KERNEL),
+ HAD_MIN_BUFFER, HAD_MAX_BUFFER);
+ if (retval) {
+ pr_err("had:preallocation failed\n");
+ goto err;
+ }
+ /* internal function call to register device with ALSA */
+ retval = snd_intelhad_create(intelhaddata, card);
+ if (retval)
+ goto err;
+ card->private_data = &intelhaddata;
+ retval = snd_card_register(card);
+ if (retval) {
+ pr_err("had: snd_card_register failed\n");
+ goto err;
+ }
+ intelhaddata->query_ops->hdmi_audio_get_caps(
+ HAD_GET_ELD, &intelhaddata->eeld);
+ retval = intelhaddata->reg_ops->hdmi_audio_write_register(
+ AUD_HDMI_STATUS, SET_BIT0);
+ return retval;
+err:
+ pr_err("had: Error returned from snd api\n");
+ snd_card_free(card);
+ return retval;
+}
+
+/**
+ * had_event_handler - Call back function to handle events
+ *
+ * @event_type: Event type to handle
+ * @data: data related to the event_type
+ *
+ * This function is invoked to handle HDMI events from client driver.
+ */
+int had_event_handler(enum had_event_type event_type, void *data)
+{
+ int retval = 0;
+ enum intel_had_aud_buf_type buf_id;
+ struct pcm_stream_info *stream;
+ u32 buf_size;
+
+ pr_debug("had:called _event_handler with event#%d\n", event_type);
+ switch (event_type) {
+ case HAD_EVENT_HOT_PLUG:
+ retval = had_hot_plug();
+ break;
+ case HAD_EVENT_HOT_UNPLUG:
+ retval = snd_card_free(intelhaddata->card);
+ break;
+ case HAD_EVENT_PM_CHANGING:
+ /*Run-time PM is not yet supported*/
+ retval = -EIO;
+ break;
+ case HAD_EVENT_AUDIO_BUFFER_DONE:
+ stream = &intelhaddata->stream_info;
+
+
+ buf_id = intelhaddata->curr_buf;
+ pr_debug("had:called _event_handler with BUFFER DONE event for\
+ Buf#%d\n", buf_id);
+ buf_size = intelhaddata->buf_info[buf_id].buf_size;
+ intelhaddata->stream_info.buffer_rendered += buf_size;
+ intelhaddata->buf_info[buf_id].is_valid = true;
+ stream->period_elapsed(stream->had_substream);
+ if (intelhaddata->valid_buf_cnt-1 == buf_id)
+ intelhaddata->curr_buf = HAD_BUF_TYPE_A;
+ else
+ intelhaddata->curr_buf++;
+ /*Reprogram the registers with addr and length*/
+ retval = intelhaddata->reg_ops->hdmi_audio_write_register(
+ AUD_BUF_A_LENGTH + (buf_id * REG_WIDTH),
+ buf_size);
+ retval = intelhaddata->reg_ops->hdmi_audio_write_register(
+ AUD_BUF_A_ADDR+(buf_id * REG_WIDTH),
+ intelhaddata->buf_info[buf_id].buf_addr|
+ REG_BIT_0 | REG_BIT_1);
+ break;
+ case HAD_EVENT_AUDIO_BUFFER_UNDERRUN:
+ /*To be handle error handling*/
+ retval = -EIO;
+ break;
+ default:
+ pr_debug("had:error un-handled event !!\n");
+ retval = -EINVAL;
+ break;
+ }
+ return retval;
+}
--
1.6.2.5
More information about the Alsa-devel
mailing list