~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/adav80x.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/soc/codecs/adav80x.c (Version linux-6.12-rc7) and /sound/soc/codecs/adav80x.c (Version linux-2.4.37.11)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  * ADAV80X Audio Codec driver supporting ADAV8    
  4  *                                                
  5  * Copyright 2011 Analog Devices Inc.             
  6  * Author: Yi Li <yi.li@analog.com>               
  7  * Author: Lars-Peter Clausen <lars@metafoo.de    
  8  */                                               
  9                                                   
 10 #include <linux/module.h>                         
 11 #include <linux/kernel.h>                         
 12 #include <linux/regmap.h>                         
 13 #include <linux/slab.h>                           
 14                                                   
 15 #include <sound/pcm.h>                            
 16 #include <sound/pcm_params.h>                     
 17 #include <sound/soc.h>                            
 18 #include <sound/tlv.h>                            
 19                                                   
 20 #include "adav80x.h"                              
 21                                                   
 22 #define ADAV80X_PLAYBACK_CTRL   0x04              
 23 #define ADAV80X_AUX_IN_CTRL     0x05              
 24 #define ADAV80X_REC_CTRL        0x06              
 25 #define ADAV80X_AUX_OUT_CTRL    0x07              
 26 #define ADAV80X_DPATH_CTRL1     0x62              
 27 #define ADAV80X_DPATH_CTRL2     0x63              
 28 #define ADAV80X_DAC_CTRL1       0x64              
 29 #define ADAV80X_DAC_CTRL2       0x65              
 30 #define ADAV80X_DAC_CTRL3       0x66              
 31 #define ADAV80X_DAC_L_VOL       0x68              
 32 #define ADAV80X_DAC_R_VOL       0x69              
 33 #define ADAV80X_PGA_L_VOL       0x6c              
 34 #define ADAV80X_PGA_R_VOL       0x6d              
 35 #define ADAV80X_ADC_CTRL1       0x6e              
 36 #define ADAV80X_ADC_CTRL2       0x6f              
 37 #define ADAV80X_ADC_L_VOL       0x70              
 38 #define ADAV80X_ADC_R_VOL       0x71              
 39 #define ADAV80X_PLL_CTRL1       0x74              
 40 #define ADAV80X_PLL_CTRL2       0x75              
 41 #define ADAV80X_ICLK_CTRL1      0x76              
 42 #define ADAV80X_ICLK_CTRL2      0x77              
 43 #define ADAV80X_PLL_CLK_SRC     0x78              
 44 #define ADAV80X_PLL_OUTE        0x7a              
 45                                                   
 46 #define ADAV80X_PLL_CLK_SRC_PLL_XIN(pll)          
 47 #define ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll)        
 48 #define ADAV80X_PLL_CLK_SRC_PLL_MASK(pll)         
 49                                                   
 50 #define ADAV80X_ICLK_CTRL1_DAC_SRC(src)           
 51 #define ADAV80X_ICLK_CTRL1_ADC_SRC(src)           
 52 #define ADAV80X_ICLK_CTRL1_ICLK2_SRC(src)         
 53 #define ADAV80X_ICLK_CTRL2_ICLK1_SRC(src)         
 54                                                   
 55 #define ADAV80X_PLL_CTRL1_PLLDIV                  
 56 #define ADAV80X_PLL_CTRL1_PLLPD(pll)              
 57 #define ADAV80X_PLL_CTRL1_XTLPD                   
 58                                                   
 59 #define ADAV80X_PLL_CTRL2_FIELD(pll, x)           
 60                                                   
 61 #define ADAV80X_PLL_CTRL2_FS_48(pll)    ADAV80    
 62 #define ADAV80X_PLL_CTRL2_FS_32(pll)    ADAV80    
 63 #define ADAV80X_PLL_CTRL2_FS_44(pll)    ADAV80    
 64                                                   
 65 #define ADAV80X_PLL_CTRL2_SEL(pll)      ADAV80    
 66 #define ADAV80X_PLL_CTRL2_DOUB(pll)     ADAV80    
 67 #define ADAV80X_PLL_CTRL2_PLL_MASK(pll) ADAV80    
 68                                                   
 69 #define ADAV80X_ADC_CTRL1_MODULATOR_MASK          
 70 #define ADAV80X_ADC_CTRL1_MODULATOR_128FS         
 71 #define ADAV80X_ADC_CTRL1_MODULATOR_64FS          
 72                                                   
 73 #define ADAV80X_DAC_CTRL1_PD                      
 74                                                   
 75 #define ADAV80X_DAC_CTRL2_DIV1                    
 76 #define ADAV80X_DAC_CTRL2_DIV1_5                  
 77 #define ADAV80X_DAC_CTRL2_DIV2                    
 78 #define ADAV80X_DAC_CTRL2_DIV3                    
 79 #define ADAV80X_DAC_CTRL2_DIV_MASK                
 80                                                   
 81 #define ADAV80X_DAC_CTRL2_INTERPOL_256FS          
 82 #define ADAV80X_DAC_CTRL2_INTERPOL_128FS          
 83 #define ADAV80X_DAC_CTRL2_INTERPOL_64FS           
 84 #define ADAV80X_DAC_CTRL2_INTERPOL_MASK           
 85                                                   
 86 #define ADAV80X_DAC_CTRL2_DEEMPH_NONE             
 87 #define ADAV80X_DAC_CTRL2_DEEMPH_44               
 88 #define ADAV80X_DAC_CTRL2_DEEMPH_32               
 89 #define ADAV80X_DAC_CTRL2_DEEMPH_48               
 90 #define ADAV80X_DAC_CTRL2_DEEMPH_MASK             
 91                                                   
 92 #define ADAV80X_CAPTURE_MODE_MASTER               
 93 #define ADAV80X_CAPTURE_WORD_LEN24                
 94 #define ADAV80X_CAPTURE_WORD_LEN20                
 95 #define ADAV80X_CAPTRUE_WORD_LEN18                
 96 #define ADAV80X_CAPTURE_WORD_LEN16                
 97 #define ADAV80X_CAPTURE_WORD_LEN_MASK             
 98                                                   
 99 #define ADAV80X_CAPTURE_MODE_LEFT_J               
100 #define ADAV80X_CAPTURE_MODE_I2S                  
101 #define ADAV80X_CAPTURE_MODE_RIGHT_J              
102 #define ADAV80X_CAPTURE_MODE_MASK                 
103                                                   
104 #define ADAV80X_PLAYBACK_MODE_MASTER              
105 #define ADAV80X_PLAYBACK_MODE_LEFT_J              
106 #define ADAV80X_PLAYBACK_MODE_I2S                 
107 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_24          
108 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_20          
109 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_18          
110 #define ADAV80X_PLAYBACK_MODE_RIGHT_J_16          
111 #define ADAV80X_PLAYBACK_MODE_MASK                
112                                                   
113 #define ADAV80X_PLL_OUTE_SYSCLKPD(x)              
114                                                   
115 static const struct reg_default adav80x_reg_de    
116         { ADAV80X_PLAYBACK_CTRL,        0x01 }    
117         { ADAV80X_AUX_IN_CTRL,          0x01 }    
118         { ADAV80X_REC_CTRL,             0x02 }    
119         { ADAV80X_AUX_OUT_CTRL,         0x01 }    
120         { ADAV80X_DPATH_CTRL1,          0xc0 }    
121         { ADAV80X_DPATH_CTRL2,          0x11 }    
122         { ADAV80X_DAC_CTRL1,            0x00 }    
123         { ADAV80X_DAC_CTRL2,            0x00 }    
124         { ADAV80X_DAC_CTRL3,            0x00 }    
125         { ADAV80X_DAC_L_VOL,            0xff }    
126         { ADAV80X_DAC_R_VOL,            0xff }    
127         { ADAV80X_PGA_L_VOL,            0x00 }    
128         { ADAV80X_PGA_R_VOL,            0x00 }    
129         { ADAV80X_ADC_CTRL1,            0x00 }    
130         { ADAV80X_ADC_CTRL2,            0x00 }    
131         { ADAV80X_ADC_L_VOL,            0xff }    
132         { ADAV80X_ADC_R_VOL,            0xff }    
133         { ADAV80X_PLL_CTRL1,            0x00 }    
134         { ADAV80X_PLL_CTRL2,            0x00 }    
135         { ADAV80X_ICLK_CTRL1,           0x00 }    
136         { ADAV80X_ICLK_CTRL2,           0x00 }    
137         { ADAV80X_PLL_CLK_SRC,          0x00 }    
138         { ADAV80X_PLL_OUTE,             0x00 }    
139 };                                                
140                                                   
141 struct adav80x {                                  
142         struct regmap *regmap;                    
143                                                   
144         enum adav80x_clk_src clk_src;             
145         unsigned int sysclk;                      
146         enum adav80x_pll_src pll_src;             
147                                                   
148         unsigned int dai_fmt[2];                  
149         unsigned int rate;                        
150         bool deemph;                              
151         bool sysclk_pd[3];                        
152 };                                                
153                                                   
154 static const char *adav80x_mux_text[] = {         
155         "ADC",                                    
156         "Playback",                               
157         "Aux Playback",                           
158 };                                                
159                                                   
160 static const unsigned int adav80x_mux_values[]    
161         0, 2, 3,                                  
162 };                                                
163                                                   
164 #define ADAV80X_MUX_ENUM_DECL(name, reg, shift    
165         SOC_VALUE_ENUM_DOUBLE_DECL(name, reg,     
166                 ARRAY_SIZE(adav80x_mux_text),     
167                 adav80x_mux_values)               
168                                                   
169 static ADAV80X_MUX_ENUM_DECL(adav80x_aux_captu    
170 static ADAV80X_MUX_ENUM_DECL(adav80x_capture_e    
171 static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum,    
172                                                   
173 static const struct snd_kcontrol_new adav80x_a    
174         SOC_DAPM_ENUM("Route", adav80x_aux_cap    
175 static const struct snd_kcontrol_new adav80x_c    
176         SOC_DAPM_ENUM("Route", adav80x_capture    
177 static const struct snd_kcontrol_new adav80x_d    
178         SOC_DAPM_ENUM("Route", adav80x_dac_enu    
179                                                   
180 #define ADAV80X_MUX(name, ctrl) \                 
181         SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0    
182                                                   
183 static const struct snd_soc_dapm_widget adav80    
184         SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_    
185         SND_SOC_DAPM_ADC("ADC", NULL, ADAV80X_    
186                                                   
187         SND_SOC_DAPM_PGA("Right PGA", ADAV80X_    
188         SND_SOC_DAPM_PGA("Left PGA", ADAV80X_A    
189                                                   
190         SND_SOC_DAPM_AIF_OUT("AIFOUT", "HiFi C    
191         SND_SOC_DAPM_AIF_IN("AIFIN", "HiFi Pla    
192                                                   
193         SND_SOC_DAPM_AIF_OUT("AIFAUXOUT", "Aux    
194         SND_SOC_DAPM_AIF_IN("AIFAUXIN", "Aux P    
195                                                   
196         ADAV80X_MUX("Aux Capture Select", &ada    
197         ADAV80X_MUX("Capture Select", &adav80x    
198         ADAV80X_MUX("DAC Select", &adav80x_dac    
199                                                   
200         SND_SOC_DAPM_INPUT("VINR"),               
201         SND_SOC_DAPM_INPUT("VINL"),               
202         SND_SOC_DAPM_OUTPUT("VOUTR"),             
203         SND_SOC_DAPM_OUTPUT("VOUTL"),             
204                                                   
205         SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_    
206         SND_SOC_DAPM_SUPPLY("PLL1", ADAV80X_PL    
207         SND_SOC_DAPM_SUPPLY("PLL2", ADAV80X_PL    
208         SND_SOC_DAPM_SUPPLY("OSC", ADAV80X_PLL    
209 };                                                
210                                                   
211 static int adav80x_dapm_sysclk_check(struct sn    
212                          struct snd_soc_dapm_w    
213 {                                                 
214         struct snd_soc_component *component =     
215         struct adav80x *adav80x = snd_soc_comp    
216         const char *clk;                          
217                                                   
218         switch (adav80x->clk_src) {               
219         case ADAV80X_CLK_PLL1:                    
220                 clk = "PLL1";                     
221                 break;                            
222         case ADAV80X_CLK_PLL2:                    
223                 clk = "PLL2";                     
224                 break;                            
225         case ADAV80X_CLK_XTAL:                    
226                 clk = "OSC";                      
227                 break;                            
228         default:                                  
229                 return 0;                         
230         }                                         
231                                                   
232         return snd_soc_dapm_widget_name_cmp(so    
233 }                                                 
234                                                   
235 static int adav80x_dapm_pll_check(struct snd_s    
236                          struct snd_soc_dapm_w    
237 {                                                 
238         struct snd_soc_component *component =     
239         struct adav80x *adav80x = snd_soc_comp    
240                                                   
241         return adav80x->pll_src == ADAV80X_PLL    
242 }                                                 
243                                                   
244                                                   
245 static const struct snd_soc_dapm_route adav80x    
246         { "DAC Select", "ADC", "ADC" },           
247         { "DAC Select", "Playback", "AIFIN" },    
248         { "DAC Select", "Aux Playback", "AIFAU    
249         { "DAC", NULL,  "DAC Select" },           
250                                                   
251         { "Capture Select", "ADC", "ADC" },       
252         { "Capture Select", "Playback", "AIFIN    
253         { "Capture Select", "Aux Playback", "A    
254         { "AIFOUT", NULL,  "Capture Select" },    
255                                                   
256         { "Aux Capture Select", "ADC", "ADC" }    
257         { "Aux Capture Select", "Playback", "A    
258         { "Aux Capture Select", "Aux Playback"    
259         { "AIFAUXOUT", NULL,  "Aux Capture Sel    
260                                                   
261         { "VOUTR",  NULL, "DAC" },                
262         { "VOUTL",  NULL, "DAC" },                
263                                                   
264         { "Left PGA", NULL, "VINL" },             
265         { "Right PGA", NULL, "VINR" },            
266         { "ADC", NULL, "Left PGA" },              
267         { "ADC", NULL, "Right PGA" },             
268                                                   
269         { "SYSCLK", NULL, "PLL1", adav80x_dapm    
270         { "SYSCLK", NULL, "PLL2", adav80x_dapm    
271         { "SYSCLK", NULL, "OSC", adav80x_dapm_    
272         { "PLL1", NULL, "OSC", adav80x_dapm_pl    
273         { "PLL2", NULL, "OSC", adav80x_dapm_pl    
274                                                   
275         { "ADC", NULL, "SYSCLK" },                
276         { "DAC", NULL, "SYSCLK" },                
277         { "AIFOUT", NULL, "SYSCLK" },             
278         { "AIFAUXOUT", NULL, "SYSCLK" },          
279         { "AIFIN", NULL, "SYSCLK" },              
280         { "AIFAUXIN", NULL, "SYSCLK" },           
281 };                                                
282                                                   
283 static int adav80x_set_deemph(struct snd_soc_c    
284 {                                                 
285         struct adav80x *adav80x = snd_soc_comp    
286         unsigned int val;                         
287                                                   
288         if (adav80x->deemph) {                    
289                 switch (adav80x->rate) {          
290                 case 32000:                       
291                         val = ADAV80X_DAC_CTRL    
292                         break;                    
293                 case 44100:                       
294                         val = ADAV80X_DAC_CTRL    
295                         break;                    
296                 case 48000:                       
297                 case 64000:                       
298                 case 88200:                       
299                 case 96000:                       
300                         val = ADAV80X_DAC_CTRL    
301                         break;                    
302                 default:                          
303                         val = ADAV80X_DAC_CTRL    
304                         break;                    
305                 }                                 
306         } else {                                  
307                 val = ADAV80X_DAC_CTRL2_DEEMPH    
308         }                                         
309                                                   
310         return regmap_update_bits(adav80x->reg    
311                 ADAV80X_DAC_CTRL2_DEEMPH_MASK,    
312 }                                                 
313                                                   
314 static int adav80x_put_deemph(struct snd_kcont    
315                 struct snd_ctl_elem_value *uco    
316 {                                                 
317         struct snd_soc_component *component =     
318         struct adav80x *adav80x = snd_soc_comp    
319         unsigned int deemph = ucontrol->value.    
320                                                   
321         if (deemph > 1)                           
322                 return -EINVAL;                   
323                                                   
324         adav80x->deemph = deemph;                 
325                                                   
326         return adav80x_set_deemph(component);     
327 }                                                 
328                                                   
329 static int adav80x_get_deemph(struct snd_kcont    
330                                 struct snd_ctl    
331 {                                                 
332         struct snd_soc_component *component =     
333         struct adav80x *adav80x = snd_soc_comp    
334                                                   
335         ucontrol->value.integer.value[0] = ada    
336         return 0;                                 
337 };                                                
338                                                   
339 static const DECLARE_TLV_DB_SCALE(adav80x_inpg    
340 static const DECLARE_TLV_DB_MINMAX(adav80x_dig    
341                                                   
342 static const struct snd_kcontrol_new adav80x_c    
343         SOC_DOUBLE_R_TLV("Master Playback Volu    
344                 ADAV80X_DAC_R_VOL, 0, 0xff, 0,    
345         SOC_DOUBLE_R_TLV("Master Capture Volum    
346                         ADAV80X_ADC_R_VOL, 0,     
347                                                   
348         SOC_DOUBLE_R_TLV("PGA Capture Volume",    
349                         ADAV80X_PGA_R_VOL, 0,     
350                                                   
351         SOC_DOUBLE("Master Playback Switch", A    
352         SOC_DOUBLE("Master Capture Switch", AD    
353                                                   
354         SOC_SINGLE("ADC High Pass Filter Switc    
355                                                   
356         SOC_SINGLE_BOOL_EXT("Playback De-empha    
357                         adav80x_get_deemph, ad    
358 };                                                
359                                                   
360 static unsigned int adav80x_port_ctrl_regs[2][    
361         { ADAV80X_REC_CTRL, ADAV80X_PLAYBACK_C    
362         { ADAV80X_AUX_OUT_CTRL, ADAV80X_AUX_IN    
363 };                                                
364                                                   
365 static int adav80x_set_dai_fmt(struct snd_soc_    
366 {                                                 
367         struct snd_soc_component *component =     
368         struct adav80x *adav80x = snd_soc_comp    
369         unsigned int capture = 0x00;              
370         unsigned int playback = 0x00;             
371                                                   
372         switch (fmt & SND_SOC_DAIFMT_CLOCK_PRO    
373         case SND_SOC_DAIFMT_CBP_CFP:              
374                 capture |= ADAV80X_CAPTURE_MOD    
375                 playback |= ADAV80X_PLAYBACK_M    
376                 break;                            
377         case SND_SOC_DAIFMT_CBC_CFC:              
378                 break;                            
379         default:                                  
380                 return -EINVAL;                   
381         }                                         
382                                                   
383         switch (fmt & SND_SOC_DAIFMT_FORMAT_MA    
384         case SND_SOC_DAIFMT_I2S:                  
385                 capture |= ADAV80X_CAPTURE_MOD    
386                 playback |= ADAV80X_PLAYBACK_M    
387                 break;                            
388         case SND_SOC_DAIFMT_LEFT_J:               
389                 capture |= ADAV80X_CAPTURE_MOD    
390                 playback |= ADAV80X_PLAYBACK_M    
391                 break;                            
392         case SND_SOC_DAIFMT_RIGHT_J:              
393                 capture |= ADAV80X_CAPTURE_MOD    
394                 playback |= ADAV80X_PLAYBACK_M    
395                 break;                            
396         default:                                  
397                 return -EINVAL;                   
398         }                                         
399                                                   
400         switch (fmt & SND_SOC_DAIFMT_INV_MASK)    
401         case SND_SOC_DAIFMT_NB_NF:                
402                 break;                            
403         default:                                  
404                 return -EINVAL;                   
405         }                                         
406                                                   
407         regmap_update_bits(adav80x->regmap, ad    
408                 ADAV80X_CAPTURE_MODE_MASK | AD    
409                 capture);                         
410         regmap_write(adav80x->regmap, adav80x_    
411                 playback);                        
412                                                   
413         adav80x->dai_fmt[dai->id] = fmt & SND_    
414                                                   
415         return 0;                                 
416 }                                                 
417                                                   
418 static int adav80x_set_adc_clock(struct snd_so    
419                 unsigned int sample_rate)         
420 {                                                 
421         struct adav80x *adav80x = snd_soc_comp    
422         unsigned int val;                         
423                                                   
424         if (sample_rate <= 48000)                 
425                 val = ADAV80X_ADC_CTRL1_MODULA    
426         else                                      
427                 val = ADAV80X_ADC_CTRL1_MODULA    
428                                                   
429         regmap_update_bits(adav80x->regmap, AD    
430                 ADAV80X_ADC_CTRL1_MODULATOR_MA    
431                                                   
432         return 0;                                 
433 }                                                 
434                                                   
435 static int adav80x_set_dac_clock(struct snd_so    
436                 unsigned int sample_rate)         
437 {                                                 
438         struct adav80x *adav80x = snd_soc_comp    
439         unsigned int val;                         
440                                                   
441         if (sample_rate <= 48000)                 
442                 val = ADAV80X_DAC_CTRL2_DIV1 |    
443         else                                      
444                 val = ADAV80X_DAC_CTRL2_DIV2 |    
445                                                   
446         regmap_update_bits(adav80x->regmap, AD    
447                 ADAV80X_DAC_CTRL2_DIV_MASK | A    
448                 val);                             
449                                                   
450         return 0;                                 
451 }                                                 
452                                                   
453 static int adav80x_set_capture_pcm_format(stru    
454                 struct snd_soc_dai *dai, struc    
455 {                                                 
456         struct adav80x *adav80x = snd_soc_comp    
457         unsigned int val;                         
458                                                   
459         switch (params_width(params)) {           
460         case 16:                                  
461                 val = ADAV80X_CAPTURE_WORD_LEN    
462                 break;                            
463         case 18:                                  
464                 val = ADAV80X_CAPTRUE_WORD_LEN    
465                 break;                            
466         case 20:                                  
467                 val = ADAV80X_CAPTURE_WORD_LEN    
468                 break;                            
469         case 24:                                  
470                 val = ADAV80X_CAPTURE_WORD_LEN    
471                 break;                            
472         default:                                  
473                 return -EINVAL;                   
474         }                                         
475                                                   
476         regmap_update_bits(adav80x->regmap, ad    
477                 ADAV80X_CAPTURE_WORD_LEN_MASK,    
478                                                   
479         return 0;                                 
480 }                                                 
481                                                   
482 static int adav80x_set_playback_pcm_format(str    
483                 struct snd_soc_dai *dai, struc    
484 {                                                 
485         struct adav80x *adav80x = snd_soc_comp    
486         unsigned int val;                         
487                                                   
488         if (adav80x->dai_fmt[dai->id] != SND_S    
489                 return 0;                         
490                                                   
491         switch (params_width(params)) {           
492         case 16:                                  
493                 val = ADAV80X_PLAYBACK_MODE_RI    
494                 break;                            
495         case 18:                                  
496                 val = ADAV80X_PLAYBACK_MODE_RI    
497                 break;                            
498         case 20:                                  
499                 val = ADAV80X_PLAYBACK_MODE_RI    
500                 break;                            
501         case 24:                                  
502                 val = ADAV80X_PLAYBACK_MODE_RI    
503                 break;                            
504         default:                                  
505                 return -EINVAL;                   
506         }                                         
507                                                   
508         regmap_update_bits(adav80x->regmap, ad    
509                 ADAV80X_PLAYBACK_MODE_MASK, va    
510                                                   
511         return 0;                                 
512 }                                                 
513                                                   
514 static int adav80x_hw_params(struct snd_pcm_su    
515                 struct snd_pcm_hw_params *para    
516 {                                                 
517         struct snd_soc_component *component =     
518         struct adav80x *adav80x = snd_soc_comp    
519         unsigned int rate = params_rate(params    
520                                                   
521         if (rate * 256 != adav80x->sysclk)        
522                 return -EINVAL;                   
523                                                   
524         if (substream->stream == SNDRV_PCM_STR    
525                 adav80x_set_playback_pcm_forma    
526                 adav80x_set_dac_clock(componen    
527         } else {                                  
528                 adav80x_set_capture_pcm_format    
529                 adav80x_set_adc_clock(componen    
530         }                                         
531         adav80x->rate = rate;                     
532         adav80x_set_deemph(component);            
533                                                   
534         return 0;                                 
535 }                                                 
536                                                   
537 static int adav80x_set_sysclk(struct snd_soc_c    
538                               int clk_id, int     
539                               unsigned int fre    
540 {                                                 
541         struct adav80x *adav80x = snd_soc_comp    
542         struct snd_soc_dapm_context *dapm = sn    
543                                                   
544         if (dir == SND_SOC_CLOCK_IN) {            
545                 switch (clk_id) {                 
546                 case ADAV80X_CLK_XIN:             
547                 case ADAV80X_CLK_XTAL:            
548                 case ADAV80X_CLK_MCLKI:           
549                 case ADAV80X_CLK_PLL1:            
550                 case ADAV80X_CLK_PLL2:            
551                         break;                    
552                 default:                          
553                         return -EINVAL;           
554                 }                                 
555                                                   
556                 adav80x->sysclk = freq;           
557                                                   
558                 if (adav80x->clk_src != clk_id    
559                         unsigned int iclk_ctrl    
560                                                   
561                         adav80x->clk_src = clk    
562                         if (clk_id == ADAV80X_    
563                                 clk_id = ADAV8    
564                                                   
565                         iclk_ctrl1 = ADAV80X_I    
566                                         ADAV80    
567                                         ADAV80    
568                         iclk_ctrl2 = ADAV80X_I    
569                                                   
570                         regmap_write(adav80x->    
571                                 iclk_ctrl1);      
572                         regmap_write(adav80x->    
573                                 iclk_ctrl2);      
574                                                   
575                         snd_soc_dapm_sync(dapm    
576                 }                                 
577         } else {                                  
578                 unsigned int mask;                
579                                                   
580                 switch (clk_id) {                 
581                 case ADAV80X_CLK_SYSCLK1:         
582                 case ADAV80X_CLK_SYSCLK2:         
583                 case ADAV80X_CLK_SYSCLK3:         
584                         break;                    
585                 default:                          
586                         return -EINVAL;           
587                 }                                 
588                                                   
589                 clk_id -= ADAV80X_CLK_SYSCLK1;    
590                 mask = ADAV80X_PLL_OUTE_SYSCLK    
591                                                   
592                 if (freq == 0) {                  
593                         regmap_update_bits(ada    
594                                 mask, mask);      
595                         adav80x->sysclk_pd[clk    
596                 } else {                          
597                         regmap_update_bits(ada    
598                                 mask, 0);         
599                         adav80x->sysclk_pd[clk    
600                 }                                 
601                                                   
602                 snd_soc_dapm_mutex_lock(dapm);    
603                                                   
604                 if (adav80x->sysclk_pd[0])        
605                         snd_soc_dapm_disable_p    
606                 else                              
607                         snd_soc_dapm_force_ena    
608                                                   
609                 if (adav80x->sysclk_pd[1] || a    
610                         snd_soc_dapm_disable_p    
611                 else                              
612                         snd_soc_dapm_force_ena    
613                                                   
614                 snd_soc_dapm_sync_unlocked(dap    
615                                                   
616                 snd_soc_dapm_mutex_unlock(dapm    
617         }                                         
618                                                   
619         return 0;                                 
620 }                                                 
621                                                   
622 static int adav80x_set_pll(struct snd_soc_comp    
623                 int source, unsigned int freq_    
624 {                                                 
625         struct snd_soc_dapm_context *dapm = sn    
626         struct adav80x *adav80x = snd_soc_comp    
627         unsigned int pll_ctrl1 = 0;               
628         unsigned int pll_ctrl2 = 0;               
629         unsigned int pll_src;                     
630                                                   
631         switch (source) {                         
632         case ADAV80X_PLL_SRC_XTAL:                
633         case ADAV80X_PLL_SRC_XIN:                 
634         case ADAV80X_PLL_SRC_MCLKI:               
635                 break;                            
636         default:                                  
637                 return -EINVAL;                   
638         }                                         
639                                                   
640         if (!freq_out)                            
641                 return 0;                         
642                                                   
643         switch (freq_in) {                        
644         case 27000000:                            
645                 break;                            
646         case 54000000:                            
647                 if (source == ADAV80X_PLL_SRC_    
648                         pll_ctrl1 |= ADAV80X_P    
649                         break;                    
650                 }                                 
651                 fallthrough;                      
652         default:                                  
653                 return -EINVAL;                   
654         }                                         
655                                                   
656         if (freq_out > 12288000) {                
657                 pll_ctrl2 |= ADAV80X_PLL_CTRL2    
658                 freq_out /= 2;                    
659         }                                         
660                                                   
661         /* freq_out = sample_rate * 256 */        
662         switch (freq_out) {                       
663         case 8192000:                             
664                 pll_ctrl2 |= ADAV80X_PLL_CTRL2    
665                 break;                            
666         case 11289600:                            
667                 pll_ctrl2 |= ADAV80X_PLL_CTRL2    
668                 break;                            
669         case 12288000:                            
670                 pll_ctrl2 |= ADAV80X_PLL_CTRL2    
671                 break;                            
672         default:                                  
673                 return -EINVAL;                   
674         }                                         
675                                                   
676         regmap_update_bits(adav80x->regmap, AD    
677                         ADAV80X_PLL_CTRL1_PLLD    
678         regmap_update_bits(adav80x->regmap, AD    
679                         ADAV80X_PLL_CTRL2_PLL_    
680                                                   
681         if (source != adav80x->pll_src) {         
682                 if (source == ADAV80X_PLL_SRC_    
683                         pll_src = ADAV80X_PLL_    
684                 else                              
685                         pll_src = ADAV80X_PLL_    
686                                                   
687                 regmap_update_bits(adav80x->re    
688                                 ADAV80X_PLL_CL    
689                                                   
690                 adav80x->pll_src = source;        
691                                                   
692                 snd_soc_dapm_sync(dapm);          
693         }                                         
694                                                   
695         return 0;                                 
696 }                                                 
697                                                   
698 static int adav80x_set_bias_level(struct snd_s    
699                 enum snd_soc_bias_level level)    
700 {                                                 
701         struct adav80x *adav80x = snd_soc_comp    
702         unsigned int mask = ADAV80X_DAC_CTRL1_    
703                                                   
704         switch (level) {                          
705         case SND_SOC_BIAS_ON:                     
706                 break;                            
707         case SND_SOC_BIAS_PREPARE:                
708                 break;                            
709         case SND_SOC_BIAS_STANDBY:                
710                 regmap_update_bits(adav80x->re    
711                         0x00);                    
712                 break;                            
713         case SND_SOC_BIAS_OFF:                    
714                 regmap_update_bits(adav80x->re    
715                         mask);                    
716                 break;                            
717         }                                         
718                                                   
719         return 0;                                 
720 }                                                 
721                                                   
722 /* Enforce the same sample rate on all audio i    
723 static int adav80x_dai_startup(struct snd_pcm_    
724         struct snd_soc_dai *dai)                  
725 {                                                 
726         struct snd_soc_component *component =     
727         struct adav80x *adav80x = snd_soc_comp    
728                                                   
729         if (!snd_soc_component_active(componen    
730                 return 0;                         
731                                                   
732         return snd_pcm_hw_constraint_single(su    
733                         SNDRV_PCM_HW_PARAM_RAT    
734 }                                                 
735                                                   
736 static void adav80x_dai_shutdown(struct snd_pc    
737                 struct snd_soc_dai *dai)          
738 {                                                 
739         struct snd_soc_component *component =     
740         struct adav80x *adav80x = snd_soc_comp    
741                                                   
742         if (!snd_soc_component_active(componen    
743                 adav80x->rate = 0;                
744 }                                                 
745                                                   
746 static const struct snd_soc_dai_ops adav80x_da    
747         .set_fmt = adav80x_set_dai_fmt,           
748         .hw_params = adav80x_hw_params,           
749         .startup = adav80x_dai_startup,           
750         .shutdown = adav80x_dai_shutdown,         
751 };                                                
752                                                   
753 #define ADAV80X_PLAYBACK_RATES (SNDRV_PCM_RATE    
754         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_    
755         SNDRV_PCM_RATE_96000)                     
756                                                   
757 #define ADAV80X_CAPTURE_RATES (SNDRV_PCM_RATE_    
758                                                   
759 #define ADAV80X_FORMATS (SNDRV_PCM_FMTBIT_S16_    
760         SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_F    
761                                                   
762 static struct snd_soc_dai_driver adav80x_dais[    
763         {                                         
764                 .name = "adav80x-hifi",           
765                 .id = 0,                          
766                 .playback = {                     
767                         .stream_name = "HiFi P    
768                         .channels_min = 2,        
769                         .channels_max = 2,        
770                         .rates = ADAV80X_PLAYB    
771                         .formats = ADAV80X_FOR    
772         },                                        
773                 .capture = {                      
774                         .stream_name = "HiFi C    
775                         .channels_min = 2,        
776                         .channels_max = 2,        
777                         .rates = ADAV80X_CAPTU    
778                         .formats = ADAV80X_FOR    
779                 },                                
780                 .ops = &adav80x_dai_ops,          
781         },                                        
782         {                                         
783                 .name = "adav80x-aux",            
784                 .id = 1,                          
785                 .playback = {                     
786                         .stream_name = "Aux Pl    
787                         .channels_min = 2,        
788                         .channels_max = 2,        
789                         .rates = ADAV80X_PLAYB    
790                         .formats = ADAV80X_FOR    
791                 },                                
792                 .capture = {                      
793                         .stream_name = "Aux Ca    
794                         .channels_min = 2,        
795                         .channels_max = 2,        
796                         .rates = ADAV80X_CAPTU    
797                         .formats = ADAV80X_FOR    
798                 },                                
799                 .ops = &adav80x_dai_ops,          
800         },                                        
801 };                                                
802                                                   
803 static int adav80x_probe(struct snd_soc_compon    
804 {                                                 
805         struct snd_soc_dapm_context *dapm = sn    
806         struct adav80x *adav80x = snd_soc_comp    
807                                                   
808         /* Force PLLs on for SYSCLK output */     
809         snd_soc_dapm_force_enable_pin(dapm, "P    
810         snd_soc_dapm_force_enable_pin(dapm, "P    
811                                                   
812         /* Power down S/PDIF receiver, since i    
813         regmap_write(adav80x->regmap, ADAV80X_    
814         /* Disable DAC zero flag */               
815         regmap_write(adav80x->regmap, ADAV80X_    
816                                                   
817         return 0;                                 
818 }                                                 
819                                                   
820 static int adav80x_resume(struct snd_soc_compo    
821 {                                                 
822         struct adav80x *adav80x = snd_soc_comp    
823                                                   
824         regcache_sync(adav80x->regmap);           
825                                                   
826         return 0;                                 
827 }                                                 
828                                                   
829 static const struct snd_soc_component_driver a    
830         .probe                  = adav80x_prob    
831         .resume                 = adav80x_resu    
832         .set_bias_level         = adav80x_set_    
833         .set_pll                = adav80x_set_    
834         .set_sysclk             = adav80x_set_    
835         .controls               = adav80x_cont    
836         .num_controls           = ARRAY_SIZE(a    
837         .dapm_widgets           = adav80x_dapm    
838         .num_dapm_widgets       = ARRAY_SIZE(a    
839         .dapm_routes            = adav80x_dapm    
840         .num_dapm_routes        = ARRAY_SIZE(a    
841         .suspend_bias_off       = 1,              
842         .idle_bias_on           = 1,              
843         .use_pmdown_time        = 1,              
844         .endianness             = 1,              
845 };                                                
846                                                   
847 int adav80x_bus_probe(struct device *dev, stru    
848 {                                                 
849         struct adav80x *adav80x;                  
850                                                   
851         if (IS_ERR(regmap))                       
852                 return PTR_ERR(regmap);           
853                                                   
854         adav80x = devm_kzalloc(dev, sizeof(*ad    
855         if (!adav80x)                             
856                 return -ENOMEM;                   
857                                                   
858         dev_set_drvdata(dev, adav80x);            
859         adav80x->regmap = regmap;                 
860                                                   
861         return devm_snd_soc_register_component    
862                 adav80x_dais, ARRAY_SIZE(adav8    
863 }                                                 
864 EXPORT_SYMBOL_GPL(adav80x_bus_probe);             
865                                                   
866 const struct regmap_config adav80x_regmap_conf    
867         .val_bits = 8,                            
868         .pad_bits = 1,                            
869         .reg_bits = 7,                            
870                                                   
871         .max_register = ADAV80X_PLL_OUTE,         
872                                                   
873         .cache_type = REGCACHE_MAPLE,             
874         .reg_defaults = adav80x_reg_defaults,     
875         .num_reg_defaults = ARRAY_SIZE(adav80x    
876 };                                                
877 EXPORT_SYMBOL_GPL(adav80x_regmap_config);         
878                                                   
879 MODULE_DESCRIPTION("ASoC ADAV80x driver");        
880 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafo    
881 MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");       
882 MODULE_LICENSE("GPL");                            
883                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php