aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /sound/firewire
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/Kconfig36
-rw-r--r--sound/firewire/Makefile8
-rw-r--r--sound/firewire/amdtp.c563
-rw-r--r--sound/firewire/amdtp.h169
-rw-r--r--sound/firewire/cmp.c307
-rw-r--r--sound/firewire/cmp.h41
-rw-r--r--sound/firewire/fcp.c224
-rw-r--r--sound/firewire/fcp.h12
-rw-r--r--sound/firewire/isight.c756
-rw-r--r--sound/firewire/iso-resources.c231
-rw-r--r--sound/firewire/iso-resources.h38
-rw-r--r--sound/firewire/lib.c85
-rw-r--r--sound/firewire/lib.h19
-rw-r--r--sound/firewire/packets-buffer.c76
-rw-r--r--sound/firewire/packets-buffer.h26
-rw-r--r--sound/firewire/speakers.c857
16 files changed, 3448 insertions, 0 deletions
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
new file mode 100644
index 000000000000..26071489970b
--- /dev/null
+++ b/sound/firewire/Kconfig
@@ -0,0 +1,36 @@
1menuconfig SND_FIREWIRE
2 bool "FireWire sound devices"
3 depends on FIREWIRE
4 default y
5 help
6 Support for IEEE-1394/FireWire/iLink sound devices.
7
8if SND_FIREWIRE && FIREWIRE
9
10config SND_FIREWIRE_LIB
11 tristate
12 depends on SND_PCM
13
14config SND_FIREWIRE_SPEAKERS
15 tristate "FireWire speakers"
16 select SND_PCM
17 select SND_FIREWIRE_LIB
18 help
19 Say Y here to include support for the Griffin FireWave Surround
20 and the LaCie FireWire Speakers.
21
22 To compile this driver as a module, choose M here: the module
23 will be called snd-firewire-speakers.
24
25config SND_ISIGHT
26 tristate "Apple iSight microphone"
27 select SND_PCM
28 select SND_FIREWIRE_LIB
29 help
30 Say Y here to include support for the front and rear microphones
31 of the Apple iSight web camera.
32
33 To compile this driver as a module, choose M here: the module
34 will be called snd-isight.
35
36endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
new file mode 100644
index 000000000000..d71ed8935f76
--- /dev/null
+++ b/sound/firewire/Makefile
@@ -0,0 +1,8 @@
1snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \
2 fcp.o cmp.o amdtp.o
3snd-firewire-speakers-objs := speakers.o
4snd-isight-objs := isight.o
5
6obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
7obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
8obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c
new file mode 100644
index 000000000000..87657dd7714c
--- /dev/null
+++ b/sound/firewire/amdtp.c
@@ -0,0 +1,563 @@
1/*
2 * Audio and Music Data Transmission Protocol (IEC 61883-6) streams
3 * with Common Isochronous Packet (IEC 61883-1) headers
4 *
5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include <linux/device.h>
10#include <linux/err.h>
11#include <linux/firewire.h>
12#include <linux/module.h>
13#include <linux/slab.h>
14#include <sound/pcm.h>
15#include "amdtp.h"
16
17#define TICKS_PER_CYCLE 3072
18#define CYCLES_PER_SECOND 8000
19#define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND)
20
21#define TRANSFER_DELAY_TICKS 0x2e00 /* 479.17 µs */
22
23#define TAG_CIP 1
24
25#define CIP_EOH (1u << 31)
26#define CIP_FMT_AM (0x10 << 24)
27#define AMDTP_FDF_AM824 (0 << 19)
28#define AMDTP_FDF_SFC_SHIFT 16
29
30/* TODO: make these configurable */
31#define INTERRUPT_INTERVAL 16
32#define QUEUE_LENGTH 48
33
34/**
35 * amdtp_out_stream_init - initialize an AMDTP output stream structure
36 * @s: the AMDTP output stream to initialize
37 * @unit: the target of the stream
38 * @flags: the packet transmission method to use
39 */
40int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
41 enum cip_out_flags flags)
42{
43 if (flags != CIP_NONBLOCKING)
44 return -EINVAL;
45
46 s->unit = fw_unit_get(unit);
47 s->flags = flags;
48 s->context = ERR_PTR(-1);
49 mutex_init(&s->mutex);
50 s->packet_index = 0;
51
52 return 0;
53}
54EXPORT_SYMBOL(amdtp_out_stream_init);
55
56/**
57 * amdtp_out_stream_destroy - free stream resources
58 * @s: the AMDTP output stream to destroy
59 */
60void amdtp_out_stream_destroy(struct amdtp_out_stream *s)
61{
62 WARN_ON(!IS_ERR(s->context));
63 mutex_destroy(&s->mutex);
64 fw_unit_put(s->unit);
65}
66EXPORT_SYMBOL(amdtp_out_stream_destroy);
67
68/**
69 * amdtp_out_stream_set_rate - set the sample rate
70 * @s: the AMDTP output stream to configure
71 * @rate: the sample rate
72 *
73 * The sample rate must be set before the stream is started, and must not be
74 * changed while the stream is running.
75 */
76void amdtp_out_stream_set_rate(struct amdtp_out_stream *s, unsigned int rate)
77{
78 static const struct {
79 unsigned int rate;
80 unsigned int syt_interval;
81 } rate_info[] = {
82 [CIP_SFC_32000] = { 32000, 8, },
83 [CIP_SFC_44100] = { 44100, 8, },
84 [CIP_SFC_48000] = { 48000, 8, },
85 [CIP_SFC_88200] = { 88200, 16, },
86 [CIP_SFC_96000] = { 96000, 16, },
87 [CIP_SFC_176400] = { 176400, 32, },
88 [CIP_SFC_192000] = { 192000, 32, },
89 };
90 unsigned int sfc;
91
92 if (WARN_ON(!IS_ERR(s->context)))
93 return;
94
95 for (sfc = 0; sfc < ARRAY_SIZE(rate_info); ++sfc)
96 if (rate_info[sfc].rate == rate) {
97 s->sfc = sfc;
98 s->syt_interval = rate_info[sfc].syt_interval;
99 return;
100 }
101 WARN_ON(1);
102}
103EXPORT_SYMBOL(amdtp_out_stream_set_rate);
104
105/**
106 * amdtp_out_stream_get_max_payload - get the stream's packet size
107 * @s: the AMDTP output stream
108 *
109 * This function must not be called before the stream has been configured
110 * with amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
111 * amdtp_out_stream_set_midi().
112 */
113unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s)
114{
115 static const unsigned int max_data_blocks[] = {
116 [CIP_SFC_32000] = 4,
117 [CIP_SFC_44100] = 6,
118 [CIP_SFC_48000] = 6,
119 [CIP_SFC_88200] = 12,
120 [CIP_SFC_96000] = 12,
121 [CIP_SFC_176400] = 23,
122 [CIP_SFC_192000] = 24,
123 };
124
125 s->data_block_quadlets = s->pcm_channels;
126 s->data_block_quadlets += DIV_ROUND_UP(s->midi_ports, 8);
127
128 return 8 + max_data_blocks[s->sfc] * 4 * s->data_block_quadlets;
129}
130EXPORT_SYMBOL(amdtp_out_stream_get_max_payload);
131
132static void amdtp_write_s16(struct amdtp_out_stream *s,
133 struct snd_pcm_substream *pcm,
134 __be32 *buffer, unsigned int frames);
135static void amdtp_write_s32(struct amdtp_out_stream *s,
136 struct snd_pcm_substream *pcm,
137 __be32 *buffer, unsigned int frames);
138
139/**
140 * amdtp_out_stream_set_pcm_format - set the PCM format
141 * @s: the AMDTP output stream to configure
142 * @format: the format of the ALSA PCM device
143 *
144 * The sample format must be set before the stream is started, and must not be
145 * changed while the stream is running.
146 */
147void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
148 snd_pcm_format_t format)
149{
150 if (WARN_ON(!IS_ERR(s->context)))
151 return;
152
153 switch (format) {
154 default:
155 WARN_ON(1);
156 /* fall through */
157 case SNDRV_PCM_FORMAT_S16:
158 s->transfer_samples = amdtp_write_s16;
159 break;
160 case SNDRV_PCM_FORMAT_S32:
161 s->transfer_samples = amdtp_write_s32;
162 break;
163 }
164}
165EXPORT_SYMBOL(amdtp_out_stream_set_pcm_format);
166
167static unsigned int calculate_data_blocks(struct amdtp_out_stream *s)
168{
169 unsigned int phase, data_blocks;
170
171 if (!cip_sfc_is_base_44100(s->sfc)) {
172 /* Sample_rate / 8000 is an integer, and precomputed. */
173 data_blocks = s->data_block_state;
174 } else {
175 phase = s->data_block_state;
176
177 /*
178 * This calculates the number of data blocks per packet so that
179 * 1) the overall rate is correct and exactly synchronized to
180 * the bus clock, and
181 * 2) packets with a rounded-up number of blocks occur as early
182 * as possible in the sequence (to prevent underruns of the
183 * device's buffer).
184 */
185 if (s->sfc == CIP_SFC_44100)
186 /* 6 6 5 6 5 6 5 ... */
187 data_blocks = 5 + ((phase & 1) ^
188 (phase == 0 || phase >= 40));
189 else
190 /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */
191 data_blocks = 11 * (s->sfc >> 1) + (phase == 0);
192 if (++phase >= (80 >> (s->sfc >> 1)))
193 phase = 0;
194 s->data_block_state = phase;
195 }
196
197 return data_blocks;
198}
199
200static unsigned int calculate_syt(struct amdtp_out_stream *s,
201 unsigned int cycle)
202{
203 unsigned int syt_offset, phase, index, syt;
204
205 if (s->last_syt_offset < TICKS_PER_CYCLE) {
206 if (!cip_sfc_is_base_44100(s->sfc))
207 syt_offset = s->last_syt_offset + s->syt_offset_state;
208 else {
209 /*
210 * The time, in ticks, of the n'th SYT_INTERVAL sample is:
211 * n * SYT_INTERVAL * 24576000 / sample_rate
212 * Modulo TICKS_PER_CYCLE, the difference between successive
213 * elements is about 1386.23. Rounding the results of this
214 * formula to the SYT precision results in a sequence of
215 * differences that begins with:
216 * 1386 1386 1387 1386 1386 1386 1387 1386 1386 1386 1387 ...
217 * This code generates _exactly_ the same sequence.
218 */
219 phase = s->syt_offset_state;
220 index = phase % 13;
221 syt_offset = s->last_syt_offset;
222 syt_offset += 1386 + ((index && !(index & 3)) ||
223 phase == 146);
224 if (++phase >= 147)
225 phase = 0;
226 s->syt_offset_state = phase;
227 }
228 } else
229 syt_offset = s->last_syt_offset - TICKS_PER_CYCLE;
230 s->last_syt_offset = syt_offset;
231
232 if (syt_offset < TICKS_PER_CYCLE) {
233 syt_offset += TRANSFER_DELAY_TICKS - TICKS_PER_CYCLE;
234 syt = (cycle + syt_offset / TICKS_PER_CYCLE) << 12;
235 syt += syt_offset % TICKS_PER_CYCLE;
236
237 return syt & 0xffff;
238 } else {
239 return 0xffff; /* no info */
240 }
241}
242
243static void amdtp_write_s32(struct amdtp_out_stream *s,
244 struct snd_pcm_substream *pcm,
245 __be32 *buffer, unsigned int frames)
246{
247 struct snd_pcm_runtime *runtime = pcm->runtime;
248 unsigned int channels, remaining_frames, frame_step, i, c;
249 const u32 *src;
250
251 channels = s->pcm_channels;
252 src = (void *)runtime->dma_area +
253 s->pcm_buffer_pointer * (runtime->frame_bits / 8);
254 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
255 frame_step = s->data_block_quadlets - channels;
256
257 for (i = 0; i < frames; ++i) {
258 for (c = 0; c < channels; ++c) {
259 *buffer = cpu_to_be32((*src >> 8) | 0x40000000);
260 src++;
261 buffer++;
262 }
263 buffer += frame_step;
264 if (--remaining_frames == 0)
265 src = (void *)runtime->dma_area;
266 }
267}
268
269static void amdtp_write_s16(struct amdtp_out_stream *s,
270 struct snd_pcm_substream *pcm,
271 __be32 *buffer, unsigned int frames)
272{
273 struct snd_pcm_runtime *runtime = pcm->runtime;
274 unsigned int channels, remaining_frames, frame_step, i, c;
275 const u16 *src;
276
277 channels = s->pcm_channels;
278 src = (void *)runtime->dma_area +
279 s->pcm_buffer_pointer * (runtime->frame_bits / 8);
280 remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;
281 frame_step = s->data_block_quadlets - channels;
282
283 for (i = 0; i < frames; ++i) {
284 for (c = 0; c < channels; ++c) {
285 *buffer = cpu_to_be32((*src << 8) | 0x40000000);
286 src++;
287 buffer++;
288 }
289 buffer += frame_step;
290 if (--remaining_frames == 0)
291 src = (void *)runtime->dma_area;
292 }
293}
294
295static void amdtp_fill_pcm_silence(struct amdtp_out_stream *s,
296 __be32 *buffer, unsigned int frames)
297{
298 unsigned int i, c;
299
300 for (i = 0; i < frames; ++i) {
301 for (c = 0; c < s->pcm_channels; ++c)
302 buffer[c] = cpu_to_be32(0x40000000);
303 buffer += s->data_block_quadlets;
304 }
305}
306
307static void amdtp_fill_midi(struct amdtp_out_stream *s,
308 __be32 *buffer, unsigned int frames)
309{
310 unsigned int i;
311
312 for (i = 0; i < frames; ++i)
313 buffer[s->pcm_channels + i * s->data_block_quadlets] =
314 cpu_to_be32(0x80000000);
315}
316
317static void queue_out_packet(struct amdtp_out_stream *s, unsigned int cycle)
318{
319 __be32 *buffer;
320 unsigned int index, data_blocks, syt, ptr;
321 struct snd_pcm_substream *pcm;
322 struct fw_iso_packet packet;
323 int err;
324
325 if (s->packet_index < 0)
326 return;
327 index = s->packet_index;
328
329 data_blocks = calculate_data_blocks(s);
330 syt = calculate_syt(s, cycle);
331
332 buffer = s->buffer.packets[index].buffer;
333 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |
334 (s->data_block_quadlets << 16) |
335 s->data_block_counter);
336 buffer[1] = cpu_to_be32(CIP_EOH | CIP_FMT_AM | AMDTP_FDF_AM824 |
337 (s->sfc << AMDTP_FDF_SFC_SHIFT) | syt);
338 buffer += 2;
339
340 pcm = ACCESS_ONCE(s->pcm);
341 if (pcm)
342 s->transfer_samples(s, pcm, buffer, data_blocks);
343 else
344 amdtp_fill_pcm_silence(s, buffer, data_blocks);
345 if (s->midi_ports)
346 amdtp_fill_midi(s, buffer, data_blocks);
347
348 s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;
349
350 packet.payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;
351 packet.interrupt = IS_ALIGNED(index + 1, INTERRUPT_INTERVAL);
352 packet.skip = 0;
353 packet.tag = TAG_CIP;
354 packet.sy = 0;
355 packet.header_length = 0;
356
357 err = fw_iso_context_queue(s->context, &packet, &s->buffer.iso_buffer,
358 s->buffer.packets[index].offset);
359 if (err < 0) {
360 dev_err(&s->unit->device, "queueing error: %d\n", err);
361 s->packet_index = -1;
362 amdtp_out_stream_pcm_abort(s);
363 return;
364 }
365
366 if (++index >= QUEUE_LENGTH)
367 index = 0;
368 s->packet_index = index;
369
370 if (pcm) {
371 ptr = s->pcm_buffer_pointer + data_blocks;
372 if (ptr >= pcm->runtime->buffer_size)
373 ptr -= pcm->runtime->buffer_size;
374 ACCESS_ONCE(s->pcm_buffer_pointer) = ptr;
375
376 s->pcm_period_pointer += data_blocks;
377 if (s->pcm_period_pointer >= pcm->runtime->period_size) {
378 s->pcm_period_pointer -= pcm->runtime->period_size;
379 snd_pcm_period_elapsed(pcm);
380 }
381 }
382}
383
384static void out_packet_callback(struct fw_iso_context *context, u32 cycle,
385 size_t header_length, void *header, void *data)
386{
387 struct amdtp_out_stream *s = data;
388 unsigned int i, packets = header_length / 4;
389
390 /*
391 * Compute the cycle of the last queued packet.
392 * (We need only the four lowest bits for the SYT, so we can ignore
393 * that bits 0-11 must wrap around at 3072.)
394 */
395 cycle += QUEUE_LENGTH - packets;
396
397 for (i = 0; i < packets; ++i)
398 queue_out_packet(s, ++cycle);
399 fw_iso_context_queue_flush(s->context);
400}
401
402static int queue_initial_skip_packets(struct amdtp_out_stream *s)
403{
404 struct fw_iso_packet skip_packet = {
405 .skip = 1,
406 };
407 unsigned int i;
408 int err;
409
410 for (i = 0; i < QUEUE_LENGTH; ++i) {
411 skip_packet.interrupt = IS_ALIGNED(s->packet_index + 1,
412 INTERRUPT_INTERVAL);
413 err = fw_iso_context_queue(s->context, &skip_packet, NULL, 0);
414 if (err < 0)
415 return err;
416 if (++s->packet_index >= QUEUE_LENGTH)
417 s->packet_index = 0;
418 }
419
420 return 0;
421}
422
423/**
424 * amdtp_out_stream_start - start sending packets
425 * @s: the AMDTP output stream to start
426 * @channel: the isochronous channel on the bus
427 * @speed: firewire speed code
428 *
429 * The stream cannot be started until it has been configured with
430 * amdtp_out_stream_set_hw_params(), amdtp_out_stream_set_pcm(), and
431 * amdtp_out_stream_set_midi(); and it must be started before any
432 * PCM or MIDI device can be started.
433 */
434int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed)
435{
436 static const struct {
437 unsigned int data_block;
438 unsigned int syt_offset;
439 } initial_state[] = {
440 [CIP_SFC_32000] = { 4, 3072 },
441 [CIP_SFC_48000] = { 6, 1024 },
442 [CIP_SFC_96000] = { 12, 1024 },
443 [CIP_SFC_192000] = { 24, 1024 },
444 [CIP_SFC_44100] = { 0, 67 },
445 [CIP_SFC_88200] = { 0, 67 },
446 [CIP_SFC_176400] = { 0, 67 },
447 };
448 int err;
449
450 mutex_lock(&s->mutex);
451
452 if (WARN_ON(!IS_ERR(s->context) ||
453 (!s->pcm_channels && !s->midi_ports))) {
454 err = -EBADFD;
455 goto err_unlock;
456 }
457
458 s->data_block_state = initial_state[s->sfc].data_block;
459 s->syt_offset_state = initial_state[s->sfc].syt_offset;
460 s->last_syt_offset = TICKS_PER_CYCLE;
461
462 err = iso_packets_buffer_init(&s->buffer, s->unit, QUEUE_LENGTH,
463 amdtp_out_stream_get_max_payload(s),
464 DMA_TO_DEVICE);
465 if (err < 0)
466 goto err_unlock;
467
468 s->context = fw_iso_context_create(fw_parent_device(s->unit)->card,
469 FW_ISO_CONTEXT_TRANSMIT,
470 channel, speed, 0,
471 out_packet_callback, s);
472 if (IS_ERR(s->context)) {
473 err = PTR_ERR(s->context);
474 if (err == -EBUSY)
475 dev_err(&s->unit->device,
476 "no free output stream on this controller\n");
477 goto err_buffer;
478 }
479
480 amdtp_out_stream_update(s);
481
482 s->packet_index = 0;
483 s->data_block_counter = 0;
484 err = queue_initial_skip_packets(s);
485 if (err < 0)
486 goto err_context;
487
488 err = fw_iso_context_start(s->context, -1, 0, 0);
489 if (err < 0)
490 goto err_context;
491
492 mutex_unlock(&s->mutex);
493
494 return 0;
495
496err_context:
497 fw_iso_context_destroy(s->context);
498 s->context = ERR_PTR(-1);
499err_buffer:
500 iso_packets_buffer_destroy(&s->buffer, s->unit);
501err_unlock:
502 mutex_unlock(&s->mutex);
503
504 return err;
505}
506EXPORT_SYMBOL(amdtp_out_stream_start);
507
508/**
509 * amdtp_out_stream_update - update the stream after a bus reset
510 * @s: the AMDTP output stream
511 */
512void amdtp_out_stream_update(struct amdtp_out_stream *s)
513{
514 ACCESS_ONCE(s->source_node_id_field) =
515 (fw_parent_device(s->unit)->card->node_id & 0x3f) << 24;
516}
517EXPORT_SYMBOL(amdtp_out_stream_update);
518
519/**
520 * amdtp_out_stream_stop - stop sending packets
521 * @s: the AMDTP output stream to stop
522 *
523 * All PCM and MIDI devices of the stream must be stopped before the stream
524 * itself can be stopped.
525 */
526void amdtp_out_stream_stop(struct amdtp_out_stream *s)
527{
528 mutex_lock(&s->mutex);
529
530 if (IS_ERR(s->context)) {
531 mutex_unlock(&s->mutex);
532 return;
533 }
534
535 fw_iso_context_stop(s->context);
536 fw_iso_context_destroy(s->context);
537 s->context = ERR_PTR(-1);
538 iso_packets_buffer_destroy(&s->buffer, s->unit);
539
540 mutex_unlock(&s->mutex);
541}
542EXPORT_SYMBOL(amdtp_out_stream_stop);
543
544/**
545 * amdtp_out_stream_pcm_abort - abort the running PCM device
546 * @s: the AMDTP stream about to be stopped
547 *
548 * If the isochronous stream needs to be stopped asynchronously, call this
549 * function first to stop the PCM device.
550 */
551void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s)
552{
553 struct snd_pcm_substream *pcm;
554
555 pcm = ACCESS_ONCE(s->pcm);
556 if (pcm) {
557 snd_pcm_stream_lock_irq(pcm);
558 if (snd_pcm_running(pcm))
559 snd_pcm_stop(pcm, SNDRV_PCM_STATE_XRUN);
560 snd_pcm_stream_unlock_irq(pcm);
561 }
562}
563EXPORT_SYMBOL(amdtp_out_stream_pcm_abort);
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h
new file mode 100644
index 000000000000..537a9cb83581
--- /dev/null
+++ b/sound/firewire/amdtp.h
@@ -0,0 +1,169 @@
1#ifndef SOUND_FIREWIRE_AMDTP_H_INCLUDED
2#define SOUND_FIREWIRE_AMDTP_H_INCLUDED
3
4#include <linux/mutex.h>
5#include <linux/spinlock.h>
6#include "packets-buffer.h"
7
8/**
9 * enum cip_out_flags - describes details of the streaming protocol
10 * @CIP_NONBLOCKING: In non-blocking mode, each packet contains
11 * sample_rate/8000 samples, with rounding up or down to adjust
12 * for clock skew and left-over fractional samples. This should
13 * be used if supported by the device.
14 */
15enum cip_out_flags {
16 CIP_NONBLOCKING = 0,
17};
18
19/**
20 * enum cip_sfc - a stream's sample rate
21 */
22enum cip_sfc {
23 CIP_SFC_32000 = 0,
24 CIP_SFC_44100 = 1,
25 CIP_SFC_48000 = 2,
26 CIP_SFC_88200 = 3,
27 CIP_SFC_96000 = 4,
28 CIP_SFC_176400 = 5,
29 CIP_SFC_192000 = 6,
30};
31
32#define AMDTP_OUT_PCM_FORMAT_BITS (SNDRV_PCM_FMTBIT_S16 | \
33 SNDRV_PCM_FMTBIT_S32)
34
35struct fw_unit;
36struct fw_iso_context;
37struct snd_pcm_substream;
38
39struct amdtp_out_stream {
40 struct fw_unit *unit;
41 enum cip_out_flags flags;
42 struct fw_iso_context *context;
43 struct mutex mutex;
44
45 enum cip_sfc sfc;
46 unsigned int data_block_quadlets;
47 unsigned int pcm_channels;
48 unsigned int midi_ports;
49 void (*transfer_samples)(struct amdtp_out_stream *s,
50 struct snd_pcm_substream *pcm,
51 __be32 *buffer, unsigned int frames);
52
53 unsigned int syt_interval;
54 unsigned int source_node_id_field;
55 struct iso_packets_buffer buffer;
56
57 struct snd_pcm_substream *pcm;
58
59 int packet_index;
60 unsigned int data_block_counter;
61
62 unsigned int data_block_state;
63
64 unsigned int last_syt_offset;
65 unsigned int syt_offset_state;
66
67 unsigned int pcm_buffer_pointer;
68 unsigned int pcm_period_pointer;
69};
70
71int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit,
72 enum cip_out_flags flags);
73void amdtp_out_stream_destroy(struct amdtp_out_stream *s);
74
75void amdtp_out_stream_set_rate(struct amdtp_out_stream *s, unsigned int rate);
76unsigned int amdtp_out_stream_get_max_payload(struct amdtp_out_stream *s);
77
78int amdtp_out_stream_start(struct amdtp_out_stream *s, int channel, int speed);
79void amdtp_out_stream_update(struct amdtp_out_stream *s);
80void amdtp_out_stream_stop(struct amdtp_out_stream *s);
81
82void amdtp_out_stream_set_pcm_format(struct amdtp_out_stream *s,
83 snd_pcm_format_t format);
84void amdtp_out_stream_pcm_abort(struct amdtp_out_stream *s);
85
86/**
87 * amdtp_out_stream_set_pcm - configure format of PCM samples
88 * @s: the AMDTP output stream to be configured
89 * @pcm_channels: the number of PCM samples in each data block, to be encoded
90 * as AM824 multi-bit linear audio
91 *
92 * This function must not be called while the stream is running.
93 */
94static inline void amdtp_out_stream_set_pcm(struct amdtp_out_stream *s,
95 unsigned int pcm_channels)
96{
97 s->pcm_channels = pcm_channels;
98}
99
100/**
101 * amdtp_out_stream_set_midi - configure format of MIDI data
102 * @s: the AMDTP output stream to be configured
103 * @midi_ports: the number of MIDI ports (i.e., MPX-MIDI Data Channels)
104 *
105 * This function must not be called while the stream is running.
106 */
107static inline void amdtp_out_stream_set_midi(struct amdtp_out_stream *s,
108 unsigned int midi_ports)
109{
110 s->midi_ports = midi_ports;
111}
112
113/**
114 * amdtp_out_streaming_error - check for streaming error
115 * @s: the AMDTP output stream
116 *
117 * If this function returns true, the stream's packet queue has stopped due to
118 * an asynchronous error.
119 */
120static inline bool amdtp_out_streaming_error(struct amdtp_out_stream *s)
121{
122 return s->packet_index < 0;
123}
124
125/**
126 * amdtp_out_stream_pcm_prepare - prepare PCM device for running
127 * @s: the AMDTP output stream
128 *
129 * This function should be called from the PCM device's .prepare callback.
130 */
131static inline void amdtp_out_stream_pcm_prepare(struct amdtp_out_stream *s)
132{
133 s->pcm_buffer_pointer = 0;
134 s->pcm_period_pointer = 0;
135}
136
137/**
138 * amdtp_out_stream_pcm_trigger - start/stop playback from a PCM device
139 * @s: the AMDTP output stream
140 * @pcm: the PCM device to be started, or %NULL to stop the current device
141 *
142 * Call this function on a running isochronous stream to enable the actual
143 * transmission of PCM data. This function should be called from the PCM
144 * device's .trigger callback.
145 */
146static inline void amdtp_out_stream_pcm_trigger(struct amdtp_out_stream *s,
147 struct snd_pcm_substream *pcm)
148{
149 ACCESS_ONCE(s->pcm) = pcm;
150}
151
152/**
153 * amdtp_out_stream_pcm_pointer - get the PCM buffer position
154 * @s: the AMDTP output stream that transports the PCM data
155 *
156 * Returns the current buffer position, in frames.
157 */
158static inline unsigned long
159amdtp_out_stream_pcm_pointer(struct amdtp_out_stream *s)
160{
161 return ACCESS_ONCE(s->pcm_buffer_pointer);
162}
163
164static inline bool cip_sfc_is_base_44100(enum cip_sfc sfc)
165{
166 return sfc & 1;
167}
168
169#endif
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c
new file mode 100644
index 000000000000..14cacbc655dd
--- /dev/null
+++ b/sound/firewire/cmp.c
@@ -0,0 +1,307 @@
1/*
2 * Connection Management Procedures (IEC 61883-1) helper functions
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/module.h>
12#include <linux/sched.h>
13#include "lib.h"
14#include "iso-resources.h"
15#include "cmp.h"
16
17#define IMPR_SPEED_MASK 0xc0000000
18#define IMPR_SPEED_SHIFT 30
19#define IMPR_XSPEED_MASK 0x00000060
20#define IMPR_XSPEED_SHIFT 5
21#define IMPR_PLUGS_MASK 0x0000001f
22
23#define IPCR_ONLINE 0x80000000
24#define IPCR_BCAST_CONN 0x40000000
25#define IPCR_P2P_CONN_MASK 0x3f000000
26#define IPCR_P2P_CONN_SHIFT 24
27#define IPCR_CHANNEL_MASK 0x003f0000
28#define IPCR_CHANNEL_SHIFT 16
29
30enum bus_reset_handling {
31 ABORT_ON_BUS_RESET,
32 SUCCEED_ON_BUS_RESET,
33};
34
35static __attribute__((format(printf, 2, 3)))
36void cmp_error(struct cmp_connection *c, const char *fmt, ...)
37{
38 va_list va;
39
40 va_start(va, fmt);
41 dev_err(&c->resources.unit->device, "%cPCR%u: %pV",
42 'i', c->pcr_index, &(struct va_format){ fmt, &va });
43 va_end(va);
44}
45
46static int pcr_modify(struct cmp_connection *c,
47 __be32 (*modify)(struct cmp_connection *c, __be32 old),
48 int (*check)(struct cmp_connection *c, __be32 pcr),
49 enum bus_reset_handling bus_reset_handling)
50{
51 struct fw_device *device = fw_parent_device(c->resources.unit);
52 int generation = c->resources.generation;
53 int rcode, errors = 0;
54 __be32 old_arg, buffer[2];
55 int err;
56
57 buffer[0] = c->last_pcr_value;
58 for (;;) {
59 old_arg = buffer[0];
60 buffer[1] = modify(c, buffer[0]);
61
62 rcode = fw_run_transaction(
63 device->card, TCODE_LOCK_COMPARE_SWAP,
64 device->node_id, generation, device->max_speed,
65 CSR_REGISTER_BASE + CSR_IPCR(c->pcr_index),
66 buffer, 8);
67
68 if (rcode == RCODE_COMPLETE) {
69 if (buffer[0] == old_arg) /* success? */
70 break;
71
72 if (check) {
73 err = check(c, buffer[0]);
74 if (err < 0)
75 return err;
76 }
77 } else if (rcode == RCODE_GENERATION)
78 goto bus_reset;
79 else if (rcode_is_permanent_error(rcode) || ++errors >= 3)
80 goto io_error;
81 }
82 c->last_pcr_value = buffer[1];
83
84 return 0;
85
86io_error:
87 cmp_error(c, "transaction failed: %s\n", rcode_string(rcode));
88 return -EIO;
89
90bus_reset:
91 return bus_reset_handling == ABORT_ON_BUS_RESET ? -EAGAIN : 0;
92}
93
94
95/**
96 * cmp_connection_init - initializes a connection manager
97 * @c: the connection manager to initialize
98 * @unit: a unit of the target device
99 * @ipcr_index: the index of the iPCR on the target device
100 */
101int cmp_connection_init(struct cmp_connection *c,
102 struct fw_unit *unit,
103 unsigned int ipcr_index)
104{
105 __be32 impr_be;
106 u32 impr;
107 int err;
108
109 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
110 CSR_REGISTER_BASE + CSR_IMPR,
111 &impr_be, 4);
112 if (err < 0)
113 return err;
114 impr = be32_to_cpu(impr_be);
115
116 if (ipcr_index >= (impr & IMPR_PLUGS_MASK))
117 return -EINVAL;
118
119 err = fw_iso_resources_init(&c->resources, unit);
120 if (err < 0)
121 return err;
122
123 c->connected = false;
124 mutex_init(&c->mutex);
125 c->last_pcr_value = cpu_to_be32(0x80000000);
126 c->pcr_index = ipcr_index;
127 c->max_speed = (impr & IMPR_SPEED_MASK) >> IMPR_SPEED_SHIFT;
128 if (c->max_speed == SCODE_BETA)
129 c->max_speed += (impr & IMPR_XSPEED_MASK) >> IMPR_XSPEED_SHIFT;
130
131 return 0;
132}
133EXPORT_SYMBOL(cmp_connection_init);
134
135/**
136 * cmp_connection_destroy - free connection manager resources
137 * @c: the connection manager
138 */
139void cmp_connection_destroy(struct cmp_connection *c)
140{
141 WARN_ON(c->connected);
142 mutex_destroy(&c->mutex);
143 fw_iso_resources_destroy(&c->resources);
144}
145EXPORT_SYMBOL(cmp_connection_destroy);
146
147
148static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr)
149{
150 ipcr &= ~cpu_to_be32(IPCR_BCAST_CONN |
151 IPCR_P2P_CONN_MASK |
152 IPCR_CHANNEL_MASK);
153 ipcr |= cpu_to_be32(1 << IPCR_P2P_CONN_SHIFT);
154 ipcr |= cpu_to_be32(c->resources.channel << IPCR_CHANNEL_SHIFT);
155
156 return ipcr;
157}
158
159static int ipcr_set_check(struct cmp_connection *c, __be32 ipcr)
160{
161 if (ipcr & cpu_to_be32(IPCR_BCAST_CONN |
162 IPCR_P2P_CONN_MASK)) {
163 cmp_error(c, "plug is already in use\n");
164 return -EBUSY;
165 }
166 if (!(ipcr & cpu_to_be32(IPCR_ONLINE))) {
167 cmp_error(c, "plug is not on-line\n");
168 return -ECONNREFUSED;
169 }
170
171 return 0;
172}
173
174/**
175 * cmp_connection_establish - establish a connection to the target
176 * @c: the connection manager
177 * @max_payload_bytes: the amount of data (including CIP headers) per packet
178 *
179 * This function establishes a point-to-point connection from the local
180 * computer to the target by allocating isochronous resources (channel and
181 * bandwidth) and setting the target's input plug control register. When this
182 * function succeeds, the caller is responsible for starting transmitting
183 * packets.
184 */
185int cmp_connection_establish(struct cmp_connection *c,
186 unsigned int max_payload_bytes)
187{
188 int err;
189
190 if (WARN_ON(c->connected))
191 return -EISCONN;
192
193 c->speed = min(c->max_speed,
194 fw_parent_device(c->resources.unit)->max_speed);
195
196 mutex_lock(&c->mutex);
197
198retry_after_bus_reset:
199 err = fw_iso_resources_allocate(&c->resources,
200 max_payload_bytes, c->speed);
201 if (err < 0)
202 goto err_mutex;
203
204 err = pcr_modify(c, ipcr_set_modify, ipcr_set_check,
205 ABORT_ON_BUS_RESET);
206 if (err == -EAGAIN) {
207 fw_iso_resources_free(&c->resources);
208 goto retry_after_bus_reset;
209 }
210 if (err < 0)
211 goto err_resources;
212
213 c->connected = true;
214
215 mutex_unlock(&c->mutex);
216
217 return 0;
218
219err_resources:
220 fw_iso_resources_free(&c->resources);
221err_mutex:
222 mutex_unlock(&c->mutex);
223
224 return err;
225}
226EXPORT_SYMBOL(cmp_connection_establish);
227
228/**
229 * cmp_connection_update - update the connection after a bus reset
230 * @c: the connection manager
231 *
232 * This function must be called from the driver's .update handler to reestablish
233 * any connection that might have been active.
234 *
235 * Returns zero on success, or a negative error code. On an error, the
236 * connection is broken and the caller must stop transmitting iso packets.
237 */
238int cmp_connection_update(struct cmp_connection *c)
239{
240 int err;
241
242 mutex_lock(&c->mutex);
243
244 if (!c->connected) {
245 mutex_unlock(&c->mutex);
246 return 0;
247 }
248
249 err = fw_iso_resources_update(&c->resources);
250 if (err < 0)
251 goto err_unconnect;
252
253 err = pcr_modify(c, ipcr_set_modify, ipcr_set_check,
254 SUCCEED_ON_BUS_RESET);
255 if (err < 0)
256 goto err_resources;
257
258 mutex_unlock(&c->mutex);
259
260 return 0;
261
262err_resources:
263 fw_iso_resources_free(&c->resources);
264err_unconnect:
265 c->connected = false;
266 mutex_unlock(&c->mutex);
267
268 return err;
269}
270EXPORT_SYMBOL(cmp_connection_update);
271
272
273static __be32 ipcr_break_modify(struct cmp_connection *c, __be32 ipcr)
274{
275 return ipcr & ~cpu_to_be32(IPCR_BCAST_CONN | IPCR_P2P_CONN_MASK);
276}
277
278/**
279 * cmp_connection_break - break the connection to the target
280 * @c: the connection manager
281 *
282 * This function deactives the connection in the target's input plug control
283 * register, and frees the isochronous resources of the connection. Before
284 * calling this function, the caller should cease transmitting packets.
285 */
286void cmp_connection_break(struct cmp_connection *c)
287{
288 int err;
289
290 mutex_lock(&c->mutex);
291
292 if (!c->connected) {
293 mutex_unlock(&c->mutex);
294 return;
295 }
296
297 err = pcr_modify(c, ipcr_break_modify, NULL, SUCCEED_ON_BUS_RESET);
298 if (err < 0)
299 cmp_error(c, "plug is still connected\n");
300
301 fw_iso_resources_free(&c->resources);
302
303 c->connected = false;
304
305 mutex_unlock(&c->mutex);
306}
307EXPORT_SYMBOL(cmp_connection_break);
diff --git a/sound/firewire/cmp.h b/sound/firewire/cmp.h
new file mode 100644
index 000000000000..f47de08feb12
--- /dev/null
+++ b/sound/firewire/cmp.h
@@ -0,0 +1,41 @@
1#ifndef SOUND_FIREWIRE_CMP_H_INCLUDED
2#define SOUND_FIREWIRE_CMP_H_INCLUDED
3
4#include <linux/mutex.h>
5#include <linux/types.h>
6#include "iso-resources.h"
7
8struct fw_unit;
9
10/**
11 * struct cmp_connection - manages an isochronous connection to a device
12 * @speed: the connection's actual speed
13 *
14 * This structure manages (using CMP) an isochronous stream from the local
15 * computer to a device's input plug (iPCR).
16 *
17 * There is no corresponding oPCR created on the local computer, so it is not
18 * possible to overlay connections on top of this one.
19 */
20struct cmp_connection {
21 int speed;
22 /* private: */
23 bool connected;
24 struct mutex mutex;
25 struct fw_iso_resources resources;
26 __be32 last_pcr_value;
27 unsigned int pcr_index;
28 unsigned int max_speed;
29};
30
31int cmp_connection_init(struct cmp_connection *connection,
32 struct fw_unit *unit,
33 unsigned int ipcr_index);
34void cmp_connection_destroy(struct cmp_connection *connection);
35
36int cmp_connection_establish(struct cmp_connection *connection,
37 unsigned int max_payload);
38int cmp_connection_update(struct cmp_connection *connection);
39void cmp_connection_break(struct cmp_connection *connection);
40
41#endif
diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c
new file mode 100644
index 000000000000..ec578b5ad8da
--- /dev/null
+++ b/sound/firewire/fcp.c
@@ -0,0 +1,224 @@
1/*
2 * Function Control Protocol (IEC 61883-1) helper functions
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/list.h>
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/spinlock.h>
15#include <linux/wait.h>
16#include <linux/delay.h>
17#include "fcp.h"
18#include "lib.h"
19
20#define CTS_AVC 0x00
21
22#define ERROR_RETRIES 3
23#define ERROR_DELAY_MS 5
24#define FCP_TIMEOUT_MS 125
25
26static DEFINE_SPINLOCK(transactions_lock);
27static LIST_HEAD(transactions);
28
29enum fcp_state {
30 STATE_PENDING,
31 STATE_BUS_RESET,
32 STATE_COMPLETE,
33};
34
35struct fcp_transaction {
36 struct list_head list;
37 struct fw_unit *unit;
38 void *response_buffer;
39 unsigned int response_size;
40 unsigned int response_match_bytes;
41 enum fcp_state state;
42 wait_queue_head_t wait;
43};
44
45/**
46 * fcp_avc_transaction - send an AV/C command and wait for its response
47 * @unit: a unit on the target device
48 * @command: a buffer containing the command frame; must be DMA-able
49 * @command_size: the size of @command
50 * @response: a buffer for the response frame
51 * @response_size: the maximum size of @response
52 * @response_match_bytes: a bitmap specifying the bytes used to detect the
53 * correct response frame
54 *
55 * This function sends a FCP command frame to the target and waits for the
56 * corresponding response frame to be returned.
57 *
58 * Because it is possible for multiple FCP transactions to be active at the
59 * same time, the correct response frame is detected by the value of certain
60 * bytes. These bytes must be set in @response before calling this function,
61 * and the corresponding bits must be set in @response_match_bytes.
62 *
63 * @command and @response can point to the same buffer.
64 *
65 * Asynchronous operation (INTERIM, NOTIFY) is not supported at the moment.
66 *
67 * Returns the actual size of the response frame, or a negative error code.
68 */
69int fcp_avc_transaction(struct fw_unit *unit,
70 const void *command, unsigned int command_size,
71 void *response, unsigned int response_size,
72 unsigned int response_match_bytes)
73{
74 struct fcp_transaction t;
75 int tcode, ret, tries = 0;
76
77 t.unit = unit;
78 t.response_buffer = response;
79 t.response_size = response_size;
80 t.response_match_bytes = response_match_bytes;
81 t.state = STATE_PENDING;
82 init_waitqueue_head(&t.wait);
83
84 spin_lock_irq(&transactions_lock);
85 list_add_tail(&t.list, &transactions);
86 spin_unlock_irq(&transactions_lock);
87
88 for (;;) {
89 tcode = command_size == 4 ? TCODE_WRITE_QUADLET_REQUEST
90 : TCODE_WRITE_BLOCK_REQUEST;
91 ret = snd_fw_transaction(t.unit, tcode,
92 CSR_REGISTER_BASE + CSR_FCP_COMMAND,
93 (void *)command, command_size);
94 if (ret < 0)
95 break;
96
97 wait_event_timeout(t.wait, t.state != STATE_PENDING,
98 msecs_to_jiffies(FCP_TIMEOUT_MS));
99
100 if (t.state == STATE_COMPLETE) {
101 ret = t.response_size;
102 break;
103 } else if (t.state == STATE_BUS_RESET) {
104 msleep(ERROR_DELAY_MS);
105 } else if (++tries >= ERROR_RETRIES) {
106 dev_err(&t.unit->device, "FCP command timed out\n");
107 ret = -EIO;
108 break;
109 }
110 }
111
112 spin_lock_irq(&transactions_lock);
113 list_del(&t.list);
114 spin_unlock_irq(&transactions_lock);
115
116 return ret;
117}
118EXPORT_SYMBOL(fcp_avc_transaction);
119
120/**
121 * fcp_bus_reset - inform the target handler about a bus reset
122 * @unit: the unit that might be used by fcp_avc_transaction()
123 *
124 * This function must be called from the driver's .update handler to inform
125 * the FCP transaction handler that a bus reset has happened. Any pending FCP
126 * transactions are retried.
127 */
128void fcp_bus_reset(struct fw_unit *unit)
129{
130 struct fcp_transaction *t;
131
132 spin_lock_irq(&transactions_lock);
133 list_for_each_entry(t, &transactions, list) {
134 if (t->unit == unit &&
135 t->state == STATE_PENDING) {
136 t->state = STATE_BUS_RESET;
137 wake_up(&t->wait);
138 }
139 }
140 spin_unlock_irq(&transactions_lock);
141}
142EXPORT_SYMBOL(fcp_bus_reset);
143
144/* checks whether the response matches the masked bytes in response_buffer */
145static bool is_matching_response(struct fcp_transaction *transaction,
146 const void *response, size_t length)
147{
148 const u8 *p1, *p2;
149 unsigned int mask, i;
150
151 p1 = response;
152 p2 = transaction->response_buffer;
153 mask = transaction->response_match_bytes;
154
155 for (i = 0; ; ++i) {
156 if ((mask & 1) && p1[i] != p2[i])
157 return false;
158 mask >>= 1;
159 if (!mask)
160 return true;
161 if (--length == 0)
162 return false;
163 }
164}
165
166static void fcp_response(struct fw_card *card, struct fw_request *request,
167 int tcode, int destination, int source,
168 int generation, unsigned long long offset,
169 void *data, size_t length, void *callback_data)
170{
171 struct fcp_transaction *t;
172 unsigned long flags;
173
174 if (length < 1 || (*(const u8 *)data & 0xf0) != CTS_AVC)
175 return;
176
177 spin_lock_irqsave(&transactions_lock, flags);
178 list_for_each_entry(t, &transactions, list) {
179 struct fw_device *device = fw_parent_device(t->unit);
180 if (device->card != card ||
181 device->generation != generation)
182 continue;
183 smp_rmb(); /* node_id vs. generation */
184 if (device->node_id != source)
185 continue;
186
187 if (t->state == STATE_PENDING &&
188 is_matching_response(t, data, length)) {
189 t->state = STATE_COMPLETE;
190 t->response_size = min((unsigned int)length,
191 t->response_size);
192 memcpy(t->response_buffer, data, t->response_size);
193 wake_up(&t->wait);
194 }
195 }
196 spin_unlock_irqrestore(&transactions_lock, flags);
197}
198
199static struct fw_address_handler response_register_handler = {
200 .length = 0x200,
201 .address_callback = fcp_response,
202};
203
204static int __init fcp_module_init(void)
205{
206 static const struct fw_address_region response_register_region = {
207 .start = CSR_REGISTER_BASE + CSR_FCP_RESPONSE,
208 .end = CSR_REGISTER_BASE + CSR_FCP_END,
209 };
210
211 fw_core_add_address_handler(&response_register_handler,
212 &response_register_region);
213
214 return 0;
215}
216
217static void __exit fcp_module_exit(void)
218{
219 WARN_ON(!list_empty(&transactions));
220 fw_core_remove_address_handler(&response_register_handler);
221}
222
223module_init(fcp_module_init);
224module_exit(fcp_module_exit);
diff --git a/sound/firewire/fcp.h b/sound/firewire/fcp.h
new file mode 100644
index 000000000000..86595688bd91
--- /dev/null
+++ b/sound/firewire/fcp.h
@@ -0,0 +1,12 @@
1#ifndef SOUND_FIREWIRE_FCP_H_INCLUDED
2#define SOUND_FIREWIRE_FCP_H_INCLUDED
3
4struct fw_unit;
5
6int fcp_avc_transaction(struct fw_unit *unit,
7 const void *command, unsigned int command_size,
8 void *response, unsigned int response_size,
9 unsigned int response_match_bytes);
10void fcp_bus_reset(struct fw_unit *unit);
11
12#endif
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
new file mode 100644
index 000000000000..440030818db7
--- /dev/null
+++ b/sound/firewire/isight.c
@@ -0,0 +1,756 @@
1/*
2 * Apple iSight audio driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <asm/byteorder.h>
9#include <linux/delay.h>
10#include <linux/device.h>
11#include <linux/firewire.h>
12#include <linux/firewire-constants.h>
13#include <linux/module.h>
14#include <linux/mod_devicetable.h>
15#include <linux/mutex.h>
16#include <linux/string.h>
17#include <sound/control.h>
18#include <sound/core.h>
19#include <sound/initval.h>
20#include <sound/pcm.h>
21#include <sound/tlv.h>
22#include "lib.h"
23#include "iso-resources.h"
24#include "packets-buffer.h"
25
26#define OUI_APPLE 0x000a27
27#define MODEL_APPLE_ISIGHT 0x000008
28#define SW_ISIGHT_AUDIO 0x000010
29
30#define REG_AUDIO_ENABLE 0x000
31#define AUDIO_ENABLE 0x80000000
32#define REG_DEF_AUDIO_GAIN 0x204
33#define REG_GAIN_RAW_START 0x210
34#define REG_GAIN_RAW_END 0x214
35#define REG_GAIN_DB_START 0x218
36#define REG_GAIN_DB_END 0x21c
37#define REG_SAMPLE_RATE_INQUIRY 0x280
38#define REG_ISO_TX_CONFIG 0x300
39#define SPEED_SHIFT 16
40#define REG_SAMPLE_RATE 0x400
41#define RATE_48000 0x80000000
42#define REG_GAIN 0x500
43#define REG_MUTE 0x504
44
45#define MAX_FRAMES_PER_PACKET 475
46
47#define QUEUE_LENGTH 20
48
49struct isight {
50 struct snd_card *card;
51 struct fw_unit *unit;
52 struct fw_device *device;
53 u64 audio_base;
54 struct fw_address_handler iris_handler;
55 struct snd_pcm_substream *pcm;
56 struct mutex mutex;
57 struct iso_packets_buffer buffer;
58 struct fw_iso_resources resources;
59 struct fw_iso_context *context;
60 bool pcm_active;
61 bool pcm_running;
62 bool first_packet;
63 int packet_index;
64 u32 total_samples;
65 unsigned int buffer_pointer;
66 unsigned int period_counter;
67 s32 gain_min, gain_max;
68 unsigned int gain_tlv[4];
69};
70
71struct audio_payload {
72 __be32 sample_count;
73 __be32 signature;
74 __be32 sample_total;
75 __be32 reserved;
76 __be16 samples[2 * MAX_FRAMES_PER_PACKET];
77};
78
79MODULE_DESCRIPTION("iSight audio driver");
80MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
81MODULE_LICENSE("GPL v2");
82
83static struct fw_iso_packet audio_packet = {
84 .payload_length = sizeof(struct audio_payload),
85 .interrupt = 1,
86 .header_length = 4,
87};
88
89static void isight_update_pointers(struct isight *isight, unsigned int count)
90{
91 struct snd_pcm_runtime *runtime = isight->pcm->runtime;
92 unsigned int ptr;
93
94 smp_wmb(); /* update buffer data before buffer pointer */
95
96 ptr = isight->buffer_pointer;
97 ptr += count;
98 if (ptr >= runtime->buffer_size)
99 ptr -= runtime->buffer_size;
100 ACCESS_ONCE(isight->buffer_pointer) = ptr;
101
102 isight->period_counter += count;
103 if (isight->period_counter >= runtime->period_size) {
104 isight->period_counter -= runtime->period_size;
105 snd_pcm_period_elapsed(isight->pcm);
106 }
107}
108
109static void isight_samples(struct isight *isight,
110 const __be16 *samples, unsigned int count)
111{
112 struct snd_pcm_runtime *runtime;
113 unsigned int count1;
114
115 if (!ACCESS_ONCE(isight->pcm_running))
116 return;
117
118 runtime = isight->pcm->runtime;
119 if (isight->buffer_pointer + count <= runtime->buffer_size) {
120 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
121 samples, count * 4);
122 } else {
123 count1 = runtime->buffer_size - isight->buffer_pointer;
124 memcpy(runtime->dma_area + isight->buffer_pointer * 4,
125 samples, count1 * 4);
126 samples += count1 * 2;
127 memcpy(runtime->dma_area, samples, (count - count1) * 4);
128 }
129
130 isight_update_pointers(isight, count);
131}
132
133static void isight_pcm_abort(struct isight *isight)
134{
135 unsigned long flags;
136
137 if (ACCESS_ONCE(isight->pcm_active)) {
138 snd_pcm_stream_lock_irqsave(isight->pcm, flags);
139 if (snd_pcm_running(isight->pcm))
140 snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN);
141 snd_pcm_stream_unlock_irqrestore(isight->pcm, flags);
142 }
143}
144
145static void isight_dropped_samples(struct isight *isight, unsigned int total)
146{
147 struct snd_pcm_runtime *runtime;
148 u32 dropped;
149 unsigned int count1;
150
151 if (!ACCESS_ONCE(isight->pcm_running))
152 return;
153
154 runtime = isight->pcm->runtime;
155 dropped = total - isight->total_samples;
156 if (dropped < runtime->buffer_size) {
157 if (isight->buffer_pointer + dropped <= runtime->buffer_size) {
158 memset(runtime->dma_area + isight->buffer_pointer * 4,
159 0, dropped * 4);
160 } else {
161 count1 = runtime->buffer_size - isight->buffer_pointer;
162 memset(runtime->dma_area + isight->buffer_pointer * 4,
163 0, count1 * 4);
164 memset(runtime->dma_area, 0, (dropped - count1) * 4);
165 }
166 isight_update_pointers(isight, dropped);
167 } else {
168 isight_pcm_abort(isight);
169 }
170}
171
172static void isight_packet(struct fw_iso_context *context, u32 cycle,
173 size_t header_length, void *header, void *data)
174{
175 struct isight *isight = data;
176 const struct audio_payload *payload;
177 unsigned int index, length, count, total;
178 int err;
179
180 if (isight->packet_index < 0)
181 return;
182 index = isight->packet_index;
183 payload = isight->buffer.packets[index].buffer;
184 length = be32_to_cpup(header) >> 16;
185
186 if (likely(length >= 16 &&
187 payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
188 count = be32_to_cpu(payload->sample_count);
189 if (likely(count <= (length - 16) / 4)) {
190 total = be32_to_cpu(payload->sample_total);
191 if (unlikely(total != isight->total_samples)) {
192 if (!isight->first_packet)
193 isight_dropped_samples(isight, total);
194 isight->first_packet = false;
195 isight->total_samples = total;
196 }
197
198 isight_samples(isight, payload->samples, count);
199 isight->total_samples += count;
200 }
201 }
202
203 err = fw_iso_context_queue(isight->context, &audio_packet,
204 &isight->buffer.iso_buffer,
205 isight->buffer.packets[index].offset);
206 if (err < 0) {
207 dev_err(&isight->unit->device, "queueing error: %d\n", err);
208 isight_pcm_abort(isight);
209 isight->packet_index = -1;
210 return;
211 }
212 fw_iso_context_queue_flush(isight->context);
213
214 if (++index >= QUEUE_LENGTH)
215 index = 0;
216 isight->packet_index = index;
217}
218
219static int isight_connect(struct isight *isight)
220{
221 int ch, err, rcode, errors = 0;
222 __be32 value;
223
224retry_after_bus_reset:
225 ch = fw_iso_resources_allocate(&isight->resources,
226 sizeof(struct audio_payload),
227 isight->device->max_speed);
228 if (ch < 0) {
229 err = ch;
230 goto error;
231 }
232
233 value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT));
234 for (;;) {
235 rcode = fw_run_transaction(
236 isight->device->card,
237 TCODE_WRITE_QUADLET_REQUEST,
238 isight->device->node_id,
239 isight->resources.generation,
240 isight->device->max_speed,
241 isight->audio_base + REG_ISO_TX_CONFIG,
242 &value, 4);
243 if (rcode == RCODE_COMPLETE) {
244 return 0;
245 } else if (rcode == RCODE_GENERATION) {
246 fw_iso_resources_free(&isight->resources);
247 goto retry_after_bus_reset;
248 } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
249 err = -EIO;
250 goto err_resources;
251 }
252 msleep(5);
253 }
254
255err_resources:
256 fw_iso_resources_free(&isight->resources);
257error:
258 return err;
259}
260
261static int isight_open(struct snd_pcm_substream *substream)
262{
263 static const struct snd_pcm_hardware hardware = {
264 .info = SNDRV_PCM_INFO_MMAP |
265 SNDRV_PCM_INFO_MMAP_VALID |
266 SNDRV_PCM_INFO_BATCH |
267 SNDRV_PCM_INFO_INTERLEAVED |
268 SNDRV_PCM_INFO_BLOCK_TRANSFER,
269 .formats = SNDRV_PCM_FMTBIT_S16_BE,
270 .rates = SNDRV_PCM_RATE_48000,
271 .rate_min = 48000,
272 .rate_max = 48000,
273 .channels_min = 2,
274 .channels_max = 2,
275 .buffer_bytes_max = 4 * 1024 * 1024,
276 .period_bytes_min = MAX_FRAMES_PER_PACKET * 4,
277 .period_bytes_max = 1024 * 1024,
278 .periods_min = 2,
279 .periods_max = UINT_MAX,
280 };
281 struct isight *isight = substream->private_data;
282
283 substream->runtime->hw = hardware;
284
285 return iso_packets_buffer_init(&isight->buffer, isight->unit,
286 QUEUE_LENGTH,
287 sizeof(struct audio_payload),
288 DMA_FROM_DEVICE);
289}
290
291static int isight_close(struct snd_pcm_substream *substream)
292{
293 struct isight *isight = substream->private_data;
294
295 iso_packets_buffer_destroy(&isight->buffer, isight->unit);
296
297 return 0;
298}
299
300static int isight_hw_params(struct snd_pcm_substream *substream,
301 struct snd_pcm_hw_params *hw_params)
302{
303 struct isight *isight = substream->private_data;
304 int err;
305
306 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
307 params_buffer_bytes(hw_params));
308 if (err < 0)
309 return err;
310
311 ACCESS_ONCE(isight->pcm_active) = true;
312
313 return 0;
314}
315
316static int reg_read(struct isight *isight, int offset, __be32 *value)
317{
318 return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST,
319 isight->audio_base + offset, value, 4);
320}
321
322static int reg_write(struct isight *isight, int offset, __be32 value)
323{
324 return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST,
325 isight->audio_base + offset, &value, 4);
326}
327
328static void isight_stop_streaming(struct isight *isight)
329{
330 if (!isight->context)
331 return;
332
333 fw_iso_context_stop(isight->context);
334 fw_iso_context_destroy(isight->context);
335 isight->context = NULL;
336 fw_iso_resources_free(&isight->resources);
337 reg_write(isight, REG_AUDIO_ENABLE, 0);
338}
339
340static int isight_hw_free(struct snd_pcm_substream *substream)
341{
342 struct isight *isight = substream->private_data;
343
344 ACCESS_ONCE(isight->pcm_active) = false;
345
346 mutex_lock(&isight->mutex);
347 isight_stop_streaming(isight);
348 mutex_unlock(&isight->mutex);
349
350 return snd_pcm_lib_free_vmalloc_buffer(substream);
351}
352
353static int isight_start_streaming(struct isight *isight)
354{
355 unsigned int i;
356 int err;
357
358 if (isight->context) {
359 if (isight->packet_index < 0)
360 isight_stop_streaming(isight);
361 else
362 return 0;
363 }
364
365 err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000));
366 if (err < 0)
367 goto error;
368
369 err = isight_connect(isight);
370 if (err < 0)
371 goto error;
372
373 err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE));
374 if (err < 0)
375 goto err_resources;
376
377 isight->context = fw_iso_context_create(isight->device->card,
378 FW_ISO_CONTEXT_RECEIVE,
379 isight->resources.channel,
380 isight->device->max_speed,
381 4, isight_packet, isight);
382 if (IS_ERR(isight->context)) {
383 err = PTR_ERR(isight->context);
384 isight->context = NULL;
385 goto err_resources;
386 }
387
388 for (i = 0; i < QUEUE_LENGTH; ++i) {
389 err = fw_iso_context_queue(isight->context, &audio_packet,
390 &isight->buffer.iso_buffer,
391 isight->buffer.packets[i].offset);
392 if (err < 0)
393 goto err_context;
394 }
395
396 isight->first_packet = true;
397 isight->packet_index = 0;
398
399 err = fw_iso_context_start(isight->context, -1, 0,
400 FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/);
401 if (err < 0)
402 goto err_context;
403
404 return 0;
405
406err_context:
407 fw_iso_context_destroy(isight->context);
408 isight->context = NULL;
409err_resources:
410 fw_iso_resources_free(&isight->resources);
411 reg_write(isight, REG_AUDIO_ENABLE, 0);
412error:
413 return err;
414}
415
416static int isight_prepare(struct snd_pcm_substream *substream)
417{
418 struct isight *isight = substream->private_data;
419 int err;
420
421 isight->buffer_pointer = 0;
422 isight->period_counter = 0;
423
424 mutex_lock(&isight->mutex);
425 err = isight_start_streaming(isight);
426 mutex_unlock(&isight->mutex);
427
428 return err;
429}
430
431static int isight_trigger(struct snd_pcm_substream *substream, int cmd)
432{
433 struct isight *isight = substream->private_data;
434
435 switch (cmd) {
436 case SNDRV_PCM_TRIGGER_START:
437 ACCESS_ONCE(isight->pcm_running) = true;
438 break;
439 case SNDRV_PCM_TRIGGER_STOP:
440 ACCESS_ONCE(isight->pcm_running) = false;
441 break;
442 default:
443 return -EINVAL;
444 }
445 return 0;
446}
447
448static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
449{
450 struct isight *isight = substream->private_data;
451
452 return ACCESS_ONCE(isight->buffer_pointer);
453}
454
455static int isight_create_pcm(struct isight *isight)
456{
457 static struct snd_pcm_ops ops = {
458 .open = isight_open,
459 .close = isight_close,
460 .ioctl = snd_pcm_lib_ioctl,
461 .hw_params = isight_hw_params,
462 .hw_free = isight_hw_free,
463 .prepare = isight_prepare,
464 .trigger = isight_trigger,
465 .pointer = isight_pointer,
466 .page = snd_pcm_lib_get_vmalloc_page,
467 .mmap = snd_pcm_lib_mmap_vmalloc,
468 };
469 struct snd_pcm *pcm;
470 int err;
471
472 err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm);
473 if (err < 0)
474 return err;
475 pcm->private_data = isight;
476 strcpy(pcm->name, "iSight");
477 isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
478 isight->pcm->ops = &ops;
479
480 return 0;
481}
482
483static int isight_gain_info(struct snd_kcontrol *ctl,
484 struct snd_ctl_elem_info *info)
485{
486 struct isight *isight = ctl->private_data;
487
488 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
489 info->count = 1;
490 info->value.integer.min = isight->gain_min;
491 info->value.integer.max = isight->gain_max;
492
493 return 0;
494}
495
496static int isight_gain_get(struct snd_kcontrol *ctl,
497 struct snd_ctl_elem_value *value)
498{
499 struct isight *isight = ctl->private_data;
500 __be32 gain;
501 int err;
502
503 err = reg_read(isight, REG_GAIN, &gain);
504 if (err < 0)
505 return err;
506
507 value->value.integer.value[0] = (s32)be32_to_cpu(gain);
508
509 return 0;
510}
511
512static int isight_gain_put(struct snd_kcontrol *ctl,
513 struct snd_ctl_elem_value *value)
514{
515 struct isight *isight = ctl->private_data;
516
517 if (value->value.integer.value[0] < isight->gain_min ||
518 value->value.integer.value[0] > isight->gain_max)
519 return -EINVAL;
520
521 return reg_write(isight, REG_GAIN,
522 cpu_to_be32(value->value.integer.value[0]));
523}
524
525static int isight_mute_get(struct snd_kcontrol *ctl,
526 struct snd_ctl_elem_value *value)
527{
528 struct isight *isight = ctl->private_data;
529 __be32 mute;
530 int err;
531
532 err = reg_read(isight, REG_MUTE, &mute);
533 if (err < 0)
534 return err;
535
536 value->value.integer.value[0] = !mute;
537
538 return 0;
539}
540
541static int isight_mute_put(struct snd_kcontrol *ctl,
542 struct snd_ctl_elem_value *value)
543{
544 struct isight *isight = ctl->private_data;
545
546 return reg_write(isight, REG_MUTE,
547 (__force __be32)!value->value.integer.value[0]);
548}
549
550static int isight_create_mixer(struct isight *isight)
551{
552 static const struct snd_kcontrol_new gain_control = {
553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
554 .name = "Mic Capture Volume",
555 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
556 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
557 .info = isight_gain_info,
558 .get = isight_gain_get,
559 .put = isight_gain_put,
560 };
561 static const struct snd_kcontrol_new mute_control = {
562 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
563 .name = "Mic Capture Switch",
564 .info = snd_ctl_boolean_mono_info,
565 .get = isight_mute_get,
566 .put = isight_mute_put,
567 };
568 __be32 value;
569 struct snd_kcontrol *ctl;
570 int err;
571
572 err = reg_read(isight, REG_GAIN_RAW_START, &value);
573 if (err < 0)
574 return err;
575 isight->gain_min = be32_to_cpu(value);
576
577 err = reg_read(isight, REG_GAIN_RAW_END, &value);
578 if (err < 0)
579 return err;
580 isight->gain_max = be32_to_cpu(value);
581
582 isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX;
583 isight->gain_tlv[1] = 2 * sizeof(unsigned int);
584
585 err = reg_read(isight, REG_GAIN_DB_START, &value);
586 if (err < 0)
587 return err;
588 isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100;
589
590 err = reg_read(isight, REG_GAIN_DB_END, &value);
591 if (err < 0)
592 return err;
593 isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100;
594
595 ctl = snd_ctl_new1(&gain_control, isight);
596 if (ctl)
597 ctl->tlv.p = isight->gain_tlv;
598 err = snd_ctl_add(isight->card, ctl);
599 if (err < 0)
600 return err;
601
602 err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight));
603 if (err < 0)
604 return err;
605
606 return 0;
607}
608
609static void isight_card_free(struct snd_card *card)
610{
611 struct isight *isight = card->private_data;
612
613 fw_iso_resources_destroy(&isight->resources);
614 fw_unit_put(isight->unit);
615 fw_device_put(isight->device);
616 mutex_destroy(&isight->mutex);
617}
618
619static u64 get_unit_base(struct fw_unit *unit)
620{
621 struct fw_csr_iterator i;
622 int key, value;
623
624 fw_csr_iterator_init(&i, unit->directory);
625 while (fw_csr_iterator_next(&i, &key, &value))
626 if (key == CSR_OFFSET)
627 return CSR_REGISTER_BASE + value * 4;
628 return 0;
629}
630
631static int isight_probe(struct device *unit_dev)
632{
633 struct fw_unit *unit = fw_unit(unit_dev);
634 struct fw_device *fw_dev = fw_parent_device(unit);
635 struct snd_card *card;
636 struct isight *isight;
637 int err;
638
639 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
640 if (err < 0)
641 return err;
642 snd_card_set_dev(card, unit_dev);
643
644 isight = card->private_data;
645 isight->card = card;
646 mutex_init(&isight->mutex);
647 isight->unit = fw_unit_get(unit);
648 isight->device = fw_device_get(fw_dev);
649 isight->audio_base = get_unit_base(unit);
650 if (!isight->audio_base) {
651 dev_err(&unit->device, "audio unit base not found\n");
652 err = -ENXIO;
653 goto err_unit;
654 }
655 fw_iso_resources_init(&isight->resources, unit);
656
657 card->private_free = isight_card_free;
658
659 strcpy(card->driver, "iSight");
660 strcpy(card->shortname, "Apple iSight");
661 snprintf(card->longname, sizeof(card->longname),
662 "Apple iSight (GUID %08x%08x) at %s, S%d",
663 fw_dev->config_rom[3], fw_dev->config_rom[4],
664 dev_name(&unit->device), 100 << fw_dev->max_speed);
665 strcpy(card->mixername, "iSight");
666
667 err = isight_create_pcm(isight);
668 if (err < 0)
669 goto error;
670
671 err = isight_create_mixer(isight);
672 if (err < 0)
673 goto error;
674
675 err = snd_card_register(card);
676 if (err < 0)
677 goto error;
678
679 dev_set_drvdata(unit_dev, isight);
680
681 return 0;
682
683err_unit:
684 fw_unit_put(isight->unit);
685 fw_device_put(isight->device);
686 mutex_destroy(&isight->mutex);
687error:
688 snd_card_free(card);
689 return err;
690}
691
692static int isight_remove(struct device *dev)
693{
694 struct isight *isight = dev_get_drvdata(dev);
695
696 isight_pcm_abort(isight);
697
698 snd_card_disconnect(isight->card);
699
700 mutex_lock(&isight->mutex);
701 isight_stop_streaming(isight);
702 mutex_unlock(&isight->mutex);
703
704 snd_card_free_when_closed(isight->card);
705
706 return 0;
707}
708
709static void isight_bus_reset(struct fw_unit *unit)
710{
711 struct isight *isight = dev_get_drvdata(&unit->device);
712
713 if (fw_iso_resources_update(&isight->resources) < 0) {
714 isight_pcm_abort(isight);
715
716 mutex_lock(&isight->mutex);
717 isight_stop_streaming(isight);
718 mutex_unlock(&isight->mutex);
719 }
720}
721
722static const struct ieee1394_device_id isight_id_table[] = {
723 {
724 .match_flags = IEEE1394_MATCH_SPECIFIER_ID |
725 IEEE1394_MATCH_VERSION,
726 .specifier_id = OUI_APPLE,
727 .version = SW_ISIGHT_AUDIO,
728 },
729 { }
730};
731MODULE_DEVICE_TABLE(ieee1394, isight_id_table);
732
733static struct fw_driver isight_driver = {
734 .driver = {
735 .owner = THIS_MODULE,
736 .name = KBUILD_MODNAME,
737 .bus = &fw_bus_type,
738 .probe = isight_probe,
739 .remove = isight_remove,
740 },
741 .update = isight_bus_reset,
742 .id_table = isight_id_table,
743};
744
745static int __init alsa_isight_init(void)
746{
747 return driver_register(&isight_driver.driver);
748}
749
750static void __exit alsa_isight_exit(void)
751{
752 driver_unregister(&isight_driver.driver);
753}
754
755module_init(alsa_isight_init);
756module_exit(alsa_isight_exit);
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c
new file mode 100644
index 000000000000..ffe20b877e9f
--- /dev/null
+++ b/sound/firewire/iso-resources.c
@@ -0,0 +1,231 @@
1/*
2 * isochronous resources helper functions
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/jiffies.h>
12#include <linux/mutex.h>
13#include <linux/sched.h>
14#include <linux/spinlock.h>
15#include "iso-resources.h"
16
17/**
18 * fw_iso_resources_init - initializes a &struct fw_iso_resources
19 * @r: the resource manager to initialize
20 * @unit: the device unit for which the resources will be needed
21 *
22 * If the device does not support all channel numbers, change @r->channels_mask
23 * after calling this function.
24 */
25int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
26{
27 r->channels_mask = ~0uLL;
28 r->unit = fw_unit_get(unit);
29 mutex_init(&r->mutex);
30 r->allocated = false;
31
32 return 0;
33}
34EXPORT_SYMBOL(fw_iso_resources_init);
35
36/**
37 * fw_iso_resources_destroy - destroy a resource manager
38 * @r: the resource manager that is no longer needed
39 */
40void fw_iso_resources_destroy(struct fw_iso_resources *r)
41{
42 WARN_ON(r->allocated);
43 mutex_destroy(&r->mutex);
44 fw_unit_put(r->unit);
45}
46EXPORT_SYMBOL(fw_iso_resources_destroy);
47
48static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed)
49{
50 unsigned int bytes, s400_bytes;
51
52 /* iso packets have three header quadlets and quadlet-aligned payload */
53 bytes = 3 * 4 + ALIGN(max_payload_bytes, 4);
54
55 /* convert to bandwidth units (quadlets at S1600 = bytes at S400) */
56 if (speed <= SCODE_400)
57 s400_bytes = bytes * (1 << (SCODE_400 - speed));
58 else
59 s400_bytes = DIV_ROUND_UP(bytes, 1 << (speed - SCODE_400));
60
61 return s400_bytes;
62}
63
64static int current_bandwidth_overhead(struct fw_card *card)
65{
66 /*
67 * Under the usual pessimistic assumption (cable length 4.5 m), the
68 * isochronous overhead for N cables is 1.797 µs + N * 0.494 µs, or
69 * 88.3 + N * 24.3 in bandwidth units.
70 *
71 * The calculation below tries to deduce N from the current gap count.
72 * If the gap count has been optimized by measuring the actual packet
73 * transmission time, this derived overhead should be near the actual
74 * overhead as well.
75 */
76 return card->gap_count < 63 ? card->gap_count * 97 / 10 + 89 : 512;
77}
78
79static int wait_isoch_resource_delay_after_bus_reset(struct fw_card *card)
80{
81 for (;;) {
82 s64 delay = (card->reset_jiffies + HZ) - get_jiffies_64();
83 if (delay <= 0)
84 return 0;
85 if (schedule_timeout_interruptible(delay) > 0)
86 return -ERESTARTSYS;
87 }
88}
89
90/**
91 * fw_iso_resources_allocate - allocate isochronous channel and bandwidth
92 * @r: the resource manager
93 * @max_payload_bytes: the amount of data (including CIP headers) per packet
94 * @speed: the speed (e.g., SCODE_400) at which the packets will be sent
95 *
96 * This function allocates one isochronous channel and enough bandwidth for the
97 * specified packet size.
98 *
99 * Returns the channel number that the caller must use for streaming, or
100 * a negative error code. Due to potentionally long delays, this function is
101 * interruptible and can return -ERESTARTSYS. On success, the caller is
102 * responsible for calling fw_iso_resources_update() on bus resets, and
103 * fw_iso_resources_free() when the resources are not longer needed.
104 */
105int fw_iso_resources_allocate(struct fw_iso_resources *r,
106 unsigned int max_payload_bytes, int speed)
107{
108 struct fw_card *card = fw_parent_device(r->unit)->card;
109 int bandwidth, channel, err;
110
111 if (WARN_ON(r->allocated))
112 return -EBADFD;
113
114 r->bandwidth = packet_bandwidth(max_payload_bytes, speed);
115
116retry_after_bus_reset:
117 spin_lock_irq(&card->lock);
118 r->generation = card->generation;
119 r->bandwidth_overhead = current_bandwidth_overhead(card);
120 spin_unlock_irq(&card->lock);
121
122 err = wait_isoch_resource_delay_after_bus_reset(card);
123 if (err < 0)
124 return err;
125
126 mutex_lock(&r->mutex);
127
128 bandwidth = r->bandwidth + r->bandwidth_overhead;
129 fw_iso_resource_manage(card, r->generation, r->channels_mask,
130 &channel, &bandwidth, true);
131 if (channel == -EAGAIN) {
132 mutex_unlock(&r->mutex);
133 goto retry_after_bus_reset;
134 }
135 if (channel >= 0) {
136 r->channel = channel;
137 r->allocated = true;
138 } else {
139 if (channel == -EBUSY)
140 dev_err(&r->unit->device,
141 "isochronous resources exhausted\n");
142 else
143 dev_err(&r->unit->device,
144 "isochronous resource allocation failed\n");
145 }
146
147 mutex_unlock(&r->mutex);
148
149 return channel;
150}
151EXPORT_SYMBOL(fw_iso_resources_allocate);
152
153/**
154 * fw_iso_resources_update - update resource allocations after a bus reset
155 * @r: the resource manager
156 *
157 * This function must be called from the driver's .update handler to reallocate
158 * any resources that were allocated before the bus reset. It is safe to call
159 * this function if no resources are currently allocated.
160 *
161 * Returns a negative error code on failure. If this happens, the caller must
162 * stop streaming.
163 */
164int fw_iso_resources_update(struct fw_iso_resources *r)
165{
166 struct fw_card *card = fw_parent_device(r->unit)->card;
167 int bandwidth, channel;
168
169 mutex_lock(&r->mutex);
170
171 if (!r->allocated) {
172 mutex_unlock(&r->mutex);
173 return 0;
174 }
175
176 spin_lock_irq(&card->lock);
177 r->generation = card->generation;
178 r->bandwidth_overhead = current_bandwidth_overhead(card);
179 spin_unlock_irq(&card->lock);
180
181 bandwidth = r->bandwidth + r->bandwidth_overhead;
182
183 fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
184 &channel, &bandwidth, true);
185 /*
186 * When another bus reset happens, pretend that the allocation
187 * succeeded; we will try again for the new generation later.
188 */
189 if (channel < 0 && channel != -EAGAIN) {
190 r->allocated = false;
191 if (channel == -EBUSY)
192 dev_err(&r->unit->device,
193 "isochronous resources exhausted\n");
194 else
195 dev_err(&r->unit->device,
196 "isochronous resource allocation failed\n");
197 }
198
199 mutex_unlock(&r->mutex);
200
201 return channel;
202}
203EXPORT_SYMBOL(fw_iso_resources_update);
204
205/**
206 * fw_iso_resources_free - frees allocated resources
207 * @r: the resource manager
208 *
209 * This function deallocates the channel and bandwidth, if allocated.
210 */
211void fw_iso_resources_free(struct fw_iso_resources *r)
212{
213 struct fw_card *card = fw_parent_device(r->unit)->card;
214 int bandwidth, channel;
215
216 mutex_lock(&r->mutex);
217
218 if (r->allocated) {
219 bandwidth = r->bandwidth + r->bandwidth_overhead;
220 fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
221 &channel, &bandwidth, false);
222 if (channel < 0)
223 dev_err(&r->unit->device,
224 "isochronous resource deallocation failed\n");
225
226 r->allocated = false;
227 }
228
229 mutex_unlock(&r->mutex);
230}
231EXPORT_SYMBOL(fw_iso_resources_free);
diff --git a/sound/firewire/iso-resources.h b/sound/firewire/iso-resources.h
new file mode 100644
index 000000000000..5a9af7c61657
--- /dev/null
+++ b/sound/firewire/iso-resources.h
@@ -0,0 +1,38 @@
1#ifndef SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
2#define SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
3
4#include <linux/mutex.h>
5#include <linux/types.h>
6
7struct fw_unit;
8
9/**
10 * struct fw_iso_resources - manages channel/bandwidth allocation
11 * @channels_mask: if the device does not support all channel numbers, set this
12 * bit mask to something else than the default (all ones)
13 *
14 * This structure manages (de)allocation of isochronous resources (channel and
15 * bandwidth) for one isochronous stream.
16 */
17struct fw_iso_resources {
18 u64 channels_mask;
19 /* private: */
20 struct fw_unit *unit;
21 struct mutex mutex;
22 unsigned int channel;
23 unsigned int bandwidth; /* in bandwidth units, without overhead */
24 unsigned int bandwidth_overhead;
25 int generation; /* in which allocation is valid */
26 bool allocated;
27};
28
29int fw_iso_resources_init(struct fw_iso_resources *r,
30 struct fw_unit *unit);
31void fw_iso_resources_destroy(struct fw_iso_resources *r);
32
33int fw_iso_resources_allocate(struct fw_iso_resources *r,
34 unsigned int max_payload_bytes, int speed);
35int fw_iso_resources_update(struct fw_iso_resources *r);
36void fw_iso_resources_free(struct fw_iso_resources *r);
37
38#endif
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
new file mode 100644
index 000000000000..4750cea2210e
--- /dev/null
+++ b/sound/firewire/lib.c
@@ -0,0 +1,85 @@
1/*
2 * miscellaneous helper functions
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/delay.h>
9#include <linux/device.h>
10#include <linux/firewire.h>
11#include <linux/module.h>
12#include "lib.h"
13
14#define ERROR_RETRY_DELAY_MS 5
15
16/**
17 * rcode_string - convert a firewire result code to a string
18 * @rcode: the result
19 */
20const char *rcode_string(unsigned int rcode)
21{
22 static const char *const names[] = {
23 [RCODE_COMPLETE] = "complete",
24 [RCODE_CONFLICT_ERROR] = "conflict error",
25 [RCODE_DATA_ERROR] = "data error",
26 [RCODE_TYPE_ERROR] = "type error",
27 [RCODE_ADDRESS_ERROR] = "address error",
28 [RCODE_SEND_ERROR] = "send error",
29 [RCODE_CANCELLED] = "cancelled",
30 [RCODE_BUSY] = "busy",
31 [RCODE_GENERATION] = "generation",
32 [RCODE_NO_ACK] = "no ack",
33 };
34
35 if (rcode < ARRAY_SIZE(names) && names[rcode])
36 return names[rcode];
37 else
38 return "unknown";
39}
40EXPORT_SYMBOL(rcode_string);
41
42/**
43 * snd_fw_transaction - send a request and wait for its completion
44 * @unit: the driver's unit on the target device
45 * @tcode: the transaction code
46 * @offset: the address in the target's address space
47 * @buffer: input/output data
48 * @length: length of @buffer
49 *
50 * Submits an asynchronous request to the target device, and waits for the
51 * response. The node ID and the current generation are derived from @unit.
52 * On a bus reset or an error, the transaction is retried a few times.
53 * Returns zero on success, or a negative error code.
54 */
55int snd_fw_transaction(struct fw_unit *unit, int tcode,
56 u64 offset, void *buffer, size_t length)
57{
58 struct fw_device *device = fw_parent_device(unit);
59 int generation, rcode, tries = 0;
60
61 for (;;) {
62 generation = device->generation;
63 smp_rmb(); /* node_id vs. generation */
64 rcode = fw_run_transaction(device->card, tcode,
65 device->node_id, generation,
66 device->max_speed, offset,
67 buffer, length);
68
69 if (rcode == RCODE_COMPLETE)
70 return 0;
71
72 if (rcode_is_permanent_error(rcode) || ++tries >= 3) {
73 dev_err(&unit->device, "transaction failed: %s\n",
74 rcode_string(rcode));
75 return -EIO;
76 }
77
78 msleep(ERROR_RETRY_DELAY_MS);
79 }
80}
81EXPORT_SYMBOL(snd_fw_transaction);
82
83MODULE_DESCRIPTION("FireWire audio helper functions");
84MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
85MODULE_LICENSE("GPL v2");
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
new file mode 100644
index 000000000000..064f3fd9ab06
--- /dev/null
+++ b/sound/firewire/lib.h
@@ -0,0 +1,19 @@
1#ifndef SOUND_FIREWIRE_LIB_H_INCLUDED
2#define SOUND_FIREWIRE_LIB_H_INCLUDED
3
4#include <linux/firewire-constants.h>
5#include <linux/types.h>
6
7struct fw_unit;
8
9int snd_fw_transaction(struct fw_unit *unit, int tcode,
10 u64 offset, void *buffer, size_t length);
11const char *rcode_string(unsigned int rcode);
12
13/* returns true if retrying the transaction would not make sense */
14static inline bool rcode_is_permanent_error(int rcode)
15{
16 return rcode == RCODE_TYPE_ERROR || rcode == RCODE_ADDRESS_ERROR;
17}
18
19#endif
diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c
new file mode 100644
index 000000000000..3c61ca2e6152
--- /dev/null
+++ b/sound/firewire/packets-buffer.c
@@ -0,0 +1,76 @@
1/*
2 * helpers for managing a buffer for many packets
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/firewire.h>
9#include <linux/slab.h>
10#include "packets-buffer.h"
11
12/**
13 * iso_packets_buffer_init - allocates the memory for packets
14 * @b: the buffer structure to initialize
15 * @unit: the device at the other end of the stream
16 * @count: the number of packets
17 * @packet_size: the (maximum) size of a packet, in bytes
18 * @direction: %DMA_TO_DEVICE or %DMA_FROM_DEVICE
19 */
20int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
21 unsigned int count, unsigned int packet_size,
22 enum dma_data_direction direction)
23{
24 unsigned int packets_per_page, pages;
25 unsigned int i, page_index, offset_in_page;
26 void *p;
27 int err;
28
29 b->packets = kmalloc(count * sizeof(*b->packets), GFP_KERNEL);
30 if (!b->packets) {
31 err = -ENOMEM;
32 goto error;
33 }
34
35 packet_size = L1_CACHE_ALIGN(packet_size);
36 packets_per_page = PAGE_SIZE / packet_size;
37 if (WARN_ON(!packets_per_page)) {
38 err = -EINVAL;
39 goto error;
40 }
41 pages = DIV_ROUND_UP(count, packets_per_page);
42
43 err = fw_iso_buffer_init(&b->iso_buffer, fw_parent_device(unit)->card,
44 pages, direction);
45 if (err < 0)
46 goto err_packets;
47
48 for (i = 0; i < count; ++i) {
49 page_index = i / packets_per_page;
50 p = page_address(b->iso_buffer.pages[page_index]);
51 offset_in_page = (i % packets_per_page) * packet_size;
52 b->packets[i].buffer = p + offset_in_page;
53 b->packets[i].offset = page_index * PAGE_SIZE + offset_in_page;
54 }
55
56 return 0;
57
58err_packets:
59 kfree(b->packets);
60error:
61 return err;
62}
63EXPORT_SYMBOL(iso_packets_buffer_init);
64
65/**
66 * iso_packets_buffer_destroy - frees packet buffer resources
67 * @b: the buffer structure to free
68 * @unit: the device at the other end of the stream
69 */
70void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
71 struct fw_unit *unit)
72{
73 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
74 kfree(b->packets);
75}
76EXPORT_SYMBOL(iso_packets_buffer_destroy);
diff --git a/sound/firewire/packets-buffer.h b/sound/firewire/packets-buffer.h
new file mode 100644
index 000000000000..6513c5cb6ea9
--- /dev/null
+++ b/sound/firewire/packets-buffer.h
@@ -0,0 +1,26 @@
1#ifndef SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
2#define SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
3
4#include <linux/dma-mapping.h>
5#include <linux/firewire.h>
6
7/**
8 * struct iso_packets_buffer - manages a buffer for many packets
9 * @iso_buffer: the memory containing the packets
10 * @packets: an array, with each element pointing to one packet
11 */
12struct iso_packets_buffer {
13 struct fw_iso_buffer iso_buffer;
14 struct {
15 void *buffer;
16 unsigned int offset;
17 } *packets;
18};
19
20int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
21 unsigned int count, unsigned int packet_size,
22 enum dma_data_direction direction);
23void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
24 struct fw_unit *unit);
25
26#endif
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
new file mode 100644
index 000000000000..5466de8527bd
--- /dev/null
+++ b/sound/firewire/speakers.c
@@ -0,0 +1,857 @@
1/*
2 * OXFW970-based speakers driver
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
8#include <linux/device.h>
9#include <linux/firewire.h>
10#include <linux/firewire-constants.h>
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/mutex.h>
14#include <linux/slab.h>
15#include <sound/control.h>
16#include <sound/core.h>
17#include <sound/initval.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include "cmp.h"
21#include "fcp.h"
22#include "amdtp.h"
23#include "lib.h"
24
25#define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000)
26/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
27
28#define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020)
29#define OXFORD_HARDWARE_ID_OXFW970 0x39443841
30#define OXFORD_HARDWARE_ID_OXFW971 0x39373100
31
32#define VENDOR_GRIFFIN 0x001292
33#define VENDOR_LACIE 0x00d04b
34
35#define SPECIFIER_1394TA 0x00a02d
36#define VERSION_AVC 0x010001
37
38struct device_info {
39 const char *driver_name;
40 const char *short_name;
41 const char *long_name;
42 int (*pcm_constraints)(struct snd_pcm_runtime *runtime);
43 unsigned int mixer_channels;
44 u8 mute_fb_id;
45 u8 volume_fb_id;
46};
47
48struct fwspk {
49 struct snd_card *card;
50 struct fw_unit *unit;
51 const struct device_info *device_info;
52 struct snd_pcm_substream *pcm;
53 struct mutex mutex;
54 struct cmp_connection connection;
55 struct amdtp_out_stream stream;
56 bool stream_running;
57 bool mute;
58 s16 volume[6];
59 s16 volume_min;
60 s16 volume_max;
61};
62
63MODULE_DESCRIPTION("FireWire speakers driver");
64MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
65MODULE_LICENSE("GPL v2");
66
67static int firewave_rate_constraint(struct snd_pcm_hw_params *params,
68 struct snd_pcm_hw_rule *rule)
69{
70 static unsigned int stereo_rates[] = { 48000, 96000 };
71 struct snd_interval *channels =
72 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
73 struct snd_interval *rate =
74 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
75
76 /* two channels work only at 48/96 kHz */
77 if (snd_interval_max(channels) < 6)
78 return snd_interval_list(rate, 2, stereo_rates, 0);
79 return 0;
80}
81
82static int firewave_channels_constraint(struct snd_pcm_hw_params *params,
83 struct snd_pcm_hw_rule *rule)
84{
85 static const struct snd_interval all_channels = { .min = 6, .max = 6 };
86 struct snd_interval *rate =
87 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
88 struct snd_interval *channels =
89 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
90
91 /* 32/44.1 kHz work only with all six channels */
92 if (snd_interval_max(rate) < 48000)
93 return snd_interval_refine(channels, &all_channels);
94 return 0;
95}
96
97static int firewave_constraints(struct snd_pcm_runtime *runtime)
98{
99 static unsigned int channels_list[] = { 2, 6 };
100 static struct snd_pcm_hw_constraint_list channels_list_constraint = {
101 .count = 2,
102 .list = channels_list,
103 };
104 int err;
105
106 runtime->hw.rates = SNDRV_PCM_RATE_32000 |
107 SNDRV_PCM_RATE_44100 |
108 SNDRV_PCM_RATE_48000 |
109 SNDRV_PCM_RATE_96000;
110 runtime->hw.channels_max = 6;
111
112 err = snd_pcm_hw_constraint_list(runtime, 0,
113 SNDRV_PCM_HW_PARAM_CHANNELS,
114 &channels_list_constraint);
115 if (err < 0)
116 return err;
117 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
118 firewave_rate_constraint, NULL,
119 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
120 if (err < 0)
121 return err;
122 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
123 firewave_channels_constraint, NULL,
124 SNDRV_PCM_HW_PARAM_RATE, -1);
125 if (err < 0)
126 return err;
127
128 return 0;
129}
130
131static int lacie_speakers_constraints(struct snd_pcm_runtime *runtime)
132{
133 runtime->hw.rates = SNDRV_PCM_RATE_32000 |
134 SNDRV_PCM_RATE_44100 |
135 SNDRV_PCM_RATE_48000 |
136 SNDRV_PCM_RATE_88200 |
137 SNDRV_PCM_RATE_96000;
138
139 return 0;
140}
141
142static int fwspk_open(struct snd_pcm_substream *substream)
143{
144 static const struct snd_pcm_hardware hardware = {
145 .info = SNDRV_PCM_INFO_MMAP |
146 SNDRV_PCM_INFO_MMAP_VALID |
147 SNDRV_PCM_INFO_BATCH |
148 SNDRV_PCM_INFO_INTERLEAVED |
149 SNDRV_PCM_INFO_BLOCK_TRANSFER,
150 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
151 .channels_min = 2,
152 .channels_max = 2,
153 .buffer_bytes_max = 4 * 1024 * 1024,
154 .period_bytes_min = 1,
155 .period_bytes_max = UINT_MAX,
156 .periods_min = 1,
157 .periods_max = UINT_MAX,
158 };
159 struct fwspk *fwspk = substream->private_data;
160 struct snd_pcm_runtime *runtime = substream->runtime;
161 int err;
162
163 runtime->hw = hardware;
164
165 err = fwspk->device_info->pcm_constraints(runtime);
166 if (err < 0)
167 return err;
168 err = snd_pcm_limit_hw_rates(runtime);
169 if (err < 0)
170 return err;
171
172 err = snd_pcm_hw_constraint_minmax(runtime,
173 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
174 5000, 8192000);
175 if (err < 0)
176 return err;
177
178 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
179 if (err < 0)
180 return err;
181
182 return 0;
183}
184
185static int fwspk_close(struct snd_pcm_substream *substream)
186{
187 return 0;
188}
189
190static void fwspk_stop_stream(struct fwspk *fwspk)
191{
192 if (fwspk->stream_running) {
193 amdtp_out_stream_stop(&fwspk->stream);
194 cmp_connection_break(&fwspk->connection);
195 fwspk->stream_running = false;
196 }
197}
198
199static int fwspk_set_rate(struct fwspk *fwspk, unsigned int sfc)
200{
201 u8 *buf;
202 int err;
203
204 buf = kmalloc(8, GFP_KERNEL);
205 if (!buf)
206 return -ENOMEM;
207
208 buf[0] = 0x00; /* AV/C, CONTROL */
209 buf[1] = 0xff; /* unit */
210 buf[2] = 0x19; /* INPUT PLUG SIGNAL FORMAT */
211 buf[3] = 0x00; /* plug 0 */
212 buf[4] = 0x90; /* format: audio */
213 buf[5] = 0x00 | sfc; /* AM824, frequency */
214 buf[6] = 0xff; /* SYT (not used) */
215 buf[7] = 0xff;
216
217 err = fcp_avc_transaction(fwspk->unit, buf, 8, buf, 8,
218 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));
219 if (err < 0)
220 goto error;
221 if (err < 6 || buf[0] != 0x09 /* ACCEPTED */) {
222 dev_err(&fwspk->unit->device, "failed to set sample rate\n");
223 err = -EIO;
224 goto error;
225 }
226
227 err = 0;
228
229error:
230 kfree(buf);
231
232 return err;
233}
234
235static int fwspk_hw_params(struct snd_pcm_substream *substream,
236 struct snd_pcm_hw_params *hw_params)
237{
238 struct fwspk *fwspk = substream->private_data;
239 int err;
240
241 mutex_lock(&fwspk->mutex);
242 fwspk_stop_stream(fwspk);
243 mutex_unlock(&fwspk->mutex);
244
245 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
246 params_buffer_bytes(hw_params));
247 if (err < 0)
248 goto error;
249
250 amdtp_out_stream_set_rate(&fwspk->stream, params_rate(hw_params));
251 amdtp_out_stream_set_pcm(&fwspk->stream, params_channels(hw_params));
252
253 amdtp_out_stream_set_pcm_format(&fwspk->stream,
254 params_format(hw_params));
255
256 err = fwspk_set_rate(fwspk, fwspk->stream.sfc);
257 if (err < 0)
258 goto err_buffer;
259
260 return 0;
261
262err_buffer:
263 snd_pcm_lib_free_vmalloc_buffer(substream);
264error:
265 return err;
266}
267
268static int fwspk_hw_free(struct snd_pcm_substream *substream)
269{
270 struct fwspk *fwspk = substream->private_data;
271
272 mutex_lock(&fwspk->mutex);
273 fwspk_stop_stream(fwspk);
274 mutex_unlock(&fwspk->mutex);
275
276 return snd_pcm_lib_free_vmalloc_buffer(substream);
277}
278
279static int fwspk_prepare(struct snd_pcm_substream *substream)
280{
281 struct fwspk *fwspk = substream->private_data;
282 int err;
283
284 mutex_lock(&fwspk->mutex);
285
286 if (amdtp_out_streaming_error(&fwspk->stream))
287 fwspk_stop_stream(fwspk);
288
289 if (!fwspk->stream_running) {
290 err = cmp_connection_establish(&fwspk->connection,
291 amdtp_out_stream_get_max_payload(&fwspk->stream));
292 if (err < 0)
293 goto err_mutex;
294
295 err = amdtp_out_stream_start(&fwspk->stream,
296 fwspk->connection.resources.channel,
297 fwspk->connection.speed);
298 if (err < 0)
299 goto err_connection;
300
301 fwspk->stream_running = true;
302 }
303
304 mutex_unlock(&fwspk->mutex);
305
306 amdtp_out_stream_pcm_prepare(&fwspk->stream);
307
308 return 0;
309
310err_connection:
311 cmp_connection_break(&fwspk->connection);
312err_mutex:
313 mutex_unlock(&fwspk->mutex);
314
315 return err;
316}
317
318static int fwspk_trigger(struct snd_pcm_substream *substream, int cmd)
319{
320 struct fwspk *fwspk = substream->private_data;
321 struct snd_pcm_substream *pcm;
322
323 switch (cmd) {
324 case SNDRV_PCM_TRIGGER_START:
325 pcm = substream;
326 break;
327 case SNDRV_PCM_TRIGGER_STOP:
328 pcm = NULL;
329 break;
330 default:
331 return -EINVAL;
332 }
333 amdtp_out_stream_pcm_trigger(&fwspk->stream, pcm);
334 return 0;
335}
336
337static snd_pcm_uframes_t fwspk_pointer(struct snd_pcm_substream *substream)
338{
339 struct fwspk *fwspk = substream->private_data;
340
341 return amdtp_out_stream_pcm_pointer(&fwspk->stream);
342}
343
344static int fwspk_create_pcm(struct fwspk *fwspk)
345{
346 static struct snd_pcm_ops ops = {
347 .open = fwspk_open,
348 .close = fwspk_close,
349 .ioctl = snd_pcm_lib_ioctl,
350 .hw_params = fwspk_hw_params,
351 .hw_free = fwspk_hw_free,
352 .prepare = fwspk_prepare,
353 .trigger = fwspk_trigger,
354 .pointer = fwspk_pointer,
355 .page = snd_pcm_lib_get_vmalloc_page,
356 .mmap = snd_pcm_lib_mmap_vmalloc,
357 };
358 struct snd_pcm *pcm;
359 int err;
360
361 err = snd_pcm_new(fwspk->card, "OXFW970", 0, 1, 0, &pcm);
362 if (err < 0)
363 return err;
364 pcm->private_data = fwspk;
365 strcpy(pcm->name, fwspk->device_info->short_name);
366 fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
367 fwspk->pcm->ops = &ops;
368 return 0;
369}
370
371enum control_action { CTL_READ, CTL_WRITE };
372enum control_attribute {
373 CTL_MIN = 0x02,
374 CTL_MAX = 0x03,
375 CTL_CURRENT = 0x10,
376};
377
378static int fwspk_mute_command(struct fwspk *fwspk, bool *value,
379 enum control_action action)
380{
381 u8 *buf;
382 u8 response_ok;
383 int err;
384
385 buf = kmalloc(11, GFP_KERNEL);
386 if (!buf)
387 return -ENOMEM;
388
389 if (action == CTL_READ) {
390 buf[0] = 0x01; /* AV/C, STATUS */
391 response_ok = 0x0c; /* STABLE */
392 } else {
393 buf[0] = 0x00; /* AV/C, CONTROL */
394 response_ok = 0x09; /* ACCEPTED */
395 }
396 buf[1] = 0x08; /* audio unit 0 */
397 buf[2] = 0xb8; /* FUNCTION BLOCK */
398 buf[3] = 0x81; /* function block type: feature */
399 buf[4] = fwspk->device_info->mute_fb_id; /* function block ID */
400 buf[5] = 0x10; /* control attribute: current */
401 buf[6] = 0x02; /* selector length */
402 buf[7] = 0x00; /* audio channel number */
403 buf[8] = 0x01; /* control selector: mute */
404 buf[9] = 0x01; /* control data length */
405 if (action == CTL_READ)
406 buf[10] = 0xff;
407 else
408 buf[10] = *value ? 0x70 : 0x60;
409
410 err = fcp_avc_transaction(fwspk->unit, buf, 11, buf, 11, 0x3fe);
411 if (err < 0)
412 goto error;
413 if (err < 11) {
414 dev_err(&fwspk->unit->device, "short FCP response\n");
415 err = -EIO;
416 goto error;
417 }
418 if (buf[0] != response_ok) {
419 dev_err(&fwspk->unit->device, "mute command failed\n");
420 err = -EIO;
421 goto error;
422 }
423 if (action == CTL_READ)
424 *value = buf[10] == 0x70;
425
426 err = 0;
427
428error:
429 kfree(buf);
430
431 return err;
432}
433
434static int fwspk_volume_command(struct fwspk *fwspk, s16 *value,
435 unsigned int channel,
436 enum control_attribute attribute,
437 enum control_action action)
438{
439 u8 *buf;
440 u8 response_ok;
441 int err;
442
443 buf = kmalloc(12, GFP_KERNEL);
444 if (!buf)
445 return -ENOMEM;
446
447 if (action == CTL_READ) {
448 buf[0] = 0x01; /* AV/C, STATUS */
449 response_ok = 0x0c; /* STABLE */
450 } else {
451 buf[0] = 0x00; /* AV/C, CONTROL */
452 response_ok = 0x09; /* ACCEPTED */
453 }
454 buf[1] = 0x08; /* audio unit 0 */
455 buf[2] = 0xb8; /* FUNCTION BLOCK */
456 buf[3] = 0x81; /* function block type: feature */
457 buf[4] = fwspk->device_info->volume_fb_id; /* function block ID */
458 buf[5] = attribute; /* control attribute */
459 buf[6] = 0x02; /* selector length */
460 buf[7] = channel; /* audio channel number */
461 buf[8] = 0x02; /* control selector: volume */
462 buf[9] = 0x02; /* control data length */
463 if (action == CTL_READ) {
464 buf[10] = 0xff;
465 buf[11] = 0xff;
466 } else {
467 buf[10] = *value >> 8;
468 buf[11] = *value;
469 }
470
471 err = fcp_avc_transaction(fwspk->unit, buf, 12, buf, 12, 0x3fe);
472 if (err < 0)
473 goto error;
474 if (err < 12) {
475 dev_err(&fwspk->unit->device, "short FCP response\n");
476 err = -EIO;
477 goto error;
478 }
479 if (buf[0] != response_ok) {
480 dev_err(&fwspk->unit->device, "volume command failed\n");
481 err = -EIO;
482 goto error;
483 }
484 if (action == CTL_READ)
485 *value = (buf[10] << 8) | buf[11];
486
487 err = 0;
488
489error:
490 kfree(buf);
491
492 return err;
493}
494
495static int fwspk_mute_get(struct snd_kcontrol *control,
496 struct snd_ctl_elem_value *value)
497{
498 struct fwspk *fwspk = control->private_data;
499
500 value->value.integer.value[0] = !fwspk->mute;
501
502 return 0;
503}
504
505static int fwspk_mute_put(struct snd_kcontrol *control,
506 struct snd_ctl_elem_value *value)
507{
508 struct fwspk *fwspk = control->private_data;
509 bool mute;
510 int err;
511
512 mute = !value->value.integer.value[0];
513
514 if (mute == fwspk->mute)
515 return 0;
516
517 err = fwspk_mute_command(fwspk, &mute, CTL_WRITE);
518 if (err < 0)
519 return err;
520 fwspk->mute = mute;
521
522 return 1;
523}
524
525static int fwspk_volume_info(struct snd_kcontrol *control,
526 struct snd_ctl_elem_info *info)
527{
528 struct fwspk *fwspk = control->private_data;
529
530 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
531 info->count = fwspk->device_info->mixer_channels;
532 info->value.integer.min = fwspk->volume_min;
533 info->value.integer.max = fwspk->volume_max;
534
535 return 0;
536}
537
538static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 };
539
540static int fwspk_volume_get(struct snd_kcontrol *control,
541 struct snd_ctl_elem_value *value)
542{
543 struct fwspk *fwspk = control->private_data;
544 unsigned int i;
545
546 for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
547 value->value.integer.value[channel_map[i]] = fwspk->volume[i];
548
549 return 0;
550}
551
552static int fwspk_volume_put(struct snd_kcontrol *control,
553 struct snd_ctl_elem_value *value)
554{
555 struct fwspk *fwspk = control->private_data;
556 unsigned int i, changed_channels;
557 bool equal_values = true;
558 s16 volume;
559 int err;
560
561 for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
562 if (value->value.integer.value[i] < fwspk->volume_min ||
563 value->value.integer.value[i] > fwspk->volume_max)
564 return -EINVAL;
565 if (value->value.integer.value[i] !=
566 value->value.integer.value[0])
567 equal_values = false;
568 }
569
570 changed_channels = 0;
571 for (i = 0; i < fwspk->device_info->mixer_channels; ++i)
572 if (value->value.integer.value[channel_map[i]] !=
573 fwspk->volume[i])
574 changed_channels |= 1 << (i + 1);
575
576 if (equal_values && changed_channels != 0)
577 changed_channels = 1 << 0;
578
579 for (i = 0; i <= fwspk->device_info->mixer_channels; ++i) {
580 volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
581 if (changed_channels & (1 << i)) {
582 err = fwspk_volume_command(fwspk, &volume, i,
583 CTL_CURRENT, CTL_WRITE);
584 if (err < 0)
585 return err;
586 }
587 if (i > 0)
588 fwspk->volume[i - 1] = volume;
589 }
590
591 return changed_channels != 0;
592}
593
594static int fwspk_create_mixer(struct fwspk *fwspk)
595{
596 static const struct snd_kcontrol_new controls[] = {
597 {
598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
599 .name = "PCM Playback Switch",
600 .info = snd_ctl_boolean_mono_info,
601 .get = fwspk_mute_get,
602 .put = fwspk_mute_put,
603 },
604 {
605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
606 .name = "PCM Playback Volume",
607 .info = fwspk_volume_info,
608 .get = fwspk_volume_get,
609 .put = fwspk_volume_put,
610 },
611 };
612 unsigned int i, first_ch;
613 int err;
614
615 err = fwspk_volume_command(fwspk, &fwspk->volume_min,
616 0, CTL_MIN, CTL_READ);
617 if (err < 0)
618 return err;
619 err = fwspk_volume_command(fwspk, &fwspk->volume_max,
620 0, CTL_MAX, CTL_READ);
621 if (err < 0)
622 return err;
623
624 err = fwspk_mute_command(fwspk, &fwspk->mute, CTL_READ);
625 if (err < 0)
626 return err;
627
628 first_ch = fwspk->device_info->mixer_channels == 1 ? 0 : 1;
629 for (i = 0; i < fwspk->device_info->mixer_channels; ++i) {
630 err = fwspk_volume_command(fwspk, &fwspk->volume[i],
631 first_ch + i, CTL_CURRENT, CTL_READ);
632 if (err < 0)
633 return err;
634 }
635
636 for (i = 0; i < ARRAY_SIZE(controls); ++i) {
637 err = snd_ctl_add(fwspk->card,
638 snd_ctl_new1(&controls[i], fwspk));
639 if (err < 0)
640 return err;
641 }
642
643 return 0;
644}
645
646static u32 fwspk_read_firmware_version(struct fw_unit *unit)
647{
648 __be32 data;
649 int err;
650
651 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
652 OXFORD_FIRMWARE_ID_ADDRESS, &data, 4);
653 return err >= 0 ? be32_to_cpu(data) : 0;
654}
655
656static void fwspk_card_free(struct snd_card *card)
657{
658 struct fwspk *fwspk = card->private_data;
659 struct fw_device *dev = fw_parent_device(fwspk->unit);
660
661 amdtp_out_stream_destroy(&fwspk->stream);
662 cmp_connection_destroy(&fwspk->connection);
663 fw_unit_put(fwspk->unit);
664 fw_device_put(dev);
665 mutex_destroy(&fwspk->mutex);
666}
667
668static const struct device_info *__devinit fwspk_detect(struct fw_device *dev)
669{
670 static const struct device_info griffin_firewave = {
671 .driver_name = "FireWave",
672 .short_name = "FireWave",
673 .long_name = "Griffin FireWave Surround",
674 .pcm_constraints = firewave_constraints,
675 .mixer_channels = 6,
676 .mute_fb_id = 0x01,
677 .volume_fb_id = 0x02,
678 };
679 static const struct device_info lacie_speakers = {
680 .driver_name = "FWSpeakers",
681 .short_name = "FireWire Speakers",
682 .long_name = "LaCie FireWire Speakers",
683 .pcm_constraints = lacie_speakers_constraints,
684 .mixer_channels = 1,
685 .mute_fb_id = 0x01,
686 .volume_fb_id = 0x01,
687 };
688 struct fw_csr_iterator i;
689 int key, value;
690
691 fw_csr_iterator_init(&i, dev->config_rom);
692 while (fw_csr_iterator_next(&i, &key, &value))
693 if (key == CSR_VENDOR)
694 switch (value) {
695 case VENDOR_GRIFFIN:
696 return &griffin_firewave;
697 case VENDOR_LACIE:
698 return &lacie_speakers;
699 }
700
701 return NULL;
702}
703
704static int __devinit fwspk_probe(struct device *unit_dev)
705{
706 struct fw_unit *unit = fw_unit(unit_dev);
707 struct fw_device *fw_dev = fw_parent_device(unit);
708 struct snd_card *card;
709 struct fwspk *fwspk;
710 u32 firmware;
711 int err;
712
713 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*fwspk), &card);
714 if (err < 0)
715 return err;
716 snd_card_set_dev(card, unit_dev);
717
718 fwspk = card->private_data;
719 fwspk->card = card;
720 mutex_init(&fwspk->mutex);
721 fw_device_get(fw_dev);
722 fwspk->unit = fw_unit_get(unit);
723 fwspk->device_info = fwspk_detect(fw_dev);
724 if (!fwspk->device_info) {
725 err = -ENODEV;
726 goto err_unit;
727 }
728
729 err = cmp_connection_init(&fwspk->connection, unit, 0);
730 if (err < 0)
731 goto err_unit;
732
733 err = amdtp_out_stream_init(&fwspk->stream, unit, CIP_NONBLOCKING);
734 if (err < 0)
735 goto err_connection;
736
737 card->private_free = fwspk_card_free;
738
739 strcpy(card->driver, fwspk->device_info->driver_name);
740 strcpy(card->shortname, fwspk->device_info->short_name);
741 firmware = fwspk_read_firmware_version(unit);
742 snprintf(card->longname, sizeof(card->longname),
743 "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
744 fwspk->device_info->long_name,
745 firmware >> 20, firmware & 0xffff,
746 fw_dev->config_rom[3], fw_dev->config_rom[4],
747 dev_name(&unit->device), 100 << fw_dev->max_speed);
748 strcpy(card->mixername, "OXFW970");
749
750 err = fwspk_create_pcm(fwspk);
751 if (err < 0)
752 goto error;
753
754 err = fwspk_create_mixer(fwspk);
755 if (err < 0)
756 goto error;
757
758 err = snd_card_register(card);
759 if (err < 0)
760 goto error;
761
762 dev_set_drvdata(unit_dev, fwspk);
763
764 return 0;
765
766err_connection:
767 cmp_connection_destroy(&fwspk->connection);
768err_unit:
769 fw_unit_put(fwspk->unit);
770 fw_device_put(fw_dev);
771 mutex_destroy(&fwspk->mutex);
772error:
773 snd_card_free(card);
774 return err;
775}
776
777static int __devexit fwspk_remove(struct device *dev)
778{
779 struct fwspk *fwspk = dev_get_drvdata(dev);
780
781 mutex_lock(&fwspk->mutex);
782 amdtp_out_stream_pcm_abort(&fwspk->stream);
783 snd_card_disconnect(fwspk->card);
784 fwspk_stop_stream(fwspk);
785 mutex_unlock(&fwspk->mutex);
786
787 snd_card_free_when_closed(fwspk->card);
788
789 return 0;
790}
791
792static void fwspk_bus_reset(struct fw_unit *unit)
793{
794 struct fwspk *fwspk = dev_get_drvdata(&unit->device);
795
796 fcp_bus_reset(fwspk->unit);
797
798 if (cmp_connection_update(&fwspk->connection) < 0) {
799 mutex_lock(&fwspk->mutex);
800 amdtp_out_stream_pcm_abort(&fwspk->stream);
801 fwspk_stop_stream(fwspk);
802 mutex_unlock(&fwspk->mutex);
803 return;
804 }
805
806 amdtp_out_stream_update(&fwspk->stream);
807}
808
809static const struct ieee1394_device_id fwspk_id_table[] = {
810 {
811 .match_flags = IEEE1394_MATCH_VENDOR_ID |
812 IEEE1394_MATCH_MODEL_ID |
813 IEEE1394_MATCH_SPECIFIER_ID |
814 IEEE1394_MATCH_VERSION,
815 .vendor_id = VENDOR_GRIFFIN,
816 .model_id = 0x00f970,
817 .specifier_id = SPECIFIER_1394TA,
818 .version = VERSION_AVC,
819 },
820 {
821 .match_flags = IEEE1394_MATCH_VENDOR_ID |
822 IEEE1394_MATCH_MODEL_ID |
823 IEEE1394_MATCH_SPECIFIER_ID |
824 IEEE1394_MATCH_VERSION,
825 .vendor_id = VENDOR_LACIE,
826 .model_id = 0x00f970,
827 .specifier_id = SPECIFIER_1394TA,
828 .version = VERSION_AVC,
829 },
830 { }
831};
832MODULE_DEVICE_TABLE(ieee1394, fwspk_id_table);
833
834static struct fw_driver fwspk_driver = {
835 .driver = {
836 .owner = THIS_MODULE,
837 .name = KBUILD_MODNAME,
838 .bus = &fw_bus_type,
839 .probe = fwspk_probe,
840 .remove = __devexit_p(fwspk_remove),
841 },
842 .update = fwspk_bus_reset,
843 .id_table = fwspk_id_table,
844};
845
846static int __init alsa_fwspk_init(void)
847{
848 return driver_register(&fwspk_driver.driver);
849}
850
851static void __exit alsa_fwspk_exit(void)
852{
853 driver_unregister(&fwspk_driver.driver);
854}
855
856module_init(alsa_fwspk_init);
857module_exit(alsa_fwspk_exit);