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


static int sgtl5000_set_property(const struct device *dev, audio_property_t property,
			       audio_channel_t channel, audio_property_value_t val)
{
	uint16_t reg_val;

	switch (property) {
	case AUDIO_PROPERTY_OUTPUT_VOLUME:
		/* Линейно мапим шкалу Zephyr (0-100%) в аппаратные шаги SGTL5000 */
		/* Аппаратная шкала: 0x3C (0dB, Максимум) вниз до 0xF0 (-90dB, Минимум) */
		if (val.vol == 0) {
			reg_val = (0xFC << 8) | 0xFC; /* Значение полного приглушения (Mute) */
		} else {
			uint8_t steps = (uint8_t)(0x3C + ((100 - val.vol) * (0xF0 - 0x3C)) / 100);
			reg_val = (steps << 8) | steps;
		}
		return sgtl5000_write_reg(dev, SGTL5000_CHIP_DAC_VOL, reg_val);

	case AUDIO_PROPERTY_OUTPUT_MUTE:
		return sgtl5000_update_reg(dev, SGTL5000_CHIP_ANA_CTRL, SGTL5000_HP_MUTE, 
					   val.mute ? SGTL5000_HP_MUTE : 0);

	default:
		break;
	}

	return -ENOTSUP;
}

static void sgtl5000_start_output(const struct device *dev) {}
static void sgtl5000_stop_output(const struct device *dev) {}

/* Базовая аппаратная последовательность включения (перенесена из Probe-рутины Linux) */
static int sgtl5000_init(const struct device *dev)
{
	const struct sgtl5000_driver_config *const dev_cfg = dev->config;
	uint16_t chip_id = 0;

	if (!device_is_ready(dev_cfg->i2c.bus)) {
		LOG_ERR("I2C Control Bus not ready");
		return -ENODEV;
	}

	/* Чтение и верификация сигнатуры чипа (Chip ID) */
	if (sgtl5000_read_reg(dev, SGTL5000_CHIP_ID, &chip_id) != 0) {
		return -EIO;
	}

	if ((chip_id >> 8) != 0xA0) {
		LOG_ERR("Device signature mismatch! Read ID: 0x%04X", chip_id);
		return -ENODEV;
	}

	/* Конфигурация питания: предполагаем стандартные 3.3V на входах */
	sgtl5000_write_reg(dev, SGTL5000_CHIP_ANA_POWER, 
			   SGTL5000_DAC_STEREO | SGTL5000_ADC_STEREO | SGTL5000_REFTOP_POWERUP);
	
	/* Конфигурация встроенного LDO регулятора для питания цифровой части VDDD */
	sgtl5000_write_reg(dev, SGTL5000_CHIP_LINREG_CTRL, 0x0008); 
	
	/* Настройка опорного напряжения виртуальной земли VAG -> VDDA/2 (~1.65V) */
	sgtl5000_write_reg(dev, SGTL5000_CHIP_REF_CTRL, 0x01FF); 
	sgtl5000_write_reg(dev, SGTL5000_CHIP_SHORT_CTRL, 0x0000); /* Отключаем детектор короткого замыкания */
	sgtl5000_write_reg(dev, SGTL5000_CHIP_DIG_POWER, SGTL5000_ADC_EN | SGTL5000_DAC_EN);
	
	/* Настройки плавного нарастания громкости (Ramp) по умолчанию */
	sgtl5000_write_reg(dev, SGTL5000_CHIP_ADCDAC_CTRL, 0x000C);
	sgtl5000_write_reg(dev, SGTL5000_CHIP_PAD_STRENGTH, 0x015F);
	sgtl5000_write_reg(dev, SGTL5000_DAP_AUDIO_EQ, 0x0001); /* Включаем режим DAP GEQ */

	LOG_INF("NXP SGTL5000 Codec initialized successfully. ID: 0x%02X Revision: 0x%02X", 
		(chip_id >> 8), (chip_id & 0xFF));
	return 0;
}

static const struct audio_codec_api sgtl5000_driver_api = {
	.configure = sgtl5000_configure,
	.start_output = sgtl5000_start_output,
	.stop_output = sgtl5000_stop_output,
	.set_property = sgtl5000_set_property,
};

#define SGTL5000_INIT(n)                                                                           \
	static const struct sgtl5000_driver_config sgtl5000_device_config_##n = {                  \
		.i2c = I2C_DT_SPEC_INST_GET(n),                                                    \
	};                                                                                         \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(n, sgtl5000_init, NULL, NULL, &sgtl5000_device_config_##n,           \
			      POST_KERNEL, CONFIG_AUDIO_CODEC_INIT_PRIORITY, &sgtl5000_driver_api);

DT_INST_FOREACH_STATUS_OKAY(SGTL5000_INIT)