diff options
Diffstat (limited to 'sound/pci/rme9652/hdsp.c')
| -rw-r--r-- | sound/pci/rme9652/hdsp.c | 593 |
1 files changed, 194 insertions, 399 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 4fae81f21ef..4c6f5d1c988 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -154,10 +154,13 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define HDSP_BIGENDIAN_MODE 0x200 #define HDSP_RD_MULTIPLE 0x400 #define HDSP_9652_ENABLE_MIXER 0x800 +#define HDSP_S200 0x800 +#define HDSP_S300 (0x100 | HDSP_S200) /* dummy, purpose of 0x100 unknown */ +#define HDSP_CYCLIC_MODE 0x1000 #define HDSP_TDO 0x10000000 -#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0) -#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1) +#define HDSP_S_PROGRAM (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0) +#define HDSP_S_LOAD (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1) /* Control Register bits */ @@ -581,10 +584,6 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer { dmab->dev.type = SNDRV_DMA_TYPE_DEV; dmab->dev.dev = snd_dma_pci_data(pci); - if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) { - if (dmab->bytes >= size) - return 0; - } if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), size, dmab) < 0) return -ENOMEM; @@ -593,10 +592,8 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) { - if (dmab->area) { - dmab->dev.dev = NULL; /* make it anonymous */ - snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci)); - } + if (dmab->area) + snd_dma_free_pages(dmab); } @@ -671,13 +668,24 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg) static int hdsp_check_for_iobox (struct hdsp *hdsp) { + int i; + if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; - if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { - snd_printk("Hammerfall-DSP: no IO box connected!\n"); - hdsp->state &= ~HDSP_FirmwareLoaded; - return -EIO; + for (i = 0; i < 500; i++) { + if (0 == (hdsp_read(hdsp, HDSP_statusRegister) & + HDSP_ConfigError)) { + if (i) { + dev_dbg(hdsp->card->dev, + "IO box found after %d ms\n", + (20 * i)); + } + return 0; + } + msleep(20); } - return 0; + dev_err(hdsp->card->dev, "no IO box connected!\n"); + hdsp->state &= ~HDSP_FirmwareLoaded; + return -EIO; } static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, @@ -692,13 +700,13 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, if (hdsp_read(hdsp, HDSP_statusRegister) & HDSP_ConfigError) msleep(delay); else { - snd_printd("Hammerfall-DSP: iobox found after %ums!\n", + dev_dbg(hdsp->card->dev, "iobox found after %ums!\n", i * delay); return 0; } } - snd_printk("Hammerfall-DSP: no IO box connected!\n"); + dev_info(hdsp->card->dev, "no IO box connected!\n"); hdsp->state &= ~HDSP_FirmwareLoaded; return -EIO; } @@ -721,13 +729,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { - snd_printk ("Hammerfall-DSP: loading firmware\n"); + dev_info(hdsp->card->dev, "loading firmware\n"); hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_PROGRAM); hdsp_write (hdsp, HDSP_fifoData, 0); if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { - snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n"); + dev_info(hdsp->card->dev, + "timeout waiting for download preparation\n"); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); return -EIO; } @@ -736,29 +746,29 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) { for (i = 0; i < HDSP_FIRMWARE_SIZE / 4; ++i) { hdsp_write(hdsp, HDSP_fifoData, cache[i]); if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { - snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); + dev_info(hdsp->card->dev, + "timeout during firmware loading\n"); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); return -EIO; } } - ssleep(3); - - if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { - snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n"); - return -EIO; - } + hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200); + ssleep(3); #ifdef SNDRV_BIG_ENDIAN hdsp->control2_register = HDSP_BIGENDIAN_MODE; #else hdsp->control2_register = 0; #endif hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register); - snd_printk ("Hammerfall-DSP: finished firmware loading\n"); + dev_info(hdsp->card->dev, "finished firmware loading\n"); } if (hdsp->state & HDSP_InitializationComplete) { - snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n"); + dev_info(hdsp->card->dev, + "firmware loaded from cache, restoring defaults\n"); spin_lock_irqsave(&hdsp->lock, flags); snd_hdsp_set_defaults(hdsp); spin_unlock_irqrestore(&hdsp->lock, flags); @@ -773,24 +783,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) { if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { - hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM); - hdsp_write (hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) - return -EIO; + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + hdsp_write(hdsp, HDSP_fifoData, 0); - hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + } + + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM); hdsp_write (hdsp, HDSP_fifoData, 0); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { + hdsp->io_type = Multiface; + dev_info(hdsp->card->dev, "Multiface found\n"); + return 0; + } - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { - hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); - hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) - hdsp->io_type = RPM; - else - hdsp->io_type = Multiface; - } else { + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + hdsp_write(hdsp, HDSP_fifoData, 0); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { hdsp->io_type = Digiface; + dev_info(hdsp->card->dev, "Digiface found\n"); + return 0; + } + + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + hdsp_write(hdsp, HDSP_fifoData, 0); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { + hdsp->io_type = Multiface; + dev_info(hdsp->card->dev, "Multiface found\n"); + return 0; } + + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + hdsp_write(hdsp, HDSP_fifoData, 0); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { + hdsp->io_type = Multiface; + dev_info(hdsp->card->dev, "Multiface found\n"); + return 0; + } + + hdsp->io_type = RPM; + dev_info(hdsp->card->dev, "RPM found\n"); + return 0; } else { /* firmware was already loaded, get iobox type */ if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) @@ -814,20 +851,18 @@ static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand) hdsp->state &= ~HDSP_FirmwareLoaded; if (! load_on_demand) return -EIO; - snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n"); + dev_err(hdsp->card->dev, "firmware not present.\n"); /* try to load firmware */ if (! (hdsp->state & HDSP_FirmwareCached)) { if (! hdsp_request_fw_loader(hdsp)) return 0; - snd_printk(KERN_ERR - "Hammerfall-DSP: No firmware loaded nor " - "cached, please upload firmware.\n"); + dev_err(hdsp->card->dev, + "No firmware loaded nor cached, please upload firmware.\n"); return -EIO; } if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) { - snd_printk(KERN_ERR - "Hammerfall-DSP: Firmware loading from " - "cache failed, please upload manually.\n"); + dev_err(hdsp->card->dev, + "Firmware loading from cache failed, please upload manually.\n"); return -EIO; } } @@ -855,7 +890,8 @@ static int hdsp_fifo_wait(struct hdsp *hdsp, int count, int timeout) udelay (100); } - snd_printk ("Hammerfall-DSP: wait for FIFO status <= %d failed after %d iterations\n", + dev_warn(hdsp->card->dev, + "wait for FIFO status <= %d failed after %d iterations\n", count, timeout); return -1; } @@ -972,7 +1008,9 @@ static int hdsp_spdif_sample_rate(struct hdsp *hdsp) default: break; } - snd_printk ("Hammerfall-DSP: unknown spdif frequency status; bits = 0x%x, status = 0x%x\n", rate_bits, status); + dev_warn(hdsp->card->dev, + "unknown spdif frequency status; bits = 0x%x, status = 0x%x\n", + rate_bits, status); return 0; } @@ -1106,7 +1144,8 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) if (!(hdsp->control_register & HDSP_ClockModeMaster)) { if (called_internally) { /* request from ctl or card initialization */ - snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n"); + dev_err(hdsp->card->dev, + "device is not running as a clock master: cannot set sample rate.\n"); return -1; } else { /* hw_param request while in AutoSync mode */ @@ -1114,11 +1153,14 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) int spdif_freq = hdsp_spdif_sample_rate(hdsp); if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) - snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n"); + dev_info(hdsp->card->dev, + "Detected ADAT in double speed mode\n"); else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) - snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n"); + dev_info(hdsp->card->dev, + "Detected ADAT in quad speed mode\n"); else if (rate != external_freq) { - snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n"); + dev_info(hdsp->card->dev, + "No AutoSync source for requested rate\n"); return -1; } } @@ -1190,7 +1232,8 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) } if (reject_if_open && (hdsp->capture_pid >= 0 || hdsp->playback_pid >= 0)) { - snd_printk ("Hammerfall-DSP: cannot change speed mode (capture PID = %d, playback PID = %d)\n", + dev_warn(hdsp->card->dev, + "cannot change speed mode (capture PID = %d, playback PID = %d)\n", hdsp->capture_pid, hdsp->playback_pid); return -EBUSY; @@ -1674,127 +1717,50 @@ static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -#define HDSP_SPDIF_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_hdsp_info_spdif_bits, \ - .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out } +#define HDSP_TOGGLE_SETTING(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .private_value = xindex, \ + .info = snd_hdsp_info_toggle_setting, \ + .get = snd_hdsp_get_toggle_setting, \ + .put = snd_hdsp_put_toggle_setting \ +} -static int hdsp_spdif_out(struct hdsp *hdsp) +static int hdsp_toggle_setting(struct hdsp *hdsp, u32 regmask) { - return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0; + return (hdsp->control_register & regmask) ? 1 : 0; } -static int hdsp_set_spdif_output(struct hdsp *hdsp, int out) +static int hdsp_set_toggle_setting(struct hdsp *hdsp, u32 regmask, int out) { if (out) - hdsp->control_register |= HDSP_SPDIFOpticalOut; + hdsp->control_register |= regmask; else - hdsp->control_register &= ~HDSP_SPDIFOpticalOut; + hdsp->control_register &= ~regmask; hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); - return 0; -} - -#define snd_hdsp_info_spdif_bits snd_ctl_boolean_mono_info - -static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp); - return 0; -} - -static int snd_hdsp_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdsp_use_is_exclusive(hdsp)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_spdif_out(hdsp); - hdsp_set_spdif_output(hdsp, val); - spin_unlock_irq(&hdsp->lock); - return change; -} -#define HDSP_SPDIF_PROFESSIONAL(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_hdsp_info_spdif_bits, \ - .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional } - -static int hdsp_spdif_professional(struct hdsp *hdsp) -{ - return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0; -} - -static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val) -{ - if (val) - hdsp->control_register |= HDSP_SPDIFProfessional; - else - hdsp->control_register &= ~HDSP_SPDIFProfessional; - hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); return 0; } -static int snd_hdsp_get_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp); - return 0; -} +#define snd_hdsp_info_toggle_setting snd_ctl_boolean_mono_info -static int snd_hdsp_put_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hdsp_get_toggle_setting(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; + u32 regmask = kcontrol->private_value; - if (!snd_hdsp_use_is_exclusive(hdsp)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_spdif_professional(hdsp); - hdsp_set_spdif_professional(hdsp, val); + ucontrol->value.integer.value[0] = hdsp_toggle_setting(hdsp, regmask); spin_unlock_irq(&hdsp->lock); - return change; -} - -#define HDSP_SPDIF_EMPHASIS(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_hdsp_info_spdif_bits, \ - .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis } - -static int hdsp_spdif_emphasis(struct hdsp *hdsp) -{ - return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0; -} - -static int hdsp_set_spdif_emphasis(struct hdsp *hdsp, int val) -{ - if (val) - hdsp->control_register |= HDSP_SPDIFEmphasis; - else - hdsp->control_register &= ~HDSP_SPDIFEmphasis; - hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); return 0; } -static int snd_hdsp_get_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp); - return 0; -} - -static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hdsp_put_toggle_setting(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + u32 regmask = kcontrol->private_value; int change; unsigned int val; @@ -1802,52 +1768,9 @@ static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_spdif_emphasis(hdsp); - hdsp_set_spdif_emphasis(hdsp, val); - spin_unlock_irq(&hdsp->lock); - return change; -} - -#define HDSP_SPDIF_NON_AUDIO(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_hdsp_info_spdif_bits, \ - .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio } - -static int hdsp_spdif_nonaudio(struct hdsp *hdsp) -{ - return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0; -} - -static int hdsp_set_spdif_nonaudio(struct hdsp *hdsp, int val) -{ - if (val) - hdsp->control_register |= HDSP_SPDIFNonAudio; - else - hdsp->control_register &= ~HDSP_SPDIFNonAudio; - hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); - return 0; -} - -static int snd_hdsp_get_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp); - return 0; -} - -static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdsp_use_is_exclusive(hdsp)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_spdif_nonaudio(hdsp); - hdsp_set_spdif_nonaudio(hdsp, val); + change = (int) val != hdsp_toggle_setting(hdsp, regmask); + if (change) + hdsp_set_toggle_setting(hdsp, regmask, val); spin_unlock_irq(&hdsp->lock); return change; } @@ -2451,114 +2374,6 @@ static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl return change; } -#define HDSP_XLR_BREAKOUT_CABLE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdsp_info_xlr_breakout_cable, \ - .get = snd_hdsp_get_xlr_breakout_cable, \ - .put = snd_hdsp_put_xlr_breakout_cable \ -} - -static int hdsp_xlr_breakout_cable(struct hdsp *hdsp) -{ - if (hdsp->control_register & HDSP_XLRBreakoutCable) - return 1; - return 0; -} - -static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode) -{ - if (mode) - hdsp->control_register |= HDSP_XLRBreakoutCable; - else - hdsp->control_register &= ~HDSP_XLRBreakoutCable; - hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); - return 0; -} - -#define snd_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info - -static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp); - return 0; -} - -static int snd_hdsp_put_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - int change; - int val; - - if (!snd_hdsp_use_is_exclusive(hdsp)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_xlr_breakout_cable(hdsp); - hdsp_set_xlr_breakout_cable(hdsp, val); - spin_unlock_irq(&hdsp->lock); - return change; -} - -/* (De)activates old RME Analog Extension Board - These are connected to the internal ADAT connector - Switching this on desactivates external ADAT -*/ -#define HDSP_AEB(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdsp_info_aeb, \ - .get = snd_hdsp_get_aeb, \ - .put = snd_hdsp_put_aeb \ -} - -static int hdsp_aeb(struct hdsp *hdsp) -{ - if (hdsp->control_register & HDSP_AnalogExtensionBoard) - return 1; - return 0; -} - -static int hdsp_set_aeb(struct hdsp *hdsp, int mode) -{ - if (mode) - hdsp->control_register |= HDSP_AnalogExtensionBoard; - else - hdsp->control_register &= ~HDSP_AnalogExtensionBoard; - hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); - return 0; -} - -#define snd_hdsp_info_aeb snd_ctl_boolean_mono_info - -static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp); - return 0; -} - -static int snd_hdsp_put_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - int change; - int val; - - if (!snd_hdsp_use_is_exclusive(hdsp)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_aeb(hdsp); - hdsp_set_aeb(hdsp, val); - spin_unlock_irq(&hdsp->lock); - return change; -} - #define HDSP_PREF_SYNC_REF(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ @@ -2747,58 +2562,6 @@ static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_c return 0; } -#define HDSP_LINE_OUT(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdsp_info_line_out, \ - .get = snd_hdsp_get_line_out, \ - .put = snd_hdsp_put_line_out \ -} - -static int hdsp_line_out(struct hdsp *hdsp) -{ - return (hdsp->control_register & HDSP_LineOut) ? 1 : 0; -} - -static int hdsp_set_line_output(struct hdsp *hdsp, int out) -{ - if (out) - hdsp->control_register |= HDSP_LineOut; - else - hdsp->control_register &= ~HDSP_LineOut; - hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); - return 0; -} - -#define snd_hdsp_info_line_out snd_ctl_boolean_mono_info - -static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdsp->lock); - ucontrol->value.integer.value[0] = hdsp_line_out(hdsp); - spin_unlock_irq(&hdsp->lock); - return 0; -} - -static int snd_hdsp_put_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -{ - struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); - int change; - unsigned int val; - - if (!snd_hdsp_use_is_exclusive(hdsp)) - return -EBUSY; - val = ucontrol->value.integer.value[0] & 1; - spin_lock_irq(&hdsp->lock); - change = (int)val != hdsp_line_out(hdsp); - hdsp_set_line_output(hdsp, val); - spin_unlock_irq(&hdsp->lock); - return change; -} - #define HDSP_PRECISE_POINTER(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_CARD, \ .name = xname, \ @@ -3190,7 +2953,7 @@ static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { HDSP_DA_GAIN("DA Gain", 0), HDSP_AD_GAIN("AD Gain", 0), HDSP_PHONE_GAIN("Phones Gain", 0), -HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), +HDSP_TOGGLE_SETTING("XLR Breakout Cable", HDSP_XLRBreakoutCable), HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) }; @@ -3232,10 +2995,10 @@ static struct snd_kcontrol_new snd_hdsp_controls[] = { }, HDSP_MIXER("Mixer", 0), HDSP_SPDIF_IN("IEC958 Input Connector", 0), -HDSP_SPDIF_OUT("IEC958 Output also on ADAT1", 0), -HDSP_SPDIF_PROFESSIONAL("IEC958 Professional Bit", 0), -HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), -HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), +HDSP_TOGGLE_SETTING("IEC958 Output also on ADAT1", HDSP_SPDIFOpticalOut), +HDSP_TOGGLE_SETTING("IEC958 Professional Bit", HDSP_SPDIFProfessional), +HDSP_TOGGLE_SETTING("IEC958 Emphasis Bit", HDSP_SPDIFEmphasis), +HDSP_TOGGLE_SETTING("IEC958 Non-audio Bit", HDSP_SPDIFNonAudio), /* 'Sample Clock Source' complies with the alsa control naming scheme */ HDSP_CLOCK_SOURCE("Sample Clock Source", 0), { @@ -3255,7 +3018,7 @@ HDSP_AUTOSYNC_SAMPLE_RATE("External Rate", 0), HDSP_WC_SYNC_CHECK("Word Clock Lock Status", 0), HDSP_SPDIF_SYNC_CHECK("SPDIF Lock Status", 0), HDSP_ADATSYNC_SYNC_CHECK("ADAT Sync Lock Status", 0), -HDSP_LINE_OUT("Line Out", 0), +HDSP_TOGGLE_SETTING("Line Out", HDSP_LineOut), HDSP_PRECISE_POINTER("Precise Pointer", 0), HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), }; @@ -3572,7 +3335,9 @@ static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { HDSP_MIXER("Mixer", 0) }; -static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); +static struct snd_kcontrol_new snd_hdsp_96xx_aeb = + HDSP_TOGGLE_SETTING("Analog Extension Board", + HDSP_AnalogExtensionBoard); static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) @@ -3995,7 +3760,9 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) } snd_iprintf(buffer, "Phones Gain : %s\n", tmp); - snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no"); + snd_iprintf(buffer, "XLR Breakout Cable : %s\n", + hdsp_toggle_setting(hdsp, HDSP_XLRBreakoutCable) ? + "yes" : "no"); if (hdsp->control_register & HDSP_AnalogExtensionBoard) snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n"); @@ -4028,7 +3795,8 @@ static int snd_hdsp_initialize_memory(struct hdsp *hdsp) snd_hammerfall_get_buffer(hdsp->pci, &hdsp->playback_dma_buf, HDSP_DMA_AREA_BYTES) < 0) { if (hdsp->capture_dma_buf.area) snd_dma_free_pages(&hdsp->capture_dma_buf); - printk(KERN_ERR "%s: no buffers available\n", hdsp->card_name); + dev_err(hdsp->card->dev, + "%s: no buffers available\n", hdsp->card_name); return -ENOMEM; } @@ -4990,7 +4758,8 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne return err; if (!(hdsp->state & HDSP_FirmwareLoaded)) { - snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n"); + dev_err(hdsp->card->dev, + "firmware needs to be uploaded to the card.\n"); return -EINVAL; } @@ -5026,29 +4795,38 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); - info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); - info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp); - info.spdif_emphasis = (unsigned char)hdsp_spdif_emphasis(hdsp); - info.spdif_nonaudio = (unsigned char)hdsp_spdif_nonaudio(hdsp); + info.spdif_out = (unsigned char)hdsp_toggle_setting(hdsp, + HDSP_SPDIFOpticalOut); + info.spdif_professional = (unsigned char) + hdsp_toggle_setting(hdsp, HDSP_SPDIFProfessional); + info.spdif_emphasis = (unsigned char) + hdsp_toggle_setting(hdsp, HDSP_SPDIFEmphasis); + info.spdif_nonaudio = (unsigned char) + hdsp_toggle_setting(hdsp, HDSP_SPDIFNonAudio); info.spdif_sample_rate = hdsp_spdif_sample_rate(hdsp); info.system_sample_rate = hdsp->system_sample_rate; info.autosync_sample_rate = hdsp_external_sample_rate(hdsp); info.system_clock_mode = (unsigned char)hdsp_system_clock_mode(hdsp); info.clock_source = (unsigned char)hdsp_clock_source(hdsp); info.autosync_ref = (unsigned char)hdsp_autosync_ref(hdsp); - info.line_out = (unsigned char)hdsp_line_out(hdsp); + info.line_out = (unsigned char) + hdsp_toggle_setting(hdsp, HDSP_LineOut); if (hdsp->io_type == H9632) { info.da_gain = (unsigned char)hdsp_da_gain(hdsp); info.ad_gain = (unsigned char)hdsp_ad_gain(hdsp); info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); - info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); + info.xlr_breakout_cable = + (unsigned char)hdsp_toggle_setting(hdsp, + HDSP_XLRBreakoutCable); } else if (hdsp->io_type == RPM) { info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); } if (hdsp->io_type == H9632 || hdsp->io_type == H9652) - info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); + info.analog_extension_board = + (unsigned char)hdsp_toggle_setting(hdsp, + HDSP_AnalogExtensionBoard); spin_unlock_irqrestore(&hdsp->lock, flags); if (copy_to_user(argp, &info, sizeof(info))) return -EFAULT; @@ -5073,6 +4851,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne if ((err = hdsp_get_iobox_version(hdsp)) < 0) return err; } + memset(&hdsp_version, 0, sizeof(hdsp_version)); hdsp_version.io_type = hdsp->io_type; hdsp_version.firmware_rev = hdsp->firmware_rev; if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) @@ -5091,7 +4870,8 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded)) return -EBUSY; - snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n"); + dev_info(hdsp->card->dev, + "initializing firmware upload\n"); firmware = (struct hdsp_firmware __user *)argp; if (get_user(firmware_data, &firmware->firmware_data)) @@ -5126,7 +4906,8 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne snd_hdsp_initialize_midi_flush(hdsp); if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n"); + dev_err(hdsp->card->dev, + "error creating alsa devices\n"); return err; } } @@ -5216,7 +4997,8 @@ static int snd_hdsp_enable_io (struct hdsp *hdsp) int i; if (hdsp_fifo_wait (hdsp, 0, 100)) { - snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n"); + dev_err(hdsp->card->dev, + "enable_io fifo_wait failed\n"); return -EIO; } @@ -5290,25 +5072,29 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp int err; if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n"); + dev_err(card->dev, + "Error creating pcm interface\n"); return err; } if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n"); + dev_err(card->dev, + "Error creating first midi interface\n"); return err; } if (hdsp->io_type == Digiface || hdsp->io_type == H9652) { if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n"); + dev_err(card->dev, + "Error creating second midi interface\n"); return err; } } if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n"); + dev_err(card->dev, + "Error creating ctl interface\n"); return err; } @@ -5321,7 +5107,8 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp hdsp->playback_substream = NULL; if ((err = snd_hdsp_set_defaults(hdsp)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n"); + dev_err(card->dev, + "Error setting default values\n"); return err; } @@ -5331,7 +5118,8 @@ static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp hdsp->port, hdsp->irq); if ((err = snd_card_register(card)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n"); + dev_err(card->dev, + "error registering card\n"); return err; } hdsp->state |= HDSP_InitializationComplete; @@ -5374,16 +5162,19 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp) fwfile = "digiface_firmware_rev11.bin"; break; default: - snd_printk(KERN_ERR "Hammerfall-DSP: invalid io_type %d\n", hdsp->io_type); + dev_err(hdsp->card->dev, + "invalid io_type %d\n", hdsp->io_type); return -EINVAL; } if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) { - snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile); + dev_err(hdsp->card->dev, + "cannot load firmware %s\n", fwfile); return -ENOENT; } if (fw->size < HDSP_FIRMWARE_SIZE) { - snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n", + dev_err(hdsp->card->dev, + "too short firmware size %d (expected %d)\n", (int)fw->size, HDSP_FIRMWARE_SIZE); return -EINVAL; } @@ -5400,13 +5191,15 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp) return err; if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n"); + dev_err(hdsp->card->dev, + "error creating hwdep device\n"); return err; } snd_hdsp_initialize_channels(hdsp); snd_hdsp_initialize_midi_flush(hdsp); if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) { - snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n"); + dev_err(hdsp->card->dev, + "error creating alsa devices\n"); return err; } } @@ -5482,13 +5275,14 @@ static int snd_hdsp_create(struct snd_card *card, return err; hdsp->port = pci_resource_start(pci, 0); if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) { - snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1); + dev_err(hdsp->card->dev, "unable to remap region 0x%lx-0x%lx\n", + hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1); return -EBUSY; } if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED, KBUILD_MODNAME, hdsp)) { - snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq); + dev_err(hdsp->card->dev, "unable to use IRQ %d\n", pci->irq); return -EBUSY; } @@ -5514,17 +5308,20 @@ static int snd_hdsp_create(struct snd_card *card, if userspace is not ready for firmware upload */ - snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n"); + dev_err(hdsp->card->dev, + "couldn't get firmware from userspace. try using hdsploader\n"); else /* init is complete, we return */ return 0; /* we defer initialization */ - snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n"); + dev_info(hdsp->card->dev, + "card initialization pending : waiting for firmware\n"); if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) return err; return 0; } else { - snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); + dev_info(hdsp->card->dev, + "Firmware already present, initializing card.\n"); if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) hdsp->io_type = RPM; else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) @@ -5608,8 +5405,8 @@ static int snd_hdsp_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct hdsp), &card); + err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, + sizeof(struct hdsp), &card); if (err < 0) return err; @@ -5617,7 +5414,6 @@ static int snd_hdsp_probe(struct pci_dev *pci, card->private_free = snd_hdsp_card_free; hdsp->dev = dev; hdsp->pci = pci; - snd_card_set_dev(card, &pci->dev); if ((err = snd_hdsp_create(card, hdsp)) < 0) { snd_card_free(card); @@ -5640,7 +5436,6 @@ static int snd_hdsp_probe(struct pci_dev *pci, static void snd_hdsp_remove(struct pci_dev *pci) { snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); } static struct pci_driver hdsp_driver = { |
