route和path的注册过程

1. route种类

route分为三种:

  1. 常规route
    {“sink”,NULL,“source”}
    path->connect=1

  2. sink widget是mixer:
    {“mixer”,name1,“source1”}
    {“mixer”,name2,“source2”}
    对应的下面的图 :
    widget mixer
    name1和name2是kcontrol,这两个kcontrol包含在mixer widget中。
    这样mixer widget中包括如下:
    1)mixer本身信息
    2)几个snd_kcontrol_new中包括name1和name2。
    3)kcontrol_new的名,可以通过操作某个kcontrol来打开某条path。

  3. sink widget是mux
    mux widget

2. route怎么变成path

构造函数snd_soc_dapm_add_route

1656 static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,            
1657                                   const struct snd_soc_dapm_route *route)       
1658 {                                                                               
1659         struct snd_soc_dapm_path *path;                                         
1660         struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;          
1661         struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;            
1662         const char *sink;                                                       
1663         const char *control = route->control;                                   
1664         const char *source;                                                     
1665         char prefixed_sink[80];                                                 
1666         char prefixed_source[80];                                               
1667         int ret = 0;                                                            
1668                                                                                 
1669         if (dapm->codec && dapm->codec->name_prefix) {                          
1670                 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",         
1671                          dapm->codec->name_prefix, route->sink);                
1672                 sink = prefixed_sink;                                           
1673                 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",     
1674                          dapm->codec->name_prefix, route->source);              
1675                 source = prefixed_source;                                       
1676         } else {                                                                
1677                 sink = route->sink;                                             
1678                 source = route->source;                                         
1679         }                                                                       
1680                                                                                 
1681         /*                                                                      
1682          * find src and dest widgets over all widgets but favor a widget from   
1683          * current DAPM context                                                 
1684          */                                                                     
1685         list_for_each_entry(w, &dapm->card->widgets, list) {                    
1686                 if (!wsink && !(strcmp(w->name, sink))) {                       
1687                         wtsink = w;                                             
1688                         if (w->dapm == dapm)                                    
1689                                 wsink = w;                                      
1690                         continue;                                               
1691                 }                                                                                                                                                                                            
1692                 if (!wsource && !(strcmp(w->name, source))) {                   
1693                         wtsource = w;                                           
1694                         if (w->dapm == dapm)                                    
1695                                 wsource = w;                                    
1696                 }        
1697         }                                                                       
1698         /* use widget from another DAPM context if not found from this */       
1699         if (!wsink)                                                             
1700                 wsink = wtsink;                                                 
1701         if (!wsource)                                                           
1702                 wsource = wtsource;                                             
1703                                                                                 
1704         if (wsource == NULL || wsink == NULL)                                   
1705                 return -ENODEV;                                                 
1706                                                                                 
1707         path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);           
1708         if (!path)                                                              
1709                 return -ENOMEM;                                                 
1710                                                                                 
1711         path->source = wsource;                                                 
1712         path->sink = wsink;                                                     
1713         path->connected = route->connected;                                     
1714         INIT_LIST_HEAD(&path->list);                                            
1715         INIT_LIST_HEAD(&path->list_source);                                     
1716         INIT_LIST_HEAD(&path->list_sink);                                       
1717                                                                                 
1718         /* check for external widgets */                                        
1719         if (wsink->id == snd_soc_dapm_input) {                                  
1720                 if (wsource->id == snd_soc_dapm_micbias ||                      
1721                         wsource->id == snd_soc_dapm_mic ||                      
1722                         wsource->id == snd_soc_dapm_line ||                     
1723                         wsource->id == snd_soc_dapm_output)                     
1724                         wsink->ext = 1;                                         
1725         }                                                                       
1726         if (wsource->id == snd_soc_dapm_output) {                               
1727                 if (wsink->id == snd_soc_dapm_spk ||                            
1728                         wsink->id == snd_soc_dapm_hp ||                         
1729                         wsink->id == snd_soc_dapm_line ||                       
1730                         wsink->id == snd_soc_dapm_input)                        
1731                         wsource->ext = 1;                                       
1732         }            
1733                                                                                 
1734         /* connect static paths */                                              
1735         if (control == NULL) {                                                  
1736                 list_add(&path->list, &dapm->card->paths);                      
1737                 list_add(&path->list_sink, &wsink->sources);                    
1738                 list_add(&path->list_source, &wsource->sinks);                  
1739                 path->connect = 1;                                              
1740                 return 0;                                                       
1741         }                                                                       
1742                                                                                 
1743         /* connect dynamic paths */                                             
1744         switch (wsink->id) {                                                    
1745         case snd_soc_dapm_adc:                                                  
1746         case snd_soc_dapm_dac:                                                  
1747         case snd_soc_dapm_pga:                                                  
1748         case snd_soc_dapm_out_drv:                                              
1749         case snd_soc_dapm_input:                                                
1750         case snd_soc_dapm_output:                                               
1751         case snd_soc_dapm_micbias:                                              
1752         case snd_soc_dapm_vmid:                                                 
1753         case snd_soc_dapm_pre:                                                  
1754         case snd_soc_dapm_post:                                                 
1755         case snd_soc_dapm_supply:                                               
1756         case snd_soc_dapm_aif_in:                                               
1757         case snd_soc_dapm_aif_out:                                              
1758                 list_add(&path->list, &dapm->card->paths);                                 
1759                 list_add(&path->list_sink, &wsink->sources);                    
1760                 list_add(&path->list_source, &wsource->sinks);                  
1761                 path->connect = 1;                                              
1762                 return 0;                                                       
1763         case snd_soc_dapm_mux:                                                  
1764         case snd_soc_dapm_virt_mux:                                             
1765         case snd_soc_dapm_value_mux:                                            
1766                 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,     
1767                         &wsink->kcontrol_news[0]);                              
1768                 if (ret != 0)                                                   
1769                         goto err;                                               
1770                 break;                                                          
1771         case snd_soc_dapm_switch:                                               
1772         case snd_soc_dapm_mixer:                                                
1773         case snd_soc_dapm_mixer_named_ctl:                                      
1774                 ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);  
1775                 if (ret != 0)                                                   
1776                         goto err;                                               
1777                 break;                                                          
1778         case snd_soc_dapm_hp:                                                   
1779         case snd_soc_dapm_mic:                                                  
1780         case snd_soc_dapm_line:                                                 
1781         case snd_soc_dapm_spk:                                                  
1782                 list_add(&path->list, &dapm->card->paths);                      
1783                 list_add(&path->list_sink, &wsink->sources);                    
1784                 list_add(&path->list_source, &wsource->sinks);                  
1785                 path->connect = 0;                                              
1786                 return 0;                                                       
1787         }                                                                       
1788         return 0;                                                               
1789                                                                                 
1790 err:                                                                            
1791         dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",       
1792                  source, control, sink);                                        
1793         kfree(path);                                                            
1794         return ret;                                                                                                                                                                                          
1795 }                                   
                                                       

说明:

  1. 找到source,sink widget
  2. 构造path
    path–>source 指向source widget
    path–>sink 指向sink widget
    path–>kcontrol = NULL
  3. 设置path->connect

(1734-1741行) a. kcontrol != NULL : 静态路径path->connect=1 (1734-1741行)
(1744-1761行) b.1 sink widget为ADC,DAC等的path,从芯片手册上看,该path一般直连(无开关),所以path->connect=1
(1765-1777行)sink widget是mixer/mux的path,path->connect=根据寄存器的值来确定,在dapm_set_path_status的204-208行可以看出。
(1778-1787)是动态插拔的耳机,喇叭,麦克,先设置path->connect=0,根据实际情况后续改变。
4. 把path放入链表

1758                 list_add(&path->list, &dapm->card->paths); 
  //如果想找出所有path,则从dpam->card找出所有path            
1759                 list_add(&path->list_sink, &wsink->sources);    
 //对于某个widget,想知道谁给我提供数据的话,则从这个wdiget的sources链表,找到这些path.
1760                 list_add(&path->list_source, &wsource->sinks);
//对于某个widget,想知道我提供数据给谁的话,则从这个wdiget的sinks链表,找到这些path.

根据链表,可知任一个widget
a. 原始数据从哪一个widget发出
b. 数据最终发给谁
也就是complete path。

  1. path->kcontrol的设置
    snd_soc_dapm_add_routes
    创建path,但path->kcontrol未设置。

在snd_soc_dapm_new_widgets函数中,他会导致mux/mixer中snd_kcontrol_new被构造为snd_kcontrol,
进而设置path->kcontrol。

dapm_set_path_status函数

dapm_connect_mixer或者dapm_connect_mux调用dapm_set_path_status函数

 188 static void dapm_set_path_status(struct snd_soc_dapm_widget *w,                 
 189         struct snd_soc_dapm_path *p, int i)                                     
 190 {                                                                               
 191         switch (w->id) {                                                        
 192         case snd_soc_dapm_switch:                                               
 193         case snd_soc_dapm_mixer:                                                
 194         case snd_soc_dapm_mixer_named_ctl: {                                    
 195                 int val;                                                        
 196                 struct soc_mixer_control *mc = (struct soc_mixer_control *)     
 197                         w->kcontrol_news[i].private_value;                      
 198                 unsigned int reg = mc->reg;                                     
 199                 unsigned int shift = mc->shift;                                 
 200                 int max = mc->max;                                              
 201                 unsigned int mask = (1 << fls(max)) - 1;                        
 202                 unsigned int invert = mc->invert;                               
 203                                                                                 
 204                 val = snd_soc_read(w->codec, reg);                              
 205                 val = (val >> shift) & mask;                                    
 206                                                                                 
 207                 if ((invert && !val) || (!invert && val))                       
 208                         p->connect = 1;                                         
 209                 else                                                            
 210                         p->connect = 0;                                         
 211         }                                                                       
 212         break;                                                                  
 213         case snd_soc_dapm_mux: {                                                
 214                 struct soc_enum *e = (struct soc_enum *)                        
 215                         w->kcontrol_news[i].private_value;                      
 216                 int val, item, bitmask;                                         
 217                                                                                 
 218                 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)              
 219                 ;                                                               
 220                 val = snd_soc_read(w->codec, e->reg);                           
 221                 item = (val >> e->shift_l) & (bitmask - 1);                     
 222                                                                                 
 223                 p->connect = 0;                                                 
 224                 for (i = 0; i < e->max; i++) {                                  
 225                         if (!(strcmp(p->name, e->texts[i])) && item == i)       
 226                                 p->connect = 1;           
 }           
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值