Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/pci/ice1712/pontis.c
10817 views
1
/*
2
* ALSA driver for ICEnsemble VT1724 (Envy24HT)
3
*
4
* Lowlevel functions for Pontis MS300
5
*
6
* Copyright (c) 2004 Takashi Iwai <[email protected]>
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 <asm/io.h>
25
#include <linux/delay.h>
26
#include <linux/interrupt.h>
27
#include <linux/init.h>
28
#include <linux/slab.h>
29
#include <linux/mutex.h>
30
31
#include <sound/core.h>
32
#include <sound/info.h>
33
#include <sound/tlv.h>
34
35
#include "ice1712.h"
36
#include "envy24ht.h"
37
#include "pontis.h"
38
39
/* I2C addresses */
40
#define WM_DEV 0x34
41
#define CS_DEV 0x20
42
43
/* WM8776 registers */
44
#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
45
#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
46
#define WM_HP_MASTER 0x02 /* headphone master (both channels) */
47
/* override LLR */
48
#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
49
#define WM_DAC_ATTEN_R 0x04
50
#define WM_DAC_MASTER 0x05
51
#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
52
#define WM_DAC_CTRL1 0x07
53
#define WM_DAC_MUTE 0x08
54
#define WM_DAC_CTRL2 0x09
55
#define WM_DAC_INT 0x0a
56
#define WM_ADC_INT 0x0b
57
#define WM_MASTER_CTRL 0x0c
58
#define WM_POWERDOWN 0x0d
59
#define WM_ADC_ATTEN_L 0x0e
60
#define WM_ADC_ATTEN_R 0x0f
61
#define WM_ALC_CTRL1 0x10
62
#define WM_ALC_CTRL2 0x11
63
#define WM_ALC_CTRL3 0x12
64
#define WM_NOISE_GATE 0x13
65
#define WM_LIMITER 0x14
66
#define WM_ADC_MUX 0x15
67
#define WM_OUT_MUX 0x16
68
#define WM_RESET 0x17
69
70
/*
71
* GPIO
72
*/
73
#define PONTIS_CS_CS (1<<4) /* CS */
74
#define PONTIS_CS_CLK (1<<5) /* CLK */
75
#define PONTIS_CS_RDATA (1<<6) /* CS8416 -> VT1720 */
76
#define PONTIS_CS_WDATA (1<<7) /* VT1720 -> CS8416 */
77
78
79
/*
80
* get the current register value of WM codec
81
*/
82
static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
83
{
84
reg <<= 1;
85
return ((unsigned short)ice->akm[0].images[reg] << 8) |
86
ice->akm[0].images[reg + 1];
87
}
88
89
/*
90
* set the register value of WM codec and remember it
91
*/
92
static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
93
{
94
unsigned short cval;
95
cval = (reg << 9) | val;
96
snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
97
}
98
99
static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
100
{
101
wm_put_nocache(ice, reg, val);
102
reg <<= 1;
103
ice->akm[0].images[reg] = val >> 8;
104
ice->akm[0].images[reg + 1] = val;
105
}
106
107
/*
108
* DAC volume attenuation mixer control (-64dB to 0dB)
109
*/
110
111
#define DAC_0dB 0xff
112
#define DAC_RES 128
113
#define DAC_MIN (DAC_0dB - DAC_RES)
114
115
static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
116
{
117
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
118
uinfo->count = 2;
119
uinfo->value.integer.min = 0; /* mute */
120
uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
121
return 0;
122
}
123
124
static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
125
{
126
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
127
unsigned short val;
128
int i;
129
130
mutex_lock(&ice->gpio_mutex);
131
for (i = 0; i < 2; i++) {
132
val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
133
val = val > DAC_MIN ? (val - DAC_MIN) : 0;
134
ucontrol->value.integer.value[i] = val;
135
}
136
mutex_unlock(&ice->gpio_mutex);
137
return 0;
138
}
139
140
static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
141
{
142
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
143
unsigned short oval, nval;
144
int i, idx, change = 0;
145
146
mutex_lock(&ice->gpio_mutex);
147
for (i = 0; i < 2; i++) {
148
nval = ucontrol->value.integer.value[i];
149
nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
150
idx = WM_DAC_ATTEN_L + i;
151
oval = wm_get(ice, idx) & 0xff;
152
if (oval != nval) {
153
wm_put(ice, idx, nval);
154
wm_put_nocache(ice, idx, nval | 0x100);
155
change = 1;
156
}
157
}
158
mutex_unlock(&ice->gpio_mutex);
159
return change;
160
}
161
162
/*
163
* ADC gain mixer control (-64dB to 0dB)
164
*/
165
166
#define ADC_0dB 0xcf
167
#define ADC_RES 128
168
#define ADC_MIN (ADC_0dB - ADC_RES)
169
170
static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
171
{
172
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
173
uinfo->count = 2;
174
uinfo->value.integer.min = 0; /* mute (-64dB) */
175
uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
176
return 0;
177
}
178
179
static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
180
{
181
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
182
unsigned short val;
183
int i;
184
185
mutex_lock(&ice->gpio_mutex);
186
for (i = 0; i < 2; i++) {
187
val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
188
val = val > ADC_MIN ? (val - ADC_MIN) : 0;
189
ucontrol->value.integer.value[i] = val;
190
}
191
mutex_unlock(&ice->gpio_mutex);
192
return 0;
193
}
194
195
static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
196
{
197
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
198
unsigned short ovol, nvol;
199
int i, idx, change = 0;
200
201
mutex_lock(&ice->gpio_mutex);
202
for (i = 0; i < 2; i++) {
203
nvol = ucontrol->value.integer.value[i];
204
nvol = nvol ? (nvol + ADC_MIN) : 0;
205
idx = WM_ADC_ATTEN_L + i;
206
ovol = wm_get(ice, idx) & 0xff;
207
if (ovol != nvol) {
208
wm_put(ice, idx, nvol);
209
change = 1;
210
}
211
}
212
mutex_unlock(&ice->gpio_mutex);
213
return change;
214
}
215
216
/*
217
* ADC input mux mixer control
218
*/
219
#define wm_adc_mux_info snd_ctl_boolean_mono_info
220
221
static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
222
{
223
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
224
int bit = kcontrol->private_value;
225
226
mutex_lock(&ice->gpio_mutex);
227
ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
228
mutex_unlock(&ice->gpio_mutex);
229
return 0;
230
}
231
232
static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
233
{
234
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
235
int bit = kcontrol->private_value;
236
unsigned short oval, nval;
237
int change;
238
239
mutex_lock(&ice->gpio_mutex);
240
nval = oval = wm_get(ice, WM_ADC_MUX);
241
if (ucontrol->value.integer.value[0])
242
nval |= (1 << bit);
243
else
244
nval &= ~(1 << bit);
245
change = nval != oval;
246
if (change) {
247
wm_put(ice, WM_ADC_MUX, nval);
248
}
249
mutex_unlock(&ice->gpio_mutex);
250
return change;
251
}
252
253
/*
254
* Analog bypass (In -> Out)
255
*/
256
#define wm_bypass_info snd_ctl_boolean_mono_info
257
258
static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
259
{
260
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
261
262
mutex_lock(&ice->gpio_mutex);
263
ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
264
mutex_unlock(&ice->gpio_mutex);
265
return 0;
266
}
267
268
static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
269
{
270
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
271
unsigned short val, oval;
272
int change = 0;
273
274
mutex_lock(&ice->gpio_mutex);
275
val = oval = wm_get(ice, WM_OUT_MUX);
276
if (ucontrol->value.integer.value[0])
277
val |= 0x04;
278
else
279
val &= ~0x04;
280
if (val != oval) {
281
wm_put(ice, WM_OUT_MUX, val);
282
change = 1;
283
}
284
mutex_unlock(&ice->gpio_mutex);
285
return change;
286
}
287
288
/*
289
* Left/Right swap
290
*/
291
#define wm_chswap_info snd_ctl_boolean_mono_info
292
293
static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
294
{
295
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
296
297
mutex_lock(&ice->gpio_mutex);
298
ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
299
mutex_unlock(&ice->gpio_mutex);
300
return 0;
301
}
302
303
static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
304
{
305
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
306
unsigned short val, oval;
307
int change = 0;
308
309
mutex_lock(&ice->gpio_mutex);
310
oval = wm_get(ice, WM_DAC_CTRL1);
311
val = oval & 0x0f;
312
if (ucontrol->value.integer.value[0])
313
val |= 0x60;
314
else
315
val |= 0x90;
316
if (val != oval) {
317
wm_put(ice, WM_DAC_CTRL1, val);
318
wm_put_nocache(ice, WM_DAC_CTRL1, val);
319
change = 1;
320
}
321
mutex_unlock(&ice->gpio_mutex);
322
return change;
323
}
324
325
/*
326
* write data in the SPI mode
327
*/
328
static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
329
{
330
unsigned int tmp = snd_ice1712_gpio_read(ice);
331
if (val)
332
tmp |= bit;
333
else
334
tmp &= ~bit;
335
snd_ice1712_gpio_write(ice, tmp);
336
}
337
338
static void spi_send_byte(struct snd_ice1712 *ice, unsigned char data)
339
{
340
int i;
341
for (i = 0; i < 8; i++) {
342
set_gpio_bit(ice, PONTIS_CS_CLK, 0);
343
udelay(1);
344
set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
345
udelay(1);
346
set_gpio_bit(ice, PONTIS_CS_CLK, 1);
347
udelay(1);
348
data <<= 1;
349
}
350
}
351
352
static unsigned int spi_read_byte(struct snd_ice1712 *ice)
353
{
354
int i;
355
unsigned int val = 0;
356
357
for (i = 0; i < 8; i++) {
358
val <<= 1;
359
set_gpio_bit(ice, PONTIS_CS_CLK, 0);
360
udelay(1);
361
if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
362
val |= 1;
363
udelay(1);
364
set_gpio_bit(ice, PONTIS_CS_CLK, 1);
365
udelay(1);
366
}
367
return val;
368
}
369
370
371
static void spi_write(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg, unsigned int data)
372
{
373
snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
374
snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
375
set_gpio_bit(ice, PONTIS_CS_CS, 0);
376
spi_send_byte(ice, dev & ~1); /* WRITE */
377
spi_send_byte(ice, reg); /* MAP */
378
spi_send_byte(ice, data); /* DATA */
379
/* trigger */
380
set_gpio_bit(ice, PONTIS_CS_CS, 1);
381
udelay(1);
382
/* restore */
383
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
384
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
385
}
386
387
static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg)
388
{
389
unsigned int val;
390
snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
391
snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
392
set_gpio_bit(ice, PONTIS_CS_CS, 0);
393
spi_send_byte(ice, dev & ~1); /* WRITE */
394
spi_send_byte(ice, reg); /* MAP */
395
/* trigger */
396
set_gpio_bit(ice, PONTIS_CS_CS, 1);
397
udelay(1);
398
set_gpio_bit(ice, PONTIS_CS_CS, 0);
399
spi_send_byte(ice, dev | 1); /* READ */
400
val = spi_read_byte(ice);
401
/* trigger */
402
set_gpio_bit(ice, PONTIS_CS_CS, 1);
403
udelay(1);
404
/* restore */
405
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
406
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
407
return val;
408
}
409
410
411
/*
412
* SPDIF input source
413
*/
414
static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
415
{
416
static const char * const texts[] = {
417
"Coax", /* RXP0 */
418
"Optical", /* RXP1 */
419
"CD", /* RXP2 */
420
};
421
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
422
uinfo->count = 1;
423
uinfo->value.enumerated.items = 3;
424
if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
425
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
426
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
427
return 0;
428
}
429
430
static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
431
{
432
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
433
434
mutex_lock(&ice->gpio_mutex);
435
ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
436
mutex_unlock(&ice->gpio_mutex);
437
return 0;
438
}
439
440
static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
441
{
442
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
443
unsigned char val;
444
int change = 0;
445
446
mutex_lock(&ice->gpio_mutex);
447
if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
448
ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
449
val = 0x80 | (ice->gpio.saved[0] << 3);
450
spi_write(ice, CS_DEV, 0x04, val);
451
change = 1;
452
}
453
mutex_unlock(&ice->gpio_mutex);
454
return change;
455
}
456
457
458
/*
459
* GPIO controls
460
*/
461
static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
462
{
463
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
464
uinfo->count = 1;
465
uinfo->value.integer.min = 0;
466
uinfo->value.integer.max = 0xffff; /* 16bit */
467
return 0;
468
}
469
470
static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
471
{
472
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
473
mutex_lock(&ice->gpio_mutex);
474
/* 4-7 reserved */
475
ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
476
mutex_unlock(&ice->gpio_mutex);
477
return 0;
478
}
479
480
static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
481
{
482
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
483
unsigned int val;
484
int changed;
485
mutex_lock(&ice->gpio_mutex);
486
/* 4-7 reserved */
487
val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
488
changed = val != ice->gpio.write_mask;
489
ice->gpio.write_mask = val;
490
mutex_unlock(&ice->gpio_mutex);
491
return changed;
492
}
493
494
static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
495
{
496
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
497
mutex_lock(&ice->gpio_mutex);
498
/* 4-7 reserved */
499
ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
500
mutex_unlock(&ice->gpio_mutex);
501
return 0;
502
}
503
504
static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
505
{
506
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
507
unsigned int val;
508
int changed;
509
mutex_lock(&ice->gpio_mutex);
510
/* 4-7 reserved */
511
val = ucontrol->value.integer.value[0] & 0xff0f;
512
changed = (val != ice->gpio.direction);
513
ice->gpio.direction = val;
514
mutex_unlock(&ice->gpio_mutex);
515
return changed;
516
}
517
518
static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
519
{
520
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
521
mutex_lock(&ice->gpio_mutex);
522
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
523
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
524
ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
525
mutex_unlock(&ice->gpio_mutex);
526
return 0;
527
}
528
529
static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
530
{
531
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
532
unsigned int val, nval;
533
int changed = 0;
534
mutex_lock(&ice->gpio_mutex);
535
snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
536
snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
537
val = snd_ice1712_gpio_read(ice) & 0xffff;
538
nval = ucontrol->value.integer.value[0] & 0xffff;
539
if (val != nval) {
540
snd_ice1712_gpio_write(ice, nval);
541
changed = 1;
542
}
543
mutex_unlock(&ice->gpio_mutex);
544
return changed;
545
}
546
547
static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
548
549
/*
550
* mixers
551
*/
552
553
static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
554
{
555
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
556
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
557
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
558
.name = "PCM Playback Volume",
559
.info = wm_dac_vol_info,
560
.get = wm_dac_vol_get,
561
.put = wm_dac_vol_put,
562
.tlv = { .p = db_scale_volume },
563
},
564
{
565
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
566
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
567
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
568
.name = "Capture Volume",
569
.info = wm_adc_vol_info,
570
.get = wm_adc_vol_get,
571
.put = wm_adc_vol_put,
572
.tlv = { .p = db_scale_volume },
573
},
574
{
575
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
576
.name = "CD Capture Switch",
577
.info = wm_adc_mux_info,
578
.get = wm_adc_mux_get,
579
.put = wm_adc_mux_put,
580
.private_value = 0,
581
},
582
{
583
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584
.name = "Line Capture Switch",
585
.info = wm_adc_mux_info,
586
.get = wm_adc_mux_get,
587
.put = wm_adc_mux_put,
588
.private_value = 1,
589
},
590
{
591
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
592
.name = "Analog Bypass Switch",
593
.info = wm_bypass_info,
594
.get = wm_bypass_get,
595
.put = wm_bypass_put,
596
},
597
{
598
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
599
.name = "Swap Output Channels",
600
.info = wm_chswap_info,
601
.get = wm_chswap_get,
602
.put = wm_chswap_put,
603
},
604
{
605
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
606
.name = "IEC958 Input Source",
607
.info = cs_source_info,
608
.get = cs_source_get,
609
.put = cs_source_put,
610
},
611
/* FIXME: which interface? */
612
{
613
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
614
.name = "GPIO Mask",
615
.info = pontis_gpio_mask_info,
616
.get = pontis_gpio_mask_get,
617
.put = pontis_gpio_mask_put,
618
},
619
{
620
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
621
.name = "GPIO Direction",
622
.info = pontis_gpio_mask_info,
623
.get = pontis_gpio_dir_get,
624
.put = pontis_gpio_dir_put,
625
},
626
{
627
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
628
.name = "GPIO Data",
629
.info = pontis_gpio_mask_info,
630
.get = pontis_gpio_data_get,
631
.put = pontis_gpio_data_put,
632
},
633
};
634
635
636
/*
637
* WM codec registers
638
*/
639
static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
640
{
641
struct snd_ice1712 *ice = entry->private_data;
642
char line[64];
643
unsigned int reg, val;
644
mutex_lock(&ice->gpio_mutex);
645
while (!snd_info_get_line(buffer, line, sizeof(line))) {
646
if (sscanf(line, "%x %x", &reg, &val) != 2)
647
continue;
648
if (reg <= 0x17 && val <= 0xffff)
649
wm_put(ice, reg, val);
650
}
651
mutex_unlock(&ice->gpio_mutex);
652
}
653
654
static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
655
{
656
struct snd_ice1712 *ice = entry->private_data;
657
int reg, val;
658
659
mutex_lock(&ice->gpio_mutex);
660
for (reg = 0; reg <= 0x17; reg++) {
661
val = wm_get(ice, reg);
662
snd_iprintf(buffer, "%02x = %04x\n", reg, val);
663
}
664
mutex_unlock(&ice->gpio_mutex);
665
}
666
667
static void wm_proc_init(struct snd_ice1712 *ice)
668
{
669
struct snd_info_entry *entry;
670
if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
671
snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
672
entry->mode |= S_IWUSR;
673
entry->c.text.write = wm_proc_regs_write;
674
}
675
}
676
677
static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
678
{
679
struct snd_ice1712 *ice = entry->private_data;
680
int reg, val;
681
682
mutex_lock(&ice->gpio_mutex);
683
for (reg = 0; reg <= 0x26; reg++) {
684
val = spi_read(ice, CS_DEV, reg);
685
snd_iprintf(buffer, "%02x = %02x\n", reg, val);
686
}
687
val = spi_read(ice, CS_DEV, 0x7f);
688
snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val);
689
mutex_unlock(&ice->gpio_mutex);
690
}
691
692
static void cs_proc_init(struct snd_ice1712 *ice)
693
{
694
struct snd_info_entry *entry;
695
if (! snd_card_proc_new(ice->card, "cs_codec", &entry))
696
snd_info_set_text_ops(entry, ice, cs_proc_regs_read);
697
}
698
699
700
static int __devinit pontis_add_controls(struct snd_ice1712 *ice)
701
{
702
unsigned int i;
703
int err;
704
705
for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
706
err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
707
if (err < 0)
708
return err;
709
}
710
711
wm_proc_init(ice);
712
cs_proc_init(ice);
713
714
return 0;
715
}
716
717
718
/*
719
* initialize the chip
720
*/
721
static int __devinit pontis_init(struct snd_ice1712 *ice)
722
{
723
static const unsigned short wm_inits[] = {
724
/* These come first to reduce init pop noise */
725
WM_ADC_MUX, 0x00c0, /* ADC mute */
726
WM_DAC_MUTE, 0x0001, /* DAC softmute */
727
WM_DAC_CTRL1, 0x0000, /* DAC mute */
728
729
WM_POWERDOWN, 0x0008, /* All power-up except HP */
730
WM_RESET, 0x0000, /* reset */
731
};
732
static const unsigned short wm_inits2[] = {
733
WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
734
WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
735
WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
736
WM_DAC_CTRL1, 0x0090, /* DAC L/R */
737
WM_OUT_MUX, 0x0001, /* OUT DAC */
738
WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
739
WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
740
WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
741
WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
742
WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
743
WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
744
/* WM_DAC_MASTER, 0x0100, */ /* DAC master muted */
745
WM_PHASE_SWAP, 0x0000, /* phase normal */
746
WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
747
WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
748
WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
749
#if 0
750
WM_ALC_CTRL1, 0x007b, /* */
751
WM_ALC_CTRL2, 0x0000, /* */
752
WM_ALC_CTRL3, 0x0000, /* */
753
WM_NOISE_GATE, 0x0000, /* */
754
#endif
755
WM_DAC_MUTE, 0x0000, /* DAC unmute */
756
WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
757
};
758
static const unsigned char cs_inits[] = {
759
0x04, 0x80, /* RUN, RXP0 */
760
0x05, 0x05, /* slave, 24bit */
761
0x01, 0x00,
762
0x02, 0x00,
763
0x03, 0x00,
764
};
765
unsigned int i;
766
767
ice->vt1720 = 1;
768
ice->num_total_dacs = 2;
769
ice->num_total_adcs = 2;
770
771
/* to remember the register values */
772
ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
773
if (! ice->akm)
774
return -ENOMEM;
775
ice->akm_codecs = 1;
776
777
/* HACK - use this as the SPDIF source.
778
* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
779
*/
780
ice->gpio.saved[0] = 0;
781
782
/* initialize WM8776 codec */
783
for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
784
wm_put(ice, wm_inits[i], wm_inits[i+1]);
785
schedule_timeout_uninterruptible(1);
786
for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
787
wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
788
789
/* initialize CS8416 codec */
790
/* assert PRST#; MT05 bit 7 */
791
outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
792
mdelay(5);
793
/* deassert PRST# */
794
outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
795
796
for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
797
spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
798
799
return 0;
800
}
801
802
803
/*
804
* Pontis boards don't provide the EEPROM data at all.
805
* hence the driver needs to sets up it properly.
806
*/
807
808
static unsigned char pontis_eeprom[] __devinitdata = {
809
[ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */
810
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
811
[ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
812
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
813
[ICE_EEP2_GPIO_DIR] = 0x07,
814
[ICE_EEP2_GPIO_DIR1] = 0x00,
815
[ICE_EEP2_GPIO_DIR2] = 0x00, /* ignored */
816
[ICE_EEP2_GPIO_MASK] = 0x0f, /* 4-7 reserved for CS8416 */
817
[ICE_EEP2_GPIO_MASK1] = 0xff,
818
[ICE_EEP2_GPIO_MASK2] = 0x00, /* ignored */
819
[ICE_EEP2_GPIO_STATE] = 0x06, /* 0-low, 1-high, 2-high */
820
[ICE_EEP2_GPIO_STATE1] = 0x00,
821
[ICE_EEP2_GPIO_STATE2] = 0x00, /* ignored */
822
};
823
824
/* entry point */
825
struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
826
{
827
.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
828
.name = "Pontis MS300",
829
.model = "ms300",
830
.chip_init = pontis_init,
831
.build_controls = pontis_add_controls,
832
.eeprom_size = sizeof(pontis_eeprom),
833
.eeprom_data = pontis_eeprom,
834
},
835
{ } /* terminator */
836
};
837
838