这里可以操作 gpio 引脚
zwzn2064@zwzn2064-CVN-Z690D5-GAMING-PRO:~$ ls /sys/class/gpio/
export unexport
zwzn2064@zwzn2064-CVN-Z690D5-GAMING-PRO:~$
操作示例
echo 110 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio110/direction
cat /sys/class/gpio/gpio110/value
echo 110 > /sys/class/gpio/unexport
Core-3588J有5组 GPI0 bank:GPI00~GPI04,每组又以 A0~A7,B0-B7,C0-C7,D0-D7 作为编号区分,常用以下公式计算引脚:
GPI0 pin脚计算公式:pin=bank*32+number
GPI0 小组编号计算公式:number=group*8+X
bank=1;//GPl01 D0 => 1, bank e [0,4]
group = 3;//GPI01 D0=>3,group ∈{(A=0),(B=1),(C=2),(D=3)}X=0;//GPI01 D0 => 0, X ∈ [0,7]
number=group*8+X=3*8+ 0=24
pin= bank*32 +number=1*32 + 24 = 56:
结构体 gpio_desc 是用于描述一个 GPIO (通用输入输出) 引脚的内部数据结构
96 struct gpio_desc {
97 struct gpio_device *gdev;
98 unsigned long flags;
99 /* flag symbols are bit numbers */
100 #define FLAG_REQUESTED 0
101 #define FLAG_IS_OUT 1
102 #define FLAG_EXPORT 2 /* protected by sysfs_lock */
103 #define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */
104 #define FLAG_ACTIVE_LOW 6 /* value has active low */
105 #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */
106 #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
107 #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
108 #define FLAG_IRQ_IS_ENABLED 10 /* GPIO is connected to an enabled IRQ */
109 #define FLAG_IS_HOGGED 11 /* GPIO is hogged */
110 #define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */
111 #define FLAG_PULL_UP 13 /* GPIO has pull up enabled */
112 #define FLAG_PULL_DOWN 14 /* GPIO has pull down enabled */
113
114 /* Connection label */
115 const char *label;
116 /* Name of the GPIO */
117 const char *name;
118 };
struct gpio_device 为 GPIO 设备提供了一个全面的描述,包括其基本属性、管理信息以及与其他内核子系统(如字符设备、Pin Control 等)的交互能力
44 struct gpio_device {
45 int id;
46 struct device dev;
47 struct cdev chrdev;
48 struct device *mockdev;
49 struct module *owner;
50 struct gpio_chip *chip;
51 struct gpio_desc *descs;
52 int base;
53 u16 ngpio;
54 const char *label;
55 void *data;
56 struct list_head list;
57
58 #ifdef CONFIG_PINCTRL
59 /*
60 * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally
61 * describe the actual pin range which they serve in an SoC. This
62 * information would be used by pinctrl subsystem to configure
63 * corresponding pins for gpio usage.
64 */
65 struct list_head pin_ranges;
66 #endif
67 };
int id;
GPIO 设备的唯一标识符,用于区分不同的 GPIO 设备。
struct device dev;
包含设备的基本信息,继承自 Linux 设备模型。这允许 GPIO 设备与内核的其他部分进行交互,如设备注册、驱动程序绑定等。
struct cdev chrdev;
用于表示字符设备的信息。这使得 GPIO 设备可以通过字符设备接口与用户空间进行通信。
struct device *mockdev;
指向一个模拟设备的指针,通常用于测试或开发环境中,以便在没有实际硬件时进行调试。
struct module *owner;
指向拥有该 GPIO 设备的模块的指针。它用于管理模块的生命周期,确保相关资源在模块卸载时被正确释放。
struct gpio_chip *chip
指向与该 GPIO 设备关联的 gpio_chip 结构体的指针。gpio_chip 结构体定义了具体的 GPIO 操作(如设置引脚状态、获取引脚状态等)。
struct gpio_desc *descs;
指向 gpio_desc 结构体数组的指针,存储与该 GPIO 设备相关的所有 GPIO 引脚的描述信息。
int base;
该 GPIO 设备管理的 GPIO 引脚的起始索引。用于确定引脚在全局 GPIO 空间中的位置。
u16 ngpio;
该 GPIO 设备所管理的 GPIO 引脚数量。
const char *label;
指向描述该 GPIO 设备的标签的字符串。这通常用于调试和日志记录,以便能快速识别设备的用途。
void *data;
一个指向用户自定义数据的指针,可以用于存储与 GPIO 设备相关的额外信息,供驱动程序或其他组件使用。
struct list_head list;
链表头,用于将该 GPIO 设备链接到其他设备的链表中。这使得可以方便地遍历系统中的所有 GPIO 设备。
struct list_head pin_ranges;
一个链表头,用于描述 GPIO 控制器所服务的引脚范围。这对于 Pin Controller 子系统来说非常重要,以便能够配置特定引脚的功能。
struct gpio_chip 是一个核心结构体,它在 Linux 内核中提供了一种标准化的方式来管理和操作 GPIO 控制器。通过这个结构体,驱动程序能够简洁地进行 GPIO 的初始化、配置和读写操作。
340 struct gpio_chip {
341 const char *label;
342 struct gpio_device *gpiodev;
343 struct device *parent;
344 struct module *owner;
345
346 int (*request)(struct gpio_chip *chip,
347 unsigned offset);
348 void (*free)(struct gpio_chip *chip,
349 unsigned offset);
350 int (*get_direction)(struct gpio_chip *chip,
351 unsigned offset);
352 int (*direction_input)(struct gpio_chip *chip,
353 unsigned offset);
354 int (*direction_output)(struct gpio_chip *chip,
355 unsigned offset, int value);
356 int (*get)(struct gpio_chip *chip,
357 unsigned offset);
358 int (*get_multiple)(struct gpio_chip *chip,
359 unsigned long *mask,
360 unsigned long *bits);
361 void (*set)(struct gpio_chip *chip,
362 unsigned offset, int value);
363 void (*set_multiple)(struct gpio_chip *chip,
364 unsigned long *mask,
365 unsigned long *bits);
366 int (*set_config)(struct gpio_chip *chip,
367 unsigned offset,
368 unsigned long config);
369 int (*to_irq)(struct gpio_chip *chip,
370 unsigned offset);
371
372 void (*dbg_show)(struct seq_file *s,
373 struct gpio_chip *chip);
374
375 int (*init_valid_mask)(struct gpio_chip *chip,
376 unsigned long *valid_mask,
377 unsigned int ngpios);
378
379 int base;
380 u16 ngpio;
381 const char *const *names;
382 bool can_sleep;
383
384 #if IS_ENABLED(CONFIG_GPIO_GENERIC)
385 unsigned long (*read_reg)(void __iomem *reg);
386 void (*write_reg)(void __iomem *reg, unsigned long data);
387 bool be_bits;
388 void __iomem *reg_dat;
389 void __iomem *reg_set;
390 void __iomem *reg_clr;
391 void __iomem *reg_dir_out;
392 void __iomem *reg_dir_in;
393 bool bgpio_dir_unreadable;
394 int bgpio_bits;
395 spinlock_t bgpio_lock;
396 unsigned long bgpio_data;
397 unsigned long bgpio_dir;
398 #endif /* CONFIG_GPIO_GENERIC */
399
400 #ifdef CONFIG_GPIOLIB_IRQCHIP
401 /*
402 * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib
403 * to handle IRQs for most practical cases.
404 */
405
406 /**
407 * @irq:
408 *
409 * Integrates interrupt chip functionality with the GPIO chip. Can be
410 * used to handle IRQs for most practical cases.
411 */
412 struct gpio_irq_chip irq;
413 #endif /* CONFIG_GPIOLIB_IRQCHIP */
414
415 /**
416 * @valid_mask:
417 *
418 * If not %NULL holds bitmask of GPIOs which are valid to be used
419 * from the chip.
420 */
421 unsigned long *valid_mask;
422
423 #if defined(CONFIG_OF_GPIO)
424 /*
425 * If CONFIG_OF is enabled, then all GPIO controllers described in the
426 * device tree automatically may have an OF translation
427 */
428
429 /**
430 * @of_node:
431 *
432 * Pointer to a device tree node representing this GPIO controller.
433 */
434 struct device_node *of_node;
435
436 /**
437 * @of_gpio_n_cells:
438 *
439 * Number of cells used to form the GPIO specifier.
440 */
441 unsigned int of_gpio_n_cells;
442
443 /**
444 * @of_xlate:
445 *
446 * Callback to translate a device tree GPIO specifier into a chip-
447 * relative GPIO number and flags.
448 */
449 int (*of_xlate)(struct gpio_chip *gc,
450 const struct of_phandle_args *gpiospec, u32 *flags);
451 #endif /* CONFIG_OF_GPIO */
452 };
函数原型 | int gpio_request(unsigned gpio, const char *label) | |
参数 | unsigned gpio | 要请求的 GPIO 引脚的编号。该编号通常由硬件平台定义,具体的引脚编号可以查阅硬件文档。 |
const char *label | 一个可选的标签,用于描述这个 GPIO 的用途。这个标签对于调试和日志记录非常有用,可以帮助开发人员识别不同的 GPIO 引脚及其功能。 | |
返回值 | int | 成功:0 失败:负数 |
功能 | 申请 GPIO (通用输入输出) 引脚 |
68 int gpio_request(unsigned gpio, const char *label)
69 {
70 struct gpio_desc *desc = gpio_to_desc(gpio);
71
72 /* Compatibility: assume unavailable "valid" GPIOs will appear later */
73 if (!desc && gpio_is_valid(gpio))
74 return -EPROBE_DEFER;
75
76 return gpiod_request(desc, label);
77 }
2754 int gpiod_request(struct gpio_desc *desc, const char *label)
2755 {
2756 int ret = -EPROBE_DEFER;
2757 struct gpio_device *gdev;
2758
2759 VALIDATE_DESC(desc);
2760 gdev = desc->gdev;
2761
2762 if (try_module_get(gdev->owner)) {
2763 ret = gpiod_request_commit(desc, label);
2764 if (ret < 0)
2765 module_put(gdev->owner);
2766 else
2767 get_device(&gdev->dev);
2768 }
2769
2770 if (ret)
2771 gpiod_dbg(desc, "%s: status %d\n", __func__, ret);
2772
2773 return ret;
2774 }
函数原型 | void gpio_free(unsigned gpio) | |
参数 | unsigned gpio | 要请求的 GPIO 引脚的编号。该编号通常由硬件平台定义,具体的引脚编号可以查阅硬件文档。 |
返回值 | ||
功能 | 释放 GPIO (通用输入输出) 引脚 |
9 void gpio_free(unsigned gpio)
10 {
11 gpiod_free(gpio_to_desc(gpio));
12 }
2810 void gpiod_free(struct gpio_desc *desc)
2811 {
2812 if (desc && desc->gdev && gpiod_free_commit(desc)) {
2813 module_put(desc->gdev->owner);
2814 put_device(&desc->gdev->dev);
2815 } else {
2816 WARN_ON(extra_checks);
2817 }
2818 }
函数原型 | int gpio_direction_input(unsigned gpio) | |
参数 | unsigned gpio | 要请求的 GPIO 引脚的编号。该编号通常由硬件平台定义,具体的引脚编号可以查阅硬件文档。 |
返回值 | ||
功能 | 设置 GPIO (通用输入输出) 引脚为输入状态 |
70 static inline int gpio_direction_input(unsigned gpio)
71 {
72 return gpiod_direction_input(gpio_to_desc(gpio));
73 }
2950 int gpiod_direction_input(struct gpio_desc *desc)
2951 {
2952 struct gpio_chip *chip;
2953 int ret = 0;
2954
2955 VALIDATE_DESC(desc);
2956 chip = desc->gdev->chip;
2957
2958 /*
2959 * It is legal to have no .get() and .direction_input() specified if
2960 * the chip is output-only, but you can't specify .direction_input()
2961 * and not support the .get() operation, that doesn't make sense.
2962 */
2963 if (!chip->get && chip->direction_input) {
2964 gpiod_warn(desc,
2965 "%s: missing get() but have direction_input()\n",
2966 __func__);
2967 return -EIO;
2968 }
2969
2970 /*
2971 * If we have a .direction_input() callback, things are simple,
2972 * just call it. Else we are some input-only chip so try to check the
2973 * direction (if .get_direction() is supported) else we silently
2974 * assume we are in input mode after this.
2975 */
2976 if (chip->direction_input) {
2977 ret = chip->direction_input(chip, gpio_chip_hwgpio(desc));
2978 } else if (chip->get_direction &&
2979 (chip->get_direction(chip, gpio_chip_hwgpio(desc)) != 1)) {
2980 gpiod_warn(desc,
2981 "%s: missing direction_input() operation and line is output\n",
2982 __func__);
2983 return -EIO;
2984 }
2985 if (ret == 0)
2986 clear_bit(FLAG_IS_OUT, &desc->flags);
2987
2988 if (test_bit(FLAG_PULL_UP, &desc->flags))
2989 gpio_set_config(chip, gpio_chip_hwgpio(desc),
2990 PIN_CONFIG_BIAS_PULL_UP);
2991 else if (test_bit(FLAG_PULL_DOWN, &desc->flags))
2992 gpio_set_config(chip, gpio_chip_hwgpio(desc),
2993 PIN_CONFIG_BIAS_PULL_DOWN);
2994
2995 trace_gpio_direction(desc_to_gpio(desc), 1, ret);
2996
2997 return ret;
2998 }
函数原型 | int gpio_direction_output(unsigned gpio, int value) | |
参数 | unsigned gpio | 要请求的 GPIO 引脚的编号。该编号通常由硬件平台定义,具体的引脚编号可以查阅硬件文档。 |
int value | GPIO 默认输出值 | |
返回值 | ||
功能 | 设置 GPIO (通用输入输出) 引脚为输出状态 |
74 static inline int gpio_direction_output(unsigned gpio, int value)
75 {
76 return gpiod_direction_output_raw(gpio_to_desc(gpio), value);
77 }
3055 int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
3056 {
3057 VALIDATE_DESC(desc);
3058 return gpiod_direction_output_raw_commit(desc, value);
3059 }
函数原型 | int gpio_get_value(unsigned int gpio) | |
参数 | unsigned gpio | 要请求的 GPIO 引脚的编号。该编号通常由硬件平台定义,具体的引脚编号可以查阅硬件文档。 |
返回值 | ||
功能 | 获取 GPIO (通用输入输出) 引脚的值 |
64 static inline int gpio_get_value(unsigned int gpio)
65 {
66 return __gpio_get_value(gpio);
67 }
函数原型 | void gpio_set_value(unsigned int gpio, int value) | |
参数 | unsigned gpio | 要请求的 GPIO 引脚的编号。该编号通常由硬件平台定义,具体的引脚编号可以查阅硬件文档。 |
int value | GPIO 值 | |
返回值 | ||
功能 | 设置 GPIO (通用输入输出) 引脚值 |
69 static inline void gpio_set_value(unsigned int gpio, int value)
70 {
71 __gpio_set_value(gpio, value);
72 }
函数原型 | int of_get_named_gpio_flags(struct device_node *np, const char *list_name, int index, enum of_gpio_flags *flags) | |
参数 | struct device_node *np | 设备树节点指针 |
const char *list_name | GPIO属性名称 | |
int index | 属性值的索引 | |
enum of_gpio_flags *flags | 用于保存GPIO属性值的标志 | |
返回值 | int | 成功:返回GPIO号 失败:负数 |
功能 | 从设备树中获取指定名称的GPIO列表中第index个GPIO的编号以及可能的标志 |
292 int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
293 int index, enum of_gpio_flags *flags)
294 {
295 struct gpio_desc *desc;
296
297 desc = of_get_named_gpiod_flags(np, list_name, index, flags);
298
299 if (IS_ERR(desc))
300 return PTR_ERR(desc);
301 else
302 return desc_to_gpio(desc);
303 }
253 static struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
254 const char *propname, int index, enum of_gpio_flags *flags)
255 {
256 struct of_phandle_args gpiospec;
257 struct gpio_chip *chip;
258 struct gpio_desc *desc;
259 int ret;
260
261 ret = of_parse_phandle_with_args_map(np, propname, "gpio", index,
262 &gpiospec);
263 if (ret) {
264 pr_debug("%s: can't parse '%s' property of node '%pOF[%d]'\n",
265 __func__, propname, np, index);
266 return ERR_PTR(ret);
267 }
268
269 chip = of_find_gpiochip_by_xlate(&gpiospec);
270 if (!chip) {
271 desc = ERR_PTR(-EPROBE_DEFER);
272 goto out;
273 }
274
275 desc = of_xlate_and_get_gpiod_flags(chip, &gpiospec, flags);
276 if (IS_ERR(desc))
277 goto out;
278
279 if (flags)
280 of_gpio_flags_quirks(np, propname, flags, index);
281
282 pr_debug("%s: parsed '%s' property of node '%pOF[%d]' - status (%d)\n",
283 __func__, propname, np, index,
284 PTR_ERR_OR_ZERO(desc));
285
286 out:
287 of_node_put(gpiospec.np);
288
289 return desc;
290 }
函数原型 | int of_get_named_gpio(struct device_node *np,const char *propname, int index) | |
参数 | struct device_node *np | 设备树节点指针 |
const char *propname | GPIO属性名称 | |
int index | 属性值的索引 | |
返回值 | int | 成功:返回GPIO号 失败:负数 |
功能 | 从设备树中获取指定名称的GPIO列表中第index个GPIO的编号 |
129 static inline int of_get_named_gpio(struct device_node *np,
130 const char *propname, int index)
131 {
132 return of_get_named_gpio_flags(np, propname, index, NULL);
133 }
199 static int jw_io_control_probe(struct platform_device *pdev)
200 {
201 struct device_node *node = pdev->dev.of_node;
202 struct jw_io_pdata *pdata;
203 int ret;
204 enum of_gpio_flags flags;
205 printk(" #######jw_io_control_probe####### \n");
206 enable = 0 ;
207
208 pdata = kzalloc(sizeof(struct jw_io_pdata), GFP_KERNEL);
209 if (pdata == NULL) {
210 printk("%s failed to allocate driver data\n",__FUNCTION__);
211 return -ENOMEM;
212 }
213 memset(pdata,0,sizeof(struct jw_io_pdata));
214
320 ret = of_get_named_gpio_flags(node, "led_ctl", 0, &flags);
321 if (ret < 0) {
322 printk("%s() Can not read property usb_5v_gpio\n", __FUNCTION__);
323 goto err;
324 } else {
325 pdata->led_gpio = ret;
326 ret = devm_gpio_request(&pdev->dev, pdata->led_gpio, "led_gpio");
327 if(ret < 0){
328 printk("%s() devm_gpio_request led_gpio request ERROR\n", __FUNCTION__);
329 goto err;
330 }
331
332 ret = gpio_direction_output(pdata->led_gpio,0);
333 if(ret < 0){
334 printk("%s() gpio_direction_input led_gpio set ERROR\n", __FUNCTION__);
335 goto err;
336 }
337 }
360
376
377 ret = device_create_file(&pdev->dev, &dev_attr_led_display);
378 if (ret) {
379 printk(KERN_ERR "%s:Fail to creat led_display class file\n", __func__);
380 return ret;
381 }else
382 printk("class_create jw_io_control led OK !!!!\n");
383
390
391 JWpdata_info = pdata;
392 printk(" #######jw_io_control_probe end####### \n");
393 return 0;
394 err:
395 kfree(pdata);
396 return ret;
397 }