int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427, struct snd_pcm_substream *play_substream, struct snd_pcm_substream *cap_substream) { struct cs8427 *chip = cs8427->private_data; struct snd_kcontrol *kctl; unsigned int idx; int err; if (snd_BUG_ON(!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; if (snd_BUG_ON(!chip->playback.pcm_ctl)) return -EIO; return 0; }
.name = "IEC958 Q-CRC Errors", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_in_error_info, .get = snd_ak4114_in_error_get, .private_value = offsetof(struct ak4114, qcrc_errors), }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "IEC958 External Rate", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_rate_info, .get = snd_ak4114_rate_get, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), .access = SNDRV_CTL_ELEM_ACCESS_READ, .info = snd_ak4114_spdif_mask_info, .get = snd_ak4114_spdif_mask_get, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_spdif_info, .get = snd_ak4114_spdif_playback_get, .put = snd_ak4114_spdif_playback_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
.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),
static int ad198x_build_controls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; struct snd_kcontrol *kctl; unsigned int i; int err; for (i = 0; i < spec->num_mixers; i++) { err = snd_hda_add_new_ctls(codec, spec->mixers[i]); if (err < 0) return err; } if (spec->multiout.dig_out_nid) { err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); if (err < 0) return err; err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); if (err < 0) return err; spec->multiout.share_spdif = 1; } if (spec->dig_in_nid) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; } /* create beep controls if needed */ #ifdef CONFIG_SND_HDA_INPUT_BEEP if (spec->beep_amp) { struct snd_kcontrol_new *knew; knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; for ( ; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; kctl->private_value = spec->beep_amp; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; } } #endif /* if we have no master control, let's create it */ if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { unsigned int vmaster_tlv[4]; snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, HDA_OUTPUT, vmaster_tlv); err = snd_hda_add_vmaster(codec, "Master Playback Volume", vmaster_tlv, (spec->slave_vols ? spec->slave_vols : ad_slave_vols)); if (err < 0) return err; } if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { err = snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, (spec->slave_sws ? spec->slave_sws : ad_slave_sws)); if (err < 0) return err; } ad198x_free_kctls(codec); /* no longer needed */ /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); if (err < 0) return err; } /* assign IEC958 enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source"); if (kctl) { err = snd_hda_add_nid(codec, kctl, 0, spec->multiout.dig_out_nid); if (err < 0) return err; } return 0; }
case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break; case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break; case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break; } if (spdif_sr == vortex->spdif_sr) return 0; vortex->spdif_sr = spdif_sr; vortex_spdif_init(vortex, vortex->spdif_sr, 1); return 1; } /* spdif controls */ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] = { { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), .info = snd_vortex_spdif_info, .get = snd_vortex_spdif_get, .put = snd_vortex_spdif_put, }, { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_vortex_spdif_info, .get = snd_vortex_spdif_mask_get }, }; /* subdevice PCM Volume control */
iec958->status[2] = ucontrol->value.iec958.status[2]; iec958->status[3] = ucontrol->value.iec958.status[3]; mutex_unlock(&player->ctrl_lock); if (player->substream && player->substream->runtime) uni_player_set_channel_status(player, player->substream->runtime); else uni_player_set_channel_status(player, NULL); return 0; } static struct snd_kcontrol_new uni_player_iec958_ctl = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), .info = uni_player_ctl_iec958_info, .get = uni_player_ctl_iec958_get, .put = uni_player_ctl_iec958_put, }; /* * uniperif rate adjustement control */ static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN; uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;
(ucontrol->value.iec958.status[3] << 24); spin_lock_irqsave(&emu->reg_lock, flags); change = val != emu->spdif_bits[idx]; if (change) { snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val); emu->spdif_bits[idx] = val; } spin_unlock_irqrestore(&emu->reg_lock, flags); return change; } #ifdef TARGET_OS2 static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control = { SNDRV_CTL_ELEM_IFACE_MIXER,0,0, SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 0,SNDRV_CTL_ELEM_ACCESS_READ, snd_emu10k1_spdif_info, snd_emu10k1_spdif_get_mask,0,0 }; static snd_kcontrol_new_t snd_emu10k1_spdif_control = { SNDRV_CTL_ELEM_IFACE_MIXER,0,0, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),0,0, snd_emu10k1_spdif_info, snd_emu10k1_spdif_get, snd_emu10k1_spdif_put,0 }; #else static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .info = ad198x_mux_enum_info, .get = ad198x_mux_enum_get, .put = ad198x_mux_enum_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = ad1983_spdif_route_info, .get = ad1983_spdif_route_get, .put = ad1983_spdif_route_put, }, { } /* end */ }; static struct hda_verb ad1983_init_verbs[] = { /* Front, HP, Mono; mute as default */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, /* Beep, PCM, Mic, Line-In: mute */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
stm32_spdifrx_get_ctrl_data(spdifrx); ucontrol->value.iec958.status[0] = spdifrx->ub[0]; ucontrol->value.iec958.status[1] = spdifrx->ub[1]; ucontrol->value.iec958.status[2] = spdifrx->ub[2]; ucontrol->value.iec958.status[3] = spdifrx->ub[3]; ucontrol->value.iec958.status[4] = spdifrx->ub[4]; return 0; } static struct snd_kcontrol_new stm32_spdifrx_iec_ctrls[] = { /* Channel status control */ { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT), .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = stm32_spdifrx_info, .get = stm32_spdifrx_capture_get, }, /* User bits control */ { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = "IEC958 User Bit Capture Default", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = stm32_spdifrx_ub_info, .get = stm32_spdif_user_bits_get, }, };
static int ad198x_build_controls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; struct snd_kcontrol *kctl; unsigned int i; int err; for (i = 0; i < spec->num_mixers; i++) { err = snd_hda_add_new_ctls(codec, spec->mixers[i]); if (err < 0) return err; } if (spec->multiout.dig_out_nid) { err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid, spec->multiout.dig_out_nid); if (err < 0) return err; err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); if (err < 0) return err; spec->multiout.share_spdif = 1; } if (spec->dig_in_nid) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; } /* create beep controls if needed */ err = create_beep_ctls(codec); if (err < 0) return err; /* if we have no master control, let's create it */ if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { unsigned int vmaster_tlv[4]; snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, HDA_OUTPUT, vmaster_tlv); err = __snd_hda_add_vmaster(codec, "Master Playback Volume", vmaster_tlv, (spec->slave_vols ? spec->slave_vols : ad_slave_pfxs), "Playback Volume", !spec->avoid_init_slave_vol, NULL); if (err < 0) return err; } if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { err = snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, (spec->slave_sws ? spec->slave_sws : ad_slave_pfxs), "Playback Switch"); if (err < 0) return err; } /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); if (err < 0) return err; } /* assign IEC958 enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source"); if (kctl) { err = snd_hda_add_nid(codec, kctl, 0, spec->multiout.dig_out_nid); if (err < 0) return err; } return 0; }