全志t3设备树与gpio使用
spi控制节点说明
spi设备在设备树里像描述i2c设备一样,需要在spi控制器节点里用子节点描述spi设备节点:
&spi0 { /* spi控制器节点 */
...
cs-gpios = <&pio 2 3 GPIO_ACTIVE_HIGH>, <&pio 0 6 GPIO_ACTIVE_HIGH>;
/* 片选的io口需与下面的spi设备节点一致 */
spidev0 {
compatible = "nanopi,spidev"; /* 此属性值用于与spi设备驱动匹配 */
reg = <0>; /*spi设备是没有设备地址的, 这里是指使用spi控制器的cs-gpios里的第几个片选io */
status = "okay"; /* status属性值为"okay"表示spidev0设备使能, "disabled"表示设备没有使用*/
spi-max-frequency = <10000000>; /* 指定spi设备的最大工作时钟 */
...
buswidth = <8>; /* 传输以8位为单位 */
mode = <0>; /* 使用第几种工作时序(CPOL, CPHA) */
/*但在现用的内核源码里发现, spi设备的工作时序并不是用mode属性值来指定的*/
/* 如CPOL需要设1, 则只需在spi设备节点里加上"spi-cpol"属性即可; CPOL设0,则不写"spi-cpol"属性即可 */
/* CPHA设1时, 则在设备节点里加上"spi-cpha"属性即可 */
/* 还可以加入自定义的属性,用于指定工作时序方式及其它功能设置等 */
};
};
SPI设备树配置
- 根据原理图修改对应引脚
linux-3.10/arch/arm/boot/dts/sun8iw11p1-pinctrl.dtsi
- 蔽掉引脚冲突功能
linux-3.10/arch/arm/boot/dts/sun8iw11p1-pinctrl.dtsi
sun8iw11p1-pinctrl.dtsi文件中,查找是否有其它功能使用PB13,PC19,PC20,PC21,PC22,如果有则蔽掉。 - spi2节点下增加对应设备属性
- 设备查看
/sys/class/spi_master/spi2/spi2.1/modalias
/sys/bus/spi/devices/spi1.0/modalias
背光控制IO设备树配置
SPI控制引脚配置
** gpio所以计算 **
文件:
sunxi-gpio.h
GPIO定义:
#ifndef _DT_BINDINGS_GPIO_GPIO_H
#define _DT_BINDINGS_GPIO_GPIO_H
#define GPIO_ACTIVE_HIGH 0
#define GPIO_ACTIVE_LOW 1
#define PA 0
#define PB 1
#define PC 2
#define PD 3
#define PE 4
#define PF 5
#define PG 6
#define PH 7
#define PI 8
#define PJ 9
#define PK 10
#define PL 11
#define PM 12
#define PN 13
#define PO 14
#define PP 15
#define default 0xffffffff
#endif
三、计算方式
举两个例子
1、PE8
gpio编号:4*32+8=136
2、PE9
gpio编号:4*32+9=137
链接: 全志GPIO使用
gpio控制器都是由厂商负责驱动好的,在设备树里关于gpio pinctrl的描述,如下:
其中“ #gpio-cells = <6>”表示在设备树里描述使用一个gpio口需要提供6个指定的参数。
通过文档,可以得知6个参数的分别作用如下:
gpio = <&pio 1 1 1 1 1 0>;
| | | | | | | |-------------------表示有效电平
| | | | | | |----------------------上下拉, 0关闭功能, 1上拉, 2下拉, 3保留
| | | | | |-------------------------驱动力,电流等级(0 - 3),级别越高,输出电流越大
| | | | |----------------------------gpio功能类型,0输入, 1输出, 6和外部中断,7关闭功能(具体查手册)
| | | |------------------------------pin bank 内偏移(即组内第几个io口).
| | |---------------------------------哪组gpio, PA(0),PB(1),PC(2),PD(3),PE(4),PF(5),PG(6),PH(7),PI(8),PJ(9),PK(10),PL(11)
| |--------------------------------------指向哪个gpio控制器, pio / r_pio(PL组)
|-----------------------------------------------------属性名字(随便命名)
获取设备树里设备节点的gpio口信息:
获取到int类型的gpio口后,就可以使用linux/gpio.h里的gpio口操作函数:
应用例子 :
dtsi:
example{
compatible = "gpio,example";
gpios = <&pio PE 8 1 1 1 1>;
};
代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/sys_config.h>
#include <linux/delay.h>
int example_probe(struct platform_device *pdev)
{
struct device_node *nd = pdev->dev.of_node;
int gpio;
struct gpio_config config;
printk("gpio count:%d\n", of_gpio_named_count(nd, "gpios"));
gpio = of_get_named_gpio_flags(nd, "gpios", 0, (enum of_gpio_flags *)&config);
if (!gpio_is_valid(gpio))
printk("gpio isn't valid\n");
if (gpio_request(gpio, pdev->name) < 0)
printk("gpio request failed %d\n", gpio);
gpio_direction_output(gpio, 1);
msleep(3000);
gpio_direction_output(gpio, 0);
msleep(3000);
gpio_direction_input(gpio);
gpio_free(gpio);
return 0;
}
int example_remove(struct platform_device *pdev)
{
printk("in myremove ...\n");
return 0;
}
struct of_device_id ids[] = {
{.compatible = "gpio,example"},
{},
};
struct platform_driver mydrv = {
.probe = example_probe,
.remove = example_remove,
.driver = {
.owner = THIS_MODULE,
.name = "example" ,
.of_match_table = ids,
},
};
module_platform_driver(example);
MODULE_LICENSE("GPL");