/**
* @brief Universal Power Management Function for SGTL5000 Analog Blocks.
*
* Configures the CHIP_ANA_POWER register (0x0030) based on target block requests.
* Automatically preserves the REFTOP reference voltage generators.
*/
static int sgtl5000_set_power(const struct device *dev, bool dac_on, bool adc_on, bool hp_on, bool lineout_on)
{
uint16_t pwr_val = SGTL5000_REFTOP_POWERUP; /* Always keep main voltage reference on */
if (dac_on) pwr_val |= SGTL5000_DAC_POWERUP | SGTL5000_DAC_STEREO;
if (adc_on) pwr_val |= SGTL5000_ADC_POWERUP | SGTL5000_ADC_STEREO;
if (hp_on) pwr_val |= SGTL5000_HP_POWERUP | SGTL5000_VAG_POWERUP;
if (lineout_on) pwr_val |= SGTL5000_LINE_OUT_POWERUP | SGTL5000_VAG_POWERUP;
/* 0x4000 is a standard internal charge pump bias requirement bit mask */
pwr_val |= 0x4000;
LOG_INF("Updating SGTL5000 Analog Power Register to: 0x%04X", pwr_val);
return sgtl5000_write_reg(dev, SGTL5000_CHIP_ANA_POWER, pwr_val);
}
/**
* @brief Centralized Audio Path Control Layer (Un-muting and Routing matrix).
*/
static int sgtl5000_set_route_state(const struct device *dev, audio_route_t route)
{
int ret;
switch (route) {
case AUDIO_ROUTE_PLAYBACK:
/* 1. Source Selection System (SSS): Direct I2S Input stream data into the DAC block */
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_SSS_CTRL, 0x0010);
if (ret != 0) return ret;
/* 2. Headphone Output Mux: Route DAC analog signals directly to the HP output stage */
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, SGTL5000_HP_SEL_MASK, 0);
if (ret != 0) return ret;
/* 3. Disable active mutes to open the gates (Clear HP_MUTE and LINEOUT_MUTE) */
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_ANA_CTRL, 0x0000);
if (ret != 0) return ret;
/* 4. Disable dynamic digital mutes inside the DAC execution engine */
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_ADCDAC_CTRL, 0x000C);
if (ret != 0) return ret;
break;
case AUDIO_ROUTE_CAPTURE:
/* 1. SSS: Connect ADC block data to I2S Output pins */
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_SSS_CTRL, 0x0002);
if (ret != 0) return ret;
/* 2. Capture Input Mux: Select LINE_IN hardware pins as the ADC target source */
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, 0x0004, 0x0004);
if (ret != 0) return ret;
/* 3. Open capture stage analog gates (Clear ADC mute switches) */
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, 0x0001, 0);
if (ret != 0) return ret;
break;
case AUDIO_ROUTE_PLAYBACK_CAPTURE:
/* Simultaneous configurations handling both matrix lines */
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_SSS_CTRL, 0x0012); /* I2S->DAC and ADC->I2S */
if (ret != 0) return ret;
ret = sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, SGTL5000_HP_SEL_MASK | 0x0004, 0x0004);
if (ret != 0) return ret;
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_ANA_CTRL, 0x0000);
if (ret != 0) return ret;
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_ADCDAC_CTRL, 0x000C);
if (ret != 0) return ret;
break;
default:
/* System safety trigger: full analog mute to prevent pop/click noise loops */
sgtl5000_write_reg(dev, SGTL5000_CHIP_ANA_CTRL, 0x0111);
break;
}
/* Force maximum initial safe volume calibrations */
sgtl5000_write_reg(dev, SGTL5000_CHIP_DAC_VOL, 0x3C3C); /* 0 dB */
sgtl5000_write_reg(dev, SGTL5000_CHIP_ANA_HP_CTRL, 0x1818); /* 0 dB */
return 0;
}