Загрузка данных


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;
}