hawkboard和TI-OMAPL138-EVM相差不大。引脚复用设置都为一样,匹配性强,KERNEL版本为2.6.32,ti-am180x-sdk的KERNEL为2.6.37基本不匹配
引脚复用设置通过以下函数设置:mux.c
int da8xx_pinmux_setup(const short pins[]);
-->int __init_or_module davinci_cfg_reg(const unsigned long index)
初始引脚的定义和初始化在da850.c中:
1225 void __init da850_init(void)
1226 {
1227 da8xx_syscfg_base = ioremap(DA8XX_SYSCFG_BASE, SZ_4K);
1228 if (WARN(!da8xx_syscfg_base, "Unable to map syscfg module "))
1229 return;
1230
1233 davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG_VIRT(0x 120);//0x01c1 4120
1234
1235 davinci_common_init(&davinci_soc_info_da850);
}
。。。。
davinci_soc_info_da850结构初始化:
1203 static struct davinci_soc_info davinci_soc_info_da850 = {
/*............*/
1211 .pinmux_pins = da850_pins,
1212 .pinmux_pins_num = ARRAY_SIZE(da850_pins),
/*............*/
1223 };
与引脚相关的是pinmux_base,pinmux_pins,pinmux_pins_num,
上面是da850系列的板级支持,下面进行初始化,
void __init davinci_common_init(struct davinci_soc_info *soc_info)
57 {
58 int ret;
59 struct davinci_id *dip;
60
61 if (!soc_info) {
62 ret = -EINVAL;
63 goto err;
64 }
65
66 memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info));//消除硬件差异性,linux分层及硬件无关可移植性无处不在
与pin设置有关的结构体还有
static const struct mux_config da850_pins[]
490 #ifdef CONFIG_DAVINCI_MUX
491 /* UART0 function */
492 MUX_CFG(DA850, NUART0_CTS, 3, 24, 15, 2 , false)
493 MUX_CFG(DA850, NUART0_RTS, 3, 28, 15, 2 , false)
494 MUX_CFG(DA850, UART0_RXD, 3, 16, 15, 2 , false)
495 MUX_CFG(DA850, UART0_TXD, 3, 20, 15, 2 , false)
。。。。。
18 #define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
19 [soc##_##desc] = { \
20 .name = #desc, \
21 .debug = dbg, \
22 .mux_reg_name = "PINMUX"#muxreg, \
23 .mux_reg = PINMUX##muxreg, \
24 .mask_offset = mode_offset, \
25 .mask = mode_mask, \
26 .mode = mux_mode, \
27 },
28
22 struct mux_config {
23 const char *name; //SOC
24 const char *mux_reg_name;//DESC
25 const unsigned char mux_reg;//复用寄存器
26 const unsigned char mask_offset;//偏移
27 const unsigned char mask;//位掩码
28 const unsigned char mode;//模式
29 bool debug;
30 };
以上都是一个结构,MUX_CFG是完成mux_config匹配的宏,需要设定某些引脚时添加对应的MUX_CFG宏即可
以pruss uart引脚设置来分析
178 static __init int omapl138_hawk_config_pru_suart(void)
179 {
/* ....... */
181
182 ret = da8xx_pinmux_setup(da850_pru_suart_pins);
183 if (ret)
184 pr_warning("hawk_init: hawk_pru_suart_pins mux set failed:%d\n", ret);
/* ........ */
191 }
da850_pru_suart_pins[]数组是软串口的引脚定义:
const short da850_pru_suart_pins[] __initdata = {
DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
DA850_AHCLKR, DA850_ACLKR, DA850_AFSR,
DA850_AXR_11 DA850_AXR_9,
DA850_AXR_12 DA850_AXR_10,
-1
};
这是函数原型:
94 int da8xx_pinmux_setup(const short pins[])
95 {
96 int i, error = -EINVAL;
97
98 if (pins)
99 for (i = 0; pins[i] >= 0; i++) {//if ping[i] == -1,break;
100 error = davinci_cfg_reg(pins[i]);
101 if (error)
102 break;
103 }
104
105 return error;
106 }
这里可以看出da850_pru_suart_pins[]的内容是一组索引号,用来传递给davinci_cfg_reg()函数,至于索引号是怎么定义的呢?
可以查看mux.c中static const struct mux_config da850_pins[]和 mux.h中enum davinci_da850_index 内容
会惊奇的发现他们的引脚定义顺序完全一样,davinci_da850_index是一个枚举类型的数组。从0开始,作为索引匹配mux_config da850_pins
的内容,而MUX_CFG这个宏完成mux_config的匹配。故我们在增加引脚设置索引后,在mux.c中也许要在对应的位置添加MUX_CFG宏。
例程:
#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)
MUX_CFG(DA850, AHCLKX, 0, 20, 15, 1, false)
int __init_or_module davinci_cfg_reg(const unsigned long index)
29 {
30 static DEFINE_SPINLOCK(mux_spin_lock);
31 struct davinci_soc_info *soc_info = &davinci_soc_info;
32 void __iomem *base = soc_info->pinmux_base;//0x01C1 4120
33 unsigned long flags;
34 const struct mux_config *cfg;
35 unsigned int reg_orig = 0, reg = 0;
36 unsigned int mask, warn = 0;
37
38 if (!soc_info->pinmux_pins)
39 BUG();
40
41 if (index >= soc_info->pinmux_pins_num) {
42 printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
43 index, soc_info->pinmux_pins_num);
44 dump_stack();
45 return -ENODEV;
46 }
47
48 cfg = &soc_info->pinmux_pins[index];
49
50 if (cfg->name == NULL) {
51 printk(KERN_ERR "No entry for the specified index\n");
52 return -ENODEV;
53 }
54
55 /* Update the mux register in question */
56 if (cfg->mask) {//0x0F
57 unsigned tmp1, tmp2;
58
59 spin_lock_irqsave(&mux_spin_lock, flags);
60 reg_orig = __raw_readl(base + cfg->mux_reg);//PINMUX0
61
62 mask = (cfg->mask << cfg->mask_offset);//20
63 tmp1 = reg_orig & mask;//0x0f << 20
64 reg = reg_orig & ~mask;//~(0x0f << 20)
65
66 tmp2 = (cfg->mode << cfg->mask_offset);//0x01 << 20
67 reg |= tmp2;
68
69 if (tmp1 != tmp2)
70 warn = 1;
71
72 __raw_writel(reg, base + cfg->mux_reg);
73 spin_unlock_irqrestore(&mux_spin_lock, flags);
74 }
75
76 if (warn) {
77 #ifdef CONFIG_DAVINCI_MUX_WARNINGS
78 printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
79 #endif
80 }
81
82 #ifdef CONFIG_DAVINCI_MUX_DEBUG
83 if (cfg->debug || warn) {
84 printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name) ;
85 printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n" ,
86 cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
87 }
88 #endif
89
90 return 0;
91 }
流程:
1.索引号是否正确
2.根据索引得到对应mux_config结构
3.读取当前引脚状态备份
4.设置配置中的引脚状态
OMAPL138/AM1808引脚复用配置
最新推荐文章于 2020-11-30 16:50:16 发布