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

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/cs35l56-shared.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/cs35l56-shared.c (Version linux-6.12-rc7) and /sound/soc/codecs/cs35l56-shared.c (Version linux-5.8.18)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 //                                                
  3 // Components shared between ASoC and HDA CS35    
  4 //                                                
  5 // Copyright (C) 2023 Cirrus Logic, Inc. and      
  6 //                    Cirrus Logic Internation    
  7                                                   
  8 #include <linux/array_size.h>                     
  9 #include <linux/firmware/cirrus/wmfw.h>           
 10 #include <linux/gpio/consumer.h>                  
 11 #include <linux/regmap.h>                         
 12 #include <linux/regulator/consumer.h>             
 13 #include <linux/types.h>                          
 14 #include <sound/cs-amp-lib.h>                     
 15                                                   
 16 #include "cs35l56.h"                              
 17                                                   
 18 static const struct reg_sequence cs35l56_patch    
 19         /*                                        
 20          * Firmware can change these to non-de    
 21          * Ensure that they are at known defau    
 22          */                                       
 23         { CS35L56_ASP1_ENABLES1,                  
 24         { CS35L56_ASP1_CONTROL1,                  
 25         { CS35L56_ASP1_CONTROL2,                  
 26         { CS35L56_ASP1_CONTROL3,                  
 27         { CS35L56_ASP1_FRAME_CONTROL1,            
 28         { CS35L56_ASP1_FRAME_CONTROL5,            
 29         { CS35L56_ASP1_DATA_CONTROL1,             
 30         { CS35L56_ASP1_DATA_CONTROL5,             
 31         { CS35L56_ASP1TX1_INPUT,                  
 32         { CS35L56_ASP1TX2_INPUT,                  
 33         { CS35L56_ASP1TX3_INPUT,                  
 34         { CS35L56_ASP1TX4_INPUT,                  
 35         { CS35L56_SWIRE_DP3_CH1_INPUT,            
 36         { CS35L56_SWIRE_DP3_CH2_INPUT,            
 37         { CS35L56_SWIRE_DP3_CH3_INPUT,            
 38         { CS35L56_SWIRE_DP3_CH4_INPUT,            
 39         { CS35L56_IRQ1_MASK_18,                   
 40                                                   
 41         /* These are not reset by a soft-reset    
 42         { CS35L56_MAIN_RENDER_USER_MUTE,          
 43         { CS35L56_MAIN_RENDER_USER_VOLUME,        
 44         { CS35L56_MAIN_POSTURE_NUMBER,            
 45 };                                                
 46                                                   
 47 int cs35l56_set_patch(struct cs35l56_base *cs3    
 48 {                                                 
 49         return regmap_register_patch(cs35l56_b    
 50                                      ARRAY_SIZ    
 51 }                                                 
 52 EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SO    
 53                                                   
 54 static const struct reg_default cs35l56_reg_de    
 55         /* no defaults for OTP_MEM - first rea    
 56                                                   
 57         { CS35L56_ASP1_ENABLES1,                  
 58         { CS35L56_ASP1_CONTROL1,                  
 59         { CS35L56_ASP1_CONTROL2,                  
 60         { CS35L56_ASP1_CONTROL3,                  
 61         { CS35L56_ASP1_FRAME_CONTROL1,            
 62         { CS35L56_ASP1_FRAME_CONTROL5,            
 63         { CS35L56_ASP1_DATA_CONTROL1,             
 64         { CS35L56_ASP1_DATA_CONTROL5,             
 65         { CS35L56_ASP1TX1_INPUT,                  
 66         { CS35L56_ASP1TX2_INPUT,                  
 67         { CS35L56_ASP1TX3_INPUT,                  
 68         { CS35L56_ASP1TX4_INPUT,                  
 69         { CS35L56_SWIRE_DP3_CH1_INPUT,            
 70         { CS35L56_SWIRE_DP3_CH2_INPUT,            
 71         { CS35L56_SWIRE_DP3_CH3_INPUT,            
 72         { CS35L56_SWIRE_DP3_CH4_INPUT,            
 73         { CS35L56_IRQ1_MASK_1,                    
 74         { CS35L56_IRQ1_MASK_2,                    
 75         { CS35L56_IRQ1_MASK_4,                    
 76         { CS35L56_IRQ1_MASK_8,                    
 77         { CS35L56_IRQ1_MASK_18,                   
 78         { CS35L56_IRQ1_MASK_20,                   
 79         { CS35L56_MAIN_RENDER_USER_MUTE,          
 80         { CS35L56_MAIN_RENDER_USER_VOLUME,        
 81         { CS35L56_MAIN_POSTURE_NUMBER,            
 82 };                                                
 83                                                   
 84 static bool cs35l56_is_dsp_memory(unsigned int    
 85 {                                                 
 86         switch (reg) {                            
 87         case CS35L56_DSP1_XMEM_PACKED_0 ... CS    
 88         case CS35L56_DSP1_XMEM_UNPACKED32_0 ..    
 89         case CS35L56_DSP1_XMEM_UNPACKED24_0 ..    
 90         case CS35L56_DSP1_YMEM_PACKED_0 ... CS    
 91         case CS35L56_DSP1_YMEM_UNPACKED32_0 ..    
 92         case CS35L56_DSP1_YMEM_UNPACKED24_0 ..    
 93         case CS35L56_DSP1_PMEM_0 ... CS35L56_D    
 94                 return true;                      
 95         default:                                  
 96                 return false;                     
 97         }                                         
 98 }                                                 
 99                                                   
100 static bool cs35l56_readable_reg(struct device    
101 {                                                 
102         switch (reg) {                            
103         case CS35L56_DEVID:                       
104         case CS35L56_REVID:                       
105         case CS35L56_RELID:                       
106         case CS35L56_OTPID:                       
107         case CS35L56_SFT_RESET:                   
108         case CS35L56_GLOBAL_ENABLES:              
109         case CS35L56_BLOCK_ENABLES:               
110         case CS35L56_BLOCK_ENABLES2:              
111         case CS35L56_REFCLK_INPUT:                
112         case CS35L56_GLOBAL_SAMPLE_RATE:          
113         case CS35L56_OTP_MEM_53:                  
114         case CS35L56_OTP_MEM_54:                  
115         case CS35L56_OTP_MEM_55:                  
116         case CS35L56_ASP1_ENABLES1:               
117         case CS35L56_ASP1_CONTROL1:               
118         case CS35L56_ASP1_CONTROL2:               
119         case CS35L56_ASP1_CONTROL3:               
120         case CS35L56_ASP1_FRAME_CONTROL1:         
121         case CS35L56_ASP1_FRAME_CONTROL5:         
122         case CS35L56_ASP1_DATA_CONTROL1:          
123         case CS35L56_ASP1_DATA_CONTROL5:          
124         case CS35L56_DACPCM1_INPUT:               
125         case CS35L56_DACPCM2_INPUT:               
126         case CS35L56_ASP1TX1_INPUT:               
127         case CS35L56_ASP1TX2_INPUT:               
128         case CS35L56_ASP1TX3_INPUT:               
129         case CS35L56_ASP1TX4_INPUT:               
130         case CS35L56_DSP1RX1_INPUT:               
131         case CS35L56_DSP1RX2_INPUT:               
132         case CS35L56_SWIRE_DP3_CH1_INPUT:         
133         case CS35L56_SWIRE_DP3_CH2_INPUT:         
134         case CS35L56_SWIRE_DP3_CH3_INPUT:         
135         case CS35L56_SWIRE_DP3_CH4_INPUT:         
136         case CS35L56_IRQ1_CFG:                    
137         case CS35L56_IRQ1_STATUS:                 
138         case CS35L56_IRQ1_EINT_1 ... CS35L56_I    
139         case CS35L56_IRQ1_EINT_18:                
140         case CS35L56_IRQ1_EINT_20:                
141         case CS35L56_IRQ1_MASK_1:                 
142         case CS35L56_IRQ1_MASK_2:                 
143         case CS35L56_IRQ1_MASK_4:                 
144         case CS35L56_IRQ1_MASK_8:                 
145         case CS35L56_IRQ1_MASK_18:                
146         case CS35L56_IRQ1_MASK_20:                
147         case CS35L56_DSP_VIRTUAL1_MBOX_1:         
148         case CS35L56_DSP_VIRTUAL1_MBOX_2:         
149         case CS35L56_DSP_VIRTUAL1_MBOX_3:         
150         case CS35L56_DSP_VIRTUAL1_MBOX_4:         
151         case CS35L56_DSP_VIRTUAL1_MBOX_5:         
152         case CS35L56_DSP_VIRTUAL1_MBOX_6:         
153         case CS35L56_DSP_VIRTUAL1_MBOX_7:         
154         case CS35L56_DSP_VIRTUAL1_MBOX_8:         
155         case CS35L56_DSP_RESTRICT_STS1:           
156         case CS35L56_DSP1_SYS_INFO_ID ... CS35    
157         case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:    
158         case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:    
159         case CS35L56_DSP1_SCRATCH1:               
160         case CS35L56_DSP1_SCRATCH2:               
161         case CS35L56_DSP1_SCRATCH3:               
162         case CS35L56_DSP1_SCRATCH4:               
163                 return true;                      
164         default:                                  
165                 return cs35l56_is_dsp_memory(r    
166         }                                         
167 }                                                 
168                                                   
169 static bool cs35l56_precious_reg(struct device    
170 {                                                 
171         switch (reg) {                            
172         case CS35L56_DSP1_XMEM_PACKED_0 ... CS    
173         case CS35L56_DSP1_YMEM_PACKED_0 ... CS    
174         case CS35L56_DSP1_PMEM_0 ... CS35L56_D    
175                 return true;                      
176         default:                                  
177                 return false;                     
178         }                                         
179 }                                                 
180                                                   
181 static bool cs35l56_volatile_reg(struct device    
182 {                                                 
183         switch (reg) {                            
184         case CS35L56_DEVID:                       
185         case CS35L56_REVID:                       
186         case CS35L56_RELID:                       
187         case CS35L56_OTPID:                       
188         case CS35L56_SFT_RESET:                   
189         case CS35L56_GLOBAL_ENABLES:              
190         case CS35L56_BLOCK_ENABLES:               
191         case CS35L56_BLOCK_ENABLES2:              
192         case CS35L56_REFCLK_INPUT:                
193         case CS35L56_GLOBAL_SAMPLE_RATE:          
194         case CS35L56_DACPCM1_INPUT:               
195         case CS35L56_DACPCM2_INPUT:               
196         case CS35L56_DSP1RX1_INPUT:               
197         case CS35L56_DSP1RX2_INPUT:               
198         case CS35L56_IRQ1_STATUS:                 
199         case CS35L56_IRQ1_EINT_1 ... CS35L56_I    
200         case CS35L56_IRQ1_EINT_18:                
201         case CS35L56_IRQ1_EINT_20:                
202         case CS35L56_DSP_VIRTUAL1_MBOX_1:         
203         case CS35L56_DSP_VIRTUAL1_MBOX_2:         
204         case CS35L56_DSP_VIRTUAL1_MBOX_3:         
205         case CS35L56_DSP_VIRTUAL1_MBOX_4:         
206         case CS35L56_DSP_VIRTUAL1_MBOX_5:         
207         case CS35L56_DSP_VIRTUAL1_MBOX_6:         
208         case CS35L56_DSP_VIRTUAL1_MBOX_7:         
209         case CS35L56_DSP_VIRTUAL1_MBOX_8:         
210         case CS35L56_DSP_RESTRICT_STS1:           
211         case CS35L56_DSP1_SYS_INFO_ID ... CS35    
212         case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:    
213         case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:    
214         case CS35L56_DSP1_SCRATCH1:               
215         case CS35L56_DSP1_SCRATCH2:               
216         case CS35L56_DSP1_SCRATCH3:               
217         case CS35L56_DSP1_SCRATCH4:               
218                 return true;                      
219         case CS35L56_MAIN_RENDER_USER_MUTE:       
220         case CS35L56_MAIN_RENDER_USER_VOLUME:     
221         case CS35L56_MAIN_POSTURE_NUMBER:         
222                 return false;                     
223         default:                                  
224                 return cs35l56_is_dsp_memory(r    
225         }                                         
226 }                                                 
227                                                   
228 int cs35l56_mbox_send(struct cs35l56_base *cs3    
229 {                                                 
230         unsigned int val;                         
231         int ret;                                  
232                                                   
233         regmap_write(cs35l56_base->regmap, CS3    
234         ret = regmap_read_poll_timeout(cs35l56    
235                                        val, (v    
236                                        CS35L56    
237         if (ret) {                                
238                 dev_warn(cs35l56_base->dev, "M    
239                 return ret;                       
240         }                                         
241                                                   
242         return 0;                                 
243 }                                                 
244 EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send, SND_SO    
245                                                   
246 int cs35l56_firmware_shutdown(struct cs35l56_b    
247 {                                                 
248         int ret;                                  
249         unsigned int val;                         
250                                                   
251         ret = cs35l56_mbox_send(cs35l56_base,     
252         if (ret)                                  
253                 return ret;                       
254                                                   
255         ret = regmap_read_poll_timeout(cs35l56    
256                                        val, (v    
257                                        CS35L56    
258                                        CS35L56    
259         if (ret < 0)                              
260                 dev_err(cs35l56_base->dev, "Fa    
261                         val, ret);                
262         return ret;                               
263 }                                                 
264 EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown    
265                                                   
266 int cs35l56_wait_for_firmware_boot(struct cs35    
267 {                                                 
268         unsigned int val = 0;                     
269         int read_ret, poll_ret;                   
270                                                   
271         /*                                        
272          * The regmap must remain in cache-onl    
273          * booted, so use a bypassed read of t    
274          */                                       
275         poll_ret = read_poll_timeout(regmap_re    
276                                      (val < 0x    
277                                      CS35L56_H    
278                                      CS35L56_H    
279                                      false,       
280                                      cs35l56_b    
281                                                   
282         if (poll_ret) {                           
283                 dev_err(cs35l56_base->dev, "Fi    
284                         read_ret, val);           
285                 return -EIO;                      
286         }                                         
287                                                   
288         return 0;                                 
289 }                                                 
290 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware    
291                                                   
292 void cs35l56_wait_control_port_ready(void)        
293 {                                                 
294         /* Wait for control port to be ready (    
295         usleep_range(CS35L56_CONTROL_PORT_READ    
296 }                                                 
297 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port    
298                                                   
299 void cs35l56_wait_min_reset_pulse(void)           
300 {                                                 
301         /* Satisfy minimum reset pulse width s    
302         usleep_range(CS35L56_RESET_PULSE_MIN_U    
303 }                                                 
304 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pu    
305                                                   
306 static const struct reg_sequence cs35l56_syste    
307         REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0),     
308         REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1,     
309 };                                                
310                                                   
311 void cs35l56_system_reset(struct cs35l56_base     
312 {                                                 
313         /*                                        
314          * Must enter cache-only first so ther    
315          * accesses other than the controlled     
316          */                                       
317         regcache_cache_only(cs35l56_base->regm    
318         regmap_multi_reg_write_bypassed(cs35l5    
319                                         cs35l5    
320                                         ARRAY_    
321                                                   
322         /* On SoundWire the registers won't be    
323         if (is_soundwire)                         
324                 return;                           
325                                                   
326         cs35l56_wait_control_port_ready();        
327                                                   
328         /* Leave in cache-only. This will be r    
329 }                                                 
330 EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, SND    
331                                                   
332 int cs35l56_irq_request(struct cs35l56_base *c    
333 {                                                 
334         int ret;                                  
335                                                   
336         if (irq < 1)                              
337                 return 0;                         
338                                                   
339         ret = devm_request_threaded_irq(cs35l5    
340                                         IRQF_O    
341                                         "cs35l    
342         if (!ret)                                 
343                 cs35l56_base->irq = irq;          
344         else                                      
345                 dev_err(cs35l56_base->dev, "Fa    
346                                                   
347         return ret;                               
348 }                                                 
349 EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_    
350                                                   
351 irqreturn_t cs35l56_irq(int irq, void *data)      
352 {                                                 
353         struct cs35l56_base *cs35l56_base = da    
354         unsigned int status1 = 0, status8 = 0,    
355         unsigned int mask1, mask8, mask20;        
356         unsigned int val;                         
357         int rv;                                   
358                                                   
359         irqreturn_t ret = IRQ_NONE;               
360                                                   
361         if (!cs35l56_base->init_done)             
362                 return IRQ_NONE;                  
363                                                   
364         mutex_lock(&cs35l56_base->irq_lock);      
365                                                   
366         rv = pm_runtime_resume_and_get(cs35l56    
367         if (rv < 0) {                             
368                 dev_err(cs35l56_base->dev, "ir    
369                 goto err_unlock;                  
370         }                                         
371                                                   
372         regmap_read(cs35l56_base->regmap, CS35    
373         if ((val & CS35L56_IRQ1_STS_MASK) == 0    
374                 dev_dbg(cs35l56_base->dev, "Sp    
375                 goto err;                         
376         }                                         
377                                                   
378         /* Ack interrupts */                      
379         regmap_read(cs35l56_base->regmap, CS35    
380         regmap_read(cs35l56_base->regmap, CS35    
381         status1 &= ~mask1;                        
382         regmap_write(cs35l56_base->regmap, CS3    
383                                                   
384         regmap_read(cs35l56_base->regmap, CS35    
385         regmap_read(cs35l56_base->regmap, CS35    
386         status8 &= ~mask8;                        
387         regmap_write(cs35l56_base->regmap, CS3    
388                                                   
389         regmap_read(cs35l56_base->regmap, CS35    
390         regmap_read(cs35l56_base->regmap, CS35    
391         status20 &= ~mask20;                      
392         /* We don't want EINT20 but they defau    
393         regmap_write(cs35l56_base->regmap, CS3    
394                                                   
395         dev_dbg(cs35l56_base->dev, "%s: %#x %#    
396                                                   
397         /* Check to see if unmasked bits are a    
398         if (!status1 && !status8 && !status20)    
399                 goto err;                         
400                                                   
401         if (status1 & CS35L56_AMP_SHORT_ERR_EI    
402                 dev_crit(cs35l56_base->dev, "A    
403                                                   
404         if (status8 & CS35L56_TEMP_ERR_EINT1_M    
405                 dev_crit(cs35l56_base->dev, "O    
406                                                   
407         ret = IRQ_HANDLED;                        
408                                                   
409 err:                                              
410         pm_runtime_put(cs35l56_base->dev);        
411 err_unlock:                                       
412         mutex_unlock(&cs35l56_base->irq_lock);    
413                                                   
414         return ret;                               
415 }                                                 
416 EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35    
417                                                   
418 int cs35l56_is_fw_reload_needed(struct cs35l56    
419 {                                                 
420         unsigned int val;                         
421         int ret;                                  
422                                                   
423         /*                                        
424          * In secure mode FIRMWARE_MISSING is     
425          * can't be used here to test for memo    
426          * Assume that tuning must be re-loade    
427          */                                       
428         if (cs35l56_base->secured)                
429                 return true;                      
430                                                   
431         ret = pm_runtime_resume_and_get(cs35l5    
432         if (ret) {                                
433                 dev_err(cs35l56_base->dev, "Fa    
434                 return ret;                       
435         }                                         
436                                                   
437         ret = regmap_read(cs35l56_base->regmap    
438         if (ret)                                  
439                 dev_err(cs35l56_base->dev, "Fa    
440         else                                      
441                 ret = !!(val & CS35L56_FIRMWAR    
442                                                   
443         pm_runtime_put_autosuspend(cs35l56_bas    
444                                                   
445         return ret;                               
446 }                                                 
447 EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_need    
448                                                   
449 static const struct reg_sequence cs35l56_hiber    
450         /* This must be the last register acce    
451         REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1,     
452 };                                                
453                                                   
454 static void cs35l56_issue_wake_event(struct cs    
455 {                                                 
456         unsigned int val;                         
457                                                   
458         /*                                        
459          * Dummy transactions to trigger I2C/S    
460          * transactions to meet the minimum re    
461          * to the last falling edge of wake.      
462          *                                        
463          * It uses bypassed read because we mu    
464          * disabling regmap cache-only.           
465          */                                       
466         regmap_read_bypassed(cs35l56_base->reg    
467                                                   
468         usleep_range(CS35L56_WAKE_HOLD_TIME_US    
469                                                   
470         regmap_read_bypassed(cs35l56_base->reg    
471                                                   
472         cs35l56_wait_control_port_ready();        
473 }                                                 
474                                                   
475 int cs35l56_runtime_suspend_common(struct cs35    
476 {                                                 
477         unsigned int val;                         
478         int ret;                                  
479                                                   
480         if (!cs35l56_base->init_done)             
481                 return 0;                         
482                                                   
483         /* Firmware must have entered a power-    
484         ret = regmap_read_poll_timeout(cs35l56    
485                                        CS35L56    
486                                        val, (v    
487                                        CS35L56    
488                                        CS35L56    
489         if (ret)                                  
490                 dev_warn(cs35l56_base->dev, "P    
491                                                   
492         /* Clear BOOT_DONE so it can be used t    
493         regmap_write(cs35l56_base->regmap, CS3    
494                                                   
495         if (!cs35l56_base->can_hibernate) {       
496                 regcache_cache_only(cs35l56_ba    
497                 dev_dbg(cs35l56_base->dev, "Su    
498                                                   
499                 return 0;                         
500         }                                         
501                                                   
502         /*                                        
503          * Must enter cache-only first so ther    
504          * accesses other than the controlled     
505          */                                       
506         regcache_cache_only(cs35l56_base->regm    
507                                                   
508         regmap_multi_reg_write_bypassed(cs35l5    
509                                         cs35l5    
510                                         ARRAY_    
511                                                   
512         dev_dbg(cs35l56_base->dev, "Suspended:    
513                                                   
514         return 0;                                 
515 }                                                 
516 EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_c    
517                                                   
518 int cs35l56_runtime_resume_common(struct cs35l    
519 {                                                 
520         unsigned int val;                         
521         int ret;                                  
522                                                   
523         if (!cs35l56_base->init_done)             
524                 return 0;                         
525                                                   
526         if (!cs35l56_base->can_hibernate)         
527                 goto out_sync;                    
528                                                   
529         /* Must be done before releasing cache    
530         if (!is_soundwire)                        
531                 cs35l56_issue_wake_event(cs35l    
532                                                   
533 out_sync:                                         
534         ret = cs35l56_wait_for_firmware_boot(c    
535         if (ret) {                                
536                 dev_err(cs35l56_base->dev, "Hi    
537                 goto err;                         
538         }                                         
539                                                   
540         regcache_cache_only(cs35l56_base->regm    
541                                                   
542         ret = cs35l56_mbox_send(cs35l56_base,     
543         if (ret)                                  
544                 goto err;                         
545                                                   
546         /* BOOT_DONE will be 1 if the amp rese    
547         regmap_read(cs35l56_base->regmap, CS35    
548         if (val & CS35L56_OTP_BOOT_DONE_MASK)     
549                 dev_dbg(cs35l56_base->dev, "Re    
550                 regcache_mark_dirty(cs35l56_ba    
551         }                                         
552                                                   
553         regcache_sync(cs35l56_base->regmap);      
554                                                   
555         dev_dbg(cs35l56_base->dev, "Resumed");    
556                                                   
557         return 0;                                 
558                                                   
559 err:                                              
560         regcache_cache_only(cs35l56_base->regm    
561                                                   
562         regmap_multi_reg_write_bypassed(cs35l5    
563                                         cs35l5    
564                                         ARRAY_    
565                                                   
566         return ret;                               
567 }                                                 
568 EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_co    
569                                                   
570 static const struct cs_dsp_region cs35l56_dsp1    
571         { .type = WMFW_HALO_PM_PACKED,  .base     
572         { .type = WMFW_HALO_XM_PACKED,  .base     
573         { .type = WMFW_HALO_YM_PACKED,  .base     
574         { .type = WMFW_ADSP2_XM,        .base     
575         { .type = WMFW_ADSP2_YM,        .base     
576 };                                                
577                                                   
578 void cs35l56_init_cs_dsp(struct cs35l56_base *    
579 {                                                 
580         cs_dsp->num = 1;                          
581         cs_dsp->type = WMFW_HALO;                 
582         cs_dsp->rev = 0;                          
583         cs_dsp->dev = cs35l56_base->dev;          
584         cs_dsp->regmap = cs35l56_base->regmap;    
585         cs_dsp->base = CS35L56_DSP1_CORE_BASE;    
586         cs_dsp->base_sysinfo = CS35L56_DSP1_SY    
587         cs_dsp->mem = cs35l56_dsp1_regions;       
588         cs_dsp->num_mems = ARRAY_SIZE(cs35l56_    
589         cs_dsp->no_core_startstop = true;         
590 }                                                 
591 EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, SND_    
592                                                   
593 struct cs35l56_pte {                              
594         u8 x;                                     
595         u8 wafer_id;                              
596         u8 pte[2];                                
597         u8 lot[3];                                
598         u8 y;                                     
599         u8 unused[3];                             
600         u8 dvs;                                   
601 } __packed;                                       
602 static_assert((sizeof(struct cs35l56_pte) % si    
603                                                   
604 static int cs35l56_read_silicon_uid(struct cs3    
605 {                                                 
606         struct cs35l56_pte pte;                   
607         u64 unique_id;                            
608         int ret;                                  
609                                                   
610         ret = regmap_raw_read(cs35l56_base->re    
611         if (ret) {                                
612                 dev_err(cs35l56_base->dev, "Fa    
613                 return ret;                       
614         }                                         
615                                                   
616         unique_id = (u32)pte.lot[2] | ((u32)pt    
617         unique_id <<= 32;                         
618         unique_id |= (u32)pte.x | ((u32)pte.y     
619                      ((u32)pte.dvs << 24);        
620                                                   
621         dev_dbg(cs35l56_base->dev, "UniqueID =    
622                                                   
623         *uid = unique_id;                         
624                                                   
625         return 0;                                 
626 }                                                 
627                                                   
628 /* Firmware calibration controls */               
629 const struct cirrus_amp_cal_controls cs35l56_c    
630         .alg_id =       0x9f210,                  
631         .mem_region =   WMFW_ADSP2_YM,            
632         .ambient =      "CAL_AMBIENT",            
633         .calr =         "CAL_R",                  
634         .status =       "CAL_STATUS",             
635         .checksum =     "CAL_CHECKSUM",           
636 };                                                
637 EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_contr    
638                                                   
639 int cs35l56_get_calibration(struct cs35l56_bas    
640 {                                                 
641         u64 silicon_uid = 0;                      
642         int ret;                                  
643                                                   
644         /* Driver can't apply calibration to a    
645         if (cs35l56_base->secured)                
646                 return 0;                         
647                                                   
648         ret = cs35l56_read_silicon_uid(cs35l56    
649         if (ret < 0)                              
650                 return ret;                       
651                                                   
652         ret = cs_amp_get_efi_calibration_data(    
653                                                   
654                                                   
655                                                   
656         /* Only return an error status if prob    
657         if ((ret == -ENOENT) || (ret == -EOVER    
658                 return 0;                         
659                                                   
660         if (ret < 0)                              
661                 return ret;                       
662                                                   
663         cs35l56_base->cal_data_valid = true;      
664                                                   
665         return 0;                                 
666 }                                                 
667 EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration,     
668                                                   
669 int cs35l56_read_prot_status(struct cs35l56_ba    
670                              bool *fw_missing,    
671 {                                                 
672         unsigned int prot_status;                 
673         int ret;                                  
674                                                   
675         ret = regmap_read(cs35l56_base->regmap    
676         if (ret) {                                
677                 dev_err(cs35l56_base->dev, "Ge    
678                 return ret;                       
679         }                                         
680                                                   
681         *fw_missing = !!(prot_status & CS35L56    
682                                                   
683         ret = regmap_read(cs35l56_base->regmap    
684         if (ret) {                                
685                 dev_err(cs35l56_base->dev, "Ge    
686                 return ret;                       
687         }                                         
688                                                   
689         return 0;                                 
690 }                                                 
691 EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status,    
692                                                   
693 int cs35l56_hw_init(struct cs35l56_base *cs35l    
694 {                                                 
695         int ret;                                  
696         unsigned int devid, revid, otpid, secu    
697         bool fw_missing;                          
698                                                   
699         /*                                        
700          * When the system is not using a rese    
701          * awake, otherwise the device has jus    
702          * the driver must wait for the contro    
703          */                                       
704         if (!cs35l56_base->reset_gpio)            
705                 cs35l56_issue_wake_event(cs35l    
706         else                                      
707                 cs35l56_wait_control_port_read    
708                                                   
709         ret = regmap_read_bypassed(cs35l56_bas    
710         if (ret < 0) {                            
711                 dev_err(cs35l56_base->dev, "Ge    
712                 return ret;                       
713         }                                         
714         cs35l56_base->rev = revid & (CS35L56_A    
715                                                   
716         ret = cs35l56_wait_for_firmware_boot(c    
717         if (ret)                                  
718                 return ret;                       
719                                                   
720         ret = regmap_read_bypassed(cs35l56_bas    
721         if (ret < 0) {                            
722                 dev_err(cs35l56_base->dev, "Ge    
723                 return ret;                       
724         }                                         
725         devid &= CS35L56_DEVID_MASK;              
726                                                   
727         switch (devid) {                          
728         case 0x35A54:                             
729         case 0x35A56:                             
730         case 0x35A57:                             
731                 break;                            
732         default:                                  
733                 dev_err(cs35l56_base->dev, "Un    
734                 return ret;                       
735         }                                         
736                                                   
737         cs35l56_base->type = devid & 0xFF;        
738                                                   
739         /* Silicon is now identified and boote    
740         regcache_cache_only(cs35l56_base->regm    
741                                                   
742         ret = regmap_read(cs35l56_base->regmap    
743         if (ret) {                                
744                 dev_err(cs35l56_base->dev, "Ge    
745                 return ret;                       
746         }                                         
747                                                   
748         /* When any bus is restricted treat th    
749         if (secured & CS35L56_RESTRICTED_MASK)    
750                 cs35l56_base->secured = true;     
751                                                   
752         ret = regmap_read(cs35l56_base->regmap    
753         if (ret < 0) {                            
754                 dev_err(cs35l56_base->dev, "Ge    
755                 return ret;                       
756         }                                         
757                                                   
758         ret = cs35l56_read_prot_status(cs35l56    
759         if (ret)                                  
760                 return ret;                       
761                                                   
762         dev_info(cs35l56_base->dev, "Cirrus Lo    
763                  cs35l56_base->type, cs35l56_b    
764                  fw_ver >> 16, (fw_ver >> 8) &    
765                                                   
766         /* Wake source and *_BLOCKED interrupt    
767         regmap_write(cs35l56_base->regmap, CS3    
768         regmap_update_bits(cs35l56_base->regma    
769                            CS35L56_AMP_SHORT_E    
770                            0);                    
771         regmap_update_bits(cs35l56_base->regma    
772                            CS35L56_TEMP_ERR_EI    
773                            0);                    
774                                                   
775         return 0;                                 
776 }                                                 
777 EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, SND_SOC_    
778                                                   
779 int cs35l56_get_speaker_id(struct cs35l56_base    
780 {                                                 
781         struct gpio_descs *descs;                 
782         u32 speaker_id;                           
783         int i, ret;                               
784                                                   
785         /* Attempt to read the speaker type fr    
786         ret = device_property_read_u32(cs35l56    
787         if (!ret) {                               
788                 dev_dbg(cs35l56_base->dev, "Sp    
789                 return speaker_id;                
790         }                                         
791                                                   
792         /* Read the speaker type qualifier fro    
793         descs = gpiod_get_array_optional(cs35l    
794         if (!descs) {                             
795                 return -ENOENT;                   
796         } else if (IS_ERR(descs)) {               
797                 ret = PTR_ERR(descs);             
798                 return dev_err_probe(cs35l56_b    
799         }                                         
800                                                   
801         speaker_id = 0;                           
802         for (i = 0; i < descs->ndescs; i++) {     
803                 ret = gpiod_get_value_cansleep    
804                 if (ret < 0) {                    
805                         dev_err_probe(cs35l56_    
806                         goto err;                 
807                 }                                 
808                                                   
809                 speaker_id |= (ret << i);         
810         }                                         
811                                                   
812         dev_dbg(cs35l56_base->dev, "Speaker ID    
813         ret = speaker_id;                         
814 err:                                              
815         gpiod_put_array(descs);                   
816                                                   
817         return ret;                               
818 }                                                 
819 EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, S    
820                                                   
821 static const u32 cs35l56_bclk_valid_for_pll_fr    
822         [0x0C] = 128000,                          
823         [0x0F] = 256000,                          
824         [0x11] = 384000,                          
825         [0x12] = 512000,                          
826         [0x15] = 768000,                          
827         [0x17] = 1024000,                         
828         [0x1A] = 1500000,                         
829         [0x1B] = 1536000,                         
830         [0x1C] = 2000000,                         
831         [0x1D] = 2048000,                         
832         [0x1E] = 2400000,                         
833         [0x20] = 3000000,                         
834         [0x21] = 3072000,                         
835         [0x23] = 4000000,                         
836         [0x24] = 4096000,                         
837         [0x25] = 4800000,                         
838         [0x27] = 6000000,                         
839         [0x28] = 6144000,                         
840         [0x29] = 6250000,                         
841         [0x2A] = 6400000,                         
842         [0x2E] = 8000000,                         
843         [0x2F] = 8192000,                         
844         [0x30] = 9600000,                         
845         [0x32] = 12000000,                        
846         [0x33] = 12288000,                        
847         [0x37] = 13500000,                        
848         [0x38] = 19200000,                        
849         [0x39] = 22579200,                        
850         [0x3B] = 24576000,                        
851 };                                                
852                                                   
853 int cs35l56_get_bclk_freq_id(unsigned int freq    
854 {                                                 
855         int i;                                    
856                                                   
857         if (freq == 0)                            
858                 return -EINVAL;                   
859                                                   
860         /* The BCLK frequency must be a valid     
861         for (i = 0; i < ARRAY_SIZE(cs35l56_bcl    
862                 if (cs35l56_bclk_valid_for_pll    
863                         return i;                 
864         }                                         
865                                                   
866         return -EINVAL;                           
867 }                                                 
868 EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id,    
869                                                   
870 static const char * const cs35l56_supplies[/*     
871         "VDD_P",                                  
872         "VDD_IO",                                 
873         "VDD_A",                                  
874 };                                                
875                                                   
876 void cs35l56_fill_supply_names(struct regulato    
877 {                                                 
878         int i;                                    
879                                                   
880         BUILD_BUG_ON(ARRAY_SIZE(cs35l56_suppli    
881         for (i = 0; i < ARRAY_SIZE(cs35l56_sup    
882                 data[i].supply = cs35l56_suppl    
883 }                                                 
884 EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names    
885                                                   
886 const char * const cs35l56_tx_input_texts[] =     
887         "None", "ASP1RX1", "ASP1RX2", "VMON",     
888         "VDDBMON", "VBSTMON", "DSP1TX1", "DSP1    
889         "DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1    
890         "INTERPOLATOR", "SDW1RX1", "SDW1RX2",     
891 };                                                
892 EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, S    
893                                                   
894 const unsigned int cs35l56_tx_input_values[] =    
895         CS35L56_INPUT_SRC_NONE,                   
896         CS35L56_INPUT_SRC_ASP1RX1,                
897         CS35L56_INPUT_SRC_ASP1RX2,                
898         CS35L56_INPUT_SRC_VMON,                   
899         CS35L56_INPUT_SRC_IMON,                   
900         CS35L56_INPUT_SRC_ERR_VOL,                
901         CS35L56_INPUT_SRC_CLASSH,                 
902         CS35L56_INPUT_SRC_VDDBMON,                
903         CS35L56_INPUT_SRC_VBSTMON,                
904         CS35L56_INPUT_SRC_DSP1TX1,                
905         CS35L56_INPUT_SRC_DSP1TX2,                
906         CS35L56_INPUT_SRC_DSP1TX3,                
907         CS35L56_INPUT_SRC_DSP1TX4,                
908         CS35L56_INPUT_SRC_DSP1TX5,                
909         CS35L56_INPUT_SRC_DSP1TX6,                
910         CS35L56_INPUT_SRC_DSP1TX7,                
911         CS35L56_INPUT_SRC_DSP1TX8,                
912         CS35L56_INPUT_SRC_TEMPMON,                
913         CS35L56_INPUT_SRC_INTERPOLATOR,           
914         CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1,     
915         CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2,     
916 };                                                
917 EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values,     
918                                                   
919 const struct regmap_config cs35l56_regmap_i2c     
920         .reg_bits = 32,                           
921         .val_bits = 32,                           
922         .reg_stride = 4,                          
923         .reg_format_endian = REGMAP_ENDIAN_BIG    
924         .val_format_endian = REGMAP_ENDIAN_BIG    
925         .max_register = CS35L56_DSP1_PMEM_5114    
926         .reg_defaults = cs35l56_reg_defaults,     
927         .num_reg_defaults = ARRAY_SIZE(cs35l56    
928         .volatile_reg = cs35l56_volatile_reg,     
929         .readable_reg = cs35l56_readable_reg,     
930         .precious_reg = cs35l56_precious_reg,     
931         .cache_type = REGCACHE_MAPLE,             
932 };                                                
933 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_S    
934                                                   
935 const struct regmap_config cs35l56_regmap_spi     
936         .reg_bits = 32,                           
937         .val_bits = 32,                           
938         .pad_bits = 16,                           
939         .reg_stride = 4,                          
940         .reg_format_endian = REGMAP_ENDIAN_BIG    
941         .val_format_endian = REGMAP_ENDIAN_BIG    
942         .max_register = CS35L56_DSP1_PMEM_5114    
943         .reg_defaults = cs35l56_reg_defaults,     
944         .num_reg_defaults = ARRAY_SIZE(cs35l56    
945         .volatile_reg = cs35l56_volatile_reg,     
946         .readable_reg = cs35l56_readable_reg,     
947         .precious_reg = cs35l56_precious_reg,     
948         .cache_type = REGCACHE_MAPLE,             
949 };                                                
950 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_S    
951                                                   
952 const struct regmap_config cs35l56_regmap_sdw     
953         .reg_bits = 32,                           
954         .val_bits = 32,                           
955         .reg_stride = 4,                          
956         .reg_format_endian = REGMAP_ENDIAN_LIT    
957         .val_format_endian = REGMAP_ENDIAN_BIG    
958         .max_register = CS35L56_DSP1_PMEM_5114    
959         .reg_defaults = cs35l56_reg_defaults,     
960         .num_reg_defaults = ARRAY_SIZE(cs35l56    
961         .volatile_reg = cs35l56_volatile_reg,     
962         .readable_reg = cs35l56_readable_reg,     
963         .precious_reg = cs35l56_precious_reg,     
964         .cache_type = REGCACHE_MAPLE,             
965 };                                                
966 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_S    
967                                                   
968 MODULE_DESCRIPTION("ASoC CS35L56 Shared");        
969 MODULE_AUTHOR("Richard Fitzgerald <rf@opensour    
970 MODULE_AUTHOR("Simon Trimmer <simont@opensourc    
971 MODULE_LICENSE("GPL");                            
972 MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB);             
973                                                   

~ [ 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