X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Frme9652%2Fhdsp.c;h=e35796c9085191894a3b914cecd4532a4c827cf3;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=628516c8b4816a755157aabc524cf17af5fee331;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 628516c8b..e35796c90 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -48,28 +49,21 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int precise_ptr[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0 }; /* Enable precise pointer */ static int line_outs_monitor[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 0}; /* Send all inputs/playback to line outs */ -static int boot_devs; -module_param_array(index, int, boot_devs, 0444); +module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface."); -MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC); -module_param_array(id, charp, boot_devs, 0444); +module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for RME Hammerfall DSP interface."); -MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC); -module_param_array(enable, bool, boot_devs, 0444); +module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable/disable specific Hammerfall DSP soundcards."); -MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); -module_param_array(precise_ptr, bool, boot_devs, 0444); +module_param_array(precise_ptr, bool, NULL, 0444); MODULE_PARM_DESC(precise_ptr, "Enable precise pointer (doesn't work reliably)."); -MODULE_PARM_SYNTAX(precise_ptr, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); -module_param_array(line_outs_monitor, bool, boot_devs, 0444); +module_param_array(line_outs_monitor, bool, NULL, 0444); MODULE_PARM_DESC(line_outs_monitor, "Send all input and playback streams to line outs by default."); -MODULE_PARM_SYNTAX(line_outs_monitor, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC); MODULE_AUTHOR("Paul Davis , Marcus Andersson, Thomas Charbonnel "); MODULE_DESCRIPTION("RME Hammerfall DSP"); MODULE_LICENSE("GPL"); -MODULE_CLASSES("{sound}"); -MODULE_DEVICES("{{RME Hammerfall-DSP}," +MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}"); @@ -406,6 +400,13 @@ MODULE_DEVICES("{{RME Hammerfall-DSP}," #define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES) #define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024) +/* use hotplug firmeare loader? */ +#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) +#ifndef HDSP_USE_HWDEP_LOADER +#define HDSP_FW_LOADER +#endif +#endif + typedef struct _hdsp hdsp_t; typedef struct _hdsp_midi hdsp_midi_t; typedef struct _hdsp_9632_meters hdsp_9632_meters_t; @@ -462,12 +463,12 @@ struct _hdsp { unsigned char qs_out_channels; unsigned char ds_out_channels; unsigned char ss_out_channels; - void *capture_buffer_unaligned; /* original buffer addresses */ - void *playback_buffer_unaligned; /* original buffer addresses */ + + struct snd_dma_buffer capture_dma_buf; + struct snd_dma_buffer playback_dma_buf; unsigned char *capture_buffer; /* suitably aligned address */ unsigned char *playback_buffer; /* suitably aligned address */ - dma_addr_t capture_buffer_addr; - dma_addr_t playback_buffer_addr; + pid_t capture_pid; pid_t playback_pid; int running; @@ -477,8 +478,7 @@ struct _hdsp { int dev; int irq; unsigned long port; - struct resource *res_port; - unsigned long iobase; + void __iomem *iobase; snd_card_t *card; snd_pcm_t *pcm; snd_hwdep_t *hwdep; @@ -561,50 +561,24 @@ static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { -1, -1 }; -#define HDSP_PREALLOCATE_MEMORY /* via module snd-hdsp_mem */ - -#ifdef HDSP_PREALLOCATE_MEMORY -static void *snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size, dma_addr_t *addrp, int capture) +static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size) { - struct snd_dma_device pdev; - struct snd_dma_buffer dmbuf; - - memset(&pdev, 0, sizeof(pdev)); - pdev.type = SNDRV_DMA_TYPE_DEV; - pdev.dev = snd_dma_pci_data(pci); - pdev.id = capture; - dmbuf.bytes = 0; - if (! snd_dma_get_reserved(&pdev, &dmbuf)) { - if (snd_dma_alloc_pages(&pdev, size, &dmbuf) < 0) - return NULL; - snd_dma_set_reserved(&pdev, &dmbuf); + 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 (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), + size, dmab) < 0) + return -ENOMEM; } - *addrp = dmbuf.addr; - return dmbuf.area; -} - -static void snd_hammerfall_free_buffer(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t addr, int capture) -{ - struct snd_dma_device pdev; - - memset(&pdev, 0, sizeof(pdev)); - pdev.type = SNDRV_DMA_TYPE_DEV; - pdev.dev = snd_dma_pci_data(pci); - pdev.id = capture; - snd_dma_free_reserved(&pdev); + return 0; } -#else -static void *snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size, dma_addr_t *addrp, int capture) +static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) { - return snd_malloc_pci_pages(pci, size, addrp); + if (dmab->area) + snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci)); } -static void snd_hammerfall_free_buffer(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t addr, int capture) -{ - snd_free_pci_pages(pci, size, ptr, addr); -} -#endif static struct pci_device_id snd_hdsp_ids[] = { { @@ -619,17 +593,17 @@ static struct pci_device_id snd_hdsp_ids[] = { MODULE_DEVICE_TABLE(pci, snd_hdsp_ids); /* prototypes */ -static int __devinit snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp); -static int __devinit snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp); -static inline int snd_hdsp_enable_io (hdsp_t *hdsp); -static inline void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp); -static inline void snd_hdsp_initialize_channels (hdsp_t *hdsp); -static inline int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout); +static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp); +static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp); +static int snd_hdsp_enable_io (hdsp_t *hdsp); +static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp); +static void snd_hdsp_initialize_channels (hdsp_t *hdsp); +static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout); static int hdsp_autosync_ref(hdsp_t *hdsp); static int snd_hdsp_set_defaults(hdsp_t *hdsp); -static inline void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp); +static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp); -static inline int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out) +static int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out) { switch (hdsp->firmware_rev) { case 0xa: @@ -642,7 +616,7 @@ static inline int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out) } } -static inline int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out) +static int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out) { switch (hdsp->firmware_rev) { case 0xa: @@ -655,17 +629,17 @@ static inline int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out) } } -static inline void hdsp_write(hdsp_t *hdsp, int reg, int val) +static void hdsp_write(hdsp_t *hdsp, int reg, int val) { writel(val, hdsp->iobase + reg); } -static inline unsigned int hdsp_read(hdsp_t *hdsp, int reg) +static unsigned int hdsp_read(hdsp_t *hdsp, int reg) { return readl (hdsp->iobase + reg); } -static inline int hdsp_check_for_iobox (hdsp_t *hdsp) +static int hdsp_check_for_iobox (hdsp_t *hdsp) { if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; @@ -738,7 +712,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) { return 0; } -static inline int hdsp_get_iobox_version (hdsp_t *hdsp) +static int hdsp_get_iobox_version (hdsp_t *hdsp) { int err; @@ -781,7 +755,7 @@ static inline int hdsp_get_iobox_version (hdsp_t *hdsp) } -static inline int hdsp_check_for_firmware (hdsp_t *hdsp) +static int hdsp_check_for_firmware (hdsp_t *hdsp) { if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { @@ -793,7 +767,7 @@ static inline int hdsp_check_for_firmware (hdsp_t *hdsp) } -static inline int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout) +static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout) { int i; @@ -818,7 +792,7 @@ static inline int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout) return -1; } -static inline int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr) +static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr) { if (addr >= HDSP_MATRIX_MIXER_SIZE) { return 0; @@ -826,7 +800,7 @@ static inline int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr) return hdsp->mixer_matrix[addr]; } -static inline int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data) +static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data) { unsigned int ad; @@ -835,7 +809,7 @@ static inline int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned shor if (hdsp->io_type == H9652 || hdsp->io_type == H9632) { - /* from martin björnsen: + /* from martin björnsen: "You can only write dwords to the mixer memory which contain two @@ -889,7 +863,7 @@ static inline int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned shor return 0; } -static inline int snd_hdsp_use_is_exclusive(hdsp_t *hdsp) +static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp) { unsigned long flags; int ret = 1; @@ -903,7 +877,7 @@ static inline int snd_hdsp_use_is_exclusive(hdsp_t *hdsp) return ret; } -static inline int hdsp_external_sample_rate (hdsp_t *hdsp) +static int hdsp_external_sample_rate (hdsp_t *hdsp) { unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register); unsigned int rate_bits = status2 & HDSP_systemFrequencyMask; @@ -920,7 +894,7 @@ static inline int hdsp_external_sample_rate (hdsp_t *hdsp) } } -static inline int hdsp_spdif_sample_rate(hdsp_t *hdsp) +static int hdsp_spdif_sample_rate(hdsp_t *hdsp) { unsigned int status = hdsp_read(hdsp, HDSP_statusRegister); unsigned int rate_bits = (status & HDSP_spdifFrequencyMask); @@ -952,7 +926,7 @@ static inline int hdsp_spdif_sample_rate(hdsp_t *hdsp) return 0; } -static inline void hdsp_compute_period_size(hdsp_t *hdsp) +static void hdsp_compute_period_size(hdsp_t *hdsp) { hdsp->period_bytes = 1 << ((hdsp_decode_latency(hdsp->control_register) + 8)); } @@ -969,29 +943,28 @@ static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp) position &= HDSP_BufferPositionMask; position /= 4; - position -= 32; - position &= (HDSP_CHANNEL_BUFFER_SAMPLES-1); + position &= (hdsp->period_bytes/2) - 1; return position; } -static inline void hdsp_reset_hw_pointer(hdsp_t *hdsp) +static void hdsp_reset_hw_pointer(hdsp_t *hdsp) { hdsp_write (hdsp, HDSP_resetPointer, 0); } -static inline void hdsp_start_audio(hdsp_t *s) +static void hdsp_start_audio(hdsp_t *s) { s->control_register |= (HDSP_AudioInterruptEnable | HDSP_Start); hdsp_write(s, HDSP_controlRegister, s->control_register); } -static inline void hdsp_stop_audio(hdsp_t *s) +static void hdsp_stop_audio(hdsp_t *s) { s->control_register &= ~(HDSP_Start | HDSP_AudioInterruptEnable); hdsp_write(s, HDSP_controlRegister, s->control_register); } -static inline void hdsp_silence_playback(hdsp_t *hdsp) +static void hdsp_silence_playback(hdsp_t *hdsp) { memset(hdsp->playback_buffer, 0, HDSP_DMA_AREA_BYTES); } @@ -1236,7 +1209,7 @@ static int hdsp_set_passthru(hdsp_t *hdsp, int onoff) MIDI ----------------------------------------------------------------------------*/ -static inline unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id) +static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id) { /* the hardware already does the relevant bit-mask with 0xff */ if (id) { @@ -1246,7 +1219,7 @@ static inline unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id) } } -static inline void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val) +static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val) { /* the hardware already does the relevant bit-mask with 0xff */ if (id) { @@ -1256,7 +1229,7 @@ static inline void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val) } } -static inline int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id) +static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id) { if (id) { return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff); @@ -1265,7 +1238,7 @@ static inline int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id) } } -static inline int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id) +static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id) { int fifo_bytes_used; @@ -1282,7 +1255,7 @@ static inline int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id) } } -static inline void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id) +static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id) { while (snd_hdsp_midi_input_available (hdsp, id)) { snd_hdsp_midi_read_byte (hdsp, id); @@ -1429,13 +1402,12 @@ static void snd_hdsp_midi_output_trigger(snd_rawmidi_substream_t * substream, in static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream) { hdsp_midi_t *hmidi; - unsigned long flags; hmidi = (hdsp_midi_t *) substream->rmidi->private_data; - spin_lock_irqsave (&hmidi->lock, flags); + spin_lock_irq (&hmidi->lock); snd_hdsp_flush_midi_input (hmidi->hdsp, hmidi->id); hmidi->input = substream; - spin_unlock_irqrestore (&hmidi->lock, flags); + spin_unlock_irq (&hmidi->lock); return 0; } @@ -1443,12 +1415,11 @@ static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream) static int snd_hdsp_midi_output_open(snd_rawmidi_substream_t * substream) { hdsp_midi_t *hmidi; - unsigned long flags; hmidi = (hdsp_midi_t *) substream->rmidi->private_data; - spin_lock_irqsave (&hmidi->lock, flags); + spin_lock_irq (&hmidi->lock); hmidi->output = substream; - spin_unlock_irqrestore (&hmidi->lock, flags); + spin_unlock_irq (&hmidi->lock); return 0; } @@ -1456,14 +1427,13 @@ static int snd_hdsp_midi_output_open(snd_rawmidi_substream_t * substream) static int snd_hdsp_midi_input_close(snd_rawmidi_substream_t * substream) { hdsp_midi_t *hmidi; - unsigned long flags; snd_hdsp_midi_input_trigger (substream, 0); hmidi = (hdsp_midi_t *) substream->rmidi->private_data; - spin_lock_irqsave (&hmidi->lock, flags); + spin_lock_irq (&hmidi->lock); hmidi->input = NULL; - spin_unlock_irqrestore (&hmidi->lock, flags); + spin_unlock_irq (&hmidi->lock); return 0; } @@ -1471,26 +1441,25 @@ static int snd_hdsp_midi_input_close(snd_rawmidi_substream_t * substream) static int snd_hdsp_midi_output_close(snd_rawmidi_substream_t * substream) { hdsp_midi_t *hmidi; - unsigned long flags; snd_hdsp_midi_output_trigger (substream, 0); hmidi = (hdsp_midi_t *) substream->rmidi->private_data; - spin_lock_irqsave (&hmidi->lock, flags); + spin_lock_irq (&hmidi->lock); hmidi->output = NULL; - spin_unlock_irqrestore (&hmidi->lock, flags); + spin_unlock_irq (&hmidi->lock); return 0; } -snd_rawmidi_ops_t snd_hdsp_midi_output = +static snd_rawmidi_ops_t snd_hdsp_midi_output = { .open = snd_hdsp_midi_output_open, .close = snd_hdsp_midi_output_close, .trigger = snd_hdsp_midi_output_trigger, }; -snd_rawmidi_ops_t snd_hdsp_midi_input = +static snd_rawmidi_ops_t snd_hdsp_midi_input = { .open = snd_hdsp_midi_input_open, .close = snd_hdsp_midi_input_close, @@ -1563,7 +1532,7 @@ static int snd_hdsp_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_in static int snd_hdsp_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif); return 0; @@ -1571,16 +1540,15 @@ static int snd_hdsp_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_va static int snd_hdsp_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; u32 val; val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = val != hdsp->creg_spdif; hdsp->creg_spdif = val; - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1593,7 +1561,7 @@ static int snd_hdsp_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_ static int snd_hdsp_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif_stream); return 0; @@ -1601,18 +1569,17 @@ static int snd_hdsp_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_ static int snd_hdsp_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; u32 val; val = snd_hdsp_convert_from_aes(&ucontrol->value.iec958); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = val != hdsp->creg_spdif_stream; hdsp->creg_spdif_stream = val; hdsp->control_register &= ~(HDSP_SPDIFProfessional | HDSP_SPDIFNonAudio | HDSP_SPDIFEmphasis); hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register |= val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1653,7 +1620,7 @@ static int hdsp_set_spdif_input(hdsp_t *hdsp, int in) static int snd_hdsp_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"}; - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1666,7 +1633,7 @@ static int snd_hdsp_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t static int snd_hdsp_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_spdif_in(hdsp); return 0; @@ -1674,19 +1641,18 @@ static int snd_hdsp_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; unsigned int val; if (!snd_hdsp_use_is_exclusive(hdsp)) return -EBUSY; val = ucontrol->value.enumerated.item[0] % ((hdsp->io_type == H9632) ? 4 : 3); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = val != hdsp_spdif_in(hdsp); if (change) hdsp_set_spdif_input(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1722,7 +1688,7 @@ static int snd_hdsp_info_spdif_bits(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_ static int snd_hdsp_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp); return 0; @@ -1730,18 +1696,17 @@ static int snd_hdsp_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_spdif_out(hdsp); hdsp_set_spdif_output(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1768,7 +1733,7 @@ static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val) static int snd_hdsp_get_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp); return 0; @@ -1776,18 +1741,17 @@ static int snd_hdsp_get_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_el static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_spdif_professional(hdsp); hdsp_set_spdif_professional(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1814,7 +1778,7 @@ static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val) static int snd_hdsp_get_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp); return 0; @@ -1822,18 +1786,17 @@ static int snd_hdsp_get_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_v static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_spdif_emphasis(hdsp); hdsp_set_spdif_emphasis(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1860,7 +1823,7 @@ static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val) static int snd_hdsp_get_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp); return 0; @@ -1868,18 +1831,17 @@ static int snd_hdsp_get_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_v static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_spdif_nonaudio(hdsp); hdsp_set_spdif_nonaudio(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -1895,7 +1857,7 @@ static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_v static int snd_hdsp_info_spdif_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"}; - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1908,7 +1870,7 @@ static int snd_hdsp_info_spdif_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_ele static int snd_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); switch (hdsp_spdif_sample_rate(hdsp)) { case 32000: @@ -1962,7 +1924,7 @@ static int snd_hdsp_info_system_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_el static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp->system_sample_rate; return 0; @@ -1979,7 +1941,7 @@ static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_el static int snd_hdsp_info_autosync_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"}; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1992,7 +1954,7 @@ static int snd_hdsp_info_autosync_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_ static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); switch (hdsp_external_sample_rate(hdsp)) { case 32000: @@ -2062,7 +2024,7 @@ static int snd_hdsp_info_system_clock_mode(snd_kcontrol_t *kcontrol, snd_ctl_ele static int snd_hdsp_get_system_clock_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_system_clock_mode(hdsp); return 0; @@ -2159,7 +2121,7 @@ static int hdsp_set_clock_source(hdsp_t *hdsp, int mode) static int snd_hdsp_info_clock_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" }; - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -2175,7 +2137,7 @@ static int snd_hdsp_info_clock_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf static int snd_hdsp_get_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_clock_source(hdsp); return 0; @@ -2183,8 +2145,7 @@ static int snd_hdsp_get_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; int val; @@ -2197,13 +2158,13 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val } else { if (val > 6) val = 6; } - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); if (val != hdsp_clock_source(hdsp)) { change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0; } else { change = 0; } - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2266,7 +2227,7 @@ static int snd_hdsp_info_da_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * static int snd_hdsp_get_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_da_gain(hdsp); return 0; @@ -2274,8 +2235,7 @@ static int snd_hdsp_get_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; int val; @@ -2284,13 +2244,13 @@ static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t val = ucontrol->value.enumerated.item[0]; if (val < 0) val = 0; if (val > 2) val = 2; - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); if (val != hdsp_da_gain(hdsp)) { change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0; } else { change = 0; } - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2353,7 +2313,7 @@ static int snd_hdsp_info_ad_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * static int snd_hdsp_get_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_ad_gain(hdsp); return 0; @@ -2361,8 +2321,7 @@ static int snd_hdsp_get_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; int val; @@ -2371,13 +2330,13 @@ static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t val = ucontrol->value.enumerated.item[0]; if (val < 0) val = 0; if (val > 2) val = 2; - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); if (val != hdsp_ad_gain(hdsp)) { change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0; } else { change = 0; } - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2440,7 +2399,7 @@ static int snd_hdsp_info_phone_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_ static int snd_hdsp_get_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_phone_gain(hdsp); return 0; @@ -2448,8 +2407,7 @@ static int snd_hdsp_get_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; int val; @@ -2458,13 +2416,13 @@ static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value val = ucontrol->value.enumerated.item[0]; if (val < 0) val = 0; if (val > 2) val = 2; - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); if (val != hdsp_phone_gain(hdsp)) { change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0; } else { change = 0; } - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2507,7 +2465,7 @@ static int snd_hdsp_info_xlr_breakout_cable(snd_kcontrol_t *kcontrol, snd_ctl_el static int snd_hdsp_get_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp); return 0; @@ -2515,18 +2473,17 @@ static int snd_hdsp_get_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_el static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_xlr_breakout_cable(hdsp); hdsp_set_xlr_breakout_cable(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2573,7 +2530,7 @@ static int snd_hdsp_info_aeb(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uin static int snd_hdsp_get_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp); return 0; @@ -2581,18 +2538,17 @@ static int snd_hdsp_get_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uc static int snd_hdsp_put_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_aeb(hdsp); hdsp_set_aeb(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2662,7 +2618,7 @@ static int hdsp_set_pref_sync_ref(hdsp_t *hdsp, int pref) static int snd_hdsp_info_pref_sync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" }; - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -2691,7 +2647,7 @@ static int snd_hdsp_info_pref_sync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_in static int snd_hdsp_get_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp); return 0; @@ -2699,8 +2655,7 @@ static int snd_hdsp_get_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_va static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change, max; unsigned int val; @@ -2723,10 +2678,10 @@ static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_va } val = ucontrol->value.enumerated.item[0] % max; - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_pref_sync_ref(hdsp); hdsp_set_pref_sync_ref(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2780,9 +2735,9 @@ static int snd_hdsp_info_autosync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_inf static int snd_hdsp_get_autosync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp); + ucontrol->value.enumerated.item[0] = hdsp_autosync_ref(hdsp); return 0; } @@ -2806,19 +2761,17 @@ static int snd_hdsp_info_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t static int snd_hdsp_get_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); ucontrol->value.integer.value[0] = hdsp->passthru; - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return 0; } static int snd_hdsp_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; unsigned int val; int err = 0; @@ -2827,11 +2780,11 @@ static int snd_hdsp_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t return -EBUSY; val = ucontrol->value.integer.value[0] & 1; - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (ucontrol->value.integer.value[0] != hdsp->passthru); if (change) err = hdsp_set_passthru(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return err ? err : change; } @@ -2871,29 +2824,27 @@ static int snd_hdsp_info_line_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t static int snd_hdsp_get_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); ucontrol->value.integer.value[0] = hdsp_line_out(hdsp); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return 0; } static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *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_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = (int)val != hdsp_line_out(hdsp); hdsp_set_line_output(hdsp, val); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -2920,8 +2871,7 @@ static int snd_hdsp_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * u static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int source; int destination; int addr; @@ -2935,16 +2885,15 @@ static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * addr = hdsp_input_to_output_key(hdsp,source, destination); } - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return 0; } static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); - unsigned long flags; + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); int change; int source; int destination; @@ -2965,11 +2914,11 @@ static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * gain = ucontrol->value.integer.value[2]; - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); change = gain != hdsp_read_gain(hdsp, addr); if (change) hdsp_write_gain(hdsp, addr, gain); - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return change; } @@ -3011,7 +2960,7 @@ static int hdsp_wc_sync_check(hdsp_t *hdsp) static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_wc_sync_check(hdsp); return 0; @@ -3043,7 +2992,7 @@ static int hdsp_spdif_sync_check(hdsp_t *hdsp) static int snd_hdsp_get_spdif_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_spdif_sync_check(hdsp); return 0; @@ -3074,7 +3023,7 @@ static int hdsp_adatsync_sync_check(hdsp_t *hdsp) static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = hdsp_adatsync_sync_check(hdsp); return 0; @@ -3105,7 +3054,7 @@ static int hdsp_adat_sync_check(hdsp_t *hdsp, int idx) static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { int offset; - hdsp_t *hdsp = _snd_kcontrol_chip(kcontrol); + hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); offset = ucontrol->id.index - 1; snd_assert(offset >= 0); @@ -3194,20 +3143,16 @@ HDSP_PASSTHRU("Passthru", 0), HDSP_LINE_OUT("Line Out", 0), }; -#define HDSP_CONTROLS (sizeof(snd_hdsp_controls)/sizeof(snd_kcontrol_new_t)) - -#define HDSP_9632_CONTROLS (sizeof(snd_hdsp_9632_controls)/sizeof(snd_kcontrol_new_t)) - static snd_kcontrol_new_t snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); static snd_kcontrol_new_t snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; -int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp) +static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp) { unsigned int idx; int err; snd_kcontrol_t *kctl; - for (idx = 0; idx < HDSP_CONTROLS; idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) { return err; } @@ -3232,7 +3177,7 @@ int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp) /* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */ if (hdsp->io_type == H9632) { - for (idx = 0; idx < HDSP_9632_CONTROLS; idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) { if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0) { return err; } @@ -3289,7 +3234,7 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) snd_iprintf(buffer, "Buffers: capture %p playback %p\n", hdsp->capture_buffer, hdsp->playback_buffer); snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", - hdsp->irq, hdsp->port, hdsp->iobase); + hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase); snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register); snd_iprintf(buffer, "Control2 register: 0x%x\n", hdsp->control2_register); snd_iprintf(buffer, "Status register: 0x%x\n", status); @@ -3583,59 +3528,34 @@ static void __devinit snd_hdsp_proc_init(hdsp_t *hdsp) static void snd_hdsp_free_buffers(hdsp_t *hdsp) { - if (hdsp->capture_buffer_unaligned) { - snd_hammerfall_free_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES, - hdsp->capture_buffer_unaligned, - hdsp->capture_buffer_addr, 1); - } - - if (hdsp->playback_buffer_unaligned) { - snd_hammerfall_free_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES, - hdsp->playback_buffer_unaligned, - hdsp->playback_buffer_addr, 0); - } + snd_hammerfall_free_buffer(&hdsp->capture_dma_buf, hdsp->pci); + snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci); } static int __devinit snd_hdsp_initialize_memory(hdsp_t *hdsp) { - void *pb, *cb; - dma_addr_t pb_addr, cb_addr; unsigned long pb_bus, cb_bus; - cb = snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES, &cb_addr, 1); - pb = snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES, &pb_addr, 0); - - if (cb == 0 || pb == 0) { - if (cb) { - snd_hammerfall_free_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES, cb, cb_addr, 1); - } - if (pb) { - snd_hammerfall_free_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES, pb, pb_addr, 0); - } - + if (snd_hammerfall_get_buffer(hdsp->pci, &hdsp->capture_dma_buf, HDSP_DMA_AREA_BYTES) < 0 || + 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); return -ENOMEM; } - /* save raw addresses for use when freeing memory later */ - - hdsp->capture_buffer_unaligned = cb; - hdsp->playback_buffer_unaligned = pb; - hdsp->capture_buffer_addr = cb_addr; - hdsp->playback_buffer_addr = pb_addr; - /* Align to bus-space 64K boundary */ - cb_bus = (cb_addr + 0xFFFF) & ~0xFFFFl; - pb_bus = (pb_addr + 0xFFFF) & ~0xFFFFl; + cb_bus = (hdsp->capture_dma_buf.addr + 0xFFFF) & ~0xFFFFl; + pb_bus = (hdsp->playback_dma_buf.addr + 0xFFFF) & ~0xFFFFl; /* Tell the card where it is */ hdsp_write(hdsp, HDSP_inputBufferAddress, cb_bus); hdsp_write(hdsp, HDSP_outputBufferAddress, pb_bus); - hdsp->capture_buffer = cb + (cb_bus - cb_addr); - hdsp->playback_buffer = pb + (pb_bus - pb_addr); + hdsp->capture_buffer = hdsp->capture_dma_buf.area + (cb_bus - hdsp->capture_dma_buf.addr); + hdsp->playback_buffer = hdsp->playback_dma_buf.area + (pb_bus - hdsp->playback_dma_buf.addr); return 0; } @@ -3740,7 +3660,7 @@ static int snd_hdsp_set_defaults(hdsp_t *hdsp) return 0; } -void hdsp_midi_tasklet(unsigned long arg) +static void hdsp_midi_tasklet(unsigned long arg) { hdsp_t *hdsp = (hdsp_t *)arg; @@ -3809,7 +3729,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *reg static snd_pcm_uframes_t snd_hdsp_hw_pointer(snd_pcm_substream_t *substream) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); return hdsp_hw_pointer(hdsp); } @@ -3836,7 +3756,7 @@ static char *hdsp_channel_buffer_location(hdsp_t *hdsp, static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); char *channel_buf; snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); @@ -3851,7 +3771,7 @@ static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel, static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); char *channel_buf; snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); @@ -3866,7 +3786,7 @@ static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel, static int snd_hdsp_hw_silence(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); char *channel_buf; channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); @@ -3878,7 +3798,7 @@ static int snd_hdsp_hw_silence(snd_pcm_substream_t *substream, int channel, static int snd_hdsp_reset(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); snd_pcm_substream_t *other; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) other = hdsp->capture_substream; @@ -3906,7 +3826,7 @@ static int snd_hdsp_reset(snd_pcm_substream_t *substream) static int snd_hdsp_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); int err; pid_t this_pid; pid_t other_pid; @@ -3989,7 +3909,7 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream, static int snd_hdsp_channel_info(snd_pcm_substream_t *substream, snd_pcm_channel_info_t *info) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); int mapped_channel; snd_assert(info->channel < hdsp->max_channels, return -EINVAL); @@ -4026,7 +3946,7 @@ static int snd_hdsp_ioctl(snd_pcm_substream_t *substream, static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); snd_pcm_substream_t *other; int running; @@ -4105,7 +4025,7 @@ static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd) static int snd_hdsp_prepare(snd_pcm_substream_t *substream) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); + hdsp_t *hdsp = snd_pcm_substream_chip(substream); int result = 0; if (hdsp_check_for_iobox (hdsp)) { @@ -4123,10 +4043,10 @@ static int snd_hdsp_prepare(snd_pcm_substream_t *substream) return -EIO; } - spin_lock(&hdsp->lock); + spin_lock_irq(&hdsp->lock); if (!hdsp->running) hdsp_reset_hw_pointer(hdsp); - spin_unlock(&hdsp->lock); + spin_unlock_irq(&hdsp->lock); return result; } @@ -4183,20 +4103,16 @@ static snd_pcm_hardware_t snd_hdsp_capture_subinfo = static unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 }; -#define HDSP_PERIOD_SIZES sizeof(hdsp_period_sizes) / sizeof(hdsp_period_sizes[0]) - static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_period_sizes = { - .count = HDSP_PERIOD_SIZES, + .count = ARRAY_SIZE(hdsp_period_sizes), .list = hdsp_period_sizes, .mask = 0 }; static unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; -#define HDSP_9632_SAMPLE_RATES sizeof(hdsp_9632_sample_rates) / sizeof(hdsp_9632_sample_rates[0]) - static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_9632_sample_rates = { - .count = HDSP_9632_SAMPLE_RATES, + .count = ARRAY_SIZE(hdsp_9632_sample_rates), .list = hdsp_9632_sample_rates, .mask = 0 }; @@ -4364,8 +4280,7 @@ static int snd_hdsp_hw_rule_rate_in_channels(snd_pcm_hw_params_t *params, static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); - unsigned long flags; + hdsp_t *hdsp = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; if (hdsp_check_for_iobox (hdsp)) { @@ -4383,7 +4298,7 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) return -EIO; } - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); snd_pcm_set_sync(substream); @@ -4399,7 +4314,7 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) hdsp->playback_pid = current->pid; hdsp->playback_substream = substream; - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); @@ -4430,15 +4345,14 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) static int snd_hdsp_playback_release(snd_pcm_substream_t *substream) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); - unsigned long flags; + hdsp_t *hdsp = snd_pcm_substream_chip(substream); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); hdsp->playback_pid = -1; hdsp->playback_substream = NULL; - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | @@ -4449,8 +4363,7 @@ static int snd_hdsp_playback_release(snd_pcm_substream_t *substream) static int snd_hdsp_capture_open(snd_pcm_substream_t *substream) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); - unsigned long flags; + hdsp_t *hdsp = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; if (hdsp_check_for_iobox (hdsp)) { @@ -4468,7 +4381,7 @@ static int snd_hdsp_capture_open(snd_pcm_substream_t *substream) return -EIO; } - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); snd_pcm_set_sync(substream); @@ -4484,7 +4397,7 @@ static int snd_hdsp_capture_open(snd_pcm_substream_t *substream) hdsp->capture_pid = current->pid; hdsp->capture_substream = substream; - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); @@ -4509,15 +4422,14 @@ static int snd_hdsp_capture_open(snd_pcm_substream_t *substream) static int snd_hdsp_capture_release(snd_pcm_substream_t *substream) { - hdsp_t *hdsp = _snd_pcm_substream_chip(substream); - unsigned long flags; + hdsp_t *hdsp = snd_pcm_substream_chip(substream); - spin_lock_irqsave(&hdsp->lock, flags); + spin_lock_irq(&hdsp->lock); hdsp->capture_pid = -1; hdsp->capture_substream = NULL; - spin_unlock_irqrestore(&hdsp->lock, flags); + spin_unlock_irq(&hdsp->lock); return 0; } @@ -4528,6 +4440,130 @@ static int snd_hdsp_hwdep_dummy_op(snd_hwdep_t *hw, struct file *file) } +/* helper functions for copying meter values */ +static inline int copy_u32_le(void __user *dest, void __iomem *src) +{ + u32 val = readl(src); + return copy_to_user(dest, &val, 4); +} + +static inline int copy_u64_le(void __user *dest, void __iomem *src_low, void __iomem *src_high) +{ + u32 rms_low, rms_high; + u64 rms; + rms_low = readl(src_low); + rms_high = readl(src_high); + rms = ((u64)rms_high << 32) | rms_low; + return copy_to_user(dest, &rms, 8); +} + +static inline int copy_u48_le(void __user *dest, void __iomem *src_low, void __iomem *src_high) +{ + u32 rms_low, rms_high; + u64 rms; + rms_low = readl(src_low) & 0xffffff00; + rms_high = readl(src_high) & 0xffffff00; + rms = ((u64)rms_high << 32) | rms_low; + return copy_to_user(dest, &rms, 8); +} + +static int hdsp_9652_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms) +{ + int doublespeed = 0; + int i, j, channels, ofs; + + if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus) + doublespeed = 1; + channels = doublespeed ? 14 : 26; + for (i = 0, j = 0; i < 26; ++i) { + if (doublespeed && (i & 4)) + continue; + ofs = HDSP_9652_peakBase - j * 4; + if (copy_u32_le(&peak_rms->input_peaks[i], hdsp->iobase + ofs)) + return -EFAULT; + ofs -= channels * 4; + if (copy_u32_le(&peak_rms->playback_peaks[i], hdsp->iobase + ofs)) + return -EFAULT; + ofs -= channels * 4; + if (copy_u32_le(&peak_rms->output_peaks[i], hdsp->iobase + ofs)) + return -EFAULT; + ofs = HDSP_9652_rmsBase + j * 8; + if (copy_u48_le(&peak_rms->input_rms[i], hdsp->iobase + ofs, + hdsp->iobase + ofs + 4)) + return -EFAULT; + ofs += channels * 8; + if (copy_u48_le(&peak_rms->playback_rms[i], hdsp->iobase + ofs, + hdsp->iobase + ofs + 4)) + return -EFAULT; + ofs += channels * 8; + if (copy_u48_le(&peak_rms->output_rms[i], hdsp->iobase + ofs, + hdsp->iobase + ofs + 4)) + return -EFAULT; + j++; + } + return 0; +} + +static int hdsp_9632_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms) +{ + int i, j; + hdsp_9632_meters_t __iomem *m; + int doublespeed = 0; + + if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus) + doublespeed = 1; + m = (hdsp_9632_meters_t __iomem *)(hdsp->iobase+HDSP_9632_metersBase); + for (i = 0, j = 0; i < 16; ++i, ++j) { + if (copy_u32_le(&peak_rms->input_peaks[i], &m->input_peak[j])) + return -EFAULT; + if (copy_u32_le(&peak_rms->playback_peaks[i], &m->playback_peak[j])) + return -EFAULT; + if (copy_u32_le(&peak_rms->output_peaks[i], &m->output_peak[j])) + return -EFAULT; + if (copy_u64_le(&peak_rms->input_rms[i], &m->input_rms_low[j], + &m->input_rms_high[j])) + return -EFAULT; + if (copy_u64_le(&peak_rms->playback_rms[i], &m->playback_rms_low[j], + &m->playback_rms_high[j])) + return -EFAULT; + if (copy_u64_le(&peak_rms->output_rms[i], &m->output_rms_low[j], + &m->output_rms_high[j])) + return -EFAULT; + if (doublespeed && i == 3) i += 4; + } + return 0; +} + +static int hdsp_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms) +{ + int i; + + for (i = 0; i < 26; i++) { + if (copy_u32_le(&peak_rms->playback_peaks[i], + hdsp->iobase + HDSP_playbackPeakLevel + i * 4)) + return -EFAULT; + if (copy_u32_le(&peak_rms->input_peaks[i], + hdsp->iobase + HDSP_inputPeakLevel + i * 4)) + return -EFAULT; + } + for (i = 0; i < 28; i++) { + if (copy_u32_le(&peak_rms->output_peaks[i], + hdsp->iobase + HDSP_outputPeakLevel + i * 4)) + return -EFAULT; + } + for (i = 0; i < 26; ++i) { + if (copy_u64_le(&peak_rms->playback_rms[i], + hdsp->iobase + HDSP_playbackRmsLevel + i * 8, + hdsp->iobase + HDSP_playbackRmsLevel + i * 8 + 4)) + return -EFAULT; + if (copy_u64_le(&peak_rms->input_rms[i], + hdsp->iobase + HDSP_inputRmsLevel + i * 8, + hdsp->iobase + HDSP_inputRmsLevel + i * 8 + 4)) + return -EFAULT; + } + return 0; +} + static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg) { hdsp_t *hdsp = (hdsp_t *)hw->private_data; @@ -4535,108 +4571,21 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int switch (cmd) { case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: { - hdsp_peak_rms_t __user *peak_rms; - int i; - - if (hdsp->io_type == H9652) { - unsigned long rms_low, rms_high; - int doublespeed = 0; - if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus) - doublespeed = 1; - peak_rms = (hdsp_peak_rms_t __user *)arg; - for (i = 0; i < 26; ++i) { - if (!(doublespeed && (i & 4))) { - if (copy_to_user_fromio((void __user *)peak_rms->input_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-i*4, 4) != 0) - return -EFAULT; - if (copy_to_user_fromio((void __user *)peak_rms->playback_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-(doublespeed ? 14 : 26)*4-i*4, 4) != 0) - return -EFAULT; - if (copy_to_user_fromio((void __user *)peak_rms->output_peaks+i*4, hdsp->iobase+HDSP_9652_peakBase-2*(doublespeed ? 14 : 26)*4-i*4, 4) != 0) - return -EFAULT; - rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8) & 0xFFFFFF00; - rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+i*8+4) & 0xFFFFFF00; - rms_high += (rms_low >> 24); - rms_low <<= 8; - if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &rms_low, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &rms_high, 4) != 0) - return -EFAULT; - rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00; - rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00; - rms_high += (rms_low >> 24); - rms_low <<= 8; - if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &rms_low, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &rms_high, 4) != 0) - return -EFAULT; - rms_low = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8) & 0xFFFFFF00; - rms_high = *(u32 *)(hdsp->iobase+HDSP_9652_rmsBase+2*(doublespeed ? 14 : 26)*8+i*8+4) & 0xFFFFFF00; - rms_high += (rms_low >> 24); - rms_low <<= 8; - if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &rms_low, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &rms_high, 4) != 0) - return -EFAULT; - } - } - return 0; - } - if (hdsp->io_type == H9632) { - int j; - hdsp_9632_meters_t *m; - int doublespeed = 0; - if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus) - doublespeed = 1; - m = (hdsp_9632_meters_t *)(hdsp->iobase+HDSP_9632_metersBase); - peak_rms = (hdsp_peak_rms_t __user *)arg; - for (i = 0, j = 0; i < 16; ++i, ++j) { - if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, &(m->input_peak[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, &(m->playback_peak[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, &(m->output_peak[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->input_rms+i*8, &(m->input_rms_low[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, &(m->playback_rms_low[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->output_rms+i*8, &(m->output_rms_low[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, &(m->input_rms_high[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, &(m->playback_rms_high[j]), 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->output_rms+i*8+4, &(m->output_rms_high[j]), 4) != 0) - return -EFAULT; - if (doublespeed && i == 3) i += 4; - } - return 0; - } + hdsp_peak_rms_t __user *peak_rms = (hdsp_peak_rms_t __user *)arg; + if (!(hdsp->state & HDSP_FirmwareLoaded)) { - snd_printk("firmware needs to be uploaded to the card.\n"); + snd_printk(KERN_ERR "firmware needs to be uploaded to the card.\n"); return -EINVAL; } - peak_rms = (hdsp_peak_rms_t __user *)arg; - for (i = 0; i < 26; ++i) { - if (copy_to_user((void __user *)peak_rms->playback_peaks+i*4, (void *)hdsp->iobase+HDSP_playbackPeakLevel+i*4, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->input_peaks+i*4, (void *)hdsp->iobase+HDSP_inputPeakLevel+i*4, 4) != 0) - return -EFAULT; - } - for (i = 0; i < 26; ++i) { - if (copy_to_user((void __user *)peak_rms->playback_rms+i*8+4, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->playback_rms+i*8, (void *)hdsp->iobase+HDSP_playbackRmsLevel+i*8+4, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->input_rms+i*8+4, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8, 4) != 0) - return -EFAULT; - if (copy_to_user((void __user *)peak_rms->input_rms+i*8, (void *)hdsp->iobase+HDSP_inputRmsLevel+i*8+4, 4) != 0) - return -EFAULT; - } - for (i = 0; i < 28; ++i) { - if (copy_to_user((void __user *)peak_rms->output_peaks+i*4, (void *)hdsp->iobase+HDSP_outputPeakLevel+i*4, 4) != 0) - return -EFAULT; + + switch (hdsp->io_type) { + case H9652: + return hdsp_9652_get_peak(hdsp, peak_rms); + case H9632: + return hdsp_9632_get_peak(hdsp, peak_rms); + default: + return hdsp_get_peak(hdsp, peak_rms); } - break; } case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: { hdsp_config_info_t info; @@ -4712,15 +4661,19 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int } break; } +#ifndef HDSP_FW_LOADER case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: { hdsp_firmware_t __user *firmware; - unsigned long __user *firmware_data; + u32 __user *firmware_data; int err; if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL; /* SNDRV_HDSP_IOCTL_GET_VERSION must have been called */ if (hdsp->io_type == Undefined) return -EINVAL; + if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded)) + return -EBUSY; + snd_printk("initializing firmware upload\n"); firmware = (hdsp_firmware_t __user *)argp; @@ -4732,7 +4685,7 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int return -EIO; } - if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(unsigned long)*24413) != 0) { + if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) { return -EFAULT; } @@ -4754,6 +4707,7 @@ static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int } break; } +#endif case SNDRV_HDSP_IOCTL_GET_MIXER: { hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp; if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE)) @@ -4809,8 +4763,7 @@ static int __devinit snd_hdsp_create_hwdep(snd_card_t *card, return 0; } -static int __devinit snd_hdsp_create_pcm(snd_card_t *card, - hdsp_t *hdsp) +static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp) { snd_pcm_t *pcm; int err; @@ -4830,19 +4783,13 @@ static int __devinit snd_hdsp_create_pcm(snd_card_t *card, return 0; } -static inline void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp) +static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp) { hdsp->control2_register |= HDSP_9652_ENABLE_MIXER; hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register); } -static inline void snd_hdsp_9652_disable_mixer (hdsp_t *hdsp) -{ - hdsp->control2_register &= ~HDSP_9652_ENABLE_MIXER; - hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register); -} - -static inline int snd_hdsp_enable_io (hdsp_t *hdsp) +static int snd_hdsp_enable_io (hdsp_t *hdsp) { int i; @@ -4858,7 +4805,7 @@ static inline int snd_hdsp_enable_io (hdsp_t *hdsp) return 0; } -static inline void snd_hdsp_initialize_channels(hdsp_t *hdsp) +static void snd_hdsp_initialize_channels(hdsp_t *hdsp) { int status, aebi_channels, aebo_channels; @@ -4901,13 +4848,13 @@ static inline void snd_hdsp_initialize_channels(hdsp_t *hdsp) } } -static inline void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp) +static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp) { snd_hdsp_flush_midi_input (hdsp, 0); snd_hdsp_flush_midi_input (hdsp, 1); } -static int __devinit snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp) +static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp) { int err; @@ -4960,6 +4907,86 @@ static int __devinit snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp return 0; } +#ifdef HDSP_FW_LOADER +/* load firmware via hotplug fw loader */ +static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp) +{ + const char *fwfile; + const struct firmware *fw; + int err; + + if (hdsp->io_type == H9652 || hdsp->io_type == H9632) + return 0; + if (hdsp->io_type == Undefined) { + if ((err = hdsp_get_iobox_version(hdsp)) < 0) + return err; + if (hdsp->io_type == H9652 || hdsp->io_type == H9632) + return 0; + } + if (hdsp_check_for_iobox (hdsp)) + return -EIO; + + /* caution: max length of firmware filename is 30! */ + switch (hdsp->io_type) { + case Multiface: + if (hdsp->firmware_rev == 0xa) + fwfile = "multiface_firmware.bin"; + else + fwfile = "multiface_firmware_rev11.bin"; + break; + case Digiface: + if (hdsp->firmware_rev == 0xa) + fwfile = "digiface_firmware.bin"; + else + fwfile = "digiface_firmware_rev11.bin"; + break; + default: + snd_printk(KERN_ERR "hdsp: invalid io_type %d\n", hdsp->io_type); + return -EINVAL; + } + + if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) { + snd_printk(KERN_ERR "hdsp: cannot load firmware %s\n", fwfile); + return -ENOENT; + } + if (fw->size < sizeof(hdsp->firmware_cache)) { + snd_printk(KERN_ERR "hdsp: too short firmware size %d (expected %d)\n", + (int)fw->size, (int)sizeof(hdsp->firmware_cache)); + release_firmware(fw); + return -EINVAL; + } +#ifdef SNDRV_BIG_ENDIAN + { + int i; + u32 *src = (void *)fw->data; + for (i = 0; i < ARRAY_SIZE(hdsp->firmware_cache); i++, src++) + hdsp->firmware_cache[i] = ((*src & 0x000000ff) << 16) | + ((*src & 0x0000ff00) << 8) | + ((*src & 0x00ff0000) >> 8) | + ((*src & 0xff000000) >> 16); + } +#else + memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache)); +#endif + release_firmware(fw); + + hdsp->state |= HDSP_FirmwareCached; + + if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0) + return err; + + if (!(hdsp->state & HDSP_InitializationComplete)) { + snd_hdsp_initialize_channels(hdsp); + snd_hdsp_initialize_midi_flush(hdsp); + if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) { + snd_printk("error creating alsa devices\n"); + return err; + } + } + return 0; +} +#endif + static int __devinit snd_hdsp_create(snd_card_t *card, hdsp_t *hdsp, int precise_ptr) @@ -4979,8 +5006,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card, hdsp->midi[1].output = NULL; spin_lock_init(&hdsp->midi[0].lock); spin_lock_init(&hdsp->midi[1].lock); - hdsp->iobase = 0; - hdsp->res_port = NULL; + hdsp->iobase = NULL; hdsp->control_register = 0; hdsp->control2_register = 0; hdsp->io_type = Undefined; @@ -5035,14 +5061,10 @@ static int __devinit snd_hdsp_create(snd_card_t *card, pci_set_master(hdsp->pci); + if ((err = pci_request_regions(pci, "hdsp")) < 0) + return err; hdsp->port = pci_resource_start(pci, 0); - - if ((hdsp->res_port = request_mem_region(hdsp->port, HDSP_IO_EXTENT, "hdsp")) == NULL) { - snd_printk("unable to grab memory region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1); - return -EBUSY; - } - - if ((hdsp->iobase = (unsigned long) ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == 0) { + if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) { snd_printk("unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1); return -EBUSY; } @@ -5073,11 +5095,16 @@ static int __devinit snd_hdsp_create(snd_card_t *card, } if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { +#ifdef HDSP_FW_LOADER + if ((err = hdsp_request_fw_loader(hdsp)) < 0) + return err; +#else snd_printk("card initialization pending : waiting for firmware\n"); if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) { return err; } return 0; +#endif } snd_printk("Firmware already loaded, initializing card.\n"); @@ -5114,7 +5141,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card, static int snd_hdsp_free(hdsp_t *hdsp) { - if (hdsp->res_port) { + if (hdsp->port) { /* stop the audio, and cancel all interrupts */ hdsp->control_register &= ~(HDSP_Start|HDSP_AudioInterruptEnable|HDSP_Midi0InterruptEnable|HDSP_Midi1InterruptEnable); hdsp_write (hdsp, HDSP_controlRegister, hdsp->control_register); @@ -5126,13 +5153,12 @@ static int snd_hdsp_free(hdsp_t *hdsp) snd_hdsp_free_buffers(hdsp); if (hdsp->iobase) - iounmap((void *) hdsp->iobase); + iounmap(hdsp->iobase); - if (hdsp->res_port) { - release_resource(hdsp->res_port); - kfree_nocheck(hdsp->res_port); - } + if (hdsp->port) + pci_release_regions(hdsp->pci); + pci_disable_device(hdsp->pci); return 0; }