1da607e19SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 29edf723fSTakashi Sakamoto /* 39edf723fSTakashi Sakamoto * digi00x.h - a part of driver for Digidesign Digi 002/003 family 49edf723fSTakashi Sakamoto * 59edf723fSTakashi Sakamoto * Copyright (c) 2014-2015 Takashi Sakamoto 69edf723fSTakashi Sakamoto */ 79edf723fSTakashi Sakamoto 89edf723fSTakashi Sakamoto #ifndef SOUND_DIGI00X_H_INCLUDED 99edf723fSTakashi Sakamoto #define SOUND_DIGI00X_H_INCLUDED 109edf723fSTakashi Sakamoto 119edf723fSTakashi Sakamoto #include <linux/compat.h> 129edf723fSTakashi Sakamoto #include <linux/device.h> 139edf723fSTakashi Sakamoto #include <linux/firewire.h> 149edf723fSTakashi Sakamoto #include <linux/module.h> 159edf723fSTakashi Sakamoto #include <linux/mod_devicetable.h> 169edf723fSTakashi Sakamoto #include <linux/delay.h> 179edf723fSTakashi Sakamoto #include <linux/slab.h> 18174cd4b1SIngo Molnar #include <linux/sched/signal.h> 199edf723fSTakashi Sakamoto 209edf723fSTakashi Sakamoto #include <sound/core.h> 219edf723fSTakashi Sakamoto #include <sound/initval.h> 22927f17dcSTakashi Sakamoto #include <sound/info.h> 23163ae6f3STakashi Sakamoto #include <sound/pcm.h> 24163ae6f3STakashi Sakamoto #include <sound/pcm_params.h> 25660dd3d5STakashi Sakamoto #include <sound/firewire.h> 26660dd3d5STakashi Sakamoto #include <sound/hwdep.h> 279dc5d31cSTakashi Sakamoto #include <sound/rawmidi.h> 289edf723fSTakashi Sakamoto 299edf723fSTakashi Sakamoto #include "../lib.h" 30163ae6f3STakashi Sakamoto #include "../iso-resources.h" 31163ae6f3STakashi Sakamoto #include "../amdtp-stream.h" 329edf723fSTakashi Sakamoto 339edf723fSTakashi Sakamoto struct snd_dg00x { 349edf723fSTakashi Sakamoto struct snd_card *card; 359edf723fSTakashi Sakamoto struct fw_unit *unit; 369edf723fSTakashi Sakamoto 379edf723fSTakashi Sakamoto struct mutex mutex; 38660dd3d5STakashi Sakamoto spinlock_t lock; 393a2a1797STakashi Sakamoto 403a2a1797STakashi Sakamoto struct amdtp_stream tx_stream; 413a2a1797STakashi Sakamoto struct fw_iso_resources tx_resources; 423a2a1797STakashi Sakamoto 433a2a1797STakashi Sakamoto struct amdtp_stream rx_stream; 443a2a1797STakashi Sakamoto struct fw_iso_resources rx_resources; 453a2a1797STakashi Sakamoto 463a2a1797STakashi Sakamoto unsigned int substreams_counter; 47660dd3d5STakashi Sakamoto 48660dd3d5STakashi Sakamoto /* for uapi */ 49660dd3d5STakashi Sakamoto int dev_lock_count; 50660dd3d5STakashi Sakamoto bool dev_lock_changed; 51660dd3d5STakashi Sakamoto wait_queue_head_t hwdep_wait; 52660dd3d5STakashi Sakamoto 5344b73088STakashi Sakamoto /* For asynchronous messages. */ 5444b73088STakashi Sakamoto struct fw_address_handler async_handler; 5544b73088STakashi Sakamoto u32 msg; 563646a54aSTakashi Sakamoto 57fdb2b2eeSTakashi Sakamoto /* Console models have additional MIDI ports for control surface. */ 5813e005f9STakashi Sakamoto bool is_console; 599a08067eSTakashi Sakamoto 609a08067eSTakashi Sakamoto struct amdtp_domain domain; 613a2a1797STakashi Sakamoto }; 623a2a1797STakashi Sakamoto 633a2a1797STakashi Sakamoto #define DG00X_ADDR_BASE 0xffffe0000000ull 643a2a1797STakashi Sakamoto 653a2a1797STakashi Sakamoto #define DG00X_OFFSET_STREAMING_STATE 0x0000 663a2a1797STakashi Sakamoto #define DG00X_OFFSET_STREAMING_SET 0x0004 67fdb2b2eeSTakashi Sakamoto /* unknown but address in host space 0x0008 */ 683a2a1797STakashi Sakamoto /* For LSB of the address 0x000c */ 693a2a1797STakashi Sakamoto /* unknown 0x0010 */ 703a2a1797STakashi Sakamoto #define DG00X_OFFSET_MESSAGE_ADDR 0x0014 713a2a1797STakashi Sakamoto /* For LSB of the address 0x0018 */ 723a2a1797STakashi Sakamoto /* unknown 0x001c */ 733a2a1797STakashi Sakamoto /* unknown 0x0020 */ 743a2a1797STakashi Sakamoto /* not used 0x0024--0x00ff */ 753a2a1797STakashi Sakamoto #define DG00X_OFFSET_ISOC_CHANNELS 0x0100 763a2a1797STakashi Sakamoto /* unknown 0x0104 */ 773a2a1797STakashi Sakamoto /* unknown 0x0108 */ 783a2a1797STakashi Sakamoto /* unknown 0x010c */ 793a2a1797STakashi Sakamoto #define DG00X_OFFSET_LOCAL_RATE 0x0110 803a2a1797STakashi Sakamoto #define DG00X_OFFSET_EXTERNAL_RATE 0x0114 813a2a1797STakashi Sakamoto #define DG00X_OFFSET_CLOCK_SOURCE 0x0118 823a2a1797STakashi Sakamoto #define DG00X_OFFSET_OPT_IFACE_MODE 0x011c 833a2a1797STakashi Sakamoto /* unknown 0x0120 */ 843a2a1797STakashi Sakamoto /* Mixer control on/off 0x0124 */ 853a2a1797STakashi Sakamoto /* unknown 0x0128 */ 863a2a1797STakashi Sakamoto #define DG00X_OFFSET_DETECT_EXTERNAL 0x012c 873a2a1797STakashi Sakamoto /* unknown 0x0138 */ 883a2a1797STakashi Sakamoto #define DG00X_OFFSET_MMC 0x0400 893a2a1797STakashi Sakamoto 903a2a1797STakashi Sakamoto enum snd_dg00x_rate { 913a2a1797STakashi Sakamoto SND_DG00X_RATE_44100 = 0, 923a2a1797STakashi Sakamoto SND_DG00X_RATE_48000, 933a2a1797STakashi Sakamoto SND_DG00X_RATE_88200, 943a2a1797STakashi Sakamoto SND_DG00X_RATE_96000, 953a2a1797STakashi Sakamoto SND_DG00X_RATE_COUNT, 963a2a1797STakashi Sakamoto }; 973a2a1797STakashi Sakamoto 983a2a1797STakashi Sakamoto enum snd_dg00x_clock { 993a2a1797STakashi Sakamoto SND_DG00X_CLOCK_INTERNAL = 0, 1003a2a1797STakashi Sakamoto SND_DG00X_CLOCK_SPDIF, 1013a2a1797STakashi Sakamoto SND_DG00X_CLOCK_ADAT, 1023a2a1797STakashi Sakamoto SND_DG00X_CLOCK_WORD, 1033a2a1797STakashi Sakamoto SND_DG00X_CLOCK_COUNT, 1049edf723fSTakashi Sakamoto }; 1059edf723fSTakashi Sakamoto 106927f17dcSTakashi Sakamoto enum snd_dg00x_optical_mode { 107927f17dcSTakashi Sakamoto SND_DG00X_OPT_IFACE_MODE_ADAT = 0, 108927f17dcSTakashi Sakamoto SND_DG00X_OPT_IFACE_MODE_SPDIF, 109927f17dcSTakashi Sakamoto SND_DG00X_OPT_IFACE_MODE_COUNT, 110927f17dcSTakashi Sakamoto }; 111927f17dcSTakashi Sakamoto 1129dc5d31cSTakashi Sakamoto #define DOT_MIDI_IN_PORTS 1 1139dc5d31cSTakashi Sakamoto #define DOT_MIDI_OUT_PORTS 2 1149dc5d31cSTakashi Sakamoto 115163ae6f3STakashi Sakamoto int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit, 116163ae6f3STakashi Sakamoto enum amdtp_stream_direction dir); 117163ae6f3STakashi Sakamoto int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate, 1189dc5d31cSTakashi Sakamoto unsigned int pcm_channels); 119163ae6f3STakashi Sakamoto void amdtp_dot_reset(struct amdtp_stream *s); 120163ae6f3STakashi Sakamoto int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s, 121163ae6f3STakashi Sakamoto struct snd_pcm_runtime *runtime); 1229dc5d31cSTakashi Sakamoto void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, 1239dc5d31cSTakashi Sakamoto struct snd_rawmidi_substream *midi); 124163ae6f3STakashi Sakamoto 12544b73088STakashi Sakamoto int snd_dg00x_transaction_register(struct snd_dg00x *dg00x); 12644b73088STakashi Sakamoto int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x); 12744b73088STakashi Sakamoto void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x); 12844b73088STakashi Sakamoto 1293a2a1797STakashi Sakamoto extern const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT]; 1303a2a1797STakashi Sakamoto extern const unsigned int snd_dg00x_stream_pcm_channels[SND_DG00X_RATE_COUNT]; 1313a2a1797STakashi Sakamoto int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x, 1323a2a1797STakashi Sakamoto unsigned int *rate); 1333a2a1797STakashi Sakamoto int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x, 1343a2a1797STakashi Sakamoto unsigned int *rate); 1353a2a1797STakashi Sakamoto int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate); 1363a2a1797STakashi Sakamoto int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x, 1373a2a1797STakashi Sakamoto enum snd_dg00x_clock *clock); 1383a2a1797STakashi Sakamoto int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, 1393a2a1797STakashi Sakamoto bool *detect); 1403a2a1797STakashi Sakamoto int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x); 14118b7f18fSTakashi Sakamoto int snd_dg00x_stream_reserve_duplex(struct snd_dg00x *dg00x, unsigned int rate, 14276c4ecbeSTakashi Sakamoto unsigned int frames_per_period, 14376c4ecbeSTakashi Sakamoto unsigned int frames_per_buffer); 144ae8ffbb2STakashi Sakamoto int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x); 1453a2a1797STakashi Sakamoto void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x); 1463a2a1797STakashi Sakamoto void snd_dg00x_stream_update_duplex(struct snd_dg00x *dg00x); 1473a2a1797STakashi Sakamoto void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x); 1483a2a1797STakashi Sakamoto 149660dd3d5STakashi Sakamoto void snd_dg00x_stream_lock_changed(struct snd_dg00x *dg00x); 150660dd3d5STakashi Sakamoto int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x); 151660dd3d5STakashi Sakamoto void snd_dg00x_stream_lock_release(struct snd_dg00x *dg00x); 152660dd3d5STakashi Sakamoto 153927f17dcSTakashi Sakamoto void snd_dg00x_proc_init(struct snd_dg00x *dg00x); 1540120d0f1STakashi Sakamoto 1550120d0f1STakashi Sakamoto int snd_dg00x_create_pcm_devices(struct snd_dg00x *dg00x); 1560120d0f1STakashi Sakamoto 1579fbfd38bSTakashi Sakamoto int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x); 1589fbfd38bSTakashi Sakamoto 159660dd3d5STakashi Sakamoto int snd_dg00x_create_hwdep_device(struct snd_dg00x *dg00x); 1609edf723fSTakashi Sakamoto #endif 161