162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * dice-tc_electronic.c - a part of driver for DICE based devices
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2018 Takashi Sakamoto
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "dice.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistruct dice_tc_spec {
1162306a36Sopenharmony_ci	unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
1262306a36Sopenharmony_ci	unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
1362306a36Sopenharmony_ci	bool has_midi;
1462306a36Sopenharmony_ci};
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistatic const struct dice_tc_spec desktop_konnekt6 = {
1762306a36Sopenharmony_ci	.tx_pcm_chs = {{6, 6, 2}, {0, 0, 0} },
1862306a36Sopenharmony_ci	.rx_pcm_chs = {{6, 6, 4}, {0, 0, 0} },
1962306a36Sopenharmony_ci	.has_midi = false,
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic const struct dice_tc_spec impact_twin = {
2362306a36Sopenharmony_ci	.tx_pcm_chs = {{14, 10, 6}, {0, 0, 0} },
2462306a36Sopenharmony_ci	.rx_pcm_chs = {{14, 10, 6}, {0, 0, 0} },
2562306a36Sopenharmony_ci	.has_midi = true,
2662306a36Sopenharmony_ci};
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic const struct dice_tc_spec konnekt_8 = {
2962306a36Sopenharmony_ci	.tx_pcm_chs = {{4, 4, 3}, {0, 0, 0} },
3062306a36Sopenharmony_ci	.rx_pcm_chs = {{4, 4, 3}, {0, 0, 0} },
3162306a36Sopenharmony_ci	.has_midi = true,
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic const struct dice_tc_spec konnekt_24d = {
3562306a36Sopenharmony_ci	.tx_pcm_chs = {{16, 16, 6}, {0, 0, 0} },
3662306a36Sopenharmony_ci	.rx_pcm_chs = {{16, 16, 6}, {0, 0, 0} },
3762306a36Sopenharmony_ci	.has_midi = true,
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_cistatic const struct dice_tc_spec konnekt_live = {
4162306a36Sopenharmony_ci	.tx_pcm_chs = {{16, 16, 6}, {0, 0, 0} },
4262306a36Sopenharmony_ci	.rx_pcm_chs = {{16, 16, 6}, {0, 0, 0} },
4362306a36Sopenharmony_ci	.has_midi = true,
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic const struct dice_tc_spec studio_konnekt_48 = {
4762306a36Sopenharmony_ci	.tx_pcm_chs = {{16, 16, 8}, {16, 16, 7} },
4862306a36Sopenharmony_ci	.rx_pcm_chs = {{16, 16, 8}, {14, 14, 7} },
4962306a36Sopenharmony_ci	.has_midi = true,
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic const struct dice_tc_spec digital_konnekt_x32 = {
5362306a36Sopenharmony_ci	.tx_pcm_chs = {{16, 16, 4}, {0, 0, 0} },
5462306a36Sopenharmony_ci	.rx_pcm_chs = {{16, 16, 4}, {0, 0, 0} },
5562306a36Sopenharmony_ci	.has_midi = false,
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciint snd_dice_detect_tcelectronic_formats(struct snd_dice *dice)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	static const struct {
6162306a36Sopenharmony_ci		u32 model_id;
6262306a36Sopenharmony_ci		const struct dice_tc_spec *spec;
6362306a36Sopenharmony_ci	} *entry, entries[] = {
6462306a36Sopenharmony_ci		{0x00000020, &konnekt_24d},
6562306a36Sopenharmony_ci		{0x00000021, &konnekt_8},
6662306a36Sopenharmony_ci		{0x00000022, &studio_konnekt_48},
6762306a36Sopenharmony_ci		{0x00000023, &konnekt_live},
6862306a36Sopenharmony_ci		{0x00000024, &desktop_konnekt6},
6962306a36Sopenharmony_ci		{0x00000027, &impact_twin},
7062306a36Sopenharmony_ci		{0x00000030, &digital_konnekt_x32},
7162306a36Sopenharmony_ci	};
7262306a36Sopenharmony_ci	struct fw_csr_iterator it;
7362306a36Sopenharmony_ci	int key, val, model_id;
7462306a36Sopenharmony_ci	int i;
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	model_id = 0;
7762306a36Sopenharmony_ci	fw_csr_iterator_init(&it, dice->unit->directory);
7862306a36Sopenharmony_ci	while (fw_csr_iterator_next(&it, &key, &val)) {
7962306a36Sopenharmony_ci		if (key == CSR_MODEL) {
8062306a36Sopenharmony_ci			model_id = val;
8162306a36Sopenharmony_ci			break;
8262306a36Sopenharmony_ci		}
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(entries); ++i) {
8662306a36Sopenharmony_ci		entry = entries + i;
8762306a36Sopenharmony_ci		if (entry->model_id == model_id)
8862306a36Sopenharmony_ci			break;
8962306a36Sopenharmony_ci	}
9062306a36Sopenharmony_ci	if (i == ARRAY_SIZE(entries))
9162306a36Sopenharmony_ci		return -ENODEV;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	memcpy(dice->tx_pcm_chs, entry->spec->tx_pcm_chs,
9462306a36Sopenharmony_ci	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
9562306a36Sopenharmony_ci	memcpy(dice->rx_pcm_chs, entry->spec->rx_pcm_chs,
9662306a36Sopenharmony_ci	       MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	if (entry->spec->has_midi) {
9962306a36Sopenharmony_ci		dice->tx_midi_ports[0] = 1;
10062306a36Sopenharmony_ci		dice->rx_midi_ports[0] = 1;
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	return 0;
10462306a36Sopenharmony_ci}
105