Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
  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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
/*
 *  Support for Digigram Lola PCI-e boards
 *
 *  Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License along with
 *  this program; if not, write to the Free Software Foundation, Inc., 59
 *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifndef _LOLA_H
#define _LOLA_H

#define DRVNAME	"snd-lola"
#define SFX	DRVNAME ": "

/*
 * Lola HD Audio Registers BAR0
 */
#define LOLA_BAR0_GCAP		0x00
#define LOLA_BAR0_VMIN		0x02
#define LOLA_BAR0_VMAJ		0x03
#define LOLA_BAR0_OUTPAY	0x04
#define LOLA_BAR0_INPAY		0x06
#define LOLA_BAR0_GCTL		0x08
#define LOLA_BAR0_WAKEEN	0x0c
#define LOLA_BAR0_STATESTS	0x0e
#define LOLA_BAR0_GSTS		0x10
#define LOLA_BAR0_OUTSTRMPAY	0x18
#define LOLA_BAR0_INSTRMPAY	0x1a
#define LOLA_BAR0_INTCTL	0x20
#define LOLA_BAR0_INTSTS	0x24
#define LOLA_BAR0_WALCLK	0x30
#define LOLA_BAR0_SSYNC		0x38

#define LOLA_BAR0_CORBLBASE	0x40
#define LOLA_BAR0_CORBUBASE	0x44
#define LOLA_BAR0_CORBWP	0x48	/* no ULONG access */
#define LOLA_BAR0_CORBRP	0x4a	/* no ULONG access */
#define LOLA_BAR0_CORBCTL	0x4c	/* no ULONG access */
#define LOLA_BAR0_CORBSTS	0x4d	/* UCHAR access only */
#define LOLA_BAR0_CORBSIZE	0x4e	/* no ULONG access */

#define LOLA_BAR0_RIRBLBASE	0x50
#define LOLA_BAR0_RIRBUBASE	0x54
#define LOLA_BAR0_RIRBWP	0x58
#define LOLA_BAR0_RINTCNT	0x5a	/* no ULONG access */
#define LOLA_BAR0_RIRBCTL	0x5c
#define LOLA_BAR0_RIRBSTS	0x5d	/* UCHAR access only */
#define LOLA_BAR0_RIRBSIZE	0x5e	/* no ULONG access */

#define LOLA_BAR0_ICW		0x60
#define LOLA_BAR0_IRR		0x64
#define LOLA_BAR0_ICS		0x68
#define LOLA_BAR0_DPLBASE	0x70
#define LOLA_BAR0_DPUBASE	0x74

/* stream register offsets from stream base 0x80 */
#define LOLA_BAR0_SD0_OFFSET	0x80
#define LOLA_REG0_SD_CTL	0x00
#define LOLA_REG0_SD_STS	0x03
#define LOLA_REG0_SD_LPIB	0x04
#define LOLA_REG0_SD_CBL	0x08
#define LOLA_REG0_SD_LVI	0x0c
#define LOLA_REG0_SD_FIFOW	0x0e
#define LOLA_REG0_SD_FIFOSIZE	0x10
#define LOLA_REG0_SD_FORMAT	0x12
#define LOLA_REG0_SD_BDLPL	0x18
#define LOLA_REG0_SD_BDLPU	0x1c

/*
 * Lola Digigram Registers BAR1
 */
#define LOLA_BAR1_FPGAVER	0x00
#define LOLA_BAR1_DEVER		0x04
#define LOLA_BAR1_UCBMV		0x08
#define LOLA_BAR1_JTAG		0x0c
#define LOLA_BAR1_UARTRX	0x10
#define LOLA_BAR1_UARTTX	0x14
#define LOLA_BAR1_UARTCR	0x18
#define LOLA_BAR1_NVRAMVER	0x1c
#define LOLA_BAR1_CTRLSPI	0x20
#define LOLA_BAR1_DSPI		0x24
#define LOLA_BAR1_AISPI		0x28
#define LOLA_BAR1_GRAN		0x2c

#define LOLA_BAR1_DINTCTL	0x80
#define LOLA_BAR1_DIINTCTL	0x84
#define LOLA_BAR1_DOINTCTL	0x88
#define LOLA_BAR1_LRC		0x90
#define LOLA_BAR1_DINTSTS	0x94
#define LOLA_BAR1_DIINTSTS	0x98
#define LOLA_BAR1_DOINTSTS	0x9c

#define LOLA_BAR1_DSD0_OFFSET	0xa0
#define LOLA_BAR1_DSD_SIZE	0x18

#define LOLA_BAR1_DSDnSTS       0x00
#define LOLA_BAR1_DSDnLPIB      0x04
#define LOLA_BAR1_DSDnCTL       0x08
#define LOLA_BAR1_DSDnLVI       0x0c
#define LOLA_BAR1_DSDnBDPL      0x10
#define LOLA_BAR1_DSDnBDPU      0x14

#define LOLA_BAR1_SSYNC		0x03e8

#define LOLA_BAR1_BOARD_CTRL	0x0f00
#define LOLA_BAR1_BOARD_MODE	0x0f02

#define LOLA_BAR1_SOURCE_GAIN_ENABLE		0x1000
#define LOLA_BAR1_DEST00_MIX_GAIN_ENABLE	0x1004
#define LOLA_BAR1_DEST31_MIX_GAIN_ENABLE	0x1080
#define LOLA_BAR1_SOURCE00_01_GAIN		0x1084
#define LOLA_BAR1_SOURCE30_31_GAIN		0x10c0
#define LOLA_BAR1_SOURCE_GAIN(src) \
	(LOLA_BAR1_SOURCE00_01_GAIN + (src) * 2)
#define LOLA_BAR1_DEST00_MIX00_01_GAIN		0x10c4
#define LOLA_BAR1_DEST00_MIX30_31_GAIN		0x1100
#define LOLA_BAR1_DEST01_MIX00_01_GAIN		0x1104
#define LOLA_BAR1_DEST01_MIX30_31_GAIN		0x1140
#define LOLA_BAR1_DEST31_MIX00_01_GAIN		0x1884
#define LOLA_BAR1_DEST31_MIX30_31_GAIN		0x18c0
#define LOLA_BAR1_MIX_GAIN(dest, mix) \
	(LOLA_BAR1_DEST00_MIX00_01_GAIN + (dest) * 0x40 + (mix) * 2)
#define LOLA_BAR1_ANALOG_CLIP_IN		0x18c4
#define LOLA_BAR1_PEAKMETERS_SOURCE00_01	0x18c8
#define LOLA_BAR1_PEAKMETERS_SOURCE30_31	0x1904
#define LOLA_BAR1_PEAKMETERS_SOURCE(src) \
	(LOLA_BAR1_PEAKMETERS_SOURCE00_01 + (src) * 2)
#define LOLA_BAR1_PEAKMETERS_DEST00_01		0x1908
#define LOLA_BAR1_PEAKMETERS_DEST30_31		0x1944
#define LOLA_BAR1_PEAKMETERS_DEST(dest) \
	(LOLA_BAR1_PEAKMETERS_DEST00_01 + (dest) * 2)
#define LOLA_BAR1_PEAKMETERS_AGC00_01		0x1948
#define LOLA_BAR1_PEAKMETERS_AGC14_15		0x1964
#define LOLA_BAR1_PEAKMETERS_AGC(x) \
	(LOLA_BAR1_PEAKMETERS_AGC00_01 + (x) * 2)

/* GCTL reset bit */
#define LOLA_GCTL_RESET		(1 << 0)
/* GCTL unsolicited response enable bit */
#define LOLA_GCTL_UREN		(1 << 8)

/* CORB/RIRB control, read/write pointer */
#define LOLA_RBCTL_DMA_EN	0x02	/* enable DMA */
#define LOLA_RBCTL_IRQ_EN	0x01	/* enable IRQ */
#define LOLA_RBRWP_CLR		0x8000	/* read/write pointer clear */

#define LOLA_RIRB_EX_UNSOL_EV	0x40000000
#define LOLA_RIRB_EX_ERROR	0x80000000

/* CORB int mask: CMEI[0] */
#define LOLA_CORB_INT_CMEI	0x01
#define LOLA_CORB_INT_MASK	LOLA_CORB_INT_CMEI

/* RIRB int mask: overrun[2], response[0] */
#define LOLA_RIRB_INT_RESPONSE	0x01
#define LOLA_RIRB_INT_OVERRUN	0x04
#define LOLA_RIRB_INT_MASK	(LOLA_RIRB_INT_RESPONSE | LOLA_RIRB_INT_OVERRUN)

/* DINTCTL and DINTSTS */
#define LOLA_DINT_GLOBAL	0x80000000 /* global interrupt enable bit */
#define LOLA_DINT_CTRL		0x40000000 /* controller interrupt enable bit */
#define LOLA_DINT_FIFOERR	0x20000000 /* global fifo error enable bit */
#define LOLA_DINT_MUERR		0x10000000 /* global microcontroller underrun error */

/* DSDnCTL bits */
#define LOLA_DSD_CTL_SRST	0x01	/* stream reset bit */
#define LOLA_DSD_CTL_SRUN	0x02	/* stream DMA start bit */
#define LOLA_DSD_CTL_IOCE	0x04	/* interrupt on completion enable */
#define LOLA_DSD_CTL_DEIE	0x10	/* descriptor error interrupt enable */
#define LOLA_DSD_CTL_VLRCV	0x20	/* valid LRCountValue information in bits 8..31 */
#define LOLA_LRC_MASK		0xffffff00

/* DSDnSTS */
#define LOLA_DSD_STS_BCIS	0x04	/* buffer completion interrupt status */
#define LOLA_DSD_STS_DESE	0x10	/* descriptor error interrupt */
#define LOLA_DSD_STS_FIFORDY	0x20	/* fifo ready */

#define LOLA_CORB_ENTRIES	256

#define MAX_STREAM_IN_COUNT	16
#define MAX_STREAM_OUT_COUNT	16
#define MAX_STREAM_COUNT	16
#define MAX_PINS		MAX_STREAM_COUNT
#define MAX_STREAM_BUFFER_COUNT	16
#define MAX_AUDIO_INOUT_COUNT	16

#define LOLA_CLOCK_TYPE_INTERNAL    0
#define LOLA_CLOCK_TYPE_AES         1
#define LOLA_CLOCK_TYPE_AES_SYNC    2
#define LOLA_CLOCK_TYPE_WORDCLOCK   3
#define LOLA_CLOCK_TYPE_ETHERSOUND  4
#define LOLA_CLOCK_TYPE_VIDEO       5

#define LOLA_CLOCK_FORMAT_NONE      0
#define LOLA_CLOCK_FORMAT_NTSC      1
#define LOLA_CLOCK_FORMAT_PAL       2

#define MAX_SAMPLE_CLOCK_COUNT  48

/* parameters used with mixer widget's mixer capabilities */
#define LOLA_PEAK_METER_CAN_AGC_MASK		1
#define LOLA_PEAK_METER_CAN_ANALOG_CLIP_MASK	2

struct lola_bar {
	unsigned long addr;
	void __iomem *remap_addr;
};

/* CORB/RIRB */
struct lola_rb {
	u32 *buf;		/* CORB/RIRB buffer, 8 byte per each entry */
	dma_addr_t addr;	/* physical address of CORB/RIRB buffer */
	unsigned short rp, wp;	/* read/write pointers */
	int cmds;		/* number of pending requests */
};

/* Pin widget setup */
struct lola_pin {
	unsigned int nid;
	bool is_analog;
	unsigned int amp_mute;
	unsigned int amp_step_size;
	unsigned int amp_num_steps;
	unsigned int amp_offset;
	unsigned int max_level;
	unsigned int config_default_reg;
	unsigned int fixed_gain_list_len;
	unsigned int cur_gain_step;
};

struct lola_pin_array {
	unsigned int num_pins;
	unsigned int num_analog_pins;
	struct lola_pin pins[MAX_PINS];
};

/* Clock widget setup */
struct lola_sample_clock {
	unsigned int type;
	unsigned int format;
	unsigned int freq;
};

struct lola_clock_widget {
	unsigned int nid;
	unsigned int items;
	unsigned int cur_index;
	unsigned int cur_freq;
	bool cur_valid;
	struct lola_sample_clock sample_clock[MAX_SAMPLE_CLOCK_COUNT];
	unsigned int idx_lookup[MAX_SAMPLE_CLOCK_COUNT];
};

#define LOLA_MIXER_DIM      32
struct lola_mixer_array {
	u32 src_gain_enable;
	u32 dest_mix_gain_enable[LOLA_MIXER_DIM];
	u16 src_gain[LOLA_MIXER_DIM];
	u16 dest_mix_gain[LOLA_MIXER_DIM][LOLA_MIXER_DIM];
};

/* Mixer widget setup */
struct lola_mixer_widget {
	unsigned int nid;
	unsigned int caps;
	struct lola_mixer_array __user *array;
	struct lola_mixer_array *array_saved;
	unsigned int src_stream_outs;
	unsigned int src_phys_ins;
	unsigned int dest_stream_ins;
	unsigned int dest_phys_outs;
	unsigned int src_stream_out_ofs;
	unsigned int dest_phys_out_ofs;
	unsigned int src_mask;
	unsigned int dest_mask;
};

/* Audio stream */
struct lola_stream {
	unsigned int nid;	/* audio widget NID */
	unsigned int index;	/* array index */
	unsigned int dsd;	/* DSD index */
	bool can_float;
	struct snd_pcm_substream *substream; /* assigned PCM substream */
	struct lola_stream *master;	/* master stream (for multi-channel) */

	/* buffer setup */
	unsigned int bufsize;
	unsigned int period_bytes;
	unsigned int frags;

	/* format + channel setup */
	unsigned int format_verb;

	/* flags */
	unsigned int opened:1;
	unsigned int prepared:1;
	unsigned int paused:1;
	unsigned int running:1;
};

#define PLAY	SNDRV_PCM_STREAM_PLAYBACK
#define CAPT	SNDRV_PCM_STREAM_CAPTURE

struct lola_pcm {
	unsigned int num_streams;
	struct snd_dma_buffer bdl; /* BDL buffer */
	struct lola_stream streams[MAX_STREAM_COUNT];
};

/* card instance */
struct lola {
	struct snd_card *card;
	struct pci_dev *pci;

	/* pci resources */
	struct lola_bar bar[2];
	int irq;

	/* locks */
	spinlock_t reg_lock;
	struct mutex open_mutex;

	/* CORB/RIRB */
	struct lola_rb corb;
	struct lola_rb rirb;
	unsigned int res, res_ex;	/* last read values */
	/* last command (for debugging) */
	unsigned int last_cmd_nid, last_verb, last_data, last_extdata;

	/* CORB/RIRB buffers */
	struct snd_dma_buffer rb;

	/* unsolicited events */
	unsigned int last_unsol_res;

	/* streams */
	struct lola_pcm pcm[2];

	/* input src */
	unsigned int input_src_caps_mask;
	unsigned int input_src_mask;

	/* pins */
	struct lola_pin_array pin[2];

	/* clock */
	struct lola_clock_widget clock;
	int ref_count_rate;
	unsigned int sample_rate;

	/* mixer */
	struct lola_mixer_widget mixer;

	/* hw info */
	unsigned int version;
	unsigned int lola_caps;

	/* parameters */
	unsigned int granularity;
	unsigned int sample_rate_min;
	unsigned int sample_rate_max;

	/* flags */
	unsigned int initialized:1;
	unsigned int cold_reset:1;
	unsigned int polling_mode:1;

	/* for debugging */
	unsigned int debug_res;
	unsigned int debug_res_ex;
};

#define BAR0	0
#define BAR1	1

/* Helper macros */
#define lola_readl(chip, idx, name) \
	readl((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
#define lola_readw(chip, idx, name) \
	readw((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
#define lola_readb(chip, idx, name) \
	readb((chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
#define lola_writel(chip, idx, name, val) \
	writel((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
#define lola_writew(chip, idx, name, val) \
	writew((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)
#define lola_writeb(chip, idx, name, val) \
	writeb((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name)

#define lola_dsd_read(chip, dsd, name) \
	readl((chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
	      (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)
#define lola_dsd_write(chip, dsd, name, val) \
	writel((val), (chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \
	       (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name)

/* GET verbs HDAudio */
#define LOLA_VERB_GET_STREAM_FORMAT		0xa00
#define LOLA_VERB_GET_AMP_GAIN_MUTE		0xb00
#define LOLA_VERB_PARAMETERS			0xf00
#define LOLA_VERB_GET_POWER_STATE		0xf05
#define LOLA_VERB_GET_CONV			0xf06
#define LOLA_VERB_GET_UNSOLICITED_RESPONSE	0xf08
#define LOLA_VERB_GET_DIGI_CONVERT_1		0xf0d
#define LOLA_VERB_GET_CONFIG_DEFAULT		0xf1c
#define LOLA_VERB_GET_SUBSYSTEM_ID		0xf20
/* GET verbs Digigram */
#define LOLA_VERB_GET_FIXED_GAIN		0xfc0
#define LOLA_VERB_GET_GAIN_SELECT		0xfc1
#define LOLA_VERB_GET_MAX_LEVEL			0xfc2
#define LOLA_VERB_GET_CLOCK_LIST		0xfc3
#define LOLA_VERB_GET_CLOCK_SELECT		0xfc4
#define LOLA_VERB_GET_CLOCK_STATUS		0xfc5

/* SET verbs HDAudio */
#define LOLA_VERB_SET_STREAM_FORMAT		0x200
#define LOLA_VERB_SET_AMP_GAIN_MUTE		0x300
#define LOLA_VERB_SET_POWER_STATE		0x705
#define LOLA_VERB_SET_CHANNEL_STREAMID		0x706
#define LOLA_VERB_SET_UNSOLICITED_ENABLE	0x708
#define LOLA_VERB_SET_DIGI_CONVERT_1		0x70d
/* SET verbs Digigram */
#define LOLA_VERB_SET_GAIN_SELECT		0xf81
#define LOLA_VERB_SET_CLOCK_SELECT		0xf84
#define LOLA_VERB_SET_GRANULARITY_STEPS		0xf86
#define LOLA_VERB_SET_SOURCE_GAIN		0xf87
#define LOLA_VERB_SET_MIX_GAIN			0xf88
#define LOLA_VERB_SET_DESTINATION_GAIN		0xf89
#define LOLA_VERB_SET_SRC			0xf8a

/* Parameter IDs used with LOLA_VERB_PARAMETERS */
#define LOLA_PAR_VENDOR_ID			0x00
#define LOLA_PAR_FUNCTION_TYPE			0x05
#define LOLA_PAR_AUDIO_WIDGET_CAP		0x09
#define LOLA_PAR_PCM				0x0a
#define LOLA_PAR_STREAM_FORMATS			0x0b
#define LOLA_PAR_PIN_CAP			0x0c
#define LOLA_PAR_AMP_IN_CAP			0x0d
#define LOLA_PAR_CONNLIST_LEN			0x0e
#define LOLA_PAR_POWER_STATE			0x0f
#define LOLA_PAR_GPIO_CAP			0x11
#define LOLA_PAR_AMP_OUT_CAP			0x12
#define LOLA_PAR_SPECIFIC_CAPS			0x80
#define LOLA_PAR_FIXED_GAIN_LIST		0x81

/* extract results of LOLA_PAR_SPECIFIC_CAPS */
#define LOLA_AFG_MIXER_WIDGET_PRESENT(res)	((res & (1 << 21)) != 0)
#define LOLA_AFG_CLOCK_WIDGET_PRESENT(res)	((res & (1 << 20)) != 0)
#define LOLA_AFG_INPUT_PIN_COUNT(res)		((res >> 10) & 0x2ff)
#define LOLA_AFG_OUTPUT_PIN_COUNT(res)		((res) & 0x2ff)

/* extract results of LOLA_PAR_AMP_IN_CAP / LOLA_PAR_AMP_OUT_CAP */
#define LOLA_AMP_MUTE_CAPABLE(res)		((res & (1 << 31)) != 0)
#define LOLA_AMP_STEP_SIZE(res)			((res >> 24) & 0x7f)
#define LOLA_AMP_NUM_STEPS(res)			((res >> 12) & 0x3ff)
#define LOLA_AMP_OFFSET(res)			((res) & 0x3ff)

#define LOLA_GRANULARITY_MIN		8
#define LOLA_GRANULARITY_MAX		32
#define LOLA_GRANULARITY_STEP		8

/* parameters used with unsolicited command/response */
#define LOLA_UNSOLICITED_TAG_MASK	0x3f
#define LOLA_UNSOLICITED_TAG		0x1a
#define LOLA_UNSOLICITED_ENABLE		0x80
#define LOLA_UNSOL_RESP_TAG_OFFSET	26

/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res)   ((res >> 2) & 0x1f)
#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res)  ((res >> 7) & 0x1f)

int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
		     unsigned int data, unsigned int extdata);
int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
		    unsigned int data, unsigned int extdata,
		    unsigned int *val, unsigned int *extval);
int lola_codec_flush(struct lola *chip);
#define lola_read_param(chip, nid, param, val) \
	lola_codec_read(chip, nid, LOLA_VERB_PARAMETERS, param, 0, val, NULL)

/* PCM */
int lola_create_pcm(struct lola *chip);
void lola_free_pcm(struct lola *chip);
int lola_init_pcm(struct lola *chip, int dir, int *nidp);
void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits);

/* clock */
int lola_init_clock_widget(struct lola *chip, int nid);
int lola_set_granularity(struct lola *chip, unsigned int val, bool force);
int lola_enable_clock_events(struct lola *chip);
int lola_set_clock_index(struct lola *chip, unsigned int idx);
int lola_set_clock(struct lola *chip, int idx);
int lola_set_sample_rate(struct lola *chip, int rate);
bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val);
unsigned int lola_sample_rate_convert(unsigned int coded);

/* mixer */
int lola_init_pins(struct lola *chip, int dir, int *nidp);
int lola_init_mixer_widget(struct lola *chip, int nid);
void lola_free_mixer(struct lola *chip);
int lola_create_mixer(struct lola *chip);
int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute);
void lola_save_mixer(struct lola *chip);
void lola_restore_mixer(struct lola *chip);
int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update);

/* proc */
#ifdef CONFIG_SND_DEBUG
void lola_proc_debug_new(struct lola *chip);
#else
#define lola_proc_debug_new(chip)
#endif

#endif /* _LOLA_H */