Openwrt中MT7628/MT7688的全部GPIO复用配置及常用接口DTS配置总结

Openwrt的不同版本中关于MT7628,MT7688的GPIO配置,存在或多或少的一些小问题

下面将以MT7628AN为基础,介绍其全部的GPIO功能复用配置,以及需要注意的地方

MT76x8一个就47个可作为GPIO引脚,如下

 关于其全部的功能复用表可以参考MTK官方的开发demo版Linkit

 在这全部的引脚中,需要特别注意的是:

1. 网口模式,因为MTK的设计,一共5个网口,要么全部作为普通网口使用,要么只有一个网口(Port0),没有中间选项;

因此,如果需要用到UART2,SDCARD等功能时,系统只剩一个P0网口可用,这也是MTK所宣传的IOT模式

2. SPI接口,datasheet介绍可以作为GPIO使用,但是因为大多系统都接了SPI NOR Flash,因此其不能设置为GPIO模式;而SPI_CS1另一个SPI片选脚,倒是不受影响,可作为GPIO

3. 关于GPIO/GPO的描述,比如I2C的两个脚是GPO,但经实际测试,描述为GPO的其实可以作为输入使用

 

关于DTS配置,其主要参考arch/mips/ralink/mt7620.c文件

 
  1. static struct rt2880_pmx_group mt7628an_pinmux_data[] = {

  2. GRP_G("pwm1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,

  3. 1, MT7628_GPIO_MODE_PWM1),

  4. GRP_G("pwm0", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,

  5. 1, MT7628_GPIO_MODE_PWM0),

  6. GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,

  7. 1, MT7628_GPIO_MODE_UART2),

  8. GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK,

  9. 1, MT7628_GPIO_MODE_UART1),

  10. GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK,

  11. 1, MT7628_GPIO_MODE_I2C),

  12. GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK),

  13. GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST),

  14. GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT),

  15. GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI),

  16. GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK,

  17. 1, MT7628_GPIO_MODE_SDMODE),

  18. GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK,

  19. 1, MT7628_GPIO_MODE_UART0),

  20. GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK,

  21. 1, MT7628_GPIO_MODE_I2S),

  22. GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK,

  23. 1, MT7628_GPIO_MODE_CS1),

  24. GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK,

  25. 1, MT7628_GPIO_MODE_SPIS),

  26. GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,

  27. 1, MT7628_GPIO_MODE_GPIO),

  28. GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK,

  29. 1, MT7628_GPIO_MODE_WLED_AN)

  30. }

在DTS文件中,填写对应的name和func名字就可以,如:

 
  1. pinctrl {

  2. state_default: pinctrl0 {

  3. gpio {

  4. ralink,group = "gpio","wled_an", "i2s", "refclk", "perst", "wdt", "spi cs1";

  5. ralink,function = "gpio";

  6. };

  7. }

常用接口及功能配置如下:

UART1开启:

 
  1. uart1@d00 {

  2. status = "okay";

  3. };

SPI_CS1 开启,使用系统spi控制器,注意pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>,配置CS1为SPI_CS1功能,同时应该去掉pinctrl0中"spi cs1"的GPIO复用

 
  1. spi@b00 {

  2. status = "okay";

  3.  
  4. pinctrl-names = "default";

  5. pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;

  6.  
  7. spidev@1 {

  8. #address-cells = <1>;

  9. #size-cells = <1>;

  10. compatible = "spidev";

  11. reg = <1 0>;

  12. spi-max-frequency = <40000000>;

  13. };

  14. }

GPIO模拟SPI配置,如:使用I2S的复用脚0-3,注意先配置I2S为GPIO模式

 
  1. spi-gpio {

  2. compatible = "spi-gpio";

  3. #address-cells = <0x1>;

  4. cs-gpios = <&gpio0 2 0>;

  5. gpio-sck = <&gpio0 0 0>;

  6. gpio-mosi = <&gpio0 3 0>;

  7. gpio-miso = <&gpio0 1 0>;

  8. num-chipselects = <1>;

  9. spidev@0 {

  10. #address-cells = <0x1>;

  11. compatible = "spidev";

  12. spi-max-frequency = <10000000>;

  13. reg = <0>;

  14. };

  15. };

I2C的RTC时钟配置,以PCF8563为例,注意reg地址的问题,pcf8563地址是0x51,常用的ds1307是0x68

 
  1. i2c@900 {

  2. status = "okay";

  3. rtc@51 {

  4. compatible = "nxp,pcf8563";

  5. reg = <0x51>;

  6. };

  7. };

LED配置参考,注意MT76x8有两组GPIO,GPIO0对应0-31,GPIO1对应32-46

 
  1. gpio-leds {

  2. compatible = "gpio-leds";

  3. modpwr {

  4. label = "modpwr";

  5. gpios = <&gpio1 8 1>;

  6. };

  7. modrst {

  8. label = "modrst";

  9. gpios = <&gpio1 4 0>;

  10. };

  11. heart {

  12. label = "heart";

  13. gpios = <&gpio1 6 1>;

  14. };

  15. }

lable对应运行系统中/sys/class/leds/lable/brightness 的lable名字

gpios = <&gpio1 8 1>; 表示GPIO1组,8 表示 32+8 即GPIO40,1表示低电平有效,即默认输出高电平

按键配置参考,

 
  1. gpio-keys-polled {

  2. compatible = "gpio-keys-polled";

  3. #address-cells = <1>;

  4. #size-cells = <0>;

  5. poll-interval = <20>;

  6. vccin {

  7. label = "BTN_0";

  8. gpios = <&gpio0 6 0>;

  9. linux,code = <0x100>;

  10. };

  11. reset {

  12. label = "reset";

  13. gpios = <&gpio1 7 1>;

  14. linux,code = <0x198>;

  15. };

  16. };

poll-interval 表示输入检测消抖时间,label对应于运行系统中/etc/rc.button/lable,即按键后对应的执行脚本文件,如上述配置,系统中应该存在reset和BTN_0两个脚本, gpios同LED说明

linux,code = <0x198>; 对应input.h的宏定义值,配合驱动文件gpio-button-hotplug.c中的相关配置,如:

 
  1. static struct bh_map button_map[] = {

  2. BH_MAP(BTN_0, "BTN_0"),

  3. BH_MAP(BTN_1, "BTN_1"),

  4. BH_MAP(BTN_2, "BTN_2"),

  5. BH_MAP(BTN_3, "BTN_3"),

  6. BH_MAP(BTN_4, "BTN_4"),

  7. BH_MAP(BTN_5, "BTN_5"),

  8. BH_MAP(BTN_6, "BTN_6"),

  9. BH_MAP(BTN_7, "BTN_7"),

  10. BH_MAP(BTN_8, "BTN_8"),

  11. BH_MAP(BTN_9, "BTN_9"),

  12. BH_MAP(KEY_POWER, "power"),

  13. BH_MAP(KEY_RESTART, "reset"),

  14. BH_MAP(KEY_RFKILL, "rfkill"),

  15. BH_MAP(KEY_WPS_BUTTON, "wps"),

  16. BH_MAP(KEY_WIMAX, "wwan"),

  17. };

其原理是gpio-button-hotplug驱动会检测按键事件,然后通过netlionk方式广播出来,proc会一直监测事件,触发hotplug,进而执行到相关reset等脚本,热拔插事件也是此类方式,具体不再详细介绍,本文主要介绍引脚复用配置

另,还需注意的是,配置了相关引脚功能后,还需在kernel中开启相关驱动模块以及选择相关的应用才能正常使用

到此,常用接口基本介绍完毕

下面大概提一下不同openwrt版本中的代码错误,以下只贴出正确的code,各位看客有功能错误的各自根据自己的现有版本对比修正即可

1. 看门狗dts 地址错误,位置:target/linux/ramips/dts/mt7628an.dtsi

 
  1. watchdog: watchdog@100 {

  2. compatible = "ralink,mt7628an-wdt", "mediatek,mt7621-wdt";

  3. reg = <0x100 0x30>;

  4.  
  5. resets = <&rstctrl 8>;

  6. reset-names = "wdt";

  7.  
  8. interrupt-parent = <&intc>;

  9. interrupts = <24>;

  10. };

根据DataSheet,watchdog的偏移地址应该是100

同时,如果需要自行喂狗的话,注意先关闭proc进程中自动喂狗功能

2. REFCLK,PERST的配置错误,位置arch/mips/ralink/mt7620.c,原来的reclk和perst引脚配置反了

 
  1. static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 37, 1) };

  2. static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };

3. PHY 0-4的LED不能作为GPIO的问题,参考补丁文件:

 
  1. --- a/arch/mips/ralink/mt7620.c 2018-09-04 17:14:33.000000000 +0800

  2. +++ b/arch/mips/ralink/mt7620.c 2018-04-09 08:28:51.000000000 +0800

  3. @@ -138,8 +138,8 @@

  4. FUNC("i2c", 0, 4, 2),

  5. };

  6.  
  7. -static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };

  8. -static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };

  9. +static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 37, 1) };

  10. +static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 36, 1) };

  11. static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 38, 1) };

  12. static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };

  13.  
  14. @@ -185,23 +185,50 @@

  15. FUNC("gpio", 0, 11, 1),

  16. };

  17.  
  18. -static struct rt2880_pmx_func wled_kn_grp_mt7628[] = {

  19. - FUNC("rsvd", 3, 35, 1),

  20. - FUNC("rsvd", 2, 35, 1),

  21. - FUNC("gpio", 1, 35, 1),

  22. - FUNC("wled_kn", 0, 35, 1),

  23. +struct rt2880_pmx_func wled_an_grp_mt7628[] = {

  24. + FUNC("rsvd", 3, 44, 1),

  25. + FUNC("rsvd", 2, 44, 1),

  26. + FUNC("gpio", 1, 44, 1),

  27. + FUNC("wled_an", 0,44, 1),

  28. +};

  29. +

  30. +static struct rt2880_pmx_func ephy_p0_grp_mt7628[] = {

  31. + FUNC("rsvd", 3, 43, 1),

  32. + FUNC("rsvd", 2, 43, 1),

  33. + FUNC("gpio", 1, 43, 1),

  34. + FUNC("ephy", 0, 43, 1),

  35. +};

  36. +

  37. +static struct rt2880_pmx_func ephy_p1_grp_mt7628[] = {

  38. + FUNC("rsvd", 3, 42, 1),

  39. + FUNC("rsvd", 2, 42, 1),

  40. + FUNC("gpio", 1, 42, 1),

  41. + FUNC("ephy", 0, 42, 1),

  42. +};

  43. +static struct rt2880_pmx_func ephy_p2_grp_mt7628[] = {

  44. + FUNC("rsvd", 3, 41, 1),

  45. + FUNC("rsvd", 2, 41, 1),

  46. + FUNC("gpio", 1, 41, 1),

  47. + FUNC("ephy", 0, 41, 1),

  48. +};

  49. +static struct rt2880_pmx_func ephy_p3_grp_mt7628[] = {

  50. + FUNC("rsvd", 3, 40, 1),

  51. + FUNC("rsvd", 2, 40, 1),

  52. + FUNC("gpio", 1, 40, 1),

  53. + FUNC("ephy", 0, 40, 1),

  54. +};

  55. +static struct rt2880_pmx_func ephy_p4_grp_mt7628[] = {

  56. + FUNC("rsvd", 3, 39, 1),

  57. + FUNC("rsvd", 2, 39, 1),

  58. + FUNC("gpio", 1, 39, 1),

  59. + FUNC("ephy", 0, 39, 1),

  60. };

  61. -

  62. -static struct rt2880_pmx_func wled_an_grp_mt7628[] = {

  63. - FUNC("rsvd", 3, 44, 1),

  64. - FUNC("rsvd", 2, 44, 1),

  65. - FUNC("gpio", 1, 44, 1),

  66. - FUNC("wled_an", 0, 44, 1),

  67. -};

  68. -

  69. #define MT7628_GPIO_MODE_MASK 0x3

  70. -

  71. -#define MT7628_GPIO_MODE_WLED_KN 48

  72. +#define MT7628_GPIO_MODE_EPHY_P4 42

  73. +#define MT7628_GPIO_MODE_EPHY_P3 40

  74. +#define MT7628_GPIO_MODE_EPHY_P2 38

  75. +#define MT7628_GPIO_MODE_EPHY_P1 36

  76. +#define MT7628_GPIO_MODE_EPHY_P0 34

  77. #define MT7628_GPIO_MODE_WLED_AN 32

  78. #define MT7628_GPIO_MODE_PWM1 30

  79. #define MT7628_GPIO_MODE_PWM0 28

  80. @@ -236,7 +263,12 @@

  81. GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_SPIS),

  82. GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_GPIO),

  83. GRP_G("wled_an", wled_an_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_WLED_AN),

  84. - GRP_G("wled_kn", wled_kn_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_WLED_KN),

  85. + GRP_G("ephy_p0", ephy_p0_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P0),

  86. + GRP_G("ephy_p1", ephy_p1_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P1),

  87. + GRP_G("ephy_p2", ephy_p2_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P2),

  88. + GRP_G("ephy_p3", ephy_p3_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P3),

  89. + GRP_G("ephy_p4", ephy_p4_grp_mt7628, MT7628_GPIO_MODE_MASK, 1, MT7628_GPIO_MODE_EPHY_P4),

  90. +

  91. { 0 }

  92. };

  93.  
  94.  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值