162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci// dice-weiss.c - a part of driver for DICE based devices
362306a36Sopenharmony_ci//
462306a36Sopenharmony_ci// Copyright (c) 2023 Rolf Anderegg and Michele Perrone
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include "dice.h"
762306a36Sopenharmony_ci
862306a36Sopenharmony_cistruct dice_weiss_spec {
962306a36Sopenharmony_ci	unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
1062306a36Sopenharmony_ci	unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
1162306a36Sopenharmony_ci};
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci// Weiss DAC202: 192kHz 2-channel DAC
1462306a36Sopenharmony_cistatic const struct dice_weiss_spec dac202 = {
1562306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
1662306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
1762306a36Sopenharmony_ci};
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci// Weiss MAN301: 192kHz 2-channel music archive network player
2062306a36Sopenharmony_cistatic const struct dice_weiss_spec man301 = {
2162306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
2262306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
2362306a36Sopenharmony_ci};
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci// Weiss INT202: 192kHz unidirectional 2-channel digital Firewire nterface
2662306a36Sopenharmony_cistatic const struct dice_weiss_spec int202 = {
2762306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
2862306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
2962306a36Sopenharmony_ci};
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci// Weiss INT203: 192kHz bidirectional 2-channel digital Firewire nterface
3262306a36Sopenharmony_cistatic const struct dice_weiss_spec int203 = {
3362306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
3462306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci// Weiss ADC2: 192kHz A/D converter with microphone preamps and line nputs
3862306a36Sopenharmony_cistatic const struct dice_weiss_spec adc2 = {
3962306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
4062306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci// Weiss DAC2/Minerva: 192kHz 2-channel DAC
4462306a36Sopenharmony_cistatic const struct dice_weiss_spec dac2_minerva = {
4562306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
4662306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
4762306a36Sopenharmony_ci};
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci// Weiss Vesta: 192kHz 2-channel Firewire to AES/EBU interface
5062306a36Sopenharmony_cistatic const struct dice_weiss_spec vesta = {
5162306a36Sopenharmony_ci	.tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
5262306a36Sopenharmony_ci	.rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci// Weiss AFI1: 192kHz 24-channel Firewire to ADAT or AES/EBU interface
5662306a36Sopenharmony_cistatic const struct dice_weiss_spec afi1 = {
5762306a36Sopenharmony_ci	.tx_pcm_chs = {{24, 16, 8}, {0, 0, 0} },
5862306a36Sopenharmony_ci	.rx_pcm_chs = {{24, 16, 8}, {0, 0, 0} },
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciint snd_dice_detect_weiss_formats(struct snd_dice *dice)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	static const struct {
6462306a36Sopenharmony_ci		u32 model_id;
6562306a36Sopenharmony_ci		const struct dice_weiss_spec *spec;
6662306a36Sopenharmony_ci	} *entry, entries[] = {
6762306a36Sopenharmony_ci		{0x000007, &dac202},
6862306a36Sopenharmony_ci		{0x000008, &dac202}, // Maya edition: same audio I/O as DAC202.
6962306a36Sopenharmony_ci		{0x000006, &int202},
7062306a36Sopenharmony_ci		{0x00000a, &int203},
7162306a36Sopenharmony_ci		{0x00000b, &man301},
7262306a36Sopenharmony_ci		{0x000001, &adc2},
7362306a36Sopenharmony_ci		{0x000003, &dac2_minerva},
7462306a36Sopenharmony_ci		{0x000002, &vesta},
7562306a36Sopenharmony_ci		{0x000004, &afi1},
7662306a36Sopenharmony_ci	};
7762306a36Sopenharmony_ci	struct fw_csr_iterator it;
7862306a36Sopenharmony_ci	int key, val, model_id;
7962306a36Sopenharmony_ci	int i;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	model_id = 0;
8262306a36Sopenharmony_ci	fw_csr_iterator_init(&it, dice->unit->directory);
8362306a36Sopenharmony_ci	while (fw_csr_iterator_next(&it, &key, &val)) {
8462306a36Sopenharmony_ci		if (key == CSR_MODEL) {
8562306a36Sopenharmony_ci			model_id = val;
8662306a36Sopenharmony_ci			break;
8762306a36Sopenharmony_ci		}
8862306a36Sopenharmony_ci	}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
9162306a36Sopenharmony_ci		entry = entries + i;
9262306a36Sopenharmony_ci		if (entry->model_id == model_id)
9362306a36Sopenharmony_ci			break;
9462306a36Sopenharmony_ci	}
9562306a36Sopenharmony_ci	if (i == ARRAY_SIZE(entries))
9662306a36Sopenharmony_ci		return -ENODEV;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	memcpy(dice->tx_pcm_chs, entry->spec->tx_pcm_chs,
9962306a36Sopenharmony_ci	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
10062306a36Sopenharmony_ci	memcpy(dice->rx_pcm_chs, entry->spec->rx_pcm_chs,
10162306a36Sopenharmony_ci	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	return 0;
10462306a36Sopenharmony_ci}
105