19edf723fSTakashi Sakamoto /* 29edf723fSTakashi Sakamoto * digi00x.h - a part of driver for Digidesign Digi 002/003 family 39edf723fSTakashi Sakamoto * 49edf723fSTakashi Sakamoto * Copyright (c) 2014-2015 Takashi Sakamoto 59edf723fSTakashi Sakamoto * 69edf723fSTakashi Sakamoto * Licensed under the terms of the GNU General Public License, version 2. 79edf723fSTakashi Sakamoto */ 89edf723fSTakashi Sakamoto 99edf723fSTakashi Sakamoto #ifndef SOUND_DIGI00X_H_INCLUDED 109edf723fSTakashi Sakamoto #define SOUND_DIGI00X_H_INCLUDED 119edf723fSTakashi Sakamoto 129edf723fSTakashi Sakamoto #include <linux/compat.h> 139edf723fSTakashi Sakamoto #include <linux/device.h> 149edf723fSTakashi Sakamoto #include <linux/firewire.h> 159edf723fSTakashi Sakamoto #include <linux/module.h> 169edf723fSTakashi Sakamoto #include <linux/mod_devicetable.h> 179edf723fSTakashi Sakamoto #include <linux/delay.h> 189edf723fSTakashi Sakamoto #include <linux/slab.h> 19174cd4b1SIngo Molnar #include <linux/sched/signal.h> 209edf723fSTakashi Sakamoto 219edf723fSTakashi Sakamoto #include <sound/core.h> 229edf723fSTakashi Sakamoto #include <sound/initval.h> 23927f17dcSTakashi Sakamoto #include <sound/info.h> 24163ae6f3STakashi Sakamoto #include <sound/pcm.h> 25163ae6f3STakashi Sakamoto #include <sound/pcm_params.h> 26660dd3d5STakashi Sakamoto #include <sound/firewire.h> 27660dd3d5STakashi Sakamoto #include <sound/hwdep.h> 289dc5d31cSTakashi Sakamoto #include <sound/rawmidi.h> 299edf723fSTakashi Sakamoto 309edf723fSTakashi Sakamoto #include "../lib.h" 31163ae6f3STakashi Sakamoto #include "../iso-resources.h" 32163ae6f3STakashi Sakamoto #include "../amdtp-stream.h" 339edf723fSTakashi Sakamoto 349edf723fSTakashi Sakamoto struct snd_dg00x { 359edf723fSTakashi Sakamoto struct snd_card *card; 369edf723fSTakashi Sakamoto struct fw_unit *unit; 379edf723fSTakashi Sakamoto 389edf723fSTakashi Sakamoto struct mutex mutex; 39660dd3d5STakashi Sakamoto spinlock_t lock; 403a2a1797STakashi Sakamoto 4186c8dd7fSTakashi Sakamoto bool registered; 4286c8dd7fSTakashi Sakamoto struct delayed_work dwork; 4386c8dd7fSTakashi Sakamoto 443a2a1797STakashi Sakamoto struct amdtp_stream tx_stream; 453a2a1797STakashi Sakamoto struct fw_iso_resources tx_resources; 463a2a1797STakashi Sakamoto 473a2a1797STakashi Sakamoto struct amdtp_stream rx_stream; 483a2a1797STakashi Sakamoto struct fw_iso_resources rx_resources; 493a2a1797STakashi Sakamoto 503a2a1797STakashi Sakamoto unsigned int substreams_counter; 51660dd3d5STakashi Sakamoto 52660dd3d5STakashi Sakamoto /* for uapi */ 53660dd3d5STakashi Sakamoto int dev_lock_count; 54660dd3d5STakashi Sakamoto bool dev_lock_changed; 55660dd3d5STakashi Sakamoto wait_queue_head_t hwdep_wait; 56660dd3d5STakashi Sakamoto 5744b73088STakashi Sakamoto /* For asynchronous messages. */ 5844b73088STakashi Sakamoto struct fw_address_handler async_handler; 5944b73088STakashi Sakamoto u32 msg; 603646a54aSTakashi Sakamoto 61*fdb2b2eeSTakashi Sakamoto /* Console models have additional MIDI ports for control surface. */ 6213e005f9STakashi Sakamoto bool is_console; 633a2a1797STakashi Sakamoto }; 643a2a1797STakashi Sakamoto 653a2a1797STakashi Sakamoto #define DG00X_ADDR_BASE 0xffffe0000000ull 663a2a1797STakashi Sakamoto 673a2a1797STakashi Sakamoto #define DG00X_OFFSET_STREAMING_STATE 0x0000 683a2a1797STakashi Sakamoto #define DG00X_OFFSET_STREAMING_SET 0x0004 69*fdb2b2eeSTakashi Sakamoto /* unknown but address in host space 0x0008 */ 703a2a1797STakashi Sakamoto /* For LSB of the address 0x000c */ 713a2a1797STakashi Sakamoto /* unknown 0x0010 */ 723a2a1797STakashi Sakamoto #define DG00X_OFFSET_MESSAGE_ADDR 0x0014 733a2a1797STakashi Sakamoto /* For LSB of the address 0x0018 */ 743a2a1797STakashi Sakamoto /* unknown 0x001c */ 753a2a1797STakashi Sakamoto /* unknown 0x0020 */ 763a2a1797STakashi Sakamoto /* not used 0x0024--0x00ff */ 773a2a1797STakashi Sakamoto #define DG00X_OFFSET_ISOC_CHANNELS 0x0100 783a2a1797STakashi Sakamoto /* unknown 0x0104 */ 793a2a1797STakashi Sakamoto /* unknown 0x0108 */ 803a2a1797STakashi Sakamoto /* unknown 0x010c */ 813a2a1797STakashi Sakamoto #define DG00X_OFFSET_LOCAL_RATE 0x0110 823a2a1797STakashi Sakamoto #define DG00X_OFFSET_EXTERNAL_RATE 0x0114 833a2a1797STakashi Sakamoto #define DG00X_OFFSET_CLOCK_SOURCE 0x0118 843a2a1797STakashi Sakamoto #define DG00X_OFFSET_OPT_IFACE_MODE 0x011c 853a2a1797STakashi Sakamoto /* unknown 0x0120 */ 863a2a1797STakashi Sakamoto /* Mixer control on/off 0x0124 */ 873a2a1797STakashi Sakamoto /* unknown 0x0128 */ 883a2a1797STakashi Sakamoto #define DG00X_OFFSET_DETECT_EXTERNAL 0x012c 893a2a1797STakashi Sakamoto /* unknown 0x0138 */ 903a2a1797STakashi Sakamoto #define DG00X_OFFSET_MMC 0x0400 913a2a1797STakashi Sakamoto 923a2a1797STakashi Sakamoto enum snd_dg00x_rate { 933a2a1797STakashi Sakamoto SND_DG00X_RATE_44100 = 0, 943a2a1797STakashi Sakamoto SND_DG00X_RATE_48000, 953a2a1797STakashi Sakamoto SND_DG00X_RATE_88200, 963a2a1797STakashi Sakamoto SND_DG00X_RATE_96000, 973a2a1797STakashi Sakamoto SND_DG00X_RATE_COUNT, 983a2a1797STakashi Sakamoto }; 993a2a1797STakashi Sakamoto 1003a2a1797STakashi Sakamoto enum snd_dg00x_clock { 1013a2a1797STakashi Sakamoto SND_DG00X_CLOCK_INTERNAL = 0, 1023a2a1797STakashi Sakamoto SND_DG00X_CLOCK_SPDIF, 1033a2a1797STakashi Sakamoto SND_DG00X_CLOCK_ADAT, 1043a2a1797STakashi Sakamoto SND_DG00X_CLOCK_WORD, 1053a2a1797STakashi Sakamoto SND_DG00X_CLOCK_COUNT, 1069edf723fSTakashi Sakamoto }; 1079edf723fSTakashi Sakamoto 108927f17dcSTakashi Sakamoto enum snd_dg00x_optical_mode { 109927f17dcSTakashi Sakamoto SND_DG00X_OPT_IFACE_MODE_ADAT = 0, 110927f17dcSTakashi Sakamoto SND_DG00X_OPT_IFACE_MODE_SPDIF, 111927f17dcSTakashi Sakamoto SND_DG00X_OPT_IFACE_MODE_COUNT, 112927f17dcSTakashi Sakamoto }; 113927f17dcSTakashi Sakamoto 1149dc5d31cSTakashi Sakamoto #define DOT_MIDI_IN_PORTS 1 1159dc5d31cSTakashi Sakamoto #define DOT_MIDI_OUT_PORTS 2 1169dc5d31cSTakashi Sakamoto 117163ae6f3STakashi Sakamoto int amdtp_dot_init(struct amdtp_stream *s, struct fw_unit *unit, 118163ae6f3STakashi Sakamoto enum amdtp_stream_direction dir); 119163ae6f3STakashi Sakamoto int amdtp_dot_set_parameters(struct amdtp_stream *s, unsigned int rate, 1209dc5d31cSTakashi Sakamoto unsigned int pcm_channels); 121163ae6f3STakashi Sakamoto void amdtp_dot_reset(struct amdtp_stream *s); 122163ae6f3STakashi Sakamoto int amdtp_dot_add_pcm_hw_constraints(struct amdtp_stream *s, 123163ae6f3STakashi Sakamoto struct snd_pcm_runtime *runtime); 124163ae6f3STakashi Sakamoto void amdtp_dot_set_pcm_format(struct amdtp_stream *s, snd_pcm_format_t format); 1259dc5d31cSTakashi Sakamoto void amdtp_dot_midi_trigger(struct amdtp_stream *s, unsigned int port, 1269dc5d31cSTakashi Sakamoto struct snd_rawmidi_substream *midi); 127163ae6f3STakashi Sakamoto 12844b73088STakashi Sakamoto int snd_dg00x_transaction_register(struct snd_dg00x *dg00x); 12944b73088STakashi Sakamoto int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x); 13044b73088STakashi Sakamoto void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x); 13144b73088STakashi Sakamoto 1323a2a1797STakashi Sakamoto extern const unsigned int snd_dg00x_stream_rates[SND_DG00X_RATE_COUNT]; 1333a2a1797STakashi Sakamoto extern const unsigned int snd_dg00x_stream_pcm_channels[SND_DG00X_RATE_COUNT]; 1343a2a1797STakashi Sakamoto int snd_dg00x_stream_get_external_rate(struct snd_dg00x *dg00x, 1353a2a1797STakashi Sakamoto unsigned int *rate); 1363a2a1797STakashi Sakamoto int snd_dg00x_stream_get_local_rate(struct snd_dg00x *dg00x, 1373a2a1797STakashi Sakamoto unsigned int *rate); 1383a2a1797STakashi Sakamoto int snd_dg00x_stream_set_local_rate(struct snd_dg00x *dg00x, unsigned int rate); 1393a2a1797STakashi Sakamoto int snd_dg00x_stream_get_clock(struct snd_dg00x *dg00x, 1403a2a1797STakashi Sakamoto enum snd_dg00x_clock *clock); 1413a2a1797STakashi Sakamoto int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, 1423a2a1797STakashi Sakamoto bool *detect); 1433a2a1797STakashi Sakamoto int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x); 1443a2a1797STakashi Sakamoto int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x, unsigned int rate); 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