Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e85e0925 authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Jaroslav Kysela
Browse files

[ALSA] oxygen: make all DMA channels configurable



Allow the card models to specify whether each of the hardware DMA
channels is used.

Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent 84aa6b7b
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -256,6 +256,11 @@ static const struct oxygen_model model_generic = {
	.update_dac_volume = update_ak4396_volume,
	.update_dac_mute = update_ak4396_mute,
	.dac_tlv = ak4396_db_scale,
	.used_channels = OXYGEN_CHANNEL_A |
			 OXYGEN_CHANNEL_C |
			 OXYGEN_CHANNEL_SPDIF |
			 OXYGEN_CHANNEL_MULTICH |
			 OXYGEN_CHANNEL_AC97,
	.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
};
static const struct oxygen_model model_meridian = {
@@ -270,7 +275,11 @@ static const struct oxygen_model model_meridian = {
	.update_dac_volume = update_ak4396_volume,
	.update_dac_mute = update_ak4396_mute,
	.dac_tlv = ak4396_db_scale,
	.record_from_dma_b = 1,
	.used_channels = OXYGEN_CHANNEL_B |
			 OXYGEN_CHANNEL_C |
			 OXYGEN_CHANNEL_SPDIF |
			 OXYGEN_CHANNEL_MULTICH |
			 OXYGEN_CHANNEL_AC97,
	.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
};

+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ struct oxygen_model {
	void (*update_dac_volume)(struct oxygen *chip);
	void (*update_dac_mute)(struct oxygen *chip);
	const unsigned int *dac_tlv;
	u8 record_from_dma_b;
	u8 used_channels;
	u8 cd_in_from_video_in;
	u8 dac_minimum_volume;
	u8 function_flags;
+49 −23
Original line number Diff line number Diff line
@@ -681,15 +681,22 @@ static void oxygen_pcm_free(struct snd_pcm *pcm)
int __devinit oxygen_pcm_init(struct oxygen *chip)
{
	struct snd_pcm *pcm;
	int outs, ins;
	int err;

	err = snd_pcm_new(chip->card, "Analog", 0, 1, 1, &pcm);
	outs = 1; /* OXYGEN_CHANNEL_MULTICH is always used */
	ins = !!(chip->model->used_channels & (OXYGEN_CHANNEL_A |
					       OXYGEN_CHANNEL_B));
	err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm);
	if (err < 0)
		return err;
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops);
	if (chip->model->used_channels & OXYGEN_CHANNEL_A)
		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
			chip->model->record_from_dma_b ?
			&oxygen_rec_b_ops : &oxygen_rec_a_ops);
				&oxygen_rec_a_ops);
	else if (chip->model->used_channels & OXYGEN_CHANNEL_B)
		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
				&oxygen_rec_b_ops);
	pcm->private_data = chip;
	pcm->private_free = oxygen_pcm_free;
	strcpy(pcm->name, "Analog");
@@ -697,32 +704,51 @@ int __devinit oxygen_pcm_init(struct oxygen *chip)
				      SNDRV_DMA_TYPE_DEV,
				      snd_dma_pci_data(chip->pci),
				      512 * 1024, 2048 * 1024);
	if (ins)
		snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
					      SNDRV_DMA_TYPE_DEV,
					      snd_dma_pci_data(chip->pci),
					      128 * 1024, 256 * 1024);

	err = snd_pcm_new(chip->card, "Digital", 1, 1, 1, &pcm);
	outs = !!(chip->model->used_channels & OXYGEN_CHANNEL_SPDIF);
	ins = !!(chip->model->used_channels & OXYGEN_CHANNEL_C);
	if (outs | ins) {
		err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
		if (err < 0)
			return err;
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_spdif_ops);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_c_ops);
		if (outs)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					&oxygen_spdif_ops);
		if (ins)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
					&oxygen_rec_c_ops);
		pcm->private_data = chip;
		pcm->private_free = oxygen_pcm_free;
		strcpy(pcm->name, "Digital");
		snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
						      snd_dma_pci_data(chip->pci),
						      128 * 1024, 256 * 1024);
	}

	if (chip->has_ac97_1) {
		err = snd_pcm_new(chip->card, "AC97", 2, 1, 0, &pcm);
	outs = chip->has_ac97_1 &&
		(chip->model->used_channels & OXYGEN_CHANNEL_AC97);
	ins = (chip->model->used_channels & (OXYGEN_CHANNEL_A |
					     OXYGEN_CHANNEL_B))
		== (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B);
	if (outs | ins) {
		err = snd_pcm_new(chip->card, ins ? "Analog2" : "AC97",
				  2, outs, ins, &pcm);
		if (err < 0)
			return err;
		if (outs)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					&oxygen_ac97_ops);
		if (ins)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
					&oxygen_rec_b_ops);
		pcm->private_data = chip;
		pcm->private_free = oxygen_pcm_free;
		strcpy(pcm->name, "Front Panel");
		strcpy(pcm->name, ins ? "Analog 2" : "Front Panel");
		snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
						      snd_dma_pci_data(chip->pci),
						      128 * 1024, 256 * 1024);
+4 −1
Original line number Diff line number Diff line
@@ -224,7 +224,10 @@ static const struct oxygen_model model_xonar = {
	.update_dac_volume = update_pcm1796_volume,
	.update_dac_mute = update_pcm1796_mute,
	.dac_tlv = pcm1796_db_scale,
	.record_from_dma_b = 1,
	.used_channels = OXYGEN_CHANNEL_B |
			 OXYGEN_CHANNEL_C |
			 OXYGEN_CHANNEL_SPDIF |
			 OXYGEN_CHANNEL_MULTICH,
	.cd_in_from_video_in = 1,
	.dac_minimum_volume = 15,
	.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,