mirror of
https://github.com/torvalds/linux.git
synced 2024-10-26 15:02:39 +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 */
|
/* DSP command sequences for ca0132_alt_select_out */
|
||||||
#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
|
#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
|
||||||
struct ca0132_alt_out_set {
|
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
|
* 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.
|
* 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);
|
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);
|
ca0132_alt_create_dummy_stream(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user