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

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


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 //                                                
  3 // Common code for Cirrus Logic Smart Amplifie    
  4 //                                                
  5 // Copyright (C) 2024 Cirrus Logic, Inc. and      
  6 //               Cirrus Logic International Se    
  7                                                   
  8 #include <asm/byteorder.h>                        
  9 #include <kunit/static_stub.h>                    
 10 #include <linux/dev_printk.h>                     
 11 #include <linux/efi.h>                            
 12 #include <linux/firmware/cirrus/cs_dsp.h>         
 13 #include <linux/module.h>                         
 14 #include <linux/slab.h>                           
 15 #include <linux/types.h>                          
 16 #include <sound/cs-amp-lib.h>                     
 17                                                   
 18 #define CS_AMP_CAL_GUID \                         
 19         EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0    
 20                                                   
 21 #define CS_AMP_CAL_NAME L"CirrusSmartAmpCalibr    
 22                                                   
 23 static int cs_amp_write_cal_coeff(struct cs_ds    
 24                                   const struct    
 25                                   const char *    
 26 {                                                 
 27         struct cs_dsp_coeff_ctl *cs_ctl;          
 28         __be32 beval = cpu_to_be32(val);          
 29         int ret;                                  
 30                                                   
 31         KUNIT_STATIC_STUB_REDIRECT(cs_amp_writ    
 32                                                   
 33         if (IS_REACHABLE(CONFIG_FW_CS_DSP)) {     
 34                 mutex_lock(&dsp->pwr_lock);       
 35                 cs_ctl = cs_dsp_get_ctl(dsp, c    
 36                 ret = cs_dsp_coeff_write_ctrl(    
 37                 mutex_unlock(&dsp->pwr_lock);     
 38                                                   
 39                 if (ret < 0) {                    
 40                         dev_err(dsp->dev, "Fai    
 41                         return ret;               
 42                 }                                 
 43                                                   
 44                 return 0;                         
 45         }                                         
 46                                                   
 47         return -ENODEV;                           
 48 }                                                 
 49                                                   
 50 static int _cs_amp_write_cal_coeffs(struct cs_    
 51                                     const stru    
 52                                     const stru    
 53 {                                                 
 54         int ret;                                  
 55                                                   
 56         dev_dbg(dsp->dev, "Calibration: Ambien    
 57                 data->calAmbient, data->calSta    
 58                                                   
 59         if (list_empty(&dsp->ctl_list)) {         
 60                 dev_info(dsp->dev, "Calibratio    
 61                 return -ENOENT;                   
 62         }                                         
 63                                                   
 64         ret = cs_amp_write_cal_coeff(dsp, cont    
 65         if (ret)                                  
 66                 return ret;                       
 67                                                   
 68         ret = cs_amp_write_cal_coeff(dsp, cont    
 69         if (ret)                                  
 70                 return ret;                       
 71                                                   
 72         ret = cs_amp_write_cal_coeff(dsp, cont    
 73         if (ret)                                  
 74                 return ret;                       
 75                                                   
 76         ret = cs_amp_write_cal_coeff(dsp, cont    
 77         if (ret)                                  
 78                 return ret;                       
 79                                                   
 80         return 0;                                 
 81 }                                                 
 82                                                   
 83 /**                                               
 84  * cs_amp_write_cal_coeffs - Write calibration    
 85  * @dsp:        Pointer to struct cs_dsp.         
 86  * @controls:   Pointer to definition of firmw    
 87  * @data:       Pointer to calibration data.      
 88  *                                                
 89  * Returns: 0 on success, else negative error     
 90  */                                               
 91 int cs_amp_write_cal_coeffs(struct cs_dsp *dsp    
 92                             const struct cirru    
 93                             const struct cirru    
 94 {                                                 
 95         if (IS_REACHABLE(CONFIG_FW_CS_DSP) ||     
 96                 return _cs_amp_write_cal_coeff    
 97         else                                      
 98                 return -ENODEV;                   
 99 }                                                 
100 EXPORT_SYMBOL_NS_GPL(cs_amp_write_cal_coeffs,     
101                                                   
102 static efi_status_t cs_amp_get_efi_variable(ef    
103                                             ef    
104                                             un    
105                                             vo    
106 {                                                 
107         u32 attr;                                 
108                                                   
109         KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_    
110                                                   
111         if (efi_rt_services_supported(EFI_RT_S    
112                 return efi.get_variable(name,     
113                                                   
114         return EFI_NOT_FOUND;                     
115 }                                                 
116                                                   
117 static struct cirrus_amp_efi_data *cs_amp_get_    
118 {                                                 
119         struct cirrus_amp_efi_data *efi_data;     
120         unsigned long data_size = 0;              
121         u8 *data;                                 
122         efi_status_t status;                      
123         int ret;                                  
124                                                   
125         /* Get real size of UEFI variable */      
126         status = cs_amp_get_efi_variable(CS_AM    
127         if (status != EFI_BUFFER_TOO_SMALL)       
128                 return ERR_PTR(-ENOENT);          
129                                                   
130         if (data_size < sizeof(*efi_data)) {      
131                 dev_err(dev, "EFI cal variable    
132                 return ERR_PTR(-EOVERFLOW);       
133         }                                         
134                                                   
135         /* Get variable contents into buffer *    
136         data = kmalloc(data_size, GFP_KERNEL);    
137         if (!data)                                
138                 return ERR_PTR(-ENOMEM);          
139                                                   
140         status = cs_amp_get_efi_variable(CS_AM    
141         if (status != EFI_SUCCESS) {              
142                 ret = -EINVAL;                    
143                 goto err;                         
144         }                                         
145                                                   
146         efi_data = (struct cirrus_amp_efi_data    
147         dev_dbg(dev, "Calibration: Size=%d, Am    
148                                                   
149         if ((efi_data->count > 128) ||            
150             offsetof(struct cirrus_amp_efi_dat    
151                 dev_err(dev, "EFI cal variable    
152                 ret = -EOVERFLOW;                 
153                 goto err;                         
154         }                                         
155                                                   
156         return efi_data;                          
157                                                   
158 err:                                              
159         kfree(data);                              
160         dev_err(dev, "Failed to read calibrati    
161                                                   
162         return ERR_PTR(ret);                      
163 }                                                 
164                                                   
165 static u64 cs_amp_cal_target_u64(const struct     
166 {                                                 
167         return ((u64)data->calTarget[1] << 32)    
168 }                                                 
169                                                   
170 static int _cs_amp_get_efi_calibration_data(st    
171                                             st    
172 {                                                 
173         struct cirrus_amp_efi_data *efi_data;     
174         struct cirrus_amp_cal_data *cal = NULL    
175         int i, ret;                               
176                                                   
177         efi_data = cs_amp_get_cal_efi_buffer(d    
178         if (IS_ERR(efi_data))                     
179                 return PTR_ERR(efi_data);         
180                                                   
181         if (target_uid) {                         
182                 for (i = 0; i < efi_data->coun    
183                         u64 cal_target = cs_am    
184                                                   
185                         /* Skip empty entries     
186                         if (!efi_data->data[i]    
187                                 continue;         
188                                                   
189                         /* Skip entries with u    
190                         if (cal_target == 0)      
191                                 continue;         
192                                                   
193                         if (cal_target == targ    
194                                 cal = &efi_dat    
195                                 break;            
196                         }                         
197                 }                                 
198         }                                         
199                                                   
200         if (!cal && (amp_index >= 0) && (amp_i    
201             (efi_data->data[amp_index].calTime    
202                 u64 cal_target = cs_amp_cal_ta    
203                                                   
204                 /*                                
205                  * Treat unpopulated cal_targe    
206                  * If target_uid != 0 we can o    
207                  * or it didn't match any cal_    
208                  * If target_uid == 0 it is a     
209                  */                               
210                 if ((cal_target == 0) || (targ    
211                         cal = &efi_data->data[    
212                 else                              
213                         dev_warn(dev, "Calibra    
214         }                                         
215                                                   
216         if (cal) {                                
217                 memcpy(out_data, cal, sizeof(*    
218                 ret = 0;                          
219         } else {                                  
220                 dev_warn(dev, "No calibration     
221                 ret = -ENOENT;                    
222         }                                         
223                                                   
224         kfree(efi_data);                          
225                                                   
226         return ret;                               
227 }                                                 
228                                                   
229 /**                                               
230  * cs_amp_get_efi_calibration_data - get an en    
231  * @dev:        struct device of the caller.      
232  * @target_uid: UID to match, or zero to ignor    
233  * @amp_index:  Entry index to use, or -1 to p    
234  * @out_data:   struct cirrus_amp_cal_data whe    
235  *                                                
236  * This function can perform 3 types of lookup    
237  *                                                
238  * (target_uid > 0, amp_index >= 0)               
239  *      UID search with fallback to using the     
240  *      Search the calibration data for a non-    
241  *      target_uid, and if found return that e    
242  *      [amp_index] has calTarget == 0, return    
243  *                                                
244  * (target_uid > 0, amp_index < 0)                
245  *      UID search only.                          
246  *      Search the calibration data for a non-    
247  *      target_uid, and if found return that e    
248  *                                                
249  * (target_uid == 0, amp_index >= 0)              
250  *      Array index fetch only.                   
251  *      Return the entry at [amp_index].          
252  *                                                
253  * An array lookup will be skipped if amp_inde    
254  * entries in the calibration array, and in th    
255  * be -ENOENT. An out-of-range amp_index does     
256  * target_uid - it has the same effect as pass    
257  *                                                
258  * If the EFI data is too short to be a valid     
259  * in the EFI data overflows the actual length    
260  * returns -EOVERFLOW.                            
261  *                                                
262  * Return: 0 if the entry was found, -ENOENT i    
263  *         -EOVERFLOW if the EFI file is corru    
264  */                                               
265 int cs_amp_get_efi_calibration_data(struct dev    
266                                     struct cir    
267 {                                                 
268         if (IS_ENABLED(CONFIG_EFI) || IS_ENABL    
269                 return _cs_amp_get_efi_calibra    
270         else                                      
271                 return -ENOENT;                   
272 }                                                 
273 EXPORT_SYMBOL_NS_GPL(cs_amp_get_efi_calibratio    
274                                                   
275 static const struct cs_amp_test_hooks cs_amp_t    
276         .get_efi_variable = cs_amp_get_efi_var    
277         .write_cal_coeff = cs_amp_write_cal_co    
278 };                                                
279                                                   
280 const struct cs_amp_test_hooks * const cs_amp_    
281         PTR_IF(IS_ENABLED(CONFIG_SND_SOC_CS_AM    
282 EXPORT_SYMBOL_NS_GPL(cs_amp_test_hooks, SND_SO    
283                                                   
284 MODULE_DESCRIPTION("Cirrus Logic amplifier lib    
285 MODULE_AUTHOR("Richard Fitzgerald <rf@opensour    
286 MODULE_LICENSE("GPL");                            
287 MODULE_IMPORT_NS(FW_CS_DSP);                      
288                                                   

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