ALSA: hda/ca0132: Add new definitions and structs for DSP
authorIan Minett <ian_minett@creativelabs.com>
Fri, 21 Dec 2012 02:53:33 +0000 (18:53 -0800)
committerTakashi Iwai <tiwai@suse.de>
Tue, 15 Jan 2013 15:57:42 +0000 (16:57 +0100)
This patch adds definitions and structs used for configuring DSP effects,
virtual nodes, effect tuning controls, and mixer control helpers.
The effect structs are also initialized.

Signed-off-by: Ian Minett <ian_minett@creativelabs.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/patch_ca0132.c

index 2fd3121afb107359387ed47437fe79327b779172..38ac07b8a4ec25f0840d578358cbb2ba5239a142 100644 (file)
 
 #include "ca0132_regs.h"
 
+/* Enable this to see controls for tuning purpose. */
+/*#define ENABLE_TUNING_CONTROLS*/
+
+#define FLOAT_ZERO     0x00000000
+#define FLOAT_ONE      0x3f800000
+#define FLOAT_TWO      0x40000000
+#define FLOAT_MINUS_5  0xc0a00000
+
+#define UNSOL_TAG_HP   0x10
+#define UNSOL_TAG_AMIC1        0x12
+#define UNSOL_TAG_DSP  0x16
+
 #define DSP_DMA_WRITE_BUFLEN_INIT (1UL<<18)
 #define DSP_DMA_WRITE_BUFLEN_OVLY (1UL<<15)
 
@@ -43,7 +55,8 @@
 #define DMA_OVERLAY_FRAME_SIZE_NWORDS          2
 
 #define MASTERCONTROL                          0x80
-#define MASTERCONTROL_ALLOC_DMA_CHAN           9
+#define MASTERCONTROL_ALLOC_DMA_CHAN           10
+#define MASTERCONTROL_QUERY_SPEAKER_EQ_ADDRESS 60
 
 #define WIDGET_CHIP_CTRL      0x15
 #define WIDGET_DSP_CTRL       0x16
 
 MODULE_FIRMWARE(EFX_FILE);
 
+static char *dirstr[2] = { "Playback", "Capture" };
+
+enum {
+       SPEAKER_OUT,
+       HEADPHONE_OUT
+};
+
+enum {
+       DIGITAL_MIC,
+       LINE_MIC_IN
+};
+
+enum {
+#define VNODE_START_NID    0x80
+       VNID_SPK = VNODE_START_NID,                     /* Speaker vnid */
+       VNID_MIC,
+       VNID_HP_SEL,
+       VNID_AMIC1_SEL,
+       VNID_HP_ASEL,
+       VNID_AMIC1_ASEL,
+       VNODE_END_NID,
+#define VNODES_COUNT  (VNODE_END_NID - VNODE_START_NID)
+
+#define EFFECT_START_NID    0x90
+#define OUT_EFFECT_START_NID    EFFECT_START_NID
+       SURROUND = OUT_EFFECT_START_NID,
+       CRYSTALIZER,
+       DIALOG_PLUS,
+       SMART_VOLUME,
+       X_BASS,
+       EQUALIZER,
+       OUT_EFFECT_END_NID,
+#define OUT_EFFECTS_COUNT  (OUT_EFFECT_END_NID - OUT_EFFECT_START_NID)
+
+#define IN_EFFECT_START_NID  OUT_EFFECT_END_NID
+       ECHO_CANCELLATION = IN_EFFECT_START_NID,
+       VOICE_FOCUS,
+       MIC_SVM,
+       NOISE_REDUCTION,
+       IN_EFFECT_END_NID,
+#define IN_EFFECTS_COUNT  (IN_EFFECT_END_NID - IN_EFFECT_START_NID)
+
+       VOICEFX = IN_EFFECT_END_NID,
+       PLAY_ENHANCEMENT,
+       CRYSTAL_VOICE,
+       EFFECT_END_NID
+#define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
+};
+
+/* Effects values size*/
+#define EFFECT_VALS_MAX_COUNT 12
+
+struct ct_effect {
+       char name[44];
+       hda_nid_t nid;
+       int mid; /*effect module ID*/
+       int reqs[EFFECT_VALS_MAX_COUNT]; /*effect module request*/
+       int direct; /* 0:output; 1:input*/
+       int params; /* number of default non-on/off params */
+       /*effect default values, 1st is on/off. */
+       unsigned int def_vals[EFFECT_VALS_MAX_COUNT];
+};
+
+#define EFX_DIR_OUT 0
+#define EFX_DIR_IN  1
+
+static struct ct_effect ca0132_effects[EFFECTS_COUNT] = {
+       { .name = "Surround",
+         .nid = SURROUND,
+         .mid = 0x96,
+         .reqs = {0, 1},
+         .direct = EFX_DIR_OUT,
+         .params = 1,
+         .def_vals = {0x3F800000, 0x3F2B851F}
+       },
+       { .name = "Crystalizer",
+         .nid = CRYSTALIZER,
+         .mid = 0x96,
+         .reqs = {7, 8},
+         .direct = EFX_DIR_OUT,
+         .params = 1,
+         .def_vals = {0x3F800000, 0x3F266666}
+       },
+       { .name = "Dialog Plus",
+         .nid = DIALOG_PLUS,
+         .mid = 0x96,
+         .reqs = {2, 3},
+         .direct = EFX_DIR_OUT,
+         .params = 1,
+         .def_vals = {0x00000000, 0x3F000000}
+       },
+       { .name = "Smart Volume",
+         .nid = SMART_VOLUME,
+         .mid = 0x96,
+         .reqs = {4, 5, 6},
+         .direct = EFX_DIR_OUT,
+         .params = 2,
+         .def_vals = {0x3F800000, 0x3F3D70A4, 0x00000000}
+       },
+       { .name = "X-Bass",
+         .nid = X_BASS,
+         .mid = 0x96,
+         .reqs = {24, 23, 25},
+         .direct = EFX_DIR_OUT,
+         .params = 2,
+         .def_vals = {0x3F800000, 0x42A00000, 0x3F000000}
+       },
+       { .name = "Equalizer",
+         .nid = EQUALIZER,
+         .mid = 0x96,
+         .reqs = {9, 10, 11, 12, 13, 14,
+                       15, 16, 17, 18, 19, 20},
+         .direct = EFX_DIR_OUT,
+         .params = 11,
+         .def_vals = {0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                      0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                      0x00000000, 0x00000000, 0x00000000, 0x00000000}
+       },
+       { .name = "Echo Cancellation",
+         .nid = ECHO_CANCELLATION,
+         .mid = 0x95,
+         .reqs = {0, 1, 2, 3},
+         .direct = EFX_DIR_IN,
+         .params = 3,
+         .def_vals = {0x00000000, 0x3F3A9692, 0x00000000, 0x00000000}
+       },
+       { .name = "Voice Focus",
+         .nid = VOICE_FOCUS,
+         .mid = 0x95,
+         .reqs = {6, 7, 8, 9},
+         .direct = EFX_DIR_IN,
+         .params = 3,
+         .def_vals = {0x3F800000, 0x3D7DF3B6, 0x41F00000, 0x41F00000}
+       },
+       { .name = "Mic SVM",
+         .nid = MIC_SVM,
+         .mid = 0x95,
+         .reqs = {44, 45},
+         .direct = EFX_DIR_IN,
+         .params = 1,
+         .def_vals = {0x00000000, 0x3F3D70A4}
+       },
+       { .name = "Noise Reduction",
+         .nid = NOISE_REDUCTION,
+         .mid = 0x95,
+         .reqs = {4, 5},
+         .direct = EFX_DIR_IN,
+         .params = 1,
+         .def_vals = {0x3F800000, 0x3F000000}
+       },
+       { .name = "VoiceFX",
+         .nid = VOICEFX,
+         .mid = 0x95,
+         .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18},
+         .direct = EFX_DIR_IN,
+         .params = 8,
+         .def_vals = {0x00000000, 0x43C80000, 0x44AF0000, 0x44FA0000,
+                      0x3F800000, 0x3F800000, 0x3F800000, 0x00000000,
+                      0x00000000}
+       }
+};
+
+/* Tuning controls */
+#ifdef ENABLE_TUNING_CONTROLS
+
+enum {
+#define TUNING_CTL_START_NID  0xC0
+       WEDGE_ANGLE = TUNING_CTL_START_NID,
+       SVM_LEVEL,
+       EQUALIZER_BAND_0,
+       EQUALIZER_BAND_1,
+       EQUALIZER_BAND_2,
+       EQUALIZER_BAND_3,
+       EQUALIZER_BAND_4,
+       EQUALIZER_BAND_5,
+       EQUALIZER_BAND_6,
+       EQUALIZER_BAND_7,
+       EQUALIZER_BAND_8,
+       EQUALIZER_BAND_9,
+       TUNING_CTL_END_NID
+#define TUNING_CTLS_COUNT  (TUNING_CTL_END_NID - TUNING_CTL_START_NID)
+};
+
+struct ct_tuning_ctl {
+       char name[44];
+       hda_nid_t parent_nid;
+       hda_nid_t nid;
+       int mid; /*effect module ID*/
+       int req; /*effect module request*/
+       int direct; /* 0:output; 1:input*/
+       unsigned int def_val;/*effect default values*/
+};
+
+static struct ct_tuning_ctl ca0132_tuning_ctls[] = {
+       { .name = "Wedge Angle",
+         .parent_nid = VOICE_FOCUS,
+         .nid = WEDGE_ANGLE,
+         .mid = 0x95,
+         .req = 8,
+         .direct = EFX_DIR_IN,
+         .def_val = 0x41F00000
+       },
+       { .name = "SVM Level",
+         .parent_nid = MIC_SVM,
+         .nid = SVM_LEVEL,
+         .mid = 0x95,
+         .req = 45,
+         .direct = EFX_DIR_IN,
+         .def_val = 0x3F3D70A4
+       },
+       { .name = "EQ Band0",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_0,
+         .mid = 0x96,
+         .req = 11,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band1",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_1,
+         .mid = 0x96,
+         .req = 12,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band2",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_2,
+         .mid = 0x96,
+         .req = 13,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band3",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_3,
+         .mid = 0x96,
+         .req = 14,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band4",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_4,
+         .mid = 0x96,
+         .req = 15,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band5",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_5,
+         .mid = 0x96,
+         .req = 16,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band6",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_6,
+         .mid = 0x96,
+         .req = 17,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band7",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_7,
+         .mid = 0x96,
+         .req = 18,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band8",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_8,
+         .mid = 0x96,
+         .req = 19,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       },
+       { .name = "EQ Band9",
+         .parent_nid = EQUALIZER,
+         .nid = EQUALIZER_BAND_9,
+         .mid = 0x96,
+         .req = 20,
+         .direct = EFX_DIR_OUT,
+         .def_val = 0x00000000
+       }
+};
+#endif
+
+/* Voice FX Presets */
+#define VOICEFX_MAX_PARAM_COUNT 9
+
+struct ct_voicefx {
+       char *name;
+       hda_nid_t nid;
+       int mid;
+       int reqs[VOICEFX_MAX_PARAM_COUNT]; /*effect module request*/
+};
+
+struct ct_voicefx_preset {
+       char *name; /*preset name*/
+       unsigned int vals[VOICEFX_MAX_PARAM_COUNT];
+};
+
+struct ct_voicefx ca0132_voicefx = {
+       .name = "VoiceFX Capture Switch",
+       .nid = VOICEFX,
+       .mid = 0x95,
+       .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18}
+};
+
+struct ct_voicefx_preset ca0132_voicefx_presets[] = {
+       { .name = "Neutral",
+         .vals = { 0x00000000, 0x43C80000, 0x44AF0000,
+                   0x44FA0000, 0x3F800000, 0x3F800000,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "Female2Male",
+         .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
+                   0x44FA0000, 0x3F19999A, 0x3F866666,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "Male2Female",
+         .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
+                   0x450AC000, 0x4017AE14, 0x3F6B851F,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "ScrappyKid",
+         .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
+                   0x44FA0000, 0x40400000, 0x3F28F5C3,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "Elderly",
+         .vals = { 0x3F800000, 0x44324000, 0x44BB8000,
+                   0x44E10000, 0x3FB33333, 0x3FB9999A,
+                   0x3F800000, 0x3E3A2E43, 0x00000000 }
+       },
+       { .name = "Orc",
+         .vals = { 0x3F800000, 0x43EA0000, 0x44A52000,
+                   0x45098000, 0x3F266666, 0x3FC00000,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "Elf",
+         .vals = { 0x3F800000, 0x43C70000, 0x44AE6000,
+                   0x45193000, 0x3F8E147B, 0x3F75C28F,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "Dwarf",
+         .vals = { 0x3F800000, 0x43930000, 0x44BEE000,
+                   0x45007000, 0x3F451EB8, 0x3F7851EC,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "AlienBrute",
+         .vals = { 0x3F800000, 0x43BFC5AC, 0x44B28FDF,
+                   0x451F6000, 0x3F266666, 0x3FA7D945,
+                   0x3F800000, 0x3CF5C28F, 0x00000000 }
+       },
+       { .name = "Robot",
+         .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
+                   0x44FA0000, 0x3FB2718B, 0x3F800000,
+                   0xBC07010E, 0x00000000, 0x00000000 }
+       },
+       { .name = "Marine",
+         .vals = { 0x3F800000, 0x43C20000, 0x44906000,
+                   0x44E70000, 0x3F4CCCCD, 0x3F8A3D71,
+                   0x3F0A3D71, 0x00000000, 0x00000000 }
+       },
+       { .name = "Emo",
+         .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
+                   0x44FA0000, 0x3F800000, 0x3F800000,
+                   0x3E4CCCCD, 0x00000000, 0x00000000 }
+       },
+       { .name = "DeepVoice",
+         .vals = { 0x3F800000, 0x43A9C5AC, 0x44AA4FDF,
+                   0x44FFC000, 0x3EDBB56F, 0x3F99C4CA,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       },
+       { .name = "Munchkin",
+         .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
+                   0x44FA0000, 0x3F800000, 0x3F1A043C,
+                   0x3F800000, 0x00000000, 0x00000000 }
+       }
+};
+
 enum hda_cmd_vendor_io {
        /* for DspIO node */
        VENDOR_DSPIO_SCP_WRITE_DATA_LOW      = 0x000,
@@ -184,8 +585,16 @@ enum control_flag_id {
  * Control parameter IDs
  */
 enum control_param_id {
+       /* 0: None, 1: Mic1In*/
+       CONTROL_PARAM_VIP_SOURCE               = 1,
        /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */
        CONTROL_PARAM_SPDIF1_SOURCE            = 2,
+       /* Port A output stage gain setting to use when 16 Ohm output
+        * impedance is selected*/
+       CONTROL_PARAM_PORTA_160OHM_GAIN        = 8,
+       /* Port D output stage gain setting to use when 16 Ohm output
+        * impedance is selected*/
+       CONTROL_PARAM_PORTD_160OHM_GAIN        = 10,
 
        /* Stream Control */
 
@@ -304,8 +713,6 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
                                    AMP_IN_UNMUTE(0));
 }
 
-static char *dirstr[2] = { "Playback", "Capture" };
-
 static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
                       int chan, int dir)
 {
@@ -2190,6 +2597,38 @@ static bool dspload_wait_loaded(struct hda_codec *codec)
        return false;
 }
 
+
+/*
+ * Mixer controls helpers.
+ */
+#define CA0132_CODEC_VOL_MONO(xname, nid, channel, dir) \
+       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+         .name = xname, \
+         .subdevice = HDA_SUBDEV_AMP_FLAG, \
+         .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+                       SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+                       SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
+         .info = ca0132_volume_info, \
+         .get = ca0132_volume_get, \
+         .put = ca0132_volume_put, \
+         .tlv = { .c = ca0132_volume_tlv }, \
+         .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
+
+#define CA0132_CODEC_MUTE_MONO(xname, nid, channel, dir) \
+       { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+         .name = xname, \
+         .subdevice = HDA_SUBDEV_AMP_FLAG, \
+         .info = snd_hda_mixer_amp_switch_info, \
+         .get = ca0132_switch_get, \
+         .put = ca0132_switch_put, \
+         .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
+
+/* stereo */
+#define CA0132_CODEC_VOL(xname, nid, dir) \
+       CA0132_CODEC_VOL_MONO(xname, nid, 3, dir)
+#define CA0132_CODEC_MUTE(xname, nid, dir) \
+       CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir)
+
 /*
  * PCM callbacks
  */