aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2015-01-16 16:15:13 -0500
committerTakashi Iwai <tiwai@suse.de>2015-01-16 16:44:08 -0500
commit0902fbb9ccf7e3be67b9774b0d5f096da44e7c65 (patch)
tree43055b387a000296775d50d270091b3b06be63fd
parent20eb26a2ec8d28f6106d210ea6a12f360e57a72b (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>
-rw-r--r--sound/pci/oxygen/oxygen.h2
-rw-r--r--sound/pci/oxygen/oxygen_lib.c15
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c27
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c45
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}