static int sgtl5000_set_property(const struct device *dev, audio_property_t property,
audio_channel_t channel, audio_property_value_t val)
{
int ret = -1;
uint16_t reg_val;
uint16_t i2s_pwr = SGTL5000_I2S_IN_POWERUP;
switch (property) {
case AUDIO_PROPERTY_OUTPUT_VOLUME:
/* Linear volume (0-100%) to SGTL5000 hw steps */
/* 0x3C (0dB, max) to 0xF0 (-90dB, min) */
if (val.vol == 0) {
reg_val = (0xFC << 8) | 0xFC; /* Mute DAC channels */
} else {
uint8_t steps = (uint8_t)(0x3C + ((100 - val.vol) * (0xF0 - 0x3C)) / 100);
reg_val = (steps << 8) | steps;
}
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_DAC_VOL, reg_val);
break; /* FIX: Added missing break to prevent fall-through */
case AUDIO_PROPERTY_OUTPUT_MUTE:
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, SGTL5000_HP_MUTE, val.mute ? SGTL5000_HP_MUTE : 0);
if (ret < 0) {
break;
}
/*
* During 'digital mute' do not mute DAC
* because LINE_IN would be muted aswell. We want to mute
* only I2S block - this can be done by powering it off
*/
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_DIG_POWER, i2s_pwr, val.mute ? 0 : i2s_pwr);
break; /* FIX: Added missing break to prevent fall-through */
case AUDIO_PROPERTY_INPUT_VOLUME:
/* Linear input volume (0-100%) mapped to SGTL5000 Line-In Analog Gain */
/* CHIP_ANA_GAIN bits [5:4] for Right, bits [1:0] for Left channel */
/* 0x0 (0dB) to 0x3 (+22.5dB) in 1.5dB steps */
{
uint8_t gain_steps = (uint8_t)((val.vol * 3) / 100);
reg_val = (gain_steps << 4) | gain_steps;
/* Update only LIN_GAIN bits, preserve the rest of the register */
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_GAIN, 0x0033, reg_val);
}
break;
case AUDIO_PROPERTY_INPUT_MUTE:
/* Mute Line-In / ADC path via CHIP_ANA_CTRL register */
/* Bit 0 (MUTE_LO) or Bit 1 (MUTE_REFTOP) depends on capture routing, */
/* standard approach is to use MUTE_ADC (Bit 0) in CHIP_ANA_CTRL */
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, SGTL5000_ADC_MUTE,
val.mute ? SGTL5000_ADC_MUTE : 0);
if (ret < 0) {
break;
}
/* Additionally gate I2S OUT digital block power for a clean mute */
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_DIG_POWER,
SGTL5000_I2S_OUT_POWERUP,
val.mute ? 0 : SGTL5000_I2S_OUT_POWERUP);
break;
default:
break;
}
return ret;
}