diff options
| -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 | } |
