0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/delay.h>
0013 #include <linux/init.h>
0014 #include <linux/slab.h>
0015 #include <linux/module.h>
0016 #include <sound/core.h>
0017 #include <sound/control.h>
0018 #include <sound/info.h>
0019 #include <sound/sb16_csp.h>
0020 #include <sound/initval.h>
0021
0022 MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
0023 MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
0024 MODULE_LICENSE("GPL");
0025 MODULE_FIRMWARE("sb16/mulaw_main.csp");
0026 MODULE_FIRMWARE("sb16/alaw_main.csp");
0027 MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
0028 MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
0029 MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
0030
0031 #ifdef SNDRV_LITTLE_ENDIAN
0032 #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
0033 #else
0034 #define CSP_HDR_VALUE(a,b,c,d) ((d) | ((c)<<8) | ((b)<<16) | ((a)<<24))
0035 #endif
0036
0037 #define RIFF_HEADER CSP_HDR_VALUE('R', 'I', 'F', 'F')
0038 #define CSP__HEADER CSP_HDR_VALUE('C', 'S', 'P', ' ')
0039 #define LIST_HEADER CSP_HDR_VALUE('L', 'I', 'S', 'T')
0040 #define FUNC_HEADER CSP_HDR_VALUE('f', 'u', 'n', 'c')
0041 #define CODE_HEADER CSP_HDR_VALUE('c', 'o', 'd', 'e')
0042 #define INIT_HEADER CSP_HDR_VALUE('i', 'n', 'i', 't')
0043 #define MAIN_HEADER CSP_HDR_VALUE('m', 'a', 'i', 'n')
0044
0045
0046
0047
0048 struct riff_header {
0049 __le32 name;
0050 __le32 len;
0051 };
0052
0053 struct desc_header {
0054 struct riff_header info;
0055 __le16 func_nr;
0056 __le16 VOC_type;
0057 __le16 flags_play_rec;
0058 __le16 flags_16bit_8bit;
0059 __le16 flags_stereo_mono;
0060 __le16 flags_rates;
0061 };
0062
0063
0064
0065
0066 static void snd_sb_csp_free(struct snd_hwdep *hw);
0067 static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file);
0068 static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg);
0069 static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file);
0070
0071 static int csp_detect(struct snd_sb *chip, int *version);
0072 static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val);
0073 static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val);
0074 static int read_register(struct snd_sb *chip, unsigned char reg);
0075 static int set_mode_register(struct snd_sb *chip, unsigned char mode);
0076 static int get_version(struct snd_sb *chip);
0077
0078 static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
0079 struct snd_sb_csp_microcode __user * code);
0080 static int snd_sb_csp_unload(struct snd_sb_csp * p);
0081 static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags);
0082 static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode);
0083 static int snd_sb_csp_check_version(struct snd_sb_csp * p);
0084
0085 static int snd_sb_csp_use(struct snd_sb_csp * p);
0086 static int snd_sb_csp_unuse(struct snd_sb_csp * p);
0087 static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels);
0088 static int snd_sb_csp_stop(struct snd_sb_csp * p);
0089 static int snd_sb_csp_pause(struct snd_sb_csp * p);
0090 static int snd_sb_csp_restart(struct snd_sb_csp * p);
0091
0092 static int snd_sb_qsound_build(struct snd_sb_csp * p);
0093 static void snd_sb_qsound_destroy(struct snd_sb_csp * p);
0094 static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p);
0095
0096 static int init_proc_entry(struct snd_sb_csp * p, int device);
0097 static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
0098
0099
0100
0101
0102 int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
0103 {
0104 struct snd_sb_csp *p;
0105 int version;
0106 int err;
0107 struct snd_hwdep *hw;
0108
0109 if (rhwdep)
0110 *rhwdep = NULL;
0111
0112 if (csp_detect(chip, &version))
0113 return -ENODEV;
0114
0115 err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw);
0116 if (err < 0)
0117 return err;
0118
0119 p = kzalloc(sizeof(*p), GFP_KERNEL);
0120 if (!p) {
0121 snd_device_free(chip->card, hw);
0122 return -ENOMEM;
0123 }
0124 p->chip = chip;
0125 p->version = version;
0126
0127
0128 p->ops.csp_use = snd_sb_csp_use;
0129 p->ops.csp_unuse = snd_sb_csp_unuse;
0130 p->ops.csp_autoload = snd_sb_csp_autoload;
0131 p->ops.csp_start = snd_sb_csp_start;
0132 p->ops.csp_stop = snd_sb_csp_stop;
0133 p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer;
0134
0135 mutex_init(&p->access_mutex);
0136 sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f));
0137 hw->iface = SNDRV_HWDEP_IFACE_SB16CSP;
0138 hw->private_data = p;
0139 hw->private_free = snd_sb_csp_free;
0140
0141
0142 hw->ops.open = snd_sb_csp_open;
0143 hw->ops.ioctl = snd_sb_csp_ioctl;
0144 hw->ops.release = snd_sb_csp_release;
0145
0146
0147 init_proc_entry(p, device);
0148 if (rhwdep)
0149 *rhwdep = hw;
0150 return 0;
0151 }
0152
0153
0154
0155
0156 static void snd_sb_csp_free(struct snd_hwdep *hwdep)
0157 {
0158 int i;
0159 struct snd_sb_csp *p = hwdep->private_data;
0160 if (p) {
0161 if (p->running & SNDRV_SB_CSP_ST_RUNNING)
0162 snd_sb_csp_stop(p);
0163 for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
0164 release_firmware(p->csp_programs[i]);
0165 kfree(p);
0166 }
0167 }
0168
0169
0170
0171
0172
0173
0174 static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file)
0175 {
0176 struct snd_sb_csp *p = hw->private_data;
0177 return (snd_sb_csp_use(p));
0178 }
0179
0180
0181
0182
0183 static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
0184 {
0185 struct snd_sb_csp *p = hw->private_data;
0186 struct snd_sb_csp_info info;
0187 struct snd_sb_csp_start start_info;
0188 int err;
0189
0190 if (snd_BUG_ON(!p))
0191 return -EINVAL;
0192
0193 if (snd_sb_csp_check_version(p))
0194 return -ENODEV;
0195
0196 switch (cmd) {
0197
0198 case SNDRV_SB_CSP_IOCTL_INFO:
0199 memset(&info, 0, sizeof(info));
0200 *info.codec_name = *p->codec_name;
0201 info.func_nr = p->func_nr;
0202 info.acc_format = p->acc_format;
0203 info.acc_channels = p->acc_channels;
0204 info.acc_width = p->acc_width;
0205 info.acc_rates = p->acc_rates;
0206 info.csp_mode = p->mode;
0207 info.run_channels = p->run_channels;
0208 info.run_width = p->run_width;
0209 info.version = p->version;
0210 info.state = p->running;
0211 if (copy_to_user((void __user *)arg, &info, sizeof(info)))
0212 err = -EFAULT;
0213 else
0214 err = 0;
0215 break;
0216
0217
0218 case SNDRV_SB_CSP_IOCTL_LOAD_CODE:
0219 err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
0220 -EBUSY : snd_sb_csp_riff_load(p, (struct snd_sb_csp_microcode __user *) arg));
0221 break;
0222 case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE:
0223 err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
0224 -EBUSY : snd_sb_csp_unload(p));
0225 break;
0226
0227
0228 case SNDRV_SB_CSP_IOCTL_START:
0229 if (copy_from_user(&start_info, (void __user *) arg, sizeof(start_info)))
0230 err = -EFAULT;
0231 else
0232 err = snd_sb_csp_start(p, start_info.sample_width, start_info.channels);
0233 break;
0234 case SNDRV_SB_CSP_IOCTL_STOP:
0235 err = snd_sb_csp_stop(p);
0236 break;
0237 case SNDRV_SB_CSP_IOCTL_PAUSE:
0238 err = snd_sb_csp_pause(p);
0239 break;
0240 case SNDRV_SB_CSP_IOCTL_RESTART:
0241 err = snd_sb_csp_restart(p);
0242 break;
0243 default:
0244 err = -ENOTTY;
0245 break;
0246 }
0247
0248 return err;
0249 }
0250
0251
0252
0253
0254 static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file)
0255 {
0256 struct snd_sb_csp *p = hw->private_data;
0257 return (snd_sb_csp_unuse(p));
0258 }
0259
0260
0261
0262
0263
0264
0265 static int snd_sb_csp_use(struct snd_sb_csp * p)
0266 {
0267 mutex_lock(&p->access_mutex);
0268 if (p->used) {
0269 mutex_unlock(&p->access_mutex);
0270 return -EAGAIN;
0271 }
0272 p->used++;
0273 mutex_unlock(&p->access_mutex);
0274
0275 return 0;
0276
0277 }
0278
0279
0280
0281
0282 static int snd_sb_csp_unuse(struct snd_sb_csp * p)
0283 {
0284 mutex_lock(&p->access_mutex);
0285 p->used--;
0286 mutex_unlock(&p->access_mutex);
0287
0288 return 0;
0289 }
0290
0291
0292
0293
0294
0295 static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
0296 struct snd_sb_csp_microcode __user * mcode)
0297 {
0298 struct snd_sb_csp_mc_header info;
0299
0300 unsigned char __user *data_ptr;
0301 unsigned char __user *data_end;
0302 unsigned short func_nr = 0;
0303
0304 struct riff_header file_h, item_h, code_h;
0305 __le32 item_type;
0306 struct desc_header funcdesc_h;
0307
0308 unsigned long flags;
0309 int err;
0310
0311 if (copy_from_user(&info, mcode, sizeof(info)))
0312 return -EFAULT;
0313 data_ptr = mcode->data;
0314
0315 if (copy_from_user(&file_h, data_ptr, sizeof(file_h)))
0316 return -EFAULT;
0317 if ((le32_to_cpu(file_h.name) != RIFF_HEADER) ||
0318 (le32_to_cpu(file_h.len) >= SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE - sizeof(file_h))) {
0319 snd_printd("%s: Invalid RIFF header\n", __func__);
0320 return -EINVAL;
0321 }
0322 data_ptr += sizeof(file_h);
0323 data_end = data_ptr + le32_to_cpu(file_h.len);
0324
0325 if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
0326 return -EFAULT;
0327 if (le32_to_cpu(item_type) != CSP__HEADER) {
0328 snd_printd("%s: Invalid RIFF file type\n", __func__);
0329 return -EINVAL;
0330 }
0331 data_ptr += sizeof (item_type);
0332
0333 for (; data_ptr < data_end; data_ptr += le32_to_cpu(item_h.len)) {
0334 if (copy_from_user(&item_h, data_ptr, sizeof(item_h)))
0335 return -EFAULT;
0336 data_ptr += sizeof(item_h);
0337 if (le32_to_cpu(item_h.name) != LIST_HEADER)
0338 continue;
0339
0340 if (copy_from_user(&item_type, data_ptr, sizeof(item_type)))
0341 return -EFAULT;
0342 switch (le32_to_cpu(item_type)) {
0343 case FUNC_HEADER:
0344 if (copy_from_user(&funcdesc_h, data_ptr + sizeof(item_type), sizeof(funcdesc_h)))
0345 return -EFAULT;
0346 func_nr = le16_to_cpu(funcdesc_h.func_nr);
0347 break;
0348 case CODE_HEADER:
0349 if (func_nr != info.func_req)
0350 break;
0351 data_ptr += sizeof(item_type);
0352
0353
0354 if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
0355 snd_sb_qsound_destroy(p);
0356 }
0357
0358 p->running = 0;
0359 p->mode = 0;
0360
0361
0362 for (;;) {
0363 if (data_ptr >= data_end)
0364 return -EINVAL;
0365 if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
0366 return -EFAULT;
0367
0368
0369 if (le32_to_cpu(code_h.name) != INIT_HEADER)
0370 break;
0371 data_ptr += sizeof(code_h);
0372 err = snd_sb_csp_load_user(p, data_ptr, le32_to_cpu(code_h.len),
0373 SNDRV_SB_CSP_LOAD_INITBLOCK);
0374 if (err)
0375 return err;
0376 data_ptr += le32_to_cpu(code_h.len);
0377 }
0378
0379 if (copy_from_user(&code_h, data_ptr, sizeof(code_h)))
0380 return -EFAULT;
0381
0382 if (le32_to_cpu(code_h.name) != MAIN_HEADER) {
0383 snd_printd("%s: Missing 'main' microcode\n", __func__);
0384 return -EINVAL;
0385 }
0386 data_ptr += sizeof(code_h);
0387 err = snd_sb_csp_load_user(p, data_ptr,
0388 le32_to_cpu(code_h.len), 0);
0389 if (err)
0390 return err;
0391
0392
0393 strscpy(p->codec_name, info.codec_name, sizeof(p->codec_name));
0394 p->func_nr = func_nr;
0395 p->mode = le16_to_cpu(funcdesc_h.flags_play_rec);
0396 switch (le16_to_cpu(funcdesc_h.VOC_type)) {
0397 case 0x0001:
0398 if (le16_to_cpu(funcdesc_h.flags_play_rec) == SNDRV_SB_CSP_MODE_DSP_WRITE) {
0399 if (snd_sb_qsound_build(p) == 0)
0400
0401 p->mode = SNDRV_SB_CSP_MODE_QSOUND;
0402 }
0403 p->acc_format = 0;
0404 break;
0405 case 0x0006:
0406 p->acc_format = SNDRV_PCM_FMTBIT_A_LAW;
0407 break;
0408 case 0x0007:
0409 p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW;
0410 break;
0411 case 0x0011:
0412 case 0x0200:
0413 p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;
0414 break;
0415 case 201:
0416
0417 p->acc_format = 0;
0418 break;
0419 case 0x0202:
0420 case 0x0203:
0421 p->acc_format = SNDRV_PCM_FMTBIT_SPECIAL;
0422 break;
0423 default:
0424 p->acc_format = p->acc_width = p->acc_rates = 0;
0425 p->mode = 0;
0426 snd_printd("%s: Unsupported CSP codec type: 0x%04x\n",
0427 __func__,
0428 le16_to_cpu(funcdesc_h.VOC_type));
0429 return -EINVAL;
0430 }
0431 p->acc_channels = le16_to_cpu(funcdesc_h.flags_stereo_mono);
0432 p->acc_width = le16_to_cpu(funcdesc_h.flags_16bit_8bit);
0433 p->acc_rates = le16_to_cpu(funcdesc_h.flags_rates);
0434
0435
0436 spin_lock_irqsave(&p->chip->reg_lock, flags);
0437 set_mode_register(p->chip, 0xfc);
0438 set_mode_register(p->chip, 0x00);
0439 spin_unlock_irqrestore(&p->chip->reg_lock, flags);
0440
0441
0442 p->running = SNDRV_SB_CSP_ST_LOADED;
0443 return 0;
0444 }
0445 }
0446 snd_printd("%s: Function #%d not found\n", __func__, info.func_req);
0447 return -EINVAL;
0448 }
0449
0450
0451
0452
0453 static int snd_sb_csp_unload(struct snd_sb_csp * p)
0454 {
0455 if (p->running & SNDRV_SB_CSP_ST_RUNNING)
0456 return -EBUSY;
0457 if (!(p->running & SNDRV_SB_CSP_ST_LOADED))
0458 return -ENXIO;
0459
0460
0461 p->acc_format = 0;
0462 p->acc_channels = p->acc_width = p->acc_rates = 0;
0463
0464 if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
0465 snd_sb_qsound_destroy(p);
0466 }
0467
0468 p->running = 0;
0469 p->mode = 0;
0470 return 0;
0471 }
0472
0473
0474
0475
0476 static inline int command_seq(struct snd_sb *chip, const unsigned char *seq, int size)
0477 {
0478 int i;
0479 for (i = 0; i < size; i++) {
0480 if (!snd_sbdsp_command(chip, seq[i]))
0481 return -EIO;
0482 }
0483 return 0;
0484 }
0485
0486
0487
0488
0489 static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val)
0490 {
0491 unsigned char dsp_cmd[3];
0492
0493 dsp_cmd[0] = 0x05;
0494 dsp_cmd[1] = val;
0495 dsp_cmd[2] = par;
0496 command_seq(chip, dsp_cmd, 3);
0497 snd_sbdsp_command(chip, 0x03);
0498 if (snd_sbdsp_get_byte(chip) != par)
0499 return -EIO;
0500 return 0;
0501 }
0502
0503
0504
0505
0506 static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val)
0507 {
0508 unsigned char dsp_cmd[3];
0509
0510 dsp_cmd[0] = 0x0e;
0511 dsp_cmd[1] = reg;
0512 dsp_cmd[2] = val;
0513 return command_seq(chip, dsp_cmd, 3);
0514 }
0515
0516
0517
0518
0519
0520 static int read_register(struct snd_sb *chip, unsigned char reg)
0521 {
0522 unsigned char dsp_cmd[2];
0523
0524 dsp_cmd[0] = 0x0f;
0525 dsp_cmd[1] = reg;
0526 command_seq(chip, dsp_cmd, 2);
0527 return snd_sbdsp_get_byte(chip);
0528 }
0529
0530
0531
0532
0533 static int set_mode_register(struct snd_sb *chip, unsigned char mode)
0534 {
0535 unsigned char dsp_cmd[2];
0536
0537 dsp_cmd[0] = 0x04;
0538 dsp_cmd[1] = mode;
0539 return command_seq(chip, dsp_cmd, 2);
0540 }
0541
0542
0543
0544
0545
0546 static int csp_detect(struct snd_sb *chip, int *version)
0547 {
0548 unsigned char csp_test1, csp_test2;
0549 unsigned long flags;
0550 int result = -ENODEV;
0551
0552 spin_lock_irqsave(&chip->reg_lock, flags);
0553
0554 set_codec_parameter(chip, 0x00, 0x00);
0555 set_mode_register(chip, 0xfc);
0556
0557 csp_test1 = read_register(chip, 0x83);
0558 set_register(chip, 0x83, ~csp_test1);
0559 csp_test2 = read_register(chip, 0x83);
0560 if (csp_test2 != (csp_test1 ^ 0xff))
0561 goto __fail;
0562
0563 set_register(chip, 0x83, csp_test1);
0564 csp_test2 = read_register(chip, 0x83);
0565 if (csp_test2 != csp_test1)
0566 goto __fail;
0567
0568 set_mode_register(chip, 0x00);
0569
0570 *version = get_version(chip);
0571 snd_sbdsp_reset(chip);
0572 if (*version >= 0x10 && *version <= 0x1f)
0573 result = 0;
0574
0575 __fail:
0576 spin_unlock_irqrestore(&chip->reg_lock, flags);
0577 return result;
0578 }
0579
0580
0581
0582
0583 static int get_version(struct snd_sb *chip)
0584 {
0585 unsigned char dsp_cmd[2];
0586
0587 dsp_cmd[0] = 0x08;
0588 dsp_cmd[1] = 0x03;
0589 command_seq(chip, dsp_cmd, 2);
0590
0591 return (snd_sbdsp_get_byte(chip));
0592 }
0593
0594
0595
0596
0597 static int snd_sb_csp_check_version(struct snd_sb_csp * p)
0598 {
0599 if (p->version < 0x10 || p->version > 0x1f) {
0600 snd_printd("%s: Invalid CSP version: 0x%x\n", __func__, p->version);
0601 return 1;
0602 }
0603 return 0;
0604 }
0605
0606
0607
0608
0609 static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int size, int load_flags)
0610 {
0611 int status, i;
0612 int err;
0613 int result = -EIO;
0614 unsigned long flags;
0615
0616 spin_lock_irqsave(&p->chip->reg_lock, flags);
0617 snd_sbdsp_command(p->chip, 0x01);
0618 if (snd_sbdsp_get_byte(p->chip)) {
0619 snd_printd("%s: Download command failed\n", __func__);
0620 goto __fail;
0621 }
0622
0623 snd_sbdsp_command(p->chip, (unsigned char)(size - 1));
0624
0625 snd_sbdsp_command(p->chip, (unsigned char)((size - 1) >> 8));
0626
0627
0628 while (size--) {
0629 if (!snd_sbdsp_command(p->chip, *buf++))
0630 goto __fail;
0631 }
0632 if (snd_sbdsp_get_byte(p->chip))
0633 goto __fail;
0634
0635 if (load_flags & SNDRV_SB_CSP_LOAD_INITBLOCK) {
0636 i = 0;
0637
0638 while (1) {
0639 snd_sbdsp_command(p->chip, 0x03);
0640 status = snd_sbdsp_get_byte(p->chip);
0641 if (status == 0x55 || ++i >= 10)
0642 break;
0643 udelay (10);
0644 }
0645 if (status != 0x55) {
0646 snd_printd("%s: Microcode initialization failed\n", __func__);
0647 goto __fail;
0648 }
0649 } else {
0650
0651
0652
0653
0654
0655 spin_lock(&p->chip->mixer_lock);
0656 status = snd_sbmixer_read(p->chip, SB_DSP4_DMASETUP);
0657 spin_unlock(&p->chip->mixer_lock);
0658 if (!(status & (SB_DMASETUP_DMA7 | SB_DMASETUP_DMA6 | SB_DMASETUP_DMA5))) {
0659 err = (set_codec_parameter(p->chip, 0xaa, 0x00) ||
0660 set_codec_parameter(p->chip, 0xff, 0x00));
0661 snd_sbdsp_reset(p->chip);
0662 if (err)
0663 goto __fail;
0664 set_mode_register(p->chip, 0xc0);
0665 set_mode_register(p->chip, 0x70);
0666 }
0667 }
0668 result = 0;
0669
0670 __fail:
0671 spin_unlock_irqrestore(&p->chip->reg_lock, flags);
0672 return result;
0673 }
0674
0675 static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
0676 {
0677 int err;
0678 unsigned char *kbuf;
0679
0680 kbuf = memdup_user(buf, size);
0681 if (IS_ERR(kbuf))
0682 return PTR_ERR(kbuf);
0683
0684 err = snd_sb_csp_load(p, kbuf, size, load_flags);
0685
0686 kfree(kbuf);
0687 return err;
0688 }
0689
0690 static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
0691 {
0692 static const char *const names[] = {
0693 "sb16/mulaw_main.csp",
0694 "sb16/alaw_main.csp",
0695 "sb16/ima_adpcm_init.csp",
0696 "sb16/ima_adpcm_playback.csp",
0697 "sb16/ima_adpcm_capture.csp",
0698 };
0699 const struct firmware *program;
0700
0701 BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
0702 program = p->csp_programs[index];
0703 if (!program) {
0704 int err = request_firmware(&program, names[index],
0705 p->chip->card->dev);
0706 if (err < 0)
0707 return err;
0708 p->csp_programs[index] = program;
0709 }
0710 return snd_sb_csp_load(p, program->data, program->size, flags);
0711 }
0712
0713
0714
0715
0716
0717 static int snd_sb_csp_autoload(struct snd_sb_csp * p, snd_pcm_format_t pcm_sfmt, int play_rec_mode)
0718 {
0719 unsigned long flags;
0720 int err = 0;
0721
0722
0723 if (p->running & (SNDRV_SB_CSP_ST_RUNNING | SNDRV_SB_CSP_ST_LOADED))
0724 return -EBUSY;
0725
0726
0727 if (((1U << (__force int)pcm_sfmt) & p->acc_format) && (play_rec_mode & p->mode)) {
0728 p->running = SNDRV_SB_CSP_ST_AUTO;
0729 } else {
0730 switch (pcm_sfmt) {
0731 case SNDRV_PCM_FORMAT_MU_LAW:
0732 err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_MULAW, 0);
0733 p->acc_format = SNDRV_PCM_FMTBIT_MU_LAW;
0734 p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE;
0735 break;
0736 case SNDRV_PCM_FORMAT_A_LAW:
0737 err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ALAW, 0);
0738 p->acc_format = SNDRV_PCM_FMTBIT_A_LAW;
0739 p->mode = SNDRV_SB_CSP_MODE_DSP_READ | SNDRV_SB_CSP_MODE_DSP_WRITE;
0740 break;
0741 case SNDRV_PCM_FORMAT_IMA_ADPCM:
0742 err = snd_sb_csp_firmware_load(p, CSP_PROGRAM_ADPCM_INIT,
0743 SNDRV_SB_CSP_LOAD_INITBLOCK);
0744 if (err)
0745 break;
0746 if (play_rec_mode == SNDRV_SB_CSP_MODE_DSP_WRITE) {
0747 err = snd_sb_csp_firmware_load
0748 (p, CSP_PROGRAM_ADPCM_PLAYBACK, 0);
0749 p->mode = SNDRV_SB_CSP_MODE_DSP_WRITE;
0750 } else {
0751 err = snd_sb_csp_firmware_load
0752 (p, CSP_PROGRAM_ADPCM_CAPTURE, 0);
0753 p->mode = SNDRV_SB_CSP_MODE_DSP_READ;
0754 }
0755 p->acc_format = SNDRV_PCM_FMTBIT_IMA_ADPCM;
0756 break;
0757 default:
0758
0759 if (p->running & SNDRV_SB_CSP_ST_AUTO) {
0760 spin_lock_irqsave(&p->chip->reg_lock, flags);
0761 set_mode_register(p->chip, 0xfc);
0762 set_mode_register(p->chip, 0x00);
0763 spin_unlock_irqrestore(&p->chip->reg_lock, flags);
0764 p->running = 0;
0765 }
0766 return -EINVAL;
0767 }
0768 if (err) {
0769 p->acc_format = 0;
0770 p->acc_channels = p->acc_width = p->acc_rates = 0;
0771
0772 p->running = 0;
0773 p->mode = 0;
0774 return (err);
0775 } else {
0776 p->running = SNDRV_SB_CSP_ST_AUTO;
0777 p->acc_width = SNDRV_SB_CSP_SAMPLE_16BIT;
0778 p->acc_channels = SNDRV_SB_CSP_MONO | SNDRV_SB_CSP_STEREO;
0779 p->acc_rates = SNDRV_SB_CSP_RATE_ALL;
0780 }
0781
0782 }
0783 return (p->running & SNDRV_SB_CSP_ST_AUTO) ? 0 : -ENXIO;
0784 }
0785
0786
0787
0788
0789 static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels)
0790 {
0791 unsigned char s_type;
0792 unsigned char mixL, mixR;
0793 int result = -EIO;
0794 unsigned long flags;
0795
0796 if (!(p->running & (SNDRV_SB_CSP_ST_LOADED | SNDRV_SB_CSP_ST_AUTO))) {
0797 snd_printd("%s: Microcode not loaded\n", __func__);
0798 return -ENXIO;
0799 }
0800 if (p->running & SNDRV_SB_CSP_ST_RUNNING) {
0801 snd_printd("%s: CSP already running\n", __func__);
0802 return -EBUSY;
0803 }
0804 if (!(sample_width & p->acc_width)) {
0805 snd_printd("%s: Unsupported PCM sample width\n", __func__);
0806 return -EINVAL;
0807 }
0808 if (!(channels & p->acc_channels)) {
0809 snd_printd("%s: Invalid number of channels\n", __func__);
0810 return -EINVAL;
0811 }
0812
0813
0814 spin_lock_irqsave(&p->chip->mixer_lock, flags);
0815 mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
0816 mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
0817 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
0818 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
0819 spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
0820
0821 spin_lock(&p->chip->reg_lock);
0822 set_mode_register(p->chip, 0xc0);
0823 set_mode_register(p->chip, 0x70);
0824
0825 s_type = 0x00;
0826 if (channels == SNDRV_SB_CSP_MONO)
0827 s_type = 0x11;
0828 if (sample_width == SNDRV_SB_CSP_SAMPLE_8BIT)
0829 s_type |= 0x22;
0830
0831 if (set_codec_parameter(p->chip, 0x81, s_type)) {
0832 snd_printd("%s: Set sample type command failed\n", __func__);
0833 goto __fail;
0834 }
0835 if (set_codec_parameter(p->chip, 0x80, 0x00)) {
0836 snd_printd("%s: Codec start command failed\n", __func__);
0837 goto __fail;
0838 }
0839 p->run_width = sample_width;
0840 p->run_channels = channels;
0841
0842 p->running |= SNDRV_SB_CSP_ST_RUNNING;
0843
0844 if (p->mode & SNDRV_SB_CSP_MODE_QSOUND) {
0845 set_codec_parameter(p->chip, 0xe0, 0x01);
0846
0847 set_codec_parameter(p->chip, 0x00, 0xff);
0848 set_codec_parameter(p->chip, 0x01, 0xff);
0849 p->running |= SNDRV_SB_CSP_ST_QSOUND;
0850
0851 snd_sb_csp_qsound_transfer(p);
0852 }
0853 result = 0;
0854
0855 __fail:
0856 spin_unlock(&p->chip->reg_lock);
0857
0858
0859 spin_lock_irqsave(&p->chip->mixer_lock, flags);
0860 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
0861 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
0862 spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
0863
0864 return result;
0865 }
0866
0867
0868
0869
0870 static int snd_sb_csp_stop(struct snd_sb_csp * p)
0871 {
0872 int result;
0873 unsigned char mixL, mixR;
0874 unsigned long flags;
0875
0876 if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
0877 return 0;
0878
0879
0880 spin_lock_irqsave(&p->chip->mixer_lock, flags);
0881 mixL = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV);
0882 mixR = snd_sbmixer_read(p->chip, SB_DSP4_PCM_DEV + 1);
0883 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL & 0x7);
0884 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR & 0x7);
0885 spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
0886
0887 spin_lock(&p->chip->reg_lock);
0888 if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
0889 set_codec_parameter(p->chip, 0xe0, 0x01);
0890
0891 set_codec_parameter(p->chip, 0x00, 0x00);
0892 set_codec_parameter(p->chip, 0x01, 0x00);
0893
0894 p->running &= ~SNDRV_SB_CSP_ST_QSOUND;
0895 }
0896 result = set_mode_register(p->chip, 0xc0);
0897 spin_unlock(&p->chip->reg_lock);
0898
0899
0900 spin_lock_irqsave(&p->chip->mixer_lock, flags);
0901 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV, mixL);
0902 snd_sbmixer_write(p->chip, SB_DSP4_PCM_DEV + 1, mixR);
0903 spin_unlock_irqrestore(&p->chip->mixer_lock, flags);
0904
0905 if (!(result))
0906 p->running &= ~(SNDRV_SB_CSP_ST_PAUSED | SNDRV_SB_CSP_ST_RUNNING);
0907 return result;
0908 }
0909
0910
0911
0912
0913 static int snd_sb_csp_pause(struct snd_sb_csp * p)
0914 {
0915 int result;
0916 unsigned long flags;
0917
0918 if (!(p->running & SNDRV_SB_CSP_ST_RUNNING))
0919 return -EBUSY;
0920
0921 spin_lock_irqsave(&p->chip->reg_lock, flags);
0922 result = set_codec_parameter(p->chip, 0x80, 0xff);
0923 spin_unlock_irqrestore(&p->chip->reg_lock, flags);
0924 if (!(result))
0925 p->running |= SNDRV_SB_CSP_ST_PAUSED;
0926
0927 return result;
0928 }
0929
0930
0931
0932
0933 static int snd_sb_csp_restart(struct snd_sb_csp * p)
0934 {
0935 int result;
0936 unsigned long flags;
0937
0938 if (!(p->running & SNDRV_SB_CSP_ST_PAUSED))
0939 return -EBUSY;
0940
0941 spin_lock_irqsave(&p->chip->reg_lock, flags);
0942 result = set_codec_parameter(p->chip, 0x80, 0x00);
0943 spin_unlock_irqrestore(&p->chip->reg_lock, flags);
0944 if (!(result))
0945 p->running &= ~SNDRV_SB_CSP_ST_PAUSED;
0946
0947 return result;
0948 }
0949
0950
0951
0952
0953
0954
0955
0956 #define snd_sb_qsound_switch_info snd_ctl_boolean_mono_info
0957
0958 static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0959 {
0960 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
0961
0962 ucontrol->value.integer.value[0] = p->q_enabled ? 1 : 0;
0963 return 0;
0964 }
0965
0966 static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0967 {
0968 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
0969 unsigned long flags;
0970 int change;
0971 unsigned char nval;
0972
0973 nval = ucontrol->value.integer.value[0] & 0x01;
0974 spin_lock_irqsave(&p->q_lock, flags);
0975 change = p->q_enabled != nval;
0976 p->q_enabled = nval;
0977 spin_unlock_irqrestore(&p->q_lock, flags);
0978 return change;
0979 }
0980
0981 static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
0982 {
0983 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
0984 uinfo->count = 2;
0985 uinfo->value.integer.min = 0;
0986 uinfo->value.integer.max = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
0987 return 0;
0988 }
0989
0990 static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
0991 {
0992 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
0993 unsigned long flags;
0994
0995 spin_lock_irqsave(&p->q_lock, flags);
0996 ucontrol->value.integer.value[0] = p->qpos_left;
0997 ucontrol->value.integer.value[1] = p->qpos_right;
0998 spin_unlock_irqrestore(&p->q_lock, flags);
0999 return 0;
1000 }
1001
1002 static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1003 {
1004 struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
1005 unsigned long flags;
1006 int change;
1007 unsigned char nval1, nval2;
1008
1009 nval1 = ucontrol->value.integer.value[0];
1010 if (nval1 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
1011 nval1 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
1012 nval2 = ucontrol->value.integer.value[1];
1013 if (nval2 > SNDRV_SB_CSP_QSOUND_MAX_RIGHT)
1014 nval2 = SNDRV_SB_CSP_QSOUND_MAX_RIGHT;
1015 spin_lock_irqsave(&p->q_lock, flags);
1016 change = p->qpos_left != nval1 || p->qpos_right != nval2;
1017 p->qpos_left = nval1;
1018 p->qpos_right = nval2;
1019 p->qpos_changed = change;
1020 spin_unlock_irqrestore(&p->q_lock, flags);
1021 return change;
1022 }
1023
1024 static const struct snd_kcontrol_new snd_sb_qsound_switch = {
1025 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1026 .name = "3D Control - Switch",
1027 .info = snd_sb_qsound_switch_info,
1028 .get = snd_sb_qsound_switch_get,
1029 .put = snd_sb_qsound_switch_put
1030 };
1031
1032 static const struct snd_kcontrol_new snd_sb_qsound_space = {
1033 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1034 .name = "3D Control - Space",
1035 .info = snd_sb_qsound_space_info,
1036 .get = snd_sb_qsound_space_get,
1037 .put = snd_sb_qsound_space_put
1038 };
1039
1040 static int snd_sb_qsound_build(struct snd_sb_csp * p)
1041 {
1042 struct snd_card *card;
1043 struct snd_kcontrol *kctl;
1044 int err;
1045
1046 if (snd_BUG_ON(!p))
1047 return -EINVAL;
1048
1049 card = p->chip->card;
1050 p->qpos_left = p->qpos_right = SNDRV_SB_CSP_QSOUND_MAX_RIGHT / 2;
1051 p->qpos_changed = 0;
1052
1053 spin_lock_init(&p->q_lock);
1054
1055 kctl = snd_ctl_new1(&snd_sb_qsound_switch, p);
1056 err = snd_ctl_add(card, kctl);
1057 if (err < 0)
1058 goto __error;
1059 p->qsound_switch = kctl;
1060 kctl = snd_ctl_new1(&snd_sb_qsound_space, p);
1061 err = snd_ctl_add(card, kctl);
1062 if (err < 0)
1063 goto __error;
1064 p->qsound_space = kctl;
1065
1066 return 0;
1067
1068 __error:
1069 snd_sb_qsound_destroy(p);
1070 return err;
1071 }
1072
1073 static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
1074 {
1075 struct snd_card *card;
1076 unsigned long flags;
1077
1078 if (snd_BUG_ON(!p))
1079 return;
1080
1081 card = p->chip->card;
1082
1083 down_write(&card->controls_rwsem);
1084 if (p->qsound_switch) {
1085 snd_ctl_remove(card, p->qsound_switch);
1086 p->qsound_switch = NULL;
1087 }
1088 if (p->qsound_space) {
1089 snd_ctl_remove(card, p->qsound_space);
1090 p->qsound_space = NULL;
1091 }
1092 up_write(&card->controls_rwsem);
1093
1094
1095 spin_lock_irqsave (&p->q_lock, flags);
1096 p->qpos_changed = 0;
1097 spin_unlock_irqrestore (&p->q_lock, flags);
1098 }
1099
1100
1101
1102
1103
1104 static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
1105 {
1106 int err = -ENXIO;
1107
1108 spin_lock(&p->q_lock);
1109 if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
1110 set_codec_parameter(p->chip, 0xe0, 0x01);
1111
1112 set_codec_parameter(p->chip, 0x00, p->qpos_left);
1113 set_codec_parameter(p->chip, 0x02, 0x00);
1114
1115 set_codec_parameter(p->chip, 0x00, p->qpos_right);
1116 set_codec_parameter(p->chip, 0x03, 0x00);
1117 err = 0;
1118 }
1119 p->qpos_changed = 0;
1120 spin_unlock(&p->q_lock);
1121 return err;
1122 }
1123
1124
1125
1126
1127
1128
1129 static int init_proc_entry(struct snd_sb_csp * p, int device)
1130 {
1131 char name[16];
1132
1133 sprintf(name, "cspD%d", device);
1134 snd_card_ro_proc_new(p->chip->card, name, p, info_read);
1135 return 0;
1136 }
1137
1138 static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1139 {
1140 struct snd_sb_csp *p = entry->private_data;
1141
1142 snd_iprintf(buffer, "Creative Signal Processor [v%d.%d]\n", (p->version >> 4), (p->version & 0x0f));
1143 snd_iprintf(buffer, "State: %cx%c%c%c\n", ((p->running & SNDRV_SB_CSP_ST_QSOUND) ? 'Q' : '-'),
1144 ((p->running & SNDRV_SB_CSP_ST_PAUSED) ? 'P' : '-'),
1145 ((p->running & SNDRV_SB_CSP_ST_RUNNING) ? 'R' : '-'),
1146 ((p->running & SNDRV_SB_CSP_ST_LOADED) ? 'L' : '-'));
1147 if (p->running & SNDRV_SB_CSP_ST_LOADED) {
1148 snd_iprintf(buffer, "Codec: %s [func #%d]\n", p->codec_name, p->func_nr);
1149 snd_iprintf(buffer, "Sample rates: ");
1150 if (p->acc_rates == SNDRV_SB_CSP_RATE_ALL) {
1151 snd_iprintf(buffer, "All\n");
1152 } else {
1153 snd_iprintf(buffer, "%s%s%s%s\n",
1154 ((p->acc_rates & SNDRV_SB_CSP_RATE_8000) ? "8000Hz " : ""),
1155 ((p->acc_rates & SNDRV_SB_CSP_RATE_11025) ? "11025Hz " : ""),
1156 ((p->acc_rates & SNDRV_SB_CSP_RATE_22050) ? "22050Hz " : ""),
1157 ((p->acc_rates & SNDRV_SB_CSP_RATE_44100) ? "44100Hz" : ""));
1158 }
1159 if (p->mode == SNDRV_SB_CSP_MODE_QSOUND) {
1160 snd_iprintf(buffer, "QSound decoder %sabled\n",
1161 p->q_enabled ? "en" : "dis");
1162 } else {
1163 snd_iprintf(buffer, "PCM format ID: 0x%x (%s/%s) [%s/%s] [%s/%s]\n",
1164 p->acc_format,
1165 ((p->acc_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? "16bit" : "-"),
1166 ((p->acc_width & SNDRV_SB_CSP_SAMPLE_8BIT) ? "8bit" : "-"),
1167 ((p->acc_channels & SNDRV_SB_CSP_MONO) ? "mono" : "-"),
1168 ((p->acc_channels & SNDRV_SB_CSP_STEREO) ? "stereo" : "-"),
1169 ((p->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) ? "playback" : "-"),
1170 ((p->mode & SNDRV_SB_CSP_MODE_DSP_READ) ? "capture" : "-"));
1171 }
1172 }
1173 if (p->running & SNDRV_SB_CSP_ST_AUTO) {
1174 snd_iprintf(buffer, "Autoloaded Mu-Law, A-Law or Ima-ADPCM hardware codec\n");
1175 }
1176 if (p->running & SNDRV_SB_CSP_ST_RUNNING) {
1177 snd_iprintf(buffer, "Processing %dbit %s PCM samples\n",
1178 ((p->run_width & SNDRV_SB_CSP_SAMPLE_16BIT) ? 16 : 8),
1179 ((p->run_channels & SNDRV_SB_CSP_MONO) ? "mono" : "stereo"));
1180 }
1181 if (p->running & SNDRV_SB_CSP_ST_QSOUND) {
1182 snd_iprintf(buffer, "Qsound position: left = 0x%x, right = 0x%x\n",
1183 p->qpos_left, p->qpos_right);
1184 }
1185 }
1186
1187
1188
1189 EXPORT_SYMBOL(snd_sb_csp_new);