From de5f4660856350ac43f642bb7c5adf063fc68287 Mon Sep 17 00:00:00 2001
From: Kurt Mahan <kmahan@freescale.com>
Date: Mon, 10 Dec 2007 13:15:33 -0700
Subject: [PATCH] Fix to allow playback at other than 44.1.

LTIBName: m5445x-audio-rates
Signed-off-by: Kurt Mahan <kmahan@freescale.com>
---
 drivers/spi/ssi_audio.c |   34 ++++++++++++++++++++++++----------
 1 files changed, 24 insertions(+), 10 deletions(-)

--- a/drivers/spi/ssi_audio.c
+++ b/drivers/spi/ssi_audio.c
@@ -34,7 +34,6 @@
 #define SOUND_DEVICE_NAME "sound"
 #define DRIVER_NAME "ssi_audio"
 
-
 /* #define AUDIO_DEBUG */
 
 #ifdef CONFIG_MMU
@@ -315,24 +314,36 @@ static inline void disable_ssi(void)
 }
 
 /* Audio CODEC initialization */
-/* TODO: also the SSI frequency/dividers must be adjusted */
 static void adjust_codec_speed(void) {
 #ifdef AUDIO_DEBUG
 	printk(DRIVER_NAME ":adjust_codec_speed: %d\n", audio_device->speed);
 #endif
-
-	if (audio_device->speed == 8000) {
+	disable_ssi();
+	switch (audio_device->speed) {
+	case 8000:
+		MCF_CCM_CDR = MCF_CCM_CDR_SSIDIV(255);
 		codec_write(CODEC_SAMPLE_RATE_REG,CODEC_SAMPLE_8KHZ);
-	} else if (audio_device->speed == 16000) {
+		break;
+	case 16000:
+		MCF_CCM_CDR = MCF_CCM_CDR_SSIDIV(129);
 		codec_write(CODEC_SAMPLE_RATE_REG,CODEC_SAMPLE_16KHZ);
-	} else if (audio_device->speed == 22000) {
+		break;
+	case 22000:
+	case 22050:
+		MCF_CCM_CDR = MCF_CCM_CDR_SSIDIV(94);
 		codec_write(CODEC_SAMPLE_RATE_REG,CODEC_SAMPLE_22KHZ);
-	} else if (audio_device->speed == 44000 || audio_device->speed == 44100) {
+		break;
+	case 44000:
+	case 44100:
+		MCF_CCM_CDR = MCF_CCM_CDR_SSIDIV(47);
 		codec_write(CODEC_SAMPLE_RATE_REG,CODEC_SAMPLE_44KHZ);
-	} else if (audio_device->speed == 48000) {
+		break;
+	case 48000:
+		MCF_CCM_CDR = MCF_CCM_CDR_SSIDIV(42);
 		codec_write(CODEC_SAMPLE_RATE_REG,CODEC_SAMPLE_48KHZ);
-	} else {
-		/* default 44KHz */
+		break;
+	default:
+		MCF_CCM_CDR = MCF_CCM_CDR_SSIDIV(47);
 		codec_write(CODEC_SAMPLE_RATE_REG,CODEC_SAMPLE_44KHZ);
 	}
 }
@@ -712,6 +723,9 @@ static int ssi_audio_ioctl(struct inode 
 	case SNDCTL_DSP_SAMPLESIZE:
 		if (access_ok(VERIFY_READ, (void *) arg, sizeof(val))) {
 			get_user(val, (unsigned long *) arg);
+#ifdef AUDIO_DEBUG
+			printk(DRIVER_NAME ":ssi_audio_ioctl: SNDCTL_DSP_SAMPLESIZE: %d\n", val);
+#endif
 			ssi_audio_txdrain();
 			ssi_audio_setsamplesize(val);
 		} else {
