linux/sound/firewire/motu/motu.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * motu.h - a part of driver for MOTU FireWire series
   4 *
   5 * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
   6 */
   7
   8#ifndef SOUND_FIREWIRE_MOTU_H_INCLUDED
   9#define SOUND_FIREWIRE_MOTU_H_INCLUDED
  10
  11#include <linux/device.h>
  12#include <linux/firewire.h>
  13#include <linux/firewire-constants.h>
  14#include <linux/module.h>
  15#include <linux/mod_devicetable.h>
  16#include <linux/mutex.h>
  17#include <linux/slab.h>
  18#include <linux/compat.h>
  19#include <linux/sched/signal.h>
  20
  21#include <sound/control.h>
  22#include <sound/core.h>
  23#include <sound/pcm.h>
  24#include <sound/info.h>
  25#include <sound/rawmidi.h>
  26#include <sound/firewire.h>
  27#include <sound/hwdep.h>
  28
  29#include "../lib.h"
  30#include "../amdtp-stream.h"
  31#include "../iso-resources.h"
  32
  33struct snd_motu_packet_format {
  34        unsigned char midi_flag_offset;
  35        unsigned char midi_byte_offset;
  36        unsigned char pcm_byte_offset;
  37
  38        unsigned char msg_chunks;
  39        unsigned char pcm_chunks[3];
  40};
  41
  42struct amdtp_motu_cache {
  43        unsigned int *event_offsets;
  44        unsigned int size;
  45        unsigned int tail;
  46        unsigned int tx_cycle_count;
  47        unsigned int head;
  48        unsigned int rx_cycle_count;
  49};
  50
  51struct snd_motu {
  52        struct snd_card *card;
  53        struct fw_unit *unit;
  54        struct mutex mutex;
  55        spinlock_t lock;
  56
  57        /* Model dependent information. */
  58        const struct snd_motu_spec *spec;
  59
  60        /* For packet streaming */
  61        struct snd_motu_packet_format tx_packet_formats;
  62        struct snd_motu_packet_format rx_packet_formats;
  63        struct amdtp_stream tx_stream;
  64        struct amdtp_stream rx_stream;
  65        struct fw_iso_resources tx_resources;
  66        struct fw_iso_resources rx_resources;
  67        unsigned int substreams_counter;
  68
  69        /* For notification. */
  70        struct fw_address_handler async_handler;
  71        u32 msg;
  72
  73        /* For uapi */
  74        int dev_lock_count;
  75        bool dev_lock_changed;
  76        wait_queue_head_t hwdep_wait;
  77
  78        struct amdtp_domain domain;
  79
  80        struct amdtp_motu_cache cache;
  81};
  82
  83enum snd_motu_spec_flags {
  84        SND_MOTU_SPEC_RX_MIDI_2ND_Q     = 0x0001,
  85        SND_MOTU_SPEC_RX_MIDI_3RD_Q     = 0x0002,
  86        SND_MOTU_SPEC_TX_MIDI_2ND_Q     = 0x0004,
  87        SND_MOTU_SPEC_TX_MIDI_3RD_Q     = 0x0008,
  88};
  89
  90#define SND_MOTU_CLOCK_RATE_COUNT       6
  91extern const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT];
  92
  93enum snd_motu_clock_source {
  94        SND_MOTU_CLOCK_SOURCE_INTERNAL,
  95        SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB,
  96        SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT,
  97        SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A,
  98        SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B,
  99        SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT,
 100        SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A,
 101        SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B,
 102        SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX,
 103        SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR,
 104        SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC,
 105        SND_MOTU_CLOCK_SOURCE_SPH,
 106        SND_MOTU_CLOCK_SOURCE_UNKNOWN,
 107};
 108
 109enum snd_motu_protocol_version {
 110        SND_MOTU_PROTOCOL_V1,
 111        SND_MOTU_PROTOCOL_V2,
 112        SND_MOTU_PROTOCOL_V3,
 113};
 114
 115struct snd_motu_spec {
 116        const char *const name;
 117        enum snd_motu_protocol_version protocol_version;
 118        // The combination of snd_motu_spec_flags enumeration-constants.
 119        unsigned int flags;
 120
 121        unsigned char tx_fixed_pcm_chunks[3];
 122        unsigned char rx_fixed_pcm_chunks[3];
 123};
 124
 125extern const struct snd_motu_spec snd_motu_spec_828;
 126extern const struct snd_motu_spec snd_motu_spec_896;
 127
 128extern const struct snd_motu_spec snd_motu_spec_828mk2;
 129extern const struct snd_motu_spec snd_motu_spec_896hd;
 130extern const struct snd_motu_spec snd_motu_spec_traveler;
 131extern const struct snd_motu_spec snd_motu_spec_ultralite;
 132extern const struct snd_motu_spec snd_motu_spec_8pre;
 133
 134extern const struct snd_motu_spec snd_motu_spec_828mk3_fw;
 135extern const struct snd_motu_spec snd_motu_spec_828mk3_hybrid;
 136extern const struct snd_motu_spec snd_motu_spec_ultralite_mk3;
 137extern const struct snd_motu_spec snd_motu_spec_audio_express;
 138extern const struct snd_motu_spec snd_motu_spec_4pre;
 139
 140int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
 141                    enum amdtp_stream_direction dir,
 142                    const struct snd_motu_spec *spec,
 143                    struct amdtp_motu_cache *cache);
 144int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
 145                              unsigned int midi_ports,
 146                              struct snd_motu_packet_format *formats);
 147int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
 148                                      struct snd_pcm_runtime *runtime);
 149void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
 150                             struct snd_rawmidi_substream *midi);
 151
 152int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
 153                              size_t size);
 154int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
 155                               size_t size);
 156int snd_motu_transaction_register(struct snd_motu *motu);
 157int snd_motu_transaction_reregister(struct snd_motu *motu);
 158void snd_motu_transaction_unregister(struct snd_motu *motu);
 159
 160int snd_motu_stream_init_duplex(struct snd_motu *motu);
 161void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
 162int snd_motu_stream_cache_packet_formats(struct snd_motu *motu);
 163int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
 164                                   unsigned int frames_per_period,
 165                                   unsigned int frames_per_buffer);
 166int snd_motu_stream_start_duplex(struct snd_motu *motu);
 167void snd_motu_stream_stop_duplex(struct snd_motu *motu);
 168int snd_motu_stream_lock_try(struct snd_motu *motu);
 169void snd_motu_stream_lock_release(struct snd_motu *motu);
 170
 171void snd_motu_proc_init(struct snd_motu *motu);
 172
 173int snd_motu_create_pcm_devices(struct snd_motu *motu);
 174
 175int snd_motu_create_midi_devices(struct snd_motu *motu);
 176
 177int snd_motu_create_hwdep_device(struct snd_motu *motu);
 178
 179int snd_motu_protocol_v1_get_clock_rate(struct snd_motu *motu,
 180                                        unsigned int *rate);
 181int snd_motu_protocol_v1_set_clock_rate(struct snd_motu *motu,
 182                                        unsigned int rate);
 183int snd_motu_protocol_v1_get_clock_source(struct snd_motu *motu,
 184                                          enum snd_motu_clock_source *src);
 185int snd_motu_protocol_v1_switch_fetching_mode(struct snd_motu *motu,
 186                                              bool enable);
 187int snd_motu_protocol_v1_cache_packet_formats(struct snd_motu *motu);
 188
 189int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu,
 190                                        unsigned int *rate);
 191int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu,
 192                                        unsigned int rate);
 193int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
 194                                          enum snd_motu_clock_source *src);
 195int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
 196                                              bool enable);
 197int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu);
 198
 199int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu,
 200                                        unsigned int *rate);
 201int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
 202                                        unsigned int rate);
 203int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
 204                                          enum snd_motu_clock_source *src);
 205int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu,
 206                                              bool enable);
 207int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu);
 208
 209static inline int snd_motu_protocol_get_clock_rate(struct snd_motu *motu,
 210                                                   unsigned int *rate)
 211{
 212        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 213                return snd_motu_protocol_v2_get_clock_rate(motu, rate);
 214        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 215                return snd_motu_protocol_v3_get_clock_rate(motu, rate);
 216        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 217                return snd_motu_protocol_v1_get_clock_rate(motu, rate);
 218        else
 219                return -ENXIO;
 220}
 221
 222static inline int snd_motu_protocol_set_clock_rate(struct snd_motu *motu,
 223                                                   unsigned int rate)
 224{
 225        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 226                return snd_motu_protocol_v2_set_clock_rate(motu, rate);
 227        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 228                return snd_motu_protocol_v3_set_clock_rate(motu, rate);
 229        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 230                return snd_motu_protocol_v1_set_clock_rate(motu, rate);
 231        else
 232                return -ENXIO;
 233}
 234
 235static inline int snd_motu_protocol_get_clock_source(struct snd_motu *motu,
 236                                        enum snd_motu_clock_source *source)
 237{
 238        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 239                return snd_motu_protocol_v2_get_clock_source(motu, source);
 240        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 241                return snd_motu_protocol_v3_get_clock_source(motu, source);
 242        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 243                return snd_motu_protocol_v1_get_clock_source(motu, source);
 244        else
 245                return -ENXIO;
 246}
 247
 248static inline int snd_motu_protocol_switch_fetching_mode(struct snd_motu *motu,
 249                                                         bool enable)
 250{
 251        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 252                return snd_motu_protocol_v2_switch_fetching_mode(motu, enable);
 253        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 254                return snd_motu_protocol_v3_switch_fetching_mode(motu, enable);
 255        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 256                return snd_motu_protocol_v1_switch_fetching_mode(motu, enable);
 257        else
 258                return -ENXIO;
 259}
 260
 261static inline int snd_motu_protocol_cache_packet_formats(struct snd_motu *motu)
 262{
 263        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 264                return snd_motu_protocol_v2_cache_packet_formats(motu);
 265        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 266                return snd_motu_protocol_v3_cache_packet_formats(motu);
 267        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 268                return snd_motu_protocol_v1_cache_packet_formats(motu);
 269        else
 270                return -ENXIO;
 271}
 272
 273#endif
 274