xref: /OK3568_Linux_fs/kernel/sound/drivers/vx/vx_hwdep.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Driver for Digigram VX soundcards
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * DSP firmware management
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/device.h>
11*4882a593Smuzhiyun #include <linux/firmware.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/vmalloc.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <sound/core.h>
16*4882a593Smuzhiyun #include <sound/hwdep.h>
17*4882a593Smuzhiyun #include <sound/vx_core.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun MODULE_FIRMWARE("vx/bx_1_vxp.b56");
20*4882a593Smuzhiyun MODULE_FIRMWARE("vx/bx_1_vp4.b56");
21*4882a593Smuzhiyun MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
22*4882a593Smuzhiyun MODULE_FIRMWARE("vx/x1_2_v22.xlx");
23*4882a593Smuzhiyun MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
24*4882a593Smuzhiyun MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
25*4882a593Smuzhiyun MODULE_FIRMWARE("vx/bd56002.boot");
26*4882a593Smuzhiyun MODULE_FIRMWARE("vx/bd563v2.boot");
27*4882a593Smuzhiyun MODULE_FIRMWARE("vx/bd563s3.boot");
28*4882a593Smuzhiyun MODULE_FIRMWARE("vx/l_1_vx2.d56");
29*4882a593Smuzhiyun MODULE_FIRMWARE("vx/l_1_v22.d56");
30*4882a593Smuzhiyun MODULE_FIRMWARE("vx/l_1_vxp.d56");
31*4882a593Smuzhiyun MODULE_FIRMWARE("vx/l_1_vp4.d56");
32*4882a593Smuzhiyun 
snd_vx_setup_firmware(struct vx_core * chip)33*4882a593Smuzhiyun int snd_vx_setup_firmware(struct vx_core *chip)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun 	static const char * const fw_files[VX_TYPE_NUMS][4] = {
36*4882a593Smuzhiyun 		[VX_TYPE_BOARD] = {
37*4882a593Smuzhiyun 			NULL, "x1_1_vx2.xlx", "bd56002.boot", "l_1_vx2.d56",
38*4882a593Smuzhiyun 		},
39*4882a593Smuzhiyun 		[VX_TYPE_V2] = {
40*4882a593Smuzhiyun 			NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
41*4882a593Smuzhiyun 		},
42*4882a593Smuzhiyun 		[VX_TYPE_MIC] = {
43*4882a593Smuzhiyun 			NULL, "x1_2_v22.xlx", "bd563v2.boot", "l_1_v22.d56",
44*4882a593Smuzhiyun 		},
45*4882a593Smuzhiyun 		[VX_TYPE_VXPOCKET] = {
46*4882a593Smuzhiyun 			"bx_1_vxp.b56", "x1_1_vxp.xlx", "bd563s3.boot", "l_1_vxp.d56"
47*4882a593Smuzhiyun 		},
48*4882a593Smuzhiyun 		[VX_TYPE_VXP440] = {
49*4882a593Smuzhiyun 			"bx_1_vp4.b56", "x1_1_vp4.xlx", "bd563s3.boot", "l_1_vp4.d56"
50*4882a593Smuzhiyun 		},
51*4882a593Smuzhiyun 	};
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	int i, err;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
56*4882a593Smuzhiyun 		char path[32];
57*4882a593Smuzhiyun 		const struct firmware *fw;
58*4882a593Smuzhiyun 		if (! fw_files[chip->type][i])
59*4882a593Smuzhiyun 			continue;
60*4882a593Smuzhiyun 		sprintf(path, "vx/%s", fw_files[chip->type][i]);
61*4882a593Smuzhiyun 		if (request_firmware(&fw, path, chip->dev)) {
62*4882a593Smuzhiyun 			snd_printk(KERN_ERR "vx: can't load firmware %s\n", path);
63*4882a593Smuzhiyun 			return -ENOENT;
64*4882a593Smuzhiyun 		}
65*4882a593Smuzhiyun 		err = chip->ops->load_dsp(chip, i, fw);
66*4882a593Smuzhiyun 		if (err < 0) {
67*4882a593Smuzhiyun 			release_firmware(fw);
68*4882a593Smuzhiyun 			return err;
69*4882a593Smuzhiyun 		}
70*4882a593Smuzhiyun 		if (i == 1)
71*4882a593Smuzhiyun 			chip->chip_status |= VX_STAT_XILINX_LOADED;
72*4882a593Smuzhiyun #ifdef CONFIG_PM
73*4882a593Smuzhiyun 		chip->firmware[i] = fw;
74*4882a593Smuzhiyun #else
75*4882a593Smuzhiyun 		release_firmware(fw);
76*4882a593Smuzhiyun #endif
77*4882a593Smuzhiyun 	}
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	/* ok, we reached to the last one */
80*4882a593Smuzhiyun 	/* create the devices if not built yet */
81*4882a593Smuzhiyun 	if ((err = snd_vx_pcm_new(chip)) < 0)
82*4882a593Smuzhiyun 		return err;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	if ((err = snd_vx_mixer_new(chip)) < 0)
85*4882a593Smuzhiyun 		return err;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	if (chip->ops->add_controls)
88*4882a593Smuzhiyun 		if ((err = chip->ops->add_controls(chip)) < 0)
89*4882a593Smuzhiyun 			return err;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	chip->chip_status |= VX_STAT_DEVICE_INIT;
92*4882a593Smuzhiyun 	chip->chip_status |= VX_STAT_CHIP_INIT;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	return snd_card_register(chip->card);
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* exported */
snd_vx_free_firmware(struct vx_core * chip)98*4882a593Smuzhiyun void snd_vx_free_firmware(struct vx_core *chip)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun #ifdef CONFIG_PM
101*4882a593Smuzhiyun 	int i;
102*4882a593Smuzhiyun 	for (i = 0; i < 4; i++)
103*4882a593Smuzhiyun 		release_firmware(chip->firmware[i]);
104*4882a593Smuzhiyun #endif
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun EXPORT_SYMBOL(snd_vx_setup_firmware);
108*4882a593Smuzhiyun EXPORT_SYMBOL(snd_vx_free_firmware);
109