summaryrefslogtreecommitdiff
path: root/include/linux/soundwire/soundwire.h
blob: 1287d2b73bf8fce662ecf733cdfb57d1dfccc678 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _LINUX_SOUNDWIRE_H
#define _LINUX_SOUNDWIRE_H
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>

extern struct bus_type soundwire_type;

/* Soundwire supports max. of 8 channels per port */
#define SWR_MAX_CHANNEL_NUM	8
/* Soundwire supports max. of 14 ports on each device */
#define SWR_MAX_DEV_PORT_NUM	14
/* Maximum number of slave devices that a master can control */
#define SWR_MAX_DEV_NUM		11
/* Maximum number of ports on master so that it can accomodate all the port
 * configurations of all devices
 */
#define SWR_MAX_MSTR_PORT_NUM	(SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM)

/* Indicates soundwire devices group information */
enum {
	SWR_GROUP_NONE = 0,
	SWR_GROUP_12 = 12,
	SWR_GROUP_13 = 13,
	SWR_BROADCAST = 15,
};

/*
 * struct swr_port_info - represent soundwire frame shape
 * @dev_id: logical device number of the soundwire slave device
 * @port_en: flag indicates whether the port is enabled
 * @port_id: logical port number of the soundwire slave device
 * @offset1: sample offset indicating the offset of the channel
 * from the start of the frame
 * @offset2: channel offset indicating offset between to channels
 * @sinterval: sample interval indicates spacing from one sample
 * event to the next
 * @ch_en: channels in a port that need to be enabled
 * @num_ch: number of channels enabled in a port
 * @ch_rate: sampling rate of the channel with which data will be
 * transferred
 *
 * Soundwire frame shape is created based on swr_port_info struct
 * parameters.
 */
struct swr_port_info {
	u8 dev_id;
	u8 port_en;
	u8 port_id;
	u8 offset1;
	u8 offset2;
	u8 sinterval;
	u8 ch_en;
	u8 num_ch;
	u32 ch_rate;
};

/*
 * struct swr_params - represent transfer of data from soundwire slave
 * to soundwire master
 * @tid: transaction ID to track each transaction
 * @dev_id: logical device number of the soundwire slave device
 * @num_port: number of ports that needs to be configured
 * @port_id: array of logical port numbers of the soundwire slave device
 * @num_ch: array of number of channels enabled
 * @ch_rate: array of sampling rate of different channels that need to
 * be configured
 * @ch_en: array of channels mask for all the ports
 */
struct swr_params {
	u8 tid;
	u8 dev_id;
	u8 num_port;
	u8 port_id[SWR_MAX_DEV_PORT_NUM];
	u8 num_ch[SWR_MAX_DEV_PORT_NUM];
	u32 ch_rate[SWR_MAX_DEV_PORT_NUM];
	u8 ch_en[SWR_MAX_DEV_PORT_NUM];
};

/*
 * struct swr_reg - struct to handle soundwire slave register read/writes
 * @tid: transaction id for reg read/writes
 * @dev_id: logical device number of the soundwire slave device
 * @regaddr: 16 bit regaddr of soundwire slave
 * @buf: value to be written/read to/from regaddr
 * @len: length of the buffer buf
 */
struct swr_reg {
	u8  tid;
	u8  dev_id;
	u32 regaddr;
	u32 *buf;
	u32 len;
};

/*
 * struct swr_master - Interface to the soundwire master controller
 * @dev: device interface to this driver
 * @list: link with other soundwire master controllers
 * @bus_num: board/SoC specific identifier for a soundwire master
 * @mlock: mutex protecting master data structures
 * @devices: list of devices on this master
 * @port: logical port numbers of the soundwire master. This array
 * can hold maximum master ports which is equal to number of slave
 * devices multiplied by number of ports in each slave device
 * @port_txn: table of port config transactions with transaction id
 * @reg_txn: table of register transactions with transaction id
 * @last_tid: size of table port_txn (can't grow beyond 256 since
 * tid is 8 bits)
 * @num_port: number of active ports on soundwire master
 * @gr_sid: slave id used by the group for write operations
 * @connect_port: callback for configuration of soundwire port(s)
 * @disconnect_port: callback for disable of soundwire port(s)
 * @read: callback for soundwire slave register read
 * @write: callback for soundwire slave register write
 * @get_logical_dev_num: callback to get soundwire slave logical
 * device number
 */
struct swr_master {
	struct device dev;
	struct list_head list;
	unsigned int bus_num;
	struct mutex mlock;
	struct list_head devices;
	struct swr_port_info port[SWR_MAX_MSTR_PORT_NUM];
	struct swr_params **port_txn;
	struct swr_reg **reg_txn;
	u8 last_tid;
	u8 num_port;
	u8 num_dev;
	u8 gr_sid;
	int (*connect_port)(struct swr_master *mstr, struct swr_params *txn);
	int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn);
	int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr,
			void *buf, u32 len);
	int (*write)(struct swr_master *mstr, u8 dev_num, u16 reg_addr,
			const void *buf);
	int (*bulk_write)(struct swr_master *master, u8 dev_num, void *reg,
			  const void *buf, size_t len);
	int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id,
				u8 *dev_num);
	void (*slvdev_datapath_control)(struct swr_master *mstr, bool enable);
	bool (*remove_from_group)(struct swr_master *mstr);
};

static inline struct swr_master *to_swr_master(struct device *dev)
{
	return dev ? container_of(dev, struct swr_master, dev) : NULL;
}

/*
 * struct swr_device - represent a soundwire slave device
 * @name: indicates the name of the device, defined in devicetree
 * binding under soundwire slave device node as a compatible field.
 * @master: soundwire master managing the bus hosting this device
 * @driver: Device's driver. Pointer to access routines
 * @dev_list: list of devices on a controller
 * @dev_num: logical device number of the soundwire slave device
 * @dev: driver model representation of the device
 * @addr: represents "ea-addr" which is unique-id of soundwire slave
 * device
 * @group_id: group id supported by the slave device
 */
struct swr_device {
	char name[SOUNDWIRE_NAME_SIZE];
	struct swr_master *master;
	struct swr_driver *driver;
	struct list_head dev_list;
	u8               dev_num;
	struct device    dev;
	unsigned long    addr;
	u8 group_id;
};

static inline struct swr_device *to_swr_device(struct device *dev)
{
	return dev ? container_of(dev, struct swr_device, dev) : NULL;
}

/*
 * struct swr_driver - Manage soundwire slave device driver
 * @probe: binds this driver to soundwire device
 * @remove: unbinds this driver from soundwire device
 * @shutdown: standard shutdown callback used during power down/halt
 * @suspend: standard suspend callback used during system suspend
 * @resume: standard resume callback used during system resume
 * @driver: soundwire device drivers should initialize name and
 * owner field of this structure
 * @id_table: list of soundwire devices supported by this driver
 */
struct swr_driver {
	int	(*probe)(struct swr_device *swr);
	int	(*remove)(struct swr_device *swr);
	void	(*shutdown)(struct swr_device *swr);
	int	(*suspend)(struct swr_device *swr, pm_message_t pmesg);
	int	(*resume)(struct swr_device *swr);
	int	(*device_up)(struct swr_device *swr);
	int	(*device_down)(struct swr_device *swr);
	int	(*reset_device)(struct swr_device *swr);
	struct device_driver		driver;
	const struct swr_device_id	*id_table;
};

static inline struct swr_driver *to_swr_driver(struct device_driver *drv)
{
	return drv ? container_of(drv, struct swr_driver, driver) : NULL;
}

/*
 * struct swr_boardinfo - Declare board info for soundwire device bringup
 * @name: name to initialize swr_device.name
 * @bus_num: identifies which soundwire master parents the soundwire
 * slave_device
 * @addr: represents "ea-addr" of soundwire slave device
 * @of_node: pointer to OpenFirmware device node
 * @swr_slave: device to be registered with soundwire
 */
struct swr_boardinfo {
	char               name[SOUNDWIRE_NAME_SIZE];
	int                bus_num;
	u64		   addr;
	struct device_node *of_node;
	struct swr_device  *swr_slave;
};

static inline void *swr_get_ctrl_data(const struct swr_master *master)
{
	return master ? dev_get_drvdata(&master->dev) : NULL;
}

static inline void swr_set_ctrl_data(struct swr_master *master, void *data)
{
	dev_set_drvdata(&master->dev, data);
}

static inline void *swr_get_dev_data(const struct swr_device *dev)
{
	return dev ? dev_get_drvdata(&dev->dev) : NULL;
}

static inline void swr_set_dev_data(struct swr_device *dev, void *data)
{
	dev_set_drvdata(&dev->dev, data);
}

extern int swr_startup_devices(struct swr_device *swr_dev);

extern struct swr_device *swr_new_device(struct swr_master *master,
				struct swr_boardinfo const *info);

extern int of_register_swr_devices(struct swr_master *master);

extern void swr_port_response(struct swr_master *mstr, u8 tid);

extern int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id,
			u8 *dev_num);

extern int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr,
			void *buf, u32 len);

extern int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr,
			const void *buf);

extern int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg_addr,
			  const void *buf, size_t len);

extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
				u8 *ch_mask, u32 *ch_rate, u8 *num_ch);

extern int swr_disconnect_port(struct swr_device *dev,
				u8 *port_id, u8 num_port);

extern int swr_set_device_group(struct swr_device *swr_dev, u8 id);

extern int swr_driver_register(struct swr_driver *drv);

extern void swr_driver_unregister(struct swr_driver *drv);

extern int swr_add_device(struct swr_master *master,
				struct swr_device *swrdev);
extern void swr_remove_device(struct swr_device *swr);

extern void swr_master_add_boarddevices(struct swr_master *master);

extern void swr_unregister_master(struct swr_master *master);

extern int swr_register_master(struct swr_master *master);

extern int swr_device_up(struct swr_device *swr_dev);

extern int swr_device_down(struct swr_device *swr_dev);

extern int swr_reset_device(struct swr_device *swr_dev);

extern int swr_slvdev_datapath_control(struct swr_device *swr_dev, u8 dev_num,
				       bool enable);
extern int swr_remove_from_group(struct swr_device *dev, u8 dev_num);

extern void swr_remove_device(struct swr_device *swr_dev);
#endif /* _LINUX_SOUNDWIRE_H */