diff options
| author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2014-11-28 10:59:27 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2014-11-29 14:22:08 -0500 |
| commit | e2786ca648d780d106bd8abca06746eb30d15ee7 (patch) | |
| tree | f79f224d43188d2852a5341bb3b5d8c7128cb256 /sound/firewire | |
| parent | 1a4e39c2e5ca2eb494a53ecd73055562f690bca0 (diff) | |
ALSA: oxfw: Split stream functionality to a new file and add a header file
This is a help for works in followed patches.
And this commit remove 'fw_unit_get()/fw_unit_put()' because these
are called by helper functions in 'snd-firewire-lib'.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/firewire')
| -rw-r--r-- | sound/firewire/oxfw/Makefile | 2 | ||||
| -rw-r--r-- | sound/firewire/oxfw/oxfw-stream.c | 80 | ||||
| -rw-r--r-- | sound/firewire/oxfw/oxfw.c | 130 | ||||
| -rw-r--r-- | sound/firewire/oxfw/oxfw.h | 56 |
4 files changed, 159 insertions, 109 deletions
diff --git a/sound/firewire/oxfw/Makefile b/sound/firewire/oxfw/Makefile index 9ca49c0fdc40..e15c4c07b49d 100644 --- a/sound/firewire/oxfw/Makefile +++ b/sound/firewire/oxfw/Makefile | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | snd-oxfw-objs := oxfw.o | 1 | snd-oxfw-objs := oxfw-stream.o oxfw.o |
| 2 | obj-m += snd-oxfw.o | 2 | obj-m += snd-oxfw.o |
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c new file mode 100644 index 000000000000..ebd156f3e29d --- /dev/null +++ b/sound/firewire/oxfw/oxfw-stream.c | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* | ||
| 2 | * oxfw_stream.c - a part of driver for OXFW970/971 based devices | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Takashi Sakamoto | ||
| 5 | * | ||
| 6 | * Licensed under the terms of the GNU General Public License, version 2. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "oxfw.h" | ||
| 10 | |||
| 11 | int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw) | ||
| 12 | { | ||
| 13 | int err; | ||
| 14 | |||
| 15 | err = cmp_connection_init(&oxfw->in_conn, oxfw->unit, | ||
| 16 | CMP_INPUT, 0); | ||
| 17 | if (err < 0) | ||
| 18 | goto end; | ||
| 19 | |||
| 20 | err = amdtp_stream_init(&oxfw->rx_stream, oxfw->unit, | ||
| 21 | AMDTP_OUT_STREAM, CIP_NONBLOCKING); | ||
| 22 | if (err < 0) { | ||
| 23 | amdtp_stream_destroy(&oxfw->rx_stream); | ||
| 24 | cmp_connection_destroy(&oxfw->in_conn); | ||
| 25 | } | ||
| 26 | end: | ||
| 27 | return err; | ||
| 28 | } | ||
| 29 | |||
| 30 | static void stop_stream(struct snd_oxfw *oxfw) | ||
| 31 | { | ||
| 32 | amdtp_stream_pcm_abort(&oxfw->rx_stream); | ||
| 33 | amdtp_stream_stop(&oxfw->rx_stream); | ||
| 34 | cmp_connection_break(&oxfw->in_conn); | ||
| 35 | } | ||
| 36 | |||
| 37 | int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw) | ||
| 38 | { | ||
| 39 | int err = 0; | ||
| 40 | |||
| 41 | if (amdtp_streaming_error(&oxfw->rx_stream)) | ||
| 42 | stop_stream(oxfw); | ||
| 43 | |||
| 44 | if (amdtp_stream_running(&oxfw->rx_stream)) | ||
| 45 | goto end; | ||
| 46 | |||
| 47 | err = cmp_connection_establish(&oxfw->in_conn, | ||
| 48 | amdtp_stream_get_max_payload(&oxfw->rx_stream)); | ||
| 49 | if (err < 0) | ||
| 50 | goto end; | ||
| 51 | |||
| 52 | err = amdtp_stream_start(&oxfw->rx_stream, | ||
| 53 | oxfw->in_conn.resources.channel, | ||
| 54 | oxfw->in_conn.speed); | ||
| 55 | if (err < 0) | ||
| 56 | stop_stream(oxfw); | ||
| 57 | end: | ||
| 58 | return err; | ||
| 59 | } | ||
| 60 | |||
| 61 | void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw) | ||
| 62 | { | ||
| 63 | stop_stream(oxfw); | ||
| 64 | } | ||
| 65 | |||
| 66 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw) | ||
| 67 | { | ||
| 68 | stop_stream(oxfw); | ||
| 69 | |||
| 70 | amdtp_stream_destroy(&oxfw->rx_stream); | ||
| 71 | cmp_connection_destroy(&oxfw->in_conn); | ||
| 72 | } | ||
| 73 | |||
| 74 | void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw) | ||
| 75 | { | ||
| 76 | if (cmp_connection_update(&oxfw->in_conn) < 0) | ||
| 77 | stop_stream(oxfw); | ||
| 78 | else | ||
| 79 | amdtp_stream_update(&oxfw->rx_stream); | ||
| 80 | } | ||
diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index 55c687ef3247..40556677ea07 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c | |||
| @@ -5,22 +5,7 @@ | |||
| 5 | * Licensed under the terms of the GNU General Public License, version 2. | 5 | * Licensed under the terms of the GNU General Public License, version 2. |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #include <linux/device.h> | 8 | #include "oxfw.h" |
| 9 | #include <linux/firewire.h> | ||
| 10 | #include <linux/firewire-constants.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/mod_devicetable.h> | ||
| 13 | #include <linux/mutex.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | #include <sound/control.h> | ||
| 16 | #include <sound/core.h> | ||
| 17 | #include <sound/initval.h> | ||
| 18 | #include <sound/pcm.h> | ||
| 19 | #include <sound/pcm_params.h> | ||
| 20 | #include "../cmp.h" | ||
| 21 | #include "../fcp.h" | ||
| 22 | #include "../amdtp.h" | ||
| 23 | #include "../lib.h" | ||
| 24 | 9 | ||
| 25 | #define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000) | 10 | #define OXFORD_FIRMWARE_ID_ADDRESS (CSR_REGISTER_BASE + 0x50000) |
| 26 | /* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */ | 11 | /* 0x970?vvvv or 0x971?vvvv, where vvvv = firmware version */ |
| @@ -35,29 +20,6 @@ | |||
| 35 | #define SPECIFIER_1394TA 0x00a02d | 20 | #define SPECIFIER_1394TA 0x00a02d |
| 36 | #define VERSION_AVC 0x010001 | 21 | #define VERSION_AVC 0x010001 |
| 37 | 22 | ||
| 38 | struct device_info { | ||
| 39 | const char *driver_name; | ||
| 40 | const char *short_name; | ||
| 41 | const char *long_name; | ||
| 42 | int (*pcm_constraints)(struct snd_pcm_runtime *runtime); | ||
| 43 | unsigned int mixer_channels; | ||
| 44 | u8 mute_fb_id; | ||
| 45 | u8 volume_fb_id; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct snd_oxfw { | ||
| 49 | struct snd_card *card; | ||
| 50 | struct fw_unit *unit; | ||
| 51 | const struct device_info *device_info; | ||
| 52 | struct mutex mutex; | ||
| 53 | struct cmp_connection in_conn; | ||
| 54 | struct amdtp_stream rx_stream; | ||
| 55 | bool mute; | ||
| 56 | s16 volume[6]; | ||
| 57 | s16 volume_min; | ||
| 58 | s16 volume_max; | ||
| 59 | }; | ||
| 60 | |||
| 61 | MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver"); | 23 | MODULE_DESCRIPTION("Oxford Semiconductor FW970/971 driver"); |
| 62 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 24 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
| 63 | MODULE_LICENSE("GPL v2"); | 25 | MODULE_LICENSE("GPL v2"); |
| @@ -180,14 +142,6 @@ static int oxfw_close(struct snd_pcm_substream *substream) | |||
| 180 | return 0; | 142 | return 0; |
| 181 | } | 143 | } |
| 182 | 144 | ||
| 183 | static void oxfw_stop_stream(struct snd_oxfw *oxfw) | ||
| 184 | { | ||
| 185 | if (amdtp_stream_running(&oxfw->rx_stream)) { | ||
| 186 | amdtp_stream_stop(&oxfw->rx_stream); | ||
| 187 | cmp_connection_break(&oxfw->in_conn); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | static int oxfw_hw_params(struct snd_pcm_substream *substream, | 145 | static int oxfw_hw_params(struct snd_pcm_substream *substream, |
| 192 | struct snd_pcm_hw_params *hw_params) | 146 | struct snd_pcm_hw_params *hw_params) |
| 193 | { | 147 | { |
| @@ -195,8 +149,8 @@ static int oxfw_hw_params(struct snd_pcm_substream *substream, | |||
| 195 | int err; | 149 | int err; |
| 196 | 150 | ||
| 197 | mutex_lock(&oxfw->mutex); | 151 | mutex_lock(&oxfw->mutex); |
| 198 | oxfw_stop_stream(oxfw); | 152 | |
| 199 | mutex_unlock(&oxfw->mutex); | 153 | snd_oxfw_stream_stop_simplex(oxfw); |
| 200 | 154 | ||
| 201 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 155 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, |
| 202 | params_buffer_bytes(hw_params)); | 156 | params_buffer_bytes(hw_params)); |
| @@ -223,6 +177,7 @@ static int oxfw_hw_params(struct snd_pcm_substream *substream, | |||
| 223 | err_buffer: | 177 | err_buffer: |
| 224 | snd_pcm_lib_free_vmalloc_buffer(substream); | 178 | snd_pcm_lib_free_vmalloc_buffer(substream); |
| 225 | error: | 179 | error: |
| 180 | mutex_unlock(&oxfw->mutex); | ||
| 226 | return err; | 181 | return err; |
| 227 | } | 182 | } |
| 228 | 183 | ||
| @@ -231,7 +186,7 @@ static int oxfw_hw_free(struct snd_pcm_substream *substream) | |||
| 231 | struct snd_oxfw *oxfw = substream->private_data; | 186 | struct snd_oxfw *oxfw = substream->private_data; |
| 232 | 187 | ||
| 233 | mutex_lock(&oxfw->mutex); | 188 | mutex_lock(&oxfw->mutex); |
| 234 | oxfw_stop_stream(oxfw); | 189 | snd_oxfw_stream_stop_simplex(oxfw); |
| 235 | mutex_unlock(&oxfw->mutex); | 190 | mutex_unlock(&oxfw->mutex); |
| 236 | 191 | ||
| 237 | return snd_pcm_lib_free_vmalloc_buffer(substream); | 192 | return snd_pcm_lib_free_vmalloc_buffer(substream); |
| @@ -244,33 +199,15 @@ static int oxfw_prepare(struct snd_pcm_substream *substream) | |||
| 244 | 199 | ||
| 245 | mutex_lock(&oxfw->mutex); | 200 | mutex_lock(&oxfw->mutex); |
| 246 | 201 | ||
| 247 | if (amdtp_streaming_error(&oxfw->rx_stream)) | 202 | snd_oxfw_stream_stop_simplex(oxfw); |
| 248 | oxfw_stop_stream(oxfw); | ||
| 249 | |||
| 250 | if (!amdtp_stream_running(&oxfw->rx_stream)) { | ||
| 251 | err = cmp_connection_establish(&oxfw->in_conn, | ||
| 252 | amdtp_stream_get_max_payload(&oxfw->rx_stream)); | ||
| 253 | if (err < 0) | ||
| 254 | goto err_mutex; | ||
| 255 | 203 | ||
| 256 | err = amdtp_stream_start(&oxfw->rx_stream, | 204 | err = snd_oxfw_stream_start_simplex(oxfw); |
| 257 | oxfw->in_conn.resources.channel, | 205 | if (err < 0) |
| 258 | oxfw->in_conn.speed); | 206 | goto end; |
| 259 | if (err < 0) | ||
| 260 | goto err_connection; | ||
| 261 | } | ||
| 262 | |||
| 263 | mutex_unlock(&oxfw->mutex); | ||
| 264 | 207 | ||
| 265 | amdtp_stream_pcm_prepare(&oxfw->rx_stream); | 208 | amdtp_stream_pcm_prepare(&oxfw->rx_stream); |
| 266 | 209 | end: | |
| 267 | return 0; | ||
| 268 | |||
| 269 | err_connection: | ||
| 270 | cmp_connection_break(&oxfw->in_conn); | ||
| 271 | err_mutex: | ||
| 272 | mutex_unlock(&oxfw->mutex); | 210 | mutex_unlock(&oxfw->mutex); |
| 273 | |||
| 274 | return err; | 211 | return err; |
| 275 | } | 212 | } |
| 276 | 213 | ||
| @@ -615,9 +552,6 @@ static void oxfw_card_free(struct snd_card *card) | |||
| 615 | { | 552 | { |
| 616 | struct snd_oxfw *oxfw = card->private_data; | 553 | struct snd_oxfw *oxfw = card->private_data; |
| 617 | 554 | ||
| 618 | amdtp_stream_destroy(&oxfw->rx_stream); | ||
| 619 | cmp_connection_destroy(&oxfw->in_conn); | ||
| 620 | fw_unit_put(oxfw->unit); | ||
| 621 | mutex_destroy(&oxfw->mutex); | 555 | mutex_destroy(&oxfw->mutex); |
| 622 | } | 556 | } |
| 623 | 557 | ||
| @@ -635,23 +569,13 @@ static int oxfw_probe(struct fw_unit *unit, | |||
| 635 | if (err < 0) | 569 | if (err < 0) |
| 636 | return err; | 570 | return err; |
| 637 | 571 | ||
| 572 | card->private_free = oxfw_card_free; | ||
| 638 | oxfw = card->private_data; | 573 | oxfw = card->private_data; |
| 639 | oxfw->card = card; | 574 | oxfw->card = card; |
| 640 | mutex_init(&oxfw->mutex); | 575 | mutex_init(&oxfw->mutex); |
| 641 | oxfw->unit = fw_unit_get(unit); | 576 | oxfw->unit = unit; |
| 642 | oxfw->device_info = (const struct device_info *)id->driver_data; | 577 | oxfw->device_info = (const struct device_info *)id->driver_data; |
| 643 | 578 | ||
| 644 | err = cmp_connection_init(&oxfw->in_conn, unit, CMP_INPUT, 0); | ||
| 645 | if (err < 0) | ||
| 646 | goto err_unit; | ||
| 647 | |||
| 648 | err = amdtp_stream_init(&oxfw->rx_stream, unit, AMDTP_OUT_STREAM, | ||
| 649 | CIP_NONBLOCKING); | ||
| 650 | if (err < 0) | ||
| 651 | goto err_connection; | ||
| 652 | |||
| 653 | card->private_free = oxfw_card_free; | ||
| 654 | |||
| 655 | strcpy(card->driver, oxfw->device_info->driver_name); | 579 | strcpy(card->driver, oxfw->device_info->driver_name); |
| 656 | strcpy(card->shortname, oxfw->device_info->short_name); | 580 | strcpy(card->shortname, oxfw->device_info->short_name); |
| 657 | firmware = oxfw_read_firmware_version(unit); | 581 | firmware = oxfw_read_firmware_version(unit); |
| @@ -671,19 +595,18 @@ static int oxfw_probe(struct fw_unit *unit, | |||
| 671 | if (err < 0) | 595 | if (err < 0) |
| 672 | goto error; | 596 | goto error; |
| 673 | 597 | ||
| 674 | err = snd_card_register(card); | 598 | err = snd_oxfw_stream_init_simplex(oxfw); |
| 675 | if (err < 0) | 599 | if (err < 0) |
| 676 | goto error; | 600 | goto error; |
| 677 | 601 | ||
| 602 | err = snd_card_register(card); | ||
| 603 | if (err < 0) { | ||
| 604 | snd_oxfw_stream_destroy_simplex(oxfw); | ||
| 605 | goto error; | ||
| 606 | } | ||
| 678 | dev_set_drvdata(&unit->device, oxfw); | 607 | dev_set_drvdata(&unit->device, oxfw); |
| 679 | 608 | ||
| 680 | return 0; | 609 | return 0; |
| 681 | |||
| 682 | err_connection: | ||
| 683 | cmp_connection_destroy(&oxfw->in_conn); | ||
| 684 | err_unit: | ||
| 685 | fw_unit_put(oxfw->unit); | ||
| 686 | mutex_destroy(&oxfw->mutex); | ||
| 687 | error: | 610 | error: |
| 688 | snd_card_free(card); | 611 | snd_card_free(card); |
| 689 | return err; | 612 | return err; |
| @@ -695,27 +618,18 @@ static void oxfw_bus_reset(struct fw_unit *unit) | |||
| 695 | 618 | ||
| 696 | fcp_bus_reset(oxfw->unit); | 619 | fcp_bus_reset(oxfw->unit); |
| 697 | 620 | ||
| 698 | if (cmp_connection_update(&oxfw->in_conn) < 0) { | 621 | mutex_lock(&oxfw->mutex); |
| 699 | amdtp_stream_pcm_abort(&oxfw->rx_stream); | 622 | snd_oxfw_stream_update_simplex(oxfw); |
| 700 | mutex_lock(&oxfw->mutex); | 623 | mutex_unlock(&oxfw->mutex); |
| 701 | oxfw_stop_stream(oxfw); | ||
| 702 | mutex_unlock(&oxfw->mutex); | ||
| 703 | return; | ||
| 704 | } | ||
| 705 | |||
| 706 | amdtp_stream_update(&oxfw->rx_stream); | ||
| 707 | } | 624 | } |
| 708 | 625 | ||
| 709 | static void oxfw_remove(struct fw_unit *unit) | 626 | static void oxfw_remove(struct fw_unit *unit) |
| 710 | { | 627 | { |
| 711 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); | 628 | struct snd_oxfw *oxfw = dev_get_drvdata(&unit->device); |
| 712 | 629 | ||
| 713 | amdtp_stream_pcm_abort(&oxfw->rx_stream); | ||
| 714 | snd_card_disconnect(oxfw->card); | 630 | snd_card_disconnect(oxfw->card); |
| 715 | 631 | ||
| 716 | mutex_lock(&oxfw->mutex); | 632 | snd_oxfw_stream_destroy_simplex(oxfw); |
| 717 | oxfw_stop_stream(oxfw); | ||
| 718 | mutex_unlock(&oxfw->mutex); | ||
| 719 | 633 | ||
| 720 | snd_card_free_when_closed(oxfw->card); | 634 | snd_card_free_when_closed(oxfw->card); |
| 721 | } | 635 | } |
diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h new file mode 100644 index 000000000000..e5836e02b48c --- /dev/null +++ b/sound/firewire/oxfw/oxfw.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * oxfw.h - a part of driver for OXFW970/971 based devices | ||
| 3 | * | ||
| 4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
| 5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/device.h> | ||
| 9 | #include <linux/firewire.h> | ||
| 10 | #include <linux/firewire-constants.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/mod_devicetable.h> | ||
| 13 | #include <linux/mutex.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | |||
| 16 | #include <sound/control.h> | ||
| 17 | #include <sound/core.h> | ||
| 18 | #include <sound/initval.h> | ||
| 19 | #include <sound/pcm.h> | ||
| 20 | #include <sound/pcm_params.h> | ||
| 21 | |||
| 22 | #include "../lib.h" | ||
| 23 | #include "../fcp.h" | ||
| 24 | #include "../packets-buffer.h" | ||
| 25 | #include "../iso-resources.h" | ||
| 26 | #include "../amdtp.h" | ||
| 27 | #include "../cmp.h" | ||
| 28 | |||
| 29 | struct device_info { | ||
| 30 | const char *driver_name; | ||
| 31 | const char *short_name; | ||
| 32 | const char *long_name; | ||
| 33 | int (*pcm_constraints)(struct snd_pcm_runtime *runtime); | ||
| 34 | unsigned int mixer_channels; | ||
| 35 | u8 mute_fb_id; | ||
| 36 | u8 volume_fb_id; | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct snd_oxfw { | ||
| 40 | struct snd_card *card; | ||
| 41 | struct fw_unit *unit; | ||
| 42 | const struct device_info *device_info; | ||
| 43 | struct mutex mutex; | ||
| 44 | struct cmp_connection in_conn; | ||
| 45 | struct amdtp_stream rx_stream; | ||
| 46 | bool mute; | ||
| 47 | s16 volume[6]; | ||
| 48 | s16 volume_min; | ||
| 49 | s16 volume_max; | ||
| 50 | }; | ||
| 51 | |||
| 52 | int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw); | ||
| 53 | int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw); | ||
| 54 | void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw); | ||
| 55 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw); | ||
| 56 | void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw); | ||
