Rockchip+RK3399TRM+V1.1+Part2+20160728.pdf Rockchip GPIO常见问题
## 基本环境 RK3326 小板 8pin引出接口中的GPIO0_B3(实际为GPIO1_C2) RK3326 EVB开发板 RK3399 EVB开发板 Linux与Android系统都适用
FAE给的操作步骤
IOMUX复用为GPIO
GPIO设置为输出
设置GPIO高低
补充,事实上还漏了一个重要一部,要先设置时钟,否则前面的设置都不生效
RK3326寄存器手册查询
参考寄存器手册Address Maping部分 GRF基地址为0xFF140000 GPIO1基地址为0xFF250000 DDR(方向寄存器)偏移地址0x04, 所以寄存器地址为0xFF250004 DR(设置高低电平)偏移地址为0x00, 所以寄存器地址为0xFF250000 GRF_GPIO1C_IOMUX_L 偏移地址为0x10, 所以IOMUX地址为0xFF140010 GPIO1_C2对应的位为bit19
RK3326 GPIO1_C2 设置实验
读取GPIO1_C2的值(DR) io -4 -l 4 0xFF250000 输出 ff250000: 00000000 bit19 为0, 测得电压为0.26V 写入bit19 为 1 io -4 -w 0xff250000 0x00040000 回读正常,测得电压为3V 方向寄存器 io -4 -l 4 0xFF2500004 输出 ff250004: 00040000
IOMUX寄存器 io -4 -l 4 0xFF140010 输出 ff140010: 00000011 根据寄存器手册P104可知, bit11:8为0, gpio1_c2为gpio功能
RK3326 WAKE_UP设置实验(对应GPIO1_C3, 对应bit20)
有前面可知,IOMUX已经设置为GPIO 设置方向寄存器(DR)为输出 io -4 -w 0xff250004 0x000C0000 设置为高电平 io -4 -w 0xff250000 0x000C0000 回读 io -4 -l 4 0xFF250000 返回: ff250000: 000c0000 万用表测得为3V, 同理,设置为低电平,万用表测得为0.027V,实验成功!
RK3326 MAV022 GPIO驱动分析
内核文件节点 /sys/class/leds/call_answer_led/brightness echo 255 > /sys/class/leds/call_answer_led/brightness (高电平) echo 0 > /sys/class/leds/call_answer_led/brightness(低电平) 原先的驱动设计是具有pwm功能的,这里我借用了这个接口,没有pwm功能,只有高低电平 DTS中的位置 rk3326-mav022-v10.dts 关键字 搜索RK_PC2或者gpio-leds 驱动不用修改,只需要修改DTS中两处即可,移植到开发板GPIO3_C2也可行
RK3326 EVB GPIO寄存器控制
选定开发板D12-GPIO3-C0作为控制脚,对应的bit = (C-A)*8 + 0 = 16 对应位设为1, 0x00010000, 设为0, 0x00000000 设置DDR方向寄存器 io -4 -w 0xFF270004 0x00050000 设置输出为低电平 io -4 -w 0xFF270000 0x00000000 LED灯亮 设置输出为高电平 io -4 -w 0xFF270000 0x00010000 LED灯灭
这一步一开始实验一直控制无效,后来参考文档《Rockchip GPIO常见问题.pdf》,发现是CLK没有设置造成的,前面的实验之所以成功,应该是在DTS里配置了相应的管脚,CLK在驱动里已经打开,而DTS没有配置的管脚,CLK默认是关闭的
查询clk cat /sys/kernel/debug/clk/clk_summary |grep gpio GPIO3果然为0 使能GPIO3 ClK echo 1 > /sys/kernel/debug/clk/pclk_gpio3/clk_enable_count
RK3399 EVB GPIO2_B2, GPIO2_B3测试
首先根据RK3326经验查询CLK cat /sys/kernel/debug/clk/clk_summary |grep gpio
gpio2为0, 写入1 echo 1 > /sys/kernel/debug/clk/pclk_gpio2/clk_enable_count GPIO2_B2 bit位为(B-A)*8 + 2 = 10 GPIO3_B3 bit位为(B-A)*8 + 3 = 11
测试DDR寄存器 io -4 -r 0xff780004 返回 807f1
读取DR寄存器 io -4 -r 0xff780004 返回 0x3f0
开始GPIO控制 测试GPIO2_B2 写入GPIO2_B2位低电平 io -4 -w 0xff780000 0x7f0 红灯亮,设置生效 测试GPIO2_B3 写入GPIO2_B3为输出 io -4 -w 0xff780004 0x80ff1 GPIO2_B3输出为低 io -4 -w 0xff780000 0xff0 发现不生效,查询IOMUX寄存器 io -4 -r 0xff77e004 返回 0x00c0
查询寄存器文档可知bit7:6为11, gpio2_b3没有设为gpio 设置iomux为gpio io -4 -w 0xff7e004 0x0000 设置无效,可能是被驱动限制了
测试GPIO2_B1 bit位为(B-A)*8 + 1 = 9 由前面可知,DDR应该已经是输出 直接设置DR io -4 -w 0xff780000 0x5f0 设置成功,黄灯亮!
另外一种用GPIO Debug接口控制的方法
经测试Android8.1下一样可以使用 以GPIO2_B2为例
查看GPIO2_B2的gpio number
1. rk3399:/sys/kernel/debug # cat gpio
GPIOs 0-31, platform/pinctrl, gpio0:
gpio-1 ( |vcc_sd ) out lo
gpio-4 ( |bt_default_wake_host) in lo
gpio-5 ( |power ) in hi
gpio-9 ( |bt_default_reset ) out lo
gpio-10 ( |reset ) out hi
GPIOs 32-63, platform/pinctrl, gpio1:
gpio-34 ( |int-n ) in hi
gpio-35 ( |camsys_gpio ) out hi
gpio-45 ( |enable ) out hi
gpio-46 ( |vsel ) out lo
gpio-49 ( |vsel ) out lo
gpio-54 ( |mpu6500 ) in lo
GPIOs 64-95, platform/pinctrl, gpio2:
gpio-64 ( |vbus-5v ) out lo
gpio-69 ( |power33 ) out hi
gpio-70 ( |power ) out hi
gpio-71 ( |reset ) out hi
gpio-72 ( |stanby ) out hi
gpio-73 ( |power18 ) out hi
gpio-74 ( |sysfs ) out lo
gpio-76 ( |int ) in hi
gpio-83 ( |bt_default_rts ) in hi
gpio-90 ( |bt_default_wake ) in lo
可知GPIO2_B2的number 为GPIO74
导出为GPIO
rk3399:/sys/class/gpio # echo 74 > export
1|rk3399:/sys/class/gpio # ls
export gpiochip0 gpiochip32 gpiochip96
gpio74 gpiochip128 gpiochip64 unexport
rk3399:/sys/class/gpio #
设置输出高低电平 rk3399:/sys/class/gpio/gpio74 # ls
active_low device direction edge power subsystem uevent value
rk3399:/sys/class/gpio/gpio74 # echo 1 > value
rk3399:/sys/class/gpio/gpio74 # echo 0 > value
rk3399:/sys/class/gpio/gpio74 #
但同样的方法GPIO73不能导出,看来这种方法还是有些局限
Rockchip+RK3399TRM+V1.1+Part2+20160728.pdf Rockchip GPIO常见问题
## 基本环境 RK3326 小板 8pin引出接口中的GPIO0_B3(实际为GPIO1_C2) RK3326 EVB开发板 RK3399 EVB开发板 Linux与Android系统都适用
FAE给的操作步骤
IOMUX复用为GPIO
GPIO设置为输出
设置GPIO高低
补充,事实上还漏了一个重要一部,要先设置时钟,否则前面的设置都不生效
RK3326寄存器手册查询
参考寄存器手册Address Maping部分 GRF基地址为0xFF140000 GPIO1基地址为0xFF250000 DDR(方向寄存器)偏移地址0x04, 所以寄存器地址为0xFF250004 DR(设置高低电平)偏移地址为0x00, 所以寄存器地址为0xFF250000 GRF_GPIO1C_IOMUX_L 偏移地址为0x10, 所以IOMUX地址为0xFF140010 GPIO1_C2对应的位为bit19
RK3326 GPIO1_C2 设置实验
读取GPIO1_C2的值(DR) io -4 -l 4 0xFF250000 输出 ff250000: 00000000 bit19 为0, 测得电压为0.26V 写入bit19 为 1 io -4 -w 0xff250000 0x00040000 回读正常,测得电压为3V 方向寄存器 io -4 -l 4 0xFF2500004 输出 ff250004: 00040000
IOMUX寄存器 io -4 -l 4 0xFF140010 输出 ff140010: 00000011 根据寄存器手册P104可知, bit11:8为0, gpio1_c2为gpio功能
RK3326 WAKE_UP设置实验(对应GPIO1_C3, 对应bit20)
有前面可知,IOMUX已经设置为GPIO 设置方向寄存器(DR)为输出 io -4 -w 0xff250004 0x000C0000 设置为高电平 io -4 -w 0xff250000 0x000C0000 回读 io -4 -l 4 0xFF250000 返回: ff250000: 000c0000 万用表测得为3V, 同理,设置为低电平,万用表测得为0.027V,实验成功!
RK3326 MAV022 GPIO驱动分析
内核文件节点 /sys/class/leds/call_answer_led/brightness echo 255 > /sys/class/leds/call_answer_led/brightness (高电平) echo 0 > /sys/class/leds/call_answer_led/brightness(低电平) 原先的驱动设计是具有pwm功能的,这里我借用了这个接口,没有pwm功能,只有高低电平 DTS中的位置 rk3326-mav022-v10.dts 关键字 搜索RK_PC2或者gpio-leds 驱动不用修改,只需要修改DTS中两处即可,移植到开发板GPIO3_C2也可行
RK3326 EVB GPIO寄存器控制
选定开发板D12-GPIO3-C0作为控制脚,对应的bit = (C-A)*8 + 0 = 16 对应位设为1, 0x00010000, 设为0, 0x00000000 设置DDR方向寄存器 io -4 -w 0xFF270004 0x00050000 设置输出为低电平 io -4 -w 0xFF270000 0x00000000 LED灯亮 设置输出为高电平 io -4 -w 0xFF270000 0x00010000 LED灯灭
这一步一开始实验一直控制无效,后来参考文档《Rockchip GPIO常见问题.pdf》,发现是CLK没有设置造成的,前面的实验之所以成功,应该是在DTS里配置了相应的管脚,CLK在驱动里已经打开,而DTS没有配置的管脚,CLK默认是关闭的
查询clk cat /sys/kernel/debug/clk/clk_summary |grep gpio GPIO3果然为0 使能GPIO3 ClK echo 1 > /sys/kernel/debug/clk/pclk_gpio3/clk_enable_count
RK3399 EVB GPIO2_B2, GPIO2_B3测试
首先根据RK3326经验查询CLK cat /sys/kernel/debug/clk/clk_summary |grep gpio
gpio2为0, 写入1 echo 1 > /sys/kernel/debug/clk/pclk_gpio2/clk_enable_count GPIO2_B2 bit位为(B-A)*8 + 2 = 10 GPIO3_B3 bit位为(B-A)*8 + 3 = 11
测试DDR寄存器 io -4 -r 0xff780004 返回 807f1
读取DR寄存器 io -4 -r 0xff780004 返回 0x3f0
开始GPIO控制 测试GPIO2_B2 写入GPIO2_B2位低电平 io -4 -w 0xff780000 0x7f0 红灯亮,设置生效 测试GPIO2_B3 写入GPIO2_B3为输出 io -4 -w 0xff780004 0x80ff1 GPIO2_B3输出为低 io -4 -w 0xff780000 0xff0 发现不生效,查询IOMUX寄存器 io -4 -r 0xff77e004 返回 0x00c0
查询寄存器文档可知bit7:6为11, gpio2_b3没有设为gpio 设置iomux为gpio io -4 -w 0xff7e004 0x0000 设置无效,可能是被驱动限制了
测试GPIO2_B1 bit位为(B-A)*8 + 1 = 9 由前面可知,DDR应该已经是输出 直接设置DR io -4 -w 0xff780000 0x5f0 设置成功,黄灯亮!
另外一种用GPIO Debug接口控制的方法
经测试Android8.1下一样可以使用 以GPIO2_B2为例
查看GPIO2_B2的gpio number
1. rk3399:/sys/kernel/debug # cat gpio
GPIOs 0-31, platform/pinctrl, gpio0:
gpio-1 ( |vcc_sd ) out lo
gpio-4 ( |bt_default_wake_host) in lo
gpio-5 ( |power ) in hi
gpio-9 ( |bt_default_reset ) out lo
gpio-10 ( |reset ) out hi
GPIOs 32-63, platform/pinctrl, gpio1:
gpio-34 ( |int-n ) in hi
gpio-35 ( |camsys_gpio ) out hi
gpio-45 ( |enable ) out hi
gpio-46 ( |vsel ) out lo
gpio-49 ( |vsel ) out lo
gpio-54 ( |mpu6500 ) in lo
GPIOs 64-95, platform/pinctrl, gpio2:
gpio-64 ( |vbus-5v ) out lo
gpio-69 ( |power33 ) out hi
gpio-70 ( |power ) out hi
gpio-71 ( |reset ) out hi
gpio-72 ( |stanby ) out hi
gpio-73 ( |power18 ) out hi
gpio-74 ( |sysfs ) out lo
gpio-76 ( |int ) in hi
gpio-83 ( |bt_default_rts ) in hi
gpio-90 ( |bt_default_wake ) in lo
可知GPIO2_B2的number 为GPIO74
导出为GPIO
rk3399:/sys/class/gpio # echo 74 > export
1|rk3399:/sys/class/gpio # ls
export gpiochip0 gpiochip32 gpiochip96
gpio74 gpiochip128 gpiochip64 unexport
rk3399:/sys/class/gpio #
设置输出高低电平 rk3399:/sys/class/gpio/gpio74 # ls
active_low device direction edge power subsystem uevent value
rk3399:/sys/class/gpio/gpio74 # echo 1 > value
rk3399:/sys/class/gpio/gpio74 # echo 0 > value
rk3399:/sys/class/gpio/gpio74 #
但同样的方法GPIO73不能导出,看来这种方法还是有些局限
举报