📄 rme9652.c
字号:
rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); if (restart) { rme9652_start(rme9652); } return 0;}static int snd_rme9652_info_adat1_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ static char *texts[2] = {"ADAT1", "Internal"}; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 2; if (uinfo->value.enumerated.item > 1) uinfo->value.enumerated.item = 1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;}static int snd_rme9652_get_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); spin_lock_irq(&rme9652->lock); ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652); spin_unlock_irq(&rme9652->lock); return 0;}static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; unsigned int val; if (!snd_rme9652_use_is_exclusive(rme9652)) return -EBUSY; val = ucontrol->value.enumerated.item[0] % 2; spin_lock_irq(&rme9652->lock); change = val != rme9652_adat1_in(rme9652); if (change) rme9652_set_adat1_input(rme9652, val); spin_unlock_irq(&rme9652->lock); return change;}#define RME9652_SPDIF_IN(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_spdif_in, \ .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in }static unsigned int rme9652_spdif_in(rme9652_t *rme9652){ return rme9652_decode_spdif_in(rme9652->control_register & RME9652_inp);}static int rme9652_set_spdif_input(rme9652_t *rme9652, int in){ int restart = 0; rme9652->control_register &= ~RME9652_inp; rme9652->control_register |= rme9652_encode_spdif_in(in); if ((restart = rme9652->running)) { rme9652_stop(rme9652); } rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); if (restart) { rme9652_start(rme9652); } return 0;}static int snd_rme9652_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ static char *texts[3] = {"ADAT1", "Coaxial", "Internal"}; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 3; if (uinfo->value.enumerated.item > 2) uinfo->value.enumerated.item = 2; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;}static int snd_rme9652_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); spin_lock_irq(&rme9652->lock); ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652); spin_unlock_irq(&rme9652->lock); return 0;}static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; unsigned int val; if (!snd_rme9652_use_is_exclusive(rme9652)) return -EBUSY; val = ucontrol->value.enumerated.item[0] % 3; spin_lock_irq(&rme9652->lock); change = val != rme9652_spdif_in(rme9652); if (change) rme9652_set_spdif_input(rme9652, val); spin_unlock_irq(&rme9652->lock); return change;}#define RME9652_SPDIF_OUT(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_spdif_out, \ .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out }static int rme9652_spdif_out(rme9652_t *rme9652){ return (rme9652->control_register & RME9652_opt_out) ? 1 : 0;}static int rme9652_set_spdif_output(rme9652_t *rme9652, int out){ int restart = 0; if (out) { rme9652->control_register |= RME9652_opt_out; } else { rme9652->control_register &= ~RME9652_opt_out; } if ((restart = rme9652->running)) { rme9652_stop(rme9652); } rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); if (restart) { rme9652_start(rme9652); } return 0;}static int snd_rme9652_info_spdif_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_rme9652_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); spin_lock_irq(&rme9652->lock); ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652); spin_unlock_irq(&rme9652->lock); return 0;}static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; unsigned int val; if (!snd_rme9652_use_is_exclusive(rme9652)) return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&rme9652->lock); change = (int)val != rme9652_spdif_out(rme9652); rme9652_set_spdif_output(rme9652, val); spin_unlock_irq(&rme9652->lock); return change;}#define RME9652_SYNC_MODE(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_sync_mode, \ .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode }static int rme9652_sync_mode(rme9652_t *rme9652){ if (rme9652->control_register & RME9652_wsel) { return 2; } else if (rme9652->control_register & RME9652_Master) { return 1; } else { return 0; }}static int rme9652_set_sync_mode(rme9652_t *rme9652, int mode){ int restart = 0; switch (mode) { case 0: rme9652->control_register &= ~(RME9652_Master | RME9652_wsel); break; case 1: rme9652->control_register = (rme9652->control_register & ~RME9652_wsel) | RME9652_Master; break; case 2: rme9652->control_register |= (RME9652_Master | RME9652_wsel); break; } if ((restart = rme9652->running)) { rme9652_stop(rme9652); } rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); if (restart) { rme9652_start(rme9652); } return 0;}static int snd_rme9652_info_sync_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ static char *texts[3] = {"AutoSync", "Master", "Word Clock"}; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 3; if (uinfo->value.enumerated.item > 2) uinfo->value.enumerated.item = 2; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;}static int snd_rme9652_get_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); spin_lock_irq(&rme9652->lock); ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652); spin_unlock_irq(&rme9652->lock); return 0;}static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; unsigned int val; val = ucontrol->value.enumerated.item[0] % 3; spin_lock_irq(&rme9652->lock); change = (int)val != rme9652_sync_mode(rme9652); rme9652_set_sync_mode(rme9652, val); spin_unlock_irq(&rme9652->lock); return change;}#define RME9652_SYNC_PREF(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_sync_pref, \ .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref }static int rme9652_sync_pref(rme9652_t *rme9652){ switch (rme9652->control_register & RME9652_SyncPref_Mask) { case RME9652_SyncPref_ADAT1: return RME9652_SYNC_FROM_ADAT1; case RME9652_SyncPref_ADAT2: return RME9652_SYNC_FROM_ADAT2; case RME9652_SyncPref_ADAT3: return RME9652_SYNC_FROM_ADAT3; case RME9652_SyncPref_SPDIF: return RME9652_SYNC_FROM_SPDIF; } /* Not reachable */ return 0;}static int rme9652_set_sync_pref(rme9652_t *rme9652, int pref){ int restart; rme9652->control_register &= ~RME9652_SyncPref_Mask; switch (pref) { case RME9652_SYNC_FROM_ADAT1: rme9652->control_register |= RME9652_SyncPref_ADAT1; break; case RME9652_SYNC_FROM_ADAT2: rme9652->control_register |= RME9652_SyncPref_ADAT2; break; case RME9652_SYNC_FROM_ADAT3: rme9652->control_register |= RME9652_SyncPref_ADAT3; break; case RME9652_SYNC_FROM_SPDIF: rme9652->control_register |= RME9652_SyncPref_SPDIF; break; } if ((restart = rme9652->running)) { rme9652_stop(rme9652); } rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); if (restart) { rme9652_start(rme9652); } return 0;}static int snd_rme9652_info_sync_pref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"}; rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3; if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;}static int snd_rme9652_get_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); spin_lock_irq(&rme9652->lock); ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652); spin_unlock_irq(&rme9652->lock); return 0;}static int snd_rme9652_put_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change, max; unsigned int val; if (!snd_rme9652_use_is_exclusive(rme9652)) return -EBUSY; max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3; val = ucontrol->value.enumerated.item[0] % max; spin_lock_irq(&rme9652->lock); change = (int)val != rme9652_sync_pref(rme9652); rme9652_set_sync_pref(rme9652, val); spin_unlock_irq(&rme9652->lock); return change;}static int snd_rme9652_info_thru(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = rme9652->ss_channels; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_rme9652_get_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); unsigned int k; u32 thru_bits = rme9652->thru_bits; for (k = 0; k < rme9652->ss_channels; ++k) { ucontrol->value.integer.value[k] = !!(thru_bits & (1 << k)); } return 0;}static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; unsigned int chn; u32 thru_bits = 0; if (!snd_rme9652_use_is_exclusive(rme9652)) return -EBUSY; for (chn = 0; chn < rme9652->ss_channels; ++chn) { if (ucontrol->value.integer.value[chn]) thru_bits |= 1 << chn; } spin_lock_irq(&rme9652->lock); change = thru_bits ^ rme9652->thru_bits; if (change) { for (chn = 0; chn < rme9652->ss_channels; ++chn) { if (!(change & (1 << chn))) continue; rme9652_set_thru(rme9652,chn,thru_bits&(1<<chn)); } } spin_unlock_irq(&rme9652->lock); return !!change;}#define RME9652_PASSTHRU(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_passthru, \ .put = snd_rme9652_put_passthru, \ .get = snd_rme9652_get_passthru }static int snd_rme9652_info_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0;}static int snd_rme9652_get_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); spin_lock_irq(&rme9652->lock); ucontrol->value.integer.value[0] = rme9652->passthru; spin_unlock_irq(&rme9652->lock); return 0;}static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; unsigned int val; int err = 0; if (!snd_rme9652_use_is_exclusive(rme9652)) return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irq(&rme9652->lock); change = (ucontrol->value.integer.value[0] != rme9652->passthru); if (change) err = rme9652_set_passthru(rme9652, val);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -