aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/maestro3.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2006-11-06 03:26:41 -0500
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:01:18 -0500
commit81d7724a8ee84693befbd60d730199ffb3988f29 (patch)
tree0fdaad0f2427729ffbe088ff78979aa8aa65a59f /sound/pci/maestro3.c
parent2493a6d18b1f5df59c7bcfeefcbde70bee146490 (diff)
[ALSA] maestro3: add request_firmware()
Load the ASSP codes using request_firmware(), if possible, instead of using the built-in blobs. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/maestro3.c')
-rw-r--r--sound/pci/maestro3.c79
1 files changed, 73 insertions, 6 deletions
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 6efe6d5ade1e..053ea4fdbffd 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,6 +41,7 @@
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
43#include <linux/moduleparam.h> 43#include <linux/moduleparam.h>
44#include <linux/firmware.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/info.h> 46#include <sound/info.h>
46#include <sound/control.h> 47#include <sound/control.h>
@@ -48,6 +49,7 @@
48#include <sound/mpu401.h> 49#include <sound/mpu401.h>
49#include <sound/ac97_codec.h> 50#include <sound/ac97_codec.h>
50#include <sound/initval.h> 51#include <sound/initval.h>
52#include <asm/byteorder.h>
51 53
52MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>"); 54MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>");
53MODULE_DESCRIPTION("ESS Maestro3 PCI"); 55MODULE_DESCRIPTION("ESS Maestro3 PCI");
@@ -864,6 +866,9 @@ struct snd_m3 {
864#ifdef CONFIG_PM 866#ifdef CONFIG_PM
865 u16 *suspend_mem; 867 u16 *suspend_mem;
866#endif 868#endif
869
870 const struct firmware *assp_kernel_image;
871 const struct firmware *assp_minisrc_image;
867}; 872};
868 873
869/* 874/*
@@ -2132,6 +2137,10 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2132} 2137}
2133 2138
2134 2139
2140#define FIRMWARE_IN_THE_KERNEL
2141
2142#ifdef FIRMWARE_IN_THE_KERNEL
2143
2135/* 2144/*
2136 * DSP Code images 2145 * DSP Code images
2137 */ 2146 */
@@ -2260,6 +2269,30 @@ static const u16 assp_minisrc_image[] = {
2260 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2269 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2261}; 2270};
2262 2271
2272static const struct firmware assp_kernel = {
2273 .data = (u8 *)assp_kernel_image,
2274 .size = sizeof assp_kernel_image
2275};
2276static const struct firmware assp_minisrc = {
2277 .data = (u8 *)assp_minisrc_image,
2278 .size = sizeof assp_minisrc_image
2279};
2280
2281#endif /* FIRMWARE_IN_THE_KERNEL */
2282
2283#ifdef __LITTLE_ENDIAN
2284static inline void snd_m3_convert_from_le(const struct firmware *fw) { }
2285#else
2286static void snd_m3_convert_from_le(const struct firmware *fw)
2287{
2288 int i;
2289 u16 *data = (u16 *)fw->data;
2290
2291 for (i = 0; i < fw->size / 2; ++i)
2292 le16_to_cpus(&data[i]);
2293}
2294#endif
2295
2263 2296
2264/* 2297/*
2265 * initialize ASSP 2298 * initialize ASSP
@@ -2274,6 +2307,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = {
2274static void snd_m3_assp_init(struct snd_m3 *chip) 2307static void snd_m3_assp_init(struct snd_m3 *chip)
2275{ 2308{
2276 unsigned int i; 2309 unsigned int i;
2310 u16 *data;
2277 2311
2278 /* zero kernel data */ 2312 /* zero kernel data */
2279 for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) 2313 for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
@@ -2291,10 +2325,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
2291 KDATA_DMA_XFER0); 2325 KDATA_DMA_XFER0);
2292 2326
2293 /* write kernel into code memory.. */ 2327 /* write kernel into code memory.. */
2294 for (i = 0 ; i < ARRAY_SIZE(assp_kernel_image); i++) { 2328 data = (u16 *)chip->assp_kernel_image->data;
2329 for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) {
2295 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 2330 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2296 REV_B_CODE_MEMORY_BEGIN + i, 2331 REV_B_CODE_MEMORY_BEGIN + i, data[i]);
2297 assp_kernel_image[i]);
2298 } 2332 }
2299 2333
2300 /* 2334 /*
@@ -2303,10 +2337,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
2303 * drop it there. It seems that the minisrc doesn't 2337 * drop it there. It seems that the minisrc doesn't
2304 * need vectors, so we won't bother with them.. 2338 * need vectors, so we won't bother with them..
2305 */ 2339 */
2306 for (i = 0; i < ARRAY_SIZE(assp_minisrc_image); i++) { 2340 data = (u16 *)chip->assp_minisrc_image->data;
2341 for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) {
2307 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 2342 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2308 0x400 + i, 2343 0x400 + i, data[i]);
2309 assp_minisrc_image[i]);
2310 } 2344 }
2311 2345
2312 /* 2346 /*
@@ -2553,6 +2587,15 @@ static int snd_m3_free(struct snd_m3 *chip)
2553 if (chip->iobase) 2587 if (chip->iobase)
2554 pci_release_regions(chip->pci); 2588 pci_release_regions(chip->pci);
2555 2589
2590#ifdef FIRMWARE_IN_THE_KERNEL
2591 if (chip->assp_kernel_image != &assp_kernel)
2592#endif
2593 release_firmware(chip->assp_kernel_image);
2594#ifdef FIRMWARE_IN_THE_KERNEL
2595 if (chip->assp_minisrc_image != &assp_minisrc)
2596#endif
2597 release_firmware(chip->assp_minisrc_image);
2598
2556 pci_disable_device(chip->pci); 2599 pci_disable_device(chip->pci);
2557 kfree(chip); 2600 kfree(chip);
2558 return 0; 2601 return 0;
@@ -2744,6 +2787,30 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2744 return -ENOMEM; 2787 return -ENOMEM;
2745 } 2788 }
2746 2789
2790 err = request_firmware(&chip->assp_kernel_image,
2791 "ess/maestro3_assp_kernel.fw", &pci->dev);
2792 if (err < 0) {
2793#ifdef FIRMWARE_IN_THE_KERNEL
2794 chip->assp_kernel_image = &assp_kernel;
2795#else
2796 snd_m3_free(chip);
2797 return err;
2798#endif
2799 } else
2800 snd_m3_convert_from_le(chip->assp_kernel_image);
2801
2802 err = request_firmware(&chip->assp_minisrc_image,
2803 "ess/maestro3_assp_minisrc.fw", &pci->dev);
2804 if (err < 0) {
2805#ifdef FIRMWARE_IN_THE_KERNEL
2806 chip->assp_minisrc_image = &assp_minisrc;
2807#else
2808 snd_m3_free(chip);
2809 return err;
2810#endif
2811 } else
2812 snd_m3_convert_from_le(chip->assp_minisrc_image);
2813
2747 if ((err = pci_request_regions(pci, card->driver)) < 0) { 2814 if ((err = pci_request_regions(pci, card->driver)) < 0) {
2748 snd_m3_free(chip); 2815 snd_m3_free(chip);
2749 return err; 2816 return err;