【嵌入式Linux内核驱动】Pinctrl子系统

Pinctrl子系统

暴露到应用层

$ cat  /sys/kernel/debug/gpio  //查看gpio 暴露的调试信息
$ cat  /sys/kernel/debug/tegra_pinctrl_reg
$ ls   /sys/kernel/debug/pinctrl/
$ cat  /sys/kernel/debug/pinctrl/pinctrl-handles //查看pinmux map对应的处理函数
GPIO当前配置情况
//注: gpio-79: 是内核gpio子系统里,对管脚的编号(是经过映射转化的)
//     I2S0_SCLK : 是该管脚在电路图上的标号
gpiochip0: GPIOs 0-255, parent: platform/6000d000.gpio, tegra-gpio:
内核里编号 电路图标号            |当前使用者           输出 高电平
 gpio-0   (                    )
 gpio-1   (                    )
 gpio-2   (                    |pcie_wake           ) in  hi    
 gpio-3   (                    )
 ...
 gpio-6   (                    |system-suspend-gpio ) out hi    
 ...
 gpio-11  (                    )
 gpio-12  (SPI1_MOSI           )
 gpio-13  (SPI1_MISO           )
 gpio-14  (SPI1_SCK            )
 gpio-15  (SPI1_CS0            )
 gpio-16  (SPI0_MOSI           )
 gpio-17  (SPI0_MISO           )
 gpio-18  (SPI0_SCK            )
 gpio-19  (SPI0_CS0            )
 gpio-20  (SPI0_CS1            )
 ...
 gpio-38  (GPIO13              )
 ...
 gpio-50  (UART1_RTS           )
 gpio-51  (UART1_CTS           )
 ...
 gpio-64  (                    |i2c-mux-gpio        ) out hi
 ...
 gpio-76  (I2S0_FS             )
 gpio-77  (I2S0_DIN            )
 gpio-78  (I2S0_DOUT           )
 gpio-79  (I2S0_SCLK           |?                   ) out hi   
 ... 
 gpio-149 (GPIO01              )
 gpio-150 (                    )
 gpio-151 (                    |cam_reset_gpio      ) out lo
 ...
 gpio-168 (GPIO07              )
 ...
 gpio-187 (                    |?                   ) out hi
 gpio-188 (                    )
 gpio-189 (                    |Power               ) in  hi IRQ
 gpio-190 (                    |Forcerecovery       ) in  hi IRQ
 ...
 gpio-194 (GPIO12              )
 ...
 gpio-200 (GPIO11              )
 gpio-201 (                    |cd                  ) in  lo IRQ
 gpio-202 (                    )
 gpio-203 (                    |vdd-3v3-sd          ) out hi
 ...
 gpio-216 (GPIO09              )
 ...
 gpio-239 (                    )
gpiochip1: GPIOs 504-511, parent: platform/max77620-gpio, max77620-gpio, can sleep:
 gpio-505 (                    |spmic-default-output) out hi
 gpio-507 (                    |vdd-3v3-sys         ) out hi
 gpio-510 (                    |enable              ) out lo
 gpio-511 (                    |avdd-io-edp-1v05    ) out lo  
管脚复用寄存器的值
Bank: 1 Reg: 0x70003000 Val: 0x00003040 -> sdmmc1_clk_pm0
Bank: 1 Reg: 0x70003004 Val: 0x00003048 -> sdmmc1_cmd_pm1
Bank: 1 Reg: 0x70003008 Val: 0x00003048 -> sdmmc1_dat3_pm2
Bank: 1 Reg: 0x7000300c Val: 0x00003048 -> sdmmc1_dat2_pm3
Bank: 1 Reg: 0x70003010 Val: 0x00003048 -> sdmmc1_dat1_pm4
Bank: 1 Reg: 0x70003014 Val: 0x00003048 -> sdmmc1_dat0_pm5
Bank: 1 Reg: 0x700032b4 Val: 0x00000000 -> sdmmc2_clk
Bank: 1 Reg: 0x700032b8 Val: 0x00000000 -> sdmmc2_clkb
Bank: 1 Reg: 0x700032bc Val: 0x00000000 -> sdmmc2_cmd
Bank: 1 Reg: 0x70003294 Val: 0x00000000 -> sdmmc2_dat0
Bank: 1 Reg: 0x70003298 Val: 0x00000000 -> sdmmc2_dat1
Bank: 1 Reg: 0x7000329c Val: 0x00000000 -> sdmmc2_dat2
Bank: 1 Reg: 0x700032a0 Val: 0x00000000 -> sdmmc2_dat3
Bank: 1 Reg: 0x700032a4 Val: 0x00000000 -> sdmmc2_dat4
Bank: 1 Reg: 0x700032a8 Val: 0x00000000 -> sdmmc2_dat5
Bank: 1 Reg: 0x700032ac Val: 0x00000000 -> sdmmc2_dat6
Bank: 1 Reg: 0x700032b0 Val: 0x00000000 -> sdmmc2_dat7
Bank: 1 Reg: 0x700032c0 Val: 0x00000000 -> sdmmc2_dqs
Bank: 1 Reg: 0x700032c4 Val: 0x00000000 -> sdmmc2_dqsb
Bank: 1 Reg: 0x7000301c Val: 0x00002040 -> sdmmc3_clk_pp0
Bank: 1 Reg: 0x70003020 Val: 0x00002048 -> sdmmc3_cmd_pp1
Bank: 1 Reg: 0x70003024 Val: 0x00002048 -> sdmmc3_dat0_pp5
Bank: 1 Reg: 0x70003028 Val: 0x00002048 -> sdmmc3_dat1_pp4
Bank: 1 Reg: 0x7000302c Val: 0x00002048 -> sdmmc3_dat2_pp3
Bank: 1 Reg: 0x70003030 Val: 0x00002048 -> sdmmc3_dat3_pp2
Bank: 1 Reg: 0x70003038 Val: 0x00000400 -> pex_l0_rst_n_pa0
Bank: 1 Reg: 0x7000303c Val: 0x00000450 -> pex_l0_clkreq_n_pa1
Bank: 1 Reg: 0x70003040 Val: 0x00000440 -> pex_wake_n_pa2
Bank: 1 Reg: 0x70003044 Val: 0x00000400 -> pex_l1_rst_n_pa3
Bank: 1 Reg: 0x70003048 Val: 0x00000440 -> pex_l1_clkreq_n_pa4
Bank: 1 Reg: 0x7000304c Val: 0x00000049 -> sata_led_active_pa5
Bank: 1 Reg: 0x7000304c Val: 0x00000049 -> pa5
Bank: 1 Reg: 0x70003050 Val: 0x0000e015 -> spi1_mosi_pc0
Bank: 1 Reg: 0x70003054 Val: 0x0000e015 -> spi1_miso_pc1
Bank: 1 Reg: 0x70003058 Val: 0x0000e015 -> spi1_sck_pc2
Bank: 1 Reg: 0x7000305c Val: 0x0000e015 -> spi1_cs0_pc3
Bank: 1 Reg: 0x70003060 Val: 0x0000e015 -> spi1_cs1_pc4
Bank: 1 Reg: 0x70003064 Val: 0x00006016 -> spi2_mosi_pb4
Bank: 1 Reg: 0x70003068 Val: 0x00006016 -> spi2_miso_pb5
Bank: 1 Reg: 0x7000306c Val: 0x00006016 -> spi2_sck_pb6
Bank: 1 Reg: 0x70003070 Val: 0x00006016 -> spi2_cs0_pb7
Bank: 1 Reg: 0x70003074 Val: 0x00006015 -> spi2_cs1_pdd0
Bank: 1 Reg: 0x70003078 Val: 0x0000e015 -> spi4_mosi_pc7
Bank: 1 Reg: 0x7000307c Val: 0x0000e015 -> spi4_miso_pd0
Bank: 1 Reg: 0x70003080 Val: 0x0000e015 -> spi4_sck_pc5
Bank: 1 Reg: 0x70003084 Val: 0x0000e015 -> spi4_cs0_pc6
Bank: 1 Reg: 0x70003088 Val: 0x00002040 -> qspi_sck_pee0
Bank: 1 Reg: 0x7000308c Val: 0x00002000 -> qspi_cs_n_pee1
Bank: 1 Reg: 0x70003090 Val: 0x00002040 -> qspi_io0_pee2
Bank: 1 Reg: 0x70003094 Val: 0x00002040 -> qspi_io1_pee3
Bank: 1 Reg: 0x70003098 Val: 0x00002040 -> qspi_io2_pee4
Bank: 1 Reg: 0x7000309c Val: 0x00002040 -> qspi_io3_pee5
Bank: 1 Reg: 0x700030a4 Val: 0x00000041 -> dmic1_clk_pe0
Bank: 1 Reg: 0x700030a8 Val: 0x00000041 -> dmic1_dat_pe1
Bank: 1 Reg: 0x700030ac Val: 0x00000041 -> dmic2_clk_pe2
Bank: 1 Reg: 0x700030b0 Val: 0x00000041 -> dmic2_dat_pe3
Bank: 1 Reg: 0x700030b4 Val: 0x00000016 -> dmic3_clk_pe4
Bank: 1 Reg: 0x700030b8 Val: 0x00000016 -> dmic3_dat_pe5
Bank: 1 Reg: 0x700030bc Val: 0x00000440 -> gen1_i2c_scl_pj1
Bank: 1 Reg: 0x700030c0 Val: 0x00000440 -> gen1_i2c_sda_pj0
Bank: 1 Reg: 0x700030c4 Val: 0x00000440 -> gen2_i2c_scl_pj2
Bank: 1 Reg: 0x700030c8 Val: 0x00000440 -> gen2_i2c_sda_pj3
Bank: 1 Reg: 0x700030cc Val: 0x00000040 -> gen3_i2c_scl_pf0
Bank: 1 Reg: 0x700030d0 Val: 0x00000040 -> gen3_i2c_sda_pf1
Bank: 1 Reg: 0x700030d4 Val: 0x00000441 -> cam_i2c_scl_ps2
Bank: 1 Reg: 0x700030d8 Val: 0x00000441 -> cam_i2c_sda_ps3
Bank: 1 Reg: 0x700030dc Val: 0x00000040 -> pwr_i2c_scl_py3
Bank: 1 Reg: 0x700030e0 Val: 0x00000040 -> pwr_i2c_sda_py4
Bank: 1 Reg: 0x700030e4 Val: 0x00000000 -> uart1_tx_pu0
Bank: 1 Reg: 0x700030e8 Val: 0x00000040 -> uart1_rx_pu1
Bank: 1 Reg: 0x700030ec Val: 0x00000015 -> uart1_rts_pu2
Bank: 1 Reg: 0x700030f0 Val: 0x00000015 -> uart1_cts_pu3
Bank: 1 Reg: 0x700030f4 Val: 0x00000000 -> uart2_tx_pg0
Bank: 1 Reg: 0x700030f8 Val: 0x00000044 -> uart2_rx_pg1
Bank: 1 Reg: 0x700030fc Val: 0x00000016 -> uart2_rts_pg2
Bank: 1 Reg: 0x70003100 Val: 0x00000016 -> uart2_cts_pg3
Bank: 1 Reg: 0x70003104 Val: 0x00000000 -> uart3_tx_pd1
Bank: 1 Reg: 0x70003108 Val: 0x00000040 -> uart3_rx_pd2
Bank: 1 Reg: 0x7000310c Val: 0x00000008 -> uart3_rts_pd3
Bank: 1 Reg: 0x70003110 Val: 0x00000048 -> uart3_cts_pd4
Bank: 1 Reg: 0x70003114 Val: 0x00000000 -> uart4_tx_pi4
Bank: 1 Reg: 0x70003118 Val: 0x00000040 -> uart4_rx_pi5
Bank: 1 Reg: 0x7000311c Val: 0x00000000 -> uart4_rts_pi6
Bank: 1 Reg: 0x70003120 Val: 0x00000048 -> uart4_cts_pi7
Bank: 1 Reg: 0x70003124 Val: 0x00006015 -> dap1_fs_pb0
Bank: 1 Reg: 0x70003128 Val: 0x00006015 -> dap1_din_pb1
Bank: 1 Reg: 0x7000312c Val: 0x00006015 -> dap1_dout_pb2
Bank: 1 Reg: 0x70003130 Val: 0x00006015 -> dap1_sclk_pb3
Bank: 1 Reg: 0x70003134 Val: 0x00006040 -> dap2_fs_paa0
Bank: 1 Reg: 0x70003138 Val: 0x00006040 -> dap2_din_paa2
Bank: 1 Reg: 0x7000313c Val: 0x00006040 -> dap2_dout_paa3
Bank: 1 Reg: 0x70003140 Val: 0x00006040 -> dap2_sclk_paa1
Bank: 1 Reg: 0x70003144 Val: 0x00000015 -> dap4_fs_pj4
Bank: 1 Reg: 0x70003148 Val: 0x00000015 -> dap4_din_pj5
Bank: 1 Reg: 0x7000314c Val: 0x00000015 -> dap4_dout_pj6
Bank: 1 Reg: 0x70003150 Val: 0x00000005 -> dap4_sclk_pj7
Bank: 1 Reg: 0x70003154 Val: 0x00000000 -> cam1_mclk_ps0
Bank: 1 Reg: 0x70003158 Val: 0x00000000 -> cam2_mclk_ps1
Bank: 1 Reg: 0x7000315c Val: 0x00000000 -> jtag_rtck
Bank: 1 Reg: 0x70003160 Val: 0x00001000 -> clk_32k_in
Bank: 1 Reg: 0x70003164 Val: 0x00000048 -> clk_32k_out_py5
Bank: 1 Reg: 0x70003168 Val: 0x00000550 -> batt_bcl
Bank: 1 Reg: 0x7000316c Val: 0x00000004 -> clk_req
Bank: 1 Reg: 0x70003170 Val: 0x00000004 -> cpu_pwr_req
Bank: 1 Reg: 0x70003174 Val: 0x00000048 -> pwr_int_n
Bank: 1 Reg: 0x70003178 Val: 0x00000000 -> shutdown
Bank: 1 Reg: 0x7000317c Val: 0x00000000 -> core_pwr_req
Bank: 1 Reg: 0x70003180 Val: 0x00000015 -> aud_mclk_pbb0
Bank: 1 Reg: 0x70003184 Val: 0x00000001 -> dvfs_pwm_pbb1
Bank: 1 Reg: 0x70003188 Val: 0x00000014 -> dvfs_clk_pbb2
Bank: 1 Reg: 0x7000318c Val: 0x00000014 -> gpio_x1_aud_pbb3
Bank: 1 Reg: 0x70003190 Val: 0x00000014 -> gpio_x3_aud_pbb4
Bank: 1 Reg: 0x70003194 Val: 0x00000500 -> pcc7
Bank: 1 Reg: 0x70003198 Val: 0x00000540 -> hdmi_cec_pcc0
Bank: 1 Reg: 0x7000319c Val: 0x00000140 -> hdmi_int_dp_hpd_pcc1
Bank: 1 Reg: 0x700031a0 Val: 0x00000015 -> spdif_out_pcc2
Bank: 1 Reg: 0x700031a4 Val: 0x00000015 -> spdif_in_pcc3
Bank: 1 Reg: 0x700031a8 Val: 0x00000149 -> usb_vbus_en0_pcc4
Bank: 1 Reg: 0x700031ac Val: 0x00000115 -> usb_vbus_en1_pcc5
Bank: 1 Reg: 0x700031b0 Val: 0x00000040 -> dp_hpd0_pcc6
Bank: 1 Reg: 0x700031b4 Val: 0x00000000 -> wifi_en_ph0
Bank: 1 Reg: 0x700031b8 Val: 0x00000014 -> wifi_rst_ph1
Bank: 1 Reg: 0x700031bc Val: 0x00000044 -> wifi_wake_ap_ph2
Bank: 1 Reg: 0x700031c0 Val: 0x00000000 -> ap_wake_bt_ph3
Bank: 1 Reg: 0x700031c4 Val: 0x00000000 -> bt_rst_ph4
Bank: 1 Reg: 0x700031c8 Val: 0x00000048 -> bt_wake_ap_ph5
Bank: 1 Reg: 0x700031cc Val: 0x00000000 -> ap_wake_nfc_ph7
Bank: 1 Reg: 0x700031d0 Val: 0x00000000 -> nfc_en_pi0
Bank: 1 Reg: 0x700031d4 Val: 0x00000050 -> nfc_int_pi1
Bank: 1 Reg: 0x700031d8 Val: 0x00000000 -> gps_en_pi2
Bank: 1 Reg: 0x700031dc Val: 0x00000014 -> gps_rst_pi3
Bank: 1 Reg: 0x700031e0 Val: 0x00000015 -> cam_rst_ps4
Bank: 1 Reg: 0x700031e4 Val: 0x00000016 -> cam_af_en_ps5
Bank: 1 Reg: 0x700031e8 Val: 0x00000016 -> cam_flash_en_ps6
Bank: 1 Reg: 0x700031ec Val: 0x00000001 -> cam1_pwdn_ps7
Bank: 1 Reg: 0x700031f0 Val: 0x00000001 -> cam2_pwdn_pt0
Bank: 1 Reg: 0x700031f4 Val: 0x00000015 -> cam1_strobe_pt1
Bank: 1 Reg: 0x700031f8 Val: 0x00000015 -> lcd_te_py2
Bank: 1 Reg: 0x700031fc Val: 0x00000017 -> lcd_bl_pwm_pv0
Bank: 1 Reg: 0x70003200 Val: 0x00000040 -> lcd_bl_en_pv1
Bank: 1 Reg: 0x70003204 Val: 0x00000014 -> lcd_rst_pv2
Bank: 1 Reg: 0x70003208 Val: 0x00000015 -> lcd_gpio1_pv3
Bank: 1 Reg: 0x7000320c Val: 0x00000001 -> lcd_gpio2_pv4
Bank: 1 Reg: 0x70003210 Val: 0x00000014 -> ap_ready_pv5
Bank: 1 Reg: 0x70003214 Val: 0x00000014 -> touch_rst_pv6
Bank: 1 Reg: 0x70003218 Val: 0x00000015 -> touch_clk_pv7
Bank: 1 Reg: 0x7000321c Val: 0x00000014 -> modem_wake_ap_px0
Bank: 1 Reg: 0x70003220 Val: 0x00000014 -> touch_int_px1
Bank: 1 Reg: 0x70003224 Val: 0x00000014 -> motion_int_px2
Bank: 1 Reg: 0x70003228 Val: 0x00000000 -> als_prox_int_px3
Bank: 1 Reg: 0x7000322c Val: 0x00000048 -> temp_alert_px4
Bank: 1 Reg: 0x70003230 Val: 0x00000048 -> button_power_on_px5
Bank: 1 Reg: 0x70003234 Val: 0x00000048 -> button_vol_up_px6
Bank: 1 Reg: 0x70003238 Val: 0x00000014 -> button_vol_down_px7
Bank: 1 Reg: 0x7000323c Val: 0x00000014 -> button_slide_sw_py0
Bank: 1 Reg: 0x70003240 Val: 0x00000048 -> button_home_py1
Bank: 1 Reg: 0x70003244 Val: 0x00000001 -> pa6
Bank: 1 Reg: 0x70003248 Val: 0x00000014 -> pe6
Bank: 1 Reg: 0x7000324c Val: 0x00000002 -> pe7
Bank: 1 Reg: 0x70003250 Val: 0x00000048 -> ph6
Bank: 1 Reg: 0x70003254 Val: 0x00006016 -> pk0
Bank: 1 Reg: 0x70003258 Val: 0x00006016 -> pk1
Bank: 1 Reg: 0x7000325c Val: 0x00006016 -> pk2
Bank: 1 Reg: 0x70003260 Val: 0x00006016 -> pk3
Bank: 1 Reg: 0x70003264 Val: 0x00006015 -> pk4
Bank: 1 Reg: 0x70003268 Val: 0x00006015 -> pk5
Bank: 1 Reg: 0x7000326c Val: 0x00006015 -> pk6
Bank: 1 Reg: 0x70003270 Val: 0x00006015 -> pk7
Bank: 1 Reg: 0x70003274 Val: 0x00006014 -> pl0
Bank: 1 Reg: 0x70003278 Val: 0x00006015 -> pl1
Bank: 1 Reg: 0x7000327c Val: 0x00000015 -> pz0
Bank: 1 Reg: 0x70003280 Val: 0x00000049 -> pz1
Bank: 1 Reg: 0x70003284 Val: 0x0000004a -> pz2
Bank: 1 Reg: 0x70003288 Val: 0x00000001 -> pz3
Bank: 1 Reg: 0x7000328c Val: 0x00000015 -> pz4
Bank: 1 Reg: 0x70003290 Val: 0x00000048 -> pz5
Bank: 0 Reg: 0x700009c0 Val: 0x00000000 -> drive_pa6
Bank: 0 Reg: 0x700009c4 Val: 0x00000000 -> drive_pcc7
Bank: 0 Reg: 0x700009c8 Val: 0x00000000 -> drive_pe6
Bank: 0 Reg: 0x700009cc Val: 0x00000000 -> drive_pe7
Bank: 0 Reg: 0x700009d0 Val: 0x00000000 -> drive_ph6
Bank: 0 Reg: 0x700009d4 Val: 0x00000000 -> drive_pk0
Bank: 0 Reg: 0x700009d8 Val: 0x00000000 -> drive_pk1
Bank: 0 Reg: 0x700009dc Val: 0x00000000 -> drive_pk2
Bank: 0 Reg: 0x700009e0 Val: 0x00000000 -> drive_pk3
Bank: 0 Reg: 0x700009e4 Val: 0x00000000 -> drive_pk4
Bank: 0 Reg: 0x700009e8 Val: 0x00000000 -> drive_pk5
Bank: 0 Reg: 0x700009ec Val: 0x00000000 -> drive_pk6
Bank: 0 Reg: 0x700009f0 Val: 0x00000000 -> drive_pk7
Bank: 0 Reg: 0x700009f4 Val: 0x00000000 -> drive_pl0
Bank: 0 Reg: 0x700009f8 Val: 0x00000000 -> drive_pl1
Bank: 0 Reg: 0x700009fc Val: 0x01010000 -> drive_pz0
Bank: 0 Reg: 0x70000a00 Val: 0x01010000 -> drive_pz1
Bank: 0 Reg: 0x70000a04 Val: 0x00000000 -> drive_pz2
Bank: 0 Reg: 0x70000a08 Val: 0x00000000 -> drive_pz3
Bank: 0 Reg: 0x70000a0c Val: 0x00000000 -> drive_pz4
Bank: 0 Reg: 0x70000a10 Val: 0x00000000 -> drive_pz5
Bank: 0 Reg: 0x70000a98 Val: 0x51115000 -> drive_sdmmc1
Bank: 0 Reg: 0x70000a9c Val: 0x07ffd040 -> drive_sdmmc2
Bank: 0 Reg: 0x70000ab0 Val: 0x51212000 -> drive_sdmmc3
Bank: 0 Reg: 0x70000ab4 Val: 0x07ffd040 -> drive_sdmmc4
Bank: 0 Reg: 0x70000b70 Val: 0x00000001 -> drive_qspi_comp_control
Bank: 0 Reg: 0x70000b78 Val: 0x00000001 -> drive_qspi_lpbk_control
Bank: 0 Reg: 0x70000a78 Val: 0x00808000 -> drive_qspi_comp
管脚复用处理函数列表

和设备树里的配置一样,方便查看

//它设备树的pinmux@700008d4 被解析生效后 当下的管脚复用情况
Requested pin control handlers their pinmux maps:
device: 700008d4.pinmux current state: default    //700008d4.pinmux控制器, 当前状态是default,  对应 pinctrl-names = "default"
  state: default
  type: MUX_GROUP controller 700008d4.pinmux group: dvfs_pwm_pbb1 (108) function: cldvfs (5) 
       //对应 nvidia,function = "cldvfs";
  type: CONFIGS_GROUP controller 700008d4.pinmux group dvfs_pwm_pbb1 (108)
    config pull=0         //对应 nvidia,pull = <TEGRA_PIN_PULL_NONE>;
	  config tristate=1     //对应 nvidia,tristate = <TEGRA_PIN_ENABLE>;
	  config enable-input=0 //对应 nvidia,enable-input = <TEGRA_PIN_DISABLE>;
	  
  type: MUX_GROUP controller 700008d4.pinmux group: dmic1_clk_pe0 (52) function: i2s3 (24)
  type: CONFIGS_GROUP controller 700008d4.pinmux group dmic1_clk_pe0 (52)
     config pull=0
     config tristate=0
     
  type: MUX_GROUP controller 700008d4.pinmux group: pe7 (158) function: pwm3 (39)  对应 nvidia,function = "pwm3";
  type: CONFIGS_GROUP controller 700008d4.pinmux group pe7 (158)
    config pull=0  //对应 nvidia,pull = <TEGRA_PIN_PULL_NONE>; 管脚内部不上拉
    config tristate=0 //对应 nvidia,tristate = <TEGRA_PIN_DISABLE>;  //禁用三态(高阻态),表示管脚与外界连通
    config enable-input=0
  
  type: MUX_GROUP controller 700008d4.pinmux group: lcd_gpio2_pv4 (142) function: pwm1 (37) 对应nvidia,function = "pwm1";
  type: CONFIGS_GROUP controller 700008d4.pinmux group lcd_gpio2_pv4 (142)
       config pull=0
       config tristate=0
       config enable-input=0

示例:点灯

$ cat /sys/kernel/debug/gpio |grep GPIO07  /* 查看电路图上 GPIO07标号的管脚的在内核里的gpio 编号
   gpio-168 (GPIO07              )
  */  	

$ echo 168 > /sys/class/gpio/export  //导出gpio管脚,进行控制
         //成功可看到 /sys/class/gpio/gpio168 有生成

$ echo out > /sys/class/gpio/gpio168/direction  //设置 为输出
$ echo 1 > /sys/class/gpio/gpio168/value //输出高电平 开灯
$ cat /sys/kernel/debug/gpio |grep GPIO07 /*查看管脚状态
  内核里编号 电路图标号          |当前使用者(程序名)   输出 高电平
   gpio-168 (GPIO07              |sysfs               ) out hi
  */  
$ echo 168 > /sys/class/gpio/unexport  //取消导出(注:用完后,必须要释放,否则会导致别的程序访问不了) 

示例: 管脚被占用问题

$ echo 79 > /sys/class/gpio/export   //导出,申请79号(在内核里的编号,不是芯片手册电路图上的编号)管脚的使用
  sh: write error: Device or resource busy //报错 资源被占用	
$ cat /sys/kernel/debug/gpio |grep I2S0_SCLK /*查看电路图上 I2S0_SCLK标号(对应丝印12) 的状态
内核里编号 电路图标号           |当前使用者      输出 高电平
  gpio-79  (I2S0_SCLK           |? (未知)      ) out hi
  
    注: 如果当前使用者 有具体程序名,如 yhai_led , 可用kill -9 杀死 
      发现被未知的使用者占用 ,可采取屏蔽相应设备树, 或堆栈dump_stack 堆栈追踪方式
   */
堆栈追踪
  • dump_stack(); //打印堆栈信息,跟踪
//drivers/pinctrl/core.c	
int pinctrl_request_gpio(unsigned gpio)
{
    if(79==gpio){
       printk("pinctrl_request_gpio go\n");
       dump_stack();   //打印堆栈信息,跟踪
    }
	
}

# run distro_bootcmd
$ scp arch/arm64/boot/Image   bbcen@192.168.10.237:/home/bbcen/	

内核启动信息 /* 查看日志, 发现是gpio_led_probe 调用触发的  -> 字符串搜索 发现是 drivers/leds/leds-gpio.c
    3.950363] pinctrl_request_gpio go
[    3.953878] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 4.9.253 #43
[    3.959959] Hardware name: NVIDIA Jetson Nano Developer Kit (DT)
[    3.965951] Call trace:
[    3.968409] [<ffffff800808bb80>] dump_backtrace+0x0/0x198
[    3.973797] [<ffffff800808c144>] show_stack+0x24/0x30
[    3.978846] [<ffffff8008f88ed8>] dump_stack+0xa0/0xc4
[    3.983894] [<ffffff80084b9248>] pinctrl_request_gpio+0x1b0/0x1b8
[    3.989978] [<ffffff80084d3164>] tegra_gpio_request+0x124/0x140
[    3.994730] mmc0: SDHCI controller on sdhci-tegra.0 [sdhci-tegra.0] using ADMA 64-bit with 64 bit addr
[    4.005168] [<ffffff80084c8aa8>] __gpiod_request+0xa0/0x158
[    4.010729] [<ffffff80084cc210>] gpiod_request+0xd0/0x1e8    
[    4.016115] [<ffffff80084cc3ac>] fwnode_get_named_gpiod+0x84/0x118
[    4.022284] [<ffffff80084c6ee0>] devm_get_gpiod_from_child+0x98/0x130
[    4.028718] [<ffffff8008bf75f0>] gpio_led_probe+0x2e8/0x3d0   触发的驱动程序
[    4.034286] [<ffffff800879b180>] platform_drv_probe+0x60/0xc0
[    4.040020] [<ffffff8008798888>] driver_probe_device+0x298/0x448
[    4.046014] [<ffffff8008798b14>] __driver_attach+0xdc/0x128
[    4.051574] [<ffffff8008796144>] bus_for_each_dev+0x5c/0xa8
[    4.057135] [<ffffff8008797ec8>] driver_attach+0x30/0x40
[    4.062435] [<ffffff80087978fc>] bus_add_driver+0x20c/0x2a8
[    4.067994] [<ffffff8008799b74>] driver_register+0x6c/0x110
[    4.073554] [<ffffff800879b0bc>] __platform_driver_register+0x5c/0x68
[    4.079987] [<ffffff8009682a90>] gpio_led_driver_init+0x18/0x20
[    4.085896] [<ffffff8008083b64>] do_one_initcall+0x44/0x130
[    4.091460] [<ffffff8009630e88>] kernel_init_freeable+0x1a0/0x268
[    4.097541] [<ffffff8008f8bcc0>] kernel_init+0x18/0x148
[    4.102754] [<ffffff80080838a0>] ret_from_fork+0x10/0x30
 */
 
 
//解决方法: 取消驱动的编译,或编译成模块,或屏蔽设备树节点,或在设备树节点中使用别的管脚
屏蔽设备树
//通过占用的驱动程序 drivers/leds/leds-gpio.c  
static const struct of_device_id of_gpio_leds_match[] = {
    { .compatible = "gpio-leds", },  //跟踪到设备树,然后屏蔽相应设备树节点
    {},
};	

//tegra210-p3448-0000-p3449-0000-b00.dts 
/*屏蔽对应的设备节点,或使用另一个gpio管脚,或吧驱动编译成模块,不加载即可
    yhai-gpio-led {
        compatible = "gpio-leds";
        led1{    
            gpios = <&gpio TEGRA_GPIO(J,7) GPIO_ACTIVE_HIGH>;  //pJ7 对应79号,占用了管脚

        };
    }; 	
*/

*设备树分析

帮助文档
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.txt
基本配置
//tegra210-soc-base.dtsi   cpu的基本配置
pinmux: pinmux@700008d4 {
    compatible = "nvidia,tegra210-pinmux";
    //定义pinmux 功能块的 寄存器资源(基地址 + 长度)
    reg = <0x0 0x700008d4 0x0 0x2a5   /* Pad control registers 管脚配置寄存器,如上拉 三态 驱动能力*/
           0x0 0x70003000 0x0 0x294>; /* Mux registers  复用设置寄存器*/
    #gpio-range-cells = <3>;  //声明 引用本节点,用 gpio-ranges 属性传参时 参数占3个单位
    status = "disabled";
};

//位置: public_sources\hardware\nvidia\soc\t210\kernel-dts\tegra210-soc\
gpio: gpio@6000d000 {//gpio子节点
    compatible = "nvidia,tegra210-gpio", "nvidia,tegra124-gpio", "nvidia,tegra30-gpio";
    reg = <0x0 0x6000d000 0x0 0x1000>; //前2个数表示起始地址(由父节点的#address-cells = <2> 决定)
                                       //后2个数表示长度范围(由父节点的#size-cells = <2> 决定)
    #gpio-cells = <2>;  //声明 引用本节点,用 gpios 属性传参时 参数占2个单位
    gpio-controller; //声明本节点 是 GPIO 控制器 
    //gpio-ranges: 设置gpio number 与 pinctrl number的 映射范围
    gpio-ranges = <&pinmux 0 0 246>; //设置管脚复用:通过引用pinmux节点,gpio-ranges属性传参的方式
   // 参数占的3个单位 0 0 246,由pinmux里的 #gpio-range-cells = <3>;指定
   //功用:设置 gpio 0~246 和 pinmux的 pin 0~246 的映射转换关系
   //第一个0: 表示gpio   的 base number
   //第二个0: 表示pinmux 的 base number
   //246: 表示长度范围
   //注:当gpio driver需要使用某一个gpio的时候,可以在gpiochip的request函数中,
   //调用pinctrl core提供的pinctrl_request_gpio接口(参数是gpio编号),
   //然后pinctrl core会查寻gpio ranges链表,将gpio编号转换成pin编号,
   //然后调用pinctrl的相应接口(参数是pin编号),申请该pin的使用。
};
管脚复用状态的配置
pe7 {
    nvidia,pins = "pe7";     //管脚名
    nvidia,function = "pwm3";  //配置管脚为 pwm3功能
    nvidia,pull = <TEGRA_PIN_PULL_NONE>; //管脚内部不上拉
    nvidia,tristate = <TEGRA_PIN_DISABLE>;  //禁用三态(高阻态),表示管脚与外界连通
    nvidia,enable-input = <TEGRA_PIN_DISABLE>;//禁用输入功能
};  
//tegra210-porg-pinmux-p3448-0000-b00.dtsi"   //当修改pinmux配置时,要修改当前的配置(状态1),
   //如果修改别的状态下的配置可能不生效(只有在特殊状态下才会切换,如CPU省电睡眠时 )
   //或通过专用的接口去申请改写,如GPIO子系统的申请。	
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
pinmux: pinmux@700008d4 {
  status = "okay";
  pinctrl-names = "default", "drive", "unused";  //定制设备自己的三种管脚状态
                             //如无指定,默认用第一个设备状态的配置单
  pinctrl-0 = <&pinmux_default>; //状态1(default) 对应的配置单(pinmux_default)
  pinctrl-1 = <&drive_default>;  //状态2(drive) 对应的配置单(drive_default)
  pinctrl-2 = <&pinmux_unused_lowpower>;

  pinmux_default: common { //默认的管脚复用,配置单
    /* SFIO Pin Configuration */
    dvfs_pwm_pbb1 {
        nvidia,pins = "dvfs_pwm_pbb1"; //
        nvidia,function = "cldvfs";  //配置当前管脚为cldvfs功能
        nvidia,pull = <TEGRA_PIN_PULL_NONE>;  
        nvidia,tristate = <TEGRA_PIN_ENABLE>; //开启三态(高阻),即断开了管脚与外界连接
        nvidia,enable-input = <TEGRA_PIN_DISABLE>; 
    };    
    dmic1_clk_pe0 {
        nvidia,pins = "dmic1_clk_pe0";
        nvidia,function = "i2s3";
        nvidia,pull = <TEGRA_PIN_PULL_NONE>;
        nvidia,tristate = <TEGRA_PIN_DISABLE>;
        nvidia,enable-input = <TEGRA_PIN_ENABLE>;
    };
    ...
    pe7 {
        nvidia,pins = "pe7";     //管脚名
        nvidia,function = "pwm3";  //配置管脚为 pwm3功能
        nvidia,pull = <TEGRA_PIN_PULL_NONE>; //管脚内部不上拉
        nvidia,tristate = <TEGRA_PIN_DISABLE>;  //禁用三态(高阻态),表示管脚与外界连通
        nvidia,enable-input = <TEGRA_PIN_DISABLE>;//禁用输入功能
    };         
    ...            
  };
  pinmux_unused_lowpower: unused_lowpower { //803 
    lcd_bl_pwm_pv0 {
        nvidia,pins = "lcd_bl_pwm_pv0";
        nvidia,function = "rsvd3";
        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
        nvidia,tristate = <TEGRA_PIN_ENABLE>;
        nvidia,enable-input = <TEGRA_PIN_DISABLE>;
    };    
    /* GPIO Pin Configuration */
    dap4_sclk_pj7 {  // pj7的管脚配置(79号 led灯)
        nvidia,pins = "dap4_sclk_pj7"; //指定管脚名
        nvidia,function = "rsvd1";  //配置该管脚为 rsvd1 功能
        nvidia,pull = <TEGRA_PIN_PULL_DOWN>; //管脚设为下拉
        nvidia,tristate = <TEGRA_PIN_ENABLE>;  //开启三态(高阻),即断开了管脚与外界连接
        nvidia,enable-input = <TEGRA_PIN_DISABLE>;//输入禁止
    };	          
  }
  drive_default: drive {
  };
    
};

官方驱动分析

源码分析  //使用者角度: 从初始化入手,逐层调用到对象
         //设计者角度: 从面向对象,到对外的接口
入口: 构建管脚配置列表
//drivers/pinctrl/tegra/pinctrl-tegra210.c

//所有管脚配置列表  -> 由设备树的 pinmux 去选择     《  重点 
static struct tegra_pingroup tegra210_groups[] = { 
//       管脚名    管脚复用:功能f0          f1      f2     f3
/*       pg_name,              f0,         f1,     f2,    f3,    r*/
PINGROUP(dvfs_pwm_pbb1,        RSVD0,      CLDVFS, SPI3,  RSVD3, 0x3184),
PINGROUP(sdmmc1_clk_pm0,       SDMMC1,     RSVD1,  RSVD2, RSVD3, 0x3000),
PINGROUP(dap4_sclk_pj7,        I2S4B,      RSVD1,  RSVD2, RSVD3, 0x3150),
PINGROUP(pe7,                  RSVD0,      I2S5A,  PWM3,  RSVD3, 0x324c),
PINGROUP(lcd_bl_pwm_pv0,       DISPLAYA,   PWM0,   SOR0,  RSVD3, 0x31fc),
PINGROUP(lcd_gpio2_pv4,        DISPLAYB,   PWM1,   RSVD2, SOR1,  0x320c),
}


static const struct tegra_pinctrl_soc_data tegra210_pinctrl = {
	.ngpios = NUM_GPIOS, //GPIO管脚个数
	.pins = tegra210_pins, //管脚描述
	.npins = ARRAY_SIZE(tegra210_pins),  //管脚数
	.functions = tegra210_functions,    //功能列表
	.nfunctions = ARRAY_SIZE(tegra210_functions),//功能数
	.groups = tegra210_groups,  //组列表
	.ngroups = ARRAY_SIZE(tegra210_groups), //组数
};

static int tegra210_pinctrl_probe(struct platform_device *pdev)  //探测初始化 pinctl设备信息
{
    return tegra_pinctrl_probe(pdev, &tegra210_pinctrl);
}
	
static const struct of_device_id tegra210_pinctrl_of_match[] = {
    {
        .compatible = "nvidia,tegra210-pinmux",
        .data = &tegra210_pinctrl_soc_data,
    }
};

static struct platform_driver tegra210_pinctrl_driver = {
    .driver = {
        .name = "tegra210-pinctrl",
        .of_match_table = tegra210_pinctrl_of_match,  //在设备树中查找匹配的设备信息
    },
    .probe = tegra210_pinctrl_probe,  //如果有匹配的,在调用初始化函数
};
static int __init tegra_pinctrl_init(void)
{
    return platform_driver_register(&tegra210_pinctrl_driver);
}
postcore_initcall(tegra_pinctrl_init); //让模块在内核初始化时,被回调自动加载
初始化对象(属性和操作集)
//文件drivers/pinctrl/tegra/pinctrl-tegra.c
//定义 pinctl设备的类
struct tegra_pmx { 
    struct device *dev;
    struct pinctrl_dev *pctl;
    const struct tegra_pinctrl_soc_data *soc;
    const char **group_pins;
};

static struct tegra_pmx *pmx;

static const struct cfg_param { //配置参数 列表
    const char *property;
    enum tegra_pinconf_param param;
} cfg_params[] = {
    {"nvidia,pull",         TEGRA_PINCONF_PARAM_PULL},
    {"nvidia,tristate",     TEGRA_PINCONF_PARAM_TRISTATE},
    {"nvidia,enable-input",     TEGRA_PINCONF_PARAM_ENABLE_INPUT},
    {"nvidia,open-drain",       TEGRA_PINCONF_PARAM_OPEN_DRAIN},
    {"nvidia,lock",         TEGRA_PINCONF_PARAM_LOCK},
    {"nvidia,io-reset",     TEGRA_PINCONF_PARAM_IORESET},
    {"nvidia,rcv-sel",      TEGRA_PINCONF_PARAM_RCV_SEL},
    {"nvidia,io-hv",        TEGRA_PINCONF_PARAM_RCV_SEL},
    {"nvidia,io-high-voltage",  TEGRA_PINCONF_PARAM_E_IO_HV},
    {"nvidia,loopback",     TEGRA_PINCONF_PARAM_LOOPBACK},
    {"nvidia,high-speed-mode",  TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE},
    {"nvidia,schmitt",      TEGRA_PINCONF_PARAM_SCHMITT},
    {"nvidia,low-power-mode",   TEGRA_PINCONF_PARAM_LOW_POWER_MODE},
    {"nvidia,pull-down-strength",   TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH},
    {"nvidia,pull-up-strength", TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH},
    {"nvidia,slew-rate-falling",    TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING},
    {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
    {"nvidia,drive-type",       TEGRA_PINCONF_PARAM_DRIVE_TYPE},
    {"nvidia,lpdr",         TEGRA_PINCONF_PARAM_LPDR},
    {"nvidia,pbias-buf",        TEGRA_PINCONF_PARAM_PBIAS_BUF},
    {"nvidia,preemp",       TEGRA_PINCONF_PARAM_PREEMP},
    {"nvidia,rfu-in",       TEGRA_PINCONF_PARAM_RFU_IN},
    {"nvidia,special-function", TEGRA_PINCONF_PARAM_GPIO_MODE},
    {"nvidia,pad-power",        TEGRA_PINCONF_PARAM_PAD_POWER},
    {"nvidia,func",         TEGRA_PINCONF_PARAM_FUNCTION},
};

static int tegra_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
                       struct device_node *np,
                       struct pinctrl_map **map,
                       unsigned *reserved_maps,
                       unsigned *num_maps)
{
  //解析设备树的属性 
  of_property_read_string(np, "nvidia,function", &function);
  for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
        ret = of_property_read_u32(np, cfg_params[i].property, &val);
  }
  of_property_count_strings(np, "nvidia,pins");
}


static const struct pinctrl_ops tegra_pinctrl_ops = { //pinctrl的操作函数集
    .get_groups_count = tegra_pinctrl_get_groups_count,
    .get_group_name = tegra_pinctrl_get_group_name,
    .get_group_pins = tegra_pinctrl_get_group_pins,
    .dt_node_to_map = tegra_pinctrl_dt_node_to_map, //解析映射设备树节点
                          //-> tegra_pinctrl_dt_subnode_to_map
    .dt_free_map = pinctrl_utils_free_map,
};



static const struct pinmux_ops tegra_pinmux_ops = { //pinmux操作函数集
    .set_mux = tegra_pinctrl_set_mux,
    .gpio_request_enable = tegra_pinctrl_gpio_request_enable,
    .gpio_disable_free = tegra_pinctrl_gpio_disable_free,
    .gpio_set_direction = tegra_pinctrl_gpio_set_direction,
    .gpio_save_config = tegra_pinctrl_gpio_save_config,
    .gpio_restore_config = tegra_pinctrl_gpio_restore_config,
};

static struct pinctrl_desc tegra_pinctrl_desc = { //pinctrl 的操作描述(类似file_operations)
    .pctlops = &tegra_pinctrl_ops,  //管脚控制操作集
    .pmxops = &tegra_pinmux_ops,   //管脚复用操作集
    .confops = &tegra_pinconf_ops, //管脚配置操作集
    .owner = THIS_MODULE,
};


int tegra_pinctrl_probe(struct platform_device *pdev,
			const struct tegra_pinctrl_soc_data *soc_data)
{

  //-----初始是 对象(为结构体中各指针,分配实体,指向实体)
  //分配device空间(以存储探测到的设备信息)
  pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
  pmx->dev = &pdev->dev;
  pmx->soc = soc_data;

  res = platform_get_resource(pdev, IORESOURCE_MEM, i);  //获取设备树中reg 属性的资源
  pmx->reg_base[i] = res->start;

  //注册pintrl设备
  pmx->pctl = devm_pinctrl_register(&pdev->dev, &tegra_pinctrl_desc, pmx);

  dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n");

  return 0;
}
EXPORT_SYMBOL_GPL(tegra_pinctrl_probe);
对外接口
//include/linux/pinctrl/consumer.h  使用:对外常用接口(GPIO子系统 做pinctrl子系统的客户)
extern int pinctrl_request_gpio(unsigned gpio);  //申请管脚做GPIO用途(使用管脚前,需申请,如被占用则申请失败)
extern void pinctrl_free_gpio(unsigned gpio);  //释放控制
extern int pinctrl_gpio_direction_input(unsigned gpio);  //设置管脚为输入
extern int pinctrl_gpio_direction_output(unsigned gpio); //设置管脚为输出
extern int pinctrl_gpio_save_config(unsigned gpio); //保存管脚配置
extern int pinctrl_gpio_restore_config(unsigned gpio);	//重载管脚配置
extern void pinctrl_put(struct pinctrl *p);
extern struct pinctrl_state * __must_check pinctrl_lookup_state(
							struct pinctrl *p,
							const char *name);
extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s); //切换当前的复用状态
extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev);
extern void devm_pinctrl_put(struct pinctrl *p);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值