At Fri, 03 Jul 2009 21:05:37 +0100, Daniel Drake wrote:
Hi,
On Mon, 2009-06-29 at 14:48 +0200, Takashi Iwai wrote:
At Mon, 29 Jun 2009 13:26:26 +0100, Mark Brown wrote:
On Mon, Jun 29, 2009 at 01:10:53PM +0100, Daniel Drake wrote:
- Volume range is ridiculous, you can go all the way down to -74dB
gain. Beyond -42dB you can barely hear anything from the speakers, and I note that all my other systems only go down as far as -46.5dB.
This is normally just a case of drivers exposing whatever control they get from the hardware. Devices will often expose very high degrees of attenuation since they're doing it anyway in order to implement the mute functionality.
Yep. There are some workaround for each codec chip. See create_controls_idx() in patch_sigmatel.c, for example.
Great. Do you have any other examples? This does not seem so easy for a non-virtual master.
This is my kcontrol for master: HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
Well, currently only patch_sigmatel.c uses the workaround. But, it's relatively easy. Define the element like
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, .info = snd_hda_mixer_amp_volume_info, .get = snd_hda_mixer_amp_volume_get, .put = snd_hda_mixer_amp_volume_put, .tlv = { .c = snd_hda_mixer_amp_tlv }, .private_value = HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 0x30), }
This is almost a plain expansion of HDA_CODE_VOLUME() macro except for the private_value field. It uses HDA_COMPOSE_AMP_VAL_OFS() instead. The last argument (0x30) is the offset of the volume steps. That is, if the volume has 127 steps (0x7f) and you want to set the lower limit to 0x30. Then pass 0x30 there.
The upper limit of the volume steps can be changed by snd_hda_override_amp_caps(), BTW.
Takashi