2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
4 * Lowlevel functions for Ego Sys Waveterminal 192M
6 * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
7 * Some functions are taken from the Prodigy192 driver
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.
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.
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
28 #include <sound/driver.h>
30 #include <linux/delay.h>
31 #include <linux/interrupt.h>
32 #include <linux/init.h>
33 #include <linux/slab.h>
34 #include <sound/core.h>
43 * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
45 static inline void stac9460_put(struct snd_ice1712
*ice
, int reg
,
48 snd_vt1724_write_i2c(ice
, STAC9460_I2C_ADDR
, reg
, val
);
51 static inline unsigned char stac9460_get(struct snd_ice1712
*ice
, int reg
)
53 return snd_vt1724_read_i2c(ice
, STAC9460_I2C_ADDR
, reg
);
57 * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
59 static inline void stac9460_2_put(struct snd_ice1712
*ice
, int reg
,
62 snd_vt1724_write_i2c(ice
, STAC9460_2_I2C_ADDR
, reg
, val
);
65 static inline unsigned char stac9460_2_get(struct snd_ice1712
*ice
, int reg
)
67 return snd_vt1724_read_i2c(ice
, STAC9460_2_I2C_ADDR
, reg
);
74 static int stac9460_dac_mute_info(struct snd_kcontrol
*kcontrol
,
75 struct snd_ctl_elem_info
*uinfo
)
77 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
79 uinfo
->value
.integer
.min
= 0;
83 static int stac9460_dac_mute_get(struct snd_kcontrol
*kcontrol
,
84 struct snd_ctl_elem_value
*ucontrol
)
86 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
90 if (kcontrol
->private_value
) {
91 idx
= STAC946X_MASTER_VOLUME
;
94 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
95 idx
= id
+ STAC946X_LF_VOLUME
;
98 val
= stac9460_get(ice
, idx
);
100 val
= stac9460_2_get(ice
,idx
- 6);
101 ucontrol
->value
.integer
.value
[0] = (~val
>> 7) & 0x1;
105 static int stac9460_dac_mute_put(struct snd_kcontrol
*kcontrol
,
106 struct snd_ctl_elem_value
*ucontrol
)
108 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
109 unsigned char new, old
;
113 if (kcontrol
->private_value
) {
114 idx
= STAC946X_MASTER_VOLUME
;
115 old
= stac9460_get(ice
, idx
);
116 new = (~ucontrol
->value
.integer
.value
[0]<< 7 & 0x80) |
118 change
= (new != old
);
120 stac9460_put(ice
, idx
, new);
121 stac9460_2_put(ice
, idx
, new);
124 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
125 idx
= id
+ STAC946X_LF_VOLUME
;
127 old
= stac9460_get(ice
, idx
);
129 old
= stac9460_2_get(ice
, idx
- 6);
130 new = (~ucontrol
->value
.integer
.value
[0]<< 7 & 0x80) |
132 change
= (new != old
);
135 stac9460_put(ice
, idx
, new);
137 stac9460_2_put(ice
, idx
- 6, new);
144 * DAC volume attenuation mixer control
146 static int stac9460_dac_vol_info(struct snd_kcontrol
*kcontrol
,
147 struct snd_ctl_elem_info
*uinfo
)
149 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
151 uinfo
->value
.integer
.min
= 0; /* mute */
152 uinfo
->value
.integer
.max
= 0x7f; /* 0dB */
156 static int stac9460_dac_vol_get(struct snd_kcontrol
*kcontrol
,
157 struct snd_ctl_elem_value
*ucontrol
)
159 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
163 if (kcontrol
->private_value
) {
164 idx
= STAC946X_MASTER_VOLUME
;
167 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
168 idx
= id
+ STAC946X_LF_VOLUME
;
171 vol
= stac9460_get(ice
, idx
) & 0x7f;
173 vol
= stac9460_2_get(ice
, idx
- 6) & 0x7f;
174 ucontrol
->value
.integer
.value
[0] = 0x7f - vol
;
178 static int stac9460_dac_vol_put(struct snd_kcontrol
*kcontrol
,
179 struct snd_ctl_elem_value
*ucontrol
)
181 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
183 unsigned char tmp
, ovol
, nvol
;
186 if (kcontrol
->private_value
) {
187 idx
= STAC946X_MASTER_VOLUME
;
188 nvol
= ucontrol
->value
.integer
.value
[0];
189 tmp
= stac9460_get(ice
, idx
);
190 ovol
= 0x7f - (tmp
& 0x7f);
191 change
= (ovol
!= nvol
);
193 stac9460_put(ice
, idx
, (0x7f - nvol
) | (tmp
& 0x80));
194 stac9460_2_put(ice
, idx
, (0x7f - nvol
) | (tmp
& 0x80));
197 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
198 idx
= id
+ STAC946X_LF_VOLUME
;
199 nvol
= ucontrol
->value
.integer
.value
[0];
201 tmp
= stac9460_get(ice
, idx
);
203 tmp
= stac9460_2_get(ice
, idx
- 6);
204 ovol
= 0x7f - (tmp
& 0x7f);
205 change
= (ovol
!= nvol
);
208 stac9460_put(ice
, idx
, (0x7f - nvol
) |
211 stac9460_2_put(ice
, idx
-6, (0x7f - nvol
) |
221 static int stac9460_adc_mute_info(struct snd_kcontrol
*kcontrol
,
222 struct snd_ctl_elem_info
*uinfo
)
224 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
226 uinfo
->value
.integer
.min
= 0;
227 uinfo
->value
.integer
.max
= 1;
231 static int stac9460_adc_mute_get(struct snd_kcontrol
*kcontrol
,
232 struct snd_ctl_elem_value
*ucontrol
)
234 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
238 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
240 for (i
= 0; i
< 2; ++i
) {
241 val
= stac9460_get(ice
, STAC946X_MIC_L_VOLUME
+ i
);
242 ucontrol
->value
.integer
.value
[i
] = ~val
>>7 & 0x1;
245 for (i
= 0; i
< 2; ++i
) {
246 val
= stac9460_2_get(ice
, STAC946X_MIC_L_VOLUME
+ i
);
247 ucontrol
->value
.integer
.value
[i
] = ~val
>>7 & 0x1;
253 static int stac9460_adc_mute_put(struct snd_kcontrol
*kcontrol
,
254 struct snd_ctl_elem_value
*ucontrol
)
256 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
257 unsigned char new, old
;
261 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
263 for (i
= 0; i
< 2; ++i
) {
264 reg
= STAC946X_MIC_L_VOLUME
+ i
;
265 old
= stac9460_get(ice
, reg
);
266 new = (~ucontrol
->value
.integer
.value
[i
]<<7&0x80) |
268 change
= (new != old
);
270 stac9460_put(ice
, reg
, new);
273 for (i
= 0; i
< 2; ++i
) {
274 reg
= STAC946X_MIC_L_VOLUME
+ i
;
275 old
= stac9460_2_get(ice
, reg
);
276 new = (~ucontrol
->value
.integer
.value
[i
]<<7&0x80) |
278 change
= (new != old
);
280 stac9460_2_put(ice
, reg
, new);
287 *ADC gain mixer control
289 static int stac9460_adc_vol_info(struct snd_kcontrol
*kcontrol
,
290 struct snd_ctl_elem_info
*uinfo
)
292 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
294 uinfo
->value
.integer
.min
= 0; /* 0dB */
295 uinfo
->value
.integer
.max
= 0x0f; /* 22.5dB */
299 static int stac9460_adc_vol_get(struct snd_kcontrol
*kcontrol
,
300 struct snd_ctl_elem_value
*ucontrol
)
302 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
306 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
308 for (i
= 0; i
< 2; ++i
) {
309 reg
= STAC946X_MIC_L_VOLUME
+ i
;
310 vol
= stac9460_get(ice
, reg
) & 0x0f;
311 ucontrol
->value
.integer
.value
[i
] = 0x0f - vol
;
314 for (i
= 0; i
< 2; ++i
) {
315 reg
= STAC946X_MIC_L_VOLUME
+ i
;
316 vol
= stac9460_2_get(ice
, reg
) & 0x0f;
317 ucontrol
->value
.integer
.value
[i
] = 0x0f - vol
;
323 static int stac9460_adc_vol_put(struct snd_kcontrol
*kcontrol
,
324 struct snd_ctl_elem_value
*ucontrol
)
326 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
328 unsigned char ovol
, nvol
;
331 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
333 for (i
= 0; i
< 2; ++i
) {
334 reg
= STAC946X_MIC_L_VOLUME
+ i
;
335 nvol
= ucontrol
->value
.integer
.value
[i
];
336 ovol
= 0x0f - stac9460_get(ice
, reg
);
337 change
= ((ovol
& 0x0f) != nvol
);
339 stac9460_put(ice
, reg
, (0x0f - nvol
) |
343 for (i
= 0; i
< 2; ++i
) {
344 reg
= STAC946X_MIC_L_VOLUME
+ i
;
345 nvol
= ucontrol
->value
.integer
.value
[i
];
346 ovol
= 0x0f - stac9460_2_get(ice
, reg
);
347 change
= ((ovol
& 0x0f) != nvol
);
349 stac9460_2_put(ice
, reg
, (0x0f - nvol
) |
357 * MIC / LINE switch fonction
360 static int stac9460_mic_sw_info(struct snd_kcontrol
*kcontrol
,
361 struct snd_ctl_elem_info
*uinfo
)
363 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
365 uinfo
->value
.integer
.min
= 0;
366 uinfo
->value
.integer
.max
= 1;
370 static int stac9460_mic_sw_get(struct snd_kcontrol
*kcontrol
,
371 struct snd_ctl_elem_value
*ucontrol
)
373 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
377 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
379 val
= stac9460_get(ice
, STAC946X_GENERAL_PURPOSE
);
381 val
= stac9460_2_get(ice
, STAC946X_GENERAL_PURPOSE
);
382 ucontrol
->value
.integer
.value
[0] = ~val
>>7 & 0x1;
386 static int stac9460_mic_sw_put(struct snd_kcontrol
*kcontrol
,
387 struct snd_ctl_elem_value
*ucontrol
)
389 struct snd_ice1712
*ice
= snd_kcontrol_chip(kcontrol
);
390 unsigned char new, old
;
393 id
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
395 old
= stac9460_get(ice
, STAC946X_GENERAL_PURPOSE
);
397 old
= stac9460_2_get(ice
, STAC946X_GENERAL_PURPOSE
);
398 new = (~ucontrol
->value
.integer
.value
[0]<< 7 & 0x80) | (old
& ~0x80);
399 change
= (new != old
);
402 stac9460_put(ice
, STAC946X_GENERAL_PURPOSE
, new);
404 stac9460_2_put(ice
, STAC946X_GENERAL_PURPOSE
, new);
412 static const struct snd_kcontrol_new stac9640_controls
[] __devinitdata
= {
414 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
415 .name
= "Master Playback Switch",
416 .info
= stac9460_dac_mute_info
,
417 .get
= stac9460_dac_mute_get
,
418 .put
= stac9460_dac_mute_put
,
422 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
423 .name
= "Master Playback Volume",
424 .info
= stac9460_dac_vol_info
,
425 .get
= stac9460_dac_vol_get
,
426 .put
= stac9460_dac_vol_put
,
430 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
431 .name
= "MIC/Line switch",
433 .info
= stac9460_mic_sw_info
,
434 .get
= stac9460_mic_sw_get
,
435 .put
= stac9460_mic_sw_put
,
439 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
440 .name
= "DAC Switch",
442 .info
= stac9460_dac_mute_info
,
443 .get
= stac9460_dac_mute_get
,
444 .put
= stac9460_dac_mute_put
,
447 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
448 .name
= "DAC Volume",
450 .info
= stac9460_dac_vol_info
,
451 .get
= stac9460_dac_vol_get
,
452 .put
= stac9460_dac_vol_put
,
455 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
456 .name
= "ADC Switch",
458 .info
= stac9460_adc_mute_info
,
459 .get
= stac9460_adc_mute_get
,
460 .put
= stac9460_adc_mute_put
,
463 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
464 .name
= "ADC Volume",
466 .info
= stac9460_adc_vol_info
,
467 .get
= stac9460_adc_vol_get
,
468 .put
= stac9460_adc_vol_put
,
476 static int __devinit
wtm_add_controls(struct snd_ice1712
*ice
)
481 for (i
= 0; i
< ARRAY_SIZE(stac9640_controls
); i
++) {
482 err
= snd_ctl_add(ice
->card
,
483 snd_ctl_new1(&stac9640_controls
[i
], ice
));
490 static int __devinit
wtm_init(struct snd_ice1712
*ice
)
492 static unsigned short stac_inits_prodigy
[] = {
499 ice
->num_total_dacs
= 8;
500 ice
->num_total_adcs
= 4;
501 ice
->force_rdma1
= 1;
504 p
= stac_inits_prodigy
;
505 for (; *p
!= (unsigned short)-1; p
+= 2) {
506 stac9460_put(ice
, p
[0], p
[1]);
507 stac9460_2_put(ice
, p
[0], p
[1]);
513 static unsigned char wtm_eeprom
[] __devinitdata
= {
514 0x47, /*SYSCONF: clock 192KHz, 4ADC, 8DAC */
515 0x80, /* ACLINK : I2S */
516 0xf8, /* I2S: vol; 96k, 24bit, 192k */
517 0xc1 /*SPDIF: out-en, spidf ext out*/,
519 0xff, /* GPIO_DIR1 */
520 0x7f, /* GPIO_DIR2 */
521 0x9f, /* GPIO_MASK */
522 0xff, /* GPIO_MASK1 */
523 0x7f, /* GPIO_MASK2 */
524 0x16, /* GPIO_STATE */
525 0x80, /* GPIO_STATE1 */
526 0x00, /* GPIO_STATE2 */
531 struct snd_ice1712_card_info snd_vt1724_wtm_cards
[] __devinitdata
= {
533 .subvendor
= VT1724_SUBDEVICE_WTM
,
534 .name
= "ESI Waveterminal 192M",
536 .chip_init
= wtm_init
,
537 .build_controls
= wtm_add_controls
,
538 .eeprom_size
= sizeof(wtm_eeprom
),
539 .eeprom_data
= wtm_eeprom
,