xref: /openbmc/linux/sound/firewire/dice/dice.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1da607e19SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
27c2d4c0cSTakashi Sakamoto /*
37c2d4c0cSTakashi Sakamoto  * dice.h - a part of driver for Dice based devices
47c2d4c0cSTakashi Sakamoto  *
57c2d4c0cSTakashi Sakamoto  * Copyright (c) Clemens Ladisch
67c2d4c0cSTakashi Sakamoto  * Copyright (c) 2014 Takashi Sakamoto
77c2d4c0cSTakashi Sakamoto  */
87c2d4c0cSTakashi Sakamoto 
97c2d4c0cSTakashi Sakamoto #ifndef SOUND_DICE_H_INCLUDED
107c2d4c0cSTakashi Sakamoto #define SOUND_DICE_H_INCLUDED
117c2d4c0cSTakashi Sakamoto 
127c2d4c0cSTakashi Sakamoto #include <linux/compat.h>
137c2d4c0cSTakashi Sakamoto #include <linux/completion.h>
147c2d4c0cSTakashi Sakamoto #include <linux/delay.h>
157c2d4c0cSTakashi Sakamoto #include <linux/device.h>
167c2d4c0cSTakashi Sakamoto #include <linux/firewire.h>
177c2d4c0cSTakashi Sakamoto #include <linux/firewire-constants.h>
187c2d4c0cSTakashi Sakamoto #include <linux/jiffies.h>
197c2d4c0cSTakashi Sakamoto #include <linux/module.h>
207c2d4c0cSTakashi Sakamoto #include <linux/mod_devicetable.h>
217c2d4c0cSTakashi Sakamoto #include <linux/mutex.h>
227c2d4c0cSTakashi Sakamoto #include <linux/slab.h>
237c2d4c0cSTakashi Sakamoto #include <linux/spinlock.h>
247c2d4c0cSTakashi Sakamoto #include <linux/wait.h>
25174cd4b1SIngo Molnar #include <linux/sched/signal.h>
267c2d4c0cSTakashi Sakamoto 
277c2d4c0cSTakashi Sakamoto #include <sound/control.h>
287c2d4c0cSTakashi Sakamoto #include <sound/core.h>
297c2d4c0cSTakashi Sakamoto #include <sound/firewire.h>
307c2d4c0cSTakashi Sakamoto #include <sound/hwdep.h>
317c2d4c0cSTakashi Sakamoto #include <sound/info.h>
327c2d4c0cSTakashi Sakamoto #include <sound/initval.h>
337c2d4c0cSTakashi Sakamoto #include <sound/pcm.h>
347c2d4c0cSTakashi Sakamoto #include <sound/pcm_params.h>
35a113ff88STakashi Sakamoto #include <sound/rawmidi.h>
367c2d4c0cSTakashi Sakamoto 
375955815eSTakashi Sakamoto #include "../amdtp-am824.h"
387c2d4c0cSTakashi Sakamoto #include "../iso-resources.h"
397c2d4c0cSTakashi Sakamoto #include "../lib.h"
407c2d4c0cSTakashi Sakamoto #include "dice-interface.h"
417c2d4c0cSTakashi Sakamoto 
428ae25b76STakashi Sakamoto /*
438ae25b76STakashi Sakamoto  * This module support maximum 2 pairs of tx/rx isochronous streams for
448ae25b76STakashi Sakamoto  * our convinience.
458ae25b76STakashi Sakamoto  *
468ae25b76STakashi Sakamoto  * In documents for ASICs called with a name of 'DICE':
478ae25b76STakashi Sakamoto  *  - ASIC for DICE II:
488ae25b76STakashi Sakamoto  *   - Maximum 2 tx and 4 rx are supported.
498ae25b76STakashi Sakamoto  *   - A packet supports maximum 16 data channels.
508ae25b76STakashi Sakamoto  *  - TCD2210/2210-E (so-called 'Dice Mini'):
518ae25b76STakashi Sakamoto  *   - Maximum 2 tx and 2 rx are supported.
528ae25b76STakashi Sakamoto  *   - A packet supports maximum 16 data channels.
538ae25b76STakashi Sakamoto  *  - TCD2220/2220-E (so-called 'Dice Jr.')
548ae25b76STakashi Sakamoto  *   - 2 tx and 2 rx are supported.
558ae25b76STakashi Sakamoto  *   - A packet supports maximum 16 data channels.
568ae25b76STakashi Sakamoto  *  - TCD3070-CH (so-called 'Dice III')
578ae25b76STakashi Sakamoto  *   - Maximum 2 tx and 2 rx are supported.
588ae25b76STakashi Sakamoto  *   - A packet supports maximum 32 data channels.
598ae25b76STakashi Sakamoto  *
608ae25b76STakashi Sakamoto  * For the above, MIDI conformant data channel is just on the first isochronous
618ae25b76STakashi Sakamoto  * stream.
628ae25b76STakashi Sakamoto  */
638ae25b76STakashi Sakamoto #define MAX_STREAMS	2
648ae25b76STakashi Sakamoto 
658feda7ddSTakashi Sakamoto enum snd_dice_rate_mode {
668feda7ddSTakashi Sakamoto 	SND_DICE_RATE_MODE_LOW = 0,
678feda7ddSTakashi Sakamoto 	SND_DICE_RATE_MODE_MIDDLE,
688feda7ddSTakashi Sakamoto 	SND_DICE_RATE_MODE_HIGH,
698feda7ddSTakashi Sakamoto 	SND_DICE_RATE_MODE_COUNT,
708feda7ddSTakashi Sakamoto };
718feda7ddSTakashi Sakamoto 
72f1f0f330STakashi Sakamoto struct snd_dice;
73f1f0f330STakashi Sakamoto typedef int (*snd_dice_detect_formats_t)(struct snd_dice *dice);
74f1f0f330STakashi Sakamoto 
757c2d4c0cSTakashi Sakamoto struct snd_dice {
767c2d4c0cSTakashi Sakamoto 	struct snd_card *card;
777c2d4c0cSTakashi Sakamoto 	struct fw_unit *unit;
787c2d4c0cSTakashi Sakamoto 	spinlock_t lock;
797c2d4c0cSTakashi Sakamoto 	struct mutex mutex;
807c2d4c0cSTakashi Sakamoto 
817c2d4c0cSTakashi Sakamoto 	/* Offsets for sub-addresses */
827c2d4c0cSTakashi Sakamoto 	unsigned int global_offset;
837c2d4c0cSTakashi Sakamoto 	unsigned int rx_offset;
847c2d4c0cSTakashi Sakamoto 	unsigned int tx_offset;
857c2d4c0cSTakashi Sakamoto 	unsigned int sync_offset;
867c2d4c0cSTakashi Sakamoto 	unsigned int rsrv_offset;
877c2d4c0cSTakashi Sakamoto 
887c2d4c0cSTakashi Sakamoto 	unsigned int clock_caps;
898feda7ddSTakashi Sakamoto 	unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
908feda7ddSTakashi Sakamoto 	unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
918feda7ddSTakashi Sakamoto 	unsigned int tx_midi_ports[MAX_STREAMS];
928feda7ddSTakashi Sakamoto 	unsigned int rx_midi_ports[MAX_STREAMS];
939a02843cSTakashi Sakamoto 
947c2d4c0cSTakashi Sakamoto 	struct fw_address_handler notification_handler;
957c2d4c0cSTakashi Sakamoto 	int owner_generation;
969a02843cSTakashi Sakamoto 	u32 notification_bits;
979a02843cSTakashi Sakamoto 
989a02843cSTakashi Sakamoto 	/* For uapi */
997c2d4c0cSTakashi Sakamoto 	int dev_lock_count; /* > 0 driver, < 0 userspace */
1007c2d4c0cSTakashi Sakamoto 	bool dev_lock_changed;
1019a02843cSTakashi Sakamoto 	wait_queue_head_t hwdep_wait;
1029a02843cSTakashi Sakamoto 
1039a02843cSTakashi Sakamoto 	/* For streaming */
1048ae25b76STakashi Sakamoto 	struct fw_iso_resources tx_resources[MAX_STREAMS];
1058ae25b76STakashi Sakamoto 	struct fw_iso_resources rx_resources[MAX_STREAMS];
1068ae25b76STakashi Sakamoto 	struct amdtp_stream tx_stream[MAX_STREAMS];
1078ae25b76STakashi Sakamoto 	struct amdtp_stream rx_stream[MAX_STREAMS];
1089f079c1bSTakashi Sakamoto 	bool global_enabled:1;
1099f079c1bSTakashi Sakamoto 	bool disable_double_pcm_frames:1;
1107c2d4c0cSTakashi Sakamoto 	struct completion clock_accepted;
1119a02843cSTakashi Sakamoto 	unsigned int substreams_counter;
112e9f21129STakashi Sakamoto 
113e9f21129STakashi Sakamoto 	struct amdtp_domain domain;
1147c2d4c0cSTakashi Sakamoto };
1157c2d4c0cSTakashi Sakamoto 
1167c2d4c0cSTakashi Sakamoto enum snd_dice_addr_type {
1177c2d4c0cSTakashi Sakamoto 	SND_DICE_ADDR_TYPE_PRIVATE,
1187c2d4c0cSTakashi Sakamoto 	SND_DICE_ADDR_TYPE_GLOBAL,
1197c2d4c0cSTakashi Sakamoto 	SND_DICE_ADDR_TYPE_TX,
1207c2d4c0cSTakashi Sakamoto 	SND_DICE_ADDR_TYPE_RX,
1217c2d4c0cSTakashi Sakamoto 	SND_DICE_ADDR_TYPE_SYNC,
1227c2d4c0cSTakashi Sakamoto 	SND_DICE_ADDR_TYPE_RSRV,
1237c2d4c0cSTakashi Sakamoto };
1247c2d4c0cSTakashi Sakamoto 
1257c2d4c0cSTakashi Sakamoto int snd_dice_transaction_write(struct snd_dice *dice,
1267c2d4c0cSTakashi Sakamoto 			       enum snd_dice_addr_type type,
1277c2d4c0cSTakashi Sakamoto 			       unsigned int offset,
1287c2d4c0cSTakashi Sakamoto 			       void *buf, unsigned int len);
1297c2d4c0cSTakashi Sakamoto int snd_dice_transaction_read(struct snd_dice *dice,
1307c2d4c0cSTakashi Sakamoto 			      enum snd_dice_addr_type type, unsigned int offset,
1317c2d4c0cSTakashi Sakamoto 			      void *buf, unsigned int len);
1327c2d4c0cSTakashi Sakamoto 
snd_dice_transaction_write_global(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1337c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_write_global(struct snd_dice *dice,
1347c2d4c0cSTakashi Sakamoto 						    unsigned int offset,
1357c2d4c0cSTakashi Sakamoto 						    void *buf, unsigned int len)
1367c2d4c0cSTakashi Sakamoto {
1377c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_write(dice,
1387c2d4c0cSTakashi Sakamoto 					  SND_DICE_ADDR_TYPE_GLOBAL, offset,
1397c2d4c0cSTakashi Sakamoto 					  buf, len);
1407c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_read_global(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1417c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_read_global(struct snd_dice *dice,
1427c2d4c0cSTakashi Sakamoto 						   unsigned int offset,
1437c2d4c0cSTakashi Sakamoto 						   void *buf, unsigned int len)
1447c2d4c0cSTakashi Sakamoto {
1457c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_read(dice,
1467c2d4c0cSTakashi Sakamoto 					 SND_DICE_ADDR_TYPE_GLOBAL, offset,
1477c2d4c0cSTakashi Sakamoto 					 buf, len);
1487c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_write_tx(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1497c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_write_tx(struct snd_dice *dice,
1507c2d4c0cSTakashi Sakamoto 						unsigned int offset,
1517c2d4c0cSTakashi Sakamoto 						void *buf, unsigned int len)
1527c2d4c0cSTakashi Sakamoto {
1537c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_TX, offset,
1547c2d4c0cSTakashi Sakamoto 					  buf, len);
1557c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_read_tx(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1567c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_read_tx(struct snd_dice *dice,
1577c2d4c0cSTakashi Sakamoto 					       unsigned int offset,
1587c2d4c0cSTakashi Sakamoto 					       void *buf, unsigned int len)
1597c2d4c0cSTakashi Sakamoto {
1607c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_TX, offset,
1617c2d4c0cSTakashi Sakamoto 					 buf, len);
1627c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_write_rx(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1637c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_write_rx(struct snd_dice *dice,
1647c2d4c0cSTakashi Sakamoto 						unsigned int offset,
1657c2d4c0cSTakashi Sakamoto 						void *buf, unsigned int len)
1667c2d4c0cSTakashi Sakamoto {
1677c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_RX, offset,
1687c2d4c0cSTakashi Sakamoto 					  buf, len);
1697c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_read_rx(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1707c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_read_rx(struct snd_dice *dice,
1717c2d4c0cSTakashi Sakamoto 					       unsigned int offset,
1727c2d4c0cSTakashi Sakamoto 					       void *buf, unsigned int len)
1737c2d4c0cSTakashi Sakamoto {
1747c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_RX, offset,
1757c2d4c0cSTakashi Sakamoto 					 buf, len);
1767c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_write_sync(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1777c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_write_sync(struct snd_dice *dice,
1787c2d4c0cSTakashi Sakamoto 						  unsigned int offset,
1797c2d4c0cSTakashi Sakamoto 						  void *buf, unsigned int len)
1807c2d4c0cSTakashi Sakamoto {
1817c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_SYNC, offset,
1827c2d4c0cSTakashi Sakamoto 					  buf, len);
1837c2d4c0cSTakashi Sakamoto }
snd_dice_transaction_read_sync(struct snd_dice * dice,unsigned int offset,void * buf,unsigned int len)1847c2d4c0cSTakashi Sakamoto static inline int snd_dice_transaction_read_sync(struct snd_dice *dice,
1857c2d4c0cSTakashi Sakamoto 						 unsigned int offset,
1867c2d4c0cSTakashi Sakamoto 						 void *buf, unsigned int len)
1877c2d4c0cSTakashi Sakamoto {
1887c2d4c0cSTakashi Sakamoto 	return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_SYNC, offset,
1897c2d4c0cSTakashi Sakamoto 					 buf, len);
1907c2d4c0cSTakashi Sakamoto }
1917c2d4c0cSTakashi Sakamoto 
1927c2d4c0cSTakashi Sakamoto int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
1937c2d4c0cSTakashi Sakamoto 					  unsigned int *source);
1947c2d4c0cSTakashi Sakamoto int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate);
1957c2d4c0cSTakashi Sakamoto int snd_dice_transaction_set_enable(struct snd_dice *dice);
1967c2d4c0cSTakashi Sakamoto void snd_dice_transaction_clear_enable(struct snd_dice *dice);
1977c2d4c0cSTakashi Sakamoto int snd_dice_transaction_init(struct snd_dice *dice);
1987c2d4c0cSTakashi Sakamoto int snd_dice_transaction_reinit(struct snd_dice *dice);
1997c2d4c0cSTakashi Sakamoto void snd_dice_transaction_destroy(struct snd_dice *dice);
2007c2d4c0cSTakashi Sakamoto 
2017c2d4c0cSTakashi Sakamoto #define SND_DICE_RATES_COUNT	7
2027c2d4c0cSTakashi Sakamoto extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
2037c2d4c0cSTakashi Sakamoto 
204b60152f7STakashi Sakamoto int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
205b60152f7STakashi Sakamoto 				  enum snd_dice_rate_mode *mode);
2063cd2c2d7STakashi Sakamoto int snd_dice_stream_start_duplex(struct snd_dice *dice);
2079a02843cSTakashi Sakamoto void snd_dice_stream_stop_duplex(struct snd_dice *dice);
2089a02843cSTakashi Sakamoto int snd_dice_stream_init_duplex(struct snd_dice *dice);
2099a02843cSTakashi Sakamoto void snd_dice_stream_destroy_duplex(struct snd_dice *dice);
21094c8101aSTakashi Sakamoto int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate,
211ecb40fd2STakashi Sakamoto 				   unsigned int events_per_period,
212ecb40fd2STakashi Sakamoto 				   unsigned int events_per_buffer);
2139a02843cSTakashi Sakamoto void snd_dice_stream_update_duplex(struct snd_dice *dice);
214b60152f7STakashi Sakamoto int snd_dice_stream_detect_current_formats(struct snd_dice *dice);
2156eb6c81eSTakashi Sakamoto 
2166eb6c81eSTakashi Sakamoto int snd_dice_stream_lock_try(struct snd_dice *dice);
2176eb6c81eSTakashi Sakamoto void snd_dice_stream_lock_release(struct snd_dice *dice);
2186eb6c81eSTakashi Sakamoto 
219c50fb91fSTakashi Sakamoto int snd_dice_create_pcm(struct snd_dice *dice);
220c50fb91fSTakashi Sakamoto 
22119af57b4STakashi Sakamoto int snd_dice_create_hwdep(struct snd_dice *dice);
22219af57b4STakashi Sakamoto 
22304d426a0STakashi Sakamoto void snd_dice_create_proc(struct snd_dice *dice);
22404d426a0STakashi Sakamoto 
225a113ff88STakashi Sakamoto int snd_dice_create_midi(struct snd_dice *dice);
226a113ff88STakashi Sakamoto 
227f1f0f330STakashi Sakamoto int snd_dice_detect_tcelectronic_formats(struct snd_dice *dice);
22828b208f6STakashi Sakamoto int snd_dice_detect_alesis_formats(struct snd_dice *dice);
229791a485fSTakashi Sakamoto int snd_dice_detect_alesis_mastercontrol_formats(struct snd_dice *dice);
23058579c05STakashi Sakamoto int snd_dice_detect_extension_formats(struct snd_dice *dice);
2317c1543f6SMelvin Vermeeren int snd_dice_detect_mytek_formats(struct snd_dice *dice);
232c4580f20STakashi Sakamoto int snd_dice_detect_presonus_formats(struct snd_dice *dice);
2339a08676fSTakashi Sakamoto int snd_dice_detect_harman_formats(struct snd_dice *dice);
2342133dc91STakashi Sakamoto int snd_dice_detect_focusrite_pro40_tcd3070_formats(struct snd_dice *dice);
235*ff7a0b40STakashi Sakamoto int snd_dice_detect_weiss_formats(struct snd_dice *dice);
236f1f0f330STakashi Sakamoto 
2377c2d4c0cSTakashi Sakamoto #endif
238