aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}