diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2015-01-16 16:15:13 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-01-16 16:44:08 -0500 |
commit | 0902fbb9ccf7e3be67b9774b0d5f096da44e7c65 (patch) | |
tree | 43055b387a000296775d50d270091b3b06be63fd /sound/pci | |
parent | 20eb26a2ec8d28f6106d210ea6a12f360e57a72b (diff) |
ALSA: oxygen: add support for third analog input
Make it possible for cards to have three stereo analog input pairs.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/oxygen/oxygen.h | 2 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 15 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 27 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_pcm.c | 45 |
4 files changed, 82 insertions, 7 deletions
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index c10ab077afd8..293d0b9a50c3 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #define CAPTURE_1_FROM_SPDIF 0x0080 | 35 | #define CAPTURE_1_FROM_SPDIF 0x0080 |
36 | #define CAPTURE_2_FROM_I2S_2 0x0100 | 36 | #define CAPTURE_2_FROM_I2S_2 0x0100 |
37 | #define CAPTURE_2_FROM_AC97_1 0x0200 | 37 | #define CAPTURE_2_FROM_AC97_1 0x0200 |
38 | /* CAPTURE_3_FROM_I2S_3 not implemented */ | 38 | #define CAPTURE_3_FROM_I2S_3 0x0400 |
39 | #define MIDI_OUTPUT 0x0800 | 39 | #define MIDI_OUTPUT 0x0800 |
40 | #define MIDI_INPUT 0x1000 | 40 | #define MIDI_INPUT 0x1000 |
41 | #define AC97_CD_INPUT 0x2000 | 41 | #define AC97_CD_INPUT 0x2000 |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index dbf1f2d4e4b5..ab47c1ca21c4 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -441,9 +441,18 @@ static void oxygen_init(struct oxygen *chip) | |||
441 | oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, | 441 | oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, |
442 | OXYGEN_I2S_MASTER | | 442 | OXYGEN_I2S_MASTER | |
443 | OXYGEN_I2S_MUTE_MCLK); | 443 | OXYGEN_I2S_MUTE_MCLK); |
444 | oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, | 444 | if (chip->model.device_config & CAPTURE_3_FROM_I2S_3) |
445 | OXYGEN_I2S_MASTER | | 445 | oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, |
446 | OXYGEN_I2S_MUTE_MCLK); | 446 | OXYGEN_RATE_48000 | |
447 | chip->model.adc_i2s_format | | ||
448 | OXYGEN_I2S_MCLK(chip->model.adc_mclks) | | ||
449 | OXYGEN_I2S_BITS_16 | | ||
450 | OXYGEN_I2S_MASTER | | ||
451 | OXYGEN_I2S_BCLK_64); | ||
452 | else | ||
453 | oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, | ||
454 | OXYGEN_I2S_MASTER | | ||
455 | OXYGEN_I2S_MUTE_MCLK); | ||
447 | oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, | 456 | oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, |
448 | OXYGEN_SPDIF_OUT_ENABLE | | 457 | OXYGEN_SPDIF_OUT_ENABLE | |
449 | OXYGEN_SPDIF_LOOPBACK); | 458 | OXYGEN_SPDIF_LOOPBACK); |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 2f698a9a5044..6492bca8c70f 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -941,6 +941,33 @@ static const struct { | |||
941 | }, | 941 | }, |
942 | }, | 942 | }, |
943 | { | 943 | { |
944 | .pcm_dev = CAPTURE_3_FROM_I2S_3, | ||
945 | .controls = { | ||
946 | { | ||
947 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
948 | .name = "Analog Input Monitor Playback Switch", | ||
949 | .index = 2, | ||
950 | .info = snd_ctl_boolean_mono_info, | ||
951 | .get = monitor_get, | ||
952 | .put = monitor_put, | ||
953 | .private_value = OXYGEN_ADC_MONITOR_C, | ||
954 | }, | ||
955 | { | ||
956 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
957 | .name = "Analog Input Monitor Playback Volume", | ||
958 | .index = 2, | ||
959 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
960 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
961 | .info = monitor_volume_info, | ||
962 | .get = monitor_get, | ||
963 | .put = monitor_put, | ||
964 | .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL | ||
965 | | (1 << 8), | ||
966 | .tlv = { .p = monitor_db_scale, }, | ||
967 | }, | ||
968 | }, | ||
969 | }, | ||
970 | { | ||
944 | .pcm_dev = CAPTURE_1_FROM_SPDIF, | 971 | .pcm_dev = CAPTURE_1_FROM_SPDIF, |
945 | .controls = { | 972 | .controls = { |
946 | { | 973 | { |
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index af22a74311d7..aa2ebd1d6d12 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c | |||
@@ -144,9 +144,11 @@ static int oxygen_open(struct snd_pcm_substream *substream, | |||
144 | runtime->hw = *oxygen_hardware[channel]; | 144 | runtime->hw = *oxygen_hardware[channel]; |
145 | switch (channel) { | 145 | switch (channel) { |
146 | case PCM_C: | 146 | case PCM_C: |
147 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | | 147 | if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) { |
148 | SNDRV_PCM_RATE_64000); | 148 | runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 | |
149 | runtime->hw.rate_min = 44100; | 149 | SNDRV_PCM_RATE_64000); |
150 | runtime->hw.rate_min = 44100; | ||
151 | } | ||
150 | /* fall through */ | 152 | /* fall through */ |
151 | case PCM_A: | 153 | case PCM_A: |
152 | case PCM_B: | 154 | case PCM_B: |
@@ -430,17 +432,36 @@ static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream, | |||
430 | struct snd_pcm_hw_params *hw_params) | 432 | struct snd_pcm_hw_params *hw_params) |
431 | { | 433 | { |
432 | struct oxygen *chip = snd_pcm_substream_chip(substream); | 434 | struct oxygen *chip = snd_pcm_substream_chip(substream); |
435 | bool is_spdif; | ||
433 | int err; | 436 | int err; |
434 | 437 | ||
435 | err = oxygen_hw_params(substream, hw_params); | 438 | err = oxygen_hw_params(substream, hw_params); |
436 | if (err < 0) | 439 | if (err < 0) |
437 | return err; | 440 | return err; |
438 | 441 | ||
442 | is_spdif = chip->model.device_config & CAPTURE_1_FROM_SPDIF; | ||
443 | |||
439 | spin_lock_irq(&chip->reg_lock); | 444 | spin_lock_irq(&chip->reg_lock); |
440 | oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, | 445 | oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, |
441 | oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT, | 446 | oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT, |
442 | OXYGEN_REC_FORMAT_C_MASK); | 447 | OXYGEN_REC_FORMAT_C_MASK); |
448 | if (!is_spdif) | ||
449 | oxygen_write16_masked(chip, OXYGEN_I2S_C_FORMAT, | ||
450 | oxygen_rate(hw_params) | | ||
451 | chip->model.adc_i2s_format | | ||
452 | get_mclk(chip, PCM_B, hw_params) | | ||
453 | oxygen_i2s_bits(hw_params), | ||
454 | OXYGEN_I2S_RATE_MASK | | ||
455 | OXYGEN_I2S_FORMAT_MASK | | ||
456 | OXYGEN_I2S_MCLK_MASK | | ||
457 | OXYGEN_I2S_BITS_MASK); | ||
443 | spin_unlock_irq(&chip->reg_lock); | 458 | spin_unlock_irq(&chip->reg_lock); |
459 | |||
460 | if (!is_spdif) { | ||
461 | mutex_lock(&chip->mutex); | ||
462 | chip->model.set_adc_params(chip, hw_params); | ||
463 | mutex_unlock(&chip->mutex); | ||
464 | } | ||
444 | return 0; | 465 | return 0; |
445 | } | 466 | } |
446 | 467 | ||
@@ -764,5 +785,23 @@ int oxygen_pcm_init(struct oxygen *chip) | |||
764 | DEFAULT_BUFFER_BYTES, | 785 | DEFAULT_BUFFER_BYTES, |
765 | BUFFER_BYTES_MAX); | 786 | BUFFER_BYTES_MAX); |
766 | } | 787 | } |
788 | |||
789 | ins = !!(chip->model.device_config & CAPTURE_3_FROM_I2S_3); | ||
790 | if (ins) { | ||
791 | err = snd_pcm_new(chip->card, "Analog3", 3, 0, ins, &pcm); | ||
792 | if (err < 0) | ||
793 | return err; | ||
794 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | ||
795 | &oxygen_rec_c_ops); | ||
796 | oxygen_write8_masked(chip, OXYGEN_REC_ROUTING, | ||
797 | OXYGEN_REC_C_ROUTE_I2S_ADC_3, | ||
798 | OXYGEN_REC_C_ROUTE_MASK); | ||
799 | pcm->private_data = chip; | ||
800 | strcpy(pcm->name, "Analog 3"); | ||
801 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
802 | snd_dma_pci_data(chip->pci), | ||
803 | DEFAULT_BUFFER_BYTES, | ||
804 | BUFFER_BYTES_MAX); | ||
805 | } | ||
767 | return 0; | 806 | return 0; |
768 | } | 807 | } |