aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorIan Minett <ian_minett@creativelabs.com>2012-12-20 21:53:33 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-15 10:57:42 -0500
commitef6b2eada3b8c1b21f6479d7480ea7030183fe1d (patch)
tree632cc3a8fe117da92b7106adc52b0604ea4f0aba /sound/pci
parentcdc83c59e59d57b250be46c4b9d31e3b2b5ae589 (diff)
ALSA: hda/ca0132: Add new definitions and structs for DSP
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>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_ca0132.c445
1 files changed, 442 insertions, 3 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 2fd3121afb10..38ac07b8a4ec 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -35,6 +35,18 @@
35 35
36#include "ca0132_regs.h" 36#include "ca0132_regs.h"
37 37
38/* Enable this to see controls for tuning purpose. */
39/*#define ENABLE_TUNING_CONTROLS*/
40
41#define FLOAT_ZERO 0x00000000
42#define FLOAT_ONE 0x3f800000
43#define FLOAT_TWO 0x40000000
44#define FLOAT_MINUS_5 0xc0a00000
45
46#define UNSOL_TAG_HP 0x10
47#define UNSOL_TAG_AMIC1 0x12
48#define UNSOL_TAG_DSP 0x16
49
38#define DSP_DMA_WRITE_BUFLEN_INIT (1UL<<18) 50#define DSP_DMA_WRITE_BUFLEN_INIT (1UL<<18)
39#define DSP_DMA_WRITE_BUFLEN_OVLY (1UL<<15) 51#define DSP_DMA_WRITE_BUFLEN_OVLY (1UL<<15)
40 52
@@ -43,7 +55,8 @@
43#define DMA_OVERLAY_FRAME_SIZE_NWORDS 2 55#define DMA_OVERLAY_FRAME_SIZE_NWORDS 2
44 56
45#define MASTERCONTROL 0x80 57#define MASTERCONTROL 0x80
46#define MASTERCONTROL_ALLOC_DMA_CHAN 9 58#define MASTERCONTROL_ALLOC_DMA_CHAN 10
59#define MASTERCONTROL_QUERY_SPEAKER_EQ_ADDRESS 60
47 60
48#define WIDGET_CHIP_CTRL 0x15 61#define WIDGET_CHIP_CTRL 0x15
49#define WIDGET_DSP_CTRL 0x16 62#define WIDGET_DSP_CTRL 0x16
@@ -63,6 +76,394 @@
63 76
64MODULE_FIRMWARE(EFX_FILE); 77MODULE_FIRMWARE(EFX_FILE);
65 78
79static char *dirstr[2] = { "Playback", "Capture" };
80
81enum {
82 SPEAKER_OUT,
83 HEADPHONE_OUT
84};
85
86enum {
87 DIGITAL_MIC,
88 LINE_MIC_IN
89};
90
91enum {
92#define VNODE_START_NID 0x80
93 VNID_SPK = VNODE_START_NID, /* Speaker vnid */
94 VNID_MIC,
95 VNID_HP_SEL,
96 VNID_AMIC1_SEL,
97 VNID_HP_ASEL,
98 VNID_AMIC1_ASEL,
99 VNODE_END_NID,
100#define VNODES_COUNT (VNODE_END_NID - VNODE_START_NID)
101
102#define EFFECT_START_NID 0x90
103#define OUT_EFFECT_START_NID EFFECT_START_NID
104 SURROUND = OUT_EFFECT_START_NID,
105 CRYSTALIZER,
106 DIALOG_PLUS,
107 SMART_VOLUME,
108 X_BASS,
109 EQUALIZER,
110 OUT_EFFECT_END_NID,
111#define OUT_EFFECTS_COUNT (OUT_EFFECT_END_NID - OUT_EFFECT_START_NID)
112
113#define IN_EFFECT_START_NID OUT_EFFECT_END_NID
114 ECHO_CANCELLATION = IN_EFFECT_START_NID,
115 VOICE_FOCUS,
116 MIC_SVM,
117 NOISE_REDUCTION,
118 IN_EFFECT_END_NID,
119#define IN_EFFECTS_COUNT (IN_EFFECT_END_NID - IN_EFFECT_START_NID)
120
121 VOICEFX = IN_EFFECT_END_NID,
122 PLAY_ENHANCEMENT,
123 CRYSTAL_VOICE,
124 EFFECT_END_NID
125#define EFFECTS_COUNT (EFFECT_END_NID - EFFECT_START_NID)
126};
127
128/* Effects values size*/
129#define EFFECT_VALS_MAX_COUNT 12
130
131struct ct_effect {
132 char name[44];
133 hda_nid_t nid;
134 int mid; /*effect module ID*/
135 int reqs[EFFECT_VALS_MAX_COUNT]; /*effect module request*/
136 int direct; /* 0:output; 1:input*/
137 int params; /* number of default non-on/off params */
138 /*effect default values, 1st is on/off. */
139 unsigned int def_vals[EFFECT_VALS_MAX_COUNT];
140};
141
142#define EFX_DIR_OUT 0
143#define EFX_DIR_IN 1
144
145static struct ct_effect ca0132_effects[EFFECTS_COUNT] = {
146 { .name = "Surround",
147 .nid = SURROUND,
148 .mid = 0x96,
149 .reqs = {0, 1},
150 .direct = EFX_DIR_OUT,
151 .params = 1,
152 .def_vals = {0x3F800000, 0x3F2B851F}
153 },
154 { .name = "Crystalizer",
155 .nid = CRYSTALIZER,
156 .mid = 0x96,
157 .reqs = {7, 8},
158 .direct = EFX_DIR_OUT,
159 .params = 1,
160 .def_vals = {0x3F800000, 0x3F266666}
161 },
162 { .name = "Dialog Plus",
163 .nid = DIALOG_PLUS,
164 .mid = 0x96,
165 .reqs = {2, 3},
166 .direct = EFX_DIR_OUT,
167 .params = 1,
168 .def_vals = {0x00000000, 0x3F000000}
169 },
170 { .name = "Smart Volume",
171 .nid = SMART_VOLUME,
172 .mid = 0x96,
173 .reqs = {4, 5, 6},
174 .direct = EFX_DIR_OUT,
175 .params = 2,
176 .def_vals = {0x3F800000, 0x3F3D70A4, 0x00000000}
177 },
178 { .name = "X-Bass",
179 .nid = X_BASS,
180 .mid = 0x96,
181 .reqs = {24, 23, 25},
182 .direct = EFX_DIR_OUT,
183 .params = 2,
184 .def_vals = {0x3F800000, 0x42A00000, 0x3F000000}
185 },
186 { .name = "Equalizer",
187 .nid = EQUALIZER,
188 .mid = 0x96,
189 .reqs = {9, 10, 11, 12, 13, 14,
190 15, 16, 17, 18, 19, 20},
191 .direct = EFX_DIR_OUT,
192 .params = 11,
193 .def_vals = {0x00000000, 0x00000000, 0x00000000, 0x00000000,
194 0x00000000, 0x00000000, 0x00000000, 0x00000000,
195 0x00000000, 0x00000000, 0x00000000, 0x00000000}
196 },
197 { .name = "Echo Cancellation",
198 .nid = ECHO_CANCELLATION,
199 .mid = 0x95,
200 .reqs = {0, 1, 2, 3},
201 .direct = EFX_DIR_IN,
202 .params = 3,
203 .def_vals = {0x00000000, 0x3F3A9692, 0x00000000, 0x00000000}
204 },
205 { .name = "Voice Focus",
206 .nid = VOICE_FOCUS,
207 .mid = 0x95,
208 .reqs = {6, 7, 8, 9},
209 .direct = EFX_DIR_IN,
210 .params = 3,
211 .def_vals = {0x3F800000, 0x3D7DF3B6, 0x41F00000, 0x41F00000}
212 },
213 { .name = "Mic SVM",
214 .nid = MIC_SVM,
215 .mid = 0x95,
216 .reqs = {44, 45},
217 .direct = EFX_DIR_IN,
218 .params = 1,
219 .def_vals = {0x00000000, 0x3F3D70A4}
220 },
221 { .name = "Noise Reduction",
222 .nid = NOISE_REDUCTION,
223 .mid = 0x95,
224 .reqs = {4, 5},
225 .direct = EFX_DIR_IN,
226 .params = 1,
227 .def_vals = {0x3F800000, 0x3F000000}
228 },
229 { .name = "VoiceFX",
230 .nid = VOICEFX,
231 .mid = 0x95,
232 .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18},
233 .direct = EFX_DIR_IN,
234 .params = 8,
235 .def_vals = {0x00000000, 0x43C80000, 0x44AF0000, 0x44FA0000,
236 0x3F800000, 0x3F800000, 0x3F800000, 0x00000000,
237 0x00000000}
238 }
239};
240
241/* Tuning controls */
242#ifdef ENABLE_TUNING_CONTROLS
243
244enum {
245#define TUNING_CTL_START_NID 0xC0
246 WEDGE_ANGLE = TUNING_CTL_START_NID,
247 SVM_LEVEL,
248 EQUALIZER_BAND_0,
249 EQUALIZER_BAND_1,
250 EQUALIZER_BAND_2,
251 EQUALIZER_BAND_3,
252 EQUALIZER_BAND_4,
253 EQUALIZER_BAND_5,
254 EQUALIZER_BAND_6,
255 EQUALIZER_BAND_7,
256 EQUALIZER_BAND_8,
257 EQUALIZER_BAND_9,
258 TUNING_CTL_END_NID
259#define TUNING_CTLS_COUNT (TUNING_CTL_END_NID - TUNING_CTL_START_NID)
260};
261
262struct ct_tuning_ctl {
263 char name[44];
264 hda_nid_t parent_nid;
265 hda_nid_t nid;
266 int mid; /*effect module ID*/
267 int req; /*effect module request*/
268 int direct; /* 0:output; 1:input*/
269 unsigned int def_val;/*effect default values*/
270};
271
272static struct ct_tuning_ctl ca0132_tuning_ctls[] = {
273 { .name = "Wedge Angle",
274 .parent_nid = VOICE_FOCUS,
275 .nid = WEDGE_ANGLE,
276 .mid = 0x95,
277 .req = 8,
278 .direct = EFX_DIR_IN,
279 .def_val = 0x41F00000
280 },
281 { .name = "SVM Level",
282 .parent_nid = MIC_SVM,
283 .nid = SVM_LEVEL,
284 .mid = 0x95,
285 .req = 45,
286 .direct = EFX_DIR_IN,
287 .def_val = 0x3F3D70A4
288 },
289 { .name = "EQ Band0",
290 .parent_nid = EQUALIZER,
291 .nid = EQUALIZER_BAND_0,
292 .mid = 0x96,
293 .req = 11,
294 .direct = EFX_DIR_OUT,
295 .def_val = 0x00000000
296 },
297 { .name = "EQ Band1",
298 .parent_nid = EQUALIZER,
299 .nid = EQUALIZER_BAND_1,
300 .mid = 0x96,
301 .req = 12,
302 .direct = EFX_DIR_OUT,
303 .def_val = 0x00000000
304 },
305 { .name = "EQ Band2",
306 .parent_nid = EQUALIZER,
307 .nid = EQUALIZER_BAND_2,
308 .mid = 0x96,
309 .req = 13,
310 .direct = EFX_DIR_OUT,
311 .def_val = 0x00000000
312 },
313 { .name = "EQ Band3",
314 .parent_nid = EQUALIZER,
315 .nid = EQUALIZER_BAND_3,
316 .mid = 0x96,
317 .req = 14,
318 .direct = EFX_DIR_OUT,
319 .def_val = 0x00000000
320 },
321 { .name = "EQ Band4",
322 .parent_nid = EQUALIZER,
323 .nid = EQUALIZER_BAND_4,
324 .mid = 0x96,
325 .req = 15,
326 .direct = EFX_DIR_OUT,
327 .def_val = 0x00000000
328 },
329 { .name = "EQ Band5",
330 .parent_nid = EQUALIZER,
331 .nid = EQUALIZER_BAND_5,
332 .mid = 0x96,
333 .req = 16,
334 .direct = EFX_DIR_OUT,
335 .def_val = 0x00000000
336 },
337 { .name = "EQ Band6",
338 .parent_nid = EQUALIZER,
339 .nid = EQUALIZER_BAND_6,
340 .mid = 0x96,
341 .req = 17,
342 .direct = EFX_DIR_OUT,
343 .def_val = 0x00000000
344 },
345 { .name = "EQ Band7",
346 .parent_nid = EQUALIZER,
347 .nid = EQUALIZER_BAND_7,
348 .mid = 0x96,
349 .req = 18,
350 .direct = EFX_DIR_OUT,
351 .def_val = 0x00000000
352 },
353 { .name = "EQ Band8",
354 .parent_nid = EQUALIZER,
355 .nid = EQUALIZER_BAND_8,
356 .mid = 0x96,
357 .req = 19,
358 .direct = EFX_DIR_OUT,
359 .def_val = 0x00000000
360 },
361 { .name = "EQ Band9",
362 .parent_nid = EQUALIZER,
363 .nid = EQUALIZER_BAND_9,
364 .mid = 0x96,
365 .req = 20,
366 .direct = EFX_DIR_OUT,
367 .def_val = 0x00000000
368 }
369};
370#endif
371
372/* Voice FX Presets */
373#define VOICEFX_MAX_PARAM_COUNT 9
374
375struct ct_voicefx {
376 char *name;
377 hda_nid_t nid;
378 int mid;
379 int reqs[VOICEFX_MAX_PARAM_COUNT]; /*effect module request*/
380};
381
382struct ct_voicefx_preset {
383 char *name; /*preset name*/
384 unsigned int vals[VOICEFX_MAX_PARAM_COUNT];
385};
386
387struct ct_voicefx ca0132_voicefx = {
388 .name = "VoiceFX Capture Switch",
389 .nid = VOICEFX,
390 .mid = 0x95,
391 .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18}
392};
393
394struct ct_voicefx_preset ca0132_voicefx_presets[] = {
395 { .name = "Neutral",
396 .vals = { 0x00000000, 0x43C80000, 0x44AF0000,
397 0x44FA0000, 0x3F800000, 0x3F800000,
398 0x3F800000, 0x00000000, 0x00000000 }
399 },
400 { .name = "Female2Male",
401 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
402 0x44FA0000, 0x3F19999A, 0x3F866666,
403 0x3F800000, 0x00000000, 0x00000000 }
404 },
405 { .name = "Male2Female",
406 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
407 0x450AC000, 0x4017AE14, 0x3F6B851F,
408 0x3F800000, 0x00000000, 0x00000000 }
409 },
410 { .name = "ScrappyKid",
411 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
412 0x44FA0000, 0x40400000, 0x3F28F5C3,
413 0x3F800000, 0x00000000, 0x00000000 }
414 },
415 { .name = "Elderly",
416 .vals = { 0x3F800000, 0x44324000, 0x44BB8000,
417 0x44E10000, 0x3FB33333, 0x3FB9999A,
418 0x3F800000, 0x3E3A2E43, 0x00000000 }
419 },
420 { .name = "Orc",
421 .vals = { 0x3F800000, 0x43EA0000, 0x44A52000,
422 0x45098000, 0x3F266666, 0x3FC00000,
423 0x3F800000, 0x00000000, 0x00000000 }
424 },
425 { .name = "Elf",
426 .vals = { 0x3F800000, 0x43C70000, 0x44AE6000,
427 0x45193000, 0x3F8E147B, 0x3F75C28F,
428 0x3F800000, 0x00000000, 0x00000000 }
429 },
430 { .name = "Dwarf",
431 .vals = { 0x3F800000, 0x43930000, 0x44BEE000,
432 0x45007000, 0x3F451EB8, 0x3F7851EC,
433 0x3F800000, 0x00000000, 0x00000000 }
434 },
435 { .name = "AlienBrute",
436 .vals = { 0x3F800000, 0x43BFC5AC, 0x44B28FDF,
437 0x451F6000, 0x3F266666, 0x3FA7D945,
438 0x3F800000, 0x3CF5C28F, 0x00000000 }
439 },
440 { .name = "Robot",
441 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
442 0x44FA0000, 0x3FB2718B, 0x3F800000,
443 0xBC07010E, 0x00000000, 0x00000000 }
444 },
445 { .name = "Marine",
446 .vals = { 0x3F800000, 0x43C20000, 0x44906000,
447 0x44E70000, 0x3F4CCCCD, 0x3F8A3D71,
448 0x3F0A3D71, 0x00000000, 0x00000000 }
449 },
450 { .name = "Emo",
451 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
452 0x44FA0000, 0x3F800000, 0x3F800000,
453 0x3E4CCCCD, 0x00000000, 0x00000000 }
454 },
455 { .name = "DeepVoice",
456 .vals = { 0x3F800000, 0x43A9C5AC, 0x44AA4FDF,
457 0x44FFC000, 0x3EDBB56F, 0x3F99C4CA,
458 0x3F800000, 0x00000000, 0x00000000 }
459 },
460 { .name = "Munchkin",
461 .vals = { 0x3F800000, 0x43C80000, 0x44AF0000,
462 0x44FA0000, 0x3F800000, 0x3F1A043C,
463 0x3F800000, 0x00000000, 0x00000000 }
464 }
465};
466
66enum hda_cmd_vendor_io { 467enum hda_cmd_vendor_io {
67 /* for DspIO node */ 468 /* for DspIO node */
68 VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000, 469 VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000,
@@ -184,8 +585,16 @@ enum control_flag_id {
184 * Control parameter IDs 585 * Control parameter IDs
185 */ 586 */
186enum control_param_id { 587enum control_param_id {
588 /* 0: None, 1: Mic1In*/
589 CONTROL_PARAM_VIP_SOURCE = 1,
187 /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */ 590 /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */
188 CONTROL_PARAM_SPDIF1_SOURCE = 2, 591 CONTROL_PARAM_SPDIF1_SOURCE = 2,
592 /* Port A output stage gain setting to use when 16 Ohm output
593 * impedance is selected*/
594 CONTROL_PARAM_PORTA_160OHM_GAIN = 8,
595 /* Port D output stage gain setting to use when 16 Ohm output
596 * impedance is selected*/
597 CONTROL_PARAM_PORTD_160OHM_GAIN = 10,
189 598
190 /* Stream Control */ 599 /* Stream Control */
191 600
@@ -304,8 +713,6 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
304 AMP_IN_UNMUTE(0)); 713 AMP_IN_UNMUTE(0));
305} 714}
306 715
307static char *dirstr[2] = { "Playback", "Capture" };
308
309static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, 716static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
310 int chan, int dir) 717 int chan, int dir)
311{ 718{
@@ -2190,6 +2597,38 @@ static bool dspload_wait_loaded(struct hda_codec *codec)
2190 return false; 2597 return false;
2191} 2598}
2192 2599
2600
2601/*
2602 * Mixer controls helpers.
2603 */
2604#define CA0132_CODEC_VOL_MONO(xname, nid, channel, dir) \
2605 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2606 .name = xname, \
2607 .subdevice = HDA_SUBDEV_AMP_FLAG, \
2608 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2609 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2610 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
2611 .info = ca0132_volume_info, \
2612 .get = ca0132_volume_get, \
2613 .put = ca0132_volume_put, \
2614 .tlv = { .c = ca0132_volume_tlv }, \
2615 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
2616
2617#define CA0132_CODEC_MUTE_MONO(xname, nid, channel, dir) \
2618 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2619 .name = xname, \
2620 .subdevice = HDA_SUBDEV_AMP_FLAG, \
2621 .info = snd_hda_mixer_amp_switch_info, \
2622 .get = ca0132_switch_get, \
2623 .put = ca0132_switch_put, \
2624 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
2625
2626/* stereo */
2627#define CA0132_CODEC_VOL(xname, nid, dir) \
2628 CA0132_CODEC_VOL_MONO(xname, nid, 3, dir)
2629#define CA0132_CODEC_MUTE(xname, nid, dir) \
2630 CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir)
2631
2193/* 2632/*
2194 * PCM callbacks 2633 * PCM callbacks
2195 */ 2634 */