linux/sound/firewire/tascam/tascam.h
<<
>>
Prefs
   1/*
   2 * tascam.h - a part of driver for TASCAM FireWire series
   3 *
   4 * Copyright (c) 2015 Takashi Sakamoto
   5 *
   6 * Licensed under the terms of the GNU General Public License, version 2.
   7 */
   8
   9#ifndef SOUND_TASCAM_H_INCLUDED
  10#define SOUND_TASCAM_H_INCLUDED
  11
  12#include <linux/device.h>
  13#include <linux/firewire.h>
  14#include <linux/firewire-constants.h>
  15#include <linux/module.h>
  16#include <linux/mod_devicetable.h>
  17#include <linux/mutex.h>
  18#include <linux/slab.h>
  19#include <linux/compat.h>
  20#include <linux/sched/signal.h>
  21
  22#include <sound/core.h>
  23#include <sound/initval.h>
  24#include <sound/info.h>
  25#include <sound/pcm.h>
  26#include <sound/pcm_params.h>
  27#include <sound/firewire.h>
  28#include <sound/hwdep.h>
  29#include <sound/rawmidi.h>
  30
  31#include "../lib.h"
  32#include "../amdtp-stream.h"
  33#include "../iso-resources.h"
  34
  35struct snd_tscm_spec {
  36        const char *const name;
  37        bool has_adat;
  38        bool has_spdif;
  39        unsigned int pcm_capture_analog_channels;
  40        unsigned int pcm_playback_analog_channels;
  41        unsigned int midi_capture_ports;
  42        unsigned int midi_playback_ports;
  43};
  44
  45#define TSCM_MIDI_IN_PORT_MAX   4
  46#define TSCM_MIDI_OUT_PORT_MAX  4
  47
  48struct snd_fw_async_midi_port {
  49        struct fw_device *parent;
  50        struct work_struct work;
  51        bool idling;
  52        ktime_t next_ktime;
  53        bool error;
  54
  55        struct fw_transaction transaction;
  56
  57        u8 buf[4];
  58        u8 running_status;
  59        bool on_sysex;
  60
  61        struct snd_rawmidi_substream *substream;
  62        int consume_bytes;
  63};
  64
  65struct snd_tscm {
  66        struct snd_card *card;
  67        struct fw_unit *unit;
  68
  69        struct mutex mutex;
  70        spinlock_t lock;
  71
  72        bool registered;
  73        struct delayed_work dwork;
  74        const struct snd_tscm_spec *spec;
  75
  76        struct fw_iso_resources tx_resources;
  77        struct fw_iso_resources rx_resources;
  78        struct amdtp_stream tx_stream;
  79        struct amdtp_stream rx_stream;
  80        unsigned int substreams_counter;
  81
  82        int dev_lock_count;
  83        bool dev_lock_changed;
  84        wait_queue_head_t hwdep_wait;
  85
  86        /* For MIDI message incoming transactions. */
  87        struct fw_address_handler async_handler;
  88        struct snd_rawmidi_substream *tx_midi_substreams[TSCM_MIDI_IN_PORT_MAX];
  89
  90        /* For MIDI message outgoing transactions. */
  91        struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX];
  92};
  93
  94#define TSCM_ADDR_BASE                  0xffff00000000ull
  95
  96#define TSCM_OFFSET_FIRMWARE_REGISTER   0x0000
  97#define TSCM_OFFSET_FIRMWARE_FPGA       0x0004
  98#define TSCM_OFFSET_FIRMWARE_ARM        0x0008
  99#define TSCM_OFFSET_FIRMWARE_HW         0x000c
 100
 101#define TSCM_OFFSET_ISOC_TX_CH          0x0200
 102#define TSCM_OFFSET_UNKNOWN             0x0204
 103#define TSCM_OFFSET_START_STREAMING     0x0208
 104#define TSCM_OFFSET_ISOC_RX_CH          0x020c
 105#define TSCM_OFFSET_ISOC_RX_ON          0x0210  /* Little conviction. */
 106#define TSCM_OFFSET_TX_PCM_CHANNELS     0x0214
 107#define TSCM_OFFSET_RX_PCM_CHANNELS     0x0218
 108#define TSCM_OFFSET_MULTIPLEX_MODE      0x021c
 109#define TSCM_OFFSET_ISOC_TX_ON          0x0220
 110/* Unknown                              0x0224 */
 111#define TSCM_OFFSET_CLOCK_STATUS        0x0228
 112#define TSCM_OFFSET_SET_OPTION          0x022c
 113
 114#define TSCM_OFFSET_MIDI_TX_ON          0x0300
 115#define TSCM_OFFSET_MIDI_TX_ADDR_HI     0x0304
 116#define TSCM_OFFSET_MIDI_TX_ADDR_LO     0x0308
 117
 118#define TSCM_OFFSET_LED_POWER           0x0404
 119
 120#define TSCM_OFFSET_MIDI_RX_QUAD        0x4000
 121
 122enum snd_tscm_clock {
 123        SND_TSCM_CLOCK_INTERNAL = 0,
 124        SND_TSCM_CLOCK_WORD     = 1,
 125        SND_TSCM_CLOCK_SPDIF    = 2,
 126        SND_TSCM_CLOCK_ADAT     = 3,
 127};
 128
 129int amdtp_tscm_init(struct amdtp_stream *s, struct fw_unit *unit,
 130                  enum amdtp_stream_direction dir, unsigned int pcm_channels);
 131int amdtp_tscm_set_parameters(struct amdtp_stream *s, unsigned int rate);
 132int amdtp_tscm_add_pcm_hw_constraints(struct amdtp_stream *s,
 133                                      struct snd_pcm_runtime *runtime);
 134
 135int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate);
 136int snd_tscm_stream_get_clock(struct snd_tscm *tscm,
 137                              enum snd_tscm_clock *clock);
 138int snd_tscm_stream_init_duplex(struct snd_tscm *tscm);
 139void snd_tscm_stream_update_duplex(struct snd_tscm *tscm);
 140void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm);
 141int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate);
 142void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm);
 143
 144void snd_tscm_stream_lock_changed(struct snd_tscm *tscm);
 145int snd_tscm_stream_lock_try(struct snd_tscm *tscm);
 146void snd_tscm_stream_lock_release(struct snd_tscm *tscm);
 147
 148void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port);
 149
 150static inline void
 151snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
 152                           struct snd_rawmidi_substream *substream)
 153{
 154        if (!port->error) {
 155                port->substream = substream;
 156                schedule_work(&port->work);
 157        }
 158}
 159
 160static inline void
 161snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
 162{
 163        port->substream = NULL;
 164        cancel_work_sync(&port->work);
 165        port->error = false;
 166}
 167
 168int snd_tscm_transaction_register(struct snd_tscm *tscm);
 169int snd_tscm_transaction_reregister(struct snd_tscm *tscm);
 170void snd_tscm_transaction_unregister(struct snd_tscm *tscm);
 171
 172void snd_tscm_proc_init(struct snd_tscm *tscm);
 173
 174int snd_tscm_create_pcm_devices(struct snd_tscm *tscm);
 175
 176int snd_tscm_create_midi_devices(struct snd_tscm *tscm);
 177
 178int snd_tscm_create_hwdep_device(struct snd_tscm *tscm);
 179
 180#endif
 181