Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/sound/pci/ice1712/phase.c (Version 2.6.31.13) and /linux/sound/pci/ice1712/phase.c (Version 2.6.11.8)


  1 /*                                                  1 
  2  *   ALSA driver for ICEnsemble ICE1724 (Envy2    
  3  *                                                
  4  *   Lowlevel functions for Terratec PHASE 22     
  5  *                                                
  6  *      Copyright (c) 2005 Misha Zhilin <misha    
  7  *                                                
  8  *   This program is free software; you can re    
  9  *   it under the terms of the GNU General Pub    
 10  *   the Free Software Foundation; either vers    
 11  *   (at your option) any later version.          
 12  *                                                
 13  *   This program is distributed in the hope t    
 14  *   but WITHOUT ANY WARRANTY; without even th    
 15  *   MERCHANTABILITY or FITNESS FOR A PARTICUL    
 16  *   GNU General Public License for more detai    
 17  *                                                
 18  *   You should have received a copy of the GN    
 19  *   along with this program; if not, write to    
 20  *   Foundation, Inc., 59 Temple Place, Suite     
 21  *                                                
 22  */                                               
 23                                                   
 24 /* PHASE 22 overview:                             
 25  *   Audio controller: VIA Envy24HT-S (slightl    
 26  *   Analog chip: AK4524 (partially via Philip    
 27  *   Digital receiver: CS8414-CS (supported in    
 28  *              PHASE 22 revision 2.0 and Terr    
 29  *              (support status unknown, pleas    
 30  *                                                
 31  *   Envy connects to AK4524                      
 32  *      - CS directly from GPIO 10                
 33  *      - CCLK via 74HCT125's gate #4 from GPI    
 34  *      - CDTI via 74HCT125's gate #2 from GPI    
 35  *              CDTI may be completely blocked    
 36  *              controlled by GPIO 3              
 37  */                                               
 38                                                   
 39 /* PHASE 28 overview:                             
 40  *   Audio controller: VIA Envy24HT (full untr    
 41  *   Analog chip: WM8770 (8 channel 192k DAC,     
 42  *   Digital receiver: CS8414-CS (supported in    
 43  */                                               
 44                                                   
 45 #include <asm/io.h>                               
 46 #include <linux/delay.h>                          
 47 #include <linux/interrupt.h>                      
 48 #include <linux/init.h>                           
 49 #include <linux/slab.h>                           
 50 #include <linux/mutex.h>                          
 51                                                   
 52 #include <sound/core.h>                           
 53                                                   
 54 #include "ice1712.h"                              
 55 #include "envy24ht.h"                             
 56 #include "phase.h"                                
 57 #include <sound/tlv.h>                            
 58                                                   
 59 /* AC97 register cache for Phase28 */             
 60 struct phase28_spec {                             
 61         unsigned short master[2];                 
 62         unsigned short vol[8];                    
 63 };                                                
 64                                                   
 65 /* WM8770 registers */                            
 66 #define WM_DAC_ATTEN            0x00    /* DAC    
 67 #define WM_DAC_MASTER_ATTEN     0x08    /* DAC    
 68 #define WM_DAC_DIG_ATTEN        0x09    /* DAC    
 69 #define WM_DAC_DIG_MASTER_ATTEN 0x11    /* DAC    
 70 #define WM_PHASE_SWAP           0x12    /* DAC    
 71 #define WM_DAC_CTRL1            0x13    /* DAC    
 72 #define WM_MUTE                 0x14    /* mut    
 73 #define WM_DAC_CTRL2            0x15    /* de-    
 74 #define WM_INT_CTRL             0x16    /* int    
 75 #define WM_MASTER               0x17    /* mas    
 76 #define WM_POWERDOWN            0x18    /* pow    
 77 #define WM_ADC_GAIN             0x19    /* ADC    
 78 #define WM_ADC_MUX              0x1b    /* inp    
 79 #define WM_OUT_MUX1             0x1c    /* out    
 80 #define WM_OUT_MUX2             0x1e    /* out    
 81 #define WM_RESET                0x1f    /* sof    
 82                                                   
 83                                                   
 84 /*                                                
 85  * Logarithmic volume values for WM8770           
 86  * Computed as 20 * Log10(255 / x)                
 87  */                                               
 88 static const unsigned char wm_vol[256] = {        
 89         127, 48, 42, 39, 36, 34, 33, 31, 30, 2    
 90         24, 23, 23, 22, 22, 21, 21, 21, 20, 20    
 91         17, 17, 17, 17, 16, 16, 16, 16, 15, 15    
 92         14, 13, 13, 13, 13, 13, 13, 13, 12, 12    
 93         11, 11, 11, 11, 11, 11, 10, 10, 10, 10    
 94         9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8,    
 95         7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6,    
 96         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,    
 97         4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3,    
 98         3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,    
 99         2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,    
100         1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,    
101 };                                                
102                                                   
103 #define WM_VOL_MAX      (sizeof(wm_vol) - 1)      
104 #define WM_VOL_MUTE     0x8000                    
105                                                   
106 static struct snd_akm4xxx akm_phase22 __devini    
107         .type = SND_AK4524,                       
108         .num_dacs = 2,                            
109         .num_adcs = 2,                            
110 };                                                
111                                                   
112 static struct snd_ak4xxx_private akm_phase22_p    
113         .caddr =        2,                        
114         .cif =          1,                        
115         .data_mask =    1 << 4,                   
116         .clk_mask =     1 << 5,                   
117         .cs_mask =      1 << 10,                  
118         .cs_addr =      1 << 10,                  
119         .cs_none =      0,                        
120         .add_flags =    1 << 3,                   
121         .mask_flags =   0,                        
122 };                                                
123                                                   
124 static int __devinit phase22_init(struct snd_i    
125 {                                                 
126         struct snd_akm4xxx *ak;                   
127         int err;                                  
128                                                   
129         /* Configure DAC/ADC description for g    
130         switch (ice->eeprom.subvendor) {          
131         case VT1724_SUBDEVICE_PHASE22:            
132         case VT1724_SUBDEVICE_TS22:               
133                 ice->num_total_dacs = 2;          
134                 ice->num_total_adcs = 2;          
135                 ice->vt1720 = 1; /* Envy24HT-S    
136                 break;                            
137         default:                                  
138                 snd_BUG();                        
139                 return -EINVAL;                   
140         }                                         
141                                                   
142         /* Initialize analog chips */             
143         ice->akm = kzalloc(sizeof(struct snd_a    
144         ak = ice->akm;                            
145         if (!ak)                                  
146                 return -ENOMEM;                   
147         ice->akm_codecs = 1;                      
148         switch (ice->eeprom.subvendor) {          
149         case VT1724_SUBDEVICE_PHASE22:            
150         case VT1724_SUBDEVICE_TS22:               
151                 err = snd_ice1712_akm4xxx_init    
152                                                   
153                 if (err < 0)                      
154                         return err;               
155                 break;                            
156         }                                         
157                                                   
158         return 0;                                 
159 }                                                 
160                                                   
161 static int __devinit phase22_add_controls(stru    
162 {                                                 
163         int err = 0;                              
164                                                   
165         switch (ice->eeprom.subvendor) {          
166         case VT1724_SUBDEVICE_PHASE22:            
167         case VT1724_SUBDEVICE_TS22:               
168                 err = snd_ice1712_akm4xxx_buil    
169                 if (err < 0)                      
170                         return err;               
171         }                                         
172         return 0;                                 
173 }                                                 
174                                                   
175 static unsigned char phase22_eeprom[] __devini    
176         [ICE_EEP2_SYSCONF]     = 0x28,  /* clo    
177                                         spdif-    
178         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S    
179         [ICE_EEP2_I2S]         = 0xf0,  /* vol    
180         [ICE_EEP2_SPDIF]       = 0xc3,  /* out    
181         [ICE_EEP2_GPIO_DIR]    = 0xff,            
182         [ICE_EEP2_GPIO_DIR1]   = 0xff,            
183         [ICE_EEP2_GPIO_DIR2]   = 0xff,            
184         [ICE_EEP2_GPIO_MASK]   = 0x00,            
185         [ICE_EEP2_GPIO_MASK1]  = 0x00,            
186         [ICE_EEP2_GPIO_MASK2]  = 0x00,            
187         [ICE_EEP2_GPIO_STATE]  = 0x00,            
188         [ICE_EEP2_GPIO_STATE1] = 0x00,            
189         [ICE_EEP2_GPIO_STATE2] = 0x00,            
190 };                                                
191                                                   
192 static unsigned char phase28_eeprom[] __devini    
193         [ICE_EEP2_SYSCONF]     = 0x2b,  /* clo    
194                                         spdif-    
195         [ICE_EEP2_ACLINK]      = 0x80,  /* I2S    
196         [ICE_EEP2_I2S]         = 0xfc,  /* vol    
197         [ICE_EEP2_SPDIF]       = 0xc3,  /* out    
198         [ICE_EEP2_GPIO_DIR]    = 0xff,            
199         [ICE_EEP2_GPIO_DIR1]   = 0xff,            
200         [ICE_EEP2_GPIO_DIR2]   = 0x5f,            
201         [ICE_EEP2_GPIO_MASK]   = 0x00,            
202         [ICE_EEP2_GPIO_MASK1]  = 0x00,            
203         [ICE_EEP2_GPIO_MASK2]  = 0x00,            
204         [ICE_EEP2_GPIO_STATE]  = 0x00,            
205         [ICE_EEP2_GPIO_STATE1] = 0x00,            
206         [ICE_EEP2_GPIO_STATE2] = 0x00,            
207 };                                                
208                                                   
209 /*                                                
210  * write data in the SPI mode                     
211  */                                               
212 static void phase28_spi_write(struct snd_ice17    
213                                 unsigned int d    
214 {                                                 
215         unsigned int tmp;                         
216         int i;                                    
217                                                   
218         tmp = snd_ice1712_gpio_read(ice);         
219                                                   
220         snd_ice1712_gpio_set_mask(ice, ~(PHASE    
221                                         PHASE2    
222         tmp |= PHASE28_WM_RW;                     
223         tmp &= ~cs;                               
224         snd_ice1712_gpio_write(ice, tmp);         
225         udelay(1);                                
226                                                   
227         for (i = bits - 1; i >= 0; i--) {         
228                 tmp &= ~PHASE28_SPI_CLK;          
229                 snd_ice1712_gpio_write(ice, tm    
230                 udelay(1);                        
231                 if (data & (1 << i))              
232                         tmp |= PHASE28_SPI_MOS    
233                 else                              
234                         tmp &= ~PHASE28_SPI_MO    
235                 snd_ice1712_gpio_write(ice, tm    
236                 udelay(1);                        
237                 tmp |= PHASE28_SPI_CLK;           
238                 snd_ice1712_gpio_write(ice, tm    
239                 udelay(1);                        
240         }                                         
241                                                   
242         tmp &= ~PHASE28_SPI_CLK;                  
243         tmp |= cs;                                
244         snd_ice1712_gpio_write(ice, tmp);         
245         udelay(1);                                
246         tmp |= PHASE28_SPI_CLK;                   
247         snd_ice1712_gpio_write(ice, tmp);         
248         udelay(1);                                
249 }                                                 
250                                                   
251 /*                                                
252  * get the current register value of WM codec     
253  */                                               
254 static unsigned short wm_get(struct snd_ice171    
255 {                                                 
256         reg <<= 1;                                
257         return ((unsigned short)ice->akm[0].im    
258                 ice->akm[0].images[reg + 1];      
259 }                                                 
260                                                   
261 /*                                                
262  * set the register value of WM codec             
263  */                                               
264 static void wm_put_nocache(struct snd_ice1712     
265 {                                                 
266         phase28_spi_write(ice, PHASE28_WM_CS,     
267 }                                                 
268                                                   
269 /*                                                
270  * set the register value of WM codec and reme    
271  */                                               
272 static void wm_put(struct snd_ice1712 *ice, in    
273 {                                                 
274         wm_put_nocache(ice, reg, val);            
275         reg <<= 1;                                
276         ice->akm[0].images[reg] = val >> 8;       
277         ice->akm[0].images[reg + 1] = val;        
278 }                                                 
279                                                   
280 static void wm_set_vol(struct snd_ice1712 *ice    
281                         unsigned short vol, un    
282 {                                                 
283         unsigned char nvol;                       
284                                                   
285         if ((master & WM_VOL_MUTE) || (vol & W    
286                 nvol = 0;                         
287         else                                      
288                 nvol = 127 - wm_vol[(((vol & ~    
289                         (master & ~WM_VOL_MUTE    
290                                                   
291         wm_put(ice, index, nvol);                 
292         wm_put_nocache(ice, index, 0x180 | nvo    
293 }                                                 
294                                                   
295 /*                                                
296  * DAC mute control                               
297  */                                               
298 #define wm_pcm_mute_info        snd_ctl_boolea    
299                                                   
300 static int wm_pcm_mute_get(struct snd_kcontrol    
301                                 struct snd_ctl    
302 {                                                 
303         struct snd_ice1712 *ice = snd_kcontrol    
304                                                   
305         mutex_lock(&ice->gpio_mutex);             
306         ucontrol->value.integer.value[0] = (wm    
307                                                   
308         mutex_unlock(&ice->gpio_mutex);           
309         return 0;                                 
310 }                                                 
311                                                   
312 static int wm_pcm_mute_put(struct snd_kcontrol    
313                                 struct snd_ctl    
314 {                                                 
315         struct snd_ice1712 *ice = snd_kcontrol    
316         unsigned short nval, oval;                
317         int change;                               
318                                                   
319         snd_ice1712_save_gpio_status(ice);        
320         oval = wm_get(ice, WM_MUTE);              
321         nval = (oval & ~0x10) | (ucontrol->val    
322         change = (nval != oval);                  
323         if (change)                               
324                 wm_put(ice, WM_MUTE, nval);       
325         snd_ice1712_restore_gpio_status(ice);     
326                                                   
327         return change;                            
328 }                                                 
329                                                   
330 /*                                                
331  * Master volume attenuation mixer control        
332  */                                               
333 static int wm_master_vol_info(struct snd_kcont    
334                                 struct snd_ctl    
335 {                                                 
336         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE    
337         uinfo->count = 2;                         
338         uinfo->value.integer.min = 0;             
339         uinfo->value.integer.max = WM_VOL_MAX;    
340         return 0;                                 
341 }                                                 
342                                                   
343 static int wm_master_vol_get(struct snd_kcontr    
344                                 struct snd_ctl    
345 {                                                 
346         struct snd_ice1712 *ice = snd_kcontrol    
347         struct phase28_spec *spec = ice->spec;    
348         int i;                                    
349         for (i = 0; i < 2; i++)                   
350                 ucontrol->value.integer.value[    
351                                                   
352         return 0;                                 
353 }                                                 
354                                                   
355 static int wm_master_vol_put(struct snd_kcontr    
356                                 struct snd_ctl    
357 {                                                 
358         struct snd_ice1712 *ice = snd_kcontrol    
359         struct phase28_spec *spec = ice->spec;    
360         int ch, change = 0;                       
361                                                   
362         snd_ice1712_save_gpio_status(ice);        
363         for (ch = 0; ch < 2; ch++) {              
364                 unsigned int vol = ucontrol->v    
365                 if (vol > WM_VOL_MAX)             
366                         continue;                 
367                 vol |= spec->master[ch] & WM_V    
368                 if (vol != spec->master[ch]) {    
369                         int dac;                  
370                         spec->master[ch] = vol    
371                         for (dac = 0; dac < ic    
372                                 wm_set_vol(ice    
373                                            spe    
374                                            spe    
375                         change = 1;               
376                 }                                 
377         }                                         
378         snd_ice1712_restore_gpio_status(ice);     
379         return change;                            
380 }                                                 
381                                                   
382 static int __devinit phase28_init(struct snd_i    
383 {                                                 
384         static const unsigned short wm_inits_p    
385                 /* These come first to reduce     
386                 0x1b, 0x044,    /* ADC Mux (AC    
387                 0x1c, 0x00B,    /* Out Mux1 (V    
388                 0x1d, 0x009,    /* Out Mux2 (V    
389                                                   
390                 0x18, 0x000,    /* All power-u    
391                                                   
392                 0x16, 0x122,    /* I2S, normal    
393                 0x17, 0x022,    /* 256fs, slav    
394                 0x00, 0,        /* DAC1 analog    
395                 0x01, 0,        /* DAC2 analog    
396                 0x02, 0,        /* DAC3 analog    
397                 0x03, 0,        /* DAC4 analog    
398                 0x04, 0,        /* DAC5 analog    
399                 0x05, 0,        /* DAC6 analog    
400                 0x06, 0,        /* DAC7 analog    
401                 0x07, 0,        /* DAC8 analog    
402                 0x08, 0x100,    /* master anal    
403                 0x09, 0xff,     /* DAC1 digita    
404                 0x0a, 0xff,     /* DAC2 digita    
405                 0x0b, 0xff,     /* DAC3 digita    
406                 0x0c, 0xff,     /* DAC4 digita    
407                 0x0d, 0xff,     /* DAC5 digita    
408                 0x0e, 0xff,     /* DAC6 digita    
409                 0x0f, 0xff,     /* DAC7 digita    
410                 0x10, 0xff,     /* DAC8 digita    
411                 0x11, 0x1ff,    /* master digi    
412                 0x12, 0x000,    /* phase norma    
413                 0x13, 0x090,    /* unmute DAC     
414                 0x14, 0x000,    /* all unmute     
415                 0x15, 0x000,    /* no deemphas    
416                 0x19, 0x000,    /* -12dB ADC/L    
417                 0x1a, 0x000,    /* -12dB ADC/R    
418                 (unsigned short)-1                
419         };                                        
420                                                   
421         unsigned int tmp;                         
422         struct snd_akm4xxx *ak;                   
423         struct phase28_spec *spec;                
424         const unsigned short *p;                  
425         int i;                                    
426                                                   
427         ice->num_total_dacs = 8;                  
428         ice->num_total_adcs = 2;                  
429                                                   
430         spec = kzalloc(sizeof(*spec), GFP_KERN    
431         if (!spec)                                
432                 return -ENOMEM;                   
433         ice->spec = spec;                         
434                                                   
435         /* Initialize analog chips */             
436         ice->akm = kzalloc(sizeof(struct snd_a    
437         ak = ice->akm;                            
438         if (!ak)                                  
439                 return -ENOMEM;                   
440         ice->akm_codecs = 1;                      
441                                                   
442         snd_ice1712_gpio_set_dir(ice, 0x5fffff    
443                                                   
444         /* reset the wm codec as the SPI mode     
445         snd_ice1712_save_gpio_status(ice);        
446         snd_ice1712_gpio_set_mask(ice, ~(PHASE    
447                                         PHASE2    
448                                                   
449         tmp = snd_ice1712_gpio_read(ice);         
450         tmp &= ~PHASE28_WM_RESET;                 
451         snd_ice1712_gpio_write(ice, tmp);         
452         udelay(1);                                
453         tmp |= PHASE28_WM_CS;                     
454         snd_ice1712_gpio_write(ice, tmp);         
455         udelay(1);                                
456         tmp |= PHASE28_WM_RESET;                  
457         snd_ice1712_gpio_write(ice, tmp);         
458         udelay(1);                                
459                                                   
460         p = wm_inits_phase28;                     
461         for (; *p != (unsigned short)-1; p +=     
462                 wm_put(ice, p[0], p[1]);          
463                                                   
464         snd_ice1712_restore_gpio_status(ice);     
465                                                   
466         spec->master[0] = WM_VOL_MUTE;            
467         spec->master[1] = WM_VOL_MUTE;            
468         for (i = 0; i < ice->num_total_dacs; i    
469                 spec->vol[i] = WM_VOL_MUTE;       
470                 wm_set_vol(ice, i, spec->vol[i    
471         }                                         
472                                                   
473         return 0;                                 
474 }                                                 
475                                                   
476 /*                                                
477  * DAC volume attenuation mixer control           
478  */                                               
479 static int wm_vol_info(struct snd_kcontrol *kc    
480                         struct snd_ctl_elem_in    
481 {                                                 
482         int voices = kcontrol->private_value >    
483         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE    
484         uinfo->count = voices;                    
485         uinfo->value.integer.min = 0;             
486         uinfo->value.integer.max = 0x7F;          
487         return 0;                                 
488 }                                                 
489                                                   
490 static int wm_vol_get(struct snd_kcontrol *kco    
491                         struct snd_ctl_elem_va    
492 {                                                 
493         struct snd_ice1712 *ice = snd_kcontrol    
494         struct phase28_spec *spec = ice->spec;    
495         int i, ofs, voices;                       
496                                                   
497         voices = kcontrol->private_value >> 8;    
498         ofs = kcontrol->private_value & 0xff;     
499         for (i = 0; i < voices; i++)              
500                 ucontrol->value.integer.value[    
501                         spec->vol[ofs+i] & ~WM    
502         return 0;                                 
503 }                                                 
504                                                   
505 static int wm_vol_put(struct snd_kcontrol *kco    
506                         struct snd_ctl_elem_va    
507 {                                                 
508         struct snd_ice1712 *ice = snd_kcontrol    
509         struct phase28_spec *spec = ice->spec;    
510         int i, idx, ofs, voices;                  
511         int change = 0;                           
512                                                   
513         voices = kcontrol->private_value >> 8;    
514         ofs = kcontrol->private_value & 0xff;     
515         snd_ice1712_save_gpio_status(ice);        
516         for (i = 0; i < voices; i++) {            
517                 unsigned int vol;                 
518                 vol = ucontrol->value.integer.    
519                 if (vol > 0x7f)                   
520                         continue;                 
521                 vol |= spec->vol[ofs+i] & WM_V    
522                 if (vol != spec->vol[ofs+i]) {    
523                         spec->vol[ofs+i] = vol    
524                         idx  = WM_DAC_ATTEN +     
525                         wm_set_vol(ice, idx, s    
526                                    spec->maste    
527                         change = 1;               
528                 }                                 
529         }                                         
530         snd_ice1712_restore_gpio_status(ice);     
531         return change;                            
532 }                                                 
533                                                   
534 /*                                                
535  * WM8770 mute control                            
536  */                                               
537 static int wm_mute_info(struct snd_kcontrol *k    
538                         struct snd_ctl_elem_in    
539         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOL    
540         uinfo->count = kcontrol->private_value    
541         uinfo->value.integer.min = 0;             
542         uinfo->value.integer.max = 1;             
543         return 0;                                 
544 }                                                 
545                                                   
546 static int wm_mute_get(struct snd_kcontrol *kc    
547                         struct snd_ctl_elem_va    
548 {                                                 
549         struct snd_ice1712 *ice = snd_kcontrol    
550         struct phase28_spec *spec = ice->spec;    
551         int voices, ofs, i;                       
552                                                   
553         voices = kcontrol->private_value >> 8;    
554         ofs = kcontrol->private_value & 0xFF;     
555                                                   
556         for (i = 0; i < voices; i++)              
557                 ucontrol->value.integer.value[    
558                         (spec->vol[ofs+i] & WM    
559         return 0;                                 
560 }                                                 
561                                                   
562 static int wm_mute_put(struct snd_kcontrol *kc    
563                         struct snd_ctl_elem_va    
564 {                                                 
565         struct snd_ice1712 *ice = snd_kcontrol    
566         struct phase28_spec *spec = ice->spec;    
567         int change = 0, voices, ofs, i;           
568                                                   
569         voices = kcontrol->private_value >> 8;    
570         ofs = kcontrol->private_value & 0xFF;     
571                                                   
572         snd_ice1712_save_gpio_status(ice);        
573         for (i = 0; i < voices; i++) {            
574                 int val = (spec->vol[ofs + i]     
575                 if (ucontrol->value.integer.va    
576                         spec->vol[ofs + i] &=     
577                         spec->vol[ofs + i] |=     
578                                 ucontrol->valu    
579                                 WM_VOL_MUTE;      
580                         wm_set_vol(ice, ofs +     
581                                         spec->    
582                         change = 1;               
583                 }                                 
584         }                                         
585         snd_ice1712_restore_gpio_status(ice);     
586                                                   
587         return change;                            
588 }                                                 
589                                                   
590 /*                                                
591  * WM8770 master mute control                     
592  */                                               
593 #define wm_master_mute_info             snd_ct    
594                                                   
595 static int wm_master_mute_get(struct snd_kcont    
596                                 struct snd_ctl    
597 {                                                 
598         struct snd_ice1712 *ice = snd_kcontrol    
599         struct phase28_spec *spec = ice->spec;    
600                                                   
601         ucontrol->value.integer.value[0] =        
602                 (spec->master[0] & WM_VOL_MUTE    
603         ucontrol->value.integer.value[1] =        
604                 (spec->master[1] & WM_VOL_MUTE    
605         return 0;                                 
606 }                                                 
607                                                   
608 static int wm_master_mute_put(struct snd_kcont    
609                                 struct snd_ctl    
610 {                                                 
611         struct snd_ice1712 *ice = snd_kcontrol    
612         struct phase28_spec *spec = ice->spec;    
613         int change = 0, i;                        
614                                                   
615         snd_ice1712_save_gpio_status(ice);        
616         for (i = 0; i < 2; i++) {                 
617                 int val = (spec->master[i] & W    
618                 if (ucontrol->value.integer.va    
619                         int dac;                  
620                         spec->master[i] &= ~WM    
621                         spec->master[i] |=        
622                                 ucontrol->valu    
623                                 WM_VOL_MUTE;      
624                         for (dac = 0; dac < ic    
625                                 wm_set_vol(ice    
626                                                   
627                                                   
628                         change = 1;               
629                 }                                 
630         }                                         
631         snd_ice1712_restore_gpio_status(ice);     
632                                                   
633         return change;                            
634 }                                                 
635                                                   
636 /* digital master volume */                       
637 #define PCM_0dB 0xff                              
638 #define PCM_RES 128     /* -64dB */               
639 #define PCM_MIN (PCM_0dB - PCM_RES)               
640 static int wm_pcm_vol_info(struct snd_kcontrol    
641                                 struct snd_ctl    
642 {                                                 
643         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTE    
644         uinfo->count = 1;                         
645         uinfo->value.integer.min = 0;             
646         uinfo->value.integer.max = PCM_RES;       
647         return 0;                                 
648 }                                                 
649                                                   
650 static int wm_pcm_vol_get(struct snd_kcontrol     
651                                 struct snd_ctl    
652 {                                                 
653         struct snd_ice1712 *ice = snd_kcontrol    
654         unsigned short val;                       
655                                                   
656         mutex_lock(&ice->gpio_mutex);             
657         val = wm_get(ice, WM_DAC_DIG_MASTER_AT    
658         val = val > PCM_MIN ? (val - PCM_MIN)     
659         ucontrol->value.integer.value[0] = val    
660         mutex_unlock(&ice->gpio_mutex);           
661         return 0;                                 
662 }                                                 
663                                                   
664 static int wm_pcm_vol_put(struct snd_kcontrol     
665                                 struct snd_ctl    
666 {                                                 
667         struct snd_ice1712 *ice = snd_kcontrol    
668         unsigned short ovol, nvol;                
669         int change = 0;                           
670                                                   
671         nvol = ucontrol->value.integer.value[0    
672         if (nvol > PCM_RES)                       
673                 return -EINVAL;                   
674         snd_ice1712_save_gpio_status(ice);        
675         nvol = (nvol ? (nvol + PCM_MIN) : 0) &    
676         ovol = wm_get(ice, WM_DAC_DIG_MASTER_A    
677         if (ovol != nvol) {                       
678                 wm_put(ice, WM_DAC_DIG_MASTER_    
679                 /* update */                      
680                 wm_put_nocache(ice, WM_DAC_DIG    
681                 change = 1;                       
682         }                                         
683         snd_ice1712_restore_gpio_status(ice);     
684         return change;                            
685 }                                                 
686                                                   
687 /*                                                
688  * Deemphasis                                     
689  */                                               
690 #define phase28_deemp_info      snd_ctl_boolea    
691                                                   
692 static int phase28_deemp_get(struct snd_kcontr    
693                                 struct snd_ctl    
694 {                                                 
695         struct snd_ice1712 *ice = snd_kcontrol    
696         ucontrol->value.integer.value[0] = (wm    
697                                                   
698         return 0;                                 
699 }                                                 
700                                                   
701 static int phase28_deemp_put(struct snd_kcontr    
702                                 struct snd_ctl    
703 {                                                 
704         struct snd_ice1712 *ice = snd_kcontrol    
705         int temp, temp2;                          
706         temp = wm_get(ice, WM_DAC_CTRL2);         
707         temp2 = temp;                             
708         if (ucontrol->value.integer.value[0])     
709                 temp |= 0xf;                      
710         else                                      
711                 temp &= ~0xf;                     
712         if (temp != temp2) {                      
713                 wm_put(ice, WM_DAC_CTRL2, temp    
714                 return 1;                         
715         }                                         
716         return 0;                                 
717 }                                                 
718                                                   
719 /*                                                
720  * ADC Oversampling                               
721  */                                               
722 static int phase28_oversampling_info(struct sn    
723                                         struct    
724 {                                                 
725         static char *texts[2] = { "128x", "64x    
726                                                   
727         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUM    
728         uinfo->count = 1;                         
729         uinfo->value.enumerated.items = 2;        
730                                                   
731         if (uinfo->value.enumerated.item >= ui    
732                 uinfo->value.enumerated.item =    
733                                                   
734         strcpy(uinfo->value.enumerated.name,      
735                 texts[uinfo->value.enumerated.    
736                                                   
737         return 0;                                 
738 }                                                 
739                                                   
740 static int phase28_oversampling_get(struct snd    
741                                         struct    
742 {                                                 
743         struct snd_ice1712 *ice = snd_kcontrol    
744         ucontrol->value.enumerated.item[0] = (    
745                                                   
746         return 0;                                 
747 }                                                 
748                                                   
749 static int phase28_oversampling_put(struct snd    
750                                         struct    
751 {                                                 
752         int temp, temp2;                          
753         struct snd_ice1712 *ice = snd_kcontrol    
754                                                   
755         temp = wm_get(ice, WM_MASTER);            
756         temp2 = temp;                             
757                                                   
758         if (ucontrol->value.enumerated.item[0]    
759                 temp |= 0x8;                      
760         else                                      
761                 temp &= ~0x8;                     
762                                                   
763         if (temp != temp2) {                      
764                 wm_put(ice, WM_MASTER, temp);     
765                 return 1;                         
766         }                                         
767         return 0;                                 
768 }                                                 
769                                                   
770 static const DECLARE_TLV_DB_SCALE(db_scale_wm_    
771 static const DECLARE_TLV_DB_SCALE(db_scale_wm_    
772                                                   
773 static struct snd_kcontrol_new phase28_dac_con    
774         {                                         
775                 .iface = SNDRV_CTL_ELEM_IFACE_    
776                 .name = "Master Playback Switc    
777                 .info = wm_master_mute_info,      
778                 .get = wm_master_mute_get,        
779                 .put = wm_master_mute_put         
780         },                                        
781         {                                         
782                 .iface = SNDRV_CTL_ELEM_IFACE_    
783                 .access = (SNDRV_CTL_ELEM_ACCE    
784                            SNDRV_CTL_ELEM_ACCE    
785                 .name = "Master Playback Volum    
786                 .info = wm_master_vol_info,       
787                 .get = wm_master_vol_get,         
788                 .put = wm_master_vol_put,         
789                 .tlv = { .p = db_scale_wm_dac     
790         },                                        
791         {                                         
792                 .iface = SNDRV_CTL_ELEM_IFACE_    
793                 .name = "Front Playback Switch    
794                 .info = wm_mute_info,             
795                 .get = wm_mute_get,               
796                 .put = wm_mute_put,               
797                 .private_value = (2 << 8) | 0     
798         },                                        
799         {                                         
800                 .iface = SNDRV_CTL_ELEM_IFACE_    
801                 .access = (SNDRV_CTL_ELEM_ACCE    
802                            SNDRV_CTL_ELEM_ACCE    
803                 .name = "Front Playback Volume    
804                 .info = wm_vol_info,              
805                 .get = wm_vol_get,                
806                 .put = wm_vol_put,                
807                 .private_value = (2 << 8) | 0,    
808                 .tlv = { .p = db_scale_wm_dac     
809         },                                        
810         {                                         
811                 .iface = SNDRV_CTL_ELEM_IFACE_    
812                 .name = "Rear Playback Switch"    
813                 .info = wm_mute_info,             
814                 .get = wm_mute_get,               
815                 .put = wm_mute_put,               
816                 .private_value = (2 << 8) | 2     
817         },                                        
818         {                                         
819                 .iface = SNDRV_CTL_ELEM_IFACE_    
820                 .access = (SNDRV_CTL_ELEM_ACCE    
821                            SNDRV_CTL_ELEM_ACCE    
822                 .name = "Rear Playback Volume"    
823                 .info = wm_vol_info,              
824                 .get = wm_vol_get,                
825                 .put = wm_vol_put,                
826                 .private_value = (2 << 8) | 2,    
827                 .tlv = { .p = db_scale_wm_dac     
828         },                                        
829         {                                         
830                 .iface = SNDRV_CTL_ELEM_IFACE_    
831                 .name = "Center Playback Switc    
832                 .info = wm_mute_info,             
833                 .get = wm_mute_get,               
834                 .put = wm_mute_put,               
835                 .private_value = (1 << 8) | 4     
836         },                                        
837         {                                         
838                 .iface = SNDRV_CTL_ELEM_IFACE_    
839                 .access = (SNDRV_CTL_ELEM_ACCE    
840                            SNDRV_CTL_ELEM_ACCE    
841                 .name = "Center Playback Volum    
842                 .info = wm_vol_info,              
843                 .get = wm_vol_get,                
844                 .put = wm_vol_put,                
845                 .private_value = (1 << 8) | 4,    
846                 .tlv = { .p = db_scale_wm_dac     
847         },                                        
848         {                                         
849                 .iface = SNDRV_CTL_ELEM_IFACE_    
850                 .name = "LFE Playback Switch",    
851                 .info = wm_mute_info,             
852                 .get = wm_mute_get,               
853                 .put = wm_mute_put,               
854                 .private_value = (1 << 8) | 5     
855         },                                        
856         {                                         
857                 .iface = SNDRV_CTL_ELEM_IFACE_    
858                 .access = (SNDRV_CTL_ELEM_ACCE    
859                            SNDRV_CTL_ELEM_ACCE    
860                 .name = "LFE Playback Volume",    
861                 .info = wm_vol_info,              
862                 .get = wm_vol_get,                
863                 .put = wm_vol_put,                
864                 .private_value = (1 << 8) | 5,    
865                 .tlv = { .p = db_scale_wm_dac     
866         },                                        
867         {                                         
868                 .iface = SNDRV_CTL_ELEM_IFACE_    
869                 .name = "Side Playback Switch"    
870                 .info = wm_mute_info,             
871                 .get = wm_mute_get,               
872                 .put = wm_mute_put,               
873                 .private_value = (2 << 8) | 6     
874         },                                        
875         {                                         
876                 .iface = SNDRV_CTL_ELEM_IFACE_    
877                 .access = (SNDRV_CTL_ELEM_ACCE    
878                            SNDRV_CTL_ELEM_ACCE    
879                 .name = "Side Playback Volume"    
880                 .info = wm_vol_info,              
881                 .get = wm_vol_get,                
882                 .put = wm_vol_put,                
883                 .private_value = (2 << 8) | 6,    
884                 .tlv = { .p = db_scale_wm_dac     
885         }                                         
886 };                                                
887                                                   
888 static struct snd_kcontrol_new wm_controls[] _    
889         {                                         
890                 .iface = SNDRV_CTL_ELEM_IFACE_    
891                 .name = "PCM Playback Switch",    
892                 .info = wm_pcm_mute_info,         
893                 .get = wm_pcm_mute_get,           
894                 .put = wm_pcm_mute_put            
895         },                                        
896         {                                         
897                 .iface = SNDRV_CTL_ELEM_IFACE_    
898                 .access = (SNDRV_CTL_ELEM_ACCE    
899                            SNDRV_CTL_ELEM_ACCE    
900                 .name = "PCM Playback Volume",    
901                 .info = wm_pcm_vol_info,          
902                 .get = wm_pcm_vol_get,            
903                 .put = wm_pcm_vol_put,            
904                 .tlv = { .p = db_scale_wm_pcm     
905         },                                        
906         {                                         
907                 .iface = SNDRV_CTL_ELEM_IFACE_    
908                 .name = "DAC Deemphasis Switch    
909                 .info = phase28_deemp_info,       
910                 .get = phase28_deemp_get,         
911                 .put = phase28_deemp_put          
912         },                                        
913         {                                         
914                 .iface = SNDRV_CTL_ELEM_IFACE_    
915                 .name = "ADC Oversampling",       
916                 .info = phase28_oversampling_i    
917                 .get = phase28_oversampling_ge    
918                 .put = phase28_oversampling_pu    
919         }                                         
920 };                                                
921                                                   
922 static int __devinit phase28_add_controls(stru    
923 {                                                 
924         unsigned int i, counts;                   
925         int err;                                  
926                                                   
927         counts = ARRAY_SIZE(phase28_dac_contro    
928         for (i = 0; i < counts; i++) {            
929                 err = snd_ctl_add(ice->card,      
930                                         snd_ct    
931                                                   
932                 if (err < 0)                      
933                         return err;               
934         }                                         
935                                                   
936         for (i = 0; i < ARRAY_SIZE(wm_controls    
937                 err = snd_ctl_add(ice->card,      
938                                         snd_ct    
939                 if (err < 0)                      
940                         return err;               
941         }                                         
942                                                   
943         return 0;                                 
944 }                                                 
945                                                   
946 struct snd_ice1712_card_info snd_vt1724_phase_    
947         {                                         
948                 .subvendor = VT1724_SUBDEVICE_    
949                 .name = "Terratec PHASE 22",      
950                 .model = "phase22",               
951                 .chip_init = phase22_init,        
952                 .build_controls = phase22_add_    
953                 .eeprom_size = sizeof(phase22_    
954                 .eeprom_data = phase22_eeprom,    
955         },                                        
956         {                                         
957                 .subvendor = VT1724_SUBDEVICE_    
958                 .name = "Terratec PHASE 28",      
959                 .model = "phase28",               
960                 .chip_init = phase28_init,        
961                 .build_controls = phase28_add_    
962                 .eeprom_size = sizeof(phase28_    
963                 .eeprom_data = phase28_eeprom,    
964         },                                        
965         {                                         
966                 .subvendor = VT1724_SUBDEVICE_    
967                 .name = "Terrasoniq TS22 PCI",    
968                 .model = "TS22",                  
969                 .chip_init = phase22_init,        
970                 .build_controls = phase22_add_    
971                 .eeprom_size = sizeof(phase22_    
972                 .eeprom_data = phase22_eeprom,    
973         },                                        
974         { } /* terminator */                      
975 };                                                
976                                                   
  This page was automatically generated by the LXR engine.