// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver for Gallant SC-6000 soundcard. This card is also known as * Audio Excel DSP 16 or Zoltrix AV302. * These cards use CompuMedia ASC-9308 chip + AD1848 codec. * SC-6600 and SC-7000 cards are also supported. They are based on * CompuMedia ASC-9408 chip and CS4231 codec. * * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl> * * I don't have documentation for this card. I used the driver * for OSS/Free included in the kernel source as reference.
*/
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for sc-6000 based soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable sc-6000 based soundcard.");
module_param_hw_array(port, long, ioport, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for sc-6000 driver.");
module_param_hw_array(mss_port, long, ioport, NULL, 0444);
MODULE_PARM_DESC(mss_port, "MSS Port # for sc-6000 driver.");
module_param_hw_array(mpu_port, long, ioport, NULL, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for sc-6000 driver.");
module_param_hw_array(irq, int, irq, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for sc-6000 driver.");
module_param_hw_array(mpu_irq, int, irq, NULL, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver.");
module_param_hw_array(dma, int, dma, NULL, 0444);
MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver.");
module_param_array(joystick, bool, NULL, 0444);
MODULE_PARM_DESC(joystick, "Enable gameport.");
/* * Commands of SC6000's DSP (SBPRO+special). * Some of them are COMMAND_xx, in the future they may change.
*/ #define WRITE_MDIRQ_CFG 0x50 /* Set M&I&DRQ mask (the real config) */ #define COMMAND_52 0x52 /* */ #define READ_HARD_CFG 0x58 /* Read Hardware Config (I/O base etc) */ #define COMMAND_5C 0x5c /* */ #define COMMAND_60 0x60 /* */ #define COMMAND_66 0x66 /* */ #define COMMAND_6C 0x6c /* */ #define COMMAND_6E 0x6e /* */ #define COMMAND_88 0x88 /* Unknown command */ #define DSP_INIT_MSS 0x8c /* Enable Microsoft Sound System mode */ #define COMMAND_C5 0xc5 /* */ #define GET_DSP_VERSION 0xe1 /* Get DSP Version */ #define GET_DSP_COPYRIGHT 0xe3 /* Get DSP Copyright */
/* * Offsets of SC6000 DSP I/O ports. The offset is added to base I/O port * to have the actual I/O port. * Register permissions are: * (wo) == Write Only * (ro) == Read Only * (w-) == Write * (r-) == Read
*/ #define DSP_RESET 0x06 /* offset of DSP RESET (wo) */ #define DSP_READ 0x0a /* offset of DSP READ (ro) */ #define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */ #define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */ #define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */ #define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */
#define PFX "sc6000: " #define DRV_NAME "SC-6000"
/* hardware dependent functions */
/* * sc6000_irq_to_softcfg - Decode irq number into cfg code.
*/ staticunsignedchar sc6000_irq_to_softcfg(int irq)
{ unsignedchar val = 0;
switch (irq) { case 5:
val = 0x28; break; case 7:
val = 0x8; break; case 9:
val = 0x10; break; case 10:
val = 0x18; break; case 11:
val = 0x20; break; default: break;
} return val;
}
/* * sc6000_dma_to_softcfg - Decode dma number into cfg code.
*/ staticunsignedchar sc6000_dma_to_softcfg(int dma)
{ unsignedchar val = 0;
switch (dma) { case 0:
val = 1; break; case 1:
val = 2; break; case 3:
val = 3; break; default: break;
} return val;
}
/* * sc6000_mpu_irq_to_softcfg - Decode MPU-401 irq number into cfg code.
*/ staticunsignedchar sc6000_mpu_irq_to_softcfg(int mpu_irq)
{ unsignedchar val = 0;
switch (mpu_irq) { case 5:
val = 4; break; case 7:
val = 0x44; break; case 9:
val = 0x84; break; case 10:
val = 0xc4; break; default: break;
} return val;
}
staticint sc6000_wait_data(char __iomem *vport)
{ int loop = 1000; unsignedchar val = 0;
do {
val = ioread8(vport + DSP_DATAVAIL); if (val & 0x80) return 0;
cpu_relax();
} while (loop--);
return -EAGAIN;
}
staticint sc6000_read(char __iomem *vport)
{ if (sc6000_wait_data(vport)) return -EBUSY;
return ioread8(vport + DSP_READ);
}
staticint sc6000_write(struct device *devptr, char __iomem *vport, int cmd)
{ unsignedchar val; int loop = 500000;
do {
val = ioread8(vport + DSP_STATUS); /* * DSP ready to receive data if bit 7 of val == 0
*/ if (!(val & 0x80)) {
iowrite8(cmd, vport + DSP_COMMAND); return 0;
}
cpu_relax();
} while (loop--);
/* * If no more data available, return to the caller, no error if len>0. * We have no other way to know when the string is finished.
*/ return len ? len : -EIO;
}
memset(answer, 0, sizeof(answer));
err = sc6000_dsp_get_answer(devptr, vport, GET_DSP_COPYRIGHT, answer, 15); if (err <= 0) {
dev_err(devptr, "sc6000_dsp_copyright: failed!\n"); return -ENODEV;
} /* * My SC-6000 card return "SC-6000" in DSPCopyright, so * if we have something different, we have to be warned.
*/ if (strncmp("SC-6000", answer, 7))
dev_warn(devptr, "Warning: non SC-6000 audio card!\n");
if (xirq == SNDRV_AUTO_IRQ) {
xirq = snd_legacy_find_free_irq(possible_irqs); if (xirq < 0) {
dev_err(devptr, "unable to find a free IRQ\n"); return -EBUSY;
}
}
if (xdma == SNDRV_AUTO_DMA) {
xdma = snd_legacy_find_free_dma(possible_dmas); if (xdma < 0) {
dev_err(devptr, "unable to find a free DMA\n"); return -EBUSY;
}
}
if (!devm_request_region(devptr, port[dev], 0x10, DRV_NAME)) {
dev_err(devptr, "I/O port region is already in use.\n"); return -EBUSY;
}
vport = devm_ioport_map(devptr, port[dev], 0x10); if (!vport) {
dev_err(devptr, "I/O port cannot be iomapped.\n"); return -EBUSY;
}
card->private_data = (void __force *)vport;
/* to make it marked as used */ if (!devm_request_region(devptr, mss_port[dev], 4, DRV_NAME)) {
dev_err(devptr, "SC-6000 port I/O port region is already in use.\n"); return -EBUSY;
}
vmss_port = devm_ioport_map(devptr, mss_port[dev], 4); if (!vmss_port) {
dev_err(devptr, "MSS port I/O cannot be iomapped.\n"); return -EBUSY;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.