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_traveler;
 130extern const struct snd_motu_spec snd_motu_spec_ultralite;
 131extern const struct snd_motu_spec snd_motu_spec_8pre;
 132
 133extern const struct snd_motu_spec snd_motu_spec_828mk3_fw;
 134extern const struct snd_motu_spec snd_motu_spec_828mk3_hybrid;
 135extern const struct snd_motu_spec snd_motu_spec_ultralite_mk3;
 136extern const struct snd_motu_spec snd_motu_spec_audio_express;
 137extern const struct snd_motu_spec snd_motu_spec_4pre;
 138
 139int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit,
 140                    enum amdtp_stream_direction dir,
 141                    const struct snd_motu_spec *spec,
 142                    struct amdtp_motu_cache *cache);
 143int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate,
 144                              unsigned int midi_ports,
 145                              struct snd_motu_packet_format *formats);
 146int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s,
 147                                      struct snd_pcm_runtime *runtime);
 148void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port,
 149                             struct snd_rawmidi_substream *midi);
 150
 151int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg,
 152                              size_t size);
 153int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg,
 154                               size_t size);
 155int snd_motu_transaction_register(struct snd_motu *motu);
 156int snd_motu_transaction_reregister(struct snd_motu *motu);
 157void snd_motu_transaction_unregister(struct snd_motu *motu);
 158
 159int snd_motu_stream_init_duplex(struct snd_motu *motu);
 160void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
 161int snd_motu_stream_cache_packet_formats(struct snd_motu *motu);
 162int snd_motu_stream_reserve_duplex(struct snd_motu *motu, unsigned int rate,
 163                                   unsigned int frames_per_period,
 164                                   unsigned int frames_per_buffer);
 165int snd_motu_stream_start_duplex(struct snd_motu *motu);
 166void snd_motu_stream_stop_duplex(struct snd_motu *motu);
 167int snd_motu_stream_lock_try(struct snd_motu *motu);
 168void snd_motu_stream_lock_release(struct snd_motu *motu);
 169
 170void snd_motu_proc_init(struct snd_motu *motu);
 171
 172int snd_motu_create_pcm_devices(struct snd_motu *motu);
 173
 174int snd_motu_create_midi_devices(struct snd_motu *motu);
 175
 176int snd_motu_create_hwdep_device(struct snd_motu *motu);
 177
 178int snd_motu_protocol_v1_get_clock_rate(struct snd_motu *motu,
 179                                        unsigned int *rate);
 180int snd_motu_protocol_v1_set_clock_rate(struct snd_motu *motu,
 181                                        unsigned int rate);
 182int snd_motu_protocol_v1_get_clock_source(struct snd_motu *motu,
 183                                          enum snd_motu_clock_source *src);
 184int snd_motu_protocol_v1_switch_fetching_mode(struct snd_motu *motu,
 185                                              bool enable);
 186int snd_motu_protocol_v1_cache_packet_formats(struct snd_motu *motu);
 187
 188int snd_motu_protocol_v2_get_clock_rate(struct snd_motu *motu,
 189                                        unsigned int *rate);
 190int snd_motu_protocol_v2_set_clock_rate(struct snd_motu *motu,
 191                                        unsigned int rate);
 192int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
 193                                          enum snd_motu_clock_source *src);
 194int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
 195                                              bool enable);
 196int snd_motu_protocol_v2_cache_packet_formats(struct snd_motu *motu);
 197
 198int snd_motu_protocol_v3_get_clock_rate(struct snd_motu *motu,
 199                                        unsigned int *rate);
 200int snd_motu_protocol_v3_set_clock_rate(struct snd_motu *motu,
 201                                        unsigned int rate);
 202int snd_motu_protocol_v3_get_clock_source(struct snd_motu *motu,
 203                                          enum snd_motu_clock_source *src);
 204int snd_motu_protocol_v3_switch_fetching_mode(struct snd_motu *motu,
 205                                              bool enable);
 206int snd_motu_protocol_v3_cache_packet_formats(struct snd_motu *motu);
 207
 208static inline int snd_motu_protocol_get_clock_rate(struct snd_motu *motu,
 209                                                   unsigned int *rate)
 210{
 211        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 212                return snd_motu_protocol_v2_get_clock_rate(motu, rate);
 213        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 214                return snd_motu_protocol_v3_get_clock_rate(motu, rate);
 215        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 216                return snd_motu_protocol_v1_get_clock_rate(motu, rate);
 217        else
 218                return -ENXIO;
 219}
 220
 221static inline int snd_motu_protocol_set_clock_rate(struct snd_motu *motu,
 222                                                   unsigned int rate)
 223{
 224        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 225                return snd_motu_protocol_v2_set_clock_rate(motu, rate);
 226        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 227                return snd_motu_protocol_v3_set_clock_rate(motu, rate);
 228        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 229                return snd_motu_protocol_v1_set_clock_rate(motu, rate);
 230        else
 231                return -ENXIO;
 232}
 233
 234static inline int snd_motu_protocol_get_clock_source(struct snd_motu *motu,
 235                                        enum snd_motu_clock_source *source)
 236{
 237        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 238                return snd_motu_protocol_v2_get_clock_source(motu, source);
 239        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 240                return snd_motu_protocol_v3_get_clock_source(motu, source);
 241        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 242                return snd_motu_protocol_v1_get_clock_source(motu, source);
 243        else
 244                return -ENXIO;
 245}
 246
 247static inline int snd_motu_protocol_switch_fetching_mode(struct snd_motu *motu,
 248                                                         bool enable)
 249{
 250        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 251                return snd_motu_protocol_v2_switch_fetching_mode(motu, enable);
 252        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 253                return snd_motu_protocol_v3_switch_fetching_mode(motu, enable);
 254        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 255                return snd_motu_protocol_v1_switch_fetching_mode(motu, enable);
 256        else
 257                return -ENXIO;
 258}
 259
 260static inline int snd_motu_protocol_cache_packet_formats(struct snd_motu *motu)
 261{
 262        if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V2)
 263                return snd_motu_protocol_v2_cache_packet_formats(motu);
 264        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V3)
 265                return snd_motu_protocol_v3_cache_packet_formats(motu);
 266        else if (motu->spec->protocol_version == SND_MOTU_PROTOCOL_V1)
 267                return snd_motu_protocol_v1_cache_packet_formats(motu);
 268        else
 269                return -ENXIO;
 270}
 271
 272#endif
 273