Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * oxfw.h - a part of driver for OXFW970/971 based devices
0004  *
0005  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/firewire.h>
0010 #include <linux/firewire-constants.h>
0011 #include <linux/module.h>
0012 #include <linux/mod_devicetable.h>
0013 #include <linux/mutex.h>
0014 #include <linux/slab.h>
0015 #include <linux/compat.h>
0016 #include <linux/sched/signal.h>
0017 
0018 #include <sound/control.h>
0019 #include <sound/core.h>
0020 #include <sound/initval.h>
0021 #include <sound/pcm.h>
0022 #include <sound/pcm_params.h>
0023 #include <sound/info.h>
0024 #include <sound/rawmidi.h>
0025 #include <sound/firewire.h>
0026 #include <sound/hwdep.h>
0027 
0028 #include "../lib.h"
0029 #include "../fcp.h"
0030 #include "../packets-buffer.h"
0031 #include "../iso-resources.h"
0032 #include "../amdtp-am824.h"
0033 #include "../cmp.h"
0034 
0035 enum snd_oxfw_quirk {
0036     // Postpone transferring packets during handling asynchronous transaction. As a result,
0037     // next isochronous packet includes more events than one packet can include.
0038     SND_OXFW_QUIRK_JUMBO_PAYLOAD = 0x01,
0039     // The dbs field of CIP header in tx packet is wrong.
0040     SND_OXFW_QUIRK_WRONG_DBS = 0x02,
0041     // Blocking transmission mode is used.
0042     SND_OXFW_QUIRK_BLOCKING_TRANSMISSION = 0x04,
0043     // Stanton SCS1.d and SCS1.m support unique transaction.
0044     SND_OXFW_QUIRK_SCS_TRANSACTION = 0x08,
0045     // Apogee Duet FireWire ignores data blocks in packet with NO_INFO for audio data
0046     // processing, while output level meter moves. Any value in syt field of packet takes
0047     // the device to process audio data even if the value is invalid in a point of
0048     // IEC 61883-1/6.
0049     SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET = 0x10,
0050     // Loud Technologies Mackie Onyx 1640i seems to configure OXFW971 ASIC so that it decides
0051     // event frequency according to events in received isochronous packets. The device looks to
0052     // performs media clock recovery voluntarily. In the recovery, the packets with NO_INFO
0053     // are ignored, thus driver should transfer packets with timestamp.
0054     SND_OXFW_QUIRK_VOLUNTARY_RECOVERY = 0x20,
0055 };
0056 
0057 /* This is an arbitrary number for convinience. */
0058 #define SND_OXFW_STREAM_FORMAT_ENTRIES  10
0059 struct snd_oxfw {
0060     struct snd_card *card;
0061     struct fw_unit *unit;
0062     struct mutex mutex;
0063     spinlock_t lock;
0064 
0065     // The combination of snd_oxfw_quirk enumeration-constants.
0066     unsigned int quirks;
0067     bool has_output;
0068     bool has_input;
0069     u8 *tx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
0070     u8 *rx_stream_formats[SND_OXFW_STREAM_FORMAT_ENTRIES];
0071     bool assumed;
0072     struct cmp_connection out_conn;
0073     struct cmp_connection in_conn;
0074     struct amdtp_stream tx_stream;
0075     struct amdtp_stream rx_stream;
0076     unsigned int substreams_count;
0077 
0078     unsigned int midi_input_ports;
0079     unsigned int midi_output_ports;
0080 
0081     int dev_lock_count;
0082     bool dev_lock_changed;
0083     wait_queue_head_t hwdep_wait;
0084 
0085     void *spec;
0086 
0087     struct amdtp_domain domain;
0088 };
0089 
0090 /*
0091  * AV/C Stream Format Information Specification 1.1 Working Draft
0092  * (Apr 2005, 1394TA)
0093  */
0094 int avc_stream_set_format(struct fw_unit *unit, enum avc_general_plug_dir dir,
0095               unsigned int pid, u8 *format, unsigned int len);
0096 int avc_stream_get_format(struct fw_unit *unit,
0097               enum avc_general_plug_dir dir, unsigned int pid,
0098               u8 *buf, unsigned int *len, unsigned int eid);
0099 static inline int
0100 avc_stream_get_format_single(struct fw_unit *unit,
0101                  enum avc_general_plug_dir dir, unsigned int pid,
0102                  u8 *buf, unsigned int *len)
0103 {
0104     return avc_stream_get_format(unit, dir, pid, buf, len, 0xff);
0105 }
0106 static inline int
0107 avc_stream_get_format_list(struct fw_unit *unit,
0108                enum avc_general_plug_dir dir, unsigned int pid,
0109                u8 *buf, unsigned int *len,
0110                unsigned int eid)
0111 {
0112     return avc_stream_get_format(unit, dir, pid, buf, len, eid);
0113 }
0114 
0115 /*
0116  * AV/C Digital Interface Command Set General Specification 4.2
0117  * (Sep 2004, 1394TA)
0118  */
0119 int avc_general_inquiry_sig_fmt(struct fw_unit *unit, unsigned int rate,
0120                 enum avc_general_plug_dir dir,
0121                 unsigned short pid);
0122 
0123 int snd_oxfw_stream_init_duplex(struct snd_oxfw *oxfw);
0124 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw,
0125                    struct amdtp_stream *stream,
0126                    unsigned int rate, unsigned int pcm_channels,
0127                    unsigned int frames_per_period,
0128                    unsigned int frames_per_buffer);
0129 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw);
0130 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw);
0131 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw);
0132 void snd_oxfw_stream_update_duplex(struct snd_oxfw *oxfw);
0133 
0134 struct snd_oxfw_stream_formation {
0135     unsigned int rate;
0136     unsigned int pcm;
0137     unsigned int midi;
0138 };
0139 int snd_oxfw_stream_parse_format(u8 *format,
0140                  struct snd_oxfw_stream_formation *formation);
0141 int snd_oxfw_stream_get_current_formation(struct snd_oxfw *oxfw,
0142                 enum avc_general_plug_dir dir,
0143                 struct snd_oxfw_stream_formation *formation);
0144 
0145 int snd_oxfw_stream_discover(struct snd_oxfw *oxfw);
0146 
0147 void snd_oxfw_stream_lock_changed(struct snd_oxfw *oxfw);
0148 int snd_oxfw_stream_lock_try(struct snd_oxfw *oxfw);
0149 void snd_oxfw_stream_lock_release(struct snd_oxfw *oxfw);
0150 
0151 int snd_oxfw_create_pcm(struct snd_oxfw *oxfw);
0152 
0153 void snd_oxfw_proc_init(struct snd_oxfw *oxfw);
0154 
0155 int snd_oxfw_create_midi(struct snd_oxfw *oxfw);
0156 
0157 int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw);
0158 
0159 int snd_oxfw_add_spkr(struct snd_oxfw *oxfw, bool is_lacie);
0160 int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw);
0161 void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw);