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


static int lt9611_hdmi_hw_params(struct device *dev, void *data, 
				 struct hdmi_codec_daifmt *fmt,
				 struct hdmi_codec_params *hparms)
{
	struct lt9611 *lt9611 = data;
	unsigned int rate;
	unsigned int len;
	unsigned int val;
	
	/* Базовая структура последовательности регистров (страница 0x84) */
	struct reg_sequence seq[] = {
		{ 0x8406, 0x08 }, // [0] Для I2S: 0x08, для SPDIF: 0x0c
		{ 0x8407, 0x10 }, // [1]
		{ 0x840f, 0x2b }, // [2] Частота сэмплирования
		{ 0x8434, 0xd4 }, // [3] CTS_N
		{ 0x8435, 0x00 }, // [4] N val (High)
		{ 0x8436, 0x18 }, // [5] N val (Mid)
		{ 0x8437, 0x00 }, // [6] N val (Low)
	};

	/* 1. Определяем тип аудиоинтерфейса и пишем в регистр страницы 0x82 */
	switch (fmt->fmt) {
	case HDMI_CODEC_I2S:
		dev_dbg(dev, "LT9611: Configuring Audio Input as I2S\n");
		regmap_write(lt9611->regmap, 0x82d7, 0x04); // Режим I2S 2ch
		seq[0].def = 0x08;                          // Соответствует китайскому 0x06 -> 0x08
		break;
		
	case HDMI_CODEC_SPDIF:
		dev_dbg(dev, "LT9611: Configuring Audio Input as SPDIF\n");
		regmap_write(lt9611->regmap, 0x82d7, 0x80); // Режим SPDIF
		seq[0].def = 0x0c;                          // Соответствует китайскому 0x06 -> 0x0c
		break;
		
	default:
		dev_err(dev, "LT9611: Unsupported audio format %d\n", fmt->fmt);
		return -EINVAL;
	}

	/* 2. Настройка частоты дискретизации (Sample Rate) */
	switch (hparms->sample_rate) {
	case 32000:   rate = LT9611_SAMPLE_FREQ_32000;   break;
	case 44100:   rate = LT9611_SAMPLE_FREQ_44100;   break;
	case 48000:   rate = LT9611_SAMPLE_FREQ_48000;   break;
	case 88200:   rate = LT9611_SAMPLE_FREQ_88200;   break;
	case 96000:   rate = LT9611_SAMPLE_FREQ_96000;   break;
	case 176400:  rate = LT9611_SAMPLE_FREQ_176400;  break;
	case 192000:  rate = LT9611_SAMPLE_FREQ_192000;  break;
	default:
		dev_err(dev, "LT9611: Unsupported sample rate %d\n", hparms->sample_rate);
		return -EINVAL;
	}

	/* 3. Настройка разрядности (только для I2S, для SPDIF игнорируется чипом) */
	switch (hparms->sample_width) {
	case 16:  len = LT9611_I2S_SAMPLE_LEN_16;  break;
	case 18:  len = LT9611_I2S_SAMPLE_LEN_18;  break;
	case 20:  len = LT9611_I2S_SAMPLE_LEN_20;  break;
	case 24:  len = LT9611_I2S_SAMPLE_LEN_24;  break;
	default:
		return -EINVAL;
	}

	/* Записываем маску частоты и длины слова в элемент seq[2] (регистр 0x840f) */
	val = rate << 4 | len;
	seq[2].def = val;

	/* 4. Расчет и установка значений N для тактовой сетки HDMI аудио */
	if (fmt->fmt == HDMI_CODEC_SPDIF) {
		/* Для SPDIF китайский референс жестко прописывает фиксированный N-коэффициент */
		seq[5].def = 0x20; // регистр 0x8436 -> 0x20
		seq[4].def = 0x00; // регистр 0x8435 -> 0x00
		seq[6].def = 0x00; // регистр 0x8437 -> 0x00
	} else {
		/* Для I2S рассчитываем динамически в зависимости от частоты потока */
		lt9611_calc_n(hparms->sample_rate, &val);
		seq[4].def = (val >> 16) & 0xF;
		seq[5].def = (val >> 8) & 0xFF;
		seq[6].def = val & 0xFF;
	}

	/* Отправляем всю пачку регистров страницы 0x84 за один раз */
	regmap_multi_reg_write(lt9611->regmap, seq, ARRAY_SIZE(seq));

	return 0;
}