diff options
-rw-r--r-- | include/sound/pt2258.h | 37 | ||||
-rw-r--r-- | sound/i2c/Makefile | 1 | ||||
-rw-r--r-- | sound/i2c/other/Makefile | 4 | ||||
-rw-r--r-- | sound/i2c/other/pt2258.c | 233 | ||||
-rw-r--r-- | sound/pci/ice1712/ice1712.h | 14 | ||||
-rw-r--r-- | sound/pci/ice1712/revo.c | 132 | ||||
-rw-r--r-- | sound/pci/ice1712/revo.h | 6 |
7 files changed, 413 insertions, 14 deletions
diff --git a/include/sound/pt2258.h b/include/sound/pt2258.h new file mode 100644 index 000000000000..160f812faa42 --- /dev/null +++ b/include/sound/pt2258.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * ALSA Driver for the PT2258 volume controller. | ||
3 | * | ||
4 | * Copyright (c) 2006 Jochen Voss <voss@seehuhn.de> | ||
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 | #ifndef __SOUND_PT2258_H | ||
23 | #define __SOUND_PT2258_H | ||
24 | |||
25 | struct snd_pt2258 { | ||
26 | struct snd_card *card; | ||
27 | struct snd_i2c_bus *i2c_bus; | ||
28 | struct snd_i2c_device *i2c_dev; | ||
29 | |||
30 | unsigned char volume[6]; | ||
31 | int mute; | ||
32 | }; | ||
33 | |||
34 | extern int snd_pt2258_reset(struct snd_pt2258 *pt); | ||
35 | extern int snd_pt2258_build_controls(struct snd_pt2258 *pt); | ||
36 | |||
37 | #endif /* __SOUND_PT2258_H */ | ||
diff --git a/sound/i2c/Makefile b/sound/i2c/Makefile index 816a2e7c88ca..45902d48c89c 100644 --- a/sound/i2c/Makefile +++ b/sound/i2c/Makefile | |||
@@ -16,3 +16,4 @@ obj-$(CONFIG_SND) += other/ | |||
16 | # Toplevel Module Dependency | 16 | # Toplevel Module Dependency |
17 | obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o | 17 | obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o |
18 | obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o | 18 | obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o |
19 | obj-$(CONFIG_SND_ICE1724) += snd-i2c.o | ||
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile index 2fe023ef00a7..77a8a7c75dd9 100644 --- a/sound/i2c/other/Makefile +++ b/sound/i2c/other/Makefile | |||
@@ -6,11 +6,11 @@ | |||
6 | snd-ak4114-objs := ak4114.o | 6 | snd-ak4114-objs := ak4114.o |
7 | snd-ak4117-objs := ak4117.o | 7 | snd-ak4117-objs := ak4117.o |
8 | snd-ak4xxx-adda-objs := ak4xxx-adda.o | 8 | snd-ak4xxx-adda-objs := ak4xxx-adda.o |
9 | snd-pt2258-objs := pt2258.o | ||
9 | snd-tea575x-tuner-objs := tea575x-tuner.o | 10 | snd-tea575x-tuner-objs := tea575x-tuner.o |
10 | 11 | ||
11 | # Module Dependency | 12 | # Module Dependency |
12 | obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o | 13 | obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o |
13 | obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o | 14 | obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o |
14 | obj-$(CONFIG_SND_ICE1724) += snd-ak4xxx-adda.o | 15 | obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4xxx-adda.o snd-pt2258.o |
15 | obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o | ||
16 | obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o | 16 | obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o |
diff --git a/sound/i2c/other/pt2258.c b/sound/i2c/other/pt2258.c new file mode 100644 index 000000000000..50df1df2f2b9 --- /dev/null +++ b/sound/i2c/other/pt2258.c | |||
@@ -0,0 +1,233 @@ | |||
1 | /* | ||
2 | * ALSA Driver for the PT2258 volume controller. | ||
3 | * | ||
4 | * Copyright (c) 2006 Jochen Voss <voss@seehuhn.de> | ||
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 | #include <sound/driver.h> | ||
23 | #include <sound/core.h> | ||
24 | #include <sound/control.h> | ||
25 | #include <sound/tlv.h> | ||
26 | #include <sound/i2c.h> | ||
27 | #include <sound/pt2258.h> | ||
28 | |||
29 | MODULE_AUTHOR("Jochen Voss <voss@seehuhn.de>"); | ||
30 | MODULE_DESCRIPTION("PT2258 volume controller (Princeton Technology Corp.)"); | ||
31 | MODULE_LICENSE("GPL"); | ||
32 | |||
33 | #define PT2258_CMD_RESET 0xc0 | ||
34 | #define PT2258_CMD_UNMUTE 0xf8 | ||
35 | #define PT2258_CMD_MUTE 0xf9 | ||
36 | |||
37 | static const unsigned char pt2258_channel_code[12] = { | ||
38 | 0x80, 0x90, /* channel 1: -10dB, -1dB */ | ||
39 | 0x40, 0x50, /* channel 2: -10dB, -1dB */ | ||
40 | 0x00, 0x10, /* channel 3: -10dB, -1dB */ | ||
41 | 0x20, 0x30, /* channel 4: -10dB, -1dB */ | ||
42 | 0x60, 0x70, /* channel 5: -10dB, -1dB */ | ||
43 | 0xa0, 0xb0 /* channel 6: -10dB, -1dB */ | ||
44 | }; | ||
45 | |||
46 | int snd_pt2258_reset(struct snd_pt2258 *pt) | ||
47 | { | ||
48 | unsigned char bytes[2]; | ||
49 | int i; | ||
50 | |||
51 | /* reset chip */ | ||
52 | bytes[0] = PT2258_CMD_RESET; | ||
53 | snd_i2c_lock(pt->i2c_bus); | ||
54 | if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1) | ||
55 | goto __error; | ||
56 | snd_i2c_unlock(pt->i2c_bus); | ||
57 | |||
58 | /* mute all channels */ | ||
59 | pt->mute = 1; | ||
60 | bytes[0] = PT2258_CMD_MUTE; | ||
61 | snd_i2c_lock(pt->i2c_bus); | ||
62 | if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1) | ||
63 | goto __error; | ||
64 | snd_i2c_unlock(pt->i2c_bus); | ||
65 | |||
66 | /* set all channels to 0dB */ | ||
67 | for (i = 0; i < 6; ++i) | ||
68 | pt->volume[i] = 0; | ||
69 | bytes[0] = 0xd0; | ||
70 | bytes[1] = 0xe0; | ||
71 | snd_i2c_lock(pt->i2c_bus); | ||
72 | if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2) | ||
73 | goto __error; | ||
74 | snd_i2c_unlock(pt->i2c_bus); | ||
75 | |||
76 | return 0; | ||
77 | |||
78 | __error: | ||
79 | snd_i2c_unlock(pt->i2c_bus); | ||
80 | snd_printk(KERN_ERR "PT2258 reset failed\n"); | ||
81 | return -EIO; | ||
82 | } | ||
83 | |||
84 | static int pt2258_stereo_volume_info(struct snd_kcontrol *kcontrol, | ||
85 | struct snd_ctl_elem_info *uinfo) | ||
86 | { | ||
87 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
88 | uinfo->count = 2; | ||
89 | uinfo->value.integer.min = 0; | ||
90 | uinfo->value.integer.max = 79; | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int pt2258_stereo_volume_get(struct snd_kcontrol *kcontrol, | ||
95 | struct snd_ctl_elem_value *ucontrol) | ||
96 | { | ||
97 | struct snd_pt2258 *pt = kcontrol->private_data; | ||
98 | int base = kcontrol->private_value; | ||
99 | |||
100 | /* chip does not support register reads */ | ||
101 | ucontrol->value.integer.value[0] = 79 - pt->volume[base]; | ||
102 | ucontrol->value.integer.value[1] = 79 - pt->volume[base + 1]; | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int pt2258_stereo_volume_put(struct snd_kcontrol *kcontrol, | ||
107 | struct snd_ctl_elem_value *ucontrol) | ||
108 | { | ||
109 | struct snd_pt2258 *pt = kcontrol->private_data; | ||
110 | int base = kcontrol->private_value; | ||
111 | unsigned char bytes[2]; | ||
112 | int val0, val1; | ||
113 | |||
114 | val0 = 79 - ucontrol->value.integer.value[0]; | ||
115 | val1 = 79 - ucontrol->value.integer.value[1]; | ||
116 | if (val0 == pt->volume[base] && val1 == pt->volume[base + 1]) | ||
117 | return 0; | ||
118 | |||
119 | pt->volume[base] = val0; | ||
120 | bytes[0] = pt2258_channel_code[2 * base] | (val0 / 10); | ||
121 | bytes[1] = pt2258_channel_code[2 * base + 1] | (val0 % 10); | ||
122 | snd_i2c_lock(pt->i2c_bus); | ||
123 | if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2) | ||
124 | goto __error; | ||
125 | snd_i2c_unlock(pt->i2c_bus); | ||
126 | |||
127 | pt->volume[base + 1] = val1; | ||
128 | bytes[0] = pt2258_channel_code[2 * base + 2] | (val1 / 10); | ||
129 | bytes[1] = pt2258_channel_code[2 * base + 3] | (val1 % 10); | ||
130 | snd_i2c_lock(pt->i2c_bus); | ||
131 | if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2) | ||
132 | goto __error; | ||
133 | snd_i2c_unlock(pt->i2c_bus); | ||
134 | |||
135 | return 1; | ||
136 | |||
137 | __error: | ||
138 | snd_i2c_unlock(pt->i2c_bus); | ||
139 | snd_printk(KERN_ERR "PT2258 access failed\n"); | ||
140 | return -EIO; | ||
141 | } | ||
142 | |||
143 | static int pt2258_switch_info(struct snd_kcontrol *kcontrol, | ||
144 | struct snd_ctl_elem_info *uinfo) | ||
145 | { | ||
146 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
147 | uinfo->count = 1; | ||
148 | uinfo->value.integer.min = 0; | ||
149 | uinfo->value.integer.max = 1; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int pt2258_switch_get(struct snd_kcontrol *kcontrol, | ||
154 | struct snd_ctl_elem_value *ucontrol) | ||
155 | { | ||
156 | struct snd_pt2258 *pt = kcontrol->private_data; | ||
157 | |||
158 | ucontrol->value.integer.value[0] = !pt->mute; | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int pt2258_switch_put(struct snd_kcontrol *kcontrol, | ||
163 | struct snd_ctl_elem_value *ucontrol) | ||
164 | { | ||
165 | struct snd_pt2258 *pt = kcontrol->private_data; | ||
166 | unsigned char bytes[2]; | ||
167 | int val; | ||
168 | |||
169 | val = !ucontrol->value.integer.value[0]; | ||
170 | if (pt->mute == val) | ||
171 | return 0; | ||
172 | |||
173 | pt->mute = val; | ||
174 | bytes[0] = val ? PT2258_CMD_MUTE : PT2258_CMD_UNMUTE; | ||
175 | snd_i2c_lock(pt->i2c_bus); | ||
176 | if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1) | ||
177 | goto __error; | ||
178 | snd_i2c_unlock(pt->i2c_bus); | ||
179 | |||
180 | return 1; | ||
181 | |||
182 | __error: | ||
183 | snd_i2c_unlock(pt->i2c_bus); | ||
184 | snd_printk(KERN_ERR "PT2258 access failed 2\n"); | ||
185 | return -EIO; | ||
186 | } | ||
187 | |||
188 | static DECLARE_TLV_DB_SCALE(pt2258_db_scale, -7900, 100, 0); | ||
189 | |||
190 | int snd_pt2258_build_controls(struct snd_pt2258 *pt) | ||
191 | { | ||
192 | struct snd_kcontrol_new knew; | ||
193 | char *names[3] = { | ||
194 | "Mic Loopback Playback Volume", | ||
195 | "Line Loopback Playback Volume", | ||
196 | "CD Loopback Playback Volume" | ||
197 | }; | ||
198 | int i, err; | ||
199 | |||
200 | for (i = 0; i < 3; ++i) { | ||
201 | memset(&knew, 0, sizeof(knew)); | ||
202 | knew.name = names[i]; | ||
203 | knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
204 | knew.count = 1; | ||
205 | knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
206 | SNDRV_CTL_ELEM_ACCESS_TLV_READ; | ||
207 | knew.private_value = 2 * i; | ||
208 | knew.info = pt2258_stereo_volume_info; | ||
209 | knew.get = pt2258_stereo_volume_get; | ||
210 | knew.put = pt2258_stereo_volume_put; | ||
211 | knew.tlv.p = pt2258_db_scale; | ||
212 | |||
213 | err = snd_ctl_add(pt->card, snd_ctl_new1(&knew, pt)); | ||
214 | if (err < 0) | ||
215 | return err; | ||
216 | } | ||
217 | |||
218 | memset(&knew, 0, sizeof(knew)); | ||
219 | knew.name = "Loopback Switch"; | ||
220 | knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
221 | knew.info = pt2258_switch_info; | ||
222 | knew.get = pt2258_switch_get; | ||
223 | knew.put = pt2258_switch_put; | ||
224 | knew.access = 0; | ||
225 | err = snd_ctl_add(pt->card, snd_ctl_new1(&knew, pt)); | ||
226 | if (err < 0) | ||
227 | return err; | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | EXPORT_SYMBOL(snd_pt2258_reset); | ||
233 | EXPORT_SYMBOL(snd_pt2258_build_controls); | ||
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index ce27eac40d4e..064542bf3af8 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <sound/i2c.h> | 28 | #include <sound/i2c.h> |
29 | #include <sound/ak4xxx-adda.h> | 29 | #include <sound/ak4xxx-adda.h> |
30 | #include <sound/ak4114.h> | 30 | #include <sound/ak4114.h> |
31 | #include <sound/pt2258.h> | ||
31 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
32 | #include <sound/mpu401.h> | 33 | #include <sound/mpu401.h> |
33 | 34 | ||
@@ -381,6 +382,11 @@ struct snd_ice1712 { | |||
381 | unsigned short master[2]; | 382 | unsigned short master[2]; |
382 | unsigned short vol[8]; | 383 | unsigned short vol[8]; |
383 | } phase28; | 384 | } phase28; |
385 | /* a non-standard I2C device for revo51 */ | ||
386 | struct revo51_spec { | ||
387 | struct snd_i2c_device *dev; | ||
388 | struct snd_pt2258 *pt2258; | ||
389 | } revo51; | ||
384 | /* Hoontech-specific setting */ | 390 | /* Hoontech-specific setting */ |
385 | struct hoontech_spec { | 391 | struct hoontech_spec { |
386 | unsigned char boxbits[4]; | 392 | unsigned char boxbits[4]; |
@@ -462,6 +468,14 @@ static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice, | |||
462 | snd_ice1712_gpio_write(ice, mask & bits); | 468 | snd_ice1712_gpio_write(ice, mask & bits); |
463 | } | 469 | } |
464 | 470 | ||
471 | static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice, | ||
472 | unsigned int mask) | ||
473 | { | ||
474 | ice->gpio.direction &= ~mask; | ||
475 | snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); | ||
476 | return (snd_ice1712_gpio_read(ice) & mask); | ||
477 | } | ||
478 | |||
465 | int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); | 479 | int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); |
466 | 480 | ||
467 | int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template, | 481 | int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template, |
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index d556de59b9ae..233e9a5a2e70 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c | |||
@@ -84,6 +84,102 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
84 | } | 84 | } |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1) | ||
88 | */ | ||
89 | |||
90 | static void revo_i2c_start(struct snd_i2c_bus *bus) | ||
91 | { | ||
92 | struct snd_ice1712 *ice = bus->private_data; | ||
93 | snd_ice1712_save_gpio_status(ice); | ||
94 | } | ||
95 | |||
96 | static void revo_i2c_stop(struct snd_i2c_bus *bus) | ||
97 | { | ||
98 | struct snd_ice1712 *ice = bus->private_data; | ||
99 | snd_ice1712_restore_gpio_status(ice); | ||
100 | } | ||
101 | |||
102 | static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data) | ||
103 | { | ||
104 | struct snd_ice1712 *ice = bus->private_data; | ||
105 | unsigned int mask, val; | ||
106 | |||
107 | val = 0; | ||
108 | if (clock) | ||
109 | val |= VT1724_REVO_I2C_CLOCK; /* write SCL */ | ||
110 | if (data) | ||
111 | val |= VT1724_REVO_I2C_DATA; /* write SDA */ | ||
112 | mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA; | ||
113 | ice->gpio.direction &= ~mask; | ||
114 | ice->gpio.direction |= val; | ||
115 | snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); | ||
116 | snd_ice1712_gpio_set_mask(ice, ~mask); | ||
117 | } | ||
118 | |||
119 | static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data) | ||
120 | { | ||
121 | struct snd_ice1712 *ice = bus->private_data; | ||
122 | unsigned int val = 0; | ||
123 | |||
124 | if (clk) | ||
125 | val |= VT1724_REVO_I2C_CLOCK; | ||
126 | if (data) | ||
127 | val |= VT1724_REVO_I2C_DATA; | ||
128 | snd_ice1712_gpio_write_bits(ice, | ||
129 | VT1724_REVO_I2C_DATA | | ||
130 | VT1724_REVO_I2C_CLOCK, val); | ||
131 | udelay(5); | ||
132 | } | ||
133 | |||
134 | static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack) | ||
135 | { | ||
136 | struct snd_ice1712 *ice = bus->private_data; | ||
137 | int bit; | ||
138 | |||
139 | if (ack) | ||
140 | udelay(5); | ||
141 | bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0; | ||
142 | return bit; | ||
143 | } | ||
144 | |||
145 | static struct snd_i2c_bit_ops revo51_bit_ops = { | ||
146 | .start = revo_i2c_start, | ||
147 | .stop = revo_i2c_stop, | ||
148 | .direction = revo_i2c_direction, | ||
149 | .setlines = revo_i2c_setlines, | ||
150 | .getdata = revo_i2c_getdata, | ||
151 | }; | ||
152 | |||
153 | static int revo51_i2c_init(struct snd_ice1712 *ice, | ||
154 | struct snd_pt2258 *pt) | ||
155 | { | ||
156 | int err; | ||
157 | |||
158 | /* create the I2C bus */ | ||
159 | err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c); | ||
160 | if (err < 0) | ||
161 | return err; | ||
162 | |||
163 | ice->i2c->private_data = ice; | ||
164 | ice->i2c->hw_ops.bit = &revo51_bit_ops; | ||
165 | |||
166 | /* create the I2C device */ | ||
167 | err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, | ||
168 | &ice->spec.revo51.dev); | ||
169 | if (err < 0) | ||
170 | return err; | ||
171 | |||
172 | pt->card = ice->card; | ||
173 | pt->i2c_bus = ice->i2c; | ||
174 | pt->i2c_dev = ice->spec.revo51.dev; | ||
175 | ice->spec.revo51.pt2258 = pt; | ||
176 | |||
177 | snd_pt2258_reset(pt); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | /* | ||
87 | * initialize the chips on M-Audio Revolution cards | 183 | * initialize the chips on M-Audio Revolution cards |
88 | */ | 184 | */ |
89 | 185 | ||
@@ -180,9 +276,9 @@ static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { | |||
180 | .cif = 0, | 276 | .cif = 0, |
181 | .data_mask = VT1724_REVO_CDOUT, | 277 | .data_mask = VT1724_REVO_CDOUT, |
182 | .clk_mask = VT1724_REVO_CCLK, | 278 | .clk_mask = VT1724_REVO_CCLK, |
183 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, | 279 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, |
184 | .cs_addr = VT1724_REVO_CS1 | VT1724_REVO_CS2, | 280 | .cs_addr = VT1724_REVO_CS1, |
185 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, | 281 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, |
186 | .add_flags = VT1724_REVO_CCLK, /* high at init */ | 282 | .add_flags = VT1724_REVO_CCLK, /* high at init */ |
187 | .mask_flags = 0, | 283 | .mask_flags = 0, |
188 | }; | 284 | }; |
@@ -198,13 +294,15 @@ static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { | |||
198 | .cif = 0, | 294 | .cif = 0, |
199 | .data_mask = VT1724_REVO_CDOUT, | 295 | .data_mask = VT1724_REVO_CDOUT, |
200 | .clk_mask = VT1724_REVO_CCLK, | 296 | .clk_mask = VT1724_REVO_CCLK, |
201 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, | 297 | .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1, |
202 | .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2, | 298 | .cs_addr = VT1724_REVO_CS0, |
203 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, | 299 | .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1, |
204 | .add_flags = VT1724_REVO_CCLK, /* high at init */ | 300 | .add_flags = VT1724_REVO_CCLK, /* high at init */ |
205 | .mask_flags = 0, | 301 | .mask_flags = 0, |
206 | }; | 302 | }; |
207 | 303 | ||
304 | static struct snd_pt2258 ptc_revo51_volume; | ||
305 | |||
208 | static int __devinit revo_init(struct snd_ice1712 *ice) | 306 | static int __devinit revo_init(struct snd_ice1712 *ice) |
209 | { | 307 | { |
210 | struct snd_akm4xxx *ak; | 308 | struct snd_akm4xxx *ak; |
@@ -243,14 +341,20 @@ static int __devinit revo_init(struct snd_ice1712 *ice) | |||
243 | break; | 341 | break; |
244 | case VT1724_SUBDEVICE_REVOLUTION51: | 342 | case VT1724_SUBDEVICE_REVOLUTION51: |
245 | ice->akm_codecs = 2; | 343 | ice->akm_codecs = 2; |
246 | if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, &akm_revo51_priv, ice)) < 0) | 344 | err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, |
345 | &akm_revo51_priv, ice); | ||
346 | if (err < 0) | ||
247 | return err; | 347 | return err; |
248 | err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo51_adc, | 348 | err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc, |
249 | &akm_revo51_adc_priv, ice); | 349 | &akm_revo51_adc_priv, ice); |
250 | if (err < 0) | 350 | if (err < 0) |
251 | return err; | 351 | return err; |
252 | /* unmute all codecs - needed! */ | 352 | err = revo51_i2c_init(ice, &ptc_revo51_volume); |
253 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); | 353 | if (err < 0) |
354 | return err; | ||
355 | /* unmute all codecs */ | ||
356 | snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, | ||
357 | VT1724_REVO_MUTE); | ||
254 | break; | 358 | break; |
255 | } | 359 | } |
256 | 360 | ||
@@ -264,10 +368,18 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) | |||
264 | 368 | ||
265 | switch (ice->eeprom.subvendor) { | 369 | switch (ice->eeprom.subvendor) { |
266 | case VT1724_SUBDEVICE_REVOLUTION71: | 370 | case VT1724_SUBDEVICE_REVOLUTION71: |
371 | err = snd_ice1712_akm4xxx_build_controls(ice); | ||
372 | if (err < 0) | ||
373 | return err; | ||
374 | break; | ||
267 | case VT1724_SUBDEVICE_REVOLUTION51: | 375 | case VT1724_SUBDEVICE_REVOLUTION51: |
268 | err = snd_ice1712_akm4xxx_build_controls(ice); | 376 | err = snd_ice1712_akm4xxx_build_controls(ice); |
269 | if (err < 0) | 377 | if (err < 0) |
270 | return err; | 378 | return err; |
379 | err = snd_pt2258_build_controls(ice->spec.revo51.pt2258); | ||
380 | if (err < 0) | ||
381 | return err; | ||
382 | break; | ||
271 | } | 383 | } |
272 | return 0; | 384 | return 0; |
273 | } | 385 | } |
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h index efbb86ec3289..c70adaf017c1 100644 --- a/sound/pci/ice1712/revo.h +++ b/sound/pci/ice1712/revo.h | |||
@@ -42,9 +42,11 @@ extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | |||
42 | #define VT1724_REVO_CCLK 0x02 | 42 | #define VT1724_REVO_CCLK 0x02 |
43 | #define VT1724_REVO_CDIN 0x04 /* not used */ | 43 | #define VT1724_REVO_CDIN 0x04 /* not used */ |
44 | #define VT1724_REVO_CDOUT 0x08 | 44 | #define VT1724_REVO_CDOUT 0x08 |
45 | #define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for Rev. 5.1 */ | 45 | #define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for (revo51) */ |
46 | #define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */ | 46 | #define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */ |
47 | #define VT1724_REVO_CS2 0x40 /* surround AKM4355 chipselect */ | 47 | #define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */ |
48 | #define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */ | ||
49 | #define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */ | ||
48 | #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ | 50 | #define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ |
49 | 51 | ||
50 | #endif /* __SOUND_REVO_H */ | 52 | #endif /* __SOUND_REVO_H */ |