162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Line 6 Linux USB driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef DRIVER_H 962306a36Sopenharmony_ci#define DRIVER_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/usb.h> 1262306a36Sopenharmony_ci#include <linux/mutex.h> 1362306a36Sopenharmony_ci#include <linux/kfifo.h> 1462306a36Sopenharmony_ci#include <sound/core.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "midi.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* USB 1.1 speed configuration */ 1962306a36Sopenharmony_ci#define USB_LOW_INTERVALS_PER_SECOND 1000 2062306a36Sopenharmony_ci#define USB_LOW_ISO_BUFFERS 2 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* USB 2.0+ speed configuration */ 2362306a36Sopenharmony_ci#define USB_HIGH_INTERVALS_PER_SECOND 8000 2462306a36Sopenharmony_ci#define USB_HIGH_ISO_BUFFERS 16 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/* Fallback USB interval and max packet size values */ 2762306a36Sopenharmony_ci#define LINE6_FALLBACK_INTERVAL 10 2862306a36Sopenharmony_ci#define LINE6_FALLBACK_MAXPACKETSIZE 16 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define LINE6_TIMEOUT 1000 3162306a36Sopenharmony_ci#define LINE6_BUFSIZE_LISTEN 64 3262306a36Sopenharmony_ci#define LINE6_MIDI_MESSAGE_MAXLEN 256 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define LINE6_RAW_MESSAGES_MAXCOUNT_ORDER 7 3562306a36Sopenharmony_ci/* 4k packets are common, BUFSIZE * MAXCOUNT should be bigger... */ 3662306a36Sopenharmony_ci#define LINE6_RAW_MESSAGES_MAXCOUNT (1 << LINE6_RAW_MESSAGES_MAXCOUNT_ORDER) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#if LINE6_BUFSIZE_LISTEN > 65535 4062306a36Sopenharmony_ci#error "Use dynamic fifo instead" 4162306a36Sopenharmony_ci#endif 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* 4462306a36Sopenharmony_ci Line 6 MIDI control commands 4562306a36Sopenharmony_ci*/ 4662306a36Sopenharmony_ci#define LINE6_PARAM_CHANGE 0xb0 4762306a36Sopenharmony_ci#define LINE6_PROGRAM_CHANGE 0xc0 4862306a36Sopenharmony_ci#define LINE6_SYSEX_BEGIN 0xf0 4962306a36Sopenharmony_ci#define LINE6_SYSEX_END 0xf7 5062306a36Sopenharmony_ci#define LINE6_RESET 0xff 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* 5362306a36Sopenharmony_ci MIDI channel for messages initiated by the host 5462306a36Sopenharmony_ci (and eventually echoed back by the device) 5562306a36Sopenharmony_ci*/ 5662306a36Sopenharmony_ci#define LINE6_CHANNEL_HOST 0x00 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* 5962306a36Sopenharmony_ci MIDI channel for messages initiated by the device 6062306a36Sopenharmony_ci*/ 6162306a36Sopenharmony_ci#define LINE6_CHANNEL_DEVICE 0x02 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */ 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#define LINE6_CHANNEL_MASK 0x0f 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ciextern const unsigned char line6_midi_id[3]; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci#define SYSEX_DATA_OFS (sizeof(line6_midi_id) + 3) 7062306a36Sopenharmony_ci#define SYSEX_EXTRA_SIZE (sizeof(line6_midi_id) + 4) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* 7362306a36Sopenharmony_ci Common properties of Line 6 devices. 7462306a36Sopenharmony_ci*/ 7562306a36Sopenharmony_cistruct line6_properties { 7662306a36Sopenharmony_ci /* Card id string (maximum 16 characters). 7762306a36Sopenharmony_ci * This can be used to address the device in ALSA programs as 7862306a36Sopenharmony_ci * "default:CARD=<id>" 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci const char *id; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci /* Card short name (maximum 32 characters) */ 8362306a36Sopenharmony_ci const char *name; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci /* Bit vector defining this device's capabilities in line6usb driver */ 8662306a36Sopenharmony_ci int capabilities; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci int altsetting; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci unsigned int ctrl_if; 9162306a36Sopenharmony_ci unsigned int ep_ctrl_r; 9262306a36Sopenharmony_ci unsigned int ep_ctrl_w; 9362306a36Sopenharmony_ci unsigned int ep_audio_r; 9462306a36Sopenharmony_ci unsigned int ep_audio_w; 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* Capability bits */ 9862306a36Sopenharmony_cienum { 9962306a36Sopenharmony_ci /* device supports settings parameter via USB */ 10062306a36Sopenharmony_ci LINE6_CAP_CONTROL = 1 << 0, 10162306a36Sopenharmony_ci /* device supports PCM input/output via USB */ 10262306a36Sopenharmony_ci LINE6_CAP_PCM = 1 << 1, 10362306a36Sopenharmony_ci /* device supports hardware monitoring */ 10462306a36Sopenharmony_ci LINE6_CAP_HWMON = 1 << 2, 10562306a36Sopenharmony_ci /* device requires output data when input is read */ 10662306a36Sopenharmony_ci LINE6_CAP_IN_NEEDS_OUT = 1 << 3, 10762306a36Sopenharmony_ci /* device uses raw MIDI via USB (data endpoints) */ 10862306a36Sopenharmony_ci LINE6_CAP_CONTROL_MIDI = 1 << 4, 10962306a36Sopenharmony_ci /* device provides low-level information */ 11062306a36Sopenharmony_ci LINE6_CAP_CONTROL_INFO = 1 << 5, 11162306a36Sopenharmony_ci /* device provides hardware monitoring volume control */ 11262306a36Sopenharmony_ci LINE6_CAP_HWMON_CTL = 1 << 6, 11362306a36Sopenharmony_ci}; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/* 11662306a36Sopenharmony_ci Common data shared by all Line 6 devices. 11762306a36Sopenharmony_ci Corresponds to a pair of USB endpoints. 11862306a36Sopenharmony_ci*/ 11962306a36Sopenharmony_cistruct usb_line6 { 12062306a36Sopenharmony_ci /* USB device */ 12162306a36Sopenharmony_ci struct usb_device *usbdev; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci /* Properties */ 12462306a36Sopenharmony_ci const struct line6_properties *properties; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci /* Interval for data USB packets */ 12762306a36Sopenharmony_ci int interval; 12862306a36Sopenharmony_ci /* ...for isochronous transfers framing */ 12962306a36Sopenharmony_ci int intervals_per_second; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* Number of isochronous URBs used for frame transfers */ 13262306a36Sopenharmony_ci int iso_buffers; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* Maximum size of data USB packet */ 13562306a36Sopenharmony_ci int max_packet_size; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci /* Device representing the USB interface */ 13862306a36Sopenharmony_ci struct device *ifcdev; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci /* Line 6 sound card data structure. 14162306a36Sopenharmony_ci * Each device has at least MIDI or PCM. 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_ci struct snd_card *card; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci /* Line 6 PCM device data structure */ 14662306a36Sopenharmony_ci struct snd_line6_pcm *line6pcm; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci /* Line 6 MIDI device data structure */ 14962306a36Sopenharmony_ci struct snd_line6_midi *line6midi; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci /* URB for listening to POD data endpoint */ 15262306a36Sopenharmony_ci struct urb *urb_listen; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* Buffer for incoming data from POD data endpoint */ 15562306a36Sopenharmony_ci unsigned char *buffer_listen; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci /* Buffer for message to be processed, generated from MIDI layer */ 15862306a36Sopenharmony_ci unsigned char *buffer_message; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci /* Length of message to be processed, generated from MIDI layer */ 16162306a36Sopenharmony_ci int message_length; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* Circular buffer for non-MIDI control messages */ 16462306a36Sopenharmony_ci struct { 16562306a36Sopenharmony_ci struct mutex read_lock; 16662306a36Sopenharmony_ci wait_queue_head_t wait_queue; 16762306a36Sopenharmony_ci unsigned int active:1; 16862306a36Sopenharmony_ci unsigned int nonblock:1; 16962306a36Sopenharmony_ci STRUCT_KFIFO_REC_2(LINE6_BUFSIZE_LISTEN * LINE6_RAW_MESSAGES_MAXCOUNT) 17062306a36Sopenharmony_ci fifo; 17162306a36Sopenharmony_ci } messages; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci /* Work for delayed PCM startup */ 17462306a36Sopenharmony_ci struct delayed_work startup_work; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* If MIDI is supported, buffer_message contains the pre-processed data; 17762306a36Sopenharmony_ci * otherwise the data is only in urb_listen (buffer_incoming). 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ci void (*process_message)(struct usb_line6 *); 18062306a36Sopenharmony_ci void (*disconnect)(struct usb_line6 *line6); 18162306a36Sopenharmony_ci void (*startup)(struct usb_line6 *line6); 18262306a36Sopenharmony_ci}; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ciextern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, 18562306a36Sopenharmony_ci int code2, int size); 18662306a36Sopenharmony_ciextern int line6_read_data(struct usb_line6 *line6, unsigned address, 18762306a36Sopenharmony_ci void *data, unsigned datalen); 18862306a36Sopenharmony_ciextern int line6_read_serial_number(struct usb_line6 *line6, 18962306a36Sopenharmony_ci u32 *serial_number); 19062306a36Sopenharmony_ciextern int line6_send_raw_message(struct usb_line6 *line6, 19162306a36Sopenharmony_ci const char *buffer, int size); 19262306a36Sopenharmony_ciextern int line6_send_raw_message_async(struct usb_line6 *line6, 19362306a36Sopenharmony_ci const char *buffer, int size); 19462306a36Sopenharmony_ciextern int line6_send_sysex_message(struct usb_line6 *line6, 19562306a36Sopenharmony_ci const char *buffer, int size); 19662306a36Sopenharmony_ciextern int line6_version_request_async(struct usb_line6 *line6); 19762306a36Sopenharmony_ciextern int line6_write_data(struct usb_line6 *line6, unsigned address, 19862306a36Sopenharmony_ci void *data, unsigned datalen); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ciint line6_probe(struct usb_interface *interface, 20162306a36Sopenharmony_ci const struct usb_device_id *id, 20262306a36Sopenharmony_ci const char *driver_name, 20362306a36Sopenharmony_ci const struct line6_properties *properties, 20462306a36Sopenharmony_ci int (*private_init)(struct usb_line6 *, const struct usb_device_id *id), 20562306a36Sopenharmony_ci size_t data_size); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_civoid line6_disconnect(struct usb_interface *interface); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#ifdef CONFIG_PM 21062306a36Sopenharmony_ciint line6_suspend(struct usb_interface *interface, pm_message_t message); 21162306a36Sopenharmony_ciint line6_resume(struct usb_interface *interface); 21262306a36Sopenharmony_ci#endif 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#endif 215