11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f31639b8SShin-ya Okada /*
3f31639b8SShin-ya Okada * ALSA driver for ICEnsemble VT1724 (Envy24HT)
4f31639b8SShin-ya Okada *
5f31639b8SShin-ya Okada * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI
6f31639b8SShin-ya Okada *
7f31639b8SShin-ya Okada * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp
8f31639b8SShin-ya Okada * (at) -> @
9f31639b8SShin-ya Okada */
10f31639b8SShin-ya Okada
11f31639b8SShin-ya Okada #include <linux/delay.h>
12f31639b8SShin-ya Okada #include <linux/interrupt.h>
13f31639b8SShin-ya Okada #include <linux/init.h>
14f31639b8SShin-ya Okada #include <linux/slab.h>
15f31639b8SShin-ya Okada #include <sound/core.h>
16f31639b8SShin-ya Okada #include <sound/tlv.h>
17f31639b8SShin-ya Okada
18f31639b8SShin-ya Okada #include "ice1712.h"
19f31639b8SShin-ya Okada #include "envy24ht.h"
20f31639b8SShin-ya Okada #include "se.h"
21f31639b8SShin-ya Okada
227cda8ba9STakashi Iwai struct se_spec {
237cda8ba9STakashi Iwai struct {
247cda8ba9STakashi Iwai unsigned char ch1, ch2;
257cda8ba9STakashi Iwai } vol[8];
267cda8ba9STakashi Iwai };
27f31639b8SShin-ya Okada
28f31639b8SShin-ya Okada /****************************************************************************/
29f31639b8SShin-ya Okada /* ONKYO WAVIO SE-200PCI */
30f31639b8SShin-ya Okada /****************************************************************************/
31f31639b8SShin-ya Okada /*
32f31639b8SShin-ya Okada * system configuration ICE_EEP2_SYSCONF=0x4b
33f31639b8SShin-ya Okada * XIN1 49.152MHz
34f31639b8SShin-ya Okada * not have UART
35f31639b8SShin-ya Okada * one stereo ADC and a S/PDIF receiver connected
36f31639b8SShin-ya Okada * four stereo DACs connected
37f31639b8SShin-ya Okada *
38f31639b8SShin-ya Okada * AC-Link configuration ICE_EEP2_ACLINK=0x80
39f31639b8SShin-ya Okada * use I2C, not use AC97
40f31639b8SShin-ya Okada *
41f31639b8SShin-ya Okada * I2S converters feature ICE_EEP2_I2S=0x78
42f31639b8SShin-ya Okada * I2S codec has no volume/mute control feature
43f31639b8SShin-ya Okada * I2S codec supports 96KHz and 192KHz
44f31639b8SShin-ya Okada * I2S codec 24bits
45f31639b8SShin-ya Okada *
46f31639b8SShin-ya Okada * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
47f31639b8SShin-ya Okada * Enable integrated S/PDIF transmitter
48f31639b8SShin-ya Okada * internal S/PDIF out implemented
49f31639b8SShin-ya Okada * S/PDIF is stereo
50f31639b8SShin-ya Okada * External S/PDIF out implemented
51f31639b8SShin-ya Okada *
52f31639b8SShin-ya Okada *
53f31639b8SShin-ya Okada * ** connected chips **
54f31639b8SShin-ya Okada *
55f31639b8SShin-ya Okada * WM8740
56f31639b8SShin-ya Okada * A 2ch-DAC of main outputs.
57f31639b8SShin-ya Okada * It setuped as I2S mode by wire, so no way to setup from software.
58f31639b8SShin-ya Okada * The sample-rate are automatically changed.
59f31639b8SShin-ya Okada * ML/I2S (28pin) --------+
60f31639b8SShin-ya Okada * MC/DM1 (27pin) -- 5V |
61f31639b8SShin-ya Okada * MD/DM0 (26pin) -- GND |
62f31639b8SShin-ya Okada * MUTEB (25pin) -- NC |
63f31639b8SShin-ya Okada * MODE (24pin) -- GND |
64f31639b8SShin-ya Okada * CSBIW (23pin) --------+
65f31639b8SShin-ya Okada * |
66f31639b8SShin-ya Okada * RSTB (22pin) --R(1K)-+
67f31639b8SShin-ya Okada * Probably it reduce the noise from the control line.
68f31639b8SShin-ya Okada *
69f31639b8SShin-ya Okada * WM8766
70f31639b8SShin-ya Okada * A 6ch-DAC for surrounds.
71f31639b8SShin-ya Okada * It's control wire was connected to GPIOxx (3-wire serial interface)
72f31639b8SShin-ya Okada * ML/I2S (11pin) -- GPIO18
73f31639b8SShin-ya Okada * MC/IWL (12pin) -- GPIO17
74f31639b8SShin-ya Okada * MD/DM (13pin) -- GPIO16
75f31639b8SShin-ya Okada * MUTE (14pin) -- GPIO01
76f31639b8SShin-ya Okada *
77f31639b8SShin-ya Okada * WM8776
78f31639b8SShin-ya Okada * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC.
79f31639b8SShin-ya Okada * It's control wire was connected to SDA/SCLK (2-wire serial interface)
80f31639b8SShin-ya Okada * MODE (16pin) -- R(1K) -- GND
81f31639b8SShin-ya Okada * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34)
82f31639b8SShin-ya Okada * DI (18pin) -- SDA
83f31639b8SShin-ya Okada * CL (19pin) -- SCLK
84f31639b8SShin-ya Okada *
85f31639b8SShin-ya Okada *
86f31639b8SShin-ya Okada * ** output pins and device names **
87f31639b8SShin-ya Okada *
88f31639b8SShin-ya Okada * 7.1ch name -- output connector color -- device (-D option)
89f31639b8SShin-ya Okada *
90f31639b8SShin-ya Okada * FRONT 2ch -- green -- plughw:0,0
91f31639b8SShin-ya Okada * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0
92f31639b8SShin-ya Okada * SURROUND 2ch -- orange -- plughw:0,2,1
93f31639b8SShin-ya Okada * SURROUND BACK 2ch -- white -- plughw:0,2,2
94f31639b8SShin-ya Okada *
95f31639b8SShin-ya Okada */
96f31639b8SShin-ya Okada
97f31639b8SShin-ya Okada
98f31639b8SShin-ya Okada /****************************************************************************/
99f31639b8SShin-ya Okada /* WM8740 interface */
100f31639b8SShin-ya Okada /****************************************************************************/
101f31639b8SShin-ya Okada
se200pci_WM8740_init(struct snd_ice1712 * ice)102e23e7a14SBill Pemberton static void se200pci_WM8740_init(struct snd_ice1712 *ice)
103f31639b8SShin-ya Okada {
104f31639b8SShin-ya Okada /* nothing to do */
105f31639b8SShin-ya Okada }
106f31639b8SShin-ya Okada
107f31639b8SShin-ya Okada
se200pci_WM8740_set_pro_rate(struct snd_ice1712 * ice,unsigned int rate)108f31639b8SShin-ya Okada static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice,
109f31639b8SShin-ya Okada unsigned int rate)
110f31639b8SShin-ya Okada {
111f31639b8SShin-ya Okada /* nothing to do */
112f31639b8SShin-ya Okada }
113f31639b8SShin-ya Okada
114f31639b8SShin-ya Okada
115f31639b8SShin-ya Okada /****************************************************************************/
116f31639b8SShin-ya Okada /* WM8766 interface */
117f31639b8SShin-ya Okada /****************************************************************************/
118f31639b8SShin-ya Okada
se200pci_WM8766_write(struct snd_ice1712 * ice,unsigned int addr,unsigned int data)119f31639b8SShin-ya Okada static void se200pci_WM8766_write(struct snd_ice1712 *ice,
120f31639b8SShin-ya Okada unsigned int addr, unsigned int data)
121f31639b8SShin-ya Okada {
122f31639b8SShin-ya Okada unsigned int st;
123f31639b8SShin-ya Okada unsigned int bits;
124f31639b8SShin-ya Okada int i;
125f31639b8SShin-ya Okada const unsigned int DATA = 0x010000;
126f31639b8SShin-ya Okada const unsigned int CLOCK = 0x020000;
127f31639b8SShin-ya Okada const unsigned int LOAD = 0x040000;
128f31639b8SShin-ya Okada const unsigned int ALL_MASK = (DATA | CLOCK | LOAD);
129f31639b8SShin-ya Okada
130f31639b8SShin-ya Okada snd_ice1712_save_gpio_status(ice);
131f31639b8SShin-ya Okada
132f31639b8SShin-ya Okada st = ((addr & 0x7f) << 9) | (data & 0x1ff);
133f31639b8SShin-ya Okada snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK);
134f31639b8SShin-ya Okada snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK);
135f31639b8SShin-ya Okada bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK;
136f31639b8SShin-ya Okada
137f31639b8SShin-ya Okada snd_ice1712_gpio_write(ice, bits);
138f31639b8SShin-ya Okada for (i = 0; i < 16; i++) {
139f31639b8SShin-ya Okada udelay(1);
140f31639b8SShin-ya Okada bits &= ~CLOCK;
141f31639b8SShin-ya Okada st = (st << 1);
142f31639b8SShin-ya Okada if (st & 0x10000)
143f31639b8SShin-ya Okada bits |= DATA;
144f31639b8SShin-ya Okada else
145f31639b8SShin-ya Okada bits &= ~DATA;
146f31639b8SShin-ya Okada
147f31639b8SShin-ya Okada snd_ice1712_gpio_write(ice, bits);
148f31639b8SShin-ya Okada
149f31639b8SShin-ya Okada udelay(1);
150f31639b8SShin-ya Okada bits |= CLOCK;
151f31639b8SShin-ya Okada snd_ice1712_gpio_write(ice, bits);
152f31639b8SShin-ya Okada }
153f31639b8SShin-ya Okada
154f31639b8SShin-ya Okada udelay(1);
155f31639b8SShin-ya Okada bits |= LOAD;
156f31639b8SShin-ya Okada snd_ice1712_gpio_write(ice, bits);
157f31639b8SShin-ya Okada
158f31639b8SShin-ya Okada udelay(1);
159f31639b8SShin-ya Okada bits |= (DATA | CLOCK);
160f31639b8SShin-ya Okada snd_ice1712_gpio_write(ice, bits);
161f31639b8SShin-ya Okada
162f31639b8SShin-ya Okada snd_ice1712_restore_gpio_status(ice);
163f31639b8SShin-ya Okada }
164f31639b8SShin-ya Okada
se200pci_WM8766_set_volume(struct snd_ice1712 * ice,int ch,unsigned int vol1,unsigned int vol2)165f31639b8SShin-ya Okada static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,
166f31639b8SShin-ya Okada unsigned int vol1, unsigned int vol2)
167f31639b8SShin-ya Okada {
168f31639b8SShin-ya Okada switch (ch) {
169f31639b8SShin-ya Okada case 0:
170f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x000, vol1);
171f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x001, vol2 | 0x100);
172f31639b8SShin-ya Okada break;
173f31639b8SShin-ya Okada case 1:
174f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x004, vol1);
175f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x005, vol2 | 0x100);
176f31639b8SShin-ya Okada break;
177f31639b8SShin-ya Okada case 2:
178f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x006, vol1);
179f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x007, vol2 | 0x100);
180f31639b8SShin-ya Okada break;
181f31639b8SShin-ya Okada }
182f31639b8SShin-ya Okada }
183f31639b8SShin-ya Okada
se200pci_WM8766_init(struct snd_ice1712 * ice)184e23e7a14SBill Pemberton static void se200pci_WM8766_init(struct snd_ice1712 *ice)
185f31639b8SShin-ya Okada {
186f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
187f31639b8SShin-ya Okada udelay(10);
188f31639b8SShin-ya Okada
189f31639b8SShin-ya Okada se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */
190f31639b8SShin-ya Okada se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */
191f31639b8SShin-ya Okada se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */
192f31639b8SShin-ya Okada
193f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */
194f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
195f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */
196f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */
197f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */
198f31639b8SShin-ya Okada
199f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */
200f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */
201f31639b8SShin-ya Okada }
202f31639b8SShin-ya Okada
se200pci_WM8766_set_pro_rate(struct snd_ice1712 * ice,unsigned int rate)203f31639b8SShin-ya Okada static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice,
204f31639b8SShin-ya Okada unsigned int rate)
205f31639b8SShin-ya Okada {
206f31639b8SShin-ya Okada if (rate > 96000)
207f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */
208f31639b8SShin-ya Okada else
209f31639b8SShin-ya Okada se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
210f31639b8SShin-ya Okada }
211f31639b8SShin-ya Okada
212f31639b8SShin-ya Okada
213f31639b8SShin-ya Okada /****************************************************************************/
214f31639b8SShin-ya Okada /* WM8776 interface */
215f31639b8SShin-ya Okada /****************************************************************************/
216f31639b8SShin-ya Okada
se200pci_WM8776_write(struct snd_ice1712 * ice,unsigned int addr,unsigned int data)217f31639b8SShin-ya Okada static void se200pci_WM8776_write(struct snd_ice1712 *ice,
218f31639b8SShin-ya Okada unsigned int addr, unsigned int data)
219f31639b8SShin-ya Okada {
220f31639b8SShin-ya Okada unsigned int val;
221f31639b8SShin-ya Okada
222f31639b8SShin-ya Okada val = (addr << 9) | data;
223f31639b8SShin-ya Okada snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff);
224f31639b8SShin-ya Okada }
225f31639b8SShin-ya Okada
226f31639b8SShin-ya Okada
se200pci_WM8776_set_output_volume(struct snd_ice1712 * ice,unsigned int vol1,unsigned int vol2)227f31639b8SShin-ya Okada static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice,
228f31639b8SShin-ya Okada unsigned int vol1, unsigned int vol2)
229f31639b8SShin-ya Okada {
230f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x03, vol1);
231f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x04, vol2 | 0x100);
232f31639b8SShin-ya Okada }
233f31639b8SShin-ya Okada
se200pci_WM8776_set_input_volume(struct snd_ice1712 * ice,unsigned int vol1,unsigned int vol2)234f31639b8SShin-ya Okada static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,
235f31639b8SShin-ya Okada unsigned int vol1, unsigned int vol2)
236f31639b8SShin-ya Okada {
237f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x0e, vol1);
238f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
239f31639b8SShin-ya Okada }
240f31639b8SShin-ya Okada
241a2af050fSTakashi Iwai static const char * const se200pci_sel[] = {
242f31639b8SShin-ya Okada "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
243f31639b8SShin-ya Okada };
244f31639b8SShin-ya Okada
se200pci_WM8776_set_input_selector(struct snd_ice1712 * ice,unsigned int sel)245f31639b8SShin-ya Okada static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice,
246f31639b8SShin-ya Okada unsigned int sel)
247f31639b8SShin-ya Okada {
248*f16a4e96STakashi Iwai static const unsigned char vals[] = {
249f31639b8SShin-ya Okada /* LINE, CD, MIC, ALL, GND */
250f31639b8SShin-ya Okada 0x10, 0x04, 0x08, 0x1c, 0x03
251f31639b8SShin-ya Okada };
252f31639b8SShin-ya Okada if (sel > 4)
253f31639b8SShin-ya Okada sel = 4;
254f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x15, vals[sel]);
255f31639b8SShin-ya Okada }
256f31639b8SShin-ya Okada
se200pci_WM8776_set_afl(struct snd_ice1712 * ice,unsigned int afl)257f31639b8SShin-ya Okada static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)
258f31639b8SShin-ya Okada {
259f31639b8SShin-ya Okada /* AFL -- After Fader Listening */
260f31639b8SShin-ya Okada if (afl)
261f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x16, 0x005);
262f31639b8SShin-ya Okada else
263f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x16, 0x001);
264f31639b8SShin-ya Okada }
265f31639b8SShin-ya Okada
266a2af050fSTakashi Iwai static const char * const se200pci_agc[] = {
267f31639b8SShin-ya Okada "Off", "LimiterMode", "ALCMode", NULL
268f31639b8SShin-ya Okada };
269f31639b8SShin-ya Okada
se200pci_WM8776_set_agc(struct snd_ice1712 * ice,unsigned int agc)270f31639b8SShin-ya Okada static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)
271f31639b8SShin-ya Okada {
272f31639b8SShin-ya Okada /* AGC -- Auto Gain Control of the input */
273f31639b8SShin-ya Okada switch (agc) {
274f31639b8SShin-ya Okada case 0:
275f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */
276f31639b8SShin-ya Okada break;
277f31639b8SShin-ya Okada case 1:
278f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x10, 0x07b);
279f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */
280f31639b8SShin-ya Okada break;
281f31639b8SShin-ya Okada case 2:
282f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x10, 0x1fb);
283f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */
284f31639b8SShin-ya Okada break;
285f31639b8SShin-ya Okada }
286f31639b8SShin-ya Okada }
287f31639b8SShin-ya Okada
se200pci_WM8776_init(struct snd_ice1712 * ice)288e23e7a14SBill Pemberton static void se200pci_WM8776_init(struct snd_ice1712 *ice)
289f31639b8SShin-ya Okada {
290f31639b8SShin-ya Okada int i;
291*f16a4e96STakashi Iwai static const unsigned short default_values[] = {
292f31639b8SShin-ya Okada 0x100, 0x100, 0x100,
293f31639b8SShin-ya Okada 0x100, 0x100, 0x100,
294f31639b8SShin-ya Okada 0x000, 0x090, 0x000, 0x000,
295f31639b8SShin-ya Okada 0x022, 0x022, 0x022,
296f31639b8SShin-ya Okada 0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
297f31639b8SShin-ya Okada 0x032, 0x000, 0x0a6, 0x001, 0x001
298f31639b8SShin-ya Okada };
299f31639b8SShin-ya Okada
300f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */
301f31639b8SShin-ya Okada /* ADC and DAC interface is I2S 24bits mode */
302f31639b8SShin-ya Okada /* The sample-rate are automatically changed */
303f31639b8SShin-ya Okada udelay(10);
304f31639b8SShin-ya Okada /* BUT my board can not do reset all, so I load all by manually. */
305f31639b8SShin-ya Okada for (i = 0; i < ARRAY_SIZE(default_values); i++)
306f31639b8SShin-ya Okada se200pci_WM8776_write(ice, i, default_values[i]);
307f31639b8SShin-ya Okada
308f31639b8SShin-ya Okada se200pci_WM8776_set_input_selector(ice, 0);
309f31639b8SShin-ya Okada se200pci_WM8776_set_afl(ice, 0);
310f31639b8SShin-ya Okada se200pci_WM8776_set_agc(ice, 0);
311f31639b8SShin-ya Okada se200pci_WM8776_set_input_volume(ice, 0, 0);
312f31639b8SShin-ya Okada se200pci_WM8776_set_output_volume(ice, 0, 0);
313f31639b8SShin-ya Okada
314f31639b8SShin-ya Okada /* head phone mute and power down */
315f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x00, 0);
316f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x01, 0);
317f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x02, 0x100);
318f31639b8SShin-ya Okada se200pci_WM8776_write(ice, 0x0d, 0x080);
319f31639b8SShin-ya Okada }
320f31639b8SShin-ya Okada
se200pci_WM8776_set_pro_rate(struct snd_ice1712 * ice,unsigned int rate)321f31639b8SShin-ya Okada static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice,
322f31639b8SShin-ya Okada unsigned int rate)
323f31639b8SShin-ya Okada {
324f31639b8SShin-ya Okada /* nothing to do */
325f31639b8SShin-ya Okada }
326f31639b8SShin-ya Okada
327f31639b8SShin-ya Okada
328f31639b8SShin-ya Okada /****************************************************************************/
329f31639b8SShin-ya Okada /* runtime interface */
330f31639b8SShin-ya Okada /****************************************************************************/
331f31639b8SShin-ya Okada
se200pci_set_pro_rate(struct snd_ice1712 * ice,unsigned int rate)332f31639b8SShin-ya Okada static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
333f31639b8SShin-ya Okada {
334f31639b8SShin-ya Okada se200pci_WM8740_set_pro_rate(ice, rate);
335f31639b8SShin-ya Okada se200pci_WM8766_set_pro_rate(ice, rate);
336f31639b8SShin-ya Okada se200pci_WM8776_set_pro_rate(ice, rate);
337f31639b8SShin-ya Okada }
338f31639b8SShin-ya Okada
339f31639b8SShin-ya Okada struct se200pci_control {
340a2af050fSTakashi Iwai const char *name;
341f31639b8SShin-ya Okada enum {
342f31639b8SShin-ya Okada WM8766,
343f31639b8SShin-ya Okada WM8776in,
344f31639b8SShin-ya Okada WM8776out,
345f31639b8SShin-ya Okada WM8776sel,
346f31639b8SShin-ya Okada WM8776agc,
347f31639b8SShin-ya Okada WM8776afl
348f31639b8SShin-ya Okada } target;
349f31639b8SShin-ya Okada enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
350f31639b8SShin-ya Okada int ch;
351a2af050fSTakashi Iwai const char * const *member;
352f31639b8SShin-ya Okada const char *comment;
353f31639b8SShin-ya Okada };
354f31639b8SShin-ya Okada
355f31639b8SShin-ya Okada static const struct se200pci_control se200pci_cont[] = {
356f31639b8SShin-ya Okada {
357f31639b8SShin-ya Okada .name = "Front Playback Volume",
358f31639b8SShin-ya Okada .target = WM8776out,
359f31639b8SShin-ya Okada .type = VOLUME1,
360f31639b8SShin-ya Okada .comment = "Front(green)"
361f31639b8SShin-ya Okada },
362f31639b8SShin-ya Okada {
363f31639b8SShin-ya Okada .name = "Side Playback Volume",
364f31639b8SShin-ya Okada .target = WM8766,
365f31639b8SShin-ya Okada .type = VOLUME1,
366f31639b8SShin-ya Okada .ch = 1,
367f31639b8SShin-ya Okada .comment = "Surround(orange)"
368f31639b8SShin-ya Okada },
369f31639b8SShin-ya Okada {
370f31639b8SShin-ya Okada .name = "Surround Playback Volume",
371f31639b8SShin-ya Okada .target = WM8766,
372f31639b8SShin-ya Okada .type = VOLUME1,
373f31639b8SShin-ya Okada .ch = 2,
374f31639b8SShin-ya Okada .comment = "SurroundBack(white)"
375f31639b8SShin-ya Okada },
376f31639b8SShin-ya Okada {
377f31639b8SShin-ya Okada .name = "CLFE Playback Volume",
378f31639b8SShin-ya Okada .target = WM8766,
379f31639b8SShin-ya Okada .type = VOLUME1,
380f31639b8SShin-ya Okada .ch = 0,
381f31639b8SShin-ya Okada .comment = "Center(Lch)&SubWoofer(Rch)(black)"
382f31639b8SShin-ya Okada },
383f31639b8SShin-ya Okada {
384f31639b8SShin-ya Okada .name = "Capture Volume",
385f31639b8SShin-ya Okada .target = WM8776in,
386f31639b8SShin-ya Okada .type = VOLUME2
387f31639b8SShin-ya Okada },
388f31639b8SShin-ya Okada {
389f31639b8SShin-ya Okada .name = "Capture Select",
390f31639b8SShin-ya Okada .target = WM8776sel,
391f31639b8SShin-ya Okada .type = ENUM,
392f31639b8SShin-ya Okada .member = se200pci_sel
393f31639b8SShin-ya Okada },
394f31639b8SShin-ya Okada {
395f31639b8SShin-ya Okada .name = "AGC Capture Mode",
396f31639b8SShin-ya Okada .target = WM8776agc,
397f31639b8SShin-ya Okada .type = ENUM,
398f31639b8SShin-ya Okada .member = se200pci_agc
399f31639b8SShin-ya Okada },
400f31639b8SShin-ya Okada {
401f31639b8SShin-ya Okada .name = "AFL Bypass Playback Switch",
402f31639b8SShin-ya Okada .target = WM8776afl,
403f31639b8SShin-ya Okada .type = BOOLEAN
404f31639b8SShin-ya Okada }
405f31639b8SShin-ya Okada };
406f31639b8SShin-ya Okada
se200pci_get_enum_count(int n)4079c45ba10STakashi Iwai static int se200pci_get_enum_count(int n)
4089c45ba10STakashi Iwai {
409a2af050fSTakashi Iwai const char * const *member;
4109c45ba10STakashi Iwai int c;
4119c45ba10STakashi Iwai
4129c45ba10STakashi Iwai member = se200pci_cont[n].member;
4139c45ba10STakashi Iwai if (!member)
4149c45ba10STakashi Iwai return 0;
4159c45ba10STakashi Iwai for (c = 0; member[c]; c++)
4169c45ba10STakashi Iwai ;
4179c45ba10STakashi Iwai return c;
4189c45ba10STakashi Iwai }
4199c45ba10STakashi Iwai
se200pci_cont_volume_info(struct snd_kcontrol * kc,struct snd_ctl_elem_info * uinfo)4209c45ba10STakashi Iwai static int se200pci_cont_volume_info(struct snd_kcontrol *kc,
421f31639b8SShin-ya Okada struct snd_ctl_elem_info *uinfo)
422f31639b8SShin-ya Okada {
423f31639b8SShin-ya Okada uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
424f31639b8SShin-ya Okada uinfo->count = 2;
425f31639b8SShin-ya Okada uinfo->value.integer.min = 0; /* mute */
426f31639b8SShin-ya Okada uinfo->value.integer.max = 0xff; /* 0dB */
4279c45ba10STakashi Iwai return 0;
4289c45ba10STakashi Iwai }
429f31639b8SShin-ya Okada
4309c45ba10STakashi Iwai #define se200pci_cont_boolean_info snd_ctl_boolean_mono_info
431f31639b8SShin-ya Okada
se200pci_cont_enum_info(struct snd_kcontrol * kc,struct snd_ctl_elem_info * uinfo)4329c45ba10STakashi Iwai static int se200pci_cont_enum_info(struct snd_kcontrol *kc,
4339c45ba10STakashi Iwai struct snd_ctl_elem_info *uinfo)
4349c45ba10STakashi Iwai {
4359c45ba10STakashi Iwai int n, c;
4369c45ba10STakashi Iwai
4379c45ba10STakashi Iwai n = kc->private_value;
4389c45ba10STakashi Iwai c = se200pci_get_enum_count(n);
4399c45ba10STakashi Iwai if (!c)
440f31639b8SShin-ya Okada return -EINVAL;
441597da2e4STakashi Iwai return snd_ctl_enum_info(uinfo, 1, c, se200pci_cont[n].member);
442f31639b8SShin-ya Okada }
443f31639b8SShin-ya Okada
se200pci_cont_volume_get(struct snd_kcontrol * kc,struct snd_ctl_elem_value * uc)4449c45ba10STakashi Iwai static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
445f31639b8SShin-ya Okada struct snd_ctl_elem_value *uc)
446f31639b8SShin-ya Okada {
4479c45ba10STakashi Iwai struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
4487cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
4499c45ba10STakashi Iwai int n = kc->private_value;
4507cda8ba9STakashi Iwai uc->value.integer.value[0] = spec->vol[n].ch1;
4517cda8ba9STakashi Iwai uc->value.integer.value[1] = spec->vol[n].ch2;
452f31639b8SShin-ya Okada return 0;
453f31639b8SShin-ya Okada }
454f31639b8SShin-ya Okada
se200pci_cont_boolean_get(struct snd_kcontrol * kc,struct snd_ctl_elem_value * uc)4559c45ba10STakashi Iwai static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
456f31639b8SShin-ya Okada struct snd_ctl_elem_value *uc)
457f31639b8SShin-ya Okada {
4589c45ba10STakashi Iwai struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
4597cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
4609c45ba10STakashi Iwai int n = kc->private_value;
4617cda8ba9STakashi Iwai uc->value.integer.value[0] = spec->vol[n].ch1;
4629c45ba10STakashi Iwai return 0;
463f31639b8SShin-ya Okada }
464f31639b8SShin-ya Okada
se200pci_cont_enum_get(struct snd_kcontrol * kc,struct snd_ctl_elem_value * uc)4659c45ba10STakashi Iwai static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
4669c45ba10STakashi Iwai struct snd_ctl_elem_value *uc)
4679c45ba10STakashi Iwai {
4689c45ba10STakashi Iwai struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
4697cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
4709c45ba10STakashi Iwai int n = kc->private_value;
4717cda8ba9STakashi Iwai uc->value.enumerated.item[0] = spec->vol[n].ch1;
4729c45ba10STakashi Iwai return 0;
4739c45ba10STakashi Iwai }
4749c45ba10STakashi Iwai
se200pci_cont_update(struct snd_ice1712 * ice,int n)4759c45ba10STakashi Iwai static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
4769c45ba10STakashi Iwai {
4777cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
478f31639b8SShin-ya Okada switch (se200pci_cont[n].target) {
479f31639b8SShin-ya Okada case WM8766:
480f31639b8SShin-ya Okada se200pci_WM8766_set_volume(ice,
4819c45ba10STakashi Iwai se200pci_cont[n].ch,
4827cda8ba9STakashi Iwai spec->vol[n].ch1,
4837cda8ba9STakashi Iwai spec->vol[n].ch2);
484f31639b8SShin-ya Okada break;
485f31639b8SShin-ya Okada
486f31639b8SShin-ya Okada case WM8776in:
4879c45ba10STakashi Iwai se200pci_WM8776_set_input_volume(ice,
4887cda8ba9STakashi Iwai spec->vol[n].ch1,
4897cda8ba9STakashi Iwai spec->vol[n].ch2);
490f31639b8SShin-ya Okada break;
491f31639b8SShin-ya Okada
492f31639b8SShin-ya Okada case WM8776out:
4939c45ba10STakashi Iwai se200pci_WM8776_set_output_volume(ice,
4947cda8ba9STakashi Iwai spec->vol[n].ch1,
4957cda8ba9STakashi Iwai spec->vol[n].ch2);
496f31639b8SShin-ya Okada break;
497f31639b8SShin-ya Okada
498f31639b8SShin-ya Okada case WM8776sel:
4999c45ba10STakashi Iwai se200pci_WM8776_set_input_selector(ice,
5007cda8ba9STakashi Iwai spec->vol[n].ch1);
501f31639b8SShin-ya Okada break;
502f31639b8SShin-ya Okada
503f31639b8SShin-ya Okada case WM8776agc:
5047cda8ba9STakashi Iwai se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
505f31639b8SShin-ya Okada break;
506f31639b8SShin-ya Okada
507f31639b8SShin-ya Okada case WM8776afl:
5087cda8ba9STakashi Iwai se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
509f31639b8SShin-ya Okada break;
510f31639b8SShin-ya Okada
511f31639b8SShin-ya Okada default:
512f31639b8SShin-ya Okada break;
513f31639b8SShin-ya Okada }
5149c45ba10STakashi Iwai }
5159c45ba10STakashi Iwai
se200pci_cont_volume_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * uc)5169c45ba10STakashi Iwai static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
5179c45ba10STakashi Iwai struct snd_ctl_elem_value *uc)
5189c45ba10STakashi Iwai {
5199c45ba10STakashi Iwai struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
5207cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
5219c45ba10STakashi Iwai int n = kc->private_value;
5229c45ba10STakashi Iwai unsigned int vol1, vol2;
5239c45ba10STakashi Iwai int changed;
5249c45ba10STakashi Iwai
5259c45ba10STakashi Iwai changed = 0;
5269c45ba10STakashi Iwai vol1 = uc->value.integer.value[0] & 0xff;
5279c45ba10STakashi Iwai vol2 = uc->value.integer.value[1] & 0xff;
5287cda8ba9STakashi Iwai if (spec->vol[n].ch1 != vol1) {
5297cda8ba9STakashi Iwai spec->vol[n].ch1 = vol1;
5309c45ba10STakashi Iwai changed = 1;
5319c45ba10STakashi Iwai }
5327cda8ba9STakashi Iwai if (spec->vol[n].ch2 != vol2) {
5337cda8ba9STakashi Iwai spec->vol[n].ch2 = vol2;
5349c45ba10STakashi Iwai changed = 1;
5359c45ba10STakashi Iwai }
5369c45ba10STakashi Iwai if (changed)
5379c45ba10STakashi Iwai se200pci_cont_update(ice, n);
538f31639b8SShin-ya Okada
539f31639b8SShin-ya Okada return changed;
540f31639b8SShin-ya Okada }
541f31639b8SShin-ya Okada
se200pci_cont_boolean_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * uc)5429c45ba10STakashi Iwai static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
5439c45ba10STakashi Iwai struct snd_ctl_elem_value *uc)
5449c45ba10STakashi Iwai {
5459c45ba10STakashi Iwai struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
5467cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
5479c45ba10STakashi Iwai int n = kc->private_value;
5489c45ba10STakashi Iwai unsigned int vol1;
5499c45ba10STakashi Iwai
5509c45ba10STakashi Iwai vol1 = !!uc->value.integer.value[0];
5517cda8ba9STakashi Iwai if (spec->vol[n].ch1 != vol1) {
5527cda8ba9STakashi Iwai spec->vol[n].ch1 = vol1;
5539c45ba10STakashi Iwai se200pci_cont_update(ice, n);
5549c45ba10STakashi Iwai return 1;
5559c45ba10STakashi Iwai }
5569c45ba10STakashi Iwai return 0;
5579c45ba10STakashi Iwai }
5589c45ba10STakashi Iwai
se200pci_cont_enum_put(struct snd_kcontrol * kc,struct snd_ctl_elem_value * uc)5599c45ba10STakashi Iwai static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
5609c45ba10STakashi Iwai struct snd_ctl_elem_value *uc)
5619c45ba10STakashi Iwai {
5629c45ba10STakashi Iwai struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
5637cda8ba9STakashi Iwai struct se_spec *spec = ice->spec;
5649c45ba10STakashi Iwai int n = kc->private_value;
5659c45ba10STakashi Iwai unsigned int vol1;
5669c45ba10STakashi Iwai
5679c45ba10STakashi Iwai vol1 = uc->value.enumerated.item[0];
5689c45ba10STakashi Iwai if (vol1 >= se200pci_get_enum_count(n))
5699c45ba10STakashi Iwai return -EINVAL;
5707cda8ba9STakashi Iwai if (spec->vol[n].ch1 != vol1) {
5717cda8ba9STakashi Iwai spec->vol[n].ch1 = vol1;
5729c45ba10STakashi Iwai se200pci_cont_update(ice, n);
5739c45ba10STakashi Iwai return 1;
5749c45ba10STakashi Iwai }
5759c45ba10STakashi Iwai return 0;
5769c45ba10STakashi Iwai }
5779c45ba10STakashi Iwai
578f31639b8SShin-ya Okada static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
579f31639b8SShin-ya Okada static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
580f31639b8SShin-ya Okada
se200pci_add_controls(struct snd_ice1712 * ice)581e23e7a14SBill Pemberton static int se200pci_add_controls(struct snd_ice1712 *ice)
582f31639b8SShin-ya Okada {
583f31639b8SShin-ya Okada int i;
584f31639b8SShin-ya Okada struct snd_kcontrol_new cont;
585f31639b8SShin-ya Okada int err;
586f31639b8SShin-ya Okada
587f31639b8SShin-ya Okada memset(&cont, 0, sizeof(cont));
588f31639b8SShin-ya Okada cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
589f31639b8SShin-ya Okada for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) {
590f31639b8SShin-ya Okada cont.private_value = i;
591f31639b8SShin-ya Okada cont.name = se200pci_cont[i].name;
592f31639b8SShin-ya Okada cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
593f31639b8SShin-ya Okada cont.tlv.p = NULL;
5949c45ba10STakashi Iwai switch (se200pci_cont[i].type) {
5959c45ba10STakashi Iwai case VOLUME1:
5969c45ba10STakashi Iwai case VOLUME2:
5979c45ba10STakashi Iwai cont.info = se200pci_cont_volume_info;
5989c45ba10STakashi Iwai cont.get = se200pci_cont_volume_get;
5999c45ba10STakashi Iwai cont.put = se200pci_cont_volume_put;
600f31639b8SShin-ya Okada cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
601f31639b8SShin-ya Okada if (se200pci_cont[i].type == VOLUME1)
602f31639b8SShin-ya Okada cont.tlv.p = db_scale_gain1;
603f31639b8SShin-ya Okada else
604f31639b8SShin-ya Okada cont.tlv.p = db_scale_gain2;
6059c45ba10STakashi Iwai break;
6069c45ba10STakashi Iwai case BOOLEAN:
6079c45ba10STakashi Iwai cont.info = se200pci_cont_boolean_info;
6089c45ba10STakashi Iwai cont.get = se200pci_cont_boolean_get;
6099c45ba10STakashi Iwai cont.put = se200pci_cont_boolean_put;
6109c45ba10STakashi Iwai break;
6119c45ba10STakashi Iwai case ENUM:
6129c45ba10STakashi Iwai cont.info = se200pci_cont_enum_info;
6139c45ba10STakashi Iwai cont.get = se200pci_cont_enum_get;
6149c45ba10STakashi Iwai cont.put = se200pci_cont_enum_put;
6159c45ba10STakashi Iwai break;
6169c45ba10STakashi Iwai default:
6179c45ba10STakashi Iwai snd_BUG();
6189c45ba10STakashi Iwai return -EINVAL;
619f31639b8SShin-ya Okada }
620f31639b8SShin-ya Okada err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice));
621f31639b8SShin-ya Okada if (err < 0)
622f31639b8SShin-ya Okada return err;
623f31639b8SShin-ya Okada }
624f31639b8SShin-ya Okada
625f31639b8SShin-ya Okada return 0;
626f31639b8SShin-ya Okada }
627f31639b8SShin-ya Okada
628f31639b8SShin-ya Okada
629f31639b8SShin-ya Okada /****************************************************************************/
630f31639b8SShin-ya Okada /* ONKYO WAVIO SE-90PCI */
631f31639b8SShin-ya Okada /****************************************************************************/
632f31639b8SShin-ya Okada /*
633f31639b8SShin-ya Okada * system configuration ICE_EEP2_SYSCONF=0x4b
634f31639b8SShin-ya Okada * AC-Link configuration ICE_EEP2_ACLINK=0x80
635f31639b8SShin-ya Okada * I2S converters feature ICE_EEP2_I2S=0x78
636f31639b8SShin-ya Okada * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
637f31639b8SShin-ya Okada *
638f31639b8SShin-ya Okada * ** connected chip **
639f31639b8SShin-ya Okada *
640f31639b8SShin-ya Okada * WM8716
641f31639b8SShin-ya Okada * A 2ch-DAC of main outputs.
642f31639b8SShin-ya Okada * It setuped as I2S mode by wire, so no way to setup from software.
643f31639b8SShin-ya Okada * ML/I2S (28pin) -- +5V
644f31639b8SShin-ya Okada * MC/DM1 (27pin) -- GND
645f31639b8SShin-ya Okada * MC/DM0 (26pin) -- GND
646f31639b8SShin-ya Okada * MUTEB (25pin) -- open (internal pull-up)
647f31639b8SShin-ya Okada * MODE (24pin) -- GND
648f31639b8SShin-ya Okada * CSBIWO (23pin) -- +5V
649f31639b8SShin-ya Okada *
650f31639b8SShin-ya Okada */
651f31639b8SShin-ya Okada
652f31639b8SShin-ya Okada /* Nothing to do for this chip. */
653f31639b8SShin-ya Okada
654f31639b8SShin-ya Okada
655f31639b8SShin-ya Okada /****************************************************************************/
656f31639b8SShin-ya Okada /* probe/initialize/setup */
657f31639b8SShin-ya Okada /****************************************************************************/
658f31639b8SShin-ya Okada
se_init(struct snd_ice1712 * ice)659e23e7a14SBill Pemberton static int se_init(struct snd_ice1712 *ice)
660f31639b8SShin-ya Okada {
6617cda8ba9STakashi Iwai struct se_spec *spec;
6627cda8ba9STakashi Iwai
6637cda8ba9STakashi Iwai spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6647cda8ba9STakashi Iwai if (!spec)
6657cda8ba9STakashi Iwai return -ENOMEM;
6667cda8ba9STakashi Iwai ice->spec = spec;
6677cda8ba9STakashi Iwai
668f31639b8SShin-ya Okada if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
669f31639b8SShin-ya Okada ice->num_total_dacs = 2;
670f31639b8SShin-ya Okada ice->num_total_adcs = 0;
671f31639b8SShin-ya Okada ice->vt1720 = 1;
672f31639b8SShin-ya Okada return 0;
673f31639b8SShin-ya Okada
674f31639b8SShin-ya Okada } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) {
675f31639b8SShin-ya Okada ice->num_total_dacs = 8;
676f31639b8SShin-ya Okada ice->num_total_adcs = 2;
677f31639b8SShin-ya Okada se200pci_WM8740_init(ice);
678f31639b8SShin-ya Okada se200pci_WM8766_init(ice);
679f31639b8SShin-ya Okada se200pci_WM8776_init(ice);
680f31639b8SShin-ya Okada ice->gpio.set_pro_rate = se200pci_set_pro_rate;
681f31639b8SShin-ya Okada return 0;
682f31639b8SShin-ya Okada }
683f31639b8SShin-ya Okada
684f31639b8SShin-ya Okada return -ENOENT;
685f31639b8SShin-ya Okada }
686f31639b8SShin-ya Okada
se_add_controls(struct snd_ice1712 * ice)687e23e7a14SBill Pemberton static int se_add_controls(struct snd_ice1712 *ice)
688f31639b8SShin-ya Okada {
689f31639b8SShin-ya Okada int err;
690f31639b8SShin-ya Okada
691f31639b8SShin-ya Okada err = 0;
692f31639b8SShin-ya Okada /* nothing to do for VT1724_SUBDEVICE_SE90PCI */
693f31639b8SShin-ya Okada if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI)
694f31639b8SShin-ya Okada err = se200pci_add_controls(ice);
695f31639b8SShin-ya Okada
696f31639b8SShin-ya Okada return err;
697f31639b8SShin-ya Okada }
698f31639b8SShin-ya Okada
699f31639b8SShin-ya Okada
700f31639b8SShin-ya Okada /****************************************************************************/
701f31639b8SShin-ya Okada /* entry point */
702f31639b8SShin-ya Okada /****************************************************************************/
703f31639b8SShin-ya Okada
704*f16a4e96STakashi Iwai static const unsigned char se200pci_eeprom[] = {
705f31639b8SShin-ya Okada [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
706f31639b8SShin-ya Okada [ICE_EEP2_ACLINK] = 0x80, /* I2S */
707f31639b8SShin-ya Okada [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
708f31639b8SShin-ya Okada [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
709f31639b8SShin-ya Okada
710f31639b8SShin-ya Okada [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */
711f31639b8SShin-ya Okada [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */
712f31639b8SShin-ya Okada [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */
713f31639b8SShin-ya Okada
714f31639b8SShin-ya Okada [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */
715f31639b8SShin-ya Okada [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */
716f31639b8SShin-ya Okada [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */
717f31639b8SShin-ya Okada
718f31639b8SShin-ya Okada [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */
719f31639b8SShin-ya Okada [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */
720f31639b8SShin-ya Okada [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */
721f31639b8SShin-ya Okada };
722f31639b8SShin-ya Okada
723*f16a4e96STakashi Iwai static const unsigned char se90pci_eeprom[] = {
724f31639b8SShin-ya Okada [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
725f31639b8SShin-ya Okada [ICE_EEP2_ACLINK] = 0x80, /* I2S */
726f31639b8SShin-ya Okada [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
727f31639b8SShin-ya Okada [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
728f31639b8SShin-ya Okada
729f31639b8SShin-ya Okada /* ALL GPIO bits are in input mode */
730f31639b8SShin-ya Okada };
731f31639b8SShin-ya Okada
732e23e7a14SBill Pemberton struct snd_ice1712_card_info snd_vt1724_se_cards[] = {
733f31639b8SShin-ya Okada {
734f31639b8SShin-ya Okada .subvendor = VT1724_SUBDEVICE_SE200PCI,
735f31639b8SShin-ya Okada .name = "ONKYO SE200PCI",
736f31639b8SShin-ya Okada .model = "se200pci",
737f31639b8SShin-ya Okada .chip_init = se_init,
738f31639b8SShin-ya Okada .build_controls = se_add_controls,
739f31639b8SShin-ya Okada .eeprom_size = sizeof(se200pci_eeprom),
740f31639b8SShin-ya Okada .eeprom_data = se200pci_eeprom,
741f31639b8SShin-ya Okada },
742f31639b8SShin-ya Okada {
743f31639b8SShin-ya Okada .subvendor = VT1724_SUBDEVICE_SE90PCI,
744f31639b8SShin-ya Okada .name = "ONKYO SE90PCI",
745f31639b8SShin-ya Okada .model = "se90pci",
746f31639b8SShin-ya Okada .chip_init = se_init,
747f31639b8SShin-ya Okada .build_controls = se_add_controls,
748f31639b8SShin-ya Okada .eeprom_size = sizeof(se90pci_eeprom),
749f31639b8SShin-ya Okada .eeprom_data = se90pci_eeprom,
750f31639b8SShin-ya Okada },
751f31639b8SShin-ya Okada {} /*terminator*/
752f31639b8SShin-ya Okada };
753