
dm365管脚复用配置浅析之.doc
6页dm365管脚复用配置浅析之davinci_cfg_reg调用内核版本:linux-2.6.32.17-psp03.01.01.39, leopardboard dm365JT发板带的 sdk 包里面的内核 davinci_cfg_reg()函数用来配置dm365的管脚复用功能,调用时直接使用davinci_cfg_reg(index)即可, 其中index是对应的复用功能它被定义在初始化数组中要了解davinci_cfg_reg的原理,理解管脚复用 表比较关键,下面就详细介绍:注:以下所有文件都是在内核arch/arm/mach-davince/T,本文以dm365的I2C管脚复用为例1、 davinci_cfg_reg 在头文件 kernel/arch/arm/mach-davince/include/mach/mux.h 中包含如 卜#ifdefCONFIG_DAVINCI_MUX/* setup pinmuxing */extern intdavinci_cfg_reg(unsigned long reg_cfg);#elser boot loaderdoes it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */static inlineint davinci_cfg_reg(unsigned long reg_cfg) (return 0;}#endif2、 davinci_cfg__reg 被定义于 kernel/arch/arm/mach-davince/mux.c 中, 如下:/** Setsthe DAVINCI MUX register based on the table*/int—init_or_module davinci_cfg_reg(const unsigned long index)(static DEFINE_SPINLOCK(mux_spin_lock); 〃添加锁struct davinci_soc_info *soc_info = &davinci_soc_info; 〃传入全局结构 体,在dm365.c初始化void —iomem *base = soc_info->pinmux_base;//获得复用寄存器的基地 址0x014c0000unsigned long flags;const struct mux_config *cfg;〃配置信恩结构体,定义于 mux.h unsigned int reg_orig = 0, reg = 0;unsigned int mask, warn = 0;if(!socjnfo->pinmux_pins)BUG();if (index >= soc_info->pinmux_pins_num) {printk(KERN_ERR Invalid pin muxindex: %lu (%lu)\n", index, soc_info->pinmux_pins_num);dump_stack();return -ENODEV;}cfg = &soc_i nfo->pi nm ux_pi nsp ndex];if(cfg->name == NULL) {printk(KERN_ERR "No entry for thespecified index\n"); return -ENODEV;/*Update the mux register in question */ if (cfg->mask) ( unsigned tmp1, tmp2;spin_lock_irqsave(&mux_spin_lockjlags); reg_orig = _raw_readl(base +cfg->mux_reg);mask = (cfg->mask cfg->mask_offset); tmp1 = reg_orig & mask;reg = reg_orig & 〜mask;tmp2 = (cfg->mode cfg->mask_offset); reg |= tmp2;if (tmp1 != tmp2) warn = 1;—raw_writel(reg, base +cfg->mux_reg); spin_unlock_irqrestore(&mux_spin_lockjlags);)if (warn) (#ifdefCONFIG_DAVINCI_MUX_WARNINGSprintk(KERN_WARNING,,MUX: initialized %s\n", cfg->name);#endif}#ifdefCONFIG_DAVINCI_MUX_DEBUGif (cfg->debug || warn) (printk(KERN_WARNING,,MUX: Setting register %s\n", cfg->name);printk(KERN_WARNING " %s(0x%08x) = 0x%08x -> 0x%08x\n",cfg->mux_reg_name5 cfg->mux_reg3reg_orig, reg);}#endifreturn 0;)EXPORT_SYMBOL(davincLcfg_reg);3、现在将详细介绍davinci_cfg_reg的执行步骤:1) 、添加锁,2) 、struct davinci_soc_info *soc_info= &davinci_soc_info;davinci_soc_info是一个比较全局结构体,在dm365.c中被初始化,内容如下(这里有一个疑问:就是没有弄清楚在什么地方把davinci_socjnfo和davinci_socjnfo_dm365 关联起来的,有知道的朋友,请说明一下)static structdavinci_soc_info davinci_socjnfo_dm365 = (.io_desc.io_desc_num•jtag_id_base.ids.ids_num.cpu_clks.psc_bases.psc_bases_num.pinmux_base=dm365 io desc,=ARRAY_SIZE(dm365_io_desc),=IO_ADDRESS(0x01c40028),=dm365Jds,=ARRAY_SIZE(dm365_ids),=dm365 elks,=dm365_psc_bases,=A R R AY_S IZE (d m365_psc_bases), //psc 基地址=IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),〃在 include/mach/hardware.h 中定义//#define DAVINCI SYSTEM MODULE BASE 0x01C40000.pinmux_pinsdm365.c 中= dm365_pins,〃dm365所有的管脚复用表,接下来要分析的,在,pinmux_pins__num = A R R AYS IZE (d m 365_pi ns),// 复用数量.intc_base .intc_type .intcjrq_prios .intc_irq_num .timerjnfo .gpio_base .gpio_num •gpiojrq .gpio_unbanked .serial_dev .emac_pdata .sram_dma .sramjen);=IO_ADDRESS(DAVINCI_ARM_INTC_BASE), =DAVINCI INTC TYPE AINTC,=dm365_default_prionties5=DAVINCI N AINTC IRQ, =&dm365_timerjnfo, =IO_ADDRESS(DAVINCI_GPIO_BASE), =104,=IRQ_DM365_GPIOO,=8, /* really 16... skip muxed GPIOs 7 =&dm365 serial device, =&dm365_emac_pdata,=0x00010000,=SZ_32K,接着,我们看以下dm365_pins结构staticconst struct mux_config dm365_pins[] = ( #ifdefCONFIG_DAVINCI_MUXMUX_CFG(DM365,MMCSD0, 0, 24, 1, 0, false)MUX_CFG(DM365,MUX_CFG(DM365,MUX_CFG(DM365,MUX_CFG(DM365,MUX_CFG(DM365,MUX_CFG(DM365,SD1_CLK,0, 16, 3, 1, false)SD1_CMD, 4, 30, 3, 1, false)SD1_DA7A3, 4, 28, 3, 1, false)SD1_DA7A2, 4, 26, 3, 1, false)SD1_DA7A1, 4, 24, 3, 1, false)SD1_DATA0, 4, 22, 3, 1, false)MUX_CFG(DM365,MUX_CFG(DM365,I2C_SDA, 3, 23, 3, 2, false) //I2C 的 SDA 管脚I2C_SCL, 3, 21, 3, 2, false) //I2C 的 SCL 管脚MUX_CFG(DM365,};AEMIF_AR, 2, 0, 3, 1, false) 省略其他的一些内容 #endif这个结构体列出了 dm365的管脚复用情况, 接看看一下MUX_CFG这个宏定义是怎么样的,定义在mux.h中#defineMUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode5 dbg)\[soc##_##desc]= (\.name = #desc, \.debug = dbg, \.m ux_reg_name =” P IN M U X"#m uxreg, \.mux_reg =PINMUX##m uxreg, \.m ask_offset =m ode_off set, \.mask = mode mask, \},这个宏就是把(DM365,.mode = mux mode, \I2C_SDA, 3, 23, 3, 2, false)这样的信息转化成 mux_configd 的格式,其中 mux_config 定义在 include/mach/mux.h 里。
如 E structmux_config (const char *name;//复用管脚的名字,一般以要复用的功能命名const char *mux_reg_name;//复用寄存器的名字const unsigned char mux_reg;//复用的配置寄存器const unsigned char mask_offset; 〃偏移量,指寄存器的第几位,比如I2C_SDA是通过 //PINMUX3的24和23位设置的,则偏移量为23,const unsigned char mask;const unsigned char mode;//mask和mode的含义比如要把PINMUX3。
