Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
Archivo: atiixp.c Proyecto: 3null/linux
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;
}