public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Alsa modularisations and support for tsc2101 1/7
@ 2006-02-20 17:44 Daniel Petrini
  2006-02-20 22:11 ` Komal Shah
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Petrini @ 2006-02-20 17:44 UTC (permalink / raw)
  To: OMAP-Linux

[-- Attachment #1: Type: text/plain, Size: 1285 bytes --]

ALSA Omap Modularisation

This series of patches adds modularisation in alsa files for omap so that
makes possible to use the same alsa omap core files for different boards.
Regarding the original omap alsa support, the codec specific functions
were removed from file omap-aic23.c (which now is called omap-alsa.c)
and inserted in a specific file for this codec. Similar action was made
for tsc2101 codec, based in oss former drivers.
With this series of patches omap now have support for osk and H2 boards.
Besides codec files, the mixer file has its support added for H2.

Summary:

-New architecture: extraction of codec dependent code from main alsa file
-Support for board H2
-Creation of codec alsa file for codec aic23 (from existing alsa work)
-Creation of codec alsa file for codec tsc2101 from oss
-Migration of specific codec configuration to platform_data
-Improvement of function probe in omap-alsa driver
-Creation of the mixer for tsc2101

This first patch creates the new files omap-alsa.[c,h] based in the
former omap-aic23.[c,h] and put the .h file in include/asm/arch/.

signed-off by Daniel Petrini <d.pensator@gmail.com>
signed-off by Mika Laitio <lamikr@cc.jyu.fi>

------------------------
Daniel Petrini
--
INdT - Manaus - Brazil

[-- Attachment #2: alsa1-20060214.patch --]
[-- Type: text/x-patch, Size: 56503 bytes --]

ALSA Omap Modularisation

This series of patches adds modularisation in alsa files for omap so that
makes possible to use the same alsa omap core files for different boards.
Regarding the original omap alsa support, the codec specific functions
were removed from file omap-aic23.c (which now is called omap-alsa.c)
and inserted in a specific file for this codec. Similar action was made
for tsc2101 codec, based in oss former drivers.
With this series of patches omap now have support for osk and H2 boards.
Besides codec files, the mixer file has its support added for H2.

Summary:

-New architecture: extraction of codec dependent code from main alsa file
-Support for board H2
-Creation of codec alsa file for codec aic23 (from existing alsa work)
-Creation of codec alsa file for codec tsc2101 from oss
-Migration of specific codec configuration to platform_data
-Improvement of function probe in omap-alsa driver
-Creation of the mixer for tsc2101

This first patch creates the new files omap-alsa.[c,h] based in the
former omap-aic23.[c,h] and put the .h file in include/asm/arch/.

signed-off by Daniel Petrini <d.pensator@gmail.com>
signed-off by Mika Laitio <lamikr@cc.jyu.fi>

Index: linux-omap-2.6.git-q/sound/arm/Makefile
===================================================================
--- linux-omap-2.6.git-q.orig/sound/arm/Makefile	2006-02-14 08:25:48.000000000 -0400
+++ linux-omap-2.6.git-q/sound/arm/Makefile	2006-02-14 09:35:12.000000000 -0400
@@ -14,5 +14,9 @@ snd-pxa2xx-pcm-objs		:= pxa2xx-pcm.o
 obj-$(CONFIG_SND_PXA2XX_AC97)	+= snd-pxa2xx-ac97.o
 snd-pxa2xx-ac97-objs		:= pxa2xx-ac97.o
 
-obj-$(CONFIG_SND_OMAP_AIC23) += snd-omap-aic23.o
-snd-omap-aic23-objs := omap-aic23.o omap-alsa-dma.o omap-alsa-mixer.o
+obj-$(CONFIG_SND_OMAP_AIC23) += snd-omap-alsa-aic23.o
+snd-omap-alsa-aic23-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-mixer.o 
+
+obj-$(CONFIG_SND_OMAP_TSC2101) += snd-omap-alsa-tsc2101.o
+snd-omap-alsa-tsc2101-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-tsc2101-mixer.o 
+
Index: linux-omap-2.6.git-q/sound/arm/omap-alsa.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6.git-q/sound/arm/omap-alsa.c	2006-02-14 09:49:14.000000000 -0400
@@ -0,0 +1,714 @@
+/*
+ * sound/arm/omap-alsa.c
+ * 
+ * Alsa Driver for AIC23 codec on OSK5912 platform board
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Written by Daniel Petrini, David Cohen, Anderson Briglia
+ *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
+ *
+ * Based on sa11xx-uda1341.c, 
+ * Copyright (C) 2002 Tomas Kasparek <tomas.kasparek@seznam.cz>
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * History:
+ *
+ * 2005-07-29   INdT Kernel Team - Alsa driver for omap osk. Creation of new 
+ *                                 file omap-aic23.c
+ * 
+ * 2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix as proposed by Ajaya Babu
+ *
+ * 2006-02-07   Daniel Petrini  - Codec specific function separated. File renamed to
+ *                                omap-alsa.c
+ * 2006-02-10	Mika Laitio	- Codec specific function pointers are set in the codec.
+ * 				  Default samplerate queried from the codec.
+ */
+
+#include <linux/platform_device.h>
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+#include <sound/driver.h>
+#include <sound/core.h>
+
+#include <asm/arch/omap-alsa.h>
+#include "omap-alsa-dma.h"
+
+MODULE_AUTHOR("Mika Laitio, Daniel Petrini, David Cohen, Anderson Briglia - INdT");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("OMAP driver for ALSA");
+MODULE_ALIAS("omap_alsa_mcbsp.1");
+
+static char *id	= NULL;	
+static struct snd_card_omap_codec 	*alsa_codec		= NULL;
+static struct omap_alsa_codec_config	*alsa_codec_config	= NULL;
+
+/*
+ * DAC USB-mode sampling rates (MCLK = 12 MHz)
+ * The rates and rate_reg_into MUST be in the same order
+ */
+static unsigned int rates[] = {
+	4000, 8000, 16000, 22050,
+	24000, 32000, 44100,
+	48000, 88200, 96000,
+};
+
+static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+	.count = ARRAY_SIZE(rates),
+	.list = rates,
+	.mask = 0,
+};
+
+/*
+ * HW interface start and stop helper functions
+ */
+static int audio_ifc_start(void)
+{
+	omap_mcbsp_start(AUDIO_MCBSP);
+	return 0;
+}
+
+static int audio_ifc_stop(void)
+{
+	omap_mcbsp_stop(AUDIO_MCBSP);
+	return 0;
+}
+
+static void omap_alsa_audio_init(struct snd_card_omap_codec *omap_alsa)
+{
+	/* Setup DMA stuff */
+	omap_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].id = "Alsa omap out";
+	omap_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id =
+	    SNDRV_PCM_STREAM_PLAYBACK;
+	omap_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev =
+	    OMAP_DMA_MCBSP1_TX;
+	omap_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].hw_start =
+	    audio_ifc_start;
+	omap_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].hw_stop =
+	    audio_ifc_stop;
+
+	omap_alsa->s[SNDRV_PCM_STREAM_CAPTURE].id = "Alsa omap in";
+	omap_alsa->s[SNDRV_PCM_STREAM_CAPTURE].stream_id =
+	    SNDRV_PCM_STREAM_CAPTURE;
+	omap_alsa->s[SNDRV_PCM_STREAM_CAPTURE].dma_dev =
+	    OMAP_DMA_MCBSP1_RX;
+	omap_alsa->s[SNDRV_PCM_STREAM_CAPTURE].hw_start =
+	    audio_ifc_start;
+	omap_alsa->s[SNDRV_PCM_STREAM_CAPTURE].hw_stop =
+	    audio_ifc_stop;
+}
+
+/* 
+ * DMA functions 
+ * Depends on omap-alsa-dma.c functions and (omap) dma.c
+ * 
+ */
+#define DMA_BUF_SIZE	1024 * 8
+
+static int audio_dma_request(struct audio_stream *s,
+			     void (*callback) (void *))
+{
+	int err;
+	ADEBUG();
+
+	err = omap_request_sound_dma(s->dma_dev, s->id, s, &s->lch);
+	if (err < 0)
+		printk(KERN_ERR "unable to grab audio dma 0x%x\n",
+		       s->dma_dev);
+	return err;
+}
+
+static int audio_dma_free(struct audio_stream *s)
+{
+	int err = 0;
+	ADEBUG();
+
+	err = omap_free_sound_dma(s, &s->lch);
+	if (err < 0)
+		printk(KERN_ERR "Unable to free audio dma channels!\n");
+	return err;
+}
+
+/*
+ *  This function should calculate the current position of the dma in the
+ *  buffer. It will help alsa middle layer to continue update the buffer.
+ *  Its correctness is crucial for good functioning.
+ */
+static u_int audio_get_dma_pos(struct audio_stream *s)
+{
+	snd_pcm_substream_t *substream = s->stream;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	unsigned int offset;
+	unsigned long flags;
+	dma_addr_t count;
+	ADEBUG();
+
+	/* this must be called w/ interrupts locked as requested in dma.c */
+	spin_lock_irqsave(&s->dma_lock, flags);
+
+	/* For the current period let's see where we are */
+	count = omap_get_dma_src_addr_counter(s->lch[s->dma_q_head]);
+
+	spin_unlock_irqrestore(&s->dma_lock, flags);
+
+	/* Now, the position related to the end of that period */
+	offset = bytes_to_frames(runtime, s->offset) - bytes_to_frames(runtime, count);
+
+	if (offset >= runtime->buffer_size || offset < 0)
+		offset = 0;
+
+	return offset;
+}
+
+/*
+ * this stops the dma and clears the dma ptrs
+ */
+static void audio_stop_dma(struct audio_stream *s)
+{
+	unsigned long flags;
+	ADEBUG();
+
+	spin_lock_irqsave(&s->dma_lock, flags);
+	s->active = 0;
+	s->period = 0;
+	s->periods = 0;
+
+	/* this stops the dma channel and clears the buffer ptrs */
+	omap_audio_stop_dma(s);
+
+	omap_clear_sound_dma(s);
+
+	spin_unlock_irqrestore(&s->dma_lock, flags);
+}
+
+/*
+ *  Main dma routine, requests dma according where you are in main alsa buffer
+ */
+static void audio_process_dma(struct audio_stream *s)
+{
+	snd_pcm_substream_t *substream = s->stream;
+	snd_pcm_runtime_t *runtime;
+	unsigned int dma_size;
+	unsigned int offset;
+	int ret;
+#ifdef CONFIG_MACH_OMAP_H6300
+	unsigned long flags;
+#endif
+	
+	ADEBUG();
+	runtime = substream->runtime;
+	if (s->active) {
+		dma_size = frames_to_bytes(runtime, runtime->period_size);
+		offset = dma_size * s->period;
+		snd_assert(dma_size <= DMA_BUF_SIZE,);
+#ifdef CONFIG_MACH_OMAP_H6300
+		spin_lock_irqsave(&s->dma_lock, flags);
+		omap_audio_stop_dma(s);
+		spin_unlock_irqrestore(&s->dma_lock, flags);
+#endif
+		ret = omap_start_sound_dma(s,
+					 (dma_addr_t) runtime->dma_area +
+					 offset, dma_size);
+		if (ret) {
+			printk(KERN_ERR
+			       "audio_process_dma: cannot queue DMA buffer (%i)\n",
+			       ret);
+			return;
+		}
+
+		s->period++;
+		s->period %= runtime->periods;
+		s->periods++;
+		s->offset = offset;
+	}
+}
+
+/* 
+ *  This is called when dma IRQ occurs at the end of each transmited block
+ */
+void audio_dma_callback(void *data)
+{
+	struct audio_stream *s = data;
+	ADEBUG();
+
+	/* 
+	 * If we are getting a callback for an active stream then we inform
+	 * the PCM middle layer we've finished a period
+	 */
+	if (s->active)
+		snd_pcm_period_elapsed(s->stream);
+
+	spin_lock(&s->dma_lock);
+	if (s->periods > 0) {
+		s->periods--;
+	}
+	audio_process_dma(s);
+	spin_unlock(&s->dma_lock);
+}
+
+/* 
+ * Alsa section
+ * PCM settings and callbacks
+ */
+
+static int snd_omap_alsa_trigger(snd_pcm_substream_t * substream, int cmd)
+{
+	struct snd_card_omap_codec *chip =
+	    snd_pcm_substream_chip(substream);
+	int stream_id = substream->pstr->stream;
+	struct audio_stream *s = &chip->s[stream_id];
+	int err = 0;
+	ADEBUG();
+
+	/* note local interrupts are already disabled in the midlevel code */
+	spin_lock(&s->dma_lock);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		/* requested stream startup */
+		s->active = 1;
+		audio_process_dma(s);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		/* requested stream shutdown */
+		audio_stop_dma(s);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+	spin_unlock(&s->dma_lock);
+	
+	return err;
+}
+
+static int snd_omap_alsa_prepare(snd_pcm_substream_t * substream)
+{
+	struct snd_card_omap_codec *chip = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct audio_stream *s = &chip->s[substream->pstr->stream];
+	ADEBUG();
+
+	/* set requested samplerate */
+	alsa_codec_config->codec_set_samplerate(runtime->rate);
+	chip->samplerate = runtime->rate;
+
+	s->period = 0;
+	s->periods = 0;
+
+	return 0;
+}
+
+static snd_pcm_uframes_t snd_omap_alsa_pointer(snd_pcm_substream_t *substream)
+{
+	struct snd_card_omap_codec *chip = snd_pcm_substream_chip(substream);
+
+	ADEBUG();	
+	return audio_get_dma_pos(&chip->s[substream->pstr->stream]);
+}
+
+/* Hardware capabilities */
+
+static snd_pcm_hardware_t snd_omap_alsa_capture = {
+	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+	.formats = (SNDRV_PCM_FMTBIT_S16_LE),
+	.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
+		  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
+		  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
+		  SNDRV_PCM_RATE_KNOT),
+	.rate_min = 8000,
+	.rate_max = 96000,
+	.channels_min = 2,
+	.channels_max = 2,
+	.buffer_bytes_max = 128 * 1024,
+	.period_bytes_min = 32,
+	.period_bytes_max = 8 * 1024,
+	.periods_min = 16,
+	.periods_max = 255,
+	.fifo_size = 0,
+};
+
+static snd_pcm_hardware_t snd_omap_alsa_playback = {
+	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),	
+	.formats = (SNDRV_PCM_FMTBIT_S16_LE),
+	.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
+		  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
+		  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
+		  SNDRV_PCM_RATE_KNOT),
+	.rate_min = 8000,
+	.rate_max = 96000,
+	.channels_min = 2,
+	.channels_max = 2,
+	.buffer_bytes_max = 128 * 1024,
+	.period_bytes_min = 32,
+	.period_bytes_max = 8 * 1024,
+	.periods_min = 16,
+	.periods_max = 255,
+	.fifo_size = 0,
+};
+
+static int snd_card_omap_alsa_open(snd_pcm_substream_t * substream)
+{
+	struct snd_card_omap_codec *chip =
+	    snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int stream_id = substream->pstr->stream;
+	int err;
+	
+	ADEBUG();
+	chip->s[stream_id].stream = substream;
+	alsa_codec_config->codec_clock_on();
+	if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
+		runtime->hw = snd_omap_alsa_playback;
+	}
+	else {
+		runtime->hw = snd_omap_alsa_capture;
+	}
+	if ((err = snd_pcm_hw_constraint_integer(runtime,
+					   SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
+		return err;
+	}
+	if ((err = snd_pcm_hw_constraint_list(runtime, 0,
+					SNDRV_PCM_HW_PARAM_RATE,
+					&hw_constraints_rates)) < 0) {
+		return err;
+	}
+	return 0;
+}
+
+static int snd_card_omap_alsa_close(snd_pcm_substream_t * substream)
+{
+	struct snd_card_omap_codec *chip =
+	    snd_pcm_substream_chip(substream);
+	ADEBUG();
+	
+	alsa_codec_config->codec_clock_off();
+	chip->s[substream->pstr->stream].stream = NULL;
+	
+	return 0;
+}
+
+/* HW params & free */
+
+static int snd_omap_alsa_hw_params(snd_pcm_substream_t * substream,
+				    snd_pcm_hw_params_t * hw_params)
+{
+	return snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+}
+
+static int snd_omap_alsa_hw_free(snd_pcm_substream_t * substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* pcm operations */
+
+static snd_pcm_ops_t snd_card_omap_alsa_playback_ops = {
+	.open =		snd_card_omap_alsa_open,
+	.close =	snd_card_omap_alsa_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_omap_alsa_hw_params,
+	.hw_free =	snd_omap_alsa_hw_free,
+	.prepare =	snd_omap_alsa_prepare,
+	.trigger =	snd_omap_alsa_trigger,
+	.pointer =	snd_omap_alsa_pointer,
+};
+
+static snd_pcm_ops_t snd_card_omap_alsa_capture_ops = {
+	.open =		snd_card_omap_alsa_open,
+	.close =	snd_card_omap_alsa_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_omap_alsa_hw_params,
+	.hw_free =	snd_omap_alsa_hw_free,
+	.prepare =	snd_omap_alsa_prepare,
+	.trigger =	snd_omap_alsa_trigger,
+	.pointer =	snd_omap_alsa_pointer,
+};
+
+/*
+ *  Alsa init and exit section
+ *  
+ *  Inits pcm alsa structures, allocate the alsa buffer, suspend, resume
+ */
+static int __init snd_card_omap_alsa_pcm(struct snd_card_omap_codec
+					  *omap_alsa, int device)
+{
+	snd_pcm_t *pcm;
+	int err;
+	ADEBUG();
+
+	if ((err =
+	     snd_pcm_new(omap_alsa->card, "AIC23 PCM", device, 1, 1, &pcm)) < 0)
+		return err;
+
+	/* sets up initial buffer with continuous allocation */
+	snd_pcm_lib_preallocate_pages_for_all(pcm,
+					      SNDRV_DMA_TYPE_CONTINUOUS,
+					      snd_dma_continuous_data
+					      (GFP_KERNEL),
+					      128 * 1024, 128 * 1024);
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+			&snd_card_omap_alsa_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+			&snd_card_omap_alsa_capture_ops);
+	pcm->private_data = omap_alsa;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, "omap aic23 pcm");
+
+	omap_alsa_audio_init(omap_alsa);
+
+	/* setup DMA controller */
+	audio_dma_request(&omap_alsa->s[SNDRV_PCM_STREAM_PLAYBACK],
+			  audio_dma_callback);
+	audio_dma_request(&omap_alsa->s[SNDRV_PCM_STREAM_CAPTURE],
+			  audio_dma_callback);
+
+	omap_alsa->pcm = pcm;
+
+	return 0;
+}
+
+
+#ifdef CONFIG_PM
+
+static int snd_omap_alsa_suspend(snd_card_t * card, pm_message_t state)
+{
+	struct snd_card_omap_codec *chip = card->private_data;
+	ADEBUG();
+
+	if (chip->card->power_state != SNDRV_CTL_POWER_D3hot) {
+		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
+		snd_pcm_suspend_all(chip->pcm);
+		/* Mutes and turn clock off */
+		alsa_codec_config->codec_clock_off();
+		snd_omap_suspend_mixer();
+	}
+	return 0;
+}
+
+/*
+ *  Prepare hardware for resume
+ */
+static int snd_omap_alsa_resume(snd_card_t * card)
+{
+	struct snd_card_omap_codec *chip = card->private_data;
+	ADEBUG();
+	
+	if (chip->card->power_state != SNDRV_CTL_POWER_D0) {
+		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
+		alsa_codec_config->codec_clock_on();
+		snd_omap_resume_mixer();
+	}
+	return 0;
+}
+
+/*
+ * Driver suspend/resume - calls alsa functions. Some hints from aaci.c
+ */
+static int omap_alsa_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	snd_card_t *card = platform_get_drvdata(pdev);
+	
+	if (card->power_state != SNDRV_CTL_POWER_D3hot) {
+		snd_omap_alsa_suspend(card, PMSG_SUSPEND);
+	}
+	return 0;
+}
+
+static int omap_alsa_resume(struct platform_device *pdev)
+{
+	snd_card_t *card = platform_get_drvdata(pdev);
+
+	if (card->power_state != SNDRV_CTL_POWER_D0) {
+		snd_omap_alsa_resume(card);
+	}
+	return 0;
+}
+
+#else
+#define snd_omap_alsa_suspend	NULL
+#define snd_omap_alsa_resume	NULL
+#define omap_alsa_suspend	NULL
+#define omap_alsa_resume	NULL
+
+#endif	/* CONFIG_PM */
+
+/* 
+ */
+void snd_omap_alsa_free(snd_card_t * card)
+{
+	struct snd_card_omap_codec *chip = card->private_data;
+	ADEBUG();
+	
+	/*
+	 * Turn off codec after it is done.
+	 * Can't do it immediately, since it may still have
+	 * buffered data.
+	 */
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(2);
+
+	omap_mcbsp_stop(AUDIO_MCBSP);
+	omap_mcbsp_free(AUDIO_MCBSP);
+
+	audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]);
+	audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
+}
+
+/* module init & exit */
+
+/* 
+ *  Inits alsa soudcard structure
+ */
+static int __init snd_omap_alsa_probe(struct platform_device *pdev)
+{
+	int err = 0;
+	int def_rate;
+	snd_card_t *card;
+	
+	ADEBUG();
+	alsa_codec_config = pdev->dev.platform_data;
+	if (alsa_codec_config == NULL) {
+		err = -ENODEV;
+		goto nodev1;
+	}
+	
+	alsa_codec_config->codec_clock_setup();
+	alsa_codec_config->codec_clock_on(); 
+
+	omap_mcbsp_request(AUDIO_MCBSP);
+	omap_mcbsp_stop(AUDIO_MCBSP);
+	omap_mcbsp_config(AUDIO_MCBSP, alsa_codec_config->mcbsp_regs_alsa);
+	omap_mcbsp_start(AUDIO_MCBSP);
+	
+	if (alsa_codec_config && alsa_codec_config->codec_configure_dev) {
+		alsa_codec_config->codec_configure_dev();
+	}
+
+	alsa_codec_config->codec_clock_off();
+
+	/* register the soundcard */
+	card = snd_card_new(-1, id, THIS_MODULE, sizeof(alsa_codec));
+	if (card == NULL) {
+		goto nodev2;
+	}
+
+	alsa_codec = kcalloc(1, sizeof(*alsa_codec), GFP_KERNEL);
+	if (alsa_codec == NULL) {
+		goto nodev3;
+	}
+
+	card->private_data = (void *)alsa_codec;
+	card->private_free = snd_omap_alsa_free;
+
+	alsa_codec->card	= card;
+	def_rate		= alsa_codec_config->get_default_samplerate(); 
+	alsa_codec->samplerate	= def_rate;
+
+	spin_lock_init(&alsa_codec->s[0].dma_lock);
+	spin_lock_init(&alsa_codec->s[1].dma_lock);
+
+	/* mixer */
+	if ((err = snd_omap_mixer(alsa_codec)) < 0) {
+		goto nodev4;
+	}
+
+	/* PCM */
+	if ((err = snd_card_omap_alsa_pcm(alsa_codec, 0)) < 0) {
+		goto nodev4;
+	}
+
+	strcpy(card->driver, "OMAP_ALSA");
+	strcpy(card->shortname, alsa_codec_config->name);
+	sprintf(card->longname, alsa_codec_config->name);
+
+	snd_omap_init_mixer();
+	snd_card_set_dev(card, &pdev->dev);
+	
+	if ((err = snd_card_register(card)) == 0) {
+		printk(KERN_INFO "audio support initialized\n");
+		platform_set_drvdata(pdev, card);
+		return 0;
+	}
+	
+nodev4:
+	kfree(alsa_codec);	
+nodev3:	
+	snd_card_free(card);
+nodev2:
+	omap_mcbsp_stop(AUDIO_MCBSP);
+	omap_mcbsp_free(AUDIO_MCBSP);
+nodev1:	
+	return err;
+}
+
+static int snd_omap_alsa_remove(struct platform_device *pdev)
+{
+	snd_card_t *card = platform_get_drvdata(pdev);
+	struct snd_card_omap_codec *chip = card->private_data;
+	
+	snd_card_free(card);
+
+	alsa_codec = NULL;
+	card->private_data = NULL;
+	kfree(chip);
+	
+	platform_set_drvdata(pdev, NULL);
+	
+	return 0;
+	
+}
+
+static struct platform_driver omap_alsa_driver = {
+	.probe =	snd_omap_alsa_probe,
+	.remove =	snd_omap_alsa_remove,
+	.suspend =	omap_alsa_suspend, 
+	.resume =	omap_alsa_resume, 
+	.driver = {
+		.name =	"omap_alsa_mcbsp",
+	},
+};
+
+static int __init omap_alsa_init(void)
+{
+	int err;
+	ADEBUG();
+
+	err = platform_driver_register(&omap_alsa_driver);
+
+	return err;
+}
+
+static void __exit omap_alsa_exit(void)
+{
+	ADEBUG();
+	
+	platform_driver_unregister(&omap_alsa_driver);
+}
+
+module_init(omap_alsa_init);
+module_exit(omap_alsa_exit);
Index: linux-omap-2.6.git-q/include/asm-arm/arch-omap/omap-alsa.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6.git-q/include/asm-arm/arch-omap/omap-alsa.h	2006-02-14 09:48:25.000000000 -0400
@@ -0,0 +1,150 @@
+/*
+ * linux/include/asm-arm/arch-omap/omap-alsa.h
+ * 
+ * Alsa Driver for AIC23 codec on OSK5912 platform board
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Written by Daniel Petrini, David Cohen, Anderson Briglia
+ *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  History
+ *  -------
+ *
+ *  2005/07/25 INdT-10LE Kernel Team - 	Alsa driver for omap osk,
+ *  					original version based in sa1100 driver
+ *  					and omap oss driver.
+ *
+ *  2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix as proposed by Ajaya Babu
+ *  2006-02-10   Mika Laitio	 - Moved from sound/arm to linux/include/asm-arm/arch-omap.
+ * 				   Added omap alsa codec config datatype to handle aic23 and tsc2101 
+ * 				   codecs from the same omap-alsa.c base driver.
+ */
+
+#ifndef __OMAP_ALSA_H
+#define __OMAP_ALSA_H
+
+#include <sound/driver.h>
+#include <asm/arch/dma.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <asm/arch/mcbsp.h>
+
+/*
+ * Debug functions
+ */
+#undef DEBUG
+//#define DEBUG
+
+#define ERR(ARGS...) printk(KERN_ERR "{%s}-ERROR: ", __FUNCTION__);printk(ARGS);
+
+#ifdef DEBUG
+#define DPRINTK(ARGS...)  printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
+#define ADEBUG() printk("XXX Alsa debug f:%s, l:%d\n", __FUNCTION__, __LINE__)
+#define FN_IN printk(KERN_INFO "[%s]: start\n", __FUNCTION__)
+#define FN_OUT(n) printk(KERN_INFO "[%s]: end(%u)\n",__FUNCTION__, n)
+#else
+#define DPRINTK(ARGS...)	/* nop */
+#define ADEBUG()		/* nop */
+#define FN_IN			/* nop */
+#define FN_OUT(n)		/* nop */
+#endif
+
+/*
+ * Buffer management for alsa and dma
+ */
+struct audio_stream {
+	char *id;		/* identification string */
+	int stream_id;		/* numeric identification */
+	int dma_dev;		/* dma number of that device */
+	int *lch;		/* Chain of channels this stream is linked to */
+	char started;		/* to store if the chain was started or not */
+	int dma_q_head;		/* DMA Channel Q Head */
+	int dma_q_tail;		/* DMA Channel Q Tail */
+	char dma_q_count;	/* DMA Channel Q Count */
+	int active:1;		/* we are using this stream for transfer now */
+	int period;		/* current transfer period */
+	int periods;		/* current count of periods registerd in the DMA engine */
+	spinlock_t dma_lock;	/* for locking in DMA operations */
+	snd_pcm_substream_t *stream;	/* the pcm stream */
+	unsigned linked:1;	/* dma channels linked */
+	int offset;		/* store start position of the last period in the alsa buffer */
+	int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
+	int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
+};
+
+/*
+ * Alsa card structure for aic23
+ */
+struct snd_card_omap_codec {
+	snd_card_t *card;
+	snd_pcm_t *pcm;
+	long samplerate;
+	struct audio_stream s[2];	/* playback & capture */
+};
+
+/* Codec specific information and function pointers. 
+ * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
+ * are responsible for defining the function pointers.
+ */
+struct omap_alsa_codec_config {
+	char 	*name;
+	struct	omap_mcbsp_reg_cfg * mcbsp_regs_alsa;
+	void	(*codec_configure_dev)(void);
+	void	(*codec_set_samplerate)(long);
+	void	(*codec_clock_setup)(void);
+	int	(*codec_clock_on)(void);
+	int 	(*codec_clock_off)(void);
+	int	(*get_default_samplerate)(void);
+};
+
+/*********** Mixer function prototypes *************************/
+int snd_omap_mixer(struct snd_card_omap_codec *);
+void snd_omap_init_mixer(void);
+#ifdef CONFIG_PM
+void snd_omap_suspend_mixer(void);
+void snd_omap_resume_mixer(void);
+#endif
+
+/*
+ * Defines codec specific functions pointers that can be used from the 
+ * common omap-alse base driver for all omap codecs. (tsc2101 and aic23)
+ */
+void define_codec_functions(struct omap_alsa_codec_config *codec_config);
+inline void aic23_configure(void);
+void aic23_set_samplerate(long rate);
+void aic23_clock_setup(void);
+int aic23_clock_on(void);
+int aic23_clock_off(void);
+int aic23_get_default_samplerate(void);
+
+inline void tsc2101_configure(void);
+void tsc2101_set_samplerate(long rate);
+void tsc2101_clock_setup(void);
+int tsc2101_clock_on(void);
+int tsc2101_clock_off(void);
+int tsc2101_get_default_samplerate(void);
+
+/*********** function prototype to function called from the dma interrupt handler ******/
+void audio_dma_callback(void *);
+
+#endif
Index: linux-omap-2.6.git-q/sound/arm/omap-aic23.h
===================================================================
--- linux-omap-2.6.git-q.orig/sound/arm/omap-aic23.h	2006-02-14 08:25:48.000000000 -0400
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,130 +0,0 @@
-/*
- * sound/arm/omap-aic23.h
- * 
- * Alsa Driver for AIC23 codec on OSK5912 platform board
- *
- * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
- * Written by Daniel Petrini, David Cohen, Anderson Briglia
- *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  History
- *  -------
- *
- *  2005/07/25 INdT-10LE Kernel Team - 	Alsa driver for omap osk,
- *  					original version based in sa1100 driver
- *  					and omap oss driver.
- *
- *  2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix as proposed by Ajaya Babu
- */
-
-#ifndef __OMAP_AIC23_H
-#define __OMAP_AIC23_H
-
-#include <sound/driver.h>
-#include <asm/arch/dma.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#define DEFAULT_OUTPUT_VOLUME         0x60
-#define DEFAULT_INPUT_VOLUME          0x00	/* 0 ==> mute line in */
-
-#define OUTPUT_VOLUME_MIN             LHV_MIN
-#define OUTPUT_VOLUME_MAX             LHV_MAX
-#define OUTPUT_VOLUME_RANGE           (OUTPUT_VOLUME_MAX - OUTPUT_VOLUME_MIN)
-#define OUTPUT_VOLUME_MASK            OUTPUT_VOLUME_MAX
-
-#define INPUT_VOLUME_MIN 	      LIV_MIN
-#define INPUT_VOLUME_MAX 	      LIV_MAX
-#define INPUT_VOLUME_RANGE 	      (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
-#define INPUT_VOLUME_MASK 	      INPUT_VOLUME_MAX
-
-#define SIDETONE_MASK                 0x1c0
-#define SIDETONE_0                    0x100
-#define SIDETONE_6                    0x000
-#define SIDETONE_9                    0x040
-#define SIDETONE_12                   0x080
-#define SIDETONE_18                   0x0c0
-
-#define DEFAULT_ANALOG_AUDIO_CONTROL  DAC_SELECTED | STE_ENABLED | BYPASS_ON | INSEL_MIC | MICB_20DB
-
-/*
- * Buffer management for alsa and dma
- */
-struct audio_stream {
-	char *id;		/* identification string */
-	int stream_id;		/* numeric identification */
-	int dma_dev;		/* dma number of that device */
-	int *lch;		/* Chain of channels this stream is linked to */
-	char started;		/* to store if the chain was started or not */
-	int dma_q_head;		/* DMA Channel Q Head */
-	int dma_q_tail;		/* DMA Channel Q Tail */
-	char dma_q_count;	/* DMA Channel Q Count */
-	int active:1;		/* we are using this stream for transfer now */
-	int period;		/* current transfer period */
-	int periods;		/* current count of periods registerd in the DMA engine */
-	spinlock_t dma_lock;	/* for locking in DMA operations */
-	snd_pcm_substream_t *stream;	/* the pcm stream */
-	unsigned linked:1;	/* dma channels linked */
-	int offset;		/* store start position of the last period in the alsa buffer */
-	int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
-	int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
-};
-
-/*
- * Alsa card structure for aic23
- */
-struct snd_card_omap_aic23 {
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	long samplerate;
-	struct audio_stream s[2];	/* playback & capture */
-};
-
-/*********** Function Prototypes *************************/
-
-void audio_dma_callback(void *);
-int snd_omap_mixer(struct snd_card_omap_aic23 *);
-void snd_omap_init_mixer(void);
-/* Clock functions */
-int omap_aic23_clock_on(void);
-int omap_aic23_clock_off(void);
-
-#ifdef CONFIG_PM
-void snd_omap_suspend_mixer(void);
-void snd_omap_resume_mixer(void);
-#endif
-
-/* Codec AIC23 */
-#if defined(CONFIG_SENSORS_TLV320AIC23) || defined (CONFIG_SENSORS_TLV320AIC23_MODULE)
-
-extern int tlv320aic23_write_value(u8 reg, u16 value);
-
-/* TLV320AIC23 is a write only device */
-static __inline__ void audio_aic23_write(u8 address, u16 data)
-{
-	tlv320aic23_write_value(address, data);
-}
-
-#endif /* CONFIG_SENSORS_TLV320AIC23 */
-
-#endif
Index: linux-omap-2.6.git-q/sound/arm/omap-aic23.c
===================================================================
--- linux-omap-2.6.git-q.orig/sound/arm/omap-aic23.c	2006-02-14 08:25:48.000000000 -0400
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,929 +0,0 @@
-/*
- * sound/arm/omap-aic23.c
- * 
- * Alsa Driver for AIC23 codec on OSK5912 platform board
- *
- * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
- * Written by Daniel Petrini, David Cohen, Anderson Briglia
- *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
- *
- * Based on sa11xx-uda1341.c, 
- * Copyright (C) 2002 Tomas Kasparek <tomas.kasparek@seznam.cz>
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * History:
- *
- * 2005-07-29   INdT Kernel Team - Alsa driver for omap osk. Creation of new 
- *                                 file omap-aic23.c
- *
- * 2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix as proposed by Ajaya Babu
- */
-
-#include <linux/config.h>
-#include <sound/driver.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/ioctl.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-
-#ifdef CONFIG_PM
-#include <linux/pm.h>
-#endif
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/arch/dma.h>
-#include <asm/arch/aic23.h>
-#include <asm/arch/mcbsp.h>
-#include <asm/arch/clock.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#include <sound/memalloc.h>
-
-#include "omap-alsa-dma.h"
-#include "omap-aic23.h"
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define ADEBUG() printk("XXX Alsa debug f:%s, l:%d\n", __FUNCTION__, __LINE__)
-#else
-#define ADEBUG()		/* nop */
-#endif
-
-/* Define to set the AIC23 as the master w.r.t McBSP */
-#define AIC23_MASTER
-
-/*
- * AUDIO related MACROS
- */
-#define DEFAULT_BITPERSAMPLE          16
-#define AUDIO_RATE_DEFAULT	      44100
-#define AUDIO_MCBSP                   OMAP_MCBSP1
-#define NUMBER_SAMPLE_RATES_SUPPORTED 10
-
-
-MODULE_AUTHOR("Daniel Petrini, David Cohen, Anderson Briglia - INdT");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("OMAP AIC23 driver for ALSA");
-MODULE_SUPPORTED_DEVICE("{{AIC23,OMAP AIC23}}");
-MODULE_ALIAS("omap_mcbsp.1");
-
-static char *id = NULL;	
-MODULE_PARM_DESC(id, "OMAP OSK ALSA Driver for AIC23 chip.");
-
-static struct snd_card_omap_aic23 *omap_aic23 = NULL;
-
-static struct clk *aic23_mclk = 0;
-
-struct sample_rate_rate_reg_info {
-	u8 control;		/* SR3, SR2, SR1, SR0 and BOSR */
-	u8 divider;		/* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
-};
-
-/*
- * DAC USB-mode sampling rates (MCLK = 12 MHz)
- * The rates and rate_reg_into MUST be in the same order
- */
-static unsigned int rates[] = {
-	4000, 8000, 16000, 22050,
-	24000, 32000, 44100,
-	48000, 88200, 96000,
-};
-static const struct sample_rate_rate_reg_info
- rate_reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
-	{0x06, 1},		/*  4000 */
-	{0x06, 0},		/*  8000 */
-	{0x0C, 1},		/* 16000 */
-	{0x11, 1},              /* 22050 */
-	{0x00, 1},		/* 24000 */
-	{0x0C, 0},		/* 32000 */
-	{0x11, 0},		/* 44100 */
-	{0x00, 0},		/* 48000 */
-	{0x1F, 0},		/* 88200 */
-	{0x0E, 0},		/* 96000 */
-};
-
-/*
- *  mcbsp configuration structure
- */
-static struct omap_mcbsp_reg_cfg initial_config_mcbsp = {
-	.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
-	.spcr1 = RINTM(3) | RRST,
-	.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
-	    RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
-	.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
-	.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
-	    XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
-	.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
-	.srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
-	.srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
-#ifndef AIC23_MASTER
-	/* configure McBSP to be the I2S master */
-	.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,
-#else
-	/* configure McBSP to be the I2S slave */
-	.pcr0 = CLKXP | CLKRP,
-#endif				/* AIC23_MASTER */
-};
-
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
-	.count = ARRAY_SIZE(rates),
-	.list = rates,
-	.mask = 0,
-};
-
-/*
- * HW interface start and stop helper functions
- */
-static int audio_ifc_start(void)
-{
-	omap_mcbsp_start(AUDIO_MCBSP);
-	return 0;
-}
-
-static int audio_ifc_stop(void)
-{
-	omap_mcbsp_stop(AUDIO_MCBSP);
-	return 0;
-}
-
-/*
- * Codec/mcbsp init and configuration section
- * codec dependent code.
- */
-
-/*
- * Sample rate changing
- */
-static void omap_aic23_set_samplerate(struct snd_card_omap_aic23
-				      *omap_aic23, long rate)
-{
-	u8 count = 0;
-	u16 data = 0;
-
-	/* Fix the rate if it has a wrong value */
-	if (rate >= 96000)
-		rate = 96000;
-	else if (rate >= 88200)
-		rate = 88200;
-	else if (rate >= 48000)
-		rate = 48000;
-	else if (rate >= 44100)
-		rate = 44100;
-	else if (rate >= 32000)
-		rate = 32000;
-	else if (rate >= 24000)
-		rate = 24000;
-	else if (rate >= 22050)
-		rate = 22050;
-	else if (rate >= 16000)
-		rate = 16000;
-	else if (rate >= 8000)
-		rate = 8000;
-	else
-		rate = 4000;
-
-	/* Search for the right sample rate */
-	/* Verify what happens if the rate is not supported
-	 * now it goes to 96Khz */
-	while ((rates[count] != rate) &&
-	       (count < (NUMBER_SAMPLE_RATES_SUPPORTED - 1))) {
-		count++;
-	}
-
-	data = (rate_reg_info[count].divider << CLKIN_SHIFT) |
-	    (rate_reg_info[count].control << BOSR_SHIFT) | USB_CLK_ON;
-
-	audio_aic23_write(SAMPLE_RATE_CONTROL_ADDR, data);
-
-	omap_aic23->samplerate = rate;
-}
-
-static inline void aic23_configure(void)
-{
-	/* Reset codec */
-	audio_aic23_write(RESET_CONTROL_ADDR, 0);
-
-	/* Initialize the AIC23 internal state */
-
-	/* Analog audio path control, DAC selected, delete INSEL_MIC for line in */
-	audio_aic23_write(ANALOG_AUDIO_CONTROL_ADDR, DEFAULT_ANALOG_AUDIO_CONTROL);
-
-	/* Digital audio path control, de-emphasis control 44.1kHz */
-	audio_aic23_write(DIGITAL_AUDIO_CONTROL_ADDR, DEEMP_44K);
-
-	/* Digital audio interface, master/slave mode, I2S, 16 bit */
-#ifdef AIC23_MASTER
-	audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR,
-			  MS_MASTER | IWL_16 | FOR_DSP);
-#else
-	audio_aic23_write(DIGITAL_AUDIO_FORMAT_ADDR, IWL_16 | FOR_DSP);
-#endif
-
-	/* Enable digital interface */
-	audio_aic23_write(DIGITAL_INTERFACE_ACT_ADDR, ACT_ON);
-
-}
-
-static void omap_aic23_audio_init(struct snd_card_omap_aic23 *omap_aic23)
-{
-	/* Setup DMA stuff */
-	omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].id = "Alsa AIC23 out";
-	omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id =
-	    SNDRV_PCM_STREAM_PLAYBACK;
-	omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev =
-	    OMAP_DMA_MCBSP1_TX;
-	omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].hw_start =
-	    audio_ifc_start;
-	omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK].hw_stop =
-	    audio_ifc_stop;
-
-	omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].id = "Alsa AIC23 in";
-	omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].stream_id =
-	    SNDRV_PCM_STREAM_CAPTURE;
-	omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].dma_dev =
-	    OMAP_DMA_MCBSP1_RX;
-	omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].hw_start =
-	    audio_ifc_start;
-	omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE].hw_stop =
-	    audio_ifc_stop;
-
-	/* configuring the McBSP */
-	omap_mcbsp_request(AUDIO_MCBSP);
-
-	/* if configured, then stop mcbsp */
-	omap_mcbsp_stop(AUDIO_MCBSP);
-
-	omap_mcbsp_config(AUDIO_MCBSP, &initial_config_mcbsp);
-	omap_mcbsp_start(AUDIO_MCBSP);
-	aic23_configure();
-}
-
-/* 
- * DMA functions 
- * Depends on omap-aic23-dma.c functions and (omap) dma.c
- * 
- */
-#define DMA_BUF_SIZE	1024 * 8
-
-static int audio_dma_request(struct audio_stream *s,
-			     void (*callback) (void *))
-{
-	int err;
-
-	err = omap_request_sound_dma(s->dma_dev, s->id, s, &s->lch);
-	if (err < 0)
-		printk(KERN_ERR "unable to grab audio dma 0x%x\n",
-		       s->dma_dev);
-	return err;
-}
-
-static int audio_dma_free(struct audio_stream *s)
-{
-	int err = 0;
-
-	err = omap_free_sound_dma(s, &s->lch);
-	if (err < 0)
-		printk(KERN_ERR "Unable to free audio dma channels!\n");
-	return err;
-}
-
-/*
- *  This function should calculate the current position of the dma in the
- *  buffer. It will help alsa middle layer to continue update the buffer.
- *  Its correctness is crucial for good functioning.
- */
-static u_int audio_get_dma_pos(struct audio_stream *s)
-{
-	snd_pcm_substream_t *substream = s->stream;
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	unsigned int offset;
-	unsigned long flags;
-	dma_addr_t count;
-	ADEBUG();
-
-	/* this must be called w/ interrupts locked as requested in dma.c */
-	spin_lock_irqsave(&s->dma_lock, flags);
-
-	/* For the current period let's see where we are */
-	count = omap_get_dma_src_addr_counter(s->lch[s->dma_q_head]);
-
-	spin_unlock_irqrestore(&s->dma_lock, flags);
-
-	/* Now, the position related to the end of that period */
-	offset = bytes_to_frames(runtime, s->offset) - bytes_to_frames(runtime, count);
-
-	if (offset >= runtime->buffer_size || offset < 0)
-		offset = 0;
-
-	return offset;
-}
-
-/*
- * this stops the dma and clears the dma ptrs
- */
-static void audio_stop_dma(struct audio_stream *s)
-{
-	unsigned long flags;
-	ADEBUG();
-
-	spin_lock_irqsave(&s->dma_lock, flags);
-	s->active = 0;
-	s->period = 0;
-	s->periods = 0;
-
-	/* this stops the dma channel and clears the buffer ptrs */
-	omap_audio_stop_dma(s);
-
-	omap_clear_sound_dma(s);
-
-	spin_unlock_irqrestore(&s->dma_lock, flags);
-}
-
-/*
- *  Main dma routine, requests dma according where you are in main alsa buffer
- */
-static void audio_process_dma(struct audio_stream *s)
-{
-	snd_pcm_substream_t *substream = s->stream;
-	snd_pcm_runtime_t *runtime;
-	unsigned int dma_size;
-	unsigned int offset;
-	int ret;
-
-	runtime = substream->runtime;
-	if (s->active) {
-		dma_size = frames_to_bytes(runtime, runtime->period_size);
-		offset = dma_size * s->period;
-		snd_assert(dma_size <= DMA_BUF_SIZE,);
-		ret =
-		    omap_start_sound_dma(s,
-					 (dma_addr_t) runtime->dma_area +
-					 offset, dma_size);
-		if (ret) {
-			printk(KERN_ERR
-			       "audio_process_dma: cannot queue DMA buffer (%i)\n",
-			       ret);
-			return;
-		}
-
-		s->period++;
-		s->period %= runtime->periods;
-		s->periods++;
-		s->offset = offset;
-	}
-}
-
-/* 
- *  This is called when dma IRQ occurs at the end of each transmited block
- */
-void audio_dma_callback(void *data)
-{
-	struct audio_stream *s = data;
-
-	/* 
-	 * If we are getting a callback for an active stream then we inform
-	 * the PCM middle layer we've finished a period
-	 */
-	if (s->active)
-		snd_pcm_period_elapsed(s->stream);
-
-	spin_lock(&s->dma_lock);
-	if (s->periods > 0) {
-		s->periods--;
-	}
-	audio_process_dma(s);
-	spin_unlock(&s->dma_lock);
-}
-
-
-/* 
- * Alsa section
- * PCM settings and callbacks
- */
-
-static int snd_omap_aic23_trigger(snd_pcm_substream_t * substream, int cmd)
-{
-	struct snd_card_omap_aic23 *chip =
-	    snd_pcm_substream_chip(substream);
-	int stream_id = substream->pstr->stream;
-	struct audio_stream *s = &chip->s[stream_id];
-	int err = 0;
-	ADEBUG();
-
-	/* note local interrupts are already disabled in the midlevel code */
-	spin_lock(&s->dma_lock);
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		/* requested stream startup */
-		s->active = 1;
-		audio_process_dma(s);
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-		/* requested stream shutdown */
-		audio_stop_dma(s);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-	spin_unlock(&s->dma_lock);
-	
-	return err;
-}
-
-static int snd_omap_aic23_prepare(snd_pcm_substream_t * substream)
-{
-	struct snd_card_omap_aic23 *chip =
-	    snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	struct audio_stream *s = &chip->s[substream->pstr->stream];
-
-	/* set requested samplerate */
-	omap_aic23_set_samplerate(chip, runtime->rate);
-
-	s->period = 0;
-	s->periods = 0;
-
-	return 0;
-}
-
-static snd_pcm_uframes_t snd_omap_aic23_pointer(snd_pcm_substream_t *
-						substream)
-{
-	struct snd_card_omap_aic23 *chip =
-	    snd_pcm_substream_chip(substream);
-	
-	return audio_get_dma_pos(&chip->s[substream->pstr->stream]);
-}
-
-/* Hardware capabilities */
-
-static snd_pcm_hardware_t snd_omap_aic23_capture = {
-	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
-		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
-	.formats = (SNDRV_PCM_FMTBIT_S16_LE),
-	.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
-		  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
-		  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-		  SNDRV_PCM_RATE_KNOT),
-	.rate_min = 8000,
-	.rate_max = 96000,
-	.channels_min = 2,
-	.channels_max = 2,
-	.buffer_bytes_max = 128 * 1024,
-	.period_bytes_min = 32,
-	.period_bytes_max = 8 * 1024,
-	.periods_min = 16,
-	.periods_max = 255,
-	.fifo_size = 0,
-};
-
-static snd_pcm_hardware_t snd_omap_aic23_playback = {
-	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
-		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),	
-	.formats = (SNDRV_PCM_FMTBIT_S16_LE),
-	.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
-		  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
-		  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-		  SNDRV_PCM_RATE_KNOT),
-	.rate_min = 8000,
-	.rate_max = 96000,
-	.channels_min = 2,
-	.channels_max = 2,
-	.buffer_bytes_max = 128 * 1024,
-	.period_bytes_min = 32,
-	.period_bytes_max = 8 * 1024,
-	.periods_min = 16,
-	.periods_max = 255,
-	.fifo_size = 0,
-};
-
-static int snd_card_omap_aic23_open(snd_pcm_substream_t * substream)
-{
-	struct snd_card_omap_aic23 *chip =
-	    snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	int stream_id = substream->pstr->stream;
-	int err;
-	ADEBUG();
-
-	chip->s[stream_id].stream = substream;
-	
-	omap_aic23_clock_on();
-	
-	if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
-		runtime->hw = snd_omap_aic23_playback;
-	else
-		runtime->hw = snd_omap_aic23_capture;
-	if ((err =
-	     snd_pcm_hw_constraint_integer(runtime,
-					   SNDRV_PCM_HW_PARAM_PERIODS)) <
-	    0)
-		return err;
-	if ((err =
-	     snd_pcm_hw_constraint_list(runtime, 0,
-					SNDRV_PCM_HW_PARAM_RATE,
-					&hw_constraints_rates)) < 0)
-		return err;
-
-	return 0;
-}
-
-static int snd_card_omap_aic23_close(snd_pcm_substream_t * substream)
-{
-	struct snd_card_omap_aic23 *chip =
-	    snd_pcm_substream_chip(substream);
-	ADEBUG();
-	
-	omap_aic23_clock_off();
-	chip->s[substream->pstr->stream].stream = NULL;
-	
-	return 0;
-}
-
-/* HW params & free */
-
-static int snd_omap_aic23_hw_params(snd_pcm_substream_t * substream,
-				    snd_pcm_hw_params_t * hw_params)
-{
-	return snd_pcm_lib_malloc_pages(substream,
-					params_buffer_bytes(hw_params));
-}
-
-static int snd_omap_aic23_hw_free(snd_pcm_substream_t * substream)
-{
-	return snd_pcm_lib_free_pages(substream);
-}
-
-/* pcm operations */
-
-static snd_pcm_ops_t snd_card_omap_aic23_playback_ops = {
-	.open =		snd_card_omap_aic23_open,
-	.close =	snd_card_omap_aic23_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_omap_aic23_hw_params,
-	.hw_free =	snd_omap_aic23_hw_free,
-	.prepare =	snd_omap_aic23_prepare,
-	.trigger =	snd_omap_aic23_trigger,
-	.pointer =	snd_omap_aic23_pointer,
-};
-
-static snd_pcm_ops_t snd_card_omap_aic23_capture_ops = {
-	.open =		snd_card_omap_aic23_open,
-	.close =	snd_card_omap_aic23_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_omap_aic23_hw_params,
-	.hw_free =	snd_omap_aic23_hw_free,
-	.prepare =	snd_omap_aic23_prepare,
-	.trigger =	snd_omap_aic23_trigger,
-	.pointer =	snd_omap_aic23_pointer,
-};
-
-/*
- *  Alsa init and exit section
- *  
- *  Inits pcm alsa structures, allocate the alsa buffer, suspend, resume
- */
-static int __init snd_card_omap_aic23_pcm(struct snd_card_omap_aic23
-					  *omap_aic23, int device)
-{
-	snd_pcm_t *pcm;
-	int err;
-	ADEBUG();
-
-	if ((err =
-	     snd_pcm_new(omap_aic23->card, "AIC23 PCM", device, 1, 1,
-			 &pcm)) < 0)
-		return err;
-
-	/* sets up initial buffer with continuous allocation */
-	snd_pcm_lib_preallocate_pages_for_all(pcm,
-					      SNDRV_DMA_TYPE_CONTINUOUS,
-					      snd_dma_continuous_data
-					      (GFP_KERNEL),
-					      128 * 1024, 128 * 1024);
-
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
-			&snd_card_omap_aic23_playback_ops);
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
-			&snd_card_omap_aic23_capture_ops);
-	pcm->private_data = omap_aic23;
-	pcm->info_flags = 0;
-	strcpy(pcm->name, "omap aic23 pcm");
-
-	omap_aic23_audio_init(omap_aic23);
-
-	/* setup DMA controller */
-	audio_dma_request(&omap_aic23->s[SNDRV_PCM_STREAM_PLAYBACK],
-			  audio_dma_callback);
-	audio_dma_request(&omap_aic23->s[SNDRV_PCM_STREAM_CAPTURE],
-			  audio_dma_callback);
-
-	omap_aic23->pcm = pcm;
-
-	return 0;
-}
-
-
-#ifdef CONFIG_PM
-
-static int snd_omap_aic23_suspend(snd_card_t * card, pm_message_t state)
-{
-	struct snd_card_omap_aic23 *chip = card->private_data;
-	ADEBUG();
-
-	if (chip->card->power_state != SNDRV_CTL_POWER_D3hot) {
-		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
-		snd_pcm_suspend_all(chip->pcm);
-		/* Mutes and turn clock off */
-		omap_aic23_clock_off();
-		snd_omap_suspend_mixer();
-	}
-
-	return 0;
-}
-
-/*
- *  Prepare hardware for resume
- */
-static int snd_omap_aic23_resume(snd_card_t * card)
-{
-	struct snd_card_omap_aic23 *chip = card->private_data;
-	ADEBUG();
-	
-	if (chip->card->power_state != SNDRV_CTL_POWER_D0) {
-		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
-		omap_aic23_clock_on();
-		snd_omap_resume_mixer();
-	}
-
-	return 0;
-}
-
-/*
- * Driver suspend/resume - calls alsa functions. Some hints from aaci.c
- */
-static int omap_aic23_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	snd_card_t *card = platform_get_drvdata(pdev);
-	
-	if (card->power_state != SNDRV_CTL_POWER_D3hot) {
-		snd_omap_aic23_suspend(card, PMSG_SUSPEND);
-	}
-	return 0;
-}
-
-static int omap_aic23_resume(struct platform_device *pdev)
-{
-	snd_card_t *card = platform_get_drvdata(pdev);
-
-	if (card->power_state != SNDRV_CTL_POWER_D0) {
-		snd_omap_aic23_resume(card);
-	}
-	return 0;
-}
-
-#else
-#define snd_omap_aic23_suspend	NULL
-#define snd_omap_aic23_resume	NULL
-#define omap_aic23_suspend	NULL
-#define omap_aic23_resume	NULL
-
-#endif	/* CONFIG_PM */
-
-/* 
- */
-void snd_omap_aic23_free(snd_card_t * card)
-{
-	struct snd_card_omap_aic23 *chip = card->private_data;
-	ADEBUG();
-	
-	/*
-	 * Turn off codec after it is done.
-	 * Can't do it immediately, since it may still have
-	 * buffered data.
-	 */
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(2);
-
-	omap_mcbsp_stop(AUDIO_MCBSP);
-	omap_mcbsp_free(AUDIO_MCBSP);
-
-	audio_aic23_write(RESET_CONTROL_ADDR, 0);
-	audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 0xff);
-
-	audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]);
-	audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
-}
-
-/*
- *  Omap MCBSP clock configuration
- *  
- *  Here we have some functions that allows clock to be enabled and
- *   disabled only when needed. Besides doing clock configuration 
- *   it allows turn on/turn off audio when necessary. 
- */
-#define CODEC_CLOCK                   12000000
-#define AUDIO_RATE_DEFAULT	      44100
-
-/*
- * Do clock framework mclk search
- */
-static __init void omap_aic23_clock_setup(void)
-{
-	aic23_mclk = clk_get(0, "mclk");
-}
-
-/*
- * Do some sanity check, set clock rate, starts it and
- *  turn codec audio on 
- */
-int omap_aic23_clock_on(void)
-{
-	if (clk_get_usecount(aic23_mclk) > 0) {
-		/* MCLK is already in use */
-		printk(KERN_WARNING
-		       "MCLK in use at %d Hz. We change it to %d Hz\n",
-		       (uint) clk_get_rate(aic23_mclk),
-		       CODEC_CLOCK);
-	}
-	
-	if (clk_set_rate(aic23_mclk, CODEC_CLOCK)) {
-		printk(KERN_ERR
-		       "Cannot set MCLK for AIC23 CODEC\n");
-		return -ECANCELED;
-	}
-
-	clk_enable(aic23_mclk);
-
-	printk(KERN_DEBUG
-		"MCLK = %d [%d], usecount = %d\n",
-	       (uint) clk_get_rate(aic23_mclk), CODEC_CLOCK,
-	       clk_get_usecount(aic23_mclk));
-
-	/* Now turn the audio on */
-	audio_aic23_write(POWER_DOWN_CONTROL_ADDR, 
-			  ~DEVICE_POWER_OFF & ~OUT_OFF & ~DAC_OFF &
-			  ~ADC_OFF & ~MIC_OFF & ~LINE_OFF);
-	
-	return 0;
-}
-/*
- * Do some sanity check, turn clock off and then turn
- *  codec audio off
- */
-int omap_aic23_clock_off(void)
-{
-	if  (clk_get_usecount(aic23_mclk) > 0) { 
-		if (clk_get_rate(aic23_mclk) != CODEC_CLOCK) {
-			printk(KERN_WARNING
-			       "MCLK for audio should be %d Hz. But is %d Hz\n",
-			       (uint) clk_get_rate(aic23_mclk),
-			       CODEC_CLOCK);
-		}
-
-		clk_disable(aic23_mclk);
-	}
-	
-	audio_aic23_write(POWER_DOWN_CONTROL_ADDR,
-			  DEVICE_POWER_OFF | OUT_OFF | DAC_OFF |
-			  ADC_OFF | MIC_OFF | LINE_OFF);	
-	return 0;
-}
-
-/* module init & exit */
-
-/* 
- *  Inits alsa soudcard structure
- */
-static int __init snd_omap_aic23_probe(struct platform_device *pdev)
-{
-	int err = 0;
-	snd_card_t *card;
-	ADEBUG();
-	
-	/* gets clock from clock framework */
-	omap_aic23_clock_setup();
-
-	/* register the soundcard */
-	card = snd_card_new(-1, id, THIS_MODULE, sizeof(omap_aic23));
-	if (card == NULL)
-		return -ENOMEM;
-
-	omap_aic23 = kcalloc(1, sizeof(*omap_aic23), GFP_KERNEL);
-	if (omap_aic23 == NULL)
-		return -ENOMEM;
-
-	card->private_data = (void *) omap_aic23;
-	card->private_free = snd_omap_aic23_free;
-
-	omap_aic23->card = card;
-	omap_aic23->samplerate = AUDIO_RATE_DEFAULT;
-
-	spin_lock_init(&omap_aic23->s[0].dma_lock);
-	spin_lock_init(&omap_aic23->s[1].dma_lock);
-
-	/* mixer */
-	if ((err = snd_omap_mixer(omap_aic23)) < 0) 
-		goto nodev;
-
-	/* PCM */
-	if ((err = snd_card_omap_aic23_pcm(omap_aic23, 0)) < 0)
-		goto nodev;
-
-	strcpy(card->driver, "AIC23");
-	strcpy(card->shortname, "OSK AIC23");
-	sprintf(card->longname, "OMAP OSK with AIC23");
-
-	snd_omap_init_mixer();
-
-	snd_card_set_dev(card, &pdev->dev);
-	
-	if ((err = snd_card_register(card)) == 0) {
-		printk(KERN_INFO "OSK audio support initialized\n");
-		platform_set_drvdata(pdev, card);
-		return 0;
-	}
-	
-nodev:
-	snd_omap_aic23_free(card);
-	
-	return err;
-}
-
-static int snd_omap_aic23_remove(struct platform_device *pdev)
-{
-	snd_card_t *card = platform_get_drvdata(pdev);
-	struct snd_card_omap_aic23 *chip = card->private_data;
-	
-	snd_card_free(card);
-
-	omap_aic23 = NULL;
-	card->private_data = NULL;
-	kfree(chip);
-	
-	platform_set_drvdata(pdev, NULL);
-	
-	return 0;
-	
-}
-
-static struct platform_driver omap_alsa_driver = {
-	.probe =	snd_omap_aic23_probe,
-	.remove =	snd_omap_aic23_remove,
-	.suspend =	omap_aic23_suspend, 
-	.resume =	omap_aic23_resume, 
-	.driver = {
-		.name =	"omap_mcbsp",
-	},
-};
-
-static int __init omap_aic23_init(void)
-{
-	int err;
-	ADEBUG();
-
-	err = platform_driver_register(&omap_alsa_driver);
-
-	return err;
-}
-
-static void __exit omap_aic23_exit(void)
-{
-	ADEBUG();
-	
-	platform_driver_unregister(&omap_alsa_driver);
-}
-
-module_init(omap_aic23_init);
-module_exit(omap_aic23_exit);


[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Alsa modularisations and support for tsc2101 1/7
  2006-02-20 17:44 [PATCH] Alsa modularisations and support for tsc2101 1/7 Daniel Petrini
@ 2006-02-20 22:11 ` Komal Shah
  2006-02-21 12:14   ` Daniel Petrini
  0 siblings, 1 reply; 7+ messages in thread
From: Komal Shah @ 2006-02-20 22:11 UTC (permalink / raw)
  To: Daniel Petrini, OMAP-Linux

Daniel, 

> @@ -0,0 +1,714 @@
> +/*
> + * sound/arm/omap-alsa.c
> + * 
> + * Alsa Driver for AIC23 codec on OSK5912 platform board

Now *not* just for AIC23. Time to update this line.

> + *
> + * History:
> + *
> + * 2005-07-29   INdT Kernel Team - Alsa driver for omap osk.
> Creation of new 
> + *                                 file omap-aic23.c
> + * 
> + * 2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix
> as proposed by Ajaya Babu
> + *
> + * 2006-02-07   Daniel Petrini  - Codec specific function separated.
> File renamed to
> + *                                omap-alsa.c
> + * 2006-02-10	Mika Laitio	- Codec specific function pointers are set
> in the codec.
> + * 				  Default samplerate queried from the codec.
> + */

I am happy to see this big development and cleaned up driver interface,
but I think we can trim down this History as I believe GIT is being
really used for this purpose. Only thing we need to take care is give
better comment at patch submit time :)

> +MODULE_ALIAS("omap_alsa_mcbsp.1");

Do we really need to add "_mcbsp" in that string? It looks confusing
while reading. 

> +#define DMA_BUF_SIZE	1024 * 8
> +

Brackets around 1024 * 8 would be better.

> +static int audio_dma_request(struct audio_stream *s,
> +			     void (*callback) (void *))
> +{
> +	int err;
> +	ADEBUG();
> +
> +	err = omap_request_sound_dma(s->dma_dev, s->id, s, &s->lch);
> +	if (err < 0)
> +		printk(KERN_ERR "unable to grab audio dma 0x%x\n",
> +		       s->dma_dev);

s/unable/Unable will look good :)

> +
> +/*
> + *  This function should calculate the current position of the dma
> in the
> + *  buffer. It will help alsa middle layer to continue update the
> buffer.
> + *  Its correctness is crucial for good functioning.
> + */
> +static u_int audio_get_dma_pos(struct audio_stream *s)
> +{
> +	snd_pcm_substream_t *substream = s->stream;
> +	snd_pcm_runtime_t *runtime = substream->runtime;
> +	unsigned int offset;
> +	unsigned long flags;
> +	dma_addr_t count;
> +	ADEBUG();
> +
> +	/* this must be called w/ interrupts locked as requested in dma.c
> */
> +	spin_lock_irqsave(&s->dma_lock, flags);
> +
> +	/* For the current period let's see where we are */
> +	count = omap_get_dma_src_addr_counter(s->lch[s->dma_q_head]);
> +
> +	spin_unlock_irqrestore(&s->dma_lock, flags);
> +
> +	/* Now, the position related to the end of that period */
> +	offset = bytes_to_frames(runtime, s->offset) -
> bytes_to_frames(runtime, count);
> +
> +	if (offset >= runtime->buffer_size || offset < 0)
> +		offset = 0;

I am not sure but will this "unsigned int offset" will be ever become <
0 here ? 

> +
> +/* 
> + *  This is called when dma IRQ occurs at the end of each transmited
> block
> + */
> +void audio_dma_callback(void *data)
> +{
> +	struct audio_stream *s = data;
> +	ADEBUG();
> +
> +	/* 
> +	 * If we are getting a callback for an active stream then we inform
> +	 * the PCM middle layer we've finished a period
> +	 */
> +	if (s->active)
> +		snd_pcm_period_elapsed(s->stream);
> +
> +	spin_lock(&s->dma_lock);
> +	if (s->periods > 0) {
> +		s->periods--;
> +	}

{} not need around if.

> +
> +/* 
> + * Alsa section
> + * PCM settings and callbacks
> + */
> +
> +static int snd_omap_alsa_trigger(snd_pcm_substream_t * substream,
> int cmd)

Extra empty line after function comments. Same review comment applies
to all other places in the file. You may like to remove that. 

> +
> +static int snd_card_omap_alsa_open(snd_pcm_substream_t * substream)
> +{
> +	struct snd_card_omap_codec *chip =
> +	    snd_pcm_substream_chip(substream);
> +	snd_pcm_runtime_t *runtime = substream->runtime;
> +	int stream_id = substream->pstr->stream;
> +	int err;
> +	
> +	ADEBUG();
> +	chip->s[stream_id].stream = substream;
> +	alsa_codec_config->codec_clock_on();
> +	if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
> +		runtime->hw = snd_omap_alsa_playback;
> +	}

{} not needed after if and else below.

> +	else {
> +		runtime->hw = snd_omap_alsa_capture;
> +	}
> +	if ((err = snd_pcm_hw_constraint_integer(runtime,
> +					   SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
> +		return err;
> +	}
> +	if ((err = snd_pcm_hw_constraint_list(runtime, 0,
> +					SNDRV_PCM_HW_PARAM_RATE,
> +					&hw_constraints_rates)) < 0) {
> +		return err;
> +	}

Ditto. Also adding one empty line between ifs will look better.

> +
> +	/* sets up initial buffer with continuous allocation */
> +	snd_pcm_lib_preallocate_pages_for_all(pcm,
> +					      SNDRV_DMA_TYPE_CONTINUOUS,
> +					      snd_dma_continuous_data
> +					      (GFP_KERNEL),
> +					      128 * 1024, 128 * 1024);

Brackets around GFP_KERNEL may not be needed.

> +
> +	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
> +			&snd_card_omap_alsa_playback_ops);
> +	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
> +			&snd_card_omap_alsa_capture_ops);
> +	pcm->private_data = omap_alsa;
> +	pcm->info_flags = 0;
> +	strcpy(pcm->name, "omap aic23 pcm");

aic23? 

> +
> +
> +#ifdef CONFIG_PM
> +
> +static int snd_omap_alsa_suspend(snd_card_t * card, pm_message_t
> state)

Empty line after CONFIG_PM may not be needed.

> +
> +#else
> +#define snd_omap_alsa_suspend	NULL
> +#define snd_omap_alsa_resume	NULL
> +#define omap_alsa_suspend	NULL
> +#define omap_alsa_resume	NULL
> +
> +#endif	/* CONFIG_PM */

May be snd_omap_alsa_suspend(x) do {} while(0) style would be better.

> +
> +/* 
> + */
> +void snd_omap_alsa_free(snd_card_t * card)
> +{
> +	struct snd_card_omap_codec *chip = card->private_data;
> +	ADEBUG();
> +	
> +	/*
> +	 * Turn off codec after it is done.
> +	 * Can't do it immediately, since it may still have
> +	 * buffered data.
> +	 */
> +	set_current_state(TASK_INTERRUPTIBLE);
> +	schedule_timeout(2);

We have now API to combine this two functions. There one long name if I
remember.

> +	
> +	if (alsa_codec_config && alsa_codec_config->codec_configure_dev) {
> +		alsa_codec_config->codec_configure_dev();
> +	}

As mentioned earlier...{} not needed, also few more in code below.

> +
> +static int snd_omap_alsa_remove(struct platform_device *pdev)
> +{
> +	snd_card_t *card = platform_get_drvdata(pdev);
> +	struct snd_card_omap_codec *chip = card->private_data;
> +	
> +	snd_card_free(card);
> +
> +	alsa_codec = NULL;
> +	card->private_data = NULL;
> +	kfree(chip);
> +	
> +	platform_set_drvdata(pdev, NULL);
> +	
> +	return 0;
> +	
> +}

Extra empty lines after return 0.

> +
> +static struct platform_driver omap_alsa_driver = {
> +	.probe =	snd_omap_alsa_probe,
> +	.remove =	snd_omap_alsa_remove,
> +	.suspend =	omap_alsa_suspend, 
> +	.resume =	omap_alsa_resume, 

May be keeping consistent naming will be good for suspend and resume.

> +
> +/*
> + * Alsa card structure for aic23
> + */

aic23? 

> +
> +/*
> + * Defines codec specific functions pointers that can be used from
> the 
> + * common omap-alse base driver for all omap codecs. (tsc2101 and
> aic23)
> + */
> +void define_codec_functions(struct omap_alsa_codec_config
> *codec_config);
> +inline void aic23_configure(void);
> +void aic23_set_samplerate(long rate);
> +void aic23_clock_setup(void);
> +int aic23_clock_on(void);
> +int aic23_clock_off(void);
> +int aic23_get_default_samplerate(void);
> +
> +inline void tsc2101_configure(void);
> +void tsc2101_set_samplerate(long rate);
> +void tsc2101_clock_setup(void);
> +int tsc2101_clock_on(void);
> +int tsc2101_clock_off(void);
> +int tsc2101_get_default_samplerate(void);

I think above functions should not be mentioned in omap-alsa.h, as it
meant to be independant of any codec information. You may want to put
them in specific codec header files, anyway they are going to called
through function pointers I believe.


---Komal Shah
http://komalshah.blogspot.com/

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Alsa modularisations and support for tsc2101 1/7
  2006-02-20 22:11 ` Komal Shah
@ 2006-02-21 12:14   ` Daniel Petrini
  2006-02-22 22:16     ` lamikr
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Petrini @ 2006-02-21 12:14 UTC (permalink / raw)
  To: Komal Shah; +Cc: OMAP-Linux

Komal,

Thanks for the comments,

On 2/20/06, Komal Shah <komal_shah802003@yahoo.com> wrote:
> Daniel,
>
> > @@ -0,0 +1,714 @@
> > +/*
> > + * sound/arm/omap-alsa.c
> > + *
> > + * Alsa Driver for AIC23 codec on OSK5912 platform board
>
> Now *not* just for AIC23. Time to update this line.

Sure

> > + *
> > + * History:
> > + *
> > + * 2005-07-29   INdT Kernel Team - Alsa driver for omap osk.
> > Creation of new
> > + *                                 file omap-aic23.c
> > + *
> > + * 2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix
> > as proposed by Ajaya Babu
> > + *
> > + * 2006-02-07   Daniel Petrini  - Codec specific function separated.
> > File renamed to
> > + *                                omap-alsa.c
> > + * 2006-02-10        Mika Laitio     - Codec specific function pointers are set
> > in the codec.
> > + *                             Default samplerate queried from the codec.
> > + */
>
> I am happy to see this big development and cleaned up driver interface,
> but I think we can trim down this History as I believe GIT is being
> really used for this purpose. Only thing we need to take care is give
> better comment at patch submit time :)

Very good suggestion. We will keep in mind to do it from now on.

> > +MODULE_ALIAS("omap_alsa_mcbsp.1");
>
> Do we really need to add "_mcbsp" in that string? It looks confusing
> while reading.

Matter of taste? Isn't better to have all this information?

> > +#define DMA_BUF_SIZE 1024 * 8
> > +
>
> Brackets around 1024 * 8 would be better.

ok.

> > +static int audio_dma_request(struct audio_stream *s,
> > +                          void (*callback) (void *))
> > +{
> > +     int err;
> > +     ADEBUG();
> > +
> > +     err = omap_request_sound_dma(s->dma_dev, s->id, s, &s->lch);
> > +     if (err < 0)
> > +             printk(KERN_ERR "unable to grab audio dma 0x%x\n",
> > +                    s->dma_dev);
>
> s/unable/Unable will look good :)

ok

> > +
> > +/*
> > + *  This function should calculate the current position of the dma
> > in the
> > + *  buffer. It will help alsa middle layer to continue update the
> > buffer.
> > + *  Its correctness is crucial for good functioning.
> > + */
> > +static u_int audio_get_dma_pos(struct audio_stream *s)
> > +{
> > +     snd_pcm_substream_t *substream = s->stream;
> > +     snd_pcm_runtime_t *runtime = substream->runtime;
> > +     unsigned int offset;
> > +     unsigned long flags;
> > +     dma_addr_t count;
> > +     ADEBUG();
> > +
> > +     /* this must be called w/ interrupts locked as requested in dma.c
> > */
> > +     spin_lock_irqsave(&s->dma_lock, flags);
> > +
> > +     /* For the current period let's see where we are */
> > +     count = omap_get_dma_src_addr_counter(s->lch[s->dma_q_head]);
> > +
> > +     spin_unlock_irqrestore(&s->dma_lock, flags);
> > +
> > +     /* Now, the position related to the end of that period */
> > +     offset = bytes_to_frames(runtime, s->offset) -
> > bytes_to_frames(runtime, count);
> > +
> > +     if (offset >= runtime->buffer_size || offset < 0)
> > +             offset = 0;
>
> I am not sure but will this "unsigned int offset" will be ever become <
> 0 here ?

Indeed, offset should not go to below zero but just for the sake that
strange things can happen, we should change its type to int to make
this test properly.

> > +
> > +/*
> > + *  This is called when dma IRQ occurs at the end of each transmited
> > block
> > + */
> > +void audio_dma_callback(void *data)
> > +{
> > +     struct audio_stream *s = data;
> > +     ADEBUG();
> > +
> > +     /*
> > +      * If we are getting a callback for an active stream then we inform
> > +      * the PCM middle layer we've finished a period
> > +      */
> > +     if (s->active)
> > +             snd_pcm_period_elapsed(s->stream);
> > +
> > +     spin_lock(&s->dma_lock);
> > +     if (s->periods > 0) {
> > +             s->periods--;
> > +     }
>
> {} not need around if.

ok, and for the next space, brackets ones too.

>
> > +
> > +/*
> > + * Alsa section
> > + * PCM settings and callbacks
> > + */
> > +
> > +static int snd_omap_alsa_trigger(snd_pcm_substream_t * substream,
> > int cmd)
>
> Extra empty line after function comments. Same review comment applies
> to all other places in the file. You may like to remove that.
>
> > +
> > +static int snd_card_omap_alsa_open(snd_pcm_substream_t * substream)
> > +{
> > +     struct snd_card_omap_codec *chip =
> > +         snd_pcm_substream_chip(substream);
> > +     snd_pcm_runtime_t *runtime = substream->runtime;
> > +     int stream_id = substream->pstr->stream;
> > +     int err;
> > +
> > +     ADEBUG();
> > +     chip->s[stream_id].stream = substream;
> > +     alsa_codec_config->codec_clock_on();
> > +     if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
> > +             runtime->hw = snd_omap_alsa_playback;
> > +     }
>
> {} not needed after if and else below.
>
> > +     else {
> > +             runtime->hw = snd_omap_alsa_capture;
> > +     }
> > +     if ((err = snd_pcm_hw_constraint_integer(runtime,
> > +                                        SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
> > +             return err;
> > +     }
> > +     if ((err = snd_pcm_hw_constraint_list(runtime, 0,
> > +                                     SNDRV_PCM_HW_PARAM_RATE,
> > +                                     &hw_constraints_rates)) < 0) {
> > +             return err;
> > +     }
>
> Ditto. Also adding one empty line between ifs will look better.
>
> > +
> > +     /* sets up initial buffer with continuous allocation */
> > +     snd_pcm_lib_preallocate_pages_for_all(pcm,
> > +                                           SNDRV_DMA_TYPE_CONTINUOUS,
> > +                                           snd_dma_continuous_data
> > +                                           (GFP_KERNEL),
> > +                                           128 * 1024, 128 * 1024);
>
> Brackets around GFP_KERNEL may not be needed.
>
> > +
> > +     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
> > +                     &snd_card_omap_alsa_playback_ops);
> > +     snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
> > +                     &snd_card_omap_alsa_capture_ops);
> > +     pcm->private_data = omap_alsa;
> > +     pcm->info_flags = 0;
> > +     strcpy(pcm->name, "omap aic23 pcm");
>
> aic23?

ok

> > +
> > +
> > +#ifdef CONFIG_PM
> > +
> > +static int snd_omap_alsa_suspend(snd_card_t * card, pm_message_t
> > state)
>
> Empty line after CONFIG_PM may not be needed.
>
> > +
> > +#else
> > +#define snd_omap_alsa_suspend        NULL
> > +#define snd_omap_alsa_resume NULL
> > +#define omap_alsa_suspend    NULL
> > +#define omap_alsa_resume     NULL
> > +
> > +#endif       /* CONFIG_PM */
>
> May be snd_omap_alsa_suspend(x) do {} while(0) style would be better.

Some files looked as models has used this manner. Mainly the PXA ones..

> > +
> > +/*
> > + */
> > +void snd_omap_alsa_free(snd_card_t * card)
> > +{
> > +     struct snd_card_omap_codec *chip = card->private_data;
> > +     ADEBUG();
> > +
> > +     /*
> > +      * Turn off codec after it is done.
> > +      * Can't do it immediately, since it may still have
> > +      * buffered data.
> > +      */
> > +     set_current_state(TASK_INTERRUPTIBLE);
> > +     schedule_timeout(2);
>
> We have now API to combine this two functions. There one long name if I
> remember.

Indeed, you mean schedule_timeout_interruptible . I will change. That 
is one issue of not being in the main line :-(

> > +
> > +     if (alsa_codec_config && alsa_codec_config->codec_configure_dev) {
> > +             alsa_codec_config->codec_configure_dev();
> > +     }
>
> As mentioned earlier...{} not needed, also few more in code below.
>
> > +
> > +static int snd_omap_alsa_remove(struct platform_device *pdev)
> > +{
> > +     snd_card_t *card = platform_get_drvdata(pdev);
> > +     struct snd_card_omap_codec *chip = card->private_data;
> > +
> > +     snd_card_free(card);
> > +
> > +     alsa_codec = NULL;
> > +     card->private_data = NULL;
> > +     kfree(chip);
> > +
> > +     platform_set_drvdata(pdev, NULL);
> > +
> > +     return 0;
> > +
> > +}
>
> Extra empty lines after return 0.
>
> > +
> > +static struct platform_driver omap_alsa_driver = {
> > +     .probe =        snd_omap_alsa_probe,
> > +     .remove =       snd_omap_alsa_remove,
> > +     .suspend =      omap_alsa_suspend,
> > +     .resume =       omap_alsa_resume,
>
> May be keeping consistent naming will be good for suspend and resume.

Allright.

> > +
> > +/*
> > + * Alsa card structure for aic23
> > + */
>
> aic23?
>
> > +
> > +/*
> > + * Defines codec specific functions pointers that can be used from
> > the
> > + * common omap-alse base driver for all omap codecs. (tsc2101 and
> > aic23)
> > + */
> > +void define_codec_functions(struct omap_alsa_codec_config
> > *codec_config);
> > +inline void aic23_configure(void);
> > +void aic23_set_samplerate(long rate);
> > +void aic23_clock_setup(void);
> > +int aic23_clock_on(void);
> > +int aic23_clock_off(void);
> > +int aic23_get_default_samplerate(void);
> > +
> > +inline void tsc2101_configure(void);
> > +void tsc2101_set_samplerate(long rate);
> > +void tsc2101_clock_setup(void);
> > +int tsc2101_clock_on(void);
> > +int tsc2101_clock_off(void);
> > +int tsc2101_get_default_samplerate(void);
>
> I think above functions should not be mentioned in omap-alsa.h, as it
> meant to be independant of any codec information. You may want to put
> them in specific codec header files, anyway they are going to called
> through function pointers I believe.

They are called through function pointers... And actually, this
prototypes can go to specific codec files, their only need is in the
board file.

> ---Komal Shah
> http://komalshah.blogspot.com/

Thanks for that,
Daniel
--
INdT - Manaus - Brazil

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Alsa modularisations and support for tsc2101 1/7
  2006-02-21 12:14   ` Daniel Petrini
@ 2006-02-22 22:16     ` lamikr
  2006-02-23 13:15       ` Komal Shah
  2006-02-24 13:24       ` Komal Shah
  0 siblings, 2 replies; 7+ messages in thread
From: lamikr @ 2006-02-22 22:16 UTC (permalink / raw)
  To: Daniel Petrini; +Cc: OMAP-Linux


>  
>
>>>+ *
>>>+ * History:
>>>+ *
>>>+ * 2005-07-29   INdT Kernel Team - Alsa driver for omap osk.
>>>Creation of new
>>>+ *                                 file omap-aic23.c
>>>+ *
>>>+ * 2005-12-18   Dirk Behme      - Added L/R Channel Interchange fix
>>>as proposed by Ajaya Babu
>>>+ *
>>>+ * 2006-02-07   Daniel Petrini  - Codec specific function separated.
>>>File renamed to
>>>+ *                                omap-alsa.c
>>>+ * 2006-02-10        Mika Laitio     - Codec specific function pointers are set
>>>in the codec.
>>>+ *                             Default samplerate queried from the codec.
>>>+ */
>>>      
>>>
>>I am happy to see this big development and cleaned up driver interface,
>>but I think we can trim down this History as I believe GIT is being
>>really used for this purpose. Only thing we need to take care is give
>>better comment at patch submit time :)
>>    
>>
>
>Very good suggestion. We will keep in mind to do it from now on.
>  
>
Is there somekind of "kernel" policy for this one.
Can we leave the first (2005-07-29) and second one (2005-12-18) from the
history to next patch round or just remove everything?

Mika

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Alsa modularisations and support for tsc2101 1/7
  2006-02-22 22:16     ` lamikr
@ 2006-02-23 13:15       ` Komal Shah
  2006-02-24 13:24       ` Komal Shah
  1 sibling, 0 replies; 7+ messages in thread
From: Komal Shah @ 2006-02-23 13:15 UTC (permalink / raw)
  To: lamikr, Daniel Petrini; +Cc: OMAP-Linux

--- lamikr <lamikr@cc.jyu.fi> wrote:

> Is there somekind of "kernel" policy for this one.
> Can we leave the first (2005-07-29) and second one (2005-12-18) from
> the
> history to next patch round or just remove everything?

AFAIK, There is no such kernel policy for history, but it depends upon
the driver maintainer to accept that History change or not. Maintainer
of subsystem/driver has authority to say NO for that History update.

---Komal Shah
http://komalshah.blogspot.com/

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Alsa modularisations and support for tsc2101 1/7
  2006-02-22 22:16     ` lamikr
  2006-02-23 13:15       ` Komal Shah
@ 2006-02-24 13:24       ` Komal Shah
  2006-02-26 23:06         ` lamikr
  1 sibling, 1 reply; 7+ messages in thread
From: Komal Shah @ 2006-02-24 13:24 UTC (permalink / raw)
  To: lamikr, Daniel Petrini; +Cc: OMAP-Linux

I hope you guys know about this ASoc stuff. 

 More info on: http://www.rpsys.net/openzaurus/patches/alsa/info.html 

If you are going ot FOSDEM then you will be able to discuss with Liam
about ALSA SoC layer.


---Komal Shah
http://komalshah.blogspot.com/

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Alsa modularisations and support for tsc2101 1/7
  2006-02-24 13:24       ` Komal Shah
@ 2006-02-26 23:06         ` lamikr
  0 siblings, 0 replies; 7+ messages in thread
From: lamikr @ 2006-02-26 23:06 UTC (permalink / raw)
  To: Komal Shah; +Cc: OMAP-Linux

Yes, listened the presentation and talked today with Liam about that in
the Fosdem.
He checked the tsc2101 specs I had and according to him it should be
doable also for the tsc2101.
I have however not yet seen the driver code for the chipsets that are
using ASoc technique and
in addition I think that alsa libraries will need some patches to fully
support that.

Mika

Komal Shah wrote:

>I hope you guys know about this ASoc stuff. 
>
> More info on: http://www.rpsys.net/openzaurus/patches/alsa/info.html 
>
>If you are going ot FOSDEM then you will be able to discuss with Liam
>about ALSA SoC layer.
>
>
>---Komal Shah
>http://komalshah.blogspot.com/
>
>__________________________________________________
>Do You Yahoo!?
>Tired of spam?  Yahoo! Mail has the best spam protection around 
>http://mail.yahoo.com 
>
>  
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-02-26 23:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-20 17:44 [PATCH] Alsa modularisations and support for tsc2101 1/7 Daniel Petrini
2006-02-20 22:11 ` Komal Shah
2006-02-21 12:14   ` Daniel Petrini
2006-02-22 22:16     ` lamikr
2006-02-23 13:15       ` Komal Shah
2006-02-24 13:24       ` Komal Shah
2006-02-26 23:06         ` lamikr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox