945 |
snd_emu10k1_fx8010_ctl_t *ctl, nctl; |
snd_emu10k1_fx8010_ctl_t *ctl, nctl; |
946 |
snd_kcontrol_new_t knew; |
snd_kcontrol_new_t knew; |
947 |
snd_kcontrol_t *kctl; |
snd_kcontrol_t *kctl; |
948 |
snd_ctl_elem_value_t val; |
snd_ctl_elem_value_t *val; |
949 |
|
|
950 |
|
val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL); |
951 |
|
if (!val) |
952 |
|
return; |
953 |
for (i = 0, _gctl = icode->gpr_add_controls; |
for (i = 0, _gctl = icode->gpr_add_controls; |
954 |
i < icode->gpr_add_control_count; i++, _gctl++) { |
i < icode->gpr_add_control_count; i++, _gctl++) { |
955 |
if (copy_from_user(&gctl, _gctl, sizeof(gctl))) |
if (copy_from_user(&gctl, _gctl, sizeof(gctl))) |
956 |
return; |
break; |
957 |
snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER || |
snd_runtime_check(gctl.id.iface == SNDRV_CTL_ELEM_IFACE_MIXER || |
958 |
gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue); |
gctl.id.iface == SNDRV_CTL_ELEM_IFACE_PCM, continue); |
959 |
snd_runtime_check(gctl.id.name[0] != '\0', continue); |
snd_runtime_check(gctl.id.name[0] != '\0', continue); |
973 |
for (j = 0; j < 32; j++) { |
for (j = 0; j < 32; j++) { |
974 |
nctl.gpr[j] = gctl.gpr[j]; |
nctl.gpr[j] = gctl.gpr[j]; |
975 |
nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */ |
nctl.value[j] = ~gctl.value[j]; /* inverted, we want to write new value in gpr_ctl_put() */ |
976 |
val.value.integer.value[j] = gctl.value[j]; |
val->value.integer.value[j] = gctl.value[j]; |
977 |
} |
} |
978 |
nctl.min = gctl.min; |
nctl.min = gctl.min; |
979 |
nctl.max = gctl.max; |
nctl.max = gctl.max; |
999 |
snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE | |
snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE | |
1000 |
SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id); |
SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id); |
1001 |
} |
} |
1002 |
snd_emu10k1_gpr_ctl_put(ctl->kcontrol, &val); |
snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val); |
1003 |
} |
} |
1004 |
|
kfree(val); |
1005 |
} |
} |
1006 |
|
|
1007 |
static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) |
static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) |
1016 |
ctl = snd_emu10k1_look_for_ctl(emu, &id); |
ctl = snd_emu10k1_look_for_ctl(emu, &id); |
1017 |
snd_runtime_check(ctl == NULL, continue); |
snd_runtime_check(ctl == NULL, continue); |
1018 |
snd_ctl_remove(emu->card, ctl->kcontrol); |
snd_ctl_remove(emu->card, ctl->kcontrol); |
|
list_del(&ctl->list); |
|
1019 |
} |
} |
1020 |
} |
} |
1021 |
|
|
1238 |
|
|
1239 |
static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu) |
static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu) |
1240 |
{ |
{ |
1241 |
int err, i, z, gpr, tmp, playback, capture, nctl; |
int err, i, z, gpr, nctl; |
1242 |
|
const int playback = 10; |
1243 |
|
const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ |
1244 |
|
const int tmp = 0x88; |
1245 |
u32 ptr; |
u32 ptr; |
1246 |
emu10k1_fx8010_code_t *icode; |
emu10k1_fx8010_code_t *icode; |
1247 |
emu10k1_fx8010_control_gpr_t *controls, *ctl; |
emu10k1_fx8010_control_gpr_t *controls, *ctl; |
1264 |
strcpy(icode->name, "Audigy DSP code for ALSA"); |
strcpy(icode->name, "Audigy DSP code for ALSA"); |
1265 |
ptr = 0; |
ptr = 0; |
1266 |
nctl = 0; |
nctl = 0; |
|
playback = 10; |
|
|
capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ |
|
1267 |
gpr = capture + 10; |
gpr = capture + 10; |
|
tmp = 0x88; |
|
1268 |
|
|
1269 |
/* stop FX processor */ |
/* stop FX processor */ |
1270 |
snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); |
snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); |
1271 |
|
|
1272 |
/* Wave Playback */ |
/* Wave Playback Volume */ |
1273 |
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), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT)); |
1274 |
A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT)); |
A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT)); |
1275 |
snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, |
snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100); |
|
emu->revision == 4 ? 50 : 100); |
|
1276 |
gpr += 2; |
gpr += 2; |
1277 |
|
|
1278 |
/* Wave Surround Playback */ |
/* Wave Surround Playback */ |
1496 |
snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0); |
snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0); |
1497 |
gpr += 2; |
gpr += 2; |
1498 |
|
|
1499 |
|
/* Master volume for audigy2 */ |
1500 |
|
if (emu->revision == 4) { |
1501 |
|
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)); |
1502 |
|
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)); |
1503 |
|
snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0); |
1504 |
|
gpr += 2; |
1505 |
|
} |
1506 |
|
|
1507 |
/* digital outputs */ |
/* digital outputs */ |
1508 |
A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); |
A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); |
1509 |
A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); |
A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS); |
1511 |
A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS); |
A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS); |
1512 |
|
|
1513 |
/* analog speakers */ |
/* analog speakers */ |
1514 |
if (emu->audigy && emu->revision == 4) { /* audigy2 */ |
if (emu->revision == 4) { /* audigy2 */ |
1515 |
A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); |
A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); |
1516 |
} else { |
} else { |
1517 |
A_PUT_STEREO_OUTPUT(A_EXTOUT_AC97_L, A_EXTOUT_AC97_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); |
A_PUT_STEREO_OUTPUT(A_EXTOUT_AC97_L, A_EXTOUT_AC97_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); |
2238 |
static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg) |
static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg) |
2239 |
{ |
{ |
2240 |
emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO); |
emu10k1_t *emu = snd_magic_cast(emu10k1_t, hw->private_data, return -ENXIO); |
2241 |
emu10k1_fx8010_info_t info; |
emu10k1_fx8010_info_t *info; |
2242 |
emu10k1_fx8010_code_t *icode; |
emu10k1_fx8010_code_t *icode; |
2243 |
emu10k1_fx8010_pcm_t *ipcm; |
emu10k1_fx8010_pcm_t *ipcm; |
2244 |
unsigned int addr; |
unsigned int addr; |
2246 |
|
|
2247 |
switch (cmd) { |
switch (cmd) { |
2248 |
case SNDRV_EMU10K1_IOCTL_INFO: |
case SNDRV_EMU10K1_IOCTL_INFO: |
2249 |
if ((res = snd_emu10k1_fx8010_info(emu, &info)) < 0) |
info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL); |
2250 |
|
if (!info) |
2251 |
|
return -ENOMEM; |
2252 |
|
if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) { |
2253 |
|
kfree(info); |
2254 |
return res; |
return res; |
2255 |
if (copy_to_user((void *)arg, &info, sizeof(info))) |
} |
2256 |
|
if (copy_to_user((void *)arg, info, sizeof(*info))) { |
2257 |
|
kfree(info); |
2258 |
return -EFAULT; |
return -EFAULT; |
2259 |
|
} |
2260 |
|
kfree(info); |
2261 |
return 0; |
return 0; |
2262 |
case SNDRV_EMU10K1_IOCTL_CODE_POKE: |
case SNDRV_EMU10K1_IOCTL_CODE_POKE: |
2263 |
if (!capable(CAP_SYS_ADMIN)) |
if (!capable(CAP_SYS_ADMIN)) |
2290 |
case SNDRV_EMU10K1_IOCTL_PCM_POKE: |
case SNDRV_EMU10K1_IOCTL_PCM_POKE: |
2291 |
if (emu->audigy) |
if (emu->audigy) |
2292 |
return -EINVAL; |
return -EINVAL; |
2293 |
ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL); |
ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL); |
2294 |
if (ipcm == NULL) |
if (ipcm == NULL) |
2295 |
return -ENOMEM; |
return -ENOMEM; |
2296 |
|
if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) { |
2297 |
|
kfree(ipcm); |
2298 |
|
return -EFAULT; |
2299 |
|
} |
2300 |
res = snd_emu10k1_ipcm_poke(emu, ipcm); |
res = snd_emu10k1_ipcm_poke(emu, ipcm); |
2301 |
kfree(ipcm); |
kfree(ipcm); |
2302 |
return res; |
return res; |
2306 |
ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL); |
ipcm = (emu10k1_fx8010_pcm_t *)snd_kcalloc(sizeof(*ipcm), GFP_KERNEL); |
2307 |
if (ipcm == NULL) |
if (ipcm == NULL) |
2308 |
return -ENOMEM; |
return -ENOMEM; |
2309 |
|
if (copy_from_user(ipcm, (void *)arg, sizeof(*ipcm))) { |
2310 |
|
kfree(ipcm); |
2311 |
|
return -EFAULT; |
2312 |
|
} |
2313 |
res = snd_emu10k1_ipcm_peek(emu, ipcm); |
res = snd_emu10k1_ipcm_peek(emu, ipcm); |
2314 |
if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) { |
if (res == 0 && copy_to_user((void *)arg, ipcm, sizeof(*ipcm))) { |
2315 |
kfree(ipcm); |
kfree(ipcm); |