aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/pci/ice1712
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/pci/ice1712')
-rw-r--r--sound/pci/ice1712/Makefile12
-rw-r--r--sound/pci/ice1712/ak4xxx.c194
-rw-r--r--sound/pci/ice1712/amp.c65
-rw-r--r--sound/pci/ice1712/amp.h34
-rw-r--r--sound/pci/ice1712/aureon.c1948
-rw-r--r--sound/pci/ice1712/aureon.h56
-rw-r--r--sound/pci/ice1712/delta.c771
-rw-r--r--sound/pci/ice1712/delta.h150
-rw-r--r--sound/pci/ice1712/envy24ht.h215
-rw-r--r--sound/pci/ice1712/ews.c1036
-rw-r--r--sound/pci/ice1712/ews.h84
-rw-r--r--sound/pci/ice1712/hoontech.c326
-rw-r--r--sound/pci/ice1712/hoontech.h77
-rw-r--r--sound/pci/ice1712/ice1712.c2760
-rw-r--r--sound/pci/ice1712/ice1712.h494
-rw-r--r--sound/pci/ice1712/ice1724.c2340
-rw-r--r--sound/pci/ice1712/juli.c230
-rw-r--r--sound/pci/ice1712/juli.h10
-rw-r--r--sound/pci/ice1712/phase.c138
-rw-r--r--sound/pci/ice1712/phase.h34
-rw-r--r--sound/pci/ice1712/pontis.c849
-rw-r--r--sound/pci/ice1712/pontis.h33
-rw-r--r--sound/pci/ice1712/prodigy192.c524
-rw-r--r--sound/pci/ice1712/prodigy192.h11
-rw-r--r--sound/pci/ice1712/revo.c205
-rw-r--r--sound/pci/ice1712/revo.h48
-rw-r--r--sound/pci/ice1712/stac946x.h25
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c115
-rw-r--r--sound/pci/ice1712/vt1720_mobo.h39
29 files changed, 12823 insertions, 0 deletions
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
new file mode 100644
index 000000000000..7837cef8855c
--- /dev/null
+++ b/sound/pci/ice1712/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-ice17xx-ak4xxx-objs := ak4xxx.o
7snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o
9
10# Toplevel Module Dependency
11obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
12obj-$(CONFIG_SND_ICE1724) += snd-ice1724.o snd-ice17xx-ak4xxx.o
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
new file mode 100644
index 000000000000..ae9dc029ba0d
--- /dev/null
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -0,0 +1,194 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include "ice1712.h"
32
33MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
34MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface");
35MODULE_LICENSE("GPL");
36
37static void snd_ice1712_akm4xxx_lock(akm4xxx_t *ak, int chip)
38{
39 ice1712_t *ice = ak->private_data[0];
40
41 snd_ice1712_save_gpio_status(ice);
42}
43
44static void snd_ice1712_akm4xxx_unlock(akm4xxx_t *ak, int chip)
45{
46 ice1712_t *ice = ak->private_data[0];
47
48 snd_ice1712_restore_gpio_status(ice);
49}
50
51/*
52 * write AK4xxx register
53 */
54static void snd_ice1712_akm4xxx_write(akm4xxx_t *ak, int chip,
55 unsigned char addr, unsigned char data)
56{
57 unsigned int tmp;
58 int idx;
59 unsigned int addrdata;
60 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
61 ice1712_t *ice = ak->private_data[0];
62
63 snd_assert(chip >= 0 && chip < 4, return);
64
65 tmp = snd_ice1712_gpio_read(ice);
66 tmp |= priv->add_flags;
67 tmp &= ~priv->mask_flags;
68 if (priv->cs_mask == priv->cs_addr) {
69 if (priv->cif) {
70 tmp |= priv->cs_mask; /* start without chip select */
71 } else {
72 tmp &= ~priv->cs_mask; /* chip select low */
73 snd_ice1712_gpio_write(ice, tmp);
74 udelay(1);
75 }
76 } else {
77 /* doesn't handle cf=1 yet */
78 tmp &= ~priv->cs_mask;
79 tmp |= priv->cs_addr;
80 snd_ice1712_gpio_write(ice, tmp);
81 udelay(1);
82 }
83
84 /* build I2C address + data byte */
85 addrdata = (priv->caddr << 6) | 0x20 | (addr & 0x1f);
86 addrdata = (addrdata << 8) | data;
87 for (idx = 15; idx >= 0; idx--) {
88 /* drop clock */
89 tmp &= ~priv->clk_mask;
90 snd_ice1712_gpio_write(ice, tmp);
91 udelay(1);
92 /* set data */
93 if (addrdata & (1 << idx))
94 tmp |= priv->data_mask;
95 else
96 tmp &= ~priv->data_mask;
97 snd_ice1712_gpio_write(ice, tmp);
98 udelay(1);
99 /* raise clock */
100 tmp |= priv->clk_mask;
101 snd_ice1712_gpio_write(ice, tmp);
102 udelay(1);
103 }
104
105 if (priv->cs_mask == priv->cs_addr) {
106 if (priv->cif) {
107 /* assert a cs pulse to trigger */
108 tmp &= ~priv->cs_mask;
109 snd_ice1712_gpio_write(ice, tmp);
110 udelay(1);
111 }
112 tmp |= priv->cs_mask; /* chip select high to trigger */
113 } else {
114 tmp &= ~priv->cs_mask;
115 tmp |= priv->cs_none; /* deselect address */
116 }
117 snd_ice1712_gpio_write(ice, tmp);
118 udelay(1);
119}
120
121/*
122 * initialize the akm4xxx_t record with the template
123 */
124int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *temp,
125 const struct snd_ak4xxx_private *_priv, ice1712_t *ice)
126{
127 struct snd_ak4xxx_private *priv;
128
129 if (_priv != NULL) {
130 priv = kmalloc(sizeof(*priv), GFP_KERNEL);
131 if (priv == NULL)
132 return -ENOMEM;
133 *priv = *_priv;
134 } else {
135 priv = NULL;
136 }
137 *ak = *temp;
138 ak->card = ice->card;
139 ak->private_value[0] = (unsigned long)priv;
140 ak->private_data[0] = ice;
141 if (ak->ops.lock == NULL)
142 ak->ops.lock = snd_ice1712_akm4xxx_lock;
143 if (ak->ops.unlock == NULL)
144 ak->ops.unlock = snd_ice1712_akm4xxx_unlock;
145 if (ak->ops.write == NULL)
146 ak->ops.write = snd_ice1712_akm4xxx_write;
147 snd_akm4xxx_init(ak);
148 return 0;
149}
150
151void snd_ice1712_akm4xxx_free(ice1712_t *ice)
152{
153 unsigned int akidx;
154 if (ice->akm == NULL)
155 return;
156 for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
157 akm4xxx_t *ak = &ice->akm[akidx];
158 kfree((void*)ak->private_value[0]);
159 }
160 kfree(ice->akm);
161}
162
163/*
164 * build AK4xxx controls
165 */
166int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice)
167{
168 unsigned int akidx;
169 int err;
170
171 for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
172 akm4xxx_t *ak = &ice->akm[akidx];
173 err = snd_akm4xxx_build_controls(ak);
174 if (err < 0)
175 return err;
176 }
177 return 0;
178}
179
180static int __init alsa_ice1712_akm4xxx_module_init(void)
181{
182 return 0;
183}
184
185static void __exit alsa_ice1712_akm4xxx_module_exit(void)
186{
187}
188
189module_init(alsa_ice1712_akm4xxx_module_init)
190module_exit(alsa_ice1712_akm4xxx_module_exit)
191
192EXPORT_SYMBOL(snd_ice1712_akm4xxx_init);
193EXPORT_SYMBOL(snd_ice1712_akm4xxx_free);
194EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls);
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
new file mode 100644
index 000000000000..779951725e1e
--- /dev/null
+++ b/sound/pci/ice1712/amp.c
@@ -0,0 +1,65 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "amp.h"
34
35
36static int __devinit snd_vt1724_amp_init(ice1712_t *ice)
37{
38 /* only use basic functionality for now */
39
40 ice->num_total_dacs = 2; /* only PSDOUT0 is connected */
41 ice->num_total_adcs = 2;
42
43 return 0;
44}
45
46static int __devinit snd_vt1724_amp_add_controls(ice1712_t *ice)
47{
48 /* we use pins 39 and 41 of the VT1616 for left and right read outputs */
49 snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
50 return 0;
51}
52
53
54/* entry point */
55struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
56 {
57 .subvendor = VT1724_SUBDEVICE_AUDIO2000,
58 .name = "AMP Ltd AUDIO2000",
59 .model = "amp2000",
60 .chip_init = snd_vt1724_amp_init,
61 .build_controls = snd_vt1724_amp_add_controls,
62 },
63 { } /* terminator */
64};
65
diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
new file mode 100644
index 000000000000..d58d43383e83
--- /dev/null
+++ b/sound/pci/ice1712/amp.h
@@ -0,0 +1,34 @@
1#ifndef __SOUND_AMP_H
2#define __SOUND_AMP_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
8 *
9 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
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
27#define AMP_AUDIO2000_DEVICE_DESC "{AMP Ltd,AUDIO2000},"
28
29#define VT1724_SUBDEVICE_AUDIO2000 0x12142417 /* Advanced Micro Peripherals Ltd AUDIO2000 */
30
31extern struct snd_ice1712_card_info snd_vt1724_amp_cards[];
32
33
34#endif /* __SOUND_AMP_H */
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
new file mode 100644
index 000000000000..4405d96cbedf
--- /dev/null
+++ b/sound/pci/ice1712/aureon.c
@@ -0,0 +1,1948 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Terratec Aureon cards
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
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 * NOTES:
24 *
25 * - we reuse the akm4xxx_t record for storing the wm8770 codec data.
26 * both wm and akm codecs are pretty similar, so we can integrate
27 * both controls in the future, once if wm codecs are reused in
28 * many boards.
29 *
30 * - DAC digital volumes are not implemented in the mixer.
31 * if they show better response than DAC analog volumes, we can use them
32 * instead.
33 *
34 * Lowlevel functions for AudioTrak Prodigy 7.1 (and possibly 192) cards
35 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
36 *
37 * version 0.82: Stable / not all features work yet (no communication with AC97 secondary)
38 * added 64x/128x oversampling switch (should be 64x only for 96khz)
39 * fixed some recording labels (still need to check the rest)
40 * recording is working probably thanks to correct wm8770 initialization
41 *
42 * version 0.5: Initial release:
43 * working: analog output, mixer, headphone amplifier switch
44 * not working: prety much everything else, at least i could verify that
45 * we have no digital output, no capture, pretty bad clicks and poops
46 * on mixer switch and other coll stuff.
47 *
48 */
49
50#include <sound/driver.h>
51#include <asm/io.h>
52#include <linux/delay.h>
53#include <linux/interrupt.h>
54#include <linux/init.h>
55#include <linux/slab.h>
56#include <sound/core.h>
57
58#include "ice1712.h"
59#include "envy24ht.h"
60#include "aureon.h"
61
62/* WM8770 registers */
63#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
64#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
65#define WM_DAC_DIG_ATTEN 0x09 /* DAC1-8 digital attenuation */
66#define WM_DAC_DIG_MASTER_ATTEN 0x11 /* DAC master digital attenuation */
67#define WM_PHASE_SWAP 0x12 /* DAC phase */
68#define WM_DAC_CTRL1 0x13 /* DAC control bits */
69#define WM_MUTE 0x14 /* mute controls */
70#define WM_DAC_CTRL2 0x15 /* de-emphasis and zefo-flag */
71#define WM_INT_CTRL 0x16 /* interface control */
72#define WM_MASTER 0x17 /* master clock and mode */
73#define WM_POWERDOWN 0x18 /* power-down controls */
74#define WM_ADC_GAIN 0x19 /* ADC gain L(19)/R(1a) */
75#define WM_ADC_MUX 0x1b /* input MUX */
76#define WM_OUT_MUX1 0x1c /* output MUX */
77#define WM_OUT_MUX2 0x1e /* output MUX */
78#define WM_RESET 0x1f /* software reset */
79
80/* CS8415A registers */
81#define CS8415_CTRL1 0x01
82#define CS8415_CTRL2 0x02
83#define CS8415_QSUB 0x14
84#define CS8415_RATIO 0x1E
85#define CS8415_C_BUFFER 0x20
86#define CS8415_ID 0x7F
87
88static void aureon_ac97_write(ice1712_t *ice, unsigned short reg, unsigned short val) {
89 unsigned int tmp;
90
91 /* Send address to XILINX chip */
92 tmp = (snd_ice1712_gpio_read(ice) & ~0xFF) | (reg & 0x7F);
93 snd_ice1712_gpio_write(ice, tmp);
94 udelay(10);
95 tmp |= AUREON_AC97_ADDR;
96 snd_ice1712_gpio_write(ice, tmp);
97 udelay(10);
98 tmp &= ~AUREON_AC97_ADDR;
99 snd_ice1712_gpio_write(ice, tmp);
100 udelay(10);
101
102 /* Send low-order byte to XILINX chip */
103 tmp &= ~AUREON_AC97_DATA_MASK;
104 tmp |= val & AUREON_AC97_DATA_MASK;
105 snd_ice1712_gpio_write(ice, tmp);
106 udelay(10);
107 tmp |= AUREON_AC97_DATA_LOW;
108 snd_ice1712_gpio_write(ice, tmp);
109 udelay(10);
110 tmp &= ~AUREON_AC97_DATA_LOW;
111 snd_ice1712_gpio_write(ice, tmp);
112 udelay(10);
113
114 /* Send high-order byte to XILINX chip */
115 tmp &= ~AUREON_AC97_DATA_MASK;
116 tmp |= (val >> 8) & AUREON_AC97_DATA_MASK;
117
118 snd_ice1712_gpio_write(ice, tmp);
119 udelay(10);
120 tmp |= AUREON_AC97_DATA_HIGH;
121 snd_ice1712_gpio_write(ice, tmp);
122 udelay(10);
123 tmp &= ~AUREON_AC97_DATA_HIGH;
124 snd_ice1712_gpio_write(ice, tmp);
125 udelay(10);
126
127 /* Instruct XILINX chip to parse the data to the STAC9744 chip */
128 tmp |= AUREON_AC97_COMMIT;
129 snd_ice1712_gpio_write(ice, tmp);
130 udelay(10);
131 tmp &= ~AUREON_AC97_COMMIT;
132 snd_ice1712_gpio_write(ice, tmp);
133 udelay(10);
134
135 /* Store the data in out private buffer */
136 ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
137}
138
139static unsigned short aureon_ac97_read(ice1712_t *ice, unsigned short reg)
140{
141 return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
142}
143
144/*
145 * Initialize STAC9744 chip
146 */
147static int aureon_ac97_init (ice1712_t *ice) {
148 int i;
149 static unsigned short ac97_defaults[] = {
150 0x00, 0x9640,
151 0x02, 0x8000,
152 0x04, 0x8000,
153 0x06, 0x8000,
154 0x0C, 0x8008,
155 0x0E, 0x8008,
156 0x10, 0x8808,
157 0x12, 0x8808,
158 0x14, 0x8808,
159 0x16, 0x8808,
160 0x18, 0x8808,
161 0x1C, 0x8000,
162 0x26, 0x000F,
163 0x28, 0x0201,
164 0x2C, 0xBB80,
165 0x32, 0xBB80,
166 0x7C, 0x8384,
167 0x7E, 0x7644,
168 (unsigned short)-1
169 };
170 unsigned int tmp;
171
172 /* Cold reset */
173 tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK;
174 snd_ice1712_gpio_write(ice, tmp);
175 udelay(3);
176
177 tmp &= ~AUREON_AC97_RESET;
178 snd_ice1712_gpio_write(ice, tmp);
179 udelay(3);
180
181 tmp |= AUREON_AC97_RESET;
182 snd_ice1712_gpio_write(ice, tmp);
183 udelay(3);
184
185 memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
186 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
187 ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
188
189 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
190
191 return 0;
192}
193
194#define AUREON_AC97_STEREO 0x80
195
196/*
197 * AC'97 volume controls
198 */
199static int aureon_ac97_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
200{
201 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
202 uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
203 uinfo->value.integer.min = 0;
204 uinfo->value.integer.max = 31;
205 return 0;
206}
207
208static int aureon_ac97_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
209{
210 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
211 unsigned short vol;
212
213 down(&ice->gpio_mutex);
214
215 vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
216 ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F);
217 if (kcontrol->private_value & AUREON_AC97_STEREO)
218 ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F);
219
220 up(&ice->gpio_mutex);
221 return 0;
222}
223
224static int aureon_ac97_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
225{
226 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
227 unsigned short ovol, nvol;
228 int change;
229
230 snd_ice1712_save_gpio_status(ice);
231
232 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
233 nvol = (0x1F - ucontrol->value.integer.value[0]) & 0x001F;
234 if (kcontrol->private_value & AUREON_AC97_STEREO)
235 nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00;
236 nvol |= ovol & ~0x1F1F;
237
238 if ((change = (ovol != nvol)))
239 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
240
241 snd_ice1712_restore_gpio_status(ice);
242
243 return change;
244}
245
246/*
247 * AC'97 mute controls
248 */
249#define aureon_ac97_mute_info aureon_mono_bool_info
250
251static int aureon_ac97_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
252{
253 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
254
255 down(&ice->gpio_mutex);
256
257 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1;
258
259 up(&ice->gpio_mutex);
260 return 0;
261}
262
263static int aureon_ac97_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
264{
265 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
266 unsigned short ovol, nvol;
267 int change;
268
269 snd_ice1712_save_gpio_status(ice);
270
271 ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F);
272 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000);
273
274 if ((change = (ovol != nvol)))
275 aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol);
276
277 snd_ice1712_restore_gpio_status(ice);
278
279 return change;
280}
281
282/*
283 * AC'97 mute controls
284 */
285#define aureon_ac97_micboost_info aureon_mono_bool_info
286
287static int aureon_ac97_micboost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
288{
289 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
290
291 down(&ice->gpio_mutex);
292
293 ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1;
294
295 up(&ice->gpio_mutex);
296 return 0;
297}
298
299static int aureon_ac97_micboost_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
300{
301 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
302 unsigned short ovol, nvol;
303 int change;
304
305 snd_ice1712_save_gpio_status(ice);
306
307 ovol = aureon_ac97_read(ice, AC97_MIC);
308 nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020);
309
310 if ((change = (ovol != nvol)))
311 aureon_ac97_write(ice, AC97_MIC, nvol);
312
313 snd_ice1712_restore_gpio_status(ice);
314
315 return change;
316}
317
318/*
319 * write data in the SPI mode
320 */
321static void aureon_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
322{
323 unsigned int tmp;
324 int i;
325
326 tmp = snd_ice1712_gpio_read(ice);
327
328 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK|
329 AUREON_WM_CS|AUREON_CS8415_CS));
330 tmp |= AUREON_WM_RW;
331 tmp &= ~cs;
332 snd_ice1712_gpio_write(ice, tmp);
333 udelay(1);
334
335 for (i = bits - 1; i >= 0; i--) {
336 tmp &= ~AUREON_SPI_CLK;
337 snd_ice1712_gpio_write(ice, tmp);
338 udelay(1);
339 if (data & (1 << i))
340 tmp |= AUREON_SPI_MOSI;
341 else
342 tmp &= ~AUREON_SPI_MOSI;
343 snd_ice1712_gpio_write(ice, tmp);
344 udelay(1);
345 tmp |= AUREON_SPI_CLK;
346 snd_ice1712_gpio_write(ice, tmp);
347 udelay(1);
348 }
349
350 tmp &= ~AUREON_SPI_CLK;
351 tmp |= cs;
352 snd_ice1712_gpio_write(ice, tmp);
353 udelay(1);
354 tmp |= AUREON_SPI_CLK;
355 snd_ice1712_gpio_write(ice, tmp);
356 udelay(1);
357}
358
359/*
360 * Read data in SPI mode
361 */
362static void aureon_spi_read(ice1712_t *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
363 int i, j;
364 unsigned int tmp;
365
366 tmp = (snd_ice1712_gpio_read(ice) & ~AUREON_SPI_CLK) | AUREON_CS8415_CS|AUREON_WM_CS;
367 snd_ice1712_gpio_write(ice, tmp);
368 tmp &= ~cs;
369 snd_ice1712_gpio_write(ice, tmp);
370 udelay(1);
371
372 for (i=bits-1; i>=0; i--) {
373 if (data & (1 << i))
374 tmp |= AUREON_SPI_MOSI;
375 else
376 tmp &= ~AUREON_SPI_MOSI;
377 snd_ice1712_gpio_write(ice, tmp);
378 udelay(1);
379
380 tmp |= AUREON_SPI_CLK;
381 snd_ice1712_gpio_write(ice, tmp);
382 udelay(1);
383
384 tmp &= ~AUREON_SPI_CLK;
385 snd_ice1712_gpio_write(ice, tmp);
386 udelay(1);
387 }
388
389 for (j=0; j<size; j++) {
390 unsigned char outdata = 0;
391 for (i=7; i>=0; i--) {
392 tmp = snd_ice1712_gpio_read(ice);
393 outdata <<= 1;
394 outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0;
395 udelay(1);
396
397 tmp |= AUREON_SPI_CLK;
398 snd_ice1712_gpio_write(ice, tmp);
399 udelay(1);
400
401 tmp &= ~AUREON_SPI_CLK;
402 snd_ice1712_gpio_write(ice, tmp);
403 udelay(1);
404 }
405 buffer[j] = outdata;
406 }
407
408 tmp |= cs;
409 snd_ice1712_gpio_write(ice, tmp);
410}
411
412static unsigned char aureon_cs8415_get(ice1712_t *ice, int reg) {
413 unsigned char val;
414 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
415 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
416 return val;
417}
418
419static void aureon_cs8415_read(ice1712_t *ice, int reg, unsigned char *buffer, int size) {
420 aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
421 aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
422}
423
424static void aureon_cs8415_put(ice1712_t *ice, int reg, unsigned char val) {
425 aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
426}
427
428/*
429 * get the current register value of WM codec
430 */
431static unsigned short wm_get(ice1712_t *ice, int reg)
432{
433 reg <<= 1;
434 return ((unsigned short)ice->akm[0].images[reg] << 8) |
435 ice->akm[0].images[reg + 1];
436}
437
438/*
439 * set the register value of WM codec
440 */
441static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
442{
443 aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
444}
445
446/*
447 * set the register value of WM codec and remember it
448 */
449static void wm_put(ice1712_t *ice, int reg, unsigned short val)
450{
451 wm_put_nocache(ice, reg, val);
452 reg <<= 1;
453 ice->akm[0].images[reg] = val >> 8;
454 ice->akm[0].images[reg + 1] = val;
455}
456
457/*
458 */
459static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
460{
461 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
462 uinfo->count = 1;
463 uinfo->value.integer.min = 0;
464 uinfo->value.integer.max = 1;
465 return 0;
466}
467
468/*
469 * AC'97 master playback mute controls (Mute on WM8770 chip)
470 */
471#define aureon_ac97_mmute_info aureon_mono_bool_info
472
473static int aureon_ac97_mmute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
474{
475 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
476
477 down(&ice->gpio_mutex);
478
479 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01;
480
481 up(&ice->gpio_mutex);
482 return 0;
483}
484
485static int aureon_ac97_mmute_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
486 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
487 unsigned short ovol, nvol;
488 int change;
489
490 snd_ice1712_save_gpio_status(ice);
491
492 ovol = wm_get(ice, WM_OUT_MUX1);
493 nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00);
494 if ((change = (ovol != nvol)))
495 wm_put(ice, WM_OUT_MUX1, nvol);
496
497 snd_ice1712_restore_gpio_status(ice);
498
499 return change;
500}
501
502/*
503 * Logarithmic volume values for WM8770
504 * Computed as 20 * Log10(255 / x)
505 */
506static unsigned char wm_vol[256] = {
507 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
508 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
509 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
510 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
511 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
512 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
513 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
514 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
515 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
517 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
518 0, 0
519};
520
521#define WM_VOL_MAX (sizeof(wm_vol) - 1)
522#define WM_VOL_MUTE 0x8000
523
524static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
525{
526 unsigned char nvol;
527
528 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
529 nvol = 0;
530 else
531 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
532
533 wm_put(ice, index, nvol);
534 wm_put_nocache(ice, index, 0x180 | nvol);
535}
536
537/*
538 * DAC mute control
539 */
540#define wm_pcm_mute_info aureon_mono_bool_info
541
542static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
543{
544 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
545
546 down(&ice->gpio_mutex);
547 ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
548 up(&ice->gpio_mutex);
549 return 0;
550}
551
552static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
553{
554 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
555 unsigned short nval, oval;
556 int change;
557
558 snd_ice1712_save_gpio_status(ice);
559 oval = wm_get(ice, WM_MUTE);
560 nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
561 if ((change = (nval != oval)))
562 wm_put(ice, WM_MUTE, nval);
563 snd_ice1712_restore_gpio_status(ice);
564
565 return change;
566}
567
568/*
569 * Master volume attenuation mixer control
570 */
571static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
572{
573 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
574 uinfo->count = 2;
575 uinfo->value.integer.min = 0;
576 uinfo->value.integer.max = WM_VOL_MAX;
577 return 0;
578}
579
580static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
581{
582 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
583 int i;
584 for (i=0; i<2; i++)
585 ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
586 return 0;
587}
588
589static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
590{
591 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
592 int ch, change = 0;
593
594 snd_ice1712_save_gpio_status(ice);
595 for (ch = 0; ch < 2; ch++) {
596 if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) {
597 int dac;
598 ice->spec.aureon.master[ch] &= WM_VOL_MUTE;
599 ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
600 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
601 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
602 ice->spec.aureon.vol[dac + ch],
603 ice->spec.aureon.master[ch]);
604 change = 1;
605 }
606 }
607 snd_ice1712_restore_gpio_status(ice);
608 return change;
609}
610
611/*
612 * DAC volume attenuation mixer control
613 */
614static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
615{
616 int voices = kcontrol->private_value >> 8;
617 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
618 uinfo->count = voices;
619 uinfo->value.integer.min = 0; /* mute (-101dB) */
620 uinfo->value.integer.max = 0x7F; /* 0dB */
621 return 0;
622}
623
624static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
625{
626 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
627 int i, ofs, voices;
628
629 voices = kcontrol->private_value >> 8;
630 ofs = kcontrol->private_value & 0xff;
631 for (i = 0; i < voices; i++)
632 ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
633 return 0;
634}
635
636static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
637{
638 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
639 int i, idx, ofs, voices;
640 int change = 0;
641
642 voices = kcontrol->private_value >> 8;
643 ofs = kcontrol->private_value & 0xff;
644 snd_ice1712_save_gpio_status(ice);
645 for (i = 0; i < voices; i++) {
646 idx = WM_DAC_ATTEN + ofs + i;
647 if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) {
648 ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE;
649 ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i];
650 wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
651 ice->spec.aureon.master[i]);
652 change = 1;
653 }
654 }
655 snd_ice1712_restore_gpio_status(ice);
656 return change;
657}
658
659/*
660 * WM8770 mute control
661 */
662static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
663 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
664 uinfo->count = kcontrol->private_value >> 8;
665 uinfo->value.integer.min = 0;
666 uinfo->value.integer.max = 1;
667 return 0;
668}
669
670static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
671{
672 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
673 int voices, ofs, i;
674
675 voices = kcontrol->private_value >> 8;
676 ofs = kcontrol->private_value & 0xFF;
677
678 for (i = 0; i < voices; i++)
679 ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
680 return 0;
681}
682
683static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
684{
685 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
686 int change = 0, voices, ofs, i;
687
688 voices = kcontrol->private_value >> 8;
689 ofs = kcontrol->private_value & 0xFF;
690
691 snd_ice1712_save_gpio_status(ice);
692 for (i = 0; i < voices; i++) {
693 int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
694 if (ucontrol->value.integer.value[i] != val) {
695 ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
696 ice->spec.aureon.vol[ofs + i] |=
697 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
698 wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
699 ice->spec.aureon.master[i]);
700 change = 1;
701 }
702 }
703 snd_ice1712_restore_gpio_status(ice);
704
705 return change;
706}
707
708/*
709 * WM8770 master mute control
710 */
711static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
712 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
713 uinfo->count = 2;
714 uinfo->value.integer.min = 0;
715 uinfo->value.integer.max = 1;
716 return 0;
717}
718
719static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
720{
721 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
722
723 ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
724 ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
725 return 0;
726}
727
728static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
729{
730 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
731 int change = 0, i;
732
733 snd_ice1712_save_gpio_status(ice);
734 for (i = 0; i < 2; i++) {
735 int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
736 if (ucontrol->value.integer.value[i] != val) {
737 int dac;
738 ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
739 ice->spec.aureon.master[i] |=
740 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
741 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
742 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
743 ice->spec.aureon.vol[dac + i],
744 ice->spec.aureon.master[i]);
745 change = 1;
746 }
747 }
748 snd_ice1712_restore_gpio_status(ice);
749
750 return change;
751}
752
753/* digital master volume */
754#define PCM_0dB 0xff
755#define PCM_RES 128 /* -64dB */
756#define PCM_MIN (PCM_0dB - PCM_RES)
757static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
758{
759 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
760 uinfo->count = 1;
761 uinfo->value.integer.min = 0; /* mute (-64dB) */
762 uinfo->value.integer.max = PCM_RES; /* 0dB */
763 return 0;
764}
765
766static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
767{
768 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
769 unsigned short val;
770
771 down(&ice->gpio_mutex);
772 val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
773 val = val > PCM_MIN ? (val - PCM_MIN) : 0;
774 ucontrol->value.integer.value[0] = val;
775 up(&ice->gpio_mutex);
776 return 0;
777}
778
779static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
780{
781 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
782 unsigned short ovol, nvol;
783 int change = 0;
784
785 snd_ice1712_save_gpio_status(ice);
786 nvol = ucontrol->value.integer.value[0];
787 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
788 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
789 if (ovol != nvol) {
790 wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
791 wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
792 change = 1;
793 }
794 snd_ice1712_restore_gpio_status(ice);
795 return change;
796}
797
798/*
799 * ADC mute control
800 */
801static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
802{
803 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
804 uinfo->count = 2;
805 uinfo->value.integer.min = 0;
806 uinfo->value.integer.max = 1;
807 return 0;
808}
809
810static int wm_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
811{
812 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
813 unsigned short val;
814 int i;
815
816 down(&ice->gpio_mutex);
817 for (i = 0; i < 2; i++) {
818 val = wm_get(ice, WM_ADC_GAIN + i);
819 ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
820 }
821 up(&ice->gpio_mutex);
822 return 0;
823}
824
825static int wm_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
826{
827 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
828 unsigned short new, old;
829 int i, change = 0;
830
831 snd_ice1712_save_gpio_status(ice);
832 for (i = 0; i < 2; i++) {
833 old = wm_get(ice, WM_ADC_GAIN + i);
834 new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
835 if (new != old) {
836 wm_put(ice, WM_ADC_GAIN + i, new);
837 change = 1;
838 }
839 }
840 snd_ice1712_restore_gpio_status(ice);
841
842 return change;
843}
844
845/*
846 * ADC gain mixer control
847 */
848static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
849{
850 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
851 uinfo->count = 2;
852 uinfo->value.integer.min = 0; /* -12dB */
853 uinfo->value.integer.max = 0x1f; /* 19dB */
854 return 0;
855}
856
857static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
858{
859 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
860 int i, idx;
861 unsigned short vol;
862
863 down(&ice->gpio_mutex);
864 for (i = 0; i < 2; i++) {
865 idx = WM_ADC_GAIN + i;
866 vol = wm_get(ice, idx) & 0x1f;
867 ucontrol->value.integer.value[i] = vol;
868 }
869 up(&ice->gpio_mutex);
870 return 0;
871}
872
873static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
874{
875 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
876 int i, idx;
877 unsigned short ovol, nvol;
878 int change = 0;
879
880 snd_ice1712_save_gpio_status(ice);
881 for (i = 0; i < 2; i++) {
882 idx = WM_ADC_GAIN + i;
883 nvol = ucontrol->value.integer.value[i];
884 ovol = wm_get(ice, idx);
885 if ((ovol & 0x1f) != nvol) {
886 wm_put(ice, idx, nvol | (ovol & ~0x1f));
887 change = 1;
888 }
889 }
890 snd_ice1712_restore_gpio_status(ice);
891 return change;
892}
893
894/*
895 * ADC input mux mixer control
896 */
897static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
898{
899 static char *texts[] = {
900 "CD", //AIN1
901 "Aux", //AIN2
902 "Line", //AIN3
903 "Mic", //AIN4
904 "AC97" //AIN5
905 };
906 static char *universe_texts[] = {
907 "Aux1", //AIN1
908 "CD", //AIN2
909 "Phono", //AIN3
910 "Line", //AIN4
911 "Aux2", //AIN5
912 "Mic", //AIN6
913 "Aux3", //AIN7
914 "AC97" //AIN8
915 };
916 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
917
918 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
919 uinfo->count = 2;
920 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
921 uinfo->value.enumerated.items = 8;
922 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
923 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
924 strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]);
925 }
926 else {
927 uinfo->value.enumerated.items = 5;
928 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
929 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
930 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
931 }
932 return 0;
933}
934
935static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
936{
937 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
938 unsigned short val;
939
940 down(&ice->gpio_mutex);
941 val = wm_get(ice, WM_ADC_MUX);
942 ucontrol->value.integer.value[0] = val & 7;
943 ucontrol->value.integer.value[1] = (val >> 4) & 7;
944 up(&ice->gpio_mutex);
945 return 0;
946}
947
948static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
949{
950 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
951 unsigned short oval, nval;
952 int change;
953
954 snd_ice1712_save_gpio_status(ice);
955 oval = wm_get(ice, WM_ADC_MUX);
956 nval = oval & ~0x77;
957 nval |= ucontrol->value.integer.value[0] & 7;
958 nval |= (ucontrol->value.integer.value[1] & 7) << 4;
959 change = (oval != nval);
960 if (change)
961 wm_put(ice, WM_ADC_MUX, nval);
962 snd_ice1712_restore_gpio_status(ice);
963 return 0;
964}
965
966/*
967 * CS8415 Input mux
968 */
969static int aureon_cs8415_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
970{
971 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
972 static char *aureon_texts[] = {
973 "CD", //RXP0
974 "Optical" //RXP1
975 };
976 static char *prodigy_texts[] = {
977 "CD",
978 "Coax"
979 };
980 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
981 uinfo->count = 1;
982 uinfo->value.enumerated.items = 2;
983 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
984 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
985 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
986 strcpy(uinfo->value.enumerated.name, prodigy_texts[uinfo->value.enumerated.item]);
987 else
988 strcpy(uinfo->value.enumerated.name, aureon_texts[uinfo->value.enumerated.item]);
989 return 0;
990}
991
992static int aureon_cs8415_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
993{
994 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
995
996 //snd_ice1712_save_gpio_status(ice);
997 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
998 ucontrol->value.integer.value[0] = ice->spec.aureon.cs8415_mux;
999 //snd_ice1712_restore_gpio_status(ice);
1000 return 0;
1001}
1002
1003static int aureon_cs8415_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1004{
1005 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1006 unsigned short oval, nval;
1007 int change;
1008
1009 snd_ice1712_save_gpio_status(ice);
1010 oval = aureon_cs8415_get(ice, CS8415_CTRL2);
1011 nval = oval & ~0x07;
1012 nval |= ucontrol->value.integer.value[0] & 7;
1013 change = (oval != nval);
1014 if (change)
1015 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1016 snd_ice1712_restore_gpio_status(ice);
1017 ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0];
1018 return change;
1019}
1020
1021static int aureon_cs8415_rate_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1022{
1023 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1024 uinfo->count = 1;
1025 uinfo->value.integer.min = 0;
1026 uinfo->value.integer.max = 192000;
1027 return 0;
1028}
1029
1030static int aureon_cs8415_rate_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1031{
1032 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1033 unsigned char ratio;
1034 ratio = aureon_cs8415_get(ice, CS8415_RATIO);
1035 ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
1036 return 0;
1037}
1038
1039/*
1040 * CS8415A Mute
1041 */
1042static int aureon_cs8415_mute_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1043{
1044 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1045 uinfo->count = 1;
1046 return 0;
1047}
1048
1049static int aureon_cs8415_mute_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1050{
1051 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1052 snd_ice1712_save_gpio_status(ice);
1053 ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
1054 snd_ice1712_restore_gpio_status(ice);
1055 return 0;
1056}
1057
1058static int aureon_cs8415_mute_put (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1059{
1060 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1061 unsigned char oval, nval;
1062 int change;
1063 snd_ice1712_save_gpio_status(ice);
1064 oval = aureon_cs8415_get(ice, CS8415_CTRL1);
1065 if (ucontrol->value.integer.value[0])
1066 nval = oval & ~0x20;
1067 else
1068 nval = oval | 0x20;
1069 if ((change = (oval != nval)))
1070 aureon_cs8415_put(ice, CS8415_CTRL1, nval);
1071 snd_ice1712_restore_gpio_status(ice);
1072 return change;
1073}
1074
1075/*
1076 * CS8415A Q-Sub info
1077 */
1078static int aureon_cs8415_qsub_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
1079 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1080 uinfo->count = 10;
1081 return 0;
1082}
1083
1084static int aureon_cs8415_qsub_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
1085 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1086
1087 snd_ice1712_save_gpio_status(ice);
1088 aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
1089 snd_ice1712_restore_gpio_status(ice);
1090
1091 return 0;
1092}
1093
1094static int aureon_cs8415_spdif_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
1095 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1096 uinfo->count = 1;
1097 return 0;
1098}
1099
1100static int aureon_cs8415_mask_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
1101 memset(ucontrol->value.iec958.status, 0xFF, 24);
1102 return 0;
1103}
1104
1105static int aureon_cs8415_spdif_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
1106 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1107
1108 snd_ice1712_save_gpio_status(ice);
1109 aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
1110 snd_ice1712_restore_gpio_status(ice);
1111 return 0;
1112}
1113
1114/*
1115 * Headphone Amplifier
1116 */
1117static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
1118{
1119 unsigned int tmp, tmp2;
1120
1121 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1122 if (enable)
1123 tmp |= AUREON_HP_SEL;
1124 else
1125 tmp &= ~ AUREON_HP_SEL;
1126 if (tmp != tmp2) {
1127 snd_ice1712_gpio_write(ice, tmp);
1128 return 1;
1129 }
1130 return 0;
1131}
1132
1133static int aureon_get_headphone_amp(ice1712_t *ice)
1134{
1135 unsigned int tmp = snd_ice1712_gpio_read(ice);
1136
1137 return ( tmp & AUREON_HP_SEL )!= 0;
1138}
1139
1140#define aureon_hpamp_info aureon_mono_bool_info
1141
1142static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1143{
1144 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1145
1146 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
1147 return 0;
1148}
1149
1150
1151static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1152{
1153 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1154
1155 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
1156}
1157
1158/*
1159 * Deemphasis
1160 */
1161
1162#define aureon_deemp_info aureon_mono_bool_info
1163
1164static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1165{
1166 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1167 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
1168 return 0;
1169}
1170
1171static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1172{
1173 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1174 int temp, temp2;
1175 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
1176 if (ucontrol->value.integer.value[0])
1177 temp |= 0xf;
1178 else
1179 temp &= ~0xf;
1180 if (temp != temp2) {
1181 wm_put(ice, WM_DAC_CTRL2, temp);
1182 return 1;
1183 }
1184 return 0;
1185}
1186
1187/*
1188 * ADC Oversampling
1189 */
1190static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
1191{
1192 static char *texts[2] = { "128x", "64x" };
1193
1194 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1195 uinfo->count = 1;
1196 uinfo->value.enumerated.items = 2;
1197
1198 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1199 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1200 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1201
1202 return 0;
1203}
1204
1205static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1206{
1207 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1208 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
1209 return 0;
1210}
1211
1212static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1213{
1214 int temp, temp2;
1215 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1216
1217 temp2 = temp = wm_get(ice, WM_MASTER);
1218
1219 if (ucontrol->value.enumerated.item[0])
1220 temp |= 0x8;
1221 else
1222 temp &= ~0x8;
1223
1224 if (temp != temp2) {
1225 wm_put(ice, WM_MASTER, temp);
1226 return 1;
1227 }
1228 return 0;
1229}
1230
1231/*
1232 * mixers
1233 */
1234
1235static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
1236 {
1237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1238 .name = "Master Playback Switch",
1239 .info = wm_master_mute_info,
1240 .get = wm_master_mute_get,
1241 .put = wm_master_mute_put
1242 },
1243 {
1244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1245 .name = "Master Playback Volume",
1246 .info = wm_master_vol_info,
1247 .get = wm_master_vol_get,
1248 .put = wm_master_vol_put
1249 },
1250 {
1251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1252 .name = "Front Playback Switch",
1253 .info = wm_mute_info,
1254 .get = wm_mute_get,
1255 .put = wm_mute_put,
1256 .private_value = (2 << 8) | 0
1257 },
1258 {
1259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1260 .name = "Front Playback Volume",
1261 .info = wm_vol_info,
1262 .get = wm_vol_get,
1263 .put = wm_vol_put,
1264 .private_value = (2 << 8) | 0
1265 },
1266 {
1267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1268 .name = "Rear Playback Switch",
1269 .info = wm_mute_info,
1270 .get = wm_mute_get,
1271 .put = wm_mute_put,
1272 .private_value = (2 << 8) | 2
1273 },
1274 {
1275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1276 .name = "Rear Playback Volume",
1277 .info = wm_vol_info,
1278 .get = wm_vol_get,
1279 .put = wm_vol_put,
1280 .private_value = (2 << 8) | 2
1281 },
1282 {
1283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1284 .name = "Center Playback Switch",
1285 .info = wm_mute_info,
1286 .get = wm_mute_get,
1287 .put = wm_mute_put,
1288 .private_value = (1 << 8) | 4
1289 },
1290 {
1291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1292 .name = "Center Playback Volume",
1293 .info = wm_vol_info,
1294 .get = wm_vol_get,
1295 .put = wm_vol_put,
1296 .private_value = (1 << 8) | 4
1297 },
1298 {
1299 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1300 .name = "LFE Playback Switch",
1301 .info = wm_mute_info,
1302 .get = wm_mute_get,
1303 .put = wm_mute_put,
1304 .private_value = (1 << 8) | 5
1305 },
1306 {
1307 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1308 .name = "LFE Playback Volume",
1309 .info = wm_vol_info,
1310 .get = wm_vol_get,
1311 .put = wm_vol_put,
1312 .private_value = (1 << 8) | 5
1313 },
1314 {
1315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1316 .name = "Side Playback Switch",
1317 .info = wm_mute_info,
1318 .get = wm_mute_get,
1319 .put = wm_mute_put,
1320 .private_value = (2 << 8) | 6
1321 },
1322 {
1323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1324 .name = "Side Playback Volume",
1325 .info = wm_vol_info,
1326 .get = wm_vol_get,
1327 .put = wm_vol_put,
1328 .private_value = (2 << 8) | 6
1329 }
1330};
1331
1332static snd_kcontrol_new_t wm_controls[] __devinitdata = {
1333 {
1334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1335 .name = "PCM Playback Switch",
1336 .info = wm_pcm_mute_info,
1337 .get = wm_pcm_mute_get,
1338 .put = wm_pcm_mute_put
1339 },
1340 {
1341 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1342 .name = "PCM Playback Volume",
1343 .info = wm_pcm_vol_info,
1344 .get = wm_pcm_vol_get,
1345 .put = wm_pcm_vol_put
1346 },
1347 {
1348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1349 .name = "Capture Switch",
1350 .info = wm_adc_mute_info,
1351 .get = wm_adc_mute_get,
1352 .put = wm_adc_mute_put,
1353 },
1354 {
1355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1356 .name = "Capture Volume",
1357 .info = wm_adc_vol_info,
1358 .get = wm_adc_vol_get,
1359 .put = wm_adc_vol_put
1360 },
1361 {
1362 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1363 .name = "Capture Source",
1364 .info = wm_adc_mux_info,
1365 .get = wm_adc_mux_get,
1366 .put = wm_adc_mux_put,
1367 .private_value = 5
1368 },
1369 {
1370 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1371 .name = "External Amplifier",
1372 .info = aureon_hpamp_info,
1373 .get = aureon_hpamp_get,
1374 .put = aureon_hpamp_put
1375 },
1376 {
1377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1378 .name = "DAC Deemphasis Switch",
1379 .info = aureon_deemp_info,
1380 .get = aureon_deemp_get,
1381 .put = aureon_deemp_put
1382 },
1383 {
1384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1385 .name = "ADC Oversampling",
1386 .info = aureon_oversampling_info,
1387 .get = aureon_oversampling_get,
1388 .put = aureon_oversampling_put
1389 }
1390};
1391
1392static snd_kcontrol_new_t ac97_controls[] __devinitdata = {
1393 {
1394 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1395 .name = "AC97 Playback Switch",
1396 .info = aureon_ac97_mmute_info,
1397 .get = aureon_ac97_mmute_get,
1398 .put = aureon_ac97_mmute_put,
1399 .private_value = AC97_MASTER
1400 },
1401 {
1402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1403 .name = "AC97 Playback Volume",
1404 .info = aureon_ac97_vol_info,
1405 .get = aureon_ac97_vol_get,
1406 .put = aureon_ac97_vol_put,
1407 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1408 },
1409 {
1410 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1411 .name = "CD Playback Switch",
1412 .info = aureon_ac97_mute_info,
1413 .get = aureon_ac97_mute_get,
1414 .put = aureon_ac97_mute_put,
1415 .private_value = AC97_CD
1416 },
1417 {
1418 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1419 .name = "CD Playback Volume",
1420 .info = aureon_ac97_vol_info,
1421 .get = aureon_ac97_vol_get,
1422 .put = aureon_ac97_vol_put,
1423 .private_value = AC97_CD|AUREON_AC97_STEREO
1424 },
1425 {
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = "Aux Playback Switch",
1428 .info = aureon_ac97_mute_info,
1429 .get = aureon_ac97_mute_get,
1430 .put = aureon_ac97_mute_put,
1431 .private_value = AC97_AUX,
1432 },
1433 {
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "Aux Playback Volume",
1436 .info = aureon_ac97_vol_info,
1437 .get = aureon_ac97_vol_get,
1438 .put = aureon_ac97_vol_put,
1439 .private_value = AC97_AUX|AUREON_AC97_STEREO
1440 },
1441 {
1442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1443 .name = "Line Playback Switch",
1444 .info = aureon_ac97_mute_info,
1445 .get = aureon_ac97_mute_get,
1446 .put = aureon_ac97_mute_put,
1447 .private_value = AC97_LINE
1448 },
1449 {
1450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1451 .name = "Line Playback Volume",
1452 .info = aureon_ac97_vol_info,
1453 .get = aureon_ac97_vol_get,
1454 .put = aureon_ac97_vol_put,
1455 .private_value = AC97_LINE|AUREON_AC97_STEREO
1456 },
1457 {
1458 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1459 .name = "Mic Playback Switch",
1460 .info = aureon_ac97_mute_info,
1461 .get = aureon_ac97_mute_get,
1462 .put = aureon_ac97_mute_put,
1463 .private_value = AC97_MIC
1464 },
1465 {
1466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1467 .name = "Mic Playback Volume",
1468 .info = aureon_ac97_vol_info,
1469 .get = aureon_ac97_vol_get,
1470 .put = aureon_ac97_vol_put,
1471 .private_value = AC97_MIC
1472 },
1473 {
1474 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1475 .name = "Mic Boost (+20dB)",
1476 .info = aureon_ac97_micboost_info,
1477 .get = aureon_ac97_micboost_get,
1478 .put = aureon_ac97_micboost_put
1479 }
1480};
1481
1482static snd_kcontrol_new_t universe_ac97_controls[] __devinitdata = {
1483 {
1484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1485 .name = "AC97 Playback Switch",
1486 .info = aureon_ac97_mmute_info,
1487 .get = aureon_ac97_mmute_get,
1488 .put = aureon_ac97_mmute_put,
1489 .private_value = AC97_MASTER
1490 },
1491 {
1492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1493 .name = "AC97 Playback Volume",
1494 .info = aureon_ac97_vol_info,
1495 .get = aureon_ac97_vol_get,
1496 .put = aureon_ac97_vol_put,
1497 .private_value = AC97_MASTER|AUREON_AC97_STEREO
1498 },
1499 {
1500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1501 .name = "CD Playback Switch",
1502 .info = aureon_ac97_mute_info,
1503 .get = aureon_ac97_mute_get,
1504 .put = aureon_ac97_mute_put,
1505 .private_value = AC97_AUX
1506 },
1507 {
1508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 .name = "CD Playback Volume",
1510 .info = aureon_ac97_vol_info,
1511 .get = aureon_ac97_vol_get,
1512 .put = aureon_ac97_vol_put,
1513 .private_value = AC97_AUX|AUREON_AC97_STEREO
1514 },
1515 {
1516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1517 .name = "Phono Playback Switch",
1518 .info = aureon_ac97_mute_info,
1519 .get = aureon_ac97_mute_get,
1520 .put = aureon_ac97_mute_put,
1521 .private_value = AC97_CD,
1522 },
1523 {
1524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525 .name = "Phono Playback Volume",
1526 .info = aureon_ac97_vol_info,
1527 .get = aureon_ac97_vol_get,
1528 .put = aureon_ac97_vol_put,
1529 .private_value = AC97_CD|AUREON_AC97_STEREO
1530 },
1531 {
1532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1533 .name = "Line Playback Switch",
1534 .info = aureon_ac97_mute_info,
1535 .get = aureon_ac97_mute_get,
1536 .put = aureon_ac97_mute_put,
1537 .private_value = AC97_LINE
1538 },
1539 {
1540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1541 .name = "Line Playback Volume",
1542 .info = aureon_ac97_vol_info,
1543 .get = aureon_ac97_vol_get,
1544 .put = aureon_ac97_vol_put,
1545 .private_value = AC97_LINE|AUREON_AC97_STEREO
1546 },
1547 {
1548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1549 .name = "Mic Playback Switch",
1550 .info = aureon_ac97_mute_info,
1551 .get = aureon_ac97_mute_get,
1552 .put = aureon_ac97_mute_put,
1553 .private_value = AC97_MIC
1554 },
1555 {
1556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1557 .name = "Mic Playback Volume",
1558 .info = aureon_ac97_vol_info,
1559 .get = aureon_ac97_vol_get,
1560 .put = aureon_ac97_vol_put,
1561 .private_value = AC97_MIC
1562 },
1563 {
1564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1565 .name = "Mic Boost (+20dB)",
1566 .info = aureon_ac97_micboost_info,
1567 .get = aureon_ac97_micboost_get,
1568 .put = aureon_ac97_micboost_put
1569 },
1570 {
1571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1572 .name = "Aux Playback Switch",
1573 .info = aureon_ac97_mute_info,
1574 .get = aureon_ac97_mute_get,
1575 .put = aureon_ac97_mute_put,
1576 .private_value = AC97_VIDEO,
1577 },
1578 {
1579 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1580 .name = "Aux Playback Volume",
1581 .info = aureon_ac97_vol_info,
1582 .get = aureon_ac97_vol_get,
1583 .put = aureon_ac97_vol_put,
1584 .private_value = AC97_VIDEO|AUREON_AC97_STEREO
1585 }
1586};
1587
1588
1589static snd_kcontrol_new_t cs8415_controls[] __devinitdata = {
1590 {
1591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1592 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
1593 .info = aureon_cs8415_mute_info,
1594 .get = aureon_cs8415_mute_get,
1595 .put = aureon_cs8415_mute_put
1596 },
1597 {
1598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1599 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source",
1600 .info = aureon_cs8415_mux_info,
1601 .get = aureon_cs8415_mux_get,
1602 .put = aureon_cs8415_mux_put,
1603 },
1604 {
1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1606 .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT),
1607 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1608 .info = aureon_cs8415_qsub_info,
1609 .get = aureon_cs8415_qsub_get,
1610 },
1611 {
1612 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1613 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
1614 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1615 .info = aureon_cs8415_spdif_info,
1616 .get = aureon_cs8415_mask_get
1617 },
1618 {
1619 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1620 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
1621 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1622 .info = aureon_cs8415_spdif_info,
1623 .get = aureon_cs8415_spdif_get
1624 },
1625 {
1626 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1627 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate",
1628 .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1629 .info = aureon_cs8415_rate_info,
1630 .get = aureon_cs8415_rate_get
1631 }
1632};
1633
1634
1635static int __devinit aureon_add_controls(ice1712_t *ice)
1636{
1637 unsigned int i, counts;
1638 int err;
1639
1640 counts = ARRAY_SIZE(aureon_dac_controls);
1641 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
1642 counts -= 2; /* no side */
1643 for (i = 0; i < counts; i++) {
1644 err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
1645 if (err < 0)
1646 return err;
1647 }
1648
1649 for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
1650 err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
1651 if (err < 0)
1652 return err;
1653 }
1654
1655 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) {
1656 for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) {
1657 err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice));
1658 if (err < 0)
1659 return err;
1660 }
1661 }
1662 else {
1663 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1664 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1665 if (err < 0)
1666 return err;
1667 }
1668 }
1669
1670 {
1671 unsigned char id;
1672 snd_ice1712_save_gpio_status(ice);
1673 id = aureon_cs8415_get(ice, CS8415_ID);
1674 if (id != 0x41)
1675 snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
1676 else if ((id & 0x0F) != 0x01)
1677 snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
1678 else {
1679 for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
1680 snd_kcontrol_t *kctl;
1681 err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
1682 if (err < 0)
1683 return err;
1684 if (i > 1)
1685 kctl->id.device = ice->pcm->device;
1686 }
1687 }
1688 snd_ice1712_restore_gpio_status(ice);
1689 }
1690
1691 return 0;
1692}
1693
1694
1695/*
1696 * initialize the chip
1697 */
1698static int __devinit aureon_init(ice1712_t *ice)
1699{
1700 static unsigned short wm_inits_aureon[] = {
1701 /* These come first to reduce init pop noise */
1702 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1703 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
1704 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
1705
1706 0x18, 0x000, /* All power-up */
1707
1708 0x16, 0x122, /* I2S, normal polarity, 24bit */
1709 0x17, 0x022, /* 256fs, slave mode */
1710 0x00, 0, /* DAC1 analog mute */
1711 0x01, 0, /* DAC2 analog mute */
1712 0x02, 0, /* DAC3 analog mute */
1713 0x03, 0, /* DAC4 analog mute */
1714 0x04, 0, /* DAC5 analog mute */
1715 0x05, 0, /* DAC6 analog mute */
1716 0x06, 0, /* DAC7 analog mute */
1717 0x07, 0, /* DAC8 analog mute */
1718 0x08, 0x100, /* master analog mute */
1719 0x09, 0xff, /* DAC1 digital full */
1720 0x0a, 0xff, /* DAC2 digital full */
1721 0x0b, 0xff, /* DAC3 digital full */
1722 0x0c, 0xff, /* DAC4 digital full */
1723 0x0d, 0xff, /* DAC5 digital full */
1724 0x0e, 0xff, /* DAC6 digital full */
1725 0x0f, 0xff, /* DAC7 digital full */
1726 0x10, 0xff, /* DAC8 digital full */
1727 0x11, 0x1ff, /* master digital full */
1728 0x12, 0x000, /* phase normal */
1729 0x13, 0x090, /* unmute DAC L/R */
1730 0x14, 0x000, /* all unmute */
1731 0x15, 0x000, /* no deemphasis, no ZFLG */
1732 0x19, 0x000, /* -12dB ADC/L */
1733 0x1a, 0x000, /* -12dB ADC/R */
1734 (unsigned short)-1
1735 };
1736 static unsigned short wm_inits_prodigy[] = {
1737
1738 /* These come first to reduce init pop noise */
1739 0x1b, 0x000, /* ADC Mux */
1740 0x1c, 0x009, /* Out Mux1 */
1741 0x1d, 0x009, /* Out Mux2 */
1742
1743 0x18, 0x000, /* All power-up */
1744
1745 0x16, 0x022, /* I2S, normal polarity, 24bit, high-pass on */
1746 0x17, 0x006, /* 128fs, slave mode */
1747
1748 0x00, 0, /* DAC1 analog mute */
1749 0x01, 0, /* DAC2 analog mute */
1750 0x02, 0, /* DAC3 analog mute */
1751 0x03, 0, /* DAC4 analog mute */
1752 0x04, 0, /* DAC5 analog mute */
1753 0x05, 0, /* DAC6 analog mute */
1754 0x06, 0, /* DAC7 analog mute */
1755 0x07, 0, /* DAC8 analog mute */
1756 0x08, 0x100, /* master analog mute */
1757
1758 0x09, 0x7f, /* DAC1 digital full */
1759 0x0a, 0x7f, /* DAC2 digital full */
1760 0x0b, 0x7f, /* DAC3 digital full */
1761 0x0c, 0x7f, /* DAC4 digital full */
1762 0x0d, 0x7f, /* DAC5 digital full */
1763 0x0e, 0x7f, /* DAC6 digital full */
1764 0x0f, 0x7f, /* DAC7 digital full */
1765 0x10, 0x7f, /* DAC8 digital full */
1766 0x11, 0x1FF, /* master digital full */
1767
1768 0x12, 0x000, /* phase normal */
1769 0x13, 0x090, /* unmute DAC L/R */
1770 0x14, 0x000, /* all unmute */
1771 0x15, 0x000, /* no deemphasis, no ZFLG */
1772
1773 0x19, 0x000, /* -12dB ADC/L */
1774 0x1a, 0x000, /* -12dB ADC/R */
1775 (unsigned short)-1
1776
1777 };
1778 static unsigned short cs_inits[] = {
1779 0x0441, /* RUN */
1780 0x0180, /* no mute, OMCK output on RMCK pin */
1781 0x0201, /* S/PDIF source on RXP1 */
1782 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
1783 (unsigned short)-1
1784 };
1785 unsigned int tmp;
1786 unsigned short *p;
1787 int err, i;
1788
1789 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
1790 ice->num_total_dacs = 6;
1791 ice->num_total_adcs = 2;
1792 } else {
1793 /* aureon 7.1 and prodigy 7.1 */
1794 ice->num_total_dacs = 8;
1795 ice->num_total_adcs = 2;
1796 }
1797
1798 /* to remeber the register values of CS8415 */
1799 ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
1800 if (! ice->akm)
1801 return -ENOMEM;
1802 ice->akm_codecs = 1;
1803
1804 if ((err = aureon_ac97_init(ice)) != 0)
1805 return err;
1806
1807 snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
1808
1809 /* reset the wm codec as the SPI mode */
1810 snd_ice1712_save_gpio_status(ice);
1811 snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RESET|AUREON_WM_CS|AUREON_CS8415_CS|AUREON_HP_SEL));
1812
1813 tmp = snd_ice1712_gpio_read(ice);
1814 tmp &= ~AUREON_WM_RESET;
1815 snd_ice1712_gpio_write(ice, tmp);
1816 udelay(1);
1817 tmp |= AUREON_WM_CS | AUREON_CS8415_CS;
1818 snd_ice1712_gpio_write(ice, tmp);
1819 udelay(1);
1820 tmp |= AUREON_WM_RESET;
1821 snd_ice1712_gpio_write(ice, tmp);
1822 udelay(1);
1823
1824 /* initialize WM8770 codec */
1825 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71)
1826 p = wm_inits_prodigy;
1827 else
1828 p = wm_inits_aureon;
1829 for (; *p != (unsigned short)-1; p += 2)
1830 wm_put(ice, p[0], p[1]);
1831
1832 /* initialize CS8415A codec */
1833 for (p = cs_inits; *p != (unsigned short)-1; p++)
1834 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
1835 ice->spec.aureon.cs8415_mux = 1;
1836
1837 aureon_set_headphone_amp(ice, 1);
1838
1839 snd_ice1712_restore_gpio_status(ice);
1840
1841 ice->spec.aureon.master[0] = WM_VOL_MUTE;
1842 ice->spec.aureon.master[1] = WM_VOL_MUTE;
1843 for (i = 0; i < ice->num_total_dacs; i++) {
1844 ice->spec.aureon.vol[i] = WM_VOL_MUTE;
1845 wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
1846 }
1847
1848 return 0;
1849}
1850
1851
1852/*
1853 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
1854 * hence the driver needs to sets up it properly.
1855 */
1856
1857static unsigned char aureon51_eeprom[] __devinitdata = {
1858 0x0a, /* SYSCONF: clock 512, spdif-in/ADC, 3DACs */
1859 0x80, /* ACLINK: I2S */
1860 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1861 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1862 0xff, /* GPIO_DIR */
1863 0xff, /* GPIO_DIR1 */
1864 0x5f, /* GPIO_DIR2 */
1865 0x00, /* GPIO_MASK */
1866 0x00, /* GPIO_MASK1 */
1867 0x00, /* GPIO_MASK2 */
1868 0x00, /* GPIO_STATE */
1869 0x00, /* GPIO_STATE1 */
1870 0x00, /* GPIO_STATE2 */
1871};
1872
1873static unsigned char aureon71_eeprom[] __devinitdata = {
1874 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1875 0x80, /* ACLINK: I2S */
1876 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1877 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1878 0xff, /* GPIO_DIR */
1879 0xff, /* GPIO_DIR1 */
1880 0x5f, /* GPIO_DIR2 */
1881 0x00, /* GPIO_MASK */
1882 0x00, /* GPIO_MASK1 */
1883 0x00, /* GPIO_MASK2 */
1884 0x00, /* GPIO_STATE */
1885 0x00, /* GPIO_STATE1 */
1886 0x00, /* GPIO_STATE2 */
1887};
1888
1889static unsigned char prodigy71_eeprom[] __devinitdata = {
1890 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1891 0x80, /* ACLINK: I2S */
1892 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1893 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1894 0xff, /* GPIO_DIR */
1895 0xff, /* GPIO_DIR1 */
1896 0x5f, /* GPIO_DIR2 */
1897 0x00, /* GPIO_MASK */
1898 0x00, /* GPIO_MASK1 */
1899 0x00, /* GPIO_MASK2 */
1900 0x00, /* GPIO_STATE */
1901 0x00, /* GPIO_STATE1 */
1902 0x00, /* GPIO_STATE2 */
1903};
1904
1905/* entry point */
1906struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
1907 {
1908 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
1909 .name = "Terratec Aureon 5.1-Sky",
1910 .model = "aureon51",
1911 .chip_init = aureon_init,
1912 .build_controls = aureon_add_controls,
1913 .eeprom_size = sizeof(aureon51_eeprom),
1914 .eeprom_data = aureon51_eeprom,
1915 .driver = "Aureon51",
1916 },
1917 {
1918 .subvendor = VT1724_SUBDEVICE_AUREON71_SPACE,
1919 .name = "Terratec Aureon 7.1-Space",
1920 .model = "aureon71",
1921 .chip_init = aureon_init,
1922 .build_controls = aureon_add_controls,
1923 .eeprom_size = sizeof(aureon71_eeprom),
1924 .eeprom_data = aureon71_eeprom,
1925 .driver = "Aureon71",
1926 },
1927 {
1928 .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE,
1929 .name = "Terratec Aureon 7.1-Universe",
1930 .model = "universe",
1931 .chip_init = aureon_init,
1932 .build_controls = aureon_add_controls,
1933 .eeprom_size = sizeof(aureon71_eeprom),
1934 .eeprom_data = aureon71_eeprom,
1935 .driver = "Aureon71Universe",
1936 },
1937 {
1938 .subvendor = VT1724_SUBDEVICE_PRODIGY71,
1939 .name = "Audiotrak Prodigy 7.1",
1940 .model = "prodigy71",
1941 .chip_init = aureon_init,
1942 .build_controls = aureon_add_controls,
1943 .eeprom_size = sizeof(prodigy71_eeprom),
1944 .eeprom_data = prodigy71_eeprom,
1945 .driver = "Prodigy71", /* should be identical with Aureon71 */
1946 },
1947 { } /* terminator */
1948};
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
new file mode 100644
index 000000000000..95d515f36f23
--- /dev/null
+++ b/sound/pci/ice1712/aureon.h
@@ -0,0 +1,56 @@
1#ifndef __SOUND_AUREON_H
2#define __SOUND_AUREON_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Terratec Aureon cards
8 *
9 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
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
27#define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\
28 "{Terratec,Aureon 7.1 Space},"\
29 "{Terratec,Aureon 7.1 Universe}," \
30 "{AudioTrak,Prodigy 7.1},"
31
32#define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */
33#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */
34#define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */
35#define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */
36
37extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
38
39/* GPIO bits */
40#define AUREON_CS8415_CS (1 << 22)
41#define AUREON_SPI_MISO (1 << 21)
42#define AUREON_WM_RESET (1 << 20)
43#define AUREON_SPI_CLK (1 << 19)
44#define AUREON_SPI_MOSI (1 << 18)
45#define AUREON_WM_RW (1 << 17)
46#define AUREON_AC97_RESET (1 << 16)
47#define AUREON_DIGITAL_SEL1 (1 << 15)
48#define AUREON_HP_SEL (1 << 14)
49#define AUREON_WM_CS (1 << 12)
50#define AUREON_AC97_COMMIT (1 << 11)
51#define AUREON_AC97_ADDR (1 << 10)
52#define AUREON_AC97_DATA_LOW (1 << 9)
53#define AUREON_AC97_DATA_HIGH (1 << 8)
54#define AUREON_AC97_DATA_MASK 0xFF
55
56#endif /* __SOUND_AUREON_H */
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
new file mode 100644
index 000000000000..eb20f73be61a
--- /dev/null
+++ b/sound/pci/ice1712/delta.c
@@ -0,0 +1,771 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
5 * Digigram VX442
6 *
7 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <asm/io.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/cs8427.h>
33#include <sound/asoundef.h>
34
35#include "ice1712.h"
36#include "delta.h"
37
38#define SND_CS8403
39#include <sound/cs8403.h>
40
41
42/*
43 * CS8427 via SPI mode (for Audiophile), emulated I2C
44 */
45
46/* send 8 bits */
47static void ap_cs8427_write_byte(ice1712_t *ice, unsigned char data, unsigned char tmp)
48{
49 int idx;
50
51 for (idx = 7; idx >= 0; idx--) {
52 tmp &= ~(ICE1712_DELTA_AP_DOUT|ICE1712_DELTA_AP_CCLK);
53 if (data & (1 << idx))
54 tmp |= ICE1712_DELTA_AP_DOUT;
55 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
56 udelay(5);
57 tmp |= ICE1712_DELTA_AP_CCLK;
58 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
59 udelay(5);
60 }
61}
62
63/* read 8 bits */
64static unsigned char ap_cs8427_read_byte(ice1712_t *ice, unsigned char tmp)
65{
66 unsigned char data = 0;
67 int idx;
68
69 for (idx = 7; idx >= 0; idx--) {
70 tmp &= ~ICE1712_DELTA_AP_CCLK;
71 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
72 udelay(5);
73 if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN)
74 data |= 1 << idx;
75 tmp |= ICE1712_DELTA_AP_CCLK;
76 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
77 udelay(5);
78 }
79 return data;
80}
81
82/* assert chip select */
83static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
84{
85 unsigned char tmp;
86 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
87 switch (ice->eeprom.subvendor) {
88 case ICE1712_SUBDEVICE_DELTA1010LT:
89 tmp &= ~ICE1712_DELTA_1010LT_CS;
90 tmp |= ICE1712_DELTA_1010LT_CCLK | ICE1712_DELTA_1010LT_CS_CS8427;
91 break;
92 case ICE1712_SUBDEVICE_AUDIOPHILE:
93 case ICE1712_SUBDEVICE_DELTA410:
94 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
95 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
96 break;
97 case ICE1712_SUBDEVICE_VX442:
98 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
99 tmp &= ~ICE1712_VX442_CS_DIGITAL;
100 break;
101 }
102 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
103 udelay(5);
104 return tmp;
105}
106
107/* deassert chip select */
108static void ap_cs8427_codec_deassert(ice1712_t *ice, unsigned char tmp)
109{
110 switch (ice->eeprom.subvendor) {
111 case ICE1712_SUBDEVICE_DELTA1010LT:
112 tmp &= ~ICE1712_DELTA_1010LT_CS;
113 tmp |= ICE1712_DELTA_1010LT_CS_NONE;
114 break;
115 case ICE1712_SUBDEVICE_AUDIOPHILE:
116 case ICE1712_SUBDEVICE_DELTA410:
117 tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
118 break;
119 case ICE1712_SUBDEVICE_VX442:
120 tmp |= ICE1712_VX442_CS_DIGITAL;
121 break;
122 }
123 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
124}
125
126/* sequential write */
127static int ap_cs8427_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
128{
129 ice1712_t *ice = device->bus->private_data;
130 int res = count;
131 unsigned char tmp;
132
133 down(&ice->gpio_mutex);
134 tmp = ap_cs8427_codec_select(ice);
135 ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */
136 while (count-- > 0)
137 ap_cs8427_write_byte(ice, *bytes++, tmp);
138 ap_cs8427_codec_deassert(ice, tmp);
139 up(&ice->gpio_mutex);
140 return res;
141}
142
143/* sequential read */
144static int ap_cs8427_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
145{
146 ice1712_t *ice = device->bus->private_data;
147 int res = count;
148 unsigned char tmp;
149
150 down(&ice->gpio_mutex);
151 tmp = ap_cs8427_codec_select(ice);
152 ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */
153 while (count-- > 0)
154 *bytes++ = ap_cs8427_read_byte(ice, tmp);
155 ap_cs8427_codec_deassert(ice, tmp);
156 up(&ice->gpio_mutex);
157 return res;
158}
159
160static int ap_cs8427_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
161{
162 if (addr == 0x10)
163 return 1;
164 return -ENOENT;
165}
166
167static snd_i2c_ops_t ap_cs8427_i2c_ops = {
168 .sendbytes = ap_cs8427_sendbytes,
169 .readbytes = ap_cs8427_readbytes,
170 .probeaddr = ap_cs8427_probeaddr,
171};
172
173/*
174 */
175
176static void snd_ice1712_delta_cs8403_spdif_write(ice1712_t *ice, unsigned char bits)
177{
178 unsigned char tmp, mask1, mask2;
179 int idx;
180 /* send byte to transmitter */
181 mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
182 mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
183 down(&ice->gpio_mutex);
184 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
185 for (idx = 7; idx >= 0; idx--) {
186 tmp &= ~(mask1 | mask2);
187 if (bits & (1 << idx))
188 tmp |= mask2;
189 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
190 udelay(100);
191 tmp |= mask1;
192 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
193 udelay(100);
194 }
195 tmp &= ~mask1;
196 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
197 up(&ice->gpio_mutex);
198}
199
200
201static void delta_spdif_default_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
202{
203 snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
204}
205
206static int delta_spdif_default_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
207{
208 unsigned int val;
209 int change;
210
211 val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
212 spin_lock_irq(&ice->reg_lock);
213 change = ice->spdif.cs8403_bits != val;
214 ice->spdif.cs8403_bits = val;
215 if (change && ice->playback_pro_substream == NULL) {
216 spin_unlock_irq(&ice->reg_lock);
217 snd_ice1712_delta_cs8403_spdif_write(ice, val);
218 } else {
219 spin_unlock_irq(&ice->reg_lock);
220 }
221 return change;
222}
223
224static void delta_spdif_stream_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
225{
226 snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
227}
228
229static int delta_spdif_stream_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
230{
231 unsigned int val;
232 int change;
233
234 val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
235 spin_lock_irq(&ice->reg_lock);
236 change = ice->spdif.cs8403_stream_bits != val;
237 ice->spdif.cs8403_stream_bits = val;
238 if (change && ice->playback_pro_substream != NULL) {
239 spin_unlock_irq(&ice->reg_lock);
240 snd_ice1712_delta_cs8403_spdif_write(ice, val);
241 } else {
242 spin_unlock_irq(&ice->reg_lock);
243 }
244 return change;
245}
246
247
248/*
249 * AK4524 on Delta 44 and 66 to choose the chip mask
250 */
251static void delta_ak4524_lock(akm4xxx_t *ak, int chip)
252{
253 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
254 ice1712_t *ice = ak->private_data[0];
255
256 snd_ice1712_save_gpio_status(ice);
257 priv->cs_mask =
258 priv->cs_addr = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A :
259 ICE1712_DELTA_CODEC_CHIP_B;
260}
261
262/*
263 * AK4524 on Delta1010LT to choose the chip address
264 */
265static void delta1010lt_ak4524_lock(akm4xxx_t *ak, int chip)
266{
267 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
268 ice1712_t *ice = ak->private_data[0];
269
270 snd_ice1712_save_gpio_status(ice);
271 priv->cs_mask = ICE1712_DELTA_1010LT_CS;
272 priv->cs_addr = chip << 4;
273}
274
275/*
276 * AK4528 on VX442 to choose the chip mask
277 */
278static void vx442_ak4524_lock(akm4xxx_t *ak, int chip)
279{
280 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
281 ice1712_t *ice = ak->private_data[0];
282
283 snd_ice1712_save_gpio_status(ice);
284 priv->cs_mask =
285 priv->cs_addr = chip == 0 ? ICE1712_VX442_CODEC_CHIP_A :
286 ICE1712_VX442_CODEC_CHIP_B;
287}
288
289/*
290 * change the DFS bit according rate for Delta1010
291 */
292static void delta_1010_set_rate_val(ice1712_t *ice, unsigned int rate)
293{
294 unsigned char tmp, tmp2;
295
296 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
297 return;
298
299 down(&ice->gpio_mutex);
300 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
301 tmp2 = tmp & ~ICE1712_DELTA_DFS;
302 if (rate > 48000)
303 tmp2 |= ICE1712_DELTA_DFS;
304 if (tmp != tmp2)
305 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2);
306 up(&ice->gpio_mutex);
307}
308
309/*
310 * change the rate of AK4524 on Delta 44/66, AP, 1010LT
311 */
312static void delta_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
313{
314 unsigned char tmp, tmp2;
315 ice1712_t *ice = ak->private_data[0];
316
317 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
318 return;
319
320 /* check before reset ak4524 to avoid unnecessary clicks */
321 down(&ice->gpio_mutex);
322 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
323 up(&ice->gpio_mutex);
324 tmp2 = tmp & ~ICE1712_DELTA_DFS;
325 if (rate > 48000)
326 tmp2 |= ICE1712_DELTA_DFS;
327 if (tmp == tmp2)
328 return;
329
330 /* do it again */
331 snd_akm4xxx_reset(ak, 1);
332 down(&ice->gpio_mutex);
333 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS;
334 if (rate > 48000)
335 tmp |= ICE1712_DELTA_DFS;
336 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
337 up(&ice->gpio_mutex);
338 snd_akm4xxx_reset(ak, 0);
339}
340
341/*
342 * change the rate of AK4524 on VX442
343 */
344static void vx442_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
345{
346 unsigned char val;
347
348 val = (rate > 48000) ? 0x65 : 0x60;
349 if (snd_akm4xxx_get(ak, 0, 0x02) != val ||
350 snd_akm4xxx_get(ak, 1, 0x02) != val) {
351 snd_akm4xxx_reset(ak, 1);
352 snd_akm4xxx_write(ak, 0, 0x02, val);
353 snd_akm4xxx_write(ak, 1, 0x02, val);
354 snd_akm4xxx_reset(ak, 0);
355 }
356}
357
358
359/*
360 * SPDIF ops for Delta 1010, Dio, 66
361 */
362
363/* open callback */
364static void delta_open_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
365{
366 ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
367}
368
369/* set up */
370static void delta_setup_spdif(ice1712_t *ice, int rate)
371{
372 unsigned long flags;
373 unsigned int tmp;
374 int change;
375
376 spin_lock_irqsave(&ice->reg_lock, flags);
377 tmp = ice->spdif.cs8403_stream_bits;
378 if (tmp & 0x01) /* consumer */
379 tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
380 switch (rate) {
381 case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
382 case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
383 case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
384 default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
385 }
386 change = ice->spdif.cs8403_stream_bits != tmp;
387 ice->spdif.cs8403_stream_bits = tmp;
388 spin_unlock_irqrestore(&ice->reg_lock, flags);
389 if (change)
390 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
391 snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
392}
393
394
395/*
396 * initialize the chips on M-Audio cards
397 */
398
399static akm4xxx_t akm_audiophile __devinitdata = {
400 .type = SND_AK4528,
401 .num_adcs = 2,
402 .num_dacs = 2,
403 .ops = {
404 .set_rate_val = delta_ak4524_set_rate_val
405 }
406};
407
408static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
409 .caddr = 2,
410 .cif = 0,
411 .data_mask = ICE1712_DELTA_AP_DOUT,
412 .clk_mask = ICE1712_DELTA_AP_CCLK,
413 .cs_mask = ICE1712_DELTA_AP_CS_CODEC,
414 .cs_addr = ICE1712_DELTA_AP_CS_CODEC,
415 .cs_none = 0,
416 .add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
417 .mask_flags = 0,
418};
419
420static akm4xxx_t akm_delta410 __devinitdata = {
421 .type = SND_AK4529,
422 .num_adcs = 2,
423 .num_dacs = 8,
424 .ops = {
425 .set_rate_val = delta_ak4524_set_rate_val
426 }
427};
428
429static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
430 .caddr = 0,
431 .cif = 0,
432 .data_mask = ICE1712_DELTA_AP_DOUT,
433 .clk_mask = ICE1712_DELTA_AP_CCLK,
434 .cs_mask = ICE1712_DELTA_AP_CS_CODEC,
435 .cs_addr = ICE1712_DELTA_AP_CS_CODEC,
436 .cs_none = 0,
437 .add_flags = ICE1712_DELTA_AP_CS_DIGITAL,
438 .mask_flags = 0,
439};
440
441static akm4xxx_t akm_delta1010lt __devinitdata = {
442 .type = SND_AK4524,
443 .num_adcs = 8,
444 .num_dacs = 8,
445 .ops = {
446 .lock = delta1010lt_ak4524_lock,
447 .set_rate_val = delta_ak4524_set_rate_val
448 }
449};
450
451static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
452 .caddr = 2,
453 .cif = 0, /* the default level of the CIF pin from AK4524 */
454 .data_mask = ICE1712_DELTA_1010LT_DOUT,
455 .clk_mask = ICE1712_DELTA_1010LT_CCLK,
456 .cs_mask = 0,
457 .cs_addr = 0, /* set later */
458 .cs_none = ICE1712_DELTA_1010LT_CS_NONE,
459 .add_flags = 0,
460 .mask_flags = 0,
461};
462
463static akm4xxx_t akm_delta44 __devinitdata = {
464 .type = SND_AK4524,
465 .num_adcs = 4,
466 .num_dacs = 4,
467 .ops = {
468 .lock = delta_ak4524_lock,
469 .set_rate_val = delta_ak4524_set_rate_val
470 }
471};
472
473static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
474 .caddr = 2,
475 .cif = 0, /* the default level of the CIF pin from AK4524 */
476 .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
477 .clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK,
478 .cs_mask = 0,
479 .cs_addr = 0, /* set later */
480 .cs_none = 0,
481 .add_flags = 0,
482 .mask_flags = 0,
483};
484
485static akm4xxx_t akm_vx442 __devinitdata = {
486 .type = SND_AK4524,
487 .num_adcs = 4,
488 .num_dacs = 4,
489 .ops = {
490 .lock = vx442_ak4524_lock,
491 .set_rate_val = vx442_ak4524_set_rate_val
492 }
493};
494
495static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
496 .caddr = 2,
497 .cif = 0,
498 .data_mask = ICE1712_VX442_DOUT,
499 .clk_mask = ICE1712_VX442_CCLK,
500 .cs_mask = 0,
501 .cs_addr = 0, /* set later */
502 .cs_none = 0,
503 .add_flags = 0,
504 .mask_flags = 0,
505};
506
507static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
508{
509 int err;
510 akm4xxx_t *ak;
511
512 /* determine I2C, DACs and ADCs */
513 switch (ice->eeprom.subvendor) {
514 case ICE1712_SUBDEVICE_AUDIOPHILE:
515 ice->num_total_dacs = 2;
516 ice->num_total_adcs = 2;
517 break;
518 case ICE1712_SUBDEVICE_DELTA410:
519 ice->num_total_dacs = 8;
520 ice->num_total_adcs = 2;
521 break;
522 case ICE1712_SUBDEVICE_DELTA44:
523 case ICE1712_SUBDEVICE_DELTA66:
524 ice->num_total_dacs = ice->omni ? 8 : 4;
525 ice->num_total_adcs = ice->omni ? 8 : 4;
526 break;
527 case ICE1712_SUBDEVICE_DELTA1010:
528 case ICE1712_SUBDEVICE_DELTA1010LT:
529 case ICE1712_SUBDEVICE_MEDIASTATION:
530 ice->num_total_dacs = 8;
531 ice->num_total_adcs = 8;
532 break;
533 case ICE1712_SUBDEVICE_DELTADIO2496:
534 ice->num_total_dacs = 4; /* two AK4324 codecs */
535 break;
536 case ICE1712_SUBDEVICE_VX442:
537 ice->num_total_dacs = 4;
538 ice->num_total_adcs = 4;
539 break;
540 }
541
542 /* initialize spdif */
543 switch (ice->eeprom.subvendor) {
544 case ICE1712_SUBDEVICE_AUDIOPHILE:
545 case ICE1712_SUBDEVICE_DELTA410:
546 case ICE1712_SUBDEVICE_DELTA1010LT:
547 case ICE1712_SUBDEVICE_VX442:
548 if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
549 snd_printk("unable to create I2C bus\n");
550 return err;
551 }
552 ice->i2c->private_data = ice;
553 ice->i2c->ops = &ap_cs8427_i2c_ops;
554 if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
555 return err;
556 break;
557 case ICE1712_SUBDEVICE_DELTA1010:
558 case ICE1712_SUBDEVICE_MEDIASTATION:
559 ice->gpio.set_pro_rate = delta_1010_set_rate_val;
560 break;
561 case ICE1712_SUBDEVICE_DELTADIO2496:
562 ice->gpio.set_pro_rate = delta_1010_set_rate_val;
563 /* fall thru */
564 case ICE1712_SUBDEVICE_DELTA66:
565 ice->spdif.ops.open = delta_open_spdif;
566 ice->spdif.ops.setup_rate = delta_setup_spdif;
567 ice->spdif.ops.default_get = delta_spdif_default_get;
568 ice->spdif.ops.default_put = delta_spdif_default_put;
569 ice->spdif.ops.stream_get = delta_spdif_stream_get;
570 ice->spdif.ops.stream_put = delta_spdif_stream_put;
571 /* Set spdif defaults */
572 snd_ice1712_delta_cs8403_spdif_write(ice, ice->spdif.cs8403_bits);
573 break;
574 }
575
576 /* no analog? */
577 switch (ice->eeprom.subvendor) {
578 case ICE1712_SUBDEVICE_DELTA1010:
579 case ICE1712_SUBDEVICE_DELTADIO2496:
580 case ICE1712_SUBDEVICE_MEDIASTATION:
581 return 0;
582 }
583
584 /* second stage of initialization, analog parts and others */
585 ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
586 if (! ak)
587 return -ENOMEM;
588 ice->akm_codecs = 1;
589
590 switch (ice->eeprom.subvendor) {
591 case ICE1712_SUBDEVICE_AUDIOPHILE:
592 err = snd_ice1712_akm4xxx_init(ak, &akm_audiophile, &akm_audiophile_priv, ice);
593 break;
594 case ICE1712_SUBDEVICE_DELTA410:
595 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
596 break;
597 case ICE1712_SUBDEVICE_DELTA1010LT:
598 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
599 break;
600 case ICE1712_SUBDEVICE_DELTA66:
601 case ICE1712_SUBDEVICE_DELTA44:
602 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
603 break;
604 case ICE1712_SUBDEVICE_VX442:
605 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
606 break;
607 default:
608 snd_BUG();
609 return -EINVAL;
610 }
611
612 return err;
613}
614
615
616/*
617 * additional controls for M-Audio cards
618 */
619
620static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata =
621ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
622static snd_kcontrol_new_t snd_ice1712_delta1010lt_wordclock_select __devinitdata =
623ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0);
624static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata =
625ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
626static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
627ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
628static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata =
629ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
630
631
632static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
633{
634 int err;
635
636 /* 1010 and dio specific controls */
637 switch (ice->eeprom.subvendor) {
638 case ICE1712_SUBDEVICE_DELTA1010:
639 case ICE1712_SUBDEVICE_MEDIASTATION:
640 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice));
641 if (err < 0)
642 return err;
643 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_status, ice));
644 if (err < 0)
645 return err;
646 break;
647 case ICE1712_SUBDEVICE_DELTADIO2496:
648 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_deltadio2496_spdif_in_select, ice));
649 if (err < 0)
650 return err;
651 break;
652 case ICE1712_SUBDEVICE_DELTA1010LT:
653 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice));
654 if (err < 0)
655 return err;
656 break;
657 }
658
659 /* normal spdif controls */
660 switch (ice->eeprom.subvendor) {
661 case ICE1712_SUBDEVICE_DELTA1010:
662 case ICE1712_SUBDEVICE_DELTADIO2496:
663 case ICE1712_SUBDEVICE_DELTA66:
664 case ICE1712_SUBDEVICE_MEDIASTATION:
665 err = snd_ice1712_spdif_build_controls(ice);
666 if (err < 0)
667 return err;
668 break;
669 }
670
671 /* spdif status in */
672 switch (ice->eeprom.subvendor) {
673 case ICE1712_SUBDEVICE_DELTA1010:
674 case ICE1712_SUBDEVICE_DELTADIO2496:
675 case ICE1712_SUBDEVICE_DELTA66:
676 case ICE1712_SUBDEVICE_MEDIASTATION:
677 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice));
678 if (err < 0)
679 return err;
680 break;
681 }
682
683 /* ak4524 controls */
684 switch (ice->eeprom.subvendor) {
685 case ICE1712_SUBDEVICE_DELTA1010LT:
686 case ICE1712_SUBDEVICE_AUDIOPHILE:
687 case ICE1712_SUBDEVICE_DELTA410:
688 case ICE1712_SUBDEVICE_DELTA44:
689 case ICE1712_SUBDEVICE_DELTA66:
690 case ICE1712_SUBDEVICE_VX442:
691 err = snd_ice1712_akm4xxx_build_controls(ice);
692 if (err < 0)
693 return err;
694 break;
695 }
696
697 return 0;
698}
699
700
701/* entry point */
702struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
703 {
704 .subvendor = ICE1712_SUBDEVICE_DELTA1010,
705 .name = "M Audio Delta 1010",
706 .model = "delta1010",
707 .chip_init = snd_ice1712_delta_init,
708 .build_controls = snd_ice1712_delta_add_controls,
709 },
710 {
711 .subvendor = ICE1712_SUBDEVICE_DELTADIO2496,
712 .name = "M Audio Delta DiO 2496",
713 .model = "dio2496",
714 .chip_init = snd_ice1712_delta_init,
715 .build_controls = snd_ice1712_delta_add_controls,
716 .no_mpu401 = 1,
717 },
718 {
719 .subvendor = ICE1712_SUBDEVICE_DELTA66,
720 .name = "M Audio Delta 66",
721 .model = "delta66",
722 .chip_init = snd_ice1712_delta_init,
723 .build_controls = snd_ice1712_delta_add_controls,
724 .no_mpu401 = 1,
725 },
726 {
727 .subvendor = ICE1712_SUBDEVICE_DELTA44,
728 .name = "M Audio Delta 44",
729 .model = "delta44",
730 .chip_init = snd_ice1712_delta_init,
731 .build_controls = snd_ice1712_delta_add_controls,
732 .no_mpu401 = 1,
733 },
734 {
735 .subvendor = ICE1712_SUBDEVICE_AUDIOPHILE,
736 .name = "M Audio Audiophile 24/96",
737 .model = "audiophile",
738 .chip_init = snd_ice1712_delta_init,
739 .build_controls = snd_ice1712_delta_add_controls,
740 },
741 {
742 .subvendor = ICE1712_SUBDEVICE_DELTA410,
743 .name = "M Audio Delta 410",
744 .model = "delta410",
745 .chip_init = snd_ice1712_delta_init,
746 .build_controls = snd_ice1712_delta_add_controls,
747 },
748 {
749 .subvendor = ICE1712_SUBDEVICE_DELTA1010LT,
750 .name = "M Audio Delta 1010LT",
751 .model = "delta1010lt",
752 .chip_init = snd_ice1712_delta_init,
753 .build_controls = snd_ice1712_delta_add_controls,
754 },
755 {
756 .subvendor = ICE1712_SUBDEVICE_VX442,
757 .name = "Digigram VX442",
758 .model = "vx442",
759 .chip_init = snd_ice1712_delta_init,
760 .build_controls = snd_ice1712_delta_add_controls,
761 .no_mpu401 = 1,
762 },
763 {
764 .subvendor = ICE1712_SUBDEVICE_MEDIASTATION,
765 .name = "Lionstracs Mediastation",
766 .model = "mediastation",
767 .chip_init = snd_ice1712_delta_init,
768 .build_controls = snd_ice1712_delta_add_controls,
769 },
770 { } /* terminator */
771};
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
new file mode 100644
index 000000000000..746ebde94522
--- /dev/null
+++ b/sound/pci/ice1712/delta.h
@@ -0,0 +1,150 @@
1#ifndef __SOUND_DELTA_H
2#define __SOUND_DELTA_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
8 * Digigram VX442
9 *
10 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#define DELTA_DEVICE_DESC \
29 "{MidiMan M Audio,Delta 1010},"\
30 "{MidiMan M Audio,Delta 1010LT},"\
31 "{MidiMan M Audio,Delta DiO 2496},"\
32 "{MidiMan M Audio,Delta 66},"\
33 "{MidiMan M Audio,Delta 44},"\
34 "{MidiMan M Audio,Audiophile 24/96},"\
35 "{Digigram,VX442},"\
36 "{Lionstracs,Mediastation},"
37
38#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6
39#define ICE1712_SUBDEVICE_DELTADIO2496 0x121431d6
40#define ICE1712_SUBDEVICE_DELTA66 0x121432d6
41#define ICE1712_SUBDEVICE_DELTA44 0x121433d6
42#define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6
43#define ICE1712_SUBDEVICE_DELTA410 0x121438d6
44#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
45#define ICE1712_SUBDEVICE_VX442 0x12143cd6
46#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
47
48/* entry point */
49extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
50
51
52/*
53 * MidiMan M-Audio Delta GPIO definitions
54 */
55
56/* MidiMan M-Audio Delta shared pins */
57#define ICE1712_DELTA_DFS 0x01 /* fast/slow sample rate mode */
58 /* (>48kHz must be 1) */
59#define ICE1712_DELTA_SPDIF_IN_STAT 0x02
60 /* S/PDIF input status */
61 /* 0 = valid signal is present */
62 /* all except Delta44 */
63 /* look to CS8414 datasheet */
64#define ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK 0x04
65 /* S/PDIF output status clock */
66 /* (writting on rising edge - 0->1) */
67 /* all except Delta44 */
68 /* look to CS8404A datasheet */
69#define ICE1712_DELTA_SPDIF_OUT_STAT_DATA 0x08
70 /* S/PDIF output status data */
71 /* all except Delta44 */
72 /* look to CS8404A datasheet */
73/* MidiMan M-Audio DeltaDiO */
74/* 0x01 = DFS */
75/* 0x02 = SPDIF_IN_STAT */
76/* 0x04 = SPDIF_OUT_STAT_CLOCK */
77/* 0x08 = SPDIF_OUT_STAT_DATA */
78#define ICE1712_DELTA_SPDIF_INPUT_SELECT 0x10
79 /* coaxial (0), optical (1) */
80 /* S/PDIF input select*/
81
82/* MidiMan M-Audio Delta1010 */
83/* 0x01 = DFS */
84/* 0x02 = SPDIF_IN_STAT */
85/* 0x04 = SPDIF_OUT_STAT_CLOCK */
86/* 0x08 = SPDIF_OUT_STAT_DATA */
87#define ICE1712_DELTA_WORD_CLOCK_SELECT 0x10
88 /* 1 - clock are taken from S/PDIF input */
89 /* 0 - clock are taken from Word Clock input */
90 /* affected SPMCLKIN pin of Envy24 */
91#define ICE1712_DELTA_WORD_CLOCK_STATUS 0x20
92 /* 0 = valid word clock signal is present */
93
94/* MidiMan M-Audio Delta66 */
95/* 0x01 = DFS */
96/* 0x02 = SPDIF_IN_STAT */
97/* 0x04 = SPDIF_OUT_STAT_CLOCK */
98/* 0x08 = SPDIF_OUT_STAT_DATA */
99#define ICE1712_DELTA_CODEC_SERIAL_DATA 0x10
100 /* AKM4524 serial data */
101#define ICE1712_DELTA_CODEC_SERIAL_CLOCK 0x20
102 /* AKM4524 serial clock */
103 /* (writting on rising edge - 0->1 */
104#define ICE1712_DELTA_CODEC_CHIP_A 0x40
105#define ICE1712_DELTA_CODEC_CHIP_B 0x80
106 /* 1 - select chip A or B */
107
108/* MidiMan M-Audio Delta44 */
109/* 0x01 = DFS */
110/* 0x10 = CODEC_SERIAL_DATA */
111/* 0x20 = CODEC_SERIAL_CLOCK */
112/* 0x40 = CODEC_CHIP_A */
113/* 0x80 = CODEC_CHIP_B */
114
115/* MidiMan M-Audio Audiophile/Delta410 definitions */
116/* thanks to Kristof Pelckmans <Kristof.Pelckmans@antwerpen.be> for Delta410 info */
117/* 0x01 = DFS */
118#define ICE1712_DELTA_AP_CCLK 0x02 /* SPI clock */
119 /* (clocking on rising edge - 0->1) */
120#define ICE1712_DELTA_AP_DIN 0x04 /* data input */
121#define ICE1712_DELTA_AP_DOUT 0x08 /* data output */
122#define ICE1712_DELTA_AP_CS_DIGITAL 0x10 /* CS8427 chip select */
123 /* low signal = select */
124#define ICE1712_DELTA_AP_CS_CODEC 0x20 /* AK4528 (audiophile), AK4529 (Delta410) chip select */
125 /* low signal = select */
126
127/* MidiMan M-Audio Delta1010LT definitions */
128/* thanks to Anders Johansson <ajh@watri.uwa.edu.au> */
129/* 0x01 = DFS */
130#define ICE1712_DELTA_1010LT_CCLK 0x02 /* SPI clock (AK4524 + CS8427) */
131#define ICE1712_DELTA_1010LT_DIN 0x04 /* data input (CS8427) */
132#define ICE1712_DELTA_1010LT_DOUT 0x08 /* data output (AK4524 + CS8427) */
133#define ICE1712_DELTA_1010LT_CS 0x70 /* mask for CS address */
134#define ICE1712_DELTA_1010LT_CS_CHIP_A 0x00 /* AK4524 #0 */
135#define ICE1712_DELTA_1010LT_CS_CHIP_B 0x10 /* AK4524 #1 */
136#define ICE1712_DELTA_1010LT_CS_CHIP_C 0x20 /* AK4524 #2 */
137#define ICE1712_DELTA_1010LT_CS_CHIP_D 0x30 /* AK4524 #3 */
138#define ICE1712_DELTA_1010LT_CS_CS8427 0x40 /* CS8427 */
139#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
140#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
141
142/* Digigram VX442 definitions */
143#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
144#define ICE1712_VX442_DIN 0x04 /* data input */
145#define ICE1712_VX442_DOUT 0x08 /* data output */
146#define ICE1712_VX442_CS_DIGITAL 0x10 /* chip select, low = CS8427 */
147#define ICE1712_VX442_CODEC_CHIP_A 0x20 /* select chip A */
148#define ICE1712_VX442_CODEC_CHIP_B 0x40 /* select chip B */
149
150#endif /* __SOUND_DELTA_H */
diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
new file mode 100644
index 000000000000..f7878020eaa3
--- /dev/null
+++ b/sound/pci/ice1712/envy24ht.h
@@ -0,0 +1,215 @@
1#ifndef __SOUND_VT1724_H
2#define __SOUND_VT1724_H
3
4/*
5 * ALSA driver for ICEnsemble VT1724 (Envy24)
6 *
7 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/control.h>
26#include <sound/ac97_codec.h>
27#include <sound/rawmidi.h>
28#include <sound/i2c.h>
29#include <sound/pcm.h>
30
31#include "ice1712.h"
32
33enum {
34 ICE_EEP2_SYSCONF = 0, /* 06 */
35 ICE_EEP2_ACLINK, /* 07 */
36 ICE_EEP2_I2S, /* 08 */
37 ICE_EEP2_SPDIF, /* 09 */
38 ICE_EEP2_GPIO_DIR, /* 0a */
39 ICE_EEP2_GPIO_DIR1, /* 0b */
40 ICE_EEP2_GPIO_DIR2, /* 0c */
41 ICE_EEP2_GPIO_MASK, /* 0d */
42 ICE_EEP2_GPIO_MASK1, /* 0e */
43 ICE_EEP2_GPIO_MASK2, /* 0f */
44 ICE_EEP2_GPIO_STATE, /* 10 */
45 ICE_EEP2_GPIO_STATE1, /* 11 */
46 ICE_EEP2_GPIO_STATE2 /* 12 */
47};
48
49/*
50 * Direct registers
51 */
52
53#define ICEREG1724(ice, x) ((ice)->port + VT1724_REG_##x)
54
55#define VT1724_REG_CONTROL 0x00 /* byte */
56#define VT1724_RESET 0x80 /* reset whole chip */
57#define VT1724_REG_IRQMASK 0x01 /* byte */
58#define VT1724_IRQ_MPU_RX 0x80
59#define VT1724_IRQ_MPU_TX 0x20
60#define VT1724_IRQ_MTPCM 0x10
61#define VT1724_REG_IRQSTAT 0x02 /* byte */
62/* look to VT1724_IRQ_* */
63#define VT1724_REG_SYS_CFG 0x04 /* byte - system configuration PCI60 on Envy24*/
64#define VT1724_CFG_CLOCK 0xc0
65#define VT1724_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */
66#define VT1724_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
67#define VT1724_CFG_MPU401 0x20 /* MPU401 UARTs */
68#define VT1724_CFG_ADC_MASK 0x0c /* one, two or one and S/PDIF, stereo ADCs */
69#define VT1724_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
70
71#define VT1724_REG_AC97_CFG 0x05 /* byte */
72#define VT1724_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */
73#define VT1724_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */
74
75#define VT1724_REG_I2S_FEATURES 0x06 /* byte */
76#define VT1724_CFG_I2S_VOLUME 0x80 /* volume/mute capability */
77#define VT1724_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */
78#define VT1724_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */
79#define VT1724_CFG_I2S_192KHZ 0x08 /* supports 192kHz sampling */
80#define VT1724_CFG_I2S_OTHER 0x07 /* other I2S IDs */
81
82#define VT1724_REG_SPDIF_CFG 0x07 /* byte */
83#define VT1724_CFG_SPDIF_OUT_EN 0x80 /*Internal S/PDIF output is enabled*/
84#define VT1724_CFG_SPDIF_OUT_INT 0x40 /*Internal S/PDIF output is implemented*/
85#define VT1724_CFG_I2S_CHIPID 0x3c /* I2S chip ID */
86#define VT1724_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */
87#define VT1724_CFG_SPDIF_OUT 0x01 /* External S/PDIF output is present */
88
89/*there is no consumer AC97 codec with the VT1724*/
90//#define VT1724_REG_AC97_INDEX 0x08 /* byte */
91//#define VT1724_REG_AC97_CMD 0x09 /* byte */
92
93#define VT1724_REG_MPU_TXFIFO 0x0a /*byte ro. number of bytes in TX fifo*/
94#define VT1724_REG_MPU_RXFIFO 0x0b /*byte ro. number of bytes in RX fifo*/
95
96//are these 2 the wrong way around? they don't seem to be used yet anyway
97#define VT1724_REG_MPU_CTRL 0x0c /* byte */
98#define VT1724_REG_MPU_DATA 0x0d /* byte */
99
100#define VT1724_REG_MPU_FIFO_WM 0x0e /*byte set the high/low watermarks for RX/TX fifos*/
101#define VT1724_MPU_RX_FIFO 0x20 //1=rx fifo watermark 0=tx fifo watermark
102#define VT1724_MPU_FIFO_MASK 0x1f
103
104#define VT1724_REG_I2C_DEV_ADDR 0x10 /* byte */
105#define VT1724_I2C_WRITE 0x01 /* write direction */
106#define VT1724_REG_I2C_BYTE_ADDR 0x11 /* byte */
107#define VT1724_REG_I2C_DATA 0x12 /* byte */
108#define VT1724_REG_I2C_CTRL 0x13 /* byte */
109#define VT1724_I2C_EEPROM 0x80 /* 1 = EEPROM exists */
110#define VT1724_I2C_BUSY 0x01 /* busy bit */
111
112#define VT1724_REG_GPIO_DATA 0x14 /* word */
113#define VT1724_REG_GPIO_WRITE_MASK 0x16 /* word */
114#define VT1724_REG_GPIO_DIRECTION 0x18 /* dword? (3 bytes) 0=input 1=output.
115 bit3 - during reset used for Eeprom power-on strapping
116 if TESTEN# pin active, bit 2 always input*/
117#define VT1724_REG_POWERDOWN 0x1c
118#define VT1724_REG_GPIO_DATA_22 0x1e /* byte direction for GPIO 16:22 */
119#define VT1724_REG_GPIO_WRITE_MASK_22 0x1f /* byte write mask for GPIO 16:22 */
120
121
122/*
123 * Professional multi-track direct control registers
124 */
125
126#define ICEMT1724(ice, x) ((ice)->profi_port + VT1724_MT_##x)
127
128#define VT1724_MT_IRQ 0x00 /* byte - interrupt mask */
129#define VT1724_MULTI_PDMA4 0x80 /* SPDIF Out / PDMA4 */
130#define VT1724_MULTI_PDMA3 0x40 /* PDMA3 */
131#define VT1724_MULTI_PDMA2 0x20 /* PDMA2 */
132#define VT1724_MULTI_PDMA1 0x10 /* PDMA1 */
133#define VT1724_MULTI_FIFO_ERR 0x08 /* DMA FIFO underrun/overrun. */
134#define VT1724_MULTI_RDMA1 0x04 /* RDMA1 (S/PDIF input) */
135#define VT1724_MULTI_RDMA0 0x02 /* RMDA0 */
136#define VT1724_MULTI_PDMA0 0x01 /* MC Interleave/PDMA0 */
137
138#define VT1724_MT_RATE 0x01 /* byte - sampling rate select */
139#define VT1724_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */
140#define VT1724_MT_I2S_FORMAT 0x02 /* byte - I2S data format */
141#define VT1724_MT_I2S_MCLK_128X 0x08
142#define VT1724_MT_I2S_FORMAT_MASK 0x03
143#define VT1724_MT_I2S_FORMAT_I2S 0x00
144#define VT1724_MT_DMA_INT_MASK 0x03 /* byte -DMA Interrupt Mask */
145/* lool to VT1724_MULTI_* */
146#define VT1724_MT_AC97_INDEX 0x04 /* byte - AC'97 index */
147#define VT1724_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */
148#define VT1724_AC97_COLD 0x80 /* cold reset */
149#define VT1724_AC97_WARM 0x40 /* warm reset */
150#define VT1724_AC97_WRITE 0x20 /* W: write, R: write in progress */
151#define VT1724_AC97_READ 0x10 /* W: read, R: read in progress */
152#define VT1724_AC97_READY 0x08 /* codec ready status bit */
153#define VT1724_AC97_ID_MASK 0x03 /* codec id mask */
154#define VT1724_MT_AC97_DATA 0x06 /* word - AC'97 data */
155#define VT1724_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */
156#define VT1724_MT_PLAYBACK_SIZE 0x14 /* dword - playback size */
157#define VT1724_MT_DMA_CONTROL 0x18 /* byte - control */
158#define VT1724_PDMA4_START 0x80 /* SPDIF out / PDMA4 start */
159#define VT1724_PDMA3_START 0x40 /* PDMA3 start */
160#define VT1724_PDMA2_START 0x20 /* PDMA2 start */
161#define VT1724_PDMA1_START 0x10 /* PDMA1 start */
162#define VT1724_RDMA1_START 0x04 /* RDMA1 start */
163#define VT1724_RDMA0_START 0x02 /* RMDA0 start */
164#define VT1724_PDMA0_START 0x01 /* MC Interleave / PDMA0 start */
165#define VT1724_MT_BURST 0x19 /* Interleaved playback DMA Active streams / PCI burst size */
166#define VT1724_MT_DMA_FIFO_ERR 0x1a /*Global playback and record DMA FIFO Underrun/Overrun */
167#define VT1724_PDMA4_UNDERRUN 0x80
168#define VT1724_PDMA2_UNDERRUN 0x40
169#define VT1724_PDMA3_UNDERRUN 0x20
170#define VT1724_PDMA1_UNDERRUN 0x10
171#define VT1724_RDMA1_UNDERRUN 0x04
172#define VT1724_RDMA0_UNDERRUN 0x02
173#define VT1724_PDMA0_UNDERRUN 0x01
174#define VT1724_MT_DMA_PAUSE 0x1b /*Global playback and record DMA FIFO pause/resume */
175#define VT1724_PDMA4_PAUSE 0x80
176#define VT1724_PDMA3_PAUSE 0x40
177#define VT1724_PDMA2_PAUSE 0x20
178#define VT1724_PDMA1_PAUSE 0x10
179#define VT1724_RDMA1_PAUSE 0x04
180#define VT1724_RDMA0_PAUSE 0x02
181#define VT1724_PDMA0_PAUSE 0x01
182#define VT1724_MT_PLAYBACK_COUNT 0x1c /* word - playback count */
183#define VT1724_MT_CAPTURE_ADDR 0x20 /* dword - capture address */
184#define VT1724_MT_CAPTURE_SIZE 0x24 /* word - capture size */
185#define VT1724_MT_CAPTURE_COUNT 0x26 /* word - capture count */
186
187#define VT1724_MT_ROUTE_PLAYBACK 0x2c /* word */
188
189#define VT1724_MT_RDMA1_ADDR 0x30 /* dword - RDMA1 capture address */
190#define VT1724_MT_RDMA1_SIZE 0x34 /* word - RDMA1 capture size */
191#define VT1724_MT_RDMA1_COUNT 0x36 /* word - RDMA1 capture count */
192
193#define VT1724_MT_SPDIF_CTRL 0x3c /* word */
194#define VT1724_MT_MONITOR_PEAKINDEX 0x3e /* byte */
195#define VT1724_MT_MONITOR_PEAKDATA 0x3f /* byte */
196
197/* concurrent stereo channels */
198#define VT1724_MT_PDMA4_ADDR 0x40 /* dword */
199#define VT1724_MT_PDMA4_SIZE 0x44 /* word */
200#define VT1724_MT_PDMA4_COUNT 0x46 /* word */
201#define VT1724_MT_PDMA3_ADDR 0x50 /* dword */
202#define VT1724_MT_PDMA3_SIZE 0x54 /* word */
203#define VT1724_MT_PDMA3_COUNT 0x56 /* word */
204#define VT1724_MT_PDMA2_ADDR 0x60 /* dword */
205#define VT1724_MT_PDMA2_SIZE 0x64 /* word */
206#define VT1724_MT_PDMA2_COUNT 0x66 /* word */
207#define VT1724_MT_PDMA1_ADDR 0x70 /* dword */
208#define VT1724_MT_PDMA1_SIZE 0x74 /* word */
209#define VT1724_MT_PDMA1_COUNT 0x76 /* word */
210
211
212unsigned char snd_vt1724_read_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr);
213void snd_vt1724_write_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr, unsigned char data);
214
215#endif /* __SOUND_VT1724_H */
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
new file mode 100644
index 000000000000..e36efa1bdac3
--- /dev/null
+++ b/sound/pci/ice1712/ews.c
@@ -0,0 +1,1036 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
7 * 2002 Takashi Iwai <tiwai@suse.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <asm/io.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/cs8427.h>
33#include <sound/asoundef.h>
34
35#include "ice1712.h"
36#include "ews.h"
37
38#define SND_CS8404
39#include <sound/cs8403.h>
40
41enum {
42 EWS_I2C_CS8404 = 0, EWS_I2C_PCF1, EWS_I2C_PCF2,
43 EWS_I2C_88D = 0,
44 EWS_I2C_6FIRE = 0
45};
46
47
48/*
49 * access via i2c mode (for EWX 24/96, EWS 88MT&D)
50 */
51
52/* send SDA and SCL */
53static void ewx_i2c_setlines(snd_i2c_bus_t *bus, int clk, int data)
54{
55 ice1712_t *ice = bus->private_data;
56 unsigned char tmp = 0;
57 if (clk)
58 tmp |= ICE1712_EWX2496_SERIAL_CLOCK;
59 if (data)
60 tmp |= ICE1712_EWX2496_SERIAL_DATA;
61 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
62 udelay(5);
63}
64
65static int ewx_i2c_getclock(snd_i2c_bus_t *bus)
66{
67 ice1712_t *ice = bus->private_data;
68 return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0;
69}
70
71static int ewx_i2c_getdata(snd_i2c_bus_t *bus, int ack)
72{
73 ice1712_t *ice = bus->private_data;
74 int bit;
75 /* set RW pin to low */
76 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW);
77 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, 0);
78 if (ack)
79 udelay(5);
80 bit = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_DATA ? 1 : 0;
81 /* set RW pin to high */
82 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_EWX2496_RW);
83 /* reset write mask */
84 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_SERIAL_CLOCK);
85 return bit;
86}
87
88static void ewx_i2c_start(snd_i2c_bus_t *bus)
89{
90 ice1712_t *ice = bus->private_data;
91 unsigned char mask;
92
93 snd_ice1712_save_gpio_status(ice);
94 /* set RW high */
95 mask = ICE1712_EWX2496_RW;
96 switch (ice->eeprom.subvendor) {
97 case ICE1712_SUBDEVICE_EWX2496:
98 mask |= ICE1712_EWX2496_AK4524_CS; /* CS high also */
99 break;
100 case ICE1712_SUBDEVICE_DMX6FIRE:
101 mask |= ICE1712_6FIRE_AK4524_CS_MASK; /* CS high also */
102 break;
103 }
104 snd_ice1712_gpio_write_bits(ice, mask, mask);
105}
106
107static void ewx_i2c_stop(snd_i2c_bus_t *bus)
108{
109 ice1712_t *ice = bus->private_data;
110 snd_ice1712_restore_gpio_status(ice);
111}
112
113static void ewx_i2c_direction(snd_i2c_bus_t *bus, int clock, int data)
114{
115 ice1712_t *ice = bus->private_data;
116 unsigned char mask = 0;
117
118 if (clock)
119 mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */
120 if (data)
121 mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */
122 ice->gpio.direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
123 ice->gpio.direction |= mask;
124 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio.direction);
125 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
126}
127
128static snd_i2c_bit_ops_t snd_ice1712_ewx_cs8427_bit_ops = {
129 .start = ewx_i2c_start,
130 .stop = ewx_i2c_stop,
131 .direction = ewx_i2c_direction,
132 .setlines = ewx_i2c_setlines,
133 .getclock = ewx_i2c_getclock,
134 .getdata = ewx_i2c_getdata,
135};
136
137
138/*
139 * AK4524 access
140 */
141
142/* AK4524 chip select; address 0x48 bit 0-3 */
143static int snd_ice1712_ews88mt_chip_select(ice1712_t *ice, int chip_mask)
144{
145 unsigned char data, ndata;
146
147 snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
148 snd_i2c_lock(ice->i2c);
149 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
150 goto __error;
151 ndata = (data & 0xf0) | chip_mask;
152 if (ndata != data)
153 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1)
154 goto __error;
155 snd_i2c_unlock(ice->i2c);
156 return 0;
157
158 __error:
159 snd_i2c_unlock(ice->i2c);
160 snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n");
161 return -EIO;
162}
163
164/* start callback for EWS88MT, needs to select a certain chip mask */
165static void ews88mt_ak4524_lock(akm4xxx_t *ak, int chip)
166{
167 ice1712_t *ice = ak->private_data[0];
168 unsigned char tmp;
169 /* assert AK4524 CS */
170 if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
171 snd_printk(KERN_ERR "fatal error (ews88mt chip select)\n");
172 snd_ice1712_save_gpio_status(ice);
173 tmp = ICE1712_EWS88_SERIAL_DATA |
174 ICE1712_EWS88_SERIAL_CLOCK |
175 ICE1712_EWS88_RW;
176 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
177 ice->gpio.direction | tmp);
178 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
179}
180
181/* stop callback for EWS88MT, needs to deselect chip mask */
182static void ews88mt_ak4524_unlock(akm4xxx_t *ak, int chip)
183{
184 ice1712_t *ice = ak->private_data[0];
185 snd_ice1712_restore_gpio_status(ice);
186 udelay(1);
187 snd_ice1712_ews88mt_chip_select(ice, 0x0f);
188}
189
190/* start callback for EWX24/96 */
191static void ewx2496_ak4524_lock(akm4xxx_t *ak, int chip)
192{
193 ice1712_t *ice = ak->private_data[0];
194 unsigned char tmp;
195 snd_ice1712_save_gpio_status(ice);
196 tmp = ICE1712_EWX2496_SERIAL_DATA |
197 ICE1712_EWX2496_SERIAL_CLOCK |
198 ICE1712_EWX2496_AK4524_CS |
199 ICE1712_EWX2496_RW;
200 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
201 ice->gpio.direction | tmp);
202 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
203}
204
205/* start callback for DMX 6fire */
206static void dmx6fire_ak4524_lock(akm4xxx_t *ak, int chip)
207{
208 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
209 ice1712_t *ice = ak->private_data[0];
210 unsigned char tmp;
211 snd_ice1712_save_gpio_status(ice);
212 tmp = priv->cs_mask = priv->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
213 tmp |= ICE1712_6FIRE_SERIAL_DATA |
214 ICE1712_6FIRE_SERIAL_CLOCK |
215 ICE1712_6FIRE_RW;
216 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
217 ice->gpio.direction | tmp);
218 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
219}
220
221/*
222 * CS8404 interface on EWS88MT/D
223 */
224
225static void snd_ice1712_ews_cs8404_spdif_write(ice1712_t *ice, unsigned char bits)
226{
227 unsigned char bytes[2];
228
229 snd_i2c_lock(ice->i2c);
230 switch (ice->eeprom.subvendor) {
231 case ICE1712_SUBDEVICE_EWS88MT:
232 case ICE1712_SUBDEVICE_EWS88MT_NEW:
233 case ICE1712_SUBDEVICE_PHASE88:
234 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_CS8404], &bits, 1) != 1)
235 goto _error;
236 break;
237 case ICE1712_SUBDEVICE_EWS88D:
238 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
239 goto _error;
240 if (bits != bytes[1]) {
241 bytes[1] = bits;
242 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
243 goto _error;
244 }
245 break;
246 }
247 _error:
248 snd_i2c_unlock(ice->i2c);
249}
250
251/*
252 */
253
254static void ews88_spdif_default_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
255{
256 snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
257}
258
259static int ews88_spdif_default_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
260{
261 unsigned int val;
262 int change;
263
264 val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
265 spin_lock_irq(&ice->reg_lock);
266 change = ice->spdif.cs8403_bits != val;
267 ice->spdif.cs8403_bits = val;
268 if (change && ice->playback_pro_substream == NULL) {
269 spin_unlock_irq(&ice->reg_lock);
270 snd_ice1712_ews_cs8404_spdif_write(ice, val);
271 } else {
272 spin_unlock_irq(&ice->reg_lock);
273 }
274 return change;
275}
276
277static void ews88_spdif_stream_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
278{
279 snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
280}
281
282static int ews88_spdif_stream_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
283{
284 unsigned int val;
285 int change;
286
287 val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
288 spin_lock_irq(&ice->reg_lock);
289 change = ice->spdif.cs8403_stream_bits != val;
290 ice->spdif.cs8403_stream_bits = val;
291 if (change && ice->playback_pro_substream != NULL) {
292 spin_unlock_irq(&ice->reg_lock);
293 snd_ice1712_ews_cs8404_spdif_write(ice, val);
294 } else {
295 spin_unlock_irq(&ice->reg_lock);
296 }
297 return change;
298}
299
300
301/* open callback */
302static void ews88_open_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
303{
304 ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
305}
306
307/* set up SPDIF for EWS88MT / EWS88D */
308static void ews88_setup_spdif(ice1712_t *ice, int rate)
309{
310 unsigned long flags;
311 unsigned char tmp;
312 int change;
313
314 spin_lock_irqsave(&ice->reg_lock, flags);
315 tmp = ice->spdif.cs8403_stream_bits;
316 if (tmp & 0x10) /* consumer */
317 tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
318 switch (rate) {
319 case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
320 case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
321 case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
322 default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
323 }
324 change = ice->spdif.cs8403_stream_bits != tmp;
325 ice->spdif.cs8403_stream_bits = tmp;
326 spin_unlock_irqrestore(&ice->reg_lock, flags);
327 if (change)
328 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif.stream_ctl->id);
329 snd_ice1712_ews_cs8404_spdif_write(ice, tmp);
330}
331
332
333/*
334 */
335static akm4xxx_t akm_ews88mt __devinitdata = {
336 .num_adcs = 8,
337 .num_dacs = 8,
338 .type = SND_AK4524,
339 .ops = {
340 .lock = ews88mt_ak4524_lock,
341 .unlock = ews88mt_ak4524_unlock
342 }
343};
344
345static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
346 .caddr = 2,
347 .cif = 1, /* CIF high */
348 .data_mask = ICE1712_EWS88_SERIAL_DATA,
349 .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
350 .cs_mask = 0,
351 .cs_addr = 0,
352 .cs_none = 0, /* no chip select on gpio */
353 .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
354 .mask_flags = 0,
355};
356
357static akm4xxx_t akm_ewx2496 __devinitdata = {
358 .num_adcs = 2,
359 .num_dacs = 2,
360 .type = SND_AK4524,
361 .ops = {
362 .lock = ewx2496_ak4524_lock
363 }
364};
365
366static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
367 .caddr = 2,
368 .cif = 1, /* CIF high */
369 .data_mask = ICE1712_EWS88_SERIAL_DATA,
370 .clk_mask = ICE1712_EWS88_SERIAL_CLOCK,
371 .cs_mask = ICE1712_EWX2496_AK4524_CS,
372 .cs_addr = ICE1712_EWX2496_AK4524_CS,
373 .cs_none = 0,
374 .add_flags = ICE1712_EWS88_RW, /* set rw bit high */
375 .mask_flags = 0,
376};
377
378static akm4xxx_t akm_6fire __devinitdata = {
379 .num_adcs = 6,
380 .num_dacs = 6,
381 .type = SND_AK4524,
382 .ops = {
383 .lock = dmx6fire_ak4524_lock
384 }
385};
386
387static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
388 .caddr = 2,
389 .cif = 1, /* CIF high */
390 .data_mask = ICE1712_6FIRE_SERIAL_DATA,
391 .clk_mask = ICE1712_6FIRE_SERIAL_CLOCK,
392 .cs_mask = 0,
393 .cs_addr = 0, /* set later */
394 .cs_none = 0,
395 .add_flags = ICE1712_6FIRE_RW, /* set rw bit high */
396 .mask_flags = 0,
397};
398
399/*
400 * initialize the chip
401 */
402
403/* 6fire specific */
404#define PCF9554_REG_INPUT 0
405#define PCF9554_REG_OUTPUT 1
406#define PCF9554_REG_POLARITY 2
407#define PCF9554_REG_CONFIG 3
408
409static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data);
410
411static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
412{
413 int err;
414 akm4xxx_t *ak;
415
416 /* set the analog DACs */
417 switch (ice->eeprom.subvendor) {
418 case ICE1712_SUBDEVICE_EWX2496:
419 ice->num_total_dacs = 2;
420 ice->num_total_adcs = 2;
421 break;
422 case ICE1712_SUBDEVICE_EWS88MT:
423 case ICE1712_SUBDEVICE_EWS88MT_NEW:
424 case ICE1712_SUBDEVICE_PHASE88:
425 ice->num_total_dacs = 8;
426 ice->num_total_adcs = 8;
427 break;
428 case ICE1712_SUBDEVICE_EWS88D:
429 /* Note: not analog but ADAT I/O */
430 ice->num_total_dacs = 8;
431 ice->num_total_adcs = 8;
432 break;
433 case ICE1712_SUBDEVICE_DMX6FIRE:
434 ice->num_total_dacs = 6;
435 ice->num_total_adcs = 6;
436 break;
437 }
438
439 /* create i2c */
440 if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
441 snd_printk("unable to create I2C bus\n");
442 return err;
443 }
444 ice->i2c->private_data = ice;
445 ice->i2c->hw_ops.bit = &snd_ice1712_ewx_cs8427_bit_ops;
446
447 /* create i2c devices */
448 switch (ice->eeprom.subvendor) {
449 case ICE1712_SUBDEVICE_DMX6FIRE:
450 if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
451 snd_printk("PCF9554 initialization failed\n");
452 return err;
453 }
454 snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
455 break;
456 case ICE1712_SUBDEVICE_EWS88MT:
457 case ICE1712_SUBDEVICE_EWS88MT_NEW:
458 case ICE1712_SUBDEVICE_PHASE88:
459 if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->spec.i2cdevs[EWS_I2C_CS8404])) < 0)
460 return err;
461 if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF1])) < 0)
462 return err;
463 if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF2])) < 0)
464 return err;
465 /* Check if the front module is connected */
466 if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
467 return err;
468 break;
469 case ICE1712_SUBDEVICE_EWS88D:
470 if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->spec.i2cdevs[EWS_I2C_88D])) < 0)
471 return err;
472 break;
473 }
474
475 /* set up SPDIF interface */
476 switch (ice->eeprom.subvendor) {
477 case ICE1712_SUBDEVICE_EWX2496:
478 if ((err = snd_ice1712_init_cs8427(ice, CS8427_BASE_ADDR)) < 0)
479 return err;
480 snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
481 break;
482 case ICE1712_SUBDEVICE_DMX6FIRE:
483 if ((err = snd_ice1712_init_cs8427(ice, ICE1712_6FIRE_CS8427_ADDR)) < 0)
484 return err;
485 snd_cs8427_reg_write(ice->cs8427, CS8427_REG_RECVERRMASK, CS8427_UNLOCK | CS8427_CONF | CS8427_BIP | CS8427_PAR);
486 break;
487 case ICE1712_SUBDEVICE_EWS88MT:
488 case ICE1712_SUBDEVICE_EWS88MT_NEW:
489 case ICE1712_SUBDEVICE_PHASE88:
490 case ICE1712_SUBDEVICE_EWS88D:
491 /* set up CS8404 */
492 ice->spdif.ops.open = ews88_open_spdif;
493 ice->spdif.ops.setup_rate = ews88_setup_spdif;
494 ice->spdif.ops.default_get = ews88_spdif_default_get;
495 ice->spdif.ops.default_put = ews88_spdif_default_put;
496 ice->spdif.ops.stream_get = ews88_spdif_stream_get;
497 ice->spdif.ops.stream_put = ews88_spdif_stream_put;
498 /* Set spdif defaults */
499 snd_ice1712_ews_cs8404_spdif_write(ice, ice->spdif.cs8403_bits);
500 break;
501 }
502
503 /* no analog? */
504 switch (ice->eeprom.subvendor) {
505 case ICE1712_SUBDEVICE_EWS88D:
506 return 0;
507 }
508
509 /* analog section */
510 ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
511 if (! ak)
512 return -ENOMEM;
513 ice->akm_codecs = 1;
514
515 switch (ice->eeprom.subvendor) {
516 case ICE1712_SUBDEVICE_EWS88MT:
517 case ICE1712_SUBDEVICE_EWS88MT_NEW:
518 case ICE1712_SUBDEVICE_PHASE88:
519 err = snd_ice1712_akm4xxx_init(ak, &akm_ews88mt, &akm_ews88mt_priv, ice);
520 break;
521 case ICE1712_SUBDEVICE_EWX2496:
522 err = snd_ice1712_akm4xxx_init(ak, &akm_ewx2496, &akm_ewx2496_priv, ice);
523 break;
524 case ICE1712_SUBDEVICE_DMX6FIRE:
525 err = snd_ice1712_akm4xxx_init(ak, &akm_6fire, &akm_6fire_priv, ice);
526 break;
527 default:
528 err = 0;
529 }
530
531 return err;
532}
533
534/*
535 * EWX 24/96 specific controls
536 */
537
538/* i/o sensitivity - this callback is shared among other devices, too */
539static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){
540
541 static char *texts[2] = {
542 "+4dBu", "-10dBV",
543 };
544 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
545 uinfo->count = 1;
546 uinfo->value.enumerated.items = 2;
547 if (uinfo->value.enumerated.item >= 2)
548 uinfo->value.enumerated.item = 1;
549 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
550 return 0;
551}
552
553static int snd_ice1712_ewx_io_sense_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
554{
555 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
556 unsigned char mask = kcontrol->private_value & 0xff;
557
558 snd_ice1712_save_gpio_status(ice);
559 ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0;
560 snd_ice1712_restore_gpio_status(ice);
561 return 0;
562}
563
564static int snd_ice1712_ewx_io_sense_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
565{
566 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
567 unsigned char mask = kcontrol->private_value & 0xff;
568 int val, nval;
569
570 if (kcontrol->private_value & (1 << 31))
571 return -EPERM;
572 nval = ucontrol->value.enumerated.item[0] ? mask : 0;
573 snd_ice1712_save_gpio_status(ice);
574 val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
575 nval |= val & ~mask;
576 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
577 snd_ice1712_restore_gpio_status(ice);
578 return val != nval;
579}
580
581static snd_kcontrol_new_t snd_ice1712_ewx2496_controls[] __devinitdata = {
582 {
583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584 .name = "Input Sensitivity Switch",
585 .info = snd_ice1712_ewx_io_sense_info,
586 .get = snd_ice1712_ewx_io_sense_get,
587 .put = snd_ice1712_ewx_io_sense_put,
588 .private_value = ICE1712_EWX2496_AIN_SEL,
589 },
590 {
591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
592 .name = "Output Sensitivity Switch",
593 .info = snd_ice1712_ewx_io_sense_info,
594 .get = snd_ice1712_ewx_io_sense_get,
595 .put = snd_ice1712_ewx_io_sense_put,
596 .private_value = ICE1712_EWX2496_AOUT_SEL,
597 },
598};
599
600
601/*
602 * EWS88MT specific controls
603 */
604/* analog output sensitivity;; address 0x48 bit 6 */
605static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
606{
607 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
608 unsigned char data;
609
610 snd_i2c_lock(ice->i2c);
611 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
612 snd_i2c_unlock(ice->i2c);
613 return -EIO;
614 }
615 snd_i2c_unlock(ice->i2c);
616 ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */
617 return 0;
618}
619
620/* analog output sensitivity;; address 0x48 bit 6 */
621static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
622{
623 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
624 unsigned char data, ndata;
625
626 snd_i2c_lock(ice->i2c);
627 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
628 snd_i2c_unlock(ice->i2c);
629 return -EIO;
630 }
631 ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
632 if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) {
633 snd_i2c_unlock(ice->i2c);
634 return -EIO;
635 }
636 snd_i2c_unlock(ice->i2c);
637 return ndata != data;
638}
639
640/* analog input sensitivity; address 0x46 */
641static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
642{
643 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
644 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
645 unsigned char data;
646
647 snd_assert(channel >= 0 && channel <= 7, return 0);
648 snd_i2c_lock(ice->i2c);
649 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
650 snd_i2c_unlock(ice->i2c);
651 return -EIO;
652 }
653 /* reversed; high = +4dBu, low = -10dBV */
654 ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1;
655 snd_i2c_unlock(ice->i2c);
656 return 0;
657}
658
659/* analog output sensitivity; address 0x46 */
660static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
661{
662 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
663 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
664 unsigned char data, ndata;
665
666 snd_assert(channel >= 0 && channel <= 7, return 0);
667 snd_i2c_lock(ice->i2c);
668 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
669 snd_i2c_unlock(ice->i2c);
670 return -EIO;
671 }
672 ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
673 if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) {
674 snd_i2c_unlock(ice->i2c);
675 return -EIO;
676 }
677 snd_i2c_unlock(ice->i2c);
678 return ndata != data;
679}
680
681static snd_kcontrol_new_t snd_ice1712_ews88mt_input_sense __devinitdata = {
682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
683 .name = "Input Sensitivity Switch",
684 .info = snd_ice1712_ewx_io_sense_info,
685 .get = snd_ice1712_ews88mt_input_sense_get,
686 .put = snd_ice1712_ews88mt_input_sense_put,
687 .count = 8,
688};
689
690static snd_kcontrol_new_t snd_ice1712_ews88mt_output_sense __devinitdata = {
691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
692 .name = "Output Sensitivity Switch",
693 .info = snd_ice1712_ewx_io_sense_info,
694 .get = snd_ice1712_ews88mt_output_sense_get,
695 .put = snd_ice1712_ews88mt_output_sense_put,
696};
697
698
699/*
700 * EWS88D specific controls
701 */
702
703static int snd_ice1712_ews88d_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
704{
705 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
706 uinfo->count = 1;
707 uinfo->value.integer.min = 0;
708 uinfo->value.integer.max = 1;
709 return 0;
710}
711
712static int snd_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
713{
714 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
715 int shift = kcontrol->private_value & 0xff;
716 int invert = (kcontrol->private_value >> 8) & 1;
717 unsigned char data[2];
718
719 snd_i2c_lock(ice->i2c);
720 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
721 snd_i2c_unlock(ice->i2c);
722 return -EIO;
723 }
724 snd_i2c_unlock(ice->i2c);
725 data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01;
726 if (invert)
727 data[0] ^= 0x01;
728 ucontrol->value.integer.value[0] = data[0];
729 return 0;
730}
731
732static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
733{
734 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
735 int shift = kcontrol->private_value & 0xff;
736 int invert = (kcontrol->private_value >> 8) & 1;
737 unsigned char data[2], ndata[2];
738 int change;
739
740 snd_i2c_lock(ice->i2c);
741 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
742 snd_i2c_unlock(ice->i2c);
743 return -EIO;
744 }
745 ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7));
746 if (invert) {
747 if (! ucontrol->value.integer.value[0])
748 ndata[shift >> 3] |= (1 << (shift & 7));
749 } else {
750 if (ucontrol->value.integer.value[0])
751 ndata[shift >> 3] |= (1 << (shift & 7));
752 }
753 change = (data[shift >> 3] != ndata[shift >> 3]);
754 if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
755 snd_i2c_unlock(ice->i2c);
756 return -EIO;
757 }
758 snd_i2c_unlock(ice->i2c);
759 return change;
760}
761
762#define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \
763{ .iface = xiface,\
764 .name = xname,\
765 .access = xaccess,\
766 .info = snd_ice1712_ews88d_control_info,\
767 .get = snd_ice1712_ews88d_control_get,\
768 .put = snd_ice1712_ews88d_control_put,\
769 .private_value = xshift | (xinvert << 8),\
770}
771
772static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = {
773 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
774 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
775 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
776 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0),
777 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0),
778};
779
780
781/*
782 * DMX 6Fire specific controls
783 */
784
785static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
786{
787 unsigned char byte;
788 snd_i2c_lock(ice->i2c);
789 byte = reg;
790 snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1);
791 byte = 0;
792 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
793 snd_i2c_unlock(ice->i2c);
794 printk("cannot read pca\n");
795 return -EIO;
796 }
797 snd_i2c_unlock(ice->i2c);
798 return byte;
799}
800
801static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data)
802{
803 unsigned char bytes[2];
804 snd_i2c_lock(ice->i2c);
805 bytes[0] = reg;
806 bytes[1] = data;
807 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
808 snd_i2c_unlock(ice->i2c);
809 return -EIO;
810 }
811 snd_i2c_unlock(ice->i2c);
812 return 0;
813}
814
815static int snd_ice1712_6fire_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
816{
817 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
818 uinfo->count = 1;
819 uinfo->value.integer.min = 0;
820 uinfo->value.integer.max = 1;
821 return 0;
822}
823
824static int snd_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
825{
826 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
827 int shift = kcontrol->private_value & 0xff;
828 int invert = (kcontrol->private_value >> 8) & 1;
829 int data;
830
831 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
832 return data;
833 data = (data >> shift) & 1;
834 if (invert)
835 data ^= 1;
836 ucontrol->value.integer.value[0] = data;
837 return 0;
838}
839
840static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
841{
842 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
843 int shift = kcontrol->private_value & 0xff;
844 int invert = (kcontrol->private_value >> 8) & 1;
845 int data, ndata;
846
847 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
848 return data;
849 ndata = data & ~(1 << shift);
850 if (ucontrol->value.integer.value[0])
851 ndata |= (1 << shift);
852 if (invert)
853 ndata ^= (1 << shift);
854 if (data != ndata) {
855 snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
856 return 1;
857 }
858 return 0;
859}
860
861static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
862{
863 static char *texts[4] = {
864 "Internal", "Front Input", "Rear Input", "Wave Table"
865 };
866 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
867 uinfo->count = 1;
868 uinfo->value.enumerated.items = 4;
869 if (uinfo->value.enumerated.item >= 4)
870 uinfo->value.enumerated.item = 1;
871 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
872 return 0;
873}
874
875static int snd_ice1712_6fire_select_input_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
876{
877 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
878 int data;
879
880 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
881 return data;
882 ucontrol->value.integer.value[0] = data & 3;
883 return 0;
884}
885
886static int snd_ice1712_6fire_select_input_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
887{
888 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
889 int data, ndata;
890
891 if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
892 return data;
893 ndata = data & ~3;
894 ndata |= (ucontrol->value.integer.value[0] & 3);
895 if (data != ndata) {
896 snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
897 return 1;
898 }
899 return 0;
900}
901
902
903#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \
904{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
905 .name = xname,\
906 .info = snd_ice1712_6fire_control_info,\
907 .get = snd_ice1712_6fire_control_get,\
908 .put = snd_ice1712_6fire_control_put,\
909 .private_value = xshift | (xinvert << 8),\
910}
911
912static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = {
913 {
914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
915 .name = "Analog Input Select",
916 .info = snd_ice1712_6fire_select_input_info,
917 .get = snd_ice1712_6fire_select_input_get,
918 .put = snd_ice1712_6fire_select_input_put,
919 },
920 DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 0),
921 // DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
922 DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
923 DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
924 DMX6FIRE_CONTROL("Breakbox LED", 6, 0),
925};
926
927
928static int __devinit snd_ice1712_ews_add_controls(ice1712_t *ice)
929{
930 unsigned int idx;
931 int err;
932
933 /* all terratec cards have spdif, but cs8427 module builds it's own controls */
934 if (ice->cs8427 == NULL) {
935 err = snd_ice1712_spdif_build_controls(ice);
936 if (err < 0)
937 return err;
938 }
939
940 /* ak4524 controls */
941 switch (ice->eeprom.subvendor) {
942 case ICE1712_SUBDEVICE_EWX2496:
943 case ICE1712_SUBDEVICE_EWS88MT:
944 case ICE1712_SUBDEVICE_EWS88MT_NEW:
945 case ICE1712_SUBDEVICE_PHASE88:
946 case ICE1712_SUBDEVICE_DMX6FIRE:
947 err = snd_ice1712_akm4xxx_build_controls(ice);
948 if (err < 0)
949 return err;
950 break;
951 }
952
953 /* card specific controls */
954 switch (ice->eeprom.subvendor) {
955 case ICE1712_SUBDEVICE_EWX2496:
956 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) {
957 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice));
958 if (err < 0)
959 return err;
960 }
961 break;
962 case ICE1712_SUBDEVICE_EWS88MT:
963 case ICE1712_SUBDEVICE_EWS88MT_NEW:
964 case ICE1712_SUBDEVICE_PHASE88:
965 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice));
966 if (err < 0)
967 return err;
968 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice));
969 if (err < 0)
970 return err;
971 break;
972 case ICE1712_SUBDEVICE_EWS88D:
973 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) {
974 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice));
975 if (err < 0)
976 return err;
977 }
978 break;
979 case ICE1712_SUBDEVICE_DMX6FIRE:
980 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) {
981 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
982 if (err < 0)
983 return err;
984 }
985 break;
986 }
987 return 0;
988}
989
990
991/* entry point */
992struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
993 {
994 .subvendor = ICE1712_SUBDEVICE_EWX2496,
995 .name = "TerraTec EWX24/96",
996 .model = "ewx2496",
997 .chip_init = snd_ice1712_ews_init,
998 .build_controls = snd_ice1712_ews_add_controls,
999 },
1000 {
1001 .subvendor = ICE1712_SUBDEVICE_EWS88MT,
1002 .name = "TerraTec EWS88MT",
1003 .model = "ews88mt",
1004 .chip_init = snd_ice1712_ews_init,
1005 .build_controls = snd_ice1712_ews_add_controls,
1006 },
1007 {
1008 .subvendor = ICE1712_SUBDEVICE_EWS88MT_NEW,
1009 .name = "TerraTec EWS88MT",
1010 .model = "ews88mt_new",
1011 .chip_init = snd_ice1712_ews_init,
1012 .build_controls = snd_ice1712_ews_add_controls,
1013 },
1014 {
1015 .subvendor = ICE1712_SUBDEVICE_PHASE88,
1016 .name = "TerraTec Phase88",
1017 .model = "phase88",
1018 .chip_init = snd_ice1712_ews_init,
1019 .build_controls = snd_ice1712_ews_add_controls,
1020 },
1021 {
1022 .subvendor = ICE1712_SUBDEVICE_EWS88D,
1023 .name = "TerraTec EWS88D",
1024 .model = "ews88d",
1025 .chip_init = snd_ice1712_ews_init,
1026 .build_controls = snd_ice1712_ews_add_controls,
1027 },
1028 {
1029 .subvendor = ICE1712_SUBDEVICE_DMX6FIRE,
1030 .name = "TerraTec DMX6Fire",
1031 .model = "dmx6fire",
1032 .chip_init = snd_ice1712_ews_init,
1033 .build_controls = snd_ice1712_ews_add_controls,
1034 },
1035 { } /* terminator */
1036};
diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h
new file mode 100644
index 000000000000..a12a0b053558
--- /dev/null
+++ b/sound/pci/ice1712/ews.h
@@ -0,0 +1,84 @@
1#ifndef __SOUND_EWS_H
2#define __SOUND_EWS_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
8 *
9 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
10 * 2002 Takashi Iwai <tiwai@suse.de>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#define EWS_DEVICE_DESC \
29 "{TerraTec,EWX 24/96},"\
30 "{TerraTec,EWS 88MT},"\
31 "{TerraTec,EWS 88D},"\
32 "{TerraTec,DMX 6Fire},"\
33 "{TerraTec,Phase 88},"
34
35#define ICE1712_SUBDEVICE_EWX2496 0x3b153011
36#define ICE1712_SUBDEVICE_EWS88MT 0x3b151511
37#define ICE1712_SUBDEVICE_EWS88MT_NEW 0x3b152511
38#define ICE1712_SUBDEVICE_EWS88D 0x3b152b11
39#define ICE1712_SUBDEVICE_DMX6FIRE 0x3b153811
40#define ICE1712_SUBDEVICE_PHASE88 0x3b155111
41
42/* entry point */
43extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
44
45
46/* TerraTec EWX 24/96 configuration definitions */
47
48#define ICE1712_EWX2496_AK4524_CS 0x01 /* AK4524 chip select; low = active */
49#define ICE1712_EWX2496_AIN_SEL 0x02 /* input sensitivity switch; high = louder */
50#define ICE1712_EWX2496_AOUT_SEL 0x04 /* output sensitivity switch; high = louder */
51#define ICE1712_EWX2496_RW 0x08 /* read/write switch for i2c; high = write */
52#define ICE1712_EWX2496_SERIAL_DATA 0x10 /* i2c & ak4524 data */
53#define ICE1712_EWX2496_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
54#define ICE1712_EWX2496_TX2 0x40 /* MIDI2 (not used) */
55#define ICE1712_EWX2496_RX2 0x80 /* MIDI2 (not used) */
56
57/* TerraTec EWS 88MT/D configuration definitions */
58/* RW, SDA snd SCLK are identical with EWX24/96 */
59#define ICE1712_EWS88_CS8414_RATE 0x07 /* CS8414 sample rate: gpio 0-2 */
60#define ICE1712_EWS88_RW 0x08 /* read/write switch for i2c; high = write */
61#define ICE1712_EWS88_SERIAL_DATA 0x10 /* i2c & ak4524 data */
62#define ICE1712_EWS88_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
63#define ICE1712_EWS88_TX2 0x40 /* MIDI2 (only on 88D) */
64#define ICE1712_EWS88_RX2 0x80 /* MIDI2 (only on 88D) */
65
66/* i2c address */
67#define ICE1712_EWS88MT_CS8404_ADDR (0x40>>1)
68#define ICE1712_EWS88MT_INPUT_ADDR (0x46>>1)
69#define ICE1712_EWS88MT_OUTPUT_ADDR (0x48>>1)
70#define ICE1712_EWS88MT_OUTPUT_SENSE 0x40 /* mask */
71#define ICE1712_EWS88D_PCF_ADDR (0x40>>1)
72
73/* TerraTec DMX 6Fire configuration definitions */
74#define ICE1712_6FIRE_AK4524_CS_MASK 0x07 /* AK4524 chip select #1-#3 */
75#define ICE1712_6FIRE_RW 0x08 /* read/write switch for i2c; high = write */
76#define ICE1712_6FIRE_SERIAL_DATA 0x10 /* i2c & ak4524 data */
77#define ICE1712_6FIRE_SERIAL_CLOCK 0x20 /* i2c & ak4524 clock */
78#define ICE1712_6FIRE_TX2 0x40 /* MIDI2 */
79#define ICE1712_6FIRE_RX2 0x80 /* MIDI2 */
80
81#define ICE1712_6FIRE_PCF9554_ADDR (0x40>>1)
82#define ICE1712_6FIRE_CS8427_ADDR (0x22)
83
84#endif /* __SOUND_EWS_H */
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
new file mode 100644
index 000000000000..ab5fbd0bdfad
--- /dev/null
+++ b/sound/pci/ice1712/hoontech.c
@@ -0,0 +1,326 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for Hoontech STDSP24
5 *
6 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "hoontech.h"
34
35
36static void __devinit snd_ice1712_stdsp24_gpio_write(ice1712_t *ice, unsigned char byte)
37{
38 byte |= ICE1712_STDSP24_CLOCK_BIT;
39 udelay(100);
40 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
41 byte &= ~ICE1712_STDSP24_CLOCK_BIT;
42 udelay(100);
43 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
44 byte |= ICE1712_STDSP24_CLOCK_BIT;
45 udelay(100);
46 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
47}
48
49static void __devinit snd_ice1712_stdsp24_darear(ice1712_t *ice, int activate)
50{
51 down(&ice->gpio_mutex);
52 ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate);
53 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
54 up(&ice->gpio_mutex);
55}
56
57static void __devinit snd_ice1712_stdsp24_mute(ice1712_t *ice, int activate)
58{
59 down(&ice->gpio_mutex);
60 ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate);
61 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
62 up(&ice->gpio_mutex);
63}
64
65static void __devinit snd_ice1712_stdsp24_insel(ice1712_t *ice, int activate)
66{
67 down(&ice->gpio_mutex);
68 ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate);
69 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
70 up(&ice->gpio_mutex);
71}
72
73static void __devinit snd_ice1712_stdsp24_box_channel(ice1712_t *ice, int box, int chn, int activate)
74{
75 down(&ice->gpio_mutex);
76
77 /* select box */
78 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
79 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
80
81 /* prepare for write */
82 if (chn == 3)
83 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
84 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, activate);
85 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
86 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
87
88 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
89 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
90 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
91 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
92 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
93 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
94 udelay(100);
95 if (chn == 3) {
96 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
97 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
98 } else {
99 switch (chn) {
100 case 0: ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 0); break;
101 case 1: ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 0); break;
102 case 2: ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 0); break;
103 }
104 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
105 }
106 udelay(100);
107 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
108 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
109 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
110 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
111 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
112 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
113 udelay(100);
114
115 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
116 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
117
118 up(&ice->gpio_mutex);
119}
120
121static void __devinit snd_ice1712_stdsp24_box_midi(ice1712_t *ice, int box, int master)
122{
123 down(&ice->gpio_mutex);
124
125 /* select box */
126 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
127 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
128
129 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
130 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, master);
131 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
132 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
133
134 udelay(100);
135
136 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 0);
137 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
138
139 mdelay(10);
140
141 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
142 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
143
144 up(&ice->gpio_mutex);
145}
146
147static void __devinit snd_ice1712_stdsp24_midi2(ice1712_t *ice, int activate)
148{
149 down(&ice->gpio_mutex);
150 ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate);
151 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
152 up(&ice->gpio_mutex);
153}
154
155static int __devinit snd_ice1712_hoontech_init(ice1712_t *ice)
156{
157 int box, chn;
158
159 ice->num_total_dacs = 8;
160 ice->num_total_adcs = 8;
161
162 ice->spec.hoontech.boxbits[0] =
163 ice->spec.hoontech.boxbits[1] =
164 ice->spec.hoontech.boxbits[2] =
165 ice->spec.hoontech.boxbits[3] = 0; /* should be already */
166
167 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 0);
168 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 0, 1);
169 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, 0);
170 ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, 0);
171
172 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 1);
173 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 1, 1);
174 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
175 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
176 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
177
178 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 2);
179 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 2, 1);
180 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
181 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
182 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
183
184 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 3);
185 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 3, 1);
186 ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, 0);
187 ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, 1);
188 ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, 0);
189
190 /* let's go - activate only functions in first box */
191 ice->spec.hoontech.config = 0;
192 /* ICE1712_STDSP24_MUTE |
193 ICE1712_STDSP24_INSEL |
194 ICE1712_STDSP24_DAREAR; */
195 ice->spec.hoontech.boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
196 ICE1712_STDSP24_BOX_CHN2 |
197 ICE1712_STDSP24_BOX_CHN3 |
198 ICE1712_STDSP24_BOX_CHN4 |
199 ICE1712_STDSP24_BOX_MIDI1 |
200 ICE1712_STDSP24_BOX_MIDI2;
201 ice->spec.hoontech.boxconfig[1] =
202 ice->spec.hoontech.boxconfig[2] =
203 ice->spec.hoontech.boxconfig[3] = 0;
204 snd_ice1712_stdsp24_darear(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
205 snd_ice1712_stdsp24_mute(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_MUTE) ? 1 : 0);
206 snd_ice1712_stdsp24_insel(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_INSEL) ? 1 : 0);
207 for (box = 0; box < 4; box++) {
208 for (chn = 0; chn < 4; chn++)
209 snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->spec.hoontech.boxconfig[box] & (1 << chn)) ? 1 : 0);
210 snd_ice1712_stdsp24_box_midi(ice, box,
211 (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
212 if (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
213 snd_ice1712_stdsp24_midi2(ice, 1);
214 }
215
216 return 0;
217}
218
219/*
220 * AK4524 access
221 */
222
223/* start callback for STDSP24 with modified hardware */
224static void stdsp24_ak4524_lock(akm4xxx_t *ak, int chip)
225{
226 ice1712_t *ice = ak->private_data[0];
227 unsigned char tmp;
228 snd_ice1712_save_gpio_status(ice);
229 tmp = ICE1712_STDSP24_SERIAL_DATA |
230 ICE1712_STDSP24_SERIAL_CLOCK |
231 ICE1712_STDSP24_AK4524_CS;
232 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
233 ice->gpio.direction | tmp);
234 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
235}
236
237static int __devinit snd_ice1712_value_init(ice1712_t *ice)
238{
239 /* Hoontech STDSP24 with modified hardware */
240 static akm4xxx_t akm_stdsp24_mv __devinitdata = {
241 .num_adcs = 2,
242 .num_dacs = 2,
243 .type = SND_AK4524,
244 .ops = {
245 .lock = stdsp24_ak4524_lock
246 }
247 };
248
249 static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
250 .caddr = 2,
251 .cif = 1, /* CIF high */
252 .data_mask = ICE1712_STDSP24_SERIAL_DATA,
253 .clk_mask = ICE1712_STDSP24_SERIAL_CLOCK,
254 .cs_mask = ICE1712_STDSP24_AK4524_CS,
255 .cs_addr = ICE1712_STDSP24_AK4524_CS,
256 .cs_none = 0,
257 .add_flags = 0,
258 };
259
260 int err;
261 akm4xxx_t *ak;
262
263 /* set the analog DACs */
264 ice->num_total_dacs = 2;
265
266 /* set the analog ADCs */
267 ice->num_total_adcs = 2;
268
269 /* analog section */
270 ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
271 if (! ak)
272 return -ENOMEM;
273 ice->akm_codecs = 1;
274
275 err = snd_ice1712_akm4xxx_init(ak, &akm_stdsp24_mv, &akm_stdsp24_mv_priv, ice);
276 if (err < 0)
277 return err;
278
279 /* ak4524 controls */
280 err = snd_ice1712_akm4xxx_build_controls(ice);
281 if (err < 0)
282 return err;
283
284 return 0;
285}
286
287static int __devinit snd_ice1712_ez8_init(ice1712_t *ice)
288{
289 ice->gpio.write_mask = ice->eeprom.gpiomask;
290 ice->gpio.direction = ice->eeprom.gpiodir;
291 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
292 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
293 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
294 return 0;
295}
296
297
298/* entry point */
299struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
300 {
301 .subvendor = ICE1712_SUBDEVICE_STDSP24,
302 .name = "Hoontech SoundTrack Audio DSP24",
303 .model = "dsp24",
304 .chip_init = snd_ice1712_hoontech_init,
305 },
306 {
307 .subvendor = ICE1712_SUBDEVICE_STDSP24_VALUE, /* a dummy id */
308 .name = "Hoontech SoundTrack Audio DSP24 Value",
309 .model = "dsp24_value",
310 .chip_init = snd_ice1712_value_init,
311 },
312 {
313 .subvendor = ICE1712_SUBDEVICE_STDSP24_MEDIA7_1,
314 .name = "Hoontech STA DSP24 Media 7.1",
315 .model = "dsp24_71",
316 .chip_init = snd_ice1712_hoontech_init,
317 },
318 {
319 .subvendor = ICE1712_SUBDEVICE_EVENT_EZ8, /* a dummy id */
320 .name = "Event Electronics EZ8",
321 .model = "ez8",
322 .chip_init = snd_ice1712_ez8_init,
323 },
324 { } /* terminator */
325};
326
diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h
new file mode 100644
index 000000000000..1ee538b20fbf
--- /dev/null
+++ b/sound/pci/ice1712/hoontech.h
@@ -0,0 +1,77 @@
1#ifndef __SOUND_HOONTECH_H
2#define __SOUND_HOONTECH_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for Hoontech STDSP24
8 *
9 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
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
27#define HOONTECH_DEVICE_DESC \
28 "{Hoontech,SoundTrack DSP 24}," \
29 "{Hoontech,SoundTrack DSP 24 Value}," \
30 "{Hoontech,SoundTrack DSP 24 Media 7.1}," \
31 "{Event Electronics,EZ8},"
32
33#define ICE1712_SUBDEVICE_STDSP24 0x12141217 /* Hoontech SoundTrack Audio DSP 24 */
34#define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */
35#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
36#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */
37
38extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
39
40
41/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
42
43#define ICE1712_STDSP24_0_BOX(r, x) r[0] = ((r[0] & ~3) | ((x)&3))
44#define ICE1712_STDSP24_0_DAREAR(r, x) r[0] = ((r[0] & ~4) | (((x)&1)<<2))
45#define ICE1712_STDSP24_1_CHN1(r, x) r[1] = ((r[1] & ~1) | ((x)&1))
46#define ICE1712_STDSP24_1_CHN2(r, x) r[1] = ((r[1] & ~2) | (((x)&1)<<1))
47#define ICE1712_STDSP24_1_CHN3(r, x) r[1] = ((r[1] & ~4) | (((x)&1)<<2))
48#define ICE1712_STDSP24_2_CHN4(r, x) r[2] = ((r[2] & ~1) | ((x)&1))
49#define ICE1712_STDSP24_2_MIDIIN(r, x) r[2] = ((r[2] & ~2) | (((x)&1)<<1))
50#define ICE1712_STDSP24_2_MIDI1(r, x) r[2] = ((r[2] & ~4) | (((x)&1)<<2))
51#define ICE1712_STDSP24_3_MIDI2(r, x) r[3] = ((r[3] & ~1) | ((x)&1))
52#define ICE1712_STDSP24_3_MUTE(r, x) r[3] = ((r[3] & ~2) | (((x)&1)<<1))
53#define ICE1712_STDSP24_3_INSEL(r, x) r[3] = ((r[3] & ~4) | (((x)&1)<<2))
54#define ICE1712_STDSP24_SET_ADDR(r, a) r[a&3] = ((r[a&3] & ~0x18) | (((a)&3)<<3))
55#define ICE1712_STDSP24_CLOCK(r, a, c) r[a&3] = ((r[a&3] & ~0x20) | (((c)&1)<<5))
56#define ICE1712_STDSP24_CLOCK_BIT (1<<5)
57
58/* Hoontech SoundTrack Audio DSP 24 box configuration definitions */
59
60#define ICE1712_STDSP24_DAREAR (1<<0)
61#define ICE1712_STDSP24_MUTE (1<<1)
62#define ICE1712_STDSP24_INSEL (1<<2)
63
64#define ICE1712_STDSP24_BOX_CHN1 (1<<0) /* input channel 1 */
65#define ICE1712_STDSP24_BOX_CHN2 (1<<1) /* input channel 2 */
66#define ICE1712_STDSP24_BOX_CHN3 (1<<2) /* input channel 3 */
67#define ICE1712_STDSP24_BOX_CHN4 (1<<3) /* input channel 4 */
68#define ICE1712_STDSP24_BOX_MIDI1 (1<<8)
69#define ICE1712_STDSP24_BOX_MIDI2 (1<<9)
70
71/* Hoontech SoundTrack Audio DSP 24 Value definitions for modified hardware */
72
73#define ICE1712_STDSP24_AK4524_CS 0x03 /* AK4524 chip select; low = active */
74#define ICE1712_STDSP24_SERIAL_DATA 0x0c /* ak4524 data */
75#define ICE1712_STDSP24_SERIAL_CLOCK 0x30 /* ak4524 clock */
76
77#endif /* __SOUND_HOONTECH_H */
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
new file mode 100644
index 000000000000..79fba6be3503
--- /dev/null
+++ b/sound/pci/ice1712/ice1712.c
@@ -0,0 +1,2760 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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 */
21
22/*
23 NOTES:
24 - spdif nonaudio consumer mode does not work (at least with my
25 Sony STR-DB830)
26*/
27
28/*
29 * Changes:
30 *
31 * 2002.09.09 Takashi Iwai <tiwai@suse.de>
32 * split the code to several files. each low-level routine
33 * is stored in the local file and called from registration
34 * function from card_info struct.
35 *
36 * 2002.11.26 James Stafford <jstafford@ampltd.com>
37 * Added support for VT1724 (Envy24HT)
38 * I have left out support for 176.4 and 192 KHz for the moment.
39 * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401
40 *
41 * 2003.02.20 Taksahi Iwai <tiwai@suse.de>
42 * Split vt1724 part to an independent driver.
43 * The GPIO is accessed through the callback functions now.
44 *
45 * 2004.03.31 Doug McLain <nostar@comcast.net>
46 * Added support for Event Electronics EZ8 card to hoontech.c.
47 */
48
49
50#include <sound/driver.h>
51#include <asm/io.h>
52#include <linux/delay.h>
53#include <linux/interrupt.h>
54#include <linux/init.h>
55#include <linux/pci.h>
56#include <linux/slab.h>
57#include <linux/moduleparam.h>
58#include <sound/core.h>
59#include <sound/cs8427.h>
60#include <sound/info.h>
61#include <sound/mpu401.h>
62#include <sound/initval.h>
63
64#include <sound/asoundef.h>
65
66#include "ice1712.h"
67
68/* lowlevel routines */
69#include "delta.h"
70#include "ews.h"
71#include "hoontech.h"
72
73MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
74MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)");
75MODULE_LICENSE("GPL");
76MODULE_SUPPORTED_DEVICE("{"
77 HOONTECH_DEVICE_DESC
78 DELTA_DEVICE_DESC
79 EWS_DEVICE_DESC
80 "{ICEnsemble,Generic ICE1712},"
81 "{ICEnsemble,Generic Envy24}}");
82
83static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
84static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
85static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
86static char *model[SNDRV_CARDS];
87static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */
88static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */
89
90module_param_array(index, int, NULL, 0444);
91MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard.");
92module_param_array(id, charp, NULL, 0444);
93MODULE_PARM_DESC(id, "ID string for ICE1712 soundcard.");
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable ICE1712 soundcard.");
96module_param_array(omni, bool, NULL, 0444);
97MODULE_PARM_DESC(omni, "Enable Midiman M-Audio Delta Omni I/O support.");
98module_param_array(cs8427_timeout, int, NULL, 0444);
99MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution.");
100module_param_array(model, charp, NULL, 0444);
101MODULE_PARM_DESC(model, "Use the given board model.");
102
103#ifndef PCI_VENDOR_ID_ICE
104#define PCI_VENDOR_ID_ICE 0x1412
105#endif
106#ifndef PCI_DEVICE_ID_ICE_1712
107#define PCI_DEVICE_ID_ICE_1712 0x1712
108#endif
109
110static struct pci_device_id snd_ice1712_ids[] = {
111 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */
112 { 0, }
113};
114
115MODULE_DEVICE_TABLE(pci, snd_ice1712_ids);
116
117static int snd_ice1712_build_pro_mixer(ice1712_t *ice);
118static int snd_ice1712_build_controls(ice1712_t *ice);
119
120static int PRO_RATE_LOCKED;
121static int PRO_RATE_RESET = 1;
122static unsigned int PRO_RATE_DEFAULT = 44100;
123
124/*
125 * Basic I/O
126 */
127
128/* check whether the clock mode is spdif-in */
129static inline int is_spdif_master(ice1712_t *ice)
130{
131 return (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER) ? 1 : 0;
132}
133
134static inline int is_pro_rate_locked(ice1712_t *ice)
135{
136 return is_spdif_master(ice) || PRO_RATE_LOCKED;
137}
138
139static inline void snd_ice1712_ds_write(ice1712_t * ice, u8 channel, u8 addr, u32 data)
140{
141 outb((channel << 4) | addr, ICEDS(ice, INDEX));
142 outl(data, ICEDS(ice, DATA));
143}
144
145static inline u32 snd_ice1712_ds_read(ice1712_t * ice, u8 channel, u8 addr)
146{
147 outb((channel << 4) | addr, ICEDS(ice, INDEX));
148 return inl(ICEDS(ice, DATA));
149}
150
151static void snd_ice1712_ac97_write(ac97_t *ac97,
152 unsigned short reg,
153 unsigned short val)
154{
155 ice1712_t *ice = (ice1712_t *)ac97->private_data;
156 int tm;
157 unsigned char old_cmd = 0;
158
159 for (tm = 0; tm < 0x10000; tm++) {
160 old_cmd = inb(ICEREG(ice, AC97_CMD));
161 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
162 continue;
163 if (!(old_cmd & ICE1712_AC97_READY))
164 continue;
165 break;
166 }
167 outb(reg, ICEREG(ice, AC97_INDEX));
168 outw(val, ICEREG(ice, AC97_DATA));
169 old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
170 outb(old_cmd | ICE1712_AC97_WRITE, ICEREG(ice, AC97_CMD));
171 for (tm = 0; tm < 0x10000; tm++)
172 if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
173 break;
174}
175
176static unsigned short snd_ice1712_ac97_read(ac97_t *ac97,
177 unsigned short reg)
178{
179 ice1712_t *ice = (ice1712_t *)ac97->private_data;
180 int tm;
181 unsigned char old_cmd = 0;
182
183 for (tm = 0; tm < 0x10000; tm++) {
184 old_cmd = inb(ICEREG(ice, AC97_CMD));
185 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
186 continue;
187 if (!(old_cmd & ICE1712_AC97_READY))
188 continue;
189 break;
190 }
191 outb(reg, ICEREG(ice, AC97_INDEX));
192 outb(old_cmd | ICE1712_AC97_READ, ICEREG(ice, AC97_CMD));
193 for (tm = 0; tm < 0x10000; tm++)
194 if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
195 break;
196 if (tm >= 0x10000) /* timeout */
197 return ~0;
198 return inw(ICEREG(ice, AC97_DATA));
199}
200
201/*
202 * pro ac97 section
203 */
204
205static void snd_ice1712_pro_ac97_write(ac97_t *ac97,
206 unsigned short reg,
207 unsigned short val)
208{
209 ice1712_t *ice = (ice1712_t *)ac97->private_data;
210 int tm;
211 unsigned char old_cmd = 0;
212
213 for (tm = 0; tm < 0x10000; tm++) {
214 old_cmd = inb(ICEMT(ice, AC97_CMD));
215 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
216 continue;
217 if (!(old_cmd & ICE1712_AC97_READY))
218 continue;
219 break;
220 }
221 outb(reg, ICEMT(ice, AC97_INDEX));
222 outw(val, ICEMT(ice, AC97_DATA));
223 old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
224 outb(old_cmd | ICE1712_AC97_WRITE, ICEMT(ice, AC97_CMD));
225 for (tm = 0; tm < 0x10000; tm++)
226 if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
227 break;
228}
229
230
231static unsigned short snd_ice1712_pro_ac97_read(ac97_t *ac97,
232 unsigned short reg)
233{
234 ice1712_t *ice = (ice1712_t *)ac97->private_data;
235 int tm;
236 unsigned char old_cmd = 0;
237
238 for (tm = 0; tm < 0x10000; tm++) {
239 old_cmd = inb(ICEMT(ice, AC97_CMD));
240 if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
241 continue;
242 if (!(old_cmd & ICE1712_AC97_READY))
243 continue;
244 break;
245 }
246 outb(reg, ICEMT(ice, AC97_INDEX));
247 outb(old_cmd | ICE1712_AC97_READ, ICEMT(ice, AC97_CMD));
248 for (tm = 0; tm < 0x10000; tm++)
249 if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
250 break;
251 if (tm >= 0x10000) /* timeout */
252 return ~0;
253 return inw(ICEMT(ice, AC97_DATA));
254}
255
256/*
257 * consumer ac97 digital mix
258 */
259static int snd_ice1712_digmix_route_ac97_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
260{
261 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
262 uinfo->count = 1;
263 uinfo->value.integer.min = 0;
264 uinfo->value.integer.max = 1;
265 return 0;
266}
267
268static int snd_ice1712_digmix_route_ac97_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
269{
270 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
271
272 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
273 return 0;
274}
275
276static int snd_ice1712_digmix_route_ac97_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
277{
278 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
279 unsigned char val, nval;
280
281 spin_lock_irq(&ice->reg_lock);
282 val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
283 nval = val & ~ICE1712_ROUTE_AC97;
284 if (ucontrol->value.integer.value[0]) nval |= ICE1712_ROUTE_AC97;
285 outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
286 spin_unlock_irq(&ice->reg_lock);
287 return val != nval;
288}
289
290static snd_kcontrol_new_t snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
292 .name = "Digital Mixer To AC97",
293 .info = snd_ice1712_digmix_route_ac97_info,
294 .get = snd_ice1712_digmix_route_ac97_get,
295 .put = snd_ice1712_digmix_route_ac97_put,
296};
297
298
299/*
300 * gpio operations
301 */
302static void snd_ice1712_set_gpio_dir(ice1712_t *ice, unsigned int data)
303{
304 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data);
305 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
306}
307
308static void snd_ice1712_set_gpio_mask(ice1712_t *ice, unsigned int data)
309{
310 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
311 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
312}
313
314static unsigned int snd_ice1712_get_gpio_data(ice1712_t *ice)
315{
316 return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
317}
318
319static void snd_ice1712_set_gpio_data(ice1712_t *ice, unsigned int val)
320{
321 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val);
322 inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
323}
324
325
326/*
327 *
328 * CS8427 interface
329 *
330 */
331
332/*
333 * change the input clock selection
334 * spdif_clock = 1 - IEC958 input, 0 - Envy24
335 */
336static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock)
337{
338 unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */
339 unsigned char val, nval;
340 int res = 0;
341
342 snd_i2c_lock(ice->i2c);
343 if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
344 snd_i2c_unlock(ice->i2c);
345 return -EIO;
346 }
347 if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) {
348 snd_i2c_unlock(ice->i2c);
349 return -EIO;
350 }
351 nval = val & 0xf0;
352 if (spdif_clock)
353 nval |= 0x01;
354 else
355 nval |= 0x04;
356 if (val != nval) {
357 reg[1] = nval;
358 if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) {
359 res = -EIO;
360 } else {
361 res++;
362 }
363 }
364 snd_i2c_unlock(ice->i2c);
365 return res;
366}
367
368/*
369 * spdif callbacks
370 */
371static void open_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
372{
373 snd_cs8427_iec958_active(ice->cs8427, 1);
374}
375
376static void close_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
377{
378 snd_cs8427_iec958_active(ice->cs8427, 0);
379}
380
381static void setup_cs8427(ice1712_t *ice, int rate)
382{
383 snd_cs8427_iec958_pcm(ice->cs8427, rate);
384}
385
386/*
387 * create and initialize callbacks for cs8427 interface
388 */
389int __devinit snd_ice1712_init_cs8427(ice1712_t *ice, int addr)
390{
391 int err;
392
393 if ((err = snd_cs8427_create(ice->i2c, addr,
394 (ice->cs8427_timeout * HZ) / 1000,
395 &ice->cs8427)) < 0) {
396 snd_printk("CS8427 initialization failed\n");
397 return err;
398 }
399 ice->spdif.ops.open = open_cs8427;
400 ice->spdif.ops.close = close_cs8427;
401 ice->spdif.ops.setup_rate = setup_cs8427;
402 return 0;
403}
404
405
406/*
407 * Interrupt handler
408 */
409
410static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
411{
412 ice1712_t *ice = dev_id;
413 unsigned char status;
414 int handled = 0;
415
416 while (1) {
417 status = inb(ICEREG(ice, IRQSTAT));
418 if (status == 0)
419 break;
420 handled = 1;
421 if (status & ICE1712_IRQ_MPU1) {
422 if (ice->rmidi[0])
423 snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
424 outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT));
425 status &= ~ICE1712_IRQ_MPU1;
426 }
427 if (status & ICE1712_IRQ_TIMER)
428 outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT));
429 if (status & ICE1712_IRQ_MPU2) {
430 if (ice->rmidi[1])
431 snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data, regs);
432 outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT));
433 status &= ~ICE1712_IRQ_MPU2;
434 }
435 if (status & ICE1712_IRQ_PROPCM) {
436 unsigned char mtstat = inb(ICEMT(ice, IRQ));
437 if (mtstat & ICE1712_MULTI_PBKSTATUS) {
438 if (ice->playback_pro_substream)
439 snd_pcm_period_elapsed(ice->playback_pro_substream);
440 outb(ICE1712_MULTI_PBKSTATUS, ICEMT(ice, IRQ));
441 }
442 if (mtstat & ICE1712_MULTI_CAPSTATUS) {
443 if (ice->capture_pro_substream)
444 snd_pcm_period_elapsed(ice->capture_pro_substream);
445 outb(ICE1712_MULTI_CAPSTATUS, ICEMT(ice, IRQ));
446 }
447 }
448 if (status & ICE1712_IRQ_FM)
449 outb(ICE1712_IRQ_FM, ICEREG(ice, IRQSTAT));
450 if (status & ICE1712_IRQ_PBKDS) {
451 u32 idx;
452 u16 pbkstatus;
453 snd_pcm_substream_t *substream;
454 pbkstatus = inw(ICEDS(ice, INTSTAT));
455 //printk("pbkstatus = 0x%x\n", pbkstatus);
456 for (idx = 0; idx < 6; idx++) {
457 if ((pbkstatus & (3 << (idx * 2))) == 0)
458 continue;
459 if ((substream = ice->playback_con_substream_ds[idx]) != NULL)
460 snd_pcm_period_elapsed(substream);
461 outw(3 << (idx * 2), ICEDS(ice, INTSTAT));
462 }
463 outb(ICE1712_IRQ_PBKDS, ICEREG(ice, IRQSTAT));
464 }
465 if (status & ICE1712_IRQ_CONCAP) {
466 if (ice->capture_con_substream)
467 snd_pcm_period_elapsed(ice->capture_con_substream);
468 outb(ICE1712_IRQ_CONCAP, ICEREG(ice, IRQSTAT));
469 }
470 if (status & ICE1712_IRQ_CONPBK) {
471 if (ice->playback_con_substream)
472 snd_pcm_period_elapsed(ice->playback_con_substream);
473 outb(ICE1712_IRQ_CONPBK, ICEREG(ice, IRQSTAT));
474 }
475 }
476 return IRQ_RETVAL(handled);
477}
478
479
480/*
481 * PCM part - misc
482 */
483
484static int snd_ice1712_hw_params(snd_pcm_substream_t * substream,
485 snd_pcm_hw_params_t * hw_params)
486{
487 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
488}
489
490static int snd_ice1712_hw_free(snd_pcm_substream_t * substream)
491{
492 return snd_pcm_lib_free_pages(substream);
493}
494
495/*
496 * PCM part - consumer I/O
497 */
498
499static int snd_ice1712_playback_trigger(snd_pcm_substream_t * substream,
500 int cmd)
501{
502 ice1712_t *ice = snd_pcm_substream_chip(substream);
503 int result = 0;
504 u32 tmp;
505
506 spin_lock(&ice->reg_lock);
507 tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
508 if (cmd == SNDRV_PCM_TRIGGER_START) {
509 tmp |= 1;
510 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
511 tmp &= ~1;
512 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
513 tmp |= 2;
514 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
515 tmp &= ~2;
516 } else {
517 result = -EINVAL;
518 }
519 snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
520 spin_unlock(&ice->reg_lock);
521 return result;
522}
523
524static int snd_ice1712_playback_ds_trigger(snd_pcm_substream_t * substream,
525 int cmd)
526{
527 ice1712_t *ice = snd_pcm_substream_chip(substream);
528 int result = 0;
529 u32 tmp;
530
531 spin_lock(&ice->reg_lock);
532 tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
533 if (cmd == SNDRV_PCM_TRIGGER_START) {
534 tmp |= 1;
535 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
536 tmp &= ~1;
537 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
538 tmp |= 2;
539 } else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
540 tmp &= ~2;
541 } else {
542 result = -EINVAL;
543 }
544 snd_ice1712_ds_write(ice, substream->number * 2, ICE1712_DSC_CONTROL, tmp);
545 spin_unlock(&ice->reg_lock);
546 return result;
547}
548
549static int snd_ice1712_capture_trigger(snd_pcm_substream_t * substream,
550 int cmd)
551{
552 ice1712_t *ice = snd_pcm_substream_chip(substream);
553 int result = 0;
554 u8 tmp;
555
556 spin_lock(&ice->reg_lock);
557 tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
558 if (cmd == SNDRV_PCM_TRIGGER_START) {
559 tmp |= 1;
560 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
561 tmp &= ~1;
562 } else {
563 result = -EINVAL;
564 }
565 snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
566 spin_unlock(&ice->reg_lock);
567 return result;
568}
569
570static int snd_ice1712_playback_prepare(snd_pcm_substream_t * substream)
571{
572 ice1712_t *ice = snd_pcm_substream_chip(substream);
573 snd_pcm_runtime_t *runtime = substream->runtime;
574 u32 period_size, buf_size, rate, tmp;
575
576 period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
577 buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
578 tmp = 0x0000;
579 if (snd_pcm_format_width(runtime->format) == 16)
580 tmp |= 0x10;
581 if (runtime->channels == 2)
582 tmp |= 0x08;
583 rate = (runtime->rate * 8192) / 375;
584 if (rate > 0x000fffff)
585 rate = 0x000fffff;
586 spin_lock_irq(&ice->reg_lock);
587 outb(0, ice->ddma_port + 15);
588 outb(ICE1712_DMA_MODE_WRITE | ICE1712_DMA_AUTOINIT, ice->ddma_port + 0x0b);
589 outl(runtime->dma_addr, ice->ddma_port + 0);
590 outw(buf_size, ice->ddma_port + 4);
591 snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_LO, rate & 0xff);
592 snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_MID, (rate >> 8) & 0xff);
593 snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_HI, (rate >> 16) & 0xff);
594 snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
595 snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_LO, period_size & 0xff);
596 snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_HI, period_size >> 8);
597 snd_ice1712_write(ice, ICE1712_IREG_PBK_LEFT, 0);
598 snd_ice1712_write(ice, ICE1712_IREG_PBK_RIGHT, 0);
599 spin_unlock_irq(&ice->reg_lock);
600 return 0;
601}
602
603static int snd_ice1712_playback_ds_prepare(snd_pcm_substream_t * substream)
604{
605 ice1712_t *ice = snd_pcm_substream_chip(substream);
606 snd_pcm_runtime_t *runtime = substream->runtime;
607 u32 period_size, buf_size, rate, tmp, chn;
608
609 period_size = snd_pcm_lib_period_bytes(substream) - 1;
610 buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
611 tmp = 0x0064;
612 if (snd_pcm_format_width(runtime->format) == 16)
613 tmp &= ~0x04;
614 if (runtime->channels == 2)
615 tmp |= 0x08;
616 rate = (runtime->rate * 8192) / 375;
617 if (rate > 0x000fffff)
618 rate = 0x000fffff;
619 ice->playback_con_active_buf[substream->number] = 0;
620 ice->playback_con_virt_addr[substream->number] = runtime->dma_addr;
621 chn = substream->number * 2;
622 spin_lock_irq(&ice->reg_lock);
623 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR0, runtime->dma_addr);
624 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT0, period_size);
625 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR1, runtime->dma_addr + (runtime->periods > 1 ? period_size + 1 : 0));
626 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT1, period_size);
627 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_RATE, rate);
628 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_VOLUME, 0);
629 snd_ice1712_ds_write(ice, chn, ICE1712_DSC_CONTROL, tmp);
630 if (runtime->channels == 2) {
631 snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_RATE, rate);
632 snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_VOLUME, 0);
633 }
634 spin_unlock_irq(&ice->reg_lock);
635 return 0;
636}
637
638static int snd_ice1712_capture_prepare(snd_pcm_substream_t * substream)
639{
640 ice1712_t *ice = snd_pcm_substream_chip(substream);
641 snd_pcm_runtime_t *runtime = substream->runtime;
642 u32 period_size, buf_size;
643 u8 tmp;
644
645 period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
646 buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
647 tmp = 0x06;
648 if (snd_pcm_format_width(runtime->format) == 16)
649 tmp &= ~0x04;
650 if (runtime->channels == 2)
651 tmp &= ~0x02;
652 spin_lock_irq(&ice->reg_lock);
653 outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR));
654 outw(buf_size, ICEREG(ice, CONCAP_COUNT));
655 snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8);
656 snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff);
657 snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
658 spin_unlock_irq(&ice->reg_lock);
659 snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
660 return 0;
661}
662
663static snd_pcm_uframes_t snd_ice1712_playback_pointer(snd_pcm_substream_t * substream)
664{
665 ice1712_t *ice = snd_pcm_substream_chip(substream);
666 snd_pcm_runtime_t *runtime = substream->runtime;
667 size_t ptr;
668
669 if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1))
670 return 0;
671 ptr = runtime->buffer_size - inw(ice->ddma_port + 4);
672 if (ptr == runtime->buffer_size)
673 ptr = 0;
674 return bytes_to_frames(substream->runtime, ptr);
675}
676
677static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(snd_pcm_substream_t * substream)
678{
679 ice1712_t *ice = snd_pcm_substream_chip(substream);
680 u8 addr;
681 size_t ptr;
682
683 if (!(snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL) & 1))
684 return 0;
685 if (ice->playback_con_active_buf[substream->number])
686 addr = ICE1712_DSC_ADDR1;
687 else
688 addr = ICE1712_DSC_ADDR0;
689 ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) -
690 ice->playback_con_virt_addr[substream->number];
691 if (ptr == substream->runtime->buffer_size)
692 ptr = 0;
693 return bytes_to_frames(substream->runtime, ptr);
694}
695
696static snd_pcm_uframes_t snd_ice1712_capture_pointer(snd_pcm_substream_t * substream)
697{
698 ice1712_t *ice = snd_pcm_substream_chip(substream);
699 size_t ptr;
700
701 if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1))
702 return 0;
703 ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr;
704 if (ptr == substream->runtime->buffer_size)
705 ptr = 0;
706 return bytes_to_frames(substream->runtime, ptr);
707}
708
709static snd_pcm_hardware_t snd_ice1712_playback =
710{
711 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
712 SNDRV_PCM_INFO_BLOCK_TRANSFER |
713 SNDRV_PCM_INFO_MMAP_VALID |
714 SNDRV_PCM_INFO_PAUSE),
715 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
716 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
717 .rate_min = 4000,
718 .rate_max = 48000,
719 .channels_min = 1,
720 .channels_max = 2,
721 .buffer_bytes_max = (64*1024),
722 .period_bytes_min = 64,
723 .period_bytes_max = (64*1024),
724 .periods_min = 1,
725 .periods_max = 1024,
726 .fifo_size = 0,
727};
728
729static snd_pcm_hardware_t snd_ice1712_playback_ds =
730{
731 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
732 SNDRV_PCM_INFO_BLOCK_TRANSFER |
733 SNDRV_PCM_INFO_MMAP_VALID |
734 SNDRV_PCM_INFO_PAUSE),
735 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
736 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
737 .rate_min = 4000,
738 .rate_max = 48000,
739 .channels_min = 1,
740 .channels_max = 2,
741 .buffer_bytes_max = (128*1024),
742 .period_bytes_min = 64,
743 .period_bytes_max = (128*1024),
744 .periods_min = 2,
745 .periods_max = 2,
746 .fifo_size = 0,
747};
748
749static snd_pcm_hardware_t snd_ice1712_capture =
750{
751 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
752 SNDRV_PCM_INFO_BLOCK_TRANSFER |
753 SNDRV_PCM_INFO_MMAP_VALID),
754 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
755 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
756 .rate_min = 4000,
757 .rate_max = 48000,
758 .channels_min = 1,
759 .channels_max = 2,
760 .buffer_bytes_max = (64*1024),
761 .period_bytes_min = 64,
762 .period_bytes_max = (64*1024),
763 .periods_min = 1,
764 .periods_max = 1024,
765 .fifo_size = 0,
766};
767
768static int snd_ice1712_playback_open(snd_pcm_substream_t * substream)
769{
770 snd_pcm_runtime_t *runtime = substream->runtime;
771 ice1712_t *ice = snd_pcm_substream_chip(substream);
772
773 ice->playback_con_substream = substream;
774 runtime->hw = snd_ice1712_playback;
775 return 0;
776}
777
778static int snd_ice1712_playback_ds_open(snd_pcm_substream_t * substream)
779{
780 snd_pcm_runtime_t *runtime = substream->runtime;
781 ice1712_t *ice = snd_pcm_substream_chip(substream);
782 u32 tmp;
783
784 ice->playback_con_substream_ds[substream->number] = substream;
785 runtime->hw = snd_ice1712_playback_ds;
786 spin_lock_irq(&ice->reg_lock);
787 tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
788 outw(tmp, ICEDS(ice, INTMASK));
789 spin_unlock_irq(&ice->reg_lock);
790 return 0;
791}
792
793static int snd_ice1712_capture_open(snd_pcm_substream_t * substream)
794{
795 snd_pcm_runtime_t *runtime = substream->runtime;
796 ice1712_t *ice = snd_pcm_substream_chip(substream);
797
798 ice->capture_con_substream = substream;
799 runtime->hw = snd_ice1712_capture;
800 runtime->hw.rates = ice->ac97->rates[AC97_RATES_ADC];
801 if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
802 runtime->hw.rate_min = 48000;
803 return 0;
804}
805
806static int snd_ice1712_playback_close(snd_pcm_substream_t * substream)
807{
808 ice1712_t *ice = snd_pcm_substream_chip(substream);
809
810 ice->playback_con_substream = NULL;
811 return 0;
812}
813
814static int snd_ice1712_playback_ds_close(snd_pcm_substream_t * substream)
815{
816 ice1712_t *ice = snd_pcm_substream_chip(substream);
817 u32 tmp;
818
819 spin_lock_irq(&ice->reg_lock);
820 tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
821 outw(tmp, ICEDS(ice, INTMASK));
822 spin_unlock_irq(&ice->reg_lock);
823 ice->playback_con_substream_ds[substream->number] = NULL;
824 return 0;
825}
826
827static int snd_ice1712_capture_close(snd_pcm_substream_t * substream)
828{
829 ice1712_t *ice = snd_pcm_substream_chip(substream);
830
831 ice->capture_con_substream = NULL;
832 return 0;
833}
834
835static snd_pcm_ops_t snd_ice1712_playback_ops = {
836 .open = snd_ice1712_playback_open,
837 .close = snd_ice1712_playback_close,
838 .ioctl = snd_pcm_lib_ioctl,
839 .hw_params = snd_ice1712_hw_params,
840 .hw_free = snd_ice1712_hw_free,
841 .prepare = snd_ice1712_playback_prepare,
842 .trigger = snd_ice1712_playback_trigger,
843 .pointer = snd_ice1712_playback_pointer,
844};
845
846static snd_pcm_ops_t snd_ice1712_playback_ds_ops = {
847 .open = snd_ice1712_playback_ds_open,
848 .close = snd_ice1712_playback_ds_close,
849 .ioctl = snd_pcm_lib_ioctl,
850 .hw_params = snd_ice1712_hw_params,
851 .hw_free = snd_ice1712_hw_free,
852 .prepare = snd_ice1712_playback_ds_prepare,
853 .trigger = snd_ice1712_playback_ds_trigger,
854 .pointer = snd_ice1712_playback_ds_pointer,
855};
856
857static snd_pcm_ops_t snd_ice1712_capture_ops = {
858 .open = snd_ice1712_capture_open,
859 .close = snd_ice1712_capture_close,
860 .ioctl = snd_pcm_lib_ioctl,
861 .hw_params = snd_ice1712_hw_params,
862 .hw_free = snd_ice1712_hw_free,
863 .prepare = snd_ice1712_capture_prepare,
864 .trigger = snd_ice1712_capture_trigger,
865 .pointer = snd_ice1712_capture_pointer,
866};
867
868static void snd_ice1712_pcm_free(snd_pcm_t *pcm)
869{
870 ice1712_t *ice = pcm->private_data;
871 ice->pcm = NULL;
872 snd_pcm_lib_preallocate_free_for_all(pcm);
873}
874
875static int __devinit snd_ice1712_pcm(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
876{
877 snd_pcm_t *pcm;
878 int err;
879
880 if (rpcm)
881 *rpcm = NULL;
882 err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm);
883 if (err < 0)
884 return err;
885
886 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ops);
887 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops);
888
889 pcm->private_data = ice;
890 pcm->private_free = snd_ice1712_pcm_free;
891 pcm->info_flags = 0;
892 strcpy(pcm->name, "ICE1712 consumer");
893 ice->pcm = pcm;
894
895 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
896 snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
897
898 if (rpcm)
899 *rpcm = pcm;
900
901 printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n");
902
903 return 0;
904}
905
906static void snd_ice1712_pcm_free_ds(snd_pcm_t *pcm)
907{
908 ice1712_t *ice = pcm->private_data;
909 ice->pcm_ds = NULL;
910 snd_pcm_lib_preallocate_free_for_all(pcm);
911}
912
913static int __devinit snd_ice1712_pcm_ds(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
914{
915 snd_pcm_t *pcm;
916 int err;
917
918 if (rpcm)
919 *rpcm = NULL;
920 err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm);
921 if (err < 0)
922 return err;
923
924 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops);
925
926 pcm->private_data = ice;
927 pcm->private_free = snd_ice1712_pcm_free_ds;
928 pcm->info_flags = 0;
929 strcpy(pcm->name, "ICE1712 consumer (DS)");
930 ice->pcm_ds = pcm;
931
932 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
933 snd_dma_pci_data(ice->pci), 64*1024, 128*1024);
934
935 if (rpcm)
936 *rpcm = pcm;
937
938 return 0;
939}
940
941/*
942 * PCM code - professional part (multitrack)
943 */
944
945static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000,
946 32000, 44100, 48000, 64000, 88200, 96000 };
947
948static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
949 .count = ARRAY_SIZE(rates),
950 .list = rates,
951 .mask = 0,
952};
953
954static int snd_ice1712_pro_trigger(snd_pcm_substream_t *substream,
955 int cmd)
956{
957 ice1712_t *ice = snd_pcm_substream_chip(substream);
958 switch (cmd) {
959 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
960 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
961 {
962 unsigned int what;
963 unsigned int old;
964 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
965 return -EINVAL;
966 what = ICE1712_PLAYBACK_PAUSE;
967 snd_pcm_trigger_done(substream, substream);
968 spin_lock(&ice->reg_lock);
969 old = inl(ICEMT(ice, PLAYBACK_CONTROL));
970 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
971 old |= what;
972 else
973 old &= ~what;
974 outl(old, ICEMT(ice, PLAYBACK_CONTROL));
975 spin_unlock(&ice->reg_lock);
976 break;
977 }
978 case SNDRV_PCM_TRIGGER_START:
979 case SNDRV_PCM_TRIGGER_STOP:
980 {
981 unsigned int what = 0;
982 unsigned int old;
983 struct list_head *pos;
984 snd_pcm_substream_t *s;
985
986 snd_pcm_group_for_each(pos, substream) {
987 s = snd_pcm_group_substream_entry(pos);
988 if (s == ice->playback_pro_substream) {
989 what |= ICE1712_PLAYBACK_START;
990 snd_pcm_trigger_done(s, substream);
991 } else if (s == ice->capture_pro_substream) {
992 what |= ICE1712_CAPTURE_START_SHADOW;
993 snd_pcm_trigger_done(s, substream);
994 }
995 }
996 spin_lock(&ice->reg_lock);
997 old = inl(ICEMT(ice, PLAYBACK_CONTROL));
998 if (cmd == SNDRV_PCM_TRIGGER_START)
999 old |= what;
1000 else
1001 old &= ~what;
1002 outl(old, ICEMT(ice, PLAYBACK_CONTROL));
1003 spin_unlock(&ice->reg_lock);
1004 break;
1005 }
1006 default:
1007 return -EINVAL;
1008 }
1009 return 0;
1010}
1011
1012/*
1013 */
1014static void snd_ice1712_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
1015{
1016 unsigned long flags;
1017 unsigned char val, old;
1018 unsigned int i;
1019
1020 switch (rate) {
1021 case 8000: val = 6; break;
1022 case 9600: val = 3; break;
1023 case 11025: val = 10; break;
1024 case 12000: val = 2; break;
1025 case 16000: val = 5; break;
1026 case 22050: val = 9; break;
1027 case 24000: val = 1; break;
1028 case 32000: val = 4; break;
1029 case 44100: val = 8; break;
1030 case 48000: val = 0; break;
1031 case 64000: val = 15; break;
1032 case 88200: val = 11; break;
1033 case 96000: val = 7; break;
1034 default:
1035 snd_BUG();
1036 val = 0;
1037 rate = 48000;
1038 break;
1039 }
1040
1041 spin_lock_irqsave(&ice->reg_lock, flags);
1042 if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
1043 ICE1712_PLAYBACK_PAUSE|
1044 ICE1712_PLAYBACK_START)) {
1045 __out:
1046 spin_unlock_irqrestore(&ice->reg_lock, flags);
1047 return;
1048 }
1049 if (!force && is_pro_rate_locked(ice))
1050 goto __out;
1051
1052 old = inb(ICEMT(ice, RATE));
1053 if (!force && old == val)
1054 goto __out;
1055 outb(val, ICEMT(ice, RATE));
1056 spin_unlock_irqrestore(&ice->reg_lock, flags);
1057
1058 if (ice->gpio.set_pro_rate)
1059 ice->gpio.set_pro_rate(ice, rate);
1060 for (i = 0; i < ice->akm_codecs; i++) {
1061 if (ice->akm[i].ops.set_rate_val)
1062 ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
1063 }
1064 if (ice->spdif.ops.setup_rate)
1065 ice->spdif.ops.setup_rate(ice, rate);
1066}
1067
1068static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream)
1069{
1070 ice1712_t *ice = snd_pcm_substream_chip(substream);
1071
1072 ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
1073 spin_lock_irq(&ice->reg_lock);
1074 outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));
1075 outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
1076 outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
1077 spin_unlock_irq(&ice->reg_lock);
1078
1079 return 0;
1080}
1081
1082static int snd_ice1712_playback_pro_hw_params(snd_pcm_substream_t * substream,
1083 snd_pcm_hw_params_t * hw_params)
1084{
1085 ice1712_t *ice = snd_pcm_substream_chip(substream);
1086
1087 snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
1088 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1089}
1090
1091static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream)
1092{
1093 ice1712_t *ice = snd_pcm_substream_chip(substream);
1094
1095 ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
1096 spin_lock_irq(&ice->reg_lock);
1097 outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));
1098 outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));
1099 outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT));
1100 spin_unlock_irq(&ice->reg_lock);
1101 return 0;
1102}
1103
1104static int snd_ice1712_capture_pro_hw_params(snd_pcm_substream_t * substream,
1105 snd_pcm_hw_params_t * hw_params)
1106{
1107 ice1712_t *ice = snd_pcm_substream_chip(substream);
1108
1109 snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
1110 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1111}
1112
1113static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(snd_pcm_substream_t * substream)
1114{
1115 ice1712_t *ice = snd_pcm_substream_chip(substream);
1116 size_t ptr;
1117
1118 if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))
1119 return 0;
1120 ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);
1121 if (ptr == substream->runtime->buffer_size)
1122 ptr = 0;
1123 return bytes_to_frames(substream->runtime, ptr);
1124}
1125
1126static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(snd_pcm_substream_t * substream)
1127{
1128 ice1712_t *ice = snd_pcm_substream_chip(substream);
1129 size_t ptr;
1130
1131 if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))
1132 return 0;
1133 ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2);
1134 if (ptr == substream->runtime->buffer_size)
1135 ptr = 0;
1136 return bytes_to_frames(substream->runtime, ptr);
1137}
1138
1139static snd_pcm_hardware_t snd_ice1712_playback_pro =
1140{
1141 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1142 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1143 SNDRV_PCM_INFO_MMAP_VALID |
1144 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
1145 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1146 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
1147 .rate_min = 4000,
1148 .rate_max = 96000,
1149 .channels_min = 10,
1150 .channels_max = 10,
1151 .buffer_bytes_max = (256*1024),
1152 .period_bytes_min = 10 * 4 * 2,
1153 .period_bytes_max = 131040,
1154 .periods_min = 1,
1155 .periods_max = 1024,
1156 .fifo_size = 0,
1157};
1158
1159static snd_pcm_hardware_t snd_ice1712_capture_pro =
1160{
1161 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1162 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1163 SNDRV_PCM_INFO_MMAP_VALID |
1164 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
1165 .formats = SNDRV_PCM_FMTBIT_S32_LE,
1166 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
1167 .rate_min = 4000,
1168 .rate_max = 96000,
1169 .channels_min = 12,
1170 .channels_max = 12,
1171 .buffer_bytes_max = (256*1024),
1172 .period_bytes_min = 12 * 4 * 2,
1173 .period_bytes_max = 131040,
1174 .periods_min = 1,
1175 .periods_max = 1024,
1176 .fifo_size = 0,
1177};
1178
1179static int snd_ice1712_playback_pro_open(snd_pcm_substream_t * substream)
1180{
1181 snd_pcm_runtime_t *runtime = substream->runtime;
1182 ice1712_t *ice = snd_pcm_substream_chip(substream);
1183
1184 ice->playback_pro_substream = substream;
1185 runtime->hw = snd_ice1712_playback_pro;
1186 snd_pcm_set_sync(substream);
1187 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1188 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1189
1190 if (ice->spdif.ops.open)
1191 ice->spdif.ops.open(ice, substream);
1192
1193 return 0;
1194}
1195
1196static int snd_ice1712_capture_pro_open(snd_pcm_substream_t * substream)
1197{
1198 ice1712_t *ice = snd_pcm_substream_chip(substream);
1199 snd_pcm_runtime_t *runtime = substream->runtime;
1200
1201 ice->capture_pro_substream = substream;
1202 runtime->hw = snd_ice1712_capture_pro;
1203 snd_pcm_set_sync(substream);
1204 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1205 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
1206 return 0;
1207}
1208
1209static int snd_ice1712_playback_pro_close(snd_pcm_substream_t * substream)
1210{
1211 ice1712_t *ice = snd_pcm_substream_chip(substream);
1212
1213 if (PRO_RATE_RESET)
1214 snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
1215 ice->playback_pro_substream = NULL;
1216 if (ice->spdif.ops.close)
1217 ice->spdif.ops.close(ice, substream);
1218
1219 return 0;
1220}
1221
1222static int snd_ice1712_capture_pro_close(snd_pcm_substream_t * substream)
1223{
1224 ice1712_t *ice = snd_pcm_substream_chip(substream);
1225
1226 if (PRO_RATE_RESET)
1227 snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
1228 ice->capture_pro_substream = NULL;
1229 return 0;
1230}
1231
1232static void snd_ice1712_pcm_profi_free(snd_pcm_t *pcm)
1233{
1234 ice1712_t *ice = pcm->private_data;
1235 ice->pcm_pro = NULL;
1236 snd_pcm_lib_preallocate_free_for_all(pcm);
1237}
1238
1239static snd_pcm_ops_t snd_ice1712_playback_pro_ops = {
1240 .open = snd_ice1712_playback_pro_open,
1241 .close = snd_ice1712_playback_pro_close,
1242 .ioctl = snd_pcm_lib_ioctl,
1243 .hw_params = snd_ice1712_playback_pro_hw_params,
1244 .hw_free = snd_ice1712_hw_free,
1245 .prepare = snd_ice1712_playback_pro_prepare,
1246 .trigger = snd_ice1712_pro_trigger,
1247 .pointer = snd_ice1712_playback_pro_pointer,
1248};
1249
1250static snd_pcm_ops_t snd_ice1712_capture_pro_ops = {
1251 .open = snd_ice1712_capture_pro_open,
1252 .close = snd_ice1712_capture_pro_close,
1253 .ioctl = snd_pcm_lib_ioctl,
1254 .hw_params = snd_ice1712_capture_pro_hw_params,
1255 .hw_free = snd_ice1712_hw_free,
1256 .prepare = snd_ice1712_capture_pro_prepare,
1257 .trigger = snd_ice1712_pro_trigger,
1258 .pointer = snd_ice1712_capture_pro_pointer,
1259};
1260
1261static int __devinit snd_ice1712_pcm_profi(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
1262{
1263 snd_pcm_t *pcm;
1264 int err;
1265
1266 if (rpcm)
1267 *rpcm = NULL;
1268 err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm);
1269 if (err < 0)
1270 return err;
1271
1272 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_pro_ops);
1273 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops);
1274
1275 pcm->private_data = ice;
1276 pcm->private_free = snd_ice1712_pcm_profi_free;
1277 pcm->info_flags = 0;
1278 strcpy(pcm->name, "ICE1712 multi");
1279
1280 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1281 snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
1282
1283 ice->pcm_pro = pcm;
1284 if (rpcm)
1285 *rpcm = pcm;
1286
1287 if (ice->cs8427) {
1288 /* assign channels to iec958 */
1289 err = snd_cs8427_iec958_build(ice->cs8427,
1290 pcm->streams[0].substream,
1291 pcm->streams[1].substream);
1292 if (err < 0)
1293 return err;
1294 }
1295
1296 if ((err = snd_ice1712_build_pro_mixer(ice)) < 0)
1297 return err;
1298 return 0;
1299}
1300
1301/*
1302 * Mixer section
1303 */
1304
1305static void snd_ice1712_update_volume(ice1712_t *ice, int index)
1306{
1307 unsigned int vol = ice->pro_volumes[index];
1308 unsigned short val = 0;
1309
1310 val |= (vol & 0x8000) == 0 ? (96 - (vol & 0x7f)) : 0x7f;
1311 val |= ((vol & 0x80000000) == 0 ? (96 - ((vol >> 16) & 0x7f)) : 0x7f) << 8;
1312 outb(index, ICEMT(ice, MONITOR_INDEX));
1313 outw(val, ICEMT(ice, MONITOR_VOLUME));
1314}
1315
1316static int snd_ice1712_pro_mixer_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1317{
1318 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1319 uinfo->count = 2;
1320 uinfo->value.integer.min = 0;
1321 uinfo->value.integer.max = 1;
1322 return 0;
1323}
1324
1325static int snd_ice1712_pro_mixer_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1326{
1327 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1328 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1329
1330 spin_lock_irq(&ice->reg_lock);
1331 ucontrol->value.integer.value[0] = !((ice->pro_volumes[index] >> 15) & 1);
1332 ucontrol->value.integer.value[1] = !((ice->pro_volumes[index] >> 31) & 1);
1333 spin_unlock_irq(&ice->reg_lock);
1334 return 0;
1335}
1336
1337static int snd_ice1712_pro_mixer_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1338{
1339 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1340 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1341 unsigned int nval, change;
1342
1343 nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) |
1344 (ucontrol->value.integer.value[1] ? 0 : 0x80000000);
1345 spin_lock_irq(&ice->reg_lock);
1346 nval |= ice->pro_volumes[index] & ~0x80008000;
1347 change = nval != ice->pro_volumes[index];
1348 ice->pro_volumes[index] = nval;
1349 snd_ice1712_update_volume(ice, index);
1350 spin_unlock_irq(&ice->reg_lock);
1351 return change;
1352}
1353
1354static int snd_ice1712_pro_mixer_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1355{
1356 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1357 uinfo->count = 2;
1358 uinfo->value.integer.min = 0;
1359 uinfo->value.integer.max = 96;
1360 return 0;
1361}
1362
1363static int snd_ice1712_pro_mixer_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1364{
1365 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1366 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1367
1368 spin_lock_irq(&ice->reg_lock);
1369 ucontrol->value.integer.value[0] = (ice->pro_volumes[index] >> 0) & 127;
1370 ucontrol->value.integer.value[1] = (ice->pro_volumes[index] >> 16) & 127;
1371 spin_unlock_irq(&ice->reg_lock);
1372 return 0;
1373}
1374
1375static int snd_ice1712_pro_mixer_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1376{
1377 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1378 int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
1379 unsigned int nval, change;
1380
1381 nval = (ucontrol->value.integer.value[0] & 127) |
1382 ((ucontrol->value.integer.value[1] & 127) << 16);
1383 spin_lock_irq(&ice->reg_lock);
1384 nval |= ice->pro_volumes[index] & ~0x007f007f;
1385 change = nval != ice->pro_volumes[index];
1386 ice->pro_volumes[index] = nval;
1387 snd_ice1712_update_volume(ice, index);
1388 spin_unlock_irq(&ice->reg_lock);
1389 return change;
1390}
1391
1392
1393static snd_kcontrol_new_t snd_ice1712_multi_playback_ctrls[] __devinitdata = {
1394 {
1395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1396 .name = "Multi Playback Switch",
1397 .info = snd_ice1712_pro_mixer_switch_info,
1398 .get = snd_ice1712_pro_mixer_switch_get,
1399 .put = snd_ice1712_pro_mixer_switch_put,
1400 .private_value = 0,
1401 .count = 10,
1402 },
1403 {
1404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1405 .name = "Multi Playback Volume",
1406 .info = snd_ice1712_pro_mixer_volume_info,
1407 .get = snd_ice1712_pro_mixer_volume_get,
1408 .put = snd_ice1712_pro_mixer_volume_put,
1409 .private_value = 0,
1410 .count = 10,
1411 },
1412};
1413
1414static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_switch __devinitdata = {
1415 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1416 .name = "H/W Multi Capture Switch",
1417 .info = snd_ice1712_pro_mixer_switch_info,
1418 .get = snd_ice1712_pro_mixer_switch_get,
1419 .put = snd_ice1712_pro_mixer_switch_put,
1420 .private_value = 10,
1421};
1422
1423static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = {
1424 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1425 .name = "IEC958 Multi Capture Switch",
1426 .info = snd_ice1712_pro_mixer_switch_info,
1427 .get = snd_ice1712_pro_mixer_switch_get,
1428 .put = snd_ice1712_pro_mixer_switch_put,
1429 .private_value = 18,
1430 .count = 2,
1431};
1432
1433static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_volume __devinitdata = {
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "H/W Multi Capture Volume",
1436 .info = snd_ice1712_pro_mixer_volume_info,
1437 .get = snd_ice1712_pro_mixer_volume_get,
1438 .put = snd_ice1712_pro_mixer_volume_put,
1439 .private_value = 10,
1440};
1441
1442static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = {
1443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1444 .name = "IEC958 Multi Capture Volume",
1445 .info = snd_ice1712_pro_mixer_volume_info,
1446 .get = snd_ice1712_pro_mixer_volume_get,
1447 .put = snd_ice1712_pro_mixer_volume_put,
1448 .private_value = 18,
1449 .count = 2,
1450};
1451
1452static int __devinit snd_ice1712_build_pro_mixer(ice1712_t *ice)
1453{
1454 snd_card_t * card = ice->card;
1455 unsigned int idx;
1456 int err;
1457
1458 /* multi-channel mixer */
1459 for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_multi_playback_ctrls); idx++) {
1460 err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_playback_ctrls[idx], ice));
1461 if (err < 0)
1462 return err;
1463 }
1464
1465 if (ice->num_total_adcs > 0) {
1466 snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_switch;
1467 tmp.count = ice->num_total_adcs;
1468 err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
1469 if (err < 0)
1470 return err;
1471 }
1472
1473 err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_switch, ice));
1474 if (err < 0)
1475 return err;
1476
1477 if (ice->num_total_adcs > 0) {
1478 snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_volume;
1479 tmp.count = ice->num_total_adcs;
1480 err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
1481 if (err < 0)
1482 return err;
1483 }
1484
1485 err = snd_ctl_add(card, snd_ctl_new1(&snd_ice1712_multi_capture_spdif_volume, ice));
1486 if (err < 0)
1487 return err;
1488
1489 /* initialize volumes */
1490 for (idx = 0; idx < 10; idx++) {
1491 ice->pro_volumes[idx] = 0x80008000; /* mute */
1492 snd_ice1712_update_volume(ice, idx);
1493 }
1494 for (idx = 10; idx < 10 + ice->num_total_adcs; idx++) {
1495 ice->pro_volumes[idx] = 0x80008000; /* mute */
1496 snd_ice1712_update_volume(ice, idx);
1497 }
1498 for (idx = 18; idx < 20; idx++) {
1499 ice->pro_volumes[idx] = 0x80008000; /* mute */
1500 snd_ice1712_update_volume(ice, idx);
1501 }
1502 return 0;
1503}
1504
1505static void snd_ice1712_mixer_free_ac97(ac97_t *ac97)
1506{
1507 ice1712_t *ice = ac97->private_data;
1508 ice->ac97 = NULL;
1509}
1510
1511static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
1512{
1513 int err, bus_num = 0;
1514 ac97_template_t ac97;
1515 ac97_bus_t *pbus;
1516 static ac97_bus_ops_t con_ops = {
1517 .write = snd_ice1712_ac97_write,
1518 .read = snd_ice1712_ac97_read,
1519 };
1520 static ac97_bus_ops_t pro_ops = {
1521 .write = snd_ice1712_pro_ac97_write,
1522 .read = snd_ice1712_pro_ac97_read,
1523 };
1524
1525 if (ice_has_con_ac97(ice)) {
1526 if ((err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus)) < 0)
1527 return err;
1528 memset(&ac97, 0, sizeof(ac97));
1529 ac97.private_data = ice;
1530 ac97.private_free = snd_ice1712_mixer_free_ac97;
1531 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
1532 printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
1533 else {
1534 if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)
1535 return err;
1536 return 0;
1537 }
1538 }
1539
1540 if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) {
1541 if ((err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus)) < 0)
1542 return err;
1543 memset(&ac97, 0, sizeof(ac97));
1544 ac97.private_data = ice;
1545 ac97.private_free = snd_ice1712_mixer_free_ac97;
1546 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
1547 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
1548 else
1549 return 0;
1550 }
1551 /* I2S mixer only */
1552 strcat(ice->card->mixername, "ICE1712 - multitrack");
1553 return 0;
1554}
1555
1556/*
1557 *
1558 */
1559
1560static inline unsigned int eeprom_double(ice1712_t *ice, int idx)
1561{
1562 return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
1563}
1564
1565static void snd_ice1712_proc_read(snd_info_entry_t *entry,
1566 snd_info_buffer_t * buffer)
1567{
1568 ice1712_t *ice = entry->private_data;
1569 unsigned int idx;
1570
1571 snd_iprintf(buffer, "%s\n\n", ice->card->longname);
1572 snd_iprintf(buffer, "EEPROM:\n");
1573
1574 snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor);
1575 snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size);
1576 snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version);
1577 snd_iprintf(buffer, " Codec : 0x%x\n", ice->eeprom.data[ICE_EEP1_CODEC]);
1578 snd_iprintf(buffer, " ACLink : 0x%x\n", ice->eeprom.data[ICE_EEP1_ACLINK]);
1579 snd_iprintf(buffer, " I2S ID : 0x%x\n", ice->eeprom.data[ICE_EEP1_I2SID]);
1580 snd_iprintf(buffer, " S/PDIF : 0x%x\n", ice->eeprom.data[ICE_EEP1_SPDIF]);
1581 snd_iprintf(buffer, " GPIO mask : 0x%x\n", ice->eeprom.gpiomask);
1582 snd_iprintf(buffer, " GPIO state : 0x%x\n", ice->eeprom.gpiostate);
1583 snd_iprintf(buffer, " GPIO direction : 0x%x\n", ice->eeprom.gpiodir);
1584 snd_iprintf(buffer, " AC'97 main : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_MAIN_LO));
1585 snd_iprintf(buffer, " AC'97 pcm : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_PCM_LO));
1586 snd_iprintf(buffer, " AC'97 record : 0x%x\n", eeprom_double(ice, ICE_EEP1_AC97_REC_LO));
1587 snd_iprintf(buffer, " AC'97 record src : 0x%x\n", ice->eeprom.data[ICE_EEP1_AC97_RECSRC]);
1588 for (idx = 0; idx < 4; idx++)
1589 snd_iprintf(buffer, " DAC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_DAC_ID + idx]);
1590 for (idx = 0; idx < 4; idx++)
1591 snd_iprintf(buffer, " ADC ID #%i : 0x%x\n", idx, ice->eeprom.data[ICE_EEP1_ADC_ID + idx]);
1592 for (idx = 0x1c; idx < ice->eeprom.size; idx++)
1593 snd_iprintf(buffer, " Extra #%02i : 0x%x\n", idx, ice->eeprom.data[idx]);
1594
1595 snd_iprintf(buffer, "\nRegisters:\n");
1596 snd_iprintf(buffer, " PSDOUT03 : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03)));
1597 snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE)));
1598 snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT)));
1599 snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
1600}
1601
1602static void __devinit snd_ice1712_proc_init(ice1712_t * ice)
1603{
1604 snd_info_entry_t *entry;
1605
1606 if (! snd_card_proc_new(ice->card, "ice1712", &entry))
1607 snd_info_set_text_ops(entry, ice, 1024, snd_ice1712_proc_read);
1608}
1609
1610/*
1611 *
1612 */
1613
1614static int snd_ice1712_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1615{
1616 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1617 uinfo->count = sizeof(ice1712_eeprom_t);
1618 return 0;
1619}
1620
1621static int snd_ice1712_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1622{
1623 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1624
1625 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
1626 return 0;
1627}
1628
1629static snd_kcontrol_new_t snd_ice1712_eeprom __devinitdata = {
1630 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1631 .name = "ICE1712 EEPROM",
1632 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1633 .info = snd_ice1712_eeprom_info,
1634 .get = snd_ice1712_eeprom_get
1635};
1636
1637/*
1638 */
1639static int snd_ice1712_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1640{
1641 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1642 uinfo->count = 1;
1643 return 0;
1644}
1645
1646static int snd_ice1712_spdif_default_get(snd_kcontrol_t * kcontrol,
1647 snd_ctl_elem_value_t * ucontrol)
1648{
1649 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1650 if (ice->spdif.ops.default_get)
1651 ice->spdif.ops.default_get(ice, ucontrol);
1652 return 0;
1653}
1654
1655static int snd_ice1712_spdif_default_put(snd_kcontrol_t * kcontrol,
1656 snd_ctl_elem_value_t * ucontrol)
1657{
1658 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1659 if (ice->spdif.ops.default_put)
1660 return ice->spdif.ops.default_put(ice, ucontrol);
1661 return 0;
1662}
1663
1664static snd_kcontrol_new_t snd_ice1712_spdif_default __devinitdata =
1665{
1666 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1667 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1668 .info = snd_ice1712_spdif_info,
1669 .get = snd_ice1712_spdif_default_get,
1670 .put = snd_ice1712_spdif_default_put
1671};
1672
1673static int snd_ice1712_spdif_maskc_get(snd_kcontrol_t * kcontrol,
1674 snd_ctl_elem_value_t * ucontrol)
1675{
1676 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1677 if (ice->spdif.ops.default_get) {
1678 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1679 IEC958_AES0_PROFESSIONAL |
1680 IEC958_AES0_CON_NOT_COPYRIGHT |
1681 IEC958_AES0_CON_EMPHASIS;
1682 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
1683 IEC958_AES1_CON_CATEGORY;
1684 ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
1685 } else {
1686 ucontrol->value.iec958.status[0] = 0xff;
1687 ucontrol->value.iec958.status[1] = 0xff;
1688 ucontrol->value.iec958.status[2] = 0xff;
1689 ucontrol->value.iec958.status[3] = 0xff;
1690 ucontrol->value.iec958.status[4] = 0xff;
1691 }
1692 return 0;
1693}
1694
1695static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol,
1696 snd_ctl_elem_value_t * ucontrol)
1697{
1698 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1699 if (ice->spdif.ops.default_get) {
1700 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1701 IEC958_AES0_PROFESSIONAL |
1702 IEC958_AES0_PRO_FS |
1703 IEC958_AES0_PRO_EMPHASIS;
1704 ucontrol->value.iec958.status[1] = IEC958_AES1_PRO_MODE;
1705 } else {
1706 ucontrol->value.iec958.status[0] = 0xff;
1707 ucontrol->value.iec958.status[1] = 0xff;
1708 ucontrol->value.iec958.status[2] = 0xff;
1709 ucontrol->value.iec958.status[3] = 0xff;
1710 ucontrol->value.iec958.status[4] = 0xff;
1711 }
1712 return 0;
1713}
1714
1715static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata =
1716{
1717 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1718 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1719 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1720 .info = snd_ice1712_spdif_info,
1721 .get = snd_ice1712_spdif_maskc_get,
1722};
1723
1724static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata =
1725{
1726 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1727 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1728 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
1729 .info = snd_ice1712_spdif_info,
1730 .get = snd_ice1712_spdif_maskp_get,
1731};
1732
1733static int snd_ice1712_spdif_stream_get(snd_kcontrol_t * kcontrol,
1734 snd_ctl_elem_value_t * ucontrol)
1735{
1736 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1737 if (ice->spdif.ops.stream_get)
1738 ice->spdif.ops.stream_get(ice, ucontrol);
1739 return 0;
1740}
1741
1742static int snd_ice1712_spdif_stream_put(snd_kcontrol_t * kcontrol,
1743 snd_ctl_elem_value_t * ucontrol)
1744{
1745 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1746 if (ice->spdif.ops.stream_put)
1747 return ice->spdif.ops.stream_put(ice, ucontrol);
1748 return 0;
1749}
1750
1751static snd_kcontrol_new_t snd_ice1712_spdif_stream __devinitdata =
1752{
1753 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
1754 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1755 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
1756 .info = snd_ice1712_spdif_info,
1757 .get = snd_ice1712_spdif_stream_get,
1758 .put = snd_ice1712_spdif_stream_put
1759};
1760
1761int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1762{
1763 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1764 uinfo->count = 1;
1765 uinfo->value.integer.min = 0;
1766 uinfo->value.integer.max = 1;
1767 return 0;
1768}
1769
1770int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1771{
1772 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1773 unsigned char mask = kcontrol->private_value & 0xff;
1774 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
1775
1776 snd_ice1712_save_gpio_status(ice);
1777 ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
1778 snd_ice1712_restore_gpio_status(ice);
1779 return 0;
1780}
1781
1782int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1783{
1784 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1785 unsigned char mask = kcontrol->private_value & 0xff;
1786 int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
1787 unsigned int val, nval;
1788
1789 if (kcontrol->private_value & (1 << 31))
1790 return -EPERM;
1791 nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert;
1792 snd_ice1712_save_gpio_status(ice);
1793 val = snd_ice1712_gpio_read(ice);
1794 nval |= val & ~mask;
1795 if (val != nval)
1796 snd_ice1712_gpio_write(ice, nval);
1797 snd_ice1712_restore_gpio_status(ice);
1798 return val != nval;
1799}
1800
1801/*
1802 * rate
1803 */
1804static int snd_ice1712_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1805{
1806 static char *texts[] = {
1807 "8000", /* 0: 6 */
1808 "9600", /* 1: 3 */
1809 "11025", /* 2: 10 */
1810 "12000", /* 3: 2 */
1811 "16000", /* 4: 5 */
1812 "22050", /* 5: 9 */
1813 "24000", /* 6: 1 */
1814 "32000", /* 7: 4 */
1815 "44100", /* 8: 8 */
1816 "48000", /* 9: 0 */
1817 "64000", /* 10: 15 */
1818 "88200", /* 11: 11 */
1819 "96000", /* 12: 7 */
1820 "IEC958 Input", /* 13: -- */
1821 };
1822 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1823 uinfo->count = 1;
1824 uinfo->value.enumerated.items = 14;
1825 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1826 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1827 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1828 return 0;
1829}
1830
1831static int snd_ice1712_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1832{
1833 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1834 static unsigned char xlate[16] = {
1835 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
1836 };
1837 unsigned char val;
1838
1839 spin_lock_irq(&ice->reg_lock);
1840 if (is_spdif_master(ice)) {
1841 ucontrol->value.enumerated.item[0] = 13;
1842 } else {
1843 val = xlate[inb(ICEMT(ice, RATE)) & 15];
1844 if (val == 255) {
1845 snd_BUG();
1846 val = 0;
1847 }
1848 ucontrol->value.enumerated.item[0] = val;
1849 }
1850 spin_unlock_irq(&ice->reg_lock);
1851 return 0;
1852}
1853
1854static int snd_ice1712_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1855{
1856 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1857 static unsigned int xrate[13] = {
1858 8000, 9600, 11025, 12000, 1600, 22050, 24000,
1859 32000, 44100, 48000, 64000, 88200, 96000
1860 };
1861 unsigned char oval;
1862 int change = 0;
1863
1864 spin_lock_irq(&ice->reg_lock);
1865 oval = inb(ICEMT(ice, RATE));
1866 if (ucontrol->value.enumerated.item[0] == 13) {
1867 outb(oval | ICE1712_SPDIF_MASTER, ICEMT(ice, RATE));
1868 } else {
1869 PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];
1870 spin_unlock_irq(&ice->reg_lock);
1871 snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);
1872 spin_lock_irq(&ice->reg_lock);
1873 }
1874 change = inb(ICEMT(ice, RATE)) != oval;
1875 spin_unlock_irq(&ice->reg_lock);
1876
1877 if ((oval & ICE1712_SPDIF_MASTER) != (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) {
1878 /* change CS8427 clock source too */
1879 if (ice->cs8427) {
1880 snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice));
1881 }
1882 /* notify ak4524 chip as well */
1883 if (is_spdif_master(ice)) {
1884 unsigned int i;
1885 for (i = 0; i < ice->akm_codecs; i++) {
1886 if (ice->akm[i].ops.set_rate_val)
1887 ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
1888 }
1889 }
1890 }
1891
1892 return change;
1893}
1894
1895static snd_kcontrol_new_t snd_ice1712_pro_internal_clock __devinitdata = {
1896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1897 .name = "Multi Track Internal Clock",
1898 .info = snd_ice1712_pro_internal_clock_info,
1899 .get = snd_ice1712_pro_internal_clock_get,
1900 .put = snd_ice1712_pro_internal_clock_put
1901};
1902
1903static int snd_ice1712_pro_internal_clock_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1904{
1905 static char *texts[] = {
1906 "8000", /* 0: 6 */
1907 "9600", /* 1: 3 */
1908 "11025", /* 2: 10 */
1909 "12000", /* 3: 2 */
1910 "16000", /* 4: 5 */
1911 "22050", /* 5: 9 */
1912 "24000", /* 6: 1 */
1913 "32000", /* 7: 4 */
1914 "44100", /* 8: 8 */
1915 "48000", /* 9: 0 */
1916 "64000", /* 10: 15 */
1917 "88200", /* 11: 11 */
1918 "96000", /* 12: 7 */
1919 // "IEC958 Input", /* 13: -- */
1920 };
1921 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1922 uinfo->count = 1;
1923 uinfo->value.enumerated.items = 13;
1924 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1925 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1926 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1927 return 0;
1928}
1929
1930static int snd_ice1712_pro_internal_clock_default_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1931{
1932 int val;
1933 static unsigned int xrate[13] = {
1934 8000, 9600, 11025, 12000, 1600, 22050, 24000,
1935 32000, 44100, 48000, 64000, 88200, 96000
1936 };
1937
1938 for (val = 0; val < 13; val++) {
1939 if (xrate[val] == PRO_RATE_DEFAULT)
1940 break;
1941 }
1942
1943 ucontrol->value.enumerated.item[0] = val;
1944 return 0;
1945}
1946
1947static int snd_ice1712_pro_internal_clock_default_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1948{
1949 static unsigned int xrate[13] = {
1950 8000, 9600, 11025, 12000, 1600, 22050, 24000,
1951 32000, 44100, 48000, 64000, 88200, 96000
1952 };
1953 unsigned char oval;
1954 int change = 0;
1955
1956 oval = PRO_RATE_DEFAULT;
1957 PRO_RATE_DEFAULT = xrate[ucontrol->value.integer.value[0] % 13];
1958 change = PRO_RATE_DEFAULT != oval;
1959
1960 return change;
1961}
1962
1963static snd_kcontrol_new_t snd_ice1712_pro_internal_clock_default __devinitdata = {
1964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1965 .name = "Multi Track Internal Clock Default",
1966 .info = snd_ice1712_pro_internal_clock_default_info,
1967 .get = snd_ice1712_pro_internal_clock_default_get,
1968 .put = snd_ice1712_pro_internal_clock_default_put
1969};
1970
1971static int snd_ice1712_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1972{
1973 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1974 uinfo->count = 1;
1975 uinfo->value.integer.min = 0;
1976 uinfo->value.integer.max = 1;
1977 return 0;
1978}
1979
1980static int snd_ice1712_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1981{
1982 ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
1983 return 0;
1984}
1985
1986static int snd_ice1712_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1987{
1988 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1989 int change = 0, nval;
1990
1991 nval = ucontrol->value.integer.value[0] ? 1 : 0;
1992 spin_lock_irq(&ice->reg_lock);
1993 change = PRO_RATE_LOCKED != nval;
1994 PRO_RATE_LOCKED = nval;
1995 spin_unlock_irq(&ice->reg_lock);
1996 return change;
1997}
1998
1999static snd_kcontrol_new_t snd_ice1712_pro_rate_locking __devinitdata = {
2000 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2001 .name = "Multi Track Rate Locking",
2002 .info = snd_ice1712_pro_rate_locking_info,
2003 .get = snd_ice1712_pro_rate_locking_get,
2004 .put = snd_ice1712_pro_rate_locking_put
2005};
2006
2007static int snd_ice1712_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2008{
2009 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2010 uinfo->count = 1;
2011 uinfo->value.integer.min = 0;
2012 uinfo->value.integer.max = 1;
2013 return 0;
2014}
2015
2016static int snd_ice1712_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2017{
2018 ucontrol->value.integer.value[0] = PRO_RATE_RESET;
2019 return 0;
2020}
2021
2022static int snd_ice1712_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2023{
2024 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2025 int change = 0, nval;
2026
2027 nval = ucontrol->value.integer.value[0] ? 1 : 0;
2028 spin_lock_irq(&ice->reg_lock);
2029 change = PRO_RATE_RESET != nval;
2030 PRO_RATE_RESET = nval;
2031 spin_unlock_irq(&ice->reg_lock);
2032 return change;
2033}
2034
2035static snd_kcontrol_new_t snd_ice1712_pro_rate_reset __devinitdata = {
2036 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2037 .name = "Multi Track Rate Reset",
2038 .info = snd_ice1712_pro_rate_reset_info,
2039 .get = snd_ice1712_pro_rate_reset_get,
2040 .put = snd_ice1712_pro_rate_reset_put
2041};
2042
2043/*
2044 * routing
2045 */
2046static int snd_ice1712_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2047{
2048 static char *texts[] = {
2049 "PCM Out", /* 0 */
2050 "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */
2051 "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */
2052 "IEC958 In L", "IEC958 In R", /* 9-10 */
2053 "Digital Mixer", /* 11 - optional */
2054 };
2055
2056 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2057 uinfo->count = 1;
2058 uinfo->value.enumerated.items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11;
2059 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2060 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2061 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2062 return 0;
2063}
2064
2065static int snd_ice1712_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2066{
2067 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2068 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2069 unsigned int val, cval;
2070
2071 spin_lock_irq(&ice->reg_lock);
2072 val = inw(ICEMT(ice, ROUTE_PSDOUT03));
2073 cval = inl(ICEMT(ice, ROUTE_CAPTURE));
2074 spin_unlock_irq(&ice->reg_lock);
2075
2076 val >>= ((idx % 2) * 8) + ((idx / 2) * 2);
2077 val &= 3;
2078 cval >>= ((idx / 2) * 8) + ((idx % 2) * 4);
2079 if (val == 1 && idx < 2)
2080 ucontrol->value.enumerated.item[0] = 11;
2081 else if (val == 2)
2082 ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
2083 else if (val == 3)
2084 ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
2085 else
2086 ucontrol->value.enumerated.item[0] = 0;
2087 return 0;
2088}
2089
2090static int snd_ice1712_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2091{
2092 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2093 int change, shift;
2094 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2095 unsigned int val, old_val, nval;
2096
2097 /* update PSDOUT */
2098 if (ucontrol->value.enumerated.item[0] >= 11)
2099 nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */
2100 else if (ucontrol->value.enumerated.item[0] >= 9)
2101 nval = 3; /* spdif in */
2102 else if (ucontrol->value.enumerated.item[0] >= 1)
2103 nval = 2; /* analog in */
2104 else
2105 nval = 0; /* pcm */
2106 shift = ((idx % 2) * 8) + ((idx / 2) * 2);
2107 spin_lock_irq(&ice->reg_lock);
2108 val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));
2109 val &= ~(0x03 << shift);
2110 val |= nval << shift;
2111 change = val != old_val;
2112 if (change)
2113 outw(val, ICEMT(ice, ROUTE_PSDOUT03));
2114 spin_unlock_irq(&ice->reg_lock);
2115 if (nval < 2) /* dig mixer of pcm */
2116 return change;
2117
2118 /* update CAPTURE */
2119 spin_lock_irq(&ice->reg_lock);
2120 val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));
2121 shift = ((idx / 2) * 8) + ((idx % 2) * 4);
2122 if (nval == 2) { /* analog in */
2123 nval = ucontrol->value.enumerated.item[0] - 1;
2124 val &= ~(0x07 << shift);
2125 val |= nval << shift;
2126 } else { /* spdif in */
2127 nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
2128 val &= ~(0x08 << shift);
2129 val |= nval << shift;
2130 }
2131 if (val != old_val) {
2132 change = 1;
2133 outl(val, ICEMT(ice, ROUTE_CAPTURE));
2134 }
2135 spin_unlock_irq(&ice->reg_lock);
2136 return change;
2137}
2138
2139static int snd_ice1712_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2140{
2141 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2142 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2143 unsigned int val, cval;
2144 val = inw(ICEMT(ice, ROUTE_SPDOUT));
2145 cval = (val >> (idx * 4 + 8)) & 0x0f;
2146 val = (val >> (idx * 2)) & 0x03;
2147 if (val == 1)
2148 ucontrol->value.enumerated.item[0] = 11;
2149 else if (val == 2)
2150 ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
2151 else if (val == 3)
2152 ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
2153 else
2154 ucontrol->value.enumerated.item[0] = 0;
2155 return 0;
2156}
2157
2158static int snd_ice1712_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
2159{
2160 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2161 int change, shift;
2162 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2163 unsigned int val, old_val, nval;
2164
2165 /* update SPDOUT */
2166 spin_lock_irq(&ice->reg_lock);
2167 val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
2168 if (ucontrol->value.enumerated.item[0] >= 11)
2169 nval = 1;
2170 else if (ucontrol->value.enumerated.item[0] >= 9)
2171 nval = 3;
2172 else if (ucontrol->value.enumerated.item[0] >= 1)
2173 nval = 2;
2174 else
2175 nval = 0;
2176 shift = idx * 2;
2177 val &= ~(0x03 << shift);
2178 val |= nval << shift;
2179 shift = idx * 4 + 8;
2180 if (nval == 2) {
2181 nval = ucontrol->value.enumerated.item[0] - 1;
2182 val &= ~(0x07 << shift);
2183 val |= nval << shift;
2184 } else if (nval == 3) {
2185 nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
2186 val &= ~(0x08 << shift);
2187 val |= nval << shift;
2188 }
2189 change = val != old_val;
2190 if (change)
2191 outw(val, ICEMT(ice, ROUTE_SPDOUT));
2192 spin_unlock_irq(&ice->reg_lock);
2193 return change;
2194}
2195
2196static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = {
2197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2198 .name = "H/W Playback Route",
2199 .info = snd_ice1712_pro_route_info,
2200 .get = snd_ice1712_pro_route_analog_get,
2201 .put = snd_ice1712_pro_route_analog_put,
2202};
2203
2204static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = {
2205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2206 .name = "IEC958 Playback Route",
2207 .info = snd_ice1712_pro_route_info,
2208 .get = snd_ice1712_pro_route_spdif_get,
2209 .put = snd_ice1712_pro_route_spdif_put,
2210 .count = 2,
2211};
2212
2213
2214static int snd_ice1712_pro_volume_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2215{
2216 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2217 uinfo->count = 1;
2218 uinfo->value.integer.min = 0;
2219 uinfo->value.integer.max = 255;
2220 return 0;
2221}
2222
2223static int snd_ice1712_pro_volume_rate_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2224{
2225 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2226
2227 ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
2228 return 0;
2229}
2230
2231static int snd_ice1712_pro_volume_rate_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2232{
2233 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2234 int change;
2235
2236 spin_lock_irq(&ice->reg_lock);
2237 change = inb(ICEMT(ice, MONITOR_RATE)) != ucontrol->value.integer.value[0];
2238 outb(ucontrol->value.integer.value[0], ICEMT(ice, MONITOR_RATE));
2239 spin_unlock_irq(&ice->reg_lock);
2240 return change;
2241}
2242
2243static snd_kcontrol_new_t snd_ice1712_mixer_pro_volume_rate __devinitdata = {
2244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2245 .name = "Multi Track Volume Rate",
2246 .info = snd_ice1712_pro_volume_rate_info,
2247 .get = snd_ice1712_pro_volume_rate_get,
2248 .put = snd_ice1712_pro_volume_rate_put
2249};
2250
2251static int snd_ice1712_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
2252{
2253 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2254 uinfo->count = 22;
2255 uinfo->value.integer.min = 0;
2256 uinfo->value.integer.max = 255;
2257 return 0;
2258}
2259
2260static int snd_ice1712_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
2261{
2262 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
2263 int idx;
2264
2265 spin_lock_irq(&ice->reg_lock);
2266 for (idx = 0; idx < 22; idx++) {
2267 outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
2268 ucontrol->value.integer.value[idx] = inb(ICEMT(ice, MONITOR_PEAKDATA));
2269 }
2270 spin_unlock_irq(&ice->reg_lock);
2271 return 0;
2272}
2273
2274static snd_kcontrol_new_t snd_ice1712_mixer_pro_peak __devinitdata = {
2275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2276 .name = "Multi Track Peak",
2277 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2278 .info = snd_ice1712_pro_peak_info,
2279 .get = snd_ice1712_pro_peak_get
2280};
2281
2282/*
2283 *
2284 */
2285
2286/*
2287 * list of available boards
2288 */
2289static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
2290 snd_ice1712_hoontech_cards,
2291 snd_ice1712_delta_cards,
2292 snd_ice1712_ews_cards,
2293 NULL,
2294};
2295
2296static unsigned char __devinit snd_ice1712_read_i2c(ice1712_t *ice,
2297 unsigned char dev,
2298 unsigned char addr)
2299{
2300 long t = 0x10000;
2301
2302 outb(addr, ICEREG(ice, I2C_BYTE_ADDR));
2303 outb(dev & ~ICE1712_I2C_WRITE, ICEREG(ice, I2C_DEV_ADDR));
2304 while (t-- > 0 && (inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_BUSY)) ;
2305 return inb(ICEREG(ice, I2C_DATA));
2306}
2307
2308static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice, const char *modelname)
2309{
2310 int dev = 0xa0; /* EEPROM device address */
2311 unsigned int i, size;
2312 struct snd_ice1712_card_info **tbl, *c;
2313
2314 if (! modelname || ! *modelname) {
2315 ice->eeprom.subvendor = 0;
2316 if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0)
2317 ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
2318 (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) |
2319 (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) |
2320 (snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
2321 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
2322 /* invalid subvendor from EEPROM, try the PCI subststem ID instead */
2323 u16 vendor, device;
2324 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
2325 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
2326 ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
2327 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
2328 printk(KERN_ERR "ice1712: No valid ID is found\n");
2329 return -ENXIO;
2330 }
2331 }
2332 }
2333 for (tbl = card_tables; *tbl; tbl++) {
2334 for (c = *tbl; c->subvendor; c++) {
2335 if (modelname && c->model && ! strcmp(modelname, c->model)) {
2336 printk(KERN_INFO "ice1712: Using board model %s\n", c->name);
2337 ice->eeprom.subvendor = c->subvendor;
2338 } else if (c->subvendor != ice->eeprom.subvendor)
2339 continue;
2340 if (! c->eeprom_size || ! c->eeprom_data)
2341 goto found;
2342 /* if the EEPROM is given by the driver, use it */
2343 snd_printdd("using the defined eeprom..\n");
2344 ice->eeprom.version = 1;
2345 ice->eeprom.size = c->eeprom_size + 6;
2346 memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
2347 goto read_skipped;
2348 }
2349 }
2350 printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
2351
2352 found:
2353 ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
2354 if (ice->eeprom.size < 6)
2355 ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
2356 else if (ice->eeprom.size > 32) {
2357 snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
2358 return -EIO;
2359 }
2360 ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
2361 if (ice->eeprom.version != 1) {
2362 snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
2363 /* return -EIO; */
2364 }
2365 size = ice->eeprom.size - 6;
2366 for (i = 0; i < size; i++)
2367 ice->eeprom.data[i] = snd_ice1712_read_i2c(ice, dev, i + 6);
2368
2369 read_skipped:
2370 ice->eeprom.gpiomask = ice->eeprom.data[ICE_EEP1_GPIO_MASK];
2371 ice->eeprom.gpiostate = ice->eeprom.data[ICE_EEP1_GPIO_STATE];
2372 ice->eeprom.gpiodir = ice->eeprom.data[ICE_EEP1_GPIO_DIR];
2373
2374 return 0;
2375}
2376
2377
2378
2379static int __devinit snd_ice1712_chip_init(ice1712_t *ice)
2380{
2381 outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));
2382 udelay(200);
2383 outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
2384 udelay(200);
2385 pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]);
2386 pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]);
2387 pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]);
2388 pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]);
2389 if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
2390 ice->gpio.write_mask = ice->eeprom.gpiomask;
2391 ice->gpio.direction = ice->eeprom.gpiodir;
2392 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
2393 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
2394 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
2395 } else {
2396 ice->gpio.write_mask = 0xc0;
2397 ice->gpio.direction = 0xff;
2398 snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0);
2399 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff);
2400 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_STDSP24_CLOCK_BIT);
2401 }
2402 snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0);
2403 if (!(ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) {
2404 outb(ICE1712_AC97_WARM, ICEREG(ice, AC97_CMD));
2405 udelay(100);
2406 outb(0, ICEREG(ice, AC97_CMD));
2407 udelay(200);
2408 snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0);
2409 }
2410 snd_ice1712_set_pro_rate(ice, 48000, 1);
2411
2412 return 0;
2413}
2414
2415int __devinit snd_ice1712_spdif_build_controls(ice1712_t *ice)
2416{
2417 int err;
2418 snd_kcontrol_t *kctl;
2419
2420 snd_assert(ice->pcm_pro != NULL, return -EIO);
2421 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
2422 if (err < 0)
2423 return err;
2424 kctl->id.device = ice->pcm_pro->device;
2425 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice));
2426 if (err < 0)
2427 return err;
2428 kctl->id.device = ice->pcm_pro->device;
2429 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice));
2430 if (err < 0)
2431 return err;
2432 kctl->id.device = ice->pcm_pro->device;
2433 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice));
2434 if (err < 0)
2435 return err;
2436 kctl->id.device = ice->pcm_pro->device;
2437 ice->spdif.stream_ctl = kctl;
2438 return 0;
2439}
2440
2441
2442static int __devinit snd_ice1712_build_controls(ice1712_t *ice)
2443{
2444 int err;
2445
2446 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_eeprom, ice));
2447 if (err < 0)
2448 return err;
2449 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock, ice));
2450 if (err < 0)
2451 return err;
2452 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_internal_clock_default, ice));
2453 if (err < 0)
2454 return err;
2455
2456 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_locking, ice));
2457 if (err < 0)
2458 return err;
2459 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_rate_reset, ice));
2460 if (err < 0)
2461 return err;
2462
2463 if (ice->num_total_dacs > 0) {
2464 snd_kcontrol_new_t tmp = snd_ice1712_mixer_pro_analog_route;
2465 tmp.count = ice->num_total_dacs;
2466 err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
2467 if (err < 0)
2468 return err;
2469 }
2470
2471 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice));
2472 if (err < 0)
2473 return err;
2474
2475 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice));
2476 if (err < 0)
2477 return err;
2478 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
2479 if (err < 0)
2480 return err;
2481
2482 return 0;
2483}
2484
2485static int snd_ice1712_free(ice1712_t *ice)
2486{
2487 if (! ice->port)
2488 goto __hw_end;
2489 /* mask all interrupts */
2490 outb(0xc0, ICEMT(ice, IRQ));
2491 outb(0xff, ICEREG(ice, IRQMASK));
2492 /* --- */
2493 __hw_end:
2494 if (ice->irq >= 0) {
2495 synchronize_irq(ice->irq);
2496 free_irq(ice->irq, (void *) ice);
2497 }
2498 if (ice->port)
2499 pci_release_regions(ice->pci);
2500 snd_ice1712_akm4xxx_free(ice);
2501 pci_disable_device(ice->pci);
2502 kfree(ice);
2503 return 0;
2504}
2505
2506static int snd_ice1712_dev_free(snd_device_t *device)
2507{
2508 ice1712_t *ice = device->device_data;
2509 return snd_ice1712_free(ice);
2510}
2511
2512static int __devinit snd_ice1712_create(snd_card_t * card,
2513 struct pci_dev *pci,
2514 const char *modelname,
2515 int omni,
2516 int cs8427_timeout,
2517 ice1712_t ** r_ice1712)
2518{
2519 ice1712_t *ice;
2520 int err;
2521 static snd_device_ops_t ops = {
2522 .dev_free = snd_ice1712_dev_free,
2523 };
2524
2525 *r_ice1712 = NULL;
2526
2527 /* enable PCI device */
2528 if ((err = pci_enable_device(pci)) < 0)
2529 return err;
2530 /* check, if we can restrict PCI DMA transfers to 28 bits */
2531 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
2532 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
2533 snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
2534 pci_disable_device(pci);
2535 return -ENXIO;
2536 }
2537
2538 ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
2539 if (ice == NULL) {
2540 pci_disable_device(pci);
2541 return -ENOMEM;
2542 }
2543 ice->omni = omni ? 1 : 0;
2544 if (cs8427_timeout < 1)
2545 cs8427_timeout = 1;
2546 else if (cs8427_timeout > 1000)
2547 cs8427_timeout = 1000;
2548 ice->cs8427_timeout = cs8427_timeout;
2549 spin_lock_init(&ice->reg_lock);
2550 init_MUTEX(&ice->gpio_mutex);
2551 init_MUTEX(&ice->i2c_mutex);
2552 init_MUTEX(&ice->open_mutex);
2553 ice->gpio.set_mask = snd_ice1712_set_gpio_mask;
2554 ice->gpio.set_dir = snd_ice1712_set_gpio_dir;
2555 ice->gpio.set_data = snd_ice1712_set_gpio_data;
2556 ice->gpio.get_data = snd_ice1712_get_gpio_data;
2557
2558 ice->spdif.cs8403_bits =
2559 ice->spdif.cs8403_stream_bits = (0x01 | /* consumer format */
2560 0x10 | /* no emphasis */
2561 0x20); /* PCM encoder/decoder */
2562 ice->card = card;
2563 ice->pci = pci;
2564 ice->irq = -1;
2565 pci_set_master(pci);
2566 pci_write_config_word(ice->pci, 0x40, 0x807f);
2567 pci_write_config_word(ice->pci, 0x42, 0x0006);
2568 snd_ice1712_proc_init(ice);
2569 synchronize_irq(pci->irq);
2570
2571 if ((err = pci_request_regions(pci, "ICE1712")) < 0) {
2572 kfree(ice);
2573 pci_disable_device(pci);
2574 return err;
2575 }
2576 ice->port = pci_resource_start(pci, 0);
2577 ice->ddma_port = pci_resource_start(pci, 1);
2578 ice->dmapath_port = pci_resource_start(pci, 2);
2579 ice->profi_port = pci_resource_start(pci, 3);
2580
2581 if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
2582 snd_printk("unable to grab IRQ %d\n", pci->irq);
2583 snd_ice1712_free(ice);
2584 return -EIO;
2585 }
2586
2587 ice->irq = pci->irq;
2588
2589 if (snd_ice1712_read_eeprom(ice, modelname) < 0) {
2590 snd_ice1712_free(ice);
2591 return -EIO;
2592 }
2593 if (snd_ice1712_chip_init(ice) < 0) {
2594 snd_ice1712_free(ice);
2595 return -EIO;
2596 }
2597
2598 /* unmask used interrupts */
2599 outb((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? ICE1712_IRQ_MPU2 : 0 |
2600 (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0,
2601 ICEREG(ice, IRQMASK));
2602 outb(0x00, ICEMT(ice, IRQ));
2603
2604 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
2605 snd_ice1712_free(ice);
2606 return err;
2607 }
2608
2609 snd_card_set_dev(card, &pci->dev);
2610
2611 *r_ice1712 = ice;
2612 return 0;
2613}
2614
2615
2616/*
2617 *
2618 * Registration
2619 *
2620 */
2621
2622static struct snd_ice1712_card_info no_matched __devinitdata;
2623
2624static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2625 const struct pci_device_id *pci_id)
2626{
2627 static int dev;
2628 snd_card_t *card;
2629 ice1712_t *ice;
2630 int pcm_dev = 0, err;
2631 struct snd_ice1712_card_info **tbl, *c;
2632
2633 if (dev >= SNDRV_CARDS)
2634 return -ENODEV;
2635 if (!enable[dev]) {
2636 dev++;
2637 return -ENOENT;
2638 }
2639
2640 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2641 if (card == NULL)
2642 return -ENOMEM;
2643
2644 strcpy(card->driver, "ICE1712");
2645 strcpy(card->shortname, "ICEnsemble ICE1712");
2646
2647 if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], cs8427_timeout[dev], &ice)) < 0) {
2648 snd_card_free(card);
2649 return err;
2650 }
2651
2652 for (tbl = card_tables; *tbl; tbl++) {
2653 for (c = *tbl; c->subvendor; c++) {
2654 if (c->subvendor == ice->eeprom.subvendor) {
2655 strcpy(card->shortname, c->name);
2656 if (c->driver) /* specific driver? */
2657 strcpy(card->driver, c->driver);
2658 if (c->chip_init) {
2659 if ((err = c->chip_init(ice)) < 0) {
2660 snd_card_free(card);
2661 return err;
2662 }
2663 }
2664 goto __found;
2665 }
2666 }
2667 }
2668 c = &no_matched;
2669 __found:
2670
2671 if ((err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL)) < 0) {
2672 snd_card_free(card);
2673 return err;
2674 }
2675
2676 if (ice_has_con_ac97(ice))
2677 if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) {
2678 snd_card_free(card);
2679 return err;
2680 }
2681
2682 if ((err = snd_ice1712_ac97_mixer(ice)) < 0) {
2683 snd_card_free(card);
2684 return err;
2685 }
2686
2687 if ((err = snd_ice1712_build_controls(ice)) < 0) {
2688 snd_card_free(card);
2689 return err;
2690 }
2691
2692 if (c->build_controls) {
2693 if ((err = c->build_controls(ice)) < 0) {
2694 snd_card_free(card);
2695 return err;
2696 }
2697 }
2698
2699 if (ice_has_con_ac97(ice))
2700 if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) {
2701 snd_card_free(card);
2702 return err;
2703 }
2704
2705 if (! c->no_mpu401) {
2706 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2707 ICEREG(ice, MPU1_CTRL), 1,
2708 ice->irq, 0,
2709 &ice->rmidi[0])) < 0) {
2710 snd_card_free(card);
2711 return err;
2712 }
2713
2714 if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401)
2715 if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
2716 ICEREG(ice, MPU2_CTRL), 1,
2717 ice->irq, 0,
2718 &ice->rmidi[1])) < 0) {
2719 snd_card_free(card);
2720 return err;
2721 }
2722 }
2723
2724 sprintf(card->longname, "%s at 0x%lx, irq %i",
2725 card->shortname, ice->port, ice->irq);
2726
2727 if ((err = snd_card_register(card)) < 0) {
2728 snd_card_free(card);
2729 return err;
2730 }
2731 pci_set_drvdata(pci, card);
2732 dev++;
2733 return 0;
2734}
2735
2736static void __devexit snd_ice1712_remove(struct pci_dev *pci)
2737{
2738 snd_card_free(pci_get_drvdata(pci));
2739 pci_set_drvdata(pci, NULL);
2740}
2741
2742static struct pci_driver driver = {
2743 .name = "ICE1712",
2744 .id_table = snd_ice1712_ids,
2745 .probe = snd_ice1712_probe,
2746 .remove = __devexit_p(snd_ice1712_remove),
2747};
2748
2749static int __init alsa_card_ice1712_init(void)
2750{
2751 return pci_module_init(&driver);
2752}
2753
2754static void __exit alsa_card_ice1712_exit(void)
2755{
2756 pci_unregister_driver(&driver);
2757}
2758
2759module_init(alsa_card_ice1712_init)
2760module_exit(alsa_card_ice1712_exit)
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
new file mode 100644
index 000000000000..8bb1c58c26a0
--- /dev/null
+++ b/sound/pci/ice1712/ice1712.h
@@ -0,0 +1,494 @@
1#ifndef __SOUND_ICE1712_H
2#define __SOUND_ICE1712_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/control.h>
26#include <sound/ac97_codec.h>
27#include <sound/rawmidi.h>
28#include <sound/i2c.h>
29#include <sound/ak4xxx-adda.h>
30#include <sound/ak4114.h>
31#include <sound/pcm.h>
32
33
34/*
35 * Direct registers
36 */
37
38#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)
39
40#define ICE1712_REG_CONTROL 0x00 /* byte */
41#define ICE1712_RESET 0x80 /* reset whole chip */
42#define ICE1712_SERR_LEVEL 0x04 /* SERR# level otherwise edge */
43#define ICE1712_NATIVE 0x01 /* native mode otherwise SB */
44#define ICE1712_REG_IRQMASK 0x01 /* byte */
45#define ICE1712_IRQ_MPU1 0x80
46#define ICE1712_IRQ_TIMER 0x40
47#define ICE1712_IRQ_MPU2 0x20
48#define ICE1712_IRQ_PROPCM 0x10
49#define ICE1712_IRQ_FM 0x08 /* FM/MIDI - legacy */
50#define ICE1712_IRQ_PBKDS 0x04 /* playback DS channels */
51#define ICE1712_IRQ_CONCAP 0x02 /* consumer capture */
52#define ICE1712_IRQ_CONPBK 0x01 /* consumer playback */
53#define ICE1712_REG_IRQSTAT 0x02 /* byte */
54/* look to ICE1712_IRQ_* */
55#define ICE1712_REG_INDEX 0x03 /* byte - indirect CCIxx regs */
56#define ICE1712_REG_DATA 0x04 /* byte - indirect CCIxx regs */
57#define ICE1712_REG_NMI_STAT1 0x05 /* byte */
58#define ICE1712_REG_NMI_DATA 0x06 /* byte */
59#define ICE1712_REG_NMI_INDEX 0x07 /* byte */
60#define ICE1712_REG_AC97_INDEX 0x08 /* byte */
61#define ICE1712_REG_AC97_CMD 0x09 /* byte */
62#define ICE1712_AC97_COLD 0x80 /* cold reset */
63#define ICE1712_AC97_WARM 0x40 /* warm reset */
64#define ICE1712_AC97_WRITE 0x20 /* W: write, R: write in progress */
65#define ICE1712_AC97_READ 0x10 /* W: read, R: read in progress */
66#define ICE1712_AC97_READY 0x08 /* codec ready status bit */
67#define ICE1712_AC97_PBK_VSR 0x02 /* playback VSR */
68#define ICE1712_AC97_CAP_VSR 0x01 /* capture VSR */
69#define ICE1712_REG_AC97_DATA 0x0a /* word (little endian) */
70#define ICE1712_REG_MPU1_CTRL 0x0c /* byte */
71#define ICE1712_REG_MPU1_DATA 0x0d /* byte */
72#define ICE1712_REG_I2C_DEV_ADDR 0x10 /* byte */
73#define ICE1712_I2C_WRITE 0x01 /* write direction */
74#define ICE1712_REG_I2C_BYTE_ADDR 0x11 /* byte */
75#define ICE1712_REG_I2C_DATA 0x12 /* byte */
76#define ICE1712_REG_I2C_CTRL 0x13 /* byte */
77#define ICE1712_I2C_EEPROM 0x80 /* EEPROM exists */
78#define ICE1712_I2C_BUSY 0x01 /* busy bit */
79#define ICE1712_REG_CONCAP_ADDR 0x14 /* dword - consumer capture */
80#define ICE1712_REG_CONCAP_COUNT 0x18 /* word - current/base count */
81#define ICE1712_REG_SERR_SHADOW 0x1b /* byte */
82#define ICE1712_REG_MPU2_CTRL 0x1c /* byte */
83#define ICE1712_REG_MPU2_DATA 0x1d /* byte */
84#define ICE1712_REG_TIMER 0x1e /* word */
85
86/*
87 * Indirect registers
88 */
89
90#define ICE1712_IREG_PBK_COUNT_LO 0x00
91#define ICE1712_IREG_PBK_COUNT_HI 0x01
92#define ICE1712_IREG_PBK_CTRL 0x02
93#define ICE1712_IREG_PBK_LEFT 0x03 /* left volume */
94#define ICE1712_IREG_PBK_RIGHT 0x04 /* right volume */
95#define ICE1712_IREG_PBK_SOFT 0x05 /* soft volume */
96#define ICE1712_IREG_PBK_RATE_LO 0x06
97#define ICE1712_IREG_PBK_RATE_MID 0x07
98#define ICE1712_IREG_PBK_RATE_HI 0x08
99#define ICE1712_IREG_CAP_COUNT_LO 0x10
100#define ICE1712_IREG_CAP_COUNT_HI 0x11
101#define ICE1712_IREG_CAP_CTRL 0x12
102#define ICE1712_IREG_GPIO_DATA 0x20
103#define ICE1712_IREG_GPIO_WRITE_MASK 0x21
104#define ICE1712_IREG_GPIO_DIRECTION 0x22
105#define ICE1712_IREG_CONSUMER_POWERDOWN 0x30
106#define ICE1712_IREG_PRO_POWERDOWN 0x31
107
108/*
109 * Consumer section direct DMA registers
110 */
111
112#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
113
114#define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */
115#define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */
116#define ICE1712_DS_DATA 0x04 /* dword - channel data */
117#define ICE1712_DS_INDEX 0x08 /* dword - channel index */
118
119/*
120 * Consumer section channel registers
121 */
122
123#define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */
124#define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */
125#define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */
126#define ICE1712_DSC_COUNT1 0x03 /* word - count 1 */
127#define ICE1712_DSC_CONTROL 0x04 /* byte - control & status */
128#define ICE1712_BUFFER1 0x80 /* buffer1 is active */
129#define ICE1712_BUFFER1_AUTO 0x40 /* buffer1 auto init */
130#define ICE1712_BUFFER0_AUTO 0x20 /* buffer0 auto init */
131#define ICE1712_FLUSH 0x10 /* flush FIFO */
132#define ICE1712_STEREO 0x08 /* stereo */
133#define ICE1712_16BIT 0x04 /* 16-bit data */
134#define ICE1712_PAUSE 0x02 /* pause */
135#define ICE1712_START 0x01 /* start */
136#define ICE1712_DSC_RATE 0x05 /* dword - rate */
137#define ICE1712_DSC_VOLUME 0x06 /* word - volume control */
138
139/*
140 * Professional multi-track direct control registers
141 */
142
143#define ICEMT(ice, x) ((ice)->profi_port + ICE1712_MT_##x)
144
145#define ICE1712_MT_IRQ 0x00 /* byte - interrupt mask */
146#define ICE1712_MULTI_CAPTURE 0x80 /* capture IRQ */
147#define ICE1712_MULTI_PLAYBACK 0x40 /* playback IRQ */
148#define ICE1712_MULTI_CAPSTATUS 0x02 /* capture IRQ status */
149#define ICE1712_MULTI_PBKSTATUS 0x01 /* playback IRQ status */
150#define ICE1712_MT_RATE 0x01 /* byte - sampling rate select */
151#define ICE1712_SPDIF_MASTER 0x10 /* S/PDIF input is master clock */
152#define ICE1712_MT_I2S_FORMAT 0x02 /* byte - I2S data format */
153#define ICE1712_MT_AC97_INDEX 0x04 /* byte - AC'97 index */
154#define ICE1712_MT_AC97_CMD 0x05 /* byte - AC'97 command & status */
155/* look to ICE1712_AC97_* */
156#define ICE1712_MT_AC97_DATA 0x06 /* word - AC'97 data */
157#define ICE1712_MT_PLAYBACK_ADDR 0x10 /* dword - playback address */
158#define ICE1712_MT_PLAYBACK_SIZE 0x14 /* word - playback size */
159#define ICE1712_MT_PLAYBACK_COUNT 0x16 /* word - playback count */
160#define ICE1712_MT_PLAYBACK_CONTROL 0x18 /* byte - control */
161#define ICE1712_CAPTURE_START_SHADOW 0x04 /* capture start */
162#define ICE1712_PLAYBACK_PAUSE 0x02 /* playback pause */
163#define ICE1712_PLAYBACK_START 0x01 /* playback start */
164#define ICE1712_MT_CAPTURE_ADDR 0x20 /* dword - capture address */
165#define ICE1712_MT_CAPTURE_SIZE 0x24 /* word - capture size */
166#define ICE1712_MT_CAPTURE_COUNT 0x26 /* word - capture count */
167#define ICE1712_MT_CAPTURE_CONTROL 0x28 /* byte - control */
168#define ICE1712_CAPTURE_START 0x01 /* capture start */
169#define ICE1712_MT_ROUTE_PSDOUT03 0x30 /* word */
170#define ICE1712_MT_ROUTE_SPDOUT 0x32 /* word */
171#define ICE1712_MT_ROUTE_CAPTURE 0x34 /* dword */
172#define ICE1712_MT_MONITOR_VOLUME 0x38 /* word */
173#define ICE1712_MT_MONITOR_INDEX 0x3a /* byte */
174#define ICE1712_MT_MONITOR_RATE 0x3b /* byte */
175#define ICE1712_MT_MONITOR_ROUTECTRL 0x3c /* byte */
176#define ICE1712_ROUTE_AC97 0x01 /* route digital mixer output to AC'97 */
177#define ICE1712_MT_MONITOR_PEAKINDEX 0x3e /* byte */
178#define ICE1712_MT_MONITOR_PEAKDATA 0x3f /* byte */
179
180/*
181 * Codec configuration bits
182 */
183
184/* PCI[60] System Configuration */
185#define ICE1712_CFG_CLOCK 0xc0
186#define ICE1712_CFG_CLOCK512 0x00 /* 22.5692Mhz, 44.1kHz*512 */
187#define ICE1712_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */
188#define ICE1712_CFG_EXT 0x80 /* external clock */
189#define ICE1712_CFG_2xMPU401 0x20 /* two MPU401 UARTs */
190#define ICE1712_CFG_NO_CON_AC97 0x10 /* consumer AC'97 codec is not present */
191#define ICE1712_CFG_ADC_MASK 0x0c /* one, two, three, four stereo ADCs */
192#define ICE1712_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */
193/* PCI[61] AC-Link Configuration */
194#define ICE1712_CFG_PRO_I2S 0x80 /* multitrack converter: I2S or AC'97 */
195#define ICE1712_CFG_AC97_PACKED 0x01 /* split or packed mode - AC'97 */
196/* PCI[62] I2S Features */
197#define ICE1712_CFG_I2S_VOLUME 0x80 /* volume/mute capability */
198#define ICE1712_CFG_I2S_96KHZ 0x40 /* supports 96kHz sampling */
199#define ICE1712_CFG_I2S_RESMASK 0x30 /* resolution mask, 16,18,20,24-bit */
200#define ICE1712_CFG_I2S_OTHER 0x0f /* other I2S IDs */
201/* PCI[63] S/PDIF Configuration */
202#define ICE1712_CFG_I2S_CHIPID 0xfc /* I2S chip ID */
203#define ICE1712_CFG_SPDIF_IN 0x02 /* S/PDIF input is present */
204#define ICE1712_CFG_SPDIF_OUT 0x01 /* S/PDIF output is present */
205
206/*
207 * DMA mode values
208 * identical with DMA_XXX on i386 architecture.
209 */
210#define ICE1712_DMA_MODE_WRITE 0x48
211#define ICE1712_DMA_AUTOINIT 0x10
212
213
214/*
215 *
216 */
217
218typedef struct _snd_ice1712 ice1712_t;
219
220typedef struct {
221 unsigned int subvendor; /* PCI[2c-2f] */
222 unsigned char size; /* size of EEPROM image in bytes */
223 unsigned char version; /* must be 1 (or 2 for vt1724) */
224 unsigned char data[32];
225 unsigned int gpiomask;
226 unsigned int gpiostate;
227 unsigned int gpiodir;
228} ice1712_eeprom_t;
229
230enum {
231 ICE_EEP1_CODEC = 0, /* 06 */
232 ICE_EEP1_ACLINK, /* 07 */
233 ICE_EEP1_I2SID, /* 08 */
234 ICE_EEP1_SPDIF, /* 09 */
235 ICE_EEP1_GPIO_MASK, /* 0a */
236 ICE_EEP1_GPIO_STATE, /* 0b */
237 ICE_EEP1_GPIO_DIR, /* 0c */
238 ICE_EEP1_AC97_MAIN_LO, /* 0d */
239 ICE_EEP1_AC97_MAIN_HI, /* 0e */
240 ICE_EEP1_AC97_PCM_LO, /* 0f */
241 ICE_EEP1_AC97_PCM_HI, /* 10 */
242 ICE_EEP1_AC97_REC_LO, /* 11 */
243 ICE_EEP1_AC97_REC_HI, /* 12 */
244 ICE_EEP1_AC97_RECSRC, /* 13 */
245 ICE_EEP1_DAC_ID, /* 14 */
246 ICE_EEP1_DAC_ID1,
247 ICE_EEP1_DAC_ID2,
248 ICE_EEP1_DAC_ID3,
249 ICE_EEP1_ADC_ID, /* 18 */
250 ICE_EEP1_ADC_ID1,
251 ICE_EEP1_ADC_ID2,
252 ICE_EEP1_ADC_ID3
253};
254
255#define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97))
256
257
258struct snd_ak4xxx_private {
259 unsigned int cif: 1; /* CIF mode */
260 unsigned char caddr; /* C0 and C1 bits */
261 unsigned int data_mask; /* DATA gpio bit */
262 unsigned int clk_mask; /* CLK gpio bit */
263 unsigned int cs_mask; /* bit mask for select/deselect address */
264 unsigned int cs_addr; /* bits to select address */
265 unsigned int cs_none; /* bits to deselect address */
266 unsigned int add_flags; /* additional bits at init */
267 unsigned int mask_flags; /* total mask bits */
268 struct snd_akm4xxx_ops {
269 void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
270 } ops;
271};
272
273struct snd_ice1712_spdif {
274 unsigned char cs8403_bits;
275 unsigned char cs8403_stream_bits;
276 snd_kcontrol_t *stream_ctl;
277
278 struct snd_ice1712_spdif_ops {
279 void (*open)(ice1712_t *, snd_pcm_substream_t *);
280 void (*setup_rate)(ice1712_t *, int rate);
281 void (*close)(ice1712_t *, snd_pcm_substream_t *);
282 void (*default_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
283 int (*default_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
284 void (*stream_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
285 int (*stream_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
286 } ops;
287};
288
289
290struct _snd_ice1712 {
291 unsigned long conp_dma_size;
292 unsigned long conc_dma_size;
293 unsigned long prop_dma_size;
294 unsigned long proc_dma_size;
295 int irq;
296
297 unsigned long port;
298 unsigned long ddma_port;
299 unsigned long dmapath_port;
300 unsigned long profi_port;
301
302 struct pci_dev *pci;
303 snd_card_t *card;
304 snd_pcm_t *pcm;
305 snd_pcm_t *pcm_ds;
306 snd_pcm_t *pcm_pro;
307 snd_pcm_substream_t *playback_con_substream;
308 snd_pcm_substream_t *playback_con_substream_ds[6];
309 snd_pcm_substream_t *capture_con_substream;
310 snd_pcm_substream_t *playback_pro_substream;
311 snd_pcm_substream_t *capture_pro_substream;
312 unsigned int playback_pro_size;
313 unsigned int capture_pro_size;
314 unsigned int playback_con_virt_addr[6];
315 unsigned int playback_con_active_buf[6];
316 unsigned int capture_con_virt_addr;
317 unsigned int ac97_ext_id;
318 ac97_t *ac97;
319 snd_rawmidi_t *rmidi[2];
320
321 spinlock_t reg_lock;
322 snd_info_entry_t *proc_entry;
323
324 ice1712_eeprom_t eeprom;
325
326 unsigned int pro_volumes[20];
327 unsigned int omni: 1; /* Delta Omni I/O */
328 unsigned int vt1724: 1;
329 unsigned int vt1720: 1;
330 unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */
331 unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */
332 unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */
333 unsigned int num_total_dacs; /* total DACs */
334 unsigned int num_total_adcs; /* total ADCs */
335 unsigned int cur_rate; /* current rate */
336
337 struct semaphore open_mutex;
338 snd_pcm_substream_t *pcm_reserved[4];
339 snd_pcm_hw_constraint_list_t *hw_rates; /* card-specific rate constraints */
340
341 unsigned int akm_codecs;
342 akm4xxx_t *akm;
343 struct snd_ice1712_spdif spdif;
344
345 struct semaphore i2c_mutex; /* I2C mutex for ICE1724 registers */
346 snd_i2c_bus_t *i2c; /* I2C bus */
347 snd_i2c_device_t *cs8427; /* CS8427 I2C device */
348 unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */
349
350 struct ice1712_gpio {
351 unsigned int direction; /* current direction bits */
352 unsigned int write_mask; /* current mask bits */
353 unsigned int saved[2]; /* for ewx_i2c */
354 /* operators */
355 void (*set_mask)(ice1712_t *ice, unsigned int data);
356 void (*set_dir)(ice1712_t *ice, unsigned int data);
357 void (*set_data)(ice1712_t *ice, unsigned int data);
358 unsigned int (*get_data)(ice1712_t *ice);
359 /* misc operators - move to another place? */
360 void (*set_pro_rate)(ice1712_t *ice, unsigned int rate);
361 void (*i2s_mclk_changed)(ice1712_t *ice);
362 } gpio;
363 struct semaphore gpio_mutex;
364
365 /* other board-specific data */
366 union {
367 /* additional i2c devices for EWS boards */
368 snd_i2c_device_t *i2cdevs[3];
369 /* AC97 register cache for Aureon */
370 struct aureon_spec {
371 unsigned short stac9744[64];
372 unsigned int cs8415_mux;
373 unsigned short master[2];
374 unsigned short vol[8];
375 } aureon;
376 /* Hoontech-specific setting */
377 struct hoontech_spec {
378 unsigned char boxbits[4];
379 unsigned int config;
380 unsigned short boxconfig[4];
381 } hoontech;
382 struct {
383 ak4114_t *ak4114;
384 unsigned int analog: 1;
385 } juli;
386 } spec;
387
388};
389
390
391/*
392 * gpio access functions
393 */
394static inline void snd_ice1712_gpio_set_dir(ice1712_t *ice, unsigned int bits)
395{
396 ice->gpio.set_dir(ice, bits);
397}
398
399static inline void snd_ice1712_gpio_set_mask(ice1712_t *ice, unsigned int bits)
400{
401 ice->gpio.set_mask(ice, bits);
402}
403
404static inline void snd_ice1712_gpio_write(ice1712_t *ice, unsigned int val)
405{
406 ice->gpio.set_data(ice, val);
407}
408
409static inline unsigned int snd_ice1712_gpio_read(ice1712_t *ice)
410{
411 return ice->gpio.get_data(ice);
412}
413
414/*
415 * save and restore gpio status
416 * The access to gpio will be protected by mutex, so don't forget to
417 * restore!
418 */
419static inline void snd_ice1712_save_gpio_status(ice1712_t *ice)
420{
421 down(&ice->gpio_mutex);
422 ice->gpio.saved[0] = ice->gpio.direction;
423 ice->gpio.saved[1] = ice->gpio.write_mask;
424}
425
426static inline void snd_ice1712_restore_gpio_status(ice1712_t *ice)
427{
428 ice->gpio.set_dir(ice, ice->gpio.saved[0]);
429 ice->gpio.set_mask(ice, ice->gpio.saved[1]);
430 ice->gpio.direction = ice->gpio.saved[0];
431 ice->gpio.write_mask = ice->gpio.saved[1];
432 up(&ice->gpio_mutex);
433}
434
435/* for bit controls */
436#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
437{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ice1712_gpio_info, \
438 .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
439 .private_value = mask | (invert << 24) }
440
441int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
442int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
443int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
444
445/*
446 * set gpio direction, write mask and data
447 */
448static inline void snd_ice1712_gpio_write_bits(ice1712_t *ice, unsigned int mask, unsigned int bits)
449{
450 ice->gpio.direction |= mask;
451 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
452 snd_ice1712_gpio_set_mask(ice, ~mask);
453 snd_ice1712_gpio_write(ice, mask & bits);
454}
455
456int snd_ice1712_spdif_build_controls(ice1712_t *ice);
457
458int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *template, const struct snd_ak4xxx_private *priv, ice1712_t *ice);
459void snd_ice1712_akm4xxx_free(ice1712_t *ice);
460int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice);
461
462int snd_ice1712_init_cs8427(ice1712_t *ice, int addr);
463
464static inline void snd_ice1712_write(ice1712_t * ice, u8 addr, u8 data)
465{
466 outb(addr, ICEREG(ice, INDEX));
467 outb(data, ICEREG(ice, DATA));
468}
469
470static inline u8 snd_ice1712_read(ice1712_t * ice, u8 addr)
471{
472 outb(addr, ICEREG(ice, INDEX));
473 return inb(ICEREG(ice, DATA));
474}
475
476
477/*
478 * entry pointer
479 */
480
481struct snd_ice1712_card_info {
482 unsigned int subvendor;
483 char *name;
484 char *model;
485 char *driver;
486 int (*chip_init)(ice1712_t *);
487 int (*build_controls)(ice1712_t *);
488 unsigned int no_mpu401: 1;
489 unsigned int eeprom_size;
490 unsigned char *eeprom_data;
491};
492
493
494#endif /* __SOUND_ICE1712_H */
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
new file mode 100644
index 000000000000..95500f06f0c6
--- /dev/null
+++ b/sound/pci/ice1712/ice1724.c
@@ -0,0 +1,2340 @@
1/*
2 * ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT)
3 * VIA VT1720 (Envy24PT)
4 *
5 * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
6 * 2002 James Stafford <jstafford@ampltd.com>
7 * 2003 Takashi Iwai <tiwai@suse.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/driver.h>
26#include <asm/io.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/init.h>
30#include <linux/pci.h>
31#include <linux/slab.h>
32#include <linux/moduleparam.h>
33#include <sound/core.h>
34#include <sound/info.h>
35#include <sound/mpu401.h>
36#include <sound/initval.h>
37
38#include <sound/asoundef.h>
39
40#include "ice1712.h"
41#include "envy24ht.h"
42
43/* lowlevel routines */
44#include "amp.h"
45#include "revo.h"
46#include "aureon.h"
47#include "vt1720_mobo.h"
48#include "pontis.h"
49#include "prodigy192.h"
50#include "juli.h"
51#include "phase.h"
52
53
54MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
55MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
56MODULE_LICENSE("GPL");
57MODULE_SUPPORTED_DEVICE("{"
58 REVO_DEVICE_DESC
59 AMP_AUDIO2000_DEVICE_DESC
60 AUREON_DEVICE_DESC
61 VT1720_MOBO_DEVICE_DESC
62 PONTIS_DEVICE_DESC
63 PRODIGY192_DEVICE_DESC
64 JULI_DEVICE_DESC
65 PHASE_DEVICE_DESC
66 "{VIA,VT1720},"
67 "{VIA,VT1724},"
68 "{ICEnsemble,Generic ICE1724},"
69 "{ICEnsemble,Generic Envy24HT}"
70 "{ICEnsemble,Generic Envy24PT}}");
71
72static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
73static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
74static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
75static char *model[SNDRV_CARDS];
76
77module_param_array(index, int, NULL, 0444);
78MODULE_PARM_DESC(index, "Index value for ICE1724 soundcard.");
79module_param_array(id, charp, NULL, 0444);
80MODULE_PARM_DESC(id, "ID string for ICE1724 soundcard.");
81module_param_array(enable, bool, NULL, 0444);
82MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard.");
83module_param_array(model, charp, NULL, 0444);
84MODULE_PARM_DESC(model, "Use the given board model.");
85
86#ifndef PCI_VENDOR_ID_ICE
87#define PCI_VENDOR_ID_ICE 0x1412
88#endif
89#ifndef PCI_DEVICE_ID_VT1724
90#define PCI_DEVICE_ID_VT1724 0x1724
91#endif
92
93/* Both VT1720 and VT1724 have the same PCI IDs */
94static struct pci_device_id snd_vt1724_ids[] = {
95 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
96 { 0, }
97};
98
99MODULE_DEVICE_TABLE(pci, snd_vt1724_ids);
100
101
102static int PRO_RATE_LOCKED;
103static int PRO_RATE_RESET = 1;
104static unsigned int PRO_RATE_DEFAULT = 44100;
105
106/*
107 * Basic I/O
108 */
109
110/* check whether the clock mode is spdif-in */
111static inline int is_spdif_master(ice1712_t *ice)
112{
113 return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
114}
115
116static inline int is_pro_rate_locked(ice1712_t *ice)
117{
118 return is_spdif_master(ice) || PRO_RATE_LOCKED;
119}
120
121/*
122 * ac97 section
123 */
124
125static unsigned char snd_vt1724_ac97_ready(ice1712_t *ice)
126{
127 unsigned char old_cmd;
128 int tm;
129 for (tm = 0; tm < 0x10000; tm++) {
130 old_cmd = inb(ICEMT1724(ice, AC97_CMD));
131 if (old_cmd & (VT1724_AC97_WRITE | VT1724_AC97_READ))
132 continue;
133 if (!(old_cmd & VT1724_AC97_READY))
134 continue;
135 return old_cmd;
136 }
137 snd_printd(KERN_ERR "snd_vt1724_ac97_ready: timeout\n");
138 return old_cmd;
139}
140
141static int snd_vt1724_ac97_wait_bit(ice1712_t *ice, unsigned char bit)
142{
143 int tm;
144 for (tm = 0; tm < 0x10000; tm++)
145 if ((inb(ICEMT1724(ice, AC97_CMD)) & bit) == 0)
146 return 0;
147 snd_printd(KERN_ERR "snd_vt1724_ac97_wait_bit: timeout\n");
148 return -EIO;
149}
150
151static void snd_vt1724_ac97_write(ac97_t *ac97,
152 unsigned short reg,
153 unsigned short val)
154{
155 ice1712_t *ice = (ice1712_t *)ac97->private_data;
156 unsigned char old_cmd;
157
158 old_cmd = snd_vt1724_ac97_ready(ice);
159 old_cmd &= ~VT1724_AC97_ID_MASK;
160 old_cmd |= ac97->num;
161 outb(reg, ICEMT1724(ice, AC97_INDEX));
162 outw(val, ICEMT1724(ice, AC97_DATA));
163 outb(old_cmd | VT1724_AC97_WRITE, ICEMT1724(ice, AC97_CMD));
164 snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_WRITE);
165}
166
167static unsigned short snd_vt1724_ac97_read(ac97_t *ac97, unsigned short reg)
168{
169 ice1712_t *ice = (ice1712_t *)ac97->private_data;
170 unsigned char old_cmd;
171
172 old_cmd = snd_vt1724_ac97_ready(ice);
173 old_cmd &= ~VT1724_AC97_ID_MASK;
174 old_cmd |= ac97->num;
175 outb(reg, ICEMT1724(ice, AC97_INDEX));
176 outb(old_cmd | VT1724_AC97_READ, ICEMT1724(ice, AC97_CMD));
177 if (snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_READ) < 0)
178 return ~0;
179 return inw(ICEMT1724(ice, AC97_DATA));
180}
181
182
183/*
184 * GPIO operations
185 */
186
187/* set gpio direction 0 = read, 1 = write */
188static void snd_vt1724_set_gpio_dir(ice1712_t *ice, unsigned int data)
189{
190 outl(data, ICEREG1724(ice, GPIO_DIRECTION));
191 inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
192}
193
194/* set the gpio mask (0 = writable) */
195static void snd_vt1724_set_gpio_mask(ice1712_t *ice, unsigned int data)
196{
197 outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
198 if (! ice->vt1720) /* VT1720 supports only 16 GPIO bits */
199 outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22));
200 inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
201}
202
203static void snd_vt1724_set_gpio_data(ice1712_t *ice, unsigned int data)
204{
205 outw(data, ICEREG1724(ice, GPIO_DATA));
206 if (! ice->vt1720)
207 outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22));
208 inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
209}
210
211static unsigned int snd_vt1724_get_gpio_data(ice1712_t *ice)
212{
213 unsigned int data;
214 if (! ice->vt1720)
215 data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22));
216 else
217 data = 0;
218 data = (data << 16) | inw(ICEREG1724(ice, GPIO_DATA));
219 return data;
220}
221
222/*
223 * Interrupt handler
224 */
225
226static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs)
227{
228 ice1712_t *ice = dev_id;
229 unsigned char status;
230 int handled = 0;
231
232 while (1) {
233 status = inb(ICEREG1724(ice, IRQSTAT));
234 if (status == 0)
235 break;
236
237 handled = 1;
238 /* these should probably be separated at some point,
239 but as we don't currently have MPU support on the board I will leave it */
240 if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) {
241 if (ice->rmidi[0])
242 snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
243 outb(status & (VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX), ICEREG1724(ice, IRQSTAT));
244 status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX);
245 }
246 if (status & VT1724_IRQ_MTPCM) {
247 /*
248 * Multi-track PCM
249 * PCM assignment are:
250 * Playback DMA0 (M/C) = playback_pro_substream
251 * Playback DMA1 = playback_con_substream_ds[0]
252 * Playback DMA2 = playback_con_substream_ds[1]
253 * Playback DMA3 = playback_con_substream_ds[2]
254 * Playback DMA4 (SPDIF) = playback_con_substream
255 * Record DMA0 = capture_pro_substream
256 * Record DMA1 = capture_con_substream
257 */
258 unsigned char mtstat = inb(ICEMT1724(ice, IRQ));
259 if (mtstat & VT1724_MULTI_PDMA0) {
260 if (ice->playback_pro_substream)
261 snd_pcm_period_elapsed(ice->playback_pro_substream);
262 }
263 if (mtstat & VT1724_MULTI_RDMA0) {
264 if (ice->capture_pro_substream)
265 snd_pcm_period_elapsed(ice->capture_pro_substream);
266 }
267 if (mtstat & VT1724_MULTI_PDMA1) {
268 if (ice->playback_con_substream_ds[0])
269 snd_pcm_period_elapsed(ice->playback_con_substream_ds[0]);
270 }
271 if (mtstat & VT1724_MULTI_PDMA2) {
272 if (ice->playback_con_substream_ds[1])
273 snd_pcm_period_elapsed(ice->playback_con_substream_ds[1]);
274 }
275 if (mtstat & VT1724_MULTI_PDMA3) {
276 if (ice->playback_con_substream_ds[2])
277 snd_pcm_period_elapsed(ice->playback_con_substream_ds[2]);
278 }
279 if (mtstat & VT1724_MULTI_PDMA4) {
280 if (ice->playback_con_substream)
281 snd_pcm_period_elapsed(ice->playback_con_substream);
282 }
283 if (mtstat & VT1724_MULTI_RDMA1) {
284 if (ice->capture_con_substream)
285 snd_pcm_period_elapsed(ice->capture_con_substream);
286 }
287 /* ack anyway to avoid freeze */
288 outb(mtstat, ICEMT1724(ice, IRQ));
289 /* ought to really handle this properly */
290 if (mtstat & VT1724_MULTI_FIFO_ERR) {
291 unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR));
292 outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR));
293 outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK));
294 /* If I don't do this, I get machine lockup due to continual interrupts */
295 }
296
297 }
298 }
299 return IRQ_RETVAL(handled);
300}
301
302/*
303 * PCM code - professional part (multitrack)
304 */
305
306static unsigned int rates[] = {
307 8000, 9600, 11025, 12000, 16000, 22050, 24000,
308 32000, 44100, 48000, 64000, 88200, 96000,
309 176400, 192000,
310};
311
312static snd_pcm_hw_constraint_list_t hw_constraints_rates_96 = {
313 .count = ARRAY_SIZE(rates) - 2, /* up to 96000 */
314 .list = rates,
315 .mask = 0,
316};
317
318static snd_pcm_hw_constraint_list_t hw_constraints_rates_48 = {
319 .count = ARRAY_SIZE(rates) - 5, /* up to 48000 */
320 .list = rates,
321 .mask = 0,
322};
323
324static snd_pcm_hw_constraint_list_t hw_constraints_rates_192 = {
325 .count = ARRAY_SIZE(rates),
326 .list = rates,
327 .mask = 0,
328};
329
330struct vt1724_pcm_reg {
331 unsigned int addr; /* ADDR register offset */
332 unsigned int size; /* SIZE register offset */
333 unsigned int count; /* COUNT register offset */
334 unsigned int start; /* start & pause bit */
335};
336
337static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
338{
339 ice1712_t *ice = snd_pcm_substream_chip(substream);
340 unsigned char what;
341 unsigned char old;
342 struct list_head *pos;
343 snd_pcm_substream_t *s;
344
345 what = 0;
346 snd_pcm_group_for_each(pos, substream) {
347 struct vt1724_pcm_reg *reg;
348 s = snd_pcm_group_substream_entry(pos);
349 reg = s->runtime->private_data;
350 what |= reg->start;
351 snd_pcm_trigger_done(s, substream);
352 }
353
354 switch (cmd) {
355 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
356 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
357 spin_lock(&ice->reg_lock);
358 old = inb(ICEMT1724(ice, DMA_PAUSE));
359 if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
360 old |= what;
361 else
362 old &= ~what;
363 outb(old, ICEMT1724(ice, DMA_PAUSE));
364 spin_unlock(&ice->reg_lock);
365 break;
366
367 case SNDRV_PCM_TRIGGER_START:
368 case SNDRV_PCM_TRIGGER_STOP:
369 spin_lock(&ice->reg_lock);
370 old = inb(ICEMT1724(ice, DMA_CONTROL));
371 if (cmd == SNDRV_PCM_TRIGGER_START)
372 old |= what;
373 else
374 old &= ~what;
375 outb(old, ICEMT1724(ice, DMA_CONTROL));
376 spin_unlock(&ice->reg_lock);
377 break;
378
379 default:
380 return -EINVAL;
381 }
382 return 0;
383}
384
385/*
386 */
387
388#define DMA_STARTS (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|\
389 VT1724_PDMA1_START|VT1724_PDMA2_START|VT1724_PDMA3_START|VT1724_PDMA4_START)
390#define DMA_PAUSES (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\
391 VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE)
392
393static int get_max_rate(ice1712_t *ice)
394{
395 if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
396 if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
397 return 192000;
398 else
399 return 96000;
400 } else
401 return 48000;
402}
403
404static void snd_vt1724_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
405{
406 unsigned long flags;
407 unsigned char val, old;
408 unsigned int i, mclk_change;
409
410 if (rate > get_max_rate(ice))
411 return;
412
413 switch (rate) {
414 case 8000: val = 6; break;
415 case 9600: val = 3; break;
416 case 11025: val = 10; break;
417 case 12000: val = 2; break;
418 case 16000: val = 5; break;
419 case 22050: val = 9; break;
420 case 24000: val = 1; break;
421 case 32000: val = 4; break;
422 case 44100: val = 8; break;
423 case 48000: val = 0; break;
424 case 64000: val = 15; break;
425 case 88200: val = 11; break;
426 case 96000: val = 7; break;
427 case 176400: val = 12; break;
428 case 192000: val = 14; break;
429 default:
430 snd_BUG();
431 val = 0;
432 break;
433 }
434
435 spin_lock_irqsave(&ice->reg_lock, flags);
436 if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) ||
437 (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
438 /* running? we cannot change the rate now... */
439 spin_unlock_irqrestore(&ice->reg_lock, flags);
440 return;
441 }
442 if (!force && is_pro_rate_locked(ice)) {
443 spin_unlock_irqrestore(&ice->reg_lock, flags);
444 return;
445 }
446
447 old = inb(ICEMT1724(ice, RATE));
448 if (force || old != val)
449 outb(val, ICEMT1724(ice, RATE));
450 else if (rate == ice->cur_rate) {
451 spin_unlock_irqrestore(&ice->reg_lock, flags);
452 return;
453 }
454
455 ice->cur_rate = rate;
456
457 /* check MT02 */
458 mclk_change = 0;
459 if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
460 val = old = inb(ICEMT1724(ice, I2S_FORMAT));
461 if (rate > 96000)
462 val |= VT1724_MT_I2S_MCLK_128X; /* 128x MCLK */
463 else
464 val &= ~VT1724_MT_I2S_MCLK_128X; /* 256x MCLK */
465 if (val != old) {
466 outb(val, ICEMT1724(ice, I2S_FORMAT));
467 mclk_change = 1;
468 }
469 }
470 spin_unlock_irqrestore(&ice->reg_lock, flags);
471
472 if (mclk_change && ice->gpio.i2s_mclk_changed)
473 ice->gpio.i2s_mclk_changed(ice);
474 if (ice->gpio.set_pro_rate)
475 ice->gpio.set_pro_rate(ice, rate);
476
477 /* set up codecs */
478 for (i = 0; i < ice->akm_codecs; i++) {
479 if (ice->akm[i].ops.set_rate_val)
480 ice->akm[i].ops.set_rate_val(&ice->akm[i], rate);
481 }
482 if (ice->spdif.ops.setup_rate)
483 ice->spdif.ops.setup_rate(ice, rate);
484}
485
486static int snd_vt1724_pcm_hw_params(snd_pcm_substream_t * substream,
487 snd_pcm_hw_params_t * hw_params)
488{
489 ice1712_t *ice = snd_pcm_substream_chip(substream);
490 int i, chs;
491
492 chs = params_channels(hw_params);
493 down(&ice->open_mutex);
494 /* mark surround channels */
495 if (substream == ice->playback_pro_substream) {
496 /* PDMA0 can be multi-channel up to 8 */
497 chs = chs / 2 - 1;
498 for (i = 0; i < chs; i++) {
499 if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) {
500 up(&ice->open_mutex);
501 return -EBUSY;
502 }
503 ice->pcm_reserved[i] = substream;
504 }
505 for (; i < 3; i++) {
506 if (ice->pcm_reserved[i] == substream)
507 ice->pcm_reserved[i] = NULL;
508 }
509 } else {
510 for (i = 0; i < 3; i++) {
511 /* check individual playback stream */
512 if (ice->playback_con_substream_ds[i] == substream) {
513 if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) {
514 up(&ice->open_mutex);
515 return -EBUSY;
516 }
517 ice->pcm_reserved[i] = substream;
518 break;
519 }
520 }
521 }
522 up(&ice->open_mutex);
523 snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
524 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
525}
526
527static int snd_vt1724_pcm_hw_free(snd_pcm_substream_t * substream)
528{
529 ice1712_t *ice = snd_pcm_substream_chip(substream);
530 int i;
531
532 down(&ice->open_mutex);
533 /* unmark surround channels */
534 for (i = 0; i < 3; i++)
535 if (ice->pcm_reserved[i] == substream)
536 ice->pcm_reserved[i] = NULL;
537 up(&ice->open_mutex);
538 return snd_pcm_lib_free_pages(substream);
539}
540
541static int snd_vt1724_playback_pro_prepare(snd_pcm_substream_t * substream)
542{
543 ice1712_t *ice = snd_pcm_substream_chip(substream);
544 unsigned char val;
545 unsigned int size;
546
547 spin_lock_irq(&ice->reg_lock);
548 val = (8 - substream->runtime->channels) >> 1;
549 outb(val, ICEMT1724(ice, BURST));
550
551 outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR));
552
553 size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1;
554 // outl(size, ICEMT1724(ice, PLAYBACK_SIZE));
555 outw(size, ICEMT1724(ice, PLAYBACK_SIZE));
556 outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2);
557 size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
558 // outl(size, ICEMT1724(ice, PLAYBACK_COUNT));
559 outw(size, ICEMT1724(ice, PLAYBACK_COUNT));
560 outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2);
561
562 spin_unlock_irq(&ice->reg_lock);
563
564 // printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream));
565 return 0;
566}
567
568static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(snd_pcm_substream_t * substream)
569{
570 ice1712_t *ice = snd_pcm_substream_chip(substream);
571 size_t ptr;
572
573 if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & VT1724_PDMA0_START))
574 return 0;
575#if 0 /* read PLAYBACK_ADDR */
576 ptr = inl(ICEMT1724(ice, PLAYBACK_ADDR));
577 if (ptr < substream->runtime->dma_addr) {
578 snd_printd("ice1724: invalid negative ptr\n");
579 return 0;
580 }
581 ptr -= substream->runtime->dma_addr;
582 ptr = bytes_to_frames(substream->runtime, ptr);
583 if (ptr >= substream->runtime->buffer_size) {
584 snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->period_size);
585 return 0;
586 }
587#else /* read PLAYBACK_SIZE */
588 ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff;
589 ptr = (ptr + 1) << 2;
590 ptr = bytes_to_frames(substream->runtime, ptr);
591 if (! ptr)
592 ;
593 else if (ptr <= substream->runtime->buffer_size)
594 ptr = substream->runtime->buffer_size - ptr;
595 else {
596 snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->buffer_size);
597 ptr = 0;
598 }
599#endif
600 return ptr;
601}
602
603static int snd_vt1724_pcm_prepare(snd_pcm_substream_t *substream)
604{
605 ice1712_t *ice = snd_pcm_substream_chip(substream);
606 struct vt1724_pcm_reg *reg = substream->runtime->private_data;
607
608 spin_lock_irq(&ice->reg_lock);
609 outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
610 outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1, ice->profi_port + reg->size);
611 outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ice->profi_port + reg->count);
612 spin_unlock_irq(&ice->reg_lock);
613 return 0;
614}
615
616static snd_pcm_uframes_t snd_vt1724_pcm_pointer(snd_pcm_substream_t *substream)
617{
618 ice1712_t *ice = snd_pcm_substream_chip(substream);
619 struct vt1724_pcm_reg *reg = substream->runtime->private_data;
620 size_t ptr;
621
622 if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start))
623 return 0;
624#if 0 /* use ADDR register */
625 ptr = inl(ice->profi_port + reg->addr);
626 ptr -= substream->runtime->dma_addr;
627 return bytes_to_frames(substream->runtime, ptr);
628#else /* use SIZE register */
629 ptr = inw(ice->profi_port + reg->size);
630 ptr = (ptr + 1) << 2;
631 ptr = bytes_to_frames(substream->runtime, ptr);
632 if (! ptr)
633 ;
634 else if (ptr <= substream->runtime->buffer_size)
635 ptr = substream->runtime->buffer_size - ptr;
636 else {
637 snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->buffer_size);
638 ptr = 0;
639 }
640 return ptr;
641#endif
642}
643
644static struct vt1724_pcm_reg vt1724_playback_pro_reg = {
645 .addr = VT1724_MT_PLAYBACK_ADDR,
646 .size = VT1724_MT_PLAYBACK_SIZE,
647 .count = VT1724_MT_PLAYBACK_COUNT,
648 .start = VT1724_PDMA0_START,
649};
650
651static struct vt1724_pcm_reg vt1724_capture_pro_reg = {
652 .addr = VT1724_MT_CAPTURE_ADDR,
653 .size = VT1724_MT_CAPTURE_SIZE,
654 .count = VT1724_MT_CAPTURE_COUNT,
655 .start = VT1724_RDMA0_START,
656};
657
658static snd_pcm_hardware_t snd_vt1724_playback_pro =
659{
660 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
661 SNDRV_PCM_INFO_BLOCK_TRANSFER |
662 SNDRV_PCM_INFO_MMAP_VALID |
663 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
664 .formats = SNDRV_PCM_FMTBIT_S32_LE,
665 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
666 .rate_min = 8000,
667 .rate_max = 192000,
668 .channels_min = 2,
669 .channels_max = 8,
670 .buffer_bytes_max = (1UL << 21), /* 19bits dword */
671 .period_bytes_min = 8 * 4 * 2, /* FIXME: constraints needed */
672 .period_bytes_max = (1UL << 21),
673 .periods_min = 2,
674 .periods_max = 1024,
675};
676
677static snd_pcm_hardware_t snd_vt1724_spdif =
678{
679 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
680 SNDRV_PCM_INFO_BLOCK_TRANSFER |
681 SNDRV_PCM_INFO_MMAP_VALID |
682 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
683 .formats = SNDRV_PCM_FMTBIT_S32_LE,
684 .rates = SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
685 .rate_min = 32000,
686 .rate_max = 48000,
687 .channels_min = 2,
688 .channels_max = 2,
689 .buffer_bytes_max = (1UL << 18), /* 16bits dword */
690 .period_bytes_min = 2 * 4 * 2,
691 .period_bytes_max = (1UL << 18),
692 .periods_min = 2,
693 .periods_max = 1024,
694};
695
696static snd_pcm_hardware_t snd_vt1724_2ch_stereo =
697{
698 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
699 SNDRV_PCM_INFO_BLOCK_TRANSFER |
700 SNDRV_PCM_INFO_MMAP_VALID |
701 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
702 .formats = SNDRV_PCM_FMTBIT_S32_LE,
703 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
704 .rate_min = 8000,
705 .rate_max = 192000,
706 .channels_min = 2,
707 .channels_max = 2,
708 .buffer_bytes_max = (1UL << 18), /* 16bits dword */
709 .period_bytes_min = 2 * 4 * 2,
710 .period_bytes_max = (1UL << 18),
711 .periods_min = 2,
712 .periods_max = 1024,
713};
714
715/*
716 * set rate constraints
717 */
718static int set_rate_constraints(ice1712_t *ice, snd_pcm_substream_t *substream)
719{
720 snd_pcm_runtime_t *runtime = substream->runtime;
721 if (ice->hw_rates) {
722 /* hardware specific */
723 runtime->hw.rate_min = ice->hw_rates->list[0];
724 runtime->hw.rate_max = ice->hw_rates->list[ice->hw_rates->count - 1];
725 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
726 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ice->hw_rates);
727 }
728 if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
729 /* I2S */
730 /* VT1720 doesn't support more than 96kHz */
731 if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
732 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192);
733 else {
734 runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000;
735 runtime->hw.rate_max = 96000;
736 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
737 }
738 } else if (ice->ac97) {
739 /* ACLINK */
740 runtime->hw.rate_max = 48000;
741 runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000;
742 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_48);
743 }
744 return 0;
745}
746
747/* multi-channel playback needs alignment 8x32bit regardless of the channels
748 * actually used
749 */
750#define VT1724_BUFFER_ALIGN 0x20
751
752static int snd_vt1724_playback_pro_open(snd_pcm_substream_t * substream)
753{
754 snd_pcm_runtime_t *runtime = substream->runtime;
755 ice1712_t *ice = snd_pcm_substream_chip(substream);
756 int chs;
757
758 runtime->private_data = &vt1724_playback_pro_reg;
759 ice->playback_pro_substream = substream;
760 runtime->hw = snd_vt1724_playback_pro;
761 snd_pcm_set_sync(substream);
762 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
763 set_rate_constraints(ice, substream);
764 down(&ice->open_mutex);
765 /* calculate the currently available channels */
766 for (chs = 0; chs < 3; chs++) {
767 if (ice->pcm_reserved[chs])
768 break;
769 }
770 chs = (chs + 1) * 2;
771 runtime->hw.channels_max = chs;
772 if (chs > 2) /* channels must be even */
773 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
774 up(&ice->open_mutex);
775 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
776 VT1724_BUFFER_ALIGN);
777 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
778 VT1724_BUFFER_ALIGN);
779 return 0;
780}
781
782static int snd_vt1724_capture_pro_open(snd_pcm_substream_t * substream)
783{
784 ice1712_t *ice = snd_pcm_substream_chip(substream);
785 snd_pcm_runtime_t *runtime = substream->runtime;
786
787 runtime->private_data = &vt1724_capture_pro_reg;
788 ice->capture_pro_substream = substream;
789 runtime->hw = snd_vt1724_2ch_stereo;
790 snd_pcm_set_sync(substream);
791 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
792 set_rate_constraints(ice, substream);
793 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
794 VT1724_BUFFER_ALIGN);
795 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
796 VT1724_BUFFER_ALIGN);
797 return 0;
798}
799
800static int snd_vt1724_playback_pro_close(snd_pcm_substream_t * substream)
801{
802 ice1712_t *ice = snd_pcm_substream_chip(substream);
803
804 if (PRO_RATE_RESET)
805 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
806 ice->playback_pro_substream = NULL;
807
808 return 0;
809}
810
811static int snd_vt1724_capture_pro_close(snd_pcm_substream_t * substream)
812{
813 ice1712_t *ice = snd_pcm_substream_chip(substream);
814
815 if (PRO_RATE_RESET)
816 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
817 ice->capture_pro_substream = NULL;
818 return 0;
819}
820
821static snd_pcm_ops_t snd_vt1724_playback_pro_ops = {
822 .open = snd_vt1724_playback_pro_open,
823 .close = snd_vt1724_playback_pro_close,
824 .ioctl = snd_pcm_lib_ioctl,
825 .hw_params = snd_vt1724_pcm_hw_params,
826 .hw_free = snd_vt1724_pcm_hw_free,
827 .prepare = snd_vt1724_playback_pro_prepare,
828 .trigger = snd_vt1724_pcm_trigger,
829 .pointer = snd_vt1724_playback_pro_pointer,
830};
831
832static snd_pcm_ops_t snd_vt1724_capture_pro_ops = {
833 .open = snd_vt1724_capture_pro_open,
834 .close = snd_vt1724_capture_pro_close,
835 .ioctl = snd_pcm_lib_ioctl,
836 .hw_params = snd_vt1724_pcm_hw_params,
837 .hw_free = snd_vt1724_pcm_hw_free,
838 .prepare = snd_vt1724_pcm_prepare,
839 .trigger = snd_vt1724_pcm_trigger,
840 .pointer = snd_vt1724_pcm_pointer,
841};
842
843static int __devinit snd_vt1724_pcm_profi(ice1712_t * ice, int device)
844{
845 snd_pcm_t *pcm;
846 int err;
847
848 err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm);
849 if (err < 0)
850 return err;
851
852 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops);
853 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vt1724_capture_pro_ops);
854
855 pcm->private_data = ice;
856 pcm->info_flags = 0;
857 strcpy(pcm->name, "ICE1724");
858
859 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
860 snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
861
862 ice->pcm_pro = pcm;
863
864 return 0;
865}
866
867
868/*
869 * SPDIF PCM
870 */
871
872static struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
873 .addr = VT1724_MT_PDMA4_ADDR,
874 .size = VT1724_MT_PDMA4_SIZE,
875 .count = VT1724_MT_PDMA4_COUNT,
876 .start = VT1724_PDMA4_START,
877};
878
879static struct vt1724_pcm_reg vt1724_capture_spdif_reg = {
880 .addr = VT1724_MT_RDMA1_ADDR,
881 .size = VT1724_MT_RDMA1_SIZE,
882 .count = VT1724_MT_RDMA1_COUNT,
883 .start = VT1724_RDMA1_START,
884};
885
886/* update spdif control bits; call with reg_lock */
887static void update_spdif_bits(ice1712_t *ice, unsigned int val)
888{
889 unsigned char cbit, disabled;
890
891 cbit = inb(ICEREG1724(ice, SPDIF_CFG));
892 disabled = cbit & ~VT1724_CFG_SPDIF_OUT_EN;
893 if (cbit != disabled)
894 outb(disabled, ICEREG1724(ice, SPDIF_CFG));
895 outw(val, ICEMT1724(ice, SPDIF_CTRL));
896 if (cbit != disabled)
897 outb(cbit, ICEREG1724(ice, SPDIF_CFG));
898 outw(val, ICEMT1724(ice, SPDIF_CTRL));
899}
900
901/* update SPDIF control bits according to the given rate */
902static void update_spdif_rate(ice1712_t *ice, unsigned int rate)
903{
904 unsigned int val, nval;
905 unsigned long flags;
906
907 spin_lock_irqsave(&ice->reg_lock, flags);
908 nval = val = inw(ICEMT1724(ice, SPDIF_CTRL));
909 nval &= ~(7 << 12);
910 switch (rate) {
911 case 44100: break;
912 case 48000: nval |= 2 << 12; break;
913 case 32000: nval |= 3 << 12; break;
914 }
915 if (val != nval)
916 update_spdif_bits(ice, nval);
917 spin_unlock_irqrestore(&ice->reg_lock, flags);
918}
919
920static int snd_vt1724_playback_spdif_prepare(snd_pcm_substream_t * substream)
921{
922 ice1712_t *ice = snd_pcm_substream_chip(substream);
923 if (! ice->force_pdma4)
924 update_spdif_rate(ice, substream->runtime->rate);
925 return snd_vt1724_pcm_prepare(substream);
926}
927
928static int snd_vt1724_playback_spdif_open(snd_pcm_substream_t *substream)
929{
930 ice1712_t *ice = snd_pcm_substream_chip(substream);
931 snd_pcm_runtime_t *runtime = substream->runtime;
932
933 runtime->private_data = &vt1724_playback_spdif_reg;
934 ice->playback_con_substream = substream;
935 if (ice->force_pdma4) {
936 runtime->hw = snd_vt1724_2ch_stereo;
937 set_rate_constraints(ice, substream);
938 } else
939 runtime->hw = snd_vt1724_spdif;
940 snd_pcm_set_sync(substream);
941 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
942 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
943 VT1724_BUFFER_ALIGN);
944 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
945 VT1724_BUFFER_ALIGN);
946 return 0;
947}
948
949static int snd_vt1724_playback_spdif_close(snd_pcm_substream_t * substream)
950{
951 ice1712_t *ice = snd_pcm_substream_chip(substream);
952
953 if (PRO_RATE_RESET)
954 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
955 ice->playback_con_substream = NULL;
956
957 return 0;
958}
959
960static int snd_vt1724_capture_spdif_open(snd_pcm_substream_t *substream)
961{
962 ice1712_t *ice = snd_pcm_substream_chip(substream);
963 snd_pcm_runtime_t *runtime = substream->runtime;
964
965 runtime->private_data = &vt1724_capture_spdif_reg;
966 ice->capture_con_substream = substream;
967 if (ice->force_rdma1) {
968 runtime->hw = snd_vt1724_2ch_stereo;
969 set_rate_constraints(ice, substream);
970 } else
971 runtime->hw = snd_vt1724_spdif;
972 snd_pcm_set_sync(substream);
973 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
974 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
975 VT1724_BUFFER_ALIGN);
976 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
977 VT1724_BUFFER_ALIGN);
978 return 0;
979}
980
981static int snd_vt1724_capture_spdif_close(snd_pcm_substream_t * substream)
982{
983 ice1712_t *ice = snd_pcm_substream_chip(substream);
984
985 if (PRO_RATE_RESET)
986 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
987 ice->capture_con_substream = NULL;
988
989 return 0;
990}
991
992static snd_pcm_ops_t snd_vt1724_playback_spdif_ops = {
993 .open = snd_vt1724_playback_spdif_open,
994 .close = snd_vt1724_playback_spdif_close,
995 .ioctl = snd_pcm_lib_ioctl,
996 .hw_params = snd_vt1724_pcm_hw_params,
997 .hw_free = snd_vt1724_pcm_hw_free,
998 .prepare = snd_vt1724_playback_spdif_prepare,
999 .trigger = snd_vt1724_pcm_trigger,
1000 .pointer = snd_vt1724_pcm_pointer,
1001};
1002
1003static snd_pcm_ops_t snd_vt1724_capture_spdif_ops = {
1004 .open = snd_vt1724_capture_spdif_open,
1005 .close = snd_vt1724_capture_spdif_close,
1006 .ioctl = snd_pcm_lib_ioctl,
1007 .hw_params = snd_vt1724_pcm_hw_params,
1008 .hw_free = snd_vt1724_pcm_hw_free,
1009 .prepare = snd_vt1724_pcm_prepare,
1010 .trigger = snd_vt1724_pcm_trigger,
1011 .pointer = snd_vt1724_pcm_pointer,
1012};
1013
1014
1015static int __devinit snd_vt1724_pcm_spdif(ice1712_t * ice, int device)
1016{
1017 char *name;
1018 snd_pcm_t *pcm;
1019 int play, capt;
1020 int err;
1021
1022 if (ice->force_pdma4 ||
1023 (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_OUT_INT)) {
1024 play = 1;
1025 ice->has_spdif = 1;
1026 } else
1027 play = 0;
1028 if (ice->force_rdma1 ||
1029 (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) {
1030 capt = 1;
1031 ice->has_spdif = 1;
1032 } else
1033 capt = 0;
1034 if (! play && ! capt)
1035 return 0; /* no spdif device */
1036
1037 if (ice->force_pdma4 || ice->force_rdma1)
1038 name = "ICE1724 Secondary";
1039 else
1040 name = "IEC1724 IEC958";
1041 err = snd_pcm_new(ice->card, name, device, play, capt, &pcm);
1042 if (err < 0)
1043 return err;
1044
1045 if (play)
1046 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1047 &snd_vt1724_playback_spdif_ops);
1048 if (capt)
1049 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1050 &snd_vt1724_capture_spdif_ops);
1051
1052 pcm->private_data = ice;
1053 pcm->info_flags = 0;
1054 strcpy(pcm->name, name);
1055
1056 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1057 snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
1058
1059 ice->pcm = pcm;
1060
1061 return 0;
1062}
1063
1064
1065/*
1066 * independent surround PCMs
1067 */
1068
1069static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
1070 {
1071 .addr = VT1724_MT_PDMA1_ADDR,
1072 .size = VT1724_MT_PDMA1_SIZE,
1073 .count = VT1724_MT_PDMA1_COUNT,
1074 .start = VT1724_PDMA1_START,
1075 },
1076 {
1077 .addr = VT1724_MT_PDMA2_ADDR,
1078 .size = VT1724_MT_PDMA2_SIZE,
1079 .count = VT1724_MT_PDMA2_COUNT,
1080 .start = VT1724_PDMA2_START,
1081 },
1082 {
1083 .addr = VT1724_MT_PDMA3_ADDR,
1084 .size = VT1724_MT_PDMA3_SIZE,
1085 .count = VT1724_MT_PDMA3_COUNT,
1086 .start = VT1724_PDMA3_START,
1087 },
1088};
1089
1090static int snd_vt1724_playback_indep_prepare(snd_pcm_substream_t * substream)
1091{
1092 ice1712_t *ice = snd_pcm_substream_chip(substream);
1093 unsigned char val;
1094
1095 spin_lock_irq(&ice->reg_lock);
1096 val = 3 - substream->number;
1097 if (inb(ICEMT1724(ice, BURST)) < val)
1098 outb(val, ICEMT1724(ice, BURST));
1099 spin_unlock_irq(&ice->reg_lock);
1100 return snd_vt1724_pcm_prepare(substream);
1101}
1102
1103static int snd_vt1724_playback_indep_open(snd_pcm_substream_t *substream)
1104{
1105 ice1712_t *ice = snd_pcm_substream_chip(substream);
1106 snd_pcm_runtime_t *runtime = substream->runtime;
1107
1108 down(&ice->open_mutex);
1109 /* already used by PDMA0? */
1110 if (ice->pcm_reserved[substream->number]) {
1111 up(&ice->open_mutex);
1112 return -EBUSY; /* FIXME: should handle blocking mode properly */
1113 }
1114 up(&ice->open_mutex);
1115 runtime->private_data = &vt1724_playback_dma_regs[substream->number];
1116 ice->playback_con_substream_ds[substream->number] = substream;
1117 runtime->hw = snd_vt1724_2ch_stereo;
1118 snd_pcm_set_sync(substream);
1119 snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
1120 set_rate_constraints(ice, substream);
1121 return 0;
1122}
1123
1124static int snd_vt1724_playback_indep_close(snd_pcm_substream_t * substream)
1125{
1126 ice1712_t *ice = snd_pcm_substream_chip(substream);
1127
1128 if (PRO_RATE_RESET)
1129 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
1130 ice->playback_con_substream_ds[substream->number] = NULL;
1131 ice->pcm_reserved[substream->number] = NULL;
1132
1133 return 0;
1134}
1135
1136static snd_pcm_ops_t snd_vt1724_playback_indep_ops = {
1137 .open = snd_vt1724_playback_indep_open,
1138 .close = snd_vt1724_playback_indep_close,
1139 .ioctl = snd_pcm_lib_ioctl,
1140 .hw_params = snd_vt1724_pcm_hw_params,
1141 .hw_free = snd_vt1724_pcm_hw_free,
1142 .prepare = snd_vt1724_playback_indep_prepare,
1143 .trigger = snd_vt1724_pcm_trigger,
1144 .pointer = snd_vt1724_pcm_pointer,
1145};
1146
1147
1148static int __devinit snd_vt1724_pcm_indep(ice1712_t * ice, int device)
1149{
1150 snd_pcm_t *pcm;
1151 int play;
1152 int err;
1153
1154 play = ice->num_total_dacs / 2 - 1;
1155 if (play <= 0)
1156 return 0;
1157
1158 err = snd_pcm_new(ice->card, "ICE1724 Surrounds", device, play, 0, &pcm);
1159 if (err < 0)
1160 return err;
1161
1162 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1163 &snd_vt1724_playback_indep_ops);
1164
1165 pcm->private_data = ice;
1166 pcm->info_flags = 0;
1167 strcpy(pcm->name, "ICE1724 Surround PCM");
1168
1169 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1170 snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
1171
1172 ice->pcm_ds = pcm;
1173
1174 return 0;
1175}
1176
1177
1178/*
1179 * Mixer section
1180 */
1181
1182static int __devinit snd_vt1724_ac97_mixer(ice1712_t * ice)
1183{
1184 int err;
1185
1186 if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
1187 ac97_bus_t *pbus;
1188 ac97_template_t ac97;
1189 static ac97_bus_ops_t ops = {
1190 .write = snd_vt1724_ac97_write,
1191 .read = snd_vt1724_ac97_read,
1192 };
1193
1194 /* cold reset */
1195 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
1196 mdelay(5); /* FIXME */
1197 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
1198
1199 if ((err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus)) < 0)
1200 return err;
1201 memset(&ac97, 0, sizeof(ac97));
1202 ac97.private_data = ice;
1203 if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0)
1204 printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
1205 else
1206 return 0;
1207 }
1208 /* I2S mixer only */
1209 strcat(ice->card->mixername, "ICE1724 - multitrack");
1210 return 0;
1211}
1212
1213/*
1214 *
1215 */
1216
1217static inline unsigned int eeprom_triple(ice1712_t *ice, int idx)
1218{
1219 return (unsigned int)ice->eeprom.data[idx] | \
1220 ((unsigned int)ice->eeprom.data[idx + 1] << 8) | \
1221 ((unsigned int)ice->eeprom.data[idx + 2] << 16);
1222}
1223
1224static void snd_vt1724_proc_read(snd_info_entry_t *entry,
1225 snd_info_buffer_t * buffer)
1226{
1227 ice1712_t *ice = entry->private_data;
1228 unsigned int idx;
1229
1230 snd_iprintf(buffer, "%s\n\n", ice->card->longname);
1231 snd_iprintf(buffer, "EEPROM:\n");
1232
1233 snd_iprintf(buffer, " Subvendor : 0x%x\n", ice->eeprom.subvendor);
1234 snd_iprintf(buffer, " Size : %i bytes\n", ice->eeprom.size);
1235 snd_iprintf(buffer, " Version : %i\n", ice->eeprom.version);
1236 snd_iprintf(buffer, " System Config : 0x%x\n", ice->eeprom.data[ICE_EEP2_SYSCONF]);
1237 snd_iprintf(buffer, " ACLink : 0x%x\n", ice->eeprom.data[ICE_EEP2_ACLINK]);
1238 snd_iprintf(buffer, " I2S : 0x%x\n", ice->eeprom.data[ICE_EEP2_I2S]);
1239 snd_iprintf(buffer, " S/PDIF : 0x%x\n", ice->eeprom.data[ICE_EEP2_SPDIF]);
1240 snd_iprintf(buffer, " GPIO direction : 0x%x\n", ice->eeprom.gpiodir);
1241 snd_iprintf(buffer, " GPIO mask : 0x%x\n", ice->eeprom.gpiomask);
1242 snd_iprintf(buffer, " GPIO state : 0x%x\n", ice->eeprom.gpiostate);
1243 for (idx = 0x12; idx < ice->eeprom.size; idx++)
1244 snd_iprintf(buffer, " Extra #%02i : 0x%x\n", idx, ice->eeprom.data[idx]);
1245
1246 snd_iprintf(buffer, "\nRegisters:\n");
1247
1248 snd_iprintf(buffer, " PSDOUT03 : 0x%08x\n", (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
1249 for (idx = 0x0; idx < 0x20 ; idx++)
1250 snd_iprintf(buffer, " CCS%02x : 0x%02x\n", idx, inb(ice->port+idx));
1251 for (idx = 0x0; idx < 0x30 ; idx++)
1252 snd_iprintf(buffer, " MT%02x : 0x%02x\n", idx, inb(ice->profi_port+idx));
1253}
1254
1255static void __devinit snd_vt1724_proc_init(ice1712_t * ice)
1256{
1257 snd_info_entry_t *entry;
1258
1259 if (! snd_card_proc_new(ice->card, "ice1724", &entry))
1260 snd_info_set_text_ops(entry, ice, 1024, snd_vt1724_proc_read);
1261}
1262
1263/*
1264 *
1265 */
1266
1267static int snd_vt1724_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1268{
1269 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1270 uinfo->count = sizeof(ice1712_eeprom_t);
1271 return 0;
1272}
1273
1274static int snd_vt1724_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1275{
1276 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1277
1278 memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
1279 return 0;
1280}
1281
1282static snd_kcontrol_new_t snd_vt1724_eeprom __devinitdata = {
1283 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1284 .name = "ICE1724 EEPROM",
1285 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1286 .info = snd_vt1724_eeprom_info,
1287 .get = snd_vt1724_eeprom_get
1288};
1289
1290/*
1291 */
1292static int snd_vt1724_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1293{
1294 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1295 uinfo->count = 1;
1296 return 0;
1297}
1298
1299static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
1300{
1301 unsigned int val;
1302
1303 val = diga->status[0] & 0x03; /* professional, non-audio */
1304 if (val & 0x01) {
1305 /* professional */
1306 if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
1307 val |= 1U << 3;
1308 switch (diga->status[0] & IEC958_AES0_PRO_FS) {
1309 case IEC958_AES0_PRO_FS_44100:
1310 break;
1311 case IEC958_AES0_PRO_FS_32000:
1312 val |= 3U << 12;
1313 break;
1314 default:
1315 val |= 2U << 12;
1316 break;
1317 }
1318 } else {
1319 /* consumer */
1320 val |= diga->status[1] & 0x04; /* copyright */
1321 if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS)== IEC958_AES0_CON_EMPHASIS_5015)
1322 val |= 1U << 3;
1323 val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */
1324 val |= (unsigned int)(diga->status[3] & IEC958_AES3_CON_FS) << 12; /* fs */
1325 }
1326 return val;
1327}
1328
1329static void decode_spdif_bits(snd_aes_iec958_t *diga, unsigned int val)
1330{
1331 memset(diga->status, 0, sizeof(diga->status));
1332 diga->status[0] = val & 0x03; /* professional, non-audio */
1333 if (val & 0x01) {
1334 /* professional */
1335 if (val & (1U << 3))
1336 diga->status[0] |= IEC958_AES0_PRO_EMPHASIS_5015;
1337 switch ((val >> 12) & 0x7) {
1338 case 0:
1339 break;
1340 case 2:
1341 diga->status[0] |= IEC958_AES0_PRO_FS_32000;
1342 break;
1343 default:
1344 diga->status[0] |= IEC958_AES0_PRO_FS_48000;
1345 break;
1346 }
1347 } else {
1348 /* consumer */
1349 diga->status[0] |= val & (1U << 2); /* copyright */
1350 if (val & (1U << 3))
1351 diga->status[0] |= IEC958_AES0_CON_EMPHASIS_5015;
1352 diga->status[1] |= (val >> 4) & 0x3f; /* category */
1353 diga->status[3] |= (val >> 12) & 0x07; /* fs */
1354 }
1355}
1356
1357static int snd_vt1724_spdif_default_get(snd_kcontrol_t * kcontrol,
1358 snd_ctl_elem_value_t * ucontrol)
1359{
1360 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1361 unsigned int val;
1362 val = inw(ICEMT1724(ice, SPDIF_CTRL));
1363 decode_spdif_bits(&ucontrol->value.iec958, val);
1364 return 0;
1365}
1366
1367static int snd_vt1724_spdif_default_put(snd_kcontrol_t * kcontrol,
1368 snd_ctl_elem_value_t * ucontrol)
1369{
1370 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1371 unsigned int val, old;
1372
1373 val = encode_spdif_bits(&ucontrol->value.iec958);
1374 spin_lock_irq(&ice->reg_lock);
1375 old = inw(ICEMT1724(ice, SPDIF_CTRL));
1376 if (val != old)
1377 update_spdif_bits(ice, val);
1378 spin_unlock_irq(&ice->reg_lock);
1379 return (val != old);
1380}
1381
1382static snd_kcontrol_new_t snd_vt1724_spdif_default __devinitdata =
1383{
1384 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1385 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1386 .info = snd_vt1724_spdif_info,
1387 .get = snd_vt1724_spdif_default_get,
1388 .put = snd_vt1724_spdif_default_put
1389};
1390
1391static int snd_vt1724_spdif_maskc_get(snd_kcontrol_t * kcontrol,
1392 snd_ctl_elem_value_t * ucontrol)
1393{
1394 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1395 IEC958_AES0_PROFESSIONAL |
1396 IEC958_AES0_CON_NOT_COPYRIGHT |
1397 IEC958_AES0_CON_EMPHASIS;
1398 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
1399 IEC958_AES1_CON_CATEGORY;
1400 ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
1401 return 0;
1402}
1403
1404static int snd_vt1724_spdif_maskp_get(snd_kcontrol_t * kcontrol,
1405 snd_ctl_elem_value_t * ucontrol)
1406{
1407 ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
1408 IEC958_AES0_PROFESSIONAL |
1409 IEC958_AES0_PRO_FS |
1410 IEC958_AES0_PRO_EMPHASIS;
1411 return 0;
1412}
1413
1414static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata =
1415{
1416 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1418 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
1419 .info = snd_vt1724_spdif_info,
1420 .get = snd_vt1724_spdif_maskc_get,
1421};
1422
1423static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata =
1424{
1425 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
1428 .info = snd_vt1724_spdif_info,
1429 .get = snd_vt1724_spdif_maskp_get,
1430};
1431
1432static int snd_vt1724_spdif_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1433{
1434 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1435 uinfo->count = 1;
1436 uinfo->value.integer.min = 0;
1437 uinfo->value.integer.max = 1;
1438 return 0;
1439}
1440
1441static int snd_vt1724_spdif_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1442{
1443 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1444 ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) & VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;
1445 return 0;
1446}
1447
1448static int snd_vt1724_spdif_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1449{
1450 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1451 unsigned char old, val;
1452
1453 spin_lock_irq(&ice->reg_lock);
1454 old = val = inb(ICEREG1724(ice, SPDIF_CFG));
1455 val &= ~VT1724_CFG_SPDIF_OUT_EN;
1456 if (ucontrol->value.integer.value[0])
1457 val |= VT1724_CFG_SPDIF_OUT_EN;
1458 if (old != val)
1459 outb(val, ICEREG1724(ice, SPDIF_CFG));
1460 spin_unlock_irq(&ice->reg_lock);
1461 return old != val;
1462}
1463
1464static snd_kcontrol_new_t snd_vt1724_spdif_switch __devinitdata =
1465{
1466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1467 /* FIXME: the following conflict with IEC958 Playback Route */
1468 // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
1469 .name = "IEC958 Output Switch",
1470 .info = snd_vt1724_spdif_sw_info,
1471 .get = snd_vt1724_spdif_sw_get,
1472 .put = snd_vt1724_spdif_sw_put
1473};
1474
1475
1476#if 0 /* NOT USED YET */
1477/*
1478 * GPIO access from extern
1479 */
1480
1481int snd_vt1724_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1482{
1483 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1484 uinfo->count = 1;
1485 uinfo->value.integer.min = 0;
1486 uinfo->value.integer.max = 1;
1487 return 0;
1488}
1489
1490int snd_vt1724_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1491{
1492 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1493 int shift = kcontrol->private_value & 0xff;
1494 int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
1495
1496 snd_ice1712_save_gpio_status(ice);
1497 ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
1498 snd_ice1712_restore_gpio_status(ice);
1499 return 0;
1500}
1501
1502int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1503{
1504 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1505 int shift = kcontrol->private_value & 0xff;
1506 int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
1507 unsigned int val, nval;
1508
1509 if (kcontrol->private_value & (1 << 31))
1510 return -EPERM;
1511 nval = (ucontrol->value.integer.value[0] ? (1 << shift) : 0) ^ invert;
1512 snd_ice1712_save_gpio_status(ice);
1513 val = snd_ice1712_gpio_read(ice);
1514 nval |= val & ~(1 << shift);
1515 if (val != nval)
1516 snd_ice1712_gpio_write(ice, nval);
1517 snd_ice1712_restore_gpio_status(ice);
1518 return val != nval;
1519}
1520#endif /* NOT USED YET */
1521
1522/*
1523 * rate
1524 */
1525static int snd_vt1724_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1526{
1527 static char *texts_1724[] = {
1528 "8000", /* 0: 6 */
1529 "9600", /* 1: 3 */
1530 "11025", /* 2: 10 */
1531 "12000", /* 3: 2 */
1532 "16000", /* 4: 5 */
1533 "22050", /* 5: 9 */
1534 "24000", /* 6: 1 */
1535 "32000", /* 7: 4 */
1536 "44100", /* 8: 8 */
1537 "48000", /* 9: 0 */
1538 "64000", /* 10: 15 */
1539 "88200", /* 11: 11 */
1540 "96000", /* 12: 7 */
1541 "176400", /* 13: 12 */
1542 "192000", /* 14: 14 */
1543 "IEC958 Input", /* 15: -- */
1544 };
1545 static char *texts_1720[] = {
1546 "8000", /* 0: 6 */
1547 "9600", /* 1: 3 */
1548 "11025", /* 2: 10 */
1549 "12000", /* 3: 2 */
1550 "16000", /* 4: 5 */
1551 "22050", /* 5: 9 */
1552 "24000", /* 6: 1 */
1553 "32000", /* 7: 4 */
1554 "44100", /* 8: 8 */
1555 "48000", /* 9: 0 */
1556 "64000", /* 10: 15 */
1557 "88200", /* 11: 11 */
1558 "96000", /* 12: 7 */
1559 "IEC958 Input", /* 13: -- */
1560 };
1561 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1562
1563 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1564 uinfo->count = 1;
1565 uinfo->value.enumerated.items = ice->vt1720 ? 14 : 16;
1566 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1567 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1568 strcpy(uinfo->value.enumerated.name,
1569 ice->vt1720 ? texts_1720[uinfo->value.enumerated.item] :
1570 texts_1724[uinfo->value.enumerated.item]);
1571 return 0;
1572}
1573
1574static int snd_vt1724_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1575{
1576 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1577 static unsigned char xlate[16] = {
1578 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10
1579 };
1580 unsigned char val;
1581
1582 spin_lock_irq(&ice->reg_lock);
1583 if (is_spdif_master(ice)) {
1584 ucontrol->value.enumerated.item[0] = ice->vt1720 ? 13 : 15;
1585 } else {
1586 val = xlate[inb(ICEMT1724(ice, RATE)) & 15];
1587 if (val == 255) {
1588 snd_BUG();
1589 val = 0;
1590 }
1591 ucontrol->value.enumerated.item[0] = val;
1592 }
1593 spin_unlock_irq(&ice->reg_lock);
1594 return 0;
1595}
1596
1597static int snd_vt1724_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1598{
1599 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1600 unsigned char oval;
1601 int rate;
1602 int change = 0;
1603 int spdif = ice->vt1720 ? 13 : 15;
1604
1605 spin_lock_irq(&ice->reg_lock);
1606 oval = inb(ICEMT1724(ice, RATE));
1607 if (ucontrol->value.enumerated.item[0] == spdif) {
1608 outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
1609 } else {
1610 rate = rates[ucontrol->value.integer.value[0] % 15];
1611 if (rate <= get_max_rate(ice)) {
1612 PRO_RATE_DEFAULT = rate;
1613 spin_unlock_irq(&ice->reg_lock);
1614 snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 1);
1615 spin_lock_irq(&ice->reg_lock);
1616 }
1617 }
1618 change = inb(ICEMT1724(ice, RATE)) != oval;
1619 spin_unlock_irq(&ice->reg_lock);
1620
1621 if ((oval & VT1724_SPDIF_MASTER) != (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER)) {
1622 /* notify akm chips as well */
1623 if (is_spdif_master(ice)) {
1624 unsigned int i;
1625 for (i = 0; i < ice->akm_codecs; i++) {
1626 if (ice->akm[i].ops.set_rate_val)
1627 ice->akm[i].ops.set_rate_val(&ice->akm[i], 0);
1628 }
1629 }
1630 }
1631 return change;
1632}
1633
1634static snd_kcontrol_new_t snd_vt1724_pro_internal_clock __devinitdata = {
1635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1636 .name = "Multi Track Internal Clock",
1637 .info = snd_vt1724_pro_internal_clock_info,
1638 .get = snd_vt1724_pro_internal_clock_get,
1639 .put = snd_vt1724_pro_internal_clock_put
1640};
1641
1642static int snd_vt1724_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1643{
1644 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1645 uinfo->count = 1;
1646 uinfo->value.integer.min = 0;
1647 uinfo->value.integer.max = 1;
1648 return 0;
1649}
1650
1651static int snd_vt1724_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1652{
1653 ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
1654 return 0;
1655}
1656
1657static int snd_vt1724_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1658{
1659 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1660 int change = 0, nval;
1661
1662 nval = ucontrol->value.integer.value[0] ? 1 : 0;
1663 spin_lock_irq(&ice->reg_lock);
1664 change = PRO_RATE_LOCKED != nval;
1665 PRO_RATE_LOCKED = nval;
1666 spin_unlock_irq(&ice->reg_lock);
1667 return change;
1668}
1669
1670static snd_kcontrol_new_t snd_vt1724_pro_rate_locking __devinitdata = {
1671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1672 .name = "Multi Track Rate Locking",
1673 .info = snd_vt1724_pro_rate_locking_info,
1674 .get = snd_vt1724_pro_rate_locking_get,
1675 .put = snd_vt1724_pro_rate_locking_put
1676};
1677
1678static int snd_vt1724_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1679{
1680 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1681 uinfo->count = 1;
1682 uinfo->value.integer.min = 0;
1683 uinfo->value.integer.max = 1;
1684 return 0;
1685}
1686
1687static int snd_vt1724_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1688{
1689 ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;
1690 return 0;
1691}
1692
1693static int snd_vt1724_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1694{
1695 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1696 int change = 0, nval;
1697
1698 nval = ucontrol->value.integer.value[0] ? 1 : 0;
1699 spin_lock_irq(&ice->reg_lock);
1700 change = PRO_RATE_RESET != nval;
1701 PRO_RATE_RESET = nval;
1702 spin_unlock_irq(&ice->reg_lock);
1703 return change;
1704}
1705
1706static snd_kcontrol_new_t snd_vt1724_pro_rate_reset __devinitdata = {
1707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1708 .name = "Multi Track Rate Reset",
1709 .info = snd_vt1724_pro_rate_reset_info,
1710 .get = snd_vt1724_pro_rate_reset_get,
1711 .put = snd_vt1724_pro_rate_reset_put
1712};
1713
1714
1715/*
1716 * routing
1717 */
1718static int snd_vt1724_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1719{
1720 static char *texts[] = {
1721 "PCM Out", /* 0 */
1722 "H/W In 0", "H/W In 1", /* 1-2 */
1723 "IEC958 In L", "IEC958 In R", /* 3-4 */
1724 };
1725
1726 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1727 uinfo->count = 1;
1728 uinfo->value.enumerated.items = 5;
1729 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1730 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1731 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1732 return 0;
1733}
1734
1735static inline int analog_route_shift(int idx)
1736{
1737 return (idx % 2) * 12 + ((idx / 2) * 3) + 8;
1738}
1739
1740static inline int digital_route_shift(int idx)
1741{
1742 return idx * 3;
1743}
1744
1745static int get_route_val(ice1712_t *ice, int shift)
1746{
1747 unsigned long val;
1748 unsigned char eitem;
1749 static unsigned char xlate[8] = {
1750 0, 255, 1, 2, 255, 255, 3, 4,
1751 };
1752
1753 val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
1754 val >>= shift;
1755 val &= 7; //we now have 3 bits per output
1756 eitem = xlate[val];
1757 if (eitem == 255) {
1758 snd_BUG();
1759 return 0;
1760 }
1761 return eitem;
1762}
1763
1764static int put_route_val(ice1712_t *ice, unsigned int val, int shift)
1765{
1766 unsigned int old_val, nval;
1767 int change;
1768 static unsigned char xroute[8] = {
1769 0, /* PCM */
1770 2, /* PSDIN0 Left */
1771 3, /* PSDIN0 Right */
1772 6, /* SPDIN Left */
1773 7, /* SPDIN Right */
1774 };
1775
1776 nval = xroute[val % 5];
1777 val = old_val = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
1778 val &= ~(0x07 << shift);
1779 val |= nval << shift;
1780 change = val != old_val;
1781 if (change)
1782 outl(val, ICEMT1724(ice, ROUTE_PLAYBACK));
1783 return change;
1784}
1785
1786static int snd_vt1724_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1787{
1788 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1789 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1790 ucontrol->value.enumerated.item[0] = get_route_val(ice, analog_route_shift(idx));
1791 return 0;
1792}
1793
1794static int snd_vt1724_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1795{
1796 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1797 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1798 return put_route_val(ice, ucontrol->value.enumerated.item[0],
1799 analog_route_shift(idx));
1800}
1801
1802static int snd_vt1724_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1803{
1804 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1805 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1806 ucontrol->value.enumerated.item[0] = get_route_val(ice, digital_route_shift(idx));
1807 return 0;
1808}
1809
1810static int snd_vt1724_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
1811{
1812 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1813 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1814 return put_route_val(ice, ucontrol->value.enumerated.item[0],
1815 digital_route_shift(idx));
1816}
1817
1818static snd_kcontrol_new_t snd_vt1724_mixer_pro_analog_route __devinitdata = {
1819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1820 .name = "H/W Playback Route",
1821 .info = snd_vt1724_pro_route_info,
1822 .get = snd_vt1724_pro_route_analog_get,
1823 .put = snd_vt1724_pro_route_analog_put,
1824};
1825
1826static snd_kcontrol_new_t snd_vt1724_mixer_pro_spdif_route __devinitdata = {
1827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1828 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
1829 .info = snd_vt1724_pro_route_info,
1830 .get = snd_vt1724_pro_route_spdif_get,
1831 .put = snd_vt1724_pro_route_spdif_put,
1832 .count = 2,
1833};
1834
1835
1836static int snd_vt1724_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1837{
1838 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1839 uinfo->count = 22; /* FIXME: for compatibility with ice1712... */
1840 uinfo->value.integer.min = 0;
1841 uinfo->value.integer.max = 255;
1842 return 0;
1843}
1844
1845static int snd_vt1724_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1846{
1847 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
1848 int idx;
1849
1850 spin_lock_irq(&ice->reg_lock);
1851 for (idx = 0; idx < 22; idx++) {
1852 outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
1853 ucontrol->value.integer.value[idx] = inb(ICEMT1724(ice, MONITOR_PEAKDATA));
1854 }
1855 spin_unlock_irq(&ice->reg_lock);
1856 return 0;
1857}
1858
1859static snd_kcontrol_new_t snd_vt1724_mixer_pro_peak __devinitdata = {
1860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1861 .name = "Multi Track Peak",
1862 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
1863 .info = snd_vt1724_pro_peak_info,
1864 .get = snd_vt1724_pro_peak_get
1865};
1866
1867/*
1868 *
1869 */
1870
1871static struct snd_ice1712_card_info no_matched __devinitdata;
1872
1873static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
1874 snd_vt1724_revo_cards,
1875 snd_vt1724_amp_cards,
1876 snd_vt1724_aureon_cards,
1877 snd_vt1720_mobo_cards,
1878 snd_vt1720_pontis_cards,
1879 snd_vt1724_prodigy192_cards,
1880 snd_vt1724_juli_cards,
1881 snd_vt1724_phase_cards,
1882 NULL,
1883};
1884
1885
1886/*
1887 */
1888
1889static void wait_i2c_busy(ice1712_t *ice)
1890{
1891 int t = 0x10000;
1892 while ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY) && t--)
1893 ;
1894 if (t == -1)
1895 printk(KERN_ERR "ice1724: i2c busy timeout\n");
1896}
1897
1898unsigned char snd_vt1724_read_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr)
1899{
1900 unsigned char val;
1901
1902 down(&ice->i2c_mutex);
1903 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
1904 outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
1905 wait_i2c_busy(ice);
1906 val = inb(ICEREG1724(ice, I2C_DATA));
1907 up(&ice->i2c_mutex);
1908 //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val);
1909 return val;
1910}
1911
1912void snd_vt1724_write_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr, unsigned char data)
1913{
1914 down(&ice->i2c_mutex);
1915 wait_i2c_busy(ice);
1916 //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data);
1917 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
1918 outb(data, ICEREG1724(ice, I2C_DATA));
1919 outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
1920 wait_i2c_busy(ice);
1921 up(&ice->i2c_mutex);
1922}
1923
1924static int __devinit snd_vt1724_read_eeprom(ice1712_t *ice, const char *modelname)
1925{
1926 const int dev = 0xa0; /* EEPROM device address */
1927 unsigned int i, size;
1928 struct snd_ice1712_card_info **tbl, *c;
1929
1930 if (! modelname || ! *modelname) {
1931 ice->eeprom.subvendor = 0;
1932 if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0)
1933 ice->eeprom.subvendor =
1934 (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) |
1935 (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) |
1936 (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) |
1937 (snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
1938 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
1939 /* invalid subvendor from EEPROM, try the PCI subststem ID instead */
1940 u16 vendor, device;
1941 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
1942 pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
1943 ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
1944 if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
1945 printk(KERN_ERR "ice1724: No valid ID is found\n");
1946 return -ENXIO;
1947 }
1948 }
1949 }
1950 for (tbl = card_tables; *tbl; tbl++) {
1951 for (c = *tbl; c->subvendor; c++) {
1952 if (modelname && c->model && ! strcmp(modelname, c->model)) {
1953 printk(KERN_INFO "ice1724: Using board model %s\n", c->name);
1954 ice->eeprom.subvendor = c->subvendor;
1955 } else if (c->subvendor != ice->eeprom.subvendor)
1956 continue;
1957 if (! c->eeprom_size || ! c->eeprom_data)
1958 goto found;
1959 /* if the EEPROM is given by the driver, use it */
1960 snd_printdd("using the defined eeprom..\n");
1961 ice->eeprom.version = 2;
1962 ice->eeprom.size = c->eeprom_size + 6;
1963 memcpy(ice->eeprom.data, c->eeprom_data, c->eeprom_size);
1964 goto read_skipped;
1965 }
1966 }
1967 printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
1968
1969 found:
1970 ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
1971 if (ice->eeprom.size < 6)
1972 ice->eeprom.size = 32;
1973 else if (ice->eeprom.size > 32) {
1974 printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n", ice->eeprom.size);
1975 return -EIO;
1976 }
1977 ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
1978 if (ice->eeprom.version != 2)
1979 printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n", ice->eeprom.version);
1980 size = ice->eeprom.size - 6;
1981 for (i = 0; i < size; i++)
1982 ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6);
1983
1984 read_skipped:
1985 ice->eeprom.gpiomask = eeprom_triple(ice, ICE_EEP2_GPIO_MASK);
1986 ice->eeprom.gpiostate = eeprom_triple(ice, ICE_EEP2_GPIO_STATE);
1987 ice->eeprom.gpiodir = eeprom_triple(ice, ICE_EEP2_GPIO_DIR);
1988
1989 return 0;
1990}
1991
1992
1993
1994static int __devinit snd_vt1724_chip_init(ice1712_t *ice)
1995{
1996 outb(VT1724_RESET , ICEREG1724(ice, CONTROL));
1997 udelay(200);
1998 outb(0, ICEREG1724(ice, CONTROL));
1999 udelay(200);
2000 outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG));
2001 outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG));
2002 outb(ice->eeprom.data[ICE_EEP2_I2S], ICEREG1724(ice, I2S_FEATURES));
2003 outb(ice->eeprom.data[ICE_EEP2_SPDIF], ICEREG1724(ice, SPDIF_CFG));
2004
2005 ice->gpio.write_mask = ice->eeprom.gpiomask;
2006 ice->gpio.direction = ice->eeprom.gpiodir;
2007 snd_vt1724_set_gpio_mask(ice, ice->eeprom.gpiomask);
2008 snd_vt1724_set_gpio_dir(ice, ice->eeprom.gpiodir);
2009 snd_vt1724_set_gpio_data(ice, ice->eeprom.gpiostate);
2010
2011 outb(0, ICEREG1724(ice, POWERDOWN));
2012
2013 return 0;
2014}
2015
2016static int __devinit snd_vt1724_spdif_build_controls(ice1712_t *ice)
2017{
2018 int err;
2019 snd_kcontrol_t *kctl;
2020
2021 snd_assert(ice->pcm != NULL, return -EIO);
2022
2023 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice));
2024 if (err < 0)
2025 return err;
2026
2027 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice));
2028 if (err < 0)
2029 return err;
2030
2031 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice));
2032 if (err < 0)
2033 return err;
2034 kctl->id.device = ice->pcm->device;
2035 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice));
2036 if (err < 0)
2037 return err;
2038 kctl->id.device = ice->pcm->device;
2039 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice));
2040 if (err < 0)
2041 return err;
2042 kctl->id.device = ice->pcm->device;
2043#if 0 /* use default only */
2044 err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice));
2045 if (err < 0)
2046 return err;
2047 kctl->id.device = ice->pcm->device;
2048 ice->spdif.stream_ctl = kctl;
2049#endif
2050 return 0;
2051}
2052
2053
2054static int __devinit snd_vt1724_build_controls(ice1712_t *ice)
2055{
2056 int err;
2057
2058 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_eeprom, ice));
2059 if (err < 0)
2060 return err;
2061 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_internal_clock, ice));
2062 if (err < 0)
2063 return err;
2064
2065 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_locking, ice));
2066 if (err < 0)
2067 return err;
2068 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_pro_rate_reset, ice));
2069 if (err < 0)
2070 return err;
2071
2072 if (ice->num_total_dacs > 0) {
2073 snd_kcontrol_new_t tmp = snd_vt1724_mixer_pro_analog_route;
2074 tmp.count = ice->num_total_dacs;
2075 if (ice->vt1720 && tmp.count > 2)
2076 tmp.count = 2;
2077 err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
2078 if (err < 0)
2079 return err;
2080 }
2081
2082 err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_peak, ice));
2083 if (err < 0)
2084 return err;
2085
2086 return 0;
2087}
2088
2089static int snd_vt1724_free(ice1712_t *ice)
2090{
2091 if (! ice->port)
2092 goto __hw_end;
2093 /* mask all interrupts */
2094 outb(0xff, ICEMT1724(ice, DMA_INT_MASK));
2095 outb(0xff, ICEREG1724(ice, IRQMASK));
2096 /* --- */
2097 __hw_end:
2098 if (ice->irq >= 0) {
2099 synchronize_irq(ice->irq);
2100 free_irq(ice->irq, (void *) ice);
2101 }
2102 pci_release_regions(ice->pci);
2103 snd_ice1712_akm4xxx_free(ice);
2104 pci_disable_device(ice->pci);
2105 kfree(ice);
2106 return 0;
2107}
2108
2109static int snd_vt1724_dev_free(snd_device_t *device)
2110{
2111 ice1712_t *ice = device->device_data;
2112 return snd_vt1724_free(ice);
2113}
2114
2115static int __devinit snd_vt1724_create(snd_card_t * card,
2116 struct pci_dev *pci,
2117 const char *modelname,
2118 ice1712_t ** r_ice1712)
2119{
2120 ice1712_t *ice;
2121 int err;
2122 unsigned char mask;
2123 static snd_device_ops_t ops = {
2124 .dev_free = snd_vt1724_dev_free,
2125 };
2126
2127 *r_ice1712 = NULL;
2128
2129 /* enable PCI device */
2130 if ((err = pci_enable_device(pci)) < 0)
2131 return err;
2132
2133 ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
2134 if (ice == NULL) {
2135 pci_disable_device(pci);
2136 return -ENOMEM;
2137 }
2138 ice->vt1724 = 1;
2139 spin_lock_init(&ice->reg_lock);
2140 init_MUTEX(&ice->gpio_mutex);
2141 init_MUTEX(&ice->open_mutex);
2142 init_MUTEX(&ice->i2c_mutex);
2143 ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
2144 ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
2145 ice->gpio.set_data = snd_vt1724_set_gpio_data;
2146 ice->gpio.get_data = snd_vt1724_get_gpio_data;
2147 ice->card = card;
2148 ice->pci = pci;
2149 ice->irq = -1;
2150 pci_set_master(pci);
2151 snd_vt1724_proc_init(ice);
2152 synchronize_irq(pci->irq);
2153
2154 if ((err = pci_request_regions(pci, "ICE1724")) < 0) {
2155 kfree(ice);
2156 pci_disable_device(pci);
2157 return err;
2158 }
2159 ice->port = pci_resource_start(pci, 0);
2160 ice->profi_port = pci_resource_start(pci, 1);
2161
2162 if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
2163 snd_printk("unable to grab IRQ %d\n", pci->irq);
2164 snd_vt1724_free(ice);
2165 return -EIO;
2166 }
2167
2168 ice->irq = pci->irq;
2169
2170 if (snd_vt1724_read_eeprom(ice, modelname) < 0) {
2171 snd_vt1724_free(ice);
2172 return -EIO;
2173 }
2174 if (snd_vt1724_chip_init(ice) < 0) {
2175 snd_vt1724_free(ice);
2176 return -EIO;
2177 }
2178
2179 /* unmask used interrupts */
2180 if (! (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401))
2181 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX;
2182 else
2183 mask = 0;
2184 outb(mask, ICEREG1724(ice, IRQMASK));
2185 /* don't handle FIFO overrun/underruns (just yet), since they cause machine lockups */
2186 outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
2187
2188 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
2189 snd_vt1724_free(ice);
2190 return err;
2191 }
2192
2193 snd_card_set_dev(card, &pci->dev);
2194
2195 *r_ice1712 = ice;
2196 return 0;
2197}
2198
2199
2200/*
2201 *
2202 * Registration
2203 *
2204 */
2205
2206static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2207 const struct pci_device_id *pci_id)
2208{
2209 static int dev;
2210 snd_card_t *card;
2211 ice1712_t *ice;
2212 int pcm_dev = 0, err;
2213 struct snd_ice1712_card_info **tbl, *c;
2214
2215 if (dev >= SNDRV_CARDS)
2216 return -ENODEV;
2217 if (!enable[dev]) {
2218 dev++;
2219 return -ENOENT;
2220 }
2221
2222 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
2223 if (card == NULL)
2224 return -ENOMEM;
2225
2226 strcpy(card->driver, "ICE1724");
2227 strcpy(card->shortname, "ICEnsemble ICE1724");
2228
2229 if ((err = snd_vt1724_create(card, pci, model[dev], &ice)) < 0) {
2230 snd_card_free(card);
2231 return err;
2232 }
2233
2234 for (tbl = card_tables; *tbl; tbl++) {
2235 for (c = *tbl; c->subvendor; c++) {
2236 if (c->subvendor == ice->eeprom.subvendor) {
2237 strcpy(card->shortname, c->name);
2238 if (c->driver) /* specific driver? */
2239 strcpy(card->driver, c->driver);
2240 if (c->chip_init) {
2241 if ((err = c->chip_init(ice)) < 0) {
2242 snd_card_free(card);
2243 return err;
2244 }
2245 }
2246 goto __found;
2247 }
2248 }
2249 }
2250 c = &no_matched;
2251 __found:
2252
2253 if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
2254 snd_card_free(card);
2255 return err;
2256 }
2257
2258 if ((err = snd_vt1724_pcm_spdif(ice, pcm_dev++)) < 0) {
2259 snd_card_free(card);
2260 return err;
2261 }
2262
2263 if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) {
2264 snd_card_free(card);
2265 return err;
2266 }
2267
2268 if ((err = snd_vt1724_ac97_mixer(ice)) < 0) {
2269 snd_card_free(card);
2270 return err;
2271 }
2272
2273 if ((err = snd_vt1724_build_controls(ice)) < 0) {
2274 snd_card_free(card);
2275 return err;
2276 }
2277
2278 if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */
2279 if ((err = snd_vt1724_spdif_build_controls(ice)) < 0) {
2280 snd_card_free(card);
2281 return err;
2282 }
2283 }
2284
2285 if (c->build_controls) {
2286 if ((err = c->build_controls(ice)) < 0) {
2287 snd_card_free(card);
2288 return err;
2289 }
2290 }
2291
2292 if (! c->no_mpu401) {
2293 if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) {
2294 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
2295 ICEREG1724(ice, MPU_CTRL), 1,
2296 ice->irq, 0,
2297 &ice->rmidi[0])) < 0) {
2298 snd_card_free(card);
2299 return err;
2300 }
2301 }
2302 }
2303
2304 sprintf(card->longname, "%s at 0x%lx, irq %i",
2305 card->shortname, ice->port, ice->irq);
2306
2307 if ((err = snd_card_register(card)) < 0) {
2308 snd_card_free(card);
2309 return err;
2310 }
2311 pci_set_drvdata(pci, card);
2312 dev++;
2313 return 0;
2314}
2315
2316static void __devexit snd_vt1724_remove(struct pci_dev *pci)
2317{
2318 snd_card_free(pci_get_drvdata(pci));
2319 pci_set_drvdata(pci, NULL);
2320}
2321
2322static struct pci_driver driver = {
2323 .name = "ICE1724",
2324 .id_table = snd_vt1724_ids,
2325 .probe = snd_vt1724_probe,
2326 .remove = __devexit_p(snd_vt1724_remove),
2327};
2328
2329static int __init alsa_card_ice1724_init(void)
2330{
2331 return pci_module_init(&driver);
2332}
2333
2334static void __exit alsa_card_ice1724_exit(void)
2335{
2336 pci_unregister_driver(&driver);
2337}
2338
2339module_init(alsa_card_ice1724_init)
2340module_exit(alsa_card_ice1724_exit)
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
new file mode 100644
index 000000000000..3fb297b969cd
--- /dev/null
+++ b/sound/pci/ice1712/juli.c
@@ -0,0 +1,230 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for ESI Juli@ cards
5 *
6 * Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "envy24ht.h"
34#include "juli.h"
35
36/*
37 * chip addresses on I2C bus
38 */
39#define AK4114_ADDR 0x20 /* S/PDIF receiver */
40#define AK4358_ADDR 0x22 /* DAC */
41
42/*
43 * GPIO pins
44 */
45#define GPIO_FREQ_MASK (3<<0)
46#define GPIO_FREQ_32KHZ (0<<0)
47#define GPIO_FREQ_44KHZ (1<<0)
48#define GPIO_FREQ_48KHZ (2<<0)
49#define GPIO_MULTI_MASK (3<<2)
50#define GPIO_MULTI_4X (0<<2)
51#define GPIO_MULTI_2X (1<<2)
52#define GPIO_MULTI_1X (2<<2) /* also external */
53#define GPIO_MULTI_HALF (3<<2)
54#define GPIO_INTERNAL_CLOCK (1<<4)
55#define GPIO_ANALOG_PRESENT (1<<5) /* RO only: 0 = present */
56#define GPIO_RXMCLK_SEL (1<<7) /* must be 0 */
57#define GPIO_AK5385A_CKS0 (1<<8)
58#define GPIO_AK5385A_DFS0 (1<<9) /* swapped with DFS1 according doc? */
59#define GPIO_AK5385A_DFS1 (1<<10)
60#define GPIO_DIGOUT_MONITOR (1<<11) /* 1 = active */
61#define GPIO_DIGIN_MONITOR (1<<12) /* 1 = active */
62#define GPIO_ANAIN_MONITOR (1<<13) /* 1 = active */
63#define GPIO_AK5385A_MCLK (1<<14) /* must be 0 */
64#define GPIO_MUTE_CONTROL (1<<15) /* 0 = off, 1 = on */
65
66static void juli_ak4114_write(void *private_data, unsigned char reg, unsigned char val)
67{
68 snd_vt1724_write_i2c((ice1712_t *)private_data, AK4114_ADDR, reg, val);
69}
70
71static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
72{
73 return snd_vt1724_read_i2c((ice1712_t *)private_data, AK4114_ADDR, reg);
74}
75
76/*
77 * AK4358 section
78 */
79
80static void juli_akm_lock(akm4xxx_t *ak, int chip)
81{
82}
83
84static void juli_akm_unlock(akm4xxx_t *ak, int chip)
85{
86}
87
88static void juli_akm_write(akm4xxx_t *ak, int chip,
89 unsigned char addr, unsigned char data)
90{
91 ice1712_t *ice = ak->private_data[0];
92
93 snd_assert(chip == 0, return);
94 snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data);
95}
96
97/*
98 * change the rate of envy24HT, AK4358
99 */
100static void juli_akm_set_rate_val(akm4xxx_t *ak, unsigned int rate)
101{
102 unsigned char old, tmp, dfs;
103
104 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
105 return;
106
107 /* adjust DFS on codecs */
108 if (rate > 96000)
109 dfs = 2;
110 else if (rate > 48000)
111 dfs = 1;
112 else
113 dfs = 0;
114
115 tmp = snd_akm4xxx_get(ak, 0, 2);
116 old = (tmp >> 4) & 0x03;
117 if (old == dfs)
118 return;
119 /* reset DFS */
120 snd_akm4xxx_reset(ak, 1);
121 tmp = snd_akm4xxx_get(ak, 0, 2);
122 tmp &= ~(0x03 << 4);
123 tmp |= dfs << 4;
124 snd_akm4xxx_set(ak, 0, 2, tmp);
125 snd_akm4xxx_reset(ak, 0);
126}
127
128static akm4xxx_t akm_juli_dac __devinitdata = {
129 .type = SND_AK4358,
130 .num_dacs = 2,
131 .ops = {
132 .lock = juli_akm_lock,
133 .unlock = juli_akm_unlock,
134 .write = juli_akm_write,
135 .set_rate_val = juli_akm_set_rate_val
136 }
137};
138
139static int __devinit juli_add_controls(ice1712_t *ice)
140{
141 return snd_ice1712_akm4xxx_build_controls(ice);
142}
143
144/*
145 * initialize the chip
146 */
147static int __devinit juli_init(ice1712_t *ice)
148{
149 static unsigned char ak4114_init_vals[] = {
150 /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
151 /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S,
152 /* AK4114_REG_IO0 */ AK4114_TX1E,
153 /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1),
154 /* AK4114_REG_INT0_MASK */ 0,
155 /* AK4114_REG_INT1_MASK */ 0
156 };
157 static unsigned char ak4114_init_txcsb[] = {
158 0x41, 0x02, 0x2c, 0x00, 0x00
159 };
160 int err;
161 akm4xxx_t *ak;
162
163#if 0
164 for (err = 0; err < 0x20; err++)
165 juli_ak4114_read(ice, err);
166 juli_ak4114_write(ice, 0, 0x0f);
167 juli_ak4114_read(ice, 0);
168 juli_ak4114_read(ice, 1);
169#endif
170 err = snd_ak4114_create(ice->card,
171 juli_ak4114_read,
172 juli_ak4114_write,
173 ak4114_init_vals, ak4114_init_txcsb,
174 ice, &ice->spec.juli.ak4114);
175 if (err < 0)
176 return err;
177
178 ice->spec.juli.analog = ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT;
179
180 if (ice->spec.juli.analog) {
181 printk(KERN_INFO "juli@: analog I/O detected\n");
182 ice->num_total_dacs = 2;
183 ice->num_total_adcs = 2;
184
185 ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
186 if (! ak)
187 return -ENOMEM;
188 ice->akm_codecs = 1;
189 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice)) < 0)
190 return err;
191 }
192
193 return 0;
194}
195
196
197/*
198 * Juli@ boards don't provide the EEPROM data except for the vendor IDs.
199 * hence the driver needs to sets up it properly.
200 */
201
202static unsigned char juli_eeprom[] __devinitdata = {
203 0x20, /* SYSCONF: clock 512, mpu401, 1xADC, 1xDACs */
204 0x80, /* ACLINK: I2S */
205 0xf8, /* I2S: vol, 96k, 24bit, 192k */
206 0xc3, /* SPDIF: out-en, out-int, spdif-in */
207 0x9f, /* GPIO_DIR */
208 0xff, /* GPIO_DIR1 */
209 0x7f, /* GPIO_DIR2 */
210 0x9f, /* GPIO_MASK */
211 0xff, /* GPIO_MASK1 */
212 0x7f, /* GPIO_MASK2 */
213 0x16, /* GPIO_STATE: internal clock, multiple 1x, 48kHz */
214 0x80, /* GPIO_STATE1: mute */
215 0x00, /* GPIO_STATE2 */
216};
217
218/* entry point */
219struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
220 {
221 .subvendor = VT1724_SUBDEVICE_JULI,
222 .name = "ESI Juli@",
223 .model = "juli",
224 .chip_init = juli_init,
225 .build_controls = juli_add_controls,
226 .eeprom_size = sizeof(juli_eeprom),
227 .eeprom_data = juli_eeprom,
228 },
229 { } /* terminator */
230};
diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h
new file mode 100644
index 000000000000..d9f8534fd92e
--- /dev/null
+++ b/sound/pci/ice1712/juli.h
@@ -0,0 +1,10 @@
1#ifndef __SOUND_JULI_H
2#define __SOUND_JULI_H
3
4#define JULI_DEVICE_DESC "{ESI,Juli@},"
5
6#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */
7
8extern struct snd_ice1712_card_info snd_vt1724_juli_cards[];
9
10#endif /* __SOUND_JULI_H */
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
new file mode 100644
index 000000000000..d1f90832443c
--- /dev/null
+++ b/sound/pci/ice1712/phase.c
@@ -0,0 +1,138 @@
1/*
2 * ALSA driver for ICEnsemble ICE1724 (Envy24)
3 *
4 * Lowlevel functions for Terratec PHASE 22
5 *
6 * Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
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
24/* PHASE 22 overview:
25 * Audio controller: VIA Envy24HT-S (slightly trimmed down version of Envy24HT)
26 * Analog chip: AK4524 (partially via Philip's 74HCT125)
27 * Digital receiver: CS8414-CS (not supported in this release)
28 *
29 * Envy connects to AK4524
30 * - CS directly from GPIO 10
31 * - CCLK via 74HCT125's gate #4 from GPIO 4
32 * - CDTI via 74HCT125's gate #2 from GPIO 5
33 * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3
34 */
35
36#include <sound/driver.h>
37#include <asm/io.h>
38#include <linux/delay.h>
39#include <linux/interrupt.h>
40#include <linux/init.h>
41#include <linux/slab.h>
42#include <sound/core.h>
43
44#include "ice1712.h"
45#include "envy24ht.h"
46#include "phase.h"
47
48static akm4xxx_t akm_phase22 __devinitdata = {
49 .type = SND_AK4524,
50 .num_dacs = 2,
51 .num_adcs = 2,
52};
53
54static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
55 .caddr = 2,
56 .cif = 1,
57 .data_mask = 1 << 4,
58 .clk_mask = 1 << 5,
59 .cs_mask = 1 << 10,
60 .cs_addr = 1 << 10,
61 .cs_none = 0,
62 .add_flags = 1 << 3,
63 .mask_flags = 0,
64};
65
66static int __devinit phase22_init(ice1712_t *ice)
67{
68 akm4xxx_t *ak;
69 int err;
70
71 // Configure DAC/ADC description for generic part of ice1724
72 switch (ice->eeprom.subvendor) {
73 case VT1724_SUBDEVICE_PHASE22:
74 ice->num_total_dacs = 2;
75 ice->num_total_adcs = 2;
76 ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO
77 break;
78 default:
79 snd_BUG();
80 return -EINVAL;
81 }
82
83 // Initialize analog chips
84 ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
85 if (! ak)
86 return -ENOMEM;
87 ice->akm_codecs = 1;
88 switch (ice->eeprom.subvendor) {
89 case VT1724_SUBDEVICE_PHASE22:
90 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0)
91 return err;
92 break;
93 }
94
95 return 0;
96}
97
98static int __devinit phase22_add_controls(ice1712_t *ice)
99{
100 int err = 0;
101
102 switch (ice->eeprom.subvendor) {
103 case VT1724_SUBDEVICE_PHASE22:
104 err = snd_ice1712_akm4xxx_build_controls(ice);
105 if (err < 0)
106 return err;
107 }
108 return 0;
109}
110
111static unsigned char phase22_eeprom[] __devinitdata = {
112 0x00, /* SYSCONF: 1xADC, 1xDACs */
113 0x80, /* ACLINK: I2S */
114 0xf8, /* I2S: vol, 96k, 24bit*/
115 0xc3, /* SPDIF: out-en, out-int, spdif-in */
116 0xFF, /* GPIO_DIR */
117 0xFF, /* GPIO_DIR1 */
118 0xFF, /* GPIO_DIR2 */
119 0x00, /* GPIO_MASK */
120 0x00, /* GPIO_MASK1 */
121 0x00, /* GPIO_MASK2 */
122 0x00, /* GPIO_STATE: */
123 0x00, /* GPIO_STATE1: */
124 0x00, /* GPIO_STATE2 */
125};
126
127struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
128 {
129 .subvendor = VT1724_SUBDEVICE_PHASE22,
130 .name = "Terratec PHASE 22",
131 .model = "phase22",
132 .chip_init = phase22_init,
133 .build_controls = phase22_add_controls,
134 .eeprom_size = sizeof(phase22_eeprom),
135 .eeprom_data = phase22_eeprom,
136 },
137 { } /* terminator */
138};
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
new file mode 100644
index 000000000000..6230cf16989f
--- /dev/null
+++ b/sound/pci/ice1712/phase.h
@@ -0,0 +1,34 @@
1#ifndef __SOUND_PHASE_H
2#define __SOUND_PHASE_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for Terratec PHASE 22
8 *
9 * Copyright (c) 2005 Misha Zhilin <misha@epiphan.com>
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
27#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"
28
29#define VT1724_SUBDEVICE_PHASE22 0x3b155011
30
31/* entry point */
32extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
33
34#endif /* __SOUND_PHASE */
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
new file mode 100644
index 000000000000..25f827d8fbd9
--- /dev/null
+++ b/sound/pci/ice1712/pontis.c
@@ -0,0 +1,849 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Pontis MS300
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/info.h>
32
33#include "ice1712.h"
34#include "envy24ht.h"
35#include "pontis.h"
36
37/* I2C addresses */
38#define WM_DEV 0x34
39#define CS_DEV 0x20
40
41/* WM8776 registers */
42#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
43#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
44#define WM_HP_MASTER 0x02 /* headphone master (both channels), override LLR */
45#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
46#define WM_DAC_ATTEN_R 0x04
47#define WM_DAC_MASTER 0x05
48#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
49#define WM_DAC_CTRL1 0x07
50#define WM_DAC_MUTE 0x08
51#define WM_DAC_CTRL2 0x09
52#define WM_DAC_INT 0x0a
53#define WM_ADC_INT 0x0b
54#define WM_MASTER_CTRL 0x0c
55#define WM_POWERDOWN 0x0d
56#define WM_ADC_ATTEN_L 0x0e
57#define WM_ADC_ATTEN_R 0x0f
58#define WM_ALC_CTRL1 0x10
59#define WM_ALC_CTRL2 0x11
60#define WM_ALC_CTRL3 0x12
61#define WM_NOISE_GATE 0x13
62#define WM_LIMITER 0x14
63#define WM_ADC_MUX 0x15
64#define WM_OUT_MUX 0x16
65#define WM_RESET 0x17
66
67/*
68 * GPIO
69 */
70#define PONTIS_CS_CS (1<<4) /* CS */
71#define PONTIS_CS_CLK (1<<5) /* CLK */
72#define PONTIS_CS_RDATA (1<<6) /* CS8416 -> VT1720 */
73#define PONTIS_CS_WDATA (1<<7) /* VT1720 -> CS8416 */
74
75
76/*
77 * get the current register value of WM codec
78 */
79static unsigned short wm_get(ice1712_t *ice, int reg)
80{
81 reg <<= 1;
82 return ((unsigned short)ice->akm[0].images[reg] << 8) |
83 ice->akm[0].images[reg + 1];
84}
85
86/*
87 * set the register value of WM codec and remember it
88 */
89static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
90{
91 unsigned short cval;
92 cval = (reg << 9) | val;
93 snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
94}
95
96static void wm_put(ice1712_t *ice, int reg, unsigned short val)
97{
98 wm_put_nocache(ice, reg, val);
99 reg <<= 1;
100 ice->akm[0].images[reg] = val >> 8;
101 ice->akm[0].images[reg + 1] = val;
102}
103
104/*
105 * DAC volume attenuation mixer control (-64dB to 0dB)
106 */
107
108#define DAC_0dB 0xff
109#define DAC_RES 128
110#define DAC_MIN (DAC_0dB - DAC_RES)
111
112static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
113{
114 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
115 uinfo->count = 2;
116 uinfo->value.integer.min = 0; /* mute */
117 uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
118 return 0;
119}
120
121static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
122{
123 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
124 unsigned short val;
125 int i;
126
127 down(&ice->gpio_mutex);
128 for (i = 0; i < 2; i++) {
129 val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
130 val = val > DAC_MIN ? (val - DAC_MIN) : 0;
131 ucontrol->value.integer.value[i] = val;
132 }
133 up(&ice->gpio_mutex);
134 return 0;
135}
136
137static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
138{
139 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
140 unsigned short oval, nval;
141 int i, idx, change = 0;
142
143 down(&ice->gpio_mutex);
144 for (i = 0; i < 2; i++) {
145 nval = ucontrol->value.integer.value[i];
146 nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
147 idx = WM_DAC_ATTEN_L + i;
148 oval = wm_get(ice, idx) & 0xff;
149 if (oval != nval) {
150 wm_put(ice, idx, nval);
151 wm_put_nocache(ice, idx, nval | 0x100);
152 change = 1;
153 }
154 }
155 up(&ice->gpio_mutex);
156 return change;
157}
158
159/*
160 * ADC gain mixer control (-64dB to 0dB)
161 */
162
163#define ADC_0dB 0xcf
164#define ADC_RES 128
165#define ADC_MIN (ADC_0dB - ADC_RES)
166
167static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
168{
169 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
170 uinfo->count = 2;
171 uinfo->value.integer.min = 0; /* mute (-64dB) */
172 uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
173 return 0;
174}
175
176static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
177{
178 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
179 unsigned short val;
180 int i;
181
182 down(&ice->gpio_mutex);
183 for (i = 0; i < 2; i++) {
184 val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
185 val = val > ADC_MIN ? (val - ADC_MIN) : 0;
186 ucontrol->value.integer.value[i] = val;
187 }
188 up(&ice->gpio_mutex);
189 return 0;
190}
191
192static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
193{
194 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
195 unsigned short ovol, nvol;
196 int i, idx, change = 0;
197
198 down(&ice->gpio_mutex);
199 for (i = 0; i < 2; i++) {
200 nvol = ucontrol->value.integer.value[i];
201 nvol = nvol ? (nvol + ADC_MIN) : 0;
202 idx = WM_ADC_ATTEN_L + i;
203 ovol = wm_get(ice, idx) & 0xff;
204 if (ovol != nvol) {
205 wm_put(ice, idx, nvol);
206 change = 1;
207 }
208 }
209 up(&ice->gpio_mutex);
210 return change;
211}
212
213/*
214 * ADC input mux mixer control
215 */
216static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
217{
218 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
219 uinfo->count = 1;
220 uinfo->value.integer.min = 0;
221 uinfo->value.integer.max = 1;
222 return 0;
223}
224
225static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
226{
227 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
228 int bit = kcontrol->private_value;
229
230 down(&ice->gpio_mutex);
231 ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
232 up(&ice->gpio_mutex);
233 return 0;
234}
235
236static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
237{
238 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
239 int bit = kcontrol->private_value;
240 unsigned short oval, nval;
241 int change;
242
243 down(&ice->gpio_mutex);
244 nval = oval = wm_get(ice, WM_ADC_MUX);
245 if (ucontrol->value.integer.value[0])
246 nval |= (1 << bit);
247 else
248 nval &= ~(1 << bit);
249 change = nval != oval;
250 if (change) {
251 wm_put(ice, WM_ADC_MUX, nval);
252 }
253 up(&ice->gpio_mutex);
254 return 0;
255}
256
257/*
258 * Analog bypass (In -> Out)
259 */
260static int wm_bypass_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
261{
262 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
263 uinfo->count = 1;
264 uinfo->value.integer.min = 0;
265 uinfo->value.integer.max = 1;
266 return 0;
267}
268
269static int wm_bypass_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
270{
271 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
272
273 down(&ice->gpio_mutex);
274 ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
275 up(&ice->gpio_mutex);
276 return 0;
277}
278
279static int wm_bypass_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
280{
281 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
282 unsigned short val, oval;
283 int change = 0;
284
285 down(&ice->gpio_mutex);
286 val = oval = wm_get(ice, WM_OUT_MUX);
287 if (ucontrol->value.integer.value[0])
288 val |= 0x04;
289 else
290 val &= ~0x04;
291 if (val != oval) {
292 wm_put(ice, WM_OUT_MUX, val);
293 change = 1;
294 }
295 up(&ice->gpio_mutex);
296 return change;
297}
298
299/*
300 * Left/Right swap
301 */
302static int wm_chswap_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
303{
304 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
305 uinfo->count = 1;
306 uinfo->value.integer.min = 0;
307 uinfo->value.integer.max = 1;
308 return 0;
309}
310
311static int wm_chswap_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
312{
313 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
314
315 down(&ice->gpio_mutex);
316 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
317 up(&ice->gpio_mutex);
318 return 0;
319}
320
321static int wm_chswap_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
322{
323 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
324 unsigned short val, oval;
325 int change = 0;
326
327 down(&ice->gpio_mutex);
328 oval = wm_get(ice, WM_DAC_CTRL1);
329 val = oval & 0x0f;
330 if (ucontrol->value.integer.value[0])
331 val |= 0x60;
332 else
333 val |= 0x90;
334 if (val != oval) {
335 wm_put(ice, WM_DAC_CTRL1, val);
336 wm_put_nocache(ice, WM_DAC_CTRL1, val);
337 change = 1;
338 }
339 up(&ice->gpio_mutex);
340 return change;
341}
342
343/*
344 * write data in the SPI mode
345 */
346static void set_gpio_bit(ice1712_t *ice, unsigned int bit, int val)
347{
348 unsigned int tmp = snd_ice1712_gpio_read(ice);
349 if (val)
350 tmp |= bit;
351 else
352 tmp &= ~bit;
353 snd_ice1712_gpio_write(ice, tmp);
354}
355
356static void spi_send_byte(ice1712_t *ice, unsigned char data)
357{
358 int i;
359 for (i = 0; i < 8; i++) {
360 set_gpio_bit(ice, PONTIS_CS_CLK, 0);
361 udelay(1);
362 set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
363 udelay(1);
364 set_gpio_bit(ice, PONTIS_CS_CLK, 1);
365 udelay(1);
366 data <<= 1;
367 }
368}
369
370static unsigned int spi_read_byte(ice1712_t *ice)
371{
372 int i;
373 unsigned int val = 0;
374
375 for (i = 0; i < 8; i++) {
376 val <<= 1;
377 set_gpio_bit(ice, PONTIS_CS_CLK, 0);
378 udelay(1);
379 if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
380 val |= 1;
381 udelay(1);
382 set_gpio_bit(ice, PONTIS_CS_CLK, 1);
383 udelay(1);
384 }
385 return val;
386}
387
388
389static void spi_write(ice1712_t *ice, unsigned int dev, unsigned int reg, unsigned int data)
390{
391 snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
392 snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
393 set_gpio_bit(ice, PONTIS_CS_CS, 0);
394 spi_send_byte(ice, dev & ~1); /* WRITE */
395 spi_send_byte(ice, reg); /* MAP */
396 spi_send_byte(ice, data); /* DATA */
397 /* trigger */
398 set_gpio_bit(ice, PONTIS_CS_CS, 1);
399 udelay(1);
400 /* restore */
401 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
402 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
403}
404
405static unsigned int spi_read(ice1712_t *ice, unsigned int dev, unsigned int reg)
406{
407 unsigned int val;
408 snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
409 snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
410 set_gpio_bit(ice, PONTIS_CS_CS, 0);
411 spi_send_byte(ice, dev & ~1); /* WRITE */
412 spi_send_byte(ice, reg); /* MAP */
413 /* trigger */
414 set_gpio_bit(ice, PONTIS_CS_CS, 1);
415 udelay(1);
416 set_gpio_bit(ice, PONTIS_CS_CS, 0);
417 spi_send_byte(ice, dev | 1); /* READ */
418 val = spi_read_byte(ice);
419 /* trigger */
420 set_gpio_bit(ice, PONTIS_CS_CS, 1);
421 udelay(1);
422 /* restore */
423 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
424 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
425 return val;
426}
427
428
429/*
430 * SPDIF input source
431 */
432static int cs_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
433{
434 static char *texts[] = {
435 "Coax", /* RXP0 */
436 "Optical", /* RXP1 */
437 "CD", /* RXP2 */
438 };
439 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
440 uinfo->count = 1;
441 uinfo->value.enumerated.items = 3;
442 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
443 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
444 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
445 return 0;
446}
447
448static int cs_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
449{
450 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
451
452 down(&ice->gpio_mutex);
453 ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
454 up(&ice->gpio_mutex);
455 return 0;
456}
457
458static int cs_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
459{
460 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
461 unsigned char val;
462 int change = 0;
463
464 down(&ice->gpio_mutex);
465 if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
466 ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
467 val = 0x80 | (ice->gpio.saved[0] << 3);
468 spi_write(ice, CS_DEV, 0x04, val);
469 change = 1;
470 }
471 up(&ice->gpio_mutex);
472 return 0;
473}
474
475
476/*
477 * GPIO controls
478 */
479static int pontis_gpio_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
480{
481 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
482 uinfo->count = 1;
483 uinfo->value.integer.min = 0;
484 uinfo->value.integer.max = 0xffff; /* 16bit */
485 return 0;
486}
487
488static int pontis_gpio_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
489{
490 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
491 down(&ice->gpio_mutex);
492 /* 4-7 reserved */
493 ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
494 up(&ice->gpio_mutex);
495 return 0;
496}
497
498static int pontis_gpio_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
499{
500 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
501 unsigned int val;
502 int changed;
503 down(&ice->gpio_mutex);
504 /* 4-7 reserved */
505 val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
506 changed = val != ice->gpio.write_mask;
507 ice->gpio.write_mask = val;
508 up(&ice->gpio_mutex);
509 return changed;
510}
511
512static int pontis_gpio_dir_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
513{
514 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
515 down(&ice->gpio_mutex);
516 /* 4-7 reserved */
517 ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
518 up(&ice->gpio_mutex);
519 return 0;
520}
521
522static int pontis_gpio_dir_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
523{
524 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
525 unsigned int val;
526 int changed;
527 down(&ice->gpio_mutex);
528 /* 4-7 reserved */
529 val = ucontrol->value.integer.value[0] & 0xff0f;
530 changed = (val != ice->gpio.direction);
531 ice->gpio.direction = val;
532 up(&ice->gpio_mutex);
533 return changed;
534}
535
536static int pontis_gpio_data_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
537{
538 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
539 down(&ice->gpio_mutex);
540 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
541 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
542 ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
543 up(&ice->gpio_mutex);
544 return 0;
545}
546
547static int pontis_gpio_data_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
548{
549 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
550 unsigned int val, nval;
551 int changed = 0;
552 down(&ice->gpio_mutex);
553 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
554 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
555 val = snd_ice1712_gpio_read(ice) & 0xffff;
556 nval = ucontrol->value.integer.value[0] & 0xffff;
557 if (val != nval) {
558 snd_ice1712_gpio_write(ice, nval);
559 changed = 1;
560 }
561 up(&ice->gpio_mutex);
562 return changed;
563}
564
565/*
566 * mixers
567 */
568
569static snd_kcontrol_new_t pontis_controls[] __devinitdata = {
570 {
571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
572 .name = "PCM Playback Volume",
573 .info = wm_dac_vol_info,
574 .get = wm_dac_vol_get,
575 .put = wm_dac_vol_put,
576 },
577 {
578 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
579 .name = "Capture Volume",
580 .info = wm_adc_vol_info,
581 .get = wm_adc_vol_get,
582 .put = wm_adc_vol_put,
583 },
584 {
585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
586 .name = "CD Capture Switch",
587 .info = wm_adc_mux_info,
588 .get = wm_adc_mux_get,
589 .put = wm_adc_mux_put,
590 .private_value = 0,
591 },
592 {
593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594 .name = "Line Capture Switch",
595 .info = wm_adc_mux_info,
596 .get = wm_adc_mux_get,
597 .put = wm_adc_mux_put,
598 .private_value = 1,
599 },
600 {
601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
602 .name = "Analog Bypass Switch",
603 .info = wm_bypass_info,
604 .get = wm_bypass_get,
605 .put = wm_bypass_put,
606 },
607 {
608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
609 .name = "Swap Output Channels",
610 .info = wm_chswap_info,
611 .get = wm_chswap_get,
612 .put = wm_chswap_put,
613 },
614 {
615 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
616 .name = "IEC958 Input Source",
617 .info = cs_source_info,
618 .get = cs_source_get,
619 .put = cs_source_put,
620 },
621 /* FIXME: which interface? */
622 {
623 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
624 .name = "GPIO Mask",
625 .info = pontis_gpio_mask_info,
626 .get = pontis_gpio_mask_get,
627 .put = pontis_gpio_mask_put,
628 },
629 {
630 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
631 .name = "GPIO Direction",
632 .info = pontis_gpio_mask_info,
633 .get = pontis_gpio_dir_get,
634 .put = pontis_gpio_dir_put,
635 },
636 {
637 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
638 .name = "GPIO Data",
639 .info = pontis_gpio_mask_info,
640 .get = pontis_gpio_data_get,
641 .put = pontis_gpio_data_put,
642 },
643};
644
645
646/*
647 * WM codec registers
648 */
649static void wm_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
650{
651 ice1712_t *ice = (ice1712_t *)entry->private_data;
652 char line[64];
653 unsigned int reg, val;
654 down(&ice->gpio_mutex);
655 while (!snd_info_get_line(buffer, line, sizeof(line))) {
656 if (sscanf(line, "%x %x", &reg, &val) != 2)
657 continue;
658 if (reg <= 0x17 && val <= 0xffff)
659 wm_put(ice, reg, val);
660 }
661 up(&ice->gpio_mutex);
662}
663
664static void wm_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
665{
666 ice1712_t *ice = (ice1712_t *)entry->private_data;
667 int reg, val;
668
669 down(&ice->gpio_mutex);
670 for (reg = 0; reg <= 0x17; reg++) {
671 val = wm_get(ice, reg);
672 snd_iprintf(buffer, "%02x = %04x\n", reg, val);
673 }
674 up(&ice->gpio_mutex);
675}
676
677static void wm_proc_init(ice1712_t *ice)
678{
679 snd_info_entry_t *entry;
680 if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
681 snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read);
682 entry->mode |= S_IWUSR;
683 entry->c.text.write_size = 1024;
684 entry->c.text.write = wm_proc_regs_write;
685 }
686}
687
688static void cs_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
689{
690 ice1712_t *ice = (ice1712_t *)entry->private_data;
691 int reg, val;
692
693 down(&ice->gpio_mutex);
694 for (reg = 0; reg <= 0x26; reg++) {
695 val = spi_read(ice, CS_DEV, reg);
696 snd_iprintf(buffer, "%02x = %02x\n", reg, val);
697 }
698 val = spi_read(ice, CS_DEV, 0x7f);
699 snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
700 up(&ice->gpio_mutex);
701}
702
703static void cs_proc_init(ice1712_t *ice)
704{
705 snd_info_entry_t *entry;
706 if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) {
707 snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read);
708 }
709}
710
711
712static int __devinit pontis_add_controls(ice1712_t *ice)
713{
714 unsigned int i;
715 int err;
716
717 for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
718 err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
719 if (err < 0)
720 return err;
721 }
722
723 wm_proc_init(ice);
724 cs_proc_init(ice);
725
726 return 0;
727}
728
729
730/*
731 * initialize the chip
732 */
733static int __devinit pontis_init(ice1712_t *ice)
734{
735 static unsigned short wm_inits[] = {
736 /* These come first to reduce init pop noise */
737 WM_ADC_MUX, 0x00c0, /* ADC mute */
738 WM_DAC_MUTE, 0x0001, /* DAC softmute */
739 WM_DAC_CTRL1, 0x0000, /* DAC mute */
740
741 WM_POWERDOWN, 0x0008, /* All power-up except HP */
742 WM_RESET, 0x0000, /* reset */
743 };
744 static unsigned short wm_inits2[] = {
745 WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
746 WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
747 WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
748 WM_DAC_CTRL1, 0x0090, /* DAC L/R */
749 WM_OUT_MUX, 0x0001, /* OUT DAC */
750 WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
751 WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
752 WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
753 WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
754 WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
755 WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
756 // WM_DAC_MASTER, 0x0100, /* DAC master muted */
757 WM_PHASE_SWAP, 0x0000, /* phase normal */
758 WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
759 WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
760 WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
761#if 0
762 WM_ALC_CTRL1, 0x007b, /* */
763 WM_ALC_CTRL2, 0x0000, /* */
764 WM_ALC_CTRL3, 0x0000, /* */
765 WM_NOISE_GATE, 0x0000, /* */
766#endif
767 WM_DAC_MUTE, 0x0000, /* DAC unmute */
768 WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
769 };
770 static unsigned char cs_inits[] = {
771 0x04, 0x80, /* RUN, RXP0 */
772 0x05, 0x05, /* slave, 24bit */
773 0x01, 0x00,
774 0x02, 0x00,
775 0x03, 0x00,
776 };
777 unsigned int i;
778
779 ice->vt1720 = 1;
780 ice->num_total_dacs = 2;
781 ice->num_total_adcs = 2;
782
783 /* to remeber the register values */
784 ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
785 if (! ice->akm)
786 return -ENOMEM;
787 ice->akm_codecs = 1;
788
789 /* HACK - use this as the SPDIF source.
790 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
791 */
792 ice->gpio.saved[0] = 0;
793
794 /* initialize WM8776 codec */
795 for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
796 wm_put(ice, wm_inits[i], wm_inits[i+1]);
797 set_current_state(TASK_UNINTERRUPTIBLE);
798 schedule_timeout(1);
799 for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
800 wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
801
802 /* initialize CS8416 codec */
803 /* assert PRST#; MT05 bit 7 */
804 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
805 mdelay(5);
806 /* deassert PRST# */
807 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
808
809 for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
810 spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
811
812 return 0;
813}
814
815
816/*
817 * Pontis boards don't provide the EEPROM data at all.
818 * hence the driver needs to sets up it properly.
819 */
820
821static unsigned char pontis_eeprom[] __devinitdata = {
822 0x08, /* SYSCONF: clock 256, mpu401, spdif-in/ADC, 1DAC */
823 0x80, /* ACLINK: I2S */
824 0xf8, /* I2S: vol, 96k, 24bit, 192k */
825 0xc3, /* SPDIF: out-en, out-int, spdif-in */
826 0x07, /* GPIO_DIR */
827 0x00, /* GPIO_DIR1 */
828 0x00, /* GPIO_DIR2 (ignored) */
829 0x0f, /* GPIO_MASK (4-7 reserved for CS8416) */
830 0xff, /* GPIO_MASK1 */
831 0x00, /* GPIO_MASK2 (ignored) */
832 0x06, /* GPIO_STATE (0-low, 1-high, 2-high) */
833 0x00, /* GPIO_STATE1 */
834 0x00, /* GPIO_STATE2 (ignored) */
835};
836
837/* entry point */
838struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
839 {
840 .subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
841 .name = "Pontis MS300",
842 .model = "ms300",
843 .chip_init = pontis_init,
844 .build_controls = pontis_add_controls,
845 .eeprom_size = sizeof(pontis_eeprom),
846 .eeprom_data = pontis_eeprom,
847 },
848 { } /* terminator */
849};
diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h
new file mode 100644
index 000000000000..d0d1378b935c
--- /dev/null
+++ b/sound/pci/ice1712/pontis.h
@@ -0,0 +1,33 @@
1#ifndef __SOUND_PONTIS_H
2#define __SOUND_PONTIS_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Pontis MS300 boards
8 *
9 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
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
27#define PONTIS_DEVICE_DESC "{Pontis,MS300},"
28
29#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */
30
31extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[];
32
33#endif /* __SOUND_PONTIS_H */
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
new file mode 100644
index 000000000000..d2c5963795d7
--- /dev/null
+++ b/sound/pci/ice1712/prodigy192.c
@@ -0,0 +1,524 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for AudioTrak Prodigy 192 cards
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
7 * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
8 * Copyright (c) 2004 Kouichi ONO <co2b@ceres.dti.ne.jp>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/driver.h>
27#include <asm/io.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <sound/core.h>
33
34#include "ice1712.h"
35#include "envy24ht.h"
36#include "prodigy192.h"
37#include "stac946x.h"
38
39static inline void stac9460_put(ice1712_t *ice, int reg, unsigned char val)
40{
41 snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
42}
43
44static inline unsigned char stac9460_get(ice1712_t *ice, int reg)
45{
46 return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
47}
48
49/*
50 * DAC mute control
51 */
52static int stac9460_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
53{
54 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
55 uinfo->count = 1;
56 uinfo->value.integer.min = 0;
57 uinfo->value.integer.max = 1;
58 return 0;
59}
60
61static int stac9460_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
62{
63 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
64 unsigned char val;
65 int idx;
66
67 if (kcontrol->private_value)
68 idx = STAC946X_MASTER_VOLUME;
69 else
70 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
71 val = stac9460_get(ice, idx);
72 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
73 return 0;
74}
75
76static int stac9460_dac_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
77{
78 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
79 unsigned char new, old;
80 int idx;
81 int change;
82
83 if (kcontrol->private_value)
84 idx = STAC946X_MASTER_VOLUME;
85 else
86 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
87 old = stac9460_get(ice, idx);
88 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80);
89 change = (new != old);
90 if (change)
91 stac9460_put(ice, idx, new);
92
93 return change;
94}
95
96/*
97 * DAC volume attenuation mixer control
98 */
99static int stac9460_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
100{
101 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
102 uinfo->count = 1;
103 uinfo->value.integer.min = 0; /* mute */
104 uinfo->value.integer.max = 0x7f; /* 0dB */
105 return 0;
106}
107
108static int stac9460_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
109{
110 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
111 int idx;
112 unsigned char vol;
113
114 if (kcontrol->private_value)
115 idx = STAC946X_MASTER_VOLUME;
116 else
117 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
118 vol = stac9460_get(ice, idx) & 0x7f;
119 ucontrol->value.integer.value[0] = 0x7f - vol;
120
121 return 0;
122}
123
124static int stac9460_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
125{
126 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
127 int idx;
128 unsigned char tmp, ovol, nvol;
129 int change;
130
131 if (kcontrol->private_value)
132 idx = STAC946X_MASTER_VOLUME;
133 else
134 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
135 nvol = ucontrol->value.integer.value[0];
136 tmp = stac9460_get(ice, idx);
137 ovol = 0x7f - (tmp & 0x7f);
138 change = (ovol != nvol);
139 if (change) {
140 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
141 }
142 return change;
143}
144
145/*
146 * ADC mute control
147 */
148static int stac9460_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
149{
150 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
151 uinfo->count = 2;
152 uinfo->value.integer.min = 0;
153 uinfo->value.integer.max = 1;
154 return 0;
155}
156
157static int stac9460_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
158{
159 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
160 unsigned char val;
161 int i;
162
163 for (i = 0; i < 2; ++i) {
164 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
165 ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
166 }
167
168 return 0;
169}
170
171static int stac9460_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
172{
173 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
174 unsigned char new, old;
175 int i, reg;
176 int change;
177
178 for (i = 0; i < 2; ++i) {
179 reg = STAC946X_MIC_L_VOLUME + i;
180 old = stac9460_get(ice, reg);
181 new = (~ucontrol->value.integer.value[i]<<7&0x80) | (old&~0x80);
182 change = (new != old);
183 if (change)
184 stac9460_put(ice, reg, new);
185 }
186
187 return change;
188}
189
190/*
191 * ADC gain mixer control
192 */
193static int stac9460_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
194{
195 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
196 uinfo->count = 2;
197 uinfo->value.integer.min = 0; /* 0dB */
198 uinfo->value.integer.max = 0x0f; /* 22.5dB */
199 return 0;
200}
201
202static int stac9460_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
203{
204 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
205 int i, reg;
206 unsigned char vol;
207
208 for (i = 0; i < 2; ++i) {
209 reg = STAC946X_MIC_L_VOLUME + i;
210 vol = stac9460_get(ice, reg) & 0x0f;
211 ucontrol->value.integer.value[i] = 0x0f - vol;
212 }
213
214 return 0;
215}
216
217static int stac9460_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
218{
219 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
220 int i, reg;
221 unsigned char ovol, nvol;
222 int change;
223
224 for (i = 0; i < 2; ++i) {
225 reg = STAC946X_MIC_L_VOLUME + i;
226 nvol = ucontrol->value.integer.value[i];
227 ovol = 0x0f - stac9460_get(ice, reg);
228 change = ((ovol & 0x0f) != nvol);
229 if (change)
230 stac9460_put(ice, reg, (0x0f - nvol) | (ovol & ~0x0f));
231 }
232
233 return change;
234}
235
236#if 0
237/*
238 * Headphone Amplifier
239 */
240static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
241{
242 unsigned int tmp, tmp2;
243
244 tmp2 = tmp = snd_ice1712_gpio_read(ice);
245 if (enable)
246 tmp |= AUREON_HP_SEL;
247 else
248 tmp &= ~ AUREON_HP_SEL;
249 if (tmp != tmp2) {
250 snd_ice1712_gpio_write(ice, tmp);
251 return 1;
252 }
253 return 0;
254}
255
256static int aureon_get_headphone_amp(ice1712_t *ice)
257{
258 unsigned int tmp = snd_ice1712_gpio_read(ice);
259
260 return ( tmp & AUREON_HP_SEL )!= 0;
261}
262
263static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
264{
265 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
266 uinfo->count = 1;
267 uinfo->value.integer.min = 0;
268 uinfo->value.integer.max = 1;
269 return 0;
270}
271
272static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
273{
274 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
275
276 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
277 return 0;
278}
279
280
281static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
282{
283 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
284
285 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
286}
287
288/*
289 * Deemphasis
290 */
291static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
292{
293 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
294 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
295 return 0;
296}
297
298static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
299{
300 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
301 int temp, temp2;
302 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
303 if (ucontrol->value.integer.value[0])
304 temp |= 0xf;
305 else
306 temp &= ~0xf;
307 if (temp != temp2) {
308 wm_put(ice, WM_DAC_CTRL2, temp);
309 return 1;
310 }
311 return 0;
312}
313
314/*
315 * ADC Oversampling
316 */
317static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
318{
319 static char *texts[2] = { "128x", "64x" };
320
321 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
322 uinfo->count = 1;
323 uinfo->value.enumerated.items = 2;
324
325 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
326 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
327 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
328
329 return 0;
330}
331
332static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
333{
334 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
335 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
336 return 0;
337}
338
339static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
340{
341 int temp, temp2;
342 ice1712_t *ice = snd_kcontrol_chip(kcontrol);
343
344 temp2 = temp = wm_get(ice, WM_MASTER);
345
346 if (ucontrol->value.enumerated.item[0])
347 temp |= 0x8;
348 else
349 temp &= ~0x8;
350
351 if (temp != temp2) {
352 wm_put(ice, WM_MASTER, temp);
353 return 1;
354 }
355 return 0;
356}
357#endif
358
359/*
360 * mixers
361 */
362
363static snd_kcontrol_new_t stac_controls[] __devinitdata = {
364 {
365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
366 .name = "Master Playback Switch",
367 .info = stac9460_dac_mute_info,
368 .get = stac9460_dac_mute_get,
369 .put = stac9460_dac_mute_put,
370 .private_value = 1,
371 },
372 {
373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
374 .name = "Master Playback Volume",
375 .info = stac9460_dac_vol_info,
376 .get = stac9460_dac_vol_get,
377 .put = stac9460_dac_vol_put,
378 .private_value = 1,
379 },
380 {
381 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
382 .name = "DAC Switch",
383 .count = 6,
384 .info = stac9460_dac_mute_info,
385 .get = stac9460_dac_mute_get,
386 .put = stac9460_dac_mute_put,
387 },
388 {
389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
390 .name = "DAC Volume",
391 .count = 6,
392 .info = stac9460_dac_vol_info,
393 .get = stac9460_dac_vol_get,
394 .put = stac9460_dac_vol_put,
395 },
396 {
397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
398 .name = "ADC Switch",
399 .count = 1,
400 .info = stac9460_adc_mute_info,
401 .get = stac9460_adc_mute_get,
402 .put = stac9460_adc_mute_put,
403
404 },
405 {
406 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
407 .name = "ADC Volume",
408 .count = 1,
409 .info = stac9460_adc_vol_info,
410 .get = stac9460_adc_vol_get,
411 .put = stac9460_adc_vol_put,
412 },
413#if 0
414 {
415 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
416 .name = "Capture Route",
417 .info = wm_adc_mux_info,
418 .get = wm_adc_mux_get,
419 .put = wm_adc_mux_put,
420 },
421 {
422 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
423 .name = "Headphone Amplifier Switch",
424 .info = aureon_bool_info,
425 .get = aureon_hpamp_get,
426 .put = aureon_hpamp_put
427 },
428 {
429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
430 .name = "DAC Deemphasis Switch",
431 .info = aureon_bool_info,
432 .get = aureon_deemp_get,
433 .put = aureon_deemp_put
434 },
435 {
436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
437 .name = "ADC Oversampling",
438 .info = aureon_oversampling_info,
439 .get = aureon_oversampling_get,
440 .put = aureon_oversampling_put
441 },
442#endif
443};
444
445static int __devinit prodigy192_add_controls(ice1712_t *ice)
446{
447 unsigned int i;
448 int err;
449
450 for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
451 err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice));
452 if (err < 0)
453 return err;
454 }
455 return 0;
456}
457
458
459/*
460 * initialize the chip
461 */
462static int __devinit prodigy192_init(ice1712_t *ice)
463{
464 static unsigned short stac_inits_prodigy[] = {
465 STAC946X_RESET, 0,
466/* STAC946X_MASTER_VOLUME, 0,
467 STAC946X_LF_VOLUME, 0,
468 STAC946X_RF_VOLUME, 0,
469 STAC946X_LR_VOLUME, 0,
470 STAC946X_RR_VOLUME, 0,
471 STAC946X_CENTER_VOLUME, 0,
472 STAC946X_LFE_VOLUME, 0,*/
473 (unsigned short)-1
474 };
475 unsigned short *p;
476
477 /* prodigy 192 */
478 ice->num_total_dacs = 6;
479 ice->num_total_adcs = 2;
480
481 /* initialize codec */
482 p = stac_inits_prodigy;
483 for (; *p != (unsigned short)-1; p += 2)
484 stac9460_put(ice, p[0], p[1]);
485
486 return 0;
487}
488
489
490/*
491 * Aureon boards don't provide the EEPROM data except for the vendor IDs.
492 * hence the driver needs to sets up it properly.
493 */
494
495static unsigned char prodigy71_eeprom[] __devinitdata = {
496 0x2b, /* SYSCONF: clock 512, mpu401, spdif-in/ADC, 4DACs */
497 0x80, /* ACLINK: I2S */
498 0xf8, /* I2S: vol, 96k, 24bit, 192k */
499 0xc3, /* SPDIF: out-en, out-int, spdif-in */
500 0xff, /* GPIO_DIR */
501 0xff, /* GPIO_DIR1 */
502 0xbf, /* GPIO_DIR2 */
503 0x00, /* GPIO_MASK */
504 0x00, /* GPIO_MASK1 */
505 0x00, /* GPIO_MASK2 */
506 0x00, /* GPIO_STATE */
507 0x00, /* GPIO_STATE1 */
508 0x00, /* GPIO_STATE2 */
509};
510
511
512/* entry point */
513struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
514 {
515 .subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
516 .name = "Audiotrak Prodigy 192",
517 .model = "prodigy192",
518 .chip_init = prodigy192_init,
519 .build_controls = prodigy192_add_controls,
520 .eeprom_size = sizeof(prodigy71_eeprom),
521 .eeprom_data = prodigy71_eeprom,
522 },
523 { } /* terminator */
524};
diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h
new file mode 100644
index 000000000000..94c824e24e06
--- /dev/null
+++ b/sound/pci/ice1712/prodigy192.h
@@ -0,0 +1,11 @@
1#ifndef __SOUND_PRODIGY192_H
2#define __SOUND_PRODIGY192_H
3
4#define PRODIGY192_DEVICE_DESC "{AudioTrak,Prodigy 192},"
5#define PRODIGY192_STAC9460_ADDR 0x54
6
7#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */
8
9extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[];
10
11#endif /* __SOUND_PRODIGY192_H */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
new file mode 100644
index 000000000000..d48d42524ac5
--- /dev/null
+++ b/sound/pci/ice1712/revo.c
@@ -0,0 +1,205 @@
1/*
2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
3 *
4 * Lowlevel functions for M-Audio Revolution 7.1
5 *
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "envy24ht.h"
34#include "revo.h"
35
36static void revo_i2s_mclk_changed(ice1712_t *ice)
37{
38 /* assert PRST# to converters; MT05 bit 7 */
39 outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
40 mdelay(5);
41 /* deassert PRST# */
42 outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
43}
44
45/*
46 * change the rate of envy24HT, AK4355 and AK4381
47 */
48static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
49{
50 unsigned char old, tmp, dfs;
51 int reg, shift;
52
53 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
54 return;
55
56 /* adjust DFS on codecs */
57 if (rate > 96000)
58 dfs = 2;
59 else if (rate > 48000)
60 dfs = 1;
61 else
62 dfs = 0;
63
64 if (ak->type == SND_AK4355) {
65 reg = 2;
66 shift = 4;
67 } else {
68 reg = 1;
69 shift = 3;
70 }
71 tmp = snd_akm4xxx_get(ak, 0, reg);
72 old = (tmp >> shift) & 0x03;
73 if (old == dfs)
74 return;
75
76 /* reset DFS */
77 snd_akm4xxx_reset(ak, 1);
78 tmp = snd_akm4xxx_get(ak, 0, reg);
79 tmp &= ~(0x03 << shift);
80 tmp |= dfs << shift;
81 // snd_akm4xxx_write(ak, 0, reg, tmp);
82 snd_akm4xxx_set(ak, 0, reg, tmp); /* the value is written in reset(0) */
83 snd_akm4xxx_reset(ak, 0);
84}
85
86/*
87 * initialize the chips on M-Audio Revolution cards
88 */
89
90static akm4xxx_t akm_revo_front __devinitdata = {
91 .type = SND_AK4381,
92 .num_dacs = 2,
93 .ops = {
94 .set_rate_val = revo_set_rate_val
95 }
96};
97
98static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
99 .caddr = 1,
100 .cif = 0,
101 .data_mask = VT1724_REVO_CDOUT,
102 .clk_mask = VT1724_REVO_CCLK,
103 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
104 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
105 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
106 .add_flags = VT1724_REVO_CCLK, /* high at init */
107 .mask_flags = 0,
108};
109
110static akm4xxx_t akm_revo_surround __devinitdata = {
111 .type = SND_AK4355,
112 .idx_offset = 1,
113 .num_dacs = 6,
114 .ops = {
115 .set_rate_val = revo_set_rate_val
116 }
117};
118
119static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
120 .caddr = 3,
121 .cif = 0,
122 .data_mask = VT1724_REVO_CDOUT,
123 .clk_mask = VT1724_REVO_CCLK,
124 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
125 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
126 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
127 .add_flags = VT1724_REVO_CCLK, /* high at init */
128 .mask_flags = 0,
129};
130
131static unsigned int rates[] = {
132 32000, 44100, 48000, 64000, 88200, 96000,
133 176400, 192000,
134};
135
136static snd_pcm_hw_constraint_list_t revo_rates = {
137 .count = ARRAY_SIZE(rates),
138 .list = rates,
139 .mask = 0,
140};
141
142static int __devinit revo_init(ice1712_t *ice)
143{
144 akm4xxx_t *ak;
145 int err;
146
147 /* determine I2C, DACs and ADCs */
148 switch (ice->eeprom.subvendor) {
149 case VT1724_SUBDEVICE_REVOLUTION71:
150 ice->num_total_dacs = 8;
151 ice->num_total_adcs = 2;
152 break;
153 default:
154 snd_BUG();
155 return -EINVAL;
156 }
157
158 ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
159
160 /* second stage of initialization, analog parts and others */
161 ak = ice->akm = kcalloc(2, sizeof(akm4xxx_t), GFP_KERNEL);
162 if (! ak)
163 return -ENOMEM;
164 ice->akm_codecs = 2;
165 switch (ice->eeprom.subvendor) {
166 case VT1724_SUBDEVICE_REVOLUTION71:
167 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0)
168 return err;
169 if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0)
170 return err;
171 /* unmute all codecs */
172 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
173 break;
174 }
175
176 ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
177
178 return 0;
179}
180
181
182static int __devinit revo_add_controls(ice1712_t *ice)
183{
184 int err;
185
186 switch (ice->eeprom.subvendor) {
187 case VT1724_SUBDEVICE_REVOLUTION71:
188 err = snd_ice1712_akm4xxx_build_controls(ice);
189 if (err < 0)
190 return err;
191 }
192 return 0;
193}
194
195/* entry point */
196struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
197 {
198 .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
199 .name = "M Audio Revolution-7.1",
200 .model = "revo71",
201 .chip_init = revo_init,
202 .build_controls = revo_add_controls,
203 },
204 { } /* terminator */
205};
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h
new file mode 100644
index 000000000000..ca4420b5e3ec
--- /dev/null
+++ b/sound/pci/ice1712/revo.h
@@ -0,0 +1,48 @@
1#ifndef __SOUND_REVO_H
2#define __SOUND_REVO_H
3
4/*
5 * ALSA driver for ICEnsemble ICE1712 (Envy24)
6 *
7 * Lowlevel functions for M-Audio Revolution 7.1
8 *
9 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
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
27#define REVO_DEVICE_DESC \
28 "{MidiMan M Audio,Revolution 7.1},"
29
30#define VT1724_SUBDEVICE_REVOLUTION71 0x12143036
31
32/* entry point */
33extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
34
35
36/*
37 * MidiMan M-Audio Revolution GPIO definitions
38 */
39
40#define VT1724_REVO_CCLK 0x02
41#define VT1724_REVO_CDIN 0x04 /* not used */
42#define VT1724_REVO_CDOUT 0x08
43#define VT1724_REVO_CS0 0x10 /* not used */
44#define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */
45#define VT1724_REVO_CS2 0x40 /* surround AKM4355 chipselect */
46#define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */
47
48#endif /* __SOUND_REVO_H */
diff --git a/sound/pci/ice1712/stac946x.h b/sound/pci/ice1712/stac946x.h
new file mode 100644
index 000000000000..5b390952d0e4
--- /dev/null
+++ b/sound/pci/ice1712/stac946x.h
@@ -0,0 +1,25 @@
1#ifndef __SOUND_STAC946X_H
2#define __SOUND_STAC946X_H
3
4#define STAC946X_RESET 0x00
5#define STAC946X_STATUS 0x01
6#define STAC946X_MASTER_VOLUME 0x02
7#define STAC946X_LF_VOLUME 0x03
8#define STAC946X_RF_VOLUME 0x04
9#define STAC946X_LR_VOLUME 0x05
10#define STAC946X_RR_VOLUME 0x06
11#define STAC946X_CENTER_VOLUME 0x07
12#define STAC946X_LFE_VOLUME 0x08
13#define STAC946X_MIC_L_VOLUME 0x09
14#define STAC946X_MIC_R_VOLUME 0x0a
15#define STAC946X_DEEMPHASIS 0x0c
16#define STAC946X_GENERAL_PURPOSE 0x0d
17#define STAC946X_AUDIO_PORT_CONTROL 0x0e
18#define STAC946X_MASTER_CLOCKING 0x0f
19#define STAC946X_POWERDOWN_CTRL1 0x10
20#define STAC946X_POWERDOWN_CTRL2 0x11
21#define STAC946X_REVISION_CODE 0x12
22#define STAC946X_ADDRESS_CONTROL 0x13
23#define STAC946X_ADDRESS 0x14
24
25#endif /* __SOUND_STAC946X_H */
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
new file mode 100644
index 000000000000..3bd92627231c
--- /dev/null
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -0,0 +1,115 @@
1/*
2 * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
3 *
4 * Lowlevel functions for VT1720-based motherboards
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
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
24#include <sound/driver.h>
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31
32#include "ice1712.h"
33#include "vt1720_mobo.h"
34
35
36static int __devinit k8x800_init(ice1712_t *ice)
37{
38 ice->vt1720 = 1;
39
40 /* VT1616 codec */
41 ice->num_total_dacs = 6;
42 ice->num_total_adcs = 2;
43
44 /* WM8728 codec */
45 /* FIXME: TODO */
46
47 return 0;
48}
49
50static int __devinit k8x800_add_controls(ice1712_t *ice)
51{
52 /* FIXME: needs some quirks for VT1616? */
53 return 0;
54}
55
56/* EEPROM image */
57
58static unsigned char k8x800_eeprom[] __devinitdata = {
59 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */
60 0x02, /* ACLINK: ACLINK, packed */
61 0x00, /* I2S: - */
62 0x00, /* SPDIF: - */
63 0xff, /* GPIO_DIR */
64 0xff, /* GPIO_DIR1 */
65 0x00, /* - */
66 0xff, /* GPIO_MASK */
67 0xff, /* GPIO_MASK1 */
68 0x00, /* - */
69 0x00, /* GPIO_STATE */
70 0x00, /* GPIO_STATE1 */
71 0x00, /* - */
72};
73
74
75/* entry point */
76struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
77 {
78 .subvendor = VT1720_SUBDEVICE_K8X800,
79 .name = "Albatron K8X800 Pro II",
80 .model = "k8x800",
81 .chip_init = k8x800_init,
82 .build_controls = k8x800_add_controls,
83 .eeprom_size = sizeof(k8x800_eeprom),
84 .eeprom_data = k8x800_eeprom,
85 },
86 {
87 .subvendor = VT1720_SUBDEVICE_ZNF3_150,
88 .name = "Chaintech ZNF3-150",
89 /* identical with k8x800 */
90 .chip_init = k8x800_init,
91 .build_controls = k8x800_add_controls,
92 .eeprom_size = sizeof(k8x800_eeprom),
93 .eeprom_data = k8x800_eeprom,
94 },
95 {
96 .subvendor = VT1720_SUBDEVICE_ZNF3_250,
97 .name = "Chaintech ZNF3-250",
98 /* identical with k8x800 */
99 .chip_init = k8x800_init,
100 .build_controls = k8x800_add_controls,
101 .eeprom_size = sizeof(k8x800_eeprom),
102 .eeprom_data = k8x800_eeprom,
103 },
104 {
105 .subvendor = VT1720_SUBDEVICE_9CJS,
106 .name = "Chaintech 9CJS",
107 /* identical with k8x800 */
108 .chip_init = k8x800_init,
109 .build_controls = k8x800_add_controls,
110 .eeprom_size = sizeof(k8x800_eeprom),
111 .eeprom_data = k8x800_eeprom,
112 },
113 { } /* terminator */
114};
115
diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h
new file mode 100644
index 000000000000..f949eb804cae
--- /dev/null
+++ b/sound/pci/ice1712/vt1720_mobo.h
@@ -0,0 +1,39 @@
1#ifndef __SOUND_VT1720_MOBO_H
2#define __SOUND_VT1720_MOBO_H
3
4/*
5 * ALSA driver for VT1720/VT1724 (Envy24PT/Envy24HT)
6 *
7 * Lowlevel functions for VT1720-based motherboards
8 *
9 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
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
27#define VT1720_MOBO_DEVICE_DESC "{Albatron,K8X800 Pro II},"\
28 "{Chaintech,ZNF3-150},"\
29 "{Chaintech,ZNF3-250},"\
30 "{Chaintech,9CJS},"
31
32#define VT1720_SUBDEVICE_K8X800 0xf217052c
33#define VT1720_SUBDEVICE_ZNF3_150 0x0f2741f6
34#define VT1720_SUBDEVICE_ZNF3_250 0x0f2745f6
35#define VT1720_SUBDEVICE_9CJS 0x0f272327
36
37extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
38
39#endif /* __SOUND_VT1720_MOBO_H */