aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-05-20 05:59:29 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-20 05:59:29 -0400
commit5e8aa85253513b9c1ade8bd71dc341218a752a65 (patch)
tree84240b7f72fefb805c78300de0ae23b7b96bf5c2
parent7bd9db83087aecef8279c0b8b9dfef4db4a8fc3c (diff)
parent550a8b691ca67761bbf382d98fbd81d215f1d7f0 (diff)
Merge branch 'topic/misc' into for-linus
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt31
-rw-r--r--include/linux/usb/audio-v2.h366
-rw-r--r--include/linux/usb/audio.h210
-rw-r--r--include/sound/asound.h20
-rw-r--r--include/sound/es1688.h11
-rw-r--r--include/sound/version.h2
-rw-r--r--sound/i2c/i2c.c18
-rw-r--r--sound/isa/Kconfig16
-rw-r--r--sound/isa/es1688/es1688.c225
-rw-r--r--sound/isa/es1688/es1688_lib.c47
-rw-r--r--sound/isa/gus/gusextreme.c26
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/es968.c248
-rw-r--r--sound/pci/Kconfig32
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/asihpi/Makefile5
-rw-r--r--sound/pci/asihpi/asihpi.c3002
-rw-r--r--sound/pci/asihpi/hpi.h2001
-rw-r--r--sound/pci/asihpi/hpi6000.c1840
-rw-r--r--sound/pci/asihpi/hpi6000.h70
-rw-r--r--sound/pci/asihpi/hpi6205.c2331
-rw-r--r--sound/pci/asihpi/hpi6205.h93
-rw-r--r--sound/pci/asihpi/hpi_internal.h1641
-rw-r--r--sound/pci/asihpi/hpicmn.c643
-rw-r--r--sound/pci/asihpi/hpicmn.h64
-rw-r--r--sound/pci/asihpi/hpidebug.c225
-rw-r--r--sound/pci/asihpi/hpidebug.h385
-rw-r--r--sound/pci/asihpi/hpidspcd.c172
-rw-r--r--sound/pci/asihpi/hpidspcd.h104
-rw-r--r--sound/pci/asihpi/hpifunc.c3864
-rw-r--r--sound/pci/asihpi/hpimsginit.c130
-rw-r--r--sound/pci/asihpi/hpimsginit.h40
-rw-r--r--sound/pci/asihpi/hpimsgx.c907
-rw-r--r--sound/pci/asihpi/hpimsgx.h36
-rw-r--r--sound/pci/asihpi/hpioctl.c484
-rw-r--r--sound/pci/asihpi/hpioctl.h38
-rw-r--r--sound/pci/asihpi/hpios.c114
-rw-r--r--sound/pci/asihpi/hpios.h178
-rw-r--r--sound/pci/asihpi/hpipcida.h37
-rw-r--r--sound/pci/es1968.c129
-rw-r--r--sound/pci/maestro3.c139
-rw-r--r--sound/usb/Kconfig3
-rw-r--r--sound/usb/Makefile26
-rw-r--r--sound/usb/caiaq/input.c1
-rw-r--r--sound/usb/card.c652
-rw-r--r--sound/usb/card.h105
-rw-r--r--sound/usb/debug.h15
-rw-r--r--sound/usb/endpoint.c362
-rw-r--r--sound/usb/endpoint.h11
-rw-r--r--sound/usb/format.c432
-rw-r--r--sound/usb/format.h8
-rw-r--r--sound/usb/helper.c113
-rw-r--r--sound/usb/helper.h32
-rw-r--r--sound/usb/midi.c (renamed from sound/usb/usbmidi.c)3
-rw-r--r--sound/usb/midi.h48
-rw-r--r--sound/usb/misc/Makefile2
-rw-r--r--sound/usb/misc/ua101.c (renamed from sound/usb/ua101.c)3
-rw-r--r--sound/usb/mixer.c (renamed from sound/usb/usbmixer.c)847
-rw-r--r--sound/usb/mixer.h55
-rw-r--r--sound/usb/mixer_maps.c (renamed from sound/usb/usbmixer_maps.c)4
-rw-r--r--sound/usb/mixer_quirks.c412
-rw-r--r--sound/usb/mixer_quirks.h13
-rw-r--r--sound/usb/pcm.c935
-rw-r--r--sound/usb/pcm.h14
-rw-r--r--sound/usb/proc.c168
-rw-r--r--sound/usb/proc.h8
-rw-r--r--sound/usb/quirks-table.h (renamed from sound/usb/usbquirks.h)68
-rw-r--r--sound/usb/quirks.c594
-rw-r--r--sound/usb/quirks.h23
-rw-r--r--sound/usb/urb.c995
-rw-r--r--sound/usb/urb.h21
-rw-r--r--sound/usb/usbaudio.c4050
-rw-r--r--sound/usb/usbaudio.h93
-rw-r--r--sound/usb/usx2y/us122l.c1
-rw-r--r--sound/usb/usx2y/usbusx2y.h1
75 files changed, 24893 insertions, 5152 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index bfcbbf88c44d..2075bbb8b3e2 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -227,6 +227,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
227 227
228 The power-management is supported. 228 The power-management is supported.
229 229
230 Module snd-asihpi
231 -----------------
232
233 Module for AudioScience ASI soundcards
234
235 enable_hpi_hwdep - enable HPI hwdep for AudioScience soundcard
236
237 This module supports multiple cards.
238 The driver requires the firmware loader support on kernel.
239
230 Module snd-atiixp 240 Module snd-atiixp
231 ----------------- 241 -----------------
232 242
@@ -622,28 +632,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
622 632
623 The power-management is supported. 633 The power-management is supported.
624 634
625 Module snd-es968
626 ----------------
627
628 Module for sound cards based on ESS ES968 chip (PnP only).
629
630 This module supports multiple cards, PnP and autoprobe.
631
632 The power-management is supported.
633
634 Module snd-es1688 635 Module snd-es1688
635 ----------------- 636 -----------------
636 637
637 Module for ESS AudioDrive ES-1688 and ES-688 sound cards. 638 Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
638 639
639 port - port # for ES-1688 chip (0x220,0x240,0x260) 640 isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
640 fm_port - port # for OPL3 (option; share the same port as default)
641 mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) 641 mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
642 irq - IRQ # for ES-1688 chip (5,7,9,10)
643 mpu_irq - IRQ # for MPU-401 port (5,7,9,10) 642 mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
643 fm_port - port # for OPL3 (option; share the same port as default)
644
645 with isapnp=0, the following additional options are available:
646 port - port # for ES-1688 chip (0x220,0x240,0x260)
647 irq - IRQ # for ES-1688 chip (5,7,9,10)
644 dma8 - DMA # for ES-1688 chip (0,1,3) 648 dma8 - DMA # for ES-1688 chip (0,1,3)
645 649
646 This module supports multiple cards and autoprobe (without MPU-401 port). 650 This module supports multiple cards and autoprobe (without MPU-401 port)
651 and PnP with the ES968 chip.
647 652
648 Module snd-es18xx 653 Module snd-es18xx
649 ----------------- 654 -----------------
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h
new file mode 100644
index 000000000000..0952231e6c3f
--- /dev/null
+++ b/include/linux/usb/audio-v2.h
@@ -0,0 +1,366 @@
1/*
2 * Copyright (c) 2010 Daniel Mack <daniel@caiaq.de>
3 *
4 * This software is distributed under the terms of the GNU General Public
5 * License ("GPL") version 2, as published by the Free Software Foundation.
6 *
7 * This file holds USB constants and structures defined
8 * by the USB Device Class Definition for Audio Devices in version 2.0.
9 * Comments below reference relevant sections of the documents contained
10 * in http://www.usb.org/developers/devclass_docs/Audio2.0_final.zip
11 */
12
13#ifndef __LINUX_USB_AUDIO_V2_H
14#define __LINUX_USB_AUDIO_V2_H
15
16#include <linux/types.h>
17
18/* v1.0 and v2.0 of this standard have many things in common. For the rest
19 * of the definitions, please refer to audio.h */
20
21/* 4.7.2.1 Clock Source Descriptor */
22
23struct uac_clock_source_descriptor {
24 __u8 bLength;
25 __u8 bDescriptorType;
26 __u8 bDescriptorSubtype;
27 __u8 bClockID;
28 __u8 bmAttributes;
29 __u8 bmControls;
30 __u8 bAssocTerminal;
31 __u8 iClockSource;
32} __attribute__((packed));
33
34/* 4.7.2.2 Clock Source Descriptor */
35
36struct uac_clock_selector_descriptor {
37 __u8 bLength;
38 __u8 bDescriptorType;
39 __u8 bDescriptorSubtype;
40 __u8 bClockID;
41 __u8 bNrInPins;
42 __u8 bmControls;
43 __u8 baCSourceID[];
44} __attribute__((packed));
45
46/* 4.7.2.4 Input terminal descriptor */
47
48struct uac2_input_terminal_descriptor {
49 __u8 bLength;
50 __u8 bDescriptorType;
51 __u8 bDescriptorSubtype;
52 __u8 bTerminalID;
53 __u16 wTerminalType;
54 __u8 bAssocTerminal;
55 __u8 bCSourceID;
56 __u8 bNrChannels;
57 __u32 bmChannelConfig;
58 __u8 iChannelNames;
59 __u16 bmControls;
60 __u8 iTerminal;
61} __attribute__((packed));
62
63/* 4.7.2.5 Output terminal descriptor */
64
65struct uac2_output_terminal_descriptor {
66 __u8 bLength;
67 __u8 bDescriptorType;
68 __u8 bDescriptorSubtype;
69 __u8 bTerminalID;
70 __u16 wTerminalType;
71 __u8 bAssocTerminal;
72 __u8 bSourceID;
73 __u8 bCSourceID;
74 __u16 bmControls;
75 __u8 iTerminal;
76} __attribute__((packed));
77
78
79
80/* 4.7.2.8 Feature Unit Descriptor */
81
82struct uac2_feature_unit_descriptor {
83 __u8 bLength;
84 __u8 bDescriptorType;
85 __u8 bDescriptorSubtype;
86 __u8 bUnitID;
87 __u8 bSourceID;
88 /* bmaControls is actually u32,
89 * but u8 is needed for the hybrid parser */
90 __u8 bmaControls[0]; /* variable length */
91} __attribute__((packed));
92
93/* 4.9.2 Class-Specific AS Interface Descriptor */
94
95struct uac_as_header_descriptor_v2 {
96 __u8 bLength;
97 __u8 bDescriptorType;
98 __u8 bDescriptorSubtype;
99 __u8 bTerminalLink;
100 __u8 bmControls;
101 __u8 bFormatType;
102 __u32 bmFormats;
103 __u8 bNrChannels;
104 __u32 bmChannelConfig;
105 __u8 iChannelNames;
106} __attribute__((packed));
107
108
109/* A.7 Audio Function Category Codes */
110#define UAC2_FUNCTION_SUBCLASS_UNDEFINED 0x00
111#define UAC2_FUNCTION_DESKTOP_SPEAKER 0x01
112#define UAC2_FUNCTION_HOME_THEATER 0x02
113#define UAC2_FUNCTION_MICROPHONE 0x03
114#define UAC2_FUNCTION_HEADSET 0x04
115#define UAC2_FUNCTION_TELEPHONE 0x05
116#define UAC2_FUNCTION_CONVERTER 0x06
117#define UAC2_FUNCTION_SOUND_RECORDER 0x07
118#define UAC2_FUNCTION_IO_BOX 0x08
119#define UAC2_FUNCTION_MUSICAL_INSTRUMENT 0x09
120#define UAC2_FUNCTION_PRO_AUDIO 0x0a
121#define UAC2_FUNCTION_AUDIO_VIDEO 0x0b
122#define UAC2_FUNCTION_CONTROL_PANEL 0x0c
123#define UAC2_FUNCTION_OTHER 0xff
124
125/* A.9 Audio Class-Specific AC Interface Descriptor Subtypes */
126/* see audio.h for the rest, which is identical to v1 */
127#define UAC2_EFFECT_UNIT 0x07
128#define UAC2_PROCESSING_UNIT_V2 0x08
129#define UAC2_EXTENSION_UNIT_V2 0x09
130#define UAC2_CLOCK_SOURCE 0x0a
131#define UAC2_CLOCK_SELECTOR 0x0b
132#define UAC2_CLOCK_MULTIPLIER 0x0c
133#define UAC2_SAMPLE_RATE_CONVERTER 0x0d
134
135/* A.10 Audio Class-Specific AS Interface Descriptor Subtypes */
136/* see audio.h for the rest, which is identical to v1 */
137#define UAC2_ENCODER 0x03
138#define UAC2_DECODER 0x04
139
140/* A.11 Effect Unit Effect Types */
141#define UAC2_EFFECT_UNDEFINED 0x00
142#define UAC2_EFFECT_PARAM_EQ 0x01
143#define UAC2_EFFECT_REVERB 0x02
144#define UAC2_EFFECT_MOD_DELAY 0x03
145#define UAC2_EFFECT_DYN_RANGE_COMP 0x04
146
147/* A.12 Processing Unit Process Types */
148#define UAC2_PROCESS_UNDEFINED 0x00
149#define UAC2_PROCESS_UP_DOWNMIX 0x01
150#define UAC2_PROCESS_DOLBY_PROLOCIC 0x02
151#define UAC2_PROCESS_STEREO_EXTENDER 0x03
152
153/* A.14 Audio Class-Specific Request Codes */
154#define UAC2_CS_CUR 0x01
155#define UAC2_CS_RANGE 0x02
156
157/* A.15 Encoder Type Codes */
158#define UAC2_ENCODER_UNDEFINED 0x00
159#define UAC2_ENCODER_OTHER 0x01
160#define UAC2_ENCODER_MPEG 0x02
161#define UAC2_ENCODER_AC3 0x03
162#define UAC2_ENCODER_WMA 0x04
163#define UAC2_ENCODER_DTS 0x05
164
165/* A.16 Decoder Type Codes */
166#define UAC2_DECODER_UNDEFINED 0x00
167#define UAC2_DECODER_OTHER 0x01
168#define UAC2_DECODER_MPEG 0x02
169#define UAC2_DECODER_AC3 0x03
170#define UAC2_DECODER_WMA 0x04
171#define UAC2_DECODER_DTS 0x05
172
173/* A.17.1 Clock Source Control Selectors */
174#define UAC2_CS_UNDEFINED 0x00
175#define UAC2_CS_CONTROL_SAM_FREQ 0x01
176#define UAC2_CS_CONTROL_CLOCK_VALID 0x02
177
178/* A.17.2 Clock Selector Control Selectors */
179#define UAC2_CX_UNDEFINED 0x00
180#define UAC2_CX_CLOCK_SELECTOR 0x01
181
182/* A.17.3 Clock Multiplier Control Selectors */
183#define UAC2_CM_UNDEFINED 0x00
184#define UAC2_CM_NUMERATOR 0x01
185#define UAC2_CM_DENOMINTATOR 0x02
186
187/* A.17.4 Terminal Control Selectors */
188#define UAC2_TE_UNDEFINED 0x00
189#define UAC2_TE_COPY_PROTECT 0x01
190#define UAC2_TE_CONNECTOR 0x02
191#define UAC2_TE_OVERLOAD 0x03
192#define UAC2_TE_CLUSTER 0x04
193#define UAC2_TE_UNDERFLOW 0x05
194#define UAC2_TE_OVERFLOW 0x06
195#define UAC2_TE_LATENCY 0x07
196
197/* A.17.5 Mixer Control Selectors */
198#define UAC2_MU_UNDEFINED 0x00
199#define UAC2_MU_MIXER 0x01
200#define UAC2_MU_CLUSTER 0x02
201#define UAC2_MU_UNDERFLOW 0x03
202#define UAC2_MU_OVERFLOW 0x04
203#define UAC2_MU_LATENCY 0x05
204
205/* A.17.6 Selector Control Selectors */
206#define UAC2_SU_UNDEFINED 0x00
207#define UAC2_SU_SELECTOR 0x01
208#define UAC2_SU_LATENCY 0x02
209
210/* A.17.7 Feature Unit Control Selectors */
211/* see audio.h for the rest, which is identical to v1 */
212#define UAC2_FU_INPUT_GAIN 0x0b
213#define UAC2_FU_INPUT_GAIN_PAD 0x0c
214#define UAC2_FU_PHASE_INVERTER 0x0d
215#define UAC2_FU_UNDERFLOW 0x0e
216#define UAC2_FU_OVERFLOW 0x0f
217#define UAC2_FU_LATENCY 0x10
218
219/* A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors */
220#define UAC2_PE_UNDEFINED 0x00
221#define UAC2_PE_ENABLE 0x01
222#define UAC2_PE_CENTERFREQ 0x02
223#define UAC2_PE_QFACTOR 0x03
224#define UAC2_PE_GAIN 0x04
225#define UAC2_PE_UNDERFLOW 0x05
226#define UAC2_PE_OVERFLOW 0x06
227#define UAC2_PE_LATENCY 0x07
228
229/* A.17.8.2 Reverberation Effect Unit Control Selectors */
230#define UAC2_RV_UNDEFINED 0x00
231#define UAC2_RV_ENABLE 0x01
232#define UAC2_RV_TYPE 0x02
233#define UAC2_RV_LEVEL 0x03
234#define UAC2_RV_TIME 0x04
235#define UAC2_RV_FEEDBACK 0x05
236#define UAC2_RV_PREDELAY 0x06
237#define UAC2_RV_DENSITY 0x07
238#define UAC2_RV_HIFREQ_ROLLOFF 0x08
239#define UAC2_RV_UNDERFLOW 0x09
240#define UAC2_RV_OVERFLOW 0x0a
241#define UAC2_RV_LATENCY 0x0b
242
243/* A.17.8.3 Modulation Delay Effect Control Selectors */
244#define UAC2_MD_UNDEFINED 0x00
245#define UAC2_MD_ENABLE 0x01
246#define UAC2_MD_BALANCE 0x02
247#define UAC2_MD_RATE 0x03
248#define UAC2_MD_DEPTH 0x04
249#define UAC2_MD_TIME 0x05
250#define UAC2_MD_FEEDBACK 0x06
251#define UAC2_MD_UNDERFLOW 0x07
252#define UAC2_MD_OVERFLOW 0x08
253#define UAC2_MD_LATENCY 0x09
254
255/* A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors */
256#define UAC2_DR_UNDEFINED 0x00
257#define UAC2_DR_ENABLE 0x01
258#define UAC2_DR_COMPRESSION_RATE 0x02
259#define UAC2_DR_MAXAMPL 0x03
260#define UAC2_DR_THRESHOLD 0x04
261#define UAC2_DR_ATTACK_TIME 0x05
262#define UAC2_DR_RELEASE_TIME 0x06
263#define UAC2_DR_UNDEFLOW 0x07
264#define UAC2_DR_OVERFLOW 0x08
265#define UAC2_DR_LATENCY 0x09
266
267/* A.17.9.1 Up/Down-mix Processing Unit Control Selectors */
268#define UAC2_UD_UNDEFINED 0x00
269#define UAC2_UD_ENABLE 0x01
270#define UAC2_UD_MODE_SELECT 0x02
271#define UAC2_UD_CLUSTER 0x03
272#define UAC2_UD_UNDERFLOW 0x04
273#define UAC2_UD_OVERFLOW 0x05
274#define UAC2_UD_LATENCY 0x06
275
276/* A.17.9.2 Dolby Prologic[tm] Processing Unit Control Selectors */
277#define UAC2_DP_UNDEFINED 0x00
278#define UAC2_DP_ENABLE 0x01
279#define UAC2_DP_MODE_SELECT 0x02
280#define UAC2_DP_CLUSTER 0x03
281#define UAC2_DP_UNDERFFLOW 0x04
282#define UAC2_DP_OVERFLOW 0x05
283#define UAC2_DP_LATENCY 0x06
284
285/* A.17.9.3 Stereo Expander Processing Unit Control Selectors */
286#define UAC2_ST_EXT_UNDEFINED 0x00
287#define UAC2_ST_EXT_ENABLE 0x01
288#define UAC2_ST_EXT_WIDTH 0x02
289#define UAC2_ST_EXT_UNDEFLOW 0x03
290#define UAC2_ST_EXT_OVERFLOW 0x04
291#define UAC2_ST_EXT_LATENCY 0x05
292
293/* A.17.10 Extension Unit Control Selectors */
294#define UAC2_XU_UNDEFINED 0x00
295#define UAC2_XU_ENABLE 0x01
296#define UAC2_XU_CLUSTER 0x02
297#define UAC2_XU_UNDERFLOW 0x03
298#define UAC2_XU_OVERFLOW 0x04
299#define UAC2_XU_LATENCY 0x05
300
301/* A.17.11 AudioStreaming Interface Control Selectors */
302#define UAC2_AS_UNDEFINED 0x00
303#define UAC2_AS_ACT_ALT_SETTING 0x01
304#define UAC2_AS_VAL_ALT_SETTINGS 0x02
305#define UAC2_AS_AUDIO_DATA_FORMAT 0x03
306
307/* A.17.12 Encoder Control Selectors */
308#define UAC2_EN_UNDEFINED 0x00
309#define UAC2_EN_BIT_RATE 0x01
310#define UAC2_EN_QUALITY 0x02
311#define UAC2_EN_VBR 0x03
312#define UAC2_EN_TYPE 0x04
313#define UAC2_EN_UNDERFLOW 0x05
314#define UAC2_EN_OVERFLOW 0x06
315#define UAC2_EN_ENCODER_ERROR 0x07
316#define UAC2_EN_PARAM1 0x08
317#define UAC2_EN_PARAM2 0x09
318#define UAC2_EN_PARAM3 0x0a
319#define UAC2_EN_PARAM4 0x0b
320#define UAC2_EN_PARAM5 0x0c
321#define UAC2_EN_PARAM6 0x0d
322#define UAC2_EN_PARAM7 0x0e
323#define UAC2_EN_PARAM8 0x0f
324
325/* A.17.13.1 MPEG Decoder Control Selectors */
326#define UAC2_MPEG_UNDEFINED 0x00
327#define UAC2_MPEG_DUAL_CHANNEL 0x01
328#define UAC2_MPEG_SECOND_STEREO 0x02
329#define UAC2_MPEG_MULTILINGUAL 0x03
330#define UAC2_MPEG_DYN_RANGE 0x04
331#define UAC2_MPEG_SCALING 0x05
332#define UAC2_MPEG_HILO_SCALING 0x06
333#define UAC2_MPEG_UNDERFLOW 0x07
334#define UAC2_MPEG_OVERFLOW 0x08
335#define UAC2_MPEG_DECODER_ERROR 0x09
336
337/* A17.13.2 AC3 Decoder Control Selectors */
338#define UAC2_AC3_UNDEFINED 0x00
339#define UAC2_AC3_MODE 0x01
340#define UAC2_AC3_DYN_RANGE 0x02
341#define UAC2_AC3_SCALING 0x03
342#define UAC2_AC3_HILO_SCALING 0x04
343#define UAC2_AC3_UNDERFLOW 0x05
344#define UAC2_AC3_OVERFLOW 0x06
345#define UAC2_AC3_DECODER_ERROR 0x07
346
347/* A17.13.3 WMA Decoder Control Selectors */
348#define UAC2_WMA_UNDEFINED 0x00
349#define UAC2_WMA_UNDERFLOW 0x01
350#define UAC2_WMA_OVERFLOW 0x02
351#define UAC2_WMA_DECODER_ERROR 0x03
352
353/* A17.13.4 DTS Decoder Control Selectors */
354#define UAC2_DTS_UNDEFINED 0x00
355#define UAC2_DTS_UNDERFLOW 0x01
356#define UAC2_DTS_OVERFLOW 0x02
357#define UAC2_DTS_DECODER_ERROR 0x03
358
359/* A17.14 Endpoint Control Selectors */
360#define UAC2_EP_CS_UNDEFINED 0x00
361#define UAC2_EP_CS_PITCH 0x01
362#define UAC2_EP_CS_DATA_OVERRUN 0x02
363#define UAC2_EP_CS_DATA_UNDERRUN 0x03
364
365#endif /* __LINUX_USB_AUDIO_V2_H */
366
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h
index 4d3e450e2b03..905a87caf3fb 100644
--- a/include/linux/usb/audio.h
+++ b/include/linux/usb/audio.h
@@ -13,6 +13,9 @@
13 * Comments below reference relevant sections of that document: 13 * Comments below reference relevant sections of that document:
14 * 14 *
15 * http://www.usb.org/developers/devclass_docs/audio10.pdf 15 * http://www.usb.org/developers/devclass_docs/audio10.pdf
16 *
17 * Types and defines in this file are either specific to version 1.0 of
18 * this standard or common for newer versions.
16 */ 19 */
17 20
18#ifndef __LINUX_USB_AUDIO_H 21#ifndef __LINUX_USB_AUDIO_H
@@ -20,14 +23,15 @@
20 23
21#include <linux/types.h> 24#include <linux/types.h>
22 25
26/* bInterfaceProtocol values to denote the version of the standard used */
27#define UAC_VERSION_1 0x00
28#define UAC_VERSION_2 0x20
29
23/* A.2 Audio Interface Subclass Codes */ 30/* A.2 Audio Interface Subclass Codes */
24#define USB_SUBCLASS_AUDIOCONTROL 0x01 31#define USB_SUBCLASS_AUDIOCONTROL 0x01
25#define USB_SUBCLASS_AUDIOSTREAMING 0x02 32#define USB_SUBCLASS_AUDIOSTREAMING 0x02
26#define USB_SUBCLASS_MIDISTREAMING 0x03 33#define USB_SUBCLASS_MIDISTREAMING 0x03
27 34
28#define UAC_VERSION_1 0x00
29#define UAC_VERSION_2 0x20
30
31/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */ 35/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
32#define UAC_HEADER 0x01 36#define UAC_HEADER 0x01
33#define UAC_INPUT_TERMINAL 0x02 37#define UAC_INPUT_TERMINAL 0x02
@@ -38,15 +42,6 @@
38#define UAC_PROCESSING_UNIT_V1 0x07 42#define UAC_PROCESSING_UNIT_V1 0x07
39#define UAC_EXTENSION_UNIT_V1 0x08 43#define UAC_EXTENSION_UNIT_V1 0x08
40 44
41/* UAC v2.0 types */
42#define UAC_EFFECT_UNIT 0x07
43#define UAC_PROCESSING_UNIT_V2 0x08
44#define UAC_EXTENSION_UNIT_V2 0x09
45#define UAC_CLOCK_SOURCE 0x0a
46#define UAC_CLOCK_SELECTOR 0x0b
47#define UAC_CLOCK_MULTIPLIER 0x0c
48#define UAC_SAMPLE_RATE_CONVERTER 0x0d
49
50/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */ 45/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
51#define UAC_AS_GENERAL 0x01 46#define UAC_AS_GENERAL 0x01
52#define UAC_FORMAT_TYPE 0x02 47#define UAC_FORMAT_TYPE 0x02
@@ -78,10 +73,6 @@
78 73
79#define UAC_GET_STAT 0xff 74#define UAC_GET_STAT 0xff
80 75
81/* Audio class v2.0 handles all the parameter calls differently */
82#define UAC2_CS_CUR 0x01
83#define UAC2_CS_RANGE 0x02
84
85/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */ 76/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
86#define UAC_MS_HEADER 0x01 77#define UAC_MS_HEADER 0x01
87#define UAC_MIDI_IN_JACK 0x02 78#define UAC_MIDI_IN_JACK 0x02
@@ -190,6 +181,156 @@ struct uac_feature_unit_descriptor_##ch { \
190 __u8 iFeature; \ 181 __u8 iFeature; \
191} __attribute__ ((packed)) 182} __attribute__ ((packed))
192 183
184/* 4.3.2.3 Mixer Unit Descriptor */
185struct uac_mixer_unit_descriptor {
186 __u8 bLength;
187 __u8 bDescriptorType;
188 __u8 bDescriptorSubtype;
189 __u8 bUnitID;
190 __u8 bNrInPins;
191 __u8 baSourceID[];
192} __attribute__ ((packed));
193
194static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
195{
196 return desc->baSourceID[desc->bNrInPins];
197}
198
199static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
200 int protocol)
201{
202 if (protocol == UAC_VERSION_1)
203 return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
204 desc->baSourceID[desc->bNrInPins + 1];
205 else
206 return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
207 (desc->baSourceID[desc->bNrInPins + 3] << 16) |
208 (desc->baSourceID[desc->bNrInPins + 2] << 8) |
209 (desc->baSourceID[desc->bNrInPins + 1]);
210}
211
212static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
213 int protocol)
214{
215 return (protocol == UAC_VERSION_1) ?
216 desc->baSourceID[desc->bNrInPins + 3] :
217 desc->baSourceID[desc->bNrInPins + 5];
218}
219
220static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
221 int protocol)
222{
223 return (protocol == UAC_VERSION_1) ?
224 &desc->baSourceID[desc->bNrInPins + 4] :
225 &desc->baSourceID[desc->bNrInPins + 6];
226}
227
228static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
229{
230 __u8 *raw = (__u8 *) desc;
231 return raw[desc->bLength - 1];
232}
233
234/* 4.3.2.4 Selector Unit Descriptor */
235struct uac_selector_unit_descriptor {
236 __u8 bLength;
237 __u8 bDescriptorType;
238 __u8 bDescriptorSubtype;
239 __u8 bUintID;
240 __u8 bNrInPins;
241 __u8 baSourceID[];
242} __attribute__ ((packed));
243
244static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
245{
246 __u8 *raw = (__u8 *) desc;
247 return raw[desc->bLength - 1];
248}
249
250/* 4.3.2.5 Feature Unit Descriptor */
251struct uac_feature_unit_descriptor {
252 __u8 bLength;
253 __u8 bDescriptorType;
254 __u8 bDescriptorSubtype;
255 __u8 bUnitID;
256 __u8 bSourceID;
257 __u8 bControlSize;
258 __u8 bmaControls[0]; /* variable length */
259} __attribute__((packed));
260
261static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
262{
263 __u8 *raw = (__u8 *) desc;
264 return raw[desc->bLength - 1];
265}
266
267/* 4.3.2.6 Processing Unit Descriptors */
268struct uac_processing_unit_descriptor {
269 __u8 bLength;
270 __u8 bDescriptorType;
271 __u8 bDescriptorSubtype;
272 __u8 bUnitID;
273 __u16 wProcessType;
274 __u8 bNrInPins;
275 __u8 baSourceID[];
276} __attribute__ ((packed));
277
278static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
279{
280 return desc->baSourceID[desc->bNrInPins];
281}
282
283static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
284 int protocol)
285{
286 if (protocol == UAC_VERSION_1)
287 return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
288 desc->baSourceID[desc->bNrInPins + 1];
289 else
290 return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
291 (desc->baSourceID[desc->bNrInPins + 3] << 16) |
292 (desc->baSourceID[desc->bNrInPins + 2] << 8) |
293 (desc->baSourceID[desc->bNrInPins + 1]);
294}
295
296static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
297 int protocol)
298{
299 return (protocol == UAC_VERSION_1) ?
300 desc->baSourceID[desc->bNrInPins + 3] :
301 desc->baSourceID[desc->bNrInPins + 5];
302}
303
304static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
305 int protocol)
306{
307 return (protocol == UAC_VERSION_1) ?
308 desc->baSourceID[desc->bNrInPins + 4] :
309 desc->baSourceID[desc->bNrInPins + 6];
310}
311
312static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
313 int protocol)
314{
315 return (protocol == UAC_VERSION_1) ?
316 &desc->baSourceID[desc->bNrInPins + 5] :
317 &desc->baSourceID[desc->bNrInPins + 7];
318}
319
320static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
321 int protocol)
322{
323 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
324 return desc->baSourceID[desc->bNrInPins + control_size];
325}
326
327static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
328 int protocol)
329{
330 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
331 return &desc->baSourceID[desc->bNrInPins + control_size + 1];
332}
333
193/* 4.5.2 Class-Specific AS Interface Descriptor */ 334/* 4.5.2 Class-Specific AS Interface Descriptor */
194struct uac_as_header_descriptor_v1 { 335struct uac_as_header_descriptor_v1 {
195 __u8 bLength; /* in bytes: 7 */ 336 __u8 bLength; /* in bytes: 7 */
@@ -200,19 +341,6 @@ struct uac_as_header_descriptor_v1 {
200 __le16 wFormatTag; /* The Audio Data Format */ 341 __le16 wFormatTag; /* The Audio Data Format */
201} __attribute__ ((packed)); 342} __attribute__ ((packed));
202 343
203struct uac_as_header_descriptor_v2 {
204 __u8 bLength;
205 __u8 bDescriptorType;
206 __u8 bDescriptorSubtype;
207 __u8 bTerminalLink;
208 __u8 bmControls;
209 __u8 bFormatType;
210 __u32 bmFormats;
211 __u8 bNrChannels;
212 __u32 bmChannelConfig;
213 __u8 iChannelNames;
214} __attribute__((packed));
215
216#define UAC_DT_AS_HEADER_SIZE 7 344#define UAC_DT_AS_HEADER_SIZE 7
217 345
218/* Formats - A.1.1 Audio Data Format Type I Codes */ 346/* Formats - A.1.1 Audio Data Format Type I Codes */
@@ -277,7 +405,6 @@ struct uac_format_type_i_ext_descriptor {
277 __u8 bSideBandProtocol; 405 __u8 bSideBandProtocol;
278} __attribute__((packed)); 406} __attribute__((packed));
279 407
280
281/* Formats - Audio Data Format Type I Codes */ 408/* Formats - Audio Data Format Type I Codes */
282 409
283#define UAC_FORMAT_TYPE_II_MPEG 0x1001 410#define UAC_FORMAT_TYPE_II_MPEG 0x1001
@@ -336,31 +463,8 @@ struct uac_iso_endpoint_descriptor {
336#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02 463#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
337#define UAC_EP_CS_ATTR_FILL_MAX 0x80 464#define UAC_EP_CS_ATTR_FILL_MAX 0x80
338 465
339/* Audio class v2.0: CLOCK_SOURCE descriptor */
340
341struct uac_clock_source_descriptor {
342 __u8 bLength;
343 __u8 bDescriptorType;
344 __u8 bDescriptorSubtype;
345 __u8 bClockID;
346 __u8 bmAttributes;
347 __u8 bmControls;
348 __u8 bAssocTerminal;
349 __u8 iClockSource;
350} __attribute__((packed));
351
352/* A.10.2 Feature Unit Control Selectors */ 466/* A.10.2 Feature Unit Control Selectors */
353 467
354struct uac_feature_unit_descriptor {
355 __u8 bLength;
356 __u8 bDescriptorType;
357 __u8 bDescriptorSubtype;
358 __u8 bUnitID;
359 __u8 bSourceID;
360 __u8 bControlSize;
361 __u8 controls[0]; /* variable length */
362} __attribute__((packed));
363
364#define UAC_FU_CONTROL_UNDEFINED 0x00 468#define UAC_FU_CONTROL_UNDEFINED 0x00
365#define UAC_MUTE_CONTROL 0x01 469#define UAC_MUTE_CONTROL 0x01
366#define UAC_VOLUME_CONTROL 0x02 470#define UAC_VOLUME_CONTROL 0x02
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 098595500632..9f1eecf99e6b 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -574,7 +574,7 @@ enum {
574#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */ 574#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */
575 575
576struct snd_timer_id { 576struct snd_timer_id {
577 int dev_class; 577 int dev_class;
578 int dev_sclass; 578 int dev_sclass;
579 int card; 579 int card;
580 int device; 580 int device;
@@ -762,7 +762,7 @@ struct snd_ctl_elem_id {
762 snd_ctl_elem_iface_t iface; /* interface identifier */ 762 snd_ctl_elem_iface_t iface; /* interface identifier */
763 unsigned int device; /* device/client number */ 763 unsigned int device; /* device/client number */
764 unsigned int subdevice; /* subdevice (substream) number */ 764 unsigned int subdevice; /* subdevice (substream) number */
765 unsigned char name[44]; /* ASCII name of item */ 765 unsigned char name[44]; /* ASCII name of item */
766 unsigned int index; /* index of item */ 766 unsigned int index; /* index of item */
767}; 767};
768 768
@@ -809,7 +809,7 @@ struct snd_ctl_elem_info {
809struct snd_ctl_elem_value { 809struct snd_ctl_elem_value {
810 struct snd_ctl_elem_id id; /* W: element ID */ 810 struct snd_ctl_elem_id id; /* W: element ID */
811 unsigned int indirect: 1; /* W: indirect access - obsoleted */ 811 unsigned int indirect: 1; /* W: indirect access - obsoleted */
812 union { 812 union {
813 union { 813 union {
814 long value[128]; 814 long value[128];
815 long *value_ptr; /* obsoleted */ 815 long *value_ptr; /* obsoleted */
@@ -827,15 +827,15 @@ struct snd_ctl_elem_value {
827 unsigned char *data_ptr; /* obsoleted */ 827 unsigned char *data_ptr; /* obsoleted */
828 } bytes; 828 } bytes;
829 struct snd_aes_iec958 iec958; 829 struct snd_aes_iec958 iec958;
830 } value; /* RO */ 830 } value; /* RO */
831 struct timespec tstamp; 831 struct timespec tstamp;
832 unsigned char reserved[128-sizeof(struct timespec)]; 832 unsigned char reserved[128-sizeof(struct timespec)];
833}; 833};
834 834
835struct snd_ctl_tlv { 835struct snd_ctl_tlv {
836 unsigned int numid; /* control element numeric identification */ 836 unsigned int numid; /* control element numeric identification */
837 unsigned int length; /* in bytes aligned to 4 */ 837 unsigned int length; /* in bytes aligned to 4 */
838 unsigned int tlv[0]; /* first TLV */ 838 unsigned int tlv[0]; /* first TLV */
839}; 839};
840 840
841#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) 841#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
@@ -886,8 +886,8 @@ struct snd_ctl_event {
886 unsigned int mask; 886 unsigned int mask;
887 struct snd_ctl_elem_id id; 887 struct snd_ctl_elem_id id;
888 } elem; 888 } elem;
889 unsigned char data8[60]; 889 unsigned char data8[60];
890 } data; 890 } data;
891}; 891};
892 892
893/* 893/*
diff --git a/include/sound/es1688.h b/include/sound/es1688.h
index 10fcf1465810..3ec7ecbe2502 100644
--- a/include/sound/es1688.h
+++ b/include/sound/es1688.h
@@ -44,7 +44,6 @@ struct snd_es1688 {
44 unsigned char pad; 44 unsigned char pad;
45 unsigned int dma_size; 45 unsigned int dma_size;
46 46
47 struct snd_card *card;
48 struct snd_pcm *pcm; 47 struct snd_pcm *pcm;
49 struct snd_pcm_substream *playback_substream; 48 struct snd_pcm_substream *playback_substream;
50 struct snd_pcm_substream *capture_substream; 49 struct snd_pcm_substream *capture_substream;
@@ -108,14 +107,16 @@ struct snd_es1688 {
108void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data); 107void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data);
109 108
110int snd_es1688_create(struct snd_card *card, 109int snd_es1688_create(struct snd_card *card,
110 struct snd_es1688 *chip,
111 unsigned long port, 111 unsigned long port,
112 unsigned long mpu_port, 112 unsigned long mpu_port,
113 int irq, 113 int irq,
114 int mpu_irq, 114 int mpu_irq,
115 int dma8, 115 int dma8,
116 unsigned short hardware, 116 unsigned short hardware);
117 struct snd_es1688 ** rchip); 117int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device,
118int snd_es1688_pcm(struct snd_es1688 *chip, int device, struct snd_pcm ** rpcm); 118 struct snd_pcm **rpcm);
119int snd_es1688_mixer(struct snd_es1688 *chip); 119int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip);
120int snd_es1688_reset(struct snd_es1688 *chip);
120 121
121#endif /* __SOUND_ES1688_H */ 122#endif /* __SOUND_ES1688_H */
diff --git a/include/sound/version.h b/include/sound/version.h
index 7fed23442db8..bf69a5b7e65f 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h */ 1/* include/version.h */
2#define CONFIG_SND_VERSION "1.0.22.1" 2#define CONFIG_SND_VERSION "1.0.23"
3#define CONFIG_SND_DATE "" 3#define CONFIG_SND_DATE ""
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index 5c0c77dd01c3..eb7c7d05a7c1 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -98,7 +98,8 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
98 bus->master = master; 98 bus->master = master;
99 } 99 }
100 strlcpy(bus->name, name, sizeof(bus->name)); 100 strlcpy(bus->name, name, sizeof(bus->name));
101 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)) < 0) { 101 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
102 if (err < 0) {
102 snd_i2c_bus_free(bus); 103 snd_i2c_bus_free(bus);
103 return err; 104 return err;
104 } 105 }
@@ -246,7 +247,8 @@ static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
246 247
247 for (i = 7; i >= 0; i--) 248 for (i = 7; i >= 0; i--)
248 snd_i2c_bit_send(bus, !!(data & (1 << i))); 249 snd_i2c_bit_send(bus, !!(data & (1 << i)));
249 if ((err = snd_i2c_bit_ack(bus)) < 0) 250 err = snd_i2c_bit_ack(bus);
251 if (err < 0)
250 return err; 252 return err;
251 return 0; 253 return 0;
252} 254}
@@ -278,12 +280,14 @@ static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
278 if (device->flags & SND_I2C_DEVICE_ADDRTEN) 280 if (device->flags & SND_I2C_DEVICE_ADDRTEN)
279 return -EIO; /* not yet implemented */ 281 return -EIO; /* not yet implemented */
280 snd_i2c_bit_start(bus); 282 snd_i2c_bit_start(bus);
281 if ((err = snd_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) { 283 err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
284 if (err < 0) {
282 snd_i2c_bit_hw_stop(bus); 285 snd_i2c_bit_hw_stop(bus);
283 return err; 286 return err;
284 } 287 }
285 while (count-- > 0) { 288 while (count-- > 0) {
286 if ((err = snd_i2c_bit_sendbyte(bus, *bytes++)) < 0) { 289 err = snd_i2c_bit_sendbyte(bus, *bytes++);
290 if (err < 0) {
287 snd_i2c_bit_hw_stop(bus); 291 snd_i2c_bit_hw_stop(bus);
288 return err; 292 return err;
289 } 293 }
@@ -302,12 +306,14 @@ static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
302 if (device->flags & SND_I2C_DEVICE_ADDRTEN) 306 if (device->flags & SND_I2C_DEVICE_ADDRTEN)
303 return -EIO; /* not yet implemented */ 307 return -EIO; /* not yet implemented */
304 snd_i2c_bit_start(bus); 308 snd_i2c_bit_start(bus);
305 if ((err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) { 309 err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
310 if (err < 0) {
306 snd_i2c_bit_hw_stop(bus); 311 snd_i2c_bit_hw_stop(bus);
307 return err; 312 return err;
308 } 313 }
309 while (count-- > 0) { 314 while (count-- > 0) {
310 if ((err = snd_i2c_bit_readbyte(bus, count == 0)) < 0) { 315 err = snd_i2c_bit_readbyte(bus, count == 0);
316 if (err < 0) {
311 snd_i2c_bit_hw_stop(bus); 317 snd_i2c_bit_hw_stop(bus);
312 return err; 318 return err;
313 } 319 }
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 755a0a5f0e3f..c6990c680796 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -128,26 +128,14 @@ config SND_CS4236
128 To compile this driver as a module, choose M here: the module 128 To compile this driver as a module, choose M here: the module
129 will be called snd-cs4236. 129 will be called snd-cs4236.
130 130
131config SND_ES968
132 tristate "Generic ESS ES968 driver"
133 depends on PNP
134 select ISAPNP
135 select SND_MPU401_UART
136 select SND_SB8_DSP
137 help
138 Say Y here to include support for ESS AudioDrive ES968 chips.
139
140 To compile this driver as a module, choose M here: the module
141 will be called snd-es968.
142
143config SND_ES1688 131config SND_ES1688
144 tristate "Generic ESS ES688/ES1688 driver" 132 tristate "Generic ESS ES688/ES1688 and ES968 PnP driver"
145 select SND_OPL3_LIB 133 select SND_OPL3_LIB
146 select SND_MPU401_UART 134 select SND_MPU401_UART
147 select SND_PCM 135 select SND_PCM
148 help 136 help
149 Say Y here to include support for ESS AudioDrive ES688 or 137 Say Y here to include support for ESS AudioDrive ES688 or
150 ES1688 chips. 138 ES1688 chips. Also, this module support cards with ES968 PnP chip.
151 139
152 To compile this driver as a module, choose M here: the module 140 To compile this driver as a module, choose M here: the module
153 will be called snd-es1688. 141 will be called snd-es1688.
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 07df201ed8fa..0cde8131a575 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/isapnp.h>
25#include <linux/time.h> 26#include <linux/time.h>
26#include <linux/wait.h> 27#include <linux/wait.h>
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
@@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
45 "{ESS,ES688 AudioDrive,pnp:ESS6881}," 46 "{ESS,ES688 AudioDrive,pnp:ESS6881},"
46 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); 47 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}");
47 48
49MODULE_ALIAS("snd_es968");
50
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53#ifdef CONFIG_PNP
54static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
55#endif
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ 56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ 57static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
52static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ 58static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
@@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
60module_param_array(id, charp, NULL, 0444); 66module_param_array(id, charp, NULL, 0444);
61MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); 67MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
62module_param_array(enable, bool, NULL, 0444); 68module_param_array(enable, bool, NULL, 0444);
69#ifdef CONFIG_PNP
70module_param_array(isapnp, bool, NULL, 0444);
71MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
72#endif
63MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); 73MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
64module_param_array(port, long, NULL, 0444); 74module_param_array(port, long, NULL, 0444);
65MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); 75MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
@@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
74module_param_array(dma8, int, NULL, 0444); 84module_param_array(dma8, int, NULL, 0444);
75MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); 85MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
76 86
87#ifdef CONFIG_PNP
88#define is_isapnp_selected(dev) isapnp[dev]
89#else
90#define is_isapnp_selected(dev) 0
91#endif
92
77static int __devinit snd_es1688_match(struct device *dev, unsigned int n) 93static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
78{ 94{
79 return enable[n]; 95 return enable[n] && !is_isapnp_selected(n);
80} 96}
81 97
82static int __devinit snd_es1688_legacy_create(struct snd_card *card, 98static int __devinit snd_es1688_legacy_create(struct snd_card *card,
83 struct device *dev, unsigned int n, struct snd_es1688 **rchip) 99 struct device *dev, unsigned int n)
84{ 100{
101 struct snd_es1688 *chip = card->private_data;
85 static long possible_ports[] = {0x220, 0x240, 0x260}; 102 static long possible_ports[] = {0x220, 0x240, 0x260};
86 static int possible_irqs[] = {5, 9, 10, 7, -1}; 103 static int possible_irqs[] = {5, 9, 10, 7, -1};
87 static int possible_dmas[] = {1, 3, 0, -1}; 104 static int possible_dmas[] = {1, 3, 0, -1};
@@ -104,47 +121,39 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card,
104 } 121 }
105 122
106 if (port[n] != SNDRV_AUTO_PORT) 123 if (port[n] != SNDRV_AUTO_PORT)
107 return snd_es1688_create(card, port[n], mpu_port[n], irq[n], 124 return snd_es1688_create(card, chip, port[n], mpu_port[n],
108 mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); 125 irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
109 126
110 i = 0; 127 i = 0;
111 do { 128 do {
112 port[n] = possible_ports[i]; 129 port[n] = possible_ports[i];
113 error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], 130 error = snd_es1688_create(card, chip, port[n], mpu_port[n],
114 mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); 131 irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
115 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); 132 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
116 133
117 return error; 134 return error;
118} 135}
119 136
120static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) 137static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
121{ 138{
122 struct snd_card *card; 139 struct snd_es1688 *chip = card->private_data;
123 struct snd_es1688 *chip;
124 struct snd_opl3 *opl3; 140 struct snd_opl3 *opl3;
125 struct snd_pcm *pcm; 141 struct snd_pcm *pcm;
126 int error; 142 int error;
127 143
128 error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); 144 error = snd_es1688_pcm(card, chip, 0, &pcm);
129 if (error < 0) 145 if (error < 0)
130 return error; 146 return error;
131 147
132 error = snd_es1688_legacy_create(card, dev, n, &chip); 148 error = snd_es1688_mixer(card, chip);
133 if (error < 0)
134 goto out;
135
136 error = snd_es1688_pcm(chip, 0, &pcm);
137 if (error < 0) 149 if (error < 0)
138 goto out; 150 return error;
139
140 error = snd_es1688_mixer(chip);
141 if (error < 0)
142 goto out;
143 151
144 strcpy(card->driver, "ES1688"); 152 strlcpy(card->driver, "ES1688", sizeof(card->driver));
145 strcpy(card->shortname, pcm->name); 153 strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
146 sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, 154 snprintf(card->longname, sizeof(card->longname),
147 chip->port, chip->irq, chip->dma8); 155 "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
156 chip->irq, chip->dma8);
148 157
149 if (fm_port[n] == SNDRV_AUTO_PORT) 158 if (fm_port[n] == SNDRV_AUTO_PORT)
150 fm_port[n] = port[n]; /* share the same port */ 159 fm_port[n] = port[n]; /* share the same port */
@@ -152,12 +161,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
152 if (fm_port[n] > 0) { 161 if (fm_port[n] > 0) {
153 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, 162 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
154 OPL3_HW_OPL3, 0, &opl3) < 0) 163 OPL3_HW_OPL3, 0, &opl3) < 0)
155 dev_warn(dev, 164 dev_warn(card->dev,
156 "opl3 not detected at 0x%lx\n", fm_port[n]); 165 "opl3 not detected at 0x%lx\n", fm_port[n]);
157 else { 166 else {
158 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 167 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
159 if (error < 0) 168 if (error < 0)
160 goto out; 169 return error;
161 } 170 }
162 } 171 }
163 172
@@ -167,23 +176,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
167 chip->mpu_port, 0, 176 chip->mpu_port, 0,
168 mpu_irq[n], IRQF_DISABLED, NULL); 177 mpu_irq[n], IRQF_DISABLED, NULL);
169 if (error < 0) 178 if (error < 0)
170 goto out; 179 return error;
171 } 180 }
172 181
182 return snd_card_register(card);
183}
184
185static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
186{
187 struct snd_card *card;
188 int error;
189
190 error = snd_card_create(index[n], id[n], THIS_MODULE,
191 sizeof(struct snd_es1688), &card);
192 if (error < 0)
193 return error;
194
195 error = snd_es1688_legacy_create(card, dev, n);
196 if (error < 0)
197 goto out;
198
173 snd_card_set_dev(card, dev); 199 snd_card_set_dev(card, dev);
174 200
175 error = snd_card_register(card); 201 error = snd_es1688_probe(card, n);
176 if (error < 0) 202 if (error < 0)
177 goto out; 203 goto out;
178 204
179 dev_set_drvdata(dev, card); 205 dev_set_drvdata(dev, card);
180 return 0;
181 206
182out: snd_card_free(card); 207 return 0;
208out:
209 snd_card_free(card);
183 return error; 210 return error;
184} 211}
185 212
186static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) 213static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
187{ 214{
188 snd_card_free(dev_get_drvdata(dev)); 215 snd_card_free(dev_get_drvdata(dev));
189 dev_set_drvdata(dev, NULL); 216 dev_set_drvdata(dev, NULL);
@@ -192,8 +219,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
192 219
193static struct isa_driver snd_es1688_driver = { 220static struct isa_driver snd_es1688_driver = {
194 .match = snd_es1688_match, 221 .match = snd_es1688_match,
195 .probe = snd_es1688_probe, 222 .probe = snd_es1688_isa_probe,
196 .remove = __devexit_p(snd_es1688_remove), 223 .remove = __devexit_p(snd_es1688_isa_remove),
197#if 0 /* FIXME */ 224#if 0 /* FIXME */
198 .suspend = snd_es1688_suspend, 225 .suspend = snd_es1688_suspend,
199 .resume = snd_es1688_resume, 226 .resume = snd_es1688_resume,
@@ -203,14 +230,142 @@ static struct isa_driver snd_es1688_driver = {
203 } 230 }
204}; 231};
205 232
233static int snd_es968_pnp_is_probed;
234
235#ifdef CONFIG_PNP
236static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
237 struct pnp_card_link *pcard,
238 const struct pnp_card_device_id *pid)
239{
240 struct snd_es1688 *chip = card->private_data;
241 struct pnp_dev *pdev;
242 int error;
243
244 pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
245 if (pdev == NULL)
246 return -ENODEV;
247
248 error = pnp_activate_dev(pdev);
249 if (error < 0) {
250 snd_printk(KERN_ERR "ES968 pnp configure failure\n");
251 return error;
252 }
253 port[n] = pnp_port_start(pdev, 0);
254 dma8[n] = pnp_dma(pdev, 0);
255 irq[n] = pnp_irq(pdev, 0);
256
257 return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
258 mpu_irq[n], dma8[n], ES1688_HW_AUTO);
259}
260
261static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
262 const struct pnp_card_device_id *pid)
263{
264 struct snd_card *card;
265 static unsigned int dev;
266 int error;
267 struct snd_es1688 *chip;
268
269 if (snd_es968_pnp_is_probed)
270 return -EBUSY;
271 for ( ; dev < SNDRV_CARDS; dev++) {
272 if (enable[dev] && isapnp[dev])
273 break;
274 }
275 if (dev == SNDRV_CARDS)
276 return -ENODEV;
277
278 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
279 sizeof(struct snd_es1688), &card);
280 if (error < 0)
281 return error;
282 chip = card->private_data;
283
284 error = snd_card_es968_pnp(card, dev, pcard, pid);
285 if (error < 0) {
286 snd_card_free(card);
287 return error;
288 }
289 snd_card_set_dev(card, &pcard->card->dev);
290 error = snd_es1688_probe(card, dev);
291 if (error < 0)
292 return error;
293 pnp_set_card_drvdata(pcard, card);
294 snd_es968_pnp_is_probed = 1;
295 return 0;
296}
297
298static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
299{
300 snd_card_free(pnp_get_card_drvdata(pcard));
301 pnp_set_card_drvdata(pcard, NULL);
302 snd_es968_pnp_is_probed = 0;
303}
304
305#ifdef CONFIG_PM
306static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
307 pm_message_t state)
308{
309 struct snd_card *card = pnp_get_card_drvdata(pcard);
310 struct snd_es1688 *chip = card->private_data;
311
312 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
313 snd_pcm_suspend_all(chip->pcm);
314 return 0;
315}
316
317static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
318{
319 struct snd_card *card = pnp_get_card_drvdata(pcard);
320 struct snd_es1688 *chip = card->private_data;
321
322 snd_es1688_reset(chip);
323 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
324 return 0;
325}
326#endif
327
328static struct pnp_card_device_id snd_es968_pnpids[] = {
329 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
330 { .id = "ESS0968", .devs = { { "ESS0968" }, } },
331 { .id = "", } /* end */
332};
333
334MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
335
336static struct pnp_card_driver es968_pnpc_driver = {
337 .flags = PNP_DRIVER_RES_DISABLE,
338 .name = DEV_NAME " PnP",
339 .id_table = snd_es968_pnpids,
340 .probe = snd_es968_pnp_detect,
341 .remove = __devexit_p(snd_es968_pnp_remove),
342#ifdef CONFIG_PM
343 .suspend = snd_es968_pnp_suspend,
344 .resume = snd_es968_pnp_resume,
345#endif
346};
347#endif
348
206static int __init alsa_card_es1688_init(void) 349static int __init alsa_card_es1688_init(void)
207{ 350{
351#ifdef CONFIG_PNP
352 pnp_register_card_driver(&es968_pnpc_driver);
353 if (snd_es968_pnp_is_probed)
354 return 0;
355 pnp_unregister_card_driver(&es968_pnpc_driver);
356#endif
208 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); 357 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
209} 358}
210 359
211static void __exit alsa_card_es1688_exit(void) 360static void __exit alsa_card_es1688_exit(void)
212{ 361{
213 isa_unregister_driver(&snd_es1688_driver); 362 if (!snd_es968_pnp_is_probed) {
363 isa_unregister_driver(&snd_es1688_driver);
364 return;
365 }
366#ifdef CONFIG_PNP
367 pnp_unregister_card_driver(&es968_pnpc_driver);
368#endif
214} 369}
215 370
216module_init(alsa_card_es1688_init); 371module_init(alsa_card_es1688_init);
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index c76bb00c9d15..07676200496a 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -99,7 +99,7 @@ static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned cha
99 return result; 99 return result;
100} 100}
101 101
102static int snd_es1688_reset(struct snd_es1688 *chip) 102int snd_es1688_reset(struct snd_es1688 *chip)
103{ 103{
104 int i; 104 int i;
105 105
@@ -115,6 +115,7 @@ static int snd_es1688_reset(struct snd_es1688 *chip)
115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ 115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */
116 return 0; 116 return 0;
117} 117}
118EXPORT_SYMBOL(snd_es1688_reset);
118 119
119static int snd_es1688_probe(struct snd_es1688 *chip) 120static int snd_es1688_probe(struct snd_es1688 *chip)
120{ 121{
@@ -620,7 +621,6 @@ static int snd_es1688_free(struct snd_es1688 *chip)
620 disable_dma(chip->dma8); 621 disable_dma(chip->dma8);
621 free_dma(chip->dma8); 622 free_dma(chip->dma8);
622 } 623 }
623 kfree(chip);
624 return 0; 624 return 0;
625} 625}
626 626
@@ -638,23 +638,20 @@ static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
638} 638}
639 639
640int snd_es1688_create(struct snd_card *card, 640int snd_es1688_create(struct snd_card *card,
641 struct snd_es1688 *chip,
641 unsigned long port, 642 unsigned long port,
642 unsigned long mpu_port, 643 unsigned long mpu_port,
643 int irq, 644 int irq,
644 int mpu_irq, 645 int mpu_irq,
645 int dma8, 646 int dma8,
646 unsigned short hardware, 647 unsigned short hardware)
647 struct snd_es1688 **rchip)
648{ 648{
649 static struct snd_device_ops ops = { 649 static struct snd_device_ops ops = {
650 .dev_free = snd_es1688_dev_free, 650 .dev_free = snd_es1688_dev_free,
651 }; 651 };
652 652
653 struct snd_es1688 *chip;
654 int err; 653 int err;
655 654
656 *rchip = NULL;
657 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
658 if (chip == NULL) 655 if (chip == NULL)
659 return -ENOMEM; 656 return -ENOMEM;
660 chip->irq = -1; 657 chip->irq = -1;
@@ -662,25 +659,21 @@ int snd_es1688_create(struct snd_card *card,
662 659
663 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { 660 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
664 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 661 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
665 snd_es1688_free(chip);
666 return -EBUSY; 662 return -EBUSY;
667 } 663 }
668 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { 664 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) {
669 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 665 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
670 snd_es1688_free(chip);
671 return -EBUSY; 666 return -EBUSY;
672 } 667 }
673 chip->irq = irq; 668 chip->irq = irq;
674 if (request_dma(dma8, "ES1688")) { 669 if (request_dma(dma8, "ES1688")) {
675 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); 670 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
676 snd_es1688_free(chip);
677 return -EBUSY; 671 return -EBUSY;
678 } 672 }
679 chip->dma8 = dma8; 673 chip->dma8 = dma8;
680 674
681 spin_lock_init(&chip->reg_lock); 675 spin_lock_init(&chip->reg_lock);
682 spin_lock_init(&chip->mixer_lock); 676 spin_lock_init(&chip->mixer_lock);
683 chip->card = card;
684 chip->port = port; 677 chip->port = port;
685 mpu_port &= ~0x000f; 678 mpu_port &= ~0x000f;
686 if (mpu_port < 0x300 || mpu_port > 0x330) 679 if (mpu_port < 0x300 || mpu_port > 0x330)
@@ -689,23 +682,16 @@ int snd_es1688_create(struct snd_card *card,
689 chip->mpu_irq = mpu_irq; 682 chip->mpu_irq = mpu_irq;
690 chip->hardware = hardware; 683 chip->hardware = hardware;
691 684
692 if ((err = snd_es1688_probe(chip)) < 0) { 685 err = snd_es1688_probe(chip);
693 snd_es1688_free(chip); 686 if (err < 0)
694 return err; 687 return err;
695 }
696 if ((err = snd_es1688_init(chip, 1)) < 0) {
697 snd_es1688_free(chip);
698 return err;
699 }
700 688
701 /* Register device */ 689 err = snd_es1688_init(chip, 1);
702 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 690 if (err < 0)
703 snd_es1688_free(chip);
704 return err; 691 return err;
705 }
706 692
707 *rchip = chip; 693 /* Register device */
708 return 0; 694 return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
709} 695}
710 696
711static struct snd_pcm_ops snd_es1688_playback_ops = { 697static struct snd_pcm_ops snd_es1688_playback_ops = {
@@ -730,12 +716,14 @@ static struct snd_pcm_ops snd_es1688_capture_ops = {
730 .pointer = snd_es1688_capture_pointer, 716 .pointer = snd_es1688_capture_pointer,
731}; 717};
732 718
733int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm) 719int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
720 int device, struct snd_pcm **rpcm)
734{ 721{
735 struct snd_pcm *pcm; 722 struct snd_pcm *pcm;
736 int err; 723 int err;
737 724
738 if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0) 725 err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm);
726 if (err < 0)
739 return err; 727 return err;
740 728
741 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops); 729 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops);
@@ -1009,18 +997,15 @@ static unsigned char snd_es1688_init_table[][2] = {
1009 { ES1688_REC_DEV, 0x17 } 997 { ES1688_REC_DEV, 0x17 }
1010}; 998};
1011 999
1012int snd_es1688_mixer(struct snd_es1688 *chip) 1000int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
1013{ 1001{
1014 struct snd_card *card;
1015 unsigned int idx; 1002 unsigned int idx;
1016 int err; 1003 int err;
1017 unsigned char reg, val; 1004 unsigned char reg, val;
1018 1005
1019 if (snd_BUG_ON(!chip || !chip->card)) 1006 if (snd_BUG_ON(!chip || !card))
1020 return -EINVAL; 1007 return -EINVAL;
1021 1008
1022 card = chip->card;
1023
1024 strcpy(card->mixername, snd_es1688_chip_id(chip)); 1009 strcpy(card->mixername, snd_es1688_chip_id(chip));
1025 1010
1026 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) { 1011 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 65e4b18581a6..008e8e5bfa37 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -95,7 +95,7 @@ static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
95} 95}
96 96
97static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, 97static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
98 struct device *dev, unsigned int n, struct snd_es1688 **rchip) 98 struct snd_es1688 *chip, struct device *dev, unsigned int n)
99{ 99{
100 static long possible_ports[] = {0x220, 0x240, 0x260}; 100 static long possible_ports[] = {0x220, 0x240, 0x260};
101 static int possible_irqs[] = {5, 9, 10, 7, -1}; 101 static int possible_irqs[] = {5, 9, 10, 7, -1};
@@ -119,14 +119,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
119 } 119 }
120 120
121 if (port[n] != SNDRV_AUTO_PORT) 121 if (port[n] != SNDRV_AUTO_PORT)
122 return snd_es1688_create(card, port[n], mpu_port[n], irq[n], 122 return snd_es1688_create(card, chip, port[n], mpu_port[n],
123 mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); 123 irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
124 124
125 i = 0; 125 i = 0;
126 do { 126 do {
127 port[n] = possible_ports[i]; 127 port[n] = possible_ports[i];
128 error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], 128 error = snd_es1688_create(card, chip, port[n], mpu_port[n],
129 mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); 129 irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
130 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); 130 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
131 131
132 return error; 132 return error;
@@ -206,9 +206,8 @@ static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
206 return 0; 206 return 0;
207} 207}
208 208
209static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) 209static int __devinit snd_gusextreme_mixer(struct snd_card *card)
210{ 210{
211 struct snd_card *card = chip->card;
212 struct snd_ctl_elem_id id1, id2; 211 struct snd_ctl_elem_id id1, id2;
213 int error; 212 int error;
214 213
@@ -241,17 +240,20 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
241 struct snd_opl3 *opl3; 240 struct snd_opl3 *opl3;
242 int error; 241 int error;
243 242
244 error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); 243 error = snd_card_create(index[n], id[n], THIS_MODULE,
244 sizeof(struct snd_es1688), &card);
245 if (error < 0) 245 if (error < 0)
246 return error; 246 return error;
247 247
248 es1688 = card->private_data;
249
248 if (mpu_port[n] == SNDRV_AUTO_PORT) 250 if (mpu_port[n] == SNDRV_AUTO_PORT)
249 mpu_port[n] = 0; 251 mpu_port[n] = 0;
250 252
251 if (mpu_irq[n] > 15) 253 if (mpu_irq[n] > 15)
252 mpu_irq[n] = -1; 254 mpu_irq[n] = -1;
253 255
254 error = snd_gusextreme_es1688_create(card, dev, n, &es1688); 256 error = snd_gusextreme_es1688_create(card, es1688, dev, n);
255 if (error < 0) 257 if (error < 0)
256 goto out; 258 goto out;
257 259
@@ -280,11 +282,11 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
280 } 282 }
281 gus->codec_flag = 1; 283 gus->codec_flag = 1;
282 284
283 error = snd_es1688_pcm(es1688, 0, NULL); 285 error = snd_es1688_pcm(card, es1688, 0, NULL);
284 if (error < 0) 286 if (error < 0)
285 goto out; 287 goto out;
286 288
287 error = snd_es1688_mixer(es1688); 289 error = snd_es1688_mixer(card, es1688);
288 if (error < 0) 290 if (error < 0)
289 goto out; 291 goto out;
290 292
@@ -300,7 +302,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
300 if (error < 0) 302 if (error < 0)
301 goto out; 303 goto out;
302 304
303 error = snd_gusextreme_mixer(es1688); 305 error = snd_gusextreme_mixer(card);
304 if (error < 0) 306 if (error < 0)
305 goto out; 307 goto out;
306 308
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index af3669681788..08b9fb974658 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -11,7 +11,6 @@ snd-sb8-objs := sb8.o
11snd-sb16-objs := sb16.o 11snd-sb16-objs := sb16.o
12snd-sbawe-objs := sbawe.o emu8000.o 12snd-sbawe-objs := sbawe.o emu8000.o
13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
14snd-es968-objs := es968.o
15snd-jazz16-objs := jazz16.o 14snd-jazz16-objs := jazz16.o
16 15
17# Toplevel Module Dependency 16# Toplevel Module Dependency
@@ -21,7 +20,6 @@ obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o
21obj-$(CONFIG_SND_SB8) += snd-sb8.o 20obj-$(CONFIG_SND_SB8) += snd-sb8.o
22obj-$(CONFIG_SND_SB16) += snd-sb16.o 21obj-$(CONFIG_SND_SB16) += snd-sb16.o
23obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 22obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
24obj-$(CONFIG_SND_ES968) += snd-es968.o
25obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o 23obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
26ifeq ($(CONFIG_SND_SB16_CSP),y) 24ifeq ($(CONFIG_SND_SB16_CSP),y)
27 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 25 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c
deleted file mode 100644
index ff18286fef9d..000000000000
--- a/sound/isa/sb/es968.c
+++ /dev/null
@@ -1,248 +0,0 @@
1
2/*
3 card-es968.c - driver for ESS AudioDrive ES968 based soundcards.
4 Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it>
5
6 Thanks to Pierfrancesco 'qM2' Passerini.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/time.h>
25#include <linux/pnp.h>
26#include <linux/moduleparam.h>
27#include <sound/core.h>
28#include <sound/initval.h>
29#include <sound/sb.h>
30
31#define PFX "es968: "
32
33MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
34MODULE_DESCRIPTION("ESS AudioDrive ES968");
35MODULE_LICENSE("GPL");
36MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}");
37
38static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
39static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
40static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
41static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
42static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
43static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
44
45module_param_array(index, int, NULL, 0444);
46MODULE_PARM_DESC(index, "Index value for es968 based soundcard.");
47module_param_array(id, charp, NULL, 0444);
48MODULE_PARM_DESC(id, "ID string for es968 based soundcard.");
49module_param_array(enable, bool, NULL, 0444);
50MODULE_PARM_DESC(enable, "Enable es968 based soundcard.");
51
52struct snd_card_es968 {
53 struct pnp_dev *dev;
54 struct snd_sb *chip;
55};
56
57static struct pnp_card_device_id snd_es968_pnpids[] = {
58 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
59 { .id = "", } /* end */
60};
61
62MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
63
64#define DRIVER_NAME "snd-card-es968"
65
66static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id)
67{
68 struct snd_sb *chip = dev_id;
69
70 if (chip->open & SB_OPEN_PCM) {
71 return snd_sb8dsp_interrupt(chip);
72 } else {
73 return snd_sb8dsp_midi_interrupt(chip);
74 }
75}
76
77static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
78 struct pnp_card_link *card,
79 const struct pnp_card_device_id *id)
80{
81 struct pnp_dev *pdev;
82 int err;
83
84 acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
85 if (acard->dev == NULL)
86 return -ENODEV;
87
88 pdev = acard->dev;
89
90 err = pnp_activate_dev(pdev);
91 if (err < 0) {
92 snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
93 return err;
94 }
95 port[dev] = pnp_port_start(pdev, 0);
96 dma8[dev] = pnp_dma(pdev, 0);
97 irq[dev] = pnp_irq(pdev, 0);
98
99 return 0;
100}
101
102static int __devinit snd_card_es968_probe(int dev,
103 struct pnp_card_link *pcard,
104 const struct pnp_card_device_id *pid)
105{
106 int error;
107 struct snd_sb *chip;
108 struct snd_card *card;
109 struct snd_card_es968 *acard;
110
111 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
112 sizeof(struct snd_card_es968), &card);
113 if (error < 0)
114 return error;
115 acard = card->private_data;
116 if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) {
117 snd_card_free(card);
118 return error;
119 }
120 snd_card_set_dev(card, &pcard->card->dev);
121
122 if ((error = snd_sbdsp_create(card, port[dev],
123 irq[dev],
124 snd_card_es968_interrupt,
125 dma8[dev],
126 -1,
127 SB_HW_AUTO, &chip)) < 0) {
128 snd_card_free(card);
129 return error;
130 }
131 acard->chip = chip;
132
133 if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
134 snd_card_free(card);
135 return error;
136 }
137
138 if ((error = snd_sbmixer_new(chip)) < 0) {
139 snd_card_free(card);
140 return error;
141 }
142
143 if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) {
144 snd_card_free(card);
145 return error;
146 }
147
148 strcpy(card->driver, "ES968");
149 strcpy(card->shortname, "ESS ES968");
150 sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d",
151 card->shortname, chip->name, chip->port, irq[dev], dma8[dev]);
152
153 if ((error = snd_card_register(card)) < 0) {
154 snd_card_free(card);
155 return error;
156 }
157 pnp_set_card_drvdata(pcard, card);
158 return 0;
159}
160
161static unsigned int __devinitdata es968_devices;
162
163static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
164 const struct pnp_card_device_id *id)
165{
166 static int dev;
167 int res;
168
169 for ( ; dev < SNDRV_CARDS; dev++) {
170 if (!enable[dev])
171 continue;
172 res = snd_card_es968_probe(dev, card, id);
173 if (res < 0)
174 return res;
175 dev++;
176 es968_devices++;
177 return 0;
178 }
179 return -ENODEV;
180}
181
182static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
183{
184 snd_card_free(pnp_get_card_drvdata(pcard));
185 pnp_set_card_drvdata(pcard, NULL);
186}
187
188#ifdef CONFIG_PM
189static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
190{
191 struct snd_card *card = pnp_get_card_drvdata(pcard);
192 struct snd_card_es968 *acard = card->private_data;
193 struct snd_sb *chip = acard->chip;
194
195 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
196 snd_pcm_suspend_all(chip->pcm);
197 snd_sbmixer_suspend(chip);
198 return 0;
199}
200
201static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
202{
203 struct snd_card *card = pnp_get_card_drvdata(pcard);
204 struct snd_card_es968 *acard = card->private_data;
205 struct snd_sb *chip = acard->chip;
206
207 snd_sbdsp_reset(chip);
208 snd_sbmixer_resume(chip);
209 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
210 return 0;
211}
212#endif
213
214static struct pnp_card_driver es968_pnpc_driver = {
215 .flags = PNP_DRIVER_RES_DISABLE,
216 .name = "es968",
217 .id_table = snd_es968_pnpids,
218 .probe = snd_es968_pnp_detect,
219 .remove = __devexit_p(snd_es968_pnp_remove),
220#ifdef CONFIG_PM
221 .suspend = snd_es968_pnp_suspend,
222 .resume = snd_es968_pnp_resume,
223#endif
224};
225
226static int __init alsa_card_es968_init(void)
227{
228 int err = pnp_register_card_driver(&es968_pnpc_driver);
229 if (err)
230 return err;
231
232 if (!es968_devices) {
233 pnp_unregister_card_driver(&es968_pnpc_driver);
234#ifdef MODULE
235 snd_printk(KERN_ERR "no ES968 based soundcards found\n");
236#endif
237 return -ENODEV;
238 }
239 return 0;
240}
241
242static void __exit alsa_card_es968_exit(void)
243{
244 pnp_unregister_card_driver(&es968_pnpc_driver);
245}
246
247module_init(alsa_card_es968_init)
248module_exit(alsa_card_es968_exit)
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1298c68d6bf0..e7a8cd058efb 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -58,6 +58,18 @@ config SND_ALI5451
58 To compile this driver as a module, choose M here: the module 58 To compile this driver as a module, choose M here: the module
59 will be called snd-ali5451. 59 will be called snd-ali5451.
60 60
61config SND_ASIHPI
62 tristate "AudioScience ASIxxxx"
63 depends on X86
64 select FW_LOADER
65 select SND_PCM
66 select SND_HWDEP
67 help
68 Say Y here to include support for AudioScience ASI sound cards.
69
70 To compile this driver as a module, choose M here: the module
71 will be called snd-asihpi.
72
61config SND_ATIIXP 73config SND_ATIIXP
62 tristate "ATI IXP AC97 Controller" 74 tristate "ATI IXP AC97 Controller"
63 select SND_AC97_CODEC 75 select SND_AC97_CODEC
@@ -501,6 +513,16 @@ config SND_ES1968
501 To compile this driver as a module, choose M here: the module 513 To compile this driver as a module, choose M here: the module
502 will be called snd-es1968. 514 will be called snd-es1968.
503 515
516config SND_ES1968_INPUT
517 bool "Enable input device for es1968 volume buttons"
518 depends on SND_ES1968
519 depends on INPUT=y || INPUT=SND_ES1968
520 help
521 If you say Y here, you will get an input device which reports
522 keypresses for the volume buttons connected to the es1968 chip.
523 If you say N the buttons will directly control the master volume.
524 It is recommended to say Y.
525
504config SND_FM801 526config SND_FM801
505 tristate "ForteMedia FM801" 527 tristate "ForteMedia FM801"
506 select SND_OPL3_LIB 528 select SND_OPL3_LIB
@@ -655,6 +677,16 @@ config SND_MAESTRO3
655 To compile this driver as a module, choose M here: the module 677 To compile this driver as a module, choose M here: the module
656 will be called snd-maestro3. 678 will be called snd-maestro3.
657 679
680config SND_MAESTRO3_INPUT
681 bool "Enable input device for maestro3 volume buttons"
682 depends on SND_MAESTRO3
683 depends on INPUT=y || INPUT=SND_MAESTRO3
684 help
685 If you say Y here, you will get an input device which reports
686 keypresses for the volume buttons connected to the maestro3 chip.
687 If you say N the buttons will directly control the master volume.
688 It is recommended to say Y.
689
658config SND_MIXART 690config SND_MIXART
659 tristate "Digigram miXart" 691 tristate "Digigram miXart"
660 select SND_HWDEP 692 select SND_HWDEP
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index ecfc609d2b9f..9cf4348ec137 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
57obj-$(CONFIG_SND) += \ 57obj-$(CONFIG_SND) += \
58 ac97/ \ 58 ac97/ \
59 ali5451/ \ 59 ali5451/ \
60 asihpi/ \
60 au88x0/ \ 61 au88x0/ \
61 aw2/ \ 62 aw2/ \
62 ctxfi/ \ 63 ctxfi/ \
diff --git a/sound/pci/asihpi/Makefile b/sound/pci/asihpi/Makefile
new file mode 100644
index 000000000000..391830a4556c
--- /dev/null
+++ b/sound/pci/asihpi/Makefile
@@ -0,0 +1,5 @@
1snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\
2 hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\
3 hpios.o hpi6000.o hpi6205.o hpimsgx.o
4
5obj-$(CONFIG_SND_ASIHPI) += snd-asihpi.o
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
new file mode 100644
index 000000000000..f74c7372b3d1
--- /dev/null
+++ b/sound/pci/asihpi/asihpi.c
@@ -0,0 +1,3002 @@
1/*
2 * Asihpi soundcard
3 * Copyright (c) by AudioScience Inc <alsa@audioscience.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 *
19 * The following is not a condition of use, merely a request:
20 * If you modify this program, particularly if you fix errors, AudioScience Inc
21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications.
23 */
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0
26
27#if REALLY_VERBOSE_LOGGING
28#define VPRINTK1 snd_printd
29#else
30#define VPRINTK1(...)
31#endif
32
33#if REALLY_VERBOSE_LOGGING > 1
34#define VPRINTK2 snd_printd
35#else
36#define VPRINTK2(...)
37#endif
38
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43
44#include "hpi_internal.h"
45#include "hpimsginit.h"
46#include "hpioctl.h"
47
48#include <linux/pci.h>
49#include <linux/init.h>
50#include <linux/jiffies.h>
51#include <linux/slab.h>
52#include <linux/time.h>
53#include <linux/wait.h>
54#include <sound/core.h>
55#include <sound/control.h>
56#include <sound/pcm.h>
57#include <sound/pcm_params.h>
58#include <sound/info.h>
59#include <sound/initval.h>
60#include <sound/tlv.h>
61#include <sound/hwdep.h>
62
63
64MODULE_LICENSE("GPL");
65MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
66MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
67
68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
70static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
71static int enable_hpi_hwdep = 1;
72
73module_param_array(index, int, NULL, S_IRUGO);
74MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
75
76module_param_array(id, charp, NULL, S_IRUGO);
77MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
78
79module_param_array(enable, bool, NULL, S_IRUGO);
80MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
81
82module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
83MODULE_PARM_DESC(enable_hpi_hwdep,
84 "ALSA enable HPI hwdep for AudioScience soundcard ");
85
86/* identify driver */
87#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else
92static char *build_info = "built within ALSA source";
93module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif
96
97/* set to 1 to dump every control from adapter to log */
98static const int mixer_dump;
99
100#define DEFAULT_SAMPLERATE 44100
101static int adapter_fs = DEFAULT_SAMPLERATE;
102
103static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104
105/* defaults */
106#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304
108#define BUFFER_BYTES_MAX (512 * 1024)
109
110/*#define TIMER_MILLISECONDS 20
111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
112*/
113
114#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
115
116struct clk_source {
117 int source;
118 int index;
119 char *name;
120};
121
122struct clk_cache {
123 int count;
124 int has_local;
125 struct clk_source s[MAX_CLOCKSOURCES];
126};
127
128/* Per card data */
129struct snd_card_asihpi {
130 struct snd_card *card;
131 struct pci_dev *pci;
132 u16 adapter_index;
133 u32 serial_number;
134 u16 type;
135 u16 version;
136 u16 num_outstreams;
137 u16 num_instreams;
138
139 u32 h_mixer;
140 struct clk_cache cc;
141
142 u16 support_mmap;
143 u16 support_grouping;
144 u16 support_mrx;
145 u16 update_interval_frames;
146 u16 in_max_chans;
147 u16 out_max_chans;
148};
149
150/* Per stream data */
151struct snd_card_asihpi_pcm {
152 struct timer_list timer;
153 unsigned int respawn_timer;
154 unsigned int hpi_buffer_attached;
155 unsigned int pcm_size;
156 unsigned int pcm_count;
157 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */
159 unsigned int pcm_buf_pos; /* position in buffer */
160 struct snd_pcm_substream *substream;
161 u32 h_stream;
162 struct hpi_format format;
163};
164
165/* universal stream verbs work with out or in stream handles */
166
167/* Functions to allow driver to give a buffer to HPI for busmastering */
168
169static u16 hpi_stream_host_buffer_attach(
170 struct hpi_hsubsys *hS,
171 u32 h_stream, /* handle to outstream. */
172 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
173 u32 pci_address
174)
175{
176 struct hpi_message hm;
177 struct hpi_response hr;
178 unsigned int obj = hpi_handle_object(h_stream);
179
180 if (!h_stream)
181 return HPI_ERROR_INVALID_OBJ;
182 hpi_init_message_response(&hm, &hr, obj,
183 obj == HPI_OBJ_OSTREAM ?
184 HPI_OSTREAM_HOSTBUFFER_ALLOC :
185 HPI_ISTREAM_HOSTBUFFER_ALLOC);
186
187 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
188 &hm.obj_index);
189
190 hm.u.d.u.buffer.buffer_size = size_in_bytes;
191 hm.u.d.u.buffer.pci_address = pci_address;
192 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
193 hpi_send_recv(&hm, &hr);
194 return hr.error;
195}
196
197static u16 hpi_stream_host_buffer_detach(
198 struct hpi_hsubsys *hS,
199 u32 h_stream
200)
201{
202 struct hpi_message hm;
203 struct hpi_response hr;
204 unsigned int obj = hpi_handle_object(h_stream);
205
206 if (!h_stream)
207 return HPI_ERROR_INVALID_OBJ;
208
209 hpi_init_message_response(&hm, &hr, obj,
210 obj == HPI_OBJ_OSTREAM ?
211 HPI_OSTREAM_HOSTBUFFER_FREE :
212 HPI_ISTREAM_HOSTBUFFER_FREE);
213
214 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
215 &hm.obj_index);
216 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
217 hpi_send_recv(&hm, &hr);
218 return hr.error;
219}
220
221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream)
222{
223 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
224 return hpi_outstream_start(hS, h_stream);
225 else
226 return hpi_instream_start(hS, h_stream);
227}
228
229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream)
230{
231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
232 return hpi_outstream_stop(hS, h_stream);
233 else
234 return hpi_instream_stop(hS, h_stream);
235}
236
237static inline u16 hpi_stream_get_info_ex(
238 struct hpi_hsubsys *hS,
239 u32 h_stream,
240 u16 *pw_state,
241 u32 *pbuffer_size,
242 u32 *pdata_in_buffer,
243 u32 *psample_count,
244 u32 *pauxiliary_data
245)
246{
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data);
251 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data);
255}
256
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
258 u32 h_master,
259 u32 h_stream)
260{
261 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
262 return hpi_outstream_group_add(hS, h_master, h_stream);
263 else
264 return hpi_instream_group_add(hS, h_master, h_stream);
265}
266
267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS,
268 u32 h_stream)
269{
270 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
271 return hpi_outstream_group_reset(hS, h_stream);
272 else
273 return hpi_instream_group_reset(hS, h_stream);
274}
275
276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS,
277 u32 h_stream, u32 *mo, u32 *mi)
278{
279 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
280 return hpi_outstream_group_get_map(hS, h_stream, mo, mi);
281 else
282 return hpi_instream_group_get_map(hS, h_stream, mo, mi);
283}
284
285static u16 handle_error(u16 err, int line, char *filename)
286{
287 if (err)
288 printk(KERN_WARNING
289 "in file %s, line %d: HPI error %d\n",
290 filename, line, err);
291 return err;
292}
293
294#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
295
296/***************************** GENERAL PCM ****************/
297#if REALLY_VERBOSE_LOGGING
298static void print_hwparams(struct snd_pcm_hw_params *p)
299{
300 snd_printd("HWPARAMS \n");
301 snd_printd("samplerate %d \n", params_rate(p));
302 snd_printd("channels %d \n", params_channels(p));
303 snd_printd("format %d \n", params_format(p));
304 snd_printd("subformat %d \n", params_subformat(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p));
307 snd_printd("access %d \n", params_access(p));
308 snd_printd("period_size %d \n", params_period_size(p));
309 snd_printd("periods %d \n", params_periods(p));
310 snd_printd("buffer_size %d \n", params_buffer_size(p));
311}
312#else
313#define print_hwparams(x)
314#endif
315
316static snd_pcm_format_t hpi_to_alsa_formats[] = {
317 -1, /* INVALID */
318 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
319 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
320 -1, /* HPI_FORMAT_MPEG_L1 3 */
321 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
322 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
323 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
324 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
325 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
326 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
327 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
328 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
329 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
330 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
331 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
332#if 1
333 /* ALSA can't handle 3 byte sample size together with power-of-2
334 * constraint on buffer_bytes, so disable this format
335 */
336 -1
337#else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */
339#endif
340};
341
342
343static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
344 u16 *hpi_format)
345{
346 u16 format;
347
348 for (format = HPI_FORMAT_PCM8_UNSIGNED;
349 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
350 if (hpi_to_alsa_formats[format] == alsa_format) {
351 *hpi_format = format;
352 return 0;
353 }
354 }
355
356 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
357 alsa_format);
358 *hpi_format = 0;
359 return -EINVAL;
360}
361
362static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
363 struct snd_pcm_hardware *pcmhw)
364{
365 u16 err;
366 u32 h_control;
367 u32 sample_rate;
368 int idx;
369 unsigned int rate_min = 200000;
370 unsigned int rate_max = 0;
371 unsigned int rates = 0;
372
373 if (asihpi->support_mrx) {
374 rates |= SNDRV_PCM_RATE_CONTINUOUS;
375 rates |= SNDRV_PCM_RATE_8000_96000;
376 rate_min = 8000;
377 rate_max = 100000;
378 } else {
379 /* on cards without SRC,
380 valid rates are determined by sampleclock */
381 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
382 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
383 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) {
385 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err);
387 }
388
389 for (idx = 0; idx < 100; idx++) {
390 if (hpi_sample_clock_query_local_rate(ss,
391 h_control, idx, &sample_rate)) {
392 if (!idx)
393 snd_printk(KERN_ERR
394 "local rate query failed\n");
395
396 break;
397 }
398
399 rate_min = min(rate_min, sample_rate);
400 rate_max = max(rate_max, sample_rate);
401
402 switch (sample_rate) {
403 case 5512:
404 rates |= SNDRV_PCM_RATE_5512;
405 break;
406 case 8000:
407 rates |= SNDRV_PCM_RATE_8000;
408 break;
409 case 11025:
410 rates |= SNDRV_PCM_RATE_11025;
411 break;
412 case 16000:
413 rates |= SNDRV_PCM_RATE_16000;
414 break;
415 case 22050:
416 rates |= SNDRV_PCM_RATE_22050;
417 break;
418 case 32000:
419 rates |= SNDRV_PCM_RATE_32000;
420 break;
421 case 44100:
422 rates |= SNDRV_PCM_RATE_44100;
423 break;
424 case 48000:
425 rates |= SNDRV_PCM_RATE_48000;
426 break;
427 case 64000:
428 rates |= SNDRV_PCM_RATE_64000;
429 break;
430 case 88200:
431 rates |= SNDRV_PCM_RATE_88200;
432 break;
433 case 96000:
434 rates |= SNDRV_PCM_RATE_96000;
435 break;
436 case 176400:
437 rates |= SNDRV_PCM_RATE_176400;
438 break;
439 case 192000:
440 rates |= SNDRV_PCM_RATE_192000;
441 break;
442 default: /* some other rate */
443 rates |= SNDRV_PCM_RATE_KNOT;
444 }
445 }
446 }
447
448 /* printk(KERN_INFO "Supported rates %X %d %d\n",
449 rates, rate_min, rate_max); */
450 pcmhw->rates = rates;
451 pcmhw->rate_min = rate_min;
452 pcmhw->rate_max = rate_max;
453}
454
455static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
456 struct snd_pcm_hw_params *params)
457{
458 struct snd_pcm_runtime *runtime = substream->runtime;
459 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
460 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
461 int err;
462 u16 format;
463 unsigned int bytes_per_sec;
464
465 print_hwparams(params);
466 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
467 if (err < 0)
468 return err;
469 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
470 if (err)
471 return err;
472
473 VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
474 format, params_channels(params),
475 params_rate(params));
476
477 hpi_handle_error(hpi_format_create(&dpcm->format,
478 params_channels(params),
479 format, params_rate(params), 0, 0));
480
481 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
482 if (hpi_instream_reset(ss, dpcm->h_stream) != 0)
483 return -EINVAL;
484
485 if (hpi_instream_set_format(ss,
486 dpcm->h_stream, &dpcm->format) != 0)
487 return -EINVAL;
488 }
489
490 dpcm->hpi_buffer_attached = 0;
491 if (card->support_mmap) {
492
493 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
494 params_buffer_bytes(params), runtime->dma_addr);
495 if (err == 0) {
496 snd_printd(KERN_INFO
497 "stream_host_buffer_attach succeeded %u %lu\n",
498 params_buffer_bytes(params),
499 (unsigned long)runtime->dma_addr);
500 } else {
501 snd_printd(KERN_INFO
502 "stream_host_buffer_attach error %d\n",
503 err);
504 return -ENOMEM;
505 }
506
507 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL,
508 &dpcm->hpi_buffer_attached,
509 NULL, NULL, NULL);
510
511 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
512 dpcm->hpi_buffer_attached);
513 }
514 bytes_per_sec = params_rate(params) * params_channels(params);
515 bytes_per_sec *= snd_pcm_format_width(params_format(params));
516 bytes_per_sec /= 8;
517 if (bytes_per_sec <= 0)
518 return -EINVAL;
519
520 dpcm->bytes_per_sec = bytes_per_sec;
521 dpcm->pcm_size = params_buffer_bytes(params);
522 dpcm->pcm_count = params_period_bytes(params);
523 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
524 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
525
526 dpcm->pcm_irq_pos = 0;
527 dpcm->pcm_buf_pos = 0;
528 return 0;
529}
530
531static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
532 substream)
533{
534 struct snd_pcm_runtime *runtime = substream->runtime;
535 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
536 int expiry;
537
538 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
539 /* wait longer the first time, for samples to propagate */
540 expiry = max(expiry, 20);
541 dpcm->timer.expires = jiffies + expiry;
542 dpcm->respawn_timer = 1;
543 add_timer(&dpcm->timer);
544}
545
546static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
547{
548 struct snd_pcm_runtime *runtime = substream->runtime;
549 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
550
551 dpcm->respawn_timer = 0;
552 del_timer(&dpcm->timer);
553}
554
555static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
556 int cmd)
557{
558 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
559 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
560 struct snd_pcm_substream *s;
561 u16 e;
562
563 snd_printd("trigger %dstream %d\n",
564 substream->stream, substream->number);
565 switch (cmd) {
566 case SNDRV_PCM_TRIGGER_START:
567 snd_pcm_group_for_each_entry(s, substream) {
568 struct snd_card_asihpi_pcm *ds;
569 ds = s->runtime->private_data;
570
571 if (snd_pcm_substream_chip(s) != card)
572 continue;
573
574 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
575 (card->support_mmap)) {
576 /* How do I know how much valid data is present
577 * in buffer? Just guessing 2 periods, but if
578 * buffer is bigger it may contain even more
579 * data??
580 */
581 unsigned int preload = ds->pcm_count * 2;
582 VPRINTK2("preload %d\n", preload);
583 hpi_handle_error(hpi_outstream_write_buf(
584 ss, ds->h_stream,
585 &s->runtime->dma_area[0],
586 preload,
587 &ds->format));
588 }
589
590 if (card->support_grouping) {
591 VPRINTK1("\t_group %dstream %d\n", s->stream,
592 s->number);
593 e = hpi_stream_group_add(ss,
594 dpcm->h_stream,
595 ds->h_stream);
596 if (!e) {
597 snd_pcm_trigger_done(s, substream);
598 } else {
599 hpi_handle_error(e);
600 break;
601 }
602 } else
603 break;
604 }
605 snd_printd("start\n");
606 /* start the master stream */
607 snd_card_asihpi_pcm_timer_start(substream);
608 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
609 break;
610
611 case SNDRV_PCM_TRIGGER_STOP:
612 snd_card_asihpi_pcm_timer_stop(substream);
613 snd_pcm_group_for_each_entry(s, substream) {
614 if (snd_pcm_substream_chip(s) != card)
615 continue;
616
617 /*? workaround linked streams don't
618 transition to SETUP 20070706*/
619 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
620
621 if (card->support_grouping) {
622 VPRINTK1("\t_group %dstream %d\n", s->stream,
623 s->number);
624 snd_pcm_trigger_done(s, substream);
625 } else
626 break;
627 }
628 snd_printd("stop\n");
629
630 /* _prepare and _hwparams reset the stream */
631 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
632 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
633 hpi_handle_error(
634 hpi_outstream_reset(ss, dpcm->h_stream));
635
636 if (card->support_grouping)
637 hpi_handle_error(hpi_stream_group_reset(ss,
638 dpcm->h_stream));
639 break;
640
641 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
642 snd_printd("pause release\n");
643 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
644 snd_card_asihpi_pcm_timer_start(substream);
645 break;
646 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
647 snd_printd("pause\n");
648 snd_card_asihpi_pcm_timer_stop(substream);
649 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
650 break;
651 default:
652 snd_printd("\tINVALID\n");
653 return -EINVAL;
654 }
655
656 return 0;
657}
658
659static int
660snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
661{
662 struct snd_pcm_runtime *runtime = substream->runtime;
663 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
664 if (dpcm->hpi_buffer_attached)
665 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
666
667 snd_pcm_lib_free_pages(substream);
668 return 0;
669}
670
671static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
672{
673 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
674 kfree(dpcm);
675}
676
677/*algorithm outline
678 Without linking degenerates to getting single stream pos etc
679 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
680*/
681/*
682buf_pos=get_buf_pos(s);
683for_each_linked_stream(s) {
684 buf_pos=get_buf_pos(s);
685 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size)
686 new_data = min(new_data, calc_new_data(buf_pos,irq_pos)
687}
688timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
689for_each_linked_stream(s) {
690 s->buf_pos = min_buf_pos;
691 if (new_data > pcm_count) {
692 if (mmap) {
693 irq_pos = (irq_pos + pcm_count) % pcm_size;
694 if (playback) {
695 write(pcm_count);
696 } else {
697 read(pcm_count);
698 }
699 }
700 snd_pcm_period_elapsed(s);
701 }
702}
703*/
704
705/** Minimum of 2 modulo values. Works correctly when the difference between
706* the values is less than half the modulus
707*/
708static inline unsigned int modulo_min(unsigned int a, unsigned int b,
709 unsigned long int modulus)
710{
711 unsigned int result;
712 if (((a-b) % modulus) < (modulus/2))
713 result = b;
714 else
715 result = a;
716
717 return result;
718}
719
720/** Timer function, equivalent to interrupt service routine for cards
721*/
722static void snd_card_asihpi_timer_function(unsigned long data)
723{
724 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
725 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream);
726 struct snd_pcm_runtime *runtime;
727 struct snd_pcm_substream *s;
728 unsigned int newdata = 0;
729 unsigned int buf_pos, min_buf_pos = 0;
730 unsigned int remdata, xfercount, next_jiffies;
731 int first = 1;
732 u16 state;
733 u32 buffer_size, data_avail, samples_played, aux;
734
735 /* find minimum newdata and buffer pos in group */
736 snd_pcm_group_for_each_entry(s, dpcm->substream) {
737 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
738 runtime = s->runtime;
739
740 if (snd_pcm_substream_chip(s) != card)
741 continue;
742
743 hpi_handle_error(hpi_stream_get_info_ex(ss,
744 ds->h_stream, &state,
745 &buffer_size, &data_avail,
746 &samples_played, &aux));
747
748 /* number of bytes in on-card buffer */
749 runtime->delay = aux;
750
751 if (state == HPI_STATE_DRAINED) {
752 snd_printd(KERN_WARNING "outstream %d drained\n",
753 s->number);
754 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
755 return;
756 }
757
758 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
759 buf_pos = frames_to_bytes(runtime, samples_played);
760 } else {
761 buf_pos = data_avail + ds->pcm_irq_pos;
762 }
763
764 if (first) {
765 /* can't statically init min when wrap is involved */
766 min_buf_pos = buf_pos;
767 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size;
768 first = 0;
769 } else {
770 min_buf_pos =
771 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L);
772 newdata = min(
773 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size,
774 newdata);
775 }
776
777 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
778 (unsigned long)frames_to_bytes(runtime,
779 runtime->status->hw_ptr),
780 (unsigned long)frames_to_bytes(runtime,
781 runtime->control->appl_ptr));
782 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
783 " aux=x%04X space=x%04X\n", s->number,
784 state, ds->pcm_irq_pos, buf_pos, (int)data_avail,
785 (int)aux, buffer_size-data_avail);
786 }
787
788 remdata = newdata % dpcm->pcm_count;
789 xfercount = newdata - remdata; /* a multiple of pcm_count */
790 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
791 next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
792 dpcm->timer.expires = jiffies + next_jiffies;
793 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n",
794 next_jiffies, min_buf_pos, newdata, xfercount);
795
796 snd_pcm_group_for_each_entry(s, dpcm->substream) {
797 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
798 ds->pcm_buf_pos = min_buf_pos;
799
800 if (xfercount) {
801 if (card->support_mmap) {
802 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
803 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
804 VPRINTK2("write OS%d x%04x\n",
805 s->number,
806 ds->pcm_count);
807 hpi_handle_error(
808 hpi_outstream_write_buf(
809 ss, ds->h_stream,
810 &s->runtime->
811 dma_area[0],
812 xfercount,
813 &ds->format));
814 } else {
815 VPRINTK2("read IS%d x%04x\n",
816 s->number,
817 dpcm->pcm_count);
818 hpi_handle_error(
819 hpi_instream_read_buf(
820 ss, ds->h_stream,
821 NULL, xfercount));
822 }
823 } /* else R/W will be handled by read/write callbacks */
824 snd_pcm_period_elapsed(s);
825 }
826 }
827
828 if (dpcm->respawn_timer)
829 add_timer(&dpcm->timer);
830}
831
832/***************************** PLAYBACK OPS ****************/
833static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
834 unsigned int cmd, void *arg)
835{
836 /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */
837 return snd_pcm_lib_ioctl(substream, cmd, arg);
838}
839
840static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
841 substream)
842{
843 struct snd_pcm_runtime *runtime = substream->runtime;
844 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
845
846 snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
847
848 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
849 dpcm->pcm_irq_pos = 0;
850 dpcm->pcm_buf_pos = 0;
851
852 return 0;
853}
854
855static snd_pcm_uframes_t
856snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
857{
858 struct snd_pcm_runtime *runtime = substream->runtime;
859 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
860 snd_pcm_uframes_t ptr;
861
862 u32 samples_played;
863 u16 err;
864
865 if (!snd_pcm_stream_linked(substream)) {
866 /* NOTE, can use samples played for playback position here and
867 * in timer fn because it LAGS the actual read pointer, and is a
868 * better representation of actual playout position
869 */
870 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
871 NULL, NULL,
872 &samples_played, NULL);
873 hpi_handle_error(err);
874
875 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
876 }
877 /* else must return most conservative value found in timer func
878 * by looping over all streams
879 */
880
881 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
882 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
883 return ptr;
884}
885
886static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
887 u32 h_stream,
888 struct snd_pcm_hardware *pcmhw)
889{
890 struct hpi_format hpi_format;
891 u16 format;
892 u16 err;
893 u32 h_control;
894 u32 sample_rate = 48000;
895
896 /* on cards without SRC, must query at valid rate,
897 * maybe set by external sync
898 */
899 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
900 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
901 HPI_CONTROL_SAMPLECLOCK, &h_control);
902
903 if (!err)
904 err = hpi_sample_clock_get_sample_rate(ss, h_control,
905 &sample_rate);
906
907 for (format = HPI_FORMAT_PCM8_UNSIGNED;
908 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
909 err = hpi_format_create(&hpi_format,
910 2, format, sample_rate, 128000, 0);
911 if (!err)
912 err = hpi_outstream_query_format(ss, h_stream,
913 &hpi_format);
914 if (!err && (hpi_to_alsa_formats[format] != -1))
915 pcmhw->formats |=
916 (1ULL << hpi_to_alsa_formats[format]);
917 }
918}
919
920static struct snd_pcm_hardware snd_card_asihpi_playback = {
921 .channels_min = 1,
922 .channels_max = 2,
923 .buffer_bytes_max = BUFFER_BYTES_MAX,
924 .period_bytes_min = PERIOD_BYTES_MIN,
925 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
926 .periods_min = PERIODS_MIN,
927 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
928 .fifo_size = 0,
929};
930
931static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
932{
933 struct snd_pcm_runtime *runtime = substream->runtime;
934 struct snd_card_asihpi_pcm *dpcm;
935 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
936 int err;
937
938 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
939 if (dpcm == NULL)
940 return -ENOMEM;
941
942 err =
943 hpi_outstream_open(ss, card->adapter_index,
944 substream->number, &dpcm->h_stream);
945 hpi_handle_error(err);
946 if (err)
947 kfree(dpcm);
948 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
949 return -EBUSY;
950 if (err)
951 return -EIO;
952
953 /*? also check ASI5000 samplerate source
954 If external, only support external rate.
955 If internal and other stream playing, cant switch
956 */
957
958 init_timer(&dpcm->timer);
959 dpcm->timer.data = (unsigned long) dpcm;
960 dpcm->timer.function = snd_card_asihpi_timer_function;
961 dpcm->substream = substream;
962 runtime->private_data = dpcm;
963 runtime->private_free = snd_card_asihpi_runtime_free;
964
965 snd_card_asihpi_playback.channels_max = card->out_max_chans;
966 /*?snd_card_asihpi_playback.period_bytes_min =
967 card->out_max_chans * 4096; */
968
969 snd_card_asihpi_playback_format(card, dpcm->h_stream,
970 &snd_card_asihpi_playback);
971
972 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
973
974 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
975 SNDRV_PCM_INFO_DOUBLE |
976 SNDRV_PCM_INFO_BATCH |
977 SNDRV_PCM_INFO_BLOCK_TRANSFER |
978 SNDRV_PCM_INFO_PAUSE;
979
980 if (card->support_mmap)
981 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
982 SNDRV_PCM_INFO_MMAP_VALID;
983
984 if (card->support_grouping)
985 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
986
987 /* struct is copied, so can create initializer dynamically */
988 runtime->hw = snd_card_asihpi_playback;
989
990 if (card->support_mmap)
991 err = snd_pcm_hw_constraint_pow2(runtime, 0,
992 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
993 if (err < 0)
994 return err;
995
996 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
997 card->update_interval_frames);
998 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames * 4, UINT_MAX);
1000
1001 snd_pcm_set_sync(substream);
1002
1003 snd_printd(KERN_INFO "playback open\n");
1004
1005 return 0;
1006}
1007
1008static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1009{
1010 struct snd_pcm_runtime *runtime = substream->runtime;
1011 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1012
1013 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream));
1014 snd_printd(KERN_INFO "playback close\n");
1015
1016 return 0;
1017}
1018
1019static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1020 int channel,
1021 snd_pcm_uframes_t pos,
1022 void __user *src,
1023 snd_pcm_uframes_t count)
1024{
1025 struct snd_pcm_runtime *runtime = substream->runtime;
1026 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1027 unsigned int len;
1028
1029 len = frames_to_bytes(runtime, count);
1030
1031 if (copy_from_user(runtime->dma_area, src, len))
1032 return -EFAULT;
1033
1034 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1035 substream->number, len);
1036
1037 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1038 runtime->dma_area, len, &dpcm->format));
1039
1040 return 0;
1041}
1042
1043static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1044 substream, int channel,
1045 snd_pcm_uframes_t pos,
1046 snd_pcm_uframes_t count)
1047{
1048 unsigned int len;
1049 struct snd_pcm_runtime *runtime = substream->runtime;
1050 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1051
1052 len = frames_to_bytes(runtime, count);
1053 snd_printd(KERN_INFO "playback silence %u bytes\n", len);
1054
1055 memset(runtime->dma_area, 0, len);
1056 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1057 runtime->dma_area, len, &dpcm->format));
1058 return 0;
1059}
1060
1061static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1062 .open = snd_card_asihpi_playback_open,
1063 .close = snd_card_asihpi_playback_close,
1064 .ioctl = snd_card_asihpi_playback_ioctl,
1065 .hw_params = snd_card_asihpi_pcm_hw_params,
1066 .hw_free = snd_card_asihpi_hw_free,
1067 .prepare = snd_card_asihpi_playback_prepare,
1068 .trigger = snd_card_asihpi_trigger,
1069 .pointer = snd_card_asihpi_playback_pointer,
1070 .copy = snd_card_asihpi_playback_copy,
1071 .silence = snd_card_asihpi_playback_silence,
1072};
1073
1074static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1075 .open = snd_card_asihpi_playback_open,
1076 .close = snd_card_asihpi_playback_close,
1077 .ioctl = snd_card_asihpi_playback_ioctl,
1078 .hw_params = snd_card_asihpi_pcm_hw_params,
1079 .hw_free = snd_card_asihpi_hw_free,
1080 .prepare = snd_card_asihpi_playback_prepare,
1081 .trigger = snd_card_asihpi_trigger,
1082 .pointer = snd_card_asihpi_playback_pointer,
1083};
1084
1085/***************************** CAPTURE OPS ****************/
1086static snd_pcm_uframes_t
1087snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1088{
1089 struct snd_pcm_runtime *runtime = substream->runtime;
1090 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1091
1092 VPRINTK2("capture pointer %d=%d\n",
1093 substream->number, dpcm->pcm_buf_pos);
1094 /* NOTE Unlike playback can't use actual dwSamplesPlayed
1095 for the capture position, because those samples aren't yet in
1096 the local buffer available for reading.
1097 */
1098 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
1099}
1100
1101static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1102 unsigned int cmd, void *arg)
1103{
1104 return snd_pcm_lib_ioctl(substream, cmd, arg);
1105}
1106
1107static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1108{
1109 struct snd_pcm_runtime *runtime = substream->runtime;
1110 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1111
1112 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1113 dpcm->pcm_irq_pos = 0;
1114 dpcm->pcm_buf_pos = 0;
1115
1116 snd_printd("capture prepare %d\n", substream->number);
1117 return 0;
1118}
1119
1120
1121
1122static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1123 u32 h_stream,
1124 struct snd_pcm_hardware *pcmhw)
1125{
1126 struct hpi_format hpi_format;
1127 u16 format;
1128 u16 err;
1129 u32 h_control;
1130 u32 sample_rate = 48000;
1131
1132 /* on cards without SRC, must query at valid rate,
1133 maybe set by external sync */
1134 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
1135 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1136 HPI_CONTROL_SAMPLECLOCK, &h_control);
1137
1138 if (!err)
1139 err = hpi_sample_clock_get_sample_rate(ss, h_control,
1140 &sample_rate);
1141
1142 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1143 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1144
1145 err = hpi_format_create(&hpi_format, 2, format,
1146 sample_rate, 128000, 0);
1147 if (!err)
1148 err = hpi_instream_query_format(ss, h_stream,
1149 &hpi_format);
1150 if (!err)
1151 pcmhw->formats |=
1152 (1ULL << hpi_to_alsa_formats[format]);
1153 }
1154}
1155
1156
1157static struct snd_pcm_hardware snd_card_asihpi_capture = {
1158 .channels_min = 1,
1159 .channels_max = 2,
1160 .buffer_bytes_max = BUFFER_BYTES_MAX,
1161 .period_bytes_min = PERIOD_BYTES_MIN,
1162 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1163 .periods_min = PERIODS_MIN,
1164 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1165 .fifo_size = 0,
1166};
1167
1168static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1169{
1170 struct snd_pcm_runtime *runtime = substream->runtime;
1171 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1172 struct snd_card_asihpi_pcm *dpcm;
1173 int err;
1174
1175 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1176 if (dpcm == NULL)
1177 return -ENOMEM;
1178
1179 snd_printd("hpi_instream_open adapter %d stream %d\n",
1180 card->adapter_index, substream->number);
1181
1182 err = hpi_handle_error(
1183 hpi_instream_open(ss, card->adapter_index,
1184 substream->number, &dpcm->h_stream));
1185 if (err)
1186 kfree(dpcm);
1187 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1188 return -EBUSY;
1189 if (err)
1190 return -EIO;
1191
1192
1193 init_timer(&dpcm->timer);
1194 dpcm->timer.data = (unsigned long) dpcm;
1195 dpcm->timer.function = snd_card_asihpi_timer_function;
1196 dpcm->substream = substream;
1197 runtime->private_data = dpcm;
1198 runtime->private_free = snd_card_asihpi_runtime_free;
1199
1200 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1201 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1202 &snd_card_asihpi_capture);
1203 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1204 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1205
1206 if (card->support_mmap)
1207 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1208 SNDRV_PCM_INFO_MMAP_VALID;
1209
1210 runtime->hw = snd_card_asihpi_capture;
1211
1212 if (card->support_mmap)
1213 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1214 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1215 if (err < 0)
1216 return err;
1217
1218 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1219 card->update_interval_frames);
1220 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1221 card->update_interval_frames * 2, UINT_MAX);
1222
1223 snd_pcm_set_sync(substream);
1224
1225 return 0;
1226}
1227
1228static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1229{
1230 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1231
1232 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream));
1233 return 0;
1234}
1235
1236static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1237 int channel, snd_pcm_uframes_t pos,
1238 void __user *dst, snd_pcm_uframes_t count)
1239{
1240 struct snd_pcm_runtime *runtime = substream->runtime;
1241 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1242 u32 data_size;
1243
1244 data_size = frames_to_bytes(runtime, count);
1245
1246 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1247 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1248 runtime->dma_area, data_size));
1249
1250 /* Used by capture_pointer */
1251 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1252
1253 if (copy_to_user(dst, runtime->dma_area, data_size))
1254 return -EFAULT;
1255
1256 return 0;
1257}
1258
1259static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1260 .open = snd_card_asihpi_capture_open,
1261 .close = snd_card_asihpi_capture_close,
1262 .ioctl = snd_card_asihpi_capture_ioctl,
1263 .hw_params = snd_card_asihpi_pcm_hw_params,
1264 .hw_free = snd_card_asihpi_hw_free,
1265 .prepare = snd_card_asihpi_capture_prepare,
1266 .trigger = snd_card_asihpi_trigger,
1267 .pointer = snd_card_asihpi_capture_pointer,
1268};
1269
1270static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1271 .open = snd_card_asihpi_capture_open,
1272 .close = snd_card_asihpi_capture_close,
1273 .ioctl = snd_card_asihpi_capture_ioctl,
1274 .hw_params = snd_card_asihpi_pcm_hw_params,
1275 .hw_free = snd_card_asihpi_hw_free,
1276 .prepare = snd_card_asihpi_capture_prepare,
1277 .trigger = snd_card_asihpi_trigger,
1278 .pointer = snd_card_asihpi_capture_pointer,
1279 .copy = snd_card_asihpi_capture_copy
1280};
1281
1282static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1283 int device, int substreams)
1284{
1285 struct snd_pcm *pcm;
1286 int err;
1287
1288 err = snd_pcm_new(asihpi->card, "asihpi PCM", device,
1289 asihpi->num_outstreams, asihpi->num_instreams,
1290 &pcm);
1291 if (err < 0)
1292 return err;
1293 /* pointer to ops struct is stored, dont change ops afterwards! */
1294 if (asihpi->support_mmap) {
1295 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1296 &snd_card_asihpi_playback_mmap_ops);
1297 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1298 &snd_card_asihpi_capture_mmap_ops);
1299 } else {
1300 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1301 &snd_card_asihpi_playback_ops);
1302 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1303 &snd_card_asihpi_capture_ops);
1304 }
1305
1306 pcm->private_data = asihpi;
1307 pcm->info_flags = 0;
1308 strcpy(pcm->name, "asihpi PCM");
1309
1310 /*? do we want to emulate MMAP for non-BBM cards?
1311 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1312 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1313 snd_dma_pci_data(asihpi->pci),
1314 64*1024, BUFFER_BYTES_MAX);
1315
1316 return 0;
1317}
1318
1319/***************************** MIXER CONTROLS ****************/
1320struct hpi_control {
1321 u32 h_control;
1322 u16 control_type;
1323 u16 src_node_type;
1324 u16 src_node_index;
1325 u16 dst_node_type;
1326 u16 dst_node_index;
1327 u16 band;
1328 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1329};
1330
1331static char *asihpi_tuner_band_names[] =
1332{
1333 "invalid",
1334 "AM",
1335 "FM mono",
1336 "TV NTSC-M",
1337 "FM stereo",
1338 "AUX",
1339 "TV PAL BG",
1340 "TV PAL I",
1341 "TV PAL DK",
1342 "TV SECAM",
1343};
1344
1345compile_time_assert(
1346 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1347 (HPI_TUNER_BAND_LAST+1)),
1348 assert_tuner_band_names_size);
1349
1350#if ASI_STYLE_NAMES
1351static char *asihpi_src_names[] =
1352{
1353 "no source",
1354 "outstream",
1355 "line_in",
1356 "aes_in",
1357 "tuner",
1358 "RF",
1359 "clock",
1360 "bitstr",
1361 "mic",
1362 "cobranet",
1363 "analog_in",
1364 "adapter",
1365};
1366#else
1367static char *asihpi_src_names[] =
1368{
1369 "no source",
1370 "PCM playback",
1371 "line in",
1372 "digital in",
1373 "tuner",
1374 "RF",
1375 "clock",
1376 "bitstream",
1377 "mic",
1378 "cobranet in",
1379 "analog in",
1380 "adapter",
1381};
1382#endif
1383
1384compile_time_assert(
1385 (ARRAY_SIZE(asihpi_src_names) ==
1386 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)),
1387 assert_src_names_size);
1388
1389#if ASI_STYLE_NAMES
1390static char *asihpi_dst_names[] =
1391{
1392 "no destination",
1393 "instream",
1394 "line_out",
1395 "aes_out",
1396 "RF",
1397 "speaker" ,
1398 "cobranet",
1399 "analog_out",
1400};
1401#else
1402static char *asihpi_dst_names[] =
1403{
1404 "no destination",
1405 "PCM capture",
1406 "line out",
1407 "digital out",
1408 "RF",
1409 "speaker",
1410 "cobranet out",
1411 "analog out"
1412};
1413#endif
1414
1415compile_time_assert(
1416 (ARRAY_SIZE(asihpi_dst_names) ==
1417 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)),
1418 assert_dst_names_size);
1419
1420static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1421 struct snd_card_asihpi *asihpi)
1422{
1423 int err;
1424
1425 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1426 if (err < 0)
1427 return err;
1428 else if (mixer_dump)
1429 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1430
1431 return 0;
1432}
1433
1434/* Convert HPI control name and location into ALSA control name */
1435static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1436 struct hpi_control *hpi_ctl,
1437 char *name)
1438{
1439 memset(snd_control, 0, sizeof(*snd_control));
1440 snd_control->name = hpi_ctl->name;
1441 snd_control->private_value = hpi_ctl->h_control;
1442 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1443 snd_control->index = 0;
1444
1445 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1446 sprintf(hpi_ctl->name, "%s%d to %s%d %s",
1447 asihpi_src_names[hpi_ctl->src_node_type],
1448 hpi_ctl->src_node_index,
1449 asihpi_dst_names[hpi_ctl->dst_node_type],
1450 hpi_ctl->dst_node_index,
1451 name);
1452 else if (hpi_ctl->dst_node_type) {
1453 sprintf(hpi_ctl->name, "%s%d %s",
1454 asihpi_dst_names[hpi_ctl->dst_node_type],
1455 hpi_ctl->dst_node_index,
1456 name);
1457 } else {
1458 sprintf(hpi_ctl->name, "%s%d %s",
1459 asihpi_src_names[hpi_ctl->src_node_type],
1460 hpi_ctl->src_node_index,
1461 name);
1462 }
1463}
1464
1465/*------------------------------------------------------------
1466 Volume controls
1467 ------------------------------------------------------------*/
1468#define VOL_STEP_mB 1
1469static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1470 struct snd_ctl_elem_info *uinfo)
1471{
1472 u32 h_control = kcontrol->private_value;
1473 u16 err;
1474 /* native gains are in millibels */
1475 short min_gain_mB;
1476 short max_gain_mB;
1477 short step_gain_mB;
1478
1479 err = hpi_volume_query_range(ss, h_control,
1480 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1481 if (err) {
1482 max_gain_mB = 0;
1483 min_gain_mB = -10000;
1484 step_gain_mB = VOL_STEP_mB;
1485 }
1486
1487 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1488 uinfo->count = 2;
1489 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1490 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1491 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1492 return 0;
1493}
1494
1495static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1496 struct snd_ctl_elem_value *ucontrol)
1497{
1498 u32 h_control = kcontrol->private_value;
1499 short an_gain_mB[HPI_MAX_CHANNELS];
1500
1501 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB));
1502 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1503 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1504
1505 return 0;
1506}
1507
1508static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1509 struct snd_ctl_elem_value *ucontrol)
1510{
1511 int change;
1512 u32 h_control = kcontrol->private_value;
1513 short an_gain_mB[HPI_MAX_CHANNELS];
1514
1515 an_gain_mB[0] =
1516 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1517 an_gain_mB[1] =
1518 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1519 /* change = asihpi->mixer_volume[addr][0] != left ||
1520 asihpi->mixer_volume[addr][1] != right;
1521 */
1522 change = 1;
1523 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB));
1524 return change;
1525}
1526
1527static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1528
1529static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1530 struct hpi_control *hpi_ctl)
1531{
1532 struct snd_card *card = asihpi->card;
1533 struct snd_kcontrol_new snd_control;
1534
1535 asihpi_ctl_init(&snd_control, hpi_ctl, "volume");
1536 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1537 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1538 snd_control.info = snd_asihpi_volume_info;
1539 snd_control.get = snd_asihpi_volume_get;
1540 snd_control.put = snd_asihpi_volume_put;
1541 snd_control.tlv.p = db_scale_100;
1542
1543 return ctl_add(card, &snd_control, asihpi);
1544}
1545
1546/*------------------------------------------------------------
1547 Level controls
1548 ------------------------------------------------------------*/
1549static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1550 struct snd_ctl_elem_info *uinfo)
1551{
1552 u32 h_control = kcontrol->private_value;
1553 u16 err;
1554 short min_gain_mB;
1555 short max_gain_mB;
1556 short step_gain_mB;
1557
1558 err =
1559 hpi_level_query_range(ss, h_control, &min_gain_mB,
1560 &max_gain_mB, &step_gain_mB);
1561 if (err) {
1562 max_gain_mB = 2400;
1563 min_gain_mB = -1000;
1564 step_gain_mB = 100;
1565 }
1566
1567 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1568 uinfo->count = 2;
1569 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1570 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1571 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1572 return 0;
1573}
1574
1575static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1577{
1578 u32 h_control = kcontrol->private_value;
1579 short an_gain_mB[HPI_MAX_CHANNELS];
1580
1581 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB));
1582 ucontrol->value.integer.value[0] =
1583 an_gain_mB[0] / HPI_UNITS_PER_dB;
1584 ucontrol->value.integer.value[1] =
1585 an_gain_mB[1] / HPI_UNITS_PER_dB;
1586
1587 return 0;
1588}
1589
1590static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1591 struct snd_ctl_elem_value *ucontrol)
1592{
1593 int change;
1594 u32 h_control = kcontrol->private_value;
1595 short an_gain_mB[HPI_MAX_CHANNELS];
1596
1597 an_gain_mB[0] =
1598 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1599 an_gain_mB[1] =
1600 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1601 /* change = asihpi->mixer_level[addr][0] != left ||
1602 asihpi->mixer_level[addr][1] != right;
1603 */
1604 change = 1;
1605 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB));
1606 return change;
1607}
1608
1609static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1610
1611static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1612 struct hpi_control *hpi_ctl)
1613{
1614 struct snd_card *card = asihpi->card;
1615 struct snd_kcontrol_new snd_control;
1616
1617 /* can't use 'volume' cos some nodes have volume as well */
1618 asihpi_ctl_init(&snd_control, hpi_ctl, "level");
1619 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1620 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1621 snd_control.info = snd_asihpi_level_info;
1622 snd_control.get = snd_asihpi_level_get;
1623 snd_control.put = snd_asihpi_level_put;
1624 snd_control.tlv.p = db_scale_level;
1625
1626 return ctl_add(card, &snd_control, asihpi);
1627}
1628
1629/*------------------------------------------------------------
1630 AESEBU controls
1631 ------------------------------------------------------------*/
1632
1633/* AESEBU format */
1634static char *asihpi_aesebu_format_names[] =
1635{
1636 "N/A",
1637 "S/PDIF",
1638 "AES/EBU",
1639};
1640
1641static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo)
1643{
1644 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1645 uinfo->count = 1;
1646 uinfo->value.enumerated.items = 3;
1647
1648 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1649 uinfo->value.enumerated.item =
1650 uinfo->value.enumerated.items - 1;
1651
1652 strcpy(uinfo->value.enumerated.name,
1653 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1654
1655 return 0;
1656}
1657
1658static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol,
1660 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *))
1661{
1662 u32 h_control = kcontrol->private_value;
1663 u16 source, err;
1664
1665 err = func(ss, h_control, &source);
1666
1667 /* default to N/A */
1668 ucontrol->value.enumerated.item[0] = 0;
1669 /* return success but set the control to N/A */
1670 if (err)
1671 return 0;
1672 if (source == HPI_AESEBU_FORMAT_SPDIF)
1673 ucontrol->value.enumerated.item[0] = 1;
1674 if (source == HPI_AESEBU_FORMAT_AESEBU)
1675 ucontrol->value.enumerated.item[0] = 2;
1676
1677 return 0;
1678}
1679
1680static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1681 struct snd_ctl_elem_value *ucontrol,
1682 u16 (*func)(const struct hpi_hsubsys *, u32, u16))
1683{
1684 u32 h_control = kcontrol->private_value;
1685
1686 /* default to S/PDIF */
1687 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1688
1689 if (ucontrol->value.enumerated.item[0] == 1)
1690 source = HPI_AESEBU_FORMAT_SPDIF;
1691 if (ucontrol->value.enumerated.item[0] == 2)
1692 source = HPI_AESEBU_FORMAT_AESEBU;
1693
1694 if (func(ss, h_control, source) != 0)
1695 return -EINVAL;
1696
1697 return 1;
1698}
1699
1700static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_value *ucontrol) {
1702 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1703 HPI_AESEBU__receiver_get_format);
1704}
1705
1706static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol) {
1708 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1709 HPI_AESEBU__receiver_set_format);
1710}
1711
1712static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1713 struct snd_ctl_elem_info *uinfo)
1714{
1715 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1716 uinfo->count = 1;
1717
1718 uinfo->value.integer.min = 0;
1719 uinfo->value.integer.max = 0X1F;
1720 uinfo->value.integer.step = 1;
1721
1722 return 0;
1723}
1724
1725static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1726 struct snd_ctl_elem_value *ucontrol) {
1727
1728 u32 h_control = kcontrol->private_value;
1729 u16 status;
1730
1731 hpi_handle_error(HPI_AESEBU__receiver_get_error_status(
1732 ss, h_control, &status));
1733 ucontrol->value.integer.value[0] = status;
1734 return 0;
1735}
1736
1737static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1738 struct hpi_control *hpi_ctl)
1739{
1740 struct snd_card *card = asihpi->card;
1741 struct snd_kcontrol_new snd_control;
1742
1743 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1744 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1745 snd_control.info = snd_asihpi_aesebu_format_info;
1746 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1747 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1748
1749
1750 if (ctl_add(card, &snd_control, asihpi) < 0)
1751 return -EINVAL;
1752
1753 asihpi_ctl_init(&snd_control, hpi_ctl, "status");
1754 snd_control.access =
1755 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1756 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1757 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1758
1759 return ctl_add(card, &snd_control, asihpi);
1760}
1761
1762static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1763 struct snd_ctl_elem_value *ucontrol) {
1764 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1765 HPI_AESEBU__transmitter_get_format);
1766}
1767
1768static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1769 struct snd_ctl_elem_value *ucontrol) {
1770 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1771 HPI_AESEBU__transmitter_set_format);
1772}
1773
1774
1775static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1776 struct hpi_control *hpi_ctl)
1777{
1778 struct snd_card *card = asihpi->card;
1779 struct snd_kcontrol_new snd_control;
1780
1781 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1782 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1783 snd_control.info = snd_asihpi_aesebu_format_info;
1784 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1785 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1786
1787 return ctl_add(card, &snd_control, asihpi);
1788}
1789
1790/*------------------------------------------------------------
1791 Tuner controls
1792 ------------------------------------------------------------*/
1793
1794/* Gain */
1795
1796static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_info *uinfo)
1798{
1799 u32 h_control = kcontrol->private_value;
1800 u16 err;
1801 short idx;
1802 u16 gain_range[3];
1803
1804 for (idx = 0; idx < 3; idx++) {
1805 err = hpi_tuner_query_gain(ss, h_control,
1806 idx, &gain_range[idx]);
1807 if (err != 0)
1808 return err;
1809 }
1810
1811 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1812 uinfo->count = 1;
1813 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1814 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1815 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1816 return 0;
1817}
1818
1819static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1820 struct snd_ctl_elem_value *ucontrol)
1821{
1822 /*
1823 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1824 */
1825 u32 h_control = kcontrol->private_value;
1826 short gain;
1827
1828 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain));
1829 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1830
1831 return 0;
1832}
1833
1834static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1835 struct snd_ctl_elem_value *ucontrol)
1836{
1837 /*
1838 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1839 */
1840 u32 h_control = kcontrol->private_value;
1841 short gain;
1842
1843 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1844 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain));
1845
1846 return 1;
1847}
1848
1849/* Band */
1850
1851static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1852 u16 *band_list, u32 len) {
1853 u32 h_control = kcontrol->private_value;
1854 u16 err = 0;
1855 u32 i;
1856
1857 for (i = 0; i < len; i++) {
1858 err = hpi_tuner_query_band(ss,
1859 h_control, i, &band_list[i]);
1860 if (err != 0)
1861 break;
1862 }
1863
1864 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1865 return -EIO;
1866
1867 return i;
1868}
1869
1870static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1871 struct snd_ctl_elem_info *uinfo)
1872{
1873 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1874 int num_bands = 0;
1875
1876 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1877 HPI_TUNER_BAND_LAST);
1878
1879 if (num_bands < 0)
1880 return num_bands;
1881
1882 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1883 uinfo->count = 1;
1884 uinfo->value.enumerated.items = num_bands;
1885
1886 if (num_bands > 0) {
1887 if (uinfo->value.enumerated.item >=
1888 uinfo->value.enumerated.items)
1889 uinfo->value.enumerated.item =
1890 uinfo->value.enumerated.items - 1;
1891
1892 strcpy(uinfo->value.enumerated.name,
1893 asihpi_tuner_band_names[
1894 tuner_bands[uinfo->value.enumerated.item]]);
1895
1896 }
1897 return 0;
1898}
1899
1900static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1901 struct snd_ctl_elem_value *ucontrol)
1902{
1903 u32 h_control = kcontrol->private_value;
1904 /*
1905 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1906 */
1907 u16 band, idx;
1908 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1909 u32 num_bands = 0;
1910
1911 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1912 HPI_TUNER_BAND_LAST);
1913
1914 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band));
1915
1916 ucontrol->value.enumerated.item[0] = -1;
1917 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1918 if (tuner_bands[idx] == band) {
1919 ucontrol->value.enumerated.item[0] = idx;
1920 break;
1921 }
1922
1923 return 0;
1924}
1925
1926static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 /*
1930 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1931 */
1932 u32 h_control = kcontrol->private_value;
1933 u16 band;
1934 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1935 u32 num_bands = 0;
1936
1937 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1938 HPI_TUNER_BAND_LAST);
1939
1940 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1941 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band));
1942
1943 return 1;
1944}
1945
1946/* Freq */
1947
1948static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1949 struct snd_ctl_elem_info *uinfo)
1950{
1951 u32 h_control = kcontrol->private_value;
1952 u16 err;
1953 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1954 u16 num_bands = 0, band_iter, idx;
1955 u32 freq_range[3], temp_freq_range[3];
1956
1957 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1958 HPI_TUNER_BAND_LAST);
1959
1960 freq_range[0] = INT_MAX;
1961 freq_range[1] = 0;
1962 freq_range[2] = INT_MAX;
1963
1964 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1965 for (idx = 0; idx < 3; idx++) {
1966 err = hpi_tuner_query_frequency(ss, h_control,
1967 idx, tuner_bands[band_iter],
1968 &temp_freq_range[idx]);
1969 if (err != 0)
1970 return err;
1971 }
1972
1973 /* skip band with bogus stepping */
1974 if (temp_freq_range[2] <= 0)
1975 continue;
1976
1977 if (temp_freq_range[0] < freq_range[0])
1978 freq_range[0] = temp_freq_range[0];
1979 if (temp_freq_range[1] > freq_range[1])
1980 freq_range[1] = temp_freq_range[1];
1981 if (temp_freq_range[2] < freq_range[2])
1982 freq_range[2] = temp_freq_range[2];
1983 }
1984
1985 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1986 uinfo->count = 1;
1987 uinfo->value.integer.min = ((int)freq_range[0]);
1988 uinfo->value.integer.max = ((int)freq_range[1]);
1989 uinfo->value.integer.step = ((int)freq_range[2]);
1990 return 0;
1991}
1992
1993static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_value *ucontrol)
1995{
1996 u32 h_control = kcontrol->private_value;
1997 u32 freq;
1998
1999 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq));
2000 ucontrol->value.integer.value[0] = freq;
2001
2002 return 0;
2003}
2004
2005static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2006 struct snd_ctl_elem_value *ucontrol)
2007{
2008 u32 h_control = kcontrol->private_value;
2009 u32 freq;
2010
2011 freq = ucontrol->value.integer.value[0];
2012 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq));
2013
2014 return 1;
2015}
2016
2017/* Tuner control group initializer */
2018static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2019 struct hpi_control *hpi_ctl)
2020{
2021 struct snd_card *card = asihpi->card;
2022 struct snd_kcontrol_new snd_control;
2023
2024 snd_control.private_value = hpi_ctl->h_control;
2025 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2026
2027 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2028 asihpi_ctl_init(&snd_control, hpi_ctl, "gain");
2029 snd_control.info = snd_asihpi_tuner_gain_info;
2030 snd_control.get = snd_asihpi_tuner_gain_get;
2031 snd_control.put = snd_asihpi_tuner_gain_put;
2032
2033 if (ctl_add(card, &snd_control, asihpi) < 0)
2034 return -EINVAL;
2035 }
2036
2037 asihpi_ctl_init(&snd_control, hpi_ctl, "band");
2038 snd_control.info = snd_asihpi_tuner_band_info;
2039 snd_control.get = snd_asihpi_tuner_band_get;
2040 snd_control.put = snd_asihpi_tuner_band_put;
2041
2042 if (ctl_add(card, &snd_control, asihpi) < 0)
2043 return -EINVAL;
2044
2045 asihpi_ctl_init(&snd_control, hpi_ctl, "freq");
2046 snd_control.info = snd_asihpi_tuner_freq_info;
2047 snd_control.get = snd_asihpi_tuner_freq_get;
2048 snd_control.put = snd_asihpi_tuner_freq_put;
2049
2050 return ctl_add(card, &snd_control, asihpi);
2051}
2052
2053/*------------------------------------------------------------
2054 Meter controls
2055 ------------------------------------------------------------*/
2056static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2057 struct snd_ctl_elem_info *uinfo)
2058{
2059 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2060 uinfo->count = HPI_MAX_CHANNELS;
2061 uinfo->value.integer.min = 0;
2062 uinfo->value.integer.max = 0x7FFFFFFF;
2063 return 0;
2064}
2065
2066/* linear values for 10dB steps */
2067static int log2lin[] = {
2068 0x7FFFFFFF, /* 0dB */
2069 679093956,
2070 214748365,
2071 67909396,
2072 21474837,
2073 6790940,
2074 2147484, /* -60dB */
2075 679094,
2076 214748, /* -80 */
2077 67909,
2078 21475, /* -100 */
2079 6791,
2080 2147,
2081 679,
2082 214,
2083 68,
2084 21,
2085 7,
2086 2
2087};
2088
2089static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2090 struct snd_ctl_elem_value *ucontrol)
2091{
2092 u32 h_control = kcontrol->private_value;
2093 short an_gain_mB[HPI_MAX_CHANNELS], i;
2094 u16 err;
2095
2096 err = hpi_meter_get_peak(ss, h_control, an_gain_mB);
2097
2098 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2099 if (err) {
2100 ucontrol->value.integer.value[i] = 0;
2101 } else if (an_gain_mB[i] >= 0) {
2102 ucontrol->value.integer.value[i] =
2103 an_gain_mB[i] << 16;
2104 } else {
2105 /* -ve is log value in millibels < -60dB,
2106 * convert to (roughly!) linear,
2107 */
2108 ucontrol->value.integer.value[i] =
2109 log2lin[an_gain_mB[i] / -1000];
2110 }
2111 }
2112 return 0;
2113}
2114
2115static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2116 struct hpi_control *hpi_ctl, int subidx)
2117{
2118 struct snd_card *card = asihpi->card;
2119 struct snd_kcontrol_new snd_control;
2120
2121 asihpi_ctl_init(&snd_control, hpi_ctl, "meter");
2122 snd_control.access =
2123 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2124 snd_control.info = snd_asihpi_meter_info;
2125 snd_control.get = snd_asihpi_meter_get;
2126
2127 snd_control.index = subidx;
2128
2129 return ctl_add(card, &snd_control, asihpi);
2130}
2131
2132/*------------------------------------------------------------
2133 Multiplexer controls
2134 ------------------------------------------------------------*/
2135static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2136{
2137 u32 h_control = snd_control->private_value;
2138 struct hpi_control hpi_ctl;
2139 int s, err;
2140 for (s = 0; s < 32; s++) {
2141 err = hpi_multiplexer_query_source(ss, h_control, s,
2142 &hpi_ctl.
2143 src_node_type,
2144 &hpi_ctl.
2145 src_node_index);
2146 if (err)
2147 break;
2148 }
2149 return s;
2150}
2151
2152static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2153 struct snd_ctl_elem_info *uinfo)
2154{
2155 int err;
2156 u16 src_node_type, src_node_index;
2157 u32 h_control = kcontrol->private_value;
2158
2159 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2160 uinfo->count = 1;
2161 uinfo->value.enumerated.items =
2162 snd_card_asihpi_mux_count_sources(kcontrol);
2163
2164 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2165 uinfo->value.enumerated.item =
2166 uinfo->value.enumerated.items - 1;
2167
2168 err =
2169 hpi_multiplexer_query_source(ss, h_control,
2170 uinfo->value.enumerated.item,
2171 &src_node_type, &src_node_index);
2172
2173 sprintf(uinfo->value.enumerated.name, "%s %d",
2174 asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE],
2175 src_node_index);
2176 return 0;
2177}
2178
2179static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2180 struct snd_ctl_elem_value *ucontrol)
2181{
2182 u32 h_control = kcontrol->private_value;
2183 u16 source_type, source_index;
2184 u16 src_node_type, src_node_index;
2185 int s;
2186
2187 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control,
2188 &source_type, &source_index));
2189 /* Should cache this search result! */
2190 for (s = 0; s < 256; s++) {
2191 if (hpi_multiplexer_query_source(ss, h_control, s,
2192 &src_node_type, &src_node_index))
2193 break;
2194
2195 if ((source_type == src_node_type)
2196 && (source_index == src_node_index)) {
2197 ucontrol->value.enumerated.item[0] = s;
2198 return 0;
2199 }
2200 }
2201 snd_printd(KERN_WARNING
2202 "control %x failed to match mux source %hu %hu\n",
2203 h_control, source_type, source_index);
2204 ucontrol->value.enumerated.item[0] = 0;
2205 return 0;
2206}
2207
2208static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2209 struct snd_ctl_elem_value *ucontrol)
2210{
2211 int change;
2212 u32 h_control = kcontrol->private_value;
2213 u16 source_type, source_index;
2214 u16 e;
2215
2216 change = 1;
2217
2218 e = hpi_multiplexer_query_source(ss, h_control,
2219 ucontrol->value.enumerated.item[0],
2220 &source_type, &source_index);
2221 if (!e)
2222 hpi_handle_error(
2223 hpi_multiplexer_set_source(ss, h_control,
2224 source_type, source_index));
2225 return change;
2226}
2227
2228
2229static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2230 struct hpi_control *hpi_ctl)
2231{
2232 struct snd_card *card = asihpi->card;
2233 struct snd_kcontrol_new snd_control;
2234
2235#if ASI_STYLE_NAMES
2236 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2237#else
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2239#endif
2240 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2241 snd_control.info = snd_asihpi_mux_info;
2242 snd_control.get = snd_asihpi_mux_get;
2243 snd_control.put = snd_asihpi_mux_put;
2244
2245 return ctl_add(card, &snd_control, asihpi);
2246
2247}
2248
2249/*------------------------------------------------------------
2250 Channel mode controls
2251 ------------------------------------------------------------*/
2252static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2253 struct snd_ctl_elem_info *uinfo)
2254{
2255 static char *mode_names[HPI_CHANNEL_MODE_LAST] = {
2256 "normal", "swap",
2257 "from_left", "from_right",
2258 "to_left", "to_right"
2259 };
2260
2261 u32 h_control = kcontrol->private_value;
2262 u16 mode;
2263 int i;
2264
2265 /* HPI channel mode values can be from 1 to 6
2266 Some adapters only support a contiguous subset
2267 */
2268 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2269 if (hpi_channel_mode_query_mode(
2270 ss, h_control, i, &mode))
2271 break;
2272
2273 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2274 uinfo->count = 1;
2275 uinfo->value.enumerated.items = i;
2276
2277 if (uinfo->value.enumerated.item >= i)
2278 uinfo->value.enumerated.item = i - 1;
2279
2280 strcpy(uinfo->value.enumerated.name,
2281 mode_names[uinfo->value.enumerated.item]);
2282
2283 return 0;
2284}
2285
2286static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288{
2289 u32 h_control = kcontrol->private_value;
2290 u16 mode;
2291
2292 if (hpi_channel_mode_get(ss, h_control, &mode))
2293 mode = 1;
2294
2295 ucontrol->value.enumerated.item[0] = mode - 1;
2296
2297 return 0;
2298}
2299
2300static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2301 struct snd_ctl_elem_value *ucontrol)
2302{
2303 int change;
2304 u32 h_control = kcontrol->private_value;
2305
2306 change = 1;
2307
2308 hpi_handle_error(hpi_channel_mode_set(ss, h_control,
2309 ucontrol->value.enumerated.item[0] + 1));
2310 return change;
2311}
2312
2313
2314static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2315 struct hpi_control *hpi_ctl)
2316{
2317 struct snd_card *card = asihpi->card;
2318 struct snd_kcontrol_new snd_control;
2319
2320 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode");
2321 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2322 snd_control.info = snd_asihpi_cmode_info;
2323 snd_control.get = snd_asihpi_cmode_get;
2324 snd_control.put = snd_asihpi_cmode_put;
2325
2326 return ctl_add(card, &snd_control, asihpi);
2327}
2328
2329/*------------------------------------------------------------
2330 Sampleclock source controls
2331 ------------------------------------------------------------*/
2332
2333static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2334 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header",
2335 "SMPTE", "AES/EBU in1", "auto", "network", "invalid",
2336 "prev module",
2337 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5",
2338 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2339
2340
2341
2342static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2343 struct snd_ctl_elem_info *uinfo)
2344{
2345 struct snd_card_asihpi *asihpi =
2346 (struct snd_card_asihpi *)(kcontrol->private_data);
2347 struct clk_cache *clkcache = &asihpi->cc;
2348 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2349 uinfo->count = 1;
2350 uinfo->value.enumerated.items = clkcache->count;
2351
2352 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2353 uinfo->value.enumerated.item =
2354 uinfo->value.enumerated.items - 1;
2355
2356 strcpy(uinfo->value.enumerated.name,
2357 clkcache->s[uinfo->value.enumerated.item].name);
2358 return 0;
2359}
2360
2361static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2362 struct snd_ctl_elem_value *ucontrol)
2363{
2364 struct snd_card_asihpi *asihpi =
2365 (struct snd_card_asihpi *)(kcontrol->private_data);
2366 struct clk_cache *clkcache = &asihpi->cc;
2367 u32 h_control = kcontrol->private_value;
2368 u16 source, srcindex = 0;
2369 int i;
2370
2371 ucontrol->value.enumerated.item[0] = 0;
2372 if (hpi_sample_clock_get_source(ss, h_control, &source))
2373 source = 0;
2374
2375 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2376 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex))
2377 srcindex = 0;
2378
2379 for (i = 0; i < clkcache->count; i++)
2380 if ((clkcache->s[i].source == source) &&
2381 (clkcache->s[i].index == srcindex))
2382 break;
2383
2384 ucontrol->value.enumerated.item[0] = i;
2385
2386 return 0;
2387}
2388
2389static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2390 struct snd_ctl_elem_value *ucontrol)
2391{
2392 struct snd_card_asihpi *asihpi =
2393 (struct snd_card_asihpi *)(kcontrol->private_data);
2394 struct clk_cache *clkcache = &asihpi->cc;
2395 int change, item;
2396 u32 h_control = kcontrol->private_value;
2397
2398 change = 1;
2399 item = ucontrol->value.enumerated.item[0];
2400 if (item >= clkcache->count)
2401 item = clkcache->count-1;
2402
2403 hpi_handle_error(hpi_sample_clock_set_source(ss,
2404 h_control, clkcache->s[item].source));
2405
2406 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2407 hpi_handle_error(hpi_sample_clock_set_source_index(ss,
2408 h_control, clkcache->s[item].index));
2409 return change;
2410}
2411
2412/*------------------------------------------------------------
2413 Clkrate controls
2414 ------------------------------------------------------------*/
2415/* Need to change this to enumerated control with list of rates */
2416static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2417 struct snd_ctl_elem_info *uinfo)
2418{
2419 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2420 uinfo->count = 1;
2421 uinfo->value.integer.min = 8000;
2422 uinfo->value.integer.max = 192000;
2423 uinfo->value.integer.step = 100;
2424
2425 return 0;
2426}
2427
2428static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2429 struct snd_ctl_elem_value *ucontrol)
2430{
2431 u32 h_control = kcontrol->private_value;
2432 u32 rate;
2433 u16 e;
2434
2435 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate);
2436 if (!e)
2437 ucontrol->value.integer.value[0] = rate;
2438 else
2439 ucontrol->value.integer.value[0] = 0;
2440 return 0;
2441}
2442
2443static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2444 struct snd_ctl_elem_value *ucontrol)
2445{
2446 int change;
2447 u32 h_control = kcontrol->private_value;
2448
2449 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2450 asihpi->mixer_clkrate[addr][1] != right;
2451 */
2452 change = 1;
2453 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control,
2454 ucontrol->value.integer.value[0]));
2455 return change;
2456}
2457
2458static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_info *uinfo)
2460{
2461 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2462 uinfo->count = 1;
2463 uinfo->value.integer.min = 8000;
2464 uinfo->value.integer.max = 192000;
2465 uinfo->value.integer.step = 100;
2466
2467 return 0;
2468}
2469
2470static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2471 struct snd_ctl_elem_value *ucontrol)
2472{
2473 u32 h_control = kcontrol->private_value;
2474 u32 rate;
2475 u16 e;
2476
2477 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate);
2478 if (!e)
2479 ucontrol->value.integer.value[0] = rate;
2480 else
2481 ucontrol->value.integer.value[0] = 0;
2482 return 0;
2483}
2484
2485static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2486 struct hpi_control *hpi_ctl)
2487{
2488 struct snd_card *card = asihpi->card;
2489 struct snd_kcontrol_new snd_control;
2490
2491 struct clk_cache *clkcache = &asihpi->cc;
2492 u32 hSC = hpi_ctl->h_control;
2493 int has_aes_in = 0;
2494 int i, j;
2495 u16 source;
2496
2497 snd_control.private_value = hpi_ctl->h_control;
2498
2499 clkcache->has_local = 0;
2500
2501 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2502 if (hpi_sample_clock_query_source(ss, hSC,
2503 i, &source))
2504 break;
2505 clkcache->s[i].source = source;
2506 clkcache->s[i].index = 0;
2507 clkcache->s[i].name = sampleclock_sources[source];
2508 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2509 has_aes_in = 1;
2510 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2511 clkcache->has_local = 1;
2512 }
2513 if (has_aes_in)
2514 /* already will have picked up index 0 above */
2515 for (j = 1; j < 8; j++) {
2516 if (hpi_sample_clock_query_source_index(ss, hSC,
2517 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2518 &source))
2519 break;
2520 clkcache->s[i].source =
2521 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2522 clkcache->s[i].index = j;
2523 clkcache->s[i].name = sampleclock_sources[
2524 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2525 i++;
2526 }
2527 clkcache->count = i;
2528
2529 asihpi_ctl_init(&snd_control, hpi_ctl, "source");
2530 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2531 snd_control.info = snd_asihpi_clksrc_info;
2532 snd_control.get = snd_asihpi_clksrc_get;
2533 snd_control.put = snd_asihpi_clksrc_put;
2534 if (ctl_add(card, &snd_control, asihpi) < 0)
2535 return -EINVAL;
2536
2537
2538 if (clkcache->has_local) {
2539 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate");
2540 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2541 snd_control.info = snd_asihpi_clklocal_info;
2542 snd_control.get = snd_asihpi_clklocal_get;
2543 snd_control.put = snd_asihpi_clklocal_put;
2544
2545
2546 if (ctl_add(card, &snd_control, asihpi) < 0)
2547 return -EINVAL;
2548 }
2549
2550 asihpi_ctl_init(&snd_control, hpi_ctl, "rate");
2551 snd_control.access =
2552 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2553 snd_control.info = snd_asihpi_clkrate_info;
2554 snd_control.get = snd_asihpi_clkrate_get;
2555
2556 return ctl_add(card, &snd_control, asihpi);
2557}
2558/*------------------------------------------------------------
2559 Mixer
2560 ------------------------------------------------------------*/
2561
2562static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2563{
2564 struct snd_card *card = asihpi->card;
2565 unsigned int idx = 0;
2566 unsigned int subindex = 0;
2567 int err;
2568 struct hpi_control hpi_ctl, prev_ctl;
2569
2570 if (snd_BUG_ON(!asihpi))
2571 return -EINVAL;
2572 strcpy(card->mixername, "asihpi mixer");
2573
2574 err =
2575 hpi_mixer_open(ss, asihpi->adapter_index,
2576 &asihpi->h_mixer);
2577 hpi_handle_error(err);
2578 if (err)
2579 return -err;
2580
2581 for (idx = 0; idx < 2000; idx++) {
2582 err = hpi_mixer_get_control_by_index(
2583 ss, asihpi->h_mixer,
2584 idx,
2585 &hpi_ctl.src_node_type,
2586 &hpi_ctl.src_node_index,
2587 &hpi_ctl.dst_node_type,
2588 &hpi_ctl.dst_node_index,
2589 &hpi_ctl.control_type,
2590 &hpi_ctl.h_control);
2591 if (err) {
2592 if (err == HPI_ERROR_CONTROL_DISABLED) {
2593 if (mixer_dump)
2594 snd_printk(KERN_INFO
2595 "disabled HPI control(%d)\n",
2596 idx);
2597 continue;
2598 } else
2599 break;
2600
2601 }
2602
2603 hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE;
2604 hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE;
2605
2606 /* ASI50xx in SSX mode has multiple meters on the same node.
2607 Use subindex to create distinct ALSA controls
2608 for any duplicated controls.
2609 */
2610 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2611 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2612 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2613 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2614 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2615 subindex++;
2616 else
2617 subindex = 0;
2618
2619 prev_ctl = hpi_ctl;
2620
2621 switch (hpi_ctl.control_type) {
2622 case HPI_CONTROL_VOLUME:
2623 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2624 break;
2625 case HPI_CONTROL_LEVEL:
2626 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2627 break;
2628 case HPI_CONTROL_MULTIPLEXER:
2629 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2630 break;
2631 case HPI_CONTROL_CHANNEL_MODE:
2632 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2633 break;
2634 case HPI_CONTROL_METER:
2635 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2636 break;
2637 case HPI_CONTROL_SAMPLECLOCK:
2638 err = snd_asihpi_sampleclock_add(
2639 asihpi, &hpi_ctl);
2640 break;
2641 case HPI_CONTROL_CONNECTION: /* ignore these */
2642 continue;
2643 case HPI_CONTROL_TUNER:
2644 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2645 break;
2646 case HPI_CONTROL_AESEBU_TRANSMITTER:
2647 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2648 break;
2649 case HPI_CONTROL_AESEBU_RECEIVER:
2650 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2651 break;
2652 case HPI_CONTROL_VOX:
2653 case HPI_CONTROL_BITSTREAM:
2654 case HPI_CONTROL_MICROPHONE:
2655 case HPI_CONTROL_PARAMETRIC_EQ:
2656 case HPI_CONTROL_COMPANDER:
2657 default:
2658 if (mixer_dump)
2659 snd_printk(KERN_INFO
2660 "untranslated HPI control"
2661 "(%d) %d %d %d %d %d\n",
2662 idx,
2663 hpi_ctl.control_type,
2664 hpi_ctl.src_node_type,
2665 hpi_ctl.src_node_index,
2666 hpi_ctl.dst_node_type,
2667 hpi_ctl.dst_node_index);
2668 continue;
2669 };
2670 if (err < 0)
2671 return err;
2672 }
2673 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2674 hpi_handle_error(err);
2675
2676 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2677
2678 return 0;
2679}
2680
2681/*------------------------------------------------------------
2682 /proc interface
2683 ------------------------------------------------------------*/
2684
2685static void
2686snd_asihpi_proc_read(struct snd_info_entry *entry,
2687 struct snd_info_buffer *buffer)
2688{
2689 struct snd_card_asihpi *asihpi = entry->private_data;
2690 u16 version;
2691 u32 h_control;
2692 u32 rate = 0;
2693 u16 source = 0;
2694 int err;
2695
2696 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2697 snd_iprintf(buffer,
2698 "adapter ID=%4X\n_index=%d\n"
2699 "num_outstreams=%d\n_num_instreams=%d\n",
2700 asihpi->type, asihpi->adapter_index,
2701 asihpi->num_outstreams, asihpi->num_instreams);
2702
2703 version = asihpi->version;
2704 snd_iprintf(buffer,
2705 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2706 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2707 version & 0x7,
2708 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2709
2710 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2711 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2712 HPI_CONTROL_SAMPLECLOCK, &h_control);
2713
2714 if (!err) {
2715 err = hpi_sample_clock_get_sample_rate(ss,
2716 h_control, &rate);
2717 err += hpi_sample_clock_get_source(ss, h_control, &source);
2718
2719 if (!err)
2720 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2721 rate, sampleclock_sources[source]);
2722 }
2723
2724}
2725
2726
2727static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2728{
2729 struct snd_info_entry *entry;
2730
2731 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2732 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2733}
2734
2735/*------------------------------------------------------------
2736 HWDEP
2737 ------------------------------------------------------------*/
2738
2739static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2740{
2741 if (enable_hpi_hwdep)
2742 return 0;
2743 else
2744 return -ENODEV;
2745
2746}
2747
2748static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2749{
2750 if (enable_hpi_hwdep)
2751 return asihpi_hpi_release(file);
2752 else
2753 return -ENODEV;
2754}
2755
2756static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2757 unsigned int cmd, unsigned long arg)
2758{
2759 if (enable_hpi_hwdep)
2760 return asihpi_hpi_ioctl(file, cmd, arg);
2761 else
2762 return -ENODEV;
2763}
2764
2765
2766/* results in /dev/snd/hwC#D0 file for each card with index #
2767 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2768*/
2769static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2770 int device, struct snd_hwdep **rhwdep)
2771{
2772 struct snd_hwdep *hw;
2773 int err;
2774
2775 if (rhwdep)
2776 *rhwdep = NULL;
2777 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2778 if (err < 0)
2779 return err;
2780 strcpy(hw->name, "asihpi (HPI)");
2781 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2782 hw->ops.open = snd_asihpi_hpi_open;
2783 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2784 hw->ops.release = snd_asihpi_hpi_release;
2785 hw->private_data = asihpi;
2786 if (rhwdep)
2787 *rhwdep = hw;
2788 return 0;
2789}
2790
2791/*------------------------------------------------------------
2792 CARD
2793 ------------------------------------------------------------*/
2794static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2795 const struct pci_device_id *pci_id)
2796{
2797 int err;
2798
2799 u16 version;
2800 int pcm_substreams;
2801
2802 struct hpi_adapter *hpi_card;
2803 struct snd_card *card;
2804 struct snd_card_asihpi *asihpi;
2805
2806 u32 h_control;
2807 u32 h_stream;
2808
2809 static int dev;
2810 if (dev >= SNDRV_CARDS)
2811 return -ENODEV;
2812
2813 /* Should this be enable[hpi_card->index] ? */
2814 if (!enable[dev]) {
2815 dev++;
2816 return -ENOENT;
2817 }
2818
2819 err = asihpi_adapter_probe(pci_dev, pci_id);
2820 if (err < 0)
2821 return err;
2822
2823 hpi_card = pci_get_drvdata(pci_dev);
2824 /* first try to give the card the same index as its hardware index */
2825 err = snd_card_create(hpi_card->index,
2826 id[hpi_card->index], THIS_MODULE,
2827 sizeof(struct snd_card_asihpi),
2828 &card);
2829 if (err < 0) {
2830 /* if that fails, try the default index==next available */
2831 err =
2832 snd_card_create(index[dev], id[dev],
2833 THIS_MODULE,
2834 sizeof(struct snd_card_asihpi),
2835 &card);
2836 if (err < 0)
2837 return err;
2838 snd_printk(KERN_WARNING
2839 "**** WARNING **** adapter index %d->ALSA index %d\n",
2840 hpi_card->index, card->number);
2841 }
2842
2843 asihpi = (struct snd_card_asihpi *) card->private_data;
2844 asihpi->card = card;
2845 asihpi->pci = hpi_card->pci;
2846 asihpi->adapter_index = hpi_card->index;
2847 hpi_handle_error(hpi_adapter_get_info(ss,
2848 asihpi->adapter_index,
2849 &asihpi->num_outstreams,
2850 &asihpi->num_instreams,
2851 &asihpi->version,
2852 &asihpi->serial_number, &asihpi->type));
2853
2854 version = asihpi->version;
2855 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2856 "num_instreams=%d S/N=%d\n"
2857 "hw version %c%d DSP code version %03d\n",
2858 asihpi->type, asihpi->adapter_index,
2859 asihpi->num_outstreams,
2860 asihpi->num_instreams, asihpi->serial_number,
2861 ((version >> 3) & 0xf) + 'A',
2862 version & 0x7,
2863 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2864
2865 pcm_substreams = asihpi->num_outstreams;
2866 if (pcm_substreams < asihpi->num_instreams)
2867 pcm_substreams = asihpi->num_instreams;
2868
2869 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2870 HPI_ADAPTER_PROPERTY_CAPS1,
2871 NULL, &asihpi->support_grouping);
2872 if (err)
2873 asihpi->support_grouping = 0;
2874
2875 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2876 HPI_ADAPTER_PROPERTY_CAPS2,
2877 &asihpi->support_mrx, NULL);
2878 if (err)
2879 asihpi->support_mrx = 0;
2880
2881 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2882 HPI_ADAPTER_PROPERTY_INTERVAL,
2883 NULL, &asihpi->update_interval_frames);
2884 if (err)
2885 asihpi->update_interval_frames = 512;
2886
2887 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index,
2888 0, &h_stream));
2889
2890 err = hpi_instream_host_buffer_free(ss, h_stream);
2891 asihpi->support_mmap = (!err);
2892
2893 hpi_handle_error(hpi_instream_close(ss, h_stream));
2894
2895 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2896 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2897 &asihpi->in_max_chans, &asihpi->out_max_chans);
2898 if (err) {
2899 asihpi->in_max_chans = 2;
2900 asihpi->out_max_chans = 2;
2901 }
2902
2903 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2904 asihpi->support_mmap,
2905 asihpi->support_grouping,
2906 asihpi->support_mrx
2907 );
2908
2909
2910 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2911 if (err < 0) {
2912 snd_printk(KERN_ERR "pcm_new failed\n");
2913 goto __nodev;
2914 }
2915 err = snd_card_asihpi_mixer_new(asihpi);
2916 if (err < 0) {
2917 snd_printk(KERN_ERR "mixer_new failed\n");
2918 goto __nodev;
2919 }
2920
2921 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2922 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2923 HPI_CONTROL_SAMPLECLOCK, &h_control);
2924
2925 if (!err)
2926 err = hpi_sample_clock_set_local_rate(
2927 ss, h_control, adapter_fs);
2928
2929 snd_asihpi_proc_init(asihpi);
2930
2931 /* always create, can be enabled or disabled dynamically
2932 by enable_hwdep module param*/
2933 snd_asihpi_hpi_new(asihpi, 0, NULL);
2934
2935 if (asihpi->support_mmap)
2936 strcpy(card->driver, "ASIHPI-MMAP");
2937 else
2938 strcpy(card->driver, "ASIHPI");
2939
2940 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2941 sprintf(card->longname, "%s %i",
2942 card->shortname, asihpi->adapter_index);
2943 err = snd_card_register(card);
2944 if (!err) {
2945 hpi_card->snd_card_asihpi = card;
2946 dev++;
2947 return 0;
2948 }
2949__nodev:
2950 snd_card_free(card);
2951 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2952 return err;
2953
2954}
2955
2956static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2957{
2958 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2959
2960 snd_card_free(hpi_card->snd_card_asihpi);
2961 hpi_card->snd_card_asihpi = NULL;
2962 asihpi_adapter_remove(pci_dev);
2963}
2964
2965static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2966 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2967 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2968 (kernel_ulong_t)HPI_6205},
2969 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2970 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2971 (kernel_ulong_t)HPI_6000},
2972 {0,}
2973};
2974MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2975
2976static struct pci_driver driver = {
2977 .name = "asihpi",
2978 .id_table = asihpi_pci_tbl,
2979 .probe = snd_asihpi_probe,
2980 .remove = __devexit_p(snd_asihpi_remove),
2981#ifdef CONFIG_PM
2982/* .suspend = snd_asihpi_suspend,
2983 .resume = snd_asihpi_resume, */
2984#endif
2985};
2986
2987static int __init snd_asihpi_init(void)
2988{
2989 asihpi_init();
2990 return pci_register_driver(&driver);
2991}
2992
2993static void __exit snd_asihpi_exit(void)
2994{
2995
2996 pci_unregister_driver(&driver);
2997 asihpi_exit();
2998}
2999
3000module_init(snd_asihpi_init)
3001module_exit(snd_asihpi_exit)
3002
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
new file mode 100644
index 000000000000..99400de6c075
--- /dev/null
+++ b/sound/pci/asihpi/hpi.h
@@ -0,0 +1,2001 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19*/
20/** \file hpi.h
21
22 AudioScience Hardware Programming Interface (HPI)
23 public API definition.
24
25 The HPI is a low-level hardware abstraction layer to all
26 AudioScience digital audio adapters
27*/
28/*
29 You must define one operating system that the HPI is to be compiled under
30 HPI_OS_WIN32_USER 32bit Windows
31 HPI_OS_DSP_C6000 DSP TI C6000 (automatically set)
32 HPI_OS_WDM Windows WDM kernel driver
33 HPI_OS_LINUX Linux userspace
34 HPI_OS_LINUX_KERNEL Linux kernel (automatically set)
35
36(C) Copyright AudioScience Inc. 1998-2010
37******************************************************************************/
38#ifndef _HPI_H_
39#define _HPI_H_
40/* HPI Version
41If HPI_VER_MINOR is odd then its a development release not intended for the
42public. If HPI_VER_MINOR is even then is a release version
43i.e 3.05.02 is a development version
44*/
45#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \
46 ((maj << 16) + (min << 8) + rel)
47
48#define HPI_VER_MAJOR(v) ((int)(v >> 16))
49#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
51
52/* Use single digits for versions less that 10 to avoid octal. */
53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 18)
54
55/* Library version as documented in hpi-api-versions.txt */
56#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
57
58#include <linux/types.h>
59#define HPI_EXCLUDE_DEPRECATED
60
61/******************************************************************************/
62/******************************************************************************/
63/******** HPI API DEFINITIONS *****/
64/******************************************************************************/
65/******************************************************************************/
66/*******************************************/
67/** Audio format types
68\ingroup stream
69*/
70enum HPI_FORMATS {
71/** Used internally on adapter. */
72 HPI_FORMAT_MIXER_NATIVE = 0,
73/** 8-bit unsigned PCM. Windows equivalent is WAVE_FORMAT_PCM. */
74 HPI_FORMAT_PCM8_UNSIGNED = 1,
75/** 16-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM. */
76 HPI_FORMAT_PCM16_SIGNED = 2,
77/** MPEG-1 Layer-1. */
78 HPI_FORMAT_MPEG_L1 = 3,
79/** MPEG-1 Layer-2.
80
81Windows equivalent is WAVE_FORMAT_MPEG.
82
83The following table shows what combinations of mode and bitrate are possible:
84
85<table border=1 cellspacing=0 cellpadding=5>
86<tr>
87<td><p><b>Bitrate (kbs)</b></p>
88<td><p><b>Mono</b></p>
89<td><p><b>Stereo,<br>Joint Stereo or<br>Dual Channel</b></p>
90
91<tr><td>32<td>X<td>_
92<tr><td>40<td>_<td>_
93<tr><td>48<td>X<td>_
94<tr><td>56<td>X<td>_
95<tr><td>64<td>X<td>X
96<tr><td>80<td>X<td>_
97<tr><td>96<td>X<td>X
98<tr><td>112<td>X<td>X
99<tr><td>128<td>X<td>X
100<tr><td>160<td>X<td>X
101<tr><td>192<td>X<td>X
102<tr><td>224<td>_<td>X
103<tr><td>256<td>-<td>X
104<tr><td>320<td>-<td>X
105<tr><td>384<td>_<td>X
106</table>
107*/
108 HPI_FORMAT_MPEG_L2 = 4,
109/** MPEG-1 Layer-3.
110Windows equivalent is WAVE_FORMAT_MPEG.
111
112The following table shows what combinations of mode and bitrate are possible:
113
114<table border=1 cellspacing=0 cellpadding=5>
115<tr>
116<td><p><b>Bitrate (kbs)</b></p>
117<td><p><b>Mono<br>Stereo @ 8,<br>11.025 and<br>12kHz*</b></p>
118<td><p><b>Mono<br>Stereo @ 16,<br>22.050 and<br>24kHz*</b></p>
119<td><p><b>Mono<br>Stereo @ 32,<br>44.1 and<br>48kHz</b></p>
120
121<tr><td>16<td>X<td>X<td>_
122<tr><td>24<td>X<td>X<td>_
123<tr><td>32<td>X<td>X<td>X
124<tr><td>40<td>X<td>X<td>X
125<tr><td>48<td>X<td>X<td>X
126<tr><td>56<td>X<td>X<td>X
127<tr><td>64<td>X<td>X<td>X
128<tr><td>80<td>_<td>X<td>X
129<tr><td>96<td>_<td>X<td>X
130<tr><td>112<td>_<td>X<td>X
131<tr><td>128<td>_<td>X<td>X
132<tr><td>144<td>_<td>X<td>_
133<tr><td>160<td>_<td>X<td>X
134<tr><td>192<td>_<td>_<td>X
135<tr><td>224<td>_<td>_<td>X
136<tr><td>256<td>-<td>_<td>X
137<tr><td>320<td>-<td>_<td>X
138</table>
139\b * Available on the ASI6000 series only
140*/
141 HPI_FORMAT_MPEG_L3 = 5,
142/** Dolby AC-2. */
143 HPI_FORMAT_DOLBY_AC2 = 6,
144/** Dolbt AC-3. */
145 HPI_FORMAT_DOLBY_AC3 = 7,
146/** 16-bit PCM big-endian. */
147 HPI_FORMAT_PCM16_BIGENDIAN = 8,
148/** TAGIT-1 algorithm - hits. */
149 HPI_FORMAT_AA_TAGIT1_HITS = 9,
150/** TAGIT-1 algorithm - inserts. */
151 HPI_FORMAT_AA_TAGIT1_INSERTS = 10,
152/** 32-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM.
153Each sample is a 32bit word. The most significant 24 bits contain a 24-bit
154sample and the least significant 8 bits are set to 0.
155*/
156 HPI_FORMAT_PCM32_SIGNED = 11,
157/** Raw bitstream - unknown format. */
158 HPI_FORMAT_RAW_BITSTREAM = 12,
159/** TAGIT-1 algorithm hits - extended. */
160 HPI_FORMAT_AA_TAGIT1_HITS_EX1 = 13,
161/** 32-bit PCM as an IEEE float. Windows equivalent is WAVE_FORMAT_IEEE_FLOAT.
162Each sample is a 32bit word in IEEE754 floating point format.
163The range is +1.0 to -1.0, which corresponds to digital fullscale.
164*/
165 HPI_FORMAT_PCM32_FLOAT = 14,
166/** 24-bit PCM signed. Windows equivalent is WAVE_FORMAT_PCM. */
167 HPI_FORMAT_PCM24_SIGNED = 15,
168/** OEM format 1 - private. */
169 HPI_FORMAT_OEM1 = 16,
170/** OEM format 2 - private. */
171 HPI_FORMAT_OEM2 = 17,
172/** Undefined format. */
173 HPI_FORMAT_UNDEFINED = 0xffff
174};
175
176/******************************************* in/out Stream states */
177/*******************************************/
178/** Stream States
179\ingroup stream
180*/
181enum HPI_STREAM_STATES {
182 /** State stopped - stream is stopped. */
183 HPI_STATE_STOPPED = 1,
184 /** State playing - stream is playing audio. */
185 HPI_STATE_PLAYING = 2,
186 /** State recording - stream is recording. */
187 HPI_STATE_RECORDING = 3,
188 /** State drained - playing stream ran out of data to play. */
189 HPI_STATE_DRAINED = 4,
190 /** State generate sine - to be implemented. */
191 HPI_STATE_SINEGEN = 5,
192 /** State wait - used for inter-card sync to mean waiting for all
193 cards to be ready. */
194 HPI_STATE_WAIT = 6
195};
196/******************************************* mixer source node types */
197/** Source node types
198\ingroup mixer
199*/
200enum HPI_SOURCENODES {
201 /** This define can be used instead of 0 to indicate
202 that there is no valid source node. A control that
203 exists on a destination node can be searched for using a source
204 node value of either 0, or HPI_SOURCENODE_NONE */
205 HPI_SOURCENODE_NONE = 100,
206 /** \deprecated Use HPI_SOURCENODE_NONE instead. */
207 HPI_SOURCENODE_BASE = 100,
208 /** Out Stream (Play) node. */
209 HPI_SOURCENODE_OSTREAM = 101,
210 /** Line in node - could be analog, AES/EBU or network. */
211 HPI_SOURCENODE_LINEIN = 102,
212 HPI_SOURCENODE_AESEBU_IN = 103, /**< AES/EBU input node. */
213 HPI_SOURCENODE_TUNER = 104, /**< tuner node. */
214 HPI_SOURCENODE_RF = 105, /**< RF input node. */
215 HPI_SOURCENODE_CLOCK_SOURCE = 106, /**< clock source node. */
216 HPI_SOURCENODE_RAW_BITSTREAM = 107, /**< raw bitstream node. */
217 HPI_SOURCENODE_MICROPHONE = 108, /**< microphone node. */
218 /** Cobranet input node -
219 Audio samples come from the Cobranet network and into the device. */
220 HPI_SOURCENODE_COBRANET = 109,
221 HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
222 HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
223 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
224 HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */
225 /* AX6 max sourcenode types = 15 */
226};
227
228/******************************************* mixer dest node types */
229/** Destination node types
230\ingroup mixer
231*/
232enum HPI_DESTNODES {
233 /** This define can be used instead of 0 to indicate
234 that there is no valid destination node. A control that
235 exists on a source node can be searched for using a destination
236 node value of either 0, or HPI_DESTNODE_NONE */
237 HPI_DESTNODE_NONE = 200,
238 /** \deprecated Use HPI_DESTNODE_NONE instead. */
239 HPI_DESTNODE_BASE = 200,
240 /** In Stream (Record) node. */
241 HPI_DESTNODE_ISTREAM = 201,
242 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
243 HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
244 HPI_DESTNODE_RF = 204, /**< RF output node. */
245 HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
246 /** Cobranet output node -
247 Audio samples from the device are sent out on the Cobranet network.*/
248 HPI_DESTNODE_COBRANET = 206,
249 HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
250
251 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
252 HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */
253 /* AX6 max destnode types = 15 */
254};
255
256/*******************************************/
257/** Mixer control types
258\ingroup mixer
259*/
260enum HPI_CONTROLS {
261 HPI_CONTROL_GENERIC = 0, /**< generic control. */
262 HPI_CONTROL_CONNECTION = 1, /**< A connection between nodes. */
263 HPI_CONTROL_VOLUME = 2, /**< volume control - works in dB_fs. */
264 HPI_CONTROL_METER = 3, /**< peak meter control. */
265 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */
266 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */
267
268 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control. */
269 HPI_CONTROL_AESEBUTX = HPI_CONTROL_AESEBU_TRANSMITTER,
270
271 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */
272 HPI_CONTROL_AESEBURX = HPI_CONTROL_AESEBU_RECEIVER,
273
274 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */
275 HPI_CONTROL_TUNER = 9, /**< tuner control. */
276/* HPI_CONTROL_ONOFFSWITCH = 10 */
277 HPI_CONTROL_VOX = 11, /**< vox control. */
278/* HPI_CONTROL_AES18_TRANSMITTER = 12 */
279/* HPI_CONTROL_AES18_RECEIVER = 13 */
280/* HPI_CONTROL_AES18_BLOCKGENERATOR = 14 */
281 HPI_CONTROL_CHANNEL_MODE = 15, /**< channel mode control. */
282
283 HPI_CONTROL_BITSTREAM = 16, /**< bitstream control. */
284 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */
285 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */
286 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */
287 HPI_CONTROL_EQUALIZER = HPI_CONTROL_PARAMETRIC_EQ,
288
289 HPI_CONTROL_COMPANDER = 20, /**< compander control. */
290 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */
291 HPI_CONTROL_TONEDETECTOR = 22, /**< tone detector control. */
292 HPI_CONTROL_SILENCEDETECTOR = 23, /**< silence detector control. */
293 HPI_CONTROL_PAD = 24, /**< tuner PAD control. */
294 HPI_CONTROL_SRC = 25, /**< samplerate converter control. */
295 HPI_CONTROL_UNIVERSAL = 26, /**< universal control. */
296
297/* !!! Update this AND hpidebug.h if you add a new control type!!!*/
298 HPI_CONTROL_LAST_INDEX = 26 /**<highest control type ID */
299/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */
300};
301
302/* Shorthand names that match attribute names */
303
304/******************************************* ADAPTER ATTRIBUTES ****/
305
306/** Adapter properties
307These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty()
308\ingroup adapter
309*/
310enum HPI_ADAPTER_PROPERTIES {
311/** \internal Used in dwProperty field of HPI_AdapterSetProperty() and
312HPI_AdapterGetProperty(). This errata applies to all ASI6000 cards with both
313analog and digital outputs. The CS4224 A/D+D/A has a one sample delay between
314left and right channels on both its input (ADC) and output (DAC).
315More details are available in Cirrus Logic errata ER284B2.
316PDF available from www.cirrus.com, released by Cirrus in 2001.
317*/
318 HPI_ADAPTER_PROPERTY_ERRATA_1 = 1,
319
320/** Adapter grouping property
321Indicates whether the adapter supports the grouping API (for ASIO and SSX2)
322*/
323 HPI_ADAPTER_PROPERTY_GROUPING = 2,
324
325/** Driver SSX2 property
326Tells the kernel driver to turn on SSX2 stream mapping.
327This feature is not used by the DSP. In fact the call is completely processed
328by the driver and is not passed on to the DSP at all.
329*/
330 HPI_ADAPTER_PROPERTY_ENABLE_SSX2 = 3,
331
332/** Adapter SSX2 property
333Indicates the state of the adapter's SSX2 setting. This setting is stored in
334non-volatile memory on the adapter. A typical call sequence would be to use
335HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload
336the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during startup
337and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2 to enable
338SSX2 stream mapping within the kernel level of the driver.
339*/
340 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4,
341
342/** Base number for readonly properties */
343 HPI_ADAPTER_PROPERTY_READONLYBASE = 256,
344
345/** Readonly adapter latency property.
346This property returns in the input and output latency in samples.
347Property 1 is the estimated input latency
348in samples, while Property 2 is that output latency in samples.
349*/
350 HPI_ADAPTER_PROPERTY_LATENCY = 256,
351
352/** Readonly adapter granularity property.
353The granulariy is the smallest size chunk of stereo samples that is processed by
354the adapter.
355This property returns the record granularity in samples in Property 1.
356Property 2 returns the play granularity.
357*/
358 HPI_ADAPTER_PROPERTY_GRANULARITY = 257,
359
360/** Readonly adapter number of current channels property.
361Property 1 is the number of record channels per record device.
362Property 2 is the number of play channels per playback device.*/
363 HPI_ADAPTER_PROPERTY_CURCHANNELS = 258,
364
365/** Readonly adapter software version.
366The SOFTWARE_VERSION property returns the version of the software running
367on the adapter as Major.Minor.Release.
368Property 1 contains Major in bits 15..8 and Minor in bits 7..0.
369Property 2 contains Release in bits 7..0. */
370 HPI_ADAPTER_PROPERTY_SOFTWARE_VERSION = 259,
371
372/** Readonly adapter MAC address MSBs.
373The MAC_ADDRESS_MSB property returns
374the most significant 32 bits of the MAC address.
375Property 1 contains bits 47..32 of the MAC address.
376Property 2 contains bits 31..16 of the MAC address. */
377 HPI_ADAPTER_PROPERTY_MAC_ADDRESS_MSB = 260,
378
379/** Readonly adapter MAC address LSBs
380The MAC_ADDRESS_LSB property returns
381the least significant 16 bits of the MAC address.
382Property 1 contains bits 15..0 of the MAC address. */
383 HPI_ADAPTER_PROPERTY_MAC_ADDRESS_LSB = 261,
384
385/** Readonly extended adapter type number
386The EXTENDED_ADAPTER_TYPE property returns the 4 digits of an extended
387adapter type, i.e ASI8920-0022, 0022 is the extended type.
388The digits are returned as ASCII characters rather than the hex digits that
389are returned for the main type
390Property 1 returns the 1st two (left most) digits, i.e "00"
391in the example above, the upper byte being the left most digit.
392Property 2 returns the 2nd two digits, i.e "22" in the example above*/
393 HPI_ADAPTER_PROPERTY_EXTENDED_ADAPTER_TYPE = 262,
394
395/** Readonly debug log buffer information */
396 HPI_ADAPTER_PROPERTY_LOGTABLEN = 263,
397 HPI_ADAPTER_PROPERTY_LOGTABBEG = 264,
398
399/** Readonly adapter IP address
400For 192.168.1.101
401Property 1 returns the 1st two (left most) digits, i.e 192*256 + 168
402in the example above, the upper byte being the left most digit.
403Property 2 returns the 2nd two digits, i.e 1*256 + 101 in the example above, */
404 HPI_ADAPTER_PROPERTY_IP_ADDRESS = 265,
405
406/** Readonly adapter buffer processed count. Returns a buffer processed count
407that is incremented every time all buffers for all streams are updated. This
408is useful for checking completion of all stream operations across the adapter
409when using grouped streams.
410*/
411 HPI_ADAPTER_PROPERTY_BUFFER_UPDATE_COUNT = 266,
412
413/** Readonly mixer and stream intervals
414
415These intervals are measured in mixer frames.
416To convert to time, divide by the adapter samplerate.
417
418The mixer interval is the number of frames processed in one mixer iteration.
419The stream update interval is the interval at which streams check for and
420process data, and BBM host buffer counters are updated.
421
422Property 1 is the mixer interval in mixer frames.
423Property 2 is the stream update interval in mixer frames.
424*/
425 HPI_ADAPTER_PROPERTY_INTERVAL = 267,
426/** Adapter capabilities 1
427Property 1 - adapter can do multichannel (SSX1)
428Property 2 - adapter can do stream grouping (supports SSX2)
429*/
430 HPI_ADAPTER_PROPERTY_CAPS1 = 268,
431/** Adapter capabilities 2
432Property 1 - adapter can do samplerate conversion (MRX)
433Property 2 - adapter can do timestretch (TSX)
434*/
435 HPI_ADAPTER_PROPERTY_CAPS2 = 269
436};
437
438/** Adapter mode commands
439
440Used in wQueryOrSet field of HPI_AdapterSetModeEx().
441\ingroup adapter
442*/
443enum HPI_ADAPTER_MODE_CMDS {
444 HPI_ADAPTER_MODE_SET = 0,
445 HPI_ADAPTER_MODE_QUERY = 1
446};
447
448/** Adapter Modes
449 These are used by HPI_AdapterSetModeEx()
450
451\warning - more than 16 possible modes breaks
452a bitmask in the Windows WAVE DLL
453\ingroup adapter
454*/
455enum HPI_ADAPTER_MODES {
456/** 4 outstream mode.
457- ASI6114: 1 instream
458- ASI6044: 4 instreams
459- ASI6012: 1 instream
460- ASI6102: no instreams
461- ASI6022, ASI6122: 2 instreams
462- ASI5111, ASI5101: 2 instreams
463- ASI652x, ASI662x: 2 instreams
464- ASI654x, ASI664x: 4 instreams
465*/
466 HPI_ADAPTER_MODE_4OSTREAM = 1,
467
468/** 6 outstream mode.
469- ASI6012: 1 instream,
470- ASI6022, ASI6122: 2 instreams
471- ASI652x, ASI662x: 4 instreams
472*/
473 HPI_ADAPTER_MODE_6OSTREAM = 2,
474
475/** 8 outstream mode.
476- ASI6114: 8 instreams
477- ASI6118: 8 instreams
478- ASI6585: 8 instreams
479*/
480 HPI_ADAPTER_MODE_8OSTREAM = 3,
481
482/** 16 outstream mode.
483- ASI6416 16 instreams
484- ASI6518, ASI6618 16 instreams
485- ASI6118 16 mono out and in streams
486*/
487 HPI_ADAPTER_MODE_16OSTREAM = 4,
488
489/** one outstream mode.
490- ASI5111 1 outstream, 1 instream
491*/
492 HPI_ADAPTER_MODE_1OSTREAM = 5,
493
494/** ASI504X mode 1. 12 outstream, 4 instream 0 to 48kHz sample rates
495 (see ASI504X datasheet for more info).
496*/
497 HPI_ADAPTER_MODE_1 = 6,
498
499/** ASI504X mode 2. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
500 (see ASI504X datasheet for more info).
501*/
502 HPI_ADAPTER_MODE_2 = 7,
503
504/** ASI504X mode 3. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
505 (see ASI504X datasheet for more info).
506*/
507 HPI_ADAPTER_MODE_3 = 8,
508
509/** ASI504X multichannel mode.
510 2 outstreams -> 4 line outs = 1 to 8 channel streams),
511 4 lineins -> 1 instream (1 to 8 channel streams) at 0-48kHz.
512 For more info see the SSX Specification.
513*/
514 HPI_ADAPTER_MODE_MULTICHANNEL = 9,
515
516/** 12 outstream mode.
517- ASI6514, ASI6614: 2 instreams
518- ASI6540,ASI6544: 8 instreams
519- ASI6640,ASI6644: 8 instreams
520*/
521 HPI_ADAPTER_MODE_12OSTREAM = 10,
522
523/** 9 outstream mode.
524- ASI6044: 8 instreams
525*/
526 HPI_ADAPTER_MODE_9OSTREAM = 11,
527
528/** mono mode.
529- ASI6416: 16 outstreams/instreams
530- ASI5402: 2 outstreams/instreams
531*/
532 HPI_ADAPTER_MODE_MONO = 12,
533
534/** Low latency mode.
535- ASI6416/ASI6316: 1 16 channel outstream and instream
536*/
537 HPI_ADAPTER_MODE_LOW_LATENCY = 13
538};
539
540/* Note, adapters can have more than one capability -
541encoding as bitfield is recommended. */
542#define HPI_CAPABILITY_NONE (0)
543#define HPI_CAPABILITY_MPEG_LAYER3 (1)
544
545/* Set this equal to maximum capability index,
546Must not be greater than 32 - see axnvdef.h */
547#define HPI_CAPABILITY_MAX 1
548/* #define HPI_CAPABILITY_AAC 2 */
549
550/******************************************* STREAM ATTRIBUTES ****/
551
552/** MPEG Ancillary Data modes
553
554The mode for the ancillary data insertion or extraction to operate in.
555\ingroup stream
556*/
557enum HPI_MPEG_ANC_MODES {
558 /** the MPEG frames have energy information stored in them (5 bytes per stereo frame, 3 per mono) */
559 HPI_MPEG_ANC_HASENERGY = 0,
560 /** the entire ancillary data field is taken up by data from the Anc data buffer
561 On encode, the encoder will insert the energy bytes before filling the remainder
562 of the ancillary data space with data from the ancillary data buffer.
563 */
564 HPI_MPEG_ANC_RAW = 1
565};
566
567/** Ancillary Data Alignment
568\ingroup instream
569*/
570enum HPI_ISTREAM_MPEG_ANC_ALIGNS {
571 /** data is packed against the end of data, then padded to the end of frame */
572 HPI_MPEG_ANC_ALIGN_LEFT = 0,
573 /** data is packed against the end of the frame */
574 HPI_MPEG_ANC_ALIGN_RIGHT = 1
575};
576
577/** MPEG modes
578MPEG modes - can be used optionally for HPI_FormatCreate()
579parameter dwAttributes.
580
581Using any mode setting other than HPI_MPEG_MODE_DEFAULT
582with single channel format will return an error.
583\ingroup stream
584*/
585enum HPI_MPEG_MODES {
586/** Causes the MPEG-1 Layer II bitstream to be recorded
587in single_channel mode when the number of channels is 1 and in stereo when the
588number of channels is 2. */
589 HPI_MPEG_MODE_DEFAULT = 0,
590 /** Standard stereo without joint-stereo compression */
591 HPI_MPEG_MODE_STEREO = 1,
592 /** Joint stereo */
593 HPI_MPEG_MODE_JOINTSTEREO = 2,
594 /** Left and Right channels are completely independent */
595 HPI_MPEG_MODE_DUALCHANNEL = 3
596};
597/******************************************* MIXER ATTRIBUTES ****/
598
599/* \defgroup mixer_flags Mixer flags for HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES
600{
601*/
602#define HPI_MIXER_GET_CONTROL_MULTIPLE_CHANGED (0)
603#define HPI_MIXER_GET_CONTROL_MULTIPLE_RESET (1)
604/*}*/
605
606/** Commands used by HPI_MixerStore()
607\ingroup mixer
608*/
609enum HPI_MIXER_STORE_COMMAND {
610/** Save all mixer control settings. */
611 HPI_MIXER_STORE_SAVE = 1,
612/** Restore all controls from saved. */
613 HPI_MIXER_STORE_RESTORE = 2,
614/** Delete saved control settings. */
615 HPI_MIXER_STORE_DELETE = 3,
616/** Enable auto storage of some control settings. */
617 HPI_MIXER_STORE_ENABLE = 4,
618/** Disable auto storage of some control settings. */
619 HPI_MIXER_STORE_DISABLE = 5,
620/** Save the attributes of a single control. */
621 HPI_MIXER_STORE_SAVE_SINGLE = 6
622};
623
624/************************************* CONTROL ATTRIBUTE VALUES ****/
625/** Used by mixer plugin enable functions
626
627E.g. HPI_ParametricEQ_SetState()
628\ingroup mixer
629*/
630enum HPI_SWITCH_STATES {
631 HPI_SWITCH_OFF = 0, /**< turn the mixer plugin on. */
632 HPI_SWITCH_ON = 1 /**< turn the mixer plugin off. */
633};
634
635/* Volume control special gain values */
636/** volumes units are 100ths of a dB
637\ingroup volume
638*/
639#define HPI_UNITS_PER_dB 100
640/** turns volume control OFF or MUTE
641\ingroup volume
642*/
643#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB)
644
645/** value returned for no signal
646\ingroup meter
647*/
648#define HPI_METER_MINIMUM (-150 * HPI_UNITS_PER_dB)
649
650/** autofade profiles
651\ingroup volume
652*/
653enum HPI_VOLUME_AUTOFADES {
654/** log fade - dB attenuation changes linearly over time */
655 HPI_VOLUME_AUTOFADE_LOG = 2,
656/** linear fade - amplitude changes linearly */
657 HPI_VOLUME_AUTOFADE_LINEAR = 3
658};
659
660/** The physical encoding format of the AESEBU I/O.
661
662Used in HPI_AESEBU_Transmitter_SetFormat(), HPI_AESEBU_Receiver_SetFormat()
663along with related Get and Query functions
664\ingroup aestx
665*/
666enum HPI_AESEBU_FORMATS {
667/** AES/EBU physical format - AES/EBU balanced "professional" */
668 HPI_AESEBU_FORMAT_AESEBU = 1,
669/** AES/EBU physical format - S/PDIF unbalanced "consumer" */
670 HPI_AESEBU_FORMAT_SPDIF = 2
671};
672
673/** AES/EBU error status bits
674
675Returned by HPI_AESEBU_Receiver_GetErrorStatus()
676\ingroup aesrx
677*/
678enum HPI_AESEBU_ERRORS {
679/** bit0: 1 when PLL is not locked */
680 HPI_AESEBU_ERROR_NOT_LOCKED = 0x01,
681/** bit1: 1 when signal quality is poor */
682 HPI_AESEBU_ERROR_POOR_QUALITY = 0x02,
683/** bit2: 1 when there is a parity error */
684 HPI_AESEBU_ERROR_PARITY_ERROR = 0x04,
685/** bit3: 1 when there is a bi-phase coding violation */
686 HPI_AESEBU_ERROR_BIPHASE_VIOLATION = 0x08,
687/** bit4: 1 when the validity bit is high */
688 HPI_AESEBU_ERROR_VALIDITY = 0x10,
689/** bit5: 1 when the CRC error bit is high */
690 HPI_AESEBU_ERROR_CRC = 0x20
691};
692
693/** \addtogroup pad
694\{
695*/
696/** The text string containing the station/channel combination. */
697#define HPI_PAD_CHANNEL_NAME_LEN 16
698/** The text string containing the artist. */
699#define HPI_PAD_ARTIST_LEN 64
700/** The text string containing the title. */
701#define HPI_PAD_TITLE_LEN 64
702/** The text string containing the comment. */
703#define HPI_PAD_COMMENT_LEN 256
704/** The PTY when the tuner has not recieved any PTY. */
705#define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff
706/** \} */
707
708/** Data types for PTY string translation.
709\ingroup rds
710*/
711enum eHPI_RDS_type {
712 HPI_RDS_DATATYPE_RDS = 0, /**< RDS bitstream.*/
713 HPI_RDS_DATATYPE_RBDS = 1 /**< RBDS bitstream.*/
714};
715
716/** Tuner bands
717
718Used for HPI_Tuner_SetBand(),HPI_Tuner_GetBand()
719\ingroup tuner
720*/
721enum HPI_TUNER_BAND {
722 HPI_TUNER_BAND_AM = 1, /**< AM band */
723 HPI_TUNER_BAND_FM = 2, /**< FM band (mono) */
724 HPI_TUNER_BAND_TV_NTSC_M = 3, /**< NTSC-M TV band*/
725 HPI_TUNER_BAND_TV = 3, /* use TV_NTSC_M */
726 HPI_TUNER_BAND_FM_STEREO = 4, /**< FM band (stereo) */
727 HPI_TUNER_BAND_AUX = 5, /**< auxiliary input */
728 HPI_TUNER_BAND_TV_PAL_BG = 6, /**< PAL-B/G TV band*/
729 HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/
730 HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/
731 HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/
732 HPI_TUNER_BAND_LAST = 9 /**< the index of the last tuner band. */
733};
734
735/** Tuner mode attributes
736
737Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
738\ingroup tuner
739
740*/
741enum HPI_TUNER_MODES {
742 HPI_TUNER_MODE_RSS = 1, /**< control RSS */
743 HPI_TUNER_MODE_RDS = 2 /**< control RBDS/RDS */
744};
745
746/** Tuner mode attribute values
747
748Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
749\ingroup tuner
750*/
751enum HPI_TUNER_MODE_VALUES {
752/* RSS attribute values */
753 HPI_TUNER_MODE_RSS_DISABLE = 0, /**< RSS disable */
754 HPI_TUNER_MODE_RSS_ENABLE = 1, /**< RSS enable */
755
756/* RDS mode attributes */
757 HPI_TUNER_MODE_RDS_DISABLE = 0, /**< RDS - disabled */
758 HPI_TUNER_MODE_RDS_RDS = 1, /**< RDS - RDS mode */
759 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */
760};
761
762/** Tuner Level settings
763\ingroup tuner
764*/
765enum HPI_TUNER_LEVEL {
766 HPI_TUNER_LEVEL_AVERAGE = 0,
767 HPI_TUNER_LEVEL_RAW = 1
768};
769
770/** Tuner Status Bits
771
772These bitfield values are returned by a call to HPI_Tuner_GetStatus().
773Multiple fields are returned from a single call.
774\ingroup tuner
775*/
776enum HPI_TUNER_STATUS_BITS {
777 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */
778 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */
779 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */
780 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */
781 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */
782 HPI_TUNER_FM_STEREO = 0x2000, /**< tuner reports back FM stereo. */
783 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */
784 HPI_TUNER_MULTIPROGRAM = 0x0400 /**< tuner reports multiple programs. */
785};
786
787/** Channel Modes
788Used for HPI_ChannelModeSet/Get()
789\ingroup channelmode
790*/
791enum HPI_CHANNEL_MODES {
792/** Left channel out = left channel in, Right channel out = right channel in. */
793 HPI_CHANNEL_MODE_NORMAL = 1,
794/** Left channel out = right channel in, Right channel out = left channel in. */
795 HPI_CHANNEL_MODE_SWAP = 2,
796/** Left channel out = left channel in, Right channel out = left channel in. */
797 HPI_CHANNEL_MODE_LEFT_TO_STEREO = 3,
798/** Left channel out = right channel in, Right channel out = right channel in.*/
799 HPI_CHANNEL_MODE_RIGHT_TO_STEREO = 4,
800/** Left channel out = (left channel in + right channel in)/2,
801 Right channel out = mute. */
802 HPI_CHANNEL_MODE_STEREO_TO_LEFT = 5,
803/** Left channel out = mute,
804 Right channel out = (right channel in + left channel in)/2. */
805 HPI_CHANNEL_MODE_STEREO_TO_RIGHT = 6,
806 HPI_CHANNEL_MODE_LAST = 6
807};
808
809/** SampleClock source values
810\ingroup sampleclock
811*/
812enum HPI_SAMPLECLOCK_SOURCES {
813/** The sampleclock output is derived from its local samplerate generator.
814 The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */
815 HPI_SAMPLECLOCK_SOURCE_LOCAL = 1,
816/** \deprecated Use HPI_SAMPLECLOCK_SOURCE_LOCAL instead */
817 HPI_SAMPLECLOCK_SOURCE_ADAPTER = 1,
818/** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/
819 HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2,
820/** From external wordclock connector */
821 HPI_SAMPLECLOCK_SOURCE_WORD = 3,
822/** Board-to-board header */
823 HPI_SAMPLECLOCK_SOURCE_WORD_HEADER = 4,
824/** FUTURE - SMPTE clock. */
825 HPI_SAMPLECLOCK_SOURCE_SMPTE = 5,
826/** One of the aesebu inputs */
827 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6,
828/** \deprecated The first aesebu input with a valid signal
829Superseded by separate Auto enable flag
830*/
831 HPI_SAMPLECLOCK_SOURCE_AESEBU_AUTO = 7,
832/** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */
833 HPI_SAMPLECLOCK_SOURCE_NETWORK = 8,
834/** From previous adjacent module (ASI2416 only)*/
835 HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10,
836/*! Update this if you add a new clock source.*/
837 HPI_SAMPLECLOCK_SOURCE_LAST = 10
838};
839
840/** Equalizer filter types. Used by HPI_ParametricEQ_SetBand()
841\ingroup parmeq
842*/
843enum HPI_FILTER_TYPE {
844 HPI_FILTER_TYPE_BYPASS = 0, /**< filter is turned off */
845
846 HPI_FILTER_TYPE_LOWSHELF = 1, /**< EQ low shelf */
847 HPI_FILTER_TYPE_HIGHSHELF = 2, /**< EQ high shelf */
848 HPI_FILTER_TYPE_EQ_BAND = 3, /**< EQ gain */
849
850 HPI_FILTER_TYPE_LOWPASS = 4, /**< standard low pass */
851 HPI_FILTER_TYPE_HIGHPASS = 5, /**< standard high pass */
852 HPI_FILTER_TYPE_BANDPASS = 6, /**< standard band pass */
853 HPI_FILTER_TYPE_BANDSTOP = 7 /**< standard band stop/notch */
854};
855
856/** Async Event sources
857\ingroup async
858*/
859enum ASYNC_EVENT_SOURCES {
860 HPI_ASYNC_EVENT_GPIO = 1, /**< GPIO event. */
861 HPI_ASYNC_EVENT_SILENCE = 2, /**< silence event detected. */
862 HPI_ASYNC_EVENT_TONE = 3 /**< tone event detected. */
863};
864/*******************************************/
865/** HPI Error codes
866
867Almost all HPI functions return an error code
868A return value of zero means there was no error.
869Otherwise one of these error codes is returned.
870Error codes can be converted to a descriptive string using HPI_GetErrorText()
871
872\note When a new error code is added HPI_GetErrorText() MUST be updated.
873\note Codes 1-100 are reserved for driver use
874\ingroup utility
875*/
876enum HPI_ERROR_CODES {
877 /** Message type does not exist. */
878 HPI_ERROR_INVALID_TYPE = 100,
879 /** Object type does not exist. */
880 HPI_ERROR_INVALID_OBJ = 101,
881 /** Function does not exist. */
882 HPI_ERROR_INVALID_FUNC = 102,
883 /** The specified object (adapter/Stream) does not exist. */
884 HPI_ERROR_INVALID_OBJ_INDEX = 103,
885 /** Trying to access an object that has not been opened yet. */
886 HPI_ERROR_OBJ_NOT_OPEN = 104,
887 /** Trying to open an already open object. */
888 HPI_ERROR_OBJ_ALREADY_OPEN = 105,
889 /** PCI, ISA resource not valid. */
890 HPI_ERROR_INVALID_RESOURCE = 106,
891 /** GetInfo call from SubSysFindAdapters failed. */
892 HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO = 107,
893 /** Default response was never updated with actual error code. */
894 HPI_ERROR_INVALID_RESPONSE = 108,
895 /** wSize field of response was not updated,
896 indicating that the message was not processed. */
897 HPI_ERROR_PROCESSING_MESSAGE = 109,
898 /** The network did not respond in a timely manner. */
899 HPI_ERROR_NETWORK_TIMEOUT = 110,
900 /** An HPI handle is invalid (uninitialised?). */
901 HPI_ERROR_INVALID_HANDLE = 111,
902 /** A function or attribute has not been implemented yet. */
903 HPI_ERROR_UNIMPLEMENTED = 112,
904 /** There are too many clients attempting to access a network resource. */
905 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113,
906 /** Response buffer passed to HPI_Message was smaller than returned response */
907 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114,
908 /** The returned response did not match the sent message */
909 HPI_ERROR_RESPONSE_MISMATCH = 115,
910
911 /** Too many adapters.*/
912 HPI_ERROR_TOO_MANY_ADAPTERS = 200,
913 /** Bad adpater. */
914 HPI_ERROR_BAD_ADAPTER = 201,
915 /** Adapter number out of range or not set properly. */
916 HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
917 /** 2 adapters with the same adapter number. */
918 HPI_DUPLICATE_ADAPTER_NUMBER = 203,
919 /** DSP code failed to bootload. */
920 HPI_ERROR_DSP_BOOTLOAD = 204,
921 /** Adapter failed DSP code self test. */
922 HPI_ERROR_DSP_SELFTEST = 205,
923 /** Couldn't find or open the DSP code file. */
924 HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
925 /** Internal DSP hardware error. */
926 HPI_ERROR_DSP_HARDWARE = 207,
927 /** Could not allocate memory in DOS. */
928 HPI_ERROR_DOS_MEMORY_ALLOC = 208,
929 /** Could not allocate memory */
930 HPI_ERROR_MEMORY_ALLOC = 208,
931 /** Failed to correctly load/config PLD .*/
932 HPI_ERROR_PLD_LOAD = 209,
933 /** Unexpected end of file, block length too big etc. */
934 HPI_ERROR_DSP_FILE_FORMAT = 210,
935
936 /** Found but could not open DSP code file. */
937 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211,
938 /** First DSP code section header not found in DSP file. */
939 HPI_ERROR_DSP_FILE_NO_HEADER = 212,
940 /** File read operation on DSP code file failed. */
941 HPI_ERROR_DSP_FILE_READ_ERROR = 213,
942 /** DSP code for adapter family not found. */
943 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214,
944 /** Other OS specific error opening DSP file. */
945 HPI_ERROR_DSP_FILE_OTHER_ERROR = 215,
946 /** Sharing violation opening DSP code file. */
947 HPI_ERROR_DSP_FILE_SHARING_VIOLATION = 216,
948 /** DSP code section header had size == 0. */
949 HPI_ERROR_DSP_FILE_NULL_HEADER = 217,
950
951 /** Base number for flash errors. */
952 HPI_ERROR_FLASH = 220,
953
954 /** Flash has bad checksum */
955 HPI_ERROR_BAD_CHECKSUM = (HPI_ERROR_FLASH + 1),
956 HPI_ERROR_BAD_SEQUENCE = (HPI_ERROR_FLASH + 2),
957 HPI_ERROR_FLASH_ERASE = (HPI_ERROR_FLASH + 3),
958 HPI_ERROR_FLASH_PROGRAM = (HPI_ERROR_FLASH + 4),
959 HPI_ERROR_FLASH_VERIFY = (HPI_ERROR_FLASH + 5),
960 HPI_ERROR_FLASH_TYPE = (HPI_ERROR_FLASH + 6),
961 HPI_ERROR_FLASH_START = (HPI_ERROR_FLASH + 7),
962
963 /** Reserved for OEMs. */
964 HPI_ERROR_RESERVED_1 = 290,
965
966 /** Stream does not exist. */
967 HPI_ERROR_INVALID_STREAM = 300,
968 /** Invalid compression format. */
969 HPI_ERROR_INVALID_FORMAT = 301,
970 /** Invalid format samplerate */
971 HPI_ERROR_INVALID_SAMPLERATE = 302,
972 /** Invalid format number of channels. */
973 HPI_ERROR_INVALID_CHANNELS = 303,
974 /** Invalid format bitrate. */
975 HPI_ERROR_INVALID_BITRATE = 304,
976 /** Invalid datasize used for stream read/write. */
977 HPI_ERROR_INVALID_DATASIZE = 305,
978 /** Stream buffer is full during stream write. */
979 HPI_ERROR_BUFFER_FULL = 306,
980 /** Stream buffer is empty during stream read. */
981 HPI_ERROR_BUFFER_EMPTY = 307,
982 /** Invalid datasize used for stream read/write. */
983 HPI_ERROR_INVALID_DATA_TRANSFER = 308,
984 /** Packet ordering error for stream read/write. */
985 HPI_ERROR_INVALID_PACKET_ORDER = 309,
986
987 /** Object can't do requested operation in its current
988 state, eg set format, change rec mux state while recording.*/
989 HPI_ERROR_INVALID_OPERATION = 310,
990
991 /** Where an SRG is shared amongst streams, an incompatible samplerate is one
992 that is different to any currently playing or recording stream. */
993 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311,
994 /** Adapter mode is illegal.*/
995 HPI_ERROR_BAD_ADAPTER_MODE = 312,
996
997 /** There have been too many attempts to set the adapter's
998 capabilities (using bad keys), the card should be returned
999 to ASI if further capabilities updates are required */
1000 HPI_ERROR_TOO_MANY_CAPABILITY_CHANGE_ATTEMPTS = 313,
1001 /** Streams on different adapters cannot be grouped. */
1002 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314,
1003 /** Streams on different DSPs cannot be grouped. */
1004 HPI_ERROR_NO_INTERDSP_GROUPS = 315,
1005
1006 /** Invalid mixer node for this adapter. */
1007 HPI_ERROR_INVALID_NODE = 400,
1008 /** Invalid control. */
1009 HPI_ERROR_INVALID_CONTROL = 401,
1010 /** Invalid control value was passed. */
1011 HPI_ERROR_INVALID_CONTROL_VALUE = 402,
1012 /** Control attribute not supported by this control. */
1013 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE = 403,
1014 /** Control is disabled. */
1015 HPI_ERROR_CONTROL_DISABLED = 404,
1016 /** I2C transaction failed due to a missing ACK. */
1017 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
1018 /** Control attribute is valid, but not supported by this hardware. */
1019 HPI_ERROR_UNSUPPORTED_CONTROL_ATTRIBUTE = 406,
1020 /** Control is busy, or coming out of
1021 reset and cannot be accessed at this time. */
1022 HPI_ERROR_CONTROL_NOT_READY = 407,
1023
1024 /** Non volatile memory */
1025 HPI_ERROR_NVMEM_BUSY = 450,
1026 HPI_ERROR_NVMEM_FULL = 451,
1027 HPI_ERROR_NVMEM_FAIL = 452,
1028
1029 /** I2C */
1030 HPI_ERROR_I2C_MISSING_ACK = HPI_ERROR_CONTROL_I2C_MISSING_ACK,
1031 HPI_ERROR_I2C_BAD_ADR = 460,
1032
1033 /** Entity errors */
1034 HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
1035 HPI_ERROR_ENTITY_ITEM_COUNT = 471,
1036 HPI_ERROR_ENTITY_TYPE_INVALID = 472,
1037 HPI_ERROR_ENTITY_ROLE_INVALID = 473,
1038
1039 /* AES18 specific errors were 500..507 */
1040
1041 /** custom error to use for debugging */
1042 HPI_ERROR_CUSTOM = 600,
1043
1044 /** hpioct32.c can't obtain mutex */
1045 HPI_ERROR_MUTEX_TIMEOUT = 700,
1046
1047 /** errors from HPI backends have values >= this */
1048 HPI_ERROR_BACKEND_BASE = 900,
1049
1050 /** indicates a cached u16 value is invalid. */
1051 HPI_ERROR_ILLEGAL_CACHE_VALUE = 0xffff
1052};
1053
1054/** \defgroup maximums HPI maximum values
1055\{
1056*/
1057/** Maximum number of adapters per HPI sub-system
1058 WARNING: modifying this value changes the response structure size.*/
1059#define HPI_MAX_ADAPTERS 20
1060/** Maximum number of in or out streams per adapter */
1061#define HPI_MAX_STREAMS 16
1062#define HPI_MAX_CHANNELS 2 /* per stream */
1063#define HPI_MAX_NODES 8 /* per mixer ? */
1064#define HPI_MAX_CONTROLS 4 /* per node ? */
1065/** maximum number of ancillary bytes per MPEG frame */
1066#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
1067#define HPI_STRING_LEN 16
1068
1069/** Velocity units */
1070#define HPI_OSTREAM_VELOCITY_UNITS 4096
1071/** OutStream timescale units */
1072#define HPI_OSTREAM_TIMESCALE_UNITS 10000
1073/** OutStream timescale passthrough - turns timescaling on in passthough mode */
1074#define HPI_OSTREAM_TIMESCALE_PASSTHROUGH 99999
1075
1076/**\}*/
1077
1078/* ////////////////////////////////////////////////////////////////////// */
1079/* STRUCTURES */
1080#ifndef DISABLE_PRAGMA_PACK1
1081#pragma pack(push, 1)
1082#endif
1083
1084/** Structure containing sample format information.
1085 See also HPI_FormatCreate().
1086 */
1087struct hpi_format {
1088 u32 sample_rate;
1089 /**< 11025, 32000, 44100 ... */
1090 u32 bit_rate; /**< for MPEG */
1091 u32 attributes;
1092 /**< Stereo/JointStereo/Mono */
1093 u16 mode_legacy;
1094 /**< Legacy ancillary mode or idle bit */
1095 u16 unused; /**< unused */
1096 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
1097 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
1098};
1099
1100struct hpi_anc_frame {
1101 u32 valid_bits_in_this_frame;
1102 u8 b_data[HPI_MAX_ANC_BYTES_PER_FRAME];
1103};
1104
1105/** An object for containing a single async event.
1106*/
1107struct hpi_async_event {
1108 u16 event_type; /**< type of event. \sa async_event */
1109 u16 sequence; /**< sequence number, allows lost event detection */
1110 u32 state; /**< new state */
1111 u32 h_object; /**< handle to the object returning the event. */
1112 union {
1113 struct {
1114 u16 index; /**< GPIO bit index. */
1115 } gpio;
1116 struct {
1117 u16 node_index; /**< what node is the control on ? */
1118 u16 node_type; /**< what type of node is the control on ? */
1119 } control;
1120 } u;
1121};
1122
1123/*/////////////////////////////////////////////////////////////////////////// */
1124/* Public HPI Entity related definitions */
1125
1126struct hpi_entity;
1127
1128enum e_entity_type {
1129 entity_type_null,
1130 entity_type_sequence, /* sequence of potentially heterogeneous TLV entities */
1131
1132 entity_type_reference, /* refers to a TLV entity or NULL */
1133
1134 entity_type_int, /* 32 bit */
1135 entity_type_float, /* ieee754 binary 32 bit encoding */
1136 entity_type_double,
1137
1138 entity_type_cstring,
1139 entity_type_octet,
1140 entity_type_ip4_address,
1141 entity_type_ip6_address,
1142 entity_type_mac_address,
1143
1144 LAST_ENTITY_TYPE
1145};
1146
1147enum e_entity_role {
1148 entity_role_null,
1149 entity_role_value,
1150 entity_role_classname,
1151
1152 entity_role_units,
1153 entity_role_flags,
1154 entity_role_range,
1155
1156 entity_role_mapping,
1157 entity_role_enum,
1158
1159 entity_role_instance_of,
1160 entity_role_depends_on,
1161 entity_role_member_of_group,
1162 entity_role_value_constraint,
1163 entity_role_parameter_port,
1164
1165 entity_role_block,
1166 entity_role_node_group,
1167 entity_role_audio_port,
1168 entity_role_clock_port,
1169 LAST_ENTITY_ROLE
1170};
1171
1172/* skip host side function declarations for
1173 DSP compile and documentation extraction */
1174
1175struct hpi_hsubsys {
1176 int not_really_used;
1177};
1178
1179#ifndef DISABLE_PRAGMA_PACK1
1180#pragma pack(pop)
1181#endif
1182
1183/*////////////////////////////////////////////////////////////////////////// */
1184/* HPI FUNCTIONS */
1185
1186/*/////////////////////////// */
1187/* DATA and FORMAT and STREAM */
1188
1189u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF,
1190 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size);
1191
1192/*/////////// */
1193/* SUB SYSTEM */
1194struct hpi_hsubsys *hpi_subsys_create(void
1195 );
1196
1197void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys);
1198
1199u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys,
1200 u32 *pversion);
1201
1202u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
1203 u32 *pversion_ex);
1204
1205u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
1206 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1207
1208u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
1209 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1210
1211u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
1212 int *pn_num_adapters);
1213
1214u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
1215 u32 *padapter_index, u16 *pw_adapter_type);
1216
1217u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass);
1218
1219u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
1220 const char *sz_interface);
1221
1222/*///////// */
1223/* ADAPTER */
1224
1225u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index);
1226
1227u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index);
1228
1229u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
1230 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
1231 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type);
1232
1233u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
1234 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
1235 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
1236 u16 *pw_module_type, u32 *ph_module);
1237
1238u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys,
1239 u16 adapter_index, u32 adapter_mode);
1240
1241u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
1242 u16 adapter_index, u32 adapter_mode, u16 query_or_set);
1243
1244u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
1245 u16 adapter_index, u32 *padapter_mode);
1246
1247u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
1248 u16 adapter_index, u16 *assert_present, char *psz_assert,
1249 u16 *pw_line_number);
1250
1251u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
1252 u16 adapter_index, u16 *assert_present, char *psz_assert,
1253 u32 *pline_number, u16 *pw_assert_on_dsp);
1254
1255u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
1256 u16 adapter_index, u16 assert_id);
1257
1258u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
1259 u16 adapter_index, u16 capability, u32 key);
1260
1261u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
1262 u16 adapter_index);
1263
1264u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
1265 u16 adapter_index, u32 dsp_address, char *p_bytes, int *count_bytes);
1266
1267u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
1268 u16 adapter_index, u16 property, u16 paramter1, u16 paramter2);
1269
1270u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
1271 u16 adapter_index, u16 property, u16 *pw_paramter1,
1272 u16 *pw_paramter2);
1273
1274u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
1275 u16 adapter_index, u16 index, u16 what_to_enumerate,
1276 u16 property_index, u32 *psetting);
1277
1278/*////////////// */
1279/* NonVol Memory */
1280u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1281 u32 *ph_nv_memory, u16 *pw_size_in_bytes);
1282
1283u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
1284 u32 h_nv_memory, u16 index, u16 *pw_data);
1285
1286u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
1287 u32 h_nv_memory, u16 index, u16 data);
1288
1289/*////////////// */
1290/* Digital I/O */
1291u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1292 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits);
1293
1294u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1295 u16 bit_index, u16 *pw_bit_data);
1296
1297u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1298 u16 aw_all_bit_data[4]
1299 );
1300
1301u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1302 u16 bit_index, u16 bit_data);
1303
1304u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1305 u16 aw_all_bit_data[4]
1306 );
1307
1308/**********************/
1309/* Async Event Object */
1310/**********************/
1311u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
1312 u16 adapter_index, u32 *ph_async);
1313
1314u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async);
1315
1316u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
1317 u16 maximum_events, struct hpi_async_event *p_events,
1318 u16 *pw_number_returned);
1319
1320u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
1321 u32 h_async, u16 *pw_count);
1322
1323u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
1324 u16 maximum_events, struct hpi_async_event *p_events,
1325 u16 *pw_number_returned);
1326
1327/*/////////// */
1328/* WATCH-DOG */
1329u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1330 u32 *ph_watchdog);
1331
1332u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
1333 u32 time_millisec);
1334
1335u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog);
1336
1337/**************/
1338/* OUT STREAM */
1339/**************/
1340u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1341 u16 outstream_index, u32 *ph_outstream);
1342
1343u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1344
1345u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1346 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play,
1347 u32 *psamples_played, u32 *pauxiliary_data_to_play);
1348
1349u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
1350 u32 h_outstream, const u8 *pb_write_buf, u32 bytes_to_write,
1351 const struct hpi_format *p_format);
1352
1353u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1354
1355u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys,
1356 u32 h_outstream);
1357
1358u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1359
1360u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys,
1361 u32 h_outstream);
1362
1363u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1364
1365u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
1366 u32 h_outstream, struct hpi_format *p_format);
1367
1368u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
1369 u32 h_outstream, struct hpi_format *p_format);
1370
1371u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
1372 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample);
1373
1374u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
1375 u32 h_outstream, short velocity);
1376
1377u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1378 u32 h_outstream, u16 mode);
1379
1380u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1381 u32 h_outstream, u32 *pframes_available);
1382
1383u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
1384 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer,
1385 u32 anc_frame_buffer_size_in_bytes,
1386 u32 number_of_ancillary_frames_to_read);
1387
1388u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
1389 u32 h_outstream, u32 time_scaleX10000);
1390
1391u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1392 u32 h_outstream, u32 size_in_bytes);
1393
1394u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1395 u32 h_outstream);
1396
1397u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1398 u32 h_outstream, u32 h_stream);
1399
1400u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1401 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map);
1402
1403u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys,
1404 u32 h_outstream);
1405
1406/*////////// */
1407/* IN_STREAM */
1408u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1409 u16 instream_index, u32 *ph_instream);
1410
1411u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1412
1413u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1414 u32 h_instream, const struct hpi_format *p_format);
1415
1416u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1417 u32 h_instream, const struct hpi_format *p_format);
1418
1419u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1420 u8 *pb_read_buf, u32 bytes_to_read);
1421
1422u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1423
1424u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys,
1425 u32 h_instream);
1426
1427u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1428
1429u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1430
1431u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1432 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded,
1433 u32 *psamples_recorded, u32 *pauxiliary_data_recorded);
1434
1435u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1436 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment,
1437 u16 idle_bit);
1438
1439u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1440 u32 h_instream, u32 *pframe_space);
1441
1442u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1443 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer,
1444 u32 anc_frame_buffer_size_in_bytes,
1445 u32 number_of_ancillary_frames_to_write);
1446
1447u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1448 u32 h_instream, u32 size_in_bytes);
1449
1450u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1451 u32 h_instream);
1452
1453u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1454 u32 h_instream, u32 h_stream);
1455
1456u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1457 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map);
1458
1459u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys,
1460 u32 h_instream);
1461
1462/*********/
1463/* MIXER */
1464/*********/
1465u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1466 u32 *ph_mixer);
1467
1468u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer);
1469
1470u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1471 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type,
1472 u16 dst_node_type_index, u16 control_type, u32 *ph_control);
1473
1474u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1475 u32 h_mixer, u16 control_index, u16 *pw_src_node_type,
1476 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index,
1477 u16 *pw_control_type, u32 *ph_control);
1478
1479u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1480 enum HPI_MIXER_STORE_COMMAND command, u16 index);
1481/*************************/
1482/* mixer CONTROLS */
1483/*************************/
1484/*************************/
1485/* volume control */
1486/*************************/
1487u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1488 short an_gain0_01dB[HPI_MAX_CHANNELS]
1489 );
1490
1491u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1492 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1493 );
1494
1495#define hpi_volume_get_range hpi_volume_query_range
1496u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1497 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB);
1498
1499u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
1500 const u32 h_volume, u32 *p_channels);
1501
1502u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1503 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
1504
1505u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
1506 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS],
1507 u32 duration_ms, u16 profile);
1508
1509/*************************/
1510/* level control */
1511/*************************/
1512u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1513 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB);
1514
1515u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1516 short an_gain0_01dB[HPI_MAX_CHANNELS]
1517 );
1518
1519u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1520 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1521 );
1522
1523/*************************/
1524/* meter control */
1525/*************************/
1526u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
1527 const u32 h_meter, u32 *p_channels);
1528
1529u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1530 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1531 );
1532
1533u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1534 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1535 );
1536
1537u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
1538 u32 h_control, u16 attack, u16 decay);
1539
1540u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
1541 u32 h_control, u16 attack, u16 decay);
1542
1543u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
1544 u32 h_control, u16 *attack, u16 *decay);
1545
1546u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
1547 u32 h_control, u16 *attack, u16 *decay);
1548
1549/*************************/
1550/* channel mode control */
1551/*************************/
1552u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys,
1553 const u32 h_mode, const u32 index, u16 *pw_mode);
1554
1555u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1556 u16 mode);
1557
1558u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1559 u16 *mode);
1560
1561/*************************/
1562/* Tuner control */
1563/*************************/
1564u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
1565 const u32 h_tuner, const u32 index, u16 *pw_band);
1566
1567u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1568 u16 band);
1569
1570u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1571 u16 *pw_band);
1572
1573u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys,
1574 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq);
1575
1576u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys,
1577 u32 h_control, u32 freq_ink_hz);
1578
1579u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys,
1580 u32 h_control, u32 *pw_freq_ink_hz);
1581
1582u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1583 short *pw_level);
1584
1585u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
1586 u32 h_control, short *pw_level);
1587
1588u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys,
1589 const u32 h_tuner, const u32 index, u16 *pw_gain);
1590
1591u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1592 short gain);
1593
1594u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1595 short *pn_gain);
1596
1597u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1598 u16 *pw_status_mask, u16 *pw_status);
1599
1600u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1601 u32 mode, u32 value);
1602
1603u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1604 u32 mode, u32 *pn_value);
1605
1606u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1607 char *p_rds_data);
1608
1609u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys,
1610 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis);
1611
1612u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys,
1613 u32 h_control, u32 deemphasis);
1614u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
1615 u32 h_control, u32 *pdeemphasis);
1616
1617u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys,
1618 const u32 h_tuner, u32 *pbitmap_program);
1619
1620u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1621 u32 program);
1622
1623u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1624 u32 *pprogram);
1625
1626u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
1627 u32 h_control, char *psz_dsp_version, const u32 string_size);
1628
1629u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
1630 u32 h_control, char *psz_sdk_version, const u32 string_size);
1631
1632u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
1633 u32 h_control, u32 *pquality);
1634
1635/****************************/
1636/* PADs control */
1637/****************************/
1638
1639u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
1640 u32 h_control, char *psz_string, const u32 string_length);
1641
1642u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1643 char *psz_string, const u32 string_length);
1644
1645u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1646 char *psz_string, const u32 string_length);
1647
1648u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1649 char *psz_string, const u32 string_length);
1650
1651u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
1652 u32 h_control, u32 *ppTY);
1653
1654u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1655 u32 *ppI);
1656
1657u16 HPI_PAD__get_program_type_string(const struct hpi_hsubsys *ph_subsys,
1658 u32 h_control, const u32 data_type, const u32 pTY, char *psz_string,
1659 const u32 string_length);
1660
1661/****************************/
1662/* AES/EBU Receiver control */
1663/****************************/
1664u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys,
1665 const u32 h_aes_rx, const u32 index, u16 *pw_format);
1666
1667u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys,
1668 u32 h_control, u16 source);
1669
1670u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys,
1671 u32 h_control, u16 *pw_source);
1672
1673u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1674 u32 h_control, u32 *psample_rate);
1675
1676u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1677 u32 h_control, u16 index, u16 *pw_data);
1678
1679u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1680 *ph_subsys, u32 h_control, u16 index, u16 *pw_data);
1681
1682u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys,
1683 u32 h_control, u16 *pw_error_data);
1684
1685/*******************************/
1686/* AES/EBU Transmitter control */
1687/*******************************/
1688u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys
1689 *ph_subsys, u32 h_control, u32 sample_rate);
1690
1691u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys,
1692 u32 h_control, u16 index, u16 data);
1693
1694u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys
1695 *ph_subsys, u32 h_control, u16 index, u16 data);
1696
1697u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys
1698 *ph_subsys, u32 h_control, u16 index, u16 *pw_data);
1699
1700u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys,
1701 const u32 h_aes_tx, const u32 index, u16 *pw_format);
1702
1703u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys,
1704 u32 h_control, u16 output_format);
1705
1706u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys,
1707 u32 h_control, u16 *pw_output_format);
1708
1709/***********************/
1710/* multiplexer control */
1711/***********************/
1712u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys,
1713 u32 h_control, u16 source_node_type, u16 source_node_index);
1714
1715u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
1716 u32 h_control, u16 *source_node_type, u16 *source_node_index);
1717
1718u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
1719 u32 h_control, u16 index, u16 *source_node_type,
1720 u16 *source_node_index);
1721
1722/***************/
1723/* VOX control */
1724/***************/
1725u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1726 short an_gain0_01dB);
1727
1728u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1729 short *an_gain0_01dB);
1730
1731/*********************/
1732/* Bitstream control */
1733/*********************/
1734u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys,
1735 u32 h_control, u16 edge_type);
1736
1737u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys,
1738 u32 h_control, u16 polarity);
1739
1740u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1741 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity);
1742
1743/***********************/
1744/* SampleClock control */
1745/***********************/
1746
1747u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys,
1748 const u32 h_clock, const u32 index, u16 *pw_source);
1749
1750u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys,
1751 u32 h_control, u16 source);
1752
1753u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys,
1754 u32 h_control, u16 *pw_source);
1755
1756u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys,
1757 const u32 h_clock, const u32 index, const u32 source,
1758 u16 *pw_source_index);
1759
1760u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys,
1761 u32 h_control, u16 source_index);
1762
1763u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys,
1764 u32 h_control, u16 *pw_source_index);
1765
1766u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1767 u32 h_control, u32 *psample_rate);
1768
1769u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys,
1770 const u32 h_clock, const u32 index, u32 *psource);
1771
1772u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys,
1773 u32 h_control, u32 sample_rate);
1774
1775u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys,
1776 u32 h_control, u32 *psample_rate);
1777
1778u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys,
1779 u32 h_control, u32 enable);
1780
1781u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys,
1782 u32 h_control, u32 *penable);
1783
1784u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
1785 u32 h_control, u32 lock);
1786
1787u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
1788 u32 h_control, u32 *plock);
1789
1790/***********************/
1791/* Microphone control */
1792/***********************/
1793u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys,
1794 u32 h_control, u16 on_off);
1795
1796u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys,
1797 u32 h_control, u16 *pw_on_off);
1798
1799/*******************************
1800 Parametric Equalizer control
1801*******************************/
1802u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
1803 u32 h_control, u16 *pw_number_of_bands, u16 *pw_enabled);
1804
1805u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys,
1806 u32 h_control, u16 on_off);
1807
1808u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
1809 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100,
1810 short gain0_01dB);
1811
1812u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
1813 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz,
1814 short *pnQ100, short *pn_gain0_01dB);
1815
1816u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
1817 u32 h_control, u16 index, short coeffs[5]
1818 );
1819
1820/*******************************
1821 Compressor Expander control
1822*******************************/
1823
1824u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1825 u16 attack, u16 decay, short ratio100, short threshold0_01dB,
1826 short makeup_gain0_01dB);
1827
1828u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1829 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
1830 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB);
1831
1832/*******************************
1833 Cobranet HMI control
1834*******************************/
1835u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1836 u32 hmi_address, u32 byte_count, u8 *pb_data);
1837
1838u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1839 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data);
1840
1841u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1842 u32 h_control, u32 *pstatus, u32 *preadable_size,
1843 u32 *pwriteable_size);
1844
1845/*Read the current IP address
1846*/
1847u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
1848 u32 h_control, u32 *pi_paddress);
1849
1850/* Write the current IP address
1851*/
1852u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
1853 u32 h_control, u32 i_paddress);
1854
1855/* Read the static IP address
1856*/
1857u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1858 u32 h_control, u32 *pi_paddress);
1859
1860/* Write the static IP address
1861*/
1862u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1863 u32 h_control, u32 i_paddress);
1864
1865/* Read the MAC address
1866*/
1867u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
1868 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs);
1869
1870/*******************************
1871 Tone Detector control
1872*******************************/
1873u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, u32 hC,
1874 u32 *state);
1875
1876u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, u32 hC,
1877 u32 enable);
1878
1879u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, u32 hC,
1880 u32 *enable);
1881
1882u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
1883 u32 hC, u32 event_enable);
1884
1885u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
1886 u32 hC, u32 *event_enable);
1887
1888u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
1889 u32 hC, int threshold);
1890
1891u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
1892 u32 hC, int *threshold);
1893
1894u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
1895 u32 hC, u32 index, u32 *frequency);
1896
1897/*******************************
1898 Silence Detector control
1899*******************************/
1900u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
1901 u32 hC, u32 *state);
1902
1903u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
1904 u32 hC, u32 enable);
1905
1906u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
1907 u32 hC, u32 *enable);
1908
1909u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
1910 u32 hC, u32 event_enable);
1911
1912u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
1913 u32 hC, u32 *event_enable);
1914
1915u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
1916 u32 hC, u32 delay);
1917
1918u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
1919 u32 hC, u32 *delay);
1920
1921u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
1922 u32 hC, int threshold);
1923
1924u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
1925 u32 hC, int *threshold);
1926
1927/*******************************
1928 Universal control
1929*******************************/
1930u16 hpi_entity_find_next(struct hpi_entity *container_entity,
1931 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
1932 struct hpi_entity **current_match);
1933
1934u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
1935 enum e_entity_type type, size_t item_count, void *value_dst_p);
1936
1937u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
1938 size_t *items, enum e_entity_role *role, void **value);
1939
1940u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
1941 const size_t item_count, const enum e_entity_role role, void *value,
1942 struct hpi_entity **entity);
1943
1944void hpi_entity_free(struct hpi_entity *entity);
1945
1946u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
1947 struct hpi_entity **info);
1948
1949u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
1950 struct hpi_entity **value);
1951
1952u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
1953 struct hpi_entity *value);
1954
1955/*/////////// */
1956/* DSP CLOCK */
1957/*/////////// */
1958u16 hpi_clock_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1959 u32 *ph_dsp_clock);
1960
1961u16 hpi_clock_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock,
1962 u16 hour, u16 minute, u16 second, u16 milli_second);
1963
1964u16 hpi_clock_get_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock,
1965 u16 *pw_hour, u16 *pw_minute, u16 *pw_second, u16 *pw_milli_second);
1966
1967/*/////////// */
1968/* PROFILE */
1969/*/////////// */
1970u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
1971 u16 adapter_index, u16 profile_index, u32 *ph_profile,
1972 u16 *pw_max_profiles);
1973
1974u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
1975 u16 index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
1976 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds);
1977
1978u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile);
1979
1980u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile);
1981
1982u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
1983 u16 index, char *sz_profile_name, u16 profile_name_length);
1984
1985u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
1986 u32 h_profile, u32 *putilization);
1987
1988/*//////////////////// */
1989/* UTILITY functions */
1990
1991u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
1992 u32 sample_rate, u32 bit_rate, u32 attributes);
1993
1994/* Until it's verified, this function is for Windows OSs only */
1995
1996#endif /*_H_HPI_ */
1997/*
1998///////////////////////////////////////////////////////////////////////////////
1999// See CVS for history. Last complete set in rev 1.146
2000////////////////////////////////////////////////////////////////////////////////
2001*/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
new file mode 100644
index 000000000000..839ecb2e4b64
--- /dev/null
+++ b/sound/pci/asihpi/hpi6000.c
@@ -0,0 +1,1840 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience ASI6200 series adapters.
20 These PCI bus adapters are based on the TI C6711 DSP.
21
22 Exported functions:
23 void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
24
25 #defines
26 HIDE_PCI_ASSERTS to show the PCI asserts
27 PROFILE_DSP2 get profile data from DSP2 if present (instead of DSP 1)
28
29(C) Copyright AudioScience Inc. 1998-2003
30*******************************************************************************/
31#define SOURCEFILE_NAME "hpi6000.c"
32
33#include "hpi_internal.h"
34#include "hpimsginit.h"
35#include "hpidebug.h"
36#include "hpi6000.h"
37#include "hpidspcd.h"
38#include "hpicmn.h"
39
40#define HPI_HIF_BASE (0x00000200) /* start of C67xx internal RAM */
41#define HPI_HIF_ADDR(member) \
42 (HPI_HIF_BASE + offsetof(struct hpi_hif_6000, member))
43#define HPI_HIF_ERROR_MASK 0x4000
44
45/* HPI6000 specific error codes */
46
47#define HPI6000_ERROR_BASE 900
48#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
49#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902
50#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
51#define HPI6000_ERROR_MSG_GET_ADR 904
52#define HPI6000_ERROR_RESP_GET_ADR 905
53#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
54#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
55#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908
56#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
57
58#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
59#define HPI6000_ERROR_SEND_DATA_ACK 912
60#define HPI6000_ERROR_SEND_DATA_ADR 913
61#define HPI6000_ERROR_SEND_DATA_TIMEOUT 914
62#define HPI6000_ERROR_SEND_DATA_CMD 915
63#define HPI6000_ERROR_SEND_DATA_WRITE 916
64#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
65#define HPI6000_ERROR_SEND_DATA_VERIFY 918
66
67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68#define HPI6000_ERROR_GET_DATA_ACK 922
69#define HPI6000_ERROR_GET_DATA_CMD 923
70#define HPI6000_ERROR_GET_DATA_READ 924
71#define HPI6000_ERROR_GET_DATA_IDLECMD 925
72
73#define HPI6000_ERROR_CONTROL_CACHE_ADDRLEN 951
74#define HPI6000_ERROR_CONTROL_CACHE_READ 952
75#define HPI6000_ERROR_CONTROL_CACHE_FLUSH 953
76
77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
80
81/* adapter init errors */
82#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
83
84/* can't access PCI2040 */
85#define HPI6000_ERROR_INIT_PCI2040 931
86/* can't access DSP HPI i/f */
87#define HPI6000_ERROR_INIT_DSPHPI 932
88/* can't access internal DSP memory */
89#define HPI6000_ERROR_INIT_DSPINTMEM 933
90/* can't access SDRAM - test#1 */
91#define HPI6000_ERROR_INIT_SDRAM1 934
92/* can't access SDRAM - test#2 */
93#define HPI6000_ERROR_INIT_SDRAM2 935
94
95#define HPI6000_ERROR_INIT_VERIFY 938
96
97#define HPI6000_ERROR_INIT_NOACK 939
98
99#define HPI6000_ERROR_INIT_PLDTEST1 941
100#define HPI6000_ERROR_INIT_PLDTEST2 942
101
102/* local defines */
103
104#define HIDE_PCI_ASSERTS
105#define PROFILE_DSP2
106
107/* for PCI2040 i/f chip */
108/* HPI CSR registers */
109/* word offsets from CSR base */
110/* use when io addresses defined as u32 * */
111
112#define INTERRUPT_EVENT_SET 0
113#define INTERRUPT_EVENT_CLEAR 1
114#define INTERRUPT_MASK_SET 2
115#define INTERRUPT_MASK_CLEAR 3
116#define HPI_ERROR_REPORT 4
117#define HPI_RESET 5
118#define HPI_DATA_WIDTH 6
119
120#define MAX_DSPS 2
121/* HPI registers, spaced 8K bytes = 2K words apart */
122#define DSP_SPACING 0x800
123
124#define CONTROL 0x0000
125#define ADDRESS 0x0200
126#define DATA_AUTOINC 0x0400
127#define DATA 0x0600
128
129#define TIMEOUT 500000
130
131struct dsp_obj {
132 __iomem u32 *prHPI_control;
133 __iomem u32 *prHPI_address;
134 __iomem u32 *prHPI_data;
135 __iomem u32 *prHPI_data_auto_inc;
136 char c_dsp_rev; /*A, B */
137 u32 control_cache_address_on_dsp;
138 u32 control_cache_length_on_dsp;
139 struct hpi_adapter_obj *pa_parent_adapter;
140};
141
142struct hpi_hw_obj {
143 __iomem u32 *dw2040_HPICSR;
144 __iomem u32 *dw2040_HPIDSP;
145
146 u16 num_dsp;
147 struct dsp_obj ado[MAX_DSPS];
148
149 u32 message_buffer_address_on_dsp;
150 u32 response_buffer_address_on_dsp;
151 u32 pCI2040HPI_error_count;
152
153 struct hpi_control_cache_single control_cache[HPI_NMIXER_CONTROLS];
154 struct hpi_control_cache *p_cache;
155};
156
157static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
158 u16 dsp_index, u32 hpi_address, u32 *source, u32 count);
159static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
160 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count);
161
162static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
165 u16 read_or_write);
166#define H6READ 1
167#define H6WRITE 0
168
169static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
170 struct hpi_message *phm);
171static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
172 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr);
173
174static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
175 struct hpi_response *phr);
176
177static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
178 u32 ack_value);
179
180static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
181 u16 dsp_index, u32 host_cmd);
182
183static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo);
184
185static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
186 struct hpi_message *phm, struct hpi_response *phr);
187
188static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
189 struct hpi_message *phm, struct hpi_response *phr);
190
191static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data);
192
193static u32 hpi_read_word(struct dsp_obj *pdo, u32 address);
194
195static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
196 u32 length);
197
198static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
199 u32 length);
200
201static void subsys_create_adapter(struct hpi_message *phm,
202 struct hpi_response *phr);
203
204static void subsys_delete_adapter(struct hpi_message *phm,
205 struct hpi_response *phr);
206
207static void adapter_get_asserts(struct hpi_adapter_obj *pao,
208 struct hpi_message *phm, struct hpi_response *phr);
209
210static short create_adapter_obj(struct hpi_adapter_obj *pao,
211 u32 *pos_error_code);
212
213/* local globals */
214
215static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
216static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
217
218static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
219{
220
221 switch (phm->function) {
222 case HPI_SUBSYS_OPEN:
223 case HPI_SUBSYS_CLOSE:
224 case HPI_SUBSYS_GET_INFO:
225 case HPI_SUBSYS_DRIVER_UNLOAD:
226 case HPI_SUBSYS_DRIVER_LOAD:
227 case HPI_SUBSYS_FIND_ADAPTERS:
228 /* messages that should not get here */
229 phr->error = HPI_ERROR_UNIMPLEMENTED;
230 break;
231 case HPI_SUBSYS_CREATE_ADAPTER:
232 subsys_create_adapter(phm, phr);
233 break;
234 case HPI_SUBSYS_DELETE_ADAPTER:
235 subsys_delete_adapter(phm, phr);
236 break;
237 default:
238 phr->error = HPI_ERROR_INVALID_FUNC;
239 break;
240 }
241}
242
243static void control_message(struct hpi_adapter_obj *pao,
244 struct hpi_message *phm, struct hpi_response *phr)
245{
246
247 switch (phm->function) {
248 case HPI_CONTROL_GET_STATE:
249 if (pao->has_control_cache) {
250 u16 err;
251 err = hpi6000_update_control_cache(pao, phm);
252
253 if (err) {
254 phr->error = err;
255 break;
256 }
257
258 if (hpi_check_control_cache(((struct hpi_hw_obj *)
259 pao->priv)->p_cache, phm,
260 phr))
261 break;
262 }
263 hw_message(pao, phm, phr);
264 break;
265 case HPI_CONTROL_GET_INFO:
266 hw_message(pao, phm, phr);
267 break;
268 case HPI_CONTROL_SET_STATE:
269 hw_message(pao, phm, phr);
270 hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)->
271 p_cache, phm, phr);
272 break;
273 default:
274 phr->error = HPI_ERROR_INVALID_FUNC;
275 break;
276 }
277}
278
279static void adapter_message(struct hpi_adapter_obj *pao,
280 struct hpi_message *phm, struct hpi_response *phr)
281{
282 switch (phm->function) {
283 case HPI_ADAPTER_GET_INFO:
284 hw_message(pao, phm, phr);
285 break;
286 case HPI_ADAPTER_GET_ASSERT:
287 adapter_get_asserts(pao, phm, phr);
288 break;
289 case HPI_ADAPTER_OPEN:
290 case HPI_ADAPTER_CLOSE:
291 case HPI_ADAPTER_TEST_ASSERT:
292 case HPI_ADAPTER_SELFTEST:
293 case HPI_ADAPTER_GET_MODE:
294 case HPI_ADAPTER_SET_MODE:
295 case HPI_ADAPTER_FIND_OBJECT:
296 case HPI_ADAPTER_GET_PROPERTY:
297 case HPI_ADAPTER_SET_PROPERTY:
298 case HPI_ADAPTER_ENUM_PROPERTY:
299 hw_message(pao, phm, phr);
300 break;
301 default:
302 phr->error = HPI_ERROR_INVALID_FUNC;
303 break;
304 }
305}
306
307static void outstream_message(struct hpi_adapter_obj *pao,
308 struct hpi_message *phm, struct hpi_response *phr)
309{
310 switch (phm->function) {
311 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
312 case HPI_OSTREAM_HOSTBUFFER_FREE:
313 /* Don't let these messages go to the HW function because
314 * they're called without allocating the spinlock.
315 * For the HPI6000 adapters the HW would return
316 * HPI_ERROR_INVALID_FUNC anyway.
317 */
318 phr->error = HPI_ERROR_INVALID_FUNC;
319 break;
320 default:
321 hw_message(pao, phm, phr);
322 return;
323 }
324}
325
326static void instream_message(struct hpi_adapter_obj *pao,
327 struct hpi_message *phm, struct hpi_response *phr)
328{
329
330 switch (phm->function) {
331 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
332 case HPI_ISTREAM_HOSTBUFFER_FREE:
333 /* Don't let these messages go to the HW function because
334 * they're called without allocating the spinlock.
335 * For the HPI6000 adapters the HW would return
336 * HPI_ERROR_INVALID_FUNC anyway.
337 */
338 phr->error = HPI_ERROR_INVALID_FUNC;
339 break;
340 default:
341 hw_message(pao, phm, phr);
342 return;
343 }
344}
345
346/************************************************************************/
347/** HPI_6000()
348 * Entry point from HPIMAN
349 * All calls to the HPI start here
350 */
351void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
352{
353 struct hpi_adapter_obj *pao = NULL;
354
355 /* subsytem messages get executed by every HPI. */
356 /* All other messages are ignored unless the adapter index matches */
357 /* an adapter in the HPI */
358 HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function);
359
360 /* if Dsp has crashed then do not communicate with it any more */
361 if (phm->object != HPI_OBJ_SUBSYSTEM) {
362 pao = hpi_find_adapter(phm->adapter_index);
363 if (!pao) {
364 HPI_DEBUG_LOG(DEBUG,
365 " %d,%d refused, for another HPI?\n",
366 phm->object, phm->function);
367 return;
368 }
369
370 if (pao->dsp_crashed >= 10) {
371 hpi_init_response(phr, phm->object, phm->function,
372 HPI_ERROR_DSP_HARDWARE);
373 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n",
374 phm->object, phm->function);
375 return;
376 }
377 }
378 /* Init default response including the size field */
379 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
380 hpi_init_response(phr, phm->object, phm->function,
381 HPI_ERROR_PROCESSING_MESSAGE);
382
383 switch (phm->type) {
384 case HPI_TYPE_MESSAGE:
385 switch (phm->object) {
386 case HPI_OBJ_SUBSYSTEM:
387 subsys_message(phm, phr);
388 break;
389
390 case HPI_OBJ_ADAPTER:
391 phr->size =
392 sizeof(struct hpi_response_header) +
393 sizeof(struct hpi_adapter_res);
394 adapter_message(pao, phm, phr);
395 break;
396
397 case HPI_OBJ_CONTROL:
398 control_message(pao, phm, phr);
399 break;
400
401 case HPI_OBJ_OSTREAM:
402 outstream_message(pao, phm, phr);
403 break;
404
405 case HPI_OBJ_ISTREAM:
406 instream_message(pao, phm, phr);
407 break;
408
409 default:
410 hw_message(pao, phm, phr);
411 break;
412 }
413 break;
414
415 default:
416 phr->error = HPI_ERROR_INVALID_TYPE;
417 break;
418 }
419}
420
421/************************************************************************/
422/* SUBSYSTEM */
423
424/* create an adapter object and initialise it based on resource information
425 * passed in in the message
426 * NOTE - you cannot use this function AND the FindAdapters function at the
427 * same time, the application must use only one of them to get the adapters
428 */
429static void subsys_create_adapter(struct hpi_message *phm,
430 struct hpi_response *phr)
431{
432 /* create temp adapter obj, because we don't know what index yet */
433 struct hpi_adapter_obj ao;
434 struct hpi_adapter_obj *pao;
435 u32 os_error_code;
436 short error = 0;
437 u32 dsp_index = 0;
438
439 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
440
441 memset(&ao, 0, sizeof(ao));
442
443 /* this HPI only creates adapters for TI/PCI2040 based devices */
444 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
445 return;
446 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
447 return;
448 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040)
449 return;
450
451 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
452 if (!ao.priv) {
453 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
454 phr->error = HPI_ERROR_MEMORY_ALLOC;
455 return;
456 }
457
458 /* create the adapter object based on the resource information */
459 /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */
460 ao.pci = *phm->u.s.resource.r.pci;
461
462 error = create_adapter_obj(&ao, &os_error_code);
463 if (!error)
464 error = hpi_add_adapter(&ao);
465 if (error) {
466 phr->u.s.data = os_error_code;
467 kfree(ao.priv);
468 phr->error = error;
469 return;
470 }
471 /* need to update paParentAdapter */
472 pao = hpi_find_adapter(ao.index);
473 if (!pao) {
474 /* We just added this adapter, why can't we find it!? */
475 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
476 phr->error = 950;
477 return;
478 }
479
480 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
481 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
482 phw->ado[dsp_index].pa_parent_adapter = pao;
483 }
484
485 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
486 phr->u.s.adapter_index = ao.index;
487 phr->u.s.num_adapters++;
488 phr->error = 0;
489}
490
491static void subsys_delete_adapter(struct hpi_message *phm,
492 struct hpi_response *phr)
493{
494 struct hpi_adapter_obj *pao = NULL;
495 struct hpi_hw_obj *phw;
496
497 pao = hpi_find_adapter(phm->adapter_index);
498 if (!pao)
499 return;
500
501 phw = (struct hpi_hw_obj *)pao->priv;
502
503 if (pao->has_control_cache)
504 hpi_free_control_cache(phw->p_cache);
505
506 hpi_delete_adapter(pao);
507 kfree(phw);
508
509 phr->error = 0;
510}
511
512/* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */
513static short create_adapter_obj(struct hpi_adapter_obj *pao,
514 u32 *pos_error_code)
515{
516 short boot_error = 0;
517 u32 dsp_index = 0;
518 u32 control_cache_size = 0;
519 u32 control_cache_count = 0;
520 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
521
522 /* init error reporting */
523 pao->dsp_crashed = 0;
524
525 /* The PCI2040 has the following address map */
526 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
527 /* BAR1 - 32K = HPI registers on DSP */
528 phw->dw2040_HPICSR = pao->pci.ap_mem_base[0];
529 phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1];
530 HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR,
531 phw->dw2040_HPIDSP);
532
533 /* set addresses for the possible DSP HPI interfaces */
534 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
535 phw->ado[dsp_index].prHPI_control =
536 phw->dw2040_HPIDSP + (CONTROL +
537 DSP_SPACING * dsp_index);
538
539 phw->ado[dsp_index].prHPI_address =
540 phw->dw2040_HPIDSP + (ADDRESS +
541 DSP_SPACING * dsp_index);
542 phw->ado[dsp_index].prHPI_data =
543 phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index);
544
545 phw->ado[dsp_index].prHPI_data_auto_inc =
546 phw->dw2040_HPIDSP + (DATA_AUTOINC +
547 DSP_SPACING * dsp_index);
548
549 HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n",
550 phw->ado[dsp_index].prHPI_control,
551 phw->ado[dsp_index].prHPI_address,
552 phw->ado[dsp_index].prHPI_data,
553 phw->ado[dsp_index].prHPI_data_auto_inc);
554
555 phw->ado[dsp_index].pa_parent_adapter = pao;
556 }
557
558 phw->pCI2040HPI_error_count = 0;
559 pao->has_control_cache = 0;
560
561 /* Set the default number of DSPs on this card */
562 /* This is (conditionally) adjusted after bootloading */
563 /* of the first DSP in the bootload section. */
564 phw->num_dsp = 1;
565
566 boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code);
567 if (boot_error)
568 return boot_error;
569
570 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
571
572 phw->message_buffer_address_on_dsp = 0L;
573 phw->response_buffer_address_on_dsp = 0L;
574
575 /* get info about the adapter by asking the adapter */
576 /* send a HPI_ADAPTER_GET_INFO message */
577 {
578 struct hpi_message hM;
579 struct hpi_response hR0; /* response from DSP 0 */
580 struct hpi_response hR1; /* response from DSP 1 */
581 u16 error = 0;
582
583 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
584 memset(&hM, 0, sizeof(hM));
585 hM.type = HPI_TYPE_MESSAGE;
586 hM.size = sizeof(struct hpi_message);
587 hM.object = HPI_OBJ_ADAPTER;
588 hM.function = HPI_ADAPTER_GET_INFO;
589 hM.adapter_index = 0;
590 memset(&hR0, 0, sizeof(hR0));
591 memset(&hR1, 0, sizeof(hR1));
592 hR0.size = sizeof(hR0);
593 hR1.size = sizeof(hR1);
594
595 error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0);
596 if (hR0.error) {
597 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error);
598 return hR0.error;
599 }
600 if (phw->num_dsp == 2) {
601 error = hpi6000_message_response_sequence(pao, 1, &hM,
602 &hR1);
603 if (error)
604 return error;
605 }
606 pao->adapter_type = hR0.u.a.adapter_type;
607 pao->index = hR0.u.a.adapter_index;
608 }
609
610 memset(&phw->control_cache[0], 0,
611 sizeof(struct hpi_control_cache_single) *
612 HPI_NMIXER_CONTROLS);
613 /* Read the control cache length to figure out if it is turned on */
614 control_cache_size =
615 hpi_read_word(&phw->ado[0],
616 HPI_HIF_ADDR(control_cache_size_in_bytes));
617 if (control_cache_size) {
618 control_cache_count =
619 hpi_read_word(&phw->ado[0],
620 HPI_HIF_ADDR(control_cache_count));
621 pao->has_control_cache = 1;
622
623 phw->p_cache =
624 hpi_alloc_control_cache(control_cache_count,
625 control_cache_size, (struct hpi_control_cache_info *)
626 &phw->control_cache[0]
627 );
628 } else
629 pao->has_control_cache = 0;
630
631 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
632 pao->adapter_type, pao->index);
633 pao->open = 0; /* upon creation the adapter is closed */
634 return 0;
635}
636
637/************************************************************************/
638/* ADAPTER */
639
640static void adapter_get_asserts(struct hpi_adapter_obj *pao,
641 struct hpi_message *phm, struct hpi_response *phr)
642{
643#ifndef HIDE_PCI_ASSERTS
644 /* if we have PCI2040 asserts then collect them */
645 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
646 phr->u.a.serial_number =
647 gw_pci_read_asserts * 100 + gw_pci_write_asserts;
648 phr->u.a.adapter_index = 1; /* assert count */
649 phr->u.a.adapter_type = -1; /* "dsp index" */
650 strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error");
651 gw_pci_read_asserts = 0;
652 gw_pci_write_asserts = 0;
653 phr->error = 0;
654 } else
655#endif
656 hw_message(pao, phm, phr); /*get DSP asserts */
657
658 return;
659}
660
661/************************************************************************/
662/* LOW-LEVEL */
663
664static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
665 u32 *pos_error_code)
666{
667 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
668 short error;
669 u32 timeout;
670 u32 read = 0;
671 u32 i = 0;
672 u32 data = 0;
673 u32 j = 0;
674 u32 test_addr = 0x80000000;
675 u32 test_data = 0x00000001;
676 u32 dw2040_reset = 0;
677 u32 dsp_index = 0;
678 u32 endian = 0;
679 u32 adapter_info = 0;
680 u32 delay = 0;
681
682 struct dsp_code dsp_code;
683 u16 boot_load_family = 0;
684
685 /* NOTE don't use wAdapterType in this routine. It is not setup yet */
686
687 switch (pao->pci.subsys_device_id) {
688 case 0x5100:
689 case 0x5110: /* ASI5100 revB or higher with C6711D */
690 case 0x6100:
691 case 0x6200:
692 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
693 break;
694 case 0x8800:
695 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x8800);
696 break;
697 default:
698 return HPI6000_ERROR_UNHANDLED_SUBSYS_ID;
699 }
700
701 /* reset all DSPs, indicate two DSPs are present
702 * set RST3-=1 to disconnect HAD8 to set DSP in little endian mode
703 */
704 endian = 0;
705 dw2040_reset = 0x0003000F;
706 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
707
708 /* read back register to make sure PCI2040 chip is functioning
709 * note that bits 4..15 are read-only and so should always return zero,
710 * even though we wrote 1 to them
711 */
712 for (i = 0; i < 1000; i++)
713 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
714 if (delay != dw2040_reset) {
715 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
716 delay);
717 return HPI6000_ERROR_INIT_PCI2040;
718 }
719
720 /* Indicate that DSP#0,1 is a C6X */
721 iowrite32(0x00000003, phw->dw2040_HPICSR + HPI_DATA_WIDTH);
722 /* set Bit30 and 29 - which will prevent Target aborts from being
723 * issued upon HPI or GP error
724 */
725 iowrite32(0x60000000, phw->dw2040_HPICSR + INTERRUPT_MASK_SET);
726
727 /* isolate DSP HAD8 line from PCI2040 so that
728 * Little endian can be set by pullup
729 */
730 dw2040_reset = dw2040_reset & (~(endian << 3));
731 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
732
733 phw->ado[0].c_dsp_rev = 'B'; /* revB */
734 phw->ado[1].c_dsp_rev = 'B'; /* revB */
735
736 /*Take both DSPs out of reset, setting HAD8 to the correct Endian */
737 dw2040_reset = dw2040_reset & (~0x00000001); /* start DSP 0 */
738 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
739 dw2040_reset = dw2040_reset & (~0x00000002); /* start DSP 1 */
740 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
741
742 /* set HAD8 back to PCI2040, now that DSP set to little endian mode */
743 dw2040_reset = dw2040_reset & (~0x00000008);
744 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
745 /*delay to allow DSP to get going */
746 for (i = 0; i < 100; i++)
747 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
748
749 /* loop through all DSPs, downloading DSP code */
750 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
751 struct dsp_obj *pdo = &phw->ado[dsp_index];
752
753 /* configure DSP so that we download code into the SRAM */
754 /* set control reg for little endian, HWOB=1 */
755 iowrite32(0x00010001, pdo->prHPI_control);
756
757 /* test access to the HPI address register (HPIA) */
758 test_data = 0x00000001;
759 for (j = 0; j < 32; j++) {
760 iowrite32(test_data, pdo->prHPI_address);
761 data = ioread32(pdo->prHPI_address);
762 if (data != test_data) {
763 HPI_DEBUG_LOG(ERROR, "INIT_DSPHPI %x %x %x\n",
764 test_data, data, dsp_index);
765 return HPI6000_ERROR_INIT_DSPHPI;
766 }
767 test_data = test_data << 1;
768 }
769
770/* if C6713 the setup PLL to generate 225MHz from 25MHz.
771* Since the PLLDIV1 read is sometimes wrong, even on a C6713,
772* we're going to do this unconditionally
773*/
774/* PLLDIV1 should have a value of 8000 after reset */
775/*
776 if (HpiReadWord(pdo,0x01B7C118) == 0x8000)
777*/
778 {
779 /* C6713 datasheet says we cannot program PLL from HPI,
780 * and indeed if we try to set the PLL multiply from the
781 * HPI, the PLL does not seem to lock,
782 * so we enable the PLL and use the default of x 7
783 */
784 /* bypass PLL */
785 hpi_write_word(pdo, 0x01B7C100, 0x0000);
786 for (i = 0; i < 100; i++)
787 delay = ioread32(phw->dw2040_HPICSR +
788 HPI_RESET);
789
790 /* ** use default of PLL x7 ** */
791 /* EMIF = 225/3=75MHz */
792 hpi_write_word(pdo, 0x01B7C120, 0x8002);
793 /* peri = 225/2 */
794 hpi_write_word(pdo, 0x01B7C11C, 0x8001);
795 /* cpu = 225/1 */
796 hpi_write_word(pdo, 0x01B7C118, 0x8000);
797 /* ~200us delay */
798 for (i = 0; i < 2000; i++)
799 delay = ioread32(phw->dw2040_HPICSR +
800 HPI_RESET);
801 /* PLL not bypassed */
802 hpi_write_word(pdo, 0x01B7C100, 0x0001);
803 /* ~200us delay */
804 for (i = 0; i < 2000; i++)
805 delay = ioread32(phw->dw2040_HPICSR +
806 HPI_RESET);
807 }
808
809 /* test r/w to internal DSP memory
810 * C6711 has L2 cache mapped to 0x0 when reset
811 *
812 * revB - because of bug 3.0.1 last HPI read
813 * (before HPI address issued) must be non-autoinc
814 */
815 /* test each bit in the 32bit word */
816 for (i = 0; i < 100; i++) {
817 test_addr = 0x00000000;
818 test_data = 0x00000001;
819 for (j = 0; j < 32; j++) {
820 hpi_write_word(pdo, test_addr + i, test_data);
821 data = hpi_read_word(pdo, test_addr + i);
822 if (data != test_data) {
823 HPI_DEBUG_LOG(ERROR,
824 "DSP mem %x %x %x %x\n",
825 test_addr + i, test_data,
826 data, dsp_index);
827
828 return HPI6000_ERROR_INIT_DSPINTMEM;
829 }
830 test_data = test_data << 1;
831 }
832 }
833
834 /* memory map of ASI6200
835 00000000-0000FFFF 16Kx32 internal program
836 01800000-019FFFFF Internal peripheral
837 80000000-807FFFFF CE0 2Mx32 SDRAM running @ 100MHz
838 90000000-9000FFFF CE1 Async peripherals:
839
840 EMIF config
841 ------------
842 Global EMIF control
843 0 -
844 1 -
845 2 -
846 3 CLK2EN = 1 CLKOUT2 enabled
847 4 CLK1EN = 0 CLKOUT1 disabled
848 5 EKEN = 1 <--!! C6713 specific, enables ECLKOUT
849 6 -
850 7 NOHOLD = 1 external HOLD disabled
851 8 HOLDA = 0 HOLDA output is low
852 9 HOLD = 0 HOLD input is low
853 10 ARDY = 1 ARDY input is high
854 11 BUSREQ = 0 BUSREQ output is low
855 12,13 Reserved = 1
856 */
857 hpi_write_word(pdo, 0x01800000, 0x34A8);
858
859 /* EMIF CE0 setup - 2Mx32 Sync DRAM
860 31..28 Wr setup
861 27..22 Wr strobe
862 21..20 Wr hold
863 19..16 Rd setup
864 15..14 -
865 13..8 Rd strobe
866 7..4 MTYPE 0011 Sync DRAM 32bits
867 3 Wr hold MSB
868 2..0 Rd hold
869 */
870 hpi_write_word(pdo, 0x01800008, 0x00000030);
871
872 /* EMIF SDRAM Extension
873 31-21 0
874 20 WR2RD = 0
875 19-18 WR2DEAC = 1
876 17 WR2WR = 0
877 16-15 R2WDQM = 2
878 14-12 RD2WR = 4
879 11-10 RD2DEAC = 1
880 9 RD2RD = 1
881 8-7 THZP = 10b
882 6-5 TWR = 2-1 = 01b (tWR = 10ns)
883 4 TRRD = 0b = 2 ECLK (tRRD = 14ns)
884 3-1 TRAS = 5-1 = 100b (Tras=42ns = 5 ECLK)
885 1 CAS latency = 3 ECLK
886 (for Micron 2M32-7 operating at 100Mhz)
887 */
888
889 /* need to use this else DSP code crashes */
890 hpi_write_word(pdo, 0x01800020, 0x001BDF29);
891
892 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
893 31 - -
894 30 SDBSZ 1 4 bank
895 29..28 SDRSZ 00 11 row address pins
896 27..26 SDCSZ 01 8 column address pins
897 25 RFEN 1 refersh enabled
898 24 INIT 1 init SDRAM
899 23..20 TRCD 0001
900 19..16 TRP 0001
901 15..12 TRC 0110
902 11..0 - -
903 */
904 /* need to use this else DSP code crashes */
905 hpi_write_word(pdo, 0x01800018, 0x47117000);
906
907 /* EMIF SDRAM Refresh Timing */
908 hpi_write_word(pdo, 0x0180001C, 0x00000410);
909
910 /*MIF CE1 setup - Async peripherals
911 @100MHz bus speed, each cycle is 10ns,
912 31..28 Wr setup = 1
913 27..22 Wr strobe = 3 30ns
914 21..20 Wr hold = 1
915 19..16 Rd setup =1
916 15..14 Ta = 2
917 13..8 Rd strobe = 3 30ns
918 7..4 MTYPE 0010 Async 32bits
919 3 Wr hold MSB =0
920 2..0 Rd hold = 1
921 */
922 {
923 u32 cE1 =
924 (1L << 28) | (3L << 22) | (1L << 20) | (1L <<
925 16) | (2L << 14) | (3L << 8) | (2L << 4) | 1L;
926 hpi_write_word(pdo, 0x01800004, cE1);
927 }
928
929 /* delay a little to allow SDRAM and DSP to "get going" */
930
931 for (i = 0; i < 1000; i++)
932 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
933
934 /* test access to SDRAM */
935 {
936 test_addr = 0x80000000;
937 test_data = 0x00000001;
938 /* test each bit in the 32bit word */
939 for (j = 0; j < 32; j++) {
940 hpi_write_word(pdo, test_addr, test_data);
941 data = hpi_read_word(pdo, test_addr);
942 if (data != test_data) {
943 HPI_DEBUG_LOG(ERROR,
944 "DSP dram %x %x %x %x\n",
945 test_addr, test_data, data,
946 dsp_index);
947
948 return HPI6000_ERROR_INIT_SDRAM1;
949 }
950 test_data = test_data << 1;
951 }
952 /* test every Nth address in the DRAM */
953#define DRAM_SIZE_WORDS 0x200000 /*2_mx32 */
954#define DRAM_INC 1024
955 test_addr = 0x80000000;
956 test_data = 0x0;
957 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
958 hpi_write_word(pdo, test_addr + i, test_data);
959 test_data++;
960 }
961 test_addr = 0x80000000;
962 test_data = 0x0;
963 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
964 data = hpi_read_word(pdo, test_addr + i);
965 if (data != test_data) {
966 HPI_DEBUG_LOG(ERROR,
967 "DSP dram %x %x %x %x\n",
968 test_addr + i, test_data,
969 data, dsp_index);
970 return HPI6000_ERROR_INIT_SDRAM2;
971 }
972 test_data++;
973 }
974
975 }
976
977 /* write the DSP code down into the DSPs memory */
978 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
979 dsp_code.ps_dev = pao->pci.p_os_data;
980
981 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
982 pos_error_code);
983
984 if (error)
985 return error;
986
987 while (1) {
988 u32 length;
989 u32 address;
990 u32 type;
991 u32 *pcode;
992
993 error = hpi_dsp_code_read_word(&dsp_code, &length);
994 if (error)
995 break;
996 if (length == 0xFFFFFFFF)
997 break; /* end of code */
998
999 error = hpi_dsp_code_read_word(&dsp_code, &address);
1000 if (error)
1001 break;
1002 error = hpi_dsp_code_read_word(&dsp_code, &type);
1003 if (error)
1004 break;
1005 error = hpi_dsp_code_read_block(length, &dsp_code,
1006 &pcode);
1007 if (error)
1008 break;
1009 error = hpi6000_dsp_block_write32(pao, (u16)dsp_index,
1010 address, pcode, length);
1011 if (error)
1012 break;
1013 }
1014
1015 if (error) {
1016 hpi_dsp_code_close(&dsp_code);
1017 return error;
1018 }
1019 /* verify that code was written correctly */
1020 /* this time through, assume no errors in DSP code file/array */
1021 hpi_dsp_code_rewind(&dsp_code);
1022 while (1) {
1023 u32 length;
1024 u32 address;
1025 u32 type;
1026 u32 *pcode;
1027
1028 hpi_dsp_code_read_word(&dsp_code, &length);
1029 if (length == 0xFFFFFFFF)
1030 break; /* end of code */
1031
1032 hpi_dsp_code_read_word(&dsp_code, &address);
1033 hpi_dsp_code_read_word(&dsp_code, &type);
1034 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1035
1036 for (i = 0; i < length; i++) {
1037 data = hpi_read_word(pdo, address);
1038 if (data != *pcode) {
1039 error = HPI6000_ERROR_INIT_VERIFY;
1040 HPI_DEBUG_LOG(ERROR,
1041 "DSP verify %x %x %x %x\n",
1042 address, *pcode, data,
1043 dsp_index);
1044 break;
1045 }
1046 pcode++;
1047 address += 4;
1048 }
1049 if (error)
1050 break;
1051 }
1052 hpi_dsp_code_close(&dsp_code);
1053 if (error)
1054 return error;
1055
1056 /* zero out the hostmailbox */
1057 {
1058 u32 address = HPI_HIF_ADDR(host_cmd);
1059 for (i = 0; i < 4; i++) {
1060 hpi_write_word(pdo, address, 0);
1061 address += 4;
1062 }
1063 }
1064 /* write the DSP number into the hostmailbox */
1065 /* structure before starting the DSP */
1066 hpi_write_word(pdo, HPI_HIF_ADDR(dsp_number), dsp_index);
1067
1068 /* write the DSP adapter Info into the */
1069 /* hostmailbox before starting the DSP */
1070 if (dsp_index > 0)
1071 hpi_write_word(pdo, HPI_HIF_ADDR(adapter_info),
1072 adapter_info);
1073
1074 /* step 3. Start code by sending interrupt */
1075 iowrite32(0x00030003, pdo->prHPI_control);
1076 for (i = 0; i < 10000; i++)
1077 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
1078
1079 /* wait for a non-zero value in hostcmd -
1080 * indicating initialization is complete
1081 *
1082 * Init could take a while if DSP checks SDRAM memory
1083 * Was 200000. Increased to 2000000 for ASI8801 so we
1084 * don't get 938 errors.
1085 */
1086 timeout = 2000000;
1087 while (timeout) {
1088 do {
1089 read = hpi_read_word(pdo,
1090 HPI_HIF_ADDR(host_cmd));
1091 } while (--timeout
1092 && hpi6000_check_PCI2040_error_flag(pao,
1093 H6READ));
1094
1095 if (read)
1096 break;
1097 /* The following is a workaround for bug #94:
1098 * Bluescreen on install and subsequent boots on a
1099 * DELL PowerEdge 600SC PC with 1.8GHz P4 and
1100 * ServerWorks chipset. Without this delay the system
1101 * locks up with a bluescreen (NOT GPF or pagefault).
1102 */
1103 else
1104 hpios_delay_micro_seconds(1000);
1105 }
1106 if (timeout == 0)
1107 return HPI6000_ERROR_INIT_NOACK;
1108
1109 /* read the DSP adapter Info from the */
1110 /* hostmailbox structure after starting the DSP */
1111 if (dsp_index == 0) {
1112 /*u32 dwTestData=0; */
1113 u32 mask = 0;
1114
1115 adapter_info =
1116 hpi_read_word(pdo,
1117 HPI_HIF_ADDR(adapter_info));
1118 if (HPI_ADAPTER_FAMILY_ASI
1119 (HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER
1120 (adapter_info)) ==
1121 HPI_ADAPTER_FAMILY_ASI(0x6200))
1122 /* all 6200 cards have this many DSPs */
1123 phw->num_dsp = 2;
1124
1125 /* test that the PLD is programmed */
1126 /* and we can read/write 24bits */
1127#define PLD_BASE_ADDRESS 0x90000000L /*for ASI6100/6200/8800 */
1128
1129 switch (boot_load_family) {
1130 case HPI_ADAPTER_FAMILY_ASI(0x6200):
1131 /* ASI6100/6200 has 24bit path to FPGA */
1132 mask = 0xFFFFFF00L;
1133 /* ASI5100 uses AX6 code, */
1134 /* but has no PLD r/w register to test */
1135 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
1136 subsys_device_id) ==
1137 HPI_ADAPTER_FAMILY_ASI(0x5100))
1138 mask = 0x00000000L;
1139 break;
1140 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1141 /* ASI8800 has 16bit path to FPGA */
1142 mask = 0xFFFF0000L;
1143 break;
1144 }
1145 test_data = 0xAAAAAA00L & mask;
1146 /* write to 24 bit Debug register (D31-D8) */
1147 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1148 read = hpi_read_word(pdo,
1149 PLD_BASE_ADDRESS + 4L) & mask;
1150 if (read != test_data) {
1151 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1152 read);
1153 return HPI6000_ERROR_INIT_PLDTEST1;
1154 }
1155 test_data = 0x55555500L & mask;
1156 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1157 read = hpi_read_word(pdo,
1158 PLD_BASE_ADDRESS + 4L) & mask;
1159 if (read != test_data) {
1160 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1161 read);
1162 return HPI6000_ERROR_INIT_PLDTEST2;
1163 }
1164 }
1165 } /* for numDSP */
1166 return 0;
1167}
1168
1169#define PCI_TIMEOUT 100
1170
1171static int hpi_set_address(struct dsp_obj *pdo, u32 address)
1172{
1173 u32 timeout = PCI_TIMEOUT;
1174
1175 do {
1176 iowrite32(address, pdo->prHPI_address);
1177 } while (hpi6000_check_PCI2040_error_flag(pdo->pa_parent_adapter,
1178 H6WRITE)
1179 && --timeout);
1180
1181 if (timeout)
1182 return 0;
1183
1184 return 1;
1185}
1186
1187/* write one word to the HPI port */
1188static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data)
1189{
1190 if (hpi_set_address(pdo, address))
1191 return;
1192 iowrite32(data, pdo->prHPI_data);
1193}
1194
1195/* read one word from the HPI port */
1196static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1197{
1198 u32 data = 0;
1199
1200 if (hpi_set_address(pdo, address))
1201 return 0; /*? no way to return error */
1202
1203 /* take care of errata in revB DSP (2.0.1) */
1204 data = ioread32(pdo->prHPI_data);
1205 return data;
1206}
1207
1208/* write a block of 32bit words to the DSP HPI port using auto-inc mode */
1209static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1210 u32 length)
1211{
1212 u16 length16 = length - 1;
1213
1214 if (length == 0)
1215 return;
1216
1217 if (hpi_set_address(pdo, address))
1218 return;
1219
1220 iowrite32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1221
1222 /* take care of errata in revB DSP (2.0.1) */
1223 /* must end with non auto-inc */
1224 iowrite32(*(pdata + length - 1), pdo->prHPI_data);
1225}
1226
1227/** read a block of 32bit words from the DSP HPI port using auto-inc mode
1228 */
1229static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1230 u32 length)
1231{
1232 u16 length16 = length - 1;
1233
1234 if (length == 0)
1235 return;
1236
1237 if (hpi_set_address(pdo, address))
1238 return;
1239
1240 ioread32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1241
1242 /* take care of errata in revB DSP (2.0.1) */
1243 /* must end with non auto-inc */
1244 *(pdata + length - 1) = ioread32(pdo->prHPI_data);
1245}
1246
1247static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
1248 u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
1249{
1250 struct dsp_obj *pdo =
1251 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1252 u32 time_out = PCI_TIMEOUT;
1253 int c6711_burst_size = 128;
1254 u32 local_hpi_address = hpi_address;
1255 int local_count = count;
1256 int xfer_size;
1257 u32 *pdata = source;
1258
1259 while (local_count) {
1260 if (local_count > c6711_burst_size)
1261 xfer_size = c6711_burst_size;
1262 else
1263 xfer_size = local_count;
1264
1265 time_out = PCI_TIMEOUT;
1266 do {
1267 hpi_write_block(pdo, local_hpi_address, pdata,
1268 xfer_size);
1269 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1270 && --time_out);
1271
1272 if (!time_out)
1273 break;
1274 pdata += xfer_size;
1275 local_hpi_address += sizeof(u32) * xfer_size;
1276 local_count -= xfer_size;
1277 }
1278
1279 if (time_out)
1280 return 0;
1281 else
1282 return 1;
1283}
1284
1285static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
1286 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
1287{
1288 struct dsp_obj *pdo =
1289 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1290 u32 time_out = PCI_TIMEOUT;
1291 int c6711_burst_size = 16;
1292 u32 local_hpi_address = hpi_address;
1293 int local_count = count;
1294 int xfer_size;
1295 u32 *pdata = dest;
1296 u32 loop_count = 0;
1297
1298 while (local_count) {
1299 if (local_count > c6711_burst_size)
1300 xfer_size = c6711_burst_size;
1301 else
1302 xfer_size = local_count;
1303
1304 time_out = PCI_TIMEOUT;
1305 do {
1306 hpi_read_block(pdo, local_hpi_address, pdata,
1307 xfer_size);
1308 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1309 && --time_out);
1310 if (!time_out)
1311 break;
1312
1313 pdata += xfer_size;
1314 local_hpi_address += sizeof(u32) * xfer_size;
1315 local_count -= xfer_size;
1316 loop_count++;
1317 }
1318
1319 if (time_out)
1320 return 0;
1321 else
1322 return 1;
1323}
1324
1325static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1326 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
1327{
1328 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1329 struct dsp_obj *pdo = &phw->ado[dsp_index];
1330 u32 timeout;
1331 u16 ack;
1332 u32 address;
1333 u32 length;
1334 u32 *p_data;
1335 u16 error = 0;
1336
1337 /* does the DSP we are referencing exist? */
1338 if (dsp_index >= phw->num_dsp)
1339 return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
1340
1341 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1342 if (ack & HPI_HIF_ERROR_MASK) {
1343 pao->dsp_crashed++;
1344 return HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT;
1345 }
1346 pao->dsp_crashed = 0;
1347
1348 /* send the message */
1349
1350 /* get the address and size */
1351 if (phw->message_buffer_address_on_dsp == 0) {
1352 timeout = TIMEOUT;
1353 do {
1354 address =
1355 hpi_read_word(pdo,
1356 HPI_HIF_ADDR(message_buffer_address));
1357 phw->message_buffer_address_on_dsp = address;
1358 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1359 && --timeout);
1360 if (!timeout)
1361 return HPI6000_ERROR_MSG_GET_ADR;
1362 } else
1363 address = phw->message_buffer_address_on_dsp;
1364
1365 /* dwLength = sizeof(struct hpi_message); */
1366 length = phm->size;
1367
1368 /* send it */
1369 p_data = (u32 *)phm;
1370 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1371 (u16)length / 4))
1372 return HPI6000_ERROR_MSG_RESP_BLOCKWRITE32;
1373
1374 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP))
1375 return HPI6000_ERROR_MSG_RESP_GETRESPCMD;
1376 hpi6000_send_dsp_interrupt(pdo);
1377
1378 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_RESP);
1379 if (ack & HPI_HIF_ERROR_MASK)
1380 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
1381
1382 /* get the address and size */
1383 if (phw->response_buffer_address_on_dsp == 0) {
1384 timeout = TIMEOUT;
1385 do {
1386 address =
1387 hpi_read_word(pdo,
1388 HPI_HIF_ADDR(response_buffer_address));
1389 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1390 && --timeout);
1391 phw->response_buffer_address_on_dsp = address;
1392
1393 if (!timeout)
1394 return HPI6000_ERROR_RESP_GET_ADR;
1395 } else
1396 address = phw->response_buffer_address_on_dsp;
1397
1398 /* read the length of the response back from the DSP */
1399 timeout = TIMEOUT;
1400 do {
1401 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1402 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1403 if (!timeout)
1404 length = sizeof(struct hpi_response);
1405
1406 /* get it */
1407 p_data = (u32 *)phr;
1408 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1409 (u16)length / 4))
1410 return HPI6000_ERROR_MSG_RESP_BLOCKREAD32;
1411
1412 /* set i/f back to idle */
1413 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1414 return HPI6000_ERROR_MSG_RESP_IDLECMD;
1415 hpi6000_send_dsp_interrupt(pdo);
1416
1417 error = hpi_validate_response(phm, phr);
1418 return error;
1419}
1420
1421/* have to set up the below defines to match stuff in the MAP file */
1422
1423#define MSG_ADDRESS (HPI_HIF_BASE+0x18)
1424#define MSG_LENGTH 11
1425#define RESP_ADDRESS (HPI_HIF_BASE+0x44)
1426#define RESP_LENGTH 16
1427#define QUEUE_START (HPI_HIF_BASE+0x88)
1428#define QUEUE_SIZE 0x8000
1429
1430static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
1431{
1432/*#define CHECKING // comment this line in to enable checking */
1433#ifdef CHECKING
1434 if (address < (u32)MSG_ADDRESS)
1435 return 0;
1436 if (address > (u32)(QUEUE_START + QUEUE_SIZE))
1437 return 0;
1438 if ((address + (length_in_dwords << 2)) >
1439 (u32)(QUEUE_START + QUEUE_SIZE))
1440 return 0;
1441#else
1442 (void)address;
1443 (void)length_in_dwords;
1444 return 1;
1445#endif
1446}
1447
1448static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1449 struct hpi_message *phm, struct hpi_response *phr)
1450{
1451 struct dsp_obj *pdo =
1452 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1453 u32 data_sent = 0;
1454 u16 ack;
1455 u32 length, address;
1456 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1457 u16 time_out = 8;
1458
1459 (void)phr;
1460
1461 /* round dwDataSize down to nearest 4 bytes */
1462 while ((data_sent < (phm->u.d.u.data.data_size & ~3L))
1463 && --time_out) {
1464 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1465 if (ack & HPI_HIF_ERROR_MASK)
1466 return HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT;
1467
1468 if (hpi6000_send_host_command(pao, dsp_index,
1469 HPI_HIF_SEND_DATA))
1470 return HPI6000_ERROR_SEND_DATA_CMD;
1471
1472 hpi6000_send_dsp_interrupt(pdo);
1473
1474 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA);
1475
1476 if (ack & HPI_HIF_ERROR_MASK)
1477 return HPI6000_ERROR_SEND_DATA_ACK;
1478
1479 do {
1480 /* get the address and size */
1481 address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1482 /* DSP returns number of DWORDS */
1483 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1484 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1485
1486 if (!hpi6000_send_data_check_adr(address, length))
1487 return HPI6000_ERROR_SEND_DATA_ADR;
1488
1489 /* send the data. break data into 512 DWORD blocks (2K bytes)
1490 * and send using block write. 2Kbytes is the max as this is the
1491 * memory window given to the HPI data register by the PCI2040
1492 */
1493
1494 {
1495 u32 len = length;
1496 u32 blk_len = 512;
1497 while (len) {
1498 if (len < blk_len)
1499 blk_len = len;
1500 if (hpi6000_dsp_block_write32(pao, dsp_index,
1501 address, p_data, blk_len))
1502 return HPI6000_ERROR_SEND_DATA_WRITE;
1503 address += blk_len * 4;
1504 p_data += blk_len;
1505 len -= blk_len;
1506 }
1507 }
1508
1509 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1510 return HPI6000_ERROR_SEND_DATA_IDLECMD;
1511
1512 hpi6000_send_dsp_interrupt(pdo);
1513
1514 data_sent += length * 4;
1515 }
1516 if (!time_out)
1517 return HPI6000_ERROR_SEND_DATA_TIMEOUT;
1518 return 0;
1519}
1520
1521static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1522 struct hpi_message *phm, struct hpi_response *phr)
1523{
1524 struct dsp_obj *pdo =
1525 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1526 u32 data_got = 0;
1527 u16 ack;
1528 u32 length, address;
1529 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1530
1531 (void)phr; /* this parameter not used! */
1532
1533 /* round dwDataSize down to nearest 4 bytes */
1534 while (data_got < (phm->u.d.u.data.data_size & ~3L)) {
1535 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1536 if (ack & HPI_HIF_ERROR_MASK)
1537 return HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT;
1538
1539 if (hpi6000_send_host_command(pao, dsp_index,
1540 HPI_HIF_GET_DATA))
1541 return HPI6000_ERROR_GET_DATA_CMD;
1542 hpi6000_send_dsp_interrupt(pdo);
1543
1544 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA);
1545
1546 if (ack & HPI_HIF_ERROR_MASK)
1547 return HPI6000_ERROR_GET_DATA_ACK;
1548
1549 /* get the address and size */
1550 do {
1551 address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1552 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1553 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1554
1555 /* read the data */
1556 {
1557 u32 len = length;
1558 u32 blk_len = 512;
1559 while (len) {
1560 if (len < blk_len)
1561 blk_len = len;
1562 if (hpi6000_dsp_block_read32(pao, dsp_index,
1563 address, p_data, blk_len))
1564 return HPI6000_ERROR_GET_DATA_READ;
1565 address += blk_len * 4;
1566 p_data += blk_len;
1567 len -= blk_len;
1568 }
1569 }
1570
1571 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1572 return HPI6000_ERROR_GET_DATA_IDLECMD;
1573 hpi6000_send_dsp_interrupt(pdo);
1574
1575 data_got += length * 4;
1576 }
1577 return 0;
1578}
1579
1580static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
1581{
1582 iowrite32(0x00030003, pdo->prHPI_control); /* DSPINT */
1583}
1584
1585static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
1586 u16 dsp_index, u32 host_cmd)
1587{
1588 struct dsp_obj *pdo =
1589 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1590 u32 timeout = TIMEOUT;
1591
1592 /* set command */
1593 do {
1594 hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd);
1595 /* flush the FIFO */
1596 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1597 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout);
1598
1599 /* reset the interrupt bit */
1600 iowrite32(0x00040004, pdo->prHPI_control);
1601
1602 if (timeout)
1603 return 0;
1604 else
1605 return 1;
1606}
1607
1608/* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */
1609static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1610 u16 read_or_write)
1611{
1612 u32 hPI_error;
1613
1614 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1615
1616 /* read the error bits from the PCI2040 */
1617 hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1618 if (hPI_error) {
1619 /* reset the error flag */
1620 iowrite32(0L, phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1621 phw->pCI2040HPI_error_count++;
1622 if (read_or_write == 1)
1623 gw_pci_read_asserts++; /************* inc global */
1624 else
1625 gw_pci_write_asserts++;
1626 return 1;
1627 } else
1628 return 0;
1629}
1630
1631static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
1632 u32 ack_value)
1633{
1634 struct dsp_obj *pdo =
1635 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1636 u32 ack = 0L;
1637 u32 timeout;
1638 u32 hPIC = 0L;
1639
1640 /* wait for host interrupt to signal ack is ready */
1641 timeout = TIMEOUT;
1642 while (--timeout) {
1643 hPIC = ioread32(pdo->prHPI_control);
1644 if (hPIC & 0x04) /* 0x04 = HINT from DSP */
1645 break;
1646 }
1647 if (timeout == 0)
1648 return HPI_HIF_ERROR_MASK;
1649
1650 /* wait for dwAckValue */
1651 timeout = TIMEOUT;
1652 while (--timeout) {
1653 /* read the ack mailbox */
1654 ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack));
1655 if (ack == ack_value)
1656 break;
1657 if ((ack & HPI_HIF_ERROR_MASK)
1658 && !hpi6000_check_PCI2040_error_flag(pao, H6READ))
1659 break;
1660 /*for (i=0;i<1000;i++) */
1661 /* dwPause=i+1; */
1662 }
1663 if (ack & HPI_HIF_ERROR_MASK)
1664 /* indicates bad read from DSP -
1665 typically 0xffffff is read for some reason */
1666 ack = HPI_HIF_ERROR_MASK;
1667
1668 if (timeout == 0)
1669 ack = HPI_HIF_ERROR_MASK;
1670 return (short)ack;
1671}
1672
1673static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
1674 struct hpi_message *phm)
1675{
1676 const u16 dsp_index = 0;
1677 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1678 struct dsp_obj *pdo = &phw->ado[dsp_index];
1679 u32 timeout;
1680 u32 cache_dirty_flag;
1681 u16 err;
1682
1683 hpios_dsplock_lock(pao);
1684
1685 timeout = TIMEOUT;
1686 do {
1687 cache_dirty_flag =
1688 hpi_read_word((struct dsp_obj *)pdo,
1689 HPI_HIF_ADDR(control_cache_is_dirty));
1690 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1691 if (!timeout) {
1692 err = HPI6000_ERROR_CONTROL_CACHE_PARAMS;
1693 goto unlock;
1694 }
1695
1696 if (cache_dirty_flag) {
1697 /* read the cached controls */
1698 u32 address;
1699 u32 length;
1700
1701 timeout = TIMEOUT;
1702 if (pdo->control_cache_address_on_dsp == 0) {
1703 do {
1704 address =
1705 hpi_read_word((struct dsp_obj *)pdo,
1706 HPI_HIF_ADDR(control_cache_address));
1707
1708 length = hpi_read_word((struct dsp_obj *)pdo,
1709 HPI_HIF_ADDR
1710 (control_cache_size_in_bytes));
1711 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1712 && --timeout);
1713 if (!timeout) {
1714 err = HPI6000_ERROR_CONTROL_CACHE_ADDRLEN;
1715 goto unlock;
1716 }
1717 pdo->control_cache_address_on_dsp = address;
1718 pdo->control_cache_length_on_dsp = length;
1719 } else {
1720 address = pdo->control_cache_address_on_dsp;
1721 length = pdo->control_cache_length_on_dsp;
1722 }
1723
1724 if (hpi6000_dsp_block_read32(pao, dsp_index, address,
1725 (u32 *)&phw->control_cache[0],
1726 length / sizeof(u32))) {
1727 err = HPI6000_ERROR_CONTROL_CACHE_READ;
1728 goto unlock;
1729 }
1730 do {
1731 hpi_write_word((struct dsp_obj *)pdo,
1732 HPI_HIF_ADDR(control_cache_is_dirty), 0);
1733 /* flush the FIFO */
1734 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1735 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1736 && --timeout);
1737 if (!timeout) {
1738 err = HPI6000_ERROR_CONTROL_CACHE_FLUSH;
1739 goto unlock;
1740 }
1741
1742 }
1743 err = 0;
1744
1745unlock:
1746 hpios_dsplock_unlock(pao);
1747 return err;
1748}
1749
1750/** Get dsp index for multi DSP adapters only */
1751static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm)
1752{
1753 u16 ret = 0;
1754 switch (phm->object) {
1755 case HPI_OBJ_ISTREAM:
1756 if (phm->obj_index < 2)
1757 ret = 1;
1758 break;
1759 case HPI_OBJ_PROFILE:
1760 ret = phm->obj_index;
1761 break;
1762 default:
1763 break;
1764 }
1765 return ret;
1766}
1767
1768/** Complete transaction with DSP
1769
1770Send message, get response, send or get stream data if any.
1771*/
1772static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1773 struct hpi_response *phr)
1774{
1775 u16 error = 0;
1776 u16 dsp_index = 0;
1777 u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp;
1778 hpios_dsplock_lock(pao);
1779
1780 if (num_dsp < 2)
1781 dsp_index = 0;
1782 else {
1783 dsp_index = get_dsp_index(pao, phm);
1784
1785 /* is this checked on the DSP anyway? */
1786 if ((phm->function == HPI_ISTREAM_GROUP_ADD)
1787 || (phm->function == HPI_OSTREAM_GROUP_ADD)) {
1788 struct hpi_message hm;
1789 u16 add_index;
1790 hm.obj_index = phm->u.d.u.stream.stream_index;
1791 hm.object = phm->u.d.u.stream.object_type;
1792 add_index = get_dsp_index(pao, &hm);
1793 if (add_index != dsp_index) {
1794 phr->error = HPI_ERROR_NO_INTERDSP_GROUPS;
1795 return;
1796 }
1797 }
1798 }
1799 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1800
1801 /* maybe an error response */
1802 if (error) {
1803 /* something failed in the HPI/DSP interface */
1804 phr->error = error;
1805 /* just the header of the response is valid */
1806 phr->size = sizeof(struct hpi_response_header);
1807 goto err;
1808 }
1809
1810 if (phr->error != 0) /* something failed in the DSP */
1811 goto err;
1812
1813 switch (phm->function) {
1814 case HPI_OSTREAM_WRITE:
1815 case HPI_ISTREAM_ANC_WRITE:
1816 error = hpi6000_send_data(pao, dsp_index, phm, phr);
1817 break;
1818 case HPI_ISTREAM_READ:
1819 case HPI_OSTREAM_ANC_READ:
1820 error = hpi6000_get_data(pao, dsp_index, phm, phr);
1821 break;
1822 case HPI_ADAPTER_GET_ASSERT:
1823 phr->u.a.adapter_index = 0; /* dsp 0 default */
1824 if (num_dsp == 2) {
1825 if (!phr->u.a.adapter_type) {
1826 /* no assert from dsp 0, check dsp 1 */
1827 error = hpi6000_message_response_sequence(pao,
1828 1, phm, phr);
1829 phr->u.a.adapter_index = 1;
1830 }
1831 }
1832 }
1833
1834 if (error)
1835 phr->error = error;
1836
1837err:
1838 hpios_dsplock_unlock(pao);
1839 return;
1840}
diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h
new file mode 100644
index 000000000000..4c7d507c0ecd
--- /dev/null
+++ b/sound/pci/asihpi/hpi6000.h
@@ -0,0 +1,70 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Public declarations for DSP Proramming Interface to TI C6701
20
21Shared between hpi6000.c and DSP code
22
23(C) Copyright AudioScience Inc. 1998-2003
24******************************************************************************/
25
26#ifndef _HPI6000_H_
27#define _HPI6000_H_
28
29#define HPI_NMIXER_CONTROLS 200
30
31/*
32 * Control caching is always supported in the HPI code.
33 * The DSP should make sure that dwControlCacheSizeInBytes is initialized to 0
34 * during boot to make it in-active.
35 */
36struct hpi_hif_6000 {
37 u32 host_cmd;
38 u32 dsp_ack;
39 u32 address;
40 u32 length;
41 u32 message_buffer_address;
42 u32 response_buffer_address;
43 u32 dsp_number;
44 u32 adapter_info;
45 u32 control_cache_is_dirty;
46 u32 control_cache_address;
47 u32 control_cache_size_in_bytes;
48 u32 control_cache_count;
49};
50
51#define HPI_HIF_PACK_ADAPTER_INFO(adapter, version_major, version_minor) \
52 ((adapter << 16) | (version_major << 8) | version_minor)
53#define HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER(adapterinfo) \
54 ((adapterinfo >> 16) & 0xffff)
55#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MAJOR(adapterinfo) \
56 ((adapterinfo >> 8) & 0xff)
57#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MINOR(adapterinfo) \
58 (adapterinfo & 0xff)
59
60/* Command/status exchanged between host and DSP */
61#define HPI_HIF_IDLE 0
62#define HPI_HIF_SEND_MSG 1
63#define HPI_HIF_GET_RESP 2
64#define HPI_HIF_DATA_MASK 0x10
65#define HPI_HIF_SEND_DATA 0x13
66#define HPI_HIF_GET_DATA 0x14
67#define HPI_HIF_SEND_DONE 5
68#define HPI_HIF_RESET 9
69
70#endif /* _HPI6000_H_ */
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
new file mode 100644
index 000000000000..5e88c1fc2b9e
--- /dev/null
+++ b/sound/pci/asihpi/hpi6205.c
@@ -0,0 +1,2331 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience
20 ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
21 These PCI and PCIe bus adapters are based on a
22 TMS320C6205 PCI bus mastering DSP,
23 and (except ASI50xx) TI TMS320C6xxx floating point DSP
24
25 Exported function:
26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
27
28(C) Copyright AudioScience Inc. 1998-2010
29*******************************************************************************/
30#define SOURCEFILE_NAME "hpi6205.c"
31
32#include "hpi_internal.h"
33#include "hpimsginit.h"
34#include "hpidebug.h"
35#include "hpi6205.h"
36#include "hpidspcd.h"
37#include "hpicmn.h"
38
39/*****************************************************************************/
40/* HPI6205 specific error codes */
41#define HPI6205_ERROR_BASE 1000
42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
43#define HPI6205_ERROR_6205_NO_IRQ 1002
44#define HPI6205_ERROR_6205_INIT_FAILED 1003
45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
47#define HPI6205_ERROR_6205_REG 1006
48#define HPI6205_ERROR_6205_DSPPAGE 1007
49#define HPI6205_ERROR_BAD_DSPINDEX 1008
50#define HPI6205_ERROR_C6713_HPIC 1009
51#define HPI6205_ERROR_C6713_HPIA 1010
52#define HPI6205_ERROR_C6713_PLL 1011
53#define HPI6205_ERROR_DSP_INTMEM 1012
54#define HPI6205_ERROR_DSP_EXTMEM 1013
55#define HPI6205_ERROR_DSP_PLD 1014
56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
57#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018
60
61#define hpi6205_error(dsp_index, err) (err)
62/*****************************************************************************/
63/* for C6205 PCI i/f */
64/* Host Status Register (HSR) bitfields */
65#define C6205_HSR_INTSRC 0x01
66#define C6205_HSR_INTAVAL 0x02
67#define C6205_HSR_INTAM 0x04
68#define C6205_HSR_CFGERR 0x08
69#define C6205_HSR_EEREAD 0x10
70/* Host-to-DSP Control Register (HDCR) bitfields */
71#define C6205_HDCR_WARMRESET 0x01
72#define C6205_HDCR_DSPINT 0x02
73#define C6205_HDCR_PCIBOOT 0x04
74/* DSP Page Register (DSPP) bitfields, */
75/* defines 4 Mbyte page that BAR0 points to */
76#define C6205_DSPP_MAP1 0x400
77
78/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
79 * BAR1 maps to non-prefetchable 8 Mbyte memory block
80 * of DSP memory mapped registers (starting at 0x01800000).
81 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
82 * needs to be added to the BAR1 base address set in the PCI config reg
83 */
84#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
85#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
86#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
87#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
88
89/* used to control LED (revA) and reset C6713 (revB) */
90#define C6205_BAR0_TIMER1_CTL (0x01980000L)
91
92/* For first 6713 in CE1 space, using DA17,16,2 */
93#define HPICL_ADDR 0x01400000L
94#define HPICH_ADDR 0x01400004L
95#define HPIAL_ADDR 0x01410000L
96#define HPIAH_ADDR 0x01410004L
97#define HPIDIL_ADDR 0x01420000L
98#define HPIDIH_ADDR 0x01420004L
99#define HPIDL_ADDR 0x01430000L
100#define HPIDH_ADDR 0x01430004L
101
102#define C6713_EMIF_GCTL 0x01800000
103#define C6713_EMIF_CE1 0x01800004
104#define C6713_EMIF_CE0 0x01800008
105#define C6713_EMIF_CE2 0x01800010
106#define C6713_EMIF_CE3 0x01800014
107#define C6713_EMIF_SDRAMCTL 0x01800018
108#define C6713_EMIF_SDRAMTIMING 0x0180001C
109#define C6713_EMIF_SDRAMEXT 0x01800020
110
111struct hpi_hw_obj {
112 /* PCI registers */
113 __iomem u32 *prHSR;
114 __iomem u32 *prHDCR;
115 __iomem u32 *prDSPP;
116
117 u32 dsp_page;
118
119 struct consistent_dma_area h_locked_mem;
120 struct bus_master_interface *p_interface_buffer;
121
122 u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
123 /* a non-NULL handle means there is an HPI allocated buffer */
124 struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
125 struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
126 /* non-zero size means a buffer exists, may be external */
127 u32 instream_host_buffer_size[HPI_MAX_STREAMS];
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129
130 struct consistent_dma_area h_control_cache;
131 struct consistent_dma_area h_async_event_buffer;
132/* struct hpi_control_cache_single *pControlCache; */
133 struct hpi_async_event *p_async_event_buffer;
134 struct hpi_control_cache *p_cache;
135};
136
137/*****************************************************************************/
138/* local prototypes */
139
140#define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141
142static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
143
144static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
145
146static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147 u32 *pos_error_code);
148
149static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150 struct hpi_message *phm, struct hpi_response *phr);
151
152static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153 struct hpi_response *phr);
154
155#define HPI6205_TIMEOUT 1000000
156
157static void subsys_create_adapter(struct hpi_message *phm,
158 struct hpi_response *phr);
159static void subsys_delete_adapter(struct hpi_message *phm,
160 struct hpi_response *phr);
161
162static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164
165static void delete_adapter_obj(struct hpi_adapter_obj *pao);
166
167static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168 struct hpi_message *phm, struct hpi_response *phr);
169
170static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171 struct hpi_message *phm, struct hpi_response *phr);
172
173static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
174 struct hpi_message *phm, struct hpi_response *phr);
175static void outstream_write(struct hpi_adapter_obj *pao,
176 struct hpi_message *phm, struct hpi_response *phr);
177
178static void outstream_get_info(struct hpi_adapter_obj *pao,
179 struct hpi_message *phm, struct hpi_response *phr);
180
181static void outstream_start(struct hpi_adapter_obj *pao,
182 struct hpi_message *phm, struct hpi_response *phr);
183
184static void outstream_open(struct hpi_adapter_obj *pao,
185 struct hpi_message *phm, struct hpi_response *phr);
186
187static void outstream_reset(struct hpi_adapter_obj *pao,
188 struct hpi_message *phm, struct hpi_response *phr);
189
190static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191 struct hpi_message *phm, struct hpi_response *phr);
192
193static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194 struct hpi_message *phm, struct hpi_response *phr);
195
196static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197 struct hpi_message *phm, struct hpi_response *phr);
198
199static void instream_read(struct hpi_adapter_obj *pao,
200 struct hpi_message *phm, struct hpi_response *phr);
201
202static void instream_get_info(struct hpi_adapter_obj *pao,
203 struct hpi_message *phm, struct hpi_response *phr);
204
205static void instream_start(struct hpi_adapter_obj *pao,
206 struct hpi_message *phm, struct hpi_response *phr);
207
208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address);
210
211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212 u32 address, u32 data);
213
214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index);
216
217static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218 u32 address, u32 length);
219
220static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221 int dsp_index);
222
223static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224 int dsp_index);
225
226static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227
228/*****************************************************************************/
229
230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231{
232
233 switch (phm->function) {
234 case HPI_SUBSYS_OPEN:
235 case HPI_SUBSYS_CLOSE:
236 case HPI_SUBSYS_GET_INFO:
237 case HPI_SUBSYS_DRIVER_UNLOAD:
238 case HPI_SUBSYS_DRIVER_LOAD:
239 case HPI_SUBSYS_FIND_ADAPTERS:
240 /* messages that should not get here */
241 phr->error = HPI_ERROR_UNIMPLEMENTED;
242 break;
243 case HPI_SUBSYS_CREATE_ADAPTER:
244 subsys_create_adapter(phm, phr);
245 break;
246 case HPI_SUBSYS_DELETE_ADAPTER:
247 subsys_delete_adapter(phm, phr);
248 break;
249 default:
250 phr->error = HPI_ERROR_INVALID_FUNC;
251 break;
252 }
253}
254
255static void control_message(struct hpi_adapter_obj *pao,
256 struct hpi_message *phm, struct hpi_response *phr)
257{
258
259 struct hpi_hw_obj *phw = pao->priv;
260
261 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr))
266 break;
267 }
268 hw_message(pao, phm, phr);
269 break;
270 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr);
272 break;
273 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr);
275 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr);
277 break;
278 default:
279 phr->error = HPI_ERROR_INVALID_FUNC;
280 break;
281 }
282}
283
284static void adapter_message(struct hpi_adapter_obj *pao,
285 struct hpi_message *phm, struct hpi_response *phr)
286{
287 switch (phm->function) {
288 default:
289 hw_message(pao, phm, phr);
290 break;
291 }
292}
293
294static void outstream_message(struct hpi_adapter_obj *pao,
295 struct hpi_message *phm, struct hpi_response *phr)
296{
297
298 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM;
300 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index);
304 return;
305 }
306
307 switch (phm->function) {
308 case HPI_OSTREAM_WRITE:
309 outstream_write(pao, phm, phr);
310 break;
311 case HPI_OSTREAM_GET_INFO:
312 outstream_get_info(pao, phm, phr);
313 break;
314 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
315 outstream_host_buffer_allocate(pao, phm, phr);
316 break;
317 case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
318 outstream_host_buffer_get_info(pao, phm, phr);
319 break;
320 case HPI_OSTREAM_HOSTBUFFER_FREE:
321 outstream_host_buffer_free(pao, phm, phr);
322 break;
323 case HPI_OSTREAM_START:
324 outstream_start(pao, phm, phr);
325 break;
326 case HPI_OSTREAM_OPEN:
327 outstream_open(pao, phm, phr);
328 break;
329 case HPI_OSTREAM_RESET:
330 outstream_reset(pao, phm, phr);
331 break;
332 default:
333 hw_message(pao, phm, phr);
334 break;
335 }
336}
337
338static void instream_message(struct hpi_adapter_obj *pao,
339 struct hpi_message *phm, struct hpi_response *phr)
340{
341
342 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM;
344 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index);
348 return;
349 }
350
351 switch (phm->function) {
352 case HPI_ISTREAM_READ:
353 instream_read(pao, phm, phr);
354 break;
355 case HPI_ISTREAM_GET_INFO:
356 instream_get_info(pao, phm, phr);
357 break;
358 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
359 instream_host_buffer_allocate(pao, phm, phr);
360 break;
361 case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
362 instream_host_buffer_get_info(pao, phm, phr);
363 break;
364 case HPI_ISTREAM_HOSTBUFFER_FREE:
365 instream_host_buffer_free(pao, phm, phr);
366 break;
367 case HPI_ISTREAM_START:
368 instream_start(pao, phm, phr);
369 break;
370 default:
371 hw_message(pao, phm, phr);
372 break;
373 }
374}
375
376/*****************************************************************************/
377/** Entry point to this HPI backend
378 * All calls to the HPI start here
379 */
380void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
381{
382 struct hpi_adapter_obj *pao = NULL;
383
384 /* subsytem messages are processed by every HPI.
385 * All other messages are ignored unless the adapter index matches
386 * an adapter in the HPI
387 */
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389 phm->function);
390
391 /* if Dsp has crashed then do not communicate with it any more */
392 if (phm->object != HPI_OBJ_SUBSYSTEM) {
393 pao = hpi_find_adapter(phm->adapter_index);
394 if (!pao) {
395 HPI_DEBUG_LOG(DEBUG,
396 " %d,%d refused, for another HPI?\n",
397 phm->object, phm->function);
398 return;
399 }
400
401 if ((pao->dsp_crashed >= 10)
402 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403 /* allow last resort debug read even after crash */
404 hpi_init_response(phr, phm->object, phm->function,
405 HPI_ERROR_DSP_HARDWARE);
406 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407 phm->object, phm->function);
408 return;
409 }
410 }
411
412 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function,
415 HPI_ERROR_PROCESSING_MESSAGE);
416
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) {
419 case HPI_TYPE_MESSAGE:
420 switch (phm->object) {
421 case HPI_OBJ_SUBSYSTEM:
422 subsys_message(phm, phr);
423 break;
424
425 case HPI_OBJ_ADAPTER:
426 phr->size =
427 sizeof(struct hpi_response_header) +
428 sizeof(struct hpi_adapter_res);
429 adapter_message(pao, phm, phr);
430 break;
431
432 case HPI_OBJ_CONTROLEX:
433 case HPI_OBJ_CONTROL:
434 control_message(pao, phm, phr);
435 break;
436
437 case HPI_OBJ_OSTREAM:
438 outstream_message(pao, phm, phr);
439 break;
440
441 case HPI_OBJ_ISTREAM:
442 instream_message(pao, phm, phr);
443 break;
444
445 default:
446 hw_message(pao, phm, phr);
447 break;
448 }
449 break;
450
451 default:
452 phr->error = HPI_ERROR_INVALID_TYPE;
453 break;
454 }
455}
456
457/*****************************************************************************/
458/* SUBSYSTEM */
459
460/** Create an adapter object and initialise it based on resource information
461 * passed in in the message
462 * *** NOTE - you cannot use this function AND the FindAdapters function at the
463 * same time, the application must use only one of them to get the adapters ***
464 */
465static void subsys_create_adapter(struct hpi_message *phm,
466 struct hpi_response *phr)
467{
468 /* create temp adapter obj, because we don't know what index yet */
469 struct hpi_adapter_obj ao;
470 u32 os_error_code;
471 u16 err;
472
473 HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
474
475 memset(&ao, 0, sizeof(ao));
476
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479 return;
480 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481 return;
482 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483 return;
484
485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
488 phr->error = HPI_ERROR_MEMORY_ALLOC;
489 return;
490 }
491
492 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao);
499 phr->error = err;
500 return;
501 }
502
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0;
507}
508
509/** delete an adapter - required by WDM driver */
510static void subsys_delete_adapter(struct hpi_message *phm,
511 struct hpi_response *phr)
512{
513 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw;
515
516 pao = hpi_find_adapter(phm->adapter_index);
517 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return;
520 }
521 phw = (struct hpi_hw_obj *)pao->priv;
522 /* reset adapter h/w */
523 /* Reset C6713 #1 */
524 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
525 /* reset C6205 */
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527
528 delete_adapter_obj(pao);
529 phr->error = 0;
530}
531
532/** Create adapter object
533 allocate buffers, bootload DSPs, initialise control cache
534*/
535static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536 u32 *pos_error_code)
537{
538 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface;
540 u32 phys_addr;
541#ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544#endif
545 int i;
546 u16 err;
547
548 /* init error reporting */
549 pao->dsp_crashed = 0;
550
551 for (i = 0; i < HPI_MAX_STREAMS; i++)
552 phw->flag_outstream_just_reset[i] = 1;
553
554 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
555 phw->prHSR =
556 pao->pci.ap_mem_base[1] +
557 C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
558 phw->prHDCR =
559 pao->pci.ap_mem_base[1] +
560 C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
561 phw->prDSPP =
562 pao->pci.ap_mem_base[1] +
563 C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
564
565 pao->has_control_cache = 0;
566
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data))
570 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer))
573 phw->p_interface_buffer = NULL;
574
575 HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576 phw->p_interface_buffer);
577
578 if (phw->p_interface_buffer) {
579 memset((void *)phw->p_interface_buffer, 0,
580 sizeof(struct bus_master_interface));
581 phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
582 }
583
584 err = adapter_boot_load_dsp(pao, pos_error_code);
585 if (err)
586 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */
588 return err;
589
590 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591
592 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
595
596 interface = phw->p_interface_buffer;
597
598#ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out = HPI6205_TIMEOUT * 10;
601 temp1 = 0;
602 while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603 temp1 = ioread32(phw->prHSR);
604
605 if (temp1 & C6205_HSR_INTSRC)
606 HPI_DEBUG_LOG(INFO,
607 "interrupt confirming DSP code running OK\n");
608 else {
609 HPI_DEBUG_LOG(ERROR,
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613 }
614
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617#endif
618
619 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
623 }
624 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it
627 */
628 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual;
630
631 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data);
634 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual);
637 if (!err) {
638 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes);
640
641 phw->p_cache =
642 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual);
647 }
648 if (!err) {
649 err = hpios_locked_mem_get_phys_addr(&phw->
650 h_control_cache, &phys_addr);
651 interface->control_cache.physical_address32 =
652 phys_addr;
653 }
654
655 if (!err)
656 pao->has_control_cache = 1;
657 else {
658 if (hpios_locked_mem_valid(&phw->h_control_cache))
659 hpios_locked_mem_free(&phw->h_control_cache);
660 pao->has_control_cache = 0;
661 }
662 }
663 /* allocate bus mastering async buffer and tell the DSP about it */
664 if (interface->async_buffer.b.size) {
665 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
666 interface->async_buffer.b.size *
667 sizeof(struct hpi_async_event), pao->pci.p_os_data);
668 if (!err)
669 err = hpios_locked_mem_get_virt_addr
670 (&phw->h_async_event_buffer, (void *)
671 &phw->p_async_event_buffer);
672 if (!err)
673 memset((void *)phw->p_async_event_buffer, 0,
674 interface->async_buffer.b.size *
675 sizeof(struct hpi_async_event));
676 if (!err) {
677 err = hpios_locked_mem_get_phys_addr
678 (&phw->h_async_event_buffer, &phys_addr);
679 interface->async_buffer.physical_address32 =
680 phys_addr;
681 }
682 if (err) {
683 if (hpios_locked_mem_valid(&phw->
684 h_async_event_buffer)) {
685 hpios_locked_mem_free
686 (&phw->h_async_event_buffer);
687 phw->p_async_event_buffer = NULL;
688 }
689 }
690 }
691 send_dsp_command(phw, H620_HIF_IDLE);
692
693 {
694 struct hpi_message hM;
695 struct hpi_response hR;
696 u32 max_streams;
697
698 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
699 memset(&hM, 0, sizeof(hM));
700 hM.type = HPI_TYPE_MESSAGE;
701 hM.size = sizeof(hM);
702 hM.object = HPI_OBJ_ADAPTER;
703 hM.function = HPI_ADAPTER_GET_INFO;
704 hM.adapter_index = 0;
705 memset(&hR, 0, sizeof(hR));
706 hR.size = sizeof(hR);
707
708 err = message_response_sequence(pao, &hM, &hR);
709 if (err) {
710 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
711 err);
712 return err;
713 }
714 if (hR.error)
715 return hR.error;
716
717 pao->adapter_type = hR.u.a.adapter_type;
718 pao->index = hR.u.a.adapter_index;
719
720 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
721
722 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
723 65536, pao->pci.p_os_data);
724
725 HPI_DEBUG_LOG(VERBOSE,
726 "got adapter info type %x index %d serial %d\n",
727 hR.u.a.adapter_type, hR.u.a.adapter_index,
728 hR.u.a.serial_number);
729 }
730
731 pao->open = 0; /* upon creation the adapter is closed */
732
733 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
734 return 0;
735}
736
737/** Free memory areas allocated by adapter
738 * this routine is called from SubSysDeleteAdapter,
739 * and SubSysCreateAdapter if duplicate index
740*/
741static void delete_adapter_obj(struct hpi_adapter_obj *pao)
742{
743 struct hpi_hw_obj *phw;
744 int i;
745
746 phw = pao->priv;
747
748 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
749 hpios_locked_mem_free(&phw->h_async_event_buffer);
750 phw->p_async_event_buffer = NULL;
751 }
752
753 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
754 hpios_locked_mem_free(&phw->h_control_cache);
755 hpi_free_control_cache(phw->p_cache);
756 }
757
758 if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
759 hpios_locked_mem_free(&phw->h_locked_mem);
760 phw->p_interface_buffer = NULL;
761 }
762
763 for (i = 0; i < HPI_MAX_STREAMS; i++)
764 if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
765 hpios_locked_mem_free(&phw->instream_host_buffers[i]);
766 /*?phw->InStreamHostBuffers[i] = NULL; */
767 phw->instream_host_buffer_size[i] = 0;
768 }
769
770 for (i = 0; i < HPI_MAX_STREAMS; i++)
771 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
772 hpios_locked_mem_free(&phw->outstream_host_buffers
773 [i]);
774 phw->outstream_host_buffer_size[i] = 0;
775 }
776
777 hpios_locked_mem_unprepare(pao->pci.p_os_data);
778
779 hpi_delete_adapter(pao);
780 kfree(phw);
781}
782
783/*****************************************************************************/
784/* OutStream Host buffer functions */
785
786/** Allocate or attach buffer for busmastering
787*/
788static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
789 struct hpi_message *phm, struct hpi_response *phr)
790{
791 u16 err = 0;
792 u32 command = phm->u.d.u.buffer.command;
793 struct hpi_hw_obj *phw = pao->priv;
794 struct bus_master_interface *interface = phw->p_interface_buffer;
795
796 hpi_init_response(phr, phm->object, phm->function, 0);
797
798 if (command == HPI_BUFFER_CMD_EXTERNAL
799 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
800 /* ALLOC phase, allocate a buffer with power of 2 size,
801 get its bus address for PCI bus mastering
802 */
803 phm->u.d.u.buffer.buffer_size =
804 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
805 /* return old size and allocated size,
806 so caller can detect change */
807 phr->u.d.u.stream_info.data_available =
808 phw->outstream_host_buffer_size[phm->obj_index];
809 phr->u.d.u.stream_info.buffer_size =
810 phm->u.d.u.buffer.buffer_size;
811
812 if (phw->outstream_host_buffer_size[phm->obj_index] ==
813 phm->u.d.u.buffer.buffer_size) {
814 /* Same size, no action required */
815 return;
816 }
817
818 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
819 obj_index]))
820 hpios_locked_mem_free(&phw->outstream_host_buffers
821 [phm->obj_index]);
822
823 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
824 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
825 pao->pci.p_os_data);
826
827 if (err) {
828 phr->error = HPI_ERROR_INVALID_DATASIZE;
829 phw->outstream_host_buffer_size[phm->obj_index] = 0;
830 return;
831 }
832
833 err = hpios_locked_mem_get_phys_addr
834 (&phw->outstream_host_buffers[phm->obj_index],
835 &phm->u.d.u.buffer.pci_address);
836 /* get the phys addr into msg for single call alloc caller
837 * needs to do this for split alloc (or use the same message)
838 * return the phy address for split alloc in the respose too
839 */
840 phr->u.d.u.stream_info.auxiliary_data_available =
841 phm->u.d.u.buffer.pci_address;
842
843 if (err) {
844 hpios_locked_mem_free(&phw->outstream_host_buffers
845 [phm->obj_index]);
846 phw->outstream_host_buffer_size[phm->obj_index] = 0;
847 phr->error = HPI_ERROR_MEMORY_ALLOC;
848 return;
849 }
850 }
851
852 if (command == HPI_BUFFER_CMD_EXTERNAL
853 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
854 /* GRANT phase. Set up the BBM status, tell the DSP about
855 the buffer so it can start using BBM.
856 */
857 struct hpi_hostbuffer_status *status;
858
859 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
860 buffer_size - 1)) {
861 HPI_DEBUG_LOG(ERROR,
862 "buffer size must be 2^N not %d\n",
863 phm->u.d.u.buffer.buffer_size);
864 phr->error = HPI_ERROR_INVALID_DATASIZE;
865 return;
866 }
867 phw->outstream_host_buffer_size[phm->obj_index] =
868 phm->u.d.u.buffer.buffer_size;
869 status = &interface->outstream_host_buffer_status[phm->
870 obj_index];
871 status->samples_processed = 0;
872 status->stream_state = HPI_STATE_STOPPED;
873 status->dSP_index = 0;
874 status->host_index = status->dSP_index;
875 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
876
877 hw_message(pao, phm, phr);
878
879 if (phr->error
880 && hpios_locked_mem_valid(&phw->
881 outstream_host_buffers[phm->obj_index])) {
882 hpios_locked_mem_free(&phw->outstream_host_buffers
883 [phm->obj_index]);
884 phw->outstream_host_buffer_size[phm->obj_index] = 0;
885 }
886 }
887}
888
889static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
890 struct hpi_message *phm, struct hpi_response *phr)
891{
892 struct hpi_hw_obj *phw = pao->priv;
893 struct bus_master_interface *interface = phw->p_interface_buffer;
894 struct hpi_hostbuffer_status *status;
895 u8 *p_bbm_data;
896
897 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
898 obj_index])) {
899 if (hpios_locked_mem_get_virt_addr(&phw->
900 outstream_host_buffers[phm->obj_index],
901 (void *)&p_bbm_data)) {
902 phr->error = HPI_ERROR_INVALID_OPERATION;
903 return;
904 }
905 status = &interface->outstream_host_buffer_status[phm->
906 obj_index];
907 hpi_init_response(phr, HPI_OBJ_OSTREAM,
908 HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
909 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
910 phr->u.d.u.hostbuffer_info.p_status = status;
911 } else {
912 hpi_init_response(phr, HPI_OBJ_OSTREAM,
913 HPI_OSTREAM_HOSTBUFFER_GET_INFO,
914 HPI_ERROR_INVALID_OPERATION);
915 }
916}
917
918static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
919 struct hpi_message *phm, struct hpi_response *phr)
920{
921 struct hpi_hw_obj *phw = pao->priv;
922 u32 command = phm->u.d.u.buffer.command;
923
924 if (phw->outstream_host_buffer_size[phm->obj_index]) {
925 if (command == HPI_BUFFER_CMD_EXTERNAL
926 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
927 phw->outstream_host_buffer_size[phm->obj_index] = 0;
928 hw_message(pao, phm, phr);
929 /* Tell adapter to stop using the host buffer. */
930 }
931 if (command == HPI_BUFFER_CMD_EXTERNAL
932 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
933 hpios_locked_mem_free(&phw->outstream_host_buffers
934 [phm->obj_index]);
935 }
936 /* Should HPI_ERROR_INVALID_OPERATION be returned
937 if no host buffer is allocated? */
938 else
939 hpi_init_response(phr, HPI_OBJ_OSTREAM,
940 HPI_OSTREAM_HOSTBUFFER_FREE, 0);
941
942}
943
944static long outstream_get_space_available(struct hpi_hostbuffer_status
945 *status)
946{
947 return status->size_in_bytes - ((long)(status->host_index) -
948 (long)(status->dSP_index));
949}
950
951static void outstream_write(struct hpi_adapter_obj *pao,
952 struct hpi_message *phm, struct hpi_response *phr)
953{
954 struct hpi_hw_obj *phw = pao->priv;
955 struct bus_master_interface *interface = phw->p_interface_buffer;
956 struct hpi_hostbuffer_status *status;
957 long space_available;
958
959 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
960 /* there is no BBM buffer, write via message */
961 hw_message(pao, phm, phr);
962 return;
963 }
964
965 hpi_init_response(phr, phm->object, phm->function, 0);
966 status = &interface->outstream_host_buffer_status[phm->obj_index];
967
968 if (phw->flag_outstream_just_reset[phm->obj_index]) {
969 /* Format can only change after reset. Must tell DSP. */
970 u16 function = phm->function;
971 phw->flag_outstream_just_reset[phm->obj_index] = 0;
972 phm->function = HPI_OSTREAM_SET_FORMAT;
973 hw_message(pao, phm, phr); /* send the format to the DSP */
974 phm->function = function;
975 if (phr->error)
976 return;
977 }
978#if 1
979 if (phw->flag_outstream_just_reset[phm->obj_index]) {
980 /* First OutStremWrite() call following reset will write data to the
981 adapter's buffers, reducing delay before stream can start
982 */
983 int partial_write = 0;
984 unsigned int original_size = 0;
985
986 /* Send the first buffer to the DSP the old way. */
987 /* Limit size of first transfer - */
988 /* expect that this will not usually be triggered. */
989 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
990 partial_write = 1;
991 original_size = phm->u.d.u.data.data_size;
992 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
993 }
994 /* write it */
995 phm->function = HPI_OSTREAM_WRITE;
996 hw_message(pao, phm, phr);
997 /* update status information that the DSP would typically
998 * update (and will update next time the DSP
999 * buffer update task reads data from the host BBM buffer)
1000 */
1001 status->auxiliary_data_available = phm->u.d.u.data.data_size;
1002 status->host_index += phm->u.d.u.data.data_size;
1003 status->dSP_index += phm->u.d.u.data.data_size;
1004
1005 /* if we did a full write, we can return from here. */
1006 if (!partial_write)
1007 return;
1008
1009 /* tweak buffer parameters and let the rest of the */
1010 /* buffer land in internal BBM buffer */
1011 phm->u.d.u.data.data_size =
1012 original_size - HPI6205_SIZEOF_DATA;
1013 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1014 }
1015#endif
1016
1017 space_available = outstream_get_space_available(status);
1018 if (space_available < (long)phm->u.d.u.data.data_size) {
1019 phr->error = HPI_ERROR_INVALID_DATASIZE;
1020 return;
1021 }
1022
1023 /* HostBuffers is used to indicate host buffer is internally allocated.
1024 otherwise, assumed external, data written externally */
1025 if (phm->u.d.u.data.pb_data
1026 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1027 obj_index])) {
1028 u8 *p_bbm_data;
1029 long l_first_write;
1030 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1031
1032 if (hpios_locked_mem_get_virt_addr(&phw->
1033 outstream_host_buffers[phm->obj_index],
1034 (void *)&p_bbm_data)) {
1035 phr->error = HPI_ERROR_INVALID_OPERATION;
1036 return;
1037 }
1038
1039 /* either all data,
1040 or enough to fit from current to end of BBM buffer */
1041 l_first_write =
1042 min(phm->u.d.u.data.data_size,
1043 status->size_in_bytes -
1044 (status->host_index & (status->size_in_bytes - 1)));
1045
1046 memcpy(p_bbm_data +
1047 (status->host_index & (status->size_in_bytes - 1)),
1048 p_app_data, l_first_write);
1049 /* remaining data if any */
1050 memcpy(p_bbm_data, p_app_data + l_first_write,
1051 phm->u.d.u.data.data_size - l_first_write);
1052 }
1053 status->host_index += phm->u.d.u.data.data_size;
1054}
1055
1056static void outstream_get_info(struct hpi_adapter_obj *pao,
1057 struct hpi_message *phm, struct hpi_response *phr)
1058{
1059 struct hpi_hw_obj *phw = pao->priv;
1060 struct bus_master_interface *interface = phw->p_interface_buffer;
1061 struct hpi_hostbuffer_status *status;
1062
1063 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1064 hw_message(pao, phm, phr);
1065 return;
1066 }
1067
1068 hpi_init_response(phr, phm->object, phm->function, 0);
1069
1070 status = &interface->outstream_host_buffer_status[phm->obj_index];
1071
1072 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1073 phr->u.d.u.stream_info.samples_transferred =
1074 status->samples_processed;
1075 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1076 phr->u.d.u.stream_info.data_available =
1077 status->size_in_bytes - outstream_get_space_available(status);
1078 phr->u.d.u.stream_info.auxiliary_data_available =
1079 status->auxiliary_data_available;
1080}
1081
1082static void outstream_start(struct hpi_adapter_obj *pao,
1083 struct hpi_message *phm, struct hpi_response *phr)
1084{
1085 hw_message(pao, phm, phr);
1086}
1087
1088static void outstream_reset(struct hpi_adapter_obj *pao,
1089 struct hpi_message *phm, struct hpi_response *phr)
1090{
1091 struct hpi_hw_obj *phw = pao->priv;
1092 phw->flag_outstream_just_reset[phm->obj_index] = 1;
1093 hw_message(pao, phm, phr);
1094}
1095
1096static void outstream_open(struct hpi_adapter_obj *pao,
1097 struct hpi_message *phm, struct hpi_response *phr)
1098{
1099 outstream_reset(pao, phm, phr);
1100}
1101
1102/*****************************************************************************/
1103/* InStream Host buffer functions */
1104
1105static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1106 struct hpi_message *phm, struct hpi_response *phr)
1107{
1108 u16 err = 0;
1109 u32 command = phm->u.d.u.buffer.command;
1110 struct hpi_hw_obj *phw = pao->priv;
1111 struct bus_master_interface *interface = phw->p_interface_buffer;
1112
1113 hpi_init_response(phr, phm->object, phm->function, 0);
1114
1115 if (command == HPI_BUFFER_CMD_EXTERNAL
1116 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1117
1118 phm->u.d.u.buffer.buffer_size =
1119 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1120 phr->u.d.u.stream_info.data_available =
1121 phw->instream_host_buffer_size[phm->obj_index];
1122 phr->u.d.u.stream_info.buffer_size =
1123 phm->u.d.u.buffer.buffer_size;
1124
1125 if (phw->instream_host_buffer_size[phm->obj_index] ==
1126 phm->u.d.u.buffer.buffer_size) {
1127 /* Same size, no action required */
1128 return;
1129 }
1130
1131 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1132 obj_index]))
1133 hpios_locked_mem_free(&phw->instream_host_buffers
1134 [phm->obj_index]);
1135
1136 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1137 obj_index], phm->u.d.u.buffer.buffer_size,
1138 pao->pci.p_os_data);
1139
1140 if (err) {
1141 phr->error = HPI_ERROR_INVALID_DATASIZE;
1142 phw->instream_host_buffer_size[phm->obj_index] = 0;
1143 return;
1144 }
1145
1146 err = hpios_locked_mem_get_phys_addr
1147 (&phw->instream_host_buffers[phm->obj_index],
1148 &phm->u.d.u.buffer.pci_address);
1149 /* get the phys addr into msg for single call alloc. Caller
1150 needs to do this for split alloc so return the phy address */
1151 phr->u.d.u.stream_info.auxiliary_data_available =
1152 phm->u.d.u.buffer.pci_address;
1153 if (err) {
1154 hpios_locked_mem_free(&phw->instream_host_buffers
1155 [phm->obj_index]);
1156 phw->instream_host_buffer_size[phm->obj_index] = 0;
1157 phr->error = HPI_ERROR_MEMORY_ALLOC;
1158 return;
1159 }
1160 }
1161
1162 if (command == HPI_BUFFER_CMD_EXTERNAL
1163 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1164 struct hpi_hostbuffer_status *status;
1165
1166 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1167 buffer_size - 1)) {
1168 HPI_DEBUG_LOG(ERROR,
1169 "buffer size must be 2^N not %d\n",
1170 phm->u.d.u.buffer.buffer_size);
1171 phr->error = HPI_ERROR_INVALID_DATASIZE;
1172 return;
1173 }
1174
1175 phw->instream_host_buffer_size[phm->obj_index] =
1176 phm->u.d.u.buffer.buffer_size;
1177 status = &interface->instream_host_buffer_status[phm->
1178 obj_index];
1179 status->samples_processed = 0;
1180 status->stream_state = HPI_STATE_STOPPED;
1181 status->dSP_index = 0;
1182 status->host_index = status->dSP_index;
1183 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1184
1185 hw_message(pao, phm, phr);
1186 if (phr->error
1187 && hpios_locked_mem_valid(&phw->
1188 instream_host_buffers[phm->obj_index])) {
1189 hpios_locked_mem_free(&phw->instream_host_buffers
1190 [phm->obj_index]);
1191 phw->instream_host_buffer_size[phm->obj_index] = 0;
1192 }
1193 }
1194}
1195
1196static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1197 struct hpi_message *phm, struct hpi_response *phr)
1198{
1199 struct hpi_hw_obj *phw = pao->priv;
1200 struct bus_master_interface *interface = phw->p_interface_buffer;
1201 struct hpi_hostbuffer_status *status;
1202 u8 *p_bbm_data;
1203
1204 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1205 obj_index])) {
1206 if (hpios_locked_mem_get_virt_addr(&phw->
1207 instream_host_buffers[phm->obj_index],
1208 (void *)&p_bbm_data)) {
1209 phr->error = HPI_ERROR_INVALID_OPERATION;
1210 return;
1211 }
1212 status = &interface->instream_host_buffer_status[phm->
1213 obj_index];
1214 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1215 HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1216 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1217 phr->u.d.u.hostbuffer_info.p_status = status;
1218 } else {
1219 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1220 HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1221 HPI_ERROR_INVALID_OPERATION);
1222 }
1223}
1224
1225static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1226 struct hpi_message *phm, struct hpi_response *phr)
1227{
1228 struct hpi_hw_obj *phw = pao->priv;
1229 u32 command = phm->u.d.u.buffer.command;
1230
1231 if (phw->instream_host_buffer_size[phm->obj_index]) {
1232 if (command == HPI_BUFFER_CMD_EXTERNAL
1233 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1234 phw->instream_host_buffer_size[phm->obj_index] = 0;
1235 hw_message(pao, phm, phr);
1236 }
1237
1238 if (command == HPI_BUFFER_CMD_EXTERNAL
1239 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1240 hpios_locked_mem_free(&phw->instream_host_buffers
1241 [phm->obj_index]);
1242
1243 } else {
1244 /* Should HPI_ERROR_INVALID_OPERATION be returned
1245 if no host buffer is allocated? */
1246 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1247 HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1248
1249 }
1250
1251}
1252
1253static void instream_start(struct hpi_adapter_obj *pao,
1254 struct hpi_message *phm, struct hpi_response *phr)
1255{
1256 hw_message(pao, phm, phr);
1257}
1258
1259static long instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1260{
1261 return (long)(status->dSP_index) - (long)(status->host_index);
1262}
1263
1264static void instream_read(struct hpi_adapter_obj *pao,
1265 struct hpi_message *phm, struct hpi_response *phr)
1266{
1267 struct hpi_hw_obj *phw = pao->priv;
1268 struct bus_master_interface *interface = phw->p_interface_buffer;
1269 struct hpi_hostbuffer_status *status;
1270 long data_available;
1271 u8 *p_bbm_data;
1272 long l_first_read;
1273 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1274
1275 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1276 hw_message(pao, phm, phr);
1277 return;
1278 }
1279 hpi_init_response(phr, phm->object, phm->function, 0);
1280
1281 status = &interface->instream_host_buffer_status[phm->obj_index];
1282 data_available = instream_get_bytes_available(status);
1283 if (data_available < (long)phm->u.d.u.data.data_size) {
1284 phr->error = HPI_ERROR_INVALID_DATASIZE;
1285 return;
1286 }
1287
1288 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1289 obj_index])) {
1290 if (hpios_locked_mem_get_virt_addr(&phw->
1291 instream_host_buffers[phm->obj_index],
1292 (void *)&p_bbm_data)) {
1293 phr->error = HPI_ERROR_INVALID_OPERATION;
1294 return;
1295 }
1296
1297 /* either all data,
1298 or enough to fit from current to end of BBM buffer */
1299 l_first_read =
1300 min(phm->u.d.u.data.data_size,
1301 status->size_in_bytes -
1302 (status->host_index & (status->size_in_bytes - 1)));
1303
1304 memcpy(p_app_data,
1305 p_bbm_data +
1306 (status->host_index & (status->size_in_bytes - 1)),
1307 l_first_read);
1308 /* remaining data if any */
1309 memcpy(p_app_data + l_first_read, p_bbm_data,
1310 phm->u.d.u.data.data_size - l_first_read);
1311 }
1312 status->host_index += phm->u.d.u.data.data_size;
1313}
1314
1315static void instream_get_info(struct hpi_adapter_obj *pao,
1316 struct hpi_message *phm, struct hpi_response *phr)
1317{
1318 struct hpi_hw_obj *phw = pao->priv;
1319 struct bus_master_interface *interface = phw->p_interface_buffer;
1320 struct hpi_hostbuffer_status *status;
1321 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1322 hw_message(pao, phm, phr);
1323 return;
1324 }
1325
1326 status = &interface->instream_host_buffer_status[phm->obj_index];
1327
1328 hpi_init_response(phr, phm->object, phm->function, 0);
1329
1330 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1331 phr->u.d.u.stream_info.samples_transferred =
1332 status->samples_processed;
1333 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1334 phr->u.d.u.stream_info.data_available =
1335 instream_get_bytes_available(status);
1336 phr->u.d.u.stream_info.auxiliary_data_available =
1337 status->auxiliary_data_available;
1338}
1339
1340/*****************************************************************************/
1341/* LOW-LEVEL */
1342#define HPI6205_MAX_FILES_TO_LOAD 2
1343
1344static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1345 u32 *pos_error_code)
1346{
1347 struct hpi_hw_obj *phw = pao->priv;
1348 struct dsp_code dsp_code;
1349 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1350 u16 firmware_id = pao->pci.subsys_device_id;
1351 u32 temp;
1352 int dsp = 0, i = 0;
1353 u16 err = 0;
1354
1355 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1356
1357 /* special cases where firmware_id != subsys ID */
1358 switch (firmware_id) {
1359 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1360 boot_code_id[0] = firmware_id;
1361 firmware_id = 0;
1362 break;
1363 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1364 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1365 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1366 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1367 break;
1368 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1369 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1370 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1371 break;
1372 }
1373 boot_code_id[1] = firmware_id;
1374
1375 /* reset DSP by writing a 1 to the WARMRESET bit */
1376 temp = C6205_HDCR_WARMRESET;
1377 iowrite32(temp, phw->prHDCR);
1378 hpios_delay_micro_seconds(1000);
1379
1380 /* check that PCI i/f was configured by EEPROM */
1381 temp = ioread32(phw->prHSR);
1382 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1383 C6205_HSR_EEREAD)
1384 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1385 temp |= 0x04;
1386 /* disable PINTA interrupt */
1387 iowrite32(temp, phw->prHSR);
1388
1389 /* check control register reports PCI boot mode */
1390 temp = ioread32(phw->prHDCR);
1391 if (!(temp & C6205_HDCR_PCIBOOT))
1392 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1393
1394 /* try writing a couple of numbers to the DSP page register */
1395 /* and reading them back. */
1396 temp = 1;
1397 iowrite32(temp, phw->prDSPP);
1398 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1399 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1400 temp = 2;
1401 iowrite32(temp, phw->prDSPP);
1402 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1403 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1404 temp = 3;
1405 iowrite32(temp, phw->prDSPP);
1406 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1408 /* reset DSP page to the correct number */
1409 temp = 0;
1410 iowrite32(temp, phw->prDSPP);
1411 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1412 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1413 phw->dsp_page = 0;
1414
1415 /* release 6713 from reset before 6205 is bootloaded.
1416 This ensures that the EMIF is inactive,
1417 and the 6713 HPI gets the correct bootmode etc
1418 */
1419 if (boot_code_id[1] != 0) {
1420 /* DSP 1 is a C6713 */
1421 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1422 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1423 hpios_delay_micro_seconds(100);
1424 /* Reset the 6713 #1 - revB */
1425 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1426
1427 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1428 boot_loader_read_mem32(pao, 0, 0);
1429
1430 hpios_delay_micro_seconds(100);
1431 /* Release C6713 from reset - revB */
1432 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1433 hpios_delay_micro_seconds(100);
1434 }
1435
1436 for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1437 /* is there a DSP to load? */
1438 if (boot_code_id[dsp] == 0)
1439 continue;
1440
1441 err = boot_loader_config_emif(pao, dsp);
1442 if (err)
1443 return err;
1444
1445 err = boot_loader_test_internal_memory(pao, dsp);
1446 if (err)
1447 return err;
1448
1449 err = boot_loader_test_external_memory(pao, dsp);
1450 if (err)
1451 return err;
1452
1453 err = boot_loader_test_pld(pao, dsp);
1454 if (err)
1455 return err;
1456
1457 /* write the DSP code down into the DSPs memory */
1458 dsp_code.ps_dev = pao->pci.p_os_data;
1459 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1460 pos_error_code);
1461 if (err)
1462 return err;
1463
1464 while (1) {
1465 u32 length;
1466 u32 address;
1467 u32 type;
1468 u32 *pcode;
1469
1470 err = hpi_dsp_code_read_word(&dsp_code, &length);
1471 if (err)
1472 break;
1473 if (length == 0xFFFFFFFF)
1474 break; /* end of code */
1475
1476 err = hpi_dsp_code_read_word(&dsp_code, &address);
1477 if (err)
1478 break;
1479 err = hpi_dsp_code_read_word(&dsp_code, &type);
1480 if (err)
1481 break;
1482 err = hpi_dsp_code_read_block(length, &dsp_code,
1483 &pcode);
1484 if (err)
1485 break;
1486 for (i = 0; i < (int)length; i++) {
1487 err = boot_loader_write_mem32(pao, dsp,
1488 address, *pcode);
1489 if (err)
1490 break;
1491 /* dummy read every 4 words */
1492 /* for 6205 advisory 1.4.4 */
1493 if (i % 4 == 0)
1494 boot_loader_read_mem32(pao, dsp,
1495 address);
1496 pcode++;
1497 address += 4;
1498 }
1499
1500 }
1501 if (err) {
1502 hpi_dsp_code_close(&dsp_code);
1503 return err;
1504 }
1505
1506 /* verify code */
1507 hpi_dsp_code_rewind(&dsp_code);
1508 while (1) {
1509 u32 length = 0;
1510 u32 address = 0;
1511 u32 type = 0;
1512 u32 *pcode = NULL;
1513 u32 data = 0;
1514
1515 hpi_dsp_code_read_word(&dsp_code, &length);
1516 if (length == 0xFFFFFFFF)
1517 break; /* end of code */
1518
1519 hpi_dsp_code_read_word(&dsp_code, &address);
1520 hpi_dsp_code_read_word(&dsp_code, &type);
1521 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1522
1523 for (i = 0; i < (int)length; i++) {
1524 data = boot_loader_read_mem32(pao, dsp,
1525 address);
1526 if (data != *pcode) {
1527 err = 0;
1528 break;
1529 }
1530 pcode++;
1531 address += 4;
1532 }
1533 if (err)
1534 break;
1535 }
1536 hpi_dsp_code_close(&dsp_code);
1537 if (err)
1538 return err;
1539 }
1540
1541 /* After bootloading all DSPs, start DSP0 running
1542 * The DSP0 code will handle starting and synchronizing with its slaves
1543 */
1544 if (phw->p_interface_buffer) {
1545 /* we need to tell the card the physical PCI address */
1546 u32 physicalPC_iaddress;
1547 struct bus_master_interface *interface =
1548 phw->p_interface_buffer;
1549 u32 host_mailbox_address_on_dsp;
1550 u32 physicalPC_iaddress_verify = 0;
1551 int time_out = 10;
1552 /* set ack so we know when DSP is ready to go */
1553 /* (dwDspAck will be changed to HIF_RESET) */
1554 interface->dsp_ack = H620_HIF_UNKNOWN;
1555 wmb(); /* ensure ack is written before dsp writes back */
1556
1557 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1558 &physicalPC_iaddress);
1559
1560 /* locate the host mailbox on the DSP. */
1561 host_mailbox_address_on_dsp = 0x80000000;
1562 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1563 && time_out--) {
1564 err = boot_loader_write_mem32(pao, 0,
1565 host_mailbox_address_on_dsp,
1566 physicalPC_iaddress);
1567 physicalPC_iaddress_verify =
1568 boot_loader_read_mem32(pao, 0,
1569 host_mailbox_address_on_dsp);
1570 }
1571 }
1572 HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1573 /* enable interrupts */
1574 temp = ioread32(phw->prHSR);
1575 temp &= ~(u32)C6205_HSR_INTAM;
1576 iowrite32(temp, phw->prHSR);
1577
1578 /* start code running... */
1579 temp = ioread32(phw->prHDCR);
1580 temp |= (u32)C6205_HDCR_DSPINT;
1581 iowrite32(temp, phw->prHDCR);
1582
1583 /* give the DSP 10ms to start up */
1584 hpios_delay_micro_seconds(10000);
1585 return err;
1586
1587}
1588
1589/*****************************************************************************/
1590/* Bootloader utility functions */
1591
1592static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1593 u32 address)
1594{
1595 struct hpi_hw_obj *phw = pao->priv;
1596 u32 data = 0;
1597 __iomem u32 *p_data;
1598
1599 if (dsp_index == 0) {
1600 /* DSP 0 is always C6205 */
1601 if ((address >= 0x01800000) & (address < 0x02000000)) {
1602 /* BAR1 register access */
1603 p_data = pao->pci.ap_mem_base[1] +
1604 (address & 0x007fffff) /
1605 sizeof(*pao->pci.ap_mem_base[1]);
1606 /* HPI_DEBUG_LOG(WARNING,
1607 "BAR1 access %08x\n", dwAddress); */
1608 } else {
1609 u32 dw4M_page = address >> 22L;
1610 if (dw4M_page != phw->dsp_page) {
1611 phw->dsp_page = dw4M_page;
1612 /* *INDENT OFF* */
1613 iowrite32(phw->dsp_page, phw->prDSPP);
1614 /* *INDENT-ON* */
1615 }
1616 address &= 0x3fffff; /* address within 4M page */
1617 /* BAR0 memory access */
1618 p_data = pao->pci.ap_mem_base[0] +
1619 address / sizeof(u32);
1620 }
1621 data = ioread32(p_data);
1622 } else if (dsp_index == 1) {
1623 /* DSP 1 is a C6713 */
1624 u32 lsb;
1625 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1626 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1627 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1628 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1629 data = (data << 16) | (lsb & 0xFFFF);
1630 }
1631 return data;
1632}
1633
1634static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1635 u32 address, u32 data)
1636{
1637 struct hpi_hw_obj *phw = pao->priv;
1638 u16 err = 0;
1639 __iomem u32 *p_data;
1640 /* u32 dwVerifyData=0; */
1641
1642 if (dsp_index == 0) {
1643 /* DSP 0 is always C6205 */
1644 if ((address >= 0x01800000) & (address < 0x02000000)) {
1645 /* BAR1 - DSP register access using */
1646 /* Non-prefetchable PCI access */
1647 p_data = pao->pci.ap_mem_base[1] +
1648 (address & 0x007fffff) /
1649 sizeof(*pao->pci.ap_mem_base[1]);
1650 } else {
1651 /* BAR0 access - all of DSP memory using */
1652 /* pre-fetchable PCI access */
1653 u32 dw4M_page = address >> 22L;
1654 if (dw4M_page != phw->dsp_page) {
1655 phw->dsp_page = dw4M_page;
1656 /* *INDENT-OFF* */
1657 iowrite32(phw->dsp_page, phw->prDSPP);
1658 /* *INDENT-ON* */
1659 }
1660 address &= 0x3fffff; /* address within 4M page */
1661 p_data = pao->pci.ap_mem_base[0] +
1662 address / sizeof(u32);
1663 }
1664 iowrite32(data, p_data);
1665 } else if (dsp_index == 1) {
1666 /* DSP 1 is a C6713 */
1667 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1668 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1669
1670 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1671 boot_loader_read_mem32(pao, 0, 0);
1672
1673 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1674 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1675
1676 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1677 boot_loader_read_mem32(pao, 0, 0);
1678 } else
1679 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1680 return err;
1681}
1682
1683static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1684{
1685 u16 err = 0;
1686
1687 if (dsp_index == 0) {
1688 u32 setting;
1689
1690 /* DSP 0 is always C6205 */
1691
1692 /* Set the EMIF */
1693 /* memory map of C6205 */
1694 /* 00000000-0000FFFF 16Kx32 internal program */
1695 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1696
1697 /* EMIF config */
1698 /*------------ */
1699 /* Global EMIF control */
1700 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1701#define WS_OFS 28
1702#define WST_OFS 22
1703#define WH_OFS 20
1704#define RS_OFS 16
1705#define RST_OFS 8
1706#define MTYPE_OFS 4
1707#define RH_OFS 0
1708
1709 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1710 setting = 0x00000030;
1711 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1712 if (setting != boot_loader_read_mem32(pao, dsp_index,
1713 0x01800008))
1714 return hpi6205_error(dsp_index,
1715 HPI6205_ERROR_DSP_EMIF);
1716
1717 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1718 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1719 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1720 /* WST should be 71, but 63 is max possible */
1721 setting =
1722 (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1723 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1724 (2L << MTYPE_OFS);
1725 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1726 if (setting != boot_loader_read_mem32(pao, dsp_index,
1727 0x01800004))
1728 return hpi6205_error(dsp_index,
1729 HPI6205_ERROR_DSP_EMIF);
1730
1731 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1732 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1733 /* plenty of wait states */
1734 setting =
1735 (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1736 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1737 (2L << MTYPE_OFS);
1738 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1739 if (setting != boot_loader_read_mem32(pao, dsp_index,
1740 0x01800010))
1741 return hpi6205_error(dsp_index,
1742 HPI6205_ERROR_DSP_EMIF);
1743
1744 /* EMIF CE3 setup - 32 bit async. */
1745 /* This is the PLD on the ASI5000 cards only */
1746 setting =
1747 (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1748 (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1749 (2L << MTYPE_OFS);
1750 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1751 if (setting != boot_loader_read_mem32(pao, dsp_index,
1752 0x01800014))
1753 return hpi6205_error(dsp_index,
1754 HPI6205_ERROR_DSP_EMIF);
1755
1756 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1757 /* need to use this else DSP code crashes? */
1758 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1759 0x07117000);
1760
1761 /* EMIF SDRAM Refresh Timing */
1762 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1763 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1764 0x00000410);
1765
1766 } else if (dsp_index == 1) {
1767 /* test access to the C6713s HPI registers */
1768 u32 write_data = 0, read_data = 0, i = 0;
1769
1770 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1771 write_data = 1;
1772 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1773 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1774 /* C67 HPI is on lower 16bits of 32bit EMIF */
1775 read_data =
1776 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1777 if (write_data != read_data) {
1778 err = hpi6205_error(dsp_index,
1779 HPI6205_ERROR_C6713_HPIC);
1780 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1781 read_data);
1782
1783 return err;
1784 }
1785 /* HPIA - walking ones test */
1786 write_data = 1;
1787 for (i = 0; i < 32; i++) {
1788 boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1789 write_data);
1790 boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1791 (write_data >> 16));
1792 read_data =
1793 0xFFFF & boot_loader_read_mem32(pao, 0,
1794 HPIAL_ADDR);
1795 read_data =
1796 read_data | ((0xFFFF &
1797 boot_loader_read_mem32(pao, 0,
1798 HPIAH_ADDR))
1799 << 16);
1800 if (read_data != write_data) {
1801 err = hpi6205_error(dsp_index,
1802 HPI6205_ERROR_C6713_HPIA);
1803 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1804 write_data, read_data);
1805 return err;
1806 }
1807 write_data = write_data << 1;
1808 }
1809
1810 /* setup C67x PLL
1811 * ** C6713 datasheet says we cannot program PLL from HPI,
1812 * and indeed if we try to set the PLL multiply from the HPI,
1813 * the PLL does not seem to lock, so we enable the PLL and
1814 * use the default multiply of x 7, which for a 27MHz clock
1815 * gives a DSP speed of 189MHz
1816 */
1817 /* bypass PLL */
1818 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1819 hpios_delay_micro_seconds(1000);
1820 /* EMIF = 189/3=63MHz */
1821 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1822 /* peri = 189/2 */
1823 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1824 /* cpu = 189/1 */
1825 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1826 hpios_delay_micro_seconds(1000);
1827 /* ** SGT test to take GPO3 high when we start the PLL */
1828 /* and low when the delay is completed */
1829 /* FSX0 <- '1' (GPO3) */
1830 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1831 /* PLL not bypassed */
1832 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1833 hpios_delay_micro_seconds(1000);
1834 /* FSX0 <- '0' (GPO3) */
1835 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1836
1837 /* 6205 EMIF CE1 resetup - 32 bit async. */
1838 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1839 boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
1840 (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1841 (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1842 (2L << MTYPE_OFS));
1843
1844 hpios_delay_micro_seconds(1000);
1845
1846 /* check that we can read one of the PLL registers */
1847 /* PLL should not be bypassed! */
1848 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1849 != 0x0001) {
1850 err = hpi6205_error(dsp_index,
1851 HPI6205_ERROR_C6713_PLL);
1852 return err;
1853 }
1854 /* setup C67x EMIF (note this is the only use of
1855 BAR1 via BootLoader_WriteMem32) */
1856 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1857 0x000034A8);
1858 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1859 0x00000030);
1860 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1861 0x001BDF29);
1862 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1863 0x47117000);
1864 boot_loader_write_mem32(pao, dsp_index,
1865 C6713_EMIF_SDRAMTIMING, 0x00000410);
1866
1867 hpios_delay_micro_seconds(1000);
1868 } else if (dsp_index == 2) {
1869 /* DSP 2 is a C6713 */
1870
1871 } else
1872 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1873 return err;
1874}
1875
1876static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1877 u32 start_address, u32 length)
1878{
1879 u32 i = 0, j = 0;
1880 u32 test_addr = 0;
1881 u32 test_data = 0, data = 0;
1882
1883 length = 1000;
1884
1885 /* for 1st word, test each bit in the 32bit word, */
1886 /* dwLength specifies number of 32bit words to test */
1887 /*for(i=0; i<dwLength; i++) */
1888 i = 0;
1889 {
1890 test_addr = start_address + i * 4;
1891 test_data = 0x00000001;
1892 for (j = 0; j < 32; j++) {
1893 boot_loader_write_mem32(pao, dsp_index, test_addr,
1894 test_data);
1895 data = boot_loader_read_mem32(pao, dsp_index,
1896 test_addr);
1897 if (data != test_data) {
1898 HPI_DEBUG_LOG(VERBOSE,
1899 "memtest error details "
1900 "%08x %08x %08x %i\n", test_addr,
1901 test_data, data, dsp_index);
1902 return 1; /* error */
1903 }
1904 test_data = test_data << 1;
1905 } /* for(j) */
1906 } /* for(i) */
1907
1908 /* for the next 100 locations test each location, leaving it as zero */
1909 /* write a zero to the next word in memory before we read */
1910 /* the previous write to make sure every memory location is unique */
1911 for (i = 0; i < 100; i++) {
1912 test_addr = start_address + i * 4;
1913 test_data = 0xA5A55A5A;
1914 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1915 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1916 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1917 if (data != test_data) {
1918 HPI_DEBUG_LOG(VERBOSE,
1919 "memtest error details "
1920 "%08x %08x %08x %i\n", test_addr, test_data,
1921 data, dsp_index);
1922 return 1; /* error */
1923 }
1924 /* leave location as zero */
1925 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1926 }
1927
1928 /* zero out entire memory block */
1929 for (i = 0; i < length; i++) {
1930 test_addr = start_address + i * 4;
1931 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1932 }
1933 return 0;
1934}
1935
1936static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1937 int dsp_index)
1938{
1939 int err = 0;
1940 if (dsp_index == 0) {
1941 /* DSP 0 is a C6205 */
1942 /* 64K prog mem */
1943 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1944 0x10000);
1945 if (!err)
1946 /* 64K data mem */
1947 err = boot_loader_test_memory(pao, dsp_index,
1948 0x80000000, 0x10000);
1949 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1950 /* DSP 1&2 are a C6713 */
1951 /* 192K internal mem */
1952 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1953 0x30000);
1954 if (!err)
1955 /* 64K internal mem / L2 cache */
1956 err = boot_loader_test_memory(pao, dsp_index,
1957 0x00030000, 0x10000);
1958 } else
1959 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1960
1961 if (err)
1962 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1963 else
1964 return 0;
1965}
1966
1967static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1968 int dsp_index)
1969{
1970 u32 dRAM_start_address = 0;
1971 u32 dRAM_size = 0;
1972
1973 if (dsp_index == 0) {
1974 /* only test for SDRAM if an ASI5000 card */
1975 if (pao->pci.subsys_device_id == 0x5000) {
1976 /* DSP 0 is always C6205 */
1977 dRAM_start_address = 0x00400000;
1978 dRAM_size = 0x200000;
1979 /*dwDRAMinc=1024; */
1980 } else
1981 return 0;
1982 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1983 /* DSP 1 is a C6713 */
1984 dRAM_start_address = 0x80000000;
1985 dRAM_size = 0x200000;
1986 /*dwDRAMinc=1024; */
1987 } else
1988 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1989
1990 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1991 dRAM_size))
1992 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1993 return 0;
1994}
1995
1996static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1997{
1998 u32 data = 0;
1999 if (dsp_index == 0) {
2000 /* only test for DSP0 PLD on ASI5000 card */
2001 if (pao->pci.subsys_device_id == 0x5000) {
2002 /* PLD is located at CE3=0x03000000 */
2003 data = boot_loader_read_mem32(pao, dsp_index,
2004 0x03000008);
2005 if ((data & 0xF) != 0x5)
2006 return hpi6205_error(dsp_index,
2007 HPI6205_ERROR_DSP_PLD);
2008 data = boot_loader_read_mem32(pao, dsp_index,
2009 0x0300000C);
2010 if ((data & 0xF) != 0xA)
2011 return hpi6205_error(dsp_index,
2012 HPI6205_ERROR_DSP_PLD);
2013 }
2014 } else if (dsp_index == 1) {
2015 /* DSP 1 is a C6713 */
2016 if (pao->pci.subsys_device_id == 0x8700) {
2017 /* PLD is located at CE1=0x90000000 */
2018 data = boot_loader_read_mem32(pao, dsp_index,
2019 0x90000010);
2020 if ((data & 0xFF) != 0xAA)
2021 return hpi6205_error(dsp_index,
2022 HPI6205_ERROR_DSP_PLD);
2023 /* 8713 - LED on */
2024 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2025 0x02);
2026 }
2027 }
2028 return 0;
2029}
2030
2031/** Transfer data to or from DSP
2032 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2033*/
2034static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2035 u32 data_size, int operation)
2036{
2037 struct hpi_hw_obj *phw = pao->priv;
2038 u32 data_transferred = 0;
2039 u16 err = 0;
2040#ifndef HPI6205_NO_HSR_POLL
2041 u32 time_out;
2042#endif
2043 u32 temp2;
2044 struct bus_master_interface *interface = phw->p_interface_buffer;
2045
2046 if (!p_data)
2047 return HPI_ERROR_INVALID_DATA_TRANSFER;
2048
2049 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2050
2051 /* make sure state is IDLE */
2052 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2053 return HPI_ERROR_DSP_HARDWARE;
2054
2055 while (data_transferred < data_size) {
2056 u32 this_copy = data_size - data_transferred;
2057
2058 if (this_copy > HPI6205_SIZEOF_DATA)
2059 this_copy = HPI6205_SIZEOF_DATA;
2060
2061 if (operation == H620_HIF_SEND_DATA)
2062 memcpy((void *)&interface->u.b_data[0],
2063 &p_data[data_transferred], this_copy);
2064
2065 interface->transfer_size_in_bytes = this_copy;
2066
2067#ifdef HPI6205_NO_HSR_POLL
2068 /* DSP must change this back to nOperation */
2069 interface->dsp_ack = H620_HIF_IDLE;
2070#endif
2071
2072 send_dsp_command(phw, operation);
2073
2074#ifdef HPI6205_NO_HSR_POLL
2075 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2076 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2077 HPI6205_TIMEOUT - temp2, this_copy);
2078
2079 if (!temp2) {
2080 /* timed out */
2081 HPI_DEBUG_LOG(ERROR,
2082 "timed out waiting for " "state %d got %d\n",
2083 operation, interface->dsp_ack);
2084
2085 break;
2086 }
2087#else
2088 /* spin waiting on the result */
2089 time_out = HPI6205_TIMEOUT;
2090 temp2 = 0;
2091 while ((temp2 == 0) && time_out--) {
2092 /* give 16k bus mastering transfer time to happen */
2093 /*(16k / 132Mbytes/s = 122usec) */
2094 hpios_delay_micro_seconds(20);
2095 temp2 = ioread32(phw->prHSR);
2096 temp2 &= C6205_HSR_INTSRC;
2097 }
2098 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2099 HPI6205_TIMEOUT - time_out, this_copy);
2100 if (temp2 == C6205_HSR_INTSRC) {
2101 HPI_DEBUG_LOG(VERBOSE,
2102 "interrupt from HIF <data> OK\n");
2103 /*
2104 if(interface->dwDspAck != nOperation) {
2105 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2106 expected %d \n",
2107 interface->dwDspAck,nOperation);
2108 }
2109 */
2110 }
2111/* need to handle this differently... */
2112 else {
2113 HPI_DEBUG_LOG(ERROR,
2114 "interrupt from HIF <data> BAD\n");
2115 err = HPI_ERROR_DSP_HARDWARE;
2116 }
2117
2118 /* reset the interrupt from the DSP */
2119 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2120#endif
2121 if (operation == H620_HIF_GET_DATA)
2122 memcpy(&p_data[data_transferred],
2123 (void *)&interface->u.b_data[0], this_copy);
2124
2125 data_transferred += this_copy;
2126 }
2127 if (interface->dsp_ack != operation)
2128 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2129 interface->dsp_ack, operation);
2130 /* err=HPI_ERROR_DSP_HARDWARE; */
2131
2132 send_dsp_command(phw, H620_HIF_IDLE);
2133
2134 return err;
2135}
2136
2137/* wait for up to timeout_us microseconds for the DSP
2138 to signal state by DMA into dwDspAck
2139*/
2140static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2141{
2142 struct bus_master_interface *interface = phw->p_interface_buffer;
2143 int t = timeout_us / 4;
2144
2145 rmb(); /* ensure interface->dsp_ack is up to date */
2146 while ((interface->dsp_ack != state) && --t) {
2147 hpios_delay_micro_seconds(4);
2148 rmb(); /* DSP changes dsp_ack by DMA */
2149 }
2150
2151 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2152 return t * 4;
2153}
2154
2155/* set the busmaster interface to cmd, then interrupt the DSP */
2156static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2157{
2158 struct bus_master_interface *interface = phw->p_interface_buffer;
2159
2160 u32 r;
2161
2162 interface->host_cmd = cmd;
2163 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2164 /* before we interrupt the DSP */
2165 r = ioread32(phw->prHDCR);
2166 r |= (u32)C6205_HDCR_DSPINT;
2167 iowrite32(r, phw->prHDCR);
2168 r &= ~(u32)C6205_HDCR_DSPINT;
2169 iowrite32(r, phw->prHDCR);
2170}
2171
2172static unsigned int message_count;
2173
2174static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2175 struct hpi_message *phm, struct hpi_response *phr)
2176{
2177#ifndef HPI6205_NO_HSR_POLL
2178 u32 temp2;
2179#endif
2180 u32 time_out, time_out2;
2181 struct hpi_hw_obj *phw = pao->priv;
2182 struct bus_master_interface *interface = phw->p_interface_buffer;
2183 u16 err = 0;
2184
2185 message_count++;
2186 /* Assume buffer of type struct bus_master_interface
2187 is allocated "noncacheable" */
2188
2189 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2190 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2191 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2192 }
2193 interface->u.message_buffer = *phm;
2194 /* signal we want a response */
2195 send_dsp_command(phw, H620_HIF_GET_RESP);
2196
2197 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2198
2199 if (time_out2 == 0) {
2200 HPI_DEBUG_LOG(ERROR,
2201 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2202 message_count, interface->dsp_ack);
2203 } else {
2204 HPI_DEBUG_LOG(VERBOSE,
2205 "(%u) transition to GET_RESP after %u\n",
2206 message_count, HPI6205_TIMEOUT - time_out2);
2207 }
2208 /* spin waiting on HIF interrupt flag (end of msg process) */
2209 time_out = HPI6205_TIMEOUT;
2210
2211#ifndef HPI6205_NO_HSR_POLL
2212 temp2 = 0;
2213 while ((temp2 == 0) && --time_out) {
2214 temp2 = ioread32(phw->prHSR);
2215 temp2 &= C6205_HSR_INTSRC;
2216 hpios_delay_micro_seconds(1);
2217 }
2218 if (temp2 == C6205_HSR_INTSRC) {
2219 rmb(); /* ensure we see latest value for dsp_ack */
2220 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2221 HPI_DEBUG_LOG(DEBUG,
2222 "(%u)interface->dsp_ack(0x%x) != "
2223 "H620_HIF_GET_RESP, t=%u\n", message_count,
2224 interface->dsp_ack,
2225 HPI6205_TIMEOUT - time_out);
2226 } else {
2227 HPI_DEBUG_LOG(VERBOSE,
2228 "(%u)int with GET_RESP after %u\n",
2229 message_count, HPI6205_TIMEOUT - time_out);
2230 }
2231
2232 } else {
2233 /* can we do anything else in response to the error ? */
2234 HPI_DEBUG_LOG(ERROR,
2235 "interrupt from HIF module BAD (function %x)\n",
2236 phm->function);
2237 }
2238
2239 /* reset the interrupt from the DSP */
2240 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2241#endif
2242
2243 /* read the result */
2244 if (time_out != 0)
2245 *phr = interface->u.response_buffer;
2246
2247 /* set interface back to idle */
2248 send_dsp_command(phw, H620_HIF_IDLE);
2249
2250 if ((time_out == 0) || (time_out2 == 0)) {
2251 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2252 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2253 }
2254 /* special case for adapter close - */
2255 /* wait for the DSP to indicate it is idle */
2256 if (phm->function == HPI_ADAPTER_CLOSE) {
2257 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2258 HPI_DEBUG_LOG(DEBUG,
2259 "timeout waiting for idle "
2260 "(on adapter_close)\n");
2261 return hpi6205_error(0,
2262 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2263 }
2264 }
2265 err = hpi_validate_response(phm, phr);
2266 return err;
2267}
2268
2269static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2270 struct hpi_response *phr)
2271{
2272
2273 u16 err = 0;
2274
2275 hpios_dsplock_lock(pao);
2276
2277 err = message_response_sequence(pao, phm, phr);
2278
2279 /* maybe an error response */
2280 if (err) {
2281 /* something failed in the HPI/DSP interface */
2282 phr->error = err;
2283 pao->dsp_crashed++;
2284
2285 /* just the header of the response is valid */
2286 phr->size = sizeof(struct hpi_response_header);
2287 goto err;
2288 } else
2289 pao->dsp_crashed = 0;
2290
2291 if (phr->error != 0) /* something failed in the DSP */
2292 goto err;
2293
2294 switch (phm->function) {
2295 case HPI_OSTREAM_WRITE:
2296 case HPI_ISTREAM_ANC_WRITE:
2297 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2298 phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2299 break;
2300
2301 case HPI_ISTREAM_READ:
2302 case HPI_OSTREAM_ANC_READ:
2303 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2304 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2305 break;
2306
2307 case HPI_CONTROL_SET_STATE:
2308 if (phm->object == HPI_OBJ_CONTROLEX
2309 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2310 err = hpi6205_transfer_data(pao,
2311 phm->u.cx.u.cobranet_bigdata.pb_data,
2312 phm->u.cx.u.cobranet_bigdata.byte_count,
2313 H620_HIF_SEND_DATA);
2314 break;
2315
2316 case HPI_CONTROL_GET_STATE:
2317 if (phm->object == HPI_OBJ_CONTROLEX
2318 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2319 err = hpi6205_transfer_data(pao,
2320 phm->u.cx.u.cobranet_bigdata.pb_data,
2321 phr->u.cx.u.cobranet_data.byte_count,
2322 H620_HIF_GET_DATA);
2323 break;
2324 }
2325 phr->error = err;
2326
2327err:
2328 hpios_dsplock_unlock(pao);
2329
2330 return;
2331}
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
new file mode 100644
index 000000000000..1adae0857cda
--- /dev/null
+++ b/sound/pci/asihpi/hpi6205.h
@@ -0,0 +1,93 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Host Interface module for an ASI6205 based
20bus mastering PCI adapter.
21
22Copyright AudioScience, Inc., 2003
23******************************************************************************/
24
25#ifndef _HPI6205_H_
26#define _HPI6205_H_
27
28/* transitional conditional compile shared between host and DSP */
29/* #define HPI6205_NO_HSR_POLL */
30
31#include "hpi_internal.h"
32
33/***********************************************************
34 Defines used for basic messaging
35************************************************************/
36#define H620_HIF_RESET 0
37#define H620_HIF_IDLE 1
38#define H620_HIF_GET_RESP 2
39#define H620_HIF_DATA_DONE 3
40#define H620_HIF_DATA_MASK 0x10
41#define H620_HIF_SEND_DATA 0x14
42#define H620_HIF_GET_DATA 0x15
43#define H620_HIF_UNKNOWN 0x0000ffff
44
45/***********************************************************
46 Types used for mixer control caching
47************************************************************/
48
49#define H620_MAX_ISTREAMS 32
50#define H620_MAX_OSTREAMS 32
51#define HPI_NMIXER_CONTROLS 2048
52
53/*********************************************************************
54This is used for dynamic control cache allocation
55**********************************************************************/
56struct controlcache_6205 {
57 u32 number_of_controls;
58 u32 physical_address32;
59 u32 size_in_bytes;
60};
61
62/*********************************************************************
63This is used for dynamic allocation of async event array
64**********************************************************************/
65struct async_event_buffer_6205 {
66 u32 physical_address32;
67 u32 spare;
68 struct hpi_fifo_buffer b;
69};
70
71/***********************************************************
72The Host located memory buffer that the 6205 will bus master
73in and out of.
74************************************************************/
75#define HPI6205_SIZEOF_DATA (16*1024)
76struct bus_master_interface {
77 u32 host_cmd;
78 u32 dsp_ack;
79 u32 transfer_size_in_bytes;
80 union {
81 struct hpi_message message_buffer;
82 struct hpi_response response_buffer;
83 u8 b_data[HPI6205_SIZEOF_DATA];
84 } u;
85 struct controlcache_6205 control_cache;
86 struct async_event_buffer_6205 async_buffer;
87 struct hpi_hostbuffer_status
88 instream_host_buffer_status[H620_MAX_ISTREAMS];
89 struct hpi_hostbuffer_status
90 outstream_host_buffer_status[H620_MAX_OSTREAMS];
91};
92
93#endif
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
new file mode 100644
index 000000000000..f1cd6f1a0d44
--- /dev/null
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -0,0 +1,1641 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI internal definitions
20
21(C) Copyright AudioScience Inc. 1996-2009
22******************************************************************************/
23
24#ifndef _HPI_INTERNAL_H_
25#define _HPI_INTERNAL_H_
26
27#include "hpi.h"
28/** maximum number of memory regions mapped to an adapter */
29#define HPI_MAX_ADAPTER_MEM_SPACES (2)
30
31/* Each OS needs its own hpios.h, or specific define as above */
32#include "hpios.h"
33
34/* physical memory allocation */
35void hpios_locked_mem_init(void
36 );
37void hpios_locked_mem_free_all(void
38 );
39#define hpios_locked_mem_prepare(a, b, c, d);
40#define hpios_locked_mem_unprepare(a)
41
42/** Allocate and map an area of locked memory for bus master DMA operations.
43
44On success, *pLockedMemeHandle is a valid handle, and 0 is returned
45On error *pLockedMemHandle marked invalid, non-zero returned.
46
47If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and
48HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
51 /**< memory handle */
52 u32 size, /**< size in bytes to allocate */
53 struct pci_dev *p_os_reference
54 /**< OS specific data required for memory allocation */
55 );
56
57/** Free mapping and memory represented by LockedMemHandle
58
59Frees any resources, then invalidates the handle.
60Returns 0 on success, 1 if handle is invalid.
61
62*/
63u16 hpios_locked_mem_free(struct consistent_dma_area *locked_mem_handle);
64
65/** Get the physical PCI address of memory represented by LockedMemHandle.
66
67If handle is invalid *pPhysicalAddr is set to zero and return 1
68*/
69u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
70 *locked_mem_handle, u32 *p_physical_addr);
71
72/** Get the CPU address of of memory represented by LockedMemHandle.
73
74If handle is NULL *ppvVirtualAddr is set to NULL and return 1
75*/
76u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
77 *locked_mem_handle, void **ppv_virtual_addr);
78
79/** Check that handle is valid
80i.e it represents a valid memory area
81*/
82u16 hpios_locked_mem_valid(struct consistent_dma_area *locked_mem_handle);
83
84/* timing/delay */
85void hpios_delay_micro_seconds(u32 num_micro_sec);
86
87struct hpi_message;
88struct hpi_response;
89
90typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
91
92/* If the assert fails, compiler complains
93 something like size of array `msg' is negative.
94 Unlike linux BUILD_BUG_ON, this works outside function scope.
95*/
96#define compile_time_assert(cond, msg) \
97 typedef char ASSERT_##msg[(cond) ? 1 : -1]
98
99/*/////////////////////////////////////////////////////////////////////////// */
100/* Private HPI Entity related definitions */
101
102#define STR_SIZE_FIELD_MAX 65535U
103#define STR_TYPE_FIELD_MAX 255U
104#define STR_ROLE_FIELD_MAX 255U
105
106struct hpi_entity_str {
107 uint16_t size;
108 uint8_t type;
109 uint8_t role;
110};
111
112#if defined(_MSC_VER)
113#pragma warning(push)
114#pragma warning(disable : 4200)
115#endif
116
117struct hpi_entity {
118 struct hpi_entity_str header;
119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
120 /* DSP C6000 compiler v6.0.8 and lower
121 do not support flexible array member */
122 uint8_t value[];
123#else
124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
126 uint8_t value[1];
127#endif
128};
129
130#if defined(_MSC_VER)
131#pragma warning(pop)
132#endif
133
134/******************************************* bus types */
135enum HPI_BUSES {
136 HPI_BUS_ISAPNP = 1,
137 HPI_BUS_PCI = 2,
138 HPI_BUS_USB = 3,
139 HPI_BUS_NET = 4
140};
141
142/******************************************* CONTROL ATTRIBUTES ****/
143/* (in order of control type ID */
144
145 /* This allows for 255 control types, 256 unique attributes each */
146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai)
147
148/* Get the sub-index of the attribute for a control type */
149#define HPI_CTL_ATTR_INDEX(i) (i&0xff)
150
151/* Generic control attributes. */
152
153/** Enable a control.
1540=disable, 1=enable
155\note generic to all mixer plugins?
156*/
157#define HPI_GENERIC_ENABLE HPI_CTL_ATTR(GENERIC, 1)
158
159/** Enable event generation for a control.
1600=disable, 1=enable
161\note generic to all controls that can generate events
162*/
163#define HPI_GENERIC_EVENT_ENABLE HPI_CTL_ATTR(GENERIC, 2)
164
165/* Volume Control attributes */
166#define HPI_VOLUME_GAIN HPI_CTL_ATTR(VOLUME, 1)
167#define HPI_VOLUME_AUTOFADE HPI_CTL_ATTR(VOLUME, 2)
168
169/** For HPI_ControlQuery() to get the number of channels of a volume control*/
170#define HPI_VOLUME_NUM_CHANNELS HPI_CTL_ATTR(VOLUME, 6)
171#define HPI_VOLUME_RANGE HPI_CTL_ATTR(VOLUME, 10)
172
173/** Level Control attributes */
174#define HPI_LEVEL_GAIN HPI_CTL_ATTR(LEVEL, 1)
175#define HPI_LEVEL_RANGE HPI_CTL_ATTR(LEVEL, 10)
176
177/* Meter Control attributes */
178/** return RMS signal level */
179#define HPI_METER_RMS HPI_CTL_ATTR(METER, 1)
180/** return peak signal level */
181#define HPI_METER_PEAK HPI_CTL_ATTR(METER, 2)
182/** ballistics for ALL rms meters on adapter */
183#define HPI_METER_RMS_BALLISTICS HPI_CTL_ATTR(METER, 3)
184/** ballistics for ALL peak meters on adapter */
185#define HPI_METER_PEAK_BALLISTICS HPI_CTL_ATTR(METER, 4)
186
187/** For HPI_ControlQuery() to get the number of channels of a meter control*/
188#define HPI_METER_NUM_CHANNELS HPI_CTL_ATTR(METER, 5)
189
190/* Multiplexer control attributes */
191#define HPI_MULTIPLEXER_SOURCE HPI_CTL_ATTR(MULTIPLEXER, 1)
192#define HPI_MULTIPLEXER_QUERYSOURCE HPI_CTL_ATTR(MULTIPLEXER, 2)
193
194/** AES/EBU transmitter control attributes */
195/** AESEBU or SPDIF */
196#define HPI_AESEBUTX_FORMAT HPI_CTL_ATTR(AESEBUTX, 1)
197#define HPI_AESEBUTX_SAMPLERATE HPI_CTL_ATTR(AESEBUTX, 3)
198#define HPI_AESEBUTX_CHANNELSTATUS HPI_CTL_ATTR(AESEBUTX, 4)
199#define HPI_AESEBUTX_USERDATA HPI_CTL_ATTR(AESEBUTX, 5)
200
201/** AES/EBU receiver control attributes */
202#define HPI_AESEBURX_FORMAT HPI_CTL_ATTR(AESEBURX, 1)
203#define HPI_AESEBURX_ERRORSTATUS HPI_CTL_ATTR(AESEBURX, 2)
204#define HPI_AESEBURX_SAMPLERATE HPI_CTL_ATTR(AESEBURX, 3)
205#define HPI_AESEBURX_CHANNELSTATUS HPI_CTL_ATTR(AESEBURX, 4)
206#define HPI_AESEBURX_USERDATA HPI_CTL_ATTR(AESEBURX, 5)
207
208/** \defgroup tuner_defs Tuners
209\{
210*/
211/** \defgroup tuner_attrs Tuner control attributes
212\{
213*/
214#define HPI_TUNER_BAND HPI_CTL_ATTR(TUNER, 1)
215#define HPI_TUNER_FREQ HPI_CTL_ATTR(TUNER, 2)
216#define HPI_TUNER_LEVEL HPI_CTL_ATTR(TUNER, 3)
217#define HPI_TUNER_AUDIOMUTE HPI_CTL_ATTR(TUNER, 4)
218/* use TUNER_STATUS instead */
219#define HPI_TUNER_VIDEO_STATUS HPI_CTL_ATTR(TUNER, 5)
220#define HPI_TUNER_GAIN HPI_CTL_ATTR(TUNER, 6)
221#define HPI_TUNER_STATUS HPI_CTL_ATTR(TUNER, 7)
222#define HPI_TUNER_MODE HPI_CTL_ATTR(TUNER, 8)
223/** RDS data. */
224#define HPI_TUNER_RDS HPI_CTL_ATTR(TUNER, 9)
225/** Audio pre-emphasis. */
226#define HPI_TUNER_DEEMPHASIS HPI_CTL_ATTR(TUNER, 10)
227/** HD Radio tuner program control. */
228#define HPI_TUNER_PROGRAM HPI_CTL_ATTR(TUNER, 11)
229/** HD Radio tuner digital signal quality. */
230#define HPI_TUNER_HDRADIO_SIGNAL_QUALITY HPI_CTL_ATTR(TUNER, 12)
231/** HD Radio SDK firmware version. */
232#define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13)
233/** HD Radio DSP firmware version. */
234#define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14)
235
236/** \} */
237
238/** \defgroup pads_attrs Tuner PADs control attributes
239\{
240*/
241/** The text string containing the station/channel combination. */
242#define HPI_PAD_CHANNEL_NAME HPI_CTL_ATTR(PAD, 1)
243/** The text string containing the artist. */
244#define HPI_PAD_ARTIST HPI_CTL_ATTR(PAD, 2)
245/** The text string containing the title. */
246#define HPI_PAD_TITLE HPI_CTL_ATTR(PAD, 3)
247/** The text string containing the comment. */
248#define HPI_PAD_COMMENT HPI_CTL_ATTR(PAD, 4)
249/** The integer containing the PTY code. */
250#define HPI_PAD_PROGRAM_TYPE HPI_CTL_ATTR(PAD, 5)
251/** The integer containing the program identification. */
252#define HPI_PAD_PROGRAM_ID HPI_CTL_ATTR(PAD, 6)
253/** The integer containing whether traffic information is supported.
254Contains either 1 or 0. */
255#define HPI_PAD_TA_SUPPORT HPI_CTL_ATTR(PAD, 7)
256/** The integer containing whether traffic announcement is in progress.
257Contains either 1 or 0. */
258#define HPI_PAD_TA_ACTIVE HPI_CTL_ATTR(PAD, 8)
259/** \} */
260/** \} */
261
262/* VOX control attributes */
263#define HPI_VOX_THRESHOLD HPI_CTL_ATTR(VOX, 1)
264
265/*?? channel mode used hpi_multiplexer_source attribute == 1 */
266#define HPI_CHANNEL_MODE_MODE HPI_CTL_ATTR(CHANNEL_MODE, 1)
267
268/** \defgroup channel_modes Channel Modes
269Used for HPI_ChannelModeSet/Get()
270\{
271*/
272/** Left channel out = left channel in, Right channel out = right channel in. */
273#define HPI_CHANNEL_MODE_NORMAL 1
274/** Left channel out = right channel in, Right channel out = left channel in. */
275#define HPI_CHANNEL_MODE_SWAP 2
276/** Left channel out = left channel in, Right channel out = left channel in. */
277#define HPI_CHANNEL_MODE_LEFT_TO_STEREO 3
278/** Left channel out = right channel in, Right channel out = right channel in.*/
279#define HPI_CHANNEL_MODE_RIGHT_TO_STEREO 4
280/** Left channel out = (left channel in + right channel in)/2,
281 Right channel out = mute. */
282#define HPI_CHANNEL_MODE_STEREO_TO_LEFT 5
283/** Left channel out = mute,
284 Right channel out = (right channel in + left channel in)/2. */
285#define HPI_CHANNEL_MODE_STEREO_TO_RIGHT 6
286#define HPI_CHANNEL_MODE_LAST 6
287/** \} */
288
289/* Bitstream control set attributes */
290#define HPI_BITSTREAM_DATA_POLARITY HPI_CTL_ATTR(BITSTREAM, 1)
291#define HPI_BITSTREAM_CLOCK_EDGE HPI_CTL_ATTR(BITSTREAM, 2)
292#define HPI_BITSTREAM_CLOCK_SOURCE HPI_CTL_ATTR(BITSTREAM, 3)
293
294#define HPI_POLARITY_POSITIVE 0
295#define HPI_POLARITY_NEGATIVE 1
296
297/* Bitstream control get attributes */
298#define HPI_BITSTREAM_ACTIVITY 1
299
300/* SampleClock control attributes */
301#define HPI_SAMPLECLOCK_SOURCE HPI_CTL_ATTR(SAMPLECLOCK, 1)
302#define HPI_SAMPLECLOCK_SAMPLERATE HPI_CTL_ATTR(SAMPLECLOCK, 2)
303#define HPI_SAMPLECLOCK_SOURCE_INDEX HPI_CTL_ATTR(SAMPLECLOCK, 3)
304#define HPI_SAMPLECLOCK_LOCAL_SAMPLERATE\
305 HPI_CTL_ATTR(SAMPLECLOCK, 4)
306#define HPI_SAMPLECLOCK_AUTO HPI_CTL_ATTR(SAMPLECLOCK, 5)
307#define HPI_SAMPLECLOCK_LOCAL_LOCK HPI_CTL_ATTR(SAMPLECLOCK, 6)
308
309/* Microphone control attributes */
310#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
311
312/** Equalizer control attributes
313*/
314/** Used to get number of filters in an EQ. (Can't set) */
315#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
316/** Set/get the filter by type, freq, Q, gain */
317#define HPI_EQUALIZER_FILTER HPI_CTL_ATTR(EQUALIZER, 2)
318/** Get the biquad coefficients */
319#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
320
321#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
322
323/* Cobranet control attributes.
324 MUST be distinct from all other control attributes.
325 This is so that host side processing can easily identify a Cobranet control
326 and apply additional host side operations (like copying data) as required.
327*/
328#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1)
329#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
330#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
331#define HPI_COBRANET_GET_DATA HPI_CTL_ATTR(COBRANET, 4)
332#define HPI_COBRANET_GET_STATUS HPI_CTL_ATTR(COBRANET, 5)
333#define HPI_COBRANET_SEND_PACKET HPI_CTL_ATTR(COBRANET, 6)
334#define HPI_COBRANET_GET_PACKET HPI_CTL_ATTR(COBRANET, 7)
335
336/*------------------------------------------------------------
337 Cobranet Chip Bridge - copied from HMI.H
338------------------------------------------------------------*/
339#define HPI_COBRANET_HMI_cobra_bridge 0x20000
340#define HPI_COBRANET_HMI_cobra_bridge_tx_pkt_buf \
341 (HPI_COBRANET_HMI_cobra_bridge + 0x1000)
342#define HPI_COBRANET_HMI_cobra_bridge_rx_pkt_buf \
343 (HPI_COBRANET_HMI_cobra_bridge + 0x2000)
344#define HPI_COBRANET_HMI_cobra_if_table1 0x110000
345#define HPI_COBRANET_HMI_cobra_if_phy_address \
346 (HPI_COBRANET_HMI_cobra_if_table1 + 0xd)
347#define HPI_COBRANET_HMI_cobra_protocolIP 0x72000
348#define HPI_COBRANET_HMI_cobra_ip_mon_currentIP \
349 (HPI_COBRANET_HMI_cobra_protocolIP + 0x0)
350#define HPI_COBRANET_HMI_cobra_ip_mon_staticIP \
351 (HPI_COBRANET_HMI_cobra_protocolIP + 0x2)
352#define HPI_COBRANET_HMI_cobra_sys 0x100000
353#define HPI_COBRANET_HMI_cobra_sys_desc \
354 (HPI_COBRANET_HMI_cobra_sys + 0x0)
355#define HPI_COBRANET_HMI_cobra_sys_objectID \
356 (HPI_COBRANET_HMI_cobra_sys + 0x100)
357#define HPI_COBRANET_HMI_cobra_sys_contact \
358 (HPI_COBRANET_HMI_cobra_sys + 0x200)
359#define HPI_COBRANET_HMI_cobra_sys_name \
360 (HPI_COBRANET_HMI_cobra_sys + 0x300)
361#define HPI_COBRANET_HMI_cobra_sys_location \
362 (HPI_COBRANET_HMI_cobra_sys + 0x400)
363
364/*------------------------------------------------------------
365 Cobranet Chip Status bits
366------------------------------------------------------------*/
367#define HPI_COBRANET_HMI_STATUS_RXPACKET 2
368#define HPI_COBRANET_HMI_STATUS_TXPACKET 3
369
370/*------------------------------------------------------------
371 Ethernet header size
372------------------------------------------------------------*/
373#define HPI_ETHERNET_HEADER_SIZE (16)
374
375/* These defines are used to fill in protocol information for an Ethernet packet
376 sent using HMI on CS18102 */
377/** ID supplied by Cirrius for ASI packets. */
378#define HPI_ETHERNET_PACKET_ID 0x85
379/** Simple packet - no special routing required */
380#define HPI_ETHERNET_PACKET_V1 0x01
381/** This packet must make its way to the host across the HPI interface */
382#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI 0x20
383/** This packet must make its way to the host across the HPI interface */
384#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI_V1 0x21
385/** This packet must make its way to the host across the HPI interface */
386#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI 0x40
387/** This packet must make its way to the host across the HPI interface */
388#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
389
390#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */
391
392/** Base network time out is set to 100 milli-seconds. */
393#define HPI_ETHERNET_TIMEOUT_MS (100)
394
395/** \defgroup tonedet_attr Tonedetector attributes
396\{
397Used by HPI_ToneDetector_Set() and HPI_ToneDetector_Get()
398*/
399
400/** Set the threshold level of a tonedetector,
401Threshold is a -ve number in units of dB/100,
402*/
403#define HPI_TONEDETECTOR_THRESHOLD HPI_CTL_ATTR(TONEDETECTOR, 1)
404
405/** Get the current state of tonedetection
406The result is a bitmap of detected tones. pairs of bits represent the left
407and right channels, with left channel in LSB.
408The lowest frequency detector state is in the LSB
409*/
410#define HPI_TONEDETECTOR_STATE HPI_CTL_ATTR(TONEDETECTOR, 2)
411
412/** Get the frequency of a tonedetector band.
413*/
414#define HPI_TONEDETECTOR_FREQUENCY HPI_CTL_ATTR(TONEDETECTOR, 3)
415
416/**\}*/
417
418/** \defgroup silencedet_attr SilenceDetector attributes
419\{
420*/
421
422/** Get the current state of tonedetection
423The result is a bitmap with 1s for silent channels. Left channel is in LSB
424*/
425#define HPI_SILENCEDETECTOR_STATE \
426 HPI_CTL_ATTR(SILENCEDETECTOR, 2)
427
428/** Set the threshold level of a SilenceDetector,
429Threshold is a -ve number in units of dB/100,
430*/
431#define HPI_SILENCEDETECTOR_THRESHOLD \
432 HPI_CTL_ATTR(SILENCEDETECTOR, 1)
433
434/** get/set the silence time before the detector triggers
435*/
436#define HPI_SILENCEDETECTOR_DELAY \
437 HPI_CTL_ATTR(SILENCEDETECTOR, 3)
438
439/**\}*/
440
441/* Locked memory buffer alloc/free phases */
442/** use one message to allocate or free physical memory */
443#define HPI_BUFFER_CMD_EXTERNAL 0
444/** alloc physical memory */
445#define HPI_BUFFER_CMD_INTERNAL_ALLOC 1
446/** send physical memory address to adapter */
447#define HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER 2
448/** notify adapter to stop using physical buffer */
449#define HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER 3
450/** free physical buffer */
451#define HPI_BUFFER_CMD_INTERNAL_FREE 4
452
453/******************************************* CONTROLX ATTRIBUTES ****/
454/* NOTE: All controlx attributes must be unique, unlike control attributes */
455
456/*****************************************************************************/
457/*****************************************************************************/
458/******** HPI LOW LEVEL MESSAGES *******/
459/*****************************************************************************/
460/*****************************************************************************/
461/** Pnp ids */
462/** "ASI" - actual is "ASX" - need to change */
463#define HPI_ID_ISAPNP_AUDIOSCIENCE 0x0669
464/** PCI vendor ID that AudioScience uses */
465#define HPI_PCI_VENDOR_ID_AUDIOSCIENCE 0x175C
466/** PCI vendor ID that the DSP56301 has */
467#define HPI_PCI_VENDOR_ID_MOTOROLA 0x1057
468/** PCI vendor ID that TI uses */
469#define HPI_PCI_VENDOR_ID_TI 0x104C
470
471#define HPI_PCI_DEV_ID_PCI2040 0xAC60
472/** TI's C6205 PCI interface has this ID */
473#define HPI_PCI_DEV_ID_DSP6205 0xA106
474
475#define HPI_USB_VENDOR_ID_AUDIOSCIENCE 0x1257
476#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */
477#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */
478
479/** First 2 hex digits define the adapter family */
480#define HPI_ADAPTER_FAMILY_MASK 0xff00
481
482#define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK)
483#define HPI_ADAPTER_ASI(f) (f)
484
485/******************************************* message types */
486#define HPI_TYPE_MESSAGE 1
487#define HPI_TYPE_RESPONSE 2
488#define HPI_TYPE_DATA 3
489#define HPI_TYPE_SSX2BYPASS_MESSAGE 4
490
491/******************************************* object types */
492#define HPI_OBJ_SUBSYSTEM 1
493#define HPI_OBJ_ADAPTER 2
494#define HPI_OBJ_OSTREAM 3
495#define HPI_OBJ_ISTREAM 4
496#define HPI_OBJ_MIXER 5
497#define HPI_OBJ_NODE 6
498#define HPI_OBJ_CONTROL 7
499#define HPI_OBJ_NVMEMORY 8
500#define HPI_OBJ_GPIO 9
501#define HPI_OBJ_WATCHDOG 10
502#define HPI_OBJ_CLOCK 11
503#define HPI_OBJ_PROFILE 12
504#define HPI_OBJ_CONTROLEX 13
505#define HPI_OBJ_ASYNCEVENT 14
506
507#define HPI_OBJ_MAXINDEX 14
508
509/******************************************* methods/functions */
510
511#define HPI_OBJ_FUNCTION_SPACING 0x100
512#define HPI_MAKE_INDEX(obj, index) (obj * HPI_OBJ_FUNCTION_SPACING + index)
513#define HPI_EXTRACT_INDEX(fn) (fn & 0xff)
514
515/* SUB-SYSTEM */
516#define HPI_SUBSYS_OPEN HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 1)
517#define HPI_SUBSYS_GET_VERSION HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 2)
518#define HPI_SUBSYS_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 3)
519#define HPI_SUBSYS_FIND_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 4)
520#define HPI_SUBSYS_CREATE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 5)
521#define HPI_SUBSYS_CLOSE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 6)
522#define HPI_SUBSYS_DELETE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 7)
523#define HPI_SUBSYS_DRIVER_LOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 8)
524#define HPI_SUBSYS_DRIVER_UNLOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 9)
525#define HPI_SUBSYS_READ_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 10)
526#define HPI_SUBSYS_WRITE_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 11)
527#define HPI_SUBSYS_GET_NUM_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 12)
528#define HPI_SUBSYS_GET_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 13)
529#define HPI_SUBSYS_SET_NETWORK_INTERFACE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 14)
530#define HPI_SUBSYS_FUNCTION_COUNT 14
531/* ADAPTER */
532#define HPI_ADAPTER_OPEN HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 1)
533#define HPI_ADAPTER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 2)
534#define HPI_ADAPTER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 3)
535#define HPI_ADAPTER_GET_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 4)
536#define HPI_ADAPTER_TEST_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 5)
537#define HPI_ADAPTER_SET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 6)
538#define HPI_ADAPTER_GET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 7)
539#define HPI_ADAPTER_ENABLE_CAPABILITY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 8)
540#define HPI_ADAPTER_SELFTEST HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 9)
541#define HPI_ADAPTER_FIND_OBJECT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 10)
542#define HPI_ADAPTER_QUERY_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 11)
543#define HPI_ADAPTER_START_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 12)
544#define HPI_ADAPTER_PROGRAM_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 13)
545#define HPI_ADAPTER_SET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 14)
546#define HPI_ADAPTER_GET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 15)
547#define HPI_ADAPTER_ENUM_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 16)
548#define HPI_ADAPTER_MODULE_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 17)
549#define HPI_ADAPTER_DEBUG_READ HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 18)
550#define HPI_ADAPTER_FUNCTION_COUNT 18
551/* OUTPUT STREAM */
552#define HPI_OSTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 1)
553#define HPI_OSTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 2)
554#define HPI_OSTREAM_WRITE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 3)
555#define HPI_OSTREAM_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 4)
556#define HPI_OSTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 5)
557#define HPI_OSTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 6)
558#define HPI_OSTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 7)
559#define HPI_OSTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 8)
560#define HPI_OSTREAM_DATA HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 9)
561#define HPI_OSTREAM_SET_VELOCITY HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 10)
562#define HPI_OSTREAM_SET_PUNCHINOUT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 11)
563#define HPI_OSTREAM_SINEGEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 12)
564#define HPI_OSTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 13)
565#define HPI_OSTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 14)
566#define HPI_OSTREAM_ANC_READ HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 15)
567#define HPI_OSTREAM_SET_TIMESCALE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 16)
568#define HPI_OSTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 17)
569#define HPI_OSTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 18)
570#define HPI_OSTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 19)
571#define HPI_OSTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 20)
572#define HPI_OSTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 21)
573#define HPI_OSTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 22)
574#define HPI_OSTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 23)
575#define HPI_OSTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 24)
576#define HPI_OSTREAM_FUNCTION_COUNT 24
577/* INPUT STREAM */
578#define HPI_ISTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 1)
579#define HPI_ISTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 2)
580#define HPI_ISTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 3)
581#define HPI_ISTREAM_READ HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 4)
582#define HPI_ISTREAM_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 5)
583#define HPI_ISTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 6)
584#define HPI_ISTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 7)
585#define HPI_ISTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 8)
586#define HPI_ISTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 9)
587#define HPI_ISTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 10)
588#define HPI_ISTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 11)
589#define HPI_ISTREAM_ANC_WRITE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 12)
590#define HPI_ISTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 13)
591#define HPI_ISTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 14)
592#define HPI_ISTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 15)
593#define HPI_ISTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 16)
594#define HPI_ISTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 17)
595#define HPI_ISTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 18)
596#define HPI_ISTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 19)
597#define HPI_ISTREAM_FUNCTION_COUNT 19
598/* MIXER */
599/* NOTE:
600 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */
601#define HPI_MIXER_OPEN HPI_MAKE_INDEX(HPI_OBJ_MIXER, 1)
602#define HPI_MIXER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 2)
603#define HPI_MIXER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 3)
604#define HPI_MIXER_GET_NODE_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 4)
605#define HPI_MIXER_GET_CONTROL HPI_MAKE_INDEX(HPI_OBJ_MIXER, 5)
606#define HPI_MIXER_SET_CONNECTION HPI_MAKE_INDEX(HPI_OBJ_MIXER, 6)
607#define HPI_MIXER_GET_CONNECTIONS HPI_MAKE_INDEX(HPI_OBJ_MIXER, 7)
608#define HPI_MIXER_GET_CONTROL_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 8)
609#define HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 9)
610#define HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES HPI_MAKE_INDEX(HPI_OBJ_MIXER, 10)
611#define HPI_MIXER_STORE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 11)
612#define HPI_MIXER_FUNCTION_COUNT 11
613/* MIXER CONTROLS */
614#define HPI_CONTROL_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 1)
615#define HPI_CONTROL_GET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 2)
616#define HPI_CONTROL_SET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 3)
617#define HPI_CONTROL_FUNCTION_COUNT 3
618/* NONVOL MEMORY */
619#define HPI_NVMEMORY_OPEN HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 1)
620#define HPI_NVMEMORY_READ_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 2)
621#define HPI_NVMEMORY_WRITE_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 3)
622#define HPI_NVMEMORY_FUNCTION_COUNT 3
623/* GPIO */
624#define HPI_GPIO_OPEN HPI_MAKE_INDEX(HPI_OBJ_GPIO, 1)
625#define HPI_GPIO_READ_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 2)
626#define HPI_GPIO_WRITE_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 3)
627#define HPI_GPIO_READ_ALL HPI_MAKE_INDEX(HPI_OBJ_GPIO, 4)
628#define HPI_GPIO_WRITE_STATUS HPI_MAKE_INDEX(HPI_OBJ_GPIO, 5)
629#define HPI_GPIO_FUNCTION_COUNT 5
630/* ASYNC EVENT */
631#define HPI_ASYNCEVENT_OPEN HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 1)
632#define HPI_ASYNCEVENT_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 2)
633#define HPI_ASYNCEVENT_WAIT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 3)
634#define HPI_ASYNCEVENT_GETCOUNT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 4)
635#define HPI_ASYNCEVENT_GET HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 5)
636#define HPI_ASYNCEVENT_SENDEVENTS HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 6)
637#define HPI_ASYNCEVENT_FUNCTION_COUNT 6
638/* WATCH-DOG */
639#define HPI_WATCHDOG_OPEN HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 1)
640#define HPI_WATCHDOG_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 2)
641#define HPI_WATCHDOG_PING HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 3)
642/* CLOCK */
643#define HPI_CLOCK_OPEN HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 1)
644#define HPI_CLOCK_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 2)
645#define HPI_CLOCK_GET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 3)
646/* PROFILE */
647#define HPI_PROFILE_OPEN_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 1)
648#define HPI_PROFILE_START_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 2)
649#define HPI_PROFILE_STOP_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 3)
650#define HPI_PROFILE_GET HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 4)
651#define HPI_PROFILE_GET_IDLECOUNT HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 5)
652#define HPI_PROFILE_GET_NAME HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 6)
653#define HPI_PROFILE_GET_UTILIZATION HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 7)
654#define HPI_PROFILE_FUNCTION_COUNT 7
655/* ////////////////////////////////////////////////////////////////////// */
656/* PRIVATE ATTRIBUTES */
657
658/* ////////////////////////////////////////////////////////////////////// */
659/* STRUCTURES */
660#ifndef DISABLE_PRAGMA_PACK1
661#pragma pack(push, 1)
662#endif
663
664/** PCI bus resource */
665struct hpi_pci {
666 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
667 struct pci_dev *p_os_data;
668
669#ifndef HPI64BIT /* keep structure size constant */
670 u32 padding[HPI_MAX_ADAPTER_MEM_SPACES + 1];
671#endif
672 u16 vendor_id;
673 u16 device_id;
674 u16 subsys_vendor_id;
675 u16 subsys_device_id;
676 u16 bus_number;
677 u16 device_number;
678 u32 interrupt;
679};
680
681struct hpi_resource {
682 union {
683 const struct hpi_pci *pci;
684 const char *net_if;
685 } r;
686#ifndef HPI64BIT /* keep structure size constant */
687 u32 pad_to64;
688#endif
689 u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */
690 u16 padding;
691
692};
693
694/** Format info used inside struct hpi_message
695 Not the same as public API struct hpi_format */
696struct hpi_msg_format {
697 u32 sample_rate;
698 /**< 11025, 32000, 44100 ... */
699 u32 bit_rate; /**< for MPEG */
700 u32 attributes;
701 /**< Stereo/JointStereo/Mono */
702 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
703 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */
704};
705
706/** Buffer+format structure.
707 Must be kept 7 * 32 bits to match public struct hpi_datastruct */
708struct hpi_msg_data {
709 struct hpi_msg_format format;
710 u8 *pb_data;
711#ifndef HPI64BIT
712 u32 padding;
713#endif
714 u32 data_size;
715};
716
717/** struct hpi_datastructure used up to 3.04 driver */
718struct hpi_data_legacy32 {
719 struct hpi_format format;
720 u32 pb_data;
721 u32 data_size;
722};
723
724#ifdef HPI64BIT
725/* Compatibility version of struct hpi_data*/
726struct hpi_data_compat32 {
727 struct hpi_msg_format format;
728 u32 pb_data;
729 u32 padding;
730 u32 data_size;
731};
732#endif
733
734struct hpi_buffer {
735 /** placehoder for backward compatability (see dwBufferSize) */
736 struct hpi_msg_format reserved;
737 u32 command; /**< HPI_BUFFER_CMD_xxx*/
738 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
739 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/
740};
741
742/*/////////////////////////////////////////////////////////////////////////// */
743/* This is used for background buffer bus mastering stream buffers. */
744struct hpi_hostbuffer_status {
745 u32 samples_processed;
746 u32 auxiliary_data_available;
747 u32 stream_state;
748 /* DSP index in to the host bus master buffer. */
749 u32 dSP_index;
750 /* Host index in to the host bus master buffer. */
751 u32 host_index;
752 u32 size_in_bytes;
753};
754
755struct hpi_streamid {
756 u16 object_type;
757 /**< Type of object, HPI_OBJ_OSTREAM or HPI_OBJ_ISTREAM. */
758 u16 stream_index; /**< outstream or instream index. */
759};
760
761struct hpi_punchinout {
762 u32 punch_in_sample;
763 u32 punch_out_sample;
764};
765
766struct hpi_subsys_msg {
767 struct hpi_resource resource;
768};
769
770struct hpi_subsys_res {
771 u32 version;
772 u32 data; /* used to return extended version */
773 u16 num_adapters; /* number of adapters */
774 u16 adapter_index;
775 u16 aw_adapter_list[HPI_MAX_ADAPTERS];
776};
777
778struct hpi_adapter_msg {
779 u32 adapter_mode; /* adapter mode */
780 u16 assert_id; /* assert number for "test assert" call
781 object_index for find object call
782 query_or_set for hpi_adapter_set_mode_ex() */
783 u16 object_type; /* for adapter find object call */
784};
785
786union hpi_adapterx_msg {
787 struct hpi_adapter_msg adapter;
788 struct {
789 u32 offset;
790 } query_flash;
791 struct {
792 u32 offset;
793 u32 length;
794 u32 key;
795 } start_flash;
796 struct {
797 u32 checksum;
798 u16 sequence;
799 u16 length;
800 u16 offset; /**< offset from start of msg to data */
801 u16 unused;
802 } program_flash;
803 struct {
804 u16 property;
805 u16 parameter1;
806 u16 parameter2;
807 } property_set;
808 struct {
809 u16 index;
810 u16 what;
811 u16 property_index;
812 } property_enum;
813 struct {
814 u16 index;
815 } module_info;
816 struct {
817 u32 dsp_address;
818 u32 count_bytes;
819 } debug_read;
820};
821
822struct hpi_adapter_res {
823 u32 serial_number;
824 u16 adapter_type;
825 u16 adapter_index; /* is this needed? also used for dsp_index */
826 u16 num_instreams;
827 u16 num_outstreams;
828 u16 num_mixers;
829 u16 version;
830 u8 sz_adapter_assert[HPI_STRING_LEN];
831};
832
833union hpi_adapterx_res {
834 struct hpi_adapter_res adapter;
835 struct {
836 u32 checksum;
837 u32 length;
838 u32 version;
839 } query_flash;
840 struct {
841 u16 sequence;
842 } program_flash;
843 struct {
844 u16 parameter1;
845 u16 parameter2;
846 } property_get;
847};
848
849struct hpi_stream_msg {
850 union {
851 struct hpi_msg_data data;
852 struct hpi_data_legacy32 data32;
853 u16 velocity;
854 struct hpi_punchinout pio;
855 u32 time_scale;
856 struct hpi_buffer buffer;
857 struct hpi_streamid stream;
858 } u;
859};
860
861struct hpi_stream_res {
862 union {
863 struct {
864 /* size of hardware buffer */
865 u32 buffer_size;
866 /* OutStream - data to play,
867 InStream - data recorded */
868 u32 data_available;
869 /* OutStream - samples played,
870 InStream - samples recorded */
871 u32 samples_transferred;
872 /* Adapter - OutStream - data to play,
873 InStream - data recorded */
874 u32 auxiliary_data_available;
875 u16 state; /* HPI_STATE_PLAYING, _STATE_STOPPED */
876 u16 padding;
877 } stream_info;
878 struct {
879 u32 buffer_size;
880 u32 data_available;
881 u32 samples_transfered;
882 u16 state;
883 u16 outstream_index;
884 u16 instream_index;
885 u16 padding;
886 u32 auxiliary_data_available;
887 } legacy_stream_info;
888 struct {
889 /* bitmap of grouped OutStreams */
890 u32 outstream_group_map;
891 /* bitmap of grouped InStreams */
892 u32 instream_group_map;
893 } group_info;
894 struct {
895 /* pointer to the buffer */
896 u8 *p_buffer;
897 /* pointer to the hostbuffer status */
898 struct hpi_hostbuffer_status *p_status;
899 } hostbuffer_info;
900 } u;
901};
902
903struct hpi_mixer_msg {
904 u16 control_index;
905 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */
906 u16 padding1; /* maintain alignment of subsequent fields */
907 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */
908 u16 node_index1; /* = 0..N */
909 u16 node_type2;
910 u16 node_index2;
911 u16 padding2; /* round to 4 bytes */
912};
913
914struct hpi_mixer_res {
915 u16 src_node_type; /* = HPI_SOURCENODE_LINEIN etc */
916 u16 src_node_index; /* = 0..N */
917 u16 dst_node_type;
918 u16 dst_node_index;
919 /* Also controlType for MixerGetControlByIndex */
920 u16 control_index;
921 /* may indicate which DSP the control is located on */
922 u16 dsp_index;
923};
924
925union hpi_mixerx_msg {
926 struct {
927 u16 starting_index;
928 u16 flags;
929 u32 length_in_bytes; /* length in bytes of p_data */
930 u32 p_data; /* pointer to a data array */
931 } gcabi;
932 struct {
933 u16 command;
934 u16 index;
935 } store; /* for HPI_MIXER_STORE message */
936};
937
938union hpi_mixerx_res {
939 struct {
940 u32 bytes_returned; /* size of items returned */
941 u32 p_data; /* pointer to data array */
942 u16 more_to_do; /* indicates if there is more to do */
943 } gcabi;
944};
945
946struct hpi_control_msg {
947 u16 attribute; /* control attribute or property */
948 u16 saved_index;
949 u32 param1; /* generic parameter 1 */
950 u32 param2; /* generic parameter 2 */
951 short an_log_value[HPI_MAX_CHANNELS];
952};
953
954struct hpi_control_union_msg {
955 u16 attribute; /* control attribute or property */
956 u16 saved_index; /* only used in ctrl save/restore */
957 union {
958 struct {
959 u32 param1; /* generic parameter 1 */
960 u32 param2; /* generic parameter 2 */
961 short an_log_value[HPI_MAX_CHANNELS];
962 } old;
963 union {
964 u32 frequency;
965 u32 gain;
966 u32 band;
967 u32 deemphasis;
968 u32 program;
969 struct {
970 u32 mode;
971 u32 value;
972 } mode;
973 } tuner;
974 } u;
975};
976
977struct hpi_control_res {
978 /* Could make union. dwParam, anLogValue never used in same response */
979 u32 param1;
980 u32 param2;
981 short an_log_value[HPI_MAX_CHANNELS];
982};
983
984union hpi_control_union_res {
985 struct {
986 u32 param1;
987 u32 param2;
988 short an_log_value[HPI_MAX_CHANNELS];
989 } old;
990 union {
991 u32 band;
992 u32 frequency;
993 u32 gain;
994 u32 level;
995 u32 deemphasis;
996 struct {
997 u32 data[2];
998 u32 bLER;
999 } rds;
1000 } tuner;
1001 struct {
1002 char sz_data[8];
1003 u32 remaining_chars;
1004 } chars8;
1005 char c_data12[12];
1006};
1007
1008/* HPI_CONTROLX_STRUCTURES */
1009
1010/* Message */
1011
1012/** Used for all HMI variables where max length <= 8 bytes
1013*/
1014struct hpi_controlx_msg_cobranet_data {
1015 u32 hmi_address;
1016 u32 byte_count;
1017 u32 data[2];
1018};
1019
1020/** Used for string data, and for packet bridge
1021*/
1022struct hpi_controlx_msg_cobranet_bigdata {
1023 u32 hmi_address;
1024 u32 byte_count;
1025 u8 *pb_data;
1026#ifndef HPI64BIT
1027 u32 padding;
1028#endif
1029};
1030
1031/** Used for PADS control reading of string fields.
1032*/
1033struct hpi_controlx_msg_pad_data {
1034 u32 field;
1035 u32 byte_count;
1036 u8 *pb_data;
1037#ifndef HPI64BIT
1038 u32 padding;
1039#endif
1040};
1041
1042/** Used for generic data
1043*/
1044
1045struct hpi_controlx_msg_generic {
1046 u32 param1;
1047 u32 param2;
1048};
1049
1050struct hpi_controlx_msg {
1051 u16 attribute; /* control attribute or property */
1052 u16 saved_index;
1053 union {
1054 struct hpi_controlx_msg_cobranet_data cobranet_data;
1055 struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
1056 struct hpi_controlx_msg_generic generic;
1057 struct hpi_controlx_msg_pad_data pad_data;
1058 /*struct param_value universal_value; */
1059 /* nothing extra to send for status read */
1060 } u;
1061};
1062
1063/* Response */
1064/**
1065*/
1066struct hpi_controlx_res_cobranet_data {
1067 u32 byte_count;
1068 u32 data[2];
1069};
1070
1071struct hpi_controlx_res_cobranet_bigdata {
1072 u32 byte_count;
1073};
1074
1075struct hpi_controlx_res_cobranet_status {
1076 u32 status;
1077 u32 readable_size;
1078 u32 writeable_size;
1079};
1080
1081struct hpi_controlx_res_generic {
1082 u32 param1;
1083 u32 param2;
1084};
1085
1086struct hpi_controlx_res {
1087 union {
1088 struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata;
1089 struct hpi_controlx_res_cobranet_data cobranet_data;
1090 struct hpi_controlx_res_cobranet_status cobranet_status;
1091 struct hpi_controlx_res_generic generic;
1092 /*struct param_info universal_info; */
1093 /*struct param_value universal_value; */
1094 } u;
1095};
1096
1097struct hpi_nvmemory_msg {
1098 u16 address;
1099 u16 data;
1100};
1101
1102struct hpi_nvmemory_res {
1103 u16 size_in_bytes;
1104 u16 data;
1105};
1106
1107struct hpi_gpio_msg {
1108 u16 bit_index;
1109 u16 bit_data;
1110};
1111
1112struct hpi_gpio_res {
1113 u16 number_input_bits;
1114 u16 number_output_bits;
1115 u16 bit_data[4];
1116};
1117
1118struct hpi_async_msg {
1119 u32 events;
1120 u16 maximum_events;
1121 u16 padding;
1122};
1123
1124struct hpi_async_res {
1125 union {
1126 struct {
1127 u16 count;
1128 } count;
1129 struct {
1130 u32 events;
1131 u16 number_returned;
1132 u16 padding;
1133 } get;
1134 struct hpi_async_event event;
1135 } u;
1136};
1137
1138struct hpi_watchdog_msg {
1139 u32 time_ms;
1140};
1141
1142struct hpi_watchdog_res {
1143 u32 time_ms;
1144};
1145
1146struct hpi_clock_msg {
1147 u16 hours;
1148 u16 minutes;
1149 u16 seconds;
1150 u16 milli_seconds;
1151};
1152
1153struct hpi_clock_res {
1154 u16 size_in_bytes;
1155 u16 hours;
1156 u16 minutes;
1157 u16 seconds;
1158 u16 milli_seconds;
1159 u16 padding;
1160};
1161
1162struct hpi_profile_msg {
1163 u16 bin_index;
1164 u16 padding;
1165};
1166
1167struct hpi_profile_res_open {
1168 u16 max_profiles;
1169};
1170
1171struct hpi_profile_res_time {
1172 u32 micro_seconds;
1173 u32 call_count;
1174 u32 max_micro_seconds;
1175 u32 min_micro_seconds;
1176 u16 seconds;
1177};
1178
1179struct hpi_profile_res_name {
1180 u8 sz_name[32];
1181};
1182
1183struct hpi_profile_res {
1184 union {
1185 struct hpi_profile_res_open o;
1186 struct hpi_profile_res_time t;
1187 struct hpi_profile_res_name n;
1188 } u;
1189};
1190
1191struct hpi_message_header {
1192 u16 size; /* total size in bytes */
1193 u8 type; /* HPI_TYPE_MESSAGE */
1194 u8 version; /* message version */
1195 u16 object; /* HPI_OBJ_* */
1196 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1197 u16 adapter_index; /* the adapter index */
1198 u16 obj_index; /* */
1199};
1200
1201struct hpi_message {
1202 /* following fields must match HPI_MESSAGE_HEADER */
1203 u16 size; /* total size in bytes */
1204 u8 type; /* HPI_TYPE_MESSAGE */
1205 u8 version; /* message version */
1206 u16 object; /* HPI_OBJ_* */
1207 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1208 u16 adapter_index; /* the adapter index */
1209 u16 obj_index; /* */
1210 union {
1211 struct hpi_subsys_msg s;
1212 struct hpi_adapter_msg a;
1213 union hpi_adapterx_msg ax;
1214 struct hpi_stream_msg d;
1215 struct hpi_mixer_msg m;
1216 union hpi_mixerx_msg mx; /* extended mixer; */
1217 struct hpi_control_msg c; /* mixer control; */
1218 /* identical to struct hpi_control_msg,
1219 but field naming is improved */
1220 struct hpi_control_union_msg cu;
1221 struct hpi_controlx_msg cx; /* extended mixer control; */
1222 struct hpi_nvmemory_msg n;
1223 struct hpi_gpio_msg l; /* digital i/o */
1224 struct hpi_watchdog_msg w;
1225 struct hpi_clock_msg t; /* dsp time */
1226 struct hpi_profile_msg p;
1227 struct hpi_async_msg as;
1228 char fixed_size[32];
1229 } u;
1230};
1231
1232#define HPI_MESSAGE_SIZE_BY_OBJECT { \
1233 sizeof(struct hpi_message_header) , /* default, no object type 0 */ \
1234 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\
1235 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\
1236 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
1237 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
1238 sizeof(struct hpi_message_header) + sizeof(struct hpi_mixer_msg),\
1239 sizeof(struct hpi_message_header) , /* no node message */ \
1240 sizeof(struct hpi_message_header) + sizeof(struct hpi_control_msg),\
1241 sizeof(struct hpi_message_header) + sizeof(struct hpi_nvmemory_msg),\
1242 sizeof(struct hpi_message_header) + sizeof(struct hpi_gpio_msg),\
1243 sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
1244 sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
1245 sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
1246 sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\
1247 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
1248}
1249
1250struct hpi_response_header {
1251 u16 size;
1252 u8 type; /* HPI_TYPE_RESPONSE */
1253 u8 version; /* response version */
1254 u16 object; /* HPI_OBJ_* */
1255 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1256 u16 error; /* HPI_ERROR_xxx */
1257 u16 specific_error; /* adapter specific error */
1258};
1259
1260struct hpi_response {
1261/* following fields must match HPI_RESPONSE_HEADER */
1262 u16 size;
1263 u8 type; /* HPI_TYPE_RESPONSE */
1264 u8 version; /* response version */
1265 u16 object; /* HPI_OBJ_* */
1266 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1267 u16 error; /* HPI_ERROR_xxx */
1268 u16 specific_error; /* adapter specific error */
1269 union {
1270 struct hpi_subsys_res s;
1271 struct hpi_adapter_res a;
1272 union hpi_adapterx_res ax;
1273 struct hpi_stream_res d;
1274 struct hpi_mixer_res m;
1275 union hpi_mixerx_res mx; /* extended mixer; */
1276 struct hpi_control_res c; /* mixer control; */
1277 /* identical to hpi_control_res, but field naming is improved */
1278 union hpi_control_union_res cu;
1279 struct hpi_controlx_res cx; /* extended mixer control; */
1280 struct hpi_nvmemory_res n;
1281 struct hpi_gpio_res l; /* digital i/o */
1282 struct hpi_watchdog_res w;
1283 struct hpi_clock_res t; /* dsp time */
1284 struct hpi_profile_res p;
1285 struct hpi_async_res as;
1286 u8 bytes[52];
1287 } u;
1288};
1289
1290#define HPI_RESPONSE_SIZE_BY_OBJECT { \
1291 sizeof(struct hpi_response_header) ,/* default, no object type 0 */ \
1292 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\
1293 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\
1294 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
1295 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
1296 sizeof(struct hpi_response_header) + sizeof(struct hpi_mixer_res),\
1297 sizeof(struct hpi_response_header) , /* no node response */ \
1298 sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res),\
1299 sizeof(struct hpi_response_header) + sizeof(struct hpi_nvmemory_res),\
1300 sizeof(struct hpi_response_header) + sizeof(struct hpi_gpio_res),\
1301 sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
1302 sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
1303 sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
1304 sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\
1305 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
1306}
1307
1308/*********************** version 1 message/response *****************************/
1309#define HPINET_ETHERNET_DATA_SIZE (1500)
1310#define HPINET_IP_HDR_SIZE (20)
1311#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE)
1312#define HPINET_UDP_HDR_SIZE (8)
1313#define HPINET_UDP_DATA_SIZE (HPINET_IP_DATA_SIZE - HPINET_UDP_HDR_SIZE)
1314#define HPINET_ASI_HDR_SIZE (2)
1315#define HPINET_ASI_DATA_SIZE (HPINET_UDP_DATA_SIZE - HPINET_ASI_HDR_SIZE)
1316
1317#define HPI_MAX_PAYLOAD_SIZE (HPINET_ASI_DATA_SIZE - 2)
1318
1319/* New style message/response, but still V0 compatible */
1320struct hpi_msg_adapter_get_info {
1321 struct hpi_message_header h;
1322};
1323
1324struct hpi_res_adapter_get_info {
1325 struct hpi_response_header h; /*v0 */
1326 struct hpi_adapter_res p;
1327};
1328
1329/* padding is so these are same size as v0 hpi_message */
1330struct hpi_msg_adapter_query_flash {
1331 struct hpi_message_header h;
1332 u32 offset;
1333 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1334 sizeof(struct hpi_message_header) - 1 * sizeof(u32)];
1335};
1336
1337/* padding is so these are same size as v0 hpi_response */
1338struct hpi_res_adapter_query_flash {
1339 struct hpi_response_header h;
1340 u32 checksum;
1341 u32 length;
1342 u32 version;
1343 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1344 sizeof(struct hpi_response_header) - 3 * sizeof(u32)];
1345};
1346
1347struct hpi_msg_adapter_start_flash {
1348 struct hpi_message_header h;
1349 u32 offset;
1350 u32 length;
1351 u32 key;
1352 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1353 sizeof(struct hpi_message_header) - 3 * sizeof(u32)];
1354};
1355
1356struct hpi_res_adapter_start_flash {
1357 struct hpi_response_header h;
1358 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1359 sizeof(struct hpi_response_header)];
1360};
1361
1362struct hpi_msg_adapter_program_flash_payload {
1363 u32 checksum;
1364 u16 sequence;
1365 u16 length;
1366 u16 offset; /**< offset from start of msg to data */
1367 u16 unused;
1368 /* ensure sizeof(header + payload) == sizeof(hpi_message_V0)
1369 because old firmware expects data after message of this size */
1370 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */
1371 sizeof(struct hpi_message_header) - sizeof(u32) -
1372 4 * sizeof(u16)];
1373};
1374
1375struct hpi_msg_adapter_program_flash {
1376 struct hpi_message_header h;
1377 struct hpi_msg_adapter_program_flash_payload p;
1378 u32 data[256];
1379};
1380
1381struct hpi_res_adapter_program_flash {
1382 struct hpi_response_header h;
1383 u16 sequence;
1384 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1385 sizeof(struct hpi_response_header) - sizeof(u16)];
1386};
1387
1388#if 1
1389#define hpi_message_header_v1 hpi_message_header
1390#define hpi_response_header_v1 hpi_response_header
1391#else
1392/* V1 headers in Addition to v0 headers */
1393struct hpi_message_header_v1 {
1394 struct hpi_message_header h0;
1395/* struct {
1396} h1; */
1397};
1398
1399struct hpi_response_header_v1 {
1400 struct hpi_response_header h0;
1401 struct {
1402 u16 adapter_index; /* the adapter index */
1403 u16 obj_index; /* object index */
1404 } h1;
1405};
1406#endif
1407
1408/* STRV HPI Packet */
1409struct hpi_msg_strv {
1410 struct hpi_message_header h;
1411 struct hpi_entity strv;
1412};
1413
1414struct hpi_res_strv {
1415 struct hpi_response_header h;
1416 struct hpi_entity strv;
1417};
1418#define MIN_STRV_PACKET_SIZE sizeof(struct hpi_res_strv)
1419
1420struct hpi_msg_payload_v0 {
1421 struct hpi_message_header h;
1422 union {
1423 struct hpi_subsys_msg s;
1424 struct hpi_adapter_msg a;
1425 union hpi_adapterx_msg ax;
1426 struct hpi_stream_msg d;
1427 struct hpi_mixer_msg m;
1428 union hpi_mixerx_msg mx;
1429 struct hpi_control_msg c;
1430 struct hpi_control_union_msg cu;
1431 struct hpi_controlx_msg cx;
1432 struct hpi_nvmemory_msg n;
1433 struct hpi_gpio_msg l;
1434 struct hpi_watchdog_msg w;
1435 struct hpi_clock_msg t;
1436 struct hpi_profile_msg p;
1437 struct hpi_async_msg as;
1438 } u;
1439};
1440
1441struct hpi_res_payload_v0 {
1442 struct hpi_response_header h;
1443 union {
1444 struct hpi_subsys_res s;
1445 struct hpi_adapter_res a;
1446 union hpi_adapterx_res ax;
1447 struct hpi_stream_res d;
1448 struct hpi_mixer_res m;
1449 union hpi_mixerx_res mx;
1450 struct hpi_control_res c;
1451 union hpi_control_union_res cu;
1452 struct hpi_controlx_res cx;
1453 struct hpi_nvmemory_res n;
1454 struct hpi_gpio_res l;
1455 struct hpi_watchdog_res w;
1456 struct hpi_clock_res t;
1457 struct hpi_profile_res p;
1458 struct hpi_async_res as;
1459 } u;
1460};
1461
1462union hpi_message_buffer_v1 {
1463 struct hpi_message m0; /* version 0 */
1464 struct hpi_message_header_v1 h;
1465 unsigned char buf[HPI_MAX_PAYLOAD_SIZE];
1466};
1467
1468union hpi_response_buffer_v1 {
1469 struct hpi_response r0; /* version 0 */
1470 struct hpi_response_header_v1 h;
1471 unsigned char buf[HPI_MAX_PAYLOAD_SIZE];
1472};
1473
1474compile_time_assert((sizeof(union hpi_message_buffer_v1) <=
1475 HPI_MAX_PAYLOAD_SIZE), message_buffer_ok);
1476compile_time_assert((sizeof(union hpi_response_buffer_v1) <=
1477 HPI_MAX_PAYLOAD_SIZE), response_buffer_ok);
1478
1479/*////////////////////////////////////////////////////////////////////////// */
1480/* declarations for compact control calls */
1481struct hpi_control_defn {
1482 u8 type;
1483 u8 channels;
1484 u8 src_node_type;
1485 u8 src_node_index;
1486 u8 dest_node_type;
1487 u8 dest_node_index;
1488};
1489
1490/*////////////////////////////////////////////////////////////////////////// */
1491/* declarations for control caching (internal to HPI<->DSP interaction) */
1492
1493/** A compact representation of (part of) a controls state.
1494Used for efficient transfer of the control state
1495between DSP and host or across a network
1496*/
1497struct hpi_control_cache_info {
1498 /** one of HPI_CONTROL_* */
1499 u8 control_type;
1500 /** The total size of cached information in 32-bit words. */
1501 u8 size_in32bit_words;
1502 /** The original index of the control on the DSP */
1503 u16 control_index;
1504};
1505
1506struct hpi_control_cache_single {
1507 struct hpi_control_cache_info i;
1508 union {
1509 struct { /* volume */
1510 u16 an_log[2];
1511 } v;
1512 struct { /* peak meter */
1513 u16 an_log_peak[2];
1514 u16 an_logRMS[2];
1515 } p;
1516 struct { /* channel mode */
1517 u16 mode;
1518 } m;
1519 struct { /* multiplexer */
1520 u16 source_node_type;
1521 u16 source_node_index;
1522 } x;
1523 struct { /* level/trim */
1524 u16 an_log[2];
1525 } l;
1526 struct { /* tuner - partial caching.
1527 some attributes go to the DSP. */
1528 u32 freq_ink_hz;
1529 u16 band;
1530 u16 level;
1531 } t;
1532 struct { /* AESEBU rx status */
1533 u32 error_status;
1534 u32 source;
1535 } aes3rx;
1536 struct { /* AESEBU tx */
1537 u32 format;
1538 } aes3tx;
1539 struct { /* tone detector */
1540 u16 state;
1541 } tone;
1542 struct { /* silence detector */
1543 u32 state;
1544 u32 count;
1545 } silence;
1546 struct { /* sample clock */
1547 u16 source;
1548 u16 source_index;
1549 u32 sample_rate;
1550 } clk;
1551 struct { /* microphone control */
1552 u16 state;
1553 } phantom_power;
1554 struct { /* generic control */
1555 u32 dw1;
1556 u32 dw2;
1557 } g;
1558 } u;
1559};
1560
1561struct hpi_control_cache_pad {
1562 struct hpi_control_cache_info i;
1563 u32 field_valid_flags;
1564 u8 c_channel[8];
1565 u8 c_artist[40];
1566 u8 c_title[40];
1567 u8 c_comment[200];
1568 u32 pTY;
1569 u32 pI;
1570 u32 traffic_supported;
1571 u32 traffic_anouncement;
1572};
1573
1574/*/////////////////////////////////////////////////////////////////////////// */
1575/* declarations for 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1576struct hpi_fifo_buffer {
1577 u32 size;
1578 u32 dSP_index;
1579 u32 host_index;
1580};
1581
1582#ifndef DISABLE_PRAGMA_PACK1
1583#pragma pack(pop)
1584#endif
1585
1586/* skip host side function declarations for DSP
1587 compile and documentation extraction */
1588
1589char hpi_handle_object(const u32 handle);
1590
1591void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
1592 u16 *pw_object_index);
1593
1594u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
1595 const u16 object_index);
1596
1597/*////////////////////////////////////////////////////////////////////////// */
1598
1599/* main HPI entry point */
1600hpi_handler_func hpi_send_recv;
1601
1602/* UDP message */
1603void hpi_send_recvUDP(struct hpi_message *phm, struct hpi_response *phr,
1604 const unsigned int timeout);
1605
1606/* used in PnP OS/driver */
1607u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
1608 const struct hpi_resource *p_resource, u16 *pw_adapter_index);
1609
1610u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
1611 u16 adapter_index);
1612
1613u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1614 u32 h_outstream, u8 **pp_buffer,
1615 struct hpi_hostbuffer_status **pp_status);
1616
1617u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1618 u32 h_instream, u8 **pp_buffer,
1619 struct hpi_hostbuffer_status **pp_status);
1620
1621u16 hpi_adapter_restart(u16 adapter_index);
1622
1623/*
1624The following 3 functions were last declared in header files for
1625driver 3.10. HPI_ControlQuery() used to be the recommended way
1626of getting a volume range. Declared here for binary asihpi32.dll
1627compatibility.
1628*/
1629
1630void hpi_format_to_msg(struct hpi_msg_format *pMF,
1631 const struct hpi_format *pF);
1632void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1633
1634/*////////////////////////////////////////////////////////////////////////// */
1635/* declarations for individual HPI entry points */
1636hpi_handler_func HPI_1000;
1637hpi_handler_func HPI_6000;
1638hpi_handler_func HPI_6205;
1639hpi_handler_func HPI_COMMON;
1640
1641#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
new file mode 100644
index 000000000000..565102cae4f8
--- /dev/null
+++ b/sound/pci/asihpi/hpicmn.c
@@ -0,0 +1,643 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19\file hpicmn.c
20
21 Common functions used by hpixxxx.c modules
22
23(C) Copyright AudioScience Inc. 1998-2003
24*******************************************************************************/
25#define SOURCEFILE_NAME "hpicmn.c"
26
27#include "hpi_internal.h"
28#include "hpidebug.h"
29#include "hpicmn.h"
30
31struct hpi_adapters_list {
32 struct hpios_spinlock list_lock;
33 struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
34 u16 gw_num_adapters;
35};
36
37static struct hpi_adapters_list adapters;
38
39/**
40* Given an HPI Message that was sent out and a response that was received,
41* validate that the response has the correct fields filled in,
42* i.e ObjectType, Function etc
43**/
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
45{
46 u16 error = 0;
47
48 if ((phr->type != HPI_TYPE_RESPONSE)
49 || (phr->object != phm->object)
50 || (phr->function != phm->function))
51 error = HPI_ERROR_INVALID_RESPONSE;
52
53 return error;
54}
55
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
57{
58 u16 retval = 0;
59 /*HPI_ASSERT(pao->wAdapterType); */
60
61 hpios_alistlock_lock(&adapters);
62
63 if (pao->index >= HPI_MAX_ADAPTERS) {
64 retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
65 goto unlock;
66 }
67
68 if (adapters.adapter[pao->index].adapter_type) {
69 {
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock;
72 }
73 }
74 adapters.adapter[pao->index] = *pao;
75 hpios_dsplock_init(&adapters.adapter[pao->index]);
76 adapters.gw_num_adapters++;
77
78unlock:
79 hpios_alistlock_un_lock(&adapters);
80 return retval;
81}
82
83void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj));
86
87 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--; /* dec the number of adapters */
89 hpios_alistlock_un_lock(&adapters);
90}
91
92/**
93* FindAdapter returns a pointer to the struct hpi_adapter_obj with
94* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
95*
96*/
97struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
98{
99 struct hpi_adapter_obj *pao = NULL;
100
101 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
103 adapter_index);
104 return NULL;
105 }
106
107 pao = &adapters.adapter[adapter_index];
108 if (pao->adapter_type != 0) {
109 /*
110 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
111 wAdapterIndex);
112 */
113 return pao;
114 } else {
115 /*
116 HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
117 wAdapterIndex);
118 */
119 return NULL;
120 }
121}
122
123/**
124*
125* wipe an HPI_ADAPTERS_LIST structure.
126*
127**/
128static void wipe_adapter_list(void
129 )
130{
131 memset(&adapters, 0, sizeof(adapters));
132}
133
134/**
135* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
136* with all adapters in the given HPI_ADAPTERS_LIST.
137*
138*/
139static void subsys_get_adapters(struct hpi_response *phr)
140{
141 /* fill in the response adapter array with the position */
142 /* identified by the adapter number/index of the adapters in */
143 /* this HPI */
144 /* i.e. if we have an A120 with it's jumper set to */
145 /* Adapter Number 2 then put an Adapter type A120 in the */
146 /* array in position 1 */
147 /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
148
149 /* input: NONE */
150 /* output: wNumAdapters */
151 /* awAdapter[] */
152 /* */
153
154 short i;
155 struct hpi_adapter_obj *pao = NULL;
156
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
158
159 /* for each adapter, place it's type in the position of the array */
160 /* corresponding to it's adapter number */
161 for (i = 0; i < adapters.gw_num_adapters; i++) {
162 pao = &adapters.adapter[i];
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) {
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
165 phr->specific_error = pao->index;
166 return;
167 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 }
170
171 phr->u.s.num_adapters = adapters.gw_num_adapters;
172 phr->error = 0; /* the function completed OK; */
173}
174
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
176{
177 unsigned int i;
178 int cached = 0;
179 if (!pC)
180 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
182 && (pC->cache_size_in_bytes)
183 ) {
184 u32 *p_master_cache;
185 pC->init = 1;
186
187 p_master_cache = (u32 *)pC->p_cache;
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
189 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *)
193 p_master_cache;
194
195 if (info->control_type) {
196 pC->p_info[i] = info;
197 cached++;
198 } else
199 pC->p_info[i] = NULL;
200
201 if (info->size_in32bit_words)
202 p_master_cache += info->size_in32bit_words;
203 else
204 p_master_cache +=
205 sizeof(struct
206 hpi_control_cache_single) /
207 sizeof(u32);
208
209 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n",
211 cached, pC->p_info[i], info->control_index,
212 info->control_type);
213 }
214 /*
215 We didn't find anything to cache, so try again later !
216 */
217 if (!cached)
218 pC->init = 0;
219 }
220 return pC->init;
221}
222
223/** Find a control.
224*/
225static short find_control(struct hpi_message *phm,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
227 u16 *pw_control_index)
228{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n",
234 phm->adapter_index, *pw_control_index);
235 return 0;
236 }
237
238 *pI = p_cache->p_info[*pw_control_index];
239 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
241 phm->adapter_index, *pw_control_index);
242 return 0;
243 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
245 (*pI)->control_type);
246 }
247 return 1;
248}
249
250/** Used by the kernel driver to figure out if a buffer needs mapping.
251 */
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269/* allow unified treatment of several string fields within struct */
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \
272 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
273
274struct pad_ofs_size {
275 unsigned int offset;
276 unsigned int field_size;
277};
278
279static struct pad_ofs_size pad_desc[] = {
280 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
281 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
282 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
283 HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
284};
285
286/** CheckControlCache checks the cache and fills the struct hpi_response
287 * accordingly. It returns one if a cache hit occurred, zero otherwise.
288 */
289short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290 struct hpi_message *phm, struct hpi_response *phr)
291{
292 short found = 1;
293 u16 control_index;
294 struct hpi_control_cache_info *pI;
295 struct hpi_control_cache_single *pC;
296 struct hpi_control_cache_pad *p_pad;
297
298 if (!find_control(phm, p_cache, &pI, &control_index))
299 return 0;
300
301 phr->error = 0;
302
303 /* pC is the default cached control strucure. May be cast to
304 something else in the following switch statement.
305 */
306 pC = (struct hpi_control_cache_single *)pI;
307 p_pad = (struct hpi_control_cache_pad *)pI;
308
309 switch (pI->control_type) {
310
311 case HPI_CONTROL_METER:
312 if (phm->u.c.attribute == HPI_METER_PEAK) {
313 phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
314 phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
315 } else if (phm->u.c.attribute == HPI_METER_RMS) {
316 phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
317 phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
318 } else
319 found = 0;
320 break;
321 case HPI_CONTROL_VOLUME:
322 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
323 phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
324 phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
325 } else
326 found = 0;
327 break;
328 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index;
332 } else {
333 found = 0;
334 }
335 break;
336 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode;
339 else
340 found = 0;
341 break;
342 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
345 phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
346 } else
347 found = 0;
348 break;
349 case HPI_CONTROL_TUNER:
350 {
351 struct hpi_control_cache_single *pCT =
352 (struct hpi_control_cache_single *)pI;
353 if (phm->u.c.attribute == HPI_TUNER_FREQ)
354 phr->u.c.param1 = pCT->u.t.freq_ink_hz;
355 else if (phm->u.c.attribute == HPI_TUNER_BAND)
356 phr->u.c.param1 = pCT->u.t.band;
357 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
358 && (phm->u.c.param1 ==
359 HPI_TUNER_LEVEL_AVERAGE))
360 phr->u.c.param1 = pCT->u.t.level;
361 else
362 found = 0;
363 }
364 break;
365 case HPI_CONTROL_AESEBU_RECEIVER:
366 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
367 phr->u.c.param1 = pC->u.aes3rx.error_status;
368 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
369 phr->u.c.param1 = pC->u.aes3rx.source;
370 else
371 found = 0;
372 break;
373 case HPI_CONTROL_AESEBU_TRANSMITTER:
374 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
375 phr->u.c.param1 = pC->u.aes3tx.format;
376 else
377 found = 0;
378 break;
379 case HPI_CONTROL_TONEDETECTOR:
380 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
381 phr->u.c.param1 = pC->u.tone.state;
382 else
383 found = 0;
384 break;
385 case HPI_CONTROL_SILENCEDETECTOR:
386 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
387 phr->u.c.param1 = pC->u.silence.state;
388 phr->u.c.param2 = pC->u.silence.count;
389 } else
390 found = 0;
391 break;
392 case HPI_CONTROL_MICROPHONE:
393 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
394 phr->u.c.param1 = pC->u.phantom_power.state;
395 else
396 found = 0;
397 break;
398 case HPI_CONTROL_SAMPLECLOCK:
399 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
400 phr->u.c.param1 = pC->u.clk.source;
401 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
402 if (pC->u.clk.source_index ==
403 HPI_ERROR_ILLEGAL_CACHE_VALUE) {
404 phr->u.c.param1 = 0;
405 phr->error = HPI_ERROR_INVALID_OPERATION;
406 } else
407 phr->u.c.param1 = pC->u.clk.source_index;
408 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
409 phr->u.c.param1 = pC->u.clk.sample_rate;
410 else
411 found = 0;
412 break;
413 case HPI_CONTROL_PAD:
414
415 if (!(p_pad->field_valid_flags & (1 <<
416 HPI_CTL_ATTR_INDEX(phm->u.c.
417 attribute)))) {
418 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
419 break;
420 }
421
422 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
423 phr->u.c.param1 = p_pad->pI;
424 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
425 phr->u.c.param1 = p_pad->pTY;
426 else {
427 unsigned int index =
428 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
429 unsigned int offset = phm->u.c.param1;
430 unsigned int pad_string_len, field_size;
431 char *pad_string;
432 unsigned int tocopy;
433
434 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
435 phm->u.c.attribute);
436
437 if (index > ARRAY_SIZE(pad_desc) - 1) {
438 phr->error =
439 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
440 break;
441 }
442
443 pad_string = ((char *)p_pad) + pad_desc[index].offset;
444 field_size = pad_desc[index].field_size;
445 /* Ensure null terminator */
446 pad_string[field_size - 1] = 0;
447
448 pad_string_len = strlen(pad_string) + 1;
449
450 if (offset > pad_string_len) {
451 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
452 break;
453 }
454
455 tocopy = pad_string_len - offset;
456 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
457 tocopy = sizeof(phr->u.cu.chars8.sz_data);
458
459 HPI_DEBUG_LOG(VERBOSE,
460 "PADS memcpy(%d), offset %d \n", tocopy,
461 offset);
462 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
463 tocopy);
464
465 phr->u.cu.chars8.remaining_chars =
466 pad_string_len - offset - tocopy;
467 }
468 break;
469 default:
470 found = 0;
471 break;
472 }
473
474 if (found)
475 HPI_DEBUG_LOG(VERBOSE,
476 "cached adap %d, ctl %d, type %d, attr %d\n",
477 phm->adapter_index, pI->control_index,
478 pI->control_type, phm->u.c.attribute);
479 else
480 HPI_DEBUG_LOG(VERBOSE,
481 "uncached adap %d, ctl %d, ctl type %d\n",
482 phm->adapter_index, pI->control_index,
483 pI->control_type);
484
485 if (found)
486 phr->size =
487 sizeof(struct hpi_response_header) +
488 sizeof(struct hpi_control_res);
489
490 return found;
491}
492
493/** Updates the cache with Set values.
494
495Only update if no error.
496Volume and Level return the limited values in the response, so use these
497Multiplexer does so use sent values
498*/
499void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
500 struct hpi_message *phm, struct hpi_response *phr)
501{
502 u16 control_index;
503 struct hpi_control_cache_single *pC;
504 struct hpi_control_cache_info *pI;
505
506 if (!find_control(phm, p_cache, &pI, &control_index))
507 return;
508
509 /* pC is the default cached control strucure.
510 May be cast to something else in the following switch statement.
511 */
512 pC = (struct hpi_control_cache_single *)pI;
513
514 switch (pI->control_type) {
515 case HPI_CONTROL_VOLUME:
516 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
517 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
518 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
519 }
520 break;
521 case HPI_CONTROL_MULTIPLEXER:
522 /* mux does not return its setting on Set command. */
523 if (phr->error)
524 return;
525 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
526 pC->u.x.source_node_type = (u16)phm->u.c.param1;
527 pC->u.x.source_node_index = (u16)phm->u.c.param2;
528 }
529 break;
530 case HPI_CONTROL_CHANNEL_MODE:
531 /* mode does not return its setting on Set command. */
532 if (phr->error)
533 return;
534 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535 pC->u.m.mode = (u16)phm->u.c.param1;
536 break;
537 case HPI_CONTROL_LEVEL:
538 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
539 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
540 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
541 }
542 break;
543 case HPI_CONTROL_MICROPHONE:
544 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
545 pC->u.phantom_power.state = (u16)phm->u.c.param1;
546 break;
547 case HPI_CONTROL_AESEBU_TRANSMITTER:
548 if (phr->error)
549 return;
550 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
551 pC->u.aes3tx.format = phm->u.c.param1;
552 break;
553 case HPI_CONTROL_AESEBU_RECEIVER:
554 if (phr->error)
555 return;
556 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
557 pC->u.aes3rx.source = phm->u.c.param1;
558 break;
559 case HPI_CONTROL_SAMPLECLOCK:
560 if (phr->error)
561 return;
562 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
563 pC->u.clk.source = (u16)phm->u.c.param1;
564 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
565 pC->u.clk.source_index = (u16)phm->u.c.param1;
566 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
567 pC->u.clk.sample_rate = phm->u.c.param1;
568 break;
569 default:
570 break;
571 }
572}
573
574struct hpi_control_cache *hpi_alloc_control_cache(const u32
575 number_of_controls, const u32 size_in_bytes,
576 struct hpi_control_cache_info *pDSP_control_buffer)
577{
578 struct hpi_control_cache *p_cache =
579 kmalloc(sizeof(*p_cache), GFP_KERNEL);
580 p_cache->cache_size_in_bytes = size_in_bytes;
581 p_cache->control_count = number_of_controls;
582 p_cache->p_cache =
583 (struct hpi_control_cache_single *)pDSP_control_buffer;
584 p_cache->init = 0;
585 p_cache->p_info =
586 kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
587 GFP_KERNEL);
588 return p_cache;
589}
590
591void hpi_free_control_cache(struct hpi_control_cache *p_cache)
592{
593 if ((p_cache->init) && (p_cache->p_info)) {
594 kfree(p_cache->p_info);
595 p_cache->p_info = NULL;
596 p_cache->init = 0;
597 kfree(p_cache);
598 }
599}
600
601static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
602{
603
604 switch (phm->function) {
605 case HPI_SUBSYS_OPEN:
606 case HPI_SUBSYS_CLOSE:
607 case HPI_SUBSYS_DRIVER_UNLOAD:
608 phr->error = 0;
609 break;
610 case HPI_SUBSYS_DRIVER_LOAD:
611 wipe_adapter_list();
612 hpios_alistlock_init(&adapters);
613 phr->error = 0;
614 break;
615 case HPI_SUBSYS_GET_INFO:
616 subsys_get_adapters(phr);
617 break;
618 case HPI_SUBSYS_CREATE_ADAPTER:
619 case HPI_SUBSYS_DELETE_ADAPTER:
620 phr->error = 0;
621 break;
622 default:
623 phr->error = HPI_ERROR_INVALID_FUNC;
624 break;
625 }
626}
627
628void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
629{
630 switch (phm->type) {
631 case HPI_TYPE_MESSAGE:
632 switch (phm->object) {
633 case HPI_OBJ_SUBSYSTEM:
634 subsys_message(phm, phr);
635 break;
636 }
637 break;
638
639 default:
640 phr->error = HPI_ERROR_INVALID_TYPE;
641 break;
642 }
643}
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
new file mode 100644
index 000000000000..6229022f56cb
--- /dev/null
+++ b/sound/pci/asihpi/hpicmn.h
@@ -0,0 +1,64 @@
1/**
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19*/
20
21struct hpi_adapter_obj {
22 struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
23 u16 adapter_type; /* ASI6701 etc */
24 u16 index; /* */
25 u16 open; /* =1 when adapter open */
26 u16 mixer_open;
27
28 struct hpios_spinlock dsp_lock;
29
30 u16 dsp_crashed;
31 u16 has_control_cache;
32 void *priv;
33};
34
35struct hpi_control_cache {
36 u32 init; /**< indicates whether the
37 structures are initialized */
38 u32 control_count;
39 u32 cache_size_in_bytes;
40 struct hpi_control_cache_info
41 **p_info; /**< pointer to allocated memory of
42 lookup pointers. */
43 struct hpi_control_cache_single
44 *p_cache; /**< pointer to DSP's control cache. */
45};
46
47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
48u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
49
50void hpi_delete_adapter(struct hpi_adapter_obj *pao);
51
52short hpi_check_control_cache(struct hpi_control_cache *pC,
53 struct hpi_message *phm, struct hpi_response *phr);
54struct hpi_control_cache *hpi_alloc_control_cache(const u32
55 number_of_controls, const u32 size_in_bytes,
56 struct hpi_control_cache_info
57 *pDSP_control_buffer);
58void hpi_free_control_cache(struct hpi_control_cache *p_cache);
59
60void hpi_sync_control_cache(struct hpi_control_cache *pC,
61 struct hpi_message *phm, struct hpi_response *phr);
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
64 struct hpi_message *phm, void **p, unsigned int *pN);
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
new file mode 100644
index 000000000000..4cd85a401b34
--- /dev/null
+++ b/sound/pci/asihpi/hpidebug.c
@@ -0,0 +1,225 @@
1/************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Debug macro translation.
20
21************************************************************************/
22
23#include "hpi_internal.h"
24#include "hpidebug.h"
25
26/* Debug level; 0 quiet; 1 informative, 2 debug, 3 verbose debug. */
27int hpi_debug_level = HPI_DEBUG_LEVEL_DEFAULT;
28
29void hpi_debug_init(void)
30{
31 printk(KERN_INFO "debug start\n");
32}
33
34int hpi_debug_level_set(int level)
35{
36 int old_level;
37
38 old_level = hpi_debug_level;
39 hpi_debug_level = level;
40 return old_level;
41}
42
43int hpi_debug_level_get(void)
44{
45 return hpi_debug_level;
46}
47
48#ifdef HPIOS_DEBUG_PRINT
49/* implies OS has no printf-like function */
50#include <stdarg.h>
51
52void hpi_debug_printf(char *fmt, ...)
53{
54 va_list arglist;
55 char buffer[128];
56
57 va_start(arglist, fmt);
58
59 if (buffer[0])
60 HPIOS_DEBUG_PRINT(buffer);
61 va_end(arglist);
62}
63#endif
64
65struct treenode {
66 void *array;
67 unsigned int num_elements;
68};
69
70#define make_treenode_from_array(nodename, array) \
71static void *tmp_strarray_##nodename[] = array; \
72static struct treenode nodename = { \
73 &tmp_strarray_##nodename, \
74 ARRAY_SIZE(tmp_strarray_##nodename) \
75};
76
77#define get_treenode_elem(node_ptr, idx, type) \
78 (&(*((type *)(node_ptr)->array)[idx]))
79
80make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
81
82 make_treenode_from_array(hpi_subsys_strings, HPI_SUBSYS_STRINGS)
83 make_treenode_from_array(hpi_adapter_strings, HPI_ADAPTER_STRINGS)
84 make_treenode_from_array(hpi_istream_strings, HPI_ISTREAM_STRINGS)
85 make_treenode_from_array(hpi_ostream_strings, HPI_OSTREAM_STRINGS)
86 make_treenode_from_array(hpi_mixer_strings, HPI_MIXER_STRINGS)
87 make_treenode_from_array(hpi_node_strings,
88 {
89 "NODE is invalid object"})
90
91 make_treenode_from_array(hpi_control_strings, HPI_CONTROL_STRINGS)
92 make_treenode_from_array(hpi_nvmemory_strings, HPI_OBJ_STRINGS)
93 make_treenode_from_array(hpi_digitalio_strings, HPI_DIGITALIO_STRINGS)
94 make_treenode_from_array(hpi_watchdog_strings, HPI_WATCHDOG_STRINGS)
95 make_treenode_from_array(hpi_clock_strings, HPI_CLOCK_STRINGS)
96 make_treenode_from_array(hpi_profile_strings, HPI_PROFILE_STRINGS)
97 make_treenode_from_array(hpi_asyncevent_strings, HPI_ASYNCEVENT_STRINGS)
98#define HPI_FUNCTION_STRINGS \
99{ \
100 &hpi_subsys_strings,\
101 &hpi_adapter_strings,\
102 &hpi_ostream_strings,\
103 &hpi_istream_strings,\
104 &hpi_mixer_strings,\
105 &hpi_node_strings,\
106 &hpi_control_strings,\
107 &hpi_nvmemory_strings,\
108 &hpi_digitalio_strings,\
109 &hpi_watchdog_strings,\
110 &hpi_clock_strings,\
111 &hpi_profile_strings,\
112 &hpi_control_strings, \
113 &hpi_asyncevent_strings \
114};
115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116
117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
118
119static char *hpi_function_string(unsigned int function)
120{
121 unsigned int object;
122 struct treenode *tmp;
123
124 object = function / HPI_OBJ_FUNCTION_SPACING;
125 function = function - object * HPI_OBJ_FUNCTION_SPACING;
126
127 if (object == 0 || object == HPI_OBJ_NODE
128 || object > hpi_function_strings.num_elements)
129 return "invalid object";
130
131 tmp = get_treenode_elem(&hpi_function_strings, object - 1,
132 struct treenode *);
133
134 if (function == 0 || function > tmp->num_elements)
135 return "invalid function";
136
137 return get_treenode_elem(tmp, function - 1, char *);
138}
139
140void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
141{
142 if (phm) {
143 if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) {
144 u16 index = 0;
145 u16 attrib = 0;
146 int is_control = 0;
147
148 index = phm->obj_index;
149 switch (phm->object) {
150 case HPI_OBJ_ADAPTER:
151 case HPI_OBJ_PROFILE:
152 break;
153 case HPI_OBJ_MIXER:
154 if (phm->function ==
155 HPI_MIXER_GET_CONTROL_BY_INDEX)
156 index = phm->u.m.control_index;
157 break;
158 case HPI_OBJ_OSTREAM:
159 case HPI_OBJ_ISTREAM:
160 break;
161
162 case HPI_OBJ_CONTROLEX:
163 case HPI_OBJ_CONTROL:
164 if (phm->version == 1)
165 attrib = HPI_CTL_ATTR(UNIVERSAL, 1);
166 else
167 attrib = phm->u.c.attribute;
168 is_control = 1;
169 break;
170 default:
171 break;
172 }
173
174 if (is_control && (attrib & 0xFF00)) {
175 int control_type = (attrib & 0xFF00) >> 8;
176 int attr_index = HPI_CTL_ATTR_INDEX(attrib);
177 /* note the KERN facility level
178 is in szFileline already */
179 printk("%s adapter %d %s "
180 "ctrl_index x%04x %s %d\n",
181 sz_fileline, phm->adapter_index,
182 hpi_function_string(phm->function),
183 index,
184 get_treenode_elem
185 (&hpi_control_type_strings,
186 control_type, char *),
187 attr_index);
188
189 } else
190 printk("%s adapter %d %s "
191 "idx x%04x attr x%04x \n",
192 sz_fileline, phm->adapter_index,
193 hpi_function_string(phm->function),
194 index, attrib);
195 } else {
196 printk("adap=%d, invalid obj=%d, func=0x%x\n",
197 phm->adapter_index, phm->object,
198 phm->function);
199 }
200 } else
201 printk(KERN_ERR
202 "NULL message pointer to hpi_debug_message!\n");
203}
204
205void hpi_debug_data(u16 *pdata, u32 len)
206{
207 u32 i;
208 int j;
209 int k;
210 int lines;
211 int cols = 8;
212
213 lines = (len + cols - 1) / cols;
214 if (lines > 8)
215 lines = 8;
216
217 for (i = 0, j = 0; j < lines; j++) {
218 printk(KERN_DEBUG "%p:", (pdata + i));
219
220 for (k = 0; k < cols && i < len; i++, k++)
221 printk("%s%04x", k == 0 ? "" : " ", pdata[i]);
222
223 printk("\n");
224 }
225}
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
new file mode 100644
index 000000000000..44dccadcc25b
--- /dev/null
+++ b/sound/pci/asihpi/hpidebug.h
@@ -0,0 +1,385 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Debug macros.
20
21*****************************************************************************/
22
23#ifndef _HPIDEBUG_H
24#define _HPIDEBUG_H
25
26#include "hpi_internal.h"
27
28/* Define debugging levels. */
29enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
30 HPI_DEBUG_LEVEL_WARNING = 1,
31 HPI_DEBUG_LEVEL_NOTICE = 2,
32 HPI_DEBUG_LEVEL_INFO = 3,
33 HPI_DEBUG_LEVEL_DEBUG = 4,
34 HPI_DEBUG_LEVEL_VERBOSE = 5 /* same printk level as DEBUG */
35};
36
37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
38
39/* an OS can define an extra flag string that is appended to
40 the start of each message, eg see hpios_linux.h */
41
42#ifdef SOURCEFILE_NAME
43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " "
44#else
45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " "
46#endif
47
48#if defined(HPI_DEBUG) && defined(_WINDOWS)
49#define HPI_DEBUGBREAK() debug_break()
50#else
51#define HPI_DEBUGBREAK()
52#endif
53
54#define HPI_DEBUG_ASSERT(expression) \
55 do { \
56 if (!(expression)) {\
57 printk(KERN_ERR FILE_LINE\
58 "ASSERT " __stringify(expression));\
59 HPI_DEBUGBREAK();\
60 } \
61 } while (0)
62
63#define HPI_DEBUG_LOG(level, ...) \
64 do { \
65 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
66 printk(HPI_DEBUG_FLAG_##level \
67 FILE_LINE __VA_ARGS__); \
68 } \
69 } while (0)
70
71void hpi_debug_init(void);
72int hpi_debug_level_set(int level);
73int hpi_debug_level_get(void);
74/* needed by Linux driver for dynamic debug level changes */
75extern int hpi_debug_level;
76
77void hpi_debug_message(struct hpi_message *phm, char *sz_fileline);
78
79void hpi_debug_data(u16 *pdata, u32 len);
80
81#define HPI_DEBUG_DATA(pdata, len) \
82 do { \
83 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
84 hpi_debug_data(pdata, len); \
85 } while (0)
86
87#define HPI_DEBUG_MESSAGE(level, phm) \
88 do { \
89 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
90 hpi_debug_message(phm,HPI_DEBUG_FLAG_##level \
91 FILE_LINE __stringify(level));\
92 } \
93 } while (0)
94
95#define HPI_DEBUG_RESPONSE(phr) \
96 do { \
97 if ((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && (phr->error))\
98 HPI_DEBUG_LOG(ERROR, \
99 "HPI response - error# %d\n", \
100 phr->error); \
101 else if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
102 HPI_DEBUG_LOG(VERBOSE, "HPI response OK\n");\
103 } while (0)
104
105#ifndef compile_time_assert
106#define compile_time_assert(cond, msg) \
107 typedef char msg[(cond) ? 1 : -1]
108#endif
109
110 /* check that size is exactly some number */
111#define function_count_check(sym, size) \
112 compile_time_assert((sym##_FUNCTION_COUNT) == (size),\
113 strings_match_defs_##sym)
114
115/* These strings should be generated using a macro which defines
116 the corresponding symbol values. */
117#define HPI_OBJ_STRINGS \
118{ \
119 "HPI_OBJ_SUBSYSTEM", \
120 "HPI_OBJ_ADAPTER", \
121 "HPI_OBJ_OSTREAM", \
122 "HPI_OBJ_ISTREAM", \
123 "HPI_OBJ_MIXER", \
124 "HPI_OBJ_NODE", \
125 "HPI_OBJ_CONTROL", \
126 "HPI_OBJ_NVMEMORY", \
127 "HPI_OBJ_DIGITALIO", \
128 "HPI_OBJ_WATCHDOG", \
129 "HPI_OBJ_CLOCK", \
130 "HPI_OBJ_PROFILE", \
131 "HPI_OBJ_CONTROLEX" \
132}
133
134#define HPI_SUBSYS_STRINGS \
135{ \
136 "HPI_SUBSYS_OPEN", \
137 "HPI_SUBSYS_GET_VERSION", \
138 "HPI_SUBSYS_GET_INFO", \
139 "HPI_SUBSYS_FIND_ADAPTERS", \
140 "HPI_SUBSYS_CREATE_ADAPTER",\
141 "HPI_SUBSYS_CLOSE", \
142 "HPI_SUBSYS_DELETE_ADAPTER", \
143 "HPI_SUBSYS_DRIVER_LOAD", \
144 "HPI_SUBSYS_DRIVER_UNLOAD", \
145 "HPI_SUBSYS_READ_PORT_8", \
146 "HPI_SUBSYS_WRITE_PORT_8", \
147 "HPI_SUBSYS_GET_NUM_ADAPTERS",\
148 "HPI_SUBSYS_GET_ADAPTER", \
149 "HPI_SUBSYS_SET_NETWORK_INTERFACE"\
150}
151function_count_check(HPI_SUBSYS, 14);
152
153#define HPI_ADAPTER_STRINGS \
154{ \
155 "HPI_ADAPTER_OPEN", \
156 "HPI_ADAPTER_CLOSE", \
157 "HPI_ADAPTER_GET_INFO", \
158 "HPI_ADAPTER_GET_ASSERT", \
159 "HPI_ADAPTER_TEST_ASSERT", \
160 "HPI_ADAPTER_SET_MODE", \
161 "HPI_ADAPTER_GET_MODE", \
162 "HPI_ADAPTER_ENABLE_CAPABILITY",\
163 "HPI_ADAPTER_SELFTEST", \
164 "HPI_ADAPTER_FIND_OBJECT", \
165 "HPI_ADAPTER_QUERY_FLASH", \
166 "HPI_ADAPTER_START_FLASH", \
167 "HPI_ADAPTER_PROGRAM_FLASH", \
168 "HPI_ADAPTER_SET_PROPERTY", \
169 "HPI_ADAPTER_GET_PROPERTY", \
170 "HPI_ADAPTER_ENUM_PROPERTY", \
171 "HPI_ADAPTER_MODULE_INFO", \
172 "HPI_ADAPTER_DEBUG_READ" \
173}
174
175function_count_check(HPI_ADAPTER, 18);
176
177#define HPI_OSTREAM_STRINGS \
178{ \
179 "HPI_OSTREAM_OPEN", \
180 "HPI_OSTREAM_CLOSE", \
181 "HPI_OSTREAM_WRITE", \
182 "HPI_OSTREAM_START", \
183 "HPI_OSTREAM_STOP", \
184 "HPI_OSTREAM_RESET", \
185 "HPI_OSTREAM_GET_INFO", \
186 "HPI_OSTREAM_QUERY_FORMAT", \
187 "HPI_OSTREAM_DATA", \
188 "HPI_OSTREAM_SET_VELOCITY", \
189 "HPI_OSTREAM_SET_PUNCHINOUT", \
190 "HPI_OSTREAM_SINEGEN", \
191 "HPI_OSTREAM_ANC_RESET", \
192 "HPI_OSTREAM_ANC_GET_INFO", \
193 "HPI_OSTREAM_ANC_READ", \
194 "HPI_OSTREAM_SET_TIMESCALE",\
195 "HPI_OSTREAM_SET_FORMAT", \
196 "HPI_OSTREAM_HOSTBUFFER_ALLOC", \
197 "HPI_OSTREAM_HOSTBUFFER_FREE", \
198 "HPI_OSTREAM_GROUP_ADD",\
199 "HPI_OSTREAM_GROUP_GETMAP", \
200 "HPI_OSTREAM_GROUP_RESET", \
201 "HPI_OSTREAM_HOSTBUFFER_GET_INFO", \
202 "HPI_OSTREAM_WAIT_START", \
203}
204function_count_check(HPI_OSTREAM, 24);
205
206#define HPI_ISTREAM_STRINGS \
207{ \
208 "HPI_ISTREAM_OPEN", \
209 "HPI_ISTREAM_CLOSE", \
210 "HPI_ISTREAM_SET_FORMAT", \
211 "HPI_ISTREAM_READ", \
212 "HPI_ISTREAM_START", \
213 "HPI_ISTREAM_STOP", \
214 "HPI_ISTREAM_RESET", \
215 "HPI_ISTREAM_GET_INFO", \
216 "HPI_ISTREAM_QUERY_FORMAT", \
217 "HPI_ISTREAM_ANC_RESET", \
218 "HPI_ISTREAM_ANC_GET_INFO", \
219 "HPI_ISTREAM_ANC_WRITE", \
220 "HPI_ISTREAM_HOSTBUFFER_ALLOC",\
221 "HPI_ISTREAM_HOSTBUFFER_FREE", \
222 "HPI_ISTREAM_GROUP_ADD", \
223 "HPI_ISTREAM_GROUP_GETMAP", \
224 "HPI_ISTREAM_GROUP_RESET", \
225 "HPI_ISTREAM_HOSTBUFFER_GET_INFO", \
226 "HPI_ISTREAM_WAIT_START", \
227}
228function_count_check(HPI_ISTREAM, 19);
229
230#define HPI_MIXER_STRINGS \
231{ \
232 "HPI_MIXER_OPEN", \
233 "HPI_MIXER_CLOSE", \
234 "HPI_MIXER_GET_INFO", \
235 "HPI_MIXER_GET_NODE_INFO", \
236 "HPI_MIXER_GET_CONTROL", \
237 "HPI_MIXER_SET_CONNECTION", \
238 "HPI_MIXER_GET_CONNECTIONS", \
239 "HPI_MIXER_GET_CONTROL_BY_INDEX", \
240 "HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX", \
241 "HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES", \
242 "HPI_MIXER_STORE", \
243}
244function_count_check(HPI_MIXER, 11);
245
246#define HPI_CONTROL_STRINGS \
247{ \
248 "HPI_CONTROL_GET_INFO", \
249 "HPI_CONTROL_GET_STATE", \
250 "HPI_CONTROL_SET_STATE" \
251}
252function_count_check(HPI_CONTROL, 3);
253
254#define HPI_NVMEMORY_STRINGS \
255{ \
256 "HPI_NVMEMORY_OPEN", \
257 "HPI_NVMEMORY_READ_BYTE", \
258 "HPI_NVMEMORY_WRITE_BYTE" \
259}
260function_count_check(HPI_NVMEMORY, 3);
261
262#define HPI_DIGITALIO_STRINGS \
263{ \
264 "HPI_GPIO_OPEN", \
265 "HPI_GPIO_READ_BIT", \
266 "HPI_GPIO_WRITE_BIT", \
267 "HPI_GPIO_READ_ALL", \
268 "HPI_GPIO_WRITE_STATUS"\
269}
270function_count_check(HPI_GPIO, 5);
271
272#define HPI_WATCHDOG_STRINGS \
273{ \
274 "HPI_WATCHDOG_OPEN", \
275 "HPI_WATCHDOG_SET_TIME", \
276 "HPI_WATCHDOG_PING" \
277}
278
279#define HPI_CLOCK_STRINGS \
280{ \
281 "HPI_CLOCK_OPEN", \
282 "HPI_CLOCK_SET_TIME", \
283 "HPI_CLOCK_GET_TIME" \
284}
285
286#define HPI_PROFILE_STRINGS \
287{ \
288 "HPI_PROFILE_OPEN_ALL", \
289 "HPI_PROFILE_START_ALL", \
290 "HPI_PROFILE_STOP_ALL", \
291 "HPI_PROFILE_GET", \
292 "HPI_PROFILE_GET_IDLECOUNT", \
293 "HPI_PROFILE_GET_NAME", \
294 "HPI_PROFILE_GET_UTILIZATION" \
295}
296function_count_check(HPI_PROFILE, 7);
297
298#define HPI_ASYNCEVENT_STRINGS \
299{ \
300 "HPI_ASYNCEVENT_OPEN",\
301 "HPI_ASYNCEVENT_CLOSE ",\
302 "HPI_ASYNCEVENT_WAIT",\
303 "HPI_ASYNCEVENT_GETCOUNT",\
304 "HPI_ASYNCEVENT_GET",\
305 "HPI_ASYNCEVENT_SENDEVENTS"\
306}
307function_count_check(HPI_ASYNCEVENT, 6);
308
309#define HPI_CONTROL_TYPE_STRINGS \
310{ \
311 "null control", \
312 "HPI_CONTROL_CONNECTION", \
313 "HPI_CONTROL_VOLUME", \
314 "HPI_CONTROL_METER", \
315 "HPI_CONTROL_MUTE", \
316 "HPI_CONTROL_MULTIPLEXER", \
317 "HPI_CONTROL_AESEBU_TRANSMITTER", \
318 "HPI_CONTROL_AESEBU_RECEIVER", \
319 "HPI_CONTROL_LEVEL", \
320 "HPI_CONTROL_TUNER", \
321 "HPI_CONTROL_ONOFFSWITCH", \
322 "HPI_CONTROL_VOX", \
323 "HPI_CONTROL_AES18_TRANSMITTER", \
324 "HPI_CONTROL_AES18_RECEIVER", \
325 "HPI_CONTROL_AES18_BLOCKGENERATOR", \
326 "HPI_CONTROL_CHANNEL_MODE", \
327 "HPI_CONTROL_BITSTREAM", \
328 "HPI_CONTROL_SAMPLECLOCK", \
329 "HPI_CONTROL_MICROPHONE", \
330 "HPI_CONTROL_PARAMETRIC_EQ", \
331 "HPI_CONTROL_COMPANDER", \
332 "HPI_CONTROL_COBRANET", \
333 "HPI_CONTROL_TONE_DETECT", \
334 "HPI_CONTROL_SILENCE_DETECT", \
335 "HPI_CONTROL_PAD", \
336 "HPI_CONTROL_SRC" ,\
337 "HPI_CONTROL_UNIVERSAL" \
338}
339
340compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
341 controltype_strings_match_defs);
342
343#define HPI_SOURCENODE_STRINGS \
344{ \
345 "no source", \
346 "HPI_SOURCENODE_OSTREAM", \
347 "HPI_SOURCENODE_LINEIN", \
348 "HPI_SOURCENODE_AESEBU_IN", \
349 "HPI_SOURCENODE_TUNER", \
350 "HPI_SOURCENODE_RF", \
351 "HPI_SOURCENODE_CLOCK_SOURCE", \
352 "HPI_SOURCENODE_RAW_BITSTREAM", \
353 "HPI_SOURCENODE_MICROPHONE", \
354 "HPI_SOURCENODE_COBRANET", \
355 "HPI_SOURCENODE_ANALOG", \
356 "HPI_SOURCENODE_ADAPTER" \
357}
358
359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) ==
360 (12), sourcenode_strings_match_defs);
361
362#define HPI_DESTNODE_STRINGS \
363{ \
364 "no destination", \
365 "HPI_DESTNODE_ISTREAM", \
366 "HPI_DESTNODE_LINEOUT", \
367 "HPI_DESTNODE_AESEBU_OUT", \
368 "HPI_DESTNODE_RF", \
369 "HPI_DESTNODE_SPEAKER", \
370 "HPI_DESTNODE_COBRANET", \
371 "HPI_DESTNODE_ANALOG" \
372}
373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_BASE + 1) == (8),
374 destnode_strings_match_defs);
375
376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
377{ \
378 "XXX HPI_CHANNEL_MODE_ERROR XXX", \
379 "HPI_CHANNEL_MODE_NORMAL", \
380 "HPI_CHANNEL_MODE_SWAP", \
381 "HPI_CHANNEL_MODE_LEFT_ONLY", \
382 "HPI_CHANNEL_MODE_RIGHT_ONLY" \
383}
384
385#endif /* _HPIDEBUG_H */
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
new file mode 100644
index 000000000000..9b10d9a5c255
--- /dev/null
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -0,0 +1,172 @@
1/***********************************************************************/
2/*!
3
4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation;
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20\file
21Functions for reading DSP code to load into DSP
22
23(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
24hotplug firmware loader from individual dsp code files
25
26If neither of the above is defined, code is read from linked arrays.
27DSPCODE_ARRAY is defined.
28
29HPI_INCLUDE_**** must be defined
30and the appropriate hzz?????.c or hex?????.c linked in
31
32 */
33/***********************************************************************/
34#define SOURCEFILE_NAME "hpidspcd.c"
35#include "hpidspcd.h"
36#include "hpidebug.h"
37
38/**
39 Header structure for binary dsp code file (see asidsp.doc)
40 This structure must match that used in s2bin.c for generation of asidsp.bin
41 */
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47struct code_header {
48 u32 size;
49 char type[4];
50 u32 adapter;
51 u32 version;
52 u32 crc;
53};
54
55#ifndef DISABLE_PRAGMA_PACK1
56#pragma pack(pop)
57#endif
58
59#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
61
62/***********************************************************************/
63#include "linux/pci.h"
64/*-------------------------------------------------------------------*/
65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
66 u32 *pos_error_code)
67{
68 const struct firmware *ps_firmware = ps_dsp_code->ps_firmware;
69 struct code_header header;
70 char fw_name[20];
71 int err;
72
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 HPI_DEBUG_LOG(INFO, "requesting firmware for %s\n", fw_name);
75
76 err = request_firmware(&ps_firmware, fw_name,
77 &ps_dsp_code->ps_dev->dev);
78 if (err != 0) {
79 HPI_DEBUG_LOG(ERROR, "%d, request_firmware failed for %s\n",
80 err, fw_name);
81 goto error1;
82 }
83 if (ps_firmware->size < sizeof(header)) {
84 HPI_DEBUG_LOG(ERROR, "header size too small %s\n", fw_name);
85 goto error2;
86 }
87 memcpy(&header, ps_firmware->data, sizeof(header));
88 if (header.adapter != adapter) {
89 HPI_DEBUG_LOG(ERROR, "adapter type incorrect %4x != %4x\n",
90 header.adapter, adapter);
91 goto error2;
92 }
93 if (header.size != ps_firmware->size) {
94 HPI_DEBUG_LOG(ERROR, "code size wrong %d != %ld\n",
95 header.size, (unsigned long)ps_firmware->size);
96 goto error2;
97 }
98
99 if (header.version / 10000 != HPI_VER_DECIMAL / 10000) {
100 HPI_DEBUG_LOG(ERROR,
101 "firmware major version mismatch "
102 "DSP image %d != driver %d\n", header.version,
103 HPI_VER_DECIMAL);
104 goto error2;
105 }
106
107 if (header.version != HPI_VER_DECIMAL) {
108 HPI_DEBUG_LOG(WARNING,
109 "version mismatch DSP image %d != driver %d\n",
110 header.version, HPI_VER_DECIMAL);
111 /* goto error2; still allow driver to load */
112 }
113
114 HPI_DEBUG_LOG(INFO, "dsp code %s opened\n", fw_name);
115 ps_dsp_code->ps_firmware = ps_firmware;
116 ps_dsp_code->block_length = header.size / sizeof(u32);
117 ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
118 ps_dsp_code->version = header.version;
119 ps_dsp_code->crc = header.crc;
120 return 0;
121
122error2:
123 release_firmware(ps_firmware);
124error1:
125 ps_dsp_code->ps_firmware = NULL;
126 ps_dsp_code->block_length = 0;
127 return HPI_ERROR_DSP_FILE_NOT_FOUND;
128}
129
130/*-------------------------------------------------------------------*/
131void hpi_dsp_code_close(struct dsp_code *ps_dsp_code)
132{
133 if (ps_dsp_code->ps_firmware != NULL) {
134 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
135 release_firmware(ps_dsp_code->ps_firmware);
136 ps_dsp_code->ps_firmware = NULL;
137 }
138}
139
140/*-------------------------------------------------------------------*/
141void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
142{
143 /* Go back to start of data, after header */
144 ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
145}
146
147/*-------------------------------------------------------------------*/
148short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
149{
150 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
151 return (HPI_ERROR_DSP_FILE_FORMAT);
152
153 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
154 word_count];
155 ps_dsp_code->word_count++;
156 return 0;
157}
158
159/*-------------------------------------------------------------------*/
160short hpi_dsp_code_read_block(size_t words_requested,
161 struct dsp_code *ps_dsp_code, u32 **ppblock)
162{
163 if (ps_dsp_code->word_count + words_requested >
164 ps_dsp_code->block_length)
165 return HPI_ERROR_DSP_FILE_FORMAT;
166
167 *ppblock =
168 ((u32 *)(ps_dsp_code->ps_firmware->data)) +
169 ps_dsp_code->word_count;
170 ps_dsp_code->word_count += words_requested;
171 return 0;
172}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
new file mode 100644
index 000000000000..d7c240398225
--- /dev/null
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -0,0 +1,104 @@
1/***********************************************************************/
2/**
3
4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation;
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20\file
21Functions for reading DSP code to load into DSP
22
23 hpi_dspcode_defines HPI DSP code loading method
24Define exactly one of these to select how the DSP code is supplied to
25the adapter.
26
27End users writing applications that use the HPI interface do not have to
28use any of the below defines; they are only necessary for building drivers
29
30HPI_DSPCODE_FILE:
31DSP code is supplied as a file that is opened and read from by the driver.
32
33HPI_DSPCODE_FIRMWARE:
34DSP code is read using the hotplug firmware loader module.
35 Only valid when compiling the HPI kernel driver under Linux.
36*/
37/***********************************************************************/
38#ifndef _HPIDSPCD_H_
39#define _HPIDSPCD_H_
40
41#include "hpi_internal.h"
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47/** Descriptor for dspcode from firmware loader */
48struct dsp_code {
49 /** Firmware descriptor */
50 const struct firmware *ps_firmware;
51 struct pci_dev *ps_dev;
52 /** Expected number of words in the whole dsp code,INCL header */
53 long int block_length;
54 /** Number of words read so far */
55 long int word_count;
56 /** Version read from dsp code file */
57 u32 version;
58 /** CRC read from dsp code file */
59 u32 crc;
60};
61
62#ifndef DISABLE_PRAGMA_PACK1
63#pragma pack(pop)
64#endif
65
66/** Prepare *psDspCode to refer to the requuested adapter.
67 Searches the file, or selects the appropriate linked array
68
69\return 0 for success, or error code if requested code is not available
70*/
71short hpi_dsp_code_open(
72 /** Code identifier, usually adapter family */
73 u32 adapter,
74 /** Pointer to DSP code control structure */
75 struct dsp_code *ps_dsp_code,
76 /** Pointer to dword to receive OS specific error code */
77 u32 *pos_error_code);
78
79/** Close the DSP code file */
80void hpi_dsp_code_close(struct dsp_code *ps_dsp_code);
81
82/** Rewind to the beginning of the DSP code file (for verify) */
83void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code);
84
85/** Read one word from the dsp code file
86 \return 0 for success, or error code if eof, or block length exceeded
87*/
88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code,
89 /**< DSP code descriptor */
90 u32 *pword /**< where to store the read word */
91 );
92
93/** Get a block of dsp code into an internal buffer, and provide a pointer to
94that buffer. (If dsp code is already an array in memory, it is referenced,
95not copied.)
96
97\return Error if requested number of words are not available
98*/
99short hpi_dsp_code_read_block(size_t words_requested,
100 struct dsp_code *ps_dsp_code,
101 /* Pointer to store (Pointer to code buffer) */
102 u32 **ppblock);
103
104#endif
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
new file mode 100644
index 000000000000..eda26b312324
--- /dev/null
+++ b/sound/pci/asihpi/hpifunc.c
@@ -0,0 +1,3864 @@
1
2#include "hpi_internal.h"
3#include "hpimsginit.h"
4
5#include "hpidebug.h"
6
7struct hpi_handle {
8 unsigned int obj_index:12;
9 unsigned int obj_type:4;
10 unsigned int adapter_index:14;
11 unsigned int spare:1;
12 unsigned int read_only:1;
13};
14
15union handle_word {
16 struct hpi_handle h;
17 u32 w;
18};
19
20u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
21 const u16 object_index)
22{
23 union handle_word handle;
24
25 handle.h.adapter_index = adapter_index;
26 handle.h.spare = 0;
27 handle.h.read_only = 0;
28 handle.h.obj_type = c_object;
29 handle.h.obj_index = object_index;
30 return handle.w;
31}
32
33void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
34 u16 *pw_object_index)
35{
36 union handle_word uhandle;
37 uhandle.w = handle;
38
39 if (pw_adapter_index)
40 *pw_adapter_index = (u16)uhandle.h.adapter_index;
41 if (pw_object_index)
42 *pw_object_index = (u16)uhandle.h.obj_index;
43}
44
45char hpi_handle_object(const u32 handle)
46{
47 union handle_word uhandle;
48 uhandle.w = handle;
49 return (char)uhandle.h.obj_type;
50}
51
52#define u32TOINDEX(h, i1) \
53do {\
54 if (h == 0) \
55 return HPI_ERROR_INVALID_OBJ; \
56 else \
57 hpi_handle_to_indexes(h, i1, NULL); \
58} while (0)
59
60#define u32TOINDEXES(h, i1, i2) \
61do {\
62 if (h == 0) \
63 return HPI_ERROR_INVALID_OBJ; \
64 else \
65 hpi_handle_to_indexes(h, i1, i2);\
66} while (0)
67
68void hpi_format_to_msg(struct hpi_msg_format *pMF,
69 const struct hpi_format *pF)
70{
71 pMF->sample_rate = pF->sample_rate;
72 pMF->bit_rate = pF->bit_rate;
73 pMF->attributes = pF->attributes;
74 pMF->channels = pF->channels;
75 pMF->format = pF->format;
76}
77
78static void hpi_msg_to_format(struct hpi_format *pF,
79 struct hpi_msg_format *pMF)
80{
81 pF->sample_rate = pMF->sample_rate;
82 pF->bit_rate = pMF->bit_rate;
83 pF->attributes = pMF->attributes;
84 pF->channels = pMF->channels;
85 pF->format = pMF->format;
86 pF->mode_legacy = 0;
87 pF->unused = 0;
88}
89
90void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
91{
92 pSR->u.legacy_stream_info.auxiliary_data_available =
93 pSR->u.stream_info.auxiliary_data_available;
94 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state;
95}
96
97static struct hpi_hsubsys gh_subsys;
98
99struct hpi_hsubsys *hpi_subsys_create(void
100 )
101{
102 struct hpi_message hm;
103 struct hpi_response hr;
104
105 memset(&gh_subsys, 0, sizeof(struct hpi_hsubsys));
106
107 {
108 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
109 HPI_SUBSYS_OPEN);
110 hpi_send_recv(&hm, &hr);
111
112 if (hr.error == 0)
113 return &gh_subsys;
114
115 }
116 return NULL;
117}
118
119void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys)
120{
121 struct hpi_message hm;
122 struct hpi_response hr;
123
124 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
125 HPI_SUBSYS_CLOSE);
126 hpi_send_recv(&hm, &hr);
127
128}
129
130u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys, u32 *pversion)
131{
132 struct hpi_message hm;
133 struct hpi_response hr;
134
135 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
136 HPI_SUBSYS_GET_VERSION);
137 hpi_send_recv(&hm, &hr);
138 *pversion = hr.u.s.version;
139 return hr.error;
140}
141
142u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
143 u32 *pversion_ex)
144{
145 struct hpi_message hm;
146 struct hpi_response hr;
147
148 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
149 HPI_SUBSYS_GET_VERSION);
150 hpi_send_recv(&hm, &hr);
151 *pversion_ex = hr.u.s.data;
152 return hr.error;
153}
154
155u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
156 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
157{
158 struct hpi_message hm;
159 struct hpi_response hr;
160 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
161 HPI_SUBSYS_GET_INFO);
162
163 hpi_send_recv(&hm, &hr);
164
165 *pversion = hr.u.s.version;
166 if (list_length > HPI_MAX_ADAPTERS)
167 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
168 HPI_MAX_ADAPTERS);
169 else
170 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list, list_length);
171 *pw_num_adapters = hr.u.s.num_adapters;
172 return hr.error;
173}
174
175u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
176 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
177{
178 struct hpi_message hm;
179 struct hpi_response hr;
180 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
181 HPI_SUBSYS_FIND_ADAPTERS);
182
183 hpi_send_recv(&hm, &hr);
184
185 if (list_length > HPI_MAX_ADAPTERS) {
186 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
187 HPI_MAX_ADAPTERS * sizeof(u16));
188 memset(&aw_adapter_list[HPI_MAX_ADAPTERS], 0,
189 (list_length - HPI_MAX_ADAPTERS) * sizeof(u16));
190 } else
191 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
192 list_length * sizeof(u16));
193 *pw_num_adapters = hr.u.s.num_adapters;
194
195 return hr.error;
196}
197
198u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
199 const struct hpi_resource *p_resource, u16 *pw_adapter_index)
200{
201 struct hpi_message hm;
202 struct hpi_response hr;
203
204 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
205 HPI_SUBSYS_CREATE_ADAPTER);
206 hm.u.s.resource = *p_resource;
207
208 hpi_send_recv(&hm, &hr);
209
210 *pw_adapter_index = hr.u.s.adapter_index;
211 return hr.error;
212}
213
214u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
215 u16 adapter_index)
216{
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
220 HPI_SUBSYS_DELETE_ADAPTER);
221 hm.adapter_index = adapter_index;
222 hpi_send_recv(&hm, &hr);
223 return hr.error;
224}
225
226u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
227 int *pn_num_adapters)
228{
229 struct hpi_message hm;
230 struct hpi_response hr;
231 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
232 HPI_SUBSYS_GET_NUM_ADAPTERS);
233 hpi_send_recv(&hm, &hr);
234 *pn_num_adapters = (int)hr.u.s.num_adapters;
235 return hr.error;
236}
237
238u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
239 u32 *padapter_index, u16 *pw_adapter_type)
240{
241 struct hpi_message hm;
242 struct hpi_response hr;
243 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
244 HPI_SUBSYS_GET_ADAPTER);
245 hm.adapter_index = (u16)iterator;
246 hpi_send_recv(&hm, &hr);
247 *padapter_index = (int)hr.u.s.adapter_index;
248 *pw_adapter_type = hr.u.s.aw_adapter_list[0];
249 return hr.error;
250}
251
252u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
253 const char *sz_interface)
254{
255 struct hpi_message hm;
256 struct hpi_response hr;
257 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
258 HPI_SUBSYS_SET_NETWORK_INTERFACE);
259 if (sz_interface == NULL)
260 return HPI_ERROR_INVALID_RESOURCE;
261 hm.u.s.resource.r.net_if = sz_interface;
262 hpi_send_recv(&hm, &hr);
263 return hr.error;
264}
265
266u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
267{
268 struct hpi_message hm;
269 struct hpi_response hr;
270 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
271 HPI_ADAPTER_OPEN);
272 hm.adapter_index = adapter_index;
273
274 hpi_send_recv(&hm, &hr);
275
276 return hr.error;
277
278}
279
280u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
281{
282 struct hpi_message hm;
283 struct hpi_response hr;
284 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
285 HPI_ADAPTER_CLOSE);
286 hm.adapter_index = adapter_index;
287
288 hpi_send_recv(&hm, &hr);
289
290 return hr.error;
291}
292
293u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys,
294 u16 adapter_index, u32 adapter_mode)
295{
296 return hpi_adapter_set_mode_ex(ph_subsys, adapter_index, adapter_mode,
297 HPI_ADAPTER_MODE_SET);
298}
299
300u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
301 u16 adapter_index, u32 adapter_mode, u16 query_or_set)
302{
303 struct hpi_message hm;
304 struct hpi_response hr;
305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
306 HPI_ADAPTER_SET_MODE);
307 hm.adapter_index = adapter_index;
308 hm.u.a.adapter_mode = adapter_mode;
309 hm.u.a.assert_id = query_or_set;
310 hpi_send_recv(&hm, &hr);
311 return hr.error;
312}
313
314u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
315 u16 adapter_index, u32 *padapter_mode)
316{
317 struct hpi_message hm;
318 struct hpi_response hr;
319 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
320 HPI_ADAPTER_GET_MODE);
321 hm.adapter_index = adapter_index;
322 hpi_send_recv(&hm, &hr);
323 if (padapter_mode)
324 *padapter_mode = hr.u.a.serial_number;
325 return hr.error;
326}
327
328u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
329 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
330 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type)
331{
332 struct hpi_message hm;
333 struct hpi_response hr;
334 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
335 HPI_ADAPTER_GET_INFO);
336 hm.adapter_index = adapter_index;
337
338 hpi_send_recv(&hm, &hr);
339
340 *pw_adapter_type = hr.u.a.adapter_type;
341 *pw_num_outstreams = hr.u.a.num_outstreams;
342 *pw_num_instreams = hr.u.a.num_instreams;
343 *pw_version = hr.u.a.version;
344 *pserial_number = hr.u.a.serial_number;
345 return hr.error;
346}
347
348u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
349 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
350 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
351 u16 *pw_module_type, u32 *ph_module)
352{
353 struct hpi_message hm;
354 struct hpi_response hr;
355
356 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
357 HPI_ADAPTER_MODULE_INFO);
358 hm.adapter_index = adapter_index;
359 hm.u.ax.module_info.index = module_index;
360
361 hpi_send_recv(&hm, &hr);
362
363 *pw_module_type = hr.u.a.adapter_type;
364 *pw_num_outputs = hr.u.a.num_outstreams;
365 *pw_num_inputs = hr.u.a.num_instreams;
366 *pw_version = hr.u.a.version;
367 *pserial_number = hr.u.a.serial_number;
368 *ph_module = 0;
369
370 return hr.error;
371}
372
373u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
374 u16 adapter_index, u16 *assert_present, char *psz_assert,
375 u16 *pw_line_number)
376{
377 struct hpi_message hm;
378 struct hpi_response hr;
379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
380 HPI_ADAPTER_GET_ASSERT);
381 hm.adapter_index = adapter_index;
382 hpi_send_recv(&hm, &hr);
383
384 *assert_present = 0;
385
386 if (!hr.error) {
387
388 *pw_line_number = (u16)hr.u.a.serial_number;
389 if (*pw_line_number) {
390
391 int i;
392 char *src = (char *)hr.u.a.sz_adapter_assert;
393 char *dst = psz_assert;
394
395 *assert_present = 1;
396
397 for (i = 0; i < HPI_STRING_LEN; i++) {
398 char c;
399 c = *src++;
400 *dst++ = c;
401 if (c == 0)
402 break;
403 }
404
405 }
406 }
407 return hr.error;
408}
409
410u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
411 u16 adapter_index, u16 *assert_present, char *psz_assert,
412 u32 *pline_number, u16 *pw_assert_on_dsp)
413{
414 struct hpi_message hm;
415 struct hpi_response hr;
416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
417 HPI_ADAPTER_GET_ASSERT);
418 hm.adapter_index = adapter_index;
419
420 hpi_send_recv(&hm, &hr);
421
422 *assert_present = 0;
423
424 if (!hr.error) {
425
426 *pline_number = hr.u.a.serial_number;
427
428 *assert_present = hr.u.a.adapter_type;
429
430 *pw_assert_on_dsp = hr.u.a.adapter_index;
431
432 if (!*assert_present && *pline_number)
433
434 *assert_present = 1;
435
436 if (*assert_present) {
437
438 int i;
439 char *src = (char *)hr.u.a.sz_adapter_assert;
440 char *dst = psz_assert;
441
442 for (i = 0; i < HPI_STRING_LEN; i++) {
443 char c;
444 c = *src++;
445 *dst++ = c;
446 if (c == 0)
447 break;
448 }
449
450 } else {
451 *psz_assert = 0;
452 }
453 }
454 return hr.error;
455}
456
457u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
458 u16 adapter_index, u16 assert_id)
459{
460 struct hpi_message hm;
461 struct hpi_response hr;
462 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
463 HPI_ADAPTER_TEST_ASSERT);
464 hm.adapter_index = adapter_index;
465 hm.u.a.assert_id = assert_id;
466
467 hpi_send_recv(&hm, &hr);
468
469 return hr.error;
470}
471
472u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
473 u16 adapter_index, u16 capability, u32 key)
474{
475 struct hpi_message hm;
476 struct hpi_response hr;
477 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
478 HPI_ADAPTER_ENABLE_CAPABILITY);
479 hm.adapter_index = adapter_index;
480 hm.u.a.assert_id = capability;
481 hm.u.a.adapter_mode = key;
482
483 hpi_send_recv(&hm, &hr);
484
485 return hr.error;
486}
487
488u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
489 u16 adapter_index)
490{
491 struct hpi_message hm;
492 struct hpi_response hr;
493 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
494 HPI_ADAPTER_SELFTEST);
495 hm.adapter_index = adapter_index;
496 hpi_send_recv(&hm, &hr);
497 return hr.error;
498}
499
500u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
501 u16 adapter_index, u32 dsp_address, char *p_buffer, int *count_bytes)
502{
503 struct hpi_message hm;
504 struct hpi_response hr;
505 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
506 HPI_ADAPTER_DEBUG_READ);
507
508 hr.size = sizeof(hr);
509
510 hm.adapter_index = adapter_index;
511 hm.u.ax.debug_read.dsp_address = dsp_address;
512
513 if (*count_bytes > sizeof(hr.u.bytes))
514 *count_bytes = sizeof(hr.u.bytes);
515
516 hm.u.ax.debug_read.count_bytes = *count_bytes;
517
518 hpi_send_recv(&hm, &hr);
519
520 if (!hr.error) {
521 *count_bytes = hr.size - 12;
522 memcpy(p_buffer, &hr.u.bytes, *count_bytes);
523 } else
524 *count_bytes = 0;
525 return hr.error;
526}
527
528u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
529 u16 adapter_index, u16 property, u16 parameter1, u16 parameter2)
530{
531 struct hpi_message hm;
532 struct hpi_response hr;
533 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
534 HPI_ADAPTER_SET_PROPERTY);
535 hm.adapter_index = adapter_index;
536 hm.u.ax.property_set.property = property;
537 hm.u.ax.property_set.parameter1 = parameter1;
538 hm.u.ax.property_set.parameter2 = parameter2;
539
540 hpi_send_recv(&hm, &hr);
541
542 return hr.error;
543}
544
545u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
546 u16 adapter_index, u16 property, u16 *pw_parameter1,
547 u16 *pw_parameter2)
548{
549 struct hpi_message hm;
550 struct hpi_response hr;
551 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
552 HPI_ADAPTER_GET_PROPERTY);
553 hm.adapter_index = adapter_index;
554 hm.u.ax.property_set.property = property;
555
556 hpi_send_recv(&hm, &hr);
557 if (!hr.error) {
558 if (pw_parameter1)
559 *pw_parameter1 = hr.u.ax.property_get.parameter1;
560 if (pw_parameter2)
561 *pw_parameter2 = hr.u.ax.property_get.parameter2;
562 }
563
564 return hr.error;
565}
566
567u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
568 u16 adapter_index, u16 index, u16 what_to_enumerate,
569 u16 property_index, u32 *psetting)
570{
571 return 0;
572}
573
574u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
575 u32 sample_rate, u32 bit_rate, u32 attributes)
576{
577 u16 error = 0;
578 struct hpi_msg_format fmt;
579
580 switch (channels) {
581 case 1:
582 case 2:
583 case 4:
584 case 6:
585 case 8:
586 case 16:
587 break;
588 default:
589 error = HPI_ERROR_INVALID_CHANNELS;
590 return error;
591 }
592 fmt.channels = channels;
593
594 switch (format) {
595 case HPI_FORMAT_PCM16_SIGNED:
596 case HPI_FORMAT_PCM24_SIGNED:
597 case HPI_FORMAT_PCM32_SIGNED:
598 case HPI_FORMAT_PCM32_FLOAT:
599 case HPI_FORMAT_PCM16_BIGENDIAN:
600 case HPI_FORMAT_PCM8_UNSIGNED:
601 case HPI_FORMAT_MPEG_L1:
602 case HPI_FORMAT_MPEG_L2:
603 case HPI_FORMAT_MPEG_L3:
604 case HPI_FORMAT_DOLBY_AC2:
605 case HPI_FORMAT_AA_TAGIT1_HITS:
606 case HPI_FORMAT_AA_TAGIT1_INSERTS:
607 case HPI_FORMAT_RAW_BITSTREAM:
608 case HPI_FORMAT_AA_TAGIT1_HITS_EX1:
609 case HPI_FORMAT_OEM1:
610 case HPI_FORMAT_OEM2:
611 break;
612 default:
613 error = HPI_ERROR_INVALID_FORMAT;
614 return error;
615 }
616 fmt.format = format;
617
618 if (sample_rate < 8000L) {
619 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
620 sample_rate = 8000L;
621 }
622 if (sample_rate > 200000L) {
623 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
624 sample_rate = 200000L;
625 }
626 fmt.sample_rate = sample_rate;
627
628 switch (format) {
629 case HPI_FORMAT_MPEG_L1:
630 case HPI_FORMAT_MPEG_L2:
631 case HPI_FORMAT_MPEG_L3:
632 fmt.bit_rate = bit_rate;
633 break;
634 case HPI_FORMAT_PCM16_SIGNED:
635 case HPI_FORMAT_PCM16_BIGENDIAN:
636 fmt.bit_rate = channels * sample_rate * 2;
637 break;
638 case HPI_FORMAT_PCM32_SIGNED:
639 case HPI_FORMAT_PCM32_FLOAT:
640 fmt.bit_rate = channels * sample_rate * 4;
641 break;
642 case HPI_FORMAT_PCM8_UNSIGNED:
643 fmt.bit_rate = channels * sample_rate;
644 break;
645 default:
646 fmt.bit_rate = 0;
647 }
648
649 switch (format) {
650 case HPI_FORMAT_MPEG_L2:
651 if ((channels == 1)
652 && (attributes != HPI_MPEG_MODE_DEFAULT)) {
653 attributes = HPI_MPEG_MODE_DEFAULT;
654 error = HPI_ERROR_INVALID_FORMAT;
655 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) {
656 attributes = HPI_MPEG_MODE_DEFAULT;
657 error = HPI_ERROR_INVALID_FORMAT;
658 }
659 fmt.attributes = attributes;
660 break;
661 default:
662 fmt.attributes = attributes;
663 }
664
665 hpi_msg_to_format(p_format, &fmt);
666 return error;
667}
668
669u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
670 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size)
671{
672
673 u32 bytes_per_second;
674 u32 size;
675 u16 channels;
676 struct hpi_format *pF = p_format;
677
678 channels = pF->channels;
679
680 switch (pF->format) {
681 case HPI_FORMAT_PCM16_BIGENDIAN:
682 case HPI_FORMAT_PCM16_SIGNED:
683 bytes_per_second = pF->sample_rate * 2L * channels;
684 break;
685 case HPI_FORMAT_PCM24_SIGNED:
686 bytes_per_second = pF->sample_rate * 3L * channels;
687 break;
688 case HPI_FORMAT_PCM32_SIGNED:
689 case HPI_FORMAT_PCM32_FLOAT:
690 bytes_per_second = pF->sample_rate * 4L * channels;
691 break;
692 case HPI_FORMAT_PCM8_UNSIGNED:
693 bytes_per_second = pF->sample_rate * 1L * channels;
694 break;
695 case HPI_FORMAT_MPEG_L1:
696 case HPI_FORMAT_MPEG_L2:
697 case HPI_FORMAT_MPEG_L3:
698 bytes_per_second = pF->bit_rate / 8L;
699 break;
700 case HPI_FORMAT_DOLBY_AC2:
701
702 bytes_per_second = 256000L / 8L;
703 break;
704 default:
705 return HPI_ERROR_INVALID_FORMAT;
706 }
707 size = (bytes_per_second * host_polling_rate_in_milli_seconds * 2) /
708 1000L;
709
710 *recommended_buffer_size =
711 roundup_pow_of_two(((size + 4095L) & ~4095L));
712 return 0;
713}
714
715u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
716 u16 outstream_index, u32 *ph_outstream)
717{
718 struct hpi_message hm;
719 struct hpi_response hr;
720 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
721 HPI_OSTREAM_OPEN);
722 hm.adapter_index = adapter_index;
723 hm.obj_index = outstream_index;
724
725 hpi_send_recv(&hm, &hr);
726
727 if (hr.error == 0)
728 *ph_outstream =
729 hpi_indexes_to_handle(HPI_OBJ_OSTREAM, adapter_index,
730 outstream_index);
731 else
732 *ph_outstream = 0;
733 return hr.error;
734}
735
736u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
737{
738 struct hpi_message hm;
739 struct hpi_response hr;
740
741 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
742 HPI_OSTREAM_HOSTBUFFER_FREE);
743 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
744 hpi_send_recv(&hm, &hr);
745
746 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
747 HPI_OSTREAM_GROUP_RESET);
748 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
749 hpi_send_recv(&hm, &hr);
750
751 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
752 HPI_OSTREAM_CLOSE);
753 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
754 hpi_send_recv(&hm, &hr);
755
756 return hr.error;
757}
758
759u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
760 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play,
761 u32 *psamples_played, u32 *pauxiliary_data_to_play)
762{
763 struct hpi_message hm;
764 struct hpi_response hr;
765 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
766 HPI_OSTREAM_GET_INFO);
767 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
768
769 hpi_send_recv(&hm, &hr);
770
771 if (pw_state)
772 *pw_state = hr.u.d.u.stream_info.state;
773 if (pbuffer_size)
774 *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
775 if (pdata_to_play)
776 *pdata_to_play = hr.u.d.u.stream_info.data_available;
777 if (psamples_played)
778 *psamples_played = hr.u.d.u.stream_info.samples_transferred;
779 if (pauxiliary_data_to_play)
780 *pauxiliary_data_to_play =
781 hr.u.d.u.stream_info.auxiliary_data_available;
782 return hr.error;
783}
784
785u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
786 u32 h_outstream, const u8 *pb_data, u32 bytes_to_write,
787 const struct hpi_format *p_format)
788{
789 struct hpi_message hm;
790 struct hpi_response hr;
791 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
792 HPI_OSTREAM_WRITE);
793 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
794 hm.u.d.u.data.pb_data = (u8 *)pb_data;
795 hm.u.d.u.data.data_size = bytes_to_write;
796
797 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
798
799 hpi_send_recv(&hm, &hr);
800
801 return hr.error;
802}
803
804u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
805{
806 struct hpi_message hm;
807 struct hpi_response hr;
808 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
809 HPI_OSTREAM_START);
810 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
811
812 hpi_send_recv(&hm, &hr);
813
814 return hr.error;
815}
816
817u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys,
818 u32 h_outstream)
819{
820 struct hpi_message hm;
821 struct hpi_response hr;
822 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
823 HPI_OSTREAM_WAIT_START);
824 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
825
826 hpi_send_recv(&hm, &hr);
827
828 return hr.error;
829}
830
831u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
832{
833 struct hpi_message hm;
834 struct hpi_response hr;
835 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
836 HPI_OSTREAM_STOP);
837 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
838
839 hpi_send_recv(&hm, &hr);
840
841 return hr.error;
842}
843
844u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys,
845 u32 h_outstream)
846{
847 struct hpi_message hm;
848 struct hpi_response hr;
849 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
850 HPI_OSTREAM_SINEGEN);
851 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
852
853 hpi_send_recv(&hm, &hr);
854
855 return hr.error;
856}
857
858u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
859{
860 struct hpi_message hm;
861 struct hpi_response hr;
862 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
863 HPI_OSTREAM_RESET);
864 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
865
866 hpi_send_recv(&hm, &hr);
867
868 return hr.error;
869}
870
871u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
872 u32 h_outstream, struct hpi_format *p_format)
873{
874 struct hpi_message hm;
875 struct hpi_response hr;
876
877 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
878 HPI_OSTREAM_QUERY_FORMAT);
879 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
880
881 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
882
883 hpi_send_recv(&hm, &hr);
884
885 return hr.error;
886}
887
888u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
889 u32 h_outstream, struct hpi_format *p_format)
890{
891 struct hpi_message hm;
892 struct hpi_response hr;
893
894 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
895 HPI_OSTREAM_SET_FORMAT);
896 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
897
898 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
899
900 hpi_send_recv(&hm, &hr);
901
902 return hr.error;
903}
904
905u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
906 u32 h_outstream, short velocity)
907{
908 struct hpi_message hm;
909 struct hpi_response hr;
910
911 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
912 HPI_OSTREAM_SET_VELOCITY);
913 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
914 hm.u.d.u.velocity = velocity;
915
916 hpi_send_recv(&hm, &hr);
917
918 return hr.error;
919}
920
921u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
922 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample)
923{
924 struct hpi_message hm;
925 struct hpi_response hr;
926
927 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
928 HPI_OSTREAM_SET_PUNCHINOUT);
929 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
930
931 hm.u.d.u.pio.punch_in_sample = punch_in_sample;
932 hm.u.d.u.pio.punch_out_sample = punch_out_sample;
933
934 hpi_send_recv(&hm, &hr);
935
936 return hr.error;
937}
938
939u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
940 u32 h_outstream, u16 mode)
941{
942 struct hpi_message hm;
943 struct hpi_response hr;
944
945 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
946 HPI_OSTREAM_ANC_RESET);
947 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
948 hm.u.d.u.data.format.channels = mode;
949 hpi_send_recv(&hm, &hr);
950 return hr.error;
951}
952
953u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
954 u32 h_outstream, u32 *pframes_available)
955{
956 struct hpi_message hm;
957 struct hpi_response hr;
958
959 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
960 HPI_OSTREAM_ANC_GET_INFO);
961 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
962 hpi_send_recv(&hm, &hr);
963 if (hr.error == 0) {
964 if (pframes_available)
965 *pframes_available =
966 hr.u.d.u.stream_info.data_available /
967 sizeof(struct hpi_anc_frame);
968 }
969 return hr.error;
970}
971
972u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
973 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer,
974 u32 anc_frame_buffer_size_in_bytes,
975 u32 number_of_ancillary_frames_to_read)
976{
977 struct hpi_message hm;
978 struct hpi_response hr;
979 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
980 HPI_OSTREAM_ANC_READ);
981 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
982 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
983 hm.u.d.u.data.data_size =
984 number_of_ancillary_frames_to_read *
985 sizeof(struct hpi_anc_frame);
986 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
987 hpi_send_recv(&hm, &hr);
988 else
989 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER;
990 return hr.error;
991}
992
993u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
994 u32 h_outstream, u32 time_scale)
995{
996 struct hpi_message hm;
997 struct hpi_response hr;
998
999 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1000 HPI_OSTREAM_SET_TIMESCALE);
1001 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1002
1003 hm.u.d.u.time_scale = time_scale;
1004
1005 hpi_send_recv(&hm, &hr);
1006
1007 return hr.error;
1008}
1009
1010u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1011 u32 h_outstream, u32 size_in_bytes)
1012{
1013 struct hpi_message hm;
1014 struct hpi_response hr;
1015
1016 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1017 HPI_OSTREAM_HOSTBUFFER_ALLOC);
1018 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1019 hm.u.d.u.data.data_size = size_in_bytes;
1020 hpi_send_recv(&hm, &hr);
1021 return hr.error;
1022}
1023
1024u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1025 u32 h_outstream, u8 **pp_buffer,
1026 struct hpi_hostbuffer_status **pp_status)
1027{
1028 struct hpi_message hm;
1029 struct hpi_response hr;
1030
1031 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1032 HPI_OSTREAM_HOSTBUFFER_GET_INFO);
1033 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1034 hpi_send_recv(&hm, &hr);
1035
1036 if (hr.error == 0) {
1037 if (pp_buffer)
1038 *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
1039 if (pp_status)
1040 *pp_status = hr.u.d.u.hostbuffer_info.p_status;
1041 }
1042 return hr.error;
1043}
1044
1045u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1046 u32 h_outstream)
1047{
1048 struct hpi_message hm;
1049 struct hpi_response hr;
1050
1051 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1052 HPI_OSTREAM_HOSTBUFFER_FREE);
1053 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1054 hpi_send_recv(&hm, &hr);
1055 return hr.error;
1056}
1057
1058u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1059 u32 h_outstream, u32 h_stream)
1060{
1061 struct hpi_message hm;
1062 struct hpi_response hr;
1063 u16 adapter;
1064 char c_obj_type;
1065
1066 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1067 HPI_OSTREAM_GROUP_ADD);
1068 hr.error = 0;
1069 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1070 c_obj_type = hpi_handle_object(h_stream);
1071 switch (c_obj_type) {
1072 case HPI_OBJ_OSTREAM:
1073 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1074 u32TOINDEXES(h_stream, &adapter,
1075 &hm.u.d.u.stream.stream_index);
1076 break;
1077 case HPI_OBJ_ISTREAM:
1078 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM;
1079 u32TOINDEXES(h_stream, &adapter,
1080 &hm.u.d.u.stream.stream_index);
1081 break;
1082 default:
1083 return HPI_ERROR_INVALID_STREAM;
1084 }
1085 if (adapter != hm.adapter_index)
1086 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
1087
1088 hpi_send_recv(&hm, &hr);
1089 return hr.error;
1090}
1091
1092u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1093 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map)
1094{
1095 struct hpi_message hm;
1096 struct hpi_response hr;
1097
1098 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1099 HPI_OSTREAM_GROUP_GETMAP);
1100 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1101 hpi_send_recv(&hm, &hr);
1102
1103 if (poutstream_map)
1104 *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
1105 if (pinstream_map)
1106 *pinstream_map = hr.u.d.u.group_info.instream_group_map;
1107
1108 return hr.error;
1109}
1110
1111u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys,
1112 u32 h_outstream)
1113{
1114 struct hpi_message hm;
1115 struct hpi_response hr;
1116
1117 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1118 HPI_OSTREAM_GROUP_RESET);
1119 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1120 hpi_send_recv(&hm, &hr);
1121 return hr.error;
1122}
1123
1124u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1125 u16 instream_index, u32 *ph_instream)
1126{
1127 struct hpi_message hm;
1128 struct hpi_response hr;
1129
1130 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1131 HPI_ISTREAM_OPEN);
1132 hm.adapter_index = adapter_index;
1133 hm.obj_index = instream_index;
1134
1135 hpi_send_recv(&hm, &hr);
1136
1137 if (hr.error == 0)
1138 *ph_instream =
1139 hpi_indexes_to_handle(HPI_OBJ_ISTREAM, adapter_index,
1140 instream_index);
1141 else
1142 *ph_instream = 0;
1143
1144 return hr.error;
1145}
1146
1147u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1148{
1149 struct hpi_message hm;
1150 struct hpi_response hr;
1151
1152 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1153 HPI_ISTREAM_HOSTBUFFER_FREE);
1154 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1155 hpi_send_recv(&hm, &hr);
1156
1157 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1158 HPI_ISTREAM_GROUP_RESET);
1159 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1160 hpi_send_recv(&hm, &hr);
1161
1162 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1163 HPI_ISTREAM_CLOSE);
1164 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1165 hpi_send_recv(&hm, &hr);
1166
1167 return hr.error;
1168}
1169
1170u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1171 u32 h_instream, const struct hpi_format *p_format)
1172{
1173 struct hpi_message hm;
1174 struct hpi_response hr;
1175
1176 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1177 HPI_ISTREAM_QUERY_FORMAT);
1178 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1179 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1180
1181 hpi_send_recv(&hm, &hr);
1182
1183 return hr.error;
1184}
1185
1186u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1187 u32 h_instream, const struct hpi_format *p_format)
1188{
1189 struct hpi_message hm;
1190 struct hpi_response hr;
1191
1192 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1193 HPI_ISTREAM_SET_FORMAT);
1194 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1195 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1196
1197 hpi_send_recv(&hm, &hr);
1198
1199 return hr.error;
1200}
1201
1202u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1203 u8 *pb_data, u32 bytes_to_read)
1204{
1205 struct hpi_message hm;
1206 struct hpi_response hr;
1207
1208 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1209 HPI_ISTREAM_READ);
1210 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1211 hm.u.d.u.data.data_size = bytes_to_read;
1212 hm.u.d.u.data.pb_data = pb_data;
1213
1214 hpi_send_recv(&hm, &hr);
1215
1216 return hr.error;
1217}
1218
1219u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1220{
1221 struct hpi_message hm;
1222 struct hpi_response hr;
1223
1224 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1225 HPI_ISTREAM_START);
1226 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1227
1228 hpi_send_recv(&hm, &hr);
1229
1230 return hr.error;
1231}
1232
1233u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys,
1234 u32 h_instream)
1235{
1236 struct hpi_message hm;
1237 struct hpi_response hr;
1238
1239 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1240 HPI_ISTREAM_WAIT_START);
1241 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1242
1243 hpi_send_recv(&hm, &hr);
1244
1245 return hr.error;
1246}
1247
1248u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1249{
1250 struct hpi_message hm;
1251 struct hpi_response hr;
1252
1253 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1254 HPI_ISTREAM_STOP);
1255 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1256
1257 hpi_send_recv(&hm, &hr);
1258
1259 return hr.error;
1260}
1261
1262u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1263{
1264 struct hpi_message hm;
1265 struct hpi_response hr;
1266
1267 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1268 HPI_ISTREAM_RESET);
1269 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1270
1271 hpi_send_recv(&hm, &hr);
1272
1273 return hr.error;
1274}
1275
1276u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1277 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded,
1278 u32 *psamples_recorded, u32 *pauxiliary_data_recorded)
1279{
1280 struct hpi_message hm;
1281 struct hpi_response hr;
1282 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1283 HPI_ISTREAM_GET_INFO);
1284 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1285
1286 hpi_send_recv(&hm, &hr);
1287
1288 if (pw_state)
1289 *pw_state = hr.u.d.u.stream_info.state;
1290 if (pbuffer_size)
1291 *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
1292 if (pdata_recorded)
1293 *pdata_recorded = hr.u.d.u.stream_info.data_available;
1294 if (psamples_recorded)
1295 *psamples_recorded = hr.u.d.u.stream_info.samples_transferred;
1296 if (pauxiliary_data_recorded)
1297 *pauxiliary_data_recorded =
1298 hr.u.d.u.stream_info.auxiliary_data_available;
1299 return hr.error;
1300}
1301
1302u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1303 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment,
1304 u16 idle_bit)
1305{
1306 struct hpi_message hm;
1307 struct hpi_response hr;
1308 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1309 HPI_ISTREAM_ANC_RESET);
1310 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1311 hm.u.d.u.data.format.attributes = bytes_per_frame;
1312 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff);
1313 hm.u.d.u.data.format.channels = idle_bit;
1314 hpi_send_recv(&hm, &hr);
1315 return hr.error;
1316}
1317
1318u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1319 u32 h_instream, u32 *pframe_space)
1320{
1321 struct hpi_message hm;
1322 struct hpi_response hr;
1323 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1324 HPI_ISTREAM_ANC_GET_INFO);
1325 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1326 hpi_send_recv(&hm, &hr);
1327 if (pframe_space)
1328 *pframe_space =
1329 (hr.u.d.u.stream_info.buffer_size -
1330 hr.u.d.u.stream_info.data_available) /
1331 sizeof(struct hpi_anc_frame);
1332 return hr.error;
1333}
1334
1335u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1336 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer,
1337 u32 anc_frame_buffer_size_in_bytes,
1338 u32 number_of_ancillary_frames_to_write)
1339{
1340 struct hpi_message hm;
1341 struct hpi_response hr;
1342
1343 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1344 HPI_ISTREAM_ANC_WRITE);
1345 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1346 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
1347 hm.u.d.u.data.data_size =
1348 number_of_ancillary_frames_to_write *
1349 sizeof(struct hpi_anc_frame);
1350 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
1351 hpi_send_recv(&hm, &hr);
1352 else
1353 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER;
1354 return hr.error;
1355}
1356
1357u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1358 u32 h_instream, u32 size_in_bytes)
1359{
1360
1361 struct hpi_message hm;
1362 struct hpi_response hr;
1363
1364 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1365 HPI_ISTREAM_HOSTBUFFER_ALLOC);
1366 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1367 hm.u.d.u.data.data_size = size_in_bytes;
1368 hpi_send_recv(&hm, &hr);
1369 return hr.error;
1370}
1371
1372u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1373 u32 h_instream, u8 **pp_buffer,
1374 struct hpi_hostbuffer_status **pp_status)
1375{
1376 struct hpi_message hm;
1377 struct hpi_response hr;
1378
1379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1380 HPI_ISTREAM_HOSTBUFFER_GET_INFO);
1381 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1382 hpi_send_recv(&hm, &hr);
1383
1384 if (hr.error == 0) {
1385 if (pp_buffer)
1386 *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
1387 if (pp_status)
1388 *pp_status = hr.u.d.u.hostbuffer_info.p_status;
1389 }
1390 return hr.error;
1391}
1392
1393u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1394 u32 h_instream)
1395{
1396
1397 struct hpi_message hm;
1398 struct hpi_response hr;
1399
1400 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1401 HPI_ISTREAM_HOSTBUFFER_FREE);
1402 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1403 hpi_send_recv(&hm, &hr);
1404 return hr.error;
1405}
1406
1407u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1408 u32 h_instream, u32 h_stream)
1409{
1410 struct hpi_message hm;
1411 struct hpi_response hr;
1412 u16 adapter;
1413 char c_obj_type;
1414
1415 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1416 HPI_ISTREAM_GROUP_ADD);
1417 hr.error = 0;
1418 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1419 c_obj_type = hpi_handle_object(h_stream);
1420
1421 switch (c_obj_type) {
1422 case HPI_OBJ_OSTREAM:
1423 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1424 u32TOINDEXES(h_stream, &adapter,
1425 &hm.u.d.u.stream.stream_index);
1426 break;
1427 case HPI_OBJ_ISTREAM:
1428 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM;
1429 u32TOINDEXES(h_stream, &adapter,
1430 &hm.u.d.u.stream.stream_index);
1431 break;
1432 default:
1433 return HPI_ERROR_INVALID_STREAM;
1434 }
1435
1436 if (adapter != hm.adapter_index)
1437 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
1438
1439 hpi_send_recv(&hm, &hr);
1440 return hr.error;
1441}
1442
1443u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1444 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map)
1445{
1446 struct hpi_message hm;
1447 struct hpi_response hr;
1448
1449 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1450 HPI_ISTREAM_HOSTBUFFER_FREE);
1451 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1452 hpi_send_recv(&hm, &hr);
1453
1454 if (poutstream_map)
1455 *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
1456 if (pinstream_map)
1457 *pinstream_map = hr.u.d.u.group_info.instream_group_map;
1458
1459 return hr.error;
1460}
1461
1462u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys,
1463 u32 h_instream)
1464{
1465 struct hpi_message hm;
1466 struct hpi_response hr;
1467
1468 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1469 HPI_ISTREAM_GROUP_RESET);
1470 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1471 hpi_send_recv(&hm, &hr);
1472 return hr.error;
1473}
1474
1475u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1476 u32 *ph_mixer)
1477{
1478 struct hpi_message hm;
1479 struct hpi_response hr;
1480 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
1481 hm.adapter_index = adapter_index;
1482
1483 hpi_send_recv(&hm, &hr);
1484
1485 if (hr.error == 0)
1486 *ph_mixer =
1487 hpi_indexes_to_handle(HPI_OBJ_MIXER, adapter_index,
1488 0);
1489 else
1490 *ph_mixer = 0;
1491 return hr.error;
1492}
1493
1494u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer)
1495{
1496 struct hpi_message hm;
1497 struct hpi_response hr;
1498 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE);
1499 u32TOINDEX(h_mixer, &hm.adapter_index);
1500 hpi_send_recv(&hm, &hr);
1501 return hr.error;
1502}
1503
1504u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1505 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type,
1506 u16 dst_node_type_index, u16 control_type, u32 *ph_control)
1507{
1508 struct hpi_message hm;
1509 struct hpi_response hr;
1510 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1511 HPI_MIXER_GET_CONTROL);
1512 u32TOINDEX(h_mixer, &hm.adapter_index);
1513 hm.u.m.node_type1 = src_node_type;
1514 hm.u.m.node_index1 = src_node_type_index;
1515 hm.u.m.node_type2 = dst_node_type;
1516 hm.u.m.node_index2 = dst_node_type_index;
1517 hm.u.m.control_type = control_type;
1518
1519 hpi_send_recv(&hm, &hr);
1520
1521 if (hr.error == 0)
1522 *ph_control =
1523 hpi_indexes_to_handle(HPI_OBJ_CONTROL,
1524 hm.adapter_index, hr.u.m.control_index);
1525 else
1526 *ph_control = 0;
1527 return hr.error;
1528}
1529
1530u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1531 u32 h_mixer, u16 control_index, u16 *pw_src_node_type,
1532 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index,
1533 u16 *pw_control_type, u32 *ph_control)
1534{
1535 struct hpi_message hm;
1536 struct hpi_response hr;
1537 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1538 HPI_MIXER_GET_CONTROL_BY_INDEX);
1539 u32TOINDEX(h_mixer, &hm.adapter_index);
1540 hm.u.m.control_index = control_index;
1541 hpi_send_recv(&hm, &hr);
1542
1543 if (pw_src_node_type) {
1544 *pw_src_node_type =
1545 hr.u.m.src_node_type + HPI_SOURCENODE_NONE;
1546 *pw_src_node_index = hr.u.m.src_node_index;
1547 *pw_dst_node_type = hr.u.m.dst_node_type + HPI_DESTNODE_NONE;
1548 *pw_dst_node_index = hr.u.m.dst_node_index;
1549 }
1550 if (pw_control_type)
1551 *pw_control_type = hr.u.m.control_index;
1552
1553 if (ph_control) {
1554 if (hr.error == 0)
1555 *ph_control =
1556 hpi_indexes_to_handle(HPI_OBJ_CONTROL,
1557 hm.adapter_index, control_index);
1558 else
1559 *ph_control = 0;
1560 }
1561 return hr.error;
1562}
1563
1564u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1565 enum HPI_MIXER_STORE_COMMAND command, u16 index)
1566{
1567 struct hpi_message hm;
1568 struct hpi_response hr;
1569 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE);
1570 u32TOINDEX(h_mixer, &hm.adapter_index);
1571 hm.u.mx.store.command = command;
1572 hm.u.mx.store.index = index;
1573 hpi_send_recv(&hm, &hr);
1574 return hr.error;
1575}
1576
1577static
1578u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
1579 const u32 h_control, const u16 attrib, const u32 param1,
1580 const u32 param2)
1581{
1582 struct hpi_message hm;
1583 struct hpi_response hr;
1584 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1585 HPI_CONTROL_SET_STATE);
1586 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1587 hm.u.c.attribute = attrib;
1588 hm.u.c.param1 = param1;
1589 hm.u.c.param2 = param2;
1590 hpi_send_recv(&hm, &hr);
1591 return hr.error;
1592}
1593
1594static
1595u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1596 const u32 h_control, const u16 attrib, u32 param1, u32 param2,
1597 u32 *pparam1, u32 *pparam2)
1598{
1599 struct hpi_message hm;
1600 struct hpi_response hr;
1601 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1602 HPI_CONTROL_GET_STATE);
1603 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1604 hm.u.c.attribute = attrib;
1605 hm.u.c.param1 = param1;
1606 hm.u.c.param2 = param2;
1607 hpi_send_recv(&hm, &hr);
1608 if (pparam1)
1609 *pparam1 = hr.u.c.param1;
1610 if (pparam2)
1611 *pparam2 = hr.u.c.param2;
1612
1613 return hr.error;
1614}
1615
1616#define hpi_control_param1_get(s, h, a, p1) \
1617 hpi_control_param_get(s, h, a, 0, 0, p1, NULL)
1618#define hpi_control_param2_get(s, h, a, p1, p2) \
1619 hpi_control_param_get(s, h, a, 0, 0, p1, p2)
1620#define hpi_control_ex_param1_get(s, h, a, p1) \
1621 hpi_control_ex_param_get(s, h, a, 0, 0, p1, NULL)
1622#define hpi_control_ex_param2_get(s, h, a, p1, p2) \
1623 hpi_control_ex_param_get(s, h, a, 0, 0, p1, p2)
1624
1625static
1626u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1627 const u32 h_control, const u16 attrib, const u32 index,
1628 const u32 param, u32 *psetting)
1629{
1630 struct hpi_message hm;
1631 struct hpi_response hr;
1632 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1633 HPI_CONTROL_GET_INFO);
1634 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1635
1636 hm.u.c.attribute = attrib;
1637 hm.u.c.param1 = index;
1638 hm.u.c.param2 = param;
1639
1640 hpi_send_recv(&hm, &hr);
1641 *psetting = hr.u.c.param1;
1642
1643 return hr.error;
1644}
1645
1646static u16 hpi_control_get_string(const struct hpi_hsubsys *ph_subsys,
1647 const u32 h_control, const u16 attribute, char *psz_string,
1648 const u32 string_length)
1649{
1650 unsigned int sub_string_index = 0, j = 0;
1651 char c = 0;
1652 unsigned int n = 0;
1653 u16 hE = 0;
1654
1655 if ((string_length < 1) || (string_length > 256))
1656 return HPI_ERROR_INVALID_CONTROL_VALUE;
1657 for (sub_string_index = 0; sub_string_index < string_length;
1658 sub_string_index += 8) {
1659 struct hpi_message hm;
1660 struct hpi_response hr;
1661
1662 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1663 HPI_CONTROL_GET_STATE);
1664 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1665 hm.u.c.attribute = attribute;
1666 hm.u.c.param1 = sub_string_index;
1667 hm.u.c.param2 = 0;
1668 hpi_send_recv(&hm, &hr);
1669
1670 if (sub_string_index == 0
1671 && (hr.u.cu.chars8.remaining_chars + 8) >
1672 string_length)
1673 return HPI_ERROR_INVALID_CONTROL_VALUE;
1674
1675 if (hr.error) {
1676 hE = hr.error;
1677 break;
1678 }
1679 for (j = 0; j < 8; j++) {
1680 c = hr.u.cu.chars8.sz_data[j];
1681 psz_string[sub_string_index + j] = c;
1682 n++;
1683 if (n >= string_length) {
1684 psz_string[string_length - 1] = 0;
1685 hE = HPI_ERROR_INVALID_CONTROL_VALUE;
1686 break;
1687 }
1688 if (c == 0)
1689 break;
1690 }
1691
1692 if ((hr.u.cu.chars8.remaining_chars == 0)
1693 && ((sub_string_index + j) < string_length)
1694 && (c != 0)) {
1695 c = 0;
1696 psz_string[sub_string_index + j] = c;
1697 }
1698 if (c == 0)
1699 break;
1700 }
1701 return hE;
1702}
1703
1704u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys,
1705 const u32 h_aes_rx, const u32 index, u16 *pw_format)
1706{
1707 u32 qr;
1708 u16 err;
1709
1710 err = hpi_control_query(ph_subsys, h_aes_rx, HPI_AESEBURX_FORMAT,
1711 index, 0, &qr);
1712 *pw_format = (u16)qr;
1713 return err;
1714}
1715
1716u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys,
1717 u32 h_control, u16 format)
1718{
1719 return hpi_control_param_set(ph_subsys, h_control,
1720 HPI_AESEBURX_FORMAT, format, 0);
1721}
1722
1723u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys,
1724 u32 h_control, u16 *pw_format)
1725{
1726 u16 err;
1727 u32 param;
1728
1729 err = hpi_control_param1_get(ph_subsys, h_control,
1730 HPI_AESEBURX_FORMAT, &param);
1731 if (!err && pw_format)
1732 *pw_format = (u16)param;
1733
1734 return err;
1735}
1736
1737u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1738 u32 h_control, u32 *psample_rate)
1739{
1740 return hpi_control_param1_get(ph_subsys, h_control,
1741 HPI_AESEBURX_SAMPLERATE, psample_rate);
1742}
1743
1744u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1745 u32 h_control, u16 index, u16 *pw_data)
1746{
1747 struct hpi_message hm;
1748 struct hpi_response hr;
1749 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1750 HPI_CONTROL_GET_STATE);
1751 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1752 hm.u.c.attribute = HPI_AESEBURX_USERDATA;
1753 hm.u.c.param1 = index;
1754
1755 hpi_send_recv(&hm, &hr);
1756
1757 if (pw_data)
1758 *pw_data = (u16)hr.u.c.param2;
1759 return hr.error;
1760}
1761
1762u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1763 *ph_subsys, u32 h_control, u16 index, u16 *pw_data)
1764{
1765 struct hpi_message hm;
1766 struct hpi_response hr;
1767 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1768 HPI_CONTROL_GET_STATE);
1769 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1770 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS;
1771 hm.u.c.param1 = index;
1772
1773 hpi_send_recv(&hm, &hr);
1774
1775 if (pw_data)
1776 *pw_data = (u16)hr.u.c.param2;
1777 return hr.error;
1778}
1779
1780u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys,
1781 u32 h_control, u16 *pw_error_data)
1782{
1783 u32 error_data = 0;
1784 u16 error = 0;
1785
1786 error = hpi_control_param1_get(ph_subsys, h_control,
1787 HPI_AESEBURX_ERRORSTATUS, &error_data);
1788 if (pw_error_data)
1789 *pw_error_data = (u16)error_data;
1790 return error;
1791}
1792
1793u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys
1794 *ph_subsys, u32 h_control, u32 sample_rate)
1795{
1796 return hpi_control_param_set(ph_subsys, h_control,
1797 HPI_AESEBUTX_SAMPLERATE, sample_rate, 0);
1798}
1799
1800u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys,
1801 u32 h_control, u16 index, u16 data)
1802{
1803 return hpi_control_param_set(ph_subsys, h_control,
1804 HPI_AESEBUTX_USERDATA, index, data);
1805}
1806
1807u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys
1808 *ph_subsys, u32 h_control, u16 index, u16 data)
1809{
1810 return hpi_control_param_set(ph_subsys, h_control,
1811 HPI_AESEBUTX_CHANNELSTATUS, index, data);
1812}
1813
1814u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys
1815 *ph_subsys, u32 h_control, u16 index, u16 *pw_data)
1816{
1817 return HPI_ERROR_INVALID_OPERATION;
1818}
1819
1820u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys,
1821 const u32 h_aes_tx, const u32 index, u16 *pw_format)
1822{
1823 u32 qr;
1824 u16 err;
1825
1826 err = hpi_control_query(ph_subsys, h_aes_tx, HPI_AESEBUTX_FORMAT,
1827 index, 0, &qr);
1828 *pw_format = (u16)qr;
1829 return err;
1830}
1831
1832u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys,
1833 u32 h_control, u16 output_format)
1834{
1835 return hpi_control_param_set(ph_subsys, h_control,
1836 HPI_AESEBUTX_FORMAT, output_format, 0);
1837}
1838
1839u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys,
1840 u32 h_control, u16 *pw_output_format)
1841{
1842 u16 err;
1843 u32 param;
1844
1845 err = hpi_control_param1_get(ph_subsys, h_control,
1846 HPI_AESEBUTX_FORMAT, &param);
1847 if (!err && pw_output_format)
1848 *pw_output_format = (u16)param;
1849
1850 return err;
1851}
1852
1853u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys,
1854 u32 h_control, u16 edge_type)
1855{
1856 return hpi_control_param_set(ph_subsys, h_control,
1857 HPI_BITSTREAM_CLOCK_EDGE, edge_type, 0);
1858}
1859
1860u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys,
1861 u32 h_control, u16 polarity)
1862{
1863 return hpi_control_param_set(ph_subsys, h_control,
1864 HPI_BITSTREAM_DATA_POLARITY, polarity, 0);
1865}
1866
1867u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1868 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity)
1869{
1870 struct hpi_message hm;
1871 struct hpi_response hr;
1872 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1873 HPI_CONTROL_GET_STATE);
1874 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1875 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY;
1876 hpi_send_recv(&hm, &hr);
1877 if (pw_clk_activity)
1878 *pw_clk_activity = (u16)hr.u.c.param1;
1879 if (pw_data_activity)
1880 *pw_data_activity = (u16)hr.u.c.param2;
1881 return hr.error;
1882}
1883
1884u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys,
1885 const u32 h_mode, const u32 index, u16 *pw_mode)
1886{
1887 u32 qr;
1888 u16 err;
1889
1890 err = hpi_control_query(ph_subsys, h_mode, HPI_CHANNEL_MODE_MODE,
1891 index, 0, &qr);
1892 *pw_mode = (u16)qr;
1893 return err;
1894}
1895
1896u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1897 u16 mode)
1898{
1899 return hpi_control_param_set(ph_subsys, h_control,
1900 HPI_CHANNEL_MODE_MODE, mode, 0);
1901}
1902
1903u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1904 u16 *mode)
1905{
1906 u32 mode32 = 0;
1907 u16 error = hpi_control_param1_get(ph_subsys, h_control,
1908 HPI_CHANNEL_MODE_MODE, &mode32);
1909 if (mode)
1910 *mode = (u16)mode32;
1911 return error;
1912}
1913
1914u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1915 u32 hmi_address, u32 byte_count, u8 *pb_data)
1916{
1917 struct hpi_message hm;
1918 struct hpi_response hr;
1919 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1920 HPI_CONTROL_SET_STATE);
1921 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1922
1923 hm.u.cx.u.cobranet_data.byte_count = byte_count;
1924 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
1925
1926 if (byte_count <= 8) {
1927 memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count);
1928 hm.u.cx.attribute = HPI_COBRANET_SET;
1929 } else {
1930 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1931 hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
1932 }
1933
1934 hpi_send_recv(&hm, &hr);
1935
1936 return hr.error;
1937}
1938
1939u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1940 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data)
1941{
1942 struct hpi_message hm;
1943 struct hpi_response hr;
1944 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1945 HPI_CONTROL_GET_STATE);
1946 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1947
1948 hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
1949 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
1950
1951 if (max_byte_count <= 8) {
1952 hm.u.cx.attribute = HPI_COBRANET_GET;
1953 } else {
1954 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1955 hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
1956 }
1957
1958 hpi_send_recv(&hm, &hr);
1959 if (!hr.error && pb_data) {
1960
1961 *pbyte_count = hr.u.cx.u.cobranet_data.byte_count;
1962
1963 if (*pbyte_count < max_byte_count)
1964 max_byte_count = *pbyte_count;
1965
1966 if (hm.u.cx.attribute == HPI_COBRANET_GET) {
1967 memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
1968 max_byte_count);
1969 } else {
1970
1971 }
1972
1973 }
1974 return hr.error;
1975}
1976
1977u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1978 u32 h_control, u32 *pstatus, u32 *preadable_size,
1979 u32 *pwriteable_size)
1980{
1981 struct hpi_message hm;
1982 struct hpi_response hr;
1983 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1984 HPI_CONTROL_GET_STATE);
1985 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1986
1987 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
1988
1989 hpi_send_recv(&hm, &hr);
1990 if (!hr.error) {
1991 if (pstatus)
1992 *pstatus = hr.u.cx.u.cobranet_status.status;
1993 if (preadable_size)
1994 *preadable_size =
1995 hr.u.cx.u.cobranet_status.readable_size;
1996 if (pwriteable_size)
1997 *pwriteable_size =
1998 hr.u.cx.u.cobranet_status.writeable_size;
1999 }
2000 return hr.error;
2001}
2002
2003u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
2004 u32 h_control, u32 *pi_paddress)
2005{
2006 u32 byte_count;
2007 u32 iP;
2008 u16 error;
2009 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2010 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
2011 (u8 *)&iP);
2012
2013 *pi_paddress =
2014 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2015 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2016
2017 if (error)
2018 *pi_paddress = 0;
2019
2020 return error;
2021
2022}
2023
2024u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
2025 u32 h_control, u32 i_paddress)
2026{
2027 u32 iP;
2028 u16 error;
2029
2030 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) <<
2031 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress &
2032 0x000000ff) << 8);
2033
2034 error = hpi_cobranet_hmi_write(ph_subsys, h_control,
2035 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP);
2036
2037 return error;
2038
2039}
2040
2041u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
2042 u32 h_control, u32 *pi_paddress)
2043{
2044 u32 byte_count;
2045 u32 iP;
2046 u16 error;
2047 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2048 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count,
2049 (u8 *)&iP);
2050
2051 *pi_paddress =
2052 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2053 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2054
2055 if (error)
2056 *pi_paddress = 0;
2057
2058 return error;
2059
2060}
2061
2062u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
2063 u32 h_control, u32 i_paddress)
2064{
2065 u32 iP;
2066 u16 error;
2067
2068 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) <<
2069 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress &
2070 0x000000ff) << 8);
2071
2072 error = hpi_cobranet_hmi_write(ph_subsys, h_control,
2073 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP);
2074
2075 return error;
2076
2077}
2078
2079u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
2080 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs)
2081{
2082 u32 byte_count;
2083 u16 error;
2084 u32 mAC;
2085 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2086 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
2087 (u8 *)&mAC);
2088 *pmAC_MS_bs =
2089 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC
2090 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8);
2091 error += hpi_cobranet_hmi_read(ph_subsys, h_control,
2092 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4, &byte_count,
2093 (u8 *)&mAC);
2094 *pmAC_LS_bs =
2095 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC
2096 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8);
2097
2098 if (error) {
2099 *pmAC_MS_bs = 0;
2100 *pmAC_LS_bs = 0;
2101 }
2102
2103 return error;
2104}
2105
2106u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2107 u16 attack, u16 decay, short ratio100, short threshold0_01dB,
2108 short makeup_gain0_01dB)
2109{
2110 struct hpi_message hm;
2111 struct hpi_response hr;
2112 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2113 HPI_CONTROL_SET_STATE);
2114 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2115
2116 hm.u.c.param1 = attack + ((u32)ratio100 << 16);
2117 hm.u.c.param2 = (decay & 0xFFFFL);
2118 hm.u.c.an_log_value[0] = threshold0_01dB;
2119 hm.u.c.an_log_value[1] = makeup_gain0_01dB;
2120 hm.u.c.attribute = HPI_COMPANDER_PARAMS;
2121
2122 hpi_send_recv(&hm, &hr);
2123
2124 return hr.error;
2125}
2126
2127u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2128 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
2129 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB)
2130{
2131 struct hpi_message hm;
2132 struct hpi_response hr;
2133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2134 HPI_CONTROL_GET_STATE);
2135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2136 hm.u.c.attribute = HPI_COMPANDER_PARAMS;
2137
2138 hpi_send_recv(&hm, &hr);
2139
2140 if (pw_attack)
2141 *pw_attack = (short)(hr.u.c.param1 & 0xFFFF);
2142 if (pw_decay)
2143 *pw_decay = (short)(hr.u.c.param2 & 0xFFFF);
2144 if (pw_ratio100)
2145 *pw_ratio100 = (short)(hr.u.c.param1 >> 16);
2146
2147 if (pn_threshold0_01dB)
2148 *pn_threshold0_01dB = hr.u.c.an_log_value[0];
2149 if (pn_makeup_gain0_01dB)
2150 *pn_makeup_gain0_01dB = hr.u.c.an_log_value[1];
2151
2152 return hr.error;
2153}
2154
2155u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2156 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
2157{
2158 struct hpi_message hm;
2159 struct hpi_response hr;
2160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2161 HPI_CONTROL_GET_STATE);
2162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2163 hm.u.c.attribute = HPI_LEVEL_RANGE;
2164
2165 hpi_send_recv(&hm, &hr);
2166 if (hr.error) {
2167 hr.u.c.an_log_value[0] = 0;
2168 hr.u.c.an_log_value[1] = 0;
2169 hr.u.c.param1 = 0;
2170 }
2171 if (min_gain_01dB)
2172 *min_gain_01dB = hr.u.c.an_log_value[0];
2173 if (max_gain_01dB)
2174 *max_gain_01dB = hr.u.c.an_log_value[1];
2175 if (step_gain_01dB)
2176 *step_gain_01dB = (short)hr.u.c.param1;
2177 return hr.error;
2178}
2179
2180u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2181 short an_gain0_01dB[HPI_MAX_CHANNELS]
2182 )
2183{
2184 struct hpi_message hm;
2185 struct hpi_response hr;
2186
2187 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2188 HPI_CONTROL_SET_STATE);
2189 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2190 memcpy(hm.u.c.an_log_value, an_gain0_01dB,
2191 sizeof(short) * HPI_MAX_CHANNELS);
2192 hm.u.c.attribute = HPI_LEVEL_GAIN;
2193
2194 hpi_send_recv(&hm, &hr);
2195
2196 return hr.error;
2197}
2198
2199u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2200 short an_gain0_01dB[HPI_MAX_CHANNELS]
2201 )
2202{
2203 struct hpi_message hm;
2204 struct hpi_response hr;
2205 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2206 HPI_CONTROL_GET_STATE);
2207 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2208 hm.u.c.attribute = HPI_LEVEL_GAIN;
2209
2210 hpi_send_recv(&hm, &hr);
2211
2212 memcpy(an_gain0_01dB, hr.u.c.an_log_value,
2213 sizeof(short) * HPI_MAX_CHANNELS);
2214 return hr.error;
2215}
2216
2217u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
2218 const u32 h_meter, u32 *p_channels)
2219{
2220 return hpi_control_query(ph_subsys, h_meter, HPI_METER_NUM_CHANNELS,
2221 0, 0, p_channels);
2222}
2223
2224u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2225 short an_peakdB[HPI_MAX_CHANNELS]
2226 )
2227{
2228 short i = 0;
2229
2230 struct hpi_message hm;
2231 struct hpi_response hr;
2232
2233 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2234 HPI_CONTROL_GET_STATE);
2235 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2236 hm.obj_index = hm.obj_index;
2237 hm.u.c.attribute = HPI_METER_PEAK;
2238
2239 hpi_send_recv(&hm, &hr);
2240
2241 if (!hr.error)
2242 memcpy(an_peakdB, hr.u.c.an_log_value,
2243 sizeof(short) * HPI_MAX_CHANNELS);
2244 else
2245 for (i = 0; i < HPI_MAX_CHANNELS; i++)
2246 an_peakdB[i] = HPI_METER_MINIMUM;
2247 return hr.error;
2248}
2249
2250u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2251 short an_rmsdB[HPI_MAX_CHANNELS]
2252 )
2253{
2254 short i = 0;
2255
2256 struct hpi_message hm;
2257 struct hpi_response hr;
2258
2259 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2260 HPI_CONTROL_GET_STATE);
2261 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2262 hm.u.c.attribute = HPI_METER_RMS;
2263
2264 hpi_send_recv(&hm, &hr);
2265
2266 if (!hr.error)
2267 memcpy(an_rmsdB, hr.u.c.an_log_value,
2268 sizeof(short) * HPI_MAX_CHANNELS);
2269 else
2270 for (i = 0; i < HPI_MAX_CHANNELS; i++)
2271 an_rmsdB[i] = HPI_METER_MINIMUM;
2272
2273 return hr.error;
2274}
2275
2276u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2277 u32 h_control, u16 attack, u16 decay)
2278{
2279 return hpi_control_param_set(ph_subsys, h_control,
2280 HPI_METER_RMS_BALLISTICS, attack, decay);
2281}
2282
2283u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2284 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2285{
2286 u32 attack;
2287 u32 decay;
2288 u16 error;
2289
2290 error = hpi_control_param2_get(ph_subsys, h_control,
2291 HPI_METER_RMS_BALLISTICS, &attack, &decay);
2292
2293 if (pn_attack)
2294 *pn_attack = (unsigned short)attack;
2295 if (pn_decay)
2296 *pn_decay = (unsigned short)decay;
2297
2298 return error;
2299}
2300
2301u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2302 u32 h_control, u16 attack, u16 decay)
2303{
2304 return hpi_control_param_set(ph_subsys, h_control,
2305 HPI_METER_PEAK_BALLISTICS, attack, decay);
2306}
2307
2308u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2309 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2310{
2311 u32 attack;
2312 u32 decay;
2313 u16 error;
2314
2315 error = hpi_control_param2_get(ph_subsys, h_control,
2316 HPI_METER_PEAK_BALLISTICS, &attack, &decay);
2317
2318 if (pn_attack)
2319 *pn_attack = (short)attack;
2320 if (pn_decay)
2321 *pn_decay = (short)decay;
2322
2323 return error;
2324}
2325
2326u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys,
2327 u32 h_control, u16 on_off)
2328{
2329 return hpi_control_param_set(ph_subsys, h_control,
2330 HPI_MICROPHONE_PHANTOM_POWER, (u32)on_off, 0);
2331}
2332
2333u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys,
2334 u32 h_control, u16 *pw_on_off)
2335{
2336 u16 error = 0;
2337 u32 on_off = 0;
2338 error = hpi_control_param1_get(ph_subsys, h_control,
2339 HPI_MICROPHONE_PHANTOM_POWER, &on_off);
2340 if (pw_on_off)
2341 *pw_on_off = (u16)on_off;
2342 return error;
2343}
2344
2345u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys,
2346 u32 h_control, u16 source_node_type, u16 source_node_index)
2347{
2348 return hpi_control_param_set(ph_subsys, h_control,
2349 HPI_MULTIPLEXER_SOURCE, source_node_type, source_node_index);
2350}
2351
2352u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
2353 u32 h_control, u16 *source_node_type, u16 *source_node_index)
2354{
2355 u32 node, index;
2356 u16 error = hpi_control_param2_get(ph_subsys, h_control,
2357 HPI_MULTIPLEXER_SOURCE, &node,
2358 &index);
2359 if (source_node_type)
2360 *source_node_type = (u16)node;
2361 if (source_node_index)
2362 *source_node_index = (u16)index;
2363 return error;
2364}
2365
2366u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
2367 u32 h_control, u16 index, u16 *source_node_type,
2368 u16 *source_node_index)
2369{
2370 struct hpi_message hm;
2371 struct hpi_response hr;
2372 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2373 HPI_CONTROL_GET_STATE);
2374 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2375 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE;
2376 hm.u.c.param1 = index;
2377
2378 hpi_send_recv(&hm, &hr);
2379
2380 if (source_node_type)
2381 *source_node_type = (u16)hr.u.c.param1;
2382 if (source_node_index)
2383 *source_node_index = (u16)hr.u.c.param2;
2384 return hr.error;
2385}
2386
2387u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
2388 u32 h_control, u16 *pw_number_of_bands, u16 *pw_on_off)
2389{
2390 u32 oB = 0;
2391 u32 oO = 0;
2392 u16 error = 0;
2393
2394 error = hpi_control_param2_get(ph_subsys, h_control,
2395 HPI_EQUALIZER_NUM_FILTERS, &oO, &oB);
2396 if (pw_number_of_bands)
2397 *pw_number_of_bands = (u16)oB;
2398 if (pw_on_off)
2399 *pw_on_off = (u16)oO;
2400 return error;
2401}
2402
2403u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys,
2404 u32 h_control, u16 on_off)
2405{
2406 return hpi_control_param_set(ph_subsys, h_control,
2407 HPI_EQUALIZER_NUM_FILTERS, on_off, 0);
2408}
2409
2410u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
2411 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz,
2412 short *pnQ100, short *pn_gain0_01dB)
2413{
2414 struct hpi_message hm;
2415 struct hpi_response hr;
2416 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2417 HPI_CONTROL_GET_STATE);
2418 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2419 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2420 hm.u.c.param2 = index;
2421
2422 hpi_send_recv(&hm, &hr);
2423
2424 if (pfrequency_hz)
2425 *pfrequency_hz = hr.u.c.param1;
2426 if (pn_type)
2427 *pn_type = (u16)(hr.u.c.param2 >> 16);
2428 if (pnQ100)
2429 *pnQ100 = hr.u.c.an_log_value[1];
2430 if (pn_gain0_01dB)
2431 *pn_gain0_01dB = hr.u.c.an_log_value[0];
2432
2433 return hr.error;
2434}
2435
2436u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
2437 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100,
2438 short gain0_01dB)
2439{
2440 struct hpi_message hm;
2441 struct hpi_response hr;
2442 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2443 HPI_CONTROL_SET_STATE);
2444 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2445
2446 hm.u.c.param1 = frequency_hz;
2447 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16);
2448 hm.u.c.an_log_value[0] = gain0_01dB;
2449 hm.u.c.an_log_value[1] = q100;
2450 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2451
2452 hpi_send_recv(&hm, &hr);
2453
2454 return hr.error;
2455}
2456
2457u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2458 u32 h_control, u16 index, short coeffs[5]
2459 )
2460{
2461 struct hpi_message hm;
2462 struct hpi_response hr;
2463 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2464 HPI_CONTROL_GET_STATE);
2465 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2466 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS;
2467 hm.u.c.param2 = index;
2468
2469 hpi_send_recv(&hm, &hr);
2470
2471 coeffs[0] = (short)hr.u.c.an_log_value[0];
2472 coeffs[1] = (short)hr.u.c.an_log_value[1];
2473 coeffs[2] = (short)hr.u.c.param1;
2474 coeffs[3] = (short)(hr.u.c.param1 >> 16);
2475 coeffs[4] = (short)hr.u.c.param2;
2476
2477 return hr.error;
2478}
2479
2480u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys,
2481 const u32 h_clock, const u32 index, u16 *pw_source)
2482{
2483 u32 qr;
2484 u16 err;
2485
2486 err = hpi_control_query(ph_subsys, h_clock, HPI_SAMPLECLOCK_SOURCE,
2487 index, 0, &qr);
2488 *pw_source = (u16)qr;
2489 return err;
2490}
2491
2492u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys,
2493 u32 h_control, u16 source)
2494{
2495 return hpi_control_param_set(ph_subsys, h_control,
2496 HPI_SAMPLECLOCK_SOURCE, source, 0);
2497}
2498
2499u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys,
2500 u32 h_control, u16 *pw_source)
2501{
2502 u16 error = 0;
2503 u32 source = 0;
2504 error = hpi_control_param1_get(ph_subsys, h_control,
2505 HPI_SAMPLECLOCK_SOURCE, &source);
2506 if (!error)
2507 if (pw_source)
2508 *pw_source = (u16)source;
2509 return error;
2510}
2511
2512u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys,
2513 const u32 h_clock, const u32 index, const u32 source,
2514 u16 *pw_source_index)
2515{
2516 u32 qr;
2517 u16 err;
2518
2519 err = hpi_control_query(ph_subsys, h_clock,
2520 HPI_SAMPLECLOCK_SOURCE_INDEX, index, source, &qr);
2521 *pw_source_index = (u16)qr;
2522 return err;
2523}
2524
2525u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys,
2526 u32 h_control, u16 source_index)
2527{
2528 return hpi_control_param_set(ph_subsys, h_control,
2529 HPI_SAMPLECLOCK_SOURCE_INDEX, source_index, 0);
2530}
2531
2532u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys,
2533 u32 h_control, u16 *pw_source_index)
2534{
2535 u16 error = 0;
2536 u32 source_index = 0;
2537 error = hpi_control_param1_get(ph_subsys, h_control,
2538 HPI_SAMPLECLOCK_SOURCE_INDEX, &source_index);
2539 if (!error)
2540 if (pw_source_index)
2541 *pw_source_index = (u16)source_index;
2542 return error;
2543}
2544
2545u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys,
2546 const u32 h_clock, const u32 index, u32 *prate)
2547{
2548 u16 err;
2549 err = hpi_control_query(ph_subsys, h_clock,
2550 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, index, 0, prate);
2551
2552 return err;
2553}
2554
2555u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys,
2556 u32 h_control, u32 sample_rate)
2557{
2558 return hpi_control_param_set(ph_subsys, h_control,
2559 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0);
2560}
2561
2562u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys,
2563 u32 h_control, u32 *psample_rate)
2564{
2565 u16 error = 0;
2566 u32 sample_rate = 0;
2567 error = hpi_control_param1_get(ph_subsys, h_control,
2568 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate);
2569 if (!error)
2570 if (psample_rate)
2571 *psample_rate = sample_rate;
2572 return error;
2573}
2574
2575u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
2576 u32 h_control, u32 *psample_rate)
2577{
2578 u16 error = 0;
2579 u32 sample_rate = 0;
2580 error = hpi_control_param1_get(ph_subsys, h_control,
2581 HPI_SAMPLECLOCK_SAMPLERATE, &sample_rate);
2582 if (!error)
2583 if (psample_rate)
2584 *psample_rate = sample_rate;
2585 return error;
2586}
2587
2588u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys,
2589 u32 h_control, u32 enable)
2590{
2591 return hpi_control_param_set(ph_subsys, h_control,
2592 HPI_SAMPLECLOCK_AUTO, enable, 0);
2593}
2594
2595u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys,
2596 u32 h_control, u32 *penable)
2597{
2598 return hpi_control_param1_get(ph_subsys, h_control,
2599 HPI_SAMPLECLOCK_AUTO, penable);
2600}
2601
2602u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
2603 u32 h_control, u32 lock)
2604{
2605 return hpi_control_param_set(ph_subsys, h_control,
2606 HPI_SAMPLECLOCK_LOCAL_LOCK, lock, 0);
2607}
2608
2609u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
2610 u32 h_control, u32 *plock)
2611{
2612 return hpi_control_param1_get(ph_subsys, h_control,
2613 HPI_SAMPLECLOCK_LOCAL_LOCK, plock);
2614}
2615
2616u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
2617 u32 h_control, u32 index, u32 *frequency)
2618{
2619 return hpi_control_param_get(ph_subsys, h_control,
2620 HPI_TONEDETECTOR_FREQUENCY, index, 0, frequency, NULL);
2621}
2622
2623u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2624 u32 h_control, u32 *state)
2625{
2626 return hpi_control_param_get(ph_subsys, h_control,
2627 HPI_TONEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
2628}
2629
2630u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2631 u32 h_control, u32 enable)
2632{
2633 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2634 (u32)enable, 0);
2635}
2636
2637u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2638 u32 h_control, u32 *enable)
2639{
2640 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2641 0, 0, (u32 *)enable, NULL);
2642}
2643
2644u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2645 u32 h_control, u32 event_enable)
2646{
2647 return hpi_control_param_set(ph_subsys, h_control,
2648 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
2649}
2650
2651u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2652 u32 h_control, u32 *event_enable)
2653{
2654 return hpi_control_param_get(ph_subsys, h_control,
2655 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
2656}
2657
2658u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2659 u32 h_control, int threshold)
2660{
2661 return hpi_control_param_set(ph_subsys, h_control,
2662 HPI_TONEDETECTOR_THRESHOLD, (u32)threshold, 0);
2663}
2664
2665u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2666 u32 h_control, int *threshold)
2667{
2668 return hpi_control_param_get(ph_subsys, h_control,
2669 HPI_TONEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
2670}
2671
2672u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2673 u32 h_control, u32 *state)
2674{
2675 return hpi_control_param_get(ph_subsys, h_control,
2676 HPI_SILENCEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
2677}
2678
2679u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2680 u32 h_control, u32 enable)
2681{
2682 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2683 (u32)enable, 0);
2684}
2685
2686u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2687 u32 h_control, u32 *enable)
2688{
2689 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2690 0, 0, (u32 *)enable, NULL);
2691}
2692
2693u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2694 u32 h_control, u32 event_enable)
2695{
2696 return hpi_control_param_set(ph_subsys, h_control,
2697 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
2698}
2699
2700u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2701 u32 h_control, u32 *event_enable)
2702{
2703 return hpi_control_param_get(ph_subsys, h_control,
2704 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
2705}
2706
2707u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
2708 u32 h_control, u32 delay)
2709{
2710 return hpi_control_param_set(ph_subsys, h_control,
2711 HPI_SILENCEDETECTOR_DELAY, (u32)delay, 0);
2712}
2713
2714u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
2715 u32 h_control, u32 *delay)
2716{
2717 return hpi_control_param_get(ph_subsys, h_control,
2718 HPI_SILENCEDETECTOR_DELAY, 0, 0, (u32 *)delay, NULL);
2719}
2720
2721u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2722 u32 h_control, int threshold)
2723{
2724 return hpi_control_param_set(ph_subsys, h_control,
2725 HPI_SILENCEDETECTOR_THRESHOLD, (u32)threshold, 0);
2726}
2727
2728u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2729 u32 h_control, int *threshold)
2730{
2731 return hpi_control_param_get(ph_subsys, h_control,
2732 HPI_SILENCEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
2733}
2734
2735u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
2736 const u32 h_tuner, const u32 index, u16 *pw_band)
2737{
2738 u32 qr;
2739 u16 err;
2740
2741 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0,
2742 &qr);
2743 *pw_band = (u16)qr;
2744 return err;
2745}
2746
2747u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2748 u16 band)
2749{
2750 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_BAND,
2751 band, 0);
2752}
2753
2754u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2755 u16 *pw_band)
2756{
2757 u32 band = 0;
2758 u16 error = 0;
2759
2760 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_BAND,
2761 &band);
2762 if (pw_band)
2763 *pw_band = (u16)band;
2764 return error;
2765}
2766
2767u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys,
2768 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq)
2769{
2770 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_FREQ, index,
2771 band, pfreq);
2772}
2773
2774u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys,
2775 u32 h_control, u32 freq_ink_hz)
2776{
2777 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_FREQ,
2778 freq_ink_hz, 0);
2779}
2780
2781u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys,
2782 u32 h_control, u32 *pw_freq_ink_hz)
2783{
2784 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_FREQ,
2785 pw_freq_ink_hz);
2786}
2787
2788u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys,
2789 const u32 h_tuner, const u32 index, u16 *pw_gain)
2790{
2791 u32 qr;
2792 u16 err;
2793
2794 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0,
2795 &qr);
2796 *pw_gain = (u16)qr;
2797 return err;
2798}
2799
2800u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2801 short gain)
2802{
2803 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_GAIN,
2804 gain, 0);
2805}
2806
2807u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2808 short *pn_gain)
2809{
2810 u32 gain = 0;
2811 u16 error = 0;
2812
2813 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_GAIN,
2814 &gain);
2815 if (pn_gain)
2816 *pn_gain = (u16)gain;
2817 return error;
2818}
2819
2820u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2821 short *pw_level)
2822{
2823 struct hpi_message hm;
2824 struct hpi_response hr;
2825 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2826 HPI_CONTROL_GET_STATE);
2827 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2828 hm.u.c.attribute = HPI_TUNER_LEVEL;
2829 hm.u.c.param1 = HPI_TUNER_LEVEL_AVERAGE;
2830 hpi_send_recv(&hm, &hr);
2831 if (pw_level)
2832 *pw_level = (short)hr.u.c.param1;
2833 return hr.error;
2834}
2835
2836u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
2837 u32 h_control, short *pw_level)
2838{
2839 struct hpi_message hm;
2840 struct hpi_response hr;
2841 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2842 HPI_CONTROL_GET_STATE);
2843 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2844 hm.u.c.attribute = HPI_TUNER_LEVEL;
2845 hm.u.c.param1 = HPI_TUNER_LEVEL_RAW;
2846 hpi_send_recv(&hm, &hr);
2847 if (pw_level)
2848 *pw_level = (short)hr.u.c.param1;
2849 return hr.error;
2850}
2851
2852u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys,
2853 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis)
2854{
2855 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_DEEMPHASIS,
2856 index, band, pdeemphasis);
2857}
2858
2859u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys,
2860 u32 h_control, u32 deemphasis)
2861{
2862 return hpi_control_param_set(ph_subsys, h_control,
2863 HPI_TUNER_DEEMPHASIS, deemphasis, 0);
2864}
2865
2866u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
2867 u32 h_control, u32 *pdeemphasis)
2868{
2869 return hpi_control_param1_get(ph_subsys, h_control,
2870 HPI_TUNER_DEEMPHASIS, pdeemphasis);
2871}
2872
2873u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys,
2874 const u32 h_tuner, u32 *pbitmap_program)
2875{
2876 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_PROGRAM, 0, 0,
2877 pbitmap_program);
2878}
2879
2880u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2881 u32 program)
2882{
2883 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_PROGRAM,
2884 program, 0);
2885}
2886
2887u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2888 u32 *pprogram)
2889{
2890 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_PROGRAM,
2891 pprogram);
2892}
2893
2894u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
2895 u32 h_control, char *psz_dsp_version, const u32 string_size)
2896{
2897 return hpi_control_get_string(ph_subsys, h_control,
2898 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
2899}
2900
2901u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
2902 u32 h_control, char *psz_sdk_version, const u32 string_size)
2903{
2904 return hpi_control_get_string(ph_subsys, h_control,
2905 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
2906}
2907
2908u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2909 u16 *pw_status_mask, u16 *pw_status)
2910{
2911 u32 status = 0;
2912 u16 error = 0;
2913
2914 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_STATUS,
2915 &status);
2916 if (pw_status) {
2917 if (!error) {
2918 *pw_status_mask = (u16)(status >> 16);
2919 *pw_status = (u16)(status & 0xFFFF);
2920 } else {
2921 *pw_status_mask = 0;
2922 *pw_status = 0;
2923 }
2924 }
2925 return error;
2926}
2927
2928u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2929 u32 mode, u32 value)
2930{
2931 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_MODE,
2932 mode, value);
2933}
2934
2935u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2936 u32 mode, u32 *pn_value)
2937{
2938 return hpi_control_param_get(ph_subsys, h_control, HPI_TUNER_MODE,
2939 mode, 0, pn_value, NULL);
2940}
2941
2942u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
2943 u32 h_control, u32 *pquality)
2944{
2945 return hpi_control_param_get(ph_subsys, h_control,
2946 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL);
2947}
2948
2949u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2950 char *p_data)
2951{
2952 struct hpi_message hm;
2953 struct hpi_response hr;
2954 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2955 HPI_CONTROL_GET_STATE);
2956 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2957 hm.u.c.attribute = HPI_TUNER_RDS;
2958 hpi_send_recv(&hm, &hr);
2959 if (p_data) {
2960 *(u32 *)&p_data[0] = hr.u.cu.tuner.rds.data[0];
2961 *(u32 *)&p_data[4] = hr.u.cu.tuner.rds.data[1];
2962 *(u32 *)&p_data[8] = hr.u.cu.tuner.rds.bLER;
2963 }
2964 return hr.error;
2965}
2966
2967u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
2968 u32 h_control, char *psz_string, const u32 data_length)
2969{
2970 return hpi_control_get_string(ph_subsys, h_control,
2971 HPI_PAD_CHANNEL_NAME, psz_string, data_length);
2972}
2973
2974u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2975 char *psz_string, const u32 data_length)
2976{
2977 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_ARTIST,
2978 psz_string, data_length);
2979}
2980
2981u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2982 char *psz_string, const u32 data_length)
2983{
2984 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_TITLE,
2985 psz_string, data_length);
2986}
2987
2988u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2989 char *psz_string, const u32 data_length)
2990{
2991 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_COMMENT,
2992 psz_string, data_length);
2993}
2994
2995u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
2996 u32 h_control, u32 *ppTY)
2997{
2998 return hpi_control_param_get(ph_subsys, h_control,
2999 HPI_PAD_PROGRAM_TYPE, 0, 0, ppTY, NULL);
3000}
3001
3002u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3003 u32 *ppI)
3004{
3005 return hpi_control_param_get(ph_subsys, h_control, HPI_PAD_PROGRAM_ID,
3006 0, 0, ppI, NULL);
3007}
3008
3009u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
3010 const u32 h_volume, u32 *p_channels)
3011{
3012 return hpi_control_query(ph_subsys, h_volume, HPI_VOLUME_NUM_CHANNELS,
3013 0, 0, p_channels);
3014}
3015
3016u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3017 short an_log_gain[HPI_MAX_CHANNELS]
3018 )
3019{
3020 struct hpi_message hm;
3021 struct hpi_response hr;
3022 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3023 HPI_CONTROL_SET_STATE);
3024 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3025 memcpy(hm.u.c.an_log_value, an_log_gain,
3026 sizeof(short) * HPI_MAX_CHANNELS);
3027 hm.u.c.attribute = HPI_VOLUME_GAIN;
3028
3029 hpi_send_recv(&hm, &hr);
3030
3031 return hr.error;
3032}
3033
3034u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3035 short an_log_gain[HPI_MAX_CHANNELS]
3036 )
3037{
3038 struct hpi_message hm;
3039 struct hpi_response hr;
3040 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3041 HPI_CONTROL_GET_STATE);
3042 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3043 hm.u.c.attribute = HPI_VOLUME_GAIN;
3044
3045 hpi_send_recv(&hm, &hr);
3046
3047 memcpy(an_log_gain, hr.u.c.an_log_value,
3048 sizeof(short) * HPI_MAX_CHANNELS);
3049 return hr.error;
3050}
3051
3052u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3053 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
3054{
3055 struct hpi_message hm;
3056 struct hpi_response hr;
3057 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3058 HPI_CONTROL_GET_STATE);
3059 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3060 hm.u.c.attribute = HPI_VOLUME_RANGE;
3061
3062 hpi_send_recv(&hm, &hr);
3063 if (hr.error) {
3064 hr.u.c.an_log_value[0] = 0;
3065 hr.u.c.an_log_value[1] = 0;
3066 hr.u.c.param1 = 0;
3067 }
3068 if (min_gain_01dB)
3069 *min_gain_01dB = hr.u.c.an_log_value[0];
3070 if (max_gain_01dB)
3071 *max_gain_01dB = hr.u.c.an_log_value[1];
3072 if (step_gain_01dB)
3073 *step_gain_01dB = (short)hr.u.c.param1;
3074 return hr.error;
3075}
3076
3077u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
3078 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS],
3079 u32 duration_ms, u16 profile)
3080{
3081 struct hpi_message hm;
3082 struct hpi_response hr;
3083 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3084 HPI_CONTROL_SET_STATE);
3085 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3086
3087 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB,
3088 sizeof(short) * HPI_MAX_CHANNELS);
3089
3090 hm.u.c.attribute = HPI_VOLUME_AUTOFADE;
3091 hm.u.c.param1 = duration_ms;
3092 hm.u.c.param2 = profile;
3093
3094 hpi_send_recv(&hm, &hr);
3095
3096 return hr.error;
3097}
3098
3099u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3100 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms)
3101{
3102 return hpi_volume_auto_fade_profile(ph_subsys, h_control,
3103 an_stop_gain0_01dB, duration_ms, HPI_VOLUME_AUTOFADE_LOG);
3104}
3105
3106u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3107 short an_gain0_01dB)
3108{
3109 struct hpi_message hm;
3110 struct hpi_response hr;
3111 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3112 HPI_CONTROL_SET_STATE);
3113 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3114 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3115
3116 hm.u.c.an_log_value[0] = an_gain0_01dB;
3117
3118 hpi_send_recv(&hm, &hr);
3119
3120 return hr.error;
3121}
3122
3123u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3124 short *an_gain0_01dB)
3125{
3126 struct hpi_message hm;
3127 struct hpi_response hr;
3128 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3129 HPI_CONTROL_GET_STATE);
3130 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3131 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3132
3133 hpi_send_recv(&hm, &hr);
3134
3135 *an_gain0_01dB = hr.u.c.an_log_value[0];
3136
3137 return hr.error;
3138}
3139
3140static size_t strv_packet_size = MIN_STRV_PACKET_SIZE;
3141
3142static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
3143 0,
3144 sizeof(struct hpi_entity),
3145 sizeof(void *),
3146
3147 sizeof(int),
3148 sizeof(float),
3149 sizeof(double),
3150
3151 sizeof(char),
3152 sizeof(char),
3153
3154 4 * sizeof(char),
3155 16 * sizeof(char),
3156 6 * sizeof(char),
3157};
3158
3159inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
3160{
3161 return entity_ptr->header.size;
3162}
3163
3164inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
3165{
3166 return sizeof(entity_ptr->header);
3167}
3168
3169inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
3170{
3171 return hpi_entity_size(entity_ptr) -
3172 hpi_entity_header_size(entity_ptr);
3173}
3174
3175inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
3176{
3177 return hpi_entity_value_size(entity_ptr) /
3178 entity_type_to_size[entity_ptr->header.type];
3179}
3180
3181inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
3182 *entity_ptr)
3183{
3184 return (void *)(((uint8_t *) entity_ptr) +
3185 hpi_entity_size(entity_ptr));
3186}
3187
3188inline u16 hpi_entity_check_type(const enum e_entity_type t)
3189{
3190 if (t >= 0 && t < STR_TYPE_FIELD_MAX)
3191 return 0;
3192 return HPI_ERROR_ENTITY_TYPE_INVALID;
3193}
3194
3195inline u16 hpi_entity_check_role(const enum e_entity_role r)
3196{
3197 if (r >= 0 && r < STR_ROLE_FIELD_MAX)
3198 return 0;
3199 return HPI_ERROR_ENTITY_ROLE_INVALID;
3200}
3201
3202static u16 hpi_entity_get_next(struct hpi_entity *entity, int recursive_flag,
3203 void *guard_p, struct hpi_entity **next)
3204{
3205 HPI_DEBUG_ASSERT(entity != NULL);
3206 HPI_DEBUG_ASSERT(next != NULL);
3207 HPI_DEBUG_ASSERT(hpi_entity_size(entity) != 0);
3208
3209 if (guard_p <= (void *)entity) {
3210 *next = NULL;
3211 return 0;
3212 }
3213
3214 if (recursive_flag && entity->header.type == entity_type_sequence)
3215 *next = (struct hpi_entity *)entity->value;
3216 else
3217 *next = (struct hpi_entity *)hpi_entity_ptr_to_next(entity);
3218
3219 if (guard_p <= (void *)*next) {
3220 *next = NULL;
3221 return 0;
3222 }
3223
3224 HPI_DEBUG_ASSERT(guard_p >= (void *)hpi_entity_ptr_to_next(*next));
3225 return 0;
3226}
3227
3228u16 hpi_entity_find_next(struct hpi_entity *container_entity,
3229 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
3230 struct hpi_entity **current_match)
3231{
3232 struct hpi_entity *tmp = NULL;
3233 void *guard_p = NULL;
3234
3235 HPI_DEBUG_ASSERT(container_entity != NULL);
3236 guard_p = hpi_entity_ptr_to_next(container_entity);
3237
3238 if (*current_match != NULL)
3239 hpi_entity_get_next(*current_match, recursive_flag, guard_p,
3240 &tmp);
3241 else
3242 hpi_entity_get_next(container_entity, 1, guard_p, &tmp);
3243
3244 while (tmp) {
3245 u16 err;
3246
3247 HPI_DEBUG_ASSERT((void *)tmp >= (void *)container_entity);
3248
3249 if ((!type || tmp->header.type == type) && (!role
3250 || tmp->header.role == role)) {
3251 *current_match = tmp;
3252 return 0;
3253 }
3254
3255 err = hpi_entity_get_next(tmp, recursive_flag, guard_p,
3256 current_match);
3257 if (err)
3258 return err;
3259
3260 tmp = *current_match;
3261 }
3262
3263 *current_match = NULL;
3264 return 0;
3265}
3266
3267void hpi_entity_free(struct hpi_entity *entity)
3268{
3269 if (entity != NULL)
3270 kfree(entity);
3271}
3272
3273static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src,
3274 struct hpi_entity **dst)
3275{
3276 size_t buf_size;
3277 HPI_DEBUG_ASSERT(dst != NULL);
3278 HPI_DEBUG_ASSERT(src != NULL);
3279
3280 buf_size = hpi_entity_size(src);
3281 *dst = kmalloc(buf_size, GFP_KERNEL);
3282 if (*dst == NULL)
3283 return HPI_ERROR_MEMORY_ALLOC;
3284 memcpy(*dst, src, buf_size);
3285 return 0;
3286}
3287
3288u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
3289 struct hpi_entity **info)
3290{
3291 struct hpi_msg_strv hm;
3292 struct hpi_res_strv *phr;
3293 u16 hpi_err;
3294 int remaining_attempts = 2;
3295 size_t resp_packet_size = 1024;
3296
3297 *info = NULL;
3298
3299 while (remaining_attempts--) {
3300 phr = kmalloc(resp_packet_size, GFP_KERNEL);
3301 HPI_DEBUG_ASSERT(phr != NULL);
3302
3303 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3304 (u16)resp_packet_size, HPI_OBJ_CONTROL,
3305 HPI_CONTROL_GET_INFO);
3306 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3307
3308 hm.strv.header.size = sizeof(hm.strv);
3309 phr->strv.header.size = resp_packet_size - sizeof(phr->h);
3310
3311 hpi_send_recv((struct hpi_message *)&hm.h,
3312 (struct hpi_response *)&phr->h);
3313 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3314
3315 HPI_DEBUG_ASSERT(phr->h.specific_error >
3316 MIN_STRV_PACKET_SIZE
3317 && phr->h.specific_error < 1500);
3318 resp_packet_size = phr->h.specific_error;
3319 } else {
3320 remaining_attempts = 0;
3321 if (!phr->h.error)
3322 hpi_entity_alloc_and_copy(&phr->strv, info);
3323 }
3324
3325 hpi_err = phr->h.error;
3326 kfree(phr);
3327 }
3328
3329 return hpi_err;
3330}
3331
3332u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
3333 struct hpi_entity **value)
3334{
3335 struct hpi_msg_strv hm;
3336 struct hpi_res_strv *phr;
3337 u16 hpi_err;
3338 int remaining_attempts = 2;
3339
3340 *value = NULL;
3341
3342 while (remaining_attempts--) {
3343 phr = kmalloc(strv_packet_size, GFP_KERNEL);
3344 if (!phr)
3345 return HPI_ERROR_MEMORY_ALLOC;
3346
3347 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3348 (u16)strv_packet_size, HPI_OBJ_CONTROL,
3349 HPI_CONTROL_GET_STATE);
3350 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3351
3352 hm.strv.header.size = sizeof(hm.strv);
3353 phr->strv.header.size = strv_packet_size - sizeof(phr->h);
3354
3355 hpi_send_recv((struct hpi_message *)&hm.h,
3356 (struct hpi_response *)&phr->h);
3357 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3358
3359 HPI_DEBUG_ASSERT(phr->h.specific_error >
3360 MIN_STRV_PACKET_SIZE
3361 && phr->h.specific_error < 1000);
3362 strv_packet_size = phr->h.specific_error;
3363 } else {
3364 remaining_attempts = 0;
3365 if (!phr->h.error)
3366 hpi_entity_alloc_and_copy(&phr->strv, value);
3367 }
3368
3369 hpi_err = phr->h.error;
3370 kfree(phr);
3371 }
3372
3373 return hpi_err;
3374}
3375
3376u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
3377 struct hpi_entity *value)
3378{
3379 struct hpi_msg_strv *phm;
3380 struct hpi_res_strv hr;
3381
3382 phm = kmalloc(sizeof(phm->h) + value->header.size, GFP_KERNEL);
3383 HPI_DEBUG_ASSERT(phm != NULL);
3384
3385 hpi_init_message_responseV1(&phm->h,
3386 sizeof(phm->h) + value->header.size, &hr.h, sizeof(hr),
3387 HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
3388 u32TOINDEXES(hC, &phm->h.adapter_index, &phm->h.obj_index);
3389 hr.strv.header.size = sizeof(hr.strv);
3390
3391 memcpy(&phm->strv, value, value->header.size);
3392 hpi_send_recv((struct hpi_message *)&phm->h,
3393 (struct hpi_response *)&hr.h);
3394
3395 return hr.h.error;
3396}
3397
3398u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
3399 const size_t item_count, const enum e_entity_role role, void *value,
3400 struct hpi_entity **entity)
3401{
3402 size_t bytes_to_copy, total_size;
3403 u16 hE = 0;
3404 *entity = NULL;
3405
3406 hE = hpi_entity_check_type(type);
3407 if (hE)
3408 return hE;
3409
3410 HPI_DEBUG_ASSERT(role > entity_role_null && type < LAST_ENTITY_TYPE);
3411
3412 bytes_to_copy = entity_type_to_size[type] * item_count;
3413 total_size = hpi_entity_header_size(*entity) + bytes_to_copy;
3414
3415 HPI_DEBUG_ASSERT(total_size >= hpi_entity_header_size(*entity)
3416 && total_size < STR_SIZE_FIELD_MAX);
3417
3418 *entity = kmalloc(total_size, GFP_KERNEL);
3419 if (*entity == NULL)
3420 return HPI_ERROR_MEMORY_ALLOC;
3421 memcpy((*entity)->value, value, bytes_to_copy);
3422 (*entity)->header.size =
3423 hpi_entity_header_size(*entity) + bytes_to_copy;
3424 (*entity)->header.type = type;
3425 (*entity)->header.role = role;
3426 return 0;
3427}
3428
3429u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
3430 enum e_entity_type type, size_t item_count, void *value_dst_p)
3431{
3432 size_t bytes_to_copy;
3433
3434 if (entity->header.type != type)
3435 return HPI_ERROR_ENTITY_TYPE_MISMATCH;
3436
3437 if (hpi_entity_item_count(entity) != item_count)
3438 return HPI_ERROR_ENTITY_ITEM_COUNT;
3439
3440 bytes_to_copy = entity_type_to_size[type] * item_count;
3441 memcpy(value_dst_p, entity->value, bytes_to_copy);
3442 return 0;
3443}
3444
3445u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
3446 size_t *item_count, enum e_entity_role *role, void **value)
3447{
3448 u16 err = 0;
3449 HPI_DEBUG_ASSERT(entity != NULL);
3450
3451 if (type)
3452 *type = entity->header.type;
3453
3454 if (role)
3455 *role = entity->header.role;
3456
3457 if (value)
3458 *value = entity->value;
3459
3460 if (item_count != NULL) {
3461 if (entity->header.type == entity_type_sequence) {
3462 void *guard_p = hpi_entity_ptr_to_next(entity);
3463 struct hpi_entity *next = NULL;
3464 void *contents = entity->value;
3465
3466 *item_count = 0;
3467 while (contents < guard_p) {
3468 (*item_count)++;
3469 err = hpi_entity_get_next(contents, 0,
3470 guard_p, &next);
3471 if (next == NULL || err)
3472 break;
3473 contents = next;
3474 }
3475 } else {
3476 *item_count = hpi_entity_item_count(entity);
3477 }
3478 }
3479 return err;
3480}
3481
3482u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3483 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits)
3484{
3485 struct hpi_message hm;
3486 struct hpi_response hr;
3487 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_OPEN);
3488 hm.adapter_index = adapter_index;
3489
3490 hpi_send_recv(&hm, &hr);
3491
3492 if (hr.error == 0) {
3493 *ph_gpio =
3494 hpi_indexes_to_handle(HPI_OBJ_GPIO, adapter_index, 0);
3495 if (pw_number_input_bits)
3496 *pw_number_input_bits = hr.u.l.number_input_bits;
3497 if (pw_number_output_bits)
3498 *pw_number_output_bits = hr.u.l.number_output_bits;
3499 } else
3500 *ph_gpio = 0;
3501 return hr.error;
3502}
3503
3504u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3505 u16 bit_index, u16 *pw_bit_data)
3506{
3507 struct hpi_message hm;
3508 struct hpi_response hr;
3509 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_BIT);
3510 u32TOINDEX(h_gpio, &hm.adapter_index);
3511 hm.u.l.bit_index = bit_index;
3512
3513 hpi_send_recv(&hm, &hr);
3514
3515 *pw_bit_data = hr.u.l.bit_data[0];
3516 return hr.error;
3517}
3518
3519u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3520 u16 aw_all_bit_data[4]
3521 )
3522{
3523 struct hpi_message hm;
3524 struct hpi_response hr;
3525 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_ALL);
3526 u32TOINDEX(h_gpio, &hm.adapter_index);
3527
3528 hpi_send_recv(&hm, &hr);
3529
3530 if (aw_all_bit_data) {
3531 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3532 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3533 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3534 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3535 }
3536 return hr.error;
3537}
3538
3539u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3540 u16 bit_index, u16 bit_data)
3541{
3542 struct hpi_message hm;
3543 struct hpi_response hr;
3544 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_WRITE_BIT);
3545 u32TOINDEX(h_gpio, &hm.adapter_index);
3546 hm.u.l.bit_index = bit_index;
3547 hm.u.l.bit_data = bit_data;
3548
3549 hpi_send_recv(&hm, &hr);
3550
3551 return hr.error;
3552}
3553
3554u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3555 u16 aw_all_bit_data[4]
3556 )
3557{
3558 struct hpi_message hm;
3559 struct hpi_response hr;
3560 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO,
3561 HPI_GPIO_WRITE_STATUS);
3562 u32TOINDEX(h_gpio, &hm.adapter_index);
3563
3564 hpi_send_recv(&hm, &hr);
3565
3566 if (aw_all_bit_data) {
3567 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3568 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3569 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3570 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3571 }
3572 return hr.error;
3573}
3574
3575u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
3576 u16 adapter_index, u32 *ph_async)
3577{
3578 struct hpi_message hm;
3579 struct hpi_response hr;
3580 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3581 HPI_ASYNCEVENT_OPEN);
3582 hm.adapter_index = adapter_index;
3583
3584 hpi_send_recv(&hm, &hr);
3585
3586 if (hr.error == 0)
3587
3588 *ph_async =
3589 hpi_indexes_to_handle(HPI_OBJ_ASYNCEVENT,
3590 adapter_index, 0);
3591 else
3592 *ph_async = 0;
3593 return hr.error;
3594
3595}
3596
3597u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async)
3598{
3599 struct hpi_message hm;
3600 struct hpi_response hr;
3601 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3602 HPI_ASYNCEVENT_OPEN);
3603 u32TOINDEX(h_async, &hm.adapter_index);
3604
3605 hpi_send_recv(&hm, &hr);
3606
3607 return hr.error;
3608}
3609
3610u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3611 u16 maximum_events, struct hpi_async_event *p_events,
3612 u16 *pw_number_returned)
3613{
3614 return 0;
3615}
3616
3617u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
3618 u32 h_async, u16 *pw_count)
3619{
3620 struct hpi_message hm;
3621 struct hpi_response hr;
3622 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3623 HPI_ASYNCEVENT_GETCOUNT);
3624 u32TOINDEX(h_async, &hm.adapter_index);
3625
3626 hpi_send_recv(&hm, &hr);
3627
3628 if (hr.error == 0)
3629 if (pw_count)
3630 *pw_count = hr.u.as.u.count.count;
3631
3632 return hr.error;
3633}
3634
3635u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3636 u16 maximum_events, struct hpi_async_event *p_events,
3637 u16 *pw_number_returned)
3638{
3639 struct hpi_message hm;
3640 struct hpi_response hr;
3641 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3642 HPI_ASYNCEVENT_GET);
3643 u32TOINDEX(h_async, &hm.adapter_index);
3644
3645 hpi_send_recv(&hm, &hr);
3646 if (!hr.error) {
3647 memcpy(p_events, &hr.u.as.u.event,
3648 sizeof(struct hpi_async_event));
3649 *pw_number_returned = 1;
3650 }
3651
3652 return hr.error;
3653}
3654
3655u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3656 u32 *ph_nv_memory, u16 *pw_size_in_bytes)
3657{
3658 struct hpi_message hm;
3659 struct hpi_response hr;
3660 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3661 HPI_NVMEMORY_OPEN);
3662 hm.adapter_index = adapter_index;
3663
3664 hpi_send_recv(&hm, &hr);
3665
3666 if (hr.error == 0) {
3667 *ph_nv_memory =
3668 hpi_indexes_to_handle(HPI_OBJ_NVMEMORY, adapter_index,
3669 0);
3670 if (pw_size_in_bytes)
3671 *pw_size_in_bytes = hr.u.n.size_in_bytes;
3672 } else
3673 *ph_nv_memory = 0;
3674 return hr.error;
3675}
3676
3677u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
3678 u32 h_nv_memory, u16 index, u16 *pw_data)
3679{
3680 struct hpi_message hm;
3681 struct hpi_response hr;
3682 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3683 HPI_NVMEMORY_READ_BYTE);
3684 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3685 hm.u.n.address = index;
3686
3687 hpi_send_recv(&hm, &hr);
3688
3689 *pw_data = hr.u.n.data;
3690 return hr.error;
3691}
3692
3693u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
3694 u32 h_nv_memory, u16 index, u16 data)
3695{
3696 struct hpi_message hm;
3697 struct hpi_response hr;
3698 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3699 HPI_NVMEMORY_WRITE_BYTE);
3700 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3701 hm.u.n.address = index;
3702 hm.u.n.data = data;
3703
3704 hpi_send_recv(&hm, &hr);
3705
3706 return hr.error;
3707}
3708
3709u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
3710 u16 adapter_index, u16 profile_index, u32 *ph_profile,
3711 u16 *pw_max_profiles)
3712{
3713 struct hpi_message hm;
3714 struct hpi_response hr;
3715 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3716 HPI_PROFILE_OPEN_ALL);
3717 hm.adapter_index = adapter_index;
3718 hm.obj_index = profile_index;
3719 hpi_send_recv(&hm, &hr);
3720
3721 *pw_max_profiles = hr.u.p.u.o.max_profiles;
3722 if (hr.error == 0)
3723 *ph_profile =
3724 hpi_indexes_to_handle(HPI_OBJ_PROFILE, adapter_index,
3725 profile_index);
3726 else
3727 *ph_profile = 0;
3728 return hr.error;
3729}
3730
3731u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3732 u16 bin_index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
3733 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds)
3734{
3735 struct hpi_message hm;
3736 struct hpi_response hr;
3737 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE, HPI_PROFILE_GET);
3738 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3739 hm.u.p.bin_index = bin_index;
3740 hpi_send_recv(&hm, &hr);
3741 if (pw_seconds)
3742 *pw_seconds = hr.u.p.u.t.seconds;
3743 if (pmicro_seconds)
3744 *pmicro_seconds = hr.u.p.u.t.micro_seconds;
3745 if (pcall_count)
3746 *pcall_count = hr.u.p.u.t.call_count;
3747 if (pmax_micro_seconds)
3748 *pmax_micro_seconds = hr.u.p.u.t.max_micro_seconds;
3749 if (pmin_micro_seconds)
3750 *pmin_micro_seconds = hr.u.p.u.t.min_micro_seconds;
3751 return hr.error;
3752}
3753
3754u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
3755 u32 h_profile, u32 *putilization)
3756{
3757 struct hpi_message hm;
3758 struct hpi_response hr;
3759 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3760 HPI_PROFILE_GET_UTILIZATION);
3761 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3762 hpi_send_recv(&hm, &hr);
3763 if (hr.error) {
3764 if (putilization)
3765 *putilization = 0;
3766 } else {
3767 if (putilization)
3768 *putilization = hr.u.p.u.t.call_count;
3769 }
3770 return hr.error;
3771}
3772
3773u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3774 u16 bin_index, char *sz_name, u16 name_length)
3775{
3776 struct hpi_message hm;
3777 struct hpi_response hr;
3778 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3779 HPI_PROFILE_GET_NAME);
3780 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3781 hm.u.p.bin_index = bin_index;
3782 hpi_send_recv(&hm, &hr);
3783 if (hr.error) {
3784 if (sz_name)
3785 strcpy(sz_name, "??");
3786 } else {
3787 if (sz_name)
3788 memcpy(sz_name, (char *)hr.u.p.u.n.sz_name,
3789 name_length);
3790 }
3791 return hr.error;
3792}
3793
3794u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3795{
3796 struct hpi_message hm;
3797 struct hpi_response hr;
3798 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3799 HPI_PROFILE_START_ALL);
3800 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3801 hpi_send_recv(&hm, &hr);
3802
3803 return hr.error;
3804}
3805
3806u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3807{
3808 struct hpi_message hm;
3809 struct hpi_response hr;
3810 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3811 HPI_PROFILE_STOP_ALL);
3812 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3813 hpi_send_recv(&hm, &hr);
3814
3815 return hr.error;
3816}
3817
3818u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3819 u32 *ph_watchdog)
3820{
3821 struct hpi_message hm;
3822 struct hpi_response hr;
3823 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3824 HPI_WATCHDOG_OPEN);
3825 hm.adapter_index = adapter_index;
3826
3827 hpi_send_recv(&hm, &hr);
3828
3829 if (hr.error == 0)
3830 *ph_watchdog =
3831 hpi_indexes_to_handle(HPI_OBJ_WATCHDOG, adapter_index,
3832 0);
3833 else
3834 *ph_watchdog = 0;
3835 return hr.error;
3836}
3837
3838u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
3839 u32 time_millisec)
3840{
3841 struct hpi_message hm;
3842 struct hpi_response hr;
3843 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3844 HPI_WATCHDOG_SET_TIME);
3845 u32TOINDEX(h_watchdog, &hm.adapter_index);
3846 hm.u.w.time_ms = time_millisec;
3847
3848 hpi_send_recv(&hm, &hr);
3849
3850 return hr.error;
3851}
3852
3853u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog)
3854{
3855 struct hpi_message hm;
3856 struct hpi_response hr;
3857 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3858 HPI_WATCHDOG_PING);
3859 u32TOINDEX(h_watchdog, &hm.adapter_index);
3860
3861 hpi_send_recv(&hm, &hr);
3862
3863 return hr.error;
3864}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
new file mode 100644
index 000000000000..8e1d099ed7e4
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -0,0 +1,130 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) Utility functions.
20
21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/
23
24#include "hpi_internal.h"
25#include "hpimsginit.h"
26
27/* The actual message size for each object type */
28static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
29/* The actual response size for each object type */
30static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
31/* Flag to enable alternate message type for SSX2 bypass. */
32static u16 gwSSX2_bypass;
33
34/** \internal
35 * Used by ASIO driver to disable SSX2 for a single process
36 * \param phSubSys Pointer to HPI subsystem handle.
37 * \param wBypass New bypass setting 0 = off, nonzero = on
38 * \return Previous bypass setting.
39 */
40u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass)
41{
42 u16 old_value = gwSSX2_bypass;
43
44 gwSSX2_bypass = bypass;
45
46 return old_value;
47}
48
49/** \internal
50 * initialize the HPI message structure
51 */
52static void hpi_init_message(struct hpi_message *phm, u16 object,
53 u16 function)
54{
55 memset(phm, 0, sizeof(*phm));
56 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
57 phm->size = msg_size[object];
58 else
59 phm->size = sizeof(*phm);
60
61 if (gwSSX2_bypass)
62 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
63 else
64 phm->type = HPI_TYPE_MESSAGE;
65 phm->object = object;
66 phm->function = function;
67 phm->version = 0;
68 /* Expect adapter index to be set by caller */
69}
70
71/** \internal
72 * initialize the HPI response structure
73 */
74void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
75 u16 error)
76{
77 memset(phr, 0, sizeof(*phr));
78 phr->type = HPI_TYPE_RESPONSE;
79 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
80 phr->size = res_size[object];
81 else
82 phr->size = sizeof(*phr);
83 phr->object = object;
84 phr->function = function;
85 phr->error = error;
86 phr->specific_error = 0;
87 phr->version = 0;
88}
89
90void hpi_init_message_response(struct hpi_message *phm,
91 struct hpi_response *phr, u16 object, u16 function)
92{
93 hpi_init_message(phm, object, function);
94 /* default error return if the response is
95 not filled in by the callee */
96 hpi_init_response(phr, object, function,
97 HPI_ERROR_PROCESSING_MESSAGE);
98}
99
100static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
101 u16 object, u16 function)
102{
103 memset(phm, 0, sizeof(*phm));
104 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
105 phm->size = size;
106 phm->type = HPI_TYPE_MESSAGE;
107 phm->object = object;
108 phm->function = function;
109 phm->version = 1;
110 /* Expect adapter index to be set by caller */
111 }
112}
113
114void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
115 u16 object, u16 function)
116{
117 memset(phr, 0, sizeof(*phr));
118 phr->size = size;
119 phr->version = 1;
120 phr->type = HPI_TYPE_RESPONSE;
121 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
122}
123
124void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
125 struct hpi_response_header *phr, u16 res_size, u16 object,
126 u16 function)
127{
128 hpi_init_messageV1(phm, msg_size, object, function);
129 hpi_init_responseV1(phr, res_size, object, function);
130}
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
new file mode 100644
index 000000000000..864ad020c9b3
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -0,0 +1,40 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) Utility functions
20
21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/
23/* Initialise response headers, or msg/response pairs.
24Note that it is valid to just init a response e.g. when a lower level is preparing
25a response to a message.
26However, when sending a message, a matching response buffer always must be prepared
27*/
28
29void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
30 u16 error);
31
32void hpi_init_message_response(struct hpi_message *phm,
33 struct hpi_response *phr, u16 object, u16 function);
34
35void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
36 u16 object, u16 function);
37
38void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
39 struct hpi_response_header *phr, u16 res_size, u16 object,
40 u16 function);
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
new file mode 100644
index 000000000000..2ee90dc3d897
--- /dev/null
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -0,0 +1,907 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Extended Message Function With Response Cacheing
20
21(C) Copyright AudioScience Inc. 2002
22*****************************************************************************/
23#define SOURCEFILE_NAME "hpimsgx.c"
24#include "hpi_internal.h"
25#include "hpimsginit.h"
26#include "hpimsgx.h"
27#include "hpidebug.h"
28
29static struct pci_device_id asihpi_pci_tbl[] = {
30#include "hpipcida.h"
31};
32
33static struct hpios_spinlock msgx_lock;
34
35static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
36
37static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
38 *pci_info)
39{
40
41 int i;
42
43 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
44 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
45 && asihpi_pci_tbl[i].vendor != pci_info->vendor_id)
46 continue;
47 if (asihpi_pci_tbl[i].device != PCI_ANY_ID
48 && asihpi_pci_tbl[i].device != pci_info->device_id)
49 continue;
50 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
51 && asihpi_pci_tbl[i].subvendor !=
52 pci_info->subsys_vendor_id)
53 continue;
54 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
55 && asihpi_pci_tbl[i].subdevice !=
56 pci_info->subsys_device_id)
57 continue;
58
59 HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i,
60 asihpi_pci_tbl[i].driver_data);
61 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
62 }
63
64 return NULL;
65}
66
67static inline void hw_entry_point(struct hpi_message *phm,
68 struct hpi_response *phr)
69{
70
71 hpi_handler_func *ep;
72
73 if (phm->adapter_index < HPI_MAX_ADAPTERS) {
74 ep = (hpi_handler_func *) hpi_entry_points[phm->
75 adapter_index];
76 if (ep) {
77 HPI_DEBUG_MESSAGE(DEBUG, phm);
78 ep(phm, phr);
79 HPI_DEBUG_RESPONSE(phr);
80 return;
81 }
82 }
83 hpi_init_response(phr, phm->object, phm->function,
84 HPI_ERROR_PROCESSING_MESSAGE);
85}
86
87static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
88static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
89
90static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
91static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
92
93static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
94 void *h_owner);
95static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
96 void *h_owner);
97static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
98 void *h_owner);
99static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
100 void *h_owner);
101
102static void HPIMSGX__reset(u16 adapter_index);
103static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
104static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
105
106#ifndef DISABLE_PRAGMA_PACK1
107#pragma pack(push, 1)
108#endif
109
110struct hpi_subsys_response {
111 struct hpi_response_header h;
112 struct hpi_subsys_res s;
113};
114
115struct hpi_adapter_response {
116 struct hpi_response_header h;
117 struct hpi_adapter_res a;
118};
119
120struct hpi_mixer_response {
121 struct hpi_response_header h;
122 struct hpi_mixer_res m;
123};
124
125struct hpi_stream_response {
126 struct hpi_response_header h;
127 struct hpi_stream_res d;
128};
129
130struct adapter_info {
131 u16 type;
132 u16 num_instreams;
133 u16 num_outstreams;
134};
135
136struct asi_open_state {
137 int open_flag;
138 void *h_owner;
139};
140
141#ifndef DISABLE_PRAGMA_PACK1
142#pragma pack(pop)
143#endif
144
145/* Globals */
146static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
147
148static struct hpi_stream_response
149 rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
150
151static struct hpi_stream_response
152 rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
153
154static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
155
156static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
157
158static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
159
160/* use these to keep track of opens from user mode apps/DLLs */
161static struct asi_open_state
162 outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
163
164static struct asi_open_state
165 instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
166
167static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
168 void *h_owner)
169{
170 switch (phm->function) {
171 case HPI_SUBSYS_GET_VERSION:
172 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
173 HPI_SUBSYS_GET_VERSION, 0);
174 phr->u.s.version = HPI_VER >> 8; /* return major.minor */
175 phr->u.s.data = HPI_VER; /* return major.minor.release */
176 break;
177 case HPI_SUBSYS_OPEN:
178 /*do not propagate the message down the chain */
179 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
180 break;
181 case HPI_SUBSYS_CLOSE:
182 /*do not propagate the message down the chain */
183 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
184 0);
185 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
186 break;
187 case HPI_SUBSYS_DRIVER_LOAD:
188 /* Initialize this module's internal state */
189 hpios_msgxlock_init(&msgx_lock);
190 memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
191 hpios_locked_mem_init();
192 /* Init subsys_findadapters response to no-adapters */
193 HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
194 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
195 HPI_SUBSYS_DRIVER_LOAD, 0);
196 /* individual HPIs dont implement driver load */
197 HPI_COMMON(phm, phr);
198 break;
199 case HPI_SUBSYS_DRIVER_UNLOAD:
200 HPI_COMMON(phm, phr);
201 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
202 hpios_locked_mem_free_all();
203 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
204 HPI_SUBSYS_DRIVER_UNLOAD, 0);
205 return;
206
207 case HPI_SUBSYS_GET_INFO:
208 HPI_COMMON(phm, phr);
209 break;
210
211 case HPI_SUBSYS_FIND_ADAPTERS:
212 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
213 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
214 break;
215 case HPI_SUBSYS_GET_NUM_ADAPTERS:
216 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
217 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
218 phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
219 break;
220 case HPI_SUBSYS_GET_ADAPTER:
221 {
222 int count = phm->adapter_index;
223 int index = 0;
224 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
225 HPI_SUBSYS_GET_ADAPTER, 0);
226
227 /* This is complicated by the fact that we want to
228 * "skip" 0's in the adapter list.
229 * First, make sure we are pointing to a
230 * non-zero adapter type.
231 */
232 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
233 s.aw_adapter_list[index] == 0) {
234 index++;
235 if (index >= HPI_MAX_ADAPTERS)
236 break;
237 }
238 while (count) {
239 /* move on to the next adapter */
240 index++;
241 if (index >= HPI_MAX_ADAPTERS)
242 break;
243 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
244 s.aw_adapter_list[index] == 0) {
245 index++;
246 if (index >= HPI_MAX_ADAPTERS)
247 break;
248 }
249 count--;
250 }
251
252 if (index < HPI_MAX_ADAPTERS) {
253 phr->u.s.adapter_index = (u16)index;
254 phr->u.s.aw_adapter_list[0] =
255 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
256 s.aw_adapter_list[index];
257 } else {
258 phr->u.s.adapter_index = 0;
259 phr->u.s.aw_adapter_list[0] = 0;
260 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
261 }
262 break;
263 }
264 case HPI_SUBSYS_CREATE_ADAPTER:
265 HPIMSGX__init(phm, phr);
266 break;
267 case HPI_SUBSYS_DELETE_ADAPTER:
268 HPIMSGX__cleanup(phm->adapter_index, h_owner);
269 {
270 struct hpi_message hm;
271 struct hpi_response hr;
272 /* call to HPI_ADAPTER_CLOSE */
273 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
274 HPI_ADAPTER_CLOSE);
275 hm.adapter_index = phm->adapter_index;
276 hw_entry_point(&hm, &hr);
277 }
278 hw_entry_point(phm, phr);
279 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.
280 aw_adapter_list[phm->adapter_index]
281 = 0;
282 hpi_entry_points[phm->adapter_index] = NULL;
283 break;
284 default:
285 hw_entry_point(phm, phr);
286 break;
287 }
288}
289
290static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
291 void *h_owner)
292{
293 switch (phm->function) {
294 case HPI_ADAPTER_OPEN:
295 adapter_open(phm, phr);
296 break;
297 case HPI_ADAPTER_CLOSE:
298 adapter_close(phm, phr);
299 break;
300 default:
301 hw_entry_point(phm, phr);
302 break;
303 }
304}
305
306static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
307{
308 switch (phm->function) {
309 case HPI_MIXER_OPEN:
310 mixer_open(phm, phr);
311 break;
312 case HPI_MIXER_CLOSE:
313 mixer_close(phm, phr);
314 break;
315 default:
316 hw_entry_point(phm, phr);
317 break;
318 }
319}
320
321static void outstream_message(struct hpi_message *phm,
322 struct hpi_response *phr, void *h_owner)
323{
324 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
325 hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
326 HPI_ERROR_INVALID_OBJ_INDEX);
327 return;
328 }
329
330 switch (phm->function) {
331 case HPI_OSTREAM_OPEN:
332 outstream_open(phm, phr, h_owner);
333 break;
334 case HPI_OSTREAM_CLOSE:
335 outstream_close(phm, phr, h_owner);
336 break;
337 default:
338 hw_entry_point(phm, phr);
339 break;
340 }
341}
342
343static void instream_message(struct hpi_message *phm,
344 struct hpi_response *phr, void *h_owner)
345{
346 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
347 hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
348 HPI_ERROR_INVALID_OBJ_INDEX);
349 return;
350 }
351
352 switch (phm->function) {
353 case HPI_ISTREAM_OPEN:
354 instream_open(phm, phr, h_owner);
355 break;
356 case HPI_ISTREAM_CLOSE:
357 instream_close(phm, phr, h_owner);
358 break;
359 default:
360 hw_entry_point(phm, phr);
361 break;
362 }
363}
364
365/* NOTE: HPI_Message() must be defined in the driver as a wrapper for
366 * HPI_MessageEx so that functions in hpifunc.c compile.
367 */
368void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
369 void *h_owner)
370{
371 HPI_DEBUG_MESSAGE(DEBUG, phm);
372
373 if (phm->type != HPI_TYPE_MESSAGE) {
374 hpi_init_response(phr, phm->object, phm->function,
375 HPI_ERROR_INVALID_TYPE);
376 return;
377 }
378
379 if (phm->adapter_index >= HPI_MAX_ADAPTERS
380 && phm->adapter_index != HPIMSGX_ALLADAPTERS) {
381 hpi_init_response(phr, phm->object, phm->function,
382 HPI_ERROR_BAD_ADAPTER_NUMBER);
383 return;
384 }
385
386 switch (phm->object) {
387 case HPI_OBJ_SUBSYSTEM:
388 subsys_message(phm, phr, h_owner);
389 break;
390
391 case HPI_OBJ_ADAPTER:
392 adapter_message(phm, phr, h_owner);
393 break;
394
395 case HPI_OBJ_MIXER:
396 mixer_message(phm, phr);
397 break;
398
399 case HPI_OBJ_OSTREAM:
400 outstream_message(phm, phr, h_owner);
401 break;
402
403 case HPI_OBJ_ISTREAM:
404 instream_message(phm, phr, h_owner);
405 break;
406
407 default:
408 hw_entry_point(phm, phr);
409 break;
410 }
411 HPI_DEBUG_RESPONSE(phr);
412#if 1
413 if (phr->error >= HPI_ERROR_BACKEND_BASE) {
414 void *ep = NULL;
415 char *ep_name;
416
417 HPI_DEBUG_MESSAGE(ERROR, phm);
418
419 if (phm->adapter_index < HPI_MAX_ADAPTERS)
420 ep = hpi_entry_points[phm->adapter_index];
421
422 /* Don't need this? Have adapter index in debug info
423 Know at driver load time index->backend mapping */
424 if (ep == HPI_6000)
425 ep_name = "HPI_6000";
426 else if (ep == HPI_6205)
427 ep_name = "HPI_6205";
428 else
429 ep_name = "unknown";
430
431 HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
432 phr->error);
433
434 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
435 hpi_debug_data((u16 *)phm,
436 sizeof(*phm) / sizeof(u16));
437 }
438#endif
439}
440
441static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
442{
443 HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
444 memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
445 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
446}
447
448static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
449{
450 HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
451 hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
452}
453
454static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
455{
456 memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
457 sizeof(rESP_HPI_MIXER_OPEN[0]));
458}
459
460static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
461{
462 hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
463}
464
465static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
466 void *h_owner)
467{
468
469 struct hpi_message hm;
470 struct hpi_response hr;
471
472 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
473
474 hpios_msgxlock_lock(&msgx_lock);
475
476 if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
477 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
478 else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
479 [phm->obj_index].h.error)
480 memcpy(phr,
481 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
482 obj_index],
483 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
484 else {
485 instream_user_open[phm->adapter_index][phm->
486 obj_index].open_flag = 1;
487 hpios_msgxlock_un_lock(&msgx_lock);
488
489 /* issue a reset */
490 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
491 HPI_ISTREAM_RESET);
492 hm.adapter_index = phm->adapter_index;
493 hm.obj_index = phm->obj_index;
494 hw_entry_point(&hm, &hr);
495
496 hpios_msgxlock_lock(&msgx_lock);
497 if (hr.error) {
498 instream_user_open[phm->adapter_index][phm->
499 obj_index].open_flag = 0;
500 phr->error = hr.error;
501 } else {
502 instream_user_open[phm->adapter_index][phm->
503 obj_index].open_flag = 1;
504 instream_user_open[phm->adapter_index][phm->
505 obj_index].h_owner = h_owner;
506 memcpy(phr,
507 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
508 [phm->obj_index],
509 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
510 }
511 }
512 hpios_msgxlock_un_lock(&msgx_lock);
513}
514
515static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
516 void *h_owner)
517{
518
519 struct hpi_message hm;
520 struct hpi_response hr;
521
522 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
523
524 hpios_msgxlock_lock(&msgx_lock);
525 if (h_owner ==
526 instream_user_open[phm->adapter_index][phm->
527 obj_index].h_owner) {
528 /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
529 "instream %d owned by %p\n",
530 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
531 instream_user_open[phm->adapter_index][phm->
532 obj_index].h_owner = NULL;
533 hpios_msgxlock_un_lock(&msgx_lock);
534 /* issue a reset */
535 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
536 HPI_ISTREAM_RESET);
537 hm.adapter_index = phm->adapter_index;
538 hm.obj_index = phm->obj_index;
539 hw_entry_point(&hm, &hr);
540 hpios_msgxlock_lock(&msgx_lock);
541 if (hr.error) {
542 instream_user_open[phm->adapter_index][phm->
543 obj_index].h_owner = h_owner;
544 phr->error = hr.error;
545 } else {
546 instream_user_open[phm->adapter_index][phm->
547 obj_index].open_flag = 0;
548 instream_user_open[phm->adapter_index][phm->
549 obj_index].h_owner = NULL;
550 }
551 } else {
552 HPI_DEBUG_LOG(WARNING,
553 "%p trying to close %d instream %d owned by %p\n",
554 h_owner, phm->adapter_index, phm->obj_index,
555 instream_user_open[phm->adapter_index][phm->
556 obj_index].h_owner);
557 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
558 }
559 hpios_msgxlock_un_lock(&msgx_lock);
560}
561
562static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
563 void *h_owner)
564{
565
566 struct hpi_message hm;
567 struct hpi_response hr;
568
569 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
570
571 hpios_msgxlock_lock(&msgx_lock);
572
573 if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
574 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
575 else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
576 [phm->obj_index].h.error)
577 memcpy(phr,
578 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
579 obj_index],
580 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
581 else {
582 outstream_user_open[phm->adapter_index][phm->
583 obj_index].open_flag = 1;
584 hpios_msgxlock_un_lock(&msgx_lock);
585
586 /* issue a reset */
587 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
588 HPI_OSTREAM_RESET);
589 hm.adapter_index = phm->adapter_index;
590 hm.obj_index = phm->obj_index;
591 hw_entry_point(&hm, &hr);
592
593 hpios_msgxlock_lock(&msgx_lock);
594 if (hr.error) {
595 outstream_user_open[phm->adapter_index][phm->
596 obj_index].open_flag = 0;
597 phr->error = hr.error;
598 } else {
599 outstream_user_open[phm->adapter_index][phm->
600 obj_index].open_flag = 1;
601 outstream_user_open[phm->adapter_index][phm->
602 obj_index].h_owner = h_owner;
603 memcpy(phr,
604 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
605 [phm->obj_index],
606 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
607 }
608 }
609 hpios_msgxlock_un_lock(&msgx_lock);
610}
611
612static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
613 void *h_owner)
614{
615
616 struct hpi_message hm;
617 struct hpi_response hr;
618
619 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
620
621 hpios_msgxlock_lock(&msgx_lock);
622
623 if (h_owner ==
624 outstream_user_open[phm->adapter_index][phm->
625 obj_index].h_owner) {
626 /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
627 "outstream %d owned by %p\n",
628 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
629 outstream_user_open[phm->adapter_index][phm->
630 obj_index].h_owner = NULL;
631 hpios_msgxlock_un_lock(&msgx_lock);
632 /* issue a reset */
633 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
634 HPI_OSTREAM_RESET);
635 hm.adapter_index = phm->adapter_index;
636 hm.obj_index = phm->obj_index;
637 hw_entry_point(&hm, &hr);
638 hpios_msgxlock_lock(&msgx_lock);
639 if (hr.error) {
640 outstream_user_open[phm->adapter_index][phm->
641 obj_index].h_owner = h_owner;
642 phr->error = hr.error;
643 } else {
644 outstream_user_open[phm->adapter_index][phm->
645 obj_index].open_flag = 0;
646 outstream_user_open[phm->adapter_index][phm->
647 obj_index].h_owner = NULL;
648 }
649 } else {
650 HPI_DEBUG_LOG(WARNING,
651 "%p trying to close %d outstream %d owned by %p\n",
652 h_owner, phm->adapter_index, phm->obj_index,
653 outstream_user_open[phm->adapter_index][phm->
654 obj_index].h_owner);
655 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
656 }
657 hpios_msgxlock_un_lock(&msgx_lock);
658}
659
660static u16 adapter_prepare(u16 adapter)
661{
662 struct hpi_message hm;
663 struct hpi_response hr;
664
665 /* Open the adapter and streams */
666 u16 i;
667
668 /* call to HPI_ADAPTER_OPEN */
669 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
670 HPI_ADAPTER_OPEN);
671 hm.adapter_index = adapter;
672 hw_entry_point(&hm, &hr);
673 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
674 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
675 if (hr.error)
676 return hr.error;
677
678 /* call to HPI_ADAPTER_GET_INFO */
679 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
680 HPI_ADAPTER_GET_INFO);
681 hm.adapter_index = adapter;
682 hw_entry_point(&hm, &hr);
683 if (hr.error)
684 return hr.error;
685
686 aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams;
687 aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams;
688 aDAPTER_INFO[adapter].type = hr.u.a.adapter_type;
689
690 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
691 hr.u.a.adapter_type;
692 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
693 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
694 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
695 HPI_MAX_ADAPTERS;
696
697 /* call to HPI_OSTREAM_OPEN */
698 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
699 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
700 HPI_OSTREAM_OPEN);
701 hm.adapter_index = adapter;
702 hm.obj_index = i;
703 hw_entry_point(&hm, &hr);
704 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
705 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
706 outstream_user_open[adapter][i].open_flag = 0;
707 outstream_user_open[adapter][i].h_owner = NULL;
708 }
709
710 /* call to HPI_ISTREAM_OPEN */
711 for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
712 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
713 HPI_ISTREAM_OPEN);
714 hm.adapter_index = adapter;
715 hm.obj_index = i;
716 hw_entry_point(&hm, &hr);
717 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
718 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
719 instream_user_open[adapter][i].open_flag = 0;
720 instream_user_open[adapter][i].h_owner = NULL;
721 }
722
723 /* call to HPI_MIXER_OPEN */
724 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
725 hm.adapter_index = adapter;
726 hw_entry_point(&hm, &hr);
727 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
728 sizeof(rESP_HPI_MIXER_OPEN[0]));
729
730 return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error;
731}
732
733static void HPIMSGX__reset(u16 adapter_index)
734{
735 int i;
736 u16 adapter;
737 struct hpi_response hr;
738
739 if (adapter_index == HPIMSGX_ALLADAPTERS) {
740 /* reset all responses to contain errors */
741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742 HPI_SUBSYS_FIND_ADAPTERS, 0);
743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744 sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745
746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747
748 hpi_init_response(&hr, HPI_OBJ_ADAPTER,
749 HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
750 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
751 sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
752
753 hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
754 HPI_ERROR_INVALID_OBJ);
755 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
756 sizeof(rESP_HPI_MIXER_OPEN[adapter]));
757
758 for (i = 0; i < HPI_MAX_STREAMS; i++) {
759 hpi_init_response(&hr, HPI_OBJ_OSTREAM,
760 HPI_OSTREAM_OPEN,
761 HPI_ERROR_INVALID_OBJ);
762 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
763 &hr,
764 sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
765 [i]));
766 hpi_init_response(&hr, HPI_OBJ_ISTREAM,
767 HPI_ISTREAM_OPEN,
768 HPI_ERROR_INVALID_OBJ);
769 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
770 &hr,
771 sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
772 [i]));
773 }
774 }
775 } else if (adapter_index < HPI_MAX_ADAPTERS) {
776 rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
777 HPI_ERROR_BAD_ADAPTER;
778 rESP_HPI_MIXER_OPEN[adapter_index].h.error =
779 HPI_ERROR_INVALID_OBJ;
780 for (i = 0; i < HPI_MAX_STREAMS; i++) {
781 rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
782 HPI_ERROR_INVALID_OBJ;
783 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
784 HPI_ERROR_INVALID_OBJ;
785 }
786 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
787 s.aw_adapter_list[adapter_index]) {
788 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
789 s.aw_adapter_list[adapter_index] = 0;
790 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
791 }
792 }
793}
794
795static u16 HPIMSGX__init(struct hpi_message *phm,
796 /* HPI_SUBSYS_CREATE_ADAPTER structure with */
797 /* resource list or NULL=find all */
798 struct hpi_response *phr
799 /* response from HPI_ADAPTER_GET_INFO */
800 )
801{
802 hpi_handler_func *entry_point_func;
803 struct hpi_response hr;
804
805 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
806 return HPI_ERROR_BAD_ADAPTER_NUMBER;
807
808 /* Init response here so we can pass in previous adapter list */
809 hpi_init_response(&hr, phm->object, phm->function,
810 HPI_ERROR_INVALID_OBJ);
811 memcpy(hr.u.s.aw_adapter_list,
812 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
813 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
814
815 entry_point_func =
816 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
817
818 if (entry_point_func) {
819 HPI_DEBUG_MESSAGE(DEBUG, phm);
820 entry_point_func(phm, &hr);
821 } else {
822 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
823 return phr->error;
824 }
825 if (hr.error == 0) {
826 /* the adapter was created succesfully
827 save the mapping for future use */
828 hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
829 /* prepare adapter (pre-open streams etc.) */
830 HPI_DEBUG_LOG(DEBUG,
831 "HPI_SUBSYS_CREATE_ADAPTER successful,"
832 " preparing adapter\n");
833 adapter_prepare(hr.u.s.adapter_index);
834 }
835 memcpy(phr, &hr, hr.size);
836 return phr->error;
837}
838
839static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
840{
841 int i, adapter, adapter_limit;
842
843 if (!h_owner)
844 return;
845
846 if (adapter_index == HPIMSGX_ALLADAPTERS) {
847 adapter = 0;
848 adapter_limit = HPI_MAX_ADAPTERS;
849 } else {
850 adapter = adapter_index;
851 adapter_limit = adapter + 1;
852 }
853
854 for (; adapter < adapter_limit; adapter++) {
855 /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */
856 for (i = 0; i < HPI_MAX_STREAMS; i++) {
857 if (h_owner ==
858 outstream_user_open[adapter][i].h_owner) {
859 struct hpi_message hm;
860 struct hpi_response hr;
861
862 HPI_DEBUG_LOG(DEBUG,
863 "close adapter %d ostream %d\n",
864 adapter, i);
865
866 hpi_init_message_response(&hm, &hr,
867 HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
868 hm.adapter_index = (u16)adapter;
869 hm.obj_index = (u16)i;
870 hw_entry_point(&hm, &hr);
871
872 hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
873 hw_entry_point(&hm, &hr);
874
875 hm.function = HPI_OSTREAM_GROUP_RESET;
876 hw_entry_point(&hm, &hr);
877
878 outstream_user_open[adapter][i].open_flag = 0;
879 outstream_user_open[adapter][i].h_owner =
880 NULL;
881 }
882 if (h_owner == instream_user_open[adapter][i].h_owner) {
883 struct hpi_message hm;
884 struct hpi_response hr;
885
886 HPI_DEBUG_LOG(DEBUG,
887 "close adapter %d istream %d\n",
888 adapter, i);
889
890 hpi_init_message_response(&hm, &hr,
891 HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
892 hm.adapter_index = (u16)adapter;
893 hm.obj_index = (u16)i;
894 hw_entry_point(&hm, &hr);
895
896 hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
897 hw_entry_point(&hm, &hr);
898
899 hm.function = HPI_ISTREAM_GROUP_RESET;
900 hw_entry_point(&hm, &hr);
901
902 instream_user_open[adapter][i].open_flag = 0;
903 instream_user_open[adapter][i].h_owner = NULL;
904 }
905 }
906 }
907}
diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h
new file mode 100644
index 000000000000..fd49e7542a88
--- /dev/null
+++ b/sound/pci/asihpi/hpimsgx.h
@@ -0,0 +1,36 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 HPI Extended Message Handler Functions
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23
24#ifndef _HPIMSGX_H_
25#define _HPIMSGX_H_
26
27#include "hpi_internal.h"
28
29#define HPIMSGX_ALLADAPTERS (0xFFFF)
30
31void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
32 void *h_owner);
33
34#define HPI_MESSAGE_LOWER_LAYER hpi_send_recv_ex
35
36#endif /* _HPIMSGX_H_ */
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
new file mode 100644
index 000000000000..7396ac54e99f
--- /dev/null
+++ b/sound/pci/asihpi/hpioctl.c
@@ -0,0 +1,484 @@
1/*******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Common Linux HPI ioctl and module probe/remove functions
20*******************************************************************************/
21#define SOURCEFILE_NAME "hpioctl.c"
22
23#include "hpi_internal.h"
24#include "hpimsginit.h"
25#include "hpidebug.h"
26#include "hpimsgx.h"
27#include "hpioctl.h"
28
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/moduleparam.h>
32#include <asm/uaccess.h>
33#include <linux/stringify.h>
34
35#ifdef MODULE_FIRMWARE
36MODULE_FIRMWARE("asihpi/dsp5000.bin");
37MODULE_FIRMWARE("asihpi/dsp6200.bin");
38MODULE_FIRMWARE("asihpi/dsp6205.bin");
39MODULE_FIRMWARE("asihpi/dsp6400.bin");
40MODULE_FIRMWARE("asihpi/dsp6600.bin");
41MODULE_FIRMWARE("asihpi/dsp8700.bin");
42MODULE_FIRMWARE("asihpi/dsp8900.bin");
43#endif
44
45static int prealloc_stream_buf;
46module_param(prealloc_stream_buf, int, S_IRUGO);
47MODULE_PARM_DESC(prealloc_stream_buf,
48 "preallocate size for per-adapter stream buffer");
49
50/* Allow the debug level to be changed after module load.
51 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
52*/
53module_param(hpi_debug_level, int, S_IRUGO | S_IWUSR);
54MODULE_PARM_DESC(hpi_debug_level, "debug verbosity 0..5");
55
56/* List of adapters found */
57static struct hpi_adapter adapters[HPI_MAX_ADAPTERS];
58
59/* Wrapper function to HPI_Message to enable dumping of the
60 message and response types.
61*/
62static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
63 struct file *file)
64{
65 int adapter = phm->adapter_index;
66
67 if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0)
68 && (phm->object != HPI_OBJ_SUBSYSTEM))
69 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
70 else
71 hpi_send_recv_ex(phm, phr, file);
72}
73
74/* This is called from hpifunc.c functions, called by ALSA
75 * (or other kernel process) In this case there is no file descriptor
76 * available for the message cache code
77 */
78void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr)
79{
80 hpi_send_recv_f(phm, phr, HOWNER_KERNEL);
81}
82
83EXPORT_SYMBOL(hpi_send_recv);
84/* for radio-asihpi */
85
86int asihpi_hpi_release(struct file *file)
87{
88 struct hpi_message hm;
89 struct hpi_response hr;
90
91/* HPI_DEBUG_LOG(INFO,"hpi_release file %p, pid %d\n", file, current->pid); */
92 /* close the subsystem just in case the application forgot to. */
93 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
94 HPI_SUBSYS_CLOSE);
95 hpi_send_recv_ex(&hm, &hr, file);
96 return 0;
97}
98
99long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
100{
101 struct hpi_ioctl_linux __user *phpi_ioctl_data;
102 void __user *puhm;
103 void __user *puhr;
104 union hpi_message_buffer_v1 *hm;
105 union hpi_response_buffer_v1 *hr;
106 u16 res_max_size;
107 u32 uncopied_bytes;
108 struct hpi_adapter *pa = NULL;
109 int err = 0;
110
111 if (cmd != HPI_IOCTL_LINUX)
112 return -EINVAL;
113
114 hm = kmalloc(sizeof(*hm), GFP_KERNEL);
115 hr = kmalloc(sizeof(*hr), GFP_KERNEL);
116 if (!hm || !hr) {
117 err = -ENOMEM;
118 goto out;
119 }
120
121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
122
123 /* Read the message and response pointers from user space. */
124 get_user(puhm, &phpi_ioctl_data->phm);
125 get_user(puhr, &phpi_ioctl_data->phr);
126
127 /* Now read the message size and data from user space. */
128 get_user(hm->h.size, (u16 __user *)puhm);
129 if (hm->h.size > sizeof(*hm))
130 hm->h.size = sizeof(*hm);
131
132 /*printk(KERN_INFO "message size %d\n", hm->h.wSize); */
133
134 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
135 if (uncopied_bytes) {
136 HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
137 err = -EFAULT;
138 goto out;
139 }
140
141 get_user(res_max_size, (u16 __user *)puhr);
142 /* printk(KERN_INFO "user response size %d\n", res_max_size); */
143 if (res_max_size < sizeof(struct hpi_response_header)) {
144 HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size);
145 err = -EFAULT;
146 goto out;
147 }
148
149 pa = &adapters[hm->h.adapter_index];
150 hr->h.size = 0;
151 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
152 switch (hm->h.function) {
153 case HPI_SUBSYS_CREATE_ADAPTER:
154 case HPI_SUBSYS_DELETE_ADAPTER:
155 /* Application must not use these functions! */
156 hr->h.size = sizeof(hr->h);
157 hr->h.error = HPI_ERROR_INVALID_OPERATION;
158 hr->h.function = hm->h.function;
159 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
160 if (uncopied_bytes)
161 err = -EFAULT;
162 else
163 err = 0;
164 goto out;
165
166 default:
167 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 }
169 } else {
170 u16 __user *ptr = NULL;
171 u32 size = 0;
172
173 /* -1=no data 0=read from user mem, 1=write to user mem */
174 int wrflag = -1;
175 u32 adapter = hm->h.adapter_index;
176
177 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) {
178 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
179 HPI_ADAPTER_OPEN,
180 HPI_ERROR_BAD_ADAPTER_NUMBER);
181
182 uncopied_bytes =
183 copy_to_user(puhr, hr, sizeof(hr->h));
184 if (uncopied_bytes)
185 err = -EFAULT;
186 else
187 err = 0;
188 goto out;
189 }
190
191 if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
192 err = -EINTR;
193 goto out;
194 }
195
196 /* Dig out any pointers embedded in the message. */
197 switch (hm->h.function) {
198 case HPI_OSTREAM_WRITE:
199 case HPI_ISTREAM_READ:{
200 /* Yes, sparse, this is correct. */
201 ptr = (u16 __user *)hm->m0.u.d.u.data.pb_data;
202 size = hm->m0.u.d.u.data.data_size;
203
204 /* Allocate buffer according to application request.
205 ?Is it better to alloc/free for the duration
206 of the transaction?
207 */
208 if (pa->buffer_size < size) {
209 HPI_DEBUG_LOG(DEBUG,
210 "realloc adapter %d stream "
211 "buffer from %zd to %d\n",
212 hm->h.adapter_index,
213 pa->buffer_size, size);
214 if (pa->p_buffer) {
215 pa->buffer_size = 0;
216 vfree(pa->p_buffer);
217 }
218 pa->p_buffer = vmalloc(size);
219 if (pa->p_buffer)
220 pa->buffer_size = size;
221 else {
222 HPI_DEBUG_LOG(ERROR,
223 "HPI could not allocate "
224 "stream buffer size %d\n",
225 size);
226
227 mutex_unlock(&adapters
228 [adapter].mutex);
229 err = -EINVAL;
230 goto out;
231 }
232 }
233
234 hm->m0.u.d.u.data.pb_data = pa->p_buffer;
235 if (hm->h.function == HPI_ISTREAM_READ)
236 /* from card, WRITE to user mem */
237 wrflag = 1;
238 else
239 wrflag = 0;
240 break;
241 }
242
243 default:
244 size = 0;
245 break;
246 }
247
248 if (size && (wrflag == 0)) {
249 uncopied_bytes =
250 copy_from_user(pa->p_buffer, ptr, size);
251 if (uncopied_bytes)
252 HPI_DEBUG_LOG(WARNING,
253 "missed %d of %d "
254 "bytes from user\n", uncopied_bytes,
255 size);
256 }
257
258 hpi_send_recv_f(&hm->m0, &hr->r0, file);
259
260 if (size && (wrflag == 1)) {
261 uncopied_bytes =
262 copy_to_user(ptr, pa->p_buffer, size);
263 if (uncopied_bytes)
264 HPI_DEBUG_LOG(WARNING,
265 "missed %d of %d " "bytes to user\n",
266 uncopied_bytes, size);
267 }
268
269 mutex_unlock(&adapters[adapter].mutex);
270 }
271
272 /* on return response size must be set */
273 /*printk(KERN_INFO "response size %d\n", hr->h.wSize); */
274
275 if (!hr->h.size) {
276 HPI_DEBUG_LOG(ERROR, "response zero size\n");
277 err = -EFAULT;
278 goto out;
279 }
280
281 if (hr->h.size > res_max_size) {
282 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
283 res_max_size);
284 /*HPI_DEBUG_MESSAGE(ERROR, hm); */
285 err = -EFAULT;
286 goto out;
287 }
288
289 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
290 if (uncopied_bytes) {
291 HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
292 err = -EFAULT;
293 goto out;
294 }
295
296out:
297 kfree(hm);
298 kfree(hr);
299 return err;
300}
301
302int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
303 const struct pci_device_id *pci_id)
304{
305 int err, idx, nm;
306 unsigned int memlen;
307 struct hpi_message hm;
308 struct hpi_response hr;
309 struct hpi_adapter adapter;
310 struct hpi_pci pci;
311
312 memset(&adapter, 0, sizeof(adapter));
313
314 printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n",
315 pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor,
316 pci_dev->subsystem_device, pci_dev->devfn);
317
318 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
319 HPI_SUBSYS_CREATE_ADAPTER);
320 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
321 HPI_ERROR_PROCESSING_MESSAGE);
322
323 hm.adapter_index = -1; /* an invalid index */
324
325 /* fill in HPI_PCI information from kernel provided information */
326 adapter.pci = pci_dev;
327
328 nm = HPI_MAX_ADAPTER_MEM_SPACES;
329
330 for (idx = 0; idx < nm; idx++) {
331 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n",
332 idx, pci_dev->resource[idx].name,
333 (unsigned long long)pci_resource_start(pci_dev, idx),
334 (unsigned long long)pci_resource_end(pci_dev, idx),
335 (unsigned long long)pci_resource_flags(pci_dev, idx));
336
337 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
338 memlen = pci_resource_len(pci_dev, idx);
339 adapter.ap_remapped_mem_base[idx] =
340 ioremap(pci_resource_start(pci_dev, idx),
341 memlen);
342 if (!adapter.ap_remapped_mem_base[idx]) {
343 HPI_DEBUG_LOG(ERROR,
344 "ioremap failed, aborting\n");
345 /* unmap previously mapped pci mem space */
346 goto err;
347 }
348 }
349
350 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
351 }
352
353 /* could replace Pci with direct pointer to pci_dev for linux
354 Instead wrap accessor functions for IDs etc.
355 Would it work for windows?
356 */
357 pci.bus_number = pci_dev->bus->number;
358 pci.vendor_id = (u16)pci_dev->vendor;
359 pci.device_id = (u16)pci_dev->device;
360 pci.subsys_vendor_id = (u16)(pci_dev->subsystem_vendor & 0xffff);
361 pci.subsys_device_id = (u16)(pci_dev->subsystem_device & 0xffff);
362 pci.device_number = pci_dev->devfn;
363 pci.interrupt = pci_dev->irq;
364 pci.p_os_data = pci_dev;
365
366 hm.u.s.resource.bus_type = HPI_BUS_PCI;
367 hm.u.s.resource.r.pci = &pci;
368
369 /* call CreateAdapterObject on the relevant hpi module */
370 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
371 if (hr.error)
372 goto err;
373
374 if (prealloc_stream_buf) {
375 adapter.p_buffer = vmalloc(prealloc_stream_buf);
376 if (!adapter.p_buffer) {
377 HPI_DEBUG_LOG(ERROR,
378 "HPI could not allocate "
379 "kernel buffer size %d\n",
380 prealloc_stream_buf);
381 goto err;
382 }
383 }
384
385 adapter.index = hr.u.s.adapter_index;
386 adapter.type = hr.u.s.aw_adapter_list[adapter.index];
387 hm.adapter_index = adapter.index;
388
389 err = hpi_adapter_open(NULL, adapter.index);
390 if (err)
391 goto err;
392
393 adapter.snd_card_asihpi = NULL;
394 /* WARNING can't init mutex in 'adapter'
395 * and then copy it to adapters[] ?!?!
396 */
397 adapters[hr.u.s.adapter_index] = adapter;
398 mutex_init(&adapters[adapter.index].mutex);
399 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
400
401 printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n",
402 adapter.type, adapter.index);
403
404 return 0;
405
406err:
407 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
408 if (adapter.ap_remapped_mem_base[idx]) {
409 iounmap(adapter.ap_remapped_mem_base[idx]);
410 adapter.ap_remapped_mem_base[idx] = NULL;
411 }
412 }
413
414 if (adapter.p_buffer) {
415 adapter.buffer_size = 0;
416 vfree(adapter.p_buffer);
417 }
418
419 HPI_DEBUG_LOG(ERROR, "adapter_probe failed\n");
420 return -ENODEV;
421}
422
423void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
424{
425 int idx;
426 struct hpi_message hm;
427 struct hpi_response hr;
428 struct hpi_adapter *pa;
429 pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev);
430
431 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
432 HPI_SUBSYS_DELETE_ADAPTER);
433 hm.adapter_index = pa->index;
434 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
435
436 /* unmap PCI memory space, mapped during device init. */
437 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
438 if (pa->ap_remapped_mem_base[idx]) {
439 iounmap(pa->ap_remapped_mem_base[idx]);
440 pa->ap_remapped_mem_base[idx] = NULL;
441 }
442 }
443
444 if (pa->p_buffer) {
445 pa->buffer_size = 0;
446 vfree(pa->p_buffer);
447 }
448
449 pci_set_drvdata(pci_dev, NULL);
450 /*
451 printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x),"
452 " HPI index # %d, removed.\n",
453 pci_dev->vendor, pci_dev->device,
454 pci_dev->subsystem_vendor,
455 pci_dev->subsystem_device, pci_dev->devfn,
456 pa->index);
457 */
458}
459
460void __init asihpi_init(void)
461{
462 struct hpi_message hm;
463 struct hpi_response hr;
464
465 memset(adapters, 0, sizeof(adapters));
466
467 printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n",
468 HPI_VER_MAJOR(HPI_VER), HPI_VER_MINOR(HPI_VER),
469 HPI_VER_RELEASE(HPI_VER));
470
471 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
472 HPI_SUBSYS_DRIVER_LOAD);
473 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
474}
475
476void asihpi_exit(void)
477{
478 struct hpi_message hm;
479 struct hpi_response hr;
480
481 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
482 HPI_SUBSYS_DRIVER_UNLOAD);
483 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
484}
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
new file mode 100644
index 000000000000..847f72f03fe1
--- /dev/null
+++ b/sound/pci/asihpi/hpioctl.h
@@ -0,0 +1,38 @@
1/*******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Linux HPI ioctl, and shared module init functions
20*******************************************************************************/
21
22int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
23 const struct pci_device_id *pci_id);
24void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev);
25void __init asihpi_init(void);
26void __exit asihpi_exit(void);
27
28int asihpi_hpi_release(struct file *file);
29
30long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
31
32/* This is called from hpifunc.c functions, called by ALSA
33 * (or other kernel process) In this case there is no file descriptor
34 * available for the message cache code
35 */
36void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
37
38#define HOWNER_KERNEL ((void *)-1)
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
new file mode 100644
index 000000000000..de615cfdb950
--- /dev/null
+++ b/sound/pci/asihpi/hpios.c
@@ -0,0 +1,114 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI Operating System function implementation for Linux
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23#define SOURCEFILE_NAME "hpios.c"
24#include "hpi_internal.h"
25#include "hpidebug.h"
26#include <linux/delay.h>
27#include <linux/sched.h>
28
29void hpios_delay_micro_seconds(u32 num_micro_sec)
30{
31 if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
32 /* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
33 schedule_timeout_uninterruptible(usecs_to_jiffies
34 (num_micro_sec));
35 } else if (num_micro_sec <= 2000)
36 udelay(num_micro_sec);
37 else
38 mdelay(num_micro_sec / 1000);
39
40}
41
42void hpios_locked_mem_init(void)
43{
44}
45
46/** Allocated an area of locked memory for bus master DMA operations.
47
48On error, return -ENOMEM, and *pMemArea.size = 0
49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
51 struct pci_dev *pdev)
52{
53 /*?? any benefit in using managed dmam_alloc_coherent? */
54 p_mem_area->vaddr =
55 dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
56 GFP_DMA32 | GFP_KERNEL);
57
58 if (p_mem_area->vaddr) {
59 HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
60 size, (unsigned int)p_mem_area->dma_handle,
61 p_mem_area->vaddr);
62 p_mem_area->pdev = &pdev->dev;
63 p_mem_area->size = size;
64 return 0;
65 } else {
66 HPI_DEBUG_LOG(WARNING,
67 "failed to allocate %d bytes locked memory\n", size);
68 p_mem_area->size = 0;
69 return -ENOMEM;
70 }
71}
72
73u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
74{
75 if (p_mem_area->size) {
76 dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
77 p_mem_area->vaddr, p_mem_area->dma_handle);
78 HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
79 (unsigned long)p_mem_area->size,
80 (unsigned int)p_mem_area->dma_handle,
81 p_mem_area->vaddr);
82 p_mem_area->size = 0;
83 return 0;
84 } else {
85 return 1;
86 }
87}
88
89void hpios_locked_mem_free_all(void)
90{
91}
92
93void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx,
94 unsigned int length)
95{
96 HPI_DEBUG_LOG(DEBUG, "mapping %d %s %08llx-%08llx %04llx len 0x%x\n",
97 idx, pci_dev->resource[idx].name,
98 (unsigned long long)pci_resource_start(pci_dev, idx),
99 (unsigned long long)pci_resource_end(pci_dev, idx),
100 (unsigned long long)pci_resource_flags(pci_dev, idx), length);
101
102 if (!(pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM)) {
103 HPI_DEBUG_LOG(ERROR, "not an io memory resource\n");
104 return NULL;
105 }
106
107 if (length > pci_resource_len(pci_dev, idx)) {
108 HPI_DEBUG_LOG(ERROR, "resource too small for requested %d \n",
109 length);
110 return NULL;
111 }
112
113 return ioremap(pci_resource_start(pci_dev, idx), length);
114}
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
new file mode 100644
index 000000000000..a62c3f1e5f09
--- /dev/null
+++ b/sound/pci/asihpi/hpios.h
@@ -0,0 +1,178 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI Operating System Specific macros for Linux Kernel driver
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23#ifndef _HPIOS_H_
24#define _HPIOS_H_
25
26#undef HPI_OS_LINUX_KERNEL
27#define HPI_OS_LINUX_KERNEL
28
29#define HPI_OS_DEFINED
30#define HPI_KERNEL_MODE
31
32#define HPI_REASSIGN_DUPLICATE_ADAPTER_IDX
33
34#include <linux/io.h>
35#include <asm/system.h>
36#include <linux/ioctl.h>
37#include <linux/kernel.h>
38#include <linux/string.h>
39#include <linux/device.h>
40#include <linux/firmware.h>
41#include <linux/interrupt.h>
42#include <linux/pci.h>
43
44#define HPI_NO_OS_FILE_OPS
45
46#ifdef CONFIG_64BIT
47#define HPI64BIT
48#endif
49
50/** Details of a memory area allocated with pci_alloc_consistent
51Need all info for parameters to pci_free_consistent
52*/
53struct consistent_dma_area {
54 struct device *pdev;
55 /* looks like dma-mapping dma_devres ?! */
56 size_t size;
57 void *vaddr;
58 dma_addr_t dma_handle;
59};
60
61static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
62 *locked_mem_handle, u32 *p_physical_addr)
63{
64 *p_physical_addr = locked_mem_handle->dma_handle;
65 return 0;
66}
67
68static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
69 *locked_mem_handle, void **pp_virtual_addr)
70{
71 *pp_virtual_addr = locked_mem_handle->vaddr;
72 return 0;
73}
74
75static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
76 *locked_mem_handle)
77{
78 return locked_mem_handle->size != 0;
79}
80
81struct hpi_ioctl_linux {
82 void __user *phm;
83 void __user *phr;
84};
85
86/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
87 and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is ununsed command
88*/
89#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
90
91#define HPI_DEBUG_FLAG_ERROR KERN_ERR
92#define HPI_DEBUG_FLAG_WARNING KERN_WARNING
93#define HPI_DEBUG_FLAG_NOTICE KERN_NOTICE
94#define HPI_DEBUG_FLAG_INFO KERN_INFO
95#define HPI_DEBUG_FLAG_DEBUG KERN_DEBUG
96#define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG /* kernel has no verbose */
97
98#include <linux/spinlock.h>
99
100#define HPI_LOCKING
101
102struct hpios_spinlock {
103 spinlock_t lock; /* SEE hpios_spinlock */
104 int lock_context;
105};
106
107/* The reason for all this evilness is that ALSA calls some of a drivers
108 * operators in atomic context, and some not. But all our functions channel
109 * through the HPI_Message conduit, so we can't handle the different context
110 * per function
111 */
112#define IN_LOCK_BH 1
113#define IN_LOCK_IRQ 0
114static inline void cond_lock(struct hpios_spinlock *l)
115{
116 if (irqs_disabled()) {
117 /* NO bh or isr can execute on this processor,
118 so ordinary lock will do
119 */
120 spin_lock(&((l)->lock));
121 l->lock_context = IN_LOCK_IRQ;
122 } else {
123 spin_lock_bh(&((l)->lock));
124 l->lock_context = IN_LOCK_BH;
125 }
126}
127
128static inline void cond_unlock(struct hpios_spinlock *l)
129{
130 if (l->lock_context == IN_LOCK_BH)
131 spin_unlock_bh(&((l)->lock));
132 else
133 spin_unlock(&((l)->lock));
134}
135
136#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
137#define hpios_msgxlock_lock(obj) cond_lock(obj)
138#define hpios_msgxlock_un_lock(obj) cond_unlock(obj)
139
140#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
141#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
142#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock)
143
144#ifdef CONFIG_SND_DEBUG
145#define HPI_DEBUG
146#endif
147
148#define HPI_ALIST_LOCKING
149#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
150#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
151#define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock))
152
153struct hpi_adapter {
154 /* mutex prevents contention for one card
155 between multiple user programs (via ioctl) */
156 struct mutex mutex;
157 u16 index;
158 u16 type;
159
160 /* ALSA card structure */
161 void *snd_card_asihpi;
162
163 char *p_buffer;
164 size_t buffer_size;
165 struct pci_dev *pci;
166 void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
167};
168
169static inline void hpios_unmap_io(void __iomem *addr,
170 unsigned long size)
171{
172 iounmap(addr);
173}
174
175void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx,
176 unsigned int length);
177
178#endif
diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h
new file mode 100644
index 000000000000..bb30868ce1a3
--- /dev/null
+++ b/sound/pci/asihpi/hpipcida.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Array initializer for PCI card IDs
20
21(C) Copyright AudioScience Inc. 1998-2003
22*******************************************************************************/
23
24/*NOTE: when adding new lines to this header file
25 they MUST be grouped by HPI entry point.
26*/
27
28{
29HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
30 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
31 (kernel_ulong_t) HPI_6205}
32, {
33HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
34 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
35 (kernel_ulong_t) HPI_6000}
36, {
370}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecaea9fb48ec..23a58f0d6cb9 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -104,6 +104,7 @@
104#include <linux/gameport.h> 104#include <linux/gameport.h>
105#include <linux/moduleparam.h> 105#include <linux/moduleparam.h>
106#include <linux/mutex.h> 106#include <linux/mutex.h>
107#include <linux/input.h>
107 108
108#include <sound/core.h> 109#include <sound/core.h>
109#include <sound/pcm.h> 110#include <sound/pcm.h>
@@ -517,14 +518,9 @@ struct es1968 {
517 518
518 /* ALSA Stuff */ 519 /* ALSA Stuff */
519 struct snd_ac97 *ac97; 520 struct snd_ac97 *ac97;
520 struct snd_kcontrol *master_switch; /* for h/w volume control */
521 struct snd_kcontrol *master_volume;
522
523 struct snd_rawmidi *rmidi; 521 struct snd_rawmidi *rmidi;
524 522
525 spinlock_t reg_lock; 523 spinlock_t reg_lock;
526 spinlock_t ac97_lock;
527 struct tasklet_struct hwvol_tq;
528 unsigned int in_suspend; 524 unsigned int in_suspend;
529 525
530 /* Maestro Stuff */ 526 /* Maestro Stuff */
@@ -547,6 +543,16 @@ struct es1968 {
547#ifdef SUPPORT_JOYSTICK 543#ifdef SUPPORT_JOYSTICK
548 struct gameport *gameport; 544 struct gameport *gameport;
549#endif 545#endif
546
547#ifdef CONFIG_SND_ES1968_INPUT
548 struct input_dev *input_dev;
549 char phys[64]; /* physical device path */
550#else
551 struct snd_kcontrol *master_switch; /* for h/w volume control */
552 struct snd_kcontrol *master_volume;
553 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq;
555#endif
550}; 556};
551 557
552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -632,28 +638,38 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
632static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 638static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
633{ 639{
634 struct es1968 *chip = ac97->private_data; 640 struct es1968 *chip = ac97->private_data;
641#ifndef CONFIG_SND_ES1968_INPUT
635 unsigned long flags; 642 unsigned long flags;
643#endif
636 644
637 snd_es1968_ac97_wait(chip); 645 snd_es1968_ac97_wait(chip);
638 646
639 /* Write the bus */ 647 /* Write the bus */
648#ifndef CONFIG_SND_ES1968_INPUT
640 spin_lock_irqsave(&chip->ac97_lock, flags); 649 spin_lock_irqsave(&chip->ac97_lock, flags);
650#endif
641 outw(val, chip->io_port + ESM_AC97_DATA); 651 outw(val, chip->io_port + ESM_AC97_DATA);
642 /*msleep(1);*/ 652 /*msleep(1);*/
643 outb(reg, chip->io_port + ESM_AC97_INDEX); 653 outb(reg, chip->io_port + ESM_AC97_INDEX);
644 /*msleep(1);*/ 654 /*msleep(1);*/
655#ifndef CONFIG_SND_ES1968_INPUT
645 spin_unlock_irqrestore(&chip->ac97_lock, flags); 656 spin_unlock_irqrestore(&chip->ac97_lock, flags);
657#endif
646} 658}
647 659
648static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 660static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
649{ 661{
650 u16 data = 0; 662 u16 data = 0;
651 struct es1968 *chip = ac97->private_data; 663 struct es1968 *chip = ac97->private_data;
664#ifndef CONFIG_SND_ES1968_INPUT
652 unsigned long flags; 665 unsigned long flags;
666#endif
653 667
654 snd_es1968_ac97_wait(chip); 668 snd_es1968_ac97_wait(chip);
655 669
670#ifndef CONFIG_SND_ES1968_INPUT
656 spin_lock_irqsave(&chip->ac97_lock, flags); 671 spin_lock_irqsave(&chip->ac97_lock, flags);
672#endif
657 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX); 673 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
658 /*msleep(1);*/ 674 /*msleep(1);*/
659 675
@@ -661,7 +677,9 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
661 data = inw(chip->io_port + ESM_AC97_DATA); 677 data = inw(chip->io_port + ESM_AC97_DATA);
662 /*msleep(1);*/ 678 /*msleep(1);*/
663 } 679 }
680#ifndef CONFIG_SND_ES1968_INPUT
664 spin_unlock_irqrestore(&chip->ac97_lock, flags); 681 spin_unlock_irqrestore(&chip->ac97_lock, flags);
682#endif
665 683
666 return data; 684 return data;
667} 685}
@@ -1874,13 +1892,17 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
1874 } 1892 }
1875} 1893}
1876 1894
1877/* 1895/* The hardware volume works by incrementing / decrementing 2 counters
1878 */ 1896 (without wrap around) in response to volume button presses and then
1897 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1898 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1879static void es1968_update_hw_volume(unsigned long private_data) 1899static void es1968_update_hw_volume(unsigned long private_data)
1880{ 1900{
1881 struct es1968 *chip = (struct es1968 *) private_data; 1901 struct es1968 *chip = (struct es1968 *) private_data;
1882 int x, val; 1902 int x, val;
1903#ifndef CONFIG_SND_ES1968_INPUT
1883 unsigned long flags; 1904 unsigned long flags;
1905#endif
1884 1906
1885 /* Figure out which volume control button was pushed, 1907 /* Figure out which volume control button was pushed,
1886 based on differences from the default register 1908 based on differences from the default register
@@ -1895,6 +1917,7 @@ static void es1968_update_hw_volume(unsigned long private_data)
1895 if (chip->in_suspend) 1917 if (chip->in_suspend)
1896 return; 1918 return;
1897 1919
1920#ifndef CONFIG_SND_ES1968_INPUT
1898 if (! chip->master_switch || ! chip->master_volume) 1921 if (! chip->master_switch || ! chip->master_volume)
1899 return; 1922 return;
1900 1923
@@ -1937,6 +1960,35 @@ static void es1968_update_hw_volume(unsigned long private_data)
1937 break; 1960 break;
1938 } 1961 }
1939 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1962 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1963#else
1964 if (!chip->input_dev)
1965 return;
1966
1967 val = 0;
1968 switch (x) {
1969 case 0x88:
1970 /* The counters have not changed, yet we've received a HV
1971 interrupt. According to tests run by various people this
1972 happens when pressing the mute button. */
1973 val = KEY_MUTE;
1974 break;
1975 case 0xaa:
1976 /* counters increased by 1 -> volume up */
1977 val = KEY_VOLUMEUP;
1978 break;
1979 case 0x66:
1980 /* counters decreased by 1 -> volume down */
1981 val = KEY_VOLUMEDOWN;
1982 break;
1983 }
1984
1985 if (val) {
1986 input_report_key(chip->input_dev, val, 1);
1987 input_sync(chip->input_dev);
1988 input_report_key(chip->input_dev, val, 0);
1989 input_sync(chip->input_dev);
1990 }
1991#endif
1940} 1992}
1941 1993
1942/* 1994/*
@@ -1953,7 +2005,11 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 2005 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1954 2006
1955 if (event & ESM_HWVOL_IRQ) 2007 if (event & ESM_HWVOL_IRQ)
2008#ifdef CONFIG_SND_ES1968_INPUT
2009 es1968_update_hw_volume((unsigned long)chip);
2010#else
1956 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */ 2011 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
2012#endif
1957 2013
1958 /* else ack 'em all, i imagine */ 2014 /* else ack 'em all, i imagine */
1959 outb(0xFF, chip->io_port + 0x1A); 2015 outb(0xFF, chip->io_port + 0x1A);
@@ -1993,7 +2049,9 @@ snd_es1968_mixer(struct es1968 *chip)
1993{ 2049{
1994 struct snd_ac97_bus *pbus; 2050 struct snd_ac97_bus *pbus;
1995 struct snd_ac97_template ac97; 2051 struct snd_ac97_template ac97;
2052#ifndef CONFIG_SND_ES1968_INPUT
1996 struct snd_ctl_elem_id elem_id; 2053 struct snd_ctl_elem_id elem_id;
2054#endif
1997 int err; 2055 int err;
1998 static struct snd_ac97_bus_ops ops = { 2056 static struct snd_ac97_bus_ops ops = {
1999 .write = snd_es1968_ac97_write, 2057 .write = snd_es1968_ac97_write,
@@ -2009,6 +2067,7 @@ snd_es1968_mixer(struct es1968 *chip)
2009 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0) 2067 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
2010 return err; 2068 return err;
2011 2069
2070#ifndef CONFIG_SND_ES1968_INPUT
2012 /* attach master switch / volumes for h/w volume control */ 2071 /* attach master switch / volumes for h/w volume control */
2013 memset(&elem_id, 0, sizeof(elem_id)); 2072 memset(&elem_id, 0, sizeof(elem_id));
2014 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2073 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2018,6 +2077,7 @@ snd_es1968_mixer(struct es1968 *chip)
2018 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2077 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2019 strcpy(elem_id.name, "Master Playback Volume"); 2078 strcpy(elem_id.name, "Master Playback Volume");
2020 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); 2079 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2080#endif
2021 2081
2022 return 0; 2082 return 0;
2023} 2083}
@@ -2341,6 +2401,7 @@ static void snd_es1968_start_irq(struct es1968 *chip)
2341 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME; 2401 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
2342 if (chip->rmidi) 2402 if (chip->rmidi)
2343 w |= ESM_HIRQ_MPU401; 2403 w |= ESM_HIRQ_MPU401;
2404 outb(w, chip->io_port + 0x1A);
2344 outw(w, chip->io_port + ESM_PORT_HOST_IRQ); 2405 outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
2345} 2406}
2346 2407
@@ -2474,8 +2535,49 @@ static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { ret
2474static inline void snd_es1968_free_gameport(struct es1968 *chip) { } 2535static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
2475#endif 2536#endif
2476 2537
2538#ifdef CONFIG_SND_ES1968_INPUT
2539static int __devinit snd_es1968_input_register(struct es1968 *chip)
2540{
2541 struct input_dev *input_dev;
2542 int err;
2543
2544 input_dev = input_allocate_device();
2545 if (!input_dev)
2546 return -ENOMEM;
2547
2548 snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2549 pci_name(chip->pci));
2550
2551 input_dev->name = chip->card->driver;
2552 input_dev->phys = chip->phys;
2553 input_dev->id.bustype = BUS_PCI;
2554 input_dev->id.vendor = chip->pci->vendor;
2555 input_dev->id.product = chip->pci->device;
2556 input_dev->dev.parent = &chip->pci->dev;
2557
2558 __set_bit(EV_KEY, input_dev->evbit);
2559 __set_bit(KEY_MUTE, input_dev->keybit);
2560 __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2561 __set_bit(KEY_VOLUMEUP, input_dev->keybit);
2562
2563 err = input_register_device(input_dev);
2564 if (err) {
2565 input_free_device(input_dev);
2566 return err;
2567 }
2568
2569 chip->input_dev = input_dev;
2570 return 0;
2571}
2572#endif /* CONFIG_SND_ES1968_INPUT */
2573
2477static int snd_es1968_free(struct es1968 *chip) 2574static int snd_es1968_free(struct es1968 *chip)
2478{ 2575{
2576#ifdef CONFIG_SND_ES1968_INPUT
2577 if (chip->input_dev)
2578 input_unregister_device(chip->input_dev);
2579#endif
2580
2479 if (chip->io_port) { 2581 if (chip->io_port) {
2480 if (chip->irq >= 0) 2582 if (chip->irq >= 0)
2481 synchronize_irq(chip->irq); 2583 synchronize_irq(chip->irq);
@@ -2486,8 +2588,6 @@ static int snd_es1968_free(struct es1968 *chip)
2486 if (chip->irq >= 0) 2588 if (chip->irq >= 0)
2487 free_irq(chip->irq, chip); 2589 free_irq(chip->irq, chip);
2488 snd_es1968_free_gameport(chip); 2590 snd_es1968_free_gameport(chip);
2489 chip->master_switch = NULL;
2490 chip->master_volume = NULL;
2491 pci_release_regions(chip->pci); 2591 pci_release_regions(chip->pci);
2492 pci_disable_device(chip->pci); 2592 pci_disable_device(chip->pci);
2493 kfree(chip); 2593 kfree(chip);
@@ -2558,9 +2658,11 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2558 spin_lock_init(&chip->substream_lock); 2658 spin_lock_init(&chip->substream_lock);
2559 INIT_LIST_HEAD(&chip->buf_list); 2659 INIT_LIST_HEAD(&chip->buf_list);
2560 INIT_LIST_HEAD(&chip->substream_list); 2660 INIT_LIST_HEAD(&chip->substream_list);
2561 spin_lock_init(&chip->ac97_lock);
2562 mutex_init(&chip->memory_mutex); 2661 mutex_init(&chip->memory_mutex);
2662#ifndef CONFIG_SND_ES1968_INPUT
2663 spin_lock_init(&chip->ac97_lock);
2563 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); 2664 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
2665#endif
2564 chip->card = card; 2666 chip->card = card;
2565 chip->pci = pci; 2667 chip->pci = pci;
2566 chip->irq = -1; 2668 chip->irq = -1;
@@ -2713,6 +2815,13 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2713 2815
2714 snd_es1968_create_gameport(chip, dev); 2816 snd_es1968_create_gameport(chip, dev);
2715 2817
2818#ifdef CONFIG_SND_ES1968_INPUT
2819 err = snd_es1968_input_register(chip);
2820 if (err)
2821 snd_printk(KERN_WARNING "Input device registration "
2822 "failed with error %i", err);
2823#endif
2824
2716 snd_es1968_start_irq(chip); 2825 snd_es1968_start_irq(chip);
2717 2826
2718 chip->clock = clock[dev]; 2827 chip->clock = clock[dev];
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index b56e33676780..3c40d726b46e 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,6 +41,7 @@
41#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/firmware.h> 43#include <linux/firmware.h>
44#include <linux/input.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/info.h> 46#include <sound/info.h>
46#include <sound/control.h> 47#include <sound/control.h>
@@ -844,11 +845,17 @@ struct snd_m3 {
844 struct m3_dma *substreams; 845 struct m3_dma *substreams;
845 846
846 spinlock_t reg_lock; 847 spinlock_t reg_lock;
847 spinlock_t ac97_lock;
848 848
849#ifdef CONFIG_SND_MAESTRO3_INPUT
850 struct input_dev *input_dev;
851 char phys[64]; /* physical device path */
852#else
853 spinlock_t ac97_lock;
849 struct snd_kcontrol *master_switch; 854 struct snd_kcontrol *master_switch;
850 struct snd_kcontrol *master_volume; 855 struct snd_kcontrol *master_volume;
851 struct tasklet_struct hwvol_tq; 856 struct tasklet_struct hwvol_tq;
857#endif
858
852 unsigned int in_suspend; 859 unsigned int in_suspend;
853 860
854#ifdef CONFIG_PM 861#ifdef CONFIG_PM
@@ -1598,18 +1605,32 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
1598 } 1605 }
1599} 1606}
1600 1607
1608/* The m3's hardware volume works by incrementing / decrementing 2 counters
1609 (without wrap around) in response to volume button presses and then
1610 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1611 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1601static void snd_m3_update_hw_volume(unsigned long private_data) 1612static void snd_m3_update_hw_volume(unsigned long private_data)
1602{ 1613{
1603 struct snd_m3 *chip = (struct snd_m3 *) private_data; 1614 struct snd_m3 *chip = (struct snd_m3 *) private_data;
1604 int x, val; 1615 int x, val;
1616#ifndef CONFIG_SND_MAESTRO3_INPUT
1605 unsigned long flags; 1617 unsigned long flags;
1618#endif
1606 1619
1607 /* Figure out which volume control button was pushed, 1620 /* Figure out which volume control button was pushed,
1608 based on differences from the default register 1621 based on differences from the default register
1609 values. */ 1622 values. */
1610 x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee; 1623 x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee;
1611 1624
1612 /* Reset the volume control registers. */ 1625 /* Reset the volume counters to 4. Tests on the allegro integrated
1626 into a Compaq N600C laptop, have revealed that:
1627 1) Writing any value will result in the 2 counters being reset to
1628 4 so writing 0x88 is not strictly necessary
1629 2) Writing to any of the 4 involved registers will reset all 4
1630 of them (and reading them always returns the same value for all
1631 of them)
1632 It could be that a maestro deviates from this, so leave the code
1633 as is. */
1613 outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE); 1634 outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE);
1614 outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE); 1635 outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE);
1615 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); 1636 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
@@ -1620,6 +1641,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1620 if (chip->in_suspend) 1641 if (chip->in_suspend)
1621 return; 1642 return;
1622 1643
1644#ifndef CONFIG_SND_MAESTRO3_INPUT
1623 if (!chip->master_switch || !chip->master_volume) 1645 if (!chip->master_switch || !chip->master_volume)
1624 return; 1646 return;
1625 1647
@@ -1629,7 +1651,9 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1629 val = chip->ac97->regs[AC97_MASTER_VOL]; 1651 val = chip->ac97->regs[AC97_MASTER_VOL];
1630 switch (x) { 1652 switch (x) {
1631 case 0x88: 1653 case 0x88:
1632 /* mute */ 1654 /* The counters have not changed, yet we've received a HV
1655 interrupt. According to tests run by various people this
1656 happens when pressing the mute button. */
1633 val ^= 0x8000; 1657 val ^= 0x8000;
1634 chip->ac97->regs[AC97_MASTER_VOL] = val; 1658 chip->ac97->regs[AC97_MASTER_VOL] = val;
1635 outw(val, chip->iobase + CODEC_DATA); 1659 outw(val, chip->iobase + CODEC_DATA);
@@ -1638,7 +1662,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1638 &chip->master_switch->id); 1662 &chip->master_switch->id);
1639 break; 1663 break;
1640 case 0xaa: 1664 case 0xaa:
1641 /* volume up */ 1665 /* counters increased by 1 -> volume up */
1642 if ((val & 0x7f) > 0) 1666 if ((val & 0x7f) > 0)
1643 val--; 1667 val--;
1644 if ((val & 0x7f00) > 0) 1668 if ((val & 0x7f00) > 0)
@@ -1650,7 +1674,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1650 &chip->master_volume->id); 1674 &chip->master_volume->id);
1651 break; 1675 break;
1652 case 0x66: 1676 case 0x66:
1653 /* volume down */ 1677 /* counters decreased by 1 -> volume down */
1654 if ((val & 0x7f) < 0x1f) 1678 if ((val & 0x7f) < 0x1f)
1655 val++; 1679 val++;
1656 if ((val & 0x7f00) < 0x1f00) 1680 if ((val & 0x7f00) < 0x1f00)
@@ -1663,6 +1687,35 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1663 break; 1687 break;
1664 } 1688 }
1665 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1689 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1690#else
1691 if (!chip->input_dev)
1692 return;
1693
1694 val = 0;
1695 switch (x) {
1696 case 0x88:
1697 /* The counters have not changed, yet we've received a HV
1698 interrupt. According to tests run by various people this
1699 happens when pressing the mute button. */
1700 val = KEY_MUTE;
1701 break;
1702 case 0xaa:
1703 /* counters increased by 1 -> volume up */
1704 val = KEY_VOLUMEUP;
1705 break;
1706 case 0x66:
1707 /* counters decreased by 1 -> volume down */
1708 val = KEY_VOLUMEDOWN;
1709 break;
1710 }
1711
1712 if (val) {
1713 input_report_key(chip->input_dev, val, 1);
1714 input_sync(chip->input_dev);
1715 input_report_key(chip->input_dev, val, 0);
1716 input_sync(chip->input_dev);
1717 }
1718#endif
1666} 1719}
1667 1720
1668static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) 1721static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
@@ -1677,7 +1730,11 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1677 return IRQ_NONE; 1730 return IRQ_NONE;
1678 1731
1679 if (status & HV_INT_PENDING) 1732 if (status & HV_INT_PENDING)
1733#ifdef CONFIG_SND_MAESTRO3_INPUT
1734 snd_m3_update_hw_volume((unsigned long)chip);
1735#else
1680 tasklet_schedule(&chip->hwvol_tq); 1736 tasklet_schedule(&chip->hwvol_tq);
1737#endif
1681 1738
1682 /* 1739 /*
1683 * ack an assp int if its running 1740 * ack an assp int if its running
@@ -1943,18 +2000,24 @@ static unsigned short
1943snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 2000snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
1944{ 2001{
1945 struct snd_m3 *chip = ac97->private_data; 2002 struct snd_m3 *chip = ac97->private_data;
2003#ifndef CONFIG_SND_MAESTRO3_INPUT
1946 unsigned long flags; 2004 unsigned long flags;
2005#endif
1947 unsigned short data = 0xffff; 2006 unsigned short data = 0xffff;
1948 2007
1949 if (snd_m3_ac97_wait(chip)) 2008 if (snd_m3_ac97_wait(chip))
1950 goto fail; 2009 goto fail;
2010#ifndef CONFIG_SND_MAESTRO3_INPUT
1951 spin_lock_irqsave(&chip->ac97_lock, flags); 2011 spin_lock_irqsave(&chip->ac97_lock, flags);
2012#endif
1952 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); 2013 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
1953 if (snd_m3_ac97_wait(chip)) 2014 if (snd_m3_ac97_wait(chip))
1954 goto fail_unlock; 2015 goto fail_unlock;
1955 data = snd_m3_inw(chip, CODEC_DATA); 2016 data = snd_m3_inw(chip, CODEC_DATA);
1956fail_unlock: 2017fail_unlock:
2018#ifndef CONFIG_SND_MAESTRO3_INPUT
1957 spin_unlock_irqrestore(&chip->ac97_lock, flags); 2019 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2020#endif
1958fail: 2021fail:
1959 return data; 2022 return data;
1960} 2023}
@@ -1963,14 +2026,20 @@ static void
1963snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 2026snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
1964{ 2027{
1965 struct snd_m3 *chip = ac97->private_data; 2028 struct snd_m3 *chip = ac97->private_data;
2029#ifndef CONFIG_SND_MAESTRO3_INPUT
1966 unsigned long flags; 2030 unsigned long flags;
2031#endif
1967 2032
1968 if (snd_m3_ac97_wait(chip)) 2033 if (snd_m3_ac97_wait(chip))
1969 return; 2034 return;
2035#ifndef CONFIG_SND_MAESTRO3_INPUT
1970 spin_lock_irqsave(&chip->ac97_lock, flags); 2036 spin_lock_irqsave(&chip->ac97_lock, flags);
2037#endif
1971 snd_m3_outw(chip, val, CODEC_DATA); 2038 snd_m3_outw(chip, val, CODEC_DATA);
1972 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); 2039 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
2040#ifndef CONFIG_SND_MAESTRO3_INPUT
1973 spin_unlock_irqrestore(&chip->ac97_lock, flags); 2041 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2042#endif
1974} 2043}
1975 2044
1976 2045
@@ -2077,7 +2146,9 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2077{ 2146{
2078 struct snd_ac97_bus *pbus; 2147 struct snd_ac97_bus *pbus;
2079 struct snd_ac97_template ac97; 2148 struct snd_ac97_template ac97;
2149#ifndef CONFIG_SND_MAESTRO3_INPUT
2080 struct snd_ctl_elem_id elem_id; 2150 struct snd_ctl_elem_id elem_id;
2151#endif
2081 int err; 2152 int err;
2082 static struct snd_ac97_bus_ops ops = { 2153 static struct snd_ac97_bus_ops ops = {
2083 .write = snd_m3_ac97_write, 2154 .write = snd_m3_ac97_write,
@@ -2097,6 +2168,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2097 schedule_timeout_uninterruptible(msecs_to_jiffies(100)); 2168 schedule_timeout_uninterruptible(msecs_to_jiffies(100));
2098 snd_ac97_write(chip->ac97, AC97_PCM, 0); 2169 snd_ac97_write(chip->ac97, AC97_PCM, 0);
2099 2170
2171#ifndef CONFIG_SND_MAESTRO3_INPUT
2100 memset(&elem_id, 0, sizeof(elem_id)); 2172 memset(&elem_id, 0, sizeof(elem_id));
2101 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2173 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2102 strcpy(elem_id.name, "Master Playback Switch"); 2174 strcpy(elem_id.name, "Master Playback Switch");
@@ -2105,6 +2177,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2105 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2177 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2106 strcpy(elem_id.name, "Master Playback Volume"); 2178 strcpy(elem_id.name, "Master Playback Volume");
2107 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); 2179 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2180#endif
2108 2181
2109 return 0; 2182 return 0;
2110} 2183}
@@ -2370,6 +2443,7 @@ snd_m3_enable_ints(struct snd_m3 *chip)
2370 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; 2443 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/;
2371 if (chip->hv_config & HV_CTRL_ENABLE) 2444 if (chip->hv_config & HV_CTRL_ENABLE)
2372 val |= HV_INT_ENABLE; 2445 val |= HV_INT_ENABLE;
2446 outb(val, chip->iobase + HOST_INT_STATUS);
2373 outw(val, io + HOST_INT_CTRL); 2447 outw(val, io + HOST_INT_CTRL);
2374 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, 2448 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
2375 io + ASSP_CONTROL_C); 2449 io + ASSP_CONTROL_C);
@@ -2384,6 +2458,11 @@ static int snd_m3_free(struct snd_m3 *chip)
2384 struct m3_dma *s; 2458 struct m3_dma *s;
2385 int i; 2459 int i;
2386 2460
2461#ifdef CONFIG_SND_MAESTRO3_INPUT
2462 if (chip->input_dev)
2463 input_unregister_device(chip->input_dev);
2464#endif
2465
2387 if (chip->substreams) { 2466 if (chip->substreams) {
2388 spin_lock_irq(&chip->reg_lock); 2467 spin_lock_irq(&chip->reg_lock);
2389 for (i = 0; i < chip->num_substreams; i++) { 2468 for (i = 0; i < chip->num_substreams; i++) {
@@ -2510,6 +2589,41 @@ static int m3_resume(struct pci_dev *pci)
2510} 2589}
2511#endif /* CONFIG_PM */ 2590#endif /* CONFIG_PM */
2512 2591
2592#ifdef CONFIG_SND_MAESTRO3_INPUT
2593static int __devinit snd_m3_input_register(struct snd_m3 *chip)
2594{
2595 struct input_dev *input_dev;
2596 int err;
2597
2598 input_dev = input_allocate_device();
2599 if (!input_dev)
2600 return -ENOMEM;
2601
2602 snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2603 pci_name(chip->pci));
2604
2605 input_dev->name = chip->card->driver;
2606 input_dev->phys = chip->phys;
2607 input_dev->id.bustype = BUS_PCI;
2608 input_dev->id.vendor = chip->pci->vendor;
2609 input_dev->id.product = chip->pci->device;
2610 input_dev->dev.parent = &chip->pci->dev;
2611
2612 __set_bit(EV_KEY, input_dev->evbit);
2613 __set_bit(KEY_MUTE, input_dev->keybit);
2614 __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2615 __set_bit(KEY_VOLUMEUP, input_dev->keybit);
2616
2617 err = input_register_device(input_dev);
2618 if (err) {
2619 input_free_device(input_dev);
2620 return err;
2621 }
2622
2623 chip->input_dev = input_dev;
2624 return 0;
2625}
2626#endif /* CONFIG_INPUT */
2513 2627
2514/* 2628/*
2515 */ 2629 */
@@ -2553,7 +2667,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2553 } 2667 }
2554 2668
2555 spin_lock_init(&chip->reg_lock); 2669 spin_lock_init(&chip->reg_lock);
2670#ifndef CONFIG_SND_MAESTRO3_INPUT
2556 spin_lock_init(&chip->ac97_lock); 2671 spin_lock_init(&chip->ac97_lock);
2672#endif
2557 2673
2558 switch (pci->device) { 2674 switch (pci->device) {
2559 case PCI_DEVICE_ID_ESS_ALLEGRO: 2675 case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2636,7 +2752,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2636 2752
2637 snd_m3_hv_init(chip); 2753 snd_m3_hv_init(chip);
2638 2754
2755#ifndef CONFIG_SND_MAESTRO3_INPUT
2639 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); 2756 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
2757#endif
2640 2758
2641 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, 2759 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
2642 card->driver, chip)) { 2760 card->driver, chip)) {
@@ -2668,7 +2786,16 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2668 2786
2669 if ((err = snd_m3_pcm(chip, 0)) < 0) 2787 if ((err = snd_m3_pcm(chip, 0)) < 0)
2670 return err; 2788 return err;
2671 2789
2790#ifdef CONFIG_SND_MAESTRO3_INPUT
2791 if (chip->hv_config & HV_CTRL_ENABLE) {
2792 err = snd_m3_input_register(chip);
2793 if (err)
2794 snd_printk(KERN_WARNING "Input device registration "
2795 "failed with error %i", err);
2796 }
2797#endif
2798
2672 snd_m3_enable_ints(chip); 2799 snd_m3_enable_ints(chip);
2673 snd_m3_assp_continue(chip); 2800 snd_m3_assp_continue(chip);
2674 2801
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index c4dcbadd83aa..44d6d2ec964f 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -22,8 +22,7 @@ config SND_USB_AUDIO
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101 24config SND_USB_UA101
25 tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)" 25 tristate "Edirol UA-101/UA-1000 driver"
26 depends on EXPERIMENTAL
27 select SND_PCM 26 select SND_PCM
28 select SND_RAWMIDI 27 select SND_RAWMIDI
29 help 28 help
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 5bf64aef9558..e7ac7f493a8f 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -2,14 +2,24 @@
2# Makefile for ALSA 2# Makefile for ALSA
3# 3#
4 4
5snd-usb-audio-objs := usbaudio.o usbmixer.o 5snd-usb-audio-objs := card.o \
6snd-usb-lib-objs := usbmidi.o 6 mixer.o \
7snd-ua101-objs := ua101.o 7 mixer_quirks.o \
8 proc.o \
9 quirks.o \
10 format.o \
11 endpoint.o \
12 urb.o \
13 pcm.o \
14 helper.o
15
16snd-usbmidi-lib-objs := midi.o
8 17
9# Toplevel Module Dependency 18# Toplevel Module Dependency
10obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o 19obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usbmidi-lib.o
11obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o snd-usb-lib.o 20
12obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o 21obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
13obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o 22obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
23obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
14 24
15obj-$(CONFIG_SND) += usx2y/ caiaq/ 25obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index 27ed0bc651ae..8bbfbfd4c658 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -16,6 +16,7 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/ 17*/
18 18
19#include <linux/gfp.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/usb.h> 21#include <linux/usb.h>
21#include <linux/usb/input.h> 22#include <linux/usb/input.h>
diff --git a/sound/usb/card.c b/sound/usb/card.c
new file mode 100644
index 000000000000..da1346bd4856
--- /dev/null
+++ b/sound/usb/card.c
@@ -0,0 +1,652 @@
1/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
5 *
6 * Many codes borrowed from audio.c by
7 * Alan Cox (alan@lxorguk.ukuu.org.uk)
8 * Thomas Sailer (sailer@ife.ee.ethz.ch)
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 *
26 * NOTES:
27 *
28 * - async unlink should be used for avoiding the sleep inside lock.
29 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
30 * oops. in such a cse, pass async_unlink=0 option.
31 * - the linked URBs would be preferred but not used so far because of
32 * the instability of unlinking.
33 * - type II is not supported properly. there is no device which supports
34 * this type *correctly*. SB extigy looks as if it supports, but it's
35 * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
36 */
37
38
39#include <linux/bitops.h>
40#include <linux/init.h>
41#include <linux/list.h>
42#include <linux/slab.h>
43#include <linux/string.h>
44#include <linux/usb.h>
45#include <linux/moduleparam.h>
46#include <linux/mutex.h>
47#include <linux/usb/audio.h>
48#include <linux/usb/audio-v2.h>
49
50#include <sound/core.h>
51#include <sound/info.h>
52#include <sound/pcm.h>
53#include <sound/pcm_params.h>
54#include <sound/initval.h>
55
56#include "usbaudio.h"
57#include "card.h"
58#include "midi.h"
59#include "mixer.h"
60#include "proc.h"
61#include "quirks.h"
62#include "endpoint.h"
63#include "helper.h"
64#include "debug.h"
65#include "pcm.h"
66#include "urb.h"
67#include "format.h"
68
69MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
70MODULE_DESCRIPTION("USB Audio");
71MODULE_LICENSE("GPL");
72MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
73
74
75static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
76static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
77static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
78/* Vendor/product IDs for this card */
79static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
80static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
81static int nrpacks = 8; /* max. number of packets per urb */
82static int async_unlink = 1;
83static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
84static int ignore_ctl_error;
85
86module_param_array(index, int, NULL, 0444);
87MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
88module_param_array(id, charp, NULL, 0444);
89MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
90module_param_array(enable, bool, NULL, 0444);
91MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
92module_param_array(vid, int, NULL, 0444);
93MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
94module_param_array(pid, int, NULL, 0444);
95MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
96module_param(nrpacks, int, 0644);
97MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
98module_param(async_unlink, bool, 0444);
99MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
100module_param_array(device_setup, int, NULL, 0444);
101MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
102module_param(ignore_ctl_error, bool, 0444);
103MODULE_PARM_DESC(ignore_ctl_error,
104 "Ignore errors from USB controller for mixer interfaces.");
105
106/*
107 * we keep the snd_usb_audio_t instances by ourselves for merging
108 * the all interfaces on the same card as one sound device.
109 */
110
111static DEFINE_MUTEX(register_mutex);
112static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
113static struct usb_driver usb_audio_driver;
114
115/*
116 * disconnect streams
117 * called from snd_usb_audio_disconnect()
118 */
119static void snd_usb_stream_disconnect(struct list_head *head)
120{
121 int idx;
122 struct snd_usb_stream *as;
123 struct snd_usb_substream *subs;
124
125 as = list_entry(head, struct snd_usb_stream, list);
126 for (idx = 0; idx < 2; idx++) {
127 subs = &as->substream[idx];
128 if (!subs->num_formats)
129 return;
130 snd_usb_release_substream_urbs(subs, 1);
131 subs->interface = -1;
132 }
133}
134
135static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
136{
137 struct usb_device *dev = chip->dev;
138 struct usb_host_interface *alts;
139 struct usb_interface_descriptor *altsd;
140 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
141
142 if (!iface) {
143 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
144 dev->devnum, ctrlif, interface);
145 return -EINVAL;
146 }
147
148 if (usb_interface_claimed(iface)) {
149 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
150 dev->devnum, ctrlif, interface);
151 return -EINVAL;
152 }
153
154 alts = &iface->altsetting[0];
155 altsd = get_iface_desc(alts);
156 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
157 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
158 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
159 int err = snd_usbmidi_create(chip->card, iface,
160 &chip->midi_list, NULL);
161 if (err < 0) {
162 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
163 dev->devnum, ctrlif, interface);
164 return -EINVAL;
165 }
166 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
167
168 return 0;
169 }
170
171 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
172 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
173 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
174 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
175 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
176 /* skip non-supported classes */
177 return -EINVAL;
178 }
179
180 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
181 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
182 return -EINVAL;
183 }
184
185 if (! snd_usb_parse_audio_endpoints(chip, interface)) {
186 usb_set_interface(dev, interface, 0); /* reset the current interface */
187 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
188 return -EINVAL;
189 }
190
191 return 0;
192}
193
194/*
195 * parse audio control descriptor and create pcm/midi streams
196 */
197static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
198{
199 struct usb_device *dev = chip->dev;
200 struct usb_host_interface *host_iface;
201 struct usb_interface_descriptor *altsd;
202 void *control_header;
203 int i, protocol;
204
205 /* find audiocontrol interface */
206 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
207 control_header = snd_usb_find_csint_desc(host_iface->extra,
208 host_iface->extralen,
209 NULL, UAC_HEADER);
210 altsd = get_iface_desc(host_iface);
211 protocol = altsd->bInterfaceProtocol;
212
213 if (!control_header) {
214 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
215 return -EINVAL;
216 }
217
218 switch (protocol) {
219 case UAC_VERSION_1: {
220 struct uac_ac_header_descriptor_v1 *h1 = control_header;
221
222 if (!h1->bInCollection) {
223 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
224 return -EINVAL;
225 }
226
227 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
228 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
229 return -EINVAL;
230 }
231
232 for (i = 0; i < h1->bInCollection; i++)
233 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
234
235 break;
236 }
237
238 case UAC_VERSION_2: {
239 struct uac_clock_source_descriptor *cs;
240 struct usb_interface_assoc_descriptor *assoc =
241 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
242
243 if (!assoc) {
244 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
245 return -EINVAL;
246 }
247
248 /* FIXME: for now, we expect there is at least one clock source
249 * descriptor and we always take the first one.
250 * We should properly support devices with multiple clock sources,
251 * clock selectors and sample rate conversion units. */
252
253 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
254 NULL, UAC2_CLOCK_SOURCE);
255
256 if (!cs) {
257 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
258 return -EINVAL;
259 }
260
261 chip->clock_id = cs->bClockID;
262
263 for (i = 0; i < assoc->bInterfaceCount; i++) {
264 int intf = assoc->bFirstInterface + i;
265
266 if (intf != ctrlif)
267 snd_usb_create_stream(chip, ctrlif, intf);
268 }
269
270 break;
271 }
272
273 default:
274 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
275 return -EINVAL;
276 }
277
278 return 0;
279}
280
281/*
282 * free the chip instance
283 *
284 * here we have to do not much, since pcm and controls are already freed
285 *
286 */
287
288static int snd_usb_audio_free(struct snd_usb_audio *chip)
289{
290 kfree(chip);
291 return 0;
292}
293
294static int snd_usb_audio_dev_free(struct snd_device *device)
295{
296 struct snd_usb_audio *chip = device->device_data;
297 return snd_usb_audio_free(chip);
298}
299
300
301/*
302 * create a chip instance and set its names.
303 */
304static int snd_usb_audio_create(struct usb_device *dev, int idx,
305 const struct snd_usb_audio_quirk *quirk,
306 struct snd_usb_audio **rchip)
307{
308 struct snd_card *card;
309 struct snd_usb_audio *chip;
310 int err, len;
311 char component[14];
312 static struct snd_device_ops ops = {
313 .dev_free = snd_usb_audio_dev_free,
314 };
315
316 *rchip = NULL;
317
318 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
319 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
320 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
321 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
322 return -ENXIO;
323 }
324
325 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
326 if (err < 0) {
327 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
328 return err;
329 }
330
331 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
332 if (! chip) {
333 snd_card_free(card);
334 return -ENOMEM;
335 }
336
337 chip->index = idx;
338 chip->dev = dev;
339 chip->card = card;
340 chip->setup = device_setup[idx];
341 chip->nrpacks = nrpacks;
342 chip->async_unlink = async_unlink;
343
344 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
345 le16_to_cpu(dev->descriptor.idProduct));
346 INIT_LIST_HEAD(&chip->pcm_list);
347 INIT_LIST_HEAD(&chip->midi_list);
348 INIT_LIST_HEAD(&chip->mixer_list);
349
350 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
351 snd_usb_audio_free(chip);
352 snd_card_free(card);
353 return err;
354 }
355
356 strcpy(card->driver, "USB-Audio");
357 sprintf(component, "USB%04x:%04x",
358 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
359 snd_component_add(card, component);
360
361 /* retrieve the device string as shortname */
362 if (quirk && quirk->product_name) {
363 strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
364 } else {
365 if (!dev->descriptor.iProduct ||
366 usb_string(dev, dev->descriptor.iProduct,
367 card->shortname, sizeof(card->shortname)) <= 0) {
368 /* no name available from anywhere, so use ID */
369 sprintf(card->shortname, "USB Device %#04x:%#04x",
370 USB_ID_VENDOR(chip->usb_id),
371 USB_ID_PRODUCT(chip->usb_id));
372 }
373 }
374
375 /* retrieve the vendor and device strings as longname */
376 if (quirk && quirk->vendor_name) {
377 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
378 } else {
379 if (dev->descriptor.iManufacturer)
380 len = usb_string(dev, dev->descriptor.iManufacturer,
381 card->longname, sizeof(card->longname));
382 else
383 len = 0;
384 /* we don't really care if there isn't any vendor string */
385 }
386 if (len > 0)
387 strlcat(card->longname, " ", sizeof(card->longname));
388
389 strlcat(card->longname, card->shortname, sizeof(card->longname));
390
391 len = strlcat(card->longname, " at ", sizeof(card->longname));
392
393 if (len < sizeof(card->longname))
394 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
395
396 strlcat(card->longname,
397 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
398 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
399 ", high speed",
400 sizeof(card->longname));
401
402 snd_usb_audio_create_proc(chip);
403
404 *rchip = chip;
405 return 0;
406}
407
408/*
409 * probe the active usb device
410 *
411 * note that this can be called multiple times per a device, when it
412 * includes multiple audio control interfaces.
413 *
414 * thus we check the usb device pointer and creates the card instance
415 * only at the first time. the successive calls of this function will
416 * append the pcm interface to the corresponding card.
417 */
418static void *snd_usb_audio_probe(struct usb_device *dev,
419 struct usb_interface *intf,
420 const struct usb_device_id *usb_id)
421{
422 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
423 int i, err;
424 struct snd_usb_audio *chip;
425 struct usb_host_interface *alts;
426 int ifnum;
427 u32 id;
428
429 alts = &intf->altsetting[0];
430 ifnum = get_iface_desc(alts)->bInterfaceNumber;
431 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
432 le16_to_cpu(dev->descriptor.idProduct));
433 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
434 goto __err_val;
435
436 if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
437 goto __err_val;
438
439 /*
440 * found a config. now register to ALSA
441 */
442
443 /* check whether it's already registered */
444 chip = NULL;
445 mutex_lock(&register_mutex);
446 for (i = 0; i < SNDRV_CARDS; i++) {
447 if (usb_chip[i] && usb_chip[i]->dev == dev) {
448 if (usb_chip[i]->shutdown) {
449 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
450 goto __error;
451 }
452 chip = usb_chip[i];
453 break;
454 }
455 }
456 if (! chip) {
457 /* it's a fresh one.
458 * now look for an empty slot and create a new card instance
459 */
460 for (i = 0; i < SNDRV_CARDS; i++)
461 if (enable[i] && ! usb_chip[i] &&
462 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
463 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
464 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
465 goto __error;
466 }
467 snd_card_set_dev(chip->card, &intf->dev);
468 break;
469 }
470 if (!chip) {
471 printk(KERN_ERR "no available usb audio device\n");
472 goto __error;
473 }
474 }
475
476 chip->txfr_quirk = 0;
477 err = 1; /* continue */
478 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
479 /* need some special handlings */
480 if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
481 goto __error;
482 }
483
484 if (err > 0) {
485 /* create normal USB audio interfaces */
486 if (snd_usb_create_streams(chip, ifnum) < 0 ||
487 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
488 goto __error;
489 }
490 }
491
492 /* we are allowed to call snd_card_register() many times */
493 if (snd_card_register(chip->card) < 0) {
494 goto __error;
495 }
496
497 usb_chip[chip->index] = chip;
498 chip->num_interfaces++;
499 mutex_unlock(&register_mutex);
500 return chip;
501
502 __error:
503 if (chip && !chip->num_interfaces)
504 snd_card_free(chip->card);
505 mutex_unlock(&register_mutex);
506 __err_val:
507 return NULL;
508}
509
510/*
511 * we need to take care of counter, since disconnection can be called also
512 * many times as well as usb_audio_probe().
513 */
514static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
515{
516 struct snd_usb_audio *chip;
517 struct snd_card *card;
518 struct list_head *p;
519
520 if (ptr == (void *)-1L)
521 return;
522
523 chip = ptr;
524 card = chip->card;
525 mutex_lock(&register_mutex);
526 chip->shutdown = 1;
527 chip->num_interfaces--;
528 if (chip->num_interfaces <= 0) {
529 snd_card_disconnect(card);
530 /* release the pcm resources */
531 list_for_each(p, &chip->pcm_list) {
532 snd_usb_stream_disconnect(p);
533 }
534 /* release the midi resources */
535 list_for_each(p, &chip->midi_list) {
536 snd_usbmidi_disconnect(p);
537 }
538 /* release mixer resources */
539 list_for_each(p, &chip->mixer_list) {
540 snd_usb_mixer_disconnect(p);
541 }
542 usb_chip[chip->index] = NULL;
543 mutex_unlock(&register_mutex);
544 snd_card_free_when_closed(card);
545 } else {
546 mutex_unlock(&register_mutex);
547 }
548}
549
550/*
551 * new 2.5 USB kernel API
552 */
553static int usb_audio_probe(struct usb_interface *intf,
554 const struct usb_device_id *id)
555{
556 void *chip;
557 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
558 if (chip) {
559 usb_set_intfdata(intf, chip);
560 return 0;
561 } else
562 return -EIO;
563}
564
565static void usb_audio_disconnect(struct usb_interface *intf)
566{
567 snd_usb_audio_disconnect(interface_to_usbdev(intf),
568 usb_get_intfdata(intf));
569}
570
571#ifdef CONFIG_PM
572static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
573{
574 struct snd_usb_audio *chip = usb_get_intfdata(intf);
575 struct list_head *p;
576 struct snd_usb_stream *as;
577
578 if (chip == (void *)-1L)
579 return 0;
580
581 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
582 if (!chip->num_suspended_intf++) {
583 list_for_each(p, &chip->pcm_list) {
584 as = list_entry(p, struct snd_usb_stream, list);
585 snd_pcm_suspend_all(as->pcm);
586 }
587 }
588
589 return 0;
590}
591
592static int usb_audio_resume(struct usb_interface *intf)
593{
594 struct snd_usb_audio *chip = usb_get_intfdata(intf);
595
596 if (chip == (void *)-1L)
597 return 0;
598 if (--chip->num_suspended_intf)
599 return 0;
600 /*
601 * ALSA leaves material resumption to user space
602 * we just notify
603 */
604
605 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
606
607 return 0;
608}
609#else
610#define usb_audio_suspend NULL
611#define usb_audio_resume NULL
612#endif /* CONFIG_PM */
613
614static struct usb_device_id usb_audio_ids [] = {
615#include "quirks-table.h"
616 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
617 .bInterfaceClass = USB_CLASS_AUDIO,
618 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
619 { } /* Terminating entry */
620};
621
622MODULE_DEVICE_TABLE (usb, usb_audio_ids);
623
624/*
625 * entry point for linux usb interface
626 */
627
628static struct usb_driver usb_audio_driver = {
629 .name = "snd-usb-audio",
630 .probe = usb_audio_probe,
631 .disconnect = usb_audio_disconnect,
632 .suspend = usb_audio_suspend,
633 .resume = usb_audio_resume,
634 .id_table = usb_audio_ids,
635};
636
637static int __init snd_usb_audio_init(void)
638{
639 if (nrpacks < 1 || nrpacks > MAX_PACKS) {
640 printk(KERN_WARNING "invalid nrpacks value.\n");
641 return -EINVAL;
642 }
643 return usb_register(&usb_audio_driver);
644}
645
646static void __exit snd_usb_audio_cleanup(void)
647{
648 usb_deregister(&usb_audio_driver);
649}
650
651module_init(snd_usb_audio_init);
652module_exit(snd_usb_audio_cleanup);
diff --git a/sound/usb/card.h b/sound/usb/card.h
new file mode 100644
index 000000000000..ed92420c1095
--- /dev/null
+++ b/sound/usb/card.h
@@ -0,0 +1,105 @@
1#ifndef __USBAUDIO_CARD_H
2#define __USBAUDIO_CARD_H
3
4#define MAX_PACKS 20
5#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
6#define MAX_URBS 8
7#define SYNC_URBS 4 /* always four urbs for sync */
8#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
9
10struct audioformat {
11 struct list_head list;
12 u64 formats; /* ALSA format bits */
13 unsigned int channels; /* # channels */
14 unsigned int fmt_type; /* USB audio format type (1-3) */
15 unsigned int frame_size; /* samples per frame for non-audio */
16 int iface; /* interface number */
17 unsigned char altsetting; /* corresponding alternate setting */
18 unsigned char altset_idx; /* array index of altenate setting */
19 unsigned char attributes; /* corresponding attributes of cs endpoint */
20 unsigned char endpoint; /* endpoint */
21 unsigned char ep_attr; /* endpoint attributes */
22 unsigned char datainterval; /* log_2 of data packet interval */
23 unsigned int maxpacksize; /* max. packet size */
24 unsigned int rates; /* rate bitmasks */
25 unsigned int rate_min, rate_max; /* min/max rates */
26 unsigned int nr_rates; /* number of rate table entries */
27 unsigned int *rate_table; /* rate table */
28};
29
30struct snd_usb_substream;
31
32struct snd_urb_ctx {
33 struct urb *urb;
34 unsigned int buffer_size; /* size of data buffer, if data URB */
35 struct snd_usb_substream *subs;
36 int index; /* index for urb array */
37 int packets; /* number of packets per urb */
38};
39
40struct snd_urb_ops {
41 int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
42 int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
43 int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
44 int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
45};
46
47struct snd_usb_substream {
48 struct snd_usb_stream *stream;
49 struct usb_device *dev;
50 struct snd_pcm_substream *pcm_substream;
51 int direction; /* playback or capture */
52 int interface; /* current interface */
53 int endpoint; /* assigned endpoint */
54 struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
55 unsigned int cur_rate; /* current rate (for hw_params callback) */
56 unsigned int period_bytes; /* current period bytes (for hw_params callback) */
57 unsigned int altset_idx; /* USB data format: index of alternate setting */
58 unsigned int datapipe; /* the data i/o pipe */
59 unsigned int syncpipe; /* 1 - async out or adaptive in */
60 unsigned int datainterval; /* log_2 of data packet interval */
61 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
62 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
63 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
64 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
65 unsigned int phase; /* phase accumulator */
66 unsigned int maxpacksize; /* max packet size in bytes */
67 unsigned int maxframesize; /* max packet size in frames */
68 unsigned int curpacksize; /* current packet size in bytes (for capture) */
69 unsigned int curframesize; /* current packet size in frames (for capture) */
70 unsigned int fill_max: 1; /* fill max packet size always */
71 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
72 unsigned int fmt_type; /* USB audio format type (1-3) */
73
74 unsigned int running: 1; /* running status */
75
76 unsigned int hwptr_done; /* processed byte position in the buffer */
77 unsigned int transfer_done; /* processed frames since last period update */
78 unsigned long active_mask; /* bitmask of active urbs */
79 unsigned long unlink_mask; /* bitmask of unlinked urbs */
80
81 unsigned int nurbs; /* # urbs */
82 struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
83 struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
84 char *syncbuf; /* sync buffer for all sync URBs */
85 dma_addr_t sync_dma; /* DMA address of syncbuf */
86
87 u64 formats; /* format bitmasks (all or'ed) */
88 unsigned int num_formats; /* number of supported audio formats (list) */
89 struct list_head fmt_list; /* format list */
90 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
91 spinlock_t lock;
92
93 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
94};
95
96struct snd_usb_stream {
97 struct snd_usb_audio *chip;
98 struct snd_pcm *pcm;
99 int pcm_index;
100 unsigned int fmt_type; /* USB audio format type (1-3) */
101 struct snd_usb_substream substream[2];
102 struct list_head list;
103};
104
105#endif /* __USBAUDIO_CARD_H */
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
new file mode 100644
index 000000000000..343ec2d9ee66
--- /dev/null
+++ b/sound/usb/debug.h
@@ -0,0 +1,15 @@
1#ifndef __USBAUDIO_DEBUG_H
2#define __USBAUDIO_DEBUG_H
3
4/*
5 * h/w constraints
6 */
7
8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else
11#define hwc_debug(fmt, args...) /**/
12#endif
13
14#endif /* __USBAUDIO_DEBUG_H */
15
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
new file mode 100644
index 000000000000..ef07a6d0dd5f
--- /dev/null
+++ b/sound/usb/endpoint.c
@@ -0,0 +1,362 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "proc.h"
30#include "quirks.h"
31#include "endpoint.h"
32#include "urb.h"
33#include "pcm.h"
34#include "helper.h"
35#include "format.h"
36
37/*
38 * free a substream
39 */
40static void free_substream(struct snd_usb_substream *subs)
41{
42 struct list_head *p, *n;
43
44 if (!subs->num_formats)
45 return; /* not initialized */
46 list_for_each_safe(p, n, &subs->fmt_list) {
47 struct audioformat *fp = list_entry(p, struct audioformat, list);
48 kfree(fp->rate_table);
49 kfree(fp);
50 }
51 kfree(subs->rate_list.list);
52}
53
54
55/*
56 * free a usb stream instance
57 */
58static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
59{
60 free_substream(&stream->substream[0]);
61 free_substream(&stream->substream[1]);
62 list_del(&stream->list);
63 kfree(stream);
64}
65
66static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
67{
68 struct snd_usb_stream *stream = pcm->private_data;
69 if (stream) {
70 stream->pcm = NULL;
71 snd_usb_audio_stream_free(stream);
72 }
73}
74
75
76/*
77 * add this endpoint to the chip instance.
78 * if a stream with the same endpoint already exists, append to it.
79 * if not, create a new pcm stream.
80 */
81int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
82{
83 struct list_head *p;
84 struct snd_usb_stream *as;
85 struct snd_usb_substream *subs;
86 struct snd_pcm *pcm;
87 int err;
88
89 list_for_each(p, &chip->pcm_list) {
90 as = list_entry(p, struct snd_usb_stream, list);
91 if (as->fmt_type != fp->fmt_type)
92 continue;
93 subs = &as->substream[stream];
94 if (!subs->endpoint)
95 continue;
96 if (subs->endpoint == fp->endpoint) {
97 list_add_tail(&fp->list, &subs->fmt_list);
98 subs->num_formats++;
99 subs->formats |= fp->formats;
100 return 0;
101 }
102 }
103 /* look for an empty stream */
104 list_for_each(p, &chip->pcm_list) {
105 as = list_entry(p, struct snd_usb_stream, list);
106 if (as->fmt_type != fp->fmt_type)
107 continue;
108 subs = &as->substream[stream];
109 if (subs->endpoint)
110 continue;
111 err = snd_pcm_new_stream(as->pcm, stream, 1);
112 if (err < 0)
113 return err;
114 snd_usb_init_substream(as, stream, fp);
115 return 0;
116 }
117
118 /* create a new pcm */
119 as = kzalloc(sizeof(*as), GFP_KERNEL);
120 if (!as)
121 return -ENOMEM;
122 as->pcm_index = chip->pcm_devs;
123 as->chip = chip;
124 as->fmt_type = fp->fmt_type;
125 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
126 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
127 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
128 &pcm);
129 if (err < 0) {
130 kfree(as);
131 return err;
132 }
133 as->pcm = pcm;
134 pcm->private_data = as;
135 pcm->private_free = snd_usb_audio_pcm_free;
136 pcm->info_flags = 0;
137 if (chip->pcm_devs > 0)
138 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
139 else
140 strcpy(pcm->name, "USB Audio");
141
142 snd_usb_init_substream(as, stream, fp);
143
144 list_add(&as->list, &chip->pcm_list);
145 chip->pcm_devs++;
146
147 snd_usb_proc_pcm_format_add(as);
148
149 return 0;
150}
151
152int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
153{
154 struct usb_device *dev;
155 struct usb_interface *iface;
156 struct usb_host_interface *alts;
157 struct usb_interface_descriptor *altsd;
158 int i, altno, err, stream;
159 int format = 0, num_channels = 0;
160 struct audioformat *fp = NULL;
161 unsigned char *fmt, *csep;
162 int num, protocol;
163
164 dev = chip->dev;
165
166 /* parse the interface's altsettings */
167 iface = usb_ifnum_to_if(dev, iface_no);
168
169 num = iface->num_altsetting;
170
171 /*
172 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
173 * one misses syncpipe, and does not produce any sound.
174 */
175 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
176 num = 4;
177
178 for (i = 0; i < num; i++) {
179 alts = &iface->altsetting[i];
180 altsd = get_iface_desc(alts);
181 protocol = altsd->bInterfaceProtocol;
182 /* skip invalid one */
183 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
184 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
185 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
186 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
187 altsd->bNumEndpoints < 1 ||
188 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
189 continue;
190 /* must be isochronous */
191 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
192 USB_ENDPOINT_XFER_ISOC)
193 continue;
194 /* check direction */
195 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
196 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
197 altno = altsd->bAlternateSetting;
198
199 if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
200 continue;
201
202 /* get audio formats */
203 switch (protocol) {
204 case UAC_VERSION_1: {
205 struct uac_as_header_descriptor_v1 *as =
206 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
207
208 if (!as) {
209 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
210 dev->devnum, iface_no, altno);
211 continue;
212 }
213
214 if (as->bLength < sizeof(*as)) {
215 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
216 dev->devnum, iface_no, altno);
217 continue;
218 }
219
220 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
221 break;
222 }
223
224 case UAC_VERSION_2: {
225 struct uac_as_header_descriptor_v2 *as =
226 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
227
228 if (!as) {
229 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
230 dev->devnum, iface_no, altno);
231 continue;
232 }
233
234 if (as->bLength < sizeof(*as)) {
235 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
236 dev->devnum, iface_no, altno);
237 continue;
238 }
239
240 num_channels = as->bNrChannels;
241 format = le32_to_cpu(as->bmFormats);
242
243 break;
244 }
245
246 default:
247 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
248 dev->devnum, iface_no, altno, protocol);
249 continue;
250 }
251
252 /* get format type */
253 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
254 if (!fmt) {
255 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
256 dev->devnum, iface_no, altno);
257 continue;
258 }
259 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
260 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
261 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
262 dev->devnum, iface_no, altno);
263 continue;
264 }
265
266 /*
267 * Blue Microphones workaround: The last altsetting is identical
268 * with the previous one, except for a larger packet size, but
269 * is actually a mislabeled two-channel setting; ignore it.
270 */
271 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
272 fp && fp->altsetting == 1 && fp->channels == 1 &&
273 fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
274 protocol == UAC_VERSION_1 &&
275 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
276 fp->maxpacksize * 2)
277 continue;
278
279 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
280 /* Creamware Noah has this descriptor after the 2nd endpoint */
281 if (!csep && altsd->bNumEndpoints >= 2)
282 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
283 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
284 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
285 " class specific endpoint descriptor\n",
286 dev->devnum, iface_no, altno);
287 csep = NULL;
288 }
289
290 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
291 if (! fp) {
292 snd_printk(KERN_ERR "cannot malloc\n");
293 return -ENOMEM;
294 }
295
296 fp->iface = iface_no;
297 fp->altsetting = altno;
298 fp->altset_idx = i;
299 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
300 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
301 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
302 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
303 /* num_channels is only set for v2 interfaces */
304 fp->channels = num_channels;
305 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
306 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
307 * (fp->maxpacksize & 0x7ff);
308 fp->attributes = csep ? csep[3] : 0;
309
310 /* some quirks for attributes here */
311
312 switch (chip->usb_id) {
313 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
314 /* Optoplay sets the sample rate attribute although
315 * it seems not supporting it in fact.
316 */
317 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
318 break;
319 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
320 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
321 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
322 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
323 /* doesn't set the sample rate attribute, but supports it */
324 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
325 break;
326 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
327 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
328 an older model 77d:223) */
329 /*
330 * plantronics headset and Griffin iMic have set adaptive-in
331 * although it's really not...
332 */
333 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
334 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
335 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
336 else
337 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
338 break;
339 }
340
341 /* ok, let's parse further... */
342 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
343 kfree(fp->rate_table);
344 kfree(fp);
345 continue;
346 }
347
348 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
349 err = snd_usb_add_audio_endpoint(chip, stream, fp);
350 if (err < 0) {
351 kfree(fp->rate_table);
352 kfree(fp);
353 return err;
354 }
355 /* try to set the interface... */
356 usb_set_interface(chip->dev, iface_no, altno);
357 snd_usb_init_pitch(chip, iface_no, alts, fp);
358 snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max);
359 }
360 return 0;
361}
362
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
new file mode 100644
index 000000000000..64dd0db023b2
--- /dev/null
+++ b/sound/usb/endpoint.h
@@ -0,0 +1,11 @@
1#ifndef __USBAUDIO_ENDPOINT_H
2#define __USBAUDIO_ENDPOINT_H
3
4int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip,
5 int iface_no);
6
7int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip,
8 int stream,
9 struct audioformat *fp);
10
11#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
new file mode 100644
index 000000000000..b87cf87c4e7b
--- /dev/null
+++ b/sound/usb/format.c
@@ -0,0 +1,432 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "quirks.h"
30#include "helper.h"
31#include "debug.h"
32
33/*
34 * parse the audio format type I descriptor
35 * and returns the corresponding pcm format
36 *
37 * @dev: usb device
38 * @fp: audioformat record
39 * @format: the format tag (wFormatTag)
40 * @fmt: the format type descriptor
41 */
42static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
43 struct audioformat *fp,
44 int format, void *_fmt,
45 int protocol)
46{
47 int sample_width, sample_bytes;
48 u64 pcm_formats;
49
50 switch (protocol) {
51 case UAC_VERSION_1: {
52 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
53 sample_width = fmt->bBitResolution;
54 sample_bytes = fmt->bSubframeSize;
55 format = 1 << format;
56 break;
57 }
58
59 case UAC_VERSION_2: {
60 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
61 sample_width = fmt->bBitResolution;
62 sample_bytes = fmt->bSubslotSize;
63 format <<= 1;
64 break;
65 }
66
67 default:
68 return -EINVAL;
69 }
70
71 pcm_formats = 0;
72
73 if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) {
74 /* some devices don't define this correctly... */
75 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
76 chip->dev->devnum, fp->iface, fp->altsetting);
77 format = 1 << UAC_FORMAT_TYPE_I_PCM;
78 }
79 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
80 if (sample_width > sample_bytes * 8) {
81 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
82 chip->dev->devnum, fp->iface, fp->altsetting,
83 sample_width, sample_bytes);
84 }
85 /* check the format byte size */
86 switch (sample_bytes) {
87 case 1:
88 pcm_formats |= SNDRV_PCM_FMTBIT_S8;
89 break;
90 case 2:
91 if (snd_usb_is_big_endian_format(chip, fp))
92 pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */
93 else
94 pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE;
95 break;
96 case 3:
97 if (snd_usb_is_big_endian_format(chip, fp))
98 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */
99 else
100 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE;
101 break;
102 case 4:
103 pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;
104 break;
105 default:
106 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
107 chip->dev->devnum, fp->iface, fp->altsetting,
108 sample_width, sample_bytes);
109 break;
110 }
111 }
112 if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) {
113 /* Dallas DS4201 workaround: it advertises U8 format, but really
114 supports S8. */
115 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
116 pcm_formats |= SNDRV_PCM_FMTBIT_S8;
117 else
118 pcm_formats |= SNDRV_PCM_FMTBIT_U8;
119 }
120 if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) {
121 pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
122 }
123 if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) {
124 pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW;
125 }
126 if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) {
127 pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;
128 }
129 if (format & ~0x3f) {
130 snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n",
131 chip->dev->devnum, fp->iface, fp->altsetting, format);
132 }
133 return pcm_formats;
134}
135
136
137/*
138 * parse the format descriptor and stores the possible sample rates
139 * on the audioformat table (audio class v1).
140 *
141 * @dev: usb device
142 * @fp: audioformat record
143 * @fmt: the format descriptor
144 * @offset: the start offset of descriptor pointing the rate type
145 * (7 for type I and II, 8 for type II)
146 */
147static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
148 unsigned char *fmt, int offset)
149{
150 int nr_rates = fmt[offset];
151
152 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
153 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
154 chip->dev->devnum, fp->iface, fp->altsetting);
155 return -1;
156 }
157
158 if (nr_rates) {
159 /*
160 * build the rate table and bitmap flags
161 */
162 int r, idx;
163
164 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
165 if (fp->rate_table == NULL) {
166 snd_printk(KERN_ERR "cannot malloc\n");
167 return -1;
168 }
169
170 fp->nr_rates = 0;
171 fp->rate_min = fp->rate_max = 0;
172 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
173 unsigned int rate = combine_triple(&fmt[idx]);
174 if (!rate)
175 continue;
176 /* C-Media CM6501 mislabels its 96 kHz altsetting */
177 if (rate == 48000 && nr_rates == 1 &&
178 (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
179 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
180 fp->altsetting == 5 && fp->maxpacksize == 392)
181 rate = 96000;
182 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
183 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
184 rate = 8000;
185
186 fp->rate_table[fp->nr_rates] = rate;
187 if (!fp->rate_min || rate < fp->rate_min)
188 fp->rate_min = rate;
189 if (!fp->rate_max || rate > fp->rate_max)
190 fp->rate_max = rate;
191 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
192 fp->nr_rates++;
193 }
194 if (!fp->nr_rates) {
195 hwc_debug("All rates were zero. Skipping format!\n");
196 return -1;
197 }
198 } else {
199 /* continuous rates */
200 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
201 fp->rate_min = combine_triple(&fmt[offset + 1]);
202 fp->rate_max = combine_triple(&fmt[offset + 4]);
203 }
204 return 0;
205}
206
207/*
208 * parse the format descriptor and stores the possible sample rates
209 * on the audioformat table (audio class v2).
210 */
211static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
212 struct audioformat *fp,
213 struct usb_host_interface *iface)
214{
215 struct usb_device *dev = chip->dev;
216 unsigned char tmp[2], *data;
217 int i, nr_rates, data_size, ret = 0;
218
219 /* get the number of sample rates first by only fetching 2 bytes */
220 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
221 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
222 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
223 tmp, sizeof(tmp), 1000);
224
225 if (ret < 0) {
226 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
227 goto err;
228 }
229
230 nr_rates = (tmp[1] << 8) | tmp[0];
231 data_size = 2 + 12 * nr_rates;
232 data = kzalloc(data_size, GFP_KERNEL);
233 if (!data) {
234 ret = -ENOMEM;
235 goto err;
236 }
237
238 /* now get the full information */
239 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
240 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
241 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
242 data, data_size, 1000);
243
244 if (ret < 0) {
245 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
246 ret = -EINVAL;
247 goto err_free;
248 }
249
250 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
251 if (!fp->rate_table) {
252 ret = -ENOMEM;
253 goto err_free;
254 }
255
256 fp->nr_rates = 0;
257 fp->rate_min = fp->rate_max = 0;
258
259 for (i = 0; i < nr_rates; i++) {
260 int rate = combine_quad(&data[2 + 12 * i]);
261
262 fp->rate_table[fp->nr_rates] = rate;
263 if (!fp->rate_min || rate < fp->rate_min)
264 fp->rate_min = rate;
265 if (!fp->rate_max || rate > fp->rate_max)
266 fp->rate_max = rate;
267 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
268 fp->nr_rates++;
269 }
270
271err_free:
272 kfree(data);
273err:
274 return ret;
275}
276
277/*
278 * parse the format type I and III descriptors
279 */
280static int parse_audio_format_i(struct snd_usb_audio *chip,
281 struct audioformat *fp,
282 int format, void *_fmt,
283 struct usb_host_interface *iface)
284{
285 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
286 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
287 int protocol = altsd->bInterfaceProtocol;
288 int pcm_format, ret;
289
290 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
291 /* FIXME: the format type is really IECxxx
292 * but we give normal PCM format to get the existing
293 * apps working...
294 */
295 switch (chip->usb_id) {
296
297 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
298 if (chip->setup == 0x00 &&
299 fp->altsetting == 6)
300 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
301 else
302 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
303 break;
304 default:
305 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
306 }
307 fp->formats = 1uLL << pcm_format;
308 } else {
309 fp->formats = parse_audio_format_i_type(chip, fp, format,
310 fmt, protocol);
311 if (!fp->formats)
312 return -1;
313 }
314
315 /* gather possible sample rates */
316 /* audio class v1 reports possible sample rates as part of the
317 * proprietary class specific descriptor.
318 * audio class v2 uses class specific EP0 range requests for that.
319 */
320 switch (protocol) {
321 case UAC_VERSION_1:
322 fp->channels = fmt->bNrChannels;
323 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
324 break;
325 case UAC_VERSION_2:
326 /* fp->channels is already set in this case */
327 ret = parse_audio_format_rates_v2(chip, fp, iface);
328 break;
329 }
330
331 if (fp->channels < 1) {
332 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
333 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
334 return -1;
335 }
336
337 return ret;
338}
339
340/*
341 * parse the format type II descriptor
342 */
343static int parse_audio_format_ii(struct snd_usb_audio *chip,
344 struct audioformat *fp,
345 int format, void *_fmt,
346 struct usb_host_interface *iface)
347{
348 int brate, framesize, ret;
349 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
350 int protocol = altsd->bInterfaceProtocol;
351
352 switch (format) {
353 case UAC_FORMAT_TYPE_II_AC3:
354 /* FIXME: there is no AC3 format defined yet */
355 // fp->formats = SNDRV_PCM_FMTBIT_AC3;
356 fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
357 break;
358 case UAC_FORMAT_TYPE_II_MPEG:
359 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
360 break;
361 default:
362 snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
363 chip->dev->devnum, fp->iface, fp->altsetting, format);
364 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
365 break;
366 }
367
368 fp->channels = 1;
369
370 switch (protocol) {
371 case UAC_VERSION_1: {
372 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
373 brate = le16_to_cpu(fmt->wMaxBitRate);
374 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
375 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
376 fp->frame_size = framesize;
377 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
378 break;
379 }
380 case UAC_VERSION_2: {
381 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
382 brate = le16_to_cpu(fmt->wMaxBitRate);
383 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
384 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
385 fp->frame_size = framesize;
386 ret = parse_audio_format_rates_v2(chip, fp, iface);
387 break;
388 }
389 }
390
391 return ret;
392}
393
394int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
395 int format, unsigned char *fmt, int stream,
396 struct usb_host_interface *iface)
397{
398 int err;
399
400 switch (fmt[3]) {
401 case UAC_FORMAT_TYPE_I:
402 case UAC_FORMAT_TYPE_III:
403 err = parse_audio_format_i(chip, fp, format, fmt, iface);
404 break;
405 case UAC_FORMAT_TYPE_II:
406 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
407 break;
408 default:
409 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
410 chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
411 return -1;
412 }
413 fp->fmt_type = fmt[3];
414 if (err < 0)
415 return err;
416#if 1
417 /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
418 /* extigy apparently supports sample rates other than 48k
419 * but not in ordinary way. so we enable only 48k atm.
420 */
421 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
422 chip->usb_id == USB_ID(0x041e, 0x3020) ||
423 chip->usb_id == USB_ID(0x041e, 0x3061)) {
424 if (fmt[3] == UAC_FORMAT_TYPE_I &&
425 fp->rates != SNDRV_PCM_RATE_48000 &&
426 fp->rates != SNDRV_PCM_RATE_96000)
427 return -1;
428 }
429#endif
430 return 0;
431}
432
diff --git a/sound/usb/format.h b/sound/usb/format.h
new file mode 100644
index 000000000000..8298c4e8ddfa
--- /dev/null
+++ b/sound/usb/format.h
@@ -0,0 +1,8 @@
1#ifndef __USBAUDIO_FORMAT_H
2#define __USBAUDIO_FORMAT_H
3
4int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
5 int format, unsigned char *fmt, int stream,
6 struct usb_host_interface *iface);
7
8#endif /* __USBAUDIO_FORMAT_H */
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
new file mode 100644
index 000000000000..d48d6f8f6ac9
--- /dev/null
+++ b/sound/usb/helper.c
@@ -0,0 +1,113 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21
22#include "usbaudio.h"
23#include "helper.h"
24
25/*
26 * combine bytes and get an integer value
27 */
28unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
29{
30 switch (size) {
31 case 1: return *bytes;
32 case 2: return combine_word(bytes);
33 case 3: return combine_triple(bytes);
34 case 4: return combine_quad(bytes);
35 default: return 0;
36 }
37}
38
39/*
40 * parse descriptor buffer and return the pointer starting the given
41 * descriptor type.
42 */
43void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
44{
45 u8 *p, *end, *next;
46
47 p = descstart;
48 end = p + desclen;
49 for (; p < end;) {
50 if (p[0] < 2)
51 return NULL;
52 next = p + p[0];
53 if (next > end)
54 return NULL;
55 if (p[1] == dtype && (!after || (void *)p > after)) {
56 return p;
57 }
58 p = next;
59 }
60 return NULL;
61}
62
63/*
64 * find a class-specified interface descriptor with the given subtype.
65 */
66void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
67{
68 unsigned char *p = after;
69
70 while ((p = snd_usb_find_desc(buffer, buflen, p,
71 USB_DT_CS_INTERFACE)) != NULL) {
72 if (p[0] >= 3 && p[2] == dsubtype)
73 return p;
74 }
75 return NULL;
76}
77
78/*
79 * Wrapper for usb_control_msg().
80 * Allocates a temp buffer to prevent dmaing from/to the stack.
81 */
82int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
83 __u8 requesttype, __u16 value, __u16 index, void *data,
84 __u16 size, int timeout)
85{
86 int err;
87 void *buf = NULL;
88
89 if (size > 0) {
90 buf = kmemdup(data, size, GFP_KERNEL);
91 if (!buf)
92 return -ENOMEM;
93 }
94 err = usb_control_msg(dev, pipe, request, requesttype,
95 value, index, buf, size, timeout);
96 if (size > 0) {
97 memcpy(data, buf, size);
98 kfree(buf);
99 }
100 return err;
101}
102
103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
104 struct usb_host_interface *alts)
105{
106 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
107 get_endpoint(alts, 0)->bInterval >= 1 &&
108 get_endpoint(alts, 0)->bInterval <= 4)
109 return get_endpoint(alts, 0)->bInterval - 1;
110 else
111 return 0;
112}
113
diff --git a/sound/usb/helper.h b/sound/usb/helper.h
new file mode 100644
index 000000000000..a6b0e51b3a9a
--- /dev/null
+++ b/sound/usb/helper.h
@@ -0,0 +1,32 @@
1#ifndef __USBAUDIO_HELPER_H
2#define __USBAUDIO_HELPER_H
3
4unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
5
6void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
7void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
8
9int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
10 __u8 request, __u8 requesttype, __u16 value, __u16 index,
11 void *data, __u16 size, int timeout);
12
13unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
14 struct usb_host_interface *alts);
15
16/*
17 * retrieve usb_interface descriptor from the host interface
18 * (conditional for compatibility with the older API)
19 */
20#ifndef get_iface_desc
21#define get_iface_desc(iface) (&(iface)->desc)
22#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
23#define get_ep_desc(ep) (&(ep)->desc)
24#define get_cfg_desc(cfg) (&(cfg)->desc)
25#endif
26
27#ifndef snd_usb_get_speed
28#define snd_usb_get_speed(dev) ((dev)->speed)
29#endif
30
31
32#endif /* __USBAUDIO_HELPER_H */
diff --git a/sound/usb/usbmidi.c b/sound/usb/midi.c
index 9e28b20cb2ce..2c1558c327bb 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/midi.c
@@ -53,7 +53,8 @@
53#include <sound/rawmidi.h> 53#include <sound/rawmidi.h>
54#include <sound/asequencer.h> 54#include <sound/asequencer.h>
55#include "usbaudio.h" 55#include "usbaudio.h"
56 56#include "midi.h"
57#include "helper.h"
57 58
58/* 59/*
59 * define this to log all USB packets 60 * define this to log all USB packets
diff --git a/sound/usb/midi.h b/sound/usb/midi.h
new file mode 100644
index 000000000000..2089ec987c66
--- /dev/null
+++ b/sound/usb/midi.h
@@ -0,0 +1,48 @@
1#ifndef __USBMIDI_H
2#define __USBMIDI_H
3
4/* maximum number of endpoints per interface */
5#define MIDI_MAX_ENDPOINTS 2
6
7/* data for QUIRK_MIDI_FIXED_ENDPOINT */
8struct snd_usb_midi_endpoint_info {
9 int8_t out_ep; /* ep number, 0 autodetect */
10 uint8_t out_interval; /* interval for interrupt endpoints */
11 int8_t in_ep;
12 uint8_t in_interval;
13 uint16_t out_cables; /* bitmask */
14 uint16_t in_cables; /* bitmask */
15};
16
17/* for QUIRK_MIDI_YAMAHA, data is NULL */
18
19/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
20 * structure (out_cables and in_cables only) */
21
22/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
23 * structures, terminated with .ifnum = -1 */
24
25/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
26
27/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
28
29/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
30
31/* for QUIRK_IGNORE_INTERFACE, data is NULL */
32
33/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
34
35/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
36 * structure (out_cables and in_cables only) */
37
38/* for QUIRK_MIDI_CME, data is NULL */
39
40int snd_usbmidi_create(struct snd_card *card,
41 struct usb_interface *iface,
42 struct list_head *midi_list,
43 const struct snd_usb_audio_quirk *quirk);
44void snd_usbmidi_input_stop(struct list_head* p);
45void snd_usbmidi_input_start(struct list_head* p);
46void snd_usbmidi_disconnect(struct list_head *p);
47
48#endif /* __USBMIDI_H */
diff --git a/sound/usb/misc/Makefile b/sound/usb/misc/Makefile
new file mode 100644
index 000000000000..ccefd8158936
--- /dev/null
+++ b/sound/usb/misc/Makefile
@@ -0,0 +1,2 @@
1snd-ua101-objs := ua101.o
2obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o
diff --git a/sound/usb/ua101.c b/sound/usb/misc/ua101.c
index 3d458d3b9962..796d8b25ee89 100644
--- a/sound/usb/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -23,7 +23,8 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include "usbaudio.h" 26#include "../usbaudio.h"
27#include "../midi.h"
27 28
28MODULE_DESCRIPTION("Edirol UA-101/1000 driver"); 29MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 30MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
diff --git a/sound/usb/usbmixer.c b/sound/usb/mixer.c
index 8e8f871b74ca..21613fe0c1a2 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/mixer.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/audio.h> 35#include <linux/usb/audio.h>
36#include <linux/usb/audio-v2.h>
36 37
37#include <sound/core.h> 38#include <sound/core.h>
38#include <sound/control.h> 39#include <sound/control.h>
@@ -41,60 +42,12 @@
41#include <sound/tlv.h> 42#include <sound/tlv.h>
42 43
43#include "usbaudio.h" 44#include "usbaudio.h"
44 45#include "mixer.h"
45/* 46#include "helper.h"
46 */ 47#include "mixer_quirks.h"
47
48/* ignore error from controls - for debugging */
49/* #define IGNORE_CTL_ERROR */
50
51/*
52 * Sound Blaster remote control configuration
53 *
54 * format of remote control data:
55 * Extigy: xx 00
56 * Audigy 2 NX: 06 80 xx 00 00 00
57 * Live! 24-bit: 06 80 xx yy 22 83
58 */
59static const struct rc_config {
60 u32 usb_id;
61 u8 offset;
62 u8 length;
63 u8 packet_length;
64 u8 min_packet_length; /* minimum accepted length of the URB result */
65 u8 mute_mixer_id;
66 u32 mute_code;
67} rc_configs[] = {
68 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
69 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
70 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
71 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
72};
73 48
74#define MAX_ID_ELEMS 256 49#define MAX_ID_ELEMS 256
75 50
76struct usb_mixer_interface {
77 struct snd_usb_audio *chip;
78 unsigned int ctrlif;
79 struct list_head list;
80 unsigned int ignore_ctl_error;
81 struct urb *urb;
82 /* array[MAX_ID_ELEMS], indexed by unit id */
83 struct usb_mixer_elem_info **id_elems;
84
85 /* Sound Blaster remote control stuff */
86 const struct rc_config *rc_cfg;
87 u32 rc_code;
88 wait_queue_head_t rc_waitq;
89 struct urb *rc_urb;
90 struct usb_ctrlrequest *rc_setup_packet;
91 u8 rc_buffer[6];
92
93 u8 audigy2nx_leds[3];
94 u8 xonar_u1_status;
95};
96
97
98struct usb_audio_term { 51struct usb_audio_term {
99 int id; 52 int id;
100 int type; 53 int type;
@@ -116,39 +69,6 @@ struct mixer_build {
116 const struct usbmix_selector_map *selector_map; 69 const struct usbmix_selector_map *selector_map;
117}; 70};
118 71
119#define MAX_CHANNELS 10 /* max logical channels */
120
121struct usb_mixer_elem_info {
122 struct usb_mixer_interface *mixer;
123 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
124 struct snd_ctl_elem_id *elem_id;
125 unsigned int id;
126 unsigned int control; /* CS or ICN (high byte) */
127 unsigned int cmask; /* channel mask bitmap: 0 = master */
128 int channels;
129 int val_type;
130 int min, max, res;
131 int dBmin, dBmax;
132 int cached;
133 int cache_val[MAX_CHANNELS];
134 u8 initialized;
135};
136
137
138enum {
139 USB_FEATURE_NONE = 0,
140 USB_FEATURE_MUTE = 1,
141 USB_FEATURE_VOLUME,
142 USB_FEATURE_BASS,
143 USB_FEATURE_MID,
144 USB_FEATURE_TREBLE,
145 USB_FEATURE_GEQ,
146 USB_FEATURE_AGC,
147 USB_FEATURE_DELAY,
148 USB_FEATURE_BASSBOOST,
149 USB_FEATURE_LOUDNESS
150};
151
152enum { 72enum {
153 USB_MIXER_BOOLEAN, 73 USB_MIXER_BOOLEAN,
154 USB_MIXER_INV_BOOLEAN, 74 USB_MIXER_INV_BOOLEAN,
@@ -213,7 +133,7 @@ enum {
213 * if the mixer topology is too complicated and the parsed names are 133 * if the mixer topology is too complicated and the parsed names are
214 * ambiguous, add the entries in usbmixer_maps.c. 134 * ambiguous, add the entries in usbmixer_maps.c.
215 */ 135 */
216#include "usbmixer_maps.c" 136#include "mixer_maps.c"
217 137
218static const struct usbmix_name_map * 138static const struct usbmix_name_map *
219find_map(struct mixer_build *state, int unitid, int control) 139find_map(struct mixer_build *state, int unitid, int control)
@@ -278,6 +198,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
278 198
279/* 199/*
280 * find an audio control unit with the given unit id 200 * find an audio control unit with the given unit id
201 * this doesn't return any clock related units, so they need to be handled elsewhere
281 */ 202 */
282static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) 203static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
283{ 204{
@@ -286,7 +207,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
286 p = NULL; 207 p = NULL;
287 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, 208 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
288 USB_DT_CS_INTERFACE)) != NULL) { 209 USB_DT_CS_INTERFACE)) != NULL) {
289 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC_EXTENSION_UNIT_V1 && p[3] == unit) 210 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC2_EXTENSION_UNIT_V2 && p[3] == unit)
290 return p; 211 return p;
291 } 212 }
292 return NULL; 213 return NULL;
@@ -383,7 +304,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
383 * retrieve a mixer value 304 * retrieve a mixer value
384 */ 305 */
385 306
386static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 307static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
387{ 308{
388 unsigned char buf[2]; 309 unsigned char buf[2];
389 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 310 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -405,6 +326,58 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
405 return -EINVAL; 326 return -EINVAL;
406} 327}
407 328
329static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
330{
331 unsigned char buf[14]; /* enough space for one range of 4 bytes */
332 unsigned char *val;
333 int ret;
334 __u8 bRequest;
335
336 bRequest = (request == UAC_GET_CUR) ?
337 UAC2_CS_CUR : UAC2_CS_RANGE;
338
339 ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
340 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
341 bRequest,
342 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
343 validx, cval->mixer->ctrlif | (cval->id << 8),
344 buf, sizeof(buf), 1000);
345
346 if (ret < 0) {
347 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
348 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
349 return ret;
350 }
351
352 switch (request) {
353 case UAC_GET_CUR:
354 val = buf;
355 break;
356 case UAC_GET_MIN:
357 val = buf + sizeof(__u16);
358 break;
359 case UAC_GET_MAX:
360 val = buf + sizeof(__u16) * 2;
361 break;
362 case UAC_GET_RES:
363 val = buf + sizeof(__u16) * 3;
364 break;
365 default:
366 return -EINVAL;
367 }
368
369 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
370
371 return 0;
372}
373
374static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
375{
376 return (cval->mixer->protocol == UAC_VERSION_1) ?
377 get_ctl_value_v1(cval, request, validx, value_ret) :
378 get_ctl_value_v2(cval, request, validx, value_ret);
379}
380
408static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) 381static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
409{ 382{
410 return get_ctl_value(cval, UAC_GET_CUR, validx, value); 383 return get_ctl_value(cval, UAC_GET_CUR, validx, value);
@@ -429,8 +402,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
429 err = get_cur_mix_raw(cval, channel, value); 402 err = get_cur_mix_raw(cval, channel, value);
430 if (err < 0) { 403 if (err < 0) {
431 if (!cval->mixer->ignore_ctl_error) 404 if (!cval->mixer->ignore_ctl_error)
432 snd_printd(KERN_ERR "cannot get current value for " 405 snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n",
433 "control %d ch %d: err = %d\n",
434 cval->control, channel, err); 406 cval->control, channel, err);
435 return err; 407 return err;
436 } 408 }
@@ -444,11 +416,26 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
444 * set a mixer value 416 * set a mixer value
445 */ 417 */
446 418
447static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set) 419int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
420 int request, int validx, int value_set)
448{ 421{
449 unsigned char buf[2]; 422 unsigned char buf[2];
450 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 423 int val_len, timeout = 10;
451 int timeout = 10; 424
425 if (cval->mixer->protocol == UAC_VERSION_1) {
426 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
427 } else { /* UAC_VERSION_2 */
428 /* audio class v2 controls are always 2 bytes in size */
429 val_len = sizeof(__u16);
430
431 /* FIXME */
432 if (request != UAC_SET_CUR) {
433 snd_printdd(KERN_WARNING "RANGE setting not yet supported\n");
434 return -EINVAL;
435 }
436
437 request = UAC2_CS_CUR;
438 }
452 439
453 value_set = convert_bytes_value(cval, value_set); 440 value_set = convert_bytes_value(cval, value_set);
454 buf[0] = value_set & 0xff; 441 buf[0] = value_set & 0xff;
@@ -468,14 +455,14 @@ static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
468 455
469static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) 456static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
470{ 457{
471 return set_ctl_value(cval, UAC_SET_CUR, validx, value); 458 return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
472} 459}
473 460
474static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 461static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
475 int index, int value) 462 int index, int value)
476{ 463{
477 int err; 464 int err;
478 err = set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, 465 err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
479 value); 466 value);
480 if (err < 0) 467 if (err < 0)
481 return err; 468 return err;
@@ -644,46 +631,65 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
644 */ 631 */
645static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) 632static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
646{ 633{
647 unsigned char *p1; 634 void *p1;
648 635
649 memset(term, 0, sizeof(*term)); 636 memset(term, 0, sizeof(*term));
650 while ((p1 = find_audio_control_unit(state, id)) != NULL) { 637 while ((p1 = find_audio_control_unit(state, id)) != NULL) {
638 unsigned char *hdr = p1;
651 term->id = id; 639 term->id = id;
652 switch (p1[2]) { 640 switch (hdr[2]) {
653 case UAC_INPUT_TERMINAL: 641 case UAC_INPUT_TERMINAL:
654 term->type = combine_word(p1 + 4); 642 if (state->mixer->protocol == UAC_VERSION_1) {
655 term->channels = p1[7]; 643 struct uac_input_terminal_descriptor *d = p1;
656 term->chconfig = combine_word(p1 + 8); 644 term->type = le16_to_cpu(d->wTerminalType);
657 term->name = p1[11]; 645 term->channels = d->bNrChannels;
646 term->chconfig = le16_to_cpu(d->wChannelConfig);
647 term->name = d->iTerminal;
648 } else { /* UAC_VERSION_2 */
649 struct uac2_input_terminal_descriptor *d = p1;
650 term->type = le16_to_cpu(d->wTerminalType);
651 term->channels = d->bNrChannels;
652 term->chconfig = le32_to_cpu(d->bmChannelConfig);
653 term->name = d->iTerminal;
654 }
658 return 0; 655 return 0;
659 case UAC_FEATURE_UNIT: 656 case UAC_FEATURE_UNIT: {
660 id = p1[4]; 657 /* the header is the same for v1 and v2 */
658 struct uac_feature_unit_descriptor *d = p1;
659 id = d->bUnitID;
661 break; /* continue to parse */ 660 break; /* continue to parse */
662 case UAC_MIXER_UNIT: 661 }
663 term->type = p1[2] << 16; /* virtual type */ 662 case UAC_MIXER_UNIT: {
664 term->channels = p1[5 + p1[4]]; 663 struct uac_mixer_unit_descriptor *d = p1;
665 term->chconfig = combine_word(p1 + 6 + p1[4]); 664 term->type = d->bDescriptorSubtype << 16; /* virtual type */
666 term->name = p1[p1[0] - 1]; 665 term->channels = uac_mixer_unit_bNrChannels(d);
666 term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol);
667 term->name = uac_mixer_unit_iMixer(d);
667 return 0; 668 return 0;
668 case UAC_SELECTOR_UNIT: 669 }
670 case UAC_SELECTOR_UNIT: {
671 struct uac_selector_unit_descriptor *d = p1;
669 /* call recursively to retrieve the channel info */ 672 /* call recursively to retrieve the channel info */
670 if (check_input_term(state, p1[5], term) < 0) 673 if (check_input_term(state, d->baSourceID[0], term) < 0)
671 return -ENODEV; 674 return -ENODEV;
672 term->type = p1[2] << 16; /* virtual type */ 675 term->type = d->bDescriptorSubtype << 16; /* virtual type */
673 term->id = id; 676 term->id = id;
674 term->name = p1[9 + p1[0] - 1]; 677 term->name = uac_selector_unit_iSelector(d);
675 return 0; 678 return 0;
679 }
676 case UAC_PROCESSING_UNIT_V1: 680 case UAC_PROCESSING_UNIT_V1:
677 case UAC_EXTENSION_UNIT_V1: 681 case UAC_EXTENSION_UNIT_V1: {
678 if (p1[6] == 1) { 682 struct uac_processing_unit_descriptor *d = p1;
679 id = p1[7]; 683 if (d->bNrInPins) {
684 id = d->baSourceID[0];
680 break; /* continue to parse */ 685 break; /* continue to parse */
681 } 686 }
682 term->type = p1[2] << 16; /* virtual type */ 687 term->type = d->bDescriptorSubtype << 16; /* virtual type */
683 term->channels = p1[7 + p1[6]]; 688 term->channels = uac_processing_unit_bNrChannels(d);
684 term->chconfig = combine_word(p1 + 8 + p1[6]); 689 term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
685 term->name = p1[12 + p1[6] + p1[11 + p1[6]]]; 690 term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
686 return 0; 691 return 0;
692 }
687 default: 693 default:
688 return -ENODEV; 694 return -ENODEV;
689 } 695 }
@@ -764,7 +770,8 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
764 int last_valid_res = cval->res; 770 int last_valid_res = cval->res;
765 771
766 while (cval->res > 1) { 772 while (cval->res > 1) {
767 if (set_ctl_value(cval, UAC_SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0) 773 if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
774 (cval->control << 8) | minchn, cval->res / 2) < 0)
768 break; 775 break;
769 cval->res /= 2; 776 cval->res /= 2;
770 } 777 }
@@ -929,6 +936,15 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
929 .put = mixer_ctl_feature_put, 936 .put = mixer_ctl_feature_put,
930}; 937};
931 938
939/* the read-only variant */
940static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
942 .name = "", /* will be filled later manually */
943 .info = mixer_ctl_feature_info,
944 .get = mixer_ctl_feature_get,
945 .put = NULL,
946};
947
932 948
933/* 949/*
934 * build a feature control 950 * build a feature control
@@ -939,20 +955,22 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
939 return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); 955 return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
940} 956}
941 957
942static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, 958static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
943 unsigned int ctl_mask, int control, 959 unsigned int ctl_mask, int control,
944 struct usb_audio_term *iterm, int unitid) 960 struct usb_audio_term *iterm, int unitid,
961 int read_only)
945{ 962{
963 struct uac_feature_unit_descriptor *desc = raw_desc;
946 unsigned int len = 0; 964 unsigned int len = 0;
947 int mapped_name = 0; 965 int mapped_name = 0;
948 int nameid = desc[desc[0] - 1]; 966 int nameid = uac_feature_unit_iFeature(desc);
949 struct snd_kcontrol *kctl; 967 struct snd_kcontrol *kctl;
950 struct usb_mixer_elem_info *cval; 968 struct usb_mixer_elem_info *cval;
951 const struct usbmix_name_map *map; 969 const struct usbmix_name_map *map;
952 970
953 control++; /* change from zero-based to 1-based value */ 971 control++; /* change from zero-based to 1-based value */
954 972
955 if (control == USB_FEATURE_GEQ) { 973 if (control == UAC_GRAPHIC_EQUALIZER_CONTROL) {
956 /* FIXME: not supported yet */ 974 /* FIXME: not supported yet */
957 return; 975 return;
958 } 976 }
@@ -984,7 +1002,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
984 /* get min/max values */ 1002 /* get min/max values */
985 get_min_max(cval, 0); 1003 get_min_max(cval, 0);
986 1004
987 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1005 if (read_only)
1006 kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
1007 else
1008 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
1009
988 if (! kctl) { 1010 if (! kctl) {
989 snd_printk(KERN_ERR "cannot malloc kcontrol\n"); 1011 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
990 kfree(cval); 1012 kfree(cval);
@@ -999,8 +1021,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
999 kctl->id.name, sizeof(kctl->id.name)); 1021 kctl->id.name, sizeof(kctl->id.name));
1000 1022
1001 switch (control) { 1023 switch (control) {
1002 case USB_FEATURE_MUTE: 1024 case UAC_MUTE_CONTROL:
1003 case USB_FEATURE_VOLUME: 1025 case UAC_VOLUME_CONTROL:
1004 /* determine the control name. the rule is: 1026 /* determine the control name. the rule is:
1005 * - if a name id is given in descriptor, use it. 1027 * - if a name id is given in descriptor, use it.
1006 * - if the connected input can be determined, then use the name 1028 * - if the connected input can be determined, then use the name
@@ -1027,9 +1049,9 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
1027 len = append_ctl_name(kctl, " Playback"); 1049 len = append_ctl_name(kctl, " Playback");
1028 } 1050 }
1029 } 1051 }
1030 append_ctl_name(kctl, control == USB_FEATURE_MUTE ? 1052 append_ctl_name(kctl, control == UAC_MUTE_CONTROL ?
1031 " Switch" : " Volume"); 1053 " Switch" : " Volume");
1032 if (control == USB_FEATURE_VOLUME) { 1054 if (control == UAC_VOLUME_CONTROL) {
1033 kctl->tlv.c = mixer_vol_tlv; 1055 kctl->tlv.c = mixer_vol_tlv;
1034 kctl->vd[0].access |= 1056 kctl->vd[0].access |=
1035 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1057 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -1094,49 +1116,92 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1094 struct usb_audio_term iterm; 1116 struct usb_audio_term iterm;
1095 unsigned int master_bits, first_ch_bits; 1117 unsigned int master_bits, first_ch_bits;
1096 int err, csize; 1118 int err, csize;
1097 struct uac_feature_unit_descriptor *ftr = _ftr; 1119 struct uac_feature_unit_descriptor *hdr = _ftr;
1120 __u8 *bmaControls;
1121
1122 if (state->mixer->protocol == UAC_VERSION_1) {
1123 csize = hdr->bControlSize;
1124 channels = (hdr->bLength - 7) / csize - 1;
1125 bmaControls = hdr->bmaControls;
1126 } else {
1127 struct uac2_feature_unit_descriptor *ftr = _ftr;
1128 csize = 4;
1129 channels = (hdr->bLength - 6) / 4;
1130 bmaControls = ftr->bmaControls;
1131 }
1098 1132
1099 if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) { 1133 if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) {
1100 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid); 1134 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
1101 return -EINVAL; 1135 return -EINVAL;
1102 } 1136 }
1103 1137
1104 /* parse the source unit */ 1138 /* parse the source unit */
1105 if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0) 1139 if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
1106 return err; 1140 return err;
1107 1141
1108 /* determine the input source type and name */ 1142 /* determine the input source type and name */
1109 if (check_input_term(state, ftr->bSourceID, &iterm) < 0) 1143 if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
1110 return -EINVAL; 1144 return -EINVAL;
1111 1145
1112 channels = (ftr->bLength - 7) / csize - 1; 1146 master_bits = snd_usb_combine_bytes(bmaControls, csize);
1113
1114 master_bits = snd_usb_combine_bytes(ftr->controls, csize);
1115 /* master configuration quirks */ 1147 /* master configuration quirks */
1116 switch (state->chip->usb_id) { 1148 switch (state->chip->usb_id) {
1117 case USB_ID(0x08bb, 0x2702): 1149 case USB_ID(0x08bb, 0x2702):
1118 snd_printk(KERN_INFO 1150 snd_printk(KERN_INFO
1119 "usbmixer: master volume quirk for PCM2702 chip\n"); 1151 "usbmixer: master volume quirk for PCM2702 chip\n");
1120 /* disable non-functional volume control */ 1152 /* disable non-functional volume control */
1121 master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1)); 1153 master_bits &= ~UAC_FU_VOLUME;
1122 break; 1154 break;
1123 } 1155 }
1124 if (channels > 0) 1156 if (channels > 0)
1125 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize); 1157 first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
1126 else 1158 else
1127 first_ch_bits = 0; 1159 first_ch_bits = 0;
1128 /* check all control types */ 1160
1129 for (i = 0; i < 10; i++) { 1161 if (state->mixer->protocol == UAC_VERSION_1) {
1130 unsigned int ch_bits = 0; 1162 /* check all control types */
1131 for (j = 0; j < channels; j++) { 1163 for (i = 0; i < 10; i++) {
1132 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize); 1164 unsigned int ch_bits = 0;
1133 if (mask & (1 << i)) 1165 for (j = 0; j < channels; j++) {
1134 ch_bits |= (1 << j); 1166 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1167 if (mask & (1 << i))
1168 ch_bits |= (1 << j);
1169 }
1170 /* audio class v1 controls are never read-only */
1171 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1172 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
1173 if (master_bits & (1 << i))
1174 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
1175 }
1176 } else { /* UAC_VERSION_2 */
1177 for (i = 0; i < 30/2; i++) {
1178 /* From the USB Audio spec v2.0:
1179 bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
1180 each containing a set of bit pairs. If a Control is present,
1181 it must be Host readable. If a certain Control is not
1182 present then the bit pair must be set to 0b00.
1183 If a Control is present but read-only, the bit pair must be
1184 set to 0b01. If a Control is also Host programmable, the bit
1185 pair must be set to 0b11. The value 0b10 is not allowed. */
1186 unsigned int ch_bits = 0;
1187 unsigned int ch_read_only = 0;
1188
1189 for (j = 0; j < channels; j++) {
1190 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1191 if (mask & (1 << (i * 2))) {
1192 ch_bits |= (1 << j);
1193 if (~mask & (1 << ((i * 2) + 1)))
1194 ch_read_only |= (1 << j);
1195 }
1196 }
1197
1198 /* FIXME: the whole unit is read-only if any of the channels is marked read-only */
1199 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1200 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, !!ch_read_only);
1201 if (master_bits & (1 << i * 2))
1202 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
1203 ~master_bits & (1 << ((i * 2) + 1)));
1135 } 1204 }
1136 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1137 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid);
1138 if (master_bits & (1 << i))
1139 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid);
1140 } 1205 }
1141 1206
1142 return 0; 1207 return 0;
@@ -1154,13 +1219,13 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1154 * input channel number (zero based) is given in control field instead. 1219 * input channel number (zero based) is given in control field instead.
1155 */ 1220 */
1156 1221
1157static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, 1222static void build_mixer_unit_ctl(struct mixer_build *state,
1223 struct uac_mixer_unit_descriptor *desc,
1158 int in_pin, int in_ch, int unitid, 1224 int in_pin, int in_ch, int unitid,
1159 struct usb_audio_term *iterm) 1225 struct usb_audio_term *iterm)
1160{ 1226{
1161 struct usb_mixer_elem_info *cval; 1227 struct usb_mixer_elem_info *cval;
1162 unsigned int input_pins = desc[4]; 1228 unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
1163 unsigned int num_outs = desc[5 + input_pins];
1164 unsigned int i, len; 1229 unsigned int i, len;
1165 struct snd_kcontrol *kctl; 1230 struct snd_kcontrol *kctl;
1166 const struct usbmix_name_map *map; 1231 const struct usbmix_name_map *map;
@@ -1178,7 +1243,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1178 cval->control = in_ch + 1; /* based on 1 */ 1243 cval->control = in_ch + 1; /* based on 1 */
1179 cval->val_type = USB_MIXER_S16; 1244 cval->val_type = USB_MIXER_S16;
1180 for (i = 0; i < num_outs; i++) { 1245 for (i = 0; i < num_outs; i++) {
1181 if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) { 1246 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
1182 cval->cmask |= (1 << i); 1247 cval->cmask |= (1 << i);
1183 cval->channels++; 1248 cval->channels++;
1184 } 1249 }
@@ -1211,18 +1276,19 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1211/* 1276/*
1212 * parse a mixer unit 1277 * parse a mixer unit
1213 */ 1278 */
1214static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1279static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
1215{ 1280{
1281 struct uac_mixer_unit_descriptor *desc = raw_desc;
1216 struct usb_audio_term iterm; 1282 struct usb_audio_term iterm;
1217 int input_pins, num_ins, num_outs; 1283 int input_pins, num_ins, num_outs;
1218 int pin, ich, err; 1284 int pin, ich, err;
1219 1285
1220 if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) { 1286 if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
1221 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid); 1287 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
1222 return -EINVAL; 1288 return -EINVAL;
1223 } 1289 }
1224 /* no bmControls field (e.g. Maya44) -> ignore */ 1290 /* no bmControls field (e.g. Maya44) -> ignore */
1225 if (desc[0] <= 10 + input_pins) { 1291 if (desc->bLength <= 10 + input_pins) {
1226 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid); 1292 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
1227 return 0; 1293 return 0;
1228 } 1294 }
@@ -1230,10 +1296,10 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1230 num_ins = 0; 1296 num_ins = 0;
1231 ich = 0; 1297 ich = 0;
1232 for (pin = 0; pin < input_pins; pin++) { 1298 for (pin = 0; pin < input_pins; pin++) {
1233 err = parse_audio_unit(state, desc[5 + pin]); 1299 err = parse_audio_unit(state, desc->baSourceID[pin]);
1234 if (err < 0) 1300 if (err < 0)
1235 return err; 1301 return err;
1236 err = check_input_term(state, desc[5 + pin], &iterm); 1302 err = check_input_term(state, desc->baSourceID[pin], &iterm);
1237 if (err < 0) 1303 if (err < 0)
1238 return err; 1304 return err;
1239 num_ins += iterm.channels; 1305 num_ins += iterm.channels;
@@ -1241,7 +1307,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1241 int och, ich_has_controls = 0; 1307 int och, ich_has_controls = 0;
1242 1308
1243 for (och = 0; och < num_outs; ++och) { 1309 for (och = 0; och < num_outs; ++och) {
1244 if (check_matrix_bitmap(desc + 9 + input_pins, 1310 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
1245 ich, och, num_outs)) { 1311 ich, och, num_outs)) {
1246 ich_has_controls = 1; 1312 ich_has_controls = 1;
1247 break; 1313 break;
@@ -1402,9 +1468,10 @@ static struct procunit_info extunits[] = {
1402/* 1468/*
1403 * build a processing/extension unit 1469 * build a processing/extension unit
1404 */ 1470 */
1405static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name) 1471static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
1406{ 1472{
1407 int num_ins = dsc[6]; 1473 struct uac_processing_unit_descriptor *desc = raw_desc;
1474 int num_ins = desc->bNrInPins;
1408 struct usb_mixer_elem_info *cval; 1475 struct usb_mixer_elem_info *cval;
1409 struct snd_kcontrol *kctl; 1476 struct snd_kcontrol *kctl;
1410 int i, err, nameid, type, len; 1477 int i, err, nameid, type, len;
@@ -1419,17 +1486,18 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1419 0, NULL, default_value_info 1486 0, NULL, default_value_info
1420 }; 1487 };
1421 1488
1422 if (dsc[0] < 13 || dsc[0] < 13 + num_ins || dsc[0] < num_ins + dsc[11 + num_ins]) { 1489 if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
1490 desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
1423 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid); 1491 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
1424 return -EINVAL; 1492 return -EINVAL;
1425 } 1493 }
1426 1494
1427 for (i = 0; i < num_ins; i++) { 1495 for (i = 0; i < num_ins; i++) {
1428 if ((err = parse_audio_unit(state, dsc[7 + i])) < 0) 1496 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1429 return err; 1497 return err;
1430 } 1498 }
1431 1499
1432 type = combine_word(&dsc[4]); 1500 type = le16_to_cpu(desc->wProcessType);
1433 for (info = list; info && info->type; info++) 1501 for (info = list; info && info->type; info++)
1434 if (info->type == type) 1502 if (info->type == type)
1435 break; 1503 break;
@@ -1437,8 +1505,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1437 info = &default_info; 1505 info = &default_info;
1438 1506
1439 for (valinfo = info->values; valinfo->control; valinfo++) { 1507 for (valinfo = info->values; valinfo->control; valinfo++) {
1440 /* FIXME: bitmap might be longer than 8bit */ 1508 __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
1441 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) 1509
1510 if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
1442 continue; 1511 continue;
1443 map = find_map(state, unitid, valinfo->control); 1512 map = find_map(state, unitid, valinfo->control);
1444 if (check_ignored_ctl(map)) 1513 if (check_ignored_ctl(map))
@@ -1456,9 +1525,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1456 1525
1457 /* get min/max values */ 1526 /* get min/max values */
1458 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) { 1527 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) {
1528 __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
1459 /* FIXME: hard-coded */ 1529 /* FIXME: hard-coded */
1460 cval->min = 1; 1530 cval->min = 1;
1461 cval->max = dsc[15]; 1531 cval->max = control_spec[0];
1462 cval->res = 1; 1532 cval->res = 1;
1463 cval->initialized = 1; 1533 cval->initialized = 1;
1464 } else { 1534 } else {
@@ -1488,7 +1558,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1488 else if (info->name) 1558 else if (info->name)
1489 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); 1559 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1490 else { 1560 else {
1491 nameid = dsc[12 + num_ins + dsc[11 + num_ins]]; 1561 nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
1492 len = 0; 1562 len = 0;
1493 if (nameid) 1563 if (nameid)
1494 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); 1564 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
@@ -1507,14 +1577,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1507} 1577}
1508 1578
1509 1579
1510static int parse_audio_processing_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1580static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
1511{ 1581{
1512 return build_audio_procunit(state, unitid, desc, procunits, "Processing Unit"); 1582 return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
1513} 1583}
1514 1584
1515static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1585static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
1516{ 1586{
1517 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit"); 1587 /* Note that we parse extension units with processing unit descriptors.
1588 * That's ok as the layout is the same */
1589 return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
1518} 1590}
1519 1591
1520 1592
@@ -1616,9 +1688,9 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
1616/* 1688/*
1617 * parse a selector unit 1689 * parse a selector unit
1618 */ 1690 */
1619static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1691static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
1620{ 1692{
1621 unsigned int num_ins = desc[4]; 1693 struct uac_selector_unit_descriptor *desc = raw_desc;
1622 unsigned int i, nameid, len; 1694 unsigned int i, nameid, len;
1623 int err; 1695 int err;
1624 struct usb_mixer_elem_info *cval; 1696 struct usb_mixer_elem_info *cval;
@@ -1626,17 +1698,17 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1626 const struct usbmix_name_map *map; 1698 const struct usbmix_name_map *map;
1627 char **namelist; 1699 char **namelist;
1628 1700
1629 if (! num_ins || desc[0] < 5 + num_ins) { 1701 if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
1630 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid); 1702 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
1631 return -EINVAL; 1703 return -EINVAL;
1632 } 1704 }
1633 1705
1634 for (i = 0; i < num_ins; i++) { 1706 for (i = 0; i < desc->bNrInPins; i++) {
1635 if ((err = parse_audio_unit(state, desc[5 + i])) < 0) 1707 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1636 return err; 1708 return err;
1637 } 1709 }
1638 1710
1639 if (num_ins == 1) /* only one ? nonsense! */ 1711 if (desc->bNrInPins == 1) /* only one ? nonsense! */
1640 return 0; 1712 return 0;
1641 1713
1642 map = find_map(state, unitid, 0); 1714 map = find_map(state, unitid, 0);
@@ -1653,18 +1725,18 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1653 cval->val_type = USB_MIXER_U8; 1725 cval->val_type = USB_MIXER_U8;
1654 cval->channels = 1; 1726 cval->channels = 1;
1655 cval->min = 1; 1727 cval->min = 1;
1656 cval->max = num_ins; 1728 cval->max = desc->bNrInPins;
1657 cval->res = 1; 1729 cval->res = 1;
1658 cval->initialized = 1; 1730 cval->initialized = 1;
1659 1731
1660 namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL); 1732 namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
1661 if (! namelist) { 1733 if (! namelist) {
1662 snd_printk(KERN_ERR "cannot malloc\n"); 1734 snd_printk(KERN_ERR "cannot malloc\n");
1663 kfree(cval); 1735 kfree(cval);
1664 return -ENOMEM; 1736 return -ENOMEM;
1665 } 1737 }
1666#define MAX_ITEM_NAME_LEN 64 1738#define MAX_ITEM_NAME_LEN 64
1667 for (i = 0; i < num_ins; i++) { 1739 for (i = 0; i < desc->bNrInPins; i++) {
1668 struct usb_audio_term iterm; 1740 struct usb_audio_term iterm;
1669 len = 0; 1741 len = 0;
1670 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); 1742 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
@@ -1678,7 +1750,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1678 } 1750 }
1679 len = check_mapped_selector_name(state, unitid, i, namelist[i], 1751 len = check_mapped_selector_name(state, unitid, i, namelist[i],
1680 MAX_ITEM_NAME_LEN); 1752 MAX_ITEM_NAME_LEN);
1681 if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0) 1753 if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
1682 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); 1754 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
1683 if (! len) 1755 if (! len)
1684 sprintf(namelist[i], "Input %d", i); 1756 sprintf(namelist[i], "Input %d", i);
@@ -1694,7 +1766,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1694 kctl->private_value = (unsigned long)namelist; 1766 kctl->private_value = (unsigned long)namelist;
1695 kctl->private_free = usb_mixer_selector_elem_free; 1767 kctl->private_free = usb_mixer_selector_elem_free;
1696 1768
1697 nameid = desc[desc[0] - 1]; 1769 nameid = uac_selector_unit_iSelector(desc);
1698 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 1770 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1699 if (len) 1771 if (len)
1700 ; 1772 ;
@@ -1713,7 +1785,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1713 } 1785 }
1714 1786
1715 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", 1787 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
1716 cval->id, kctl->id.name, num_ins); 1788 cval->id, kctl->id.name, desc->bNrInPins);
1717 if ((err = add_control_to_empty(state, kctl)) < 0) 1789 if ((err = add_control_to_empty(state, kctl)) < 0)
1718 return err; 1790 return err;
1719 1791
@@ -1748,9 +1820,17 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1748 case UAC_FEATURE_UNIT: 1820 case UAC_FEATURE_UNIT:
1749 return parse_audio_feature_unit(state, unitid, p1); 1821 return parse_audio_feature_unit(state, unitid, p1);
1750 case UAC_PROCESSING_UNIT_V1: 1822 case UAC_PROCESSING_UNIT_V1:
1751 return parse_audio_processing_unit(state, unitid, p1); 1823 /* UAC2_EFFECT_UNIT has the same value */
1824 if (state->mixer->protocol == UAC_VERSION_1)
1825 return parse_audio_processing_unit(state, unitid, p1);
1826 else
1827 return 0; /* FIXME - effect units not implemented yet */
1752 case UAC_EXTENSION_UNIT_V1: 1828 case UAC_EXTENSION_UNIT_V1:
1753 return parse_audio_extension_unit(state, unitid, p1); 1829 /* UAC2_PROCESSING_UNIT_V2 has the same value */
1830 if (state->mixer->protocol == UAC_VERSION_1)
1831 return parse_audio_extension_unit(state, unitid, p1);
1832 else /* UAC_VERSION_2 */
1833 return parse_audio_processing_unit(state, unitid, p1);
1754 default: 1834 default:
1755 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); 1835 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
1756 return -EINVAL; 1836 return -EINVAL;
@@ -1783,11 +1863,11 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
1783 */ 1863 */
1784static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) 1864static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1785{ 1865{
1786 struct uac_output_terminal_descriptor_v1 *desc;
1787 struct mixer_build state; 1866 struct mixer_build state;
1788 int err; 1867 int err;
1789 const struct usbmix_ctl_map *map; 1868 const struct usbmix_ctl_map *map;
1790 struct usb_host_interface *hostif; 1869 struct usb_host_interface *hostif;
1870 void *p;
1791 1871
1792 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; 1872 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
1793 memset(&state, 0, sizeof(state)); 1873 memset(&state, 0, sizeof(state));
@@ -1806,23 +1886,39 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1806 } 1886 }
1807 } 1887 }
1808 1888
1809 desc = NULL; 1889 p = NULL;
1810 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, UAC_OUTPUT_TERMINAL)) != NULL) { 1890 while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
1811 if (desc->bLength < 9) 1891 if (mixer->protocol == UAC_VERSION_1) {
1812 continue; /* invalid descriptor? */ 1892 struct uac_output_terminal_descriptor_v1 *desc = p;
1813 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */ 1893
1814 state.oterm.id = desc->bTerminalID; 1894 if (desc->bLength < sizeof(*desc))
1815 state.oterm.type = le16_to_cpu(desc->wTerminalType); 1895 continue; /* invalid descriptor? */
1816 state.oterm.name = desc->iTerminal; 1896 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1817 err = parse_audio_unit(&state, desc->bSourceID); 1897 state.oterm.id = desc->bTerminalID;
1818 if (err < 0) 1898 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1819 return err; 1899 state.oterm.name = desc->iTerminal;
1900 err = parse_audio_unit(&state, desc->bSourceID);
1901 if (err < 0)
1902 return err;
1903 } else { /* UAC_VERSION_2 */
1904 struct uac2_output_terminal_descriptor *desc = p;
1905
1906 if (desc->bLength < sizeof(*desc))
1907 continue; /* invalid descriptor? */
1908 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1909 state.oterm.id = desc->bTerminalID;
1910 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1911 state.oterm.name = desc->iTerminal;
1912 err = parse_audio_unit(&state, desc->bSourceID);
1913 if (err < 0)
1914 return err;
1915 }
1820 } 1916 }
1917
1821 return 0; 1918 return 0;
1822} 1919}
1823 1920
1824static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, 1921void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
1825 int unitid)
1826{ 1922{
1827 struct usb_mixer_elem_info *info; 1923 struct usb_mixer_elem_info *info;
1828 1924
@@ -1871,34 +1967,6 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
1871 } 1967 }
1872} 1968}
1873 1969
1874static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
1875 int unitid)
1876{
1877 if (!mixer->rc_cfg)
1878 return;
1879 /* unit ids specific to Extigy/Audigy 2 NX: */
1880 switch (unitid) {
1881 case 0: /* remote control */
1882 mixer->rc_urb->dev = mixer->chip->dev;
1883 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
1884 break;
1885 case 4: /* digital in jack */
1886 case 7: /* line in jacks */
1887 case 19: /* speaker out jacks */
1888 case 20: /* headphones out jack */
1889 break;
1890 /* live24ext: 4 = line-in jack */
1891 case 3: /* hp-out jack (may actuate Mute) */
1892 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
1893 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
1894 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
1895 break;
1896 default:
1897 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
1898 break;
1899 }
1900}
1901
1902static void snd_usb_mixer_status_complete(struct urb *urb) 1970static void snd_usb_mixer_status_complete(struct urb *urb)
1903{ 1971{
1904 struct usb_mixer_interface *mixer = urb->context; 1972 struct usb_mixer_interface *mixer = urb->context;
@@ -1916,7 +1984,7 @@ static void snd_usb_mixer_status_complete(struct urb *urb)
1916 if (!(buf[0] & 0x40)) 1984 if (!(buf[0] & 0x40))
1917 snd_usb_mixer_notify_id(mixer, buf[1]); 1985 snd_usb_mixer_notify_id(mixer, buf[1]);
1918 else 1986 else
1919 snd_usb_mixer_memory_change(mixer, buf[1]); 1987 snd_usb_mixer_rc_memory_change(mixer, buf[1]);
1920 } 1988 }
1921 } 1989 }
1922 if (urb->status != -ENOENT && urb->status != -ECONNRESET) { 1990 if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
@@ -1960,296 +2028,6 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
1960 return 0; 2028 return 0;
1961} 2029}
1962 2030
1963static void snd_usb_soundblaster_remote_complete(struct urb *urb)
1964{
1965 struct usb_mixer_interface *mixer = urb->context;
1966 const struct rc_config *rc = mixer->rc_cfg;
1967 u32 code;
1968
1969 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
1970 return;
1971
1972 code = mixer->rc_buffer[rc->offset];
1973 if (rc->length == 2)
1974 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1975
1976 /* the Mute button actually changes the mixer control */
1977 if (code == rc->mute_code)
1978 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
1979 mixer->rc_code = code;
1980 wmb();
1981 wake_up(&mixer->rc_waitq);
1982}
1983
1984static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
1985 long count, loff_t *offset)
1986{
1987 struct usb_mixer_interface *mixer = hw->private_data;
1988 int err;
1989 u32 rc_code;
1990
1991 if (count != 1 && count != 4)
1992 return -EINVAL;
1993 err = wait_event_interruptible(mixer->rc_waitq,
1994 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
1995 if (err == 0) {
1996 if (count == 1)
1997 err = put_user(rc_code, buf);
1998 else
1999 err = put_user(rc_code, (u32 __user *)buf);
2000 }
2001 return err < 0 ? err : count;
2002}
2003
2004static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
2005 poll_table *wait)
2006{
2007 struct usb_mixer_interface *mixer = hw->private_data;
2008
2009 poll_wait(file, &mixer->rc_waitq, wait);
2010 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
2011}
2012
2013static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
2014{
2015 struct snd_hwdep *hwdep;
2016 int err, len, i;
2017
2018 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
2019 if (rc_configs[i].usb_id == mixer->chip->usb_id)
2020 break;
2021 if (i >= ARRAY_SIZE(rc_configs))
2022 return 0;
2023 mixer->rc_cfg = &rc_configs[i];
2024
2025 len = mixer->rc_cfg->packet_length;
2026
2027 init_waitqueue_head(&mixer->rc_waitq);
2028 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
2029 if (err < 0)
2030 return err;
2031 snprintf(hwdep->name, sizeof(hwdep->name),
2032 "%s remote control", mixer->chip->card->shortname);
2033 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
2034 hwdep->private_data = mixer;
2035 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
2036 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
2037 hwdep->exclusive = 1;
2038
2039 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
2040 if (!mixer->rc_urb)
2041 return -ENOMEM;
2042 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
2043 if (!mixer->rc_setup_packet) {
2044 usb_free_urb(mixer->rc_urb);
2045 mixer->rc_urb = NULL;
2046 return -ENOMEM;
2047 }
2048 mixer->rc_setup_packet->bRequestType =
2049 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2050 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
2051 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
2052 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
2053 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
2054 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
2055 usb_rcvctrlpipe(mixer->chip->dev, 0),
2056 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
2057 snd_usb_soundblaster_remote_complete, mixer);
2058 return 0;
2059}
2060
2061#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
2062
2063static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2064{
2065 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2066 int index = kcontrol->private_value;
2067
2068 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
2069 return 0;
2070}
2071
2072static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2073{
2074 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2075 int index = kcontrol->private_value;
2076 int value = ucontrol->value.integer.value[0];
2077 int err, changed;
2078
2079 if (value > 1)
2080 return -EINVAL;
2081 changed = value != mixer->audigy2nx_leds[index];
2082 err = snd_usb_ctl_msg(mixer->chip->dev,
2083 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
2084 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
2085 value, index + 2, NULL, 0, 100);
2086 if (err < 0)
2087 return err;
2088 mixer->audigy2nx_leds[index] = value;
2089 return changed;
2090}
2091
2092static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
2093 {
2094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2095 .name = "CMSS LED Switch",
2096 .info = snd_audigy2nx_led_info,
2097 .get = snd_audigy2nx_led_get,
2098 .put = snd_audigy2nx_led_put,
2099 .private_value = 0,
2100 },
2101 {
2102 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2103 .name = "Power LED Switch",
2104 .info = snd_audigy2nx_led_info,
2105 .get = snd_audigy2nx_led_get,
2106 .put = snd_audigy2nx_led_put,
2107 .private_value = 1,
2108 },
2109 {
2110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2111 .name = "Dolby Digital LED Switch",
2112 .info = snd_audigy2nx_led_info,
2113 .get = snd_audigy2nx_led_get,
2114 .put = snd_audigy2nx_led_put,
2115 .private_value = 2,
2116 },
2117};
2118
2119static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
2120{
2121 int i, err;
2122
2123 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
2124 if (i > 1 && /* Live24ext has 2 LEDs only */
2125 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2126 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
2127 break;
2128 err = snd_ctl_add(mixer->chip->card,
2129 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
2130 if (err < 0)
2131 return err;
2132 }
2133 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
2134 return 0;
2135}
2136
2137static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
2138 struct snd_info_buffer *buffer)
2139{
2140 static const struct sb_jack {
2141 int unitid;
2142 const char *name;
2143 } jacks_audigy2nx[] = {
2144 {4, "dig in "},
2145 {7, "line in"},
2146 {19, "spk out"},
2147 {20, "hph out"},
2148 {-1, NULL}
2149 }, jacks_live24ext[] = {
2150 {4, "line in"}, /* &1=Line, &2=Mic*/
2151 {3, "hph out"}, /* headphones */
2152 {0, "RC "}, /* last command, 6 bytes see rc_config above */
2153 {-1, NULL}
2154 };
2155 const struct sb_jack *jacks;
2156 struct usb_mixer_interface *mixer = entry->private_data;
2157 int i, err;
2158 u8 buf[3];
2159
2160 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
2161 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
2162 jacks = jacks_audigy2nx;
2163 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2164 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
2165 jacks = jacks_live24ext;
2166 else
2167 return;
2168
2169 for (i = 0; jacks[i].name; ++i) {
2170 snd_iprintf(buffer, "%s: ", jacks[i].name);
2171 err = snd_usb_ctl_msg(mixer->chip->dev,
2172 usb_rcvctrlpipe(mixer->chip->dev, 0),
2173 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
2174 USB_RECIP_INTERFACE, 0,
2175 jacks[i].unitid << 8, buf, 3, 100);
2176 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
2177 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
2178 else
2179 snd_iprintf(buffer, "?\n");
2180 }
2181}
2182
2183static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
2184 struct snd_ctl_elem_value *ucontrol)
2185{
2186 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2187
2188 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
2189 return 0;
2190}
2191
2192static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
2193 struct snd_ctl_elem_value *ucontrol)
2194{
2195 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2196 u8 old_status, new_status;
2197 int err, changed;
2198
2199 old_status = mixer->xonar_u1_status;
2200 if (ucontrol->value.integer.value[0])
2201 new_status = old_status | 0x02;
2202 else
2203 new_status = old_status & ~0x02;
2204 changed = new_status != old_status;
2205 err = snd_usb_ctl_msg(mixer->chip->dev,
2206 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
2207 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
2208 50, 0, &new_status, 1, 100);
2209 if (err < 0)
2210 return err;
2211 mixer->xonar_u1_status = new_status;
2212 return changed;
2213}
2214
2215static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
2216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2217 .name = "Digital Playback Switch",
2218 .info = snd_ctl_boolean_mono_info,
2219 .get = snd_xonar_u1_switch_get,
2220 .put = snd_xonar_u1_switch_put,
2221};
2222
2223static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
2224{
2225 int err;
2226
2227 err = snd_ctl_add(mixer->chip->card,
2228 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
2229 if (err < 0)
2230 return err;
2231 mixer->xonar_u1_status = 0x05;
2232 return 0;
2233}
2234
2235void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
2236 unsigned char samplerate_id)
2237{
2238 struct usb_mixer_interface *mixer;
2239 struct usb_mixer_elem_info *cval;
2240 int unitid = 12; /* SamleRate ExtensionUnit ID */
2241
2242 list_for_each_entry(mixer, &chip->mixer_list, list) {
2243 cval = mixer->id_elems[unitid];
2244 if (cval) {
2245 set_cur_ctl_value(cval, cval->control << 8,
2246 samplerate_id);
2247 snd_usb_mixer_notify_id(mixer, unitid);
2248 }
2249 break;
2250 }
2251}
2252
2253int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 2031int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2254 int ignore_error) 2032 int ignore_error)
2255{ 2033{
@@ -2259,7 +2037,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2259 struct usb_mixer_interface *mixer; 2037 struct usb_mixer_interface *mixer;
2260 struct snd_info_entry *entry; 2038 struct snd_info_entry *entry;
2261 struct usb_host_interface *host_iface; 2039 struct usb_host_interface *host_iface;
2262 int err, protocol; 2040 int err;
2263 2041
2264 strcpy(chip->card->mixername, "USB Mixer"); 2042 strcpy(chip->card->mixername, "USB Mixer");
2265 2043
@@ -2277,38 +2055,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2277 } 2055 }
2278 2056
2279 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; 2057 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
2280 protocol = host_iface->desc.bInterfaceProtocol; 2058 mixer->protocol = get_iface_desc(host_iface)->bInterfaceProtocol;
2281
2282 /* FIXME! */
2283 if (protocol != UAC_VERSION_1) {
2284 snd_printk(KERN_WARNING "mixer interface protocol 0x%02x not yet supported\n",
2285 protocol);
2286 return 0;
2287 }
2288 2059
2289 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 2060 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
2290 (err = snd_usb_mixer_status_create(mixer)) < 0) 2061 (err = snd_usb_mixer_status_create(mixer)) < 0)
2291 goto _error; 2062 goto _error;
2292 2063
2293 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) 2064 snd_usb_mixer_apply_create_quirk(mixer);
2294 goto _error;
2295
2296 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2297 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2298 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
2299 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
2300 goto _error;
2301 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
2302 snd_info_set_text_ops(entry, mixer,
2303 snd_audigy2nx_proc_read);
2304 }
2305
2306 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
2307 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
2308 err = snd_xonar_u1_controls_create(mixer);
2309 if (err < 0)
2310 goto _error;
2311 }
2312 2065
2313 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); 2066 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
2314 if (err < 0) 2067 if (err < 0)
@@ -2329,7 +2082,7 @@ _error:
2329void snd_usb_mixer_disconnect(struct list_head *p) 2082void snd_usb_mixer_disconnect(struct list_head *p)
2330{ 2083{
2331 struct usb_mixer_interface *mixer; 2084 struct usb_mixer_interface *mixer;
2332 2085
2333 mixer = list_entry(p, struct usb_mixer_interface, list); 2086 mixer = list_entry(p, struct usb_mixer_interface, list);
2334 usb_kill_urb(mixer->urb); 2087 usb_kill_urb(mixer->urb);
2335 usb_kill_urb(mixer->rc_urb); 2088 usb_kill_urb(mixer->rc_urb);
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
new file mode 100644
index 000000000000..130123854a6c
--- /dev/null
+++ b/sound/usb/mixer.h
@@ -0,0 +1,55 @@
1#ifndef __USBMIXER_H
2#define __USBMIXER_H
3
4struct usb_mixer_interface {
5 struct snd_usb_audio *chip;
6 unsigned int ctrlif;
7 struct list_head list;
8 unsigned int ignore_ctl_error;
9 struct urb *urb;
10 /* array[MAX_ID_ELEMS], indexed by unit id */
11 struct usb_mixer_elem_info **id_elems;
12
13 /* the usb audio specification version this interface complies to */
14 int protocol;
15
16 /* Sound Blaster remote control stuff */
17 const struct rc_config *rc_cfg;
18 u32 rc_code;
19 wait_queue_head_t rc_waitq;
20 struct urb *rc_urb;
21 struct usb_ctrlrequest *rc_setup_packet;
22 u8 rc_buffer[6];
23
24 u8 audigy2nx_leds[3];
25 u8 xonar_u1_status;
26};
27
28#define MAX_CHANNELS 10 /* max logical channels */
29
30struct usb_mixer_elem_info {
31 struct usb_mixer_interface *mixer;
32 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
33 struct snd_ctl_elem_id *elem_id;
34 unsigned int id;
35 unsigned int control; /* CS or ICN (high byte) */
36 unsigned int cmask; /* channel mask bitmap: 0 = master */
37 int channels;
38 int val_type;
39 int min, max, res;
40 int dBmin, dBmax;
41 int cached;
42 int cache_val[MAX_CHANNELS];
43 u8 initialized;
44};
45
46int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
47 int ignore_error);
48void snd_usb_mixer_disconnect(struct list_head *p);
49
50void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
51
52int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
53 int request, int validx, int value_set);
54
55#endif /* __USBMIXER_H */
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/mixer_maps.c
index 79e903a60862..d93fc89beba8 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -85,8 +85,8 @@ static struct usbmix_name_map extigy_map[] = {
85 /* 16: MU (w/o controls) */ 85 /* 16: MU (w/o controls) */
86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */ 86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */
87 { 17, "Channel Routing", 2 }, /* PU: mode select */ 87 { 17, "Channel Routing", 2 }, /* PU: mode select */
88 { 18, "Tone Control - Bass", USB_FEATURE_BASS }, /* FU */ 88 { 18, "Tone Control - Bass", UAC_BASS_CONTROL }, /* FU */
89 { 18, "Tone Control - Treble", USB_FEATURE_TREBLE }, /* FU */ 89 { 18, "Tone Control - Treble", UAC_TREBLE_CONTROL }, /* FU */
90 { 18, "Master Playback" }, /* FU; others */ 90 { 18, "Master Playback" }, /* FU; others */
91 /* 19: OT speaker */ 91 /* 19: OT speaker */
92 /* 20: OT headphone */ 92 /* 20: OT headphone */
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
new file mode 100644
index 000000000000..e7df1e5e3f2e
--- /dev/null
+++ b/sound/usb/mixer_quirks.c
@@ -0,0 +1,412 @@
1/*
2 * USB Audio Driver for ALSA
3 *
4 * Quirks and vendor-specific extensions for mixer interfaces
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/usb.h>
31#include <linux/usb/audio.h>
32
33#include <sound/core.h>
34#include <sound/control.h>
35#include <sound/hwdep.h>
36#include <sound/info.h>
37
38#include "usbaudio.h"
39#include "mixer.h"
40#include "mixer_quirks.h"
41#include "helper.h"
42
43/*
44 * Sound Blaster remote control configuration
45 *
46 * format of remote control data:
47 * Extigy: xx 00
48 * Audigy 2 NX: 06 80 xx 00 00 00
49 * Live! 24-bit: 06 80 xx yy 22 83
50 */
51static const struct rc_config {
52 u32 usb_id;
53 u8 offset;
54 u8 length;
55 u8 packet_length;
56 u8 min_packet_length; /* minimum accepted length of the URB result */
57 u8 mute_mixer_id;
58 u32 mute_code;
59} rc_configs[] = {
60 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
64};
65
66static void snd_usb_soundblaster_remote_complete(struct urb *urb)
67{
68 struct usb_mixer_interface *mixer = urb->context;
69 const struct rc_config *rc = mixer->rc_cfg;
70 u32 code;
71
72 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
73 return;
74
75 code = mixer->rc_buffer[rc->offset];
76 if (rc->length == 2)
77 code |= mixer->rc_buffer[rc->offset + 1] << 8;
78
79 /* the Mute button actually changes the mixer control */
80 if (code == rc->mute_code)
81 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
82 mixer->rc_code = code;
83 wmb();
84 wake_up(&mixer->rc_waitq);
85}
86
87static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
88 long count, loff_t *offset)
89{
90 struct usb_mixer_interface *mixer = hw->private_data;
91 int err;
92 u32 rc_code;
93
94 if (count != 1 && count != 4)
95 return -EINVAL;
96 err = wait_event_interruptible(mixer->rc_waitq,
97 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
98 if (err == 0) {
99 if (count == 1)
100 err = put_user(rc_code, buf);
101 else
102 err = put_user(rc_code, (u32 __user *)buf);
103 }
104 return err < 0 ? err : count;
105}
106
107static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
108 poll_table *wait)
109{
110 struct usb_mixer_interface *mixer = hw->private_data;
111
112 poll_wait(file, &mixer->rc_waitq, wait);
113 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
114}
115
116static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
117{
118 struct snd_hwdep *hwdep;
119 int err, len, i;
120
121 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
122 if (rc_configs[i].usb_id == mixer->chip->usb_id)
123 break;
124 if (i >= ARRAY_SIZE(rc_configs))
125 return 0;
126 mixer->rc_cfg = &rc_configs[i];
127
128 len = mixer->rc_cfg->packet_length;
129
130 init_waitqueue_head(&mixer->rc_waitq);
131 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
132 if (err < 0)
133 return err;
134 snprintf(hwdep->name, sizeof(hwdep->name),
135 "%s remote control", mixer->chip->card->shortname);
136 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
137 hwdep->private_data = mixer;
138 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
139 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
140 hwdep->exclusive = 1;
141
142 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
143 if (!mixer->rc_urb)
144 return -ENOMEM;
145 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
146 if (!mixer->rc_setup_packet) {
147 usb_free_urb(mixer->rc_urb);
148 mixer->rc_urb = NULL;
149 return -ENOMEM;
150 }
151 mixer->rc_setup_packet->bRequestType =
152 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
153 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
154 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
155 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
156 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
157 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
158 usb_rcvctrlpipe(mixer->chip->dev, 0),
159 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
160 snd_usb_soundblaster_remote_complete, mixer);
161 return 0;
162}
163
164#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
165
166static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
167{
168 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
169 int index = kcontrol->private_value;
170
171 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
172 return 0;
173}
174
175static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
176{
177 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
178 int index = kcontrol->private_value;
179 int value = ucontrol->value.integer.value[0];
180 int err, changed;
181
182 if (value > 1)
183 return -EINVAL;
184 changed = value != mixer->audigy2nx_leds[index];
185 err = snd_usb_ctl_msg(mixer->chip->dev,
186 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
187 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
188 value, index + 2, NULL, 0, 100);
189 if (err < 0)
190 return err;
191 mixer->audigy2nx_leds[index] = value;
192 return changed;
193}
194
195static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
196 {
197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
198 .name = "CMSS LED Switch",
199 .info = snd_audigy2nx_led_info,
200 .get = snd_audigy2nx_led_get,
201 .put = snd_audigy2nx_led_put,
202 .private_value = 0,
203 },
204 {
205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
206 .name = "Power LED Switch",
207 .info = snd_audigy2nx_led_info,
208 .get = snd_audigy2nx_led_get,
209 .put = snd_audigy2nx_led_put,
210 .private_value = 1,
211 },
212 {
213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
214 .name = "Dolby Digital LED Switch",
215 .info = snd_audigy2nx_led_info,
216 .get = snd_audigy2nx_led_get,
217 .put = snd_audigy2nx_led_put,
218 .private_value = 2,
219 },
220};
221
222static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
223{
224 int i, err;
225
226 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
227 if (i > 1 && /* Live24ext has 2 LEDs only */
228 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
229 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
230 break;
231 err = snd_ctl_add(mixer->chip->card,
232 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
233 if (err < 0)
234 return err;
235 }
236 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
237 return 0;
238}
239
240static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
241 struct snd_info_buffer *buffer)
242{
243 static const struct sb_jack {
244 int unitid;
245 const char *name;
246 } jacks_audigy2nx[] = {
247 {4, "dig in "},
248 {7, "line in"},
249 {19, "spk out"},
250 {20, "hph out"},
251 {-1, NULL}
252 }, jacks_live24ext[] = {
253 {4, "line in"}, /* &1=Line, &2=Mic*/
254 {3, "hph out"}, /* headphones */
255 {0, "RC "}, /* last command, 6 bytes see rc_config above */
256 {-1, NULL}
257 };
258 const struct sb_jack *jacks;
259 struct usb_mixer_interface *mixer = entry->private_data;
260 int i, err;
261 u8 buf[3];
262
263 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
264 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
265 jacks = jacks_audigy2nx;
266 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
267 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
268 jacks = jacks_live24ext;
269 else
270 return;
271
272 for (i = 0; jacks[i].name; ++i) {
273 snd_iprintf(buffer, "%s: ", jacks[i].name);
274 err = snd_usb_ctl_msg(mixer->chip->dev,
275 usb_rcvctrlpipe(mixer->chip->dev, 0),
276 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
277 USB_RECIP_INTERFACE, 0,
278 jacks[i].unitid << 8, buf, 3, 100);
279 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
280 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
281 else
282 snd_iprintf(buffer, "?\n");
283 }
284}
285
286static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
290
291 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
292 return 0;
293}
294
295static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
297{
298 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
299 u8 old_status, new_status;
300 int err, changed;
301
302 old_status = mixer->xonar_u1_status;
303 if (ucontrol->value.integer.value[0])
304 new_status = old_status | 0x02;
305 else
306 new_status = old_status & ~0x02;
307 changed = new_status != old_status;
308 err = snd_usb_ctl_msg(mixer->chip->dev,
309 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
310 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
311 50, 0, &new_status, 1, 100);
312 if (err < 0)
313 return err;
314 mixer->xonar_u1_status = new_status;
315 return changed;
316}
317
318static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Playback Switch",
321 .info = snd_ctl_boolean_mono_info,
322 .get = snd_xonar_u1_switch_get,
323 .put = snd_xonar_u1_switch_put,
324};
325
326static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
327{
328 int err;
329
330 err = snd_ctl_add(mixer->chip->card,
331 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
332 if (err < 0)
333 return err;
334 mixer->xonar_u1_status = 0x05;
335 return 0;
336}
337
338void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
339 unsigned char samplerate_id)
340{
341 struct usb_mixer_interface *mixer;
342 struct usb_mixer_elem_info *cval;
343 int unitid = 12; /* SamleRate ExtensionUnit ID */
344
345 list_for_each_entry(mixer, &chip->mixer_list, list) {
346 cval = mixer->id_elems[unitid];
347 if (cval) {
348 snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
349 cval->control << 8,
350 samplerate_id);
351 snd_usb_mixer_notify_id(mixer, unitid);
352 }
353 break;
354 }
355}
356
357int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
358{
359 int err;
360 struct snd_info_entry *entry;
361
362 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
363 return err;
364
365 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
366 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
367 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
368 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
369 return err;
370 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
371 snd_info_set_text_ops(entry, mixer,
372 snd_audigy2nx_proc_read);
373 }
374
375 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
376 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
377 err = snd_xonar_u1_controls_create(mixer);
378 if (err < 0)
379 return err;
380 }
381
382 return 0;
383}
384
385void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
386 int unitid)
387{
388 if (!mixer->rc_cfg)
389 return;
390 /* unit ids specific to Extigy/Audigy 2 NX: */
391 switch (unitid) {
392 case 0: /* remote control */
393 mixer->rc_urb->dev = mixer->chip->dev;
394 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
395 break;
396 case 4: /* digital in jack */
397 case 7: /* line in jacks */
398 case 19: /* speaker out jacks */
399 case 20: /* headphones out jack */
400 break;
401 /* live24ext: 4 = line-in jack */
402 case 3: /* hp-out jack (may actuate Mute) */
403 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
404 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
405 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
406 break;
407 default:
408 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
409 break;
410 }
411}
412
diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h
new file mode 100644
index 000000000000..bdbfab093816
--- /dev/null
+++ b/sound/usb/mixer_quirks.h
@@ -0,0 +1,13 @@
1#ifndef SND_USB_MIXER_QUIRKS_H
2#define SND_USB_MIXER_QUIRKS_H
3
4int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer);
5
6void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
7 unsigned char samplerate_id);
8
9void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
10 int unitid);
11
12#endif /* SND_USB_MIXER_QUIRKS_H */
13
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
new file mode 100644
index 000000000000..2bf0d77d1768
--- /dev/null
+++ b/sound/usb/pcm.c
@@ -0,0 +1,935 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
21#include <linux/usb/audio-v2.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "quirks.h"
30#include "debug.h"
31#include "urb.h"
32#include "helper.h"
33#include "pcm.h"
34
35/*
36 * return the current pcm pointer. just based on the hwptr_done value.
37 */
38static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
39{
40 struct snd_usb_substream *subs;
41 unsigned int hwptr_done;
42
43 subs = (struct snd_usb_substream *)substream->runtime->private_data;
44 spin_lock(&subs->lock);
45 hwptr_done = subs->hwptr_done;
46 spin_unlock(&subs->lock);
47 return hwptr_done / (substream->runtime->frame_bits >> 3);
48}
49
50/*
51 * find a matching audio format
52 */
53static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
54 unsigned int rate, unsigned int channels)
55{
56 struct list_head *p;
57 struct audioformat *found = NULL;
58 int cur_attr = 0, attr;
59
60 list_for_each(p, &subs->fmt_list) {
61 struct audioformat *fp;
62 fp = list_entry(p, struct audioformat, list);
63 if (!(fp->formats & (1uLL << format)))
64 continue;
65 if (fp->channels != channels)
66 continue;
67 if (rate < fp->rate_min || rate > fp->rate_max)
68 continue;
69 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
70 unsigned int i;
71 for (i = 0; i < fp->nr_rates; i++)
72 if (fp->rate_table[i] == rate)
73 break;
74 if (i >= fp->nr_rates)
75 continue;
76 }
77 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
78 if (! found) {
79 found = fp;
80 cur_attr = attr;
81 continue;
82 }
83 /* avoid async out and adaptive in if the other method
84 * supports the same format.
85 * this is a workaround for the case like
86 * M-audio audiophile USB.
87 */
88 if (attr != cur_attr) {
89 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
90 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
91 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
92 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
93 continue;
94 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
95 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
96 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
97 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
98 found = fp;
99 cur_attr = attr;
100 continue;
101 }
102 }
103 /* find the format with the largest max. packet size */
104 if (fp->maxpacksize > found->maxpacksize) {
105 found = fp;
106 cur_attr = attr;
107 }
108 }
109 return found;
110}
111
112static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
113 struct usb_host_interface *alts,
114 struct audioformat *fmt)
115{
116 struct usb_device *dev = chip->dev;
117 unsigned int ep;
118 unsigned char data[1];
119 int err;
120
121 ep = get_endpoint(alts, 0)->bEndpointAddress;
122
123 /* if endpoint doesn't have pitch control, bail out */
124 if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
125 return 0;
126
127 data[0] = 1;
128 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
129 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
130 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
131 data, sizeof(data), 1000)) < 0) {
132 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
133 dev->devnum, iface, ep);
134 return err;
135 }
136
137 return 0;
138}
139
140/*
141 * initialize the picth control and sample rate
142 */
143int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
144 struct usb_host_interface *alts,
145 struct audioformat *fmt)
146{
147 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
148
149 switch (altsd->bInterfaceProtocol) {
150 case UAC_VERSION_1:
151 return init_pitch_v1(chip, iface, alts, fmt);
152
153 case UAC_VERSION_2:
154 /* not implemented yet */
155 return 0;
156 }
157
158 return -EINVAL;
159}
160
161static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
162 struct usb_host_interface *alts,
163 struct audioformat *fmt, int rate)
164{
165 struct usb_device *dev = chip->dev;
166 unsigned int ep;
167 unsigned char data[3];
168 int err, crate;
169
170 ep = get_endpoint(alts, 0)->bEndpointAddress;
171 /* if endpoint doesn't have sampling rate control, bail out */
172 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
173 snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
174 dev->devnum, iface, fmt->altsetting);
175 return 0;
176 }
177
178 data[0] = rate;
179 data[1] = rate >> 8;
180 data[2] = rate >> 16;
181 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
182 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
183 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
184 data, sizeof(data), 1000)) < 0) {
185 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
186 dev->devnum, iface, fmt->altsetting, rate, ep);
187 return err;
188 }
189 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
190 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
191 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
192 data, sizeof(data), 1000)) < 0) {
193 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
194 dev->devnum, iface, fmt->altsetting, ep);
195 return 0; /* some devices don't support reading */
196 }
197 crate = data[0] | (data[1] << 8) | (data[2] << 16);
198 if (crate != rate) {
199 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
200 // runtime->rate = crate;
201 }
202
203 return 0;
204}
205
206static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
207 struct usb_host_interface *alts,
208 struct audioformat *fmt, int rate)
209{
210 struct usb_device *dev = chip->dev;
211 unsigned char data[4];
212 int err, crate;
213
214 data[0] = rate;
215 data[1] = rate >> 8;
216 data[2] = rate >> 16;
217 data[3] = rate >> 24;
218 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
219 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
220 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
221 data, sizeof(data), 1000)) < 0) {
222 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
223 dev->devnum, iface, fmt->altsetting, rate);
224 return err;
225 }
226 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
227 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
228 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
229 data, sizeof(data), 1000)) < 0) {
230 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
231 dev->devnum, iface, fmt->altsetting);
232 return err;
233 }
234 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
235 if (crate != rate)
236 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
237
238 return 0;
239}
240
241int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
242 struct usb_host_interface *alts,
243 struct audioformat *fmt, int rate)
244{
245 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
246
247 switch (altsd->bInterfaceProtocol) {
248 case UAC_VERSION_1:
249 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
250
251 case UAC_VERSION_2:
252 return set_sample_rate_v2(chip, iface, alts, fmt, rate);
253 }
254
255 return -EINVAL;
256}
257
258/*
259 * find a matching format and set up the interface
260 */
261static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
262{
263 struct usb_device *dev = subs->dev;
264 struct usb_host_interface *alts;
265 struct usb_interface_descriptor *altsd;
266 struct usb_interface *iface;
267 unsigned int ep, attr;
268 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
269 int err;
270
271 iface = usb_ifnum_to_if(dev, fmt->iface);
272 if (WARN_ON(!iface))
273 return -EINVAL;
274 alts = &iface->altsetting[fmt->altset_idx];
275 altsd = get_iface_desc(alts);
276 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
277 return -EINVAL;
278
279 if (fmt == subs->cur_audiofmt)
280 return 0;
281
282 /* close the old interface */
283 if (subs->interface >= 0 && subs->interface != fmt->iface) {
284 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
285 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
286 dev->devnum, fmt->iface, fmt->altsetting);
287 return -EIO;
288 }
289 subs->interface = -1;
290 subs->altset_idx = 0;
291 }
292
293 /* set interface */
294 if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) {
295 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
296 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
297 dev->devnum, fmt->iface, fmt->altsetting);
298 return -EIO;
299 }
300 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
301 subs->interface = fmt->iface;
302 subs->altset_idx = fmt->altset_idx;
303 }
304
305 /* create a data pipe */
306 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
307 if (is_playback)
308 subs->datapipe = usb_sndisocpipe(dev, ep);
309 else
310 subs->datapipe = usb_rcvisocpipe(dev, ep);
311 subs->datainterval = fmt->datainterval;
312 subs->syncpipe = subs->syncinterval = 0;
313 subs->maxpacksize = fmt->maxpacksize;
314 subs->fill_max = 0;
315
316 /* we need a sync pipe in async OUT or adaptive IN mode */
317 /* check the number of EP, since some devices have broken
318 * descriptors which fool us. if it has only one EP,
319 * assume it as adaptive-out or sync-in.
320 */
321 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
322 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
323 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
324 altsd->bNumEndpoints >= 2) {
325 /* check sync-pipe endpoint */
326 /* ... and check descriptor size before accessing bSynchAddress
327 because there is a version of the SB Audigy 2 NX firmware lacking
328 the audio fields in the endpoint descriptors */
329 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
330 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
331 get_endpoint(alts, 1)->bSynchAddress != 0)) {
332 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
333 dev->devnum, fmt->iface, fmt->altsetting);
334 return -EINVAL;
335 }
336 ep = get_endpoint(alts, 1)->bEndpointAddress;
337 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
338 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
339 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
340 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
341 dev->devnum, fmt->iface, fmt->altsetting);
342 return -EINVAL;
343 }
344 ep &= USB_ENDPOINT_NUMBER_MASK;
345 if (is_playback)
346 subs->syncpipe = usb_rcvisocpipe(dev, ep);
347 else
348 subs->syncpipe = usb_sndisocpipe(dev, ep);
349 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
350 get_endpoint(alts, 1)->bRefresh >= 1 &&
351 get_endpoint(alts, 1)->bRefresh <= 9)
352 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
353 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
354 subs->syncinterval = 1;
355 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
356 get_endpoint(alts, 1)->bInterval <= 16)
357 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
358 else
359 subs->syncinterval = 3;
360 }
361
362 /* always fill max packet size */
363 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
364 subs->fill_max = 1;
365
366 if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0)
367 return err;
368
369 subs->cur_audiofmt = fmt;
370
371 snd_usb_set_format_quirk(subs, fmt);
372
373#if 0
374 printk(KERN_DEBUG
375 "setting done: format = %d, rate = %d..%d, channels = %d\n",
376 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
377 printk(KERN_DEBUG
378 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
379 subs->datapipe, subs->syncpipe);
380#endif
381
382 return 0;
383}
384
385/*
386 * hw_params callback
387 *
388 * allocate a buffer and set the given audio format.
389 *
390 * so far we use a physically linear buffer although packetize transfer
391 * doesn't need a continuous area.
392 * if sg buffer is supported on the later version of alsa, we'll follow
393 * that.
394 */
395static int snd_usb_hw_params(struct snd_pcm_substream *substream,
396 struct snd_pcm_hw_params *hw_params)
397{
398 struct snd_usb_substream *subs = substream->runtime->private_data;
399 struct audioformat *fmt;
400 unsigned int channels, rate, format;
401 int ret, changed;
402
403 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
404 params_buffer_bytes(hw_params));
405 if (ret < 0)
406 return ret;
407
408 format = params_format(hw_params);
409 rate = params_rate(hw_params);
410 channels = params_channels(hw_params);
411 fmt = find_format(subs, format, rate, channels);
412 if (!fmt) {
413 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
414 format, rate, channels);
415 return -EINVAL;
416 }
417
418 changed = subs->cur_audiofmt != fmt ||
419 subs->period_bytes != params_period_bytes(hw_params) ||
420 subs->cur_rate != rate;
421 if ((ret = set_format(subs, fmt)) < 0)
422 return ret;
423
424 if (subs->cur_rate != rate) {
425 struct usb_host_interface *alts;
426 struct usb_interface *iface;
427 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
428 alts = &iface->altsetting[fmt->altset_idx];
429 ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate);
430 if (ret < 0)
431 return ret;
432 subs->cur_rate = rate;
433 }
434
435 if (changed) {
436 /* format changed */
437 snd_usb_release_substream_urbs(subs, 0);
438 /* influenced: period_bytes, channels, rate, format, */
439 ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params),
440 params_rate(hw_params),
441 snd_pcm_format_physical_width(params_format(hw_params)) *
442 params_channels(hw_params));
443 }
444
445 return ret;
446}
447
448/*
449 * hw_free callback
450 *
451 * reset the audio format and release the buffer
452 */
453static int snd_usb_hw_free(struct snd_pcm_substream *substream)
454{
455 struct snd_usb_substream *subs = substream->runtime->private_data;
456
457 subs->cur_audiofmt = NULL;
458 subs->cur_rate = 0;
459 subs->period_bytes = 0;
460 if (!subs->stream->chip->shutdown)
461 snd_usb_release_substream_urbs(subs, 0);
462 return snd_pcm_lib_free_vmalloc_buffer(substream);
463}
464
465/*
466 * prepare callback
467 *
468 * only a few subtle things...
469 */
470static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
471{
472 struct snd_pcm_runtime *runtime = substream->runtime;
473 struct snd_usb_substream *subs = runtime->private_data;
474
475 if (! subs->cur_audiofmt) {
476 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
477 return -ENXIO;
478 }
479
480 /* some unit conversions in runtime */
481 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
482 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
483
484 /* reset the pointer */
485 subs->hwptr_done = 0;
486 subs->transfer_done = 0;
487 subs->phase = 0;
488 runtime->delay = 0;
489
490 return snd_usb_substream_prepare(subs, runtime);
491}
492
493static struct snd_pcm_hardware snd_usb_hardware =
494{
495 .info = SNDRV_PCM_INFO_MMAP |
496 SNDRV_PCM_INFO_MMAP_VALID |
497 SNDRV_PCM_INFO_BATCH |
498 SNDRV_PCM_INFO_INTERLEAVED |
499 SNDRV_PCM_INFO_BLOCK_TRANSFER |
500 SNDRV_PCM_INFO_PAUSE,
501 .buffer_bytes_max = 1024 * 1024,
502 .period_bytes_min = 64,
503 .period_bytes_max = 512 * 1024,
504 .periods_min = 2,
505 .periods_max = 1024,
506};
507
508static int hw_check_valid_format(struct snd_usb_substream *subs,
509 struct snd_pcm_hw_params *params,
510 struct audioformat *fp)
511{
512 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
513 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
514 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
515 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
516 struct snd_mask check_fmts;
517 unsigned int ptime;
518
519 /* check the format */
520 snd_mask_none(&check_fmts);
521 check_fmts.bits[0] = (u32)fp->formats;
522 check_fmts.bits[1] = (u32)(fp->formats >> 32);
523 snd_mask_intersect(&check_fmts, fmts);
524 if (snd_mask_empty(&check_fmts)) {
525 hwc_debug(" > check: no supported format %d\n", fp->format);
526 return 0;
527 }
528 /* check the channels */
529 if (fp->channels < ct->min || fp->channels > ct->max) {
530 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
531 return 0;
532 }
533 /* check the rate is within the range */
534 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
535 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
536 return 0;
537 }
538 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
539 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
540 return 0;
541 }
542 /* check whether the period time is >= the data packet interval */
543 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
544 ptime = 125 * (1 << fp->datainterval);
545 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
546 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
547 return 0;
548 }
549 }
550 return 1;
551}
552
553static int hw_rule_rate(struct snd_pcm_hw_params *params,
554 struct snd_pcm_hw_rule *rule)
555{
556 struct snd_usb_substream *subs = rule->private;
557 struct list_head *p;
558 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
559 unsigned int rmin, rmax;
560 int changed;
561
562 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
563 changed = 0;
564 rmin = rmax = 0;
565 list_for_each(p, &subs->fmt_list) {
566 struct audioformat *fp;
567 fp = list_entry(p, struct audioformat, list);
568 if (!hw_check_valid_format(subs, params, fp))
569 continue;
570 if (changed++) {
571 if (rmin > fp->rate_min)
572 rmin = fp->rate_min;
573 if (rmax < fp->rate_max)
574 rmax = fp->rate_max;
575 } else {
576 rmin = fp->rate_min;
577 rmax = fp->rate_max;
578 }
579 }
580
581 if (!changed) {
582 hwc_debug(" --> get empty\n");
583 it->empty = 1;
584 return -EINVAL;
585 }
586
587 changed = 0;
588 if (it->min < rmin) {
589 it->min = rmin;
590 it->openmin = 0;
591 changed = 1;
592 }
593 if (it->max > rmax) {
594 it->max = rmax;
595 it->openmax = 0;
596 changed = 1;
597 }
598 if (snd_interval_checkempty(it)) {
599 it->empty = 1;
600 return -EINVAL;
601 }
602 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
603 return changed;
604}
605
606
607static int hw_rule_channels(struct snd_pcm_hw_params *params,
608 struct snd_pcm_hw_rule *rule)
609{
610 struct snd_usb_substream *subs = rule->private;
611 struct list_head *p;
612 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
613 unsigned int rmin, rmax;
614 int changed;
615
616 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
617 changed = 0;
618 rmin = rmax = 0;
619 list_for_each(p, &subs->fmt_list) {
620 struct audioformat *fp;
621 fp = list_entry(p, struct audioformat, list);
622 if (!hw_check_valid_format(subs, params, fp))
623 continue;
624 if (changed++) {
625 if (rmin > fp->channels)
626 rmin = fp->channels;
627 if (rmax < fp->channels)
628 rmax = fp->channels;
629 } else {
630 rmin = fp->channels;
631 rmax = fp->channels;
632 }
633 }
634
635 if (!changed) {
636 hwc_debug(" --> get empty\n");
637 it->empty = 1;
638 return -EINVAL;
639 }
640
641 changed = 0;
642 if (it->min < rmin) {
643 it->min = rmin;
644 it->openmin = 0;
645 changed = 1;
646 }
647 if (it->max > rmax) {
648 it->max = rmax;
649 it->openmax = 0;
650 changed = 1;
651 }
652 if (snd_interval_checkempty(it)) {
653 it->empty = 1;
654 return -EINVAL;
655 }
656 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
657 return changed;
658}
659
660static int hw_rule_format(struct snd_pcm_hw_params *params,
661 struct snd_pcm_hw_rule *rule)
662{
663 struct snd_usb_substream *subs = rule->private;
664 struct list_head *p;
665 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
666 u64 fbits;
667 u32 oldbits[2];
668 int changed;
669
670 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
671 fbits = 0;
672 list_for_each(p, &subs->fmt_list) {
673 struct audioformat *fp;
674 fp = list_entry(p, struct audioformat, list);
675 if (!hw_check_valid_format(subs, params, fp))
676 continue;
677 fbits |= fp->formats;
678 }
679
680 oldbits[0] = fmt->bits[0];
681 oldbits[1] = fmt->bits[1];
682 fmt->bits[0] &= (u32)fbits;
683 fmt->bits[1] &= (u32)(fbits >> 32);
684 if (!fmt->bits[0] && !fmt->bits[1]) {
685 hwc_debug(" --> get empty\n");
686 return -EINVAL;
687 }
688 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
689 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
690 return changed;
691}
692
693static int hw_rule_period_time(struct snd_pcm_hw_params *params,
694 struct snd_pcm_hw_rule *rule)
695{
696 struct snd_usb_substream *subs = rule->private;
697 struct audioformat *fp;
698 struct snd_interval *it;
699 unsigned char min_datainterval;
700 unsigned int pmin;
701 int changed;
702
703 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
704 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
705 min_datainterval = 0xff;
706 list_for_each_entry(fp, &subs->fmt_list, list) {
707 if (!hw_check_valid_format(subs, params, fp))
708 continue;
709 min_datainterval = min(min_datainterval, fp->datainterval);
710 }
711 if (min_datainterval == 0xff) {
712 hwc_debug(" --> get emtpy\n");
713 it->empty = 1;
714 return -EINVAL;
715 }
716 pmin = 125 * (1 << min_datainterval);
717 changed = 0;
718 if (it->min < pmin) {
719 it->min = pmin;
720 it->openmin = 0;
721 changed = 1;
722 }
723 if (snd_interval_checkempty(it)) {
724 it->empty = 1;
725 return -EINVAL;
726 }
727 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
728 return changed;
729}
730
731/*
732 * If the device supports unusual bit rates, does the request meet these?
733 */
734static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
735 struct snd_usb_substream *subs)
736{
737 struct audioformat *fp;
738 int count = 0, needs_knot = 0;
739 int err;
740
741 list_for_each_entry(fp, &subs->fmt_list, list) {
742 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
743 return 0;
744 count += fp->nr_rates;
745 if (fp->rates & SNDRV_PCM_RATE_KNOT)
746 needs_knot = 1;
747 }
748 if (!needs_knot)
749 return 0;
750
751 subs->rate_list.count = count;
752 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
753 subs->rate_list.mask = 0;
754 count = 0;
755 list_for_each_entry(fp, &subs->fmt_list, list) {
756 int i;
757 for (i = 0; i < fp->nr_rates; i++)
758 subs->rate_list.list[count++] = fp->rate_table[i];
759 }
760 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
761 &subs->rate_list);
762 if (err < 0)
763 return err;
764
765 return 0;
766}
767
768
769/*
770 * set up the runtime hardware information.
771 */
772
773static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
774{
775 struct list_head *p;
776 unsigned int pt, ptmin;
777 int param_period_time_if_needed;
778 int err;
779
780 runtime->hw.formats = subs->formats;
781
782 runtime->hw.rate_min = 0x7fffffff;
783 runtime->hw.rate_max = 0;
784 runtime->hw.channels_min = 256;
785 runtime->hw.channels_max = 0;
786 runtime->hw.rates = 0;
787 ptmin = UINT_MAX;
788 /* check min/max rates and channels */
789 list_for_each(p, &subs->fmt_list) {
790 struct audioformat *fp;
791 fp = list_entry(p, struct audioformat, list);
792 runtime->hw.rates |= fp->rates;
793 if (runtime->hw.rate_min > fp->rate_min)
794 runtime->hw.rate_min = fp->rate_min;
795 if (runtime->hw.rate_max < fp->rate_max)
796 runtime->hw.rate_max = fp->rate_max;
797 if (runtime->hw.channels_min > fp->channels)
798 runtime->hw.channels_min = fp->channels;
799 if (runtime->hw.channels_max < fp->channels)
800 runtime->hw.channels_max = fp->channels;
801 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
802 /* FIXME: there might be more than one audio formats... */
803 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
804 fp->frame_size;
805 }
806 pt = 125 * (1 << fp->datainterval);
807 ptmin = min(ptmin, pt);
808 }
809
810 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
811 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
812 /* full speed devices have fixed data packet interval */
813 ptmin = 1000;
814 if (ptmin == 1000)
815 /* if period time doesn't go below 1 ms, no rules needed */
816 param_period_time_if_needed = -1;
817 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
818 ptmin, UINT_MAX);
819
820 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
821 hw_rule_rate, subs,
822 SNDRV_PCM_HW_PARAM_FORMAT,
823 SNDRV_PCM_HW_PARAM_CHANNELS,
824 param_period_time_if_needed,
825 -1)) < 0)
826 return err;
827 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
828 hw_rule_channels, subs,
829 SNDRV_PCM_HW_PARAM_FORMAT,
830 SNDRV_PCM_HW_PARAM_RATE,
831 param_period_time_if_needed,
832 -1)) < 0)
833 return err;
834 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
835 hw_rule_format, subs,
836 SNDRV_PCM_HW_PARAM_RATE,
837 SNDRV_PCM_HW_PARAM_CHANNELS,
838 param_period_time_if_needed,
839 -1)) < 0)
840 return err;
841 if (param_period_time_if_needed >= 0) {
842 err = snd_pcm_hw_rule_add(runtime, 0,
843 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
844 hw_rule_period_time, subs,
845 SNDRV_PCM_HW_PARAM_FORMAT,
846 SNDRV_PCM_HW_PARAM_CHANNELS,
847 SNDRV_PCM_HW_PARAM_RATE,
848 -1);
849 if (err < 0)
850 return err;
851 }
852 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
853 return err;
854 return 0;
855}
856
857static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
858{
859 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
860 struct snd_pcm_runtime *runtime = substream->runtime;
861 struct snd_usb_substream *subs = &as->substream[direction];
862
863 subs->interface = -1;
864 subs->altset_idx = 0;
865 runtime->hw = snd_usb_hardware;
866 runtime->private_data = subs;
867 subs->pcm_substream = substream;
868 return setup_hw_info(runtime, subs);
869}
870
871static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
872{
873 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
874 struct snd_usb_substream *subs = &as->substream[direction];
875
876 if (!as->chip->shutdown && subs->interface >= 0) {
877 usb_set_interface(subs->dev, subs->interface, 0);
878 subs->interface = -1;
879 }
880 subs->pcm_substream = NULL;
881 return 0;
882}
883
884static int snd_usb_playback_open(struct snd_pcm_substream *substream)
885{
886 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
887}
888
889static int snd_usb_playback_close(struct snd_pcm_substream *substream)
890{
891 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
892}
893
894static int snd_usb_capture_open(struct snd_pcm_substream *substream)
895{
896 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
897}
898
899static int snd_usb_capture_close(struct snd_pcm_substream *substream)
900{
901 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
902}
903
904static struct snd_pcm_ops snd_usb_playback_ops = {
905 .open = snd_usb_playback_open,
906 .close = snd_usb_playback_close,
907 .ioctl = snd_pcm_lib_ioctl,
908 .hw_params = snd_usb_hw_params,
909 .hw_free = snd_usb_hw_free,
910 .prepare = snd_usb_pcm_prepare,
911 .trigger = snd_usb_substream_playback_trigger,
912 .pointer = snd_usb_pcm_pointer,
913 .page = snd_pcm_lib_get_vmalloc_page,
914 .mmap = snd_pcm_lib_mmap_vmalloc,
915};
916
917static struct snd_pcm_ops snd_usb_capture_ops = {
918 .open = snd_usb_capture_open,
919 .close = snd_usb_capture_close,
920 .ioctl = snd_pcm_lib_ioctl,
921 .hw_params = snd_usb_hw_params,
922 .hw_free = snd_usb_hw_free,
923 .prepare = snd_usb_pcm_prepare,
924 .trigger = snd_usb_substream_capture_trigger,
925 .pointer = snd_usb_pcm_pointer,
926 .page = snd_pcm_lib_get_vmalloc_page,
927 .mmap = snd_pcm_lib_mmap_vmalloc,
928};
929
930void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
931{
932 snd_pcm_set_ops(pcm, stream,
933 stream == SNDRV_PCM_STREAM_PLAYBACK ?
934 &snd_usb_playback_ops : &snd_usb_capture_ops);
935}
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
new file mode 100644
index 000000000000..1c931b68f3b5
--- /dev/null
+++ b/sound/usb/pcm.h
@@ -0,0 +1,14 @@
1#ifndef __USBAUDIO_PCM_H
2#define __USBAUDIO_PCM_H
3
4void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
5
6int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
7 struct usb_host_interface *alts,
8 struct audioformat *fmt);
9
10int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
11 struct usb_host_interface *alts,
12 struct audioformat *fmt, int rate);
13
14#endif /* __USBAUDIO_PCM_H */
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
new file mode 100644
index 000000000000..f5e3f356b95f
--- /dev/null
+++ b/sound/usb/proc.c
@@ -0,0 +1,168 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/usb.h>
20
21#include <sound/core.h>
22#include <sound/info.h>
23#include <sound/pcm.h>
24
25#include "usbaudio.h"
26#include "helper.h"
27#include "card.h"
28#include "proc.h"
29
30/* convert our full speed USB rate into sampling rate in Hz */
31static inline unsigned get_full_speed_hz(unsigned int usb_rate)
32{
33 return (usb_rate * 125 + (1 << 12)) >> 13;
34}
35
36/* convert our high speed USB rate into sampling rate in Hz */
37static inline unsigned get_high_speed_hz(unsigned int usb_rate)
38{
39 return (usb_rate * 125 + (1 << 9)) >> 10;
40}
41
42/*
43 * common proc files to show the usb device info
44 */
45static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
46{
47 struct snd_usb_audio *chip = entry->private_data;
48 if (!chip->shutdown)
49 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
50}
51
52static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
53{
54 struct snd_usb_audio *chip = entry->private_data;
55 if (!chip->shutdown)
56 snd_iprintf(buffer, "%04x:%04x\n",
57 USB_ID_VENDOR(chip->usb_id),
58 USB_ID_PRODUCT(chip->usb_id));
59}
60
61void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
62{
63 struct snd_info_entry *entry;
64 if (!snd_card_proc_new(chip->card, "usbbus", &entry))
65 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
66 if (!snd_card_proc_new(chip->card, "usbid", &entry))
67 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
68}
69
70/*
71 * proc interface for list the supported pcm formats
72 */
73static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
74{
75 struct list_head *p;
76 static char *sync_types[4] = {
77 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
78 };
79
80 list_for_each(p, &subs->fmt_list) {
81 struct audioformat *fp;
82 snd_pcm_format_t fmt;
83 fp = list_entry(p, struct audioformat, list);
84 snd_iprintf(buffer, " Interface %d\n", fp->iface);
85 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
86 snd_iprintf(buffer, " Format:");
87 for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt)
88 if (fp->formats & (1uLL << fmt))
89 snd_iprintf(buffer, " %s",
90 snd_pcm_format_name(fmt));
91 snd_iprintf(buffer, "\n");
92 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
93 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
94 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
95 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
96 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
97 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
98 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
99 fp->rate_min, fp->rate_max);
100 } else {
101 unsigned int i;
102 snd_iprintf(buffer, " Rates: ");
103 for (i = 0; i < fp->nr_rates; i++) {
104 if (i > 0)
105 snd_iprintf(buffer, ", ");
106 snd_iprintf(buffer, "%d", fp->rate_table[i]);
107 }
108 snd_iprintf(buffer, "\n");
109 }
110 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
111 snd_iprintf(buffer, " Data packet interval: %d us\n",
112 125 * (1 << fp->datainterval));
113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
114 // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
115 }
116}
117
118static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
119{
120 if (subs->running) {
121 unsigned int i;
122 snd_iprintf(buffer, " Status: Running\n");
123 snd_iprintf(buffer, " Interface = %d\n", subs->interface);
124 snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx);
125 snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
126 for (i = 0; i < subs->nurbs; i++)
127 snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
128 snd_iprintf(buffer, "]\n");
129 snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
130 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
131 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
132 ? get_full_speed_hz(subs->freqm)
133 : get_high_speed_hz(subs->freqm),
134 subs->freqm >> 16, subs->freqm & 0xffff);
135 } else {
136 snd_iprintf(buffer, " Status: Stop\n");
137 }
138}
139
140static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
141{
142 struct snd_usb_stream *stream = entry->private_data;
143
144 snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
145
146 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
147 snd_iprintf(buffer, "\nPlayback:\n");
148 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
149 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
150 }
151 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
152 snd_iprintf(buffer, "\nCapture:\n");
153 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
154 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
155 }
156}
157
158void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
159{
160 struct snd_info_entry *entry;
161 char name[32];
162 struct snd_card *card = stream->chip->card;
163
164 sprintf(name, "stream%d", stream->pcm_index);
165 if (!snd_card_proc_new(card, name, &entry))
166 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
167}
168
diff --git a/sound/usb/proc.h b/sound/usb/proc.h
new file mode 100644
index 000000000000..a45b765e4cf1
--- /dev/null
+++ b/sound/usb/proc.h
@@ -0,0 +1,8 @@
1#ifndef __USBAUDIO_PROC_H
2#define __USBAUDIO_PROC_H
3
4void snd_usb_audio_create_proc(struct snd_usb_audio *chip);
5void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream);
6
7#endif /* __USBAUDIO_PROC_H */
8
diff --git a/sound/usb/usbquirks.h b/sound/usb/quirks-table.h
index 2b426c1fd0e8..91ddef31bcbd 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/quirks-table.h
@@ -279,7 +279,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
279 .ifnum = 0, 279 .ifnum = 0,
280 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 280 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
281 .data = & (const struct audioformat) { 281 .data = & (const struct audioformat) {
282 .format = SNDRV_PCM_FORMAT_S16_LE, 282 .formats = SNDRV_PCM_FMTBIT_S16_LE,
283 .channels = 4, 283 .channels = 4,
284 .iface = 0, 284 .iface = 0,
285 .altsetting = 1, 285 .altsetting = 1,
@@ -296,7 +296,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
296 .ifnum = 1, 296 .ifnum = 1,
297 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 297 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
298 .data = & (const struct audioformat) { 298 .data = & (const struct audioformat) {
299 .format = SNDRV_PCM_FORMAT_S16_LE, 299 .formats = SNDRV_PCM_FMTBIT_S16_LE,
300 .channels = 2, 300 .channels = 2,
301 .iface = 1, 301 .iface = 1,
302 .altsetting = 1, 302 .altsetting = 1,
@@ -580,7 +580,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
580 .ifnum = 0, 580 .ifnum = 0,
581 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 581 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
582 .data = & (const struct audioformat) { 582 .data = & (const struct audioformat) {
583 .format = SNDRV_PCM_FORMAT_S24_3LE, 583 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
584 .channels = 2, 584 .channels = 2,
585 .iface = 0, 585 .iface = 0,
586 .altsetting = 1, 586 .altsetting = 1,
@@ -597,7 +597,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
597 .ifnum = 1, 597 .ifnum = 1,
598 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 598 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
599 .data = & (const struct audioformat) { 599 .data = & (const struct audioformat) {
600 .format = SNDRV_PCM_FORMAT_S24_3LE, 600 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
601 .channels = 2, 601 .channels = 2,
602 .iface = 1, 602 .iface = 1,
603 .altsetting = 1, 603 .altsetting = 1,
@@ -793,7 +793,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
793 .ifnum = 1, 793 .ifnum = 1,
794 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 794 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
795 .data = & (const struct audioformat) { 795 .data = & (const struct audioformat) {
796 .format = SNDRV_PCM_FORMAT_S24_3LE, 796 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
797 .channels = 2, 797 .channels = 2,
798 .iface = 1, 798 .iface = 1,
799 .altsetting = 1, 799 .altsetting = 1,
@@ -810,7 +810,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
810 .ifnum = 2, 810 .ifnum = 2,
811 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 811 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
812 .data = & (const struct audioformat) { 812 .data = & (const struct audioformat) {
813 .format = SNDRV_PCM_FORMAT_S24_3LE, 813 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
814 .channels = 2, 814 .channels = 2,
815 .iface = 2, 815 .iface = 2,
816 .altsetting = 1, 816 .altsetting = 1,
@@ -1826,6 +1826,60 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1826 } 1826 }
1827 } 1827 }
1828}, 1828},
1829{
1830 USB_DEVICE(0x0763, 0x2080),
1831 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1832 /* .vendor_name = "M-Audio", */
1833 /* .product_name = "Fast Track Ultra 8", */
1834 .ifnum = QUIRK_ANY_INTERFACE,
1835 .type = QUIRK_COMPOSITE,
1836 .data = & (const struct snd_usb_audio_quirk[]) {
1837 {
1838 .ifnum = 0,
1839 .type = QUIRK_IGNORE_INTERFACE
1840 },
1841 {
1842 .ifnum = 1,
1843 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1844 },
1845 {
1846 .ifnum = 2,
1847 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1848 },
1849 /* interface 3 (MIDI) is standard compliant */
1850 {
1851 .ifnum = -1
1852 }
1853 }
1854 }
1855},
1856{
1857 USB_DEVICE(0x0763, 0x2081),
1858 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1859 /* .vendor_name = "M-Audio", */
1860 /* .product_name = "Fast Track Ultra 8R", */
1861 .ifnum = QUIRK_ANY_INTERFACE,
1862 .type = QUIRK_COMPOSITE,
1863 .data = & (const struct snd_usb_audio_quirk[]) {
1864 {
1865 .ifnum = 0,
1866 .type = QUIRK_IGNORE_INTERFACE
1867 },
1868 {
1869 .ifnum = 1,
1870 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1871 },
1872 {
1873 .ifnum = 2,
1874 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1875 },
1876 /* interface 3 (MIDI) is standard compliant */
1877 {
1878 .ifnum = -1
1879 }
1880 }
1881 }
1882},
1829 1883
1830/* Casio devices */ 1884/* Casio devices */
1831{ 1885{
@@ -2203,7 +2257,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2203 .ifnum = 1, 2257 .ifnum = 1,
2204 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 2258 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2205 .data = &(const struct audioformat) { 2259 .data = &(const struct audioformat) {
2206 .format = SNDRV_PCM_FORMAT_S24_3BE, 2260 .formats = SNDRV_PCM_FMTBIT_S24_3BE,
2207 .channels = 2, 2261 .channels = 2,
2208 .iface = 1, 2262 .iface = 1,
2209 .altsetting = 1, 2263 .altsetting = 1,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
new file mode 100644
index 000000000000..136e5b4cf6de
--- /dev/null
+++ b/sound/usb/quirks.c
@@ -0,0 +1,594 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
21
22#include <sound/core.h>
23#include <sound/info.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "card.h"
28#include "mixer.h"
29#include "mixer_quirks.h"
30#include "midi.h"
31#include "quirks.h"
32#include "helper.h"
33#include "endpoint.h"
34#include "pcm.h"
35
36/*
37 * handle the quirks for the contained interfaces
38 */
39static int create_composite_quirk(struct snd_usb_audio *chip,
40 struct usb_interface *iface,
41 struct usb_driver *driver,
42 const struct snd_usb_audio_quirk *quirk)
43{
44 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
45 int err;
46
47 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
48 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
49 if (!iface)
50 continue;
51 if (quirk->ifnum != probed_ifnum &&
52 usb_interface_claimed(iface))
53 continue;
54 err = snd_usb_create_quirk(chip, iface, driver, quirk);
55 if (err < 0)
56 return err;
57 if (quirk->ifnum != probed_ifnum)
58 usb_driver_claim_interface(driver, iface, (void *)-1L);
59 }
60 return 0;
61}
62
63static int ignore_interface_quirk(struct snd_usb_audio *chip,
64 struct usb_interface *iface,
65 struct usb_driver *driver,
66 const struct snd_usb_audio_quirk *quirk)
67{
68 return 0;
69}
70
71
72/*
73 * Allow alignment on audio sub-slot (channel samples) rather than
74 * on audio slots (audio frames)
75 */
76static int create_align_transfer_quirk(struct snd_usb_audio *chip,
77 struct usb_interface *iface,
78 struct usb_driver *driver,
79 const struct snd_usb_audio_quirk *quirk)
80{
81 chip->txfr_quirk = 1;
82 return 1; /* Continue with creating streams and mixer */
83}
84
85static int create_any_midi_quirk(struct snd_usb_audio *chip,
86 struct usb_interface *intf,
87 struct usb_driver *driver,
88 const struct snd_usb_audio_quirk *quirk)
89{
90 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
91}
92
93/*
94 * create a stream for an interface with proper descriptors
95 */
96static int create_standard_audio_quirk(struct snd_usb_audio *chip,
97 struct usb_interface *iface,
98 struct usb_driver *driver,
99 const struct snd_usb_audio_quirk *quirk)
100{
101 struct usb_host_interface *alts;
102 struct usb_interface_descriptor *altsd;
103 int err;
104
105 alts = &iface->altsetting[0];
106 altsd = get_iface_desc(alts);
107 err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber);
108 if (err < 0) {
109 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
110 altsd->bInterfaceNumber, err);
111 return err;
112 }
113 /* reset the current interface */
114 usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
115 return 0;
116}
117
118/*
119 * create a stream for an endpoint/altsetting without proper descriptors
120 */
121static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
122 struct usb_interface *iface,
123 struct usb_driver *driver,
124 const struct snd_usb_audio_quirk *quirk)
125{
126 struct audioformat *fp;
127 struct usb_host_interface *alts;
128 int stream, err;
129 unsigned *rate_table = NULL;
130
131 fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
132 if (! fp) {
133 snd_printk(KERN_ERR "cannot memdup\n");
134 return -ENOMEM;
135 }
136 if (fp->nr_rates > 0) {
137 rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
138 if (!rate_table) {
139 kfree(fp);
140 return -ENOMEM;
141 }
142 memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
143 fp->rate_table = rate_table;
144 }
145
146 stream = (fp->endpoint & USB_DIR_IN)
147 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
148 err = snd_usb_add_audio_endpoint(chip, stream, fp);
149 if (err < 0) {
150 kfree(fp);
151 kfree(rate_table);
152 return err;
153 }
154 if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
155 fp->altset_idx >= iface->num_altsetting) {
156 kfree(fp);
157 kfree(rate_table);
158 return -EINVAL;
159 }
160 alts = &iface->altsetting[fp->altset_idx];
161 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
162 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
163 usb_set_interface(chip->dev, fp->iface, 0);
164 snd_usb_init_pitch(chip, fp->iface, alts, fp);
165 snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
166 return 0;
167}
168
169/*
170 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
171 * The only way to detect the sample rate is by looking at wMaxPacketSize.
172 */
173static int create_uaxx_quirk(struct snd_usb_audio *chip,
174 struct usb_interface *iface,
175 struct usb_driver *driver,
176 const struct snd_usb_audio_quirk *quirk)
177{
178 static const struct audioformat ua_format = {
179 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
180 .channels = 2,
181 .fmt_type = UAC_FORMAT_TYPE_I,
182 .altsetting = 1,
183 .altset_idx = 1,
184 .rates = SNDRV_PCM_RATE_CONTINUOUS,
185 };
186 struct usb_host_interface *alts;
187 struct usb_interface_descriptor *altsd;
188 struct audioformat *fp;
189 int stream, err;
190
191 /* both PCM and MIDI interfaces have 2 or more altsettings */
192 if (iface->num_altsetting < 2)
193 return -ENXIO;
194 alts = &iface->altsetting[1];
195 altsd = get_iface_desc(alts);
196
197 if (altsd->bNumEndpoints == 2) {
198 static const struct snd_usb_midi_endpoint_info ua700_ep = {
199 .out_cables = 0x0003,
200 .in_cables = 0x0003
201 };
202 static const struct snd_usb_audio_quirk ua700_quirk = {
203 .type = QUIRK_MIDI_FIXED_ENDPOINT,
204 .data = &ua700_ep
205 };
206 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
207 .out_cables = 0x0001,
208 .in_cables = 0x0001
209 };
210 static const struct snd_usb_audio_quirk uaxx_quirk = {
211 .type = QUIRK_MIDI_FIXED_ENDPOINT,
212 .data = &uaxx_ep
213 };
214 const struct snd_usb_audio_quirk *quirk =
215 chip->usb_id == USB_ID(0x0582, 0x002b)
216 ? &ua700_quirk : &uaxx_quirk;
217 return snd_usbmidi_create(chip->card, iface,
218 &chip->midi_list, quirk);
219 }
220
221 if (altsd->bNumEndpoints != 1)
222 return -ENXIO;
223
224 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
225 if (!fp)
226 return -ENOMEM;
227 memcpy(fp, &ua_format, sizeof(*fp));
228
229 fp->iface = altsd->bInterfaceNumber;
230 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
231 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
232 fp->datainterval = 0;
233 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
234
235 switch (fp->maxpacksize) {
236 case 0x120:
237 fp->rate_max = fp->rate_min = 44100;
238 break;
239 case 0x138:
240 case 0x140:
241 fp->rate_max = fp->rate_min = 48000;
242 break;
243 case 0x258:
244 case 0x260:
245 fp->rate_max = fp->rate_min = 96000;
246 break;
247 default:
248 snd_printk(KERN_ERR "unknown sample rate\n");
249 kfree(fp);
250 return -ENXIO;
251 }
252
253 stream = (fp->endpoint & USB_DIR_IN)
254 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
255 err = snd_usb_add_audio_endpoint(chip, stream, fp);
256 if (err < 0) {
257 kfree(fp);
258 return err;
259 }
260 usb_set_interface(chip->dev, fp->iface, 0);
261 return 0;
262}
263
264/*
265 * audio-interface quirks
266 *
267 * returns zero if no standard audio/MIDI parsing is needed.
268 * returns a postive value if standard audio/midi interfaces are parsed
269 * after this.
270 * returns a negative value at error.
271 */
272int snd_usb_create_quirk(struct snd_usb_audio *chip,
273 struct usb_interface *iface,
274 struct usb_driver *driver,
275 const struct snd_usb_audio_quirk *quirk)
276{
277 typedef int (*quirk_func_t)(struct snd_usb_audio *,
278 struct usb_interface *,
279 struct usb_driver *,
280 const struct snd_usb_audio_quirk *);
281 static const quirk_func_t quirk_funcs[] = {
282 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
283 [QUIRK_COMPOSITE] = create_composite_quirk,
284 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
285 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
286 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
287 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
288 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
289 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
290 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
291 [QUIRK_MIDI_CME] = create_any_midi_quirk,
292 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
293 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
294 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
295 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
296 };
297
298 if (quirk->type < QUIRK_TYPE_COUNT) {
299 return quirk_funcs[quirk->type](chip, iface, driver, quirk);
300 } else {
301 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
302 return -ENXIO;
303 }
304}
305
306/*
307 * boot quirks
308 */
309
310#define EXTIGY_FIRMWARE_SIZE_OLD 794
311#define EXTIGY_FIRMWARE_SIZE_NEW 483
312
313static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
314{
315 struct usb_host_config *config = dev->actconfig;
316 int err;
317
318 if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
319 le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
320 snd_printdd("sending Extigy boot sequence...\n");
321 /* Send message to force it to reconnect with full interface. */
322 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
323 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
324 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
325 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
326 &dev->descriptor, sizeof(dev->descriptor));
327 config = dev->actconfig;
328 if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
329 err = usb_reset_configuration(dev);
330 if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
331 snd_printdd("extigy_boot: new boot length = %d\n",
332 le16_to_cpu(get_cfg_desc(config)->wTotalLength));
333 return -ENODEV; /* quit this anyway */
334 }
335 return 0;
336}
337
338static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
339{
340 u8 buf = 1;
341
342 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
343 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
344 0, 0, &buf, 1, 1000);
345 if (buf == 0) {
346 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
347 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
348 1, 2000, NULL, 0, 1000);
349 return -ENODEV;
350 }
351 return 0;
352}
353
354/*
355 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
356 * documented in the device's data sheet.
357 */
358static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
359{
360 u8 buf[4];
361 buf[0] = 0x20;
362 buf[1] = value & 0xff;
363 buf[2] = (value >> 8) & 0xff;
364 buf[3] = reg;
365 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
366 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
367 0, 0, &buf, 4, 1000);
368}
369
370static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
371{
372 /*
373 * Enable line-out driver mode, set headphone source to front
374 * channels, enable stereo mic.
375 */
376 return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
377}
378
379/*
380 * C-Media CM6206 is based on CM106 with two additional
381 * registers that are not documented in the data sheet.
382 * Values here are chosen based on sniffing USB traffic
383 * under Windows.
384 */
385static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
386{
387 int err, reg;
388 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
389
390 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
391 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
392 if (err < 0)
393 return err;
394 }
395
396 return err;
397}
398
399/*
400 * This call will put the synth in "USB send" mode, i.e it will send MIDI
401 * messages through USB (this is disabled at startup). The synth will
402 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
403 * sign on its LCD. Values here are chosen based on sniffing USB traffic
404 * under Windows.
405 */
406static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
407{
408 int err, actual_length;
409
410 /* "midi send" enable */
411 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
412
413 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
414 if (!buf)
415 return -ENOMEM;
416 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
417 ARRAY_SIZE(seq), &actual_length, 1000);
418 kfree(buf);
419 if (err < 0)
420 return err;
421
422 return 0;
423}
424
425/*
426 * Setup quirks
427 */
428#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
429#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
430#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
431#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
432#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
433#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
434#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
435#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
436#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
437#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
438
439static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
440 int iface,
441 int altno)
442{
443 /* Reset ALL ifaces to 0 altsetting.
444 * Call it for every possible altsetting of every interface.
445 */
446 usb_set_interface(chip->dev, iface, 0);
447
448 if (chip->setup & AUDIOPHILE_SET) {
449 if ((chip->setup & AUDIOPHILE_SET_DTS)
450 && altno != 6)
451 return 1; /* skip this altsetting */
452 if ((chip->setup & AUDIOPHILE_SET_96K)
453 && altno != 1)
454 return 1; /* skip this altsetting */
455 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
456 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
457 return 1; /* skip this altsetting */
458 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
459 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
460 return 1; /* skip this altsetting */
461 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
462 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
463 return 1; /* skip this altsetting */
464 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
465 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
466 return 1; /* skip this altsetting */
467 }
468
469 return 0; /* keep this altsetting */
470}
471
472int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
473 int iface,
474 int altno)
475{
476 /* audiophile usb: skip altsets incompatible with device_setup */
477 if (chip->usb_id == USB_ID(0x0763, 0x2003))
478 return audiophile_skip_setting_quirk(chip, iface, altno);
479
480 return 0;
481}
482
483int snd_usb_apply_boot_quirk(struct usb_device *dev,
484 struct usb_interface *intf,
485 const struct snd_usb_audio_quirk *quirk)
486{
487 u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
488 le16_to_cpu(dev->descriptor.idProduct));
489
490 /* SB Extigy needs special boot-up sequence */
491 /* if more models come, this will go to the quirk list. */
492 if (id == USB_ID(0x041e, 0x3000))
493 return snd_usb_extigy_boot_quirk(dev, intf);
494
495 /* SB Audigy 2 NX needs its own boot-up magic, too */
496 if (id == USB_ID(0x041e, 0x3020))
497 return snd_usb_audigy2nx_boot_quirk(dev);
498
499 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
500 if (id == USB_ID(0x10f5, 0x0200))
501 return snd_usb_cm106_boot_quirk(dev);
502
503 /* C-Media CM6206 / CM106-Like Sound Device */
504 if (id == USB_ID(0x0d8c, 0x0102))
505 return snd_usb_cm6206_boot_quirk(dev);
506
507 /* Access Music VirusTI Desktop */
508 if (id == USB_ID(0x133e, 0x0815))
509 return snd_usb_accessmusic_boot_quirk(dev);
510
511 return 0;
512}
513
514/*
515 * check if the device uses big-endian samples
516 */
517int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
518{
519 switch (chip->usb_id) {
520 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
521 if (fp->endpoint & USB_DIR_IN)
522 return 1;
523 break;
524 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
525 if (chip->setup == 0x00 ||
526 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
527 return 1;
528 }
529 return 0;
530}
531
532/*
533 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
534 * not for interface.
535 */
536
537enum {
538 EMU_QUIRK_SR_44100HZ = 0,
539 EMU_QUIRK_SR_48000HZ,
540 EMU_QUIRK_SR_88200HZ,
541 EMU_QUIRK_SR_96000HZ,
542 EMU_QUIRK_SR_176400HZ,
543 EMU_QUIRK_SR_192000HZ
544};
545
546static void set_format_emu_quirk(struct snd_usb_substream *subs,
547 struct audioformat *fmt)
548{
549 unsigned char emu_samplerate_id = 0;
550
551 /* When capture is active
552 * sample rate shouldn't be changed
553 * by playback substream
554 */
555 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
556 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
557 return;
558 }
559
560 switch (fmt->rate_min) {
561 case 48000:
562 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
563 break;
564 case 88200:
565 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
566 break;
567 case 96000:
568 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
569 break;
570 case 176400:
571 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
572 break;
573 case 192000:
574 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
575 break;
576 default:
577 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
578 break;
579 }
580 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
581}
582
583void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
584 struct audioformat *fmt)
585{
586 switch (subs->stream->chip->usb_id) {
587 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
588 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
589 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
590 set_format_emu_quirk(subs, fmt);
591 break;
592 }
593}
594
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
new file mode 100644
index 000000000000..03e5e94098cd
--- /dev/null
+++ b/sound/usb/quirks.h
@@ -0,0 +1,23 @@
1#ifndef __USBAUDIO_QUIRKS_H
2#define __USBAUDIO_QUIRKS_H
3
4int snd_usb_create_quirk(struct snd_usb_audio *chip,
5 struct usb_interface *iface,
6 struct usb_driver *driver,
7 const struct snd_usb_audio_quirk *quirk);
8
9int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
10 int iface,
11 int altno);
12
13int snd_usb_apply_boot_quirk(struct usb_device *dev,
14 struct usb_interface *intf,
15 const struct snd_usb_audio_quirk *quirk);
16
17void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
18 struct audioformat *fmt);
19
20int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
21 struct audioformat *fp);
22
23#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
new file mode 100644
index 000000000000..5570a2ba5736
--- /dev/null
+++ b/sound/usb/urb.c
@@ -0,0 +1,995 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/gfp.h>
19#include <linux/init.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "helper.h"
28#include "card.h"
29#include "urb.h"
30#include "pcm.h"
31
32/*
33 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
34 * this will overflow at approx 524 kHz
35 */
36static inline unsigned get_usb_full_speed_rate(unsigned int rate)
37{
38 return ((rate << 13) + 62) / 125;
39}
40
41/*
42 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
43 * this will overflow at approx 4 MHz
44 */
45static inline unsigned get_usb_high_speed_rate(unsigned int rate)
46{
47 return ((rate << 10) + 62) / 125;
48}
49
50/*
51 * unlink active urbs.
52 */
53static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
54{
55 struct snd_usb_audio *chip = subs->stream->chip;
56 unsigned int i;
57 int async;
58
59 subs->running = 0;
60
61 if (!force && subs->stream->chip->shutdown) /* to be sure... */
62 return -EBADFD;
63
64 async = !can_sleep && chip->async_unlink;
65
66 if (!async && in_interrupt())
67 return 0;
68
69 for (i = 0; i < subs->nurbs; i++) {
70 if (test_bit(i, &subs->active_mask)) {
71 if (!test_and_set_bit(i, &subs->unlink_mask)) {
72 struct urb *u = subs->dataurb[i].urb;
73 if (async)
74 usb_unlink_urb(u);
75 else
76 usb_kill_urb(u);
77 }
78 }
79 }
80 if (subs->syncpipe) {
81 for (i = 0; i < SYNC_URBS; i++) {
82 if (test_bit(i+16, &subs->active_mask)) {
83 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
84 struct urb *u = subs->syncurb[i].urb;
85 if (async)
86 usb_unlink_urb(u);
87 else
88 usb_kill_urb(u);
89 }
90 }
91 }
92 }
93 return 0;
94}
95
96
97/*
98 * release a urb data
99 */
100static void release_urb_ctx(struct snd_urb_ctx *u)
101{
102 if (u->urb) {
103 if (u->buffer_size)
104 usb_buffer_free(u->subs->dev, u->buffer_size,
105 u->urb->transfer_buffer,
106 u->urb->transfer_dma);
107 usb_free_urb(u->urb);
108 u->urb = NULL;
109 }
110}
111
112/*
113 * wait until all urbs are processed.
114 */
115static int wait_clear_urbs(struct snd_usb_substream *subs)
116{
117 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
118 unsigned int i;
119 int alive;
120
121 do {
122 alive = 0;
123 for (i = 0; i < subs->nurbs; i++) {
124 if (test_bit(i, &subs->active_mask))
125 alive++;
126 }
127 if (subs->syncpipe) {
128 for (i = 0; i < SYNC_URBS; i++) {
129 if (test_bit(i + 16, &subs->active_mask))
130 alive++;
131 }
132 }
133 if (! alive)
134 break;
135 schedule_timeout_uninterruptible(1);
136 } while (time_before(jiffies, end_time));
137 if (alive)
138 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
139 return 0;
140}
141
142/*
143 * release a substream
144 */
145void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
146{
147 int i;
148
149 /* stop urbs (to be sure) */
150 deactivate_urbs(subs, force, 1);
151 wait_clear_urbs(subs);
152
153 for (i = 0; i < MAX_URBS; i++)
154 release_urb_ctx(&subs->dataurb[i]);
155 for (i = 0; i < SYNC_URBS; i++)
156 release_urb_ctx(&subs->syncurb[i]);
157 usb_buffer_free(subs->dev, SYNC_URBS * 4,
158 subs->syncbuf, subs->sync_dma);
159 subs->syncbuf = NULL;
160 subs->nurbs = 0;
161}
162
163/*
164 * complete callback from data urb
165 */
166static void snd_complete_urb(struct urb *urb)
167{
168 struct snd_urb_ctx *ctx = urb->context;
169 struct snd_usb_substream *subs = ctx->subs;
170 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
171 int err = 0;
172
173 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
174 !subs->running || /* can be stopped during retire callback */
175 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
176 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
177 clear_bit(ctx->index, &subs->active_mask);
178 if (err < 0) {
179 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
180 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
181 }
182 }
183}
184
185
186/*
187 * complete callback from sync urb
188 */
189static void snd_complete_sync_urb(struct urb *urb)
190{
191 struct snd_urb_ctx *ctx = urb->context;
192 struct snd_usb_substream *subs = ctx->subs;
193 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
194 int err = 0;
195
196 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
197 !subs->running || /* can be stopped during retire callback */
198 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
199 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
200 clear_bit(ctx->index + 16, &subs->active_mask);
201 if (err < 0) {
202 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
203 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
204 }
205 }
206}
207
208
209/*
210 * initialize a substream for plaback/capture
211 */
212int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
213 unsigned int period_bytes,
214 unsigned int rate,
215 unsigned int frame_bits)
216{
217 unsigned int maxsize, i;
218 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
219 unsigned int urb_packs, total_packs, packs_per_ms;
220 struct snd_usb_audio *chip = subs->stream->chip;
221
222 /* calculate the frequency in 16.16 format */
223 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
224 subs->freqn = get_usb_full_speed_rate(rate);
225 else
226 subs->freqn = get_usb_high_speed_rate(rate);
227 subs->freqm = subs->freqn;
228 /* calculate max. frequency */
229 if (subs->maxpacksize) {
230 /* whatever fits into a max. size packet */
231 maxsize = subs->maxpacksize;
232 subs->freqmax = (maxsize / (frame_bits >> 3))
233 << (16 - subs->datainterval);
234 } else {
235 /* no max. packet size: just take 25% higher than nominal */
236 subs->freqmax = subs->freqn + (subs->freqn >> 2);
237 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
238 >> (16 - subs->datainterval);
239 }
240 subs->phase = 0;
241
242 if (subs->fill_max)
243 subs->curpacksize = subs->maxpacksize;
244 else
245 subs->curpacksize = maxsize;
246
247 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
248 packs_per_ms = 8 >> subs->datainterval;
249 else
250 packs_per_ms = 1;
251
252 if (is_playback) {
253 urb_packs = max(chip->nrpacks, 1);
254 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
255 } else
256 urb_packs = 1;
257 urb_packs *= packs_per_ms;
258 if (subs->syncpipe)
259 urb_packs = min(urb_packs, 1U << subs->syncinterval);
260
261 /* decide how many packets to be used */
262 if (is_playback) {
263 unsigned int minsize, maxpacks;
264 /* determine how small a packet can be */
265 minsize = (subs->freqn >> (16 - subs->datainterval))
266 * (frame_bits >> 3);
267 /* with sync from device, assume it can be 12% lower */
268 if (subs->syncpipe)
269 minsize -= minsize >> 3;
270 minsize = max(minsize, 1u);
271 total_packs = (period_bytes + minsize - 1) / minsize;
272 /* we need at least two URBs for queueing */
273 if (total_packs < 2) {
274 total_packs = 2;
275 } else {
276 /* and we don't want too long a queue either */
277 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
278 total_packs = min(total_packs, maxpacks);
279 }
280 } else {
281 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
282 urb_packs >>= 1;
283 total_packs = MAX_URBS * urb_packs;
284 }
285 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
286 if (subs->nurbs > MAX_URBS) {
287 /* too much... */
288 subs->nurbs = MAX_URBS;
289 total_packs = MAX_URBS * urb_packs;
290 } else if (subs->nurbs < 2) {
291 /* too little - we need at least two packets
292 * to ensure contiguous playback/capture
293 */
294 subs->nurbs = 2;
295 }
296
297 /* allocate and initialize data urbs */
298 for (i = 0; i < subs->nurbs; i++) {
299 struct snd_urb_ctx *u = &subs->dataurb[i];
300 u->index = i;
301 u->subs = subs;
302 u->packets = (i + 1) * total_packs / subs->nurbs
303 - i * total_packs / subs->nurbs;
304 u->buffer_size = maxsize * u->packets;
305 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
306 u->packets++; /* for transfer delimiter */
307 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
308 if (!u->urb)
309 goto out_of_memory;
310 u->urb->transfer_buffer =
311 usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL,
312 &u->urb->transfer_dma);
313 if (!u->urb->transfer_buffer)
314 goto out_of_memory;
315 u->urb->pipe = subs->datapipe;
316 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
317 u->urb->interval = 1 << subs->datainterval;
318 u->urb->context = u;
319 u->urb->complete = snd_complete_urb;
320 }
321
322 if (subs->syncpipe) {
323 /* allocate and initialize sync urbs */
324 subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4,
325 GFP_KERNEL, &subs->sync_dma);
326 if (!subs->syncbuf)
327 goto out_of_memory;
328 for (i = 0; i < SYNC_URBS; i++) {
329 struct snd_urb_ctx *u = &subs->syncurb[i];
330 u->index = i;
331 u->subs = subs;
332 u->packets = 1;
333 u->urb = usb_alloc_urb(1, GFP_KERNEL);
334 if (!u->urb)
335 goto out_of_memory;
336 u->urb->transfer_buffer = subs->syncbuf + i * 4;
337 u->urb->transfer_dma = subs->sync_dma + i * 4;
338 u->urb->transfer_buffer_length = 4;
339 u->urb->pipe = subs->syncpipe;
340 u->urb->transfer_flags = URB_ISO_ASAP |
341 URB_NO_TRANSFER_DMA_MAP;
342 u->urb->number_of_packets = 1;
343 u->urb->interval = 1 << subs->syncinterval;
344 u->urb->context = u;
345 u->urb->complete = snd_complete_sync_urb;
346 }
347 }
348 return 0;
349
350out_of_memory:
351 snd_usb_release_substream_urbs(subs, 0);
352 return -ENOMEM;
353}
354
355/*
356 * prepare urb for full speed capture sync pipe
357 *
358 * fill the length and offset of each urb descriptor.
359 * the fixed 10.14 frequency is passed through the pipe.
360 */
361static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
362 struct snd_pcm_runtime *runtime,
363 struct urb *urb)
364{
365 unsigned char *cp = urb->transfer_buffer;
366 struct snd_urb_ctx *ctx = urb->context;
367
368 urb->dev = ctx->subs->dev; /* we need to set this at each time */
369 urb->iso_frame_desc[0].length = 3;
370 urb->iso_frame_desc[0].offset = 0;
371 cp[0] = subs->freqn >> 2;
372 cp[1] = subs->freqn >> 10;
373 cp[2] = subs->freqn >> 18;
374 return 0;
375}
376
377/*
378 * prepare urb for high speed capture sync pipe
379 *
380 * fill the length and offset of each urb descriptor.
381 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
382 */
383static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
384 struct snd_pcm_runtime *runtime,
385 struct urb *urb)
386{
387 unsigned char *cp = urb->transfer_buffer;
388 struct snd_urb_ctx *ctx = urb->context;
389
390 urb->dev = ctx->subs->dev; /* we need to set this at each time */
391 urb->iso_frame_desc[0].length = 4;
392 urb->iso_frame_desc[0].offset = 0;
393 cp[0] = subs->freqn;
394 cp[1] = subs->freqn >> 8;
395 cp[2] = subs->freqn >> 16;
396 cp[3] = subs->freqn >> 24;
397 return 0;
398}
399
400/*
401 * process after capture sync complete
402 * - nothing to do
403 */
404static int retire_capture_sync_urb(struct snd_usb_substream *subs,
405 struct snd_pcm_runtime *runtime,
406 struct urb *urb)
407{
408 return 0;
409}
410
411/*
412 * prepare urb for capture data pipe
413 *
414 * fill the offset and length of each descriptor.
415 *
416 * we use a temporary buffer to write the captured data.
417 * since the length of written data is determined by host, we cannot
418 * write onto the pcm buffer directly... the data is thus copied
419 * later at complete callback to the global buffer.
420 */
421static int prepare_capture_urb(struct snd_usb_substream *subs,
422 struct snd_pcm_runtime *runtime,
423 struct urb *urb)
424{
425 int i, offs;
426 struct snd_urb_ctx *ctx = urb->context;
427
428 offs = 0;
429 urb->dev = ctx->subs->dev; /* we need to set this at each time */
430 for (i = 0; i < ctx->packets; i++) {
431 urb->iso_frame_desc[i].offset = offs;
432 urb->iso_frame_desc[i].length = subs->curpacksize;
433 offs += subs->curpacksize;
434 }
435 urb->transfer_buffer_length = offs;
436 urb->number_of_packets = ctx->packets;
437 return 0;
438}
439
440/*
441 * process after capture complete
442 *
443 * copy the data from each desctiptor to the pcm buffer, and
444 * update the current position.
445 */
446static int retire_capture_urb(struct snd_usb_substream *subs,
447 struct snd_pcm_runtime *runtime,
448 struct urb *urb)
449{
450 unsigned long flags;
451 unsigned char *cp;
452 int i;
453 unsigned int stride, frames, bytes, oldptr;
454 int period_elapsed = 0;
455
456 stride = runtime->frame_bits >> 3;
457
458 for (i = 0; i < urb->number_of_packets; i++) {
459 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
460 if (urb->iso_frame_desc[i].status) {
461 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
462 // continue;
463 }
464 bytes = urb->iso_frame_desc[i].actual_length;
465 frames = bytes / stride;
466 if (!subs->txfr_quirk)
467 bytes = frames * stride;
468 if (bytes % (runtime->sample_bits >> 3) != 0) {
469#ifdef CONFIG_SND_DEBUG_VERBOSE
470 int oldbytes = bytes;
471#endif
472 bytes = frames * stride;
473 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
474 oldbytes, bytes);
475 }
476 /* update the current pointer */
477 spin_lock_irqsave(&subs->lock, flags);
478 oldptr = subs->hwptr_done;
479 subs->hwptr_done += bytes;
480 if (subs->hwptr_done >= runtime->buffer_size * stride)
481 subs->hwptr_done -= runtime->buffer_size * stride;
482 frames = (bytes + (oldptr % stride)) / stride;
483 subs->transfer_done += frames;
484 if (subs->transfer_done >= runtime->period_size) {
485 subs->transfer_done -= runtime->period_size;
486 period_elapsed = 1;
487 }
488 spin_unlock_irqrestore(&subs->lock, flags);
489 /* copy a data chunk */
490 if (oldptr + bytes > runtime->buffer_size * stride) {
491 unsigned int bytes1 =
492 runtime->buffer_size * stride - oldptr;
493 memcpy(runtime->dma_area + oldptr, cp, bytes1);
494 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
495 } else {
496 memcpy(runtime->dma_area + oldptr, cp, bytes);
497 }
498 }
499 if (period_elapsed)
500 snd_pcm_period_elapsed(subs->pcm_substream);
501 return 0;
502}
503
504/*
505 * Process after capture complete when paused. Nothing to do.
506 */
507static int retire_paused_capture_urb(struct snd_usb_substream *subs,
508 struct snd_pcm_runtime *runtime,
509 struct urb *urb)
510{
511 return 0;
512}
513
514
515/*
516 * prepare urb for full speed playback sync pipe
517 *
518 * set up the offset and length to receive the current frequency.
519 */
520
521static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
522 struct snd_pcm_runtime *runtime,
523 struct urb *urb)
524{
525 struct snd_urb_ctx *ctx = urb->context;
526
527 urb->dev = ctx->subs->dev; /* we need to set this at each time */
528 urb->iso_frame_desc[0].length = 3;
529 urb->iso_frame_desc[0].offset = 0;
530 return 0;
531}
532
533/*
534 * prepare urb for high speed playback sync pipe
535 *
536 * set up the offset and length to receive the current frequency.
537 */
538
539static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
540 struct snd_pcm_runtime *runtime,
541 struct urb *urb)
542{
543 struct snd_urb_ctx *ctx = urb->context;
544
545 urb->dev = ctx->subs->dev; /* we need to set this at each time */
546 urb->iso_frame_desc[0].length = 4;
547 urb->iso_frame_desc[0].offset = 0;
548 return 0;
549}
550
551/*
552 * process after full speed playback sync complete
553 *
554 * retrieve the current 10.14 frequency from pipe, and set it.
555 * the value is referred in prepare_playback_urb().
556 */
557static int retire_playback_sync_urb(struct snd_usb_substream *subs,
558 struct snd_pcm_runtime *runtime,
559 struct urb *urb)
560{
561 unsigned int f;
562 unsigned long flags;
563
564 if (urb->iso_frame_desc[0].status == 0 &&
565 urb->iso_frame_desc[0].actual_length == 3) {
566 f = combine_triple((u8*)urb->transfer_buffer) << 2;
567 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
568 spin_lock_irqsave(&subs->lock, flags);
569 subs->freqm = f;
570 spin_unlock_irqrestore(&subs->lock, flags);
571 }
572 }
573
574 return 0;
575}
576
577/*
578 * process after high speed playback sync complete
579 *
580 * retrieve the current 12.13 frequency from pipe, and set it.
581 * the value is referred in prepare_playback_urb().
582 */
583static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
584 struct snd_pcm_runtime *runtime,
585 struct urb *urb)
586{
587 unsigned int f;
588 unsigned long flags;
589
590 if (urb->iso_frame_desc[0].status == 0 &&
591 urb->iso_frame_desc[0].actual_length == 4) {
592 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
593 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
594 spin_lock_irqsave(&subs->lock, flags);
595 subs->freqm = f;
596 spin_unlock_irqrestore(&subs->lock, flags);
597 }
598 }
599
600 return 0;
601}
602
603/*
604 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
605 *
606 * These devices return the number of samples per packet instead of the number
607 * of samples per microframe.
608 */
609static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
610 struct snd_pcm_runtime *runtime,
611 struct urb *urb)
612{
613 unsigned int f;
614 unsigned long flags;
615
616 if (urb->iso_frame_desc[0].status == 0 &&
617 urb->iso_frame_desc[0].actual_length == 4) {
618 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
619 f >>= subs->datainterval;
620 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
621 spin_lock_irqsave(&subs->lock, flags);
622 subs->freqm = f;
623 spin_unlock_irqrestore(&subs->lock, flags);
624 }
625 }
626
627 return 0;
628}
629
630/* determine the number of frames in the next packet */
631static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
632{
633 if (subs->fill_max)
634 return subs->maxframesize;
635 else {
636 subs->phase = (subs->phase & 0xffff)
637 + (subs->freqm << subs->datainterval);
638 return min(subs->phase >> 16, subs->maxframesize);
639 }
640}
641
642/*
643 * Prepare urb for streaming before playback starts or when paused.
644 *
645 * We don't have any data, so we send silence.
646 */
647static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
648 struct snd_pcm_runtime *runtime,
649 struct urb *urb)
650{
651 unsigned int i, offs, counts;
652 struct snd_urb_ctx *ctx = urb->context;
653 int stride = runtime->frame_bits >> 3;
654
655 offs = 0;
656 urb->dev = ctx->subs->dev;
657 for (i = 0; i < ctx->packets; ++i) {
658 counts = snd_usb_audio_next_packet_size(subs);
659 urb->iso_frame_desc[i].offset = offs * stride;
660 urb->iso_frame_desc[i].length = counts * stride;
661 offs += counts;
662 }
663 urb->number_of_packets = ctx->packets;
664 urb->transfer_buffer_length = offs * stride;
665 memset(urb->transfer_buffer,
666 runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
667 offs * stride);
668 return 0;
669}
670
671/*
672 * prepare urb for playback data pipe
673 *
674 * Since a URB can handle only a single linear buffer, we must use double
675 * buffering when the data to be transferred overflows the buffer boundary.
676 * To avoid inconsistencies when updating hwptr_done, we use double buffering
677 * for all URBs.
678 */
679static int prepare_playback_urb(struct snd_usb_substream *subs,
680 struct snd_pcm_runtime *runtime,
681 struct urb *urb)
682{
683 int i, stride;
684 unsigned int counts, frames, bytes;
685 unsigned long flags;
686 int period_elapsed = 0;
687 struct snd_urb_ctx *ctx = urb->context;
688
689 stride = runtime->frame_bits >> 3;
690
691 frames = 0;
692 urb->dev = ctx->subs->dev; /* we need to set this at each time */
693 urb->number_of_packets = 0;
694 spin_lock_irqsave(&subs->lock, flags);
695 for (i = 0; i < ctx->packets; i++) {
696 counts = snd_usb_audio_next_packet_size(subs);
697 /* set up descriptor */
698 urb->iso_frame_desc[i].offset = frames * stride;
699 urb->iso_frame_desc[i].length = counts * stride;
700 frames += counts;
701 urb->number_of_packets++;
702 subs->transfer_done += counts;
703 if (subs->transfer_done >= runtime->period_size) {
704 subs->transfer_done -= runtime->period_size;
705 period_elapsed = 1;
706 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
707 if (subs->transfer_done > 0) {
708 /* FIXME: fill-max mode is not
709 * supported yet */
710 frames -= subs->transfer_done;
711 counts -= subs->transfer_done;
712 urb->iso_frame_desc[i].length =
713 counts * stride;
714 subs->transfer_done = 0;
715 }
716 i++;
717 if (i < ctx->packets) {
718 /* add a transfer delimiter */
719 urb->iso_frame_desc[i].offset =
720 frames * stride;
721 urb->iso_frame_desc[i].length = 0;
722 urb->number_of_packets++;
723 }
724 break;
725 }
726 }
727 if (period_elapsed) /* finish at the period boundary */
728 break;
729 }
730 bytes = frames * stride;
731 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
732 /* err, the transferred area goes over buffer boundary. */
733 unsigned int bytes1 =
734 runtime->buffer_size * stride - subs->hwptr_done;
735 memcpy(urb->transfer_buffer,
736 runtime->dma_area + subs->hwptr_done, bytes1);
737 memcpy(urb->transfer_buffer + bytes1,
738 runtime->dma_area, bytes - bytes1);
739 } else {
740 memcpy(urb->transfer_buffer,
741 runtime->dma_area + subs->hwptr_done, bytes);
742 }
743 subs->hwptr_done += bytes;
744 if (subs->hwptr_done >= runtime->buffer_size * stride)
745 subs->hwptr_done -= runtime->buffer_size * stride;
746 runtime->delay += frames;
747 spin_unlock_irqrestore(&subs->lock, flags);
748 urb->transfer_buffer_length = bytes;
749 if (period_elapsed)
750 snd_pcm_period_elapsed(subs->pcm_substream);
751 return 0;
752}
753
754/*
755 * process after playback data complete
756 * - decrease the delay count again
757 */
758static int retire_playback_urb(struct snd_usb_substream *subs,
759 struct snd_pcm_runtime *runtime,
760 struct urb *urb)
761{
762 unsigned long flags;
763 int stride = runtime->frame_bits >> 3;
764 int processed = urb->transfer_buffer_length / stride;
765
766 spin_lock_irqsave(&subs->lock, flags);
767 if (processed > runtime->delay)
768 runtime->delay = 0;
769 else
770 runtime->delay -= processed;
771 spin_unlock_irqrestore(&subs->lock, flags);
772 return 0;
773}
774
775static const char *usb_error_string(int err)
776{
777 switch (err) {
778 case -ENODEV:
779 return "no device";
780 case -ENOENT:
781 return "endpoint not enabled";
782 case -EPIPE:
783 return "endpoint stalled";
784 case -ENOSPC:
785 return "not enough bandwidth";
786 case -ESHUTDOWN:
787 return "device disabled";
788 case -EHOSTUNREACH:
789 return "device suspended";
790 case -EINVAL:
791 case -EAGAIN:
792 case -EFBIG:
793 case -EMSGSIZE:
794 return "internal error";
795 default:
796 return "unknown error";
797 }
798}
799
800/*
801 * set up and start data/sync urbs
802 */
803static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
804{
805 unsigned int i;
806 int err;
807
808 if (subs->stream->chip->shutdown)
809 return -EBADFD;
810
811 for (i = 0; i < subs->nurbs; i++) {
812 if (snd_BUG_ON(!subs->dataurb[i].urb))
813 return -EINVAL;
814 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
815 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
816 goto __error;
817 }
818 }
819 if (subs->syncpipe) {
820 for (i = 0; i < SYNC_URBS; i++) {
821 if (snd_BUG_ON(!subs->syncurb[i].urb))
822 return -EINVAL;
823 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
824 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
825 goto __error;
826 }
827 }
828 }
829
830 subs->active_mask = 0;
831 subs->unlink_mask = 0;
832 subs->running = 1;
833 for (i = 0; i < subs->nurbs; i++) {
834 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
835 if (err < 0) {
836 snd_printk(KERN_ERR "cannot submit datapipe "
837 "for urb %d, error %d: %s\n",
838 i, err, usb_error_string(err));
839 goto __error;
840 }
841 set_bit(i, &subs->active_mask);
842 }
843 if (subs->syncpipe) {
844 for (i = 0; i < SYNC_URBS; i++) {
845 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
846 if (err < 0) {
847 snd_printk(KERN_ERR "cannot submit syncpipe "
848 "for urb %d, error %d: %s\n",
849 i, err, usb_error_string(err));
850 goto __error;
851 }
852 set_bit(i + 16, &subs->active_mask);
853 }
854 }
855 return 0;
856
857 __error:
858 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
859 deactivate_urbs(subs, 0, 0);
860 return -EPIPE;
861}
862
863
864/*
865 */
866static struct snd_urb_ops audio_urb_ops[2] = {
867 {
868 .prepare = prepare_nodata_playback_urb,
869 .retire = retire_playback_urb,
870 .prepare_sync = prepare_playback_sync_urb,
871 .retire_sync = retire_playback_sync_urb,
872 },
873 {
874 .prepare = prepare_capture_urb,
875 .retire = retire_capture_urb,
876 .prepare_sync = prepare_capture_sync_urb,
877 .retire_sync = retire_capture_sync_urb,
878 },
879};
880
881static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
882 {
883 .prepare = prepare_nodata_playback_urb,
884 .retire = retire_playback_urb,
885 .prepare_sync = prepare_playback_sync_urb_hs,
886 .retire_sync = retire_playback_sync_urb_hs,
887 },
888 {
889 .prepare = prepare_capture_urb,
890 .retire = retire_capture_urb,
891 .prepare_sync = prepare_capture_sync_urb_hs,
892 .retire_sync = retire_capture_sync_urb,
893 },
894};
895
896/*
897 * initialize the substream instance.
898 */
899
900void snd_usb_init_substream(struct snd_usb_stream *as,
901 int stream, struct audioformat *fp)
902{
903 struct snd_usb_substream *subs = &as->substream[stream];
904
905 INIT_LIST_HEAD(&subs->fmt_list);
906 spin_lock_init(&subs->lock);
907
908 subs->stream = as;
909 subs->direction = stream;
910 subs->dev = as->chip->dev;
911 subs->txfr_quirk = as->chip->txfr_quirk;
912 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
913 subs->ops = audio_urb_ops[stream];
914 } else {
915 subs->ops = audio_urb_ops_high_speed[stream];
916 switch (as->chip->usb_id) {
917 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
918 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
919 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
920 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
921 break;
922 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
923 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
924 subs->ops.prepare_sync = prepare_playback_sync_urb;
925 subs->ops.retire_sync = retire_playback_sync_urb;
926 break;
927 }
928 }
929
930 snd_usb_set_pcm_ops(as->pcm, stream);
931
932 list_add_tail(&fp->list, &subs->fmt_list);
933 subs->formats |= fp->formats;
934 subs->endpoint = fp->endpoint;
935 subs->num_formats++;
936 subs->fmt_type = fp->fmt_type;
937}
938
939int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
940{
941 struct snd_usb_substream *subs = substream->runtime->private_data;
942
943 switch (cmd) {
944 case SNDRV_PCM_TRIGGER_START:
945 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
946 subs->ops.prepare = prepare_playback_urb;
947 return 0;
948 case SNDRV_PCM_TRIGGER_STOP:
949 return deactivate_urbs(subs, 0, 0);
950 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
951 subs->ops.prepare = prepare_nodata_playback_urb;
952 return 0;
953 }
954
955 return -EINVAL;
956}
957
958int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
959{
960 struct snd_usb_substream *subs = substream->runtime->private_data;
961
962 switch (cmd) {
963 case SNDRV_PCM_TRIGGER_START:
964 subs->ops.retire = retire_capture_urb;
965 return start_urbs(subs, substream->runtime);
966 case SNDRV_PCM_TRIGGER_STOP:
967 return deactivate_urbs(subs, 0, 0);
968 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
969 subs->ops.retire = retire_paused_capture_urb;
970 return 0;
971 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
972 subs->ops.retire = retire_capture_urb;
973 return 0;
974 }
975
976 return -EINVAL;
977}
978
979int snd_usb_substream_prepare(struct snd_usb_substream *subs,
980 struct snd_pcm_runtime *runtime)
981{
982 /* clear urbs (to be sure) */
983 deactivate_urbs(subs, 0, 1);
984 wait_clear_urbs(subs);
985
986 /* for playback, submit the URBs now; otherwise, the first hwptr_done
987 * updates for all URBs would happen at the same time when starting */
988 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
989 subs->ops.prepare = prepare_nodata_playback_urb;
990 return start_urbs(subs, runtime);
991 }
992
993 return 0;
994}
995
diff --git a/sound/usb/urb.h b/sound/usb/urb.h
new file mode 100644
index 000000000000..888da38079cf
--- /dev/null
+++ b/sound/usb/urb.h
@@ -0,0 +1,21 @@
1#ifndef __USBAUDIO_URB_H
2#define __USBAUDIO_URB_H
3
4void snd_usb_init_substream(struct snd_usb_stream *as,
5 int stream,
6 struct audioformat *fp);
7
8int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
9 unsigned int period_bytes,
10 unsigned int rate,
11 unsigned int frame_bits);
12
13void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
14
15int snd_usb_substream_prepare(struct snd_usb_substream *subs,
16 struct snd_pcm_runtime *runtime);
17
18int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
19int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
20
21#endif /* __USBAUDIO_URB_H */
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
deleted file mode 100644
index 11b0826b8fe6..000000000000
--- a/sound/usb/usbaudio.c
+++ /dev/null
@@ -1,4050 +0,0 @@
1/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Main and PCM part
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 *
28 * NOTES:
29 *
30 * - async unlink should be used for avoiding the sleep inside lock.
31 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
32 * oops. in such a cse, pass async_unlink=0 option.
33 * - the linked URBs would be preferred but not used so far because of
34 * the instability of unlinking.
35 * - type II is not supported properly. there is no device which supports
36 * this type *correctly*. SB extigy looks as if it supports, but it's
37 * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
38 */
39
40
41#include <linux/bitops.h>
42#include <linux/init.h>
43#include <linux/list.h>
44#include <linux/slab.h>
45#include <linux/string.h>
46#include <linux/usb.h>
47#include <linux/moduleparam.h>
48#include <linux/mutex.h>
49#include <linux/usb/audio.h>
50#include <linux/usb/ch9.h>
51
52#include <sound/core.h>
53#include <sound/info.h>
54#include <sound/pcm.h>
55#include <sound/pcm_params.h>
56#include <sound/initval.h>
57
58#include "usbaudio.h"
59
60
61MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
62MODULE_DESCRIPTION("USB Audio");
63MODULE_LICENSE("GPL");
64MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
65
66
67static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
68static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
69static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
70/* Vendor/product IDs for this card */
71static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
72static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
73static int nrpacks = 8; /* max. number of packets per urb */
74static int async_unlink = 1;
75static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/
76static int ignore_ctl_error;
77
78module_param_array(index, int, NULL, 0444);
79MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
80module_param_array(id, charp, NULL, 0444);
81MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
82module_param_array(enable, bool, NULL, 0444);
83MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
84module_param_array(vid, int, NULL, 0444);
85MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
86module_param_array(pid, int, NULL, 0444);
87MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
88module_param(nrpacks, int, 0644);
89MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
90module_param(async_unlink, bool, 0444);
91MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
92module_param_array(device_setup, int, NULL, 0444);
93MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
94module_param(ignore_ctl_error, bool, 0444);
95MODULE_PARM_DESC(ignore_ctl_error,
96 "Ignore errors from USB controller for mixer interfaces.");
97
98/*
99 * debug the h/w constraints
100 */
101/* #define HW_CONST_DEBUG */
102
103
104/*
105 *
106 */
107
108#define MAX_PACKS 20
109#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
110#define MAX_URBS 8
111#define SYNC_URBS 4 /* always four urbs for sync */
112#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
113
114struct audioformat {
115 struct list_head list;
116 snd_pcm_format_t format; /* format type */
117 unsigned int channels; /* # channels */
118 unsigned int fmt_type; /* USB audio format type (1-3) */
119 unsigned int frame_size; /* samples per frame for non-audio */
120 int iface; /* interface number */
121 unsigned char altsetting; /* corresponding alternate setting */
122 unsigned char altset_idx; /* array index of altenate setting */
123 unsigned char attributes; /* corresponding attributes of cs endpoint */
124 unsigned char endpoint; /* endpoint */
125 unsigned char ep_attr; /* endpoint attributes */
126 unsigned char datainterval; /* log_2 of data packet interval */
127 unsigned int maxpacksize; /* max. packet size */
128 unsigned int rates; /* rate bitmasks */
129 unsigned int rate_min, rate_max; /* min/max rates */
130 unsigned int nr_rates; /* number of rate table entries */
131 unsigned int *rate_table; /* rate table */
132};
133
134struct snd_usb_substream;
135
136struct snd_urb_ctx {
137 struct urb *urb;
138 unsigned int buffer_size; /* size of data buffer, if data URB */
139 struct snd_usb_substream *subs;
140 int index; /* index for urb array */
141 int packets; /* number of packets per urb */
142};
143
144struct snd_urb_ops {
145 int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
146 int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
147 int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
148 int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
149};
150
151struct snd_usb_substream {
152 struct snd_usb_stream *stream;
153 struct usb_device *dev;
154 struct snd_pcm_substream *pcm_substream;
155 int direction; /* playback or capture */
156 int interface; /* current interface */
157 int endpoint; /* assigned endpoint */
158 struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
159 unsigned int cur_rate; /* current rate (for hw_params callback) */
160 unsigned int period_bytes; /* current period bytes (for hw_params callback) */
161 unsigned int format; /* USB data format */
162 unsigned int datapipe; /* the data i/o pipe */
163 unsigned int syncpipe; /* 1 - async out or adaptive in */
164 unsigned int datainterval; /* log_2 of data packet interval */
165 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
166 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
167 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
168 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
169 unsigned int phase; /* phase accumulator */
170 unsigned int maxpacksize; /* max packet size in bytes */
171 unsigned int maxframesize; /* max packet size in frames */
172 unsigned int curpacksize; /* current packet size in bytes (for capture) */
173 unsigned int curframesize; /* current packet size in frames (for capture) */
174 unsigned int fill_max: 1; /* fill max packet size always */
175 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
176 unsigned int fmt_type; /* USB audio format type (1-3) */
177
178 unsigned int running: 1; /* running status */
179
180 unsigned int hwptr_done; /* processed byte position in the buffer */
181 unsigned int transfer_done; /* processed frames since last period update */
182 unsigned long active_mask; /* bitmask of active urbs */
183 unsigned long unlink_mask; /* bitmask of unlinked urbs */
184
185 unsigned int nurbs; /* # urbs */
186 struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
187 struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
188 char *syncbuf; /* sync buffer for all sync URBs */
189 dma_addr_t sync_dma; /* DMA address of syncbuf */
190
191 u64 formats; /* format bitmasks (all or'ed) */
192 unsigned int num_formats; /* number of supported audio formats (list) */
193 struct list_head fmt_list; /* format list */
194 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
195 spinlock_t lock;
196
197 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
198};
199
200
201struct snd_usb_stream {
202 struct snd_usb_audio *chip;
203 struct snd_pcm *pcm;
204 int pcm_index;
205 unsigned int fmt_type; /* USB audio format type (1-3) */
206 struct snd_usb_substream substream[2];
207 struct list_head list;
208};
209
210
211/*
212 * we keep the snd_usb_audio_t instances by ourselves for merging
213 * the all interfaces on the same card as one sound device.
214 */
215
216static DEFINE_MUTEX(register_mutex);
217static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
218
219
220/*
221 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
222 * this will overflow at approx 524 kHz
223 */
224static inline unsigned get_usb_full_speed_rate(unsigned int rate)
225{
226 return ((rate << 13) + 62) / 125;
227}
228
229/*
230 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
231 * this will overflow at approx 4 MHz
232 */
233static inline unsigned get_usb_high_speed_rate(unsigned int rate)
234{
235 return ((rate << 10) + 62) / 125;
236}
237
238/* convert our full speed USB rate into sampling rate in Hz */
239static inline unsigned get_full_speed_hz(unsigned int usb_rate)
240{
241 return (usb_rate * 125 + (1 << 12)) >> 13;
242}
243
244/* convert our high speed USB rate into sampling rate in Hz */
245static inline unsigned get_high_speed_hz(unsigned int usb_rate)
246{
247 return (usb_rate * 125 + (1 << 9)) >> 10;
248}
249
250
251/*
252 * prepare urb for full speed capture sync pipe
253 *
254 * fill the length and offset of each urb descriptor.
255 * the fixed 10.14 frequency is passed through the pipe.
256 */
257static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
258 struct snd_pcm_runtime *runtime,
259 struct urb *urb)
260{
261 unsigned char *cp = urb->transfer_buffer;
262 struct snd_urb_ctx *ctx = urb->context;
263
264 urb->dev = ctx->subs->dev; /* we need to set this at each time */
265 urb->iso_frame_desc[0].length = 3;
266 urb->iso_frame_desc[0].offset = 0;
267 cp[0] = subs->freqn >> 2;
268 cp[1] = subs->freqn >> 10;
269 cp[2] = subs->freqn >> 18;
270 return 0;
271}
272
273/*
274 * prepare urb for high speed capture sync pipe
275 *
276 * fill the length and offset of each urb descriptor.
277 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
278 */
279static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
280 struct snd_pcm_runtime *runtime,
281 struct urb *urb)
282{
283 unsigned char *cp = urb->transfer_buffer;
284 struct snd_urb_ctx *ctx = urb->context;
285
286 urb->dev = ctx->subs->dev; /* we need to set this at each time */
287 urb->iso_frame_desc[0].length = 4;
288 urb->iso_frame_desc[0].offset = 0;
289 cp[0] = subs->freqn;
290 cp[1] = subs->freqn >> 8;
291 cp[2] = subs->freqn >> 16;
292 cp[3] = subs->freqn >> 24;
293 return 0;
294}
295
296/*
297 * process after capture sync complete
298 * - nothing to do
299 */
300static int retire_capture_sync_urb(struct snd_usb_substream *subs,
301 struct snd_pcm_runtime *runtime,
302 struct urb *urb)
303{
304 return 0;
305}
306
307/*
308 * prepare urb for capture data pipe
309 *
310 * fill the offset and length of each descriptor.
311 *
312 * we use a temporary buffer to write the captured data.
313 * since the length of written data is determined by host, we cannot
314 * write onto the pcm buffer directly... the data is thus copied
315 * later at complete callback to the global buffer.
316 */
317static int prepare_capture_urb(struct snd_usb_substream *subs,
318 struct snd_pcm_runtime *runtime,
319 struct urb *urb)
320{
321 int i, offs;
322 struct snd_urb_ctx *ctx = urb->context;
323
324 offs = 0;
325 urb->dev = ctx->subs->dev; /* we need to set this at each time */
326 for (i = 0; i < ctx->packets; i++) {
327 urb->iso_frame_desc[i].offset = offs;
328 urb->iso_frame_desc[i].length = subs->curpacksize;
329 offs += subs->curpacksize;
330 }
331 urb->transfer_buffer_length = offs;
332 urb->number_of_packets = ctx->packets;
333 return 0;
334}
335
336/*
337 * process after capture complete
338 *
339 * copy the data from each desctiptor to the pcm buffer, and
340 * update the current position.
341 */
342static int retire_capture_urb(struct snd_usb_substream *subs,
343 struct snd_pcm_runtime *runtime,
344 struct urb *urb)
345{
346 unsigned long flags;
347 unsigned char *cp;
348 int i;
349 unsigned int stride, frames, bytes, oldptr;
350 int period_elapsed = 0;
351
352 stride = runtime->frame_bits >> 3;
353
354 for (i = 0; i < urb->number_of_packets; i++) {
355 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
356 if (urb->iso_frame_desc[i].status) {
357 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
358 // continue;
359 }
360 bytes = urb->iso_frame_desc[i].actual_length;
361 frames = bytes / stride;
362 if (!subs->txfr_quirk)
363 bytes = frames * stride;
364 if (bytes % (runtime->sample_bits >> 3) != 0) {
365#ifdef CONFIG_SND_DEBUG_VERBOSE
366 int oldbytes = bytes;
367#endif
368 bytes = frames * stride;
369 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
370 oldbytes, bytes);
371 }
372 /* update the current pointer */
373 spin_lock_irqsave(&subs->lock, flags);
374 oldptr = subs->hwptr_done;
375 subs->hwptr_done += bytes;
376 if (subs->hwptr_done >= runtime->buffer_size * stride)
377 subs->hwptr_done -= runtime->buffer_size * stride;
378 frames = (bytes + (oldptr % stride)) / stride;
379 subs->transfer_done += frames;
380 if (subs->transfer_done >= runtime->period_size) {
381 subs->transfer_done -= runtime->period_size;
382 period_elapsed = 1;
383 }
384 spin_unlock_irqrestore(&subs->lock, flags);
385 /* copy a data chunk */
386 if (oldptr + bytes > runtime->buffer_size * stride) {
387 unsigned int bytes1 =
388 runtime->buffer_size * stride - oldptr;
389 memcpy(runtime->dma_area + oldptr, cp, bytes1);
390 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
391 } else {
392 memcpy(runtime->dma_area + oldptr, cp, bytes);
393 }
394 }
395 if (period_elapsed)
396 snd_pcm_period_elapsed(subs->pcm_substream);
397 return 0;
398}
399
400/*
401 * Process after capture complete when paused. Nothing to do.
402 */
403static int retire_paused_capture_urb(struct snd_usb_substream *subs,
404 struct snd_pcm_runtime *runtime,
405 struct urb *urb)
406{
407 return 0;
408}
409
410
411/*
412 * prepare urb for full speed playback sync pipe
413 *
414 * set up the offset and length to receive the current frequency.
415 */
416
417static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
418 struct snd_pcm_runtime *runtime,
419 struct urb *urb)
420{
421 struct snd_urb_ctx *ctx = urb->context;
422
423 urb->dev = ctx->subs->dev; /* we need to set this at each time */
424 urb->iso_frame_desc[0].length = 3;
425 urb->iso_frame_desc[0].offset = 0;
426 return 0;
427}
428
429/*
430 * prepare urb for high speed playback sync pipe
431 *
432 * set up the offset and length to receive the current frequency.
433 */
434
435static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
436 struct snd_pcm_runtime *runtime,
437 struct urb *urb)
438{
439 struct snd_urb_ctx *ctx = urb->context;
440
441 urb->dev = ctx->subs->dev; /* we need to set this at each time */
442 urb->iso_frame_desc[0].length = 4;
443 urb->iso_frame_desc[0].offset = 0;
444 return 0;
445}
446
447/*
448 * process after full speed playback sync complete
449 *
450 * retrieve the current 10.14 frequency from pipe, and set it.
451 * the value is referred in prepare_playback_urb().
452 */
453static int retire_playback_sync_urb(struct snd_usb_substream *subs,
454 struct snd_pcm_runtime *runtime,
455 struct urb *urb)
456{
457 unsigned int f;
458 unsigned long flags;
459
460 if (urb->iso_frame_desc[0].status == 0 &&
461 urb->iso_frame_desc[0].actual_length == 3) {
462 f = combine_triple((u8*)urb->transfer_buffer) << 2;
463 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
464 spin_lock_irqsave(&subs->lock, flags);
465 subs->freqm = f;
466 spin_unlock_irqrestore(&subs->lock, flags);
467 }
468 }
469
470 return 0;
471}
472
473/*
474 * process after high speed playback sync complete
475 *
476 * retrieve the current 12.13 frequency from pipe, and set it.
477 * the value is referred in prepare_playback_urb().
478 */
479static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
480 struct snd_pcm_runtime *runtime,
481 struct urb *urb)
482{
483 unsigned int f;
484 unsigned long flags;
485
486 if (urb->iso_frame_desc[0].status == 0 &&
487 urb->iso_frame_desc[0].actual_length == 4) {
488 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
489 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
490 spin_lock_irqsave(&subs->lock, flags);
491 subs->freqm = f;
492 spin_unlock_irqrestore(&subs->lock, flags);
493 }
494 }
495
496 return 0;
497}
498
499/*
500 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
501 *
502 * These devices return the number of samples per packet instead of the number
503 * of samples per microframe.
504 */
505static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
506 struct snd_pcm_runtime *runtime,
507 struct urb *urb)
508{
509 unsigned int f;
510 unsigned long flags;
511
512 if (urb->iso_frame_desc[0].status == 0 &&
513 urb->iso_frame_desc[0].actual_length == 4) {
514 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
515 f >>= subs->datainterval;
516 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
517 spin_lock_irqsave(&subs->lock, flags);
518 subs->freqm = f;
519 spin_unlock_irqrestore(&subs->lock, flags);
520 }
521 }
522
523 return 0;
524}
525
526/* determine the number of frames in the next packet */
527static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
528{
529 if (subs->fill_max)
530 return subs->maxframesize;
531 else {
532 subs->phase = (subs->phase & 0xffff)
533 + (subs->freqm << subs->datainterval);
534 return min(subs->phase >> 16, subs->maxframesize);
535 }
536}
537
538/*
539 * Prepare urb for streaming before playback starts or when paused.
540 *
541 * We don't have any data, so we send silence.
542 */
543static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
544 struct snd_pcm_runtime *runtime,
545 struct urb *urb)
546{
547 unsigned int i, offs, counts;
548 struct snd_urb_ctx *ctx = urb->context;
549 int stride = runtime->frame_bits >> 3;
550
551 offs = 0;
552 urb->dev = ctx->subs->dev;
553 for (i = 0; i < ctx->packets; ++i) {
554 counts = snd_usb_audio_next_packet_size(subs);
555 urb->iso_frame_desc[i].offset = offs * stride;
556 urb->iso_frame_desc[i].length = counts * stride;
557 offs += counts;
558 }
559 urb->number_of_packets = ctx->packets;
560 urb->transfer_buffer_length = offs * stride;
561 memset(urb->transfer_buffer,
562 subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
563 offs * stride);
564 return 0;
565}
566
567/*
568 * prepare urb for playback data pipe
569 *
570 * Since a URB can handle only a single linear buffer, we must use double
571 * buffering when the data to be transferred overflows the buffer boundary.
572 * To avoid inconsistencies when updating hwptr_done, we use double buffering
573 * for all URBs.
574 */
575static int prepare_playback_urb(struct snd_usb_substream *subs,
576 struct snd_pcm_runtime *runtime,
577 struct urb *urb)
578{
579 int i, stride;
580 unsigned int counts, frames, bytes;
581 unsigned long flags;
582 int period_elapsed = 0;
583 struct snd_urb_ctx *ctx = urb->context;
584
585 stride = runtime->frame_bits >> 3;
586
587 frames = 0;
588 urb->dev = ctx->subs->dev; /* we need to set this at each time */
589 urb->number_of_packets = 0;
590 spin_lock_irqsave(&subs->lock, flags);
591 for (i = 0; i < ctx->packets; i++) {
592 counts = snd_usb_audio_next_packet_size(subs);
593 /* set up descriptor */
594 urb->iso_frame_desc[i].offset = frames * stride;
595 urb->iso_frame_desc[i].length = counts * stride;
596 frames += counts;
597 urb->number_of_packets++;
598 subs->transfer_done += counts;
599 if (subs->transfer_done >= runtime->period_size) {
600 subs->transfer_done -= runtime->period_size;
601 period_elapsed = 1;
602 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
603 if (subs->transfer_done > 0) {
604 /* FIXME: fill-max mode is not
605 * supported yet */
606 frames -= subs->transfer_done;
607 counts -= subs->transfer_done;
608 urb->iso_frame_desc[i].length =
609 counts * stride;
610 subs->transfer_done = 0;
611 }
612 i++;
613 if (i < ctx->packets) {
614 /* add a transfer delimiter */
615 urb->iso_frame_desc[i].offset =
616 frames * stride;
617 urb->iso_frame_desc[i].length = 0;
618 urb->number_of_packets++;
619 }
620 break;
621 }
622 }
623 if (period_elapsed) /* finish at the period boundary */
624 break;
625 }
626 bytes = frames * stride;
627 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
628 /* err, the transferred area goes over buffer boundary. */
629 unsigned int bytes1 =
630 runtime->buffer_size * stride - subs->hwptr_done;
631 memcpy(urb->transfer_buffer,
632 runtime->dma_area + subs->hwptr_done, bytes1);
633 memcpy(urb->transfer_buffer + bytes1,
634 runtime->dma_area, bytes - bytes1);
635 } else {
636 memcpy(urb->transfer_buffer,
637 runtime->dma_area + subs->hwptr_done, bytes);
638 }
639 subs->hwptr_done += bytes;
640 if (subs->hwptr_done >= runtime->buffer_size * stride)
641 subs->hwptr_done -= runtime->buffer_size * stride;
642 runtime->delay += frames;
643 spin_unlock_irqrestore(&subs->lock, flags);
644 urb->transfer_buffer_length = bytes;
645 if (period_elapsed)
646 snd_pcm_period_elapsed(subs->pcm_substream);
647 return 0;
648}
649
650/*
651 * process after playback data complete
652 * - decrease the delay count again
653 */
654static int retire_playback_urb(struct snd_usb_substream *subs,
655 struct snd_pcm_runtime *runtime,
656 struct urb *urb)
657{
658 unsigned long flags;
659 int stride = runtime->frame_bits >> 3;
660 int processed = urb->transfer_buffer_length / stride;
661
662 spin_lock_irqsave(&subs->lock, flags);
663 if (processed > runtime->delay)
664 runtime->delay = 0;
665 else
666 runtime->delay -= processed;
667 spin_unlock_irqrestore(&subs->lock, flags);
668 return 0;
669}
670
671
672/*
673 */
674static struct snd_urb_ops audio_urb_ops[2] = {
675 {
676 .prepare = prepare_nodata_playback_urb,
677 .retire = retire_playback_urb,
678 .prepare_sync = prepare_playback_sync_urb,
679 .retire_sync = retire_playback_sync_urb,
680 },
681 {
682 .prepare = prepare_capture_urb,
683 .retire = retire_capture_urb,
684 .prepare_sync = prepare_capture_sync_urb,
685 .retire_sync = retire_capture_sync_urb,
686 },
687};
688
689static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
690 {
691 .prepare = prepare_nodata_playback_urb,
692 .retire = retire_playback_urb,
693 .prepare_sync = prepare_playback_sync_urb_hs,
694 .retire_sync = retire_playback_sync_urb_hs,
695 },
696 {
697 .prepare = prepare_capture_urb,
698 .retire = retire_capture_urb,
699 .prepare_sync = prepare_capture_sync_urb_hs,
700 .retire_sync = retire_capture_sync_urb,
701 },
702};
703
704/*
705 * complete callback from data urb
706 */
707static void snd_complete_urb(struct urb *urb)
708{
709 struct snd_urb_ctx *ctx = urb->context;
710 struct snd_usb_substream *subs = ctx->subs;
711 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
712 int err = 0;
713
714 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
715 !subs->running || /* can be stopped during retire callback */
716 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
717 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
718 clear_bit(ctx->index, &subs->active_mask);
719 if (err < 0) {
720 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
721 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
722 }
723 }
724}
725
726
727/*
728 * complete callback from sync urb
729 */
730static void snd_complete_sync_urb(struct urb *urb)
731{
732 struct snd_urb_ctx *ctx = urb->context;
733 struct snd_usb_substream *subs = ctx->subs;
734 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
735 int err = 0;
736
737 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
738 !subs->running || /* can be stopped during retire callback */
739 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
740 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
741 clear_bit(ctx->index + 16, &subs->active_mask);
742 if (err < 0) {
743 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
744 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
745 }
746 }
747}
748
749
750/*
751 * unlink active urbs.
752 */
753static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
754{
755 unsigned int i;
756 int async;
757
758 subs->running = 0;
759
760 if (!force && subs->stream->chip->shutdown) /* to be sure... */
761 return -EBADFD;
762
763 async = !can_sleep && async_unlink;
764
765 if (!async && in_interrupt())
766 return 0;
767
768 for (i = 0; i < subs->nurbs; i++) {
769 if (test_bit(i, &subs->active_mask)) {
770 if (!test_and_set_bit(i, &subs->unlink_mask)) {
771 struct urb *u = subs->dataurb[i].urb;
772 if (async)
773 usb_unlink_urb(u);
774 else
775 usb_kill_urb(u);
776 }
777 }
778 }
779 if (subs->syncpipe) {
780 for (i = 0; i < SYNC_URBS; i++) {
781 if (test_bit(i+16, &subs->active_mask)) {
782 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
783 struct urb *u = subs->syncurb[i].urb;
784 if (async)
785 usb_unlink_urb(u);
786 else
787 usb_kill_urb(u);
788 }
789 }
790 }
791 }
792 return 0;
793}
794
795
796static const char *usb_error_string(int err)
797{
798 switch (err) {
799 case -ENODEV:
800 return "no device";
801 case -ENOENT:
802 return "endpoint not enabled";
803 case -EPIPE:
804 return "endpoint stalled";
805 case -ENOSPC:
806 return "not enough bandwidth";
807 case -ESHUTDOWN:
808 return "device disabled";
809 case -EHOSTUNREACH:
810 return "device suspended";
811 case -EINVAL:
812 case -EAGAIN:
813 case -EFBIG:
814 case -EMSGSIZE:
815 return "internal error";
816 default:
817 return "unknown error";
818 }
819}
820
821/*
822 * set up and start data/sync urbs
823 */
824static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
825{
826 unsigned int i;
827 int err;
828
829 if (subs->stream->chip->shutdown)
830 return -EBADFD;
831
832 for (i = 0; i < subs->nurbs; i++) {
833 if (snd_BUG_ON(!subs->dataurb[i].urb))
834 return -EINVAL;
835 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
836 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
837 goto __error;
838 }
839 }
840 if (subs->syncpipe) {
841 for (i = 0; i < SYNC_URBS; i++) {
842 if (snd_BUG_ON(!subs->syncurb[i].urb))
843 return -EINVAL;
844 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
845 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
846 goto __error;
847 }
848 }
849 }
850
851 subs->active_mask = 0;
852 subs->unlink_mask = 0;
853 subs->running = 1;
854 for (i = 0; i < subs->nurbs; i++) {
855 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
856 if (err < 0) {
857 snd_printk(KERN_ERR "cannot submit datapipe "
858 "for urb %d, error %d: %s\n",
859 i, err, usb_error_string(err));
860 goto __error;
861 }
862 set_bit(i, &subs->active_mask);
863 }
864 if (subs->syncpipe) {
865 for (i = 0; i < SYNC_URBS; i++) {
866 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
867 if (err < 0) {
868 snd_printk(KERN_ERR "cannot submit syncpipe "
869 "for urb %d, error %d: %s\n",
870 i, err, usb_error_string(err));
871 goto __error;
872 }
873 set_bit(i + 16, &subs->active_mask);
874 }
875 }
876 return 0;
877
878 __error:
879 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
880 deactivate_urbs(subs, 0, 0);
881 return -EPIPE;
882}
883
884
885/*
886 * wait until all urbs are processed.
887 */
888static int wait_clear_urbs(struct snd_usb_substream *subs)
889{
890 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
891 unsigned int i;
892 int alive;
893
894 do {
895 alive = 0;
896 for (i = 0; i < subs->nurbs; i++) {
897 if (test_bit(i, &subs->active_mask))
898 alive++;
899 }
900 if (subs->syncpipe) {
901 for (i = 0; i < SYNC_URBS; i++) {
902 if (test_bit(i + 16, &subs->active_mask))
903 alive++;
904 }
905 }
906 if (! alive)
907 break;
908 schedule_timeout_uninterruptible(1);
909 } while (time_before(jiffies, end_time));
910 if (alive)
911 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
912 return 0;
913}
914
915
916/*
917 * return the current pcm pointer. just based on the hwptr_done value.
918 */
919static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
920{
921 struct snd_usb_substream *subs;
922 unsigned int hwptr_done;
923
924 subs = (struct snd_usb_substream *)substream->runtime->private_data;
925 spin_lock(&subs->lock);
926 hwptr_done = subs->hwptr_done;
927 spin_unlock(&subs->lock);
928 return hwptr_done / (substream->runtime->frame_bits >> 3);
929}
930
931
932/*
933 * start/stop playback substream
934 */
935static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream,
936 int cmd)
937{
938 struct snd_usb_substream *subs = substream->runtime->private_data;
939
940 switch (cmd) {
941 case SNDRV_PCM_TRIGGER_START:
942 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
943 subs->ops.prepare = prepare_playback_urb;
944 return 0;
945 case SNDRV_PCM_TRIGGER_STOP:
946 return deactivate_urbs(subs, 0, 0);
947 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
948 subs->ops.prepare = prepare_nodata_playback_urb;
949 return 0;
950 default:
951 return -EINVAL;
952 }
953}
954
955/*
956 * start/stop capture substream
957 */
958static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream,
959 int cmd)
960{
961 struct snd_usb_substream *subs = substream->runtime->private_data;
962
963 switch (cmd) {
964 case SNDRV_PCM_TRIGGER_START:
965 subs->ops.retire = retire_capture_urb;
966 return start_urbs(subs, substream->runtime);
967 case SNDRV_PCM_TRIGGER_STOP:
968 return deactivate_urbs(subs, 0, 0);
969 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
970 subs->ops.retire = retire_paused_capture_urb;
971 return 0;
972 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
973 subs->ops.retire = retire_capture_urb;
974 return 0;
975 default:
976 return -EINVAL;
977 }
978}
979
980
981/*
982 * release a urb data
983 */
984static void release_urb_ctx(struct snd_urb_ctx *u)
985{
986 if (u->urb) {
987 if (u->buffer_size)
988 usb_buffer_free(u->subs->dev, u->buffer_size,
989 u->urb->transfer_buffer,
990 u->urb->transfer_dma);
991 usb_free_urb(u->urb);
992 u->urb = NULL;
993 }
994}
995
996/*
997 * release a substream
998 */
999static void release_substream_urbs(struct snd_usb_substream *subs, int force)
1000{
1001 int i;
1002
1003 /* stop urbs (to be sure) */
1004 deactivate_urbs(subs, force, 1);
1005 wait_clear_urbs(subs);
1006
1007 for (i = 0; i < MAX_URBS; i++)
1008 release_urb_ctx(&subs->dataurb[i]);
1009 for (i = 0; i < SYNC_URBS; i++)
1010 release_urb_ctx(&subs->syncurb[i]);
1011 usb_buffer_free(subs->dev, SYNC_URBS * 4,
1012 subs->syncbuf, subs->sync_dma);
1013 subs->syncbuf = NULL;
1014 subs->nurbs = 0;
1015}
1016
1017/*
1018 * initialize a substream for plaback/capture
1019 */
1020static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes,
1021 unsigned int rate, unsigned int frame_bits)
1022{
1023 unsigned int maxsize, i;
1024 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
1025 unsigned int urb_packs, total_packs, packs_per_ms;
1026
1027 /* calculate the frequency in 16.16 format */
1028 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
1029 subs->freqn = get_usb_full_speed_rate(rate);
1030 else
1031 subs->freqn = get_usb_high_speed_rate(rate);
1032 subs->freqm = subs->freqn;
1033 /* calculate max. frequency */
1034 if (subs->maxpacksize) {
1035 /* whatever fits into a max. size packet */
1036 maxsize = subs->maxpacksize;
1037 subs->freqmax = (maxsize / (frame_bits >> 3))
1038 << (16 - subs->datainterval);
1039 } else {
1040 /* no max. packet size: just take 25% higher than nominal */
1041 subs->freqmax = subs->freqn + (subs->freqn >> 2);
1042 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
1043 >> (16 - subs->datainterval);
1044 }
1045 subs->phase = 0;
1046
1047 if (subs->fill_max)
1048 subs->curpacksize = subs->maxpacksize;
1049 else
1050 subs->curpacksize = maxsize;
1051
1052 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
1053 packs_per_ms = 8 >> subs->datainterval;
1054 else
1055 packs_per_ms = 1;
1056
1057 if (is_playback) {
1058 urb_packs = max(nrpacks, 1);
1059 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
1060 } else
1061 urb_packs = 1;
1062 urb_packs *= packs_per_ms;
1063 if (subs->syncpipe)
1064 urb_packs = min(urb_packs, 1U << subs->syncinterval);
1065
1066 /* decide how many packets to be used */
1067 if (is_playback) {
1068 unsigned int minsize, maxpacks;
1069 /* determine how small a packet can be */
1070 minsize = (subs->freqn >> (16 - subs->datainterval))
1071 * (frame_bits >> 3);
1072 /* with sync from device, assume it can be 12% lower */
1073 if (subs->syncpipe)
1074 minsize -= minsize >> 3;
1075 minsize = max(minsize, 1u);
1076 total_packs = (period_bytes + minsize - 1) / minsize;
1077 /* we need at least two URBs for queueing */
1078 if (total_packs < 2) {
1079 total_packs = 2;
1080 } else {
1081 /* and we don't want too long a queue either */
1082 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
1083 total_packs = min(total_packs, maxpacks);
1084 }
1085 } else {
1086 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
1087 urb_packs >>= 1;
1088 total_packs = MAX_URBS * urb_packs;
1089 }
1090 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
1091 if (subs->nurbs > MAX_URBS) {
1092 /* too much... */
1093 subs->nurbs = MAX_URBS;
1094 total_packs = MAX_URBS * urb_packs;
1095 } else if (subs->nurbs < 2) {
1096 /* too little - we need at least two packets
1097 * to ensure contiguous playback/capture
1098 */
1099 subs->nurbs = 2;
1100 }
1101
1102 /* allocate and initialize data urbs */
1103 for (i = 0; i < subs->nurbs; i++) {
1104 struct snd_urb_ctx *u = &subs->dataurb[i];
1105 u->index = i;
1106 u->subs = subs;
1107 u->packets = (i + 1) * total_packs / subs->nurbs
1108 - i * total_packs / subs->nurbs;
1109 u->buffer_size = maxsize * u->packets;
1110 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
1111 u->packets++; /* for transfer delimiter */
1112 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
1113 if (!u->urb)
1114 goto out_of_memory;
1115 u->urb->transfer_buffer =
1116 usb_buffer_alloc(subs->dev, u->buffer_size, GFP_KERNEL,
1117 &u->urb->transfer_dma);
1118 if (!u->urb->transfer_buffer)
1119 goto out_of_memory;
1120 u->urb->pipe = subs->datapipe;
1121 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
1122 u->urb->interval = 1 << subs->datainterval;
1123 u->urb->context = u;
1124 u->urb->complete = snd_complete_urb;
1125 }
1126
1127 if (subs->syncpipe) {
1128 /* allocate and initialize sync urbs */
1129 subs->syncbuf = usb_buffer_alloc(subs->dev, SYNC_URBS * 4,
1130 GFP_KERNEL, &subs->sync_dma);
1131 if (!subs->syncbuf)
1132 goto out_of_memory;
1133 for (i = 0; i < SYNC_URBS; i++) {
1134 struct snd_urb_ctx *u = &subs->syncurb[i];
1135 u->index = i;
1136 u->subs = subs;
1137 u->packets = 1;
1138 u->urb = usb_alloc_urb(1, GFP_KERNEL);
1139 if (!u->urb)
1140 goto out_of_memory;
1141 u->urb->transfer_buffer = subs->syncbuf + i * 4;
1142 u->urb->transfer_dma = subs->sync_dma + i * 4;
1143 u->urb->transfer_buffer_length = 4;
1144 u->urb->pipe = subs->syncpipe;
1145 u->urb->transfer_flags = URB_ISO_ASAP |
1146 URB_NO_TRANSFER_DMA_MAP;
1147 u->urb->number_of_packets = 1;
1148 u->urb->interval = 1 << subs->syncinterval;
1149 u->urb->context = u;
1150 u->urb->complete = snd_complete_sync_urb;
1151 }
1152 }
1153 return 0;
1154
1155out_of_memory:
1156 release_substream_urbs(subs, 0);
1157 return -ENOMEM;
1158}
1159
1160
1161/*
1162 * find a matching audio format
1163 */
1164static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
1165 unsigned int rate, unsigned int channels)
1166{
1167 struct list_head *p;
1168 struct audioformat *found = NULL;
1169 int cur_attr = 0, attr;
1170
1171 list_for_each(p, &subs->fmt_list) {
1172 struct audioformat *fp;
1173 fp = list_entry(p, struct audioformat, list);
1174 if (fp->format != format || fp->channels != channels)
1175 continue;
1176 if (rate < fp->rate_min || rate > fp->rate_max)
1177 continue;
1178 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
1179 unsigned int i;
1180 for (i = 0; i < fp->nr_rates; i++)
1181 if (fp->rate_table[i] == rate)
1182 break;
1183 if (i >= fp->nr_rates)
1184 continue;
1185 }
1186 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
1187 if (! found) {
1188 found = fp;
1189 cur_attr = attr;
1190 continue;
1191 }
1192 /* avoid async out and adaptive in if the other method
1193 * supports the same format.
1194 * this is a workaround for the case like
1195 * M-audio audiophile USB.
1196 */
1197 if (attr != cur_attr) {
1198 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
1199 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1200 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1201 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
1202 continue;
1203 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
1204 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1205 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1206 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
1207 found = fp;
1208 cur_attr = attr;
1209 continue;
1210 }
1211 }
1212 /* find the format with the largest max. packet size */
1213 if (fp->maxpacksize > found->maxpacksize) {
1214 found = fp;
1215 cur_attr = attr;
1216 }
1217 }
1218 return found;
1219}
1220
1221
1222/*
1223 * initialize the picth control and sample rate
1224 */
1225static int init_usb_pitch(struct usb_device *dev, int iface,
1226 struct usb_host_interface *alts,
1227 struct audioformat *fmt)
1228{
1229 unsigned int ep;
1230 unsigned char data[1];
1231 int err;
1232
1233 ep = get_endpoint(alts, 0)->bEndpointAddress;
1234 /* if endpoint has pitch control, enable it */
1235 if (fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL) {
1236 data[0] = 1;
1237 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1238 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1239 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
1240 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
1241 dev->devnum, iface, ep);
1242 return err;
1243 }
1244 }
1245 return 0;
1246}
1247
1248static int init_usb_sample_rate(struct usb_device *dev, int iface,
1249 struct usb_host_interface *alts,
1250 struct audioformat *fmt, int rate)
1251{
1252 unsigned int ep;
1253 unsigned char data[3];
1254 int err;
1255
1256 ep = get_endpoint(alts, 0)->bEndpointAddress;
1257 /* if endpoint has sampling rate control, set it */
1258 if (fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE) {
1259 int crate;
1260 data[0] = rate;
1261 data[1] = rate >> 8;
1262 data[2] = rate >> 16;
1263 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1264 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1265 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1266 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
1267 dev->devnum, iface, fmt->altsetting, rate, ep);
1268 return err;
1269 }
1270 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
1271 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
1272 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1273 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
1274 dev->devnum, iface, fmt->altsetting, ep);
1275 return 0; /* some devices don't support reading */
1276 }
1277 crate = data[0] | (data[1] << 8) | (data[2] << 16);
1278 if (crate != rate) {
1279 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
1280 // runtime->rate = crate;
1281 }
1282 }
1283 return 0;
1284}
1285
1286/*
1287 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
1288 * not for interface.
1289 */
1290static void set_format_emu_quirk(struct snd_usb_substream *subs,
1291 struct audioformat *fmt)
1292{
1293 unsigned char emu_samplerate_id = 0;
1294
1295 /* When capture is active
1296 * sample rate shouldn't be changed
1297 * by playback substream
1298 */
1299 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1300 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
1301 return;
1302 }
1303
1304 switch (fmt->rate_min) {
1305 case 48000:
1306 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1307 break;
1308 case 88200:
1309 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1310 break;
1311 case 96000:
1312 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1313 break;
1314 case 176400:
1315 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1316 break;
1317 case 192000:
1318 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1319 break;
1320 default:
1321 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1322 break;
1323 }
1324 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
1325}
1326
1327/*
1328 * find a matching format and set up the interface
1329 */
1330static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1331{
1332 struct usb_device *dev = subs->dev;
1333 struct usb_host_interface *alts;
1334 struct usb_interface_descriptor *altsd;
1335 struct usb_interface *iface;
1336 unsigned int ep, attr;
1337 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
1338 int err;
1339
1340 iface = usb_ifnum_to_if(dev, fmt->iface);
1341 if (WARN_ON(!iface))
1342 return -EINVAL;
1343 alts = &iface->altsetting[fmt->altset_idx];
1344 altsd = get_iface_desc(alts);
1345 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
1346 return -EINVAL;
1347
1348 if (fmt == subs->cur_audiofmt)
1349 return 0;
1350
1351 /* close the old interface */
1352 if (subs->interface >= 0 && subs->interface != fmt->iface) {
1353 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
1354 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
1355 dev->devnum, fmt->iface, fmt->altsetting);
1356 return -EIO;
1357 }
1358 subs->interface = -1;
1359 subs->format = 0;
1360 }
1361
1362 /* set interface */
1363 if (subs->interface != fmt->iface || subs->format != fmt->altset_idx) {
1364 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
1365 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
1366 dev->devnum, fmt->iface, fmt->altsetting);
1367 return -EIO;
1368 }
1369 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
1370 subs->interface = fmt->iface;
1371 subs->format = fmt->altset_idx;
1372 }
1373
1374 /* create a data pipe */
1375 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
1376 if (is_playback)
1377 subs->datapipe = usb_sndisocpipe(dev, ep);
1378 else
1379 subs->datapipe = usb_rcvisocpipe(dev, ep);
1380 subs->datainterval = fmt->datainterval;
1381 subs->syncpipe = subs->syncinterval = 0;
1382 subs->maxpacksize = fmt->maxpacksize;
1383 subs->fill_max = 0;
1384
1385 /* we need a sync pipe in async OUT or adaptive IN mode */
1386 /* check the number of EP, since some devices have broken
1387 * descriptors which fool us. if it has only one EP,
1388 * assume it as adaptive-out or sync-in.
1389 */
1390 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
1391 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
1392 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
1393 altsd->bNumEndpoints >= 2) {
1394 /* check sync-pipe endpoint */
1395 /* ... and check descriptor size before accessing bSynchAddress
1396 because there is a version of the SB Audigy 2 NX firmware lacking
1397 the audio fields in the endpoint descriptors */
1398 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
1399 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1400 get_endpoint(alts, 1)->bSynchAddress != 0)) {
1401 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
1402 dev->devnum, fmt->iface, fmt->altsetting);
1403 return -EINVAL;
1404 }
1405 ep = get_endpoint(alts, 1)->bEndpointAddress;
1406 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1407 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
1408 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
1409 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
1410 dev->devnum, fmt->iface, fmt->altsetting);
1411 return -EINVAL;
1412 }
1413 ep &= USB_ENDPOINT_NUMBER_MASK;
1414 if (is_playback)
1415 subs->syncpipe = usb_rcvisocpipe(dev, ep);
1416 else
1417 subs->syncpipe = usb_sndisocpipe(dev, ep);
1418 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1419 get_endpoint(alts, 1)->bRefresh >= 1 &&
1420 get_endpoint(alts, 1)->bRefresh <= 9)
1421 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
1422 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
1423 subs->syncinterval = 1;
1424 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
1425 get_endpoint(alts, 1)->bInterval <= 16)
1426 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
1427 else
1428 subs->syncinterval = 3;
1429 }
1430
1431 /* always fill max packet size */
1432 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
1433 subs->fill_max = 1;
1434
1435 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0)
1436 return err;
1437
1438 subs->cur_audiofmt = fmt;
1439
1440 switch (subs->stream->chip->usb_id) {
1441 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1442 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1443 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
1444 set_format_emu_quirk(subs, fmt);
1445 break;
1446 }
1447
1448#if 0
1449 printk(KERN_DEBUG
1450 "setting done: format = %d, rate = %d..%d, channels = %d\n",
1451 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
1452 printk(KERN_DEBUG
1453 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
1454 subs->datapipe, subs->syncpipe);
1455#endif
1456
1457 return 0;
1458}
1459
1460/*
1461 * hw_params callback
1462 *
1463 * allocate a buffer and set the given audio format.
1464 *
1465 * so far we use a physically linear buffer although packetize transfer
1466 * doesn't need a continuous area.
1467 * if sg buffer is supported on the later version of alsa, we'll follow
1468 * that.
1469 */
1470static int snd_usb_hw_params(struct snd_pcm_substream *substream,
1471 struct snd_pcm_hw_params *hw_params)
1472{
1473 struct snd_usb_substream *subs = substream->runtime->private_data;
1474 struct audioformat *fmt;
1475 unsigned int channels, rate, format;
1476 int ret, changed;
1477
1478 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
1479 params_buffer_bytes(hw_params));
1480 if (ret < 0)
1481 return ret;
1482
1483 format = params_format(hw_params);
1484 rate = params_rate(hw_params);
1485 channels = params_channels(hw_params);
1486 fmt = find_format(subs, format, rate, channels);
1487 if (!fmt) {
1488 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
1489 format, rate, channels);
1490 return -EINVAL;
1491 }
1492
1493 changed = subs->cur_audiofmt != fmt ||
1494 subs->period_bytes != params_period_bytes(hw_params) ||
1495 subs->cur_rate != rate;
1496 if ((ret = set_format(subs, fmt)) < 0)
1497 return ret;
1498
1499 if (subs->cur_rate != rate) {
1500 struct usb_host_interface *alts;
1501 struct usb_interface *iface;
1502 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
1503 alts = &iface->altsetting[fmt->altset_idx];
1504 ret = init_usb_sample_rate(subs->dev, subs->interface, alts, fmt, rate);
1505 if (ret < 0)
1506 return ret;
1507 subs->cur_rate = rate;
1508 }
1509
1510 if (changed) {
1511 /* format changed */
1512 release_substream_urbs(subs, 0);
1513 /* influenced: period_bytes, channels, rate, format, */
1514 ret = init_substream_urbs(subs, params_period_bytes(hw_params),
1515 params_rate(hw_params),
1516 snd_pcm_format_physical_width(params_format(hw_params)) * params_channels(hw_params));
1517 }
1518
1519 return ret;
1520}
1521
1522/*
1523 * hw_free callback
1524 *
1525 * reset the audio format and release the buffer
1526 */
1527static int snd_usb_hw_free(struct snd_pcm_substream *substream)
1528{
1529 struct snd_usb_substream *subs = substream->runtime->private_data;
1530
1531 subs->cur_audiofmt = NULL;
1532 subs->cur_rate = 0;
1533 subs->period_bytes = 0;
1534 if (!subs->stream->chip->shutdown)
1535 release_substream_urbs(subs, 0);
1536 return snd_pcm_lib_free_vmalloc_buffer(substream);
1537}
1538
1539/*
1540 * prepare callback
1541 *
1542 * only a few subtle things...
1543 */
1544static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
1545{
1546 struct snd_pcm_runtime *runtime = substream->runtime;
1547 struct snd_usb_substream *subs = runtime->private_data;
1548
1549 if (! subs->cur_audiofmt) {
1550 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
1551 return -ENXIO;
1552 }
1553
1554 /* some unit conversions in runtime */
1555 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
1556 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
1557
1558 /* reset the pointer */
1559 subs->hwptr_done = 0;
1560 subs->transfer_done = 0;
1561 subs->phase = 0;
1562 runtime->delay = 0;
1563
1564 /* clear urbs (to be sure) */
1565 deactivate_urbs(subs, 0, 1);
1566 wait_clear_urbs(subs);
1567
1568 /* for playback, submit the URBs now; otherwise, the first hwptr_done
1569 * updates for all URBs would happen at the same time when starting */
1570 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1571 subs->ops.prepare = prepare_nodata_playback_urb;
1572 return start_urbs(subs, runtime);
1573 } else
1574 return 0;
1575}
1576
1577static struct snd_pcm_hardware snd_usb_hardware =
1578{
1579 .info = SNDRV_PCM_INFO_MMAP |
1580 SNDRV_PCM_INFO_MMAP_VALID |
1581 SNDRV_PCM_INFO_BATCH |
1582 SNDRV_PCM_INFO_INTERLEAVED |
1583 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1584 SNDRV_PCM_INFO_PAUSE,
1585 .buffer_bytes_max = 1024 * 1024,
1586 .period_bytes_min = 64,
1587 .period_bytes_max = 512 * 1024,
1588 .periods_min = 2,
1589 .periods_max = 1024,
1590};
1591
1592/*
1593 * h/w constraints
1594 */
1595
1596#ifdef HW_CONST_DEBUG
1597#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
1598#else
1599#define hwc_debug(fmt, args...) /**/
1600#endif
1601
1602static int hw_check_valid_format(struct snd_usb_substream *subs,
1603 struct snd_pcm_hw_params *params,
1604 struct audioformat *fp)
1605{
1606 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1607 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1608 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1609 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1610 unsigned int ptime;
1611
1612 /* check the format */
1613 if (!snd_mask_test(fmts, fp->format)) {
1614 hwc_debug(" > check: no supported format %d\n", fp->format);
1615 return 0;
1616 }
1617 /* check the channels */
1618 if (fp->channels < ct->min || fp->channels > ct->max) {
1619 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
1620 return 0;
1621 }
1622 /* check the rate is within the range */
1623 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
1624 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
1625 return 0;
1626 }
1627 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
1628 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
1629 return 0;
1630 }
1631 /* check whether the period time is >= the data packet interval */
1632 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
1633 ptime = 125 * (1 << fp->datainterval);
1634 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
1635 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
1636 return 0;
1637 }
1638 }
1639 return 1;
1640}
1641
1642static int hw_rule_rate(struct snd_pcm_hw_params *params,
1643 struct snd_pcm_hw_rule *rule)
1644{
1645 struct snd_usb_substream *subs = rule->private;
1646 struct list_head *p;
1647 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1648 unsigned int rmin, rmax;
1649 int changed;
1650
1651 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
1652 changed = 0;
1653 rmin = rmax = 0;
1654 list_for_each(p, &subs->fmt_list) {
1655 struct audioformat *fp;
1656 fp = list_entry(p, struct audioformat, list);
1657 if (!hw_check_valid_format(subs, params, fp))
1658 continue;
1659 if (changed++) {
1660 if (rmin > fp->rate_min)
1661 rmin = fp->rate_min;
1662 if (rmax < fp->rate_max)
1663 rmax = fp->rate_max;
1664 } else {
1665 rmin = fp->rate_min;
1666 rmax = fp->rate_max;
1667 }
1668 }
1669
1670 if (!changed) {
1671 hwc_debug(" --> get empty\n");
1672 it->empty = 1;
1673 return -EINVAL;
1674 }
1675
1676 changed = 0;
1677 if (it->min < rmin) {
1678 it->min = rmin;
1679 it->openmin = 0;
1680 changed = 1;
1681 }
1682 if (it->max > rmax) {
1683 it->max = rmax;
1684 it->openmax = 0;
1685 changed = 1;
1686 }
1687 if (snd_interval_checkempty(it)) {
1688 it->empty = 1;
1689 return -EINVAL;
1690 }
1691 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
1692 return changed;
1693}
1694
1695
1696static int hw_rule_channels(struct snd_pcm_hw_params *params,
1697 struct snd_pcm_hw_rule *rule)
1698{
1699 struct snd_usb_substream *subs = rule->private;
1700 struct list_head *p;
1701 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1702 unsigned int rmin, rmax;
1703 int changed;
1704
1705 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
1706 changed = 0;
1707 rmin = rmax = 0;
1708 list_for_each(p, &subs->fmt_list) {
1709 struct audioformat *fp;
1710 fp = list_entry(p, struct audioformat, list);
1711 if (!hw_check_valid_format(subs, params, fp))
1712 continue;
1713 if (changed++) {
1714 if (rmin > fp->channels)
1715 rmin = fp->channels;
1716 if (rmax < fp->channels)
1717 rmax = fp->channels;
1718 } else {
1719 rmin = fp->channels;
1720 rmax = fp->channels;
1721 }
1722 }
1723
1724 if (!changed) {
1725 hwc_debug(" --> get empty\n");
1726 it->empty = 1;
1727 return -EINVAL;
1728 }
1729
1730 changed = 0;
1731 if (it->min < rmin) {
1732 it->min = rmin;
1733 it->openmin = 0;
1734 changed = 1;
1735 }
1736 if (it->max > rmax) {
1737 it->max = rmax;
1738 it->openmax = 0;
1739 changed = 1;
1740 }
1741 if (snd_interval_checkempty(it)) {
1742 it->empty = 1;
1743 return -EINVAL;
1744 }
1745 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
1746 return changed;
1747}
1748
1749static int hw_rule_format(struct snd_pcm_hw_params *params,
1750 struct snd_pcm_hw_rule *rule)
1751{
1752 struct snd_usb_substream *subs = rule->private;
1753 struct list_head *p;
1754 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1755 u64 fbits;
1756 u32 oldbits[2];
1757 int changed;
1758
1759 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
1760 fbits = 0;
1761 list_for_each(p, &subs->fmt_list) {
1762 struct audioformat *fp;
1763 fp = list_entry(p, struct audioformat, list);
1764 if (!hw_check_valid_format(subs, params, fp))
1765 continue;
1766 fbits |= (1ULL << fp->format);
1767 }
1768
1769 oldbits[0] = fmt->bits[0];
1770 oldbits[1] = fmt->bits[1];
1771 fmt->bits[0] &= (u32)fbits;
1772 fmt->bits[1] &= (u32)(fbits >> 32);
1773 if (!fmt->bits[0] && !fmt->bits[1]) {
1774 hwc_debug(" --> get empty\n");
1775 return -EINVAL;
1776 }
1777 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
1778 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
1779 return changed;
1780}
1781
1782static int hw_rule_period_time(struct snd_pcm_hw_params *params,
1783 struct snd_pcm_hw_rule *rule)
1784{
1785 struct snd_usb_substream *subs = rule->private;
1786 struct audioformat *fp;
1787 struct snd_interval *it;
1788 unsigned char min_datainterval;
1789 unsigned int pmin;
1790 int changed;
1791
1792 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1793 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
1794 min_datainterval = 0xff;
1795 list_for_each_entry(fp, &subs->fmt_list, list) {
1796 if (!hw_check_valid_format(subs, params, fp))
1797 continue;
1798 min_datainterval = min(min_datainterval, fp->datainterval);
1799 }
1800 if (min_datainterval == 0xff) {
1801 hwc_debug(" --> get emtpy\n");
1802 it->empty = 1;
1803 return -EINVAL;
1804 }
1805 pmin = 125 * (1 << min_datainterval);
1806 changed = 0;
1807 if (it->min < pmin) {
1808 it->min = pmin;
1809 it->openmin = 0;
1810 changed = 1;
1811 }
1812 if (snd_interval_checkempty(it)) {
1813 it->empty = 1;
1814 return -EINVAL;
1815 }
1816 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
1817 return changed;
1818}
1819
1820/*
1821 * If the device supports unusual bit rates, does the request meet these?
1822 */
1823static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1824 struct snd_usb_substream *subs)
1825{
1826 struct audioformat *fp;
1827 int count = 0, needs_knot = 0;
1828 int err;
1829
1830 list_for_each_entry(fp, &subs->fmt_list, list) {
1831 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
1832 return 0;
1833 count += fp->nr_rates;
1834 if (fp->rates & SNDRV_PCM_RATE_KNOT)
1835 needs_knot = 1;
1836 }
1837 if (!needs_knot)
1838 return 0;
1839
1840 subs->rate_list.count = count;
1841 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
1842 subs->rate_list.mask = 0;
1843 count = 0;
1844 list_for_each_entry(fp, &subs->fmt_list, list) {
1845 int i;
1846 for (i = 0; i < fp->nr_rates; i++)
1847 subs->rate_list.list[count++] = fp->rate_table[i];
1848 }
1849 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1850 &subs->rate_list);
1851 if (err < 0)
1852 return err;
1853
1854 return 0;
1855}
1856
1857
1858/*
1859 * set up the runtime hardware information.
1860 */
1861
1862static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
1863{
1864 struct list_head *p;
1865 unsigned int pt, ptmin;
1866 int param_period_time_if_needed;
1867 int err;
1868
1869 runtime->hw.formats = subs->formats;
1870
1871 runtime->hw.rate_min = 0x7fffffff;
1872 runtime->hw.rate_max = 0;
1873 runtime->hw.channels_min = 256;
1874 runtime->hw.channels_max = 0;
1875 runtime->hw.rates = 0;
1876 ptmin = UINT_MAX;
1877 /* check min/max rates and channels */
1878 list_for_each(p, &subs->fmt_list) {
1879 struct audioformat *fp;
1880 fp = list_entry(p, struct audioformat, list);
1881 runtime->hw.rates |= fp->rates;
1882 if (runtime->hw.rate_min > fp->rate_min)
1883 runtime->hw.rate_min = fp->rate_min;
1884 if (runtime->hw.rate_max < fp->rate_max)
1885 runtime->hw.rate_max = fp->rate_max;
1886 if (runtime->hw.channels_min > fp->channels)
1887 runtime->hw.channels_min = fp->channels;
1888 if (runtime->hw.channels_max < fp->channels)
1889 runtime->hw.channels_max = fp->channels;
1890 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
1891 /* FIXME: there might be more than one audio formats... */
1892 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
1893 fp->frame_size;
1894 }
1895 pt = 125 * (1 << fp->datainterval);
1896 ptmin = min(ptmin, pt);
1897 }
1898
1899 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
1900 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
1901 /* full speed devices have fixed data packet interval */
1902 ptmin = 1000;
1903 if (ptmin == 1000)
1904 /* if period time doesn't go below 1 ms, no rules needed */
1905 param_period_time_if_needed = -1;
1906 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1907 ptmin, UINT_MAX);
1908
1909 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1910 hw_rule_rate, subs,
1911 SNDRV_PCM_HW_PARAM_FORMAT,
1912 SNDRV_PCM_HW_PARAM_CHANNELS,
1913 param_period_time_if_needed,
1914 -1)) < 0)
1915 return err;
1916 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1917 hw_rule_channels, subs,
1918 SNDRV_PCM_HW_PARAM_FORMAT,
1919 SNDRV_PCM_HW_PARAM_RATE,
1920 param_period_time_if_needed,
1921 -1)) < 0)
1922 return err;
1923 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1924 hw_rule_format, subs,
1925 SNDRV_PCM_HW_PARAM_RATE,
1926 SNDRV_PCM_HW_PARAM_CHANNELS,
1927 param_period_time_if_needed,
1928 -1)) < 0)
1929 return err;
1930 if (param_period_time_if_needed >= 0) {
1931 err = snd_pcm_hw_rule_add(runtime, 0,
1932 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1933 hw_rule_period_time, subs,
1934 SNDRV_PCM_HW_PARAM_FORMAT,
1935 SNDRV_PCM_HW_PARAM_CHANNELS,
1936 SNDRV_PCM_HW_PARAM_RATE,
1937 -1);
1938 if (err < 0)
1939 return err;
1940 }
1941 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1942 return err;
1943 return 0;
1944}
1945
1946static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
1947{
1948 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1949 struct snd_pcm_runtime *runtime = substream->runtime;
1950 struct snd_usb_substream *subs = &as->substream[direction];
1951
1952 subs->interface = -1;
1953 subs->format = 0;
1954 runtime->hw = snd_usb_hardware;
1955 runtime->private_data = subs;
1956 subs->pcm_substream = substream;
1957 return setup_hw_info(runtime, subs);
1958}
1959
1960static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
1961{
1962 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1963 struct snd_usb_substream *subs = &as->substream[direction];
1964
1965 if (!as->chip->shutdown && subs->interface >= 0) {
1966 usb_set_interface(subs->dev, subs->interface, 0);
1967 subs->interface = -1;
1968 }
1969 subs->pcm_substream = NULL;
1970 return 0;
1971}
1972
1973static int snd_usb_playback_open(struct snd_pcm_substream *substream)
1974{
1975 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
1976}
1977
1978static int snd_usb_playback_close(struct snd_pcm_substream *substream)
1979{
1980 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
1981}
1982
1983static int snd_usb_capture_open(struct snd_pcm_substream *substream)
1984{
1985 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
1986}
1987
1988static int snd_usb_capture_close(struct snd_pcm_substream *substream)
1989{
1990 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
1991}
1992
1993static struct snd_pcm_ops snd_usb_playback_ops = {
1994 .open = snd_usb_playback_open,
1995 .close = snd_usb_playback_close,
1996 .ioctl = snd_pcm_lib_ioctl,
1997 .hw_params = snd_usb_hw_params,
1998 .hw_free = snd_usb_hw_free,
1999 .prepare = snd_usb_pcm_prepare,
2000 .trigger = snd_usb_pcm_playback_trigger,
2001 .pointer = snd_usb_pcm_pointer,
2002 .page = snd_pcm_lib_get_vmalloc_page,
2003 .mmap = snd_pcm_lib_mmap_vmalloc,
2004};
2005
2006static struct snd_pcm_ops snd_usb_capture_ops = {
2007 .open = snd_usb_capture_open,
2008 .close = snd_usb_capture_close,
2009 .ioctl = snd_pcm_lib_ioctl,
2010 .hw_params = snd_usb_hw_params,
2011 .hw_free = snd_usb_hw_free,
2012 .prepare = snd_usb_pcm_prepare,
2013 .trigger = snd_usb_pcm_capture_trigger,
2014 .pointer = snd_usb_pcm_pointer,
2015 .page = snd_pcm_lib_get_vmalloc_page,
2016 .mmap = snd_pcm_lib_mmap_vmalloc,
2017};
2018
2019
2020
2021/*
2022 * helper functions
2023 */
2024
2025/*
2026 * combine bytes and get an integer value
2027 */
2028unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
2029{
2030 switch (size) {
2031 case 1: return *bytes;
2032 case 2: return combine_word(bytes);
2033 case 3: return combine_triple(bytes);
2034 case 4: return combine_quad(bytes);
2035 default: return 0;
2036 }
2037}
2038
2039/*
2040 * parse descriptor buffer and return the pointer starting the given
2041 * descriptor type.
2042 */
2043void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
2044{
2045 u8 *p, *end, *next;
2046
2047 p = descstart;
2048 end = p + desclen;
2049 for (; p < end;) {
2050 if (p[0] < 2)
2051 return NULL;
2052 next = p + p[0];
2053 if (next > end)
2054 return NULL;
2055 if (p[1] == dtype && (!after || (void *)p > after)) {
2056 return p;
2057 }
2058 p = next;
2059 }
2060 return NULL;
2061}
2062
2063/*
2064 * find a class-specified interface descriptor with the given subtype.
2065 */
2066void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
2067{
2068 unsigned char *p = after;
2069
2070 while ((p = snd_usb_find_desc(buffer, buflen, p,
2071 USB_DT_CS_INTERFACE)) != NULL) {
2072 if (p[0] >= 3 && p[2] == dsubtype)
2073 return p;
2074 }
2075 return NULL;
2076}
2077
2078/*
2079 * Wrapper for usb_control_msg().
2080 * Allocates a temp buffer to prevent dmaing from/to the stack.
2081 */
2082int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
2083 __u8 requesttype, __u16 value, __u16 index, void *data,
2084 __u16 size, int timeout)
2085{
2086 int err;
2087 void *buf = NULL;
2088
2089 if (size > 0) {
2090 buf = kmemdup(data, size, GFP_KERNEL);
2091 if (!buf)
2092 return -ENOMEM;
2093 }
2094 err = usb_control_msg(dev, pipe, request, requesttype,
2095 value, index, buf, size, timeout);
2096 if (size > 0) {
2097 memcpy(data, buf, size);
2098 kfree(buf);
2099 }
2100 return err;
2101}
2102
2103
2104/*
2105 * entry point for linux usb interface
2106 */
2107
2108static int usb_audio_probe(struct usb_interface *intf,
2109 const struct usb_device_id *id);
2110static void usb_audio_disconnect(struct usb_interface *intf);
2111
2112#ifdef CONFIG_PM
2113static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message);
2114static int usb_audio_resume(struct usb_interface *intf);
2115#else
2116#define usb_audio_suspend NULL
2117#define usb_audio_resume NULL
2118#endif
2119
2120static struct usb_device_id usb_audio_ids [] = {
2121#include "usbquirks.h"
2122 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
2123 .bInterfaceClass = USB_CLASS_AUDIO,
2124 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
2125 { } /* Terminating entry */
2126};
2127
2128MODULE_DEVICE_TABLE (usb, usb_audio_ids);
2129
2130static struct usb_driver usb_audio_driver = {
2131 .name = "snd-usb-audio",
2132 .probe = usb_audio_probe,
2133 .disconnect = usb_audio_disconnect,
2134 .suspend = usb_audio_suspend,
2135 .resume = usb_audio_resume,
2136 .id_table = usb_audio_ids,
2137};
2138
2139
2140#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
2141
2142/*
2143 * proc interface for list the supported pcm formats
2144 */
2145static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
2146{
2147 struct list_head *p;
2148 static char *sync_types[4] = {
2149 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
2150 };
2151
2152 list_for_each(p, &subs->fmt_list) {
2153 struct audioformat *fp;
2154 fp = list_entry(p, struct audioformat, list);
2155 snd_iprintf(buffer, " Interface %d\n", fp->iface);
2156 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
2157 snd_iprintf(buffer, " Format: %s\n",
2158 snd_pcm_format_name(fp->format));
2159 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
2160 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
2161 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
2162 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
2163 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
2164 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
2165 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
2166 fp->rate_min, fp->rate_max);
2167 } else {
2168 unsigned int i;
2169 snd_iprintf(buffer, " Rates: ");
2170 for (i = 0; i < fp->nr_rates; i++) {
2171 if (i > 0)
2172 snd_iprintf(buffer, ", ");
2173 snd_iprintf(buffer, "%d", fp->rate_table[i]);
2174 }
2175 snd_iprintf(buffer, "\n");
2176 }
2177 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
2178 snd_iprintf(buffer, " Data packet interval: %d us\n",
2179 125 * (1 << fp->datainterval));
2180 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
2181 // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
2182 }
2183}
2184
2185static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
2186{
2187 if (subs->running) {
2188 unsigned int i;
2189 snd_iprintf(buffer, " Status: Running\n");
2190 snd_iprintf(buffer, " Interface = %d\n", subs->interface);
2191 snd_iprintf(buffer, " Altset = %d\n", subs->format);
2192 snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
2193 for (i = 0; i < subs->nurbs; i++)
2194 snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
2195 snd_iprintf(buffer, "]\n");
2196 snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
2197 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
2198 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
2199 ? get_full_speed_hz(subs->freqm)
2200 : get_high_speed_hz(subs->freqm),
2201 subs->freqm >> 16, subs->freqm & 0xffff);
2202 } else {
2203 snd_iprintf(buffer, " Status: Stop\n");
2204 }
2205}
2206
2207static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
2208{
2209 struct snd_usb_stream *stream = entry->private_data;
2210
2211 snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
2212
2213 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
2214 snd_iprintf(buffer, "\nPlayback:\n");
2215 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
2216 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
2217 }
2218 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
2219 snd_iprintf(buffer, "\nCapture:\n");
2220 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
2221 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
2222 }
2223}
2224
2225static void proc_pcm_format_add(struct snd_usb_stream *stream)
2226{
2227 struct snd_info_entry *entry;
2228 char name[32];
2229 struct snd_card *card = stream->chip->card;
2230
2231 sprintf(name, "stream%d", stream->pcm_index);
2232 if (!snd_card_proc_new(card, name, &entry))
2233 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
2234}
2235
2236#else
2237
2238static inline void proc_pcm_format_add(struct snd_usb_stream *stream)
2239{
2240}
2241
2242#endif
2243
2244/*
2245 * initialize the substream instance.
2246 */
2247
2248static void init_substream(struct snd_usb_stream *as, int stream, struct audioformat *fp)
2249{
2250 struct snd_usb_substream *subs = &as->substream[stream];
2251
2252 INIT_LIST_HEAD(&subs->fmt_list);
2253 spin_lock_init(&subs->lock);
2254
2255 subs->stream = as;
2256 subs->direction = stream;
2257 subs->dev = as->chip->dev;
2258 subs->txfr_quirk = as->chip->txfr_quirk;
2259 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
2260 subs->ops = audio_urb_ops[stream];
2261 } else {
2262 subs->ops = audio_urb_ops_high_speed[stream];
2263 switch (as->chip->usb_id) {
2264 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
2265 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
2266 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
2267 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
2268 break;
2269 }
2270 }
2271 snd_pcm_set_ops(as->pcm, stream,
2272 stream == SNDRV_PCM_STREAM_PLAYBACK ?
2273 &snd_usb_playback_ops : &snd_usb_capture_ops);
2274
2275 list_add_tail(&fp->list, &subs->fmt_list);
2276 subs->formats |= 1ULL << fp->format;
2277 subs->endpoint = fp->endpoint;
2278 subs->num_formats++;
2279 subs->fmt_type = fp->fmt_type;
2280}
2281
2282
2283/*
2284 * free a substream
2285 */
2286static void free_substream(struct snd_usb_substream *subs)
2287{
2288 struct list_head *p, *n;
2289
2290 if (!subs->num_formats)
2291 return; /* not initialized */
2292 list_for_each_safe(p, n, &subs->fmt_list) {
2293 struct audioformat *fp = list_entry(p, struct audioformat, list);
2294 kfree(fp->rate_table);
2295 kfree(fp);
2296 }
2297 kfree(subs->rate_list.list);
2298}
2299
2300
2301/*
2302 * free a usb stream instance
2303 */
2304static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
2305{
2306 free_substream(&stream->substream[0]);
2307 free_substream(&stream->substream[1]);
2308 list_del(&stream->list);
2309 kfree(stream);
2310}
2311
2312static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
2313{
2314 struct snd_usb_stream *stream = pcm->private_data;
2315 if (stream) {
2316 stream->pcm = NULL;
2317 snd_usb_audio_stream_free(stream);
2318 }
2319}
2320
2321
2322/*
2323 * add this endpoint to the chip instance.
2324 * if a stream with the same endpoint already exists, append to it.
2325 * if not, create a new pcm stream.
2326 */
2327static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
2328{
2329 struct list_head *p;
2330 struct snd_usb_stream *as;
2331 struct snd_usb_substream *subs;
2332 struct snd_pcm *pcm;
2333 int err;
2334
2335 list_for_each(p, &chip->pcm_list) {
2336 as = list_entry(p, struct snd_usb_stream, list);
2337 if (as->fmt_type != fp->fmt_type)
2338 continue;
2339 subs = &as->substream[stream];
2340 if (!subs->endpoint)
2341 continue;
2342 if (subs->endpoint == fp->endpoint) {
2343 list_add_tail(&fp->list, &subs->fmt_list);
2344 subs->num_formats++;
2345 subs->formats |= 1ULL << fp->format;
2346 return 0;
2347 }
2348 }
2349 /* look for an empty stream */
2350 list_for_each(p, &chip->pcm_list) {
2351 as = list_entry(p, struct snd_usb_stream, list);
2352 if (as->fmt_type != fp->fmt_type)
2353 continue;
2354 subs = &as->substream[stream];
2355 if (subs->endpoint)
2356 continue;
2357 err = snd_pcm_new_stream(as->pcm, stream, 1);
2358 if (err < 0)
2359 return err;
2360 init_substream(as, stream, fp);
2361 return 0;
2362 }
2363
2364 /* create a new pcm */
2365 as = kzalloc(sizeof(*as), GFP_KERNEL);
2366 if (!as)
2367 return -ENOMEM;
2368 as->pcm_index = chip->pcm_devs;
2369 as->chip = chip;
2370 as->fmt_type = fp->fmt_type;
2371 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
2372 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
2373 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
2374 &pcm);
2375 if (err < 0) {
2376 kfree(as);
2377 return err;
2378 }
2379 as->pcm = pcm;
2380 pcm->private_data = as;
2381 pcm->private_free = snd_usb_audio_pcm_free;
2382 pcm->info_flags = 0;
2383 if (chip->pcm_devs > 0)
2384 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
2385 else
2386 strcpy(pcm->name, "USB Audio");
2387
2388 init_substream(as, stream, fp);
2389
2390 list_add(&as->list, &chip->pcm_list);
2391 chip->pcm_devs++;
2392
2393 proc_pcm_format_add(as);
2394
2395 return 0;
2396}
2397
2398
2399/*
2400 * check if the device uses big-endian samples
2401 */
2402static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
2403{
2404 switch (chip->usb_id) {
2405 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
2406 if (fp->endpoint & USB_DIR_IN)
2407 return 1;
2408 break;
2409 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2410 if (device_setup[chip->index] == 0x00 ||
2411 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
2412 return 1;
2413 }
2414 return 0;
2415}
2416
2417/*
2418 * parse the audio format type I descriptor
2419 * and returns the corresponding pcm format
2420 *
2421 * @dev: usb device
2422 * @fp: audioformat record
2423 * @format: the format tag (wFormatTag)
2424 * @fmt: the format type descriptor
2425 */
2426static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2427 struct audioformat *fp,
2428 int format, void *_fmt,
2429 int protocol)
2430{
2431 int pcm_format, i;
2432 int sample_width, sample_bytes;
2433
2434 switch (protocol) {
2435 case UAC_VERSION_1: {
2436 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2437 sample_width = fmt->bBitResolution;
2438 sample_bytes = fmt->bSubframeSize;
2439 break;
2440 }
2441
2442 case UAC_VERSION_2: {
2443 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
2444 sample_width = fmt->bBitResolution;
2445 sample_bytes = fmt->bSubslotSize;
2446
2447 /*
2448 * FIXME
2449 * USB audio class v2 devices specify a bitmap of possible
2450 * audio formats rather than one fix value. For now, we just
2451 * pick one of them and report that as the only possible
2452 * value for this setting.
2453 * The bit allocation map is in fact compatible to the
2454 * wFormatTag of the v1 AS streaming descriptors, which is why
2455 * we can simply map the matrix.
2456 */
2457
2458 for (i = 0; i < 5; i++)
2459 if (format & (1UL << i)) {
2460 format = i + 1;
2461 break;
2462 }
2463
2464 break;
2465 }
2466
2467 default:
2468 return -EINVAL;
2469 }
2470
2471 /* FIXME: correct endianess and sign? */
2472 pcm_format = -1;
2473
2474 switch (format) {
2475 case UAC_FORMAT_TYPE_I_UNDEFINED: /* some devices don't define this correctly... */
2476 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
2477 chip->dev->devnum, fp->iface, fp->altsetting);
2478 /* fall-through */
2479 case UAC_FORMAT_TYPE_I_PCM:
2480 if (sample_width > sample_bytes * 8) {
2481 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
2482 chip->dev->devnum, fp->iface, fp->altsetting,
2483 sample_width, sample_bytes);
2484 }
2485 /* check the format byte size */
2486 switch (sample_bytes) {
2487 case 1:
2488 pcm_format = SNDRV_PCM_FORMAT_S8;
2489 break;
2490 case 2:
2491 if (is_big_endian_format(chip, fp))
2492 pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */
2493 else
2494 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2495 break;
2496 case 3:
2497 if (is_big_endian_format(chip, fp))
2498 pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */
2499 else
2500 pcm_format = SNDRV_PCM_FORMAT_S24_3LE;
2501 break;
2502 case 4:
2503 pcm_format = SNDRV_PCM_FORMAT_S32_LE;
2504 break;
2505 default:
2506 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
2507 chip->dev->devnum, fp->iface, fp->altsetting,
2508 sample_width, sample_bytes);
2509 break;
2510 }
2511 break;
2512 case UAC_FORMAT_TYPE_I_PCM8:
2513 pcm_format = SNDRV_PCM_FORMAT_U8;
2514
2515 /* Dallas DS4201 workaround: it advertises U8 format, but really
2516 supports S8. */
2517 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2518 pcm_format = SNDRV_PCM_FORMAT_S8;
2519 break;
2520 case UAC_FORMAT_TYPE_I_IEEE_FLOAT:
2521 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
2522 break;
2523 case UAC_FORMAT_TYPE_I_ALAW:
2524 pcm_format = SNDRV_PCM_FORMAT_A_LAW;
2525 break;
2526 case UAC_FORMAT_TYPE_I_MULAW:
2527 pcm_format = SNDRV_PCM_FORMAT_MU_LAW;
2528 break;
2529 default:
2530 snd_printk(KERN_INFO "%d:%u:%d : unsupported format type %d\n",
2531 chip->dev->devnum, fp->iface, fp->altsetting, format);
2532 break;
2533 }
2534 return pcm_format;
2535}
2536
2537
2538/*
2539 * parse the format descriptor and stores the possible sample rates
2540 * on the audioformat table (audio class v1).
2541 *
2542 * @dev: usb device
2543 * @fp: audioformat record
2544 * @fmt: the format descriptor
2545 * @offset: the start offset of descriptor pointing the rate type
2546 * (7 for type I and II, 8 for type II)
2547 */
2548static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
2549 unsigned char *fmt, int offset)
2550{
2551 int nr_rates = fmt[offset];
2552
2553 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2554 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2555 chip->dev->devnum, fp->iface, fp->altsetting);
2556 return -1;
2557 }
2558
2559 if (nr_rates) {
2560 /*
2561 * build the rate table and bitmap flags
2562 */
2563 int r, idx;
2564
2565 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2566 if (fp->rate_table == NULL) {
2567 snd_printk(KERN_ERR "cannot malloc\n");
2568 return -1;
2569 }
2570
2571 fp->nr_rates = 0;
2572 fp->rate_min = fp->rate_max = 0;
2573 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
2574 unsigned int rate = combine_triple(&fmt[idx]);
2575 if (!rate)
2576 continue;
2577 /* C-Media CM6501 mislabels its 96 kHz altsetting */
2578 if (rate == 48000 && nr_rates == 1 &&
2579 (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
2580 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
2581 fp->altsetting == 5 && fp->maxpacksize == 392)
2582 rate = 96000;
2583 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
2584 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
2585 rate = 8000;
2586 fp->rate_table[fp->nr_rates] = rate;
2587 if (!fp->rate_min || rate < fp->rate_min)
2588 fp->rate_min = rate;
2589 if (!fp->rate_max || rate > fp->rate_max)
2590 fp->rate_max = rate;
2591 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2592 fp->nr_rates++;
2593 }
2594 if (!fp->nr_rates) {
2595 hwc_debug("All rates were zero. Skipping format!\n");
2596 return -1;
2597 }
2598 } else {
2599 /* continuous rates */
2600 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
2601 fp->rate_min = combine_triple(&fmt[offset + 1]);
2602 fp->rate_max = combine_triple(&fmt[offset + 4]);
2603 }
2604 return 0;
2605}
2606
2607/*
2608 * parse the format descriptor and stores the possible sample rates
2609 * on the audioformat table (audio class v2).
2610 */
2611static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
2612 struct audioformat *fp,
2613 struct usb_host_interface *iface)
2614{
2615 struct usb_device *dev = chip->dev;
2616 unsigned char tmp[2], *data;
2617 int i, nr_rates, data_size, ret = 0;
2618
2619 /* get the number of sample rates first by only fetching 2 bytes */
2620 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2621 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2622 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000);
2623
2624 if (ret < 0) {
2625 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
2626 goto err;
2627 }
2628
2629 nr_rates = (tmp[1] << 8) | tmp[0];
2630 data_size = 2 + 12 * nr_rates;
2631 data = kzalloc(data_size, GFP_KERNEL);
2632 if (!data) {
2633 ret = -ENOMEM;
2634 goto err;
2635 }
2636
2637 /* now get the full information */
2638 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2639 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2640 0x0100, chip->clock_id << 8, data, data_size, 1000);
2641
2642 if (ret < 0) {
2643 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
2644 ret = -EINVAL;
2645 goto err_free;
2646 }
2647
2648 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2649 if (!fp->rate_table) {
2650 ret = -ENOMEM;
2651 goto err_free;
2652 }
2653
2654 fp->nr_rates = 0;
2655 fp->rate_min = fp->rate_max = 0;
2656
2657 for (i = 0; i < nr_rates; i++) {
2658 int rate = combine_quad(&data[2 + 12 * i]);
2659
2660 fp->rate_table[fp->nr_rates] = rate;
2661 if (!fp->rate_min || rate < fp->rate_min)
2662 fp->rate_min = rate;
2663 if (!fp->rate_max || rate > fp->rate_max)
2664 fp->rate_max = rate;
2665 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2666 fp->nr_rates++;
2667 }
2668
2669err_free:
2670 kfree(data);
2671err:
2672 return ret;
2673}
2674
2675/*
2676 * parse the format type I and III descriptors
2677 */
2678static int parse_audio_format_i(struct snd_usb_audio *chip,
2679 struct audioformat *fp,
2680 int format, void *_fmt,
2681 struct usb_host_interface *iface)
2682{
2683 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2684 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2685 int protocol = altsd->bInterfaceProtocol;
2686 int pcm_format, ret;
2687
2688 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
2689 /* FIXME: the format type is really IECxxx
2690 * but we give normal PCM format to get the existing
2691 * apps working...
2692 */
2693 switch (chip->usb_id) {
2694
2695 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2696 if (device_setup[chip->index] == 0x00 &&
2697 fp->altsetting == 6)
2698 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
2699 else
2700 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2701 break;
2702 default:
2703 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2704 }
2705 } else {
2706 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol);
2707 if (pcm_format < 0)
2708 return -1;
2709 }
2710
2711 fp->format = pcm_format;
2712
2713 /* gather possible sample rates */
2714 /* audio class v1 reports possible sample rates as part of the
2715 * proprietary class specific descriptor.
2716 * audio class v2 uses class specific EP0 range requests for that.
2717 */
2718 switch (protocol) {
2719 case UAC_VERSION_1:
2720 fp->channels = fmt->bNrChannels;
2721 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
2722 break;
2723 case UAC_VERSION_2:
2724 /* fp->channels is already set in this case */
2725 ret = parse_audio_format_rates_v2(chip, fp, iface);
2726 break;
2727 }
2728
2729 if (fp->channels < 1) {
2730 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
2731 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
2732 return -1;
2733 }
2734
2735 return ret;
2736}
2737
2738/*
2739 * parse the format type II descriptor
2740 */
2741static int parse_audio_format_ii(struct snd_usb_audio *chip,
2742 struct audioformat *fp,
2743 int format, void *_fmt,
2744 struct usb_host_interface *iface)
2745{
2746 int brate, framesize, ret;
2747 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2748 int protocol = altsd->bInterfaceProtocol;
2749
2750 switch (format) {
2751 case UAC_FORMAT_TYPE_II_AC3:
2752 /* FIXME: there is no AC3 format defined yet */
2753 // fp->format = SNDRV_PCM_FORMAT_AC3;
2754 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */
2755 break;
2756 case UAC_FORMAT_TYPE_II_MPEG:
2757 fp->format = SNDRV_PCM_FORMAT_MPEG;
2758 break;
2759 default:
2760 snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
2761 chip->dev->devnum, fp->iface, fp->altsetting, format);
2762 fp->format = SNDRV_PCM_FORMAT_MPEG;
2763 break;
2764 }
2765
2766 fp->channels = 1;
2767
2768 switch (protocol) {
2769 case UAC_VERSION_1: {
2770 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
2771 brate = le16_to_cpu(fmt->wMaxBitRate);
2772 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2773 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2774 fp->frame_size = framesize;
2775 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
2776 break;
2777 }
2778 case UAC_VERSION_2: {
2779 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
2780 brate = le16_to_cpu(fmt->wMaxBitRate);
2781 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2782 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2783 fp->frame_size = framesize;
2784 ret = parse_audio_format_rates_v2(chip, fp, iface);
2785 break;
2786 }
2787 }
2788
2789 return ret;
2790}
2791
2792static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
2793 int format, unsigned char *fmt, int stream,
2794 struct usb_host_interface *iface)
2795{
2796 int err;
2797
2798 switch (fmt[3]) {
2799 case UAC_FORMAT_TYPE_I:
2800 case UAC_FORMAT_TYPE_III:
2801 err = parse_audio_format_i(chip, fp, format, fmt, iface);
2802 break;
2803 case UAC_FORMAT_TYPE_II:
2804 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
2805 break;
2806 default:
2807 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
2808 chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
2809 return -1;
2810 }
2811 fp->fmt_type = fmt[3];
2812 if (err < 0)
2813 return err;
2814#if 1
2815 /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
2816 /* extigy apparently supports sample rates other than 48k
2817 * but not in ordinary way. so we enable only 48k atm.
2818 */
2819 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
2820 chip->usb_id == USB_ID(0x041e, 0x3020) ||
2821 chip->usb_id == USB_ID(0x041e, 0x3061)) {
2822 if (fmt[3] == UAC_FORMAT_TYPE_I &&
2823 fp->rates != SNDRV_PCM_RATE_48000 &&
2824 fp->rates != SNDRV_PCM_RATE_96000)
2825 return -1;
2826 }
2827#endif
2828 return 0;
2829}
2830
2831static unsigned char parse_datainterval(struct snd_usb_audio *chip,
2832 struct usb_host_interface *alts)
2833{
2834 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
2835 get_endpoint(alts, 0)->bInterval >= 1 &&
2836 get_endpoint(alts, 0)->bInterval <= 4)
2837 return get_endpoint(alts, 0)->bInterval - 1;
2838 else
2839 return 0;
2840}
2841
2842static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
2843 int iface, int altno);
2844static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2845{
2846 struct usb_device *dev;
2847 struct usb_interface *iface;
2848 struct usb_host_interface *alts;
2849 struct usb_interface_descriptor *altsd;
2850 int i, altno, err, stream;
2851 int format = 0, num_channels = 0;
2852 struct audioformat *fp = NULL;
2853 unsigned char *fmt, *csep;
2854 int num, protocol;
2855
2856 dev = chip->dev;
2857
2858 /* parse the interface's altsettings */
2859 iface = usb_ifnum_to_if(dev, iface_no);
2860
2861 num = iface->num_altsetting;
2862
2863 /*
2864 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
2865 * one misses syncpipe, and does not produce any sound.
2866 */
2867 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2868 num = 4;
2869
2870 for (i = 0; i < num; i++) {
2871 alts = &iface->altsetting[i];
2872 altsd = get_iface_desc(alts);
2873 protocol = altsd->bInterfaceProtocol;
2874 /* skip invalid one */
2875 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2876 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2877 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
2878 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
2879 altsd->bNumEndpoints < 1 ||
2880 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
2881 continue;
2882 /* must be isochronous */
2883 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
2884 USB_ENDPOINT_XFER_ISOC)
2885 continue;
2886 /* check direction */
2887 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
2888 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
2889 altno = altsd->bAlternateSetting;
2890
2891 /* audiophile usb: skip altsets incompatible with device_setup
2892 */
2893 if (chip->usb_id == USB_ID(0x0763, 0x2003) &&
2894 audiophile_skip_setting_quirk(chip, iface_no, altno))
2895 continue;
2896
2897 /* get audio formats */
2898 switch (protocol) {
2899 case UAC_VERSION_1: {
2900 struct uac_as_header_descriptor_v1 *as =
2901 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2902
2903 if (!as) {
2904 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2905 dev->devnum, iface_no, altno);
2906 continue;
2907 }
2908
2909 if (as->bLength < sizeof(*as)) {
2910 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2911 dev->devnum, iface_no, altno);
2912 continue;
2913 }
2914
2915 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
2916 break;
2917 }
2918
2919 case UAC_VERSION_2: {
2920 struct uac_as_header_descriptor_v2 *as =
2921 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2922
2923 if (!as) {
2924 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2925 dev->devnum, iface_no, altno);
2926 continue;
2927 }
2928
2929 if (as->bLength < sizeof(*as)) {
2930 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2931 dev->devnum, iface_no, altno);
2932 continue;
2933 }
2934
2935 num_channels = as->bNrChannels;
2936 format = le32_to_cpu(as->bmFormats);
2937
2938 break;
2939 }
2940
2941 default:
2942 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
2943 dev->devnum, iface_no, altno, protocol);
2944 continue;
2945 }
2946
2947 /* get format type */
2948 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
2949 if (!fmt) {
2950 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
2951 dev->devnum, iface_no, altno);
2952 continue;
2953 }
2954 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
2955 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
2956 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2957 dev->devnum, iface_no, altno);
2958 continue;
2959 }
2960
2961 /*
2962 * Blue Microphones workaround: The last altsetting is identical
2963 * with the previous one, except for a larger packet size, but
2964 * is actually a mislabeled two-channel setting; ignore it.
2965 */
2966 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
2967 fp && fp->altsetting == 1 && fp->channels == 1 &&
2968 fp->format == SNDRV_PCM_FORMAT_S16_LE &&
2969 protocol == UAC_VERSION_1 &&
2970 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
2971 fp->maxpacksize * 2)
2972 continue;
2973
2974 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
2975 /* Creamware Noah has this descriptor after the 2nd endpoint */
2976 if (!csep && altsd->bNumEndpoints >= 2)
2977 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2978 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
2979 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2980 " class specific endpoint descriptor\n",
2981 dev->devnum, iface_no, altno);
2982 csep = NULL;
2983 }
2984
2985 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
2986 if (! fp) {
2987 snd_printk(KERN_ERR "cannot malloc\n");
2988 return -ENOMEM;
2989 }
2990
2991 fp->iface = iface_no;
2992 fp->altsetting = altno;
2993 fp->altset_idx = i;
2994 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
2995 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
2996 fp->datainterval = parse_datainterval(chip, alts);
2997 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
2998 /* num_channels is only set for v2 interfaces */
2999 fp->channels = num_channels;
3000 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
3001 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
3002 * (fp->maxpacksize & 0x7ff);
3003 fp->attributes = csep ? csep[3] : 0;
3004
3005 /* some quirks for attributes here */
3006
3007 switch (chip->usb_id) {
3008 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
3009 /* Optoplay sets the sample rate attribute although
3010 * it seems not supporting it in fact.
3011 */
3012 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
3013 break;
3014 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
3015 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
3016 /* doesn't set the sample rate attribute, but supports it */
3017 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
3018 break;
3019 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
3020 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
3021 an older model 77d:223) */
3022 /*
3023 * plantronics headset and Griffin iMic have set adaptive-in
3024 * although it's really not...
3025 */
3026 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
3027 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
3028 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
3029 else
3030 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
3031 break;
3032 }
3033
3034 /* ok, let's parse further... */
3035 if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
3036 kfree(fp->rate_table);
3037 kfree(fp);
3038 continue;
3039 }
3040
3041 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
3042 err = add_audio_endpoint(chip, stream, fp);
3043 if (err < 0) {
3044 kfree(fp->rate_table);
3045 kfree(fp);
3046 return err;
3047 }
3048 /* try to set the interface... */
3049 usb_set_interface(chip->dev, iface_no, altno);
3050 init_usb_pitch(chip->dev, iface_no, alts, fp);
3051 init_usb_sample_rate(chip->dev, iface_no, alts, fp, fp->rate_max);
3052 }
3053 return 0;
3054}
3055
3056
3057/*
3058 * disconnect streams
3059 * called from snd_usb_audio_disconnect()
3060 */
3061static void snd_usb_stream_disconnect(struct list_head *head)
3062{
3063 int idx;
3064 struct snd_usb_stream *as;
3065 struct snd_usb_substream *subs;
3066
3067 as = list_entry(head, struct snd_usb_stream, list);
3068 for (idx = 0; idx < 2; idx++) {
3069 subs = &as->substream[idx];
3070 if (!subs->num_formats)
3071 return;
3072 release_substream_urbs(subs, 1);
3073 subs->interface = -1;
3074 }
3075}
3076
3077static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
3078{
3079 struct usb_device *dev = chip->dev;
3080 struct usb_host_interface *alts;
3081 struct usb_interface_descriptor *altsd;
3082 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
3083
3084 if (!iface) {
3085 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
3086 dev->devnum, ctrlif, interface);
3087 return -EINVAL;
3088 }
3089
3090 if (usb_interface_claimed(iface)) {
3091 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
3092 dev->devnum, ctrlif, interface);
3093 return -EINVAL;
3094 }
3095
3096 alts = &iface->altsetting[0];
3097 altsd = get_iface_desc(alts);
3098 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
3099 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
3100 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
3101 int err = snd_usbmidi_create(chip->card, iface,
3102 &chip->midi_list, NULL);
3103 if (err < 0) {
3104 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
3105 dev->devnum, ctrlif, interface);
3106 return -EINVAL;
3107 }
3108 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3109
3110 return 0;
3111 }
3112
3113 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
3114 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
3115 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
3116 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
3117 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
3118 /* skip non-supported classes */
3119 return -EINVAL;
3120 }
3121
3122 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
3123 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
3124 return -EINVAL;
3125 }
3126
3127 if (! parse_audio_endpoints(chip, interface)) {
3128 usb_set_interface(dev, interface, 0); /* reset the current interface */
3129 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3130 return -EINVAL;
3131 }
3132
3133 return 0;
3134}
3135
3136/*
3137 * parse audio control descriptor and create pcm/midi streams
3138 */
3139static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
3140{
3141 struct usb_device *dev = chip->dev;
3142 struct usb_host_interface *host_iface;
3143 struct usb_interface_descriptor *altsd;
3144 void *control_header;
3145 int i, protocol;
3146
3147 /* find audiocontrol interface */
3148 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
3149 control_header = snd_usb_find_csint_desc(host_iface->extra,
3150 host_iface->extralen,
3151 NULL, UAC_HEADER);
3152 altsd = get_iface_desc(host_iface);
3153 protocol = altsd->bInterfaceProtocol;
3154
3155 if (!control_header) {
3156 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
3157 return -EINVAL;
3158 }
3159
3160 switch (protocol) {
3161 case UAC_VERSION_1: {
3162 struct uac_ac_header_descriptor_v1 *h1 = control_header;
3163
3164 if (!h1->bInCollection) {
3165 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
3166 return -EINVAL;
3167 }
3168
3169 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
3170 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
3171 return -EINVAL;
3172 }
3173
3174 for (i = 0; i < h1->bInCollection; i++)
3175 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
3176
3177 break;
3178 }
3179
3180 case UAC_VERSION_2: {
3181 struct uac_clock_source_descriptor *cs;
3182 struct usb_interface_assoc_descriptor *assoc =
3183 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
3184
3185 if (!assoc) {
3186 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
3187 return -EINVAL;
3188 }
3189
3190 /* FIXME: for now, we expect there is at least one clock source
3191 * descriptor and we always take the first one.
3192 * We should properly support devices with multiple clock sources,
3193 * clock selectors and sample rate conversion units. */
3194
3195 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
3196 NULL, UAC_CLOCK_SOURCE);
3197
3198 if (!cs) {
3199 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
3200 return -EINVAL;
3201 }
3202
3203 chip->clock_id = cs->bClockID;
3204
3205 for (i = 0; i < assoc->bInterfaceCount; i++) {
3206 int intf = assoc->bFirstInterface + i;
3207
3208 if (intf != ctrlif)
3209 snd_usb_create_stream(chip, ctrlif, intf);
3210 }
3211
3212 break;
3213 }
3214
3215 default:
3216 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
3217 return -EINVAL;
3218 }
3219
3220 return 0;
3221}
3222
3223/*
3224 * create a stream for an endpoint/altsetting without proper descriptors
3225 */
3226static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
3227 struct usb_interface *iface,
3228 const struct snd_usb_audio_quirk *quirk)
3229{
3230 struct audioformat *fp;
3231 struct usb_host_interface *alts;
3232 int stream, err;
3233 unsigned *rate_table = NULL;
3234
3235 fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
3236 if (! fp) {
3237 snd_printk(KERN_ERR "cannot memdup\n");
3238 return -ENOMEM;
3239 }
3240 if (fp->nr_rates > 0) {
3241 rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
3242 if (!rate_table) {
3243 kfree(fp);
3244 return -ENOMEM;
3245 }
3246 memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
3247 fp->rate_table = rate_table;
3248 }
3249
3250 stream = (fp->endpoint & USB_DIR_IN)
3251 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3252 err = add_audio_endpoint(chip, stream, fp);
3253 if (err < 0) {
3254 kfree(fp);
3255 kfree(rate_table);
3256 return err;
3257 }
3258 if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
3259 fp->altset_idx >= iface->num_altsetting) {
3260 kfree(fp);
3261 kfree(rate_table);
3262 return -EINVAL;
3263 }
3264 alts = &iface->altsetting[fp->altset_idx];
3265 fp->datainterval = parse_datainterval(chip, alts);
3266 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3267 usb_set_interface(chip->dev, fp->iface, 0);
3268 init_usb_pitch(chip->dev, fp->iface, alts, fp);
3269 init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max);
3270 return 0;
3271}
3272
3273/*
3274 * create a stream for an interface with proper descriptors
3275 */
3276static int create_standard_audio_quirk(struct snd_usb_audio *chip,
3277 struct usb_interface *iface,
3278 const struct snd_usb_audio_quirk *quirk)
3279{
3280 struct usb_host_interface *alts;
3281 struct usb_interface_descriptor *altsd;
3282 int err;
3283
3284 alts = &iface->altsetting[0];
3285 altsd = get_iface_desc(alts);
3286 err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
3287 if (err < 0) {
3288 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
3289 altsd->bInterfaceNumber, err);
3290 return err;
3291 }
3292 /* reset the current interface */
3293 usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
3294 return 0;
3295}
3296
3297/*
3298 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
3299 * The only way to detect the sample rate is by looking at wMaxPacketSize.
3300 */
3301static int create_uaxx_quirk(struct snd_usb_audio *chip,
3302 struct usb_interface *iface,
3303 const struct snd_usb_audio_quirk *quirk)
3304{
3305 static const struct audioformat ua_format = {
3306 .format = SNDRV_PCM_FORMAT_S24_3LE,
3307 .channels = 2,
3308 .fmt_type = UAC_FORMAT_TYPE_I,
3309 .altsetting = 1,
3310 .altset_idx = 1,
3311 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3312 };
3313 struct usb_host_interface *alts;
3314 struct usb_interface_descriptor *altsd;
3315 struct audioformat *fp;
3316 int stream, err;
3317
3318 /* both PCM and MIDI interfaces have 2 or more altsettings */
3319 if (iface->num_altsetting < 2)
3320 return -ENXIO;
3321 alts = &iface->altsetting[1];
3322 altsd = get_iface_desc(alts);
3323
3324 if (altsd->bNumEndpoints == 2) {
3325 static const struct snd_usb_midi_endpoint_info ua700_ep = {
3326 .out_cables = 0x0003,
3327 .in_cables = 0x0003
3328 };
3329 static const struct snd_usb_audio_quirk ua700_quirk = {
3330 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3331 .data = &ua700_ep
3332 };
3333 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
3334 .out_cables = 0x0001,
3335 .in_cables = 0x0001
3336 };
3337 static const struct snd_usb_audio_quirk uaxx_quirk = {
3338 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3339 .data = &uaxx_ep
3340 };
3341 const struct snd_usb_audio_quirk *quirk =
3342 chip->usb_id == USB_ID(0x0582, 0x002b)
3343 ? &ua700_quirk : &uaxx_quirk;
3344 return snd_usbmidi_create(chip->card, iface,
3345 &chip->midi_list, quirk);
3346 }
3347
3348 if (altsd->bNumEndpoints != 1)
3349 return -ENXIO;
3350
3351 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
3352 if (!fp)
3353 return -ENOMEM;
3354 memcpy(fp, &ua_format, sizeof(*fp));
3355
3356 fp->iface = altsd->bInterfaceNumber;
3357 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3358 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3359 fp->datainterval = 0;
3360 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3361
3362 switch (fp->maxpacksize) {
3363 case 0x120:
3364 fp->rate_max = fp->rate_min = 44100;
3365 break;
3366 case 0x138:
3367 case 0x140:
3368 fp->rate_max = fp->rate_min = 48000;
3369 break;
3370 case 0x258:
3371 case 0x260:
3372 fp->rate_max = fp->rate_min = 96000;
3373 break;
3374 default:
3375 snd_printk(KERN_ERR "unknown sample rate\n");
3376 kfree(fp);
3377 return -ENXIO;
3378 }
3379
3380 stream = (fp->endpoint & USB_DIR_IN)
3381 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3382 err = add_audio_endpoint(chip, stream, fp);
3383 if (err < 0) {
3384 kfree(fp);
3385 return err;
3386 }
3387 usb_set_interface(chip->dev, fp->iface, 0);
3388 return 0;
3389}
3390
3391static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3392 struct usb_interface *iface,
3393 const struct snd_usb_audio_quirk *quirk);
3394
3395/*
3396 * handle the quirks for the contained interfaces
3397 */
3398static int create_composite_quirk(struct snd_usb_audio *chip,
3399 struct usb_interface *iface,
3400 const struct snd_usb_audio_quirk *quirk)
3401{
3402 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
3403 int err;
3404
3405 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
3406 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
3407 if (!iface)
3408 continue;
3409 if (quirk->ifnum != probed_ifnum &&
3410 usb_interface_claimed(iface))
3411 continue;
3412 err = snd_usb_create_quirk(chip, iface, quirk);
3413 if (err < 0)
3414 return err;
3415 if (quirk->ifnum != probed_ifnum)
3416 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3417 }
3418 return 0;
3419}
3420
3421static int ignore_interface_quirk(struct snd_usb_audio *chip,
3422 struct usb_interface *iface,
3423 const struct snd_usb_audio_quirk *quirk)
3424{
3425 return 0;
3426}
3427
3428/*
3429 * Allow alignment on audio sub-slot (channel samples) rather than
3430 * on audio slots (audio frames)
3431 */
3432static int create_align_transfer_quirk(struct snd_usb_audio *chip,
3433 struct usb_interface *iface,
3434 const struct snd_usb_audio_quirk *quirk)
3435{
3436 chip->txfr_quirk = 1;
3437 return 1; /* Continue with creating streams and mixer */
3438}
3439
3440
3441/*
3442 * boot quirks
3443 */
3444
3445#define EXTIGY_FIRMWARE_SIZE_OLD 794
3446#define EXTIGY_FIRMWARE_SIZE_NEW 483
3447
3448static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
3449{
3450 struct usb_host_config *config = dev->actconfig;
3451 int err;
3452
3453 if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
3454 le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
3455 snd_printdd("sending Extigy boot sequence...\n");
3456 /* Send message to force it to reconnect with full interface. */
3457 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
3458 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
3459 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
3460 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
3461 &dev->descriptor, sizeof(dev->descriptor));
3462 config = dev->actconfig;
3463 if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
3464 err = usb_reset_configuration(dev);
3465 if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
3466 snd_printdd("extigy_boot: new boot length = %d\n",
3467 le16_to_cpu(get_cfg_desc(config)->wTotalLength));
3468 return -ENODEV; /* quit this anyway */
3469 }
3470 return 0;
3471}
3472
3473static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
3474{
3475 u8 buf = 1;
3476
3477 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
3478 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
3479 0, 0, &buf, 1, 1000);
3480 if (buf == 0) {
3481 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
3482 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
3483 1, 2000, NULL, 0, 1000);
3484 return -ENODEV;
3485 }
3486 return 0;
3487}
3488
3489/*
3490 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
3491 * documented in the device's data sheet.
3492 */
3493static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
3494{
3495 u8 buf[4];
3496 buf[0] = 0x20;
3497 buf[1] = value & 0xff;
3498 buf[2] = (value >> 8) & 0xff;
3499 buf[3] = reg;
3500 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
3501 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
3502 0, 0, &buf, 4, 1000);
3503}
3504
3505static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
3506{
3507 /*
3508 * Enable line-out driver mode, set headphone source to front
3509 * channels, enable stereo mic.
3510 */
3511 return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
3512}
3513
3514/*
3515 * C-Media CM6206 is based on CM106 with two additional
3516 * registers that are not documented in the data sheet.
3517 * Values here are chosen based on sniffing USB traffic
3518 * under Windows.
3519 */
3520static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
3521{
3522 int err, reg;
3523 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
3524
3525 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
3526 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
3527 if (err < 0)
3528 return err;
3529 }
3530
3531 return err;
3532}
3533
3534/*
3535 * This call will put the synth in "USB send" mode, i.e it will send MIDI
3536 * messages through USB (this is disabled at startup). The synth will
3537 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
3538 * sign on its LCD. Values here are chosen based on sniffing USB traffic
3539 * under Windows.
3540 */
3541static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
3542{
3543 int err, actual_length;
3544
3545 /* "midi send" enable */
3546 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
3547
3548 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
3549 if (!buf)
3550 return -ENOMEM;
3551 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
3552 ARRAY_SIZE(seq), &actual_length, 1000);
3553 kfree(buf);
3554 if (err < 0)
3555 return err;
3556
3557 return 0;
3558}
3559
3560/*
3561 * Setup quirks
3562 */
3563#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
3564#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
3565#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
3566#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
3567#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
3568#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
3569#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
3570#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
3571#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
3572#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
3573
3574static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3575 int iface, int altno)
3576{
3577 /* Reset ALL ifaces to 0 altsetting.
3578 * Call it for every possible altsetting of every interface.
3579 */
3580 usb_set_interface(chip->dev, iface, 0);
3581
3582 if (device_setup[chip->index] & AUDIOPHILE_SET) {
3583 if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
3584 && altno != 6)
3585 return 1; /* skip this altsetting */
3586 if ((device_setup[chip->index] & AUDIOPHILE_SET_96K)
3587 && altno != 1)
3588 return 1; /* skip this altsetting */
3589 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3590 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
3591 return 1; /* skip this altsetting */
3592 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3593 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
3594 return 1; /* skip this altsetting */
3595 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3596 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
3597 return 1; /* skip this altsetting */
3598 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3599 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
3600 return 1; /* skip this altsetting */
3601 }
3602 return 0; /* keep this altsetting */
3603}
3604
3605static int create_any_midi_quirk(struct snd_usb_audio *chip,
3606 struct usb_interface *intf,
3607 const struct snd_usb_audio_quirk *quirk)
3608{
3609 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
3610}
3611
3612/*
3613 * audio-interface quirks
3614 *
3615 * returns zero if no standard audio/MIDI parsing is needed.
3616 * returns a postive value if standard audio/midi interfaces are parsed
3617 * after this.
3618 * returns a negative value at error.
3619 */
3620static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3621 struct usb_interface *iface,
3622 const struct snd_usb_audio_quirk *quirk)
3623{
3624 typedef int (*quirk_func_t)(struct snd_usb_audio *, struct usb_interface *,
3625 const struct snd_usb_audio_quirk *);
3626 static const quirk_func_t quirk_funcs[] = {
3627 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
3628 [QUIRK_COMPOSITE] = create_composite_quirk,
3629 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
3630 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
3631 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
3632 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
3633 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
3634 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
3635 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
3636 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3637 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3638 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3639 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3640 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3641 };
3642
3643 if (quirk->type < QUIRK_TYPE_COUNT) {
3644 return quirk_funcs[quirk->type](chip, iface, quirk);
3645 } else {
3646 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
3647 return -ENXIO;
3648 }
3649}
3650
3651
3652/*
3653 * common proc files to show the usb device info
3654 */
3655static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3656{
3657 struct snd_usb_audio *chip = entry->private_data;
3658 if (!chip->shutdown)
3659 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
3660}
3661
3662static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3663{
3664 struct snd_usb_audio *chip = entry->private_data;
3665 if (!chip->shutdown)
3666 snd_iprintf(buffer, "%04x:%04x\n",
3667 USB_ID_VENDOR(chip->usb_id),
3668 USB_ID_PRODUCT(chip->usb_id));
3669}
3670
3671static void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
3672{
3673 struct snd_info_entry *entry;
3674 if (!snd_card_proc_new(chip->card, "usbbus", &entry))
3675 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
3676 if (!snd_card_proc_new(chip->card, "usbid", &entry))
3677 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
3678}
3679
3680/*
3681 * free the chip instance
3682 *
3683 * here we have to do not much, since pcm and controls are already freed
3684 *
3685 */
3686
3687static int snd_usb_audio_free(struct snd_usb_audio *chip)
3688{
3689 kfree(chip);
3690 return 0;
3691}
3692
3693static int snd_usb_audio_dev_free(struct snd_device *device)
3694{
3695 struct snd_usb_audio *chip = device->device_data;
3696 return snd_usb_audio_free(chip);
3697}
3698
3699
3700/*
3701 * create a chip instance and set its names.
3702 */
3703static int snd_usb_audio_create(struct usb_device *dev, int idx,
3704 const struct snd_usb_audio_quirk *quirk,
3705 struct snd_usb_audio **rchip)
3706{
3707 struct snd_card *card;
3708 struct snd_usb_audio *chip;
3709 int err, len;
3710 char component[14];
3711 static struct snd_device_ops ops = {
3712 .dev_free = snd_usb_audio_dev_free,
3713 };
3714
3715 *rchip = NULL;
3716
3717 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
3718 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
3719 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
3720 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
3721 return -ENXIO;
3722 }
3723
3724 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
3725 if (err < 0) {
3726 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
3727 return err;
3728 }
3729
3730 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
3731 if (! chip) {
3732 snd_card_free(card);
3733 return -ENOMEM;
3734 }
3735
3736 chip->index = idx;
3737 chip->dev = dev;
3738 chip->card = card;
3739 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3740 le16_to_cpu(dev->descriptor.idProduct));
3741 INIT_LIST_HEAD(&chip->pcm_list);
3742 INIT_LIST_HEAD(&chip->midi_list);
3743 INIT_LIST_HEAD(&chip->mixer_list);
3744
3745 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
3746 snd_usb_audio_free(chip);
3747 snd_card_free(card);
3748 return err;
3749 }
3750
3751 strcpy(card->driver, "USB-Audio");
3752 sprintf(component, "USB%04x:%04x",
3753 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
3754 snd_component_add(card, component);
3755
3756 /* retrieve the device string as shortname */
3757 if (quirk && quirk->product_name) {
3758 strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
3759 } else {
3760 if (!dev->descriptor.iProduct ||
3761 usb_string(dev, dev->descriptor.iProduct,
3762 card->shortname, sizeof(card->shortname)) <= 0) {
3763 /* no name available from anywhere, so use ID */
3764 sprintf(card->shortname, "USB Device %#04x:%#04x",
3765 USB_ID_VENDOR(chip->usb_id),
3766 USB_ID_PRODUCT(chip->usb_id));
3767 }
3768 }
3769
3770 /* retrieve the vendor and device strings as longname */
3771 if (quirk && quirk->vendor_name) {
3772 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
3773 } else {
3774 if (dev->descriptor.iManufacturer)
3775 len = usb_string(dev, dev->descriptor.iManufacturer,
3776 card->longname, sizeof(card->longname));
3777 else
3778 len = 0;
3779 /* we don't really care if there isn't any vendor string */
3780 }
3781 if (len > 0)
3782 strlcat(card->longname, " ", sizeof(card->longname));
3783
3784 strlcat(card->longname, card->shortname, sizeof(card->longname));
3785
3786 len = strlcat(card->longname, " at ", sizeof(card->longname));
3787
3788 if (len < sizeof(card->longname))
3789 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
3790
3791 strlcat(card->longname,
3792 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
3793 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
3794 ", high speed",
3795 sizeof(card->longname));
3796
3797 snd_usb_audio_create_proc(chip);
3798
3799 *rchip = chip;
3800 return 0;
3801}
3802
3803
3804/*
3805 * probe the active usb device
3806 *
3807 * note that this can be called multiple times per a device, when it
3808 * includes multiple audio control interfaces.
3809 *
3810 * thus we check the usb device pointer and creates the card instance
3811 * only at the first time. the successive calls of this function will
3812 * append the pcm interface to the corresponding card.
3813 */
3814static void *snd_usb_audio_probe(struct usb_device *dev,
3815 struct usb_interface *intf,
3816 const struct usb_device_id *usb_id)
3817{
3818 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
3819 int i, err;
3820 struct snd_usb_audio *chip;
3821 struct usb_host_interface *alts;
3822 int ifnum;
3823 u32 id;
3824
3825 alts = &intf->altsetting[0];
3826 ifnum = get_iface_desc(alts)->bInterfaceNumber;
3827 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3828 le16_to_cpu(dev->descriptor.idProduct));
3829 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
3830 goto __err_val;
3831
3832 /* SB Extigy needs special boot-up sequence */
3833 /* if more models come, this will go to the quirk list. */
3834 if (id == USB_ID(0x041e, 0x3000)) {
3835 if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
3836 goto __err_val;
3837 }
3838 /* SB Audigy 2 NX needs its own boot-up magic, too */
3839 if (id == USB_ID(0x041e, 0x3020)) {
3840 if (snd_usb_audigy2nx_boot_quirk(dev) < 0)
3841 goto __err_val;
3842 }
3843
3844 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
3845 if (id == USB_ID(0x10f5, 0x0200)) {
3846 if (snd_usb_cm106_boot_quirk(dev) < 0)
3847 goto __err_val;
3848 }
3849
3850 /* C-Media CM6206 / CM106-Like Sound Device */
3851 if (id == USB_ID(0x0d8c, 0x0102)) {
3852 if (snd_usb_cm6206_boot_quirk(dev) < 0)
3853 goto __err_val;
3854 }
3855
3856 /* Access Music VirusTI Desktop */
3857 if (id == USB_ID(0x133e, 0x0815)) {
3858 if (snd_usb_accessmusic_boot_quirk(dev) < 0)
3859 goto __err_val;
3860 }
3861
3862 /*
3863 * found a config. now register to ALSA
3864 */
3865
3866 /* check whether it's already registered */
3867 chip = NULL;
3868 mutex_lock(&register_mutex);
3869 for (i = 0; i < SNDRV_CARDS; i++) {
3870 if (usb_chip[i] && usb_chip[i]->dev == dev) {
3871 if (usb_chip[i]->shutdown) {
3872 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
3873 goto __error;
3874 }
3875 chip = usb_chip[i];
3876 break;
3877 }
3878 }
3879 if (! chip) {
3880 /* it's a fresh one.
3881 * now look for an empty slot and create a new card instance
3882 */
3883 for (i = 0; i < SNDRV_CARDS; i++)
3884 if (enable[i] && ! usb_chip[i] &&
3885 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
3886 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
3887 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
3888 goto __error;
3889 }
3890 snd_card_set_dev(chip->card, &intf->dev);
3891 break;
3892 }
3893 if (!chip) {
3894 printk(KERN_ERR "no available usb audio device\n");
3895 goto __error;
3896 }
3897 }
3898
3899 chip->txfr_quirk = 0;
3900 err = 1; /* continue */
3901 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
3902 /* need some special handlings */
3903 if ((err = snd_usb_create_quirk(chip, intf, quirk)) < 0)
3904 goto __error;
3905 }
3906
3907 if (err > 0) {
3908 /* create normal USB audio interfaces */
3909 if (snd_usb_create_streams(chip, ifnum) < 0 ||
3910 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
3911 goto __error;
3912 }
3913 }
3914
3915 /* we are allowed to call snd_card_register() many times */
3916 if (snd_card_register(chip->card) < 0) {
3917 goto __error;
3918 }
3919
3920 usb_chip[chip->index] = chip;
3921 chip->num_interfaces++;
3922 mutex_unlock(&register_mutex);
3923 return chip;
3924
3925 __error:
3926 if (chip && !chip->num_interfaces)
3927 snd_card_free(chip->card);
3928 mutex_unlock(&register_mutex);
3929 __err_val:
3930 return NULL;
3931}
3932
3933/*
3934 * we need to take care of counter, since disconnection can be called also
3935 * many times as well as usb_audio_probe().
3936 */
3937static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
3938{
3939 struct snd_usb_audio *chip;
3940 struct snd_card *card;
3941 struct list_head *p;
3942
3943 if (ptr == (void *)-1L)
3944 return;
3945
3946 chip = ptr;
3947 card = chip->card;
3948 mutex_lock(&register_mutex);
3949 chip->shutdown = 1;
3950 chip->num_interfaces--;
3951 if (chip->num_interfaces <= 0) {
3952 snd_card_disconnect(card);
3953 /* release the pcm resources */
3954 list_for_each(p, &chip->pcm_list) {
3955 snd_usb_stream_disconnect(p);
3956 }
3957 /* release the midi resources */
3958 list_for_each(p, &chip->midi_list) {
3959 snd_usbmidi_disconnect(p);
3960 }
3961 /* release mixer resources */
3962 list_for_each(p, &chip->mixer_list) {
3963 snd_usb_mixer_disconnect(p);
3964 }
3965 usb_chip[chip->index] = NULL;
3966 mutex_unlock(&register_mutex);
3967 snd_card_free_when_closed(card);
3968 } else {
3969 mutex_unlock(&register_mutex);
3970 }
3971}
3972
3973/*
3974 * new 2.5 USB kernel API
3975 */
3976static int usb_audio_probe(struct usb_interface *intf,
3977 const struct usb_device_id *id)
3978{
3979 void *chip;
3980 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
3981 if (chip) {
3982 usb_set_intfdata(intf, chip);
3983 return 0;
3984 } else
3985 return -EIO;
3986}
3987
3988static void usb_audio_disconnect(struct usb_interface *intf)
3989{
3990 snd_usb_audio_disconnect(interface_to_usbdev(intf),
3991 usb_get_intfdata(intf));
3992}
3993
3994#ifdef CONFIG_PM
3995static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
3996{
3997 struct snd_usb_audio *chip = usb_get_intfdata(intf);
3998 struct list_head *p;
3999 struct snd_usb_stream *as;
4000
4001 if (chip == (void *)-1L)
4002 return 0;
4003
4004 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
4005 if (!chip->num_suspended_intf++) {
4006 list_for_each(p, &chip->pcm_list) {
4007 as = list_entry(p, struct snd_usb_stream, list);
4008 snd_pcm_suspend_all(as->pcm);
4009 }
4010 }
4011
4012 return 0;
4013}
4014
4015static int usb_audio_resume(struct usb_interface *intf)
4016{
4017 struct snd_usb_audio *chip = usb_get_intfdata(intf);
4018
4019 if (chip == (void *)-1L)
4020 return 0;
4021 if (--chip->num_suspended_intf)
4022 return 0;
4023 /*
4024 * ALSA leaves material resumption to user space
4025 * we just notify
4026 */
4027
4028 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
4029
4030 return 0;
4031}
4032#endif /* CONFIG_PM */
4033
4034static int __init snd_usb_audio_init(void)
4035{
4036 if (nrpacks < 1 || nrpacks > MAX_PACKS) {
4037 printk(KERN_WARNING "invalid nrpacks value.\n");
4038 return -EINVAL;
4039 }
4040 return usb_register(&usb_audio_driver);
4041}
4042
4043
4044static void __exit snd_usb_audio_cleanup(void)
4045{
4046 usb_deregister(&usb_audio_driver);
4047}
4048
4049module_init(snd_usb_audio_init);
4050module_exit(snd_usb_audio_cleanup);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 42c299cbf63a..d679e72a3e5c 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -21,15 +21,13 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24/* maximum number of endpoints per interface */
25#define MIDI_MAX_ENDPOINTS 2
26
27/* handling of USB vendor/product ID pairs as 32-bit numbers */ 24/* handling of USB vendor/product ID pairs as 32-bit numbers */
28#define USB_ID(vendor, product) (((vendor) << 16) | (product)) 25#define USB_ID(vendor, product) (((vendor) << 16) | (product))
29#define USB_ID_VENDOR(id) ((id) >> 16) 26#define USB_ID_VENDOR(id) ((id) >> 16)
30#define USB_ID_PRODUCT(id) ((u16)(id)) 27#define USB_ID_PRODUCT(id) ((u16)(id))
31 28
32/* 29/*
30 *
33 */ 31 */
34 32
35struct snd_usb_audio { 33struct snd_usb_audio {
@@ -51,6 +49,10 @@ struct snd_usb_audio {
51 struct list_head midi_list; /* list of midi interfaces */ 49 struct list_head midi_list; /* list of midi interfaces */
52 50
53 struct list_head mixer_list; /* list of mixer interfaces */ 51 struct list_head mixer_list; /* list of mixer interfaces */
52
53 int setup; /* from the 'device_setup' module param */
54 int nrpacks; /* from the 'nrpacks' module param */
55 int async_unlink; /* from the 'async_unlink' module param */
54}; 56};
55 57
56/* 58/*
@@ -89,93 +91,8 @@ struct snd_usb_audio_quirk {
89 const void *data; 91 const void *data;
90}; 92};
91 93
92/* data for QUIRK_MIDI_FIXED_ENDPOINT */
93struct snd_usb_midi_endpoint_info {
94 int8_t out_ep; /* ep number, 0 autodetect */
95 uint8_t out_interval; /* interval for interrupt endpoints */
96 int8_t in_ep;
97 uint8_t in_interval;
98 uint16_t out_cables; /* bitmask */
99 uint16_t in_cables; /* bitmask */
100};
101
102/* for QUIRK_MIDI_YAMAHA, data is NULL */
103
104/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
105 * structure (out_cables and in_cables only) */
106
107/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
108 * structures, terminated with .ifnum = -1 */
109
110/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
111
112/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
113
114/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
115
116/* for QUIRK_IGNORE_INTERFACE, data is NULL */
117
118/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
119
120/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
121 * structure (out_cables and in_cables only) */
122
123/* for QUIRK_MIDI_CME, data is NULL */
124
125/*
126 */
127
128/*E-mu USB samplerate control quirk*/
129enum {
130 EMU_QUIRK_SR_44100HZ = 0,
131 EMU_QUIRK_SR_48000HZ,
132 EMU_QUIRK_SR_88200HZ,
133 EMU_QUIRK_SR_96000HZ,
134 EMU_QUIRK_SR_176400HZ,
135 EMU_QUIRK_SR_192000HZ
136};
137
138#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) 94#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
139#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 95#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
140#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 96#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
141 97
142unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
143
144void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
145void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
146
147int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
148 __u8 request, __u8 requesttype, __u16 value, __u16 index,
149 void *data, __u16 size, int timeout);
150
151int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
152 int ignore_error);
153void snd_usb_mixer_disconnect(struct list_head *p);
154
155int snd_usbmidi_create(struct snd_card *card,
156 struct usb_interface *iface,
157 struct list_head *midi_list,
158 const struct snd_usb_audio_quirk *quirk);
159void snd_usbmidi_input_stop(struct list_head* p);
160void snd_usbmidi_input_start(struct list_head* p);
161void snd_usbmidi_disconnect(struct list_head *p);
162
163void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
164 unsigned char samplerate_id);
165
166/*
167 * retrieve usb_interface descriptor from the host interface
168 * (conditional for compatibility with the older API)
169 */
170#ifndef get_iface_desc
171#define get_iface_desc(iface) (&(iface)->desc)
172#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
173#define get_ep_desc(ep) (&(ep)->desc)
174#define get_cfg_desc(cfg) (&(cfg)->desc)
175#endif
176
177#ifndef snd_usb_get_speed
178#define snd_usb_get_speed(dev) ((dev)->speed)
179#endif
180
181#endif /* __USBAUDIO_H */ 98#endif /* __USBAUDIO_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 9ca9a13a78da..6ef68e42138e 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -26,6 +26,7 @@
26#define MODNAME "US122L" 26#define MODNAME "US122L"
27#include "usb_stream.c" 27#include "usb_stream.c"
28#include "../usbaudio.h" 28#include "../usbaudio.h"
29#include "../midi.h"
29#include "us122l.h" 30#include "us122l.h"
30 31
31MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>"); 32MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>");
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 1d174cea352b..e43c0a86441a 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -1,6 +1,7 @@
1#ifndef USBUSX2Y_H 1#ifndef USBUSX2Y_H
2#define USBUSX2Y_H 2#define USBUSX2Y_H
3#include "../usbaudio.h" 3#include "../usbaudio.h"
4#include "../midi.h"
4#include "usbus428ctldefs.h" 5#include "usbus428ctldefs.h"
5 6
6#define NRURBS 2 7#define NRURBS 2