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/soc/codecs/tlv320aic3x.c (Version 2.6.25.8) and /linux/sound/soc/codecs/tlv320aic3x.c (Version 2.6.11.8)


  1 /*                                                  1 
  2  * ALSA SoC TLV320AIC3X codec driver              
  3  *                                                
  4  * Author:      Vladimir Barinov, <vbarinov@ru    
  5  * Copyright:   (C) 2007 MontaVista Software,     
  6  *                                                
  7  * Based on sound/soc/codecs/wm8753.c by Liam     
  8  *                                                
  9  * This program is free software; you can redi    
 10  * it under the terms of the GNU General Publi    
 11  * published by the Free Software Foundation.     
 12  *                                                
 13  * Notes:                                         
 14  *  The AIC3X is a driver for a low power ster    
 15  *  codecs aic31, aic32, aic33.                   
 16  *                                                
 17  *  It supports full aic33 codec functionality    
 18  *  The compatibility with aic32, aic31 is as     
 19  *        aic32        |        aic31             
 20  *  ---------------------------------------       
 21  *   MONO_LOUT -> N/A  |  MONO_LOUT -> N/A        
 22  *                     |  IN1L -> LINE1L          
 23  *                     |  IN1R -> LINE1R          
 24  *                     |  IN2L -> LINE2L          
 25  *                     |  IN2R -> LINE2R          
 26  *                     |  MIC3L/R -> N/A          
 27  *   truncated internal functionality in          
 28  *   accordance with documentation                
 29  *  ---------------------------------------       
 30  *                                                
 31  *  Hence the machine layer should disable uns    
 32  *  snd_soc_dapm_set_endpoint(codec, "MONO_LOU    
 33  */                                               
 34                                                   
 35 #include <linux/module.h>                         
 36 #include <linux/moduleparam.h>                    
 37 #include <linux/init.h>                           
 38 #include <linux/delay.h>                          
 39 #include <linux/pm.h>                             
 40 #include <linux/i2c.h>                            
 41 #include <linux/platform_device.h>                
 42 #include <sound/core.h>                           
 43 #include <sound/pcm.h>                            
 44 #include <sound/pcm_params.h>                     
 45 #include <sound/soc.h>                            
 46 #include <sound/soc-dapm.h>                       
 47 #include <sound/initval.h>                        
 48                                                   
 49 #include "tlv320aic3x.h"                          
 50                                                   
 51 #define AUDIO_NAME "aic3x"                        
 52 #define AIC3X_VERSION "0.1"                       
 53                                                   
 54 /* codec private data */                          
 55 struct aic3x_priv {                               
 56         unsigned int sysclk;                      
 57         int master;                               
 58 };                                                
 59                                                   
 60 /*                                                
 61  * AIC3X register cache                           
 62  * We can't read the AIC3X register space when    
 63  * using 2 wire for device control, so we cach    
 64  * There is no point in caching the reset regi    
 65  */                                               
 66 static const u8 aic3x_reg[AIC3X_CACHEREGNUM] =    
 67         0x00, 0x00, 0x00, 0x10, /* 0 */           
 68         0x04, 0x00, 0x00, 0x00, /* 4 */           
 69         0x00, 0x00, 0x00, 0x01, /* 8 */           
 70         0x00, 0x00, 0x00, 0x80, /* 12 */          
 71         0x80, 0xff, 0xff, 0x78, /* 16 */          
 72         0x78, 0x78, 0x78, 0x78, /* 20 */          
 73         0x78, 0x00, 0x00, 0xfe, /* 24 */          
 74         0x00, 0x00, 0xfe, 0x00, /* 28 */          
 75         0x18, 0x18, 0x00, 0x00, /* 32 */          
 76         0x00, 0x00, 0x00, 0x00, /* 36 */          
 77         0x00, 0x00, 0x00, 0x80, /* 40 */          
 78         0x80, 0x00, 0x00, 0x00, /* 44 */          
 79         0x00, 0x00, 0x00, 0x04, /* 48 */          
 80         0x00, 0x00, 0x00, 0x00, /* 52 */          
 81         0x00, 0x00, 0x04, 0x00, /* 56 */          
 82         0x00, 0x00, 0x00, 0x00, /* 60 */          
 83         0x00, 0x04, 0x00, 0x00, /* 64 */          
 84         0x00, 0x00, 0x00, 0x00, /* 68 */          
 85         0x04, 0x00, 0x00, 0x00, /* 72 */          
 86         0x00, 0x00, 0x00, 0x00, /* 76 */          
 87         0x00, 0x00, 0x00, 0x00, /* 80 */          
 88         0x00, 0x00, 0x00, 0x00, /* 84 */          
 89         0x00, 0x00, 0x00, 0x00, /* 88 */          
 90         0x00, 0x00, 0x00, 0x00, /* 92 */          
 91         0x00, 0x00, 0x00, 0x00, /* 96 */          
 92         0x00, 0x00, 0x02,       /* 100 */         
 93 };                                                
 94                                                   
 95 /*                                                
 96  * read aic3x register cache                      
 97  */                                               
 98 static inline unsigned int aic3x_read_reg_cach    
 99                                                   
100 {                                                 
101         u8 *cache = codec->reg_cache;             
102         if (reg >= AIC3X_CACHEREGNUM)             
103                 return -1;                        
104         return cache[reg];                        
105 }                                                 
106                                                   
107 /*                                                
108  * write aic3x register cache                     
109  */                                               
110 static inline void aic3x_write_reg_cache(struc    
111                                          u8 re    
112 {                                                 
113         u8 *cache = codec->reg_cache;             
114         if (reg >= AIC3X_CACHEREGNUM)             
115                 return;                           
116         cache[reg] = value;                       
117 }                                                 
118                                                   
119 /*                                                
120  * write to the aic3x register space              
121  */                                               
122 static int aic3x_write(struct snd_soc_codec *c    
123                        unsigned int value)        
124 {                                                 
125         u8 data[2];                               
126                                                   
127         /* data is                                
128          *   D15..D8 aic3x register offset        
129          *   D7...D0 register data                
130          */                                       
131         data[0] = reg & 0xff;                     
132         data[1] = value & 0xff;                   
133                                                   
134         aic3x_write_reg_cache(codec, data[0],     
135         if (codec->hw_write(codec->control_dat    
136                 return 0;                         
137         else                                      
138                 return -EIO;                      
139 }                                                 
140                                                   
141 #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shif    
142 {       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .    
143         .info = snd_soc_info_volsw, \             
144         .get = snd_soc_dapm_get_volsw, .put =     
145         .private_value =  SOC_SINGLE_VALUE(reg    
146                                                   
147 /*                                                
148  * All input lines are connected when !0xf and    
149  * so we have to use specific dapm_put call fo    
150  */                                               
151 static int snd_soc_dapm_put_volsw_aic3x(struct    
152                                         struct    
153 {                                                 
154         struct snd_soc_dapm_widget *widget = s    
155         int reg = kcontrol->private_value & 0x    
156         int shift = (kcontrol->private_value >    
157         int mask = (kcontrol->private_value >>    
158         int invert = (kcontrol->private_value     
159         unsigned short val, val_mask;             
160         int ret;                                  
161         struct snd_soc_dapm_path *path;           
162         int found = 0;                            
163                                                   
164         val = (ucontrol->value.integer.value[0    
165                                                   
166         mask = 0xf;                               
167         if (val)                                  
168                 val = mask;                       
169                                                   
170         if (invert)                               
171                 val = mask - val;                 
172         val_mask = mask << shift;                 
173         val = val << shift;                       
174                                                   
175         mutex_lock(&widget->codec->mutex);        
176                                                   
177         if (snd_soc_test_bits(widget->codec, r    
178                 /* find dapm widget path assoc    
179                 list_for_each_entry(path, &wid    
180                         if (path->kcontrol !=     
181                                 continue;         
182                                                   
183                         /* found, now check ty    
184                         found = 1;                
185                         if (val)                  
186                                 /* new connect    
187                                 path->connect     
188                         else                      
189                                 /* old connect    
190                                 path->connect     
191                         break;                    
192                 }                                 
193                                                   
194                 if (found)                        
195                         snd_soc_dapm_sync_endp    
196         }                                         
197                                                   
198         ret = snd_soc_update_bits(widget->code    
199                                                   
200         mutex_unlock(&widget->codec->mutex);      
201         return ret;                               
202 }                                                 
203                                                   
204 static const char *aic3x_left_dac_mux[] = { "D    
205 static const char *aic3x_right_dac_mux[] = { "    
206 static const char *aic3x_left_hpcom_mux[] =       
207     { "differential of HPLOUT", "constant VCM"    
208 static const char *aic3x_right_hpcom_mux[] =      
209     { "differential of HPROUT", "constant VCM"    
210       "differential of HPLCOM", "external feed    
211 static const char *aic3x_linein_mode_mux[] = {    
212                                                   
213 #define LDAC_ENUM       0                         
214 #define RDAC_ENUM       1                         
215 #define LHPCOM_ENUM     2                         
216 #define RHPCOM_ENUM     3                         
217 #define LINE1L_ENUM     4                         
218 #define LINE1R_ENUM     5                         
219 #define LINE2L_ENUM     6                         
220 #define LINE2R_ENUM     7                         
221                                                   
222 static const struct soc_enum aic3x_enum[] = {     
223         SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, ai    
224         SOC_ENUM_SINGLE(DAC_LINE_MUX, 4, 3, ai    
225         SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3    
226         SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3    
227         SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7,    
228         SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7,    
229         SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7,    
230         SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7,    
231 };                                                
232                                                   
233 static const struct snd_kcontrol_new aic3x_snd    
234         /* Output */                              
235         SOC_DOUBLE_R("PCM Playback Volume", LD    
236                                                   
237         SOC_DOUBLE_R("Line DAC Playback Volume    
238                      DACR1_2_RLOPM_VOL, 0, 0x7    
239         SOC_DOUBLE_R("Line DAC Playback Switch    
240                      0x01, 0),                    
241         SOC_DOUBLE_R("Line PGA Bypass Playback    
242                      PGAR_2_RLOPM_VOL, 0, 0x7f    
243         SOC_DOUBLE_R("Line Line2 Bypass Playba    
244                      LINE2R_2_RLOPM_VOL, 0, 0x    
245                                                   
246         SOC_DOUBLE_R("Mono DAC Playback Volume    
247                      DACR1_2_MONOLOPM_VOL, 0,     
248         SOC_SINGLE("Mono DAC Playback Switch",    
249         SOC_DOUBLE_R("Mono PGA Bypass Playback    
250                      PGAR_2_MONOLOPM_VOL, 0, 0    
251         SOC_DOUBLE_R("Mono Line2 Bypass Playba    
252                      LINE2R_2_MONOLOPM_VOL, 0,    
253                                                   
254         SOC_DOUBLE_R("HP DAC Playback Volume",    
255                      DACR1_2_HPROUT_VOL, 0, 0x    
256         SOC_DOUBLE_R("HP DAC Playback Switch",    
257                      0x01, 0),                    
258         SOC_DOUBLE_R("HP PGA Bypass Playback V    
259                      PGAR_2_HPROUT_VOL, 0, 0x7    
260         SOC_DOUBLE_R("HP Line2 Bypass Playback    
261                      LINE2R_2_HPROUT_VOL, 0, 0    
262                                                   
263         SOC_DOUBLE_R("HPCOM DAC Playback Volum    
264                      DACR1_2_HPRCOM_VOL, 0, 0x    
265         SOC_DOUBLE_R("HPCOM DAC Playback Switc    
266                      0x01, 0),                    
267         SOC_DOUBLE_R("HPCOM PGA Bypass Playbac    
268                      PGAR_2_HPRCOM_VOL, 0, 0x7    
269         SOC_DOUBLE_R("HPCOM Line2 Bypass Playb    
270                      LINE2R_2_HPRCOM_VOL, 0, 0    
271                                                   
272         /*                                        
273          * Note: enable Automatic input Gain C    
274          * adjust PGA to max value when ADC is    
275         */                                        
276         SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A    
277                                                   
278         /* Input */                               
279         SOC_DOUBLE_R("PGA Capture Volume", LAD    
280         SOC_DOUBLE_R("PGA Capture Switch", LAD    
281 };                                                
282                                                   
283 /* add non dapm controls */                       
284 static int aic3x_add_controls(struct snd_soc_c    
285 {                                                 
286         int err, i;                               
287                                                   
288         for (i = 0; i < ARRAY_SIZE(aic3x_snd_c    
289                 err = snd_ctl_add(codec->card,    
290                                   snd_soc_cnew    
291                                                   
292                 if (err < 0)                      
293                         return err;               
294         }                                         
295                                                   
296         return 0;                                 
297 }                                                 
298                                                   
299 /* Left DAC Mux */                                
300 static const struct snd_kcontrol_new aic3x_lef    
301 SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]);    
302                                                   
303 /* Right DAC Mux */                               
304 static const struct snd_kcontrol_new aic3x_rig    
305 SOC_DAPM_ENUM("Route", aic3x_enum[RDAC_ENUM]);    
306                                                   
307 /* Left HPCOM Mux */                              
308 static const struct snd_kcontrol_new aic3x_lef    
309 SOC_DAPM_ENUM("Route", aic3x_enum[LHPCOM_ENUM]    
310                                                   
311 /* Right HPCOM Mux */                             
312 static const struct snd_kcontrol_new aic3x_rig    
313 SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]    
314                                                   
315 /* Left DAC_L1 Mixer */                           
316 static const struct snd_kcontrol_new aic3x_lef    
317         SOC_DAPM_SINGLE("Line Switch", DACL1_2    
318         SOC_DAPM_SINGLE("Mono Switch", DACL1_2    
319         SOC_DAPM_SINGLE("HP Switch", DACL1_2_H    
320         SOC_DAPM_SINGLE("HPCOM Switch", DACL1_    
321 };                                                
322                                                   
323 /* Right DAC_R1 Mixer */                          
324 static const struct snd_kcontrol_new aic3x_rig    
325         SOC_DAPM_SINGLE("Line Switch", DACR1_2    
326         SOC_DAPM_SINGLE("Mono Switch", DACR1_2    
327         SOC_DAPM_SINGLE("HP Switch", DACR1_2_H    
328         SOC_DAPM_SINGLE("HPCOM Switch", DACR1_    
329 };                                                
330                                                   
331 /* Left PGA Mixer */                              
332 static const struct snd_kcontrol_new aic3x_lef    
333         SOC_DAPM_SINGLE_AIC3X("Line1L Switch",    
334         SOC_DAPM_SINGLE_AIC3X("Line2L Switch",    
335         SOC_DAPM_SINGLE_AIC3X("Mic3L Switch",     
336 };                                                
337                                                   
338 /* Right PGA Mixer */                             
339 static const struct snd_kcontrol_new aic3x_rig    
340         SOC_DAPM_SINGLE_AIC3X("Line1R Switch",    
341         SOC_DAPM_SINGLE_AIC3X("Line2R Switch",    
342         SOC_DAPM_SINGLE_AIC3X("Mic3R Switch",     
343 };                                                
344                                                   
345 /* Left Line1 Mux */                              
346 static const struct snd_kcontrol_new aic3x_lef    
347 SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_ENUM]    
348                                                   
349 /* Right Line1 Mux */                             
350 static const struct snd_kcontrol_new aic3x_rig    
351 SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_ENUM]    
352                                                   
353 /* Left Line2 Mux */                              
354 static const struct snd_kcontrol_new aic3x_lef    
355 SOC_DAPM_ENUM("Route", aic3x_enum[LINE2L_ENUM]    
356                                                   
357 /* Right Line2 Mux */                             
358 static const struct snd_kcontrol_new aic3x_rig    
359 SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]    
360                                                   
361 /* Left PGA Bypass Mixer */                       
362 static const struct snd_kcontrol_new aic3x_lef    
363         SOC_DAPM_SINGLE("Line Switch", PGAL_2_    
364         SOC_DAPM_SINGLE("Mono Switch", PGAL_2_    
365         SOC_DAPM_SINGLE("HP Switch", PGAL_2_HP    
366         SOC_DAPM_SINGLE("HPCOM Switch", PGAL_2    
367 };                                                
368                                                   
369 /* Right PGA Bypass Mixer */                      
370 static const struct snd_kcontrol_new aic3x_rig    
371         SOC_DAPM_SINGLE("Line Switch", PGAR_2_    
372         SOC_DAPM_SINGLE("Mono Switch", PGAR_2_    
373         SOC_DAPM_SINGLE("HP Switch", PGAR_2_HP    
374         SOC_DAPM_SINGLE("HPCOM Switch", PGAR_2    
375 };                                                
376                                                   
377 /* Left Line2 Bypass Mixer */                     
378 static const struct snd_kcontrol_new aic3x_lef    
379         SOC_DAPM_SINGLE("Line Switch", LINE2L_    
380         SOC_DAPM_SINGLE("Mono Switch", LINE2L_    
381         SOC_DAPM_SINGLE("HP Switch", LINE2L_2_    
382         SOC_DAPM_SINGLE("HPCOM Switch", LINE2L    
383 };                                                
384                                                   
385 /* Right Line2 Bypass Mixer */                    
386 static const struct snd_kcontrol_new aic3x_rig    
387         SOC_DAPM_SINGLE("Line Switch", LINE2R_    
388         SOC_DAPM_SINGLE("Mono Switch", LINE2R_    
389         SOC_DAPM_SINGLE("HP Switch", LINE2R_2_    
390         SOC_DAPM_SINGLE("HPCOM Switch", LINE2R    
391 };                                                
392                                                   
393 static const struct snd_soc_dapm_widget aic3x_    
394         /* Left DAC to Left Outputs */            
395         SND_SOC_DAPM_DAC("Left DAC", "Left Pla    
396         SND_SOC_DAPM_MUX("Left DAC Mux", SND_S    
397                          &aic3x_left_dac_mux_c    
398         SND_SOC_DAPM_MIXER("Left DAC_L1 Mixer"    
399                            &aic3x_left_dac_mix    
400                            ARRAY_SIZE(aic3x_le    
401         SND_SOC_DAPM_MUX("Left HPCOM Mux", SND    
402                          &aic3x_left_hpcom_mux    
403         SND_SOC_DAPM_PGA("Left Line Out", LLOP    
404         SND_SOC_DAPM_PGA("Left HP Out", HPLOUT    
405         SND_SOC_DAPM_PGA("Left HP Com", HPLCOM    
406                                                   
407         /* Right DAC to Right Outputs */          
408         SND_SOC_DAPM_DAC("Right DAC", "Right P    
409         SND_SOC_DAPM_MUX("Right DAC Mux", SND_    
410                          &aic3x_right_dac_mux_    
411         SND_SOC_DAPM_MIXER("Right DAC_R1 Mixer    
412                            &aic3x_right_dac_mi    
413                            ARRAY_SIZE(aic3x_ri    
414         SND_SOC_DAPM_MUX("Right HPCOM Mux", SN    
415                          &aic3x_right_hpcom_mu    
416         SND_SOC_DAPM_PGA("Right Line Out", RLO    
417         SND_SOC_DAPM_PGA("Right HP Out", HPROU    
418         SND_SOC_DAPM_PGA("Right HP Com", HPRCO    
419                                                   
420         /* Mono Output */                         
421         SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_    
422                                                   
423         /* Left Inputs to Left ADC */             
424         SND_SOC_DAPM_ADC("Left ADC", "Left Cap    
425         SND_SOC_DAPM_MIXER("Left PGA Mixer", S    
426                            &aic3x_left_pga_mix    
427                            ARRAY_SIZE(aic3x_le    
428         SND_SOC_DAPM_MUX("Left Line1L Mux", SN    
429                          &aic3x_left_line1_mux    
430         SND_SOC_DAPM_MUX("Left Line2L Mux", SN    
431                          &aic3x_left_line2_mux    
432                                                   
433         /* Right Inputs to Right ADC */           
434         SND_SOC_DAPM_ADC("Right ADC", "Right C    
435                          LINE1R_2_RADC_CTRL, 2    
436         SND_SOC_DAPM_MIXER("Right PGA Mixer",     
437                            &aic3x_right_pga_mi    
438                            ARRAY_SIZE(aic3x_ri    
439         SND_SOC_DAPM_MUX("Right Line1R Mux", S    
440                          &aic3x_right_line1_mu    
441         SND_SOC_DAPM_MUX("Right Line2R Mux", S    
442                          &aic3x_right_line2_mu    
443                                                   
444         /* Mic Bias */                            
445         SND_SOC_DAPM_MICBIAS("Mic Bias 2V", MI    
446         SND_SOC_DAPM_MICBIAS("Mic Bias 2.5V",     
447         SND_SOC_DAPM_MICBIAS("Mic Bias AVDD",     
448         SND_SOC_DAPM_MICBIAS("Mic Bias AVDD",     
449                                                   
450         /* Left PGA to Left Output bypass */      
451         SND_SOC_DAPM_MIXER("Left PGA Bypass Mi    
452                            &aic3x_left_pga_bp_    
453                            ARRAY_SIZE(aic3x_le    
454                                                   
455         /* Right PGA to Right Output bypass */    
456         SND_SOC_DAPM_MIXER("Right PGA Bypass M    
457                            &aic3x_right_pga_bp    
458                            ARRAY_SIZE(aic3x_ri    
459                                                   
460         /* Left Line2 to Left Output bypass */    
461         SND_SOC_DAPM_MIXER("Left Line2 Bypass     
462                            &aic3x_left_line2_b    
463                            ARRAY_SIZE(aic3x_le    
464                                                   
465         /* Right Line2 to Right Output bypass     
466         SND_SOC_DAPM_MIXER("Right Line2 Bypass    
467                            &aic3x_right_line2_    
468                            ARRAY_SIZE(aic3x_ri    
469                                                   
470         SND_SOC_DAPM_OUTPUT("LLOUT"),             
471         SND_SOC_DAPM_OUTPUT("RLOUT"),             
472         SND_SOC_DAPM_OUTPUT("MONO_LOUT"),         
473         SND_SOC_DAPM_OUTPUT("HPLOUT"),            
474         SND_SOC_DAPM_OUTPUT("HPROUT"),            
475         SND_SOC_DAPM_OUTPUT("HPLCOM"),            
476         SND_SOC_DAPM_OUTPUT("HPRCOM"),            
477                                                   
478         SND_SOC_DAPM_INPUT("MIC3L"),              
479         SND_SOC_DAPM_INPUT("MIC3R"),              
480         SND_SOC_DAPM_INPUT("LINE1L"),             
481         SND_SOC_DAPM_INPUT("LINE1R"),             
482         SND_SOC_DAPM_INPUT("LINE2L"),             
483         SND_SOC_DAPM_INPUT("LINE2R"),             
484 };                                                
485                                                   
486 static const char *intercon[][3] = {              
487         /* Left Output */                         
488         {"Left DAC Mux", "DAC_L1", "Left DAC"}    
489         {"Left DAC Mux", "DAC_L2", "Left DAC"}    
490         {"Left DAC Mux", "DAC_L3", "Left DAC"}    
491                                                   
492         {"Left DAC_L1 Mixer", "Line Switch", "    
493         {"Left DAC_L1 Mixer", "Mono Switch", "    
494         {"Left DAC_L1 Mixer", "HP Switch", "Le    
495         {"Left DAC_L1 Mixer", "HPCOM Switch",     
496         {"Left Line Out", NULL, "Left DAC Mux"    
497         {"Left HP Out", NULL, "Left DAC Mux"},    
498                                                   
499         {"Left HPCOM Mux", "differential of HP    
500         {"Left HPCOM Mux", "constant VCM", "Le    
501         {"Left HPCOM Mux", "single-ended", "Le    
502                                                   
503         {"Left Line Out", NULL, "Left DAC_L1 M    
504         {"Mono Out", NULL, "Left DAC_L1 Mixer"    
505         {"Left HP Out", NULL, "Left DAC_L1 Mix    
506         {"Left HP Com", NULL, "Left HPCOM Mux"    
507                                                   
508         {"LLOUT", NULL, "Left Line Out"},         
509         {"LLOUT", NULL, "Left Line Out"},         
510         {"HPLOUT", NULL, "Left HP Out"},          
511         {"HPLCOM", NULL, "Left HP Com"},          
512                                                   
513         /* Right Output */                        
514         {"Right DAC Mux", "DAC_R1", "Right DAC    
515         {"Right DAC Mux", "DAC_R2", "Right DAC    
516         {"Right DAC Mux", "DAC_R3", "Right DAC    
517                                                   
518         {"Right DAC_R1 Mixer", "Line Switch",     
519         {"Right DAC_R1 Mixer", "Mono Switch",     
520         {"Right DAC_R1 Mixer", "HP Switch", "R    
521         {"Right DAC_R1 Mixer", "HPCOM Switch",    
522         {"Right Line Out", NULL, "Right DAC Mu    
523         {"Right HP Out", NULL, "Right DAC Mux"    
524                                                   
525         {"Right HPCOM Mux", "differential of H    
526         {"Right HPCOM Mux", "constant VCM", "R    
527         {"Right HPCOM Mux", "single-ended", "R    
528         {"Right HPCOM Mux", "differential of H    
529         {"Right HPCOM Mux", "external feedback    
530                                                   
531         {"Right Line Out", NULL, "Right DAC_R1    
532         {"Mono Out", NULL, "Right DAC_R1 Mixer    
533         {"Right HP Out", NULL, "Right DAC_R1 M    
534         {"Right HP Com", NULL, "Right HPCOM Mu    
535                                                   
536         {"RLOUT", NULL, "Right Line Out"},        
537         {"RLOUT", NULL, "Right Line Out"},        
538         {"HPROUT", NULL, "Right HP Out"},         
539         {"HPRCOM", NULL, "Right HP Com"},         
540                                                   
541         /* Mono Output */                         
542         {"MONOLOUT", NULL, "Mono Out"},           
543         {"MONOLOUT", NULL, "Mono Out"},           
544                                                   
545         /* Left Input */                          
546         {"Left Line1L Mux", "single-ended", "L    
547         {"Left Line1L Mux", "differential", "L    
548                                                   
549         {"Left Line2L Mux", "single-ended", "L    
550         {"Left Line2L Mux", "differential", "L    
551                                                   
552         {"Left PGA Mixer", "Line1L Switch", "L    
553         {"Left PGA Mixer", "Line2L Switch", "L    
554         {"Left PGA Mixer", "Mic3L Switch", "MI    
555                                                   
556         {"Left ADC", NULL, "Left PGA Mixer"},     
557                                                   
558         /* Right Input */                         
559         {"Right Line1R Mux", "single-ended", "    
560         {"Right Line1R Mux", "differential", "    
561                                                   
562         {"Right Line2R Mux", "single-ended", "    
563         {"Right Line2R Mux", "differential", "    
564                                                   
565         {"Right PGA Mixer", "Line1R Switch", "    
566         {"Right PGA Mixer", "Line2R Switch", "    
567         {"Right PGA Mixer", "Mic3R Switch", "M    
568                                                   
569         {"Right ADC", NULL, "Right PGA Mixer"}    
570                                                   
571         /* Left PGA Bypass */                     
572         {"Left PGA Bypass Mixer", "Line Switch    
573         {"Left PGA Bypass Mixer", "Mono Switch    
574         {"Left PGA Bypass Mixer", "HP Switch",    
575         {"Left PGA Bypass Mixer", "HPCOM Switc    
576                                                   
577         {"Left HPCOM Mux", "differential of HP    
578         {"Left HPCOM Mux", "constant VCM", "Le    
579         {"Left HPCOM Mux", "single-ended", "Le    
580                                                   
581         {"Left Line Out", NULL, "Left PGA Bypa    
582         {"Mono Out", NULL, "Left PGA Bypass Mi    
583         {"Left HP Out", NULL, "Left PGA Bypass    
584                                                   
585         /* Right PGA Bypass */                    
586         {"Right PGA Bypass Mixer", "Line Switc    
587         {"Right PGA Bypass Mixer", "Mono Switc    
588         {"Right PGA Bypass Mixer", "HP Switch"    
589         {"Right PGA Bypass Mixer", "HPCOM Swit    
590                                                   
591         {"Right HPCOM Mux", "differential of H    
592         {"Right HPCOM Mux", "constant VCM", "R    
593         {"Right HPCOM Mux", "single-ended", "R    
594         {"Right HPCOM Mux", "differential of H    
595         {"Right HPCOM Mux", "external feedback    
596                                                   
597         {"Right Line Out", NULL, "Right PGA By    
598         {"Mono Out", NULL, "Right PGA Bypass M    
599         {"Right HP Out", NULL, "Right PGA Bypa    
600                                                   
601         /* Left Line2 Bypass */                   
602         {"Left Line2 Bypass Mixer", "Line Swit    
603         {"Left Line2 Bypass Mixer", "Mono Swit    
604         {"Left Line2 Bypass Mixer", "HP Switch    
605         {"Left Line2 Bypass Mixer", "HPCOM Swi    
606                                                   
607         {"Left HPCOM Mux", "differential of HP    
608         {"Left HPCOM Mux", "constant VCM", "Le    
609         {"Left HPCOM Mux", "single-ended", "Le    
610                                                   
611         {"Left Line Out", NULL, "Left Line2 By    
612         {"Mono Out", NULL, "Left Line2 Bypass     
613         {"Left HP Out", NULL, "Left Line2 Bypa    
614                                                   
615         /* Right Line2 Bypass */                  
616         {"Right Line2 Bypass Mixer", "Line Swi    
617         {"Right Line2 Bypass Mixer", "Mono Swi    
618         {"Right Line2 Bypass Mixer", "HP Switc    
619         {"Right Line2 Bypass Mixer", "HPCOM Sw    
620                                                   
621         {"Right HPCOM Mux", "differential of H    
622         {"Right HPCOM Mux", "constant VCM", "R    
623         {"Right HPCOM Mux", "single-ended", "R    
624         {"Right HPCOM Mux", "differential of H    
625         {"Right HPCOM Mux", "external feedback    
626                                                   
627         {"Right Line Out", NULL, "Right Line2     
628         {"Mono Out", NULL, "Right Line2 Bypass    
629         {"Right HP Out", NULL, "Right Line2 By    
630                                                   
631         /* terminator */                          
632         {NULL, NULL, NULL},                       
633 };                                                
634                                                   
635 static int aic3x_add_widgets(struct snd_soc_co    
636 {                                                 
637         int i;                                    
638                                                   
639         for (i = 0; i < ARRAY_SIZE(aic3x_dapm_    
640                 snd_soc_dapm_new_control(codec    
641                                                   
642         /* set up audio path interconnects */     
643         for (i = 0; intercon[i][0] != NULL; i+    
644                 snd_soc_dapm_connect_input(cod    
645                                            int    
646                                                   
647         snd_soc_dapm_new_widgets(codec);          
648         return 0;                                 
649 }                                                 
650                                                   
651 struct aic3x_rate_divs {                          
652         u32 mclk;                                 
653         u32 rate;                                 
654         u32 fsref_reg;                            
655         u8 sr_reg:4;                              
656         u8 pllj_reg;                              
657         u16 plld_reg;                             
658 };                                                
659                                                   
660 /* AIC3X codec mclk clock divider coefficients    
661 static const struct aic3x_rate_divs aic3x_divs    
662         /* 8k */                                  
663         {22579200, 8000, 48000, 0xa, 8, 7075},    
664         {33868800, 8000, 48000, 0xa, 5, 8049},    
665         /* 11.025k */                             
666         {22579200, 11025, 44100, 0x6, 8, 0},      
667         {33868800, 11025, 44100, 0x6, 5, 3333}    
668         /* 16k */                                 
669         {22579200, 16000, 48000, 0x4, 8, 7075}    
670         {33868800, 16000, 48000, 0x4, 5, 8049}    
671         /* 22.05k */                              
672         {22579200, 22050, 44100, 0x2, 8, 0},      
673         {33868800, 22050, 44100, 0x2, 5, 3333}    
674         /* 32k */                                 
675         {22579200, 32000, 48000, 0x1, 8, 7075}    
676         {33868800, 32000, 48000, 0x1, 5, 8049}    
677         /* 44.1k */                               
678         {22579200, 44100, 44100, 0x0, 8, 0},      
679         {33868800, 44100, 44100, 0x0, 5, 3333}    
680         /* 48k */                                 
681         {22579200, 48000, 48000, 0x0, 8, 7075}    
682         {33868800, 48000, 48000, 0x0, 5, 8049}    
683         /* 64k */                                 
684         {22579200, 64000, 96000, 0x1, 8, 7075}    
685         {33868800, 64000, 96000, 0x1, 5, 8049}    
686         /* 88.2k */                               
687         {22579200, 88200, 88200, 0x0, 8, 0},      
688         {33868800, 88200, 88200, 0x0, 5, 3333}    
689         /* 96k */                                 
690         {22579200, 96000, 96000, 0x0, 8, 7075}    
691         {33868800, 96000, 96000, 0x0, 5, 8049}    
692 };                                                
693                                                   
694 static inline int aic3x_get_divs(int mclk, int    
695 {                                                 
696         int i;                                    
697                                                   
698         for (i = 0; i < ARRAY_SIZE(aic3x_divs)    
699                 if (aic3x_divs[i].rate == rate    
700                         return i;                 
701         }                                         
702                                                   
703         return 0;                                 
704 }                                                 
705                                                   
706 static int aic3x_hw_params(struct snd_pcm_subs    
707                            struct snd_pcm_hw_p    
708 {                                                 
709         struct snd_soc_pcm_runtime *rtd = subs    
710         struct snd_soc_device *socdev = rtd->s    
711         struct snd_soc_codec *codec = socdev->    
712         struct aic3x_priv *aic3x = codec->priv    
713         int i;                                    
714         u8 data, pll_p, pll_r, pll_j;             
715         u16 pll_d;                                
716                                                   
717         i = aic3x_get_divs(aic3x->sysclk, para    
718                                                   
719         /* Route Left DAC to left channel inpu    
720          * right DAC to right channel input */    
721         data = (LDAC2LCH | RDAC2RCH);             
722         switch (aic3x_divs[i].fsref_reg) {        
723         case 44100:                               
724                 data |= FSREF_44100;              
725                 break;                            
726         case 48000:                               
727                 data |= FSREF_48000;              
728                 break;                            
729         case 88200:                               
730                 data |= FSREF_44100 | DUAL_RAT    
731                 break;                            
732         case 96000:                               
733                 data |= FSREF_48000 | DUAL_RAT    
734                 break;                            
735         }                                         
736         aic3x_write(codec, AIC3X_CODEC_DATAPAT    
737                                                   
738         /* codec sample rate select */            
739         data = aic3x_divs[i].sr_reg;              
740         data |= (data << 4);                      
741         aic3x_write(codec, AIC3X_SAMPLE_RATE_S    
742                                                   
743         /* Use PLL for generation Fsref by equ    
744          * Fsref = (MCLK * K * R)/(2048 * P);     
745          * Fix P = 2 and R = 1 and calculate K    
746          * K = J.D, i.e. J - an interger porti    
747          * one with 4 digits of precision;        
748          * Example:                               
749          * For MCLK = 22.5792 MHz and Fsref =     
750          * Select P = 2, R= 1, K = 8.7074, whi    
751          */                                       
752         pll_p = 2;                                
753         pll_r = 1;                                
754         pll_j = aic3x_divs[i].pllj_reg;           
755         pll_d = aic3x_divs[i].plld_reg;           
756                                                   
757         data = aic3x_read_reg_cache(codec, AIC    
758         aic3x_write(codec, AIC3X_PLL_PROGA_REG    
759         aic3x_write(codec, AIC3X_OVRF_STATUS_A    
760         aic3x_write(codec, AIC3X_PLL_PROGB_REG    
761         aic3x_write(codec, AIC3X_PLL_PROGC_REG    
762         aic3x_write(codec, AIC3X_PLL_PROGD_REG    
763                     (pll_d & 0x3F) << PLLD_LSB    
764                                                   
765         /* select data word length */             
766         data =                                    
767             aic3x_read_reg_cache(codec, AIC3X_    
768         switch (params_format(params)) {          
769         case SNDRV_PCM_FORMAT_S16_LE:             
770                 break;                            
771         case SNDRV_PCM_FORMAT_S20_3LE:            
772                 data |= (0x01 << 4);              
773                 break;                            
774         case SNDRV_PCM_FORMAT_S24_LE:             
775                 data |= (0x02 << 4);              
776                 break;                            
777         case SNDRV_PCM_FORMAT_S32_LE:             
778                 data |= (0x03 << 4);              
779                 break;                            
780         }                                         
781         aic3x_write(codec, AIC3X_ASD_INTF_CTRL    
782                                                   
783         return 0;                                 
784 }                                                 
785                                                   
786 static int aic3x_mute(struct snd_soc_codec_dai    
787 {                                                 
788         struct snd_soc_codec *codec = dai->cod    
789         u8 ldac_reg = aic3x_read_reg_cache(cod    
790         u8 rdac_reg = aic3x_read_reg_cache(cod    
791                                                   
792         if (mute) {                               
793                 aic3x_write(codec, LDAC_VOL, l    
794                 aic3x_write(codec, RDAC_VOL, r    
795         } else {                                  
796                 aic3x_write(codec, LDAC_VOL, l    
797                 aic3x_write(codec, RDAC_VOL, r    
798         }                                         
799                                                   
800         return 0;                                 
801 }                                                 
802                                                   
803 static int aic3x_set_dai_sysclk(struct snd_soc    
804                                 int clk_id, un    
805 {                                                 
806         struct snd_soc_codec *codec = codec_da    
807         struct aic3x_priv *aic3x = codec->priv    
808                                                   
809         switch (freq) {                           
810         case 22579200:                            
811         case 33868800:                            
812                 aic3x->sysclk = freq;             
813                 return 0;                         
814         }                                         
815                                                   
816         return -EINVAL;                           
817 }                                                 
818                                                   
819 static int aic3x_set_dai_fmt(struct snd_soc_co    
820                              unsigned int fmt)    
821 {                                                 
822         struct snd_soc_codec *codec = codec_da    
823         struct aic3x_priv *aic3x = codec->priv    
824         u8 iface_areg = 0;                        
825         u8 iface_breg = 0;                        
826                                                   
827         /* set master/slave audio interface */    
828         switch (fmt & SND_SOC_DAIFMT_MASTER_MA    
829         case SND_SOC_DAIFMT_CBM_CFM:              
830                 aic3x->master = 1;                
831                 iface_areg |= BIT_CLK_MASTER |    
832                 break;                            
833         case SND_SOC_DAIFMT_CBS_CFS:              
834                 aic3x->master = 0;                
835                 break;                            
836         default:                                  
837                 return -EINVAL;                   
838         }                                         
839                                                   
840         /* interface format */                    
841         switch (fmt & SND_SOC_DAIFMT_FORMAT_MA    
842         case SND_SOC_DAIFMT_I2S:                  
843                 break;                            
844         case SND_SOC_DAIFMT_DSP_A:                
845                 iface_breg |= (0x01 << 6);        
846                 break;                            
847         case SND_SOC_DAIFMT_RIGHT_J:              
848                 iface_breg |= (0x02 << 6);        
849                 break;                            
850         case SND_SOC_DAIFMT_LEFT_J:               
851                 iface_breg |= (0x03 << 6);        
852                 break;                            
853         default:                                  
854                 return -EINVAL;                   
855         }                                         
856                                                   
857         /* set iface */                           
858         aic3x_write(codec, AIC3X_ASD_INTF_CTRL    
859         aic3x_write(codec, AIC3X_ASD_INTF_CTRL    
860                                                   
861         return 0;                                 
862 }                                                 
863                                                   
864 static int aic3x_dapm_event(struct snd_soc_cod    
865 {                                                 
866         struct aic3x_priv *aic3x = codec->priv    
867         u8 reg;                                   
868                                                   
869         switch (event) {                          
870         case SNDRV_CTL_POWER_D0:                  
871                 /* all power is driven by DAPM    
872                 if (aic3x->master) {              
873                         /* enable pll */          
874                         reg = aic3x_read_reg_c    
875                         aic3x_write(codec, AIC    
876                                     reg | PLL_    
877                 }                                 
878                 break;                            
879         case SNDRV_CTL_POWER_D1:                  
880         case SNDRV_CTL_POWER_D2:                  
881                 break;                            
882         case SNDRV_CTL_POWER_D3hot:               
883                 /*                                
884                  * all power is driven by DAPM    
885                  * so output power is safe if     
886                  */                               
887                 if (aic3x->master) {              
888                         /* disable pll */         
889                         reg = aic3x_read_reg_c    
890                         aic3x_write(codec, AIC    
891                                     reg & ~PLL    
892                 }                                 
893                 break;                            
894         case SNDRV_CTL_POWER_D3cold:              
895                 /* force all power off */         
896                 reg = aic3x_read_reg_cache(cod    
897                 aic3x_write(codec, LINE1L_2_LA    
898                 reg = aic3x_read_reg_cache(cod    
899                 aic3x_write(codec, LINE1R_2_RA    
900                                                   
901                 reg = aic3x_read_reg_cache(cod    
902                 aic3x_write(codec, DAC_PWR, re    
903                                                   
904                 reg = aic3x_read_reg_cache(cod    
905                 aic3x_write(codec, HPLOUT_CTRL    
906                 reg = aic3x_read_reg_cache(cod    
907                 aic3x_write(codec, HPROUT_CTRL    
908                                                   
909                 reg = aic3x_read_reg_cache(cod    
910                 aic3x_write(codec, HPLCOM_CTRL    
911                 reg = aic3x_read_reg_cache(cod    
912                 aic3x_write(codec, HPRCOM_CTRL    
913                                                   
914                 reg = aic3x_read_reg_cache(cod    
915                 aic3x_write(codec, MONOLOPM_CT    
916                                                   
917                 reg = aic3x_read_reg_cache(cod    
918                 aic3x_write(codec, LLOPM_CTRL,    
919                 reg = aic3x_read_reg_cache(cod    
920                 aic3x_write(codec, RLOPM_CTRL,    
921                                                   
922                 if (aic3x->master) {              
923                         /* disable pll */         
924                         reg = aic3x_read_reg_c    
925                         aic3x_write(codec, AIC    
926                                     reg & ~PLL    
927                 }                                 
928                 break;                            
929         }                                         
930         codec->dapm_state = event;                
931                                                   
932         return 0;                                 
933 }                                                 
934                                                   
935 #define AIC3X_RATES     SNDRV_PCM_RATE_8000_96    
936 #define AIC3X_FORMATS   (SNDRV_PCM_FMTBIT_S16_    
937                          SNDRV_PCM_FMTBIT_S24_    
938                                                   
939 struct snd_soc_codec_dai aic3x_dai = {            
940         .name = "aic3x",                          
941         .playback = {                             
942                 .stream_name = "Playback",        
943                 .channels_min = 1,                
944                 .channels_max = 2,                
945                 .rates = AIC3X_RATES,             
946                 .formats = AIC3X_FORMATS,},       
947         .capture = {                              
948                 .stream_name = "Capture",         
949                 .channels_min = 1,                
950                 .channels_max = 2,                
951                 .rates = AIC3X_RATES,             
952                 .formats = AIC3X_FORMATS,},       
953         .ops = {                                  
954                 .hw_params = aic3x_hw_params,     
955         },                                        
956         .dai_ops = {                              
957                 .digital_mute = aic3x_mute,       
958                 .set_sysclk = aic3x_set_dai_sy    
959                 .set_fmt = aic3x_set_dai_fmt,     
960         }                                         
961 };                                                
962 EXPORT_SYMBOL_GPL(aic3x_dai);                     
963                                                   
964 static int aic3x_suspend(struct platform_devic    
965 {                                                 
966         struct snd_soc_device *socdev = platfo    
967         struct snd_soc_codec *codec = socdev->    
968                                                   
969         aic3x_dapm_event(codec, SNDRV_CTL_POWE    
970                                                   
971         return 0;                                 
972 }                                                 
973                                                   
974 static int aic3x_resume(struct platform_device    
975 {                                                 
976         struct snd_soc_device *socdev = platfo    
977         struct snd_soc_codec *codec = socdev->    
978         int i;                                    
979         u8 data[2];                               
980         u8 *cache = codec->reg_cache;             
981                                                   
982         /* Sync reg_cache with the hardware */    
983         for (i = 0; i < ARRAY_SIZE(aic3x_reg);    
984                 data[0] = i;                      
985                 data[1] = cache[i];               
986                 codec->hw_write(codec->control    
987         }                                         
988                                                   
989         aic3x_dapm_event(codec, codec->suspend    
990                                                   
991         return 0;                                 
992 }                                                 
993                                                   
994 /*                                                
995  * initialise the AIC3X driver                    
996  * register the mixer and dsp interfaces with     
997  */                                               
998 static int aic3x_init(struct snd_soc_device *s    
999 {                                                 
1000         struct snd_soc_codec *codec = socdev-    
1001         int reg, ret = 0;                        
1002                                                  
1003         codec->name = "aic3x";                   
1004         codec->owner = THIS_MODULE;              
1005         codec->read = aic3x_read_reg_cache;      
1006         codec->write = aic3x_write;              
1007         codec->dapm_event = aic3x_dapm_event;    
1008         codec->dai = &aic3x_dai;                 
1009         codec->num_dai = 1;                      
1010         codec->reg_cache_size = sizeof(aic3x_    
1011         codec->reg_cache = kmemdup(aic3x_reg,    
1012         if (codec->reg_cache == NULL)            
1013                 return -ENOMEM;                  
1014                                                  
1015         aic3x_write(codec, AIC3X_PAGE_SELECT,    
1016         aic3x_write(codec, AIC3X_RESET, SOFT_    
1017                                                  
1018         /* register pcms */                      
1019         ret = snd_soc_new_pcms(socdev, SNDRV_    
1020         if (ret < 0) {                           
1021                 printk(KERN_ERR "aic3x: faile    
1022                 goto pcm_err;                    
1023         }                                        
1024                                                  
1025         /* DAC default volume and mute */        
1026         aic3x_write(codec, LDAC_VOL, DEFAULT_    
1027         aic3x_write(codec, RDAC_VOL, DEFAULT_    
1028                                                  
1029         /* DAC to HP default volume and route    
1030         aic3x_write(codec, DACL1_2_HPLOUT_VOL    
1031         aic3x_write(codec, DACR1_2_HPROUT_VOL    
1032         aic3x_write(codec, DACL1_2_HPLCOM_VOL    
1033         aic3x_write(codec, DACR1_2_HPRCOM_VOL    
1034         /* DAC to Line Out default volume and    
1035         aic3x_write(codec, DACL1_2_LLOPM_VOL,    
1036         aic3x_write(codec, DACR1_2_RLOPM_VOL,    
1037         /* DAC to Mono Line Out default volum    
1038         aic3x_write(codec, DACL1_2_MONOLOPM_V    
1039         aic3x_write(codec, DACR1_2_MONOLOPM_V    
1040                                                  
1041         /* unmute all outputs */                 
1042         reg = aic3x_read_reg_cache(codec, LLO    
1043         aic3x_write(codec, LLOPM_CTRL, reg |     
1044         reg = aic3x_read_reg_cache(codec, RLO    
1045         aic3x_write(codec, RLOPM_CTRL, reg |     
1046         reg = aic3x_read_reg_cache(codec, MON    
1047         aic3x_write(codec, MONOLOPM_CTRL, reg    
1048         reg = aic3x_read_reg_cache(codec, HPL    
1049         aic3x_write(codec, HPLOUT_CTRL, reg |    
1050         reg = aic3x_read_reg_cache(codec, HPR    
1051         aic3x_write(codec, HPROUT_CTRL, reg |    
1052         reg = aic3x_read_reg_cache(codec, HPL    
1053         aic3x_write(codec, HPLCOM_CTRL, reg |    
1054         reg = aic3x_read_reg_cache(codec, HPR    
1055         aic3x_write(codec, HPRCOM_CTRL, reg |    
1056                                                  
1057         /* ADC default volume and unmute */      
1058         aic3x_write(codec, LADC_VOL, DEFAULT_    
1059         aic3x_write(codec, RADC_VOL, DEFAULT_    
1060         /* By default route Line1 to ADC PGA     
1061         aic3x_write(codec, LINE1L_2_LADC_CTRL    
1062         aic3x_write(codec, LINE1R_2_RADC_CTRL    
1063                                                  
1064         /* PGA to HP Bypass default volume, d    
1065         aic3x_write(codec, PGAL_2_HPLOUT_VOL,    
1066         aic3x_write(codec, PGAR_2_HPROUT_VOL,    
1067         aic3x_write(codec, PGAL_2_HPLCOM_VOL,    
1068         aic3x_write(codec, PGAR_2_HPRCOM_VOL,    
1069         /* PGA to Line Out default volume, di    
1070         aic3x_write(codec, PGAL_2_LLOPM_VOL,     
1071         aic3x_write(codec, PGAR_2_RLOPM_VOL,     
1072         /* PGA to Mono Line Out default volum    
1073         aic3x_write(codec, PGAL_2_MONOLOPM_VO    
1074         aic3x_write(codec, PGAR_2_MONOLOPM_VO    
1075                                                  
1076         /* Line2 to HP Bypass default volume,    
1077         aic3x_write(codec, LINE2L_2_HPLOUT_VO    
1078         aic3x_write(codec, LINE2R_2_HPROUT_VO    
1079         aic3x_write(codec, LINE2L_2_HPLCOM_VO    
1080         aic3x_write(codec, LINE2R_2_HPRCOM_VO    
1081         /* Line2 Line Out default volume, dis    
1082         aic3x_write(codec, LINE2L_2_LLOPM_VOL    
1083         aic3x_write(codec, LINE2R_2_RLOPM_VOL    
1084         /* Line2 to Mono Out default volume,     
1085         aic3x_write(codec, LINE2L_2_MONOLOPM_    
1086         aic3x_write(codec, LINE2R_2_MONOLOPM_    
1087                                                  
1088         /* off, with power on */                 
1089         aic3x_dapm_event(codec, SNDRV_CTL_POW    
1090                                                  
1091         aic3x_add_controls(codec);               
1092         aic3x_add_widgets(codec);                
1093         ret = snd_soc_register_card(socdev);     
1094         if (ret < 0) {                           
1095                 printk(KERN_ERR "aic3x: faile    
1096                 goto card_err;                   
1097         }                                        
1098                                                  
1099         return ret;                              
1100                                                  
1101 card_err:                                        
1102         snd_soc_free_pcms(socdev);               
1103         snd_soc_dapm_free(socdev);               
1104 pcm_err:                                         
1105         kfree(codec->reg_cache);                 
1106         return ret;                              
1107 }                                                
1108                                                  
1109 static struct snd_soc_device *aic3x_socdev;      
1110                                                  
1111 #if defined(CONFIG_I2C) || defined(CONFIG_I2C    
1112 /*                                               
1113  * AIC3X 2 wire address can be up to 4 device    
1114  * 0x18, 0x19, 0x1A, 0x1B                        
1115  */                                              
1116 static unsigned short normal_i2c[] = { 0, I2C    
1117                                                  
1118 /* Magic definition of all other variables an    
1119 I2C_CLIENT_INSMOD;                               
1120                                                  
1121 static struct i2c_driver aic3x_i2c_driver;       
1122 static struct i2c_client client_template;        
1123                                                  
1124 /*                                               
1125  * If the i2c layer weren't so broken, we cou    
1126  * around                                        
1127  */                                              
1128 static int aic3x_codec_probe(struct i2c_adapt    
1129 {                                                
1130         struct snd_soc_device *socdev = aic3x    
1131         struct aic3x_setup_data *setup = socd    
1132         struct snd_soc_codec *codec = socdev-    
1133         struct i2c_client *i2c;                  
1134         int ret;                                 
1135                                                  
1136         if (addr != setup->i2c_address)          
1137                 return -ENODEV;                  
1138                                                  
1139         client_template.adapter = adap;          
1140         client_template.addr = addr;             
1141                                                  
1142         i2c = kmemdup(&client_template, sizeo    
1143         if (i2c == NULL) {                       
1144                 kfree(codec);                    
1145                 return -ENOMEM;                  
1146         }                                        
1147         i2c_set_clientdata(i2c, codec);          
1148         codec->control_data = i2c;               
1149                                                  
1150         ret = i2c_attach_client(i2c);            
1151         if (ret < 0) {                           
1152                 printk(KERN_ERR "aic3x: faile    
1153                        addr);                    
1154                 goto err;                        
1155         }                                        
1156                                                  
1157         ret = aic3x_init(socdev);                
1158         if (ret < 0) {                           
1159                 printk(KERN_ERR "aic3x: faile    
1160                 goto err;                        
1161         }                                        
1162         return ret;                              
1163                                                  
1164 err:                                             
1165         kfree(codec);                            
1166         kfree(i2c);                              
1167         return ret;                              
1168 }                                                
1169                                                  
1170 static int aic3x_i2c_detach(struct i2c_client    
1171 {                                                
1172         struct snd_soc_codec *codec = i2c_get    
1173         i2c_detach_client(client);               
1174         kfree(codec->reg_cache);                 
1175         kfree(client);                           
1176         return 0;                                
1177 }                                                
1178                                                  
1179 static int aic3x_i2c_attach(struct i2c_adapte    
1180 {                                                
1181         return i2c_probe(adap, &addr_data, ai    
1182 }                                                
1183                                                  
1184 /* machine i2c codec control layer */            
1185 static struct i2c_driver aic3x_i2c_driver = {    
1186         .driver = {                              
1187                 .name = "aic3x I2C Codec",       
1188                 .owner = THIS_MODULE,            
1189         },                                       
1190         .attach_adapter = aic3x_i2c_attach,      
1191         .detach_client = aic3x_i2c_detach,       
1192 };                                               
1193                                                  
1194 static struct i2c_client client_template = {     
1195         .name = "AIC3X",                         
1196         .driver = &aic3x_i2c_driver,             
1197 };                                               
1198 #endif                                           
1199                                                  
1200 static int aic3x_probe(struct platform_device    
1201 {                                                
1202         struct snd_soc_device *socdev = platf    
1203         struct aic3x_setup_data *setup;          
1204         struct snd_soc_codec *codec;             
1205         struct aic3x_priv *aic3x;                
1206         int ret = 0;                             
1207                                                  
1208         printk(KERN_INFO "AIC3X Audio Codec %    
1209                                                  
1210         setup = socdev->codec_data;              
1211         codec = kzalloc(sizeof(struct snd_soc    
1212         if (codec == NULL)                       
1213                 return -ENOMEM;                  
1214                                                  
1215         aic3x = kzalloc(sizeof(struct aic3x_p    
1216         if (aic3x == NULL) {                     
1217                 kfree(codec);                    
1218                 return -ENOMEM;                  
1219         }                                        
1220                                                  
1221         codec->private_data = aic3x;             
1222         socdev->codec = codec;                   
1223         mutex_init(&codec->mutex);               
1224         INIT_LIST_HEAD(&codec->dapm_widgets);    
1225         INIT_LIST_HEAD(&codec->dapm_paths);      
1226                                                  
1227         aic3x_socdev = socdev;                   
1228 #if defined(CONFIG_I2C) || defined(CONFIG_I2C    
1229         if (setup->i2c_address) {                
1230                 normal_i2c[0] = setup->i2c_ad    
1231                 codec->hw_write = (hw_write_t    
1232                 ret = i2c_add_driver(&aic3x_i    
1233                 if (ret != 0)                    
1234                         printk(KERN_ERR "can'    
1235         }                                        
1236 #else                                            
1237         /* Add other interfaces here */          
1238 #endif                                           
1239         return ret;                              
1240 }                                                
1241                                                  
1242 static int aic3x_remove(struct platform_devic    
1243 {                                                
1244         struct snd_soc_device *socdev = platf    
1245         struct snd_soc_codec *codec = socdev-    
1246                                                  
1247         /* power down chip */                    
1248         if (codec->control_data)                 
1249                 aic3x_dapm_event(codec, SNDRV    
1250                                                  
1251         snd_soc_free_pcms(socdev);               
1252         snd_soc_dapm_free(socdev);               
1253 #if defined(CONFIG_I2C) || defined(CONFIG_I2C    
1254         i2c_del_driver(&aic3x_i2c_driver);       
1255 #endif                                           
1256         kfree(codec->private_data);              
1257         kfree(codec);                            
1258                                                  
1259         return 0;                                
1260 }                                                
1261                                                  
1262 struct snd_soc_codec_device soc_codec_dev_aic    
1263         .probe = aic3x_probe,                    
1264         .remove = aic3x_remove,                  
1265         .suspend = aic3x_suspend,                
1266         .resume = aic3x_resume,                  
1267 };                                               
1268 EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);          
1269                                                  
1270 MODULE_DESCRIPTION("ASoC TLV320AIC3X codec dr    
1271 MODULE_AUTHOR("Vladimir Barinov");               
1272 MODULE_LICENSE("GPL");                           
1273                                                  
  This page was automatically generated by the LXR engine.