2 * ALSA driver for ICEnsemble ICE1712 (Envy24)
4 * Lowlevel functions for M-Audio Revolution 7.1
6 * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
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.
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.
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
24 #include <sound/driver.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>
36 static void revo_i2s_mclk_changed(struct snd_ice1712
*ice
)
38 /* assert PRST# to converters; MT05 bit 7 */
39 outb(inb(ICEMT1724(ice
, AC97_CMD
)) | 0x80, ICEMT1724(ice
, AC97_CMD
));
42 outb(inb(ICEMT1724(ice
, AC97_CMD
)) & ~0x80, ICEMT1724(ice
, AC97_CMD
));
46 * change the rate of envy24HT, AK4355 and AK4381
48 static void revo_set_rate_val(struct snd_akm4xxx
*ak
, unsigned int rate
)
50 unsigned char old
, tmp
, dfs
;
53 if (rate
== 0) /* no hint - S/PDIF input is master, simply return */
56 /* adjust DFS on codecs */
59 else if (rate
> 48000)
64 if (ak
->type
== SND_AK4355
|| ak
->type
== SND_AK4358
) {
71 tmp
= snd_akm4xxx_get(ak
, 0, reg
);
72 old
= (tmp
>> shift
) & 0x03;
77 snd_akm4xxx_reset(ak
, 1);
78 tmp
= snd_akm4xxx_get(ak
, 0, reg
);
79 tmp
&= ~(0x03 << 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);
87 * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
90 static void revo_i2c_start(struct snd_i2c_bus
*bus
)
92 struct snd_ice1712
*ice
= bus
->private_data
;
93 snd_ice1712_save_gpio_status(ice
);
96 static void revo_i2c_stop(struct snd_i2c_bus
*bus
)
98 struct snd_ice1712
*ice
= bus
->private_data
;
99 snd_ice1712_restore_gpio_status(ice
);
102 static void revo_i2c_direction(struct snd_i2c_bus
*bus
, int clock
, int data
)
104 struct snd_ice1712
*ice
= bus
->private_data
;
105 unsigned int mask
, val
;
109 val
|= VT1724_REVO_I2C_CLOCK
; /* write SCL */
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
);
119 static void revo_i2c_setlines(struct snd_i2c_bus
*bus
, int clk
, int data
)
121 struct snd_ice1712
*ice
= bus
->private_data
;
122 unsigned int val
= 0;
125 val
|= VT1724_REVO_I2C_CLOCK
;
127 val
|= VT1724_REVO_I2C_DATA
;
128 snd_ice1712_gpio_write_bits(ice
,
129 VT1724_REVO_I2C_DATA
|
130 VT1724_REVO_I2C_CLOCK
, val
);
134 static int revo_i2c_getdata(struct snd_i2c_bus
*bus
, int ack
)
136 struct snd_ice1712
*ice
= bus
->private_data
;
141 bit
= snd_ice1712_gpio_read_bits(ice
, VT1724_REVO_I2C_DATA
) ? 1 : 0;
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
,
153 static int revo51_i2c_init(struct snd_ice1712
*ice
,
154 struct snd_pt2258
*pt
)
158 /* create the I2C bus */
159 err
= snd_i2c_bus_create(ice
->card
, "ICE1724 GPIO6", NULL
, &ice
->i2c
);
163 ice
->i2c
->private_data
= ice
;
164 ice
->i2c
->hw_ops
.bit
= &revo51_bit_ops
;
166 /* create the I2C device */
167 err
= snd_i2c_device_create(ice
->i2c
, "PT2258", 0x40,
168 &ice
->spec
.revo51
.dev
);
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
;
177 snd_pt2258_reset(pt
);
183 * initialize the chips on M-Audio Revolution cards
186 #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
188 static const struct snd_akm4xxx_dac_channel revo71_front
[] = {
189 AK_DAC("PCM Playback Volume", 2)
192 static const struct snd_akm4xxx_dac_channel revo71_surround
[] = {
193 AK_DAC("PCM Center Playback Volume", 1),
194 AK_DAC("PCM LFE Playback Volume", 1),
195 AK_DAC("PCM Side Playback Volume", 2),
196 AK_DAC("PCM Rear Playback Volume", 2),
199 static const struct snd_akm4xxx_dac_channel revo51_dac
[] = {
200 AK_DAC("PCM Playback Volume", 2),
201 AK_DAC("PCM Center Playback Volume", 1),
202 AK_DAC("PCM LFE Playback Volume", 1),
203 AK_DAC("PCM Rear Playback Volume", 2),
206 static const char *revo51_adc_input_names
[] = {
213 static const struct snd_akm4xxx_adc_channel revo51_adc
[] = {
215 .name
= "PCM Capture Volume",
216 .switch_name
= "PCM Capture Switch",
218 .input_names
= revo51_adc_input_names
222 static const struct snd_akm4xxx akm_revo_front __devinitdata
= {
226 .set_rate_val
= revo_set_rate_val
228 .dac_info
= revo71_front
,
231 static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata
= {
234 .data_mask
= VT1724_REVO_CDOUT
,
235 .clk_mask
= VT1724_REVO_CCLK
,
236 .cs_mask
= VT1724_REVO_CS0
| VT1724_REVO_CS1
| VT1724_REVO_CS2
,
237 .cs_addr
= VT1724_REVO_CS0
| VT1724_REVO_CS2
,
238 .cs_none
= VT1724_REVO_CS0
| VT1724_REVO_CS1
| VT1724_REVO_CS2
,
239 .add_flags
= VT1724_REVO_CCLK
, /* high at init */
243 static const struct snd_akm4xxx akm_revo_surround __devinitdata
= {
248 .set_rate_val
= revo_set_rate_val
250 .dac_info
= revo71_surround
,
253 static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata
= {
256 .data_mask
= VT1724_REVO_CDOUT
,
257 .clk_mask
= VT1724_REVO_CCLK
,
258 .cs_mask
= VT1724_REVO_CS0
| VT1724_REVO_CS1
| VT1724_REVO_CS2
,
259 .cs_addr
= VT1724_REVO_CS0
| VT1724_REVO_CS1
,
260 .cs_none
= VT1724_REVO_CS0
| VT1724_REVO_CS1
| VT1724_REVO_CS2
,
261 .add_flags
= VT1724_REVO_CCLK
, /* high at init */
265 static const struct snd_akm4xxx akm_revo51 __devinitdata
= {
269 .set_rate_val
= revo_set_rate_val
271 .dac_info
= revo51_dac
,
274 static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata
= {
277 .data_mask
= VT1724_REVO_CDOUT
,
278 .clk_mask
= VT1724_REVO_CCLK
,
279 .cs_mask
= VT1724_REVO_CS0
| VT1724_REVO_CS1
,
280 .cs_addr
= VT1724_REVO_CS1
,
281 .cs_none
= VT1724_REVO_CS0
| VT1724_REVO_CS1
,
282 .add_flags
= VT1724_REVO_CCLK
, /* high at init */
286 static const struct snd_akm4xxx akm_revo51_adc __devinitdata
= {
289 .adc_info
= revo51_adc
,
292 static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata
= {
295 .data_mask
= VT1724_REVO_CDOUT
,
296 .clk_mask
= VT1724_REVO_CCLK
,
297 .cs_mask
= VT1724_REVO_CS0
| VT1724_REVO_CS1
,
298 .cs_addr
= VT1724_REVO_CS0
,
299 .cs_none
= VT1724_REVO_CS0
| VT1724_REVO_CS1
,
300 .add_flags
= VT1724_REVO_CCLK
, /* high at init */
304 static struct snd_pt2258 ptc_revo51_volume
;
306 /* AK4358 for AP192 DAC, AK5385A for ADC */
307 static void ap192_set_rate_val(struct snd_akm4xxx
*ak
, unsigned int rate
)
309 struct snd_ice1712
*ice
= ak
->private_data
[0];
311 revo_set_rate_val(ak
, rate
);
313 #if 1 /* FIXME: do we need this procedure? */
314 /* reset DFS pin of AK5385A for ADC, too */
315 /* DFS0 (pin 18) -- GPIO10 pin 77 */
316 snd_ice1712_save_gpio_status(ice
);
317 snd_ice1712_gpio_write_bits(ice
, 1 << 10,
318 rate
> 48000 ? (1 << 10) : 0);
319 snd_ice1712_restore_gpio_status(ice
);
323 static const struct snd_akm4xxx_dac_channel ap192_dac
[] = {
324 AK_DAC("PCM Playback Volume", 2)
327 static const struct snd_akm4xxx akm_ap192 __devinitdata
= {
331 .set_rate_val
= ap192_set_rate_val
333 .dac_info
= ap192_dac
,
336 static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata
= {
339 .data_mask
= VT1724_REVO_CDOUT
,
340 .clk_mask
= VT1724_REVO_CCLK
,
341 .cs_mask
= VT1724_REVO_CS0
| VT1724_REVO_CS3
,
342 .cs_addr
= VT1724_REVO_CS3
,
343 .cs_none
= VT1724_REVO_CS0
| VT1724_REVO_CS3
,
344 .add_flags
= VT1724_REVO_CCLK
, /* high at init */
349 /* FIXME: ak4114 makes the sound much lower due to some confliction,
350 * so let's disable it right now...
352 #define BUILD_AK4114_AP192
355 #ifdef BUILD_AK4114_AP192
356 /* AK4114 support on Audiophile 192 */
357 /* CDTO (pin 32) -- GPIO2 pin 52
358 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
359 * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
360 * CSN (pin 35) -- GPIO7 pin 59
362 #define AK4114_ADDR 0x00
364 static void write_data(struct snd_ice1712
*ice
, unsigned int gpio
,
365 unsigned int data
, int idx
)
367 for (; idx
>= 0; idx
--) {
369 gpio
&= ~VT1724_REVO_CCLK
;
370 snd_ice1712_gpio_write(ice
, gpio
);
373 if (data
& (1 << idx
))
374 gpio
|= VT1724_REVO_CDOUT
;
376 gpio
&= ~VT1724_REVO_CDOUT
;
377 snd_ice1712_gpio_write(ice
, gpio
);
380 gpio
|= VT1724_REVO_CCLK
;
381 snd_ice1712_gpio_write(ice
, gpio
);
386 static unsigned char read_data(struct snd_ice1712
*ice
, unsigned int gpio
,
389 unsigned char data
= 0;
391 for (; idx
>= 0; idx
--) {
393 gpio
&= ~VT1724_REVO_CCLK
;
394 snd_ice1712_gpio_write(ice
, gpio
);
397 if (snd_ice1712_gpio_read(ice
) & VT1724_REVO_CDIN
)
401 gpio
|= VT1724_REVO_CCLK
;
402 snd_ice1712_gpio_write(ice
, gpio
);
408 static unsigned char ap192_4wire_start(struct snd_ice1712
*ice
)
412 snd_ice1712_save_gpio_status(ice
);
413 tmp
= snd_ice1712_gpio_read(ice
);
414 tmp
|= VT1724_REVO_CCLK
; /* high at init */
415 tmp
|= VT1724_REVO_CS0
;
416 tmp
&= ~VT1724_REVO_CS3
;
417 snd_ice1712_gpio_write(ice
, tmp
);
422 static void ap192_4wire_finish(struct snd_ice1712
*ice
, unsigned int tmp
)
424 tmp
|= VT1724_REVO_CS3
;
425 tmp
|= VT1724_REVO_CS0
;
426 snd_ice1712_gpio_write(ice
, tmp
);
428 snd_ice1712_restore_gpio_status(ice
);
431 static void ap192_ak4114_write(void *private_data
, unsigned char addr
,
434 struct snd_ice1712
*ice
= private_data
;
435 unsigned int tmp
, addrdata
;
437 tmp
= ap192_4wire_start(ice
);
438 addrdata
= (AK4114_ADDR
<< 6) | 0x20 | (addr
& 0x1f);
439 addrdata
= (addrdata
<< 8) | data
;
440 write_data(ice
, tmp
, addrdata
, 15);
441 ap192_4wire_finish(ice
, tmp
);
444 static unsigned char ap192_ak4114_read(void *private_data
, unsigned char addr
)
446 struct snd_ice1712
*ice
= private_data
;
450 tmp
= ap192_4wire_start(ice
);
451 write_data(ice
, tmp
, (AK4114_ADDR
<< 6) | (addr
& 0x1f), 7);
452 data
= read_data(ice
, tmp
, 7);
453 ap192_4wire_finish(ice
, tmp
);
457 static int ap192_ak4114_init(struct snd_ice1712
*ice
)
459 static const unsigned char ak4114_init_vals
[] = {
460 AK4114_RST
| AK4114_PWN
| AK4114_OCKS0
| AK4114_OCKS1
,
463 AK4114_EFH_1024
| AK4114_DIT
| AK4114_IPS(1),
467 static const unsigned char ak4114_init_txcsb
[] = {
468 0x41, 0x02, 0x2c, 0x00, 0x00
473 return snd_ak4114_create(ice
->card
,
476 ak4114_init_vals
, ak4114_init_txcsb
,
479 #endif /* BUILD_AK4114_AP192 */
481 static int __devinit
revo_init(struct snd_ice1712
*ice
)
483 struct snd_akm4xxx
*ak
;
486 /* determine I2C, DACs and ADCs */
487 switch (ice
->eeprom
.subvendor
) {
488 case VT1724_SUBDEVICE_REVOLUTION71
:
489 ice
->num_total_dacs
= 8;
490 ice
->num_total_adcs
= 2;
491 ice
->gpio
.i2s_mclk_changed
= revo_i2s_mclk_changed
;
493 case VT1724_SUBDEVICE_REVOLUTION51
:
494 ice
->num_total_dacs
= 6;
495 ice
->num_total_adcs
= 2;
497 case VT1724_SUBDEVICE_AUDIOPHILE192
:
498 ice
->num_total_dacs
= 2;
499 ice
->num_total_adcs
= 2;
506 /* second stage of initialization, analog parts and others */
507 ak
= ice
->akm
= kcalloc(2, sizeof(struct snd_akm4xxx
), GFP_KERNEL
);
511 switch (ice
->eeprom
.subvendor
) {
512 case VT1724_SUBDEVICE_REVOLUTION71
:
514 if ((err
= snd_ice1712_akm4xxx_init(ak
, &akm_revo_front
, &akm_revo_front_priv
, ice
)) < 0)
516 if ((err
= snd_ice1712_akm4xxx_init(ak
+ 1, &akm_revo_surround
, &akm_revo_surround_priv
, ice
)) < 0)
518 /* unmute all codecs */
519 snd_ice1712_gpio_write_bits(ice
, VT1724_REVO_MUTE
, VT1724_REVO_MUTE
);
521 case VT1724_SUBDEVICE_REVOLUTION51
:
523 err
= snd_ice1712_akm4xxx_init(ak
, &akm_revo51
,
524 &akm_revo51_priv
, ice
);
527 err
= snd_ice1712_akm4xxx_init(ak
+1, &akm_revo51_adc
,
528 &akm_revo51_adc_priv
, ice
);
531 err
= revo51_i2c_init(ice
, &ptc_revo51_volume
);
534 /* unmute all codecs */
535 snd_ice1712_gpio_write_bits(ice
, VT1724_REVO_MUTE
,
538 case VT1724_SUBDEVICE_AUDIOPHILE192
:
540 err
= snd_ice1712_akm4xxx_init(ak
, &akm_ap192
, &akm_ap192_priv
,
552 static int __devinit
revo_add_controls(struct snd_ice1712
*ice
)
556 switch (ice
->eeprom
.subvendor
) {
557 case VT1724_SUBDEVICE_REVOLUTION71
:
558 err
= snd_ice1712_akm4xxx_build_controls(ice
);
562 case VT1724_SUBDEVICE_REVOLUTION51
:
563 err
= snd_ice1712_akm4xxx_build_controls(ice
);
566 err
= snd_pt2258_build_controls(ice
->spec
.revo51
.pt2258
);
570 case VT1724_SUBDEVICE_AUDIOPHILE192
:
571 err
= snd_ice1712_akm4xxx_build_controls(ice
);
574 #ifdef BUILD_AK4114_AP192
575 err
= ap192_ak4114_init(ice
);
585 const struct snd_ice1712_card_info snd_vt1724_revo_cards
[] __devinitdata
= {
587 .subvendor
= VT1724_SUBDEVICE_REVOLUTION71
,
588 .name
= "M Audio Revolution-7.1",
590 .chip_init
= revo_init
,
591 .build_controls
= revo_add_controls
,
594 .subvendor
= VT1724_SUBDEVICE_REVOLUTION51
,
595 .name
= "M Audio Revolution-5.1",
597 .chip_init
= revo_init
,
598 .build_controls
= revo_add_controls
,
601 .subvendor
= VT1724_SUBDEVICE_AUDIOPHILE192
,
602 .name
= "M Audio Audiophile192",
604 .chip_init
= revo_init
,
605 .build_controls
= revo_add_controls
,