diff options
| -rw-r--r-- | sound/pci/Kconfig | 1 | ||||
| -rw-r--r-- | sound/pci/maestro3.c | 79 |
2 files changed, 74 insertions, 6 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 7573997af760..1bcfb3aac18d 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
| @@ -587,6 +587,7 @@ config SND_KORG1212 | |||
| 587 | config SND_MAESTRO3 | 587 | config SND_MAESTRO3 |
| 588 | tristate "ESS Allegro/Maestro3" | 588 | tristate "ESS Allegro/Maestro3" |
| 589 | depends on SND | 589 | depends on SND |
| 590 | select FW_LOADER | ||
| 590 | select SND_AC97_CODEC | 591 | select SND_AC97_CODEC |
| 591 | help | 592 | help |
| 592 | Say Y here to include support for soundcards based on ESS Maestro 3 | 593 | Say Y here to include support for soundcards based on ESS Maestro 3 |
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 | ||
| 52 | MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>"); | 54 | MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>"); |
| 53 | MODULE_DESCRIPTION("ESS Maestro3 PCI"); | 55 | MODULE_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 | ||
| 2272 | static const struct firmware assp_kernel = { | ||
| 2273 | .data = (u8 *)assp_kernel_image, | ||
| 2274 | .size = sizeof assp_kernel_image | ||
| 2275 | }; | ||
| 2276 | static 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 | ||
| 2284 | static inline void snd_m3_convert_from_le(const struct firmware *fw) { } | ||
| 2285 | #else | ||
| 2286 | static 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] = { | |||
| 2274 | static void snd_m3_assp_init(struct snd_m3 *chip) | 2307 | static 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; |
