[commit] r2406 - in trunk/linux-2.6.x: arch/arm/mach-nds arch/arm/mach-nds/arm7 include/asm-arm/arch-nds sound/arm

dslinux_sonny_jim at dslinux.in-berlin.de dslinux_sonny_jim at dslinux.in-berlin.de
Sat Dec 20 13:32:04 CET 2008


Author: dslinux_sonny_jim
Date: Sat Dec 20 13:32:03 2008
New Revision: 2406

Log:
Add updated microphone patch from sjoemac

Modified:
   trunk/linux-2.6.x/arch/arm/mach-nds/arm7/main.c
   trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.c
   trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.h
   trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.c
   trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.h
   trunk/linux-2.6.x/arch/arm/mach-nds/fifo.c
   trunk/linux-2.6.x/include/asm-arm/arch-nds/fifo.h
   trunk/linux-2.6.x/sound/arm/nds-sound.c

Modified: trunk/linux-2.6.x/arch/arm/mach-nds/arm7/main.c
==============================================================================
--- trunk/linux-2.6.x/arch/arm/mach-nds/arm7/main.c	(original)
+++ trunk/linux-2.6.x/arch/arm/mach-nds/arm7/main.c	Sat Dec 20 13:32:03 2008
@@ -89,6 +89,9 @@
 			break;
 		case FIFO_MIC:
 			switch (FIFO_MIC_CMD(data)) {
+			case FIFO_MIC_FORMAT:
+				mic_set_format(FIFO_MIC_DATA(data));
+				break;
 			case FIFO_MIC_POWER:
 				if (data & 0x1) 
 					mic_on(); 
@@ -100,6 +103,9 @@
 			case FIFO_MIC_DMA_SIZE:
 				mic_set_size(FIFO_MIC_DATA(data));
 				break;
+			case FIFO_MIC_PERIOD_SIZE:
+				mic_set_period_size(FIFO_MIC_DATA(data));
+				break;
 			case FIFO_MIC_RATE:
 				mic_set_rate(FIFO_MIC_DATA(data));
 				break;

Modified: trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.c
==============================================================================
--- trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.c	(original)
+++ trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.c	Sat Dec 20 13:32:03 2008
@@ -3,21 +3,25 @@
 #include "spi.h"
 #include "microphone.h"
 #include "arm7.h"
+#include "asm/arch/fifo.h"
 
 //same as SOUND_FREQ(n)
 #define MIC_FREQ(n)		(0 - (0x1000000 / (n)))
 
-static u8 *mic_buffer  = 0;  //pointer to the buffer 
+static u8 *mic_buffer8  = 0;  //pointer to the buffer (8-bit) 
+static u16 *mic_buffer16 = 0; //pointer to the buffer (16-bit)
 static u32 buffer_size = 0;  //size of the buffer
 static u32 current_ptr = 0;  //current pointer in the buffer
 static u32 mic_rate = 0;  //sample rate.
+static u8 mic_format = 0;
+static u32 period_size = 0; //number of bytes to read before signaling arm9
 
 /********************
  *mic_on()
  ********************/
 void mic_on()
 {
-	mic_on_off(1);
+	mic_on_off(1); // or power_write(POWER_MIC_CONTROL, 1);
 }
 
 /********************
@@ -25,7 +29,23 @@
  ********************/
 void mic_off()
 {
-	mic_on_off(0);
+	mic_on_off(0); // or power_write(POWER_MIC_CONTROL, 0);
+}
+
+/********************
+ *mic_set_power()
+ ********************/
+void mic_set_power(u8 power) {
+	if (power == 0) 
+	{
+		mic_off();
+		power_write(POWER_MIC_GAIN, 0);
+	}
+	else 
+	{
+		mic_on();
+		power_write(POWER_MIC_GAIN, power - 1);
+	}
 }
 
 /********************
@@ -33,7 +53,8 @@
  ********************/
 void mic_set_address(u32 buffer)
 {
-	mic_buffer = (u8*)buffer;
+	mic_buffer8 = (u8*)buffer;
+	mic_buffer16 = (u16*)buffer;
 }
 
 /********************
@@ -53,6 +74,22 @@
 }
 
 /********************
+ *mic_set_format()
+ ********************/
+void mic_set_format(u8 format) 
+{
+	mic_format = format;
+}
+
+/********************
+ *mic_set_period_size()
+ ********************/
+void mic_set_period_size(u32 size)
+{
+	period_size = size;
+}
+
+/********************
  *mic_start()
  ********************/
 void mic_start()
@@ -73,7 +110,8 @@
 	REG_TM3CNT_H &= ~NDS_TCR_ENB;
 	//disable the timer irq.
 	NDS_IE &= ~IRQ_TIMER3;
-	mic_buffer = 0;
+	mic_buffer8 = 0;
+	mic_buffer16 = 0;
 	return current_ptr;
 }
 
@@ -82,8 +120,33 @@
  ********************/
 void mic_timer_handler(void)
 {
-	mic_buffer[current_ptr] = mic_read8() /*^ 0x80*/;
-	current_ptr++; 
+	if (mic_format & MIC_FORMAT_8BIT)
+	{
+		if (mic_buffer8) 
+		{
+			mic_buffer8[current_ptr] = mic_read8();
+			if (mic_format & MIC_FORMAT_SIGNED)
+				mic_buffer8[current_ptr] = mic_buffer8[current_ptr] ^ 0x80;
+			current_ptr++;
+		}
+	}
+	else 
+	{
+		if (mic_buffer16)
+		{
+			mic_buffer16[current_ptr/2] = mic_read12();
+			if (mic_format & MIC_FORMAT_SIGNED)
+				mic_buffer16[current_ptr/2] = (mic_buffer16[current_ptr/2] - 2048) << 4;
+			current_ptr+=2;
+		}
+	}
+	if ((period_size > 0) && (current_ptr % period_size == 0))
+	{
+		if (mic_format & MIC_FORMAT_8BIT)
+			nds_fifo_send(FIFO_MIC | FIFO_MIC_HAVEDATA /*| mic_buffer8[current_ptr]*/);
+		else
+			nds_fifo_send(FIFO_MIC | FIFO_MIC_HAVEDATA /*| mic_buffer16[current_ptr/2]*/);
+	}
 	if (current_ptr >= buffer_size)
 	{
 		//buffer wraps around.

Modified: trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.h
==============================================================================
--- trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.h	(original)
+++ trunk/linux-2.6.x/arch/arm/mach-nds/arm7/microphone.h	Sat Dec 20 13:32:03 2008
@@ -4,12 +4,21 @@
 /* Turn the microphone off */
 void mic_off(void);
 
+/* Set the mic power */
+void mic_set_power(u8 power);
+
 /* set the buffer for data to go. */
 void mic_set_address(u32 buffer);
 
 /* set the buffer size */
 void mic_set_size(u32 size);
 
+/* set the data format */
+void mic_set_format(u8 format);
+
+/* set the period size */
+void mic_set_period_size(u32 size);
+
 /* Set the sample rate */
 void mic_set_rate(u32 rate);
 

Modified: trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.c
==============================================================================
--- trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.c	(original)
+++ trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.c	Sat Dec 20 13:32:03 2008
@@ -18,7 +18,7 @@
 #define SPI_POWER	(0<<8)
 #define SPI_FIRMWARE	(1<<8)
 #define SPI_TOUCH	(2<<8)
-#define SPI_MIC	(2<<8) // TODO Check
+#define SPI_MIC	(2<<8)
 #define SPI_8CLOCKS	(0<<10)
 #define SPI_16CLOCKS	(1<<10)
 #define SPI_SINGLE	(0<<11)
@@ -193,7 +193,7 @@
 	WAIT_FOR_NOT_BUSY();
 
 	result = REG_SPI_DATA;
-	REG_SPI_CR = SPI_ENABLE | SPI_TOUCH | SPI_2MHZ;
+	REG_SPI_CR = SPI_ENABLE | SPI_MIC | SPI_2MHZ;
 	REG_SPI_DATA = 0x00;
 
 	WAIT_FOR_NOT_BUSY();
@@ -203,3 +203,36 @@
 	return (((result & 0x7F) << 1) | ((result2>>7)&1));
 
 }
+
+
+/*
+ * mic_read12() : Read a short from the microphone. 
+ * Code based on neimod's example.
+ */
+u16 mic_read12() {
+
+	static u16 result, result2;
+
+	WAIT_FOR_NOT_BUSY();
+
+	REG_SPI_CR = SPI_ENABLE | SPI_MIC | SPI_2MHZ | SPI_CONTINUOUS;
+	
+	REG_SPI_DATA = 0xE4;  // Touchscreen command format for AUX, 12bit
+
+	WAIT_FOR_NOT_BUSY();
+
+	REG_SPI_DATA = 0x00;
+
+	WAIT_FOR_NOT_BUSY();
+
+	result = REG_SPI_DATA;
+	REG_SPI_CR = SPI_ENABLE | SPI_TOUCH | SPI_2MHZ;
+	REG_SPI_DATA = 0x00;
+
+	WAIT_FOR_NOT_BUSY();
+
+	result2 = REG_SPI_DATA;
+
+	return (((result & 0x7F) << 5) | ((result2>>3)&0x1F));
+}
+

Modified: trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.h
==============================================================================
--- trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.h	(original)
+++ trunk/linux-2.6.x/arch/arm/mach-nds/arm7/spi.h	Sat Dec 20 13:32:03 2008
@@ -24,5 +24,7 @@
 
 void mic_on_off(u8 control);
 u8 mic_read8(void);
+u16 mic_read12(void);
+
 
 #endif

Modified: trunk/linux-2.6.x/arch/arm/mach-nds/fifo.c
==============================================================================
--- trunk/linux-2.6.x/arch/arm/mach-nds/fifo.c	(original)
+++ trunk/linux-2.6.x/arch/arm/mach-nds/fifo.c	Sat Dec 20 13:32:03 2008
@@ -62,6 +62,9 @@
 					    FIFO_WIFI_GET_CMD(data),
 					    FIFO_WIFI_GET_DATA(data));
 					break;
+				case FIFO_MIC:
+					cb -> handler.mic_handler();
+					break;
 				default:
 					break;
 				}

Modified: trunk/linux-2.6.x/include/asm-arm/arch-nds/fifo.h
==============================================================================
--- trunk/linux-2.6.x/include/asm-arm/arch-nds/fifo.h	(original)
+++ trunk/linux-2.6.x/include/asm-arm/arch-nds/fifo.h	Sat Dec 20 13:32:03 2008
@@ -119,12 +119,29 @@
 #define FIFO_MIC_DATA(d)	(d & 0x00ffffff)
 #define FIFO_MIC_DMA(d)	(FIFO_MIC_DATA(d) + 0x02000000)
 
+/* MIC arm9 => arm7 commands */
+#define FIFO_MIC_PERIOD_SIZE (1<<24)
 #define FIFO_MIC_DMA_ADDRESS	(2<<24) //FIFO_DMA_ADDRESS
 #define FIFO_MIC_DMA_SIZE	(3<<24) //FIFO_DMA_SIZE
+#define FIFO_MIC_FORMAT	(4<<24) //FIFO_SOUND_FORMAT
 #define FIFO_MIC_RATE	(5<<24) //FIFO_SOUND_RATE
 #define FIFO_MIC_TRIGGER	(6<<24) //FIFO_SOUND_TRIGGER
 #define FIFO_MIC_POWER	(7<<24) //FIFO_SOUND_POWER
 
+/* MIC arm7 => arm9 messages */
+#define FIFO_MIC_HAVEDATA	(1<<24)
+
+/* MIC FORMAT defines */
+#define MIC_FORMAT_8BIT	1
+#define MIC_FORMAT_16BIT	0
+#define MIC_FORMAT_SIGNED	2
+#define MIC_FORMAT_UNSIGNED	0
+
+#define MIC_FORMAT_U8	MIC_FORMAT_8BIT  | MIC_FORMAT_UNSIGNED
+#define MIC_FORMAT_S8	MIC_FORMAT_8BIT  | MIC_FORMAT_SIGNED
+#define MIC_FORMAT_U16	MIC_FORMAT_16BIT | MIC_FORMAT_UNSIGNED
+#define MIC_FORMAT_S16	MIC_FORMAT_16BIT | MIC_FORMAT_SIGNED
+
 /* FIFO registers */
 #define NDS_REG_IPCFIFOSEND (*(volatile u32*) 0x04000188)
 #define NDS_REG_IPCFIFORECV (*(volatile u32*) 0x04100000)
@@ -149,6 +166,7 @@
 		void (*touch_handler)(u8 pressed, u8 x, u8 y);
 		void (*time_handler)(u32 seconds);
 		void (*wifi_handler)(u8 cmd, u32 data);
+		void (*mic_handler)(void); 
 		/* ... */
 	} handler;
 };

Modified: trunk/linux-2.6.x/sound/arm/nds-sound.c
==============================================================================
--- trunk/linux-2.6.x/sound/arm/nds-sound.c	(original)
+++ trunk/linux-2.6.x/sound/arm/nds-sound.c	Sat Dec 20 13:32:03 2008
@@ -26,7 +26,7 @@
 #define TIMER_CASCADE	(TIMER_ENABLE|(1<<2))
 
 #define DMA_BUFFERSIZE	(128*1024)
-#define DMA_BUFFERSIZE_CAPTURE (32768)
+#define DMA_BUFFERSIZE_CAPTURE (64*1024)
 
 /* module parameters (see "Module Parameters") */
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -77,19 +77,26 @@
 	.info = (SNDRV_PCM_INFO_MMAP |
 		 SNDRV_PCM_INFO_NONINTERLEAVED |
 		 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
-	.formats = SNDRV_PCM_FMTBIT_U8 /*| SNDRV_PCM_FMTBIT_U16_LE*/,
+	.formats =  SNDRV_PCM_FMTBIT_U8 | 
+				SNDRV_PCM_FMTBIT_S8 | 
+				SNDRV_PCM_FMTBIT_U16_LE |
+				SNDRV_PCM_FMTBIT_S16_LE,
 	.rates = SNDRV_PCM_RATE_8000_48000,
 	.rate_min = 8000,
 	.rate_max = 48000,
 	.channels_min = 1,
 	.channels_max = 1,
-	.buffer_bytes_max = 32768,
-	.period_bytes_min = 512,
-	.period_bytes_max = 4096,
+	.buffer_bytes_max = DMA_BUFFERSIZE_CAPTURE,
+	.period_bytes_min = DMA_BUFFERSIZE_CAPTURE/16,
+	.period_bytes_max = DMA_BUFFERSIZE_CAPTURE/8,
 	.periods_min = 1,
 	.periods_max = 1024,
 };
 
+static struct nds *capture_chip;  //Global reference for capture to deal with the FIFO signals.
+
+
+
 /* Set the sample format */
 void nds_playback_set_sample_format(struct nds *chip, snd_pcm_format_t format)
 {
@@ -108,6 +115,27 @@
 	}
 }
 
+void nds_capture_set_sample_format(struct nds *chip, snd_pcm_format_t format)
+{
+	switch (format)
+	{
+		case SNDRV_PCM_FORMAT_U8:
+			nds_fifo_send(FIFO_MIC | FIFO_MIC_FORMAT | MIC_FORMAT_U8);
+			break;
+		case SNDRV_PCM_FORMAT_S8:
+			nds_fifo_send(FIFO_MIC | FIFO_MIC_FORMAT | MIC_FORMAT_S8);
+			break;
+		case SNDRV_PCM_FORMAT_U16_LE:
+			nds_fifo_send(FIFO_MIC | FIFO_MIC_FORMAT | MIC_FORMAT_U16);
+			break;
+		case SNDRV_PCM_FORMAT_S16_LE:
+			nds_fifo_send(FIFO_MIC | FIFO_MIC_FORMAT | MIC_FORMAT_S16);
+			break;
+		default:
+			snd_printk("nds_capture_set_sample_format(): Unrecognized Format: %d\n", format);
+	}
+}
+
 /* Set the sample rate */
 void nds_playback_set_sample_rate(struct nds *chip, unsigned int rate)
 {
@@ -140,6 +168,7 @@
 	nds_fifo_send(FIFO_MIC | FIFO_MIC_DMA_SIZE | buffer_size);
 	nds_fifo_send(FIFO_MIC | FIFO_MIC_DMA_ADDRESS |
 		(((u32) dma_area) & 0xffffff));
+	nds_fifo_send(FIFO_MIC | FIFO_MIC_PERIOD_SIZE | period_size);
 }
 
 /* open callback */
@@ -195,12 +224,10 @@
 /* close callback */
 static int snd_nds_capture_close(snd_pcm_substream_t * substream) 
 {
-	// turn off the power to the mic and clear the timer.
+	// turn off the power to the mic.
 	nds_fifo_send(FIFO_MIC | FIFO_MIC_POWER | 0);
-	
-	TIMER1_CR=0;
-	TIMER2_CR=0;
-  return 0;
+	capture_chip = NULL;
+	return 0;
 }
 
 /* hw_params callback */
@@ -258,65 +285,42 @@
 	return 0;
 }
 
+/****************************************
+ *snd_nds_capture_prepare:
+ ****************************************/
 static int snd_nds_capture_prepare(snd_pcm_substream_t * substream)
 {
 	struct nds *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	/* set up the hardware with the current configuration
-	 * for example...
-	 */
 
 	chip->buffer_size = snd_pcm_lib_buffer_bytes(substream);
 	chip->period_size = snd_pcm_lib_period_bytes(substream);
 
-	TIMER1_CR = 0;
-	TIMER2_CR = 0;
-	/* use exactly the same formula as for ARM7, to get the
-	   same period regarding rounding errors */
-	TIMER1_DATA = 0 - ((0x1000000 / runtime->rate)*2);
-
-	TIMER2_DATA = 0 - (chip -> period_size / runtime -> channels);
-
-	switch (runtime->format) {
-	case SNDRV_PCM_FORMAT_U8:
-	case SNDRV_PCM_FORMAT_S8:
-	case SNDRV_PCM_FORMAT_S16_LE:
-	case SNDRV_PCM_FORMAT_IMA_ADPCM:
-	  break;
-	default:
-	  printk("Error format is not handled?%d\n",runtime -> format);
-		break;
-	}
-
-	//nds_playback_set_channels(chip, runtime->channels);
-	//nds_playback_set_sample_format(chip, runtime->format);
+	nds_capture_set_sample_format(chip, runtime->format);
 	nds_capture_set_sample_rate(chip, runtime->rate);
 	nds_capture_set_dma_setup(chip, capturebuf,
 				   chip->buffer_size, chip->period_size);
 	chip->period = 0;
 
+	//pointer to the chip so we can log the period that are finished by the arm7.
+	capture_chip = chip;
 	return 0;
+}
 
 
-}
-/* trigger callback */
-static int snd_nds_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
+
+/****************************************
+ *snd_nds_playback_trigger()
+ ****************************************/
+static int snd_nds_playback_trigger(snd_pcm_substream_t * substream, int cmd)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	int target;
-	if (substream -> stream == SNDRV_PCM_STREAM_CAPTURE)
-	{
-		target = FIFO_MIC;
-	}
-	else 
-	{
-		target = FIFO_SOUND;
-	}
 
-	switch (cmd) {
+	switch (cmd) 
+	{
 	case SNDRV_PCM_TRIGGER_START:
 		// start the PCM engine
-		nds_fifo_send(target | FIFO_SOUND_TRIGGER | 1);
+		nds_fifo_send(FIFO_SOUND | FIFO_SOUND_TRIGGER | 1);
 
 		/* wait until we know for shure that the ARM7 has 
 		   started the sound output */
@@ -329,13 +333,13 @@
 			;
 
 		/* now we can start the timer and be shure that
-                   the timer interrupt is not comming to early. */
+	       the timer interrupt is not comming to early. */
 		TIMER1_CR = TIMER_ENABLE;
 		TIMER2_CR = TIMER_CASCADE | TIMER_IRQ_REQ;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		// stop the PCM engine
-		nds_fifo_send(target | FIFO_SOUND_TRIGGER | 0);
+		nds_fifo_send(FIFO_SOUND | FIFO_SOUND_TRIGGER | 0);
 		TIMER1_CR = 0;
 		TIMER2_CR = 0;
 		break;
@@ -345,6 +349,29 @@
 	return 0;
 }
 
+/*************************************
+ *snd_nds_capture_trigger()
+ *************************************/
+static int snd_nds_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+{
+
+	switch (cmd) 
+	{
+	case SNDRV_PCM_TRIGGER_START:
+		// start the PCM engine
+		nds_fifo_send(FIFO_MIC | FIFO_MIC_TRIGGER | 1);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		// stop the PCM engine
+		nds_fifo_send(FIFO_MIC | FIFO_MIC_TRIGGER | 0);
+		capture_chip = NULL;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 /* pointer callback */
 static snd_pcm_uframes_t snd_nds_pcm_pointer(snd_pcm_substream_t * substream)
 {
@@ -355,15 +382,33 @@
 	return chip->period * runtime->period_size;
 }
 
-static int capture_copy(snd_pcm_substream_t *substream, int channel,
+/*******************************
+ *snd_nds_capture_copy()
+ *******************************/
+static int snd_nds_capture_copy(snd_pcm_substream_t *substream, int channel,
 			snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count)
 {
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	char *cdst = (char*)dst;
+	int cpos;
+	int ccount;
 	int i;
-	char* cdst = (char*)dst;
-	for (i=0;i<count;i++)
+	switch (runtime -> format) 
 	{
-		cdst[i] = capturebuf[pos+i];
+	default:
+	case SNDRV_PCM_FORMAT_U8:
+	case SNDRV_PCM_FORMAT_S8:
+		cpos = pos;
+		ccount = count;
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+	case SNDRV_PCM_FORMAT_U16_LE:
+		cpos = pos * 2;
+		ccount = count * 2;
+		break;
 	}
+	memcpy(dst, &capturebuf[cpos], ccount);
+
 	return 0;
 }
 
@@ -375,7 +420,7 @@
 	.hw_params = snd_nds_pcm_hw_params,
 	.hw_free = snd_nds_pcm_hw_free,
 	.prepare = snd_nds_playback_prepare,
-	.trigger = snd_nds_pcm_trigger,
+	.trigger = snd_nds_playback_trigger,
 	.pointer = snd_nds_pcm_pointer,
 };
 
@@ -387,14 +432,12 @@
 	.hw_params = snd_nds_pcm_hw_params,
 	.hw_free = snd_nds_pcm_hw_free,
 	.prepare = snd_nds_capture_prepare,
-	.trigger = snd_nds_pcm_trigger,
+	.trigger = snd_nds_capture_trigger,
 	.pointer = snd_nds_pcm_pointer,
-	.copy = capture_copy,
+	.copy = snd_nds_capture_copy,
 };
 
-/*
- * definitions of capture are omitted here...
- */
+
 /* create a pcm device */
 static int __devinit snd_nds_new_pcm(struct nds *chip)
 {
@@ -435,6 +478,42 @@
 	return 0;
 }
 
+/*************************************
+ *nds_mic_handler(): Handles the HAVE_DATA signals from the arm7 when recording microphone data.
+ *************************************/
+static void nds_mic_handler(void) 
+{
+	struct nds *chip = capture_chip;
+	snd_pcm_substream_t *substream;
+	snd_pcm_runtime_t *runtime;
+	u8 period;
+	if (chip)
+	{
+		substream = chip->substream;
+		runtime = substream->runtime;
+
+		spin_lock(&chip->lock);
+
+		period = chip->period + 1;
+		if (period == runtime->periods)
+			period = 0;
+		chip->period = period;
+
+		spin_unlock(&chip->lock);
+
+		/* call updater, unlock before it */
+		snd_pcm_period_elapsed(chip->substream);
+	}
+}
+
+static struct fifo_cb nds_mic_fifocb = {
+	.type = FIFO_MIC,
+	.handler.mic_handler = nds_mic_handler
+};
+
+/*****************************************
+ *snd_nds_interrupt() : Handles the interrupt from the timer for sound
+ *****************************************/
 static irqreturn_t snd_nds_interrupt(int irq, void *dev_id,
 				     struct pt_regs *regs)
 {
@@ -501,7 +580,7 @@
 	chip->card = card;
 	spin_lock_init(&chip->lock);
 
-	// TODO: register with FIFO or IPC here
+	register_fifocb(&nds_mic_fifocb);
 
 	if (request_irq(IRQ_TC2, snd_nds_interrupt,
 			SA_INTERRUPT, "NDS sound", chip)) {
@@ -519,6 +598,7 @@
 	return 0;
 }
 
+
 /* constructor -- see "Constructor" sub-section */
 static int __init snd_nds_init(void)
 {
@@ -570,6 +650,7 @@
 static void __exit snd_nds_exit(void)
 {
 	//snd_card_free(nds_sound->card);
+	unregister_fifocb(&nds_mic_fifocb);
 }
 
 module_init(snd_nds_init);


More information about the dslinux-commit mailing list