ret = davinci_cfg_reg_list(da850_i2c0_pins)
->
int __init_or_module davinci_cfg_reg_list(const short pins[])
{
int i, error = -EINVAL;
if (pins)
for (i = 0; pins[i] >= 0; i++) {
error = davinci_cfg_reg(pins[i]);
if (error)
break;
}
return error;
}
da850_i2c0_pins的内容如下:
const short da850_i2c0_pins[] __initdata = {
DA850_I2C0_SCL, DA850_I2C0_SDA,
-1
};
所以,函数执行后相当于这两句话:
davinci_cfg_reg(DA850_I2C0_SCL);
davinci_cfg_reg(DA850_I2C0_SDA);
先来看一下davinci_cfg_reg这个函数所作的处理:
/*
* Sets the 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;//得到与开发板相对应的davinci_soc_info全局结构体,位于arch/arm/mach-davinci/Da850.c中。
unsigned long flags;
const struct mux_config *cfg;
unsigned int reg_orig = 0, reg = 0;
unsigned int mask, warn = 0;
if (WARN_ON(!soc_info->pinmux_pins))
return -ENODEV;
if (!pinmux_base) {
/*获得复用寄存器的地址,并进行内存映射
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
#define DA8XX_SYSCFG0_BASE (IO_PHYS + 0x14000)
#define IO_PHYS 0x01c00000UL
最终得到:pinmux_base=0x01c14120
*/
pinmux_base = ioremap(soc_info->pinmux_base, SZ_4K);
if (WARN_ON(!pinmux_base))
return -ENOMEM;
}
if (index >= soc_info->pinmux_pins_num) {
printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
index, soc_info->pinmux_pins_num);
dump_stack();
return -ENODEV;
}
cfg = &soc_info->pinmux_pins[index];
if (cfg->name == NULL) {
printk(KERN_ERR "No entry for the specified index\n");
return -ENODEV;
}
/* Update the mux register in question */
if (cfg->mask) {
unsigned tmp1, tmp2;
spin_lock_irqsave(&mux_spin_lock, flags);
reg_orig = __raw_readl(pinmux_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, pinmux_base + cfg->mux_reg);
spin_unlock_irqrestore(&mux_spin_lock, flags);
}
if (warn) {
#ifdef CONFIG_DAVINCI_MUX_WARNINGS
printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
#endif
}
#ifdef CONFIG_DAVINCI_MUX_DEBUG
if (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_name, cfg->mux_reg, reg_orig, reg);
}
#endif
return 0;
}
可以看出传入的DA850_I2C0_SCL、DA850_I2C0_SDA都是unsigned long 类型的,这两个变量被定义在arch\arm\mach-davinci\Mux.c文件中,它们并不是整型类型直接定义的,而是以枚举类型定义的。DA850_I2C0_SCL、DA850_I2C0_SDA是其中的枚举元素,枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2…。如在下面的davinci_da850_index中,DA850_NUART0_CTS值为0,DA850_NUART0_RTS值为1,DA850_I2C0_SDA值为15,DA850_I2C0_SCL值为16。
enum davinci_da850_index {
/* UART0 function */
DA850_NUART0_CTS,(0)
DA850_NUART0_RTS,(1)
DA850_UART0_RXD,(2)
DA850_UART0_TXD,(3)
/* UART1 function */
DA850_NUART1_CTS,(4)
DA850_NUART1_RTS,(5)
DA850_UART1_RXD,(6)
DA850_UART1_TXD,(7)
DA850_GPIO0_15,(8)
/* UART2 function */
DA850_NUART2_CTS,(9)
DA850_NUART2_RTS,(10)
DA850_UART2_RXD,(11)
DA850_UART2_TXD,(12)
/* I2C1 function */
DA850_I2C1_SCL,(13)
DA850_I2C1_SDA,(14)
/* I2C0 function */
DA850_I2C0_SDA,(15)
DA850_I2C0_SCL,(16)
/* EMAC function */
DA850_MII_TXEN,
DA850_MII_TXCLK,
DA850_MII_COL,
DA850_MII_TXD_3,
DA850_MII_TXD_2,
DA850_MII_TXD_1,
DA850_MII_TXD_0,
DA850_MII_RXER,
DA850_MII_CRS,
DA850_MII_RXCLK,
DA850_MII_RXDV,
DA850_MII_RXD_3,
DA850_MII_RXD_2,
DA850_MII_RXD_1,
DA850_MII_RXD_0,
DA850_MDIO_CLK,
DA850_MDIO_D,
DA850_RMII_TXD_0,
DA850_RMII_TXD_1,
DA850_RMII_TXEN,
DA850_RMII_CRS_DV,
DA850_RMII_RXD_0,
DA850_RMII_RXD_1,
DA850_RMII_RXER,
DA850_RMII_MHZ_50_CLK,
/* McASP function */
DA850_ACLKR,
DA850_ACLKX,
DA850_AFSR,
DA850_AFSX,
DA850_AHCLKR,
DA850_AHCLKX,
DA850_AMUTE,
DA850_AXR_15,
DA850_AXR_14,
DA850_AXR_13,
DA850_AXR_12,
DA850_AXR_11,
DA850_AXR_10,
DA850_AXR_9,
DA850_AXR_8,
DA850_AXR_7,
DA850_AXR_6,
DA850_AXR_5,
DA850_AXR_4,
DA850_AXR_3,
DA850_AXR_2,
DA850_AXR_1,
DA850_AXR_0,
/* LCD function */
DA850_LCD_D_7,
DA850_LCD_D_6,
DA850_LCD_D_5,
DA850_LCD_D_4,
DA850_LCD_D_3,
DA850_LCD_D_2,
DA850_LCD_D_1,
DA850_LCD_D_0,
DA850_LCD_D_15,
DA850_LCD_D_14,
DA850_LCD_D_13,
DA850_LCD_D_12,
DA850_LCD_D_11,
DA850_LCD_D_10,
DA850_LCD_D_9,
DA850_LCD_D_8,
DA850_LCD_PCLK,
DA850_LCD_MCLK,
DA850_LCD_HSYNC,
DA850_LCD_VSYNC,
DA850_NLCD_AC_ENB_CS,
/* MMC/SD0 function */
DA850_MMCSD0_DAT_0,
DA850_MMCSD0_DAT_1,
DA850_MMCSD0_DAT_2,
DA850_MMCSD0_DAT_3,
DA850_MMCSD0_CLK,
DA850_MMCSD0_CMD,
/* MMC/SD1 function */
DA850_MMCSD1_DAT_0,
DA850_MMCSD1_DAT_1,
DA850_MMCSD1_DAT_2,
DA850_MMCSD1_DAT_3,
DA850_MMCSD1_CLK,
DA850_MMCSD1_CMD,
/* EMIF2.5/EMIFA function */
DA850_EMA_D_7,
DA850_EMA_D_6,
DA850_EMA_D_5,
DA850_EMA_D_4,
DA850_EMA_D_3,
DA850_EMA_D_2,
DA850_EMA_D_1,
DA850_EMA_D_0,
DA850_EMA_A_1,
DA850_EMA_A_2,
DA850_NEMA_CS_3,
DA850_NEMA_CS_4,
DA850_NEMA_CS_5,
DA850_NEMA_WE,
DA850_NEMA_OE,
DA850_EMA_D_15,
DA850_EMA_D_14,
DA850_EMA_D_13,
DA850_EMA_D_12,
DA850_EMA_D_11,
DA850_EMA_D_10,
DA850_EMA_D_9,
DA850_EMA_D_8,
DA850_EMA_A_0,
DA850_EMA_A_3,
DA850_EMA_A_4,
DA850_EMA_A_5,
DA850_EMA_A_6,
DA850_EMA_A_7,
DA850_EMA_A_8,
DA850_EMA_A_9,
DA850_EMA_A_10,
DA850_EMA_A_11,
DA850_EMA_A_12,
DA850_EMA_A_13,
DA850_EMA_A_14,
DA850_EMA_A_15,
DA850_EMA_A_16,
DA850_EMA_A_17,
DA850_EMA_A_18,
DA850_EMA_A_19,
DA850_EMA_A_20,
DA850_EMA_A_21,
DA850_EMA_A_22,
DA850_EMA_A_23,
DA850_EMA_BA_0,
DA850_EMA_BA_1,
DA850_EMA_CLK,
DA850_EMA_WAIT_1,
DA850_NEMA_CS_2,
/* GPIO function */
DA850_GPIO2_1,
DA850_GPIO2_2,
DA850_GPIO2_3,
DA850_GPIO2_4,
DA850_GPIO2_5,
DA850_GPIO2_6,
DA850_GPIO2_8,
DA850_GPIO2_15,
DA850_GPIO3_9,
DA850_GPIO3_12,
DA850_GPIO3_13,
DA850_GPIO4_0,
DA850_GPIO4_1,
DA850_GPIO6_1,
DA850_GPIO6_2,
DA850_GPIO6_3,
DA850_GPIO6_9,
DA850_GPIO6_10,
DA850_GPIO6_13,
DA850_GPIO6_14,
DA850_GPIO1_4,
DA850_GPIO1_5,
DA850_GPIO0_11,
DA850_GPIO2_12,
DA850_GPIO0_9,
DA850_GPIO6_12,
DA850_GPIO6_8,
DA850_GPIO0_13,
DA850_GPIO5_0,
DA850_GPIO5_2,
DA850_GPIO5_4,
DA850_GPIO5_6,
DA850_GPIO5_7,
DA850_GPIO5_8,
DA850_GPIO5_9,
DA850_GPIO5_10,
DA850_GPIO5_11,
DA850_GPIO5_12,
DA850_GPIO5_13,
DA850_GPIO5_14,
DA850_GPIO5_15,
DA850_RTC_ALARM,
DA850_GPIO7_4,
DA850_GPIO8_10,
DA850_GPIO8_1,
DA850_GPIO0_0,
DA850_GPIO0_1,
DA850_GPIO0_2,
DA850_GPIO0_5,
DA850_GPIO0_6,
DA850_GPIO0_8,
/* eHRPWM0 function */
DA850_EHRPWM0_A,
DA850_EHRPWM0_B,
DA850_EHRPWM0_TZ,
/* eHRPWM1 function */
DA850_EHRPWM1_A,
DA850_EHRPWM1_B,
DA850_EHRPWM1_TZ,
/* eCAP functions */
DA850_ECAP0_APWM0,
DA850_ECAP1_APWM1,
DA850_ECAP2_APWM2,
/* VPIF Capture */
DA850_VPIF_DIN0,
DA850_VPIF_DIN1,
DA850_VPIF_DIN2,
DA850_VPIF_DIN3,
DA850_VPIF_DIN4,
DA850_VPIF_DIN5,
DA850_VPIF_DIN6,
DA850_VPIF_DIN7,
DA850_VPIF_DIN8,
DA850_VPIF_DIN9,
DA850_VPIF_DIN10,
DA850_VPIF_DIN11,
DA850_VPIF_DIN12,
DA850_VPIF_DIN13,
DA850_VPIF_DIN14,
DA850_VPIF_DIN15,
DA850_VPIF_CLKIN0,
DA850_VPIF_CLKIN1,
DA850_VPIF_CLKIN2,
DA850_VPIF_CLKIN3,
/* VPIF Display */
DA850_VPIF_DOUT0,
DA850_VPIF_DOUT1,
DA850_VPIF_DOUT2,
DA850_VPIF_DOUT3,
DA850_VPIF_DOUT4,
DA850_VPIF_DOUT5,
DA850_VPIF_DOUT6,
DA850_VPIF_DOUT7,
DA850_VPIF_DOUT8,
DA850_VPIF_DOUT9,
DA850_VPIF_DOUT10,
DA850_VPIF_DOUT11,
DA850_VPIF_DOUT12,
DA850_VPIF_DOUT13,
DA850_VPIF_DOUT14,
DA850_VPIF_DOUT15,
DA850_VPIF_CLKO2,
DA850_VPIF_CLKO3,
/* McBSP1 fucntion */
DA850_MCBSP1_CLKR,
DA850_MCBSP1_CLKX,
DA850_MCBSP1_FSR,
DA850_MCBSP1_FSX,
DA850_MCBSP1_DR,
DA850_MCBSP1_DX,
DA850_MCBSP1_CLKS,
/* SPI1 function */
DA850_SPI1_CS_0,
DA850_SPI1_CS_1,
DA850_SPI1_CS_2,
DA850_SPI1_CS_3,
DA850_SPI1_CLK,
DA850_SPI1_SOMI,
DA850_SPI1_SIMO,
};
static struct davinci_soc_info davinci_soc_info_da850 = {
.io_desc = da850_io_desc,
.io_desc_num = ARRAY_SIZE(da850_io_desc),
.jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
.ids = da850_ids,
.ids_num = ARRAY_SIZE(da850_ids),
.cpu_clks = da850_clks,
.psc_bases = da850_psc_bases,
.psc_bases_num = ARRAY_SIZE(da850_psc_bases),
.pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
.pinmux_pins = da850_pins,
.pinmux_pins_num = ARRAY_SIZE(da850_pins),
.intc_base = DA8XX_CP_INTC_BASE,
.intc_type = DAVINCI_INTC_TYPE_CP_INTC,
.intc_irq_prios = da850_default_priorities,
.intc_irq_num = DA850_N_CP_INTC_IRQ,
.timer_info = &da850_timer_info,
.gpio_type = GPIO_TYPE_DAVINCI,
.gpio_base = DA8XX_GPIO_BASE,
.gpio_num = 144,
.gpio_irq = IRQ_DA8XX_GPIO0,
.serial_dev = &da8xx_serial_device,
.emac_pdata = &da8xx_emac_pdata,
.sram_phys = DA8XX_ARM_RAM_BASE,
.sram_len = SZ_8K,
};
接下来看/* I2C0 function */
DA850_I2C0_SDA,(15)
DA850_I2C0_SCL,(16)
是如何与实际的管脚复用配置相联系的
在arch/arm/mach-davinci/Da850.c中可以找到相关的配置信息
/*
* Device specific mux setup
*
* soc description mux mode mode mux dbg
* reg offset mask mode
*/
static const struct mux_config da850_pins[] = {
#ifdef CONFIG_DAVINCI_MUX
/* UART0 function */
MUX_CFG(DA850, NUART0_CTS, 3, 24, 15, 2, false)
MUX_CFG(DA850, NUART0_RTS, 3, 28, 15, 2, false)
MUX_CFG(DA850, UART0_RXD, 3, 16, 15, 2, false)
MUX_CFG(DA850, UART0_TXD, 3, 20, 15, 2, false)
/* UART1 function */
MUX_CFG(DA850, NUART1_CTS, 0, 20, 15, 4, false)
MUX_CFG(DA850, NUART1_RTS, 0, 16, 15, 4, false)
MUX_CFG(DA850, UART1_RXD, 4, 24, 15, 2, false)
MUX_CFG(DA850, UART1_TXD, 4, 28, 15, 2, false)
MUX_CFG(DA850, GPIO0_15, 0, 0, 15, 8, false)
/* UART2 function */
MUX_CFG(DA850, UART2_RXD, 4, 16, 15, 2, false)
MUX_CFG(DA850, UART2_TXD, 4, 20, 15, 2, false)
/* I2C1 function */
MUX_CFG(DA850, I2C1_SCL, 4, 16, 15, 4, false)
MUX_CFG(DA850, I2C1_SDA, 4, 20, 15, 4, false)
/* I2C0 function */
MUX_CFG(DA850, I2C0_SDA, 4, 12, 15, 2, false)
MUX_CFG(DA850, I2C0_SCL, 4, 8, 15, 2, false)
/* EMAC function */
MUX_CFG(DA850, MII_TXEN, 2, 4, 15, 8, false)
MUX_CFG(DA850, MII_TXCLK, 2, 8, 15, 8, false)
MUX_CFG(DA850, MII_COL, 2, 12, 15, 8, false)
MUX_CFG(DA850, MII_TXD_3, 2, 16, 15, 8, false)
MUX_CFG(DA850, MII_TXD_2, 2, 20, 15, 8, false)
MUX_CFG(DA850, MII_TXD_1, 2, 24, 15, 8, false)
MUX_CFG(DA850, MII_TXD_0, 2, 28, 15, 8, false)
MUX_CFG(DA850, MII_RXCLK, 3, 0, 15, 8, false)
MUX_CFG(DA850, MII_RXDV, 3, 4, 15, 8, false)
MUX_CFG(DA850, MII_RXER, 3, 8, 15, 8, false)
MUX_CFG(DA850, MII_CRS, 3, 12, 15, 8, false)
MUX_CFG(DA850, MII_RXD_3, 3, 16, 15, 8, false)
MUX_CFG(DA850, MII_RXD_2, 3, 20, 15, 8, false)
MUX_CFG(DA850, MII_RXD_1, 3, 24, 15, 8, false)
MUX_CFG(DA850, MII_RXD_0, 3, 28, 15, 8, false)
MUX_CFG(DA850, MDIO_CLK, 4, 0, 15, 8, false)
MUX_CFG(DA850, MDIO_D, 4, 4, 15, 8, false)
MUX_CFG(DA850, RMII_TXD_0, 14, 12, 15, 8, false)
MUX_CFG(DA850, RMII_TXD_1, 14, 8, 15, 8, false)
MUX_CFG(DA850, RMII_TXEN, 14, 16, 15, 8, false)
MUX_CFG(DA850, RMII_CRS_DV, 15, 4, 15, 8, false)
MUX_CFG(DA850, RMII_RXD_0, 14, 24, 15, 8, false)
MUX_CFG(DA850, RMII_RXD_1, 14, 20, 15, 8, false)
MUX_CFG(DA850, RMII_RXER, 14, 28, 15, 8, false)
MUX_CFG(DA850, RMII_MHZ_50_CLK, 15, 0, 15, 0, false)
/* McASP function */
MUX_CFG(DA850, ACLKR, 0, 0, 15, 1, false)
MUX_CFG(DA850, ACLKX, 0, 4, 15, 1, false)
MUX_CFG(DA850, AFSR, 0, 8, 15, 1, false)
MUX_CFG(DA850, AFSX, 0, 12, 15, 1, false)
MUX_CFG(DA850, AHCLKR, 0, 16, 15, 1, false)
MUX_CFG(DA850, AHCLKX, 0, 20, 15, 1, false)
MUX_CFG(DA850, AMUTE, 0, 24, 15, 1, false)
MUX_CFG(DA850, AXR_15, 1, 0, 15, 1, false)
MUX_CFG(DA850, AXR_14, 1, 4, 15, 1, false)
MUX_CFG(DA850, AXR_13, 1, 8, 15, 1, false)
MUX_CFG(DA850, AXR_12, 1, 12, 15, 1, false)
MUX_CFG(DA850, AXR_11, 1, 16, 15, 1, false)
MUX_CFG(DA850, AXR_10, 1, 20, 15, 1, false)
MUX_CFG(DA850, AXR_9, 1, 24, 15, 1, false)
MUX_CFG(DA850, AXR_8, 1, 28, 15, 1, false)
MUX_CFG(DA850, AXR_7, 2, 0, 15, 1, false)
MUX_CFG(DA850, AXR_6, 2, 4, 15, 1, false)
MUX_CFG(DA850, AXR_5, 2, 8, 15, 1, false)
MUX_CFG(DA850, AXR_4, 2, 12, 15, 1, false)
MUX_CFG(DA850, AXR_3, 2, 16, 15, 1, false)
MUX_CFG(DA850, AXR_2, 2, 20, 15, 1, false)
MUX_CFG(DA850, AXR_1, 2, 24, 15, 1, false)
MUX_CFG(DA850, AXR_0, 2, 28, 15, 1, false)
/* LCD function */
MUX_CFG(DA850, LCD_D_7, 16, 8, 15, 2, false)
MUX_CFG(DA850, LCD_D_6, 16, 12, 15, 2, false)
MUX_CFG(DA850, LCD_D_5, 16, 16, 15, 2, false)
MUX_CFG(DA850, LCD_D_4, 16, 20, 15, 2, false)
MUX_CFG(DA850, LCD_D_3, 16, 24, 15, 2, false)
MUX_CFG(DA850, LCD_D_2, 16, 28, 15, 2, false)
MUX_CFG(DA850, LCD_D_1, 17, 0, 15, 2, false)
MUX_CFG(DA850, LCD_D_0, 17, 4, 15, 2, false)
MUX_CFG(DA850, LCD_D_15, 17, 8, 15, 2, false)
MUX_CFG(DA850, LCD_D_14, 17, 12, 15, 2, false)
MUX_CFG(DA850, LCD_D_13, 17, 16, 15, 2, false)
MUX_CFG(DA850, LCD_D_12, 17, 20, 15, 2, false)
MUX_CFG(DA850, LCD_D_11, 17, 24, 15, 2, false)
MUX_CFG(DA850, LCD_D_10, 17, 28, 15, 2, false)
MUX_CFG(DA850, LCD_D_9, 18, 0, 15, 2, false)
MUX_CFG(DA850, LCD_D_8, 18, 4, 15, 2, false)
MUX_CFG(DA850, LCD_PCLK, 18, 24, 15, 2, false)
MUX_CFG(DA850, LCD_MCLK, 18, 28, 15, 2, false)
MUX_CFG(DA850, LCD_HSYNC, 19, 0, 15, 2, false)
MUX_CFG(DA850, LCD_VSYNC, 19, 4, 15, 2, false)
MUX_CFG(DA850, NLCD_AC_ENB_CS, 19, 24, 15, 2, false)
/* MMC/SD0 function */
MUX_CFG(DA850, MMCSD0_DAT_0, 10, 8, 15, 2, false)
MUX_CFG(DA850, MMCSD0_DAT_1, 10, 12, 15, 2, false)
MUX_CFG(DA850, MMCSD0_DAT_2, 10, 16, 15, 2, false)
MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false)
MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false)
MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false)
/* MMC/SD1 function */
MUX_CFG(DA850, MMCSD1_DAT_0, 18, 8, 15, 2, false)
MUX_CFG(DA850, MMCSD1_DAT_1, 19, 16, 15, 2, false)
MUX_CFG(DA850, MMCSD1_DAT_2, 19, 12, 15, 2, false)
MUX_CFG(DA850, MMCSD1_DAT_3, 19, 8, 15, 2, false)
MUX_CFG(DA850, MMCSD1_CLK, 18, 12, 15, 2, false)
MUX_CFG(DA850, MMCSD1_CMD, 18, 16, 15, 2, false)
/* EMIF2.5/EMIFA function */
MUX_CFG(DA850, EMA_D_7, 9, 0, 15, 1, false)
MUX_CFG(DA850, EMA_D_6, 9, 4, 15, 1, false)
MUX_CFG(DA850, EMA_D_5, 9, 8, 15, 1, false)
MUX_CFG(DA850, EMA_D_4, 9, 12, 15, 1, false)
MUX_CFG(DA850, EMA_D_3, 9, 16, 15, 1, false)
MUX_CFG(DA850, EMA_D_2, 9, 20, 15, 1, false)
MUX_CFG(DA850, EMA_D_1, 9, 24, 15, 1, false)
MUX_CFG(DA850, EMA_D_0, 9, 28, 15, 1, false)
MUX_CFG(DA850, EMA_A_1, 12, 24, 15, 1, false)
MUX_CFG(DA850, EMA_A_2, 12, 20, 15, 1, false)
MUX_CFG(DA850, NEMA_CS_3, 7, 4, 15, 1, false)
MUX_CFG(DA850, NEMA_CS_4, 7, 8, 15, 1, false)
MUX_CFG(DA850, NEMA_CS_5, 7, 12, 15, 1, false)
MUX_CFG(DA850, NEMA_WE, 7, 16, 15, 1, false)
MUX_CFG(DA850, NEMA_OE, 7, 20, 15, 1, false)
MUX_CFG(DA850, EMA_A_0, 12, 28, 15, 1, false)
MUX_CFG(DA850, EMA_A_3, 12, 16, 15, 1, false)
MUX_CFG(DA850, EMA_A_4, 12, 12, 15, 1, false)
MUX_CFG(DA850, EMA_A_5, 12, 8, 15, 1, false)
MUX_CFG(DA850, EMA_A_6, 12, 4, 15, 1, false)
MUX_CFG(DA850, EMA_A_7, 12, 0, 15, 1, false)
MUX_CFG(DA850, EMA_A_8, 11, 28, 15, 1, false)
MUX_CFG(DA850, EMA_A_9, 11, 24, 15, 1, false)
MUX_CFG(DA850, EMA_A_10, 11, 20, 15, 1, false)
MUX_CFG(DA850, EMA_A_11, 11, 16, 15, 1, false)
MUX_CFG(DA850, EMA_A_12, 11, 12, 15, 1, false)
MUX_CFG(DA850, EMA_A_13, 11, 8, 15, 1, false)
MUX_CFG(DA850, EMA_A_14, 11, 4, 15, 1, false)
MUX_CFG(DA850, EMA_A_15, 11, 0, 15, 1, false)
MUX_CFG(DA850, EMA_A_16, 10, 28, 15, 1, false)
MUX_CFG(DA850, EMA_A_17, 10, 24, 15, 1, false)
MUX_CFG(DA850, EMA_A_18, 10, 20, 15, 1, false)
MUX_CFG(DA850, EMA_A_19, 10, 16, 15, 1, false)
MUX_CFG(DA850, EMA_A_20, 10, 12, 15, 1, false)
MUX_CFG(DA850, EMA_A_21, 10, 8, 15, 1, false)
MUX_CFG(DA850, EMA_A_22, 10, 4, 15, 1, false)
MUX_CFG(DA850, EMA_A_23, 10, 0, 15, 1, false)
MUX_CFG(DA850, EMA_D_8, 8, 28, 15, 1, false)
MUX_CFG(DA850, EMA_D_9, 8, 24, 15, 1, false)
MUX_CFG(DA850, EMA_D_10, 8, 20, 15, 1, false)
MUX_CFG(DA850, EMA_D_11, 8, 16, 15, 1, false)
MUX_CFG(DA850, EMA_D_12, 8, 12, 15, 1, false)
MUX_CFG(DA850, EMA_D_13, 8, 8, 15, 1, false)
MUX_CFG(DA850, EMA_D_14, 8, 4, 15, 1, false)
MUX_CFG(DA850, EMA_D_15, 8, 0, 15, 1, false)
MUX_CFG(DA850, EMA_BA_0, 5, 28, 15, 1, false)
MUX_CFG(DA850, EMA_BA_1, 5, 24, 15, 1, false)
MUX_CFG(DA850, EMA_CLK, 6, 0, 15, 1, false)
MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false)
MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false)
/* GPIO function */
MUX_CFG(DA850, GPIO2_1, 6, 24, 15, 8, false)
MUX_CFG(DA850, GPIO2_2, 6, 20, 15, 8, false)
MUX_CFG(DA850, GPIO2_3, 6, 16, 15, 8, false)
MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false)
MUX_CFG(DA850, GPIO2_5, 6, 12, 15, 8, false)
MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false)
MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false)
MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false)
MUX_CFG(DA850, GPIO3_9, 7, 24, 15, 8, false)
MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false)
MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false)
MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false)
MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false)
MUX_CFG(DA850, GPIO6_1, 19, 20, 15, 8, false)
MUX_CFG(DA850, GPIO6_2, 19, 16, 15, 8, false)
MUX_CFG(DA850, GPIO6_3, 19, 12, 15, 8, false)
MUX_CFG(DA850, GPIO6_9, 13, 24, 15, 8, false)
MUX_CFG(DA850, GPIO6_10, 13, 20, 15, 8, false)
MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false)
MUX_CFG(DA850, GPIO6_14, 13, 4, 15, 8, false)
MUX_CFG(DA850, GPIO1_4, 4, 12, 15, 8, false)
MUX_CFG(DA850, GPIO1_5, 4, 8, 15, 8, false)
MUX_CFG(DA850, GPIO0_11, 0, 16, 15, 8, false)
MUX_CFG(DA850, GPIO2_12, 5, 12, 15, 8, false)
MUX_CFG(DA850, GPIO0_9, 0, 24, 15, 8, false)
MUX_CFG(DA850, GPIO6_12, 13, 12, 15, 8, false)
MUX_CFG(DA850, GPIO6_8, 19, 12, 15, 8, false)
MUX_CFG(DA850, GPIO0_13, 0, 8, 15, 8, false)
MUX_CFG(DA850, GPIO5_0, 12, 28, 15, 8, false)
MUX_CFG(DA850, GPIO5_2, 12, 20, 15, 8, false)
MUX_CFG(DA850, GPIO5_4, 12, 12, 15, 8, false)
MUX_CFG(DA850, GPIO5_6, 12, 4, 15, 8, false)
MUX_CFG(DA850, GPIO5_7, 12, 0, 15, 8, false)
MUX_CFG(DA850, GPIO5_8, 11, 28, 15, 8, false)
MUX_CFG(DA850, GPIO5_9, 11, 24, 15, 8, false)
MUX_CFG(DA850, GPIO5_10, 11, 20, 15, 8, false)
MUX_CFG(DA850, GPIO5_11, 11, 16, 15, 8, false)
MUX_CFG(DA850, GPIO5_12, 11, 12, 15, 8, false)
MUX_CFG(DA850, GPIO5_13, 11, 8, 15, 8, false)
MUX_CFG(DA850, GPIO5_14, 11, 4, 15, 8, false)
MUX_CFG(DA850, GPIO5_15, 11, 0, 15, 8, false)
MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false)
MUX_CFG(DA850, GPIO7_4, 17, 20, 15, 8, false)
MUX_CFG(DA850, GPIO8_10, 18, 28, 15, 8, false)
MUX_CFG(DA850, GPIO8_1, 3, 28, 15, 4, false)
MUX_CFG(DA850, GPIO0_0, 1, 28, 15, 8, false)
MUX_CFG(DA850, GPIO0_1, 1, 24, 15, 8, false)
MUX_CFG(DA850, GPIO0_2, 1, 20, 15, 8, false)
MUX_CFG(DA850, GPIO0_5, 1, 8, 15, 8, false)
MUX_CFG(DA850, GPIO0_6, 1, 4, 15, 8, false)
MUX_CFG(DA850, GPIO0_8, 0, 28, 15, 8, false)
/* eHRPWM0 function */
MUX_CFG(DA850, EHRPWM0_A, 3, 0, 15, 2, false)
MUX_CFG(DA850, EHRPWM0_B, 3, 4, 15, 2, false)
MUX_CFG(DA850, EHRPWM0_TZ, 1, 0, 15, 2, false)
/* eHRPWM1 function */
MUX_CFG(DA850, EHRPWM1_A, 5, 0, 15, 2, false)
MUX_CFG(DA850, EHRPWM1_B, 5, 4, 15, 2, false)
MUX_CFG(DA850, EHRPWM1_TZ, 2, 0, 15, 8, false)
/* eCAP0 function */
MUX_CFG(DA850, ECAP0_APWM0, 2, 28, 15, 2, false)
/* eCAP1 function */
MUX_CFG(DA850, ECAP1_APWM1, 1, 28, 15, 4, false)
/* eCAP2 function */
MUX_CFG(DA850, ECAP2_APWM2, 1, 0, 15, 4, false)
/* VPIF Capture */
MUX_CFG(DA850, VPIF_DIN0, 15, 4, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN1, 15, 0, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN2, 14, 28, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN3, 14, 24, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN4, 14, 20, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN5, 14, 16, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN6, 14, 12, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN7, 14, 8, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN8, 16, 4, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN9, 16, 0, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN10, 15, 28, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN11, 15, 24, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN12, 15, 20, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN13, 15, 16, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN14, 15, 12, 15, 1, false)
MUX_CFG(DA850, VPIF_DIN15, 15, 8, 15, 1, false)
MUX_CFG(DA850, VPIF_CLKIN0, 14, 0, 15, 1, false)
MUX_CFG(DA850, VPIF_CLKIN1, 14, 4, 15, 1, false)
MUX_CFG(DA850, VPIF_CLKIN2, 19, 8, 15, 1, false)
MUX_CFG(DA850, VPIF_CLKIN3, 19, 16, 15, 1, false)
/* VPIF Display */
MUX_CFG(DA850, VPIF_DOUT0, 17, 4, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT1, 17, 0, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT2, 16, 28, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT3, 16, 24, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT4, 16, 20, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT5, 16, 16, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT6, 16, 12, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT7, 16, 8, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT8, 18, 4, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT9, 18, 0, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT10, 17, 28, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT11, 17, 24, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT12, 17, 20, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT13, 17, 16, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT14, 17, 12, 15, 1, false)
MUX_CFG(DA850, VPIF_DOUT15, 17, 8, 15, 1, false)
MUX_CFG(DA850, VPIF_CLKO2, 19, 12, 15, 1, false)
MUX_CFG(DA850, VPIF_CLKO3, 19, 20, 15, 1, false)
/* McBSP1 function */
MUX_CFG(DA850, MCBSP1_CLKR, 1, 4, 15, 2, false)
MUX_CFG(DA850, MCBSP1_CLKX, 1, 8, 15, 2, false)
MUX_CFG(DA850, MCBSP1_FSR, 1, 12, 15, 2, false)
MUX_CFG(DA850, MCBSP1_FSX, 1, 16, 15, 2, false)
MUX_CFG(DA850, MCBSP1_DR, 1, 20, 15, 2, false)
MUX_CFG(DA850, MCBSP1_DX, 1, 24, 15, 2, false)
MUX_CFG(DA850, MCBSP1_CLKS, 1, 28, 15, 2, false)
/* SPI1 function */
MUX_CFG(DA850, SPI1_CS_0, 5, 4, 15, 1, false)
MUX_CFG(DA850, SPI1_CS_1, 5, 0, 15, 1, false)
MUX_CFG(DA850, SPI1_CS_2, 4, 28, 15, 1, false)
MUX_CFG(DA850, SPI1_CS_3, 4, 24, 15, 1, false)
MUX_CFG(DA850, SPI1_CLK, 5, 8, 15, 1, false)
MUX_CFG(DA850, SPI1_SOMI, 5, 16, 15, 1, false)
MUX_CFG(DA850, SPI1_SIMO, 5, 20, 15, 1, false)
#endif
};
最终实现如下的两个指向:
/* I2C0 function */
DA850_I2C0_SDA->MUX_CFG(DA850, I2C0_SDA, 4, 12, 15, 2, false)
DA850_I2C0_SCL->MUX_CFG(DA850, I2C0_SCL, 4, 8, 15, 2, false)
MUX_CFG的定义如下:
#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
[soc##_##desc] = { \
.name = #desc, \
.debug = dbg, \
.mux_reg_name = "PINMUX"#muxreg, \
.mux_reg = PINMUX(muxreg), \
.mask_offset = mode_offset, \
.mask = mode_mask, \
.mode = mux_mode, \
},
展开后:
MUX_CFG(DA850, I2C0_SDA, 4, 12, 15, 2, false)
[DA850_ I2C0_SDA]={
.name = # I2C0_SDA,
.debug = false, \
.mux_reg_name = "PINMUX"4, \
.mux_reg = PINMUX(4), \
.mask_offset = 12, \
.mask = 15, \
.mode = 2,
}
MUX_CFG(DA850, I2C0_SCL, 4, 8, 15, 2, false)
[DA850_ I2C0_SCL]={
.name = # I2C0_SCL,
.debug = false, \
.mux_reg_name = "PINMUX"4, \
.mux_reg = PINMUX(4), \
.mask_offset = 8, \
.mask = 15, \
.mode = 2,
}
接下来就是寄存器的配置,以DA850_ I2C0_SDA为例:
/* Update the mux register in question */
if (cfg->mask) {//检查mask是否被定义
unsigned tmp1, tmp2;
spin_lock_irqsave(&mux_spin_lock, flags);
reg_orig = __raw_readl(pinmux_base + cfg->mux_reg);//首先读出寄存器的初始值
mask = (cfg->mask << cfg->mask_offset);//相当于15<<12
tmp1 = reg_orig & mask;//把寄存器的12-15位保留,其余位置为0
reg = reg_orig & ~mask;//把寄存器的12-15位置0,其余位不改变
tmp2 = (cfg->mode << cfg->mask_offset);//2<<12
reg |= tmp2;//将寄存器的13位置1
if (tmp1 != tmp2)//看寄存器的值是否发生了改变,如果前后不一样,输出警告信息
warn = 1;
__raw_writel(reg, pinmux_base + cfg->mux_reg);//将修改后的寄存器状态写入相应的寄存器地址
spin_unlock_irqrestore(&mux_spin_lock, flags);
}
通过查对应的寄存器手册,可以看到这个函数作用就是实现了pinmux的功能选择
类似的分析DA850_I2C0_SCL,实现了如下管脚复用: