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

TOMOYO Linux Cross Reference
Linux/sound/soc/codecs/mt6359-accdet.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/soc/codecs/mt6359-accdet.c (Version linux-6.11.5) and /sound/soc/codecs/mt6359-accdet.c (Version linux-4.10.17)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 //                                                
  3 // mt6359-accdet.c  --  ALSA SoC mt6359 accdet    
  4 //                                                
  5 // Copyright (C) 2021 MediaTek Inc.               
  6 // Author: Argus Lin <argus.lin@mediatek.com>     
  7 //                                                
  8                                                   
  9 #include <linux/of.h>                             
 10 #include <linux/input.h>                          
 11 #include <linux/kthread.h>                        
 12 #include <linux/io.h>                             
 13 #include <linux/sched/clock.h>                    
 14 #include <linux/workqueue.h>                      
 15 #include <linux/timer.h>                          
 16 #include <linux/delay.h>                          
 17 #include <linux/module.h>                         
 18 #include <linux/platform_device.h>                
 19 #include <linux/init.h>                           
 20 #include <linux/irqdomain.h>                      
 21 #include <linux/irq.h>                            
 22 #include <linux/regmap.h>                         
 23 #include <sound/soc.h>                            
 24 #include <sound/jack.h>                           
 25 #include <linux/mfd/mt6397/core.h>                
 26                                                   
 27 #include "mt6359-accdet.h"                        
 28 #include "mt6359.h"                               
 29                                                   
 30 /* global variable definitions */                 
 31 #define REGISTER_VAL(x) ((x) - 1)                 
 32                                                   
 33 /* mt6359 accdet capability */                    
 34 #define ACCDET_PMIC_EINT_IRQ            BIT(0)    
 35 #define ACCDET_AP_GPIO_EINT             BIT(1)    
 36                                                   
 37 #define ACCDET_PMIC_EINT0               BIT(2)    
 38 #define ACCDET_PMIC_EINT1               BIT(3)    
 39 #define ACCDET_PMIC_BI_EINT             BIT(4)    
 40                                                   
 41 #define ACCDET_PMIC_GPIO_TRIG_EINT      BIT(5)    
 42 #define ACCDET_PMIC_INVERTER_TRIG_EINT  BIT(6)    
 43 #define ACCDET_PMIC_RSV_EINT            BIT(7)    
 44                                                   
 45 #define ACCDET_THREE_KEY                BIT(8)    
 46 #define ACCDET_FOUR_KEY                 BIT(9)    
 47 #define ACCDET_TRI_KEY_CDD              BIT(10    
 48 #define ACCDET_RSV_KEY                  BIT(11    
 49                                                   
 50 #define ACCDET_ANALOG_FASTDISCHARGE     BIT(12    
 51 #define ACCDET_DIGITAL_FASTDISCHARGE    BIT(13    
 52 #define ACCDET_AD_FASTDISCHRAGE         BIT(14    
 53                                                   
 54 static struct platform_driver mt6359_accdet_dr    
 55 static const struct snd_soc_component_driver m    
 56                                                   
 57 /* local function declaration */                  
 58 static void accdet_set_debounce(struct mt6359_    
 59                                 unsigned int d    
 60 static unsigned int adjust_eint_analog_setting    
 61 static void config_digital_init_by_mode(struct    
 62 static void config_eint_init_by_mode(struct mt    
 63 static inline void mt6359_accdet_init(struct m    
 64 static unsigned int mt6359_accdet_jd_setting(s    
 65 static void mt6359_accdet_recover_jd_setting(s    
 66 static void mt6359_accdet_jack_report(struct m    
 67 static void recover_eint_analog_setting(struct    
 68 static void recover_eint_digital_setting(struc    
 69 static void recover_eint_setting(struct mt6359    
 70                                                   
 71 static unsigned int adjust_eint_analog_setting    
 72 {                                                 
 73         if (priv->data->eint_detect_mode == 0x    
 74             priv->data->eint_detect_mode == 0x    
 75                 /* ESD switches off */            
 76                 regmap_update_bits(priv->regma    
 77                                    RG_ACCDETSP    
 78         }                                         
 79         if (priv->data->eint_detect_mode == 0x    
 80                 if (priv->caps & ACCDET_PMIC_E    
 81                         /* enable RG_EINT0CONF    
 82                         regmap_update_bits(pri    
 83                                            RG_    
 84                                            RG_    
 85                                            BIT    
 86                 } else if (priv->caps & ACCDET    
 87                         /* enable RG_EINT1CONF    
 88                         regmap_update_bits(pri    
 89                                            RG_    
 90                                            RG_    
 91                                            BIT    
 92                 }                                 
 93                 if (priv->data->eint_use_ext_r    
 94                     priv->data->eint_use_ext_r    
 95                         /*select 500k, use int    
 96                         regmap_update_bits(pri    
 97                                            RG_    
 98                                            RG_    
 99                                            BIT    
100                 }                                 
101         }                                         
102         return 0;                                 
103 }                                                 
104                                                   
105 static unsigned int adjust_eint_digital_settin    
106 {                                                 
107         if (priv->caps & ACCDET_PMIC_EINT0) {     
108                 /* disable inverter */            
109                 regmap_update_bits(priv->regma    
110                                    ACCDET_EINT    
111                                    ACCDET_EINT    
112         } else if (priv->caps & ACCDET_PMIC_EI    
113                 /* disable inverter */            
114                 regmap_update_bits(priv->regma    
115                                    ACCDET_EINT    
116                                    ACCDET_EINT    
117         }                                         
118                                                   
119         if (priv->data->eint_detect_mode == 0x    
120                 if (priv->caps & ACCDET_PMIC_E    
121                         /* set DA stable signa    
122                         regmap_update_bits(pri    
123                                            ACC    
124                                            ACC    
125                 } else if (priv->caps & ACCDET    
126                         /* set DA stable signa    
127                         regmap_update_bits(pri    
128                                            ACC    
129                                            ACC    
130                 }                                 
131         }                                         
132         return 0;                                 
133 }                                                 
134                                                   
135 static unsigned int mt6359_accdet_jd_setting(s    
136 {                                                 
137         if (priv->jd_sts == M_PLUG_IN) {          
138                 /* adjust digital setting */      
139                 adjust_eint_digital_setting(pr    
140                 /* adjust analog setting */       
141                 adjust_eint_analog_setting(pri    
142         } else if (priv->jd_sts == M_PLUG_OUT)    
143                 /* set debounce to 1ms */         
144                 accdet_set_debounce(priv, eint    
145                                     priv->data    
146         } else {                                  
147                 dev_dbg(priv->dev, "should not    
148         }                                         
149                                                   
150         return 0;                                 
151 }                                                 
152                                                   
153 static void recover_eint_analog_setting(struct    
154 {                                                 
155         if (priv->data->eint_detect_mode == 0x    
156             priv->data->eint_detect_mode == 0x    
157                 /* ESD switches on */             
158                 regmap_update_bits(priv->regma    
159                                    1 << 8, 1 <    
160         }                                         
161         if (priv->data->eint_detect_mode == 0x    
162                 if (priv->caps & ACCDET_PMIC_E    
163                         /* disable RG_EINT0CON    
164                         regmap_update_bits(pri    
165                                            RG_    
166                                            RG_    
167                 } else if (priv->caps & ACCDET    
168                         /* disable RG_EINT1CON    
169                         regmap_update_bits(pri    
170                                            RG_    
171                                            RG_    
172                 }                                 
173                 regmap_update_bits(priv->regma    
174                                    RG_EINT0HIR    
175         }                                         
176 }                                                 
177                                                   
178 static void recover_eint_digital_setting(struc    
179 {                                                 
180         if (priv->caps & ACCDET_PMIC_EINT0) {     
181                 regmap_update_bits(priv->regma    
182                                    ACCDET_EINT    
183                                    ACCDET_EINT    
184         } else if (priv->caps & ACCDET_PMIC_EI    
185                 regmap_update_bits(priv->regma    
186                                    ACCDET_EINT    
187                                    ACCDET_EINT    
188         }                                         
189         if (priv->data->eint_detect_mode == 0x    
190                 /* enable eint0cen */             
191                 if (priv->caps & ACCDET_PMIC_E    
192                         /* enable eint0cen */     
193                         regmap_update_bits(pri    
194                                            ACC    
195                                            ACC    
196                                            BIT    
197                 } else if (priv->caps & ACCDET    
198                         /* enable eint1cen */     
199                         regmap_update_bits(pri    
200                                            ACC    
201                                            ACC    
202                                            BIT    
203                 }                                 
204         }                                         
205                                                   
206         if (priv->data->eint_detect_mode != 0x    
207                 if (priv->caps & ACCDET_PMIC_E    
208                         /* enable inverter */     
209                         regmap_update_bits(pri    
210                                            ACC    
211                                            ACC    
212                                            BIT    
213                 } else if (priv->caps & ACCDET    
214                         /* enable inverter */     
215                         regmap_update_bits(pri    
216                                            ACC    
217                                            ACC    
218                                            BIT    
219                 }                                 
220         }                                         
221 }                                                 
222                                                   
223 static void recover_eint_setting(struct mt6359    
224 {                                                 
225         if (priv->jd_sts == M_PLUG_OUT) {         
226                 recover_eint_analog_setting(pr    
227                 recover_eint_digital_setting(p    
228         }                                         
229 }                                                 
230                                                   
231 static void mt6359_accdet_recover_jd_setting(s    
232 {                                                 
233         int ret;                                  
234         unsigned int value = 0;                   
235                                                   
236         regmap_update_bits(priv->regmap, ACCDE    
237                            ACCDET_IRQ_CLR_MASK    
238         usleep_range(200, 300);                   
239         ret = regmap_read_poll_timeout(priv->r    
240                                        ACCDET_    
241                                        value,     
242                                        (value     
243                                        0,         
244                                        1000);     
245         if (ret)                                  
246                 dev_warn(priv->dev, "%s(), ret    
247         /* clear accdet int, modify  for fix i    
248         regmap_update_bits(priv->regmap, ACCDE    
249                            ACCDET_IRQ_CLR_MASK    
250         regmap_update_bits(priv->regmap, RG_IN    
251                            RG_INT_STATUS_ACCDE    
252                            BIT(RG_INT_STATUS_A    
253                                                   
254         /* recover accdet debounce0,3 */          
255         accdet_set_debounce(priv, accdet_state    
256                             priv->data->pwm_de    
257         accdet_set_debounce(priv, accdet_state    
258                             priv->data->pwm_de    
259         accdet_set_debounce(priv, accdet_state    
260                             priv->data->pwm_de    
261                                                   
262         priv->jack_type = 0;                      
263         priv->btn_type = 0;                       
264         priv->accdet_status = 0x3;                
265         mt6359_accdet_jack_report(priv);          
266 }                                                 
267                                                   
268 static void accdet_set_debounce(struct mt6359_    
269                                 unsigned int d    
270 {                                                 
271         switch (state) {                          
272         case accdet_state000:                     
273                 regmap_write(priv->regmap, ACC    
274                 break;                            
275         case accdet_state001:                     
276                 regmap_write(priv->regmap, ACC    
277                 break;                            
278         case accdet_state010:                     
279                 regmap_write(priv->regmap, ACC    
280                 break;                            
281         case accdet_state011:                     
282                 regmap_write(priv->regmap, ACC    
283                 break;                            
284         case accdet_auxadc:                       
285                 regmap_write(priv->regmap,        
286                              ACCDET_CONNECT_AU    
287                 break;                            
288         case eint_state000:                       
289                 regmap_update_bits(priv->regma    
290                                    0xF << ACCD    
291                                    debounce <<    
292                 break;                            
293         case eint_state001:                       
294                 regmap_update_bits(priv->regma    
295                                    0xF << ACCD    
296                                    debounce <<    
297                 break;                            
298         case eint_state010:                       
299                 regmap_update_bits(priv->regma    
300                                    0xF << ACCD    
301                                    debounce <<    
302                 break;                            
303         case eint_state011:                       
304                 regmap_update_bits(priv->regma    
305                                    0xF << ACCD    
306                                    debounce <<    
307                 break;                            
308         case eint_inverter_state000:              
309                 regmap_write(priv->regmap, ACC    
310                              debounce);           
311                 break;                            
312         default:                                  
313                 dev_warn(priv->dev, "Error: %s    
314                          state);                  
315                 break;                            
316         }                                         
317 }                                                 
318                                                   
319 static void mt6359_accdet_jack_report(struct m    
320 {                                                 
321         int report = 0;                           
322                                                   
323         if (!priv->jack)                          
324                 return;                           
325                                                   
326         report = priv->jack_type | priv->btn_t    
327         snd_soc_jack_report(priv->jack, report    
328 }                                                 
329                                                   
330 static unsigned int check_button(struct mt6359    
331 {                                                 
332         if (priv->caps & ACCDET_FOUR_KEY) {       
333                 if (v < priv->data->four_key.d    
334                     v >= priv->data->four_key.    
335                         priv->btn_type = SND_J    
336                 if (v < priv->data->four_key.u    
337                     v >= priv->data->four_key.    
338                         priv->btn_type = SND_J    
339                 if (v < priv->data->four_key.v    
340                     v >= priv->data->four_key.    
341                         priv->btn_type = SND_J    
342                 if (v < priv->data->four_key.m    
343                         priv->btn_type = SND_J    
344         } else {                                  
345                 if (v < priv->data->three_key.    
346                     v >= priv->data->three_key    
347                         priv->btn_type = SND_J    
348                 if (v < priv->data->three_key.    
349                     v >= priv->data->three_key    
350                         priv->btn_type = SND_J    
351                 if (v < priv->data->three_key.    
352                         priv->btn_type = SND_J    
353         }                                         
354         return 0;                                 
355 }                                                 
356                                                   
357 static void is_key_pressed(struct mt6359_accde    
358 {                                                 
359         priv->btn_type = priv->jack_type & ~MT    
360                                                   
361         if (pressed)                              
362                 check_button(priv, priv->cali_    
363 }                                                 
364                                                   
365 static inline void check_jack_btn_type(struct     
366 {                                                 
367         unsigned int val = 0;                     
368                                                   
369         regmap_read(priv->regmap, ACCDET_MEM_I    
370                                                   
371         priv->accdet_status =                     
372                 (val >> ACCDET_STATE_MEM_IN_OF    
373                                                   
374         switch (priv->accdet_status) {            
375         case 0:                                   
376                 if (priv->jack_type == SND_JAC    
377                         is_key_pressed(priv, t    
378                 else                              
379                         priv->jack_type = SND_    
380                 break;                            
381         case 1:                                   
382                 if (priv->jack_type == SND_JAC    
383                         is_key_pressed(priv, f    
384                 } else {                          
385                         priv->jack_type = SND_    
386                         accdet_set_debounce(pr    
387                 }                                 
388                 break;                            
389         case 3:                                   
390         default:                                  
391                 priv->jack_type = 0;              
392                 break;                            
393         }                                         
394 }                                                 
395                                                   
396 static void mt6359_accdet_work(struct work_str    
397 {                                                 
398         struct mt6359_accdet *priv =              
399                 container_of(work, struct mt63    
400                                                   
401         mutex_lock(&priv->res_lock);              
402         priv->pre_accdet_status = priv->accdet    
403         check_jack_btn_type(priv);                
404                                                   
405         if (priv->jack_plugged &&                 
406             priv->pre_accdet_status != priv->a    
407                 mt6359_accdet_jack_report(priv    
408         mutex_unlock(&priv->res_lock);            
409 }                                                 
410                                                   
411 static void mt6359_accdet_jd_work(struct work_    
412 {                                                 
413         int ret;                                  
414         unsigned int value = 0;                   
415                                                   
416         struct mt6359_accdet *priv =              
417                 container_of(work, struct mt63    
418                                                   
419         mutex_lock(&priv->res_lock);              
420         if (priv->jd_sts == M_PLUG_IN) {          
421                 priv->jack_plugged = true;        
422                                                   
423                 /* set and clear initial bit e    
424                 regmap_update_bits(priv->regma    
425                                    ACCDET_SEQ_    
426                                    BIT(ACCDET_    
427                 regmap_update_bits(priv->regma    
428                                    ACCDET_SEQ_    
429                 ret = regmap_read_poll_timeout    
430                                                   
431                                                   
432                                                   
433                                                   
434                                                   
435                 if (ret)                          
436                         dev_err(priv->dev, "%s    
437                                                   
438                 /* enable ACCDET unit */          
439                 regmap_update_bits(priv->regma    
440                                    ACCDET_SW_E    
441         } else if (priv->jd_sts == M_PLUG_OUT)    
442                 priv->jack_plugged = false;       
443                                                   
444                 accdet_set_debounce(priv, accd    
445                                     priv->data    
446                 regmap_update_bits(priv->regma    
447                                    ACCDET_SW_E    
448                 mt6359_accdet_recover_jd_setti    
449         }                                         
450                                                   
451         if (priv->caps & ACCDET_PMIC_EINT_IRQ)    
452                 recover_eint_setting(priv);       
453         mutex_unlock(&priv->res_lock);            
454 }                                                 
455                                                   
456 static irqreturn_t mt6359_accdet_irq(int irq,     
457 {                                                 
458         struct mt6359_accdet *priv = data;        
459         unsigned int irq_val = 0, val = 0, val    
460         int ret;                                  
461                                                   
462         mutex_lock(&priv->res_lock);              
463         regmap_read(priv->regmap, ACCDET_IRQ_A    
464                                                   
465         if (irq_val & ACCDET_IRQ_MASK_SFT) {      
466                 regmap_update_bits(priv->regma    
467                                    ACCDET_IRQ_    
468                                    BIT(ACCDET_    
469                 ret = regmap_read_poll_timeout    
470                                                   
471                                                   
472                                                   
473                                                   
474                                                   
475                 if (ret) {                        
476                         dev_err(priv->dev, "%s    
477                         mutex_unlock(&priv->re    
478                         return IRQ_NONE;          
479                 }                                 
480                 regmap_update_bits(priv->regma    
481                                    ACCDET_IRQ_    
482                 regmap_update_bits(priv->regma    
483                                    RG_INT_STAT    
484                                    BIT(RG_INT_    
485                                                   
486                 queue_work(priv->accdet_workqu    
487         } else {                                  
488                 if (irq_val & ACCDET_EINT0_IRQ    
489                         regmap_update_bits(pri    
490                                            ACC    
491                                            BIT    
492                         ret = regmap_read_poll    
493                                                   
494                                                   
495                                                   
496                                                   
497                                                   
498                         if (ret) {                
499                                 dev_err(priv->    
500                                         ret);     
501                                 mutex_unlock(&    
502                                 return IRQ_NON    
503                         }                         
504                         regmap_update_bits(pri    
505                                            ACC    
506                         regmap_update_bits(pri    
507                                            RG_    
508                                            RG_    
509                                            BIT    
510                 }                                 
511                 if (irq_val & ACCDET_EINT1_IRQ    
512                         regmap_update_bits(pri    
513                                            ACC    
514                                            BIT    
515                         ret = regmap_read_poll    
516                                                   
517                                                   
518                                                   
519                                                   
520                                                   
521                         if (ret) {                
522                                 dev_err(priv->    
523                                         ret);     
524                                 mutex_unlock(&    
525                                 return IRQ_NON    
526                         }                         
527                         regmap_update_bits(pri    
528                                            ACC    
529                         regmap_update_bits(pri    
530                                            RG_    
531                                            RG_    
532                                            BIT    
533                 }                                 
534                 /* get jack detection status *    
535                 regmap_read(priv->regmap, ACCD    
536                 priv->jd_sts = ((val >> ACCDET    
537                                    ACCDET_EINT    
538                 /* adjust eint digital/analog     
539                 mt6359_accdet_jd_setting(priv)    
540                                                   
541                 queue_work(priv->jd_workqueue,    
542         }                                         
543         mutex_unlock(&priv->res_lock);            
544                                                   
545         return IRQ_HANDLED;                       
546 }                                                 
547                                                   
548 static int mt6359_accdet_parse_dt(struct mt635    
549 {                                                 
550         int ret;                                  
551         struct device *dev = priv->dev;           
552         struct device_node *node = NULL;          
553         int pwm_deb[15] = {0};                    
554         unsigned int tmp = 0;                     
555                                                   
556         node = of_get_child_by_name(dev->paren    
557         if (!node)                                
558                 return -EINVAL;                   
559                                                   
560         ret = of_property_read_u32(node, "medi    
561                                    &priv->data    
562         if (ret)                                  
563                 priv->data->mic_vol = 8;          
564                                                   
565         ret = of_property_read_u32(node, "medi    
566                                    &priv->data    
567         if (ret)                                  
568                 priv->data->plugout_deb = 1;      
569                                                   
570         ret = of_property_read_u32(node, "medi    
571                                    &priv->data    
572         if (ret)                                  
573                 priv->data->mic_mode = 2;         
574                                                   
575         ret = of_property_read_u32_array(node,    
576                                          pwm_d    
577         /* debounce8(auxadc debounce) is defau    
578         if (!ret)                                 
579                 memcpy(priv->data->pwm_deb, pw    
580                                                   
581         ret = of_property_read_u32(node, "medi    
582                                    &priv->data    
583         if (ret)                                  
584                 priv->data->eint_pol = 8;         
585                                                   
586         ret = of_property_read_u32(node, "medi    
587         if (ret)                                  
588                 tmp = 0;                          
589         if (tmp == 0)                             
590                 priv->caps |= ACCDET_PMIC_EINT    
591         else if (tmp == 1)                        
592                 priv->caps |= ACCDET_AP_GPIO_E    
593                                                   
594         ret = of_property_read_u32(node, "medi    
595                                    &priv->data    
596         if (ret) {                                
597                 /* eint detection mode equals     
598                 priv->data->eint_detect_mode =    
599         }                                         
600                                                   
601         ret = of_property_read_u32(node, "medi    
602         if (ret)                                  
603                 tmp = 0;                          
604         if (tmp == 0)                             
605                 priv->caps |= ACCDET_PMIC_EINT    
606         else if (tmp == 1)                        
607                 priv->caps |= ACCDET_PMIC_EINT    
608         else if (tmp == 2)                        
609                 priv->caps |= ACCDET_PMIC_BI_E    
610                                                   
611         ret = of_property_read_u32(node, "medi    
612                                    &tmp);         
613         if (ret)                                  
614                 tmp = 0;                          
615         if (tmp == 0)                             
616                 priv->caps |= ACCDET_PMIC_GPIO    
617         else if (tmp == 1)                        
618                 priv->caps |= ACCDET_PMIC_INVE    
619                                                   
620         ret = of_property_read_u32(node, "medi    
621                                    &priv->data    
622         if (ret) {                                
623                 /* eint use internal resister     
624                 priv->data->eint_use_ext_res =    
625         }                                         
626                                                   
627         ret = of_property_read_u32(node, "medi    
628                                    &priv->data    
629         if (ret)                                  
630                 priv->data->eint_comp_vth = 0x    
631                                                   
632         ret = of_property_read_u32(node, "medi    
633         if (ret)                                  
634                 tmp = 0;                          
635         if (tmp == 0) {                           
636                 int three_key[4];                 
637                                                   
638                 priv->caps |= ACCDET_THREE_KEY    
639                 ret = of_property_read_u32_arr    
640                                                   
641                                                   
642                                                   
643                 if (!ret)                         
644                         memcpy(&priv->data->th    
645                                sizeof(struct t    
646         } else if (tmp == 1) {                    
647                 int four_key[5];                  
648                                                   
649                 priv->caps |= ACCDET_FOUR_KEY;    
650                 ret = of_property_read_u32_arr    
651                                                   
652                                                   
653                                                   
654                 if (!ret) {                       
655                         memcpy(&priv->data->fo    
656                                sizeof(struct f    
657                 } else {                          
658                         dev_warn(priv->dev,       
659                                  "accdet no 4-    
660                 }                                 
661         } else if (tmp == 2) {                    
662                 int three_key[4];                 
663                                                   
664                 priv->caps |= ACCDET_TRI_KEY_C    
665                 ret = of_property_read_u32_arr    
666                                                   
667                                                   
668                                                   
669                 if (!ret)                         
670                         memcpy(&priv->data->th    
671                                sizeof(struct t    
672         }                                         
673                                                   
674         of_node_put(node);                        
675         dev_warn(priv->dev, "accdet caps=%x\n"    
676                                                   
677         return 0;                                 
678 }                                                 
679                                                   
680 static void config_digital_init_by_mode(struct    
681 {                                                 
682         /* enable eint cmpmem pwm */              
683         regmap_write(priv->regmap, ACCDET_EINT    
684                      (priv->data->pwm_deb->ein    
685                      priv->data->pwm_deb->eint    
686         /* DA signal stable */                    
687         if (priv->caps & ACCDET_PMIC_EINT0) {     
688                 regmap_write(priv->regmap, ACC    
689                              ACCDET_EINT0_STAB    
690         } else if (priv->caps & ACCDET_PMIC_EI    
691                 regmap_write(priv->regmap, ACC    
692                              ACCDET_EINT1_STAB    
693         }                                         
694         /* after receive n+1 number, interrupt    
695         regmap_update_bits(priv->regmap, ACCDE    
696                            ACCDET_EINT_M_PLUG_    
697                            BIT(ACCDET_EINT_M_P    
698         /* setting HW mode, enable digital fas    
699          * if use EINT0 & EINT1 detection, ple    
700          * ACCDET_HWMODE_EN_ADDR[2:1]             
701          */                                       
702         regmap_write(priv->regmap, ACCDET_HWMO    
703                                                   
704         regmap_update_bits(priv->regmap, ACCDE    
705                            ACCDET_EINT_M_DETEC    
706                                                   
707         /* enable PWM */                          
708         regmap_write(priv->regmap, ACCDET_CMP_    
709         /* enable inverter detection */           
710         if (priv->data->eint_detect_mode == 0x    
711                 /* disable inverter detection     
712                 if (priv->caps & ACCDET_PMIC_E    
713                         regmap_update_bits(pri    
714                                            ACC    
715                                            ACC    
716                                            0);    
717                 } else if (priv->caps & ACCDET    
718                         regmap_update_bits(pri    
719                                            ACC    
720                                            ACC    
721                                            0);    
722                 }                                 
723         } else {                                  
724                 if (priv->caps & ACCDET_PMIC_E    
725                         regmap_update_bits(pri    
726                                            ACC    
727                                            ACC    
728                                            BIT    
729                 } else if (priv->caps & ACCDET    
730                         regmap_update_bits(pri    
731                                            ACC    
732                                            ACC    
733                                            BIT    
734                 }                                 
735         }                                         
736 }                                                 
737                                                   
738 static void config_eint_init_by_mode(struct mt    
739 {                                                 
740         unsigned int val = 0;                     
741                                                   
742         if (priv->caps & ACCDET_PMIC_EINT0) {     
743                 regmap_update_bits(priv->regma    
744                                    RG_EINT0EN_    
745         } else if (priv->caps & ACCDET_PMIC_EI    
746                 regmap_update_bits(priv->regma    
747                                    RG_EINT1EN_    
748         }                                         
749         /* ESD switches on */                     
750         regmap_update_bits(priv->regmap, RG_AC    
751                            1 << 8, 1 << 8);       
752         /* before playback, set NCP pull low b    
753         regmap_update_bits(priv->regmap, RG_NC    
754                            RG_NCP_PDDIS_EN_MAS    
755                                                   
756         if (priv->data->eint_detect_mode == 0x    
757             priv->data->eint_detect_mode == 0x    
758             priv->data->eint_detect_mode == 0x    
759                 if (priv->data->eint_use_ext_r    
760                         if (priv->caps & ACCDE    
761                                 regmap_update_    
762                                                   
763                                                   
764                                                   
765                         } else if (priv->caps     
766                                 regmap_update_    
767                                                   
768                                                   
769                                                   
770                         }                         
771                 } else {                          
772                         if (priv->caps & ACCDE    
773                                 regmap_update_    
774                                                   
775                                                   
776                                                   
777                         } else if (priv->caps     
778                                 regmap_update_    
779                                                   
780                                                   
781                                                   
782                         }                         
783                 }                                 
784         }                                         
785                                                   
786         if (priv->data->eint_detect_mode != 0x    
787                 /* current detect set 0.25uA *    
788                 regmap_update_bits(priv->regma    
789                                    0x3 << RG_A    
790                                    0x3 << RG_A    
791         }                                         
792         regmap_write(priv->regmap, RG_EINTCOMP    
793                      val | priv->data->eint_co    
794 }                                                 
795                                                   
796 static void mt6359_accdet_init(struct mt6359_a    
797 {                                                 
798         unsigned int reg = 0;                     
799                                                   
800         regmap_update_bits(priv->regmap, ACCDE    
801                            ACCDET_SEQ_INIT_MAS    
802         mdelay(2);                                
803         regmap_update_bits(priv->regmap, ACCDE    
804                            ACCDET_SEQ_INIT_MAS    
805         mdelay(1);                                
806         /* init the debounce time (debounce/32    
807         accdet_set_debounce(priv, accdet_state    
808                             priv->data->pwm_de    
809         accdet_set_debounce(priv, accdet_state    
810                             priv->data->pwm_de    
811         accdet_set_debounce(priv, accdet_state    
812                             priv->data->pwm_de    
813         accdet_set_debounce(priv, accdet_auxad    
814                             priv->data->pwm_de    
815                                                   
816         accdet_set_debounce(priv, eint_state00    
817                             priv->data->pwm_de    
818         accdet_set_debounce(priv, eint_state00    
819                             priv->data->pwm_de    
820         accdet_set_debounce(priv, eint_state01    
821                             priv->data->pwm_de    
822         accdet_set_debounce(priv, eint_inverte    
823                             priv->data->pwm_de    
824                                                   
825         regmap_update_bits(priv->regmap, RG_AC    
826                            RG_ACCDET_RST_MASK_    
827         regmap_update_bits(priv->regmap, RG_AC    
828                            RG_ACCDET_RST_MASK_    
829                                                   
830         /* clear high micbias1 voltage setting    
831         regmap_update_bits(priv->regmap, RG_AU    
832                            0x3 << RG_AUDMICBIA    
833         regmap_update_bits(priv->regmap, RG_AU    
834                            0x7 << RG_AUDMICBIA    
835                                                   
836         /* init pwm frequency, duty & rise/fal    
837         regmap_write(priv->regmap, ACCDET_PWM_    
838                      REGISTER_VAL(priv->data->    
839         regmap_write(priv->regmap, ACCDET_PWM_    
840                      REGISTER_VAL(priv->data->    
841         regmap_write(priv->regmap, ACCDET_RISE    
842                      (priv->data->pwm_deb->fal    
843                       priv->data->pwm_deb->ris    
844                                                   
845         regmap_read(priv->regmap, RG_AUDPWDBMI    
846         if (priv->data->mic_vol <= 7) {           
847                 /* micbias1 <= 2.7V */            
848                 regmap_write(priv->regmap, RG_    
849                              reg | (priv->data    
850                              RG_AUDMICBIAS1LOW    
851         } else if (priv->data->mic_vol == 8) {    
852                 /* micbias1 = 2.8v */             
853                 regmap_write(priv->regmap, RG_    
854                              reg | (3 << RG_AU    
855                              RG_AUDMICBIAS1LOW    
856         } else if (priv->data->mic_vol == 9) {    
857                 /* micbias1 = 2.85v */            
858                 regmap_write(priv->regmap, RG_    
859                              reg | (1 << RG_AU    
860                              RG_AUDMICBIAS1LOW    
861         }                                         
862         /* mic mode setting */                    
863         regmap_read(priv->regmap, RG_AUDACCDET    
864         if (priv->data->mic_mode == HEADSET_MO    
865                 /* ACC mode*/                     
866                 regmap_write(priv->regmap, RG_    
867                              reg | RG_ACCDET_M    
868                 /* enable analog fast discharg    
869                 regmap_update_bits(priv->regma    
870                                    RG_ANALOGFD    
871                                    BIT(RG_ANAL    
872                 regmap_update_bits(priv->regma    
873                                    0x3 << 11,     
874         } else if (priv->data->mic_mode == HEA    
875                 /* DCC mode Low cost mode with    
876                 regmap_write(priv->regmap, RG_    
877                              reg | RG_ACCDET_M    
878                 /* enable analog fast discharg    
879                 regmap_update_bits(priv->regma    
880                                    0x3 << RG_A    
881                                    0x3 << RG_A    
882         } else if (priv->data->mic_mode == HEA    
883                 /* DCC mode Low cost mode with    
884                  * bit8 = 1 to use internal bi    
885                  */                               
886                 regmap_write(priv->regmap, RG_    
887                              reg | RG_ACCDET_M    
888                 regmap_update_bits(priv->regma    
889                                    RG_AUDMICBI    
890                                    BIT(RG_AUDM    
891                 /* enable analog fast discharg    
892                 regmap_update_bits(priv->regma    
893                                    0x3 << RG_A    
894                                    0x3 << RG_A    
895         }                                         
896                                                   
897         if (priv->caps & ACCDET_PMIC_EINT_IRQ)    
898                 config_eint_init_by_mode(priv)    
899                 config_digital_init_by_mode(pr    
900         }                                         
901 }                                                 
902                                                   
903 int mt6359_accdet_enable_jack_detect(struct sn    
904                                      struct sn    
905 {                                                 
906         struct mt6359_accdet *priv =              
907                 snd_soc_component_get_drvdata(    
908                                                   
909         snd_jack_set_key(jack->jack, SND_JACK_    
910         snd_jack_set_key(jack->jack, SND_JACK_    
911         snd_jack_set_key(jack->jack, SND_JACK_    
912         snd_jack_set_key(jack->jack, SND_JACK_    
913                                                   
914         priv->jack = jack;                        
915                                                   
916         mt6359_accdet_jack_report(priv);          
917                                                   
918         return 0;                                 
919 }                                                 
920 EXPORT_SYMBOL_GPL(mt6359_accdet_enable_jack_de    
921                                                   
922 static int mt6359_accdet_probe(struct platform    
923 {                                                 
924         struct mt6359_accdet *priv;               
925         struct mt6397_chip *mt6397 = dev_get_d    
926         int ret;                                  
927                                                   
928         dev_dbg(&pdev->dev, "%s(), dev name %s    
929                 __func__, dev_name(&pdev->dev)    
930                                                   
931         priv = devm_kzalloc(&pdev->dev, sizeof    
932                             GFP_KERNEL);          
933         if (!priv)                                
934                 return -ENOMEM;                   
935                                                   
936         priv->data = devm_kzalloc(&pdev->dev,     
937                                   GFP_KERNEL);    
938         if (!priv->data)                          
939                 return -ENOMEM;                   
940                                                   
941         priv->data->pwm_deb = devm_kzalloc(&pd    
942                                            siz    
943                                            GFP    
944         if (!priv->data->pwm_deb)                 
945                 return -ENOMEM;                   
946                                                   
947         priv->regmap = mt6397->regmap;            
948         if (IS_ERR(priv->regmap)) {               
949                 ret = PTR_ERR(priv->regmap);      
950                 dev_err(&pdev->dev, "Failed to    
951                         ret);                     
952                 return ret;                       
953         }                                         
954         priv->dev = &pdev->dev;                   
955                                                   
956         ret = mt6359_accdet_parse_dt(priv);       
957         if (ret) {                                
958                 dev_err(&pdev->dev, "Failed to    
959                 return ret;                       
960         }                                         
961         mutex_init(&priv->res_lock);              
962                                                   
963         priv->accdet_irq = platform_get_irq(pd    
964         if (priv->accdet_irq >= 0) {              
965                 ret = devm_request_threaded_ir    
966                                                   
967                                                   
968                                                   
969                 if (ret) {                        
970                         dev_err(&pdev->dev,       
971                                 "Failed to req    
972                         return ret;               
973                 }                                 
974         }                                         
975                                                   
976         if (priv->caps & ACCDET_PMIC_EINT0) {     
977                 priv->accdet_eint0 = platform_    
978                 if (priv->accdet_eint0 >= 0) {    
979                         ret = devm_request_thr    
980                                                   
981                                                   
982                                                   
983                                                   
984                         if (ret) {                
985                                 dev_err(&pdev-    
986                                         "Faile    
987                                         ret);     
988                                 return ret;       
989                         }                         
990                 }                                 
991         } else if (priv->caps & ACCDET_PMIC_EI    
992                 priv->accdet_eint1 = platform_    
993                 if (priv->accdet_eint1 >= 0) {    
994                         ret = devm_request_thr    
995                                                   
996                                                   
997                                                   
998                                                   
999                         if (ret) {                
1000                                 dev_err(&pdev    
1001                                         "Fail    
1002                                         ret);    
1003                                 return ret;      
1004                         }                        
1005                 }                                
1006         }                                        
1007                                                  
1008         priv->accdet_workqueue = create_singl    
1009         INIT_WORK(&priv->accdet_work, mt6359_    
1010         if (!priv->accdet_workqueue) {           
1011                 dev_err(&pdev->dev, "Failed t    
1012                 ret = -1;                        
1013                 goto err_accdet_wq;              
1014         }                                        
1015                                                  
1016         priv->jd_workqueue = create_singlethr    
1017         INIT_WORK(&priv->jd_work, mt6359_accd    
1018         if (!priv->jd_workqueue) {               
1019                 dev_err(&pdev->dev, "Failed t    
1020                 ret = -1;                        
1021                 goto err_eint_wq;                
1022         }                                        
1023                                                  
1024         platform_set_drvdata(pdev, priv);        
1025         ret = devm_snd_soc_register_component    
1026                                                  
1027                                                  
1028         if (ret) {                               
1029                 dev_err(&pdev->dev, "Failed t    
1030                 return ret;                      
1031         }                                        
1032                                                  
1033         priv->jd_sts = M_PLUG_OUT;               
1034         priv->jack_type = 0;                     
1035         priv->btn_type = 0;                      
1036         priv->accdet_status = 0x3;               
1037         mt6359_accdet_init(priv);                
1038                                                  
1039         mt6359_accdet_jack_report(priv);         
1040                                                  
1041         return 0;                                
1042                                                  
1043 err_eint_wq:                                     
1044         destroy_workqueue(priv->accdet_workqu    
1045 err_accdet_wq:                                   
1046         dev_err(&pdev->dev, "%s error. now ex    
1047         return ret;                              
1048 }                                                
1049                                                  
1050 static struct platform_driver mt6359_accdet_d    
1051         .driver = {                              
1052                 .name = "pmic-codec-accdet",     
1053         },                                       
1054         .probe = mt6359_accdet_probe,            
1055 };                                               
1056                                                  
1057 module_platform_driver(mt6359_accdet_driver)     
1058                                                  
1059 /* Module information */                         
1060 MODULE_DESCRIPTION("MT6359 ALSA SoC codec jac    
1061 MODULE_AUTHOR("Argus Lin <argus.lin@mediatek.    
1062 MODULE_LICENSE("GPL v2");                        
1063                                                  

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