📄 ews.c
字号:
break; case ICE1712_SUBDEVICE_EWX2496: err = snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, &akm_ewx2496_priv, ice); break; case ICE1712_SUBDEVICE_DMX6FIRE: err = snd_ice1712_akm4xxx_init(ak, &akm_6fire, &akm_6fire_priv, ice); break; default: err = 0; } return err;}/* * EWX 24/96 specific controls *//* i/o sensitivity - this callback is shared among other devices, too */static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ static char *texts[2] = { "+4dBu", "-10dBV", }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 2; if (uinfo->value.enumerated.item >= 2) uinfo->value.enumerated.item = 1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;}static int snd_ice1712_ewx_io_sense_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); unsigned char mask = kcontrol->private_value & 0xff; snd_ice1712_save_gpio_status(ice); ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0; snd_ice1712_restore_gpio_status(ice); return 0;}static int snd_ice1712_ewx_io_sense_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); unsigned char mask = kcontrol->private_value & 0xff; int val, nval; if (kcontrol->private_value & (1 << 31)) return -EPERM; nval = ucontrol->value.enumerated.item[0] ? mask : 0; snd_ice1712_save_gpio_status(ice); val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); nval |= val & ~mask; snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval); snd_ice1712_restore_gpio_status(ice); return val != nval;}static snd_kcontrol_new_t snd_ice1712_ewx2496_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, .get = snd_ice1712_ewx_io_sense_get, .put = snd_ice1712_ewx_io_sense_put, .private_value = ICE1712_EWX2496_AIN_SEL, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Output Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, .get = snd_ice1712_ewx_io_sense_get, .put = snd_ice1712_ewx_io_sense_put, .private_value = ICE1712_EWX2496_AOUT_SEL, },};/* * EWS88MT specific controls *//* analog output sensitivity;; address 0x48 bit 6 */static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); unsigned char data; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */ return 0;}/* analog output sensitivity;; address 0x48 bit 6 */static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); unsigned char data, ndata; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) { snd_i2c_unlock(ice->i2c); return -EIO; } ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0); if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); return ndata != data;}/* analog input sensitivity; address 0x46 */static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned char data; snd_assert(channel >= 0 && channel <= 7, return 0); snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { snd_i2c_unlock(ice->i2c); return -EIO; } /* reversed; high = +4dBu, low = -10dBV */ ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1; snd_i2c_unlock(ice->i2c); return 0;}/* analog output sensitivity; address 0x46 */static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned char data, ndata; snd_assert(channel >= 0 && channel <= 7, return 0); snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { snd_i2c_unlock(ice->i2c); return -EIO; } ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel)); if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); return ndata != data;}static snd_kcontrol_new_t snd_ice1712_ews88mt_input_sense __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, .get = snd_ice1712_ews88mt_input_sense_get, .put = snd_ice1712_ews88mt_input_sense_put, .count = 8,};static snd_kcontrol_new_t snd_ice1712_ews88mt_output_sense __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Output Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, .get = snd_ice1712_ews88mt_output_sense_get, .put = snd_ice1712_ews88mt_output_sense_put,};/* * EWS88D specific controls */static int snd_ice1712_ews88d_control_info(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_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value >> 8) & 1; unsigned char data[2]; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01; if (invert) data[0] ^= 0x01; ucontrol->value.integer.value[0] = data[0]; return 0;}static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value >> 8) & 1; unsigned char data[2], ndata[2]; int change; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) { snd_i2c_unlock(ice->i2c); return -EIO; } ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7)); if (invert) { if (! ucontrol->value.integer.value[0]) ndata[shift >> 3] |= (1 << (shift & 7)); } else { if (ucontrol->value.integer.value[0]) ndata[shift >> 3] |= (1 << (shift & 7)); } change = (data[shift >> 3] != ndata[shift >> 3]); if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); return change;}#define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \{ .iface = xiface,\ .name = xname,\ .access = xaccess,\ .info = snd_ice1712_ews88d_control_info,\ .get = snd_ice1712_ews88d_control_get,\ .put = snd_ice1712_ews88d_control_put,\ .private_value = xshift | (xinvert << 8),\}static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = { EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0),};/* * DMX 6Fire specific controls */static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg){ unsigned char byte; snd_i2c_lock(ice->i2c); byte = reg; snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1); byte = 0; if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) { snd_i2c_unlock(ice->i2c); printk(KERN_ERR "cannot read pca\n"); return -EIO; } snd_i2c_unlock(ice->i2c); return byte;}static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data){ unsigned char bytes[2]; snd_i2c_lock(ice->i2c); bytes[0] = reg; bytes[1] = data; if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) { snd_i2c_unlock(ice->i2c); return -EIO; } snd_i2c_unlock(ice->i2c); return 0;}static int snd_ice1712_6fire_control_info(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_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value >> 8) & 1; int data; if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) return data; data = (data >> shift) & 1; if (invert) data ^= 1; ucontrol->value.integer.value[0] = data; return 0;}static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value >> 8) & 1; int data, ndata; if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) return data; ndata = data & ~(1 << shift); if (ucontrol->value.integer.value[0]) ndata |= (1 << shift); if (invert) ndata ^= (1 << shift); if (data != ndata) { snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata); return 1; } return 0;}static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ static char *texts[4] = { "Internal", "Front Input", "Rear Input", "Wave Table" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 4; if (uinfo->value.enumerated.item >= 4) uinfo->value.enumerated.item = 1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0;} static int snd_ice1712_6fire_select_input_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int data; if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) return data; ucontrol->value.integer.value[0] = data & 3; return 0;}static int snd_ice1712_6fire_select_input_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ ice1712_t *ice = snd_kcontrol_chip(kcontrol); int data, ndata; if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0) return data; ndata = data & ~3; ndata |= (ucontrol->value.integer.value[0] & 3); if (data != ndata) { snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata); return 1; } return 0;}#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\ .name = xname,\ .info = snd_ice1712_6fire_control_info,\ .get = snd_ice1712_6fire_control_get,\ .put = snd_ice1712_6fire_control_put,\ .private_value = xshift | (xinvert << 8),\}static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Analog Input Select", .info = snd_ice1712_6fire_select_input_info, .get = snd_ice1712_6fire_select_input_get, .put = snd_ice1712_6fire_select_input_put, }, DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 0), // DMX6FIRE_CONTROL("Master Clock Select", 3, 0), DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0), DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0), DMX6FIRE_CONTROL("Breakbox LED", 6, 0),};static int __devinit snd_ice1712_ews_add_controls(ice1712_t *ice){ unsigned int idx; int err; /* all terratec cards have spdif, but cs8427 module builds it's own controls */ if (ice->cs8427 == NULL) { err = snd_ice1712_spdif_build_controls(ice); if (err < 0) return err; } /* ak4524 controls */ switch (ice->eeprom.subvendor) { case ICE1712_SUBDEVICE_EWX2496: case ICE1712_SUBDEVICE_EWS88MT: case ICE1712_SUBDEVICE_EWS88MT_NEW: case ICE1712_SUBDEVICE_PHASE88: case ICE1712_SUBDEVICE_DMX6FIRE: err = snd_ice1712_akm4xxx_build_controls(ice); if (err < 0) return err; break; } /* card specific controls */ switch (ice->eeprom.subvendor) { case ICE1712_SUBDEVICE_EWX2496: for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice)); if (err < 0) return err; } break; case ICE1712_SUBDEVICE_EWS88MT: case ICE1712_SUBDEVICE_EWS88MT_NEW: case ICE1712_SUBDEVICE_PHASE88: err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice)); if (err < 0) return err; err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice)); if (err < 0) return err; break; case ICE1712_SUBDEVICE_EWS88D: for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice)); if (err < 0) return err; } break; case ICE1712_SUBDEVICE_DMX6FIRE: for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice)); if (err < 0) return err; } break; } return 0;}/* entry point */struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_EWX2496, .name = "TerraTec EWX24/96", .model = "ewx2496", .chip_init = snd_ice1712_ews_init, .build_controls = snd_ice1712_ews_add_controls, }, { .subvendor = ICE1712_SUBDEVICE_EWS88MT, .name = "TerraTec EWS88MT", .model = "ews88mt", .chip_init = snd_ice1712_ews_init, .build_controls = snd_ice1712_ews_add_controls, }, { .subvendor = ICE1712_SUBDEVICE_EWS88MT_NEW, .name = "TerraTec EWS88MT", .model = "ews88mt_new", .chip_init = snd_ice1712_ews_init, .build_controls = snd_ice1712_ews_add_controls, }, { .subvendor = ICE1712_SUBDEVICE_PHASE88, .name = "TerraTec Phase88", .model = "phase88", .chip_init = snd_ice1712_ews_init, .build_controls = snd_ice1712_ews_add_controls, }, { .subvendor = ICE1712_SUBDEVICE_EWS88D, .name = "TerraTec EWS88D", .model = "ews88d", .chip_init = snd_ice1712_ews_init, .build_controls = snd_ice1712_ews_add_controls, }, { .subvendor = ICE1712_SUBDEVICE_DMX6FIRE, .name = "TerraTec DMX6Fire", .model = "dmx6fire", .chip_init = snd_ice1712_ews_init, .build_controls = snd_ice1712_ews_add_controls, }, { } /* terminator */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -