Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wtm.c
Go to the documentation of this file.
1 /*
2  * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3  *
4  * Lowlevel functions for Ego Sys Waveterminal 192M
5  *
6  * Copyright (c) 2006 Guedez Clement <[email protected]>
7  * Some functions are taken from the Prodigy192 driver
8  * source
9  *
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.
14  *
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.
19  *
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
23  *
24  */
25 
26 
27 
28 #include <linux/io.h>
29 #include <linux/delay.h>
30 #include <linux/interrupt.h>
31 #include <linux/init.h>
32 #include <sound/core.h>
33 
34 #include "ice1712.h"
35 #include "envy24ht.h"
36 #include "wtm.h"
37 #include "stac946x.h"
38 
39 
40 /*
41  * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
42  */
43 static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
44  unsigned char val)
45 {
47 }
48 
49 static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
50 {
51  return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
52 }
53 
54 /*
55  * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
56  */
57 static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
58  unsigned char val)
59 {
61 }
62 
63 static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
64 {
65  return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
66 }
67 
68 
69 /*
70  * DAC mute control
71  */
72 #define stac9460_dac_mute_info snd_ctl_boolean_mono_info
73 
74 static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
75  struct snd_ctl_elem_value *ucontrol)
76 {
77  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
78  unsigned char val;
79  int idx, id;
80 
81  if (kcontrol->private_value) {
83  id = 0;
84  } else {
85  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
86  idx = id + STAC946X_LF_VOLUME;
87  }
88  if (id < 6)
89  val = stac9460_get(ice, idx);
90  else
91  val = stac9460_2_get(ice, idx - 6);
92  ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
93  return 0;
94 }
95 
96 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
97  struct snd_ctl_elem_value *ucontrol)
98 {
99  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
100  unsigned char new, old;
101  int id, idx;
102  int change;
103 
104  if (kcontrol->private_value) {
106  old = stac9460_get(ice, idx);
107  new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
108  (old & ~0x80);
109  change = (new != old);
110  if (change) {
111  stac9460_put(ice, idx, new);
112  stac9460_2_put(ice, idx, new);
113  }
114  } else {
115  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
116  idx = id + STAC946X_LF_VOLUME;
117  if (id < 6)
118  old = stac9460_get(ice, idx);
119  else
120  old = stac9460_2_get(ice, idx - 6);
121  new = (~ucontrol->value.integer.value[0] << 7 & 0x80) |
122  (old & ~0x80);
123  change = (new != old);
124  if (change) {
125  if (id < 6)
126  stac9460_put(ice, idx, new);
127  else
128  stac9460_2_put(ice, idx - 6, new);
129  }
130  }
131  return change;
132 }
133 
134 /*
135  * DAC volume attenuation mixer control
136  */
137 static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
138  struct snd_ctl_elem_info *uinfo)
139 {
141  uinfo->count = 1;
142  uinfo->value.integer.min = 0; /* mute */
143  uinfo->value.integer.max = 0x7f; /* 0dB */
144  return 0;
145 }
146 
147 static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
148  struct snd_ctl_elem_value *ucontrol)
149 {
150  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
151  int idx, id;
152  unsigned char vol;
153 
154  if (kcontrol->private_value) {
156  id = 0;
157  } else {
158  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
159  idx = id + STAC946X_LF_VOLUME;
160  }
161  if (id < 6)
162  vol = stac9460_get(ice, idx) & 0x7f;
163  else
164  vol = stac9460_2_get(ice, idx - 6) & 0x7f;
165  ucontrol->value.integer.value[0] = 0x7f - vol;
166  return 0;
167 }
168 
169 static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
170  struct snd_ctl_elem_value *ucontrol)
171 {
172  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
173  int idx, id;
174  unsigned char tmp, ovol, nvol;
175  int change;
176 
177  if (kcontrol->private_value) {
179  nvol = ucontrol->value.integer.value[0] & 0x7f;
180  tmp = stac9460_get(ice, idx);
181  ovol = 0x7f - (tmp & 0x7f);
182  change = (ovol != nvol);
183  if (change) {
184  stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
185  stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
186  }
187  } else {
188  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
189  idx = id + STAC946X_LF_VOLUME;
190  nvol = ucontrol->value.integer.value[0] & 0x7f;
191  if (id < 6)
192  tmp = stac9460_get(ice, idx);
193  else
194  tmp = stac9460_2_get(ice, idx - 6);
195  ovol = 0x7f - (tmp & 0x7f);
196  change = (ovol != nvol);
197  if (change) {
198  if (id < 6)
199  stac9460_put(ice, idx, (0x7f - nvol) |
200  (tmp & 0x80));
201  else
202  stac9460_2_put(ice, idx-6, (0x7f - nvol) |
203  (tmp & 0x80));
204  }
205  }
206  return change;
207 }
208 
209 /*
210  * ADC mute control
211  */
212 #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
213 
214 static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
215  struct snd_ctl_elem_value *ucontrol)
216 {
217  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
218  unsigned char val;
219  int i, id;
220 
221  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
222  if (id == 0) {
223  for (i = 0; i < 2; ++i) {
224  val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
225  ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
226  }
227  } else {
228  for (i = 0; i < 2; ++i) {
229  val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
230  ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
231  }
232  }
233  return 0;
234 }
235 
236 static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
237  struct snd_ctl_elem_value *ucontrol)
238 {
239  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
240  unsigned char new, old;
241  int i, reg, id;
242  int change;
243 
244  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
245  if (id == 0) {
246  for (i = 0; i < 2; ++i) {
247  reg = STAC946X_MIC_L_VOLUME + i;
248  old = stac9460_get(ice, reg);
249  new = (~ucontrol->value.integer.value[i]<<7&0x80) |
250  (old&~0x80);
251  change = (new != old);
252  if (change)
253  stac9460_put(ice, reg, new);
254  }
255  } else {
256  for (i = 0; i < 2; ++i) {
257  reg = STAC946X_MIC_L_VOLUME + i;
258  old = stac9460_2_get(ice, reg);
259  new = (~ucontrol->value.integer.value[i]<<7&0x80) |
260  (old&~0x80);
261  change = (new != old);
262  if (change)
263  stac9460_2_put(ice, reg, new);
264  }
265  }
266  return change;
267 }
268 
269 /*
270  *ADC gain mixer control
271  */
272 static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
273  struct snd_ctl_elem_info *uinfo)
274 {
276  uinfo->count = 2;
277  uinfo->value.integer.min = 0; /* 0dB */
278  uinfo->value.integer.max = 0x0f; /* 22.5dB */
279  return 0;
280 }
281 
282 static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
283  struct snd_ctl_elem_value *ucontrol)
284 {
285  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
286  int i, reg, id;
287  unsigned char vol;
288 
289  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
290  if (id == 0) {
291  for (i = 0; i < 2; ++i) {
292  reg = STAC946X_MIC_L_VOLUME + i;
293  vol = stac9460_get(ice, reg) & 0x0f;
294  ucontrol->value.integer.value[i] = 0x0f - vol;
295  }
296  } else {
297  for (i = 0; i < 2; ++i) {
298  reg = STAC946X_MIC_L_VOLUME + i;
299  vol = stac9460_2_get(ice, reg) & 0x0f;
300  ucontrol->value.integer.value[i] = 0x0f - vol;
301  }
302  }
303  return 0;
304 }
305 
306 static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
307  struct snd_ctl_elem_value *ucontrol)
308 {
309  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
310  int i, reg, id;
311  unsigned char ovol, nvol;
312  int change;
313 
314  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
315  if (id == 0) {
316  for (i = 0; i < 2; ++i) {
317  reg = STAC946X_MIC_L_VOLUME + i;
318  nvol = ucontrol->value.integer.value[i] & 0x0f;
319  ovol = 0x0f - stac9460_get(ice, reg);
320  change = ((ovol & 0x0f) != nvol);
321  if (change)
322  stac9460_put(ice, reg, (0x0f - nvol) |
323  (ovol & ~0x0f));
324  }
325  } else {
326  for (i = 0; i < 2; ++i) {
327  reg = STAC946X_MIC_L_VOLUME + i;
328  nvol = ucontrol->value.integer.value[i] & 0x0f;
329  ovol = 0x0f - stac9460_2_get(ice, reg);
330  change = ((ovol & 0x0f) != nvol);
331  if (change)
332  stac9460_2_put(ice, reg, (0x0f - nvol) |
333  (ovol & ~0x0f));
334  }
335  }
336  return change;
337 }
338 
339 /*
340  * MIC / LINE switch fonction
341  */
342 
343 #define stac9460_mic_sw_info snd_ctl_boolean_mono_info
344 
345 static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
346  struct snd_ctl_elem_value *ucontrol)
347 {
348  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
349  unsigned char val;
350  int id;
351 
352  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
353  if (id == 0)
354  val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
355  else
356  val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
357  ucontrol->value.integer.value[0] = ~val>>7 & 0x1;
358  return 0;
359 }
360 
361 static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
362  struct snd_ctl_elem_value *ucontrol)
363 {
364  struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
365  unsigned char new, old;
366  int change, id;
367 
368  id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
369  if (id == 0)
370  old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
371  else
372  old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
373  new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80);
374  change = (new != old);
375  if (change) {
376  if (id == 0)
377  stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
378  else
379  stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
380  }
381  return change;
382 }
383 
384 /*
385  * Control tabs
386  */
387 static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
388  {
390  .name = "Master Playback Switch",
391  .info = stac9460_dac_mute_info,
392  .get = stac9460_dac_mute_get,
393  .put = stac9460_dac_mute_put,
394  .private_value = 1
395  },
396  {
398  .name = "Master Playback Volume",
399  .info = stac9460_dac_vol_info,
400  .get = stac9460_dac_vol_get,
401  .put = stac9460_dac_vol_put,
402  .private_value = 1,
403  },
404  {
406  .name = "MIC/Line switch",
407  .count = 2,
408  .info = stac9460_mic_sw_info,
409  .get = stac9460_mic_sw_get,
410  .put = stac9460_mic_sw_put,
411 
412  },
413  {
415  .name = "DAC Switch",
416  .count = 8,
417  .info = stac9460_dac_mute_info,
418  .get = stac9460_dac_mute_get,
419  .put = stac9460_dac_mute_put,
420  },
421  {
423  .name = "DAC Volume",
424  .count = 8,
425  .info = stac9460_dac_vol_info,
426  .get = stac9460_dac_vol_get,
427  .put = stac9460_dac_vol_put,
428  },
429  {
431  .name = "ADC Switch",
432  .count = 2,
433  .info = stac9460_adc_mute_info,
434  .get = stac9460_adc_mute_get,
435  .put = stac9460_adc_mute_put,
436  },
437  {
439  .name = "ADC Volume",
440  .count = 2,
441  .info = stac9460_adc_vol_info,
442  .get = stac9460_adc_vol_get,
443  .put = stac9460_adc_vol_put,
444 
445  }
446 };
447 
448 
449 
450 /*INIT*/
451 static int __devinit wtm_add_controls(struct snd_ice1712 *ice)
452 {
453  unsigned int i;
454  int err;
455 
456  for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
457  err = snd_ctl_add(ice->card,
458  snd_ctl_new1(&stac9640_controls[i], ice));
459  if (err < 0)
460  return err;
461  }
462  return 0;
463 }
464 
465 static int __devinit wtm_init(struct snd_ice1712 *ice)
466 {
467  static unsigned short stac_inits_prodigy[] = {
468  STAC946X_RESET, 0,
469  (unsigned short)-1
470  };
471  unsigned short *p;
472 
473  /*WTM 192M*/
474  ice->num_total_dacs = 8;
475  ice->num_total_adcs = 4;
476  ice->force_rdma1 = 1;
477 
478  /*initialize codec*/
479  p = stac_inits_prodigy;
480  for (; *p != (unsigned short)-1; p += 2) {
481  stac9460_put(ice, p[0], p[1]);
482  stac9460_2_put(ice, p[0], p[1]);
483  }
484  return 0;
485 }
486 
487 
488 static unsigned char wtm_eeprom[] __devinitdata = {
489  0x47, /*SYSCONF: clock 192KHz, 4ADC, 8DAC */
490  0x80, /* ACLINK : I2S */
491  0xf8, /* I2S: vol; 96k, 24bit, 192k */
492  0xc1 /*SPDIF: out-en, spidf ext out*/,
493  0x9f, /* GPIO_DIR */
494  0xff, /* GPIO_DIR1 */
495  0x7f, /* GPIO_DIR2 */
496  0x9f, /* GPIO_MASK */
497  0xff, /* GPIO_MASK1 */
498  0x7f, /* GPIO_MASK2 */
499  0x16, /* GPIO_STATE */
500  0x80, /* GPIO_STATE1 */
501  0x00, /* GPIO_STATE2 */
502 };
503 
504 
505 /*entry point*/
506 struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = {
507  {
508  .subvendor = VT1724_SUBDEVICE_WTM,
509  .name = "ESI Waveterminal 192M",
510  .model = "WT192M",
511  .chip_init = wtm_init,
512  .build_controls = wtm_add_controls,
513  .eeprom_size = sizeof(wtm_eeprom),
514  .eeprom_data = wtm_eeprom,
515  },
516  {} /*terminator*/
517 };