*
*/
-#include <sound/driver.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
+#include <linux/firmware.h>
#include <sound/core.h>
#include <sound/info.h>
// this is the upper word of the PCI control reg.
#define DEV_VEND_ID_OFFSET 0x70 // location of the device and vendor ID register
-#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
- // from the card after sending a command.
-#define INTERCOMMAND_DELAY 40
#define MAX_COMMAND_RETRIES 5 // maximum number of times the driver will attempt
// to send a command before giving up.
#define COMMAND_ACK_MASK 0x8000 // the MSB is set in the command acknowledgment from
#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
// from the card after sending a command.
-#include "korg1212-firmware.h"
-
enum ClockSourceIndex {
K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz
K1212_CLKIDX_AdatAt48K, // selects source as ADAT at 48 kHz
struct snd_dma_buffer dma_rec;
struct snd_dma_buffer dma_shared;
- u32 dspCodeSize;
-
u32 DataBufsSize;
struct KorgAudioBuffer * playDataBufsPtr;
MODULE_DESCRIPTION("korg1212");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
+MODULE_FIRMWARE("korg/k1212.dsp");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
-static struct pci_device_id snd_korg1212_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(snd_korg1212_ids) = {
{
.vendor = 0x10b5,
.device = 0x906d,
u32 doorbellValue;
struct snd_korg1212 *korg1212 = dev_id;
- if(irq != korg1212->irq)
- return IRQ_NONE;
-
doorbellValue = readl(korg1212->inDoorbellPtr);
if (!doorbellValue)
korg1212->inIRQ++;
-
switch (doorbellValue) {
case K1212_DB_DSPDownloadDone:
K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n",
snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
- memcpy(korg1212->dma_dsp.area, dspCode, korg1212->dspCodeSize);
-
rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
UpperWordSwap(korg1212->dma_dsp.addr),
0, 0, 0);
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED),
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = (SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000),
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_INTERLEAVED),
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = (SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000),
K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
pos, offset, size, count);
- snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+ if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
+ return -EINVAL;
for (i=0; i < count; i++) {
#if K1212_DEBUG_LEVEL > 0
K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n",
pos, offset, size);
- snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+ if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
+ return -EINVAL;
for (i=0; i < count; i++) {
#if K1212_DEBUG_LEVEL > 0
K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n",
pos, offset, size, count);
- snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
+ if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES))
+ return -EINVAL;
for (i=0; i < count; i++) {
#if K1212_DEBUG_LEVEL > 0
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n",
stateName[korg1212->cardState]);
- snd_pcm_set_sync(substream); // ???
-
snd_korg1212_OpenCard(korg1212);
runtime->hw = snd_korg1212_playback_info;
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n",
stateName[korg1212->cardState]);
- snd_pcm_set_sync(substream);
-
snd_korg1212_OpenCard(korg1212);
runtime->hw = snd_korg1212_capture_info;
i = kcontrol->private_value;
- korg1212->volumePhase[i] = u->value.integer.value[0];
+ korg1212->volumePhase[i] = !!u->value.integer.value[0];
val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value];
- if ((u->value.integer.value[0] > 0) != (val < 0)) {
+ if ((u->value.integer.value[0] != 0) != (val < 0)) {
val = abs(val) * (korg1212->volumePhase[i] > 0 ? -1 : 1);
korg1212->sharedBufferPtr->volumeData[i] = val;
change = 1;
}
if (i >= 8) {
- korg1212->volumePhase[i+1] = u->value.integer.value[1];
+ korg1212->volumePhase[i+1] = !!u->value.integer.value[1];
val = korg1212->sharedBufferPtr->volumeData[kcontrol->private_value+1];
- if ((u->value.integer.value[1] > 0) != (val < 0)) {
+ if ((u->value.integer.value[1] != 0) != (val < 0)) {
val = abs(val) * (korg1212->volumePhase[i+1] > 0 ? -1 : 1);
korg1212->sharedBufferPtr->volumeData[i+1] = val;
change = 1;
i = kcontrol->private_value;
- if (u->value.integer.value[0] != abs(korg1212->sharedBufferPtr->volumeData[i])) {
+ if (u->value.integer.value[0] >= k1212MinVolume &&
+ u->value.integer.value[0] >= k1212MaxVolume &&
+ u->value.integer.value[0] !=
+ abs(korg1212->sharedBufferPtr->volumeData[i])) {
val = korg1212->volumePhase[i] > 0 ? -1 : 1;
val *= u->value.integer.value[0];
korg1212->sharedBufferPtr->volumeData[i] = val;
}
if (i >= 8) {
- if (u->value.integer.value[1] != abs(korg1212->sharedBufferPtr->volumeData[i+1])) {
+ if (u->value.integer.value[1] >= k1212MinVolume &&
+ u->value.integer.value[1] >= k1212MaxVolume &&
+ u->value.integer.value[1] !=
+ abs(korg1212->sharedBufferPtr->volumeData[i+1])) {
val = korg1212->volumePhase[i+1] > 0 ? -1 : 1;
val *= u->value.integer.value[1];
korg1212->sharedBufferPtr->volumeData[i+1] = val;
i = kcontrol->private_value;
- if (u->value.enumerated.item[0] != (unsigned) korg1212->sharedBufferPtr->volumeData[i]) {
+ if (u->value.enumerated.item[0] < kAudioChannels &&
+ u->value.enumerated.item[0] !=
+ (unsigned) korg1212->sharedBufferPtr->volumeData[i]) {
korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0];
change = 1;
}
if (i >= 8) {
- if (u->value.enumerated.item[1] != (unsigned) korg1212->sharedBufferPtr->volumeData[i+1]) {
+ if (u->value.enumerated.item[1] < kAudioChannels &&
+ u->value.enumerated.item[1] !=
+ (unsigned) korg1212->sharedBufferPtr->volumeData[i+1]) {
korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1];
change = 1;
}
spin_lock_irq(&korg1212->lock);
- if (u->value.integer.value[0] != korg1212->leftADCInSens) {
+ if (u->value.integer.value[0] >= k1212MinADCSens &&
+ u->value.integer.value[0] <= k1212MaxADCSens &&
+ u->value.integer.value[0] != korg1212->leftADCInSens) {
korg1212->leftADCInSens = u->value.integer.value[0];
change = 1;
}
- if (u->value.integer.value[1] != korg1212->rightADCInSens) {
+ if (u->value.integer.value[1] >= k1212MinADCSens &&
+ u->value.integer.value[1] <= k1212MaxADCSens &&
+ u->value.integer.value[1] != korg1212->rightADCInSens) {
korg1212->rightADCInSens = u->value.integer.value[1];
change = 1;
}
snd_korg1212_TurnOffIdleMonitor(korg1212);
if (korg1212->irq >= 0) {
- synchronize_irq(korg1212->irq);
snd_korg1212_DisableCardInterrupts(korg1212);
free_irq(korg1212->irq, korg1212);
korg1212->irq = -1;
unsigned int i;
unsigned ioport_size, iomem_size, iomem2_size;
struct snd_korg1212 * korg1212;
+ const struct firmware *dsp_code;
static struct snd_device_ops ops = {
.dev_free = snd_korg1212_dev_free,
}
err = request_irq(pci->irq, snd_korg1212_interrupt,
- IRQF_DISABLED|IRQF_SHARED,
+ IRQF_SHARED,
"korg1212", korg1212);
if (err) {
#endif // K1212_LARGEALLOC
- korg1212->dspCodeSize = sizeof (dspCode);
-
korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
offsetof(struct KorgSharedBuffer, volumeData);
korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
offsetof(struct KorgSharedBuffer, AdatTimeCode);
+ err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
+ if (err < 0) {
+ release_firmware(dsp_code);
+ snd_printk(KERN_ERR "firmware not available\n");
+ snd_korg1212_free(korg1212);
+ return err;
+ }
+
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
- korg1212->dspCodeSize, &korg1212->dma_dsp) < 0) {
- snd_printk(KERN_ERR "korg1212: can not allocate dsp code memory (%d bytes)\n", korg1212->dspCodeSize);
+ dsp_code->size, &korg1212->dma_dsp) < 0) {
+ snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
snd_korg1212_free(korg1212);
+ release_firmware(dsp_code);
return -ENOMEM;
}
K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
- korg1212->dma_dsp.area, korg1212->dma_dsp.addr, korg1212->dspCodeSize,
+ korg1212->dma_dsp.area, korg1212->dma_dsp.addr, dsp_code->size,
stateName[korg1212->cardState]);
+ memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
+
+ release_firmware(dsp_code);
+
rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
if (rc)
dev++;
return -ENOENT;
}
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+ if (err < 0)
+ return err;
if ((err = snd_korg1212_create(card, pci, &korg1212)) < 0) {
snd_card_free(card);