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