ALSA: dice: ensure transmission speed for transmitted packets
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 3 Jan 2017 03:44:43 +0000 (12:44 +0900)
committerTakashi Iwai <tiwai@suse.de>
Tue, 3 Jan 2017 10:38:39 +0000 (11:38 +0100)
As of kernel 4.10, ALSA dice driver is expected to be used in default
speed. In most cases, it's S400. While, IEEE 1394 specification describes
the other speed such as S800.

According to 'TCD30XX User Guide', its link layer controller supports
several transmission speed up to S800[0]. In Dice software interface,
transmission speed in output direction can be configured by asynchronous
transaction to 'TX_SPEED' offset in its address space. S800 may be
available.

This commit improves configuration of transmission unit before starting
packet streaming for this purpose. The value of 'max_speed' in 'fw_device'
data structure has available maximum speed decided in bus arbitration,
thus it's within capacity of the unit.

[0] TCD3xx User Guide - TCAT 1394 LLC, Revision 0.9.0-41360 (TC Applied Technologies, May 6 2015)
http://www.tctechnologies.tc/index.php/support/support-hardware/dice-iii-detailed-documentation

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/firewire/dice/dice-interface.h
sound/firewire/dice/dice-stream.c

index 27b044f84c816f5b4f15efa9782b7c4fbd1a217d..47f2c0a6f5d9b3b566fdc95757145acadaccec16 100644 (file)
 
 /*
  * The speed at which the packets are sent, SCODE_100-_400; read/write.
+ * SCODE_800 is only available in Dice III.
  */
 #define TX_SPEED                       0x014
 
index ec4db3a514fce3c4f16c2b8c38a71ad2e9a77d4e..8573289c381ed7314c6e1a08d4b39191756941f9 100644 (file)
@@ -195,6 +195,7 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
        unsigned int i, pcm_chs, midi_ports;
        struct amdtp_stream *streams;
        struct fw_iso_resources *resources;
+       struct fw_device *fw_dev = fw_parent_device(dice->unit);
        int err = 0;
 
        if (dir == AMDTP_IN_STREAM) {
@@ -237,8 +238,17 @@ static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
                if (err < 0)
                        return err;
 
+               if (dir == AMDTP_IN_STREAM) {
+                       reg[0] = cpu_to_be32(fw_dev->max_speed);
+                       err = snd_dice_transaction_write_tx(dice,
+                                       params->size * i + TX_SPEED,
+                                       reg, sizeof(reg[0]));
+                       if (err < 0)
+                               return err;
+               }
+
                err = amdtp_stream_start(&streams[i], resources[i].channel,
-                               fw_parent_device(dice->unit)->max_speed);
+                                        fw_dev->max_speed);
                if (err < 0)
                        return err;
        }