| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // dice-presonus.c - a part of driver for DICE based devices |
| 3 | // |
| 4 | // Copyright (c) 2019 Takashi Sakamoto |
| 5 | |
| 6 | #include "dice.h" |
| 7 | |
| 8 | struct dice_presonus_spec { |
| 9 | unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; |
| 10 | unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT]; |
| 11 | bool has_midi; |
| 12 | }; |
| 13 | |
| 14 | static const struct dice_presonus_spec dice_presonus_firesutio = { |
| 15 | .tx_pcm_chs = {{16, 16, 0}, {10, 2, 0} }, |
| 16 | .rx_pcm_chs = {{16, 16, 0}, {10, 2, 0} }, |
| 17 | .has_midi = true, |
| 18 | }; |
| 19 | |
| 20 | int snd_dice_detect_presonus_formats(struct snd_dice *dice) |
| 21 | { |
| 22 | static const struct { |
| 23 | u32 model_id; |
| 24 | const struct dice_presonus_spec *spec; |
| 25 | } *entry, entries[] = { |
| 26 | {0x000008, &dice_presonus_firesutio}, |
| 27 | }; |
| 28 | struct fw_csr_iterator it; |
| 29 | int key, val, model_id; |
| 30 | int i; |
| 31 | |
| 32 | model_id = 0; |
| 33 | fw_csr_iterator_init(ci: &it, p: dice->unit->directory); |
| 34 | while (fw_csr_iterator_next(ci: &it, key: &key, value: &val)) { |
| 35 | if (key == CSR_MODEL) { |
| 36 | model_id = val; |
| 37 | break; |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | for (i = 0; i < ARRAY_SIZE(entries); ++i) { |
| 42 | entry = entries + i; |
| 43 | if (entry->model_id == model_id) |
| 44 | break; |
| 45 | } |
| 46 | if (i == ARRAY_SIZE(entries)) |
| 47 | return -ENODEV; |
| 48 | |
| 49 | memcpy(dice->tx_pcm_chs, entry->spec->tx_pcm_chs, |
| 50 | MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int)); |
| 51 | memcpy(dice->rx_pcm_chs, entry->spec->rx_pcm_chs, |
| 52 | MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int)); |
| 53 | |
| 54 | if (entry->spec->has_midi) { |
| 55 | dice->tx_midi_ports[0] = 1; |
| 56 | dice->rx_midi_ports[0] = 1; |
| 57 | } |
| 58 | |
| 59 | return 0; |
| 60 | } |
| 61 | |