1 // SPDX-License-Identifier: GPL-2.0-only
3 * fireworks_proc.c - a part of driver for Fireworks based devices
5 * Copyright (c) 2009-2010 Clemens Ladisch
6 * Copyright (c) 2013-2014 Takashi Sakamoto
9 #include "./fireworks.h"
11 static inline const char*
12 get_phys_name(struct snd_efw_phys_grp
*grp
, bool input
)
14 static const char *const ch_type
[] = {
15 "Analog", "S/PDIF", "ADAT", "S/PDIF or ADAT", "Mirroring",
16 "Headphones", "I2S", "Guitar", "Pirzo Guitar", "Guitar String",
19 if (grp
->type
< ARRAY_SIZE(ch_type
))
20 return ch_type
[grp
->type
];
28 proc_read_hwinfo(struct snd_info_entry
*entry
, struct snd_info_buffer
*buffer
)
30 struct snd_efw
*efw
= entry
->private_data
;
32 struct snd_efw_hwinfo
*hwinfo
;
34 hwinfo
= kmalloc(sizeof(struct snd_efw_hwinfo
), GFP_KERNEL
);
38 if (snd_efw_command_get_hwinfo(efw
, hwinfo
) < 0)
41 snd_iprintf(buffer
, "guid_hi: 0x%X\n", hwinfo
->guid_hi
);
42 snd_iprintf(buffer
, "guid_lo: 0x%X\n", hwinfo
->guid_lo
);
43 snd_iprintf(buffer
, "type: 0x%X\n", hwinfo
->type
);
44 snd_iprintf(buffer
, "version: 0x%X\n", hwinfo
->version
);
45 snd_iprintf(buffer
, "vendor_name: %s\n", hwinfo
->vendor_name
);
46 snd_iprintf(buffer
, "model_name: %s\n", hwinfo
->model_name
);
48 snd_iprintf(buffer
, "dsp_version: 0x%X\n", hwinfo
->dsp_version
);
49 snd_iprintf(buffer
, "arm_version: 0x%X\n", hwinfo
->arm_version
);
50 snd_iprintf(buffer
, "fpga_version: 0x%X\n", hwinfo
->fpga_version
);
52 snd_iprintf(buffer
, "flags: 0x%X\n", hwinfo
->flags
);
54 snd_iprintf(buffer
, "max_sample_rate: 0x%X\n", hwinfo
->max_sample_rate
);
55 snd_iprintf(buffer
, "min_sample_rate: 0x%X\n", hwinfo
->min_sample_rate
);
56 snd_iprintf(buffer
, "supported_clock: 0x%X\n",
57 hwinfo
->supported_clocks
);
59 snd_iprintf(buffer
, "phys out: 0x%X\n", hwinfo
->phys_out
);
60 snd_iprintf(buffer
, "phys in: 0x%X\n", hwinfo
->phys_in
);
62 snd_iprintf(buffer
, "phys in grps: 0x%X\n",
63 hwinfo
->phys_in_grp_count
);
64 for (i
= 0; i
< hwinfo
->phys_in_grp_count
; i
++) {
66 "phys in grp[%d]: type 0x%X, count 0x%X\n",
67 i
, hwinfo
->phys_out_grps
[i
].type
,
68 hwinfo
->phys_out_grps
[i
].count
);
71 snd_iprintf(buffer
, "phys out grps: 0x%X\n",
72 hwinfo
->phys_out_grp_count
);
73 for (i
= 0; i
< hwinfo
->phys_out_grp_count
; i
++) {
75 "phys out grps[%d]: type 0x%X, count 0x%X\n",
76 i
, hwinfo
->phys_out_grps
[i
].type
,
77 hwinfo
->phys_out_grps
[i
].count
);
80 snd_iprintf(buffer
, "amdtp rx pcm channels 1x: 0x%X\n",
81 hwinfo
->amdtp_rx_pcm_channels
);
82 snd_iprintf(buffer
, "amdtp tx pcm channels 1x: 0x%X\n",
83 hwinfo
->amdtp_tx_pcm_channels
);
84 snd_iprintf(buffer
, "amdtp rx pcm channels 2x: 0x%X\n",
85 hwinfo
->amdtp_rx_pcm_channels_2x
);
86 snd_iprintf(buffer
, "amdtp tx pcm channels 2x: 0x%X\n",
87 hwinfo
->amdtp_tx_pcm_channels_2x
);
88 snd_iprintf(buffer
, "amdtp rx pcm channels 4x: 0x%X\n",
89 hwinfo
->amdtp_rx_pcm_channels_4x
);
90 snd_iprintf(buffer
, "amdtp tx pcm channels 4x: 0x%X\n",
91 hwinfo
->amdtp_tx_pcm_channels_4x
);
93 snd_iprintf(buffer
, "midi out ports: 0x%X\n", hwinfo
->midi_out_ports
);
94 snd_iprintf(buffer
, "midi in ports: 0x%X\n", hwinfo
->midi_in_ports
);
96 snd_iprintf(buffer
, "mixer playback channels: 0x%X\n",
97 hwinfo
->mixer_playback_channels
);
98 snd_iprintf(buffer
, "mixer capture channels: 0x%X\n",
99 hwinfo
->mixer_capture_channels
);
105 proc_read_clock(struct snd_info_entry
*entry
, struct snd_info_buffer
*buffer
)
107 struct snd_efw
*efw
= entry
->private_data
;
108 enum snd_efw_clock_source clock_source
;
109 unsigned int sampling_rate
;
111 if (snd_efw_command_get_clock_source(efw
, &clock_source
) < 0)
114 if (snd_efw_command_get_sampling_rate(efw
, &sampling_rate
) < 0)
117 snd_iprintf(buffer
, "Clock Source: %d\n", clock_source
);
118 snd_iprintf(buffer
, "Sampling Rate: %d\n", sampling_rate
);
123 * dB = 20 * log10(linear / 0x01000000)
124 * -144.0 dB when linear is 0
127 proc_read_phys_meters(struct snd_info_entry
*entry
,
128 struct snd_info_buffer
*buffer
)
130 struct snd_efw
*efw
= entry
->private_data
;
131 struct snd_efw_phys_meters
*meters
;
132 unsigned int g
, c
, m
, max
, size
;
137 size
= sizeof(struct snd_efw_phys_meters
) +
138 (efw
->phys_in
+ efw
->phys_out
) * sizeof(u32
);
139 meters
= kzalloc(size
, GFP_KERNEL
);
143 err
= snd_efw_command_get_phys_meters(efw
, meters
, size
);
147 snd_iprintf(buffer
, "Physical Meters:\n");
150 max
= min(efw
->phys_out
, meters
->out_meters
);
151 linear
= meters
->values
;
152 snd_iprintf(buffer
, " %d Outputs:\n", max
);
153 for (g
= 0; g
< efw
->phys_out_grp_count
; g
++) {
154 name
= get_phys_name(&efw
->phys_out_grps
[g
], false);
155 for (c
= 0; c
< efw
->phys_out_grps
[g
].count
; c
++) {
157 snd_iprintf(buffer
, "\t%s [%d]: %d\n",
158 name
, c
, linear
[m
++]);
163 max
= min(efw
->phys_in
, meters
->in_meters
);
164 linear
= meters
->values
+ meters
->out_meters
;
165 snd_iprintf(buffer
, " %d Inputs:\n", max
);
166 for (g
= 0; g
< efw
->phys_in_grp_count
; g
++) {
167 name
= get_phys_name(&efw
->phys_in_grps
[g
], true);
168 for (c
= 0; c
< efw
->phys_in_grps
[g
].count
; c
++)
170 snd_iprintf(buffer
, "\t%s [%d]: %d\n",
171 name
, c
, linear
[m
++]);
178 proc_read_queues_state(struct snd_info_entry
*entry
,
179 struct snd_info_buffer
*buffer
)
181 struct snd_efw
*efw
= entry
->private_data
;
182 unsigned int consumed
;
184 if (efw
->pull_ptr
> efw
->push_ptr
)
185 consumed
= snd_efw_resp_buf_size
-
186 (unsigned int)(efw
->pull_ptr
- efw
->push_ptr
);
188 consumed
= (unsigned int)(efw
->push_ptr
- efw
->pull_ptr
);
190 snd_iprintf(buffer
, "%d/%d\n",
191 consumed
, snd_efw_resp_buf_size
);
195 add_node(struct snd_efw
*efw
, struct snd_info_entry
*root
, const char *name
,
196 void (*op
)(struct snd_info_entry
*e
, struct snd_info_buffer
*b
))
198 struct snd_info_entry
*entry
;
200 entry
= snd_info_create_card_entry(efw
->card
, name
, root
);
202 snd_info_set_text_ops(entry
, efw
, op
);
205 void snd_efw_proc_init(struct snd_efw
*efw
)
207 struct snd_info_entry
*root
;
210 * All nodes are automatically removed at snd_card_disconnect(),
211 * by following to link list.
213 root
= snd_info_create_card_entry(efw
->card
, "firewire",
214 efw
->card
->proc_root
);
217 root
->mode
= S_IFDIR
| 0555;
219 add_node(efw
, root
, "clock", proc_read_clock
);
220 add_node(efw
, root
, "firmware", proc_read_hwinfo
);
221 add_node(efw
, root
, "meters", proc_read_phys_meters
);
222 add_node(efw
, root
, "queues", proc_read_queues_state
);