ALSA: oxfw: Split stream functionality to a new file and add a header file
[deliverable/linux.git] / sound / firewire / oxfw / oxfw.c
CommitLineData
31ef9134 1/*
8832c5a7 2 * oxfw.c - a part of driver for OXFW970/971 based devices
31ef9134
CL
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * Licensed under the terms of the GNU General Public License, version 2.
6 */
7
e2786ca6 8#include "oxfw.h"
31ef9134
CL
9
10#define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000)
11/* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */
12
13#define OXFORD_HARDWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x90020)
14#define OXFORD_HARDWARE_ID_OXFW970 0x39443841
15#define OXFORD_HARDWARE_ID_OXFW971 0x39373100
16
17#define VENDOR_GRIFFIN 0x001292
18#define VENDOR_LACIE 0x00d04b
19
20#define SPECIFIER_1394TA 0x00a02d
21#define VERSION_AVC 0x010001
22
8832c5a7 23MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver");
31ef9134
CL
24MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
25MODULE_LICENSE("GPL v2");
8832c5a7 26MODULE_ALIAS("snd-firewire-speakers");
31ef9134
CL
27
28static int firewave_rate_constraint(struct snd_pcm_hw_params *params,
29 struct snd_pcm_hw_rule *rule)
30{
31 static unsigned int stereo_rates[] = { 48000, 96000 };
32 struct snd_interval *channels =
33 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
34 struct snd_interval *rate =
35 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
36
37 /* two channels work only at 48/96 kHz */
38 if (snd_interval_max(channels) < 6)
39 return snd_interval_list(rate, 2, stereo_rates, 0);
40 return 0;
41}
42
43static int firewave_channels_constraint(struct snd_pcm_hw_params *params,
44 struct snd_pcm_hw_rule *rule)
45{
46 static const struct snd_interval all_channels = { .min = 6, .max = 6 };
47 struct snd_interval *rate =
48 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
49 struct snd_interval *channels =
50 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
51
52 /* 32/44.1 kHz work only with all six channels */
53 if (snd_interval_max(rate) < 48000)
54 return snd_interval_refine(channels, &all_channels);
55 return 0;
56}
57
58static int firewave_constraints(struct snd_pcm_runtime *runtime)
59{
60 static unsigned int channels_list[] = { 2, 6 };
61 static struct snd_pcm_hw_constraint_list channels_list_constraint = {
62 .count = 2,
63 .list = channels_list,
64 };
65 int err;
66
67 runtime->hw.rates = SNDRV_PCM_RATE_32000 |
68 SNDRV_PCM_RATE_44100 |
69 SNDRV_PCM_RATE_48000 |
70 SNDRV_PCM_RATE_96000;
71 runtime->hw.channels_max = 6;
72
73 err = snd_pcm_hw_constraint_list(runtime, 0,
74 SNDRV_PCM_HW_PARAM_CHANNELS,
75 &channels_list_constraint);
76 if (err < 0)
77 return err;
78 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
79 firewave_rate_constraint, NULL,
80 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
81 if (err < 0)
82 return err;
83 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
84 firewave_channels_constraint, NULL,
85 SNDRV_PCM_HW_PARAM_RATE, -1);
86 if (err < 0)
87 return err;
88
89 return 0;
90}
91
92static int lacie_speakers_constraints(struct snd_pcm_runtime *runtime)
93{
94 runtime->hw.rates = SNDRV_PCM_RATE_32000 |
95 SNDRV_PCM_RATE_44100 |
96 SNDRV_PCM_RATE_48000 |
97 SNDRV_PCM_RATE_88200 |
98 SNDRV_PCM_RATE_96000;
99
100 return 0;
101}
102
8832c5a7 103static int oxfw_open(struct snd_pcm_substream *substream)
31ef9134
CL
104{
105 static const struct snd_pcm_hardware hardware = {
106 .info = SNDRV_PCM_INFO_MMAP |
107 SNDRV_PCM_INFO_MMAP_VALID |
108 SNDRV_PCM_INFO_BATCH |
109 SNDRV_PCM_INFO_INTERLEAVED |
110 SNDRV_PCM_INFO_BLOCK_TRANSFER,
111 .formats = AMDTP_OUT_PCM_FORMAT_BITS,
112 .channels_min = 2,
113 .channels_max = 2,
114 .buffer_bytes_max = 4 * 1024 * 1024,
115 .period_bytes_min = 1,
116 .period_bytes_max = UINT_MAX,
117 .periods_min = 1,
118 .periods_max = UINT_MAX,
119 };
8832c5a7 120 struct snd_oxfw *oxfw = substream->private_data;
31ef9134
CL
121 struct snd_pcm_runtime *runtime = substream->runtime;
122 int err;
123
124 runtime->hw = hardware;
125
8832c5a7 126 err = oxfw->device_info->pcm_constraints(runtime);
31ef9134
CL
127 if (err < 0)
128 return err;
129 err = snd_pcm_limit_hw_rates(runtime);
130 if (err < 0)
131 return err;
132
8832c5a7 133 err = amdtp_stream_add_pcm_hw_constraints(&oxfw->rx_stream, runtime);
31ef9134
CL
134 if (err < 0)
135 return err;
136
137 return 0;
138}
139
8832c5a7 140static int oxfw_close(struct snd_pcm_substream *substream)
31ef9134
CL
141{
142 return 0;
143}
144
8832c5a7 145static int oxfw_hw_params(struct snd_pcm_substream *substream,
31ef9134
CL
146 struct snd_pcm_hw_params *hw_params)
147{
8832c5a7 148 struct snd_oxfw *oxfw = substream->private_data;
31ef9134
CL
149 int err;
150
8832c5a7 151 mutex_lock(&oxfw->mutex);
e2786ca6
TS
152
153 snd_oxfw_stream_stop_simplex(oxfw);
31ef9134
CL
154
155 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
156 params_buffer_bytes(hw_params));
157 if (err < 0)
158 goto error;
159
8832c5a7 160 amdtp_stream_set_parameters(&oxfw->rx_stream,
be4a2894
TS
161 params_rate(hw_params),
162 params_channels(hw_params),
163 0);
31ef9134 164
8832c5a7 165 amdtp_stream_set_pcm_format(&oxfw->rx_stream,
be4a2894 166 params_format(hw_params));
31ef9134 167
8832c5a7 168 err = avc_general_set_sig_fmt(oxfw->unit, params_rate(hw_params),
1017abed
TS
169 AVC_GENERAL_PLUG_DIR_IN, 0);
170 if (err < 0) {
8832c5a7 171 dev_err(&oxfw->unit->device, "failed to set sample rate\n");
31ef9134 172 goto err_buffer;
1017abed 173 }
31ef9134
CL
174
175 return 0;
176
177err_buffer:
178 snd_pcm_lib_free_vmalloc_buffer(substream);
179error:
e2786ca6 180 mutex_unlock(&oxfw->mutex);
31ef9134
CL
181 return err;
182}
183
8832c5a7 184static int oxfw_hw_free(struct snd_pcm_substream *substream)
31ef9134 185{
8832c5a7 186 struct snd_oxfw *oxfw = substream->private_data;
31ef9134 187
8832c5a7 188 mutex_lock(&oxfw->mutex);
e2786ca6 189 snd_oxfw_stream_stop_simplex(oxfw);
8832c5a7 190 mutex_unlock(&oxfw->mutex);
31ef9134
CL
191
192 return snd_pcm_lib_free_vmalloc_buffer(substream);
193}
194
8832c5a7 195static int oxfw_prepare(struct snd_pcm_substream *substream)
31ef9134 196{
8832c5a7 197 struct snd_oxfw *oxfw = substream->private_data;
31ef9134
CL
198 int err;
199
8832c5a7 200 mutex_lock(&oxfw->mutex);
31ef9134 201
e2786ca6 202 snd_oxfw_stream_stop_simplex(oxfw);
31ef9134 203
e2786ca6
TS
204 err = snd_oxfw_stream_start_simplex(oxfw);
205 if (err < 0)
206 goto end;
31ef9134 207
8832c5a7 208 amdtp_stream_pcm_prepare(&oxfw->rx_stream);
e2786ca6 209end:
8832c5a7 210 mutex_unlock(&oxfw->mutex);
31ef9134
CL
211 return err;
212}
213
8832c5a7 214static int oxfw_trigger(struct snd_pcm_substream *substream, int cmd)
31ef9134 215{
8832c5a7 216 struct snd_oxfw *oxfw = substream->private_data;
31ef9134
CL
217 struct snd_pcm_substream *pcm;
218
219 switch (cmd) {
220 case SNDRV_PCM_TRIGGER_START:
221 pcm = substream;
222 break;
223 case SNDRV_PCM_TRIGGER_STOP:
224 pcm = NULL;
225 break;
226 default:
227 return -EINVAL;
228 }
8832c5a7 229 amdtp_stream_pcm_trigger(&oxfw->rx_stream, pcm);
31ef9134
CL
230 return 0;
231}
232
8832c5a7 233static snd_pcm_uframes_t oxfw_pointer(struct snd_pcm_substream *substream)
31ef9134 234{
8832c5a7 235 struct snd_oxfw *oxfw = substream->private_data;
31ef9134 236
8832c5a7 237 return amdtp_stream_pcm_pointer(&oxfw->rx_stream);
31ef9134
CL
238}
239
8832c5a7 240static int oxfw_create_pcm(struct snd_oxfw *oxfw)
31ef9134
CL
241{
242 static struct snd_pcm_ops ops = {
8832c5a7
TS
243 .open = oxfw_open,
244 .close = oxfw_close,
31ef9134 245 .ioctl = snd_pcm_lib_ioctl,
8832c5a7
TS
246 .hw_params = oxfw_hw_params,
247 .hw_free = oxfw_hw_free,
248 .prepare = oxfw_prepare,
249 .trigger = oxfw_trigger,
250 .pointer = oxfw_pointer,
31ef9134
CL
251 .page = snd_pcm_lib_get_vmalloc_page,
252 .mmap = snd_pcm_lib_mmap_vmalloc,
253 };
254 struct snd_pcm *pcm;
255 int err;
256
8832c5a7 257 err = snd_pcm_new(oxfw->card, "OXFW", 0, 1, 0, &pcm);
31ef9134
CL
258 if (err < 0)
259 return err;
8832c5a7
TS
260 pcm->private_data = oxfw;
261 strcpy(pcm->name, oxfw->device_info->short_name);
b6c44f41 262 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops);
31ef9134
CL
263 return 0;
264}
265
266enum control_action { CTL_READ, CTL_WRITE };
267enum control_attribute {
268 CTL_MIN = 0x02,
269 CTL_MAX = 0x03,
270 CTL_CURRENT = 0x10,
271};
272
8832c5a7 273static int oxfw_mute_command(struct snd_oxfw *oxfw, bool *value,
31ef9134
CL
274 enum control_action action)
275{
276 u8 *buf;
277 u8 response_ok;
278 int err;
279
280 buf = kmalloc(11, GFP_KERNEL);
281 if (!buf)
282 return -ENOMEM;
283
284 if (action == CTL_READ) {
285 buf[0] = 0x01; /* AV/C, STATUS */
286 response_ok = 0x0c; /* STABLE */
287 } else {
288 buf[0] = 0x00; /* AV/C, CONTROL */
289 response_ok = 0x09; /* ACCEPTED */
290 }
291 buf[1] = 0x08; /* audio unit 0 */
292 buf[2] = 0xb8; /* FUNCTION BLOCK */
293 buf[3] = 0x81; /* function block type: feature */
8832c5a7 294 buf[4] = oxfw->device_info->mute_fb_id; /* function block ID */
31ef9134
CL
295 buf[5] = 0x10; /* control attribute: current */
296 buf[6] = 0x02; /* selector length */
297 buf[7] = 0x00; /* audio channel number */
298 buf[8] = 0x01; /* control selector: mute */
299 buf[9] = 0x01; /* control data length */
300 if (action == CTL_READ)
301 buf[10] = 0xff;
302 else
303 buf[10] = *value ? 0x70 : 0x60;
304
8832c5a7 305 err = fcp_avc_transaction(oxfw->unit, buf, 11, buf, 11, 0x3fe);
31ef9134
CL
306 if (err < 0)
307 goto error;
308 if (err < 11) {
8832c5a7 309 dev_err(&oxfw->unit->device, "short FCP response\n");
31ef9134
CL
310 err = -EIO;
311 goto error;
312 }
313 if (buf[0] != response_ok) {
8832c5a7 314 dev_err(&oxfw->unit->device, "mute command failed\n");
31ef9134
CL
315 err = -EIO;
316 goto error;
317 }
318 if (action == CTL_READ)
319 *value = buf[10] == 0x70;
320
321 err = 0;
322
323error:
324 kfree(buf);
325
326 return err;
327}
328
8832c5a7 329static int oxfw_volume_command(struct snd_oxfw *oxfw, s16 *value,
31ef9134
CL
330 unsigned int channel,
331 enum control_attribute attribute,
332 enum control_action action)
333{
334 u8 *buf;
335 u8 response_ok;
336 int err;
337
338 buf = kmalloc(12, GFP_KERNEL);
339 if (!buf)
340 return -ENOMEM;
341
342 if (action == CTL_READ) {
343 buf[0] = 0x01; /* AV/C, STATUS */
344 response_ok = 0x0c; /* STABLE */
345 } else {
346 buf[0] = 0x00; /* AV/C, CONTROL */
347 response_ok = 0x09; /* ACCEPTED */
348 }
349 buf[1] = 0x08; /* audio unit 0 */
350 buf[2] = 0xb8; /* FUNCTION BLOCK */
351 buf[3] = 0x81; /* function block type: feature */
8832c5a7 352 buf[4] = oxfw->device_info->volume_fb_id; /* function block ID */
31ef9134
CL
353 buf[5] = attribute; /* control attribute */
354 buf[6] = 0x02; /* selector length */
355 buf[7] = channel; /* audio channel number */
356 buf[8] = 0x02; /* control selector: volume */
357 buf[9] = 0x02; /* control data length */
358 if (action == CTL_READ) {
359 buf[10] = 0xff;
360 buf[11] = 0xff;
361 } else {
362 buf[10] = *value >> 8;
363 buf[11] = *value;
364 }
365
8832c5a7 366 err = fcp_avc_transaction(oxfw->unit, buf, 12, buf, 12, 0x3fe);
31ef9134
CL
367 if (err < 0)
368 goto error;
369 if (err < 12) {
8832c5a7 370 dev_err(&oxfw->unit->device, "short FCP response\n");
31ef9134
CL
371 err = -EIO;
372 goto error;
373 }
374 if (buf[0] != response_ok) {
8832c5a7 375 dev_err(&oxfw->unit->device, "volume command failed\n");
31ef9134
CL
376 err = -EIO;
377 goto error;
378 }
379 if (action == CTL_READ)
380 *value = (buf[10] << 8) | buf[11];
381
382 err = 0;
383
384error:
385 kfree(buf);
386
387 return err;
388}
389
8832c5a7 390static int oxfw_mute_get(struct snd_kcontrol *control,
31ef9134
CL
391 struct snd_ctl_elem_value *value)
392{
8832c5a7 393 struct snd_oxfw *oxfw = control->private_data;
31ef9134 394
8832c5a7 395 value->value.integer.value[0] = !oxfw->mute;
31ef9134
CL
396
397 return 0;
398}
399
8832c5a7 400static int oxfw_mute_put(struct snd_kcontrol *control,
31ef9134
CL
401 struct snd_ctl_elem_value *value)
402{
8832c5a7 403 struct snd_oxfw *oxfw = control->private_data;
31ef9134
CL
404 bool mute;
405 int err;
406
407 mute = !value->value.integer.value[0];
408
8832c5a7 409 if (mute == oxfw->mute)
31ef9134
CL
410 return 0;
411
8832c5a7 412 err = oxfw_mute_command(oxfw, &mute, CTL_WRITE);
31ef9134
CL
413 if (err < 0)
414 return err;
8832c5a7 415 oxfw->mute = mute;
31ef9134
CL
416
417 return 1;
418}
419
8832c5a7 420static int oxfw_volume_info(struct snd_kcontrol *control,
31ef9134
CL
421 struct snd_ctl_elem_info *info)
422{
8832c5a7 423 struct snd_oxfw *oxfw = control->private_data;
31ef9134
CL
424
425 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
8832c5a7
TS
426 info->count = oxfw->device_info->mixer_channels;
427 info->value.integer.min = oxfw->volume_min;
428 info->value.integer.max = oxfw->volume_max;
31ef9134
CL
429
430 return 0;
431}
432
433static const u8 channel_map[6] = { 0, 1, 4, 5, 2, 3 };
434
8832c5a7 435static int oxfw_volume_get(struct snd_kcontrol *control,
31ef9134
CL
436 struct snd_ctl_elem_value *value)
437{
8832c5a7 438 struct snd_oxfw *oxfw = control->private_data;
31ef9134
CL
439 unsigned int i;
440
8832c5a7
TS
441 for (i = 0; i < oxfw->device_info->mixer_channels; ++i)
442 value->value.integer.value[channel_map[i]] = oxfw->volume[i];
31ef9134
CL
443
444 return 0;
445}
446
8832c5a7 447static int oxfw_volume_put(struct snd_kcontrol *control,
31ef9134
CL
448 struct snd_ctl_elem_value *value)
449{
8832c5a7 450 struct snd_oxfw *oxfw = control->private_data;
31ef9134
CL
451 unsigned int i, changed_channels;
452 bool equal_values = true;
453 s16 volume;
454 int err;
455
8832c5a7
TS
456 for (i = 0; i < oxfw->device_info->mixer_channels; ++i) {
457 if (value->value.integer.value[i] < oxfw->volume_min ||
458 value->value.integer.value[i] > oxfw->volume_max)
31ef9134
CL
459 return -EINVAL;
460 if (value->value.integer.value[i] !=
461 value->value.integer.value[0])
462 equal_values = false;
463 }
464
465 changed_channels = 0;
8832c5a7 466 for (i = 0; i < oxfw->device_info->mixer_channels; ++i)
31ef9134 467 if (value->value.integer.value[channel_map[i]] !=
8832c5a7 468 oxfw->volume[i])
31ef9134
CL
469 changed_channels |= 1 << (i + 1);
470
471 if (equal_values && changed_channels != 0)
472 changed_channels = 1 << 0;
473
8832c5a7 474 for (i = 0; i <= oxfw->device_info->mixer_channels; ++i) {
31ef9134
CL
475 volume = value->value.integer.value[channel_map[i ? i - 1 : 0]];
476 if (changed_channels & (1 << i)) {
8832c5a7 477 err = oxfw_volume_command(oxfw, &volume, i,
31ef9134
CL
478 CTL_CURRENT, CTL_WRITE);
479 if (err < 0)
480 return err;
481 }
482 if (i > 0)
8832c5a7 483 oxfw->volume[i - 1] = volume;
31ef9134
CL
484 }
485
486 return changed_channels != 0;
487}
488
8832c5a7 489static int oxfw_create_mixer(struct snd_oxfw *oxfw)
31ef9134
CL
490{
491 static const struct snd_kcontrol_new controls[] = {
492 {
493 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
494 .name = "PCM Playback Switch",
495 .info = snd_ctl_boolean_mono_info,
8832c5a7
TS
496 .get = oxfw_mute_get,
497 .put = oxfw_mute_put,
31ef9134
CL
498 },
499 {
500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
501 .name = "PCM Playback Volume",
8832c5a7
TS
502 .info = oxfw_volume_info,
503 .get = oxfw_volume_get,
504 .put = oxfw_volume_put,
31ef9134
CL
505 },
506 };
507 unsigned int i, first_ch;
508 int err;
509
8832c5a7 510 err = oxfw_volume_command(oxfw, &oxfw->volume_min,
31ef9134
CL
511 0, CTL_MIN, CTL_READ);
512 if (err < 0)
513 return err;
8832c5a7 514 err = oxfw_volume_command(oxfw, &oxfw->volume_max,
31ef9134
CL
515 0, CTL_MAX, CTL_READ);
516 if (err < 0)
517 return err;
518
8832c5a7 519 err = oxfw_mute_command(oxfw, &oxfw->mute, CTL_READ);
31ef9134
CL
520 if (err < 0)
521 return err;
522
8832c5a7
TS
523 first_ch = oxfw->device_info->mixer_channels == 1 ? 0 : 1;
524 for (i = 0; i < oxfw->device_info->mixer_channels; ++i) {
525 err = oxfw_volume_command(oxfw, &oxfw->volume[i],
31ef9134
CL
526 first_ch + i, CTL_CURRENT, CTL_READ);
527 if (err < 0)
528 return err;
529 }
530
531 for (i = 0; i < ARRAY_SIZE(controls); ++i) {
8832c5a7
TS
532 err = snd_ctl_add(oxfw->card,
533 snd_ctl_new1(&controls[i], oxfw));
31ef9134
CL
534 if (err < 0)
535 return err;
536 }
537
538 return 0;
539}
540
8832c5a7 541static u32 oxfw_read_firmware_version(struct fw_unit *unit)
31ef9134
CL
542{
543 __be32 data;
544 int err;
545
546 err = snd_fw_transaction(unit, TCODE_READ_QUADLET_REQUEST,
1b70485f 547 OXFORD_FIRMWARE_ID_ADDRESS, &data, 4, 0);
31ef9134
CL
548 return err >= 0 ? be32_to_cpu(data) : 0;
549}
550
8832c5a7 551static void oxfw_card_free(struct snd_card *card)
31ef9134 552{
8832c5a7 553 struct snd_oxfw *oxfw = card->private_data;
31ef9134 554
8832c5a7 555 mutex_destroy(&oxfw->mutex);
31ef9134
CL
556}
557
8832c5a7 558static int oxfw_probe(struct fw_unit *unit,
94a87157 559 const struct ieee1394_device_id *id)
31ef9134 560{
31ef9134
CL
561 struct fw_device *fw_dev = fw_parent_device(unit);
562 struct snd_card *card;
8832c5a7 563 struct snd_oxfw *oxfw;
31ef9134
CL
564 u32 firmware;
565 int err;
566
06b45f00 567 err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
8832c5a7 568 sizeof(*oxfw), &card);
31ef9134
CL
569 if (err < 0)
570 return err;
31ef9134 571
e2786ca6 572 card->private_free = oxfw_card_free;
8832c5a7
TS
573 oxfw = card->private_data;
574 oxfw->card = card;
575 mutex_init(&oxfw->mutex);
e2786ca6 576 oxfw->unit = unit;
8832c5a7 577 oxfw->device_info = (const struct device_info *)id->driver_data;
31ef9134 578
8832c5a7
TS
579 strcpy(card->driver, oxfw->device_info->driver_name);
580 strcpy(card->shortname, oxfw->device_info->short_name);
581 firmware = oxfw_read_firmware_version(unit);
31ef9134
CL
582 snprintf(card->longname, sizeof(card->longname),
583 "%s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
8832c5a7 584 oxfw->device_info->long_name,
31ef9134
CL
585 firmware >> 20, firmware & 0xffff,
586 fw_dev->config_rom[3], fw_dev->config_rom[4],
587 dev_name(&unit->device), 100 << fw_dev->max_speed);
8832c5a7 588 strcpy(card->mixername, "OXFW");
31ef9134 589
8832c5a7 590 err = oxfw_create_pcm(oxfw);
31ef9134
CL
591 if (err < 0)
592 goto error;
593
8832c5a7 594 err = oxfw_create_mixer(oxfw);
31ef9134
CL
595 if (err < 0)
596 goto error;
597
e2786ca6 598 err = snd_oxfw_stream_init_simplex(oxfw);
31ef9134
CL
599 if (err < 0)
600 goto error;
601
e2786ca6
TS
602 err = snd_card_register(card);
603 if (err < 0) {
604 snd_oxfw_stream_destroy_simplex(oxfw);
605 goto error;
606 }
8832c5a7 607 dev_set_drvdata(&unit->device, oxfw);
31ef9134
CL
608
609 return 0;
31ef9134
CL
610error:
611 snd_card_free(card);
612 return err;
613}
614
8832c5a7 615static void oxfw_bus_reset(struct fw_unit *unit)
31ef9134 616{
8832c5a7 617 struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
31ef9134 618
8832c5a7 619 fcp_bus_reset(oxfw->unit);
31ef9134 620
e2786ca6
TS
621 mutex_lock(&oxfw->mutex);
622 snd_oxfw_stream_update_simplex(oxfw);
623 mutex_unlock(&oxfw->mutex);
31ef9134
CL
624}
625
8832c5a7 626static void oxfw_remove(struct fw_unit *unit)
94a87157 627{
8832c5a7 628 struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device);
94a87157 629
8832c5a7 630 snd_card_disconnect(oxfw->card);
94a87157 631
e2786ca6 632 snd_oxfw_stream_destroy_simplex(oxfw);
94a87157 633
8832c5a7 634 snd_card_free_when_closed(oxfw->card);
94a87157
SR
635}
636
637static const struct device_info griffin_firewave = {
638 .driver_name = "FireWave",
639 .short_name = "FireWave",
640 .long_name = "Griffin FireWave Surround",
641 .pcm_constraints = firewave_constraints,
642 .mixer_channels = 6,
643 .mute_fb_id = 0x01,
644 .volume_fb_id = 0x02,
645};
646
647static const struct device_info lacie_speakers = {
648 .driver_name = "FWSpeakers",
649 .short_name = "FireWire Speakers",
650 .long_name = "LaCie FireWire Speakers",
651 .pcm_constraints = lacie_speakers_constraints,
652 .mixer_channels = 1,
653 .mute_fb_id = 0x01,
654 .volume_fb_id = 0x01,
655};
656
8832c5a7 657static const struct ieee1394_device_id oxfw_id_table[] = {
31ef9134
CL
658 {
659 .match_flags = IEEE1394_MATCH_VENDOR_ID |
660 IEEE1394_MATCH_MODEL_ID |
661 IEEE1394_MATCH_SPECIFIER_ID |
662 IEEE1394_MATCH_VERSION,
663 .vendor_id = VENDOR_GRIFFIN,
664 .model_id = 0x00f970,
665 .specifier_id = SPECIFIER_1394TA,
666 .version = VERSION_AVC,
94a87157 667 .driver_data = (kernel_ulong_t)&griffin_firewave,
31ef9134
CL
668 },
669 {
670 .match_flags = IEEE1394_MATCH_VENDOR_ID |
671 IEEE1394_MATCH_MODEL_ID |
672 IEEE1394_MATCH_SPECIFIER_ID |
673 IEEE1394_MATCH_VERSION,
674 .vendor_id = VENDOR_LACIE,
675 .model_id = 0x00f970,
676 .specifier_id = SPECIFIER_1394TA,
677 .version = VERSION_AVC,
94a87157 678 .driver_data = (kernel_ulong_t)&lacie_speakers,
31ef9134
CL
679 },
680 { }
681};
8832c5a7 682MODULE_DEVICE_TABLE(ieee1394, oxfw_id_table);
31ef9134 683
8832c5a7 684static struct fw_driver oxfw_driver = {
31ef9134
CL
685 .driver = {
686 .owner = THIS_MODULE,
687 .name = KBUILD_MODNAME,
688 .bus = &fw_bus_type,
31ef9134 689 },
8832c5a7
TS
690 .probe = oxfw_probe,
691 .update = oxfw_bus_reset,
692 .remove = oxfw_remove,
693 .id_table = oxfw_id_table,
31ef9134
CL
694};
695
8832c5a7 696static int __init snd_oxfw_init(void)
31ef9134 697{
8832c5a7 698 return driver_register(&oxfw_driver.driver);
31ef9134
CL
699}
700
8832c5a7 701static void __exit snd_oxfw_exit(void)
31ef9134 702{
8832c5a7 703 driver_unregister(&oxfw_driver.driver);
31ef9134
CL
704}
705
8832c5a7
TS
706module_init(snd_oxfw_init);
707module_exit(snd_oxfw_exit);
This page took 0.226363 seconds and 5 git commands to generate.