/**********************************************************************************************                           TI AM335x Linux MUX hacking*  声明:*      1. 本文主要是对TI的AM335x Linux驱动中的引脚复用配置代码进行跟踪;*      2. 参考书籍:AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference Manual**                                             2015-6-25 阵雨 深圳 南山平山村 曾剑锋*********************************************************************************************/\\\\\\\\\\\\\-*- 目录 -*-/| 一、跟踪板级文件:                 | 二、跟踪am335x_evm_init()函数:    | 三、跟踪board_mux参数:            | 四、跟踪am33xx_mux_init()函数:    | 五、跟踪am33xx_muxmodes参数:     | 六、跟踪omap_mux_init()函数:      | 七、跟踪omap_mux_init_list()函数: | 八、跟踪omap_mux_init_signals函数:\\\\\\\\\\\\\\\\\\\\//
一、跟踪板级文件:......MACHINE_START(AM335XEVM, "am335xevm")/* Maintainer: Texas Instruments */.atag_offset    = 0x100,.map_io     = am335x_evm_map_io,.init_early = am33xx_init_early,.init_irq   = ti81xx_init_irq,.handle_irq     = omap3_intc_handle_irq,.timer      = &omap3_am33xx_timer,.init_machine   = am335x_evm_init,          // 跟踪该函数MACHINE_END                                            ^|MACHINE_START(AM335XIAEVM, "am335xiaevm")              |/* Maintainer: Texas Instruments */                |.atag_offset    = 0x100,                           |.map_io     = am335x_evm_map_io,                   |.init_irq   = ti81xx_init_irq,                     |.init_early = am33xx_init_early,                   |.timer      = &omap3_am33xx_timer,                 |.init_machine   = am335x_evm_init,    -------------+MACHINE_END二、跟踪am335x_evm_init()函数:static void __init am335x_evm_init(void){am33xx_cpuidle_init();am33xx_mux_init(board_mux);         // 跟踪函数、参数
        omap_serial_init();am335x_evm_i2c_init();omap_sdrc_init(NULL, NULL);usb_musb_init(&musb_board_data);omap_board_config = am335x_evm_config;omap_board_config_size = ARRAY_SIZE(am335x_evm_config);/* Create an alias for icss clock */if (clk_add_alias("pruss", NULL, "pruss_uart_gclk", NULL))pr_warn("failed to create an alias: icss_uart_gclk --> pruss\n");/* Create an alias for gfx/sgx clock */if (clk_add_alias("sgx_ck", NULL, "gfx_fclk", NULL))pr_warn("failed to create an alias: gfx_fclk --> sgx_ck\n");} 三、跟踪board_mux参数:1. 跟踪board_mux[]数组:static struct omap_board_mux board_mux[] __initdata = {/** Setting SYSBOOT[5] should set xdma_event_intr0 pin to mode 3 thereby* allowing clkout1 to be available on xdma_event_intr0.* However, on some boards (like EVM-SK), SYSBOOT[5] isn't properly* latched.* To be extra cautious, setup the pin-mux manually.* If any modules/usecase requries it in different mode, then subsequent* module init call will change the mux accordingly.** 参考书籍:AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference Manual -- 760页* --------------------------------------------------------------------* | Offset | Acronym               | Register | Description Section  |* --------------------------------------------------------------------* | 9B0h   | conf_xdma_event_intr0 |          | Section 9.3.51       |* --------------------------------------------------------------------* 观察上面的内容和接下来要配置引脚,我们只需要将Acronym中的conf_前缀去掉,* 然后将剩下的字符串大写,就能配置对应的引脚了,如:*      1. conf_xdma_event_intr0*      2. xdma_event_intr0*      3. XDMA_EVENT_INTR0*                 |*                 |*/                VAM33XX_MUX(XDMA_EVENT_INTR0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT), // 跟踪宏AM33XX_MUX(I2C0_SDA, OMAP_MUX_MODE0 | AM33XX_SLEWCTRL_SLOW |AM33XX_INPUT_EN | AM33XX_PIN_OUTPUT),AM33XX_MUX(I2C0_SCL, OMAP_MUX_MODE0 | AM33XX_SLEWCTRL_SLOW |AM33XX_INPUT_EN | AM33XX_PIN_OUTPUT),{ .reg_offset = OMAP_MUX_TERMINATOR }, //后面的程序通过判断这个表示来结束注册
        };2. 跟踪struct omap_board_mux结构体:/**  * struct omap_board_mux - data for initializing mux registers* @reg_offset: mux register offset from the mux base* @mux_value:  desired mux value to set */          struct omap_board_mux {u16 reg_offset;u16 value;};3. 跟踪AM33XX_MUX()宏:/* If pin is not defined as input, pull would get disabled.* If defined as input, flags supplied will determine pull on/off.*/  // 以此为例://     AM33XX_MUX(XDMA_EVENT_INTR0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT)//// .reg_offset = (AM33XX_CONTROL_PADCONF_XDMA_EVENT_INTR0_OFFSET) // 跟踪宏   // .value      = (((OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT) & AM33XX_INPUT_EN) \//               ? (OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT) \//               : ((mux_value) | AM33XX_PULL_DISA)) #define AM33XX_MUX(mode0, mux_value)                    \{                                   \.reg_offset = (AM33XX_CONTROL_PADCONF_##mode0##_OFFSET),    \.value      = (((mux_value) & AM33XX_INPUT_EN) ? (mux_value)\: ((mux_value) | AM33XX_PULL_DISA)),    \}4. 跟踪模式宏声明:/* 34xx mux mode options for each pin. See TRM for options */#define OMAP_MUX_MODE0      0#define OMAP_MUX_MODE1      1#define OMAP_MUX_MODE2      2#define OMAP_MUX_MODE3      3#define OMAP_MUX_MODE4      4#define OMAP_MUX_MODE5      5#define OMAP_MUX_MODE6      6#define OMAP_MUX_MODE7      75. 跟踪输出宏声明:/* Definition of output pin could have pull disabled, but* this has not been done due to two reasons* 1. AM33XX_MUX will take care of it* 2. If pull was disabled for out macro, combining out & in pull on macros*    would disable pull resistor and AM33XX_MUX cannot take care of the*    correct pull setting and unintentionally pull would get disabled*/#define AM33XX_PIN_OUTPUT       (0)6. 跟踪引脚配置偏移宏,并对比数据手册:// 参考书籍:AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference Manual -- 760页// -----------------------------------------------------------------------// | Offset | Acronym               | Register   |  Description Section  |// +--------+-----------------------+------------+-----------------------+// | 9B0h   | conf_xdma_event_intr0 |            |  Section 9.3.51       |// -----------------------------------------------------------------------#define AM33XX_CONTROL_PADCONF_XDMA_EVENT_INTR0_OFFSET      0x09B0四、跟踪am33xx_mux_init()函数:1. 跟踪am33xx_mux_init()函数:int __init am33xx_mux_init(struct omap_board_mux *board_subset){return omap_mux_init("core", 0, AM33XX_CONTROL_PADCONF_MUX_PBASE, // 跟踪参数
                AM33XX_CONTROL_PADCONF_MUX_SIZE, am33xx_muxmodes,NULL, board_subset, NULL);}2. 跟踪AM33XX_CONTROL_PADCONF_MUX_PBASE宏:// 参考书籍:AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference  Manual -- 158页// ----------------------------------------------------------------------------------------------------// | Region Name     | Start Address (hex) | End Address (hex)  | Size   |       Description          |// +-----------------+---------------------+--------------------+--------+----------------------------+// | Control Module  |  0x44E1_0000        | 0x44E1_1FFF        | 128KB  |  Control Module Registers  |// ----------------------------------------------------------------------------------------------------#define AM33XX_CONTROL_PADCONF_MUX_PBASE            0x44E10000LU3. 跟踪AM33XX_CONTROL_PADCONF_MUX_SIZE宏:// 参考书籍:AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference  Manual -- 761页// 这里的大小没有搞懂,在datasheet中是1444h,而这里是B34h,没搞懂// ----------------------------------------------------------------// | Offset | Acronym           | Register | Description Section  |// +--------+-------------------+----------+----------------------+// | 1444h  | ddr_data1_ioctrl  |          | Section 9.3.92       |// ----------------------------------------------------------------#define AM33XX_CONTROL_PADCONF_VREFN_OFFSET         0x0B34          #define AM33XX_CONTROL_PADCONF_MUX_SIZE             \(AM33XX_CONTROL_PADCONF_VREFN_OFFSET + 0x4)五、跟踪am33xx_muxmodes参数:1. 跟踪am33xx_muxmodes[]数组:/* AM33XX pin mux super set */static struct omap_mux am33xx_muxmodes[] = {_AM33XX_MUXENTRY(GPMC_AD0, 0,"gpmc_ad0", "mmc1_dat0", NULL, NULL,NULL, NULL, NULL, "gpio1_0"),_AM33XX_MUXENTRY(GPMC_AD1, 0,"gpmc_ad1", "mmc1_dat1", NULL, NULL,NULL, NULL, NULL, "gpio1_1"),_AM33XX_MUXENTRY(GPMC_AD2, 0,"gpmc_ad2", "mmc1_dat2", NULL, NULL,NULL, NULL, NULL, "gpio1_2"),_AM33XX_MUXENTRY(GPMC_AD3, 0,"gpmc_ad3", "mmc1_dat3", NULL, NULL,NULL, NULL, NULL, "gpio1_3"),_AM33XX_MUXENTRY(GPMC_AD4, 0,"gpmc_ad4", "mmc1_dat4", NULL, NULL,NULL, NULL, NULL, "gpio1_4"),......{ .reg_offset = OMAP_MUX_TERMINATOR },  //后面的程序通过判断这个表示来结束注册
        }2. 跟踪struct omap_mux结构体:/*** struct omap_mux - data for omap mux register offset and it's value* @reg_offset: mux register offset from the mux base* @gpio:       GPIO number* @muxnames:   available signal modes for a ball* @balls:      available balls on the package* @partition:  mux partition*/struct omap_mux {u16 reg_offset;u16 gpio;#ifdef CONFIG_OMAP_MUXchar    *muxnames[OMAP_MUX_NR_MODES];#ifdef CONFIG_DEBUG_FSchar    *balls[OMAP_MUX_NR_SIDES];#endif   #endif}; 2. 跟踪_AM33XX_MUXENTRY宏://// 以此为例://  _AM33XX_MUXENTRY(GPMC_AD0, 0, "gpmc_ad0", "mmc1_dat0", NULL, NULL, NULL, NULL, NULL, "gpio1_0")//  // .reg_offset = AM33XX_CONTROL_PADCONF_GPMC_AD0_OFFSET // .gpio       = 0      // 相当于取下面muxnames中的第0个// .muxnames   = {"gpmc_ad0", "mmc1_dat0", NULL, NULL, NULL, NULL, NULL, "gpio1_0"}#define _AM33XX_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7)     \{                                   \.reg_offset = (AM33XX_CONTROL_PADCONF_##M0##_OFFSET),   \.gpio       = (g),                      \.muxnames   = { m0, m1, m2, m3, m4, m5, m6, m7 },       \}3. 跟踪AM33XX_CONTROL_PADCONF_GPMC_AD0_OFFSET宏,并对比datasheet:// 参考书籍:AM335x ARM® Cortex™-A8 Microprocessors (MPUs) Technical Reference Manual -- 758页// ------------------------------------------------------------------------------------------------------------// | Offset | Acronym        | Register  | Description Section                                                // +--------+----------------+-----------+---------------------------------------------------------------------// | 800h   | conf_gpmc_ad0  |           | See the device datasheet for information on default pin Section 9.3.51// ------------------------------------------------------------------------------------------------------------#define AM33XX_CONTROL_PADCONF_GPMC_AD0_OFFSET          0x0800六、跟踪omap_mux_init()函数:int __init omap_mux_init(const char *name, u32 flags,u32 mux_pbase, u32 mux_size,struct omap_mux *superset,struct omap_mux *package_subset,struct omap_board_mux *board_mux,struct omap_ball *package_balls){struct omap_mux_partition *partition;partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);if (!partition)return -ENOMEM;partition->name = name;                             // 分区的意思相当于模块的意思partition->flags = flags;partition->size = mux_size;partition->phys = mux_pbase;partition->base = ioremap(mux_pbase, mux_size);     // 重新映射IO地址if (!partition->base) {pr_err("%s: Could not ioremap mux partition at 0x%08x\n",__func__, partition->phys);kfree(partition);return -ENODEV;}INIT_LIST_HEAD(&partition->muxmodes);               // 初始化分区头结点链表
    list_add_tail(&partition->node, &mux_partitions);   // 将分区加入分区链表mux_partitions_cnt++;                               // 分区总数统计pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,mux_partitions_cnt, partition->name, partition->flags);omap_mux_init_package(superset, package_subset, package_balls); // 两个都是nullomap_mux_init_list(partition, superset);                        // 跟踪函数omap_mux_init_signals(partition, board_mux);                    // 跟踪函数return 0;}七、跟踪omap_mux_init_list()函数:1. 跟踪omap_mux_init_list()函数:/** Note if CONFIG_OMAP_MUX is not selected, we will only initialize* the GPIO to mux offset mapping that is needed for dynamic muxing* of GPIO pins for off-idle.*/static void __init omap_mux_init_list(struct omap_mux_partition *partition,struct omap_mux *superset){while (superset->reg_offset !=  OMAP_MUX_TERMINATOR) {struct omap_mux *entry;// 去掉一些不符合要求的的配置引脚
        #ifdef CONFIG_OMAP_MUXif (!superset->muxnames || !superset->muxnames[0]) {superset++;continue;}#else/* Skip pins that are not muxed as GPIO by bootloader */if (!OMAP_MODE_GPIO(omap_mux_read(partition,superset->reg_offset))) {superset++;continue;}#endifentry = omap_mux_list_add(partition, superset);if (!entry) {pr_err("%s: Could not add entry\n", __func__);return;}superset++;}}2. 跟踪omap_mux_list_add()函数:static struct omap_mux * __init omap_mux_list_add(struct omap_mux_partition *partition,struct omap_mux *src){struct omap_mux_entry *entry;struct omap_mux *m;entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);if (!entry)return NULL;m = &entry->mux;entry->mux = *src;#ifdef CONFIG_OMAP_MUXif (omap_mux_copy_names(src, m)) {      // 将数据另存的感觉
                kfree(entry);return NULL;}#endifmutex_lock(&muxmode_mutex);list_add_tail(&entry->node, &partition->muxmodes);      // 将节点放入分区节点链表中mutex_unlock(&muxmode_mutex);return m;}3. 跟踪omap_mux_copy_names()函数:// 这个函数的大概意思也就是转存的感觉static int __init omap_mux_copy_names(struct omap_mux *src,struct omap_mux *dst){int i;for (i = 0; i < OMAP_MUX_NR_MODES; i++) {if (src->muxnames[i]) {dst->muxnames[i] = kstrdup(src->muxnames[i],GFP_KERNEL);if (!dst->muxnames[i])goto free;}}#ifdef CONFIG_DEBUG_FSfor (i = 0; i < OMAP_MUX_NR_SIDES; i++) {if (src->balls[i]) {dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL);if (!dst->balls[i])goto free;}}#endifreturn 0;free:omap_mux_free_names(dst);return -ENOMEM;}八、跟踪omap_mux_init_signals函数:1. 跟踪omap_mux_init_signals()函数:static void omap_mux_init_signals(struct omap_mux_partition *partition,struct omap_board_mux *board_mux){omap_mux_set_cmdline_signals();             // 不知道这里是干啥的,不跟踪omap_mux_write_array(partition, board_mux); // 跟踪该函数
        }2. 跟踪omap_mux_write_array()函数:void omap_mux_write_array(struct omap_mux_partition *partition,struct omap_board_mux *board_mux){if (!board_mux)return;while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {omap_mux_write(partition, board_mux->value,  // 跟踪函数board_mux->reg_offset);board_mux++;}}3. 跟踪am33xx_mux_init()函数:/** int __init am33xx_mux_init(struct omap_board_mux *board_subset)*  {   *      return omap_mux_init("core", 0 /* flag = 0 */, AM33XX_CONTROL_PADCONF_MUX_PBASE,*              AM33XX_CONTROL_PADCONF_MUX_SIZE, am33xx_muxmodes,*              NULL, board_subset, NULL);*  } */void omap_mux_write(struct omap_mux_partition *partition, u16 val,u16 reg){if (partition->flags & OMAP_MUX_REG_8BIT)__raw_writeb(val, partition->base + reg);else__raw_writew(val, partition->base + reg);}4. 跟踪OMAP_MUX_REG_8BIT宏:/*              * omap_mux_init flags definition:*   * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.* The default value is 16 bits.* OMAP_MUX_GPIO_IN_MODE3: The GPIO is selected in mode3.* The default is mode4.*/#define OMAP_MUX_REG_8BIT       (1 << 0)

转载于:https://www.cnblogs.com/zengjfgit/p/4599595.html

TI AM335x Linux MUX hacking相关推荐

  1. TI am335x OMAP MUX configure

    http://blog.chinaunix.net/uid-20543672-id-3067021.html Linux下TI omap芯片 MUX 配置分析(以AM335X芯片为例)  在移植内核的 ...

  2. linux 内核代码分析1 TI am335x

    1.     TI AM335x  内核源码分析 1.1 Board-am335xevm.c Board-am335xevm.c(./arch/arm/mach-omap2)中开始执行入口: MACH ...

  3. a335x换linux内核,linux 内核代码分析1 TI am335x

    1.     TI AM335x  内核源码分析 1.1 Board-am335xevm.c Board-am335xevm.c(./arch/arm/mach-omap2)中开始执行入口: MACH ...

  4. a335x换linux内核,linux 內核代碼分析1 TI am335x

    1.     TI AM335x  內核源碼分析 1.1 Board-am335xevm.c Board-am335xevm.c(./arch/arm/mach-omap2)中開始執行入口: MACH ...

  5. TI am335x U-boot

    http://blog.chinaunix.NET/uid-28458801-id-3486399.html 参考文件: 1,AM335x ARM Cortex-A8 Microprocessors ...

  6. 创龙基于TI AM335x ARM Cortex-A8 CPU,主频高达1GHz开发板规格书,用于电力控制

    TL335x-EVM是由广州创龙基于TI ARM Cortex-A8而设计的工业级开发板.它为用户提供了SOM-TL335x核心板的测试平台,用于快速评估SOM-TL335x核心板的整体性能. TL3 ...

  7. 基于TI AM335x创龙开发板U-Boot编译

    分享一下基于广州创龙TL335x-IDK开发板的U-Boot编译.希望能帮助上你. 板子特点如下:  基于 TI AM335x ARM Cortex-A8 CPU,主频可高达 1GHz,运算能力可高 ...

  8. 基于TI AM335x ARM Cortex-A8 CPU 核心板

    核心板简介 基于TI AM335x ARM Cortex-A8 CPU,主频高达1GHz,运算能力高达2000DMIPS,搭配DDR3,兼容eMMC和NAND FLASH,性价比高: pin to p ...

  9. TI am335x U-boot移植(正常启动)

    ****************************************************************** 深圳南山 2017/09/26 ***************** ...

  10. 创龙基于TI AM335x ARM Cortex-A8 CPU,主频高达1GHz核心板规格书

    由广州创龙自主研发的SOM-TL335x是体积极小的AM335x Cortex-A8工业级核心板.采用沉金无铅工艺的8层板设计,专业的PCB Layout保证信号完整性的同时,经过严格的质量控制,满足 ...

最新文章

  1. 线程间操作无效: 从不是创建控件的线程访问它
  2. 网络与服务器编程框架库 acl_3.0.13 发布
  3. letswave7中文教程2:脑电数据预处理-通道位置分配
  4. BZOJ4155 : [Ipsc2015]Humble Captains
  5. 【安全漏洞】SRC另类思路分享:不受限制的资源调用
  6. python 绘图与可视化 Graphviz 二叉树 、 error: Microsoft Visual C++ 14.0 is required
  7. 设计模式_1_工厂模式与抽象工厂
  8. 沐猿而冠 -教育-读书笔记(一)
  9. sublime_text_2 注册
  10. 如何做web程序权限管理
  11. oracle instant client package,Oracle数据库之Oracle Instant Client的安装和使用
  12. android模拟器设置静态ip,安卓模拟器多开挂手游改IP防封号技术讲解
  13. 【rfc5506】RTCP mode
  14. 【R言R语】算法工程师入职一年半的总结与感悟
  15. Solidity 生成Java类
  16. 特斯拉充电电流设置多大_特斯拉再次升级Model S 充电状况不稳时自动降低电流...
  17. iOS闪退问题,避免闪退看我就足够了, try catch等方法
  18. 3ds max材质库操作
  19. 在OpenCV里车牌识别的方法2
  20. Python+Office:轻松实现python自动化办公

热门文章

  1. 编码基本功:性能测试工具可用于检查死循环
  2. 别人问了个问题:有没有选择JAVA开发的设计文档
  3. unknown type name err_status_t; did you mean srtp_err_status_t/err_status_ok/err_status_replay_fail
  4. LINUX下载及编译libtool
  5. 编译OpenJDK12:LINK : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
  6. 一个简单进程池的实现
  7. wait和waitpid
  8. 如何用c语言做衣物存放系统,C语言一个简单的商店管理系统
  9. python爬虫好学不_python爬虫难学吗
  10. access html导出,AccessToFile