snd_emu10k1_fx8010_ctl_t *ctl, nctl;
snd_kcontrol_new_t knew;
snd_kcontrol_t *kctl;
- snd_ctl_elem_value_t val;
+ snd_ctl_elem_value_t *val;
+ val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
+ if (!val)
+ return;
for (i = 0, _gctl = icode->gpr_add_controls;
i < icode->gpr_add_control_count; i++, _gctl++) {
if (copy_from_user(&gctl, _gctl, sizeof(gctl)))
- return;
+ break;
snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue);
snd_runtime_check(gctl.id.name[0] != '\0', continue);
for (j = 0; j < 32; j++) {
nctl.gpr[j] = gctl.gpr[j];
nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
- val.value.integer.value[j] = gctl.value[j];
+ val->value.integer.value[j] = gctl.value[j];
}
nctl.min = gctl.min;
nctl.max = gctl.max;
snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
}
- snd_emu10k1_gpr_ctl_put(ctl->kcontrol, &val);
+ snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
}
+ kfree(val);
}
static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
{
- int err, i, z, gpr, tmp, playback, capture, nctl;
+ int err, i, z, gpr, nctl;
+ const int playback = 10;
+ const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
+ const int tmp = 0x88;
u32 ptr;
emu10k1_fx8010_code_t *icode;
emu10k1_fx8010_control_gpr_t *controls, *ctl;
strcpy(icode->name, "Audigy DSP code for ALSA");
ptr = 0;
nctl = 0;
- playback = 10;
- capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
gpr = capture + 10;
- tmp = 0x88;
/* stop FX processor */
snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
- /* Wave Playback */
+ /* Wave Playback Volume */
A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
- snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr,
- emu->revision == 4 ? 50 : 100);
+ snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
gpr += 2;
/* Wave Surround Playback */
snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
gpr += 2;
+ /* Master volume for audigy2 */
+ if (emu->revision == 4) {
+ A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
+ A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr+1), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
+ snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
+ gpr += 2;
+ }
+
/* digital outputs */
A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
/* analog speakers */
- if (emu->audigy && emu->revision == 4) { /* audigy2 */
+ if (emu->revision == 4) { /* audigy2 */
A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
} else {
A_PUT_STEREO_OUTPUT(A_EXTOUT_AC97_L, A_EXTOUT_AC97_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
{
emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO);
- emu10k1_fx8010_info_t info;
+ emu10k1_fx8010_info_t *info;
emu10k1_fx8010_code_t *icode;
emu10k1_fx8010_pcm_t *ipcm;
unsigned int addr;
switch (cmd) {
case SNDRV_EMU10K1_IOCTL_INFO:
- if ((res = snd_emu10k1_fx8010_info(emu, &info)) < 0)
+ info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
+ kfree(info);
return res;
- if (copy_to_user((void *)arg, &info, sizeof(info)))
+ }
+ if (copy_to_user((void *)arg, info, sizeof(*info))) {
+ kfree(info);
return -EFAULT;
+ }
+ kfree(info);
return 0;
case SNDRV_EMU10K1_IOCTL_CODE_POKE:
if (!capable(CAP_SYS_ADMIN))
case SNDRV_EMU10K1_IOCTL_PCM_POKE:
if (emu->audigy)
return -EINVAL;
- ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
+ ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
if (ipcm == NULL)
return -ENOMEM;
+ if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
+ kfree(ipcm);
+ return -EFAULT;
+ }
res = snd_emu10k1_ipcm_poke(emu, ipcm);
kfree(ipcm);
return res;
ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL);
if (ipcm == NULL)
return -ENOMEM;
+ if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) {
+ kfree(ipcm);
+ return -EFAULT;
+ }
res = snd_emu10k1_ipcm_peek(emu, ipcm);
if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) {
kfree(ipcm);