1da607e19SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2b5b04336STakashi Sakamoto /* 3b5b04336STakashi Sakamoto * fireworks.h - a part of driver for Fireworks based devices 4b5b04336STakashi Sakamoto * 5b5b04336STakashi Sakamoto * Copyright (c) 2009-2010 Clemens Ladisch 6b5b04336STakashi Sakamoto * Copyright (c) 2013-2014 Takashi Sakamoto 7b5b04336STakashi Sakamoto */ 8b5b04336STakashi Sakamoto #ifndef SOUND_FIREWORKS_H_INCLUDED 9b5b04336STakashi Sakamoto #define SOUND_FIREWORKS_H_INCLUDED 10b5b04336STakashi Sakamoto 11b5b04336STakashi Sakamoto #include <linux/compat.h> 12b5b04336STakashi Sakamoto #include <linux/device.h> 13b5b04336STakashi Sakamoto #include <linux/firewire.h> 14b5b04336STakashi Sakamoto #include <linux/firewire-constants.h> 15b5b04336STakashi Sakamoto #include <linux/module.h> 16b5b04336STakashi Sakamoto #include <linux/mod_devicetable.h> 17b5b04336STakashi Sakamoto #include <linux/delay.h> 18b5b04336STakashi Sakamoto #include <linux/slab.h> 19174cd4b1SIngo Molnar #include <linux/sched/signal.h> 20b5b04336STakashi Sakamoto 21b5b04336STakashi Sakamoto #include <sound/core.h> 22b5b04336STakashi Sakamoto #include <sound/initval.h> 23bde8a8f2STakashi Sakamoto #include <sound/pcm.h> 246a22683eSTakashi Sakamoto #include <sound/info.h> 25a63d3ff1STakashi Sakamoto #include <sound/rawmidi.h> 26aa02bb6eSTakashi Sakamoto #include <sound/pcm_params.h> 27594ddcedSTakashi Sakamoto #include <sound/firewire.h> 28594ddcedSTakashi Sakamoto #include <sound/hwdep.h> 29bde8a8f2STakashi Sakamoto 30315fd41fSTakashi Sakamoto #include "../packets-buffer.h" 31315fd41fSTakashi Sakamoto #include "../iso-resources.h" 325955815eSTakashi Sakamoto #include "../amdtp-am824.h" 33bde8a8f2STakashi Sakamoto #include "../cmp.h" 34bde8a8f2STakashi Sakamoto #include "../lib.h" 35bde8a8f2STakashi Sakamoto 36315fd41fSTakashi Sakamoto #define SND_EFW_MAX_MIDI_OUT_PORTS 2 37315fd41fSTakashi Sakamoto #define SND_EFW_MAX_MIDI_IN_PORTS 2 38315fd41fSTakashi Sakamoto 39bde8a8f2STakashi Sakamoto #define SND_EFW_MULTIPLIER_MODES 3 40bde8a8f2STakashi Sakamoto #define HWINFO_NAME_SIZE_BYTES 32 41bde8a8f2STakashi Sakamoto #define HWINFO_MAX_CAPS_GROUPS 8 42bde8a8f2STakashi Sakamoto 43bde8a8f2STakashi Sakamoto /* 44bde8a8f2STakashi Sakamoto * This should be greater than maximum bytes for EFW response content. 45bde8a8f2STakashi Sakamoto * Currently response against command for isochronous channel mapping is 46bde8a8f2STakashi Sakamoto * confirmed to be the maximum one. But for flexibility, use maximum data 47bde8a8f2STakashi Sakamoto * payload for asynchronous primary packets at S100 (Cable base rate) in 48bde8a8f2STakashi Sakamoto * IEEE Std 1394-1995. 49bde8a8f2STakashi Sakamoto */ 50bde8a8f2STakashi Sakamoto #define SND_EFW_RESPONSE_MAXIMUM_BYTES 0x200U 51bde8a8f2STakashi Sakamoto 52555e8a8fSTakashi Sakamoto extern unsigned int snd_efw_resp_buf_size; 53555e8a8fSTakashi Sakamoto extern bool snd_efw_resp_buf_debug; 54555e8a8fSTakashi Sakamoto 55bde8a8f2STakashi Sakamoto struct snd_efw_phys_grp { 56bde8a8f2STakashi Sakamoto u8 type; /* see enum snd_efw_grp_type */ 57bde8a8f2STakashi Sakamoto u8 count; 58bde8a8f2STakashi Sakamoto } __packed; 59b5b04336STakashi Sakamoto 60b5b04336STakashi Sakamoto struct snd_efw { 61b5b04336STakashi Sakamoto struct snd_card *card; 62b5b04336STakashi Sakamoto struct fw_unit *unit; 63b5b04336STakashi Sakamoto int card_index; 64b5b04336STakashi Sakamoto 65b5b04336STakashi Sakamoto struct mutex mutex; 66b5b04336STakashi Sakamoto spinlock_t lock; 67bde8a8f2STakashi Sakamoto 68bde8a8f2STakashi Sakamoto /* for transaction */ 69bde8a8f2STakashi Sakamoto u32 seqnum; 70bde8a8f2STakashi Sakamoto bool resp_addr_changable; 71315fd41fSTakashi Sakamoto 7269702239STakashi Sakamoto /* for quirks */ 7369702239STakashi Sakamoto bool is_af9; 7418f5ed36STakashi Sakamoto bool is_fireworks3; 75d9cd0065STakashi Sakamoto u32 firmware_version; 7669702239STakashi Sakamoto 77315fd41fSTakashi Sakamoto unsigned int midi_in_ports; 78315fd41fSTakashi Sakamoto unsigned int midi_out_ports; 79315fd41fSTakashi Sakamoto 80315fd41fSTakashi Sakamoto unsigned int supported_sampling_rate; 81315fd41fSTakashi Sakamoto unsigned int pcm_capture_channels[SND_EFW_MULTIPLIER_MODES]; 82315fd41fSTakashi Sakamoto unsigned int pcm_playback_channels[SND_EFW_MULTIPLIER_MODES]; 83315fd41fSTakashi Sakamoto 84315fd41fSTakashi Sakamoto struct amdtp_stream tx_stream; 85315fd41fSTakashi Sakamoto struct amdtp_stream rx_stream; 86315fd41fSTakashi Sakamoto struct cmp_connection out_conn; 87315fd41fSTakashi Sakamoto struct cmp_connection in_conn; 881dc59210STakashi Sakamoto unsigned int substreams_counter; 896a22683eSTakashi Sakamoto 906a22683eSTakashi Sakamoto /* hardware metering parameters */ 916a22683eSTakashi Sakamoto unsigned int phys_out; 926a22683eSTakashi Sakamoto unsigned int phys_in; 936a22683eSTakashi Sakamoto unsigned int phys_out_grp_count; 946a22683eSTakashi Sakamoto unsigned int phys_in_grp_count; 956a22683eSTakashi Sakamoto struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS]; 966a22683eSTakashi Sakamoto struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS]; 97594ddcedSTakashi Sakamoto 98594ddcedSTakashi Sakamoto /* for uapi */ 99594ddcedSTakashi Sakamoto int dev_lock_count; 100594ddcedSTakashi Sakamoto bool dev_lock_changed; 101594ddcedSTakashi Sakamoto wait_queue_head_t hwdep_wait; 102555e8a8fSTakashi Sakamoto 103555e8a8fSTakashi Sakamoto /* response queue */ 104555e8a8fSTakashi Sakamoto u8 *resp_buf; 105555e8a8fSTakashi Sakamoto u8 *pull_ptr; 106555e8a8fSTakashi Sakamoto u8 *push_ptr; 107db40eeb2STakashi Sakamoto 108db40eeb2STakashi Sakamoto struct amdtp_domain domain; 109b5b04336STakashi Sakamoto }; 110b5b04336STakashi Sakamoto 111555e8a8fSTakashi Sakamoto int snd_efw_transaction_cmd(struct fw_unit *unit, 112555e8a8fSTakashi Sakamoto const void *cmd, unsigned int size); 113bde8a8f2STakashi Sakamoto int snd_efw_transaction_run(struct fw_unit *unit, 114bde8a8f2STakashi Sakamoto const void *cmd, unsigned int cmd_size, 115bde8a8f2STakashi Sakamoto void *resp, unsigned int resp_size); 116bde8a8f2STakashi Sakamoto int snd_efw_transaction_register(void); 117bde8a8f2STakashi Sakamoto void snd_efw_transaction_unregister(void); 118bde8a8f2STakashi Sakamoto void snd_efw_transaction_bus_reset(struct fw_unit *unit); 119555e8a8fSTakashi Sakamoto void snd_efw_transaction_add_instance(struct snd_efw *efw); 120555e8a8fSTakashi Sakamoto void snd_efw_transaction_remove_instance(struct snd_efw *efw); 121bde8a8f2STakashi Sakamoto 122bde8a8f2STakashi Sakamoto struct snd_efw_hwinfo { 123bde8a8f2STakashi Sakamoto u32 flags; 124bde8a8f2STakashi Sakamoto u32 guid_hi; 125bde8a8f2STakashi Sakamoto u32 guid_lo; 126bde8a8f2STakashi Sakamoto u32 type; 127bde8a8f2STakashi Sakamoto u32 version; 128bde8a8f2STakashi Sakamoto char vendor_name[HWINFO_NAME_SIZE_BYTES]; 129bde8a8f2STakashi Sakamoto char model_name[HWINFO_NAME_SIZE_BYTES]; 130bde8a8f2STakashi Sakamoto u32 supported_clocks; 131bde8a8f2STakashi Sakamoto u32 amdtp_rx_pcm_channels; 132bde8a8f2STakashi Sakamoto u32 amdtp_tx_pcm_channels; 133bde8a8f2STakashi Sakamoto u32 phys_out; 134bde8a8f2STakashi Sakamoto u32 phys_in; 135bde8a8f2STakashi Sakamoto u32 phys_out_grp_count; 136bde8a8f2STakashi Sakamoto struct snd_efw_phys_grp phys_out_grps[HWINFO_MAX_CAPS_GROUPS]; 137bde8a8f2STakashi Sakamoto u32 phys_in_grp_count; 138bde8a8f2STakashi Sakamoto struct snd_efw_phys_grp phys_in_grps[HWINFO_MAX_CAPS_GROUPS]; 139bde8a8f2STakashi Sakamoto u32 midi_out_ports; 140bde8a8f2STakashi Sakamoto u32 midi_in_ports; 141bde8a8f2STakashi Sakamoto u32 max_sample_rate; 142bde8a8f2STakashi Sakamoto u32 min_sample_rate; 143bde8a8f2STakashi Sakamoto u32 dsp_version; 144bde8a8f2STakashi Sakamoto u32 arm_version; 145bde8a8f2STakashi Sakamoto u32 mixer_playback_channels; 146bde8a8f2STakashi Sakamoto u32 mixer_capture_channels; 147bde8a8f2STakashi Sakamoto u32 fpga_version; 148bde8a8f2STakashi Sakamoto u32 amdtp_rx_pcm_channels_2x; 149bde8a8f2STakashi Sakamoto u32 amdtp_tx_pcm_channels_2x; 150bde8a8f2STakashi Sakamoto u32 amdtp_rx_pcm_channels_4x; 151bde8a8f2STakashi Sakamoto u32 amdtp_tx_pcm_channels_4x; 152bde8a8f2STakashi Sakamoto u32 reserved[16]; 153bde8a8f2STakashi Sakamoto } __packed; 154bde8a8f2STakashi Sakamoto enum snd_efw_grp_type { 155bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_ANALOG = 0, 156bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_SPDIF = 1, 157bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_ADAT = 2, 158bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_SPDIF_OR_ADAT = 3, 159bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_ANALOG_MIRRORING = 4, 160bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_HEADPHONES = 5, 161bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_I2S = 6, 162bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_GUITAR = 7, 163bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_PIEZO_GUITAR = 8, 164bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_GUITAR_STRING = 9, 165bde8a8f2STakashi Sakamoto SND_EFW_CH_TYPE_DUMMY 166bde8a8f2STakashi Sakamoto }; 167bde8a8f2STakashi Sakamoto struct snd_efw_phys_meters { 168bde8a8f2STakashi Sakamoto u32 status; /* guitar state/midi signal/clock input detect */ 169bde8a8f2STakashi Sakamoto u32 reserved0; 170bde8a8f2STakashi Sakamoto u32 reserved1; 171bde8a8f2STakashi Sakamoto u32 reserved2; 172bde8a8f2STakashi Sakamoto u32 reserved3; 173bde8a8f2STakashi Sakamoto u32 out_meters; 174bde8a8f2STakashi Sakamoto u32 in_meters; 175bde8a8f2STakashi Sakamoto u32 reserved4; 176bde8a8f2STakashi Sakamoto u32 reserved5; 17789ebe49aSGustavo A. R. Silva u32 values[]; 178bde8a8f2STakashi Sakamoto } __packed; 179bde8a8f2STakashi Sakamoto enum snd_efw_clock_source { 180bde8a8f2STakashi Sakamoto SND_EFW_CLOCK_SOURCE_INTERNAL = 0, 181*77f1fd6dSTakashi Sakamoto // Unused. 182bde8a8f2STakashi Sakamoto SND_EFW_CLOCK_SOURCE_WORDCLOCK = 2, 183bde8a8f2STakashi Sakamoto SND_EFW_CLOCK_SOURCE_SPDIF = 3, 184bde8a8f2STakashi Sakamoto SND_EFW_CLOCK_SOURCE_ADAT_1 = 4, 185bde8a8f2STakashi Sakamoto SND_EFW_CLOCK_SOURCE_ADAT_2 = 5, 186bde8a8f2STakashi Sakamoto SND_EFW_CLOCK_SOURCE_CONTINUOUS = 6 /* internal variable clock */ 187bde8a8f2STakashi Sakamoto }; 188bde8a8f2STakashi Sakamoto enum snd_efw_transport_mode { 189bde8a8f2STakashi Sakamoto SND_EFW_TRANSPORT_MODE_WINDOWS = 0, 190bde8a8f2STakashi Sakamoto SND_EFW_TRANSPORT_MODE_IEC61883 = 1, 191bde8a8f2STakashi Sakamoto }; 192bde8a8f2STakashi Sakamoto int snd_efw_command_set_resp_addr(struct snd_efw *efw, 193bde8a8f2STakashi Sakamoto u16 addr_high, u32 addr_low); 19493219d06STakashi Sakamoto int snd_efw_command_set_tx_mode(struct snd_efw *efw, 19593219d06STakashi Sakamoto enum snd_efw_transport_mode mode); 196bde8a8f2STakashi Sakamoto int snd_efw_command_get_hwinfo(struct snd_efw *efw, 197bde8a8f2STakashi Sakamoto struct snd_efw_hwinfo *hwinfo); 198bde8a8f2STakashi Sakamoto int snd_efw_command_get_phys_meters(struct snd_efw *efw, 199bde8a8f2STakashi Sakamoto struct snd_efw_phys_meters *meters, 200bde8a8f2STakashi Sakamoto unsigned int len); 201bde8a8f2STakashi Sakamoto int snd_efw_command_get_clock_source(struct snd_efw *efw, 202bde8a8f2STakashi Sakamoto enum snd_efw_clock_source *source); 203bde8a8f2STakashi Sakamoto int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate); 204bde8a8f2STakashi Sakamoto int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate); 205bde8a8f2STakashi Sakamoto 206315fd41fSTakashi Sakamoto int snd_efw_stream_init_duplex(struct snd_efw *efw); 207dd20e68aSTakashi Sakamoto int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate, 208659c6af5STakashi Sakamoto unsigned int frames_per_period, 209659c6af5STakashi Sakamoto unsigned int frames_per_buffer); 2103d725066STakashi Sakamoto int snd_efw_stream_start_duplex(struct snd_efw *efw); 211315fd41fSTakashi Sakamoto void snd_efw_stream_stop_duplex(struct snd_efw *efw); 212315fd41fSTakashi Sakamoto void snd_efw_stream_update_duplex(struct snd_efw *efw); 213315fd41fSTakashi Sakamoto void snd_efw_stream_destroy_duplex(struct snd_efw *efw); 214594ddcedSTakashi Sakamoto void snd_efw_stream_lock_changed(struct snd_efw *efw); 215594ddcedSTakashi Sakamoto int snd_efw_stream_lock_try(struct snd_efw *efw); 216594ddcedSTakashi Sakamoto void snd_efw_stream_lock_release(struct snd_efw *efw); 217315fd41fSTakashi Sakamoto 2186a22683eSTakashi Sakamoto void snd_efw_proc_init(struct snd_efw *efw); 2196a22683eSTakashi Sakamoto 220a63d3ff1STakashi Sakamoto int snd_efw_create_midi_devices(struct snd_efw *efw); 221a63d3ff1STakashi Sakamoto 222aa02bb6eSTakashi Sakamoto int snd_efw_create_pcm_devices(struct snd_efw *efw); 223aa02bb6eSTakashi Sakamoto int snd_efw_get_multiplier_mode(unsigned int sampling_rate, unsigned int *mode); 224aa02bb6eSTakashi Sakamoto 225594ddcedSTakashi Sakamoto int snd_efw_create_hwdep_device(struct snd_efw *efw); 226594ddcedSTakashi Sakamoto 227b5b04336STakashi Sakamoto #endif 228