int snd_hdac_add_chmap_ctls(struct snd_pcm *pcm, int pcm_idx, struct hdac_chmap *hchmap) { struct snd_pcm_chmap *chmap; struct snd_kcontrol *kctl; int err, i; err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, NULL, 0, pcm_idx, &chmap); if (err < 0) return err; /* override handlers */ chmap->private_data = hchmap; kctl = chmap->kctl; for (i = 0; i < kctl->count; i++) kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE; kctl->info = hdmi_chmap_ctl_info; kctl->get = hdmi_chmap_ctl_get; kctl->put = hdmi_chmap_ctl_put; kctl->tlv.c = hdmi_chmap_ctl_tlv; return 0; }
/* create a pcm device */ static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) { struct snd_pcm *pcm; struct snd_kcontrol *kctl; int i; int err, nr_capt; if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST) return -ENODEV; /* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the * same dma engine. WT uses it own separate dma engine which can't capture. */ if (idx == VORTEX_PCM_ADB) nr_capt = nr; else nr_capt = 0; err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr, nr_capt, &pcm); if (err < 0) return err; snprintf(pcm->name, sizeof(pcm->name), "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]); chip->pcm[idx] = pcm; // This is an evil hack, but it saves a lot of duplicated code. VORTEX_PCM_TYPE(pcm) = idx; pcm->private_data = chip; /* set operators */ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vortex_playback_ops); if (idx == VORTEX_PCM_ADB) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vortex_playback_ops); /* pre-allocation of Scatter-Gather buffers */ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci_dev), 0x10000, 0x10000); switch (VORTEX_PCM_TYPE(pcm)) { case VORTEX_PCM_ADB: err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_std_chmaps, VORTEX_IS_QUAD(chip) ? 4 : 2, 0, NULL); if (err < 0) return err; err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE, snd_pcm_std_chmaps, 2, 0, NULL); if (err < 0) return err; break; #ifdef CHIP_AU8830 case VORTEX_PCM_A3D: err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_std_chmaps, 1, 0, NULL); if (err < 0) return err; break; #endif } if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) { for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) { kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip); if (!kctl) return -ENOMEM; if ((err = snd_ctl_add(chip->card, kctl)) < 0) return err; } } if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) { for (i = 0; i < NR_PCM; i++) { chip->pcm_vol[i].active = 0; chip->pcm_vol[i].dma = -1; kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip); if (!kctl) return -ENOMEM; chip->pcm_vol[i].kctl = kctl; kctl->id.device = 0; kctl->id.subdevice = i; err = snd_ctl_add(chip->card, kctl); if (err < 0) return err; } } return 0; }
/* Create ALSA pcm device */ int ct_alsa_pcm_create(struct ct_atc *atc, enum CTALSADEVS device, const char *device_name) { struct snd_pcm *pcm; const struct snd_pcm_chmap_elem *map; int chs; int err; int playback_count, capture_count; playback_count = (IEC958 == device) ? 1 : 256; capture_count = (FRONT == device) ? 1 : 0; err = snd_pcm_new(atc->card, "ctxfi", device, playback_count, capture_count, &pcm); if (err < 0) { pr_err("ctxfi: snd_pcm_new failed!! Err=%d\n", err); return err; } pcm->private_data = atc; pcm->info_flags = 0; pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; strlcpy(pcm->name, device_name, sizeof(pcm->name)); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops); if (FRONT == device) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(atc->pci), 128*1024, 128*1024); chs = 2; switch (device) { case FRONT: chs = 8; map = snd_pcm_std_chmaps; break; case SURROUND: map = surround_map; break; case CLFE: map = clfe_map; break; case SIDE: map = side_map; break; default: map = snd_pcm_std_chmaps; break; } err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs, 0, NULL); if (err < 0) return err; #ifdef CONFIG_PM_SLEEP atc->pcms[device] = pcm; #endif return 0; }
static int snd_atiixp_pcm_new(struct atiixp *chip) { struct snd_pcm *pcm; struct snd_pcm_chmap *chmap; struct snd_ac97_bus *pbus = chip->ac97_bus; int err, i, num_pcms; /* initialize constants */ chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops; chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops; if (! chip->spdif_over_aclink) chip->dmas[ATI_DMA_SPDIF].ops = &snd_atiixp_spdif_dma_ops; /* assign AC97 pcm */ if (chip->spdif_over_aclink) num_pcms = 3; else num_pcms = 2; err = snd_ac97_pcm_assign(pbus, num_pcms, atiixp_pcm_defs); if (err < 0) return err; for (i = 0; i < num_pcms; i++) chip->pcms[i] = &pbus->pcms[i]; chip->max_channels = 2; if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) { if (pbus->pcms[ATI_PCM_OUT].r[0].slots & (1 << AC97_SLOT_LFE)) chip->max_channels = 6; else chip->max_channels = 4; } /* PCM #0: analog I/O */ err = snd_pcm_new(chip->card, "ATI IXP AC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops); pcm->private_data = chip; strcpy(pcm->name, "ATI IXP AC97"); chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 128*1024); err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_alt_chmaps, chip->max_channels, 0, &chmap); if (err < 0) return err; chmap->channel_mask = SND_PCM_CHMAP_MASK_2468; chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap; /* no SPDIF support on codec? */ if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates) return 0; /* FIXME: non-48k sample rate doesn't work on my test machine with AD1888 */ if (chip->pcms[ATI_PCM_SPDIF]) chip->pcms[ATI_PCM_SPDIF]->rates = SNDRV_PCM_RATE_48000; /* PCM #1: spdif playback */ err = snd_pcm_new(chip->card, "ATI IXP IEC958", ATI_PCMDEV_DIGITAL, 1, 0, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_spdif_ops); pcm->private_data = chip; if (chip->spdif_over_aclink) strcpy(pcm->name, "ATI IXP IEC958 (AC97)"); else strcpy(pcm->name, "ATI IXP IEC958 (Direct)"); chip->pcmdevs[ATI_PCMDEV_DIGITAL] = pcm; snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), 64*1024, 128*1024); /* pre-select AC97 SPDIF slots 10/11 */ for (i = 0; i < NUM_ATI_CODECS; i++) { if (chip->ac97[i]) snd_ac97_update_bits(chip->ac97[i], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4); } return 0; }