RK芯片引脚寄存器修改

此前遇到用户层无法控制的GPIO引脚,命令也没法改变GPIO高低电平,也没有被别的功能复用,困惑了很久,才知道,硬件地址的寄存器,存在初始固化的操作,将gpio的功能已经写死,需要用修改寄存器的值来改变。以此做个笔记。

一、准备工作

        要知道所操作的GPIO地址,首先拿到数据手册《Rockchip RK3528 TRM Part1》;

        其次,在手册搜对应引脚,我的是gpio2a5

        

知道基地址和偏移地址,和对应的寄存器数值对应的功能

二、解决的思路

        1、通过内核驱动访问寄存器,修改;

        2、通过、/dev/mem,直接访问寄存器;

        3、通过寄存器工具,(devmem2, 或者 RK提供的IO工具);

简单测试可行性,可以直接用寄存器工具,这里我是必须更改寄存器的,所以我选更为 安全 ,可控,不会破坏系统稳定性的内核驱动方式修改。

三,通过内核驱动访问寄存器,修改对应的值

        1、在内核驱动文件下,创造一个.c文件

                 touch  drivers/misc/rk3528_iomux_multi_we.c
        2、实现具体的操作,提醒一句,这里要熟悉平台的操作方式,就比如我这是RK平台,它有一个Rockchip IOC 的「write-enable 掩码写寄存器机制, 不能单独的写对应位,要同时写高 16 位:write_enable和低 16 位:目标值,代码如下:

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>

#define IOMUX_BASE  0xFF570000
#define IOMUX_SIZE  0x200

struct rk_iomux_cfg {
    u32 offset;   /* 寄存器偏移 */
    u8  shift;    /* 位起始 */
    u8  width;    /* 位宽 */
    u32 value;    /* 写入值 */
};

/*
 * ===== 在这里配置你要改的 pin =====
 * 注意:value 是功能选择值,不是 mask
 */
static struct rk_iomux_cfg iomux_cfgs[] = {
    /* GPIO2_A4 / A5 / A6 -> GPIO */
    { 0x44,  0, 4, 0x0 }, /* gpio2a4_sel */
    { 0x44,  4, 4, 0x0 }, /* gpio2a5_sel */
    { 0x44,  8, 4, 0x0 }, /* gpio2a6_sel */
    /*这里可以添加更多引脚*/
};

static int __init rk3528_iomux_multi_init(void)
{
    void __iomem *base;
    u32 we_mask, val_mask;
    int i;

    base = ioremap(IOMUX_BASE, IOMUX_SIZE);
    if (!base)
        return -ENOMEM;

    /*
     * 每个 offset 单独组合一次 write_enable + value
     * 防止不同寄存器混写
     */
    for (i = 0; i < ARRAY_SIZE(iomux_cfgs); ) {
        u32 offset = iomux_cfgs[i].offset;
        u32 write_val = 0;

        we_mask  = 0;
        val_mask = 0;

        /* 合并同一个寄存器里的多个 pin */
        for (; i < ARRAY_SIZE(iomux_cfgs) &&
               iomux_cfgs[i].offset == offset; i++) {

            struct rk_iomux_cfg *c = &iomux_cfgs[i];
            u32 mask = ((1 << c->width) - 1);

            /* write_enable 对应低16位 */
            we_mask  |= (mask << c->shift);
            val_mask |= (c->value & mask) << c->shift;
        }

        write_val = (we_mask << 16) | val_mask;

        writel(write_val, base + offset);

        pr_info("IOMUX WE: off=0x%x we=0x%04x val=0x%04x\n",
                offset, we_mask, val_mask);
    }

    iounmap(base);
    return 0;
}

late_initcall(rk3528_iomux_multi_init);

        3、Makefile(编进内核)                

                drivers/misc/Makefile:

                                obj-y += rk3528_iomux_multi_we.o
        4、启动后你应该看到的 dmesg

                IOMUX WE: off=0x44 we=0x0fff val=0x0000

                这就更改成功了。

四、其它两种方法,更为简单,只是为了系统安全,后续会补充剩余两种方法的详细操作步骤

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值