diff options
author | Markus Bollinger <bollinger@digigram.com> | 2008-11-25 06:28:06 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-11-25 06:28:06 -0500 |
commit | 7628700e08403618b0b07bd25b6456d8b2d074ef (patch) | |
tree | 4d1326484baa59ae412303345532f8e4137ce306 /sound | |
parent | 9d948d270010e3552c94281bab75694580ca23e9 (diff) |
ALSA: pcxhr - add support for pcxhr stereo sound cards (firmware support)
- Add support for pcxhr stereo cards and their firmware
- autorize sound cards without analog IO
- do some cleanup
Signed-off-by: Markus Bollinger <bollinger@digigram.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/pcxhr/pcxhr_hwdep.c | 148 |
1 files changed, 108 insertions, 40 deletions
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index 96640d9c227d..ea50018d785b 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "pcxhr_mixer.h" | 31 | #include "pcxhr_mixer.h" |
32 | #include "pcxhr_hwdep.h" | 32 | #include "pcxhr_hwdep.h" |
33 | #include "pcxhr_core.h" | 33 | #include "pcxhr_core.h" |
34 | #include "pcxhr_mix22.h" | ||
34 | 35 | ||
35 | 36 | ||
36 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | 37 | #if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) |
@@ -40,10 +41,10 @@ | |||
40 | #endif | 41 | #endif |
41 | 42 | ||
42 | 43 | ||
44 | static int pcxhr_sub_init(struct pcxhr_mgr *mgr); | ||
43 | /* | 45 | /* |
44 | * get basic information and init pcxhr card | 46 | * get basic information and init pcxhr card |
45 | */ | 47 | */ |
46 | |||
47 | static int pcxhr_init_board(struct pcxhr_mgr *mgr) | 48 | static int pcxhr_init_board(struct pcxhr_mgr *mgr) |
48 | { | 49 | { |
49 | int err; | 50 | int err; |
@@ -68,7 +69,7 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr) | |||
68 | if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2) | 69 | if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2) |
69 | return -EINVAL; | 70 | return -EINVAL; |
70 | /* test 8 or 2 phys in */ | 71 | /* test 8 or 2 phys in */ |
71 | if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) != | 72 | if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) < |
72 | mgr->capture_chips * 2) | 73 | mgr->capture_chips * 2) |
73 | return -EINVAL; | 74 | return -EINVAL; |
74 | /* test max nb substream per board */ | 75 | /* test max nb substream per board */ |
@@ -77,20 +78,34 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr) | |||
77 | /* test max nb substream per pipe */ | 78 | /* test max nb substream per pipe */ |
78 | if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS) | 79 | if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS) |
79 | return -EINVAL; | 80 | return -EINVAL; |
81 | snd_printdd("supported formats : playback=%x capture=%x\n", | ||
82 | rmh.stat[2], rmh.stat[3]); | ||
80 | 83 | ||
81 | pcxhr_init_rmh(&rmh, CMD_VERSION); | 84 | pcxhr_init_rmh(&rmh, CMD_VERSION); |
82 | /* firmware num for DSP */ | 85 | /* firmware num for DSP */ |
83 | rmh.cmd[0] |= mgr->firmware_num; | 86 | rmh.cmd[0] |= mgr->firmware_num; |
84 | /* transfer granularity in samples (should be multiple of 48) */ | 87 | /* transfer granularity in samples (should be multiple of 48) */ |
85 | rmh.cmd[1] = (1<<23) + PCXHR_GRANULARITY; | 88 | rmh.cmd[1] = (1<<23) + mgr->granularity; |
86 | rmh.cmd_len = 2; | 89 | rmh.cmd_len = 2; |
87 | err = pcxhr_send_msg(mgr, &rmh); | 90 | err = pcxhr_send_msg(mgr, &rmh); |
88 | if (err) | 91 | if (err) |
89 | return err; | 92 | return err; |
90 | snd_printdd("PCXHR DSP version is %d.%d.%d\n", | 93 | snd_printdd("PCXHR DSP version is %d.%d.%d\n", (rmh.stat[0]>>16)&0xff, |
91 | (rmh.stat[0]>>16)&0xff, (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff); | 94 | (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff); |
92 | mgr->dsp_version = rmh.stat[0]; | 95 | mgr->dsp_version = rmh.stat[0]; |
93 | 96 | ||
97 | if (mgr->is_hr_stereo) | ||
98 | err = hr222_sub_init(mgr); | ||
99 | else | ||
100 | err = pcxhr_sub_init(mgr); | ||
101 | return err; | ||
102 | } | ||
103 | |||
104 | static int pcxhr_sub_init(struct pcxhr_mgr *mgr) | ||
105 | { | ||
106 | int err; | ||
107 | struct pcxhr_rmh rmh; | ||
108 | |||
94 | /* get options */ | 109 | /* get options */ |
95 | pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); | 110 | pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); |
96 | rmh.cmd[0] |= IO_NUM_REG_STATUS; | 111 | rmh.cmd[0] |= IO_NUM_REG_STATUS; |
@@ -100,20 +115,22 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr) | |||
100 | if (err) | 115 | if (err) |
101 | return err; | 116 | return err; |
102 | 117 | ||
103 | if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == REG_STATUS_OPT_ANALOG_BOARD) | 118 | if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == |
104 | mgr->board_has_analog = 1; /* analog addon board available */ | 119 | REG_STATUS_OPT_ANALOG_BOARD) |
105 | else | 120 | mgr->board_has_analog = 1; /* analog addon board found */ |
106 | /* analog addon board not available -> no support for instance */ | ||
107 | return -EINVAL; | ||
108 | 121 | ||
109 | /* unmute inputs */ | 122 | /* unmute inputs */ |
110 | err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, | 123 | err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, |
111 | REG_CONT_UNMUTE_INPUTS, NULL); | 124 | REG_CONT_UNMUTE_INPUTS, NULL); |
112 | if (err) | 125 | if (err) |
113 | return err; | 126 | return err; |
114 | /* unmute outputs */ | 127 | /* unmute outputs (a write to IO_NUM_REG_MUTE_OUT mutes!) */ |
115 | pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* a write to IO_NUM_REG_MUTE_OUT mutes! */ | 128 | pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); |
116 | rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; | 129 | rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; |
130 | if (DSP_EXT_CMD_SET(mgr)) { | ||
131 | rmh.cmd[1] = 1; /* unmute digital plugs */ | ||
132 | rmh.cmd_len = 2; | ||
133 | } | ||
117 | err = pcxhr_send_msg(mgr, &rmh); | 134 | err = pcxhr_send_msg(mgr, &rmh); |
118 | return err; | 135 | return err; |
119 | } | 136 | } |
@@ -124,19 +141,25 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr) | |||
124 | 141 | ||
125 | if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { | 142 | if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { |
126 | /* mute outputs */ | 143 | /* mute outputs */ |
144 | if (!mgr->is_hr_stereo) { | ||
127 | /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */ | 145 | /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */ |
128 | pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); | 146 | pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); |
129 | rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; | 147 | rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; |
130 | pcxhr_send_msg(mgr, &rmh); | 148 | pcxhr_send_msg(mgr, &rmh); |
131 | /* mute inputs */ | 149 | /* mute inputs */ |
132 | pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 0, NULL); | 150 | pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, |
151 | 0, NULL); | ||
152 | } | ||
153 | /* stereo cards mute with reset of dsp */ | ||
133 | } | 154 | } |
134 | /* reset pcxhr dsp */ | 155 | /* reset pcxhr dsp */ |
135 | if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX)) | 156 | if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX)) |
136 | pcxhr_reset_dsp(mgr); | 157 | pcxhr_reset_dsp(mgr); |
137 | /* reset second xilinx */ | 158 | /* reset second xilinx */ |
138 | if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) | 159 | if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) { |
139 | pcxhr_reset_xilinx_com(mgr); | 160 | pcxhr_reset_xilinx_com(mgr); |
161 | mgr->dsp_loaded = 1; | ||
162 | } | ||
140 | return; | 163 | return; |
141 | } | 164 | } |
142 | 165 | ||
@@ -144,8 +167,9 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr) | |||
144 | /* | 167 | /* |
145 | * allocate a playback/capture pipe (pcmp0/pcmc0) | 168 | * allocate a playback/capture pipe (pcmp0/pcmc0) |
146 | */ | 169 | */ |
147 | static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe, | 170 | static int pcxhr_dsp_allocate_pipe(struct pcxhr_mgr *mgr, |
148 | int is_capture, int pin) | 171 | struct pcxhr_pipe *pipe, |
172 | int is_capture, int pin) | ||
149 | { | 173 | { |
150 | int stream_count, audio_count; | 174 | int stream_count, audio_count; |
151 | int err; | 175 | int err; |
@@ -161,15 +185,23 @@ static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pi | |||
161 | stream_count = PCXHR_PLAYBACK_STREAMS; | 185 | stream_count = PCXHR_PLAYBACK_STREAMS; |
162 | audio_count = 2; /* always stereo */ | 186 | audio_count = 2; /* always stereo */ |
163 | } | 187 | } |
164 | snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", pin, is_capture ? 'c' : 'p'); | 188 | snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", |
189 | pin, is_capture ? 'c' : 'p'); | ||
165 | pipe->is_capture = is_capture; | 190 | pipe->is_capture = is_capture; |
166 | pipe->first_audio = pin; | 191 | pipe->first_audio = pin; |
167 | /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */ | 192 | /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */ |
168 | pcxhr_init_rmh(&rmh, CMD_RES_PIPE); | 193 | pcxhr_init_rmh(&rmh, CMD_RES_PIPE); |
169 | pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, audio_count, stream_count); | 194 | pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, |
195 | audio_count, stream_count); | ||
196 | rmh.cmd[1] |= 0x020000; /* add P_PCM_ONLY_MASK */ | ||
197 | if (DSP_EXT_CMD_SET(mgr)) { | ||
198 | /* add channel mask to command */ | ||
199 | rmh.cmd[rmh.cmd_len++] = (audio_count == 1) ? 0x01 : 0x03; | ||
200 | } | ||
170 | err = pcxhr_send_msg(mgr, &rmh); | 201 | err = pcxhr_send_msg(mgr, &rmh); |
171 | if (err < 0) { | 202 | if (err < 0) { |
172 | snd_printk(KERN_ERR "error pipe allocation (CMD_RES_PIPE) err=%x!\n", err ); | 203 | snd_printk(KERN_ERR "error pipe allocation " |
204 | "(CMD_RES_PIPE) err=%x!\n", err); | ||
173 | return err; | 205 | return err; |
174 | } | 206 | } |
175 | pipe->status = PCXHR_PIPE_DEFINED; | 207 | pipe->status = PCXHR_PIPE_DEFINED; |
@@ -199,10 +231,12 @@ static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe) | |||
199 | snd_printk(KERN_ERR "error stopping pipe!\n"); | 231 | snd_printk(KERN_ERR "error stopping pipe!\n"); |
200 | /* release the pipe */ | 232 | /* release the pipe */ |
201 | pcxhr_init_rmh(&rmh, CMD_FREE_PIPE); | 233 | pcxhr_init_rmh(&rmh, CMD_FREE_PIPE); |
202 | pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, 0, 0); | 234 | pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, |
235 | 0, 0); | ||
203 | err = pcxhr_send_msg(mgr, &rmh); | 236 | err = pcxhr_send_msg(mgr, &rmh); |
204 | if (err < 0) | 237 | if (err < 0) |
205 | snd_printk(KERN_ERR "error pipe release (CMD_FREE_PIPE) err(%x)\n", err); | 238 | snd_printk(KERN_ERR "error pipe release " |
239 | "(CMD_FREE_PIPE) err(%x)\n", err); | ||
206 | pipe->status = PCXHR_PIPE_UNDEFINED; | 240 | pipe->status = PCXHR_PIPE_UNDEFINED; |
207 | return err; | 241 | return err; |
208 | } | 242 | } |
@@ -248,15 +282,16 @@ static int pcxhr_start_pipes(struct pcxhr_mgr *mgr) | |||
248 | for (i = 0; i < mgr->num_cards; i++) { | 282 | for (i = 0; i < mgr->num_cards; i++) { |
249 | chip = mgr->chip[i]; | 283 | chip = mgr->chip[i]; |
250 | if (chip->nb_streams_play) | 284 | if (chip->nb_streams_play) |
251 | playback_mask |= (1 << chip->playback_pipe.first_audio); | 285 | playback_mask |= 1 << chip->playback_pipe.first_audio; |
252 | for (j = 0; j < chip->nb_streams_capt; j++) | 286 | for (j = 0; j < chip->nb_streams_capt; j++) |
253 | capture_mask |= (1 << chip->capture_pipe[j].first_audio); | 287 | capture_mask |= 1 << chip->capture_pipe[j].first_audio; |
254 | } | 288 | } |
255 | return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); | 289 | return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); |
256 | } | 290 | } |
257 | 291 | ||
258 | 292 | ||
259 | static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmware *dsp) | 293 | static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, |
294 | const struct firmware *dsp) | ||
260 | { | 295 | { |
261 | int err, card_index; | 296 | int err, card_index; |
262 | 297 | ||
@@ -330,22 +365,33 @@ static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmwar | |||
330 | 365 | ||
331 | int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) | 366 | int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) |
332 | { | 367 | { |
333 | static char *fw_files[5] = { | 368 | static char *fw_files[][5] = { |
334 | "xi_1_882.dat", | 369 | [0] = { "xi_1_882.dat", "xc_1_882.dat", |
335 | "xc_1_882.dat", | 370 | "e321_512.e56", "b321_512.b56", "d321_512.d56" }, |
336 | "e321_512.e56", | 371 | [1] = { "xi_1_882.dat", "xc_882e.dat", |
337 | "b321_512.b56", | 372 | "e321_512.e56", "b882e.b56", "d321_512.d56" }, |
338 | "d321_512.d56" | 373 | [2] = { "xi_1_882.dat", "xc_1222.dat", |
374 | "e321_512.e56", "b1222.b56", "d1222.d56" }, | ||
375 | [3] = { "xi_1_882.dat", "xc_1222e.dat", | ||
376 | "e321_512.e56", "b1222e.b56", "d1222.d56" }, | ||
377 | [4] = { NULL, "x1_222hr.dat", | ||
378 | "e924.e56", "b924.b56", "l_1_222.d56" }, | ||
379 | [5] = { NULL, "x1_924hr.dat", | ||
380 | "e924.e56", "b924.b56", "l_1_222.d56" }, | ||
339 | }; | 381 | }; |
340 | char path[32]; | 382 | char path[32]; |
341 | 383 | ||
342 | const struct firmware *fw_entry; | 384 | const struct firmware *fw_entry; |
343 | int i, err; | 385 | int i, err; |
386 | int fw_set = mgr->fw_file_set; | ||
344 | 387 | ||
345 | for (i = 0; i < ARRAY_SIZE(fw_files); i++) { | 388 | for (i = 0; i < 5; i++) { |
346 | sprintf(path, "pcxhr/%s", fw_files[i]); | 389 | if (!fw_files[fw_set][i]) |
390 | continue; | ||
391 | sprintf(path, "pcxhr/%s", fw_files[fw_set][i]); | ||
347 | if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { | 392 | if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { |
348 | snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n", path); | 393 | snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n", |
394 | path); | ||
349 | return -ENOENT; | 395 | return -ENOENT; |
350 | } | 396 | } |
351 | /* fake hwdep dsp record */ | 397 | /* fake hwdep dsp record */ |
@@ -360,10 +406,25 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) | |||
360 | 406 | ||
361 | MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); | 407 | MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); |
362 | MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); | 408 | MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); |
409 | MODULE_FIRMWARE("pcxhr/xc_882e.dat"); | ||
363 | MODULE_FIRMWARE("pcxhr/e321_512.e56"); | 410 | MODULE_FIRMWARE("pcxhr/e321_512.e56"); |
364 | MODULE_FIRMWARE("pcxhr/b321_512.b56"); | 411 | MODULE_FIRMWARE("pcxhr/b321_512.b56"); |
412 | MODULE_FIRMWARE("pcxhr/b882e.b56"); | ||
365 | MODULE_FIRMWARE("pcxhr/d321_512.d56"); | 413 | MODULE_FIRMWARE("pcxhr/d321_512.d56"); |
366 | 414 | ||
415 | MODULE_FIRMWARE("pcxhr/xc_1222.dat"); | ||
416 | MODULE_FIRMWARE("pcxhr/xc_1222e.dat"); | ||
417 | MODULE_FIRMWARE("pcxhr/b1222.b56"); | ||
418 | MODULE_FIRMWARE("pcxhr/b1222e.b56"); | ||
419 | MODULE_FIRMWARE("pcxhr/d1222.d56"); | ||
420 | |||
421 | MODULE_FIRMWARE("pcxhr/x1_222hr.dat"); | ||
422 | MODULE_FIRMWARE("pcxhr/x1_924hr.dat"); | ||
423 | MODULE_FIRMWARE("pcxhr/e924.e56"); | ||
424 | MODULE_FIRMWARE("pcxhr/b924.b56"); | ||
425 | MODULE_FIRMWARE("pcxhr/l_1_222.d56"); | ||
426 | |||
427 | |||
367 | #else /* old style firmware loading */ | 428 | #else /* old style firmware loading */ |
368 | 429 | ||
369 | /* pcxhr hwdep interface id string */ | 430 | /* pcxhr hwdep interface id string */ |
@@ -373,7 +434,8 @@ MODULE_FIRMWARE("pcxhr/d321_512.d56"); | |||
373 | static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw, | 434 | static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw, |
374 | struct snd_hwdep_dsp_status *info) | 435 | struct snd_hwdep_dsp_status *info) |
375 | { | 436 | { |
376 | strcpy(info->id, "pcxhr"); | 437 | struct pcxhr_mgr *mgr = hw->private_data; |
438 | sprintf(info->id, "pcxhr%d", mgr->fw_file_set); | ||
377 | info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX; | 439 | info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX; |
378 | 440 | ||
379 | if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) | 441 | if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) |
@@ -393,8 +455,8 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw, | |||
393 | fw.size = dsp->length; | 455 | fw.size = dsp->length; |
394 | fw.data = vmalloc(fw.size); | 456 | fw.data = vmalloc(fw.size); |
395 | if (! fw.data) { | 457 | if (! fw.data) { |
396 | snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n", | 458 | snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image " |
397 | (unsigned long)fw.size); | 459 | "(%lu bytes)\n", (unsigned long)fw.size); |
398 | return -ENOMEM; | 460 | return -ENOMEM; |
399 | } | 461 | } |
400 | if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) { | 462 | if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) { |
@@ -424,8 +486,11 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) | |||
424 | int err; | 486 | int err; |
425 | struct snd_hwdep *hw; | 487 | struct snd_hwdep *hw; |
426 | 488 | ||
427 | /* only create hwdep interface for first cardX (see "index" module parameter)*/ | 489 | /* only create hwdep interface for first cardX |
428 | if ((err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw)) < 0) | 490 | * (see "index" module parameter) |
491 | */ | ||
492 | err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw); | ||
493 | if (err < 0) | ||
429 | return err; | 494 | return err; |
430 | 495 | ||
431 | hw->iface = SNDRV_HWDEP_IFACE_PCXHR; | 496 | hw->iface = SNDRV_HWDEP_IFACE_PCXHR; |
@@ -435,10 +500,13 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) | |||
435 | hw->ops.dsp_status = pcxhr_hwdep_dsp_status; | 500 | hw->ops.dsp_status = pcxhr_hwdep_dsp_status; |
436 | hw->ops.dsp_load = pcxhr_hwdep_dsp_load; | 501 | hw->ops.dsp_load = pcxhr_hwdep_dsp_load; |
437 | hw->exclusive = 1; | 502 | hw->exclusive = 1; |
503 | /* stereo cards don't need fw_file_0 -> dsp_loaded = 1 */ | ||
504 | hw->dsp_loaded = mgr->is_hr_stereo ? 1 : 0; | ||
438 | mgr->dsp_loaded = 0; | 505 | mgr->dsp_loaded = 0; |
439 | sprintf(hw->name, PCXHR_HWDEP_ID); | 506 | sprintf(hw->name, PCXHR_HWDEP_ID); |
440 | 507 | ||
441 | if ((err = snd_card_register(mgr->chip[0]->card)) < 0) | 508 | err = snd_card_register(mgr->chip[0]->card); |
509 | if (err < 0) | ||
442 | return err; | 510 | return err; |
443 | return 0; | 511 | return 0; |
444 | } | 512 | } |