X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fpci%2Fcs46xx%2Fcs46xx_lib.c;h=9b18681418c820188e5aa374ba08c6b7925d58d0;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=9a1758396395b0ee487376ddd3f28802224c2054;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 9a1758396..9b1868141 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -79,6 +79,8 @@ static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip, (codec_index == CS46XX_SECONDARY_CODEC_INDEX), return -EINVAL); + chip->active_ctrl(chip, 1); + if (codec_index == CS46XX_SECONDARY_CODEC_INDEX) offset = CS46XX_SECONDARY_CODEC_OFFSET; @@ -184,27 +186,22 @@ static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip, //snd_cs46xx_peekBA0(chip, BA0_ACCAD); result = snd_cs46xx_peekBA0(chip, BA0_ACSDA + offset); end: + chip->active_ctrl(chip, -1); return result; } static unsigned short snd_cs46xx_ac97_read(ac97_t * ac97, unsigned short reg) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, ac97->private_data, return -ENXIO); + cs46xx_t *chip = ac97->private_data; unsigned short val; - int codec_index = -1; - - /* UGGLY: nr_ac97_codecs == 0 primery codec detection is in progress */ - if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] || chip->nr_ac97_codecs == 0) - codec_index = CS46XX_PRIMARY_CODEC_INDEX; - /* UGGLY: nr_ac97_codecs == 1 secondary codec detection is in progress */ - else if (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] || chip->nr_ac97_codecs == 1) - codec_index = CS46XX_SECONDARY_CODEC_INDEX; - else - snd_assert(0, return 0xffff); - chip->active_ctrl(chip, 1); + int codec_index = ac97->num; + + snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || + codec_index == CS46XX_SECONDARY_CODEC_INDEX, + return 0xffff); + val = snd_cs46xx_codec_read(chip, reg, codec_index); - chip->active_ctrl(chip, -1); /* HACK: voyetra uses EAPD bit in the reverse way. * we flip the bit to show the mixer status correctly @@ -227,6 +224,8 @@ static void snd_cs46xx_codec_write(cs46xx_t *chip, (codec_index == CS46XX_SECONDARY_CODEC_INDEX), return); + chip->active_ctrl(chip, 1); + /* * 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address * 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 @@ -271,27 +270,24 @@ static void snd_cs46xx_codec_write(cs46xx_t *chip, * ACCTL = 460h, DCV should be reset by now and 460h = 07h */ if (!(snd_cs46xx_peekBA0(chip, BA0_ACCTL) & ACCTL_DCV)) { - return; + goto end; } } snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val); + end: + chip->active_ctrl(chip, -1); } static void snd_cs46xx_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, ac97->private_data, return); - int codec_index = -1; + cs46xx_t *chip = ac97->private_data; + int codec_index = ac97->num; - /* UGGLY: nr_ac97_codecs == 0 primery codec detection is in progress */ - if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] || chip->nr_ac97_codecs == 0) - codec_index = CS46XX_PRIMARY_CODEC_INDEX; - /* UGGLY: nr_ac97_codecs == 1 secondary codec detection is in progress */ - else if (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] || chip->nr_ac97_codecs == 1) - codec_index = CS46XX_SECONDARY_CODEC_INDEX; - else - snd_assert(0,return); + snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || + codec_index == CS46XX_SECONDARY_CODEC_INDEX, + return); /* HACK: voyetra uses EAPD bit in the reverse way. * we flip the bit to show the mixer status correctly @@ -299,9 +295,7 @@ static void snd_cs46xx_ac97_write(ac97_t *ac97, if (reg == AC97_POWERDOWN && chip->amplifier_ctrl == amp_voyetra) val ^= 0x8000; - chip->active_ctrl(chip, 1); snd_cs46xx_codec_write(chip, reg, val, codec_index); - chip->active_ctrl(chip, -1); } @@ -688,84 +682,35 @@ static void snd_cs46xx_set_capture_sample_rate(cs46xx_t *chip, unsigned int rate * PCM part */ +static void snd_cs46xx_pb_trans_copy(snd_pcm_substream_t *substream, + snd_pcm_indirect_t *rec, size_t bytes) +{ + snd_pcm_runtime_t *runtime = substream->runtime; + cs46xx_pcm_t * cpcm = runtime->private_data; + memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes); +} + static int snd_cs46xx_playback_transfer(snd_pcm_substream_t *substream) { - /* cs46xx_t *chip = snd_pcm_substream_chip(substream); */ snd_pcm_runtime_t *runtime = substream->runtime; - cs46xx_pcm_t * cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO); - snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr; - snd_pcm_sframes_t diff = appl_ptr - cpcm->appl_ptr; - int buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; - - if (diff) { - if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) - diff += runtime->boundary; - cpcm->sw_ready += diff * (1 << cpcm->shift); - cpcm->appl_ptr = appl_ptr; - } - while (cpcm->hw_ready < buffer_size && - cpcm->sw_ready > 0) { - size_t hw_to_end = buffer_size - cpcm->hw_data; - size_t sw_to_end = cpcm->sw_bufsize - cpcm->sw_data; - size_t bytes = buffer_size - cpcm->hw_ready; - if (cpcm->sw_ready < (int)bytes) - bytes = cpcm->sw_ready; - if (hw_to_end < bytes) - bytes = hw_to_end; - if (sw_to_end < bytes) - bytes = sw_to_end; - memcpy(cpcm->hw_buf.area + cpcm->hw_data, - runtime->dma_area + cpcm->sw_data, - bytes); - cpcm->hw_data += bytes; - if ((int)cpcm->hw_data == buffer_size) - cpcm->hw_data = 0; - cpcm->sw_data += bytes; - if (cpcm->sw_data == cpcm->sw_bufsize) - cpcm->sw_data = 0; - cpcm->hw_ready += bytes; - cpcm->sw_ready -= bytes; - } + cs46xx_pcm_t * cpcm = runtime->private_data; + snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy); return 0; } -static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream) +static void snd_cs46xx_cp_trans_copy(snd_pcm_substream_t *substream, + snd_pcm_indirect_t *rec, size_t bytes) { cs46xx_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr; - snd_pcm_sframes_t diff = appl_ptr - chip->capt.appl_ptr; - int buffer_size = runtime->period_size * CS46XX_FRAGS << chip->capt.shift; - - if (diff) { - if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) - diff += runtime->boundary; - chip->capt.sw_ready -= diff * (1 << chip->capt.shift); - chip->capt.appl_ptr = appl_ptr; - } - while (chip->capt.hw_ready > 0 && - chip->capt.sw_ready < (int)chip->capt.sw_bufsize) { - size_t hw_to_end = buffer_size - chip->capt.hw_data; - size_t sw_to_end = chip->capt.sw_bufsize - chip->capt.sw_data; - size_t bytes = chip->capt.sw_bufsize - chip->capt.sw_ready; - if (chip->capt.hw_ready < (int)bytes) - bytes = chip->capt.hw_ready; - if (hw_to_end < bytes) - bytes = hw_to_end; - if (sw_to_end < bytes) - bytes = sw_to_end; - memcpy(runtime->dma_area + chip->capt.sw_data, - chip->capt.hw_buf.area + chip->capt.hw_data, - bytes); - chip->capt.hw_data += bytes; - if ((int)chip->capt.hw_data == buffer_size) - chip->capt.hw_data = 0; - chip->capt.sw_data += bytes; - if (chip->capt.sw_data == chip->capt.sw_bufsize) - chip->capt.sw_data = 0; - chip->capt.hw_ready -= bytes; - chip->capt.sw_ready += bytes; - } + memcpy(runtime->dma_area + rec->sw_data, + chip->capt.hw_buf.area + rec->hw_data, bytes); +} + +static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream) +{ + cs46xx_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy); return 0; } @@ -773,7 +718,7 @@ static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(snd_pcm_substream_t { cs46xx_t *chip = snd_pcm_substream_chip(substream); size_t ptr; - cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO); + cs46xx_pcm_t *cpcm = substream->runtime->private_data; snd_assert (cpcm->pcm_channel,return -ENXIO); #ifdef CONFIG_SND_CS46XX_NEW_DSP @@ -789,9 +734,7 @@ static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(snd_pcm_substream_ { cs46xx_t *chip = snd_pcm_substream_chip(substream); size_t ptr; - cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO); - ssize_t bytes; - int buffer_size = substream->runtime->period_size * CS46XX_FRAGS << cpcm->shift; + cs46xx_pcm_t *cpcm = substream->runtime->private_data; #ifdef CONFIG_SND_CS46XX_NEW_DSP snd_assert (cpcm->pcm_channel,return -ENXIO); @@ -800,18 +743,7 @@ static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(snd_pcm_substream_ ptr = snd_cs46xx_peek(chip, BA1_PBA); #endif ptr -= cpcm->hw_buf.addr; - - bytes = ptr - cpcm->hw_io; - - if (bytes < 0) - bytes += buffer_size; - cpcm->hw_io = ptr; - cpcm->hw_ready -= bytes; - cpcm->sw_io += bytes; - if (cpcm->sw_io >= cpcm->sw_bufsize) - cpcm->sw_io -= cpcm->sw_bufsize; - snd_cs46xx_playback_transfer(substream); - return cpcm->sw_io >> cpcm->shift; + return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr); } static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(snd_pcm_substream_t * substream) @@ -825,18 +757,7 @@ static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(snd_pcm_substream_t { cs46xx_t *chip = snd_pcm_substream_chip(substream); size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr; - ssize_t bytes = ptr - chip->capt.hw_io; - int buffer_size = substream->runtime->period_size * CS46XX_FRAGS << chip->capt.shift; - - if (bytes < 0) - bytes += buffer_size; - chip->capt.hw_io = ptr; - chip->capt.hw_ready += bytes; - chip->capt.sw_io += bytes; - if (chip->capt.sw_io >= chip->capt.sw_bufsize) - chip->capt.sw_io -= chip->capt.sw_bufsize; - snd_cs46xx_capture_transfer(substream); - return chip->capt.sw_io >> chip->capt.shift; + return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr); } static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, @@ -847,13 +768,7 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, int result = 0; #ifdef CONFIG_SND_CS46XX_NEW_DSP - cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO); -#else - spin_lock(&chip->reg_lock); -#endif - -#ifdef CONFIG_SND_CS46XX_NEW_DSP - + cs46xx_pcm_t *cpcm = substream->runtime->private_data; if (! cpcm->pcm_channel) { return -ENXIO; } @@ -872,6 +787,7 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, if (substream->runtime->periods != CS46XX_FRAGS) snd_cs46xx_playback_transfer(substream); #else + spin_lock(&chip->reg_lock); if (substream->runtime->periods != CS46XX_FRAGS) snd_cs46xx_playback_transfer(substream); { unsigned int tmp; @@ -879,6 +795,7 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, tmp &= 0x0000ffff; snd_cs46xx_poke(chip, BA1_PCTL, chip->play_ctl | tmp); } + spin_unlock(&chip->reg_lock); #endif break; case SNDRV_PCM_TRIGGER_STOP: @@ -891,11 +808,13 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, if (!cpcm->pcm_channel->unlinked) cs46xx_dsp_pcm_unlink(chip,cpcm->pcm_channel); #else + spin_lock(&chip->reg_lock); { unsigned int tmp; tmp = snd_cs46xx_peek(chip, BA1_PCTL); tmp &= 0x0000ffff; snd_cs46xx_poke(chip, BA1_PCTL, tmp); } + spin_unlock(&chip->reg_lock); #endif break; default: @@ -903,10 +822,6 @@ static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream, break; } -#ifndef CONFIG_SND_CS46XX_NEW_DSP - spin_unlock(&chip->reg_lock); -#endif - return result; } @@ -987,7 +902,7 @@ static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream, int sample_rate = params_rate(hw_params); int period_size = params_period_bytes(hw_params); #endif - cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO); + cpcm = runtime->private_data; #ifdef CONFIG_SND_CS46XX_NEW_DSP snd_assert (sample_rate != 0, return -ENXIO); @@ -1084,7 +999,7 @@ static int snd_cs46xx_playback_hw_free(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; cs46xx_pcm_t *cpcm; - cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO); + cpcm = runtime->private_data; /* if play_back open fails, then this function is called and cpcm can actually be NULL here */ @@ -1108,7 +1023,7 @@ static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; cs46xx_pcm_t *cpcm; - cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO); + cpcm = runtime->private_data; #ifdef CONFIG_SND_CS46XX_NEW_DSP snd_assert (cpcm->pcm_channel != NULL, return -ENXIO); @@ -1143,10 +1058,9 @@ static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream) pfie |= 0x00004000; } - cpcm->sw_bufsize = snd_pcm_lib_buffer_bytes(substream); - cpcm->sw_data = cpcm->sw_io = cpcm->sw_ready = 0; - cpcm->hw_data = cpcm->hw_io = cpcm->hw_ready = 0; - cpcm->appl_ptr = 0; + memset(&cpcm->pcm_rec, 0, sizeof(cpcm->pcm_rec)); + cpcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); + cpcm->pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; #ifdef CONFIG_SND_CS46XX_NEW_DSP @@ -1223,10 +1137,9 @@ static int snd_cs46xx_capture_prepare(snd_pcm_substream_t * substream) snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr); chip->capt.shift = 2; - chip->capt.sw_bufsize = snd_pcm_lib_buffer_bytes(substream); - chip->capt.sw_data = chip->capt.sw_io = chip->capt.sw_ready = 0; - chip->capt.hw_data = chip->capt.hw_io = chip->capt.hw_ready = 0; - chip->capt.appl_ptr = 0; + memset(&chip->capt.pcm_rec, 0, sizeof(chip->capt.pcm_rec)); + chip->capt.pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); + chip->capt.pcm_rec.hw_buffer_size = runtime->period_size * CS46XX_FRAGS << 2; snd_cs46xx_set_capture_sample_rate(chip, runtime->rate); return 0; @@ -1234,7 +1147,7 @@ static int snd_cs46xx_capture_prepare(snd_pcm_substream_t * substream) static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, dev_id, return IRQ_NONE); + cs46xx_t *chip = dev_id; u32 status1; #ifdef CONFIG_SND_CS46XX_NEW_DSP dsp_spos_instance_t * ins = chip->dsp_spos_instance; @@ -1265,7 +1178,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *r if (ins->pcm_channels[i].active && ins->pcm_channels[i].private_data && !ins->pcm_channels[i].unlinked) { - cpcm = snd_magic_cast(cs46xx_pcm_t, ins->pcm_channels[i].private_data, continue); + cpcm = ins->pcm_channels[i].private_data; snd_pcm_period_elapsed(cpcm->substream); } } @@ -1275,7 +1188,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *r if (ins->pcm_channels[i].active && ins->pcm_channels[i].private_data && !ins->pcm_channels[i].unlinked) { - cpcm = snd_magic_cast(cs46xx_pcm_t, ins->pcm_channels[i].private_data, continue); + cpcm = ins->pcm_channels[i].private_data; snd_pcm_period_elapsed(cpcm->substream); } } @@ -1302,7 +1215,9 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *r c = snd_cs46xx_peekBA0(chip, BA0_MIDRP); if ((chip->midcr & MIDCR_RIE) == 0) continue; + spin_unlock(&chip->reg_lock); snd_rawmidi_receive(chip->midi_input, &c, 1); + spin_lock(&chip->reg_lock); } while ((snd_cs46xx_peekBA0(chip, BA0_MIDSR) & MIDSR_TBF) == 0) { if ((chip->midcr & MIDCR_TIE) == 0) @@ -1370,10 +1285,8 @@ static snd_pcm_hardware_t snd_cs46xx_capture = static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; -#define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0]) - static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = { - .count = PERIOD_SIZES, + .count = ARRAY_SIZE(period_sizes), .list = period_sizes, .mask = 0 }; @@ -1382,10 +1295,8 @@ static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = { static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime) { - cs46xx_pcm_t * cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return); - - if (cpcm) - snd_magic_kfree(cpcm); + cs46xx_pcm_t * cpcm = runtime->private_data; + kfree(cpcm); } static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pcm_channel_id) @@ -1394,11 +1305,12 @@ static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pc cs46xx_pcm_t * cpcm; snd_pcm_runtime_t *runtime = substream->runtime; - cpcm = snd_magic_kcalloc(cs46xx_pcm_t, 0, GFP_KERNEL); + cpcm = kcalloc(1, sizeof(*cpcm), GFP_KERNEL); if (cpcm == NULL) return -ENOMEM; - if (snd_dma_alloc_pages(&chip->dma_dev, PAGE_SIZE, &cpcm->hw_buf) < 0) { - snd_magic_kfree(cpcm); + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), + PAGE_SIZE, &cpcm->hw_buf) < 0) { + kfree(cpcm); return -ENOMEM; } @@ -1486,7 +1398,8 @@ static int snd_cs46xx_capture_open(snd_pcm_substream_t * substream) { cs46xx_t *chip = snd_pcm_substream_chip(substream); - if (snd_dma_alloc_pages(&chip->dma_dev, PAGE_SIZE, &chip->capt.hw_buf) < 0) + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), + PAGE_SIZE, &chip->capt.hw_buf) < 0) return -ENOMEM; chip->capt.substream = substream; substream->runtime->hw = snd_cs46xx_capture; @@ -1510,7 +1423,7 @@ static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream) snd_pcm_runtime_t *runtime = substream->runtime; cs46xx_pcm_t * cpcm; - cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO); + cpcm = runtime->private_data; /* when playback_open fails, then cpcm can be NULL */ if (!cpcm) return -ENXIO; @@ -1527,7 +1440,7 @@ static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream) #endif cpcm->substream = NULL; - snd_dma_free_pages(&chip->dma_dev, &cpcm->hw_buf); + snd_dma_free_pages(&cpcm->hw_buf); chip->active_ctrl(chip, -1); return 0; @@ -1538,7 +1451,7 @@ static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream) cs46xx_t *chip = snd_pcm_substream_chip(substream); chip->capt.substream = NULL; - snd_dma_free_pages(&chip->dma_dev, &chip->capt.hw_buf); + snd_dma_free_pages(&chip->capt.hw_buf); chip->active_ctrl(chip, -1); return 0; @@ -1664,7 +1577,7 @@ snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = { static void snd_cs46xx_pcm_free(snd_pcm_t *pcm) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return); + cs46xx_t *chip = pcm->private_data; chip->pcm = NULL; snd_pcm_lib_preallocate_free_for_all(pcm); } @@ -1672,21 +1585,21 @@ static void snd_cs46xx_pcm_free(snd_pcm_t *pcm) #ifdef CONFIG_SND_CS46XX_NEW_DSP static void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return); + cs46xx_t *chip = pcm->private_data; chip->pcm_rear = NULL; snd_pcm_lib_preallocate_free_for_all(pcm); } static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return); + cs46xx_t *chip = pcm->private_data; chip->pcm_center_lfe = NULL; snd_pcm_lib_preallocate_free_for_all(pcm); } static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, pcm->private_data, return); + cs46xx_t *chip = pcm->private_data; chip->pcm_iec958 = NULL; snd_pcm_lib_preallocate_free_for_all(pcm); } @@ -1824,14 +1737,14 @@ int __devinit snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t ** rpc */ static void snd_cs46xx_mixer_free_ac97_bus(ac97_bus_t *bus) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, bus->private_data, return); + cs46xx_t *chip = bus->private_data; chip->ac97_bus = NULL; } static void snd_cs46xx_mixer_free_ac97(ac97_t *ac97) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, ac97->private_data, return); + cs46xx_t *chip = ac97->private_data; snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), @@ -2420,7 +2333,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97) { unsigned long end_time; int err; - cs46xx_t * chip = snd_magic_cast(cs46xx_t,ac97->private_data,return /* -ENXIO */); + cs46xx_t * chip = ac97->private_data; /* reset to defaults */ snd_ac97_write(ac97, AC97_RESET, 0); @@ -2470,39 +2383,38 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97) int __devinit snd_cs46xx_mixer(cs46xx_t *chip) { snd_card_t *card = chip->card; - ac97_bus_t bus; - ac97_t ac97; + ac97_template_t ac97; snd_ctl_elem_id_t id; int err; unsigned int idx; + static ac97_bus_ops_t ops = { +#ifdef CONFIG_SND_CS46XX_NEW_DSP + .reset = snd_cs46xx_codec_reset, +#endif + .write = snd_cs46xx_ac97_write, + .read = snd_cs46xx_ac97_read, + }; /* detect primary codec */ chip->nr_ac97_codecs = 0; snd_printdd("snd_cs46xx: detecting primary codec\n"); - memset(&bus, 0, sizeof(bus)); - bus.write = snd_cs46xx_ac97_write; - bus.read = snd_cs46xx_ac97_read; -#ifdef CONFIG_SND_CS46XX_NEW_DSP - bus.reset = snd_cs46xx_codec_reset; -#endif - bus.private_data = chip; - bus.private_free = snd_cs46xx_mixer_free_ac97_bus; - if ((err = snd_ac97_bus(card, &bus, &chip->ac97_bus)) < 0) + if ((err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus)) < 0) return err; + chip->ac97_bus->private_free = snd_cs46xx_mixer_free_ac97_bus; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = chip; ac97.private_free = snd_cs46xx_mixer_free_ac97; - chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = &ac97; - snd_cs46xx_ac97_write(&ac97, AC97_MASTER, 0x8000); + snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, + CS46XX_PRIMARY_CODEC_INDEX); for (idx = 0; idx < 100; ++idx) { - if (snd_cs46xx_ac97_read(&ac97, AC97_MASTER) == 0x8000) + if (snd_cs46xx_codec_read(chip, AC97_MASTER, + CS46XX_PRIMARY_CODEC_INDEX) == 0x8000) goto _ok; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/100); } - chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; return -ENXIO; _ok: @@ -2519,18 +2431,21 @@ int __devinit snd_cs46xx_mixer(cs46xx_t *chip) ac97.private_free = snd_cs46xx_mixer_free_ac97; ac97.num = CS46XX_SECONDARY_CODEC_INDEX; - snd_cs46xx_ac97_write(&ac97, AC97_RESET, 0); + snd_cs46xx_codec_write(chip, AC97_RESET, 0, + CS46XX_SECONDARY_CODEC_INDEX); udelay(10); - if (snd_cs46xx_ac97_read(&ac97, AC97_RESET) & 0x8000) { + if (snd_cs46xx_codec_read(chip, AC97_RESET, + CS46XX_SECONDARY_CODEC_INDEX) & 0x8000) { snd_printdd("snd_cs46xx: seconadry codec not present\n"); goto _no_sec_codec; } - chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = &ac97; - snd_cs46xx_ac97_write(&ac97, AC97_MASTER, 0x8000); + snd_cs46xx_codec_write(chip, AC97_MASTER, 0x8000, + CS46XX_SECONDARY_CODEC_INDEX); for (idx = 0; idx < 100; ++idx) { - if (snd_cs46xx_ac97_read(&ac97, AC97_MASTER) == 0x8000) { + if (snd_cs46xx_codec_read(chip, AC97_MASTER, + CS46XX_SECONDARY_CODEC_INDEX) == 0x8000) { goto _ok2; } set_current_state(TASK_INTERRUPTIBLE); @@ -2540,7 +2455,6 @@ int __devinit snd_cs46xx_mixer(cs46xx_t *chip) _no_sec_codec: snd_printdd("snd_cs46xx: secondary codec did not respond ...\n"); - chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL; chip->nr_ac97_codecs = 1; /* well, one codec only ... */ @@ -2605,11 +2519,10 @@ static void snd_cs46xx_midi_reset(cs46xx_t *chip) static int snd_cs46xx_midi_input_open(snd_rawmidi_substream_t * substream) { - unsigned long flags; - cs46xx_t *chip = snd_magic_cast(cs46xx_t, substream->rmidi->private_data, return -ENXIO); + cs46xx_t *chip = substream->rmidi->private_data; chip->active_ctrl(chip, 1); - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); chip->uartm |= CS46XX_MODE_INPUT; chip->midcr |= MIDCR_RXE; chip->midi_input = substream; @@ -2618,16 +2531,15 @@ static int snd_cs46xx_midi_input_open(snd_rawmidi_substream_t * substream) } else { snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); } - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); return 0; } static int snd_cs46xx_midi_input_close(snd_rawmidi_substream_t * substream) { - unsigned long flags; - cs46xx_t *chip = snd_magic_cast(cs46xx_t, substream->rmidi->private_data, return -ENXIO); + cs46xx_t *chip = substream->rmidi->private_data; - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE); chip->midi_input = NULL; if (!(chip->uartm & CS46XX_MODE_OUTPUT)) { @@ -2636,19 +2548,18 @@ static int snd_cs46xx_midi_input_close(snd_rawmidi_substream_t * substream) snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); } chip->uartm &= ~CS46XX_MODE_INPUT; - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); chip->active_ctrl(chip, -1); return 0; } static int snd_cs46xx_midi_output_open(snd_rawmidi_substream_t * substream) { - unsigned long flags; - cs46xx_t *chip = snd_magic_cast(cs46xx_t, substream->rmidi->private_data, return -ENXIO); + cs46xx_t *chip = substream->rmidi->private_data; chip->active_ctrl(chip, 1); - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); chip->uartm |= CS46XX_MODE_OUTPUT; chip->midcr |= MIDCR_TXE; chip->midi_output = substream; @@ -2657,16 +2568,15 @@ static int snd_cs46xx_midi_output_open(snd_rawmidi_substream_t * substream) } else { snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); } - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); return 0; } static int snd_cs46xx_midi_output_close(snd_rawmidi_substream_t * substream) { - unsigned long flags; - cs46xx_t *chip = snd_magic_cast(cs46xx_t, substream->rmidi->private_data, return -ENXIO); + cs46xx_t *chip = substream->rmidi->private_data; - spin_lock_irqsave(&chip->reg_lock, flags); + spin_lock_irq(&chip->reg_lock); chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE); chip->midi_output = NULL; if (!(chip->uartm & CS46XX_MODE_INPUT)) { @@ -2675,7 +2585,7 @@ static int snd_cs46xx_midi_output_close(snd_rawmidi_substream_t * substream) snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr); } chip->uartm &= ~CS46XX_MODE_OUTPUT; - spin_unlock_irqrestore(&chip->reg_lock, flags); + spin_unlock_irq(&chip->reg_lock); chip->active_ctrl(chip, -1); return 0; } @@ -2683,7 +2593,7 @@ static int snd_cs46xx_midi_output_close(snd_rawmidi_substream_t * substream) static void snd_cs46xx_midi_input_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; - cs46xx_t *chip = snd_magic_cast(cs46xx_t, substream->rmidi->private_data, return); + cs46xx_t *chip = substream->rmidi->private_data; spin_lock_irqsave(&chip->reg_lock, flags); if (up) { @@ -2703,7 +2613,7 @@ static void snd_cs46xx_midi_input_trigger(snd_rawmidi_substream_t * substream, i static void snd_cs46xx_midi_output_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; - cs46xx_t *chip = snd_magic_cast(cs46xx_t, substream->rmidi->private_data, return); + cs46xx_t *chip = substream->rmidi->private_data; unsigned char byte; spin_lock_irqsave(&chip->reg_lock, flags); @@ -2781,7 +2691,7 @@ static void snd_cs46xx_gameport_trigger(struct gameport *gameport) cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; cs46xx_t *chip; snd_assert(gp, return); - chip = snd_magic_cast(cs46xx_t, gp->chip, return); + chip = gp->chip; snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); } @@ -2790,7 +2700,7 @@ static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; cs46xx_t *chip; snd_assert(gp, return 0); - chip = snd_magic_cast(cs46xx_t, gp->chip, return 0); + chip = gp->chip; return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); } @@ -2801,7 +2711,7 @@ static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, unsigned js1, js2, jst; snd_assert(gp, return 0); - chip = snd_magic_cast(cs46xx_t, gp->chip, return 0); + chip = gp->chip; js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); @@ -2866,18 +2776,18 @@ void __devinit snd_cs46xx_gameport(cs46xx_t *chip) */ static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data, - struct file *file, char __user *buf, long count) + struct file *file, char __user *buf, + unsigned long count, unsigned long pos) { long size; snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data; size = count; - if (file->f_pos + (size_t)size > region->size) - size = region->size - file->f_pos; + if (pos + (size_t)size > region->size) + size = region->size - pos; if (size > 0) { - if (copy_to_user_fromio(buf, region->remap_addr + file->f_pos, size)) + if (copy_to_user_fromio(buf, region->remap_addr + pos, size)) return -EFAULT; - file->f_pos += size; } return size; } @@ -3011,13 +2921,13 @@ static int snd_cs46xx_free(cs46xx_t *chip) } #endif - snd_magic_kfree(chip); + kfree(chip); return 0; } static int snd_cs46xx_dev_free(snd_device_t *device) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, device->device_data, return -ENXIO); + cs46xx_t *chip = device->device_data; return snd_cs46xx_free(chip); } @@ -3786,7 +3696,7 @@ static struct cs_card_type __devinitdata cards[] = { #ifdef CONFIG_PM static int snd_cs46xx_suspend(snd_card_t *card, unsigned int state) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, card->pm_private_data, return -EINVAL); + cs46xx_t *chip = card->pm_private_data; int amp_saved; snd_pcm_suspend_all(chip->pcm); @@ -3810,7 +3720,7 @@ static int snd_cs46xx_suspend(snd_card_t *card, unsigned int state) static int snd_cs46xx_resume(snd_card_t *card, unsigned int state) { - cs46xx_t *chip = snd_magic_cast(cs46xx_t, card->pm_private_data, return -EINVAL); + cs46xx_t *chip = card->pm_private_data; int amp_saved; pci_enable_device(chip->pci); @@ -3869,7 +3779,7 @@ int __devinit snd_cs46xx_create(snd_card_t * card, if ((err = pci_enable_device(pci)) < 0) return err; - chip = snd_magic_kcalloc(cs46xx_t, 0, GFP_KERNEL); + chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->reg_lock); @@ -3913,10 +3823,6 @@ int __devinit snd_cs46xx_create(snd_card_t * card, region->base = chip->ba1_addr + BA1_SP_REG; region->size = CS46XX_BA1_REG_SIZE; - memset(&chip->dma_dev, 0, sizeof(chip->dma_dev)); - chip->dma_dev.type = SNDRV_DMA_TYPE_DEV; - chip->dma_dev.dev = snd_dma_pci_data(pci); - /* set up amp and clkrun hack */ pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor); pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &ss_card);