mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
ALSA: hda/ca0132 - Add speaker tuning initialization commands.
Add speaker tuning initialization DSP commands, and also define previously unknown DSP command values. Signed-off-by: Connor McAdams <conmanx360@gmail.com> Link: https://lore.kernel.org/r/20200825201040.30339-3-conmanx360@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
bf2aa9ccc8
commit
896e361e82
@ -589,6 +589,60 @@ static const struct ct_eq_preset ca0132_alt_eq_presets[] = {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions for the DSP req's to handle speaker tuning. These all belong to
|
||||
* module ID 0x96, the output effects module.
|
||||
*/
|
||||
enum speaker_tuning_reqs {
|
||||
/*
|
||||
* Currently, this value is always set to 0.0f. However, on Windows,
|
||||
* when selecting certain headphone profiles on the new Sound Blaster
|
||||
* connect software, the QUERY_SPEAKER_EQ_ADDRESS req on mid 0x80 is
|
||||
* sent. This gets the speaker EQ address area, which is then used to
|
||||
* send over (presumably) an equalizer profile for the specific
|
||||
* headphone setup. It is sent using the same method the DSP
|
||||
* firmware is uploaded with, which I believe is why the 'ctspeq.bin'
|
||||
* file exists in linux firmware tree but goes unused. It would also
|
||||
* explain why the QUERY_SPEAKER_EQ_ADDRESS req is defined but unused.
|
||||
* Once this profile is sent over, SPEAKER_TUNING_USE_SPEAKER_EQ is
|
||||
* set to 1.0f.
|
||||
*/
|
||||
SPEAKER_TUNING_USE_SPEAKER_EQ = 0x1f,
|
||||
SPEAKER_TUNING_ENABLE_CENTER_EQ = 0x20,
|
||||
SPEAKER_TUNING_FRONT_LEFT_VOL_LEVEL = 0x21,
|
||||
SPEAKER_TUNING_FRONT_RIGHT_VOL_LEVEL = 0x22,
|
||||
SPEAKER_TUNING_CENTER_VOL_LEVEL = 0x23,
|
||||
SPEAKER_TUNING_LFE_VOL_LEVEL = 0x24,
|
||||
SPEAKER_TUNING_REAR_LEFT_VOL_LEVEL = 0x25,
|
||||
SPEAKER_TUNING_REAR_RIGHT_VOL_LEVEL = 0x26,
|
||||
SPEAKER_TUNING_SURROUND_LEFT_VOL_LEVEL = 0x27,
|
||||
SPEAKER_TUNING_SURROUND_RIGHT_VOL_LEVEL = 0x28,
|
||||
/*
|
||||
* Inversion is used when setting headphone virtualization to line
|
||||
* out. Not sure why this is, but it's the only place it's ever used.
|
||||
*/
|
||||
SPEAKER_TUNING_FRONT_LEFT_INVERT = 0x29,
|
||||
SPEAKER_TUNING_FRONT_RIGHT_INVERT = 0x2a,
|
||||
SPEAKER_TUNING_CENTER_INVERT = 0x2b,
|
||||
SPEAKER_TUNING_LFE_INVERT = 0x2c,
|
||||
SPEAKER_TUNING_REAR_LEFT_INVERT = 0x2d,
|
||||
SPEAKER_TUNING_REAR_RIGHT_INVERT = 0x2e,
|
||||
SPEAKER_TUNING_SURROUND_LEFT_INVERT = 0x2f,
|
||||
SPEAKER_TUNING_SURROUND_RIGHT_INVERT = 0x30,
|
||||
/* Delay is used when setting surround speaker distance in Windows. */
|
||||
SPEAKER_TUNING_FRONT_LEFT_DELAY = 0x31,
|
||||
SPEAKER_TUNING_FRONT_RIGHT_DELAY = 0x32,
|
||||
SPEAKER_TUNING_CENTER_DELAY = 0x33,
|
||||
SPEAKER_TUNING_LFE_DELAY = 0x34,
|
||||
SPEAKER_TUNING_REAR_LEFT_DELAY = 0x35,
|
||||
SPEAKER_TUNING_REAR_RIGHT_DELAY = 0x36,
|
||||
SPEAKER_TUNING_SURROUND_LEFT_DELAY = 0x37,
|
||||
SPEAKER_TUNING_SURROUND_RIGHT_DELAY = 0x38,
|
||||
/* Of these two, only mute seems to ever be used. */
|
||||
SPEAKER_TUNING_MAIN_VOLUME = 0x39,
|
||||
SPEAKER_TUNING_MUTE = 0x3a,
|
||||
};
|
||||
|
||||
/* DSP command sequences for ca0132_alt_select_out */
|
||||
#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
|
||||
struct ca0132_alt_out_set {
|
||||
@ -6874,6 +6928,67 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Default speaker tuning values setup for alternative codecs.
|
||||
*/
|
||||
static const unsigned int sbz_default_delay_values[] = {
|
||||
/* Non-zero values are floating point 0.000198. */
|
||||
0x394f9e38, 0x394f9e38, 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
|
||||
static const unsigned int zxr_default_delay_values[] = {
|
||||
/* Non-zero values are floating point 0.000220. */
|
||||
0x00000000, 0x00000000, 0x3966afcd, 0x3966afcd, 0x3966afcd, 0x3966afcd
|
||||
};
|
||||
|
||||
static const unsigned int ae5_default_delay_values[] = {
|
||||
/* Non-zero values are floating point 0.000100. */
|
||||
0x00000000, 0x00000000, 0x38d1b717, 0x38d1b717, 0x38d1b717, 0x38d1b717
|
||||
};
|
||||
|
||||
/*
|
||||
* If we never change these, probably only need them on initialization.
|
||||
*/
|
||||
static void ca0132_alt_init_speaker_tuning(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
unsigned int i, tmp, start_req, end_req;
|
||||
const unsigned int *values;
|
||||
|
||||
switch (ca0132_quirk(spec)) {
|
||||
case QUIRK_SBZ:
|
||||
values = sbz_default_delay_values;
|
||||
break;
|
||||
case QUIRK_ZXR:
|
||||
values = zxr_default_delay_values;
|
||||
break;
|
||||
case QUIRK_AE5:
|
||||
values = ae5_default_delay_values;
|
||||
break;
|
||||
default:
|
||||
values = sbz_default_delay_values;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = FLOAT_ZERO;
|
||||
dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_ENABLE_CENTER_EQ, tmp);
|
||||
|
||||
start_req = SPEAKER_TUNING_FRONT_LEFT_VOL_LEVEL;
|
||||
end_req = SPEAKER_TUNING_REAR_RIGHT_VOL_LEVEL;
|
||||
for (i = start_req; i < end_req + 1; i++)
|
||||
dspio_set_uint_param(codec, 0x96, i, tmp);
|
||||
|
||||
start_req = SPEAKER_TUNING_FRONT_LEFT_INVERT;
|
||||
end_req = SPEAKER_TUNING_REAR_RIGHT_INVERT;
|
||||
for (i = start_req; i < end_req + 1; i++)
|
||||
dspio_set_uint_param(codec, 0x96, i, tmp);
|
||||
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
dspio_set_uint_param(codec, 0x96,
|
||||
SPEAKER_TUNING_FRONT_LEFT_DELAY + i, values[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a dummy stream to bind the output to. This seems to have to be done
|
||||
* after changing the main outputs source and destination streams.
|
||||
@ -7373,6 +7488,8 @@ static void sbz_setup_defaults(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
ca0132_alt_init_speaker_tuning(codec);
|
||||
|
||||
ca0132_alt_create_dummy_stream(codec);
|
||||
}
|
||||
|
||||
@ -7440,6 +7557,8 @@ static void ae5_setup_defaults(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
ca0132_alt_init_speaker_tuning(codec);
|
||||
|
||||
ca0132_alt_create_dummy_stream(codec);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user