Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[ALSA] sb16: add request_firmware()

Load the CSP programs using request_firmware(), if possible, instead of
using the built-in firmware blobs.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>

authored by

Clemens Ladisch and committed by
Jaroslav Kysela
de66d53e 219e281f

+68 -8
+14
include/sound/sb16_csp.h
··· 114 114 #ifdef __KERNEL__ 115 115 #include "sb.h" 116 116 #include "hwdep.h" 117 + #include <linux/firmware.h> 117 118 118 119 struct snd_sb_csp; 120 + 121 + /* indices for the known CSP programs */ 122 + enum { 123 + CSP_PROGRAM_MULAW, 124 + CSP_PROGRAM_ALAW, 125 + CSP_PROGRAM_ADPCM_INIT, 126 + CSP_PROGRAM_ADPCM_PLAYBACK, 127 + CSP_PROGRAM_ADPCM_CAPTURE, 128 + 129 + CSP_PROGRAM_COUNT 130 + }; 119 131 120 132 /* 121 133 * CSP operators ··· 171 159 struct snd_kcontrol *qsound_space; 172 160 173 161 struct mutex access_mutex; /* locking */ 162 + 163 + const struct firmware *csp_programs[CSP_PROGRAM_COUNT]; 174 164 }; 175 165 176 166 int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep);
+1
sound/isa/Kconfig
··· 358 358 config SND_SB16_CSP 359 359 bool "Sound Blaster 16/AWE CSP support" 360 360 depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) 361 + select FW_LOADER 361 362 help 362 363 Say Y here to include support for the CSP core. This special 363 364 coprocessor can do variable tasks like various compression and
+53 -8
sound/isa/sb/sb16_csp.c
··· 161 161 */ 162 162 static void snd_sb_csp_free(struct snd_hwdep *hwdep) 163 163 { 164 + int i; 164 165 struct snd_sb_csp *p = hwdep->private_data; 165 166 if (p) { 166 167 if (p->running & SNDRV_SB_CSP_ST_RUNNING) 167 168 snd_sb_csp_stop(p); 169 + for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) 170 + release_firmware(p->csp_programs[i]); 168 171 kfree(p); 169 172 } 170 173 } ··· 690 687 return err; 691 688 } 692 689 690 + #define FIRMWARE_IN_THE_KERNEL 691 + 692 + #ifdef FIRMWARE_IN_THE_KERNEL 693 693 #include "sb16_csp_codecs.h" 694 + 695 + static const struct firmware snd_sb_csp_static_programs[] = { 696 + { .data = mulaw_main, .size = sizeof mulaw_main }, 697 + { .data = alaw_main, .size = sizeof alaw_main }, 698 + { .data = ima_adpcm_init, .size = sizeof ima_adpcm_init }, 699 + { .data = ima_adpcm_playback, .size = sizeof ima_adpcm_playback }, 700 + { .data = ima_adpcm_capture, .size = sizeof ima_adpcm_capture }, 701 + }; 702 + #endif 703 + 704 + static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) 705 + { 706 + static const char *const names[] = { 707 + "sb16/mulaw_main.csp", 708 + "sb16/alaw_main.csp", 709 + "sb16/ima_adpcm_init.csp", 710 + "sb16/ima_adpcm_playback.csp", 711 + "sb16/ima_adpcm_capture.csp", 712 + }; 713 + const struct firmware *program; 714 + int err; 715 + 716 + BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); 717 + program = p->csp_programs[index]; 718 + if (!program) { 719 + err = request_firmware(&program, names[index], 720 + p->chip->card->dev); 721 + if (err >= 0) 722 + p->csp_programs[index] = program; 723 + else { 724 + #ifdef FIRMWARE_IN_THE_KERNEL 725 + program = &snd_sb_csp_static_programs[index]; 726 + #else 727 + return err; 728 + #endif 729 + } 730 + } 731 + return snd_sb_csp_load(p, program->data, program->size, flags); 732 + } 694 733 695 734 /* 696 735 * autoload hardware codec if necessary ··· 753 708 } else { 754 709 switch (pcm_sfmt) { 755 710 case SNDRV_PCM_FORMAT_MU_LAW: 756 - err = snd_sb_csp_load(p, &mulaw_main[0], sizeof(mulaw_main), 0); 711 + err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0); 757 712 p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW; 758 713 p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; 759 714 break; 760 715 case SNDRV_PCM_FORMAT_A_LAW: 761 - err = snd_sb_csp_load(p, &alaw_main[0], sizeof(alaw_main), 0); 716 + err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0); 762 717 p->acc_format = SNDRV_PCM_FMTBIT_A_LAW; 763 718 p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE; 764 719 break; 765 720 case SNDRV_PCM_FORMAT_IMA_ADPCM: 766 - err = snd_sb_csp_load(p, &ima_adpcm_init[0], sizeof(ima_adpcm_init), 767 - SNDRV_SB_CSP_LOAD_INITBLOCK); 721 + err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT, 722 + SNDRV_SB_CSP_LOAD_INITBLOCK); 768 723 if (err) 769 724 break; 770 725 if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) { 771 - err = snd_sb_csp_load(p, &ima_adpcm_playback[0], 772 - sizeof(ima_adpcm_playback), 0); 726 + err = snd_sb_csp_firmware_load 727 + (p, CSP_PROGRAM_ADPCM_PLAYBACK, 0); 773 728 p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE; 774 729 } else { 775 - err = snd_sb_csp_load(p, &ima_adpcm_capture[0], 776 - sizeof(ima_adpcm_capture), 0); 730 + err = snd_sb_csp_firmware_load 731 + (p, CSP_PROGRAM_ADPCM_CAPTURE, 0); 777 732 p->mode = SNDRV_SB_CSP_MODE_DSP_READ; 778 733 } 779 734 p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;