2 * TC Applied Technologies Digital Interface Communications Engine driver
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
8 #include <linux/compat.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/slab.h>
17 #include <linux/spinlock.h>
18 #include <linux/wait.h>
19 #include <sound/control.h>
20 #include <sound/core.h>
21 #include <sound/firewire.h>
22 #include <sound/hwdep.h>
23 #include <sound/initval.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
27 #include "iso-resources.h"
29 #include "dice-interface.h"
33 struct snd_card *card;
37 unsigned int global_offset;
38 unsigned int rx_offset;
39 struct fw_address_handler notification_handler;
41 int dev_lock_count; /* > 0 driver, < 0 userspace */
42 bool dev_lock_changed;
44 wait_queue_head_t hwdep_wait;
45 u32 notification_bits;
46 struct snd_pcm_substream *pcm;
47 struct fw_iso_resources resources;
48 struct amdtp_out_stream stream;
51 MODULE_DESCRIPTION("DICE driver");
52 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
53 MODULE_LICENSE("GPL v2");
55 static const unsigned int dice_rates[] = {
65 static void dice_lock_changed(struct dice *dice)
67 dice->dev_lock_changed = true;
68 wake_up(&dice->hwdep_wait);
71 static int dice_try_lock(struct dice *dice)
75 spin_lock_irq(&dice->lock);
77 if (dice->dev_lock_count < 0) {
82 if (dice->dev_lock_count++ == 0)
83 dice_lock_changed(dice);
87 spin_unlock_irq(&dice->lock);
92 static void dice_unlock(struct dice *dice)
94 spin_lock_irq(&dice->lock);
96 if (WARN_ON(dice->dev_lock_count <= 0))
99 if (--dice->dev_lock_count == 0)
100 dice_lock_changed(dice);
103 spin_unlock_irq(&dice->lock);
106 static inline u64 global_address(struct dice *dice, unsigned int offset)
108 return DICE_PRIVATE_SPACE + dice->global_offset + offset;
112 static inline u64 rx_address(struct dice *dice, unsigned int offset)
114 return DICE_PRIVATE_SPACE + dice->rx_offset + offset;
117 static int dice_owner_set(struct dice *dice)
119 struct fw_device *device = fw_parent_device(dice->unit);
121 int rcode, err, errors = 0;
123 buffer = kmalloc(2 * 8, GFP_KERNEL);
128 buffer[0] = cpu_to_be64(OWNER_NO_OWNER);
129 buffer[1] = cpu_to_be64(
130 ((u64)device->card->node_id << OWNER_NODE_SHIFT) |
131 dice->notification_handler.offset);
133 dice->owner_generation = device->generation;
134 smp_rmb(); /* node_id vs. generation */
135 rcode = fw_run_transaction(device->card,
136 TCODE_LOCK_COMPARE_SWAP,
138 dice->owner_generation,
140 global_address(dice, GLOBAL_OWNER),
143 if (rcode == RCODE_COMPLETE) {
144 if (buffer[0] == cpu_to_be64(OWNER_NO_OWNER)) {
147 dev_err(&dice->unit->device,
148 "device is already in use\n");
153 if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
154 dev_err(&dice->unit->device,
155 "setting device owner failed: %s\n",
156 fw_rcode_string(rcode));
168 static int dice_owner_update(struct dice *dice)
170 struct fw_device *device = fw_parent_device(dice->unit);
172 int rcode, err, errors = 0;
174 if (dice->owner_generation == -1)
177 buffer = kmalloc(2 * 8, GFP_KERNEL);
182 buffer[0] = cpu_to_be64(OWNER_NO_OWNER);
183 buffer[1] = cpu_to_be64(
184 ((u64)device->card->node_id << OWNER_NODE_SHIFT) |
185 dice->notification_handler.offset);
187 dice->owner_generation = device->generation;
188 smp_rmb(); /* node_id vs. generation */
189 rcode = fw_run_transaction(device->card,
190 TCODE_LOCK_COMPARE_SWAP,
192 dice->owner_generation,
194 global_address(dice, GLOBAL_OWNER),
197 if (rcode == RCODE_COMPLETE) {
198 if (buffer[0] == cpu_to_be64(OWNER_NO_OWNER)) {
201 dev_err(&dice->unit->device,
202 "device is already in use\n");
207 if (rcode == RCODE_GENERATION) {
208 err = 0; /* try again later */
211 if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
212 dev_err(&dice->unit->device,
213 "setting device owner failed: %s\n",
214 fw_rcode_string(rcode));
224 dice->owner_generation = -1;
229 static void dice_owner_clear(struct dice *dice)
231 struct fw_device *device = fw_parent_device(dice->unit);
233 int rcode, errors = 0;
235 buffer = kmalloc(2 * 8, GFP_KERNEL);
240 buffer[0] = cpu_to_be64(
241 ((u64)device->card->node_id << OWNER_NODE_SHIFT) |
242 dice->notification_handler.offset);
243 buffer[1] = cpu_to_be64(OWNER_NO_OWNER);
245 rcode = fw_run_transaction(device->card,
246 TCODE_LOCK_COMPARE_SWAP,
248 dice->owner_generation,
250 global_address(dice, GLOBAL_OWNER),
253 if (rcode == RCODE_COMPLETE)
255 if (rcode == RCODE_GENERATION)
257 if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
258 dev_err(&dice->unit->device,
259 "clearing device owner failed: %s\n",
260 fw_rcode_string(rcode));
268 dice->owner_generation = -1;
271 static int dice_enable_set(struct dice *dice)
273 struct fw_device *device = fw_parent_device(dice->unit);
275 int rcode, err, errors = 0;
277 value = cpu_to_be32(1);
279 rcode = fw_run_transaction(device->card,
280 TCODE_WRITE_QUADLET_REQUEST,
282 dice->owner_generation,
284 global_address(dice, GLOBAL_ENABLE),
286 if (rcode == RCODE_COMPLETE) {
287 dice->global_enabled = true;
291 if (rcode == RCODE_GENERATION) {
295 if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
296 dev_err(&dice->unit->device,
297 "device enabling failed: %s\n",
298 fw_rcode_string(rcode));
308 static void dice_enable_clear(struct dice *dice)
310 struct fw_device *device = fw_parent_device(dice->unit);
312 int rcode, errors = 0;
316 rcode = fw_run_transaction(device->card,
317 TCODE_WRITE_QUADLET_REQUEST,
319 dice->owner_generation,
321 global_address(dice, GLOBAL_ENABLE),
323 if (rcode == RCODE_COMPLETE ||
324 rcode == RCODE_GENERATION)
326 if (rcode_is_permanent_error(rcode) || ++errors >= 3) {
327 dev_err(&dice->unit->device,
328 "device disabling failed: %s\n",
329 fw_rcode_string(rcode));
334 dice->global_enabled = false;
337 static void dice_notification(struct fw_card *card, struct fw_request *request,
338 int tcode, int destination, int source,
339 int generation, unsigned long long offset,
340 void *data, size_t length, void *callback_data)
342 struct dice *dice = callback_data;
345 if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
346 fw_send_response(card, request, RCODE_TYPE_ERROR);
349 if ((offset & 3) != 0) {
350 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
353 spin_lock_irqsave(&dice->lock, flags);
354 dice->notification_bits |= be32_to_cpup(data);
355 spin_unlock_irqrestore(&dice->lock, flags);
356 fw_send_response(card, request, RCODE_COMPLETE);
357 wake_up(&dice->hwdep_wait);
360 static int dice_open(struct snd_pcm_substream *substream)
362 static const struct snd_pcm_hardware hardware = {
363 .info = SNDRV_PCM_INFO_MMAP |
364 SNDRV_PCM_INFO_MMAP_VALID |
365 SNDRV_PCM_INFO_BATCH |
366 SNDRV_PCM_INFO_INTERLEAVED |
367 SNDRV_PCM_INFO_BLOCK_TRANSFER,
368 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
369 .buffer_bytes_max = 16 * 1024 * 1024,
370 .period_bytes_min = 1,
371 .period_bytes_max = UINT_MAX,
373 .periods_max = UINT_MAX,
375 struct dice *dice = substream->private_data;
376 struct snd_pcm_runtime *runtime = substream->runtime;
377 __be32 clock_sel, number_audio, number_midi;
381 err = dice_try_lock(dice);
385 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
386 global_address(dice, GLOBAL_CLOCK_SELECT),
390 rate = (be32_to_cpu(clock_sel) & CLOCK_RATE_MASK) >> CLOCK_RATE_SHIFT;
391 if (rate >= ARRAY_SIZE(dice_rates)) {
395 rate = dice_rates[rate];
397 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
398 rx_address(dice, RX_NUMBER_AUDIO),
402 err = snd_fw_transaction(dice->unit, TCODE_READ_QUADLET_REQUEST,
403 rx_address(dice, RX_NUMBER_MIDI),
408 runtime->hw = hardware;
410 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
411 snd_pcm_limit_hw_rates(runtime);
413 runtime->hw.channels_min = be32_to_cpu(number_audio);
414 runtime->hw.channels_max = be32_to_cpu(number_audio);
416 amdtp_out_stream_set_rate(&dice->stream, rate);
417 amdtp_out_stream_set_pcm(&dice->stream, be32_to_cpu(number_audio));
418 amdtp_out_stream_set_midi(&dice->stream, be32_to_cpu(number_midi));
420 err = snd_pcm_hw_constraint_minmax(runtime,
421 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
426 err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
438 static int dice_close(struct snd_pcm_substream *substream)
440 struct dice *dice = substream->private_data;
447 static int dice_stream_start_packets(struct dice *dice)
451 if (amdtp_out_stream_running(&dice->stream))
454 err = amdtp_out_stream_start(&dice->stream, dice->resources.channel,
455 fw_parent_device(dice->unit)->max_speed);
459 err = dice_enable_set(dice);
461 amdtp_out_stream_stop(&dice->stream);
468 static int dice_stream_start(struct dice *dice)
473 if (!dice->resources.allocated) {
474 err = fw_iso_resources_allocate(&dice->resources,
475 amdtp_out_stream_get_max_payload(&dice->stream),
476 fw_parent_device(dice->unit)->max_speed);
480 channel = cpu_to_be32(dice->resources.channel);
481 err = snd_fw_transaction(dice->unit,
482 TCODE_WRITE_QUADLET_REQUEST,
483 rx_address(dice, RX_ISOCHRONOUS),
489 err = dice_stream_start_packets(dice);
496 channel = cpu_to_be32((u32)-1);
497 snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST,
498 rx_address(dice, RX_ISOCHRONOUS), &channel, 4);
500 fw_iso_resources_free(&dice->resources);
505 static void dice_stream_stop_packets(struct dice *dice)
507 if (amdtp_out_stream_running(&dice->stream)) {
508 dice_enable_clear(dice);
509 amdtp_out_stream_stop(&dice->stream);
513 static void dice_stream_stop(struct dice *dice)
517 dice_stream_stop_packets(dice);
519 if (!dice->resources.allocated)
522 channel = cpu_to_be32((u32)-1);
523 snd_fw_transaction(dice->unit, TCODE_WRITE_QUADLET_REQUEST,
524 rx_address(dice, RX_ISOCHRONOUS), &channel, 4);
526 fw_iso_resources_free(&dice->resources);
529 static int dice_hw_params(struct snd_pcm_substream *substream,
530 struct snd_pcm_hw_params *hw_params)
532 struct dice *dice = substream->private_data;
535 mutex_lock(&dice->mutex);
536 dice_stream_stop(dice);
537 mutex_unlock(&dice->mutex);
539 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
540 params_buffer_bytes(hw_params));
544 amdtp_out_stream_set_pcm_format(&dice->stream,
545 params_format(hw_params));
553 static int dice_hw_free(struct snd_pcm_substream *substream)
555 struct dice *dice = substream->private_data;
557 mutex_lock(&dice->mutex);
558 dice_stream_stop(dice);
559 mutex_unlock(&dice->mutex);
561 return snd_pcm_lib_free_vmalloc_buffer(substream);
564 static int dice_prepare(struct snd_pcm_substream *substream)
566 struct dice *dice = substream->private_data;
569 mutex_lock(&dice->mutex);
571 if (amdtp_out_streaming_error(&dice->stream))
572 dice_stream_stop_packets(dice);
574 err = dice_stream_start(dice);
576 mutex_unlock(&dice->mutex);
580 mutex_unlock(&dice->mutex);
582 amdtp_out_stream_pcm_prepare(&dice->stream);
587 static int dice_trigger(struct snd_pcm_substream *substream, int cmd)
589 struct dice *dice = substream->private_data;
590 struct snd_pcm_substream *pcm;
593 case SNDRV_PCM_TRIGGER_START:
596 case SNDRV_PCM_TRIGGER_STOP:
602 amdtp_out_stream_pcm_trigger(&dice->stream, pcm);
607 static snd_pcm_uframes_t dice_pointer(struct snd_pcm_substream *substream)
609 struct dice *dice = substream->private_data;
611 return amdtp_out_stream_pcm_pointer(&dice->stream);
614 static int dice_create_pcm(struct dice *dice)
616 static struct snd_pcm_ops ops = {
619 .ioctl = snd_pcm_lib_ioctl,
620 .hw_params = dice_hw_params,
621 .hw_free = dice_hw_free,
622 .prepare = dice_prepare,
623 .trigger = dice_trigger,
624 .pointer = dice_pointer,
625 .page = snd_pcm_lib_get_vmalloc_page,
626 .mmap = snd_pcm_lib_mmap_vmalloc,
631 err = snd_pcm_new(dice->card, "DICE", 0, 1, 0, &pcm);
634 pcm->private_data = dice;
635 strcpy(pcm->name, dice->card->shortname);
636 dice->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
637 dice->pcm->ops = &ops;
642 static long dice_hwdep_read(struct snd_hwdep *hwdep, char __user *buf,
643 long count, loff_t *offset)
645 struct dice *dice = hwdep->private_data;
647 union snd_firewire_event event;
649 spin_lock_irq(&dice->lock);
651 while (!dice->dev_lock_changed && dice->notification_bits == 0) {
652 prepare_to_wait(&dice->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
653 spin_unlock_irq(&dice->lock);
655 finish_wait(&dice->hwdep_wait, &wait);
656 if (signal_pending(current))
658 spin_lock_irq(&dice->lock);
661 memset(&event, 0, sizeof(event));
662 if (dice->dev_lock_changed) {
663 event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
664 event.lock_status.status = dice->dev_lock_count > 0;
665 dice->dev_lock_changed = false;
667 count = min(count, (long)sizeof(event.lock_status));
669 event.dice_notification.type = SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION;
670 event.dice_notification.notification = dice->notification_bits;
671 dice->notification_bits = 0;
673 count = min(count, (long)sizeof(event.dice_notification));
676 spin_unlock_irq(&dice->lock);
678 if (copy_to_user(buf, &event, count))
684 static unsigned int dice_hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
687 struct dice *dice = hwdep->private_data;
690 poll_wait(file, &dice->hwdep_wait, wait);
692 spin_lock_irq(&dice->lock);
693 if (dice->dev_lock_changed || dice->notification_bits != 0)
694 events = POLLIN | POLLRDNORM;
697 spin_unlock_irq(&dice->lock);
702 static int dice_hwdep_get_info(struct dice *dice, void __user *arg)
704 struct fw_device *dev = fw_parent_device(dice->unit);
705 struct snd_firewire_get_info info;
707 memset(&info, 0, sizeof(info));
708 info.type = SNDRV_FIREWIRE_TYPE_DICE;
709 info.card = dev->card->index;
710 *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
711 *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
712 strlcpy(info.device_name, dev_name(&dev->device),
713 sizeof(info.device_name));
715 if (copy_to_user(arg, &info, sizeof(info)))
721 static int dice_hwdep_lock(struct dice *dice)
725 spin_lock_irq(&dice->lock);
727 if (dice->dev_lock_count == 0) {
728 dice->dev_lock_count = -1;
734 spin_unlock_irq(&dice->lock);
739 static int dice_hwdep_unlock(struct dice *dice)
743 spin_lock_irq(&dice->lock);
745 if (dice->dev_lock_count == -1) {
746 dice->dev_lock_count = 0;
752 spin_unlock_irq(&dice->lock);
757 static int dice_hwdep_release(struct snd_hwdep *hwdep, struct file *file)
759 struct dice *dice = hwdep->private_data;
761 spin_lock_irq(&dice->lock);
762 if (dice->dev_lock_count == -1)
763 dice->dev_lock_count = 0;
764 spin_unlock_irq(&dice->lock);
769 static int dice_hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
770 unsigned int cmd, unsigned long arg)
772 struct dice *dice = hwdep->private_data;
775 case SNDRV_FIREWIRE_IOCTL_GET_INFO:
776 return dice_hwdep_get_info(dice, (void __user *)arg);
777 case SNDRV_FIREWIRE_IOCTL_LOCK:
778 return dice_hwdep_lock(dice);
779 case SNDRV_FIREWIRE_IOCTL_UNLOCK:
780 return dice_hwdep_unlock(dice);
787 static int dice_hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
788 unsigned int cmd, unsigned long arg)
790 return dice_hwdep_ioctl(hwdep, file, cmd,
791 (unsigned long)compat_ptr(arg));
794 #define dice_hwdep_compat_ioctl NULL
797 static int dice_create_hwdep(struct dice *dice)
799 static const struct snd_hwdep_ops ops = {
800 .read = dice_hwdep_read,
801 .release = dice_hwdep_release,
802 .poll = dice_hwdep_poll,
803 .ioctl = dice_hwdep_ioctl,
804 .ioctl_compat = dice_hwdep_compat_ioctl,
806 struct snd_hwdep *hwdep;
809 err = snd_hwdep_new(dice->card, "DICE", 0, &hwdep);
812 strcpy(hwdep->name, "DICE");
813 hwdep->iface = SNDRV_HWDEP_IFACE_FW_DICE;
815 hwdep->private_data = dice;
816 hwdep->exclusive = true;
821 static void dice_card_free(struct snd_card *card)
823 struct dice *dice = card->private_data;
825 amdtp_out_stream_destroy(&dice->stream);
826 fw_core_remove_address_handler(&dice->notification_handler);
827 mutex_destroy(&dice->mutex);
830 #define DICE_CATEGORY_ID 0x04
832 static int dice_interface_check(struct fw_unit *unit)
834 static const int min_values[10] = {
841 struct fw_device *device = fw_parent_device(unit);
842 struct fw_csr_iterator it;
843 int key, value, vendor = -1, model = -1, err;
845 __be32 pointers[ARRAY_SIZE(min_values)];
849 * Check that GUID and unit directory are constructed according to DICE
850 * rules, i.e., that the specifier ID is the GUID's OUI, and that the
851 * GUID chip ID consists of the 8-bit DICE category ID, the 10-bit
852 * product ID, and a 22-bit serial number.
854 fw_csr_iterator_init(&it, unit->directory);
855 while (fw_csr_iterator_next(&it, &key, &value)) {
857 case CSR_SPECIFIER_ID:
865 if (device->config_rom[3] != ((vendor << 8) | DICE_CATEGORY_ID) ||
866 device->config_rom[4] >> 22 != model)
870 * Check that the sub address spaces exist and are located inside the
871 * private address space. The minimum values are chosen so that all
872 * minimally required registers are included.
874 err = snd_fw_transaction(unit, TCODE_READ_BLOCK_REQUEST,
876 pointers, sizeof(pointers));
879 for (i = 0; i < ARRAY_SIZE(pointers); ++i) {
880 value = be32_to_cpu(pointers[i]);
881 if (value < min_values[i] || value >= 0x40000)
886 * Check that the implemented DICE driver specification major version
889 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
891 be32_to_cpu(pointers[0]) * 4 + GLOBAL_VERSION,
895 if ((version & cpu_to_be32(0xff000000)) != cpu_to_be32(0x01000000)) {
896 dev_err(&unit->device,
897 "unknown DICE version: 0x%08x\n", be32_to_cpu(version));
904 static int dice_init_offsets(struct dice *dice)
909 err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST,
911 pointers, sizeof(pointers));
915 dice->global_offset = be32_to_cpu(pointers[0]) * 4;
916 dice->rx_offset = be32_to_cpu(pointers[4]) * 4;
921 static void dice_card_strings(struct dice *dice)
923 struct snd_card *card = dice->card;
924 struct fw_device *dev = fw_parent_device(dice->unit);
925 char vendor[32], model[32];
929 strcpy(card->driver, "DICE");
931 strcpy(card->shortname, "DICE");
932 BUILD_BUG_ON(NICK_NAME_SIZE < sizeof(card->shortname));
933 err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST,
934 global_address(dice, GLOBAL_NICK_NAME),
935 card->shortname, sizeof(card->shortname));
937 /* DICE strings are returned in "always-wrong" endianness */
938 BUILD_BUG_ON(sizeof(card->shortname) % 4 != 0);
939 for (i = 0; i < sizeof(card->shortname); i += 4)
940 swab32s((u32 *)&card->shortname[i]);
941 card->shortname[sizeof(card->shortname) - 1] = '\0';
945 fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor));
947 fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model));
948 snprintf(card->longname, sizeof(card->longname),
949 "%s %s (serial %u) at %s, S%d",
950 vendor, model, dev->config_rom[4] & 0x3fffff,
951 dev_name(&dice->unit->device), 100 << dev->max_speed);
953 strcpy(card->mixername, "DICE");
956 static int dice_probe(struct fw_unit *unit, const struct ieee1394_device_id *id)
958 struct snd_card *card;
963 err = dice_interface_check(unit);
967 err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*dice), &card);
970 snd_card_set_dev(card, &unit->device);
972 dice = card->private_data;
974 spin_lock_init(&dice->lock);
975 mutex_init(&dice->mutex);
977 init_waitqueue_head(&dice->hwdep_wait);
979 err = dice_init_offsets(dice);
983 dice->notification_handler.length = 4;
984 dice->notification_handler.address_callback = dice_notification;
985 dice->notification_handler.callback_data = dice;
986 err = fw_core_add_address_handler(&dice->notification_handler,
987 &fw_high_memory_region);
991 err = fw_iso_resources_init(&dice->resources, unit);
993 goto err_notification_handler;
994 dice->resources.channels_mask = 0x00000000ffffffffuLL;
996 err = amdtp_out_stream_init(&dice->stream, unit, CIP_BLOCKING);
1000 err = dice_owner_set(dice);
1004 card->private_free = dice_card_free;
1006 dice_card_strings(dice);
1008 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
1009 global_address(dice, GLOBAL_CLOCK_SELECT),
1013 clock_sel &= cpu_to_be32(~CLOCK_SOURCE_MASK);
1014 clock_sel |= cpu_to_be32(CLOCK_SOURCE_ARX1);
1015 err = snd_fw_transaction(unit, TCODE_WRITE_QUADLET_REQUEST,
1016 global_address(dice, GLOBAL_CLOCK_SELECT),
1021 err = dice_create_pcm(dice);
1025 err = dice_create_hwdep(dice);
1029 err = snd_card_register(card);
1033 dev_set_drvdata(&unit->device, dice);
1038 amdtp_out_stream_destroy(&dice->stream);
1040 fw_iso_resources_destroy(&dice->resources);
1041 err_notification_handler:
1042 fw_core_remove_address_handler(&dice->notification_handler);
1044 mutex_destroy(&dice->mutex);
1046 snd_card_free(card);
1050 static void dice_remove(struct fw_unit *unit)
1052 struct dice *dice = dev_get_drvdata(&unit->device);
1054 mutex_lock(&dice->mutex);
1056 amdtp_out_stream_pcm_abort(&dice->stream);
1058 snd_card_disconnect(dice->card);
1060 dice_stream_stop(dice);
1061 dice_owner_clear(dice);
1063 mutex_unlock(&dice->mutex);
1065 snd_card_free_when_closed(dice->card);
1068 static void dice_bus_reset(struct fw_unit *unit)
1070 struct dice *dice = dev_get_drvdata(&unit->device);
1072 mutex_lock(&dice->mutex);
1075 * On a bus reset, the DICE firmware disables streaming and then goes
1076 * off contemplating its own navel for hundreds of milliseconds before
1077 * it can react to any of our attempts to reenable streaming. This
1078 * means that we lose synchronization anyway, so we force our streams
1079 * to stop so that the application can restart them in an orderly
1082 amdtp_out_stream_pcm_abort(&dice->stream);
1083 dice_stream_stop_packets(dice);
1085 dice_owner_update(dice);
1087 fw_iso_resources_update(&dice->resources);
1089 mutex_unlock(&dice->mutex);
1092 #define DICE_INTERFACE 0x000001
1094 static const struct ieee1394_device_id dice_id_table[] = {
1096 .match_flags = IEEE1394_MATCH_VERSION,
1097 .version = DICE_INTERFACE,
1101 MODULE_DEVICE_TABLE(ieee1394, dice_id_table);
1103 static struct fw_driver dice_driver = {
1105 .owner = THIS_MODULE,
1106 .name = KBUILD_MODNAME,
1107 .bus = &fw_bus_type,
1109 .probe = dice_probe,
1110 .update = dice_bus_reset,
1111 .remove = dice_remove,
1112 .id_table = dice_id_table,
1115 static int __init alsa_dice_init(void)
1117 return driver_register(&dice_driver.driver);
1120 static void __exit alsa_dice_exit(void)
1122 driver_unregister(&dice_driver.driver);
1125 module_init(alsa_dice_init);
1126 module_exit(alsa_dice_exit);