static int sgtl5000_configure(const struct device *dev, struct audio_codec_cfg *cfg)
{
int ret;
bool is_master = (cfg->dai_cfg.i2s.options & I2S_OPT_FRAME_CLK_MASTER);
if (cfg->dai_type >= AUDIO_DAI_TYPE_INVALID) {
return -EINVAL;
}
/* --------------------------------------------------------------------- */
/* MONOLITHIC HARD OVERWRITE FOR I2S BUS SELECTION (REG 0x0006) */
/* --------------------------------------------------------------------- */
uint16_t i2s_ctl = 0;
/* 1. Map data bit-widths and clock frequency speed properties */
switch (cfg->dai_cfg.i2s.word_size) {
case 16:
i2s_ctl |= (0x03 << 4); /* Set DLEN bits 4-5 to 11 (16-bit size) */
i2s_ctl |= (0x01 << 8); /* Set SCLKFREQ bit 8 to 1 (32*FS speed) */
break;
case 20:
i2s_ctl |= (0x02 << 4); /* 20-bit size */
i2s_ctl |= (0x00 << 8); /* 64*FS speed */
break;
case 24:
i2s_ctl |= (0x01 << 4); /* 24-bit size */
i2s_ctl |= (0x00 << 8); /* 64*FS speed */
break;
case 32:
i2s_ctl |= (0x00 << 4); /* 32-bit size */
i2s_ctl |= (0x00 << 8); /* 64*FS speed */
break;
default:
LOG_ERR("SGTL5000: Word size %d not supported", cfg->dai_cfg.i2s.word_size);
return -EINVAL;
}
/* 2. Configure Master/Slave hardware operating modes */
if (is_master) {
i2s_ctl |= 0x0080; /* Set Master bit 7 to 1 */
}
/* 3. Configure Alignment Formats matching Zephyr properties */
switch (cfg->dai_type) {
case AUDIO_DAI_TYPE_I2S:
/* Standard I2S mode: format bits 2-3 = 00 */
break;
case AUDIO_DAI_TYPE_LEFT_JUSTIFIED:
/* Left Justified mode: bits 2-3 = 01, plus LRALIGN bit (0x0004) */
i2s_ctl |= (0x01 << 2) | 0x0004;
break;
case AUDIO_DAI_TYPE_RIGHT_JUSTIFIED:
/* Right Justified mode: bits 2-3 = 10, plus LRPOL bit (0x0002) */
i2s_ctl |= (0x02 << 2) | 0x0002;
break;
default:
return -EINVAL;
}
/* 4. Force a clean write_reg over 0x0006 to kill any ongoing mask corruption */
ret = sgtl5000_write_reg(dev, SGTL5000_CHIP_I2S_CTRL, i2s_ctl);
if (ret != 0) return ret;
LOG_INF("SGTL5000: Monolithic write to CHIP_I2S_CTRL (0x0006) complete. Val: 0x%04X", i2s_ctl);
/* --------------------------------------------------------------------- */
/* CLOCK CONTROLLER INTEGRATION */
/* --------------------------------------------------------------------- */
ret = sgtl5000_set_clock(dev, cfg->mclk_freq, cfg->dai_cfg.i2s.frame_clk_freq, is_master);
if (ret != 0) return ret;
/* !!! CRITICAL ACTION: REMOVE THE OLD FUNCTION CALL INTERFACE !!! */
/* ret = sgtl5000_protocol_config(dev, cfg->dai_type, is_master); */
/* --------------------------------------------------------------------- */
/* ROUTING PATHWAYS CONFIGURATION */
/* --------------------------------------------------------------------- */
switch (cfg->dai_route) {
case AUDIO_ROUTE_PLAYBACK:
sgtl5000_set_power(dev, true, false, true, false);
sgtl5000_set_route_state(dev, AUDIO_ROUTE_PLAYBACK);
break;
case AUDIO_ROUTE_CAPTURE:
sgtl5000_set_power(dev, false, true, false, false);
sgtl5000_set_route_state(dev, AUDIO_ROUTE_CAPTURE);
break;
case AUDIO_ROUTE_PLAYBACK_CAPTURE:
sgtl5000_set_power(dev, true, true, true, true);
sgtl5000_set_route_state(dev, AUDIO_ROUTE_PLAYBACK_CAPTURE);
break;
default:
sgtl5000_set_power(dev, false, false, false, false);
sgtl5000_set_route_state(dev, AUDIO_ROUTE_BYPASS);
break;
}
return 0;
}