aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2014-04-25 09:45:01 -0400
committerTakashi Iwai <tiwai@suse.de>2014-05-26 08:24:03 -0400
commitbde8a8f23bbe6db51fa4e81644273af18fef3d7a (patch)
tree92ea0fbb1023bda284156ac561640f4502132409 /sound
parentb5b04336015e76eb52ffc188e16c9cee01821c7c (diff)
ALSA: fireworks: Add transaction and some commands
Fireworks uses own command and response. This commit adds functionality to transact and adds some commands required for sound card instance and kernel streaming. There are two ways to deliver substance of this transaction: 1.AV/C vendor dependent command for command/response 2.Async transaction to specific addresses for command/response By way 1, I confirm AudioFire12 cannot correctly response to some commands with firmware version 5.0 or later. This is also confirmed by FFADO. So this driver implement way 2. The address for response gives an issue. When this driver allocate own callback function into the address, then no one can allocate its own callback function. This situation is not good for applications in user-land. This issue is solved in later commit. I note there is a command to change the address for response if the device supports. But this driver uses default value. So users should not execute this command as long as hoping this driver works correctly. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/firewire/Kconfig1
-rw-r--r--sound/firewire/fireworks/Makefile2
-rw-r--r--sound/firewire/fireworks/fireworks.c69
-rw-r--r--sound/firewire/fireworks/fireworks.h126
-rw-r--r--sound/firewire/fireworks/fireworks_command.c370
-rw-r--r--sound/firewire/fireworks/fireworks_transaction.c190
6 files changed, 751 insertions, 7 deletions
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 8cd4f1f940b0..0b85ebd60920 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -63,6 +63,7 @@ config SND_SCS1X
63 63
64config SND_FIREWORKS 64config SND_FIREWORKS
65 tristate "Echo Fireworks board module support" 65 tristate "Echo Fireworks board module support"
66 select SND_FIREWIRE_LIB
66 help 67 help
67 Say Y here to include support for FireWire devices based 68 Say Y here to include support for FireWire devices based
68 on Echo Digital Audio Fireworks board: 69 on Echo Digital Audio Fireworks board:
diff --git a/sound/firewire/fireworks/Makefile b/sound/firewire/fireworks/Makefile
index 99f6fc385a45..a6ce2147e0ab 100644
--- a/sound/firewire/fireworks/Makefile
+++ b/sound/firewire/fireworks/Makefile
@@ -1,2 +1,2 @@
1snd-fireworks-objs := fireworks.o 1snd-fireworks-objs := fireworks_transaction.o fireworks_command.o fireworks.o
2obj-m += snd-fireworks.o 2obj-m += snd-fireworks.o
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
index ad719a1d5353..6fa3a5d725d5 100644
--- a/sound/firewire/fireworks/fireworks.c
+++ b/sound/firewire/fireworks/fireworks.c
@@ -59,6 +59,50 @@ static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
59/* unknown as product */ 59/* unknown as product */
60#define MODEL_GIBSON_GOLDTOP 0x00afb9 60#define MODEL_GIBSON_GOLDTOP 0x00afb9
61 61
62/* part of hardware capability flags */
63#define FLAG_RESP_ADDR_CHANGABLE 0
64
65static int
66get_hardware_info(struct snd_efw *efw)
67{
68 struct fw_device *fw_dev = fw_parent_device(efw->unit);
69 struct snd_efw_hwinfo *hwinfo;
70 char version[12] = {0};
71 int err;
72
73 hwinfo = kzalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL);
74 if (hwinfo == NULL)
75 return -ENOMEM;
76
77 err = snd_efw_command_get_hwinfo(efw, hwinfo);
78 if (err < 0)
79 goto end;
80
81 /* firmware version for communication chipset */
82 snprintf(version, sizeof(version), "%u.%u",
83 (hwinfo->arm_version >> 24) & 0xff,
84 (hwinfo->arm_version >> 16) & 0xff);
85 if (err < 0)
86 goto end;
87
88 strcpy(efw->card->driver, "Fireworks");
89 strcpy(efw->card->shortname, hwinfo->model_name);
90 strcpy(efw->card->mixername, hwinfo->model_name);
91 snprintf(efw->card->longname, sizeof(efw->card->longname),
92 "%s %s v%s, GUID %08x%08x at %s, S%d",
93 hwinfo->vendor_name, hwinfo->model_name, version,
94 hwinfo->guid_hi, hwinfo->guid_lo,
95 dev_name(&efw->unit->device), 100 << fw_dev->max_speed);
96 if (err < 0)
97 goto end;
98
99 if (hwinfo->flags & BIT(FLAG_RESP_ADDR_CHANGABLE))
100 efw->resp_addr_changable = true;
101end:
102 kfree(hwinfo);
103 return err;
104}
105
62static void 106static void
63efw_card_free(struct snd_card *card) 107efw_card_free(struct snd_card *card)
64{ 108{
@@ -107,14 +151,14 @@ efw_probe(struct fw_unit *unit,
107 mutex_init(&efw->mutex); 151 mutex_init(&efw->mutex);
108 spin_lock_init(&efw->lock); 152 spin_lock_init(&efw->lock);
109 153
110 strcpy(efw->card->driver, "Fireworks"); 154 err = get_hardware_info(efw);
111 strcpy(efw->card->shortname, efw->card->driver); 155 if (err < 0)
112 strcpy(efw->card->longname, efw->card->driver); 156 goto error;
113 strcpy(efw->card->mixername, efw->card->driver);
114 157
115 err = snd_card_register(card); 158 err = snd_card_register(card);
116 if (err < 0) 159 if (err < 0)
117 goto error; 160 goto error;
161
118 dev_set_drvdata(&unit->device, efw); 162 dev_set_drvdata(&unit->device, efw);
119end: 163end:
120 mutex_unlock(&devices_mutex); 164 mutex_unlock(&devices_mutex);
@@ -127,7 +171,8 @@ error:
127 171
128static void efw_update(struct fw_unit *unit) 172static void efw_update(struct fw_unit *unit)
129{ 173{
130 return; 174 struct snd_efw *efw = dev_get_drvdata(&unit->device);
175 snd_efw_transaction_bus_reset(efw->unit);
131} 176}
132 177
133static void efw_remove(struct fw_unit *unit) 178static void efw_remove(struct fw_unit *unit)
@@ -169,11 +214,23 @@ static struct fw_driver efw_driver = {
169 214
170static int __init snd_efw_init(void) 215static int __init snd_efw_init(void)
171{ 216{
172 return driver_register(&efw_driver.driver); 217 int err;
218
219 err = snd_efw_transaction_register();
220 if (err < 0)
221 goto end;
222
223 err = driver_register(&efw_driver.driver);
224 if (err < 0)
225 snd_efw_transaction_unregister();
226
227end:
228 return err;
173} 229}
174 230
175static void __exit snd_efw_exit(void) 231static void __exit snd_efw_exit(void)
176{ 232{
233 snd_efw_transaction_unregister();
177 driver_unregister(&efw_driver.driver); 234 driver_unregister(&efw_driver.driver);
178 mutex_destroy(&devices_mutex); 235 mutex_destroy(&devices_mutex);
179} 236}
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
index 9dfeb8210e71..e999802ab470 100644
--- a/sound/firewire/fireworks/fireworks.h
+++ b/sound/firewire/fireworks/fireworks.h
@@ -20,6 +20,28 @@
20 20
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/pcm.h>
24
25#include "../cmp.h"
26#include "../lib.h"
27
28#define SND_EFW_MULTIPLIER_MODES 3
29#define HWINFO_NAME_SIZE_BYTES 32
30#define HWINFO_MAX_CAPS_GROUPS 8
31
32/*
33 * This should be greater than maximum bytes for EFW response content.
34 * Currently response against command for isochronous channel mapping is
35 * confirmed to be the maximum one. But for flexibility, use maximum data
36 * payload for asynchronous primary packets at S100 (Cable base rate) in
37 * IEEE Std 1394-1995.
38 */
39#define SND_EFW_RESPONSE_MAXIMUM_BYTES 0x200U
40
41struct snd_efw_phys_grp {
42 u8 type; /* see enum snd_efw_grp_type */
43 u8 count;
44} __packed;
23 45
24struct snd_efw { 46struct snd_efw {
25 struct snd_card *card; 47 struct snd_card *card;
@@ -28,7 +50,111 @@ struct snd_efw {
28 50
29 struct mutex mutex; 51 struct mutex mutex;
30 spinlock_t lock; 52 spinlock_t lock;
53
54 /* for transaction */
55 u32 seqnum;
56 bool resp_addr_changable;
57};
58
59struct snd_efw_transaction {
60 __be32 length;
61 __be32 version;
62 __be32 seqnum;
63 __be32 category;
64 __be32 command;
65 __be32 status;
66 __be32 params[0];
67};
68int snd_efw_transaction_run(struct fw_unit *unit,
69 const void *cmd, unsigned int cmd_size,
70 void *resp, unsigned int resp_size);
71int snd_efw_transaction_register(void);
72void snd_efw_transaction_unregister(void);
73void snd_efw_transaction_bus_reset(struct fw_unit *unit);
74
75struct snd_efw_hwinfo {
76 u32 flags;
77 u32 guid_hi;
78 u32 guid_lo;
79 u32 type;
80 u32 version;
81 char vendor_name[HWINFO_NAME_SIZE_BYTES];
82 char model_name[HWINFO_NAME_SIZE_BYTES];
83 u32 supported_clocks;
84 u32 amdtp_rx_pcm_channels;
85 u32 amdtp_tx_pcm_channels;
86 u32 phys_out;
87 u32 phys_in;
88 u32 phys_out_grp_count;
89 struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS];
90 u32 phys_in_grp_count;
91 struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS];
92 u32 midi_out_ports;
93 u32 midi_in_ports;
94 u32 max_sample_rate;
95 u32 min_sample_rate;
96 u32 dsp_version;
97 u32 arm_version;
98 u32 mixer_playback_channels;
99 u32 mixer_capture_channels;
100 u32 fpga_version;
101 u32 amdtp_rx_pcm_channels_2x;
102 u32 amdtp_tx_pcm_channels_2x;
103 u32 amdtp_rx_pcm_channels_4x;
104 u32 amdtp_tx_pcm_channels_4x;
105 u32 reserved[16];
106} __packed;
107enum snd_efw_grp_type {
108 SND_EFW_CH_TYPE_ANALOG = 0,
109 SND_EFW_CH_TYPE_SPDIF = 1,
110 SND_EFW_CH_TYPE_ADAT = 2,
111 SND_EFW_CH_TYPE_SPDIF_OR_ADAT = 3,
112 SND_EFW_CH_TYPE_ANALOG_MIRRORING = 4,
113 SND_EFW_CH_TYPE_HEADPHONES = 5,
114 SND_EFW_CH_TYPE_I2S = 6,
115 SND_EFW_CH_TYPE_GUITAR = 7,
116 SND_EFW_CH_TYPE_PIEZO_GUITAR = 8,
117 SND_EFW_CH_TYPE_GUITAR_STRING = 9,
118 SND_EFW_CH_TYPE_VIRTUAL = 0x10000,
119 SND_EFW_CH_TYPE_DUMMY
120};
121struct snd_efw_phys_meters {
122 u32 status; /* guitar state/midi signal/clock input detect */
123 u32 reserved0;
124 u32 reserved1;
125 u32 reserved2;
126 u32 reserved3;
127 u32 out_meters;
128 u32 in_meters;
129 u32 reserved4;
130 u32 reserved5;
131 u32 values[0];
132} __packed;
133enum snd_efw_clock_source {
134 SND_EFW_CLOCK_SOURCE_INTERNAL = 0,
135 SND_EFW_CLOCK_SOURCE_SYTMATCH = 1,
136 SND_EFW_CLOCK_SOURCE_WORDCLOCK = 2,
137 SND_EFW_CLOCK_SOURCE_SPDIF = 3,
138 SND_EFW_CLOCK_SOURCE_ADAT_1 = 4,
139 SND_EFW_CLOCK_SOURCE_ADAT_2 = 5,
140 SND_EFW_CLOCK_SOURCE_CONTINUOUS = 6 /* internal variable clock */
141};
142enum snd_efw_transport_mode {
143 SND_EFW_TRANSPORT_MODE_WINDOWS = 0,
144 SND_EFW_TRANSPORT_MODE_IEC61883 = 1,
31}; 145};
146int snd_efw_command_set_resp_addr(struct snd_efw *efw,
147 u16 addr_high, u32 addr_low);
148int snd_efw_command_set_tx_mode(struct snd_efw *efw, unsigned int mode);
149int snd_efw_command_get_hwinfo(struct snd_efw *efw,
150 struct snd_efw_hwinfo *hwinfo);
151int snd_efw_command_get_phys_meters(struct snd_efw *efw,
152 struct snd_efw_phys_meters *meters,
153 unsigned int len);
154int snd_efw_command_get_clock_source(struct snd_efw *efw,
155 enum snd_efw_clock_source *source);
156int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate);
157int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate);
32 158
33#define SND_EFW_DEV_ENTRY(vendor, model) \ 159#define SND_EFW_DEV_ENTRY(vendor, model) \
34{ \ 160{ \
diff --git a/sound/firewire/fireworks/fireworks_command.c b/sound/firewire/fireworks/fireworks_command.c
new file mode 100644
index 000000000000..d5ea7051ad0c
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_command.c
@@ -0,0 +1,370 @@
1/*
2 * fireworks_command.c - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2013-2014 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9#include "./fireworks.h"
10
11/*
12 * This driver uses transaction version 1 or later to use extended hardware
13 * information. Then too old devices are not available.
14 *
15 * Each commands are not required to have continuous sequence numbers. This
16 * number is just used to match command and response.
17 *
18 * This module support a part of commands. Please see FFADO if you want to see
19 * whole commands. But there are some commands which FFADO don't implement.
20 *
21 * Fireworks also supports AV/C general commands and AV/C Stream Format
22 * Information commands. But this module don't use them.
23 */
24
25#define EFW_TRANSACTION_SEQNUM_MAX ((u32)~0)
26
27/* for clock source and sampling rate */
28struct efc_clock {
29 u32 source;
30 u32 sampling_rate;
31 u32 index;
32};
33
34/* command categories */
35enum efc_category {
36 EFC_CAT_HWINFO = 0,
37 EFC_CAT_TRANSPORT = 2,
38 EFC_CAT_HWCTL = 3,
39};
40
41/* hardware info category commands */
42enum efc_cmd_hwinfo {
43 EFC_CMD_HWINFO_GET_CAPS = 0,
44 EFC_CMD_HWINFO_GET_POLLED = 1,
45 EFC_CMD_HWINFO_SET_RESP_ADDR = 2
46};
47
48enum efc_cmd_transport {
49 EFC_CMD_TRANSPORT_SET_TX_MODE = 0
50};
51
52/* hardware control category commands */
53enum efc_cmd_hwctl {
54 EFC_CMD_HWCTL_SET_CLOCK = 0,
55 EFC_CMD_HWCTL_GET_CLOCK = 1,
56 EFC_CMD_HWCTL_IDENTIFY = 5
57};
58
59/* return values in response */
60enum efr_status {
61 EFR_STATUS_OK = 0,
62 EFR_STATUS_BAD = 1,
63 EFR_STATUS_BAD_COMMAND = 2,
64 EFR_STATUS_COMM_ERR = 3,
65 EFR_STATUS_BAD_QUAD_COUNT = 4,
66 EFR_STATUS_UNSUPPORTED = 5,
67 EFR_STATUS_1394_TIMEOUT = 6,
68 EFR_STATUS_DSP_TIMEOUT = 7,
69 EFR_STATUS_BAD_RATE = 8,
70 EFR_STATUS_BAD_CLOCK = 9,
71 EFR_STATUS_BAD_CHANNEL = 10,
72 EFR_STATUS_BAD_PAN = 11,
73 EFR_STATUS_FLASH_BUSY = 12,
74 EFR_STATUS_BAD_MIRROR = 13,
75 EFR_STATUS_BAD_LED = 14,
76 EFR_STATUS_BAD_PARAMETER = 15,
77 EFR_STATUS_INCOMPLETE = 0x80000000
78};
79
80static const char *const efr_status_names[] = {
81 [EFR_STATUS_OK] = "OK",
82 [EFR_STATUS_BAD] = "bad",
83 [EFR_STATUS_BAD_COMMAND] = "bad command",
84 [EFR_STATUS_COMM_ERR] = "comm err",
85 [EFR_STATUS_BAD_QUAD_COUNT] = "bad quad count",
86 [EFR_STATUS_UNSUPPORTED] = "unsupported",
87 [EFR_STATUS_1394_TIMEOUT] = "1394 timeout",
88 [EFR_STATUS_DSP_TIMEOUT] = "DSP timeout",
89 [EFR_STATUS_BAD_RATE] = "bad rate",
90 [EFR_STATUS_BAD_CLOCK] = "bad clock",
91 [EFR_STATUS_BAD_CHANNEL] = "bad channel",
92 [EFR_STATUS_BAD_PAN] = "bad pan",
93 [EFR_STATUS_FLASH_BUSY] = "flash busy",
94 [EFR_STATUS_BAD_MIRROR] = "bad mirror",
95 [EFR_STATUS_BAD_LED] = "bad LED",
96 [EFR_STATUS_BAD_PARAMETER] = "bad parameter",
97 [EFR_STATUS_BAD_PARAMETER + 1] = "incomplete"
98};
99
100static int
101efw_transaction(struct snd_efw *efw, unsigned int category,
102 unsigned int command,
103 const __be32 *params, unsigned int param_bytes,
104 const __be32 *resp, unsigned int resp_bytes)
105{
106 struct snd_efw_transaction *header;
107 __be32 *buf;
108 u32 seqnum;
109 unsigned int buf_bytes, cmd_bytes;
110 int err;
111
112 /* calculate buffer size*/
113 buf_bytes = sizeof(struct snd_efw_transaction) +
114 max(param_bytes, resp_bytes);
115
116 /* keep buffer */
117 buf = kzalloc(buf_bytes, GFP_KERNEL);
118 if (buf == NULL)
119 return -ENOMEM;
120
121 /* to keep consistency of sequence number */
122 spin_lock(&efw->lock);
123 if (efw->seqnum + 2 >= EFW_TRANSACTION_SEQNUM_MAX)
124 efw->seqnum = 0;
125 else
126 efw->seqnum += 2;
127 seqnum = efw->seqnum;
128 spin_unlock(&efw->lock);
129
130 /* fill transaction header fields */
131 cmd_bytes = sizeof(struct snd_efw_transaction) + param_bytes;
132 header = (struct snd_efw_transaction *)buf;
133 header->length = cpu_to_be32(cmd_bytes / sizeof(__be32));
134 header->version = cpu_to_be32(1);
135 header->seqnum = cpu_to_be32(seqnum);
136 header->category = cpu_to_be32(category);
137 header->command = cpu_to_be32(command);
138 header->status = 0;
139
140 /* fill transaction command parameters */
141 memcpy(header->params, params, param_bytes);
142
143 err = snd_efw_transaction_run(efw->unit, buf, cmd_bytes,
144 buf, buf_bytes);
145 if (err < 0)
146 goto end;
147
148 /* check transaction header fields */
149 if ((be32_to_cpu(header->version) < 1) ||
150 (be32_to_cpu(header->category) != category) ||
151 (be32_to_cpu(header->command) != command) ||
152 (be32_to_cpu(header->status) != EFR_STATUS_OK)) {
153 dev_err(&efw->unit->device, "EFW command failed [%u/%u]: %s\n",
154 be32_to_cpu(header->category),
155 be32_to_cpu(header->command),
156 efr_status_names[be32_to_cpu(header->status)]);
157 err = -EIO;
158 goto end;
159 }
160
161 if (resp == NULL)
162 goto end;
163
164 /* fill transaction response parameters */
165 memset((void *)resp, 0, resp_bytes);
166 resp_bytes = min_t(unsigned int, resp_bytes,
167 be32_to_cpu(header->length) * sizeof(__be32) -
168 sizeof(struct snd_efw_transaction));
169 memcpy((void *)resp, &buf[6], resp_bytes);
170end:
171 kfree(buf);
172 return err;
173}
174
175/*
176 * The address in host system for transaction response is changable when the
177 * device supports. struct hwinfo.flags includes its flag. The default is
178 * MEMORY_SPACE_EFW_RESPONSE.
179 */
180int snd_efw_command_set_resp_addr(struct snd_efw *efw,
181 u16 addr_high, u32 addr_low)
182{
183 __be32 addr[2];
184
185 addr[0] = cpu_to_be32(addr_high);
186 addr[1] = cpu_to_be32(addr_low);
187
188 if (!efw->resp_addr_changable)
189 return -ENOSYS;
190
191 return efw_transaction(efw, EFC_CAT_HWCTL,
192 EFC_CMD_HWINFO_SET_RESP_ADDR,
193 addr, sizeof(addr), NULL, 0);
194}
195
196/*
197 * This is for timestamp processing. In Windows mode, all 32bit fields of second
198 * CIP header in AMDTP transmit packet is used for 'presentation timestamp'. In
199 * 'no data' packet the value of this field is 0x90ffffff.
200 */
201int snd_efw_command_set_tx_mode(struct snd_efw *efw,
202 enum snd_efw_transport_mode mode)
203{
204 __be32 param = cpu_to_be32(mode);
205 return efw_transaction(efw, EFC_CAT_TRANSPORT,
206 EFC_CMD_TRANSPORT_SET_TX_MODE,
207 &param, sizeof(param), NULL, 0);
208}
209
210int snd_efw_command_get_hwinfo(struct snd_efw *efw,
211 struct snd_efw_hwinfo *hwinfo)
212{
213 int err;
214
215 err = efw_transaction(efw, EFC_CAT_HWINFO,
216 EFC_CMD_HWINFO_GET_CAPS,
217 NULL, 0, (__be32 *)hwinfo, sizeof(*hwinfo));
218 if (err < 0)
219 goto end;
220
221 be32_to_cpus(&hwinfo->flags);
222 be32_to_cpus(&hwinfo->guid_hi);
223 be32_to_cpus(&hwinfo->guid_lo);
224 be32_to_cpus(&hwinfo->type);
225 be32_to_cpus(&hwinfo->version);
226 be32_to_cpus(&hwinfo->supported_clocks);
227 be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels);
228 be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels);
229 be32_to_cpus(&hwinfo->phys_out);
230 be32_to_cpus(&hwinfo->phys_in);
231 be32_to_cpus(&hwinfo->phys_out_grp_count);
232 be32_to_cpus(&hwinfo->phys_in_grp_count);
233 be32_to_cpus(&hwinfo->midi_out_ports);
234 be32_to_cpus(&hwinfo->midi_in_ports);
235 be32_to_cpus(&hwinfo->max_sample_rate);
236 be32_to_cpus(&hwinfo->min_sample_rate);
237 be32_to_cpus(&hwinfo->dsp_version);
238 be32_to_cpus(&hwinfo->arm_version);
239 be32_to_cpus(&hwinfo->mixer_playback_channels);
240 be32_to_cpus(&hwinfo->mixer_capture_channels);
241 be32_to_cpus(&hwinfo->fpga_version);
242 be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels_2x);
243 be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels_2x);
244 be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels_4x);
245 be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels_4x);
246
247 /* ensure terminated */
248 hwinfo->vendor_name[HWINFO_NAME_SIZE_BYTES - 1] = '\0';
249 hwinfo->model_name[HWINFO_NAME_SIZE_BYTES - 1] = '\0';
250end:
251 return err;
252}
253
254int snd_efw_command_get_phys_meters(struct snd_efw *efw,
255 struct snd_efw_phys_meters *meters,
256 unsigned int len)
257{
258 __be32 *buf = (__be32 *)meters;
259 unsigned int i;
260 int err;
261
262 err = efw_transaction(efw, EFC_CAT_HWINFO,
263 EFC_CMD_HWINFO_GET_POLLED,
264 NULL, 0, (__be32 *)meters, len);
265 if (err >= 0)
266 for (i = 0; i < len / sizeof(u32); i++)
267 be32_to_cpus(&buf[i]);
268
269 return err;
270}
271
272static int
273command_get_clock(struct snd_efw *efw, struct efc_clock *clock)
274{
275 int err;
276
277 err = efw_transaction(efw, EFC_CAT_HWCTL,
278 EFC_CMD_HWCTL_GET_CLOCK,
279 NULL, 0,
280 (__be32 *)clock, sizeof(struct efc_clock));
281 if (err >= 0) {
282 be32_to_cpus(&clock->source);
283 be32_to_cpus(&clock->sampling_rate);
284 be32_to_cpus(&clock->index);
285 }
286
287 return err;
288}
289
290/* give UINT_MAX if set nothing */
291static int
292command_set_clock(struct snd_efw *efw,
293 unsigned int source, unsigned int rate)
294{
295 struct efc_clock clock = {0};
296 int err;
297
298 /* check arguments */
299 if ((source == UINT_MAX) && (rate == UINT_MAX)) {
300 err = -EINVAL;
301 goto end;
302 }
303
304 /* get current status */
305 err = command_get_clock(efw, &clock);
306 if (err < 0)
307 goto end;
308
309 /* no need */
310 if ((clock.source == source) && (clock.sampling_rate == rate))
311 goto end;
312
313 /* set params */
314 if ((source != UINT_MAX) && (clock.source != source))
315 clock.source = source;
316 if ((rate != UINT_MAX) && (clock.sampling_rate != rate))
317 clock.sampling_rate = rate;
318 clock.index = 0;
319
320 cpu_to_be32s(&clock.source);
321 cpu_to_be32s(&clock.sampling_rate);
322 cpu_to_be32s(&clock.index);
323
324 err = efw_transaction(efw, EFC_CAT_HWCTL,
325 EFC_CMD_HWCTL_SET_CLOCK,
326 (__be32 *)&clock, sizeof(struct efc_clock),
327 NULL, 0);
328 if (err < 0)
329 goto end;
330
331 /*
332 * With firmware version 5.8, just after changing clock state, these
333 * parameters are not immediately retrieved by get command. In my
334 * trial, there needs to be 100msec to get changed parameters.
335 */
336 msleep(150);
337end:
338 return err;
339}
340
341int snd_efw_command_get_clock_source(struct snd_efw *efw,
342 enum snd_efw_clock_source *source)
343{
344 int err;
345 struct efc_clock clock = {0};
346
347 err = command_get_clock(efw, &clock);
348 if (err >= 0)
349 *source = clock.source;
350
351 return err;
352}
353
354int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate)
355{
356 int err;
357 struct efc_clock clock = {0};
358
359 err = command_get_clock(efw, &clock);
360 if (err >= 0)
361 *rate = clock.sampling_rate;
362
363 return err;
364}
365
366int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate)
367{
368 return command_set_clock(efw, UINT_MAX, rate);
369}
370
diff --git a/sound/firewire/fireworks/fireworks_transaction.c b/sound/firewire/fireworks/fireworks_transaction.c
new file mode 100644
index 000000000000..aac91d8485d5
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_transaction.c
@@ -0,0 +1,190 @@
1/*
2 * fireworks_transaction.c - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2013-2014 Takashi Sakamoto
5 *
6 * Licensed under the terms of the GNU General Public License, version 2.
7 */
8
9/*
10 * Fireworks have its own transaction. The transaction can be delivered by AV/C
11 * Vendor Specific command. But at least Windows driver and firmware version 5.5
12 * or later don't use it.
13 *
14 * Transaction substance:
15 * At first, 6 data exist. Following to the 6 data, parameters for each
16 * commands exists. All of parameters are 32 bit alighed to big endian.
17 * data[0]: Length of transaction substance
18 * data[1]: Transaction version
19 * data[2]: Sequence number. This is incremented by the device
20 * data[3]: transaction category
21 * data[4]: transaction command
22 * data[5]: return value in response.
23 * data[6-]: parameters
24 *
25 * Transaction address:
26 * command: 0xecc000000000
27 * response: 0xecc080000000 (default)
28 *
29 * I note that the address for response can be changed by command. But this
30 * module uses the default address.
31 */
32#include "./fireworks.h"
33
34#define MEMORY_SPACE_EFW_COMMAND 0xecc000000000
35#define MEMORY_SPACE_EFW_RESPONSE 0xecc080000000
36
37#define ERROR_RETRIES 3
38#define ERROR_DELAY_MS 5
39#define EFC_TIMEOUT_MS 125
40
41static DEFINE_SPINLOCK(transaction_queues_lock);
42static LIST_HEAD(transaction_queues);
43
44enum transaction_queue_state {
45 STATE_PENDING,
46 STATE_BUS_RESET,
47 STATE_COMPLETE
48};
49
50struct transaction_queue {
51 struct list_head list;
52 struct fw_unit *unit;
53 void *buf;
54 unsigned int size;
55 u32 seqnum;
56 enum transaction_queue_state state;
57 wait_queue_head_t wait;
58};
59
60int snd_efw_transaction_run(struct fw_unit *unit,
61 const void *cmd, unsigned int cmd_size,
62 void *resp, unsigned int resp_size)
63{
64 struct transaction_queue t;
65 unsigned int tries;
66 int ret;
67
68 t.unit = unit;
69 t.buf = resp;
70 t.size = resp_size;
71 t.seqnum = be32_to_cpu(((struct snd_efw_transaction *)cmd)->seqnum) + 1;
72 t.state = STATE_PENDING;
73 init_waitqueue_head(&t.wait);
74
75 spin_lock_irq(&transaction_queues_lock);
76 list_add_tail(&t.list, &transaction_queues);
77 spin_unlock_irq(&transaction_queues_lock);
78
79 tries = 0;
80 do {
81 ret = snd_fw_transaction(unit, TCODE_WRITE_BLOCK_REQUEST,
82 MEMORY_SPACE_EFW_COMMAND,
83 (void *)cmd, cmd_size, 0);
84 if (ret < 0)
85 break;
86
87 wait_event_timeout(t.wait, t.state != STATE_PENDING,
88 msecs_to_jiffies(EFC_TIMEOUT_MS));
89
90 if (t.state == STATE_COMPLETE) {
91 ret = t.size;
92 break;
93 } else if (t.state == STATE_BUS_RESET) {
94 msleep(ERROR_DELAY_MS);
95 } else if (++tries >= ERROR_RETRIES) {
96 dev_err(&t.unit->device, "EFW transaction timed out\n");
97 ret = -EIO;
98 break;
99 }
100 } while (1);
101
102 spin_lock_irq(&transaction_queues_lock);
103 list_del(&t.list);
104 spin_unlock_irq(&transaction_queues_lock);
105
106 return ret;
107}
108
109static void
110efw_response(struct fw_card *card, struct fw_request *request,
111 int tcode, int destination, int source,
112 int generation, unsigned long long offset,
113 void *data, size_t length, void *callback_data)
114{
115 struct fw_device *device;
116 struct transaction_queue *t;
117 unsigned long flags;
118 int rcode;
119 u32 seqnum;
120
121 rcode = RCODE_TYPE_ERROR;
122 if (length < sizeof(struct snd_efw_transaction)) {
123 rcode = RCODE_DATA_ERROR;
124 goto end;
125 } else if (offset != MEMORY_SPACE_EFW_RESPONSE) {
126 rcode = RCODE_ADDRESS_ERROR;
127 goto end;
128 }
129
130 seqnum = be32_to_cpu(((struct snd_efw_transaction *)data)->seqnum);
131
132 spin_lock_irqsave(&transaction_queues_lock, flags);
133 list_for_each_entry(t, &transaction_queues, list) {
134 device = fw_parent_device(t->unit);
135 if ((device->card != card) ||
136 (device->generation != generation))
137 continue;
138 smp_rmb(); /* node_id vs. generation */
139 if (device->node_id != source)
140 continue;
141
142 if ((t->state == STATE_PENDING) && (t->seqnum == seqnum)) {
143 t->state = STATE_COMPLETE;
144 t->size = min_t(unsigned int, length, t->size);
145 memcpy(t->buf, data, t->size);
146 wake_up(&t->wait);
147 rcode = RCODE_COMPLETE;
148 }
149 }
150 spin_unlock_irqrestore(&transaction_queues_lock, flags);
151end:
152 fw_send_response(card, request, rcode);
153}
154
155void snd_efw_transaction_bus_reset(struct fw_unit *unit)
156{
157 struct transaction_queue *t;
158
159 spin_lock_irq(&transaction_queues_lock);
160 list_for_each_entry(t, &transaction_queues, list) {
161 if ((t->unit == unit) &&
162 (t->state == STATE_PENDING)) {
163 t->state = STATE_BUS_RESET;
164 wake_up(&t->wait);
165 }
166 }
167 spin_unlock_irq(&transaction_queues_lock);
168}
169
170static struct fw_address_handler resp_register_handler = {
171 .length = SND_EFW_RESPONSE_MAXIMUM_BYTES,
172 .address_callback = efw_response
173};
174
175int snd_efw_transaction_register(void)
176{
177 static const struct fw_address_region resp_register_region = {
178 .start = MEMORY_SPACE_EFW_RESPONSE,
179 .end = MEMORY_SPACE_EFW_RESPONSE +
180 SND_EFW_RESPONSE_MAXIMUM_BYTES
181 };
182 return fw_core_add_address_handler(&resp_register_handler,
183 &resp_register_region);
184}
185
186void snd_efw_transaction_unregister(void)
187{
188 WARN_ON(!list_empty(&transaction_queues));
189 fw_core_remove_address_handler(&resp_register_handler);
190}