0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/interrupt.h>
0011 #include <linux/vmalloc.h>
0012 #include <linux/firmware.h>
0013 #include <linux/pci.h>
0014 #include <linux/module.h>
0015 #include <linux/io.h>
0016 #include <sound/core.h>
0017 #include <sound/hwdep.h>
0018 #include "pcxhr.h"
0019 #include "pcxhr_mixer.h"
0020 #include "pcxhr_hwdep.h"
0021 #include "pcxhr_core.h"
0022 #include "pcxhr_mix22.h"
0023
0024
0025 static int pcxhr_sub_init(struct pcxhr_mgr *mgr);
0026
0027
0028
0029 static int pcxhr_init_board(struct pcxhr_mgr *mgr)
0030 {
0031 int err;
0032 struct pcxhr_rmh rmh;
0033 int card_streams;
0034
0035
0036 if (mgr->mono_capture)
0037 card_streams = mgr->capture_chips * 2;
0038 else
0039 card_streams = mgr->capture_chips;
0040 card_streams += mgr->playback_chips * PCXHR_PLAYBACK_STREAMS;
0041
0042
0043 pcxhr_enable_dsp(mgr);
0044
0045 pcxhr_init_rmh(&rmh, CMD_SUPPORTED);
0046 err = pcxhr_send_msg(mgr, &rmh);
0047 if (err)
0048 return err;
0049
0050 if ((rmh.stat[0] & MASK_FIRST_FIELD) < mgr->playback_chips * 2)
0051 return -EINVAL;
0052
0053 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
0054 mgr->capture_chips * 2)
0055 return -EINVAL;
0056
0057 if ((rmh.stat[1] & 0x5F) < card_streams)
0058 return -EINVAL;
0059
0060 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
0061 return -EINVAL;
0062 dev_dbg(&mgr->pci->dev,
0063 "supported formats : playback=%x capture=%x\n",
0064 rmh.stat[2], rmh.stat[3]);
0065
0066 pcxhr_init_rmh(&rmh, CMD_VERSION);
0067
0068 rmh.cmd[0] |= mgr->firmware_num;
0069
0070 rmh.cmd[1] = (1<<23) + mgr->granularity;
0071 rmh.cmd_len = 2;
0072 err = pcxhr_send_msg(mgr, &rmh);
0073 if (err)
0074 return err;
0075 dev_dbg(&mgr->pci->dev,
0076 "PCXHR DSP version is %d.%d.%d\n", (rmh.stat[0]>>16)&0xff,
0077 (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
0078 mgr->dsp_version = rmh.stat[0];
0079
0080 if (mgr->is_hr_stereo)
0081 err = hr222_sub_init(mgr);
0082 else
0083 err = pcxhr_sub_init(mgr);
0084 return err;
0085 }
0086
0087 static int pcxhr_sub_init(struct pcxhr_mgr *mgr)
0088 {
0089 int err;
0090 struct pcxhr_rmh rmh;
0091
0092
0093 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
0094 rmh.cmd[0] |= IO_NUM_REG_STATUS;
0095 rmh.cmd[1] = REG_STATUS_OPTIONS;
0096 rmh.cmd_len = 2;
0097 err = pcxhr_send_msg(mgr, &rmh);
0098 if (err)
0099 return err;
0100
0101 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) ==
0102 REG_STATUS_OPT_ANALOG_BOARD)
0103 mgr->board_has_analog = 1;
0104
0105
0106 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
0107 REG_CONT_UNMUTE_INPUTS, NULL);
0108 if (err)
0109 return err;
0110
0111 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
0112 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
0113 if (DSP_EXT_CMD_SET(mgr)) {
0114 rmh.cmd[1] = 1;
0115 rmh.cmd_len = 2;
0116 }
0117 err = pcxhr_send_msg(mgr, &rmh);
0118 return err;
0119 }
0120
0121 void pcxhr_reset_board(struct pcxhr_mgr *mgr)
0122 {
0123 struct pcxhr_rmh rmh;
0124
0125 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
0126
0127 if (!mgr->is_hr_stereo) {
0128
0129 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
0130 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
0131 pcxhr_send_msg(mgr, &rmh);
0132
0133 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
0134 0, NULL);
0135 }
0136
0137 }
0138
0139 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
0140 pcxhr_reset_dsp(mgr);
0141
0142 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) {
0143 pcxhr_reset_xilinx_com(mgr);
0144 mgr->dsp_loaded = 1;
0145 }
0146 return;
0147 }
0148
0149
0150
0151
0152
0153 static int pcxhr_dsp_allocate_pipe(struct pcxhr_mgr *mgr,
0154 struct pcxhr_pipe *pipe,
0155 int is_capture, int pin)
0156 {
0157 int stream_count, audio_count;
0158 int err;
0159 struct pcxhr_rmh rmh;
0160
0161 if (is_capture) {
0162 stream_count = 1;
0163 if (mgr->mono_capture)
0164 audio_count = 1;
0165 else
0166 audio_count = 2;
0167 } else {
0168 stream_count = PCXHR_PLAYBACK_STREAMS;
0169 audio_count = 2;
0170 }
0171 dev_dbg(&mgr->pci->dev, "snd_add_ref_pipe pin(%d) pcm%c0\n",
0172 pin, is_capture ? 'c' : 'p');
0173 pipe->is_capture = is_capture;
0174 pipe->first_audio = pin;
0175
0176 pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
0177 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin,
0178 audio_count, stream_count);
0179 rmh.cmd[1] |= 0x020000;
0180 if (DSP_EXT_CMD_SET(mgr)) {
0181
0182 rmh.cmd[rmh.cmd_len++] = (audio_count == 1) ? 0x01 : 0x03;
0183 }
0184 err = pcxhr_send_msg(mgr, &rmh);
0185 if (err < 0) {
0186 dev_err(&mgr->pci->dev, "error pipe allocation "
0187 "(CMD_RES_PIPE) err=%x!\n", err);
0188 return err;
0189 }
0190 pipe->status = PCXHR_PIPE_DEFINED;
0191
0192 return 0;
0193 }
0194
0195
0196
0197
0198 #if 0
0199 static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
0200 {
0201 struct pcxhr_rmh rmh;
0202 int capture_mask = 0;
0203 int playback_mask = 0;
0204 int err = 0;
0205
0206 if (pipe->is_capture)
0207 capture_mask = (1 << pipe->first_audio);
0208 else
0209 playback_mask = (1 << pipe->first_audio);
0210
0211
0212 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
0213 if (err < 0)
0214 dev_err(&mgr->pci->dev, "error stopping pipe!\n");
0215
0216 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
0217 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio,
0218 0, 0);
0219 err = pcxhr_send_msg(mgr, &rmh);
0220 if (err < 0)
0221 dev_err(&mgr->pci->dev, "error pipe release "
0222 "(CMD_FREE_PIPE) err(%x)\n", err);
0223 pipe->status = PCXHR_PIPE_UNDEFINED;
0224 return err;
0225 }
0226 #endif
0227
0228
0229 static int pcxhr_config_pipes(struct pcxhr_mgr *mgr)
0230 {
0231 int err, i, j;
0232 struct snd_pcxhr *chip;
0233 struct pcxhr_pipe *pipe;
0234
0235
0236 for (i = 0; i < mgr->num_cards; i++) {
0237 chip = mgr->chip[i];
0238 if (chip->nb_streams_play) {
0239 pipe = &chip->playback_pipe;
0240 err = pcxhr_dsp_allocate_pipe( mgr, pipe, 0, i*2);
0241 if (err)
0242 return err;
0243 for(j = 0; j < chip->nb_streams_play; j++)
0244 chip->playback_stream[j].pipe = pipe;
0245 }
0246 for (j = 0; j < chip->nb_streams_capt; j++) {
0247 pipe = &chip->capture_pipe[j];
0248 err = pcxhr_dsp_allocate_pipe(mgr, pipe, 1, i*2 + j);
0249 if (err)
0250 return err;
0251 chip->capture_stream[j].pipe = pipe;
0252 }
0253 }
0254 return 0;
0255 }
0256
0257 static int pcxhr_start_pipes(struct pcxhr_mgr *mgr)
0258 {
0259 int i, j;
0260 struct snd_pcxhr *chip;
0261 int playback_mask = 0;
0262 int capture_mask = 0;
0263
0264
0265 for (i = 0; i < mgr->num_cards; i++) {
0266 chip = mgr->chip[i];
0267 if (chip->nb_streams_play)
0268 playback_mask |= 1 << chip->playback_pipe.first_audio;
0269 for (j = 0; j < chip->nb_streams_capt; j++)
0270 capture_mask |= 1 << chip->capture_pipe[j].first_audio;
0271 }
0272 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
0273 }
0274
0275
0276 static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index,
0277 const struct firmware *dsp)
0278 {
0279 int err, card_index;
0280
0281 dev_dbg(&mgr->pci->dev,
0282 "loading dsp [%d] size = %zd\n", index, dsp->size);
0283
0284 switch (index) {
0285 case PCXHR_FIRMWARE_XLX_INT_INDEX:
0286 pcxhr_reset_xilinx_com(mgr);
0287 return pcxhr_load_xilinx_binary(mgr, dsp, 0);
0288
0289 case PCXHR_FIRMWARE_XLX_COM_INDEX:
0290 pcxhr_reset_xilinx_com(mgr);
0291 return pcxhr_load_xilinx_binary(mgr, dsp, 1);
0292
0293 case PCXHR_FIRMWARE_DSP_EPRM_INDEX:
0294 pcxhr_reset_dsp(mgr);
0295 return pcxhr_load_eeprom_binary(mgr, dsp);
0296
0297 case PCXHR_FIRMWARE_DSP_BOOT_INDEX:
0298 return pcxhr_load_boot_binary(mgr, dsp);
0299
0300 case PCXHR_FIRMWARE_DSP_MAIN_INDEX:
0301 err = pcxhr_load_dsp_binary(mgr, dsp);
0302 if (err)
0303 return err;
0304 break;
0305 default:
0306 dev_err(&mgr->pci->dev, "wrong file index\n");
0307 return -EFAULT;
0308 }
0309
0310
0311 err = pcxhr_init_board(mgr);
0312 if (err < 0) {
0313 dev_err(&mgr->pci->dev, "pcxhr could not be set up\n");
0314 return err;
0315 }
0316 err = pcxhr_config_pipes(mgr);
0317 if (err < 0) {
0318 dev_err(&mgr->pci->dev, "pcxhr pipes could not be set up\n");
0319 return err;
0320 }
0321
0322 for (card_index = 0; card_index < mgr->num_cards; card_index++) {
0323 struct snd_pcxhr *chip = mgr->chip[card_index];
0324
0325 err = pcxhr_create_pcm(chip);
0326 if (err < 0)
0327 return err;
0328
0329 if (card_index == 0) {
0330 err = pcxhr_create_mixer(chip->mgr);
0331 if (err < 0)
0332 return err;
0333 }
0334 err = snd_card_register(chip->card);
0335 if (err < 0)
0336 return err;
0337 }
0338 err = pcxhr_start_pipes(mgr);
0339 if (err < 0) {
0340 dev_err(&mgr->pci->dev, "pcxhr pipes could not be started\n");
0341 return err;
0342 }
0343 dev_dbg(&mgr->pci->dev,
0344 "pcxhr firmware downloaded and successfully set up\n");
0345
0346 return 0;
0347 }
0348
0349
0350
0351
0352 int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
0353 {
0354 static const char * const fw_files[][5] = {
0355 [0] = { "xlxint.dat", "xlxc882hr.dat",
0356 "dspe882.e56", "dspb882hr.b56", "dspd882.d56" },
0357 [1] = { "xlxint.dat", "xlxc882e.dat",
0358 "dspe882.e56", "dspb882e.b56", "dspd882.d56" },
0359 [2] = { "xlxint.dat", "xlxc1222hr.dat",
0360 "dspe882.e56", "dspb1222hr.b56", "dspd1222.d56" },
0361 [3] = { "xlxint.dat", "xlxc1222e.dat",
0362 "dspe882.e56", "dspb1222e.b56", "dspd1222.d56" },
0363 [4] = { NULL, "xlxc222.dat",
0364 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
0365 [5] = { NULL, "xlxc924.dat",
0366 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
0367 };
0368 char path[32];
0369
0370 const struct firmware *fw_entry;
0371 int i, err;
0372 int fw_set = mgr->fw_file_set;
0373
0374 for (i = 0; i < 5; i++) {
0375 if (!fw_files[fw_set][i])
0376 continue;
0377 sprintf(path, "pcxhr/%s", fw_files[fw_set][i]);
0378 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
0379 dev_err(&mgr->pci->dev,
0380 "pcxhr: can't load firmware %s\n",
0381 path);
0382 return -ENOENT;
0383 }
0384
0385 err = pcxhr_dsp_load(mgr, i, fw_entry);
0386 release_firmware(fw_entry);
0387 if (err < 0)
0388 return err;
0389 mgr->dsp_loaded |= 1 << i;
0390 }
0391 return 0;
0392 }
0393
0394 MODULE_FIRMWARE("pcxhr/xlxint.dat");
0395 MODULE_FIRMWARE("pcxhr/xlxc882hr.dat");
0396 MODULE_FIRMWARE("pcxhr/xlxc882e.dat");
0397 MODULE_FIRMWARE("pcxhr/dspe882.e56");
0398 MODULE_FIRMWARE("pcxhr/dspb882hr.b56");
0399 MODULE_FIRMWARE("pcxhr/dspb882e.b56");
0400 MODULE_FIRMWARE("pcxhr/dspd882.d56");
0401
0402 MODULE_FIRMWARE("pcxhr/xlxc1222hr.dat");
0403 MODULE_FIRMWARE("pcxhr/xlxc1222e.dat");
0404 MODULE_FIRMWARE("pcxhr/dspb1222hr.b56");
0405 MODULE_FIRMWARE("pcxhr/dspb1222e.b56");
0406 MODULE_FIRMWARE("pcxhr/dspd1222.d56");
0407
0408 MODULE_FIRMWARE("pcxhr/xlxc222.dat");
0409 MODULE_FIRMWARE("pcxhr/xlxc924.dat");
0410 MODULE_FIRMWARE("pcxhr/dspe924.e56");
0411 MODULE_FIRMWARE("pcxhr/dspb924.b56");
0412 MODULE_FIRMWARE("pcxhr/dspd222.d56");