[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