aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-04-25 09:45:21 -0400
committerTakashi Iwai <tiwai@suse.de>2014-05-26 08:31:15 -0400
commit1fc9522a084f36d042298ef15893cf07d66a54bc (patch)
tree7fe03c4b4b01fdc53ea9f8a98fae2add483ea373 /sound/firewire
parent618eabeae711c56d376daa147c6a684116d68705 (diff)
ALSA: bebob: Prepare for device specific operations
This commit is for some devices which have its own operations or quirks. Many functionality should be implemented in user land. Then this commit adds functionality related to stream such as sampling frequency or clock source. For help to debug, this commit adds the functionality to get metering information if it's available. To help these functionalities, this commit adds some AV/C commands defined in 'AV/C Audio Subunit Specification (1394TA). Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/bebob/Makefile3
-rw-r--r--sound/firewire/bebob/bebob.c72
-rw-r--r--sound/firewire/bebob/bebob.h33
-rw-r--r--sound/firewire/bebob/bebob_command.c77
-rw-r--r--sound/firewire/bebob/bebob_pcm.c3
-rw-r--r--sound/firewire/bebob/bebob_proc.c57
-rw-r--r--sound/firewire/bebob/bebob_stream.c27
7 files changed, 230 insertions, 42 deletions
diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile
index 78087772a022..e4b08e38dd23 100644
--- a/sound/firewire/bebob/Makefile
+++ b/sound/firewire/bebob/Makefile
@@ -1,4 +1,3 @@
1snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \ 1snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \
2 bebob_pcm.o bebob_hwdep.o \ 2 bebob_pcm.o bebob_hwdep.o bebob.o
3 bebob.o
4obj-m += snd-bebob.o 3obj-m += snd-bebob.o
diff --git a/sound/firewire/bebob/bebob.c b/sound/firewire/bebob/bebob.c
index b7d70c2e4e87..3d7909036a3c 100644
--- a/sound/firewire/bebob/bebob.c
+++ b/sound/firewire/bebob/bebob.c
@@ -126,6 +126,7 @@ bebob_probe(struct fw_unit *unit,
126{ 126{
127 struct snd_card *card; 127 struct snd_card *card;
128 struct snd_bebob *bebob; 128 struct snd_bebob *bebob;
129 const struct snd_bebob_spec *spec;
129 unsigned int card_index; 130 unsigned int card_index;
130 int err; 131 int err;
131 132
@@ -140,6 +141,12 @@ bebob_probe(struct fw_unit *unit,
140 goto end; 141 goto end;
141 } 142 }
142 143
144 spec = (const struct snd_bebob_spec *)entry->driver_data;
145 if (spec == NULL) {
146 err = -ENOSYS;
147 goto end;
148 }
149
143 err = snd_card_new(&unit->device, index[card_index], id[card_index], 150 err = snd_card_new(&unit->device, index[card_index], id[card_index],
144 THIS_MODULE, sizeof(struct snd_bebob), &card); 151 THIS_MODULE, sizeof(struct snd_bebob), &card);
145 if (err < 0) 152 if (err < 0)
@@ -151,6 +158,7 @@ bebob_probe(struct fw_unit *unit,
151 158
152 bebob->card = card; 159 bebob->card = card;
153 bebob->unit = unit; 160 bebob->unit = unit;
161 bebob->spec = spec;
154 mutex_init(&bebob->mutex); 162 mutex_init(&bebob->mutex);
155 spin_lock_init(&bebob->lock); 163 spin_lock_init(&bebob->lock);
156 init_waitqueue_head(&bebob->hwdep_wait); 164 init_waitqueue_head(&bebob->hwdep_wait);
@@ -216,62 +224,72 @@ static void bebob_remove(struct fw_unit *unit)
216 snd_card_free_when_closed(bebob->card); 224 snd_card_free_when_closed(bebob->card);
217} 225}
218 226
227struct snd_bebob_rate_spec normal_rate_spec = {
228 .get = &snd_bebob_stream_get_rate,
229 .set = &snd_bebob_stream_set_rate
230};
231static const struct snd_bebob_spec spec_normal = {
232 .clock = NULL,
233 .rate = &normal_rate_spec,
234 .meter = NULL
235};
236
219static const struct ieee1394_device_id bebob_id_table[] = { 237static const struct ieee1394_device_id bebob_id_table[] = {
220 /* Edirol, FA-66 */ 238 /* Edirol, FA-66 */
221 SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049), 239 SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010049, &spec_normal),
222 /* Edirol, FA-101 */ 240 /* Edirol, FA-101 */
223 SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048), 241 SND_BEBOB_DEV_ENTRY(VEN_EDIROL, 0x00010048, &spec_normal),
224 /* Presonus, FIREBOX */ 242 /* Presonus, FIREBOX */
225 SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000), 243 SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010000, &spec_normal),
226 /* PreSonus, FIREPOD/FP10 */ 244 /* PreSonus, FIREPOD/FP10 */
227 SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066), 245 SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010066, &spec_normal),
228 /* PreSonus, Inspire1394 */ 246 /* PreSonus, Inspire1394 */
229 SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001), 247 SND_BEBOB_DEV_ENTRY(VEN_PRESONUS, 0x00010001, &spec_normal),
230 /* BridgeCo, RDAudio1 */ 248 /* BridgeCo, RDAudio1 */
231 SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048), 249 SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010048, &spec_normal),
232 /* BridgeCo, Audio5 */ 250 /* BridgeCo, Audio5 */
233 SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049), 251 SND_BEBOB_DEV_ENTRY(VEN_BRIDGECO, 0x00010049, &spec_normal),
234 /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */ 252 /* Mackie, Onyx 1220/1620/1640 (Firewire I/O Card) */
235 SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065), 253 SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010065, &spec_normal),
236 /* Mackie, d.2 (Firewire Option) */ 254 /* Mackie, d.2 (Firewire Option) */
237 SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067), 255 SND_BEBOB_DEV_ENTRY(VEN_MACKIE, 0x00010067, &spec_normal),
238 /* Stanton, ScratchAmp */ 256 /* Stanton, ScratchAmp */
239 SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001), 257 SND_BEBOB_DEV_ENTRY(VEN_STANTON, 0x00000001, &spec_normal),
240 /* Tascam, IF-FW DM */ 258 /* Tascam, IF-FW DM */
241 SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067), 259 SND_BEBOB_DEV_ENTRY(VEN_TASCAM, 0x00010067, &spec_normal),
242 /* Behringer, XENIX UFX 1204 */ 260 /* Behringer, XENIX UFX 1204 */
243 SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204), 261 SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001204, &spec_normal),
244 /* Behringer, XENIX UFX 1604 */ 262 /* Behringer, XENIX UFX 1604 */
245 SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604), 263 SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00001604, &spec_normal),
246 /* Behringer, Digital Mixer X32 series (X-UF Card) */ 264 /* Behringer, Digital Mixer X32 series (X-UF Card) */
247 SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006), 265 SND_BEBOB_DEV_ENTRY(VEN_BEHRINGER, 0x00000006, &spec_normal),
248 /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */ 266 /* Apogee Electronics, Rosetta 200/400 (X-FireWire card) */
249 /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */ 267 /* Apogee Electronics, DA/AD/DD-16X (X-FireWire card) */
250 SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048), 268 SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00010048, &spec_normal),
251 /* Apogee Electronics, Ensemble */ 269 /* Apogee Electronics, Ensemble */
252 SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00001eee), 270 SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x00001eee, &spec_normal),
253 /* ESI, Quatafire610 */ 271 /* ESI, Quatafire610 */
254 SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064), 272 SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal),
255 /* AcousticReality, eARMasterOne */ 273 /* AcousticReality, eARMasterOne */
256 SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002), 274 SND_BEBOB_DEV_ENTRY(VEN_ACOUSTIC, 0x00000002, &spec_normal),
257 /* CME, MatrixKFW */ 275 /* CME, MatrixKFW */
258 SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000), 276 SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal),
259 /* Phonic, Helix Board 12 MkII */ 277 /* Phonic, Helix Board 12 MkII */
260 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000), 278 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00050000, &spec_normal),
261 /* Phonic, Helix Board 18 MkII */ 279 /* Phonic, Helix Board 18 MkII */
262 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000), 280 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00060000, &spec_normal),
263 /* Phonic, Helix Board 24 MkII */ 281 /* Phonic, Helix Board 24 MkII */
264 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000), 282 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00070000, &spec_normal),
265 /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */ 283 /* Phonic, Helix Board 12 Universal/18 Universal/24 Universal */
266 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000), 284 SND_BEBOB_DEV_ENTRY(VEN_PHONIC, 0x00000000, &spec_normal),
267 /* Lynx, Aurora 8/16 (LT-FW) */ 285 /* Lynx, Aurora 8/16 (LT-FW) */
268 SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001), 286 SND_BEBOB_DEV_ENTRY(VEN_LYNX, 0x00000001, &spec_normal),
269 /* ICON, FireXon */ 287 /* ICON, FireXon */
270 SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001), 288 SND_BEBOB_DEV_ENTRY(VEN_ICON, 0x00000001, &spec_normal),
271 /* PrismSound, Orpheus */ 289 /* PrismSound, Orpheus */
272 SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048), 290 SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x00010048, &spec_normal),
273 /* PrismSound, ADA-8XR */ 291 /* PrismSound, ADA-8XR */
274 SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8), 292 SND_BEBOB_DEV_ENTRY(VEN_PRISMSOUND, 0x0000ada8, &spec_normal),
275 /* IDs are unknown but able to be supported */ 293 /* IDs are unknown but able to be supported */
276 /* Apogee, Mini-ME Firewire */ 294 /* Apogee, Mini-ME Firewire */
277 /* Apogee, Mini-DAC Firewire */ 295 /* Apogee, Mini-DAC Firewire */
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h
index e8a5e447ff17..7365f92a6aed 100644
--- a/sound/firewire/bebob/bebob.h
+++ b/sound/firewire/bebob/bebob.h
@@ -48,6 +48,28 @@ struct snd_bebob_stream_formation {
48/* this is a lookup table for index of stream formations */ 48/* this is a lookup table for index of stream formations */
49extern const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES]; 49extern const unsigned int snd_bebob_rate_table[SND_BEBOB_STRM_FMT_ENTRIES];
50 50
51/* device specific operations */
52#define SND_BEBOB_CLOCK_INTERNAL "Internal"
53struct snd_bebob_clock_spec {
54 unsigned int num;
55 char *const *labels;
56 int (*get)(struct snd_bebob *bebob, unsigned int *id);
57};
58struct snd_bebob_rate_spec {
59 int (*get)(struct snd_bebob *bebob, unsigned int *rate);
60 int (*set)(struct snd_bebob *bebob, unsigned int rate);
61};
62struct snd_bebob_meter_spec {
63 unsigned int num;
64 char *const *labels;
65 int (*get)(struct snd_bebob *bebob, u32 *target, unsigned int size);
66};
67struct snd_bebob_spec {
68 struct snd_bebob_clock_spec *clock;
69 struct snd_bebob_rate_spec *rate;
70 struct snd_bebob_meter_spec *meter;
71};
72
51struct snd_bebob { 73struct snd_bebob {
52 struct snd_card *card; 74 struct snd_card *card;
53 struct fw_unit *unit; 75 struct fw_unit *unit;
@@ -56,6 +78,8 @@ struct snd_bebob {
56 struct mutex mutex; 78 struct mutex mutex;
57 spinlock_t lock; 79 spinlock_t lock;
58 80
81 const struct snd_bebob_spec *spec;
82
59 unsigned int midi_input_ports; 83 unsigned int midi_input_ports;
60 unsigned int midi_output_ports; 84 unsigned int midi_output_ports;
61 85
@@ -100,6 +124,12 @@ snd_bebob_read_quad(struct fw_unit *unit, u64 addr, u32 *buf)
100 (void *)buf, sizeof(u32), 0); 124 (void *)buf, sizeof(u32), 0);
101} 125}
102 126
127/* AV/C Audio Subunit Specification 1.0 (Oct 2000, 1394TA) */
128int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
129 unsigned int fb_id, unsigned int num);
130int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
131 unsigned int fb_id, unsigned int *num);
132
103/* 133/*
104 * AVC command extensions, AV/C Unit and Subunit, Revision 17 134 * AVC command extensions, AV/C Unit and Subunit, Revision 17
105 * (Nov 2003, BridgeCo) 135 * (Nov 2003, BridgeCo)
@@ -194,12 +224,13 @@ int snd_bebob_create_pcm_devices(struct snd_bebob *bebob);
194 224
195int snd_bebob_create_hwdep_device(struct snd_bebob *bebob); 225int snd_bebob_create_hwdep_device(struct snd_bebob *bebob);
196 226
197#define SND_BEBOB_DEV_ENTRY(vendor, model) \ 227#define SND_BEBOB_DEV_ENTRY(vendor, model, data) \
198{ \ 228{ \
199 .match_flags = IEEE1394_MATCH_VENDOR_ID | \ 229 .match_flags = IEEE1394_MATCH_VENDOR_ID | \
200 IEEE1394_MATCH_MODEL_ID, \ 230 IEEE1394_MATCH_MODEL_ID, \
201 .vendor_id = vendor, \ 231 .vendor_id = vendor, \
202 .model_id = model, \ 232 .model_id = model, \
233 .driver_data = (kernel_ulong_t)data \
203} 234}
204 235
205#endif 236#endif
diff --git a/sound/firewire/bebob/bebob_command.c b/sound/firewire/bebob/bebob_command.c
index 6a017951a888..9402cc15dbc1 100644
--- a/sound/firewire/bebob/bebob_command.c
+++ b/sound/firewire/bebob/bebob_command.c
@@ -8,6 +8,83 @@
8 8
9#include "./bebob.h" 9#include "./bebob.h"
10 10
11int avc_audio_set_selector(struct fw_unit *unit, unsigned int subunit_id,
12 unsigned int fb_id, unsigned int num)
13{
14 u8 *buf;
15 int err;
16
17 buf = kzalloc(12, GFP_KERNEL);
18 if (buf == NULL)
19 return -ENOMEM;
20
21 buf[0] = 0x00; /* AV/C CONTROL */
22 buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
23 buf[2] = 0xb8; /* FUNCTION BLOCK */
24 buf[3] = 0x80; /* type is 'selector'*/
25 buf[4] = 0xff & fb_id; /* function block id */
26 buf[5] = 0x10; /* control attribute is CURRENT */
27 buf[6] = 0x02; /* selector length is 2 */
28 buf[7] = 0xff & num; /* input function block plug number */
29 buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
30
31 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
33 BIT(6) | BIT(7) | BIT(8));
34 if (err > 0 && err < 9)
35 err = -EIO;
36 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
37 err = -ENOSYS;
38 else if (buf[0] == 0x0a) /* REJECTED */
39 err = -EINVAL;
40 else if (err > 0)
41 err = 0;
42
43 kfree(buf);
44 return err;
45}
46
47int avc_audio_get_selector(struct fw_unit *unit, unsigned int subunit_id,
48 unsigned int fb_id, unsigned int *num)
49{
50 u8 *buf;
51 int err;
52
53 buf = kzalloc(12, GFP_KERNEL);
54 if (buf == NULL)
55 return -ENOMEM;
56
57 buf[0] = 0x01; /* AV/C STATUS */
58 buf[1] = 0x08 | (0x07 & subunit_id); /* AUDIO SUBUNIT ID */
59 buf[2] = 0xb8; /* FUNCTION BLOCK */
60 buf[3] = 0x80; /* type is 'selector'*/
61 buf[4] = 0xff & fb_id; /* function block id */
62 buf[5] = 0x10; /* control attribute is CURRENT */
63 buf[6] = 0x02; /* selector length is 2 */
64 buf[7] = 0xff; /* input function block plug number */
65 buf[8] = 0x01; /* control selector is SELECTOR_CONTROL */
66
67 err = fcp_avc_transaction(unit, buf, 12, buf, 12,
68 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
69 BIT(6) | BIT(8));
70 if (err > 0 && err < 9)
71 err = -EIO;
72 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */
73 err = -ENOSYS;
74 else if (buf[0] == 0x0a) /* REJECTED */
75 err = -EINVAL;
76 else if (buf[0] == 0x0b) /* IN TRANSITION */
77 err = -EAGAIN;
78 if (err < 0)
79 goto end;
80
81 *num = buf[7];
82 err = 0;
83end:
84 kfree(buf);
85 return err;
86}
87
11static inline void 88static inline void
12avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr) 89avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr)
13{ 90{
diff --git a/sound/firewire/bebob/bebob_pcm.c b/sound/firewire/bebob/bebob_pcm.c
index 9d868171db4e..4a55561ed4ec 100644
--- a/sound/firewire/bebob/bebob_pcm.c
+++ b/sound/firewire/bebob/bebob_pcm.c
@@ -155,6 +155,7 @@ static int
155pcm_open(struct snd_pcm_substream *substream) 155pcm_open(struct snd_pcm_substream *substream)
156{ 156{
157 struct snd_bebob *bebob = substream->private_data; 157 struct snd_bebob *bebob = substream->private_data;
158 struct snd_bebob_rate_spec *spec = bebob->spec->rate;
158 unsigned int sampling_rate; 159 unsigned int sampling_rate;
159 bool internal; 160 bool internal;
160 int err; 161 int err;
@@ -178,7 +179,7 @@ pcm_open(struct snd_pcm_substream *substream)
178 if (!internal || 179 if (!internal ||
179 amdtp_stream_pcm_running(&bebob->tx_stream) || 180 amdtp_stream_pcm_running(&bebob->tx_stream) ||
180 amdtp_stream_pcm_running(&bebob->rx_stream)) { 181 amdtp_stream_pcm_running(&bebob->rx_stream)) {
181 err = snd_bebob_stream_get_rate(bebob, &sampling_rate); 182 err = spec->get(bebob, &sampling_rate);
182 if (err < 0) { 183 if (err < 0) {
183 dev_err(&bebob->unit->device, 184 dev_err(&bebob->unit->device,
184 "fail to get sampling rate: %d\n", err); 185 "fail to get sampling rate: %d\n", err);
diff --git a/sound/firewire/bebob/bebob_proc.c b/sound/firewire/bebob/bebob_proc.c
index c31ca4f42a58..335da64506e0 100644
--- a/sound/firewire/bebob/bebob_proc.c
+++ b/sound/firewire/bebob/bebob_proc.c
@@ -69,6 +69,39 @@ end:
69} 69}
70 70
71static void 71static void
72proc_read_meters(struct snd_info_entry *entry,
73 struct snd_info_buffer *buffer)
74{
75 struct snd_bebob *bebob = entry->private_data;
76 struct snd_bebob_meter_spec *spec = bebob->spec->meter;
77 u32 *buf;
78 unsigned int i, c, channels, size;
79
80 if (spec == NULL)
81 return;
82
83 channels = spec->num * 2;
84 size = channels * sizeof(u32);
85 buf = kmalloc(size, GFP_KERNEL);
86 if (buf == NULL)
87 return;
88
89 if (spec->get(bebob, buf, size) < 0)
90 goto end;
91
92 for (i = 0, c = 1; i < channels; i++) {
93 snd_iprintf(buffer, "%s %d:\t%d\n",
94 spec->labels[i / 2], c++, buf[i]);
95 if ((i + 1 < channels - 1) &&
96 (strcmp(spec->labels[i / 2],
97 spec->labels[(i + 1) / 2]) != 0))
98 c = 1;
99 }
100end:
101 kfree(buf);
102}
103
104static void
72proc_read_formation(struct snd_info_entry *entry, 105proc_read_formation(struct snd_info_entry *entry,
73 struct snd_info_buffer *buffer) 106 struct snd_info_buffer *buffer)
74{ 107{
@@ -100,16 +133,25 @@ proc_read_clock(struct snd_info_entry *entry,
100 struct snd_info_buffer *buffer) 133 struct snd_info_buffer *buffer)
101{ 134{
102 struct snd_bebob *bebob = entry->private_data; 135 struct snd_bebob *bebob = entry->private_data;
103 unsigned int rate; 136 struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
137 struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
138 unsigned int rate, id;
104 bool internal; 139 bool internal;
105 140
106 if (snd_bebob_stream_get_rate(bebob, &rate) >= 0) 141 if (rate_spec->get(bebob, &rate) >= 0)
107 snd_iprintf(buffer, "Sampling rate: %d\n", rate); 142 snd_iprintf(buffer, "Sampling rate: %d\n", rate);
108 143
109 if (snd_bebob_stream_check_internal_clock(bebob, &internal) >= 0) 144 if (clk_spec) {
110 snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)", 145 if (clk_spec->get(bebob, &id) >= 0)
111 (internal) ? "Internal" : "External", 146 snd_iprintf(buffer, "Clock Source: %s\n",
112 bebob->sync_input_plug); 147 clk_spec->labels[id]);
148 } else {
149 if (snd_bebob_stream_check_internal_clock(bebob,
150 &internal) >= 0)
151 snd_iprintf(buffer, "Clock Source: %s (MSU-dest: %d)\n",
152 (internal) ? "Internal" : "External",
153 bebob->sync_input_plug);
154 }
113} 155}
114 156
115static void 157static void
@@ -148,4 +190,7 @@ void snd_bebob_proc_init(struct snd_bebob *bebob)
148 add_node(bebob, root, "clock", proc_read_clock); 190 add_node(bebob, root, "clock", proc_read_clock);
149 add_node(bebob, root, "firmware", proc_read_hw_info); 191 add_node(bebob, root, "firmware", proc_read_hw_info);
150 add_node(bebob, root, "formation", proc_read_formation); 192 add_node(bebob, root, "formation", proc_read_formation);
193
194 if (bebob->spec->meter != NULL)
195 add_node(bebob, root, "meter", proc_read_meters);
151} 196}
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c
index 85b4fd661787..4a21dcf95d95 100644
--- a/sound/firewire/bebob/bebob_stream.c
+++ b/sound/firewire/bebob/bebob_stream.c
@@ -119,13 +119,27 @@ end:
119int 119int
120snd_bebob_stream_check_internal_clock(struct snd_bebob *bebob, bool *internal) 120snd_bebob_stream_check_internal_clock(struct snd_bebob *bebob, bool *internal)
121{ 121{
122 struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
122 u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7]; 123 u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7];
124 unsigned int id;
123 int err = 0; 125 int err = 0;
124 126
125 *internal = false; 127 *internal = false;
126 128
129 /* 1.The device has its own operation to switch source of clock */
130 if (clk_spec) {
131 err = clk_spec->get(bebob, &id);
132 if (err < 0)
133 dev_err(&bebob->unit->device,
134 "fail to get clock source: %d\n", err);
135 else if (strncmp(clk_spec->labels[id], SND_BEBOB_CLOCK_INTERNAL,
136 strlen(SND_BEBOB_CLOCK_INTERNAL)) == 0)
137 *internal = true;
138 goto end;
139 }
140
127 /* 141 /*
128 * 1.The device don't support to switch source of clock then assumed 142 * 2.The device don't support to switch source of clock then assumed
129 * to use internal clock always 143 * to use internal clock always
130 */ 144 */
131 if (bebob->sync_input_plug < 0) { 145 if (bebob->sync_input_plug < 0) {
@@ -134,7 +148,7 @@ snd_bebob_stream_check_internal_clock(struct snd_bebob *bebob, bool *internal)
134 } 148 }
135 149
136 /* 150 /*
137 * 2.The device supports to switch source of clock by an usual way. 151 * 3.The device supports to switch source of clock by an usual way.
138 * Let's check input for 'Music Sub Unit Sync Input' plug. 152 * Let's check input for 'Music Sub Unit Sync Input' plug.
139 */ 153 */
140 avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN, 154 avc_bridgeco_fill_msu_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
@@ -442,6 +456,7 @@ end:
442 456
443int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, int rate) 457int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, int rate)
444{ 458{
459 struct snd_bebob_rate_spec *rate_spec = bebob->spec->rate;
445 struct amdtp_stream *master, *slave; 460 struct amdtp_stream *master, *slave;
446 atomic_t *slave_substreams; 461 atomic_t *slave_substreams;
447 enum cip_flags sync_mode; 462 enum cip_flags sync_mode;
@@ -508,7 +523,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, int rate)
508 break_both_connections(bebob); 523 break_both_connections(bebob);
509 524
510 /* stop streams if rate is different */ 525 /* stop streams if rate is different */
511 err = snd_bebob_stream_get_rate(bebob, &curr_rate); 526 err = rate_spec->get(bebob, &curr_rate);
512 if (err < 0) { 527 if (err < 0) {
513 dev_err(&bebob->unit->device, 528 dev_err(&bebob->unit->device,
514 "fail to get sampling rate: %d\n", err); 529 "fail to get sampling rate: %d\n", err);
@@ -532,7 +547,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, int rate)
532 * If establishing connections at first, Yamaha GO46 547 * If establishing connections at first, Yamaha GO46
533 * (and maybe Terratec X24) don't generate sound. 548 * (and maybe Terratec X24) don't generate sound.
534 */ 549 */
535 err = snd_bebob_stream_set_rate(bebob, rate); 550 err = rate_spec->set(bebob, rate);
536 if (err < 0) { 551 if (err < 0) {
537 dev_err(&bebob->unit->device, 552 dev_err(&bebob->unit->device,
538 "fail to set sampling rate: %d\n", 553 "fail to set sampling rate: %d\n",
@@ -822,6 +837,7 @@ end:
822 837
823int snd_bebob_stream_discover(struct snd_bebob *bebob) 838int snd_bebob_stream_discover(struct snd_bebob *bebob)
824{ 839{
840 struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
825 u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES]; 841 u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
826 enum avc_bridgeco_plug_type type; 842 enum avc_bridgeco_plug_type type;
827 unsigned int i; 843 unsigned int i;
@@ -908,7 +924,8 @@ int snd_bebob_stream_discover(struct snd_bebob *bebob)
908 } 924 }
909 925
910 /* for check source of clock later */ 926 /* for check source of clock later */
911 err = seek_msu_sync_input_plug(bebob); 927 if (!clk_spec)
928 err = seek_msu_sync_input_plug(bebob);
912end: 929end:
913 return err; 930 return err;
914} 931}