?? mixer.c
字號:
case CMD_READPTR: if(ctl.val[1] >= 0x40) return -EINVAL; if((ctl.val[0] & 0x7ff) > 0xff) return -EINVAL; if((ctl.val[0] & 0x7ff) > 0x3f) ctl.val[1] = 0x00; ctl.val[2] = sblive_readptr(card, ctl.val[0], ctl.val[1]); if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl))) return -EFAULT; return 0; break; case CMD_SETRECSRC: switch(ctl.val[0]){ case WAVERECORD_AC97: if(card->isaps) return -EINVAL; card->wavein.recsrc = WAVERECORD_AC97; break; case WAVERECORD_MIC: card->wavein.recsrc = WAVERECORD_MIC; break; case WAVERECORD_FX: card->wavein.recsrc = WAVERECORD_FX; card->wavein.fxwc = ctl.val[1] & 0xffff; if(!card->wavein.fxwc) return -EINVAL; break; default: return -EINVAL; } return 0; break; case CMD_GETRECSRC: ctl.val[0] = card->wavein.recsrc; ctl.val[1] = card->wavein.fxwc; if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl))) return -EFAULT; return 0; break; case CMD_GETVOICEPARAM: ctl.val[0] = card->waveout.send_routing[0]; ctl.val[1] = card->waveout.send_a[0] | card->waveout.send_b[0] << 8 | card->waveout.send_c[0] << 16 | card->waveout.send_d[0] << 24; ctl.val[2] = card->waveout.send_routing[1]; ctl.val[3] = card->waveout.send_a[1] | card->waveout.send_b[1] << 8 | card->waveout.send_c[1] << 16 | card->waveout.send_d[1] << 24; ctl.val[4] = card->waveout.send_routing[2]; ctl.val[5] = card->waveout.send_a[2] | card->waveout.send_b[2] << 8 | card->waveout.send_c[2] << 16 | card->waveout.send_d[2] << 24; if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl))) return -EFAULT; return 0; break; case CMD_SETVOICEPARAM: card->waveout.send_routing[0] = ctl.val[0] & 0xffff; card->waveout.send_a[0] = ctl.val[1] & 0xff; card->waveout.send_b[0] = (ctl.val[1] >> 8) & 0xff; card->waveout.send_c[0] = (ctl.val[1] >> 16) & 0xff; card->waveout.send_d[0] = (ctl.val[1] >> 24) & 0xff; card->waveout.send_routing[1] = ctl.val[2] & 0xffff; card->waveout.send_a[1] = ctl.val[3] & 0xff; card->waveout.send_b[1] = (ctl.val[3] >> 8) & 0xff; card->waveout.send_c[1] = (ctl.val[3] >> 16) & 0xff; card->waveout.send_d[1] = (ctl.val[3] >> 24) & 0xff; card->waveout.send_routing[2] = ctl.val[4] & 0xffff; card->waveout.send_a[2] = ctl.val[5] & 0xff; card->waveout.send_b[2] = (ctl.val[5] >> 8) & 0xff; card->waveout.send_c[2] = (ctl.val[5] >> 16) & 0xff; card->waveout.send_d[2] = (ctl.val[5] >> 24) & 0xff; return 0; break; default: return -EINVAL; break; } } break; case SOUND_MIXER_PRIVATE4:{ u32 size; int size_reg = 0; if (copy_from_user(&size, (void *) arg, sizeof(size))) return -EFAULT; DPD(2,"External tram size 0x%x\n", size); if(size > 0x1fffff) return -EINVAL; if (size != 0) { size = (size - 1) >> 14; while (size) { size >>= 1; size_reg++; } size = 0x4000 << size_reg; } DPD(2,"External tram size 0x%x 0x%x\n", size, size_reg); if (size != card->tankmem.size) { if (card->tankmem.size > 0) { emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 1); sblive_writeptr_tag(card, 0, TCB, 0, TCBS, 0, TAGLIST_END); pci_free_consistent(card->pci_dev, card->tankmem.size, card->tankmem.addr, card->tankmem.dma_handle); card->tankmem.size = 0; } if (size != 0) { if ((card->tankmem.addr = pci_alloc_consistent(card->pci_dev, size, &card->tankmem.dma_handle)) == NULL) return -ENOMEM; card->tankmem.size = size; sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END); emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0); } } return 0; } break; default: break; } if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) return -EINVAL; if (_IOC_DIR(cmd) == _IOC_READ) { switch (_IOC_NR(cmd)) { case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ DPF(4, "SOUND_MIXER_READ_DEVMASK\n"); if (card->isaps)#ifdef TONE_CONTROL return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE, (int *) arg); #else return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME, (int *) arg); #endif #ifdef TONE_CONTROL return put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_OGAIN | SOUND_MASK_LINE1 | SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_PHONEIN | SOUND_MASK_MIC | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV | SOUND_MASK_SPEAKER | SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);#else return put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_OGAIN | SOUND_MASK_LINE1 | SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_PHONEIN | SOUND_MASK_MIC | SOUND_MASK_RECLEV | SOUND_MASK_SPEAKER | SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);#endif case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ DPF(2, "SOUND_MIXER_READ_RECMASK\n"); if (card->isaps) return put_user(0, (int *) arg); return put_user(SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_LINE1 | SOUND_MASK_LINE | SOUND_MASK_VOLUME | SOUND_MASK_OGAIN | SOUND_MASK_PHONEIN, (int *) arg); case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ DPF(2, "SOUND_MIXER_READ_STEREODEVS\n"); if (card->isaps)#ifdef TONE_CONTROL return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE, (int *) arg);#else return put_user(SOUND_MASK_PCM | SOUND_MASK_VOLUME, (int *) arg);#endif#ifdef TONE_CONTROL return put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_OGAIN | SOUND_MASK_LINE1 | SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV | SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);#else return put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_OGAIN | SOUND_MASK_LINE1 | SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_RECLEV | SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);#endif case SOUND_MIXER_CAPS: DPF(2, "SOUND_MIXER_READ_CAPS\n"); return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);#ifdef PRIVATE_PCM_VOLUME case SOUND_MIXER_PCM: /* needs to be before default: !!*/ { int i; for (i = 0; i < MAX_PCM_CHANNELS; i++) { if (sblive_pcm_volume[i].files == current->files) { return put_user((int) sblive_pcm_volume[i].mixer, (int *) arg); } } }#endif default: break; } switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ DPF(2, "SOUND_MIXER_READ_RECSRC\n"); if (card->isaps) return put_user(0, (int *) arg); sblive_readac97(card, AC97_RECORDSELECT, ®); return put_user(recsrc[reg & 7], (int *) arg); default: i = _IOC_NR(cmd); DPD(4, "SOUND_MIXER_READ(%d)\n", i); if (i >= SOUND_MIXER_NRDEVICES) return -EINVAL;#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS return mixer_rdch(card, i, (int *) arg);#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ if (!volidx[i]) return -EINVAL; return put_user(card->arrwVol[volidx[i]], (int *) arg);#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ } } /* End of _IOC_READ */ if (_IOC_DIR(cmd) != (_IOC_READ | _IOC_WRITE)) return -EINVAL; /* _IOC_WRITE */ card->modcnt++; switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ DPF(2, "SOUND_MIXER_WRITE_RECSRC\n"); if (card->isaps) return -EINVAL; if (get_user(val, (int *) arg)) return -EFAULT; i = hweight32(val); if (i == 0) return 0; /* val = mixer_recmask(s); */ else if (i > 1) { sblive_readac97(card, AC97_RECORDSELECT, ®); val &= ~recsrc[reg & 7]; } for (i = 0; i < 8; i++) { if (val & recsrc[i]) { DPD(2, "Selecting record source to be 0x%04x\n", 0x0101 * i); sblive_writeac97(card, AC97_RECORDSELECT, 0x0101 * i); return 0; } } return 0; default: i = _IOC_NR(cmd); DPD(4, "SOUND_MIXER_WRITE(%d)\n", i); if (i >= SOUND_MIXER_NRDEVICES) return -EINVAL; if (get_user(val, (int *) arg)) return -EFAULT; if (emu10k1_mixer_wrch(card, i, val)) return -EINVAL;#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS return mixer_rdch(card, i, (int *) arg);#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ return put_user(card->arrwVol[volidx[i]], (int *) arg);#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ }}static int emu10k1_mixer_open(struct inode *inode, struct file *file){ int minor = MINOR(inode->i_rdev); struct emu10k1_card *card; struct list_head *entry; DPF(4, "emu10k1_mixer_open()\n"); list_for_each(entry, &emu10k1_devs) { card = list_entry(entry, struct emu10k1_card, list); if (card->mixer_num == minor) break; } if (entry == &emu10k1_devs) return -ENODEV; file->private_data = card; return 0;}static int emu10k1_mixer_release(struct inode *inode, struct file *file){ DPF(4, "emu10k1_mixer_release()\n"); return 0;}struct file_operations emu10k1_mixer_fops = { owner: THIS_MODULE, llseek: emu10k1_mixer_llseek, ioctl: emu10k1_mixer_ioctl, open: emu10k1_mixer_open, release: emu10k1_mixer_release,};
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -