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 | |
| 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 | 13f3a46 | 2015-09-20 21:18:55 +0900 | [diff] [blame] | 52 | bool wrong_dbs; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 53 | bool has_output; |
| 54 | u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 55 | u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES]; |
| 56 | bool assumed; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 57 | struct cmp_connection out_conn; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 58 | struct cmp_connection in_conn; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 59 | struct amdtp_stream tx_stream; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 60 | struct amdtp_stream rx_stream; |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 61 | unsigned int capture_substreams; |
| 62 | unsigned int playback_substreams; |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 63 | |
Takashi Sakamoto | 05588d3 | 2014-12-09 00:10:48 +0900 | [diff] [blame] | 64 | unsigned int midi_input_ports; |
| 65 | unsigned int midi_output_ports; |
| 66 | |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 67 | bool mute; |
| 68 | s16 volume[6]; |
| 69 | s16 volume_min; |
| 70 | s16 volume_max; |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 71 | |
| 72 | int dev_lock_count; |
| 73 | bool dev_lock_changed; |
| 74 | wait_queue_head_t hwdep_wait; |
Takashi Sakamoto | e2786ca | 2014-11-29 00:59:27 +0900 | [diff] [blame] | 75 | }; |
| 76 | |
Takashi Sakamoto | 5b59d809 | 2014-12-09 00:10:41 +0900 | [diff] [blame] | 77 | /* |
| 78 | * AV/C Stream Format Information Specification 1.1 Working Draft |
| 79 | * (Apr 2005, 1394TA) |
| 80 | */ |
| 81 | int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir, |
| 82 | unsigned int pid, u8 *format, unsigned int len); |
| 83 | int avc_stream_get_format(struct fw_unit *unit, |
| 84 | enum avc_general_plug_dir dir, unsigned int pid, |
| 85 | u8 *buf, unsigned int *len, unsigned int eid); |
| 86 | static inline int |
| 87 | avc_stream_get_format_single(struct fw_unit *unit, |
| 88 | enum avc_general_plug_dir dir, unsigned int pid, |
| 89 | u8 *buf, unsigned int *len) |
| 90 | { |
| 91 | return avc_stream_get_format(unit, dir, pid, buf, len, 0xff); |
| 92 | } |
| 93 | static inline int |
| 94 | avc_stream_get_format_list(struct fw_unit *unit, |
| 95 | enum avc_general_plug_dir dir, unsigned int pid, |
| 96 | u8 *buf, unsigned int *len, |
| 97 | unsigned int eid) |
| 98 | { |
| 99 | return avc_stream_get_format(unit, dir, pid, buf, len, eid); |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | * AV/C Digital Interface Command Set General Specification 4.2 |
| 104 | * (Sep 2004, 1394TA) |
| 105 | */ |
| 106 | int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate, |
| 107 | enum avc_general_plug_dir dir, |
| 108 | unsigned short pid); |
| 109 | |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 110 | int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw, |
| 111 | struct amdtp_stream *stream); |
| 112 | int snd_oxfw_stream_start_simplex(struct snd_oxfw *oxfw, |
| 113 | struct amdtp_stream *stream, |
| 114 | unsigned int rate, unsigned int pcm_channels); |
| 115 | void snd_oxfw_stream_stop_simplex(struct snd_oxfw *oxfw, |
| 116 | struct amdtp_stream *stream); |
| 117 | void snd_oxfw_stream_destroy_simplex(struct snd_oxfw *oxfw, |
| 118 | struct amdtp_stream *stream); |
| 119 | void snd_oxfw_stream_update_simplex(struct snd_oxfw *oxfw, |
| 120 | struct amdtp_stream *stream); |
Takashi Sakamoto | 3713d93 | 2014-11-29 00:59:28 +0900 | [diff] [blame] | 121 | |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 122 | struct snd_oxfw_stream_formation { |
| 123 | unsigned int rate; |
| 124 | unsigned int pcm; |
| 125 | unsigned int midi; |
| 126 | }; |
| 127 | int snd_oxfw_stream_parse_format(u8 *format, |
| 128 | struct snd_oxfw_stream_formation *formation); |
| 129 | int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw, |
| 130 | enum avc_general_plug_dir dir, |
| 131 | struct snd_oxfw_stream_formation *formation); |
Takashi Sakamoto | b0ac000 | 2014-12-09 00:10:46 +0900 | [diff] [blame] | 132 | |
Takashi Sakamoto | 5cd1d3f | 2014-12-09 00:10:42 +0900 | [diff] [blame] | 133 | int snd_oxfw_stream_discover(struct snd_oxfw *oxfw); |
| 134 | |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 135 | void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw); |
| 136 | int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw); |
| 137 | void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw); |
| 138 | |
Takashi Sakamoto | 3713d93 | 2014-11-29 00:59:28 +0900 | [diff] [blame] | 139 | int snd_oxfw_create_pcm(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 31514bf | 2014-11-29 00:59:29 +0900 | [diff] [blame] | 140 | |
Takashi Sakamoto | 3c96101 | 2014-12-09 00:10:43 +0900 | [diff] [blame] | 141 | void snd_oxfw_proc_init(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 05588d3 | 2014-12-09 00:10:48 +0900 | [diff] [blame] | 142 | |
| 143 | int snd_oxfw_create_midi(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 8985f4a | 2014-12-09 00:10:49 +0900 | [diff] [blame] | 144 | |
| 145 | int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw); |
Takashi Sakamoto | 29aa09a | 2015-12-15 23:56:18 +0900 | [diff] [blame^] | 146 | |
| 147 | int snd_oxfw_add_spkr(struct snd_oxfw *oxfw); |