Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 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> |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 15 | #include <linux/compat.h> |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 16 | |
| 17 | #include <sound/control.h> |
| 18 | #include <sound/core.h> |
| 19 | #include <sound/initval.h> |
| 20 | #include <sound/pcm.h> |
| 21 | #include <sound/pcm_params.h> |
Takashi Sakamoto | 3c96101 | 2014-12-09 00:10:43 +0900 | [diff] [blame] | 22 | #include <sound/info.h> |
Takashi Sakamoto | 05588d3 | 2014-12-09 00:10:48 +0900 | [diff] [blame] | 23 | #include <sound/rawmidi.h> |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 24 | #include <sound/firewire.h> |
| 25 | #include <sound/hwdep.h> |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 26 | |
| 27 | #include "../lib.h" |
| 28 | #include "../fcp.h" |
| 29 | #include "../packets-buffer.h" |
| 30 | #include "../iso-resources.h" |
| 31 | #include "../amdtp.h" |
| 32 | #include "../cmp.h" |
| 33 | |
| 34 | struct device_info { |
| 35 | const char *driver_name; |
Takashi Sakamoto | fec7b75 | 2014-12-09 00:10:40 +0900 | [diff] [blame] | 36 | const char *vendor_name; |
| 37 | const char *model_name; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 38 | unsigned int mixer_channels; |
| 39 | u8 mute_fb_id; |
| 40 | u8 volume_fb_id; |
| 41 | }; |
| 42 | |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 43 | /* This is an arbitrary number for convinience. */ |
| 44 | #define SND_OXFW_STREAM_FORMAT_ENTRIES 10 |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 45 | struct snd_oxfw { |
| 46 | struct snd_card *card; |
| 47 | struct fw_unit *unit; |
| 48 | const struct device_info *device_info; |
| 49 | struct mutex mutex; |
Takashi Sakamoto | 05588d3 | 2014-12-09 00:10:48 +0900 | [diff] [blame] | 50 | spinlock_t lock; |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 51 | |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 52 | bool has_output; |
| 53 | u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 54 | u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; |
| 55 | bool assumed; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 56 | struct cmp_connection out_conn; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 57 | struct cmp_connection in_conn; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 58 | struct amdtp_stream tx_stream; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 59 | struct amdtp_stream rx_stream; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 60 | unsigned int capture_substreams; |
| 61 | unsigned int playback_substreams; |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 62 | |
Takashi Sakamoto | 05588d3 | 2014-12-09 00:10:48 +0900 | [diff] [blame] | 63 | unsigned int midi_input_ports; |
| 64 | unsigned int midi_output_ports; |
| 65 | |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 66 | bool mute; |
| 67 | s16 volume[6]; |
| 68 | s16 volume_min; |
| 69 | s16 volume_max; |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 70 | |
| 71 | int dev_lock_count; |
| 72 | bool dev_lock_changed; |
| 73 | wait_queue_head_t hwdep_wait; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 74 | }; |
| 75 | |
Takashi Sakamoto | 5b59d80 | 2014-12-09 00:10:41 +0900 | [diff] [blame] | 76 | /* |
| 77 | * AV/C Stream Format Information Specification 1.1 Working Draft |
| 78 | * (Apr 2005, 1394TA) |
| 79 | */ |
| 80 | int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir, |
| 81 | unsigned int pid, u8 *format, unsigned int len); |
| 82 | int avc_stream_get_format(struct fw_unit *unit, |
| 83 | enum avc_general_plug_dir dir, unsigned int pid, |
| 84 | u8 *buf, unsigned int *len, unsigned int eid); |
| 85 | static inline int |
| 86 | avc_stream_get_format_single(struct fw_unit *unit, |
| 87 | enum avc_general_plug_dir dir, unsigned int pid, |
| 88 | u8 *buf, unsigned int *len) |
| 89 | { |
| 90 | return avc_stream_get_format(unit, dir, pid, buf, len, 0xff); |
| 91 | } |
| 92 | static inline int |
| 93 | avc_stream_get_format_list(struct fw_unit *unit, |
| 94 | enum avc_general_plug_dir dir, unsigned int pid, |
| 95 | u8 *buf, unsigned int *len, |
| 96 | unsigned int eid) |
| 97 | { |
| 98 | return avc_stream_get_format(unit, dir, pid, buf, len, eid); |
| 99 | } |
| 100 | |
| 101 | /* |
| 102 | * AV/C Digital Interface Command Set General Specification 4.2 |
| 103 | * (Sep 2004, 1394TA) |
| 104 | */ |
| 105 | int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate, |
| 106 | enum avc_general_plug_dir dir, |
| 107 | unsigned short pid); |
| 108 | |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 109 | int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw, |
| 110 | struct amdtp_stream *stream); |
| 111 | int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw, |
| 112 | struct amdtp_stream *stream, |
| 113 | unsigned int rate, unsigned int pcm_channels); |
| 114 | void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw, |
| 115 | struct amdtp_stream *stream); |
| 116 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, |
| 117 | struct amdtp_stream *stream); |
| 118 | void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw, |
| 119 | struct amdtp_stream *stream); |
Takashi Sakamoto | 3713d93 | 2014-11-29 00:59:28 +0900 | [diff] [blame] | 120 | |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 121 | struct snd_oxfw_stream_formation { |
| 122 | unsigned int rate; |
| 123 | unsigned int pcm; |
| 124 | unsigned int midi; |
| 125 | }; |
| 126 | int snd_oxfw_stream_parse_format(u8 *format, |
| 127 | struct snd_oxfw_stream_formation *formation); |
| 128 | int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw, |
| 129 | enum avc_general_plug_dir dir, |
| 130 | struct snd_oxfw_stream_formation *formation); |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 131 | |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 132 | int snd_oxfw_stream_discover(struct snd_oxfw *oxfw); |
| 133 | |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 134 | void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw); |
| 135 | int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw); |
| 136 | void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw); |
| 137 | |
Takashi Sakamoto | 3713d93 | 2014-11-29 00:59:28 +0900 | [diff] [blame] | 138 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 31514bf | 2014-11-29 00:59:29 +0900 | [diff] [blame] | 139 | |
| 140 | int snd_oxfw_create_mixer(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 3c96101 | 2014-12-09 00:10:43 +0900 | [diff] [blame] | 141 | |
| 142 | void snd_oxfw_proc_init(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 05588d3 | 2014-12-09 00:10:48 +0900 | [diff] [blame] | 143 | |
| 144 | int snd_oxfw_create_midi(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 145 | |
| 146 | int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw); |