Blame view

sound/pci/ice1712/pontis.c 22 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /*
   *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
   *
   *   Lowlevel functions for Pontis MS300
   *
   *	Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
   *
   *   This program is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License as published by
   *   the Free Software Foundation; either version 2 of the License, or
   *   (at your option) any later version.
   *
   *   This program is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *   GNU General Public License for more details.
   *
   *   You should have received a copy of the GNU General Public License
   *   along with this program; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   *
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
  #include <asm/io.h>
  #include <linux/delay.h>
  #include <linux/interrupt.h>
  #include <linux/init.h>
  #include <linux/slab.h>
62932df8f   Ingo Molnar   [ALSA] semaphore ...
28
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
  #include <sound/core.h>
  #include <sound/info.h>
f640c3205   Takashi Iwai   [ALSA] Add dB sca...
31
  #include <sound/tlv.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
37
38
39
40
41
42
43
  
  #include "ice1712.h"
  #include "envy24ht.h"
  #include "pontis.h"
  
  /* I2C addresses */
  #define WM_DEV		0x34
  #define CS_DEV		0x20
  
  /* WM8776 registers */
  #define WM_HP_ATTEN_L		0x00	/* headphone left attenuation */
  #define WM_HP_ATTEN_R		0x01	/* headphone left attenuation */
cc67b7f73   Vedran Miletic   ALSA: ice1712/ice...
44
45
  #define WM_HP_MASTER		0x02	/* headphone master (both channels) */
  					/* override LLR */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  #define WM_DAC_ATTEN_L		0x03	/* digital left attenuation */
  #define WM_DAC_ATTEN_R		0x04
  #define WM_DAC_MASTER		0x05
  #define WM_PHASE_SWAP		0x06	/* DAC phase swap */
  #define WM_DAC_CTRL1		0x07
  #define WM_DAC_MUTE		0x08
  #define WM_DAC_CTRL2		0x09
  #define WM_DAC_INT		0x0a
  #define WM_ADC_INT		0x0b
  #define WM_MASTER_CTRL		0x0c
  #define WM_POWERDOWN		0x0d
  #define WM_ADC_ATTEN_L		0x0e
  #define WM_ADC_ATTEN_R		0x0f
  #define WM_ALC_CTRL1		0x10
  #define WM_ALC_CTRL2		0x11
  #define WM_ALC_CTRL3		0x12
  #define WM_NOISE_GATE		0x13
  #define WM_LIMITER		0x14
  #define WM_ADC_MUX		0x15
  #define WM_OUT_MUX		0x16
  #define WM_RESET		0x17
  
  /*
   * GPIO
   */
  #define PONTIS_CS_CS		(1<<4)	/* CS */
  #define PONTIS_CS_CLK		(1<<5)	/* CLK */
  #define PONTIS_CS_RDATA		(1<<6)	/* CS8416 -> VT1720 */
  #define PONTIS_CS_WDATA		(1<<7)	/* VT1720 -> CS8416 */
  
  
  /*
   * get the current register value of WM codec
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
80
  static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
83
84
85
86
87
88
89
  {
  	reg <<= 1;
  	return ((unsigned short)ice->akm[0].images[reg] << 8) |
  		ice->akm[0].images[reg + 1];
  }
  
  /*
   * set the register value of WM codec and remember it
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
90
  static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
95
  {
  	unsigned short cval;
  	cval = (reg << 9) | val;
  	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
96
  static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  {
  	wm_put_nocache(ice, reg, val);
  	reg <<= 1;
  	ice->akm[0].images[reg] = val >> 8;
  	ice->akm[0].images[reg + 1] = val;
  }
  
  /*
   * DAC volume attenuation mixer control (-64dB to 0dB)
   */
  
  #define DAC_0dB	0xff
  #define DAC_RES	128
  #define DAC_MIN	(DAC_0dB - DAC_RES)
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
111
  static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
115
116
117
118
  {
  	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  	uinfo->count = 2;
  	uinfo->value.integer.min = 0;	/* mute */
  	uinfo->value.integer.max = DAC_RES;	/* 0dB, 0.5dB step */
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
119
  static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
121
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
  	unsigned short val;
  	int i;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
124
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
129
  	for (i = 0; i < 2; i++) {
  		val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff;
  		val = val > DAC_MIN ? (val - DAC_MIN) : 0;
  		ucontrol->value.integer.value[i] = val;
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
130
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
132
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
133
  static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
135
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
  	unsigned short oval, nval;
  	int i, idx, change = 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
138
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
143
144
145
146
147
148
149
  	for (i = 0; i < 2; i++) {
  		nval = ucontrol->value.integer.value[i];
  		nval = (nval ? (nval + DAC_MIN) : 0) & 0xff;
  		idx = WM_DAC_ATTEN_L + i;
  		oval = wm_get(ice, idx) & 0xff;
  		if (oval != nval) {
  			wm_put(ice, idx, nval);
  			wm_put_nocache(ice, idx, nval | 0x100);
  			change = 1;
  		}
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
150
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
157
158
159
160
  	return change;
  }
  
  /*
   * ADC gain mixer control (-64dB to 0dB)
   */
  
  #define ADC_0dB	0xcf
  #define ADC_RES	128
  #define ADC_MIN	(ADC_0dB - ADC_RES)
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
161
  static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
165
166
167
168
  {
  	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  	uinfo->count = 2;
  	uinfo->value.integer.min = 0;	/* mute (-64dB) */
  	uinfo->value.integer.max = ADC_RES;	/* 0dB, 0.5dB step */
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
169
  static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
171
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  	unsigned short val;
  	int i;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
174
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
178
179
  	for (i = 0; i < 2; i++) {
  		val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
  		val = val > ADC_MIN ? (val - ADC_MIN) : 0;
  		ucontrol->value.integer.value[i] = val;
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
180
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
183
  static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
185
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
  	unsigned short ovol, nvol;
  	int i, idx, change = 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
188
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
191
192
193
194
195
196
197
198
  	for (i = 0; i < 2; i++) {
  		nvol = ucontrol->value.integer.value[i];
  		nvol = nvol ? (nvol + ADC_MIN) : 0;
  		idx  = WM_ADC_ATTEN_L + i;
  		ovol = wm_get(ice, idx) & 0xff;
  		if (ovol != nvol) {
  			wm_put(ice, idx, nvol);
  			change = 1;
  		}
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
199
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
205
  	return change;
  }
  
  /*
   * ADC input mux mixer control
   */
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
206
  #define wm_adc_mux_info		snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207

ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
208
  static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
210
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  	int bit = kcontrol->private_value;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
212
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  	ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
214
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
217
  static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
219
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
222
  	int bit = kcontrol->private_value;
  	unsigned short oval, nval;
  	int change;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
223
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
227
228
229
230
231
232
  	nval = oval = wm_get(ice, WM_ADC_MUX);
  	if (ucontrol->value.integer.value[0])
  		nval |= (1 << bit);
  	else
  		nval &= ~(1 << bit);
  	change = nval != oval;
  	if (change) {
  		wm_put(ice, WM_ADC_MUX, nval);
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
233
  	mutex_unlock(&ice->gpio_mutex);
43337ac0d   Takashi Iwai   [ALSA] ice1724 - ...
234
  	return change;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
237
238
239
  }
  
  /*
   * Analog bypass (In -> Out)
   */
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
240
  #define wm_bypass_info		snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241

ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
242
  static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
244
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245

62932df8f   Ingo Molnar   [ALSA] semaphore ...
246
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
  	ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
248
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
251
  static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
253
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
  	unsigned short val, oval;
  	int change = 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
256
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
260
261
262
263
264
265
  	val = oval = wm_get(ice, WM_OUT_MUX);
  	if (ucontrol->value.integer.value[0])
  		val |= 0x04;
  	else
  		val &= ~0x04;
  	if (val != oval) {
  		wm_put(ice, WM_OUT_MUX, val);
  		change = 1;
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
266
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
269
270
271
272
  	return change;
  }
  
  /*
   * Left/Right swap
   */
a5ce88909   Takashi Iwai   [ALSA] Clean up w...
273
  #define wm_chswap_info		snd_ctl_boolean_mono_info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274

ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
275
  static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
277
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278

62932df8f   Ingo Molnar   [ALSA] semaphore ...
279
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
281
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
284
  static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
286
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
  	unsigned short val, oval;
  	int change = 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
289
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
293
294
295
296
297
298
299
300
  	oval = wm_get(ice, WM_DAC_CTRL1);
  	val = oval & 0x0f;
  	if (ucontrol->value.integer.value[0])
  		val |= 0x60;
  	else
  		val |= 0x90;
  	if (val != oval) {
  		wm_put(ice, WM_DAC_CTRL1, val);
  		wm_put_nocache(ice, WM_DAC_CTRL1, val);
  		change = 1;
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
301
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
303
304
305
306
307
  	return change;
  }
  
  /*
   * write data in the SPI mode
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
308
  static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
313
314
315
316
  {
  	unsigned int tmp = snd_ice1712_gpio_read(ice);
  	if (val)
  		tmp |= bit;
  	else
  		tmp &= ~bit;
  	snd_ice1712_gpio_write(ice, tmp);
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
317
  static void spi_send_byte(struct snd_ice1712 *ice, unsigned char data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
321
322
323
324
325
326
327
328
329
  {
  	int i;
  	for (i = 0; i < 8; i++) {
  		set_gpio_bit(ice, PONTIS_CS_CLK, 0);
  		udelay(1);
  		set_gpio_bit(ice, PONTIS_CS_WDATA, data & 0x80);
  		udelay(1);
  		set_gpio_bit(ice, PONTIS_CS_CLK, 1);
  		udelay(1);
  		data <<= 1;
  	}
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
330
  static unsigned int spi_read_byte(struct snd_ice1712 *ice)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
  {
  	int i;
  	unsigned int val = 0;
  
  	for (i = 0; i < 8; i++) {
  		val <<= 1;
  		set_gpio_bit(ice, PONTIS_CS_CLK, 0);
  		udelay(1);
  		if (snd_ice1712_gpio_read(ice) & PONTIS_CS_RDATA)
  			val |= 1;
  		udelay(1);
  		set_gpio_bit(ice, PONTIS_CS_CLK, 1);
  		udelay(1);
  	}
  	return val;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
347
  static void spi_write(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg, unsigned int data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  {
  	snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
  	snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
  	set_gpio_bit(ice, PONTIS_CS_CS, 0);
  	spi_send_byte(ice, dev & ~1); /* WRITE */
  	spi_send_byte(ice, reg); /* MAP */
  	spi_send_byte(ice, data); /* DATA */
  	/* trigger */
  	set_gpio_bit(ice, PONTIS_CS_CS, 1);
  	udelay(1);
  	/* restore */
  	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
  	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
362
  static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  {
  	unsigned int val;
  	snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
  	snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
  	set_gpio_bit(ice, PONTIS_CS_CS, 0);
  	spi_send_byte(ice, dev & ~1); /* WRITE */
  	spi_send_byte(ice, reg); /* MAP */
  	/* trigger */
  	set_gpio_bit(ice, PONTIS_CS_CS, 1);
  	udelay(1);
  	set_gpio_bit(ice, PONTIS_CS_CS, 0);
  	spi_send_byte(ice, dev | 1); /* READ */
  	val = spi_read_byte(ice);
  	/* trigger */
  	set_gpio_bit(ice, PONTIS_CS_CS, 1);
  	udelay(1);
  	/* restore */
  	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
  	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
  	return val;
  }
  
  
  /*
   * SPDIF input source
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
389
  static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  {
32b47da03   Takashi Iwai   [ALSA] Add 'const...
391
  	static const char * const texts[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
393
394
395
396
397
398
399
400
401
402
403
  		"Coax",		/* RXP0 */
  		"Optical",	/* RXP1 */
  		"CD",		/* RXP2 */
  	};
  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  	uinfo->count = 1;
  	uinfo->value.enumerated.items = 3;
  	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
  		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
  	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
404
  static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
406
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407

62932df8f   Ingo Molnar   [ALSA] semaphore ...
408
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  	ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
62932df8f   Ingo Molnar   [ALSA] semaphore ...
410
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
412
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
413
  static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
415
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
  	unsigned char val;
  	int change = 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
418
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
420
421
422
423
424
  	if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) {
  		ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3;
  		val = 0x80 | (ice->gpio.saved[0] << 3);
  		spi_write(ice, CS_DEV, 0x04, val);
  		change = 1;
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
425
  	mutex_unlock(&ice->gpio_mutex);
43337ac0d   Takashi Iwai   [ALSA] ice1724 - ...
426
  	return change;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
429
430
431
432
  }
  
  
  /*
   * GPIO controls
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
433
  static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
436
437
438
439
440
  {
  	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  	uinfo->count = 1;
  	uinfo->value.integer.min = 0;
  	uinfo->value.integer.max = 0xffff; /* 16bit */
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
441
  static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
443
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
62932df8f   Ingo Molnar   [ALSA] semaphore ...
444
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
446
  	/* 4-7 reserved */
  	ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
447
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
450
  	return 0;
  }
  	
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
451
  static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
453
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
455
  	unsigned int val;
  	int changed;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
456
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
458
459
460
  	/* 4-7 reserved */
  	val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0;
  	changed = val != ice->gpio.write_mask;
  	ice->gpio.write_mask = val;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
461
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
463
  	return changed;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
464
  static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
466
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
62932df8f   Ingo Molnar   [ALSA] semaphore ...
467
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
469
  	/* 4-7 reserved */
  	ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
470
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
473
  	return 0;
  }
  	
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
474
  static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
476
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
  	unsigned int val;
  	int changed;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
479
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
482
483
  	/* 4-7 reserved */
  	val = ucontrol->value.integer.value[0] & 0xff0f;
  	changed = (val != ice->gpio.direction);
  	ice->gpio.direction = val;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
484
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
  	return changed;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
487
  static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
489
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
62932df8f   Ingo Molnar   [ALSA] semaphore ...
490
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
  	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
  	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
  	ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
494
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
  	return 0;
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
497
  static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
499
  	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
  	unsigned int val, nval;
  	int changed = 0;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
502
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
505
506
507
508
509
510
  	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
  	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
  	val = snd_ice1712_gpio_read(ice) & 0xffff;
  	nval = ucontrol->value.integer.value[0] & 0xffff;
  	if (val != nval) {
  		snd_ice1712_gpio_write(ice, nval);
  		changed = 1;
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
511
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
513
  	return changed;
  }
0cb29ea0d   Takashi Iwai   [ALSA] Add even m...
514
  static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
f640c3205   Takashi Iwai   [ALSA] Add dB sca...
515

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
517
518
  /*
   * mixers
   */
1b60f6b09   Takashi Iwai   [ALSA] Fix confli...
519
  static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
f640c3205   Takashi Iwai   [ALSA] Add dB sca...
522
523
  		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
524
525
526
527
  		.name = "PCM Playback Volume",
  		.info = wm_dac_vol_info,
  		.get = wm_dac_vol_get,
  		.put = wm_dac_vol_put,
f640c3205   Takashi Iwai   [ALSA] Add dB sca...
528
  		.tlv = { .p = db_scale_volume },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
530
531
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
f640c3205   Takashi Iwai   [ALSA] Add dB sca...
532
533
  		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  			   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
  		.name = "Capture Volume",
  		.info = wm_adc_vol_info,
  		.get = wm_adc_vol_get,
  		.put = wm_adc_vol_put,
f640c3205   Takashi Iwai   [ALSA] Add dB sca...
538
  		.tlv = { .p = db_scale_volume },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  		.name = "CD Capture Switch",
  		.info = wm_adc_mux_info,
  		.get = wm_adc_mux_get,
  		.put = wm_adc_mux_put,
  		.private_value = 0,
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  		.name = "Line Capture Switch",
  		.info = wm_adc_mux_info,
  		.get = wm_adc_mux_get,
  		.put = wm_adc_mux_put,
  		.private_value = 1,
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  		.name = "Analog Bypass Switch",
  		.info = wm_bypass_info,
  		.get = wm_bypass_get,
  		.put = wm_bypass_put,
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  		.name = "Swap Output Channels",
  		.info = wm_chswap_info,
  		.get = wm_chswap_get,
  		.put = wm_chswap_put,
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  		.name = "IEC958 Input Source",
  		.info = cs_source_info,
  		.get = cs_source_get,
  		.put = cs_source_put,
  	},
  	/* FIXME: which interface? */
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_CARD,
  		.name = "GPIO Mask",
  		.info = pontis_gpio_mask_info,
  		.get = pontis_gpio_mask_get,
  		.put = pontis_gpio_mask_put,
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_CARD,
  		.name = "GPIO Direction",
  		.info = pontis_gpio_mask_info,
  		.get = pontis_gpio_dir_get,
  		.put = pontis_gpio_dir_put,
  	},
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_CARD,
  		.name = "GPIO Data",
  		.info = pontis_gpio_mask_info,
  		.get = pontis_gpio_data_get,
  		.put = pontis_gpio_data_put,
  	},
  };
  
  
  /*
   * WM codec registers
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
605
  static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
  {
9fe856e47   Joe Perches   sound: Remove unn...
607
  	struct snd_ice1712 *ice = entry->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
609
  	char line[64];
  	unsigned int reg, val;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
610
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
612
613
614
615
616
  	while (!snd_info_get_line(buffer, line, sizeof(line))) {
  		if (sscanf(line, "%x %x", &reg, &val) != 2)
  			continue;
  		if (reg <= 0x17 && val <= 0xffff)
  			wm_put(ice, reg, val);
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
617
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
619
  static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620
  {
9fe856e47   Joe Perches   sound: Remove unn...
621
  	struct snd_ice1712 *ice = entry->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  	int reg, val;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
623
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
625
626
627
628
  	for (reg = 0; reg <= 0x17; reg++) {
  		val = wm_get(ice, reg);
  		snd_iprintf(buffer, "%02x = %04x
  ", reg, val);
  	}
62932df8f   Ingo Molnar   [ALSA] semaphore ...
629
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
631
  static void wm_proc_init(struct snd_ice1712 *ice)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
633
  	struct snd_info_entry *entry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
  	if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
bf850204a   Takashi Iwai   [ALSA] Remove unn...
635
  		snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  		entry->mode |= S_IWUSR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
638
639
  		entry->c.text.write = wm_proc_regs_write;
  	}
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
640
  static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
  {
9fe856e47   Joe Perches   sound: Remove unn...
642
  	struct snd_ice1712 *ice = entry->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
  	int reg, val;
62932df8f   Ingo Molnar   [ALSA] semaphore ...
644
  	mutex_lock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
646
647
648
649
650
651
652
  	for (reg = 0; reg <= 0x26; reg++) {
  		val = spi_read(ice, CS_DEV, reg);
  		snd_iprintf(buffer, "%02x = %02x
  ", reg, val);
  	}
  	val = spi_read(ice, CS_DEV, 0x7f);
  	snd_iprintf(buffer, "%02x = %02x
  ", 0x7f, val);
62932df8f   Ingo Molnar   [ALSA] semaphore ...
653
  	mutex_unlock(&ice->gpio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
655
  static void cs_proc_init(struct snd_ice1712 *ice)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
  {
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
657
  	struct snd_info_entry *entry;
bf850204a   Takashi Iwai   [ALSA] Remove unn...
658
659
  	if (! snd_card_proc_new(ice->card, "cs_codec", &entry))
  		snd_info_set_text_ops(entry, ice, cs_proc_regs_read);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
  }
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
661
  static int __devinit pontis_add_controls(struct snd_ice1712 *ice)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
  {
  	unsigned int i;
  	int err;
  
  	for (i = 0; i < ARRAY_SIZE(pontis_controls); i++) {
  		err = snd_ctl_add(ice->card, snd_ctl_new1(&pontis_controls[i], ice));
  		if (err < 0)
  			return err;
  	}
  
  	wm_proc_init(ice);
  	cs_proc_init(ice);
  
  	return 0;
  }
  
  
  /*
   * initialize the chip
   */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
682
  static int __devinit pontis_init(struct snd_ice1712 *ice)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
683
  {
32b47da03   Takashi Iwai   [ALSA] Add 'const...
684
  	static const unsigned short wm_inits[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
686
687
688
689
690
691
692
  		/* These come first to reduce init pop noise */
  		WM_ADC_MUX,	0x00c0,	/* ADC mute */
  		WM_DAC_MUTE,	0x0001,	/* DAC softmute */
  		WM_DAC_CTRL1,	0x0000,	/* DAC mute */
  
  		WM_POWERDOWN,	0x0008,	/* All power-up except HP */
  		WM_RESET,	0x0000,	/* reset */
  	};
32b47da03   Takashi Iwai   [ALSA] Add 'const...
693
  	static const unsigned short wm_inits2[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
695
696
697
698
699
700
701
702
703
704
  		WM_MASTER_CTRL,	0x0022,	/* 256fs, slave mode */
  		WM_DAC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
  		WM_ADC_INT,	0x0022,	/* I2S, normal polarity, 24bit */
  		WM_DAC_CTRL1,	0x0090,	/* DAC L/R */
  		WM_OUT_MUX,	0x0001,	/* OUT DAC */
  		WM_HP_ATTEN_L,	0x0179,	/* HP 0dB */
  		WM_HP_ATTEN_R,	0x0179,	/* HP 0dB */
  		WM_DAC_ATTEN_L,	0x0000,	/* DAC 0dB */
  		WM_DAC_ATTEN_L,	0x0100,	/* DAC 0dB */
  		WM_DAC_ATTEN_R,	0x0000,	/* DAC 0dB */
  		WM_DAC_ATTEN_R,	0x0100,	/* DAC 0dB */
cc67b7f73   Vedran Miletic   ALSA: ice1712/ice...
705
  		/* WM_DAC_MASTER,	0x0100, */	/* DAC master muted */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
706
707
708
709
710
711
712
713
714
715
716
717
718
  		WM_PHASE_SWAP,	0x0000,	/* phase normal */
  		WM_DAC_CTRL2,	0x0000,	/* no deemphasis, no ZFLG */
  		WM_ADC_ATTEN_L,	0x0000,	/* ADC muted */
  		WM_ADC_ATTEN_R,	0x0000,	/* ADC muted */
  #if 0
  		WM_ALC_CTRL1,	0x007b,	/* */
  		WM_ALC_CTRL2,	0x0000,	/* */
  		WM_ALC_CTRL3,	0x0000,	/* */
  		WM_NOISE_GATE,	0x0000,	/* */
  #endif
  		WM_DAC_MUTE,	0x0000,	/* DAC unmute */
  		WM_ADC_MUX,	0x0003,	/* ADC unmute, both CD/Line On */
  	};
32b47da03   Takashi Iwai   [ALSA] Add 'const...
719
  	static const unsigned char cs_inits[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
721
722
723
724
725
726
727
728
729
730
  		0x04,	0x80,	/* RUN, RXP0 */
  		0x05,	0x05,	/* slave, 24bit */
  		0x01,	0x00,
  		0x02,	0x00,
  		0x03,	0x00,
  	};
  	unsigned int i;
  
  	ice->vt1720 = 1;
  	ice->num_total_dacs = 2;
  	ice->num_total_adcs = 2;
25985edce   Lucas De Marchi   Fix common misspe...
731
  	/* to remember the register values */
ab0c7d72c   Takashi Iwai   [ALSA] Remove xxx...
732
  	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
734
735
736
737
738
739
740
741
742
743
744
  	if (! ice->akm)
  		return -ENOMEM;
  	ice->akm_codecs = 1;
  
  	/* HACK - use this as the SPDIF source.
  	 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
  	 */
  	ice->gpio.saved[0] = 0;
  
  	/* initialize WM8776 codec */
  	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
  		wm_put(ice, wm_inits[i], wm_inits[i+1]);
8433a509c   Nishanth Aravamudan   [ALSA] Fix schedu...
745
  	schedule_timeout_uninterruptible(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
  	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
  		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
  
  	/* initialize CS8416 codec */
  	/* assert PRST#; MT05 bit 7 */
  	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
  	mdelay(5);
  	/* deassert PRST# */
  	outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
  
  	for (i = 0; i < ARRAY_SIZE(cs_inits); i += 2)
  		spi_write(ice, CS_DEV, cs_inits[i], cs_inits[i+1]);
  
  	return 0;
  }
  
  
  /*
   * Pontis boards don't provide the EEPROM data at all.
   * hence the driver needs to sets up it properly.
   */
1b60f6b09   Takashi Iwai   [ALSA] Fix confli...
767
  static unsigned char pontis_eeprom[] __devinitdata = {
189bc1714   Takashi Iwai   [ALSA] ice1712 - ...
768
769
770
771
772
773
774
775
776
777
778
779
780
  	[ICE_EEP2_SYSCONF]     = 0x08,	/* clock 256, mpu401, spdif-in/ADC, 1DAC */
  	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
  	[ICE_EEP2_I2S]         = 0xf8,	/* vol, 96k, 24bit, 192k */
  	[ICE_EEP2_SPDIF]       = 0xc3,	/* out-en, out-int, spdif-in */
  	[ICE_EEP2_GPIO_DIR]    = 0x07,
  	[ICE_EEP2_GPIO_DIR1]   = 0x00,
  	[ICE_EEP2_GPIO_DIR2]   = 0x00,	/* ignored */
  	[ICE_EEP2_GPIO_MASK]   = 0x0f,	/* 4-7 reserved for CS8416 */
  	[ICE_EEP2_GPIO_MASK1]  = 0xff,
  	[ICE_EEP2_GPIO_MASK2]  = 0x00,	/* ignored */
  	[ICE_EEP2_GPIO_STATE]  = 0x06,	/* 0-low, 1-high, 2-high */
  	[ICE_EEP2_GPIO_STATE1] = 0x00,
  	[ICE_EEP2_GPIO_STATE2] = 0x00,	/* ignored */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
782
783
  };
  
  /* entry point */
1b60f6b09   Takashi Iwai   [ALSA] Fix confli...
784
  struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
787
788
789
790
791
792
793
794
795
  	{
  		.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
  		.name = "Pontis MS300",
  		.model = "ms300",
  		.chip_init = pontis_init,
  		.build_controls = pontis_add_controls,
  		.eeprom_size = sizeof(pontis_eeprom),
  		.eeprom_data = pontis_eeprom,
  	},
  	{ } /* terminator */
  };