📄 cs8427.c
字号:
snd_assert(cs8427, return); chip = cs8427->private_data; snd_i2c_lock(cs8427->bus); chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK); snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]); udelay(200); chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK; snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]); udelay(200); snd_i2c_unlock(cs8427->bus); end_time = jiffies + chip->reset_timeout; while (time_after_eq(end_time, jiffies)) { snd_i2c_lock(cs8427->bus); data = snd_cs8427_reg_read(cs8427, CS8427_REG_RECVERRORS); snd_i2c_unlock(cs8427->bus); if (!(data & CS8427_UNLOCK)) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); } snd_i2c_lock(cs8427->bus); chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK; chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT; snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]); snd_i2c_unlock(cs8427->bus);}static int snd_cs8427_in_status_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = 0; uinfo->value.integer.max = 255; return 0;}static int snd_cs8427_in_status_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol); int data; snd_i2c_lock(device->bus); data = snd_cs8427_reg_read(device, kcontrol->private_value); snd_i2c_unlock(device->bus); if (data < 0) return data; ucontrol->value.integer.value[0] = data; return 0;}static int snd_cs8427_qsubcode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = 10; return 0;}static int snd_cs8427_qsubcode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol){ snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol); unsigned char reg = CS8427_REG_QSUBCODE; int err; snd_i2c_lock(device->bus); if ((err = snd_i2c_sendbytes(device, ®, 1)) != 1) { snd_printk("unable to send register 0x%x byte to CS8427\n", reg); snd_i2c_unlock(device->bus); return err < 0 ? err : -EIO; } if ((err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10)) != 10) { snd_printk("unable to read Q-subcode bytes from CS8427\n"); snd_i2c_unlock(device->bus); return err < 0 ? err : -EIO; } snd_i2c_unlock(device->bus); return 0;}static int snd_cs8427_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_cs8427_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol); cs8427_t *chip = device->private_data; snd_i2c_lock(device->bus); memcpy(ucontrol->value.iec958.status, chip->playback.def_status, 24); snd_i2c_unlock(device->bus); return 0;}static int snd_cs8427_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol); cs8427_t *chip = device->private_data; unsigned char *status = kcontrol->private_value ? chip->playback.pcm_status : chip->playback.def_status; snd_pcm_runtime_t *runtime = chip->playback.substream ? chip->playback.substream->runtime : NULL; int err, change; snd_i2c_lock(device->bus); change = memcmp(ucontrol->value.iec958.status, status, 24) != 0; memcpy(status, ucontrol->value.iec958.status, 24); if (change && (kcontrol->private_value ? runtime != NULL : runtime == NULL)) { err = snd_cs8427_send_corudata(device, 0, status, 24); if (err < 0) change = err; } snd_i2c_unlock(device->bus); return change;}static int snd_cs8427_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_cs8427_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ memset(ucontrol->value.iec958.status, 0xff, 24); return 0;}static snd_kcontrol_new_t snd_cs8427_iec958_controls[] = {{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .info = snd_cs8427_in_status_info, .name = "IEC958 CS8427 Input Status", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .get = snd_cs8427_in_status_get, .private_value = 15,},{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .info = snd_cs8427_in_status_info, .name = "IEC958 CS8427 Error Status", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .get = snd_cs8427_in_status_get, .private_value = 16,},{ .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .info = snd_cs8427_spdif_mask_info, .get = snd_cs8427_spdif_mask_get,},{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .info = snd_cs8427_spdif_info, .get = snd_cs8427_spdif_get, .put = snd_cs8427_spdif_put, .private_value = 0},{ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), .info = snd_cs8427_spdif_info, .get = snd_cs8427_spdif_get, .put = snd_cs8427_spdif_put, .private_value = 1},{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .info = snd_cs8427_qsubcode_info, .name = "IEC958 Q-subcode Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .get = snd_cs8427_qsubcode_get}};int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *play_substream, snd_pcm_substream_t *cap_substream){ cs8427_t *chip = cs8427->private_data; snd_kcontrol_t *kctl; unsigned int idx; int err; snd_assert(play_substream && cap_substream, return -EINVAL); for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) { kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427); if (kctl == NULL) return -ENOMEM; kctl->id.device = play_substream->pcm->device; kctl->id.subdevice = play_substream->number; err = snd_ctl_add(cs8427->bus->card, kctl); if (err < 0) return err; if (!strcmp(kctl->id.name, SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM))) chip->playback.pcm_ctl = kctl; } chip->playback.substream = play_substream; chip->capture.substream = cap_substream; snd_assert(chip->playback.pcm_ctl, return -EIO); return 0;}int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active){ cs8427_t *chip; snd_assert(cs8427, return -ENXIO); chip = cs8427->private_data; if (active) memcpy(chip->playback.pcm_status, chip->playback.def_status, 24); chip->playback.pcm_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(cs8427->bus->card, SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, &chip->playback.pcm_ctl->id); return 0;}int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate){ cs8427_t *chip; char *status; int err, reset; snd_assert(cs8427, return -ENXIO); chip = cs8427->private_data; status = chip->playback.pcm_status; snd_i2c_lock(cs8427->bus); if (status[0] & IEC958_AES0_PROFESSIONAL) { status[0] &= ~IEC958_AES0_PRO_FS; switch (rate) { case 32000: status[0] |= IEC958_AES0_PRO_FS_32000; break; case 44100: status[0] |= IEC958_AES0_PRO_FS_44100; break; case 48000: status[0] |= IEC958_AES0_PRO_FS_48000; break; default: status[0] |= IEC958_AES0_PRO_FS_NOTID; break; } } else { status[3] &= ~IEC958_AES3_CON_FS; switch (rate) { case 32000: status[3] |= IEC958_AES3_CON_FS_32000; break; case 44100: status[3] |= IEC958_AES3_CON_FS_44100; break; case 48000: status[3] |= IEC958_AES3_CON_FS_48000; break; } } err = snd_cs8427_send_corudata(cs8427, 0, status, 24); if (err > 0) snd_ctl_notify(cs8427->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->playback.pcm_ctl->id); reset = chip->rate != rate; chip->rate = rate; snd_i2c_unlock(cs8427->bus); if (reset) snd_cs8427_reset(cs8427); return err < 0 ? err : 0;}static int __init alsa_cs8427_module_init(void){ return 0;}static void __exit alsa_cs8427_module_exit(void){}module_init(alsa_cs8427_module_init)module_exit(alsa_cs8427_module_exit)EXPORT_SYMBOL(snd_cs8427_create);EXPORT_SYMBOL(snd_cs8427_reset);EXPORT_SYMBOL(snd_cs8427_reg_write);EXPORT_SYMBOL(snd_cs8427_iec958_build);EXPORT_SYMBOL(snd_cs8427_iec958_active);EXPORT_SYMBOL(snd_cs8427_iec958_pcm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -