[kernel] r14124 - in dists/trunk/linux-2.6/debian: . patches/features/all patches/series

Ben Hutchings benh at alioth.debian.org
Sun Aug 16 23:40:35 UTC 2009


Author: benh
Date: Sun Aug 16 23:40:34 2009
New Revision: 14124

Log:
snd-cs46xx: reenable using external firmware (closes: #464197)

Added:
   dists/trunk/linux-2.6/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/base

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Sun Aug 16 19:52:12 2009	(r14123)
+++ dists/trunk/linux-2.6/debian/changelog	Sun Aug 16 23:40:34 2009	(r14124)
@@ -45,6 +45,8 @@
   * cxgb3: remove PHY firmware and use request_firmware() to load it
   * Add firmware-linux-free package containing DFSG-free firmware
   * av7110: include firmware source and binary
+  * snd-cs46xx: reenable using external firmware (closes: #464197,
+    but note that Debian cannot currently distribute the firmware)
 
   [ Martin Michlmayr ]
   * [armel/orion5x, armel/kirkwood] Set GPIO_SYSFS=y since these

Added: dists/trunk/linux-2.6/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/features/all/sound-pci-cs46xx-request_firmware.patch	Sun Aug 16 23:40:34 2009	(r14124)
@@ -0,0 +1,169 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+
+Tested by Antonio Ospite <ospite at studenti.unina.it>.
+Unfortunately we cannot currently distribute the firmware.
+
+diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
+index 17e03b9..124b3a0 100644
+--- a/sound/pci/Kconfig
++++ b/sound/pci/Kconfig
+@@ -229,7 +229,7 @@ config SND_CS4281
+ 
+ config SND_CS46XX
+ 	tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
+-	depends on BROKEN
++	select FW_LOADER
+ 	select SND_RAWMIDI
+ 	select SND_AC97_CODEC
+ 	help
+@@ -241,6 +241,7 @@ config SND_CS46XX
+ 
+ config SND_CS46XX_NEW_DSP
+ 	bool "Cirrus Logic (Sound Fusion) New DSP support"
++	depends on BROKEN
+ 	depends on SND_CS46XX
+ 	default y
+ 	help
+diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
+index 1be96ea..b12b930 100644
+--- a/sound/pci/cs46xx/cs46xx_lib.c
++++ b/sound/pci/cs46xx/cs46xx_lib.c
+@@ -53,6 +53,7 @@
+ #include <linux/slab.h>
+ #include <linux/gameport.h>
+ #include <linux/mutex.h>
++#include <linux/firmware.h>
+ 
+ 
+ #include <sound/core.h>
+@@ -308,7 +309,7 @@ static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
+  */
+ 
+ int snd_cs46xx_download(struct snd_cs46xx *chip,
+-			u32 *src,
++			const __le32 *src,
+                         unsigned long offset,
+                         unsigned long len)
+ {
+@@ -321,9 +322,9 @@ int snd_cs46xx_download(struct snd_cs46xx *chip,
+ 	dst = chip->region.idx[bank+1].remap_addr + offset;
+ 	len /= sizeof(u32);
+ 
+-	/* writel already converts 32-bit value to right endianess */
+ 	while (len-- > 0) {
+-		writel(*src++, dst);
++		__raw_writel((__force u32)*src++, dst);
++		mmiowb();
+ 		dst += sizeof(u32);
+ 	}
+ 	return 0;
+@@ -360,23 +361,77 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
+ 
+ #else /* old DSP image */
+ 
+-#include "cs46xx_image.h"
++struct cs46xx_old_image {
++	__le32 size[BA1_MEMORY_COUNT];
++	__le32 data[0];
++};
+ 
+-int snd_cs46xx_download_image(struct snd_cs46xx *chip)
++static int snd_cs46xx_check_image_size(const struct firmware *firmware)
+ {
+-	int idx, err;
+-	unsigned long offset = 0;
++	const struct cs46xx_old_image *image =
++		(const struct cs46xx_old_image *)firmware->data;
++	size_t offset = sizeof(*image);
++	int idx;
++
++	if (firmware->size < offset) {
++		snd_printk(KERN_ERR "cs46xx: firmware too small\n");
++		return -EINVAL;
++	}
+ 
+ 	for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
+-		if ((err = snd_cs46xx_download(chip,
+-					       &BA1Struct.map[offset],
+-					       BA1Struct.memory[idx].offset,
+-					       BA1Struct.memory[idx].size)) < 0)
+-			return err;
+-		offset += BA1Struct.memory[idx].size >> 2;
+-	}	
++		size_t size = le32_to_cpu(image->size[idx]);
++
++		if (size % sizeof(u32)) {
++			snd_printk(KERN_ERR "cs46xx: firmware hunk misaligned\n");
++			return -EINVAL;
++		}
++		if (size > BA1_DWORD_SIZE * sizeof(u32)) {
++			snd_printk(KERN_ERR "cs46xx: firmware hunk out of range\n");
++			return -EINVAL;
++		}
++		offset += size;
++	}
++
++	if (firmware->size != offset) {
++		snd_printk(KERN_ERR "cs46xx: firmware size mismatch\n");
++		return -EINVAL;
++	}
++
+ 	return 0;
+ }
++
++static int snd_cs46xx_download_image(struct snd_cs46xx *chip)
++{
++	int idx, err;
++	const struct firmware *firmware = NULL;
++	const struct cs46xx_old_image *image;
++	const __le32 *data;
++
++	err = request_firmware(&firmware, "cs46xx/cs46xx-old.fw",
++			       &chip->pci->dev);
++	if (err < 0) {
++		snd_printk(KERN_ERR "cs46xx: no firmware\n");
++		return err;
++	}
++
++	err = snd_cs46xx_check_image_size(firmware);
++	if (err < 0)
++		goto end;
++	image = (const struct cs46xx_old_image *)firmware->data;
++	data = image->data;
++
++	for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
++		size_t size = le32_to_cpu(image->size[idx]);
++
++		err = snd_cs46xx_download(chip, data, idx << 16, size);
++		if (err < 0)
++			goto end;
++		data += size / sizeof(u32);
++	}
++end:
++	release_firmware(firmware);
++	return err;
++}
+ #endif /* CONFIG_SND_CS46XX_NEW_DSP */
+ 
+ /*
+@@ -3874,3 +3929,5 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
+ 	*rchip = chip;
+ 	return 0;
+ }
++
++MODULE_FIRMWARE("cs46xx/cs46xx-old.fw");
+diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
+index 4eb55aa..85babb5 100644
+--- a/sound/pci/cs46xx/cs46xx_lib.h
++++ b/sound/pci/cs46xx/cs46xx_lib.h
+@@ -103,8 +103,8 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip);
+ #define cs46xx_dsp_proc_done(chip)
+ #endif
+ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip);
+-int snd_cs46xx_download (struct snd_cs46xx *chip, u32 *src, unsigned long offset,
+-			 unsigned long len);
++int snd_cs46xx_download(struct snd_cs46xx *chip, const __le32 *src, unsigned long offset,
++			unsigned long len);
+ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, unsigned long offset, unsigned long len);
+ int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip);
+ int cs46xx_dsp_enable_spdif_hw (struct snd_cs46xx *chip);

Modified: dists/trunk/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/base	Sun Aug 16 19:52:12 2009	(r14123)
+++ dists/trunk/linux-2.6/debian/patches/series/base	Sun Aug 16 23:40:34 2009	(r14124)
@@ -14,6 +14,7 @@
 + features/all/lib-crcitut-bit-reversed.patch
 + features/all/drivers-staging-rt28x0sta-request_firmware.patch
 + features/all/export-unionfs-symbols.patch
++ features/all/sound-pci-cs46xx-request_firmware.patch
 
 + bugfix/sparc/drivers_net-broken.patch
 #+ bugfix/ia64/hardcode-arch-script-output.patch



More information about the Kernel-svn-changes mailing list