aboutsummaryrefslogtreecommitdiffstats
path: root/sound/firewire/fireworks
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire/fireworks')
-rw-r--r--sound/firewire/fireworks/Makefile4
-rw-r--r--sound/firewire/fireworks/fireworks.c353
-rw-r--r--sound/firewire/fireworks/fireworks.h233
-rw-r--r--sound/firewire/fireworks/fireworks_command.c372
-rw-r--r--sound/firewire/fireworks/fireworks_hwdep.c298
-rw-r--r--sound/firewire/fireworks/fireworks_midi.c168
-rw-r--r--sound/firewire/fireworks/fireworks_pcm.c403
-rw-r--r--sound/firewire/fireworks/fireworks_proc.c232
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c372
-rw-r--r--sound/firewire/fireworks/fireworks_transaction.c326
10 files changed, 2761 insertions, 0 deletions
diff --git a/sound/firewire/fireworks/Makefile b/sound/firewire/fireworks/Makefile
new file mode 100644
index 000000000000..0c7440826db8
--- /dev/null
+++ b/sound/firewire/fireworks/Makefile
@@ -0,0 +1,4 @@
1snd-fireworks-objs := fireworks_transaction.o fireworks_command.o \
2 fireworks_stream.o fireworks_proc.o fireworks_midi.o \
3 fireworks_pcm.o fireworks_hwdep.o fireworks.o
4obj-m += snd-fireworks.o
diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c
new file mode 100644
index 000000000000..996fdc44c83c
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks.c
@@ -0,0 +1,353 @@
1/*
2 * fireworks.c - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2009-2010 Clemens Ladisch
5 * Copyright (c) 2013-2014 Takashi Sakamoto
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10/*
11 * Fireworks is a board module which Echo Audio produced. This module consists
12 * of three chipsets:
13 * - Communication chipset for IEEE1394 PHY/Link and IEC 61883-1/6
14 * - DSP or/and FPGA for signal processing
15 * - Flash Memory to store firmwares
16 */
17
18#include "fireworks.h"
19
20MODULE_DESCRIPTION("Echo Fireworks driver");
21MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
22MODULE_LICENSE("GPL v2");
23
24static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
25static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
26static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
27unsigned int snd_efw_resp_buf_size = 1024;
28bool snd_efw_resp_buf_debug = false;
29
30module_param_array(index, int, NULL, 0444);
31MODULE_PARM_DESC(index, "card index");
32module_param_array(id, charp, NULL, 0444);
33MODULE_PARM_DESC(id, "ID string");
34module_param_array(enable, bool, NULL, 0444);
35MODULE_PARM_DESC(enable, "enable Fireworks sound card");
36module_param_named(resp_buf_size, snd_efw_resp_buf_size, uint, 0444);
37MODULE_PARM_DESC(resp_buf_size,
38 "response buffer size (max 4096, default 1024)");
39module_param_named(resp_buf_debug, snd_efw_resp_buf_debug, bool, 0444);
40MODULE_PARM_DESC(resp_buf_debug, "store all responses to buffer");
41
42static DEFINE_MUTEX(devices_mutex);
43static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
44
45#define VENDOR_LOUD 0x000ff2
46#define MODEL_MACKIE_400F 0x00400f
47#define MODEL_MACKIE_1200F 0x01200f
48
49#define VENDOR_ECHO 0x001486
50#define MODEL_ECHO_AUDIOFIRE_12 0x00af12
51#define MODEL_ECHO_AUDIOFIRE_12HD 0x0af12d
52#define MODEL_ECHO_AUDIOFIRE_12_APPLE 0x0af12a
53/* This is applied for AudioFire8 (until 2009 July) */
54#define MODEL_ECHO_AUDIOFIRE_8 0x000af8
55#define MODEL_ECHO_AUDIOFIRE_2 0x000af2
56#define MODEL_ECHO_AUDIOFIRE_4 0x000af4
57/* AudioFire9 is applied for AudioFire8(since 2009 July) and AudioFirePre8 */
58#define MODEL_ECHO_AUDIOFIRE_9 0x000af9
59/* unknown as product */
60#define MODEL_ECHO_FIREWORKS_8 0x0000f8
61#define MODEL_ECHO_FIREWORKS_HDMI 0x00afd1
62
63#define VENDOR_GIBSON 0x00075b
64/* for Robot Interface Pack of Dark Fire, Dusk Tiger, Les Paul Standard 2010 */
65#define MODEL_GIBSON_RIP 0x00afb2
66/* unknown as product */
67#define MODEL_GIBSON_GOLDTOP 0x00afb9
68
69/* part of hardware capability flags */
70#define FLAG_RESP_ADDR_CHANGABLE 0
71
72static int
73get_hardware_info(struct snd_efw *efw)
74{
75 struct fw_device *fw_dev = fw_parent_device(efw->unit);
76 struct snd_efw_hwinfo *hwinfo;
77 char version[12] = {0};
78 int err;
79
80 hwinfo = kzalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL);
81 if (hwinfo == NULL)
82 return -ENOMEM;
83
84 err = snd_efw_command_get_hwinfo(efw, hwinfo);
85 if (err < 0)
86 goto end;
87
88 /* firmware version for communication chipset */
89 snprintf(version, sizeof(version), "%u.%u",
90 (hwinfo->arm_version >> 24) & 0xff,
91 (hwinfo->arm_version >> 16) & 0xff);
92 efw->firmware_version = hwinfo->arm_version;
93
94 strcpy(efw->card->driver, "Fireworks");
95 strcpy(efw->card->shortname, hwinfo->model_name);
96 strcpy(efw->card->mixername, hwinfo->model_name);
97 snprintf(efw->card->longname, sizeof(efw->card->longname),
98 "%s %s v%s, GUID %08x%08x at %s, S%d",
99 hwinfo->vendor_name, hwinfo->model_name, version,
100 hwinfo->guid_hi, hwinfo->guid_lo,
101 dev_name(&efw->unit->device), 100 << fw_dev->max_speed);
102
103 if (hwinfo->flags & BIT(FLAG_RESP_ADDR_CHANGABLE))
104 efw->resp_addr_changable = true;
105
106 efw->supported_sampling_rate = 0;
107 if ((hwinfo->min_sample_rate <= 22050)
108 && (22050 <= hwinfo->max_sample_rate))
109 efw->supported_sampling_rate |= SNDRV_PCM_RATE_22050;
110 if ((hwinfo->min_sample_rate <= 32000)
111 && (32000 <= hwinfo->max_sample_rate))
112 efw->supported_sampling_rate |= SNDRV_PCM_RATE_32000;
113 if ((hwinfo->min_sample_rate <= 44100)
114 && (44100 <= hwinfo->max_sample_rate))
115 efw->supported_sampling_rate |= SNDRV_PCM_RATE_44100;
116 if ((hwinfo->min_sample_rate <= 48000)
117 && (48000 <= hwinfo->max_sample_rate))
118 efw->supported_sampling_rate |= SNDRV_PCM_RATE_48000;
119 if ((hwinfo->min_sample_rate <= 88200)
120 && (88200 <= hwinfo->max_sample_rate))
121 efw->supported_sampling_rate |= SNDRV_PCM_RATE_88200;
122 if ((hwinfo->min_sample_rate <= 96000)
123 && (96000 <= hwinfo->max_sample_rate))
124 efw->supported_sampling_rate |= SNDRV_PCM_RATE_96000;
125 if ((hwinfo->min_sample_rate <= 176400)
126 && (176400 <= hwinfo->max_sample_rate))
127 efw->supported_sampling_rate |= SNDRV_PCM_RATE_176400;
128 if ((hwinfo->min_sample_rate <= 192000)
129 && (192000 <= hwinfo->max_sample_rate))
130 efw->supported_sampling_rate |= SNDRV_PCM_RATE_192000;
131
132 /* the number of MIDI ports, not of MIDI conformant data channels */
133 if (hwinfo->midi_out_ports > SND_EFW_MAX_MIDI_OUT_PORTS ||
134 hwinfo->midi_in_ports > SND_EFW_MAX_MIDI_IN_PORTS) {
135 err = -EIO;
136 goto end;
137 }
138 efw->midi_out_ports = hwinfo->midi_out_ports;
139 efw->midi_in_ports = hwinfo->midi_in_ports;
140
141 if (hwinfo->amdtp_tx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM ||
142 hwinfo->amdtp_tx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM ||
143 hwinfo->amdtp_tx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM ||
144 hwinfo->amdtp_rx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM ||
145 hwinfo->amdtp_rx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM ||
146 hwinfo->amdtp_rx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM) {
147 err = -ENOSYS;
148 goto end;
149 }
150 efw->pcm_capture_channels[0] = hwinfo->amdtp_tx_pcm_channels;
151 efw->pcm_capture_channels[1] = hwinfo->amdtp_tx_pcm_channels_2x;
152 efw->pcm_capture_channels[2] = hwinfo->amdtp_tx_pcm_channels_4x;
153 efw->pcm_playback_channels[0] = hwinfo->amdtp_rx_pcm_channels;
154 efw->pcm_playback_channels[1] = hwinfo->amdtp_rx_pcm_channels_2x;
155 efw->pcm_playback_channels[2] = hwinfo->amdtp_rx_pcm_channels_4x;
156
157 /* Hardware metering. */
158 if (hwinfo->phys_in_grp_count > HWINFO_MAX_CAPS_GROUPS ||
159 hwinfo->phys_out_grp_count > HWINFO_MAX_CAPS_GROUPS) {
160 err = -EIO;
161 goto end;
162 }
163 efw->phys_in = hwinfo->phys_in;
164 efw->phys_out = hwinfo->phys_out;
165 efw->phys_in_grp_count = hwinfo->phys_in_grp_count;
166 efw->phys_out_grp_count = hwinfo->phys_out_grp_count;
167 memcpy(&efw->phys_in_grps, hwinfo->phys_in_grps,
168 sizeof(struct snd_efw_phys_grp) * hwinfo->phys_in_grp_count);
169 memcpy(&efw->phys_out_grps, hwinfo->phys_out_grps,
170 sizeof(struct snd_efw_phys_grp) * hwinfo->phys_out_grp_count);
171end:
172 kfree(hwinfo);
173 return err;
174}
175
176static void
177efw_card_free(struct snd_card *card)
178{
179 struct snd_efw *efw = card->private_data;
180
181 if (efw->card_index >= 0) {
182 mutex_lock(&devices_mutex);
183 clear_bit(efw->card_index, devices_used);
184 mutex_unlock(&devices_mutex);
185 }
186
187 mutex_destroy(&efw->mutex);
188 kfree(efw->resp_buf);
189}
190
191static int
192efw_probe(struct fw_unit *unit,
193 const struct ieee1394_device_id *entry)
194{
195 struct snd_card *card;
196 struct snd_efw *efw;
197 int card_index, err;
198
199 mutex_lock(&devices_mutex);
200
201 /* check registered cards */
202 for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) {
203 if (!test_bit(card_index, devices_used) && enable[card_index])
204 break;
205 }
206 if (card_index >= SNDRV_CARDS) {
207 err = -ENOENT;
208 goto end;
209 }
210
211 err = snd_card_new(&unit->device, index[card_index], id[card_index],
212 THIS_MODULE, sizeof(struct snd_efw), &card);
213 if (err < 0)
214 goto end;
215 efw = card->private_data;
216 efw->card_index = card_index;
217 set_bit(card_index, devices_used);
218 card->private_free = efw_card_free;
219
220 efw->card = card;
221 efw->unit = unit;
222 mutex_init(&efw->mutex);
223 spin_lock_init(&efw->lock);
224 init_waitqueue_head(&efw->hwdep_wait);
225
226 /* prepare response buffer */
227 snd_efw_resp_buf_size = clamp(snd_efw_resp_buf_size,
228 SND_EFW_RESPONSE_MAXIMUM_BYTES, 4096U);
229 efw->resp_buf = kzalloc(snd_efw_resp_buf_size, GFP_KERNEL);
230 if (efw->resp_buf == NULL) {
231 err = -ENOMEM;
232 goto error;
233 }
234 efw->pull_ptr = efw->push_ptr = efw->resp_buf;
235 snd_efw_transaction_add_instance(efw);
236
237 err = get_hardware_info(efw);
238 if (err < 0)
239 goto error;
240 if (entry->model_id == MODEL_ECHO_AUDIOFIRE_9)
241 efw->is_af9 = true;
242
243 snd_efw_proc_init(efw);
244
245 if (efw->midi_out_ports || efw->midi_in_ports) {
246 err = snd_efw_create_midi_devices(efw);
247 if (err < 0)
248 goto error;
249 }
250
251 err = snd_efw_create_pcm_devices(efw);
252 if (err < 0)
253 goto error;
254
255 err = snd_efw_create_hwdep_device(efw);
256 if (err < 0)
257 goto error;
258
259 err = snd_efw_stream_init_duplex(efw);
260 if (err < 0)
261 goto error;
262
263 err = snd_card_register(card);
264 if (err < 0) {
265 snd_efw_stream_destroy_duplex(efw);
266 goto error;
267 }
268
269 dev_set_drvdata(&unit->device, efw);
270end:
271 mutex_unlock(&devices_mutex);
272 return err;
273error:
274 snd_efw_transaction_remove_instance(efw);
275 mutex_unlock(&devices_mutex);
276 snd_card_free(card);
277 return err;
278}
279
280static void efw_update(struct fw_unit *unit)
281{
282 struct snd_efw *efw = dev_get_drvdata(&unit->device);
283
284 snd_efw_transaction_bus_reset(efw->unit);
285 snd_efw_stream_update_duplex(efw);
286}
287
288static void efw_remove(struct fw_unit *unit)
289{
290 struct snd_efw *efw = dev_get_drvdata(&unit->device);
291
292 snd_efw_stream_destroy_duplex(efw);
293 snd_efw_transaction_remove_instance(efw);
294
295 snd_card_disconnect(efw->card);
296 snd_card_free_when_closed(efw->card);
297}
298
299static const struct ieee1394_device_id efw_id_table[] = {
300 SND_EFW_DEV_ENTRY(VENDOR_LOUD, MODEL_MACKIE_400F),
301 SND_EFW_DEV_ENTRY(VENDOR_LOUD, MODEL_MACKIE_1200F),
302 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_8),
303 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_12),
304 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_12HD),
305 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_12_APPLE),
306 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_2),
307 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_4),
308 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_AUDIOFIRE_9),
309 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_FIREWORKS_8),
310 SND_EFW_DEV_ENTRY(VENDOR_ECHO, MODEL_ECHO_FIREWORKS_HDMI),
311 SND_EFW_DEV_ENTRY(VENDOR_GIBSON, MODEL_GIBSON_RIP),
312 SND_EFW_DEV_ENTRY(VENDOR_GIBSON, MODEL_GIBSON_GOLDTOP),
313 {}
314};
315MODULE_DEVICE_TABLE(ieee1394, efw_id_table);
316
317static struct fw_driver efw_driver = {
318 .driver = {
319 .owner = THIS_MODULE,
320 .name = "snd-fireworks",
321 .bus = &fw_bus_type,
322 },
323 .probe = efw_probe,
324 .update = efw_update,
325 .remove = efw_remove,
326 .id_table = efw_id_table,
327};
328
329static int __init snd_efw_init(void)
330{
331 int err;
332
333 err = snd_efw_transaction_register();
334 if (err < 0)
335 goto end;
336
337 err = driver_register(&efw_driver.driver);
338 if (err < 0)
339 snd_efw_transaction_unregister();
340
341end:
342 return err;
343}
344
345static void __exit snd_efw_exit(void)
346{
347 snd_efw_transaction_unregister();
348 driver_unregister(&efw_driver.driver);
349 mutex_destroy(&devices_mutex);
350}
351
352module_init(snd_efw_init);
353module_exit(snd_efw_exit);
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h
new file mode 100644
index 000000000000..d2b36be4d2f8
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks.h
@@ -0,0 +1,233 @@
1/*
2 * fireworks.h - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2009-2010 Clemens Ladisch
5 * Copyright (c) 2013-2014 Takashi Sakamoto
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9#ifndef SOUND_FIREWORKS_H_INCLUDED
10#define SOUND_FIREWORKS_H_INCLUDED
11
12#include <linux/compat.h>
13#include <linux/device.h>
14#include <linux/firewire.h>
15#include <linux/firewire-constants.h>
16#include <linux/module.h>
17#include <linux/mod_devicetable.h>
18#include <linux/delay.h>
19#include <linux/slab.h>
20
21#include <sound/core.h>
22#include <sound/initval.h>
23#include <sound/pcm.h>
24#include <sound/info.h>
25#include <sound/rawmidi.h>
26#include <sound/pcm_params.h>
27#include <sound/firewire.h>
28#include <sound/hwdep.h>
29
30#include "../packets-buffer.h"
31#include "../iso-resources.h"
32#include "../amdtp.h"
33#include "../cmp.h"
34#include "../lib.h"
35
36#define SND_EFW_MAX_MIDI_OUT_PORTS 2
37#define SND_EFW_MAX_MIDI_IN_PORTS 2
38
39#define SND_EFW_MULTIPLIER_MODES 3
40#define HWINFO_NAME_SIZE_BYTES 32
41#define HWINFO_MAX_CAPS_GROUPS 8
42
43/*
44 * This should be greater than maximum bytes for EFW response content.
45 * Currently response against command for isochronous channel mapping is
46 * confirmed to be the maximum one. But for flexibility, use maximum data
47 * payload for asynchronous primary packets at S100 (Cable base rate) in
48 * IEEE Std 1394-1995.
49 */
50#define SND_EFW_RESPONSE_MAXIMUM_BYTES 0x200U
51
52extern unsigned int snd_efw_resp_buf_size;
53extern bool snd_efw_resp_buf_debug;
54
55struct snd_efw_phys_grp {
56 u8 type; /* see enum snd_efw_grp_type */
57 u8 count;
58} __packed;
59
60struct snd_efw {
61 struct snd_card *card;
62 struct fw_unit *unit;
63 int card_index;
64
65 struct mutex mutex;
66 spinlock_t lock;
67
68 /* for transaction */
69 u32 seqnum;
70 bool resp_addr_changable;
71
72 /* for quirks */
73 bool is_af9;
74 u32 firmware_version;
75
76 unsigned int midi_in_ports;
77 unsigned int midi_out_ports;
78
79 unsigned int supported_sampling_rate;
80 unsigned int pcm_capture_channels[SND_EFW_MULTIPLIER_MODES];
81 unsigned int pcm_playback_channels[SND_EFW_MULTIPLIER_MODES];
82
83 struct amdtp_stream *master;
84 struct amdtp_stream tx_stream;
85 struct amdtp_stream rx_stream;
86 struct cmp_connection out_conn;
87 struct cmp_connection in_conn;
88 atomic_t capture_substreams;
89 atomic_t playback_substreams;
90
91 /* hardware metering parameters */
92 unsigned int phys_out;
93 unsigned int phys_in;
94 unsigned int phys_out_grp_count;
95 unsigned int phys_in_grp_count;
96 struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS];
97 struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS];
98
99 /* for uapi */
100 int dev_lock_count;
101 bool dev_lock_changed;
102 wait_queue_head_t hwdep_wait;
103
104 /* response queue */
105 u8 *resp_buf;
106 u8 *pull_ptr;
107 u8 *push_ptr;
108 unsigned int resp_queues;
109};
110
111int snd_efw_transaction_cmd(struct fw_unit *unit,
112 const void *cmd, unsigned int size);
113int snd_efw_transaction_run(struct fw_unit *unit,
114 const void *cmd, unsigned int cmd_size,
115 void *resp, unsigned int resp_size);
116int snd_efw_transaction_register(void);
117void snd_efw_transaction_unregister(void);
118void snd_efw_transaction_bus_reset(struct fw_unit *unit);
119void snd_efw_transaction_add_instance(struct snd_efw *efw);
120void snd_efw_transaction_remove_instance(struct snd_efw *efw);
121
122struct snd_efw_hwinfo {
123 u32 flags;
124 u32 guid_hi;
125 u32 guid_lo;
126 u32 type;
127 u32 version;
128 char vendor_name[HWINFO_NAME_SIZE_BYTES];
129 char model_name[HWINFO_NAME_SIZE_BYTES];
130 u32 supported_clocks;
131 u32 amdtp_rx_pcm_channels;
132 u32 amdtp_tx_pcm_channels;
133 u32 phys_out;
134 u32 phys_in;
135 u32 phys_out_grp_count;
136 struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS];
137 u32 phys_in_grp_count;
138 struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS];
139 u32 midi_out_ports;
140 u32 midi_in_ports;
141 u32 max_sample_rate;
142 u32 min_sample_rate;
143 u32 dsp_version;
144 u32 arm_version;
145 u32 mixer_playback_channels;
146 u32 mixer_capture_channels;
147 u32 fpga_version;
148 u32 amdtp_rx_pcm_channels_2x;
149 u32 amdtp_tx_pcm_channels_2x;
150 u32 amdtp_rx_pcm_channels_4x;
151 u32 amdtp_tx_pcm_channels_4x;
152 u32 reserved[16];
153} __packed;
154enum snd_efw_grp_type {
155 SND_EFW_CH_TYPE_ANALOG = 0,
156 SND_EFW_CH_TYPE_SPDIF = 1,
157 SND_EFW_CH_TYPE_ADAT = 2,
158 SND_EFW_CH_TYPE_SPDIF_OR_ADAT = 3,
159 SND_EFW_CH_TYPE_ANALOG_MIRRORING = 4,
160 SND_EFW_CH_TYPE_HEADPHONES = 5,
161 SND_EFW_CH_TYPE_I2S = 6,
162 SND_EFW_CH_TYPE_GUITAR = 7,
163 SND_EFW_CH_TYPE_PIEZO_GUITAR = 8,
164 SND_EFW_CH_TYPE_GUITAR_STRING = 9,
165 SND_EFW_CH_TYPE_VIRTUAL = 0x10000,
166 SND_EFW_CH_TYPE_DUMMY
167};
168struct snd_efw_phys_meters {
169 u32 status; /* guitar state/midi signal/clock input detect */
170 u32 reserved0;
171 u32 reserved1;
172 u32 reserved2;
173 u32 reserved3;
174 u32 out_meters;
175 u32 in_meters;
176 u32 reserved4;
177 u32 reserved5;
178 u32 values[0];
179} __packed;
180enum snd_efw_clock_source {
181 SND_EFW_CLOCK_SOURCE_INTERNAL = 0,
182 SND_EFW_CLOCK_SOURCE_SYTMATCH = 1,
183 SND_EFW_CLOCK_SOURCE_WORDCLOCK = 2,
184 SND_EFW_CLOCK_SOURCE_SPDIF = 3,
185 SND_EFW_CLOCK_SOURCE_ADAT_1 = 4,
186 SND_EFW_CLOCK_SOURCE_ADAT_2 = 5,
187 SND_EFW_CLOCK_SOURCE_CONTINUOUS = 6 /* internal variable clock */
188};
189enum snd_efw_transport_mode {
190 SND_EFW_TRANSPORT_MODE_WINDOWS = 0,
191 SND_EFW_TRANSPORT_MODE_IEC61883 = 1,
192};
193int snd_efw_command_set_resp_addr(struct snd_efw *efw,
194 u16 addr_high, u32 addr_low);
195int snd_efw_command_set_tx_mode(struct snd_efw *efw,
196 enum snd_efw_transport_mode mode);
197int snd_efw_command_get_hwinfo(struct snd_efw *efw,
198 struct snd_efw_hwinfo *hwinfo);
199int snd_efw_command_get_phys_meters(struct snd_efw *efw,
200 struct snd_efw_phys_meters *meters,
201 unsigned int len);
202int snd_efw_command_get_clock_source(struct snd_efw *efw,
203 enum snd_efw_clock_source *source);
204int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate);
205int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate);
206
207int snd_efw_stream_init_duplex(struct snd_efw *efw);
208int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate);
209void snd_efw_stream_stop_duplex(struct snd_efw *efw);
210void snd_efw_stream_update_duplex(struct snd_efw *efw);
211void snd_efw_stream_destroy_duplex(struct snd_efw *efw);
212void snd_efw_stream_lock_changed(struct snd_efw *efw);
213int snd_efw_stream_lock_try(struct snd_efw *efw);
214void snd_efw_stream_lock_release(struct snd_efw *efw);
215
216void snd_efw_proc_init(struct snd_efw *efw);
217
218int snd_efw_create_midi_devices(struct snd_efw *efw);
219
220int snd_efw_create_pcm_devices(struct snd_efw *efw);
221int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode);
222
223int snd_efw_create_hwdep_device(struct snd_efw *efw);
224
225#define SND_EFW_DEV_ENTRY(vendor, model) \
226{ \
227 .match_flags = IEEE1394_MATCH_VENDOR_ID | \
228 IEEE1394_MATCH_MODEL_ID, \
229 .vendor_id = vendor,\
230 .model_id = model \
231}
232
233#endif
diff --git a/sound/firewire/fireworks/fireworks_command.c b/sound/firewire/fireworks/fireworks_command.c
new file mode 100644
index 000000000000..166f80584c2a
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_command.c
@@ -0,0 +1,372 @@
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 KERNEL_SEQNUM_MIN (SND_EFW_TRANSACTION_USER_SEQNUM_MAX + 2)
26#define KERNEL_SEQNUM_MAX ((u32)~0)
27
28/* for clock source and sampling rate */
29struct efc_clock {
30 u32 source;
31 u32 sampling_rate;
32 u32 index;
33};
34
35/* command categories */
36enum efc_category {
37 EFC_CAT_HWINFO = 0,
38 EFC_CAT_TRANSPORT = 2,
39 EFC_CAT_HWCTL = 3,
40};
41
42/* hardware info category commands */
43enum efc_cmd_hwinfo {
44 EFC_CMD_HWINFO_GET_CAPS = 0,
45 EFC_CMD_HWINFO_GET_POLLED = 1,
46 EFC_CMD_HWINFO_SET_RESP_ADDR = 2
47};
48
49enum efc_cmd_transport {
50 EFC_CMD_TRANSPORT_SET_TX_MODE = 0
51};
52
53/* hardware control category commands */
54enum efc_cmd_hwctl {
55 EFC_CMD_HWCTL_SET_CLOCK = 0,
56 EFC_CMD_HWCTL_GET_CLOCK = 1,
57 EFC_CMD_HWCTL_IDENTIFY = 5
58};
59
60/* return values in response */
61enum efr_status {
62 EFR_STATUS_OK = 0,
63 EFR_STATUS_BAD = 1,
64 EFR_STATUS_BAD_COMMAND = 2,
65 EFR_STATUS_COMM_ERR = 3,
66 EFR_STATUS_BAD_QUAD_COUNT = 4,
67 EFR_STATUS_UNSUPPORTED = 5,
68 EFR_STATUS_1394_TIMEOUT = 6,
69 EFR_STATUS_DSP_TIMEOUT = 7,
70 EFR_STATUS_BAD_RATE = 8,
71 EFR_STATUS_BAD_CLOCK = 9,
72 EFR_STATUS_BAD_CHANNEL = 10,
73 EFR_STATUS_BAD_PAN = 11,
74 EFR_STATUS_FLASH_BUSY = 12,
75 EFR_STATUS_BAD_MIRROR = 13,
76 EFR_STATUS_BAD_LED = 14,
77 EFR_STATUS_BAD_PARAMETER = 15,
78 EFR_STATUS_INCOMPLETE = 0x80000000
79};
80
81static const char *const efr_status_names[] = {
82 [EFR_STATUS_OK] = "OK",
83 [EFR_STATUS_BAD] = "bad",
84 [EFR_STATUS_BAD_COMMAND] = "bad command",
85 [EFR_STATUS_COMM_ERR] = "comm err",
86 [EFR_STATUS_BAD_QUAD_COUNT] = "bad quad count",
87 [EFR_STATUS_UNSUPPORTED] = "unsupported",
88 [EFR_STATUS_1394_TIMEOUT] = "1394 timeout",
89 [EFR_STATUS_DSP_TIMEOUT] = "DSP timeout",
90 [EFR_STATUS_BAD_RATE] = "bad rate",
91 [EFR_STATUS_BAD_CLOCK] = "bad clock",
92 [EFR_STATUS_BAD_CHANNEL] = "bad channel",
93 [EFR_STATUS_BAD_PAN] = "bad pan",
94 [EFR_STATUS_FLASH_BUSY] = "flash busy",
95 [EFR_STATUS_BAD_MIRROR] = "bad mirror",
96 [EFR_STATUS_BAD_LED] = "bad LED",
97 [EFR_STATUS_BAD_PARAMETER] = "bad parameter",
98 [EFR_STATUS_BAD_PARAMETER + 1] = "incomplete"
99};
100
101static int
102efw_transaction(struct snd_efw *efw, unsigned int category,
103 unsigned int command,
104 const __be32 *params, unsigned int param_bytes,
105 const __be32 *resp, unsigned int resp_bytes)
106{
107 struct snd_efw_transaction *header;
108 __be32 *buf;
109 u32 seqnum;
110 unsigned int buf_bytes, cmd_bytes;
111 int err;
112
113 /* calculate buffer size*/
114 buf_bytes = sizeof(struct snd_efw_transaction) +
115 max(param_bytes, resp_bytes);
116
117 /* keep buffer */
118 buf = kzalloc(buf_bytes, GFP_KERNEL);
119 if (buf == NULL)
120 return -ENOMEM;
121
122 /* to keep consistency of sequence number */
123 spin_lock(&efw->lock);
124 if ((efw->seqnum < KERNEL_SEQNUM_MIN) ||
125 (efw->seqnum >= KERNEL_SEQNUM_MAX - 2))
126 efw->seqnum = KERNEL_SEQNUM_MIN;
127 else
128 efw->seqnum += 2;
129 seqnum = efw->seqnum;
130 spin_unlock(&efw->lock);
131
132 /* fill transaction header fields */
133 cmd_bytes = sizeof(struct snd_efw_transaction) + param_bytes;
134 header = (struct snd_efw_transaction *)buf;
135 header->length = cpu_to_be32(cmd_bytes / sizeof(__be32));
136 header->version = cpu_to_be32(1);
137 header->seqnum = cpu_to_be32(seqnum);
138 header->category = cpu_to_be32(category);
139 header->command = cpu_to_be32(command);
140 header->status = 0;
141
142 /* fill transaction command parameters */
143 memcpy(header->params, params, param_bytes);
144
145 err = snd_efw_transaction_run(efw->unit, buf, cmd_bytes,
146 buf, buf_bytes);
147 if (err < 0)
148 goto end;
149
150 /* check transaction header fields */
151 if ((be32_to_cpu(header->version) < 1) ||
152 (be32_to_cpu(header->category) != category) ||
153 (be32_to_cpu(header->command) != command) ||
154 (be32_to_cpu(header->status) != EFR_STATUS_OK)) {
155 dev_err(&efw->unit->device, "EFW command failed [%u/%u]: %s\n",
156 be32_to_cpu(header->category),
157 be32_to_cpu(header->command),
158 efr_status_names[be32_to_cpu(header->status)]);
159 err = -EIO;
160 goto end;
161 }
162
163 if (resp == NULL)
164 goto end;
165
166 /* fill transaction response parameters */
167 memset((void *)resp, 0, resp_bytes);
168 resp_bytes = min_t(unsigned int, resp_bytes,
169 be32_to_cpu(header->length) * sizeof(__be32) -
170 sizeof(struct snd_efw_transaction));
171 memcpy((void *)resp, &buf[6], resp_bytes);
172end:
173 kfree(buf);
174 return err;
175}
176
177/*
178 * The address in host system for transaction response is changable when the
179 * device supports. struct hwinfo.flags includes its flag. The default is
180 * MEMORY_SPACE_EFW_RESPONSE.
181 */
182int snd_efw_command_set_resp_addr(struct snd_efw *efw,
183 u16 addr_high, u32 addr_low)
184{
185 __be32 addr[2];
186
187 addr[0] = cpu_to_be32(addr_high);
188 addr[1] = cpu_to_be32(addr_low);
189
190 if (!efw->resp_addr_changable)
191 return -ENOSYS;
192
193 return efw_transaction(efw, EFC_CAT_HWCTL,
194 EFC_CMD_HWINFO_SET_RESP_ADDR,
195 addr, sizeof(addr), NULL, 0);
196}
197
198/*
199 * This is for timestamp processing. In Windows mode, all 32bit fields of second
200 * CIP header in AMDTP transmit packet is used for 'presentation timestamp'. In
201 * 'no data' packet the value of this field is 0x90ffffff.
202 */
203int snd_efw_command_set_tx_mode(struct snd_efw *efw,
204 enum snd_efw_transport_mode mode)
205{
206 __be32 param = cpu_to_be32(mode);
207 return efw_transaction(efw, EFC_CAT_TRANSPORT,
208 EFC_CMD_TRANSPORT_SET_TX_MODE,
209 &param, sizeof(param), NULL, 0);
210}
211
212int snd_efw_command_get_hwinfo(struct snd_efw *efw,
213 struct snd_efw_hwinfo *hwinfo)
214{
215 int err;
216
217 err = efw_transaction(efw, EFC_CAT_HWINFO,
218 EFC_CMD_HWINFO_GET_CAPS,
219 NULL, 0, (__be32 *)hwinfo, sizeof(*hwinfo));
220 if (err < 0)
221 goto end;
222
223 be32_to_cpus(&hwinfo->flags);
224 be32_to_cpus(&hwinfo->guid_hi);
225 be32_to_cpus(&hwinfo->guid_lo);
226 be32_to_cpus(&hwinfo->type);
227 be32_to_cpus(&hwinfo->version);
228 be32_to_cpus(&hwinfo->supported_clocks);
229 be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels);
230 be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels);
231 be32_to_cpus(&hwinfo->phys_out);
232 be32_to_cpus(&hwinfo->phys_in);
233 be32_to_cpus(&hwinfo->phys_out_grp_count);
234 be32_to_cpus(&hwinfo->phys_in_grp_count);
235 be32_to_cpus(&hwinfo->midi_out_ports);
236 be32_to_cpus(&hwinfo->midi_in_ports);
237 be32_to_cpus(&hwinfo->max_sample_rate);
238 be32_to_cpus(&hwinfo->min_sample_rate);
239 be32_to_cpus(&hwinfo->dsp_version);
240 be32_to_cpus(&hwinfo->arm_version);
241 be32_to_cpus(&hwinfo->mixer_playback_channels);
242 be32_to_cpus(&hwinfo->mixer_capture_channels);
243 be32_to_cpus(&hwinfo->fpga_version);
244 be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels_2x);
245 be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels_2x);
246 be32_to_cpus(&hwinfo->amdtp_rx_pcm_channels_4x);
247 be32_to_cpus(&hwinfo->amdtp_tx_pcm_channels_4x);
248
249 /* ensure terminated */
250 hwinfo->vendor_name[HWINFO_NAME_SIZE_BYTES - 1] = '\0';
251 hwinfo->model_name[HWINFO_NAME_SIZE_BYTES - 1] = '\0';
252end:
253 return err;
254}
255
256int snd_efw_command_get_phys_meters(struct snd_efw *efw,
257 struct snd_efw_phys_meters *meters,
258 unsigned int len)
259{
260 __be32 *buf = (__be32 *)meters;
261 unsigned int i;
262 int err;
263
264 err = efw_transaction(efw, EFC_CAT_HWINFO,
265 EFC_CMD_HWINFO_GET_POLLED,
266 NULL, 0, (__be32 *)meters, len);
267 if (err >= 0)
268 for (i = 0; i < len / sizeof(u32); i++)
269 be32_to_cpus(&buf[i]);
270
271 return err;
272}
273
274static int
275command_get_clock(struct snd_efw *efw, struct efc_clock *clock)
276{
277 int err;
278
279 err = efw_transaction(efw, EFC_CAT_HWCTL,
280 EFC_CMD_HWCTL_GET_CLOCK,
281 NULL, 0,
282 (__be32 *)clock, sizeof(struct efc_clock));
283 if (err >= 0) {
284 be32_to_cpus(&clock->source);
285 be32_to_cpus(&clock->sampling_rate);
286 be32_to_cpus(&clock->index);
287 }
288
289 return err;
290}
291
292/* give UINT_MAX if set nothing */
293static int
294command_set_clock(struct snd_efw *efw,
295 unsigned int source, unsigned int rate)
296{
297 struct efc_clock clock = {0};
298 int err;
299
300 /* check arguments */
301 if ((source == UINT_MAX) && (rate == UINT_MAX)) {
302 err = -EINVAL;
303 goto end;
304 }
305
306 /* get current status */
307 err = command_get_clock(efw, &clock);
308 if (err < 0)
309 goto end;
310
311 /* no need */
312 if ((clock.source == source) && (clock.sampling_rate == rate))
313 goto end;
314
315 /* set params */
316 if ((source != UINT_MAX) && (clock.source != source))
317 clock.source = source;
318 if ((rate != UINT_MAX) && (clock.sampling_rate != rate))
319 clock.sampling_rate = rate;
320 clock.index = 0;
321
322 cpu_to_be32s(&clock.source);
323 cpu_to_be32s(&clock.sampling_rate);
324 cpu_to_be32s(&clock.index);
325
326 err = efw_transaction(efw, EFC_CAT_HWCTL,
327 EFC_CMD_HWCTL_SET_CLOCK,
328 (__be32 *)&clock, sizeof(struct efc_clock),
329 NULL, 0);
330 if (err < 0)
331 goto end;
332
333 /*
334 * With firmware version 5.8, just after changing clock state, these
335 * parameters are not immediately retrieved by get command. In my
336 * trial, there needs to be 100msec to get changed parameters.
337 */
338 msleep(150);
339end:
340 return err;
341}
342
343int snd_efw_command_get_clock_source(struct snd_efw *efw,
344 enum snd_efw_clock_source *source)
345{
346 int err;
347 struct efc_clock clock = {0};
348
349 err = command_get_clock(efw, &clock);
350 if (err >= 0)
351 *source = clock.source;
352
353 return err;
354}
355
356int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate)
357{
358 int err;
359 struct efc_clock clock = {0};
360
361 err = command_get_clock(efw, &clock);
362 if (err >= 0)
363 *rate = clock.sampling_rate;
364
365 return err;
366}
367
368int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate)
369{
370 return command_set_clock(efw, UINT_MAX, rate);
371}
372
diff --git a/sound/firewire/fireworks/fireworks_hwdep.c b/sound/firewire/fireworks/fireworks_hwdep.c
new file mode 100644
index 000000000000..4f8216fb6b62
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_hwdep.c
@@ -0,0 +1,298 @@
1/*
2 * fireworks_hwdep.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 * This codes have five functionalities.
11 *
12 * 1.get information about firewire node
13 * 2.get notification about starting/stopping stream
14 * 3.lock/unlock streaming
15 * 4.transmit command of EFW transaction
16 * 5.receive response of EFW transaction
17 *
18 */
19
20#include "fireworks.h"
21
22static long
23hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained,
24 loff_t *offset)
25{
26 unsigned int length, till_end, type;
27 struct snd_efw_transaction *t;
28 long count = 0;
29
30 if (remained < sizeof(type) + sizeof(struct snd_efw_transaction))
31 return -ENOSPC;
32
33 /* data type is SNDRV_FIREWIRE_EVENT_EFW_RESPONSE */
34 type = SNDRV_FIREWIRE_EVENT_EFW_RESPONSE;
35 if (copy_to_user(buf, &type, sizeof(type)))
36 return -EFAULT;
37 remained -= sizeof(type);
38 buf += sizeof(type);
39
40 /* write into buffer as many responses as possible */
41 while (efw->resp_queues > 0) {
42 t = (struct snd_efw_transaction *)(efw->pull_ptr);
43 length = be32_to_cpu(t->length) * sizeof(__be32);
44
45 /* confirm enough space for this response */
46 if (remained < length)
47 break;
48
49 /* copy from ring buffer to user buffer */
50 while (length > 0) {
51 till_end = snd_efw_resp_buf_size -
52 (unsigned int)(efw->pull_ptr - efw->resp_buf);
53 till_end = min_t(unsigned int, length, till_end);
54
55 if (copy_to_user(buf, efw->pull_ptr, till_end))
56 return -EFAULT;
57
58 efw->pull_ptr += till_end;
59 if (efw->pull_ptr >= efw->resp_buf +
60 snd_efw_resp_buf_size)
61 efw->pull_ptr = efw->resp_buf;
62
63 length -= till_end;
64 buf += till_end;
65 count += till_end;
66 remained -= till_end;
67 }
68
69 efw->resp_queues--;
70 }
71
72 return count;
73}
74
75static long
76hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count,
77 loff_t *offset)
78{
79 union snd_firewire_event event;
80
81 memset(&event, 0, sizeof(event));
82
83 event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
84 event.lock_status.status = (efw->dev_lock_count > 0);
85 efw->dev_lock_changed = false;
86
87 count = min_t(long, count, sizeof(event.lock_status));
88
89 if (copy_to_user(buf, &event, count))
90 return -EFAULT;
91
92 return count;
93}
94
95static long
96hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
97 loff_t *offset)
98{
99 struct snd_efw *efw = hwdep->private_data;
100 DEFINE_WAIT(wait);
101
102 spin_lock_irq(&efw->lock);
103
104 while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) {
105 prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
106 spin_unlock_irq(&efw->lock);
107 schedule();
108 finish_wait(&efw->hwdep_wait, &wait);
109 if (signal_pending(current))
110 return -ERESTARTSYS;
111 spin_lock_irq(&efw->lock);
112 }
113
114 if (efw->dev_lock_changed)
115 count = hwdep_read_locked(efw, buf, count, offset);
116 else if (efw->resp_queues > 0)
117 count = hwdep_read_resp_buf(efw, buf, count, offset);
118
119 spin_unlock_irq(&efw->lock);
120
121 return count;
122}
123
124static long
125hwdep_write(struct snd_hwdep *hwdep, const char __user *data, long count,
126 loff_t *offset)
127{
128 struct snd_efw *efw = hwdep->private_data;
129 u32 seqnum;
130 u8 *buf;
131
132 if (count < sizeof(struct snd_efw_transaction) ||
133 SND_EFW_RESPONSE_MAXIMUM_BYTES < count)
134 return -EINVAL;
135
136 buf = memdup_user(data, count);
137 if (IS_ERR(buf))
138 return PTR_ERR(buf);
139
140 /* check seqnum is not for kernel-land */
141 seqnum = be32_to_cpu(((struct snd_efw_transaction *)buf)->seqnum);
142 if (seqnum > SND_EFW_TRANSACTION_USER_SEQNUM_MAX) {
143 count = -EINVAL;
144 goto end;
145 }
146
147 if (snd_efw_transaction_cmd(efw->unit, buf, count) < 0)
148 count = -EIO;
149end:
150 kfree(buf);
151 return count;
152}
153
154static unsigned int
155hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait)
156{
157 struct snd_efw *efw = hwdep->private_data;
158 unsigned int events;
159
160 poll_wait(file, &efw->hwdep_wait, wait);
161
162 spin_lock_irq(&efw->lock);
163 if (efw->dev_lock_changed || (efw->resp_queues > 0))
164 events = POLLIN | POLLRDNORM;
165 else
166 events = 0;
167 spin_unlock_irq(&efw->lock);
168
169 return events | POLLOUT;
170}
171
172static int
173hwdep_get_info(struct snd_efw *efw, void __user *arg)
174{
175 struct fw_device *dev = fw_parent_device(efw->unit);
176 struct snd_firewire_get_info info;
177
178 memset(&info, 0, sizeof(info));
179 info.type = SNDRV_FIREWIRE_TYPE_FIREWORKS;
180 info.card = dev->card->index;
181 *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
182 *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
183 strlcpy(info.device_name, dev_name(&dev->device),
184 sizeof(info.device_name));
185
186 if (copy_to_user(arg, &info, sizeof(info)))
187 return -EFAULT;
188
189 return 0;
190}
191
192static int
193hwdep_lock(struct snd_efw *efw)
194{
195 int err;
196
197 spin_lock_irq(&efw->lock);
198
199 if (efw->dev_lock_count == 0) {
200 efw->dev_lock_count = -1;
201 err = 0;
202 } else {
203 err = -EBUSY;
204 }
205
206 spin_unlock_irq(&efw->lock);
207
208 return err;
209}
210
211static int
212hwdep_unlock(struct snd_efw *efw)
213{
214 int err;
215
216 spin_lock_irq(&efw->lock);
217
218 if (efw->dev_lock_count == -1) {
219 efw->dev_lock_count = 0;
220 err = 0;
221 } else {
222 err = -EBADFD;
223 }
224
225 spin_unlock_irq(&efw->lock);
226
227 return err;
228}
229
230static int
231hwdep_release(struct snd_hwdep *hwdep, struct file *file)
232{
233 struct snd_efw *efw = hwdep->private_data;
234
235 spin_lock_irq(&efw->lock);
236 if (efw->dev_lock_count == -1)
237 efw->dev_lock_count = 0;
238 spin_unlock_irq(&efw->lock);
239
240 return 0;
241}
242
243static int
244hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,
245 unsigned int cmd, unsigned long arg)
246{
247 struct snd_efw *efw = hwdep->private_data;
248
249 switch (cmd) {
250 case SNDRV_FIREWIRE_IOCTL_GET_INFO:
251 return hwdep_get_info(efw, (void __user *)arg);
252 case SNDRV_FIREWIRE_IOCTL_LOCK:
253 return hwdep_lock(efw);
254 case SNDRV_FIREWIRE_IOCTL_UNLOCK:
255 return hwdep_unlock(efw);
256 default:
257 return -ENOIOCTLCMD;
258 }
259}
260
261#ifdef CONFIG_COMPAT
262static int
263hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,
264 unsigned int cmd, unsigned long arg)
265{
266 return hwdep_ioctl(hwdep, file, cmd,
267 (unsigned long)compat_ptr(arg));
268}
269#else
270#define hwdep_compat_ioctl NULL
271#endif
272
273static const struct snd_hwdep_ops hwdep_ops = {
274 .read = hwdep_read,
275 .write = hwdep_write,
276 .release = hwdep_release,
277 .poll = hwdep_poll,
278 .ioctl = hwdep_ioctl,
279 .ioctl_compat = hwdep_compat_ioctl,
280};
281
282int snd_efw_create_hwdep_device(struct snd_efw *efw)
283{
284 struct snd_hwdep *hwdep;
285 int err;
286
287 err = snd_hwdep_new(efw->card, "Fireworks", 0, &hwdep);
288 if (err < 0)
289 goto end;
290 strcpy(hwdep->name, "Fireworks");
291 hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREWORKS;
292 hwdep->ops = hwdep_ops;
293 hwdep->private_data = efw;
294 hwdep->exclusive = true;
295end:
296 return err;
297}
298
diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c
new file mode 100644
index 000000000000..cf9c65260439
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_midi.c
@@ -0,0 +1,168 @@
1/*
2 * fireworks_midi.c - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2009-2010 Clemens Ladisch
5 * Copyright (c) 2013-2014 Takashi Sakamoto
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9#include "fireworks.h"
10
11static int midi_capture_open(struct snd_rawmidi_substream *substream)
12{
13 struct snd_efw *efw = substream->rmidi->private_data;
14 int err;
15
16 err = snd_efw_stream_lock_try(efw);
17 if (err < 0)
18 goto end;
19
20 atomic_inc(&efw->capture_substreams);
21 err = snd_efw_stream_start_duplex(efw, 0);
22 if (err < 0)
23 snd_efw_stream_lock_release(efw);
24
25end:
26 return err;
27}
28
29static int midi_playback_open(struct snd_rawmidi_substream *substream)
30{
31 struct snd_efw *efw = substream->rmidi->private_data;
32 int err;
33
34 err = snd_efw_stream_lock_try(efw);
35 if (err < 0)
36 goto end;
37
38 atomic_inc(&efw->playback_substreams);
39 err = snd_efw_stream_start_duplex(efw, 0);
40 if (err < 0)
41 snd_efw_stream_lock_release(efw);
42end:
43 return err;
44}
45
46static int midi_capture_close(struct snd_rawmidi_substream *substream)
47{
48 struct snd_efw *efw = substream->rmidi->private_data;
49
50 atomic_dec(&efw->capture_substreams);
51 snd_efw_stream_stop_duplex(efw);
52
53 snd_efw_stream_lock_release(efw);
54 return 0;
55}
56
57static int midi_playback_close(struct snd_rawmidi_substream *substream)
58{
59 struct snd_efw *efw = substream->rmidi->private_data;
60
61 atomic_dec(&efw->playback_substreams);
62 snd_efw_stream_stop_duplex(efw);
63
64 snd_efw_stream_lock_release(efw);
65 return 0;
66}
67
68static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
69{
70 struct snd_efw *efw = substrm->rmidi->private_data;
71 unsigned long flags;
72
73 spin_lock_irqsave(&efw->lock, flags);
74
75 if (up)
76 amdtp_stream_midi_trigger(&efw->tx_stream,
77 substrm->number, substrm);
78 else
79 amdtp_stream_midi_trigger(&efw->tx_stream,
80 substrm->number, NULL);
81
82 spin_unlock_irqrestore(&efw->lock, flags);
83}
84
85static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
86{
87 struct snd_efw *efw = substrm->rmidi->private_data;
88 unsigned long flags;
89
90 spin_lock_irqsave(&efw->lock, flags);
91
92 if (up)
93 amdtp_stream_midi_trigger(&efw->rx_stream,
94 substrm->number, substrm);
95 else
96 amdtp_stream_midi_trigger(&efw->rx_stream,
97 substrm->number, NULL);
98
99 spin_unlock_irqrestore(&efw->lock, flags);
100}
101
102static struct snd_rawmidi_ops midi_capture_ops = {
103 .open = midi_capture_open,
104 .close = midi_capture_close,
105 .trigger = midi_capture_trigger,
106};
107
108static struct snd_rawmidi_ops midi_playback_ops = {
109 .open = midi_playback_open,
110 .close = midi_playback_close,
111 .trigger = midi_playback_trigger,
112};
113
114static void set_midi_substream_names(struct snd_efw *efw,
115 struct snd_rawmidi_str *str)
116{
117 struct snd_rawmidi_substream *subs;
118
119 list_for_each_entry(subs, &str->substreams, list) {
120 snprintf(subs->name, sizeof(subs->name),
121 "%s MIDI %d", efw->card->shortname, subs->number + 1);
122 }
123}
124
125int snd_efw_create_midi_devices(struct snd_efw *efw)
126{
127 struct snd_rawmidi *rmidi;
128 struct snd_rawmidi_str *str;
129 int err;
130
131 /* create midi ports */
132 err = snd_rawmidi_new(efw->card, efw->card->driver, 0,
133 efw->midi_out_ports, efw->midi_in_ports,
134 &rmidi);
135 if (err < 0)
136 return err;
137
138 snprintf(rmidi->name, sizeof(rmidi->name),
139 "%s MIDI", efw->card->shortname);
140 rmidi->private_data = efw;
141
142 if (efw->midi_in_ports > 0) {
143 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
144
145 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
146 &midi_capture_ops);
147
148 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];
149
150 set_midi_substream_names(efw, str);
151 }
152
153 if (efw->midi_out_ports > 0) {
154 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
155
156 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
157 &midi_playback_ops);
158
159 str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
160
161 set_midi_substream_names(efw, str);
162 }
163
164 if ((efw->midi_out_ports > 0) && (efw->midi_in_ports > 0))
165 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
166
167 return 0;
168}
diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c
new file mode 100644
index 000000000000..8a34753de210
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_pcm.c
@@ -0,0 +1,403 @@
1/*
2 * fireworks_pcm.c - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2009-2010 Clemens Ladisch
5 * Copyright (c) 2013-2014 Takashi Sakamoto
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9#include "./fireworks.h"
10
11/*
12 * NOTE:
13 * Fireworks changes its AMDTP channels for PCM data according to its sampling
14 * rate. There are three modes. Here _XX is either _rx or _tx.
15 * 0: 32.0- 48.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels applied
16 * 1: 88.2- 96.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_2x applied
17 * 2: 176.4-192.0 kHz then snd_efw_hwinfo.amdtp_XX_pcm_channels_4x applied
18 *
19 * The number of PCM channels for analog input and output are always fixed but
20 * the number of PCM channels for digital input and output are differed.
21 *
22 * Additionally, according to "AudioFire Owner's Manual Version 2.2", in some
23 * model, the number of PCM channels for digital input has more restriction
24 * depending on which digital interface is selected.
25 * - S/PDIF coaxial and optical : use input 1-2
26 * - ADAT optical at 32.0-48.0 kHz : use input 1-8
27 * - ADAT optical at 88.2-96.0 kHz : use input 1-4 (S/MUX format)
28 *
29 * The data in AMDTP channels for blank PCM channels are zero.
30 */
31static const unsigned int freq_table[] = {
32 /* multiplier mode 0 */
33 [0] = 32000,
34 [1] = 44100,
35 [2] = 48000,
36 /* multiplier mode 1 */
37 [3] = 88200,
38 [4] = 96000,
39 /* multiplier mode 2 */
40 [5] = 176400,
41 [6] = 192000,
42};
43
44static inline unsigned int
45get_multiplier_mode_with_index(unsigned int index)
46{
47 return ((int)index - 1) / 2;
48}
49
50int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode)
51{
52 unsigned int i;
53
54 for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
55 if (freq_table[i] == sampling_rate) {
56 *mode = get_multiplier_mode_with_index(i);
57 return 0;
58 }
59 }
60
61 return -EINVAL;
62}
63
64static int
65hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
66{
67 unsigned int *pcm_channels = rule->private;
68 struct snd_interval *r =
69 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
70 const struct snd_interval *c =
71 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
72 struct snd_interval t = {
73 .min = UINT_MAX, .max = 0, .integer = 1
74 };
75 unsigned int i, mode;
76
77 for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
78 mode = get_multiplier_mode_with_index(i);
79 if (!snd_interval_test(c, pcm_channels[mode]))
80 continue;
81
82 t.min = min(t.min, freq_table[i]);
83 t.max = max(t.max, freq_table[i]);
84 }
85
86 return snd_interval_refine(r, &t);
87}
88
89static int
90hw_rule_channels(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
91{
92 unsigned int *pcm_channels = rule->private;
93 struct snd_interval *c =
94 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
95 const struct snd_interval *r =
96 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
97 struct snd_interval t = {
98 .min = UINT_MAX, .max = 0, .integer = 1
99 };
100 unsigned int i, mode;
101
102 for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
103 mode = get_multiplier_mode_with_index(i);
104 if (!snd_interval_test(r, freq_table[i]))
105 continue;
106
107 t.min = min(t.min, pcm_channels[mode]);
108 t.max = max(t.max, pcm_channels[mode]);
109 }
110
111 return snd_interval_refine(c, &t);
112}
113
114static void
115limit_channels(struct snd_pcm_hardware *hw, unsigned int *pcm_channels)
116{
117 unsigned int i, mode;
118
119 hw->channels_min = UINT_MAX;
120 hw->channels_max = 0;
121
122 for (i = 0; i < ARRAY_SIZE(freq_table); i++) {
123 mode = get_multiplier_mode_with_index(i);
124 if (pcm_channels[mode] == 0)
125 continue;
126
127 hw->channels_min = min(hw->channels_min, pcm_channels[mode]);
128 hw->channels_max = max(hw->channels_max, pcm_channels[mode]);
129 }
130}
131
132static void
133limit_period_and_buffer(struct snd_pcm_hardware *hw)
134{
135 hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */
136 hw->periods_max = UINT_MAX;
137
138 hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */
139
140 /* Just to prevent from allocating much pages. */
141 hw->period_bytes_max = hw->period_bytes_min * 2048;
142 hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;
143}
144
145static int
146pcm_init_hw_params(struct snd_efw *efw,
147 struct snd_pcm_substream *substream)
148{
149 struct snd_pcm_runtime *runtime = substream->runtime;
150 struct amdtp_stream *s;
151 unsigned int *pcm_channels;
152 int err;
153
154 runtime->hw.info = SNDRV_PCM_INFO_BATCH |
155 SNDRV_PCM_INFO_BLOCK_TRANSFER |
156 SNDRV_PCM_INFO_INTERLEAVED |
157 SNDRV_PCM_INFO_JOINT_DUPLEX |
158 SNDRV_PCM_INFO_MMAP |
159 SNDRV_PCM_INFO_MMAP_VALID;
160
161 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
162 runtime->hw.formats = AMDTP_IN_PCM_FORMAT_BITS;
163 s = &efw->tx_stream;
164 pcm_channels = efw->pcm_capture_channels;
165 } else {
166 runtime->hw.formats = AMDTP_OUT_PCM_FORMAT_BITS;
167 s = &efw->rx_stream;
168 pcm_channels = efw->pcm_playback_channels;
169 }
170
171 /* limit rates */
172 runtime->hw.rates = efw->supported_sampling_rate,
173 snd_pcm_limit_hw_rates(runtime);
174
175 limit_channels(&runtime->hw, pcm_channels);
176 limit_period_and_buffer(&runtime->hw);
177
178 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
179 hw_rule_channels, pcm_channels,
180 SNDRV_PCM_HW_PARAM_RATE, -1);
181 if (err < 0)
182 goto end;
183
184 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
185 hw_rule_rate, pcm_channels,
186 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
187 if (err < 0)
188 goto end;
189
190 err = amdtp_stream_add_pcm_hw_constraints(s, runtime);
191end:
192 return err;
193}
194
195static int pcm_open(struct snd_pcm_substream *substream)
196{
197 struct snd_efw *efw = substream->private_data;
198 unsigned int sampling_rate;
199 enum snd_efw_clock_source clock_source;
200 int err;
201
202 err = snd_efw_stream_lock_try(efw);
203 if (err < 0)
204 goto end;
205
206 err = pcm_init_hw_params(efw, substream);
207 if (err < 0)
208 goto err_locked;
209
210 err = snd_efw_command_get_clock_source(efw, &clock_source);
211 if (err < 0)
212 goto err_locked;
213
214 /*
215 * When source of clock is not internal or any PCM streams are running,
216 * available sampling rate is limited at current sampling rate.
217 */
218 if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
219 amdtp_stream_pcm_running(&efw->tx_stream) ||
220 amdtp_stream_pcm_running(&efw->rx_stream)) {
221 err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
222 if (err < 0)
223 goto err_locked;
224 substream->runtime->hw.rate_min = sampling_rate;
225 substream->runtime->hw.rate_max = sampling_rate;
226 }
227
228 snd_pcm_set_sync(substream);
229end:
230 return err;
231err_locked:
232 snd_efw_stream_lock_release(efw);
233 return err;
234}
235
236static int pcm_close(struct snd_pcm_substream *substream)
237{
238 struct snd_efw *efw = substream->private_data;
239 snd_efw_stream_lock_release(efw);
240 return 0;
241}
242
243static int pcm_capture_hw_params(struct snd_pcm_substream *substream,
244 struct snd_pcm_hw_params *hw_params)
245{
246 struct snd_efw *efw = substream->private_data;
247
248 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
249 atomic_inc(&efw->capture_substreams);
250 amdtp_stream_set_pcm_format(&efw->tx_stream, params_format(hw_params));
251
252 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
253 params_buffer_bytes(hw_params));
254}
255static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
256 struct snd_pcm_hw_params *hw_params)
257{
258 struct snd_efw *efw = substream->private_data;
259
260 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
261 atomic_inc(&efw->playback_substreams);
262 amdtp_stream_set_pcm_format(&efw->rx_stream, params_format(hw_params));
263
264 return snd_pcm_lib_alloc_vmalloc_buffer(substream,
265 params_buffer_bytes(hw_params));
266}
267
268static int pcm_capture_hw_free(struct snd_pcm_substream *substream)
269{
270 struct snd_efw *efw = substream->private_data;
271
272 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
273 atomic_dec(&efw->capture_substreams);
274
275 snd_efw_stream_stop_duplex(efw);
276
277 return snd_pcm_lib_free_vmalloc_buffer(substream);
278}
279static int pcm_playback_hw_free(struct snd_pcm_substream *substream)
280{
281 struct snd_efw *efw = substream->private_data;
282
283 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
284 atomic_dec(&efw->playback_substreams);
285
286 snd_efw_stream_stop_duplex(efw);
287
288 return snd_pcm_lib_free_vmalloc_buffer(substream);
289}
290
291static int pcm_capture_prepare(struct snd_pcm_substream *substream)
292{
293 struct snd_efw *efw = substream->private_data;
294 struct snd_pcm_runtime *runtime = substream->runtime;
295 int err;
296
297 err = snd_efw_stream_start_duplex(efw, runtime->rate);
298 if (err >= 0)
299 amdtp_stream_pcm_prepare(&efw->tx_stream);
300
301 return err;
302}
303static int pcm_playback_prepare(struct snd_pcm_substream *substream)
304{
305 struct snd_efw *efw = substream->private_data;
306 struct snd_pcm_runtime *runtime = substream->runtime;
307 int err;
308
309 err = snd_efw_stream_start_duplex(efw, runtime->rate);
310 if (err >= 0)
311 amdtp_stream_pcm_prepare(&efw->rx_stream);
312
313 return err;
314}
315
316static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
317{
318 struct snd_efw *efw = substream->private_data;
319
320 switch (cmd) {
321 case SNDRV_PCM_TRIGGER_START:
322 amdtp_stream_pcm_trigger(&efw->tx_stream, substream);
323 break;
324 case SNDRV_PCM_TRIGGER_STOP:
325 amdtp_stream_pcm_trigger(&efw->tx_stream, NULL);
326 break;
327 default:
328 return -EINVAL;
329 }
330
331 return 0;
332}
333static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
334{
335 struct snd_efw *efw = substream->private_data;
336
337 switch (cmd) {
338 case SNDRV_PCM_TRIGGER_START:
339 amdtp_stream_pcm_trigger(&efw->rx_stream, substream);
340 break;
341 case SNDRV_PCM_TRIGGER_STOP:
342 amdtp_stream_pcm_trigger(&efw->rx_stream, NULL);
343 break;
344 default:
345 return -EINVAL;
346 }
347
348 return 0;
349}
350
351static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)
352{
353 struct snd_efw *efw = sbstrm->private_data;
354 return amdtp_stream_pcm_pointer(&efw->tx_stream);
355}
356static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)
357{
358 struct snd_efw *efw = sbstrm->private_data;
359 return amdtp_stream_pcm_pointer(&efw->rx_stream);
360}
361
362static const struct snd_pcm_ops pcm_capture_ops = {
363 .open = pcm_open,
364 .close = pcm_close,
365 .ioctl = snd_pcm_lib_ioctl,
366 .hw_params = pcm_capture_hw_params,
367 .hw_free = pcm_capture_hw_free,
368 .prepare = pcm_capture_prepare,
369 .trigger = pcm_capture_trigger,
370 .pointer = pcm_capture_pointer,
371 .page = snd_pcm_lib_get_vmalloc_page,
372};
373
374static const struct snd_pcm_ops pcm_playback_ops = {
375 .open = pcm_open,
376 .close = pcm_close,
377 .ioctl = snd_pcm_lib_ioctl,
378 .hw_params = pcm_playback_hw_params,
379 .hw_free = pcm_playback_hw_free,
380 .prepare = pcm_playback_prepare,
381 .trigger = pcm_playback_trigger,
382 .pointer = pcm_playback_pointer,
383 .page = snd_pcm_lib_get_vmalloc_page,
384 .mmap = snd_pcm_lib_mmap_vmalloc,
385};
386
387int snd_efw_create_pcm_devices(struct snd_efw *efw)
388{
389 struct snd_pcm *pcm;
390 int err;
391
392 err = snd_pcm_new(efw->card, efw->card->driver, 0, 1, 1, &pcm);
393 if (err < 0)
394 goto end;
395
396 pcm->private_data = efw;
397 snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname);
398 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);
399 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);
400end:
401 return err;
402}
403
diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c
new file mode 100644
index 000000000000..f29d4aaf56a1
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_proc.c
@@ -0,0 +1,232 @@
1/*
2 * fireworks_proc.c - a part of driver for Fireworks based devices
3 *
4 * Copyright (c) 2009-2010 Clemens Ladisch
5 * Copyright (c) 2013-2014 Takashi Sakamoto
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10#include "./fireworks.h"
11
12static inline const char*
13get_phys_name(struct snd_efw_phys_grp *grp, bool input)
14{
15 const char *const ch_type[] = {
16 "Analog", "S/PDIF", "ADAT", "S/PDIF or ADAT", "Mirroring",
17 "Headphones", "I2S", "Guitar", "Pirzo Guitar", "Guitar String",
18 };
19
20 if (grp->type < ARRAY_SIZE(ch_type))
21 return ch_type[grp->type];
22 else if (input)
23 return "Input";
24 else
25 return "Output";
26}
27
28static void
29proc_read_hwinfo(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
30{
31 struct snd_efw *efw = entry->private_data;
32 unsigned short i;
33 struct snd_efw_hwinfo *hwinfo;
34
35 hwinfo = kmalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL);
36 if (hwinfo == NULL)
37 return;
38
39 if (snd_efw_command_get_hwinfo(efw, hwinfo) < 0)
40 goto end;
41
42 snd_iprintf(buffer, "guid_hi: 0x%X\n", hwinfo->guid_hi);
43 snd_iprintf(buffer, "guid_lo: 0x%X\n", hwinfo->guid_lo);
44 snd_iprintf(buffer, "type: 0x%X\n", hwinfo->type);
45 snd_iprintf(buffer, "version: 0x%X\n", hwinfo->version);
46 snd_iprintf(buffer, "vendor_name: %s\n", hwinfo->vendor_name);
47 snd_iprintf(buffer, "model_name: %s\n", hwinfo->model_name);
48
49 snd_iprintf(buffer, "dsp_version: 0x%X\n", hwinfo->dsp_version);
50 snd_iprintf(buffer, "arm_version: 0x%X\n", hwinfo->arm_version);
51 snd_iprintf(buffer, "fpga_version: 0x%X\n", hwinfo->fpga_version);
52
53 snd_iprintf(buffer, "flags: 0x%X\n", hwinfo->flags);
54
55 snd_iprintf(buffer, "max_sample_rate: 0x%X\n", hwinfo->max_sample_rate);
56 snd_iprintf(buffer, "min_sample_rate: 0x%X\n", hwinfo->min_sample_rate);
57 snd_iprintf(buffer, "supported_clock: 0x%X\n",
58 hwinfo->supported_clocks);
59
60 snd_iprintf(buffer, "phys out: 0x%X\n", hwinfo->phys_out);
61 snd_iprintf(buffer, "phys in: 0x%X\n", hwinfo->phys_in);
62
63 snd_iprintf(buffer, "phys in grps: 0x%X\n",
64 hwinfo->phys_in_grp_count);
65 for (i = 0; i < hwinfo->phys_in_grp_count; i++) {
66 snd_iprintf(buffer,
67 "phys in grp[0x%d]: type 0x%d, count 0x%d\n",
68 i, hwinfo->phys_out_grps[i].type,
69 hwinfo->phys_out_grps[i].count);
70 }
71
72 snd_iprintf(buffer, "phys out grps: 0x%X\n",
73 hwinfo->phys_out_grp_count);
74 for (i = 0; i < hwinfo->phys_out_grp_count; i++) {
75 snd_iprintf(buffer,
76 "phys out grps[0x%d]: type 0x%d, count 0x%d\n",
77 i, hwinfo->phys_out_grps[i].type,
78 hwinfo->phys_out_grps[i].count);
79 }
80
81 snd_iprintf(buffer, "amdtp rx pcm channels 1x: 0x%X\n",
82 hwinfo->amdtp_rx_pcm_channels);
83 snd_iprintf(buffer, "amdtp tx pcm channels 1x: 0x%X\n",
84 hwinfo->amdtp_tx_pcm_channels);
85 snd_iprintf(buffer, "amdtp rx pcm channels 2x: 0x%X\n",
86 hwinfo->amdtp_rx_pcm_channels_2x);
87 snd_iprintf(buffer, "amdtp tx pcm channels 2x: 0x%X\n",
88 hwinfo->amdtp_tx_pcm_channels_2x);
89 snd_iprintf(buffer, "amdtp rx pcm channels 4x: 0x%X\n",
90 hwinfo->amdtp_rx_pcm_channels_4x);
91 snd_iprintf(buffer, "amdtp tx pcm channels 4x: 0x%X\n",
92 hwinfo->amdtp_tx_pcm_channels_4x);
93
94 snd_iprintf(buffer, "midi out ports: 0x%X\n", hwinfo->midi_out_ports);
95 snd_iprintf(buffer, "midi in ports: 0x%X\n", hwinfo->midi_in_ports);
96
97 snd_iprintf(buffer, "mixer playback channels: 0x%X\n",
98 hwinfo->mixer_playback_channels);
99 snd_iprintf(buffer, "mixer capture channels: 0x%X\n",
100 hwinfo->mixer_capture_channels);
101end:
102 kfree(hwinfo);
103}
104
105static void
106proc_read_clock(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
107{
108 struct snd_efw *efw = entry->private_data;
109 enum snd_efw_clock_source clock_source;
110 unsigned int sampling_rate;
111
112 if (snd_efw_command_get_clock_source(efw, &clock_source) < 0)
113 return;
114
115 if (snd_efw_command_get_sampling_rate(efw, &sampling_rate) < 0)
116 return;
117
118 snd_iprintf(buffer, "Clock Source: %d\n", clock_source);
119 snd_iprintf(buffer, "Sampling Rate: %d\n", sampling_rate);
120}
121
122/*
123 * NOTE:
124 * dB = 20 * log10(linear / 0x01000000)
125 * -144.0 dB when linear is 0
126 */
127static void
128proc_read_phys_meters(struct snd_info_entry *entry,
129 struct snd_info_buffer *buffer)
130{
131 struct snd_efw *efw = entry->private_data;
132 struct snd_efw_phys_meters *meters;
133 unsigned int g, c, m, max, size;
134 const char *name;
135 u32 *linear;
136 int err;
137
138 size = sizeof(struct snd_efw_phys_meters) +
139 (efw->phys_in + efw->phys_out) * sizeof(u32);
140 meters = kzalloc(size, GFP_KERNEL);
141 if (meters == NULL)
142 return;
143
144 err = snd_efw_command_get_phys_meters(efw, meters, size);
145 if (err < 0)
146 goto end;
147
148 snd_iprintf(buffer, "Physical Meters:\n");
149
150 m = 0;
151 max = min(efw->phys_out, meters->out_meters);
152 linear = meters->values;
153 snd_iprintf(buffer, " %d Outputs:\n", max);
154 for (g = 0; g < efw->phys_out_grp_count; g++) {
155 name = get_phys_name(&efw->phys_out_grps[g], false);
156 for (c = 0; c < efw->phys_out_grps[g].count; c++) {
157 if (m < max)
158 snd_iprintf(buffer, "\t%s [%d]: %d\n",
159 name, c, linear[m++]);
160 }
161 }
162
163 m = 0;
164 max = min(efw->phys_in, meters->in_meters);
165 linear = meters->values + meters->out_meters;
166 snd_iprintf(buffer, " %d Inputs:\n", max);
167 for (g = 0; g < efw->phys_in_grp_count; g++) {
168 name = get_phys_name(&efw->phys_in_grps[g], true);
169 for (c = 0; c < efw->phys_in_grps[g].count; c++)
170 if (m < max)
171 snd_iprintf(buffer, "\t%s [%d]: %d\n",
172 name, c, linear[m++]);
173 }
174end:
175 kfree(meters);
176}
177
178static void
179proc_read_queues_state(struct snd_info_entry *entry,
180 struct snd_info_buffer *buffer)
181{
182 struct snd_efw *efw = entry->private_data;
183 unsigned int consumed;
184
185 if (efw->pull_ptr > efw->push_ptr)
186 consumed = snd_efw_resp_buf_size -
187 (unsigned int)(efw->pull_ptr - efw->push_ptr);
188 else
189 consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr);
190
191 snd_iprintf(buffer, "%d %d/%d\n",
192 efw->resp_queues, consumed, snd_efw_resp_buf_size);
193}
194
195static void
196add_node(struct snd_efw *efw, struct snd_info_entry *root, const char *name,
197 void (*op)(struct snd_info_entry *e, struct snd_info_buffer *b))
198{
199 struct snd_info_entry *entry;
200
201 entry = snd_info_create_card_entry(efw->card, name, root);
202 if (entry == NULL)
203 return;
204
205 snd_info_set_text_ops(entry, efw, op);
206 if (snd_info_register(entry) < 0)
207 snd_info_free_entry(entry);
208}
209
210void snd_efw_proc_init(struct snd_efw *efw)
211{
212 struct snd_info_entry *root;
213
214 /*
215 * All nodes are automatically removed at snd_card_disconnect(),
216 * by following to link list.
217 */
218 root = snd_info_create_card_entry(efw->card, "firewire",
219 efw->card->proc_root);
220 if (root == NULL)
221 return;
222 root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
223 if (snd_info_register(root) < 0) {
224 snd_info_free_entry(root);
225 return;
226 }
227
228 add_node(efw, root, "clock", proc_read_clock);
229 add_node(efw, root, "firmware", proc_read_hwinfo);
230 add_node(efw, root, "meters", proc_read_phys_meters);
231 add_node(efw, root, "queues", proc_read_queues_state);
232}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
new file mode 100644
index 000000000000..541569022a7c
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -0,0 +1,372 @@
1/*
2 * fireworks_stream.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#include "./fireworks.h"
9
10#define CALLBACK_TIMEOUT 100
11
12static int
13init_stream(struct snd_efw *efw, struct amdtp_stream *stream)
14{
15 struct cmp_connection *conn;
16 enum cmp_direction c_dir;
17 enum amdtp_stream_direction s_dir;
18 int err;
19
20 if (stream == &efw->tx_stream) {
21 conn = &efw->out_conn;
22 c_dir = CMP_OUTPUT;
23 s_dir = AMDTP_IN_STREAM;
24 } else {
25 conn = &efw->in_conn;
26 c_dir = CMP_INPUT;
27 s_dir = AMDTP_OUT_STREAM;
28 }
29
30 err = cmp_connection_init(conn, efw->unit, c_dir, 0);
31 if (err < 0)
32 goto end;
33
34 err = amdtp_stream_init(stream, efw->unit, s_dir, CIP_BLOCKING);
35 if (err < 0) {
36 amdtp_stream_destroy(stream);
37 cmp_connection_destroy(conn);
38 }
39end:
40 return err;
41}
42
43static void
44stop_stream(struct snd_efw *efw, struct amdtp_stream *stream)
45{
46 amdtp_stream_pcm_abort(stream);
47 amdtp_stream_stop(stream);
48
49 if (stream == &efw->tx_stream)
50 cmp_connection_break(&efw->out_conn);
51 else
52 cmp_connection_break(&efw->in_conn);
53}
54
55static int
56start_stream(struct snd_efw *efw, struct amdtp_stream *stream,
57 unsigned int sampling_rate)
58{
59 struct cmp_connection *conn;
60 unsigned int mode, pcm_channels, midi_ports;
61 int err;
62
63 err = snd_efw_get_multiplier_mode(sampling_rate, &mode);
64 if (err < 0)
65 goto end;
66 if (stream == &efw->tx_stream) {
67 conn = &efw->out_conn;
68 pcm_channels = efw->pcm_capture_channels[mode];
69 midi_ports = efw->midi_out_ports;
70 } else {
71 conn = &efw->in_conn;
72 pcm_channels = efw->pcm_playback_channels[mode];
73 midi_ports = efw->midi_in_ports;
74 }
75
76 amdtp_stream_set_parameters(stream, sampling_rate,
77 pcm_channels, midi_ports);
78
79 /* establish connection via CMP */
80 err = cmp_connection_establish(conn,
81 amdtp_stream_get_max_payload(stream));
82 if (err < 0)
83 goto end;
84
85 /* start amdtp stream */
86 err = amdtp_stream_start(stream,
87 conn->resources.channel,
88 conn->speed);
89 if (err < 0) {
90 stop_stream(efw, stream);
91 goto end;
92 }
93
94 /* wait first callback */
95 if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) {
96 stop_stream(efw, stream);
97 err = -ETIMEDOUT;
98 }
99end:
100 return err;
101}
102
103static void
104destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream)
105{
106 stop_stream(efw, stream);
107
108 amdtp_stream_destroy(stream);
109
110 if (stream == &efw->tx_stream)
111 cmp_connection_destroy(&efw->out_conn);
112 else
113 cmp_connection_destroy(&efw->in_conn);
114}
115
116static int
117get_sync_mode(struct snd_efw *efw, enum cip_flags *sync_mode)
118{
119 enum snd_efw_clock_source clock_source;
120 int err;
121
122 err = snd_efw_command_get_clock_source(efw, &clock_source);
123 if (err < 0)
124 return err;
125
126 if (clock_source == SND_EFW_CLOCK_SOURCE_SYTMATCH)
127 return -ENOSYS;
128
129 *sync_mode = CIP_SYNC_TO_DEVICE;
130 return 0;
131}
132
133static int
134check_connection_used_by_others(struct snd_efw *efw, struct amdtp_stream *s)
135{
136 struct cmp_connection *conn;
137 bool used;
138 int err;
139
140 if (s == &efw->tx_stream)
141 conn = &efw->out_conn;
142 else
143 conn = &efw->in_conn;
144
145 err = cmp_connection_check_used(conn, &used);
146 if ((err >= 0) && used && !amdtp_stream_running(s)) {
147 dev_err(&efw->unit->device,
148 "Connection established by others: %cPCR[%d]\n",
149 (conn->direction == CMP_OUTPUT) ? 'o' : 'i',
150 conn->pcr_index);
151 err = -EBUSY;
152 }
153
154 return err;
155}
156
157int snd_efw_stream_init_duplex(struct snd_efw *efw)
158{
159 int err;
160
161 err = init_stream(efw, &efw->tx_stream);
162 if (err < 0)
163 goto end;
164 /* Fireworks transmits NODATA packets with TAG0. */
165 efw->tx_stream.flags |= CIP_EMPTY_WITH_TAG0;
166 /* Fireworks has its own meaning for dbc. */
167 efw->tx_stream.flags |= CIP_DBC_IS_END_EVENT;
168 /* Fireworks reset dbc at bus reset. */
169 efw->tx_stream.flags |= CIP_SKIP_DBC_ZERO_CHECK;
170 /* AudioFire9 always reports wrong dbs. */
171 if (efw->is_af9)
172 efw->tx_stream.flags |= CIP_WRONG_DBS;
173 /* Firmware version 5.5 reports fixed interval for dbc. */
174 if (efw->firmware_version == 0x5050000)
175 efw->tx_stream.tx_dbc_interval = 8;
176
177 err = init_stream(efw, &efw->rx_stream);
178 if (err < 0) {
179 destroy_stream(efw, &efw->tx_stream);
180 goto end;
181 }
182 /*
183 * Fireworks ignores MIDI messages in more than first 8 data
184 * blocks of an received AMDTP packet.
185 */
186 efw->rx_stream.rx_blocks_for_midi = 8;
187
188 /* set IEC61883 compliant mode (actually not fully compliant...) */
189 err = snd_efw_command_set_tx_mode(efw, SND_EFW_TRANSPORT_MODE_IEC61883);
190 if (err < 0) {
191 destroy_stream(efw, &efw->tx_stream);
192 destroy_stream(efw, &efw->rx_stream);
193 }
194end:
195 return err;
196}
197
198int snd_efw_stream_start_duplex(struct snd_efw *efw, unsigned int rate)
199{
200 struct amdtp_stream *master, *slave;
201 atomic_t *slave_substreams;
202 enum cip_flags sync_mode;
203 unsigned int curr_rate;
204 int err = 0;
205
206 mutex_lock(&efw->mutex);
207
208 /* Need no substreams */
209 if ((atomic_read(&efw->playback_substreams) == 0) &&
210 (atomic_read(&efw->capture_substreams) == 0))
211 goto end;
212
213 err = get_sync_mode(efw, &sync_mode);
214 if (err < 0)
215 goto end;
216 if (sync_mode == CIP_SYNC_TO_DEVICE) {
217 master = &efw->tx_stream;
218 slave = &efw->rx_stream;
219 slave_substreams = &efw->playback_substreams;
220 } else {
221 master = &efw->rx_stream;
222 slave = &efw->tx_stream;
223 slave_substreams = &efw->capture_substreams;
224 }
225
226 /*
227 * Considering JACK/FFADO streaming:
228 * TODO: This can be removed hwdep functionality becomes popular.
229 */
230 err = check_connection_used_by_others(efw, master);
231 if (err < 0)
232 goto end;
233
234 /* packet queueing error */
235 if (amdtp_streaming_error(slave))
236 stop_stream(efw, slave);
237 if (amdtp_streaming_error(master))
238 stop_stream(efw, master);
239
240 /* stop streams if rate is different */
241 err = snd_efw_command_get_sampling_rate(efw, &curr_rate);
242 if (err < 0)
243 goto end;
244 if (rate == 0)
245 rate = curr_rate;
246 if (rate != curr_rate) {
247 stop_stream(efw, slave);
248 stop_stream(efw, master);
249 }
250
251 /* master should be always running */
252 if (!amdtp_stream_running(master)) {
253 amdtp_stream_set_sync(sync_mode, master, slave);
254 efw->master = master;
255
256 err = snd_efw_command_set_sampling_rate(efw, rate);
257 if (err < 0)
258 goto end;
259
260 err = start_stream(efw, master, rate);
261 if (err < 0) {
262 dev_err(&efw->unit->device,
263 "fail to start AMDTP master stream:%d\n", err);
264 goto end;
265 }
266 }
267
268 /* start slave if needed */
269 if (atomic_read(slave_substreams) > 0 && !amdtp_stream_running(slave)) {
270 err = start_stream(efw, slave, rate);
271 if (err < 0) {
272 dev_err(&efw->unit->device,
273 "fail to start AMDTP slave stream:%d\n", err);
274 stop_stream(efw, master);
275 }
276 }
277end:
278 mutex_unlock(&efw->mutex);
279 return err;
280}
281
282void snd_efw_stream_stop_duplex(struct snd_efw *efw)
283{
284 struct amdtp_stream *master, *slave;
285 atomic_t *master_substreams, *slave_substreams;
286
287 mutex_lock(&efw->mutex);
288
289 if (efw->master == &efw->rx_stream) {
290 slave = &efw->tx_stream;
291 master = &efw->rx_stream;
292 slave_substreams = &efw->capture_substreams;
293 master_substreams = &efw->playback_substreams;
294 } else {
295 slave = &efw->rx_stream;
296 master = &efw->tx_stream;
297 slave_substreams = &efw->playback_substreams;
298 master_substreams = &efw->capture_substreams;
299 }
300
301 if (atomic_read(slave_substreams) == 0) {
302 stop_stream(efw, slave);
303
304 if (atomic_read(master_substreams) == 0)
305 stop_stream(efw, master);
306 }
307
308 mutex_unlock(&efw->mutex);
309}
310
311void snd_efw_stream_update_duplex(struct snd_efw *efw)
312{
313 if ((cmp_connection_update(&efw->out_conn) < 0) ||
314 (cmp_connection_update(&efw->in_conn) < 0)) {
315 mutex_lock(&efw->mutex);
316 stop_stream(efw, &efw->rx_stream);
317 stop_stream(efw, &efw->tx_stream);
318 mutex_unlock(&efw->mutex);
319 } else {
320 amdtp_stream_update(&efw->rx_stream);
321 amdtp_stream_update(&efw->tx_stream);
322 }
323}
324
325void snd_efw_stream_destroy_duplex(struct snd_efw *efw)
326{
327 mutex_lock(&efw->mutex);
328
329 destroy_stream(efw, &efw->rx_stream);
330 destroy_stream(efw, &efw->tx_stream);
331
332 mutex_unlock(&efw->mutex);
333}
334
335void snd_efw_stream_lock_changed(struct snd_efw *efw)
336{
337 efw->dev_lock_changed = true;
338 wake_up(&efw->hwdep_wait);
339}
340
341int snd_efw_stream_lock_try(struct snd_efw *efw)
342{
343 int err;
344
345 spin_lock_irq(&efw->lock);
346
347 /* user land lock this */
348 if (efw->dev_lock_count < 0) {
349 err = -EBUSY;
350 goto end;
351 }
352
353 /* this is the first time */
354 if (efw->dev_lock_count++ == 0)
355 snd_efw_stream_lock_changed(efw);
356 err = 0;
357end:
358 spin_unlock_irq(&efw->lock);
359 return err;
360}
361
362void snd_efw_stream_lock_release(struct snd_efw *efw)
363{
364 spin_lock_irq(&efw->lock);
365
366 if (WARN_ON(efw->dev_lock_count <= 0))
367 goto end;
368 if (--efw->dev_lock_count == 0)
369 snd_efw_stream_lock_changed(efw);
370end:
371 spin_unlock_irq(&efw->lock);
372}
diff --git a/sound/firewire/fireworks/fireworks_transaction.c b/sound/firewire/fireworks/fireworks_transaction.c
new file mode 100644
index 000000000000..aa56b8ac537c
--- /dev/null
+++ b/sound/firewire/fireworks/fireworks_transaction.c
@@ -0,0 +1,326 @@
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 0xecc000000000ULL
35#define MEMORY_SPACE_EFW_RESPONSE 0xecc080000000ULL
36
37#define ERROR_RETRIES 3
38#define ERROR_DELAY_MS 5
39#define EFC_TIMEOUT_MS 125
40
41static DEFINE_SPINLOCK(instances_lock);
42static struct snd_efw *instances[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
43
44static DEFINE_SPINLOCK(transaction_queues_lock);
45static LIST_HEAD(transaction_queues);
46
47enum transaction_queue_state {
48 STATE_PENDING,
49 STATE_BUS_RESET,
50 STATE_COMPLETE
51};
52
53struct transaction_queue {
54 struct list_head list;
55 struct fw_unit *unit;
56 void *buf;
57 unsigned int size;
58 u32 seqnum;
59 enum transaction_queue_state state;
60 wait_queue_head_t wait;
61};
62
63int snd_efw_transaction_cmd(struct fw_unit *unit,
64 const void *cmd, unsigned int size)
65{
66 return snd_fw_transaction(unit, TCODE_WRITE_BLOCK_REQUEST,
67 MEMORY_SPACE_EFW_COMMAND,
68 (void *)cmd, size, 0);
69}
70
71int snd_efw_transaction_run(struct fw_unit *unit,
72 const void *cmd, unsigned int cmd_size,
73 void *resp, unsigned int resp_size)
74{
75 struct transaction_queue t;
76 unsigned int tries;
77 int ret;
78
79 t.unit = unit;
80 t.buf = resp;
81 t.size = resp_size;
82 t.seqnum = be32_to_cpu(((struct snd_efw_transaction *)cmd)->seqnum) + 1;
83 t.state = STATE_PENDING;
84 init_waitqueue_head(&t.wait);
85
86 spin_lock_irq(&transaction_queues_lock);
87 list_add_tail(&t.list, &transaction_queues);
88 spin_unlock_irq(&transaction_queues_lock);
89
90 tries = 0;
91 do {
92 ret = snd_efw_transaction_cmd(t.unit, (void *)cmd, cmd_size);
93 if (ret < 0)
94 break;
95
96 wait_event_timeout(t.wait, t.state != STATE_PENDING,
97 msecs_to_jiffies(EFC_TIMEOUT_MS));
98
99 if (t.state == STATE_COMPLETE) {
100 ret = t.size;
101 break;
102 } else if (t.state == STATE_BUS_RESET) {
103 msleep(ERROR_DELAY_MS);
104 } else if (++tries >= ERROR_RETRIES) {
105 dev_err(&t.unit->device, "EFW transaction timed out\n");
106 ret = -EIO;
107 break;
108 }
109 } while (1);
110
111 spin_lock_irq(&transaction_queues_lock);
112 list_del(&t.list);
113 spin_unlock_irq(&transaction_queues_lock);
114
115 return ret;
116}
117
118static void
119copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode)
120{
121 size_t capacity, till_end;
122 struct snd_efw_transaction *t;
123
124 spin_lock_irq(&efw->lock);
125
126 t = (struct snd_efw_transaction *)data;
127 length = min_t(size_t, t->length * sizeof(t->length), length);
128
129 if (efw->push_ptr < efw->pull_ptr)
130 capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr);
131 else
132 capacity = snd_efw_resp_buf_size -
133 (unsigned int)(efw->push_ptr - efw->pull_ptr);
134
135 /* confirm enough space for this response */
136 if (capacity < length) {
137 *rcode = RCODE_CONFLICT_ERROR;
138 goto end;
139 }
140
141 /* copy to ring buffer */
142 while (length > 0) {
143 till_end = snd_efw_resp_buf_size -
144 (unsigned int)(efw->push_ptr - efw->resp_buf);
145 till_end = min_t(unsigned int, length, till_end);
146
147 memcpy(efw->push_ptr, data, till_end);
148
149 efw->push_ptr += till_end;
150 if (efw->push_ptr >= efw->resp_buf + snd_efw_resp_buf_size)
151 efw->push_ptr = efw->resp_buf;
152
153 length -= till_end;
154 data += till_end;
155 }
156
157 /* for hwdep */
158 efw->resp_queues++;
159 wake_up(&efw->hwdep_wait);
160
161 *rcode = RCODE_COMPLETE;
162end:
163 spin_unlock_irq(&efw->lock);
164}
165
166static void
167handle_resp_for_user(struct fw_card *card, int generation, int source,
168 void *data, size_t length, int *rcode)
169{
170 struct fw_device *device;
171 struct snd_efw *efw;
172 unsigned int i;
173
174 spin_lock_irq(&instances_lock);
175
176 for (i = 0; i < SNDRV_CARDS; i++) {
177 efw = instances[i];
178 if (efw == NULL)
179 continue;
180 device = fw_parent_device(efw->unit);
181 if ((device->card != card) ||
182 (device->generation != generation))
183 continue;
184 smp_rmb(); /* node id vs. generation */
185 if (device->node_id != source)
186 continue;
187
188 break;
189 }
190 if (i == SNDRV_CARDS)
191 goto end;
192
193 copy_resp_to_buf(efw, data, length, rcode);
194end:
195 spin_unlock_irq(&instances_lock);
196}
197
198static void
199handle_resp_for_kernel(struct fw_card *card, int generation, int source,
200 void *data, size_t length, int *rcode, u32 seqnum)
201{
202 struct fw_device *device;
203 struct transaction_queue *t;
204 unsigned long flags;
205
206 spin_lock_irqsave(&transaction_queues_lock, flags);
207 list_for_each_entry(t, &transaction_queues, list) {
208 device = fw_parent_device(t->unit);
209 if ((device->card != card) ||
210 (device->generation != generation))
211 continue;
212 smp_rmb(); /* node_id vs. generation */
213 if (device->node_id != source)
214 continue;
215
216 if ((t->state == STATE_PENDING) && (t->seqnum == seqnum)) {
217 t->state = STATE_COMPLETE;
218 t->size = min_t(unsigned int, length, t->size);
219 memcpy(t->buf, data, t->size);
220 wake_up(&t->wait);
221 *rcode = RCODE_COMPLETE;
222 }
223 }
224 spin_unlock_irqrestore(&transaction_queues_lock, flags);
225}
226
227static void
228efw_response(struct fw_card *card, struct fw_request *request,
229 int tcode, int destination, int source,
230 int generation, unsigned long long offset,
231 void *data, size_t length, void *callback_data)
232{
233 int rcode, dummy;
234 u32 seqnum;
235
236 rcode = RCODE_TYPE_ERROR;
237 if (length < sizeof(struct snd_efw_transaction)) {
238 rcode = RCODE_DATA_ERROR;
239 goto end;
240 } else if (offset != MEMORY_SPACE_EFW_RESPONSE) {
241 rcode = RCODE_ADDRESS_ERROR;
242 goto end;
243 }
244
245 seqnum = be32_to_cpu(((struct snd_efw_transaction *)data)->seqnum);
246 if (seqnum > SND_EFW_TRANSACTION_USER_SEQNUM_MAX + 1) {
247 handle_resp_for_kernel(card, generation, source,
248 data, length, &rcode, seqnum);
249 if (snd_efw_resp_buf_debug)
250 handle_resp_for_user(card, generation, source,
251 data, length, &dummy);
252 } else {
253 handle_resp_for_user(card, generation, source,
254 data, length, &rcode);
255 }
256end:
257 fw_send_response(card, request, rcode);
258}
259
260void snd_efw_transaction_add_instance(struct snd_efw *efw)
261{
262 unsigned int i;
263
264 spin_lock_irq(&instances_lock);
265
266 for (i = 0; i < SNDRV_CARDS; i++) {
267 if (instances[i] != NULL)
268 continue;
269 instances[i] = efw;
270 break;
271 }
272
273 spin_unlock_irq(&instances_lock);
274}
275
276void snd_efw_transaction_remove_instance(struct snd_efw *efw)
277{
278 unsigned int i;
279
280 spin_lock_irq(&instances_lock);
281
282 for (i = 0; i < SNDRV_CARDS; i++) {
283 if (instances[i] != efw)
284 continue;
285 instances[i] = NULL;
286 }
287
288 spin_unlock_irq(&instances_lock);
289}
290
291void snd_efw_transaction_bus_reset(struct fw_unit *unit)
292{
293 struct transaction_queue *t;
294
295 spin_lock_irq(&transaction_queues_lock);
296 list_for_each_entry(t, &transaction_queues, list) {
297 if ((t->unit == unit) &&
298 (t->state == STATE_PENDING)) {
299 t->state = STATE_BUS_RESET;
300 wake_up(&t->wait);
301 }
302 }
303 spin_unlock_irq(&transaction_queues_lock);
304}
305
306static struct fw_address_handler resp_register_handler = {
307 .length = SND_EFW_RESPONSE_MAXIMUM_BYTES,
308 .address_callback = efw_response
309};
310
311int snd_efw_transaction_register(void)
312{
313 static const struct fw_address_region resp_register_region = {
314 .start = MEMORY_SPACE_EFW_RESPONSE,
315 .end = MEMORY_SPACE_EFW_RESPONSE +
316 SND_EFW_RESPONSE_MAXIMUM_BYTES
317 };
318 return fw_core_add_address_handler(&resp_register_handler,
319 &resp_register_region);
320}
321
322void snd_efw_transaction_unregister(void)
323{
324 WARN_ON(!list_empty(&transaction_queues));
325 fw_core_remove_address_handler(&resp_register_handler);
326}