Loading include/sound/ymfpci.h +6 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,7 @@ struct _snd_ymfpci_pcm { unsigned int running: 1; unsigned int output_front: 1; unsigned int output_rear: 1; unsigned int update_pcm_vol; u32 period_size; /* cached from runtime->period_size */ u32 buffer_size; /* cached from runtime->buffer_size */ u32 period_pos; Loading Loading @@ -367,6 +368,11 @@ struct _snd_ymfpci { int mode_dup4ch; int rear_opened; int spdif_opened; struct { u16 left; u16 right; snd_kcontrol_t *ctl; } pcm_mixer[32]; spinlock_t reg_lock; spinlock_t voice_lock; Loading sound/pci/ymfpci/ymfpci_main.c +160 −72 Original line number Diff line number Diff line Loading @@ -321,6 +321,26 @@ static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice) snd_pcm_period_elapsed(ypcm->substream); spin_lock(&chip->reg_lock); } if (unlikely(ypcm->update_pcm_vol)) { unsigned int subs = ypcm->substream->number; unsigned int next_bank = 1 - chip->active_bank; snd_ymfpci_playback_bank_t *bank; u32 volume; bank = &voice->bank[next_bank]; volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15); bank->left_gain_end = volume; if (ypcm->output_rear) bank->eff2_gain_end = volume; if (ypcm->voices[1]) bank = &ypcm->voices[1]->bank[next_bank]; volume = cpu_to_le32(chip->pcm_mixer[subs].right << 15); bank->right_gain_end = volume; if (ypcm->output_rear) bank->eff3_gain_end = volume; ypcm->update_pcm_vol--; } } spin_unlock(&chip->reg_lock); } Loading Loading @@ -451,87 +471,74 @@ static int snd_ymfpci_pcm_voice_alloc(ymfpci_pcm_t *ypcm, int voices) return 0; } static void snd_ymfpci_pcm_init_voice(ymfpci_voice_t *voice, int stereo, int rate, int w_16, unsigned long addr, unsigned int end, int output_front, int output_rear) static void snd_ymfpci_pcm_init_voice(ymfpci_pcm_t *ypcm, unsigned int voiceidx, snd_pcm_runtime_t *runtime, int has_pcm_volume) { ymfpci_voice_t *voice = ypcm->voices[voiceidx]; u32 format; u32 delta = snd_ymfpci_calc_delta(rate); u32 lpfQ = snd_ymfpci_calc_lpfQ(rate); u32 lpfK = snd_ymfpci_calc_lpfK(rate); u32 delta = snd_ymfpci_calc_delta(runtime->rate); u32 lpfQ = snd_ymfpci_calc_lpfQ(runtime->rate); u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate); snd_ymfpci_playback_bank_t *bank; unsigned int nbank; u32 vol_left, vol_right; u8 use_left, use_right; snd_assert(voice != NULL, return); format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000); if (runtime->channels == 1) { use_left = 1; use_right = 1; } else { use_left = (voiceidx & 1) == 0; use_right = !use_left; } if (has_pcm_volume) { vol_left = cpu_to_le32(ypcm->chip->pcm_mixer [ypcm->substream->number].left << 15); vol_right = cpu_to_le32(ypcm->chip->pcm_mixer [ypcm->substream->number].right << 15); } else { vol_left = cpu_to_le32(0x40000000); vol_right = cpu_to_le32(0x40000000); } format = runtime->channels == 2 ? 0x00010000 : 0; if (snd_pcm_format_width(runtime->format) == 8) format |= 0x80000000; if (runtime->channels == 2 && (voiceidx & 1) != 0) format |= 1; for (nbank = 0; nbank < 2; nbank++) { bank = &voice->bank[nbank]; memset(bank, 0, sizeof(*bank)); bank->format = cpu_to_le32(format); bank->loop_default = 0; bank->base = cpu_to_le32(addr); bank->loop_start = 0; bank->loop_end = cpu_to_le32(end); bank->loop_frac = 0; bank->eg_gain_end = cpu_to_le32(0x40000000); bank->base = cpu_to_le32(runtime->dma_addr); bank->loop_end = cpu_to_le32(ypcm->buffer_size); bank->lpfQ = cpu_to_le32(lpfQ); bank->status = 0; bank->num_of_frames = 0; bank->loop_count = 0; bank->start = 0; bank->start_frac = 0; bank->delta = bank->delta_end = cpu_to_le32(delta); bank->lpfK = bank->lpfK_end = cpu_to_le32(lpfK); bank->eg_gain = cpu_to_le32(0x40000000); bank->lpfD1 = bank->lpfD2 = 0; bank->left_gain = bank->right_gain = bank->left_gain_end = bank->right_gain_end = bank->eff1_gain = bank->eff2_gain = bank->eff3_gain = bank->eff1_gain_end = bank->eff2_gain_end = bank->eff3_gain_end = 0; bank->eg_gain = bank->eg_gain_end = cpu_to_le32(0x40000000); if (!stereo) { if (output_front) { if (ypcm->output_front) { if (use_left) { bank->left_gain = bank->right_gain = bank->left_gain_end = bank->right_gain_end = cpu_to_le32(0x40000000); bank->left_gain_end = vol_left; } if (output_rear) { bank->eff2_gain = bank->eff2_gain_end = bank->eff3_gain = bank->eff3_gain_end = cpu_to_le32(0x40000000); } } else { if (output_front) { if ((voice->number & 1) == 0) { bank->left_gain = bank->left_gain_end = cpu_to_le32(0x40000000); } else { bank->format |= cpu_to_le32(1); if (use_right) { bank->right_gain = bank->right_gain_end = cpu_to_le32(0x40000000); bank->right_gain_end = vol_right; } } if (output_rear) { if ((voice->number & 1) == 0) { bank->eff3_gain = bank->eff3_gain_end = cpu_to_le32(0x40000000); } else { bank->format |= cpu_to_le32(1); if (ypcm->output_rear) { if (use_left) { bank->eff2_gain = bank->eff2_gain_end = cpu_to_le32(0x40000000); bank->eff2_gain_end = vol_left; } if (use_right) { bank->eff3_gain = bank->eff3_gain_end = vol_right; } } } Loading Loading @@ -613,7 +620,7 @@ static int snd_ymfpci_playback_hw_free(snd_pcm_substream_t * substream) static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) { // ymfpci_t *chip = snd_pcm_substream_chip(substream); ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm = runtime->private_data; unsigned int nvoice; Loading @@ -623,14 +630,8 @@ static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) ypcm->period_pos = 0; ypcm->last_pos = 0; for (nvoice = 0; nvoice < runtime->channels; nvoice++) snd_ymfpci_pcm_init_voice(ypcm->voices[nvoice], runtime->channels == 2, runtime->rate, snd_pcm_format_width(runtime->format) == 16, runtime->dma_addr, ypcm->buffer_size, ypcm->output_front, ypcm->output_rear); snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, substream->pcm == chip->pcm); return 0; } Loading Loading @@ -882,6 +883,7 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; snd_kcontrol_t *kctl; int err; if ((err = snd_ymfpci_playback_open_1(substream)) < 0) Loading @@ -895,6 +897,10 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) chip->rear_opened++; } spin_unlock_irq(&chip->reg_lock); kctl = chip->pcm_mixer[substream->number].ctl; kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return 0; } Loading Loading @@ -987,6 +993,7 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) { ymfpci_t *chip = snd_pcm_substream_chip(substream); ymfpci_pcm_t *ypcm = substream->runtime->private_data; snd_kcontrol_t *kctl; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear && chip->rear_opened > 0) { Loading @@ -994,6 +1001,9 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) ymfpci_close_extension(chip); } spin_unlock_irq(&chip->reg_lock); kctl = chip->pcm_mixer[substream->number].ctl; kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return snd_ymfpci_playback_close_1(substream); } Loading Loading @@ -1665,6 +1675,66 @@ static snd_kcontrol_new_t snd_ymfpci_rear_shared __devinitdata = { .private_value = 2, }; /* * PCM voice volume */ static int snd_ymfpci_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0x8000; return 0; } static int snd_ymfpci_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int subs = kcontrol->id.subdevice; ucontrol->value.integer.value[0] = chip->pcm_mixer[subs].left; ucontrol->value.integer.value[1] = chip->pcm_mixer[subs].right; return 0; } static int snd_ymfpci_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int subs = kcontrol->id.subdevice; snd_pcm_substream_t *substream; unsigned long flags; if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left || ucontrol->value.integer.value[1] != chip->pcm_mixer[subs].right) { chip->pcm_mixer[subs].left = ucontrol->value.integer.value[0]; chip->pcm_mixer[subs].right = ucontrol->value.integer.value[1]; substream = (snd_pcm_substream_t *)kcontrol->private_value; spin_lock_irqsave(&chip->voice_lock, flags); if (substream->runtime && substream->runtime->private_data) { ymfpci_pcm_t *ypcm = substream->runtime->private_data; ypcm->update_pcm_vol = 2; } spin_unlock_irqrestore(&chip->voice_lock, flags); return 1; } return 0; } static snd_kcontrol_new_t snd_ymfpci_pcm_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "PCM Playback Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .info = snd_ymfpci_pcm_vol_info, .get = snd_ymfpci_pcm_vol_get, .put = snd_ymfpci_pcm_vol_put, }; /* * Mixer routines Loading @@ -1686,6 +1756,7 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) { ac97_template_t ac97; snd_kcontrol_t *kctl; snd_pcm_substream_t *substream; unsigned int idx; int err; static ac97_bus_ops_t ops = { Loading Loading @@ -1739,6 +1810,23 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) return err; } /* per-voice volume */ substream = chip->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; for (idx = 0; idx < 32; ++idx) { kctl = snd_ctl_new1(&snd_ymfpci_pcm_volume, chip); if (!kctl) return -ENOMEM; kctl->id.device = chip->pcm->device; kctl->id.subdevice = idx; kctl->private_value = (unsigned long)substream; if ((err = snd_ctl_add(chip->card, kctl)) < 0) return err; chip->pcm_mixer[idx].left = 0x8000; chip->pcm_mixer[idx].right = 0x8000; chip->pcm_mixer[idx].ctl = kctl; substream = substream->next; } return 0; } Loading Loading
include/sound/ymfpci.h +6 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,7 @@ struct _snd_ymfpci_pcm { unsigned int running: 1; unsigned int output_front: 1; unsigned int output_rear: 1; unsigned int update_pcm_vol; u32 period_size; /* cached from runtime->period_size */ u32 buffer_size; /* cached from runtime->buffer_size */ u32 period_pos; Loading Loading @@ -367,6 +368,11 @@ struct _snd_ymfpci { int mode_dup4ch; int rear_opened; int spdif_opened; struct { u16 left; u16 right; snd_kcontrol_t *ctl; } pcm_mixer[32]; spinlock_t reg_lock; spinlock_t voice_lock; Loading
sound/pci/ymfpci/ymfpci_main.c +160 −72 Original line number Diff line number Diff line Loading @@ -321,6 +321,26 @@ static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice) snd_pcm_period_elapsed(ypcm->substream); spin_lock(&chip->reg_lock); } if (unlikely(ypcm->update_pcm_vol)) { unsigned int subs = ypcm->substream->number; unsigned int next_bank = 1 - chip->active_bank; snd_ymfpci_playback_bank_t *bank; u32 volume; bank = &voice->bank[next_bank]; volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15); bank->left_gain_end = volume; if (ypcm->output_rear) bank->eff2_gain_end = volume; if (ypcm->voices[1]) bank = &ypcm->voices[1]->bank[next_bank]; volume = cpu_to_le32(chip->pcm_mixer[subs].right << 15); bank->right_gain_end = volume; if (ypcm->output_rear) bank->eff3_gain_end = volume; ypcm->update_pcm_vol--; } } spin_unlock(&chip->reg_lock); } Loading Loading @@ -451,87 +471,74 @@ static int snd_ymfpci_pcm_voice_alloc(ymfpci_pcm_t *ypcm, int voices) return 0; } static void snd_ymfpci_pcm_init_voice(ymfpci_voice_t *voice, int stereo, int rate, int w_16, unsigned long addr, unsigned int end, int output_front, int output_rear) static void snd_ymfpci_pcm_init_voice(ymfpci_pcm_t *ypcm, unsigned int voiceidx, snd_pcm_runtime_t *runtime, int has_pcm_volume) { ymfpci_voice_t *voice = ypcm->voices[voiceidx]; u32 format; u32 delta = snd_ymfpci_calc_delta(rate); u32 lpfQ = snd_ymfpci_calc_lpfQ(rate); u32 lpfK = snd_ymfpci_calc_lpfK(rate); u32 delta = snd_ymfpci_calc_delta(runtime->rate); u32 lpfQ = snd_ymfpci_calc_lpfQ(runtime->rate); u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate); snd_ymfpci_playback_bank_t *bank; unsigned int nbank; u32 vol_left, vol_right; u8 use_left, use_right; snd_assert(voice != NULL, return); format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000); if (runtime->channels == 1) { use_left = 1; use_right = 1; } else { use_left = (voiceidx & 1) == 0; use_right = !use_left; } if (has_pcm_volume) { vol_left = cpu_to_le32(ypcm->chip->pcm_mixer [ypcm->substream->number].left << 15); vol_right = cpu_to_le32(ypcm->chip->pcm_mixer [ypcm->substream->number].right << 15); } else { vol_left = cpu_to_le32(0x40000000); vol_right = cpu_to_le32(0x40000000); } format = runtime->channels == 2 ? 0x00010000 : 0; if (snd_pcm_format_width(runtime->format) == 8) format |= 0x80000000; if (runtime->channels == 2 && (voiceidx & 1) != 0) format |= 1; for (nbank = 0; nbank < 2; nbank++) { bank = &voice->bank[nbank]; memset(bank, 0, sizeof(*bank)); bank->format = cpu_to_le32(format); bank->loop_default = 0; bank->base = cpu_to_le32(addr); bank->loop_start = 0; bank->loop_end = cpu_to_le32(end); bank->loop_frac = 0; bank->eg_gain_end = cpu_to_le32(0x40000000); bank->base = cpu_to_le32(runtime->dma_addr); bank->loop_end = cpu_to_le32(ypcm->buffer_size); bank->lpfQ = cpu_to_le32(lpfQ); bank->status = 0; bank->num_of_frames = 0; bank->loop_count = 0; bank->start = 0; bank->start_frac = 0; bank->delta = bank->delta_end = cpu_to_le32(delta); bank->lpfK = bank->lpfK_end = cpu_to_le32(lpfK); bank->eg_gain = cpu_to_le32(0x40000000); bank->lpfD1 = bank->lpfD2 = 0; bank->left_gain = bank->right_gain = bank->left_gain_end = bank->right_gain_end = bank->eff1_gain = bank->eff2_gain = bank->eff3_gain = bank->eff1_gain_end = bank->eff2_gain_end = bank->eff3_gain_end = 0; bank->eg_gain = bank->eg_gain_end = cpu_to_le32(0x40000000); if (!stereo) { if (output_front) { if (ypcm->output_front) { if (use_left) { bank->left_gain = bank->right_gain = bank->left_gain_end = bank->right_gain_end = cpu_to_le32(0x40000000); bank->left_gain_end = vol_left; } if (output_rear) { bank->eff2_gain = bank->eff2_gain_end = bank->eff3_gain = bank->eff3_gain_end = cpu_to_le32(0x40000000); } } else { if (output_front) { if ((voice->number & 1) == 0) { bank->left_gain = bank->left_gain_end = cpu_to_le32(0x40000000); } else { bank->format |= cpu_to_le32(1); if (use_right) { bank->right_gain = bank->right_gain_end = cpu_to_le32(0x40000000); bank->right_gain_end = vol_right; } } if (output_rear) { if ((voice->number & 1) == 0) { bank->eff3_gain = bank->eff3_gain_end = cpu_to_le32(0x40000000); } else { bank->format |= cpu_to_le32(1); if (ypcm->output_rear) { if (use_left) { bank->eff2_gain = bank->eff2_gain_end = cpu_to_le32(0x40000000); bank->eff2_gain_end = vol_left; } if (use_right) { bank->eff3_gain = bank->eff3_gain_end = vol_right; } } } Loading Loading @@ -613,7 +620,7 @@ static int snd_ymfpci_playback_hw_free(snd_pcm_substream_t * substream) static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) { // ymfpci_t *chip = snd_pcm_substream_chip(substream); ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm = runtime->private_data; unsigned int nvoice; Loading @@ -623,14 +630,8 @@ static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream) ypcm->period_pos = 0; ypcm->last_pos = 0; for (nvoice = 0; nvoice < runtime->channels; nvoice++) snd_ymfpci_pcm_init_voice(ypcm->voices[nvoice], runtime->channels == 2, runtime->rate, snd_pcm_format_width(runtime->format) == 16, runtime->dma_addr, ypcm->buffer_size, ypcm->output_front, ypcm->output_rear); snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, substream->pcm == chip->pcm); return 0; } Loading Loading @@ -882,6 +883,7 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm; snd_kcontrol_t *kctl; int err; if ((err = snd_ymfpci_playback_open_1(substream)) < 0) Loading @@ -895,6 +897,10 @@ static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream) chip->rear_opened++; } spin_unlock_irq(&chip->reg_lock); kctl = chip->pcm_mixer[substream->number].ctl; kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return 0; } Loading Loading @@ -987,6 +993,7 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) { ymfpci_t *chip = snd_pcm_substream_chip(substream); ymfpci_pcm_t *ypcm = substream->runtime->private_data; snd_kcontrol_t *kctl; spin_lock_irq(&chip->reg_lock); if (ypcm->output_rear && chip->rear_opened > 0) { Loading @@ -994,6 +1001,9 @@ static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream) ymfpci_close_extension(chip); } spin_unlock_irq(&chip->reg_lock); kctl = chip->pcm_mixer[substream->number].ctl; kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); return snd_ymfpci_playback_close_1(substream); } Loading Loading @@ -1665,6 +1675,66 @@ static snd_kcontrol_new_t snd_ymfpci_rear_shared __devinitdata = { .private_value = 2, }; /* * PCM voice volume */ static int snd_ymfpci_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0x8000; return 0; } static int snd_ymfpci_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int subs = kcontrol->id.subdevice; ucontrol->value.integer.value[0] = chip->pcm_mixer[subs].left; ucontrol->value.integer.value[1] = chip->pcm_mixer[subs].right; return 0; } static int snd_ymfpci_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); unsigned int subs = kcontrol->id.subdevice; snd_pcm_substream_t *substream; unsigned long flags; if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left || ucontrol->value.integer.value[1] != chip->pcm_mixer[subs].right) { chip->pcm_mixer[subs].left = ucontrol->value.integer.value[0]; chip->pcm_mixer[subs].right = ucontrol->value.integer.value[1]; substream = (snd_pcm_substream_t *)kcontrol->private_value; spin_lock_irqsave(&chip->voice_lock, flags); if (substream->runtime && substream->runtime->private_data) { ymfpci_pcm_t *ypcm = substream->runtime->private_data; ypcm->update_pcm_vol = 2; } spin_unlock_irqrestore(&chip->voice_lock, flags); return 1; } return 0; } static snd_kcontrol_new_t snd_ymfpci_pcm_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "PCM Playback Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .info = snd_ymfpci_pcm_vol_info, .get = snd_ymfpci_pcm_vol_get, .put = snd_ymfpci_pcm_vol_put, }; /* * Mixer routines Loading @@ -1686,6 +1756,7 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) { ac97_template_t ac97; snd_kcontrol_t *kctl; snd_pcm_substream_t *substream; unsigned int idx; int err; static ac97_bus_ops_t ops = { Loading Loading @@ -1739,6 +1810,23 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch) return err; } /* per-voice volume */ substream = chip->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; for (idx = 0; idx < 32; ++idx) { kctl = snd_ctl_new1(&snd_ymfpci_pcm_volume, chip); if (!kctl) return -ENOMEM; kctl->id.device = chip->pcm->device; kctl->id.subdevice = idx; kctl->private_value = (unsigned long)substream; if ((err = snd_ctl_add(chip->card, kctl)) < 0) return err; chip->pcm_mixer[idx].left = 0x8000; chip->pcm_mixer[idx].right = 0x8000; chip->pcm_mixer[idx].ctl = kctl; substream = substream->next; } return 0; } Loading