On Tuesday 15 June 2010 16:53:23 ext Mark Brown wrote: > On Tue, Jun 15, 2010 at 04:42:32PM +0300, Peter Ujfalusi wrote: > > On Tuesday 15 June 2010 08:11:10 ext Stuart Longland wrote: > > > Okay, I've had a close inspection of how the SOC_DOUBLE_R_SX_TLV > > > widgets are implemented. I couldn't find where in the git trees the > > > control had been added, I wound up applying this patch myself in my > > > tree... it apparently got applied in the official trees, but I cannot > > > find it. > > > > I'm not really sure what the SOC_DOUBLE_R_SX_TLV is for... > > It's for value ranges which have normal unsigned integer mapping but > where the zero point is not at the lowest value so you need to wrap > around. Which isn't actually what Stuart is looking for... I found the CS42L51 datasheet, and now it is clear what the _SX is doing. > > But would a simple SOC_DOUBLE_R_TLV enough for the aic3204 codec? > > I have not looked at the datasheet (if it is available), but I'll try to > > find it. > > Well looking at the _2r_sx functions in soc-core.c does not really clears > > the intention, but at least I can see several things in the > > snd_soc_put_volsw_2r_sx > > ...and this won't work since Stuart is looking for something that does > signed values which I don't think we have already, the standard stuff > all wants unsigned quantities. Yeah, the aic3204 needs signed values. There is this _s8 things, which does signed, but never used, nor really checked it. > > - instead of updating the bits, it rewrites the register, which I think > > will erase bits, which it should not touch. > > It's just open coding the update bits so there's no actual problem here. It might be so that I have overlooked something, but... If the register has: bit # Function 0 .. 6 : Gain 7 : Mute Let say that the mute is set to one, and the user modifies the gain, than in the function: int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int mask = (1<<mc->shift)-1; /* * mc->shift is 7, whiche means seven bits for the gain bit array * mask == 0x7f (b0111 1111): it only covers the gain area */ int min = mc->min; int ret; unsigned int val, valr, oval, ovalr; val = ((ucontrol->value.integer.value[0]+min) & 0xff); val &= mask; valr = ((ucontrol->value.integer.value[1]+min) & 0xff); valr &= mask; /* * Here we make sure that the coming new value has only bits set withing the * gain area, so we have b0xxx xxxx for the val, and valr */ oval = snd_soc_read(codec, mc->reg) & mask; ovalr = snd_soc_read(codec, mc->rreg) & mask; /* * We read the content of the register, and taking only the bits, which is * within the gain area: b0xxx xxxx */ ret = 0; if (oval != val) { /* Only update, if the gain in the chip is different than the new one */ ret = snd_soc_write(codec, mc->reg, val); /* * Write the val to the chip. * Now, if the mute was set before it is going to be cleared, since the code has * masked it out, the val only contains the updated bits for the gain part, the * rest is 0. * So if the user changes the volume, the mute bit is going to be erased. */ if (ret < 0) return 0; ret = 1; } if (ovalr != valr) { ret = snd_soc_write(codec, mc->rreg, valr); if (ret < 0) return 0; ret = 1; } return 0; } Have I missed something? -- Péter _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel