]> err.no Git - linux-2.6/commitdiff
[ALSA] oxygen: change model-specific PCM device configuration
authorClemens Ladisch <clemens@ladisch.de>
Wed, 19 Mar 2008 07:19:41 +0000 (08:19 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 24 Apr 2008 10:00:28 +0000 (12:00 +0200)
When specifying which PCM devices to use, model drivers now use flags
that also specify the routing between PCM devices and DMA channels
instead of just DMA channel bits.  This simplifies some code that checks
for these flags.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/oxygen/hifier.c
sound/pci/oxygen/oxygen.c
sound/pci/oxygen/oxygen.h
sound/pci/oxygen/oxygen_mixer.c
sound/pci/oxygen/oxygen_pcm.c
sound/pci/oxygen/virtuoso.c

index 666f69a3312e9a3c08cd90ac91008105f482fa3d..fa489ed3ed46fdcdf8b65dd9d93450de4b8a1d4c 100644 (file)
@@ -160,10 +160,10 @@ static const struct oxygen_model model_hifier = {
        .update_dac_volume = update_ak4396_volume,
        .update_dac_mute = update_ak4396_mute,
        .model_data_size = sizeof(struct hifier_data),
+       .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
+                      PLAYBACK_1_TO_SPDIF |
+                      CAPTURE_0_FROM_I2S_1,
        .dac_channels = 2,
-       .used_channels = OXYGEN_CHANNEL_A |
-                        OXYGEN_CHANNEL_SPDIF |
-                        OXYGEN_CHANNEL_MULTICH,
        .function_flags = 0,
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
index 542752442a9561f2a958d7044eb4ccd214a368df..9faf43c949b22e929e8162ce3ec37acd4e35d4e3 100644 (file)
@@ -303,12 +303,13 @@ static const struct oxygen_model model_generic = {
        .update_dac_mute = update_ak4396_mute,
        .ac97_switch_hook = cmi9780_switch_hook,
        .model_data_size = sizeof(struct generic_data),
+       .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
+                      PLAYBACK_1_TO_SPDIF |
+                      PLAYBACK_2_TO_AC97_1 |
+                      CAPTURE_0_FROM_I2S_1 |
+                      CAPTURE_1_FROM_SPDIF |
+                      CAPTURE_2_FROM_AC97_1,
        .dac_channels = 8,
-       .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,
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
@@ -327,12 +328,13 @@ static const struct oxygen_model model_meridian = {
        .update_dac_mute = update_ak4396_mute,
        .ac97_switch_hook = cmi9780_switch_hook,
        .model_data_size = sizeof(struct generic_data),
+       .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
+                      PLAYBACK_1_TO_SPDIF |
+                      PLAYBACK_2_TO_AC97_1 |
+                      CAPTURE_0_FROM_I2S_2 |
+                      CAPTURE_1_FROM_SPDIF |
+                      CAPTURE_2_FROM_AC97_1,
        .dac_channels = 8,
-       .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,
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
index ad50fb8b206b5a356c082682db51e8e13be25640..fde995cf2edfeda2d848b5501f4d760e68edd7fd 100644 (file)
 #define PCM_AC97       5
 #define PCM_COUNT      6
 
+/* model-specific configuration of outputs/inputs */
+#define PLAYBACK_0_TO_I2S      0x001
+#define PLAYBACK_1_TO_SPDIF    0x004
+#define PLAYBACK_2_TO_AC97_1   0x008
+#define CAPTURE_0_FROM_I2S_1   0x010
+#define CAPTURE_0_FROM_I2S_2   0x020
+#define CAPTURE_1_FROM_SPDIF   0x080
+#define CAPTURE_2_FROM_I2S_2   0x100
+#define CAPTURE_2_FROM_AC97_1  0x200
+
 enum {
        CONTROL_SPDIF_PCM,
        CONTROL_SPDIF_INPUT_BITS,
@@ -91,8 +101,8 @@ struct oxygen_model {
                                 unsigned int reg, int mute);
        void (*gpio_changed)(struct oxygen *chip);
        size_t model_data_size;
+       unsigned int pcm_dev_cfg;
        u8 dac_channels;
-       u8 used_channels;
        u8 function_flags;
        u16 dac_i2s_format;
        u16 adc_i2s_format;
index 4e77b79b3b6e4bc43baf4593f638c13c390e3942..6b5ff6e0fadd529186cfbd3c9949564ac6163c48 100644 (file)
@@ -737,90 +737,111 @@ static const struct snd_kcontrol_new controls[] = {
        },
 };
 
-static const struct snd_kcontrol_new monitor_a_controls[] = {
+static const struct {
+       unsigned int pcm_dev;
+       struct snd_kcontrol_new controls[2];
+} monitor_controls[] = {
        {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Input Monitor Switch",
-               .info = snd_ctl_boolean_mono_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_A,
+               .pcm_dev = CAPTURE_0_FROM_I2S_1,
+               .controls = {
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Switch",
+                               .info = snd_ctl_boolean_mono_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_A,
+                       },
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Volume",
+                               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+                               .info = monitor_volume_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL
+                                               | (1 << 8),
+                               .tlv = { .p = monitor_db_scale, },
+                       },
+               },
        },
        {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Input Monitor Volume",
-               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
-               .info = monitor_volume_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL | (1 << 8),
-               .tlv = { .p = monitor_db_scale, },
+               .pcm_dev = CAPTURE_0_FROM_I2S_2,
+               .controls = {
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Switch",
+                               .info = snd_ctl_boolean_mono_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_B,
+                       },
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Volume",
+                               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+                               .info = monitor_volume_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
+                                               | (1 << 8),
+                               .tlv = { .p = monitor_db_scale, },
+                       },
+               },
        },
-};
-static const struct snd_kcontrol_new monitor_b_controls[] = {
        {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Input Monitor Switch",
-               .info = snd_ctl_boolean_mono_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_B,
+               .pcm_dev = CAPTURE_2_FROM_I2S_2,
+               .controls = {
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Switch",
+                               .index = 1,
+                               .info = snd_ctl_boolean_mono_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_B,
+                       },
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Analog Input Monitor Volume",
+                               .index = 1,
+                               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+                               .info = monitor_volume_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
+                                               | (1 << 8),
+                               .tlv = { .p = monitor_db_scale, },
+                       },
+               },
        },
        {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Input Monitor Volume",
-               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
-               .info = monitor_volume_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL | (1 << 8),
-               .tlv = { .p = monitor_db_scale, },
-       },
-};
-static const struct snd_kcontrol_new monitor_2nd_b_controls[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Input Monitor Switch",
-               .index = 1,
-               .info = snd_ctl_boolean_mono_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_B,
-       },
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Input Monitor Volume",
-               .index = 1,
-               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
-               .info = monitor_volume_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL | (1 << 8),
-               .tlv = { .p = monitor_db_scale, },
-       },
-};
-static const struct snd_kcontrol_new monitor_c_controls[] = {
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Digital Input Monitor Switch",
-               .info = snd_ctl_boolean_mono_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_C,
-       },
-       {
-               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Digital Input Monitor Volume",
-               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
-               .info = monitor_volume_info,
-               .get = monitor_get,
-               .put = monitor_put,
-               .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL | (1 << 8),
-               .tlv = { .p = monitor_db_scale, },
+               .pcm_dev = CAPTURE_1_FROM_SPDIF,
+               .controls = {
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Digital Input Monitor Switch",
+                               .info = snd_ctl_boolean_mono_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_C,
+                       },
+                       {
+                               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+                               .name = "Digital Input Monitor Volume",
+                               .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+                                         SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+                               .info = monitor_volume_info,
+                               .get = monitor_get,
+                               .put = monitor_put,
+                               .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
+                                               | (1 << 8),
+                               .tlv = { .p = monitor_db_scale, },
+                       },
+               },
        },
 };
 
@@ -905,32 +926,17 @@ static int add_controls(struct oxygen *chip,
 
 int oxygen_mixer_init(struct oxygen *chip)
 {
+       unsigned int i;
        int err;
 
        err = add_controls(chip, controls, ARRAY_SIZE(controls));
        if (err < 0)
                return err;
-       if (chip->model->used_channels & OXYGEN_CHANNEL_A) {
-               err = add_controls(chip, monitor_a_controls,
-                                  ARRAY_SIZE(monitor_a_controls));
-               if (err < 0)
-                       return err;
-       } else if (chip->model->used_channels & OXYGEN_CHANNEL_B) {
-               err = add_controls(chip, monitor_b_controls,
-                                  ARRAY_SIZE(monitor_b_controls));
-               if (err < 0)
-                       return err;
-       }
-       if ((chip->model->used_channels & (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B))
-           == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B)) {
-               err = add_controls(chip, monitor_2nd_b_controls,
-                                  ARRAY_SIZE(monitor_2nd_b_controls));
-               if (err < 0)
-                       return err;
-       }
-       if (chip->model->used_channels & OXYGEN_CHANNEL_C) {
-               err = add_controls(chip, monitor_c_controls,
-                                  ARRAY_SIZE(monitor_c_controls));
+       for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
+               if (!(chip->model->pcm_dev_cfg & monitor_controls[i].pcm_dev))
+                       continue;
+               err = add_controls(chip, monitor_controls[i].controls,
+                                  ARRAY_SIZE(monitor_controls[i].controls));
                if (err < 0)
                        return err;
        }
index b70046aca65764ac30b618d9c873b3b63ac4c909..b17c405e069df5349daceba5db00416de012eb1b 100644 (file)
@@ -119,7 +119,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
 
        runtime->private_data = (void *)(uintptr_t)channel;
        if (channel == PCM_B && chip->has_ac97_1 &&
-           (chip->model->used_channels & OXYGEN_CHANNEL_AC97))
+           (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1))
                runtime->hw = oxygen_ac97_hardware;
        else
                runtime->hw = *oxygen_hardware[channel];
@@ -365,7 +365,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
                return err;
 
        is_ac97 = chip->has_ac97_1 &&
-               (chip->model->used_channels & OXYGEN_CHANNEL_AC97);
+               (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1);
 
        spin_lock_irq(&chip->reg_lock);
        oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
@@ -640,34 +640,39 @@ int oxygen_pcm_init(struct oxygen *chip)
        int outs, ins;
        int err;
 
-       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,
-                               &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");
-       snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
-                                     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);
-
-       outs = !!(chip->model->used_channels & OXYGEN_CHANNEL_SPDIF);
-       ins = !!(chip->model->used_channels & OXYGEN_CHANNEL_C);
+       outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_0_TO_I2S);
+       ins = !!(chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 |
+                                            CAPTURE_0_FROM_I2S_2));
+       if (outs | ins) {
+               err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm);
+               if (err < 0)
+                       return err;
+               if (outs)
+                       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                                       &oxygen_multich_ops);
+               if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1)
+                       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+                                       &oxygen_rec_a_ops);
+               else if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_2)
+                       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");
+               if (outs)
+                       snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
+                                                     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);
+       }
+
+       outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF);
+       ins = !!(chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF);
        if (outs | ins) {
                err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
                if (err < 0)
@@ -686,12 +691,13 @@ int oxygen_pcm_init(struct oxygen *chip)
                                                      128 * 1024, 256 * 1024);
        }
 
-       outs = chip->has_ac97_1 &&
-               (chip->model->used_channels & OXYGEN_CHANNEL_AC97);
-       ins = outs ||
-               (chip->model->used_channels & (OXYGEN_CHANNEL_A |
-                                              OXYGEN_CHANNEL_B))
-               == (OXYGEN_CHANNEL_A | OXYGEN_CHANNEL_B);
+       if (chip->has_ac97_1) {
+               outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_2_TO_AC97_1);
+               ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1);
+       } else {
+               outs = 0;
+               ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_I2S_2);
+       }
        if (outs | ins) {
                err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
                                  2, outs, ins, &pcm);
index 127dd664fc16bc38ec839b236fa8a0bcbf9179b9..5cd1fac141321f128eb8e86b6db3dbc5663aa992 100644 (file)
@@ -348,11 +348,11 @@ static const struct oxygen_model model_xonar = {
        .ac97_switch_hook = xonar_ac97_switch_hook,
        .gpio_changed = xonar_gpio_changed,
        .model_data_size = sizeof(struct xonar_data),
+       .pcm_dev_cfg = PLAYBACK_0_TO_I2S |
+                      PLAYBACK_1_TO_SPDIF |
+                      CAPTURE_0_FROM_I2S_2 |
+                      CAPTURE_1_FROM_SPDIF,
        .dac_channels = 8,
-       .used_channels = OXYGEN_CHANNEL_B |
-                        OXYGEN_CHANNEL_C |
-                        OXYGEN_CHANNEL_SPDIF |
-                        OXYGEN_CHANNEL_MULTICH,
        .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,