我正在尝试为odroid-c2写一个基于自定义描述符的gpio内核模块。 但是,一旦插入模块,我就会收到错误消息:
OF: /soc/periphs@c8834000/pinctrl@4b0/bank@4b0: could not get #gpio-cells for /soc/periphs@c8834000/pinctrl@4b0
这是我到目前为止编写的代码:
static int __init gpio_test_driver_init(void) {
int err = 0;
int gpios;
struct device_node *np;
struct pinctrl_dev *pctldev;
enum of_gpio_flags flags;
printk(KERN_DEBUG "Init Called\n");
chip = gpiochip_find("periphs-banks", chip_match_name);
if (!chip) {
printk(KERN_ERR "Cannot Find A GPIO Chip");
return -ENODEV;
}
printk(KERN_DEBUG "Got valid GPIO Chip Total num gpios %d\n", chip->ngpio);
np = chip->of_node;
if (np == NULL) {
printk(KERN_ERR "device node is null\n");
return -ENOMEM;
}
gpios = of_get_named_gpio_flags(np, "gpio-ranges", 0, &flags);
if (gpio_is_valid(gpios)) {
printk(KERN_ERR "Valid GPIO==> %d\n", gpios);
}
else {
printk(KERN_ERR "Invalid GPIO==> %d\n", gpios);
}
return err;
}
dtsi文件如下:meson-gxbb.dtsi
&periphs {
pinctrl_periphs: pinctrl@4b0 {
compatible = "amlogic,meson-gxbb-periphs-pinctrl";
#address-cells = <2>;
#size-cells = <2>;
ranges;
gpio: bank@4b0 {
reg = <0x0 0x004b0 0x0 0x28>,
<0x0 0x004e8 0x0 0x14>,
<0x0 0x00520 0x0 0x14>,
<0x0 0x00430 0x0 0x40>;
reg-names = "mux", "pull", "pull-enable", "gpio";
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pinctrl_periphs 0 0 119>;
};
emmc_pins: emmc {
mux {
groups = "emmc_nand_d07",
"emmc_cmd",
"emmc_clk";
function = "emmc";
bias-disable;
};
};
emmc_ds_pins: emmc-ds {
mux {
groups = "emmc_ds";
function = "emmc";
bias-disable;
};
};
emmc_clk_gate_pins: emmc_clk_gate {
mux {
groups = "BOOT_8";
function = "gpio_periphs";
bias-pull-down;
};
};
nor_pins: nor {
mux {
groups = "nor_d",
"nor_q",
"nor_c",
"nor_cs";
function = "nor";
bias-disable;
};
};
spi_pins: spi-pins {
mux {
groups = "spi_miso",
"spi_mosi",
"spi_sclk";
function = "spi";
bias-disable;
};
};
spi_ss0_pins: spi-ss0 {
mux {
groups = "spi_ss0";
function = "spi";
bias-disable;
};
};
sdcard_pins: sdcard {
mux {
groups = "sdcard_d0",
"sdcard_d1",
"sdcard_d2",
"sdcard_d3",
"sdcard_cmd",
"sdcard_clk";
function = "sdcard";
bias-disable;
};
};
sdcard_clk_gate_pins: sdcard_clk_gate {
mux {
groups = "CARD_2";
function = "gpio_periphs";
bias-pull-down;
};
};
sdio_pins: sdio {
mux {
groups = "sdio_d0",
"sdio_d1",
"sdio_d2",
"sdio_d3",
"sdio_cmd",
"sdio_clk";
function = "sdio";
bias-disable;
};
};
sdio_clk_gate_pins: sdio_clk_gate {
mux {
groups = "GPIOX_4";
function = "gpio_periphs";
bias-pull-down;
};
};
sdio_irq_pins: sdio_irq {
mux {
groups = "sdio_irq";
function = "sdio";
bias-disable;
};
};
uart_a_pins: uart_a {
mux {
groups = "uart_tx_a",
"uart_rx_a";
function = "uart_a";
bias-disable;
};
};
uart_a_cts_rts_pins: uart_a_cts_rts {
mux {
groups = "uart_cts_a",
"uart_rts_a";
function = "uart_a";
bias-disable;
};
};
uart_b_pins: uart_b {
mux {
groups = "uart_tx_b",
"uart_rx_b";
function = "uart_b";
bias-disable;
};
};
uart_b_cts_rts_pins: uart_b_cts_rts {
mux {
groups = "uart_cts_b",
"uart_rts_b";
function = "uart_b";
bias-disable;
};
};
uart_c_pins: uart_c {
mux {
groups = "uart_tx_c",
"uart_rx_c";
function = "uart_c";
bias-disable;
};
};
uart_c_cts_rts_pins: uart_c_cts_rts {
mux {
groups = "uart_cts_c",
"uart_rts_c";
function = "uart_c";
bias-disable;
};
};
i2c_a_pins: i2c_a {
mux {
groups = "i2c_sck_a",
"i2c_sda_a";
function = "i2c_a";
bias-disable;
};
};
i2c_b_pins: i2c_b {
mux {
groups = "i2c_sck_b",
"i2c_sda_b";
function = "i2c_b";
bias-disable;
};
};
i2c_c_pins: i2c_c {
mux {
groups = "i2c_sck_c",
"i2c_sda_c";
function = "i2c_c";
bias-disable;
};
};
eth_rgmii_pins: eth-rgmii {
mux {
groups = "eth_mdio",
"eth_mdc",
"eth_clk_rx_clk",
"eth_rx_dv",
"eth_rxd0",
"eth_rxd1",
"eth_rxd2",
"eth_rxd3",
"eth_rgmii_tx_clk",
"eth_tx_en",
"eth_txd0",
"eth_txd1",
"eth_txd2",
"eth_txd3";
function = "eth";
bias-disable;
};
};
eth_rmii_pins: eth-rmii {
mux {
groups = "eth_mdio",
"eth_mdc",
"eth_clk_rx_clk",
"eth_rx_dv",
"eth_rxd0",
"eth_rxd1",
"eth_tx_en",
"eth_txd0",
"eth_txd1";
function = "eth";
bias-disable;
};
};
pwm_a_x_pins: pwm_a_x {
mux {
groups = "pwm_a_x";
function = "pwm_a_x";
bias-disable;
};
};
pwm_a_y_pins: pwm_a_y {
mux {
groups = "pwm_a_y";
function = "pwm_a_y";
bias-disable;
};
};
pwm_b_pins: pwm_b {
mux {
groups = "pwm_b";
function = "pwm_b";
bias-disable;
};
};
pwm_d_pins: pwm_d {
mux {
groups = "pwm_d";
function = "pwm_d";
bias-disable;
};
};
pwm_e_pins: pwm_e {
mux {
groups = "pwm_e";
function = "pwm_e";
bias-disable;
};
};
pwm_f_x_pins: pwm_f_x {
mux {
groups = "pwm_f_x";
function = "pwm_f_x";
bias-disable;
};
};
pwm_f_y_pins: pwm_f_y {
mux {
groups = "pwm_f_y";
function = "pwm_f_y";
bias-disable;
};
};
hdmi_hpd_pins: hdmi_hpd {
mux {
groups = "hdmi_hpd";
function = "hdmi_hpd";
bias-disable;
};
};
hdmi_i2c_pins: hdmi_i2c {
mux {
groups = "hdmi_sda", "hdmi_scl";
function = "hdmi_i2c";
bias-disable;
};
};
i2sout_ch23_y_pins: i2sout_ch23_y {
mux {
groups = "i2sout_ch23_y";
function = "i2s_out";
bias-disable;
};
};
i2sout_ch45_y_pins: i2sout_ch45_y {
mux {
groups = "i2sout_ch45_y";
function = "i2s_out";
bias-disable;
};
};
i2sout_ch67_y_pins: i2sout_ch67_y {
mux {
groups = "i2sout_ch67_y";
function = "i2s_out";
bias-disable;
};
};
spdif_out_y_pins: spdif_out_y {
mux {
groups = "spdif_out_y";
function = "spdif_out";
bias-disable;
};
};
};
};
我想在linux模块中访问gpio,但是我无法获得它。在特定节点“ gpio:bank @ 4b0”的dtsi
文件中,单元数被称为“#gpio-cells = <2>;”。但即使我遇到错误。
更新:
我修改了要使用的代码,并修改了现有的在内核空间中运行的引脚控制驱动程序,并且依赖于此。
我已经使用了该驱动程序的API,并且按预期方式工作,我正在尝试和学习,因此下面的代码仅供参考:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/gpio/driver.h>
#include <dt-bindings/gpio/meson-gxbb-gpio.h>
struct gpio_chip *chip;
static int chip_match_name(struct gpio_chip *chip, void *data)
{
printk(KERN_INFO "Label: %s", chip->label);
printk(KERN_INFO "Name: %s", chip->parent->init_name);
printk(KERN_INFO "OF Node Full Name: %s", chip->of_node->full_name);
return !strcmp(chip->label, data);
}
int gpio_test_init(void)
{
int err = 0;
printk(KERN_DEBUG "Init Called\n");
chip = gpiochip_find("periphs-banks", chip_match_name);
if (!chip) {
printk(KERN_ERR "Cannot Find A GPIO Chip");
return -ENODEV;
}
printk(KERN_DEBUG "Got valid GPIO Chip Total num gpios %d\n",
chip->ngpio);
err = chip->get(chip, GPIOX_11);
printk(KERN_INFO "Before Setting Value %d\n", err);
err = chip->direction_output(chip, GPIOX_11, 1);
if (err < 0) {
printk(KERN_DEBUG "Error Setting GPIO Direction %d", err);
}
chip->set(chip, GPIOX_11, 1);
err = chip->get(chip, GPIOX_11);
printk(KERN_INFO "After Setting Value %d\n", err);
mdelay(2000);
chip->set(chip, GPIOX_11, 0);
err = chip->get(chip, GPIOX_11);
printk(KERN_INFO "After Clearing Value %d\n", err);
return 0;
}
void gpio_test_exit(void)
{
printk(KERN_DEBUG "Exiting....\n");
}
module_init( gpio_test_init);
module_exit( gpio_test_exit);
MODULE_LICENSE("GPL");
我不确定这是否是访问GPIO的正确方法。
如果我做错了,请纠正我。