SSD_Padmux使用说明
1. Padmux是什么¶
Padmux是位于kernel\drivers\sstar\padmux的一个linux platform驱动。因为gpio pin复用的关系,通常同一个gpio可以用作不同的功能,所以我们就用padmux驱动在开机的时候统一将需要使用的gpio pin功能配置好。
2. PadMux驱动介绍¶
Padmux驱动定义如下:
2. static struct platform_driver sstar_padmux_driver = { 3. .driver = { 4. .name = "padmux", 5. .owner = THIS_MODULE, 6. .of_match_table = sstar_padmux_of_match, 7. .pm = &sstar_padmux_pm_ops, 8. }, 9. .probe = sstar_padmux_probe, 10. };
2.1. sstar_padmux_of_match¶
用来匹配开机需要配置的gpio table设备:
2.2. sstar_padmux_pm_ops¶
实现str待机对应的resume和suspend函数:
1. static const struct dev_pm_ops sstar_padmux_pm_ops = { 2. .suspend_late = sstar_padmux_suspend, 3. .resume_early = sstar_padmux_resume, 4. };
2.3. sstar_padmux_probe¶
在匹配到padmux设备后,系统会call sstar_padmux_probe进行gpio功能配置:
最终通过MDrv_GPIO_PadVal_Set将gpio配置成对应的功能:
kernel\drivers\sstar\gpio mdrv_gpio.c
1. int MDrv_GPIO_PadVal_Set(U8 u8IndexGPIO, U32 u32PadMode) 2. { 3. return MHal_GPIO_PadVal_Set(u8IndexGPIO, u32PadMode); 4. }
kernel\drivers\sstar\gpio\infinity2m mhal_gpio.c
1. int MHal_GPIO_PadVal_Set(U8 u8IndexGPIO, U32 u32PadMode) 2. { 3. return HalPadSetVal((U32)u8IndexGPIO, u32PadMode); 4. }
kernel\drivers\sstar\gpio\infinity2m mhal_pinmux.c
1. S32 HalPadSetVal(U32 u32PadID, U32 u32Mode) 2. { 3. if (FALSE == _HalCheckPin(u32PadID)) { 4. return FALSE; 5. } 6. if(u32PadID>=PAD_ETH_RN && u32PadID <= PAD_SAR_GPIO3) 7. return HalPadSetMode_MISC(u32PadID, u32Mode); 8. return HalPadSetMode_General(u32PadID, u32Mode); 9. } 10. static S32 HalPadSetMode_General(U32 u32PadID, U32 u32Mode) 11. { 12. U32 u32RegAddr = 0; 13. U16 u16RegVal = 0; 14. U8 u8ModeIsFind = 0; 15. U16 i = 0; 16. 17. for (i = 0; i < sizeof(m_stPadMuxTbl)/sizeof(struct stPadMux); i++) 18. { 19. if (u32PadID == m_stPadMuxTbl[i].padID) 20. { 21. u32RegAddr = _RIUA_16BIT(m_stPadMuxTbl[i].base, m_stPadMuxTbl[i].offset); 22. 23. if (u32Mode == m_stPadMuxTbl[i].mode) 24. { 25. u16RegVal = _GPIO_R_WORD_MASK(u32RegAddr, 0xFFFF); 26. u16RegVal &= ~(m_stPadMuxTbl[i].mask); 27. u16RegVal |= m_stPadMuxTbl[i].val; // CHECK Multi-Pad Mode 28. 29. _GPIO_W_WORD_MASK(u32RegAddr, u16RegVal, 0xFFFF); 30. 31. u8ModeIsFind = 1; 32. #if (ENABLE_CHECK_ALL_PAD_CONFLICT == 0) 33. break; 34. #endif 35. } 36. else 37. { //Clear high priority setting 38. u16RegVal = _GPIO_R_WORD_MASK(u32RegAddr, m_stPadMuxTbl[i].mask); 39. if (u16RegVal == m_stPadMuxTbl[i].val) 40. { 41. printk(KERN_INFO"[Padmux]reset PAD%d(reg 0x%x:%x; mask0x%x) t0 %s (org: %s)\n", 42. u32PadID, 43. m_stPadMuxTbl[i].base, 44. m_stPadMuxTbl[i].offset, 45. m_stPadMuxTbl[i].mask, 46. m_stPadModeInfoTbl[u32Mode].u8PadName, 47. m_stPadModeInfoTbl[m_stPadMuxTbl[i].mode].u8PadName); 48. if (m_stPadMuxTbl[i].val != 0) 49. { 50. _GPIO_W_WORD_MASK(u32RegAddr, 0, m_stPadMuxTbl[i].mask); 51. } 52. else 53. { 54. _GPIO_W_WORD_MASK(u32RegAddr, m_stPadMuxTbl[i].mask, m_stPadMuxTbl[i].mask); 55. } 56. } 57. } 58. } 59. } 60. 61. return (u8ModeIsFind) ? 0 : -1; 62. }
通过在m_stPadMuxTbl里面找到需要配置的gpio和mode设定对应的reg。
以PAD_GPIO4配置成PINMUX_FOR_PWM0_MODE_3为例:
当在dts padmux里面配置了:
<PAD_GPIO4 PINMUX_FOR_PWM0_MODE_3 MDRV_PUSE_PWM0 >,
在probe的时候会根据m_stPadMuxTbl的寄存器设定将寄存器bank 0x103c offset 0x65的bit2设置为1:
1. #define CHIPTOP_BANK 0x101E00 2. #define REG_PWM0_MODE 0x07 3. #define REG_PWM0_MODE_MASK BIT0|BIT1|BIT2 4. {PAD_GPIO4, CHIPTOP_BANK, REG_PWM0_MODE, REG_PWM0_MODE_MASK, BIT1|BIT0, PINMUX_FOR_PWM0_MODE_3},
可以在板子通过读取reg确认设定有没有生效:riu_r 0x101E 0xE 的bit0/bit1
3. PadMux怎么用¶
通过上面padmux驱动的介绍,我们知道只要确认padmux驱动有enable,并在dts里面将需要配置的pin和对应的mode写进去,开机padmux probe的时候就会将gpio对应的功能配置好。需要注意的是pamdux驱动依赖gpio驱动,所以这两个驱动都要build进kernel。目前公板默认的配置gpio和padmux都有默认打开buildin:
1. CONFIG_MS_GPIO=y 2. CONFIG_MS_PADMUX=y
下面介绍如何在dts的padmux中配置对应的gpio功能。
3.1. 用哪个padmux dts文件¶
根据下面的follow找到对应kernel config文件中指定的padmux dts文件,例如:
kernel\arch\arm\configs\infinity2m_spinand_ssc011a_s01a_minigui_defconfig:
1. CONFIG_SS_DTB_NAME="infinity2m-spinand-ssc011a-s01a-display"
kernel\arch\arm\boot\dts\infinity2m-spinand-ssc011a-s01a-display.dts:
1. #include "infinity2m.dtsi" 2. #include "infinity2m-ssc011a-s01a-display.dtsi" 3. #include "infinity2m-ssc011a-s01a-padmux-display.dtsi"
kernel\arch\arm\boot\dts\infinity2m-ssc011a-s01a-padmux-display.dtsi
3.2. 配置gpio mode¶
根据SDK release的硬件发布资料SSD201 HW Checklist V18.xlsx,找到padmux这栏:
以上图将PAD_GPIO4配置成PWM0为例,可以看到PAD_GPIO4要配置成PWM0只能将其配置成pwm0 mode 3,所以在padmux dts里面配置如下:
< PAD_GPIO4 PINMUX_FOR_PWM0_MODE_3 MDRV_PUSE_PWM0>,
其中MDRV_PUSE_PWM0一般只做说明注释没有特殊用途,除非对应功能驱动有特别设定。其他i2c,spi,uart,ttl,mipi的设定也可以参考hw checklist在padmux dts配置。
4. 注意事项¶
同一个gpio pin只能复用成一种功能,不能同时在padmux配置成两种功能。如果在padmux配置的功能不生效,需要在dts确认是否被配置成其他功能了。