1/*
2 * dice.h - a part of driver for Dice based devices
3 *
4 * Copyright (c) Clemens Ladisch
5 * Copyright (c) 2014 Takashi Sakamoto
6 *
7 * Licensed under the terms of the GNU General Public License, version 2.
8 */
9
10#ifndef SOUND_DICE_H_INCLUDED
11#define SOUND_DICE_H_INCLUDED
12
13#include <linux/compat.h>
14#include <linux/completion.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/firewire.h>
18#include <linux/firewire-constants.h>
19#include <linux/jiffies.h>
20#include <linux/module.h>
21#include <linux/mod_devicetable.h>
22#include <linux/mutex.h>
23#include <linux/slab.h>
24#include <linux/spinlock.h>
25#include <linux/wait.h>
26
27#include <sound/control.h>
28#include <sound/core.h>
29#include <sound/firewire.h>
30#include <sound/hwdep.h>
31#include <sound/info.h>
32#include <sound/initval.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/rawmidi.h>
36
37#include "../amdtp.h"
38#include "../iso-resources.h"
39#include "../lib.h"
40#include "dice-interface.h"
41
42struct snd_dice {
43	struct snd_card *card;
44	struct fw_unit *unit;
45	spinlock_t lock;
46	struct mutex mutex;
47
48	/* Offsets for sub-addresses */
49	unsigned int global_offset;
50	unsigned int rx_offset;
51	unsigned int tx_offset;
52	unsigned int sync_offset;
53	unsigned int rsrv_offset;
54
55	unsigned int clock_caps;
56	unsigned int tx_channels[3];
57	unsigned int rx_channels[3];
58	unsigned int tx_midi_ports[3];
59	unsigned int rx_midi_ports[3];
60
61	struct fw_address_handler notification_handler;
62	int owner_generation;
63	u32 notification_bits;
64
65	/* For uapi */
66	int dev_lock_count; /* > 0 driver, < 0 userspace */
67	bool dev_lock_changed;
68	wait_queue_head_t hwdep_wait;
69
70	/* For streaming */
71	struct fw_iso_resources tx_resources;
72	struct fw_iso_resources rx_resources;
73	struct amdtp_stream tx_stream;
74	struct amdtp_stream rx_stream;
75	bool global_enabled;
76	struct completion clock_accepted;
77	unsigned int substreams_counter;
78};
79
80enum snd_dice_addr_type {
81	SND_DICE_ADDR_TYPE_PRIVATE,
82	SND_DICE_ADDR_TYPE_GLOBAL,
83	SND_DICE_ADDR_TYPE_TX,
84	SND_DICE_ADDR_TYPE_RX,
85	SND_DICE_ADDR_TYPE_SYNC,
86	SND_DICE_ADDR_TYPE_RSRV,
87};
88
89int snd_dice_transaction_write(struct snd_dice *dice,
90			       enum snd_dice_addr_type type,
91			       unsigned int offset,
92			       void *buf, unsigned int len);
93int snd_dice_transaction_read(struct snd_dice *dice,
94			      enum snd_dice_addr_type type, unsigned int offset,
95			      void *buf, unsigned int len);
96
97static inline int snd_dice_transaction_write_global(struct snd_dice *dice,
98						    unsigned int offset,
99						    void *buf, unsigned int len)
100{
101	return snd_dice_transaction_write(dice,
102					  SND_DICE_ADDR_TYPE_GLOBAL, offset,
103					  buf, len);
104}
105static inline int snd_dice_transaction_read_global(struct snd_dice *dice,
106						   unsigned int offset,
107						   void *buf, unsigned int len)
108{
109	return snd_dice_transaction_read(dice,
110					 SND_DICE_ADDR_TYPE_GLOBAL, offset,
111					 buf, len);
112}
113static inline int snd_dice_transaction_write_tx(struct snd_dice *dice,
114						unsigned int offset,
115						void *buf, unsigned int len)
116{
117	return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_TX, offset,
118					  buf, len);
119}
120static inline int snd_dice_transaction_read_tx(struct snd_dice *dice,
121					       unsigned int offset,
122					       void *buf, unsigned int len)
123{
124	return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_TX, offset,
125					 buf, len);
126}
127static inline int snd_dice_transaction_write_rx(struct snd_dice *dice,
128						unsigned int offset,
129						void *buf, unsigned int len)
130{
131	return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_RX, offset,
132					  buf, len);
133}
134static inline int snd_dice_transaction_read_rx(struct snd_dice *dice,
135					       unsigned int offset,
136					       void *buf, unsigned int len)
137{
138	return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_RX, offset,
139					 buf, len);
140}
141static inline int snd_dice_transaction_write_sync(struct snd_dice *dice,
142						  unsigned int offset,
143						  void *buf, unsigned int len)
144{
145	return snd_dice_transaction_write(dice, SND_DICE_ADDR_TYPE_SYNC, offset,
146					  buf, len);
147}
148static inline int snd_dice_transaction_read_sync(struct snd_dice *dice,
149						 unsigned int offset,
150						 void *buf, unsigned int len)
151{
152	return snd_dice_transaction_read(dice, SND_DICE_ADDR_TYPE_SYNC, offset,
153					 buf, len);
154}
155
156int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
157					  unsigned int *source);
158int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate);
159int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate);
160int snd_dice_transaction_set_enable(struct snd_dice *dice);
161void snd_dice_transaction_clear_enable(struct snd_dice *dice);
162int snd_dice_transaction_init(struct snd_dice *dice);
163int snd_dice_transaction_reinit(struct snd_dice *dice);
164void snd_dice_transaction_destroy(struct snd_dice *dice);
165
166#define SND_DICE_RATES_COUNT	7
167extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
168
169int snd_dice_stream_get_rate_mode(struct snd_dice *dice,
170				  unsigned int rate, unsigned int *mode);
171
172int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate);
173void snd_dice_stream_stop_duplex(struct snd_dice *dice);
174int snd_dice_stream_init_duplex(struct snd_dice *dice);
175void snd_dice_stream_destroy_duplex(struct snd_dice *dice);
176void snd_dice_stream_update_duplex(struct snd_dice *dice);
177
178int snd_dice_stream_lock_try(struct snd_dice *dice);
179void snd_dice_stream_lock_release(struct snd_dice *dice);
180
181int snd_dice_create_pcm(struct snd_dice *dice);
182
183int snd_dice_create_hwdep(struct snd_dice *dice);
184
185void snd_dice_create_proc(struct snd_dice *dice);
186
187int snd_dice_create_midi(struct snd_dice *dice);
188
189#endif
190