#include "ctatc.h"
 #include "ctpcm.h"
 #include "ctmixer.h"
-#include "cthardware.h"
 #include "ctsrc.h"
 #include "ctamixer.h"
 #include "ctdaio.h"
        return 0;
 }
 
-static int atc_have_digit_io_switch(struct ct_atc *atc)
+static struct capabilities atc_capabilities(struct ct_atc *atc)
 {
        struct hw *hw = atc->hw;
 
-       return hw->have_digit_io_switch(hw);
-}
-
-static int atc_have_dedicated_mic(struct ct_atc *atc)
-{
-       struct hw *hw = atc->hw;
-
-       return hw->have_dedicated_mic(hw);
-}
-
-static int atc_have_output_switch(struct ct_atc *atc)
-{
-       struct hw *hw = atc->hw;
-
-       return hw->have_output_switch(hw);
+       return hw->capabilities(hw);
 }
 
 static int atc_output_switch_get(struct ct_atc *atc)
        return hw->output_switch_put(hw, position);
 }
 
-static int atc_have_mic_source_switch(struct ct_atc *atc)
-{
-       struct hw *hw = atc->hw;
-
-       return hw->have_mic_source_switch(hw);
-}
-
 static int atc_mic_source_switch_get(struct ct_atc *atc)
 {
        struct hw *hw = atc->hw;
        .spdif_out_get_status = atc_spdif_out_get_status,
        .spdif_out_set_status = atc_spdif_out_set_status,
        .spdif_out_passthru = atc_spdif_out_passthru,
-       .have_digit_io_switch = atc_have_digit_io_switch,
-       .have_dedicated_mic = atc_have_dedicated_mic,
-       .have_output_switch = atc_have_output_switch,
+       .capabilities = atc_capabilities,
        .output_switch_get = atc_output_switch_get,
        .output_switch_put = atc_output_switch_put,
-       .have_mic_source_switch = atc_have_mic_source_switch,
        .mic_source_switch_get = atc_mic_source_switch_get,
        .mic_source_switch_put = atc_mic_source_switch_put,
 #ifdef CONFIG_PM
 
 #include <sound/core.h>
 
 #include "ctvmem.h"
+#include "cthardware.h"
 #include "ctresource.h"
 
 enum CTALSADEVS {              /* Types of alsa devices */
        int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
        int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
        int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
-       int (*have_digit_io_switch)(struct ct_atc *atc);
-       int (*have_dedicated_mic)(struct ct_atc *atc);
-       int (*have_output_switch)(struct ct_atc *atc);
+       struct capabilities (*capabilities)(struct ct_atc *atc);
        int (*output_switch_get)(struct ct_atc *atc);
        int (*output_switch_put)(struct ct_atc *atc, int position);
-       int (*have_mic_source_switch)(struct ct_atc *atc);
        int (*mic_source_switch_get)(struct ct_atc *atc);
        int (*mic_source_switch_put)(struct ct_atc *atc, int position);
 
 
        unsigned int msr;       /* master sample rate in rsrs */
 };
 
+struct capabilities {
+       unsigned int digit_io_switch:1;
+       unsigned int dedicated_mic:1;
+       unsigned int output_switch:1;
+       unsigned int mic_source_switch:1;
+};
+
 struct hw {
        int (*card_init)(struct hw *hw, struct card_conf *info);
        int (*card_stop)(struct hw *hw);
 #endif
        int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
        int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
-       int (*have_digit_io_switch)(struct hw *hw);
-       int (*have_dedicated_mic)(struct hw *hw);
-       int (*have_output_switch)(struct hw *hw);
+       struct capabilities (*capabilities)(struct hw *hw);
        int (*output_switch_get)(struct hw *hw);
        int (*output_switch_put)(struct hw *hw, int position);
-       int (*have_mic_source_switch)(struct hw *hw);
        int (*mic_source_switch_get)(struct hw *hw);
        int (*mic_source_switch_put)(struct hw *hw, int position);
 
 
                return adc_init_SBx(hw, info->input, info->mic20db);
 }
 
-static int hw_have_digit_io_switch(struct hw *hw)
+static struct capabilities hw_capabilities(struct hw *hw)
 {
-       /* SB073x and Vista compatible cards have no digit IO switch */
-       return !(hw->model == CTSB073X || hw->model == CTUAA);
-}
-
-static int hw_have_dedicated_mic(struct hw *hw)
-{
-       return 0;
-}
+       struct capabilities cap;
 
-static int hw_have_output_switch(struct hw *hw)
-{
-       return 0;
-}
+       /* SB073x and Vista compatible cards have no digit IO switch */
+       cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA);
+       cap.dedicated_mic = 0;
+       cap.output_switch = 0;
+       cap.mic_source_switch = 0;
 
-static int hw_have_mic_source_switch(struct hw *hw)
-{
-       return 0;
+       return cap;
 }
 
 #define CTLBITS(a, b, c, d)    (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
        .pll_init = hw_pll_init,
        .is_adc_source_selected = hw_is_adc_input_selected,
        .select_adc_source = hw_adc_input_select,
-       .have_digit_io_switch = hw_have_digit_io_switch,
-       .have_dedicated_mic = hw_have_dedicated_mic,
-       .have_output_switch = hw_have_output_switch,
-       .have_mic_source_switch = hw_have_mic_source_switch,
+       .capabilities = hw_capabilities,
 #ifdef CONFIG_PM
        .suspend = hw_suspend,
        .resume = hw_resume,
 
        return err;
 }
 
-static int hw_have_digit_io_switch(struct hw *hw)
+static struct capabilities hw_capabilities(struct hw *hw)
 {
-       return 0;
-}
+       struct capabilities cap;
 
-static int hw_have_dedicated_mic(struct hw *hw)
-{
-       return hw->model == CTSB1270;
-}
+       cap.digit_io_switch = 0;
+       cap.dedicated_mic = hw->model == CTSB1270;
+       cap.output_switch = hw->model == CTSB1270;
+       cap.mic_source_switch = hw->model == CTSB1270;
 
-static int hw_have_output_switch(struct hw *hw)
-{
-       return hw->model == CTSB1270;
+       return cap;
 }
 
 static int hw_output_switch_get(struct hw *hw)
        return 1;
 }
 
-static int hw_have_mic_source_switch(struct hw *hw)
-{
-       return hw->model == CTSB1270;
-}
-
 static int hw_mic_source_switch_get(struct hw *hw)
 {
        struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
        .pll_init = hw_pll_init,
        .is_adc_source_selected = hw_is_adc_input_selected,
        .select_adc_source = hw_adc_input_select,
-       .have_digit_io_switch = hw_have_digit_io_switch,
-       .have_dedicated_mic = hw_have_dedicated_mic,
-       .have_output_switch = hw_have_output_switch,
+       .capabilities = hw_capabilities,
        .output_switch_get = hw_output_switch_get,
        .output_switch_put = hw_output_switch_put,
-       .have_mic_source_switch = hw_have_mic_source_switch,
        .mic_source_switch_get = hw_mic_source_switch_get,
        .mic_source_switch_put = hw_mic_source_switch_put,
 #ifdef CONFIG_PM
 
 static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
 {
        struct ct_mixer *mixer = atc->mixer;
-       int have_dedicated_mic = atc->have_dedicated_mic(atc);
+       struct capabilities cap = atc->capabilities(atc);
 
        /* Do changes in mixer. */
        if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
                }
        }
        /* Do changes out of mixer. */
-       if (!have_dedicated_mic &&
+       if (!cap.dedicated_mic &&
            (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) {
                if (state)
                        do_line_mic_switch(atc, type);
                atc->line_in_unmute(atc, state);
-       } else if (have_dedicated_mic && (MIXER_LINEIN_C_S == type))
+       } else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type))
                atc->line_in_unmute(atc, state);
-       else if (have_dedicated_mic && (MIXER_MIC_C_S == type))
+       else if (cap.dedicated_mic && (MIXER_MIC_C_S == type))
                atc->mic_unmute(atc, state);
        else if (MIXER_SPDIFI_C_S == type)
                atc->spdif_in_unmute(atc, state);
 {
        enum CTALSA_MIXER_CTL type;
        struct ct_atc *atc = mixer->atc;
+       struct capabilities cap = atc->capabilities(atc);
        int err;
 
        /* Create snd kcontrol instances on demand */
                }
        }
 
-       ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl =
-                                       atc->have_digit_io_switch(atc);
+       ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch;
 
        for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
                if (ct_kcontrol_init_table[type].ctl) {
        if (err)
                return err;
 
-       if (atc->have_output_switch(atc)) {
+       if (cap.output_switch) {
                err = ct_mixer_kcontrol_new(mixer, &output_ctl);
                if (err)
                        return err;
        }
 
-       if (atc->have_mic_source_switch(atc)) {
+       if (cap.mic_source_switch) {
                err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl);
                if (err)
                        return err;
        atc->spdif_out_unmute(atc, 0);
        set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
        atc->line_in_unmute(atc, 0);
-       if (atc->have_dedicated_mic(atc))
+       if (cap.dedicated_mic)
                atc->mic_unmute(atc, 0);
        atc->spdif_in_unmute(atc, 0);
        set_switch_state(mixer, MIXER_PCM_C_S, 0);